intable 0.0.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 (74) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +22 -0
  3. package/dist/chevron-right.js +8 -0
  4. package/dist/components/Columns.d.ts +3 -0
  5. package/dist/components/Columns.js +105 -0
  6. package/dist/components/DocTree.d.ts +4 -0
  7. package/dist/components/DocTree.js +40 -0
  8. package/dist/components/Menu.d.ts +1 -0
  9. package/dist/components/Menu.js +131 -0
  10. package/dist/components/Popover.d.ts +14 -0
  11. package/dist/components/Popover.js +49 -0
  12. package/dist/components/Render.d.ts +4 -0
  13. package/dist/components/Render.js +21 -0
  14. package/dist/components/Split.d.ts +15 -0
  15. package/dist/components/Split.js +88 -0
  16. package/dist/components/Tree.d.ts +37 -0
  17. package/dist/components/Tree.js +101 -0
  18. package/dist/components/utils.d.ts +3 -0
  19. package/dist/components/utils.js +10 -0
  20. package/dist/demo.d.ts +2 -0
  21. package/dist/demo.js +64 -0
  22. package/dist/hooks/index.d.ts +38 -0
  23. package/dist/hooks/index.js +182 -0
  24. package/dist/hooks/useDir.d.ts +11 -0
  25. package/dist/hooks/useDir.js +59 -0
  26. package/dist/hooks/useVirtualizer.d.ts +25 -0
  27. package/dist/hooks/useVirtualizer.js +92 -0
  28. package/dist/index.d.ts +116 -0
  29. package/dist/index.js +348 -0
  30. package/dist/intable.css +277 -0
  31. package/dist/loading.js +8 -0
  32. package/dist/plugins/CellChangeHighlightPlugin.d.ts +2 -0
  33. package/dist/plugins/CellChangeHighlightPlugin.js +4 -0
  34. package/dist/plugins/CellSelectionPlugin.d.ts +15 -0
  35. package/dist/plugins/CellSelectionPlugin.js +150 -0
  36. package/dist/plugins/CommandPlugin.d.ts +14 -0
  37. package/dist/plugins/CommandPlugin.js +9 -0
  38. package/dist/plugins/CopyPastePlugin.d.ts +14 -0
  39. package/dist/plugins/CopyPastePlugin.js +54 -0
  40. package/dist/plugins/DiffPlugin.d.ts +23 -0
  41. package/dist/plugins/DiffPlugin.js +68 -0
  42. package/dist/plugins/DragColumnPlugin.d.ts +2 -0
  43. package/dist/plugins/DragColumnPlugin.js +4 -0
  44. package/dist/plugins/EditablePlugin.d.ts +49 -0
  45. package/dist/plugins/EditablePlugin.js +191 -0
  46. package/dist/plugins/ExpandPlugin.d.ts +20 -0
  47. package/dist/plugins/ExpandPlugin.js +56 -0
  48. package/dist/plugins/HistoryPlugin.d.ts +10 -0
  49. package/dist/plugins/HistoryPlugin.js +35 -0
  50. package/dist/plugins/MenuPlugin.d.ts +18 -0
  51. package/dist/plugins/MenuPlugin.js +131 -0
  52. package/dist/plugins/RenderPlugin/components.d.ts +5 -0
  53. package/dist/plugins/RenderPlugin/components.js +105 -0
  54. package/dist/plugins/RenderPlugin/index.d.ts +30 -0
  55. package/dist/plugins/RenderPlugin/index.js +61 -0
  56. package/dist/plugins/ResizePlugin.d.ts +27 -0
  57. package/dist/plugins/ResizePlugin.js +103 -0
  58. package/dist/plugins/RowGroupPlugin.d.ts +17 -0
  59. package/dist/plugins/RowGroupPlugin.js +99 -0
  60. package/dist/plugins/RowSelectionPlugin.d.ts +32 -0
  61. package/dist/plugins/RowSelectionPlugin.js +69 -0
  62. package/dist/plugins/VirtualScrollPlugin.d.ts +15 -0
  63. package/dist/plugins/VirtualScrollPlugin.js +121 -0
  64. package/dist/plus.js +8 -0
  65. package/dist/types/auto-imports.d.js +0 -0
  66. package/dist/utils.d.ts +29 -0
  67. package/dist/utils.js +88 -0
  68. package/dist/vite.svg +1 -0
  69. package/dist/wc.d.ts +1 -0
  70. package/dist/wc.js +24 -0
  71. package/dist/web-component.d.ts +1 -0
  72. package/dist/web-component.js +2 -0
  73. package/dist/x.js +8 -0
  74. package/package.json +71 -0
