diff --git a/cypress/integration/Button.spec.ts b/cypress/integration/Button.spec.ts index 2dae24ec00..d33179542d 100644 --- a/cypress/integration/Button.spec.ts +++ b/cypress/integration/Button.spec.ts @@ -7,7 +7,7 @@ describe('Button', () => { context('given primary buttons are rendered', () => { beforeEach(() => { - h.stories.load('Components|Buttons/Button/React', 'Primary'); + h.stories.load('Components|Buttons/Button/React/Standard', 'Primary'); }); it('should not have any axe errors', () => { diff --git a/eslintrc.js b/eslintrc.js index ac148570bc..4d5079b04f 100644 --- a/eslintrc.js +++ b/eslintrc.js @@ -75,7 +75,7 @@ module.exports = { 'no-param-reassign': 'error', 'no-undef-init': 'error', 'no-unused-labels': 'error', - 'no-use-before-define': 'warn', // Decide on this + 'no-use-before-define': ['warn', {functions: false, classes: true}], 'no-var': 'error', 'prefer-const': 'error', 'quote-props': 'off', diff --git a/modules/_labs/pagination/react/lib/Pages.tsx b/modules/_labs/pagination/react/lib/Pages.tsx index 377c3e110d..6dae2fdd56 100644 --- a/modules/_labs/pagination/react/lib/Pages.tsx +++ b/modules/_labs/pagination/react/lib/Pages.tsx @@ -19,17 +19,21 @@ const noPointerEvents = css({ pointerEvents: 'none', }); +const autoWidth = css({ + width: 'auto', +}); + const ellipsisStyle = css(noPointerEvents, { width: canvas.spacing.l, textAlign: 'center', display: 'inline-block', }); -const noTransitions = css({ +const noTransitions = css(autoWidth, { '&:not(:hover)': {transition: 'none !important'}, }); -const activeStyling = css(noPointerEvents, noTransitions, { +const activeStyling = css(noPointerEvents, noTransitions, autoWidth, { color: canvas.colors.frenchVanilla100, }); diff --git a/modules/button/react/README.md b/modules/button/react/README.md index e43fe5fcd4..3d6b36efaf 100644 --- a/modules/button/react/README.md +++ b/modules/button/react/README.md @@ -22,15 +22,13 @@ yarn add @workday/canvas-kit-react-button > primary, and accompanying secondary, and delete). These are still avialable, but will be removed > in the first major release after they are available for all Workday customers. The biggest change > is with regards to colors and styling, but the behavior should remain the same. - -### New Button - -Anywhere you were using `Button`, you will automatically get the updated styling (previously -`beta_Button`). This will be a visual breaking change (padding and colors have changed). Note, we -are still supporting the import for `beta_Button` as well. However, if you are using -`import {beta_Button as Button}...` you can remove it now too since this too will be removed in a -future release. The new buttons include: blue primary button, and accompanying secondary, delete, -outline, and dropdown buttons. The import and usage is documented below. +> +> ### New Button +> +> Anywhere you were using `Button`, you will automatically get the updated styling (previously +> `beta_Button`). This will be a visual breaking change (padding and colors have changed). The new +> buttons include: blue primary button, and accompanying secondary, delete, outline, highlight, and +> dropdown buttons. The import and usage is documented below. ### Deprecated Buttons @@ -51,7 +49,19 @@ able to compile your code. --- -## Button +## Table of Contents + +- [Button](#button) +- [DeleteButton](#deletebutton) +- [DropdownButton](#dropdownbutton) +- [HighlightButton](#highlightbutton) +- [OutlineButton](#outlinebutton) +- [TextButton](#textbutton) +- [Icon Button](#icon-button) + +--- + +# Button ```tsx import * as React from 'react'; @@ -62,7 +72,7 @@ import {Button} from '@workday/canvas-kit-react-button'; ## Static Properties -#### `Sizes: ButtonSize` +#### `Size: 'small' | 'medium' | 'large'` ```tsx @@ -70,7 +80,7 @@ import {Button} from '@workday/canvas-kit-react-button'; --- -#### `Types: ButtonVariant` +#### `Variant: ButtonVariant` ```tsx @@ -96,21 +106,220 @@ Default: `ButtonVariant.Secondary` | ----------- | ------------------------------- | | `Primary` | Blue background, white text | | `Secondary` | Gray background, dark gray text | -| `Delete` | Red background, dark text | --- -#### `size: ButtonSize` +#### `size: 'small' | 'medium' | 'large'` + +> The size of the button + +Default: `'medium'` + +| Theme | Description | +| -------- | -------------------------------------- | +| `small` | 24px tall, small padding, small text | +| `medium` | 32px tall, medium padding, medium text | +| `large` | 48px tall, large padding, larger text | + +--- + +#### `grow: boolean` + +> If true, the button will grow to its container's width. + +Default: `false` + +--- + +#### `buttonRef: React.Ref` + +> Returns the ref to the rendered HTMLButtonElement. + +--- + +#### `dataLabel: String` + +> The data label of the button (generally used for media timestamps). +> +> Note: not displayed at `small` size. + +--- + +### `icon: CanvasSystemIcon` + +> The icon of the button. +> +> Note: not displayed at `small` size. + +--- + +# DeleteButton + +```tsx +import * as React from 'react'; +import {DeleteButton} from '@workday/canvas-kit-react-button'; + +Button Label; +``` + +## Static Properties + +#### `Size: 'small' | 'medium' | 'large'` + +```tsx +Small Button +``` + +## Component Props + +### Required + +#### `children: ReactNode` + +> Buttons cannot be empty + +### Optional + +#### `size: 'small' | 'medium' | 'large'` + +> The size of the button + +Default: `'medium'` + +| Theme | Description | +| -------- | -------------------------------------- | +| `small` | 24px tall, small padding, small text | +| `medium` | 32px tall, medium padding, medium text | +| `large` | 48px tall, large padding, larger text | + +--- + +#### `buttonRef: React.Ref` + +> Returns the ref to the rendered HTMLButtonElement. + +--- + +#### `grow: boolean` + +> If true, the button will grow to its container's width. + +Default: `false` + +--- + +# DropdownButton + +```tsx +import * as React from 'react'; +import {DropdownButton} from '@workday/canvas-kit-react-button'; + +Button Label; +``` + +## Static Properties + +#### `Size: 'medium' | 'large'` + +```tsx +Large Button +``` + +--- + +#### `Variant: DropdownButtonVariant` + +```tsx +Primary Button +``` + +## Component Props + +### Required + +#### `children: ReactNode` + +> Buttons cannot be empty + +### Optional + +#### `variant: ButtonVariant` + +> The type of the button + +Default: `DropdownButtonVariant.Secondary` + +| Theme | Description | +| ----------- | ------------------------------------ | +| `Primary` | Blue background, white text/icon | +| `Secondary` | Gray background, dark gray text/icon | + +--- + +#### `size: 'medium' | 'large'` + +> The size of the button + +Default: `'medium'` + +| Theme | Description | +| -------- | -------------------------------------- | +| `medium` | 32px tall, medium padding, medium text | +| `large` | 48px tall, large padding, larger text | + +--- + +#### `grow: boolean` + +> If true, the button will grow to its container's width. + +Default: `false` + +--- + +#### `buttonRef: React.Ref` + +> Returns the ref to the rendered HTMLButtonElement. + +--- + +# HighlightButton + +```tsx +import * as React from 'react'; +import {HighlightButton} from '@workday/canvas-kit-react-button'; + +Button Label; +``` + +## Static Properties + +#### `Size: 'medium' | 'large'` + +```tsx +Large Button +``` + +## Component Props + +### Required + +#### `children: ReactNode` + +> Buttons cannot be empty + +### Optional + +#### `size: 'medium' | 'large'` > The size of the button -Default: `ButtonSize.Large` +Default: `'medium'` | Theme | Description | | -------- | -------------------------------------- | -| `Small` | 18px tall, small padding, small text | -| `Medium` | 24px tall, medium padding, medium text | -| `Large` | 40px tall, large padding, larger text | +| `medium` | 32px tall, medium padding, medium text | +| `large` | 48px tall, large padding, larger text | --- @@ -126,6 +335,195 @@ Default: `false` > Returns the ref to the rendered HTMLButtonElement. +--- + +### `icon: CanvasSystemIcon` + +> The icon of the button + +--- + +# OutlineButton + +```tsx +import * as React from 'react'; +import {OutlineButton} from '@workday/canvas-kit-react-button'; + +Button Label; +``` + +## Static Properties + +#### `Size: 'small' | 'medium' | 'large'` + +```tsx +Small Button +``` + +--- + +#### `Variant: OutlineButtonVariant` + +```tsx +Primary Button +``` + +## Component Props + +### Required + +#### `children: ReactNode` + +> Buttons cannot be empty + +### Optional + +#### `variant: ButtonVariant` + +> The type of the button + +Default: `OutlineButtonVariant.Secondary` + +| Theme | Description | +| ----------- | --------------------------------------------- | +| `Primary` | Transparent background, blue border and text | +| `Secondary` | Transparent background, gray border and text | +| `Inverse` | Transparent background, white border and text | + +--- + +#### `size: 'small' | 'medium' | 'large'` + +> The size of the button + +Default: `'medium'` + +| Theme | Description | +| -------- | -------------------------------------- | +| `small` | 24px tall, small padding, small text | +| `medium` | 32px tall, medium padding, medium text | +| `large` | 48px tall, large padding, larger text | + +--- + +#### `grow: boolean` + +> If true, the button will grow to its container's width. + +Default: `false` + +--- + +#### `buttonRef: React.Ref` + +> Returns the ref to the rendered HTMLButtonElement. + +--- + +#### `dataLabel: String` + +> The data label of the button (generally used for media timestamps) +> +> Note: not displayed at `small` size. + +--- + +### `icon: CanvasSystemIcon` + +> The icon of the button +> +> Note: not displayed at `small` size. + +--- + +# TextButton + +```tsx +import * as React from 'react'; +import {TextButton} from '@workday/canvas-kit-react-button'; + +Button Label; +``` + +## Static Properties + +#### `Size: 'small' | 'medium'` + +```tsx +Small Button +``` + +--- + +#### `Variant: ButtonVariant` + +```tsx +Inverse Button +``` + +## Component Props + +### Required + +#### `children: ReactNode` + +> Buttons cannot be empty + +### Optional + +#### `variant: TextButtonVariant` + +> The type of the button + +Default: `TextButtonVariant.Default` + +| Theme | Description | +| --------- | ----------- | +| `Default` | Blue text | +| `Inverse` | White text | + +--- + +#### `size: 'small' | 'medium' | 'large'` + +> The size of the button + +Default: `'medium'` + +| Theme | Description | +| -------- | -------------------------------------- | +| `small` | 24px tall, small padding, small text | +| `medium` | 32px tall, medium padding, medium text | +| `large` | 48px tall, large padding, larger text | + +--- + +#### `iconPosition: ButtonIconPosition` + +> The position of the TextButton icon. + +Default: `ButtonIconPosition.Left` + +--- + +#### `buttonRef: React.Ref` + +> Returns the ref to the rendered HTMLButtonElement. + +--- + +### `icon: CanvasSystemIcon` + +> The icon of the button. + +--- + +### `allCaps: boolean` + +> The capitialization of the text in the button. + +--- + # Icon Button > Button containing an icon. Icon may be a component from @@ -139,16 +537,12 @@ import {IconButton} from '@workday/canvas-kit-react-button'; import {SystemIcon} from '@workday/canvas-kit-react-icon'; import {activityStreamIcon} from '@workday/canvas-system-icons-web'; - - -; - ; ``` ## Static Properties -#### `Sizes: ButtonSize` +#### `Size: 'small' | 'medium'` ```tsx @@ -156,7 +550,7 @@ import {activityStreamIcon} from '@workday/canvas-system-icons-web'; --- -#### `Types: IconButtonVariant` +#### `Variant: IconButtonVariant` ```tsx @@ -196,18 +590,16 @@ Default: `IconButtonVariant.Circle` --- -#### `size: ButtonSize.Small | ButtonSize.Medium` +#### `size: 'small' | 'medium` > The size of the icon button -Default: `ButtonSize.Medium` +Default: `'medium'` -| Theme | Description | Is Default | -| --------------------------- | ----------------------------- | ---------- | -| `Small` | 32px Diameter, 20px Icon Size | False | -| `Medium` | 40px Diameter, 24px Icon Size | True | -| `Small` (Square Icon Type) | 32px x 32px, 24px Icon Size | True | -| `Medium` (Square Icon Type) | 40px x 40px, 24px Icon Size | False | +| Theme | Description | Is Default | +| -------- | ----------------------------- | ---------- | +| `Small` | 32px Diameter, 20px Icon Size | False | +| `Medium` | 40px Diameter, 24px Icon Size | True | --- @@ -231,68 +623,19 @@ Default: `undefined` --- -#### `value: string` - -> Value of the button. Must be unique if used within an IconButtonToggleGroup. - -## Accessibility Notes - -> The content of an IconButton is not always clear to the user. In order to better convey what the -> icon represents, the IconButton should be initialized with `title` and `aria-label` attributes. - -# Icon Button Toggle Group - -> Group of buttons containing an icon. This is a -> [_controlled_](https://reactjs.org/docs/forms.html#controlled-components) component. - -## Usage - -```tsx -import * as React from 'react'; -import {IconButton, IconButtonToggleGroup} from '@workday/canvas-kit-react-button'; -import {listViewIcon, worksheetsIcon} from '@workday/canvas-system-icons-web'; - - - - -; -``` - -**Note:** while managing state using a unique `value` for each `IconButton` child is encouraged, you -can also use indexes and omit the `value` field. It is strongly recommended to not mix these two -methods. - -## Static Properties - -> None - -## Component Props - -### Required - -#### `children: React.ReactElement[]` - -> Icon buttons to toggle between. - ---- - -### Optional - -#### `value: string | number` +#### `buttonRef: React.Ref` -> Identify which item is selected (toggled=true). If a string is passed, the IconButton with the -> corresponding value will be selected. If a number is passed, the IconButton with the corresponding -> index will be selected. +> Returns the ref to the rendered HTMLButtonElement. --- -#### `isRTL: boolean` +### `icon: CanvasSystemIcon` -> Identify whether to render from right to left +> The icon of the button. Optional because IconButton can also wrap a SystemIcon component. --- -#### `onChange: (value:string | number)=> void` +## Accessibility Notes -> Callback function when a toggle button is selected. The value (if defined) or the index of the -> button will be returned. +> The content of an IconButton is not always clear to the user. In order to better convey what the +> icon represents, the IconButton should be initialized with `title` and `aria-label` attributes. diff --git a/modules/button/react/index.ts b/modules/button/react/index.ts index 132e7b7f30..d5d3252c25 100644 --- a/modules/button/react/index.ts +++ b/modules/button/react/index.ts @@ -1,17 +1,10 @@ -import Button from './lib/Button'; +export {default as Button, default as beta_Button, ButtonProps} from './lib/Button'; -export default Button; -export { - default as Button, - default as beta_Button, - deprecated_Button, - ButtonProps, -} from './lib/Button'; +export {default as DeleteButton, DeleteButtonProps} from './lib/DeleteButton'; +export {default as deprecated_Button, DeprecatedButtonProps} from './lib/deprecated_Button'; +export {default as DropdownButton, DropdownButtonProps} from './lib/DropdownButton'; +export {default as HighlightButton, HighlightButtonProps} from './lib/HighlightButton'; +export {default as OutlineButton, OutlineButtonProps} from './lib/OutlineButton'; export {default as IconButton, IconButtonProps} from './lib/IconButton'; -export {default as DropdownButton} from './lib/DropdownButton'; export {default as TextButton, TextButtonProps} from './lib/TextButton'; -export { - default as IconButtonToggleGroup, - IconButtonToggleGroupProps, -} from './lib/IconButtonToggleGroup'; export * from './lib/types'; diff --git a/modules/button/react/lib/Button.tsx b/modules/button/react/lib/Button.tsx index efa4c52a84..8d372630e4 100644 --- a/modules/button/react/lib/Button.tsx +++ b/modules/button/react/lib/Button.tsx @@ -1,101 +1,109 @@ -/** @jsx jsx */ -import {jsx} from '@emotion/core'; import * as React from 'react'; -import {ButtonBaseCon, ButtonBaseLabel, ButtonLabelData, ButtonLabelIcon} from './ButtonBase'; -import {DeprecatedButtonVariant, ButtonSize, ButtonVariant} from './types'; -import {CanvasSystemIcon} from '@workday/design-assets-types'; +import {colors} from '@workday/canvas-kit-react-core'; import {GrowthBehavior} from '@workday/canvas-kit-react-common'; -import {labelDataBaseStyles} from './ButtonStyles'; +import {CanvasSystemIcon} from '@workday/design-assets-types'; +import {ButtonVariant, ButtonColors, DropdownButtonVariant, ButtonSize} from './types'; +import {ButtonContainer, ButtonLabel, ButtonLabelData, ButtonLabelIcon} from './parts'; -export interface BaseButtonProps - extends React.ButtonHTMLAttributes { +export interface ButtonProps extends React.ButtonHTMLAttributes, GrowthBehavior { /** * The variant of the Button. * @default ButtonVariant.Secondary */ - variant?: T; + variant?: ButtonVariant; /** * The size of the Button. - * @default ButtonSize.Medium + * @default 'medium' */ - size?: ButtonSize; + size?: 'small' | 'medium' | 'large'; /** * The ref to the button that the styled component renders. */ buttonRef?: React.Ref; /** * The data label of the Button. + * Note: not displayed at `small` size */ dataLabel?: String; /** * The icon of the Button. + * Note: not displayed at `small` size */ icon?: CanvasSystemIcon; } -export interface ButtonProps - extends BaseButtonProps, - GrowthBehavior { - /** - * The children of the Button (cannot be empty). - */ - children: React.ReactNode; -} - -export default class Button extends React.Component { - public static Variant = ButtonVariant; - public static Size = ButtonSize; +const Button = ({ + variant = ButtonVariant.Secondary, + size = 'medium', + buttonRef, + dataLabel, + icon, + children, + ...elemProps +}: ButtonProps) => ( + + {icon && size !== 'small' && } + {children} + {dataLabel && size !== 'small' && {dataLabel}} + +); - static defaultProps = { - size: ButtonSize.Medium, - variant: ButtonVariant.Secondary, - grow: false, - }; +Button.Variant = ButtonVariant; +Button.Size = ButtonSize; - public render() { - const {variant, size, buttonRef, dataLabel, icon, children, ...elemProps} = this.props; +export default Button; - // Restrict Hightlight button to only being sized Large, Medium with an Icon - if (variant === ButtonVariant.Highlight && (icon === undefined || size === ButtonSize.Small)) { - return null; - } - - return ( - - {icon && } - - {children} - - {dataLabel && ( - - {dataLabel} - - )} - - ); +export const getButtonColors = (variant: ButtonVariant | DropdownButtonVariant): ButtonColors => { + switch (variant) { + case ButtonVariant.Primary: + case DropdownButtonVariant.Primary: + return { + default: { + background: colors.blueberry400, + icon: colors.frenchVanilla100, + label: colors.frenchVanilla100, + }, + hover: { + background: colors.blueberry500, + }, + active: { + background: colors.blueberry600, + }, + focus: { + background: colors.blueberry400, + }, + disabled: { + background: colors.blueberry200, + }, + }; + case ButtonVariant.Secondary: + case DropdownButtonVariant.Secondary: + default: + return { + default: { + background: colors.soap200, + icon: colors.licorice200, + label: colors.blackPepper400, + labelData: colors.blackPepper400, + }, + hover: { + background: colors.soap400, + icon: colors.licorice500, + }, + active: { + background: colors.soap500, + icon: colors.licorice500, + }, + focus: { + background: colors.soap200, + icon: colors.licorice500, + }, + disabled: { + background: colors.soap100, + icon: colors.soap600, + label: colors.licorice100, + labelData: colors.licorice100, + }, + }; } -} -/** - * @deprecated deprecated_Button in @workday/canvas-kit-react-button will be removed soon. Use Button instead. - */ -// eslint-disable-next-line @typescript-eslint/class-name-casing -export class deprecated_Button extends React.Component> { - public static Variant = DeprecatedButtonVariant; - public static Size = ButtonSize; - - static defaultProps = { - size: ButtonSize.Large, - variant: DeprecatedButtonVariant.Secondary, - grow: false, - }; - - public componentDidMount() { - console.warn('This component is now deprecated, consider using the new Button component'); - } - - public render() { - const {variant, size, buttonRef, dataLabel, icon, children, ...elemProps} = this.props; - - return ); - expect(component.find('button').props().id).toBe('myBtn'); - component.unmount(); - }); - - test('should call a callback function', () => { - const component = mount(); - const button = component.find('button'); - button.simulate('click'); - expect(cb.mock.calls.length).toBe(1); - component.unmount(); - }); - - test('should not call a callback function when disabled', () => { - const component = mount( - - ); - const button = component.find('button'); - button.simulate('click'); - expect(cb.mock.calls.length).toBe(0); - component.unmount(); - }); - - test('Button should spread extra props', () => { - const component = mount(); - const container = component.at(0).getDOMNode(); - expect(container.getAttribute('data-propspread')).toBe('test'); - component.unmount(); - }); -}); - -describe('TextButton', () => { - const cb = jest.fn(); - afterEach(() => { - cb.mockReset(); - }); - - test('should call a callback function', () => { - const component = mount(Button Label); - const button = component.find('button span'); - button.simulate('click'); - expect(cb.mock.calls.length).toBe(1); - component.unmount(); - }); -}); - -describe('Button Accessibility', () => { - const cb = jest.fn(); - afterEach(() => { - cb.mockReset(); - }); - - test('button should be using HTML5 ); - expect(component.getDOMNode().tagName.toLowerCase()).toEqual('button'); - component.unmount(); - }); - - test("button's label should be in a span", () => { - const labelText: string = 'Button'; - const component = mount(); - expect( - component - .find('button') - .find('span') - .getDOMNode().innerHTML - ).toEqual(labelText); - component.unmount(); - }); - - test('enabled button should NOT have disabled attribute set', () => { - const component = mount(); - expect( - component - .find('button') - .getDOMNode() - .hasAttribute('disabled') - ).toEqual(false); - component.unmount(); - }); - - test('disabled button should have disabled attribute set', () => { - const component = mount(); - expect( - component - .find('button') - .getDOMNode() - .hasAttribute('disabled') - ).toEqual(true); - component.unmount(); - }); - - test('button should pass axe DOM accessibility guidelines', async () => { - const html = ReactDOMServer.renderToString(); - expect(await axe(html)).toHaveNoViolations(); - }); -}); - -describe('Button Focus', () => { - const cb = jest.fn(); - afterEach(() => { - cb.mockReset(); - }); - - // expected usage to manage focus via buttonRef - class FocusableButton extends React.Component> { - readonly buttonRef: React.RefObject; - - constructor(props: ButtonProps) { - super(props); - this.buttonRef = React.createRef(); - } - - // focus on button in componentDidMount for purposes of tests - componentDidMount() { - if (!this.props.disabled && this.buttonRef && this.buttonRef.current) { - this.buttonRef.current.focus(); - } - } - - render() { - return ( - - ); - } - } - - // expected usage to manage focus via buttonRef cb - class FocusableButtonCB extends React.Component> { - private buttonElement: HTMLButtonElement; - - // focus on button in componentDidMount for purposes of tests - componentDidMount() { - if (!this.props.disabled && this.buttonElement) { - this.buttonElement.focus(); - } - } - - render() { - return ( - - ); - } - } - - test('button should not allow focus when disabled via buttonRef cb', () => { - const component = mount(Button); - const activeElement = document.activeElement; - const buttonWrapper = component.find('button'); - expect(buttonWrapper.getDOMNode()).not.toEqual(activeElement); - }); - - test('button should allow focus via buttonRef cb', () => { - const component = mount(Button); - const activeElement = document.activeElement; - const buttonWrapper = component.find('button'); - expect(buttonWrapper.getDOMNode()).toEqual(activeElement); - }); - - test('button should not allow focus when disabled via buttonRef', () => { - const component = mount(Button); - const activeElement = document.activeElement; - const buttonWrapper = component.find('button'); - expect(buttonWrapper.getDOMNode()).not.toEqual(activeElement); - }); - - test('button should allow focus via buttonRef', () => { - const component = mount(Button); - const activeElement = document.activeElement; - const buttonWrapper = component.find('button'); - expect(buttonWrapper.getDOMNode()).toEqual(activeElement); - }); -}); diff --git a/modules/button/react/spec/IconButton.spec.tsx b/modules/button/react/spec/IconButton.spec.tsx index 534b988559..c0379741d8 100644 --- a/modules/button/react/spec/IconButton.spec.tsx +++ b/modules/button/react/spec/IconButton.spec.tsx @@ -1,11 +1,7 @@ import * as React from 'react'; -import {mount} from 'enzyme'; -import {render} from '@testing-library/react'; -import IconButton, {iconButtonIdentifier} from '../lib/IconButton'; -import {SystemIcon} from '@workday/canvas-kit-react-icon'; +import {IconButton} from '../index'; import {activityStreamIcon} from '@workday/canvas-system-icons-web'; -import ReactDOMServer from 'react-dom/server'; -import {axe} from 'jest-axe'; +import {render, fireEvent} from '@testing-library/react'; describe('Icon Button', () => { const cb = jest.fn(); @@ -13,130 +9,89 @@ describe('Icon Button', () => { cb.mockReset(); }); - test('render an icon button with id', () => { - const component = mount( - - - - ); - expect(component.find('button').props().id).toBe('myBtn'); - component.unmount(); + describe('when rendered', () => { + it('should render a button', () => { + const {getByRole} = render( + + ); + expect(getByRole('button')).toBeDefined(); + }); }); - it('should have an identifier class', () => { - const {getByRole} = render( - - - - ); - - expect(getByRole('button').className).toContain(iconButtonIdentifier); - }); - it('should compose custom classNames with the identifier class', () => { - const testClassName = 'test classname'; - const {getByRole} = render( - - - - ); - - expect(getByRole('button').className).toContain(`${iconButtonIdentifier} ${testClassName}`); + describe('when rendered with an id', () => { + it('should render a button with id', () => { + const id = 'myButton'; + const {getByRole} = render( + + ); + expect(getByRole('button')).toHaveAttribute('id', id); + }); }); - test('should call a callback function', () => { - const component = mount( - - - - ); - const button = component.find('button'); - button.simulate('click'); - expect(cb.mock.calls.length).toBe(1); - component.unmount(); + describe('when rendered with disabled attribute', () => { + it('should render a disabled button', () => { + const {getByRole} = render( + + ); + expect(getByRole('button')).toHaveProperty('disabled', true); + }); }); - test('should not call a callback function when disabled', () => { - const component = mount( - - - - ); - const button = component.find('button'); - button.simulate('click'); - expect(cb.mock.calls.length).toBe(0); - component.unmount(); + describe('when rendered with extra, arbitrary props', () => { + it('should spread extra props onto the button', () => { + const attr = 'test'; + const {getByRole} = render( + + ); + expect(getByRole('button')).toHaveAttribute('data-propspread', attr); + }); }); - test('should call onToggleChange when toggle prop changes', () => { - const wrapper = mount( - - - - ); + describe('when rendered with a button ref', () => { + it('should set the ref to the checkbox input element', () => { + const ref = React.createRef(); - wrapper.setProps({toggled: true}); - wrapper.update(); - wrapper.setProps({toggled: true}); - wrapper.update(); - wrapper.setProps({toggled: undefined}); - wrapper.update(); + render(); - expect(cb.mock.calls.length).toBe(2); + expect(ref.current).not.toBeNull(); + expect(ref.current!.tagName.toLowerCase()).toEqual('button'); + }); }); -}); -describe('Icon Button Accessibility', () => { - const cb = jest.fn(); - afterEach(() => { - cb.mockReset(); + describe('when clicked', () => { + it('should call a callback function', () => { + const {getByRole} = render( + + ); + fireEvent.click(getByRole('button')); + expect(cb).toHaveBeenCalledTimes(1); + }); }); - test('icon button should be using HTML5 - - - -

Medium Primary

- - - - -

Small Primary

- - -

Growing Primary

-
- -
- - )) - .add('Secondary', () => ( -
-

Large Secondary

- - - - -

Medium Secondary

- - - - -

Small Secondary

- - -

Growing Secondary

- -
- )) - .add('Delete', () => ( -
-

Large Delete

- - -

Medium Delete

- - -

Small Delete

- - -
- )) - .add('Highlight', () => ( -
-

Large Highlight

- - - -

Medium Highlight

- - - -

Growing

-
- - -
-
- )); - -storiesOf('Components|Buttons/Button/React/Text', module) - .addParameters({component: TextButton}) - .addDecorator(withReadme(README)) - .add('Default', () => ( -
-

Large

- - Text - - - Text - -

Small

- - Text - - - Text - -

All Caps

- All Caps -

Icons

-
- - Left Icon Large - - - Right Icon Large - -
-
- )) - .add('Inverse', () => ( -
-

Large Inverse

-
- - Text - - - Text - -
-

Small Inverse

-
- - Text - - - Text - -
-

All Caps Inverse

-
- All Caps -
-

Icons Inverse

-
- - Left Icon Large - - - Right Icon Large - -
-
- )); - -storiesOf('Components|Buttons/Button/React/Outline', module) - .addParameters({component: Button}) - .addDecorator(withReadme(README)) - .add('Primary', () => ( -
-

Large Primary

- - - - -

Medium Primary

- - - - -

Small Primary

- - -

Growing Primary

- -
- )) - .add('Secondary', () => ( -
-

Large Secondary

- - - - -

Medium Secondary

- - - - -

Small Secondary

- - -

Growing Secondary

- -
- )) - .add('Inverse', () => ( -
-

Large Inverse

-
- - - - -
-

Medium Inverse

-
- - - - -
-

Small Inverse

-
- - -
-

Growing Inverse

-
- -
-
- )); - -storiesOf('Components|Buttons/Button/React/Dropdown', module) - .addParameters({component: DropdownButton}) - .addDecorator(withReadme(README)) - .add('Primary', () => ( -
-

Large Primary

- - Dropdown Button - - - Dropdown Button - -

Medium Primary

- - Dropdown Button - - - Dropdown Button - -
- )) - .add('Secondary', () => ( -
-

Large Secondary

- - Dropdown Button - - - Dropdown Button - -

Medium Secondary

- - Dropdown Button - - - Dropdown Button - -
- )); diff --git a/modules/button/react/stories/stories_Button.tsx b/modules/button/react/stories/stories_Button.tsx new file mode 100644 index 0000000000..5b42b7c605 --- /dev/null +++ b/modules/button/react/stories/stories_Button.tsx @@ -0,0 +1,156 @@ +/// +/** @jsx jsx */ +import {jsx} from '@emotion/core'; +import {storiesOf} from '@storybook/react'; +import withReadme from 'storybook-readme/with-readme'; + +import {editIcon, playCircleIcon, activityStreamIcon} from '@workday/canvas-system-icons-web'; + +import {Button} from '../index'; +import README from '../README.md'; + +const buttonContainer = { + display: 'flex', + alignItems: 'center', + '& button + button': { + marginLeft: 10, + }, +}; + +storiesOf('Components|Buttons/Button/React/Standard', module) + .addParameters({component: Button}) + .addDecorator(withReadme(README)) + .add('Primary', () => ( +
+

Large Primary

+ + + + + +

Medium Primary

+ + + + + +

Small Primary

+ + + +

Growing Primary

+
+ +
+
+ )) + .add('Secondary', () => ( +
+

Large Secondary

+ + + + + +

Medium Secondary

+ + + + + +

Small Secondary

+ + + +

Growing Secondary

+ +
+ )); diff --git a/modules/button/react/stories/stories_DeleteButton.tsx b/modules/button/react/stories/stories_DeleteButton.tsx new file mode 100644 index 0000000000..7d5400de54 --- /dev/null +++ b/modules/button/react/stories/stories_DeleteButton.tsx @@ -0,0 +1,33 @@ +/// +/** @jsx jsx */ +import {jsx} from '@emotion/core'; +import {storiesOf} from '@storybook/react'; +import withReadme from 'storybook-readme/with-readme'; + +import {DeleteButton} from '../index'; +import README from '../README.md'; + +storiesOf('Components|Buttons/Button/React', module) + .addParameters({component: DeleteButton}) + .addDecorator(withReadme(README)) + .add('Delete', () => ( +
+

Large Delete

+ Delete + + Delete + + +

Medium Delete

+ Delete + + Delete + + +

Small Delete

+ Delete + + Delete + +
+ )); diff --git a/modules/button/react/stories/stories_Dropdown.tsx b/modules/button/react/stories/stories_Dropdown.tsx new file mode 100644 index 0000000000..58325fc518 --- /dev/null +++ b/modules/button/react/stories/stories_Dropdown.tsx @@ -0,0 +1,50 @@ +/// +/** @jsx jsx */ +import {jsx} from '@emotion/core'; +import {storiesOf} from '@storybook/react'; +import withReadme from 'storybook-readme/with-readme'; + +import {DropdownButton} from '../index'; +import README from '../README.md'; + +storiesOf('Components|Buttons/Button/React/Dropdown', module) + .addParameters({component: DropdownButton}) + .addDecorator(withReadme(README)) + .add('Primary', () => ( +
+

Large Primary

+ + Dropdown Button + + + Dropdown Button + + +

Medium Primary

+ + Dropdown Button + + + Dropdown Button + +
+ )) + .add('Secondary', () => ( +
+

Large Secondary

+ + Dropdown Button + + + Dropdown Button + + +

Medium Secondary

+ + Dropdown Button + + + Dropdown Button + +
+ )); diff --git a/modules/button/react/stories/stories_HighlightButton.tsx b/modules/button/react/stories/stories_HighlightButton.tsx new file mode 100644 index 0000000000..57371b8144 --- /dev/null +++ b/modules/button/react/stories/stories_HighlightButton.tsx @@ -0,0 +1,49 @@ +/// +/** @jsx jsx */ +import {jsx} from '@emotion/core'; +import {storiesOf} from '@storybook/react'; +import withReadme from 'storybook-readme/with-readme'; + +import {playCircleIcon, activityStreamIcon} from '@workday/canvas-system-icons-web'; + +import {HighlightButton} from '../index'; +import README from '../README.md'; + +const buttonContainer = { + display: 'flex', + alignItems: 'center', + '& button + button': { + marginLeft: 10, + }, +}; + +storiesOf('Components|Buttons/Button/React', module) + .addParameters({component: HighlightButton}) + .addDecorator(withReadme(README)) + .add('Highlight', () => ( +
+

