svelte-tably 1.3.0 → 1.5.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.
@@ -1,28 +1,16 @@
1
1
  export declare function getDefaultHeader<T, V>(title: string): () => any;
2
- import { type HeaderCtx } from './column-state.svelte.js';
2
+ import { type ColumnProps } from './column-state.svelte.js';
3
+ declare function $$render<T, V>(): {
4
+ props: ColumnProps<T, V>;
5
+ exports: {};
6
+ bindings: "";
7
+ slots: {};
8
+ events: {};
9
+ };
3
10
  declare class __sveltets_Render<T, V> {
4
- props(): {
5
- id: string;
6
- table?: import("../index.js").TableState<T> | undefined;
7
- header?: string | import("svelte").Snippet<[ctx: HeaderCtx<T>]> | undefined;
8
- row?: import("svelte").Snippet<[item: T, ctx: import("./column-state.svelte.js").RowColumnCtx<T, V>]> | undefined;
9
- statusbar?: import("svelte").Snippet<[ctx: import("./column-state.svelte.js").StatusbarCtx<T>]> | undefined;
10
- sticky?: boolean | undefined;
11
- show?: boolean | undefined;
12
- sortby?: boolean | undefined;
13
- width?: number | undefined;
14
- fixed?: boolean | undefined;
15
- value?: ((item: T) => V) | undefined;
16
- sort?: boolean | ((a: V, b: V) => number) | undefined;
17
- resizeable?: boolean | undefined;
18
- filter?: ((value: V) => boolean) | undefined;
19
- style?: string | undefined;
20
- class?: string | undefined;
21
- onclick?: ((event: MouseEvent, rowColumnCtx: import("./column-state.svelte.js").RowColumnCtx<T, V>) => void) | undefined;
22
- pad?: "row" | "header" | "statusbar" | "both" | undefined;
23
- };
24
- events(): {};
25
- slots(): {};
11
+ props(): ReturnType<typeof $$render<T, V>>['props'];
12
+ events(): ReturnType<typeof $$render<T, V>>['events'];
13
+ slots(): ReturnType<typeof $$render<T, V>>['slots'];
26
14
  bindings(): "";
27
15
  exports(): {};
28
16
  }
@@ -1,8 +1,15 @@
1
1
  import { type ExpandableProps } from './expandable-state.svelte.js';
2
+ declare function $$render<T>(): {
3
+ props: ExpandableProps<T>;
4
+ exports: {};
5
+ bindings: "";
6
+ slots: {};
7
+ events: {};
8
+ };
2
9
  declare class __sveltets_Render<T> {
3
- props(): ExpandableProps<T>;
4
- events(): {};
5
- slots(): {};
10
+ props(): ReturnType<typeof $$render<T>>['props'];
11
+ events(): ReturnType<typeof $$render<T>>['events'];
12
+ slots(): ReturnType<typeof $$render<T>>['slots'];
6
13
  bindings(): "";
7
14
  exports(): {};
8
15
  }
@@ -1,8 +1,15 @@
1
1
  import { type PanelProps } from './panel-state.svelte.js';
2
+ declare function $$render<T>(): {
3
+ props: PanelProps<T>;
4
+ exports: {};
5
+ bindings: "";
6
+ slots: {};
7
+ events: {};
8
+ };
2
9
  declare class __sveltets_Render<T> {
3
- props(): PanelProps<T>;
4
- events(): {};
5
- slots(): {};
10
+ props(): ReturnType<typeof $$render<T>>['props'];
11
+ events(): ReturnType<typeof $$render<T>>['events'];
12
+ slots(): ReturnType<typeof $$render<T>>['slots'];
6
13
  bindings(): "";
7
14
  exports(): {};
8
15
  }
@@ -1,8 +1,15 @@
1
1
  import { type RowProps } from './row-state.svelte.js';
2
+ declare function $$render<T>(): {
3
+ props: RowProps<T>;
4
+ exports: {};
5
+ bindings: "";
6
+ slots: {};
7
+ events: {};
8
+ };
2
9
  declare class __sveltets_Render<T> {
3
- props(): RowProps<T>;
4
- events(): {};
5
- slots(): {};
10
+ props(): ReturnType<typeof $$render<T>>['props'];
11
+ events(): ReturnType<typeof $$render<T>>['events'];
12
+ slots(): ReturnType<typeof $$render<T>>['slots'];
6
13
  bindings(): "";
7
14
  exports(): {};
8
15
  }
@@ -1,6 +1,6 @@
1
1
  import { type RowCtx } from '../table/table-state.svelte.js';
2
2
  import type { Snippet } from 'svelte';
