@ai-matrx/design-system 0.36.0 → 0.38.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 (47) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/content-transfer.cjs +81 -17
  3. package/dist/content-transfer.cjs.map +1 -1
  4. package/dist/content-transfer.js +81 -17
  5. package/dist/content-transfer.js.map +1 -1
  6. package/dist/data-table/copy-helpers.d.cts +1 -1
  7. package/dist/data-table/copy-helpers.d.ts +1 -1
  8. package/dist/data-table/data-row-inspector.cjs +81 -17
  9. package/dist/data-table/data-row-inspector.cjs.map +1 -1
  10. package/dist/data-table/data-row-inspector.js +83 -19
  11. package/dist/data-table/data-row-inspector.js.map +1 -1
  12. package/dist/data-table/data-row-window.cjs +81 -17
  13. package/dist/data-table/data-row-window.cjs.map +1 -1
  14. package/dist/data-table/data-row-window.js +83 -19
  15. package/dist/data-table/data-row-window.js.map +1 -1
  16. package/dist/data-table/filter-engine.d.cts +1 -1
  17. package/dist/data-table/filter-engine.d.ts +1 -1
  18. package/dist/data-table/host.d.cts +1 -1
  19. package/dist/data-table/host.d.ts +1 -1
  20. package/dist/data-table/index.cjs +127 -25
  21. package/dist/data-table/index.cjs.map +1 -1
  22. package/dist/data-table/index.d.cts +2 -2
  23. package/dist/data-table/index.d.ts +2 -2
  24. package/dist/data-table/index.js +223 -121
  25. package/dist/data-table/index.js.map +1 -1
  26. package/dist/data-table/infer-filter.d.cts +1 -1
  27. package/dist/data-table/infer-filter.d.ts +1 -1
  28. package/dist/data-table/layered-filters.d.cts +1 -1
  29. package/dist/data-table/layered-filters.d.ts +1 -1
  30. package/dist/data-table/query-control.d.cts +1 -1
  31. package/dist/data-table/query-control.d.ts +1 -1
  32. package/dist/data-table/types.cjs.map +1 -1
  33. package/dist/data-table/types.d.cts +1 -1
  34. package/dist/data-table/types.d.ts +1 -1
  35. package/dist/data-table/url-state.d.cts +1 -1
  36. package/dist/data-table/url-state.d.ts +1 -1
  37. package/dist/data-table/xlsx.d.cts +1 -1
  38. package/dist/data-table/xlsx.d.ts +1 -1
  39. package/dist/index.cjs +81 -17
  40. package/dist/index.cjs.map +1 -1
  41. package/dist/index.d.cts +21 -0
  42. package/dist/index.d.ts +21 -0
  43. package/dist/index.js +91 -27
  44. package/dist/index.js.map +1 -1
  45. package/dist/{types-Cxm5XK0L.d.ts → types-B8vwElPz.d.ts} +25 -1
  46. package/dist/{types-kiV-CAuZ.d.cts → types-BuMHbFjs.d.cts} +25 -1
  47. package/package.json +7 -7
@@ -227,7 +227,8 @@ var Dialog = ({
227
227
  children,
228
228
  ...props
229
229
  }) => {
230
- const modal = props.modal ?? true;
230
+ const isMobile = useIsMobile();
231
+ const modal = props.modal ?? isMobile;
231
232
  return /* @__PURE__ */ jsx5(RadixDialogModalProvider, { modal, children: /* @__PURE__ */ jsx5(DialogPrimitive.Root, { ...props, modal, children }) });
232
233
  };
233
234
  Dialog.displayName = "Dialog";
@@ -273,6 +274,11 @@ DialogContentPrimitive.displayName = "DialogContentPrimitive";
273
274
  var DIALOG_DESKTOP_CLASSES = "matrx-dialog-card fixed inset-0 z-[10000] m-auto grid h-fit min-w-0 w-full max-w-lg gap-4 max-h-[85dvh] overflow-y-auto overscroll-contain [--dialog-pad:1.5rem] overflow-x-clip border bg-background p-6 shadow-lg [overflow-wrap:anywhere] [&>*]:min-w-0 [&>*]:max-w-full sm:rounded-lg";