Large Highlight

+ Highlight + + Highlight + + +

Medium Highlight

+ + Highlight + + + Highlight + + +

Growing

+
+ + Highlight + + + Highlight + +
+
+ )); diff --git a/modules/button/react/stories/stories_IconButton.tsx b/modules/button/react/stories/stories_IconButton.tsx new file mode 100644 index 0000000000..09f24566db --- /dev/null +++ b/modules/button/react/stories/stories_IconButton.tsx @@ -0,0 +1,379 @@ +/// +/** @jsx jsx */ +import {jsx, CSSObject} from '@emotion/core'; +import * as React from 'react'; +import {storiesOf} from '@storybook/react'; +import withReadme from 'storybook-readme/with-readme'; + +import {activityStreamIcon} from '@workday/canvas-system-icons-web'; + +import {IconButton} from '../index'; + +import README from '../README.md'; + +const iconButtonLayout: CSSObject = { + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + margin: '0 10px', + padding: '24px', + maxWidth: 'max-content', + borderRadius: '4px', + button: { + margin: '0 12px', + }, +}; + +const blueBackground: CSSObject = { + ...iconButtonLayout, + backgroundColor: '#0875e1', +}; + +storiesOf('Components|Buttons/Button/React/Icon Button', module) + .addParameters({component: IconButton}) + .addDecorator(withReadme(README)) + .add('Circle', () => { + const [toggled, setToggled] = React.useState(); + const handleToggle = () => { + setToggled(!toggled); + }; + + return ( +
+

