@wheelhouse/ui 0.2.16 → 0.3.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/dist/blocks/floating-menu-widget/floating-menu-widget.d.ts +4 -1
- package/dist/blocks/floating-menu-widget/floating-menu-widget.d.ts.map +1 -1
- package/dist/blocks/floating-menu-widget/floating-menu-widget.js +70 -22
- package/dist/blocks/floating-menu-widget/floating-menu-widget.stories.d.ts +1 -0
- package/dist/blocks/floating-menu-widget/floating-menu-widget.stories.d.ts.map +1 -1
- package/dist/blocks/floating-menu-widget/floating-menu-widget.stories.js +3 -0
- package/dist/blocks/floating-menu-widget/index.d.ts +1 -1
- package/dist/blocks/floating-menu-widget/index.d.ts.map +1 -1
- package/dist/components/badge/badge.d.ts +3 -3
- package/dist/components/badge/badge.js +3 -3
- package/dist/components/button/button.d.ts +8 -8
- package/dist/components/button/button.js +15 -15
- package/dist/components/button-group/button-group.js +3 -3
- package/dist/components/combobox/combobox.js +1 -1
- package/dist/components/data-grid/data-grid-column-filter.js +1 -1
- package/dist/components/data-grid/data-grid-column-header.js +1 -1
- package/dist/components/data-grid/data-grid-pagination.js +4 -4
- package/dist/components/data-grid/data-grid-table-dnd-rows.js +2 -2
- package/dist/components/data-grid/data-grid-table-dnd.js +1 -1
- package/dist/components/dialog/dialog.js +1 -1
- package/dist/components/filters/filter-date-metric-value.js +1 -1
- package/dist/components/input/input.js +4 -4
- package/dist/components/input-group/input-group.d.ts +1 -1
- package/dist/components/input-group/input-group.js +7 -7
- package/dist/components/native-select/native-select.js +1 -1
- package/dist/components/number-field/number-field.js +4 -4
- package/dist/components/select/select.js +1 -1
- package/dist/components/sheet/sheet.js +1 -1
- package/dist/components/sidebar/sidebar.js +6 -6
- package/dist/components/textarea/textarea.js +1 -1
- package/dist/components/toggle/toggle.d.ts +3 -3
- package/dist/components/toggle/toggle.d.ts.map +1 -1
- package/dist/components/toggle/toggle.js +3 -3
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -5,6 +5,7 @@ export type FloatingMenuWidgetInset = {
|
|
|
5
5
|
right: number;
|
|
6
6
|
bottom: number;
|
|
7
7
|
};
|
|
8
|
+
export type FloatingMenuWidgetCorner = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
8
9
|
export type FloatingMenuWidgetProps = Omit<React.ComponentProps<'div'>, 'children'> & {
|
|
9
10
|
children: React.ReactNode;
|
|
10
11
|
menuTitle: string;
|
|
@@ -18,9 +19,11 @@ export type FloatingMenuWidgetProps = Omit<React.ComponentProps<'div'>, 'childre
|
|
|
18
19
|
positionStorageKey?: string;
|
|
19
20
|
/** Long-press to drag. */
|
|
20
21
|
draggable?: boolean;
|
|
22
|
+
/** After a drag, glide to the nearest viewport corner (resting at `defaultInset` from its edges) and stay pinned there on resize. */
|
|
23
|
+
snapToCorners?: boolean;
|
|
21
24
|
open?: boolean;
|
|
22
25
|
onOpenChange?: (open: boolean) => void;
|
|
23
26
|
};
|
|
24
|
-
declare function FloatingMenuWidget({ children, menuTitle, menuDescription, triggerIcon, renderTrigger, triggerNativeButton, defaultInset, positionStorageKey, draggable, open: openControlled, onOpenChange: onOpenChangeControlled, className, ...rest }: FloatingMenuWidgetProps): import("react/jsx-runtime").JSX.Element;
|
|
27
|
+
declare function FloatingMenuWidget({ children, menuTitle, menuDescription, triggerIcon, renderTrigger, triggerNativeButton, defaultInset, positionStorageKey, draggable, snapToCorners, open: openControlled, onOpenChange: onOpenChangeControlled, className, ...rest }: FloatingMenuWidgetProps): import("react/jsx-runtime").JSX.Element;
|
|
25
28
|
export { FloatingMenuWidget };
|
|
26
29
|
//# sourceMappingURL=floating-menu-widget.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"floating-menu-widget.d.ts","sourceRoot":"","sources":["../../../src/blocks/floating-menu-widget/floating-menu-widget.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,EAA2C,KAAK,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAS7G,MAAM,MAAM,+BAA+B,GAAG,WAAW,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC;AAEzF,MAAM,MAAM,uBAAuB,GAAG;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,GAAG;IAClF,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,aAAa,CAAC,EAAE,+BAA+B,CAAC;IAChD,mEAAmE;IACnE,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,YAAY,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAChD,4DAA4D;IAC5D,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,0BAA0B;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CAC1C,CAAC;
|
|
1
|
+
{"version":3,"file":"floating-menu-widget.d.ts","sourceRoot":"","sources":["../../../src/blocks/floating-menu-widget/floating-menu-widget.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,EAA2C,KAAK,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAS7G,MAAM,MAAM,+BAA+B,GAAG,WAAW,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC;AAEzF,MAAM,MAAM,uBAAuB,GAAG;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,UAAU,GAAG,WAAW,GAAG,aAAa,GAAG,cAAc,CAAC;AAIjG,MAAM,MAAM,uBAAuB,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,GAAG;IAClF,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,aAAa,CAAC,EAAE,+BAA+B,CAAC;IAChD,mEAAmE;IACnE,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,YAAY,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAChD,4DAA4D;IAC5D,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,0BAA0B;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,qIAAqI;IACrI,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CAC1C,CAAC;AA2CF,iBAAS,kBAAkB,CAAC,EACxB,QAAQ,EACR,SAAS,EACT,eAAe,EACf,WAAyC,EACzC,aAAa,EACb,mBAA0B,EAC1B,YAAY,EACZ,kBAAkB,EAClB,SAAgB,EAChB,aAAqB,EACrB,IAAI,EAAE,cAAc,EACpB,YAAY,EAAE,sBAAsB,EACpC,SAAS,EACT,GAAG,IAAI,EACV,EAAE,uBAAuB,2CAwQzB;AAED,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
|
|
@@ -10,10 +10,11 @@ import { cn } from '../../lib/utils';
|
|
|
10
10
|
const DEFAULT_INSET = 24;
|
|
11
11
|
const LONG_PRESS_MS = 160;
|
|
12
12
|
const LONG_PRESS_MOVE_CANCEL_PX = 22;
|
|
13
|
+
const CORNERS = ['top-left', 'top-right', 'bottom-left', 'bottom-right'];
|
|
13
14
|
function clamp(n, min, max) {
|
|
14
15
|
return Math.min(max, Math.max(min, n));
|
|
15
16
|
}
|
|
16
|
-
function
|
|
17
|
+
function readStoredPosition(key) {
|
|
17
18
|
if (typeof window === 'undefined')
|
|
18
19
|
return null;
|
|
19
20
|
try {
|
|
@@ -23,29 +24,48 @@ function readStoredInset(key) {
|
|
|
23
24
|
const parsed = JSON.parse(raw);
|
|
24
25
|
if (!parsed || typeof parsed !== 'object')
|
|
25
26
|
return null;
|
|
26
|
-
const { right, bottom } = parsed;
|
|
27
|
+
const { right, bottom, corner } = parsed;
|
|
27
28
|
if (typeof right !== 'number' || typeof bottom !== 'number')
|
|
28
29
|
return null;
|
|
29
|
-
return { right, bottom };
|
|
30
|
+
return { right, bottom, corner: corner && CORNERS.includes(corner) ? corner : undefined };
|
|
30
31
|
}
|
|
31
32
|
catch {
|
|
32
33
|
return null;
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
|
-
function
|
|
36
|
+
function nearestCorner(rect) {
|
|
37
|
+
const vertical = rect.top + rect.height / 2 < window.innerHeight / 2 ? 'top' : 'bottom';
|
|
38
|
+
const horizontal = rect.left + rect.width / 2 < window.innerWidth / 2 ? 'left' : 'right';
|
|
39
|
+
return `${vertical}-${horizontal}`;
|
|
40
|
+
}
|
|
41
|
+
/** Resting `right`/`bottom` inset for a corner, given the widget size and the per-edge resting distance. */
|
|
42
|
+
function cornerInset(corner, width, height, rest) {
|
|
43
|
+
const margin = 8;
|
|
44
|
+
return {
|
|
45
|
+
right: corner.endsWith('right') ? rest.right : Math.max(margin, window.innerWidth - width - rest.right),
|
|
46
|
+
bottom: corner.startsWith('bottom') ? rest.bottom : Math.max(margin, window.innerHeight - height - rest.bottom),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function FloatingMenuWidget({ children, menuTitle, menuDescription, triggerIcon = _jsx(Menu, { className: "size-4" }), renderTrigger, triggerNativeButton = true, defaultInset, positionStorageKey, draggable = true, snapToCorners = false, open: openControlled, onOpenChange: onOpenChangeControlled, className, ...rest }) {
|
|
36
50
|
const isMobile = useIsMobile();
|
|
37
51
|
const anchorRef = React.useRef(null);
|
|
38
52
|
const planRef = React.useRef(null);
|
|
39
53
|
const longPressTimerRef = React.useRef(null);
|
|
40
54
|
const storageKeyFull = positionStorageKey ? `wheelhouse:floating-menu-widget:${positionStorageKey}` : null;
|
|
55
|
+
const restRight = defaultInset?.right ?? DEFAULT_INSET;
|
|
56
|
+
const restBottom = defaultInset?.bottom ?? DEFAULT_INSET;
|
|
41
57
|
const [inset, setInset] = React.useState(() => {
|
|
42
|
-
const stored = storageKeyFull ?
|
|
58
|
+
const stored = storageKeyFull ? readStoredPosition(storageKeyFull) : null;
|
|
43
59
|
if (stored)
|
|
44
|
-
return stored;
|
|
45
|
-
return {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
60
|
+
return { right: stored.right, bottom: stored.bottom };
|
|
61
|
+
return { right: restRight, bottom: restBottom };
|
|
62
|
+
});
|
|
63
|
+
const [corner, setCorner] = React.useState(() => {
|
|
64
|
+
if (!snapToCorners)
|
|
65
|
+
return null;
|
|
66
|
+
const stored = storageKeyFull ? readStoredPosition(storageKeyFull) : null;
|
|
67
|
+
// A stored inset without a corner predates snapping — leave it free until the next drag.
|
|
68
|
+
return stored ? (stored.corner ?? null) : 'bottom-right';
|
|
49
69
|
});
|
|
50
70
|
const insetRef = React.useRef(inset);
|
|
51
71
|
React.useEffect(() => {
|
|
@@ -74,6 +94,21 @@ function FloatingMenuWidget({ children, menuTitle, menuDescription, triggerIcon
|
|
|
74
94
|
}
|
|
75
95
|
};
|
|
76
96
|
}, []);
|
|
97
|
+
// While pinned to a corner, keep the resting inset exact across mounts and window resizes
|
|
98
|
+
// (top/left corners are expressed via right/bottom, so they drift without this).
|
|
99
|
+
React.useLayoutEffect(() => {
|
|
100
|
+
if (!snapToCorners || !corner)
|
|
101
|
+
return;
|
|
102
|
+
const reposition = () => {
|
|
103
|
+
const shell = anchorRef.current;
|
|
104
|
+
if (!shell)
|
|
105
|
+
return;
|
|
106
|
+
setInset(cornerInset(corner, shell.offsetWidth, shell.offsetHeight, { right: restRight, bottom: restBottom }));
|
|
107
|
+
};
|
|
108
|
+
reposition();
|
|
109
|
+
window.addEventListener('resize', reposition);
|
|
110
|
+
return () => window.removeEventListener('resize', reposition);
|
|
111
|
+
}, [snapToCorners, corner, restRight, restBottom]);
|
|
77
112
|
React.useEffect(() => {
|
|
78
113
|
if (!isDragging || typeof document === 'undefined')
|
|
79
114
|
return;
|
|
@@ -101,6 +136,7 @@ function FloatingMenuWidget({ children, menuTitle, menuDescription, triggerIcon
|
|
|
101
136
|
}
|
|
102
137
|
const { right, bottom } = insetRef.current;
|
|
103
138
|
planRef.current = { kind: 'drag', pointerId, startX, startY, originRight: right, originBottom: bottom };
|
|
139
|
+
setCorner(null);
|
|
104
140
|
setIsDragging(true);
|
|
105
141
|
}, []);
|
|
106
142
|
const onShellPointerDown = React.useCallback((event) => {
|
|
@@ -160,18 +196,30 @@ function FloatingMenuWidget({ children, menuTitle, menuDescription, triggerIcon
|
|
|
160
196
|
catch {
|
|
161
197
|
/* released */
|
|
162
198
|
}
|
|
163
|
-
|
|
164
|
-
if (storageKeyFull
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
catch {
|
|
169
|
-
/* quota / private mode */
|
|
170
|
-
}
|
|
199
|
+
const persist = (value) => {
|
|
200
|
+
if (!storageKeyFull || typeof window === 'undefined')
|
|
201
|
+
return;
|
|
202
|
+
try {
|
|
203
|
+
window.localStorage.setItem(storageKeyFull, JSON.stringify(value));
|
|
171
204
|
}
|
|
172
|
-
|
|
173
|
-
|
|
205
|
+
catch {
|
|
206
|
+
/* quota / private mode */
|
|
207
|
+
}
|
|
208
|
+
};
|
|
174
209
|
const shell = anchorRef.current;
|
|
210
|
+
if (snapToCorners && shell) {
|
|
211
|
+
const target = nearestCorner(shell.getBoundingClientRect());
|
|
212
|
+
const targetInset = cornerInset(target, shell.offsetWidth, shell.offsetHeight, { right: restRight, bottom: restBottom });
|
|
213
|
+
setCorner(target);
|
|
214
|
+
setInset(targetInset);
|
|
215
|
+
persist({ ...targetInset, corner: target });
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
setInset((cur) => {
|
|
219
|
+
persist(cur);
|
|
220
|
+
return cur;
|
|
221
|
+
});
|
|
222
|
+
}
|
|
175
223
|
if (shell) {
|
|
176
224
|
shell.style.pointerEvents = 'none';
|
|
177
225
|
requestAnimationFrame(() => {
|
|
@@ -183,8 +231,8 @@ function FloatingMenuWidget({ children, menuTitle, menuDescription, triggerIcon
|
|
|
183
231
|
return;
|
|
184
232
|
}
|
|
185
233
|
planRef.current = null;
|
|
186
|
-
}, [clearLongPressTimer, storageKeyFull]);
|
|
187
|
-
const shellClass = cn('fixed z-50 flex touch-none items-center justify-center overflow-hidden rounded-full bg-background shadow-lg ring-1 ring-foreground/5', isDragging && 'cursor-grabbing', className);
|
|
234
|
+
}, [clearLongPressTimer, storageKeyFull, snapToCorners, restRight, restBottom]);
|
|
235
|
+
const shellClass = cn('fixed z-50 flex touch-none items-center justify-center overflow-hidden rounded-full bg-background shadow-lg ring-1 ring-foreground/5', snapToCorners && !isDragging && 'transition-[right,bottom] duration-300 ease-out', isDragging && 'cursor-grabbing', className);
|
|
188
236
|
const shellPointer = draggable
|
|
189
237
|
? {
|
|
190
238
|
onPointerDown: onShellPointerDown,
|
|
@@ -11,5 +11,6 @@ declare const meta: {
|
|
|
11
11
|
export default meta;
|
|
12
12
|
type Story = StoryObj<typeof FloatingMenuWidget>;
|
|
13
13
|
export declare const Default: Story;
|
|
14
|
+
export declare const SnapToCorners: Story;
|
|
14
15
|
export declare const NotDraggable: Story;
|
|
15
16
|
//# sourceMappingURL=floating-menu-widget.stories.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"floating-menu-widget.stories.d.ts","sourceRoot":"","sources":["../../../src/blocks/floating-menu-widget/floating-menu-widget.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAKvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,QAAA,MAAM,IAAI;;;;;;;CAOiC,CAAC;AAE5C,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAqBjD,eAAO,MAAM,OAAO,EAAE,KAYrB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAQ1B,CAAC"}
|
|
1
|
+
{"version":3,"file":"floating-menu-widget.stories.d.ts","sourceRoot":"","sources":["../../../src/blocks/floating-menu-widget/floating-menu-widget.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAKvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,QAAA,MAAM,IAAI;;;;;;;CAOiC,CAAC;AAE5C,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAqBjD,eAAO,MAAM,OAAO,EAAE,KAYrB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAY3B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAQ1B,CAAC"}
|
|
@@ -17,6 +17,9 @@ function DemoLinks() {
|
|
|
17
17
|
export const Default = {
|
|
18
18
|
render: () => (_jsxs("div", { className: "relative min-h-[100dvh] bg-muted/30 p-8", children: [_jsx("p", { className: "max-w-md text-sm text-muted-foreground", children: "Click the circular control to open a popover on wide viewports (bottom sheet on narrow ones). Press and hold the control to drag it. Resize the preview to compare." }), _jsx(FloatingMenuWidget, { menuTitle: "Quick actions", menuDescription: "Shortcuts for this preview", positionStorageKey: "storybook-demo", children: _jsx(DemoLinks, {}) })] })),
|
|
19
19
|
};
|
|
20
|
+
export const SnapToCorners = {
|
|
21
|
+
render: () => (_jsxs("div", { className: "relative min-h-[100dvh] bg-muted/30 p-8", children: [_jsx("p", { className: "max-w-md text-sm text-muted-foreground", children: "Press and hold the control, drag it anywhere, and release \u2014 it glides to the nearest viewport corner and stays pinned there when the window resizes." }), _jsx(FloatingMenuWidget, { menuTitle: "Quick actions", snapToCorners: true, positionStorageKey: "storybook-snap-demo", children: _jsx(DemoLinks, {}) })] })),
|
|
22
|
+
};
|
|
20
23
|
export const NotDraggable = {
|
|
21
24
|
render: () => (_jsx("div", { className: "relative min-h-[100dvh] bg-muted/30 p-8", children: _jsx(FloatingMenuWidget, { menuTitle: "Menu", draggable: false, defaultInset: { right: 32, bottom: 32 }, children: _jsx(DemoLinks, {}) }) })),
|
|
22
25
|
};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { FloatingMenuWidget } from './floating-menu-widget';
|
|
2
|
-
export type { FloatingMenuWidgetInset, FloatingMenuWidgetProps, FloatingMenuWidgetRenderTrigger } from './floating-menu-widget';
|
|
2
|
+
export type { FloatingMenuWidgetCorner, FloatingMenuWidgetInset, FloatingMenuWidgetProps, FloatingMenuWidgetRenderTrigger } from './floating-menu-widget';
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/blocks/floating-menu-widget/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,YAAY,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,+BAA+B,EAAE,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/blocks/floating-menu-widget/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,YAAY,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,+BAA+B,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -19,9 +19,9 @@ declare const badgeVariantStyles: {
|
|
|
19
19
|
readonly 'destructive-outline': "border-border bg-background text-destructive-foreground dark:bg-input/30";
|
|
20
20
|
};
|
|
21
21
|
declare const badgeSizeStyles: {
|
|
22
|
-
readonly default: "h-5
|
|
23
|
-
readonly lg: "h-
|
|
24
|
-
readonly sm: "h-5 min-w-5 rounded-[.25rem] px-[calc(--spacing(1)-1px)] text-xs sm:h-
|
|
22
|
+
readonly default: "h-5 min-w-5 rounded-[.25rem] px-[calc(--spacing(1)-1px)] text-xs sm:h-4 sm:min-w-4 sm:text-[.625rem]";
|
|
23
|
+
readonly lg: "h-5.5 min-w-5.5 px-[calc(--spacing(1)-0px)] text-sm sm:h-4.5 sm:min-w-4.5 sm:text-xs";
|
|
24
|
+
readonly sm: "h-4.5 min-w-4.5 rounded-[.25rem] px-[calc(--spacing(1)-1px)] text-xs sm:h-3.5 sm:min-w-3.5 sm:text-[.625rem]";
|
|
25
25
|
};
|
|
26
26
|
export declare const badgeVariantKeys: (keyof typeof badgeVariantStyles)[];
|
|
27
27
|
export declare const badgeSizeKeys: (keyof typeof badgeSizeStyles)[];
|
|
@@ -21,9 +21,9 @@ const badgeVariantStyles = {
|
|
|
21
21
|
'destructive-outline': 'border-border bg-background text-destructive-foreground dark:bg-input/30',
|
|
22
22
|
};
|
|
23
23
|
const badgeSizeStyles = {
|
|
24
|
-
default: 'h-5
|
|
25
|
-
lg: 'h-
|
|
26
|
-
sm: 'h-5 min-w-5 rounded-[.25rem] px-[calc(--spacing(1)-1px)] text-xs sm:h-
|
|
24
|
+
default: 'h-5 min-w-5 rounded-[.25rem] px-[calc(--spacing(1)-1px)] text-xs sm:h-4 sm:min-w-4 sm:text-[.625rem]',
|
|
25
|
+
lg: 'h-5.5 min-w-5.5 px-[calc(--spacing(1)-0px)] text-sm sm:h-4.5 sm:min-w-4.5 sm:text-xs',
|
|
26
|
+
sm: 'h-4.5 min-w-4.5 rounded-[.25rem] px-[calc(--spacing(1)-1px)] text-xs sm:h-3.5 sm:min-w-3.5 sm:text-[.625rem]',
|
|
27
27
|
};
|
|
28
28
|
export const badgeVariantKeys = Object.keys(badgeVariantStyles);
|
|
29
29
|
export const badgeSizeKeys = Object.keys(badgeSizeStyles);
|
|
@@ -10,14 +10,14 @@ declare const buttonVariantStyles: {
|
|
|
10
10
|
readonly link: "text-primary underline-offset-4 hover:underline [&_[data-slot=button-loading-indicator]]:text-primary";
|
|
11
11
|
};
|
|
12
12
|
declare const buttonSizeStyles: {
|
|
13
|
-
readonly default: "h-
|
|
14
|
-
readonly xs: "h-
|
|
15
|
-
readonly sm: "h-
|
|
16
|
-
readonly lg: "h-
|
|
17
|
-
readonly icon: "size-
|
|
18
|
-
readonly 'icon-xs': "size-
|
|
19
|
-
readonly 'icon-sm': "size-
|
|
20
|
-
readonly 'icon-lg': "size-
|
|
13
|
+
readonly default: "h-7 gap-1.5 rounded-[min(var(--radius-md),12px)] px-[calc(--spacing(2.5)-1px)] text-sm in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-2 [&_svg:not([class*='size-'])]:size-3.5";
|
|
14
|
+
readonly xs: "h-5 gap-1 rounded-[min(var(--radius-md),8px)] px-1.5 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1 has-data-[icon=inline-start]:pl-1 [&_svg:not([class*='size-'])]:size-2.5";
|
|
15
|
+
readonly sm: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3";
|
|
16
|
+
readonly lg: "h-8 gap-2 px-[calc(--spacing(3)-1px)] text-sm has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2 [&_svg:not([class*='size-'])]:size-3";
|
|
17
|
+
readonly icon: "size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg";
|
|
18
|
+
readonly 'icon-xs': "size-5 rounded-[min(var(--radius-md),8px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-2.5";
|
|
19
|
+
readonly 'icon-sm': "size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3";
|
|
20
|
+
readonly 'icon-lg': "size-8 text-sm";
|
|
21
21
|
};
|
|
22
22
|
export declare const buttonVariantKeys: (keyof typeof buttonVariantStyles)[];
|
|
23
23
|
export declare const buttonSizeKeys: (keyof typeof buttonSizeStyles)[];
|
|
@@ -13,14 +13,14 @@ const buttonVariantStyles = {
|
|
|
13
13
|
link: 'text-primary underline-offset-4 hover:underline [&_[data-slot=button-loading-indicator]]:text-primary',
|
|
14
14
|
};
|
|
15
15
|
const buttonSizeStyles = {
|
|
16
|
-
default: "h-
|
|
17
|
-
xs: "h-
|
|
18
|
-
sm: "h-
|
|
19
|
-
lg: "h-
|
|
20
|
-
icon: 'size-
|
|
21
|
-
'icon-xs': "size-
|
|
22
|
-
'icon-sm':
|
|
23
|
-
'icon-lg': 'size-
|
|
16
|
+
default: "h-7 gap-1.5 rounded-[min(var(--radius-md),12px)] px-[calc(--spacing(2.5)-1px)] text-sm in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-2 [&_svg:not([class*='size-'])]:size-3.5",
|
|
17
|
+
xs: "h-5 gap-1 rounded-[min(var(--radius-md),8px)] px-1.5 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1 has-data-[icon=inline-start]:pl-1 [&_svg:not([class*='size-'])]:size-2.5",
|
|
18
|
+
sm: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
|
|
19
|
+
lg: "h-8 gap-2 px-[calc(--spacing(3)-1px)] text-sm has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2 [&_svg:not([class*='size-'])]:size-3",
|
|
20
|
+
icon: 'size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg',
|
|
21
|
+
'icon-xs': "size-5 rounded-[min(var(--radius-md),8px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-2.5",
|
|
22
|
+
'icon-sm': "size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3",
|
|
23
|
+
'icon-lg': 'size-8 text-sm',
|
|
24
24
|
};
|
|
25
25
|
export const buttonVariantKeys = Object.keys(buttonVariantStyles);
|
|
26
26
|
export const buttonSizeKeys = Object.keys(buttonSizeStyles);
|
|
@@ -35,13 +35,13 @@ const buttonVariants = cva("group/button relative inline-flex shrink-0 cursor-po
|
|
|
35
35
|
},
|
|
36
36
|
});
|
|
37
37
|
const spinnerSizeByButtonSize = {
|
|
38
|
-
default: 'size-3',
|
|
39
|
-
xs: 'size-
|
|
40
|
-
sm: 'size-3
|
|
41
|
-
lg: 'size-3
|
|
42
|
-
icon: 'size-
|
|
43
|
-
'icon-xs': 'size-
|
|
44
|
-
'icon-sm': 'size-3
|
|
38
|
+
default: 'size-3.5',
|
|
39
|
+
xs: 'size-2.5',
|
|
40
|
+
sm: 'size-3',
|
|
41
|
+
lg: 'size-3',
|
|
42
|
+
icon: 'size-3.5',
|
|
43
|
+
'icon-xs': 'size-2.5',
|
|
44
|
+
'icon-sm': 'size-3',
|
|
45
45
|
'icon-lg': 'size-4',
|
|
46
46
|
};
|
|
47
47
|
function Button({ className, variant = 'default', size = 'default', loading = false, disabled, children, ...props }) {
|
|
@@ -7,9 +7,9 @@ import { Separator } from '../separator';
|
|
|
7
7
|
const buttonGroupTextVariants = cva('flex shrink-0 items-center gap-2 rounded-lg border bg-muted font-medium [&_svg]:pointer-events-none', {
|
|
8
8
|
variants: {
|
|
9
9
|
size: {
|
|
10
|
-
sm: "h-
|
|
11
|
-
default: "min-h-
|
|
12
|
-
lg: "h-
|
|
10
|
+
sm: "h-6 px-1.5 text-xs leading-none [&_svg:not([class*='size-'])]:size-3",
|
|
11
|
+
default: "min-h-7 px-2 text-sm leading-none [&_svg:not([class*='size-'])]:size-3.5",
|
|
12
|
+
lg: "min-h-8 px-2.5 text-base [&_svg:not([class*='size-'])]:size-4",
|
|
13
13
|
},
|
|
14
14
|
},
|
|
15
15
|
defaultVariants: {
|
|
@@ -52,7 +52,7 @@ function ComboboxChips({ className, ...props }) {
|
|
|
52
52
|
return (_jsx(ComboboxPrimitive.Chips, { "data-slot": "combobox-chips", className: cn('flex min-h-8 flex-wrap items-center gap-1 rounded-lg border border-input bg-transparent bg-clip-padding px-2.5 py-1 text-sm transition-colors focus-within:border-ring focus-within:ring-3 focus-within:ring-ring/50 has-aria-invalid:border-destructive has-aria-invalid:ring-3 has-aria-invalid:ring-destructive/20 has-data-[slot=combobox-chip]:px-1 dark:bg-input/30 dark:has-aria-invalid:border-destructive/50 dark:has-aria-invalid:ring-destructive/40', className), ...props }));
|
|
53
53
|
}
|
|
54
54
|
function ComboboxChip({ className, children, showRemove = true, ...props }) {
|
|
55
|
-
return (_jsxs(ComboboxPrimitive.Chip, { "data-slot": "combobox-chip", className: cn('flex h-[calc(--spacing(5.25))] w-fit items-center justify-center gap-1 rounded-sm bg-muted px-1.5 text-xs font-medium whitespace-nowrap text-foreground has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50 has-data-[slot=combobox-chip-remove]:pr-0', className), ...props, children: [children, showRemove && (_jsx(ComboboxPrimitive.ChipRemove, { render: _jsx(Button, { variant: "ghost", size: "icon-
|
|
55
|
+
return (_jsxs(ComboboxPrimitive.Chip, { "data-slot": "combobox-chip", className: cn('flex h-[calc(--spacing(5.25))] w-fit items-center justify-center gap-1 rounded-sm bg-muted px-1.5 text-xs font-medium whitespace-nowrap text-foreground has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50 has-data-[slot=combobox-chip-remove]:pr-0', className), ...props, children: [children, showRemove && (_jsx(ComboboxPrimitive.ChipRemove, { render: _jsx(Button, { variant: "ghost", size: "icon-sm" }), className: "-ml-1 opacity-50 hover:opacity-100", "data-slot": "combobox-chip-remove", children: _jsx(X, { className: "pointer-events-none" }) }))] }));
|
|
56
56
|
}
|
|
57
57
|
function ComboboxChipsInput({ className, ...props }) {
|
|
58
58
|
return _jsx(ComboboxPrimitive.Input, { "data-slot": "combobox-chip-input", className: cn('min-w-16 flex-1 outline-none', className), ...props });
|
|
@@ -17,7 +17,7 @@ function DataGridColumnFilter({ column, title, options }) {
|
|
|
17
17
|
return options;
|
|
18
18
|
return options.filter((option) => option.label.toLowerCase().includes(searchQuery.toLowerCase()));
|
|
19
19
|
}, [options, searchQuery]);
|
|
20
|
-
return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { render: _jsxs(Button, { variant: "outline",
|
|
20
|
+
return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { render: _jsxs(Button, { variant: "outline", children: [_jsx(CirclePlusIcon, { className: "size-4" }), title, selectedValues?.size > 0 && (_jsxs(_Fragment, { children: [_jsx(Separator, { orientation: "vertical", className: "mx-2 h-4" }), _jsx(Badge, { variant: "secondary", className: "rounded-sm px-1 font-normal lg:hidden", children: selectedValues.size }), _jsx("div", { className: "hidden space-x-1 lg:flex", children: selectedValues.size > 2 ? (_jsxs(Badge, { variant: "secondary", className: "rounded-sm px-1 font-normal", children: [selectedValues.size, " selected"] })) : (options
|
|
21
21
|
.filter((option) => selectedValues.has(option.value))
|
|
22
22
|
.map((option) => (_jsx(Badge, { variant: "secondary", className: "rounded-sm px-1 font-normal", children: option.label }, option.value)))) })] }))] }) }), _jsxs(PopoverContent, { className: "w-[200px] p-0", align: "start", children: [_jsx("div", { className: "p-2", children: _jsx(Input, { placeholder: title, value: searchQuery, onChange: (e) => setSearchQuery(e.target.value) }) }), _jsxs("div", { className: "max-h-[300px] overflow-y-auto", children: [filteredOptions.length === 0 ? (_jsx("div", { className: "py-6 text-center text-sm text-muted-foreground", children: "No results found." })) : (_jsx("div", { className: "p-1", children: filteredOptions.map((option) => {
|
|
23
23
|
const isSelected = selectedValues.has(option.value);
|
|
@@ -126,7 +126,7 @@ function DataGridColumnHeaderInner({ column, title, icon, className, filter, vis
|
|
|
126
126
|
columnVisibilityKey, // Needed to update checkbox states when visibility changes
|
|
127
127
|
]);
|
|
128
128
|
if (hasControls) {
|
|
129
|
-
return (_jsxs("div", { className: "flex h-full items-center justify-between gap-1.5", children: [_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { render: _jsxs(Button, { variant: "ghost", className: headerButtonClassName, disabled: isLoading || recordCount === 0, children: [icon && icon, resolvedTitle, sortIcon] }) }), _jsx(DropdownMenuContent, { className: "w-40", align: "start", children: menuItems })] }), props.tableLayout?.columnsPinnable && canPin && isPinned && (_jsx(Button, { size: "icon
|
|
129
|
+
return (_jsxs("div", { className: "flex h-full items-center justify-between gap-1.5", children: [_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { render: _jsxs(Button, { variant: "ghost", className: headerButtonClassName, disabled: isLoading || recordCount === 0, children: [icon && icon, resolvedTitle, sortIcon] }) }), _jsx(DropdownMenuContent, { className: "w-40", align: "start", children: menuItems })] }), props.tableLayout?.columnsPinnable && canPin && isPinned && (_jsx(Button, { size: "icon", variant: "ghost", className: "-me-1 size-7 rounded-md", onClick: () => column.pin(false), "aria-label": `Unpin ${resolvedTitle} column`, title: `Unpin ${resolvedTitle} column`, children: _jsx(PinOffIcon, { className: "size-3.5! opacity-50!", "aria-hidden": "true" }) }))] }));
|
|
130
130
|
}
|
|
131
131
|
if (canSort || (props.tableLayout?.columnsResizable && canResize)) {
|
|
132
132
|
return (_jsx("div", { className: "flex h-full items-center", children: _jsxs(Button, { variant: "ghost", className: headerButtonClassName, disabled: isLoading || recordCount === 0, onClick: handleSort, children: [icon && icon, resolvedTitle, sortIcon] }) }));
|
|
@@ -44,7 +44,7 @@ function DataGridPagination(props) {
|
|
|
44
44
|
const renderPageButtons = () => {
|
|
45
45
|
const buttons = [];
|
|
46
46
|
for (let i = currentGroupStart; i < currentGroupEnd; i++) {
|
|
47
|
-
buttons.push(_jsx(Button, { size: "icon
|
|
47
|
+
buttons.push(_jsx(Button, { size: "icon", variant: "ghost", className: cn(btnBaseClasses, 'text-muted-foreground', {
|
|
48
48
|
'bg-accent text-accent-foreground': pageIndex === i,
|
|
49
49
|
}), onClick: () => {
|
|
50
50
|
if (pageIndex !== i) {
|
|
@@ -57,20 +57,20 @@ function DataGridPagination(props) {
|
|
|
57
57
|
// Render a "previous" ellipsis button if there are previous pages to show
|
|
58
58
|
const renderEllipsisPrevButton = () => {
|
|
59
59
|
if (currentGroupStart > 0) {
|
|
60
|
-
return (_jsx(Button, { size: "icon
|
|
60
|
+
return (_jsx(Button, { size: "icon", className: btnBaseClasses, variant: "ghost", onClick: () => table.setPageIndex(currentGroupStart - 1), children: mergedProps.ellipsisText }));
|
|
61
61
|
}
|
|
62
62
|
return null;
|
|
63
63
|
};
|
|
64
64
|
// Render a "next" ellipsis button if there are more pages to show after the current group
|
|
65
65
|
const renderEllipsisNextButton = () => {
|
|
66
66
|
if (currentGroupEnd < pageCount) {
|
|
67
|
-
return (_jsx(Button, { className: btnBaseClasses, variant: "ghost", size: "icon
|
|
67
|
+
return (_jsx(Button, { className: btnBaseClasses, variant: "ghost", size: "icon", onClick: () => table.setPageIndex(currentGroupEnd), children: mergedProps.ellipsisText }));
|
|
68
68
|
}
|
|
69
69
|
return null;
|
|
70
70
|
};
|
|
71
71
|
return (_jsxs("div", { "data-slot": "data-grid-pagination", className: cn('flex grow flex-col flex-wrap items-center justify-between gap-2.5 py-2.5 sm:flex-row sm:py-0', mergedProps?.className), children: [_jsx("div", { className: "order-2 flex flex-wrap items-center space-x-2.5 pb-2.5 sm:order-1 sm:pb-0", children: isLoading ? (mergedProps?.sizesSkeleton) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "text-sm text-muted-foreground", children: mergedProps.rowsPerPageLabel }), _jsxs(Select, { value: `${pageSize}`, onValueChange: (value) => {
|
|
72
72
|
const newPageSize = Number(value);
|
|
73
73
|
table.setPageSize(newPageSize);
|
|
74
|
-
}, children: [_jsx(SelectTrigger, { className: "w-14",
|
|
74
|
+
}, children: [_jsx(SelectTrigger, { className: "w-14", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { side: "top", className: "min-w-18", children: mergedProps?.sizes?.map((size) => (_jsx(SelectItem, { value: `${size}`, children: size }, size))) })] })] })) }), _jsx("div", { className: "order-1 flex flex-col items-center justify-center gap-2.5 pt-2.5 sm:order-2 sm:flex-row sm:justify-end sm:pt-0", children: isLoading ? (mergedProps?.infoSkeleton) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "order-2 text-sm text-nowrap text-muted-foreground sm:order-1", children: paginationInfo }), pageCount > 1 && (_jsxs("div", { className: "order-1 flex items-center space-x-1 sm:order-2", children: [_jsxs(Button, { size: "icon", variant: "ghost", className: btnArrowClasses, onClick: () => table.previousPage(), disabled: !table.getCanPreviousPage(), children: [_jsx("span", { className: "sr-only", children: mergedProps.previousPageLabel }), _jsx(ChevronLeftIcon, { className: "size-4" })] }), renderEllipsisPrevButton(), renderPageButtons(), renderEllipsisNextButton(), _jsxs(Button, { size: "icon", variant: "ghost", className: btnArrowClasses, onClick: () => table.nextPage(), disabled: !table.getCanNextPage(), children: [_jsx("span", { className: "sr-only", children: mergedProps.nextPageLabel }), _jsx(ChevronRightIcon, { className: "size-4" })] })] }))] })) })] }));
|
|
75
75
|
}
|
|
76
76
|
export { DataGridPagination };
|
|
@@ -16,9 +16,9 @@ function DataGridTableDndRowHandle({ className }) {
|
|
|
16
16
|
const context = useContext(SortableRowContext);
|
|
17
17
|
if (!context) {
|
|
18
18
|
// Fallback if context is not available (shouldn't happen in normal usage)
|
|
19
|
-
return (_jsx(Button, { variant: "ghost", size: "icon
|
|
19
|
+
return (_jsx(Button, { variant: "ghost", size: "icon", className: cn('size-7 cursor-grab opacity-70 hover:bg-transparent hover:opacity-100 active:cursor-grabbing', className), disabled: true, children: _jsx(GripHorizontalIcon, {}) }));
|
|
20
20
|
}
|
|
21
|
-
return (_jsx(Button, { variant: "ghost", size: "icon
|
|
21
|
+
return (_jsx(Button, { variant: "ghost", size: "icon", className: cn('size-7 cursor-grab opacity-70 hover:bg-transparent hover:opacity-100 active:cursor-grabbing', className), ...context.attributes, ...context.listeners, children: _jsx(GripHorizontalIcon, {}) }));
|
|
22
22
|
}
|
|
23
23
|
function DataGridTableDndRow({ row }) {
|
|
24
24
|
const { transform, transition, setNodeRef, isDragging, attributes, listeners } = useSortable({
|
|
@@ -27,7 +27,7 @@ function DataGridTableDndHeader({ header }) {
|
|
|
27
27
|
width: props.tableLayout?.columnsResizable ? `calc(var(--header-${header.id}-size) * 1px)` : header.column.getSize(),
|
|
28
28
|
zIndex: isDragging ? 1 : 0,
|
|
29
29
|
};
|
|
30
|
-
return (_jsx(DataGridTableHeadRowCell, { header: header, dndStyle: style, dndRef: setNodeRef, children: _jsxs("div", { className: "flex items-center justify-start gap-0.5", children: [canOrder && (_jsx(Button, { size: "icon
|
|
30
|
+
return (_jsx(DataGridTableHeadRowCell, { header: header, dndStyle: style, dndRef: setNodeRef, children: _jsxs("div", { className: "flex items-center justify-start gap-0.5", children: [canOrder && (_jsx(Button, { size: "icon", variant: "ghost", className: `-ms-2 size-6 ${isDragging ? 'cursor-grabbing' : 'cursor-grab active:cursor-grabbing'}`, ...attributes, ...listeners, "aria-label": "Drag to reorder", children: _jsx(GripVerticalIcon, { className: "opacity-60 hover:opacity-100", "aria-hidden": "true" }) })), _jsx("span", { className: "grow truncate", children: header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext()) }), props.tableLayout?.columnsResizable && column.getCanResize() && _jsx(DataGridTableHeadRowCellResize, { header: header })] }) }));
|
|
31
31
|
}
|
|
32
32
|
function DataGridTableDndCell({ cell }) {
|
|
33
33
|
const { props } = useDataGrid();
|
|
@@ -21,7 +21,7 @@ function DialogOverlay({ className, ...props }) {
|
|
|
21
21
|
return (_jsx(DialogPrimitive.Backdrop, { "data-slot": "dialog-overlay", className: cn('fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0', className), ...props }));
|
|
22
22
|
}
|
|
23
23
|
function DialogContent({ className, children, showCloseButton = true, ...props }) {
|
|
24
|
-
return (_jsxs(DialogPortal, { children: [_jsx(DialogOverlay, {}), _jsxs(DialogPrimitive.Popup, { "data-slot": "dialog-content", className: cn('fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-popover p-4 text-sm text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95', className), ...props, children: [children, showCloseButton && (_jsxs(DialogPrimitive.Close, { "data-slot": "dialog-close", render: _jsx(Button, { variant: "ghost", className: "absolute top-2 right-2", size: "icon
|
|
24
|
+
return (_jsxs(DialogPortal, { children: [_jsx(DialogOverlay, {}), _jsxs(DialogPrimitive.Popup, { "data-slot": "dialog-content", className: cn('fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-popover p-4 text-sm text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95', className), ...props, children: [children, showCloseButton && (_jsxs(DialogPrimitive.Close, { "data-slot": "dialog-close", render: _jsx(Button, { variant: "ghost", className: "absolute top-2 right-2", size: "icon" }), children: [_jsx(X, {}), _jsx("span", { className: "sr-only", children: "Close" })] }))] })] }));
|
|
25
25
|
}
|
|
26
26
|
function DialogHeader({ className, ...props }) {
|
|
27
27
|
return _jsx("div", { "data-slot": "dialog-header", className: cn('flex flex-col gap-2', className), ...props });
|
|
@@ -176,7 +176,7 @@ export function FilterDateMetricBarPeriodSegments({ field, values, onChange, i18
|
|
|
176
176
|
if (!open) {
|
|
177
177
|
setCustomDraft(null);
|
|
178
178
|
}
|
|
179
|
-
}, children: _jsxs(DialogContent, { className: "max-h-[min(90vh,32rem)] w-[min(calc(100vw-2rem),28rem)] gap-0 overflow-y-auto p-4 sm:max-w-none", children: [_jsx(DialogHeader, { className: "pb-2", children: _jsx(DialogTitle, { children: mergedDateI18n.selectDate }) }), _jsx("div", { className: "flex flex-col gap-6 py-2", children: _jsx("section", { className: "flex flex-col gap-2", children: _jsx(DateSelector, { ...field.dateMetricProps, className: cn('max-w-none space-y-3', field.dateMetricProps?.className), value: customDraft ?? dateMetricValueForCustomEditor(payload.date), onChange: setCustomDraft, showOperators: field.dateMetricProps?.showOperators !== false, showInput: field.dateMetricProps?.showInput ?? false, dayDateFormat: dayFormat, showRollingPresets: false }) }) }), _jsx(DialogFooter, { className: "mt-2 border-t pt-4 sm:justify-end", children: _jsx(Button, { type: "button",
|
|
179
|
+
}, children: _jsxs(DialogContent, { className: "max-h-[min(90vh,32rem)] w-[min(calc(100vw-2rem),28rem)] gap-0 overflow-y-auto p-4 sm:max-w-none", children: [_jsx(DialogHeader, { className: "pb-2", children: _jsx(DialogTitle, { children: mergedDateI18n.selectDate }) }), _jsx("div", { className: "flex flex-col gap-6 py-2", children: _jsx("section", { className: "flex flex-col gap-2", children: _jsx(DateSelector, { ...field.dateMetricProps, className: cn('max-w-none space-y-3', field.dateMetricProps?.className), value: customDraft ?? dateMetricValueForCustomEditor(payload.date), onChange: setCustomDraft, showOperators: field.dateMetricProps?.showOperators !== false, showInput: field.dateMetricProps?.showInput ?? false, dayDateFormat: dayFormat, showRollingPresets: false }) }) }), _jsx(DialogFooter, { className: "mt-2 border-t pt-4 sm:justify-end", children: _jsx(Button, { type: "button", variant: "default", onClick: commitCustomDialog, children: i18n.dateMetricDialogDone }) })] }) })] }));
|
|
180
180
|
}
|
|
181
181
|
/** Typographic en dash (–) for “no amount” on the bar trigger. */
|
|
182
182
|
const METRIC_EMPTY_AMOUNT = '\u2013';
|
|
@@ -4,12 +4,12 @@ import * as React from 'react';
|
|
|
4
4
|
import { Input as InputPrimitive } from '@base-ui/react/input';
|
|
5
5
|
import { cva } from 'class-variance-authority';
|
|
6
6
|
import { cn } from '../../lib/utils';
|
|
7
|
-
const inputVariants = cva('flex w-full min-w-0 rounded-md border border-input bg-background shadow-xs transition-[color,box-shadow] outline-none group-has-disabled/field:opacity-50 file:inline-flex file:h-
|
|
7
|
+
const inputVariants = cva('flex w-full min-w-0 rounded-md border border-input bg-background shadow-xs transition-[color,box-shadow] outline-none group-has-disabled/field:opacity-50 file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-invalid:border-destructive data-invalid:ring-3 data-invalid:ring-destructive/20 dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 dark:data-invalid:border-destructive/50 dark:data-invalid:ring-destructive/40', {
|
|
8
8
|
variants: {
|
|
9
9
|
size: {
|
|
10
|
-
sm: 'h-
|
|
11
|
-
default: 'h-
|
|
12
|
-
lg: 'h-
|
|
10
|
+
sm: 'h-6 rounded-[min(var(--radius-md),10px)] px-[calc(--spacing(2)-1px)] text-xs',
|
|
11
|
+
default: 'h-7 rounded-[min(var(--radius-md),12px)] px-[calc(--spacing(2.5)-1px)] text-sm',
|
|
12
|
+
lg: 'h-8 px-[calc(--spacing(3)-1px)] text-sm',
|
|
13
13
|
},
|
|
14
14
|
},
|
|
15
15
|
defaultVariants: {
|
|
@@ -31,7 +31,7 @@ export type InputGroupInputProps = InputProps;
|
|
|
31
31
|
export type InputGroupTextareaProps = TextareaProps;
|
|
32
32
|
/**
|
|
33
33
|
* Wraps a control and addons in a single bordered, focus-styled shell. Set `data-disabled` on the root when the field is disabled.
|
|
34
|
-
* `size` sets shell height (`sm` =
|
|
34
|
+
* `size` sets shell height (`sm` = 24px, `default` = 28px, `lg` = 32px) and is inherited by `InputGroupInput` unless overridden there.
|
|
35
35
|
*/
|
|
36
36
|
declare function InputGroup({ className, size, ...props }: InputGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
37
37
|
/**
|
|
@@ -11,16 +11,16 @@ const InputGroupSizeContext = React.createContext(undefined);
|
|
|
11
11
|
const inputGroupVariants = cva('group/input-group relative flex w-full min-w-0 items-center rounded-lg border border-input transition-colors outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-disabled:bg-input/50 has-disabled:opacity-50 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:bg-input/30 dark:has-disabled:bg-input/80 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5', {
|
|
12
12
|
variants: {
|
|
13
13
|
size: {
|
|
14
|
-
sm: 'h-
|
|
15
|
-
default: 'h-
|
|
16
|
-
lg: 'h-
|
|
14
|
+
sm: 'h-6 rounded-[min(var(--radius-md),10px)]',
|
|
15
|
+
default: 'h-7 rounded-[min(var(--radius-md),12px)]',
|
|
16
|
+
lg: 'h-8',
|
|
17
17
|
},
|
|
18
18
|
},
|
|
19
19
|
defaultVariants: {
|
|
20
20
|
size: 'default',
|
|
21
21
|
},
|
|
22
22
|
});
|
|
23
|
-
const inputGroupAddonVariants = cva("flex h-auto cursor-text items-center justify-center gap-2 py-1
|
|
23
|
+
const inputGroupAddonVariants = cva("flex h-auto cursor-text items-center justify-center gap-2 py-1 text-sm font-medium text-muted-foreground select-none group-data-[disabled=true]/input-group:opacity-50 group-data-[size=lg]/input-group:py-1.5 group-data-[size=sm]/input-group:py-0.5 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-3.5 group-data-[size=lg]/input-group:[&>svg:not([class*='size-'])]:size-4 group-data-[size=sm]/input-group:[&>svg:not([class*='size-'])]:size-3", {
|
|
24
24
|
variants: {
|
|
25
25
|
align: {
|
|
26
26
|
'inline-start': 'order-first pl-2 has-[>button]:ml-[-0.3rem] has-[>kbd]:ml-[-0.15rem]',
|
|
@@ -37,10 +37,10 @@ export const inputGroupAddonAlignKeys = ['inline-start', 'inline-end', 'block-st
|
|
|
37
37
|
const inputGroupButtonVariants = cva('flex items-center gap-2 text-sm shadow-none', {
|
|
38
38
|
variants: {
|
|
39
39
|
size: {
|
|
40
|
-
xs: "h-
|
|
40
|
+
xs: "h-5 gap-1 rounded-[calc(var(--radius)-3px)] px-1 [&>svg:not([class*='size-'])]:size-3",
|
|
41
41
|
sm: '',
|
|
42
42
|
'icon-xs': 'size-6 rounded-[calc(var(--radius)-3px)] p-0 has-[>svg]:p-0',
|
|
43
|
-
'icon-sm': 'size-
|
|
43
|
+
'icon-sm': 'size-7 p-0 has-[>svg]:p-0',
|
|
44
44
|
},
|
|
45
45
|
},
|
|
46
46
|
defaultVariants: {
|
|
@@ -50,7 +50,7 @@ const inputGroupButtonVariants = cva('flex items-center gap-2 text-sm shadow-non
|
|
|
50
50
|
export const inputGroupButtonSizeKeys = ['xs', 'sm', 'icon-xs', 'icon-sm'];
|
|
51
51
|
/**
|
|
52
52
|
* Wraps a control and addons in a single bordered, focus-styled shell. Set `data-disabled` on the root when the field is disabled.
|
|
53
|
-
* `size` sets shell height (`sm` =
|
|
53
|
+
* `size` sets shell height (`sm` = 24px, `default` = 28px, `lg` = 32px) and is inherited by `InputGroupInput` unless overridden there.
|
|
54
54
|
*/
|
|
55
55
|
function InputGroup({ className, size = 'default', ...props }) {
|
|
56
56
|
const resolvedSize = size ?? 'default';
|
|
@@ -3,7 +3,7 @@ import * as React from 'react';
|
|
|
3
3
|
import { ChevronDown } from 'lucide-react';
|
|
4
4
|
import { cn } from '../../lib/utils';
|
|
5
5
|
function NativeSelect({ className, size = 'default', ...props }) {
|
|
6
|
-
return (_jsxs("div", { className: cn('group/native-select relative w-fit has-[select:disabled]:opacity-50', className), "data-slot": "native-select-wrapper", "data-size": size, children: [_jsx("select", { "data-slot": "native-select", "data-size": size, className: "h-
|
|
6
|
+
return (_jsxs("div", { className: cn('group/native-select relative w-fit has-[select:disabled]:opacity-50', className), "data-slot": "native-select-wrapper", "data-size": size, children: [_jsx("select", { "data-slot": "native-select", "data-size": size, className: "h-7 w-full min-w-0 appearance-none rounded-[min(var(--radius-md),10px)] border border-input bg-transparent py-0.5 pr-8 pl-2.5 text-sm transition-colors outline-none select-none selection:bg-primary selection:text-primary-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=sm]:h-6 data-[size=sm]:text-xs dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40", ...props }), _jsx(ChevronDown, { className: "pointer-events-none absolute top-1/2 right-2.5 size-4 -translate-y-1/2 text-muted-foreground select-none", "aria-hidden": "true", "data-slot": "native-select-icon" })] }));
|
|
7
7
|
}
|
|
8
8
|
function NativeSelectOption({ className, ...props }) {
|
|
9
9
|
return _jsx("option", { "data-slot": "native-select-option", className: cn('bg-[Canvas] text-[CanvasText]', className), ...props });
|