@getmicdrop/svelte-components 5.3.3 → 5.3.10

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 (194) hide show
  1. package/dist/calendar/AboutShow/AboutShow.svelte +9 -8
  2. package/dist/calendar/AboutShow/AboutShow.svelte.d.ts.map +1 -1
  3. package/dist/calendar/Calendar/MiniMonthCalendar.svelte +19 -18
  4. package/dist/calendar/Calendar/MiniMonthCalendar.svelte.d.ts +6 -6
  5. package/dist/calendar/Calendar/MiniMonthCalendar.svelte.d.ts.map +1 -1
  6. package/dist/calendar/FAQs/FAQs.svelte +6 -5
  7. package/dist/calendar/FAQs/FAQs.svelte.d.ts.map +1 -1
  8. package/dist/calendar/MonthSwitcher/MonthSwitcher.svelte +3 -2
  9. package/dist/calendar/MonthSwitcher/MonthSwitcher.svelte.d.ts.map +1 -1
  10. package/dist/calendar/OrderSummary/OrderSummary.svelte +21 -20
  11. package/dist/calendar/OrderSummary/OrderSummary.svelte.d.ts +2 -2
  12. package/dist/calendar/OrderSummary/OrderSummary.svelte.d.ts.map +1 -1
  13. package/dist/calendar/PublicCard/PublicCard.svelte +9 -11
  14. package/dist/calendar/PublicCard/PublicCard.svelte.d.ts +2 -2
  15. package/dist/calendar/PublicCard/PublicCard.svelte.d.ts.map +1 -1
  16. package/dist/calendar/ShowCard/ShowCard.svelte +13 -12
  17. package/dist/calendar/ShowCard/ShowCard.svelte.d.ts +2 -2
  18. package/dist/calendar/ShowCard/ShowCard.svelte.d.ts.map +1 -1
  19. package/dist/calendar/ShowTimeCard/ShowTimeCard.svelte +5 -3
  20. package/dist/calendar/ShowTimeCard/ShowTimeCard.svelte.d.ts.map +1 -1
  21. package/dist/components/Layout/Section.svelte +4 -4
  22. package/dist/components/Layout/Section.svelte.d.ts.map +1 -1
  23. package/dist/index.d.ts +3 -0
  24. package/dist/index.js +9 -0
  25. package/dist/patterns/data/DataTable.svelte +4 -2
  26. package/dist/patterns/data/DataTable.svelte.d.ts.map +1 -1
  27. package/dist/patterns/forms/FormSection.svelte +4 -2
  28. package/dist/patterns/forms/FormSection.svelte.d.ts.map +1 -1
  29. package/dist/patterns/navigation/BottomNav.svelte +4 -3
  30. package/dist/patterns/navigation/BottomNav.svelte.d.ts.map +1 -1
  31. package/dist/patterns/navigation/Header.svelte +49 -37
  32. package/dist/patterns/navigation/Header.svelte.d.ts.map +1 -1
  33. package/dist/patterns/page/PageHeader.svelte +3 -2
  34. package/dist/patterns/page/PageHeader.svelte.d.ts.map +1 -1
  35. package/dist/patterns/page/PageLayout.svelte +3 -2
  36. package/dist/patterns/page/PageLayout.svelte.d.ts.map +1 -1
  37. package/dist/patterns/page/PageLoader.svelte +2 -1
  38. package/dist/patterns/page/PageLoader.svelte.d.ts.map +1 -1
  39. package/dist/patterns/page/SectionHeader.svelte +5 -3
  40. package/dist/patterns/page/SectionHeader.svelte.d.ts.map +1 -1
  41. package/dist/primitives/Accordion/Accordion.stories.svelte +75 -0
  42. package/dist/primitives/Accordion/Accordion.stories.svelte.d.ts +28 -0
  43. package/dist/primitives/Accordion/Accordion.stories.svelte.d.ts.map +1 -0
  44. package/dist/primitives/Accordion/Accordion.svelte +2 -1
  45. package/dist/primitives/Accordion/Accordion.svelte.d.ts.map +1 -1
  46. package/dist/primitives/Accordion/AccordionItem.svelte +5 -4
  47. package/dist/primitives/Accordion/AccordionItem.svelte.d.ts.map +1 -1
  48. package/dist/primitives/Alert/Alert.stories.svelte +88 -0
  49. package/dist/primitives/Alert/Alert.stories.svelte.d.ts +28 -0
  50. package/dist/primitives/Alert/Alert.stories.svelte.d.ts.map +1 -0
  51. package/dist/primitives/Avatar/Avatar.stories.svelte +94 -0
  52. package/dist/primitives/Avatar/Avatar.stories.svelte.d.ts +28 -0
  53. package/dist/primitives/Avatar/Avatar.stories.svelte.d.ts.map +1 -0
  54. package/dist/primitives/BottomSheet/BottomSheet.svelte +2 -1
  55. package/dist/primitives/BottomSheet/BottomSheet.svelte.d.ts.map +1 -1
  56. package/dist/primitives/Breadcrumb/Breadcrumb.svelte +7 -6
  57. package/dist/primitives/Breadcrumb/Breadcrumb.svelte.d.ts.map +1 -1
  58. package/dist/primitives/Button/Button.svelte +94 -43
  59. package/dist/primitives/Button/Button.svelte.d.ts +5 -3
  60. package/dist/primitives/Button/Button.svelte.d.ts.map +1 -1
  61. package/dist/primitives/Button/ButtonSaveDemo.svelte +2 -1
  62. package/dist/primitives/Button/ButtonSaveDemo.svelte.d.ts.map +1 -1
  63. package/dist/primitives/Card.svelte +1 -1
  64. package/dist/primitives/Checkbox/Checkbox.stories.svelte +84 -0
  65. package/dist/primitives/Checkbox/Checkbox.stories.svelte.d.ts +28 -0
  66. package/dist/primitives/Checkbox/Checkbox.stories.svelte.d.ts.map +1 -0
  67. package/dist/primitives/DarkModeToggle.svelte +43 -44
  68. package/dist/primitives/DarkModeToggle.svelte.d.ts.map +1 -1
  69. package/dist/primitives/Drawer/Drawer.stories.svelte +100 -0
  70. package/dist/primitives/Drawer/Drawer.stories.svelte.d.ts +28 -0
  71. package/dist/primitives/Drawer/Drawer.stories.svelte.d.ts.map +1 -0
  72. package/dist/primitives/Drawer/Drawer.svelte +121 -47
  73. package/dist/primitives/Drawer/Drawer.svelte.d.ts +4 -0
  74. package/dist/primitives/Drawer/Drawer.svelte.d.ts.map +1 -1
  75. package/dist/primitives/Dropdown/Dropdown.stories.svelte +137 -0
  76. package/dist/primitives/Dropdown/Dropdown.stories.svelte.d.ts +28 -0
  77. package/dist/primitives/Dropdown/Dropdown.stories.svelte.d.ts.map +1 -0
  78. package/dist/primitives/Dropdown/Dropdown.svelte +13 -15
  79. package/dist/primitives/Dropdown/Dropdown.svelte.d.ts.map +1 -1
  80. package/dist/primitives/Icons/Icon.svelte +2 -1
  81. package/dist/primitives/Icons/Icon.svelte.d.ts.map +1 -1
  82. package/dist/primitives/Input/Input.svelte +41 -80
  83. package/dist/primitives/Input/Input.svelte.d.ts +4 -6
  84. package/dist/primitives/Input/Input.svelte.d.ts.map +1 -1
  85. package/dist/primitives/Input/Select.stories.svelte +112 -0
  86. package/dist/primitives/Input/Select.stories.svelte.d.ts +28 -0
  87. package/dist/primitives/Input/Select.stories.svelte.d.ts.map +1 -0
  88. package/dist/primitives/Input/Select.svelte +66 -13
  89. package/dist/primitives/Input/Select.svelte.d.ts +2 -0
  90. package/dist/primitives/Input/Select.svelte.d.ts.map +1 -1
  91. package/dist/primitives/Input/Textarea.stories.svelte +137 -0
  92. package/dist/primitives/Input/Textarea.stories.svelte.d.ts +28 -0
  93. package/dist/primitives/Input/Textarea.stories.svelte.d.ts.map +1 -0
  94. package/dist/primitives/Input/Textarea.svelte +5 -3
  95. package/dist/primitives/Input/Textarea.svelte.d.ts.map +1 -1
  96. package/dist/primitives/Modal/Modal.svelte +13 -1
  97. package/dist/primitives/Modal/Modal.svelte.d.ts.map +1 -1
  98. package/dist/primitives/Pagination/Pagination.stories.svelte +76 -0
  99. package/dist/primitives/Pagination/Pagination.stories.svelte.d.ts +28 -0
  100. package/dist/primitives/Pagination/Pagination.stories.svelte.d.ts.map +1 -0
  101. package/dist/primitives/Pagination/Pagination.svelte +6 -5
  102. package/dist/primitives/Pagination/Pagination.svelte.d.ts +1 -1
  103. package/dist/primitives/Pagination/Pagination.svelte.d.ts.map +1 -1
  104. package/dist/primitives/Radio/Radio.stories.svelte +80 -0
  105. package/dist/primitives/Radio/Radio.stories.svelte.d.ts +28 -0
  106. package/dist/primitives/Radio/Radio.stories.svelte.d.ts.map +1 -0
  107. package/dist/primitives/Skeleton/Skeleton.stories.svelte +151 -0
  108. package/dist/primitives/Skeleton/Skeleton.stories.svelte.d.ts +28 -0
  109. package/dist/primitives/Skeleton/Skeleton.stories.svelte.d.ts.map +1 -0
  110. package/dist/primitives/Tabs/Tabs.stories.svelte +112 -0
  111. package/dist/primitives/Tabs/Tabs.stories.svelte.d.ts +28 -0
  112. package/dist/primitives/Tabs/Tabs.stories.svelte.d.ts.map +1 -0
  113. package/dist/primitives/Tabs/Tabs.svelte +5 -4
  114. package/dist/primitives/Tabs/Tabs.svelte.d.ts.map +1 -1
  115. package/dist/primitives/Toggle.svelte +4 -4
  116. package/dist/primitives/ValidationError.spec.js +25 -1
  117. package/dist/primitives/ValidationError.stories.svelte +24 -0
  118. package/dist/primitives/ValidationError.stories.svelte.d.ts.map +1 -1
  119. package/dist/primitives/ValidationError.svelte +8 -4
  120. package/dist/primitives/ValidationError.svelte.d.ts +2 -0
  121. package/dist/primitives/ValidationError.svelte.d.ts.map +1 -1
  122. package/dist/recipes/CropImage/CropImage.svelte +12 -7
  123. package/dist/recipes/CropImage/CropImage.svelte.d.ts.map +1 -1
  124. package/dist/recipes/ImageUploader/ImageUploader.stories.svelte +125 -0
  125. package/dist/recipes/ImageUploader/ImageUploader.stories.svelte.d.ts +28 -0
  126. package/dist/recipes/ImageUploader/ImageUploader.stories.svelte.d.ts.map +1 -0
  127. package/dist/recipes/ImageUploader/ImageUploader.svelte +939 -0
  128. package/dist/recipes/ImageUploader/ImageUploader.svelte.d.ts +60 -0
  129. package/dist/recipes/ImageUploader/ImageUploader.svelte.d.ts.map +1 -0
  130. package/dist/recipes/SuperLogin/SuperLogin.svelte +71 -63
  131. package/dist/recipes/SuperLogin/SuperLogin.svelte.d.ts.map +1 -1
  132. package/dist/recipes/feedback/EmptyState/EmptyState.svelte +5 -3
  133. package/dist/recipes/feedback/EmptyState/EmptyState.svelte.d.ts.map +1 -1
  134. package/dist/recipes/fields/CheckboxField.svelte +3 -2
  135. package/dist/recipes/fields/CheckboxField.svelte.d.ts.map +1 -1
  136. package/dist/recipes/fields/FormField.svelte +12 -4
  137. package/dist/recipes/fields/FormField.svelte.d.ts +3 -1
  138. package/dist/recipes/fields/FormField.svelte.d.ts.map +1 -1
  139. package/dist/recipes/fields/RadioGroup.svelte +13 -4
  140. package/dist/recipes/fields/RadioGroup.svelte.d.ts +4 -1
  141. package/dist/recipes/fields/RadioGroup.svelte.d.ts.map +1 -1
  142. package/dist/recipes/fields/SelectField.svelte +12 -3
  143. package/dist/recipes/fields/SelectField.svelte.d.ts +4 -1
  144. package/dist/recipes/fields/SelectField.svelte.d.ts.map +1 -1
  145. package/dist/recipes/fields/TextareaField.svelte +2 -1
  146. package/dist/recipes/fields/TextareaField.svelte.d.ts.map +1 -1
  147. package/dist/recipes/fields/ToggleField.svelte +3 -2
  148. package/dist/recipes/fields/ToggleField.svelte.d.ts.map +1 -1
  149. package/dist/recipes/inputs/MultiSelect.svelte +8 -7
  150. package/dist/recipes/inputs/MultiSelect.svelte.d.ts.map +1 -1
  151. package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.svelte +9 -9
  152. package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.svelte.d.ts.map +1 -1
  153. package/dist/recipes/inputs/Search.svelte +7 -6
  154. package/dist/recipes/inputs/Search.svelte.d.ts.map +1 -1
  155. package/dist/recipes/modals/AlertModal.svelte +3 -2
  156. package/dist/recipes/modals/AlertModal.svelte.d.ts.map +1 -1
  157. package/dist/recipes/modals/ConfirmationModal.svelte +4 -3
  158. package/dist/recipes/modals/ConfirmationModal.svelte.d.ts.map +1 -1
  159. package/dist/recipes/modals/InputModal.svelte +10 -8
  160. package/dist/recipes/modals/InputModal.svelte.d.ts.map +1 -1
  161. package/dist/recipes/modals/ModalStateManager.svelte +4 -3
  162. package/dist/recipes/modals/ModalStateManager.svelte.d.ts.map +1 -1
  163. package/dist/recipes/modals/StatusModal.svelte +5 -4
  164. package/dist/recipes/modals/StatusModal.svelte.d.ts.map +1 -1
  165. package/dist/stories/ButtonAuditReview.svelte +361 -397
  166. package/dist/stories/ButtonAuditReview.svelte.d.ts +24 -4
  167. package/dist/stories/ButtonAuditReview.svelte.d.ts.map +1 -1
  168. package/dist/stories/ComponentConsolidation.stories.svelte +276 -188
  169. package/dist/stories/ComponentConsolidation.stories.svelte.d.ts.map +1 -1
  170. package/dist/stories/PatternsGallery.stories.svelte +19 -0
  171. package/dist/stories/PatternsGallery.stories.svelte.d.ts +28 -0
  172. package/dist/stories/PatternsGallery.stories.svelte.d.ts.map +1 -0
  173. package/dist/stories/PatternsGallery.svelte +388 -0
  174. package/dist/stories/PatternsGallery.svelte.d.ts +4 -0
  175. package/dist/stories/PatternsGallery.svelte.d.ts.map +1 -0
  176. package/dist/stories/PrimitivesGallery.stories.svelte +19 -0
  177. package/dist/stories/PrimitivesGallery.stories.svelte.d.ts +28 -0
  178. package/dist/stories/PrimitivesGallery.stories.svelte.d.ts.map +1 -0
  179. package/dist/stories/PrimitivesGallery.svelte +752 -0
  180. package/dist/stories/PrimitivesGallery.svelte.d.ts +4 -0
  181. package/dist/stories/PrimitivesGallery.svelte.d.ts.map +1 -0
  182. package/dist/stories/RecipesGallery.stories.svelte +19 -0
  183. package/dist/stories/RecipesGallery.stories.svelte.d.ts +28 -0
  184. package/dist/stories/RecipesGallery.stories.svelte.d.ts.map +1 -0
  185. package/dist/stories/RecipesGallery.svelte +441 -0
  186. package/dist/stories/RecipesGallery.svelte.d.ts +4 -0
  187. package/dist/stories/RecipesGallery.svelte.d.ts.map +1 -0
  188. package/dist/tokens/index.d.ts +4 -8
  189. package/dist/tokens/index.d.ts.map +1 -1
  190. package/dist/tokens/index.js +4 -8
  191. package/dist/tokens/typography.d.ts +76 -169
  192. package/dist/tokens/typography.d.ts.map +1 -1
  193. package/dist/tokens/typography.js +93 -62
  194. package/package.json +6 -3