Medium Default

+ + + +

Small Default

+ + + +

Toggleable Default

+ +
+ ); + }) + .add('Square', () => { + const [toggled, setToggled] = React.useState(); + const handleToggle = () => { + setToggled(!toggled); + }; + + return ( +
+

Medium Square

+ + + +

Small Square

+ + + +

Toggleable Square

+ +
+ ); + }) + .add('Square Filled', () => { + const [toggled, setToggled] = React.useState(); + const handleToggle = () => { + setToggled(!toggled); + }; + + return ( +
+

Medium Square

+ + +

Small Square

+ + +

Toggleable Square

+ +
+ ); + }) + .add('Plain', () => { + const [toggled, setToggled] = React.useState(); + const handleToggle = () => { + setToggled(!toggled); + }; + + return ( +
+

Medium Plain

+ + +

Small Plain

+ + +

Toggleable Plain

+ +
+ ); + }) + .add('Circle Filled', () => { + const [toggled, setToggled] = React.useState(); + const handleToggle = () => { + setToggled(!toggled); + }; + + return ( +
+

Medium Filled

+ + +

Small Filled

+ + +

Toggleable Filled

+ +
+ ); + }) + .add('Inverse', () => { + const [toggled, setToggled] = React.useState(); + const handleToggle = () => { + setToggled(!toggled); + }; + + return ( +
+

Medium Inverse

+
+ + +
+

Small Inverse

+
+ + +
+

Toggleable Inverse

+
+ +
+
+ ); + }) + .add('Inverse Filled', () => { + const [toggled, setToggled] = React.useState(); + const handleToggle = () => { + setToggled(!toggled); + }; + + return ( +
+

Medium Inverse Filled

+
+ + +
+

Small Inverse Filled

+
+ + +
+

Toggleable Inverse Filled

+
+ +
+
+ ); + }); diff --git a/modules/button/react/stories/stories_OutlineButton.tsx b/modules/button/react/stories/stories_OutlineButton.tsx new file mode 100644 index 0000000000..96dfc596b7 --- /dev/null +++ b/modules/button/react/stories/stories_OutlineButton.tsx @@ -0,0 +1,211 @@ +/// +/** @jsx jsx */ +import {jsx, CSSObject} from '@emotion/core'; +import {storiesOf} from '@storybook/react'; +import withReadme from 'storybook-readme/with-readme'; + +import {editIcon, playCircleIcon, activityStreamIcon} from '@workday/canvas-system-icons-web'; + +import {OutlineButton} from '../index'; +import README from '../README.md'; + +const blueBackground: CSSObject = { + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + flexWrap: 'wrap', + backgroundColor: '#0875e1', + margin: '0 10px', + padding: '12px', + maxWidth: 'max-content', + borderRadius: '3px', + button: { + margin: '12px', + }, +}; + +storiesOf('Components|OutlineButtons/OutlineButton/React/Outline', module) + .addParameters({component: OutlineButton}) + .addDecorator(withReadme(README)) + .add('Primary', () => ( +
+

