@ai-matrx/design-system 0.86.350 → 0.86.351

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 +5 -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 +90 -29
  19. package/dist/desktop.cjs.map +1 -1
  20. package/dist/desktop.css +19 -0
  21. package/dist/desktop.d.cts +1 -1
  22. package/dist/desktop.d.ts +1 -1
  23. package/dist/desktop.js +90 -29
  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.css CHANGED
@@ -1308,3 +1308,22 @@
1308
1308
  color: var(--mx-label);
1309
1309
  padding: 10px 10px 10px 12px;
1310
1310
  }
1311
+ /* Inside the card the title is one line cut with an ellipsis and the line at most two, so a long
1312
+ notice never runs past the card or under its ×. Plain CSS here (not utility classes) so every
1313
+ host's build draws it. */
1314
+ [data-slot="banner"][data-float] [data-slot="banner-title"] {
1315
+ display: block;
1316
+ overflow: hidden;
1317
+ text-overflow: ellipsis;
1318
+ white-space: nowrap;
1319
+ }
1320
+ [data-slot="banner"][data-float] [data-slot="banner-message"] {
1321
+ display: -webkit-box;
1322
+ -webkit-line-clamp: 2;
1323
+ -webkit-box-orient: vertical;
1324
+ overflow: hidden;
1325
+ overflow-wrap: anywhere;
1326
+ }
1327
+ [data-slot="banner"][data-float] [data-slot="banner-text"] {
1328
+ flex-basis: 0;
1329
+ }
@@ -2200,7 +2200,7 @@ interface BannerProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "title"
2200
2200
  * THE inline notice (one pattern, every screen): the tone's icon, a semantic tint, one fixed
2201
2201
  * minimum height, the title and one line, trailing actions, and × when it can be put away.
2202
2202
  */
