@aspect-ops/exon-ui 0.0.2 → 0.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.
Files changed (237) hide show
  1. package/README.md +793 -43
  2. package/dist/components/Accordion/Accordion.svelte +79 -0
  3. package/dist/components/Accordion/Accordion.svelte.d.ts +10 -0
  4. package/dist/components/Accordion/AccordionItem.svelte +198 -0
  5. package/dist/components/Accordion/AccordionItem.svelte.d.ts +10 -0
  6. package/dist/components/Accordion/index.d.ts +2 -0
  7. package/dist/components/Accordion/index.js +2 -0
  8. package/dist/components/ActionSheet/ActionSheet.svelte +270 -0
  9. package/dist/components/ActionSheet/ActionSheet.svelte.d.ts +12 -0
  10. package/dist/components/ActionSheet/ActionSheetItem.svelte +151 -0
  11. package/dist/components/ActionSheet/ActionSheetItem.svelte.d.ts +10 -0
  12. package/dist/components/ActionSheet/index.d.ts +3 -0
  13. package/dist/components/ActionSheet/index.js +2 -0
  14. package/dist/components/Alert/Alert.svelte +165 -0
  15. package/dist/components/Alert/Alert.svelte.d.ts +11 -0
  16. package/dist/components/Alert/index.d.ts +1 -0
  17. package/dist/components/Alert/index.js +1 -0
  18. package/dist/components/AspectRatio/AspectRatio.svelte +42 -0
  19. package/dist/components/AspectRatio/AspectRatio.svelte.d.ts +9 -0
  20. package/dist/components/AspectRatio/index.d.ts +1 -0
  21. package/dist/components/AspectRatio/index.js +1 -0
  22. package/dist/components/Avatar/Avatar.svelte +147 -0
  23. package/dist/components/Avatar/Avatar.svelte.d.ts +12 -0
  24. package/dist/components/Avatar/AvatarGroup.svelte +153 -0
  25. package/dist/components/Avatar/AvatarGroup.svelte.d.ts +12 -0
  26. package/dist/components/Avatar/index.d.ts +2 -0
  27. package/dist/components/Avatar/index.js +2 -0
  28. package/dist/components/BottomSheet/BottomSheet.svelte +230 -0
  29. package/dist/components/BottomSheet/BottomSheet.svelte.d.ts +7 -0
  30. package/dist/components/BottomSheet/BottomSheetBody.svelte +20 -0
  31. package/dist/components/BottomSheet/BottomSheetBody.svelte.d.ts +7 -0
  32. package/dist/components/BottomSheet/BottomSheetHeader.svelte +27 -0
  33. package/dist/components/BottomSheet/BottomSheetHeader.svelte.d.ts +7 -0
  34. package/dist/components/BottomSheet/index.d.ts +3 -0
  35. package/dist/components/BottomSheet/index.js +3 -0
  36. package/dist/components/Box/Box.svelte +41 -0
  37. package/dist/components/Box/Box.svelte.d.ts +7 -0
  38. package/dist/components/Box/index.d.ts +1 -0
  39. package/dist/components/Box/index.js +1 -0
  40. package/dist/components/Card/Card.svelte +95 -0
  41. package/dist/components/Card/Card.svelte.d.ts +10 -0
  42. package/dist/components/Card/CardBody.svelte +32 -0
  43. package/dist/components/Card/CardBody.svelte.d.ts +7 -0
  44. package/dist/components/Card/CardFooter.svelte +34 -0
  45. package/dist/components/Card/CardFooter.svelte.d.ts +7 -0
  46. package/dist/components/Card/CardHeader.svelte +67 -0
  47. package/dist/components/Card/CardHeader.svelte.d.ts +9 -0
  48. package/dist/components/Card/index.d.ts +4 -0
  49. package/dist/components/Card/index.js +4 -0
  50. package/dist/components/Carousel/Carousel.svelte +454 -0
  51. package/dist/components/Carousel/Carousel.svelte.d.ts +14 -0
  52. package/dist/components/Carousel/CarouselSlide.svelte +22 -0
  53. package/dist/components/Carousel/CarouselSlide.svelte.d.ts +7 -0
  54. package/dist/components/Carousel/index.d.ts +2 -0
  55. package/dist/components/Carousel/index.js +2 -0
  56. package/dist/components/Center/Center.svelte +28 -0
  57. package/dist/components/Center/Center.svelte.d.ts +8 -0
  58. package/dist/components/Center/index.d.ts +1 -0
  59. package/dist/components/Center/index.js +1 -0
  60. package/dist/components/Chip/Chip.svelte +461 -0
  61. package/dist/components/Chip/Chip.svelte.d.ts +17 -0
  62. package/dist/components/Chip/ChipGroup.svelte +76 -0
  63. package/dist/components/Chip/ChipGroup.svelte.d.ts +9 -0
  64. package/dist/components/Chip/index.d.ts +2 -0
  65. package/dist/components/Chip/index.js +2 -0
  66. package/dist/components/Container/Container.svelte +58 -0
  67. package/dist/components/Container/Container.svelte.d.ts +10 -0
  68. package/dist/components/Container/index.d.ts +1 -0
  69. package/dist/components/Container/index.js +1 -0
  70. package/dist/components/DatePicker/DatePicker.svelte +746 -0
  71. package/dist/components/DatePicker/DatePicker.svelte.d.ts +19 -0
  72. package/dist/components/DatePicker/index.d.ts +1 -0
  73. package/dist/components/DatePicker/index.js +1 -0
  74. package/dist/components/Divider/Divider.svelte +38 -0
  75. package/dist/components/Divider/Divider.svelte.d.ts +9 -0
  76. package/dist/components/Divider/index.d.ts +1 -0
  77. package/dist/components/Divider/index.js +1 -0
  78. package/dist/components/EmptyState/EmptyState.svelte +164 -0
  79. package/dist/components/EmptyState/EmptyState.svelte.d.ts +12 -0
  80. package/dist/components/EmptyState/index.d.ts +1 -0
  81. package/dist/components/EmptyState/index.js +1 -0
  82. package/dist/components/FAB/FAB.svelte +242 -0
  83. package/dist/components/FAB/FAB.svelte.d.ts +9 -0
  84. package/dist/components/FAB/FABGroup.svelte +449 -0
  85. package/dist/components/FAB/FABGroup.svelte.d.ts +9 -0
  86. package/dist/components/FAB/index.d.ts +3 -0
  87. package/dist/components/FAB/index.js +2 -0
  88. package/dist/components/FileUpload/FileUpload.svelte +484 -0
  89. package/dist/components/FileUpload/FileUpload.svelte.d.ts +16 -0
  90. package/dist/components/FileUpload/index.d.ts +1 -0
  91. package/dist/components/FileUpload/index.js +1 -0
  92. package/dist/components/Grid/Grid.svelte +136 -0
  93. package/dist/components/Grid/Grid.svelte.d.ts +12 -0
  94. package/dist/components/Grid/GridItem.svelte +21 -0
  95. package/dist/components/Grid/GridItem.svelte.d.ts +7 -0
  96. package/dist/components/Grid/index.d.ts +2 -0
  97. package/dist/components/Grid/index.js +2 -0
  98. package/dist/components/Image/Image.svelte +223 -0
  99. package/dist/components/Image/Image.svelte.d.ts +19 -0
  100. package/dist/components/Image/index.d.ts +1 -0
  101. package/dist/components/Image/index.js +1 -0
  102. package/dist/components/List/List.svelte +42 -0
  103. package/dist/components/List/List.svelte.d.ts +18 -0
  104. package/dist/components/List/ListItem.svelte +139 -0
  105. package/dist/components/List/ListItem.svelte.d.ts +36 -0
  106. package/dist/components/List/index.d.ts +2 -0
  107. package/dist/components/List/index.js +2 -0
  108. package/dist/components/Modal/Modal.svelte +204 -0
  109. package/dist/components/Modal/Modal.svelte.d.ts +7 -0
  110. package/dist/components/Modal/ModalBody.svelte +50 -0
  111. package/dist/components/Modal/ModalBody.svelte.d.ts +7 -0
  112. package/dist/components/Modal/ModalFooter.svelte +37 -0
  113. package/dist/components/Modal/ModalFooter.svelte.d.ts +7 -0
  114. package/dist/components/Modal/ModalHeader.svelte +73 -0
  115. package/dist/components/Modal/ModalHeader.svelte.d.ts +7 -0
  116. package/dist/components/Modal/index.d.ts +4 -0
  117. package/dist/components/Modal/index.js +4 -0
  118. package/dist/components/OTPInput/OTPInput.svelte +312 -0
  119. package/dist/components/OTPInput/OTPInput.svelte.d.ts +57 -0
  120. package/dist/components/OTPInput/index.d.ts +1 -0
  121. package/dist/components/OTPInput/index.js +1 -0
  122. package/dist/components/Popover/Popover.svelte +14 -0
  123. package/dist/components/Popover/Popover.svelte.d.ts +7 -0
  124. package/dist/components/Popover/PopoverContent.svelte +63 -0
  125. package/dist/components/Popover/PopoverContent.svelte.d.ts +7 -0
  126. package/dist/components/Popover/PopoverTrigger.svelte +14 -0
  127. package/dist/components/Popover/PopoverTrigger.svelte.d.ts +7 -0
  128. package/dist/components/Popover/index.d.ts +3 -0
  129. package/dist/components/Popover/index.js +3 -0
  130. package/dist/components/Progress/ProgressBar.svelte +86 -0
  131. package/dist/components/Progress/ProgressBar.svelte.d.ts +11 -0
  132. package/dist/components/Progress/ProgressCircle.svelte +134 -0
  133. package/dist/components/Progress/ProgressCircle.svelte.d.ts +12 -0
  134. package/dist/components/Progress/Spinner.svelte +68 -0
  135. package/dist/components/Progress/Spinner.svelte.d.ts +8 -0
  136. package/dist/components/Progress/index.d.ts +3 -0
  137. package/dist/components/Progress/index.js +3 -0
  138. package/dist/components/PullToRefresh/PullToRefresh.svelte +304 -0
  139. package/dist/components/PullToRefresh/PullToRefresh.svelte.d.ts +20 -0
  140. package/dist/components/PullToRefresh/index.d.ts +1 -0
  141. package/dist/components/PullToRefresh/index.js +1 -0
  142. package/dist/components/Rating/Rating.svelte +316 -0
  143. package/dist/components/Rating/Rating.svelte.d.ts +16 -0
  144. package/dist/components/Rating/index.d.ts +1 -0
  145. package/dist/components/Rating/index.js +1 -0
  146. package/dist/components/SafeArea/SafeArea.svelte +33 -0
  147. package/dist/components/SafeArea/SafeArea.svelte.d.ts +7 -0
  148. package/dist/components/SearchInput/SearchInput.svelte +480 -0
  149. package/dist/components/SearchInput/SearchInput.svelte.d.ts +22 -0
  150. package/dist/components/SearchInput/index.d.ts +1 -0
  151. package/dist/components/SearchInput/index.js +1 -0
  152. package/dist/components/Select/Select.svelte +55 -12
  153. package/dist/components/Skeleton/Skeleton.svelte +59 -0
  154. package/dist/components/Skeleton/Skeleton.svelte.d.ts +10 -0
  155. package/dist/components/Skeleton/index.d.ts +1 -0
  156. package/dist/components/Skeleton/index.js +1 -0
  157. package/dist/components/Slider/Slider.svelte +324 -0
  158. package/dist/components/Slider/Slider.svelte.d.ts +14 -0
  159. package/dist/components/Slider/index.d.ts +1 -0
  160. package/dist/components/Slider/index.js +1 -0
  161. package/dist/components/Spacer/Spacer.svelte +56 -0
  162. package/dist/components/Spacer/Spacer.svelte.d.ts +6 -0
  163. package/dist/components/Spacer/index.d.ts +1 -0
  164. package/dist/components/Spacer/index.js +1 -0
  165. package/dist/components/Stack/Stack.svelte +117 -0
  166. package/dist/components/Stack/Stack.svelte.d.ts +13 -0
  167. package/dist/components/Stack/index.d.ts +1 -0
  168. package/dist/components/Stack/index.js +1 -0
  169. package/dist/components/Stepper/Stepper.svelte +100 -0
  170. package/dist/components/Stepper/Stepper.svelte.d.ts +11 -0
  171. package/dist/components/Stepper/StepperStep.svelte +391 -0
  172. package/dist/components/Stepper/StepperStep.svelte.d.ts +13 -0
  173. package/dist/components/Stepper/index.d.ts +2 -0
  174. package/dist/components/Stepper/index.js +2 -0
  175. package/dist/components/SwipeActions/SwipeAction.svelte +43 -0
  176. package/dist/components/SwipeActions/SwipeAction.svelte.d.ts +8 -0
  177. package/dist/components/SwipeActions/SwipeActions.svelte +193 -0
  178. package/dist/components/SwipeActions/SwipeActions.svelte.d.ts +9 -0
  179. package/dist/components/SwipeActions/index.d.ts +2 -0
  180. package/dist/components/SwipeActions/index.js +2 -0
  181. package/dist/components/Switch/Switch.svelte +29 -9
  182. package/dist/components/Table/Table.svelte +175 -0
  183. package/dist/components/Table/Table.svelte.d.ts +38 -0
  184. package/dist/components/Table/TableBody.svelte +26 -0
  185. package/dist/components/Table/TableBody.svelte.d.ts +13 -0
  186. package/dist/components/Table/TableCell.svelte +85 -0
  187. package/dist/components/Table/TableCell.svelte.d.ts +28 -0
  188. package/dist/components/Table/TableHead.svelte +36 -0
  189. package/dist/components/Table/TableHead.svelte.d.ts +13 -0
  190. package/dist/components/Table/TableHeader.svelte +217 -0
  191. package/dist/components/Table/TableHeader.svelte.d.ts +32 -0
  192. package/dist/components/Table/TableRow.svelte +92 -0
  193. package/dist/components/Table/TableRow.svelte.d.ts +28 -0
  194. package/dist/components/Table/index.d.ts +6 -0
  195. package/dist/components/Table/index.js +6 -0
  196. package/dist/components/Tag/Tag.svelte +189 -0
  197. package/dist/components/Tag/Tag.svelte.d.ts +13 -0
  198. package/dist/components/Tag/index.d.ts +1 -0
  199. package/dist/components/Tag/index.js +1 -0
  200. package/dist/components/TimePicker/TimePicker.svelte +803 -0
  201. package/dist/components/TimePicker/TimePicker.svelte.d.ts +17 -0
  202. package/dist/components/TimePicker/index.d.ts +1 -0
  203. package/dist/components/TimePicker/index.js +1 -0
  204. package/dist/components/Toast/Toast.svelte +241 -0
  205. package/dist/components/Toast/Toast.svelte.d.ts +18 -0
  206. package/dist/components/Toast/ToastContainer.svelte +110 -0
  207. package/dist/components/Toast/ToastContainer.svelte.d.ts +8 -0
  208. package/dist/components/Toast/index.d.ts +3 -0
  209. package/dist/components/Toast/index.js +3 -0
  210. package/dist/components/Toast/toast.d.ts +13 -0
  211. package/dist/components/Toast/toast.js +55 -0
  212. package/dist/components/Tooltip/Tooltip.svelte +71 -0
  213. package/dist/components/Tooltip/Tooltip.svelte.d.ts +7 -0
  214. package/dist/components/Tooltip/index.d.ts +2 -0
  215. package/dist/components/Tooltip/index.js +1 -0
  216. package/dist/index.d.ts +38 -1
  217. package/dist/index.js +41 -0
  218. package/dist/styles/tokens.css +5 -0
  219. package/dist/types/data-display.d.ts +161 -0
  220. package/dist/types/data-display.js +1 -0
  221. package/dist/types/feedback.d.ts +92 -0
  222. package/dist/types/feedback.js +1 -0
  223. package/dist/types/index.d.ts +6 -1
  224. package/dist/types/input.d.ts +67 -0
  225. package/dist/types/input.js +2 -0
  226. package/dist/types/layout.d.ts +57 -0
  227. package/dist/types/layout.js +1 -0
  228. package/dist/types/mobile.d.ts +91 -0
  229. package/dist/types/mobile.js +1 -0
  230. package/dist/types/navigation.d.ts +15 -0
  231. package/dist/utils/gestures.d.ts +219 -0
  232. package/dist/utils/gestures.js +492 -0
  233. package/dist/utils/haptics.d.ts +89 -0
  234. package/dist/utils/haptics.js +198 -0
  235. package/dist/utils/platform.d.ts +47 -0
  236. package/dist/utils/platform.js +156 -0
  237. package/package.json +1 -1