Large Primary

+ + Outline Primary + + + Outline Primary + + + Outline Primary + + + Outline Primary + + +

Medium Primary

+ + Outline Primary + + + Outline Primary + + + Outline Primary + + + Outline Primary + + +

Small Primary

+ + Outline Primary + + + Outline Primary + + +

Growing Primary

+ + Growing Primary Outline + +
+ )) + .add('Secondary', () => ( +
+

Large Secondary

+ Outline Secondary + + Outline Secondary + + + Outline Secondary + + + Outline Secondary + + +

Medium Secondary

+ Outline Secondary + + Outline Secondary + + + Outline Secondary + + + Outline Secondary + + +

Small Secondary

+ Outline Secondary + + Outline Secondary + + +

Growing Secondary

+ + Growing Secondary Outline + +
+ )) + .add('Inverse', () => ( +
+

Large Inverse

+
+ + Outline Inverse + + + Outline Inverse + + + Outline Inverse + + + Outline Inverse + +
+ +

Medium Inverse

+
+ + Outline Inverse + + + Outline Inverse + + + Outline Inverse + + + Outline Inverse + +
+ +

Small Inverse

+
+ + Outline Inverse + + + Outline Inverse + +
+ +

Growing Inverse

+
+ + Growing Inverse Outline + +
+
+ )); diff --git a/modules/button/react/stories/stories_TextButton.tsx b/modules/button/react/stories/stories_TextButton.tsx new file mode 100644 index 0000000000..aa3f0eba3d --- /dev/null +++ b/modules/button/react/stories/stories_TextButton.tsx @@ -0,0 +1,125 @@ +/// +/** @jsx jsx */ +import {jsx, CSSObject} from '@emotion/core'; +import {storiesOf} from '@storybook/react'; +import withReadme from 'storybook-readme/with-readme'; + +import {editIcon, arrowRightIcon} from '@workday/canvas-system-icons-web'; + +import {TextButton} from '../index'; +import README from '../README.md'; + +const blueBackground: CSSObject = { + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + flexWrap: 'wrap', + backgroundColor: '#0875e1', + margin: '0 10px', + padding: '12px', + maxWidth: 'max-content', + borderRadius: '3px', + button: { + margin: '12px', + }, +}; + +const buttonContainer = { + display: 'flex', + alignItems: 'center', + '& button + button': { + marginLeft: 10, + }, +}; + +storiesOf('Components|Buttons/Button/React/Text', module) + .addParameters({component: TextButton}) + .addDecorator(withReadme(README)) + .add('Default', () => ( +
+

