@juspay/svelte-ui-components 2.28.2 → 2.28.3
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.
- package/dist/Banner/Banner.svelte +34 -7
- package/dist/Banner/properties.d.ts +2 -0
- package/dist/Breadcrumb/Breadcrumb.svelte +58 -0
- package/dist/Breadcrumb/Breadcrumb.svelte.d.ts +4 -0
- package/dist/Breadcrumb/properties.d.ts +19 -0
- package/dist/Breadcrumb/properties.js +1 -0
- package/dist/Calendar/Calendar.svelte +10 -4
- package/dist/Calendar/properties.d.ts +2 -0
- package/dist/DateRangePicker/DateRangePicker.svelte +627 -0
- package/dist/DateRangePicker/DateRangePicker.svelte.d.ts +4 -0
- package/dist/DateRangePicker/properties.d.ts +74 -0
- package/dist/DateRangePicker/properties.js +1 -0
- package/dist/EmptyState/EmptyState.svelte +3 -1
- package/dist/EmptyState/properties.d.ts +1 -1
- package/dist/FileInput/FileInput.svelte +176 -0
- package/dist/FileInput/FileInput.svelte.d.ts +4 -0
- package/dist/FileInput/properties.d.ts +18 -0
- package/dist/FileInput/properties.js +1 -0
- package/dist/Modal/Modal.svelte +5 -4
- package/dist/Pagination/Pagination.svelte +56 -11
- package/dist/Pagination/properties.d.ts +15 -0
- package/dist/Pill/Pill.svelte +10 -0
- package/dist/Pill/properties.d.ts +7 -0
- package/dist/Select/Select.svelte +69 -29
- package/dist/Select/Select.svelte.d.ts +1 -1
- package/dist/Select/properties.d.ts +8 -1
- package/dist/Sheet/Sheet.svelte +16 -0
- package/dist/Sheet/properties.d.ts +4 -0
- package/dist/Table/Table.svelte +28 -6
- package/dist/Table/properties.d.ts +6 -0
- package/dist/Tabs/Tabs.svelte +52 -8
- package/dist/index.d.ts +6 -0
- package/dist/index.js +3 -0
- package/package.json +1 -1
|
@@ -5,18 +5,25 @@
|
|
|
5
5
|
import chevronDownSvg from '../assets/chevron-down.svg?raw';
|
|
6
6
|
|
|
7
7
|
let {
|
|
8
|
-
items,
|
|
8
|
+
items: rawItems,
|
|
9
9
|
value = $bindable([]),
|
|
10
10
|
multiple = false,
|
|
11
11
|
searchable = false,
|
|
12
12
|
placeholder = '',
|
|
13
13
|
disabled = false,
|
|
14
|
+
bottomContent,
|
|
15
|
+
optionIndicator,
|
|
14
16
|
testId,
|
|
15
17
|
onchange,
|
|
16
|
-
classes
|
|
18
|
+
classes,
|
|
19
|
+
open = $bindable(false)
|
|
17
20
|
}: SelectProperties = $props();
|
|
18
21
|
|
|
19
|
-
|
|
22
|
+
function normalizeItems(source: SelectItem[] | string[]): SelectItem[] {
|
|
23
|
+
return source.map((entry) => (typeof entry === 'string' ? { id: entry, label: entry } : entry));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
let items: SelectItem[] = $derived(normalizeItems(rawItems));
|
|
20
27
|
let query = $state('');
|
|
21
28
|
let highlightedIndex = $state(-1);
|
|
22
29
|
let containerEl: HTMLDivElement | null = $state(null);
|
|
@@ -48,13 +55,13 @@
|
|
|
48
55
|
highlightedIndex >= 0 ? `${listboxId}-option-${highlightedIndex}` : null
|
|
49
56
|
);
|
|
50
57
|
|
|
51
|
-
let searchPlaceholder = $derived(
|
|
58
|
+
let searchPlaceholder = $derived(open && displayText.length > 0 ? displayText : placeholder);
|
|
52
59
|
|
|
53
|
-
async function
|
|
54
|
-
if (disabled ||
|
|
60
|
+
async function openDropdown(): Promise<void> {
|
|
61
|
+
if (disabled || open) {
|
|
55
62
|
return;
|
|
56
63
|
}
|
|
57
|
-
|
|
64
|
+
open = true;
|
|
58
65
|
highlightedIndex = -1;
|
|
59
66
|
query = '';
|
|
60
67
|
if (searchable) {
|
|
@@ -66,7 +73,7 @@
|
|
|
66
73
|
}
|
|
67
74
|
|
|
68
75
|
function close(): void {
|
|
69
|
-
|
|
76
|
+
open = false;
|
|
70
77
|
query = '';
|
|
71
78
|
highlightedIndex = -1;
|
|
72
79
|
}
|
|
@@ -119,17 +126,17 @@
|
|
|
119
126
|
|
|
120
127
|
function handleTriggerClick(event: MouseEvent): void {
|
|
121
128
|
if (event.target instanceof HTMLInputElement) {
|
|
122
|
-
if (!
|
|
123
|
-
|
|
129
|
+
if (!open) {
|
|
130
|
+
openDropdown();
|
|
124
131
|
}
|
|
125
132
|
return;
|
|
126
133
|
}
|
|
127
134
|
if (multiple && searchable) {
|
|
128
|
-
|
|
129
|
-
} else if (
|
|
135
|
+
openDropdown();
|
|
136
|
+
} else if (open) {
|
|
130
137
|
close();
|
|
131
138
|
} else {
|
|
132
|
-
|
|
139
|
+
openDropdown();
|
|
133
140
|
}
|
|
134
141
|
}
|
|
135
142
|
|
|
@@ -140,28 +147,28 @@
|
|
|
140
147
|
switch (event.key) {
|
|
141
148
|
case 'Enter':
|
|
142
149
|
event.preventDefault();
|
|
143
|
-
if (
|
|
150
|
+
if (open) {
|
|
144
151
|
selectHighlighted();
|
|
145
152
|
} else {
|
|
146
|
-
|
|
153
|
+
openDropdown();
|
|
147
154
|
}
|
|
148
155
|
break;
|
|
149
156
|
case ' ':
|
|
150
157
|
if (!(event.target instanceof HTMLInputElement)) {
|
|
151
158
|
event.preventDefault();
|
|
152
|
-
if (
|
|
159
|
+
if (open) {
|
|
153
160
|
selectHighlighted();
|
|
154
161
|
} else {
|
|
155
|
-
|
|
162
|
+
openDropdown();
|
|
156
163
|
}
|
|
157
164
|
}
|
|
158
165
|
break;
|
|
159
166
|
case 'ArrowDown':
|
|
160
167
|
event.preventDefault();
|
|
161
|
-
if (
|
|
168
|
+
if (open) {
|
|
162
169
|
moveHighlight(1);
|
|
163
170
|
} else {
|
|
164
|
-
|
|
171
|
+
openDropdown();
|
|
165
172
|
}
|
|
166
173
|
break;
|
|
167
174
|
case 'ArrowUp':
|
|
@@ -169,7 +176,7 @@
|
|
|
169
176
|
moveHighlight(-1);
|
|
170
177
|
break;
|
|
171
178
|
case 'Escape':
|
|
172
|
-
if (
|
|
179
|
+
if (open) {
|
|
173
180
|
close();
|
|
174
181
|
if (!searchable && triggerEl !== null) {
|
|
175
182
|
triggerEl.focus();
|
|
@@ -185,7 +192,7 @@
|
|
|
185
192
|
}
|
|
186
193
|
break;
|
|
187
194
|
case 'Tab':
|
|
188
|
-
if (
|
|
195
|
+
if (open) {
|
|
189
196
|
close();
|
|
190
197
|
}
|
|
191
198
|
break;
|
|
@@ -197,15 +204,15 @@
|
|
|
197
204
|
return;
|
|
198
205
|
}
|
|
199
206
|
query = event.target.value;
|
|
200
|
-
if (!
|
|
201
|
-
|
|
207
|
+
if (!open) {
|
|
208
|
+
open = true;
|
|
202
209
|
}
|
|
203
210
|
highlightedIndex = -1;
|
|
204
211
|
}
|
|
205
212
|
|
|
206
213
|
function handleSearchFocus(): void {
|
|
207
|
-
if (!
|
|
208
|
-
|
|
214
|
+
if (!open) {
|
|
215
|
+
openDropdown();
|
|
209
216
|
}
|
|
210
217
|
}
|
|
211
218
|
|
|
@@ -229,7 +236,7 @@
|
|
|
229
236
|
|
|
230
237
|
<div
|
|
231
238
|
class="select {classes ?? ''}"
|
|
232
|
-
class:open
|
|
239
|
+
class:open
|
|
233
240
|
class:disabled
|
|
234
241
|
bind:this={containerEl}
|
|
235
242
|
{...typeof testId === 'string' ? { 'data-pw': testId } : {}}
|
|
@@ -240,7 +247,7 @@
|
|
|
240
247
|
onclick={handleTriggerClick}
|
|
241
248
|
onkeydown={handleKeydown}
|
|
242
249
|
role="combobox"
|
|
243
|
-
aria-expanded={
|
|
250
|
+
aria-expanded={open}
|
|
244
251
|
aria-haspopup="listbox"
|
|
245
252
|
aria-controls={listboxId}
|
|
246
253
|
{...highlightedOptionId !== null ? { 'aria-activedescendant': highlightedOptionId } : {}}
|
|
@@ -276,7 +283,7 @@
|
|
|
276
283
|
<input
|
|
277
284
|
class="select-search"
|
|
278
285
|
type="text"
|
|
279
|
-
value={
|
|
286
|
+
value={open ? query : displayText}
|
|
280
287
|
oninput={handleSearchInput}
|
|
281
288
|
onfocus={handleSearchFocus}
|
|
282
289
|
bind:this={searchInputEl}
|
|
@@ -294,7 +301,7 @@
|
|
|
294
301
|
<span class="select-arrow">{@html chevronDownSvg}</span>
|
|
295
302
|
</div>
|
|
296
303
|
|
|
297
|
-
{#if
|
|
304
|
+
{#if open && !disabled}
|
|
298
305
|
<div class="select-dropdown" role="listbox" id={listboxId} aria-multiselectable={multiple}>
|
|
299
306
|
{#if filteredItems.length === 0}
|
|
300
307
|
<div class="select-empty">No results</div>
|
|
@@ -303,6 +310,7 @@
|
|
|
303
310
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
304
311
|
<div
|
|
305
312
|
class="select-option"
|
|
313
|
+
class:multi={multiple}
|
|
306
314
|
class:selected={value.includes(item.id)}
|
|
307
315
|
class:highlighted={index === highlightedIndex}
|
|
308
316
|
role="option"
|
|
@@ -312,10 +320,24 @@
|
|
|
312
320
|
onclick={() => selectItem(item.id)}
|
|
313
321
|
onmouseenter={() => (highlightedIndex = index)}
|
|
314
322
|
>
|
|
323
|
+
{#if multiple}
|
|
324
|
+
{#if typeof optionIndicator === 'function'}
|
|
325
|
+
{@render optionIndicator({ checked: value.includes(item.id) })}
|
|
326
|
+
{:else}
|
|
327
|
+
<span class="select-option-indicator" aria-hidden="true"
|
|
328
|
+
>{value.includes(item.id) ? '☑' : '☐'}</span
|
|
329
|
+
>
|
|
330
|
+
{/if}
|
|
331
|
+
{/if}
|
|
315
332
|
{item.label}
|
|
316
333
|
</div>
|
|
317
334
|
{/each}
|
|
318
335
|
{/if}
|
|
336
|
+
{#if typeof bottomContent === 'function'}
|
|
337
|
+
<div class="select-bottom-content">
|
|
338
|
+
{@render bottomContent()}
|
|
339
|
+
</div>
|
|
340
|
+
{/if}
|
|
319
341
|
</div>
|
|
320
342
|
{/if}
|
|
321
343
|
</div>
|
|
@@ -436,6 +458,12 @@
|
|
|
436
458
|
transition: background 0.1s;
|
|
437
459
|
}
|
|
438
460
|
|
|
461
|
+
.select-option.multi {
|
|
462
|
+
display: flex;
|
|
463
|
+
align-items: center;
|
|
464
|
+
gap: var(--select-option-gap, 0);
|
|
465
|
+
}
|
|
466
|
+
|
|
439
467
|
.select-option:hover,
|
|
440
468
|
.select-option.highlighted {
|
|
441
469
|
background: var(--select-option-hover-background, #f0f0f0);
|
|
@@ -454,6 +482,13 @@
|
|
|
454
482
|
);
|
|
455
483
|
}
|
|
456
484
|
|
|
485
|
+
.select-option-indicator {
|
|
486
|
+
display: inline-flex;
|
|
487
|
+
align-items: center;
|
|
488
|
+
color: var(--select-option-indicator-color, currentColor);
|
|
489
|
+
flex-shrink: 0;
|
|
490
|
+
}
|
|
491
|
+
|
|
457
492
|
.select-empty {
|
|
458
493
|
padding: var(--select-empty-padding, 8px 12px);
|
|
459
494
|
color: var(--select-empty-color, #999999);
|
|
@@ -461,6 +496,11 @@
|
|
|
461
496
|
font-size: var(--select-empty-font-size, inherit);
|
|
462
497
|
}
|
|
463
498
|
|
|
499
|
+
.select-bottom-content {
|
|
500
|
+
border-top: var(--select-bottom-content-border, none);
|
|
501
|
+
padding: var(--select-bottom-content-padding, 8px 12px);
|
|
502
|
+
}
|
|
503
|
+
|
|
464
504
|
.select-trigger :global(.pill) {
|
|
465
505
|
--pill-background: var(--select-pill-background, #e0e0e0);
|
|
466
506
|
--pill-color: var(--select-pill-color, #333333);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { SelectProperties } from './properties';
|
|
2
|
-
declare const Select: import("svelte").Component<SelectProperties, {}, "value">;
|
|
2
|
+
declare const Select: import("svelte").Component<SelectProperties, {}, "value" | "open">;
|
|
3
3
|
type Select = ReturnType<typeof Select>;
|
|
4
4
|
export default Select;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
1
2
|
export type SelectProperties = MandatorySelectProperties & OptionalSelectProperties & SelectEventProperties;
|
|
2
3
|
export type SelectItem = {
|
|
3
4
|
id: string;
|
|
4
5
|
label: string;
|
|
5
6
|
};
|
|
6
7
|
export type MandatorySelectProperties = {
|
|
7
|
-
items: SelectItem[];
|
|
8
|
+
items: SelectItem[] | string[];
|
|
8
9
|
};
|
|
9
10
|
export type OptionalSelectProperties = {
|
|
10
11
|
value?: string[];
|
|
@@ -12,8 +13,14 @@ export type OptionalSelectProperties = {
|
|
|
12
13
|
searchable?: boolean;
|
|
13
14
|
placeholder?: string;
|
|
14
15
|
disabled?: boolean;
|
|
16
|
+
bottomContent?: Snippet;
|
|
17
|
+
optionIndicator?: Snippet<[{
|
|
18
|
+
checked: boolean;
|
|
19
|
+
}]>;
|
|
15
20
|
testId?: string;
|
|
16
21
|
classes?: string;
|
|
22
|
+
/** Bindable. Controls whether the dropdown is open; the component writes back on open/close so parents can `bind:open` to observe or drive it. Unbound, the component manages its own state. */
|
|
23
|
+
open?: boolean;
|
|
17
24
|
};
|
|
18
25
|
export type SelectEventProperties = {
|
|
19
26
|
onchange?: (value: string[]) => void;
|
package/dist/Sheet/Sheet.svelte
CHANGED
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
content,
|
|
15
15
|
footer,
|
|
16
16
|
onclose,
|
|
17
|
+
onafteropen,
|
|
18
|
+
onafterclose,
|
|
17
19
|
classes
|
|
18
20
|
}: SheetProperties = $props();
|
|
19
21
|
|
|
@@ -90,6 +92,18 @@
|
|
|
90
92
|
}
|
|
91
93
|
};
|
|
92
94
|
}
|
|
95
|
+
|
|
96
|
+
function handleIntroEnd() {
|
|
97
|
+
if (typeof onafteropen === 'function') {
|
|
98
|
+
onafteropen();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function handleOutroEnd() {
|
|
103
|
+
if (typeof onafterclose === 'function') {
|
|
104
|
+
onafterclose();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
93
107
|
</script>
|
|
94
108
|
|
|
95
109
|
{#if open}
|
|
@@ -112,6 +126,8 @@
|
|
|
112
126
|
aria-label={title ?? 'Sheet'}
|
|
113
127
|
tabindex="-1"
|
|
114
128
|
transition:fly|global={flyParams}
|
|
129
|
+
onintroend={handleIntroEnd}
|
|
130
|
+
onoutroend={handleOutroEnd}
|
|
115
131
|
>
|
|
116
132
|
{#if typeof title === 'string' || showCloseButton}
|
|
117
133
|
<div class="sheet-header">
|
|
@@ -16,4 +16,8 @@ export type OptionalSheetProperties = {
|
|
|
16
16
|
};
|
|
17
17
|
export type SheetEventProperties = {
|
|
18
18
|
onclose?: () => void;
|
|
19
|
+
/** Called once after the open transition has fully completed. */
|
|
20
|
+
onafteropen?: () => void;
|
|
21
|
+
/** Called once after the close transition has fully completed. */
|
|
22
|
+
onafterclose?: () => void;
|
|
19
23
|
};
|
package/dist/Table/Table.svelte
CHANGED
|
@@ -24,7 +24,10 @@
|
|
|
24
24
|
empty,
|
|
25
25
|
onRowClick,
|
|
26
26
|
onSort,
|
|
27
|
-
classes
|
|
27
|
+
classes,
|
|
28
|
+
paginatorSlot,
|
|
29
|
+
getRowTestId,
|
|
30
|
+
getCellTestId
|
|
28
31
|
}: TableProperties = $props();
|
|
29
32
|
|
|
30
33
|
let sortColumn = $state<number | null>(null);
|
|
@@ -48,9 +51,9 @@
|
|
|
48
51
|
const colIndex = sortColumn;
|
|
49
52
|
const direction = sortDirection;
|
|
50
53
|
|
|
51
|
-
return [...tableData].sort((
|
|
52
|
-
const valueA =
|
|
53
|
-
const valueB =
|
|
54
|
+
return [...tableData].sort((rowA, rowB) => {
|
|
55
|
+
const valueA = rowA[colIndex];
|
|
56
|
+
const valueB = rowB[colIndex];
|
|
54
57
|
|
|
55
58
|
if (typeof valueA === 'number' && typeof valueB === 'number') {
|
|
56
59
|
return direction === 'asc' ? valueA - valueB : valueB - valueA;
|
|
@@ -171,12 +174,20 @@
|
|
|
171
174
|
<tr
|
|
172
175
|
class="table-row"
|
|
173
176
|
class:table-row-clickable={isRowClickable}
|
|
177
|
+
data-pw={typeof getRowTestId === 'function' ? getRowTestId(row, rowIndex) : null}
|
|
174
178
|
onclick={isRowClickable ? () => handleRowClick(rowIndex, row) : null}
|
|
175
|
-
onkeydown={isRowClickable
|
|
179
|
+
onkeydown={isRowClickable
|
|
180
|
+
? (keyboardEvent) => handleRowKeydown(keyboardEvent, rowIndex, row)
|
|
181
|
+
: null}
|
|
176
182
|
tabindex={isRowClickable ? 0 : null}
|
|
177
183
|
>
|
|
178
184
|
{#each row as cellValue, colIndex (colIndex)}
|
|
179
|
-
<td
|
|
185
|
+
<td
|
|
186
|
+
class="table-content"
|
|
187
|
+
data-pw={typeof getCellTestId === 'function'
|
|
188
|
+
? getCellTestId(row, cellValue, rowIndex)
|
|
189
|
+
: null}
|
|
190
|
+
>
|
|
180
191
|
<div class={isContentScrollable ? 'scrollable-content' : ''}>
|
|
181
192
|
{#if typeof cell === 'function'}
|
|
182
193
|
{@render cell(cellValue, rowIndex, colIndex)}
|
|
@@ -191,6 +202,11 @@
|
|
|
191
202
|
{/if}
|
|
192
203
|
</tbody>
|
|
193
204
|
</table>
|
|
205
|
+
{#if typeof paginatorSlot === 'function'}
|
|
206
|
+
<div class="table-footer">
|
|
207
|
+
{@render paginatorSlot()}
|
|
208
|
+
</div>
|
|
209
|
+
{/if}
|
|
194
210
|
</div>
|
|
195
211
|
{/if}
|
|
196
212
|
|
|
@@ -341,6 +357,12 @@
|
|
|
341
357
|
color: var(--table-empty-color, #9ca3af);
|
|
342
358
|
}
|
|
343
359
|
|
|
360
|
+
.table-footer {
|
|
361
|
+
border-top: var(--table-footer-border, 1px solid #e5e7eb);
|
|
362
|
+
padding: var(--table-footer-padding, 8px 16px);
|
|
363
|
+
background-color: var(--table-footer-background, transparent);
|
|
364
|
+
}
|
|
365
|
+
|
|
344
366
|
.sr-only {
|
|
345
367
|
position: absolute;
|
|
346
368
|
width: 1px;
|
|
@@ -19,6 +19,12 @@ export type OptionalTableProperties = {
|
|
|
19
19
|
cell?: Snippet<[JSONValue, number, number]>;
|
|
20
20
|
empty?: Snippet;
|
|
21
21
|
classes?: string;
|
|
22
|
+
/** Snippet rendered in a footer region below the table (e.g. a paginator). */
|
|
23
|
+
paginatorSlot?: Snippet;
|
|
24
|
+
/** Return a data-pw value for the given row. */
|
|
25
|
+
getRowTestId?: (row: JSONValue[], rowIndex: number) => string;
|
|
26
|
+
/** Return a data-pw value for the given cell. */
|
|
27
|
+
getCellTestId?: (row: JSONValue[], column: JSONValue, rowIndex: number) => string;
|
|
22
28
|
};
|
|
23
29
|
export type TableEventProperties = {
|
|
24
30
|
onRowClick?: (rowIndex: number, rowData: JSONValue[]) => void;
|
package/dist/Tabs/Tabs.svelte
CHANGED
|
@@ -44,6 +44,11 @@
|
|
|
44
44
|
let canScrollLeft = $state(false);
|
|
45
45
|
let canScrollRight = $state(false);
|
|
46
46
|
|
|
47
|
+
// Sliding indicator state
|
|
48
|
+
let indicatorLeft = $state(0);
|
|
49
|
+
let indicatorWidth = $state(0);
|
|
50
|
+
let indicatorReady = $state(false);
|
|
51
|
+
|
|
47
52
|
function updateOverflow(): void {
|
|
48
53
|
if (scrollContainer === null) {
|
|
49
54
|
return;
|
|
@@ -53,6 +58,22 @@
|
|
|
53
58
|
canScrollRight = scrollLeft + clientWidth < scrollWidth - 1;
|
|
54
59
|
}
|
|
55
60
|
|
|
61
|
+
function updateIndicator(): void {
|
|
62
|
+
if (scrollContainer === null) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const activeEl = scrollContainer.querySelector<HTMLElement>('.tabs-item.active');
|
|
66
|
+
if (activeEl === null) {
|
|
67
|
+
indicatorReady = false;
|
|
68
|
+
indicatorLeft = 0;
|
|
69
|
+
indicatorWidth = 0;
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
indicatorLeft = activeEl.offsetLeft;
|
|
73
|
+
indicatorWidth = activeEl.offsetWidth;
|
|
74
|
+
indicatorReady = true;
|
|
75
|
+
}
|
|
76
|
+
|
|
56
77
|
function scroll(direction: 'left' | 'right'): void {
|
|
57
78
|
if (scrollContainer === null) {
|
|
58
79
|
return;
|
|
@@ -73,7 +94,10 @@
|
|
|
73
94
|
if (typeof rawItem !== 'object') {
|
|
74
95
|
return;
|
|
75
96
|
}
|
|
76
|
-
const tabItem = toTabItem(rawItem)
|
|
97
|
+
const tabItem = toTabItem(rawItem);
|
|
98
|
+
if (tabItem === null) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
77
101
|
if (tabItem.key === activeKey) {
|
|
78
102
|
return;
|
|
79
103
|
}
|
|
@@ -101,8 +125,17 @@
|
|
|
101
125
|
function initOverflow(node: HTMLDivElement): { destroy: () => void } {
|
|
102
126
|
scrollContainer = node;
|
|
103
127
|
updateOverflow();
|
|
104
|
-
|
|
105
|
-
observer
|
|
128
|
+
updateIndicator();
|
|
129
|
+
const observer = new MutationObserver(() => {
|
|
130
|
+
updateOverflow();
|
|
131
|
+
updateIndicator();
|
|
132
|
+
});
|
|
133
|
+
observer.observe(node, {
|
|
134
|
+
childList: true,
|
|
135
|
+
subtree: true,
|
|
136
|
+
attributes: true,
|
|
137
|
+
attributeFilter: ['class']
|
|
138
|
+
});
|
|
106
139
|
return {
|
|
107
140
|
destroy() {
|
|
108
141
|
observer.disconnect();
|
|
@@ -153,11 +186,15 @@
|
|
|
153
186
|
{:else}
|
|
154
187
|
{label}
|
|
155
188
|
{/if}
|
|
156
|
-
{#if isActiveItem(index)}
|
|
157
|
-
<span class="tabs-indicator"></span>
|
|
158
|
-
{/if}
|
|
159
189
|
</div>
|
|
160
190
|
{/each}
|
|
191
|
+
{#if indicatorReady}
|
|
192
|
+
<span
|
|
193
|
+
class="tabs-indicator"
|
|
194
|
+
aria-hidden="true"
|
|
195
|
+
style="left: {indicatorLeft}px; width: {indicatorWidth}px;"
|
|
196
|
+
></span>
|
|
197
|
+
{/if}
|
|
161
198
|
</div>
|
|
162
199
|
{#if canScrollRight}
|
|
163
200
|
<button
|
|
@@ -199,6 +236,7 @@
|
|
|
199
236
|
gap: var(--tabs-bar-gap, 0px);
|
|
200
237
|
overflow-x: auto;
|
|
201
238
|
scrollbar-width: none;
|
|
239
|
+
position: relative;
|
|
202
240
|
}
|
|
203
241
|
|
|
204
242
|
.tabs-bar::-webkit-scrollbar {
|
|
@@ -294,10 +332,16 @@
|
|
|
294
332
|
.tabs-indicator {
|
|
295
333
|
position: absolute;
|
|
296
334
|
bottom: 0;
|
|
297
|
-
left: 0;
|
|
298
|
-
right: 0;
|
|
299
335
|
height: var(--tabs-indicator-height, 2px);
|
|
300
336
|
background-color: var(--tabs-indicator-color, #1a73e8);
|
|
301
337
|
border-radius: var(--tabs-indicator-border-radius, 2px 2px 0 0);
|
|
338
|
+
transition: var(--tabs-indicator-transition, left 0.3s ease, width 0.3s ease);
|
|
339
|
+
pointer-events: none;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
@media (prefers-reduced-motion: reduce) {
|
|
343
|
+
.tabs-indicator {
|
|
344
|
+
transition: none;
|
|
345
|
+
}
|
|
302
346
|
}
|
|
303
347
|
</style>
|
package/dist/index.d.ts
CHANGED
|
@@ -56,6 +56,9 @@ export { default as EmptyState } from './EmptyState/EmptyState.svelte';
|
|
|
56
56
|
export { default as Combobox } from './Combobox/Combobox.svelte';
|
|
57
57
|
export { default as ColorPicker } from './ColorPicker/ColorPicker.svelte';
|
|
58
58
|
export { default as SplitInput } from './SplitInput/SplitInput.svelte';
|
|
59
|
+
export { default as FileInput } from './FileInput/FileInput.svelte';
|
|
60
|
+
export { default as DateRangePicker } from './DateRangePicker/DateRangePicker.svelte';
|
|
61
|
+
export { default as Breadcrumb } from './Breadcrumb/Breadcrumb.svelte';
|
|
59
62
|
export type * from './Button/properties';
|
|
60
63
|
export type * from './Modal/properties';
|
|
61
64
|
export type * from './Input/properties';
|
|
@@ -108,4 +111,7 @@ export type * from './EmptyState/properties';
|
|
|
108
111
|
export type * from './Combobox/properties';
|
|
109
112
|
export type * from './ColorPicker/properties';
|
|
110
113
|
export type * from './SplitInput/properties';
|
|
114
|
+
export type * from './FileInput/properties';
|
|
115
|
+
export type * from './DateRangePicker/properties';
|
|
116
|
+
export type * from './Breadcrumb/properties';
|
|
111
117
|
export { validateInput } from './utils';
|
package/dist/index.js
CHANGED
|
@@ -56,4 +56,7 @@ export { default as EmptyState } from './EmptyState/EmptyState.svelte';
|
|
|
56
56
|
export { default as Combobox } from './Combobox/Combobox.svelte';
|
|
57
57
|
export { default as ColorPicker } from './ColorPicker/ColorPicker.svelte';
|
|
58
58
|
export { default as SplitInput } from './SplitInput/SplitInput.svelte';
|
|
59
|
+
export { default as FileInput } from './FileInput/FileInput.svelte';
|
|
60
|
+
export { default as DateRangePicker } from './DateRangePicker/DateRangePicker.svelte';
|
|
61
|
+
export { default as Breadcrumb } from './Breadcrumb/Breadcrumb.svelte';
|
|
59
62
|
export { validateInput } from './utils';
|