@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,79 @@
1
+ <script lang="ts">
2
+ import { setContext } from 'svelte';
3
+
4
+ interface Props {
5
+ value?: string | string[];
6
+ multiple?: boolean;
7
+ disabled?: boolean;
8
+ class?: string;
9
+ children?: import('svelte').Snippet;
10
+ }
11
+
12
+ let {
13
+ value = $bindable([]),
14
+ multiple = false,
15
+ disabled = false,
16
+ class: className = '',
17
+ children
18
+ }: Props = $props();
19
+
20
+ // Normalize value to always work with arrays internally
21
+ let expandedItems = $derived.by(() => {
22
+ if (Array.isArray(value)) {
23
+ return value;
24
+ }
25
+ return value ? [value] : [];
26
+ });
27
+
28
+ // Context key
29
+ const ACCORDION_KEY = Symbol('accordion');
30
+
31
+ // Context API
32
+ const accordionContext = {
33
+ isExpanded: (itemValue: string): boolean => {
34
+ return expandedItems.includes(itemValue);
35
+ },
36
+ toggle: (itemValue: string): void => {
37
+ if (disabled) return;
38
+
39
+ const isCurrentlyExpanded = expandedItems.includes(itemValue);
40
+
41
+ if (multiple) {
42
+ // Multiple mode: toggle the item in the array
43
+ if (isCurrentlyExpanded) {
44
+ value = expandedItems.filter((v) => v !== itemValue) as typeof value;
45
+ } else {
46
+ value = [...expandedItems, itemValue] as typeof value;
47
+ }
48
+ } else {
49
+ // Single mode: replace with new value or clear
50
+ if (isCurrentlyExpanded) {
51
+ value = (Array.isArray(value) ? [] : '') as typeof value;
52
+ } else {
53
+ value = (Array.isArray(value) ? [itemValue] : itemValue) as typeof value;
54
+ }
55
+ }
56
+ },
57
+ isDisabled: (): boolean => disabled
58
+ };
59
+
60
+ setContext(ACCORDION_KEY, accordionContext);
61
+ </script>
62
+
63
+ <div class="accordion {className}" role="presentation">
64
+ {#if children}
65
+ {@render children()}
66
+ {/if}
67
+ </div>
68
+
69
+ <style>
70
+ .accordion {
71
+ display: flex;
72
+ flex-direction: column;
73
+ width: 100%;
74
+ border: 1px solid var(--color-border, #e5e7eb);
75
+ border-radius: var(--radius-md, 0.375rem);
76
+ background: var(--color-bg-card, #ffffff);
77
+ overflow: hidden;
78
+ }
79
+ </style>
@@ -0,0 +1,10 @@
1
+ interface Props {
2
+ value?: string | string[];
3
+ multiple?: boolean;
4
+ disabled?: boolean;
5
+ class?: string;
6
+ children?: import('svelte').Snippet;
7
+ }
8
+ declare const Accordion: import("svelte").Component<Props, {}, "value">;
9
+ type Accordion = ReturnType<typeof Accordion>;
10
+ export default Accordion;
@@ -0,0 +1,198 @@
1
+ <script lang="ts">
2
+ import { getContext } from 'svelte';
3
+
4
+ interface Props {
5
+ value: string;
6
+ disabled?: boolean;
7
+ class?: string;
8
+ header?: import('svelte').Snippet;
9
+ children?: import('svelte').Snippet;
10
+ }
11
+
12
+ let { value, disabled = false, class: className = '', header, children }: Props = $props();
13
+
14
+ // Context key (must match parent)
15
+ const ACCORDION_KEY = Symbol('accordion');
16
+
17
+ // Get context from parent Accordion
18
+ const ctx = getContext<{
19
+ isExpanded: (value: string) => boolean;
20
+ toggle: (value: string) => void;
21
+ isDisabled: () => boolean;
22
+ }>(ACCORDION_KEY);
23
+
24
+ // Generate unique IDs for ARIA (using $derived to avoid warnings)
25
+ const headerId = $derived(`accordion-header-${value}`);
26
+ const bodyId = $derived(`accordion-body-${value}`);
27
+
28
+ // Derived states
29
+ const isExpanded = $derived(ctx.isExpanded(value));
30
+ const isDisabled = $derived(disabled || ctx.isDisabled());
31
+
32
+ // Toggle handler
33
+ function handleToggle() {
34
+ if (!isDisabled) {
35
+ ctx.toggle(value);
36
+ }
37
+ }
38
+
39
+ // Keyboard handler
40
+ function handleKeydown(event: KeyboardEvent) {
41
+ if (event.key === 'Enter' || event.key === ' ') {
42
+ event.preventDefault();
43
+ handleToggle();
44
+ }
45
+ }
46
+
47
+ // Body element reference for height animation
48
+ let bodyElement: HTMLDivElement | undefined = $state();
49
+
50
+ // Height calculation for smooth animation
51
+ const contentHeight = $derived.by(() => {
52
+ if (!bodyElement) return '0px';
53
+ if (!isExpanded) return '0px';
54
+
55
+ // Get the actual scrollHeight when expanded
56
+ const height = bodyElement.scrollHeight;
57
+ return `${height}px`;
58
+ });
59
+ </script>
60
+
61
+ <div class="accordion-item {className}">
62
+ <button
63
+ id={headerId}
64
+ class="accordion-header"
65
+ type="button"
66
+ aria-expanded={isExpanded}
67
+ aria-controls={bodyId}
68
+ disabled={isDisabled}
69
+ onclick={handleToggle}
70
+ onkeydown={handleKeydown}
71
+ >
72
+ <span class="accordion-header__content">
73
+ {#if header}
74
+ {@render header()}
75
+ {/if}
76
+ </span>
77
+ <svg
78
+ class="accordion-header__chevron"
79
+ class:accordion-header__chevron--expanded={isExpanded}
80
+ width="20"
81
+ height="20"
82
+ viewBox="0 0 20 20"
83
+ fill="none"
84
+ xmlns="http://www.w3.org/2000/svg"
85
+ aria-hidden="true"
86
+ >
87
+ <path
88
+ d="M5 7.5L10 12.5L15 7.5"
89
+ stroke="currentColor"
90
+ stroke-width="2"
91
+ stroke-linecap="round"
92
+ stroke-linejoin="round"
93
+ />
94
+ </svg>
95
+ </button>
96
+
97
+ <div
98
+ bind:this={bodyElement}
99
+ id={bodyId}
100
+ class="accordion-body"
101
+ class:accordion-body--expanded={isExpanded}
102
+ role="region"
103
+ aria-labelledby={headerId}
104
+ style="--content-height: {contentHeight}"
105
+ >
106
+ <div class="accordion-body__content">
107
+ {#if children}
108
+ {@render children()}
109
+ {/if}
110
+ </div>
111
+ </div>
112
+ </div>
113
+
114
+ <style>
115
+ .accordion-item {
116
+ border-bottom: 1px solid var(--color-border, #e5e7eb);
117
+ }
118
+
119
+ .accordion-item:last-child {
120
+ border-bottom: none;
121
+ }
122
+
123
+ /* Header */
124
+ .accordion-header {
125
+ display: flex;
126
+ align-items: center;
127
+ justify-content: space-between;
128
+ width: 100%;
129
+ min-height: var(--touch-target-min, 44px);
130
+ padding: var(--space-md, 1rem);
131
+ border: none;
132
+ background: transparent;
133
+ color: var(--color-text, #1f2937);
134
+ font-family: inherit;
135
+ font-size: var(--text-base, 1rem);
136
+ font-weight: var(--font-medium, 500);
137
+ text-align: left;
138
+ cursor: pointer;
139
+ transition: background-color var(--transition-fast, 150ms ease);
140
+ -webkit-tap-highlight-color: transparent;
141
+ }
142
+
143
+ .accordion-header:hover:not(:disabled) {
144
+ background: var(--color-bg-hover, #f3f4f6);
145
+ }
146
+
147
+ .accordion-header:focus-visible {
148
+ outline: 2px solid var(--color-primary, #3b82f6);
149
+ outline-offset: -2px;
150
+ }
151
+
152
+ .accordion-header:disabled {
153
+ opacity: 0.5;
154
+ cursor: not-allowed;
155
+ }
156
+
157
+ .accordion-header__content {
158
+ flex: 1;
159
+ display: flex;
160
+ align-items: center;
161
+ }
162
+
163
+ .accordion-header__chevron {
164
+ flex-shrink: 0;
165
+ margin-left: var(--space-sm, 0.5rem);
166
+ color: var(--color-text-muted, #6b7280);
167
+ transition: transform var(--transition-base, 200ms ease);
168
+ }
169
+
170
+ .accordion-header__chevron--expanded {
171
+ transform: rotate(180deg);
172
+ }
173
+
174
+ /* Body */
175
+ .accordion-body {
176
+ max-height: 0;
177
+ overflow: hidden;
178
+ transition: max-height var(--transition-base, 200ms ease);
179
+ }
180
+
181
+ .accordion-body--expanded {
182
+ max-height: var(--content-height);
183
+ }
184
+
185
+ .accordion-body__content {
186
+ padding: 0 var(--space-md, 1rem) var(--space-md, 1rem);
187
+ color: var(--color-text-muted, #6b7280);
188
+ font-size: var(--text-sm, 0.875rem);
189
+ line-height: var(--leading-normal, 1.5);
190
+ }
191
+
192
+ /* Mobile optimization - ensure min touch target */
193
+ @media (max-width: 640px) {
194
+ .accordion-header {
195
+ min-height: var(--touch-target-min, 44px);
196
+ }
197
+ }
198
+ </style>
@@ -0,0 +1,10 @@
1
+ interface Props {
2
+ value: string;
3
+ disabled?: boolean;
4
+ class?: string;
5
+ header?: import('svelte').Snippet;
6
+ children?: import('svelte').Snippet;
7
+ }
8
+ declare const AccordionItem: import("svelte").Component<Props, {}, "">;
9
+ type AccordionItem = ReturnType<typeof AccordionItem>;
10
+ export default AccordionItem;
@@ -0,0 +1,2 @@
1
+ export { default as Accordion } from './Accordion.svelte';
2
+ export { default as AccordionItem } from './AccordionItem.svelte';
@@ -0,0 +1,2 @@
1
+ export { default as Accordion } from './Accordion.svelte';
2
+ export { default as AccordionItem } from './AccordionItem.svelte';