@tpzdsp/next-toolkit 2.5.1 → 3.0.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 +32 -0
- package/src/components/ErrorModal/ErrorModal.stories.tsx +101 -0
- package/src/components/ErrorModal/ErrorModal.tsx +120 -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 +4 -2
- package/src/components/Footer/Footer.stories.tsx +24 -0
- package/src/components/Footer/Footer.tsx +41 -0
- package/src/components/Footer/Licence.tsx +18 -0
- package/src/components/{layout/footer → Footer}/MetaLinks.tsx +8 -3
- package/src/components/Footer/Small/SmallFooter.tsx +43 -42
- 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 +303 -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 +114 -0
- package/src/components/Modal/Modal.stories.tsx +41 -160
- package/src/components/Modal/Modal.tsx +132 -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 +194 -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 +291 -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 +342 -61
- package/src/errors/errorDisplay.ts +70 -0
- package/src/errors/index.ts +1 -0
- package/src/http/constants.ts +1 -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/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,194 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from 'react';
|
|
2
|
-
|
|
3
|
-
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
4
|
-
|
|
5
|
-
import { SelectSkeleton } from './SelectSkeleton';
|
|
6
|
-
|
|
7
|
-
const meta = {
|
|
8
|
-
title: 'Components/SelectSkeleton',
|
|
9
|
-
component: SelectSkeleton,
|
|
10
|
-
parameters: {
|
|
11
|
-
layout: 'centered',
|
|
12
|
-
},
|
|
13
|
-
tags: ['autodocs'],
|
|
14
|
-
} satisfies Meta<typeof SelectSkeleton>;
|
|
15
|
-
|
|
16
|
-
export default meta;
|
|
17
|
-
type Story = StoryObj<typeof meta>;
|
|
18
|
-
|
|
19
|
-
export const Default: Story = {};
|
|
20
|
-
|
|
21
|
-
export const InContainer: Story = {
|
|
22
|
-
render: () => (
|
|
23
|
-
<div className="w-80">
|
|
24
|
-
<SelectSkeleton />
|
|
25
|
-
</div>
|
|
26
|
-
),
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export const Multiple: Story = {
|
|
30
|
-
render: () => (
|
|
31
|
-
<div className="space-y-4 w-80">
|
|
32
|
-
<SelectSkeleton />
|
|
33
|
-
|
|
34
|
-
<SelectSkeleton />
|
|
35
|
-
|
|
36
|
-
<SelectSkeleton />
|
|
37
|
-
</div>
|
|
38
|
-
),
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
export const InForm: Story = {
|
|
42
|
-
render: () => (
|
|
43
|
-
<form className="space-y-4 p-4 border rounded w-96">
|
|
44
|
-
<div>
|
|
45
|
-
<p className="block text-sm font-medium mb-1">Flavor</p>
|
|
46
|
-
|
|
47
|
-
<SelectSkeleton />
|
|
48
|
-
</div>
|
|
49
|
-
|
|
50
|
-
<div>
|
|
51
|
-
<p className="block text-sm font-medium mb-1">Toppings</p>
|
|
52
|
-
|
|
53
|
-
<SelectSkeleton />
|
|
54
|
-
</div>
|
|
55
|
-
|
|
56
|
-
<div>
|
|
57
|
-
<p className="block text-sm font-medium mb-1">Size</p>
|
|
58
|
-
|
|
59
|
-
<SelectSkeleton />
|
|
60
|
-
</div>
|
|
61
|
-
</form>
|
|
62
|
-
),
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
export const WithOtherSkeletons: Story = {
|
|
66
|
-
render: () => (
|
|
67
|
-
<div className="space-y-4 p-4 border rounded w-96">
|
|
68
|
-
<div>
|
|
69
|
-
<div className="h-4 bg-gray-200 rounded w-1/4 mb-2 animate-pulse"></div>
|
|
70
|
-
|
|
71
|
-
<SelectSkeleton />
|
|
72
|
-
</div>
|
|
73
|
-
|
|
74
|
-
<div>
|
|
75
|
-
<div className="h-4 bg-gray-200 rounded w-1/3 mb-2 animate-pulse"></div>
|
|
76
|
-
|
|
77
|
-
<SelectSkeleton />
|
|
78
|
-
</div>
|
|
79
|
-
|
|
80
|
-
<div className="flex gap-4">
|
|
81
|
-
<div className="flex-1">
|
|
82
|
-
<div className="h-4 bg-gray-200 rounded w-1/2 mb-2 animate-pulse"></div>
|
|
83
|
-
|
|
84
|
-
<SelectSkeleton />
|
|
85
|
-
</div>
|
|
86
|
-
|
|
87
|
-
<div className="flex-1">
|
|
88
|
-
<div className="h-4 bg-gray-200 rounded w-2/3 mb-2 animate-pulse"></div>
|
|
89
|
-
|
|
90
|
-
<SelectSkeleton />
|
|
91
|
-
</div>
|
|
92
|
-
</div>
|
|
93
|
-
</div>
|
|
94
|
-
),
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
export const DifferentWidths: Story = {
|
|
98
|
-
render: () => (
|
|
99
|
-
<div className="space-y-4">
|
|
100
|
-
<div className="w-32">
|
|
101
|
-
<div className="text-sm mb-1">Small (w-32)</div>
|
|
102
|
-
|
|
103
|
-
<SelectSkeleton />
|
|
104
|
-
</div>
|
|
105
|
-
|
|
106
|
-
<div className="w-64">
|
|
107
|
-
<div className="text-sm mb-1">Medium (w-64)</div>
|
|
108
|
-
|
|
109
|
-
<SelectSkeleton />
|
|
110
|
-
</div>
|
|
111
|
-
|
|
112
|
-
<div className="w-96">
|
|
113
|
-
<div className="text-sm mb-1">Large (w-96)</div>
|
|
114
|
-
|
|
115
|
-
<SelectSkeleton />
|
|
116
|
-
</div>
|
|
117
|
-
|
|
118
|
-
<div className="w-full max-w-lg">
|
|
119
|
-
<div className="text-sm mb-1">Full width (max-w-lg)</div>
|
|
120
|
-
|
|
121
|
-
<SelectSkeleton />
|
|
122
|
-
</div>
|
|
123
|
-
</div>
|
|
124
|
-
),
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
export const LoadingTransition: Story = {
|
|
128
|
-
render: () => {
|
|
129
|
-
const [isLoading, setIsLoading] = useState(true);
|
|
130
|
-
|
|
131
|
-
useEffect(() => {
|
|
132
|
-
const timer = setTimeout(() => {
|
|
133
|
-
setIsLoading(false);
|
|
134
|
-
}, 3000);
|
|
135
|
-
|
|
136
|
-
return () => clearTimeout(timer);
|
|
137
|
-
}, []);
|
|
138
|
-
|
|
139
|
-
return (
|
|
140
|
-
<div className="space-y-4 w-80">
|
|
141
|
-
<div className="text-sm text-gray-600">
|
|
142
|
-
{isLoading ? 'Loading options...' : 'Options loaded!'}
|
|
143
|
-
</div>
|
|
144
|
-
{isLoading ? (
|
|
145
|
-
<SelectSkeleton />
|
|
146
|
-
) : (
|
|
147
|
-
<select className="w-full p-2 border border-gray-300 rounded-md">
|
|
148
|
-
<option>Chocolate</option>
|
|
149
|
-
|
|
150
|
-
<option>Strawberry</option>
|
|
151
|
-
|
|
152
|
-
<option>Vanilla</option>
|
|
153
|
-
</select>
|
|
154
|
-
)}
|
|
155
|
-
<button
|
|
156
|
-
onClick={() => setIsLoading(true)}
|
|
157
|
-
className="px-3 py-1 bg-blue-500 text-white rounded text-sm"
|
|
158
|
-
>
|
|
159
|
-
Reload
|
|
160
|
-
</button>
|
|
161
|
-
</div>
|
|
162
|
-
);
|
|
163
|
-
},
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
export const GridLayout: Story = {
|
|
167
|
-
render: () => (
|
|
168
|
-
<div className="grid grid-cols-2 gap-4 w-96">
|
|
169
|
-
<div>
|
|
170
|
-
<div className="h-4 bg-gray-200 rounded w-3/4 mb-2 animate-pulse"></div>
|
|
171
|
-
|
|
172
|
-
<SelectSkeleton />
|
|
173
|
-
</div>
|
|
174
|
-
|
|
175
|
-
<div>
|
|
176
|
-
<div className="h-4 bg-gray-200 rounded w-2/3 mb-2 animate-pulse"></div>
|
|
177
|
-
|
|
178
|
-
<SelectSkeleton />
|
|
179
|
-
</div>
|
|
180
|
-
|
|
181
|
-
<div>
|
|
182
|
-
<div className="h-4 bg-gray-200 rounded w-1/2 mb-2 animate-pulse"></div>
|
|
183
|
-
|
|
184
|
-
<SelectSkeleton />
|
|
185
|
-
</div>
|
|
186
|
-
|
|
187
|
-
<div>
|
|
188
|
-
<div className="h-4 bg-gray-200 rounded w-5/6 mb-2 animate-pulse"></div>
|
|
189
|
-
|
|
190
|
-
<SelectSkeleton />
|
|
191
|
-
</div>
|
|
192
|
-
</div>
|
|
193
|
-
),
|
|
194
|
-
};
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { SelectSkeleton } from './SelectSkeleton';
|
|
2
|
-
import { render, screen } from '../../test/renderers';
|
|
3
|
-
|
|
4
|
-
const LOADING_OPTIONS_LABEL = 'Loading options';
|
|
5
|
-
|
|
6
|
-
describe('SelectSkeleton', () => {
|
|
7
|
-
it('should render with default props', () => {
|
|
8
|
-
render(<SelectSkeleton />);
|
|
9
|
-
|
|
10
|
-
const skeleton = screen.getByLabelText(LOADING_OPTIONS_LABEL);
|
|
11
|
-
|
|
12
|
-
expect(skeleton).toBeInTheDocument();
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it('should have correct CSS classes for skeleton styling', () => {
|
|
16
|
-
const { container } = render(<SelectSkeleton />);
|
|
17
|
-
|
|
18
|
-
const skeletonContainer = container.firstChild as HTMLElement;
|
|
19
|
-
|
|
20
|
-
// Just verify it's a div element - we can't easily test the exact Tailwind classes from SELECT_CONTAINER_CLASSES
|
|
21
|
-
expect(skeletonContainer.tagName).toBe('DIV');
|
|
22
|
-
|
|
23
|
-
const skeletonElement = screen.getByLabelText(LOADING_OPTIONS_LABEL);
|
|
24
|
-
|
|
25
|
-
expect(skeletonElement).toHaveClass(
|
|
26
|
-
'w-full',
|
|
27
|
-
'h-full',
|
|
28
|
-
'bg-gray-100',
|
|
29
|
-
'animate-pulse',
|
|
30
|
-
'col-span-2',
|
|
31
|
-
);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it('should have proper accessibility attributes', () => {
|
|
35
|
-
render(<SelectSkeleton />);
|
|
36
|
-
|
|
37
|
-
const skeleton = screen.getByLabelText(LOADING_OPTIONS_LABEL);
|
|
38
|
-
|
|
39
|
-
expect(skeleton).toHaveAttribute('aria-label', LOADING_OPTIONS_LABEL);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('should render skeleton with correct structure', () => {
|
|
43
|
-
const { container } = render(<SelectSkeleton />);
|
|
44
|
-
|
|
45
|
-
// Should have container div
|
|
46
|
-
const containerDiv = container.firstChild;
|
|
47
|
-
|
|
48
|
-
expect(containerDiv).toBeInTheDocument();
|
|
49
|
-
|
|
50
|
-
// Should have control div inside container
|
|
51
|
-
const controlDiv = containerDiv?.firstChild;
|
|
52
|
-
|
|
53
|
-
expect(controlDiv).toBeInTheDocument();
|
|
54
|
-
|
|
55
|
-
// Should have skeleton div inside control
|
|
56
|
-
const skeletonDiv = controlDiv?.firstChild;
|
|
57
|
-
|
|
58
|
-
expect(skeletonDiv).toBeInTheDocument();
|
|
59
|
-
expect(skeletonDiv).toHaveAttribute('aria-label', LOADING_OPTIONS_LABEL);
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it('should apply SELECT_CONTAINER_CLASSES to container', () => {
|
|
63
|
-
const { container } = render(<SelectSkeleton />);
|
|
64
|
-
|
|
65
|
-
const containerElement = container.firstChild as HTMLElement;
|
|
66
|
-
|
|
67
|
-
// Since we can't easily test the exact classes from common.ts,
|
|
68
|
-
// we test that it's a div with some expected structure
|
|
69
|
-
expect(containerElement.tagName).toBe('DIV');
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it('should apply SELECT_CONTROL_CLASSES to control element', () => {
|
|
73
|
-
const { container } = render(<SelectSkeleton />);
|
|
74
|
-
|
|
75
|
-
const controlElement = container.firstChild?.firstChild as HTMLElement;
|
|
76
|
-
|
|
77
|
-
expect(controlElement.tagName).toBe('DIV');
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it('should be visually distinguishable as a loading state', () => {
|
|
81
|
-
render(<SelectSkeleton />);
|
|
82
|
-
|
|
83
|
-
const skeleton = screen.getByLabelText(LOADING_OPTIONS_LABEL);
|
|
84
|
-
|
|
85
|
-
// Should have animation class for loading indication
|
|
86
|
-
expect(skeleton).toHaveClass('animate-pulse');
|
|
87
|
-
|
|
88
|
-
// Should have background color for visual feedback
|
|
89
|
-
expect(skeleton).toHaveClass('bg-gray-100');
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it('should maintain consistent dimensions with Select component', () => {
|
|
93
|
-
const { container } = render(<SelectSkeleton />);
|
|
94
|
-
|
|
95
|
-
const skeleton = screen.getByLabelText(LOADING_OPTIONS_LABEL);
|
|
96
|
-
|
|
97
|
-
// Should fill available space
|
|
98
|
-
expect(skeleton).toHaveClass('w-full', 'h-full');
|
|
99
|
-
|
|
100
|
-
// Container should have proper structure
|
|
101
|
-
expect(container.firstChild).toBeInTheDocument();
|
|
102
|
-
expect(container.firstChild?.firstChild).toBeInTheDocument();
|
|
103
|
-
});
|
|
104
|
-
});
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { SELECT_CONTAINER_CLASSES, SELECT_CONTROL_CLASSES } from './common';
|
|
2
|
-
import type { ExtendProps } from '../../types';
|
|
3
|
-
import { cn } from '../../utils';
|
|
4
|
-
|
|
5
|
-
type Props = {
|
|
6
|
-
/** Explicitly disallow children as we hard-code the skeleton content */
|
|
7
|
-
children?: never;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export type SelectSkeletonProps = ExtendProps<'div', Props>;
|
|
11
|
-
|
|
12
|
-
export const SelectSkeleton = ({ className, ...props }: SelectSkeletonProps = {}) => {
|
|
13
|
-
return (
|
|
14
|
-
<div className={cn(SELECT_CONTAINER_CLASSES, className)} {...props}>
|
|
15
|
-
<div className={cn(SELECT_CONTROL_CLASSES, 'p-2')}>
|
|
16
|
-
<div
|
|
17
|
-
className="w-full h-full bg-gray-100 animate-pulse col-span-2"
|
|
18
|
-
aria-label="Loading options"
|
|
19
|
-
></div>
|
|
20
|
-
</div>
|
|
21
|
-
</div>
|
|
22
|
-
);
|
|
23
|
-
};
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
// Select components with react-select dependency
|
|
2
|
-
export { Select } from './Select';
|
|
3
|
-
export { SelectSkeleton } from './SelectSkeleton';
|
|
4
|
-
|
|
5
|
-
// Export types
|
|
6
|
-
export type { SelectProps } from './Select';
|
|
7
|
-
export type { SelectSkeletonProps } from './SelectSkeleton';
|
|
8
|
-
|
|
9
|
-
// Re-export useful types from react-select for convenience
|
|
10
|
-
export type {
|
|
11
|
-
Props as ReactSelectProps,
|
|
12
|
-
GroupBase,
|
|
13
|
-
OptionsOrGroups,
|
|
14
|
-
SingleValue,
|
|
15
|
-
MultiValue,
|
|
16
|
-
ActionMeta,
|
|
17
|
-
OnChangeValue,
|
|
18
|
-
} from 'react-select';
|
|
@@ -1,346 +0,0 @@
|
|
|
1
|
-
/* eslint-disable jsx-a11y/anchor-is-valid */
|
|
2
|
-
|
|
3
|
-
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
4
|
-
|
|
5
|
-
import { SkipLink } from './SkipLink';
|
|
6
|
-
|
|
7
|
-
const meta = {
|
|
8
|
-
title: 'Components/SkipLink',
|
|
9
|
-
component: SkipLink,
|
|
10
|
-
parameters: {
|
|
11
|
-
layout: 'fullscreen',
|
|
12
|
-
docs: {
|
|
13
|
-
description: {
|
|
14
|
-
component:
|
|
15
|
-
'A skip link component that allows users to jump to the main content, improving accessibility for keyboard and screen reader users.',
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
tags: ['autodocs'],
|
|
20
|
-
argTypes: {
|
|
21
|
-
mainContentId: {
|
|
22
|
-
control: 'text',
|
|
23
|
-
description: 'The ID of the main content element to skip to',
|
|
24
|
-
defaultValue: 'main-content',
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
} satisfies Meta<typeof SkipLink>;
|
|
28
|
-
|
|
29
|
-
export default meta;
|
|
30
|
-
type Story = StoryObj<typeof meta>;
|
|
31
|
-
|
|
32
|
-
export const Default: Story = {
|
|
33
|
-
parameters: {
|
|
34
|
-
docs: {
|
|
35
|
-
description: {
|
|
36
|
-
story: 'Default skip link with the standard main content ID.',
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
},
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export const CustomTarget: Story = {
|
|
43
|
-
args: {
|
|
44
|
-
mainContentId: 'custom-main',
|
|
45
|
-
},
|
|
46
|
-
parameters: {
|
|
47
|
-
docs: {
|
|
48
|
-
description: {
|
|
49
|
-
story: 'Skip link with a custom target ID.',
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
export const WithMainContent: Story = {
|
|
56
|
-
render: (args) => (
|
|
57
|
-
<div className="min-h-screen">
|
|
58
|
-
<SkipLink {...args} />
|
|
59
|
-
|
|
60
|
-
<header className="bg-blue-600 text-white p-4">
|
|
61
|
-
<nav>
|
|
62
|
-
<ul className="flex space-x-4">
|
|
63
|
-
<li>
|
|
64
|
-
<a href="#" className="hover:underline">
|
|
65
|
-
Home
|
|
66
|
-
</a>
|
|
67
|
-
</li>
|
|
68
|
-
|
|
69
|
-
<li>
|
|
70
|
-
<a href="#" className="hover:underline">
|
|
71
|
-
About
|
|
72
|
-
</a>
|
|
73
|
-
</li>
|
|
74
|
-
|
|
75
|
-
<li>
|
|
76
|
-
<a href="#" className="hover:underline">
|
|
77
|
-
Services
|
|
78
|
-
</a>
|
|
79
|
-
</li>
|
|
80
|
-
|
|
81
|
-
<li>
|
|
82
|
-
<a href="#" className="hover:underline">
|
|
83
|
-
Contact
|
|
84
|
-
</a>
|
|
85
|
-
</li>
|
|
86
|
-
</ul>
|
|
87
|
-
</nav>
|
|
88
|
-
</header>
|
|
89
|
-
|
|
90
|
-
<main id="main-content" className="p-8">
|
|
91
|
-
<h1 className="text-3xl font-bold mb-6">Main Content</h1>
|
|
92
|
-
|
|
93
|
-
<p className="mb-4">
|
|
94
|
-
This is the main content area. Use Tab key to navigate to the skip link at the top, then
|
|
95
|
-
press Enter to jump directly here.
|
|
96
|
-
</p>
|
|
97
|
-
|
|
98
|
-
<p className="mb-4">
|
|
99
|
-
The skip link is invisible by default but becomes visible when focused, providing an
|
|
100
|
-
accessible way for keyboard users to bypass navigation.
|
|
101
|
-
</p>
|
|
102
|
-
|
|
103
|
-
<div className="space-y-4">
|
|
104
|
-
<p>Sample content paragraph 1.</p>
|
|
105
|
-
|
|
106
|
-
<p>Sample content paragraph 2.</p>
|
|
107
|
-
|
|
108
|
-
<p>Sample content paragraph 3.</p>
|
|
109
|
-
</div>
|
|
110
|
-
</main>
|
|
111
|
-
|
|
112
|
-
<footer className="bg-gray-800 text-white p-4 mt-8">
|
|
113
|
-
<p>© 2024 Example Site. All rights reserved.</p>
|
|
114
|
-
</footer>
|
|
115
|
-
</div>
|
|
116
|
-
),
|
|
117
|
-
parameters: {
|
|
118
|
-
docs: {
|
|
119
|
-
description: {
|
|
120
|
-
story:
|
|
121
|
-
'Complete page layout showing how the skip link works in context. Use Tab to focus the skip link, then Enter to jump to main content.',
|
|
122
|
-
},
|
|
123
|
-
},
|
|
124
|
-
},
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
export const CustomTargetWithContent: Story = {
|
|
128
|
-
args: {
|
|
129
|
-
mainContentId: 'article-content',
|
|
130
|
-
},
|
|
131
|
-
render: (args) => (
|
|
132
|
-
<div className="min-h-screen">
|
|
133
|
-
<SkipLink {...args} />
|
|
134
|
-
|
|
135
|
-
<header className="bg-green-600 text-white p-4">
|
|
136
|
-
<h1 className="text-xl font-bold">Site Header</h1>
|
|
137
|
-
</header>
|
|
138
|
-
|
|
139
|
-
<nav className="bg-gray-200 p-4">
|
|
140
|
-
<ul className="flex space-x-4">
|
|
141
|
-
<li>
|
|
142
|
-
<a href="#" className="text-blue-600 hover:underline">
|
|
143
|
-
Navigation Link 1
|
|
144
|
-
</a>
|
|
145
|
-
</li>
|
|
146
|
-
|
|
147
|
-
<li>
|
|
148
|
-
<a href="#" className="text-blue-600 hover:underline">
|
|
149
|
-
Navigation Link 2
|
|
150
|
-
</a>
|
|
151
|
-
</li>
|
|
152
|
-
|
|
153
|
-
<li>
|
|
154
|
-
<a href="#" className="text-blue-600 hover:underline">
|
|
155
|
-
Navigation Link 3
|
|
156
|
-
</a>
|
|
157
|
-
</li>
|
|
158
|
-
</ul>
|
|
159
|
-
</nav>
|
|
160
|
-
|
|
161
|
-
<aside className="bg-yellow-100 p-4">
|
|
162
|
-
<h2 className="font-bold mb-2">Sidebar</h2>
|
|
163
|
-
|
|
164
|
-
<p>Some sidebar content that users might want to skip.</p>
|
|
165
|
-
</aside>
|
|
166
|
-
|
|
167
|
-
<article id="article-content" className="p-8 bg-white">
|
|
168
|
-
<h1 className="text-3xl font-bold mb-6">Article Title</h1>
|
|
169
|
-
|
|
170
|
-
<p className="mb-4">
|
|
171
|
-
This skip link targets a custom ID "article-content" instead of the default
|
|
172
|
-
"main-content".
|
|
173
|
-
</p>
|
|
174
|
-
|
|
175
|
-
<p className="mb-4">
|
|
176
|
-
This demonstrates how the component can be configured for different page layouts and
|
|
177
|
-
content structures.
|
|
178
|
-
</p>
|
|
179
|
-
</article>
|
|
180
|
-
</div>
|
|
181
|
-
),
|
|
182
|
-
parameters: {
|
|
183
|
-
docs: {
|
|
184
|
-
description: {
|
|
185
|
-
story:
|
|
186
|
-
'Skip link with custom target ID, demonstrating flexibility for different page structures.',
|
|
187
|
-
},
|
|
188
|
-
},
|
|
189
|
-
},
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
export const FocusedState: Story = {
|
|
193
|
-
args: {
|
|
194
|
-
mainContentId: 'article-content-focused',
|
|
195
|
-
},
|
|
196
|
-
render: (args) => (
|
|
197
|
-
<div className="min-h-screen relative">
|
|
198
|
-
<style>
|
|
199
|
-
{`
|
|
200
|
-
.skip-link {
|
|
201
|
-
position: relative !important;
|
|
202
|
-
top: 0 !important;
|
|
203
|
-
display: block !important;
|
|
204
|
-
}
|
|
205
|
-
`}
|
|
206
|
-
</style>
|
|
207
|
-
|
|
208
|
-
<SkipLink {...args} />
|
|
209
|
-
|
|
210
|
-
<div className="p-8">
|
|
211
|
-
<h1 className="text-2xl font-bold mb-4">Skip Link in Focused State</h1>
|
|
212
|
-
|
|
213
|
-
<p className="mb-4">
|
|
214
|
-
This story shows how the skip link appears when focused. Normally it's hidden
|
|
215
|
-
off-screen until a user tabs to it.
|
|
216
|
-
</p>
|
|
217
|
-
|
|
218
|
-
<main id="main-content-focused" className="mt-8 p-4 border-2 border-dashed border-gray-400">
|
|
219
|
-
<h2 className="text-xl font-bold mb-2">Main Content Target</h2>
|
|
220
|
-
|
|
221
|
-
<p>This is where users will land when they activate the skip link.</p>
|
|
222
|
-
</main>
|
|
223
|
-
</div>
|
|
224
|
-
</div>
|
|
225
|
-
),
|
|
226
|
-
parameters: {
|
|
227
|
-
docs: {
|
|
228
|
-
description: {
|
|
229
|
-
story:
|
|
230
|
-
'Shows the visual appearance of the skip link when focused (normally hidden off-screen).',
|
|
231
|
-
},
|
|
232
|
-
},
|
|
233
|
-
},
|
|
234
|
-
};
|
|
235
|
-
|
|
236
|
-
export const AccessibilityTest: Story = {
|
|
237
|
-
args: {
|
|
238
|
-
mainContentId: 'article-content-accessibility',
|
|
239
|
-
},
|
|
240
|
-
render: (args) => (
|
|
241
|
-
<div className="min-h-screen">
|
|
242
|
-
<SkipLink {...args} />
|
|
243
|
-
|
|
244
|
-
<div className="p-8">
|
|
245
|
-
<h1 className="text-2xl font-bold mb-6">Accessibility Testing</h1>
|
|
246
|
-
|
|
247
|
-
<div className="bg-blue-50 border border-blue-200 rounded p-4 mb-6">
|
|
248
|
-
<h2 className="font-bold text-blue-800 mb-2">Testing Instructions:</h2>
|
|
249
|
-
|
|
250
|
-
<ol className="list-decimal list-inside space-y-1 text-blue-700">
|
|
251
|
-
<li>Use Tab key to navigate to the skip link (it will appear at the top)</li>
|
|
252
|
-
|
|
253
|
-
<li>Press Enter or Space to activate the skip link</li>
|
|
254
|
-
|
|
255
|
-
<li>Verify that focus moves to the main content below</li>
|
|
256
|
-
|
|
257
|
-
<li>Test with screen reader for proper announcement</li>
|
|
258
|
-
</ol>
|
|
259
|
-
</div>
|
|
260
|
-
|
|
261
|
-
<nav className="mb-8">
|
|
262
|
-
<h2 className="text-lg font-semibold mb-3">Navigation Menu</h2>
|
|
263
|
-
|
|
264
|
-
<ul className="space-y-2">
|
|
265
|
-
<li>
|
|
266
|
-
<a
|
|
267
|
-
href="#"
|
|
268
|
-
className="text-blue-600 hover:underline focus:outline-2 focus:outline-blue-500"
|
|
269
|
-
>
|
|
270
|
-
Link 1
|
|
271
|
-
</a>
|
|
272
|
-
</li>
|
|
273
|
-
|
|
274
|
-
<li>
|
|
275
|
-
<a
|
|
276
|
-
href="#"
|
|
277
|
-
className="text-blue-600 hover:underline focus:outline-2 focus:outline-blue-500"
|
|
278
|
-
>
|
|
279
|
-
Link 2
|
|
280
|
-
</a>
|
|
281
|
-
</li>
|
|
282
|
-
|
|
283
|
-
<li>
|
|
284
|
-
<a
|
|
285
|
-
href="#"
|
|
286
|
-
className="text-blue-600 hover:underline focus:outline-2 focus:outline-blue-500"
|
|
287
|
-
>
|
|
288
|
-
Link 3
|
|
289
|
-
</a>
|
|
290
|
-
</li>
|
|
291
|
-
|
|
292
|
-
<li>
|
|
293
|
-
<a
|
|
294
|
-
href="#"
|
|
295
|
-
className="text-blue-600 hover:underline focus:outline-2 focus:outline-blue-500"
|
|
296
|
-
>
|
|
297
|
-
Link 4
|
|
298
|
-
</a>
|
|
299
|
-
</li>
|
|
300
|
-
|
|
301
|
-
<li>
|
|
302
|
-
<a
|
|
303
|
-
href="#"
|
|
304
|
-
className="text-blue-600 hover:underline focus:outline-2 focus:outline-blue-500"
|
|
305
|
-
>
|
|
306
|
-
Link 5
|
|
307
|
-
</a>
|
|
308
|
-
</li>
|
|
309
|
-
</ul>
|
|
310
|
-
</nav>
|
|
311
|
-
|
|
312
|
-
<main
|
|
313
|
-
id="main-content-accessibility"
|
|
314
|
-
className="p-6 bg-green-50 border border-green-200 rounded"
|
|
315
|
-
>
|
|
316
|
-
<h2 className="text-xl font-bold mb-4 text-green-800">Main Content Area</h2>
|
|
317
|
-
|
|
318
|
-
<p className="mb-4">
|
|
319
|
-
If the skip link worked correctly, focus should now be on this main content area,
|
|
320
|
-
bypassing all the navigation links above.
|
|
321
|
-
</p>
|
|
322
|
-
|
|
323
|
-
<p className="mb-4">
|
|
324
|
-
This is particularly important for users who rely on keyboard navigation or screen
|
|
325
|
-
readers, as it saves them from having to tab through all navigation elements on every
|
|
326
|
-
page.
|
|
327
|
-
</p>
|
|
328
|
-
|
|
329
|
-
<button
|
|
330
|
-
className="bg-green-600 text-white px-4 py-2 rounded hover:bg-green-700 focus:outline-2
|
|
331
|
-
focus:outline-green-500"
|
|
332
|
-
>
|
|
333
|
-
Interactive Element
|
|
334
|
-
</button>
|
|
335
|
-
</main>
|
|
336
|
-
</div>
|
|
337
|
-
</div>
|
|
338
|
-
),
|
|
339
|
-
parameters: {
|
|
340
|
-
docs: {
|
|
341
|
-
description: {
|
|
342
|
-
story: 'Complete accessibility testing scenario with instructions for manual testing.',
|
|
343
|
-
},
|
|
344
|
-
},
|
|
345
|
-
},
|
|
346
|
-
};
|