@ai-matrx/design-system 0.86.350 → 0.86.352

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 (39) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/carousel.js +2 -2
  3. package/dist/{chunk-BCGNEWZM.js → chunk-FLWSEDUW.js} +2 -2
  4. package/dist/{chunk-UTADJKVR.js → chunk-GMNROZQJ.js} +3 -3
  5. package/dist/{chunk-UTADJKVR.js.map → chunk-GMNROZQJ.js.map} +1 -1
  6. package/dist/{chunk-SC3XPADZ.js → chunk-UGQRAQTE.js} +431 -342
  7. package/dist/chunk-UGQRAQTE.js.map +1 -0
  8. package/dist/controls.cjs +547 -458
  9. package/dist/controls.cjs.map +1 -1
  10. package/dist/controls.css +27 -18
  11. package/dist/controls.d.cts +51 -3
  12. package/dist/controls.d.ts +51 -3
  13. package/dist/controls.js +10 -2
  14. package/dist/data-table/index.cjs +45 -38
  15. package/dist/data-table/index.cjs.map +1 -1
  16. package/dist/data-table/index.js +44 -37
  17. package/dist/data-table/index.js.map +1 -1
  18. package/dist/desktop.cjs +98 -34
  19. package/dist/desktop.cjs.map +1 -1
  20. package/dist/desktop.css +29 -0
  21. package/dist/desktop.d.cts +17 -5
  22. package/dist/desktop.d.ts +17 -5
  23. package/dist/desktop.js +98 -34
  24. package/dist/desktop.js.map +1 -1
  25. package/dist/index.cjs +3 -3
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.cts +3 -3
  28. package/dist/index.d.ts +3 -3
  29. package/dist/index.js +4 -4
  30. package/dist/index.js.map +1 -1
  31. package/dist/settings.cjs +2 -2
  32. package/dist/settings.cjs.map +1 -1
  33. package/dist/settings.js +1 -1
  34. package/dist/writing-field.cjs +2 -2
  35. package/dist/writing-field.cjs.map +1 -1
  36. package/dist/writing-field.js +1 -1
  37. package/package.json +2 -2
  38. package/dist/chunk-SC3XPADZ.js.map +0 -1
  39. /package/dist/{chunk-BCGNEWZM.js.map → chunk-FLWSEDUW.js.map} +0 -0
