aeico-components 0.1.1

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 (174) hide show
  1. package/README.md +0 -0
  2. package/dist/index.cjs +4226 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.js +4226 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/types/aeico-component.d.ts +8 -0
  7. package/dist/types/aeico-field.d.ts +132 -0
  8. package/dist/types/alert/alert.d.ts +49 -0
  9. package/dist/types/alert/defines.d.ts +3 -0
  10. package/dist/types/alert/index.d.ts +3 -0
  11. package/dist/types/badge/badge.d.ts +34 -0
  12. package/dist/types/badge/defines.d.ts +3 -0
  13. package/dist/types/badge/index.d.ts +3 -0
  14. package/dist/types/breadcrumb/breadcrumb-item.d.ts +31 -0
  15. package/dist/types/breadcrumb/breadcrumb.d.ts +60 -0
  16. package/dist/types/breadcrumb/defines.d.ts +1 -0
  17. package/dist/types/breadcrumb/index.d.ts +5 -0
  18. package/dist/types/button/button.d.ts +60 -0
  19. package/dist/types/button/defines.d.ts +3 -0
  20. package/dist/types/button/index.d.ts +3 -0
  21. package/dist/types/button-group/button-group.d.ts +56 -0
  22. package/dist/types/button-group/index.d.ts +2 -0
  23. package/dist/types/card/card.d.ts +19 -0
  24. package/dist/types/card/defines.d.ts +2 -0
  25. package/dist/types/card/index.d.ts +3 -0
  26. package/dist/types/checkbox/checkbox.d.ts +37 -0
  27. package/dist/types/checkbox/defines.d.ts +1 -0
  28. package/dist/types/checkbox/index.d.ts +3 -0
  29. package/dist/types/detail/defines.d.ts +2 -0
  30. package/dist/types/detail/detail.d.ts +40 -0
  31. package/dist/types/detail/index.d.ts +3 -0
  32. package/dist/types/dialog/dialog.d.ts +29 -0
  33. package/dist/types/dialog/index.d.ts +2 -0
  34. package/dist/types/divider/divider.d.ts +34 -0
  35. package/dist/types/divider/index.d.ts +2 -0
  36. package/dist/types/dropdown/defines.d.ts +1 -0
  37. package/dist/types/dropdown/dropdown-button.d.ts +60 -0
  38. package/dist/types/dropdown/dropdown-item.d.ts +56 -0
  39. package/dist/types/dropdown/dropdown.d.ts +84 -0
  40. package/dist/types/dropdown/index.d.ts +7 -0
  41. package/dist/types/icon/defines.d.ts +10 -0
  42. package/dist/types/icon/icon.d.ts +21 -0
  43. package/dist/types/icon/index.d.ts +4 -0
  44. package/dist/types/icon/registry.d.ts +8 -0
  45. package/dist/types/icon-button/icon-button.d.ts +32 -0
  46. package/dist/types/icon-button/index.d.ts +2 -0
  47. package/dist/types/index.d.ts +74 -0
  48. package/dist/types/navbar/defines.d.ts +2 -0
  49. package/dist/types/navbar/index.d.ts +3 -0
  50. package/dist/types/navbar/navbar.d.ts +73 -0
  51. package/dist/types/radio-group/defines.d.ts +6 -0
  52. package/dist/types/radio-group/index.d.ts +5 -0
  53. package/dist/types/radio-group/radio-group.d.ts +41 -0
  54. package/dist/types/radio-group/radio.d.ts +47 -0
  55. package/dist/types/select/defines.d.ts +8 -0
  56. package/dist/types/select/index.d.ts +5 -0
  57. package/dist/types/select/select-option.d.ts +20 -0
  58. package/dist/types/select/select.d.ts +60 -0
  59. package/dist/types/slider/defines.d.ts +31 -0
  60. package/dist/types/slider/index.d.ts +3 -0
  61. package/dist/types/slider/slider.d.ts +45 -0
  62. package/dist/types/switch/index.d.ts +2 -0
  63. package/dist/types/switch/switch.d.ts +35 -0
  64. package/dist/types/tabs/defines.d.ts +1 -0
  65. package/dist/types/tabs/index.d.ts +3 -0
  66. package/dist/types/tabs/tab-panel.d.ts +11 -0
  67. package/dist/types/tabs/tab.d.ts +18 -0
  68. package/dist/types/tabs/tabs.d.ts +24 -0
  69. package/dist/types/tag/defines.d.ts +3 -0
  70. package/dist/types/tag/index.d.ts +3 -0
  71. package/dist/types/tag/tag.d.ts +36 -0
  72. package/dist/types/text-input/index.d.ts +2 -0
  73. package/dist/types/text-input/text-input.d.ts +26 -0
  74. package/dist/types/utils.d.ts +2 -0
  75. package/package.json +63 -0
  76. package/src/aeico-component.ts +17 -0
  77. package/src/aeico-field.ts +228 -0
  78. package/src/alert/alert.ts +107 -0
  79. package/src/alert/defines.ts +11 -0
  80. package/src/alert/index.ts +3 -0
  81. package/src/badge/badge.ts +62 -0
  82. package/src/badge/defines.ts +12 -0
  83. package/src/badge/index.ts +3 -0
  84. package/src/breadcrumb/breadcrumb-item.ts +61 -0
  85. package/src/breadcrumb/breadcrumb.ts +138 -0
  86. package/src/breadcrumb/defines.ts +10 -0
  87. package/src/breadcrumb/index.ts +5 -0
  88. package/src/button/button.ts +147 -0
  89. package/src/button/defines.ts +12 -0
  90. package/src/button/index.ts +3 -0
  91. package/src/button-group/button-group.ts +140 -0
  92. package/src/button-group/index.ts +2 -0
  93. package/src/card/card.ts +57 -0
  94. package/src/card/defines.ts +11 -0
  95. package/src/card/index.ts +3 -0
  96. package/src/checkbox/checkbox.ts +90 -0
  97. package/src/checkbox/defines.ts +1 -0
  98. package/src/checkbox/index.ts +3 -0
  99. package/src/detail/defines.ts +11 -0
  100. package/src/detail/detail.ts +122 -0
  101. package/src/detail/index.ts +3 -0
  102. package/src/dialog/dialog.ts +149 -0
  103. package/src/dialog/index.ts +2 -0
  104. package/src/divider/divider.ts +56 -0
  105. package/src/divider/index.ts +2 -0
  106. package/src/dropdown/defines.ts +13 -0
  107. package/src/dropdown/dropdown-button.ts +130 -0
  108. package/src/dropdown/dropdown-item.ts +136 -0
  109. package/src/dropdown/dropdown.ts +211 -0
  110. package/src/dropdown/index.ts +7 -0
  111. package/src/icon/defines.ts +21 -0
  112. package/src/icon/icon.ts +84 -0
  113. package/src/icon/index.ts +4 -0
  114. package/src/icon/registry.ts +25 -0
  115. package/src/icon-button/icon-button.ts +64 -0
  116. package/src/icon-button/index.ts +2 -0
  117. package/src/index.ts +85 -0
  118. package/src/navbar/defines.ts +11 -0
  119. package/src/navbar/index.ts +3 -0
  120. package/src/navbar/navbar.ts +162 -0
  121. package/src/radio-group/defines.ts +5 -0
  122. package/src/radio-group/index.ts +5 -0
  123. package/src/radio-group/radio-group.ts +227 -0
  124. package/src/radio-group/radio.ts +58 -0
  125. package/src/select/defines.ts +12 -0
  126. package/src/select/index.ts +5 -0
  127. package/src/select/select-option.ts +59 -0
  128. package/src/select/select.ts +387 -0
  129. package/src/slider/defines.ts +33 -0
  130. package/src/slider/index.ts +3 -0
  131. package/src/slider/slider.ts +364 -0
  132. package/src/styles/color.css +117 -0
  133. package/src/styles/components/alert.css +104 -0
  134. package/src/styles/components/badge.css +67 -0
  135. package/src/styles/components/breadcrumb-item.css +59 -0
  136. package/src/styles/components/breadcrumb.css +19 -0
  137. package/src/styles/components/button-group.css +25 -0
  138. package/src/styles/components/button.css +213 -0
  139. package/src/styles/components/card.css +64 -0
  140. package/src/styles/components/checkbox.css +78 -0
  141. package/src/styles/components/detail.css +127 -0
  142. package/src/styles/components/dialog.css +103 -0
  143. package/src/styles/components/divider.css +18 -0
  144. package/src/styles/components/dropdown-item.css +91 -0
  145. package/src/styles/components/dropdown.css +179 -0
  146. package/src/styles/components/icon-button.css +116 -0
  147. package/src/styles/components/icon.css +29 -0
  148. package/src/styles/components/navbar.css +250 -0
  149. package/src/styles/components/radio-group.css +360 -0
  150. package/src/styles/components/select-option.css +43 -0
  151. package/src/styles/components/select.css +222 -0
  152. package/src/styles/components/slider.css +326 -0
  153. package/src/styles/components/switch.css +117 -0
  154. package/src/styles/components/tab-panel.css +8 -0
  155. package/src/styles/components/tab.css +44 -0
  156. package/src/styles/components/tabs.css +16 -0
  157. package/src/styles/components/tag.css +107 -0
  158. package/src/styles/components/text-input.css +110 -0
  159. package/src/styles/layout.css +43 -0
  160. package/src/styles/size.css +7 -0
  161. package/src/styles/variables.css +368 -0
  162. package/src/switch/index.ts +2 -0
  163. package/src/switch/switch.ts +88 -0
  164. package/src/tabs/defines.ts +1 -0
  165. package/src/tabs/index.ts +3 -0
  166. package/src/tabs/tab-panel.ts +23 -0
  167. package/src/tabs/tab.ts +62 -0
  168. package/src/tabs/tabs.ts +134 -0
  169. package/src/tag/defines.ts +12 -0
  170. package/src/tag/index.ts +3 -0
  171. package/src/tag/tag.ts +85 -0
  172. package/src/text-input/index.ts +2 -0
  173. package/src/text-input/text-input.ts +75 -0
  174. package/src/utils.ts +6 -0
