compote-ui 0.47.1 → 0.47.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/components/data-table-v8/toolbar/data-table-column-filter.svelte +245 -118
- package/dist/components/drawer/drawer-root.svelte +10 -3
- package/dist/components/drawer/drawer-root.svelte.d.ts +1 -1
- package/dist/components/number-input/number-input.svelte +8 -3
- package/dist/components/scroll-area/scroll-area-content.svelte +1 -1
- package/dist/components/scroll-area/scroll-area-scrollbar.svelte +1 -1
- package/dist/components/tabs/tabs.svelte +1 -0
- package/package.json +1 -1
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { getReactiveTableState, type DataTableInstance } from '../data-table-utils';
|
|
9
9
|
import NumberInput from '../../number-input/number-input.svelte';
|
|
10
10
|
import * as Field from '../../field';
|
|
11
|
+
import { PhX, PhMagnifyingGlass } from '../../../icons';
|
|
11
12
|
|
|
12
13
|
type Props = {
|
|
13
14
|
table: DataTableInstance<T>;
|
|
@@ -19,13 +20,33 @@
|
|
|
19
20
|
let localText: Record<string, string> = $state({});
|
|
20
21
|
let localNumMin: Record<string, number> = $state({});
|
|
21
22
|
let localNumMax: Record<string, number> = $state({});
|
|
23
|
+
let localSelectSearch: Record<string, string> = $state({});
|
|
22
24
|
const timers: Record<string, ReturnType<typeof setTimeout>> = {};
|
|
23
25
|
|
|
24
26
|
const columnFilters = $derived(getReactiveTableState(table).columnFilters);
|
|
25
27
|
const activeCount = $derived(columnFilters.length);
|
|
26
|
-
|
|
28
|
+
|
|
29
|
+
let activeFilterIds: string[] = $derived(columnFilters.map((f) => f.id));
|
|
30
|
+
let showColumnPicker = $state(false);
|
|
31
|
+
let columnSearchText = $state('');
|
|
32
|
+
|
|
33
|
+
const activeColumns = $derived.by(() => {
|
|
34
|
+
getReactiveTableState(table);
|
|
35
|
+
return activeFilterIds
|
|
36
|
+
.map((id) => table.getColumn(id))
|
|
37
|
+
.filter((col): col is Column<T, unknown> => col != null);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const availableColumns = $derived.by(() => {
|
|
27
41
|
getReactiveTableState(table);
|
|
28
|
-
return table
|
|
42
|
+
return table
|
|
43
|
+
.getAllLeafColumns()
|
|
44
|
+
.filter((col) => col.getCanFilter() && !activeFilterIds.includes(col.id))
|
|
45
|
+
.filter(
|
|
46
|
+
(col) =>
|
|
47
|
+
!columnSearchText ||
|
|
48
|
+
getColumnLabel(col).toLowerCase().includes(columnSearchText.toLowerCase())
|
|
49
|
+
);
|
|
29
50
|
});
|
|
30
51
|
|
|
31
52
|
onDestroy(() => {
|
|
@@ -42,12 +63,33 @@
|
|
|
42
63
|
return typeof column.columnDef.header === 'string' ? column.columnDef.header : column.id;
|
|
43
64
|
}
|
|
44
65
|
|
|
66
|
+
function addFilter(column: Column<T, unknown>) {
|
|
67
|
+
activeFilterIds = [...activeFilterIds, column.id];
|
|
68
|
+
showColumnPicker = false;
|
|
69
|
+
columnSearchText = '';
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function removeFilter(column: Column<T, unknown>) {
|
|
73
|
+
activeFilterIds = activeFilterIds.filter((id) => id !== column.id);
|
|
74
|
+
column.setFilterValue(undefined);
|
|
75
|
+
delete localText[column.id];
|
|
76
|
+
delete localNumMin[column.id];
|
|
77
|
+
delete localNumMax[column.id];
|
|
78
|
+
delete localSelectSearch[column.id];
|
|
79
|
+
clearTimeout(timers[column.id]);
|
|
80
|
+
clearTimeout(timers[`${column.id}_min`]);
|
|
81
|
+
clearTimeout(timers[`${column.id}_max`]);
|
|
82
|
+
}
|
|
83
|
+
|
|
45
84
|
function clearFilters() {
|
|
46
85
|
Object.values(timers).forEach(clearTimeout);
|
|
47
86
|
for (const key of Object.keys(timers)) delete timers[key];
|
|
48
87
|
localText = {};
|
|
49
88
|
localNumMin = {};
|
|
50
89
|
localNumMax = {};
|
|
90
|
+
localSelectSearch = {};
|
|
91
|
+
showColumnPicker = false;
|
|
92
|
+
columnSearchText = '';
|
|
51
93
|
table.resetColumnFilters();
|
|
52
94
|
}
|
|
53
95
|
|
|
@@ -117,8 +159,8 @@
|
|
|
117
159
|
{/if}
|
|
118
160
|
</Popover.Trigger>
|
|
119
161
|
|
|
120
|
-
<Popover.Content class="w-72
|
|
121
|
-
<div class="
|
|
162
|
+
<Popover.Content class="w-72 p-0" showArrow={false}>
|
|
163
|
+
<div class="flex items-center justify-between px-3 py-2.5">
|
|
122
164
|
<span class="text-sm font-medium text-ink">Filters</span>
|
|
123
165
|
{#if activeCount > 0}
|
|
124
166
|
<button type="button" onclick={clearFilters} class="text-xs text-primary hover:underline">
|
|
@@ -126,123 +168,208 @@
|
|
|
126
168
|
</button>
|
|
127
169
|
{/if}
|
|
128
170
|
</div>
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
min={facetMin}
|
|
147
|
-
max={facetMax}
|
|
148
|
-
formatOptions={colFormatOptions}
|
|
149
|
-
onValueChange={({ valueAsNumber }) =>
|
|
150
|
-
handleNumericInput(
|
|
151
|
-
column,
|
|
152
|
-
'min',
|
|
153
|
-
isNaN(valueAsNumber) ? null : valueAsNumber
|
|
154
|
-
)}
|
|
155
|
-
/>
|
|
171
|
+
|
|
172
|
+
{#if activeColumns.length > 0}
|
|
173
|
+
<div class="overflow-hidden border-t border-surface-3">
|
|
174
|
+
<ScrollArea.Root class="h-96">
|
|
175
|
+
<ScrollArea.Viewport>
|
|
176
|
+
<ScrollArea.Content>
|
|
177
|
+
{#each activeColumns as column (column.id)}
|
|
178
|
+
<div class="border border-surface-3 p-3">
|
|
179
|
+
<div class="mb-2 flex items-center justify-between">
|
|
180
|
+
<span class="text-sm font-medium text-ink">{getColumnLabel(column)}</span>
|
|
181
|
+
<button
|
|
182
|
+
type="button"
|
|
183
|
+
onclick={() => removeFilter(column)}
|
|
184
|
+
class="text-ink-dim transition-colors hover:text-ink"
|
|
185
|
+
>
|
|
186
|
+
<PhX class="size-3.5" />
|
|
187
|
+
</button>
|
|
156
188
|
</div>
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
column
|
|
167
|
-
|
|
168
|
-
|
|
189
|
+
|
|
190
|
+
{#if getColumnType(column) === 'number' || getColumnType(column) === 'currency' || getColumnType(column) === 'percent'}
|
|
191
|
+
{@const [facetMin, facetMax] = getFacetedMinMax(column)}
|
|
192
|
+
{@const colFormatOptions = getColumnFormatOptions(column)}
|
|
193
|
+
<div class="flex flex-col gap-1.5">
|
|
194
|
+
<div class="min-w-0 flex-1">
|
|
195
|
+
<NumberInput
|
|
196
|
+
layout="horizontal"
|
|
197
|
+
label="From"
|
|
198
|
+
value={localNumMin[column.id] ?? facetMin ?? null}
|
|
199
|
+
min={facetMin}
|
|
200
|
+
max={facetMax}
|
|
201
|
+
formatOptions={colFormatOptions}
|
|
202
|
+
onValueChange={({ valueAsNumber }) =>
|
|
203
|
+
handleNumericInput(
|
|
204
|
+
column,
|
|
205
|
+
'min',
|
|
206
|
+
isNaN(valueAsNumber) ? null : valueAsNumber
|
|
207
|
+
)}
|
|
208
|
+
/>
|
|
209
|
+
</div>
|
|
210
|
+
<div class="min-w-0 flex-1">
|
|
211
|
+
<NumberInput
|
|
212
|
+
layout="horizontal"
|
|
213
|
+
label="To"
|
|
214
|
+
value={localNumMax[column.id] ?? facetMax ?? null}
|
|
215
|
+
min={facetMin}
|
|
216
|
+
max={facetMax}
|
|
217
|
+
formatOptions={colFormatOptions}
|
|
218
|
+
onValueChange={({ valueAsNumber }) =>
|
|
219
|
+
handleNumericInput(
|
|
220
|
+
column,
|
|
221
|
+
'max',
|
|
222
|
+
isNaN(valueAsNumber) ? null : valueAsNumber
|
|
223
|
+
)}
|
|
224
|
+
/>
|
|
225
|
+
</div>
|
|
226
|
+
</div>
|
|
227
|
+
{:else if getColumnType(column) === 'boolean'}
|
|
228
|
+
{@const boolFilter = column.getFilterValue() as boolean | undefined}
|
|
229
|
+
<div class="flex overflow-hidden rounded border border-border text-xs">
|
|
230
|
+
<button
|
|
231
|
+
type="button"
|
|
232
|
+
onclick={() => column.setFilterValue(undefined)}
|
|
233
|
+
class={cn(
|
|
234
|
+
'flex-1 px-2 py-1',
|
|
235
|
+
boolFilter === undefined
|
|
236
|
+
? 'bg-surface-3 font-medium text-ink'
|
|
237
|
+
: 'text-ink-dim hover:bg-surface-2'
|
|
169
238
|
)}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
239
|
+
>
|
|
240
|
+
All
|
|
241
|
+
</button>
|
|
242
|
+
<button
|
|
243
|
+
type="button"
|
|
244
|
+
onclick={() =>
|
|
245
|
+
column.setFilterValue(boolFilter === true ? undefined : true)}
|
|
246
|
+
class={cn(
|
|
247
|
+
'flex-1 border-x border-border px-2 py-1',
|
|
248
|
+
boolFilter === true
|
|
249
|
+
? 'bg-surface-3 font-medium text-ink'
|
|
250
|
+
: 'text-ink-dim hover:bg-surface-2'
|
|
251
|
+
)}
|
|
252
|
+
>
|
|
253
|
+
Yes
|
|
254
|
+
</button>
|
|
255
|
+
<button
|
|
256
|
+
type="button"
|
|
257
|
+
onclick={() =>
|
|
258
|
+
column.setFilterValue(boolFilter === false ? undefined : false)}
|
|
259
|
+
class={cn(
|
|
260
|
+
'flex-1 px-2 py-1',
|
|
261
|
+
boolFilter === false
|
|
262
|
+
? 'bg-surface-3 font-medium text-ink'
|
|
263
|
+
: 'text-ink-dim hover:bg-surface-2'
|
|
264
|
+
)}
|
|
265
|
+
>
|
|
266
|
+
No
|
|
267
|
+
</button>
|
|
268
|
+
</div>
|
|
269
|
+
{:else if getColumnType(column) === 'select'}
|
|
270
|
+
{@const allOptions = getFacetedValues(column)}
|
|
271
|
+
{@const search = localSelectSearch[column.id] ?? ''}
|
|
272
|
+
{@const options = search
|
|
273
|
+
? allOptions.filter((o) => o.toLowerCase().includes(search.toLowerCase()))
|
|
274
|
+
: allOptions}
|
|
275
|
+
{@const selected = getSelectValues(column)}
|
|
276
|
+
<div class="flex flex-col gap-1">
|
|
277
|
+
<Field.Root>
|
|
278
|
+
<Field.Input
|
|
279
|
+
placeholder="Search..."
|
|
280
|
+
value={search}
|
|
281
|
+
oninput={(e: Event) => {
|
|
282
|
+
localSelectSearch[column.id] = (
|
|
283
|
+
e.currentTarget as HTMLInputElement
|
|
284
|
+
).value;
|
|
285
|
+
}}
|
|
286
|
+
/>
|
|
287
|
+
</Field.Root>
|
|
288
|
+
<div class="max-h-44 overflow-hidden">
|
|
289
|
+
<ScrollArea.Root class="h-full">
|
|
290
|
+
<ScrollArea.Viewport>
|
|
291
|
+
<ScrollArea.Content>
|
|
292
|
+
<div class="flex flex-col gap-0.5">
|
|
293
|
+
{#each options as option (option)}
|
|
294
|
+
<Checkbox
|
|
295
|
+
size="sm"
|
|
296
|
+
label={option}
|
|
297
|
+
class="min-h-7 rounded-sm px-2 hover:bg-surface-2"
|
|
298
|
+
checked={selected.includes(option)}
|
|
299
|
+
onCheckedChange={({ checked }) =>
|
|
300
|
+
handleSelectChange(column, option, checked === true)}
|
|
301
|
+
/>
|
|
302
|
+
{/each}
|
|
303
|
+
</div>
|
|
304
|
+
</ScrollArea.Content>
|
|
305
|
+
</ScrollArea.Viewport>
|
|
306
|
+
<ScrollArea.Scrollbar orientation="vertical">
|
|
307
|
+
<ScrollArea.Thumb />
|
|
308
|
+
</ScrollArea.Scrollbar>
|
|
309
|
+
<ScrollArea.Corner />
|
|
310
|
+
</ScrollArea.Root>
|
|
311
|
+
</div>
|
|
312
|
+
</div>
|
|
313
|
+
{:else}
|
|
314
|
+
<Field.Root>
|
|
315
|
+
<Field.Input
|
|
316
|
+
placeholder="Search..."
|
|
317
|
+
value={localText[column.id] ?? ''}
|
|
318
|
+
oninput={(e: Event) =>
|
|
319
|
+
handleTextInput(column, (e.currentTarget as HTMLInputElement).value)}
|
|
320
|
+
/>
|
|
321
|
+
</Field.Root>
|
|
322
|
+
{/if}
|
|
227
323
|
</div>
|
|
228
|
-
{
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
324
|
+
{/each}
|
|
325
|
+
</ScrollArea.Content>
|
|
326
|
+
</ScrollArea.Viewport>
|
|
327
|
+
<ScrollArea.Scrollbar orientation="vertical">
|
|
328
|
+
<ScrollArea.Thumb />
|
|
329
|
+
</ScrollArea.Scrollbar>
|
|
330
|
+
<ScrollArea.Corner />
|
|
331
|
+
</ScrollArea.Root>
|
|
332
|
+
</div>
|
|
333
|
+
{/if}
|
|
334
|
+
|
|
335
|
+
{#if showColumnPicker}
|
|
336
|
+
<div class="border-t border-surface-3 p-3">
|
|
337
|
+
<div class="relative mb-1">
|
|
338
|
+
<PhMagnifyingGlass
|
|
339
|
+
class="pointer-events-none absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2 text-ink-dim"
|
|
340
|
+
/>
|
|
341
|
+
<input
|
|
342
|
+
type="text"
|
|
343
|
+
placeholder="Search columns..."
|
|
344
|
+
bind:value={columnSearchText}
|
|
345
|
+
class="h-8 w-full rounded border border-border bg-surface-1 pr-3 pl-7 text-sm text-ink outline-none placeholder:text-ink-dim focus:ring-1 focus:ring-ring"
|
|
346
|
+
/>
|
|
347
|
+
</div>
|
|
348
|
+
<div class="max-h-48 overflow-y-auto">
|
|
349
|
+
{#each availableColumns as column (column.id)}
|
|
350
|
+
<button
|
|
351
|
+
type="button"
|
|
352
|
+
onclick={() => addFilter(column)}
|
|
353
|
+
class="w-full rounded px-2 py-1.5 text-left text-sm text-ink hover:bg-surface-2"
|
|
354
|
+
>
|
|
355
|
+
{getColumnLabel(column)}
|
|
356
|
+
</button>
|
|
357
|
+
{:else}
|
|
358
|
+
<p class="px-2 py-3 text-center text-sm text-ink-dim">No more columns</p>
|
|
239
359
|
{/each}
|
|
240
|
-
</
|
|
241
|
-
</
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
360
|
+
</div>
|
|
361
|
+
</div>
|
|
362
|
+
{:else}
|
|
363
|
+
<div class="border-t border-surface-3">
|
|
364
|
+
<button
|
|
365
|
+
type="button"
|
|
366
|
+
onclick={() => (showColumnPicker = true)}
|
|
367
|
+
class="flex w-full items-center gap-2 px-3 py-2.5 text-sm text-ink-dim hover:bg-surface-2 hover:text-ink"
|
|
368
|
+
>
|
|
369
|
+
<span class="text-base leading-none">+</span>
|
|
370
|
+
Add Filter
|
|
371
|
+
</button>
|
|
372
|
+
</div>
|
|
373
|
+
{/if}
|
|
247
374
|
</Popover.Content>
|
|
248
375
|
</Popover.Root>
|
|
@@ -2,13 +2,20 @@
|
|
|
2
2
|
import { Drawer } from '@ark-ui/svelte/drawer';
|
|
3
3
|
import type { DrawerRootProps } from '@ark-ui/svelte/drawer';
|
|
4
4
|
|
|
5
|
-
interface Props extends Omit<DrawerRootProps, 'open'
|
|
5
|
+
interface Props extends Omit<DrawerRootProps, 'open'> {
|
|
6
6
|
open?: boolean;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
let { children, open = $bindable(), ...rest }: Props = $props();
|
|
9
|
+
let { children, open = $bindable(), onOpenChange, ...rest }: Props = $props();
|
|
10
10
|
</script>
|
|
11
11
|
|
|
12
|
-
<Drawer.Root
|
|
12
|
+
<Drawer.Root
|
|
13
|
+
{open}
|
|
14
|
+
onOpenChange={(details) => {
|
|
15
|
+
open = details.open;
|
|
16
|
+
onOpenChange?.(details);
|
|
17
|
+
}}
|
|
18
|
+
{...rest}
|
|
19
|
+
>
|
|
13
20
|
{@render children?.()}
|
|
14
21
|
</Drawer.Root>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DrawerRootProps } from '@ark-ui/svelte/drawer';
|
|
2
|
-
interface Props extends Omit<DrawerRootProps, 'open'
|
|
2
|
+
interface Props extends Omit<DrawerRootProps, 'open'> {
|
|
3
3
|
open?: boolean;
|
|
4
4
|
}
|
|
5
5
|
declare const DrawerRoot: import("svelte").Component<Props, {}, "open">;
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
const locale = useLocaleContext();
|
|
18
18
|
const rootClass = $derived(
|
|
19
19
|
layout === 'horizontal'
|
|
20
|
-
? 'flex items-center gap-1.5 w-full
|
|
20
|
+
? 'flex items-center justify-between gap-1.5 w-full data-disabled:opacity-50 data-disabled:grayscale'
|
|
21
21
|
: 'flex flex-col gap-1.5 w-full max-w-48 data-disabled:opacity-50 data-disabled:grayscale'
|
|
22
22
|
);
|
|
23
23
|
</script>
|
|
@@ -28,7 +28,12 @@
|
|
|
28
28
|
{...restProps}
|
|
29
29
|
allowMouseWheel
|
|
30
30
|
locale={locale().locale}
|
|
31
|
-
value={value != null
|
|
31
|
+
value={value != null
|
|
32
|
+
? new Intl.NumberFormat(locale().locale, {
|
|
33
|
+
useGrouping: false,
|
|
34
|
+
maximumFractionDigits: 20
|
|
35
|
+
}).format(value)
|
|
36
|
+
: undefined}
|
|
32
37
|
readOnly={readonly}
|
|
33
38
|
onValueChange={(valueChangeDetails) => {
|
|
34
39
|
onValueChange?.(valueChangeDetails);
|
|
@@ -48,7 +53,7 @@
|
|
|
48
53
|
{/if}
|
|
49
54
|
<NumberInput.Control class="relative isolate">
|
|
50
55
|
<NumberInput.Input
|
|
51
|
-
class="h-9 w-full rounded-md border bg-surface-1 px-3 pr-8 text-right text-sm font-medium tabular-nums shadow-sm focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none data-invalid:border-danger data-invalid:focus-visible:ring-danger"
|
|
56
|
+
class="h-9 w-full max-w-48 rounded-md border bg-surface-1 px-3 pr-8 text-right text-sm font-medium tabular-nums shadow-sm focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none data-invalid:border-danger data-invalid:focus-visible:ring-danger"
|
|
52
57
|
/>
|
|
53
58
|
<div
|
|
54
59
|
class="absolute top-px right-px bottom-px z-10 flex w-6 flex-col overflow-hidden rounded-r border-l"
|
|
@@ -10,6 +10,6 @@
|
|
|
10
10
|
let { class: className, children, ...rest }: Props = $props();
|
|
11
11
|
</script>
|
|
12
12
|
|
|
13
|
-
<ScrollArea.Content {...rest} class={cn('
|
|
13
|
+
<ScrollArea.Content {...rest} class={cn('p-3', className)}>
|
|
14
14
|
{@render children?.()}
|
|
15
15
|
</ScrollArea.Content>
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
<ScrollArea.Scrollbar
|
|
14
14
|
{...rest}
|
|
15
15
|
class={cn(
|
|
16
|
-
'group pointer-events-none relative m-
|
|
16
|
+
'group pointer-events-none relative m-1 flex rounded-md bg-well opacity-0 transition-opacity duration-150',
|
|
17
17
|
'data-hover:pointer-events-auto data-hover:opacity-100',
|
|
18
18
|
'data-scrolling:pointer-events-auto data-scrolling:opacity-100 data-scrolling:duration-0',
|
|
19
19
|
'data-[orientation=vertical]:w-1 data-[orientation=vertical]:[&:not([data-overflow-y])]:hidden',
|