Medium Large

+ + Text + + + Text + + +

Small

+ + Text + + + Text + + +

All Caps

+ All Caps + +

Icons

+
+ + Left Icon + + + Right Icon + +
+
+ )) + .add('Inverse', () => ( +
+

Medium Inverse

+
+ + Text + + + Text + +
+ +

Small Inverse

+
+ + Text + + + Text + +
+ +

All Caps Inverse

+
+ + All Caps + +
+ +

Icons Inverse

+
+ + Left Icon + + + Right Icon + +
+
+ )); diff --git a/modules/button/react/stories/stories_deprecated.tsx b/modules/button/react/stories/stories_deprecatedButton.tsx similarity index 99% rename from modules/button/react/stories/stories_deprecated.tsx rename to modules/button/react/stories/stories_deprecatedButton.tsx index 9cb037eafd..6d2b16685a 100644 --- a/modules/button/react/stories/stories_deprecated.tsx +++ b/modules/button/react/stories/stories_deprecatedButton.tsx @@ -16,6 +16,7 @@ storiesOf('Components|Buttons/Button/React/Deprecated', module) +

Medium Primary

+

Small Primary

+

Growing Primary

+

Medium Secondary

+

Small Secondary

+

Growing Secondary

+

Medium Delete

+

Small Delete