@@ -0,0 +1,112 @@
1
+ <script module>
2
+ import { defineMeta } from '@storybook/addon-svelte-csf';
3
+ import Select from './Select.svelte';
4
+
5
+ const { Story } = defineMeta({
6
+ title: 'Primitives/Select',
7
+ component: Select,
8
+ tags: ['autodocs'],
9
+ argTypes: {
10
+ label: { control: 'text' },
11
+ disabled: { control: 'boolean' },
12
+ required: { control: 'boolean' },
13
+ errorText: { control: 'text' },
14
+ },
15
+ parameters: {
16
+ docs: {
17
+ description: {
18
+ component: 'Native select dropdown component.',
19
+ },
20
+ },
21
+ },
22
+ });
23
+
24
+ let value = $state('');
25
+ </script>
26
+
27
+ <Story name="Default">
28
+ {#snippet template()}
29
+ <div class="max-w-xs">
30
+ <Select label="Country">
31
+ <option value="">Select a country</option>
32
+ <option value="us">United States</option>
33
+ <option value="uk">United Kingdom</option>
34
+ <option value="ca">Canada</option>
35
+ <option value="au">Australia</option>
36
+ </Select>
37
+ </div>
38
+ {/snippet}
39
+ </Story>
40
+
41
+ <Story name="With Value">
42
+ {#snippet template()}
43
+ <div class="max-w-xs">
44
+ <Select label="Size" bind:value={value}>
45
+ <option value="">Choose size</option>
46
+ <option value="sm">Small</option>
47
+ <option value="md">Medium</option>
48
+ <option value="lg">Large</option>
49
+ </Select>
50
+ <p class="text-sm text-gray-500 mt-2">Selected: {value || 'none'}</p>
51
+ </div>
52
+ {/snippet}
53
+ </Story>
54
+
55
+ <Story name="With Error">
56
+ {#snippet template()}
57
+ <div class="max-w-xs">
58
+ <Select label="Category" errorText="Please select a category">
59
+ <option value="">Select category</option>
60
+ <option value="comedy">Comedy</option>
61
+ <option value="music">Music</option>
62
+ </Select>
63
+ </div>
64
+ {/snippet}
65
+ </Story>
66
+
67
+ <Story name="Disabled">
68
+ {#snippet template()}
69
+ <div class="max-w-xs">
70
+ <Select label="Disabled Select" disabled>
71
+ <option value="">Cannot select</option>
72
+ </Select>
73
+ </div>
74
+ {/snippet}
75
+ </Story>
76
+
77
+ <Story name="Required">
78
+ {#snippet template()}
79
+ <div class="max-w-xs">
80
+ <Select label="Required Field" required>
81
+ <option value="">Choose an option</option>
82
+ <option value="1">Option 1</option>
83
+ <option value="2">Option 2</option>
84
+ </Select>
85
+ </div>
86
+ {/snippet}
87
+ </Story>
88
+
89
+ <Story name="All States">
90
+ {#snippet template()}
91
+ <div class="grid grid-cols-2 gap-6 max-w-xl">
92
+ <Select label="Default">
93
+ <option value="">Select option</option>
94
+ <option value="1">Option 1</option>
95
+ </Select>
96
+
97
+ <Select label="With Error" errorText="This field is required">
98
+ <option value="">Select option</option>
99
+ <option value="1">Option 1</option>
100
+ </Select>
101
+
102
+ <Select label="Disabled" disabled>
103
+ <option value="">Cannot select</option>
104
+ </Select>
105
+
106
+ <Select label="Required" required>
107
+ <option value="">Select option</option>
108
+ <option value="1">Option 1</option>
109
+ </Select>
110
+ </div>
111
+ {/snippet}
112
+ </Story>
@@ -0,0 +1,28 @@
1
+ export default Select;
2
+ type Select = SvelteComponent<{
3
+ [x: string]: never;
4
+ }, {
5
+ [evt: string]: CustomEvent<any>;
6
+ }, {}> & {
7
+ $$bindings?: string | undefined;
8
+ };
9
+ declare const Select: $$__sveltets_2_IsomorphicComponent<{
10
+ [x: string]: never;
11
+ }, {
12
+ [evt: string]: CustomEvent<any>;
13
+ }, {}, {}, string>;
14
+ import Select from './Select.svelte';
15
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
16
+ new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
17
+ $$bindings?: Bindings;
18
+ } & Exports;
19
+ (internal: unknown, props: {
20
+ $$events?: Events;
21
+ $$slots?: Slots;
22
+ }): Exports & {
23
+ $set?: any;
24
+ $on?: any;
25
+ };
26
+ z_$$bindings?: Bindings;
27
+ }
28
+ //# sourceMappingURL=Select.stories.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Select.stories.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Input/Select.stories.svelte.js"],"names":[],"mappings":";;;;;;;;AA8HA;;;;mBAAkH;mBA1H7F,iBAAiB;6CAiHO,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,OAAO,OAAO,QAAQ;IAC3L,cAAc,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,WAAW,OAAO,SAAS;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IACtG,eAAe,QAAQ,CAAC"}
@@ -1,6 +1,8 @@
1
1
  <script>
2
- import { onMount } from "svelte";
3
- import { ChevronDownOutline, CheckOutline } from "../Icons";
2
+ import { onMount, tick } from "svelte";
3
+ import { ChevronDownOutline } from "../Icons";
4
+ import { portal as portalAction } from "../../utils/portal.js";
5
+ import { typography } from "../../tokens/typography";
4
6
 
5
7
  let {
6
8
  value = $bindable(""),
@@ -13,6 +15,7 @@
13
15
  name = "",
14
16
  id = "",
15
17
  size = "md",
18
+ portal = false,
16
19
  onchange,
17
20
  ...restProps
18
21
  } = $props();
@@ -21,6 +24,7 @@
21
24
  let triggerElement = $state(null);
22
25
  let dropdownElement = $state(null);
23
26
  let focusedIndex = $state(-1);
27
+ let dropdownPosition = $state({ top: 0, left: 0, width: 0 });
24
28
 
25
29
  const instanceId = Math.random().toString(36).substring(2, 9);
26
30
 
@@ -35,12 +39,26 @@
35
39
 
36
40
  let sizeClass = $derived(sizeClasses[size] || sizeClasses.md);
37
41
 
38
- function toggle() {
42
+ function updateDropdownPosition() {
43
+ if (!triggerElement || !portal) return;
44
+ const rect = triggerElement.getBoundingClientRect();
45
+ dropdownPosition = {
46
+ top: rect.bottom + 4,
47
+ left: rect.left,
48
+ width: rect.width
49
+ };
50
+ }
51
+
52
+ async function toggle() {
39
53
  if (disabled) return;
40
54
  isOpen = !isOpen;
41
55
  if (isOpen) {
42
56
  focusedIndex = items.findIndex((item) => item.value === value);
43
57
  window.dispatchEvent(new CustomEvent('select-opened', { detail: { instanceId } }));
58
+ if (portal) {
59
+ await tick();
60
+ updateDropdownPosition();
61
+ }
44
62
  }
45
63
  }
46
64
 
@@ -112,9 +130,20 @@
112
130
  onMount(() => {
113
131
  document.addEventListener("click", handleClickOutside, true);
114
132
  window.addEventListener("select-opened", handleOtherSelectOpened);
133
+
134
+ // Update position on scroll/resize when portal is enabled
135
+ if (portal) {
136
+ window.addEventListener("scroll", updateDropdownPosition, true);
137
+ window.addEventListener("resize", updateDropdownPosition);
138
+ }
139
+
115
140
  return () => {
116
141
  document.removeEventListener("click", handleClickOutside, true);
117
142
  window.removeEventListener("select-opened", handleOtherSelectOpened);
143
+ if (portal) {
144
+ window.removeEventListener("scroll", updateDropdownPosition, true);
145
+ window.removeEventListener("resize", updateDropdownPosition);
146
+ }
118
147
  };
119
148
  });
120
149
  </script>
@@ -122,7 +151,7 @@
122
151
  <div class="w-full flex flex-col gap-2" {...restProps}>
123
152
  {#if label}
124
153
  <div class="flex justify-start items-center gap-1">
125
- <label for={id || name} class="text-sm font-medium text-gray-900 dark:text-white">
154
+ <label for={id || name} class={typography.label}>
126
155
  {label}{#if required}<span class="text-red-500 font-medium text-sm ml-0.5">*</span>{/if}
127
156
  </label>
128
157
  </div>
@@ -134,7 +163,7 @@
134
163
  bind:this={triggerElement}
135
164
  {id}
136
165
  {name}
137
- class="flex items-center justify-between w-full {sizeClass} bg-gray-50 dark:bg-gray-700 border rounded-lg cursor-pointer transition-colors text-left focus:outline-none focus:ring-4 focus:ring-blue-300 dark:focus:ring-blue-800 {error ? 'border-red-500 dark:border-red-500' : 'border-gray-300 dark:border-gray-600 hover:border-blue-500 dark:hover:border-blue-500'} {disabled ? 'opacity-50 cursor-not-allowed' : ''} {!selectedItem ? 'text-gray-500 dark:text-gray-400' : 'text-gray-900 dark:text-white'}"
166
+ class="flex items-center justify-between w-full {sizeClass} bg-gray-50 dark:bg-gray-700 border rounded-lg cursor-pointer transition-colors text-left focus:outline-none focus:ring-4 focus:ring-blue-300 dark:focus:ring-blue-800 {error ? 'border-red-500 dark:border-red-500' : 'border-gray-300 dark:border-gray-600 hover:border-blue-500 dark:hover:border-blue-500'} {disabled ? 'opacity-50 cursor-not-allowed' : ''} {!selectedItem ? `${typography.textMuted}` : `${typography.body}`}"
138
167
  {disabled}
139
168
  aria-haspopup="listbox"
140
169
  aria-expanded={isOpen}
@@ -142,10 +171,10 @@
142
171
  onkeydown={handleKeydown}
143
172
  >
144
173
  <span class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap">{displayText}</span>
145
- <ChevronDownOutline class="w-4 h-4 shrink-0 text-gray-500 dark:text-gray-400 transition-transform duration-200 {isOpen ? 'rotate-180' : ''}" />
174
+ <ChevronDownOutline class="w-4 h-4 shrink-0 {typography.iconMuted} transition-transform duration-200 {isOpen ? 'rotate-180' : ''}" />
146
175
  </button>
147
176
 
148
- {#if isOpen}
177
+ {#if isOpen && !portal}
149
178
  <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
150
179
  <ul
151
180
  bind:this={dropdownElement}
@@ -157,16 +186,13 @@
157
186
  <!-- svelte-ignore a11y_click_events_have_key_events -->
158
187
  <li
159
188
  id="{id || name}-option-{index}"
160
- class="flex items-center justify-between px-4 py-2 cursor-pointer text-sm transition-colors {item.value === value ? 'font-semibold text-gray-900 dark:text-white' : 'text-gray-700 dark:text-gray-300'} {index === focusedIndex ? 'bg-gray-100 dark:bg-gray-600' : 'hover:bg-gray-100 dark:hover:bg-gray-600'}"
189
+ class={`px-4 py-2 cursor-pointer ${typography.sm} transition-colors ${item.value === value ? '' : `${typography.textMuted}`} ${index === focusedIndex ? 'bg-gray-100 dark:bg-gray-600' : 'hover:bg-gray-100 dark:hover:bg-gray-600'}`}
161
190
  role="option"
162
191
  aria-selected={item.value === value}
163
192
  onclick={() => selectItem(item)}
164
193
  onmouseenter={() => (focusedIndex = index)}
165
194
  >
166
- <span class="flex-1">{item.name}</span>
167
- {#if item.value === value}
168
- <CheckOutline class="w-4 h-4 shrink-0 text-blue-600" />
169
- {/if}
195
+ {item.name}
170
196
  </li>
171
197
  {/each}
172
198
  </ul>
@@ -174,6 +200,33 @@
174
200
  </div>
175
201
 
176
202
  {#if error}
177
- <p class="text-sm text-red-500">{error}</p>
203
+ <p class={typography.error}>{error}</p>
178
204
  {/if}
179
205
  </div>
206
+
207
+ {#if isOpen && portal}
208
+ <!-- Portal dropdown - truly moved to document.body to escape overflow containers and transforms -->
209
+ <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
210
+ <ul
211
+ bind:this={dropdownElement}
212
+ use:portalAction
213
+ class="fixed z-[9999] bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-lg shadow-lg max-h-60 overflow-y-auto py-1"
214
+ style="top: {dropdownPosition.top}px; left: {dropdownPosition.left}px; width: {dropdownPosition.width}px;"
215
+ role="listbox"
216
+ tabindex="-1"
217
+ >
218
+ {#each items as item, index}
219
+ <!-- svelte-ignore a11y_click_events_have_key_events -->
220
+ <li
221
+ id="{id || name}-option-{index}"
222
+ class={`px-4 py-2 cursor-pointer ${typography.sm} transition-colors ${item.value === value ? '' : `${typography.textMuted}`} ${index === focusedIndex ? 'bg-gray-100 dark:bg-gray-600' : 'hover:bg-gray-100 dark:hover:bg-gray-600'}`}
223
+ role="option"
224
+ aria-selected={item.value === value}
225
+ onclick={() => selectItem(item)}
226
+ onmouseenter={() => (focusedIndex = index)}
227
+ >
228
+ {item.name}
229
+ </li>
230
+ {/each}
231
+ </ul>
232
+ {/if}
@@ -14,6 +14,7 @@ declare const Select: import("svelte").Component<{
14
14
  name?: string;
15
15
  id?: string;
16
16
  size?: string;
17
+ portal?: boolean;
17
18
  onchange: any;
18
19
  } & Record<string, any>, {}, "value">;
19
20
  type $$ComponentProps = {
@@ -27,6 +28,7 @@ type $$ComponentProps = {
27
28
  name?: string;
28
29
  id?: string;
29
30
  size?: string;
31
+ portal?: boolean;
30
32
  onchange: any;
31
33
  } & Record<string, any>;
32
34
  //# sourceMappingURL=Select.svelte.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Select.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Input/Select.svelte.js"],"names":[],"mappings":";;;;;AAqKA;YA3J6B,MAAM;YAAU,GAAG,EAAE;kBAAgB,MAAM;YAAU,MAAM;eAAa,OAAO;eAAa,OAAO;YAAU,MAAM;WAAS,MAAM;SAAO,MAAM;WAAS,MAAM;cAAY,GAAG;sCA2JrJ;wBA3JlC;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC"}
1
+ {"version":3,"file":"Select.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Input/Select.svelte.js"],"names":[],"mappings":";;;;;AA8MA;YAhM6B,MAAM;YAAU,GAAG,EAAE;kBAAgB,MAAM;YAAU,MAAM;eAAa,OAAO;eAAa,OAAO;YAAU,MAAM;WAAS,MAAM;SAAO,MAAM;WAAS,MAAM;aAAW,OAAO;cAAY,GAAG;sCAgMvK;wBAhMlC;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC"}
@@ -0,0 +1,137 @@
1
+ <script module>
2
+ import { defineMeta } from '@storybook/addon-svelte-csf';
3
+ import Textarea from './Textarea.svelte';
4
+
5
+ const { Story } = defineMeta({
6
+ title: 'Primitives/Textarea',
7
+ component: Textarea,
8
+ tags: ['autodocs'],
9
+ argTypes: {
10
+ label: { control: 'text' },
11
+ placeholder: { control: 'text' },
12
+ rows: { control: 'number' },
13
+ disabled: { control: 'boolean' },
14
+ required: { control: 'boolean' },
15
+ maxlength: { control: 'number' },
16
+ errorText: { control: 'text' },
17
+ },
18
+ parameters: {
19
+ docs: {
20
+ description: {
21
+ component: 'Multi-line text input component.',
22
+ },
23
+ },
24
+ },
25
+ });
26
+
27
+ let value = $state('');
28
+ </script>
29
+
30
+ <Story name="Default">
31
+ {#snippet template()}
32
+ <div class="max-w-md">
33
+ <Textarea
34
+ label="Description"
35
+ placeholder="Enter your description..."
36
+ />
37
+ </div>
38
+ {/snippet}
39
+ </Story>
40
+
41
+ <Story name="With Value">
42
+ {#snippet template()}
43
+ <div class="max-w-md">
44
+ <Textarea
45
+ label="Bio"
46
+ placeholder="Tell us about yourself..."
47
+ bind:value={value}
48
+ />
49
+ <p class="text-sm text-gray-500 mt-2">{value.length} characters</p>
50
+ </div>
51
+ {/snippet}
52
+ </Story>
53
+
54
+ <Story name="With Max Length">
55
+ {#snippet template()}
56
+ <div class="max-w-md">
57
+ <Textarea
58
+ label="Short Bio"
59
+ placeholder="Keep it brief..."
60
+ maxlength={200}
61
+ helperText="Maximum 200 characters"
62
+ />
63
+ </div>
64
+ {/snippet}
65
+ </Story>
66
+
67
+ <Story name="With Error">
68
+ {#snippet template()}
69
+ <div class="max-w-md">
70
+ <Textarea
71
+ label="Comments"
72
+ placeholder="Enter your comments..."
73
+ errorText="Please provide at least 10 characters"
74
+ />
75
+ </div>
76
+ {/snippet}
77
+ </Story>
78
+
79
+ <Story name="Custom Rows">
80
+ {#snippet template()}
81
+ <div class="space-y-6 max-w-md">
82
+ <Textarea
83
+ label="Small (2 rows)"
84
+ placeholder="Two rows..."
85
+ rows={2}
86
+ />
87
+ <Textarea
88
+ label="Medium (4 rows)"
89
+ placeholder="Four rows..."
90
+ rows={4}
91
+ />
92
+ <Textarea
93
+ label="Large (8 rows)"
94
+ placeholder="Eight rows..."
95
+ rows={8}
96
+ />
97
+ </div>
98
+ {/snippet}
99
+ </Story>
100
+
101
+ <Story name="Disabled">
102
+ {#snippet template()}
103
+ <div class="max-w-md">
104
+ <Textarea
105
+ label="Disabled Textarea"
106
+ placeholder="Cannot edit this..."
107
+ disabled
108
+ />
109
+ </div>
110
+ {/snippet}
111
+ </Story>
112
+
113
+ <Story name="All States">
114
+ {#snippet template()}
115
+ <div class="grid grid-cols-2 gap-6 max-w-2xl">
116
+ <Textarea
117
+ label="Default"
118
+ placeholder="Enter text..."
119
+ />
120
+ <Textarea
121
+ label="With Error"
122
+ placeholder="Enter text..."
123
+ errorText="This field is required"
124
+ />
125
+ <Textarea
126
+ label="Disabled"
127
+ placeholder="Cannot edit..."
128
+ disabled
129
+ />
130
+ <Textarea
131
+ label="With Helper"
132
+ placeholder="Enter text..."
133
+ helperText="Optional additional information"
134
+ />
135
+ </div>
136
+ {/snippet}
137
+ </Story>
@@ -0,0 +1,28 @@
1
+ export default Textarea;
2
+ type Textarea = SvelteComponent<{
3
+ [x: string]: never;
4
+ }, {
5
+ [evt: string]: CustomEvent<any>;
6
+ }, {}> & {
7
+ $$bindings?: string | undefined;
8
+ };
9
+ declare const Textarea: $$__sveltets_2_IsomorphicComponent<{
10
+ [x: string]: never;
11
+ }, {
12
+ [evt: string]: CustomEvent<any>;
13
+ }, {}, {}, string>;
14
+ import Textarea from './Textarea.svelte';
15
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
16
+ new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
17
+ $$bindings?: Bindings;
18
+ } & Exports;
19
+ (internal: unknown, props: {
20
+ $$events?: Events;
21
+ $$slots?: Slots;
22
+ }): Exports & {
23
+ $set?: any;
24
+ $on?: any;
25
+ };
26
+ z_$$bindings?: Bindings;
27
+ }
28
+ //# sourceMappingURL=Textarea.stories.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Textarea.stories.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Input/Textarea.stories.svelte.js"],"names":[],"mappings":";;;;;;;;AAwGA;;;;mBAAoH;qBApG7F,mBAAmB;6CA2FG,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,OAAO,OAAO,QAAQ;IAC3L,cAAc,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,WAAW,OAAO,SAAS;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IACtG,eAAe,QAAQ,CAAC"}
@@ -1,4 +1,6 @@
1
1
  <script>
2
+ import { typography } from "../../tokens/typography";
3
+
2
4
  let {
3
5
  value = $bindable(""),
4
6
  placeholder = "",
@@ -43,7 +45,7 @@
43
45
 
44
46
  <div class="flex flex-col gap-2 w-full">
45
47
  {#if label}
46
- <label for={id || name} class="text-sm font-medium text-gray-900 dark:text-white leading-tight">
48
+ <label for={id || name} class={`${typography.label} leading-tight`}>
47
49
  {label}{#if required}<span class="text-red-500 font-medium text-sm ml-0.5">*</span>{/if}
48
50
  </label>
49
51
  {/if}
@@ -57,7 +59,7 @@
57
59
  {readonly}
58
60
  {maxlength}
59
61
  {minlength}
60
- class="w-full p-2.5 bg-gray-50 dark:bg-gray-700 text-gray-900 dark:text-white text-sm leading-normal border rounded-lg resize-y transition-colors focus:outline-none focus:ring-4 focus:ring-blue-300 dark:focus:ring-blue-800 placeholder-gray-500 dark:placeholder-gray-400 {error ? 'border-red-500' : 'border-gray-300 dark:border-gray-600 hover:border-blue-500 focus:border-blue-500'} {disabled ? 'opacity-50 cursor-not-allowed' : ''} {className}"
62
+ class="{typography.sm} w-full p-2.5 bg-gray-50 dark:bg-gray-700 leading-normal border rounded-lg resize-y transition-colors focus:outline-none focus:ring-4 focus:ring-blue-300 dark:focus:ring-blue-800 placeholder-gray-500 dark:placeholder-gray-400 {error ? 'border-red-500' : 'border-gray-300 dark:border-gray-600 hover:border-blue-500 focus:border-blue-500'} {disabled ? 'opacity-50 cursor-not-allowed' : ''} {className}"
61
63
  bind:value
62
64
  oninput={handleInput}
63
65
  onchange={handleChange}
@@ -72,6 +74,6 @@
72
74
  ></textarea>
73
75
 
74
76
  {#if error}
75
- <p class="text-sm text-red-500">{error}</p>
77
+ <p class={typography.error}>{error}</p>
76
78
  {/if}
77
79
  </div>
@@ -1 +1 @@
1
- {"version":3,"file":"Textarea.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Input/Textarea.svelte.js"],"names":[],"mappings":";;;;;AA8DA;YA1D6B,MAAM;kBAAgB,MAAM;WAAS,MAAM;eAAa,OAAO;eAAa,OAAO;eAAa,OAAO;SAAO,MAAM;WAAS,MAAM;YAAU,MAAM;YAAU,MAAM;gBAAc,GAAG;gBAAc,GAAG;YAAU,MAAM;aAAW,GAAG;cAAY,GAAG;YAAU,GAAG;aAAW,GAAG;eAAa,GAAG;aAAW,GAAG;gBAAc,GAAG;sCA0DlS;wBA1DpC;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,GAAG,CAAC;IAAC,SAAS,CAAC,EAAE,GAAG,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,GAAG,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAC;IAAC,MAAM,EAAE,GAAG,CAAC;IAAC,OAAO,EAAE,GAAG,CAAC;IAAC,SAAS,EAAE,GAAG,CAAC;IAAC,OAAO,EAAE,GAAG,CAAC;IAAC,UAAU,EAAE,GAAG,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC"}
1
+ {"version":3,"file":"Textarea.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Input/Textarea.svelte.js"],"names":[],"mappings":";;;;;AAkEA;YA1D6B,MAAM;kBAAgB,MAAM;WAAS,MAAM;eAAa,OAAO;eAAa,OAAO;eAAa,OAAO;SAAO,MAAM;WAAS,MAAM;YAAU,MAAM;YAAU,MAAM;gBAAc,GAAG;gBAAc,GAAG;YAAU,MAAM;aAAW,GAAG;cAAY,GAAG;YAAU,GAAG;aAAW,GAAG;eAAa,GAAG;aAAW,GAAG;gBAAc,GAAG;sCA0DlS;wBA1DpC;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,GAAG,CAAC;IAAC,SAAS,CAAC,EAAE,GAAG,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,GAAG,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAC;IAAC,MAAM,EAAE,GAAG,CAAC;IAAC,OAAO,EAAE,GAAG,CAAC;IAAC,SAAS,EAAE,GAAG,CAAC;IAAC,OAAO,EAAE,GAAG,CAAC;IAAC,UAAU,EAAE,GAAG,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC"}
@@ -99,7 +99,19 @@
99
99
  <!-- svelte-ignore a11y_no_static_element_interactions -->
100
100
  <div
101
101
  class="fixed inset-0 flex bg-black/50 z-50 items-end justify-center md:items-center md:p-4 touch-none overscroll-none"
102
- onclick={persistent ? null : resetModal}
102
+ onmousedown={(e) => {
103
+ // Only track direct clicks on backdrop, not drags that end on backdrop
104
+ if (e.target === e.currentTarget && !persistent) {
105
+ e.currentTarget.dataset.clickStartedOnBackdrop = 'true';
106
+ }
107
+ }}
108
+ onmouseup={(e) => {
109
+ // Only close if both mousedown and mouseup were on the backdrop
110
+ if (e.target === e.currentTarget && e.currentTarget.dataset.clickStartedOnBackdrop === 'true' && !persistent) {
111
+ resetModal();
112
+ }
113
+ delete e.currentTarget.dataset.clickStartedOnBackdrop;
114
+ }}
103
115
  transition:fade={{ duration: 300 }}
104
116
  role="dialog"
105
117
  aria-modal="true"
@@ -1 +1 @@
1
- {"version":3,"file":"Modal.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Modal/Modal.svelte.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AA0JA;;WAZW,OAAO;mBACC,OAAO;gBACV,OAAO;WACZ,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ;iBAClC,OAAO;eACT,MAAM,IAAI;aACZ,GAAG;WACL,GAAG;aACD,GAAG;YACJ,MAAM;eAGkC"}
1
+ {"version":3,"file":"Modal.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Modal/Modal.svelte.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAqKA;;WAZW,OAAO;mBACC,OAAO;gBACV,OAAO;WACZ,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ;iBAClC,OAAO;eACT,MAAM,IAAI;aACZ,GAAG;WACL,GAAG;aACD,GAAG;YACJ,MAAM;eAGkC"}
@@ -0,0 +1,76 @@
1
+ <script module>
2
+ import { defineMeta } from '@storybook/addon-svelte-csf';
3
+ import Pagination from './Pagination.svelte';
4
+
5
+ const { Story } = defineMeta({
6
+ title: 'Primitives/Pagination',
7
+ component: Pagination,
8
+ tags: ['autodocs'],
9
+ argTypes: {
10
+ totalPages: { control: 'number' },
11
+ currentPage: { control: 'number' },
12
+ },
13
+ parameters: {
14
+ docs: {
15
+ description: {
16
+ component: 'Page navigation control for paginated data.',
17
+ },
18
+ },
19
+ },
20
+ });
21
+
22
+ let page1 = $state(1);
23
+ let page2 = $state(5);
24
+ let page3 = $state(1);
25
+ </script>
26
+
27
+ <Story name="Default">
28
+ {#snippet template()}
29
+ <div>
30
+ <Pagination totalPages={10} bind:currentPage={page1} />
31
+ <p class="text-sm text-gray-500 mt-4">Current page: {page1}</p>
32
+ </div>
33
+ {/snippet}
34
+ </Story>
35
+
36
+ <Story name="Middle Page">
37
+ {#snippet template()}
38
+ <div>
39
+ <Pagination totalPages={10} bind:currentPage={page2} />
40
+ <p class="text-sm text-gray-500 mt-4">Current page: {page2}</p>
41
+ </div>
42
+ {/snippet}
43
+ </Story>
44
+
45
+ <Story name="Few Pages">
46
+ {#snippet template()}
47
+ <div>
48
+ <Pagination totalPages={3} bind:currentPage={page3} />
49
+ <p class="text-sm text-gray-500 mt-4">Current page: {page3}</p>
50
+ </div>
51
+ {/snippet}
52
+ </Story>
53
+
54
+ <Story name="Many Pages">
55
+ {#snippet template()}
56
+ <Pagination totalPages={100} currentPage={50} />
57
+ {/snippet}
58
+ </Story>
59
+
60
+ <Story name="In Context">
61
+ {#snippet template()}
62
+ <div class="border rounded-lg p-4">
63
+ <h3 class="font-medium mb-4">Search Results</h3>
64
+ <ul class="space-y-2 mb-4">
65
+ {#each [1, 2, 3, 4, 5] as i}
66
+ <li class="p-3 border rounded hover:bg-gray-50">
67
+ Result item {i}
68
+ </li>
69
+ {/each}
70
+ </ul>
71
+ <div class="border-t pt-4">
72
+ <Pagination totalPages={20} bind:currentPage={page1} />
73
+ </div>
74
+ </div>
75
+ {/snippet}
76
+ </Story>
@@ -0,0 +1,28 @@
1
+ export default Pagination;
2
+ type Pagination = SvelteComponent<{
3
+ [x: string]: never;
4
+ }, {
5
+ [evt: string]: CustomEvent<any>;
6
+ }, {}> & {
7
+ $$bindings?: string | undefined;
8
+ };
9
+ declare const Pagination: $$__sveltets_2_IsomorphicComponent<{
10
+ [x: string]: never;
11
+ }, {
12
+ [evt: string]: CustomEvent<any>;
13
+ }, {}, {}, string>;
14
+ import Pagination from './Pagination.svelte';
15
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
16
+ new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
17
+ $$bindings?: Bindings;
18
+ } & Exports;
19
+ (internal: unknown, props: {
20
+ $$events?: Events;
21
+ $$slots?: Slots;
22
+ }): Exports & {
23
+ $set?: any;
24
+ $on?: any;
25
+ };
26
+ z_$$bindings?: Bindings;
27
+ }
28
+ //# sourceMappingURL=Pagination.stories.svelte.d.ts.map