@isoftdata/svelte-table 2.11.1 → 2.12.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.
@@ -53,7 +53,10 @@ declare class __sveltets_Render<R extends UuidRowProps> {
53
53
  }, []> : T : never : never, {
54
54
  strict: true;
55
55
  }>[] | undefined;
56
- rowSelectionIdProp?: "uuid" | RowProperties<R> | undefined;
56
+ rowSelectionIdProp?: RowProperties<R & {
57
+ originalIndex: number;
58
+ uuid: string;
59
+ }> | undefined;
57
60
  rowSelectionRequiresModKey?: boolean;
58
61
  selectionMode?: "SINGLE" | "RANGE" | null;
59
62
  multiSelectEnabled?: boolean;
@@ -74,7 +77,7 @@ declare class __sveltets_Render<R extends UuidRowProps> {
74
77
  totalItemsCount?: number;
75
78
  stickyHeader?: boolean;
76
79
  responsive?: boolean | "sm" | "md" | "lg" | "xl";
77
- size?: "sm" | "";
80
+ size?: "xs" | "sm" | "";
78
81
  striped?: boolean;
79
82
  /** When true, enables tree-specific features. Required if you want to use `TreeRow`s. */
80
83
  tree?: boolean;
@@ -145,34 +148,19 @@ declare class __sveltets_Render<R extends UuidRowProps> {
145
148
  columnInfo: ColumnInfoRunicStore<R>;
146
149
  defaultColumnClicked: (clickedColumn: GenericColumn<R & {}>, sortDirection: SortDirection) => Promise<void>;
147
150
  defaultRowMatchesFilter: (filter: string, row: R, props: RowProperties<R>[]) => boolean;
148
- getNestedProperty: {
149
- (row: R & {
150
- uuid: string;
151
- }, path: "uuid" | RowProperties<R>, defaultValue?: string | number): import("type-fest/source/get").GetWithPath<R & {
152
- originalIndex: number;
153
- uuid: string;
154
- }, RowProperties<R & {
155
- originalIndex: number;
156
- uuid: string;
157
- }> extends infer T ? T extends RowProperties<R & {
158
- originalIndex: number;
159
- uuid: string;
160
- }> ? T extends string ? import("type-fest/source/split").SplitHelper<import("type-fest/source/get").FixPathSquareBrackets<T>, ".", {
161
- strictLiteralChecks: false;
162
- }, []> : T : never : never, {
163
- strict: true;
164
- }>;
165
- (row: R, path: RowProperties<R>, defaultValue?: string | number): import("type-fest/source/get").GetWithPath<R, RowProperties<R> extends infer T ? T extends RowProperties<R> ? T extends string ? import("type-fest/source/split").SplitHelper<import("type-fest/source/get").FixPathSquareBrackets<T>, ".", {
166
- strictLiteralChecks: false;
167
- }, []> : T : never : never, {
168
- strict: true;
169
- }>;
170
- };
151
+ getNestedProperty: <Row extends R, K extends RowProperties<Row>>(row: Row, path: K, defaultValue?: string | number) => import("type-fest/source/get").GetWithPath<Row, K extends string ? import("type-fest/source/split").SplitHelper<import("type-fest/source/get").FixPathSquareBrackets<K>, ".", {
152
+ strictLiteralChecks: false;
153
+ }, []> : K, {
154
+ strict: true;
155
+ }>;
171
156
  expandRow: (rowId: string | number, expanded?: boolean) => void;
172
157
  rowIsSelected: (row: R & {
173
158
  originalIndex: number;
174
159
  uuid: string;
175
- }, rowSelectionIdProp: "uuid" | RowProperties<R>, selectedRowIds: import("type-fest/source/get").GetWithPath<R & {
160
+ }, rowSelectionIdProp: RowProperties<R & {
161
+ originalIndex: number;
162
+ uuid: string;
163
+ }>, selectedRowIds: import("type-fest/source/get").GetWithPath<R & {
176
164
  originalIndex: number;
177
165
  uuid: string;
178
166
  }, RowProperties<R & {
package/dist/Td.svelte CHANGED
@@ -1,171 +1,172 @@
1
- <script
2
- lang="ts"
3
- generics="R extends UuidRowProps = any"
4
- >
5
- import type { ColumnInfo, RowProperties, UuidRowProps } from './'
6
- import type { ColumnInfoRunicStore } from './column-info-store.svelte'
7
- import type { HTMLTdAttributes, ClassValue } from 'svelte/elements'
8
- import type { Writable } from 'svelte/store'
9
- import { getContext, onMount, type Snippet } from 'svelte'
10
-
11
- // Get the columnInfo store from the Table component
12
- const columnInfo = getContext<ColumnInfoRunicStore<UuidRowProps>>('columnInfo')
13
- const columnResizingEnabled = getContext<Writable<boolean>>('columnResizingEnabled')
14
- const bs5 = getContext<boolean>('bs5')
15
-
16
- interface Props extends Omit<HTMLTdAttributes, 'align'> {
17
- class?: ClassValue
18
- property: ColumnInfo<R>['property']
19
- /** Direction to align the column's contents
20
- *
21
- * `start` and `end` are only available in Bootstrap 5+
22
- *
23
- * `left` and `right`should only be used while you transition to Boostrap 5+
24
- */
25
- align?: 'start' | 'left' | 'center' | 'right' | 'end'
26
- /** If enabled, pressing enter while focused in this Td will focus the next non-disabled input/select/textarea in the column. Holding shift will go up instead of down.
27
- *
28
- * Can also be a callback that is fired when the enter key is used to move between rows.
29
- */
30
- enterGoesDown?: boolean | ((ctx: { event: KeyboardEvent; tr: HTMLTableRowElement }) => void)
31
- /** If enabled, keypress (enter only) and click events on the Td's contents will have `stopPropagation`/`preventDefault` called on them. */
32
- stopPropagation?: boolean
33
- tagName?: 'td' | 'th'
34
- children?: Snippet
35
- }
36
-
37
- let {
38
- //
39
- class: classNames = '',
40
- property,
41
- align = $bindable(columnInfo.current[property]?.align),
42
- enterGoesDown = false,
43
- stopPropagation = false,
44
- tagName = 'td',
45
- children,
46
- ...rest
47
- }: Props = $props()
48
-
49
- const thisColumnInfo = $derived(
50
- columnInfo.current[property] as (typeof columnInfo.current)[typeof property] | undefined,
51
- )
52
- const alignClass = $derived.by(() => {
53
- let alignment = align || thisColumnInfo?.align || (thisColumnInfo?.numeric ? 'right' : undefined)
54
- if (bs5 && alignment === 'right') {
55
- alignment = 'end'
56
- } else if (bs5 && alignment === 'left') {
57
- alignment = 'start'
58
- }
59
- return alignment ? (`text-${alignment}` as const) : ''
60
- })
61
- const visible = $derived(thisColumnInfo?.visible ?? true)
62
-
63
- /** Handle `stopPropagation` and `enterGoesDown` props */
64
- function onkeypress(event: KeyboardEvent) {
65
- if (event.key === 'Enter') {
66
- event.stopPropagation()
67
- event.preventDefault()
68
- }
69
-
70
- if (event.key === 'Enter' && enterGoesDown) {
71
- const target = event.target
72
- if (!(target instanceof HTMLElement)) {
73
- return
74
- }
75
- const tr = target?.closest('tr') ?? null
76
- const td = target?.closest('td') ?? null
77
- const tdIndex = td ? Array.from(tr?.children ?? []).indexOf(td) : -1
78
- const allTrs = Array.from(tr?.parentElement?.children ?? [])
79
-
80
- // if they're holding shift, reverse the tr list
81
- if (event.shiftKey) {
82
- allTrs.reverse()
83
- }
84
- // Find the next Td in the column with a non-disabled input, select, or textarea
85
- const lastTrIndex = tr ? allTrs.indexOf(tr) : -1
86
- const newTrIndex = allTrs.findIndex(
87
- (tr, index) =>
88
- index > lastTrIndex &&
89
- tr.children[tdIndex]?.querySelector('input:enabled, select:enabled, textarea:enabled') &&
90
- tr instanceof HTMLTableRowElement &&
91
- tr.offsetParent !== null,
92
- )
93
- const theTd = allTrs[newTrIndex]?.children[tdIndex] ?? null
94
- theTd?.querySelector<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>('input,select,textarea')?.focus()
95
- if (typeof enterGoesDown === 'function') {
96
- enterGoesDown({
97
- tr: allTrs[newTrIndex] as HTMLTableRowElement,
98
- event,
99
- })
100
- }
101
- }
102
- }
103
-
104
- onMount(() => {
105
- if (!(property in columnInfo.current)) {
106
- console.warn(
107
- `Column "${property}" does not exist in its parent Table component's list of columns.\r\n\r\nPlease check that this Td's "property" prop matches the "property" prop of one of the columns in the parent Table component.`,
108
- )
109
- }
110
- })
111
- </script>
112
-
113
- {#if visible}
114
- <svelte:element
115
- this={tagName}
116
- class={[
117
- classNames,
118
- alignClass,
119
- {
120
- pinned: thisColumnInfo?.pinned,
121
- },
122
- ]}
123
- {...rest}
124
- style:font-variant-numeric={thisColumnInfo?.numeric ? 'tabular-nums' : undefined}
125
- style:overflow={$columnResizingEnabled ? 'hidden' : undefined}
126
- style:text-overflow={$columnResizingEnabled ? 'ellipsis' : undefined}
127
- style:--pinned-column-offset={thisColumnInfo?.pinned ? columnInfo.getPinnedColumnOffset(property) : undefined}
128
- >
129
- <!--
130
- Don't listen to events that the user hasn't turned on the features for.
131
- Also, put them on a span so they can still click in the td to click the row but not the td's child content
132
- -->
133
- {#if stopPropagation || enterGoesDown}
134
- <!-- svelte-ignore a11y_no_static_element_interactions -->
135
- <span
136
- onclick={stopPropagation ? e => e.stopPropagation() : undefined}
137
- {onkeypress}
138
- >
139
- {@render children?.()}
140
- </span>
141
- {:else}
142
- {@render children?.()}
143
- {/if}
144
- </svelte:element>
145
- {/if}
146
-
147
- <style>
148
- td.text-right :global(input),
149
- td.text-end :global(input) {
150
- text-align: right;
151
- }
152
- td.text-right :global(select),
153
- td.text-end :global(select) {
154
- text-align: right;
155
- }
156
- td.text-right :global(textarea),
157
- td.text-end :global(textarea) {
158
- text-align: right;
159
- }
160
-
161
- /* BS5 uses floats for checkbox alignment, which overrides the text align classes, so undo that here. */
162
- td:where(.text-start, .text-center, .text-end) :global(.form-check-input) {
163
- float: unset;
164
- }
165
-
166
- .pinned {
167
- position: sticky;
168
- z-index: 10 !important;
169
- left: var(--pinned-column-offset, -1);
170
- }
171
- </style>
1
+ <!-- eslint-disable @typescript-eslint/no-explicit-any -->
2
+ <script
3
+ lang="ts"
4
+ generics="R extends UuidRowProps = any"
5
+ >
6
+ import type { ColumnInfo, UuidRowProps } from './'
7
+ import type { ColumnInfoRunicStore } from './column-info-store.svelte'
8
+ import type { HTMLTdAttributes, ClassValue } from 'svelte/elements'
9
+ import type { Writable } from 'svelte/store'
10
+ import { getContext, onMount, type Snippet } from 'svelte'
11
+
12
+ // Get the columnInfo store from the Table component
13
+ const columnInfo = getContext<ColumnInfoRunicStore<UuidRowProps>>('columnInfo')
14
+ const columnResizingEnabled = getContext<Writable<boolean>>('columnResizingEnabled')
15
+ const bs5 = getContext<boolean>('bs5')
16
+
17
+ interface Props extends Omit<HTMLTdAttributes, 'align'> {
18
+ class?: ClassValue
19
+ property: ColumnInfo<R>['property']
20
+ /** Direction to align the column's contents
21
+ *
22
+ * `start` and `end` are only available in Bootstrap 5+
23
+ *
24
+ * `left` and `right`should only be used while you transition to Boostrap 5+
25
+ */
26
+ align?: 'start' | 'left' | 'center' | 'right' | 'end'
27
+ /** If enabled, pressing enter while focused in this Td will focus the next non-disabled input/select/textarea in the column. Holding shift will go up instead of down.
28
+ *
29
+ * Can also be a callback that is fired when the enter key is used to move between rows.
30
+ */
31
+ enterGoesDown?: boolean | ((ctx: { event: KeyboardEvent; tr: HTMLTableRowElement }) => void)
32
+ /** If enabled, keypress (enter only) and click events on the Td's contents will have `stopPropagation`/`preventDefault` called on them. */
33
+ stopPropagation?: boolean
34
+ tagName?: 'td' | 'th'
35
+ children?: Snippet
36
+ }
37
+
38
+ let {
39
+ //
40
+ class: classNames = '',
41
+ property,
42
+ align = $bindable(columnInfo.current[property]?.align),
43
+ enterGoesDown = false,
44
+ stopPropagation = false,
45
+ tagName = 'td',
46
+ children,
47
+ ...rest
48
+ }: Props = $props()
49
+
50
+ const thisColumnInfo = $derived(
51
+ columnInfo.current[property] as (typeof columnInfo.current)[typeof property] | undefined,
52
+ )
53
+ const alignClass = $derived.by(() => {
54
+ let alignment = align || thisColumnInfo?.align || (thisColumnInfo?.numeric ? 'right' : undefined)
55
+ if (bs5 && alignment === 'right') {
56
+ alignment = 'end'
57
+ } else if (bs5 && alignment === 'left') {
58
+ alignment = 'start'
59
+ }
60
+ return alignment ? (`text-${alignment}` as const) : ''
61
+ })
62
+ const visible = $derived(thisColumnInfo?.visible ?? true)
63
+
64
+ /** Handle `stopPropagation` and `enterGoesDown` props */
65
+ function onkeypress(event: KeyboardEvent) {
66
+ if (event.key === 'Enter') {
67
+ event.stopPropagation()
68
+ event.preventDefault()
69
+ }
70
+
71
+ if (event.key === 'Enter' && enterGoesDown) {
72
+ const target = event.target
73
+ if (!(target instanceof HTMLElement)) {
74
+ return
75
+ }
76
+ const tr = target?.closest('tr') ?? null
77
+ const td = target?.closest('td') ?? null
78
+ const tdIndex = td ? Array.from(tr?.children ?? []).indexOf(td) : -1
79
+ const allTrs = Array.from(tr?.parentElement?.children ?? [])
80
+
81
+ // if they're holding shift, reverse the tr list
82
+ if (event.shiftKey) {
83
+ allTrs.reverse()
84
+ }
85
+ // Find the next Td in the column with a non-disabled input, select, or textarea
86
+ const lastTrIndex = tr ? allTrs.indexOf(tr) : -1
87
+ const newTrIndex = allTrs.findIndex(
88
+ (tr, index) =>
89
+ index > lastTrIndex &&
90
+ tr.children[tdIndex]?.querySelector('input:enabled, select:enabled, textarea:enabled') &&
91
+ tr instanceof HTMLTableRowElement &&
92
+ tr.offsetParent !== null,
93
+ )
94
+ const theTd = allTrs[newTrIndex]?.children[tdIndex] ?? null
95
+ theTd?.querySelector<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>('input,select,textarea')?.focus()
96
+ if (typeof enterGoesDown === 'function') {
97
+ enterGoesDown({
98
+ tr: allTrs[newTrIndex] as HTMLTableRowElement,
99
+ event,
100
+ })
101
+ }
102
+ }
103
+ }
104
+
105
+ onMount(() => {
106
+ if (!(property in columnInfo.current)) {
107
+ console.warn(
108
+ `Column "${property}" does not exist in its parent Table component's list of columns.\r\n\r\nPlease check that this Td's "property" prop matches the "property" prop of one of the columns in the parent Table component.`,
109
+ )
110
+ }
111
+ })
112
+ </script>
113
+
114
+ {#if visible}
115
+ <svelte:element
116
+ this={tagName}
117
+ class={[
118
+ classNames,
119
+ alignClass,
120
+ {
121
+ pinned: thisColumnInfo?.pinned,
122
+ },
123
+ ]}
124
+ {...rest}
125
+ style:font-variant-numeric={thisColumnInfo?.numeric ? 'tabular-nums' : undefined}
126
+ style:overflow={$columnResizingEnabled ? 'hidden' : undefined}
127
+ style:text-overflow={$columnResizingEnabled ? 'ellipsis' : undefined}
128
+ style:--pinned-column-offset={thisColumnInfo?.pinned ? columnInfo.getPinnedColumnOffset(property) : undefined}
129
+ >
130
+ <!--
131
+ Don't listen to events that the user hasn't turned on the features for.
132
+ Also, put them on a span so they can still click in the td to click the row but not the td's child content
133
+ -->
134
+ {#if stopPropagation || enterGoesDown}
135
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
136
+ <span
137
+ onclick={stopPropagation ? e => e.stopPropagation() : undefined}
138
+ {onkeypress}
139
+ >
140
+ {@render children?.()}
141
+ </span>
142
+ {:else}
143
+ {@render children?.()}
144
+ {/if}
145
+ </svelte:element>
146
+ {/if}
147
+
148
+ <style>
149
+ td.text-right :global(input),
150
+ td.text-end :global(input) {
151
+ text-align: right;
152
+ }
153
+ td.text-right :global(select),
154
+ td.text-end :global(select) {
155
+ text-align: right;
156
+ }
157
+ td.text-right :global(textarea),
158
+ td.text-end :global(textarea) {
159
+ text-align: right;
160
+ }
161
+
162
+ /* BS5 uses floats for checkbox alignment, which overrides the text align classes, so undo that here. */
163
+ td:where(.text-start, .text-center, .text-end) :global(.form-check-input) {
164
+ float: unset;
165
+ }
166
+
167
+ .pinned {
168
+ position: sticky;
169
+ z-index: 10 !important;
170
+ left: var(--pinned-column-offset, -1);
171
+ }
172
+ </style>
@@ -1,10 +1,10 @@
1
- import type { RowProperties, UuidRowProps } from './';
1
+ import type { UuidRowProps } from './';
2
2
  import type { HTMLTdAttributes, ClassValue } from 'svelte/elements';
3
3
  import { type Snippet } from 'svelte';
4
4
  declare class __sveltets_Render<R extends UuidRowProps = any> {
5
5
  props(): Omit<HTMLTdAttributes, "align"> & {
6
6
  class?: ClassValue;
7
- property: `_${string}` | RowProperties<R>;
7
+ property: `_${string}` | import("./").RowProperties<R>;
8
8
  /** Direction to align the column's contents
9
9
  *
10
10
  * `start` and `end` are only available in Bootstrap 5+