aural-ui 3.0.7 → 4.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/dist/components/aspect-ratio/AspectRatio.stories.tsx +290 -1199
- package/dist/components/avatar/Avatar.stories.tsx +235 -237
- package/dist/components/badge/Badge.stories.tsx +379 -116
- package/dist/components/banner/Banner.stories.tsx +445 -391
- package/dist/components/breadcrumb/Breadcrumb.stories.tsx +453 -199
- package/dist/components/button/Button.stories.tsx +585 -230
- package/dist/components/button/index.tsx +7 -7
- package/dist/components/card/Card.stories.tsx +619 -301
- package/dist/components/char-count/CharCount.stories.tsx +350 -248
- package/dist/components/checkbox/Checkbox.stories.tsx +309 -167
- package/dist/components/chip/Chip.stories.tsx +362 -168
- package/dist/components/circular-loader/CircularLoader.stories.tsx +221 -620
- package/dist/components/clamp-lines/ClampLines.stories.tsx +246 -117
- package/dist/components/collapsible/Collapsible.stories.tsx +391 -252
- package/dist/components/command/Command.stories.tsx +533 -856
- package/dist/components/dialog/Dialog.stories.tsx +505 -949
- package/dist/components/divider/Divider.stories.tsx +265 -502
- package/dist/components/dot-loader/DotLoader.stories.tsx +256 -257
- package/dist/components/drawer/Drawer.stories.tsx +659 -993
- package/dist/components/drawer/index.tsx +3 -3
- package/dist/components/dropdown/Dropdown.stories.tsx +643 -1018
- package/dist/components/form/Form.stories.tsx +560 -274
- package/dist/components/helper-text/HelperText.stories.tsx +199 -200
- package/dist/components/hover-card/HoverCard.stories.tsx +318 -1221
- package/dist/components/icon-button/IconButton.stories.tsx +837 -194
- package/dist/components/if-else/if-else.stories.tsx +370 -83
- package/dist/components/input/Input.stories.tsx +436 -368
- package/dist/components/label/Label.stories.tsx +156 -154
- package/dist/components/list/List.stories.tsx +485 -822
- package/dist/components/marquee/Marquee.stories.tsx +356 -694
- package/dist/components/otp-inputs/OtpInputs.stories.tsx +352 -410
- package/dist/components/overlay/Overlay.stories.tsx +452 -818
- package/dist/components/overlay/index.tsx +4 -4
- package/dist/components/pagination/Pagination.stories.tsx +721 -210
- package/dist/components/popover/Popover.stories.tsx +484 -873
- package/dist/components/radio/Radio.stories.tsx +432 -124
- package/dist/components/resizable/Resizable.stories.tsx +496 -752
- package/dist/components/scroll-area/ScrollArea.stories.tsx +384 -1006
- package/dist/components/search/Search.stories.tsx +314 -575
- package/dist/components/select/Select.stories.tsx +684 -787
- package/dist/components/sheet/Sheet.stories.tsx +671 -936
- package/dist/components/skelton/Skelton.stories.tsx +230 -764
- package/dist/components/slider/Slider.stories.tsx +384 -737
- package/dist/components/stepper/Stepper.stories.tsx +371 -514
- package/dist/components/switch/Switch.stories.tsx +461 -208
- package/dist/components/switch-case/SwitchCase.stories.tsx +367 -188
- package/dist/components/table/Table.stories.tsx +770 -914
- package/dist/components/tabs/Tabs.stories.tsx +459 -1400
- package/dist/components/tag/Tag.stories.tsx +714 -542
- package/dist/components/textarea/TextArea.stories.tsx +621 -562
- package/dist/components/thumbnail-tags/ThumbnailTags.stories.tsx +228 -148
- package/dist/components/toast/Toast.stories.tsx +452 -1333
- package/dist/components/toggle/Toggle.stories.tsx +488 -909
- package/dist/components/tooltip/Tooltip.stories.tsx +344 -1372
- package/dist/components/typography/Typography.stories.tsx +406 -89
- package/dist/hooks/use-change-state/UseChangeState.stories.tsx +309 -606
- package/dist/hooks/use-previous/UsePrevious.stories.tsx +367 -917
- package/dist/hooks/use-standalone-pagination/UseStandalonePagination.stories.tsx +639 -867
- package/dist/icons/Icons.stories.tsx +0 -12
- package/dist/icons/ai-avatar-icon/AiAvatarIcon.stories.tsx +226 -1013
- package/dist/icons/alert-icon/AlertIcon.stories.tsx +109 -929
- package/dist/icons/all-icons.tsx +124 -87
- package/dist/icons/angle-down-icon/AngleDownIcon.stories.tsx +140 -971
- package/dist/icons/apple-logo-icon/AppleLogoIcon.stories.tsx +148 -888
- package/dist/icons/arrow-box-left-icon/ArrowBoxLeftIcon.stories.tsx +135 -1019
- package/dist/icons/arrow-corner-up-left-icon/ArrowCornerUpLeftIcon.stories.tsx +137 -953
- package/dist/icons/arrow-corner-up-right-icon/ArrowCornerUpRightIcon.stories.tsx +138 -997
- package/dist/icons/arrow-left-icon/ArrowLeftIcon.stories.tsx +136 -942
- package/dist/icons/arrow-right-icon/ArrowRightIcon.stories.tsx +148 -1092
- package/dist/icons/arrow-right-up-icon/ArrowRightUpIcon.stories.tsx +146 -1211
- package/dist/icons/art-board-icon/ArtBoardIcon.stories.tsx +126 -615
- package/dist/icons/audio-bar-icon/AudioBarIcon.stories.tsx +144 -1164
- package/dist/icons/backward-ten-seconds-icon/BackwardTenSecondsIcon.stories.tsx +167 -985
- package/dist/icons/bubble-check-icon/BubbleCheckIcon.stories.tsx +122 -1179
- package/dist/icons/bubble-crossed-icon/BubbleCrossedIcon.stories.tsx +124 -1168
- package/dist/icons/bubble-sparkle-icon/BubbleSparkleIcon.stories.tsx +119 -850
- package/dist/icons/camera-icon/CameraIcon.stories.tsx +112 -1213
- package/dist/icons/capital-a-letter-icon/CapitalALetterIcon.stories.tsx +117 -934
- package/dist/icons/chevron-double-left-icon/ChevronDoubleLeftIcon.stories.tsx +160 -961
- package/dist/icons/chevron-double-right-icon/ChevronDoubleRightIcon.stories.tsx +163 -961
- package/dist/icons/chevron-down-icon/ChevronDownIcon.stories.tsx +144 -942
- package/dist/icons/chevron-left-icon/ChevronLeftIcon.stories.tsx +129 -966
- package/dist/icons/chevron-right-icon/ChevronRightIcon.stories.tsx +147 -964
- package/dist/icons/chevron-up-icon/ChevronUpIcon.stories.tsx +145 -975
- package/dist/icons/circle-tick-icon/CircleTickIcon.stories.tsx +150 -1142
- package/dist/icons/circular-play-icon/CircularPlayIcon.stories.tsx +114 -461
- package/dist/icons/coin-icon/CoinIcon.stories.tsx +124 -1322
- package/dist/icons/coin-toons-icon/CoinToonsIcon.stories.tsx +117 -1318
- package/dist/icons/column-wide-add-icon/ColumnWideAddIcon.stories.tsx +114 -903
- package/dist/icons/command-icon/CommandIcon.stories.tsx +127 -1042
- package/dist/icons/copy-icon/CopyIcon.stories.tsx +123 -962
- package/dist/icons/cross-circle-icon/CrossCircleIcon.stories.tsx +147 -999
- package/dist/icons/cross-icon/CrossIcon.stories.tsx +139 -960
- package/dist/icons/download-icon/DownloadIcon.stories.tsx +126 -820
- package/dist/icons/edit-big-icon/EditBigIcon.stories.tsx +124 -1031
- package/dist/icons/email-icon/EmailIcon.stories.tsx +115 -936
- package/dist/icons/expand-icon/ExpandIcon.stories.tsx +112 -1111
- package/dist/icons/eye-close-icon/EyeCloseIcon.stories.tsx +144 -1025
- package/dist/icons/eye-open-icon/EyeOpenIcon.stories.tsx +143 -1036
- package/dist/icons/feature-shine-icon/FeatureShineIcon.stories.tsx +127 -1011
- package/dist/icons/file-chart-icon/FileChartIcon.stories.tsx +126 -1056
- package/dist/icons/file-text-icon/FileTextIcon.stories.tsx +125 -614
- package/dist/icons/filter-bar-row-icon/FilterBarRowIcon.stories.tsx +119 -1050
- package/dist/icons/forward-ten-seconds-icon/ForwardTenSecondsIcon.stories.tsx +169 -989
- package/dist/icons/git-branch-icon/GitBranchIcon.stories.tsx +115 -1145
- package/dist/icons/git-fork-icon/GitForkIcon.stories.tsx +115 -1122
- package/dist/icons/globe-icon/GlobeIcon.stories.tsx +130 -313
- package/dist/icons/google-logo-icon/GoogleLogoIcon.stories.tsx +145 -940
- package/dist/icons/grip-vertical-icon/GripVerticalIcon.stories.tsx +119 -1174
- package/dist/icons/head-icon/HeadIcon.stories.tsx +111 -916
- package/dist/icons/heart-icon/HeartIcon.stories.tsx +120 -1019
- package/dist/icons/image-avatar-sparkle-icon/ImageAvatarSparkleIcon.stories.tsx +119 -683
- package/dist/icons/image-icon/ImageIcon.stories.tsx +105 -1121
- package/dist/icons/import-folder-icon/ImportFolderIcon.stories.tsx +111 -1192
- package/dist/icons/import-left-arrow-folder-icon/ImportLeftArrowFolderIcon.stories.tsx +136 -1256
- package/dist/icons/indian-flag-icon/IndianFlagIcon.stories.tsx +159 -962
- package/dist/icons/instagram-icon/InstagramIcon.stories.tsx +161 -1385
- package/dist/icons/layout-column-icon/LayoutColumnIcon.stories.tsx +124 -972
- package/dist/icons/layout-left-icon/LayoutLeftIcon.stories.tsx +119 -948
- package/dist/icons/layout-right-icon/LayoutRightIcon.stories.tsx +119 -942
- package/dist/icons/light-bulb-simple-icon/LightBulbSimpleIcon.stories.tsx +108 -1215
- package/dist/icons/linked-in-icon/LinkedInIcon.stories.tsx +154 -1517
- package/dist/icons/magic-book-icon/MagicBookIcon.stories.tsx +110 -1188
- package/dist/icons/magic-edit-icon/MagicEditIcon.stories.tsx +119 -678
- package/dist/icons/maintenance-icon/MaintenanceIcon.stories.tsx +123 -1184
- package/dist/icons/message-icon/MessageIcon.stories.tsx +114 -538
- package/dist/icons/minimize-icon/MinimizeIcon.stories.tsx +116 -1158
- package/dist/icons/moon-icon/MoonIcon.stories.tsx +120 -536
- package/dist/icons/move-horizontal-icon/MoveHorizontalIcon.stories.tsx +109 -1184
- package/dist/icons/move-vertical-icon/MoveVerticalIcon.stories.tsx +115 -1134
- package/dist/icons/musical-note-icon/MusicalNoteIcon.stories.tsx +119 -971
- package/dist/icons/notepad-icon/NotepadIcon.stories.tsx +111 -1100
- package/dist/icons/notes-icon/NotesIcon.stories.tsx +119 -1101
- package/dist/icons/page-search-icon/PageSearchIcon.stories.tsx +109 -1111
- package/dist/icons/page-text-icon/PageTextIcon.stories.tsx +122 -684
- package/dist/icons/paint-roll-icon/PaintRollIcon.stories.tsx +113 -954
- package/dist/icons/paper-plane-icon/PaperPlaneIcon.stories.tsx +112 -877
- package/dist/icons/pause-icon/PauseIcon.stories.tsx +113 -1000
- package/dist/icons/pencil-icon/PencilIcon.stories.tsx +115 -1070
- package/dist/icons/phone-icon/PhoneIcon.stories.tsx +115 -978
- package/dist/icons/plus-icon/PlusIcon.stories.tsx +106 -1093
- package/dist/icons/pocket-studio-icon/PocketStudioIcon.stories.tsx +107 -829
- package/dist/icons/scroll-down-icon/ScrollDownIcon.stories.tsx +102 -469
- package/dist/icons/search-icon/SearchIcon.stories.tsx +111 -1124
- package/dist/icons/setting-icon/SettingIcon.stories.tsx +107 -970
- package/dist/icons/share-icon/ShareIcon.stories.tsx +120 -1025
- package/dist/icons/shield-icon/ShieldIcon.stories.tsx +117 -931
- package/dist/icons/site-logo-icon/SiteLogoIcon.stories.tsx +137 -1104
- package/dist/icons/skip-backward-icon/SkipBackwardIcon.stories.tsx +172 -982
- package/dist/icons/skip-forward-icon/SkipForwardIcon.stories.tsx +164 -983
- package/dist/icons/sparkles-soft-icon/SparklesSoftIcon.stories.tsx +105 -958
- package/dist/icons/spinner-gradient-icon/SpinnerGradientIcon.stories.tsx +158 -580
- package/dist/icons/spinner-gradient-icon/index.tsx +6 -1
- package/dist/icons/spinner-solid-icon/SpinnerSolidIcon.stories.tsx +158 -587
- package/dist/icons/spinner-solid-icon/index.tsx +6 -1
- package/dist/icons/spinner-solid-neutral-icon/SpinnerSolidINeutralcon.stories.tsx +146 -682
- package/dist/icons/spinner-solid-neutral-icon/index.tsx +1 -1
- package/dist/icons/star-icon/StarIcon.stories.tsx +124 -904
- package/dist/icons/store-coin-icon/StoreCoinIcon.stories.tsx +112 -964
- package/dist/icons/suggestion-icon/SuggestionIcon.stories.tsx +116 -852
- package/dist/icons/sun-icon/SunIcon.stories.tsx +120 -831
- package/dist/icons/text-color-icon/TextColorIcon.stories.tsx +116 -950
- package/dist/icons/text-indicator-icon/TextIndicatorIcon.stories.tsx +123 -980
- package/dist/icons/threads-icon/ThreadsIcon.stories.tsx +156 -1427
- package/dist/icons/tick-circle-icon/TickCircleIcon.stories.tsx +146 -1142
- package/dist/icons/tick-icon/TickIcon.stories.tsx +145 -1276
- package/dist/icons/trash-icon/TrashIcon.stories.tsx +108 -933
- package/dist/icons/twitter-x-icon/TwitterXIcon.stories.tsx +157 -1402
- package/dist/icons/upload-icon/UploadIcon.stories.tsx +115 -889
- package/dist/icons/vertical-menu-icon/VerticalMenuIcon.stories.tsx +118 -984
- package/dist/icons/video-play-list-icon/VideoPlaylistIcon.stories.tsx +125 -1049
- package/dist/icons/voice-playing-icon/VoicePlayingIcon.stories.tsx +123 -1356
- package/dist/icons/volume-full-icon/VolumeFullIcon.stories.tsx +110 -1171
- package/dist/icons/volume-half-icon/VolumeHalfIcon.stories.tsx +112 -1093
- package/dist/icons/volume-off-icon/VolumeOffIcon.stories.tsx +115 -1087
- package/dist/icons/warning-icon/WarningIcon.stories.tsx +122 -1046
- package/dist/icons/youtube-icon/YoutubeIcon.stories.tsx +161 -936
- package/dist/index.cjs +84 -84
- package/dist/index.js +84 -84
- package/dist/styles/aural-all-theme.css +1222 -0
- package/dist/styles/{aural-theme.css → aural-dark-theme.css} +15 -3
- package/dist/styles/aural-light-theme.css +1047 -0
- package/package.json +1 -1
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from "react"
|
|
2
2
|
import { Button } from "@components/button"
|
|
3
3
|
import type { Meta, StoryObj } from "@storybook/react-vite"
|
|
4
4
|
|
|
5
|
+
import { AuralComponentDocsPage } from "src/ui/story-spec/components/component-story-docs-page"
|
|
6
|
+
|
|
5
7
|
import CircularLoader from "."
|
|
6
8
|
|
|
7
9
|
const meta: Meta<typeof CircularLoader> = {
|
|
@@ -9,107 +11,32 @@ const meta: Meta<typeof CircularLoader> = {
|
|
|
9
11
|
component: CircularLoader,
|
|
10
12
|
parameters: {
|
|
11
13
|
layout: "centered",
|
|
12
|
-
backgrounds: {
|
|
13
|
-
default: "dark",
|
|
14
|
-
values: [
|
|
15
|
-
{ name: "dark", value: "#0a0a0a" },
|
|
16
|
-
{ name: "darker", value: "#000000" },
|
|
17
|
-
{ name: "light", value: "#ffffff" },
|
|
18
|
-
],
|
|
19
|
-
},
|
|
20
14
|
docs: {
|
|
21
15
|
description: {
|
|
22
|
-
component:
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
An accessible circular loading spinner component with multiple variants, customizable sizing, and comprehensive screen reader support. Built with proper ARIA attributes and semantic HTML.
|
|
26
|
-
|
|
27
|
-
## Features
|
|
28
|
-
|
|
29
|
-
- **Multiple Variants**: Three distinct spinner designs (gradient, solid, neutral)
|
|
30
|
-
- **Size Options**: Four predefined sizes (sm, md, lg, xl) for different contexts
|
|
31
|
-
- **Accessibility First**: Full ARIA support with screen reader compatibility
|
|
32
|
-
- **Customizable Text**: Optional visual text with separate screen reader messages
|
|
33
|
-
- **Live Regions**: Configurable aria-live announcements for dynamic updates
|
|
34
|
-
- **Flexible Styling**: Custom classes for root, loader, and text elements
|
|
35
|
-
- **Semantic HTML**: Proper role and status indicators
|
|
36
|
-
|
|
37
|
-
## Accessibility Features
|
|
38
|
-
|
|
39
|
-
- **ARIA Labels**: Automatic labeling for screen readers
|
|
40
|
-
- **Live Regions**: Announces loading state changes
|
|
41
|
-
- **Screen Reader Text**: Hidden text for assistive technologies
|
|
42
|
-
- **Keyboard Safe**: Non-focusable decorative elements
|
|
43
|
-
- **Status Role**: Proper semantic meaning for loading states
|
|
44
|
-
|
|
45
|
-
## Usage Examples
|
|
46
|
-
|
|
47
|
-
### Basic Loading
|
|
48
|
-
\`\`\`tsx
|
|
49
|
-
import CircularLoader from '@/components/circular-loader'
|
|
50
|
-
|
|
51
|
-
// Simple loading with visual text
|
|
52
|
-
<CircularLoader text="Loading..." />
|
|
53
|
-
|
|
54
|
-
// Screen reader only (no visual text)
|
|
55
|
-
<CircularLoader aria-label="Loading user data" />
|
|
56
|
-
\`\`\`
|
|
57
|
-
|
|
58
|
-
### Different Variants
|
|
59
|
-
\`\`\`tsx
|
|
60
|
-
// Gradient spinner (default)
|
|
61
|
-
<CircularLoader variant="v1" text="Loading..." />
|
|
62
|
-
|
|
63
|
-
// Solid spinner
|
|
64
|
-
<CircularLoader variant="v2" text="Processing..." />
|
|
65
|
-
|
|
66
|
-
// Neutral spinner
|
|
67
|
-
<CircularLoader variant="v3" text="Please wait..." />
|
|
68
|
-
\`\`\`
|
|
69
|
-
|
|
70
|
-
### Size Variations
|
|
71
|
-
\`\`\`tsx
|
|
72
|
-
// Small loader for buttons
|
|
73
|
-
<CircularLoader size="sm" text="Save" />
|
|
74
|
-
|
|
75
|
-
// Large loader for page loading
|
|
76
|
-
<CircularLoader size="xl" text="Loading application..." />
|
|
77
|
-
\`\`\`
|
|
78
|
-
|
|
79
|
-
### Advanced Accessibility
|
|
80
|
-
\`\`\`tsx
|
|
81
|
-
// Custom loading message for screen readers
|
|
82
|
-
<CircularLoader
|
|
83
|
-
text="Submitting form..."
|
|
84
|
-
loadingMessage="Your form is being processed, please wait"
|
|
85
|
-
aria-live="assertive"
|
|
86
|
-
/>
|
|
87
|
-
|
|
88
|
-
// Programmatic control
|
|
89
|
-
<CircularLoader
|
|
90
|
-
id="form-loader"
|
|
91
|
-
aria-label="Saving changes"
|
|
92
|
-
aria-live="polite"
|
|
93
|
-
/>
|
|
94
|
-
\`\`\`
|
|
95
|
-
|
|
96
|
-
### Custom Styling
|
|
97
|
-
\`\`\`tsx
|
|
98
|
-
<CircularLoader
|
|
99
|
-
variant="v2"
|
|
100
|
-
size="lg"
|
|
101
|
-
text="Loading..."
|
|
102
|
-
classes={{
|
|
103
|
-
root: "my-8",
|
|
104
|
-
loader: "text-blue-500",
|
|
105
|
-
text: "text-gray-600 font-medium"
|
|
106
|
-
}}
|
|
107
|
-
/>
|
|
108
|
-
\`\`\`
|
|
109
|
-
`,
|
|
16
|
+
component:
|
|
17
|
+
"An accessible circular loading spinner with three visual variants (gradient, solid, neutral), four sizes (sm/md/lg/xl), optional visible text, and full ARIA support including aria-live regions and screen-reader-only messages.",
|
|
110
18
|
},
|
|
19
|
+
page: () => (
|
|
20
|
+
<AuralComponentDocsPage
|
|
21
|
+
features={[
|
|
22
|
+
{
|
|
23
|
+
title: "3 Visual Variants",
|
|
24
|
+
description: "Gradient, solid, neutral",
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
title: "Size Scale",
|
|
28
|
+
description: "sm to xl scale",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
title: "ARIA Support",
|
|
32
|
+
description: "Live regions built in",
|
|
33
|
+
},
|
|
34
|
+
]}
|
|
35
|
+
/>
|
|
36
|
+
),
|
|
111
37
|
},
|
|
112
38
|
},
|
|
39
|
+
tags: ["autodocs"],
|
|
113
40
|
argTypes: {
|
|
114
41
|
variant: {
|
|
115
42
|
control: { type: "select" },
|
|
@@ -148,594 +75,268 @@ import CircularLoader from '@/components/circular-loader'
|
|
|
148
75
|
description: "Custom classes for different parts of the component",
|
|
149
76
|
},
|
|
150
77
|
},
|
|
151
|
-
tags: ["autodocs"],
|
|
152
78
|
}
|
|
153
79
|
|
|
154
80
|
export default meta
|
|
155
81
|
type Story = StoryObj<typeof CircularLoader>
|
|
156
82
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
83
|
+
const loaderTextClass = "text-fm-primary"
|
|
84
|
+
|
|
85
|
+
function StoryCircularLoader(
|
|
86
|
+
props: React.ComponentProps<typeof CircularLoader>
|
|
87
|
+
) {
|
|
88
|
+
return (
|
|
89
|
+
<CircularLoader
|
|
90
|
+
{...props}
|
|
91
|
+
classes={{
|
|
92
|
+
...props.classes,
|
|
93
|
+
text: [loaderTextClass, props.classes?.text].filter(Boolean).join(" "),
|
|
94
|
+
}}
|
|
95
|
+
/>
|
|
96
|
+
)
|
|
166
97
|
}
|
|
167
98
|
|
|
168
|
-
// 1.
|
|
169
|
-
|
|
99
|
+
// ─── 1. Playground ────────────────────────────────────────────────────────────
|
|
100
|
+
|
|
101
|
+
export const Playground: Story = {
|
|
170
102
|
args: {
|
|
171
|
-
text: "Loading...",
|
|
172
103
|
variant: "v1",
|
|
173
104
|
size: "md",
|
|
105
|
+
text: "Loading...",
|
|
106
|
+
"aria-label": "Loading",
|
|
107
|
+
"aria-live": "polite",
|
|
108
|
+
loadingMessage: "",
|
|
174
109
|
},
|
|
175
|
-
parameters: storyParameters,
|
|
176
110
|
render: (args) => (
|
|
177
|
-
<div className="
|
|
178
|
-
<
|
|
179
|
-
|
|
180
|
-
),
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// 2. Variant Showcase
|
|
184
|
-
export const Variants: Story = {
|
|
185
|
-
parameters: {
|
|
186
|
-
...storyParameters,
|
|
187
|
-
docs: {
|
|
188
|
-
description: {
|
|
189
|
-
story:
|
|
190
|
-
"Different visual variants of the CircularLoader component with consistent accessibility features.",
|
|
191
|
-
},
|
|
192
|
-
},
|
|
193
|
-
},
|
|
194
|
-
render: () => (
|
|
195
|
-
<div className="space-y-8 rounded-lg bg-gradient-to-br from-gray-900 to-gray-800 p-8 text-white">
|
|
196
|
-
<div className="text-center">
|
|
197
|
-
<h3 className="mb-4 text-xl font-bold text-white">Spinner Variants</h3>
|
|
198
|
-
<p className="text-sm text-white/60">
|
|
199
|
-
Three distinct visual styles with full accessibility support
|
|
200
|
-
</p>
|
|
111
|
+
<div className="w-full max-w-sm space-y-4">
|
|
112
|
+
<div className="flex justify-center py-6">
|
|
113
|
+
<StoryCircularLoader {...args} />
|
|
201
114
|
</div>
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
<CircularLoader variant="v1" text="Gradient" size="lg" />
|
|
207
|
-
</div>
|
|
208
|
-
<div className="space-y-1">
|
|
209
|
-
<div className="font-medium text-white">Variant V1</div>
|
|
210
|
-
<div className="text-xs text-white/60">
|
|
211
|
-
Gradient spinner with smooth transitions
|
|
212
|
-
</div>
|
|
213
|
-
</div>
|
|
214
|
-
</div>
|
|
215
|
-
|
|
216
|
-
<div className="text-center">
|
|
217
|
-
<div className="mb-4 flex h-32 items-center justify-center rounded-lg border border-white/10 bg-white/5">
|
|
218
|
-
<CircularLoader variant="v2" text="Solid" size="lg" />
|
|
219
|
-
</div>
|
|
220
|
-
<div className="space-y-1">
|
|
221
|
-
<div className="font-medium text-white">Variant V2</div>
|
|
222
|
-
<div className="text-xs text-white/60">
|
|
223
|
-
Solid spinner with consistent theming
|
|
224
|
-
</div>
|
|
225
|
-
</div>
|
|
226
|
-
</div>
|
|
227
|
-
|
|
228
|
-
<div className="text-center">
|
|
229
|
-
<div className="mb-4 flex h-32 items-center justify-center rounded-lg border border-white/10 bg-white/5">
|
|
230
|
-
<CircularLoader variant="v3" text="Neutral" size="lg" />
|
|
231
|
-
</div>
|
|
232
|
-
<div className="space-y-1">
|
|
233
|
-
<div className="font-medium text-white">Variant V3</div>
|
|
234
|
-
<div className="text-xs text-white/60">
|
|
235
|
-
Neutral spinner for any theme
|
|
236
|
-
</div>
|
|
237
|
-
</div>
|
|
238
|
-
</div>
|
|
115
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border px-4 py-3">
|
|
116
|
+
<code className="text-fm-secondary text-fm-md leading-fm-md font-(--font-fm-mono)">
|
|
117
|
+
{`<CircularLoader variant="${args.variant}" size="${args.size}"${args.text ? ` text="${args.text}"` : ""} />`}
|
|
118
|
+
</code>
|
|
239
119
|
</div>
|
|
240
120
|
</div>
|
|
241
121
|
),
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// 3. Size Variations
|
|
245
|
-
export const Sizes: Story = {
|
|
246
122
|
parameters: {
|
|
247
|
-
...storyParameters,
|
|
248
123
|
docs: {
|
|
249
124
|
description: {
|
|
250
125
|
story:
|
|
251
|
-
"
|
|
126
|
+
"Adjust variant, size, text, and accessibility props using the controls panel in the sidebar.",
|
|
252
127
|
},
|
|
253
128
|
},
|
|
254
129
|
},
|
|
255
|
-
|
|
256
|
-
<div className="space-y-8 rounded-lg bg-gradient-to-br from-gray-900 to-gray-800 p-8 text-white">
|
|
257
|
-
<div className="text-center">
|
|
258
|
-
<h3 className="mb-4 text-xl font-bold text-white">Size Variations</h3>
|
|
259
|
-
<p className="text-sm text-white/60">
|
|
260
|
-
Four predefined sizes for different contexts and use cases
|
|
261
|
-
</p>
|
|
262
|
-
</div>
|
|
263
|
-
|
|
264
|
-
<div className="grid grid-cols-2 gap-6 md:grid-cols-4">
|
|
265
|
-
<div className="text-center">
|
|
266
|
-
<div className="mb-4 flex h-24 items-center justify-center rounded-lg border border-white/10 bg-white/5">
|
|
267
|
-
<CircularLoader size="sm" text="Small" />
|
|
268
|
-
</div>
|
|
269
|
-
<div className="space-y-1">
|
|
270
|
-
<div className="font-medium text-white">Small</div>
|
|
271
|
-
<div className="text-xs text-white/60">
|
|
272
|
-
16×16px - Inline elements
|
|
273
|
-
</div>
|
|
274
|
-
</div>
|
|
275
|
-
</div>
|
|
276
|
-
|
|
277
|
-
<div className="text-center">
|
|
278
|
-
<div className="mb-4 flex h-24 items-center justify-center rounded-lg border border-white/10 bg-white/5">
|
|
279
|
-
<CircularLoader size="md" text="Medium" />
|
|
280
|
-
</div>
|
|
281
|
-
<div className="space-y-1">
|
|
282
|
-
<div className="font-medium text-white">Medium</div>
|
|
283
|
-
<div className="text-xs text-white/60">24×24px - Default size</div>
|
|
284
|
-
</div>
|
|
285
|
-
</div>
|
|
130
|
+
}
|
|
286
131
|
|
|
287
|
-
|
|
288
|
-
<div className="mb-4 flex h-24 items-center justify-center rounded-lg border border-white/10 bg-white/5">
|
|
289
|
-
<CircularLoader size="lg" text="Large" />
|
|
290
|
-
</div>
|
|
291
|
-
<div className="space-y-1">
|
|
292
|
-
<div className="font-medium text-white">Large</div>
|
|
293
|
-
<div className="text-xs text-white/60">
|
|
294
|
-
32×32px - Prominent loading
|
|
295
|
-
</div>
|
|
296
|
-
</div>
|
|
297
|
-
</div>
|
|
132
|
+
// ─── 2. AllVariants ───────────────────────────────────────────────────────────
|
|
298
133
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
134
|
+
export const AllVariants: Story = {
|
|
135
|
+
render: () => (
|
|
136
|
+
<div className="space-y-8">
|
|
137
|
+
<div className="space-y-4">
|
|
138
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
139
|
+
Spinner Variants
|
|
140
|
+
</h4>
|
|
141
|
+
<div className="flex flex-wrap items-end gap-8">
|
|
142
|
+
<div className="space-y-2 text-center">
|
|
143
|
+
<StoryCircularLoader variant="v1" size="lg" text="Gradient" />
|
|
144
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
145
|
+
V1 — Gradient
|
|
146
|
+
</p>
|
|
147
|
+
</div>
|
|
148
|
+
<div className="space-y-2 text-center">
|
|
149
|
+
<StoryCircularLoader variant="v2" size="lg" text="Solid" />
|
|
150
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
151
|
+
V2 — Solid
|
|
152
|
+
</p>
|
|
153
|
+
</div>
|
|
154
|
+
<div className="space-y-2 text-center">
|
|
155
|
+
<StoryCircularLoader variant="v3" size="lg" text="Neutral" />
|
|
156
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
157
|
+
V3 — Neutral
|
|
158
|
+
</p>
|
|
306
159
|
</div>
|
|
307
160
|
</div>
|
|
308
161
|
</div>
|
|
309
162
|
</div>
|
|
310
163
|
),
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
// 4. Accessibility Features
|
|
314
|
-
export const AccessibilityFeatures: Story = {
|
|
315
164
|
parameters: {
|
|
316
|
-
...storyParameters,
|
|
317
165
|
docs: {
|
|
318
166
|
description: {
|
|
319
167
|
story:
|
|
320
|
-
"
|
|
168
|
+
"Three distinct spinner designs — gradient (v1), solid branded (v2), and neutral (v3) — shown at large size for easy comparison.",
|
|
321
169
|
},
|
|
322
170
|
},
|
|
323
171
|
},
|
|
324
|
-
|
|
325
|
-
<div className="space-y-8 rounded-lg bg-gradient-to-br from-gray-900 to-gray-800 p-8 text-white">
|
|
326
|
-
<div className="text-center">
|
|
327
|
-
<h3 className="mb-4 text-xl font-bold text-white">
|
|
328
|
-
Accessibility Features
|
|
329
|
-
</h3>
|
|
330
|
-
<p className="text-sm text-white/60">
|
|
331
|
-
Built with comprehensive screen reader support and ARIA attributes
|
|
332
|
-
</p>
|
|
333
|
-
</div>
|
|
334
|
-
|
|
335
|
-
<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
|
|
336
|
-
<div className="space-y-6">
|
|
337
|
-
<div className="rounded-lg border border-white/10 bg-white/5 p-6">
|
|
338
|
-
<h4 className="mb-4 text-lg font-semibold text-white">
|
|
339
|
-
Visual + Screen Reader
|
|
340
|
-
</h4>
|
|
341
|
-
<div className="mb-4 flex items-center justify-center">
|
|
342
|
-
<CircularLoader text="Loading data..." size="lg" />
|
|
343
|
-
</div>
|
|
344
|
-
<div className="text-sm text-white/70">
|
|
345
|
-
Shows visible text and provides the same message to screen readers
|
|
346
|
-
</div>
|
|
347
|
-
</div>
|
|
348
|
-
|
|
349
|
-
<div className="rounded-lg border border-white/10 bg-white/5 p-6">
|
|
350
|
-
<h4 className="mb-4 text-lg font-semibold text-white">
|
|
351
|
-
Screen Reader Only
|
|
352
|
-
</h4>
|
|
353
|
-
<div className="mb-4 flex items-center justify-center">
|
|
354
|
-
<CircularLoader
|
|
355
|
-
aria-label="Processing user authentication"
|
|
356
|
-
size="lg"
|
|
357
|
-
/>
|
|
358
|
-
</div>
|
|
359
|
-
<div className="text-sm text-white/70">
|
|
360
|
-
No visible text but provides descriptive label for screen readers
|
|
361
|
-
</div>
|
|
362
|
-
</div>
|
|
363
|
-
</div>
|
|
364
|
-
|
|
365
|
-
<div className="space-y-6">
|
|
366
|
-
<div className="rounded-lg border border-white/10 bg-white/5 p-6">
|
|
367
|
-
<h4 className="mb-4 text-lg font-semibold text-white">
|
|
368
|
-
Custom Loading Message
|
|
369
|
-
</h4>
|
|
370
|
-
<div className="mb-4 flex items-center justify-center">
|
|
371
|
-
<CircularLoader
|
|
372
|
-
text="Saving..."
|
|
373
|
-
loadingMessage="Your changes are being saved to the server"
|
|
374
|
-
size="lg"
|
|
375
|
-
/>
|
|
376
|
-
</div>
|
|
377
|
-
<div className="text-sm text-white/70">
|
|
378
|
-
Visual text differs from detailed screen reader message
|
|
379
|
-
</div>
|
|
380
|
-
</div>
|
|
172
|
+
}
|
|
381
173
|
|
|
382
|
-
|
|
383
|
-
<h4 className="mb-4 text-lg font-semibold text-white">
|
|
384
|
-
Assertive Announcements
|
|
385
|
-
</h4>
|
|
386
|
-
<div className="mb-4 flex items-center justify-center">
|
|
387
|
-
<CircularLoader
|
|
388
|
-
text="Critical process..."
|
|
389
|
-
aria-live="assertive"
|
|
390
|
-
size="lg"
|
|
391
|
-
/>
|
|
392
|
-
</div>
|
|
393
|
-
<div className="text-sm text-white/70">
|
|
394
|
-
Immediately announces changes to screen readers
|
|
395
|
-
</div>
|
|
396
|
-
</div>
|
|
397
|
-
</div>
|
|
398
|
-
</div>
|
|
174
|
+
// ─── 3. Sizes ─────────────────────────────────────────────────────────────────
|
|
399
175
|
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
176
|
+
export const Sizes: Story = {
|
|
177
|
+
render: () => (
|
|
178
|
+
<div className="space-y-8">
|
|
179
|
+
<div className="space-y-4">
|
|
180
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
181
|
+
Size Scale
|
|
403
182
|
</h4>
|
|
404
|
-
<div className="
|
|
405
|
-
<div>
|
|
406
|
-
<
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
</
|
|
416
|
-
</div>
|
|
417
|
-
<div>
|
|
418
|
-
<
|
|
419
|
-
<
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
183
|
+
<div className="flex flex-wrap items-end justify-center gap-8">
|
|
184
|
+
<div className="space-y-2 text-center">
|
|
185
|
+
<CircularLoader size="sm" aria-label="Loading small" />
|
|
186
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
187
|
+
Small (16px)
|
|
188
|
+
</p>
|
|
189
|
+
</div>
|
|
190
|
+
<div className="space-y-2 text-center">
|
|
191
|
+
<CircularLoader size="md" aria-label="Loading medium" />
|
|
192
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
193
|
+
Medium (24px)
|
|
194
|
+
</p>
|
|
195
|
+
</div>
|
|
196
|
+
<div className="space-y-2 text-center">
|
|
197
|
+
<CircularLoader size="lg" aria-label="Loading large" />
|
|
198
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
199
|
+
Large (32px)
|
|
200
|
+
</p>
|
|
201
|
+
</div>
|
|
202
|
+
<div className="space-y-2 text-center">
|
|
203
|
+
<CircularLoader size="xl" aria-label="Loading extra large" />
|
|
204
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
205
|
+
Extra Large (48px)
|
|
206
|
+
</p>
|
|
426
207
|
</div>
|
|
427
208
|
</div>
|
|
428
209
|
</div>
|
|
429
210
|
</div>
|
|
430
211
|
),
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
// 5. Real-world Usage Examples
|
|
434
|
-
export const UsageExamples: Story = {
|
|
435
212
|
parameters: {
|
|
436
|
-
...storyParameters,
|
|
437
213
|
docs: {
|
|
438
214
|
description: {
|
|
439
215
|
story:
|
|
440
|
-
"
|
|
216
|
+
"Four predefined sizes side by side — sm for inline/button use, md as the default, lg for prominent loading areas, xl for full-page loading states.",
|
|
441
217
|
},
|
|
442
218
|
},
|
|
443
219
|
},
|
|
444
|
-
|
|
445
|
-
const [buttonLoading, setButtonLoading] = useState(false)
|
|
446
|
-
const [cardLoading, setCardLoading] = useState(false)
|
|
447
|
-
const [pageLoading, setPageLoading] = useState(false)
|
|
448
|
-
|
|
449
|
-
const handleButtonClick = () => {
|
|
450
|
-
setButtonLoading(true)
|
|
451
|
-
setTimeout(() => setButtonLoading(false), 3000)
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
const handleCardRefresh = () => {
|
|
455
|
-
setCardLoading(true)
|
|
456
|
-
setTimeout(() => setCardLoading(false), 2000)
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
const handlePageRefresh = () => {
|
|
460
|
-
setPageLoading(true)
|
|
461
|
-
setTimeout(() => setPageLoading(false), 4000)
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
return (
|
|
465
|
-
<div className="space-y-8 rounded-lg bg-gradient-to-br from-gray-900 to-gray-800 p-8 text-white">
|
|
466
|
-
<div className="text-center">
|
|
467
|
-
<h3 className="mb-4 text-xl font-bold text-white">
|
|
468
|
-
Real-world Usage
|
|
469
|
-
</h3>
|
|
470
|
-
<p className="text-sm text-white/60">
|
|
471
|
-
Common UI patterns and contexts where CircularLoader is used
|
|
472
|
-
</p>
|
|
473
|
-
</div>
|
|
474
|
-
|
|
475
|
-
<div className="grid grid-cols-1 gap-8 lg:grid-cols-3">
|
|
476
|
-
{/* Button Loading */}
|
|
477
|
-
<div className="space-y-4">
|
|
478
|
-
<h4 className="text-lg font-semibold text-white">Button Loading</h4>
|
|
479
|
-
<div className="space-y-3">
|
|
480
|
-
<Button
|
|
481
|
-
onClick={handleButtonClick}
|
|
482
|
-
disabled={buttonLoading}
|
|
483
|
-
className="w-full"
|
|
484
|
-
>
|
|
485
|
-
{buttonLoading ? (
|
|
486
|
-
<div className="flex items-center gap-2">
|
|
487
|
-
<CircularLoader size="sm" aria-label="Saving changes" />
|
|
488
|
-
<span>Saving...</span>
|
|
489
|
-
</div>
|
|
490
|
-
) : (
|
|
491
|
-
"Save Changes"
|
|
492
|
-
)}
|
|
493
|
-
</Button>
|
|
494
|
-
<div className="text-xs text-white/60">
|
|
495
|
-
Inline loader in button with accessible label
|
|
496
|
-
</div>
|
|
497
|
-
</div>
|
|
498
|
-
</div>
|
|
220
|
+
}
|
|
499
221
|
|
|
500
|
-
|
|
501
|
-
<div className="space-y-4">
|
|
502
|
-
<h4 className="text-lg font-semibold text-white">Card Loading</h4>
|
|
503
|
-
<div className="rounded-lg border border-white/10 bg-white/5 p-4">
|
|
504
|
-
{cardLoading ? (
|
|
505
|
-
<div className="flex h-32 items-center justify-center">
|
|
506
|
-
<CircularLoader
|
|
507
|
-
text="Refreshing data..."
|
|
508
|
-
loadingMessage="Refreshing chart data from server"
|
|
509
|
-
size="lg"
|
|
510
|
-
/>
|
|
511
|
-
</div>
|
|
512
|
-
) : (
|
|
513
|
-
<div className="space-y-3">
|
|
514
|
-
<div className="h-4 rounded bg-white/10"></div>
|
|
515
|
-
<div className="h-4 rounded bg-white/10"></div>
|
|
516
|
-
<div className="h-4 w-3/4 rounded bg-white/10"></div>
|
|
517
|
-
<Button
|
|
518
|
-
onClick={handleCardRefresh}
|
|
519
|
-
size="sm"
|
|
520
|
-
className="mt-2"
|
|
521
|
-
>
|
|
522
|
-
Refresh Data
|
|
523
|
-
</Button>
|
|
524
|
-
</div>
|
|
525
|
-
)}
|
|
526
|
-
</div>
|
|
527
|
-
<div className="text-xs text-white/60">
|
|
528
|
-
Content area with detailed loading message
|
|
529
|
-
</div>
|
|
530
|
-
</div>
|
|
222
|
+
// ─── 4. Accessibility ─────────────────────────────────────────────────────────
|
|
531
223
|
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
224
|
+
export const Accessibility: Story = {
|
|
225
|
+
render: () => (
|
|
226
|
+
<div className="space-y-8">
|
|
227
|
+
<div className="space-y-4">
|
|
228
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
229
|
+
ARIA Patterns
|
|
230
|
+
</h4>
|
|
231
|
+
<div className="flex flex-wrap items-start gap-8">
|
|
232
|
+
<div className="space-y-2 text-center">
|
|
233
|
+
<StoryCircularLoader
|
|
234
|
+
size="lg"
|
|
235
|
+
text="Loading data..."
|
|
236
|
+
aria-live="polite"
|
|
237
|
+
/>
|
|
238
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
239
|
+
Visual text (polite)
|
|
240
|
+
</p>
|
|
241
|
+
</div>
|
|
242
|
+
<div className="space-y-2 text-center">
|
|
243
|
+
<CircularLoader
|
|
244
|
+
size="lg"
|
|
245
|
+
aria-label="Processing your authentication"
|
|
246
|
+
aria-live="polite"
|
|
247
|
+
/>
|
|
248
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
249
|
+
SR label only
|
|
250
|
+
</p>
|
|
251
|
+
</div>
|
|
252
|
+
<div className="space-y-2 text-center">
|
|
253
|
+
<StoryCircularLoader
|
|
254
|
+
size="lg"
|
|
255
|
+
text="Saving..."
|
|
256
|
+
loadingMessage="Your changes are being saved to the server"
|
|
257
|
+
aria-live="polite"
|
|
258
|
+
/>
|
|
259
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
260
|
+
Custom SR message
|
|
261
|
+
</p>
|
|
262
|
+
</div>
|
|
263
|
+
<div className="space-y-2 text-center">
|
|
264
|
+
<StoryCircularLoader
|
|
265
|
+
size="lg"
|
|
266
|
+
text="Critical update..."
|
|
267
|
+
aria-live="assertive"
|
|
268
|
+
/>
|
|
269
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
270
|
+
Assertive announce
|
|
271
|
+
</p>
|
|
565
272
|
</div>
|
|
566
273
|
</div>
|
|
274
|
+
</div>
|
|
567
275
|
|
|
568
|
-
|
|
569
|
-
<
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
<div className="
|
|
574
|
-
<
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
className="rounded-lg border border-white/20 bg-white/10 p-3 text-white placeholder-white/50"
|
|
584
|
-
/>
|
|
585
|
-
</div>
|
|
586
|
-
<textarea
|
|
587
|
-
placeholder="Message"
|
|
588
|
-
rows={3}
|
|
589
|
-
className="w-full rounded-lg border border-white/20 bg-white/10 p-3 text-white placeholder-white/50"
|
|
590
|
-
/>
|
|
591
|
-
<div className="flex items-center justify-between">
|
|
592
|
-
<div className="flex items-center gap-2">
|
|
593
|
-
<CircularLoader size="sm" aria-label="Submitting form" />
|
|
594
|
-
<span className="text-sm text-white/70">
|
|
595
|
-
Submitting your message...
|
|
596
|
-
</span>
|
|
597
|
-
</div>
|
|
598
|
-
<Button disabled>Submit</Button>
|
|
599
|
-
</div>
|
|
600
|
-
</div>
|
|
276
|
+
<div className="space-y-4">
|
|
277
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
278
|
+
In-context Usage
|
|
279
|
+
</h4>
|
|
280
|
+
<div className="flex flex-wrap gap-6">
|
|
281
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary flex items-center gap-3 rounded-lg border px-4 py-3">
|
|
282
|
+
<CircularLoader size="sm" aria-label="Saving changes" />
|
|
283
|
+
<span className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
284
|
+
Saving changes...
|
|
285
|
+
</span>
|
|
286
|
+
</div>
|
|
287
|
+
<Button disabled>
|
|
288
|
+
<CircularLoader size="sm" aria-label="Submitting form" />
|
|
289
|
+
Submitting
|
|
290
|
+
</Button>
|
|
601
291
|
</div>
|
|
602
292
|
</div>
|
|
603
|
-
)
|
|
604
|
-
},
|
|
605
|
-
}
|
|
606
293
|
|
|
607
|
-
|
|
608
|
-
|
|
294
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
|
|
295
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
|
|
296
|
+
<strong className="text-fm-primary">Best practices:</strong>
|
|
297
|
+
</p>
|
|
298
|
+
<ul className="mt-2 space-y-1">
|
|
299
|
+
<li>
|
|
300
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
301
|
+
• Always supply <code>text</code> or <code>aria-label</code> so
|
|
302
|
+
screen readers know what is loading.
|
|
303
|
+
</p>
|
|
304
|
+
</li>
|
|
305
|
+
<li>
|
|
306
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
307
|
+
• Use <code>loadingMessage</code> when the visible text is too
|
|
308
|
+
brief — the message is read instead by screen readers.
|
|
309
|
+
</p>
|
|
310
|
+
</li>
|
|
311
|
+
<li>
|
|
312
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
313
|
+
• Prefer <code>aria-live="polite"</code> for background tasks;
|
|
314
|
+
reserve <code>"assertive"</code> for critical, time-sensitive
|
|
315
|
+
updates.
|
|
316
|
+
</p>
|
|
317
|
+
</li>
|
|
318
|
+
<li>
|
|
319
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
320
|
+
• The spinner icon carries <code>aria-hidden="true"</code> — it is
|
|
321
|
+
purely decorative and excluded from the accessibility tree.
|
|
322
|
+
</p>
|
|
323
|
+
</li>
|
|
324
|
+
<li>
|
|
325
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
326
|
+
• <code>role="status"</code> is set automatically on the root
|
|
327
|
+
element, meeting WCAG 4.1.3 (Status Messages).
|
|
328
|
+
</p>
|
|
329
|
+
</li>
|
|
330
|
+
</ul>
|
|
331
|
+
</div>
|
|
332
|
+
</div>
|
|
333
|
+
),
|
|
609
334
|
parameters: {
|
|
610
|
-
...storyParameters,
|
|
611
335
|
docs: {
|
|
612
336
|
description: {
|
|
613
337
|
story:
|
|
614
|
-
"
|
|
338
|
+
"Accessibility-focused examples covering polite and assertive aria-live regions, screen-reader-only labels, custom loading messages, and inline button integration — with a best-practices reference.",
|
|
615
339
|
},
|
|
616
340
|
},
|
|
617
341
|
},
|
|
618
|
-
args: {
|
|
619
|
-
variant: "v1",
|
|
620
|
-
size: "md",
|
|
621
|
-
text: "Loading...",
|
|
622
|
-
"aria-label": "",
|
|
623
|
-
"aria-live": "polite",
|
|
624
|
-
loadingMessage: "",
|
|
625
|
-
className: "",
|
|
626
|
-
classes: {},
|
|
627
|
-
},
|
|
628
|
-
argTypes: {
|
|
629
|
-
variant: {
|
|
630
|
-
control: { type: "select" },
|
|
631
|
-
options: ["v1", "v2", "v3"],
|
|
632
|
-
description: "Visual variant of the spinner",
|
|
633
|
-
},
|
|
634
|
-
size: {
|
|
635
|
-
control: { type: "select" },
|
|
636
|
-
options: ["sm", "md", "lg", "xl"],
|
|
637
|
-
description: "Size of the spinner",
|
|
638
|
-
},
|
|
639
|
-
text: {
|
|
640
|
-
control: "text",
|
|
641
|
-
description: "Visible text displayed below the spinner",
|
|
642
|
-
},
|
|
643
|
-
"aria-label": {
|
|
644
|
-
control: "text",
|
|
645
|
-
description:
|
|
646
|
-
"Accessible label for screen readers when no text is provided",
|
|
647
|
-
},
|
|
648
|
-
"aria-live": {
|
|
649
|
-
control: { type: "select" },
|
|
650
|
-
options: ["polite", "assertive", "off"],
|
|
651
|
-
description: "How screen readers announce loading state changes",
|
|
652
|
-
},
|
|
653
|
-
loadingMessage: {
|
|
654
|
-
control: "text",
|
|
655
|
-
description: "Custom loading message for screen readers",
|
|
656
|
-
},
|
|
657
|
-
className: {
|
|
658
|
-
control: "text",
|
|
659
|
-
description: "Additional CSS classes for the spinner icon",
|
|
660
|
-
},
|
|
661
|
-
classes: {
|
|
662
|
-
control: "object",
|
|
663
|
-
description: "Custom classes for different parts of the component",
|
|
664
|
-
},
|
|
665
|
-
},
|
|
666
|
-
render: (args) => (
|
|
667
|
-
<div className="space-y-8 rounded-lg bg-gradient-to-br from-gray-900 to-gray-800 p-8 text-white">
|
|
668
|
-
<div className="text-center">
|
|
669
|
-
<h3 className="mb-4 text-xl font-bold text-white">
|
|
670
|
-
Interactive Playground
|
|
671
|
-
</h3>
|
|
672
|
-
<p className="text-sm text-white/60">
|
|
673
|
-
Experiment with all CircularLoader configurations and accessibility
|
|
674
|
-
features
|
|
675
|
-
</p>
|
|
676
|
-
</div>
|
|
677
|
-
|
|
678
|
-
<div className="flex items-center justify-center">
|
|
679
|
-
<div className="rounded-lg border border-white/10 bg-white/5 p-8">
|
|
680
|
-
<CircularLoader {...args} />
|
|
681
|
-
</div>
|
|
682
|
-
</div>
|
|
683
|
-
|
|
684
|
-
<div className="rounded-lg border border-white/10 bg-white/5 p-6">
|
|
685
|
-
<h4 className="mb-4 text-lg font-semibold text-white">
|
|
686
|
-
Current Configuration
|
|
687
|
-
</h4>
|
|
688
|
-
<div className="grid grid-cols-2 gap-4 text-sm">
|
|
689
|
-
<div>
|
|
690
|
-
<div className="font-medium text-white">Variant:</div>
|
|
691
|
-
<div className="text-white/70">{args.variant}</div>
|
|
692
|
-
</div>
|
|
693
|
-
<div>
|
|
694
|
-
<div className="font-medium text-white">Size:</div>
|
|
695
|
-
<div className="text-white/70">{args.size}</div>
|
|
696
|
-
</div>
|
|
697
|
-
<div>
|
|
698
|
-
<div className="font-medium text-white">Visual Text:</div>
|
|
699
|
-
<div className="text-white/70">{args.text || "None"}</div>
|
|
700
|
-
</div>
|
|
701
|
-
<div>
|
|
702
|
-
<div className="font-medium text-white">ARIA Label:</div>
|
|
703
|
-
<div className="text-white/70">{args["aria-label"] || "None"}</div>
|
|
704
|
-
</div>
|
|
705
|
-
<div>
|
|
706
|
-
<div className="font-medium text-white">ARIA Live:</div>
|
|
707
|
-
<div className="text-white/70">{args["aria-live"]}</div>
|
|
708
|
-
</div>
|
|
709
|
-
<div>
|
|
710
|
-
<div className="font-medium text-white">Loading Message:</div>
|
|
711
|
-
<div className="text-white/70">{args.loadingMessage || "None"}</div>
|
|
712
|
-
</div>
|
|
713
|
-
</div>
|
|
714
|
-
</div>
|
|
715
|
-
|
|
716
|
-
<div className="rounded-lg border border-green-500/20 bg-green-500/10 p-6">
|
|
717
|
-
<h4 className="mb-4 text-lg font-semibold text-green-200">
|
|
718
|
-
Accessibility Info
|
|
719
|
-
</h4>
|
|
720
|
-
<div className="space-y-2 text-sm text-green-200/80">
|
|
721
|
-
<div>
|
|
722
|
-
<strong>Screen Reader Message:</strong>{" "}
|
|
723
|
-
{args.text ||
|
|
724
|
-
args.loadingMessage ||
|
|
725
|
-
args["aria-label"] ||
|
|
726
|
-
"Loading"}
|
|
727
|
-
</div>
|
|
728
|
-
<div>
|
|
729
|
-
<strong>Announcement Type:</strong> {args["aria-live"]}
|
|
730
|
-
</div>
|
|
731
|
-
<div>
|
|
732
|
-
<strong>Role:</strong> status
|
|
733
|
-
</div>
|
|
734
|
-
<div>
|
|
735
|
-
<strong>Focusable:</strong> No (decorative spinner)
|
|
736
|
-
</div>
|
|
737
|
-
</div>
|
|
738
|
-
</div>
|
|
739
|
-
</div>
|
|
740
|
-
),
|
|
741
342
|
}
|