@@ -0,0 +1,223 @@
1
+ <script lang="ts">
2
+ interface Props {
3
+ src: string;
4
+ alt: string;
5
+ width?: number | string;
6
+ height?: number | string;
7
+ loading?: 'lazy' | 'eager';
8
+ objectFit?: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';
9
+ objectPosition?: string;
10
+ placeholder?: string;
11
+ fallback?: string;
12
+ rounded?: boolean | 'sm' | 'md' | 'lg' | 'full';
13
+ aspectRatio?: string;
14
+ class?: string;
15
+ onload?: () => void;
16
+ onerror?: () => void;
17
+ }
18
+
19
+ let {
20
+ src,
21
+ alt,
22
+ width,
23
+ height,
24
+ loading = 'lazy',
25
+ objectFit = 'cover',
26
+ objectPosition = 'center',
27
+ placeholder,
28
+ fallback,
29
+ rounded = false,
30
+ aspectRatio,
31
+ class: className = '',
32
+ onload,
33
+ onerror
34
+ }: Props = $props();
35
+
36
+ let status = $state<'loading' | 'loaded' | 'error'>('loading');
37
+
38
+ const currentSrc = $derived(status === 'error' && fallback ? fallback : src);
39
+
40
+ const roundedClass = $derived(() => {
41
+ if (rounded === false) return '';
42
+ if (rounded === true) return 'image-container--rounded-md';
43
+ return `image-container--rounded-${rounded}`;
44
+ });
45
+
46
+ const containerStyle = $derived(() => {
47
+ const styles: string[] = [];
48
+ if (aspectRatio) {
49
+ styles.push(`aspect-ratio: ${aspectRatio}`);
50
+ }
51
+ if (width) {
52
+ styles.push(`width: ${typeof width === 'number' ? `${width}px` : width}`);
53
+ }
54
+ if (height && !aspectRatio) {
55
+ styles.push(`height: ${typeof height === 'number' ? `${height}px` : height}`);
56
+ }
57
+ return styles.join('; ');
58
+ });
59
+
60
+ const imageStyle = $derived(() => {
61
+ const styles: string[] = [];
62
+ styles.push(`object-fit: ${objectFit}`);
63
+ styles.push(`object-position: ${objectPosition}`);
64
+ return styles.join('; ');
65
+ });
66
+
67
+ function handleLoad() {
68
+ status = 'loaded';
69
+ onload?.();
70
+ }
71
+
72
+ function handleError() {
73
+ status = 'error';
74
+ onerror?.();
75
+ }
76
+
77
+ // Reset status when src changes
78
+ $effect(() => {
79
+ src;
80
+ status = 'loading';
81
+ });
82
+ </script>
83
+
84
+ <div
85
+ class="image-container {roundedClass()} {className}"
86
+ style={containerStyle()}
87
+ role="img"
88
+ aria-label={alt}
89
+ >
90
+ {#if status === 'loading' && placeholder}
91
+ <div
92
+ class="image-placeholder"
93
+ style={typeof placeholder === 'string' && placeholder.startsWith('#')
94
+ ? `background-color: ${placeholder}`
95
+ : `background-image: url(${placeholder})`}
96
+ ></div>
97
+ {/if}
98
+
99
+ <img
100
+ class="image image--{status}"
101
+ src={currentSrc}
102
+ {alt}
103
+ {loading}
104
+ style={imageStyle()}
105
+ onload={handleLoad}
106
+ onerror={handleError}
107
+ />
108
+
109
+ {#if status === 'error' && !fallback}
110
+ <div class="image-error">
111
+ <svg
112
+ class="image-error__icon"
113
+ viewBox="0 0 24 24"
114
+ fill="none"
115
+ xmlns="http://www.w3.org/2000/svg"
116
+ aria-hidden="true"
117
+ >
118
+ <path
119
+ d="M21 19V5C21 3.9 20.1 3 19 3H5C3.9 3 3 3.9 3 5V19C3 20.1 3.9 21 5 21H19C20.1 21 21 20.1 21 19ZM8.5 13.5L11 16.51L14.5 12L19 18H5L8.5 13.5Z"
120
+ fill="currentColor"
121
+ />
122
+ <line
123
+ x1="4"
124
+ y1="4"
125
+ x2="20"
126
+ y2="20"
127
+ stroke="currentColor"
128
+ stroke-width="2"
129
+ stroke-linecap="round"
130
+ />
131
+ </svg>
132
+ <span class="image-error__text">{alt}</span>
133
+ </div>
134
+ {/if}
135
+ </div>
136
+
137
+ <style>
138
+ .image-container {
139
+ position: relative;
140
+ overflow: hidden;
141
+ display: inline-block;
142
+ background: var(--color-bg-muted, #f3f4f6);
143
+ }
144
+
145
+ .image {
146
+ width: 100%;
147
+ height: 100%;
148
+ display: block;
149
+ transition: opacity var(--transition-base, 0.2s ease);
150
+ }
151
+
152
+ .image--loading {
153
+ opacity: 0;
154
+ }
155
+
156
+ .image--loaded {
157
+ opacity: 1;
158
+ }
159
+
160
+ .image--error {
161
+ opacity: 0;
162
+ }
163
+
164
+ /* Rounded variants */
165
+ .image-container--rounded-sm {
166
+ border-radius: var(--radius-sm, 0.25rem);
167
+ }
168
+
169
+ .image-container--rounded-md {
170
+ border-radius: var(--radius-md, 0.375rem);
171
+ }
172
+
173
+ .image-container--rounded-lg {
174
+ border-radius: var(--radius-lg, 0.5rem);
175
+ }
176
+
177
+ .image-container--rounded-full {
178
+ border-radius: var(--radius-full, 9999px);
179
+ }
180
+
181
+ /* Placeholder */
182
+ .image-placeholder {
183
+ position: absolute;
184
+ inset: 0;
185
+ background-size: cover;
186
+ background-position: center;
187
+ background-repeat: no-repeat;
188
+ z-index: 1;
189
+ }
190
+
191
+ /* Error state */
192
+ .image-error {
193
+ position: absolute;
194
+ inset: 0;
195
+ display: flex;
196
+ flex-direction: column;
197
+ align-items: center;
198
+ justify-content: center;
199
+ background: var(--color-bg-muted, #f3f4f6);
200
+ color: var(--color-text-muted, #6b7280);
201
+ padding: 1rem;
202
+ text-align: center;
203
+ z-index: 2;
204
+ }
205
+
206
+ .image-error__icon {
207
+ width: 3rem;
208
+ height: 3rem;
209
+ margin-bottom: 0.5rem;
210
+ opacity: 0.5;
211
+ }
212
+
213
+ .image-error__text {
214
+ font-size: 0.875rem;
215
+ max-width: 100%;
216
+ overflow: hidden;
217
+ text-overflow: ellipsis;
218
+ display: -webkit-box;
219
+ line-clamp: 2;
220
+ -webkit-line-clamp: 2;
221
+ -webkit-box-orient: vertical;
222
+ }
223
+ </style>
@@ -0,0 +1,19 @@
1
+ interface Props {
2
+ src: string;
3
+ alt: string;
4
+ width?: number | string;
5
+ height?: number | string;
6
+ loading?: 'lazy' | 'eager';
7
+ objectFit?: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';
8
+ objectPosition?: string;
9
+ placeholder?: string;
10
+ fallback?: string;
11
+ rounded?: boolean | 'sm' | 'md' | 'lg' | 'full';
12
+ aspectRatio?: string;
13
+ class?: string;
14
+ onload?: () => void;
15
+ onerror?: () => void;
16
+ }
17
+ declare const Image: import("svelte").Component<Props, {}, "">;
18
+ type Image = ReturnType<typeof Image>;
19
+ export default Image;
@@ -0,0 +1 @@
1
+ export { default as Image } from './Image.svelte';
@@ -0,0 +1 @@
1
+ export { default as Image } from './Image.svelte';
@@ -0,0 +1,42 @@
1
+ <script lang="ts">
2
+ import type { ListProps } from '../../types/data-display.js';
3
+
4
+ interface Props {
5
+ /**
6
+ * Show dividers between list items
7
+ * @default false
8
+ */
9
+ dividers?: boolean;
10
+ /**
11
+ * Additional CSS classes
12
+ */
13
+ class?: string;
14
+ /**
15
+ * List item content
16
+ */
17
+ children?: import('svelte').Snippet;
18
+ }
19
+
20
+ let { dividers = false, class: className = '', children }: Props = $props();
21
+ </script>
22
+
23
+ <ul class="list {dividers ? 'list--dividers' : ''} {className}" role="list">
24
+ {#if children}
25
+ {@render children()}
26
+ {/if}
27
+ </ul>
28
+
29
+ <style>
30
+ .list {
31
+ /* Reset default list styles */
32
+ list-style: none;
33
+ padding: 0;
34
+ margin: 0;
35
+ font-family: inherit;
36
+ }
37
+
38
+ /* Divider styles - applied to list items */
39
+ .list--dividers :global(> li:not(:last-child)) {
40
+ border-bottom: 1px solid var(--color-border, #e5e7eb);
41
+ }
42
+ </style>
@@ -0,0 +1,18 @@
1
+ interface Props {
2
+ /**
3
+ * Show dividers between list items
4
+ * @default false
5
+ */
6
+ dividers?: boolean;
7
+ /**
8
+ * Additional CSS classes
9
+ */
10
+ class?: string;
11
+ /**
12
+ * List item content
13
+ */
14
+ children?: import('svelte').Snippet;
15
+ }
16
+ declare const List: import("svelte").Component<Props, {}, "">;
17
+ type List = ReturnType<typeof List>;
18
+ export default List;
@@ -0,0 +1,139 @@
1
+ <script lang="ts">
2
+ interface Props {
3
+ /**
4
+ * Makes the list item interactive with hover/active states
5
+ * @default false
6
+ */
7
+ clickable?: boolean;
8
+ /**
9
+ * Marks the list item as selected
10
+ * @default false
11
+ */
12
+ selected?: boolean;
13
+ /**
14
+ * Disables the list item
15
+ * @default false
16
+ */
17
+ disabled?: boolean;
18
+ /**
19
+ * Additional CSS classes
20
+ */
21
+ class?: string;
22
+ /**
23
+ * Leading content slot (icons/avatars)
24
+ */
25
+ leading?: import('svelte').Snippet;
26
+ /**
27
+ * Trailing content slot (actions/badges)
28
+ */
29
+ trailing?: import('svelte').Snippet;
30
+ /**
31
+ * Main content
32
+ */
33
+ children?: import('svelte').Snippet;
34
+ }
35
+
36
+ let {
37
+ clickable = false,
38
+ selected = false,
39
+ disabled = false,
40
+ class: className = '',
41
+ leading,
42
+ trailing,
43
+ children
44
+ }: Props = $props();
45
+ </script>
46
+
47
+ <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
48
+ <li
49
+ class="list-item {clickable ? 'list-item--clickable' : ''} {selected
50
+ ? 'list-item--selected'
51
+ : ''} {disabled ? 'list-item--disabled' : ''} {className}"
52
+ role={clickable ? 'button' : undefined}
53
+ aria-selected={selected ? 'true' : undefined}
54
+ aria-disabled={disabled ? 'true' : undefined}
55
+ tabindex={clickable && !disabled ? 0 : -1}
56
+ >
57
+ {#if leading}
58
+ <div class="list-item__leading">
59
+ {@render leading()}
60
+ </div>
61
+ {/if}
62
+
63
+ <div class="list-item__content">
64
+ {#if children}
65
+ {@render children()}
66
+ {/if}
67
+ </div>
68
+
69
+ {#if trailing}
70
+ <div class="list-item__trailing">
71
+ {@render trailing()}
72
+ </div>
73
+ {/if}
74
+ </li>
75
+
76
+ <style>
77
+ .list-item {
78
+ display: flex;
79
+ align-items: center;
80
+ min-height: 3rem; /* 48px for touch targets */
81
+ padding: 0.75rem 1rem;
82
+ font-family: inherit;
83
+ transition: background-color var(--transition-fast, 150ms ease);
84
+ }
85
+
86
+ .list-item__leading {
87
+ display: flex;
88
+ align-items: center;
89
+ flex-shrink: 0;
90
+ margin-right: 0.75rem;
91
+ }
92
+
93
+ .list-item__content {
94
+ flex: 1;
95
+ min-width: 0; /* Allows text truncation */
96
+ }
97
+
98
+ .list-item__trailing {
99
+ display: flex;
100
+ align-items: center;
101
+ flex-shrink: 0;
102
+ margin-left: 0.75rem;
103
+ }
104
+
105
+ /* Clickable state */
106
+ .list-item--clickable {
107
+ cursor: pointer;
108
+ user-select: none;
109
+ }
110
+
111
+ .list-item--clickable:hover:not(.list-item--disabled) {
112
+ background-color: var(--color-bg-hover, rgba(0, 0, 0, 0.04));
113
+ }
114
+
115
+ .list-item--clickable:active:not(.list-item--disabled) {
116
+ background-color: var(--color-bg-active, rgba(0, 0, 0, 0.08));
117
+ }
118
+
119
+ .list-item--clickable:focus-visible {
120
+ outline: 2px solid var(--color-primary, #3b82f6);
121
+ outline-offset: -2px;
122
+ }
123
+
124
+ /* Selected state */
125
+ .list-item--selected {
126
+ background-color: var(--color-primary-bg, rgba(59, 130, 246, 0.1));
127
+ }
128
+
129
+ .list-item--selected.list-item--clickable:hover:not(.list-item--disabled) {
130
+ background-color: var(--color-primary-bg-hover, rgba(59, 130, 246, 0.15));
131
+ }
132
+
133
+ /* Disabled state */
134
+ .list-item--disabled {
135
+ opacity: 0.5;
136
+ pointer-events: none;
137
+ cursor: not-allowed;
138
+ }
139
+ </style>
@@ -0,0 +1,36 @@
1
+ interface Props {
2
+ /**
3
+ * Makes the list item interactive with hover/active states
4
+ * @default false
5
+ */
6
+ clickable?: boolean;
7
+ /**
8
+ * Marks the list item as selected
9
+ * @default false
10
+ */
11
+ selected?: boolean;
12
+ /**
13
+ * Disables the list item
14
+ * @default false
15
+ */
16
+ disabled?: boolean;
17
+ /**
18
+ * Additional CSS classes
19
+ */
20
+ class?: string;
21
+ /**
22
+ * Leading content slot (icons/avatars)
23
+ */
24
+ leading?: import('svelte').Snippet;
25
+ /**
26
+ * Trailing content slot (actions/badges)
27
+ */
28
+ trailing?: import('svelte').Snippet;
29
+ /**
30
+ * Main content
31
+ */
32
+ children?: import('svelte').Snippet;
33
+ }
34
+ declare const ListItem: import("svelte").Component<Props, {}, "">;
35
+ type ListItem = ReturnType<typeof ListItem>;
36
+ export default ListItem;
@@ -0,0 +1,2 @@
1
+ export { default as List } from './List.svelte';
2
+ export { default as ListItem } from './ListItem.svelte';
@@ -0,0 +1,2 @@
1
+ export { default as List } from './List.svelte';
2
+ export { default as ListItem } from './ListItem.svelte';
@@ -0,0 +1,204 @@
1
+ <script lang="ts">
2
+ import type { ModalProps } from '../../types/index.js';
3
+ import { Dialog } from 'bits-ui';
4
+
5
+ interface Props extends ModalProps {
6
+ children?: import('svelte').Snippet;
7
+ }
8
+
9
+ let {
10
+ open = $bindable(false),
11
+ size = 'md',
12
+ closeOnEscape = true,
13
+ closeOnBackdrop = true,
14
+ class: className = '',
15
+ children
16
+ }: Props = $props();
17
+
18
+ function handleOpenChange(value: boolean) {
19
+ // Only close if escape is allowed or if it's not an escape key event
20
+ if (!value && !closeOnEscape) {
21
+ return;
22
+ }
23
+ open = value;
24
+ }
25
+
26
+ function handleBackdropClick() {
27
+ if (closeOnBackdrop) {
28
+ open = false;
29
+ }
30
+ }
31
+
32
+ function handleEscapeKeyDown(event: KeyboardEvent) {
33
+ if (event.key === 'Escape' && !closeOnEscape) {
34
+ event.preventDefault();
35
+ }
36
+ }
37
+ </script>
38
+
39
+ <Dialog.Root {open} onOpenChange={handleOpenChange}>
40
+ <Dialog.Portal>
41
+ <Dialog.Overlay class="modal-overlay" onclick={handleBackdropClick} />
42
+ <Dialog.Content class="modal-content modal-{size} {className}" onkeydown={handleEscapeKeyDown}>
43
+ {@render children?.()}
44
+ </Dialog.Content>
45
+ </Dialog.Portal>
46
+ </Dialog.Root>
47
+
48
+ <style>
49
+ /* Overlay */
50
+ :global(.modal-overlay) {
51
+ position: fixed;
52
+ inset: 0;
53
+ background: rgba(0, 0, 0, 0.5);
54
+ z-index: 100;
55
+ }
56
+
57
+ :global(.modal-overlay[data-state='open']) {
58
+ animation: fade-in 200ms ease-out;
59
+ }
60
+
61
+ :global(.modal-overlay[data-state='closed']) {
62
+ animation: fade-out 150ms ease-in;
63
+ }
64
+
65
+ @keyframes -global-fade-in {
66
+ from {
67
+ opacity: 0;
68
+ }
69
+ to {
70
+ opacity: 1;
71
+ }
72
+ }
73
+
74
+ @keyframes -global-fade-out {
75
+ from {
76
+ opacity: 1;
77
+ }
78
+ to {
79
+ opacity: 0;
80
+ }
81
+ }
82
+
83
+ /* Content */
84
+ :global(.modal-content) {
85
+ /* MUST set font-family explicitly - portal doesn't inherit (F33) */
86
+ font-family: var(--font-family, system-ui, -apple-system, sans-serif);
87
+ position: fixed;
88
+ top: 50%;
89
+ left: 50%;
90
+ transform: translate(-50%, -50%);
91
+ background: var(--color-bg, #ffffff);
92
+ border-radius: var(--radius-md, 0.5rem);
93
+ box-shadow: var(--shadow-lg, 0 10px 25px rgba(0, 0, 0, 0.2));
94
+ z-index: 101;
95
+ max-height: 90vh;
96
+ display: flex;
97
+ flex-direction: column;
98
+ /* Safe area handling (F21) */
99
+ padding-top: env(safe-area-inset-top, 0);
100
+ padding-bottom: env(safe-area-inset-bottom, 0);
101
+ }
102
+
103
+ :global(.modal-content[data-state='open']) {
104
+ animation: modal-in 200ms ease-out;
105
+ }
106
+
107
+ :global(.modal-content[data-state='closed']) {
108
+ animation: modal-out 150ms ease-in;
109
+ }
110
+
111
+ @keyframes -global-modal-in {
112
+ from {
113
+ opacity: 0;
114
+ transform: translate(-50%, -50%) scale(0.95);
115
+ }
116
+ to {
117
+ opacity: 1;
118
+ transform: translate(-50%, -50%) scale(1);
119
+ }
120
+ }
121
+
122
+ @keyframes -global-modal-out {
123
+ from {
124
+ opacity: 1;
125
+ transform: translate(-50%, -50%) scale(1);
126
+ }
127
+ to {
128
+ opacity: 0;
129
+ transform: translate(-50%, -50%) scale(0.95);
130
+ }
131
+ }
132
+
133
+ /* Size variants (F32: rem units) */
134
+ :global(.modal-sm) {
135
+ width: 25rem;
136
+ max-width: calc(100vw - 2rem);
137
+ }
138
+
139
+ :global(.modal-md) {
140
+ width: 31.25rem;
141
+ max-width: calc(100vw - 2rem);
142
+ }
143
+
144
+ :global(.modal-lg) {
145
+ width: 43.75rem;
146
+ max-width: calc(100vw - 2rem);
147
+ }
148
+
149
+ :global(.modal-full) {
150
+ width: 100%;
151
+ max-width: 100%;
152
+ height: 100vh;
153
+ max-height: 100vh;
154
+ border-radius: 0;
155
+ top: 0;
156
+ left: 0;
157
+ transform: none;
158
+ }
159
+
160
+ /* Mobile responsive */
161
+ @media (max-width: 640px) {
162
+ :global(.modal-content:not(.modal-full)) {
163
+ width: 100% !important;
164
+ max-width: 100% !important;
165
+ max-height: 90vh;
166
+ top: auto;
167
+ bottom: 0;
168
+ left: 0;
169
+ transform: none;
170
+ border-radius: 1rem 1rem 0 0;
171
+ margin: 0;
172
+ }
173
+
174
+ :global(.modal-content:not(.modal-full)[data-state='open']) {
175
+ animation: modal-slide-up 250ms ease-out;
176
+ }
177
+
178
+ :global(.modal-content:not(.modal-full)[data-state='closed']) {
179
+ animation: modal-slide-down 200ms ease-in;
180
+ }
181
+ }
182
+
183
+ @keyframes -global-modal-slide-up {
184
+ from {
185
+ opacity: 0;
186
+ transform: translateY(100%);
187
+ }
188
+ to {
189
+ opacity: 1;
190
+ transform: translateY(0);
191
+ }
192
+ }
193
+
194
+ @keyframes -global-modal-slide-down {
195
+ from {
196
+ opacity: 1;
197
+ transform: translateY(0);
198
+ }
199
+ to {
200
+ opacity: 0;
201
+ transform: translateY(100%);
202
+ }
203
+ }
204
+ </style>
@@ -0,0 +1,7 @@
1
+ import type { ModalProps } from '../../types/index.js';
2
+ interface Props extends ModalProps {
3
+ children?: import('svelte').Snippet;
4
+ }
5
+ declare const Modal: import("svelte").Component<Props, {}, "open">;
6
+ type Modal = ReturnType<typeof Modal>;
7
+ export default Modal;