@aspect-ops/exon-ui 0.0.3 → 0.2.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 (79) hide show
  1. package/README.md +929 -54
  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/Carousel/Carousel.svelte +454 -0
  9. package/dist/components/Carousel/Carousel.svelte.d.ts +14 -0
  10. package/dist/components/Carousel/CarouselSlide.svelte +22 -0
  11. package/dist/components/Carousel/CarouselSlide.svelte.d.ts +7 -0
  12. package/dist/components/Carousel/index.d.ts +2 -0
  13. package/dist/components/Carousel/index.js +2 -0
  14. package/dist/components/Chip/Chip.svelte +461 -0
  15. package/dist/components/Chip/Chip.svelte.d.ts +17 -0
  16. package/dist/components/Chip/ChipGroup.svelte +76 -0
  17. package/dist/components/Chip/ChipGroup.svelte.d.ts +9 -0
  18. package/dist/components/Chip/index.d.ts +2 -0
  19. package/dist/components/Chip/index.js +2 -0
  20. package/dist/components/DatePicker/DatePicker.svelte +746 -0
  21. package/dist/components/DatePicker/DatePicker.svelte.d.ts +19 -0
  22. package/dist/components/DatePicker/index.d.ts +1 -0
  23. package/dist/components/DatePicker/index.js +1 -0
  24. package/dist/components/FileUpload/FileUpload.svelte +484 -0
  25. package/dist/components/FileUpload/FileUpload.svelte.d.ts +16 -0
  26. package/dist/components/FileUpload/index.d.ts +1 -0
  27. package/dist/components/FileUpload/index.js +1 -0
  28. package/dist/components/Image/Image.svelte +223 -0
  29. package/dist/components/Image/Image.svelte.d.ts +19 -0
  30. package/dist/components/Image/index.d.ts +1 -0
  31. package/dist/components/Image/index.js +1 -0
  32. package/dist/components/NumberInput/NumberInput.svelte +293 -0
  33. package/dist/components/NumberInput/NumberInput.svelte.d.ts +16 -0
  34. package/dist/components/NumberInput/index.d.ts +1 -0
  35. package/dist/components/NumberInput/index.js +1 -0
  36. package/dist/components/OTPInput/OTPInput.svelte +312 -0
  37. package/dist/components/OTPInput/OTPInput.svelte.d.ts +57 -0
  38. package/dist/components/OTPInput/index.d.ts +1 -0
  39. package/dist/components/OTPInput/index.js +1 -0
  40. package/dist/components/Pagination/Pagination.svelte +243 -0
  41. package/dist/components/Pagination/Pagination.svelte.d.ts +10 -0
  42. package/dist/components/Pagination/index.d.ts +1 -0
  43. package/dist/components/Pagination/index.js +1 -0
  44. package/dist/components/Rating/Rating.svelte +316 -0
  45. package/dist/components/Rating/Rating.svelte.d.ts +16 -0
  46. package/dist/components/Rating/index.d.ts +1 -0
  47. package/dist/components/Rating/index.js +1 -0
  48. package/dist/components/SearchInput/SearchInput.svelte +480 -0
  49. package/dist/components/SearchInput/SearchInput.svelte.d.ts +22 -0
  50. package/dist/components/SearchInput/index.d.ts +1 -0
  51. package/dist/components/SearchInput/index.js +1 -0
  52. package/dist/components/Slider/Slider.svelte +324 -0
  53. package/dist/components/Slider/Slider.svelte.d.ts +14 -0
  54. package/dist/components/Slider/index.d.ts +1 -0
  55. package/dist/components/Slider/index.js +1 -0
  56. package/dist/components/Stepper/Stepper.svelte +100 -0
  57. package/dist/components/Stepper/Stepper.svelte.d.ts +11 -0
  58. package/dist/components/Stepper/StepperStep.svelte +391 -0
  59. package/dist/components/Stepper/StepperStep.svelte.d.ts +13 -0
  60. package/dist/components/Stepper/index.d.ts +2 -0
  61. package/dist/components/Stepper/index.js +2 -0
  62. package/dist/components/TimePicker/TimePicker.svelte +803 -0
  63. package/dist/components/TimePicker/TimePicker.svelte.d.ts +17 -0
  64. package/dist/components/TimePicker/index.d.ts +1 -0
  65. package/dist/components/TimePicker/index.js +1 -0
  66. package/dist/components/ToggleGroup/ToggleGroup.svelte +91 -0
  67. package/dist/components/ToggleGroup/ToggleGroup.svelte.d.ts +13 -0
  68. package/dist/components/ToggleGroup/ToggleGroupItem.svelte +158 -0
  69. package/dist/components/ToggleGroup/ToggleGroupItem.svelte.d.ts +9 -0
  70. package/dist/components/ToggleGroup/index.d.ts +3 -0
  71. package/dist/components/ToggleGroup/index.js +2 -0
  72. package/dist/index.d.ts +13 -1
  73. package/dist/index.js +12 -0
  74. package/dist/types/data-display.d.ts +68 -0
  75. package/dist/types/index.d.ts +3 -2
  76. package/dist/types/input.d.ts +82 -0
  77. package/dist/types/input.js +2 -0
  78. package/dist/types/navigation.d.ts +15 -0
  79. package/package.json +1 -1
