compote-ui 0.46.4 → 0.47.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 (29) hide show
  1. package/dist/components/combobox/combobox.svelte +99 -28
  2. package/dist/components/combobox/types.d.ts +1 -0
  3. package/dist/components/data-table-v8/index.d.ts +4 -4
  4. package/dist/components/data-table-v8/index.js +4 -4
  5. package/dist/components/data-table-v8/{data-table-column-filter.svelte → toolbar/data-table-column-filter.svelte} +6 -6
  6. package/dist/components/data-table-v8/{data-table-column-filter.svelte.d.ts → toolbar/data-table-column-filter.svelte.d.ts} +1 -1
  7. package/dist/components/data-table-v8/{data-table-column-visibility.svelte → toolbar/data-table-column-visibility.svelte} +4 -4
  8. package/dist/components/data-table-v8/{data-table-column-visibility.svelte.d.ts → toolbar/data-table-column-visibility.svelte.d.ts} +1 -1
  9. package/dist/components/data-table-v8/{data-table-search.svelte → toolbar/data-table-search.svelte} +3 -3
  10. package/dist/components/data-table-v8/{data-table-search.svelte.d.ts → toolbar/data-table-search.svelte.d.ts} +1 -1
  11. package/dist/components/data-table-v8/{data-table-virtual-rows.svelte → virtual/data-table-virtual-rows.svelte} +4 -4
  12. package/dist/components/data-table-v8/{data-table-virtual-rows.svelte.d.ts → virtual/data-table-virtual-rows.svelte.d.ts} +1 -1
  13. package/dist/components/data-table-v8/{data-table-virtualized.svelte → virtual/data-table-virtualized.svelte} +3 -3
  14. package/dist/components/data-table-v8/{data-table-virtualized.svelte.d.ts → virtual/data-table-virtualized.svelte.d.ts} +1 -1
  15. package/dist/components/data-table-v8/virtual/index.d.ts +1 -1
  16. package/dist/components/data-table-v8/virtual/index.js +1 -1
  17. package/dist/components/number-input/number-input.svelte +1 -1
  18. package/dist/components/toggle/toggle.svelte +6 -1
  19. package/dist/components/toggle/toggle.variants.d.ts +9 -0
  20. package/dist/components/toggle/toggle.variants.js +9 -1
  21. package/dist/components/toggle/types.d.ts +1 -0
  22. package/dist/components/toggle-group/toggle-group-context.d.ts +7 -0
  23. package/dist/components/toggle-group/toggle-group-item.svelte +9 -5
  24. package/dist/components/toggle-group/toggle-group-item.svelte.d.ts +1 -0
  25. package/dist/components/toggle-group/toggle-group.svelte +24 -9
  26. package/dist/components/toggle-group/toggle-group.svelte.d.ts +3 -0
  27. package/package.json +1 -1
  28. /package/dist/components/data-table-v8/{data-table-toolbar.svelte → toolbar/data-table-toolbar.svelte} +0 -0
  29. /package/dist/components/data-table-v8/{data-table-toolbar.svelte.d.ts → toolbar/data-table-toolbar.svelte.d.ts} +0 -0
@@ -3,6 +3,8 @@
3
3
  import { Field } from '@ark-ui/svelte/field';
4
4
  import { useFilter } from '@ark-ui/svelte/locale';
5
5
  import { Portal } from '@ark-ui/svelte/portal';
6
+ import { createVirtualizer } from '@tanstack/svelte-virtual';
7
+ import { untrack } from 'svelte';
6
8
  import type { ComboboxProps } from './types';
7
9
  import { createListCollection, type ListItem } from '../../utils/collections';
8
10
  import { cn } from 'tailwind-variants';
@@ -18,26 +20,22 @@
18
20
  readOnly,
19
21
  multiple,
20
22
  loading = false,
23
+ virtualized = false,
21
24
  class: className,
22
25
  onValueChange,
23
26
  ...restProps
24
27
  }: ComboboxProps<T> = $props();
25
28
 
26
- // Client-side filtering state
27
29
  let filterText = $state('');
