@tpzdsp/next-toolkit 2.5.1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +21 -12
- package/src/assets/styles/globals.css +75 -95
- package/src/assets/styles/ol.css +57 -16
- package/src/assets/styles/utils.css +80 -0
- package/src/components/Accordion/Accordion.css +85 -0
- package/src/components/Accordion/Accordion.stories.tsx +264 -0
- package/src/components/Accordion/Accordion.tsx +98 -0
- package/src/components/Alert/Alert.css +129 -0
- package/src/components/Alert/Alert.stories.tsx +291 -0
- package/src/components/Alert/Alert.tsx +76 -0
- package/src/components/BackLink/BackLink.css +12 -0
- package/src/components/BackLink/BackLink.stories.tsx +52 -0
- package/src/components/BackLink/BackLink.tsx +44 -0
- package/src/components/BackToTop/BackToTop.css +23 -0
- package/src/components/BackToTop/BackToTop.stories.tsx +41 -0
- package/src/components/BackToTop/BackToTop.tsx +48 -0
- package/src/components/Breadcrumb/Breadcrumb.css +42 -0
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +94 -0
- package/src/components/Breadcrumb/Breadcrumb.tsx +135 -0
- package/src/components/Button/Button.css +229 -0
- package/src/components/Button/Button.stories.tsx +140 -20
- package/src/components/Button/Button.tsx +53 -28
- package/src/components/Button/ButtonSkeleton.stories.tsx +50 -0
- package/src/components/Button/ButtonSkeleton.tsx +14 -0
- package/src/components/ButtonGroup/ButtonGroup.css +52 -0
- package/src/components/ButtonGroup/ButtonGroup.stories.tsx +156 -0
- package/src/components/ButtonGroup/ButtonGroup.tsx +50 -0
- package/src/components/ButtonLink/ButtonLink.css +114 -0
- package/src/components/ButtonLink/ButtonLink.stories.tsx +38 -51
- package/src/components/ButtonLink/ButtonLink.tsx +54 -23
- package/src/components/Card/Card.css +13 -0
- package/src/components/Card/Card.stories.tsx +98 -57
- package/src/components/Card/Card.tsx +4 -13
- package/src/components/CardGroup/CardGroup.css +10 -0
- package/src/components/CardGroup/CardGroup.stories.tsx +81 -0
- package/src/components/CardGroup/CardGroup.tsx +9 -0
- package/src/components/Checkbox/Checkbox.css +49 -0
- package/src/components/Checkbox/Checkbox.stories.tsx +86 -0
- package/src/components/Checkbox/Checkbox.tsx +32 -0
- package/src/components/Chip/Chip.css +54 -0
- package/src/components/Chip/Chip.stories.tsx +94 -0
- package/src/components/Chip/Chip.tsx +34 -0
- package/src/components/CookieBanner/CookieBanner.css +19 -0
- package/src/components/CookieBanner/CookieBanner.stories.tsx +52 -0
- package/src/components/CookieBanner/CookieBanner.tsx +55 -0
- package/src/components/CopyButton/CopyButton.stories.tsx +28 -0
- package/src/components/CopyButton/CopyButton.tsx +65 -0
- package/src/components/DateInput/DateInput.css +13 -0
- package/src/components/DateInput/DateInput.stories.tsx +131 -0
- package/src/components/DateInput/DateInput.test.tsx +21 -0
- package/src/components/DateInput/DateInput.tsx +98 -0
- package/src/components/Details/Details.css +28 -0
- package/src/components/Details/Details.stories.tsx +48 -0
- package/src/components/Details/Details.tsx +41 -0
- package/src/components/Dropdown/Dropdown.css +81 -0
- package/src/components/Dropdown/Dropdown.stories.tsx +131 -0
- package/src/components/Dropdown/Dropdown.tsx +69 -0
- package/src/components/ErrorBoundary/ErrorBoundary.stories.tsx +4 -39
- package/src/components/ErrorBoundary/ErrorBoundary.tsx +7 -4
- package/src/components/ErrorBoundary/ErrorFallback.tsx +32 -66
- package/src/components/ErrorModal/ErrorModal.css +34 -0
- package/src/components/ErrorModal/ErrorModal.stories.tsx +100 -0
- package/src/components/ErrorModal/ErrorModal.tsx +123 -0
- package/src/components/ErrorText/ErrorText.css +22 -0
- package/src/components/ErrorText/ErrorText.stories.tsx +42 -27
- package/src/components/ErrorText/ErrorText.tsx +10 -8
- package/src/components/ExternalLink/ExternalLink.css +12 -0
- package/src/components/ExternalLink/ExternalLink.stories.tsx +43 -0
- package/src/components/ExternalLink/ExternalLink.tsx +43 -0
- package/src/components/Fieldset/Fieldset.css +103 -0
- package/src/components/Fieldset/Fieldset.stories.tsx +304 -0
- package/src/components/Fieldset/Fieldset.tsx +38 -0
- package/src/components/FileUpload/FileUpload.css +85 -0
- package/src/components/FileUpload/FileUpload.stories.tsx +106 -0
- package/src/components/FileUpload/FileUpload.tsx +99 -0
- package/src/components/{layout/footer → Footer}/Copyright.tsx +3 -2
- package/src/components/Footer/Footer.stories.tsx +27 -0
- package/src/components/Footer/Footer.tsx +46 -0
- package/src/components/Footer/Licence.tsx +18 -0
- package/src/components/Footer/MetaLinks.tsx +47 -0
- package/src/components/Footer/Small/SmallFooter.stories.tsx +3 -0
- package/src/components/Footer/Small/SmallFooter.tsx +53 -41
- package/src/components/Form/FormGroup.css +18 -0
- package/src/components/Form/FormGroup.stories.tsx +87 -0
- package/src/components/Form/FormGroup.tsx +16 -0
- package/src/components/{layout/header → Header}/Header.stories.tsx +26 -12
- package/src/components/Header/Header.test.tsx +87 -0
- package/src/components/Header/Header.tsx +304 -0
- package/src/components/Header/HeaderAppContent.tsx +120 -0
- package/src/components/Heading/Heading.css +40 -0
- package/src/components/Heading/Heading.stories.tsx +15 -5
- package/src/components/Heading/Heading.tsx +21 -44
- package/src/components/Heading/HeadingSkeleton.stories.tsx +30 -0
- package/src/components/Heading/HeadingSkeleton.tsx +14 -0
- package/src/components/Hero/Hero.css +19 -0
- package/src/components/Hero/Hero.stories.tsx +41 -0
- package/src/components/Hero/Hero.tsx +14 -0
- package/src/components/HintText/HintText.css +5 -0
- package/src/components/HintText/HintText.stories.tsx +29 -0
- package/src/components/HintText/HintText.tsx +13 -0
- package/src/components/InfoBox/InfoBox.css +38 -0
- package/src/components/InfoBox/InfoBox.stories.tsx +51 -403
- package/src/components/InfoBox/InfoBox.tsx +31 -158
- package/src/components/Input/Input.css +77 -0
- package/src/components/Input/Input.stories.tsx +123 -0
- package/src/components/Input/Input.tsx +74 -0
- package/src/components/InputGroup/InputGroup.css +140 -0
- package/src/components/InputGroup/InputGroup.stories.tsx +125 -0
- package/src/components/InputGroup/InputGroup.tsx +47 -0
- package/src/components/InsetText/InsetText.css +5 -0
- package/src/components/InsetText/InsetText.stories.tsx +30 -0
- package/src/components/InsetText/InsetText.tsx +9 -0
- package/src/components/Keyboard/Keyboard.css +9 -0
- package/src/components/Keyboard/Keyboard.stories.tsx +63 -0
- package/src/components/Keyboard/Keyboard.tsx +30 -0
- package/src/components/Label/Label.css +27 -0
- package/src/components/Label/Label.stories.tsx +40 -0
- package/src/components/Label/Label.tsx +17 -0
- package/src/components/LayerSwitcher/LayerSwitcher.css +59 -0
- package/src/components/LayerSwitcher/LayerSwitcher.stories.tsx +112 -0
- package/src/components/LayerSwitcher/LayerSwitcher.tsx +61 -0
- package/src/components/Layout/401/401.stories.tsx +23 -0
- package/src/components/Layout/401/401.tsx +1 -0
- package/src/components/Layout/403/403.stories.tsx +23 -0
- package/src/components/Layout/403/403.tsx +21 -0
- package/src/components/Layout/404/404.stories.tsx +23 -0
- package/src/components/Layout/404/404.tsx +28 -0
- package/src/components/Layout/500/500.stories.tsx +56 -0
- package/src/components/Layout/500/500.tsx +63 -0
- package/src/components/Layout/ButtonGroup/ButtonGroup.css +52 -0
- package/src/components/Layout/ButtonGroup/ButtonGroup.stories.tsx +156 -0
- package/src/components/Layout/ButtonGroup/ButtonGroup.tsx +50 -0
- package/src/components/Layout/HeadingGroup/HeadingGroup.css +21 -0
- package/src/components/Layout/HeadingGroup/HeadingGroup.stories.tsx +84 -0
- package/src/components/Layout/HeadingGroup/HeadingGroup.tsx +9 -0
- package/src/components/Layout/MainWrapper/MainWrapper.css +12 -0
- package/src/components/Layout/MainWrapper/MainWrapper.stories.tsx +36 -0
- package/src/components/Layout/MainWrapper/MainWrapper.tsx +14 -0
- package/src/components/Layout/PageShell/PageShell.css +42 -0
- package/src/components/Layout/PageShell/PageShell.stories.tsx +108 -0
- package/src/components/Layout/PageShell/PageShell.tsx +31 -0
- package/src/components/Layout/ParagraphGroup/ParagraphGroup.css +5 -0
- package/src/components/Layout/ParagraphGroup/ParagraphGroup.stories.tsx +34 -0
- package/src/components/Layout/ParagraphGroup/ParagraphGroup.tsx +9 -0
- package/src/components/Layout/Stack/Stack.css +29 -0
- package/src/components/Layout/Stack/Stack.stories.tsx +83 -0
- package/src/components/Layout/Stack/Stack.tsx +19 -0
- package/src/components/Layout/WidthContainer/WidthContainer.css +17 -0
- package/src/components/Layout/WidthContainer/WidthContainer.stories.tsx +59 -0
- package/src/components/Layout/WidthContainer/WidthContainer.tsx +13 -0
- package/src/components/Legend/Legend.css +95 -0
- package/src/components/Legend/Legend.stories.tsx +81 -0
- package/src/components/Legend/Legend.tsx +32 -0
- package/src/components/Legend/LegendDot.tsx +15 -0
- package/src/components/Legend/LegendPanel.stories.tsx +101 -0
- package/src/components/Legend/LegendPanel.tsx +68 -0
- package/src/components/Legend/LegendSkeleton.stories.tsx +87 -0
- package/src/components/Legend/LegendSkeleton.tsx +73 -0
- package/src/components/LegendSelect/LegendSelect.css +8 -0
- package/src/components/LegendSelect/LegendSelect.stories.tsx +80 -0
- package/src/components/LegendSelect/LegendSelect.tsx +26 -0
- package/src/components/Link/Link.css +98 -0
- package/src/components/Link/Link.stories.tsx +70 -0
- package/src/components/Link/Link.tsx +52 -0
- package/src/components/LinkButton/LinkButton.css +67 -0
- package/src/components/LinkButton/LinkButton.stories.tsx +90 -42
- package/src/components/LinkButton/LinkButton.tsx +50 -63
- package/src/components/LinkList/LinkList.css +28 -0
- package/src/components/LinkList/LinkList.stories.tsx +46 -0
- package/src/components/LinkList/LinkList.tsx +23 -0
- package/src/components/List/Li.tsx +9 -0
- package/src/components/List/List.css +9 -0
- package/src/components/List/OrderedList.stories.tsx +36 -0
- package/src/components/List/OrderedList.tsx +9 -0
- package/src/components/List/UnorderedList.stories.tsx +36 -0
- package/src/components/List/UnorderedList.tsx +9 -0
- package/src/components/LoadingBox/LoadingBox.css +27 -0
- package/src/components/LoadingBox/LoadingBox.stories.tsx +66 -0
- package/src/components/LoadingBox/LoadingBox.tsx +40 -0
- package/src/components/Modal/Modal.css +111 -0
- package/src/components/Modal/Modal.stories.tsx +94 -155
- package/src/components/Modal/Modal.tsx +141 -75
- package/src/components/NoScriptBanner/NoScriptBanner.css +17 -0
- package/src/components/NoScriptBanner/NoScriptBanner.stories.tsx +46 -0
- package/src/components/NoScriptBanner/NoScriptBanner.tsx +26 -0
- package/src/components/Paragraph/Paragraph.css +22 -0
- package/src/components/Paragraph/Paragraph.stories.tsx +1 -42
- package/src/components/Paragraph/Paragraph.tsx +4 -3
- package/src/components/Paragraph/ParagraphSkeleton.stories.tsx +44 -0
- package/src/components/Paragraph/ParagraphSkeleton.tsx +33 -0
- package/src/components/PasswordInput/PasswordInput.css +3 -0
- package/src/components/PasswordInput/PasswordInput.stories.tsx +47 -0
- package/src/components/PasswordInput/PasswordInput.tsx +45 -0
- package/src/components/PhaseBanner/PhaseBanner.css +12 -0
- package/src/components/PhaseBanner/PhaseBanner.stories.tsx +61 -0
- package/src/components/PhaseBanner/PhaseBanner.tsx +17 -0
- package/src/components/Popover/Popover.css +43 -0
- package/src/components/Popover/Popover.stories.tsx +102 -0
- package/src/components/Popover/Popover.tsx +40 -0
- package/src/components/Radio/Radio.css +69 -0
- package/src/components/Radio/Radio.stories.tsx +169 -0
- package/src/components/Radio/Radio.tsx +56 -0
- package/src/components/Resizable/Resizable.css +86 -0
- package/src/components/Resizable/Resizable.stories.tsx +123 -0
- package/src/components/Resizable/Resizable.tsx +86 -0
- package/src/components/ScrollArea/ScrollArea.css +9 -0
- package/src/components/ScrollArea/ScrollArea.stories.tsx +42 -0
- package/src/components/ScrollArea/ScrollArea.tsx +11 -0
- package/src/components/SearchBox/SearchBox.stories.tsx +88 -0
- package/src/components/SearchBox/SearchBox.tsx +36 -0
- package/src/components/Select/AsyncSelect.stories.tsx +84 -0
- package/src/components/Select/AsyncSelect.tsx +41 -0
- package/src/components/Select/Select.css +202 -0
- package/src/components/Select/Select.stories.tsx +162 -0
- package/src/components/Select/Select.test.tsx +36 -0
- package/src/components/Select/Select.tsx +296 -0
- package/src/components/Select/SelectSkeleton.stories.tsx +51 -0
- package/src/components/Select/SelectSkeleton.tsx +23 -0
- package/src/components/Separator/Separator.css +41 -0
- package/src/components/Separator/Separator.stories.tsx +63 -0
- package/src/components/Separator/Separator.tsx +42 -0
- package/src/components/Sidebar/ResizableSidebar.tsx +118 -0
- package/src/components/Sidebar/Sidebar.css +203 -0
- package/src/components/Sidebar/Sidebar.stories.tsx +438 -0
- package/src/components/Sidebar/Sidebar.tsx +225 -0
- package/src/components/Skeleton/Skeleton.css +16 -0
- package/src/components/Skeleton/Skeleton.stories.tsx +39 -0
- package/src/components/Skeleton/Skeleton.tsx +12 -0
- package/src/components/SkipLink/SkipLink.css +16 -0
- package/src/components/SkipLink/SkipLink.stories.tsx +40 -0
- package/src/components/SkipLink/SkipLink.tsx +15 -0
- package/src/components/Spinner/Spinner.css +30 -0
- package/src/components/Spinner/Spinner.stories.tsx +36 -0
- package/src/components/Spinner/Spinner.tsx +45 -0
- package/src/components/StartButton/StartButton.css +13 -0
- package/src/components/StartButton/StartButton.stories.tsx +68 -0
- package/src/components/StartButton/StartButton.tsx +50 -0
- package/src/components/SubmitButton/SubmitButton.stories.tsx +31 -0
- package/src/components/SubmitButton/SubmitButton.tsx +14 -0
- package/src/components/SummaryList/SummaryList.css +71 -0
- package/src/components/SummaryList/SummaryList.stories.tsx +211 -0
- package/src/components/SummaryList/SummaryList.tsx +41 -0
- package/src/components/SummaryList/SummaryListSkeleton.stories.tsx +67 -0
- package/src/components/SummaryList/SummaryListSkeleton.tsx +40 -0
- package/src/components/Tabs/Tabs.css +84 -0
- package/src/components/Tabs/Tabs.stories.tsx +133 -0
- package/src/components/Tabs/Tabs.tsx +66 -0
- package/src/components/Tag/Tag.css +8 -0
- package/src/components/Tag/Tag.stories.tsx +96 -0
- package/src/components/Tag/Tag.tsx +34 -0
- package/src/components/Textarea/Textarea.css +38 -0
- package/src/components/Textarea/Textarea.stories.tsx +131 -0
- package/src/components/Textarea/Textarea.tsx +50 -0
- package/src/components/TextareaCount/TextareaCount.css +17 -0
- package/src/components/TextareaCount/TextareaCount.stories.tsx +131 -0
- package/src/components/TextareaCount/TextareaCount.tsx +108 -0
- package/src/components/Tooltip/Tooltip.css +43 -0
- package/src/components/Tooltip/Tooltip.stories.tsx +110 -0
- package/src/components/Tooltip/Tooltip.tsx +53 -0
- package/src/components/WarningText/WarningText.css +20 -0
- package/src/components/WarningText/WarningText.stories.tsx +29 -0
- package/src/components/WarningText/WarningText.tsx +17 -0
- package/src/components/index.ts +343 -61
- package/src/errors/errorDisplay.ts +70 -0
- package/src/errors/index.ts +1 -0
- package/src/http/constants.ts +2 -0
- package/src/http/fetch.ts +7 -3
- package/src/map/LayerSwitcherPanel.tsx +2 -173
- package/src/map/LegendShim.tsx +2 -0
- package/src/map/MapComponent.tsx +7 -17
- package/src/map/MapControlsOverlay.tsx +68 -175
- package/src/map/Popup.tsx +71 -24
- package/src/map/geocoder/Geocoder.test.tsx +46 -3
- package/src/map/geocoder/Geocoder.tsx +155 -278
- package/src/map/index.ts +1 -1
- package/src/types/utils.ts +0 -10
- package/src/utils/components.ts +96 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/utils.ts +0 -12
- package/src/assets/images/defra-logo.svg +0 -51
- package/src/assets/images/ea-logo.svg +0 -58
- package/src/assets/images/ogl.svg +0 -1
- package/src/components/Button/Button.test.tsx +0 -53
- package/src/components/ButtonLink/ButtonLink.test.tsx +0 -154
- package/src/components/Card/Card.test.tsx +0 -51
- package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +0 -75
- package/src/components/ErrorBoundary/ErrorFallback.test.tsx +0 -107
- package/src/components/ErrorText/ErrorText.test.tsx +0 -33
- package/src/components/Heading/Heading.test.tsx +0 -22
- package/src/components/Hint/Hint.stories.tsx +0 -58
- package/src/components/Hint/Hint.test.tsx +0 -33
- package/src/components/Hint/Hint.tsx +0 -12
- package/src/components/InfoBox/InfoBox.test.tsx +0 -330
- package/src/components/InfoBox/types.ts +0 -6
- package/src/components/LinkButton/LinkButton.test.tsx +0 -177
- package/src/components/Modal/Modal.test.tsx +0 -246
- package/src/components/NotificationBanner/NotificationBanner.stories.tsx +0 -45
- package/src/components/NotificationBanner/NotificationBanner.test.tsx +0 -58
- package/src/components/NotificationBanner/NotificationBanner.tsx +0 -45
- package/src/components/Paragraph/Paragraph.test.tsx +0 -10
- package/src/components/SlidingPanel/SlidingPanel.stories.tsx +0 -129
- package/src/components/SlidingPanel/SlidingPanel.test.tsx +0 -83
- package/src/components/SlidingPanel/SlidingPanel.tsx +0 -258
- package/src/components/accordion/Accordion.stories.tsx +0 -234
- package/src/components/accordion/Accordion.test.tsx +0 -192
- package/src/components/accordion/Accordion.tsx +0 -73
- package/src/components/backToTop/BackToTop.stories.tsx +0 -407
- package/src/components/backToTop/BackToTop.test.tsx +0 -57
- package/src/components/backToTop/BackToTop.tsx +0 -134
- package/src/components/chip/Chip.stories.tsx +0 -61
- package/src/components/chip/Chip.test.tsx +0 -31
- package/src/components/chip/Chip.tsx +0 -23
- package/src/components/container/Container.tsx +0 -42
- package/src/components/cookieBanner/CookieBanner.stories.tsx +0 -257
- package/src/components/cookieBanner/CookieBanner.test.tsx +0 -68
- package/src/components/cookieBanner/CookieBanner.tsx +0 -73
- package/src/components/divider/RuleDivider.stories.tsx +0 -254
- package/src/components/divider/RuleDivider.test.tsx +0 -164
- package/src/components/divider/RuleDivider.tsx +0 -23
- package/src/components/dropdown/DropdownMenu.test.tsx +0 -211
- package/src/components/dropdown/DropdownMenu.tsx +0 -108
- package/src/components/dropdown/useDropdownMenu.ts +0 -249
- package/src/components/form/Input.stories.tsx +0 -435
- package/src/components/form/Input.test.tsx +0 -206
- package/src/components/form/Input.tsx +0 -23
- package/src/components/form/TextArea.stories.tsx +0 -464
- package/src/components/form/TextArea.test.tsx +0 -232
- package/src/components/form/TextArea.tsx +0 -23
- package/src/components/layout/footer/Footer.tsx +0 -26
- package/src/components/layout/footer/Licence.tsx +0 -19
- package/src/components/layout/footer/MetaLinks.tsx +0 -36
- package/src/components/layout/header/Header.test.tsx +0 -36
- package/src/components/layout/header/Header.tsx +0 -90
- package/src/components/layout/header/HeaderAuthClient.test.tsx +0 -45
- package/src/components/layout/header/HeaderAuthClient.tsx +0 -40
- package/src/components/layout/header/HeaderNavClient.test.tsx +0 -44
- package/src/components/layout/header/HeaderNavClient.tsx +0 -67
- package/src/components/link/ExternalLink.test.tsx +0 -102
- package/src/components/link/ExternalLink.tsx +0 -29
- package/src/components/link/Link.tsx +0 -26
- package/src/components/select/Select.stories.tsx +0 -336
- package/src/components/select/Select.test.tsx +0 -474
- package/src/components/select/Select.tsx +0 -125
- package/src/components/select/SelectSkeleton.stories.tsx +0 -194
- package/src/components/select/SelectSkeleton.test.tsx +0 -104
- package/src/components/select/SelectSkeleton.tsx +0 -23
- package/src/components/select/common.ts +0 -3
- package/src/components/select/index.ts +0 -18
- package/src/components/skipLink/SkipLink.stories.tsx +0 -346
- package/src/components/skipLink/SkipLink.test.tsx +0 -22
- package/src/components/skipLink/SkipLink.tsx +0 -49
- package/src/map/LegendPanel.tsx +0 -85
- /package/src/{components → assets}/images/DefraLogo.tsx +0 -0
- /package/src/{components → assets}/images/EaLogo.tsx +0 -0
- /package/src/{components → assets}/images/OglLogo.tsx +0 -0
- /package/src/components/{googleAnalytics → GoogleAnalytics}/GlobalVars.tsx +0 -0
- /package/src/components/{googleAnalytics → GoogleAnalytics}/GoogleAnalytics.tsx +0 -0
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
import { Accordion } from './Accordion';
|
|
2
|
-
import { render, screen, userEvent } from '../../test/renderers';
|
|
3
|
-
|
|
4
|
-
const TEST_CONTENT = 'Test content';
|
|
5
|
-
const ARIA_EXPANDED = 'aria-expanded';
|
|
6
|
-
const ARIA_HIDDEN = 'aria-hidden';
|
|
7
|
-
|
|
8
|
-
describe('Accordion', () => {
|
|
9
|
-
it('should render with title and content', () => {
|
|
10
|
-
render(
|
|
11
|
-
<Accordion title="Test Section">
|
|
12
|
-
<div>{TEST_CONTENT}</div>
|
|
13
|
-
</Accordion>,
|
|
14
|
-
);
|
|
15
|
-
|
|
16
|
-
expect(screen.getByText('Test Section')).toBeInTheDocument();
|
|
17
|
-
expect(screen.getByText(TEST_CONTENT)).toBeInTheDocument();
|
|
18
|
-
|
|
19
|
-
expect(screen.getByText(TEST_CONTENT).closest('section')).toHaveClass('hidden');
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
it('should render with content closed by default', () => {
|
|
23
|
-
render(
|
|
24
|
-
<Accordion title="Test Section">
|
|
25
|
-
<div>{TEST_CONTENT}</div>
|
|
26
|
-
</Accordion>,
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
expect(screen.getByRole('button', { name: /test section/i })).toHaveAttribute(
|
|
30
|
-
ARIA_EXPANDED,
|
|
31
|
-
'false',
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
const section = screen.getByText(TEST_CONTENT).closest('section');
|
|
35
|
-
|
|
36
|
-
expect(section).toHaveAttribute(ARIA_HIDDEN, 'true');
|
|
37
|
-
expect(section).toHaveClass('hidden');
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('should open and close content when clicked', async () => {
|
|
41
|
-
const user = userEvent.setup();
|
|
42
|
-
|
|
43
|
-
render(
|
|
44
|
-
<Accordion title="Test Section">
|
|
45
|
-
<div>Test content</div>
|
|
46
|
-
</Accordion>,
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
const button = screen.getByRole('button', { name: /test section/i });
|
|
50
|
-
const section = screen.getByText(TEST_CONTENT).closest('section');
|
|
51
|
-
|
|
52
|
-
// Initially closed
|
|
53
|
-
expect(button).toHaveAttribute(ARIA_EXPANDED, 'false');
|
|
54
|
-
expect(section).toHaveAttribute(ARIA_HIDDEN, 'true');
|
|
55
|
-
expect(section).toHaveClass('hidden');
|
|
56
|
-
|
|
57
|
-
// Click to open
|
|
58
|
-
await user.click(button);
|
|
59
|
-
expect(button).toHaveAttribute(ARIA_EXPANDED, 'true');
|
|
60
|
-
expect(section).toHaveAttribute(ARIA_HIDDEN, 'false');
|
|
61
|
-
expect(section).toHaveClass('block');
|
|
62
|
-
|
|
63
|
-
// Click again to close
|
|
64
|
-
await user.click(button);
|
|
65
|
-
expect(button).toHaveAttribute(ARIA_EXPANDED, 'false');
|
|
66
|
-
expect(section).toHaveAttribute(ARIA_HIDDEN, 'true');
|
|
67
|
-
expect(section).toHaveClass('hidden');
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it('should render with content open when defaultOpen is true', () => {
|
|
71
|
-
render(
|
|
72
|
-
<Accordion title="Test Section" defaultOpen>
|
|
73
|
-
<div>Test content</div>
|
|
74
|
-
</Accordion>,
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
const button = screen.getByRole('button', { name: /test section/i });
|
|
78
|
-
|
|
79
|
-
expect(button).toHaveAttribute(ARIA_EXPANDED, 'true');
|
|
80
|
-
expect(screen.getByText(TEST_CONTENT)).toBeInTheDocument();
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it('should have proper accessibility attributes', () => {
|
|
84
|
-
render(
|
|
85
|
-
<Accordion title="Test Section">
|
|
86
|
-
<div>Test content</div>
|
|
87
|
-
</Accordion>,
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
const button = screen.getByRole('button', { name: /test section/i });
|
|
91
|
-
|
|
92
|
-
expect(button).toHaveAttribute(ARIA_EXPANDED, 'false');
|
|
93
|
-
expect(button).toHaveAttribute('aria-controls');
|
|
94
|
-
expect(button).toHaveAttribute('id');
|
|
95
|
-
|
|
96
|
-
const content = screen.getByRole('region', { hidden: true });
|
|
97
|
-
|
|
98
|
-
expect(content).toHaveAttribute('aria-labelledby', button.id);
|
|
99
|
-
expect(content).toHaveAttribute(ARIA_HIDDEN, 'true');
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it('should update aria-hidden when opened', async () => {
|
|
103
|
-
const user = userEvent.setup();
|
|
104
|
-
|
|
105
|
-
render(
|
|
106
|
-
<Accordion title="Test Section">
|
|
107
|
-
<div>Test content</div>
|
|
108
|
-
</Accordion>,
|
|
109
|
-
);
|
|
110
|
-
|
|
111
|
-
const button = screen.getByRole('button', { name: /test section/i });
|
|
112
|
-
const content = screen.getByRole('region', { hidden: true });
|
|
113
|
-
|
|
114
|
-
expect(content).toHaveAttribute(ARIA_HIDDEN, 'true');
|
|
115
|
-
|
|
116
|
-
await user.click(button);
|
|
117
|
-
|
|
118
|
-
expect(content).toHaveAttribute(ARIA_HIDDEN, 'false');
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
it('should render complex content correctly', () => {
|
|
122
|
-
render(
|
|
123
|
-
<Accordion title="Complex Section" defaultOpen>
|
|
124
|
-
<div>
|
|
125
|
-
<p>Paragraph content</p>
|
|
126
|
-
|
|
127
|
-
<button>Nested button</button>
|
|
128
|
-
|
|
129
|
-
<ul>
|
|
130
|
-
<li>List item 1</li>
|
|
131
|
-
|
|
132
|
-
<li>List item 2</li>
|
|
133
|
-
</ul>
|
|
134
|
-
</div>
|
|
135
|
-
</Accordion>,
|
|
136
|
-
);
|
|
137
|
-
|
|
138
|
-
expect(screen.getByText('Paragraph content')).toBeInTheDocument();
|
|
139
|
-
expect(screen.getByRole('button', { name: 'Nested button' })).toBeInTheDocument();
|
|
140
|
-
expect(screen.getByText('List item 1')).toBeInTheDocument();
|
|
141
|
-
expect(screen.getByText('List item 2')).toBeInTheDocument();
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
it('should rotate chevron icon when opened', async () => {
|
|
145
|
-
const user = userEvent.setup();
|
|
146
|
-
|
|
147
|
-
render(
|
|
148
|
-
<Accordion title="Test Section">
|
|
149
|
-
<div>Test content</div>
|
|
150
|
-
</Accordion>,
|
|
151
|
-
);
|
|
152
|
-
|
|
153
|
-
const button = screen.getByRole('button', { name: /test section/i });
|
|
154
|
-
const chevron = button.querySelector('.rotate-180');
|
|
155
|
-
|
|
156
|
-
// Should not have rotate-180 class when closed
|
|
157
|
-
expect(chevron).toBeNull();
|
|
158
|
-
|
|
159
|
-
await user.click(button);
|
|
160
|
-
|
|
161
|
-
// Should have rotate-180 class when opened
|
|
162
|
-
const rotatedChevron = button.querySelector('.rotate-180');
|
|
163
|
-
|
|
164
|
-
expect(rotatedChevron).toBeInTheDocument();
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
it('should have correct styling classes', () => {
|
|
168
|
-
render(
|
|
169
|
-
<Accordion title="Test Section">
|
|
170
|
-
<div>Test content</div>
|
|
171
|
-
</Accordion>,
|
|
172
|
-
);
|
|
173
|
-
|
|
174
|
-
const container = screen.getByRole('button').closest('div');
|
|
175
|
-
|
|
176
|
-
expect(container).toHaveClass('flex', 'flex-col', 'border-l-2', 'border-neutral-100');
|
|
177
|
-
|
|
178
|
-
const button = screen.getByRole('button');
|
|
179
|
-
|
|
180
|
-
expect(button).toHaveClass(
|
|
181
|
-
'flex',
|
|
182
|
-
'justify-between',
|
|
183
|
-
'items-center',
|
|
184
|
-
'px-2',
|
|
185
|
-
'py-1',
|
|
186
|
-
'text-[color:#000000]',
|
|
187
|
-
'border-y-2',
|
|
188
|
-
'border-neutral-100',
|
|
189
|
-
'focus-yellow',
|
|
190
|
-
);
|
|
191
|
-
});
|
|
192
|
-
});
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { type ReactNode, useId, useState } from 'react';
|
|
4
|
-
|
|
5
|
-
import { LuChevronDown } from 'react-icons/lu';
|
|
6
|
-
|
|
7
|
-
import type { ExtendProps } from '../../types';
|
|
8
|
-
import { cn } from '../../utils';
|
|
9
|
-
|
|
10
|
-
type Props = {
|
|
11
|
-
title: string;
|
|
12
|
-
children: ReactNode;
|
|
13
|
-
defaultOpen?: boolean;
|
|
14
|
-
disabled?: boolean;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export type AccordionProps = ExtendProps<'div', Props>;
|
|
18
|
-
|
|
19
|
-
export const Accordion = ({
|
|
20
|
-
title,
|
|
21
|
-
children,
|
|
22
|
-
defaultOpen = false,
|
|
23
|
-
disabled = false,
|
|
24
|
-
className,
|
|
25
|
-
...props
|
|
26
|
-
}: AccordionProps) => {
|
|
27
|
-
const contentId = useId();
|
|
28
|
-
const buttonId = useId();
|
|
29
|
-
|
|
30
|
-
const [isOpen, setIsOpen] = useState(defaultOpen);
|
|
31
|
-
|
|
32
|
-
return (
|
|
33
|
-
<div
|
|
34
|
-
className={cn(
|
|
35
|
-
'flex flex-col border-l-2 border-neutral-100',
|
|
36
|
-
disabled ? 'opacity-50' : '',
|
|
37
|
-
className,
|
|
38
|
-
)}
|
|
39
|
-
{...props}
|
|
40
|
-
>
|
|
41
|
-
<button
|
|
42
|
-
aria-expanded={disabled ? undefined : isOpen}
|
|
43
|
-
aria-controls={disabled ? undefined : contentId}
|
|
44
|
-
disabled={disabled}
|
|
45
|
-
className={cn(
|
|
46
|
-
`flex justify-between items-center px-2 py-1 bg-[#fefefefe] text-[color:#000000]
|
|
47
|
-
border-y-2 border-neutral-100`,
|
|
48
|
-
disabled ? 'cursor-not-allowed' : 'focus-yellow',
|
|
49
|
-
)}
|
|
50
|
-
id={buttonId}
|
|
51
|
-
onClick={disabled ? undefined : () => setIsOpen(!isOpen)}
|
|
52
|
-
type="button"
|
|
53
|
-
>
|
|
54
|
-
<span>{title}</span>
|
|
55
|
-
|
|
56
|
-
<span aria-hidden="true">
|
|
57
|
-
<LuChevronDown className={cn('w-4 h-4', isOpen ? 'rotate-180' : '')} />
|
|
58
|
-
</span>
|
|
59
|
-
</button>
|
|
60
|
-
|
|
61
|
-
{!disabled ? (
|
|
62
|
-
<section
|
|
63
|
-
id={contentId}
|
|
64
|
-
aria-labelledby={buttonId}
|
|
65
|
-
aria-hidden={!isOpen}
|
|
66
|
-
className={cn('p-2 bg-[#efefef]', isOpen ? 'block' : 'hidden')}
|
|
67
|
-
>
|
|
68
|
-
{children}
|
|
69
|
-
</section>
|
|
70
|
-
) : null}
|
|
71
|
-
</div>
|
|
72
|
-
);
|
|
73
|
-
};
|
|
@@ -1,407 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
-
|
|
3
|
-
import { BackToTop } from './BackToTop';
|
|
4
|
-
|
|
5
|
-
const meta = {
|
|
6
|
-
title: 'Components/BackToTop',
|
|
7
|
-
component: BackToTop,
|
|
8
|
-
parameters: {
|
|
9
|
-
layout: 'fullscreen',
|
|
10
|
-
docs: {
|
|
11
|
-
description: {
|
|
12
|
-
component:
|
|
13
|
-
'A floating "Back to Top" button that appears when the user scrolls down and allows quick navigation back to the top of the page.',
|
|
14
|
-
},
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
tags: ['autodocs'],
|
|
18
|
-
argTypes: {
|
|
19
|
-
threshold: {
|
|
20
|
-
control: { type: 'number', min: 0, max: 2000, step: 100 },
|
|
21
|
-
description: 'Scroll threshold in pixels before button appears',
|
|
22
|
-
defaultValue: 600,
|
|
23
|
-
},
|
|
24
|
-
bottom: {
|
|
25
|
-
control: { type: 'number', min: 0, max: 100, step: 4 },
|
|
26
|
-
description: 'Position from bottom in pixels',
|
|
27
|
-
defaultValue: 16,
|
|
28
|
-
},
|
|
29
|
-
left: {
|
|
30
|
-
control: { type: 'number', min: 0, max: 100, step: 4 },
|
|
31
|
-
description: 'Position from left in pixels',
|
|
32
|
-
defaultValue: 8,
|
|
33
|
-
},
|
|
34
|
-
className: {
|
|
35
|
-
control: 'text',
|
|
36
|
-
description: 'Custom className for additional styling',
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
} satisfies Meta<typeof BackToTop>;
|
|
40
|
-
|
|
41
|
-
export default meta;
|
|
42
|
-
|
|
43
|
-
type Story = StoryObj<typeof meta>;
|
|
44
|
-
|
|
45
|
-
export const Default: Story = {
|
|
46
|
-
parameters: {
|
|
47
|
-
docs: {
|
|
48
|
-
description: {
|
|
49
|
-
story: 'Default back to top button. Scroll down to see it appear at 600px threshold.',
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
render: (args) => (
|
|
54
|
-
<div>
|
|
55
|
-
<BackToTop {...args} />
|
|
56
|
-
|
|
57
|
-
<div className="space-y-8 p-8">
|
|
58
|
-
<h1 className="text-3xl font-bold">Scroll down to see the Back to Top button</h1>
|
|
59
|
-
|
|
60
|
-
<div className="space-y-6">
|
|
61
|
-
{Array.from({ length: 50 }, (_, i) => (
|
|
62
|
-
<div key={i} className="p-4 bg-gray-100 rounded">
|
|
63
|
-
<h2 className="text-xl font-semibold mb-2">Section {i + 1}</h2>
|
|
64
|
-
|
|
65
|
-
<p>
|
|
66
|
-
This is content section {i + 1}. Lorem ipsum dolor sit amet, consectetur adipiscing
|
|
67
|
-
elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
|
|
68
|
-
minim veniam, quis nostrud exercitation ullamco laboris.
|
|
69
|
-
</p>
|
|
70
|
-
</div>
|
|
71
|
-
))}
|
|
72
|
-
</div>
|
|
73
|
-
</div>
|
|
74
|
-
</div>
|
|
75
|
-
),
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
export const LowThreshold: Story = {
|
|
79
|
-
args: {
|
|
80
|
-
threshold: 200,
|
|
81
|
-
},
|
|
82
|
-
parameters: {
|
|
83
|
-
docs: {
|
|
84
|
-
description: {
|
|
85
|
-
story: 'Back to top button with a low threshold (200px) - appears quickly when scrolling.',
|
|
86
|
-
},
|
|
87
|
-
},
|
|
88
|
-
},
|
|
89
|
-
render: (args) => (
|
|
90
|
-
<div>
|
|
91
|
-
<BackToTop {...args} />
|
|
92
|
-
|
|
93
|
-
<div className="space-y-8 p-8">
|
|
94
|
-
<h1 className="text-3xl font-bold">Low Threshold Example (200px)</h1>
|
|
95
|
-
|
|
96
|
-
<div className="bg-yellow-100 border border-yellow-400 rounded p-4 mb-6">
|
|
97
|
-
<p className="text-yellow-800">
|
|
98
|
-
This example has a low threshold of 200px. The button will appear much sooner when
|
|
99
|
-
scrolling.
|
|
100
|
-
</p>
|
|
101
|
-
</div>
|
|
102
|
-
|
|
103
|
-
<div className="space-y-6">
|
|
104
|
-
{Array.from({ length: 30 }, (_, i) => (
|
|
105
|
-
<div key={i} className="p-4 bg-blue-50 rounded">
|
|
106
|
-
<h2 className="text-xl font-semibold mb-2">Content Block {i + 1}</h2>
|
|
107
|
-
|
|
108
|
-
<p>
|
|
109
|
-
Content with low threshold setting. The back to top button should appear after
|
|
110
|
-
scrolling just 200 pixels down the page.
|
|
111
|
-
</p>
|
|
112
|
-
</div>
|
|
113
|
-
))}
|
|
114
|
-
</div>
|
|
115
|
-
</div>
|
|
116
|
-
</div>
|
|
117
|
-
),
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
export const CustomPosition: Story = {
|
|
121
|
-
args: {
|
|
122
|
-
bottom: 32,
|
|
123
|
-
left: 32,
|
|
124
|
-
},
|
|
125
|
-
parameters: {
|
|
126
|
-
docs: {
|
|
127
|
-
description: {
|
|
128
|
-
story: 'Back to top button with custom positioning (32px from bottom and left).',
|
|
129
|
-
},
|
|
130
|
-
},
|
|
131
|
-
},
|
|
132
|
-
render: (args) => (
|
|
133
|
-
<div>
|
|
134
|
-
<BackToTop {...args} />
|
|
135
|
-
|
|
136
|
-
<div className="space-y-8 p-8">
|
|
137
|
-
<h1 className="text-3xl font-bold">Custom Position Example</h1>
|
|
138
|
-
|
|
139
|
-
<div className="bg-green-100 border border-green-400 rounded p-4 mb-6">
|
|
140
|
-
<p className="text-green-800">
|
|
141
|
-
This button is positioned 32px from both bottom and left edges.
|
|
142
|
-
</p>
|
|
143
|
-
</div>
|
|
144
|
-
|
|
145
|
-
<div className="space-y-6">
|
|
146
|
-
{Array.from({ length: 40 }, (_, i) => (
|
|
147
|
-
<div key={i} className="p-4 bg-green-50 rounded">
|
|
148
|
-
<h2 className="text-xl font-semibold mb-2">Section {i + 1}</h2>
|
|
149
|
-
|
|
150
|
-
<p>Scroll down to see the back to top button in its custom position.</p>
|
|
151
|
-
</div>
|
|
152
|
-
))}
|
|
153
|
-
</div>
|
|
154
|
-
</div>
|
|
155
|
-
</div>
|
|
156
|
-
),
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
export const RightAligned: Story = {
|
|
160
|
-
args: {
|
|
161
|
-
left: undefined,
|
|
162
|
-
className: 'right-4',
|
|
163
|
-
},
|
|
164
|
-
parameters: {
|
|
165
|
-
docs: {
|
|
166
|
-
description: {
|
|
167
|
-
story: 'Back to top button positioned on the right side using custom className.',
|
|
168
|
-
},
|
|
169
|
-
},
|
|
170
|
-
},
|
|
171
|
-
render: (args) => (
|
|
172
|
-
<div>
|
|
173
|
-
<BackToTop {...args} />
|
|
174
|
-
|
|
175
|
-
<div className="space-y-8 p-8">
|
|
176
|
-
<h1 className="text-3xl font-bold">Right-Aligned Button</h1>
|
|
177
|
-
|
|
178
|
-
<div className="bg-purple-100 border border-purple-400 rounded p-4 mb-6">
|
|
179
|
-
<p className="text-purple-800">
|
|
180
|
-
This button is positioned on the right side of the screen using className override.
|
|
181
|
-
</p>
|
|
182
|
-
</div>
|
|
183
|
-
|
|
184
|
-
<div className="space-y-6">
|
|
185
|
-
{Array.from({ length: 35 }, (_, i) => (
|
|
186
|
-
<div key={i} className="p-4 bg-purple-50 rounded">
|
|
187
|
-
<h2 className="text-xl font-semibold mb-2">Content {i + 1}</h2>
|
|
188
|
-
|
|
189
|
-
<p>The back to top button appears on the right side instead of the default left.</p>
|
|
190
|
-
</div>
|
|
191
|
-
))}
|
|
192
|
-
</div>
|
|
193
|
-
</div>
|
|
194
|
-
</div>
|
|
195
|
-
),
|
|
196
|
-
};
|
|
197
|
-
|
|
198
|
-
export const CustomStyling: Story = {
|
|
199
|
-
args: {
|
|
200
|
-
className: 'bg-blue-600 text-white border-blue-700 hover:bg-blue-700 shadow-xl',
|
|
201
|
-
},
|
|
202
|
-
parameters: {
|
|
203
|
-
docs: {
|
|
204
|
-
description: {
|
|
205
|
-
story: 'Back to top button with custom styling using className prop.',
|
|
206
|
-
},
|
|
207
|
-
},
|
|
208
|
-
},
|
|
209
|
-
render: (args) => (
|
|
210
|
-
<div>
|
|
211
|
-
<BackToTop {...args} />
|
|
212
|
-
|
|
213
|
-
<div className="space-y-8 p-8">
|
|
214
|
-
<h1 className="text-3xl font-bold">Custom Styled Button</h1>
|
|
215
|
-
|
|
216
|
-
<div className="bg-blue-100 border border-blue-400 rounded p-4 mb-6">
|
|
217
|
-
<p className="text-blue-800">
|
|
218
|
-
This button has custom blue styling applied via the className prop.
|
|
219
|
-
</p>
|
|
220
|
-
</div>
|
|
221
|
-
|
|
222
|
-
<div className="space-y-6">
|
|
223
|
-
{Array.from({ length: 25 }, (_, i) => (
|
|
224
|
-
<div key={i} className="p-4 bg-blue-50 rounded">
|
|
225
|
-
<h2 className="text-xl font-semibold mb-2">Styled Section {i + 1}</h2>
|
|
226
|
-
|
|
227
|
-
<p>Custom styled back to top button with blue theme.</p>
|
|
228
|
-
</div>
|
|
229
|
-
))}
|
|
230
|
-
</div>
|
|
231
|
-
</div>
|
|
232
|
-
</div>
|
|
233
|
-
),
|
|
234
|
-
};
|
|
235
|
-
|
|
236
|
-
export const AlwaysVisible: Story = {
|
|
237
|
-
args: {
|
|
238
|
-
threshold: 0,
|
|
239
|
-
},
|
|
240
|
-
parameters: {
|
|
241
|
-
docs: {
|
|
242
|
-
description: {
|
|
243
|
-
story: 'Back to top button that is always visible (threshold set to 0).',
|
|
244
|
-
},
|
|
245
|
-
},
|
|
246
|
-
},
|
|
247
|
-
render: (args) => (
|
|
248
|
-
<div>
|
|
249
|
-
<BackToTop {...args} />
|
|
250
|
-
|
|
251
|
-
<div className="space-y-8 p-8">
|
|
252
|
-
<h1 className="text-3xl font-bold">Always Visible Button</h1>
|
|
253
|
-
|
|
254
|
-
<div className="bg-red-100 border border-red-400 rounded p-4 mb-6">
|
|
255
|
-
<p className="text-red-800">
|
|
256
|
-
This button is always visible because threshold is set to 0px.
|
|
257
|
-
</p>
|
|
258
|
-
</div>
|
|
259
|
-
|
|
260
|
-
<div className="space-y-6">
|
|
261
|
-
{Array.from({ length: 20 }, (_, i) => (
|
|
262
|
-
<div key={i} className="p-4 bg-red-50 rounded">
|
|
263
|
-
<h2 className="text-xl font-semibold mb-2">Always Visible {i + 1}</h2>
|
|
264
|
-
|
|
265
|
-
<p>The button is visible even at the top of the page.</p>
|
|
266
|
-
</div>
|
|
267
|
-
))}
|
|
268
|
-
</div>
|
|
269
|
-
</div>
|
|
270
|
-
</div>
|
|
271
|
-
),
|
|
272
|
-
};
|
|
273
|
-
|
|
274
|
-
export const LongPageExample: Story = {
|
|
275
|
-
parameters: {
|
|
276
|
-
docs: {
|
|
277
|
-
description: {
|
|
278
|
-
story: 'Comprehensive example with a very long page to test scroll behavior thoroughly.',
|
|
279
|
-
},
|
|
280
|
-
},
|
|
281
|
-
},
|
|
282
|
-
render: (args) => (
|
|
283
|
-
<div>
|
|
284
|
-
<BackToTop {...args} />
|
|
285
|
-
|
|
286
|
-
<div className="space-y-8 p-8">
|
|
287
|
-
<header className="mb-12">
|
|
288
|
-
<h1 className="text-4xl font-bold mb-4">Long Page Scroll Test</h1>
|
|
289
|
-
|
|
290
|
-
<p className="text-lg text-gray-600">
|
|
291
|
-
This page demonstrates the back to top functionality with extensive content. Scroll down
|
|
292
|
-
to see the button appear after 600px.
|
|
293
|
-
</p>
|
|
294
|
-
</header>
|
|
295
|
-
|
|
296
|
-
<section className="space-y-8">
|
|
297
|
-
<h2 className="text-2xl font-bold border-b pb-2">Article Content</h2>
|
|
298
|
-
{Array.from({ length: 100 }, (_, i) => (
|
|
299
|
-
<article key={i} className="p-6 bg-white border rounded-lg shadow-sm">
|
|
300
|
-
<h3 className="text-xl font-semibold mb-3">Article {i + 1}</h3>
|
|
301
|
-
|
|
302
|
-
<p className="mb-4">
|
|
303
|
-
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor
|
|
304
|
-
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
|
|
305
|
-
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
|
306
|
-
</p>
|
|
307
|
-
|
|
308
|
-
<p>
|
|
309
|
-
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
|
|
310
|
-
fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
|
|
311
|
-
qui officia deserunt mollit anim id est laborum.
|
|
312
|
-
</p>
|
|
313
|
-
{i % 10 === 9 ? (
|
|
314
|
-
<div className="mt-4 p-3 bg-gray-100 rounded">
|
|
315
|
-
<p className="text-sm text-gray-600">
|
|
316
|
-
📍 Checkpoint: You've scrolled through {i + 1} articles. Use the back to
|
|
317
|
-
top button to return to the beginning!
|
|
318
|
-
</p>
|
|
319
|
-
</div>
|
|
320
|
-
) : null}
|
|
321
|
-
</article>
|
|
322
|
-
))}
|
|
323
|
-
</section>
|
|
324
|
-
|
|
325
|
-
<footer className="mt-12 p-6 bg-gray-800 text-white rounded">
|
|
326
|
-
<p className="text-center">
|
|
327
|
-
🎉 You've reached the end! Use the back to top button to scroll back up.
|
|
328
|
-
</p>
|
|
329
|
-
</footer>
|
|
330
|
-
</div>
|
|
331
|
-
</div>
|
|
332
|
-
),
|
|
333
|
-
};
|
|
334
|
-
|
|
335
|
-
export const AccessibilityDemo: Story = {
|
|
336
|
-
parameters: {
|
|
337
|
-
docs: {
|
|
338
|
-
description: {
|
|
339
|
-
story:
|
|
340
|
-
'Demonstration of accessibility features including keyboard navigation and screen reader support.',
|
|
341
|
-
},
|
|
342
|
-
},
|
|
343
|
-
},
|
|
344
|
-
render: (args) => (
|
|
345
|
-
<div>
|
|
346
|
-
<BackToTop {...args} />
|
|
347
|
-
|
|
348
|
-
<div className="space-y-8 p-8">
|
|
349
|
-
<h1 className="text-3xl font-bold">Accessibility Features Demo</h1>
|
|
350
|
-
|
|
351
|
-
<div className="bg-blue-50 border border-blue-200 rounded p-6">
|
|
352
|
-
<h2 className="text-xl font-bold text-blue-800 mb-4">Accessibility Features:</h2>
|
|
353
|
-
|
|
354
|
-
<ul className="list-disc list-inside space-y-2 text-blue-700">
|
|
355
|
-
<li>
|
|
356
|
-
<strong>Keyboard Navigation:</strong> Tab to focus, Enter or Space to activate
|
|
357
|
-
</li>
|
|
358
|
-
|
|
359
|
-
<li>
|
|
360
|
-
<strong>Screen Reader:</strong> Proper aria-label and hidden decorative icon
|
|
361
|
-
</li>
|
|
362
|
-
|
|
363
|
-
<li>
|
|
364
|
-
<strong>Focus Management:</strong> Visible focus indicators with ring
|
|
365
|
-
</li>
|
|
366
|
-
|
|
367
|
-
<li>
|
|
368
|
-
<strong>Responsive Text:</strong> “Back to top” text hidden on mobile,
|
|
369
|
-
available to screen readers
|
|
370
|
-
</li>
|
|
371
|
-
|
|
372
|
-
<li>
|
|
373
|
-
<strong>Semantic HTML:</strong> Proper button element with type attribute
|
|
374
|
-
</li>
|
|
375
|
-
</ul>
|
|
376
|
-
</div>
|
|
377
|
-
|
|
378
|
-
<div className="bg-green-50 border border-green-200 rounded p-4">
|
|
379
|
-
<h3 className="font-bold text-green-800 mb-2">Testing Instructions:</h3>
|
|
380
|
-
|
|
381
|
-
<ol className="list-decimal list-inside space-y-1 text-green-700 text-sm">
|
|
382
|
-
<li>Scroll down until the back to top button appears</li>
|
|
383
|
-
|
|
384
|
-
<li>Use Tab key to navigate to the button</li>
|
|
385
|
-
|
|
386
|
-
<li>Press Enter or Space to activate it</li>
|
|
387
|
-
|
|
388
|
-
<li>Test with a screen reader for proper announcements</li>
|
|
389
|
-
</ol>
|
|
390
|
-
</div>
|
|
391
|
-
|
|
392
|
-
<div className="space-y-6">
|
|
393
|
-
{Array.from({ length: 30 }, (_, i) => (
|
|
394
|
-
<div key={i} className="p-4 bg-gray-50 rounded">
|
|
395
|
-
<h3 className="text-lg font-semibold mb-2">Accessibility Section {i + 1}</h3>
|
|
396
|
-
|
|
397
|
-
<p>
|
|
398
|
-
This content tests the accessibility of the back to top button. The button should be
|
|
399
|
-
properly focusable and operable via keyboard.
|
|
400
|
-
</p>
|
|
401
|
-
</div>
|
|
402
|
-
))}
|
|
403
|
-
</div>
|
|
404
|
-
</div>
|
|
405
|
-
</div>
|
|
406
|
-
),
|
|
407
|
-
};
|