package/dist/desktop.cjs CHANGED
@@ -2393,7 +2393,7 @@ var DialogContent2 = React14.forwardRef(function DialogContent3({ className, sho
2393
2393
  function DialogHeader2({ className, ...props }) {
2394
2394
  return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DialogHeader, { className: cn("gap-1 space-y-0 pr-0 text-left sm:text-left", className), ...props });
2395
2395
  }
2396
- function DialogBody({ className, children, ...props }) {
2396
+ function DialogBody({ className, children, minHeight, ...props }) {
2397
2397
  const ref = React14.useRef(null);
2398
2398
  const [overflowing, setOverflowing] = React14.useState(false);
2399
2399
  React14.useLayoutEffect(() => {
@@ -2407,7 +2407,7 @@ function DialogBody({ className, children, ...props }) {
2407
2407
  for (const child of Array.from(el.children)) observer.observe(child);
2408
2408
  return () => observer.disconnect();
2409
2409
  }, [children]);
2410
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { ref, "data-slot": "sheet-body", "data-overflowing": overflowing ? "" : void 0, className: cn("flex min-h-0 flex-col gap-4", className), ...props, children });
2410
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { ref, "data-slot": "sheet-body", "data-min-height": minHeight, "data-overflowing": overflowing ? "" : void 0, className: cn("flex min-h-0 flex-col gap-4", className), ...props, children });
2411
2411
  }
2412
2412
  function DialogFooter2({ className, ...props }) {
2413
2413
  return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DialogFooter, { className: cn("flex-row justify-end gap-2 space-x-0 bg-content pt-1 sm:gap-2 sm:space-x-0", className), ...props });
@@ -2930,30 +2930,79 @@ var WIDTH = {
2930
2930
  wide: "max-w-none",
2931
2931
  full: "max-w-none"
2932
2932
  };
2933
- function noticeElements(children) {
2934
- const out = [];
2935
- for (const c of React16.Children.toArray(children)) {
2936
- if (!React16.isValidElement(c)) continue;
2937
- if (c.type === React16.Fragment) out.push(...noticeElements(c.props.children));
2938
- else out.push(c);
2939
- }
2940
- return out;
2933
+ var EMPTY_LAYOUT = { drawn: /* @__PURE__ */ new Map(), folded: 0, total: 0 };
2934
+ function createNoticeRegistry() {
2935
+ let entries = [];
2936
+ let expanded = false;
2937
+ let layout = EMPTY_LAYOUT;
2938
+ const listeners = /* @__PURE__ */ new Set();
2939
+ const recompute = () => {
2940
+ const groups = collapseNotices(entries, (e) => e.key);
2941
+ const { shown, folded } = expanded ? { shown: groups, folded: 0 } : visibleNotices(groups);
2942
+ const drawn = /* @__PURE__ */ new Map();
2943
+ for (const g of shown) {
2944
+ const dismissers = g.members.map((m) => m.dismiss).filter((d) => typeof d === "function");
2945
+ drawn.set(g.item.id, { count: g.count, dismissAll: g.item.dismiss ? () => dismissers.forEach((d) => d()) : void 0 });
2946
+ }
2947
+ layout = { drawn, folded, total: entries.length };
2948
+ listeners.forEach((l) => l());
2949
+ };
2950
+ return {
2951
+ set(id, key2, dismiss) {
2952
+ const at = entries.findIndex((e) => e.id === id);
2953
+ if (at >= 0) {
2954
+ const old = entries[at];
2955
+ if (old.key === key2 && old.dismiss === dismiss) return;
2956
+ entries = entries.map((e, i) => i === at ? { id, key: key2, dismiss } : e);
2957
+ } else {
2958
+ entries = [...entries, { id, key: key2, dismiss }];
2959
+ }
2960
+ recompute();
2961
+ },
2962
+ remove(id) {
2963
+ if (!entries.some((e) => e.id === id)) return;
2964
+ entries = entries.filter((e) => e.id !== id);
2965
+ if (entries.length === 0) expanded = false;
2966
+ recompute();
2967
+ },
2968
+ subscribe(listener) {
2969
+ listeners.add(listener);
2970
+ return () => listeners.delete(listener);
2971
+ },
2972
+ snapshot: () => layout,
2973
+ expand() {
2974
+ expanded = true;
2975
+ recompute();
2976
+ }
2977
+ };
2978
+ }
2979
+ var NoticeStackContext = React16.createContext(null);
2980
+ function useNoticeStackLayout(registry3) {
2981
+ return React16.useSyncExternalStore(
2982
+ React16.useCallback((l) => registry3 ? registry3.subscribe(l) : () => void 0, [registry3]),
2983
+ () => registry3 ? registry3.snapshot() : EMPTY_LAYOUT,
2984
+ () => registry3 ? registry3.snapshot() : EMPTY_LAYOUT
2985
+ );
2941
2986
  }
2942
- function elementKey(el) {
2943
- const p = el.props;
2944
- if (typeof p.tone !== "string" || typeof p.title !== "string" && typeof p.title !== "number") return null;
2945
- return noticeKey(p.tone, p.title, p.message);
2987
+ function bannerNoticeKey(tone, title, message) {
2988
+ if (typeof title !== "string" && typeof title !== "number") return null;
2989
+ return noticeKey(tone, title, message);
2990
+ }
2991
+ function holdsElements(children) {
2992
+ return React16.Children.toArray(children).some(
2993
+ (c) => React16.isValidElement(c) && c.type === React16.Fragment ? holdsElements(c.props.children) : React16.isValidElement(c)
2994
+ );
2946
2995
  }
2947
- var NoticeStackContext = React16.createContext(false);
2948
2996
  function Notices({ children, className, onHeight, ...props }) {
2949
2997
  const stack = React16.useRef(null);
2950
- const [expanded, setExpanded] = React16.useState(false);
2951
- const elements = noticeElements(children);
2952
- const drawn = elements.length > 0;
2998
+ const parent = React16.useContext(NoticeStackContext);
2999
+ const [registry3] = React16.useState(createNoticeRegistry);
3000
+ const layout = useNoticeStackLayout(registry3);
3001
+ const drawn = layout.total > 0;
2953
3002
  React16.useLayoutEffect(() => {
2954
3003
  const el = stack.current;
2955
3004
  if (!onHeight) return;
2956
- if (!el) return onHeight(0);
3005
+ if (!el || !drawn) return onHeight(0);
2957
3006
  const report = () => onHeight(el.offsetHeight);
2958
3007
  report();
2959
3008
  if (typeof ResizeObserver === "undefined") return;
@@ -2964,9 +3013,8 @@ function Notices({ children, className, onHeight, ...props }) {
2964
3013
  onHeight(0);
2965
3014
  };
2966
3015
  }, [onHeight, drawn]);
2967
- if (!drawn) return null;
2968
- const groups = collapseNotices(elements, elementKey);
2969
- const { shown, folded } = expanded ? { shown: groups, folded: 0 } : visibleNotices(groups);
3016
+ if (parent) return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_jsx_runtime20.Fragment, { children });
3017
+ if (!holdsElements(children)) return null;
2970
3018
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2971
3019
  "div",
2972
3020
  {
@@ -2974,15 +3022,16 @@ function Notices({ children, className, onHeight, ...props }) {
2974
3022
  "data-slot": "notices",
2975
3023
  "data-float": "",
2976
3024
  "aria-live": "polite",
3025
+ hidden: !drawn || void 0,
2977
3026
  style: { width: `${NOTICE_STACK.widthRem}rem` },
2978
3027
  className: cn("flex flex-col items-stretch gap-2 empty:hidden", className),
2979
3028
  ...props,
2980
- children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(NoticeStackContext.Provider, { value: true, children: [
2981
- folded > 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", "data-slot": "notices-more", className: "self-end rounded-full px-2 py-0.5", onClick: () => setExpanded(true), children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Text, { variant: "caption", tone: "secondary", children: [
2982
- folded,
3029
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(NoticeStackContext.Provider, { value: registry3, children: [
3030
+ layout.folded > 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "button", "data-slot": "notices-more", className: "order-first self-end rounded-full px-2 py-0.5", onClick: () => registry3.expand(), children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Text, { variant: "caption", tone: "secondary", children: [
3031
+ layout.folded,
2983
3032
  " more"
2984
3033
  ] }) }) : null,
2985
- shown.map((g) => g.count > 1 ? React16.cloneElement(g.item, { count: g.count }) : g.item)
3034
+ children
2986
3035
  ] })
2987
3036
  }
2988
3037
  );
@@ -5487,7 +5536,21 @@ var BANNER_ICON = {
5487
5536
  };
5488
5537
  function Banner({ tone, icon, title, message, actions, detail, onDismiss, count, className, ...props }) {
5489
5538
  const [copied, setCopied] = React34.useState(false);
5490
- const floating = React34.useContext(NoticeStackContext);
5539
+ const registry3 = React34.useContext(NoticeStackContext);
5540
+ const floating = registry3 !== null;
5541
+ const id = React34.useId();
5542
+ const key2 = bannerNoticeKey(tone, title, message);
5543
+ React34.useLayoutEffect(() => {
5544
+ registry3?.set(id, key2, onDismiss);
5545
+ }, [registry3, id, key2, onDismiss]);
5546
+ React34.useLayoutEffect(() => registry3 ? () => registry3.remove(id) : void 0, [registry3, id]);
5547
+ const layout = useNoticeStackLayout(registry3);
5548
+ const slot = layout.drawn.get(id);
5549
+ if (floating && !slot) return null;
5550
+ if (slot) {
5551
+ count = Math.max(count ?? 1, slot.count);
5552
+ if (slot.dismissAll) onDismiss = slot.dismissAll;
5553
+ }
5491
5554
  return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
5492
5555
  "div",
5493
5556
  {
@@ -5502,14 +5565,14 @@ function Banner({ tone, icon, title, message, actions, detail, onDismiss, count,
5502
5565
  /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: cn("flex shrink-0 self-start pt-px [&_svg]:size-icon", BANNER_TONE[tone].icon), children: icon ?? BANNER_ICON[tone] }),
5503
5566
  /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { "data-slot": "banner-body", className: "flex min-w-0 flex-1 flex-wrap items-center gap-x-3 gap-y-2", children: [
5504
5567
  /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { "data-slot": "banner-text", className: "flex min-w-0 flex-1 basis-56 flex-col gap-0.5", title: detail || void 0, children: [
5505
- /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(Text, { emphasized: true, className: floating ? "line-clamp-1" : void 0, children: [
5568
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(Text, { "data-slot": "banner-title", emphasized: true, ...floating && typeof title === "string" ? { title } : {}, children: [
5506
5569
  title,
5507
5570
  count && count > 1 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("span", { "data-slot": "banner-count", className: "ml-1.5 font-normal text-label-secondary", children: [
5508
5571
  "\xD7",
5509
5572
  count
5510
5573
  ] }) : null
5511
5574
  ] }),
5512
- message ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Text, { as: "p", tone: "secondary", selectable: true, className: floating ? "line-clamp-2" : void 0, children: message }) : null
5575
+ message ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Text, { "data-slot": "banner-message", as: "p", tone: "secondary", selectable: true, children: message }) : null
5513
5576
  ] }),
5514
5577
  actions || detail ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { "data-slot": "banner-actions", className: "ml-auto flex shrink-0 items-center gap-2", children: [
5515
5578
  detail ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
@@ -5669,13 +5732,13 @@ function TableFilterTokens({ columns, state, onChange }) {
5669
5732
  return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(RemovableTag, { "data-table-filter-token": column.key, className: "shrink-0", removeLabel: `Remove the ${name} filter`, onRemove: () => onChange(setValues(state, column.key, [])), children: `${name}: ${labels.join(", ")}` }, column.key);
5670
5733
  }) });
5671
5734
  }
5672
- function TableFilterBar({ columns, rows, state, onChange, shown, label }) {
5735
+ function TableFilterBar({ columns, rows, state, onChange, shown, label, noun }) {
5673
5736
  const searchable = columns.some((c) => c.search);
5674
5737
  const active = filterActive(state);
5675
5738
  return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { "data-slot": "data-table-filter-bar", className: "flex h-table-filter-bar shrink-0 items-center gap-2 border-b border-separator px-3", children: [
5676
5739
  /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-1.5 overflow-hidden", children: [
5677
5740
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(TableFilterTokens, { columns, state, onChange }),
5678
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Text, { tone: "secondary", className: "shrink-0 tabular-nums", "data-table-filter-count": shown, children: active ? `${shown} of ${rows.length}` : `${rows.length}` })
5741
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Text, { tone: "secondary", className: "shrink-0 tabular-nums", "data-table-filter-count": shown, children: `${active ? `${shown} of ${rows.length}` : `${rows.length}`}${noun ? ` ${rows.length === 1 ? noun[0] : noun[1]}` : ""}` })
5679
5742
  ] }),
5680
5743
  searchable ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
5681
5744
  SearchField,
@@ -5788,6 +5851,7 @@ function DataTable({
5788
5851
  onFilterStateChange,
5789
5852
  defaultFilter,
5790
5853
  filterBar = true,
5854
+ noun,
5791
5855
  className,
5792
5856
  "aria-label": ariaLabel,
5793
5857
  columns: allColumns,
@@ -5978,7 +6042,7 @@ function DataTable({
5978
6042
  }
5979
6043
  };
5980
6044
  const contextItems = menuRow !== null && rowContextMenu ? rowContextMenu(menuRow) ?? null : null;
5981
- const bar = filterable && filterBar && givenRows.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(TableFilterBar, { columns: allColumns, rows: givenRows, state: filter, onChange: setFilter, shown: rows.length, label: ariaLabel.toLowerCase() }) : null;
6045
+ const bar = filterable && filterBar && givenRows.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(TableFilterBar, { columns: allColumns, rows: givenRows, state: filter, onChange: setFilter, shown: rows.length, label: ariaLabel.toLowerCase(), noun }) : null;
5982
6046
  const framed = (body) => bar ? /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
5983
6047
  "div",
5984
6048
  {
@@ -8750,12 +8814,12 @@ function Skeleton({ className, animated = true, motion = "pulse", shape, height,
8750
8814
  // src/controls/surfaces.tsx
8751
8815
  var import_jsx_runtime68 = require("react/jsx-runtime");
8752
8816
  var Tile = React50.forwardRef(
8753
- ({ layout = "row", variant = "outline", icon, title, wrapTitle, line, end, selected, selectedStyle, tooltip, level, fit, endInset, oneLine, dashed, hoverStyle, danger, dimmed, glyphTone, hero, tone, dense, asChild = false, className, children, onClick, type, ...props }, ref) => {
8817
+ ({ layout = "row", variant = "outline", icon, title, wrapTitle, line, end, selected, selectedStyle, tooltip, level, fit, endInset, oneLine, dashed, hoverStyle, danger, dimmed, glyphTone, hero, tone, iconTone, dense, asChild = false, className, children, onClick, type, ...props }, ref) => {
8754
8818
  const Component = asChild ? import_react_slot5.Slot : "button";
8755
8819
  const ariaDisabled = props["aria-disabled"];
8756
8820
  const inert = ariaDisabled === true || ariaDisabled === "true";
8757
8821
  const body = /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_jsx_runtime68.Fragment, { children: [
8758
- icon ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "matrx-tile-icon", children: icon }) : null,
8822
+ icon ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "matrx-tile-icon", "data-tone": iconTone && iconTone !== "neutral" ? iconTone : void 0, children: icon }) : null,
8759
8823
  /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("span", { className: "matrx-tile-text", children: [
8760
8824
  /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "matrx-tile-title", children: title }),
8761
8825
  line ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "matrx-tile-line", children: line }) : null