28
- const filters = useFilter({ sensitivity: 'base' });
29
30
 
30
- // Base collection only rebuilds when items prop changes
31
+ const filters = useFilter({ sensitivity: 'base' });
31
32
  const baseCollection = $derived(createListCollection(items));
32
-
33
- // Filtered view — lightweight .filter() on keystroke, full collection when empty
34
33
  const collection = $derived(
35
34
  filterText
36
35
  ? baseCollection.filter((itemString) => filters().contains(itemString, filterText))
37
36
  : baseCollection
38
37
  );
39
38
 
40
- // Handle input change — only filter on actual user typing, not on selection/clear events
41
39
  function handleInputChange(details: Combobox.InputValueChangeDetails) {
42
40
  if (details.reason === 'input-change') {
43
41
  filterText = details.inputValue;
@@ -78,6 +76,29 @@
78
76
  }
79
77
  onValueChange?.(details);
80
78
  }
79
+
80
+ let contentRef = $state<HTMLDivElement | null>(null);
81
+
82
+ const virtualizer = createVirtualizer({
83
+ get count() {
84
+ return virtualized ? collection.size : 0;
85
+ },
86
+ getScrollElement: () => contentRef,
87
+ estimateSize: () => 36,
88
+ overscan: 10
89
+ });
90
+
91
+ $effect(() => {
92
+ const count = virtualized ? collection.size : 0;
93
+ const scrollElement = contentRef;
94
+
95
+ if (!scrollElement) return;
96
+
97
+ untrack(() => {
98
+ $virtualizer.setOptions({ ...$virtualizer.options, count });
99
+ $virtualizer.measure();
100
+ });
101
+ });
81
102
  </script>
82
103
 
83
104
  <Combobox.Root
@@ -86,6 +107,9 @@
86
107
  inputValue={controlledInputValue}
87
108
  onValueChange={handleValueChange}
88
109
  onInputValueChange={handleInputChange}
110
+ scrollToIndexFn={virtualized
111
+ ? (d) => $virtualizer.scrollToIndex(d.index, { align: 'center' })
112
+ : undefined}
89
113
  openOnClick
90
114
  {multiple}
91
115
  {readOnly}
@@ -140,31 +164,78 @@
140
164
  <Portal>
141
165
  <Combobox.Positioner class="data-[state=closed]:pointer-events-none">
142
166
  <Combobox.Content
143
- class="z-200 max-h-60 min-w-(--reference-width) overflow-auto rounded-md border bg-surface-document p-1 shadow-md data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95"
167
+ class={cn(
168
+ 'z-200 min-w-(--reference-width) rounded-md border bg-surface-document p-1 shadow-md',
169
+ 'data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95',
170
+ 'data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95',
171
+ virtualized ? 'overflow-hidden' : 'max-h-60 overflow-auto'
172
+ )}
144
173
  >
