@fluixi-ui/table 0.2.0-alpha.18 → 0.2.0-alpha.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,17 +1,5 @@
1
- import "@fluixi-ui/tokens/css/base.css";
2
- import "@fluixi-ui/tokens/css/table.css";
3
1
  import { Table, TableBody, TableCell, TableFooter, TableHead, TableHeader, TableRow, flexRender, useTableContext } from "./table.js";
4
2
  import { TableColumnMenu, TableViewMenu } from "./table-menu.js";
5
- export {
6
- Table,
7
- TableBody,
8
- TableCell,
9
- TableColumnMenu,
10
- TableFooter,
11
- TableHead,
12
- TableHeader,
13
- TableRow,
14
- TableViewMenu,
15
- flexRender,
16
- useTableContext
17
- };
3
+ import "@fluixi-ui/tokens/css/base.css";
4
+ import "@fluixi-ui/tokens/css/table.css";
5
+ export { Table, TableBody, TableCell, TableColumnMenu, TableFooter, TableHead, TableHeader, TableRow, TableViewMenu, flexRender, useTableContext };
@@ -1,155 +1,274 @@
1
- import { createComponent, createNativeElement, spread, insert, delegateEvents } from "@fluixi/dom";
1
+ import { createComponent, createNativeElement, delegateEvents, insert, spread } from "@fluixi/dom";
2
2
  import { createMemo, onCleanup } from "@fluixi/reactive/signal";
3
- import { Show, For } from "@fluixi/core";
4
- import { ContextMenu, ContextMenuTrigger, ContextMenuPortal, ContextMenuContent, ContextMenuItem, ContextMenuSeparator, ContextMenuLabel } from "@fluixi-ui/context-menu";
3
+ import { For, Show } from "@fluixi/core";
4
+ import { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuSeparator, ContextMenuTrigger } from "@fluixi-ui/context-menu";
5
+ //#region src/table-menu.tsx
5
6
  delegateEvents(["click"]);
7
+ /** Stop a `contextmenu` event from bubbling past this node. Added as a ref so it
8
+ * fires on the same node as (and after) the menu's own open handler, letting a
9
+ * header menu win over an outer table-wide menu. */
6
10
  function stopContextMenu(node) {
7
- const handler = (event) => event.stopPropagation();
8
- node.addEventListener("contextmenu", handler);
9
- onCleanup(() => node.removeEventListener("contextmenu", handler));
11
+ const handler = (event) => event.stopPropagation();
12
+ node.addEventListener("contextmenu", handler);
13
+ onCleanup(() => node.removeEventListener("contextmenu", handler));
10
14
  }
