compote-ui 0.35.0 → 0.36.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.
@@ -6,6 +6,8 @@ declare const dataTableFeatures: {
6
6
  columnResizingFeature: import("@tanstack/table-core").TableFeature<import("@tanstack/table-core").ColumnResizingFeatureConstructors<import("@tanstack/table-core").TableFeatures, RowData>>;
7
7
  columnFilteringFeature: import("@tanstack/table-core").TableFeature<import("@tanstack/table-core").ColumnFilteringFeatureConstructors<import("@tanstack/table-core").TableFeatures, RowData>>;
8
8
  columnFacetingFeature: import("@tanstack/table-core").TableFeature<import("@tanstack/table-core").ColumnFacetingFeatureConstructors<import("@tanstack/table-core").TableFeatures, RowData>>;
9
+ columnPinningFeature: import("@tanstack/table-core").TableFeature<import("@tanstack/table-core").ColumnPinningFeatureConstructors<import("@tanstack/table-core").TableFeatures, RowData>>;
10
+ columnOrderingFeature: import("@tanstack/table-core").TableFeature<import("@tanstack/table-core").ColumnOrderingFeatureConstructors<import("@tanstack/table-core").TableFeatures, RowData>>;
9
11
  rowSelectionFeature: import("@tanstack/table-core").TableFeature<import("@tanstack/table-core").RowSelectionFeatureConstructors<import("@tanstack/table-core").TableFeatures, RowData>>;
10
12
  rowSortingFeature: import("@tanstack/table-core").TableFeature<import("@tanstack/table-core").RowSortingFeatureConstructors<import("@tanstack/table-core").TableFeatures, RowData>>;
11
13
  };
@@ -31,6 +33,8 @@ export declare function createTable<T extends RowData>(options: CreateDataTableO
31
33
  columnResizingFeature: import("@tanstack/table-core").TableFeature<import("@tanstack/table-core").ColumnResizingFeatureConstructors<import("@tanstack/table-core").TableFeatures, RowData>>;
32
34
  columnFilteringFeature: import("@tanstack/table-core").TableFeature<import("@tanstack/table-core").ColumnFilteringFeatureConstructors<import("@tanstack/table-core").TableFeatures, RowData>>;
33
35
  columnFacetingFeature: import("@tanstack/table-core").TableFeature<import("@tanstack/table-core").ColumnFacetingFeatureConstructors<import("@tanstack/table-core").TableFeatures, RowData>>;
36
+ columnPinningFeature: import("@tanstack/table-core").TableFeature<import("@tanstack/table-core").ColumnPinningFeatureConstructors<import("@tanstack/table-core").TableFeatures, RowData>>;
37
+ columnOrderingFeature: import("@tanstack/table-core").TableFeature<import("@tanstack/table-core").ColumnOrderingFeatureConstructors<import("@tanstack/table-core").TableFeatures, RowData>>;
34
38
  rowSelectionFeature: import("@tanstack/table-core").TableFeature<import("@tanstack/table-core").RowSelectionFeatureConstructors<import("@tanstack/table-core").TableFeatures, RowData>>;
35
39
  rowSortingFeature: import("@tanstack/table-core").TableFeature<import("@tanstack/table-core").RowSortingFeatureConstructors<import("@tanstack/table-core").TableFeatures, RowData>>;
36
40
  }, T, DataTableSelectedState>;
@@ -1,4 +1,4 @@
1
- import { columnVisibilityFeature, columnResizingFeature, columnSizingFeature, columnFilteringFeature, columnFacetingFeature, createSortedRowModel, createFilteredRowModel, createFacetedRowModel, createFacetedMinMaxValues, createFacetedUniqueValues, createTable as createTanStackTable, filterFns, renderComponent, renderSnippet, rowSelectionFeature, rowSortingFeature, sortFns, tableFeatures } from '@tanstack/svelte-table';
1
+ import { columnVisibilityFeature, columnResizingFeature, columnSizingFeature, columnFilteringFeature, columnFacetingFeature, columnPinningFeature, columnOrderingFeature, createSortedRowModel, createFilteredRowModel, createFacetedRowModel, createFacetedMinMaxValues, createFacetedUniqueValues, createTable as createTanStackTable, filterFns, renderComponent, renderSnippet, rowSelectionFeature, rowSortingFeature, sortFns, tableFeatures } from '@tanstack/svelte-table';
2
2
  import { useLocaleContext } from '@ark-ui/svelte/locale';
