@getmicdrop/svelte-components 5.10.1 → 5.10.3

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.
Files changed (227) hide show
  1. package/dist/calendar/AboutShow/AboutShow.svelte +172 -172
  2. package/dist/calendar/Calendar/MiniMonthCalendar.svelte +782 -782
  3. package/dist/calendar/FAQs/FAQs.svelte +75 -75
  4. package/dist/calendar/MonthSwitcher/MonthSwitcher.svelte +126 -126
  5. package/dist/calendar/OrderSummary/OrderSummary.svelte +367 -367
  6. package/dist/calendar/PublicCard/PublicCard.svelte +146 -146
  7. package/dist/calendar/ShowCard/ShowCard.svelte +157 -157
  8. package/dist/calendar/ShowTimeCard/ShowTimeCard.svelte +61 -61
  9. package/dist/components/Heading.svelte +60 -60
  10. package/dist/components/Layout/AppShell.svelte +104 -104
  11. package/dist/components/Layout/ContentSection.svelte +80 -80
  12. package/dist/components/Layout/Grid.svelte +4 -4
  13. package/dist/components/Layout/Heading.svelte +81 -81
  14. package/dist/components/Layout/PageContainer.svelte +69 -69
  15. package/dist/components/Layout/Responsive.svelte +75 -75
  16. package/dist/components/Layout/Section.svelte +80 -80
  17. package/dist/components/Layout/ShowOnDesktop.svelte +37 -37
  18. package/dist/components/Layout/ShowOnMobile.svelte +37 -37
  19. package/dist/components/Layout/Sidebar.svelte +108 -108
  20. package/dist/components/Layout/Stack.svelte +6 -6
  21. package/dist/components/Layout/Text.svelte +87 -87
  22. package/dist/components/Layout/TwoColumn.svelte +108 -108
  23. package/dist/components/Text.svelte +53 -53
  24. package/dist/constants/validation.js +91 -91
  25. package/dist/constants/validation.spec.js +64 -64
  26. package/dist/index.js +51 -51
  27. package/dist/patterns/data/DataGrid.svelte +45 -45
  28. package/dist/patterns/data/DataList.svelte +24 -24
  29. package/dist/patterns/data/DataTable.svelte +36 -36
  30. package/dist/patterns/forms/FormActions.spec.js +95 -95
  31. package/dist/patterns/forms/FormActions.stories.svelte +97 -97
  32. package/dist/patterns/forms/FormActions.svelte +46 -46
  33. package/dist/patterns/forms/FormGrid.svelte +33 -33
  34. package/dist/patterns/forms/FormSection.svelte +32 -32
  35. package/dist/patterns/forms/FormValidationSummary.stories.svelte +83 -83
  36. package/dist/patterns/forms/FormValidationSummary.svelte +74 -74
  37. package/dist/patterns/layout/Sidebar.svelte +39 -39
  38. package/dist/patterns/layout/index.js +29 -29
  39. package/dist/patterns/navigation/BottomNav.stories.svelte +117 -117
  40. package/dist/patterns/navigation/BottomNav.svelte +74 -74
  41. package/dist/patterns/navigation/Header.stories.svelte +77 -77
  42. package/dist/patterns/navigation/Header.svelte +255 -255
  43. package/dist/patterns/page/PageHeader.svelte +18 -18
  44. package/dist/patterns/page/PageLayout.svelte +40 -40
  45. package/dist/patterns/page/PageLoader.spec.js +57 -57
  46. package/dist/patterns/page/PageLoader.stories.svelte +137 -137
  47. package/dist/patterns/page/PageLoader.svelte +24 -24
  48. package/dist/patterns/page/SectionHeader.svelte +29 -29
  49. package/dist/presets/badges.js +112 -112
  50. package/dist/presets/buttons.js +76 -76
  51. package/dist/presets/index.js +9 -9
  52. package/dist/primitives/Accordion/Accordion.stories.svelte +75 -75
  53. package/dist/primitives/Accordion/Accordion.svelte +42 -42
  54. package/dist/primitives/Accordion/AccordionItem.svelte +95 -95
  55. package/dist/primitives/Alert/Alert.spec.js +173 -173
  56. package/dist/primitives/Alert/Alert.stories.svelte +88 -88
  57. package/dist/primitives/Alert/Alert.svelte +27 -27
  58. package/dist/primitives/Avatar/Avatar.stories.svelte +94 -94
  59. package/dist/primitives/Avatar/Avatar.svelte +66 -66
  60. package/dist/primitives/Badges/Badge.spec.js +144 -144
  61. package/dist/primitives/Badges/Badge.stories.svelte +86 -86
  62. package/dist/primitives/Badges/Badge.svelte +99 -99
  63. package/dist/primitives/BottomSheet/BottomSheet.spec.js +136 -136
  64. package/dist/primitives/BottomSheet/BottomSheet.stories.svelte +83 -83
  65. package/dist/primitives/BottomSheet/BottomSheet.svelte +100 -100
  66. package/dist/primitives/Breadcrumb/Breadcrumb.spec.js +122 -122
  67. package/dist/primitives/Breadcrumb/Breadcrumb.stories.svelte +23 -23
  68. package/dist/primitives/Breadcrumb/Breadcrumb.svelte +98 -98
  69. package/dist/primitives/Button/Button.spec.js +223 -223
  70. package/dist/primitives/Button/Button.stories.svelte +76 -76
  71. package/dist/primitives/Button/Button.svelte +283 -283
  72. package/dist/primitives/Button/ButtonGroup.svelte +50 -50
  73. package/dist/primitives/Button/ButtonSaveDemo.spec.js +146 -146
  74. package/dist/primitives/Button/ButtonSaveDemo.svelte +25 -25
  75. package/dist/primitives/Button/ButtonVariantShowcase.svelte +129 -129
  76. package/dist/primitives/Card.spec.js +49 -49
  77. package/dist/primitives/Card.stories.svelte +22 -22
  78. package/dist/primitives/Card.svelte +28 -28
  79. package/dist/primitives/Checkbox/Checkbox.stories.svelte +84 -84
  80. package/dist/primitives/Checkbox/Checkbox.svelte +88 -88
  81. package/dist/primitives/DarkModeToggle.spec.js +390 -390
  82. package/dist/primitives/DarkModeToggle.stories.svelte +57 -57
  83. package/dist/primitives/DarkModeToggle.svelte +136 -136
  84. package/dist/primitives/Drawer/Drawer.stories.svelte +80 -80
  85. package/dist/primitives/Drawer/Drawer.svelte +120 -120
  86. package/dist/primitives/Dropdown/Dropdown.stories.svelte +137 -137
  87. package/dist/primitives/Dropdown/Dropdown.svelte +170 -170
  88. package/dist/primitives/Dropdown/DropdownDivider.svelte +9 -9
  89. package/dist/primitives/Dropdown/DropdownItem.svelte +80 -80
  90. package/dist/primitives/Helper/Helper.svelte +33 -33
  91. package/dist/primitives/Icons/ArrowLeft.svelte +8 -8
  92. package/dist/primitives/Icons/ArrowRight.svelte +8 -8
  93. package/dist/primitives/Icons/Availability.svelte +14 -14
  94. package/dist/primitives/Icons/Back.svelte +14 -14
  95. package/dist/primitives/Icons/CheckCircle.svelte +6 -6
  96. package/dist/primitives/Icons/CheckCircleOutline.svelte +15 -15
  97. package/dist/primitives/Icons/ChevronLeft.svelte +4 -4
  98. package/dist/primitives/Icons/ChevronRight.svelte +4 -4
  99. package/dist/primitives/Icons/Copy.svelte +15 -15
  100. package/dist/primitives/Icons/Cross.svelte +5 -5
  101. package/dist/primitives/Icons/DownArrow.svelte +8 -8
  102. package/dist/primitives/Icons/ErrorCircle.svelte +6 -6
  103. package/dist/primitives/Icons/FacebookIcon.svelte +2 -2
  104. package/dist/primitives/Icons/Home.svelte +15 -15
  105. package/dist/primitives/Icons/Icon.spec.js +169 -169
  106. package/dist/primitives/Icons/Icon.stories.svelte +100 -100
  107. package/dist/primitives/Icons/Icon.svelte +52 -52
  108. package/dist/primitives/Icons/IconGallery.stories.svelte +235 -235
  109. package/dist/primitives/Icons/Info.svelte +7 -7
  110. package/dist/primitives/Icons/InstagramIcon.svelte +4 -4
  111. package/dist/primitives/Icons/LogoInstagram.svelte +2 -2
  112. package/dist/primitives/Icons/Message.svelte +15 -15
  113. package/dist/primitives/Icons/MoonIcon.svelte +5 -5
  114. package/dist/primitives/Icons/More.svelte +21 -21
  115. package/dist/primitives/Icons/MoreHori.spec.js +61 -61
  116. package/dist/primitives/Icons/MoreHori.svelte +22 -22
  117. package/dist/primitives/Icons/Notification.svelte +14 -14
  118. package/dist/primitives/Icons/Payment.svelte +14 -14
  119. package/dist/primitives/Icons/Profile.svelte +21 -21
  120. package/dist/primitives/Icons/Reload.svelte +29 -29
  121. package/dist/primitives/Icons/Shows.svelte +21 -21
  122. package/dist/primitives/Icons/Signout.svelte +21 -21
  123. package/dist/primitives/Icons/SunIcon.svelte +8 -8
  124. package/dist/primitives/Icons/TiktokIcon.svelte +2 -2
  125. package/dist/primitives/Icons/TwitterIcon.svelte +2 -2
  126. package/dist/primitives/Icons/WarningIcon.spec.js +18 -18
  127. package/dist/primitives/Icons/WarningIcon.svelte +5 -5
  128. package/dist/primitives/Input/Input.spec.js +573 -573
  129. package/dist/primitives/Input/Input.stories.svelte +139 -139
  130. package/dist/primitives/Input/Input.svelte +423 -423
  131. package/dist/primitives/Input/Select.spec.js +218 -218
  132. package/dist/primitives/Input/Select.stories.svelte +112 -112
  133. package/dist/primitives/Input/Select.svelte +252 -252
  134. package/dist/primitives/Input/Textarea.stories.svelte +137 -137
  135. package/dist/primitives/Input/Textarea.svelte +105 -105
  136. package/dist/primitives/Label/Label.svelte +37 -37
  137. package/dist/primitives/Modal/Modal.spec.js +99 -99
  138. package/dist/primitives/Modal/Modal.stories.svelte +86 -86
  139. package/dist/primitives/Modal/Modal.svelte +157 -157
  140. package/dist/primitives/Pagination/Pagination.stories.svelte +76 -76
  141. package/dist/primitives/Pagination/Pagination.svelte +261 -261
  142. package/dist/primitives/Radio/Radio.stories.svelte +80 -80
  143. package/dist/primitives/Radio/Radio.svelte +67 -67
  144. package/dist/primitives/Skeleton/CardPlaceholder.svelte +87 -87
  145. package/dist/primitives/Skeleton/ImagePlaceholder.svelte +59 -59
  146. package/dist/primitives/Skeleton/ListPlaceholder.svelte +76 -76
  147. package/dist/primitives/Skeleton/Skeleton.stories.svelte +151 -151
  148. package/dist/primitives/Skeleton/Skeleton.svelte +26 -26
  149. package/dist/primitives/Spinner/Spinner.spec.js +71 -71
  150. package/dist/primitives/Spinner/Spinner.stories.svelte +29 -29
  151. package/dist/primitives/Spinner/Spinner.svelte +20 -20
  152. package/dist/primitives/Tabs/TabItem.svelte +49 -49
  153. package/dist/primitives/Tabs/Tabs.stories.svelte +112 -112
  154. package/dist/primitives/Tabs/Tabs.svelte +137 -137
  155. package/dist/primitives/Toggle.spec.js +146 -146
  156. package/dist/primitives/Toggle.stories.svelte +92 -92
  157. package/dist/primitives/Toggle.svelte +131 -131
  158. package/dist/primitives/Tooltip/Tooltip.svelte +83 -83
  159. package/dist/primitives/Typography/Typography.svelte +53 -53
  160. package/dist/primitives/ValidationError.spec.js +103 -103
  161. package/dist/primitives/ValidationError.stories.svelte +69 -69
  162. package/dist/primitives/ValidationError.svelte +29 -29
  163. package/dist/primitives/index.js +92 -92
  164. package/dist/recipes/CropImage/CropImage.spec.js +208 -208
  165. package/dist/recipes/CropImage/CropImage.stories.svelte +104 -104
  166. package/dist/recipes/CropImage/CropImage.svelte +219 -219
  167. package/dist/recipes/ImageUploader/ImageUploader.stories.svelte +125 -125
  168. package/dist/recipes/ImageUploader/ImageUploader.svelte +970 -970
  169. package/dist/recipes/Toaster/Toaster.stories.svelte +62 -62
  170. package/dist/recipes/feedback/EmptyState/EmptyState.svelte +1 -1
  171. package/dist/recipes/feedback/ErrorDisplay.spec.js +69 -69
  172. package/dist/recipes/feedback/ErrorDisplay.stories.svelte +101 -101
  173. package/dist/recipes/feedback/ErrorDisplay.svelte +1 -1
  174. package/dist/recipes/feedback/StatusIndicator/StatusIndicator.spec.js +133 -133
  175. package/dist/recipes/feedback/StatusIndicator/StatusIndicator.svelte +157 -157
  176. package/dist/recipes/fields/CheckboxField.svelte +85 -85
  177. package/dist/recipes/fields/FormField.svelte +58 -58
  178. package/dist/recipes/fields/RadioGroup.svelte +95 -95
  179. package/dist/recipes/fields/SelectField.svelte +80 -80
  180. package/dist/recipes/fields/TextareaField.svelte +97 -97
  181. package/dist/recipes/fields/ToggleField.svelte +60 -60
  182. package/dist/recipes/fields/index.js +7 -7
  183. package/dist/recipes/inputs/MultiSelect.spec.js +260 -260
  184. package/dist/recipes/inputs/MultiSelect.stories.svelte +133 -133
  185. package/dist/recipes/inputs/MultiSelect.svelte +283 -283
  186. package/dist/recipes/inputs/OTPInput.spec.js +251 -251
  187. package/dist/recipes/inputs/OTPInput.stories.svelte +162 -162
  188. package/dist/recipes/inputs/OTPInput.svelte +117 -117
  189. package/dist/recipes/inputs/PasswordInput.svelte +22 -22
  190. package/dist/recipes/inputs/PasswordStrengthIndicator/PasswordStrengthIndicator.svelte +131 -117
  191. package/dist/recipes/inputs/PasswordStrengthIndicator/PasswordStrengthIndicator.svelte.d.ts.map +1 -1
  192. package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.stories.svelte +123 -123
  193. package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.svelte +344 -344
  194. package/dist/recipes/inputs/Search.svelte +102 -102
  195. package/dist/recipes/inputs/SelectDropdown.svelte +171 -171
  196. package/dist/recipes/modals/AlertModal.svelte +130 -130
  197. package/dist/recipes/modals/ConfirmationModal.spec.js +206 -206
  198. package/dist/recipes/modals/ConfirmationModal.stories.svelte +119 -119
  199. package/dist/recipes/modals/ConfirmationModal.svelte +152 -152
  200. package/dist/recipes/modals/InputModal.svelte +182 -182
  201. package/dist/recipes/modals/ModalStateManager.spec.js +100 -100
  202. package/dist/recipes/modals/ModalStateManager.svelte +77 -77
  203. package/dist/recipes/modals/ModalTestWrapper.svelte +65 -65
  204. package/dist/recipes/modals/StatusModal.svelte +206 -206
  205. package/dist/services/EventService.js +75 -75
  206. package/dist/services/EventService.spec.js +217 -217
  207. package/dist/services/ShowService.spec.js +345 -345
  208. package/dist/stores/toaster.js +13 -13
  209. package/dist/stories/ButtonAuditReview.stories.svelte +14 -14
  210. package/dist/stories/ButtonAuditReview.svelte +427 -427
  211. package/dist/stories/PatternsGallery.stories.svelte +19 -19
  212. package/dist/stories/PatternsGallery.svelte +206 -206
  213. package/dist/stories/PrimitivesGallery.stories.svelte +19 -19
  214. package/dist/stories/PrimitivesGallery.svelte +752 -752
  215. package/dist/stories/RecipesGallery.stories.svelte +19 -19
  216. package/dist/stories/RecipesGallery.svelte +471 -471
  217. package/dist/stories/button-audit-manifest.json +11186 -11186
  218. package/dist/tailwind/preset.cjs +82 -82
  219. package/dist/telemetry.js +405 -405
  220. package/dist/telemetry.spec.js +1169 -1169
  221. package/dist/tokens/tokens.css +87 -87
  222. package/dist/tokens/typography-base.css +163 -163
  223. package/dist/tokens/utilities.css +353 -353
  224. package/dist/utils/apiConfig.spec.js +219 -219
  225. package/dist/utils/transitions.js +4 -4
  226. package/dist/utils/utils.js +693 -693
  227. package/package.json +297 -297
