@cascivo/react 0.16.0 → 0.17.0

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 (99) hide show
  1. package/README.md +6 -1
  2. package/dist/accordion/accordion.js +5 -4
  3. package/dist/app-shell/app-shell.css +1 -1
  4. package/dist/app-shell/app-shell.js +28 -26
  5. package/dist/app-shell/app-shell.module.js +8 -8
  6. package/dist/badge/badge.js +1 -1
  7. package/dist/button/button.css +1 -1
  8. package/dist/button/button.js +4 -1
  9. package/dist/button/button.module.js +4 -1
  10. package/dist/calendar/calendar.js +67 -63
  11. package/dist/card/card.css +1 -1
  12. package/dist/card/card.module.js +8 -8
  13. package/dist/checkbox/checkbox.css +1 -1
  14. package/dist/checkbox/checkbox.module.js +4 -4
  15. package/dist/combobox/combobox.js +55 -54
  16. package/dist/context-menu/context-menu.js +42 -38
  17. package/dist/data-table/data-table.css +1 -1
  18. package/dist/data-table/data-table.js +155 -160
  19. package/dist/data-table/data-table.module.js +29 -29
  20. package/dist/date-picker/date-picker.js +90 -89
  21. package/dist/field/field.css +1 -1
  22. package/dist/field/field.module.js +3 -3
  23. package/dist/index.d.ts +307 -145
  24. package/dist/infinite-scroll/infinite-scroll.css +1 -0
  25. package/dist/infinite-scroll/infinite-scroll.js +49 -0
  26. package/dist/infinite-scroll/infinite-scroll.module.js +8 -0
  27. package/dist/large-title-header/large-title-header.css +1 -0
  28. package/dist/large-title-header/large-title-header.js +38 -0
  29. package/dist/large-title-header/large-title-header.module.js +13 -0
  30. package/dist/layouts/src/grid/grid.css +1 -1
  31. package/dist/layouts/src/grid/grid.module.js +3 -3
  32. package/dist/link/link.css +1 -1
  33. package/dist/link/link.module.js +1 -1
  34. package/dist/menu/menu.js +47 -43
  35. package/dist/node/accordion/accordion.js +5 -4
  36. package/dist/node/app-shell/app-shell.js +28 -26
  37. package/dist/node/app-shell/app-shell.module.js +8 -8
  38. package/dist/node/badge/badge.js +1 -1
  39. package/dist/node/button/button.js +4 -1
  40. package/dist/node/button/button.module.js +4 -1
  41. package/dist/node/calendar/calendar.js +67 -63
  42. package/dist/node/card/card.module.js +8 -8
  43. package/dist/node/checkbox/checkbox.module.js +4 -4
  44. package/dist/node/combobox/combobox.js +55 -54
  45. package/dist/node/context-menu/context-menu.js +42 -38
  46. package/dist/node/data-table/data-table.js +155 -160
  47. package/dist/node/data-table/data-table.module.js +29 -29
  48. package/dist/node/date-picker/date-picker.js +90 -89
  49. package/dist/node/field/field.module.js +3 -3
  50. package/dist/node/infinite-scroll/infinite-scroll.js +49 -0
  51. package/dist/node/infinite-scroll/infinite-scroll.module.js +7 -0
  52. package/dist/node/large-title-header/large-title-header.js +38 -0
  53. package/dist/node/large-title-header/large-title-header.module.js +12 -0
  54. package/dist/node/layouts/src/grid/grid.module.js +3 -3
  55. package/dist/node/link/link.module.js +1 -1
  56. package/dist/node/menu/menu.js +47 -43
  57. package/dist/node/react/src/index.js +27 -23
  58. package/dist/node/reorder-list/reorder-list.js +143 -0
  59. package/dist/node/reorder-list/reorder-list.module.js +11 -0
  60. package/dist/node/search/search.js +5 -4
  61. package/dist/node/side-nav/side-nav.js +90 -89
  62. package/dist/node/skip-nav/skip-nav.js +1 -0
  63. package/dist/node/swap/swap.js +2 -3
  64. package/dist/node/switcher/switcher.js +1 -1
  65. package/dist/node/tabs/tabs.js +41 -40
  66. package/dist/node/tag/tag.module.js +2 -2
  67. package/dist/node/toc/toc.js +5 -4
  68. package/dist/node/virtual-list/virtual-list.js +40 -0
  69. package/dist/node/virtual-list/virtual-list.module.js +7 -0
  70. package/dist/node/wheel-picker/wheel-picker.js +84 -0
  71. package/dist/node/wheel-picker/wheel-picker.module.js +8 -0
  72. package/dist/react/src/index.js +27 -23
  73. package/dist/reorder-list/reorder-list.css +1 -0
  74. package/dist/reorder-list/reorder-list.js +143 -0
  75. package/dist/reorder-list/reorder-list.module.js +12 -0
  76. package/dist/search/search.js +5 -4
  77. package/dist/side-nav/side-nav.js +90 -89
  78. package/dist/skip-nav/skip-nav.js +1 -0
  79. package/dist/styles.css +48 -11
  80. package/dist/swap/swap.js +2 -3
  81. package/dist/switcher/switcher.js +1 -1
  82. package/dist/tabs/tabs.js +41 -40
  83. package/dist/tag/tag.css +1 -1
  84. package/dist/tag/tag.module.js +2 -2
  85. package/dist/toc/toc.js +5 -4
  86. package/dist/virtual-list/virtual-list.css +1 -0
  87. package/dist/virtual-list/virtual-list.js +40 -0
  88. package/dist/virtual-list/virtual-list.module.js +8 -0
  89. package/dist/wheel-picker/wheel-picker.css +1 -0
  90. package/dist/wheel-picker/wheel-picker.js +84 -0
  91. package/dist/wheel-picker/wheel-picker.module.js +9 -0
  92. package/package.json +4 -4
  93. package/readme.body.md +6 -1
  94. package/dist/node/react/src/theme.js +0 -78
  95. package/dist/node/storage/src/drivers.js +0 -34
  96. package/dist/node/storage/src/persisted-signal.js +0 -41
  97. package/dist/react/src/theme.js +0 -78
  98. package/dist/storage/src/drivers.js +0 -34
  99. package/dist/storage/src/persisted-signal.js +0 -41