274
275
  var DIALOG_MOBILE_SHEET_CLASSES = "matrx-mobile-sheet matrx-dialog-card fixed inset-x-0 bottom-0 left-0 right-0 top-auto z-[10000] flex min-w-0 flex-col w-full max-w-full max-h-[90dvh] gap-4 [--dialog-pad:1rem] overflow-x-clip border-t bg-background p-4 pb-safe shadow-lg [overflow-wrap:anywhere] [&>*]:min-w-0 [&>*]:max-w-full rounded-t-2xl rounded-b-none overflow-y-auto overscroll-contain";
275
276
  var DIALOG_MOBILE_SHEET_OVERRIDE = "inset-x-0 bottom-0 left-0 right-0 top-auto translate-none w-full max-w-full max-h-[90dvh] rounded-b-none rounded-t-2xl overflow-y-auto";
277
+ var DialogWindowHandleContext = React5.createContext(null);
278
+ var WINDOW_KEEP_VISIBLE = 80;
279
+ function isInteractiveTarget(target) {
280
+ return target instanceof Element && Boolean(target.closest("button, a, input, textarea, select, [role='button'], [contenteditable='true']"));
281
+ }
276
282
  var DialogContent = React5.forwardRef(
277
283
  ({
278
284
  className,
@@ -281,15 +287,50 @@ var DialogContent = React5.forwardRef(
281
287
  animated = true,
282
288
  showCloseButton = true,
283
289
  container,
290
+ dismissOnOutsideClick = false,
291
+ onInteractOutside,
292
+ onEscapeKeyDown,
293
+ style,
284
294
  ...props
285
295
  }, ref) => {
286
296
  const isMobile = useIsMobile();
287
297
  const isModal = useRadixDialogModal();
288
298
  const injectedContainer = usePortalContainer(container);
289
299
  const asSheet = mobileSheet && isMobile;
300
+ const windowed = !isModal && !asSheet;
290
301
  const [containerEl, setContainerEl] = React5.useState(
291
302
  null
292
303
  );
304
+ const [offset, setOffset] = React5.useState({ x: 0, y: 0 });
305
+ const dragRef = React5.useRef(null);
306
+ const handle = React5.useMemo(() => {
307
+ if (!windowed) return null;
308
+ const clamp = (value, limit) => Math.max(-limit, Math.min(limit, value));
309
+ return {
310
+ onPointerDown: (event) => {
311
+ if (event.button !== 0 || isInteractiveTarget(event.target)) return;
312
+ dragRef.current = { x: event.clientX, y: event.clientY, baseX: offset.x, baseY: offset.y };
313
+ event.currentTarget.setPointerCapture?.(event.pointerId);
314
+ },
315
+ onPointerMove: (event) => {
316
+ const start = dragRef.current;
317
+ if (!start) return;
318
+ setOffset({
319
+ x: clamp(start.baseX + event.clientX - start.x, window.innerWidth / 2 - WINDOW_KEEP_VISIBLE / 2),
320
+ y: clamp(start.baseY + event.clientY - start.y, window.innerHeight / 2 - WINDOW_KEEP_VISIBLE / 2)
321
+ });
322
+ },
323
+ onPointerUp: (event) => {
324
+ if (!dragRef.current) return;
325
+ dragRef.current = null;
326
+ event.currentTarget.releasePointerCapture?.(event.pointerId);
327
+ },
328
+ onPointerCancel: () => {
329
+ dragRef.current = null;
330
+ },
331
+ onDoubleClick: () => setOffset({ x: 0, y: 0 })
332
+ };
333
+ }, [windowed, offset.x, offset.y]);
293
334
  const mergedRef = React5.useCallback(
294
335
  (node) => {
295
336
  setContainerEl(node);
@@ -317,19 +358,33 @@ var DialogContent = React5.forwardRef(
317
358
  // can sit beside a host's floating window manager (which starts at
318
359
  // z=1000); staying below that boundary makes a newly focused window
319
360
  // usable without coupling the two systems.
320
- !isModal && "z-[900]"
361
+ !isModal && "z-[900]",
362
+ // Without an overlay the card needs its own separation from the page.
363
+ windowed && "shadow-2xl ring-1 ring-border/60"
321
364
  ),
365
+ style: windowed && (offset.x !== 0 || offset.y !== 0) ? { ...style, translate: `${offset.x}px ${offset.y}px` } : style,
366
+ onInteractOutside: (event) => {
367
+ onInteractOutside?.(event);
368
+ if (windowed && !dismissOnOutsideClick) event.preventDefault();
369
+ },
370
+ onEscapeKeyDown: (event) => {
371
+ onEscapeKeyDown?.(event);
372
+ const pressedIn = event.target instanceof Node && event.target !== document.body ? event.target : document.activeElement;
373
+ if (windowed && containerEl && !(pressedIn && containerEl.contains(pressedIn))) {
374
+ event.preventDefault();
375
+ }
376
+ },
322
377
  ...hasDescription ? {} : { "aria-describedby": void 0 },
323
378
  ...props,
324
379
  children: [
325
380
  hasTitle ? null : /* @__PURE__ */ jsx5(VisuallyHidden.Root, { children: /* @__PURE__ */ jsx5(DialogPrimitive.Title, { children: "Dialog" }) }),
326
- /* @__PURE__ */ jsx5(DialogContainerContext.Provider, { value: containerEl, children: /* @__PURE__ */ jsx5(
381
+ /* @__PURE__ */ jsx5(DialogContainerContext.Provider, { value: containerEl, children: /* @__PURE__ */ jsx5(DialogWindowHandleContext.Provider, { value: handle, children: /* @__PURE__ */ jsx5(
327
382
  PortalContainerProvider,
328
383
  {
329
384
  container: containerEl ?? injectedContainer ?? null,
330
385
  children
331
386
  }
332
- ) }),
387
+ ) }) }),
333
388
  showCloseButton ? /* @__PURE__ */ jsxs2(
334
389
  DialogPrimitive.Close,
335
390
  {
@@ -352,19 +407,28 @@ DialogContent.displayName = DialogPrimitive.Content.displayName;
352
407
  var DialogHeader = ({
353
408
  className,
354
409
  ...props
355
- }) => /* @__PURE__ */ jsx5(
356
- "div",
357
- {
358
- "data-slot": "dialog-header",
359
- className: cn(
360
- // DialogContent owns an absolute close control. Reserve its hit area in
361
- // every header so trailing actions never render underneath it.
362
- "flex flex-col space-y-1.5 pr-12 text-center sm:text-left",
363
- className
364
- ),
365
- ...props
366
- }
367
- );
410
+ }) => {
411
+ const handle = React5.useContext(DialogWindowHandleContext);
412
+ return /* @__PURE__ */ jsx5(
413
+ "div",
414
+ {
415
+ "data-slot": "dialog-header",
416
+ ...handle ? {
417
+ ...handle,
418
+ "data-window-handle": "",
419
+ title: "Drag to move \xB7 double-click to recenter"
420
+ } : {},
421
+ className: cn(
422
+ // DialogContent owns an absolute close control. Reserve its hit area in
423
+ // every header so trailing actions never render underneath it.
424
+ "flex flex-col space-y-1.5 pr-12 text-center sm:text-left",
425
+ handle && "cursor-grab select-none active:cursor-grabbing",
426
+ className
427
+ ),
428
+ ...props
429
+ }
430
+ );
431
+ };
368
432
  DialogHeader.displayName = "DialogHeader";
369
433
  var DialogFooter = ({
370
434
  className,
@@ -2991,7 +3055,7 @@ function CopyButtons(props) {
2991
3055
  // src/data-table/MatrxUuidCell.tsx
2992
3056
  import {
2993
3057
  useEffect as useEffect4,
2994
- useRef as useRef4,
3058
+ useRef as useRef5,
2995
3059
  useState as useState7
2996
3060
  } from "react";
2997
3061
 
@@ -3079,7 +3143,7 @@ function MatrxUuidCell({
3079
3143
  const [copied, setCopied] = useState7(false);
3080
3144
  const [opening, setOpening] = useState7(false);
3081
3145
  const [peekOpen, setPeekOpen] = useState7(false);
3082
- const timer = useRef4(null);
3146
+ const timer = useRef5(null);
3083
3147
  useEffect4(
3084
3148
  () => () => {
3085
3149
  if (timer.current) clearTimeout(timer.current);