3
- type ContextOptions<T> = {
3
+ type ContextOptions<_T> = {
4
4
  /**
5
5
  * Only show the context *content* when hovering the row?
6
6
  *
@@ -21,8 +21,12 @@ type ContextOptions<T> = {
21
21
  * @default false
22
22
  */
23
23
  alignHeaderToRows?: boolean;
24
+ /** Class name for the context column element */
25
+ class?: string;
24
26
  };
25
27
  export interface RowProps<T> {
28
+ /** Class name for the row element */
29
+ class?: string;
26
30
  /**
27
31
  * A sticky context column on the right of each table
28
32
  */
@@ -43,7 +47,9 @@ export declare class RowState<T> {
43
47
  oncontextmenu: ((event: MouseEvent, ctx: RowCtx<T>) => void) | undefined;
44
48
  };
45
49
  options: {
50
+ class: string | undefined;
46
51
  context: {
52
+ class: string | undefined;
47
53
  hover: boolean;
48
54
  width: string;
49
55
  alignHeaderToRows: boolean;
@@ -11,7 +11,9 @@ export class RowState {
11
11
  oncontextmenu: this.#props.oncontextmenu
12
12
  });
13
13
  options = $derived({
14
+ class: this.#props.class,
14
15
  context: {
16
+ class: this.#props.contextOptions?.class,
15
17
  hover: this.#props.contextOptions?.hover ?? true,
16
18
  width: this.#props.contextOptions?.width ?? 'max-content',
17
19
  alignHeaderToRows: this.#props.contextOptions?.alignHeaderToRows ?? false
@@ -17,24 +17,54 @@
17
17
  type RowSelectCtx,
18
18
  type TableProps
19
19
  } from './table-state.svelte.js'
20
- import Column from '../column/Column.svelte'
21
- import Panel from '../panel/Panel.svelte'
22
- import Expandable from '../expandable/Expandable.svelte'
23
- import Row from '../row/Row.svelte'
20
+ import type { ColumnProps } from '../column/column-state.svelte.js'
21
+ import type { PanelProps } from '../panel/panel-state.svelte.js'
22
+ import type { ExpandableProps } from '../expandable/expandable-state.svelte.js'
23
+ import type { RowProps } from '../row/row-state.svelte.js'
24
+
25
+ /**
26
+ * Column component type with proper generic inference.
27
+ * T is fixed to the table's Item type, V is inferred from the value prop.
28
+ */
29
+ type ColumnComponentType<T> = {
30
+ <V>(internal: unknown, props: ColumnProps<T, V>): void
31
+ new <V>(options: import('svelte').ComponentConstructorOptions<ColumnProps<T, V>>): import('svelte').SvelteComponent<ColumnProps<T, V>>
32
+ }
33
+
34
+ /**
35
+ * Panel component type.
36
+ */
37
+ type PanelComponentType<T> = {
38
+ (internal: unknown, props: PanelProps<T>): void
39
+ new (options: import('svelte').ComponentConstructorOptions<PanelProps<T>>): import('svelte').SvelteComponent<PanelProps<T>>
40
+ }
24
41
 
25
- type ConstructorReturnType<C extends new (...args: any[]) => any> =
26
- C extends new (...args: any[]) => infer K ? K : never
27
- type ConstructorParams<C extends new (...args: any[]) => any> =
28
- C extends new (...args: infer K) => any ? K : never
42
+ /**
43
+ * Expandable component type.
44
+ */
45
+ type ExpandableComponentType<T> = {
46
+ (internal: unknown, props: ExpandableProps<T>): void
47
+ new (options: import('svelte').ComponentConstructorOptions<ExpandableProps<T>>): import('svelte').SvelteComponent<ExpandableProps<T>>
48
+ }
49
+
50
+ /**
51
+ * Row component type.
52
+ */
53
+ type RowComponentType<T> = {
54
+ (internal: unknown, props: RowProps<T>): void
55
+ new (options: import('svelte').ComponentConstructorOptions<RowProps<T>>): import('svelte').SvelteComponent<RowProps<T>>
56
+ }
29
57
 
30
58
  export type ContentCtx<Item = any> = {
31
- Column: {
32
- new <V>(...args: ConstructorParams<typeof Column<Item, V>>): ConstructorReturnType<typeof Column<Item, V>>
33
- <V>(...args: Parameters<typeof Column<Item, V>>): ReturnType<typeof Column<Item, V>>
34
- }
35
- Panel: typeof Panel<Item>
36
- Expandable: typeof Expandable<Item>
37
- Row: typeof Row<Item>
59
+ /** Column component - use to define table columns */
60
+ readonly Column: ColumnComponentType<Item>
61
+ /** Panel component - use to define side panels */
62
+ readonly Panel: PanelComponentType<Item>
63
+ /** Expandable component - use to define expandable row content */
64
+ readonly Expandable: ExpandableComponentType<Item>
65
+ /** Row component - use to configure row behavior and context menus */
66
+ readonly Row: RowComponentType<Item>
67
+ /** The table state instance */
38
68
  readonly table: TableState<Item>
39
69
  }
40
70
 
@@ -52,6 +82,10 @@
52
82
  import { SizeTween } from '../size-tween.svelte.js'
53
83
  import { on } from 'svelte/events'
54
84
  import type { CSVOptions } from './csv.js'
85
+ import Column from '../column/Column.svelte'
86
+ import Panel from '../panel/Panel.svelte'
87
+ import Expandable from '../expandable/Expandable.svelte'
88
+ import Row from '../row/Row.svelte'
55
89
 
56
90
  type T = $$Generic
57
91
 
@@ -61,6 +95,7 @@
61
95
  panel: _panel = $bindable(),
62
96
  data: _data = $bindable([]),
63
97
  table: _table = $bindable(),
98
+ class: className,
64
99
  ...restProps
65
100
  }: TableProps<T> & { content?: ContentSnippet<T> } = $props()
66
101
 
@@ -235,9 +270,9 @@
235
270
  `
236
271
 
237
272
  const tbodyTemplateColumns = `
238
- [data-area-class='${table.cssId}'] tr.row,
239
- [data-area-class='${table.cssId}'] tr.expandable,
240
- [data-area-class='${table.cssId}'] tr.filler,
273
+ [data-area-class='${table.cssId}'] tr.tably-row,
274
+ [data-area-class='${table.cssId}'] tr.tably-expandable,
275
+ [data-area-class='${table.cssId}'] tr.tably-filler,
241
276
  [data-svelte-tably="${table.cssId}"] > tbody::after {
242
277
  grid-template-columns: ${templateColumns};
243
278
  }
@@ -248,8 +283,8 @@
248
283
  .map((column, i, arr) => {
249
284
  sum += getWidth(arr[i - 1]?.id, i === 0 ? 0 : undefined)
250
285
  return `
251
- [data-svelte-tably="${table.cssId}"] .column.sticky[data-column='${column.id}'],
252
- [data-svelte-tably-row='${table.cssId}'] .column.sticky[data-column='${column.id}'] {
286
+ [data-svelte-tably="${table.cssId}"] .tably-column.tably-sticky[data-column='${column.id}'],
287
+ [data-svelte-tably-row='${table.cssId}'] .tably-column.tably-sticky[data-column='${column.id}'] {
253
288
  left: ${sum}px;
254
289
  }
255
290
  `
@@ -261,7 +296,7 @@
261
296
  !column.options.style ?
262
297
  ''
263
298
  : `
264
- [data-area-class='${table.cssId}'] .column[data-column='${column.id}'] {
299
+ [data-area-class='${table.cssId}'] .tably-column[data-column='${column.id}'] {
265
300
  ${column.options.style}
266
301
  }
267
302
  `
@@ -542,18 +577,18 @@
542
577
  <svelte:element
543
578
  this={isHeader ? 'th' : 'td'}
544
579
  class={column.options.class ?? ''}
545
- class:column={true}
546
- class:sticky={true}
547
- class:fixed={true}
580
+ class:tably-column={true}
581
+ class:tably-sticky={true}
582
+ class:tably-fixed={true}
548
583
  use:addRowColumnEvents={[where, column, () => args[1]]}
549
584
  data-column={column.id}
550
- class:pad={
585
+ class:tably-pad={
551
586
  (where === 'header' && column.options.padHeader) ||
552
587
  (where === 'row' && column.options.padRow) ||
553
588
  (where === 'statusbar' && column.options.padStatusbar)
554
589
  }
555
- class:header={isHeader}
556
- class:sortable
590
+ class:tably-header={isHeader}
591
+ class:tably-sortable={sortable}
557
592
  use:conditional={[isHeader, (node) => table.dataState.sortAction(node, column.id)]}
558
593
  onpointerenter={() => (hoveredColumn = column)}
559
594
  onpointerleave={() => (hoveredColumn = null)}
@@ -574,20 +609,20 @@
574
609
  <svelte:element
575
610
  this={isHeader ? 'th' : 'td'}
576
611
  class={column.options.class ?? ''}
577
- class:column={true}
578
- class:sticky={true}
612
+ class:tably-column={true}
613
+ class:tably-sticky={true}
579
614
  use:addRowColumnEvents={[where, column, () => args[1]]}
580
615
  use:observeColumnWidth={isHeader}
581
616
  data-column={column.id}
582
- class:pad={
617
+ class:tably-pad={
583
618
  (where === 'header' && column.options.padHeader) ||
584
619
  (where === 'row' && column.options.padRow) ||
585
620
  (where === 'statusbar' && column.options.padStatusbar)
586
621
  }
587
- class:header={isHeader}
588
- class:resizeable={isHeader && column.options.resizeable && table.options.resizeable}
589
- class:border={i == sticky.length - 1}
590
- class:sortable
622
+ class:tably-header={isHeader}
623
+ class:tably-resizeable={isHeader && column.options.resizeable && table.options.resizeable}
624
+ class:tably-border={i == sticky.length - 1}
625
+ class:tably-sortable={sortable}
591
626
  use:conditional={[isHeader, (node) => table.dataState.sortAction(node, column.id)]}
592
627
  onpointerenter={() => (hoveredColumn = column)}
593
628
  onpointerleave={() => (hoveredColumn = null)}
@@ -608,17 +643,17 @@
608
643
  <svelte:element
609
644
  this={isHeader ? 'th' : 'td'}
610
645
  class={column.options.class ?? ''}
611
- class:column={true}
646
+ class:tably-column={true}
612
647
  data-column={column.id}
613
- class:pad={
648
+ class:tably-pad={
614
649
  (where === 'header' && column.options.padHeader) ||
615
650
  (where === 'row' && column.options.padRow) ||
616
651
  (where === 'statusbar' && column.options.padStatusbar)
617
652
  }
618
653
  use:addRowColumnEvents={[where, column, () => args[1]]}
619
654
  use:observeColumnWidth={isHeader}
620
- class:resizeable={isHeader && column.options.resizeable && table.options.resizeable}
621
- class:sortable
655
+ class:tably-resizeable={isHeader && column.options.resizeable && table.options.resizeable}
656
+ class:tably-sortable={sortable}
622
657
  use:conditional={[isHeader, (node) => table.dataState.sortAction(node, column.id)]}
623
658
  onpointerenter={() => (hoveredColumn = column)}
624
659
  onpointerleave={() => (hoveredColumn = null)}
@@ -677,11 +712,11 @@
677
712
  <tr
678
713
  aria-rowindex={index + 1}
679
714
  style:opacity={itemState?.positioning ? 0 : 1}
680
- class="row"
681
- class:dragging={itemState?.dragging}
682
- class:selected={table.selected?.includes(item)}
683
- class:first={index === 0}
684
- class:last={index === virtualization.area.length - 1}
715
+ class="tably-row {table.row?.options.class ?? ''}"
716
+ class:tably-dragging={itemState?.dragging}
717
+ class:tably-selected={table.selected?.includes(item)}
718
+ class:tably-first={index === 0}
719
+ class:tably-last={index === virtualization.area.length - 1}
685
720
  {...itemState?.dragging ? { 'data-svelte-tably-row': table.cssId } : {}}
686
721
  onpointerenter={() => (hoveredRow = item)}
687
722
  onpointerleave={() => (hoveredRow = null)}
@@ -716,8 +751,8 @@
716
751
  )}
717
752
  {#if table.row?.snippets.context}
718
753
  <td
719
- class="context-col"
720
- class:hidden={table.row?.options.context.hover && hoveredRow !== item}
754
+ class="context-col {table.row?.options.context.class ?? ''}"
755
+ class:tably-hidden={table.row?.options.context.hover && hoveredRow !== item}
721
756
  data-tably-context-measure={
722
757
  table.row?.options.context.alignHeaderToRows &&
723
758
  index === virtualization.topIndex ?
@@ -741,26 +776,26 @@
741
776
  {#if table.expandable && (expanded || expandableTween.current > 0 || expandableTween.transitioning)}
742
777
  {@const expandId = getExpandId(item)}
743
778
  {@const expandLabelId = `${expandId}-label`}
744
- <tr class="expandable">
779
+ <tr class="tably-expandable">
745
780
  <td
746
- class="expandable-cell"
781
+ class="tably-expandable-cell"
747
782
  colspan={columns.length + (table.row?.snippets.context ? 1 : 0)}
748
783
  style="padding: 0"
749
784
  >
750
- <div class="expandable-sticky">
785
+ <div class="tably-expandable-sticky">
751
786
  <div
752
- class="expandable-clip"
787
+ class="tably-expandable-clip"
753
788
  style="height: {Math.round(expandableTween.current)}px"
754
789
  id={expandId}
755
790
  role="region"
756
791
  aria-labelledby={expandLabelId}
757
792
  aria-hidden={!expanded}
758
793
  >
759
- <span class="sr-only" id={expandLabelId}>
794
+ <span class="tably-sr-only" id={expandLabelId}>
760
795
  Expanded content for {getRowLabel(item, index)}
761
796
  </span>
762
797
  <div
763
- class="expandable-content"
798
+ class="tably-expandable-content"
764
799
  bind:offsetHeight={expandableTween.size}
765
800
  >
766
801
  {@render table.expandable?.snippets.content?.(item, ctx)}
@@ -775,12 +810,12 @@
775
810
  <table
776
811
  id={table.id}
777
812
  data-svelte-tably={table.cssId}
778
- class="table svelte-tably"
813
+ class="tably-table svelte-tably {className ?? ''}"
779
814
  style="--t: {virtualization.virtualTop}px; --b: {virtualization.virtualBottom}px; --scrollbar: {tbody.scrollbar}px; --viewport-width: {tbody.viewportWidth}px; --tably-context-width: {table.row?.options.context.alignHeaderToRows && contextWidth > 0 ? `${contextWidth}px` : (table.row?.options.context.width ?? 'max-content')};"
780
815
  aria-rowcount={table.data.length}
781
816
  >
782
817
  {#if columns.some((v) => v.snippets.header)}
783
- <thead class="headers" bind:this={elements.headers}>
818
+ <thead class="tably-headers" bind:this={elements.headers}>
784
819
  <tr>
785
820
  {@render columnsSnippet(
786
821
  (column) => column.snippets.header,
@@ -798,7 +833,7 @@
798
833
  )}
799
834
  {#if table.row?.snippets.context}
800
835
  <th
801
- class="context-col"
836
+ class="context-col {table.row?.options.context.class ?? ''}"
802
837
  data-tably-context-measure={table.row?.options.context.alignHeaderToRows ? 'header' : undefined}
803
838
  aria-hidden={table.row?.snippets.contextHeader ? undefined : true}
804
839
  role={table.row?.snippets.contextHeader ? undefined : 'presentation'}
@@ -815,7 +850,7 @@
815
850
  {/if}
816
851
 
817
852
  <tbody
818
- class="content"
853
+ class="tably-content"
819
854
  use:reorderArea={{ axis: 'y', class: table.cssId }}
820
855
  use:observeScrollbar
821
856
  bind:this={virtualization.viewport.element}
@@ -841,11 +876,11 @@
841
876
  {/if}
842
877
 
843
878
  {#if columns.length > 0 && virtualization.virtualTop === 0 && virtualization.virtualBottom === 0}
844
- <tr class="filler" aria-hidden="true">
879
+ <tr class="tably-filler" aria-hidden="true">
845
880
  {#each fixed as column (column)}
846
881
  {#if !hidden.includes(column)}
847
882
  <td
848
- class={`column sticky fixed ${column.options.class ?? ''}`}
883
+ class={`tably-column tably-sticky tably-fixed ${column.options.class ?? ''}`}
849
884
  data-column={column.id}
850
885
  ></td>
851
886
  {/if}
@@ -853,8 +888,8 @@
853
888
  {#each sticky as column, i (column)}
854
889
  {#if !hidden.includes(column)}
855
890
  <td
856
- class={`column sticky ${column.options.class ?? ''}`}
857
- class:border={i == sticky.length - 1}
891
+ class={`tably-column tably-sticky ${column.options.class ?? ''}`}
892
+ class:tably-border={i == sticky.length - 1}
858
893
  data-column={column.id}
859
894
  ></td>
860
895
  {/if}
@@ -862,7 +897,7 @@
862
897
  {#each scrolled as column (column)}
863
898
  {#if !hidden.includes(column)}
864
899
  <td
865
- class={`column ${column.options.class ?? ''}`}
900
+ class={`tably-column ${column.options.class ?? ''}`}
866
901
  data-column={column.id}
867
902
  ></td>
868
903
  {/if}
@@ -875,7 +910,7 @@
875
910
  </tbody>
876
911
 
877
912
  {#if columns.some((v) => v.snippets.statusbar)}
878
- <tfoot class="statusbar" bind:this={elements.statusbar}>
913
+ <tfoot class="tably-statusbar" bind:this={elements.statusbar}>
879
914
  <tr>
880
915
  {@render columnsSnippet(
881
916
  (column) => column.snippets.statusbar,
@@ -895,10 +930,10 @@
895
930
  </tfoot>
896
931
  {/if}
897
932
 
898
- <caption class="panel" style="width: {panelTween.current}px;">
933
+ <caption class="tably-panel" style="width: {panelTween.current}px;">
899
934
  {#if properties.panel && properties.panel in table.panels}
900
935
  <div
901
- class="panel-content"
936
+ class="tably-panel-content"
902
937
  bind:offsetWidth={panelTween.size}
903
938
  in:fly={{ x: 100, easing: sineInOut, duration: 300 }}
904
939
  out:fly={{ x: 100, duration: 200, easing: sineInOut }}
@@ -915,7 +950,7 @@
915
950
  {/if}
916
951
  </caption>
917
952
  <caption
918
- class="backdrop"
953
+ class="tably-backdrop"
919
954
  aria-hidden={properties.panel && table.panels[properties.panel]?.backdrop ? false : true}
920
955
  >
921
956
  <button
@@ -1080,7 +1115,7 @@
1080
1115
  z-index: 3;
1081
1116
  padding: 0;
1082
1117
  border-left: 1px solid var(--tably-border);
1083
- &.hidden {
1118
+ &.tably-hidden {
1084
1119
  pointer-events: none;
1085
1120
  user-select: none;
1086
1121
  border-left: none;
@@ -1099,7 +1134,7 @@
1099
1134
  width: 100%;
1100
1135
  }
1101
1136
 
1102
- .table::before {
1137
+ .tably-table::before {
1103
1138
  content: '';
1104
1139
  grid-area: headers;
1105
1140
  justify-self: end;
@@ -1114,7 +1149,7 @@
1114
1149
  z-index: 4;
1115
1150
  }
1116
1151
 
1117
- .table::after {
1152
+ .tably-table::after {
1118
1153
  content: '';
1119
1154
  grid-area: statusbar;
1120
1155
  justify-self: end;
@@ -1149,21 +1184,21 @@
1149
1184
  border-spacing: 0;
1150
1185
  }
1151
1186
 
1152
- .expandable {
1187
+ .tably-expandable {
1153
1188
  & > td {
1154
1189
  padding: 0;
1155
1190
  border: none;
1156
1191
  }
1157
1192
  }
1158
1193
 
1159
- .expandable-cell {
1194
+ .tably-expandable-cell {
1160
1195
  grid-column: 1 / -1;
1161
1196
  display: block;
1162
1197
  min-width: 0;
1163
1198
  width: 100%;
1164
1199
  }
1165
1200
 
1166
- .expandable-sticky {
1201
+ .tably-expandable-sticky {
1167
1202
  position: sticky;
1168
1203
  left: 0;
1169
1204
  width: var(--viewport-width, 100%);
@@ -1173,14 +1208,14 @@
1173
1208
  z-index: 1;
1174
1209
  }
1175
1210
 
1176
- .expandable-clip {
1211
+ .tably-expandable-clip {
1177
1212
  overflow: hidden;
1178
1213
  width: 100%;
1179
1214
  background-color: var(--tably-bg);
1180
1215
  border-bottom: 1px solid var(--tably-border-grid);
1181
1216
  }
1182
1217
 
1183
- .expandable-content {
1218
+ .tably-expandable-content {
1184
1219
  overflow: auto;
1185
1220
  width: 100%;
1186
1221
  background-color: var(--tably-bg);
@@ -1272,12 +1307,12 @@
1272
1307
  height: var(--b);
1273
1308
  }
1274
1309
 
1275
- .row:global(:is(a)) {
1310
+ .tably-row:global(:is(a)) {
1276
1311
  color: inherit;
1277
1312
  text-decoration: inherit;
1278
1313
  }
1279
1314
 
1280
- .backdrop {
1315
+ .tably-backdrop {
1281
1316
  position: absolute;
1282
1317
  left: 0px;
1283
1318
  top: 0px;
@@ -1305,17 +1340,17 @@
1305
1340
  }
1306
1341
  }
1307
1342
 
1308
- .sticky {
1343
+ .tably-sticky {
1309
1344
  position: sticky;
1310
1345
  /* right: 100px; */
1311
1346
  z-index: 1;
1312
1347
  }
1313
1348
 
1314
- .sticky.border {
1349
+ .tably-sticky.tably-border {
1315
1350
  border-right: 1px solid var(--tably-border);
1316
1351
  }
1317
1352
 
1318
- .headers > tr > .column {
1353
+ .tably-headers > tr > .tably-column {
1319
1354
  overflow: hidden;
1320
1355
  padding: var(--tably-padding-y) 0;
1321
1356
  cursor: default;
@@ -1325,16 +1360,16 @@
1325
1360
  border-right: none;
1326
1361
  }
1327
1362
 
1328
- &.sortable {
1363
+ &.tably-sortable {
1329
1364
  cursor: pointer;
1330
1365
  }
1331
1366
 
1332
- &.resizeable {
1367
+ &.tably-resizeable {
1333
1368
  resize: horizontal;
1334
1369
  }
1335
1370
  }
1336
1371
 
1337
- .table {
1372
+ .tably-table {
1338
1373
  display: grid;
1339
1374
  width: 100%;
1340
1375
  min-width: 0;
@@ -1358,7 +1393,7 @@
1358
1393
  border-radius: var(--tably-radius);
1359
1394
  }
1360
1395
 
1361
- .headers {
1396
+ .tably-headers {
1362
1397
  display: flex;
1363
1398
  grid-area: headers;
1364
1399
  z-index: 2;
@@ -1368,19 +1403,19 @@
1368
1403
  border-bottom: 1px solid var(--tably-border);
1369
1404
  }
1370
1405
 
1371
- .headers > tr > .column {
1406
+ .tably-headers > tr > .tably-column {
1372
1407
  width: auto !important;
1373
1408
  }
1374
- .headers > tr > .column:not(:first-child) {
1409
+ .tably-headers > tr > .tably-column:not(:first-child) {
1375
1410
  border-left: 1px solid var(--tably-border-grid);
1376
1411
  }
1377
1412
 
1378
- .headers > tr > .context-col {
1413
+ .tably-headers > tr > .context-col {
1379
1414
  border-left: 1px solid var(--tably-border);
1380
1415
  background-color: var(--tably-bg);
1381
1416
  }
1382
1417
 
1383
- .content {
1418
+ .tably-content {
1384
1419
  display: flex;
1385
1420
  flex-direction: column;
1386
1421
  min-width: 0;
@@ -1392,17 +1427,17 @@
1392
1427
  overflow-y: scroll;
1393
1428
  }
1394
1429
 
1395
- .content > tr.row,
1396
- .content > tr.expandable {
1430
+ .tably-content > tr.tably-row,
1431
+ .tably-content > tr.tably-expandable {
1397
1432
  flex: 0 0 auto;
1398
1433
  }
1399
1434
 
1400
- .content > tr.filler {
1435
+ .tably-content > tr.tably-filler {
1401
1436
  flex: 1 0 0px;
1402
1437
  min-height: 0;
1403
1438
  }
1404
1439
 
1405
- .statusbar {
1440
+ .tably-statusbar {
1406
1441
  display: flex;
1407
1442
  grid-area: statusbar;
1408
1443
  overflow: hidden;
@@ -1411,34 +1446,34 @@
1411
1446
  padding-right: var(--scrollbar, 0px);
1412
1447
  }
1413
1448
 
1414
- .statusbar > tr > .column {
1449
+ .tably-statusbar > tr > .tably-column {
1415
1450
  border-top: 1px solid var(--tably-border);
1416
1451
  padding: calc(var(--tably-padding-y) / 2) 0;
1417
1452
  }
1418
- .statusbar > tr > .context-col {
1453
+ .tably-statusbar > tr > .context-col {
1419
1454
  border-top: 1px solid var(--tably-border);
1420
1455
  border-left: 1px solid var(--tably-border);
1421
1456
  }
1422
1457
 
1423
- .statusbar > tr > .context-col {
1458
+ .tably-statusbar > tr > .context-col {
1424
1459
  background-color: var(--tably-statusbar);
1425
1460
  }
1426
1461
 
1427
- .headers > tr,
1428
- .row,
1429
- .expandable,
1430
- .filler,
1431
- .statusbar > tr {
1462
+ .tably-headers > tr,
1463
+ .tably-row,
1464
+ .tably-expandable,
1465
+ .tably-filler,
1466
+ .tably-statusbar > tr {
1432
1467
  display: grid;
1433
1468
  width: 100%;
1434
1469
  min-width: max-content;
1435
1470
 
1436
- & > .column {
1471
+ & > .tably-column {
1437
1472
  display: flex;
1438
1473
  overflow: hidden;
1439
1474
 
1440
- &:not(.pad),
1441
- &.pad > :global(*:first-child) {
1475
+ &:not(.tably-pad),
1476
+ &.tably-pad > :global(*:first-child) {
1442
1477
  padding-left: var(--tably-padding-x);
1443
1478
  }
1444
1479
  }
@@ -1446,54 +1481,54 @@
1446
1481
  & > *:last-child:not(.context-col) {
1447
1482
  width: 100%;
1448
1483
 
1449
- &:not(.pad),
1450
- &.pad > :global(*:first-child) {
1484
+ &:not(.tably-pad),
1485
+ &.tably-pad > :global(*:first-child) {
1451
1486
  padding-right: var(--tably-padding-x);
1452
1487
  }
1453
1488
  }
1454
1489
  }
1455
1490
 
1456
- .row > .column {
1491
+ .tably-row > .tably-column {
1457
1492
  background-color: var(--tably-bg);
1458
- &:not(.pad),
1459
- &.pad > :global(*:first-child) {
1493
+ &:not(.tably-pad),
1494
+ &.tably-pad > :global(*:first-child) {
1460
1495
  padding-top: var(--tably-padding-y);
1461
1496
  padding-bottom: var(--tably-padding-y);
1462
1497
  }
1463
1498
  }
1464
1499
 
1465
- .row > .context-col {
1500
+ .tably-row > .context-col {
1466
1501
  background-color: var(--tably-bg);
1467
1502
  }
1468
1503
 
1469
- .row > .context-col.hidden {
1504
+ .tably-row > .context-col.tably-hidden {
1470
1505
  background-color: transparent;
1471
1506
  }
1472
1507
 
1473
- :global(#runic-drag .row) {
1508
+ :global(#runic-drag .tably-row) {
1474
1509
  border: 1px solid var(--tably-border-grid);
1475
1510
  border-top: 2px solid var(--tably-border-grid);
1476
1511
  }
1477
1512
 
1478
- .headers > tr > .column:not(:first-child),
1479
- .row > .column:not(:first-child),
1480
- .filler > .column:not(:first-child),
1481
- .statusbar > tr > .column:not(:first-child) {
1513
+ .tably-headers > tr > .tably-column:not(:first-child),
1514
+ .tably-row > .tably-column:not(:first-child),
1515
+ .tably-filler > .tably-column:not(:first-child),
1516
+ .tably-statusbar > tr > .tably-column:not(:first-child) {
1482
1517
  border-left: 1px solid var(--tably-border-grid);
1483
1518
  }
1484
1519
 
1485
- .row,
1486
- .filler {
1520
+ .tably-row,
1521
+ .tably-filler {
1487
1522
  border-bottom: 1px solid var(--tably-border-grid);
1488
1523
  }
1489
1524
 
1490
- .filler {
1525
+ .tably-filler {
1491
1526
  pointer-events: none;
1492
1527
  user-select: none;
1493
1528
  background: none;
1494
1529
  }
1495
1530
 
1496
- .sr-only {
1531
+ .tably-sr-only {
1497
1532
  position: absolute;
1498
1533
  width: 1px;
1499
1534
  height: 1px;
@@ -1505,7 +1540,7 @@
1505
1540
  border: 0;
1506
1541
  }
1507
1542
 
1508
- .panel {
1543
+ .tably-panel {
1509
1544
  position: relative;
1510
1545
  grid-area: panel;
1511
1546
  height: 100%;
@@ -1514,7 +1549,7 @@
1514
1549
 
1515
1550
  z-index: 4;
1516
1551
 
1517
- > .panel-content {
1552
+ > .tably-panel-content {
1518
1553
  position: absolute;
1519
1554
  top: 0;
1520
1555
  right: 0;
@@ -1,29 +1,67 @@
1
1
  import type { Snippet } from 'svelte';
2
2
  import { TableState, type TableProps } from './table-state.svelte.js';
3
- import Column from '../column/Column.svelte';
4
- import Panel from '../panel/Panel.svelte';
5
- import Expandable from '../expandable/Expandable.svelte';
6
- import Row from '../row/Row.svelte';
7
- type ConstructorReturnType<C extends new (...args: any[]) => any> = C extends new (...args: any[]) => infer K ? K : never;
8
- type ConstructorParams<C extends new (...args: any[]) => any> = C extends new (...args: infer K) => any ? K : never;
3
+ import type { ColumnProps } from '../column/column-state.svelte.js';
4
+ import type { PanelProps } from '../panel/panel-state.svelte.js';
5
+ import type { ExpandableProps } from '../expandable/expandable-state.svelte.js';
6
+ import type { RowProps } from '../row/row-state.svelte.js';
7
+ /**
8
+ * Column component type with proper generic inference.
9
+ * T is fixed to the table's Item type, V is inferred from the value prop.
10
+ */
11
+ type ColumnComponentType<T> = {
12
+ <V>(internal: unknown, props: ColumnProps<T, V>): void;
13
+ new <V>(options: import('svelte').ComponentConstructorOptions<ColumnProps<T, V>>): import('svelte').SvelteComponent<ColumnProps<T, V>>;
14
+ };
15
+ /**
16
+ * Panel component type.
17
+ */
18
+ type PanelComponentType<T> = {
19
+ (internal: unknown, props: PanelProps<T>): void;
20
+ new (options: import('svelte').ComponentConstructorOptions<PanelProps<T>>): import('svelte').SvelteComponent<PanelProps<T>>;
21
+ };
22
+ /**
23
+ * Expandable component type.
24
+ */
25
+ type ExpandableComponentType<T> = {
26
+ (internal: unknown, props: ExpandableProps<T>): void;
27
+ new (options: import('svelte').ComponentConstructorOptions<ExpandableProps<T>>): import('svelte').SvelteComponent<ExpandableProps<T>>;
28
+ };
29
+ /**
30
+ * Row component type.
31
+ */
32
+ type RowComponentType<T> = {
33
+ (internal: unknown, props: RowProps<T>): void;
34
+ new (options: import('svelte').ComponentConstructorOptions<RowProps<T>>): import('svelte').SvelteComponent<RowProps<T>>;
35
+ };
9
36
  export type ContentCtx<Item = any> = {
10
- Column: {
11
- new <V>(...args: ConstructorParams<typeof Column<Item, V>>): ConstructorReturnType<typeof Column<Item, V>>;
12
- <V>(...args: Parameters<typeof Column<Item, V>>): ReturnType<typeof Column<Item, V>>;
13
- };
14
- Panel: typeof Panel<Item>;
15
- Expandable: typeof Expandable<Item>;
16
- Row: typeof Row<Item>;
37
+ /** Column component - use to define table columns */
38
+ readonly Column: ColumnComponentType<Item>;
39
+ /** Panel component - use to define side panels */
40
+ readonly Panel: PanelComponentType<Item>;
41
+ /** Expandable component - use to define expandable row content */
42
+ readonly Expandable: ExpandableComponentType<Item>;
43
+ /** Row component - use to configure row behavior and context menus */
44
+ readonly Row: RowComponentType<Item>;
45
+ /** The table state instance */
17
46
  readonly table: TableState<Item>;
18
47
  };
19
48
  export type ContentSnippet<Item = any> = Snippet<[context: ContentCtx<Item>]>;
20
49
  import type { CSVOptions } from './csv.js';
21
- declare class __sveltets_Render<T> {
22
- props(): TableProps<T> & {
23
- content?: ContentSnippet<T> | undefined;
50
+ declare function $$render<T>(): {
51
+ props: TableProps<T> & {
52
+ content?: ContentSnippet<T>;
24
53
  };
25
- events(): {};
26
- slots(): {};
54
+ exports: {
55
+ toCSV: (options?: CSVOptions<T>) => Promise<string>;
56
+ };
57
+ bindings: "table" | "data" | "selected" | "panel";
58
+ slots: {};
59
+ events: {};
60
+ };
61
+ declare class __sveltets_Render<T> {
62
+ props(): ReturnType<typeof $$render<T>>['props'];
63
+ events(): ReturnType<typeof $$render<T>>['events'];
64
+ slots(): ReturnType<typeof $$render<T>>['slots'];
27
65
  bindings(): "table" | "data" | "selected" | "panel";
28
66
  exports(): {
29
67
  toCSV: (options?: CSVOptions<T>) => Promise<string>;
@@ -51,6 +51,8 @@ type SelectOptions<T extends any> = {
51
51
  };
52
52
  export type TableProps<T extends any> = {
53
53
  id?: string;
54
+ /** Class name for the table element */
55
+ class?: string;
54
56
  /** Bindable to TableState; `bind:table` */
55
57
  table?: TableState<T>;
56
58
  data: T[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelte-tably",
3
- "version": "1.3.0",
3
+ "version": "1.5.0",
4
4
  "description": "A high performant dynamic table for Svelte 5",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -11,13 +11,14 @@
11
11
  "url": "https://github.com/Refzlund/svelte-tably/issues"
12
12
  },
13
13
  "files": [
14
- "dist"
14
+ "dist",
15
+ "LICENSE",
16
+ "README.md"
15
17
  ],
16
18
  "type": "module",
17
19
  "exports": {
18
20
  ".": {
19
21
  "types": "./dist/index.d.ts",
20
- "default": "./dist/index.js",
21
22
  "svelte": "./dist/index.js"
22
23
  }
23
24
  },