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.
@@ -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 };
@@ -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) => V(H().some((B) => B?.contains(h.target)))), B;
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, a) {
10
- for (e += 1; e <= this.n; e += e & -e) this.tree[e] += a;
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 a = 0;
14
- for (e += 1; e > 0; e -= e & -e) a += this.tree[e];
15
- return a;
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 a = 0;
22
- for (let o = 1 << Math.floor(Math.log2(this.n || 1)); o > 0; o >>= 1) a + o <= this.n && this.tree[a + o] <= e && (a += o, e -= this.tree[a]);
23
- return Math.min(a, this.n - 1);
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(a) {
26
- let o = a.length, s = new e(o);
27
- for (let e = 0; e < o; e++) {
28
- s.tree[e + 1] += a[e];
29
- let c = e + 1 + (e + 1 & -(e + 1));
30
- c <= o && (s.tree[c] += s.tree[e + 1]);
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 s;
33
+ return l;
33
34
  }
34
35
  };
35
- function useVirtualizer(l) {
36
- l = mergeProps({
36
+ function useVirtualizer(d) {
37
+ d = mergeProps({
37
38
  overscan: 0,
38
39
  batch: 0,
39
40
  enable: !0
40
- }, l);
41
- let u = createElementSize(l.getScrollElement), d = createScrollPosition(l.getScrollElement), f = createMemo(() => l.horizontal ? d.x : d.y), p = createMemo(() => l.horizontal ? u.width : u.height), m = [], h = new FenwickTree(0), [g, _] = createSignal(void 0, { equals: !1 });
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 } = l;
44
+ let { count: e } = d;
44
45
  untrack(() => {
45
- if (e !== m.length) {
46
- if (e > m.length) for (let a = m.length; a < e; a++) m.push(l.estimateSize(a));
47
- else m.length = e;
48
- h = FenwickTree.build(m.slice(0, e)), _();
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 v = (e) => ({
53
+ let S = (e) => ({
53
54
  index: e,
54
- start: e > 0 ? h.sum(e - 1) : 0,
55
- end: h.sum(e)
56
- }), y = createMemo((e) => {
57
- g();
58
- let { batch: a, overscan: o = 0 } = l, s = h.findByOffset(f()) - o;
59
- return a && (s > e ? s = s <= e + a ? e : s > e + a * 2 ? s : e + a : s -= a), Math.max(s, 0);
60
- }, 0), b = createMemo((e) => {
61
- g();
62
- let { batch: a, overscan: o = 0 } = l, s = h.findByOffset(f() + p()) + o;
63
- return a && (s < e ? s = s >= e - a ? e : s < e - a * 2 ? s : e - a : s += a), Math.min(s, l.count - 1);
64
- }, 0), x = createMemo(() => {
65
- if (g(), !l.enable) return Array.from({ length: l.count }, (e, a) => v(a));
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 a = y(); a <= b(); a++) e.push(v(a));
68
- return l.extras && (e.push(...l.extras(y(), b())?.map((e) => v(e)) || []), e = uniqBy(e, (e) => e.index).sort((e, a) => e.index - a.index)), e;
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: l,
72
- startIdx: y,
73
- endIdx: b,
74
- getTotalSize: () => (g(), h.total()),
75
- resizeItem: (e, a) => {
76
- let o = m[e] ?? 0;
77
- if (o !== a) {
78
- if (e < y()) {
79
- let e = l.getScrollElement();
80
- (l.horizontal ? e.scrollLeft : e.scrollTop) !== 0 && (l.horizontal ? e.scrollLeft += a - o : e.scrollTop += a - o);
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
- h.add(e, a - o), m[e] = a, _();
83
+ _.add(e, s - c), g[e] = s, x();
83
84
  }
84
85
  },
85
- getVirtualItems: x,
86
+ getVirtualItems: T,
86
87
  getVirtualItem: (() => {
87
- let e = createMemo(() => {
88
- g();
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?: any;
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, createComputed, createContext, createEffect, createMemo, createSignal, getOwner, mapArray, mergeProps as mergeProps$1, on, onCleanup, onMount, runWithOwner, untrack, useContext } from "solid-js";
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
- ...defaultsPlugins,
43
- ...q.plugins || [],
44
- RenderPlugin
45
- ].map(X).sort((v, q) => (q.priority || 0) - (v.priority || 0)));
46
- createComputed((v) => {
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
- q.forEach((v) => Object.assign(Y, v.store?.(Y)));
50
- }), Z();
51
- }, []), Y.props = (() => {
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
- for (let J of q) {
171
- let q = J.target, { inlineSize: Y, blockSize: X } = J.borderBoxSize[0], Z = v.ths.indexOf(q);
172
- Z >= 0 && q.parentElement && (v.thSizes[Z] = {
173
- width: Y,
174
- height: X
175
- });
176
- }
177
- }), J = makeResizeObserver((q) => {
178
- for (let J of q) {
179
- let q = J.target, { inlineSize: Y, blockSize: X } = J.borderBoxSize[0], Z = v.trs.indexOf(q);
180
- Z >= 0 && q.parentElement && (v.trSizes[Z] = {
181
- width: Y,
182
- height: X
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 a = getOwner(), o = createMemo(() => e.plugins.reduce((n, r) => Object.assign(n, runWithOwner(a, () => r.commands?.(e, { ...n }))), {}));
11
- return {
12
- get commands() {
13
- return o();
14
- },
15
- scrollToCell(n, r, i) {
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
- ...i
18
+ ...a
21
19
  });
22
20
  },
23
- scrollCellIfNeeded(n, r, i = !1) {
24
- n = typeof n == "object" ? e.props.columns.indexOf(n) : n, r = typeof r == "object" ? e.props.data.indexOf(r) : r;
25
- let a = e.table.querySelector(`[x="${n}"][y="${r}"]`);
26
- a && (a.scrollIntoViewIfNeeded(i), a.focus());
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 n of c.plugins) {
34
- let r = runWithOwner(u, () => n.keybindings?.(c));
35
- r && Object.assign(e, r);
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 n = c.props?.keybindings;
38
- if (n) for (let [r, i] of Object.entries(n)) i === !1 ? delete e[r] : typeof i == "function" && (e[r] = i);
39
- return createKeybindingsHandler(Object.fromEntries(Object.entries(e).map(([e, n]) => [e, (e) => {
40
- e.preventDefault(), n(e);
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 || "text"), y = {
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
- if (!e && b.getValue() !== g) {
36
- let e = [...x.data];
37
- e[_.y] = {
38
- ...e[_.y],
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), console.log("validate", e), await h.validateCell(e, _.data, _.col);
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(e, r) {
75
- return e == r;
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 == e.props.data[i]), i > -1 && (a[i] = r, e.props.onDataChange?.(a));
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);
@@ -4,6 +4,7 @@ declare module '../../index' {
4
4
  interface TableProps {
5
5
  }
6
6
  interface TableColumn {
7
+ type?: string;
7
8
  render?: Render;
8
9
  enum?: Record<string, any> | {
9
10
  label?: string;
@@ -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