@rinzai/zen 0.9.0 → 0.10.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 (112) hide show
  1. package/dist/animated-number/index.d.ts +6 -2
  2. package/dist/animated-number/index.d.ts.map +1 -1
  3. package/dist/animated-number/index.js +68 -17
  4. package/dist/calendar-heatmap/index.d.ts +25 -0
  5. package/dist/calendar-heatmap/index.d.ts.map +1 -0
  6. package/dist/calendar-heatmap/index.js +48 -0
  7. package/dist/chart/allocation.d.ts +30 -0
  8. package/dist/chart/allocation.d.ts.map +1 -0
  9. package/dist/chart/allocation.js +69 -0
  10. package/dist/chart/index.d.ts +1 -0
  11. package/dist/chart/index.d.ts.map +1 -1
  12. package/dist/chart/index.js +85 -83
  13. package/dist/code-block/index.d.ts +1 -1
  14. package/dist/code-block/index.d.ts.map +1 -1
  15. package/dist/code-block/index.js +31 -22
  16. package/dist/collapse/index.d.ts +3 -2
  17. package/dist/collapse/index.d.ts.map +1 -1
  18. package/dist/collapse/index.js +1 -1
  19. package/dist/date-picker/index.d.ts +10 -2
  20. package/dist/date-picker/index.d.ts.map +1 -1
  21. package/dist/date-picker/index.js +43 -21
  22. package/dist/dialog/index.d.ts +4 -2
  23. package/dist/dialog/index.d.ts.map +1 -1
  24. package/dist/dialog/index.js +69 -113
  25. package/dist/editable-cell/index.d.ts +2 -1
  26. package/dist/editable-cell/index.d.ts.map +1 -1
  27. package/dist/editable-cell/index.js +24 -17
  28. package/dist/filter-bar/index.d.ts +21 -0
  29. package/dist/filter-bar/index.d.ts.map +1 -0
  30. package/dist/filter-bar/index.js +90 -0
  31. package/dist/icon-picker/index.d.ts +38 -0
  32. package/dist/icon-picker/index.d.ts.map +1 -0
  33. package/dist/icon-picker/index.js +112 -0
  34. package/dist/icons/arrow-left.js +23 -0
  35. package/dist/icons/micro/arrow-trending-down.d.ts +3 -0
  36. package/dist/icons/micro/arrow-trending-down.d.ts.map +1 -0
  37. package/dist/icons/micro/arrow-trending-down.js +21 -0
  38. package/dist/icons/micro/arrow-trending-up.d.ts +3 -0
  39. package/dist/icons/micro/arrow-trending-up.d.ts.map +1 -0
  40. package/dist/icons/micro/arrow-trending-up.js +21 -0
  41. package/dist/index.d.ts +17 -5
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/kbd/index.d.ts +4 -0
  44. package/dist/kbd/index.d.ts.map +1 -0
  45. package/dist/kbd/index.js +12 -0
  46. package/dist/keypad/index.d.ts +20 -0
  47. package/dist/keypad/index.d.ts.map +1 -0
  48. package/dist/keypad/index.js +42 -0
  49. package/dist/lib.js +92 -77
  50. package/dist/load-more/index.d.ts +19 -0
  51. package/dist/load-more/index.d.ts.map +1 -0
  52. package/dist/load-more/index.js +37 -0
  53. package/dist/menu/index.d.ts +22 -3
  54. package/dist/menu/index.d.ts.map +1 -1
  55. package/dist/menu/index.js +139 -48
  56. package/dist/meter/index.d.ts +3 -1
  57. package/dist/meter/index.d.ts.map +1 -1
  58. package/dist/meter/index.js +19 -14
  59. package/dist/money-input/index.d.ts +3 -3
  60. package/dist/page-transition/index.d.ts +10 -0
  61. package/dist/page-transition/index.d.ts.map +1 -0
  62. package/dist/page-transition/index.js +16 -0
  63. package/dist/progress-ring/index.d.ts +4 -1
  64. package/dist/progress-ring/index.d.ts.map +1 -1
  65. package/dist/progress-ring/index.js +47 -38
  66. package/dist/range-slider/index.d.ts +26 -0
  67. package/dist/range-slider/index.d.ts.map +1 -0
  68. package/dist/range-slider/index.js +44 -0
  69. package/dist/repeat-picker/index.d.ts +22 -0
  70. package/dist/repeat-picker/index.d.ts.map +1 -0
  71. package/dist/repeat-picker/index.js +115 -0
  72. package/dist/slider/index.d.ts +2 -0
  73. package/dist/slider/index.d.ts.map +1 -1
  74. package/dist/slider/index.js +19 -18
  75. package/dist/sortable/index.d.ts +33 -0
  76. package/dist/sortable/index.d.ts.map +1 -0
  77. package/dist/sortable/index.js +147 -0
  78. package/dist/table/index.d.ts +5 -1
  79. package/dist/table/index.d.ts.map +1 -1
  80. package/dist/table/index.js +90 -58
  81. package/dist/table/selection.d.ts +55 -0
  82. package/dist/table/selection.d.ts.map +1 -0
  83. package/dist/table/selection.js +83 -0
  84. package/dist/table/swipe.d.ts +18 -0
  85. package/dist/table/swipe.d.ts.map +1 -0
  86. package/dist/table/swipe.js +53 -0
  87. package/dist/tabs/index.d.ts.map +1 -1
  88. package/dist/tabs/index.js +101 -51
  89. package/dist/theme-toggle/index.js +6 -6
  90. package/dist/theme.css +184 -11
  91. package/dist/toast/index.js +25 -25
  92. package/dist/toggle/index.d.ts.map +1 -1
  93. package/dist/toggle/index.js +1 -1
  94. package/dist/trend/index.d.ts +19 -0
  95. package/dist/trend/index.d.ts.map +1 -0
  96. package/dist/trend/index.js +27 -0
  97. package/dist/utils/date.d.ts +34 -0
  98. package/dist/utils/date.d.ts.map +1 -1
  99. package/dist/utils/date.js +45 -12
  100. package/dist/utils/money.d.ts +3 -1
  101. package/dist/utils/money.d.ts.map +1 -1
  102. package/dist/utils/money.js +24 -1
  103. package/dist/utils/repeat.d.ts +17 -0
  104. package/dist/utils/repeat.d.ts.map +1 -0
  105. package/dist/utils/repeat.js +38 -0
  106. package/dist/utils/swipe.d.ts +29 -0
  107. package/dist/utils/swipe.d.ts.map +1 -0
  108. package/dist/utils/swipe.js +85 -0
  109. package/dist/utils/useAnchoredPopup.d.ts.map +1 -1
  110. package/dist/utils/useAnchoredPopup.js +3 -9
  111. package/dist/zen.css +1 -1
  112. package/package.json +3 -1