15
+ /**
16
+ * Right-click menu for a single column header. Auto-lists the actions that make
17
+ * sense for the column — sort ascending/descending/clear (when sortable) and
18
+ * hide (when hideable) — plus any extra `children` items. Drop it in as a
19
+ * {@link TableHead}'s child; left-click still sorts. Stops propagation so it
20
+ * takes precedence over a surrounding {@link TableViewMenu}.
21
+ */
11
22
  function TableColumnMenu(props) {
12
- const column = props.column;
13
- const canSort = () => column.getCanSort?.() ?? false;
14
- const isSorted = () => canSort() ? column.getIsSorted() : false;
15
- const canHide = () => column.getCanHide?.() ?? false;
16
- const canPin = () => column.getCanPin?.() ?? false;
17
- const pinned = () => canPin() ? column.getIsPinned() : false;
18
- return createMemo(() => createComponent(ContextMenu, { get children() {
19
- return [createMemo(() => createComponent(ContextMenuTrigger, { get ref() {
20
- return stopContextMenu;
21
- }, get "data-table-column-menu-trigger"() {
22
- return "";
23
- }, get "data-sortable"() {
24
- return () => canSort() ? "" : void 0;
25
- }, get onClick() {
26
- return canSort() ? column.getToggleSortingHandler() : void 0;
27
- }, get children() {
28
- return [() => props.label ?? String(column.columnDef.header ?? column.id), createMemo(() => createComponent(Show, { get when() {
29
- return canSort();
30
- }, get children() {
31
- return (() => {
32
- const _el$ = createNativeElement("span");
33
- spread({ element: _el$, props: { "data-table-sort-indicator": "", "data-direction": () => isSorted() || "none", "aria-hidden": "true" } });
34
- return _el$;
35
- })();
36
- } }))];
37
- } })), createMemo(() => createComponent(ContextMenuPortal, { get children() {
38
- return createMemo(() => createComponent(ContextMenuContent, { get children() {
39
- return [createMemo(() => createComponent(Show, { get when() {
40
- return canSort();
41
- }, get children() {
42
- return [createMemo(() => createComponent(ContextMenuItem, { get onSelect() {
43
- return () => column.toggleSorting(false);
44
- }, get children() {
45
- return () => props.labels?.sortAscending ?? "Sort ascending";
46
- } })), createMemo(() => createComponent(ContextMenuItem, { get onSelect() {
47
- return () => column.toggleSorting(true);
48
- }, get children() {
49
- return () => props.labels?.sortDescending ?? "Sort descending";
50
- } })), createMemo(() => createComponent(Show, { get when() {
51
- return !!isSorted();
52
- }, get children() {
53
- return createMemo(() => createComponent(ContextMenuItem, { get onSelect() {
54
- return () => column.clearSorting();
55
- }, get children() {
56
- return () => props.labels?.clearSort ?? "Clear sort";
57
- } }));
58
- } }))];
59
- } })), createMemo(() => createComponent(Show, { get when() {
60
- return canSort() && (canPin() || canHide());
61
- }, get children() {
62
- return createMemo(() => createComponent(ContextMenuSeparator, {}));
63
- } })), createMemo(() => createComponent(Show, { get when() {
64
- return canPin();
65
- }, get children() {
66
- return [createMemo(() => createComponent(Show, { get when() {
67
- return pinned() !== "left";
68
- }, get children() {
69
- return createMemo(() => createComponent(ContextMenuItem, { get onSelect() {
70
- return () => column.pin("left");
71
- }, get children() {
72
- return () => props.labels?.pinLeft ?? "Pin left";
73
- } }));
74
- } })), createMemo(() => createComponent(Show, { get when() {
75
- return pinned() !== "right";
76
- }, get children() {
77
- return createMemo(() => createComponent(ContextMenuItem, { get onSelect() {
78
- return () => column.pin("right");
79
- }, get children() {
80
- return () => props.labels?.pinRight ?? "Pin right";
81
- } }));
82
- } })), createMemo(() => createComponent(Show, { get when() {
83
- return !!pinned();
84
- }, get children() {
85
- return createMemo(() => createComponent(ContextMenuItem, { get onSelect() {
86
- return () => column.pin(false);
87
- }, get children() {
88
- return () => props.labels?.unpin ?? "Unpin";
89
- } }));
90
- } }))];
91
- } })), createMemo(() => createComponent(Show, { get when() {
92
- return canPin() && canHide();
93
- }, get children() {
94
- return createMemo(() => createComponent(ContextMenuSeparator, {}));
95
- } })), createMemo(() => createComponent(Show, { get when() {
96
- return canHide();
97
- }, get children() {
98
- return createMemo(() => createComponent(ContextMenuItem, { get onSelect() {
99
- return () => column.toggleVisibility(false);
100
- }, get children() {
101
- return () => props.labels?.hideColumn ?? "Hide column";
102
- } }));
103
- } })), props.children];
104
- } }));
105
- } }))];
106
- } }));
23
+ const column = props.column;
24
+ const canSort = () => column.getCanSort?.() ?? false;
25
+ const isSorted = () => canSort() ? column.getIsSorted() : false;
26
+ const canHide = () => column.getCanHide?.() ?? false;
27
+ const canPin = () => column.getCanPin?.() ?? false;
28
+ const pinned = () => canPin() ? column.getIsPinned() : false;
29
+ return createMemo(() => createComponent(ContextMenu, { get children() {
30
+ return [createMemo(() => createComponent(ContextMenuTrigger, {
31
+ get ref() {
32
+ return stopContextMenu;
33
+ },
34
+ get "data-table-column-menu-trigger"() {
35
+ return "";
36
+ },
37
+ get "data-sortable"() {
38
+ return () => canSort() ? "" : void 0;
39
+ },
40
+ get onClick() {
41
+ return canSort() ? column.getToggleSortingHandler() : void 0;
42
+ },
43
+ get children() {
44
+ return [() => props.label ?? String(column.columnDef.header ?? column.id), createMemo(() => createComponent(Show, {
45
+ get when() {
46
+ return canSort();
47
+ },
48
+ get children() {
49
+ return (() => {
50
+ const _el$ = createNativeElement("span");
51
+ spread({
52
+ element: _el$,
53
+ props: {
54
+ "data-table-sort-indicator": "",
55
+ "data-direction": () => isSorted() || "none",
56
+ "aria-hidden": "true"
57
+ }
58
+ });
59
+ return _el$;
60
+ })();
61
+ }
62
+ }))];
63
+ }
64
+ })), createMemo(() => createComponent(ContextMenuPortal, { get children() {
65
+ return createMemo(() => createComponent(ContextMenuContent, { get children() {
66
+ return [
67
+ createMemo(() => createComponent(Show, {
68
+ get when() {
69
+ return canSort();
70
+ },
71
+ get children() {
72
+ return [
73
+ createMemo(() => createComponent(ContextMenuItem, {
74
+ get onSelect() {
75
+ return () => column.toggleSorting(false);
76
+ },
77
+ get children() {
78
+ return () => props.labels?.sortAscending ?? "Sort ascending";
79
+ }
80
+ })),
81
+ createMemo(() => createComponent(ContextMenuItem, {
82
+ get onSelect() {
83
+ return () => column.toggleSorting(true);
84
+ },
85
+ get children() {
86
+ return () => props.labels?.sortDescending ?? "Sort descending";
87
+ }
88
+ })),
89
+ createMemo(() => createComponent(Show, {
90
+ get when() {
91
+ return !!isSorted();
92
+ },
93
+ get children() {
94
+ return createMemo(() => createComponent(ContextMenuItem, {
95
+ get onSelect() {
96
+ return () => column.clearSorting();
97
+ },
98
+ get children() {
99
+ return () => props.labels?.clearSort ?? "Clear sort";
100
+ }
101
+ }));
102
+ }
103
+ }))
104
+ ];
105
+ }
106
+ })),
107
+ createMemo(() => createComponent(Show, {
108
+ get when() {
109
+ return canSort() && (canPin() || canHide());
110
+ },
111
+ get children() {
112
+ return createMemo(() => createComponent(ContextMenuSeparator, {}));
113
+ }
114
+ })),
115
+ createMemo(() => createComponent(Show, {
116
+ get when() {
117
+ return canPin();
118
+ },
119
+ get children() {
120
+ return [
121
+ createMemo(() => createComponent(Show, {
122
+ get when() {
123
+ return pinned() !== "left";
124
+ },
125
+ get children() {
126
+ return createMemo(() => createComponent(ContextMenuItem, {
127
+ get onSelect() {
128
+ return () => column.pin("left");
129
+ },
130
+ get children() {
131
+ return () => props.labels?.pinLeft ?? "Pin left";
132
+ }
133
+ }));
134
+ }
135
+ })),
136
+ createMemo(() => createComponent(Show, {
137
+ get when() {
138
+ return pinned() !== "right";
139
+ },
140
+ get children() {
141
+ return createMemo(() => createComponent(ContextMenuItem, {
142
+ get onSelect() {
143
+ return () => column.pin("right");
144
+ },
145
+ get children() {
146
+ return () => props.labels?.pinRight ?? "Pin right";
147
+ }
148
+ }));
149
+ }
150
+ })),
151
+ createMemo(() => createComponent(Show, {
152
+ get when() {
153
+ return !!pinned();
154
+ },
155
+ get children() {
156
+ return createMemo(() => createComponent(ContextMenuItem, {
157
+ get onSelect() {
158
+ return () => column.pin(false);
159
+ },
160
+ get children() {
161
+ return () => props.labels?.unpin ?? "Unpin";
162
+ }
163
+ }));
164
+ }
165
+ }))
166
+ ];
167
+ }
168
+ })),
169
+ createMemo(() => createComponent(Show, {
170
+ get when() {
171
+ return canPin() && canHide();
172
+ },
173
+ get children() {
174
+ return createMemo(() => createComponent(ContextMenuSeparator, {}));
175
+ }
176
+ })),
177
+ createMemo(() => createComponent(Show, {
178
+ get when() {
179
+ return canHide();
180
+ },
181
+ get children() {
182
+ return createMemo(() => createComponent(ContextMenuItem, {
183
+ get onSelect() {
184
+ return () => column.toggleVisibility(false);
185
+ },
186
+ get children() {
187
+ return () => props.labels?.hideColumn ?? "Hide column";
188
+ }
189
+ }));
190
+ }
191
+ })),
192
+ props.children
193
+ ];
194
+ } }));
195
+ } }))];
196
+ } }));
107
197
  }