@@ -2,45 +2,46 @@
2
2
 
3
3
  import e from "./combobox.module.js";
4
4
  import { useId as t, useRef as n } from "react";
5
- import { cn as r, createMachine as i, focusElement as a, useMachine as o, useSignal as s, useSignalEffect as c, useSignals as l } from "@cascivo/core";
6
- import { builtin as u, t as d } from "@cascivo/i18n";
7
- import { jsx as f, jsxs as p } from "react/jsx-runtime";
5
+ import { cn as r, createMachine as i, focusElement as a, useControllableSignal as o, useMachine as s, useSignal as c, useSignalEffect as l, useSignals as u } from "@cascivo/core";
6
+ import { builtin as d, t as f } from "@cascivo/i18n";
7
+ import { jsx as p, jsxs as m } from "react/jsx-runtime";
8
8
  //#region ../components/src/combobox/combobox.tsx
9
- var m = i({
9
+ var h = i({
10
10
  initial: "closed",
11
11
  states: {
12
12
  closed: { on: { OPEN: "open" } },
13
13
  open: { on: { CLOSE: "closed" } }
14
14
  }
15
15
  });
16
- function h({ options: i, value: h, defaultValue: g, onValueChange: _, onChange: v, clearable: y = !1, searchable: b = !0, label: x, hint: S, error: C, size: w = "md", disabled: T = !1, labels: E, className: D, id: O }) {
17
- l();
18
- let [k, A] = o(m), j = t(), M = O ?? `cascade-combobox-${j}`, N = `${j}-listbox`, P = n(null), F = E?.placeholder ?? d(u.combobox.placeholder), I = E?.empty ?? d(u.combobox.empty), L = E?.clear ?? d(u.combobox.clear), R = E?.search ?? d(u.combobox.search), z = s(h ?? g);
19
- h !== void 0 && (z.value = h);
20
- let B = s(""), V = s(0), H = k.value === "open", U = i.filter((e) => !b || !B.value ? !0 : e.label.toLowerCase().includes(B.value.toLowerCase())), W = i.find((e) => e.value === z.value);
21
- c(() => {
16
+ function g({ options: i, value: g, defaultValue: _, onValueChange: v, onChange: y, clearable: b = !1, searchable: x = !0, label: S, hint: C, error: w, size: T = "md", disabled: E = !1, labels: D, className: O, id: k }) {
17
+ u();
18
+ let [A, j] = s(h), M = t(), N = k ?? `cascade-combobox-${M}`, P = `${M}-listbox`, F = n(null), ee = D?.placeholder ?? f(d.combobox.placeholder), I = D?.empty ?? f(d.combobox.empty), L = D?.clear ?? f(d.combobox.clear), R = D?.search ?? f(d.combobox.search), [z] = o({
19
+ value: g,
20
+ defaultValue: _
21
+ }), B = c(""), V = c(0), H = A.value === "open", U = i.filter((e) => !x || !B.value ? !0 : e.label.toLowerCase().includes(B.value.toLowerCase())), W = i.find((e) => e.value === z.value);
22
+ l(() => {
22
23
  if (!H) return;
23
24
  let e = (e) => {
24
- let t = document.getElementById(`${j}-root`);
25
- t && !t.contains(e.target) && A("CLOSE");
25
+ let t = document.getElementById(`${M}-root`);
26
+ t && !t.contains(e.target) && j("CLOSE");
26
27
  };
27
28
  return document.addEventListener("mousedown", e), () => document.removeEventListener("mousedown", e);
28
29
  });
29
30
  let G = () => {
30
- T || (B.value = "", V.value = 0, A("OPEN"), setTimeout(() => a(P.current), 0));
31
+ E || (B.value = "", V.value = 0, j("OPEN"), setTimeout(() => a(F.current), 0));
31
32
  }, K = () => {
32
- A("CLOSE"), B.value = "";
33
- }, q = _ ?? v, J = (e) => {
34
- h === void 0 && (z.value = e), q?.(e), K();
33
+ j("CLOSE"), B.value = "";
34
+ }, q = v ?? y, J = (e) => {
35
+ g === void 0 && (z.value = e), q?.(e), K();
35
36
  }, Y = () => {
36
- h === void 0 && (z.value = void 0), q?.(void 0);
37
+ g === void 0 && (z.value = void 0), q?.(void 0);
37
38
  }, X = U.flatMap((e, t) => e.disabled ? [] : [t]), Z = (e) => {
38
39
  if (X.length === 0) return;
39
40
  let t = X[(X.indexOf(V.value) + e + X.length) % X.length];
40
41
  t !== void 0 && (V.value = t);
41
42
  }, Q = (e) => {
42
43
  (e.key === "Enter" || e.key === " " || e.key === "ArrowDown") && (e.preventDefault(), G());
43
- }, ee = (e) => {
44
+ }, te = (e) => {
44
45
  switch (e.key) {
45
46
  case "ArrowDown":
46
47
  e.preventDefault(), Z(1);
@@ -61,42 +62,42 @@ function h({ options: i, value: h, defaultValue: g, onValueChange: _, onChange:
61
62
  K();
62
63
  break;
63
64
  }
64
- }, $ = (e) => `${j}-option-${e}`;
65
- return /* @__PURE__ */ p("div", {
66
- id: `${j}-root`,
67
- className: r(e.wrapper, D),
68
- "data-state": C ? "error" : k.value,
69
- "data-size": w,
65
+ }, $ = (e) => `${M}-option-${e}`;
66
+ return /* @__PURE__ */ m("div", {
67
+ id: `${M}-root`,
68
+ className: r(e.wrapper, O),
69
+ "data-state": w ? "error" : A.value,
70
+ "data-size": T,
70
71
  children: [
71
- x && /* @__PURE__ */ f("label", {
72
+ S && /* @__PURE__ */ p("label", {
72
73
  className: e.label,
73
- htmlFor: M,
74
- children: x
74
+ htmlFor: N,
75
+ children: S
75
76
  }),
76
- /* @__PURE__ */ p("div", {
77
+ /* @__PURE__ */ m("div", {
77
78
  className: e.field,
78
- children: [/* @__PURE__ */ p("button", {
79
- id: M,
79
+ children: [/* @__PURE__ */ m("button", {
80
+ id: N,
80
81
  type: "button",
81
82
  role: "combobox",
82
83
  "aria-expanded": H,
83
- "aria-controls": N,
84
+ "aria-controls": P,
84
85
  "aria-haspopup": "listbox",
85
86
  "aria-activedescendant": H && V.value >= 0 ? $(V.value) : void 0,
86
- "aria-invalid": C ? !0 : void 0,
87
- "aria-describedby": C ? `${j}-error` : S ? `${j}-hint` : void 0,
87
+ "aria-invalid": w ? !0 : void 0,
88
+ "aria-describedby": w ? `${M}-error` : C ? `${M}-hint` : void 0,
88
89
  className: e.trigger,
89
- disabled: T,
90
+ disabled: E,
90
91
  onKeyDown: Q,
91
92
  onClick: H ? K : G,
92
- children: [/* @__PURE__ */ f("span", {
93
+ children: [/* @__PURE__ */ p("span", {
93
94
  className: r(e.value, W ? void 0 : e.placeholder),
94
- children: W?.label ?? F
95
- }), /* @__PURE__ */ f("span", {
95
+ children: W?.label ?? ee
96
+ }), /* @__PURE__ */ p("span", {
96
97
  className: e.chevron,
97
98
  "aria-hidden": "true"
98
99
  })]
99
- }), y && z.value !== void 0 && /* @__PURE__ */ f("button", {
100
+ }), b && z.value !== void 0 && /* @__PURE__ */ p("button", {
100
101
  type: "button",
101
102
  className: e.clear,
102
103
  "aria-label": L,
@@ -106,30 +107,30 @@ function h({ options: i, value: h, defaultValue: g, onValueChange: _, onChange:
106
107
  children: "✕"
107
108
  })]
108
109
  }),
109
- /* @__PURE__ */ p("div", {
110
+ /* @__PURE__ */ m("div", {
110
111
  role: "listbox",
111
- id: N,
112
+ id: P,
112
113
  className: e.listbox,
113
114
  "data-state": H ? "open" : "closed",
114
- "aria-label": x,
115
- children: [b && H && /* @__PURE__ */ f("div", {
115
+ "aria-label": S,
116
+ children: [x && H && /* @__PURE__ */ p("div", {
116
117
  className: e.searchWrapper,
117
- children: /* @__PURE__ */ f("input", {
118
- ref: P,
118
+ children: /* @__PURE__ */ p("input", {
119
+ ref: F,
119
120
  type: "text",
120
121
  className: e.search,
121
122
  value: B.value,
122
123
  onChange: (e) => {
123
124
  B.value = e.target.value, V.value = 0;
124
125
  },
125
- onKeyDown: ee,
126
+ onKeyDown: te,
126
127
  "aria-label": R,
127
128
  autoComplete: "off"
128
129
  })
129
- }), U.length === 0 ? /* @__PURE__ */ f("div", {
130
+ }), U.length === 0 ? /* @__PURE__ */ p("div", {
130
131
  className: e.empty,
131
132
  children: I
132
- }) : U.map((t, n) => /* @__PURE__ */ f("div", {
133
+ }) : U.map((t, n) => /* @__PURE__ */ p("div", {
133
134
  id: $(n),
134
135
  role: "option",
135
136
  "aria-selected": t.value === z.value,
@@ -146,19 +147,19 @@ function h({ options: i, value: h, defaultValue: g, onValueChange: _, onChange:
146
147
  children: t.label
147
148
  }, t.value))]
148
149
  }),
149
- C && /* @__PURE__ */ f("span", {
150
- id: `${j}-error`,
150
+ w && /* @__PURE__ */ p("span", {
151
+ id: `${M}-error`,
151
152
  className: e.error,
152
153
  role: "alert",
153
- children: C
154
+ children: w
154
155
  }),
155
- !C && S && /* @__PURE__ */ f("span", {
156
- id: `${j}-hint`,
156
+ !w && C && /* @__PURE__ */ p("span", {
157
+ id: `${M}-hint`,
157
158
  className: e.hint,
158
- children: S
159
+ children: C
159
160
  })
160
161
  ]
161
162
  });
162
163
  }
163
164
  //#endregion
164
- export { h as Combobox };
165
+ export { g as Combobox };
@@ -1,89 +1,93 @@
1
1
  "use client";
2
2
 
3
3
  import e from "./context-menu.module.js";
4
- import { useRef as t } from "react";
5
- import { useSignal as n, useSignalEffect as r, useSignals as i } from "@cascivo/core";
6
- import { jsx as a, jsxs as o } from "react/jsx-runtime";
4
+ import { Children as t, isValidElement as n, useRef as r } from "react";
5
+ import { useSignal as i, useSignalEffect as a, useSignals as o } from "@cascivo/core";
6
+ import { jsx as s, jsxs as c } from "react/jsx-runtime";
7
7
  //#region ../components/src/context-menu/context-menu.tsx
8
- function s({ children: s }) {
9
- i();
10
- let c = t(null), l = t(null), u = n(!1), d = () => {
11
- let e = c.current;
8
+ function l() {
9
+ return globalThis.process?.env?.NODE_ENV !== "production";
10
+ }
11
+ function u({ children: u }) {
12
+ o();
13
+ let f = r(null), p = r(null), m = i(!1), h = () => {
14
+ let e = f.current;
12
15
  return e ? Array.from(e.querySelectorAll("[role=\"menuitem\"]:not([aria-disabled=\"true\"])")) : [];
13
- }, f = (e) => {
14
- let t = d();
16
+ }, g = (e) => {
17
+ let t = h();
15
18
  t.length !== 0 && t[e(t, t.indexOf(document.activeElement))]?.focus();
16
- }, p = (e) => {
19
+ }, _ = (e) => {
17
20
  switch (e.key) {
18
21
  case "ArrowDown":
19
- e.preventDefault(), f((e, t) => t < 0 ? 0 : (t + 1) % e.length);
22
+ e.preventDefault(), g((e, t) => t < 0 ? 0 : (t + 1) % e.length);
20
23
  break;
21
24
  case "ArrowUp":
22
- e.preventDefault(), f((e, t) => t < 0 ? e.length - 1 : (t - 1 + e.length) % e.length);
25
+ e.preventDefault(), g((e, t) => t < 0 ? e.length - 1 : (t - 1 + e.length) % e.length);
23
26
  break;
24
27
  case "Home":
25
- e.preventDefault(), f(() => 0);
28
+ e.preventDefault(), g(() => 0);
26
29
  break;
27
30
  case "End":
28
- e.preventDefault(), f((e) => e.length - 1);
31
+ e.preventDefault(), g((e) => e.length - 1);
29
32
  break;
30
33
  }
31
34
  };
32
- r(() => {
33
- let e = c.current;
34
- if (e) if (u.value) {
35
+ a(() => {
36
+ let e = f.current;
37
+ if (e) if (m.value) {
35
38
  try {
36
39
  e.showPopover();
37
40
  } catch {}
38
- d()[0]?.focus();
41
+ h()[0]?.focus();
39
42
  } else try {
40
43
  e.hidePopover();
41
44
  } catch {}
42
- }), r(() => {
43
- let e = c.current;
45
+ }), a(() => {
46
+ let e = f.current;
44
47
  if (!e) return;
45
48
  let t = (e) => {
46
- e.newState === "closed" && (u.value = !1);
49
+ e.newState === "closed" && (m.value = !1);
47
50
  };
48
51
  return e.addEventListener("toggle", t), () => e.removeEventListener("toggle", t);
49
52
  });
50
- function m(e) {
53
+ function v(e) {
51
54
  e.preventDefault();
52
- let t = l.current;
53
- t && (t.style.setProperty("--cascivo-context-x", `${e.clientX}px`), t.style.setProperty("--cascivo-context-y", `${e.clientY}px`), u.value = !0);
55
+ let t = p.current;
56
+ t && (t.style.setProperty("--cascivo-context-x", `${e.clientX}px`), t.style.setProperty("--cascivo-context-y", `${e.clientY}px`), m.value = !0);
54
57
  }
55
- let [h, ...g] = Array.isArray(s) ? s : [s];
56
- return /* @__PURE__ */ o("div", {
57
- ref: l,
58
- onContextMenu: m,
58
+ let y = t.toArray(u), b = y.filter((e) => n(e) && e.type === d), x = y.filter((e) => !b.includes(e));
59
+ if (b.length === 0 && l()) throw Error("<ContextMenu> requires at least one <ContextMenuItem> child. Items are matched by component identity, so they must be direct children — not wrapped in a fragment or another component.");
60
+ return /* @__PURE__ */ c("div", {
61
+ ref: p,
62
+ onContextMenu: v,
59
63
  className: e.wrapper,
60
- children: [h, /* @__PURE__ */ a("div", {
61
- ref: c,
64
+ children: [x, /* @__PURE__ */ s("div", {
65
+ ref: f,
62
66
  popover: "auto",
63
67
  role: "menu",
64
- "data-state": u.value ? "open" : "closed",
68
+ "data-state": m.value ? "open" : "closed",
65
69
  className: e.menu,
66
- onKeyDown: p,
67
- children: g
70
+ onKeyDown: _,
71
+ children: b
68
72
  })]
69
73
  });
70
74
  }
71
- function c({ children: t, onSelect: n, disabled: r }) {
75
+ function d({ children: t, onSelect: n, disabled: r }) {
72
76
  function i() {
73
77
  r || n();
74
78
  }
75
- function o(e) {
79
+ function a(e) {
76
80
  (e.key === "Enter" || e.key === " ") && (e.preventDefault(), i());
77
81
  }
78
- return /* @__PURE__ */ a("div", {
82
+ return /* @__PURE__ */ s("div", {
79
83
  role: "menuitem",
80
84
  tabIndex: r ? -1 : 0,
81
85
  "aria-disabled": r,
82
86
  onClick: i,
83
- onKeyDown: o,
87
+ onKeyDown: a,
84
88
  className: e.item,
85
89
  children: t
86
90
  });
87
91
  }
88
92
  //#endregion
89
- export { s as ContextMenu, c as ContextMenuItem };
93
+ export { u as ContextMenu, d as ContextMenuItem };
@@ -1 +1 @@
1
- @layer cascivo.component{._root_1wd65_2{--_row-height:3rem;font-family:var(--cascivo-font-sans);font-size:var(--cascivo-text-sm);color:var(--cascivo-color-text);border:1px solid var(--cascivo-color-border);border-radius:var(--cascivo-radius-surface);background-color:var(--cascivo-color-surface);flex-direction:column;display:flex;overflow:hidden}._root_1wd65_2[data-density=compact]{--_row-height:2.25rem}._root_1wd65_2[data-density=normal]{--_row-height:3rem}._root_1wd65_2[data-density=relaxed]{--_row-height:3.75rem}._toolbar_1wd65_26{justify-content:space-between;align-items:flex-end;gap:var(--cascivo-space-4);padding:var(--cascivo-space-3) var(--cascivo-space-4);border-block-end:1px solid var(--cascivo-color-border);display:flex}._heading_1wd65_35{gap:var(--cascivo-space-1);flex-direction:column;display:flex}._title_1wd65_41{font-size:var(--cascivo-text-base);font-weight:var(--cascivo-font-semibold);color:var(--cascivo-color-text)}._description_1wd65_47{font-size:var(--cascivo-text-sm);color:var(--cascivo-color-text-subtle)}._search_1wd65_52{appearance:none;height:2rem;min-inline-size:14rem;padding-inline:var(--cascivo-space-3);font-family:var(--cascivo-font-sans);font-size:var(--cascivo-text-sm);color:var(--cascivo-color-text);background-color:var(--cascivo-color-surface);border:1px solid var(--cascivo-color-border);border-radius:var(--cascivo-radius-field);transition:border-color var(--cascivo-duration-150) var(--cascivo-ease-out), box-shadow var(--cascivo-duration-150) var(--cascivo-ease-out);outline:none}._search_1wd65_52:hover:not(:focus){border-color:var(--cascivo-color-border-strong)}._search_1wd65_52:focus-visible{border-color:var(--cascivo-color-accent);box-shadow:0 0 0 3px color-mix(in srgb, var(--cascivo-color-accent) 20%, transparent)}._batchBar_1wd65_79{justify-content:space-between;align-items:center;gap:var(--cascivo-space-4);padding:var(--cascivo-space-2) var(--cascivo-space-4);background-color:var(--cascivo-color-bg-subtle);border-block-end:1px solid var(--cascivo-color-border);display:flex}._batchCount_1wd65_89{font-size:var(--cascivo-text-sm);font-weight:var(--cascivo-font-medium);color:var(--cascivo-color-text)}._batchActions_1wd65_95{gap:var(--cascivo-space-2);display:flex}._scroller_1wd65_101{max-block-size:var(--cascivo-data-table-max-height,none);scrollbar-gutter:stable;overflow:auto}._scrollerVirtualized_1wd65_111{block-size:var(--cascivo-data-table-height,400px);max-block-size:none;overflow:auto}._table_1wd65_117{border-collapse:collapse;table-layout:auto;inline-size:100%}._root_1wd65_2[data-paginated=true][data-fixed-layout=true] ._table_1wd65_117{table-layout:fixed}._table_1wd65_117 thead th{padding-block:var(--cascivo-space-2);padding-inline:var(--cascivo-data-table-cell-gap,var(--cascivo-space-4));text-align:start;font-weight:var(--cascivo-font-semibold);font-size:var(--cascivo-text-xs);text-transform:uppercase;letter-spacing:var(--cascivo-tracking-wide);color:var(--cascivo-color-text-subtle);background-color:var(--cascivo-color-bg-subtle);border-block-end:1px solid var(--cascivo-color-border);white-space:nowrap}._table_1wd65_117 thead th[data-align=end]{text-align:end}._table_1wd65_117 td{padding-block:0;padding-inline:var(--cascivo-data-table-cell-gap,var(--cascivo-space-4));block-size:var(--_row-height);vertical-align:middle;border-block-end:1px solid var(--cascivo-color-border);color:var(--cascivo-color-text)}._table_1wd65_117 td[data-sized],._table_1wd65_117 th[data-sized]{overflow-wrap:break-word;min-inline-size:min-content}._table_1wd65_117 td[data-align=end]{text-align:end}._table_1wd65_117 tbody tr[data-filler-row] td{border-block-end:none}._root_1wd65_2[data-sticky-header=true] ._table_1wd65_117 thead th{z-index:var(--cascivo-z-raised,10);background-color:var(--cascivo-color-surface);position:sticky;inset-block-start:0}._root_1wd65_2[data-zebra=true] ._table_1wd65_117 tbody tr:nth-child(2n of ._row_1wd65_199){background-color:var(--cascivo-color-bg-subtle)}._controlCol_1wd65_205{inline-size:3rem}._controlCell_1wd65_209{text-align:center;padding-inline:var(--cascivo-space-2)}._sortButton_1wd65_215{align-items:center;gap:var(--cascivo-space-1);font-family:inherit;font-size:inherit;font-weight:inherit;text-transform:inherit;letter-spacing:inherit;color:inherit;cursor:pointer;background:0 0;border:none;outline:none;padding:0;display:inline-flex}._sortButton_1wd65_215:focus-visible{text-decoration:underline}._sortButton_1wd65_215:after{content:"↕";opacity:.4;font-size:.75em}._sortButton_1wd65_215[data-state=ascending]:after{content:"↑";opacity:.9}._sortButton_1wd65_215[data-state=descending]:after{content:"↓";opacity:.9}._row_1wd65_199{content-visibility:auto;contain-intrinsic-size:auto var(--_row-height,3rem)}._row_1wd65_199[data-state=selected] td{background-color:color-mix(in srgb, var(--cascivo-color-accent) 8%, transparent)}._emptyCell_1wd65_263{padding:var(--cascivo-space-8) var(--cascivo-space-4);text-align:center;color:var(--cascivo-color-text-muted)}._expansionRow_1wd65_270[data-state=closed]{display:none}._expansionGrid_1wd65_276{overflow:hidden}._expansionInner_1wd65_280{padding:var(--cascivo-space-4)}._expandButton_1wd65_285{cursor:pointer;block-size:1.5rem;inline-size:1.5rem;color:var(--cascivo-color-text-muted);border-radius:var(--cascivo-radius-control);background:0 0;border:none;outline:none;justify-content:center;align-items:center;display:inline-flex}._expandButton_1wd65_285:focus-visible{box-shadow:0 0 0 2px var(--cascivo-color-accent)}._expandButton_1wd65_285:hover{color:var(--cascivo-color-text);background-color:var(--cascivo-color-bg-subtle)}._chevron_1wd65_308{block-size:.75rem;inline-size:.75rem;transition:transform var(--cascivo-duration-150) var(--cascivo-ease-out);border-block-end:2px solid;border-inline-end:2px solid;display:block;transform:rotate(45deg)}._expandButton_1wd65_285[data-state=open] ._chevron_1wd65_308{transform:rotate(-135deg)}._shimmer_1wd65_323{background-color:var(--cascivo-color-bg-subtle);border-radius:var(--cascivo-radius-indicator);block-size:.875rem;inline-size:80%;display:block;position:relative;overflow:hidden}._shimmer_1wd65_323:after{content:"";background:linear-gradient(90deg, transparent, var(--cascivo-color-surface), transparent);animation:_shimmer_1wd65_323 var(--cascivo-duration-500,.5s) var(--cascivo-ease-in-out,ease-in-out) infinite;position:absolute;inset:0;translate:-100%}@keyframes _shimmer_1wd65_323{to{translate:100%}}._footer_1wd65_350{justify-content:flex-end;align-items:center;gap:var(--cascivo-space-4);padding:var(--cascivo-space-3) var(--cascivo-space-4);border-block-start:1px solid var(--cascivo-color-border);font-size:var(--cascivo-text-sm);display:flex}._pageSize_1wd65_360{align-items:center;gap:var(--cascivo-space-2);color:var(--cascivo-color-text-muted);display:flex}._pageSize_1wd65_360 select{appearance:none;height:2rem;padding-inline:var(--cascivo-space-2);font-family:var(--cascivo-font-sans);font-size:var(--cascivo-text-sm);color:var(--cascivo-color-text);background-color:var(--cascivo-color-surface);border:1px solid var(--cascivo-color-border);border-radius:var(--cascivo-radius-field);cursor:pointer;outline:none}._pageSize_1wd65_360 select:focus-visible{border-color:var(--cascivo-color-accent);box-shadow:0 0 0 3px color-mix(in srgb, var(--cascivo-color-accent) 20%, transparent)}._range_1wd65_386{color:var(--cascivo-color-text-muted);white-space:nowrap}._pageButtons_1wd65_391{gap:var(--cascivo-space-1);display:flex}._pageButton_1wd65_391{border:1px solid var(--cascivo-color-border);border-radius:var(--cascivo-radius-control);cursor:pointer;block-size:2rem;inline-size:2rem;color:var(--cascivo-color-text);font-size:var(--cascivo-text-base);transition:background-color var(--cascivo-duration-150) var(--cascivo-ease-out), border-color var(--cascivo-duration-150) var(--cascivo-ease-out);background:0 0;outline:none;justify-content:center;align-items:center;display:inline-flex}._pageButton_1wd65_391:hover:not(:disabled){background-color:var(--cascivo-color-bg-subtle);border-color:var(--cascivo-color-border-strong)}._pageButton_1wd65_391:focus-visible{border-color:var(--cascivo-color-accent);box-shadow:0 0 0 3px color-mix(in srgb, var(--cascivo-color-accent) 20%, transparent)}._pageButton_1wd65_391:disabled{color:var(--cascivo-color-text-muted);cursor:not-allowed}._srOnly_1wd65_432{clip-path:inset(50%);white-space:nowrap;block-size:1px;inline-size:1px;position:absolute;overflow:hidden}}
1
+ @layer cascivo.component{._root_bwapn_2{--_row-height:3rem;font-family:var(--cascivo-font-sans);font-size:var(--cascivo-text-sm);color:var(--cascivo-color-text);border:1px solid var(--cascivo-color-border);border-radius:var(--cascivo-radius-surface);background-color:var(--cascivo-color-surface);flex-direction:column;display:flex;overflow:hidden}._root_bwapn_2[data-density=compact]{--_row-height:2.25rem}._root_bwapn_2[data-density=normal]{--_row-height:3rem}._root_bwapn_2[data-density=relaxed]{--_row-height:3.75rem}._toolbar_bwapn_26{justify-content:space-between;align-items:flex-end;gap:var(--cascivo-space-4);padding:var(--cascivo-space-3) var(--cascivo-space-4);border-block-end:1px solid var(--cascivo-color-border);display:flex}._heading_bwapn_35{gap:var(--cascivo-space-1);flex-direction:column;display:flex}._title_bwapn_41{font-size:var(--cascivo-text-base);font-weight:var(--cascivo-font-semibold);color:var(--cascivo-color-text)}._description_bwapn_47{font-size:var(--cascivo-text-sm);color:var(--cascivo-color-text-subtle)}._search_bwapn_52{appearance:none;height:2rem;min-inline-size:14rem;padding-inline:var(--cascivo-space-3);font-family:var(--cascivo-font-sans);font-size:var(--cascivo-text-sm);color:var(--cascivo-color-text);background-color:var(--cascivo-color-surface);border:1px solid var(--cascivo-color-border);border-radius:var(--cascivo-radius-field);transition:border-color var(--cascivo-duration-150) var(--cascivo-ease-out), box-shadow var(--cascivo-duration-150) var(--cascivo-ease-out);outline:none}._search_bwapn_52:hover:not(:focus){border-color:var(--cascivo-color-border-strong)}._search_bwapn_52:focus-visible{border-color:var(--cascivo-color-accent);box-shadow:0 0 0 3px color-mix(in srgb, var(--cascivo-color-accent) 20%, transparent)}._batchBar_bwapn_79{justify-content:space-between;align-items:center;gap:var(--cascivo-space-4);padding:var(--cascivo-space-2) var(--cascivo-space-4);background-color:var(--cascivo-color-bg-subtle);border-block-end:1px solid var(--cascivo-color-border);display:flex}._batchCount_bwapn_89{font-size:var(--cascivo-text-sm);font-weight:var(--cascivo-font-medium);color:var(--cascivo-color-text)}._batchActions_bwapn_95{gap:var(--cascivo-space-2);display:flex}._scroller_bwapn_101{max-block-size:var(--cascivo-data-table-max-height,none);scrollbar-gutter:stable;overflow:auto}._scrollerVirtualized_bwapn_111{block-size:var(--cascivo-data-table-height,400px);max-block-size:none;overflow:auto}._table_bwapn_117{border-collapse:collapse;table-layout:auto;inline-size:100%}._root_bwapn_2[data-paginated=true][data-fixed-layout=true] ._table_bwapn_117{table-layout:fixed}._table_bwapn_117 thead th{padding-block:var(--cascivo-space-2);padding-inline:var(--cascivo-data-table-cell-gap,var(--cascivo-space-4));text-align:start;font-weight:var(--cascivo-font-semibold);font-size:var(--cascivo-text-xs);text-transform:uppercase;letter-spacing:var(--cascivo-tracking-wide);color:var(--cascivo-color-text-subtle);background-color:var(--cascivo-color-bg-subtle);border-block-end:1px solid var(--cascivo-color-border);white-space:nowrap}._table_bwapn_117 thead th[data-align=end]{text-align:end}._table_bwapn_117 td{padding-block:0;padding-inline:var(--cascivo-data-table-cell-gap,var(--cascivo-space-4));block-size:var(--_row-height);vertical-align:middle;border-block-end:1px solid var(--cascivo-color-border);color:var(--cascivo-color-text)}._table_bwapn_117 td[data-sized],._table_bwapn_117 th[data-sized]{overflow-wrap:break-word;min-inline-size:min-content}._table_bwapn_117 td[data-align=end]{text-align:end}._table_bwapn_117 tbody tr[data-filler-row] td{border-block-end:none}._root_bwapn_2[data-sticky-header=true] ._table_bwapn_117 thead th{z-index:var(--cascivo-z-raised,10);background-color:var(--cascivo-color-surface);position:sticky;inset-block-start:0}._root_bwapn_2[data-zebra=true] ._table_bwapn_117 tbody tr:nth-child(2n of ._row_bwapn_199){background-color:var(--cascivo-table-zebra-bg,color-mix(in oklab, var(--cascivo-color-text) 5%, transparent))}._controlCol_bwapn_219{inline-size:3rem}._controlCell_bwapn_223{text-align:center;padding-inline:var(--cascivo-space-2)}._sortButton_bwapn_229{align-items:center;gap:var(--cascivo-space-1);font-family:inherit;font-size:inherit;font-weight:inherit;text-transform:inherit;letter-spacing:inherit;color:inherit;cursor:pointer;background:0 0;border:none;outline:none;padding:0;display:inline-flex}._sortButton_bwapn_229:focus-visible{text-decoration:underline}._sortButton_bwapn_229:after{content:"↕";opacity:.4;font-size:.75em}._sortButton_bwapn_229[data-state=ascending]:after{content:"↑";opacity:.9}._sortButton_bwapn_229[data-state=descending]:after{content:"↓";opacity:.9}._row_bwapn_199{content-visibility:auto;contain-intrinsic-size:auto var(--_row-height,3rem)}._row_bwapn_199[data-state=selected] td{background-color:color-mix(in srgb, var(--cascivo-color-accent) 8%, transparent)}._emptyCell_bwapn_277{padding:var(--cascivo-space-8) var(--cascivo-space-4);text-align:center;color:var(--cascivo-color-text-muted)}._expansionRow_bwapn_284[data-state=closed]{display:none}._expansionGrid_bwapn_290{overflow:hidden}._expansionInner_bwapn_294{padding:var(--cascivo-space-4)}._expandButton_bwapn_299{cursor:pointer;block-size:1.5rem;inline-size:1.5rem;color:var(--cascivo-color-text-muted);border-radius:var(--cascivo-radius-control);background:0 0;border:none;outline:none;justify-content:center;align-items:center;display:inline-flex}._expandButton_bwapn_299:focus-visible{box-shadow:0 0 0 2px var(--cascivo-color-accent)}._expandButton_bwapn_299:hover{color:var(--cascivo-color-text);background-color:var(--cascivo-color-bg-subtle)}._chevron_bwapn_322{block-size:.75rem;inline-size:.75rem;transition:transform var(--cascivo-duration-150) var(--cascivo-ease-out);border-block-end:2px solid;border-inline-end:2px solid;display:block;transform:rotate(45deg)}._expandButton_bwapn_299[data-state=open] ._chevron_bwapn_322{transform:rotate(-135deg)}._shimmer_bwapn_337{background-color:var(--cascivo-color-bg-subtle);border-radius:var(--cascivo-radius-indicator);block-size:.875rem;inline-size:80%;display:block;position:relative;overflow:hidden}._shimmer_bwapn_337:after{content:"";background:linear-gradient(90deg, transparent, var(--cascivo-color-surface), transparent);animation:_shimmer_bwapn_337 var(--cascivo-duration-500,.5s) var(--cascivo-ease-in-out,ease-in-out) infinite;position:absolute;inset:0;translate:-100%}@keyframes _shimmer_bwapn_337{to{translate:100%}}._footer_bwapn_364{justify-content:flex-end;align-items:center;gap:var(--cascivo-space-4);padding:var(--cascivo-space-3) var(--cascivo-space-4);border-block-start:1px solid var(--cascivo-color-border);font-size:var(--cascivo-text-sm);display:flex}._pageSize_bwapn_374{align-items:center;gap:var(--cascivo-space-2);color:var(--cascivo-color-text-muted);display:flex}._pageSize_bwapn_374 select{appearance:none;height:2rem;padding-inline:var(--cascivo-space-2);font-family:var(--cascivo-font-sans);font-size:var(--cascivo-text-sm);color:var(--cascivo-color-text);background-color:var(--cascivo-color-surface);border:1px solid var(--cascivo-color-border);border-radius:var(--cascivo-radius-field);cursor:pointer;outline:none}._pageSize_bwapn_374 select:focus-visible{border-color:var(--cascivo-color-accent);box-shadow:0 0 0 3px color-mix(in srgb, var(--cascivo-color-accent) 20%, transparent)}._range_bwapn_400{color:var(--cascivo-color-text-muted);white-space:nowrap}._pageButtons_bwapn_405{gap:var(--cascivo-space-1);display:flex}._pageButton_bwapn_405{border:1px solid var(--cascivo-color-border);border-radius:var(--cascivo-radius-control);cursor:pointer;block-size:2rem;inline-size:2rem;color:var(--cascivo-color-text);font-size:var(--cascivo-text-base);transition:background-color var(--cascivo-duration-150) var(--cascivo-ease-out), border-color var(--cascivo-duration-150) var(--cascivo-ease-out);background:0 0;outline:none;justify-content:center;align-items:center;display:inline-flex}._pageButton_bwapn_405:hover:not(:disabled){background-color:var(--cascivo-color-bg-subtle);border-color:var(--cascivo-color-border-strong)}._pageButton_bwapn_405:focus-visible{border-color:var(--cascivo-color-accent);box-shadow:0 0 0 3px color-mix(in srgb, var(--cascivo-color-accent) 20%, transparent)}._pageButton_bwapn_405:disabled{color:var(--cascivo-color-text-muted);cursor:not-allowed}._srOnly_bwapn_446{clip-path:inset(50%);white-space:nowrap;block-size:1px;inline-size:1px;position:absolute;overflow:hidden}}