@@ -2,155 +2,111 @@
2
2
  import { cx as e } from "../utils/cx.js";
3
3
  import { useGraphicsMode as t } from "../utils/graphics.js";
4
4
  import n from "../button/index.js";
5
- import { useToastHost as r } from "../toast/index.js";
6
- import { createContext as i, useContext as a, useEffect as o, useId as s, useRef as c } from "react";
7
- import { jsx as l, jsxs as u } from "react/jsx-runtime";
5
+ import r from "../icons/micro/x-mark.js";
6
+ import { useToastHost as i } from "../toast/index.js";
7
+ import { useSwipe as a } from "../utils/swipe.js";
8
+ import { createContext as o, useContext as s, useEffect as c, useId as l, useRef as u } from "react";
9
+ import { jsx as d, jsxs as f } from "react/jsx-runtime";
8
10
  //#region packages/dialog/index.tsx
9
- var d = i(() => {});
10
- function f({ open: t, onOpenChange: n, title: r, description: i, children: a, dismissible: o = !0, initialFocus: f, size: m = "md", side: h, className: g, role: _ }) {
11
- let y = c(null), b = s(), x = s();
12
- return v(y, o && t ? h : void 0, () => n?.(!1)), p(y, t, f), /* @__PURE__ */ l("dialog", {
13
- ref: y,
14
- role: _,
15
- "aria-labelledby": b,
16
- "aria-describedby": i ? x : void 0,
17
- "data-side": h,
18
- className: e("zen__dialog glass glass-blur glow-edge text-card-foreground bg-card/90! overflow-visible p-0", !h && "m-auto max-h-[calc(100dvh-2rem)] max-w-[calc(100vw-2rem)] rounded-xl", !h && (m === "lg" ? "w-[60rem]" : "w-[28rem]"), h === "bottom" && "mx-auto mt-auto mb-0 max-h-[85dvh] w-full max-w-2xl rounded-t-2xl", (h === "left" || h === "right") && "my-0 h-dvh max-h-dvh w-[24rem] max-w-[calc(100vw-2.5rem)]", h === "right" && "mr-0 ml-auto rounded-l-2xl", h === "left" && "mr-auto ml-0 rounded-r-2xl", "backdrop:bg-[color:var(--backdrop-scrim,oklch(0_0_0/0.5))] backdrop:backdrop-blur-sm pointer-coarse:backdrop:backdrop-blur-none", g),
11
+ var p = o(() => {});
12
+ function m({ open: t, onOpenChange: n, title: i, description: a, children: o, dismissible: s = !0, initialFocus: c, size: m = "md", side: g, className: v, role: y, closeLabel: b = "Close" }) {
13
+ let x = u(null), S = l(), C = l();
14
+ return _(x, s && t ? g : void 0, () => n?.(!1)), h(x, t, c), /* @__PURE__ */ f("dialog", {
15
+ ref: x,
16
+ role: y,
17
+ "aria-labelledby": S,
18
+ "aria-describedby": a ? C : void 0,
19
+ "data-side": g,
20
+ className: e("zen__dialog glass glass-blur glow-edge text-card-foreground bg-card/90! overflow-visible p-0", !g && "m-auto max-h-[calc(100dvh-2rem)] max-w-[calc(100vw-2rem)] rounded-xl", !g && (m === "lg" ? "w-[60rem]" : "w-[28rem]"), g === "bottom" && "mx-auto mt-auto mb-0 max-h-[85dvh] w-full max-w-2xl rounded-t-2xl", (g === "left" || g === "right") && "my-0 h-dvh max-h-dvh w-[24rem] max-w-[calc(100vw-2.5rem)]", g === "right" && "mr-0 ml-auto rounded-l-2xl", g === "left" && "mr-auto ml-0 rounded-r-2xl", "backdrop:bg-[color:var(--backdrop-scrim,oklch(0_0_0/0.5))] backdrop:backdrop-blur-sm pointer-coarse:backdrop:backdrop-blur-none", v),
19
21
  onCancel: (e) => {
20
- e.preventDefault(), o && n?.(!1);
22
+ e.preventDefault(), s && n?.(!1);
21
23
  },
22
24
  onClick: (e) => {
23
- e.target === e.currentTarget && o && n?.(!1);
25
+ e.target === e.currentTarget && s && n?.(!1);
24
26
  },
25
- children: /* @__PURE__ */ u("div", {
26
- className: e("flex flex-col gap-4 overflow-x-hidden overflow-y-auto p-6", h ? h === "bottom" ? "max-h-[85dvh] pt-3" : "h-full" : "max-h-[calc(100dvh-2rem)]"),
27
+ children: [/* @__PURE__ */ f("div", {
28
+ className: e("flex flex-col gap-4 overflow-x-hidden overflow-y-auto p-6", g ? g === "bottom" ? "max-h-[85dvh] pt-3" : "h-full" : "max-h-[calc(100dvh-2rem)]"),
27
29
  children: [
28
- h === "bottom" && /* @__PURE__ */ l("div", {
30
+ g === "bottom" && /* @__PURE__ */ d("div", {
29
31
  "aria-hidden": !0,
30
32
  className: "bg-tint/20 mx-auto h-1 w-10 shrink-0 rounded-full"
31
33
  }),
32
- /* @__PURE__ */ u("div", {
33
- className: "flex flex-col gap-2",
34
- children: [/* @__PURE__ */ l("h2", {
35
- id: b,
34
+ /* @__PURE__ */ f("div", {
35
+ className: e("flex flex-col gap-2", s && "pe-8"),
36
+ children: [/* @__PURE__ */ d("h2", {
37
+ id: S,
36
38
  className: "text-lg font-semibold tracking-tight text-balance",
37
- children: r
38
- }), i && /* @__PURE__ */ l("p", {
39
- id: x,
40
- className: "text-muted-foreground mt-0! text-sm leading-5",
41
39
  children: i
40
+ }), a && /* @__PURE__ */ d("p", {
41
+ id: C,
42
+ className: "text-muted-foreground mt-0! text-sm leading-5",
43
+ children: a
42
44
  })]
43
45
  }),
44
- /* @__PURE__ */ l(d.Provider, {
46
+ /* @__PURE__ */ d(p.Provider, {
45
47
  value: () => n?.(!1),
46
- children: a
48
+ children: o
47
49
  })
48
50
  ]
49
- })
51
+ }), s && /* @__PURE__ */ d("button", {
52
+ type: "button",
53
+ "aria-label": b,
54
+ onClick: () => n?.(!1),
55
+ className: e("text-muted-foreground hover:bg-tint/[0.07] hover:text-foreground focus-visible:ring-ring/50 absolute end-4 grid size-8 cursor-pointer place-items-center rounded-lg outline-hidden transition-colors focus-visible:ring-2", g === "bottom" ? "top-7.5" : "top-5.5"),
56
+ children: /* @__PURE__ */ d(r, { className: "size-4" })
57
+ })]
50
58
  });
51
59
  }
52
- function p(e, n, i) {
53
- t(), o(() => {
60
+ function h(e, n, r) {
61
+ t(), c(() => {
54
62
  let t = e.current;
55
63
  if (t) {
56
64
  if (n && !t.open) {
57
65
  let e = document.documentElement;
58
66
  e.toggleAttribute("data-zen-scrollbar", window.innerWidth > e.clientWidth);
59
- let n = document.activeElement === document.body ? null : document.activeElement?.getBoundingClientRect(), r = !!n && !t.dataset.side;
60
- if (t.toggleAttribute("data-zen-from", r), t.showModal(), r) {
67
+ let n = document.activeElement === document.body ? null : document.activeElement?.getBoundingClientRect(), i = !!n && !t.dataset.side;
68
+ if (t.toggleAttribute("data-zen-from", i), t.showModal(), i) {
61
69
  let e = n.left + n.width / 2 - t.offsetLeft, r = n.top + n.height / 2 - t.offsetTop;
62
70
  t.style.transformOrigin = `${Math.round(e)}px ${Math.round(r)}px`;
63
71
  }
64
- i?.current?.focus();
72
+ r?.current?.focus();
65
73
  } else !n && t.open && t.close();
66
74
  }
67
75
  }, [
68
76
  e,
69
77
  n,
70
- i
71
- ]), r(e, n);
72
- }
73
- var m = .3, h = .5, g = 100, _ = 8;
74
- function v(e, t, n) {
75
- let r = c(n);
76
- o(() => {
77
- r.current = n;
78
- }), o(() => {
79
- let n = e.current;
80
- if (!n || (n.style.removeProperty("--zen-swipe"), n.style.removeProperty("--zen-swipe-progress"), !t)) return;
81
- let i = t === "bottom" ? "y" : "x", a = t === "left" ? -1 : 1, o = null, s = !1, c = () => i === "y" ? n.offsetHeight : n.offsetWidth, l = (e) => (i === "y" ? e.clientY - o.y : e.clientX - o.x) * a, u = (e) => i === "y" ? e.clientX - o.x : e.clientY - o.y, d = (e) => {
82
- let t = e > 0 ? e : e / 6;
83
- n.style.setProperty("--zen-swipe", i === "y" ? `0 ${t}px` : `${t * a}px 0`), n.style.setProperty("--zen-swipe-progress", String(Math.max(0, Math.min(1, e / c()))));
84
- }, f = (e) => {
85
- let t = o?.on;
86
- if (o = null, t) {
87
- if (delete n.dataset.swiping, s = !0, e) return r.current();
88
- n.style.removeProperty("--zen-swipe"), n.style.removeProperty("--zen-swipe-progress");
89
- }
90
- }, p = (e) => {
91
- if (s = !1, e.pointerType === "touch") {
92
- if (!e.isPrimary) return f(!1);
93
- y(e.target, n, i) || (o = {
94
- id: e.pointerId,
95
- x: e.clientX,
96
- y: e.clientY,
97
- points: [[e.timeStamp, 0]],
98
- on: !1
99
- });
100
- }
101
- }, v = (e) => {
102
- if (!o || e.pointerId !== o.id) return;
103
- let t = l(e);
104
- if (!o.on) {
105
- if (Math.hypot(t, u(e)) < _) return;
106
- if (t <= 0 || Math.abs(u(e)) * 1.5 > t || b(e.target, n, i, a)) {
107
- o = null;
108
- return;
109
- }
110
- o.on = !0, n.dataset.swiping = "", n.setPointerCapture?.(e.pointerId);
111
- }
112
- o.points = [...o.points.filter(([t]) => e.timeStamp - t < g), [e.timeStamp, t]], d(t);
113
- }, x = (e) => {
114
- if (!o || e.pointerId !== o.id) return;
115
- let t = l(e), [n, r] = o.points.find(([t]) => e.timeStamp - t < g) ?? [e.timeStamp, t], i = (t - r) / Math.max(1, e.timeStamp - n);
116
- f(e.type === "pointerup" && (t > c() * m || t > 0 && i > h));
117
- }, S = (e) => {
118
- o?.on && e.preventDefault();
119
- }, C = (e) => {
120
- s && (s = !1, e.stopPropagation(), e.preventDefault());
121
- };
122
- return n.addEventListener("pointerdown", p), n.addEventListener("pointermove", v), n.addEventListener("pointerup", x), n.addEventListener("pointercancel", x), n.addEventListener("touchmove", S, { passive: !1 }), n.addEventListener("click", C, !0), () => {
123
- n.removeEventListener("pointerdown", p), n.removeEventListener("pointermove", v), n.removeEventListener("pointerup", x), n.removeEventListener("pointercancel", x), n.removeEventListener("touchmove", S), n.removeEventListener("click", C, !0), delete n.dataset.swiping;
124
- };
125
- }, [e, t]);
78
+ r
79
+ ]), i(e, n);
126
80
  }
127
- function y(e, t, n) {
128
- if (e.closest("input, textarea, select, [contenteditable]:not([contenteditable=\"false\"])")) return !0;
129
- let r = n === "y" ? /pan-(y|up|down)/ : /pan-(x|left|right)/;
130
- for (let n = e; n && n !== t; n = n.parentElement) {
131
- let e = getComputedStyle(n).touchAction;
132
- if (e && e !== "auto" && e !== "manipulation" && !r.test(e)) return !0;
133
- }
134
- return !1;
135
- }
136
- function b(e, t, n, r) {
137
- for (let i = e; i; i = i === t ? null : i.parentElement) {
138
- let e = getComputedStyle(i);
139
- if (!/auto|scroll/.test(n === "y" ? e.overflowY : e.overflowX)) continue;
140
- let t = n === "y" ? i.scrollTop : i.scrollLeft, a = n === "y" ? i.scrollHeight - i.clientHeight : i.scrollWidth - i.clientWidth;
141
- if (!(a <= 0) && (r > 0 ? t > 0 : t < a - 1)) return !0;
142
- }
143
- return !1;
81
+ var g = .3;
82
+ function _(e, t, n) {
83
+ let r = t === "bottom" ? "y" : "x", i = t === "left" ? -1 : 1, o = () => r === "y" ? e.current.offsetHeight : e.current.offsetWidth, s = () => {
84
+ e.current?.style.removeProperty("--zen-swipe"), e.current?.style.removeProperty("--zen-swipe-progress");
85
+ };
86
+ c(s, [e, t]), a(e, t ? {
87
+ axis: r,
88
+ sign: i
89
+ } : void 0, {
90
+ move: (t) => {
91
+ let n = t > 0 ? t : t / 6;
92
+ e.current.style.setProperty("--zen-swipe", r === "y" ? `0 ${n}px` : `${n * i}px 0`), e.current.style.setProperty("--zen-swipe-progress", String(Math.max(0, Math.min(1, t / o()))));
93
+ },
94
+ release: (e, t) => {
95
+ e > o() * g || e > 0 && t > .5 ? n() : s();
96
+ },
97
+ cancel: s,
98
+ threshold: () => o() * g
99
+ });
144
100
  }
145
- function x({ className: t, ...n }) {
146
- return /* @__PURE__ */ l("div", {
101
+ function v({ className: t, ...n }) {
102
+ return /* @__PURE__ */ d("div", {
147
103
  className: e("flex justify-end gap-2", t),
148
104
  ...n
149
105
  });
150
106
  }
151
- function S({ onClick: e, ...t }) {
152
- let r = a(d);
153
- return /* @__PURE__ */ l(n, {
107
+ function y({ onClick: e, ...t }) {
108
+ let r = s(p);
109
+ return /* @__PURE__ */ d(n, {
154
110
  ...t,
155
111
  onClick: (t) => {
156
112
  e?.(t), t.defaultPrevented || r();
@@ -158,4 +114,4 @@ function S({ onClick: e, ...t }) {
158
114
  });
159
115
  }
160
116
  //#endregion
161
- export { S as DialogClose, x as DialogFooter, f as default, p as useModal };
117
+ export { y as DialogClose, v as DialogFooter, m as default, h as useModal };
@@ -3,7 +3,8 @@ import { ReactNode } from 'react';
3
3
  * A value edited in place, e.g. in a table cell: shows `children` as a button,
4
4
  * and on click (or Enter) swaps in your editor. Call `close()` from the editor
5
5
  * when it's done (committed or cancelled). Works with any editor: a compact
6
- * MoneyInput, an Input, a Select.
6
+ * MoneyInput, an Input, a Select. A value changed by an edit glows briefly
7
+ * when the editor closes.
7
8
  */
8
9
  export default function EditableCell({ children, editor, label, readOnly, editing: editingProp, onEditingChange, title, className, }: EditableCellProps): import('react').JSX.Element;
9
10
  export interface EditableCellProps {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/editable-cell/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAY,MAAM,OAAO,CAAC;AAE5C;;;;;GAKG;AACH,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EACjC,QAAQ,EACR,MAAM,EACN,KAAK,EACL,QAAgB,EAChB,OAAO,EAAE,WAAW,EACpB,eAAe,EACf,KAAK,EACL,SAAS,GACZ,EAAE,iBAAiB,+BA8BnB;AAED,MAAM,WAAW,iBAAiB;IAC9B,4CAA4C;IAC5C,QAAQ,EAAE,SAAS,CAAC;IACpB,qEAAqE;IACrE,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,IAAI,KAAK,SAAS,CAAC;IACzC,qGAAqG;IACrG,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,iEAAiE;IACjE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/editable-cell/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAgD,MAAM,OAAO,CAAC;AAIhF;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EACjC,QAAQ,EACR,MAAM,EACN,KAAK,EACL,QAAgB,EAChB,OAAO,EAAE,WAAW,EACpB,eAAe,EACf,KAAK,EACL,SAAS,GACZ,EAAE,iBAAiB,+BAwCnB;AAED,MAAM,WAAW,iBAAiB;IAC9B,4CAA4C;IAC5C,QAAQ,EAAE,SAAS,CAAC;IACpB,qEAAqE;IACrE,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,IAAI,KAAK,SAAS,CAAC;IACzC,qGAAqG;IACrG,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,iEAAiE;IACjE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB"}
@@ -1,24 +1,31 @@
1
1
  "use client";
2
2
  import { cx as e } from "../utils/cx.js";
3
- import { useState as t } from "react";
4
- import { Fragment as n, jsx as r } from "react/jsx-runtime";
3
+ import { useEffect as t, useLayoutEffect as n, useRef as r, useState as i } from "react";
4
+ import { Fragment as a, jsx as o } from "react/jsx-runtime";
5
5
  //#region packages/editable-cell/index.tsx
6
- function i({ children: i, editor: a, label: o, readOnly: s = !1, editing: c, onEditingChange: l, title: u, className: d }) {
7
- let [f, p] = t(!1), m = c ?? f, h = (e) => {
8
- c === void 0 && p(e), l?.(e);
9
- };
10
- return s ? /* @__PURE__ */ r("span", {
11
- title: u,
12
- className: e("zen__editable-cell block px-1 text-right tabular-nums", d),
13
- children: i
14
- }) : m ? /* @__PURE__ */ r(n, { children: a(() => h(!1)) }) : /* @__PURE__ */ r("button", {
6
+ var s = typeof window > "u" ? t : n;
7
+ function c({ children: t, editor: n, label: c, readOnly: l = !1, editing: u, onEditingChange: d, title: f, className: p }) {
8
+ let [m, h] = i(!1), g = u ?? m, _ = (e) => {
9
+ u === void 0 && h(e), d?.(e);
10
+ }, v = r(null), [y, b] = i(null);
11
+ return s(() => {
12
+ let e = v.current;
13
+ !g && e && y !== null && e.textContent !== y && (e.dataset.changed = "");
14
+ }, [g, y]), l ? /* @__PURE__ */ o("span", {
15
+ title: f,
16
+ className: e("zen__editable-cell block px-1 text-right tabular-nums", p),
17
+ children: t
18
+ }) : g ? /* @__PURE__ */ o(a, { children: n(() => _(!1)) }) : /* @__PURE__ */ o("button", {
19
+ ref: v,
15
20
  type: "button",
16
- title: u,
17
- "aria-label": o ? `${o}. Edit` : void 0,
18
- onClick: () => h(!0),
19
- className: e("zen__editable-cell hover:bg-primary/10 focus-visible:ring-ring/50 w-full cursor-pointer rounded-md px-1.5 py-0.5 text-right tabular-nums transition-colors focus-visible:ring-2 focus-visible:outline-hidden", d),
20
- children: i
21
+ title: f,
22
+ "aria-label": c ? `${c}. Edit` : void 0,
23
+ onClick: (e) => {
24
+ b(e.currentTarget.textContent), _(!0);
25
+ },
26
+ className: e("zen__editable-cell hover:bg-primary/10 focus-visible:ring-ring/50 w-full cursor-pointer rounded-md px-1.5 py-0.5 text-right tabular-nums transition-colors focus-visible:ring-2 focus-visible:outline-hidden", p),
27
+ children: t
21
28
  });
22
29
  }
23
30
  //#endregion
24
- export { i as default };
31
+ export { c as default };
@@ -0,0 +1,21 @@
1
+ import { ComponentProps, ReactNode } from 'react';
2
+ /**
3
+ * The filters in effect, as chips each removed with its ×, and "Clear all"
4
+ * once there are two or more. Renders nothing when no filter is set.
5
+ */
6
+ export default function FilterBar({ onClear, clearLabel, 'aria-label': label, className, children, ref, ...rest }: FilterBarProps): import('react').JSX.Element | null;
7
+ /** One filter in a FilterBar: what it is (e.g. "Amount: $50–$500"), and its × to remove it. */
8
+ export declare function FilterChip({ onRemove, removeLabel, className, children }: FilterChipProps): import('react').JSX.Element;
9
+ export interface FilterBarProps extends ComponentProps<'div'> {
10
+ /** Removes every filter; shown as "Clear all" once there are two or more. */
11
+ onClear?: () => void;
12
+ clearLabel?: ReactNode;
13
+ }
14
+ export interface FilterChipProps {
15
+ onRemove: () => void;
16
+ /** The × button's name for screen readers, e.g. "Remove amount filter". */
17
+ removeLabel?: string;
18
+ className?: string;
19
+ children: ReactNode;
20
+ }
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/filter-bar/index.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAY,cAAc,EAAE,SAAS,EAAiD,MAAM,OAAO,CAAC;AAM3G;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,EAC9B,OAAO,EACP,UAAwB,EACxB,YAAY,EAAE,KAAwB,EACtC,SAAS,EACT,QAAQ,EACR,GAAG,EACH,GAAG,IAAI,EACV,EAAE,cAAc,sCA6BhB;AAiDD,+FAA+F;AAC/F,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,WAA6B,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,eAAe,+BAmB3G;AAED,MAAM,WAAW,cAAe,SAAQ,cAAc,CAAC,KAAK,CAAC;IACzD,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,SAAS,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC5B,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACvB"}
@@ -0,0 +1,90 @@
1
+ "use client";
2
+ import { cx as e } from "../utils/cx.js";
3
+ import { reducedMotion as t } from "../utils/motion.js";
4
+ import n from "../icons/micro/x-mark.js";
5
+ import { Children as r, useEffect as i, useLayoutEffect as a, useRef as o } from "react";
6
+ import { jsx as s, jsxs as c } from "react/jsx-runtime";
7
+ //#region packages/filter-bar/index.tsx
8
+ var l = typeof window > "u" ? i : a, u = {
9
+ duration: 260,
10
+ easing: "cubic-bezier(0.2, 0.8, 0.2, 1)"
11
+ }, d = {
12
+ duration: 120,
13
+ easing: "ease-in"
14
+ };
15
+ function f({ onClear: t, clearLabel: n = "Clear all", "aria-label": i = "Active filters", className: a, children: l, ref: u, ...d }) {
16
+ let f = r.toArray(l).length, m = o(null);
17
+ return p(m), f === 0 ? null : /* @__PURE__ */ c("div", {
18
+ ref: (e) => {
19
+ if (m.current = e, typeof u == "function") return u(e);
20
+ u && (u.current = e);
21
+ },
22
+ role: "group",
23
+ "aria-label": i,
24
+ className: e("zen__filter-bar relative flex flex-wrap items-center gap-1.5", a),
25
+ ...d,
26
+ children: [l, f > 1 && t && /* @__PURE__ */ s("button", {
27
+ type: "button",
28
+ onClick: t,
29
+ className: "zen__filter-clear text-muted-foreground hover:text-foreground focus-visible:ring-ring/50 touch-target ml-1 cursor-pointer rounded-md px-1.5 py-1 text-xs outline-hidden focus-visible:ring-2",
30
+ children: n
31
+ })]
32
+ });
33
+ }
34
+ function p(e) {
35
+ let n = o(/* @__PURE__ */ new Map());
36
+ l(() => {
37
+ let r = e.current, i = n.current, a = /* @__PURE__ */ new Map();
38
+ for (let e of r ? [...r.children] : []) e instanceof HTMLElement && !e.dataset.zenLeaving && a.set(e, {
39
+ left: e.offsetLeft,
40
+ top: e.offsetTop
41
+ });
42
+ if (n.current = a, !r || t()) return;
43
+ let o = !1;
44
+ for (let [e, t] of i) {
45
+ if (e.isConnected || !(e instanceof HTMLElement)) continue;
46
+ o = !0, e.dataset.zenLeaving = "", e.setAttribute("aria-hidden", "true"), e.inert = !0, Object.assign(e.style, {
47
+ position: "absolute",
48
+ left: `${t.left}px`,
49
+ top: `${t.top}px`,
50
+ margin: "0",
51
+ animation: "none"
52
+ }), r.append(e);
53
+ let n = e.animate?.({
54
+ opacity: [1, 0],
55
+ scale: [1, .9]
56
+ }, d);
57
+ n ? n.onfinish = n.oncancel = () => e.remove() : e.remove();
58
+ }
59
+ let s = {
60
+ ...u,
61
+ delay: o ? d.duration : 0,
62
+ fill: "backwards"
63
+ };
64
+ for (let [e, t] of a) {
65
+ let n = i.get(e);
66
+ !n || n.left === t.left && n.top === t.top || (n.top === t.top ? e.animate?.({ translate: [`${n.left - t.left}px 0`, "0 0"] }, s) : e.animate?.({
67
+ opacity: [0, 1],
68
+ translate: ["0 3px", "0 0"]
69
+ }, {
70
+ ...s,
71
+ duration: 200,
72
+ delay: s.delay + u.duration * .6
73
+ }));
74
+ }
75
+ });
76
+ }
77
+ function m({ onRemove: t, removeLabel: r = "Remove filter", className: i, children: a }) {
78
+ return /* @__PURE__ */ c("span", {
79
+ className: e("zen__filter-chip bg-primary/12 text-foreground inline-flex items-center gap-1 rounded-full py-1 pr-1 pl-3 text-xs shadow-[inset_0_0_0_1px_oklch(var(--primary)/0.25)]", i),
80
+ children: [a, /* @__PURE__ */ s("button", {
81
+ type: "button",
82
+ "aria-label": r,
83
+ onClick: t,
84
+ className: "text-muted-foreground hover:text-foreground hover:bg-tint/10 focus-visible:ring-ring/50 touch-target grid size-5 cursor-pointer place-items-center rounded-full outline-hidden focus-visible:ring-2",
85
+ children: /* @__PURE__ */ s(n, { className: "size-3" })
86
+ })]
87
+ });
88
+ }
89
+ //#endregion
90
+ export { m as FilterChip, f as default };
@@ -0,0 +1,38 @@
1
+ import { ReactNode } from 'react';
2
+ /** The chart palette, so a category's colour matches it in charts. */
3
+ export declare const ICON_COLORS: IconColor[];
4
+ /**
5
+ * Pick an icon and a colour for something, e.g. a spending category: a button
6
+ * showing the choice opens a grid of icons and a row of colours. Icons are
7
+ * yours (emoji work); colours default to the chart palette. Both are radio
8
+ * groups, so arrow keys move through them.
9
+ */
10
+ export default function IconPicker({ icons, colors, value, onChange, label, className, }: IconPickerProps): import('react').JSX.Element;
11
+ export interface IconColor {
12
+ /** What's stored, e.g. "blue". */
13
+ value: string;
14
+ label: string;
15
+ /** Any CSS colour. */
16
+ color: string;
17
+ }
18
+ export interface IconPickerProps {
19
+ icons: {
20
+ value: string;
21
+ label: string;
22
+ icon: ReactNode;
23
+ }[];
24
+ /** Default: ICON_COLORS, the chart palette. */
25
+ colors?: IconColor[];
26
+ value: {
27
+ icon: string;
28
+ color?: string;
29
+ };
30
+ onChange: (value: {
31
+ icon: string;
32
+ color?: string;
33
+ }) => void;
34
+ /** What it's the icon of, e.g. "Category icon"; the button also says the current choice. */
35
+ label: string;
36
+ className?: string;
37
+ }
38
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/icon-picker/index.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAiB,SAAS,EAAS,MAAM,OAAO,CAAC;AAExD,sEAAsE;AACtE,eAAO,MAAM,WAAW,EAAE,SAAS,EASlC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EAC/B,KAAK,EACL,MAAoB,EACpB,KAAK,EACL,QAAQ,EACR,KAAK,EACL,SAAS,GACZ,EAAE,eAAe,+BAgEjB;AAED,MAAM,WAAW,SAAS;IACtB,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,sBAAsB;IACtB,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC5B,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,SAAS,CAAA;KAAE,EAAE,CAAC;IAC3D,+CAA+C;IAC/C,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IACrB,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,QAAQ,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC5D,4FAA4F;IAC5F,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB"}
@@ -0,0 +1,112 @@
1
+ "use client";
2
+ import { cx as e } from "../utils/cx.js";
3
+ import t, { PopoverContent as n, PopoverTrigger as r } from "../popover/index.js";
4
+ import { useId as i } from "react";
5
+ import { jsx as a, jsxs as o } from "react/jsx-runtime";
6
+ //#region packages/icon-picker/index.tsx
7
+ var s = [
8
+ {
9
+ value: "blue",
10
+ label: "Blue",
11
+ color: "var(--chart-1)"
12
+ },
13
+ {
14
+ value: "orange",
15
+ label: "Orange",
16
+ color: "var(--chart-2)"
17
+ },
18
+ {
19
+ value: "teal",
20
+ label: "Teal",
21
+ color: "var(--chart-3)"
22
+ },
23
+ {
24
+ value: "amber",
25
+ label: "Amber",
26
+ color: "var(--chart-4)"
27
+ },
28
+ {
29
+ value: "pink",
30
+ label: "Pink",
31
+ color: "var(--chart-5)"
32
+ },
33
+ {
34
+ value: "green",
35
+ label: "Green",
36
+ color: "var(--chart-6)"
37
+ },
38
+ {
39
+ value: "violet",
40
+ label: "Violet",
41
+ color: "var(--chart-7)"
42
+ },
43
+ {
44
+ value: "red",
45
+ label: "Red",
46
+ color: "var(--chart-8)"
47
+ }
48
+ ];
49
+ function c({ icons: c, colors: l = s, value: u, onChange: d, label: f, className: p }) {
50
+ let m = i(), h = c.find((e) => e.value === u.icon), g = l.find((e) => e.value === u.color), _ = (e) => ({ "--icon-color": e ?? "var(--color-muted-foreground)" });
51
+ return /* @__PURE__ */ o(t, { children: [/* @__PURE__ */ a(r, {
52
+ "aria-label": `${f}: ${[h?.label, g?.label].filter(Boolean).join(", ") || "none"}`,
53
+ style: _(g?.color),
54
+ className: e("zen__icon-picker focus-visible:ring-ring/50 grid size-10 shrink-0 place-items-center rounded-xl bg-[color-mix(in_oklch,var(--icon-color)_18%,transparent)] text-lg text-(--icon-color) outline-hidden transition-colors focus-visible:ring-2", p),
55
+ children: h?.icon
56
+ }), /* @__PURE__ */ o(n, {
57
+ "aria-label": f,
58
+ className: "flex w-72 flex-col gap-3 p-3",
59
+ children: [l.length > 0 && /* @__PURE__ */ o("fieldset", {
60
+ className: "flex flex-wrap gap-1.5",
61
+ children: [/* @__PURE__ */ a("legend", {
62
+ className: "text-muted-foreground mb-1.5 text-xs",
63
+ children: "Colour"
64
+ }), l.map((e) => /* @__PURE__ */ o("label", {
65
+ title: e.label,
66
+ className: "relative cursor-pointer",
67
+ children: [/* @__PURE__ */ a("input", {
68
+ type: "radio",
69
+ name: `${m}-color`,
70
+ "aria-label": e.label,
71
+ checked: u.color === e.value,
72
+ onChange: () => d({
73
+ ...u,
74
+ color: e.value
75
+ }),
76
+ className: "peer sr-only"
77
+ }), /* @__PURE__ */ a("span", {
78
+ "aria-hidden": !0,
79
+ style: { background: e.color },
80
+ className: "ring-offset-background peer-focus-visible:ring-ring/60 peer-checked:ring-foreground/70 block size-6 rounded-full ring-offset-2 transition-shadow peer-checked:ring-2 peer-focus-visible:ring-2"
81
+ })]
82
+ }, e.value))]
83
+ }), /* @__PURE__ */ o("fieldset", {
84
+ className: "grid grid-cols-6 gap-1",
85
+ style: _(g?.color),
86
+ children: [/* @__PURE__ */ a("legend", {
87
+ className: "text-muted-foreground mb-1.5 text-xs",
88
+ children: "Icon"
89
+ }), c.map((e) => /* @__PURE__ */ o("label", {
90
+ title: e.label,
91
+ className: "cursor-pointer",
92
+ children: [/* @__PURE__ */ a("input", {
93
+ type: "radio",
94
+ name: `${m}-icon`,
95
+ "aria-label": e.label,
96
+ checked: u.icon === e.value,
97
+ onChange: () => d({
98
+ ...u,
99
+ icon: e.value
100
+ }),
101
+ className: "peer sr-only"
102
+ }), /* @__PURE__ */ a("span", {
103
+ "aria-hidden": !0,
104
+ className: "hover:bg-tint/[0.07] peer-focus-visible:ring-ring/50 grid size-10 place-items-center rounded-lg text-lg transition-colors peer-checked:bg-[color-mix(in_oklch,var(--icon-color)_22%,transparent)] peer-checked:text-(--icon-color) peer-focus-visible:ring-2",
105
+ children: e.icon
106
+ })]
107
+ }, e.value))]
108
+ })]
109
+ })] });
110
+ }
111
+ //#endregion
112
+ export { s as ICON_COLORS, c as default };
@@ -0,0 +1,23 @@
1
+ "use client";
2
+ import { jsx as e } from "react/jsx-runtime";
3
+ //#region packages/icons/arrow-left.tsx
4
+ function t(t) {
5
+ return /* @__PURE__ */ e("svg", {
6
+ className: "size-6",
7
+ xmlns: "http://www.w3.org/2000/svg",
8
+ fill: "none",
9
+ viewBox: "0 0 24 24",
10
+ strokeWidth: "1.5",
11
+ stroke: "currentColor",
12
+ "aria-hidden": "true",
13
+ "data-slot": "icon",
14
+ ...t,
15
+ children: /* @__PURE__ */ e("path", {
16
+ strokeLinecap: "round",
17
+ strokeLinejoin: "round",
18
+ d: "M10.5 19.5 3 12m0 0 7.5-7.5M3 12h18"
19
+ })
20
+ });
21
+ }
22
+ //#endregion
23
+ export { t as default };
@@ -0,0 +1,3 @@
1
+ import { default as IconProps } from '../icon.types';
2
+ export default function ArrowTrendingDownMicro(props: IconProps): import('react').JSX.Element;
3
+ //# sourceMappingURL=arrow-trending-down.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arrow-trending-down.d.ts","sourceRoot":"","sources":["../../../packages/icons/micro/arrow-trending-down.tsx"],"names":[],"mappings":"AAEA,OAAO,SAAS,MAAM,eAAe,CAAC;AAEtC,MAAM,CAAC,OAAO,UAAU,sBAAsB,CAAC,KAAK,EAAE,SAAS,+BAkB9D"}
@@ -0,0 +1,21 @@
1
+ "use client";
2
+ import { jsx as e } from "react/jsx-runtime";
3
+ //#region packages/icons/micro/arrow-trending-down.tsx
4
+ function t(t) {
5
+ return /* @__PURE__ */ e("svg", {
6
+ className: "size-4",
7
+ xmlns: "http://www.w3.org/2000/svg",
8
+ viewBox: "0 0 16 16",
9
+ fill: "currentColor",
10
+ "aria-hidden": "true",
11
+ "data-slot": "icon",
12
+ ...t,
13
+ children: /* @__PURE__ */ e("path", {
14
+ fillRule: "evenodd",
15
+ d: "M1.22 4.22a.75.75 0 0 1 1.06 0L6 7.94l2.761-2.762a.75.75 0 0 1 1.158.12 24.9 24.9 0 0 1 2.718 5.556l.729-1.261a.75.75 0 0 1 1.299.75l-1.591 2.755a.75.75 0 0 1-1.025.275l-2.756-1.591a.75.75 0 1 1 .75-1.3l1.097.634a23.417 23.417 0 0 0-1.984-4.211L6.53 9.53a.75.75 0 0 1-1.06 0L1.22 5.28a.75.75 0 0 1 0-1.06Z",
16
+ clipRule: "evenodd"
17
+ })
18
+ });
19
+ }
20
+ //#endregion
21
+ export { t as default };
@@ -0,0 +1,3 @@
1
+ import { default as IconProps } from '../icon.types';
2
+ export default function ArrowTrendingUpMicro(props: IconProps): import('react').JSX.Element;
3
+ //# sourceMappingURL=arrow-trending-up.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arrow-trending-up.d.ts","sourceRoot":"","sources":["../../../packages/icons/micro/arrow-trending-up.tsx"],"names":[],"mappings":"AAEA,OAAO,SAAS,MAAM,eAAe,CAAC;AAEtC,MAAM,CAAC,OAAO,UAAU,oBAAoB,CAAC,KAAK,EAAE,SAAS,+BAkB5D"}