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.
- package/LICENSE +21 -0
- package/README.md +22 -0
- package/dist/chevron-right.js +8 -0
- package/dist/components/Columns.d.ts +3 -0
- package/dist/components/Columns.js +105 -0
- package/dist/components/DocTree.d.ts +4 -0
- package/dist/components/DocTree.js +40 -0
- package/dist/components/Menu.d.ts +1 -0
- package/dist/components/Menu.js +131 -0
- package/dist/components/Popover.d.ts +14 -0
- package/dist/components/Popover.js +49 -0
- package/dist/components/Render.d.ts +4 -0
- package/dist/components/Render.js +21 -0
- package/dist/components/Split.d.ts +15 -0
- package/dist/components/Split.js +88 -0
- package/dist/components/Tree.d.ts +37 -0
- package/dist/components/Tree.js +101 -0
- package/dist/components/utils.d.ts +3 -0
- package/dist/components/utils.js +10 -0
- package/dist/demo.d.ts +2 -0
- package/dist/demo.js +64 -0
- package/dist/hooks/index.d.ts +38 -0
- package/dist/hooks/index.js +182 -0
- package/dist/hooks/useDir.d.ts +11 -0
- package/dist/hooks/useDir.js +59 -0
- package/dist/hooks/useVirtualizer.d.ts +25 -0
- package/dist/hooks/useVirtualizer.js +92 -0
- package/dist/index.d.ts +116 -0
- package/dist/index.js +348 -0
- package/dist/intable.css +277 -0
- package/dist/loading.js +8 -0
- package/dist/plugins/CellChangeHighlightPlugin.d.ts +2 -0
- package/dist/plugins/CellChangeHighlightPlugin.js +4 -0
- package/dist/plugins/CellSelectionPlugin.d.ts +15 -0
- package/dist/plugins/CellSelectionPlugin.js +150 -0
- package/dist/plugins/CommandPlugin.d.ts +14 -0
- package/dist/plugins/CommandPlugin.js +9 -0
- package/dist/plugins/CopyPastePlugin.d.ts +14 -0
- package/dist/plugins/CopyPastePlugin.js +54 -0
- package/dist/plugins/DiffPlugin.d.ts +23 -0
- package/dist/plugins/DiffPlugin.js +68 -0
- package/dist/plugins/DragColumnPlugin.d.ts +2 -0
- package/dist/plugins/DragColumnPlugin.js +4 -0
- package/dist/plugins/EditablePlugin.d.ts +49 -0
- package/dist/plugins/EditablePlugin.js +191 -0
- package/dist/plugins/ExpandPlugin.d.ts +20 -0
- package/dist/plugins/ExpandPlugin.js +56 -0
- package/dist/plugins/HistoryPlugin.d.ts +10 -0
- package/dist/plugins/HistoryPlugin.js +35 -0
- package/dist/plugins/MenuPlugin.d.ts +18 -0
- package/dist/plugins/MenuPlugin.js +131 -0
- package/dist/plugins/RenderPlugin/components.d.ts +5 -0
- package/dist/plugins/RenderPlugin/components.js +105 -0
- package/dist/plugins/RenderPlugin/index.d.ts +30 -0
- package/dist/plugins/RenderPlugin/index.js +61 -0
- package/dist/plugins/ResizePlugin.d.ts +27 -0
- package/dist/plugins/ResizePlugin.js +103 -0
- package/dist/plugins/RowGroupPlugin.d.ts +17 -0
- package/dist/plugins/RowGroupPlugin.js +99 -0
- package/dist/plugins/RowSelectionPlugin.d.ts +32 -0
- package/dist/plugins/RowSelectionPlugin.js +69 -0
- package/dist/plugins/VirtualScrollPlugin.d.ts +15 -0
- package/dist/plugins/VirtualScrollPlugin.js +121 -0
- package/dist/plus.js +8 -0
- package/dist/types/auto-imports.d.js +0 -0
- package/dist/utils.d.ts +29 -0
- package/dist/utils.js +88 -0
- package/dist/vite.svg +1 -0
- package/dist/wc.d.ts +1 -0
- package/dist/wc.js +24 -0
- package/dist/web-component.d.ts +1 -0
- package/dist/web-component.js +2 -0
- package/dist/x.js +8 -0
- package/package.json +71 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { createComponent } from "solid-js/web";
|
|
2
|
+
function solidComponent(comp) {
|
|
3
|
+
comp.__solid = 1;
|
|
4
|
+
return comp;
|
|
5
|
+
}
|
|
6
|
+
function renderComponent(Comp, props, renderer) {
|
|
7
|
+
if (!Comp.__solid) Comp = renderer(Comp);
|
|
8
|
+
return createComponent(Comp, props);
|
|
9
|
+
}
|
|
10
|
+
export { renderComponent, solidComponent };
|
package/dist/demo.d.ts
ADDED
package/dist/demo.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { log } from "./utils.js";
|
|
2
|
+
import { Table } from "./index.js";
|
|
3
|
+
/* empty css */
|
|
4
|
+
/* empty css */
|
|
5
|
+
import { VirtualScrollPlugin } from "./plugins/VirtualScrollPlugin.js";
|
|
6
|
+
import { createComponent, delegateEvents, effect, insert, render, template } from "solid-js/web";
|
|
7
|
+
import { batch } from "solid-js";
|
|
8
|
+
import { createMutable, reconcile } from "solid-js/store";
|
|
9
|
+
import { range } from "es-toolkit";
|
|
10
|
+
var _tmpl$ = /* @__PURE__ */ template(`<input type=checkbox>`), _tmpl$2 = /* @__PURE__ */ template(`<button>xxx`), _tmpl$3 = /* @__PURE__ */ template(`<div class=p-6>`);
|
|
11
|
+
var root = document.getElementById("root");
|
|
12
|
+
var state = createMutable({ bool: true });
|
|
13
|
+
var cols = createMutable(range(5).map((e) => ({
|
|
14
|
+
name: "col_" + e,
|
|
15
|
+
id: "col_" + e,
|
|
16
|
+
width: 80
|
|
17
|
+
})));
|
|
18
|
+
var data = createMutable(range(100).map((e, i) => Object.fromEntries(cols.map((e$1) => [e$1.id, i + 1]))));
|
|
19
|
+
render(() => (() => {
|
|
20
|
+
var _el$ = _tmpl$();
|
|
21
|
+
_el$.addEventListener("change", (e) => state.bool = e.currentTarget.checked);
|
|
22
|
+
effect(() => _el$.checked = state.bool);
|
|
23
|
+
return _el$;
|
|
24
|
+
})(), root);
|
|
25
|
+
render(() => (() => {
|
|
26
|
+
var _el$2 = _tmpl$2();
|
|
27
|
+
_el$2.$$click = () => data[0].col_1 = "xxx";
|
|
28
|
+
return _el$2;
|
|
29
|
+
})(), root);
|
|
30
|
+
cols[0].editor = "select";
|
|
31
|
+
cols[0].enum = {
|
|
32
|
+
1: 1,
|
|
33
|
+
2: 2,
|
|
34
|
+
3: 3
|
|
35
|
+
};
|
|
36
|
+
cols.forEach((e) => (e.editable = true, e.editOnInput = true));
|
|
37
|
+
cols.at(-3).width = void 0;
|
|
38
|
+
cols.at(-1).width = void 0;
|
|
39
|
+
data.forEach((e) => e.g = e.col_0 % 10);
|
|
40
|
+
data.forEach((e) => e.n = e.col_0 % 3);
|
|
41
|
+
render(() => createComponent(Table, {
|
|
42
|
+
"class": "w-50vw! h-40vh of-auto",
|
|
43
|
+
get index() {
|
|
44
|
+
return state.bool;
|
|
45
|
+
},
|
|
46
|
+
get stickyHeader() {
|
|
47
|
+
return state.bool;
|
|
48
|
+
},
|
|
49
|
+
columns: cols,
|
|
50
|
+
onColumnsChange: (o) => reconcile(o)(cols),
|
|
51
|
+
data,
|
|
52
|
+
border: true,
|
|
53
|
+
plugins: [VirtualScrollPlugin],
|
|
54
|
+
onDataChange: (v) => batch(() => (data.length = 0, data.push(...v))),
|
|
55
|
+
expand: { render: ({ data: data$1 }) => (() => {
|
|
56
|
+
var _el$3 = _tmpl$3();
|
|
57
|
+
insert(_el$3, () => JSON.stringify(data$1));
|
|
58
|
+
return _el$3;
|
|
59
|
+
})() },
|
|
60
|
+
diff: { onCommit: (...arg) => log(arg) },
|
|
61
|
+
virtual: {},
|
|
62
|
+
rowSelection: {}
|
|
63
|
+
}), root);
|
|
64
|
+
delegateEvents(["click"]);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type Signal } from 'solid-js';
|
|
2
|
+
import { type Many, type MaybeAccessor } from '@solid-primitives/utils';
|
|
3
|
+
interface UseDragOptions {
|
|
4
|
+
start?(e: PointerEvent, move: (cb: MoveCB) => void, end: (cb: EndCb) => void): void;
|
|
5
|
+
}
|
|
6
|
+
type MoveCB = (e: PointerEvent, o: {
|
|
7
|
+
sx: number;
|
|
8
|
+
sy: number;
|
|
9
|
+
ox: number;
|
|
10
|
+
oy: number;
|
|
11
|
+
}) => void;
|
|
12
|
+
type EndCb = (e: PointerEvent) => void;
|
|
13
|
+
export declare function usePointerDrag(el: MaybeAccessor<HTMLElement | undefined>, options: UseDragOptions): void;
|
|
14
|
+
export declare function model(el: any, value: () => [() => string, (v: string) => any]): void;
|
|
15
|
+
export declare function toSignle<T extends Record<string, any>>(state: T, k: keyof T): ((v: any) => any)[];
|
|
16
|
+
export declare function useDark(): [get: import("solid-js").Accessor<boolean>, set: import("solid-js").Setter<boolean>, init: string | Promise<string> | null];
|
|
17
|
+
export declare function useMemoAsync<T>(fn: (prev?: T) => Promise<T> | T, init?: Awaited<T>): import("solid-js").Accessor<Awaited<T> | undefined>;
|
|
18
|
+
export declare function useSignle2<T>(v: T | (() => T), opt?: {
|
|
19
|
+
before?: (v: T) => Promise<T | void> | T;
|
|
20
|
+
}): Signal<T>;
|
|
21
|
+
type Reactive<T extends object> = {
|
|
22
|
+
[K in keyof T]: T[K] extends () => infer V ? V : T[K];
|
|
23
|
+
};
|
|
24
|
+
export declare function toReactive<T extends object>(fn: (() => T) | T): Reactive<T>;
|
|
25
|
+
export declare function useMemo<T>(fn: () => T): import("solid-js").Accessor<T>;
|
|
26
|
+
export declare function useHover(el: MaybeAccessor<Many<HTMLElement | undefined>>): import("solid-js").Accessor<boolean>;
|
|
27
|
+
export declare function useMouseDown(el: MaybeAccessor<Many<HTMLElement | undefined>>): import("solid-js").Accessor<boolean>;
|
|
28
|
+
export declare function useClicked(el: MaybeAccessor<Many<HTMLElement | undefined>>): import("solid-js").Accessor<boolean>;
|
|
29
|
+
export declare function useMutation<T>(initial: MaybeAccessor<Node | Node[]>, options: MutationObserverInit, cb: () => T): import("solid-js").Accessor<T>;
|
|
30
|
+
export declare function useTinykeys(el: MaybeAccessor<HTMLElement | undefined>, handlers: any): void;
|
|
31
|
+
export declare function useHistory([val, setVal]: [any, any]): {
|
|
32
|
+
undo: () => any;
|
|
33
|
+
redo: () => any;
|
|
34
|
+
clear: () => any[];
|
|
35
|
+
readonly index: number;
|
|
36
|
+
readonly history: any[];
|
|
37
|
+
};
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { unFn } from "../utils.js";
|
|
2
|
+
import { $PROXY, createComputed, createEffect, createMemo, createRenderEffect, createRoot, createSignal, on, onCleanup } from "solid-js";
|
|
3
|
+
import { $RAW, createMutable } from "solid-js/store";
|
|
4
|
+
import { isFunction, isPromise, mapValues } from "es-toolkit";
|
|
5
|
+
import { createEventListener } from "@solid-primitives/event-listener";
|
|
6
|
+
import { createPointerListeners } from "@solid-primitives/pointer";
|
|
7
|
+
import { access } from "@solid-primitives/utils";
|
|
8
|
+
import { makePersisted, storageSync } from "@solid-primitives/storage";
|
|
9
|
+
import { createMutationObserver } from "@solid-primitives/mutation-observer";
|
|
10
|
+
import { castArray } from "es-toolkit/compat";
|
|
11
|
+
import { createKeybindingsHandler } from "tinykeys";
|
|
12
|
+
function usePointerDrag(el, options) {
|
|
13
|
+
createPointerListeners({
|
|
14
|
+
target: el,
|
|
15
|
+
passive: false,
|
|
16
|
+
onDown(e) {
|
|
17
|
+
e.preventDefault();
|
|
18
|
+
const [sx, sy] = [e.x, e.y];
|
|
19
|
+
let move;
|
|
20
|
+
let end;
|
|
21
|
+
options.start?.(e, (cb) => move = cb, (cb) => end = cb);
|
|
22
|
+
createRoot((dispose) => {
|
|
23
|
+
createPointerListeners({
|
|
24
|
+
target: document,
|
|
25
|
+
onMove(e$1) {
|
|
26
|
+
const [ox, oy] = [e$1.x - sx, e$1.y - sy];
|
|
27
|
+
move?.(e$1, {
|
|
28
|
+
sx,
|
|
29
|
+
sy,
|
|
30
|
+
ox,
|
|
31
|
+
oy
|
|
32
|
+
});
|
|
33
|
+
},
|
|
34
|
+
onUp() {
|
|
35
|
+
end?.(e);
|
|
36
|
+
dispose();
|
|
37
|
+
move = void 0;
|
|
38
|
+
end = void 0;
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
function model(el, value) {
|
|
46
|
+
const [field, setField] = value();
|
|
47
|
+
createRenderEffect(() => el.value = field());
|
|
48
|
+
el.addEventListener("input", (e) => setField(e.target.value));
|
|
49
|
+
}
|
|
50
|
+
function toSignle(state, k) {
|
|
51
|
+
return [() => state[k], (v) => state[k] = v];
|
|
52
|
+
}
|
|
53
|
+
function useDark() {
|
|
54
|
+
const get = (v) => v == "dark" || prefersDark() && !v, set = (v) => v ? "dark" : "light";
|
|
55
|
+
const prefersDark = () => window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
56
|
+
const dark = makePersisted(createSignal(prefersDark()), {
|
|
57
|
+
name: "color-schema",
|
|
58
|
+
storage: localStorage,
|
|
59
|
+
sync: storageSync,
|
|
60
|
+
serialize: set,
|
|
61
|
+
deserialize: get
|
|
62
|
+
});
|
|
63
|
+
createEffect(() => document.documentElement.classList[dark[0]() ? "add" : "remove"]("dark"));
|
|
64
|
+
createEffect(() => window.dispatchEvent(new StorageEvent("storage", {
|
|
65
|
+
key: "color-schema",
|
|
66
|
+
newValue: set(dark[0]())
|
|
67
|
+
})));
|
|
68
|
+
return dark;
|
|
69
|
+
}
|
|
70
|
+
function useMemoAsync(fn, init) {
|
|
71
|
+
const REJECT = Symbol();
|
|
72
|
+
const [val, setVal] = createSignal(init);
|
|
73
|
+
createComputed(async () => {
|
|
74
|
+
const ret = fn(val());
|
|
75
|
+
const v = ret instanceof Promise ? await new Promise((resolve) => {
|
|
76
|
+
ret.then(resolve);
|
|
77
|
+
onCleanup(() => resolve(REJECT));
|
|
78
|
+
}) : ret;
|
|
79
|
+
v == REJECT || setVal(() => v);
|
|
80
|
+
});
|
|
81
|
+
return val;
|
|
82
|
+
}
|
|
83
|
+
function useSignle2(v, opt) {
|
|
84
|
+
const state = createSignal(isFunction(v) ? void 0 : v);
|
|
85
|
+
const before = (v$1) => {
|
|
86
|
+
const v2 = opt?.before?.(v$1);
|
|
87
|
+
return isPromise(v2) ? v2.then((v3) => v3 === void 0 ? v$1 : v3) : v2 ?? v$1;
|
|
88
|
+
};
|
|
89
|
+
const val = useMemoAsync(() => before(state[0]()));
|
|
90
|
+
if (isFunction(v)) {
|
|
91
|
+
const fned = useMemoAsync(() => before(v()));
|
|
92
|
+
createComputed(() => state[1](fned()));
|
|
93
|
+
}
|
|
94
|
+
return [val, state[1]];
|
|
95
|
+
}
|
|
96
|
+
var $MEMO = Symbol();
|
|
97
|
+
function toReactive(fn) {
|
|
98
|
+
const v = () => unFn(fn);
|
|
99
|
+
const trueFn = () => true;
|
|
100
|
+
const get = (k) => ((e) => typeof e == "function" && $MEMO in e ? e() : e)(v()[k]);
|
|
101
|
+
return new Proxy(Object.create(null), {
|
|
102
|
+
get: (o, k, r) => k == $PROXY ? r : k == $RAW ? r : ((v$1) => typeof v$1 == "function" && $MEMO in v$1 ? v$1() : v$1)(v()[k]),
|
|
103
|
+
set: trueFn,
|
|
104
|
+
defineProperty: (o, k, attributes) => Object.defineProperty(v(), k, attributes),
|
|
105
|
+
deleteProperty: trueFn,
|
|
106
|
+
getPrototypeOf: () => Object.getPrototypeOf(v()),
|
|
107
|
+
has: (o, p) => p == $PROXY || p in v(),
|
|
108
|
+
ownKeys: (o) => Object.keys(v()),
|
|
109
|
+
getOwnPropertyDescriptor: (o, k) => ({
|
|
110
|
+
enumerable: true,
|
|
111
|
+
configurable: true,
|
|
112
|
+
get() {
|
|
113
|
+
return get(k);
|
|
114
|
+
},
|
|
115
|
+
set: trueFn
|
|
116
|
+
})
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
function useMemo(fn) {
|
|
120
|
+
const ret = createMemo(fn);
|
|
121
|
+
ret[$MEMO] = 1;
|
|
122
|
+
return ret;
|
|
123
|
+
}
|
|
124
|
+
function useHover(el) {
|
|
125
|
+
const [hover, setHover] = createSignal(false);
|
|
126
|
+
createEventListener(el, "pointerenter", () => setHover(true));
|
|
127
|
+
createEventListener(el, "pointerleave", () => setHover(false));
|
|
128
|
+
return hover;
|
|
129
|
+
}
|
|
130
|
+
function useMouseDown(el) {
|
|
131
|
+
const [down, setDown] = createSignal(false);
|
|
132
|
+
createEventListener(el, "pointerdown", () => setDown(true));
|
|
133
|
+
createEventListener(document.body, "pointerup", () => setDown(false));
|
|
134
|
+
return down;
|
|
135
|
+
}
|
|
136
|
+
function useClicked(el) {
|
|
137
|
+
const [clicked, setClicked] = createSignal(false);
|
|
138
|
+
const els = () => castArray(access(el));
|
|
139
|
+
createEventListener(() => els().map((e) => e?.getRootNode()), "click", (e) => setClicked(els().some((el$1) => el$1?.contains(e.target))));
|
|
140
|
+
return clicked;
|
|
141
|
+
}
|
|
142
|
+
function useMutation(initial, options, cb) {
|
|
143
|
+
const ret = createSignal(cb());
|
|
144
|
+
createMutationObserver(initial, options, (ms) => ret[1](cb()));
|
|
145
|
+
return ret[0];
|
|
146
|
+
}
|
|
147
|
+
function useTinykeys(el, handlers) {
|
|
148
|
+
createEventListener(el, "keydown", createKeybindingsHandler({ ...mapValues(handlers, (cb) => (e) => {
|
|
149
|
+
e.preventDefault();
|
|
150
|
+
cb(e);
|
|
151
|
+
}) }));
|
|
152
|
+
}
|
|
153
|
+
function useHistory([val, setVal]) {
|
|
154
|
+
let bool = 1;
|
|
155
|
+
const state = createMutable({
|
|
156
|
+
index: -1,
|
|
157
|
+
history: []
|
|
158
|
+
});
|
|
159
|
+
const clear = () => (state.index = 0, state.history = [val()]);
|
|
160
|
+
const canUndo = () => state.index > 0;
|
|
161
|
+
const canRedo = () => state.index < state.history.length - 1;
|
|
162
|
+
const undo = () => canUndo() && ((bool = 0) || setVal(state.history[--state.index]));
|
|
163
|
+
const redo = () => canRedo() && ((bool = 0) || setVal(state.history[++state.index]));
|
|
164
|
+
createRenderEffect(on(val, (ret) => {
|
|
165
|
+
if (ret == null) return;
|
|
166
|
+
if (!bool) return bool = 1;
|
|
167
|
+
if (canRedo()) state.history = state.history.slice(0, state.index + 1);
|
|
168
|
+
state.history[++state.index] = ret;
|
|
169
|
+
}));
|
|
170
|
+
return {
|
|
171
|
+
undo,
|
|
172
|
+
redo,
|
|
173
|
+
clear,
|
|
174
|
+
get index() {
|
|
175
|
+
return state.index;
|
|
176
|
+
},
|
|
177
|
+
get history() {
|
|
178
|
+
return state.history;
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
export { model, toReactive, toSignle, useClicked, useDark, useHistory, useHover, useMemo, useMemoAsync, useMouseDown, useMutation, usePointerDrag, useSignle2, useTinykeys };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type MaybeAccessor } from '@solid-primitives/utils';
|
|
2
|
+
interface UseDirOptions {
|
|
3
|
+
ref: MaybeAccessor<HTMLElement | undefined>;
|
|
4
|
+
list?: MaybeAccessor<HTMLElement | undefined>;
|
|
5
|
+
loop?: boolean;
|
|
6
|
+
options?: EventListenerOptions;
|
|
7
|
+
defaultFirst?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function useDir(options: UseDirOptions): void;
|
|
10
|
+
export declare function VDir(el: HTMLElement, options: any): void;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { createEffect, mergeProps } from "solid-js";
|
|
2
|
+
import { createEventListener } from "@solid-primitives/event-listener";
|
|
3
|
+
import { access } from "@solid-primitives/utils";
|
|
4
|
+
import { createMutationObserver } from "@solid-primitives/mutation-observer";
|
|
5
|
+
function useDir(options) {
|
|
6
|
+
options = mergeProps({ loop: true }, options);
|
|
7
|
+
const list = () => access(options.list) ?? access(options.ref);
|
|
8
|
+
const ref = () => access(options.ref) ?? access(options.list);
|
|
9
|
+
createEffect(() => {
|
|
10
|
+
if (ref().tabIndex > -1) return;
|
|
11
|
+
ref().tabIndex = 0;
|
|
12
|
+
});
|
|
13
|
+
createEventListener(ref, "keydown", (e) => {
|
|
14
|
+
if (![
|
|
15
|
+
"ArrowDown",
|
|
16
|
+
"ArrowUp",
|
|
17
|
+
"Enter"
|
|
18
|
+
].includes(e.key)) return;
|
|
19
|
+
e.stopPropagation();
|
|
20
|
+
e.preventDefault();
|
|
21
|
+
let hover = list()?.querySelector(".hover");
|
|
22
|
+
if (e.key == "Enter") {
|
|
23
|
+
hover?.click();
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
let index = e.key == "ArrowDown" ? hover ? +hover?.getAttribute("data-index") + 1 : 0 : e.key == "ArrowUp" ? hover ? +hover?.getAttribute("data-index") - 1 : -1 : 0;
|
|
27
|
+
const el = list()?.querySelector(`[data-index='${index}']`);
|
|
28
|
+
if (!el) {
|
|
29
|
+
if (options.loop) {
|
|
30
|
+
hover?.classList.remove("hover");
|
|
31
|
+
index >= 0 ? list()?.querySelector(`[data-index='0']`)?.classList.add("hover") : [...list()?.querySelectorAll(`[data-index]`)].at(-1)?.classList.add("hover");
|
|
32
|
+
}
|
|
33
|
+
} else {
|
|
34
|
+
hover?.classList.remove("hover");
|
|
35
|
+
el.classList.add("hover");
|
|
36
|
+
}
|
|
37
|
+
}, options.options);
|
|
38
|
+
createEffect(() => {
|
|
39
|
+
if (!options.defaultFirst) return;
|
|
40
|
+
const el = list();
|
|
41
|
+
if (!el) return;
|
|
42
|
+
const hover = () => {
|
|
43
|
+
if (el.querySelector(".hover")) return;
|
|
44
|
+
el.querySelector(`[data-index]`)?.classList.add("hover");
|
|
45
|
+
};
|
|
46
|
+
createMutationObserver(el, { childList: true }, hover);
|
|
47
|
+
hover();
|
|
48
|
+
});
|
|
49
|
+
createEventListener(list, "mouseover", () => {
|
|
50
|
+
list()?.querySelector(".hover")?.classList.remove("hover");
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function VDir(el, options) {
|
|
54
|
+
useDir({
|
|
55
|
+
...options(),
|
|
56
|
+
list: el
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
export { VDir, useDir };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
interface VirtualizerOptions {
|
|
2
|
+
enable?: boolean;
|
|
3
|
+
overscan?: number;
|
|
4
|
+
batch?: number;
|
|
5
|
+
getScrollElement: () => Element;
|
|
6
|
+
horizontal?: boolean;
|
|
7
|
+
count: number;
|
|
8
|
+
estimateSize: (i: number) => number;
|
|
9
|
+
}
|
|
10
|
+
export declare function useVirtualizer(opt: VirtualizerOptions): {
|
|
11
|
+
options: VirtualizerOptions;
|
|
12
|
+
getTotalSize: () => number;
|
|
13
|
+
resizeItem: (i: any, size: any) => void;
|
|
14
|
+
getVirtualItems: import("solid-js").Accessor<{
|
|
15
|
+
start: number;
|
|
16
|
+
end: number;
|
|
17
|
+
index: number;
|
|
18
|
+
}[]>;
|
|
19
|
+
getVirtualItem: (i: any) => {
|
|
20
|
+
start: number;
|
|
21
|
+
end: number;
|
|
22
|
+
index: number;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { createComputed, createMemo, createRenderEffect, createSignal, mergeProps, untrack } from "solid-js";
|
|
2
|
+
import { createMutable } from "solid-js/store";
|
|
3
|
+
import { keyBy, uniqBy } from "es-toolkit";
|
|
4
|
+
import { createElementSize } from "@solid-primitives/resize-observer";
|
|
5
|
+
import { createScrollPosition } from "@solid-primitives/scroll";
|
|
6
|
+
function useVirtualizer(opt) {
|
|
7
|
+
opt = mergeProps({
|
|
8
|
+
overscan: 0,
|
|
9
|
+
batch: 0,
|
|
10
|
+
enable: true
|
|
11
|
+
}, opt);
|
|
12
|
+
const size = createElementSize(opt.getScrollElement);
|
|
13
|
+
const pos = createScrollPosition(opt.getScrollElement);
|
|
14
|
+
const y = createMemo(() => opt.horizontal ? pos.x : pos.y);
|
|
15
|
+
const h = createMemo(() => opt.horizontal ? size.width : size.height);
|
|
16
|
+
const y2 = createMemo(() => y() + h());
|
|
17
|
+
const sizes = createMutable(Array(opt.count));
|
|
18
|
+
createComputed(() => {
|
|
19
|
+
const { count } = opt;
|
|
20
|
+
untrack(() => {
|
|
21
|
+
for (let i = 0; i < count; i++) sizes[i] ||= opt.estimateSize(i);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
const [items, setItems] = createSignal([]);
|
|
25
|
+
createRenderEffect(() => {
|
|
26
|
+
const { count } = opt;
|
|
27
|
+
let arr = Array(count);
|
|
28
|
+
let t = 0;
|
|
29
|
+
for (let i = 0; i < count; i++) {
|
|
30
|
+
arr[i] = {
|
|
31
|
+
start: t,
|
|
32
|
+
end: t + sizes[i],
|
|
33
|
+
index: i
|
|
34
|
+
};
|
|
35
|
+
t = arr[i].end;
|
|
36
|
+
}
|
|
37
|
+
setItems(arr);
|
|
38
|
+
});
|
|
39
|
+
const start = createMemo((prev) => {
|
|
40
|
+
const { batch: batch$1, overscan = 0 } = opt;
|
|
41
|
+
let i = findClosestIndex(items(), (e) => e.start > y() ? -1 : e.end < y() ? 1 : 0);
|
|
42
|
+
i -= overscan;
|
|
43
|
+
if (batch$1) if (i > prev) i = i <= prev + batch$1 ? prev : i > prev + batch$1 * 2 ? i : prev + batch$1;
|
|
44
|
+
else i -= batch$1;
|
|
45
|
+
return Math.max(i, 0);
|
|
46
|
+
}, 0);
|
|
47
|
+
const end = createMemo((prev) => {
|
|
48
|
+
const { batch: batch$1, overscan = 0 } = opt;
|
|
49
|
+
let i = findClosestIndex(items(), (e) => e.start > y2() ? -1 : e.end < y2() ? 1 : 0);
|
|
50
|
+
i += overscan;
|
|
51
|
+
if (batch$1) if (i < prev) i = i >= prev - batch$1 ? prev : i < prev - batch$1 * 2 ? i : prev - batch$1;
|
|
52
|
+
else i += batch$1;
|
|
53
|
+
return Math.min(i, opt.count - 1);
|
|
54
|
+
}, 0);
|
|
55
|
+
const items2 = createMemo(() => {
|
|
56
|
+
if (!opt.enable) return items();
|
|
57
|
+
let arr = items().slice(start(), end() + 1);
|
|
58
|
+
if (opt.extras) {
|
|
59
|
+
arr.push(...opt.extras()?.map((i) => items()[i]) || []);
|
|
60
|
+
arr = uniqBy(arr, (e) => e.index).sort((a, b) => a.index - b.index);
|
|
61
|
+
}
|
|
62
|
+
return arr;
|
|
63
|
+
});
|
|
64
|
+
function findClosestIndex(arr, fn) {
|
|
65
|
+
let l = 0, r = arr.length - 1;
|
|
66
|
+
while (l < r) {
|
|
67
|
+
const m = l + Math.floor((r - l) / 2);
|
|
68
|
+
const v = fn(arr[m]);
|
|
69
|
+
if (v < 0 && r != m) r = m;
|
|
70
|
+
else if (v > 0 && l != m) l = m;
|
|
71
|
+
else return m;
|
|
72
|
+
}
|
|
73
|
+
return l;
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
options: opt,
|
|
77
|
+
getTotalSize: () => items()[items().length - 1]?.end || 0,
|
|
78
|
+
resizeItem: (i, size$1) => {
|
|
79
|
+
if (i <= start() && size$1 != sizes[i]) {
|
|
80
|
+
const el = opt.getScrollElement();
|
|
81
|
+
if ((opt.horizontal ? el.scrollLeft : el.scrollTop) != 0) opt.horizontal ? el.scrollLeft += size$1 - sizes[i] : el.scrollTop += size$1 - sizes[i];
|
|
82
|
+
}
|
|
83
|
+
sizes[i] = size$1;
|
|
84
|
+
},
|
|
85
|
+
getVirtualItems: items2,
|
|
86
|
+
getVirtualItem: (() => {
|
|
87
|
+
const keybyed = createMemo(() => keyBy(items2(), (e) => e.index));
|
|
88
|
+
return (i) => keybyed()[i];
|
|
89
|
+
})()
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
export { useVirtualizer };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { For, type JSX, type Component } from 'solid-js';
|
|
2
|
+
import './styles/index.scss';
|
|
3
|
+
import './plugins/CellSelectionPlugin';
|
|
4
|
+
import './plugins/CopyPastePlugin';
|
|
5
|
+
import './plugins/EditablePlugin';
|
|
6
|
+
import './plugins/RenderPlugin';
|
|
7
|
+
import './plugins/MenuPlugin';
|
|
8
|
+
import './plugins/CommandPlugin';
|
|
9
|
+
import './plugins/RowSelectionPlugin';
|
|
10
|
+
import './plugins/ResizePlugin';
|
|
11
|
+
export declare const Ctx: import("solid-js").Context<{
|
|
12
|
+
props: TableProps2;
|
|
13
|
+
}>;
|
|
14
|
+
type Requireds<T, K extends keyof T> = Pri<Omit<T, K> & Required<Pick<T, K>>>;
|
|
15
|
+
type Pri<T> = {
|
|
16
|
+
[K in keyof T]: T[K];
|
|
17
|
+
};
|
|
18
|
+
type TableProps2 = Requireds<TableProps, ('Table' | 'Thead' | 'Tbody' | 'Tr' | 'Th' | 'Td' | 'EachRows' | 'EachCells' | 'rowKey' | 'data' | 'columns' | 'newRow')>;
|
|
19
|
+
type ProcessProps = {
|
|
20
|
+
[K in keyof TableProps]?: (prev: TableProps2, ctx: {
|
|
21
|
+
store: TableStore;
|
|
22
|
+
}) => TableProps[K];
|
|
23
|
+
};
|
|
24
|
+
export interface Plugin {
|
|
25
|
+
priority?: number;
|
|
26
|
+
store?: (store: TableStore) => Partial<TableStore> | void;
|
|
27
|
+
rewriteProps?: ProcessProps;
|
|
28
|
+
layers?: Component<TableStore>[];
|
|
29
|
+
}
|
|
30
|
+
export interface TableProps {
|
|
31
|
+
columns?: TableColumn[];
|
|
32
|
+
data?: any[];
|
|
33
|
+
index?: boolean;
|
|
34
|
+
border?: boolean;
|
|
35
|
+
stickyHeader?: boolean;
|
|
36
|
+
class?: any;
|
|
37
|
+
style?: any;
|
|
38
|
+
rowKey?: any;
|
|
39
|
+
size?: string;
|
|
40
|
+
newRow?: (i: number) => any;
|
|
41
|
+
Table?: Component<any>;
|
|
42
|
+
Thead?: Component<any>;
|
|
43
|
+
Tbody?: Component<any>;
|
|
44
|
+
Td?: TD;
|
|
45
|
+
Th?: Component<THProps>;
|
|
46
|
+
Tr?: Component<{
|
|
47
|
+
y?: number;
|
|
48
|
+
data?: any;
|
|
49
|
+
children: JSX.Element;
|
|
50
|
+
}>;
|
|
51
|
+
EachRows?: typeof For;
|
|
52
|
+
EachCells?: typeof For<TableColumn[], JSX.Element>;
|
|
53
|
+
cellClass?: ((props: Omit<TDProps, 'y'> & {
|
|
54
|
+
y?: number;
|
|
55
|
+
}) => string) | string;
|
|
56
|
+
cellStyle?: ((props: Omit<TDProps, 'y'> & {
|
|
57
|
+
y?: number;
|
|
58
|
+
}) => string) | string;
|
|
59
|
+
renderer?: (comp: (props: any) => JSX.Element) => ((props: any) => JSX.Element);
|
|
60
|
+
plugins?: Plugin[];
|
|
61
|
+
onDataChange?: (data: any[]) => void;
|
|
62
|
+
}
|
|
63
|
+
type THProps = {
|
|
64
|
+
x: number;
|
|
65
|
+
col: TableColumn;
|
|
66
|
+
children: JSX.Element;
|
|
67
|
+
};
|
|
68
|
+
type TDProps = {
|
|
69
|
+
x: number;
|
|
70
|
+
y: number;
|
|
71
|
+
data: any;
|
|
72
|
+
col: TableColumn;
|
|
73
|
+
children: JSX.Element;
|
|
74
|
+
};
|
|
75
|
+
export type TD = Component<{
|
|
76
|
+
x: number;
|
|
77
|
+
y: number;
|
|
78
|
+
data: any;
|
|
79
|
+
col: TableColumn;
|
|
80
|
+
children: JSX.Element;
|
|
81
|
+
}>;
|
|
82
|
+
type Obj = Record<string | symbol, any>;
|
|
83
|
+
export interface TableColumn extends Obj {
|
|
84
|
+
id?: any;
|
|
85
|
+
name?: string;
|
|
86
|
+
width?: number;
|
|
87
|
+
fixed?: 'left' | 'right';
|
|
88
|
+
class?: any;
|
|
89
|
+
style?: any;
|
|
90
|
+
props?: (props: any) => JSX.HTMLAttributes<any>;
|
|
91
|
+
}
|
|
92
|
+
type Nullable<T> = T | undefined;
|
|
93
|
+
export interface TableStore extends Obj {
|
|
94
|
+
scroll_el?: HTMLElement;
|
|
95
|
+
table: HTMLElement;
|
|
96
|
+
thead: HTMLElement;
|
|
97
|
+
tbody: HTMLElement;
|
|
98
|
+
ths: Nullable<Element>[];
|
|
99
|
+
thSizes: Nullable<{
|
|
100
|
+
width: number;
|
|
101
|
+
height: number;
|
|
102
|
+
}>[];
|
|
103
|
+
trs: Nullable<Element>[];
|
|
104
|
+
trSizes: Nullable<{
|
|
105
|
+
width: number;
|
|
106
|
+
height: number;
|
|
107
|
+
}>[];
|
|
108
|
+
internal: symbol;
|
|
109
|
+
props?: TableProps2;
|
|
110
|
+
rawProps: TableProps;
|
|
111
|
+
plugins: Plugin[];
|
|
112
|
+
}
|
|
113
|
+
export declare const Table: (props: TableProps) => JSX.Element;
|
|
114
|
+
export declare const ScrollPlugin: Plugin;
|
|
115
|
+
export declare const defaultsPlugins: Plugin[];
|
|
116
|
+
export {};
|