@@ -0,0 +1,454 @@
1
+ <script lang="ts">
2
+ import { onMount, onDestroy } from 'svelte';
3
+
4
+ interface Props {
5
+ activeIndex?: number;
6
+ autoplay?: boolean;
7
+ autoplayInterval?: number;
8
+ loop?: boolean;
9
+ showIndicators?: boolean;
10
+ showArrows?: boolean;
11
+ class?: string;
12
+ onchange?: (index: number) => void;
13
+ children?: import('svelte').Snippet;
14
+ }
15
+
16
+ let {
17
+ activeIndex = $bindable(0),
18
+ autoplay = false,
19
+ autoplayInterval = 5000,
20
+ loop = true,
21
+ showIndicators = true,
22
+ showArrows = true,
23
+ class: className = '',
24
+ onchange,
25
+ children
26
+ }: Props = $props();
27
+
28
+ let containerRef: HTMLDivElement;
29
+ let slidesRef: HTMLDivElement;
30
+ let slideCount = $state(0);
31
+ let isDragging = $state(false);
32
+ let startX = 0;
33
+ let currentX = 0;
34
+ let autoplayTimer: number | null = null;
35
+ let isHovered = $state(false);
36
+ let isFocused = $state(false);
37
+
38
+ // Derive the transform value
39
+ const translateX = $derived(-activeIndex * 100);
40
+
41
+ // Count slides on mount
42
+ onMount(() => {
43
+ updateSlideCount();
44
+ if (autoplay) {
45
+ startAutoplay();
46
+ }
47
+ });
48
+
49
+ onDestroy(() => {
50
+ stopAutoplay();
51
+ });
52
+
53
+ function updateSlideCount() {
54
+ if (slidesRef) {
55
+ slideCount = slidesRef.children.length;
56
+ }
57
+ }
58
+
59
+ function next() {
60
+ if (activeIndex < slideCount - 1) {
61
+ setActiveIndex(activeIndex + 1);
62
+ } else if (loop) {
63
+ setActiveIndex(0);
64
+ }
65
+ }
66
+
67
+ function prev() {
68
+ if (activeIndex > 0) {
69
+ setActiveIndex(activeIndex - 1);
70
+ } else if (loop) {
71
+ setActiveIndex(slideCount - 1);
72
+ }
73
+ }
74
+
75
+ function goToSlide(index: number) {
76
+ setActiveIndex(index);
77
+ }
78
+
79
+ function setActiveIndex(index: number) {
80
+ if (index !== activeIndex) {
81
+ activeIndex = index;
82
+ onchange?.(index);
83
+ }
84
+ }
85
+
86
+ function handleTouchStart(e: TouchEvent) {
87
+ stopAutoplay();
88
+ isDragging = true;
89
+ startX = e.touches[0].clientX;
90
+ currentX = startX;
91
+ }
92
+
93
+ function handleTouchMove(e: TouchEvent) {
94
+ if (!isDragging) return;
95
+ currentX = e.touches[0].clientX;
96
+ }
97
+
98
+ function handleTouchEnd() {
99
+ if (!isDragging) return;
100
+ isDragging = false;
101
+
102
+ const diff = startX - currentX;
103
+ const threshold = 50;
104
+
105
+ if (Math.abs(diff) > threshold) {
106
+ if (diff > 0) {
107
+ next();
108
+ } else {
109
+ prev();
110
+ }
111
+ }
112
+
113
+ if (autoplay && !isHovered && !isFocused) {
114
+ startAutoplay();
115
+ }
116
+ }
117
+
118
+ function handleKeydown(e: KeyboardEvent) {
119
+ switch (e.key) {
120
+ case 'ArrowLeft':
121
+ e.preventDefault();
122
+ prev();
123
+ break;
124
+ case 'ArrowRight':
125
+ e.preventDefault();
126
+ next();
127
+ break;
128
+ case 'Home':
129
+ e.preventDefault();
130
+ goToSlide(0);
131
+ break;
132
+ case 'End':
133
+ e.preventDefault();
134
+ goToSlide(slideCount - 1);
135
+ break;
136
+ }
137
+ }
138
+
139
+ function startAutoplay() {
140
+ if (!autoplay) return;
141
+ stopAutoplay();
142
+ autoplayTimer = window.setInterval(() => {
143
+ next();
144
+ }, autoplayInterval);
145
+ }
146
+
147
+ function stopAutoplay() {
148
+ if (autoplayTimer !== null) {
149
+ clearInterval(autoplayTimer);
150
+ autoplayTimer = null;
151
+ }
152
+ }
153
+
154
+ function handleMouseEnter() {
155
+ isHovered = true;
156
+ if (autoplay) {
157
+ stopAutoplay();
158
+ }
159
+ }
160
+
161
+ function handleMouseLeave() {
162
+ isHovered = false;
163
+ if (autoplay && !isFocused) {
164
+ startAutoplay();
165
+ }
166
+ }
167
+
168
+ function handleFocus() {
169
+ isFocused = true;
170
+ if (autoplay) {
171
+ stopAutoplay();
172
+ }
173
+ }
174
+
175
+ function handleBlur() {
176
+ isFocused = false;
177
+ if (autoplay && !isHovered) {
178
+ startAutoplay();
179
+ }
180
+ }
181
+
182
+ // Restart autoplay when props change
183
+ $effect(() => {
184
+ if (autoplay) {
185
+ stopAutoplay();
186
+ if (!isHovered && !isFocused) {
187
+ startAutoplay();
188
+ }
189
+ } else {
190
+ stopAutoplay();
191
+ }
192
+ });
193
+
194
+ // Update slide count when children change
195
+ $effect(() => {
196
+ if (children) {
197
+ updateSlideCount();
198
+ }
199
+ });
200
+ </script>
201
+
202
+ <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
203
+ <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
204
+ <div
205
+ class="carousel {className}"
206
+ bind:this={containerRef}
207
+ role="region"
208
+ aria-roledescription="carousel"
209
+ aria-label="Image carousel"
210
+ onmouseenter={handleMouseEnter}
211
+ onmouseleave={handleMouseLeave}
212
+ onfocus={handleFocus}
213
+ onblur={handleBlur}
214
+ onkeydown={handleKeydown}
215
+ tabindex="0"
216
+ >
217
+ <!-- Carousel viewport -->
218
+ <div
219
+ class="carousel__viewport"
220
+ ontouchstart={handleTouchStart}
221
+ ontouchmove={handleTouchMove}
222
+ ontouchend={handleTouchEnd}
223
+ ontouchcancel={handleTouchEnd}
224
+ >
225
+ <div
226
+ bind:this={slidesRef}
227
+ class="carousel__slides"
228
+ style="transform: translateX({translateX}%); transition: {isDragging
229
+ ? 'none'
230
+ : 'transform 300ms cubic-bezier(0.32, 0.72, 0, 1)'};"
231
+ aria-live="polite"
232
+ aria-atomic="false"
233
+ >
234
+ {@render children?.()}
235
+ </div>
236
+ </div>
237
+
238
+ <!-- Previous/Next arrows -->
239
+ {#if showArrows && slideCount > 1}
240
+ <button
241
+ class="carousel__arrow carousel__arrow--prev"
242
+ onclick={prev}
243
+ aria-label="Previous slide"
244
+ disabled={!loop && activeIndex === 0}
245
+ tabindex="-1"
246
+ >
247
+ <svg
248
+ width="24"
249
+ height="24"
250
+ viewBox="0 0 24 24"
251
+ fill="none"
252
+ stroke="currentColor"
253
+ stroke-width="2"
254
+ stroke-linecap="round"
255
+ stroke-linejoin="round"
256
+ aria-hidden="true"
257
+ >
258
+ <polyline points="15 18 9 12 15 6"></polyline>
259
+ </svg>
260
+ </button>
261
+ <button
262
+ class="carousel__arrow carousel__arrow--next"
263
+ onclick={next}
264
+ aria-label="Next slide"
265
+ disabled={!loop && activeIndex === slideCount - 1}
266
+ tabindex="-1"
267
+ >
268
+ <svg
269
+ width="24"
270
+ height="24"
271
+ viewBox="0 0 24 24"
272
+ fill="none"
273
+ stroke="currentColor"
274
+ stroke-width="2"
275
+ stroke-linecap="round"
276
+ stroke-linejoin="round"
277
+ aria-hidden="true"
278
+ >
279
+ <polyline points="9 18 15 12 9 6"></polyline>
280
+ </svg>
281
+ </button>
282
+ {/if}
283
+
284
+ <!-- Indicators -->
285
+ {#if showIndicators && slideCount > 1}
286
+ <div class="carousel__indicators" role="tablist">
287
+ {#each Array(slideCount) as _, index}
288
+ <button
289
+ class="carousel__indicator"
290
+ class:carousel__indicator--active={index === activeIndex}
291
+ onclick={() => goToSlide(index)}
292
+ aria-label="Slide {index + 1} of {slideCount}"
293
+ aria-selected={index === activeIndex}
294
+ role="tab"
295
+ tabindex="-1"
296
+ ></button>
297
+ {/each}
298
+ </div>
299
+ {/if}
300
+ </div>
301
+
302
+ <style>
303
+ .carousel {
304
+ position: relative;
305
+ width: 100%;
306
+ overflow: hidden;
307
+ border-radius: var(--radius-md, 0.375rem);
308
+ }
309
+
310
+ .carousel:focus-visible {
311
+ outline: 2px solid var(--color-primary, #3b82f6);
312
+ outline-offset: 2px;
313
+ }
314
+
315
+ .carousel__viewport {
316
+ position: relative;
317
+ width: 100%;
318
+ overflow: hidden;
319
+ touch-action: pan-y;
320
+ }
321
+
322
+ .carousel__slides {
323
+ display: flex;
324
+ width: 100%;
325
+ }
326
+
327
+ /* Arrows */
328
+ .carousel__arrow {
329
+ position: absolute;
330
+ top: 50%;
331
+ transform: translateY(-50%);
332
+ display: flex;
333
+ align-items: center;
334
+ justify-content: center;
335
+ min-width: 44px;
336
+ min-height: 44px;
337
+ width: 2.75rem;
338
+ height: 2.75rem;
339
+ padding: 0;
340
+ background: rgba(255, 255, 255, 0.9);
341
+ border: 1px solid var(--color-border, #e5e7eb);
342
+ border-radius: var(--radius-full, 9999px);
343
+ color: var(--color-text, #1f2937);
344
+ font-family: inherit;
345
+ cursor: pointer;
346
+ transition: all var(--transition-fast, 150ms ease);
347
+ z-index: 2;
348
+ -webkit-tap-highlight-color: transparent;
349
+ }
350
+
351
+ .carousel__arrow:hover:not(:disabled) {
352
+ background: rgba(255, 255, 255, 1);
353
+ box-shadow: var(--shadow-md, 0 4px 6px rgba(0, 0, 0, 0.1));
354
+ }
355
+
356
+ .carousel__arrow:active:not(:disabled) {
357
+ transform: translateY(-50%) scale(0.95);
358
+ }
359
+
360
+ .carousel__arrow:disabled {
361
+ opacity: 0.5;
362
+ cursor: not-allowed;
363
+ pointer-events: none;
364
+ }
365
+
366
+ .carousel__arrow:focus-visible {
367
+ outline: 2px solid var(--color-primary, #3b82f6);
368
+ outline-offset: 2px;
369
+ }
370
+
371
+ .carousel__arrow--prev {
372
+ left: var(--space-md, 1rem);
373
+ }
374
+
375
+ .carousel__arrow--next {
376
+ right: var(--space-md, 1rem);
377
+ }
378
+
379
+ /* Indicators */
380
+ .carousel__indicators {
381
+ position: absolute;
382
+ bottom: var(--space-md, 1rem);
383
+ left: 50%;
384
+ transform: translateX(-50%);
385
+ display: flex;
386
+ gap: var(--space-sm, 0.5rem);
387
+ padding: var(--space-sm, 0.5rem);
388
+ background: rgba(0, 0, 0, 0.3);
389
+ border-radius: var(--radius-full, 9999px);
390
+ z-index: 2;
391
+ }
392
+
393
+ .carousel__indicator {
394
+ width: 0.5rem;
395
+ height: 0.5rem;
396
+ min-width: 44px;
397
+ min-height: 44px;
398
+ padding: 0;
399
+ background: rgba(255, 255, 255, 0.5);
400
+ border: none;
401
+ border-radius: var(--radius-full, 9999px);
402
+ cursor: pointer;
403
+ transition: all var(--transition-fast, 150ms ease);
404
+ position: relative;
405
+ -webkit-tap-highlight-color: transparent;
406
+ }
407
+
408
+ .carousel__indicator::before {
409
+ content: '';
410
+ position: absolute;
411
+ top: 50%;
412
+ left: 50%;
413
+ transform: translate(-50%, -50%);
414
+ width: 0.5rem;
415
+ height: 0.5rem;
416
+ background: currentColor;
417
+ border-radius: var(--radius-full, 9999px);
418
+ opacity: 0.5;
419
+ transition: opacity var(--transition-fast, 150ms ease);
420
+ }
421
+
422
+ .carousel__indicator--active::before {
423
+ background: rgba(255, 255, 255, 1);
424
+ opacity: 1;
425
+ }
426
+
427
+ .carousel__indicator:hover::before {
428
+ opacity: 0.8;
429
+ }
430
+
431
+ .carousel__indicator:focus-visible {
432
+ outline: 2px solid var(--color-primary, #3b82f6);
433
+ outline-offset: 2px;
434
+ }
435
+
436
+ /* Responsive adjustments */
437
+ @media (min-width: 640px) {
438
+ .carousel__arrow {
439
+ width: 3rem;
440
+ height: 3rem;
441
+ }
442
+ }
443
+
444
+ /* Dark mode support */
445
+ :global([data-theme='dark']) .carousel__arrow {
446
+ background: rgba(31, 41, 55, 0.9);
447
+ border-color: var(--color-border, #374151);
448
+ color: var(--color-text, #f9fafb);
449
+ }
450
+
451
+ :global([data-theme='dark']) .carousel__arrow:hover:not(:disabled) {
452
+ background: rgba(31, 41, 55, 1);
453
+ }
454
+ </style>
@@ -0,0 +1,14 @@
1
+ interface Props {
2
+ activeIndex?: number;
3
+ autoplay?: boolean;
4
+ autoplayInterval?: number;
5
+ loop?: boolean;
6
+ showIndicators?: boolean;
7
+ showArrows?: boolean;
8
+ class?: string;
9
+ onchange?: (index: number) => void;
10
+ children?: import('svelte').Snippet;
11
+ }
12
+ declare const Carousel: import("svelte").Component<Props, {}, "activeIndex">;
13
+ type Carousel = ReturnType<typeof Carousel>;
14
+ export default Carousel;
@@ -0,0 +1,22 @@
1
+ <script lang="ts">
2
+ interface Props {
3
+ class?: string;
4
+ children?: import('svelte').Snippet;
5
+ }
6
+
7
+ let { class: className = '', children }: Props = $props();
8
+ </script>
9
+
10
+ <div class="carousel-slide {className}">
11
+ {@render children?.()}
12
+ </div>
13
+
14
+ <style>
15
+ .carousel-slide {
16
+ flex: 0 0 100%;
17
+ min-width: 100%;
18
+ display: flex;
19
+ align-items: center;
20
+ justify-content: center;
21
+ }
22
+ </style>
@@ -0,0 +1,7 @@
1
+ interface Props {
2
+ class?: string;
3
+ children?: import('svelte').Snippet;
4
+ }
5
+ declare const CarouselSlide: import("svelte").Component<Props, {}, "">;
6
+ type CarouselSlide = ReturnType<typeof CarouselSlide>;
7
+ export default CarouselSlide;
@@ -0,0 +1,2 @@
1
+ export { default as Carousel } from './Carousel.svelte';
2
+ export { default as CarouselSlide } from './CarouselSlide.svelte';
@@ -0,0 +1,2 @@
1
+ export { default as Carousel } from './Carousel.svelte';
2
+ export { default as CarouselSlide } from './CarouselSlide.svelte';