@@ -0,0 +1,15 @@
1
+ import { type Plugin } from '..';
2
+ declare module '../index' {
3
+ interface TableProps {
4
+ }
5
+ interface TableStore {
6
+ selected: {
7
+ start: number[];
8
+ end: number[];
9
+ };
10
+ }
11
+ interface Commands {
12
+ getAreaRows(): any[];
13
+ }
14
+ }
15
+ export declare const CellSelectionPlugin: Plugin;
@@ -0,0 +1,150 @@
1
+ import { usePointerDrag, useTinykeys } from "../hooks/index.js";
2
+ import { Ctx } from "../index.js";
3
+ import { createComponent, memo, mergeProps, template } from "solid-js/web";
4
+ import { batch, createMemo, useContext } from "solid-js";
5
+ import { combineProps } from "@solid-primitives/props";
6
+ var _tmpl$ = /* @__PURE__ */ template(`<div class=area>`);
7
+ var inrange = (v, min, max) => v <= max && v >= min;
8
+ const CellSelectionPlugin = {
9
+ store: () => ({ selected: {
10
+ start: [],
11
+ end: []
12
+ } }),
13
+ commands: (store) => ({ getAreaRows() {
14
+ const { start, end } = store.selected;
15
+ const [y1, y2] = [start[1], end[1]].sort((a, b) => a - b);
16
+ return store.props.data.slice(y1, y2 + 1);
17
+ } }),
18
+ rewriteProps: {
19
+ Th: ({ Th }, { store }) => (o) => {
20
+ const clazz = createMemo(() => {
21
+ const { start, end } = store.selected;
22
+ return inrange(o.x, ...[start[0], end[0]].sort((a, b) => a - b)) ? "col-range-highlight" : "";
23
+ });
24
+ const mo = combineProps(o, { get class() {
25
+ return clazz();
26
+ } });
27
+ return createComponent(Th, mergeProps(mo, { get children() {
28
+ return [memo(() => mo.children), memo(() => memo(() => !!clazz())() && _tmpl$())];
29
+ } }));
30
+ },
31
+ Td: ({ Td }, { store }) => (o) => {
32
+ const clazz = createMemo(() => {
33
+ let clazz$1 = "";
34
+ const { xs, ys } = store.cellSelectionRect();
35
+ const inx = inrange(o.x, xs[0], xs[1]);
36
+ const iny = inrange(o.y, ys[0], ys[1]);
37
+ if (inx && iny) {
38
+ clazz$1 += "range-selected ";
39
+ if (o.x == xs[0]) clazz$1 += "range-selected-l ";
40
+ if (o.x == xs[1]) clazz$1 += "range-selected-r ";
41
+ if (o.y == ys[0]) clazz$1 += "range-selected-t ";
42
+ if (o.y == ys[1]) clazz$1 += "range-selected-b ";
43
+ }
44
+ if (o.x == 0 && iny) clazz$1 += "row-range-highlight ";
45
+ return clazz$1;
46
+ });
47
+ const mo = combineProps(o, {
48
+ get class() {
49
+ return clazz();
50
+ },
51
+ tabindex: -1
52
+ });
53
+ return createComponent(Td, mergeProps(mo, { get children() {
54
+ return [memo(() => mo.children), memo(() => memo(() => !!clazz())() && _tmpl$())];
55
+ } }));
56
+ },
57
+ Table: ({ Table }, { store }) => (o) => {
58
+ const { props } = useContext(Ctx);
59
+ store.cellSelectionRect ??= createMemo(() => {
60
+ const { start, end } = store.selected;
61
+ const xs = [start[0], end[0]].sort((a, b) => a - b);
62
+ const ys = [start[1], end[1]].sort((a, b) => a - b);
63
+ return {
64
+ xs,
65
+ ys
66
+ };
67
+ });
68
+ usePointerDrag(() => store.table, { start(e, move, end) {
69
+ batch(() => {
70
+ const findCell = (e$1) => e$1.composedPath().find((e$2) => e$2.tagName == "TH" || e$2.tagName == "TD");
71
+ const getXY = (cell$1) => [cell$1.getAttribute("x"), cell$1.getAttribute("y")];
72
+ const cell = findCell(e);
73
+ if (!cell) return;
74
+ if (e.buttons != 1 && cell.classList.contains("range-selected")) return;
75
+ if (cell.tagName == "TH") {
76
+ const [x, y] = getXY(cell);
77
+ if (x == null) return;
78
+ store.selected.start = [+x, 0];
79
+ store.selected.end = [+x, Infinity];
80
+ move((e$1) => {
81
+ const cell$1 = findCell(e$1);
82
+ if (!cell$1) return;
83
+ const [x$1, y$1] = getXY(cell$1);
84
+ if (x$1 == null) return;
85
+ store.selected.end = [+x$1, Infinity];
86
+ });
87
+ }
88
+ if (cell.classList.contains("index")) {
89
+ const [x, y] = getXY(cell);
90
+ if (x == null || y == null) return;
91
+ store.selected.start = [0, +y];
92
+ store.selected.end = [Infinity, +y];
93
+ move((e$1) => {
94
+ const cell$1 = findCell(e$1);
95
+ if (!cell$1) return;
96
+ const [x$1, y$1] = getXY(cell$1);
97
+ if (x$1 == null || y$1 == null) return;
98
+ store.selected.end = [Infinity, +y$1];
99
+ });
100
+ } else if (cell.tagName == "TD") {
101
+ const [x, y] = getXY(cell);
102
+ if (x == null || y == null) return;
103
+ store.selected.start = [+x, +y];
104
+ store.selected.end = [...store.selected.start];
105
+ move((e$1) => {
106
+ const cell$1 = findCell(e$1);
107
+ if (!cell$1) return;
108
+ const [x$1, y$1] = getXY(cell$1);
109
+ if (x$1 == null || y$1 == null) return;
110
+ store.selected.end = [+x$1, +y$1];
111
+ });
112
+ }
113
+ });
114
+ } });
115
+ useTinykeys(() => store.table, {
116
+ "ArrowLeft": () => {
117
+ const { start, end } = store.selected;
118
+ start[0] = end[0] = Math.max(start[0] - 1, 0);
119
+ end[1] = start[1];
120
+ scrollIntoView();
121
+ },
122
+ "ArrowRight": () => {
123
+ const { start, end } = store.selected;
124
+ start[0] = end[0] = Math.min(start[0] + 1, props.columns.length - 1);
125
+ end[1] = start[1];
126
+ scrollIntoView();
127
+ },
128
+ "ArrowUp": () => {
129
+ const { start, end } = store.selected;
130
+ start[1] = end[1] = Math.max(start[1] - 1, 0);
131
+ end[0] = start[0];
132
+ scrollIntoView();
133
+ },
134
+ "ArrowDown": () => {
135
+ const { start, end } = store.selected;
136
+ start[1] = end[1] = Math.min(start[1] + 1, props.data.length - 1);
137
+ end[0] = start[0];
138
+ scrollIntoView();
139
+ }
140
+ });
141
+ const scrollIntoView = () => {
142
+ const cell = store.table.querySelector(`td[x="${store.selected.start[0]}"][y="${store.selected.start[1]}"]`);
143
+ cell?.scrollIntoViewIfNeeded(false);
144
+ cell?.focus();
145
+ };
146
+ return createComponent(Table, o);
147
+ }
148
+ }
149
+ };
150
+ export { CellSelectionPlugin };
@@ -0,0 +1,14 @@
1
+ import { type Plugin } from '..';
2
+ declare module '../index' {
3
+ interface TableProps {
4
+ }
5
+ interface TableStore {
6
+ commands: Commands;
7
+ }
8
+ interface Plugin {
9
+ commands?: (store: TableStore, commands: Partial<Commands>) => Partial<Commands> & Record<string, any>;
10
+ }
11
+ interface Commands {
12
+ }
13
+ }
14
+ export declare const CommandPlugin: Plugin;
@@ -0,0 +1,9 @@
1
+ import { createComponent } from "solid-js/web";
2
+ import { createComputed } from "solid-js";
3
+ const CommandPlugin = { rewriteProps: { Table: ({ Table }, { store }) => (o) => {
4
+ createComputed(() => {
5
+ store.commands = store.plugins.reduce((o$1, e) => Object.assign(o$1, e.commands?.(store, { ...o$1 })), {});
6
+ });
7
+ return createComponent(Table, o);
8
+ } } };
9
+ export { CommandPlugin };
@@ -0,0 +1,14 @@
1
+ import { type Plugin } from '..';
2
+ declare module '../index' {
3
+ interface TableProps {
4
+ }
5
+ interface TableStore {
6
+ }
7
+ interface Plugin {
8
+ }
9
+ interface Commands {
10
+ copy: () => void;
11
+ paste: () => void;
12
+ }
13
+ }
14
+ export declare const ClipboardPlugin: Plugin;
@@ -0,0 +1,54 @@
1
+ import { useTinykeys } from "../hooks/index.js";
2
+ import { createComponent } from "solid-js/web";
3
+ import { createEffect } from "solid-js";
4
+ import { combineProps } from "@solid-primitives/props";
5
+ const ClipboardPlugin = {
6
+ rewriteProps: { Table: ({ Table }, { store }) => (o) => {
7
+ let el;
8
+ useTinykeys(() => el, {
9
+ "Control+C": () => {
10
+ store.commands.copy();
11
+ el.classList.add("copied");
12
+ },
13
+ "Control+V": () => store.commands.paste()
14
+ });
15
+ createEffect(() => {
16
+ JSON.stringify(store.selected);
17
+ el.classList.remove("copied");
18
+ });
19
+ o = combineProps({
20
+ ref: (e) => el = e,
21
+ tabindex: -1
22
+ }, o);
23
+ return createComponent(Table, o);
24
+ } },
25
+ menus: (store) => [],
26
+ commands: (store) => ({
27
+ copy: () => {
28
+ const { start, end } = store.selected;
29
+ if (start.length == 0) return;
30
+ const [x1, x2] = [start[0], end[0]].sort((a, b) => a - b);
31
+ const [y1, y2] = [start[1], end[1]].sort((a, b) => a - b);
32
+ const cols = store.props.columns.slice(x1, x2 + 1);
33
+ const text = store.props.data.slice(y1, y2 + 1).map((row) => cols.map((col) => row[col.id])).map((row) => row.join(" ")).join("\n");
34
+ navigator.clipboard.writeText(text);
35
+ },
36
+ paste: async () => {
37
+ const { start, end } = store.selected;
38
+ if (start.length == 0) return;
39
+ const arr2 = (await navigator.clipboard.readText()).split("\n").map((row) => row.split(" "));
40
+ const cols = store.props.columns.slice(start[0], start[0] + arr2[0].length);
41
+ const data = store.props.data.slice();
42
+ arr2.forEach((row, y) => {
43
+ row = Object.fromEntries(cols.map((col, x) => [col.id, row[x]]));
44
+ data[start[1] + y] = {
45
+ ...data[start[1] + y],
46
+ ...row
47
+ };
48
+ });
49
+ store.selected.end = [start[0] + cols.length - 1, Math.min(start[1] + arr2.length - 1, ctx.props.data.length - 1)];
50
+ store.props.onDataChange?.(data);
51
+ }
52
+ })
53
+ };
54
+ export { ClipboardPlugin };
@@ -0,0 +1,23 @@
1
+ import { type Plugin } from '..';
2
+ declare module '../index' {
3
+ interface TableProps {
4
+ diff?: {
5
+ /** @default true */ added?: boolean;
6
+ /** @default true */ removed?: boolean;
7
+ /** @default true */ changed?: boolean;
8
+ onCommit?: (data: any, opt: {
9
+ added: any[];
10
+ removed: any[];
11
+ changed: any[];
12
+ }) => any;
13
+ };
14
+ }
15
+ interface TableStore {
16
+ diffData: any[];
17
+ diffDataKeyed: () => any;
18
+ }
19
+ interface Commands {
20
+ diffCommit(data?: any[]): void;
21
+ }
22
+ }
23
+ export declare const DiffPlugin: Plugin;
@@ -0,0 +1,68 @@
1
+ import { useTinykeys } from "../hooks/index.js";
2
+ import { createComponent } from "solid-js/web";
3
+ import { unwrap } from "solid-js/store";
4
+ import { isEqual, keyBy } from "es-toolkit";
5
+ import { combineProps } from "@solid-primitives/props";
6
+ import { createLazyMemo } from "@solid-primitives/memo";
7
+ import { v4 } from "uuid";
8
+ import { diffArrays } from "diff";
9
+ var DEL = Symbol("del");
10
+ var NEW = Symbol("new");
11
+ const DiffPlugin = {
12
+ priority: Infinity,
13
+ store: (store) => {
14
+ const data = store.rawProps.data || [];
15
+ data.forEach((row) => unwrap(row)[store.rawProps.rowKey] ??= v4());
16
+ return {
17
+ diffData: structuredClone(unwrap(data || [])),
18
+ diffDataKeyed: createLazyMemo(() => keyBy(store.diffData, (e) => e[store.props.rowKey]))
19
+ };
20
+ },
21
+ commands: (store) => ({ async diffCommit(data = store.rawProps.data || []) {
22
+ const { rowKey } = store.props || {};
23
+ data.forEach((row) => unwrap(row)[rowKey] ??= v4());
24
+ data = structuredClone(unwrap(data));
25
+ const added = [], removed = [], changed = [];
26
+ const keyed = keyBy(data, (e) => e[rowKey]);
27
+ for (const e of data) {
28
+ const old = store.diffDataKeyed()[e[rowKey]];
29
+ if (!old) added.push(e);
30
+ else if (!isEqual(e, old)) changed.push(e);
31
+ }
32
+ for (const e of store.diffData) !keyed[e[rowKey]] && removed.push(e);
33
+ await store.props.diff?.onCommit?.(data, {
34
+ added,
35
+ removed,
36
+ changed
37
+ });
38
+ added[NEW] = 0;
39
+ store.diffData = data;
40
+ } }),
41
+ rewriteProps: {
42
+ diff: ({ diff }) => ({
43
+ added: true,
44
+ removed: true,
45
+ changed: true,
46
+ ...diff
47
+ }),
48
+ data: ({ data }, { store }) => {
49
+ const { rowKey, diff } = store.props || {};
50
+ return diffArrays(store.diffData || [], data, { comparator: (a, b) => a[rowKey] == b[rowKey] }).flatMap((e) => e.added ? e.value.map((e$1) => (e$1[NEW] = 1, e$1)) : e.removed ? diff.removed ? e.value.map((e$1) => ({
51
+ ...e$1,
52
+ [DEL]: 1,
53
+ [store.internal]: 1
54
+ })) : [] : e.value);
55
+ },
56
+ Table: ({ Table }, { store }) => (o) => {
57
+ useTinykeys(() => store.table, { "Control+S": () => store.commands.diffCommit() });
58
+ o = combineProps({ tabindex: -1 }, o);
59
+ return createComponent(Table, o);
60
+ },
61
+ tdProps: ({ tdProps }, { store }) => (o) => combineProps(tdProps?.(o) || {}, { get class() {
62
+ const { diff } = store.props || {};
63
+ const id = unwrap(o.data)[store.props.rowKey];
64
+ return [o.data[NEW] ? diff?.added ? "bg-#dafaea" : "" : o.data[DEL] ? "bg-#ffe8e8" : o.data[store.internal] ? "" : diff.changed && o.data[o.col.id] != store.diffDataKeyed()[id][o.col.id] ? "bg-#dafaea" : ""].join(" ");
65
+ } })
66
+ }
67
+ };
68
+ export { DiffPlugin };
@@ -0,0 +1,2 @@
1
+ import type { Plugin } from '..';
2
+ export declare function DragColumnPlugin(): Plugin;
@@ -0,0 +1,4 @@
1
+ function DragColumnPlugin() {
2
+ return {};
3
+ }
4
+ export { DragColumnPlugin };
@@ -0,0 +1,49 @@
1
+ import { type JSX } from 'solid-js';
2
+ import { type Plugin, type TableColumn } from '..';
3
+ declare module '../index' {
4
+ interface TableProps {
5
+ }
6
+ interface TableColumn {
7
+ editable?: boolean;
8
+ editor?: string | Editor;
9
+ editorProps?: any;
10
+ editorPopup?: boolean;
11
+ editOnInput?: boolean;
12
+ }
13
+ interface TableStore {
14
+ editors: {
15
+ [key: string]: Editor;
16
+ };
17
+ }
18
+ }
19
+ export type Editor = (props: EditorOpt) => {
20
+ el: JSX.Element;
21
+ getValue: () => any;
22
+ destroy: () => void;
23
+ focus?: () => void;
24
+ blur?: () => void;
25
+ };
26
+ export interface EditorOpt {
27
+ col: TableColumn;
28
+ data: any;
29
+ value: any;
30
+ eventKey?: string;
31
+ ok: () => void;
32
+ cancel: () => void;
33
+ props?: any;
34
+ }
35
+ export declare const EditablePlugin: Plugin;
36
+ export declare const editors: {
37
+ text: Editor;
38
+ number: Editor;
39
+ range: Editor;
40
+ date: Editor;
41
+ time: Editor;
42
+ datetime: Editor;
43
+ color: Editor;
44
+ tel: Editor;
45
+ password: Editor;
46
+ file: Editor;
47
+ checkbox: Editor;
48
+ select: Editor;
49
+ };
@@ -0,0 +1,191 @@
1
+ import { chooseFile, resolveOptions } from "../utils.js";
2
+ import { Checkbox, Files } from "./RenderPlugin/components.js";
3
+ import { Ctx } from "../index.js";
4
+ import { createComponent, delegateEvents, effect, insert, memo, mergeProps, spread, template, use } from "solid-js/web";
5
+ import { createComputed, createEffect, createMemo, createRoot, createSignal, on, onCleanup, useContext } from "solid-js";
6
+ import { createMutable } from "solid-js/store";
7
+ import { delay } from "es-toolkit";
8
+ import { combineProps } from "@solid-primitives/props";
9
+ import { createAsyncMemo } from "@solid-primitives/memo";
10
+ var _tmpl$ = /* @__PURE__ */ template(`<input style=position:absolute;margin-top:1em;width:0;height:0;pointer-events:none;opacity:0>`), _tmpl$2 = /* @__PURE__ */ template(`<div class=in-cell-edit-wrapper>`), _tmpl$3 = /* @__PURE__ */ template(`<input>`), _tmpl$4 = /* @__PURE__ */ template(`<select>`), _tmpl$5 = /* @__PURE__ */ template(`<option>`), _tmpl$6 = /* @__PURE__ */ template(`<label class="h-full flex items-center">`);
11
+ const EditablePlugin = {
12
+ store: () => ({ editors: { ...editors } }),
13
+ rewriteProps: { Td: ({ Td }, { store }) => (o) => {
14
+ let el;
15
+ const { props } = useContext(Ctx);
16
+ const editable = createMemo(() => !!o.col.editable && !o.data[store.internal] && !o.col[store.internal]);
17
+ const [editing, setEditing] = createSignal(false);
18
+ let eventKey = "";
19
+ const selected = createMemo(() => (([x, y]) => o.x == x && o.y == y)(store.selected.start || []));
20
+ const preEdit = createMemo(() => selected() && editable() && !editing() && o.col.editOnInput);
21
+ const editorState = createAsyncMemo(async () => {
22
+ if (editing()) {
23
+ let canceled = false;
24
+ const editor = ((editor$1) => typeof editor$1 == "string" ? store.editors[editor$1] : editor$1)(o.col.editor || "text");
25
+ const opt = {
26
+ props: o.col.editorProps,
27
+ col: o.col,
28
+ eventKey,
29
+ data: o.data,
30
+ value: o.data[o.col.id],
31
+ ok: () => setEditing(false),
32
+ cancel: () => (canceled = true, setEditing(false))
33
+ };
34
+ const ret = editor(opt);
35
+ onCleanup(() => {
36
+ if (!canceled && ret.getValue() !== o.data[o.col.id]) {
37
+ const arr = [...props.data];
38
+ arr[o.y] = {
39
+ ...arr[o.y],
40
+ [o.col.id]: ret.getValue()
41
+ };
42
+ props.onDataChange?.(arr);
43
+ }
44
+ ret.destroy();
45
+ });
46
+ return [opt, ret];
47
+ }
48
+ });
49
+ createEffect(() => {
50
+ editorState()?.[1]?.focus?.();
51
+ });
52
+ createEffect(() => {
53
+ if (editing()) {
54
+ const sss = createMemo(() => JSON.stringify(store.selected));
55
+ createEffect(on(sss, () => setEditing(false), { defer: true }));
56
+ }
57
+ });
58
+ let input;
59
+ const size = createMutable({
60
+ w: 0,
61
+ h: 0
62
+ });
63
+ createComputed(() => editing() && (size.w = el.getBoundingClientRect().width, size.h = el.getBoundingClientRect().height));
64
+ o = combineProps(o, {
65
+ ref: (v) => el = v,
66
+ get class() {
67
+ return editing() ? "is-editing" : "";
68
+ },
69
+ get style() {
70
+ return editing() ? `width: ${size.w}px; height: ${size.h}px; padding: 0; ` : "";
71
+ },
72
+ onClick: () => input?.focus?.(),
73
+ onDblClick: () => setEditing(editable()),
74
+ onKeyDown: (e) => e.key == "Escape" && editorState()?.[0].cancel()
75
+ });
76
+ return createComponent(Td, mergeProps(o, { get children() {
77
+ return [memo(() => memo(() => !!preEdit())() && (() => {
78
+ var _el$ = _tmpl$();
79
+ _el$.addEventListener("compositionend", () => {
80
+ setEditing(true);
81
+ });
82
+ _el$.$$input = (e) => {
83
+ eventKey = e.target.value;
84
+ setEditing(!e.isComposing);
85
+ };
86
+ _el$.$$keydown = (e) => {
87
+ e.key == " " && e.preventDefault();
88
+ };
89
+ use((e) => {
90
+ input = e;
91
+ delay(0).then(() => e.focus({ preventScroll: true }));
92
+ }, _el$);
93
+ return _el$;
94
+ })()), memo(() => memo(() => !!editorState()?.[1]?.el)() ? (() => {
95
+ var _el$2 = _tmpl$2();
96
+ insert(_el$2, () => editorState()?.[1]?.el);
97
+ return _el$2;
98
+ })() : o.children)];
99
+ } }));
100
+ } }
101
+ };
102
+ var createEditor = (Comp, extra, isSelector) => ({ eventKey, value, col, ok, cancel, props }) => createRoot((destroy) => {
103
+ const [v, setV] = createSignal(eventKey || value);
104
+ let el;
105
+ createComponent(Comp, mergeProps({
106
+ ref: (e) => el = e,
107
+ "class": "relative block px-2 size-full z-9 box-border resize-none outline-0",
108
+ get value() {
109
+ return v();
110
+ },
111
+ onInput: (e) => setV(e instanceof Event ? e.target.value : e),
112
+ onChange: (e) => (setV(e instanceof Event ? e.target.value : e), isSelector && ok()),
113
+ "on:pointerdown": (e) => e.stopPropagation(),
114
+ "on:keydown": (e) => {
115
+ e.stopPropagation();
116
+ e.key == "Enter" && ok();
117
+ e.key == "Escape" && cancel();
118
+ },
119
+ get options() {
120
+ return memo(() => !!col.enum)() ? resolveOptions(col.enum ?? []) : void 0;
121
+ }
122
+ }, extra, props));
123
+ return {
124
+ el,
125
+ getValue: v,
126
+ focus: () => el.focus(),
127
+ destroy
128
+ };
129
+ });
130
+ var Input = (o) => (() => {
131
+ var _el$3 = _tmpl$3();
132
+ spread(_el$3, o, false, false);
133
+ return _el$3;
134
+ })();
135
+ var text = createEditor(Input);
136
+ var number = createEditor(Input, { type: "number" });
137
+ var range$1 = createEditor(Input, { type: "range" });
138
+ var color = createEditor(Input, { type: "color" });
139
+ var tel = createEditor(Input, { type: "tel" });
140
+ var password = createEditor(Input, { type: "password" });
141
+ var date = createEditor(Input, { type: "date" }, true);
142
+ var time = createEditor(Input, { type: "time" }, true);
143
+ var datetime = createEditor(Input, { type: "datetime-local" }, true);
144
+ var select = createEditor((o) => (() => {
145
+ var _el$4 = _tmpl$4();
146
+ spread(_el$4, o, false, true);
147
+ insert(_el$4, () => o.options?.map((e) => (() => {
148
+ var _el$5 = _tmpl$5();
149
+ insert(_el$5, () => e.label);
150
+ effect(() => _el$5.value = e.value);
151
+ return _el$5;
152
+ })()));
153
+ return _el$4;
154
+ })(), {}, true);
155
+ var file = createEditor((o) => {
156
+ const onAdd = () => chooseFile({ multiple: true }).then((files) => o.onChange([...o.value || [], ...files.map((e) => ({
157
+ name: e.name,
158
+ size: e.size
159
+ }))]));
160
+ return createComponent(Files, mergeProps(o, {
161
+ "class": "relative z-9 outline-2 outline-blue min-h-a! h-a! p-1 bg-#fff",
162
+ onAdd
163
+ }));
164
+ });
165
+ var checkbox = createEditor((o) => (() => {
166
+ var _el$6 = _tmpl$6();
167
+ var _ref$ = o.ref;
168
+ typeof _ref$ === "function" ? use(_ref$, _el$6) : o.ref = _el$6;
169
+ insert(_el$6, createComponent(Checkbox, mergeProps(o, {
170
+ ref: () => {},
171
+ onInput: () => {},
172
+ "class": "mx-3!"
173
+ })));
174
+ return _el$6;
175
+ })());
176
+ const editors = {
177
+ text,
178
+ number,
179
+ range: range$1,
180
+ date,
181
+ time,
182
+ datetime,
183
+ color,
184
+ tel,
185
+ password,
186
+ file,
187
+ checkbox,
188
+ select
189
+ };
190
+ delegateEvents(["keydown", "input"]);
191
+ export { EditablePlugin, editors };
@@ -0,0 +1,20 @@
1
+ import type { JSX } from 'solid-js';
2
+ import { type Plugin } from '..';
3
+ declare module '../index' {
4
+ interface TableProps {
5
+ expand?: {
6
+ enable?: boolean;
7
+ render?: (props: {
8
+ data: any;
9
+ y: number;
10
+ }) => JSX.Element;
11
+ };
12
+ }
13
+ interface TableStore {
14
+ expands: any[];
15
+ expandCol: TableColumn;
16
+ isExpand: (data: any) => boolean;
17
+ toggleExpand: (data: any) => void;
18
+ }
19
+ }
20
+ export declare const ExpandPlugin: Plugin;
@@ -0,0 +1,56 @@
1
+ import { renderComponent, solidComponent } from "../components/utils.js";
2
+ import { Ctx } from "../index.js";
3
+ import chevron_right_default from "../chevron-right.js";
4
+ import { createComponent, effect, insert, memo, mergeProps, setAttribute, template } from "solid-js/web";
5
+ import { createMemo, useContext } from "solid-js";
6
+ import { unwrap } from "solid-js/store";
7
+ import { remove } from "es-toolkit";
8
+ var _tmpl$ = /* @__PURE__ */ template(`<td style=width:100%>`), _tmpl$2 = /* @__PURE__ */ template(`<div style=display:flex;align-items:center;width:100%;height:100%;opacity:.4>`);
9
+ const ExpandPlugin = {
10
+ store: (store) => ({
11
+ expands: [],
12
+ expandCol: {
13
+ id: Symbol("expand"),
14
+ fixed: "left",
15
+ width: 45,
16
+ render: solidComponent((o) => createComponent(ArrowCell, {
17
+ store,
18
+ get data() {
19
+ return o.data;
20
+ }
21
+ })),
22
+ props: (o) => ({ onClick: () => store.toggleExpand(o.data) }),
23
+ [store.internal]: 1
24
+ },
25
+ isExpand: (data) => !!store.expands.find((e) => unwrap(e) == unwrap(data)),
26
+ toggleExpand: (data) => store.isExpand(data) ? remove(store.expands, (e) => unwrap(e) == unwrap(data)) : store.expands.push(unwrap(data))
27
+ }),
28
+ rewriteProps: {
29
+ columns: ({ columns }, { store }) => [store.expandCol, ...columns],
30
+ Tr: ({ Tr }, { store }) => (o) => {
31
+ const { props } = useContext(Ctx);
32
+ if (!o.data?.[store.expandCol.id]) return createComponent(Tr, o);
33
+ return createComponent(Tr, mergeProps(o, { get children() {
34
+ var _el$ = _tmpl$();
35
+ insert(_el$, (() => {
36
+ var _c$ = memo(() => !!props.expand?.render);
37
+ return () => _c$() && renderComponent(props.expand.render, o, props.renderer);
38
+ })());
39
+ effect(() => setAttribute(_el$, "colspan", props.columns?.length));
40
+ return _el$;
41
+ } }));
42
+ },
43
+ data: ({ data }, { store }) => store.expands.length ? data?.flatMap((e) => store.isExpand(e) ? [e, { [store.expandCol.id]: 1 }] : e) : data
44
+ }
45
+ };
46
+ var ArrowCell = (_props) => {
47
+ const show = createMemo(() => _props.store.isExpand(_props.data));
48
+ return (() => {
49
+ var _el$2 = _tmpl$2();
50
+ insert(_el$2, createComponent(chevron_right_default, { get style() {
51
+ return `transform: rotate(${show() ? 90 : 0}deg);`;
52
+ } }));
53
+ return _el$2;
54
+ })();
55
+ };
56
+ export { ExpandPlugin };