2203
- declare function Banner({ tone, icon, title, message, actions, detail, onDismiss, count, className, ...props }: BannerProps): React.JSX.Element;
2203
+ declare function Banner({ tone, icon, title, message, actions, detail, onDismiss, count, className, ...props }: BannerProps): React.JSX.Element | null;
2204
2204
  interface ErrorBannerProps extends Omit<BannerProps, "tone" | "title" | "message" | "actions" | "detail" | "onDismiss"> {
2205
2205
  /** The failed action's error (e.g. `useDesktopAction().error`); nothing renders without one. */
2206
2206
  error: {
package/dist/desktop.d.ts CHANGED
@@ -2200,7 +2200,7 @@ interface BannerProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "title"
2200
2200
  * THE inline notice (one pattern, every screen): the tone's icon, a semantic tint, one fixed
2201
2201
  * minimum height, the title and one line, trailing actions, and × when it can be put away.
2202
2202
  */
2203
- declare function Banner({ tone, icon, title, message, actions, detail, onDismiss, count, className, ...props }: BannerProps): React.JSX.Element;
2203
+ declare function Banner({ tone, icon, title, message, actions, detail, onDismiss, count, className, ...props }: BannerProps): React.JSX.Element | null;
2204
2204
  interface ErrorBannerProps extends Omit<BannerProps, "tone" | "title" | "message" | "actions" | "detail" | "onDismiss"> {
2205
2205
  /** The failed action's error (e.g. `useDesktopAction().error`); nothing renders without one. */
2206
2206
  error: {
package/dist/desktop.js CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  matchesOrganizationQuery,
20
20
  orderOrganizationsForPicker,
21
21
  organizationColor
22
- } from "./chunk-BCGNEWZM.js";
22
+ } from "./chunk-FLWSEDUW.js";
23
23
  import {
24
24
  Collapsible,
25
25
  CollapsibleContent,
@@ -41,7 +41,7 @@ import {
41
41
  import "./chunk-VQQ3O7J5.js";
42
42
  import {
43
43
  Tile
44
- } from "./chunk-UTADJKVR.js";
44
+ } from "./chunk-GMNROZQJ.js";
45
45
  import "./chunk-HKLIRHT2.js";
46
46
  import {
47
47
  Skeleton
@@ -1120,30 +1120,78 @@ var WIDTH = {
1120
1120
  wide: "max-w-none",
1121
1121
  full: "max-w-none"
1122
1122
  };
1123
- function noticeElements(children) {
1124
- const out = [];
1125
- for (const c of React8.Children.toArray(children)) {
1126
- if (!React8.isValidElement(c)) continue;
1127
- if (c.type === React8.Fragment) out.push(...noticeElements(c.props.children));
1128
- else out.push(c);
1129
- }
1130
- return out;
1123
+ var EMPTY_LAYOUT = { drawn: /* @__PURE__ */ new Map(), folded: 0, total: 0 };
1124
+ function createNoticeRegistry() {
1125
+ let entries = [];
1126
+ let expanded = false;
1127
+ let layout = EMPTY_LAYOUT;
1128
+ const listeners = /* @__PURE__ */ new Set();
1129
+ const recompute = () => {
1130
+ const groups = collapseNotices(entries, (e) => e.key);
1131
+ const { shown, folded } = expanded ? { shown: groups, folded: 0 } : visibleNotices(groups);
1132
+ const drawn = /* @__PURE__ */ new Map();
1133
+ for (const g of shown) {
1134
+ const dismissers = g.members.map((m) => m.dismiss).filter((d) => typeof d === "function");
1135
+ drawn.set(g.item.id, { count: g.count, dismissAll: g.item.dismiss ? () => dismissers.forEach((d) => d()) : void 0 });
1136
+ }
1137
+ layout = { drawn, folded, total: entries.length };
1138
+ listeners.forEach((l) => l());
1139
+ };
1140
+ return {
1141
+ set(id, key2, dismiss) {
1142
+ const at = entries.findIndex((e) => e.id === id);
1143
+ if (at >= 0) {
1144
+ const old = entries[at];
1145
+ if (old.key === key2 && old.dismiss === dismiss) return;
1146
+ entries = entries.map((e, i) => i === at ? { id, key: key2, dismiss } : e);
1147
+ } else {
1148
+ entries = [...entries, { id, key: key2, dismiss }];
1149
+ }
1150
+ recompute();
1151
+ },
1152
+ remove(id) {
1153
+ if (!entries.some((e) => e.id === id)) return;
1154
+ entries = entries.filter((e) => e.id !== id);
1155
+ if (entries.length === 0) expanded = false;
1156
+ recompute();
1157
+ },
1158
+ subscribe(listener) {
1159
+ listeners.add(listener);
1160
+ return () => listeners.delete(listener);
1161
+ },
1162
+ snapshot: () => layout,
1163
+ expand() {
1164
+ expanded = true;
1165
+ recompute();
1166
+ }
1167
+ };
1168
+ }
1169
+ var NoticeStackContext = React8.createContext(null);
1170
+ function useNoticeStackLayout(registry) {
1171
+ return React8.useSyncExternalStore(
1172
+ React8.useCallback((l) => registry ? registry.subscribe(l) : () => void 0, [registry]),
1173
+ () => registry ? registry.snapshot() : EMPTY_LAYOUT,
1174
+ () => registry ? registry.snapshot() : EMPTY_LAYOUT
1175
+ );
1131
1176
  }
1132
- function elementKey(el) {
1133
- const p = el.props;
1134
- if (typeof p.tone !== "string" || typeof p.title !== "string" && typeof p.title !== "number") return null;
1135
- return noticeKey(p.tone, p.title, p.message);
1177
+ function bannerNoticeKey(tone, title, message) {
1178
+ if (typeof title !== "string" && typeof title !== "number") return null;
1179
+ return noticeKey(tone, title, message);
1180
+ }
1181
+ function holdsElements(children) {
1182
+ return React8.Children.toArray(children).some(
1183
+ (c) => React8.isValidElement(c) && c.type === React8.Fragment ? holdsElements(c.props.children) : React8.isValidElement(c)
1184
+ );
1136
1185
  }
1137
- var NoticeStackContext = React8.createContext(false);
1138
1186
  function Notices({ children, className, onHeight, ...props }) {
1139
1187
  const stack = React8.useRef(null);
1140
- const [expanded, setExpanded] = React8.useState(false);
1141
- const elements = noticeElements(children);
1142
- const drawn = elements.length > 0;
1188
+ const [registry] = React8.useState(createNoticeRegistry);
1189
+ const layout = useNoticeStackLayout(registry);
1190
+ const drawn = layout.total > 0;
1143
1191
  React8.useLayoutEffect(() => {
1144
1192
  const el = stack.current;
1145
1193
  if (!onHeight) return;
1146
- if (!el) return onHeight(0);
1194
+ if (!el || !drawn) return onHeight(0);
1147
1195
  const report = () => onHeight(el.offsetHeight);
1148
1196
  report();
1149
1197
  if (typeof ResizeObserver === "undefined") return;
@@ -1154,9 +1202,7 @@ function Notices({ children, className, onHeight, ...props }) {
1154
1202
  onHeight(0);
1155
1203
  };
1156
1204
  }, [onHeight, drawn]);
1157
- if (!drawn) return null;
1158
- const groups = collapseNotices(elements, elementKey);
1159
- const { shown, folded } = expanded ? { shown: groups, folded: 0 } : visibleNotices(groups);
1205
+ if (!holdsElements(children)) return null;
1160
1206
  return /* @__PURE__ */ jsx11(
1161
1207
  "div",
1162
1208
  {
@@ -1164,15 +1210,16 @@ function Notices({ children, className, onHeight, ...props }) {
1164
1210
  "data-slot": "notices",
1165
1211
  "data-float": "",
1166
1212
  "aria-live": "polite",
1213
+ hidden: !drawn || void 0,
1167
1214
  style: { width: `${NOTICE_STACK.widthRem}rem` },
1168
1215
  className: cn2("flex flex-col items-stretch gap-2 empty:hidden", className),
1169
1216
  ...props,
1170
- children: /* @__PURE__ */ jsxs7(NoticeStackContext.Provider, { value: true, children: [
1171
- folded > 0 ? /* @__PURE__ */ jsx11("button", { type: "button", "data-slot": "notices-more", className: "self-end rounded-full px-2 py-0.5", onClick: () => setExpanded(true), children: /* @__PURE__ */ jsxs7(Text, { variant: "caption", tone: "secondary", children: [
1172
- folded,
1217
+ children: /* @__PURE__ */ jsxs7(NoticeStackContext.Provider, { value: registry, children: [
1218
+ layout.folded > 0 ? /* @__PURE__ */ jsx11("button", { type: "button", "data-slot": "notices-more", className: "order-first self-end rounded-full px-2 py-0.5", onClick: () => registry.expand(), children: /* @__PURE__ */ jsxs7(Text, { variant: "caption", tone: "secondary", children: [
1219
+ layout.folded,
1173
1220
  " more"
1174
1221
  ] }) }) : null,
1175
- shown.map((g) => g.count > 1 ? React8.cloneElement(g.item, { count: g.count }) : g.item)
1222
+ children
1176
1223
  ] })
1177
1224
  }
1178
1225
  );
@@ -3127,7 +3174,21 @@ var BANNER_ICON = {
3127
3174
  };
3128
3175
  function Banner({ tone, icon, title, message, actions, detail, onDismiss, count, className, ...props }) {
3129
3176
  const [copied, setCopied] = React20.useState(false);
3130
- const floating = React20.useContext(NoticeStackContext);
3177
+ const registry = React20.useContext(NoticeStackContext);
3178
+ const floating = registry !== null;
3179
+ const id = React20.useId();
3180
+ const key2 = bannerNoticeKey(tone, title, message);
3181
+ React20.useLayoutEffect(() => {
3182
+ registry?.set(id, key2, onDismiss);
3183
+ }, [registry, id, key2, onDismiss]);
3184
+ React20.useLayoutEffect(() => registry ? () => registry.remove(id) : void 0, [registry, id]);
3185
+ const layout = useNoticeStackLayout(registry);
3186
+ const slot = layout.drawn.get(id);
3187
+ if (floating && !slot) return null;
3188
+ if (slot) {
3189
+ count = Math.max(count ?? 1, slot.count);
3190
+ if (slot.dismissAll) onDismiss = slot.dismissAll;
3191
+ }
3131
3192
  return /* @__PURE__ */ jsxs22(
3132
3193
  "div",
3133
3194
  {
@@ -3142,14 +3203,14 @@ function Banner({ tone, icon, title, message, actions, detail, onDismiss, count,
3142
3203
  /* @__PURE__ */ jsx28("span", { className: cn2("flex shrink-0 self-start pt-px [&_svg]:size-icon", BANNER_TONE[tone].icon), children: icon ?? BANNER_ICON[tone] }),
3143
3204
  /* @__PURE__ */ jsxs22("div", { "data-slot": "banner-body", className: "flex min-w-0 flex-1 flex-wrap items-center gap-x-3 gap-y-2", children: [
3144
3205
  /* @__PURE__ */ jsxs22("div", { "data-slot": "banner-text", className: "flex min-w-0 flex-1 basis-56 flex-col gap-0.5", title: detail || void 0, children: [
3145
- /* @__PURE__ */ jsxs22(Text, { emphasized: true, className: floating ? "line-clamp-1" : void 0, children: [
3206
+ /* @__PURE__ */ jsxs22(Text, { "data-slot": "banner-title", emphasized: true, ...floating && typeof title === "string" ? { title } : {}, children: [
3146
3207
  title,
3147
3208
  count && count > 1 ? /* @__PURE__ */ jsxs22("span", { "data-slot": "banner-count", className: "ml-1.5 font-normal text-label-secondary", children: [
3148
3209
  "\xD7",
3149
3210
  count
3150
3211
  ] }) : null
3151
3212
  ] }),
3152
- message ? /* @__PURE__ */ jsx28(Text, { as: "p", tone: "secondary", selectable: true, className: floating ? "line-clamp-2" : void 0, children: message }) : null
3213
+ message ? /* @__PURE__ */ jsx28(Text, { "data-slot": "banner-message", as: "p", tone: "secondary", selectable: true, children: message }) : null
3153
3214
  ] }),
3154
3215
  actions || detail ? /* @__PURE__ */ jsxs22("div", { "data-slot": "banner-actions", className: "ml-auto flex shrink-0 items-center gap-2", children: [
3155
3216
  detail ? /* @__PURE__ */ jsx28(