145
- {#if loading}
146
- <div class="flex items-center justify-center py-4">
147
- <span
148
- class="size-5 animate-spin rounded-full border-2 border-surface-3 border-t-ink-dim"
149
- ></span>
150
- </div>
174
+ {#if virtualized}
175
+ {#if loading}
176
+ <div class="flex items-center justify-center py-4">
177
+ <span
178
+ class="size-5 animate-spin rounded-full border-2 border-surface-3 border-t-ink-dim"
179
+ ></span>
180
+ </div>
181
+ {:else if collection.size === 0}
182
+ <Combobox.Empty class="py-2 text-center text-sm text-ink-dim">
183
+ No results found
184
+ </Combobox.Empty>
185
+ {:else}
186
+ <div
187
+ bind:this={contentRef}
188
+ class="overflow-auto overscroll-contain"
189
+ style="height: min(15rem, {$virtualizer.getTotalSize()}px);"
190
+ >
191
+ <div
192
+ style="height: {$virtualizer.getTotalSize()}px; width: 100%; position: relative;"
193
+ >
194
+ {#each $virtualizer.getVirtualItems() as vItem (vItem.key)}
195
+ {@const item = collection.items[vItem.index]}
196
+ {#if item}
197
+ <Combobox.Item
198
+ {item}
199
+ aria-setsize={collection.size}
200
+ aria-posinset={vItem.index + 1}
201
+ style="position:absolute;top:0;left:0;width:100%;height:{vItem.size}px;transform:translateY({vItem.start}px)"
202
+ class="relative flex cursor-default items-center rounded-sm py-1.5 pr-8 pl-2 text-sm select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-highlighted:bg-surface-1 data-[state=checked]:bg-surface-1"
203
+ >
204
+ <Combobox.ItemText>{item.label}</Combobox.ItemText>
205
+ <Combobox.ItemIndicator class="absolute right-2 items-center justify-center">
206
+ <PhCheck class="size-3.5" />
207
+ </Combobox.ItemIndicator>
208
+ </Combobox.Item>
209
+ {/if}
210
+ {/each}
211
+ </div>
212
+ </div>
213
+ {/if}
151
214
  {:else}
152
- <Combobox.Empty class="py-2 text-center text-sm text-ink-dim">
153
- No results found
154
- </Combobox.Empty>
155
- {/if}
215
+ {#if loading}
216
+ <div class="flex items-center justify-center py-4">
217
+ <span
218
+ class="size-5 animate-spin rounded-full border-2 border-surface-3 border-t-ink-dim"
219
+ ></span>
220
+ </div>
221
+ {:else}
222
+ <Combobox.Empty class="py-2 text-center text-sm text-ink-dim">
223
+ No results found
224
+ </Combobox.Empty>
225
+ {/if}
156
226
 
157
- {#each loading ? [] : collection.items as item (item.value)}
158
- <Combobox.Item
159
- {item}
160
- class="relative flex cursor-default items-center rounded-sm py-1.5 pr-8 pl-2 text-sm select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-highlighted:bg-surface-1 data-[state=checked]:bg-surface-1"
161
- >
162
- <Combobox.ItemText>{item.label}</Combobox.ItemText>
163
- <Combobox.ItemIndicator class="absolute right-2 items-center justify-center">
164
- <PhCheck class="size-3.5" />
165
- </Combobox.ItemIndicator>
166
- </Combobox.Item>
167
- {/each}
227
+ {#each loading ? [] : collection.items as item (item.value)}
228
+ <Combobox.Item
229
+ {item}
230
+ class="relative flex cursor-default items-center rounded-sm py-1.5 pr-8 pl-2 text-sm select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-highlighted:bg-surface-1 data-[state=checked]:bg-surface-1"
231
+ >
232
+ <Combobox.ItemText>{item.label}</Combobox.ItemText>
233
+ <Combobox.ItemIndicator class="absolute right-2 items-center justify-center">
234
+ <PhCheck class="size-3.5" />
235
+ </Combobox.ItemIndicator>
236
+ </Combobox.Item>
237
+ {/each}
238
+ {/if}
168
239
  </Combobox.Content>
169
240
  </Combobox.Positioner>
170
241
  </Portal>
@@ -9,5 +9,6 @@ export interface ComboboxProps<T extends ListItem> extends Omit<ComboboxRootBase
9
9
  multiple?: boolean;
10
10
  layout?: 'vertical' | 'horizontal';
11
11
  loading?: boolean;
12
+ virtualized?: boolean;
12
13
  class?: string;
13
14
  }
@@ -3,10 +3,10 @@ export { createTable } from './create-table.svelte';
3
3
  export { renderComponent, renderSnippet } from './render-helpers';
4
4
  export { default as FlexRender } from './flex-render.svelte';
5
5
  export { default as Root } from './data-table.svelte';
6
- export { default as Toolbar } from './data-table-toolbar.svelte';
7
6
  export { default as Title } from './data-table-title.svelte';
8
- export { default as ColumnVisibility } from './data-table-column-visibility.svelte';
9
- export { default as ColumnFilter } from './data-table-column-filter.svelte';
10
- export { default as Search } from './data-table-search.svelte';
7
+ export { default as Toolbar } from './toolbar/data-table-toolbar.svelte';
8
+ export { default as ColumnFilter } from './toolbar/data-table-column-filter.svelte';
9
+ export { default as ColumnVisibility } from './toolbar/data-table-column-visibility.svelte';
10
+ export { default as Search } from './toolbar/data-table-search.svelte';
11
11
  export type { CreateDataTableOptions, DataTableInstance } from './create-table.svelte';
12
12
  export type { DataTableAlign, DataTableAccessorFnColumn, DataTableAccessorKeyColumn, DataTableColumn, DataTableColumnBase, DataTableColumnOptions, DataTableColumnType, DataTableCellPropsResolver, DataTableCellRenderProps, DataTableGroupColumn, DataTableLeafColumnBase, DataTableLeafColumn } from './types';
@@ -3,8 +3,8 @@ export { createTable } from './create-table.svelte';
3
3
  export { renderComponent, renderSnippet } from './render-helpers';
4
4
  export { default as FlexRender } from './flex-render.svelte';
5
5
  export { default as Root } from './data-table.svelte';
6
- export { default as Toolbar } from './data-table-toolbar.svelte';
7
6
  export { default as Title } from './data-table-title.svelte';
8
- export { default as ColumnVisibility } from './data-table-column-visibility.svelte';
9
- export { default as ColumnFilter } from './data-table-column-filter.svelte';
10
- export { default as Search } from './data-table-search.svelte';
7
+ export { default as Toolbar } from './toolbar/data-table-toolbar.svelte';
8
+ export { default as ColumnFilter } from './toolbar/data-table-column-filter.svelte';
9
+ export { default as ColumnVisibility } from './toolbar/data-table-column-visibility.svelte';
10
+ export { default as Search } from './toolbar/data-table-search.svelte';
@@ -1,13 +1,13 @@
1
1
  <script lang="ts" generics="T extends RowData">
2
2
  import { onDestroy } from 'svelte';
3
3
  import type { Column, RowData } from '@tanstack/table-core';
4
- import * as Popover from '../popover';
5
- import * as ScrollArea from '../scroll-area';
6
- import Checkbox from '../checkbox/checkbox.svelte';
4
+ import * as Popover from '../../popover';
5
+ import * as ScrollArea from '../../scroll-area';
6
+ import Checkbox from '../../checkbox/checkbox.svelte';
7
7
  import { cn } from 'tailwind-variants';
8
- import { getReactiveTableState, type DataTableInstance } from './data-table-utils';
9
- import NumberInput from '../number-input/number-input.svelte';
10
- import * as Field from '../field';
8
+ import { getReactiveTableState, type DataTableInstance } from '../data-table-utils';
9
+ import NumberInput from '../../number-input/number-input.svelte';
10
+ import * as Field from '../../field';
11
11
 
12
12
  type Props = {
13
13
  table: DataTableInstance<T>;
@@ -1,5 +1,5 @@
1
1
  import type { RowData } from '@tanstack/table-core';
2
- import { type DataTableInstance } from './data-table-utils';
2
+ import { type DataTableInstance } from '../data-table-utils';
3
3
  declare function $$render<T extends RowData>(): {
4
4
  props: {
5
5
  table: DataTableInstance<T>;
@@ -1,9 +1,9 @@
1
1
  <script lang="ts" generics="T extends RowData">
2
2
  import type { RowData } from '@tanstack/table-core';
3
- import * as Popover from '../popover';
4
- import * as ScrollArea from '../scroll-area';
5
- import Checkbox from '../checkbox/checkbox.svelte';
6
- import { getReactiveTableState, type DataTableInstance } from './data-table-utils';
3
+ import * as Popover from '../../popover';
4
+ import * as ScrollArea from '../../scroll-area';
5
+ import Checkbox from '../../checkbox/checkbox.svelte';
6
+ import { getReactiveTableState, type DataTableInstance } from '../data-table-utils';
7
7
 
8
8
  type Props = {
9
9
  table: DataTableInstance<T>;
@@ -1,5 +1,5 @@
1
1
  import type { RowData } from '@tanstack/table-core';
2
- import { type DataTableInstance } from './data-table-utils';
2
+ import { type DataTableInstance } from '../data-table-utils';
3
3
  declare function $$render<T extends RowData>(): {
4
4
  props: {
5
5
  table: DataTableInstance<T>;
@@ -2,9 +2,9 @@
2
2
  import { onDestroy } from 'svelte';
3
3
  import type { RowData } from '@tanstack/table-core';
4
4
  import { cn, type ClassValue } from 'tailwind-variants';
5
- import { PhMagnifyingGlass, PhX } from '../../icons';
6
- import * as Field from '../field';
7
- import { getReactiveTableState, type DataTableInstance } from './data-table-utils';
5
+ import { PhMagnifyingGlass, PhX } from '../../../icons';
6
+ import * as Field from '../../field';
7
+ import { getReactiveTableState, type DataTableInstance } from '../data-table-utils';
8
8
 
9
9
  type Props = {
10
10
  table: DataTableInstance<T>;
@@ -1,6 +1,6 @@
1
1
  import type { RowData } from '@tanstack/table-core';
2
2
  import { type ClassValue } from 'tailwind-variants';
3
- import { type DataTableInstance } from './data-table-utils';
3
+ import { type DataTableInstance } from '../data-table-utils';
4
4
  declare function $$render<T extends RowData>(): {
5
5
  props: {
6
6
  table: DataTableInstance<T>;
@@ -3,9 +3,9 @@
3
3
  import { createVirtualizer } from '@tanstack/svelte-virtual';
4
4
  import { untrack } from 'svelte';
5
5
  import { cn } from 'tailwind-variants';
6
- import { PhArrowSquareOut, PhCheck, PhX } from '../../icons';
7
- import type { DataTableInstance } from './data-table-utils';
8
- import FlexRender from './flex-render.svelte';
6
+ import { PhArrowSquareOut, PhCheck, PhX } from '../../../icons';
7
+ import type { DataTableInstance } from '../data-table-utils';
8
+ import FlexRender from '../flex-render.svelte';
9
9
  import {
10
10
  alignClass,
11
11
  getBooleanCellValue,
@@ -20,7 +20,7 @@
20
20
  virtualColumnSizeStyle,
21
21
  virtualGrowColumnSizeStyle,
22
22
  virtualSelectionColumnSizeStyle
23
- } from './data-table-utils';
23
+ } from '../data-table-utils';
24
24
 
25
25
  type Props = {
26
26
  rows: Row<T>[];
@@ -1,5 +1,5 @@
1
1
  import type { Row, RowData } from '@tanstack/table-core';
2
- import type { DataTableInstance } from './data-table-utils';
2
+ import type { DataTableInstance } from '../data-table-utils';
3
3
  declare function $$render<T extends RowData>(): {
4
4
  props: {
5
5
  rows: Row<T>[];
@@ -2,15 +2,15 @@
2
2
  import type { RowData } from '@tanstack/table-core';
3
3
  import type { HTMLAttributes } from 'svelte/elements';
4
4
  import { cn, type ClassValue } from 'tailwind-variants';
5
- import type { DataTableInstance } from './data-table-utils';
6
- import DataTableHead from './data-table-head.svelte';
5
+ import type { DataTableInstance } from '../data-table-utils';
6
+ import DataTableHead from '../data-table-head.svelte';
7
7
  import DataTableVirtualRows from './data-table-virtual-rows.svelte';
8
8
  import {
9
9
  getAllRowsSelectionState,
10
10
  getReactiveTableState,
11
11
  getSelectedRowCount,
12
12
  tableSizeStyle
13
- } from './data-table-utils';
13
+ } from '../data-table-utils';
14
14
 
15
15
  type Props = Omit<HTMLAttributes<HTMLDivElement>, 'class'> & {
16
16
  table: DataTableInstance<T>;
@@ -1,7 +1,7 @@
1
1
  import type { RowData } from '@tanstack/table-core';
2
2
  import type { HTMLAttributes } from 'svelte/elements';
3
3
  import { type ClassValue } from 'tailwind-variants';
4
- import type { DataTableInstance } from './data-table-utils';
4
+ import type { DataTableInstance } from '../data-table-utils';
5
5
  declare function $$render<T extends RowData>(): {
6
6
  props: Omit<HTMLAttributes<HTMLDivElement>, "class"> & {
7
7
  table: DataTableInstance<T>;
@@ -1,3 +1,3 @@
1
- export { default as Root } from '../data-table-virtualized.svelte';
1
+ export { default as Root } from './data-table-virtualized.svelte';
2
2
  export { ColumnFilter, ColumnVisibility, FlexRender, Search, Title, Toolbar, createDataTableColumnHelper, createTable, renderComponent, renderSnippet } from '../index';
3
3
  export type { CreateDataTableOptions, DataTableAccessorFnColumn, DataTableAccessorKeyColumn, DataTableAlign, DataTableCellPropsResolver, DataTableCellRenderProps, DataTableColumn, DataTableColumnBase, DataTableColumnOptions, DataTableColumnType, DataTableGroupColumn, DataTableInstance, DataTableLeafColumn, DataTableLeafColumnBase } from '../index';
@@ -1,2 +1,2 @@
1
- export { default as Root } from '../data-table-virtualized.svelte';
1
+ export { default as Root } from './data-table-virtualized.svelte';
2
2
  export { ColumnFilter, ColumnVisibility, FlexRender, Search, Title, Toolbar, createDataTableColumnHelper, createTable, renderComponent, renderSnippet } from '../index';
@@ -28,7 +28,7 @@
28
28
  {...restProps}
29
29
  allowMouseWheel
30
30
  locale={locale().locale}
31
- value={value?.toString()}
31
+ value={value != null ? new Intl.NumberFormat(locale().locale, { useGrouping: false, maximumFractionDigits: 20 }).format(value) : undefined}
32
32
  readOnly={readonly}
33
33
  onValueChange={(valueChangeDetails) => {
34
34
  onValueChange?.(valueChangeDetails);
@@ -8,10 +8,15 @@
8
8
  children,
9
9
  pressed = $bindable(),
10
10
  size,
11
+ icon,
11
12
  ...rootProps
12
13
  }: ToggleProps = $props();
13
14
  </script>
14
15
 
15
- <ArkToggle.Root {...rootProps} bind:pressed class={toggle({ size, class: className as never })}>
16
+ <ArkToggle.Root
17
+ {...rootProps}
18
+ bind:pressed
19
+ class={toggle({ size, icon, class: className as never })}
20
+ >
16
21
  {@render children?.()}
17
22
  </ArkToggle.Root>
@@ -5,17 +5,26 @@ export declare const toggle: import("tailwind-variants").TVReturnType<{
5
5
  md: string;
6
6
  lg: string;
7
7
  };
8
+ icon: {
9
+ true: string;
10
+ };
8
11
  }, undefined, "inline-flex cursor-pointer items-center justify-center rounded-md font-medium text-ink-dim transition-colors select-none hover:bg-surface-2 hover:text-ink focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-pressed:bg-surface-2 data-pressed:text-ink data-pressed:shadow-sm data-[state=on]:bg-surface-2 data-[state=on]:text-ink data-[state=on]:shadow-sm [&_svg]:shrink-0", {
9
12
  size: {
10
13
  sm: string;
11
14
  md: string;
12
15
  lg: string;
13
16
  };
17
+ icon: {
18
+ true: string;
19
+ };
14
20
  }, undefined, import("tailwind-variants").TVReturnType<{
15
21
  size: {
16
22
  sm: string;
17
23
  md: string;
18
24
  lg: string;
19
25
  };
26
+ icon: {
27
+ true: string;
28
+ };
20
29
  }, undefined, "inline-flex cursor-pointer items-center justify-center rounded-md font-medium text-ink-dim transition-colors select-none hover:bg-surface-2 hover:text-ink focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-pressed:bg-surface-2 data-pressed:text-ink data-pressed:shadow-sm data-[state=on]:bg-surface-2 data-[state=on]:text-ink data-[state=on]:shadow-sm [&_svg]:shrink-0", unknown, unknown, undefined>>;
21
30
  export type ToggleSize = NonNullable<VariantProps<typeof toggle>['size']>;
@@ -5,8 +5,16 @@ export const toggle = tv({
5
5
  size: {
6
6
  sm: 'h-7 min-w-7 gap-1 px-1.5 text-xs [&_svg]:size-3.5',
7
7
  md: 'h-8 min-w-8 gap-1.5 px-2 text-sm [&_svg]:size-4',
8
- lg: 'h-10 min-w-10 gap-2 px-2.5 text-sm [&_svg]:size-5'
8
+ lg: 'h-9 min-w-9 gap-2 px-2.5 text-sm [&_svg]:size-5'
9
+ },
10
+ icon: {
11
+ true: ''
9
12
  }
10
13
  },
14
+ compoundVariants: [
15
+ { size: 'sm', icon: true, class: 'w-7 px-0 [&_svg]:size-5' },
16
+ { size: 'md', icon: true, class: 'w-8 px-0 [&_svg]:size-6' },
17
+ { size: 'lg', icon: true, class: 'w-9 px-0 [&_svg]:size-7' }
18
+ ],
11
19
  defaultVariants: { size: 'md' }
12
20
  });
@@ -4,5 +4,6 @@ import type { ToggleSize } from './toggle.variants';
4
4
  export interface ToggleProps extends ToggleRootProps {
5
5
  class?: ClassValue | null;
6
6
  size?: ToggleSize;
7
+ icon?: boolean;
7
8
  }
8
9
  export type { ToggleSize };
@@ -1,8 +1,15 @@
1
1
  import type { ToggleSize } from '../toggle/toggle.variants';
2
+ export type ToggleGroupVariant = 'outline' | 'ghost';
2
3
  export declare const getToggleGroupContext: () => {
3
4
  readonly size: ToggleSize;
5
+ readonly variant: ToggleGroupVariant;
6
+ readonly icon: boolean;
4
7
  }, setToggleGroupContext: (context: {
5
8
  readonly size: ToggleSize;
9
+ readonly variant: ToggleGroupVariant;
10
+ readonly icon: boolean;
6
11
  }) => {
7
12
  readonly size: ToggleSize;
13
+ readonly variant: ToggleGroupVariant;
14
+ readonly icon: boolean;
8
15
  };
@@ -8,16 +8,20 @@
8
8
  interface Props extends ToggleGroupItemBaseProps {
9
9
  class?: ClassValue | null;
10
10
  size?: ToggleSize;
11
+ icon?: boolean;
11
12
  }
12
13
 
13
- let { class: className, children, size, ...rest }: Props = $props();
14
+ let { class: className, children, size, icon, ...rest }: Props = $props();
14
15
  const groupContext = getToggleGroupContext();
15
16
  const itemSize = $derived(size ?? groupContext.size);
17
+ const itemIcon = $derived(icon ?? groupContext.icon);
18
+ const itemClass = $derived(
19
+ groupContext.variant === 'ghost'
20
+ ? toggle({ size: itemSize, icon: itemIcon, class: className as never })
21
+ : toggle({ size: itemSize, icon: itemIcon, class: ['rounded-none', className] as never })
22
+ );
16
23
  </script>
17
24
 
18
- <ToggleGroup.Item
19
- {...rest}
20
- class={toggle({ size: itemSize, class: ['rounded-none', className] as never })}
21
- >
25
+ <ToggleGroup.Item {...rest} class={itemClass}>
22
26
  {@render children?.()}
23
27
  </ToggleGroup.Item>
@@ -4,6 +4,7 @@ import { type ToggleSize } from '../toggle/toggle.variants';
4
4
  interface Props extends ToggleGroupItemBaseProps {
5
5
  class?: ClassValue | null;
6
6
  size?: ToggleSize;
7
+ icon?: boolean;
7
8
  }
8
9
  declare const ToggleGroupItem: import("svelte").Component<Props, {}, "">;
9
10
  type ToggleGroupItem = ReturnType<typeof ToggleGroupItem>;
@@ -3,11 +3,13 @@
3
3
  import type { ToggleGroupRootBaseProps } from '@ark-ui/svelte/toggle-group';
4
4
  import { cn } from 'tailwind-variants';
5
5
  import type { ToggleSize } from '../toggle/toggle.variants';
6
- import { setToggleGroupContext } from './toggle-group-context';
6
+ import { setToggleGroupContext, type ToggleGroupVariant } from './toggle-group-context';
7
7
 
8
8
  interface Props extends ToggleGroupRootBaseProps {
9
9
  class?: string;
10
10
  size?: ToggleSize;
11
+ variant?: ToggleGroupVariant;
12
+ icon?: boolean;
11
13
  }
12
14
 
13
15
  let {
@@ -15,23 +17,36 @@
15
17
  children,
16
18
  value = $bindable(),
17
19
  size = 'md',
20
+ variant = 'outline',
21
+ icon = false,
18
22
  ...rootProps
19
23
  }: Props = $props();
20
24
 
21
25
  setToggleGroupContext({
22
26
  get size() {
23
27
  return size;
28
+ },
29
+ get variant() {
30
+ return variant;
31
+ },
32
+ get icon() {
33
+ return icon;
24
34
  }
25
35
  });
36
+
37
+ const rootClass = $derived(
38
+ variant === 'ghost'
39
+ ? cn(
40
+ 'inline-flex w-fit gap-1 data-[orientation=vertical]:flex-col data-[orientation=vertical]:gap-1',
41
+ className
42
+ )
43
+ : cn(
44
+ 'inline-flex w-fit rounded border border-border data-[orientation=vertical]:flex-col [&>:not([hidden])~:not([hidden])]:border-border data-[orientation=horizontal]:[&>:not([hidden])~:not([hidden])]:border-s data-[orientation=horizontal]:[&>:not([hidden])~:not([hidden])]:border-e-0 data-[orientation=vertical]:[&>:not([hidden])~:not([hidden])]:border-t data-[orientation=vertical]:[&>:not([hidden])~:not([hidden])]:border-b-0',
45
+ className
46
+ )
47
+ );
26
48
  </script>
27
49
 
28
- <ToggleGroup.Root
29
- {...rootProps}
30
- bind:value
31
- class={cn(
32
- 'inline-flex w-fit rounded border border-border data-[orientation=vertical]:flex-col [&>:not([hidden])~:not([hidden])]:border-border data-[orientation=horizontal]:[&>:not([hidden])~:not([hidden])]:border-s data-[orientation=horizontal]:[&>:not([hidden])~:not([hidden])]:border-e-0 data-[orientation=vertical]:[&>:not([hidden])~:not([hidden])]:border-t data-[orientation=vertical]:[&>:not([hidden])~:not([hidden])]:border-b-0',
33
- className
34
- )}
35
- >
50
+ <ToggleGroup.Root {...rootProps} bind:value class={rootClass}>
36
51
  {@render children?.()}
37
52
  </ToggleGroup.Root>
@@ -1,9 +1,12 @@
1
1
  import { ToggleGroup } from '@ark-ui/svelte/toggle-group';
2
2
  import type { ToggleGroupRootBaseProps } from '@ark-ui/svelte/toggle-group';
3
3
  import type { ToggleSize } from '../toggle/toggle.variants';
4
+ import { type ToggleGroupVariant } from './toggle-group-context';
4
5
  interface Props extends ToggleGroupRootBaseProps {
5
6
  class?: string;
6
7
  size?: ToggleSize;
8
+ variant?: ToggleGroupVariant;
9
+ icon?: boolean;
7
10
  }
8
11
  declare const ToggleGroup: import("svelte").Component<Props, {}, "value">;
9
12
  type ToggleGroup = ReturnType<typeof ToggleGroup>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "compote-ui",
3
- "version": "0.46.4",
3
+ "version": "0.47.1",
4
4
  "license": "MIT",
5
5
  "scripts": {
6
6
  "dev": "vite dev --open",