@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.
- package/CHANGELOG.md +31 -0
- package/dist/content-transfer.cjs +81 -17
- package/dist/content-transfer.cjs.map +1 -1
- package/dist/content-transfer.js +81 -17
- package/dist/content-transfer.js.map +1 -1
- package/dist/data-table/copy-helpers.d.cts +1 -1
- package/dist/data-table/copy-helpers.d.ts +1 -1
- package/dist/data-table/data-row-inspector.cjs +81 -17
- package/dist/data-table/data-row-inspector.cjs.map +1 -1
- package/dist/data-table/data-row-inspector.js +83 -19
- package/dist/data-table/data-row-inspector.js.map +1 -1
- package/dist/data-table/data-row-window.cjs +81 -17
- package/dist/data-table/data-row-window.cjs.map +1 -1
- package/dist/data-table/data-row-window.js +83 -19
- package/dist/data-table/data-row-window.js.map +1 -1
- package/dist/data-table/filter-engine.d.cts +1 -1
- package/dist/data-table/filter-engine.d.ts +1 -1
- package/dist/data-table/host.d.cts +1 -1
- package/dist/data-table/host.d.ts +1 -1
- package/dist/data-table/index.cjs +127 -25
- package/dist/data-table/index.cjs.map +1 -1
- package/dist/data-table/index.d.cts +2 -2
- package/dist/data-table/index.d.ts +2 -2
- package/dist/data-table/index.js +223 -121
- package/dist/data-table/index.js.map +1 -1
- package/dist/data-table/infer-filter.d.cts +1 -1
- package/dist/data-table/infer-filter.d.ts +1 -1
- package/dist/data-table/layered-filters.d.cts +1 -1
- package/dist/data-table/layered-filters.d.ts +1 -1
- package/dist/data-table/query-control.d.cts +1 -1
- package/dist/data-table/query-control.d.ts +1 -1
- package/dist/data-table/types.cjs.map +1 -1
- package/dist/data-table/types.d.cts +1 -1
- package/dist/data-table/types.d.ts +1 -1
- package/dist/data-table/url-state.d.cts +1 -1
- package/dist/data-table/url-state.d.ts +1 -1
- package/dist/data-table/xlsx.d.cts +1 -1
- package/dist/data-table/xlsx.d.ts +1 -1
- package/dist/index.cjs +81 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +91 -27
- package/dist/index.js.map +1 -1
- package/dist/{types-Cxm5XK0L.d.ts → types-B8vwElPz.d.ts} +25 -1
- package/dist/{types-kiV-CAuZ.d.cts → types-BuMHbFjs.d.cts} +25 -1
- package/package.json +7 -7
package/dist/index.d.cts
CHANGED
|
@@ -792,6 +792,20 @@ declare function CreatablePicker({ value, options, onSelect, placeholder, search
|
|
|
792
792
|
* `aria-describedby` is dropped when there is no description rather than
|
|
793
793
|
* pointing at nothing.
|
|
794
794
|
*
|
|
795
|
+
* 6. ON DESKTOP A DIALOG IS A WINDOW, NOT A WALL (0.38.0, Arman 2026-09-23:
|
|
796
|
+
* "none of the built-in page ai integrations are accessible because the
|
|
797
|
+
* page is totally blocked"). Unless the caller passes `modal`, a desktop
|
|
798
|
+
* dialog does not block the page: no overlay, the page, the Agents menu,
|
|
799
|
+
* the assist dock and right-click AI stay usable beside it. It behaves like
|
|
800
|
+
* a window: a click outside never closes it (`dismissOnOutsideClick` opts a
|
|
801
|
+
* quick picker back in), Escape closes it only while focus is inside it
|
|
802
|
+
* (Escape in the page belongs to the page), and its `DialogHeader` drags
|
|
803
|
+
* it, clamped on screen, double-click to recenter. On a phone it stays the
|
|
804
|
+
* blocking bottom sheet — nothing useful sits behind a sheet. Confirmations
|
|
805
|
+
* are `AlertDialog`, a different component, and stay blocking. This is a
|
|
806
|
+
* LIGHT window: the host's heavy window manager (tray, persistence) is a
|
|
807
|
+
* separate system and must not be pulled into every dialog.
|
|
808
|
+
*
|
|
795
809
|
* SEAM INVERSIONS. The host original resolved its portal target through
|
|
796
810
|
* app-shaped hooks (a popped-out window-panel body). Here that is the
|
|
797
811
|
* package's `PortalContainerProvider` seam, with an explicit `container` prop
|
|
@@ -828,6 +842,13 @@ declare const DialogOverlay: React.ForwardRefExoticComponent<Omit<DialogPrimitiv
|
|
|
828
842
|
*/
|
|
829
843
|
declare const DialogContentPrimitive: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
830
844
|
interface DialogContentProps extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> {
|
|
845
|
+
/**
|
|
846
|
+
* Windowed (non-blocking) dialogs never close from a click outside them —
|
|
847
|
+
* the person is reaching for the page or an AI control beside the window.
|
|
848
|
+
* Pass `true` for a quick picker that should close when the person clicks
|
|
849
|
+
* away. Ignored on a blocking dialog, which keeps Radix's behaviour.
|
|
850
|
+
*/
|
|
851
|
+
dismissOnOutsideClick?: boolean;
|
|
831
852
|
/** Render as a bottom sheet below the mobile breakpoint. Default `true`. */
|
|
832
853
|
mobileSheet?: boolean;
|
|
833
854
|
/** Render the built-in close control. Default `true`. */
|
package/dist/index.d.ts
CHANGED
|
@@ -792,6 +792,20 @@ declare function CreatablePicker({ value, options, onSelect, placeholder, search
|
|
|
792
792
|
* `aria-describedby` is dropped when there is no description rather than
|
|
793
793
|
* pointing at nothing.
|
|
794
794
|
*
|
|
795
|
+
* 6. ON DESKTOP A DIALOG IS A WINDOW, NOT A WALL (0.38.0, Arman 2026-09-23:
|
|
796
|
+
* "none of the built-in page ai integrations are accessible because the
|
|
797
|
+
* page is totally blocked"). Unless the caller passes `modal`, a desktop
|
|
798
|
+
* dialog does not block the page: no overlay, the page, the Agents menu,
|
|
799
|
+
* the assist dock and right-click AI stay usable beside it. It behaves like
|
|
800
|
+
* a window: a click outside never closes it (`dismissOnOutsideClick` opts a
|
|
801
|
+
* quick picker back in), Escape closes it only while focus is inside it
|
|
802
|
+
* (Escape in the page belongs to the page), and its `DialogHeader` drags
|
|
803
|
+
* it, clamped on screen, double-click to recenter. On a phone it stays the
|
|
804
|
+
* blocking bottom sheet — nothing useful sits behind a sheet. Confirmations
|
|
805
|
+
* are `AlertDialog`, a different component, and stay blocking. This is a
|
|
806
|
+
* LIGHT window: the host's heavy window manager (tray, persistence) is a
|
|
807
|
+
* separate system and must not be pulled into every dialog.
|
|
808
|
+
*
|
|
795
809
|
* SEAM INVERSIONS. The host original resolved its portal target through
|
|
796
810
|
* app-shaped hooks (a popped-out window-panel body). Here that is the
|
|
797
811
|
* package's `PortalContainerProvider` seam, with an explicit `container` prop
|
|
@@ -828,6 +842,13 @@ declare const DialogOverlay: React.ForwardRefExoticComponent<Omit<DialogPrimitiv
|
|
|
828
842
|
*/
|
|
829
843
|
declare const DialogContentPrimitive: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
830
844
|
interface DialogContentProps extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> {
|
|
845
|
+
/**
|
|
846
|
+
* Windowed (non-blocking) dialogs never close from a click outside them —
|
|
847
|
+
* the person is reaching for the page or an AI control beside the window.
|
|
848
|
+
* Pass `true` for a quick picker that should close when the person clicks
|
|
849
|
+
* away. Ignored on a blocking dialog, which keeps Radix's behaviour.
|
|
850
|
+
*/
|
|
851
|
+
dismissOnOutsideClick?: boolean;
|
|
831
852
|
/** Render as a bottom sheet below the mobile breakpoint. Default `true`. */
|
|
832
853
|
mobileSheet?: boolean;
|
|
833
854
|
/** Render the built-in close control. Default `true`. */
|
package/dist/index.js
CHANGED
|
@@ -1877,7 +1877,8 @@ var Dialog = ({
|
|
|
1877
1877
|
children,
|
|
1878
1878
|
...props
|
|
1879
1879
|
}) => {
|
|
1880
|
-
const
|
|
1880
|
+
const isMobile = useIsMobile();
|
|
1881
|
+
const modal = props.modal ?? isMobile;
|
|
1881
1882
|
return /* @__PURE__ */ jsx21(RadixDialogModalProvider, { modal, children: /* @__PURE__ */ jsx21(DialogPrimitive2.Root, { ...props, modal, children }) });
|
|
1882
1883
|
};
|
|
1883
1884
|
Dialog.displayName = "Dialog";
|
|
@@ -1926,6 +1927,11 @@ DialogContentPrimitive.displayName = "DialogContentPrimitive";
|
|
|
1926
1927
|
var DIALOG_DESKTOP_CLASSES2 = "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";
|
|
1927
1928
|
var DIALOG_MOBILE_SHEET_CLASSES2 = "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";
|
|
1928
1929
|
var DIALOG_MOBILE_SHEET_OVERRIDE2 = "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";
|
|
1930
|
+
var DialogWindowHandleContext = React17.createContext(null);
|
|
1931
|
+
var WINDOW_KEEP_VISIBLE = 80;
|
|
1932
|
+
function isInteractiveTarget(target) {
|
|
1933
|
+
return target instanceof Element && Boolean(target.closest("button, a, input, textarea, select, [role='button'], [contenteditable='true']"));
|
|
1934
|
+
}
|
|
1929
1935
|
var DialogContent = React17.forwardRef(
|
|
1930
1936
|
({
|
|
1931
1937
|
className,
|
|
@@ -1934,15 +1940,50 @@ var DialogContent = React17.forwardRef(
|
|
|
1934
1940
|
animated = true,
|
|
1935
1941
|
showCloseButton = true,
|
|
1936
1942
|
container,
|
|
1943
|
+
dismissOnOutsideClick = false,
|
|
1944
|
+
onInteractOutside,
|
|
1945
|
+
onEscapeKeyDown,
|
|
1946
|
+
style,
|
|
1937
1947
|
...props
|
|
1938
1948
|
}, ref) => {
|
|
1939
1949
|
const isMobile = useIsMobile();
|
|
1940
1950
|
const isModal = useRadixDialogModal();
|
|
1941
1951
|
const injectedContainer = usePortalContainer(container);
|
|
1942
1952
|
const asSheet = mobileSheet && isMobile;
|
|
1953
|
+
const windowed = !isModal && !asSheet;
|
|
1943
1954
|
const [containerEl, setContainerEl] = React17.useState(
|
|
1944
1955
|
null
|
|
1945
1956
|
);
|
|
1957
|
+
const [offset, setOffset] = React17.useState({ x: 0, y: 0 });
|
|
1958
|
+
const dragRef = React17.useRef(null);
|
|
1959
|
+
const handle = React17.useMemo(() => {
|
|
1960
|
+
if (!windowed) return null;
|
|
1961
|
+
const clamp = (value, limit) => Math.max(-limit, Math.min(limit, value));
|
|
1962
|
+
return {
|
|
1963
|
+
onPointerDown: (event) => {
|
|
1964
|
+
if (event.button !== 0 || isInteractiveTarget(event.target)) return;
|
|
1965
|
+
dragRef.current = { x: event.clientX, y: event.clientY, baseX: offset.x, baseY: offset.y };
|
|
1966
|
+
event.currentTarget.setPointerCapture?.(event.pointerId);
|
|
1967
|
+
},
|
|
1968
|
+
onPointerMove: (event) => {
|
|
1969
|
+
const start = dragRef.current;
|
|
1970
|
+
if (!start) return;
|
|
1971
|
+
setOffset({
|
|
1972
|
+
x: clamp(start.baseX + event.clientX - start.x, window.innerWidth / 2 - WINDOW_KEEP_VISIBLE / 2),
|
|
1973
|
+
y: clamp(start.baseY + event.clientY - start.y, window.innerHeight / 2 - WINDOW_KEEP_VISIBLE / 2)
|
|
1974
|
+
});
|
|
1975
|
+
},
|
|
1976
|
+
onPointerUp: (event) => {
|
|
1977
|
+
if (!dragRef.current) return;
|
|
1978
|
+
dragRef.current = null;
|
|
1979
|
+
event.currentTarget.releasePointerCapture?.(event.pointerId);
|
|
1980
|
+
},
|
|
1981
|
+
onPointerCancel: () => {
|
|
1982
|
+
dragRef.current = null;
|
|
1983
|
+
},
|
|
1984
|
+
onDoubleClick: () => setOffset({ x: 0, y: 0 })
|
|
1985
|
+
};
|
|
1986
|
+
}, [windowed, offset.x, offset.y]);
|
|
1946
1987
|
const mergedRef = React17.useCallback(
|
|
1947
1988
|
(node) => {
|
|
1948
1989
|
setContainerEl(node);
|
|
@@ -1970,19 +2011,33 @@ var DialogContent = React17.forwardRef(
|
|
|
1970
2011
|
// can sit beside a host's floating window manager (which starts at
|
|
1971
2012
|
// z=1000); staying below that boundary makes a newly focused window
|
|
1972
2013
|
// usable without coupling the two systems.
|
|
1973
|
-
!isModal && "z-[900]"
|
|
2014
|
+
!isModal && "z-[900]",
|
|
2015
|
+
// Without an overlay the card needs its own separation from the page.
|
|
2016
|
+
windowed && "shadow-2xl ring-1 ring-border/60"
|
|
1974
2017
|
),
|
|
2018
|
+
style: windowed && (offset.x !== 0 || offset.y !== 0) ? { ...style, translate: `${offset.x}px ${offset.y}px` } : style,
|
|
2019
|
+
onInteractOutside: (event) => {
|
|
2020
|
+
onInteractOutside?.(event);
|
|
2021
|
+
if (windowed && !dismissOnOutsideClick) event.preventDefault();
|
|
2022
|
+
},
|
|
2023
|
+
onEscapeKeyDown: (event) => {
|
|
2024
|
+
onEscapeKeyDown?.(event);
|
|
2025
|
+
const pressedIn = event.target instanceof Node && event.target !== document.body ? event.target : document.activeElement;
|
|
2026
|
+
if (windowed && containerEl && !(pressedIn && containerEl.contains(pressedIn))) {
|
|
2027
|
+
event.preventDefault();
|
|
2028
|
+
}
|
|
2029
|
+
},
|
|
1975
2030
|
...hasDescription ? {} : { "aria-describedby": void 0 },
|
|
1976
2031
|
...props,
|
|
1977
2032
|
children: [
|
|
1978
2033
|
hasTitle ? null : /* @__PURE__ */ jsx21(VisuallyHidden2.Root, { children: /* @__PURE__ */ jsx21(DialogPrimitive2.Title, { children: "Dialog" }) }),
|
|
1979
|
-
/* @__PURE__ */ jsx21(DialogContainerContext.Provider, { value: containerEl, children: /* @__PURE__ */ jsx21(
|
|
2034
|
+
/* @__PURE__ */ jsx21(DialogContainerContext.Provider, { value: containerEl, children: /* @__PURE__ */ jsx21(DialogWindowHandleContext.Provider, { value: handle, children: /* @__PURE__ */ jsx21(
|
|
1980
2035
|
PortalContainerProvider,
|
|
1981
2036
|
{
|
|
1982
2037
|
container: containerEl ?? injectedContainer ?? null,
|
|
1983
2038
|
children
|
|
1984
2039
|
}
|
|
1985
|
-
) }),
|
|
2040
|
+
) }) }),
|
|
1986
2041
|
showCloseButton ? /* @__PURE__ */ jsxs10(
|
|
1987
2042
|
DialogPrimitive2.Close,
|
|
1988
2043
|
{
|
|
@@ -2005,19 +2060,28 @@ DialogContent.displayName = DialogPrimitive2.Content.displayName;
|
|
|
2005
2060
|
var DialogHeader = ({
|
|
2006
2061
|
className,
|
|
2007
2062
|
...props
|
|
2008
|
-
}) =>
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
"
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2063
|
+
}) => {
|
|
2064
|
+
const handle = React17.useContext(DialogWindowHandleContext);
|
|
2065
|
+
return /* @__PURE__ */ jsx21(
|
|
2066
|
+
"div",
|
|
2067
|
+
{
|
|
2068
|
+
"data-slot": "dialog-header",
|
|
2069
|
+
...handle ? {
|
|
2070
|
+
...handle,
|
|
2071
|
+
"data-window-handle": "",
|
|
2072
|
+
title: "Drag to move \xB7 double-click to recenter"
|
|
2073
|
+
} : {},
|
|
2074
|
+
className: cn(
|
|
2075
|
+
// DialogContent owns an absolute close control. Reserve its hit area in
|
|
2076
|
+
// every header so trailing actions never render underneath it.
|
|
2077
|
+
"flex flex-col space-y-1.5 pr-12 text-center sm:text-left",
|
|
2078
|
+
handle && "cursor-grab select-none active:cursor-grabbing",
|
|
2079
|
+
className
|
|
2080
|
+
),
|
|
2081
|
+
...props
|
|
2082
|
+
}
|
|
2083
|
+
);
|
|
2084
|
+
};
|
|
2021
2085
|
DialogHeader.displayName = "DialogHeader";
|
|
2022
2086
|
var DialogFooter = ({
|
|
2023
2087
|
className,
|
|
@@ -2207,7 +2271,7 @@ var DropdownMenuShortcut = ({
|
|
|
2207
2271
|
DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
|
|
2208
2272
|
|
|
2209
2273
|
// src/editable-label.tsx
|
|
2210
|
-
import { useCallback as useCallback3, useEffect as useEffect2, useRef as
|
|
2274
|
+
import { useCallback as useCallback3, useEffect as useEffect2, useRef as useRef3, useState as useState4 } from "react";
|
|
2211
2275
|
import { jsx as jsx23, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2212
2276
|
function EditableLabel({
|
|
2213
2277
|
value,
|
|
@@ -2233,7 +2297,7 @@ function EditableLabel({
|
|
|
2233
2297
|
const [draft, setDraft] = useState4(value);
|
|
2234
2298
|
const [error, setError] = useState4(null);
|
|
2235
2299
|
const [busy, setBusy] = useState4(false);
|
|
2236
|
-
const inputRef =
|
|
2300
|
+
const inputRef = useRef3(null);
|
|
2237
2301
|
useEffect2(() => {
|
|
2238
2302
|
if (!editing) setDraft(value);
|
|
2239
2303
|
}, [value, editing]);
|
|
@@ -2514,7 +2578,7 @@ var Label3 = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ *
|
|
|
2514
2578
|
Label3.displayName = LabelPrimitive.Root.displayName;
|
|
2515
2579
|
|
|
2516
2580
|
// src/overflow-toolbar.tsx
|
|
2517
|
-
import { useLayoutEffect, useMemo, useRef as
|
|
2581
|
+
import { useLayoutEffect, useMemo as useMemo2, useRef as useRef4, useState as useState5 } from "react";
|
|
2518
2582
|
import { Fragment, jsx as jsx26, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2519
2583
|
var GAP_PX = 6;
|
|
2520
2584
|
var TONE = {
|
|
@@ -2596,13 +2660,13 @@ function OverflowToolbar({
|
|
|
2596
2660
|
renderOverflowMenu,
|
|
2597
2661
|
renderTooltip
|
|
2598
2662
|
}) {
|
|
2599
|
-
const visibleActions =
|
|
2663
|
+
const visibleActions = useMemo2(
|
|
2600
2664
|
() => actions.filter((a) => !a.hidden),
|
|
2601
2665
|
[actions]
|
|
2602
2666
|
);
|
|
2603
|
-
const containerRef =
|
|
2604
|
-
const ghostRef =
|
|
2605
|
-
const leadingRef =
|
|
2667
|
+
const containerRef = useRef4(null);
|
|
2668
|
+
const ghostRef = useRef4(null);
|
|
2669
|
+
const leadingRef = useRef4(null);
|
|
2606
2670
|
const [visibleCount, setVisibleCount] = useState5(visibleActions.length);
|
|
2607
2671
|
const signature = visibleActions.map(
|
|
2608
2672
|
(a) => `${a.id}:${a.hideLabel ? 1 : 0}:${a.running ? 1 : 0}:${a.runningLabel ?? ""}:${a.label}`
|
|
@@ -4005,15 +4069,15 @@ var TextareaWithPrefix = React32.forwardRef(
|
|
|
4005
4069
|
TextareaWithPrefix.displayName = "TextareaWithPrefix";
|
|
4006
4070
|
|
|
4007
4071
|
// src/use-scroll-fade.ts
|
|
4008
|
-
import { useCallback as useCallback5, useEffect as useEffect4, useRef as
|
|
4072
|
+
import { useCallback as useCallback5, useEffect as useEffect4, useRef as useRef6, useState as useState8 } from "react";
|
|
4009
4073
|
var EPSILON = 2;
|
|
4010
4074
|
function useScrollFade() {
|
|
4011
4075
|
const [state, setState] = useState8({
|
|
4012
4076
|
top: false,
|
|
4013
4077
|
bottom: false
|
|
4014
4078
|
});
|
|
4015
|
-
const nodeRef =
|
|
4016
|
-
const cleanupRef =
|
|
4079
|
+
const nodeRef = useRef6(null);
|
|
4080
|
+
const cleanupRef = useRef6(null);
|
|
4017
4081
|
const measure = useCallback5(() => {
|
|
4018
4082
|
const el = nodeRef.current;
|
|
4019
4083
|
if (!el) return;
|