intable 0.0.22 → 0.0.23
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 -21
- package/README.md +378 -378
- package/dist/__uno.css +1 -1
- package/dist/components/AndOr.d.ts +35 -0
- package/dist/components/AndOr.js +188 -0
- package/dist/components/AndOrFields.d.ts +38 -0
- package/dist/components/AndOrFields.js +280 -0
- package/dist/components/Filter.d.ts +10 -0
- package/dist/components/Filter.js +97 -0
- package/dist/filter.js +6 -0
- package/dist/hooks/index.js +4 -1
- package/dist/hooks/useVirtualizer.js +55 -59
- package/dist/index.d.ts +1 -1
- package/dist/index.js +30 -26
- package/dist/plugins/CommandPlugin.js +19 -21
- package/dist/plugins/EditablePlugin.js +6 -10
- package/dist/plugins/FilterPlugin.d.ts +14 -0
- package/dist/plugins/FilterPlugin.js +138 -0
- package/dist/plugins/MenuPlugin.js +4 -3
- package/dist/plugins/RenderPlugin/index.d.ts +1 -0
- package/dist/plugins/RenderPlugin/index.js +1 -1
- package/dist/plugins/ValidatorPlugin.js +36 -35
- package/dist/style.css +2 -2
- package/dist/theme/antd.scss +41 -41
- package/dist/theme/dark.scss +46 -46
- package/dist/theme/element-plus.scss +38 -38
- package/dist/theme/github.scss +80 -80
- package/dist/theme/material.scss +73 -73
- package/dist/theme/shadcn.scss +66 -66
- package/dist/theme/stripe.scss +57 -57
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +42 -31
- package/package.json +1 -1
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Popover } from "./Popover.js";
|
|
2
|
+
import { AndOrFields, RuleValueEditor, isValueFreeOp, newRule } from "./AndOrFields.js";
|
|
3
|
+
import filter_default from "../filter.js";
|
|
4
|
+
import { addEventListener, className, createComponent, delegateEvents, effect, insert, template, use } from "solid-js/web";
|
|
5
|
+
import { Show } from "solid-js";
|
|
6
|
+
import { isEqual } from "es-toolkit";
|
|
7
|
+
import { autoPlacement, offset } from "floating-ui-solid";
|
|
8
|
+
var _tmpl$ = /* @__PURE__ */ template("<div class=\"mt-1 flex gap-1.5\"><button aria-label=筛选 title=筛选>"), _tmpl$2 = /* @__PURE__ */ template("<div class=\"filter-input min-w-24 op-60 select-none\">"), _tmpl$3 = /* @__PURE__ */ template("<div class=\"tt-menu p-4! z-2\">");
|
|
9
|
+
function isRuleNode(e) {
|
|
10
|
+
return e ? "field" in e : !1;
|
|
11
|
+
}
|
|
12
|
+
function firstRule(e) {
|
|
13
|
+
if (e) {
|
|
14
|
+
if (isRuleNode(e)) return e;
|
|
15
|
+
for (let _ of e.children ?? []) {
|
|
16
|
+
let e = firstRule(_);
|
|
17
|
+
if (e) return e;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const Filter = (y) => {
|
|
22
|
+
let b, x = () => y.tree, C = () => firstRule(x()), w = () => isValueFreeOp(C()?.op), T = (e) => {
|
|
23
|
+
if (isEqual({
|
|
24
|
+
...x(),
|
|
25
|
+
value: e
|
|
26
|
+
}, newRule(y.col))) {
|
|
27
|
+
y.setTree();
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (!x()) {
|
|
31
|
+
y.setTree(newRule(y.col, { value: e }));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
let _ = firstRule(x());
|
|
35
|
+
_ && (_.value = e);
|
|
36
|
+
};
|
|
37
|
+
return (() => {
|
|
38
|
+
var v = _tmpl$(), S = v.firstChild;
|
|
39
|
+
v.$$click = (e) => e.stopPropagation(), addEventListener(v, "pointerdown", (e) => e.stopPropagation()), addEventListener(v, "keydown", (e) => e.stopPropagation()), insert(v, createComponent(Show, {
|
|
40
|
+
get when() {
|
|
41
|
+
return !w();
|
|
42
|
+
},
|
|
43
|
+
get fallback() {
|
|
44
|
+
return _tmpl$2();
|
|
45
|
+
},
|
|
46
|
+
get children() {
|
|
47
|
+
return createComponent(RuleValueEditor, {
|
|
48
|
+
get field() {
|
|
49
|
+
return y.col;
|
|
50
|
+
},
|
|
51
|
+
get op() {
|
|
52
|
+
return C()?.op;
|
|
53
|
+
},
|
|
54
|
+
class: "filter-input",
|
|
55
|
+
get value() {
|
|
56
|
+
return C()?.value ?? "";
|
|
57
|
+
},
|
|
58
|
+
get enum() {
|
|
59
|
+
return y.col.enum;
|
|
60
|
+
},
|
|
61
|
+
onChange: (e) => T(String(e ?? ""))
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}), S);
|
|
65
|
+
var E = b;
|
|
66
|
+
return typeof E == "function" ? use(E, S) : b = S, insert(S, createComponent(filter_default, { class: "size-3.5 op-75" })), insert(v, createComponent(Popover, {
|
|
67
|
+
trigger: "click",
|
|
68
|
+
strategy: "fixed",
|
|
69
|
+
placement: "bottom",
|
|
70
|
+
get middleware() {
|
|
71
|
+
return [offset({ mainAxis: 6 }), autoPlacement({
|
|
72
|
+
boundary: document.body,
|
|
73
|
+
alignment: "start"
|
|
74
|
+
})];
|
|
75
|
+
},
|
|
76
|
+
reference: b,
|
|
77
|
+
get floating() {
|
|
78
|
+
return (() => {
|
|
79
|
+
var e = _tmpl$3();
|
|
80
|
+
return insert(e, createComponent(AndOrFields, {
|
|
81
|
+
get fields() {
|
|
82
|
+
return [y.col];
|
|
83
|
+
},
|
|
84
|
+
get value() {
|
|
85
|
+
return x() ?? newRule(y.col);
|
|
86
|
+
},
|
|
87
|
+
onChange: (e) => y.setTree(isEqual(e, newRule(y.col)) ? void 0 : e),
|
|
88
|
+
newRule: () => newRule(y.col),
|
|
89
|
+
hideFields: !0
|
|
90
|
+
})), e;
|
|
91
|
+
})();
|
|
92
|
+
}
|
|
93
|
+
}), null), effect(() => className(S, `filter-input w-a! flex items-center justify-center ${x() && "bg-blue/20! c-blue b-#00000000!"}`)), v;
|
|
94
|
+
})();
|
|
95
|
+
};
|
|
96
|
+
delegateEvents(["click"]);
|
|
97
|
+
export { Filter };
|
package/dist/filter.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { spread, template } from "solid-js/web";
|
|
2
|
+
var _tmpl$ = /* @__PURE__ */ template("<svg viewBox=\"0 0 24 24\"width=1.2em height=1.2em><path fill=none stroke=currentColor stroke-linecap=round stroke-linejoin=round stroke-width=2 d=\"M22 3H2l8 9.46V19l4 2v-8.54z\">"), filter_default = (n = {}) => (() => {
|
|
3
|
+
var r = _tmpl$();
|
|
4
|
+
return spread(r, n, !0, !0), r;
|
|
5
|
+
})();
|
|
6
|
+
export { filter_default as default };
|
package/dist/hooks/index.js
CHANGED
|
@@ -111,7 +111,10 @@ function useMouseDown(h) {
|
|
|
111
111
|
}
|
|
112
112
|
function useClicked(h) {
|
|
113
113
|
let [B, V] = createSignal(!1), H = () => castArray(access(h));
|
|
114
|
-
return createEventListener(() => H().map((h) => h?.getRootNode()), "click", (h) =>
|
|
114
|
+
return createEventListener(() => H().map((h) => h?.getRootNode()), "click", (h) => {
|
|
115
|
+
let B = h.composedPath();
|
|
116
|
+
V(H().some((h) => B.includes(h)));
|
|
117
|
+
}), B;
|
|
115
118
|
}
|
|
116
119
|
function useMutation(h, B, V) {
|
|
117
120
|
let H = createSignal(V());
|
|
@@ -1,96 +1,92 @@
|
|
|
1
|
+
import { throttlePromise } from "../utils.js";
|
|
1
2
|
import { createComputed, createMemo, createSignal, mergeProps, untrack } from "solid-js";
|
|
2
3
|
import { createElementSize } from "@solid-primitives/resize-observer";
|
|
3
4
|
import { createScrollPosition } from "@solid-primitives/scroll";
|
|
4
|
-
import { uniqBy } from "es-toolkit";
|
|
5
|
+
import { keyBy, uniqBy } from "es-toolkit";
|
|
5
6
|
var FenwickTree = class e {
|
|
6
7
|
constructor(e) {
|
|
7
8
|
this.n = e, this.tree = new Float64Array(e + 1);
|
|
8
9
|
}
|
|
9
|
-
add(e,
|
|
10
|
-
for (e += 1; e <= this.n; e += e & -e) this.tree[e] +=
|
|
10
|
+
add(e, s) {
|
|
11
|
+
for (e += 1; e <= this.n; e += e & -e) this.tree[e] += s;
|
|
11
12
|
}
|
|
12
13
|
sum(e) {
|
|
13
|
-
let
|
|
14
|
-
for (e += 1; e > 0; e -= e & -e)
|
|
15
|
-
return
|
|
14
|
+
let s = 0;
|
|
15
|
+
for (e += 1; e > 0; e -= e & -e) s += this.tree[e];
|
|
16
|
+
return s;
|
|
16
17
|
}
|
|
17
18
|
total() {
|
|
18
19
|
return this.n > 0 ? this.sum(this.n - 1) : 0;
|
|
19
20
|
}
|
|
20
21
|
findByOffset(e) {
|
|
21
|
-
let
|
|
22
|
-
for (let
|
|
23
|
-
return Math.min(
|
|
22
|
+
let s = 0;
|
|
23
|
+
for (let c = 1 << Math.floor(Math.log2(this.n || 1)); c > 0; c >>= 1) s + c <= this.n && this.tree[s + c] <= e && (s += c, e -= this.tree[s]);
|
|
24
|
+
return Math.min(s, this.n - 1);
|
|
24
25
|
}
|
|
25
|
-
static build(
|
|
26
|
-
let
|
|
27
|
-
for (let e = 0; e <
|
|
28
|
-
|
|
29
|
-
let
|
|
30
|
-
|
|
26
|
+
static build(s) {
|
|
27
|
+
let c = s.length, l = new e(c);
|
|
28
|
+
for (let e = 0; e < c; e++) {
|
|
29
|
+
l.tree[e + 1] += s[e];
|
|
30
|
+
let u = e + 1 + (e + 1 & -(e + 1));
|
|
31
|
+
u <= c && (l.tree[u] += l.tree[e + 1]);
|
|
31
32
|
}
|
|
32
|
-
return
|
|
33
|
+
return l;
|
|
33
34
|
}
|
|
34
35
|
};
|
|
35
|
-
function useVirtualizer(
|
|
36
|
-
|
|
36
|
+
function useVirtualizer(d) {
|
|
37
|
+
d = mergeProps({
|
|
37
38
|
overscan: 0,
|
|
38
39
|
batch: 0,
|
|
39
40
|
enable: !0
|
|
40
|
-
},
|
|
41
|
-
let
|
|
41
|
+
}, d);
|
|
42
|
+
let f = createElementSize(d.getScrollElement), p = createScrollPosition(d.getScrollElement), m = createMemo(() => d.horizontal ? p.x : p.y), h = createMemo(() => d.horizontal ? f.width : f.height), g = [], _ = new FenwickTree(0), [v, y] = createSignal(void 0, { equals: !1 }), b = throttlePromise(queueMicrotask), x = () => b().then(y);
|
|
42
43
|
createComputed(() => {
|
|
43
|
-
let { count: e } =
|
|
44
|
+
let { count: e } = d;
|
|
44
45
|
untrack(() => {
|
|
45
|
-
if (e !==
|
|
46
|
-
if (e >
|
|
47
|
-
else
|
|
48
|
-
|
|
46
|
+
if (e !== g.length) {
|
|
47
|
+
if (e > g.length) for (let s = g.length; s < e; s++) g.push(d.estimateSize(s));
|
|
48
|
+
else g.length = e;
|
|
49
|
+
_ = FenwickTree.build(g.slice(0, e)), x();
|
|
49
50
|
}
|
|
50
51
|
});
|
|
51
52
|
});
|
|
52
|
-
let
|
|
53
|
+
let S = (e) => ({
|
|
53
54
|
index: e,
|
|
54
|
-
start:
|
|
55
|
-
end:
|
|
56
|
-
}),
|
|
57
|
-
|
|
58
|
-
let { batch:
|
|
59
|
-
return
|
|
60
|
-
}, 0),
|
|
61
|
-
|
|
62
|
-
let { batch:
|
|
63
|
-
return
|
|
64
|
-
}, 0),
|
|
65
|
-
if (
|
|
55
|
+
start: _.sum(e - 1),
|
|
56
|
+
end: _.sum(e)
|
|
57
|
+
}), C = createMemo((e) => {
|
|
58
|
+
v();
|
|
59
|
+
let { batch: s, overscan: c = 0 } = d, l = _.findByOffset(m()) - c;
|
|
60
|
+
return s && (l > e ? l = l <= e + s ? e : l > e + s * 2 ? l : e + s : l -= s), Math.max(l, 0);
|
|
61
|
+
}, 0), w = createMemo((e) => {
|
|
62
|
+
v();
|
|
63
|
+
let { batch: s, overscan: c = 0 } = d, l = _.findByOffset(m() + h()) + c;
|
|
64
|
+
return s && (l < e ? l = l >= e - s ? e : l < e - s * 2 ? l : e - s : l += s), Math.min(l, d.count - 1);
|
|
65
|
+
}, 0), T = createMemo(() => {
|
|
66
|
+
if (v(), !d.enable) return Array.from({ length: d.count }, (e, s) => S(s));
|
|
66
67
|
let e = [];
|
|
67
|
-
for (let
|
|
68
|
-
return
|
|
68
|
+
for (let s = C(); s <= w(); s++) e.push(S(s));
|
|
69
|
+
return d.extras && (e.push(...d.extras(C(), w())?.map((e) => S(e)) || []), e = uniqBy(e, (e) => e.index)), e;
|
|
69
70
|
});
|
|
70
71
|
return {
|
|
71
|
-
options:
|
|
72
|
-
startIdx:
|
|
73
|
-
endIdx:
|
|
74
|
-
getTotalSize: () => (
|
|
75
|
-
resizeItem: (e,
|
|
76
|
-
let
|
|
77
|
-
if (
|
|
78
|
-
if (e <
|
|
79
|
-
let e =
|
|
80
|
-
(
|
|
72
|
+
options: d,
|
|
73
|
+
startIdx: C,
|
|
74
|
+
endIdx: w,
|
|
75
|
+
getTotalSize: () => (v(), _.total()),
|
|
76
|
+
resizeItem: (e, s) => {
|
|
77
|
+
let c = g[e] ?? 0;
|
|
78
|
+
if (c !== s) {
|
|
79
|
+
if (e < C()) {
|
|
80
|
+
let e = d.getScrollElement();
|
|
81
|
+
(d.horizontal ? e.scrollLeft : e.scrollTop) !== 0 && (d.horizontal ? e.scrollLeft += s - c : e.scrollTop += s - c);
|
|
81
82
|
}
|
|
82
|
-
|
|
83
|
+
_.add(e, s - c), g[e] = s, x();
|
|
83
84
|
}
|
|
84
85
|
},
|
|
85
|
-
getVirtualItems:
|
|
86
|
+
getVirtualItems: T,
|
|
86
87
|
getVirtualItem: (() => {
|
|
87
|
-
let e = createMemo(() =>
|
|
88
|
-
|
|
89
|
-
let e = {};
|
|
90
|
-
for (let a of x()) e[a.index] = a;
|
|
91
|
-
return e;
|
|
92
|
-
});
|
|
93
|
-
return (a) => e()[a];
|
|
88
|
+
let e = createMemo(() => keyBy(T(), (e) => e.index));
|
|
89
|
+
return (s) => e()[s];
|
|
94
90
|
})()
|
|
95
91
|
};
|
|
96
92
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -116,7 +116,7 @@ export type TDProps = {
|
|
|
116
116
|
export type TD = Component<TDProps>;
|
|
117
117
|
type Obj = Record<string | symbol, any>;
|
|
118
118
|
export interface TableColumn extends Obj {
|
|
119
|
-
id
|
|
119
|
+
id: any;
|
|
120
120
|
name?: string;
|
|
121
121
|
width?: number;
|
|
122
122
|
fixed?: 'left' | 'right';
|
package/dist/index.js
CHANGED
|
@@ -18,7 +18,7 @@ import { TreePlugin } from "./plugins/TreePlugin.js";
|
|
|
18
18
|
import { HeaderGroupPlugin } from "./plugins/HeaderGroup.js";
|
|
19
19
|
import { ValidatorPlugin } from "./plugins/ValidatorPlugin.js";
|
|
20
20
|
import { createComponent, insert, memo, mergeProps, spread, template, use } from "solid-js/web";
|
|
21
|
-
import { $PROXY, For, batch,
|
|
21
|
+
import { $PROXY, For, batch, createContext, createEffect, createMemo, createSignal, getOwner, mapArray, mergeProps as mergeProps$1, on, onCleanup, onMount, runWithOwner, untrack, useContext } from "solid-js";
|
|
22
22
|
import { createMutable, reconcile } from "solid-js/store";
|
|
23
23
|
import { combineProps } from "@solid-primitives/props";
|
|
24
24
|
import { createLazyMemo } from "@solid-primitives/memo";
|
|
@@ -38,17 +38,17 @@ const Ctx = createContext({
|
|
|
38
38
|
get plugins() {
|
|
39
39
|
return Z();
|
|
40
40
|
}
|
|
41
|
-
}), X = memoize((q) => runWithOwner(J, () => unFn(q, Y))), Z = createMemo(() =>
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
let q = difference(Z(), v);
|
|
41
|
+
}), X = memoize((q) => runWithOwner(J, () => unFn(q, Y))), Z = createMemo((v) => {
|
|
42
|
+
let Z = [
|
|
43
|
+
...defaultsPlugins,
|
|
44
|
+
...q.plugins || [],
|
|
45
|
+
RenderPlugin
|
|
46
|
+
].map(X).sort((v, q) => (q.priority || 0) - (v.priority || 0)), $ = difference(Z, v);
|
|
48
47
|
return runWithOwner(J, () => {
|
|
49
|
-
|
|
50
|
-
}), Z
|
|
51
|
-
}, [])
|
|
48
|
+
$.forEach((v) => Object.assign(Y, v.store?.(Y)));
|
|
49
|
+
}), Z;
|
|
50
|
+
}, []);
|
|
51
|
+
Y.props = (() => {
|
|
52
52
|
let v = getOwner(), J = {}, X = (q) => J[q] ??= runWithOwner(v, () => createMemo(() => Q(q)));
|
|
53
53
|
function Q(v) {
|
|
54
54
|
return createMemo(() => Z().map((q) => q.rewriteProps?.[v]).filter((v) => v), void 0, { equals: isEqual })().reduce((q, J) => J({ [v]: q }, { store: Y }), q[v]);
|
|
@@ -167,21 +167,25 @@ function BasePlugin() {
|
|
|
167
167
|
priority: Infinity,
|
|
168
168
|
store: (v) => {
|
|
169
169
|
let q = makeResizeObserver((q) => {
|
|
170
|
-
|
|
171
|
-
let
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
170
|
+
batch(() => {
|
|
171
|
+
for (let J of q) {
|
|
172
|
+
let q = J.target, { inlineSize: Y, blockSize: X } = J.borderBoxSize[0], Z = q.getAttribute("x");
|
|
173
|
+
Z >= 0 && q.parentElement && (v.thSizes[Z] = {
|
|
174
|
+
width: Y,
|
|
175
|
+
height: X
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
}), J = makeResizeObserver(async (q) => {
|
|
180
|
+
batch(() => {
|
|
181
|
+
for (let J of q) {
|
|
182
|
+
let q = J.target, { inlineSize: Y, blockSize: X } = J.borderBoxSize[0], Z = q.getAttribute("y");
|
|
183
|
+
Z >= 0 && q.parentElement && (v.trSizes[Z] = {
|
|
184
|
+
width: Y,
|
|
185
|
+
height: X
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
});
|
|
185
189
|
});
|
|
186
190
|
return {
|
|
187
191
|
thObs: q,
|
|
@@ -1,43 +1,41 @@
|
|
|
1
1
|
import { createComponent } from "solid-js/web";
|
|
2
2
|
import { createMemo, getOwner, runWithOwner } from "solid-js";
|
|
3
3
|
import { combineProps } from "@solid-primitives/props";
|
|
4
|
+
import { createLazyMemo } from "@solid-primitives/memo";
|
|
4
5
|
import { createEventListener } from "@solid-primitives/event-listener";
|
|
5
6
|
import { createKeybindingsHandler } from "tinykeys";
|
|
6
7
|
const CommandPlugin = {
|
|
7
8
|
name: "command",
|
|
8
9
|
priority: Infinity,
|
|
9
10
|
store: (e) => {
|
|
10
|
-
let
|
|
11
|
-
return {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
n = typeof n == "object" ? e.props.columns.indexOf(n) : n, r = typeof r == "object" ? e.props.data.indexOf(r) : r;
|
|
17
|
-
let a = e.table.querySelector(`[x="${n}"][y="${r}"]`);
|
|
18
|
-
a && a.scrollIntoView({
|
|
11
|
+
let r = getOwner(), o = createLazyMemo(() => e.plugins.reduce((i, o) => Object.assign(i, runWithOwner(r, () => o.commands?.(e, { ...i }))), {}));
|
|
12
|
+
return Object.defineProperty(e, "commands", { get: () => o() }), {
|
|
13
|
+
scrollToCell(r, i, a) {
|
|
14
|
+
r = typeof r == "object" ? e.props.columns.indexOf(r) : r, i = typeof i == "object" ? e.props.data.indexOf(i) : i;
|
|
15
|
+
let o = e.table.querySelector(`[x="${r}"][y="${i}"]`);
|
|
16
|
+
o && o.scrollIntoView({
|
|
19
17
|
behavior: "smooth",
|
|
20
|
-
...
|
|
18
|
+
...a
|
|
21
19
|
});
|
|
22
20
|
},
|
|
23
|
-
scrollCellIfNeeded(
|
|
24
|
-
|
|
25
|
-
let
|
|
26
|
-
|
|
21
|
+
scrollCellIfNeeded(r, i, a = !1) {
|
|
22
|
+
r = typeof r == "object" ? e.props.columns.indexOf(r) : r, i = typeof i == "object" ? e.props.data.indexOf(i) : i;
|
|
23
|
+
let o = e.table.querySelector(`[x="${r}"][y="${i}"]`);
|
|
24
|
+
o && (o.scrollIntoViewIfNeeded(a), o.focus());
|
|
27
25
|
}
|
|
28
26
|
};
|
|
29
27
|
},
|
|
30
28
|
rewriteProps: { Table: ({ Table: s }, { store: c }) => (l) => {
|
|
31
29
|
let u = getOwner(), d = createMemo(() => {
|
|
32
30
|
let e = {};
|
|
33
|
-
for (let
|
|
34
|
-
let
|
|
35
|
-
|
|
31
|
+
for (let r of c.plugins) {
|
|
32
|
+
let i = runWithOwner(u, () => r.keybindings?.(c));
|
|
33
|
+
i && Object.assign(e, i);
|
|
36
34
|
}
|
|
37
|
-
let
|
|
38
|
-
if (
|
|
39
|
-
return createKeybindingsHandler(Object.fromEntries(Object.entries(e).map(([e,
|
|
40
|
-
e.preventDefault(),
|
|
35
|
+
let r = c.props?.keybindings;
|
|
36
|
+
if (r) for (let [i, a] of Object.entries(r)) a === !1 ? delete e[i] : typeof a == "function" && (e[i] = a);
|
|
37
|
+
return createKeybindingsHandler(Object.fromEntries(Object.entries(e).map(([e, r]) => [e, (e) => {
|
|
38
|
+
e.preventDefault(), r(e);
|
|
41
39
|
}])));
|
|
42
40
|
});
|
|
43
41
|
return createEventListener(() => c.scroll_el, "keydown", (e) => d()(e)), l = combineProps({ tabindex: -1 }, l), createComponent(s, l);
|
|
@@ -19,7 +19,7 @@ const EditablePlugin = {
|
|
|
19
19
|
Td: ({ Td: e }, { store: h }) => (_) => {
|
|
20
20
|
let v, { props: x } = useContext(Ctx), S = createMemo(() => unFn(x.editable, _)), [w, T] = createSignal(!1), A = "", j = createMemo(() => (([e, h]) => _.x == e && _.y == h)(h.selected.start || [])), M = createMemo(() => j() && S() && !w()), [N, P] = createSignal(!1), F = createAsyncMemo(() => {
|
|
21
21
|
if (w()) {
|
|
22
|
-
let e = !1, g = _.data[_.col.id], v = ((e) => typeof e == "string" ? h.editors[e] : e)(_.col.editor
|
|
22
|
+
let e = !1, g = _.data[_.col.id], v = ((e) => typeof e == "string" ? h.editors[e] : e)(_.col.editor ?? _.col.type ?? "text"), y = {
|
|
23
23
|
props: _.col.editorProps,
|
|
24
24
|
col: _.col,
|
|
25
25
|
eventKey: A,
|
|
@@ -32,20 +32,16 @@ const EditablePlugin = {
|
|
|
32
32
|
onChange: (e) => w() && I(e).catch(() => {})
|
|
33
33
|
}, b = v(y);
|
|
34
34
|
return onCleanup(() => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
[_.col.id]: b.getValue()
|
|
40
|
-
}, x.onDataChange?.(e);
|
|
41
|
-
}
|
|
42
|
-
e || I(b.getValue()).catch(() => {}), b.destroy();
|
|
35
|
+
!e && b.getValue() !== g && h.commands.rowChange({
|
|
36
|
+
...x.data[_.y],
|
|
37
|
+
[_.col.id]: b.getValue()
|
|
38
|
+
}), e || I(b.getValue()).catch(() => {}), A = "", b.destroy();
|
|
43
39
|
}), [y, b];
|
|
44
40
|
}
|
|
45
41
|
});
|
|
46
42
|
async function I(e) {
|
|
47
43
|
try {
|
|
48
|
-
P(!0),
|
|
44
|
+
P(!0), await h.validateCell(e, _.data, _.col);
|
|
49
45
|
} finally {
|
|
50
46
|
P(!1);
|
|
51
47
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Plugin } from '..';
|
|
2
|
+
import type { AndOrNode } from '../components/AndOr';
|
|
3
|
+
declare module '../index' {
|
|
4
|
+
interface TableProps {
|
|
5
|
+
filterable?: boolean;
|
|
6
|
+
}
|
|
7
|
+
interface TableColumn {
|
|
8
|
+
filterable?: boolean;
|
|
9
|
+
}
|
|
10
|
+
interface TableStore {
|
|
11
|
+
filters: Record<string, AndOrNode>;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export declare const FilterPlugin: Plugin;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { normalizeType } from "../components/AndOrFields.js";
|
|
2
|
+
import { Filter } from "../components/Filter.js";
|
|
3
|
+
import { createComponent, memo, mergeProps } from "solid-js/web";
|
|
4
|
+
import { Show } from "solid-js";
|
|
5
|
+
function isBlank(e) {
|
|
6
|
+
return e == null || String(e).trim() === "";
|
|
7
|
+
}
|
|
8
|
+
function toNum(e) {
|
|
9
|
+
let u = Number(e);
|
|
10
|
+
return Number.isNaN(u) ? null : u;
|
|
11
|
+
}
|
|
12
|
+
function toDateTs(e) {
|
|
13
|
+
if (isBlank(e)) return null;
|
|
14
|
+
let u = new Date(String(e)).getTime();
|
|
15
|
+
return Number.isNaN(u) ? null : u;
|
|
16
|
+
}
|
|
17
|
+
function toBool(e) {
|
|
18
|
+
if (typeof e == "boolean") return e;
|
|
19
|
+
if (typeof e == "number") return e !== 0;
|
|
20
|
+
let u = String(e ?? "").trim().toLowerCase();
|
|
21
|
+
return [
|
|
22
|
+
"1",
|
|
23
|
+
"true",
|
|
24
|
+
"yes",
|
|
25
|
+
"y",
|
|
26
|
+
"on"
|
|
27
|
+
].includes(u) ? !0 : [
|
|
28
|
+
"0",
|
|
29
|
+
"false",
|
|
30
|
+
"no",
|
|
31
|
+
"n",
|
|
32
|
+
"off",
|
|
33
|
+
""
|
|
34
|
+
].includes(u) ? !1 : !!e;
|
|
35
|
+
}
|
|
36
|
+
function isRuleNode(e) {
|
|
37
|
+
return "field" in e;
|
|
38
|
+
}
|
|
39
|
+
function hasActiveRule(e) {
|
|
40
|
+
return !!e.op;
|
|
41
|
+
}
|
|
42
|
+
function hasActiveTree(e) {
|
|
43
|
+
return e ? isRuleNode(e) ? hasActiveRule(e) : (e.children ?? []).some(hasActiveTree) : !1;
|
|
44
|
+
}
|
|
45
|
+
function matchFilter(e, u, d) {
|
|
46
|
+
let f = u.op;
|
|
47
|
+
if (f === "blank") return isBlank(e);
|
|
48
|
+
if (f === "noblank") return !isBlank(e);
|
|
49
|
+
if (f === "true") return toBool(e);
|
|
50
|
+
if (f === "false") return !toBool(e);
|
|
51
|
+
let p = u.value;
|
|
52
|
+
if (d === "number") {
|
|
53
|
+
let u = toNum(e), d = toNum(p);
|
|
54
|
+
if (u == null || d == null) return !1;
|
|
55
|
+
if (f === "eq") return u === d;
|
|
56
|
+
if (f === "lt") return u < d;
|
|
57
|
+
if (f === "gt") return u > d;
|
|
58
|
+
if (f === "lte") return u <= d;
|
|
59
|
+
if (f === "gte") return u >= d;
|
|
60
|
+
}
|
|
61
|
+
if (d === "date") {
|
|
62
|
+
let u = toDateTs(e), d = toDateTs(p);
|
|
63
|
+
if (u == null || d == null) return !1;
|
|
64
|
+
if (f === "eq") return u === d;
|
|
65
|
+
if (f === "lt") return u < d;
|
|
66
|
+
if (f === "gt") return u > d;
|
|
67
|
+
if (f === "lte") return u <= d;
|
|
68
|
+
if (f === "gte") return u >= d;
|
|
69
|
+
}
|
|
70
|
+
let m = String(e ?? "").toLowerCase(), v = String(p ?? "").toLowerCase();
|
|
71
|
+
return f === "eq" ? m === v : f === "neq" ? m !== v : f === "startwith" ? m.startsWith(v) : f === "endwith" ? m.endsWith(v) : m.includes(v);
|
|
72
|
+
}
|
|
73
|
+
function getFilterTree(e, u) {
|
|
74
|
+
return e[u.id];
|
|
75
|
+
}
|
|
76
|
+
function setFilterTree(e, u, d) {
|
|
77
|
+
if (!d) {
|
|
78
|
+
delete e[u.id];
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
e[u.id] = d;
|
|
82
|
+
}
|
|
83
|
+
function evaluateFilterTree(e, u, d) {
|
|
84
|
+
if (isRuleNode(u)) return hasActiveRule(u) ? matchFilter(e, u, d) : !0;
|
|
85
|
+
let f = (u.children ?? []).filter(hasActiveTree);
|
|
86
|
+
return f.length ? u.op === "or" ? f.some((u) => evaluateFilterTree(e, u, d)) : f.every((u) => evaluateFilterTree(e, u, d)) : !0;
|
|
87
|
+
}
|
|
88
|
+
function passesFilters(u, d, f, p, m) {
|
|
89
|
+
return f.every((f) => {
|
|
90
|
+
if (f[m] || !(f.filterable ?? p)) return !0;
|
|
91
|
+
let h = getFilterTree(d, f);
|
|
92
|
+
return !h || !hasActiveTree(h) ? !0 : evaluateFilterTree(u[f.id], h, normalizeType(f));
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
const FilterPlugin = {
|
|
96
|
+
name: "filter",
|
|
97
|
+
store: () => ({ filters: {} }),
|
|
98
|
+
rewriteProps: {
|
|
99
|
+
data: ({ data: e }, { store: u }) => {
|
|
100
|
+
if (!e) return e;
|
|
101
|
+
let { filters: d } = u, { columns: f = [], filterable: p } = u.props;
|
|
102
|
+
return Object.values(d).some(hasActiveTree) ? e.filter((e) => passesFilters(e, d, f, p, u.internal)) : e;
|
|
103
|
+
},
|
|
104
|
+
onDataChange: ({ onDataChange: e }, { store: u }) => (d) => {
|
|
105
|
+
let f = u.rawProps.data ?? [], { columns: p = [], filterable: m } = u.props;
|
|
106
|
+
if (!Object.values(u.filters).some(hasActiveTree)) {
|
|
107
|
+
e?.(d);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
let h = [...f], g = 0;
|
|
111
|
+
f.forEach((e, f) => {
|
|
112
|
+
passesFilters(e, u.filters, p, m, u.internal) && (h[f] = d[g++]);
|
|
113
|
+
}), e?.(h);
|
|
114
|
+
},
|
|
115
|
+
Th: ({ Th: e }, { store: h }) => (g) => {
|
|
116
|
+
let _ = () => !!(g.col.filterable ?? h.props.filterable) && !g.col[h.internal];
|
|
117
|
+
return createComponent(e, mergeProps(g, { get children() {
|
|
118
|
+
return [memo(() => g.children), createComponent(Show, {
|
|
119
|
+
get when() {
|
|
120
|
+
return _();
|
|
121
|
+
},
|
|
122
|
+
get children() {
|
|
123
|
+
return createComponent(Filter, {
|
|
124
|
+
get col() {
|
|
125
|
+
return g.col;
|
|
126
|
+
},
|
|
127
|
+
get tree() {
|
|
128
|
+
return getFilterTree(h.filters, g.col);
|
|
129
|
+
},
|
|
130
|
+
setTree: (e) => setFilterTree(h.filters, g.col, e)
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
})];
|
|
134
|
+
} }));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
export { FilterPlugin };
|
|
@@ -71,15 +71,16 @@ const MenuPlugin = {
|
|
|
71
71
|
}
|
|
72
72
|
],
|
|
73
73
|
commands: (e) => ({
|
|
74
|
-
rowEquals(
|
|
75
|
-
|
|
74
|
+
rowEquals(r, i) {
|
|
75
|
+
let a = e.props.rowKey;
|
|
76
|
+
return r == i || a != null && r?.[a] == i?.[a];
|
|
76
77
|
},
|
|
77
78
|
rowIndexOf(r, i) {
|
|
78
79
|
return r.findIndex((r) => e.commands.rowEquals(r, i));
|
|
79
80
|
},
|
|
80
81
|
rowChange(r, i) {
|
|
81
82
|
let a = [...e.rawProps.data || []];
|
|
82
|
-
i = i == null ? e.commands.rowIndexOf(a, r) : a.findIndex((r) => r
|
|
83
|
+
i = i == null ? e.commands.rowIndexOf(a, r) : a.findIndex((r) => e.commands.rowEquals(r, e.props.data[i])), i > -1 && (a[i] = r, e.props.onDataChange?.(a));
|
|
83
84
|
},
|
|
84
85
|
addRows(r, i, a = !0) {
|
|
85
86
|
addRows(e, r, i, a);
|
|
@@ -10,7 +10,7 @@ const RenderPlugin = {
|
|
|
10
10
|
store: () => ({ renders: { ...renders } }),
|
|
11
11
|
rewriteProps: { Td: ({ Td: e }, { store: p }) => (m) => createComponent(e, mergeProps(m, { get children() {
|
|
12
12
|
return (() => {
|
|
13
|
-
let e = ((e) => typeof e == "string" ? p.renders[e] : e)(m.col.render) || text;
|
|
13
|
+
let e = ((e) => typeof e == "string" ? p.renders[e] : e)(m.col.render ?? m.col.type) || text;
|
|
14
14
|
return renderComponent(e, mergeProps$1(m, { onChange: (e) => p.commands.rowChange({
|
|
15
15
|
...m.data,
|
|
16
16
|
[m.col.id]: e
|