Skip to content

Commit

Permalink
feat: move tooltip to next (#887)
Browse files Browse the repository at this point in the history
* chore: move Tooltip to next

* chore: update counter story since it uses tooltip

* chore: add tooltip styling comments

* chore: update prop and comments

* chore: respond to comments

* chore: nit: remove redundant prop in story
  • Loading branch information
jinlee93 authored and anniehu4 committed Apr 20, 2022
1 parent 6384dc3 commit 8ac1f58
Show file tree
Hide file tree
Showing 15 changed files with 977 additions and 298 deletions.
4 changes: 2 additions & 2 deletions .storybook/data/tokens.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
"eds-l-max-width": "71.25rem",
"eds-l-linelength-width": "36rem",
"eds-box-shadow-sm": "0px 1px 2px 1px rgba(0, 0, 0, 0.2)",
"eds-box-shadow-md": "0 0.5rem 0.375rem -0.375rem rgba(0, 0, 0, 0.1)",
"eds-box-shadow-md": "0px 0px 0px 1px var(--eds-color-neutral-200), 0px 2px 3px rgba(0, 0, 0, 0.02), 0px 4px 8px rgba(0, 0, 0, 0.08)",
"eds-size-1": "0.5rem",
"eds-size-2": "1rem",
"eds-size-3": "1.5rem",
Expand Down Expand Up @@ -201,5 +201,5 @@
"eds-theme-color-form-input-border-error": "#BD0044",
"eds-theme-form-input-border-width": "1px",
"eds-theme-form-input-border-radius": "4px",
"eds-theme-box-shadow": "0 0.5rem 0.375rem -0.375rem rgba(0, 0, 0, 0.1)"
"eds-theme-box-shadow": "0px 0px 0px 1px var(--eds-color-neutral-200), 0px 2px 3px rgba(0, 0, 0, 0.02), 0px 4px 8px rgba(0, 0, 0, 0.08)"
}
8 changes: 7 additions & 1 deletion .stylelintrc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
],
"custom-property-empty-line-before": "never",
"max-nesting-depth": 1,
"selector-class-pattern": null
"selector-class-pattern": null,
"selector-pseudo-class-no-unknown": [
true,
{
"ignorePseudoClasses": ["global"]
}
]
}
}
22 changes: 11 additions & 11 deletions docs/CODE_GUIDELINES.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ Here's another example:

### CSS Nesting