198
+ /**
199
+ * Table-wide right-click menu. Lists every hideable column as a toggle (so
200
+ * hidden columns can be restored) plus show-all and reset-view actions. Wrap
201
+ * it around the whole `<Table>`; header menus stop propagation, so right-clicking
202
+ * a header opens its {@link TableColumnMenu} instead of this one.
203
+ */
108
204
  function TableViewMenu(props) {
109
- const table = props.table;
110
- const hideableColumns = table.getAllLeafColumns().filter((c) => c.getCanHide?.() && typeof c.columnDef.header === "string");
111
- const showAll = () => props.onShowAll ? props.onShowAll() : table.toggleAllColumnsVisible(true);
112
- const resetView = () => {
113
- if (props.onReset) return props.onReset();
114
- table.resetSorting?.();
115
- table.resetColumnFilters?.();
116
- table.resetColumnVisibility?.();
117
- table.resetColumnOrder?.();
118
- };
119
- return createMemo(() => createComponent(ContextMenu, { get children() {
120
- return [createMemo(() => createComponent(ContextMenuTrigger, { get children() {
121
- return props.children;
122
- } })), createMemo(() => createComponent(ContextMenuPortal, { get children() {
123
- return createMemo(() => createComponent(ContextMenuContent, { get children() {
124
- return [createMemo(() => createComponent(ContextMenuLabel, { get children() {
125
- return () => props.labels?.columns ?? "Columns";
126
- } })), createMemo(() => createComponent(For, { get each() {
127
- return hideableColumns;
128
- }, get children() {
129
- return (column) => createMemo(() => createComponent(ContextMenuItem, { get onSelect() {
130
- return () => column.toggleVisibility();
131
- }, get children() {
132
- return [(() => {
133
- const _el$ = createNativeElement("span");
134
- spread({ element: _el$, props: { "data-table-menu-check": "", "data-checked": () => column.getIsVisible() || void 0 } });
135
- insert(_el$, "✓");
136
- return _el$;
137
- })(), () => String(column.columnDef.header)];
138
- } }));
139
- } })), createMemo(() => createComponent(ContextMenuSeparator, {})), createMemo(() => createComponent(ContextMenuItem, { get onSelect() {
140
- return showAll;
141
- }, get children() {
142
- return () => props.labels?.showAllColumns ?? "Show all columns";
143
- } })), createMemo(() => createComponent(ContextMenuItem, { get onSelect() {
144
- return resetView;
145
- }, get children() {
146
- return () => props.labels?.resetView ?? "Reset view";
147
- } })), () => props.extra];
148
- } }));
149
- } }))];
150
- } }));
205
+ const table = props.table;
206
+ const hideableColumns = table.getAllLeafColumns().filter((c) => c.getCanHide?.() && typeof c.columnDef.header === "string");
207
+ const showAll = () => props.onShowAll ? props.onShowAll() : table.toggleAllColumnsVisible(true);
208
+ const resetView = () => {
209
+ if (props.onReset) return props.onReset();
210
+ table.resetSorting?.();
211
+ table.resetColumnFilters?.();
212
+ table.resetColumnVisibility?.();
213
+ table.resetColumnOrder?.();
214
+ };
215
+ return createMemo(() => createComponent(ContextMenu, { get children() {
216
+ return [createMemo(() => createComponent(ContextMenuTrigger, { get children() {
217
+ return props.children;
218
+ } })), createMemo(() => createComponent(ContextMenuPortal, { get children() {
219
+ return createMemo(() => createComponent(ContextMenuContent, { get children() {
220
+ return [
221
+ createMemo(() => createComponent(ContextMenuLabel, { get children() {
222
+ return () => props.labels?.columns ?? "Columns";
223
+ } })),
224
+ createMemo(() => createComponent(For, {
225
+ get each() {
226
+ return hideableColumns;
227
+ },
228
+ get children() {
229
+ return (column) => createMemo(() => createComponent(ContextMenuItem, {
230
+ get onSelect() {
231
+ return () => column.toggleVisibility();
232
+ },
233
+ get children() {
234
+ return [(() => {
235
+ const _el$ = createNativeElement("span");
236
+ spread({
237
+ element: _el$,
238
+ props: {
239
+ "data-table-menu-check": "",
240
+ "data-checked": () => column.getIsVisible() || void 0
241
+ }
242
+ });
243
+ insert(_el$, "✓");
244
+ return _el$;
245
+ })(), () => String(column.columnDef.header)];
246
+ }
247
+ }));
248
+ }
249
+ })),
250
+ createMemo(() => createComponent(ContextMenuSeparator, {})),
251
+ createMemo(() => createComponent(ContextMenuItem, {
252
+ get onSelect() {
253
+ return showAll;
254
+ },
255
+ get children() {
256
+ return () => props.labels?.showAllColumns ?? "Show all columns";
257
+ }
258
+ })),
259
+ createMemo(() => createComponent(ContextMenuItem, {
260
+ get onSelect() {
261
+ return resetView;
262
+ },
263
+ get children() {
264
+ return () => props.labels?.resetView ?? "Reset view";
265
+ }
266
+ })),
267
+ () => props.extra
268
+ ];
269
+ } }));
270
+ } }))];
271
+ } }));
151
272
  }
152
- export {
153
- TableColumnMenu,
154
- TableViewMenu
155
- };
273
+ //#endregion
274
+ export { TableColumnMenu, TableViewMenu };