+

Growing Delete

- - )} + {renderFn} ); -const DropdownButtonStates = () => ( - - + getButtonStates( + { + variant: [ + {value: Button.Variant.Primary, label: 'Primary'}, + {value: Button.Variant.Secondary, label: 'Secondary'}, + ], + size: [ + {value: Button.Size.Small, label: 'Small'}, + {value: Button.Size.Medium, label: 'Medium'}, + {value: Button.Size.Large, label: 'Large'}, + ], + icon: [{value: undefined, label: ''}, {value: playCircleIcon, label: 'w/ Icon'}], + dataLabel: [{value: undefined, label: ''}, {value: '1:23', label: 'w/ Data Label'}], + }, + (props: any) => ( + + + + ) + ) + ); + +storiesOf('Components|Buttons/Button/React/Visual Testing/Delete Button', module) + .addParameters({ + component: DeleteButton, + chromatic: { + disable: false, + }, + }) + .add('States', () => + getButtonStates( + { + size: [ + {value: DeleteButton.Size.Small, label: 'Small'}, + {value: DeleteButton.Size.Medium, label: 'Medium'}, + {value: DeleteButton.Size.Large, label: 'Large'}, + ], + }, + (props: any) => ( + + Test + + ) + ) + ); + +storiesOf('Components|Buttons/Button/React/Visual Testing/Deprecated Button', module) + .addParameters({ + component: DeprecatedButton, + chromatic: { + disable: false, + }, + }) + .add('States', () => + getButtonStates( + { + variant: [ + {value: DeprecatedButton.Variant.Primary, label: 'Primary'}, + {value: DeprecatedButton.Variant.Secondary, label: 'Secondary'}, + {value: DeprecatedButton.Variant.Delete, label: 'Delete'}, + ], + size: [ + {value: Button.Size.Small, label: 'Small'}, + {value: Button.Size.Medium, label: 'Medium'}, + {value: Button.Size.Large, label: 'Large'}, + ], + }, + (props: any) => ( + + Test + + ) + ) + ); + +storiesOf('Components|Buttons/Button/React/Visual Testing/Dropdown Button', module) + .addParameters({ + component: DropdownButton, + chromatic: { + disable: false, + }, + }) + .add('States', () => + getButtonStates( + { variant: [ {value: DropdownButton.Variant.Primary, label: 'Primary'}, {value: DropdownButton.Variant.Secondary, label: 'Secondary'}, @@ -101,176 +164,101 @@ const DropdownButtonStates = () => ( {value: DropdownButton.Size.Medium, label: 'Medium'}, {value: DropdownButton.Size.Large, label: 'Large'}, ], - })} - columnProps={permutateProps( - { - className: [ - {label: 'Default', value: ''}, - {label: 'Hover', value: 'hover'}, - {label: 'Focus', value: 'focus'}, - {label: 'Focus Hover', value: 'focus hover'}, - {label: 'Active', value: 'active'}, - {label: 'Active Hover', value: 'active hover'}, - ], - disabled: [{label: '', value: false}, {label: 'Disabled', value: true}], - }, - props => { - if (props.disabled && !['', 'hover'].includes(props.className)) { - return false; - } - return true; - } - )} - > - {props => ( + icon: [{value: undefined, label: ''}, {value: playCircleIcon, label: 'w/ Icon'}], + dataLabel: [{value: undefined, label: ''}, {value: '1:23', label: 'w/ Data Label'}], + }, + (props: any) => ( Test - )} - - -); + ) + ) + ); -const TextButtonStates = () => ( - - { - return true; - } - )} - columnProps={permutateProps( - { - className: [ - {label: 'Default', value: ''}, - {label: 'Hover', value: 'hover'}, - {label: 'Focus', value: 'focus'}, - {label: 'Focus Hover', value: 'focus hover'}, - {label: 'Active', value: 'active'}, - {label: 'Active Hover', value: 'active hover'}, - ], - disabled: [{label: '', value: false}, {label: 'Disabled', value: true}], - }, - props => { - if (props.disabled && !['', 'hover'].includes(props.className)) { - return false; - } - return true; - } - )} - > - {props => ( - - Test - - )} - - -); - -const IconButtonStates = () => ( - - {[false, true].map(toggled => ( -
-

Toggled {toggled ? 'On' : 'Off'}

- - { - if (props.disabled && !['', 'hover'].includes(props.className)) { - return false; - } - return true; - } - )} - > - {props => ( - - {}} // eslint-disable-line no-empty-function - /> - - )} - - -
- ))} -
-); - -storiesOf('Components|Buttons/Button/React/Visual Testing/Button', module) +storiesOf('Components|Buttons/Button/React/Visual Testing/Highlight Button', module) .addParameters({ - component: Button, + component: HighlightButton, chromatic: { disable: false, }, }) - .add('States', () => ); + .add('States', () => + getButtonStates( + { + size: [ + {value: Button.Size.Small, label: 'Small'}, + {value: Button.Size.Medium, label: 'Medium'}, + {value: Button.Size.Large, label: 'Large'}, + ], + icon: [{value: undefined, label: ''}, {value: playCircleIcon, label: 'w/ Icon'}], + }, + (props: any) => ( + + Test + + ) + ) + ); -storiesOf('Components|Buttons/Button/React/Visual Testing/Dropdown', module) +storiesOf('Components|Buttons/Button/React/Visual Testing/Outline Button', module) .addParameters({ - component: DropdownButton, + component: Button, chromatic: { disable: false, }, }) - .add('States', () => ); + .add('States', () => + getButtonStates( + { + variant: [ + {value: OutlineButton.Variant.Primary, label: 'Outline Primary'}, + {value: OutlineButton.Variant.Secondary, label: 'Outline Secondary'}, + {value: OutlineButton.Variant.Inverse, label: 'Outline Inverse'}, + ], + size: [ + {value: Button.Size.Small, label: 'Small'}, + {value: Button.Size.Medium, label: 'Medium'}, + {value: Button.Size.Large, label: 'Large'}, + ], + icon: [{value: undefined, label: ''}, {value: playCircleIcon, label: 'w/ Icon'}], + dataLabel: [{value: undefined, label: ''}, {value: '1:23', label: 'w/ Data Label'}], + }, + (props: any) => ( + + Test + + ) + ) + ); -storiesOf('Components|Buttons/Button/React/Visual Testing/Text', module) +storiesOf('Components|Buttons/Button/React/Visual Testing/Text Button', module) .addParameters({ component: TextButton, chromatic: { disable: false, }, }) - .add('States', () => ); + .add('States', () => + getButtonStates( + { + variant: [ + {value: TextButton.Variant.Default, label: 'Default'}, + {value: TextButton.Variant.Inverse, label: 'Inverse'}, + ], + size: [ + {value: TextButton.Size.Small, label: 'Small'}, + {value: TextButton.Size.Medium, label: 'Medium'}, + ], + icon: [{value: undefined, label: ''}, {value: playCircleIcon, label: 'w/ Icon'}], + allCaps: [{value: undefined, label: ''}, {value: true, label: 'All Caps'}], + }, + (props: any) => ( + + Test + + ) + ) + ); storiesOf('Components|Buttons/Button/React/Visual Testing/Icon Button', module) .addParameters({ @@ -279,4 +267,44 @@ storiesOf('Components|Buttons/Button/React/Visual Testing/Icon Button', module) disable: false, }, }) - .add('States', () => ); + .add('States', () => ( + + {[false, true].map(toggled => ( +
+

Toggled {toggled ? 'On' : 'Off'}

+ {getButtonStates( + { + variant: [ + {value: IconButton.Variant.Inverse, label: 'Inverse'}, + {value: IconButton.Variant.InverseFilled, label: 'Inverse Filled'}, + {value: IconButton.Variant.Plain, label: 'Plain'}, + {value: IconButton.Variant.Circle, label: 'Circle'}, + {value: IconButton.Variant.CircleFilled, label: 'Circle Filled'}, + {value: IconButton.Variant.Square, label: 'Square'}, + {value: IconButton.Variant.SquareFilled, label: 'Square Filled'}, + ], + size: [ + {value: IconButton.Size.Small, label: 'Small'}, + {value: IconButton.Size.Medium, label: 'Medium'}, + ], + }, + (props: any) => ( + + {}} // eslint-disable-line no-empty-function + /> + + ) + )} +
+ ))} +
+ )); diff --git a/modules/button/react/tsconfig.cjs.json b/modules/button/react/tsconfig.cjs.json new file mode 100644 index 0000000000..261641fcc9 --- /dev/null +++ b/modules/button/react/tsconfig.cjs.json @@ -0,0 +1,11 @@ + +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "declaration": true, + "module": "commonjs", + "outDir": "dist/commonjs", + "skipLibCheck": true, + "tsBuildInfoFile": "./.build-info/tsconfig.cjs.tsbuildinfo" + } +} diff --git a/modules/button/react/tsconfig.es6.json b/modules/button/react/tsconfig.es6.json index 601797a826..cdf8edae25 100644 --- a/modules/button/react/tsconfig.es6.json +++ b/modules/button/react/tsconfig.es6.json @@ -1,3 +1,4 @@ + { "extends": "./tsconfig.json", "compilerOptions": { diff --git a/modules/modal/react/stories/stories.tsx b/modules/modal/react/stories/stories.tsx index 0bfaaf399b..ec23aa7ce4 100644 --- a/modules/modal/react/stories/stories.tsx +++ b/modules/modal/react/stories/stories.tsx @@ -3,7 +3,7 @@ import * as React from 'react'; import {storiesOf} from '@storybook/react'; import withReadme from 'storybook-readme/with-readme'; -import {Button} from '../../../button/react'; +import {Button, DeleteButton} from '../../../button/react'; import Modal, {useModal} from '..'; import README from '../README.md'; @@ -22,14 +22,14 @@ const DefaultModalExample = () => { return ( <> - +

Are you sure you'd like to delete the item titled 'My Item'?

- + @@ -43,14 +43,12 @@ const UseModalExample = () => { return ( <> - + Delete Item

Are you sure you'd like to delete the item titled 'My Item'?

- + @@ -64,9 +62,7 @@ const NoCloseModalExample = () => { return ( <> - + Delete Item { handleClose={undefined} >

Are you sure you'd like to delete the item titled 'My Item'?

- + @@ -91,9 +87,7 @@ const CustomFocusModalExample = () => { return ( <> - + Delete Item { handleClose={undefined} >

Are you sure you'd like to delete the item titled 'My Item'?

- +