@@ -1,162 +1,162 @@
1
- <script module>
2
- import { defineMeta } from "@storybook/addon-svelte-csf";
3
-
4
- import OTPInput from './OTPInput.svelte';
5
-
6
- const { Story } = defineMeta({
7
- title: 'Components/Input/OTPInput',
8
- component: OTPInput,
9
- tags: ['autodocs'],
10
- argTypes: {
11
- length: {
12
- control: { type: 'number', min: 4, max: 8 },
13
- description: 'Number of digits in the OTP',
14
- },
15
- disabled: {
16
- control: 'boolean',
17
- description: 'Disable all inputs',
18
- },
19
- },
20
- });
21
- </script>
22
-
23
- <script>
24
- let code = $state(['', '', '', '', '', '']);
25
- let code4 = $state(['', '', '', '']);
26
- let code8 = $state(['', '', '', '', '', '', '', '']);
27
- let completedCode = $state('');
28
- let otpRef = $state(null);
29
-
30
- function handleComplete(event) {
31
- completedCode = event.code;
32
- console.log('OTP Complete:', event.code);
33
- }
34
- </script>
35
-
36
-
37
- <Story
38
- name="Default (6 digits)"
39
- args={{
40
- value: ['', '', '', '', '', ''],
41
- length: 6,
42
- disabled: false,
43
- }}
44
- />
45
-
46
- <Story
47
- name="Four Digits"
48
- args={{
49
- value: ['', '', '', ''],
50
- length: 4,
51
- disabled: false,
52
- }}
53
- />
54
-
55
- <Story
56
- name="Eight Digits"
57
- args={{
58
- value: ['', '', '', '', '', '', '', ''],
59
- length: 8,
60
- disabled: false,
61
- }}
62
- />
63
-
64
- <Story
65
- name="Pre-filled"
66
- args={{
67
- value: ['1', '2', '3', '4', '5', '6'],
68
- length: 6,
69
- disabled: false,
70
- }}
71
- />
72
-
73
- <Story
74
- name="Disabled"
75
- args={{
76
- value: ['1', '2', '3', '4', '5', '6'],
77
- length: 6,
78
- disabled: true,
79
- }}
80
- />
81
-
82
- <Story name="Interactive">
83
- <div class="max-w-md space-y-6">
84
- <div>
85
- <h3 class="text-lg font-semibold mb-2">Enter Verification Code</h3>
86
- <p class="text-sm text-gray-500 dark:text-gray-400 mb-4">
87
- Enter the 6-digit code sent to your phone
88
- </p>
89
- <OTPInput
90
- bind:value={code}
91
- bind:this={otpRef}
92
- oncomplete={handleComplete}
93
- onchange={(e) => console.log('Changed:', e.code)}
94
- />
95
- </div>
96
-
97
- {#if completedCode}
98
- <div class="p-4 bg-green-50 border border-green-200 rounded">
99
- <p class="text-sm font-medium text-green-800">
100
- Code entered: {completedCode}
101
- </p>
102
- </div>
103
- {/if}
104
-
105
- <div class="flex gap-2">
106
- <button
107
- class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-primary"
108
- onclick={() => otpRef?.focus()}
109
- >
110
- Focus First Input
111
- </button>
112
- <button
113
- class="px-4 py-2 bg-gray-500 text-white rounded hover:bg-gray-600"
114
- onclick={() => {
115
- otpRef?.clear();
116
- completedCode = '';
117
- }}
118
- >
119
- Clear
120
- </button>
121
- </div>
122
- </div>
123
- </Story>
124
-
125
- <Story name="Verification Flow">
126
- <div class="max-w-md mx-auto p-6 bg-white dark:bg-gray-900 rounded-lg shadow-lg">
127
- <div class="text-center mb-6">
128
- <h2 class="text-2xl font-bold mb-2">Verify Your Phone</h2>
129
- <p class="text-gray-500 dark:text-gray-400">
130
- We've sent a 4-digit code to<br />
131
- <span class="font-medium">+1 (555) 123-4567</span>
132
- </p>
133
- </div>
134
-
135
- <div class="mb-6">
136
- <OTPInput
137
- bind:value={code4}
138
- length={4}
139
- oncomplete={(e) => alert(`Verifying code: ${e.code}`)}
140
- />
141
- </div>
142
-
143
- <p class="text-center text-sm text-gray-500 dark:text-gray-400">
144
- Didn't receive a code?
145
- <button class="text-primary hover:underline">Resend</button>
146
- </p>
147
- </div>
148
- </Story>
149
-
150
- <Story name="With Auto-Submit">
151
- <div class="max-w-md">
152
- <p class="text-sm text-gray-500 dark:text-gray-400 mb-4">
153
- Code will auto-submit when all digits are entered
154
- </p>
155
- <OTPInput
156
- value={['', '', '', '', '', '']}
157
- oncomplete={(e) => {
158
- alert(`Auto-submitting code: ${e.code}`);
159
- }}
160
- />
161
- </div>
162
- </Story>
1
+ <script module>
2
+ import { defineMeta } from "@storybook/addon-svelte-csf";
3
+
4
+ import OTPInput from './OTPInput.svelte';
5
+
6
+ const { Story } = defineMeta({
7
+ title: 'Components/Input/OTPInput',
8
+ component: OTPInput,
9
+ tags: ['autodocs'],
10
+ argTypes: {
11
+ length: {
12
+ control: { type: 'number', min: 4, max: 8 },
13
+ description: 'Number of digits in the OTP',
14
+ },
15
+ disabled: {
16
+ control: 'boolean',
17
+ description: 'Disable all inputs',
18
+ },
19
+ },
20
+ });
21
+ </script>
22
+
23
+ <script>
24
+ let code = $state(['', '', '', '', '', '']);
25
+ let code4 = $state(['', '', '', '']);
26
+ let code8 = $state(['', '', '', '', '', '', '', '']);
27
+ let completedCode = $state('');
28
+ let otpRef = $state(null);
29
+
30
+ function handleComplete(event) {
31
+ completedCode = event.code;
32
+ console.log('OTP Complete:', event.code);
33
+ }
34
+ </script>
35
+
36
+
37
+ <Story
38
+ name="Default (6 digits)"
39
+ args={{
40
+ value: ['', '', '', '', '', ''],
41
+ length: 6,
42
+ disabled: false,
43
+ }}
44
+ />
45
+
46
+ <Story
47
+ name="Four Digits"
48
+ args={{
49
+ value: ['', '', '', ''],
50
+ length: 4,
51
+ disabled: false,
52
+ }}
53
+ />
54
+
55
+ <Story
56
+ name="Eight Digits"
57
+ args={{
58
+ value: ['', '', '', '', '', '', '', ''],
59
+ length: 8,
60
+ disabled: false,
61
+ }}
62
+ />
63
+
64
+ <Story
65
+ name="Pre-filled"
66
+ args={{
67
+ value: ['1', '2', '3', '4', '5', '6'],
68
+ length: 6,
69
+ disabled: false,
70
+ }}
71
+ />
72
+
73
+ <Story
74
+ name="Disabled"
75
+ args={{
76
+ value: ['1', '2', '3', '4', '5', '6'],
77
+ length: 6,
78
+ disabled: true,
79
+ }}
80
+ />
81
+
82
+ <Story name="Interactive">
83
+ <div class="max-w-md space-y-6">
84
+ <div>
85
+ <h3 class="text-lg font-semibold mb-2">Enter Verification Code</h3>
86
+ <p class="text-sm text-gray-500 dark:text-gray-400 mb-4">
87
+ Enter the 6-digit code sent to your phone
88
+ </p>
89
+ <OTPInput
90
+ bind:value={code}
91
+ bind:this={otpRef}
92
+ oncomplete={handleComplete}
93
+ onchange={(e) => console.log('Changed:', e.code)}
94
+ />
95
+ </div>
96
+
97
+ {#if completedCode}
98
+ <div class="p-4 bg-green-50 border border-green-200 rounded">
99
+ <p class="text-sm font-medium text-green-800">
100
+ Code entered: {completedCode}
101
+ </p>
102
+ </div>
103
+ {/if}
104
+
105
+ <div class="flex gap-2">
106
+ <button
107
+ class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-primary"
108
+ onclick={() => otpRef?.focus()}
109
+ >
110
+ Focus First Input
111
+ </button>
112
+ <button
113
+ class="px-4 py-2 bg-gray-500 text-white rounded hover:bg-gray-600"
114
+ onclick={() => {
115
+ otpRef?.clear();
116
+ completedCode = '';
117
+ }}
118
+ >
119
+ Clear
120
+ </button>
121
+ </div>
122
+ </div>
123
+ </Story>
124
+
125
+ <Story name="Verification Flow">
126
+ <div class="max-w-md mx-auto p-6 bg-white dark:bg-gray-900 rounded-lg shadow-lg">
127
+ <div class="text-center mb-6">
128
+ <h2 class="text-2xl font-bold mb-2">Verify Your Phone</h2>
129
+ <p class="text-gray-500 dark:text-gray-400">
130
+ We've sent a 4-digit code to<br />
131
+ <span class="font-medium">+1 (555) 123-4567</span>
132
+ </p>
133
+ </div>
134
+
135
+ <div class="mb-6">
136
+ <OTPInput
137
+ bind:value={code4}
138
+ length={4}
139
+ oncomplete={(e) => alert(`Verifying code: ${e.code}`)}
140
+ />
141
+ </div>
142
+
143
+ <p class="text-center text-sm text-gray-500 dark:text-gray-400">
144
+ Didn't receive a code?
145
+ <button class="text-primary hover:underline">Resend</button>
146
+ </p>
147
+ </div>
148
+ </Story>
149
+
150
+ <Story name="With Auto-Submit">
151
+ <div class="max-w-md">
152
+ <p class="text-sm text-gray-500 dark:text-gray-400 mb-4">
153
+ Code will auto-submit when all digits are entered
154
+ </p>
155
+ <OTPInput
156
+ value={['', '', '', '', '', '']}
157
+ oncomplete={(e) => {
158
+ alert(`Auto-submitting code: ${e.code}`);
159
+ }}
160
+ />
161
+ </div>
162
+ </Story>
@@ -1,117 +1,117 @@
1
- <script lang="ts">
2
- interface CompleteEvent {
3
- code: string;
4
- }
5
- interface ChangeEvent {
6
- value: string[];
7
- code: string;
8
- }
9
- interface Props {
10
- value?: string[];
11
- length?: number;
12
- disabled?: boolean;
13
- oncomplete?: (event: CompleteEvent) => void;
14
- onchange?: (event: ChangeEvent) => void;
15
- }
16
-
17
- let {
18
- value = $bindable(["", "", "", "", "", ""]),
19
- length = 6,
20
- disabled = false,
21
- oncomplete,
22
- onchange,
23
- }: Props = $props();
24
-
25
- let inputs = $state<HTMLInputElement[]>([]);
26
-
27
- // Initialize value array if needed
28
- $effect(() => {
29
- if (value.length !== length) {
30
- value = Array(length).fill("");
31
- }
32
- });
33
-
34
- function handleInput(index: number, event: Event) {
35
- const target = event.target as HTMLInputElement;
36
- const inputValue = target.value;
37
-
38
- // Only allow digits
39
- if (!/^\d$/.test(inputValue) && inputValue !== "") {
40
- target.value = "";
41
- return;
42
- }
43
-
44
- value[index] = inputValue;
45
- value = [...value];
46
-
47
- // Auto-advance to next input
48
- if (inputValue && index < length - 1) {
49
- inputs[index + 1]?.focus();
50
- }
51
-
52
- // Check if complete
53
- if (value.every((digit) => digit !== "")) {
54
- oncomplete?.({ code: value.join("") });
55
- }
56
-
57
- onchange?.({ value, code: value.join("") });
58
- }
59
-
60
- function handleKeyDown(index: number, event: KeyboardEvent) {
61
- if (event.key === "Backspace" && !value[index] && index > 0) {
62
- inputs[index - 1]?.focus();
63
- }
64
- }
65
-
66
- function handlePaste(event: ClipboardEvent) {
67
- event.preventDefault();
68
- const pastedData = event.clipboardData?.getData("text").replace(/\D/g, "") || "";
69
-
70
- if (pastedData.length === length) {
71
- value = pastedData.split("");
72
- value = [...value];
73
-
74
- inputs[length - 1]?.focus();
75
-
76
- setTimeout(() => {
77
- oncomplete?.({ code: value.join("") });
78
- }, 100);
79
- }
80
- }
81
-
82
- export function focus() {
83
- inputs[0]?.focus();
84
- }
85
-
86
- export function clear() {
87
- value = Array(length).fill("");
88
- inputs[0]?.focus();
89
- }
90
- </script>
91
-
92
- <div
93
- class="flex justify-between gap-2 md:gap-3"
94
- role="group"
95
- aria-label="Enter {length}-digit verification code"
96
- >
97
- <span id="otp-instructions" class="sr-only">
98
- Enter one digit per box. Use backspace to navigate back. You can also paste a {length}-digit code.
99
- </span>
100
- {#each value as digit, index}
101
- <input
102
- bind:this={inputs[index]}
103
- type="text"
104
- inputmode="numeric"
105
- autocomplete="one-time-code"
106
- maxlength="1"
107
- value={digit}
108
- {disabled}
109
- aria-label="Digit {index + 1} of {length}"
110
- aria-describedby="otp-instructions"
111
- class="h-12 w-12 border-2 border-gray-300 bg-gray-50 p-0 text-center text-xl font-semibold leading-none text-gray-900 transition-colors focus:border-blue-500 focus:outline-hidden focus:ring-blue-500 disabled:cursor-not-allowed disabled:bg-gray-200 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500 dark:disabled:bg-gray-600 md:h-14 md:w-14 md:text-2xl rounded-lg"
112
- oninput={(e) => handleInput(index, e)}
113
- onkeydown={(e) => handleKeyDown(index, e)}
114
- onpaste={handlePaste}
115
- />
116
- {/each}
117
- </div>
1
+ <script lang="ts">
2
+ interface CompleteEvent {
3
+ code: string;
4
+ }
5
+ interface ChangeEvent {
6
+ value: string[];
7
+ code: string;
8
+ }
9
+ interface Props {
10
+ value?: string[];
11
+ length?: number;
12
+ disabled?: boolean;
13
+ oncomplete?: (event: CompleteEvent) => void;
14
+ onchange?: (event: ChangeEvent) => void;
15
+ }
16
+
17
+ let {
18
+ value = $bindable(["", "", "", "", "", ""]),
19
+ length = 6,
20
+ disabled = false,
21
+ oncomplete,
22
+ onchange,
23
+ }: Props = $props();
24
+
25
+ let inputs = $state<HTMLInputElement[]>([]);
26
+
27
+ // Initialize value array if needed
28
+ $effect(() => {
29
+ if (value.length !== length) {
30
+ value = Array(length).fill("");
31
+ }
32
+ });
33
+
34
+ function handleInput(index: number, event: Event) {
35
+ const target = event.target as HTMLInputElement;
36
+ const inputValue = target.value;
37
+
38
+ // Only allow digits
39
+ if (!/^\d$/.test(inputValue) && inputValue !== "") {
40
+ target.value = "";
41
+ return;
42
+ }
43
+
44
+ value[index] = inputValue;
45
+ value = [...value];
46
+
47
+ // Auto-advance to next input
48
+ if (inputValue && index < length - 1) {
49
+ inputs[index + 1]?.focus();
50
+ }
51
+
52
+ // Check if complete
53
+ if (value.every((digit) => digit !== "")) {
54
+ oncomplete?.({ code: value.join("") });
55
+ }
56
+
57
+ onchange?.({ value, code: value.join("") });
58
+ }
59
+
60
+ function handleKeyDown(index: number, event: KeyboardEvent) {
61
+ if (event.key === "Backspace" && !value[index] && index > 0) {
62
+ inputs[index - 1]?.focus();
63
+ }
64
+ }
65
+
66
+ function handlePaste(event: ClipboardEvent) {
67
+ event.preventDefault();
68
+ const pastedData = event.clipboardData?.getData("text").replace(/\D/g, "") || "";
69
+
70
+ if (pastedData.length === length) {
71
+ value = pastedData.split("");
72
+ value = [...value];
73
+
74
+ inputs[length - 1]?.focus();
75
+
76
+ setTimeout(() => {
77
+ oncomplete?.({ code: value.join("") });
78
+ }, 100);
79
+ }
80
+ }
81
+
82
+ export function focus() {
83
+ inputs[0]?.focus();
84
+ }
85
+
86
+ export function clear() {
87
+ value = Array(length).fill("");
88
+ inputs[0]?.focus();
89
+ }
90
+ </script>
91
+
92
+ <div
93
+ class="flex justify-between gap-2 md:gap-3"
94
+ role="group"
95
+ aria-label="Enter {length}-digit verification code"
96
+ >
97
+ <span id="otp-instructions" class="sr-only">
98
+ Enter one digit per box. Use backspace to navigate back. You can also paste a {length}-digit code.
99
+ </span>
100
+ {#each value as digit, index}
101
+ <input
102
+ bind:this={inputs[index]}
103
+ type="text"
104
+ inputmode="numeric"
105
+ autocomplete="one-time-code"
106
+ maxlength="1"
107
+ value={digit}
108
+ {disabled}
109
+ aria-label="Digit {index + 1} of {length}"
110
+ aria-describedby="otp-instructions"
111
+ class="h-12 w-12 border-2 border-gray-300 bg-gray-50 p-0 text-center text-xl font-semibold leading-none text-gray-900 transition-colors focus:border-blue-500 focus:outline-hidden focus:ring-blue-500 disabled:cursor-not-allowed disabled:bg-gray-200 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500 dark:disabled:bg-gray-600 md:h-14 md:w-14 md:text-2xl rounded-lg"
112
+ oninput={(e) => handleInput(index, e)}
113
+ onkeydown={(e) => handleKeyDown(index, e)}
114
+ onpaste={handlePaste}
115
+ />
116
+ {/each}
117
+ </div>
@@ -77,14 +77,14 @@
77
77
  onblur,
78
78
  onfocus,
79
79
  }: Props = $props();
80
-
81
- // Password strength tracking
82
- let strengthScore = $state(-1);
83
- let strengthText = $state('');
84
- let strengthColor = $state('');
85
- </script>
86
-
87
- <div class={className}>
80
+
81
+ // Password strength tracking
82
+ let strengthScore = $state(-1);
83
+ let strengthText = $state('');
84
+ let strengthColor = $state('');
85
+ </script>
86
+
87
+ <div class={className}>
88
88
  <Input
89
89
  type="password"
90
90
  {id}
@@ -105,17 +105,17 @@
105
105
  {onblur}
106
106
  {onfocus}
107
107
  />
108
-
109
- {#if showStrength && value}
110
- <PasswordStrengthIndicator
111
- password={value}
112
- bind:score={strengthScore}
113
- bind:strengthText
114
- bind:textColor={strengthColor}
115
- >
116
- <p class="text-xs {strengthColor}">
117
- Password strength: {strengthText}
118
- </p>
119
- </PasswordStrengthIndicator>
120
- {/if}
121
- </div>
108
+
109
+ {#if showStrength && value}
110
+ <PasswordStrengthIndicator
111
+ password={value}
112
+ bind:score={strengthScore}
113
+ bind:strengthText
114
+ bind:textColor={strengthColor}
115
+ >
116
+ <p class="text-xs {strengthColor}">
117
+ Password strength: {strengthText}
118
+ </p>
119
+ </PasswordStrengthIndicator>
120
+ {/if}
121
+ </div>