EDS uses [PostCSS Nested](https://github.com/postcss/postcss-nested) to provide some developer ergononics. As a general principle, nesting should be used sparingly and is only used in the following situations:
EDS uses [PostCSS Nested](https://github.com/postcss/postcss-nested) to provide some developer ergonomics. As a general principle, nesting should be used sparingly and is only used in the following situations:

- Media queries
- States and pseudo-selectors
Expand Down Expand Up @@ -127,7 +127,7 @@ EDS uses [PostCSS Nested](https://github.com/postcss/postcss-nested) to provide

#### Parent selectors

Use [parent selectors](https://sass-lang.com/documentation/style-rules/parent-selector) to target a selector when it appears inside a specific parent element. Use parent selectors instead of child selectors in order to co-locate all styles around a specific selector, which improves maintability and findability.
Use [parent selectors](https://sass-lang.com/documentation/style-rules/parent-selector) to target a selector when it appears inside a specific parent element. Use parent selectors instead of child selectors in order to co-locate all styles around a specific selector, which improves maintainability and findability.

Use the following conventions:

Expand Down Expand Up @@ -188,7 +188,7 @@ For example:
}
```

Not all CSS declarations warrant a comment, but non-obvious declarations (like context-specific styles, magic numbers, or styles dependant on other selector styles) should be accompanied by a comment.
Not all CSS declarations warrant a comment, but non-obvious declarations (like context-specific styles, magic numbers, or styles dependent on other selector styles) should be accompanied by a comment.

### Other CSS Rules

Expand Down Expand Up @@ -261,7 +261,7 @@ Please refer to the [design tokens documentation](./TOKENS.md) to learn how to u

- **Presentational Components Only** - EDS provides a library of reusable [presentational UI components](https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0) that are consumed by CZI applications. These presentational components are "dumb" and don't contain any application business logic and aren't hooked up to any data models.
- **Predictable APIs** - EDS provides consistent, clear [component APIs](#component-naming) in order to provide a consistent and intuitive user developer experience.
- **Composition over inheritence** EDS adheres to the [composition over inheritence](https://en.wikipedia.org/wiki/Composition_over_inheritance) principle in order to create clean, extensible components that aren't tied to specific contexts or content.
- **Composition over inheritance** EDS adheres to the [composition over inheritance](https://en.wikipedia.org/wiki/Composition_over_inheritance) principle in order to create clean, extensible components that aren't tied to specific contexts or content.

## JavaScript Tools <a name="js-tools"></a>

Expand Down Expand Up @@ -320,7 +320,7 @@ export interface Props {
}
```

All component props must be defined with appropriate [TypeScript type](https://www.typescriptlang.org/docs/handbook/basic-types.html) applied. Each prop must contain a comment above the prop declaration to document the prop's function. These comments and prop declarations are automatically converted into prop documentation in Storybook. As a general guideline, try to organize component prop definitiones alphabetically.
All component props must be defined with appropriate [TypeScript type](https://www.typescriptlang.org/docs/handbook/basic-types.html) applied. Each prop must contain a comment above the prop declaration to document the prop's function. These comments and prop declarations are automatically converted into prop documentation in Storybook. As a general guideline, try to organize component prop definitions alphabetically.

### Export module

Expand All @@ -333,7 +333,7 @@ export const ComponentName: React.FC<Props> = ({
}) => {
```
This defines the component name and passses in all the `Props`.
This defines the component name and passes in all the `Props`.
### Variables, Methods, and Hooks (if applicable)
Expand Down Expand Up @@ -371,7 +371,7 @@ Components in this library exist in a flat structure so each component directory
Certain components (such as `<Tabs />` and `<Table />`) require splitting up into smaller subcomponents.
By default, we err towards more centralized control over the component architecture in order to prevent undesired results (for instance, we don't want users to put a `<Card />` inside of `<Breadcrumbs />`). However, certain components will require more flexibility and will therefore be architected to be composible and flexible (such as `<Card>`).
By default, we err towards more centralized control over the component architecture in order to prevent undesired results (for instance, we don't want users to put a `<Card />` inside of `<Breadcrumbs />`). However, certain components will require more flexibility and will therefore be architected to be composable and flexible (such as `<Card>`).
#### Conventions for compound components
Expand All @@ -391,17 +391,17 @@ By default, we err towards more centralized control over the component architect
EDS follows specific front-end API naming conventions. Authoring a consistent API language provides many benefits:
- **More efficient development** - Because the API language is consistent across components, user developers can spend more time coding rather than reading API documentation. Also, library contributors don't have to think as much about component API naming when creating new components/variants.
- **Shared vocuabulary between designers and developers** - When the code library and design library use the same language, designers and developers can spend more time collaborating rather than futzing over what things are named. This improves team velocity and product quality. It also positions the team to benefit from future tooling that can bring design and code closer together (something many startups and plugins are trying to solve right now!)
- **Shared vocabulary between designers and developers** - When the code library and design library use the same language, designers and developers can spend more time collaborating rather than futzing over what things are named. This improves team velocity and product quality. It also positions the team to benefit from future tooling that can bring design and code closer together (something many startups and plugins are trying to solve right now!)
- **Future changes** - Utilizing a consistent language means that future changes and improvements are as easy as find-and-replace.
EDS adhreres to the following API naming conventions:
EDS adheres to the following API naming conventions:
### Variants
- `variant` should be used for primary _stylistic_ variations of a component, such as (e.g. `<Card variant="bordered">` or `<Button variant="secondary">`). `variant` should be used if there is primarily one variable used to manipulate the component style.
- `inverted` should be used consistently for stylistic `variation`s that "invert" the color schemes (e.g. `inverted=true`) to work on a darker background.
- `size` should be used for adjusting size attributes (e.g. `<Button variant="secondary" size="sm">` or `<Button size="lg"`>). Default to `sm` and `lg`, with "md" being the default.
- `behavior` should be used for funcitonal variations of a pattern, such as `<Banner behavior="dismissable">`. Additional non-exclusive behaviors should be handled using boolean props prefixed with `is` (e.g. `isSticky` and `isDismissable`).
- `behavior` should be used for functional variations of a pattern, such as `<Banner behavior="dismissable">`. Additional non-exclusive behaviors should be handled using boolean props prefixed with `is` (e.g. `isSticky` and `isDismissable`).
- `orientation` should be used for controlling the layout or orientation of a component (e.g. `<ButtonGroup orientation="stacked">`)
- `align` should be used for aligning content, and should include `left` (default), `center`, `right` if needed.
- `verticalAlign` should be used for vertically aligning content, and should include `top`, `middle`, `bottom` if needed.
Expand All @@ -410,7 +410,7 @@ EDS adhreres to the following API naming conventions:
- Default to `text` for strings of text, such as `<Button text="First Name">`.
- For headings, default to `title`, such as `<PageHeader title="My Page Title">`.
- For form-related comnp, use the semantic `label` or `legend` (e.g. `<TextField label="first name" />`).
- For form-related component, use the semantic `label` or `legend` (e.g. `<TextField label="first name" />`).
### Tag name
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
},
"dependencies": {
"@headlessui/react": "1.4.3",
"@tippyjs/react": "^4.2.6",
"@tippyjs/react": "4.2.5",
"clsx": "^1.1.1",
"downshift": "^6.1.7",
"nanoid": "^3.3.1",
Expand Down
168 changes: 88 additions & 80 deletions src/components/Button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,87 +81,95 @@ export interface Props {
/**
* Primary UI component for user interaction
*/
export const Button: React.FC<Props> = ({
buttonRef,
className,
variant,
size,
disabled,
fullWidth,
iconName,
iconPosition = 'before',
inverted,
loading,
onClick,
screenReaderText,
href,
text,
type,
hideText,
...other
}) => {
const componentClassName = clsx(styles['button'], className, {
[styles['button--primary']]: variant === 'primary',
[styles['button--bare']]: variant === 'bare',
[styles['button--link']]: variant === 'link',
[styles['button--sm']]: size === 'sm',
[styles['button--table-header']]: variant === 'table-header',
[styles['button--inverted']]: inverted === true,
[styles['button--full-width']]: fullWidth,
[styles['eds-is-loading']]: loading,
});
const TagName = href ? 'a' : 'button';
export const Button = React.forwardRef(
(
{
buttonRef,
className,
variant,
size,
disabled,
fullWidth,
iconName,
iconPosition = 'before',
inverted,
loading,
onClick,
screenReaderText,
href,
text,
type,
hideText,
...other
}: Props,
ref,
) => {
const componentClassName = clsx(styles['button'], className, {
[styles['button--primary']]: variant === 'primary',
[styles['button--bare']]: variant === 'bare',
[styles['button--link']]: variant === 'link',
[styles['button--sm']]: size === 'sm',
[styles['button--table-header']]: variant === 'table-header',
[styles['button--inverted']]: inverted === true,
[styles['button--full-width']]: fullWidth,
[styles['eds-is-loading']]: loading,
});
const TagName = href ? 'a' : 'button';

const computedIcon = (
<>
{loading && (
<Icon
aria-hidden="true"
className={styles['button__icon']}
focusable={false}
name="spinner"
/>
)}
{!loading && iconName && (
<Icon
aria-hidden="true"
className={styles['button__icon']}
focusable={false}
name={iconName}
/>
)}
</>
);
const computedIcon = (
<>
{loading && (
<Icon
aria-hidden="true"
focusable={false}
name="spinner"
className={styles['button__icon']}
/>
)}
{!loading && iconName && (
<Icon
aria-hidden="true"
focusable={false}
name={iconName}
className={styles['button__icon']}
/>
)}
</>
);

return (
<TagName
className={componentClassName}
disabled={disabled}
href={href}
onClick={onClick}
ref={buttonRef}
tabIndex={disabled ? -1 : undefined}
type={type}
{...other}
>
{iconPosition === 'before' && computedIcon}
return (
<TagName
className={componentClassName}
href={href}
disabled={disabled}
tabIndex={disabled ? -1 : undefined}
ref={buttonRef || ref}
type={type}
onClick={onClick}
{...other}
>
{iconPosition === 'before' && computedIcon}

{text && (
<span
className={
!hideText
? styles['button__text']
: styles['button__text'] + 'u-is-vishidden'
}
>
{text}
{screenReaderText && (
<span className={styles['u-is-vishidden']}>{screenReaderText}</span>
)}
</span>
)}
{text && (
<span
className={
!hideText
? styles['button__text']
: styles['button__text'] + 'u-is-vishidden'
}
>
{text}
{screenReaderText && (
<span className={styles['u-is-vishidden']}>
{screenReaderText}
</span>
)}
</span>
)}

{iconPosition === 'after' && computedIcon}
</TagName>
);
};
{iconPosition === 'after' && computedIcon}
</TagName>
);
},
);
Button.displayName = 'Button';
10 changes: 8 additions & 2 deletions src/components/Counter/Counter.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Story, Meta } from '@storybook/react';
import React from 'react';
import { Counter, Props } from './Counter';
import { Button } from '../Button/Button';
import { Tooltip } from '../Tooltip/Tooltip';

export default {
Expand Down Expand Up @@ -30,8 +31,13 @@ DefaultWithTooltip.args = {
plusButtonText: 'Add by 1',
fieldNote: 'This is a counter field',
labelAfter: (
<Tooltip buttonText="Select this button to trigger the tooltip">
Some text to help with a form field
<Tooltip text="Some text to help with a form field">
<Button
variant="bare"
iconPosition="after"
iconName="question-mark-circle"
text="Hover this button to trigger the tooltip"
/>
</Tooltip>
),
};
Expand Down
Loading

0 comments on commit 8ac1f58

Please sign in to comment.