@@ -0,0 +1,387 @@
1
+ import AeicoField from '../aeico-field';
2
+ import type { InferProps } from 'aeico';
3
+ import { html, tags } from 'aeico';
4
+ import { t } from 'aeico-localize';
5
+ import type {
6
+ SelectOptionValue,
7
+ SelectOption,
8
+ SelectOptions,
9
+ SelectPosition,
10
+ SelectMultiValue,
11
+ } from './defines';
12
+ import style from '../styles/components/select.css?inline';
13
+ import variables from '../styles/variables.css?inline';
14
+ import sizeCSS from '../styles/size.css?inline';
15
+ import SelectOptionElement from './select-option';
16
+ import '../tag/tag';
17
+ import { prop } from 'aeico';
18
+
19
+ /**
20
+ * Select component supporting single and multi-select modes, with options provided via both props and slots.
21
+ * - `options` prop accepts an array of strings or objects with `value` and `label` for programmatic options.
22
+ * - Slot content allows for declarative options using `<ae-select-option>` elements.
23
+ * @example
24
+ * <ae-select placeholder="Choose an option" position="bottom">
25
+ * <ae-select-option value="1" label="Option 1">Option 1</ae-select-option>
26
+ * <ae-select-option value="2" label="Option 2">Option 2</ae-select-option>
27
+ * </ae-select>
28
+ *
29
+ */
30
+ class Select extends AeicoField<SelectOptionValue | SelectMultiValue> {
31
+ protected fieldElement = null;
32
+ private _isOpen = false;
33
+ private _triggerEl: HTMLElement | null = null;
34
+ private _dropdownEl: HTMLElement | null = null;
35
+ private _slotEl: HTMLSlotElement | null = null;
36
+ private _slotOptionData: Array<{ value: string; label: string }> = [];
37
+ private _selectedListEl: HTMLElement | null = null;
38
+
39
+ static tagName = 'select';
40
+
41
+ @prop({ type: Boolean, observe: false, reflect: false })
42
+ accessor _expanded: boolean = false;
43
+
44
+ @prop({ type: Array })
45
+ accessor options: SelectOptions | undefined;
46
+
47
+ @prop({ type: String })
48
+ accessor position: SelectPosition | undefined;
49
+
50
+ @prop({ type: String })
51
+ accessor placeholder: string | undefined;
52
+
53
+ @prop({ type: Boolean })
54
+ accessor multiple: boolean = false;
55
+
56
+ @prop({ type: Boolean })
57
+ accessor expandable: boolean = false;
58
+
59
+ // Override base class value prop to support both string and array (multi-select).
60
+ // Uses field decorator (not accessor) because TypeScript TS2611 disallows overriding
61
+ // a parent class data property (declare value?) with an accessor in a subclass.
62
+ @prop({
63
+ type: String,
64
+ parser: (v) => {
65
+ if (v === null || v === undefined) return undefined;
66
+ try {
67
+ return JSON.parse(v);
68
+ } catch {
69
+ return v;
70
+ }
71
+ },
72
+ formatter: (v) => {
73
+ if (v === null || v === undefined) return '';
74
+ if (Array.isArray(v)) return JSON.stringify(v);
75
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
76
+ return String(v);
77
+ },
78
+ })
79
+ override value: SelectOptionValue | SelectMultiValue | undefined = undefined;
80
+
81
+ // Override base class defaultValue so arrays are JSON-serialized to the attribute,
82
+ // matching the value prop's parser/formatter. Without this override, setting
83
+ // defaultValue = ['a', 'b'] would be serialized as String(['a','b']) = "a,b",
84
+ // and reset() would restore a single string "a,b" instead of the array.
85
+ @prop({
86
+ type: String,
87
+ parser: (v) => {
88
+ if (v === null || v === undefined) return undefined;
89
+ try {
90
+ return JSON.parse(v);
91
+ } catch {
92
+ return v;
93
+ }
94
+ },
95
+ formatter: (v) => {
96
+ if (v === null || v === undefined) return '';
97
+ if (Array.isArray(v)) return JSON.stringify(v);
98
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
99
+ return String(v);
100
+ },
101
+ })
102
+ override defaultValue: SelectOptionValue | SelectMultiValue | undefined = undefined;
103
+
104
+ protected static styles = [variables, sizeCSS, style];
105
+
106
+ protected writeValue(_value: SelectOptionValue | SelectMultiValue): void {
107
+ // Reactive re-render via this.value prop change handles the display update
108
+ }
109
+
110
+ protected getValue(): any {
111
+ if (this.multiple) return this._getMultiValues();
112
+
113
+ return this.value || '';
114
+ }
115
+
116
+ private _getMultiValues(): SelectMultiValue {
117
+ if (Array.isArray(this.value)) return this.value;
118
+ if (this.value != null && this.value !== '') return [this.value];
119
+
120
+ return [];
121
+ }
122
+
123
+ protected onDisabledChanged(_newValue: boolean): void {
124
+ // disabled is a reactive prop — render() already picks it up automatically
125
+ }
126
+
127
+ protected onUpdated(_changedProps: Map<string, unknown>): void {
128
+ if (!this.multiple || this.expandable) {
129
+ if (this._expanded) this._expanded = false;
130
+ return;
131
+ }
132
+ const list = this._selectedListEl;
133
+ if (!list) return;
134
+ const overflowing = list.scrollWidth > list.clientWidth + 1;
135
+ if (overflowing !== this._expanded) this._expanded = overflowing;
136
+ }
137
+
138
+ private _findLabel(value: SelectOptionValue): string {
139
+ const strVal = String(value);
140
+ if (Array.isArray(this.options)) {
141
+ for (const opt of this.options) {
142
+ if (this._isSelectOption(opt)) {
143
+ if (String(opt.value) === strVal) return t(opt.label, opt.label);
144
+ } else {
145
+ if (String(opt) === strVal) return strVal;
146
+ }
147
+ }
148
+ }
149
+
150
+ for (const opt of this._slotOptionData) {
151
+ if (opt.value === strVal) return opt.label;
152
+ }
153
+
154
+ return strVal;
155
+ }
156
+
157
+ private _onSlotChange(): void {
158
+ if (!this._slotEl) return;
159
+ const data: Array<{ value: string; label: string }> = [];
160
+ for (const el of this._slotEl.assignedElements({ flatten: true })) {
161
+ if (el.tagName.toLowerCase() !== 'ae-select-option') continue;
162
+ const optEl = el as SelectOptionElement;
163
+ data.push({
164
+ value: optEl.value ?? el.getAttribute('value') ?? '',
165
+ label: optEl.label || el.textContent?.trim() || '',
166
+ });
167
+ }
168
+ this._slotOptionData = data;
169
+ this.update();
170
+ }
171
+
172
+ private _toggleDropdown(): void {
173
+ if (this._isOpen) {
174
+ this._closeDropdown();
175
+ } else {
176
+ this._openDropdown();
177
+ }
178
+ }
179
+
180
+ private _openDropdown(): void {
181
+ this._isOpen = true;
182
+ this._syncOpenState();
183
+ }
184
+
185
+ private _closeDropdown(): void {
186
+ this._isOpen = false;
187
+ this._syncOpenState();
188
+ }
189
+
190
+ private _syncOpenState(): void {
191
+ this._triggerEl?.classList.toggle('open', this._isOpen);
192
+ this._dropdownEl?.classList.toggle('open', this._isOpen);
193
+ }
194
+
195
+ private readonly _handleOutsideClick = (e: Event): void => {
196
+ if (!e.composedPath().includes(this)) {
197
+ this._closeDropdown();
198
+ }
199
+ };
200
+
201
+ private readonly _handleOptionSelect = (e: Event): void => {
202
+ const { value, label } = (e as CustomEvent<{ value: string; label: string }>).detail;
203
+ if (!this._slotOptionData.find((o) => o.value === value)) {
204
+ this._slotOptionData = [
205
+ ...this._slotOptionData.filter((o) => o.value !== value),
206
+ { value, label },
207
+ ];
208
+ }
209
+ if (this.multiple) {
210
+ const current = this._getMultiValues();
211
+ const idx = current.findIndex((v) => String(v) === value);
212
+ const next: SelectMultiValue =
213
+ idx >= 0 ? current.filter((_, i) => i !== idx) : [...current, value];
214
+
215
+ this.setValue(next, { silent: false, action: 'change' });
216
+ } else {
217
+ this.setValue(value, { silent: false, action: 'change' });
218
+ this._closeDropdown();
219
+ }
220
+ };
221
+
222
+ connectedCallback() {
223
+ super.connectedCallback();
224
+ document.addEventListener('click', this._handleOutsideClick);
225
+ this.addEventListener('selectoption', this._handleOptionSelect);
226
+ }
227
+
228
+ disconnectedCallback() {
229
+ super.disconnectedCallback();
230
+ document.removeEventListener('click', this._handleOutsideClick);
231
+ this.removeEventListener('selectoption', this._handleOptionSelect);
232
+ }
233
+
234
+ private _syncSlotOptionsSelected(): void {
235
+ if (!this._slotEl) return;
236
+ const multiValues = this._getMultiValues();
237
+ for (const el of this._slotEl.assignedElements({ flatten: true })) {
238
+ if (el.tagName.toLowerCase() !== 'ae-select-option') continue;
239
+ const optEl = el as SelectOptionElement;
240
+ const optVal = optEl.value ?? el.getAttribute('value') ?? '';
241
+ const isSelected = this.multiple
242
+ ? multiValues.some((v) => String(v) === optVal)
243
+ : this.value != null && this.value !== '' && String(this.value) === optVal;
244
+ // undefined triggers removeAttribute via reactive setter
245
+ // (null would work too but undefined is type-safe for boolean | undefined)
246
+ optEl.selected = isSelected ? true : undefined;
247
+ }
248
+ }
249
+
250
+ render() {
251
+ const position = this.position || 'bottom';
252
+ const multiValues = this.multiple ? this._getMultiValues() : [];
253
+ const hasMultiSelection = this.multiple && multiValues.length > 0;
254
+ const selectedLabel =
255
+ !this.multiple && this.value != null && this.value !== ''
256
+ ? this._findLabel(this.value as SelectOptionValue)
257
+ : '';
258
+ const isDisabled = Boolean(this.disabled);
259
+ this._selectedListEl = null;
260
+
261
+ this._syncSlotOptionsSelected();
262
+
263
+ return html(({ div, span, slot }) => {
264
+ div({ className: 'container' }, () => {
265
+ this._triggerEl = div(
266
+ {
267
+ className: `trigger${this._isOpen ? ' open' : ''}${isDisabled ? ' disabled' : ''}`,
268
+ '@click': () => {
269
+ if (isDisabled) return;
270
+
271
+ this._toggleDropdown();
272
+ },
273
+ },
274
+ () => {
275
+ if (this.multiple) {
276
+ if (hasMultiSelection) {
277
+ this._selectedListEl = div(
278
+ {
279
+ className: `selected-list${!this.expandable ? ' selected-list--clipped' : ''}`,
280
+ },
281
+ () => {
282
+ for (const v of multiValues) {
283
+ const lbl = this._findLabel(v);
284
+ tags.aeTag({
285
+ key: `sel-${v}`,
286
+ color: 'default',
287
+ variant: 'faint',
288
+ dismissible: true,
289
+ disabled: isDisabled,
290
+ textContent: lbl,
291
+ '@dismiss': (e: Event) => {
292
+ e.stopPropagation();
293
+ if (isDisabled) return;
294
+
295
+ const next = multiValues.filter((item) => String(item) !== String(v));
296
+ this.setValue(next, { silent: false, action: 'change' });
297
+ },
298
+ });
299
+ }
300
+ },
301
+ );
302
+ if (!this.expandable && this._expanded) {
303
+ span({ className: 'overflow-indicator', textContent: '…' });
304
+ }
305
+ } else {
306
+ span({ className: 'value placeholder', textContent: this.placeholder || '' });
307
+ }
308
+ } else {
309
+ if (selectedLabel) {
310
+ span({ className: 'value', textContent: selectedLabel });
311
+ } else {
312
+ span({ className: 'value placeholder', textContent: this.placeholder || '' });
313
+ }
314
+ }
315
+ span({ className: 'arrow', textContent: '▾' });
316
+ },
317
+ );
318
+
319
+ this._dropdownEl = div(
320
+ {
321
+ className: `dropdown position-${position}${this._isOpen ? ' open' : ''}`,
322
+ },
323
+ () => {
324
+ this._renderProgrammaticOptions();
325
+ this._slotEl = slot({
326
+ '@slotchange': () => this._onSlotChange(),
327
+ });
328
+ },
329
+ );
330
+
331
+ this.renderActionButtons();
332
+ });
333
+ });
334
+ }
335
+
336
+ private _renderProgrammaticOptions(): void {
337
+ if (!Array.isArray(this.options)) return;
338
+
339
+ const { aeSelectOption } = tags;
340
+ const multiValues = this.multiple ? this._getMultiValues() : [];
341
+ for (const opt of this.options) {
342
+ if (this._isSelectOption(opt)) {
343
+ const isSelected = this.multiple
344
+ ? multiValues.some((v) => String(v) === String(opt.value))
345
+ : this.value != null && String(opt.value) === String(this.value);
346
+ aeSelectOption({
347
+ key: `opt-${opt.value}`,
348
+ value: String(opt.value),
349
+ label: opt.label,
350
+ textContent: t(opt.label, opt.label),
351
+ selected: isSelected ? true : undefined,
352
+ });
353
+ } else {
354
+ const isSelected = this.multiple
355
+ ? multiValues.some((v) => String(v) === String(opt))
356
+ : this.value != null && String(opt) === String(this.value);
357
+ aeSelectOption({
358
+ key: `opt-${opt}`,
359
+ value: String(opt),
360
+ textContent: String(opt),
361
+ selected: isSelected ? true : undefined,
362
+ });
363
+ }
364
+ }
365
+ }
366
+
367
+ private _isSelectOption(option: unknown): option is SelectOption {
368
+ return (
369
+ option !== null &&
370
+ typeof option === 'object' &&
371
+ typeof (option as SelectOption).label === 'string' &&
372
+ (typeof (option as SelectOption).value === 'string' ||
373
+ typeof (option as SelectOption).value === 'number')
374
+ );
375
+ }
376
+ }
377
+
378
+ Select.register();
379
+
380
+ declare global {
381
+ interface HTMLElementTagNameMap {
382
+ 'ae-select': Select;
383
+ }
384
+ }
385
+
386
+ export default Select;
387
+ export type SelectProps = InferProps<typeof Select>;
@@ -0,0 +1,33 @@
1
+ export type SliderOptionValue = string | number;
2
+
3
+ export type SliderOption = {
4
+ label: string;
5
+ value: SliderOptionValue;
6
+ };
7
+
8
+ export type SliderOptions = SliderOptionValue[] | SliderOption[];
9
+
10
+ export type NormalizedOption = {
11
+ label: string;
12
+ value: string; // stored as string for consistency with this.value
13
+ rangeValue: number; // numeric value used by the range input
14
+ };
15
+
16
+ /**
17
+ * A single mark on the slider track.
18
+ * - `number` — mark at that numeric position, no label
19
+ * - `{ value, label? }` — mark at `value` with optional label
20
+ *
21
+ * Marks are purely visual; they do NOT constrain snapping.
22
+ * The slider still snaps according to `step` / `options`.
23
+ * Marks outside [min, max] are silently ignored.
24
+ */
25
+ export type MarkItem = number | { value: number; label?: string };
26
+
27
+ /**
28
+ * The `marks` prop accepts:
29
+ * - `true` — auto-generate marks (at option positions, or min+max in free mode)
30
+ * - `MarkItem[]` — custom marks at the given positions
31
+ * - `false` / omitted — no marks
32
+ */
33
+ export type SliderMarks = boolean | MarkItem[];
@@ -0,0 +1,3 @@
1
+ export { default, default as Slider } from './slider';
2
+ export type { SliderProps } from './slider';
3
+ export type { SliderOptionValue, SliderOption, SliderOptions } from './defines';