From 750af7502535ab431effba9a3a958c6364d4c0e7 Mon Sep 17 00:00:00 2001 From: Will Seabrook Date: Fri, 20 Oct 2023 15:37:16 +0100 Subject: [PATCH] docs(storybook): upgrade storybook to v7 --- .eslintrc | 51 +- .storybook/{main.js => main.ts} | 43 +- .storybook/{manager.js => manager.ts} | 17 +- .storybook/modes.js | 11 + .storybook/{preview.js => preview.ts} | 16 +- .storybook/sageStorybookTheme.ts | 16 + .storybook/utils/styled-system-props.js | 903 - .storybook/utils/styled-system-props.ts | 1050 + .storybook/utils/translation-keys-table.js | 31 - .storybook/utils/translation-keys-table.tsx | 121 + .../get-started/get-started.component.js | 2 +- .../welcome-page/header/header.component.js | 4 +- .vscode/settings.json | 19 + CONTRIBUTING.md | 6 +- README.md | 2 +- {docs => contributing}/codebase-overview.md | 0 .../dev-environment-setup.md | 0 {docs => contributing}/testing-guide.md | 0 .../button-toggle/button-toggle.cy.tsx | 825 - cypress/locators/button-toggle-group/index.js | 2 +- .../locators/button-toggle-group/locators.js | 2 +- cypress/locators/button-toggle/index.js | 2 +- cypress/locators/button-toggle/locators.js | 2 +- cypress/webpack.config.js | 9 + ...undle-size.stories.mdx => bundle-size.mdx} | 2 + docs/{colors.stories.mdx => colors.mdx} | 122 +- ...tories.mdx => component-dos-and-donts.mdx} | 12 +- ...ending-styles-using-styled-components.mdx} | 31 +- ...styles-using-styled-components.stories.tsx | 37 + ...bute.stories.mdx => how-to-contribute.mdx} | 2 + docs/{i18n.stories.mdx => i18n.mdx} | 2 + ...tallation.stories.mdx => installation.mdx} | 3 + docs/{roadmap.stories.mdx => roadmap.mdx} | 2 + ...ing.stories.mdx => usage-with-routing.mdx} | 4 +- docs/{usage.stories.mdx => usage.mdx} | 6 +- docs/using-draft-js.mdx | 138 + docs/using-draft-js.stories.mdx | 119 - ...alidations.stories.mdx => validations.mdx} | 130 +- docs/validations.stories.tsx | 120 + package-lock.json | 46643 +++++++++------- package.json | 54 +- src/__spec_helper__/test-utils.ts | 9 +- .../accordion-group.stories.tsx | 33 + .../{accordion.stories.mdx => accordion.mdx} | 153 +- .../accordion/accordion.stories.tsx | 86 +- .../action-popover-item.stories.tsx | 23 + .../action-popover-menu-button.stories.tsx | 23 + .../action-popover-menu.stories.tsx | 25 + ...popover.stories.mdx => action-popover.mdx} | 132 +- .../action-popover/action-popover.pw.tsx | 84 +- .../action-popover/action-popover.stories.tsx | 858 +- .../action-popover/components.test-pw.tsx | 662 +- ....stories.mdx => advanced-color-picker.mdx} | 31 +- .../advanced-color-picker.stories.tsx | 48 +- .../alert/{alert.stories.mdx => alert.mdx} | 22 +- src/components/alert/alert.stories.tsx | 44 +- .../anchor-navigation-item.stories.tsx | 25 + .../anchor-navigation-test.stories.tsx | 15 +- ...tion.stories.mdx => anchor-navigation.mdx} | 51 +- .../anchor-navigation.stories.tsx | 154 + .../badge/{badge.stories.mdx => badge.mdx} | 42 +- src/components/badge/badge.stories.tsx | 119 +- ...ection.stories.mdx => batch-selection.mdx} | 37 +- .../batch-selection.stories.tsx | 161 +- .../box/{box.stories.mdx => box.mdx} | 63 +- src/components/box/box.stories.tsx | 102 +- ...readcrumbs.stories.mdx => breadcrumbs.mdx} | 35 +- .../breadcrumbs/breadcrumbs.stories.tsx | 22 +- .../breadcrumbs/crumb/crumb.stories.tsx | 25 + src/components/button-bar/button-bar.mdx | 72 + .../button-bar/button-bar.stories.mdx | 103 - .../button-bar/button-bar.stories.tsx | 245 +- .../button-minor/button-minor.component.tsx | 4 + src/components/button-minor/button-minor.mdx | 130 + .../button-minor/button-minor.pw.tsx | 4 +- .../button-minor/button-minor.stories.mdx | 241 - .../button-minor/button-minor.stories.tsx | 788 +- .../button-minor/components.test-pw.tsx | 425 + .../button-toggle-group.stories.tsx | 190 +- .../button-toggle/button-toggle.mdx | 132 + .../button-toggle/button-toggle.stories.mdx | 179 - .../button-toggle/button-toggle.stories.tsx | 568 +- src/components/button/button.mdx | 223 + src/components/button/button.stories.mdx | 316 - src/components/button/button.stories.tsx | 149 +- ...ovider.stories.mdx => carbon-provider.mdx} | 23 +- .../carbon-provider/carbon-provider.pw.tsx | 3 +- .../carbon-provider.stories.tsx | 39 +- .../carbon-provider/components.test-pw.tsx | 16 + .../card/card-column/card-column.stories.tsx | 25 + .../card/card-footer/card-footer.stories.tsx | 33 + .../card/card-row/card-row.stories.tsx | 33 + src/components/card/card.mdx | 124 + src/components/card/card.pw.tsx | 18 +- src/components/card/card.stories.mdx | 161 - src/components/card/card.stories.tsx | 1170 +- src/components/card/components.test-pw.tsx | 720 +- src/components/carousel/carousel.mdx | 62 + src/components/carousel/carousel.stories.mdx | 66 - src/components/carousel/carousel.stories.tsx | 259 +- .../carousel/slide/slide.stories.tsx | 23 + .../checkbox-group.component.tsx | 20 +- .../checkbox-group.spec.tsx | 16 +- .../checkbox-group/checkbox-group.stories.tsx | 33 + .../checkbox-group.style.ts | 10 +- .../checkbox/checkbox-validations.stories.mdx | 94 - .../checkbox/checkbox-validations.stories.tsx | 473 - .../checkbox/checkbox.component.tsx | 2 +- .../{checkbox.stories.mdx => checkbox.mdx} | 78 +- src/components/checkbox/checkbox.pw.tsx | 4 +- src/components/checkbox/checkbox.stories.tsx | 209 +- .../checkbox/components.test-pw.tsx | 33 + src/components/checkbox/index.ts | 4 +- .../checkbox/validations.stories.tsx | 193 + .../{confirm.stories.mdx => confirm.mdx} | 68 +- src/components/confirm/confirm.stories.tsx | 69 +- .../content/content-test.stories.mdx | 59 - .../{content.stories.mdx => content.mdx} | 31 +- src/components/content/content.stories.tsx | 61 +- ...{date-range.stories.mdx => date-range.mdx} | 77 +- .../date-range/date-range.stories.tsx | 68 +- .../date/{date.stories.mdx => date.mdx} | 124 +- src/components/date/date.stories.tsx | 103 +- src/components/decimal/decimal.mdx | 151 + src/components/decimal/decimal.stories.mdx | 220 - src/components/decimal/decimal.stories.tsx | 318 +- .../definition-list/components.test-pw.tsx | 6 +- .../definition-list/{ => dd}/dd.component.tsx | 4 +- .../definition-list/dd/dd.stories.tsx | 36 + .../definition-list-test.stories.tsx | 6 +- ...n-list.stories.mdx => definition-list.mdx} | 40 +- .../definition-list/definition-list.pw.tsx | 4 +- .../definition-list/definition-list.spec.tsx | 4 +- .../definition-list.stories.tsx | 43 +- .../definition-list/dl.component.tsx | 21 +- .../definition-list/{ => dt}/dt.component.tsx | 4 +- .../definition-list/dt/dt.stories.tsx | 36 + src/components/definition-list/index.ts | 8 +- .../detail/{detail.stories.mdx => detail.mdx} | 31 +- src/components/detail/detail.stories.tsx | 38 +- ...een.stories.mdx => dialog-full-screen.mdx} | 82 +- .../dialog-full-screen.stories.tsx | 65 +- src/components/dialog/components.test-pw.tsx | 463 +- .../dialog/{dialog.stories.mdx => dialog.mdx} | 95 +- src/components/dialog/dialog.pw.tsx | 6 +- src/components/dialog/dialog.stories.tsx | 79 +- .../dismissible-box/dismissible-box.mdx | 51 + .../dismissible-box.stories.mdx | 63 - .../dismissible-box.stories.tsx | 118 +- .../drop-target.component.tsx | 2 +- .../draggable/components.test-pw.tsx | 5 +- .../draggable-container.component.tsx | 4 +- .../draggable-item.component.tsx | 2 +- .../draggable-item/draggable-item.stories.tsx | 36 + .../draggable-item.style.ts | 4 +- .../draggable/draggable-test.stories.tsx | 2 +- .../{draggable.stories.mdx => draggable.mdx} | 41 +- src/components/draggable/draggable.spec.tsx | 6 +- .../draggable/draggable.stories.tsx | 39 +- src/components/draggable/index.ts | 4 +- src/components/drawer/drawer.mdx | 120 + src/components/drawer/drawer.stories.mdx | 169 - src/components/drawer/drawer.stories.tsx | 66 +- .../duelling-picklist-test.stories.tsx | 2 +- ...list.stories.mdx => duelling-picklist.mdx} | 62 +- .../duelling-picklist.stories.tsx | 137 +- .../picklist-item/picklist-item.stories.tsx | 26 + .../picklist-placeholder.component.tsx | 12 +- .../picklist-placeholder.stories.tsx | 25 + .../picklist/picklist.stories.tsx | 26 + src/components/fieldset/fieldset-examples.mdx | 39 + .../fieldset/fieldset-examples.stories.mdx | 50 - .../fieldset/fieldset-examples.stories.tsx | 192 +- src/components/fieldset/fieldset.mdx | 58 + src/components/fieldset/fieldset.stories.mdx | 73 - src/components/fieldset/fieldset.stories.tsx | 39 +- .../file-upload-status.stories.tsx | 25 + ...{file-input.stories.mdx => file-input.mdx} | 103 +- .../file-input/file-input.stories.tsx | 62 +- .../flat-table-body-draggable.stories.tsx | 26 + .../flat-table-body.stories.tsx | 26 + .../flat-table-cell.stories.tsx | 33 + .../flat-table-checkbox.stories.tsx | 23 + .../flat-table/flat-table-expandable.mdx | 96 + .../flat-table-expandable.stories.mdx | 144 - .../flat-table-expandable.stories.tsx | 142 +- .../flat-table-head.stories.tsx | 26 + .../flat-table-header.component.tsx | 6 +- .../flat-table-header.stories.tsx | 36 + .../flat-table-row-header.stories.tsx | 36 + .../flat-table-row/flat-table-row.stories.tsx | 25 + .../flat-table/flat-table-test.stories.tsx | 10 +- .../flat-table/flat-table-themes.mdx | 24 + .../flat-table/flat-table-themes.stories.mdx | 41 - .../flat-table/flat-table-themes.stories.tsx | 25 +- ...{flat-table.stories.mdx => flat-table.mdx} | 208 +- .../flat-table/flat-table.stories.tsx | 2125 +- .../flat-table/sort/sort.component.tsx | 2 +- .../flat-table/sort/sort.stories.tsx | 25 + .../form/{form.stories.mdx => form.mdx} | 86 +- src/components/form/form.stories.tsx | 99 +- .../global-header/global-header.mdx | 68 + .../global-header/global-header.stories.mdx | 94 - .../global-header/global-header.stories.tsx | 54 +- .../grid-container/grid-container.stories.tsx | 33 + .../grid/grid-item/grid-item.stories.tsx | 33 + src/components/grid/grid.mdx | 135 + src/components/grid/grid.stories.mdx | 509 - src/components/grid/grid.stories.tsx | 382 + .../grouped-character-test.stories.tsx | 2 +- .../grouped-character/grouped-character.mdx | 128 + .../grouped-character.stories.mdx | 207 - .../grouped-character.stories.tsx | 159 +- src/components/heading/heading.mdx | 97 + src/components/heading/heading.stories.mdx | 138 - src/components/heading/heading.stories.tsx | 305 +- .../help/{help.stories.mdx => help.mdx} | 44 +- src/components/help/help.stories.tsx | 93 +- src/components/hr/{hr.stories.mdx => hr.mdx} | 36 +- src/components/hr/hr.stories.tsx | 163 +- src/components/icon-button/icon-button.mdx | 35 + .../icon-button/icon-button.stories.mdx | 45 - .../icon-button/icon-button.stories.tsx | 62 +- .../icon/{icon.stories.mdx => icon.mdx} | 62 +- src/components/icon/icon.stories.tsx | 158 +- .../image/{image.stories.mdx => image.mdx} | 50 +- src/components/image/image.stories.tsx | 86 +- .../inline-inputs/components.test-pw.tsx | 89 + .../inline-inputs/inline-inputs.mdx | 45 + .../inline-inputs/inline-inputs.pw.tsx | 2 +- .../inline-inputs/inline-inputs.stories.mdx | 72 - .../inline-inputs/inline-inputs.stories.tsx | 40 +- ...k-preview.stories.mdx => link-preview.mdx} | 22 +- .../link-preview/link-preview.stories.tsx | 24 +- .../link/{link.stories.mdx => link.mdx} | 79 +- src/components/link/link.stories.tsx | 377 +- ...{loader-bar.stories.mdx => loader-bar.mdx} | 30 +- .../loader-bar/loader-bar.stories.tsx | 40 +- .../loader/{loader.stories.mdx => loader.mdx} | 45 +- src/components/loader/loader.stories.tsx | 105 +- .../menu-divider/menu-divider.stories.tsx | 24 + .../menu-full-screen.stories.tsx | 26 + .../menu/menu-item/menu-item.stories.tsx | 35 + .../menu-segment-title.stories.tsx | 23 + src/components/menu/menu-test.stories.tsx | 26 +- .../menu/{menu.stories.mdx => menu.mdx} | 122 +- src/components/menu/menu.stories.tsx | 817 +- .../scrollable-block.stories.tsx | 26 + .../{message.stories.mdx => message.mdx} | 56 +- src/components/message/message.stories.tsx | 64 +- .../multi-action-button.mdx | 107 + .../multi-action-button.stories.mdx | 117 - .../multi-action-button.stories.tsx | 165 +- .../navigation-bar/components.test-pw.tsx | 80 +- .../navigation-bar/navigation-bar.mdx | 91 + .../navigation-bar/navigation-bar.stories.mdx | 123 - .../navigation-bar/navigation-bar.stories.tsx | 338 +- .../note/{note.stories.mdx => note.mdx} | 55 +- src/components/note/note.stories.tsx | 67 +- src/components/number/number.component.tsx | 22 +- src/components/number/number.mdx | 94 + src/components/number/number.stories.mdx | 124 - src/components/number/number.stories.tsx | 112 +- ...eral-date.stories.mdx => numeral-date.mdx} | 62 +- .../numeral-date/numeral-date.stories.tsx | 137 +- .../pager/{pager.stories.mdx => pager.mdx} | 69 +- src/components/pager/pager.stories.tsx | 138 +- src/components/pages/page/page.stories.tsx | 33 + src/components/pages/pages.mdx | 50 + src/components/pages/pages.spec.tsx | 10 +- src/components/pages/pages.stories.mdx | 64 - src/components/pages/pages.stories.tsx | 39 +- src/components/password/password.mdx | 179 + src/components/password/password.stories.mdx | 248 - src/components/password/password.stories.tsx | 100 +- .../pill/{pill.stories.mdx => pill.mdx} | 57 +- src/components/pill/pill.stories.tsx | 78 +- src/components/pod/pod.mdx | 143 + src/components/pod/pod.stories.mdx | 198 - src/components/pod/pod.stories.tsx | 393 +- ...iner.stories.mdx => popover-container.mdx} | 69 +- .../popover-container.stories.tsx | 198 +- .../render-close/render-close.stories.tsx | 23 + .../render-open/render-open.stories.tsx | 23 + src/components/portal/portal.mdx | 39 + src/components/portal/portal.stories.mdx | 64 - src/components/portal/portal.stories.tsx | 23 + src/components/portal/portal.tsx | 2 +- .../{portrait.stories.mdx => portrait.mdx} | 57 +- src/components/portrait/portrait.stories.tsx | 119 +- src/components/preview/preview.component.tsx | 2 +- src/components/preview/preview.mdx | 49 + src/components/preview/preview.stories.mdx | 99 - src/components/preview/preview.stories.tsx | 52 +- .../{profile.stories.mdx => profile.mdx} | 42 +- src/components/profile/profile.stories.tsx | 83 +- ...acker.stories.mdx => progress-tracker.mdx} | 69 +- .../progress-tracker.stories.tsx | 69 +- .../radio-button/components.test-pw.tsx | 642 +- src/components/radio-button/index.ts | 5 +- .../radio-button-group.component.tsx | 26 +- .../radio-button-group.spec.tsx | 16 +- .../radio-button-group.stories.tsx | 33 + .../radio-button-group.style.ts | 0 .../radio-button-test.stories.tsx | 40 +- ...io-button.stories.mdx => radio-button.mdx} | 87 +- .../radio-button/radio-button.pw.tsx | 2 +- .../radio-button/radio-button.stories.tsx | 875 +- .../search/{search.stories.mdx => search.mdx} | 100 +- src/components/search/search.stories.tsx | 138 +- ...lect.stories.mdx => filterable-select.mdx} | 105 +- .../filterable-select.stories.tsx | 714 +- ...ti-select.stories.mdx => multi-select.mdx} | 87 +- .../multi-select/multi-select.stories.tsx | 632 +- .../select/option/option.stories.tsx | 25 + .../select-textbox/select-textbox.stories.tsx | 25 + .../simple-select/simple-select-sizes.mdx | 21 + .../simple-select-sizes.stories.mdx | 27 - .../simple-select-sizes.stories.tsx | 147 +- ...e-select.stories.mdx => simple-select.mdx} | 121 +- .../simple-select/simple-select.stories.tsx | 843 +- .../settings-row-test.stories.tsx | 2 +- ...tings-row.stories.mdx => settings-row.mdx} | 21 +- .../settings-row/settings-row.stories.tsx | 110 +- .../{sidebar.stories.mdx => sidebar.mdx} | 77 +- src/components/sidebar/sidebar.stories.tsx | 77 +- .../simple-color-picker.mdx | 71 + .../simple-color-picker.stories.mdx | 80 - .../simple-color-picker.stories.tsx | 31 +- .../simple-color/simple-color.stories.tsx | 23 + src/components/split-button/split-button.mdx | 100 + .../split-button/split-button.stories.mdx | 125 - .../split-button/split-button.stories.tsx | 111 +- .../{step-flow.stories.mdx => step-flow.mdx} | 83 +- .../step-flow/step-flow.stories.tsx | 161 +- .../step-sequence-item.stories.tsx | 23 + .../step-sequence/step-sequence.mdx | 77 + .../step-sequence/step-sequence.stories.mdx | 83 - .../step-sequence/step-sequence.stories.tsx | 248 +- src/components/switch/components.test-pw.tsx | 22 + .../switch/{switch.stories.mdx => switch.mdx} | 120 +- src/components/switch/switch.pw.tsx | 2 +- src/components/switch/switch.stories.tsx | 165 +- src/components/tabs/components.test-pw.tsx | 373 +- src/components/tabs/tab/tab.stories.tsx | 33 + .../tabs/{tabs.stories.mdx => tabs.mdx} | 196 +- src/components/tabs/tabs.pw.tsx | 5 +- src/components/tabs/tabs.stories.tsx | 100 +- .../text-editor/components.test-pw.tsx | 31 +- ...ext-editor.stories.mdx => text-editor.mdx} | 81 +- src/components/text-editor/text-editor.pw.tsx | 2 +- .../text-editor/text-editor.stories.tsx | 74 +- .../textarea/components.test-pw.tsx | 28 +- .../{textarea.stories.mdx => textarea.mdx} | 169 +- src/components/textarea/textarea.stories.tsx | 125 +- src/components/textbox/textbox.component.tsx | 13 +- .../{textbox.stories.mdx => textbox.mdx} | 158 +- src/components/textbox/textbox.stories.tsx | 134 +- src/components/tile-select/index.ts | 4 +- .../tile-select-group.component.tsx | 10 +- .../tile-select-group.stories.tsx | 33 + ...ile-select.stories.mdx => tile-select.mdx} | 65 +- .../tile-select/tile-select.stories.tsx | 50 +- .../flex-tile-cell/flex-tile-cell.stories.tsx | 37 + .../flex-tile-container.stories.tsx | 25 + .../tile/tile-footer/tile-footer.stories.tsx | 33 + .../tile/tile-header/tile-header.stories.tsx | 33 + .../tile/{tile.stories.mdx => tile.mdx} | 206 +- src/components/tile/tile.stories.tsx | 1528 +- .../time/{time.stories.mdx => time.mdx} | 81 +- src/components/time/time.stories.tsx | 75 +- .../toast/{toast.stories.mdx => toast.mdx} | 112 +- src/components/toast/toast.stories.tsx | 156 +- .../{tooltip.stories.mdx => tooltip.mdx} | 47 +- src/components/tooltip/tooltip.stories.tsx | 34 +- ...{typography.stories.mdx => typography.mdx} | 29 +- .../typography/typography.stories.tsx | 39 +- .../vertical-divider-test.stories.tsx | 2 +- ...vider.stories.mdx => vertical-divider.mdx} | 56 +- .../vertical-divider.stories.tsx | 504 +- src/components/vertical-menu/index.ts | 12 +- .../vertical-menu-full-screen.component.tsx | 22 +- .../vertical-menu-full-screen.context.ts | 0 .../vertical-menu-full-screen.spec.tsx | 14 +- .../vertical-menu-full-screen.stories.tsx | 25 + .../vertical-menu-item.component.tsx | 12 +- .../vertical-menu-item.spec.tsx | 14 +- .../vertical-menu-item.stories.tsx | 33 + .../vertical-menu-test.stories.tsx | 2 +- .../vertical-menu-trigger.component.tsx | 8 +- .../vertical-menu-trigger.spec.tsx | 8 +- .../vertical-menu-trigger.stories.tsx | 31 + ...cal-menu.stories.mdx => vertical-menu.mdx} | 67 +- .../vertical-menu/vertical-menu.pw.tsx | 2 +- .../vertical-menu/vertical-menu.stories.tsx | 323 +- ...-query.stories.mdx => use-media-query.mdx} | 26 +- .../useMediaQuery/use-media-query.stories.tsx | 31 + tsconfig.json | 10 +- 398 files changed, 49139 insertions(+), 41352 deletions(-) rename .storybook/{main.js => main.ts} (59%) rename .storybook/{manager.js => manager.ts} (56%) create mode 100644 .storybook/modes.js rename .storybook/{preview.js => preview.ts} (82%) create mode 100644 .storybook/sageStorybookTheme.ts delete mode 100644 .storybook/utils/styled-system-props.js create mode 100644 .storybook/utils/styled-system-props.ts delete mode 100644 .storybook/utils/translation-keys-table.js create mode 100644 .storybook/utils/translation-keys-table.tsx rename {docs => contributing}/codebase-overview.md (100%) rename {docs => contributing}/dev-environment-setup.md (100%) rename {docs => contributing}/testing-guide.md (100%) delete mode 100644 cypress/components/button-toggle/button-toggle.cy.tsx rename docs/{bundle-size.stories.mdx => bundle-size.mdx} (95%) rename docs/{colors.stories.mdx => colors.mdx} (89%) rename docs/{component-dos-and-donts.stories.mdx => component-dos-and-donts.mdx} (91%) rename docs/{extending-styles-using-styled-components.stories.mdx => extending-styles-using-styled-components.mdx} (72%) create mode 100644 docs/extending-styles-using-styled-components.stories.tsx rename docs/{how-to-contribute.stories.mdx => how-to-contribute.mdx} (85%) rename docs/{i18n.stories.mdx => i18n.mdx} (96%) rename docs/{installation.stories.mdx => installation.mdx} (98%) rename docs/{roadmap.stories.mdx => roadmap.mdx} (97%) rename docs/{usage-with-routing.stories.mdx => usage-with-routing.mdx} (98%) rename docs/{usage.stories.mdx => usage.mdx} (91%) create mode 100644 docs/using-draft-js.mdx delete mode 100644 docs/using-draft-js.stories.mdx rename docs/{validations.stories.mdx => validations.mdx} (64%) create mode 100644 docs/validations.stories.tsx create mode 100644 src/components/accordion/accordion-group/accordion-group.stories.tsx rename src/components/accordion/{accordion.stories.mdx => accordion.mdx} (55%) create mode 100644 src/components/action-popover/action-popover-item/action-popover-item.stories.tsx create mode 100644 src/components/action-popover/action-popover-menu-button/action-popover-menu-button.stories.tsx create mode 100644 src/components/action-popover/action-popover-menu/action-popover-menu.stories.tsx rename src/components/action-popover/{action-popover.stories.mdx => action-popover.mdx} (58%) rename src/components/advanced-color-picker/{advanced-color-picker.stories.mdx => advanced-color-picker.mdx} (54%) rename src/components/alert/{alert.stories.mdx => alert.mdx} (68%) create mode 100644 src/components/anchor-navigation/anchor-navigation-item/anchor-navigation-item.stories.tsx rename src/components/anchor-navigation/{anchor-navigation.stories.mdx => anchor-navigation.mdx} (70%) create mode 100644 src/components/anchor-navigation/anchor-navigation.stories.tsx rename src/components/badge/{badge.stories.mdx => badge.mdx} (51%) rename src/components/batch-selection/{batch-selection.stories.mdx => batch-selection.mdx} (61%) rename src/components/box/{box.stories.mdx => box.mdx} (52%) rename src/components/breadcrumbs/{breadcrumbs.stories.mdx => breadcrumbs.mdx} (63%) create mode 100644 src/components/breadcrumbs/crumb/crumb.stories.tsx create mode 100644 src/components/button-bar/button-bar.mdx delete mode 100644 src/components/button-bar/button-bar.stories.mdx create mode 100644 src/components/button-minor/button-minor.mdx delete mode 100644 src/components/button-minor/button-minor.stories.mdx create mode 100644 src/components/button-toggle/button-toggle.mdx delete mode 100644 src/components/button-toggle/button-toggle.stories.mdx create mode 100644 src/components/button/button.mdx delete mode 100644 src/components/button/button.stories.mdx rename src/components/carbon-provider/{carbon-provider.stories.mdx => carbon-provider.mdx} (76%) create mode 100644 src/components/card/card-column/card-column.stories.tsx create mode 100644 src/components/card/card-footer/card-footer.stories.tsx create mode 100644 src/components/card/card-row/card-row.stories.tsx create mode 100644 src/components/card/card.mdx delete mode 100644 src/components/card/card.stories.mdx create mode 100644 src/components/carousel/carousel.mdx delete mode 100644 src/components/carousel/carousel.stories.mdx create mode 100644 src/components/carousel/slide/slide.stories.tsx rename src/components/checkbox/{ => checkbox-group}/checkbox-group.component.tsx (86%) rename src/components/checkbox/{ => checkbox-group}/checkbox-group.spec.tsx (93%) create mode 100644 src/components/checkbox/checkbox-group/checkbox-group.stories.tsx rename src/components/checkbox/{ => checkbox-group}/checkbox-group.style.ts (75%) delete mode 100644 src/components/checkbox/checkbox-validations.stories.mdx delete mode 100644 src/components/checkbox/checkbox-validations.stories.tsx rename src/components/checkbox/{checkbox.stories.mdx => checkbox.mdx} (58%) create mode 100644 src/components/checkbox/validations.stories.tsx rename src/components/confirm/{confirm.stories.mdx => confirm.mdx} (51%) delete mode 100644 src/components/content/content-test.stories.mdx rename src/components/content/{content.stories.mdx => content.mdx} (52%) rename src/components/date-range/{date-range.stories.mdx => date-range.mdx} (60%) rename src/components/date/{date.stories.mdx => date.mdx} (60%) create mode 100644 src/components/decimal/decimal.mdx delete mode 100644 src/components/decimal/decimal.stories.mdx rename src/components/definition-list/{ => dd}/dd.component.tsx (85%) create mode 100644 src/components/definition-list/dd/dd.stories.tsx rename src/components/definition-list/{definition-list.stories.mdx => definition-list.mdx} (55%) rename src/components/definition-list/{ => dt}/dt.component.tsx (86%) create mode 100644 src/components/definition-list/dt/dt.stories.tsx rename src/components/detail/{detail.stories.mdx => detail.mdx} (62%) rename src/components/dialog-full-screen/{dialog-full-screen.stories.mdx => dialog-full-screen.mdx} (63%) rename src/components/dialog/{dialog.stories.mdx => dialog.mdx} (63%) create mode 100644 src/components/dismissible-box/dismissible-box.mdx delete mode 100644 src/components/dismissible-box/dismissible-box.stories.mdx rename src/components/draggable/{internal => __internal__}/drop-target.component.tsx (90%) rename src/components/draggable/{ => draggable-item}/draggable-item.component.tsx (96%) create mode 100644 src/components/draggable/draggable-item/draggable-item.stories.tsx rename src/components/draggable/{ => draggable-item}/draggable-item.style.ts (90%) rename src/components/draggable/{draggable.stories.mdx => draggable.mdx} (57%) create mode 100644 src/components/drawer/drawer.mdx delete mode 100644 src/components/drawer/drawer.stories.mdx rename src/components/duelling-picklist/{duelling-picklist.stories.mdx => duelling-picklist.mdx} (66%) create mode 100644 src/components/duelling-picklist/picklist-item/picklist-item.stories.tsx create mode 100644 src/components/duelling-picklist/picklist-placeholder/picklist-placeholder.stories.tsx create mode 100644 src/components/duelling-picklist/picklist/picklist.stories.tsx create mode 100644 src/components/fieldset/fieldset-examples.mdx delete mode 100644 src/components/fieldset/fieldset-examples.stories.mdx create mode 100644 src/components/fieldset/fieldset.mdx delete mode 100644 src/components/fieldset/fieldset.stories.mdx create mode 100644 src/components/file-input/__internal__/file-upload-status/file-upload-status.stories.tsx rename src/components/file-input/{file-input.stories.mdx => file-input.mdx} (71%) create mode 100644 src/components/flat-table/flat-table-body-draggable/flat-table-body-draggable.stories.tsx create mode 100644 src/components/flat-table/flat-table-body/flat-table-body.stories.tsx create mode 100644 src/components/flat-table/flat-table-cell/flat-table-cell.stories.tsx create mode 100644 src/components/flat-table/flat-table-checkbox/flat-table-checkbox.stories.tsx create mode 100644 src/components/flat-table/flat-table-expandable.mdx delete mode 100644 src/components/flat-table/flat-table-expandable.stories.mdx create mode 100644 src/components/flat-table/flat-table-head/flat-table-head.stories.tsx create mode 100644 src/components/flat-table/flat-table-header/flat-table-header.stories.tsx create mode 100644 src/components/flat-table/flat-table-row-header/flat-table-row-header.stories.tsx create mode 100644 src/components/flat-table/flat-table-row/flat-table-row.stories.tsx create mode 100644 src/components/flat-table/flat-table-themes.mdx delete mode 100644 src/components/flat-table/flat-table-themes.stories.mdx rename src/components/flat-table/{flat-table.stories.mdx => flat-table.mdx} (56%) create mode 100644 src/components/flat-table/sort/sort.stories.tsx rename src/components/form/{form.stories.mdx => form.mdx} (62%) create mode 100644 src/components/global-header/global-header.mdx delete mode 100644 src/components/global-header/global-header.stories.mdx create mode 100644 src/components/grid/grid-container/grid-container.stories.tsx create mode 100644 src/components/grid/grid-item/grid-item.stories.tsx create mode 100644 src/components/grid/grid.mdx delete mode 100644 src/components/grid/grid.stories.mdx create mode 100644 src/components/grid/grid.stories.tsx create mode 100644 src/components/grouped-character/grouped-character.mdx delete mode 100644 src/components/grouped-character/grouped-character.stories.mdx create mode 100644 src/components/heading/heading.mdx delete mode 100644 src/components/heading/heading.stories.mdx rename src/components/help/{help.stories.mdx => help.mdx} (56%) rename src/components/hr/{hr.stories.mdx => hr.mdx} (54%) create mode 100644 src/components/icon-button/icon-button.mdx delete mode 100644 src/components/icon-button/icon-button.stories.mdx rename src/components/icon/{icon.stories.mdx => icon.mdx} (51%) rename src/components/image/{image.stories.mdx => image.mdx} (63%) create mode 100644 src/components/inline-inputs/components.test-pw.tsx create mode 100644 src/components/inline-inputs/inline-inputs.mdx delete mode 100644 src/components/inline-inputs/inline-inputs.stories.mdx rename src/components/link-preview/{link-preview.stories.mdx => link-preview.mdx} (65%) rename src/components/link/{link.stories.mdx => link.mdx} (60%) rename src/components/loader-bar/{loader-bar.stories.mdx => loader-bar.mdx} (68%) rename src/components/loader/{loader.stories.mdx => loader.mdx} (68%) create mode 100644 src/components/menu/menu-divider/menu-divider.stories.tsx create mode 100644 src/components/menu/menu-full-screen/menu-full-screen.stories.tsx create mode 100644 src/components/menu/menu-item/menu-item.stories.tsx create mode 100644 src/components/menu/menu-segment-title/menu-segment-title.stories.tsx rename src/components/menu/{menu.stories.mdx => menu.mdx} (58%) create mode 100644 src/components/menu/scrollable-block/scrollable-block.stories.tsx rename src/components/message/{message.stories.mdx => message.mdx} (69%) create mode 100644 src/components/multi-action-button/multi-action-button.mdx delete mode 100644 src/components/multi-action-button/multi-action-button.stories.mdx create mode 100644 src/components/navigation-bar/navigation-bar.mdx delete mode 100644 src/components/navigation-bar/navigation-bar.stories.mdx rename src/components/note/{note.stories.mdx => note.mdx} (66%) create mode 100644 src/components/number/number.mdx delete mode 100644 src/components/number/number.stories.mdx rename src/components/numeral-date/{numeral-date.stories.mdx => numeral-date.mdx} (63%) rename src/components/pager/{pager.stories.mdx => pager.mdx} (74%) create mode 100644 src/components/pages/page/page.stories.tsx create mode 100644 src/components/pages/pages.mdx delete mode 100644 src/components/pages/pages.stories.mdx create mode 100644 src/components/password/password.mdx delete mode 100644 src/components/password/password.stories.mdx rename src/components/pill/{pill.stories.mdx => pill.mdx} (56%) create mode 100644 src/components/pod/pod.mdx delete mode 100644 src/components/pod/pod.stories.mdx rename src/components/popover-container/{popover-container.stories.mdx => popover-container.mdx} (67%) create mode 100644 src/components/popover-container/render-close/render-close.stories.tsx create mode 100644 src/components/popover-container/render-open/render-open.stories.tsx create mode 100644 src/components/portal/portal.mdx delete mode 100644 src/components/portal/portal.stories.mdx create mode 100644 src/components/portal/portal.stories.tsx rename src/components/portrait/{portrait.stories.mdx => portrait.mdx} (53%) create mode 100644 src/components/preview/preview.mdx delete mode 100644 src/components/preview/preview.stories.mdx rename src/components/profile/{profile.stories.mdx => profile.mdx} (53%) rename src/components/progress-tracker/{progress-tracker.stories.mdx => progress-tracker.mdx} (65%) rename src/components/radio-button/{ => radio-button-group}/radio-button-group.component.tsx (87%) rename src/components/radio-button/{ => radio-button-group}/radio-button-group.spec.tsx (95%) create mode 100644 src/components/radio-button/radio-button-group/radio-button-group.stories.tsx rename src/components/radio-button/{ => radio-button-group}/radio-button-group.style.ts (100%) rename src/components/radio-button/{radio-button.stories.mdx => radio-button.mdx} (63%) rename src/components/search/{search.stories.mdx => search.mdx} (50%) rename src/components/select/filterable-select/{filterable-select.stories.mdx => filterable-select.mdx} (64%) rename src/components/select/multi-select/{multi-select.stories.mdx => multi-select.mdx} (61%) create mode 100644 src/components/select/option/option.stories.tsx create mode 100644 src/components/select/select-textbox/select-textbox.stories.tsx create mode 100644 src/components/select/simple-select/simple-select-sizes.mdx delete mode 100644 src/components/select/simple-select/simple-select-sizes.stories.mdx rename src/components/select/simple-select/{simple-select.stories.mdx => simple-select.mdx} (66%) rename src/components/settings-row/{settings-row.stories.mdx => settings-row.mdx} (60%) rename src/components/sidebar/{sidebar.stories.mdx => sidebar.mdx} (60%) create mode 100644 src/components/simple-color-picker/simple-color-picker.mdx delete mode 100644 src/components/simple-color-picker/simple-color-picker.stories.mdx create mode 100644 src/components/simple-color-picker/simple-color/simple-color.stories.tsx create mode 100644 src/components/split-button/split-button.mdx delete mode 100644 src/components/split-button/split-button.stories.mdx rename src/components/step-flow/{step-flow.stories.mdx => step-flow.mdx} (66%) create mode 100644 src/components/step-sequence/step-sequence-item/step-sequence-item.stories.tsx create mode 100644 src/components/step-sequence/step-sequence.mdx delete mode 100644 src/components/step-sequence/step-sequence.stories.mdx rename src/components/switch/{switch.stories.mdx => switch.mdx} (60%) create mode 100644 src/components/tabs/tab/tab.stories.tsx rename src/components/tabs/{tabs.stories.mdx => tabs.mdx} (62%) rename src/components/text-editor/{text-editor.stories.mdx => text-editor.mdx} (77%) rename src/components/textarea/{textarea.stories.mdx => textarea.mdx} (50%) rename src/components/textbox/{textbox.stories.mdx => textbox.mdx} (54%) rename src/components/tile-select/{ => tile-select-group}/tile-select-group.component.tsx (87%) create mode 100644 src/components/tile-select/tile-select-group/tile-select-group.stories.tsx rename src/components/tile-select/{tile-select.stories.mdx => tile-select.mdx} (71%) create mode 100644 src/components/tile/flex-tile-cell/flex-tile-cell.stories.tsx create mode 100644 src/components/tile/flex-tile-container/flex-tile-container.stories.tsx create mode 100644 src/components/tile/tile-footer/tile-footer.stories.tsx create mode 100644 src/components/tile/tile-header/tile-header.stories.tsx rename src/components/tile/{tile.stories.mdx => tile.mdx} (50%) rename src/components/time/{time.stories.mdx => time.mdx} (61%) rename src/components/toast/{toast.stories.mdx => toast.mdx} (57%) rename src/components/tooltip/{tooltip.stories.mdx => tooltip.mdx} (72%) rename src/components/typography/{typography.stories.mdx => typography.mdx} (70%) rename src/components/vertical-divider/{vertical-divider.stories.mdx => vertical-divider.mdx} (58%) rename src/components/vertical-menu/{ => vertical-menu-full-screen}/vertical-menu-full-screen.component.tsx (81%) rename src/components/vertical-menu/{ => vertical-menu-full-screen}/vertical-menu-full-screen.context.ts (100%) rename src/components/vertical-menu/{ => vertical-menu-full-screen}/vertical-menu-full-screen.spec.tsx (92%) create mode 100644 src/components/vertical-menu/vertical-menu-full-screen/vertical-menu-full-screen.stories.tsx rename src/components/vertical-menu/{ => vertical-menu-item}/vertical-menu-item.component.tsx (91%) rename src/components/vertical-menu/{ => vertical-menu-item}/vertical-menu-item.spec.tsx (96%) create mode 100644 src/components/vertical-menu/vertical-menu-item/vertical-menu-item.stories.tsx rename src/components/vertical-menu/{ => vertical-menu-trigger}/vertical-menu-trigger.component.tsx (80%) rename src/components/vertical-menu/{ => vertical-menu-trigger}/vertical-menu-trigger.spec.tsx (87%) create mode 100644 src/components/vertical-menu/vertical-menu-trigger/vertical-menu-trigger.stories.tsx rename src/components/vertical-menu/{vertical-menu.stories.mdx => vertical-menu.mdx} (61%) rename src/hooks/useMediaQuery/{use-media-query.stories.mdx => use-media-query.mdx} (53%) create mode 100644 src/hooks/useMediaQuery/use-media-query.stories.tsx diff --git a/.eslintrc b/.eslintrc index 7841263444..a861093076 100644 --- a/.eslintrc +++ b/.eslintrc @@ -93,7 +93,17 @@ } ] } - ] + ], + /* TODO: (FE-6306) - These rules have been added to allow us to + * upgrade Storybook, but all rules will need to be looked at */ + "no-restricted-exports": "off", + "default-param-last": "off", + "react/no-unstable-nested-components": "off", + "react/jsx-no-constructed-context-values": "off", + "react/jsx-no-useless-fragment": "off", + "no-unsafe-optional-chaining": "off", + "prefer-regex-literals": "off", + "arrow-body-style": "off" }, "env": { "es6": true, @@ -106,14 +116,22 @@ "plugin:react-hooks/recommended", "plugin:no-unsanitized/DOM", "airbnb", - "prettier", - "prettier/react" + "prettier" ], "globals": { "global": false, "process": false }, "overrides": [ + { + "files": ["*.mdx"], + "extends": "plugin:mdx/recommended", + "rules": { + "jsx-a11y/anchor-has-content": "off", + "jsx-a11y/control-has-associated-label": "off", + "react/self-closing-comp": "off" + } + }, { "files": ["*.ts", "*.tsx"], "parser": "@typescript-eslint/parser", @@ -130,9 +148,10 @@ "plugins": ["@typescript-eslint"], "extends": [ "plugin:@typescript-eslint/recommended", - "prettier/@typescript-eslint" + "prettier" ], "settings": { + "mdx/code-blocks": true, "react": { "version": "detect" } @@ -146,6 +165,13 @@ "error", { "allow": ["arrowFunctions"] } ], + "react/function-component-definition": [ + "error", + { + "namedComponents": "arrow-function", + "unnamedComponents": "arrow-function" + } + ], "no-restricted-imports": [ "error", { @@ -156,6 +182,18 @@ "react/prop-types": "off" } }, + { + "files": ["*.stories.tsx"], + "rules": { + "react/function-component-definition": [ + "error", + { + "namedComponents": "arrow-function", + "unnamedComponents": "arrow-function" + } + ] + } + }, { "files": ["*.spec.*"], "env": { @@ -173,7 +211,8 @@ ], "rules": { "jest/expect-expect": "off", - "jest-dom/prefer-to-have-attribute": "off" + "jest-dom/prefer-to-have-attribute": "off", + "jest/no-alias-methods": "off" } }, { @@ -201,4 +240,4 @@ } } ] -} +} \ No newline at end of file diff --git a/.storybook/main.js b/.storybook/main.ts similarity index 59% rename from .storybook/main.js rename to .storybook/main.ts index 57b113cc7e..f5156401c4 100644 --- a/.storybook/main.js +++ b/.storybook/main.ts @@ -1,36 +1,33 @@ const path = require("path"); const glob = require("glob"); - const projectRoot = path.resolve(__dirname, "../"); const ignoreTests = process.env.IGNORE_TESTS === "true"; const isChromatic = !ignoreTests; const getStories = () => - glob.sync(`${projectRoot}/src/**/*.stories.@(js|mdx|tsx)`, { + glob.sync(`${projectRoot}/src/**/*.{mdx,stories.@(js|jsx|ts|tsx)}`, { ...(ignoreTests && { - ignore: `${projectRoot}/src/**/*-test.stories.@(js|mdx|tsx)`, + ignore: `${projectRoot}/src/**/*-test.stories.@(js|jsx|ts|tsx)`, }), }); - module.exports = { - framework: "@storybook/react", - stories: (list) => [ - ...list, + stories: [ "./welcome-page/welcome.stories.js", - "../docs/*.stories.mdx", + "../docs/*.mdx", + "../docs/*.stories.tsx", ...getStories(), ], core: { disableTelemetry: true, }, addons: [ + "@storybook/addon-a11y", "@storybook/addon-actions", - "@storybook/addon-docs", "@storybook/addon-controls", - "@storybook/addon-viewport", - "@storybook/addon-a11y", - "@storybook/addon-google-analytics", + "@storybook/addon-docs", "@storybook/addon-links", + "@storybook/addon-mdx-gfm", "@storybook/addon-toolbars", + "@storybook/addon-viewport", ], staticDirs: ["../.assets", "../logo"], webpackFinal: async (config, { configType }) => { @@ -41,10 +38,19 @@ module.exports = { extensions: [".js", ".tsx", ".ts"], }; - // Workaround to stop hashes being added to font filenames, so we can pre-load them - config.module.rules.find((rule) => + // Finds the rule for woff2 files and modifies the file-loader to preserve the original filenames to allow us to preload them + const fontRuleIndex = config.module.rules.findIndex((rule) => rule.test.toString().includes("woff2") - ).options.name = "static/media/[name].[ext]"; + ); + if (fontRuleIndex !== -1) { + config.module.rules[fontRuleIndex] = { + test: /\.(woff(2)?|eot|ttf|otf|svg|png)$/, + type: "asset/resource", + generator: { + filename: "static/media/[name][ext]", + }, + }; + } return config; }, @@ -58,4 +64,11 @@ module.exports = { `, }), + framework: { + name: "@storybook/react-webpack5", + options: {}, + }, + docs: { + autodocs: true, + }, }; diff --git a/.storybook/manager.js b/.storybook/manager.ts similarity index 56% rename from .storybook/manager.js rename to .storybook/manager.ts index 5e6bc4a8a9..3b960ee496 100644 --- a/.storybook/manager.js +++ b/.storybook/manager.ts @@ -1,13 +1,26 @@ -import { addons, types } from "@storybook/addons"; +import { addons } from "@storybook/manager-api"; +import { types } from "@storybook/addons"; import sageTheme from "./sageTheme"; import { ADDON_ID, TOOL_ID } from "./version-picker/constants"; import { VersionPicker } from "./version-picker"; +import { API_PreparedIndexEntry, API_StatusObject } from "@storybook/types"; addons.setConfig({ theme: sageTheme, panelPosition: "bottom", showNav: true, showPanel: true, + sidebar: { + filters: { + patterns: ( + item: API_PreparedIndexEntry & { + status: Record; + } + ): boolean => { + return !(item.tags ?? []).includes("hideInSidebar"); + }, + }, + }, }); if (process.env.NODE_ENV === "production") { @@ -20,5 +33,3 @@ if (process.env.NODE_ENV === "production") { }); }); } - -window.STORYBOOK_GA_ID = "UA-77028225-13"; diff --git a/.storybook/modes.js b/.storybook/modes.js new file mode 100644 index 0000000000..3e7c9b8d46 --- /dev/null +++ b/.storybook/modes.js @@ -0,0 +1,11 @@ +export const allModes = { + default: { + viewport: 1280, + }, + chromatic: { + viewport: { + height: 1200, + width: 900, + }, + }, +}; diff --git a/.storybook/preview.js b/.storybook/preview.ts similarity index 82% rename from .storybook/preview.js rename to .storybook/preview.ts index 1e64a50a4a..554a05560f 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.ts @@ -2,23 +2,11 @@ import withGlobalStyles from "./with-global-styles"; import { withLocaleSelector } from "./locale-selector"; import { withThemeProvider, globalThemeProvider } from "./withThemeProvider"; import { withPortalProvider } from "./with-portal-provider"; -import { configureActions } from "@storybook/addon-actions"; +import sageStorybookTheme from "./sageStorybookTheme"; import "../src/style/fonts.css"; import "./style/story-root.css"; -// Temporary fix for issue mentioned in FE-2565 ticket -// Should be solved by the storybook team in foreseeable future -// https://github.com/storybookjs/storybook/issues/9948 -// This usage is legacy (https://github.com/storybookjs/storybook/blob/master/addons/actions/ADVANCED.md) -// and will be removed in Storybook v7 -configureActions({ - // Maximum depth of serialization for large objects - depth: 6, - // Limit the number of items logged into the actions panel - limit: 20, -}); - const customViewports = { extraSmall: { name: "Smart Phones", @@ -58,7 +46,7 @@ const customViewports = { }; export const parameters = { - layout: "fullscreen", + docs: { canvas: { layout: "padded" }, theme: sageStorybookTheme }, a11y: { // axe-core optionsParameter (https://github.com/dequelabs/axe-core/blob/develop/doc/API.md#options-parameter) options: { diff --git a/.storybook/sageStorybookTheme.ts b/.storybook/sageStorybookTheme.ts new file mode 100644 index 0000000000..2ab6bc3d0d --- /dev/null +++ b/.storybook/sageStorybookTheme.ts @@ -0,0 +1,16 @@ +import { create } from "@storybook/theming/create"; + +export default create({ + base: "light", + + // Typography + fontBase: '"Sage UI", sans-serif', + fontCode: "monospace", + + brandTitle: "Carbon by Sage", + brandUrl: "https://carbon.sage.com", + brandImage: "carbon-by-sage-logo.png", + + colorPrimary: "#3A10E5", + colorSecondary: "#007e45", +}); diff --git a/.storybook/utils/styled-system-props.js b/.storybook/utils/styled-system-props.js deleted file mode 100644 index 0781a104ec..0000000000 --- a/.storybook/utils/styled-system-props.js +++ /dev/null @@ -1,903 +0,0 @@ -import React from "react"; -import PropTypes from "prop-types"; -import { ArgsTable } from "@storybook/components"; -import { ArgsTable as Props } from "@storybook/addon-docs"; - -const generateStyledSystemMarginProps = (defaults) => { - return [ - { - name: "m", - type: { summary: "number | string" }, - description: - "Margin, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.m || "-", - }, - table: { - category: "Margin", - }, - }, - { - name: "mt", - type: { summary: "number | string" }, - description: - "Margin top, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.mt || "-", - }, - table: { - category: "Margin", - }, - }, - { - name: "mr", - type: { summary: "number | string" }, - description: - "Margin right, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.mr || "-", - }, - table: { - category: "Margin", - }, - }, - { - name: "mb", - type: { summary: "number | string" }, - description: - "Margin bottom, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.mb || "-", - }, - table: { - category: "Margin", - }, - }, - { - name: "ml", - type: { summary: "number | string" }, - description: - "Margin left, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.ml || "-", - }, - table: { - category: "Margin", - }, - }, - { - name: "mx", - type: { summary: "number | string" }, - // eslint-disable-next-line max-len - description: - "Margin left/right, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.mx || "-", - }, - table: { - category: "Margin", - }, - }, - { - name: "my", - type: { summary: "number | string" }, - // eslint-disable-next-line max-len - description: - "Margin top/bottom, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.my || "-", - }, - table: { - category: "Margin", - }, - }, - ]; -}; - -const generateStyledSystemPaddingProps = (defaults) => { - return [ - { - name: "p", - type: { summary: "number | string" }, - description: - "Padding, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.p || "-", - }, - table: { - category: "Padding", - }, - }, - { - name: "pt", - type: { summary: "number | string" }, - description: - "Padding top, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.pt || "-", - }, - table: { - category: "Padding", - }, - }, - { - name: "pr", - type: { summary: "number | string" }, - description: - "Padding right, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.pr || "-", - }, - table: { - category: "Padding", - }, - }, - { - name: "pb", - type: { summary: "number | string" }, - description: - "Padding bottom, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.pb || "-", - }, - table: { - category: "Padding", - }, - }, - { - name: "pl", - type: { summary: "number | string" }, - description: - "Padding left, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.pl || "-", - }, - table: { - category: "Padding", - }, - }, - { - name: "px", - type: { summary: "number | string" }, - // eslint-disable-next-line max-len - description: - "Padding left/right, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.px || "-", - }, - table: { - category: "Padding", - }, - }, - { - name: "py", - type: { summary: "number | string" }, - // eslint-disable-next-line max-len - description: - "Padding top/bottom, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.py || "-", - }, - table: { - category: "Padding", - }, - }, - ]; -}; - -const generateStyledSystemSpacingProps = (defaults) => { - return [ - ...generateStyledSystemMarginProps(defaults), - ...generateStyledSystemPaddingProps(defaults), - ]; -}; - -const generateStyledSystemColorProps = (defaults) => { - return [ - { - name: "color", - type: { summary: "string" }, - description: "Color, design token, theme value or any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.color || "-", - }, - table: { - category: "Color", - }, - }, - { - name: "backgroundColor", - type: { summary: "string" }, - description: - "Background, design token, theme value or any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.backgroundColor || "-", - }, - table: { - category: "Color", - }, - }, - { - name: "bg", - type: { summary: "string" }, - description: "Shorthand for backgroundColor", - required: false, - defaultValue: { - summary: defaults.bg || "-", - }, - table: { - category: "Color", - }, - }, - { - name: "opacity", - type: { summary: "decimal" }, - description: "Any decimal between 0 and 1.0", - required: false, - defaultValue: { - summary: defaults.opacity || "-", - }, - table: { - category: "Color", - }, - }, - ]; -}; - -const generateStyledSystemWidthProps = (defaults) => [ - { - name: "width", - type: { summary: "number | string" }, - description: - "Numbers from 0-1 are converted to percentage widths. Numbers greater than 1 are converted to pixel values. String values are passed as raw CSS values. And arrays are converted to responsive width styles. If theme.sizes is defined, the width prop will attempt to pick up values from the theme", - required: false, - defaultValue: { - summary: defaults.width || "-", - }, - table: { - category: "Layout", - }, - }, -]; - -const generateStyledSystemLayoutProps = (defaults) => { - return [ - ...generateStyledSystemWidthProps(defaults), - { - name: "height", - type: { summary: "number | string" }, - description: - "Numbers from 0-1 are converted to percentage heights. Numbers greater than 1 are converted to pixel values. String values are passed as raw CSS values. And arrays are converted to responsive height styles. If theme.sizes is defined, the height prop will attempt to pick up values from the theme", - required: false, - defaultValue: { - summary: defaults.height || "-", - }, - table: { - category: "Layout", - }, - }, - { - name: "minWidth", - type: { summary: "number | string" }, - // eslint-disable-next-line max-len - description: - "Numbers from 0-1 are converted to percentage widths. Numbers greater than 1 are converted to pixel values. String values are passed as raw CSS values. And arrays are converted to responsive width styles. If theme.sizes is defined, the width prop will attempt to pick up values from the theme", - required: false, - defaultValue: { - summary: defaults.minWidth || "-", - }, - table: { - category: "Layout", - }, - }, - { - name: "maxWidth", - type: { summary: "number | string" }, - // eslint-disable-next-line max-len - description: - "Numbers from 0-1 are converted to percentage widths. Numbers greater than 1 are converted to pixel values. String values are passed as raw CSS values. And arrays are converted to responsive width styles. If theme.sizes is defined, the width prop will attempt to pick up values from the theme", - required: false, - defaultValue: { - summary: defaults.maxWidth || "-", - }, - table: { - category: "Layout", - }, - }, - { - name: "minHeight", - type: { summary: "number | string" }, - // eslint-disable-next-line max-len - description: - "Numbers from 0-1 are converted to percentage heights. Numbers greater than 1 are converted to pixel values. String values are passed as raw CSS values. And arrays are converted to responsive height styles. If theme.sizes is defined, the height prop will attempt to pick up values from the theme", - required: false, - defaultValue: { - summary: defaults.minWidth || "-", - }, - table: { - category: "Layout", - }, - }, - { - name: "maxHeight", - type: { summary: "number | string" }, - // eslint-disable-next-line max-len - description: - "Numbers from 0-1 are converted to percentage heights. Numbers greater than 1 are converted to pixel values. String values are passed as raw CSS values. And arrays are converted to responsive height styles. If theme.sizes is defined, the height prop will attempt to pick up values from the theme", - required: false, - defaultValue: { - summary: defaults.maxWidth || "-", - }, - table: { - category: "Layout", - }, - }, - { - name: "size", - type: { summary: "number | string" }, - // eslint-disable-next-line max-len - description: - "Width/Height, Numbers from 0-1 are converted to percentage values. Numbers greater than 1 are converted to pixel values. String values are passed as raw CSS values. And arrays are converted to responsive styles. If theme.sizes is defined, the height and width props will attempt to pick up values from the theme", - required: false, - defaultValue: { - summary: defaults.size || "-", - }, - table: { - category: "Layout", - }, - }, - { - name: "display", - type: { summary: "string" }, - description: "Any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.display || "-", - }, - table: { - category: "Layout", - }, - }, - { - name: "verticalAlign", - type: { summary: "string" }, - description: "Any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.verticalAlign || "-", - }, - table: { - category: "Layout", - }, - }, - { - name: "overflow", - type: { summary: "string" }, - description: "Any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.overflow || "-", - }, - table: { - category: "Layout", - }, - }, - { - name: "overflowX", - type: { summary: "string" }, - description: "Any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.overflowX || "-", - }, - table: { - category: "Layout", - }, - }, - { - name: "overflowY", - type: { summary: "string" }, - description: "Any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.display || "-", - }, - table: { - category: "Layout", - }, - }, - ]; -}; - -const generateStyledSystemFlexBoxProps = (defaults) => { - return [ - { - name: "alignItems", - type: { summary: "string" }, - description: "Any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.alignItems || "-", - }, - table: { - category: "Flexbox", - }, - }, - { - name: "alignContent", - type: { summary: "string" }, - description: "Any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.alignContent || "-", - }, - table: { - category: "Flexbox", - }, - }, - { - name: "justifyItems", - type: { summary: "string" }, - description: "Any valid CSS string", - required: false, - defaultValue: { - summary: defaults.justifyItems || "-", - }, - table: { - category: "Flexbox", - }, - }, - { - name: "justifyContent", - type: { summary: "string" }, - description: "Any valid CSS string", - required: false, - defaultValue: { - summary: defaults.justifyContent || "-", - }, - table: { - category: "Flexbox", - }, - }, - { - name: "flexWrap", - type: { summary: "string" }, - description: "Any valid CSS string", - required: false, - defaultValue: { - summary: defaults.flexWrap || "-", - }, - table: { - category: "Flexbox", - }, - }, - { - name: "flexDirection", - type: { summary: "string" }, - description: "Any valid CSS string", - required: false, - defaultValue: { - summary: defaults.flexDirection || "-", - }, - table: { - category: "Flexbox", - }, - }, - { - name: "flex", - type: { summary: "string" }, - description: "Any valid CSS string", - required: false, - defaultValue: { - summary: defaults.flex || "-", - }, - table: { - category: "Flexbox", - }, - }, - { - name: "flexGrow", - type: { summary: "number" }, - description: "Any number greater than 0.", - required: false, - defaultValue: { - summary: defaults.flexGrow || "-", - }, - table: { - category: "Flexbox", - }, - }, - { - name: "flexShrink", - type: { summary: "number" }, - description: "Any number greater than 0.", - required: false, - defaultValue: { - summary: defaults.flexShrink || "-", - }, - table: { - category: "Flexbox", - }, - }, - { - name: "flexBasis", - type: { summary: "string" }, - description: "Any valid CSS string", - required: false, - defaultValue: { - summary: defaults.flexBasis || "-", - }, - table: { - category: "Flexbox", - }, - }, - { - name: "justifySelf", - type: { summary: "string" }, - description: "Any valid CSS string", - required: false, - defaultValue: { - summary: defaults.justifySelf || "-", - }, - table: { - category: "Flexbox", - }, - }, - { - name: "alignSelf", - type: { summary: "string" }, - description: "Any valid CSS string", - required: false, - defaultValue: { - summary: defaults.alignSelf || "-", - }, - table: { - category: "Flexbox", - }, - }, - { - name: "order", - type: { summary: "number" }, - description: "Any number greater than 0.", - required: false, - defaultValue: { - summary: defaults.order || "-", - }, - table: { - category: "Flexbox", - }, - }, - ]; -}; - -const generateStyledSystemGridProps = (defaults) => { - return [ - { - name: "gridColumn", - type: { summary: "string" }, - description: "Any valid CSS string", - required: false, - defaultValue: { - summary: defaults.gridColumn || "-", - }, - table: { - category: "Grid", - }, - }, - { - name: "gridRow", - type: { summary: "string" }, - description: "Any valid CSS string", - required: false, - defaultValue: { - summary: defaults.gridRow || "-", - }, - table: { - category: "Grid", - }, - }, - { - name: "gridArea", - type: { summary: "string" }, - description: "Any valid CSS string", - required: false, - defaultValue: { - summary: defaults.gridArea || "-", - }, - table: { - category: "Grid", - }, - }, - { - name: "gridAutoFlow", - type: { summary: "string" }, - description: "Any valid CSS string", - required: false, - defaultValue: { - summary: defaults.gridAutoFlow || "-", - }, - table: { - category: "Grid", - }, - }, - { - name: "gridAutoRows", - type: { summary: "string" }, - description: "Any valid CSS string", - required: false, - defaultValue: { - summary: defaults.gridAutoRows || "-", - }, - table: { - category: "Grid", - }, - }, - { - name: "gridAutoColumns", - type: { summary: "string" }, - description: "Any valid CSS string", - required: false, - defaultValue: { - summary: defaults.gridAutoColumns || "-", - }, - table: { - category: "Grid", - }, - }, - { - name: "gridTemplateRows", - type: { summary: "string" }, - description: "Any valid CSS string", - required: false, - defaultValue: { - summary: defaults.gridTemplateRows || "-", - }, - table: { - category: "Grid", - }, - }, - { - name: "gridTemplateColumns", - type: { summary: "string" }, - description: "Any valid CSS string", - required: false, - defaultValue: { - summary: defaults.gridTemplateColumns || "-", - }, - table: { - category: "Grid", - }, - }, - { - name: "gridTemplateAreas", - type: { summary: "string" }, - description: "Any valid CSS string", - required: false, - defaultValue: { - summary: defaults.gridTemplateAreas || "-", - }, - table: { - category: "Grid", - }, - }, - ]; -}; - -const generateStyledSystemBackgroundProps = (defaults) => { - return [ - { - name: "background", - type: { summary: "string" }, - description: "Any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.background || "-", - }, - table: { - category: "Background", - }, - }, - { - name: "backgroundImage", - type: { summary: "string" }, - description: "Any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.backgroundImage || "-", - }, - table: { - category: "Background", - }, - }, - { - name: "backgroundSize", - type: { summary: "string" }, - description: "Any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.backgroundSize || "-", - }, - table: { - category: "Background", - }, - }, - { - name: "backgroundPosition", - type: { summary: "string" }, - description: "Any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.backgroundPosition || "-", - }, - table: { - category: "Background", - }, - }, - { - name: "backgroundRepeat", - type: { summary: "string" }, - description: "Any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.backgroundRepeat || "-", - }, - table: { - category: "Background", - }, - }, - ]; -}; - -const generateStyledSystemPositionProps = (defaults) => { - return [ - { - name: "top", - type: { summary: "string" }, - description: "Any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.top || "-", - }, - table: { - category: "position", - }, - }, - { - name: "bottom", - type: { summary: "string" }, - description: "Any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.bottom || "-", - }, - table: { - category: "position", - }, - }, - { - name: "left", - type: { summary: "string" }, - description: "Any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.left || "-", - }, - table: { - category: "position", - }, - }, - { - name: "right", - type: { summary: "string" }, - description: "Any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.right || "-", - }, - table: { - category: "position", - }, - }, - { - name: "position", - type: { summary: "string" }, - description: "Any valid CSS string.", - required: false, - defaultValue: { - summary: defaults.position || "-", - }, - table: { - category: "position", - }, - }, - ]; -}; - -const StyledSystemProps = ({ - of, - spacing, - color, - width, - layout, - flexBox, - grid, - defaults = {}, - noHeader, - margin, - padding, - background, - position, -}) => { - let rows = []; - - if (spacing) { - rows.push(...generateStyledSystemSpacingProps(defaults)); - } - if (margin) { - rows.push(...generateStyledSystemMarginProps(defaults)); - } - if (padding) { - rows.push(...generateStyledSystemPaddingProps(defaults)); - } - if (color) { - rows.push(...generateStyledSystemColorProps(defaults)); - } - if (layout) { - rows.push(...generateStyledSystemLayoutProps(defaults)); - } - if (width) { - rows.push(...generateStyledSystemWidthProps(defaults)); - } - if (flexBox) { - rows.push(...generateStyledSystemFlexBoxProps(defaults)); - } - if (grid) { - rows.push(...generateStyledSystemGridProps(defaults)); - } - if (background) { - rows.push(...generateStyledSystemBackgroundProps(defaults)); - } - if (position) { - rows.push(...generateStyledSystemPositionProps(defaults)); - } - - return ( - <> - {!noHeader &&

Props

} - {rows.length > 0 && } - {of && } - - ); -}; - -StyledSystemProps.propTypes = { - of: PropTypes.oneOfType([PropTypes.node, PropTypes.func, PropTypes.object]), - noHeader: PropTypes.bool, - spacing: PropTypes.bool, - width: PropTypes.bool, - layout: PropTypes.bool, - flexBox: PropTypes.bool, - grid: PropTypes.bool, - defaults: PropTypes.object, - margin: PropTypes.bool, - padding: PropTypes.bool, - background: PropTypes.bool, -}; - -export default StyledSystemProps; diff --git a/.storybook/utils/styled-system-props.ts b/.storybook/utils/styled-system-props.ts new file mode 100644 index 0000000000..363fe4a5b3 --- /dev/null +++ b/.storybook/utils/styled-system-props.ts @@ -0,0 +1,1050 @@ +import { ArgTypes } from "@storybook/react"; +import { + SpaceProps, + LayoutProps, + FlexboxProps, + GridProps, + BorderProps, + PositionProps, + BackgroundProps, + TypographyProps, + ColorProps, +} from "styled-system"; + +interface StyledSystemDefaults + extends SpaceProps, + LayoutProps, + FlexboxProps, + GridProps, + BorderProps, + PositionProps, + BackgroundProps, + TypographyProps, + ColorProps {} + +interface StyledSystemProps { + color?: boolean; + spacing?: boolean; + width?: boolean; + layout?: boolean; + flexBox?: boolean; + grid?: boolean; + defaults?: StyledSystemDefaults; + margin?: boolean; + padding?: boolean; + background?: boolean; + position?: boolean; +} + +interface Table { + category?: string; + defaultValue?: { + summary: string; + detail?: string; + }; + subcategory?: string; + type?: { + summary?: string; + detail?: string; + }; +} + +interface ControlType { + type: string; +} + +interface Mapping { + [key: string]: { + [option: string]: any; + }; +} + +type Conditional = boolean | ((props: any) => boolean); + +interface PropType { + control?: ControlType | { type: ControlType }; + description?: string; + if?: Conditional; + mapping?: Mapping; + name?: string; + options?: string[]; + table?: Table; + type?: string | { name: string }; +} + +type Props = { + [key: string]: PropType; +}; + +const generateStyledSystemMarginProps = ( + defaults: StyledSystemDefaults +): ArgTypes[] => { + return [ + { + m: { + control: "text", + description: + "Margin, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Margin", + defaultValue: defaults.m && { summary: defaults.m }, + type: { summary: "number | string" }, + }, + }, + }, + { + mt: { + control: "text", + description: + "Margin top, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Margin", + defaultValue: defaults.mt && { summary: defaults.mt }, + type: { summary: "number | string" }, + }, + }, + }, + { + mr: { + control: "text", + description: + "Margin right, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Margin", + defaultValue: defaults.mr && { summary: defaults.mr }, + type: { summary: "number | string" }, + }, + }, + }, + { + mb: { + control: "text", + description: + "Margin bottom, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Margin", + defaultValue: defaults.mb && { summary: defaults.mb }, + type: { summary: "number | string" }, + }, + }, + }, + { + ml: { + control: "text", + description: + "Margin left, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Margin", + defaultValue: defaults.ml && { summary: defaults.ml }, + type: { summary: "number | string" }, + }, + }, + }, + { + mx: { + control: "text", + description: + "Margin left/right, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Margin", + defaultValue: defaults.mx && { summary: defaults.mx }, + type: { summary: "number | string" }, + }, + }, + }, + { + my: { + control: "text", + description: + "Margin top/bottom, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Margin", + defaultValue: defaults.my && { summary: defaults.my }, + type: { summary: "number | string" }, + }, + }, + }, + ]; +}; + +const generateStyledSystemPaddingProps = (defaults: StyledSystemDefaults) => { + return [ + { + p: { + control: "text", + description: + "Padding, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Padding", + defaultValue: defaults.p && { summary: defaults.p }, + type: { summary: "number | string" }, + }, + }, + }, + { + pt: { + control: "text", + description: + "Padding top, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Padding", + defaultValue: defaults.pt && { summary: defaults.pt }, + type: { summary: "number | string" }, + }, + }, + }, + { + pr: { + control: "text", + description: + "Padding right, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Padding", + defaultValue: defaults.pr && { summary: defaults.pr }, + type: { summary: "number | string" }, + }, + }, + }, + { + pb: { + control: "text", + description: + "Padding bottom, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Padding", + defaultValue: defaults.pb && { summary: defaults.pb }, + type: { summary: "number | string" }, + }, + }, + }, + { + pl: { + control: "text", + description: + "Padding left, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Padding", + defaultValue: defaults.pl && { summary: defaults.pl }, + type: { summary: "number | string" }, + }, + }, + }, + { + px: { + control: "text", + description: + "Padding left/right, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Padding", + defaultValue: defaults.px && { summary: defaults.px }, + type: { summary: "number | string" }, + }, + }, + }, + { + py: { + control: "text", + description: + "Padding top/bottom, an integer multiplier of the base spacing constant (8px) or any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Padding", + defaultValue: defaults.py && { summary: defaults.py }, + type: { summary: "number | string" }, + }, + }, + }, + ]; +}; + +const generateStyledSystemSpacingProps = (defaults: StyledSystemDefaults) => { + return [ + ...generateStyledSystemMarginProps(defaults), + ...generateStyledSystemPaddingProps(defaults), + ]; +}; + +const generateStyledSystemColorProps = (defaults: StyledSystemDefaults) => { + return [ + { + color: { + control: "text", + description: + "Color, design token, theme value or any valid CSS string.", + table: { + category: "Styled System Props", + subcategory: "Color", + type: { summary: "string" }, + defaultValue: defaults.color && { summary: defaults.color }, + }, + }, + }, + { + backgroundColor: { + control: "text", + description: + "Background, design token, theme value or any valid CSS string.", + table: { + category: "Styled System Props", + subcategory: "Color", + type: { summary: "string" }, + defaultValue: defaults.backgroundColor && { + summary: defaults.backgroundColor, + }, + }, + }, + }, + { + bg: { + control: "text", + description: "Shorthand for backgroundColor", + table: { + category: "Styled System Props", + subcategory: "Color", + defaultValue: defaults.backgroundColor && { + summary: defaults.backgroundColor, + }, + type: { summary: "string" }, + }, + }, + }, + { + opacity: { + control: "text", + description: "Any decimal between 0 and 1.0", + table: { + category: "Styled System Props", + subcategory: "Color", + defaultValue: defaults.opacity && { summary: defaults.opacity }, + type: { summary: "decimal" }, + }, + }, + }, + ]; +}; + +const generateStyledSystemWidthProps = (defaults: StyledSystemDefaults) => [ + { + width: { + control: "text", + description: + "Numbers from 0-1 are converted to percentage widths. Numbers greater than 1 are converted to pixel values. String values are passed as raw CSS values. And arrays are converted to responsive width styles. If theme.sizes is defined, the width prop will attempt to pick up values from the theme", + required: false, + table: { + category: "Styled System Props", + subcategory: "Layout", + defaultValue: defaults.width && { summary: defaults.width }, + type: { summary: "number | string" }, + }, + }, + }, +]; + +const generateStyledSystemLayoutProps = (defaults: StyledSystemDefaults) => { + return [ + ...generateStyledSystemWidthProps(defaults), + { + height: { + control: "text", + description: + "Numbers from 0-1 are converted to percentage heights. Numbers greater than 1 are converted to pixel values. String values are passed as raw CSS values. And arrays are converted to responsive height styles. If theme.sizes is defined, the height prop will attempt to pick up values from the theme", + required: false, + table: { + category: "Styled System Props", + subcategory: "Layout", + defaultValue: defaults.height && { summary: defaults.height }, + type: { summary: "number | string" }, + }, + }, + }, + { + minWidth: { + control: "text", + description: + "Numbers from 0-1 are converted to percentage widths. Numbers greater than 1 are converted to pixel values. String values are passed as raw CSS values. And arrays are converted to responsive width styles. If theme.sizes is defined, the width prop will attempt to pick up values from the theme", + required: false, + table: { + category: "Styled System Props", + subcategory: "Layout", + defaultValue: defaults.height && { summary: defaults.height }, + type: { summary: "number | string" }, + }, + }, + }, + { + maxWidth: { + control: "text", + description: + "Numbers from 0-1 are converted to percentage widths. Numbers greater than 1 are converted to pixel values. String values are passed as raw CSS values. And arrays are converted to responsive width styles. If theme.sizes is defined, the width prop will attempt to pick up values from the theme", + required: false, + table: { + category: "Styled System Props", + subcategory: "Layout", + defaultValue: defaults.maxWidth && { summary: defaults.maxWidth }, + type: { summary: "number | string" }, + }, + }, + }, + { + minHeight: { + control: "text", + description: + "Numbers from 0-1 are converted to percentage heights. Numbers greater than 1 are converted to pixel values. String values are passed as raw CSS values. And arrays are converted to responsive height styles. If theme.sizes is defined, the height prop will attempt to pick up values from the theme", + required: false, + table: { + category: "Styled System Props", + subcategory: "Layout", + defaultValue: defaults.minWidth && { summary: defaults.minWidth }, + type: { summary: "number | string" }, + }, + }, + }, + { + maxHeight: { + control: "text", + description: + "Numbers from 0-1 are converted to percentage heights. Numbers greater than 1 are converted to pixel values. String values are passed as raw CSS values. And arrays are converted to responsive height styles. If theme.sizes is defined, the height prop will attempt to pick up values from the theme", + required: false, + table: { + category: "Styled System Props", + subcategory: "Layout", + defaultValue: defaults.maxWidth && { summary: defaults.maxWidth }, + type: { summary: "number | string" }, + }, + }, + }, + { + size: { + control: "text", + description: + "Width/Height, Numbers from 0-1 are converted to percentage values. Numbers greater than 1 are converted to pixel values. String values are passed as raw CSS values. And arrays are converted to responsive styles. If theme.sizes is defined, the height and width props will attempt to pick up values from the theme", + required: false, + table: { + category: "Styled System Props", + subcategory: "Layout", + defaultValue: defaults.size && { summary: defaults.size }, + type: { summary: "number | string" }, + }, + }, + }, + { + display: { + control: "text", + description: "Any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Layout", + defaultValue: defaults.display && { summary: defaults.display }, + type: { summary: "string" }, + }, + }, + }, + { + verticalAlign: { + control: "text", + description: "Any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Layout", + defaultValue: defaults.verticalAlign && { + summary: defaults.verticalAlign, + }, + type: { summary: "string" }, + }, + }, + }, + { + overflow: { + control: "text", + description: "Any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Layout", + defaultValue: defaults.overflow && { summary: defaults.overflow }, + type: { summary: "string" }, + }, + }, + }, + { + overflowX: { + control: "text", + description: "Any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Layout", + defaultValue: defaults.overflowX && { summary: defaults.overflowX }, + type: { summary: "string" }, + }, + }, + }, + { + overflowY: { + control: "text", + description: "Any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Layout", + defaultValue: defaults.display && { summary: defaults.display }, + type: { summary: "string" }, + }, + }, + }, + ]; +}; + +const generateStyledSystemFlexBoxProps = (defaults: StyledSystemDefaults) => { + return [ + { + alignItems: { + control: "text", + description: "Any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Flexbox", + defaultValue: defaults.alignItems && { summary: defaults.alignItems }, + type: { summary: "string" }, + }, + }, + }, + { + alignContent: { + control: "text", + description: "Any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Flexbox", + defaultValue: defaults.alignContent && { + summary: defaults.alignContent, + }, + type: { summary: "string" }, + }, + }, + }, + { + justifyItems: { + control: "text", + description: "Any valid CSS string", + required: false, + table: { + category: "Styled System Props", + subcategory: "Flexbox", + defaultValue: defaults.justifyItems && { + summary: defaults.justifyItems, + }, + type: { summary: "string" }, + }, + }, + }, + { + justifyContent: { + control: "text", + description: "Any valid CSS string", + required: false, + table: { + category: "Styled System Props", + subcategory: "Flexbox", + defaultValue: defaults.justifyContent && { + summary: defaults.justifyContent, + }, + type: { summary: "string" }, + }, + }, + }, + { + flexWrap: { + control: "text", + description: "Any valid CSS string", + required: false, + table: { + category: "Styled System Props", + subcategory: "Flexbox", + defaultValue: defaults.flexWrap && { summary: defaults.flexWrap }, + type: { summary: "string" }, + }, + }, + }, + { + flexDirection: { + control: "text", + description: "Any valid CSS string", + required: false, + table: { + category: "Styled System Props", + subcategory: "Flexbox", + defaultValue: defaults.flexDirection && { + summary: defaults.flexDirection, + }, + type: { summary: "string" }, + }, + }, + }, + { + flex: { + control: "text", + description: "Any valid CSS string", + required: false, + table: { + category: "Styled System Props", + subcategory: "Flexbox", + defaultValue: defaults.flex && { summary: defaults.flex }, + type: { summary: "string" }, + }, + }, + }, + { + flexGrow: { + control: "number", + description: "Any number greater than 0.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Flexbox", + defaultValue: defaults.flexGrow && { summary: defaults.flexGrow }, + type: { summary: "number" }, + }, + }, + }, + { + flexShrink: { + control: "number", + description: "Any number greater than 0.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Flexbox", + defaultValue: defaults.flexShrink && { summary: defaults.flexShrink }, + type: { summary: "number" }, + }, + }, + }, + { + flexBasis: { + control: "text", + description: "Any valid CSS string", + required: false, + table: { + category: "Styled System Props", + subcategory: "Flexbox", + defaultValue: defaults.flexBasis && { summary: defaults.flexBasis }, + type: { summary: "string" }, + }, + }, + }, + { + justifySelf: { + control: "text", + description: "Any valid CSS string", + required: false, + table: { + category: "Styled System Props", + subcategory: "Flexbox", + defaultValue: defaults.justifySelf && { + summary: defaults.justifySelf, + }, + type: { summary: "string" }, + }, + }, + }, + { + alignSelf: { + control: "text", + description: "Any valid CSS string", + required: false, + table: { + category: "Styled System Props", + subcategory: "Flexbox", + defaultValue: defaults.alignSelf && { summary: defaults.alignSelf }, + type: { summary: "string" }, + }, + }, + }, + { + order: { + control: "number", + description: "Any number greater than 0.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Flexbox", + defaultValue: defaults.order && { summary: defaults.order }, + type: { summary: "number" }, + }, + }, + }, + ]; +}; + +const generateStyledSystemGridProps = (defaults: StyledSystemDefaults) => { + return [ + { + gridColumn: { + control: "text", + description: "Any valid CSS string", + required: false, + table: { + category: "Styled System Props", + subcategory: "Grid", + defaultValue: defaults.gridColumn && { summary: defaults.gridColumn }, + type: { summary: "string" }, + }, + }, + }, + { + gridRow: { + control: "text", + description: "Any valid CSS string", + required: false, + table: { + category: "Styled System Props", + subcategory: "Grid", + defaultValue: defaults.gridRow && { summary: defaults.gridRow }, + type: { summary: "string" }, + }, + }, + }, + { + gridArea: { + control: "text", + description: "Any valid CSS string", + required: false, + table: { + category: "Styled System Props", + subcategory: "Grid", + defaultValue: defaults.gridArea && { summary: defaults.gridArea }, + type: { summary: "string" }, + }, + }, + }, + { + gridAutoFlow: { + control: "text", + description: "Any valid CSS string", + required: false, + table: { + category: "Styled System Props", + subcategory: "Grid", + defaultValue: defaults.gridAutoFlow && { + summary: defaults.gridAutoFlow, + }, + type: { summary: "string" }, + }, + }, + }, + { + gridAutoRows: { + control: "text", + description: "Any valid CSS string", + required: false, + table: { + category: "Styled System Props", + subcategory: "Grid", + defaultValue: defaults.gridAutoRows && { + summary: defaults.gridAutoRows, + }, + type: { summary: "string" }, + }, + }, + }, + { + gridAutoColumns: { + control: "text", + description: "Any valid CSS string", + required: false, + table: { + category: "Styled System Props", + subcategory: "Grid", + defaultValue: defaults.gridAutoColumns && { + summary: defaults.gridAutoColumns, + }, + type: { summary: "string" }, + }, + }, + }, + { + gridTemplateRows: { + control: "text", + description: "Any valid CSS string", + required: false, + table: { + category: "Styled System Props", + subcategory: "Grid", + defaultValue: defaults.gridTemplateRows && { + summary: defaults.gridTemplateRows, + }, + type: { summary: "string" }, + }, + }, + }, + { + gridTemplateColumns: { + control: "text", + description: "Any valid CSS string", + required: false, + table: { + category: "Styled System Props", + subcategory: "Grid", + defaultValue: defaults.gridTemplateColumns && { + summary: defaults.gridTemplateColumns, + }, + type: { summary: "string" }, + }, + }, + }, + { + gridTemplateAreas: { + control: "text", + description: "Any valid CSS string", + required: false, + table: { + category: "Styled System Props", + subcategory: "Grid", + defaultValue: defaults.gridTemplateAreas && { + summary: defaults.gridTemplateAreas, + }, + type: { summary: "string" }, + }, + }, + }, + ]; +}; + +const generateStyledSystemBackgroundProps = ( + defaults: StyledSystemDefaults +) => { + return [ + { + background: { + control: "text", + description: "Any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Background", + defaultValue: defaults.background && { summary: defaults.background }, + type: { summary: "string" }, + }, + }, + }, + { + backgroundImage: { + control: "text", + description: "Any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Background", + defaultValue: defaults.backgroundImage && { + summary: defaults.backgroundImage, + }, + type: { summary: "string" }, + }, + }, + }, + { + backgroundSize: { + control: "text", + description: "Any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Background", + defaultValue: defaults.backgroundSize && { + summary: defaults.backgroundSize, + }, + type: { summary: "string" }, + }, + }, + }, + { + backgroundPosition: { + control: "text", + description: "Any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Background", + defaultValue: defaults.backgroundPosition && { + summary: defaults.backgroundPosition, + }, + type: { summary: "string" }, + }, + }, + }, + { + backgroundRepeat: { + control: "text", + description: "Any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Background", + defaultValue: defaults.backgroundRepeat && { + summary: defaults.backgroundRepeat, + }, + type: { summary: "string" }, + }, + }, + }, + ]; +}; + +const generateStyledSystemPositionProps = (defaults: StyledSystemDefaults) => { + return [ + { + top: { + control: "text", + description: "Any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Position", + defaultValue: defaults.top && { summary: defaults.top }, + type: { summary: "string" }, + }, + }, + }, + { + bottom: { + control: "text", + description: "Any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Position", + defaultValue: defaults.bottom && { summary: defaults.bottom }, + type: { summary: "string" }, + }, + }, + }, + { + left: { + control: "text", + description: "Any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Position", + defaultValue: defaults.left && { summary: defaults.left }, + type: { summary: "string" }, + }, + }, + }, + { + right: { + control: "text", + description: "Any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Position", + defaultValue: defaults.right && { summary: defaults.right }, + type: { summary: "string" }, + }, + }, + }, + { + position: { + control: "text", + description: "Any valid CSS string.", + required: false, + table: { + category: "Styled System Props", + subcategory: "Position", + defaultValue: defaults.position && { summary: defaults.position }, + type: { summary: "string" }, + }, + }, + }, + ]; +}; + +const generateStyledSystemProps = ( + props: StyledSystemProps, + defaults?: StyledSystemDefaults +): ArgTypes => { + const { + spacing, + margin, + padding, + color, + layout, + width, + flexBox, + grid, + background, + position, + } = props; + const result: Props = {}; + + if (spacing) { + Object.assign(result, ...generateStyledSystemSpacingProps(defaults || {})); + } + if (margin) { + Object.assign(result, ...generateStyledSystemMarginProps(defaults || {})); + } + if (padding) { + Object.assign(result, ...generateStyledSystemPaddingProps(defaults || {})); + } + if (color) { + Object.assign(result, ...generateStyledSystemColorProps(defaults || {})); + } + if (layout) { + Object.assign(result, ...generateStyledSystemLayoutProps(defaults || {})); + } + if (width) { + Object.assign(result, ...generateStyledSystemWidthProps(defaults || {})); + } + if (flexBox) { + Object.assign(result, ...generateStyledSystemFlexBoxProps(defaults || {})); + } + if (grid) { + Object.assign(result, ...generateStyledSystemGridProps(defaults || {})); + } + if (background) { + Object.assign( + result, + ...generateStyledSystemBackgroundProps(defaults || {}) + ); + } + if (position) { + Object.assign(result, ...generateStyledSystemPositionProps(defaults || {})); + } + + return result; +}; + +export default generateStyledSystemProps; diff --git a/.storybook/utils/translation-keys-table.js b/.storybook/utils/translation-keys-table.js deleted file mode 100644 index d85c5ae867..0000000000 --- a/.storybook/utils/translation-keys-table.js +++ /dev/null @@ -1,31 +0,0 @@ -import React from "react"; -import PropTypes from "prop-types"; -import { ArgsTable } from "@storybook/components"; - -const generateTranslationRows = (translationData) => { - return translationData.map(({ name, description, type, returnType }) => ({ - name: name, - description, - type: { - summary: type, - detail: `expects ${returnType} to be returned`, - }, - })); -}; - -const TranslationKeysTable = ({ translationData }) => ( - -); - -TranslationKeysTable.propTypes = { - translationData: PropTypes.arrayOf( - PropTypes.shape({ - name: PropTypes.string.isRequired, - type: PropTypes.string.isRequired, - description: PropTypes.string.isRequired, - returnType: PropTypes.string.isRequired, - }) - ).isRequired, -}; - -export default TranslationKeysTable; diff --git a/.storybook/utils/translation-keys-table.tsx b/.storybook/utils/translation-keys-table.tsx new file mode 100644 index 0000000000..a34cfe9e04 --- /dev/null +++ b/.storybook/utils/translation-keys-table.tsx @@ -0,0 +1,121 @@ +import React from "react"; +import styled from "styled-components"; +import Markdown from "react-markdown"; + +interface TranslationDataItem { + name: string; + type: string; + description: string; + returnType: string; +} + +interface TranslationKeysTableProps { + translationData: TranslationDataItem[]; +} + +const TranslationKeysTable = ({ + translationData, +}: TranslationKeysTableProps) => { + return ( + + + + Name + Description + Type + + + + {translationData.map((item, index) => ( + + + {item.name} + + + {item.description} + + +
+ + {item.type} + +
+
+ expects {item.returnType} to be returned +
+ + + ))} + +
+ ); +}; + +const StyledTable = styled.table` + border-spacing: 0; + color: #2e3438; + font-size: 13px; + line-height: 20px; + text-align: left; + width: 100%; + margin: 25px 1px 40px; + + tbody { + -webkit-filter: drop-shadow(0px 1px 3px rgba(0, 0, 0, 0.1)); + filter: drop-shadow(0px 1px 3px rgba(0, 0, 0, 0.1)); + + & > tr:first-of-type > td:first-of-type { + border-top-left-radius: 4px; + } + & > tr:first-of-type > td:last-of-type { + border-top-right-radius: 4px; + } + & > tr:last-of-type > td:first-of-type { + border-bottom-left-radius: 4px; + } + & > tr:last-of-type > td:last-of-type { + border-bottom-right-radius: 4px; + } + + & > tr:last-of-type > * { + border-block-end: 1px solid hsla(203, 50%, 30%, 0.15); + } + + & > tr > *:first-of-type { + border-inline-start: 1px solid hsla(203, 50%, 30%, 0.15); + } + + & > tr:first-of-type > * { + border-block-start: 1px solid hsla(203, 50%, 30%, 0.15); + } + + & > tr > * { + background: #ffffff; + border-top: 1px solid hsla(203, 50%, 30%, 0.15); + } + } + + td, + th { + border: none; + vertical-align: top; + text-overflow: ellipsis; + } + + th:first-of-type, + td:first-of-type { + padding-left: 20px; + width: 25%; + } + + td { + padding: 10px 15px; + } + + th { + color: rgba(46, 52, 56, 0.75); + padding: 10px 15px; + } +`; + +export default TranslationKeysTable; diff --git a/.storybook/welcome-page/get-started/get-started.component.js b/.storybook/welcome-page/get-started/get-started.component.js index 0bc4f01ffc..5c714a4778 100644 --- a/.storybook/welcome-page/get-started/get-started.component.js +++ b/.storybook/welcome-page/get-started/get-started.component.js @@ -24,7 +24,7 @@ const GetStarted = () => ( + setIsOpen(false)} + title="Title" + subtitle="Subtitle" + > + + First + Second + Third + + Navigation item with very long label + + Fifth + + } + > + + + + + + + + + + + + + + + + + + + + + + + ); +}; +InFullScreenDialogStory.storyName = "In Full Screen Dialog"; diff --git a/src/components/badge/badge.stories.mdx b/src/components/badge/badge.mdx similarity index 51% rename from src/components/badge/badge.stories.mdx rename to src/components/badge/badge.mdx index c612c55db0..d25919a531 100644 --- a/src/components/badge/badge.stories.mdx +++ b/src/components/badge/badge.mdx @@ -1,21 +1,19 @@ -import { Meta, Story, Canvas, ArgsTable } from "@storybook/addon-docs"; +import { Meta, Canvas } from "@storybook/addon-docs"; +import { ArgTypes } from "@storybook/blocks"; -import Badge from "."; -import Box from "../box"; -import Button from "../button"; +import * as BadgeStories from "./badge.stories"; -import * as stories from "./badge.stories"; - - + # Badge - Product Design System component + Product Design System component Compact visual indicators that help things in common stand out. @@ -38,45 +36,35 @@ import Badge from "carbon-react/lib/components/badge"; ### Default Badge - - - + ### Badge with counter > 99 Badge doesn't support more than 2 digits - - - + ### Badge with counter 0 If the counter is less than 1 badge will not show itself - - - + ### Display Only -To acheive a `display only` version of this component, you can simply not pass an `onClick` function to the component. This means that instead of rendering as a `button` element, +To acheive a `display only` version of this component, you can simply not pass an `onClick` function to the component. This means that instead of rendering as a `button` element, the component will render as a `span`. - - - + ### Custom Color -You can use the `color` prop to override the default color of the component. +You can use the `color` prop to override the default color of the component. - - - + ## Props ### Badge - + diff --git a/src/components/badge/badge.stories.tsx b/src/components/badge/badge.stories.tsx index d9df616791..f4d1000fe1 100644 --- a/src/components/badge/badge.stories.tsx +++ b/src/components/badge/badge.stories.tsx @@ -1,54 +1,77 @@ import React from "react"; -import { ComponentStory } from "@storybook/react"; +import { Meta, StoryObj } from "@storybook/react"; import Badge from "."; import Button from "../button"; import Box from "../box"; -export const Default: ComponentStory = () => ( - - {}}> - - - -); - -export const WithThreeDigits: ComponentStory = () => ( - - {}}> - - - -); - -export const WithCounterZero: ComponentStory = () => ( - - {}}> - - - -); - -export const DisplayOnly: ComponentStory = () => ( - - - - - -); - -export const CustomColor: ComponentStory = () => ( - - {}} color="--colorsSemanticNegative500"> - - - -); +const meta: Meta = { + title: "Badge", + component: Badge, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = () => { + return ( + + {}}> + + + + ); +}; +Default.storyName = "Default"; + +export const WithThreeDigits: Story = () => { + return ( + + {}}> + + + + ); +}; +WithThreeDigits.storyName = "With Three Digits"; + +export const WithCounterZero: Story = () => { + return ( + + {}}> + + + + ); +}; +WithCounterZero.storyName = "With Counter Zero"; + +export const DisplayOnly: Story = () => { + return ( + + + + + + ); +}; +DisplayOnly.storyName = "Display Only"; + +export const CustomColor: Story = () => { + return ( + + {}} color="--colorsSemanticNegative500"> + + + + ); +}; +CustomColor.storyName = "Custom Colour"; diff --git a/src/components/batch-selection/batch-selection.stories.mdx b/src/components/batch-selection/batch-selection.mdx similarity index 61% rename from src/components/batch-selection/batch-selection.stories.mdx rename to src/components/batch-selection/batch-selection.mdx index 2a32672ac3..fcd5409f0f 100644 --- a/src/components/batch-selection/batch-selection.stories.mdx +++ b/src/components/batch-selection/batch-selection.mdx @@ -1,12 +1,11 @@ -import { Meta, ArgsTable, Canvas, Story } from "@storybook/addon-docs"; +import { Meta, Canvas } from "@storybook/addon-docs"; +import { ArgTypes } from "@storybook/blocks"; import TranslationKeysTable from "../../../.storybook/utils/translation-keys-table"; -import BatchSelection from "."; -import IconButton from "../icon-button"; +import * as IconButtonStories from "../icon-button/icon-button.stories"; +import * as BatchSelectionStories from "./batch-selection.stories"; -import * as stories from "./batch-selection.stories"; - - + # Batch Selection @@ -32,48 +31,38 @@ import IconButton from "carbon-react/lib/components/icon-button"; ### Default usage - - - + ### On dark background - - - + ### On light background - - - + ### On white background - - - + ### Disabled - - - + ## Props ### Batch Selection - + ### Icon Button - + ## Translation keys The following keys are available to override the translations for this component by passing in a custom locale object to the -[i18nProvider](https://carbon.sage.com/?path=/story/documentation-i18n--page). +[i18nProvider](../?path=/docs/documentation-i18n--docs). = () => ( - - - {}}> - - - {}}> - - - {}}> - - - -); +const meta: Meta = { + title: "Batch Selection", + component: BatchSelection, +}; -export const Dark: ComponentStory = () => ( - - {}}> - - - {}}> - - - {}}> - - - -); +export default meta; +type Story = StoryObj; -export const Light: ComponentStory = () => ( - - {}}> - - - {}}> - - - {}}> - - - -); +export const Default: Story = () => { + return ( + + + {}}> + + + {}}> + + + {}}> + + + + ); +}; +Default.storyName = "Default"; -export const White: ComponentStory = () => ( - - {}}> - - - {}}> - - - {}}> - - - -); +export const Dark: Story = () => { + return ( + + {}}> + + + {}}> + + + {}}> + + + + ); +}; +Dark.storyName = "Dark"; -export const Disabled: ComponentStory = () => ( - - {}}> - - - {}}> - - - {}}> - - - -); +export const Light: Story = () => { + return ( + + {}}> + + + {}}> + + + {}}> + + + + ); +}; +Light.storyName = "Light"; + +export const White: Story = () => { + return ( + + {}}> + + + {}}> + + + {}}> + + + + ); +}; +White.storyName = "White"; + +export const Disabled: Story = () => { + return ( + + {}}> + + + {}}> + + + {}}> + + + + ); +}; +Disabled.storyName = "Disabled"; diff --git a/src/components/box/box.stories.mdx b/src/components/box/box.mdx similarity index 52% rename from src/components/box/box.stories.mdx rename to src/components/box/box.mdx index bdbfe8ed3b..645b31901d 100644 --- a/src/components/box/box.stories.mdx +++ b/src/components/box/box.mdx @@ -1,13 +1,8 @@ -import { Meta, Story, Canvas, ArgsTable } from "@storybook/addon-docs"; -import { ArgsTable as SimpleArgsTable } from "@storybook/components"; +import { Meta, ArgTypes, Canvas } from "@storybook/blocks"; -import StyledSystemProps from "../../../.storybook/utils/styled-system-props"; +import * as BoxStories from "./box.stories"; -import Box from "."; - -import * as stories from "./box.stories"; - - + # Box @@ -31,41 +26,29 @@ import Box from "carbon-react/lib/components/box"; ### Spacing - - - + ### Position -Please note that in order to see the `position: fixed` Box, you will need to view this example in the `Canvas` tab. +Please view [this example as a standalone canvas](../?path=/story/box--position) in order to see the `position: fixed` Box. - - - + ### Color - - - + ### Box Shadow - - - + ### Flex - - - + ### Grid - - - + ### Gap @@ -73,44 +56,32 @@ The `Box` component also supports the `gap`, `column-gap` and `row-gap` properti `flex`, `inline-flex`, `grid` or `inline-grid`. See the [prop table](#props) below for more information on the types it accepts. Below is an example of how these props can be used. - - - + ### Layout - - - + ## OverflowWrap Use the `overflowWrap` prop to apply `overflow-wrap: break-word` to the content within the `Box` wrapper. - - - + ### Scroll Use the `scrollVariant` prop to indicate which theme scrollbar you would like to display. Use `light` or `dark` values to display as below. This will still require the use of the `overflow` prop and only displays in Chrome or Safari. If no `scrollVariant` prop is set then the scroll bar will resort to the browser default. - - - + ### Rounded corners -Use the `borderRadius` to set the radius on the corners of the `Box`, +Use the `borderRadius` to set the radius on the corners of the `Box`, see [prop table](#props) below for more information on the types it accepts - - - + ## Props -### Style System - - \ No newline at end of file + diff --git a/src/components/box/box.stories.tsx b/src/components/box/box.stories.tsx index 17b2108ed2..a9bfdf396a 100644 --- a/src/components/box/box.stories.tsx +++ b/src/components/box/box.stories.tsx @@ -1,19 +1,40 @@ import React from "react"; -import { ComponentStory } from "@storybook/react"; +import { Meta, StoryObj } from "@storybook/react"; import Box, { BoxProps } from "."; import Button from "../button"; import Typography from "../typography"; +import generateStyledSystemProps from "../../../.storybook/utils/styled-system-props"; -export const Spacing: ComponentStory = () => { +const styledSystemProps = generateStyledSystemProps({ + spacing: true, + flexBox: true, + grid: true, + layout: true, + position: true, +}); + +const meta: Meta = { + title: "Box", + component: Box, + argTypes: { + ...styledSystemProps, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Spacing: Story = () => { return ( ); }; +Spacing.storyName = "Spacing"; -export const Position: ComponentStory = () => { +export const Position: Story = () => { return ( = () => { ); }; +Position.storyName = "Position"; -export const Color: ComponentStory = () => { +export const Color: Story = () => { return ( @@ -71,14 +93,16 @@ export const Color: ComponentStory = () => { ); }; +Color.storyName = "Color"; -export const BoxShadow: ComponentStory = () => { +export const BoxShadow: Story = () => { return ( ); }; +BoxShadow.storyName = "Box Shadow"; -export const Flex: ComponentStory = () => { +export const Flex: Story = () => { return ( = () => { ); }; +Flex.storyName = "Flex"; -export const Grid: ComponentStory = () => { +export const grid: Story = () => { return ( @@ -153,8 +178,9 @@ export const Grid: ComponentStory = () => { ); }; +grid.storyName = "Grid"; -export const Gap: ComponentStory = () => { +export const Gap: Story = () => { return ( @@ -212,8 +238,9 @@ export const Gap: ComponentStory = () => { ); }; +Gap.storyName = "Gap"; -export const Layout: ComponentStory = () => { +export const Layout: Story = () => { return ( = () => { ); }; +Layout.storyName = "Layout"; -export const OverflowWrap: ComponentStory = () => { +export const OverflowWrap: Story = () => { return (
= () => {
); }; +OverflowWrap.storyName = "OverflowWrap"; OverflowWrap.parameters = { chromatic: { disableSnapshot: true } }; -export const Scroll: ComponentStory = () => { +export const Scroll: Story = () => { return (
= () => {
); }; +Scroll.storyName = "Scroll"; Scroll.parameters = { chromatic: { disableSnapshot: true } }; -const radiusTokens: BoxProps["borderRadius"][] = [ - "borderRadius000", - "borderRadius010", - "borderRadius025", - "borderRadius050", - "borderRadius100", - "borderRadius200", - "borderRadius400", - "borderRadiusCircle", -]; - -export const RoundedCorners = () => ( - - {radiusTokens.map((token) => ( - - ))} - -); +export const RoundedCorners: Story = () => { + const radiusTokens: BoxProps["borderRadius"][] = [ + "borderRadius000", + "borderRadius010", + "borderRadius025", + "borderRadius050", + "borderRadius100", + "borderRadius200", + "borderRadius400", + "borderRadiusCircle", + ]; + return ( + + {radiusTokens.map((token) => ( + + ))} + + ); +}; +RoundedCorners.storyName = "Rounded Corners"; RoundedCorners.parameters = { chromatic: { disableSnapshot: false } }; diff --git a/src/components/breadcrumbs/breadcrumbs.stories.mdx b/src/components/breadcrumbs/breadcrumbs.mdx similarity index 63% rename from src/components/breadcrumbs/breadcrumbs.stories.mdx rename to src/components/breadcrumbs/breadcrumbs.mdx index a0fb7d3c89..c7ef9850aa 100644 --- a/src/components/breadcrumbs/breadcrumbs.stories.mdx +++ b/src/components/breadcrumbs/breadcrumbs.mdx @@ -1,20 +1,21 @@ -import { Meta, Story, Canvas, ArgsTable } from "@storybook/addon-docs"; -import { Breadcrumbs, Crumb } from "./index"; -import * as stories from "./breadcrumbs.stories.tsx"; +import { Meta, ArgTypes, Canvas } from "@storybook/blocks"; import TranslationKeysTable from "../../../.storybook/utils/translation-keys-table"; -import StyledSystemProps from "../../../.storybook/utils/styled-system-props"; - +import * as CrumbStories from "./crumb/crumb.stories.tsx"; +import * as BreadcrumbsStories from "./breadcrumbs.stories.tsx"; + + # Breadcrumbs - - Product Design System component - + rel="noreferrer" +> + Product Design System component + Breadcrumbs are a secondary navigation aid that helps users easily understand their location. @@ -36,28 +37,22 @@ import { Breadcrumbs, Crumb } from "carbon-react/lib/components/breadcrumbs"; ### Breadcrumbs - - - + ## Props ### Breadcrumbs - + ### Crumb - + ## Translation keys The following keys are available to override the translations for this component by passing in a custom locale object to the -[i18nProvider](https://carbon.sage.com/?path=/story/documentation-i18n--page). +[i18nProvider](../?path=/docs/documentation-i18n--docs). diff --git a/src/components/breadcrumbs/breadcrumbs.stories.tsx b/src/components/breadcrumbs/breadcrumbs.stories.tsx index ce93b50b86..f0a2c4b009 100644 --- a/src/components/breadcrumbs/breadcrumbs.stories.tsx +++ b/src/components/breadcrumbs/breadcrumbs.stories.tsx @@ -1,11 +1,26 @@ import React from "react"; -import { ComponentStory } from "@storybook/react"; +import { Meta, StoryObj } from "@storybook/react"; import { Breadcrumbs } from "."; import { Crumb } from "./crumb"; +import generateStyledSystemProps from "../../../.storybook/utils/styled-system-props"; -// eslint-disable-next-line import/prefer-default-export -export const DefaultBreadcrumbs: ComponentStory = () => { +const styledSystemProps = generateStyledSystemProps({ + spacing: true, +}); + +const meta: Meta = { + title: "Breadcrumbs", + component: Breadcrumbs, + argTypes: { + ...styledSystemProps, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = () => { return ( Breadcrumb 1 @@ -17,3 +32,4 @@ export const DefaultBreadcrumbs: ComponentStory = () => { ); }; +Default.storyName = "Default"; diff --git a/src/components/breadcrumbs/crumb/crumb.stories.tsx b/src/components/breadcrumbs/crumb/crumb.stories.tsx new file mode 100644 index 0000000000..26ee463284 --- /dev/null +++ b/src/components/breadcrumbs/crumb/crumb.stories.tsx @@ -0,0 +1,25 @@ +import { Meta, StoryObj } from "@storybook/react"; +import Crumb from "./crumb.component"; + +/** + * This file is used primarily as a means to generate the props table. + * It contains the tag: ["hideInSidebar"] so that it is not included in the sidebar. + */ + +const meta: Meta = { + title: "Crumb", + component: Crumb, + tags: ["hideInSidebar"], + parameters: { + chromatic: { disableSnapshot: true }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + children: [], + }, +}; diff --git a/src/components/button-bar/button-bar.mdx b/src/components/button-bar/button-bar.mdx new file mode 100644 index 0000000000..3e790c68dc --- /dev/null +++ b/src/components/button-bar/button-bar.mdx @@ -0,0 +1,72 @@ +import { Meta, ArgTypes, Canvas } from "@storybook/blocks"; + +import * as ButtonBarStories from "./button-bar.stories"; + + + +# Button Bar + +A Button bar groups together multiple buttons. + +## Contents + +- [Quick Start](#quick-start) +- [Examples](#examples) +- [Props](#props) + +## Quickstart + +```javascript +import ButtonBar from "carbon-react/lib/components/button-bar"; +``` + +## Examples + +### Button Bar - Sizes + +Button bars of different sizes. + + + + + +Button bars with different icon positions. + +### Button Bar - Icon Position + + + +### Button Bar Minor - Icon Position + + + +### Button Bar - Icon Only + + + +### Button Bar Minor - Icon Only + + + +`IconButton` components on a button bar. + + + +Button bars can be `fullWidth`. + +### Button Bar - Full Width + + + +### Button Bar Minor - Full Width + + + +## Props + +Options shared between all of the above types of button bars. When setting padding we recommend using either the `p`, `py` +or `px` props to ensure the spacing within the button bar is applied evenly. + +### Button Bar + + diff --git a/src/components/button-bar/button-bar.stories.mdx b/src/components/button-bar/button-bar.stories.mdx deleted file mode 100644 index 07778bf85c..0000000000 --- a/src/components/button-bar/button-bar.stories.mdx +++ /dev/null @@ -1,103 +0,0 @@ -import { Meta, Story, Canvas } from "@storybook/addon-docs"; -import ButtonBar from "."; -import Button from "../button"; -import StyledSystemProps from "../../../.storybook/utils/styled-system-props"; -import IconButton from "../icon-button/icon-button.component"; -import Icon from "../icon"; - -import * as stories from "./button-bar.stories"; - - - -# Button Bar - -A Button bar groups together multiple buttons. - -## Contents - -- [Quick Start](#quick-start) -- [Examples](#examples) -- [Props](#props) - -## Quickstart - -```javascript -import ButtonBar from "carbon-react/lib/components/button-bar"; -``` - -## Examples - -### Button Bar - Sizes - -Button bars of different sizes. - - - - - - - - - -Button bars with different icon positions. - -### Button Bar - Icon Position - - - - - -### Button Bar Minor - Icon Position - - - - - -### Button Bar - Icon Only - - - - - -### Button Bar Minor - Icon Only - - - - - -`IconButton` components on a button bar. - - - - - -Button bars can be `fullWidth`. - -### Button Bar - Full Width - - - - - -### Button Bar Minor - Full Width - - - - - -## Props - -Options shared between all of the above types of button bars. When setting padding we recommend using either the `p`, `py` -or `px` props to ensure the spacing within the button bar is applied evenly. - -### Button Bar - - \ No newline at end of file diff --git a/src/components/button-bar/button-bar.stories.tsx b/src/components/button-bar/button-bar.stories.tsx index 7a64da9168..29e3f77151 100644 --- a/src/components/button-bar/button-bar.stories.tsx +++ b/src/components/button-bar/button-bar.stories.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { ComponentStory } from "@storybook/react"; +import { Meta, StoryObj } from "@storybook/react"; import ButtonBar from "."; import Button from "../button"; @@ -7,61 +7,87 @@ import ButtonMinor from "../button-minor"; import Icon from "../icon"; import IconButton from "../icon-button"; +import generateStyledSystemProps from "../../../.storybook/utils/styled-system-props"; -export const buttonBarSizes: ComponentStory = () => ( - <> - - - - - - - - - - - - - - - - - - - - - +const styledSystemProps = generateStyledSystemProps( + { + spacing: true, + }, + { pt: "1px", pb: "1px", px: "24px" } ); -export const buttonBarMinorSizes: ComponentStory = () => ( - <> - - Small - Small - Small - +const meta: Meta = { + title: "Button Bar", + component: ButtonBar, + argTypes: { + ...styledSystemProps, + }, + parameters: { chromatic: { disableSnapshot: true } }, +}; - - Medium - Medium - Medium - +export default meta; +type Story = StoryObj; - - Large - Large - Large - +export const buttonBarSizes: Story = () => { + return ( + <> + + + + + + + + + + + + + + + + + + + + + + ); +}; +buttonBarSizes.storyName = "Sizes"; - - Large - Large - Large - - -); +export const buttonBarMinorSizes: Story = () => { + return ( + <> + + Small + Small + Small + + + + Medium + Medium + Medium + + + + Large + Large + Large + + + + Large + Large + Large + + + ); +}; +buttonBarMinorSizes.storyName = "Minor Sizes"; -export const buttonBarIcons: ComponentStory = () => { +export const buttonBarIcons: Story = () => { const BUTTON_BAR_SIZES = ["small", "medium", "large"] as const; const BUTTON_BAR_ICON_POSITIONS = ["before", "after"] as const; @@ -85,8 +111,9 @@ export const buttonBarIcons: ComponentStory = () => { ); }; +buttonBarIcons.storyName = "Icons"; -export const buttonBarMinorIcons: ComponentStory = () => { +export const buttonBarMinorIcons: Story = () => { const BUTTON_BAR_SIZES = ["small", "medium", "large"] as const; const BUTTON_BAR_ICON_POSITIONS = ["before", "after"] as const; @@ -110,8 +137,9 @@ export const buttonBarMinorIcons: ComponentStory = () => { ); }; +buttonBarMinorIcons.storyName = "Minor Icons"; -export const buttonBarIconsOnly: ComponentStory = () => { +export const buttonBarIconsOnly: Story = () => { const BUTTON_BAR_SIZES = ["small", "medium", "large"] as const; return ( @@ -126,8 +154,9 @@ export const buttonBarIconsOnly: ComponentStory = () => { ); }; +buttonBarIconsOnly.storyName = "Icons Only"; -export const buttonBarMinorIconsOnly: ComponentStory = () => { +export const buttonBarMinorIconsOnly: Story = () => { const BUTTON_BAR_SIZES = ["small", "medium", "large"] as const; return ( @@ -142,57 +171,67 @@ export const buttonBarMinorIconsOnly: ComponentStory = () => { ); }; +buttonBarMinorIconsOnly.storyName = "Minor Icons Only"; -export const buttonBarIconButtons: ComponentStory = () => ( - - {}}> - - - {}}> - - - {}}> - - - -); - -export const buttonBarFullWidth: ComponentStory = () => ( - <> - - - - - - - - - - - - - - +export const buttonBarIconButtons: Story = () => { + return ( + + {}}> + + + {}}> + + + {}}> + + - -); + ); +}; +buttonBarIconButtons.storyName = "Icon Buttons"; -export const buttonBarMinorFullWidth: ComponentStory = () => ( - <> - - Small full width - Small full width - Small full width - - - Medium full width - Medium full width - Medium full width - - - Large full width - Large full width - Large full width - - -); +export const buttonBarFullWidth: Story = () => { + return ( + <> + + + + + + + + + + + + + + + + + ); +}; +buttonBarFullWidth.storyName = "Full Width"; + +export const buttonBarMinorFullWidth: Story = () => { + return ( + <> + + Small full width + Small full width + Small full width + + + Medium full width + Medium full width + Medium full width + + + Large full width + Large full width + Large full width + + + ); +}; +buttonBarMinorFullWidth.storyName = "Minor Full Width"; diff --git a/src/components/button-minor/button-minor.component.tsx b/src/components/button-minor/button-minor.component.tsx index 4f71a2742a..0b9241e0ce 100644 --- a/src/components/button-minor/button-minor.component.tsx +++ b/src/components/button-minor/button-minor.component.tsx @@ -10,6 +10,8 @@ export interface ButtonMinorProps extends ButtonProps { export const ButtonMinor = ({ buttonType: buttonTypeProp = "secondary", + disabled = false, + destructive = false, size: sizeProp = "medium", iconPosition: iconPositionProp = "before", fullWidth: fullWidthProp = false, @@ -34,6 +36,8 @@ export const ButtonMinor = ({ fullWidth={fullWidth} iconPosition={iconPosition} buttonType={buttonType} + disabled={disabled} + destructive={destructive} {...rest} /> ); diff --git a/src/components/button-minor/button-minor.mdx b/src/components/button-minor/button-minor.mdx new file mode 100644 index 0000000000..404dc0cff1 --- /dev/null +++ b/src/components/button-minor/button-minor.mdx @@ -0,0 +1,130 @@ +import { Meta, ArgTypes, Canvas } from "@storybook/blocks"; + +import * as ButtonMinorStories from "./button-minor.stories"; + + + +# Button Minor + + + Product Design System component - Button Minor Component + + +- A minor button is a user interface button rather than a primary action button. +- It is less prominent than a major button. + +## Contents + +- [Quick Start](#quick-start) +- [Examples](#examples) +- [Props](#props) + +## Quickstart + +```javascript +import ButtonMinor from "carbon-react/lib/components/button-minor"; +``` + +## Examples + +### Primary Buttons + +For the single most prominent call to action on the page (e.g. Save, Submit, Continue). + + + +Primary buttons can be destructive. + + + +Primary buttons can be disabled. + + + +Primary buttons can have an icon positioned before or after the text. + + + +Primary buttons can be `fullWidth`. + + + +Primary buttons can be set into `noWrap` mode to prevent text wrapping. + + + +### Secondary Buttons + +Less prominent, there can be multiple secondary buttons on a page. +Secondary buttons are transparent, rather than white. + + + +Secondary buttons can be destructive. + + +Secondary buttons can be disabled. + + + +Secondary buttons can have an icon positioned before or after the text. + + + +Secondary buttons can be `fullWidth`. + + + +Secondary buttons can be set into `noWrap` mode to prevent text wrapping. + + + +### Tertiary Buttons + +Tertiary Buttons or 'ghost' buttons are used for reversing actions, like 'Cancel' or 'Back'. + + + +Tertiary buttons can be destructive. + + + +Tertiary buttons can be disabled. + + + +Tertiary buttons can have an icon positioned before or after the text. + + + +Tertiary buttons can be `fullWidth`. + + + +Tertiary buttons can be set to `noWrap` mode to prevent text wrapping. + + + +### Icon Only Button + +Buttons can be rendered with just an icon. + + + +Icon only buttons can also display a tooltip message when the icon is hovered over. This can be acheived by passing a string to the `iconTooltipMessage` prop. + + + +## Props + +Options shared between all of the above types of buttons. When setting padding we recommend using either the `p`, `py` +or `px` props to ensure the spacing within the button is applied evenly. + +### Button Minor + + diff --git a/src/components/button-minor/button-minor.pw.tsx b/src/components/button-minor/button-minor.pw.tsx index da504e4683..26937c5919 100644 --- a/src/components/button-minor/button-minor.pw.tsx +++ b/src/components/button-minor/button-minor.pw.tsx @@ -5,8 +5,6 @@ import { Default as ButtonMinor, ButtonMinorCustom, ButtonMinorDifferentTypes, -} from "./components.test-pw"; -import { PrimaryButton, PrimaryDestructiveButton, PrimaryDisabledButton, @@ -27,7 +25,7 @@ import { TertiaryNoWrapButton, IconOnlyButton, IconOnlyWithTooltipButton, -} from "./button-minor.stories"; +} from "./components.test-pw"; import { buttonMinorComponent } from "../../../playwright/components/button/index"; import { BUTTON_ICON_POSITIONS } from "../button/button.config"; import { ICON } from "../../../playwright/components/locators"; diff --git a/src/components/button-minor/button-minor.stories.mdx b/src/components/button-minor/button-minor.stories.mdx deleted file mode 100644 index f3bb276d2a..0000000000 --- a/src/components/button-minor/button-minor.stories.mdx +++ /dev/null @@ -1,241 +0,0 @@ -import { Meta, Story, Canvas } from "@storybook/addon-docs"; - -import ButtonMinor from "."; -import Button from "../button"; -import StyledSystemProps from "../../../.storybook/utils/styled-system-props"; -import * as stories from "./button-minor.stories"; - - - -# Button Minor - - - Product Design System component - Button Minor Component - - -- A minor button is a user interface button rather than a primary action button. -- It is less prominent than a major button. - -## Contents - -- [Quick Start](#quick-start) -- [Examples](#examples) -- [Props](#props) - -## Quickstart - -```javascript -import ButtonMinor from "carbon-react/lib/components/button-minor"; -``` - -## Examples - -### Primary Buttons - -For the single most prominent call to action on the page (e.g. Save, Submit, Continue). - - - - - -Primary buttons can be destructive. - - - - - -Primary buttons can be disabled. - - - - - -Primary buttons can have an icon positioned before or after the text. - - - - - -Primary buttons can be `fullWidth`. - - - - - -Primary buttons can be set into `noWrap` mode to prevent text wrapping. - - - - - -### Secondary Buttons - -Less prominent, there can be multiple secondary buttons on a page. -Secondary buttons are transparent, rather than white. - - - - - -Secondary buttons can be destructive. - - - - - -Secondary buttons can be disabled. - - - - - -Secondary buttons can have an icon positioned before or after the text. - - - - - -Secondary buttons can be `fullWidth`. - - - - - -Secondary buttons can be set into `noWrap` mode to prevent text wrapping. - - - - - -### Tertiary Buttons - -Tertiary Buttons or 'ghost' buttons are used for reversing actions, like 'Cancel' or 'Back'. - - - - - -Tertiary buttons can be destructive. - - - - - -Tertiary buttons can be disabled. - - - - - -Tertiary buttons can have an icon positioned before or after the text. - - - - - -Tertiary buttons can be `fullWidth`. - - - - - -Tertiary buttons can be set to `noWrap` mode to prevent text wrapping. - - - - - -### Icon Only Button - -Buttons can be rendered with just an icon. - - - - - -Icon only buttons can also display a tooltip message when the icon is hovered over. This can be acheived by passing a string to the `iconTooltipMessage` prop. - - - - - - -## Props - -Options shared between all of the above types of buttons. When setting padding we recommend using either the `p`, `py` -or `px` props to ensure the spacing within the button is applied evenly. - -### Button Minor - - diff --git a/src/components/button-minor/button-minor.stories.tsx b/src/components/button-minor/button-minor.stories.tsx index ecf682c855..6de1c1f6cd 100644 --- a/src/components/button-minor/button-minor.stories.tsx +++ b/src/components/button-minor/button-minor.stories.tsx @@ -1,400 +1,472 @@ import React from "react"; +import { Meta, StoryObj } from "@storybook/react"; import ButtonMinor from "."; -export const PrimaryButton = () => ( - <> - - Small - - - Medium - - - Large - - -); +import generateStyledSystemProps from "../../../.storybook/utils/styled-system-props"; -export const PrimaryDestructiveButton = () => ( - <> - - Small - - - Medium - - - Large - - +const styledSystemProps = generateStyledSystemProps( + { + spacing: true, + }, + { pt: "1px", pb: "1px", px: "24px" } ); -export const PrimaryDisabledButton = () => ( - <> - - Small - - - Medium - - - Large - - -); +const meta: Meta = { + title: "Button Minor", + component: ButtonMinor, + argTypes: { + ...styledSystemProps, + }, +}; -export const PrimaryIconButton = () => ( - <> - - Medium - - - Medium - - - Medium - - -); +export default meta; +type Story = StoryObj; -export const PrimaryFullWidthButton = () => ( - <> +export const PrimaryButton: Story = () => { + return ( + <> + + Small + + + Medium + + + Large + + + ); +}; +PrimaryButton.storyName = "Primary"; + +export const PrimaryDestructiveButton: Story = () => { + return ( + <> + + Small + + + Medium + + + Large + + + ); +}; +PrimaryDestructiveButton.storyName = "Primary/Destructive"; + +export const PrimaryDisabledButton: Story = () => { + return ( + <> + + Small + + + Medium + + + Large + + + ); +}; +PrimaryDisabledButton.storyName = "Primary/Disabled"; + +export const PrimaryIconButton: Story = () => { + return ( + <> + + Medium + + + Medium + + + Medium + + + ); +}; +PrimaryIconButton.storyName = "Primary/Icon"; + +export const PrimaryFullWidthButton: Story = () => { + return ( Full Width - -); + ); +}; +PrimaryFullWidthButton.storyName = "Primary/Full Width"; -export const PrimaryNoWrapButton = () => ( - <> +export const PrimaryNoWrapButton: Story = () => { + return ( Long button text - -); + ); +}; +PrimaryNoWrapButton.storyName = "Primary/No Wrap"; -export const SecondaryButton = () => ( - <> - - Small - - - Medium - - - Large - - -); +export const SecondaryButton: Story = () => { + return ( + <> + + Small + + + Medium + + + Large + + + ); +}; +SecondaryButton.storyName = "Secondary"; -export const SecondaryDestructiveButton = () => ( - <> - - Small - - - Medium - - - Large - - -); +export const SecondaryDestructiveButton: Story = () => { + return ( + <> + + Small + + + Medium + + + Large + + + ); +}; +SecondaryDestructiveButton.storyName = "Secondary/Destructive"; -export const SecondaryDisabledButton = () => ( - <> - - Small - - - Medium - - - Large - - -); +export const SecondaryDisabledButton: Story = () => { + return ( + <> + + Small + + + Medium + + + Large + + + ); +}; +SecondaryDisabledButton.storyName = "Secondary/Disabled"; -export const SecondaryIconButton = () => ( - <> - - Medium - - - Medium - - - Medium - - -); +export const SecondaryIconButton: Story = () => { + return ( + <> + + Medium + + + Medium + + + Medium + + + ); +}; +SecondaryIconButton.storyName = "Secondary/Icon"; -export const SecondaryFullWidthButton = () => ( - <> +export const SecondaryFullWidthButton: Story = () => { + return ( Full Width - -); + ); +}; +SecondaryFullWidthButton.storyName = "Secondary/Full Width"; -export const SecondaryNoWrapButton = () => ( - <> +export const SecondaryNoWrapButton: Story = () => { + return ( Long button text - -); + ); +}; +SecondaryNoWrapButton.storyName = "Secondary/No Wrap"; +SecondaryNoWrapButton.parameters = { chromatic: { disableSnapshot: true } }; -export const TertiaryButton = () => ( - <> - - Small - - - Medium - - - Large - - -); +export const TertiaryButton: Story = () => { + return ( + <> + + Small + + + Medium + + + Large + + + ); +}; +TertiaryButton.storyName = "Tertiary"; -export const TertiaryDestructiveButton = () => ( - <> - - Small - - - Medium - - - Large - - -); +export const TertiaryDestructiveButton: Story = () => { + return ( + <> + + Small + + + Medium + + + Large + + + ); +}; +TertiaryDestructiveButton.storyName = "Tertiary/Destructive"; -export const TertiaryDisabledButton = () => ( - <> - - Small - - - Medium - - - Large - - -); +export const TertiaryDisabledButton: Story = () => { + return ( + <> + + Small + + + Medium + + + Large + + + ); +}; +TertiaryDisabledButton.storyName = "Tertiary/Disabled"; -export const TertiaryIconButton = () => ( - <> - - Medium - - - Medium - - - Medium - - -); +export const TertiaryIconButton: Story = () => { + return ( + <> + + Medium + + + Medium + + + Medium + + + ); +}; +TertiaryIconButton.storyName = "Tertiary/Icon"; -export const TertiaryFullWidthButton = () => ( - <> +export const TertiaryFullWidthButton: Story = () => { + return ( Full Width - -); + ); +}; +TertiaryFullWidthButton.storyName = "Tertiary/Full Width"; -export const TertiaryNoWrapButton = () => ( - <> +export const TertiaryNoWrapButton: Story = () => { + return ( Long button text - -); + ); +}; +TertiaryNoWrapButton.storyName = "Tertiary/No Wrap"; +TertiaryNoWrapButton.parameters = { chromatic: { disableSnapshot: true } }; -export const IconOnlyButton = () => ( - <> - - - - -); +export const IconOnlyButton: Story = () => { + return ( + <> + + + + + ); +}; +IconOnlyButton.storyName = "Icon Only"; -export const IconOnlyWithTooltipButton = () => ( - <> - - - - -); +export const IconOnlyWithTooltipButton: Story = () => { + return ( + <> + + + + + ); +}; +IconOnlyWithTooltipButton.storyName = "Icon Only With Tooltip"; +IconOnlyWithTooltipButton.parameters = { chromatic: { disableSnapshot: true } }; diff --git a/src/components/button-minor/components.test-pw.tsx b/src/components/button-minor/components.test-pw.tsx index 581e71209b..9f9656d802 100644 --- a/src/components/button-minor/components.test-pw.tsx +++ b/src/components/button-minor/components.test-pw.tsx @@ -23,3 +23,428 @@ const ButtonMinorDifferentTypes = (props: ButtonMinorProps) => { }; export { Default, ButtonMinorCustom, ButtonMinorDifferentTypes }; + +export const PrimaryButton = () => { + return ( + <> + + Small + + + Medium + + + Large + + + ); +}; + +export const PrimaryDestructiveButton = () => { + return ( + <> + + Small + + + Medium + + + Large + + + ); +}; + +export const PrimaryDisabledButton = () => { + return ( + <> + + Small + + + Medium + + + Large + + + ); +}; + +export const PrimaryIconButton = () => { + return ( + <> + + Medium + + + Medium + + + Medium + + + ); +}; + +export const PrimaryFullWidthButton = () => { + return ( + + Full Width + + ); +}; + +export const PrimaryNoWrapButton = () => { + return ( + + Long button text + + ); +}; + +export const SecondaryButton = () => { + return ( + <> + + Small + + + Medium + + + Large + + + ); +}; + +export const SecondaryDestructiveButton = () => { + return ( + <> + + Small + + + Medium + + + Large + + + ); +}; + +export const SecondaryDisabledButton = () => { + return ( + <> + + Small + + + Medium + + + Large + + + ); +}; + +export const SecondaryIconButton = () => { + return ( + <> + + Medium + + + Medium + + + Medium + + + ); +}; + +export const SecondaryFullWidthButton = () => { + return ( + + Full Width + + ); +}; + +export const SecondaryNoWrapButton = () => { + return ( + + Long button text + + ); +}; + +export const TertiaryButton = () => { + return ( + <> + + Small + + + Medium + + + Large + + + ); +}; + +export const TertiaryDestructiveButton = () => { + return ( + <> + + Small + + + Medium + + + Large + + + ); +}; + +export const TertiaryDisabledButton = () => { + return ( + <> + + Small + + + Medium + + + Large + + + ); +}; + +export const TertiaryIconButton = () => { + return ( + <> + + Medium + + + Medium + + + Medium + + + ); +}; + +export const TertiaryFullWidthButton = () => { + return ( + + Full Width + + ); +}; + +export const TertiaryNoWrapButton = () => { + return ( + + Long button text + + ); +}; + +export const IconOnlyButton = () => { + return ( + <> + + + + + ); +}; + +export const IconOnlyWithTooltipButton = () => { + return ( + <> + + + + + ); +}; diff --git a/src/components/button-toggle/button-toggle-group/button-toggle-group.stories.tsx b/src/components/button-toggle/button-toggle-group/button-toggle-group.stories.tsx index f18402b182..f0486ff7e5 100644 --- a/src/components/button-toggle/button-toggle-group/button-toggle-group.stories.tsx +++ b/src/components/button-toggle/button-toggle-group/button-toggle-group.stories.tsx @@ -1,172 +1,32 @@ -import React, { useState } from "react"; -import { ComponentStory } from "@storybook/react"; +import { Meta, StoryObj } from "@storybook/react"; +import generateStyledSystemProps from "../../../../.storybook/utils/styled-system-props"; import ButtonToggleGroup from "."; -import { ButtonToggle } from ".."; -import Box from "../../box"; -export const Default: ComponentStory = () => ( - - - Foo - Bar - Baz - - -); - -export const Controlled: ComponentStory = () => { - const [value, setValue] = useState("bar"); - function onChangeHandler( - event: React.MouseEvent, - selectedValue?: string - ) { - setValue(selectedValue as string); - } - return ( - - - Foo - Bar - Baz - - - ); +/** + * This file is used primarily as a means to generate the props table. + * It contains the tag: ["hideInSidebar"] so that it is not included in the sidebar. + */ + +const styledSystemProps = generateStyledSystemProps({ + margin: true, +}); + +const meta: Meta = { + title: "Button Toggle/Button Toggle Group", + component: ButtonToggleGroup, + argTypes: { + ...styledSystemProps, + }, + tags: ["hideInSidebar"], + parameters: { + chromatic: { disableSnapshot: true }, + }, }; -export const FullWidth: ComponentStory = () => ( - - {}} - > - Foo - Bar - Baz - - -); - -export const InputHint: ComponentStory = () => ( - - - Foo - Bar - Baz - - -); - -export const AllowDeselection: ComponentStory< - typeof ButtonToggleGroup -> = () => { - const [value, setValue] = useState("bar"); - function onChangeHandler( - event: React.MouseEvent, - selectedValue?: string - ) { - setValue(selectedValue as string); - } - return ( - - - Foo - Bar - Baz - - - ); -}; +export default meta; +type Story = StoryObj; -export const AriaLabel: ComponentStory = () => { - const [value, setValue] = useState("bar"); - function onChangeHandler( - event: React.MouseEvent, - selectedValue?: string - ) { - setValue(selectedValue as string); - } - return ( - - - Foo - Bar - Baz - - - ); +export const Default: Story = { + args: {}, }; - -export const DisabledGroup: ComponentStory = () => ( - - - Foo - Bar - Baz - - -); - -export const WrappedButtons: ComponentStory = () => ( - - - - Add - - - Share - - - Tick - - - Email - - - Alert - - - Calendar - - - -); diff --git a/src/components/button-toggle/button-toggle.mdx b/src/components/button-toggle/button-toggle.mdx new file mode 100644 index 0000000000..5af6828de8 --- /dev/null +++ b/src/components/button-toggle/button-toggle.mdx @@ -0,0 +1,132 @@ +import { Meta, ArgTypes, Canvas } from "@storybook/blocks"; + +import * as ButtonToggleStories from "./button-toggle.stories"; +import * as ButtonToggleGroupStories from "./button-toggle-group/button-toggle-group.stories"; + + + +# Button Toggle + + + Product Design System component + + +Press one of the buttons to make selection. This component should be used when user has to make a choice between a small number of options. + +## Contents + +- [Quick Start](#quick-start) +- [Examples](#examples) +- [Props](#props) + +## Quick Start + +```javascript +import { + ButtonToggle, + ButtonToggleGroup, +} from "carbon-react/lib/components/button-toggle"; +``` + +## Examples + +### Default + + + +### With inputHint + + + +### Controlled + + + +### With aria-label + +If you do not want a visible label to appear above the group, you should use the aria-label prop to give it a non-visible +accessible name to be used by screen readers. Failure to do this will result in accessibility violations. + + + +### With fullWidth + +When the `fullWidth` prop is `true`, the buttons will expand in size to take up the full width of the container. + + + +### Allowing deselection + +By default, in a `ButtonToggleGroup` there is no way to deselect the currently-selected toggle button except by selecting another one. +The `allowDeselect` prop changes this behaviour, making it possible for there to be no selection. + +If you use this, you should include text in the `inputHint` prop which makes clear that deselection is allowed, as in the example below. + + + +### Small icon + + + +### Large icon + + + +### Icon only + +While we do not advocate the use of icon-only buttons for accessibility reasons, the `aria-label` or `aria-labelledby` props can be used with `buttonIcon` so assistive techniques are aware of the action that will be taken when the component pressed. + + + +### Small + + + +### Small with small icon + + + +### Small with large icon + + + +### Large + + + +### Large with small icon + + + +### Large with large icon + + + +### Disabled Button + + + +### Disabled Group + + + +### Wrapped Group + +Buttons will wrap onto the next line in smaller screens. + + + +## Props + +### Button Toggle + + + +### Button Toggle Group + + diff --git a/src/components/button-toggle/button-toggle.stories.mdx b/src/components/button-toggle/button-toggle.stories.mdx deleted file mode 100644 index e4a86aa3ee..0000000000 --- a/src/components/button-toggle/button-toggle.stories.mdx +++ /dev/null @@ -1,179 +0,0 @@ -import { Meta, Story, Canvas } from "@storybook/addon-docs"; -import StyledSystemProps from "../../../.storybook/utils/styled-system-props"; -import LinkTo from "@storybook/addon-links/react"; -import { ButtonToggle, ButtonToggleGroup } from "."; - -import * as stories from "./button-toggle.stories"; -import * as groupStories from "./button-toggle-group/button-toggle-group.stories"; - - - -# Button Toggle - - - Product Design System component - - -Press one of the buttons to make selection. This component should be used when user has to make a choice between a small number of options. - -## Contents - -- [Quick Start](#quick-start) -- [Examples](#examples) -- [Props](#props) - -## Quick Start - -```javascript -import { - ButtonToggle, - ButtonToggleGroup, -} from "carbon-react/lib/components/button-toggle"; -``` - -- You should use the ButtonToggleGroup component if you need to wrap multiple `ButtonToggle` components together. -- An icon could be added to make the meaning of an option clearer. - -## Examples - -### Default - - - - - -### With inputHint - - - - - -### Controlled - - - - - -### With aria-label - -If you do not want a visible label to appear above the group, you should use the aria-label prop to give it a non-visible -accessible name to be used by screenreaders. Failure to do this will result in accessibility violations. - - - - - -### With fullWidth - -When the `fullWidth` prop is `true`, the buttons will expand in size to take up the full width of the container. - - - - - -### Allowing deselection - -By default, in a `ButtonToggleGroup` there is no way to deselect the currently-selected toggle button except by selecting another one. -The `allowDeselect` prop changes this behaviour, making it possible for there to be no selection. - -If you use this, you should include text in the `inputHint` prop which makes clear that deselection is allowed, as in the example below. - - - - - -### Small icon - - - - - -### Large icon - - - - - -### Icon only - -While we do not advocate the use of icon-only buttons for accessibility reasons, the `aria-label` or `aria-labelledby` props can be used with `buttonIcon` so assistive techniques are aware of the action that will be taken when the component pressed. - - - - - -### Small - - - - - -### Small with small icon - - - - - -### Small with large icon - - - - - -### Large - - - - - -### Large with small icon - - - - - -### Large with large icon - - - - - -### Disabled Button - - - - - -### Disabled Group - - - - - -### Wrapped Group - -Buttons will wrap onto the next line in smaller screens. - - - - - -## Props - -### Button Toggle - - - -### Button Toggle Group - - diff --git a/src/components/button-toggle/button-toggle.stories.tsx b/src/components/button-toggle/button-toggle.stories.tsx index 38343efc2a..850bb1bb82 100644 --- a/src/components/button-toggle/button-toggle.stories.tsx +++ b/src/components/button-toggle/button-toggle.stories.tsx @@ -1,230 +1,408 @@ -import React from "react"; -import { ComponentStory } from "@storybook/react"; +import React, { useState } from "react"; +import { Meta, StoryObj } from "@storybook/react"; import { ButtonToggle, ButtonToggleGroup } from "."; import Box from "../box"; -export const Default: ComponentStory = () => ( - - - Foo - Bar - Baz - - -); +const meta: Meta = { + title: "Button Toggle", + component: ButtonToggle, + parameters: { themeProvider: { chromatic: { theme: "sage" } } }, +}; -export const DefaultSmallIcon: ComponentStory = () => ( - - - - Add - - - Share - - - Tick - - - -); +export default meta; +type Story = StoryObj; -export const DefaultLargeIcon: ComponentStory = () => ( - - - - Add - - - Share - - - Tick - - - -); +export const Default: Story = () => { + return ( + + + Foo + Bar + Baz + + + ); +}; +Default.storyName = "Default"; -export const iconOnly: ComponentStory = () => ( - - - - - - - -); +export const InputHint: Story = () => { + return ( + + + Foo + Bar + Baz + + + ); +}; +InputHint.storyName = "Input Hint"; -export const small: ComponentStory = () => ( - - - - Add - - - Share - - - Tick - - - -); +export const Controlled: Story = () => { + const [value, setValue] = useState("bar"); + function onChangeHandler( + event: React.MouseEvent, + selectedValue?: string + ) { + setValue(selectedValue as string); + } + return ( + + + Foo + Bar + Baz + + + ); +}; +Controlled.storyName = "Controlled"; -export const smallSmallIcon: ComponentStory = () => ( - - - - Add - - - Share - - - Tick - - - -); +export const AriaLabel: Story = () => { + const [value, setValue] = useState("bar"); + function onChangeHandler( + event: React.MouseEvent, + selectedValue?: string + ) { + setValue(selectedValue as string); + } + return ( + + + Foo + Bar + Baz + + + ); +}; +AriaLabel.storyName = "Aria Label"; -export const smallLargeIcon: ComponentStory = () => ( - - - { + return ( + + {}} > - Add - - Foo + Bar + Baz + + + ); +}; +FullWidth.storyName = "Full Width"; + +export const AllowDeselection: Story = () => { + const [value, setValue] = useState("bar"); + function onChangeHandler( + event: React.MouseEvent, + selectedValue?: string + ) { + setValue(selectedValue as string); + } + return ( + + - Share - - Foo + Bar + Baz + + + ); +}; +AllowDeselection.storyName = "Allow Deselection"; + +export const DefaultSmallIcon: Story = () => { + return ( + + + + Add + + + Share + + + Tick + + + + ); +}; +DefaultSmallIcon.storyName = "Small Icon"; + +export const DefaultLargeIcon: Story = () => { + return ( + + + + Add + + + Share + + + Tick + + + + ); +}; +DefaultLargeIcon.storyName = "Large Icon"; + +export const IconOnly: Story = () => { + return ( + + + + + + + + ); +}; +IconOnly.storyName = "Icon Only"; + +export const Small: Story = () => { + return ( + + + + Add + + + Share + + + Tick + + + + ); +}; +Small.storyName = "Small"; + +export const SmallSmallIcon: Story = () => { + return ( + + - Tick - - - -); + + Add + + + Share + + + Tick + + + + ); +}; +SmallSmallIcon.storyName = "Small with Small Icon"; -export const large: ComponentStory = () => ( - - - - Add - - - Share - - - Tick - - - -); +export const SmallLargeIcon: Story = () => { + return ( + + + + Add + + + Share + + + Tick + + + + ); +}; +SmallLargeIcon.storyName = "Small with Large Icon"; + +export const Large: Story = () => { + return ( + + + + Add + + + Share + + + Tick + + + + ); +}; +Large.storyName = "Large"; + +export const LargeSmallIcon: Story = () => { + return ( + + + + Add + + + Share + + + Tick + + + + ); +}; +LargeSmallIcon.storyName = "Large with Small Icon"; + +export const LargeLargeIcon: Story = () => { + return ( + + + + Add + + + Share + + + Tick + + + + ); +}; +LargeLargeIcon.storyName = "Large Large Icon"; -export const largeSmallIcon: ComponentStory = () => ( - +export const DisabledButton: Story = () => { + return ( + + + + Foo + + Bar + Baz + + + ); +}; +DisabledButton.storyName = "Disabled Button"; + +export const DisabledGroup: Story = () => ( + - - Add - - - Share - - - Tick - + Foo + Bar + Baz ); +DisabledGroup.storyName = "Disabled Group"; -export const largeLargeIcon: ComponentStory = () => ( - +export const WrappedButtons: Story = () => ( + - + Add - + Share - + Tick - - -); - -export const disabledButton: ComponentStory = () => ( - - - - Foo - - Bar - Baz - - -); - -export const Grouped: ComponentStory = () => ( - - {}} - > - - Foo + + Email - - Bar + + Alert - - Baz + + Calendar ); +WrappedButtons.storyName = "Wrapped Buttons"; diff --git a/src/components/button/button.mdx b/src/components/button/button.mdx new file mode 100644 index 0000000000..946f1c6fcf --- /dev/null +++ b/src/components/button/button.mdx @@ -0,0 +1,223 @@ +import { Meta, ArgTypes, Canvas } from "@storybook/blocks"; + +import * as ButtonStories from "./button.stories"; + + + +# Button + + + Product Design System component - Button Major Component + + +A Button triggers a single action or event. +Use it to submit a form (Save), to advance to the next step in a process (Next), or to create a new item (New). + +## Contents + +- [Quick Start](#quick-start) +- [Examples](#examples) +- [Props](#props) + +## Quickstart + +```javascript +import Button from "carbon-react/lib/components/button"; +``` + +## Examples + +### Primary Buttons + +For the single most prominent call to action on the page (e.g. Save, Submit, Continue). + + + +Primary buttons can be destructive. + + + +Primary buttons can be disabled. + + + +Primary buttons can have an icon positioned before or after the text. + + + +Primary buttons can be `fullWidth`. + + + +Primary buttons can be set into `noWrap` mode to prevent text wrapping. + + + +### Secondary Buttons + +Less prominent, there can be multiple secondary buttons on a page. +Secondary buttons are transparent, rather than white. + + + +Secondary buttons can be destructive. + + + +Secondary buttons can be disabled. + + + +Secondary buttons can have an icon positioned before or after the text. + + + +Secondary buttons can be `fullWidth`. + + + +Secondary buttons can be set into `noWrap` mode to prevent text wrapping. + + + +### Tertiary Buttons + +Tertiary or ‘ghost’ buttons are used for reversing actions, like ‘Cancel’ or ‘Back’. + + + +Tertiary buttons can be destructive. + + + +Tertiary buttons can be disabled. + + + +Tertiary buttons can have an icon positioned before or after the text. + + + +Tertiary buttons can be `fullWidth`. + + + +Tertiary buttons can be set to `noWrap` mode to prevent text wrapping. + + + +### Dashed Buttons + +Dashed buttons are used for adding new content that replaces empty states. + + + +Dashed buttons can be disabled. + + + +Dashed buttons can have an icon positioned before or after the text. + + + +Dashed buttons can be `fullWidth`. + + + +Dashed buttons can be set to `noWrap` mode to prevent text wrapping. + + + +### Dark Background Buttons + +Dark Background buttons are used for adding new content that replaces empty states. + + + +Dark Background buttons can be disabled. + + + +Dark Background buttons can have an icon positioned before or after the text. + + + +Dark Background buttons can be `fullWidth`. + + + +Dark Background buttons can be set to `noWrap` mode to prevent text wrapping. + + + +### Gradient Buttons + +The `Button` component supports a `gradient-white` `buttonType`. + + + +`gradient-white` buttons can also be `disabled`. + + + +`gradient-white` buttons can have an icon positioned before or after the text. + + + +`gradient-white` buttons can be `fullWidth`. + + + +`gradient-white` buttons can be set to `noWrap` mode to prevent text wrapping. + + + +The `Button` component supports a `gradient-grey` `buttonType`. + + + +`gradient-grey` buttons can also be `disabled`. + + + +`gradient-grey` buttons can have an icon positioned before or after the text. + + + +`gradient-grey` buttons can be `fullWidth`. + + + +`gradient-grey` buttons can be set to `noWrap` mode to prevent text wrapping. + + + +### Button as a link + +Passing in the `href` prop will render an anchor with `role="button"` and the Button styles. The `target` and `rel` props are also available. + + + +### Icon Only Button + +Buttons can be rendered with just an icon. + + + +Icon only buttons can also display a tooltip message when the icon is hovered over. This can be acheived by passing a string to the `iconTooltipMessage` prop. + + + +## Props + +Options shared between all of the above types of buttons. When setting padding we recommend using either the `p`, `py` +or `px` props to ensure the spacing within the button is applied evenly. + +### Button + + diff --git a/src/components/button/button.stories.mdx b/src/components/button/button.stories.mdx deleted file mode 100644 index a6ee08e4d4..0000000000 --- a/src/components/button/button.stories.mdx +++ /dev/null @@ -1,316 +0,0 @@ -import { Meta, Story, Canvas } from "@storybook/addon-docs"; - -import StyledSystemProps from "../../../.storybook/utils/styled-system-props"; - -import Button from "."; - -import * as stories from "./button.stories"; - - - -# Button - - - Product Design System component - Button Major Component - - -A Button triggers a single action or event. -Use it to submit a form (Save), to advance to the next step in a process (Next), or to create a new item (New). - -## Contents - -- [Quick Start](#quick-start) -- [Examples](#examples) -- [Props](#props) - -## Quickstart - -```javascript -import Button from "carbon-react/lib/components/button"; -``` - -## Examples - -### Primary Buttons - -For the single most prominent call to action on the page (e.g. Save, Submit, Continue). - - - - - -Primary buttons can be destructive. - - - - - -Primary buttons can be disabled. - - - - - -Primary buttons can have an icon positioned before or after the text. - - - - - -Primary buttons can be `fullWidth`. - - - - - -Primary buttons can be set into `noWrap` mode to prevent text wrapping. - - - - - -### Secondary Buttons - -Less prominent, there can be multiple secondary buttons on a page. -Secondary buttons are transparent, rather than white. - - - - - -Secondary buttons can be destructive. - - - - - -Secondary buttons can be disabled. - - - - - -Secondary buttons can have an icon positioned before or after the text. - - - - - -Secondary buttons can be `fullWidth`. - - - - - -Secondary buttons can be set into `noWrap` mode to prevent text wrapping. - - - - - -### Tertiary Buttons - -Tertiary or ‘ghost’ buttons are used for reversing actions, like ‘Cancel’ or ‘Back’. - - - - - -Tertiary buttons can be destructive. - - - - - -Tertiary buttons can be disabled. - - - - - -Tertiary buttons can have an icon positioned before or after the text. - - - - - -Tertiary buttons can be `fullWidth`. - - - - - -Tertiary buttons can be set to `noWrap` mode to prevent text wrapping. - - - - - -### Dashed Buttons - -Dashed buttons are used for adding new content that replaces empty states. - - - - - -Dashed buttons can be disabled. - - - - - -Dashed buttons can have an icon positioned before or after the text. - - - - - -Dashed buttons can be `fullWidth`. - - - - - -Dashed buttons can be set to `noWrap` mode to prevent text wrapping. - - - - - -### Dark Background Buttons - -Dark Background buttons are used for adding new content that replaces empty states. - - - - - -Dark Background buttons can be disabled. - - - - - -Dark Background buttons can have an icon positioned before or after the text. - - - - - -Dark Background buttons can be `fullWidth`. - - - - - -Dark Background buttons can be set to `noWrap` mode to prevent text wrapping. - - - - - -### Gradient Buttons - -The `Button` component supports a `gradient-white` `buttonType`. - - - - - -`gradient-white` buttons can also be `disabled`. - - - - - -`gradient-white` buttons can have an icon positioned before or after the text. - - - - - -`gradient-white` buttons can be `fullWidth`. - - - - - -`gradient-white` buttons can be set to `noWrap` mode to prevent text wrapping. - - - - - -The `Button` component supports a `gradient-grey` `buttonType`. - - - - - -`gradient-grey` buttons can also be `disabled`. - - - - - -`gradient-grey` buttons can have an icon positioned before or after the text. - - - - - -`gradient-grey` buttons can be `fullWidth`. - - - - - -`gradient-grey` buttons can be set to `noWrap` mode to prevent text wrapping. - - - - - -### Button as a link - -Passing in the `href` prop will render an anchor with `role="button"` and the Button styles. The `target` and `rel` props are also available. - - - - - -### Icon Only Button - -Buttons can be rendered with just an icon. - - - - - -Icon only buttons can also display a tooltip message when the icon is hovered over. This can be acheived by passing a string to the `iconTooltipMessage` prop. - - - - - -## Props - -Options shared between all of the above types of buttons. When setting padding we recommend using either the `p`, `py` -or `px` props to ensure the spacing within the button is applied evenly. - -### Button - - diff --git a/src/components/button/button.stories.tsx b/src/components/button/button.stories.tsx index 059331fdd1..b0055c739c 100644 --- a/src/components/button/button.stories.tsx +++ b/src/components/button/button.stories.tsx @@ -1,9 +1,29 @@ import React from "react"; -import { ComponentStory } from "@storybook/react"; +import { Meta, StoryObj } from "@storybook/react"; import Button from "."; import Box from "../box"; +import generateStyledSystemProps from "../../../.storybook/utils/styled-system-props"; -export const PrimaryButton: ComponentStory = () => { +const styledSystemProps = generateStyledSystemProps( + { + spacing: true, + }, + { pt: "1px", pb: "1px", px: "24px" } +); + +const meta: Meta = { + title: "Button", + component: Button, + argTypes: { + ...styledSystemProps, + }, + parameters: { chromatic: { disableSnapshot: true } }, +}; + +export default meta; +type Story = StoryObj; + +export const PrimaryButton: Story = () => { return ( - -); -SageTheme.storyName = "using latest sage theme"; +const meta: Meta = { + title: "Carbon Provider", + component: CarbonProvider, + parameters: { chromatic: { disableSnapshot: true } }, +}; -export const MintTheme: StoryFn = () => ( - - - -); -MintTheme.storyName = "using mint theme"; +export default meta; +type Story = StoryObj; + +export const SageTheme: Story = () => { + return ( + + + + ); +}; +SageTheme.storyName = "Using Latest Sage Theme"; + +export const MintTheme: Story = () => { + return ( + + + + ); +}; +MintTheme.storyName = "Using Mint Theme"; diff --git a/src/components/carbon-provider/components.test-pw.tsx b/src/components/carbon-provider/components.test-pw.tsx index 3d09494a30..2cdce4f0a1 100644 --- a/src/components/carbon-provider/components.test-pw.tsx +++ b/src/components/carbon-provider/components.test-pw.tsx @@ -28,3 +28,19 @@ const AllThemes = () => { }; export default AllThemes; + +export const SageTheme = () => { + return ( + + + + ); +}; + +export const MintTheme = () => { + return ( + + + + ); +}; diff --git a/src/components/card/card-column/card-column.stories.tsx b/src/components/card/card-column/card-column.stories.tsx new file mode 100644 index 0000000000..9189405311 --- /dev/null +++ b/src/components/card/card-column/card-column.stories.tsx @@ -0,0 +1,25 @@ +import { Meta, StoryObj } from "@storybook/react"; +import CardColumn from "."; + +/** + * This file is used primarily as a means to generate the props table. + * It contains the tag: ["hideInSidebar"] so that it is not included in the sidebar. + */ + +const meta: Meta = { + title: "CardColumn", + component: CardColumn, + tags: ["hideInSidebar"], + parameters: { + chromatic: { disableSnapshot: true }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + children: [], + }, +}; diff --git a/src/components/card/card-footer/card-footer.stories.tsx b/src/components/card/card-footer/card-footer.stories.tsx new file mode 100644 index 0000000000..19c4ac81d3 --- /dev/null +++ b/src/components/card/card-footer/card-footer.stories.tsx @@ -0,0 +1,33 @@ +import { Meta, StoryObj } from "@storybook/react"; +import generateStyledSystemProps from "../../../../.storybook/utils/styled-system-props"; +import CardFooter from "."; + +/** + * This file is used primarily as a means to generate the props table. + * It contains the tag: ["hideInSidebar"] so that it is not included in the sidebar. + */ + +const styledSystemProps = generateStyledSystemProps({ + spacing: true, +}); + +const meta: Meta = { + title: "CardFooter", + component: CardFooter, + tags: ["hideInSidebar"], + argTypes: { + ...styledSystemProps, + }, + parameters: { + chromatic: { disableSnapshot: true }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + children: [], + }, +}; diff --git a/src/components/card/card-row/card-row.stories.tsx b/src/components/card/card-row/card-row.stories.tsx new file mode 100644 index 0000000000..c09ea86869 --- /dev/null +++ b/src/components/card/card-row/card-row.stories.tsx @@ -0,0 +1,33 @@ +import { Meta, StoryObj } from "@storybook/react"; +import generateStyledSystemProps from "../../../../.storybook/utils/styled-system-props"; +import CardRow from "."; + +/** + * This file is used primarily as a means to generate the props table. + * It contains the tag: ["hideInSidebar"] so that it is not included in the sidebar. + */ + +const styledSystemProps = generateStyledSystemProps({ + padding: true, +}); + +const meta: Meta = { + title: "CardRow", + component: CardRow, + tags: ["hideInSidebar"], + argTypes: { + ...styledSystemProps, + }, + parameters: { + chromatic: { disableSnapshot: true }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + children: [], + }, +}; diff --git a/src/components/card/card.mdx b/src/components/card/card.mdx new file mode 100644 index 0000000000..d3883c34b6 --- /dev/null +++ b/src/components/card/card.mdx @@ -0,0 +1,124 @@ +import { Meta, ArgTypes, Canvas } from "@storybook/blocks"; + +import * as CardStories from "./card.stories"; +import * as CardColumnStories from "./card-column/card-column.stories"; +import * as CardFooterStories from "./card-footer/card-footer.stories"; +import * as CardRowStories from "./card-row/card-row.stories"; + + + +# Card + + + Product Design System component + + +A container for interactive content and controls related to a single subject. + +## Contents + +- [Quick Start](#quick-start) +- [Examples](#examples) +- [Props](#props) + +## Quick start + +```javascript +import { + Card, + CardRow, + CardFooter, + CardColumn, +} from "carbon-react/lib/components/card"; +``` + +## Examples + +### Default - medium spacing + + + +### Small spacing + + + +### Large spacing + + + +### With large roundness on corners + + + +### With width provided + + + +### Interactive + +The card is "interactive" when you pass either or both of `onClick` and `href` props. +Passing just an `onClick` prop will render a `button` element within the `Card`. +Passing an `href` (with or without an `onClick`) will render an `a`nchor element. +Setting the `draggable` prop will negate both `onClick` and `href` prop values and will render a `div` instead. + + + +### With custom box shadow + + + +### Different `` padding + + + +### Different `` padding + + + +### More `` examples + + + +## With string as child + + + +## With custom height + + + +## With draggable + +By using the `draggable` prop, Cards can be implemented to be draggable. + +This example uses the `react-dnd` and `react-dnd-html5-backend` packages. + +```javascript +import { DndProvider, useDrag, useDrop } from "react-dnd"; +import { HTML5Backend } from "react-dnd-html5-backend"; +``` + + + +## Props + +### Card + + + +### CardRow + + + +### CardColumn + + + +### CardFooter + + diff --git a/src/components/card/card.pw.tsx b/src/components/card/card.pw.tsx index aa2e9d086f..7dd78a088b 100644 --- a/src/components/card/card.pw.tsx +++ b/src/components/card/card.pw.tsx @@ -16,22 +16,20 @@ import { } from "../../../playwright/support/helper"; import { Card } from "../../../src/components/card"; import { - DifferentCardFooterPadding, - DifferentCardRowPadding, - Interactive, - LargeSpacing, - MoreExamplesOfCardFooter, + CardComponent, + CardTextAlignment, + DraggableExample, SmallSpacing, + LargeSpacing, WithWidthProvided, WithCustomBoxShadow, WithCustomHeight, + DifferentCardFooterPadding, + DifferentCardRowPadding, + Interactive, + MoreExamplesOfCardFooter, WithDraggable, WithStringAsChild, -} from "../../../src/components/card/card.stories"; -import { - CardComponent, - CardTextAlignment, - DraggableExample, } from "../../../src/components/card/components.test-pw"; const testData = [CHARACTERS.DIACRITICS, CHARACTERS.SPECIALCHARACTERS]; diff --git a/src/components/card/card.stories.mdx b/src/components/card/card.stories.mdx deleted file mode 100644 index db78189ebc..0000000000 --- a/src/components/card/card.stories.mdx +++ /dev/null @@ -1,161 +0,0 @@ -import { Meta, Story, Canvas, ArgsTable } from "@storybook/addon-docs"; -import StyledSystemProps from "../../../.storybook/utils/styled-system-props"; -import { Card, CardRow, CardFooter, CardColumn } from "."; - -import * as stories from "./card.stories.tsx"; - - - -# Card - - - Product Design System component - - -A container for interactive content and controls related to a single subject. - -## Contents - -- [Quick Start](#quick-start) -- [Examples](#examples) -- [Props](#props) - -## Quick start - -```javascript -import { - Card, - CardRow, - CardFooter, - CardColumn, -} from "carbon-react/lib/components/card"; -``` - -## Examples - -### Default - medium spacing - - - - - -### Small spacing - - - - - -### Large spacing - - - - - -### With large roundness on corners - - - - - -### With width provided - - - - - -### Interactive - -The card is "interactive" when you pass either or both of `onClick` and `href` props. -Passing just an `onClick` prop will render a `button` element within the `Card`. -Passing an `href` (with or without an `onClick`) will render an `a`nchor element. -Setting the `draggable` prop will negate both `onClick` and `href` prop values and will render a `div` instead. - - - - - -### With custom box shadow - - - - - - -### Different `` padding - - - - - -### Different `` padding - - - - - -### More `` examples - - - - - -## With string as child - - - - - -## With custom height - - - - - -## With draggable - -By using the `draggable` prop, Cards can be implemented to be draggable. - -This example uses the `react-dnd` and `react-dnd-html5-backend` packages. - -```javascript -import { DndProvider, useDrag, useDrop } from "react-dnd"; -import { HTML5Backend } from "react-dnd-html5-backend"; -``` - - - - - -## Props - -### Card - - - -### CardRow - - - -### CardColumn - - - -### CardFooter - - diff --git a/src/components/card/card.stories.tsx b/src/components/card/card.stories.tsx index 37af6e0fe3..811d969a09 100644 --- a/src/components/card/card.stories.tsx +++ b/src/components/card/card.stories.tsx @@ -1,6 +1,5 @@ import React, { useState } from "react"; -import { ComponentStory, StoryFn } from "@storybook/react"; - +import { Meta, StoryObj } from "@storybook/react"; import { DndProvider, useDrag, useDrop } from "react-dnd"; import { HTML5Backend } from "react-dnd-html5-backend"; import { Card, CardRow, CardFooter, CardColumn, CardProps } from "."; @@ -14,680 +13,732 @@ import Button from "../button"; import VerticalDivider from "../vertical-divider"; import IconButton from "../icon-button"; -export const DefaultStory: ComponentStory = (args: CardProps) => ( - {}} - footer={ - - - - Footer link - - - - } - > - - - - - Additional text - - - - - - - - - - Body text - - - Even more text - - - -); +import generateStyledSystemProps from "../../../.storybook/utils/styled-system-props"; -export const SmallSpacing = () => ( - - - - Footer link - - - - } - > - - - - - Additional text - - - - - - - - - - Body text - - - Even more text - - - -); - -export const LargeSpacing = () => ( - - - - Footer link - - - - } - > - - - - - Additional text - - - - - - - - - - Body text - - - Even more text - - - -); +const styledSystemProps = generateStyledSystemProps({ + margin: true, +}); -export const WithWidthProvided = () => ( - - - - Footer link - - - - } - > - - - - - Additional text - - - - - - - - - - Body text - - - Even more text - - - -); +const meta: Meta = { + title: "Card", + component: Card, + argTypes: { + ...styledSystemProps, + }, + parameters: { controls: { disable: true } }, +}; -export const WithCustomHeight = () => ( - - - - Footer link - - - - } - > - - - - - Additional text - - - - - - - - - - Body text - - - Even more text - - - -); +export default meta; +type Story = StoryObj; -export const WithExtraRoundness = () => ( - - - - Footer link - - - - } - > - - - - - Additional text - - - - - - - - - - Body text - - - Even more text - - - -); - -export const Interactive: StoryFn = () => { - const [clickCounter, setClickCounter] = useState(0); - return ( - - - Card has been clicked {clickCounter} times - +export const DefaultStory: Story = { + render: (args: CardProps) => { + return ( setClickCounter((prevCounter) => prevCounter + 1)} - aria-label="Card with button element" + {...args} + onClick={() => {}} footer={ - Footer link + + Footer link + } > - - - - This Card is a button as it has an onClick prop + + + + + Additional text + + + - - - - Footer link - - - } - > - + - - This Card is a link as it has an href prop + + Body text + + Even more text - - ); + ); + }, }; -Interactive.parameters = { chromatic: { disableSnapshot: true } }; - -export const WithCustomBoxShadow = () => ( - - - - Footer link - - - - } - > - - - - - Additional text - - - - - - - - - - Body text - - - Even more text - - - -); - -export const DifferentCardRowPadding: StoryFn = () => ( - - - - Footer link - - - - } - > - - - - - Additional text - - - - - - - - - - Body text - - - Even more text - - - - - - Body text - - - Even more text - - - -); -DifferentCardRowPadding.parameters = { chromatic: { disableSnapshot: true } }; +DefaultStory.storyName = "Default"; -export const DifferentCardFooterPadding: StoryFn = () => ( - +export const SmallSpacing: Story = () => { + return ( - - - - - - - - + + + + Footer link + + } > - - - Here is some text + + + + Additional text + + + - - - - - - - - - - - - } - > - - Here is some text + + Body text + + Even more text + ); +}; +SmallSpacing.storyName = "Small Spacing"; + +export const LargeSpacing: Story = () => { + return ( - - - - - - - - + + + + Footer link + + } > - - - Here is some text + + + + Additional text + + + - - - - - - - - - - - - } - > - - Here is some text + + Body text + + Even more text + ); +}; +LargeSpacing.storyName = "Large Spacing"; + +export const WithWidthProvided: Story = () => { + return ( - - - - - - - - + + + + Footer link + + } > - - - Here is some text + + + + Additional text + + + - - - - - - - - - - - - } - > - - Here is some text + + Body text + + Even more text - -); -DifferentCardFooterPadding.parameters = { - chromatic: { disableSnapshot: true }, + ); }; +WithWidthProvided.storyName = "With Width Provided"; -export const MoreExamplesOfCardFooter: StoryFn = () => ( - +export const WithCustomHeight: Story = () => { + return ( - - - {}}> - - - {}}> - - - {}}> - - - {}}> - - - - - - - - + + + + Footer link + + } > + + + + + Additional text + + + + + + - - Here is some text + + Body text + + Even more text + ); +}; +WithCustomHeight.storyName = "With Custom Height"; + +export const WithExtraRoundness: Story = () => { + return ( - - - - - - - + + + + Footer link + + } > + + + + + Additional text + + + + + + - - Here is some text + + Body text + + Even more text + ); +}; +WithExtraRoundness.storyName = "With Extra Roundness"; + +export const Interactive: Story = () => { + const [clickCounter, setClickCounter] = useState(0); + return ( + + + Card has been clicked {clickCounter} times + + setClickCounter((prevCounter) => prevCounter + 1)} + aria-label="Card with button element" + footer={ + + + Footer link + + + } + > + + + + This Card is a button as it has an onClick prop + + + + + + + Footer link + + + } + > + + + + This Card is a link as it has an href prop + + + + + + ); +}; +Interactive.parameters = { chromatic: { disableSnapshot: true } }; +Interactive.storyName = "Interactive"; + +export const WithCustomBoxShadow: Story = () => { + return ( - - - - - - - + + + + Footer link + + } > + + + + + Additional text + + + + + + - - Here is some text + + Body text + + Even more text + ); +}; +WithCustomBoxShadow.storyName = "With Custom Box Shadow"; + +export const DifferentCardRowPadding: Story = () => { + return ( - + + - View Stripe Dashboard + Footer link - + } > - + + + + + Additional text + + + + + + + - - Here is some text + + Body text + + Even more text + + + + + + Body text + + + Even more text - -); + ); +}; +DifferentCardRowPadding.parameters = { chromatic: { disableSnapshot: true } }; +DifferentCardRowPadding.storyName = "Different Card Row Padding"; -export const WithStringAsChild: StoryFn = () => ( - String passed as child -); +export const DifferentCardFooterPadding: Story = () => { + return ( + + + + + + + + + + + + } + > + + + + Here is some text + + + + + + + + + + + + + + + } + > + + + + Here is some text + + + + + + + + + + + + + + + } + > + + + + Here is some text + + + + + + + + + + + + + + + } + > + + + + Here is some text + + + + + + + + + + + + + + + } + > + + + + Here is some text + + + + + + + + + + + + + + + } + > + + + + Here is some text + + + + + + ); +}; +DifferentCardFooterPadding.parameters = { + chromatic: { disableSnapshot: true }, +}; +DifferentCardFooterPadding.storyName = "Different Card Footer Padding"; + +export const MoreExamplesOfCardFooter: Story = () => { + return ( + + + + + {}}> + + + {}}> + + + {}}> + + + {}}> + + + + + + + + + + } + > + + + + Here is some text + + + + + + + + + + + + + + } + > + + + + Here is some text + + + + + + + + + + + + + + } + > + + + + Here is some text + + + + + + + + View Stripe Dashboard + + + + } + > + + + + Here is some text + + + + + + ); +}; +MoreExamplesOfCardFooter.storyName = "More Examples of Card Footer"; + +export const WithStringAsChild: Story = () => { + return String passed as child; +}; WithStringAsChild.parameters = { chromatic: { disableSnapshot: true } }; +WithStringAsChild.storyName = "With String as Child"; -export const WithDraggable: StoryFn = () => { +export const WithDraggable: Story = () => { const columnNames = { PRODUCT_ONE: "Product One", PRODUCT_TWO: "Product Two", @@ -852,3 +903,4 @@ export const WithDraggable: StoryFn = () => { return ; }; WithDraggable.parameters = { chromatic: { disableSnapshot: true } }; +WithDraggable.storyName = "With Draggable"; diff --git a/src/components/card/components.test-pw.tsx b/src/components/card/components.test-pw.tsx index fdc0525dbd..c396de186a 100644 --- a/src/components/card/components.test-pw.tsx +++ b/src/components/card/components.test-pw.tsx @@ -1,4 +1,5 @@ -import React from "react"; +/* eslint-disable react/no-unstable-nested-components */ +import React, { useState } from "react"; import { DndProvider, useDrag, useDrop } from "react-dnd"; import { HTML5Backend } from "react-dnd-html5-backend"; import { Card, CardRow, CardFooter, CardColumn, CardProps } from "."; @@ -7,6 +8,9 @@ import Heading from "../heading"; import Typography from "../typography"; import Icon from "../icon"; import Box from "../box"; +import Button from "../button"; +import IconButton from "../icon-button"; +import VerticalDivider from "../vertical-divider"; export const CardComponent = (props: Partial) => { return ( @@ -62,6 +66,7 @@ export const DraggableExample = () => { children?: React.ReactNode; title: string; } + const MovableItem = ({ "data-element": dataElement, name, @@ -228,3 +233,716 @@ export const CardTextAlignment = ({ ...props }) => { ); }; + +export const SmallSpacing = () => ( + + + + + + user.name@sage.com + + + + + + + + + + Stripe Balance + + + LAST ENTRY: 15 DAYS AGO + + + + + + View Stripe Dashboard + + + + +); + +export const LargeSpacing = () => ( + + + + + + user.name@sage.com + + + + + + + + + + Stripe Balance + + + LAST ENTRY: 15 DAYS AGO + + + + + + View Stripe Dashboard + + + + +); + +export const WithWidthProvided = () => ( + + + + Footer link + + + + } + > + + + + + Additional text + + + + + + + + + + Body text + + + Even more text + + + +); + +export const WithCustomHeight = () => ( + + + + + + user.name@sage.com + + + + + + + + + + Stripe Balance + + + LAST ENTRY: 15 DAYS AGO + + + + + + View Stripe Dashboard + + + + +); + +export const WithCustomBoxShadow = () => ( + + + + + + user.name@sage.com + + + + + + + + + + Stripe Balance + + + LAST ENTRY: 15 DAYS AGO + + + + + + View Stripe Dashboard + + + + +); + +export const DifferentCardFooterPadding = () => { + return ( + + + + + + Here is some text + + + + + + + + + + + + + + + + + + + Here is some text + + + + + + + + + + + + + + + + + + + Here is some text + + + + + + + + + + + + + + + + + + + Here is some text + + + + + + + + + + + + + + + + + + + Here is some text + + + + + + + + + + + + + + + + + + + Here is some text + + + + + + + + + + + + + + + + ); +}; + +export const DifferentCardRowPadding = () => { + return ( + + + + + + user.name@sage.com + + + + + + + + + + Stripe Balance + + + LAST ENTRY: 5 DAYS AGO + + + + + + Stripe Balance + + + LAST ENTRY: 15 DAYS AGO + + + + + + View Stripe Dashboard + + + + + ); +}; + +export const Interactive = () => { + const [clickCounter, setClickCounter] = useState(0); + return ( + + + Card has been clicked {clickCounter} times + + setClickCounter((prevCounter) => prevCounter + 1)} + aria-label="Card with button element" + footer={ + + + Footer link + + + } + > + + + + This Card is a button as it has an onClick prop + + + + + + + Footer link + + + } + > + + + + This Card is a link as it has an href prop + + + + + + ); +}; + +export const MoreExamplesOfCardFooter = () => { + return ( + + + + + + Here is some text + + + + + + + {}}> + + + {}}> + + + {}}> + + + {}}> + + + + + + + + + + + + + + + Here is some text + + + + + + + + + + + + + + + + + + Here is some text + + + + + + + + + + + + + + + + + + Here is some text + + + + + + + View Stripe Dashboard + + + + + + ); +}; + +export const WithDraggable = () => { + const columnNames = { + PRODUCT_ONE: "Product One", + PRODUCT_TWO: "Product Two", + } as const; + + const ITEM_TYPE = "Card"; + + interface CardSpec { + id: number; + name: string; + column: string; + } + + interface MovableItemProps { + "data-element"?: string; + name: string; + changeColumn: (column: string) => void; + } + + interface ColumnProps { + "data-element"?: string; + children?: React.ReactNode; + title: string; + } + + const MovableItem = ({ + "data-element": dataElement, + name, + changeColumn, + }: MovableItemProps) => { + const [{ isDragging }, drag] = useDrag({ + type: ITEM_TYPE, + item: { name }, + collect: (monitor) => ({ + isDragging: monitor.isDragging(), + }), + end: (_, monitor) => { + const dropResult = monitor.getDropResult<{ column: string }>(); + if (!dropResult) return; + changeColumn(dropResult.column); + }, + }); + + return ( + + + + + + user.name@sage.com + + + + + + + + ); + }; + + const Column = ({ + "data-element": dataElement, + children, + title, + }: ColumnProps) => { + const [{ isOver }, drop] = useDrop({ + accept: ITEM_TYPE, + drop: () => ({ column: title }), + collect: (monitor) => ({ + isOver: monitor.isOver(), + }), + }); + + return ( + + + {title} + + {children} + + ); + }; + + const App = () => { + const [cards, setCards] = useState([ + { id: 0, name: "Item 1", column: columnNames.PRODUCT_ONE }, + { id: 1, name: "Item 2", column: columnNames.PRODUCT_ONE }, + { id: 2, name: "Item 3", column: columnNames.PRODUCT_TWO }, + { id: 3, name: "Item 4", column: columnNames.PRODUCT_ONE }, + ]); + + const changeItemColumn = (id: number, column: string) => { + setCards((prevState) => + prevState.map((card) => ({ + ...card, + column: card.id === id ? column : card.column, + })) + ); + }; + + const returnColumnItems = (column: string) => + cards + .filter((card) => card.column === column) + .map(({ id, name }) => ( + changeItemColumn(id, newColumn)} + data-element={`draggable-card-${id}`} + /> + )); + + return ( + + + + + {returnColumnItems(columnNames.PRODUCT_ONE)} + + + {returnColumnItems(columnNames.PRODUCT_TWO)} + + + + + ); + }; + return ; +}; + +export const WithStringAsChild = () => { + return String passed as child; +}; diff --git a/src/components/carousel/carousel.mdx b/src/components/carousel/carousel.mdx new file mode 100644 index 0000000000..b28b4331df --- /dev/null +++ b/src/components/carousel/carousel.mdx @@ -0,0 +1,62 @@ +import { Meta, ArgTypes, Canvas } from "@storybook/blocks"; + +import DeprecationWarning from "../../../.storybook/docs-helpers/components/deprecation-warning"; + +import * as SlideStories from "./slide/slide.stories"; +import * as CarouselStories from "./carousel.stories"; + + + +# Carousel + + + We've deprecated Carousel. It's no longer available in the Design System and + we recommend that you do not use it in new products. + + + Product Design System component + + +- Presents a series of images which the user can step through one-by-one, or quickly jump to a particular step. +- Useful for showcasing a set of new features, for example. + +## Contents + +- [Quick Start](#quick-start) +- [Examples](#examples) +- [Props](#props) + +## Quick Start + +```javascript +import { Carousel, Slide } from "carbon-react/lib/components/carousel"; +``` + +## Examples + +### Default + + + +### Without buttons + + + +### Without slideSelectors + + + +## Props + +### Carousel + + + +### Slide + + diff --git a/src/components/carousel/carousel.stories.mdx b/src/components/carousel/carousel.stories.mdx deleted file mode 100644 index 0115982f3d..0000000000 --- a/src/components/carousel/carousel.stories.mdx +++ /dev/null @@ -1,66 +0,0 @@ -import { useState } from "react"; -import { Meta, Story, Canvas, ArgsTable } from "@storybook/addon-docs"; -import DeprecationWarning from "../../../.storybook/docs-helpers/components/deprecation-warning" - -import { Carousel, Slide } from "."; -import * as stories from "./carousel.stories"; - - - -# Carousel - - -We've deprecated Carousel. It's no longer available in the Design System and we recommend that you do not use it in new products. - - - Product Design System component - - -- Presents a series of images which the user can step through one-by-one, or quickly jump to a particular step. -- Useful for showcasing a set of new features, for example. - -## Contents - -- [Quick Start](#quick-start) -- [Examples](#examples) -- [Props](#props) - -## Quick Start - -```javascript -import { Carousel, Slide } from "carbon-react/lib/components/carousel"; -``` - -## Examples - -### Default - - - - - -### Without buttons - - - - - -### Without slideSelectors - - - - - -## Props - -### Carousel - - - -### Slide - - diff --git a/src/components/carousel/carousel.stories.tsx b/src/components/carousel/carousel.stories.tsx index 28717973aa..e7bd832948 100644 --- a/src/components/carousel/carousel.stories.tsx +++ b/src/components/carousel/carousel.stories.tsx @@ -1,129 +1,146 @@ import React from "react"; -import { ComponentStory } from "@storybook/react"; +import { Meta, StoryObj } from "@storybook/react"; import { Carousel, Slide } from "."; import Box from "../box"; import Typography from "../typography"; -export const Default: ComponentStory = () => ( - - - - - Slide 1 - - - - - - Slide 2 - - - - - - Slide 3 - - - - -); +const meta: Meta = { + title: "Carousel", + component: Carousel, +}; -export const WithoutButtons: ComponentStory = () => ( - - - - - Slide 1 - - - - - - Slide 2 - - - - - - Slide 3 - - - - -); +export default meta; +type Story = StoryObj; -export const WithoutSlideSelectors: ComponentStory = () => ( - - - - - Slide 1 - - - - - - Slide 2 - - - - - - Slide 3 - - - - -); +export const Default: Story = () => { + return ( + + + + + Slide 1 + + + + + + Slide 2 + + + + + + Slide 3 + + + + + ); +}; +Default.storyName = "Default"; + +export const WithoutButtons: Story = () => { + return ( + + + + + Slide 1 + + + + + + Slide 2 + + + + + + Slide 3 + + + + + ); +}; +WithoutButtons.storyName = "Without Buttons"; + +export const WithoutSlideSelectors: Story = () => { + return ( + + + + + Slide 1 + + + + + + Slide 2 + + + + + + Slide 3 + + + + + ); +}; +WithoutSlideSelectors.storyName = "Without Slide Selectors"; diff --git a/src/components/carousel/slide/slide.stories.tsx b/src/components/carousel/slide/slide.stories.tsx new file mode 100644 index 0000000000..d63bf82d5e --- /dev/null +++ b/src/components/carousel/slide/slide.stories.tsx @@ -0,0 +1,23 @@ +import { Meta, StoryObj } from "@storybook/react"; +import Slide from "./slide.component"; + +/** + * This file is used primarily as a means to generate the props table. + * It contains the tag: ["hideInSidebar"] so that it is not included in the sidebar. + */ + +const meta: Meta = { + title: "Slide", + component: Slide, + tags: ["hideInSidebar"], + parameters: { + chromatic: { disableSnapshot: true }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: {}, +}; diff --git a/src/components/checkbox/checkbox-group.component.tsx b/src/components/checkbox/checkbox-group/checkbox-group.component.tsx similarity index 86% rename from src/components/checkbox/checkbox-group.component.tsx rename to src/components/checkbox/checkbox-group/checkbox-group.component.tsx index 28d869d019..d539e024b2 100644 --- a/src/components/checkbox/checkbox-group.component.tsx +++ b/src/components/checkbox/checkbox-group/checkbox-group.component.tsx @@ -1,16 +1,16 @@ import React, { useContext } from "react"; import { MarginProps } from "styled-system"; -import tagComponent from "../../__internal__/utils/helpers/tags/tags"; +import tagComponent from "../../../__internal__/utils/helpers/tags/tags"; import StyledCheckboxGroup, { StyledHintText } from "./checkbox-group.style"; -import Fieldset from "../../__internal__/fieldset"; -import { filterStyledSystemMarginProps } from "../../style/utils"; -import { TooltipProvider } from "../../__internal__/tooltip-provider"; -import { ValidationProps } from "../../__internal__/validations"; -import FormSpacingProvider from "../../__internal__/form-spacing-provider"; -import { NewValidationContext } from "../carbon-provider/carbon-provider.component"; -import ValidationMessage from "../../__internal__/validation-message/validation-message.component"; -import Box from "../../components/box"; -import { ErrorBorder } from "../../components/textbox/textbox.style"; +import Fieldset from "../../../__internal__/fieldset"; +import { filterStyledSystemMarginProps } from "../../../style/utils"; +import { TooltipProvider } from "../../../__internal__/tooltip-provider"; +import { ValidationProps } from "../../../__internal__/validations"; +import FormSpacingProvider from "../../../__internal__/form-spacing-provider"; +import { NewValidationContext } from "../../carbon-provider/carbon-provider.component"; +import ValidationMessage from "../../../__internal__/validation-message/validation-message.component"; +import Box from "../../box"; +import { ErrorBorder } from "../../textbox/textbox.style"; export interface CheckboxGroupProps extends ValidationProps, MarginProps { /** The content for the CheckboxGroup Legend */ diff --git a/src/components/checkbox/checkbox-group.spec.tsx b/src/components/checkbox/checkbox-group/checkbox-group.spec.tsx similarity index 93% rename from src/components/checkbox/checkbox-group.spec.tsx rename to src/components/checkbox/checkbox-group/checkbox-group.spec.tsx index 26ac553bec..8f4d53751e 100644 --- a/src/components/checkbox/checkbox-group.spec.tsx +++ b/src/components/checkbox/checkbox-group/checkbox-group.spec.tsx @@ -2,18 +2,18 @@ import React from "react"; import { mount } from "enzyme"; import CarbonProvider from "components/carbon-provider/carbon-provider.component"; import CheckboxGroup, { CheckboxGroupProps } from "./checkbox-group.component"; -import { Checkbox } from "."; +import { Checkbox } from ".."; import { assertStyleMatch, testStyledSystemMargin, -} from "../../__spec_helper__/test-utils"; -import StyledCheckbox from "./checkbox.style"; +} from "../../../__spec_helper__/test-utils"; +import StyledCheckbox from "../checkbox.style"; import StyledCheckboxGroup, { StyledHintText } from "./checkbox-group.style"; -import Fieldset from "../../__internal__/fieldset"; -import Tooltip from "../tooltip"; -import StyledFormField from "../../__internal__/form-field/form-field.style"; -import { ErrorBorder } from "../textbox/textbox.style"; -import Logger from "../../__internal__/utils/logger"; +import Fieldset from "../../../__internal__/fieldset"; +import Tooltip from "../../tooltip"; +import StyledFormField from "../../../__internal__/form-field/form-field.style"; +import { ErrorBorder } from "../../textbox/textbox.style"; +import Logger from "../../../__internal__/utils/logger"; // mock Logger.deprecate so that no console warnings occur while running the tests const loggerSpy = jest.spyOn(Logger, "deprecate"); diff --git a/src/components/checkbox/checkbox-group/checkbox-group.stories.tsx b/src/components/checkbox/checkbox-group/checkbox-group.stories.tsx new file mode 100644 index 0000000000..e6f29a2ad9 --- /dev/null +++ b/src/components/checkbox/checkbox-group/checkbox-group.stories.tsx @@ -0,0 +1,33 @@ +import { Meta, StoryObj } from "@storybook/react"; +import generateStyledSystemProps from "../../../../.storybook/utils/styled-system-props"; +import { CheckboxGroup } from ".."; + +/** + * This file is used primarily as a means to generate the props table. + * It contains the tag: ["hideInSidebar"] so that it is not included in the sidebar. + */ + +const styledSystemProps = generateStyledSystemProps({ + margin: true, +}); + +const meta: Meta = { + title: "CheckboxGroup", + component: CheckboxGroup, + tags: ["hideInSidebar"], + argTypes: { + ...styledSystemProps, + }, + parameters: { + chromatic: { disableSnapshot: true }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + children: [], + }, +}; diff --git a/src/components/checkbox/checkbox-group.style.ts b/src/components/checkbox/checkbox-group/checkbox-group.style.ts similarity index 75% rename from src/components/checkbox/checkbox-group.style.ts rename to src/components/checkbox/checkbox-group/checkbox-group.style.ts index 0720372797..c2d153d51c 100644 --- a/src/components/checkbox/checkbox-group.style.ts +++ b/src/components/checkbox/checkbox-group/checkbox-group.style.ts @@ -1,9 +1,9 @@ import styled, { css } from "styled-components"; -import StyledFormField from "../../__internal__/form-field/form-field.style"; -import StyledIcon from "../icon/icon.style"; -import CheckboxStyle from "./checkbox.style"; -import { StyledLabelContainer } from "../../__internal__/label/label.style"; -import StyledValidationIcon from "../../__internal__/validations/validation-icon.style"; +import StyledFormField from "../../../__internal__/form-field/form-field.style"; +import StyledIcon from "../../icon/icon.style"; +import CheckboxStyle from "../checkbox.style"; +import { StyledLabelContainer } from "../../../__internal__/label/label.style"; +import StyledValidationIcon from "../../../__internal__/validations/validation-icon.style"; export const StyledHintText = styled.div` margin-top: -4px; diff --git a/src/components/checkbox/checkbox-validations.stories.mdx b/src/components/checkbox/checkbox-validations.stories.mdx deleted file mode 100644 index 7c84c38c93..0000000000 --- a/src/components/checkbox/checkbox-validations.stories.mdx +++ /dev/null @@ -1,94 +0,0 @@ -import { Meta, Story, Canvas } from "@storybook/addon-docs"; -import * as stories from "./checkbox-validations.stories"; - -import { Checkbox, CheckboxGroup } from "."; - - - -# Checkbox - - - Product Design System component - - -## Validations - -Validation status can be set by passing `error`, `warning` or `info` prop to the component - -Passing a string to these props will display a properly colored border along with a validation icon and tooltip - string value will be displayed as the tooltip message. - -Passing a boolean to these props will display only a properly colored border. - -For more information check our [Validations](?path=/docs/documentation-validations--page "Validations") documentation page - -### New Validations - - - - - - - - - - - - - - - - - -### As a string applied to single Checkbox - - - - - -It is possible to use the `tooltipPosition` to override the default placement of tooltips rendered as part of this component. - - - - - -### As a boolean applied to single Checkbox - - - - - -### As a string applied to CheckboxGroup - - - - - -It is possible to use the `tooltipPosition` to override the default placement of tooltips rendered as part of this component. - - - - - -### As a boolean applied to CheckboxGroup - - - - - -### Required - -You can use the `required` prop to indicate if the field is mandatory. - - - - diff --git a/src/components/checkbox/checkbox-validations.stories.tsx b/src/components/checkbox/checkbox-validations.stories.tsx deleted file mode 100644 index 3f77ba67c0..0000000000 --- a/src/components/checkbox/checkbox-validations.stories.tsx +++ /dev/null @@ -1,473 +0,0 @@ -import React from "react"; -import { ComponentStory } from "@storybook/react"; -import { Checkbox, CheckboxGroup } from "."; -import CarbonProvider from "../carbon-provider/carbon-provider.component"; - -export const StringValidation: ComponentStory = () => ( - <> - - - - -); - -export const StringValidationWithTooltipPosition: ComponentStory< - typeof Checkbox -> = () => ( - <> - - - - -); - -StringValidationWithTooltipPosition.parameters = { - chromatic: { disableSnapshot: true }, -}; - -export const BooleanValidation: ComponentStory = () => ( - <> - - - - -); - -export const CheckboxGroupStringValidation: ComponentStory< - typeof Checkbox -> = () => ( - <> - - - - - - - - - - - - - - - - -); - -export const CheckboxGroupStringValidationTooltipPosition: ComponentStory< - typeof Checkbox -> = () => ( - <> - - - - - - - - - - - - - - - - -); - -CheckboxGroupStringValidationTooltipPosition.parameters = { - chromatic: { disableSnapshot: true }, -}; - -export const CheckboxGroupBooleanValidation: ComponentStory< - typeof Checkbox -> = () => ( - <> - - - - - - - - - - - - - - - - -); - -export const Required: ComponentStory = () => ( - -); - -export const NewStringValidation: ComponentStory = () => ( - - - - - - - - - - - - -); - -export const NewStringValidationInline: ComponentStory< - typeof Checkbox -> = () => ( - - - - - - - - - - - - -); - -export const NewInline: ComponentStory = () => ( - - - - - - - -); - -export const NewBooleanValidation: ComponentStory = () => ( - - - - -); diff --git a/src/components/checkbox/checkbox.component.tsx b/src/components/checkbox/checkbox.component.tsx index dbd27eb502..b4d2f8a319 100644 --- a/src/components/checkbox/checkbox.component.tsx +++ b/src/components/checkbox/checkbox.component.tsx @@ -8,7 +8,7 @@ import CheckableInput, { import CheckboxSvg from "./checkbox-svg.component"; import useIsAboveBreakpoint from "../../hooks/__internal__/useIsAboveBreakpoint"; import { TooltipProvider } from "../../__internal__/tooltip-provider"; -import { CheckboxGroupContext } from "./checkbox-group.component"; +import { CheckboxGroupContext } from "./checkbox-group/checkbox-group.component"; import Logger from "../../__internal__/utils/logger"; import useFormSpacing from "../../hooks/__internal__/useFormSpacing"; import { NewValidationContext } from "../carbon-provider/carbon-provider.component"; diff --git a/src/components/checkbox/checkbox.stories.mdx b/src/components/checkbox/checkbox.mdx similarity index 58% rename from src/components/checkbox/checkbox.stories.mdx rename to src/components/checkbox/checkbox.mdx index 53264d79c2..481a3fca80 100644 --- a/src/components/checkbox/checkbox.stories.mdx +++ b/src/components/checkbox/checkbox.mdx @@ -1,20 +1,20 @@ -import { Meta, Story, Canvas } from "@storybook/addon-docs"; -import StyledSystemProps from "../../../.storybook/utils/styled-system-props"; -import * as stories from "./checkbox.stories"; -import * as validationStories from "./checkbox-validations.stories"; +import { Meta, ArgTypes, Canvas } from "@storybook/blocks"; -import { Checkbox, CheckboxGroup } from "."; +import * as CheckboxStories from "./checkbox.stories"; +import * as CheckboxGroupStories from "./checkbox-group/checkbox-group.stories"; +import * as ValidationStories from "./validations.stories"; - + # Checkbox - Product Design System component + Product Design System component - Checkbox provides a way to efficiently select more than one item from a list. @@ -49,51 +49,35 @@ import { Checkbox, CheckboxGroup } from "carbon-react/lib/components/checkbox"; ### Default - - - + ### Sizes - - - + ### Disabled - - - + ### Reversed - - - + ### With fieldHelp - - - + ### With labelHelp - - - + ### With custom labelWidth - - - + ### Checkbox Group - - - + ### With inline legend @@ -101,9 +85,7 @@ The legend can be made inline. Its width can be changed with the `legendWidth` p The spacing between the legend and the checkboxes can be changed with the `legendSpacing` prop, this can be `1` or `2`, which is multiplied by the base theme spacing constant of `8px`, so therefore `8px` or `16px`. The default is `2` for this prop. - - - + ## Validations @@ -113,38 +95,34 @@ Passing a string to these props will display a properly colored border along wit Passing a boolean to these props will display only a properly colored border. -For more information check our [Validations](?path=/docs/documentation-validations--string-validation "Validations") documentation page +For more information check our [Validations](../?path=/docs/documentation-validations--docs) documentation page ### New Validations This is an example of `Checkbox` in a `CheckboxGroup` with validations passed as a string. - - - + + This is an example of `Checkbox` in a `CheckboxGroup` displayed inline. - - - + + This is an example of `Checkbox` in a `CheckboxGroup` with validations passed as a string displayed inline. - - - + + This is an example of `Checkbox` with validations passed as boolean values. - - - + + ## Props ### Checkbox - + **Any other supplied props will be provided to the underlying HTML input element** ### CheckboxGroup - \ No newline at end of file + diff --git a/src/components/checkbox/checkbox.pw.tsx b/src/components/checkbox/checkbox.pw.tsx index 497b1f3fbd..b19824c0b5 100644 --- a/src/components/checkbox/checkbox.pw.tsx +++ b/src/components/checkbox/checkbox.pw.tsx @@ -7,8 +7,10 @@ import { CheckboxComponent, CheckboxGroupComponent, CheckboxGroupComponentNewValidation, + Sizes, + Reversed, + WithCustomLabelWidth, } from "./components.test-pw"; -import { Sizes, Reversed, WithCustomLabelWidth } from "./checkbox.stories"; import { checkboxComponent, checkboxRole, diff --git a/src/components/checkbox/checkbox.stories.tsx b/src/components/checkbox/checkbox.stories.tsx index 56391e8e13..80409b4346 100644 --- a/src/components/checkbox/checkbox.stories.tsx +++ b/src/components/checkbox/checkbox.stories.tsx @@ -1,8 +1,24 @@ import React, { useState } from "react"; -import { ComponentStory } from "@storybook/react"; +import { Meta, StoryObj } from "@storybook/react"; import { Checkbox, CheckboxGroup } from "."; +import generateStyledSystemProps from "../../../.storybook/utils/styled-system-props"; -export const Default: ComponentStory = () => { +const styledSystemProps = generateStyledSystemProps({ + margin: true, +}); + +const meta: Meta = { + title: "Checkbox", + component: Checkbox, + argTypes: { + ...styledSystemProps, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = () => { const [isChecked, setIsChecked] = useState(false); return ( @@ -14,97 +30,118 @@ export const Default: ComponentStory = () => { /> ); }; +Default.storyName = "Default"; -export const Sizes: ComponentStory = () => ( - <> - - - -); +export const Sizes: Story = () => { + return ( + <> + + + + ); +}; +Sizes.storyName = "Sizes"; -export const Disabled: ComponentStory = () => ( - -); +export const Disabled: Story = () => { + return ( + + ); +}; +Disabled.storyName = "Disabled"; -export const Reversed: ComponentStory = () => ( - -); +export const Reversed: Story = () => { + return ; +}; +Reversed.storyName = "Reversed"; + +export const WithFieldHelp: Story = () => { + return ( + <> + + + + ); +}; +WithFieldHelp.storyName = "With fieldHelp"; -export const WithFieldHelp: ComponentStory = () => ( - <> +export const WithLabelHelp: Story = () => { + return ( + ); +}; +WithLabelHelp.storyName = "With labelHelp"; + +export const WithCustomLabelWidth: Story = () => { + return ( - -); - -export const WithLabelHelp: ComponentStory = () => ( - -); - -export const WithCustomLabelWidth: ComponentStory = () => ( - -); + ); +}; +WithCustomLabelWidth.storyName = "With custom labelWidth"; -export const CheckboxGroupStory: ComponentStory = () => ( - - {["One", "Two", "Three"].map((label) => ( - - ))} - -); +export const CheckboxGroupStory: Story = () => { + return ( + + {["One", "Two", "Three"].map((label) => ( + + ))} + + ); +}; +CheckboxGroupStory.storyName = "CheckboxGroup"; -export const CheckboxGroupWithInlineLegend: ComponentStory< - typeof Checkbox -> = () => ( - - {["One", "Two", "Three"].map((label) => ( - - ))} - -); +export const CheckboxGroupWithInlineLegend: Story = () => { + return ( + + {["One", "Two", "Three"].map((label) => ( + + ))} + + ); +}; +CheckboxGroupWithInlineLegend.storyName = "CheckboxGroup with inline legend"; diff --git a/src/components/checkbox/components.test-pw.tsx b/src/components/checkbox/components.test-pw.tsx index 66d92e845c..95456c6e2d 100644 --- a/src/components/checkbox/components.test-pw.tsx +++ b/src/components/checkbox/components.test-pw.tsx @@ -92,3 +92,36 @@ export const CheckboxGroupComponentNewValidation = ({
); }; + +export const Sizes = () => { + return ( + <> + + + + ); +}; + +export const Reversed = () => { + return ; +}; + +export const WithCustomLabelWidth = () => { + return ( + + ); +}; diff --git a/src/components/checkbox/index.ts b/src/components/checkbox/index.ts index 4eca03bf8c..5c72380a3a 100644 --- a/src/components/checkbox/index.ts +++ b/src/components/checkbox/index.ts @@ -1,4 +1,4 @@ -export { default as CheckboxGroup } from "./checkbox-group.component"; -export type { CheckboxGroupProps } from "./checkbox-group.component"; +export { default as CheckboxGroup } from "./checkbox-group/checkbox-group.component"; +export type { CheckboxGroupProps } from "./checkbox-group/checkbox-group.component"; export { default as Checkbox } from "./checkbox.component"; export type { CheckboxProps } from "./checkbox.component"; diff --git a/src/components/checkbox/validations.stories.tsx b/src/components/checkbox/validations.stories.tsx new file mode 100644 index 0000000000..e3fbaed73c --- /dev/null +++ b/src/components/checkbox/validations.stories.tsx @@ -0,0 +1,193 @@ +import React from "react"; +import { Meta, StoryObj } from "@storybook/react"; +import { Checkbox, CheckboxGroup } from "."; +import CarbonProvider from "../carbon-provider/carbon-provider.component"; + +const meta: Meta = { + title: "Checkbox", + component: Checkbox, +}; + +export default meta; +type Story = StoryObj; + +export const Required: Story = () => { + return ( + + ); +}; +Required.storyName = "Required"; + +export const NewStringValidation: Story = () => { + return ( + + + + + + + + + + + + + ); +}; +NewStringValidation.storyName = "New String Validation"; + +export const NewStringValidationInline: Story = () => { + return ( + + + + + + + + + + + + + ); +}; +NewStringValidationInline.storyName = "New String Validation Inline"; + +export const NewInline: Story = () => { + return ( + + + + + + + + ); +}; +NewInline.storyName = "New Inline"; + +export const NewBooleanValidation: Story = () => { + return ( + + + + + ); +}; +NewBooleanValidation.storyName = "New Boolean Validation"; diff --git a/src/components/confirm/confirm.stories.mdx b/src/components/confirm/confirm.mdx similarity index 51% rename from src/components/confirm/confirm.stories.mdx rename to src/components/confirm/confirm.mdx index 57eb29a0db..89e56bda2c 100644 --- a/src/components/confirm/confirm.stories.mdx +++ b/src/components/confirm/confirm.mdx @@ -1,14 +1,8 @@ -import { Meta, Story, Canvas, ArgsTable } from "@storybook/addon-docs"; -import Confirm from "."; -import * as stories from "./confirm.stories"; - - +import { Meta, ArgTypes, Canvas } from "@storybook/blocks"; + +import * as ConfirmStories from "./confirm.stories"; + + # Confirm @@ -38,82 +32,54 @@ import Confirm from "carbon-react/lib/components/confirm"; ### Default - - - + ### Single action - - - + ### Destructive cancel button - - - + ### Destructive confirm button - - - + ### Disable confirm button - - - + ### Disable cancel button - - - + ### Change cancel button type Allows to set variant which is supported in ` + setIsOpen(false)} + title="Title" + subtitle="Subtitle" + > +
setIsOpen(false)}>Cancel + } + saveButton={ + + } + > + + This is an example of a dialog with a Form as content + + + + + + + + + + + + + + +
+ + ); +}; + +export const Editable = () => { + const [isOpen, setIsOpen] = useState(defaultOpenState); + const [isDisabled, setIsDisabled] = useState(true); + const [radioValue, setRadioValue] = useState("1"); + + return ( + <> + + setIsOpen(false)} + title="Add an address" + > +
setIsOpen(false)}>Cancel + } + saveButton={ + + } + > + + Basic details + + + setRadioValue(target.value)} + value={radioValue} + legendWidth={40} + > + + + + + +
+ + + + + +
+
+
+
+ + ); +}; + +export const WithHelp = () => { + const [isOpen, setIsOpen] = useState(defaultOpenState); + return ( + <> + + setIsOpen(false)} + title="Add an address" + help="Some help text" + > +
setIsOpen(false)}>Cancel + } + saveButton={ + + } + > + + +
+ + + + + +
+
+
+
+ + ); +}; + +export const LoadingContent = () => { + const [isLoading, setIsLoading] = useState(false); + const [isOpen, setIsOpen] = useState(defaultOpenState); + + const handleOpen = () => { + setIsLoading(true); + setIsOpen(true); + setTimeout(() => { + setIsLoading(false); + }, 3000); + }; + + return ( + <> + + setIsOpen(false)} + > + {isLoading ? ( + + ) : ( + <> + + + + + + + + + )} + + + ); +}; + +export const FocusingADifferentFirstElement = () => { + const [isOpenOne, setIsOpenOne] = useState(false); + const [isOpenTwo, setIsOpenTwo] = useState(false); + const ref = useRef(null); + return ( + <> + + setIsOpenOne(false)} + aria-label="Demo using focusFirstElement" + > + + Focus an element that does not support autofocus + + + + + + + + + setIsOpenTwo(false)} + aria-label="Demo using autoFocus" + > + Focus an element that supports autoFocus + + + + + + + + ); +}; + +export const OverridingContentPadding = () => { + const [isOpen, setIsOpen] = useState(defaultOpenState); + return ( + <> + + setIsOpen(false)} + title="Title" + subtitle="Subtitle" + contentPadding={{ p: 0 }} + > +
setIsOpen(false)}>Cancel + } + saveButton={ + + } + > + + This is an example of a dialog with a Form as content + + + + + + + + + + + + + + +
+ + ); +}; + +export const OtherFocusableContainers = () => { + const [isDialogOpen, setIsDialogOpen] = useState(false); + const [isToast1Open, setIsToast1Open] = useState(false); + const [isToast2Open, setIsToast2Open] = useState(false); + const toast1Ref = useRef(null); + const toast2Ref = useRef(null); + + return ( + <> + + setIsDialogOpen(false)} + title="Title" + subtitle="Subtitle" + focusableContainers={[toast1Ref, toast2Ref]} + > +
setIsDialogOpen(false)}>Cancel + } + saveButton={ + + } + > + + This is an example of a dialog with a Form as content + + + + + + + +
+ setIsToast1Open(false)} + ref={toast1Ref} + targetPortalId="stacked" + > + Toast message 1 + + setIsToast2Open(false)} + ref={toast2Ref} + targetPortalId="stacked" + > + Toast message 2 + + + ); +}; + +export const Responsive = () => { + const [isOpen, setIsOpen] = useState(defaultOpenState); + const largeScreen = useMediaQuery("(min-width: 1260px)"); + const mediumScreen = useMediaQuery("(min-width: 960px)"); + const smallScreen = useMediaQuery("(min-width: 600px)"); + const setCorrectScreenSize = () => { + if (largeScreen) return "large"; + if (mediumScreen) return "medium"; + if (smallScreen) return "small"; + return "auto"; + }; + + return ( + <> + + setIsOpen(false)} + title="Title" + subtitle="Subtitle" + > +
setIsOpen(false)}>Cancel + } + saveButton={ + + } + > + + This is an example of a dialog with a Form as content + + + + + + + + +
+ + ); +}; + +export const UsingHandle = () => { + const dialogHandle = useRef(null); + + const [isOpen, setIsOpen] = useState(defaultOpenState); + const [isSubmitted, setIsSubmitted] = useState(false); + + function handleSubmit(ev: React.FormEvent) { + ev.preventDefault(); + setIsSubmitted(true); + dialogHandle.current?.focus(); + } + + return ( + + + setIsOpen(false)} + title={isSubmitted ? "Thank you for your feedback." : "Give feedback"} + showCloseIcon + ref={dialogHandle} + > + {isSubmitted ? ( + + Your feedback helps us continually improve our software. + + ) : ( +
Submit} + onSubmit={handleSubmit} + > +