3
3
  const dataTableFeatures = tableFeatures({
4
4
  columnVisibilityFeature,
@@ -6,6 +6,8 @@ const dataTableFeatures = tableFeatures({
6
6
  columnResizingFeature,
7
7
  columnFilteringFeature,
8
8
  columnFacetingFeature,
9
+ columnPinningFeature,
10
+ columnOrderingFeature,
9
11
  rowSelectionFeature,
10
12
  rowSortingFeature
11
13
  });
@@ -39,6 +41,7 @@ export function createTable(options) {
39
41
  initialState: {
40
42
  columnVisibility: createColumnVisibility(options.columns),
41
43
  columnSizing: createColumnSizing(options.columns),
44
+ columnPinning: createColumnPinning(options.columns),
42
45
  rowSelection: options.initialRowSelection ?? {},
43
46
  sorting: options.initialSorting ?? [],
44
47
  columnFilters: options.initialColumnFilters ?? []
@@ -66,6 +69,13 @@ function createColumnSizing(columns) {
66
69
  return sizes;
67
70
  }, {});
68
71
  }
72
+ function createColumnPinning(columns) {
73
+ const leafCols = getLeafColumns(columns);
74
+ return {
75
+ left: leafCols.filter((c) => c.pinned === 'left').map(getColumnId),
76
+ right: leafCols.filter((c) => c.pinned === 'right').map(getColumnId)
77
+ };
78
+ }
69
79
  function createColumns(columns, localeCtx) {
70
80
  return columns.map((column) => {
71
81
  if (isGroupColumn(column)) {
@@ -1,6 +1,6 @@
1
1
  <script lang="ts" generics="T extends RowData">
2
2
  import { FlexRender } from '@tanstack/svelte-table';
3
- import type { CellData, Header, RowData } from '@tanstack/svelte-table';
3
+ import type { CellData, ColumnPinningPosition, Header, RowData } from '@tanstack/svelte-table';
4
4
  import type { HTMLAttributes } from 'svelte/elements';
5
5
  import { cn, type ClassValue } from 'tailwind-variants';
6
6
  import { PhArrowSquareOut, PhCaretDown, PhCaretUp, PhCheck, PhX } from '../../icons';
@@ -110,6 +110,44 @@
110
110
  return undefined;
111
111
  }
112
112
 
113
+ // type PinPosition = 'center' | false | 'left' | 'right';
114
+ function getPinningStyle(
115
+ column: {
116
+ getIsPinned(): ColumnPinningPosition;
117
+ getStart(position?: ColumnPinningPosition): number;
118
+ getAfter(position?: ColumnPinningPosition): number;
119
+ getIsLastColumn(position?: ColumnPinningPosition): boolean;
120
+ getIsFirstColumn(position?: ColumnPinningPosition): boolean;
121
+ },
122
+ isHeader = false
123
+ ): string | undefined {
124
+ const isPinned = column.getIsPinned();
125
+ if (!isPinned) return undefined;
126
+
127
+ const zIndex = isHeader ? 15 : 1;
128
+ const selectionOffset = isRowSelectionEnabled ? 40 : 0;
129
+
130
+ if (isPinned === 'left') {
131
+ const left = column.getStart('left') + selectionOffset;
132
+ const shadow =
133
+ !isHeader && column.getIsLastColumn('left')
134
+ ? 'box-shadow: -4px 0 4px -4px var(--compote-border) inset'
135
+ : undefined;
136
+ return ['position: sticky', `z-index: ${zIndex}`, `left: ${left}px`, shadow]
137
+ .filter(Boolean)
138
+ .join('; ');
139
+ } else {
140
+ const right = column.getAfter('right');
141
+ const shadow =
142
+ !isHeader && column.getIsFirstColumn('right')
143
+ ? 'box-shadow: 4px 0 4px -4px var(--compote-border) inset'
144
+ : undefined;
145
+ return ['position: sticky', `z-index: ${zIndex}`, `right: ${right}px`, shadow]
146
+ .filter(Boolean)
147
+ .join('; ');
148
+ }
149
+ }
150
+
113
151
  function getUrlCellValue(value: unknown) {
114
152
  if (typeof value !== 'string' || value.trim() === '') return undefined;
115
153
  return value;
@@ -205,6 +243,7 @@
205
243
  {#if isRowSelectionEnabled && headerGroupIndex === 0}
206
244
  <th
207
245
  class="border-b border-surface-3 bg-surface-2 px-3 py-2 text-center align-middle font-medium"
246
+ style="position: sticky; left: 0; z-index: 15"
208
247
  rowspan={headerGroupCount}
209
248
  >
210
249
  {#if isMultiRowSelectionEnabled}
@@ -230,6 +269,7 @@
230
269
  aria-sort={header.column.getCanSort()
231
270
  ? getHeaderAriaSort(sortDirection)
232
271
  : undefined}
272
+ style={getPinningStyle(header.column, true)}
233
273
  >
234
274
  {#if !header.isPlaceholder}
235
275
  {#if header.column.getCanSort()}
@@ -281,12 +321,18 @@
281
321
  {@const rowSelected = getRowSelectionState(table.store.state.rowSelection, row.id)}
282
322
  <tr
283
323
  class={cn(
284
- 'border-b border-surface-3 last:border-b-0 hover:bg-well/60',
285
- rowSelected && 'bg-well/60'
324
+ 'group/row border-b border-surface-3 last:border-b-0',
325
+ '[--row-bg:var(--compote-surface-1)]',
326
+ 'hover:bg-well/60 hover:[--row-bg:color-mix(in_srgb,var(--compote-well)_60%,var(--compote-surface-1))]',
327
+ rowSelected &&
328
+ 'bg-well/60 [--row-bg:color-mix(in_srgb,var(--compote-well)_60%,var(--compote-surface-1))]'
286
329
  )}
287
330
  >
288
331
  {#if isRowSelectionEnabled}
289
- <td class="px-3 py-2 text-center align-middle">
332
+ <td
333
+ class="bg-(--row-bg) px-3 py-2 text-center align-middle"
334
+ style="position: sticky; left: 0; z-index: 1"
335
+ >
290
336
  <Checkbox
291
337
  size="sm"
292
338
  aria-label="Select row"
@@ -299,7 +345,14 @@
299
345
  {/if}
300
346
  {#each row.getVisibleCells() as cell (cell.id)}
301
347
  {@const columnDef = findColumnById(cell.column.id, columns)}
302
- <td class={cn('px-3 py-2 text-ink-dim', alignClass(columnDef?.align))}>
348
+ <td
349
+ class={cn(
350
+ 'truncate px-3 py-2',
351
+ alignClass(columnDef?.align),
352
+ cell.column.getIsPinned() && 'bg-(--row-bg)'
353
+ )}
354
+ style={getPinningStyle(cell.column)}
355
+ >
303
356
  {#if columnDef?.type === 'boolean'}
304
357
  {@const value = getBooleanCellValue(cell.getValue())}
305
358
  {#if value === true}
@@ -21,6 +21,7 @@ export type DataTableLeafColumnBase<T extends RowData> = DataTableColumnOptions<
21
21
  type?: DataTableColumnType;
22
22
  formatOptions?: Intl.NumberFormatOptions;
23
23
  formatLocale?: string;
24
+ pinned?: 'left' | 'right';
24
25
  columns?: never;
25
26
  };
26
27
  export type DataTableAccessorKeyColumn<T extends RowData> = DataTableLeafColumnBase<T> & {
@@ -0,0 +1,69 @@
1
+ <script lang="ts">
2
+ import { HoverCard } from '@ark-ui/svelte/hover-card';
3
+ import { Portal } from '@ark-ui/svelte/portal';
4
+ import { cn } from 'tailwind-variants';
5
+ import type { ClassValue } from 'svelte/elements';
6
+ import type { Snippet } from 'svelte';
7
+
8
+ interface Props {
9
+ class?: ClassValue;
10
+ children: Snippet;
11
+ showArrow?: boolean;
12
+ }
13
+
14
+ let { class: className, children, showArrow = true }: Props = $props();
15
+ </script>
16
+
17
+ <Portal>
18
+ <HoverCard.Positioner>
19
+ <HoverCard.Content
20
+ class={cn(
21
+ 'z-50 w-72 rounded-md border border-border bg-surface-1 p-4 shadow-md outline-none [--arrow-background:var(--compote-surface-1)] [--arrow-size:10px]',
22
+ className
23
+ )}
24
+ >
25
+ {#if showArrow}
26
+ <HoverCard.Arrow>
27
+ <HoverCard.ArrowTip class="border-t border-l border-border" />
28
+ </HoverCard.Arrow>
29
+ {/if}
30
+ {@render children()}
31
+ </HoverCard.Content>
32
+ </HoverCard.Positioner>
33
+ </Portal>
34
+
35
+ <style>
36
+ :global([data-scope='hover-card'][data-part='content']) {
37
+ transform-origin: var(--transform-origin);
38
+ }
39
+
40
+ :global([data-scope='hover-card'][data-part='content'][data-state='open']) {
41
+ animation: hover-card-in 150ms ease-out;
42
+ }
43
+
44
+ :global([data-scope='hover-card'][data-part='content'][data-state='closed']) {
45
+ animation: hover-card-out 100ms ease-in;
46
+ }
47
+
48
+ @keyframes hover-card-in {
49
+ from {
50
+ opacity: 0;
51
+ transform: scale(0.95);
52
+ }
53
+ to {
54
+ opacity: 1;
55
+ transform: scale(1);
56
+ }
57
+ }
58
+
59
+ @keyframes hover-card-out {
60
+ from {
61
+ opacity: 1;
62
+ transform: scale(1);
63
+ }
64
+ to {
65
+ opacity: 0;
66
+ transform: scale(0.95);
67
+ }
68
+ }
69
+ </style>
@@ -0,0 +1,10 @@
1
+ import type { ClassValue } from 'svelte/elements';
2
+ import type { Snippet } from 'svelte';
3
+ interface Props {
4
+ class?: ClassValue;
5
+ children: Snippet;
6
+ showArrow?: boolean;
7
+ }
8
+ declare const HoverCardContent: import("svelte").Component<Props, {}, "">;
9
+ type HoverCardContent = ReturnType<typeof HoverCardContent>;
10
+ export default HoverCardContent;
@@ -0,0 +1,24 @@
1
+ <script lang="ts">
2
+ import { HoverCard } from '@ark-ui/svelte/hover-card';
3
+ import type { HoverCardRootBaseProps } from '@ark-ui/svelte/hover-card';
4
+ import type { Snippet } from 'svelte';
5
+
6
+ interface Props extends HoverCardRootBaseProps {
7
+ open?: boolean;
8
+ children: Snippet;
9
+ lazyMount?: boolean;
10
+ unmountOnExit?: boolean;
11
+ }
12
+
13
+ let {
14
+ open = $bindable(),
15
+ children,
16
+ lazyMount = true,
17
+ unmountOnExit = true,
18
+ ...restProps
19
+ }: Props = $props();
20
+ </script>
21
+
22
+ <HoverCard.Root bind:open {lazyMount} {unmountOnExit} {...restProps}>
23
+ {@render children()}
24
+ </HoverCard.Root>
@@ -0,0 +1,11 @@
1
+ import type { HoverCardRootBaseProps } from '@ark-ui/svelte/hover-card';
2
+ import type { Snippet } from 'svelte';
3
+ interface Props extends HoverCardRootBaseProps {
4
+ open?: boolean;
5
+ children: Snippet;
6
+ lazyMount?: boolean;
7
+ unmountOnExit?: boolean;
8
+ }
9
+ declare const HoverCardRoot: import("svelte").Component<Props, {}, "open">;
10
+ type HoverCardRoot = ReturnType<typeof HoverCardRoot>;
11
+ export default HoverCardRoot;
@@ -0,0 +1,14 @@
1
+ <script lang="ts">
2
+ import { HoverCard } from '@ark-ui/svelte/hover-card';
3
+ import type { HoverCardTriggerProps } from '@ark-ui/svelte/hover-card';
4
+
5
+ type Props = Omit<HoverCardTriggerProps, 'class'> & {
6
+ class?: string;
7
+ };
8
+
9
+ const { class: className, children, ...restProps }: Props = $props();
10
+ </script>
11
+
12
+ <HoverCard.Trigger class={className} {...restProps}>
13
+ {@render children?.()}
14
+ </HoverCard.Trigger>
@@ -0,0 +1,7 @@
1
+ import type { HoverCardTriggerProps } from '@ark-ui/svelte/hover-card';
2
+ type Props = Omit<HoverCardTriggerProps, 'class'> & {
3
+ class?: string;
4
+ };
5
+ declare const HoverCardTrigger: import("svelte").Component<Props, {}, "">;
6
+ type HoverCardTrigger = ReturnType<typeof HoverCardTrigger>;
7
+ export default HoverCardTrigger;
@@ -0,0 +1,3 @@
1
+ export { default as Root } from './hover-card-root.svelte';
2
+ export { default as Trigger } from './hover-card-trigger.svelte';
3
+ export { default as Content } from './hover-card-content.svelte';
@@ -0,0 +1,3 @@
1
+ export { default as Root } from './hover-card-root.svelte';
2
+ export { default as Trigger } from './hover-card-trigger.svelte';
3
+ export { default as Content } from './hover-card-content.svelte';
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ export { default as Button } from './components/button/button.svelte';
4
4
  export { default as LinkButton } from './components/button/link-button.svelte';
5
5
  export * as Card from './components/card';
6
6
  export * as Collapsible from './components/collapsible';
7
+ export * as HoverCard from './components/hover-card';
7
8
  export * as ScrollArea from './components/scroll-area';
8
9
  export { loadImage, fileToDataUrl, cropImage, processImage } from './utils/image-processing';
9
10
  export type { ProcessImageOptions, CropRegion } from './utils/image-processing';
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ export { default as Button } from './components/button/button.svelte';
4
4
  export { default as LinkButton } from './components/button/link-button.svelte';
5
5
  export * as Card from './components/card';
6
6
  export * as Collapsible from './components/collapsible';
7
+ export * as HoverCard from './components/hover-card';
7
8
  export * as ScrollArea from './components/scroll-area';
8
9
  export { loadImage, fileToDataUrl, cropImage, processImage } from './utils/image-processing';
9
10
  export * as Carousel from './components/carousel';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "compote-ui",
3
- "version": "0.35.0",
3
+ "version": "0.36.0",
4
4
  "license": "MIT",
5
5
  "scripts": {
6
6
  "dev": "vite dev --open",