@moldable-ai/ui 0.2.20 → 0.2.21
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/catalog/catalog-coverage.d.ts +15 -0
- package/dist/catalog/catalog-coverage.d.ts.map +1 -0
- package/dist/catalog/catalog-coverage.js +44 -0
- package/dist/catalog/catalog-manifest.d.ts.map +1 -1
- package/dist/catalog/catalog-manifest.js +35 -23
- package/dist/catalog/catalog-types.d.ts +10 -0
- package/dist/catalog/catalog-types.d.ts.map +1 -1
- package/dist/catalog/catalog-types.js +6 -0
- package/dist/catalog/component-catalog.d.ts.map +1 -1
- package/dist/catalog/component-catalog.js +16 -6
- package/dist/catalog/core-catalog-exclusions.d.ts +8 -0
- package/dist/catalog/core-catalog-exclusions.d.ts.map +1 -0
- package/dist/catalog/core-catalog-exclusions.js +151 -0
- package/dist/catalog/core-catalog.d.ts +0 -4
- package/dist/catalog/core-catalog.d.ts.map +1 -1
- package/dist/catalog/core-catalog.js +12 -98
- package/dist/catalog/core-collection-stories.d.ts +3 -0
- package/dist/catalog/core-collection-stories.d.ts.map +1 -0
- package/dist/catalog/core-collection-stories.js +42 -0
- package/dist/catalog/core-control-stories.d.ts +3 -0
- package/dist/catalog/core-control-stories.d.ts.map +1 -0
- package/dist/catalog/core-control-stories.js +94 -0
- package/dist/catalog/core-feedback-stories.d.ts +3 -0
- package/dist/catalog/core-feedback-stories.d.ts.map +1 -0
- package/dist/catalog/core-feedback-stories.js +50 -0
- package/dist/catalog/core-foundation-stories.d.ts +3 -0
- package/dist/catalog/core-foundation-stories.d.ts.map +1 -0
- package/dist/catalog/core-foundation-stories.js +53 -0
- package/dist/catalog/core-navigation-stories.d.ts +3 -0
- package/dist/catalog/core-navigation-stories.d.ts.map +1 -0
- package/dist/catalog/core-navigation-stories.js +25 -0
- package/dist/catalog/core-overlay-stories.d.ts +3 -0
- package/dist/catalog/core-overlay-stories.d.ts.map +1 -0
- package/dist/catalog/core-overlay-stories.js +20 -0
- package/dist/catalog/index.d.ts +3 -1
- package/dist/catalog/index.d.ts.map +1 -1
- package/dist/catalog/index.js +3 -1
- package/dist/components/chat/chat-panel.d.ts +0 -1
- package/dist/components/chat/chat-panel.d.ts.map +1 -1
- package/dist/components/chat/chat-panel.js +7 -11
- package/dist/components/ui/alert-dialog.d.ts +7 -3
- package/dist/components/ui/alert-dialog.d.ts.map +1 -1
- package/dist/components/ui/alert-dialog.js +9 -5
- package/dist/components/ui/alert.d.ts +19 -3
- package/dist/components/ui/alert.d.ts.map +1 -1
- package/dist/components/ui/alert.js +25 -8
- package/dist/components/ui/app-frame.d.ts +9 -3
- package/dist/components/ui/app-frame.d.ts.map +1 -1
- package/dist/components/ui/app-frame.js +45 -6
- package/dist/components/ui/collapsible.d.ts +9 -1
- package/dist/components/ui/collapsible.d.ts.map +1 -1
- package/dist/components/ui/collapsible.js +13 -2
- package/dist/components/ui/collection-navigation.d.ts +8 -0
- package/dist/components/ui/collection-navigation.d.ts.map +1 -0
- package/dist/components/ui/collection-navigation.js +19 -0
- package/dist/components/ui/command.d.ts +5 -1
- package/dist/components/ui/command.d.ts.map +1 -1
- package/dist/components/ui/command.js +13 -1
- package/dist/components/ui/confirm-dialog.d.ts +19 -0
- package/dist/components/ui/confirm-dialog.d.ts.map +1 -0
- package/dist/components/ui/confirm-dialog.js +45 -0
- package/dist/components/ui/date-picker.d.ts +24 -0
- package/dist/components/ui/date-picker.d.ts.map +1 -0
- package/dist/components/ui/date-picker.js +92 -0
- package/dist/components/ui/dialog.d.ts +4 -2
- package/dist/components/ui/dialog.d.ts.map +1 -1
- package/dist/components/ui/dialog.js +8 -5
- package/dist/components/ui/empty.d.ts +7 -2
- package/dist/components/ui/empty.d.ts.map +1 -1
- package/dist/components/ui/empty.js +20 -7
- package/dist/components/ui/grid.d.ts.map +1 -1
- package/dist/components/ui/grid.js +70 -46
- package/dist/components/ui/index.d.ts +4 -0
- package/dist/components/ui/index.d.ts.map +1 -1
- package/dist/components/ui/index.js +4 -0
- package/dist/components/ui/list.d.ts +5 -1
- package/dist/components/ui/list.d.ts.map +1 -1
- package/dist/components/ui/list.js +27 -16
- package/dist/components/ui/material.d.ts +34 -0
- package/dist/components/ui/material.d.ts.map +1 -0
- package/dist/components/ui/material.js +34 -0
- package/dist/components/ui/message-scroller-controller.d.ts +162 -0
- package/dist/components/ui/message-scroller-controller.d.ts.map +1 -0
- package/dist/components/ui/message-scroller-controller.js +888 -0
- package/dist/components/ui/message-scroller-policy.d.ts +74 -0
- package/dist/components/ui/message-scroller-policy.d.ts.map +1 -0
- package/dist/components/ui/message-scroller-policy.js +129 -0
- package/dist/components/ui/message-scroller-primitive.d.ts +55 -0
- package/dist/components/ui/message-scroller-primitive.d.ts.map +1 -0
- package/dist/components/ui/message-scroller-primitive.js +226 -0
- package/dist/components/ui/message-scroller.d.ts +2 -2
- package/dist/components/ui/message-scroller.d.ts.map +1 -1
- package/dist/components/ui/message-scroller.js +3 -15
- package/dist/components/ui/navigation-button-group.d.ts +16 -0
- package/dist/components/ui/navigation-button-group.d.ts.map +1 -0
- package/dist/components/ui/navigation-button-group.js +9 -0
- package/dist/components/ui/popover.d.ts +9 -2
- package/dist/components/ui/popover.d.ts.map +1 -1
- package/dist/components/ui/popover.js +13 -3
- package/dist/components/ui/scroll-area.d.ts +8 -2
- package/dist/components/ui/scroll-area.d.ts.map +1 -1
- package/dist/components/ui/scroll-area.js +6 -3
- package/dist/components/ui/search-field.d.ts.map +1 -1
- package/dist/components/ui/segmented-control.d.ts.map +1 -1
- package/dist/components/ui/segmented-control.js +6 -5
- package/dist/components/ui/sheet.d.ts +4 -2
- package/dist/components/ui/sheet.d.ts.map +1 -1
- package/dist/components/ui/sheet.js +12 -9
- package/dist/components/ui/sonner.d.ts +1 -1
- package/dist/components/ui/sonner.d.ts.map +1 -1
- package/dist/components/ui/table.d.ts.map +1 -1
- package/dist/components/ui/table.js +7 -2
- package/dist/components/ui/toggle.d.ts +12 -4
- package/dist/components/ui/toggle.d.ts.map +1 -1
- package/dist/components/ui/toggle.js +13 -2
- package/dist/components/ui/toolbar.d.ts +9 -2
- package/dist/components/ui/toolbar.d.ts.map +1 -1
- package/dist/components/ui/toolbar.js +23 -4
- package/dist/components/ui/tooltip.d.ts +8 -3
- package/dist/components/ui/tooltip.d.ts.map +1 -1
- package/dist/components/ui/tooltip.js +11 -6
- package/dist/lib/frame-lifecycle.d.ts +1 -0
- package/dist/lib/frame-lifecycle.d.ts.map +1 -1
- package/dist/lib/frame-lifecycle.js +3 -2
- package/dist/lib/theme.d.ts.map +1 -1
- package/dist/lib/theme.js +2 -1
- package/docs/README.md +3 -1
- package/docs/adaptive-materials.md +79 -0
- package/docs/app-anatomy.md +3 -1
- package/docs/component-catalog.md +26 -3
- package/docs/design-tokens.md +17 -4
- package/docs/foundations.md +5 -3
- package/docs/standalone-app-windows.md +8 -0
- package/package.json +1 -2
- package/src/components/ui/alert-dialog.md +31 -0
- package/src/components/ui/alert.md +28 -6
- package/src/components/ui/app-frame.md +5 -0
- package/src/components/ui/collapsible.md +52 -0
- package/src/components/ui/combobox.md +0 -1
- package/src/components/ui/command.md +54 -0
- package/src/components/ui/date-field.md +1 -1
- package/src/components/ui/date-picker.md +55 -0
- package/src/components/ui/dialog.md +40 -0
- package/src/components/ui/empty.md +8 -3
- package/src/components/ui/grid.md +8 -4
- package/src/components/ui/icon-button.md +2 -2
- package/src/components/ui/list.md +35 -2
- package/src/components/ui/material.md +51 -0
- package/src/components/ui/navigation-button-group.md +46 -0
- package/src/components/ui/popover.md +31 -0
- package/src/components/ui/scroll-area.md +11 -7
- package/src/components/ui/search-field.md +1 -1
- package/src/components/ui/segmented-control.md +2 -5
- package/src/components/ui/sheet.md +30 -0
- package/src/components/ui/table.md +4 -2
- package/src/components/ui/toggle-button.md +48 -0
- package/src/components/ui/toolbar.md +5 -0
- package/src/components/ui/tooltip.md +31 -0
- package/src/styles/index.css +213 -0
|
@@ -2,11 +2,24 @@
|
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import { cn } from '../../lib/utils';
|
|
4
4
|
import { cva } from 'class-variance-authority';
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
const emptyVariants = cva('group/empty flex min-w-0 flex-col items-center justify-center text-balance text-center', {
|
|
6
|
+
variants: {
|
|
7
|
+
variant: {
|
|
8
|
+
compact: 'gap-3 p-4',
|
|
9
|
+
pane: 'flex-1 gap-4 p-6',
|
|
10
|
+
full: 'min-h-full flex-1 gap-6 p-8 md:p-10',
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
defaultVariants: {
|
|
14
|
+
variant: 'pane',
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
function Empty({ className, safeBottom = false, variant = 'pane', ...props }) {
|
|
18
|
+
return (_jsx("div", { "data-slot": "empty", "data-safe-bottom": safeBottom || undefined, "data-variant": variant, className: cn(emptyVariants({ variant }), safeBottom &&
|
|
19
|
+
'pb-[calc(var(--chat-safe-padding,0px)+var(--density-pane-padding))]', className), ...props }));
|
|
7
20
|
}
|
|
8
21
|
function EmptyHeader({ className, ...props }) {
|
|
9
|
-
return (_jsx("div", { "data-slot": "empty-header", className: cn('flex max-w-sm flex-col items-center gap-2 text-center', className), ...props }));
|
|
22
|
+
return (_jsx("div", { "data-slot": "empty-header", className: cn('flex max-w-sm flex-col items-center gap-2 text-center group-data-[variant=compact]/empty:gap-1.5', className), ...props }));
|
|
10
23
|
}
|
|
11
24
|
const emptyMediaVariants = cva('flex shrink-0 items-center justify-center mb-2 [&_svg]:pointer-events-none [&_svg]:shrink-0', {
|
|
12
25
|
variants: {
|
|
@@ -23,12 +36,12 @@ function EmptyMedia({ className, variant = 'default', ...props }) {
|
|
|
23
36
|
return (_jsx("div", { "data-slot": "empty-icon", "data-variant": variant, className: cn(emptyMediaVariants({ variant, className })), ...props }));
|
|
24
37
|
}
|
|
25
38
|
function EmptyTitle({ className, ...props }) {
|
|
26
|
-
return (_jsx("div", { "data-slot": "empty-title", className: cn('
|
|
39
|
+
return (_jsx("div", { "data-slot": "empty-title", className: cn('font-medium tracking-tight group-data-[variant=compact]/empty:text-sm group-data-[variant=full]/empty:text-lg group-data-[variant=pane]/empty:text-base', className), ...props }));
|
|
27
40
|
}
|
|
28
41
|
function EmptyDescription({ className, ...props }) {
|
|
29
|
-
return (_jsx("p", { "data-slot": "empty-description", className: cn('text-muted-foreground [&>a:hover]:text-primary text-sm/relaxed [&>a]:underline [&>a]:underline-offset-4', className), ...props }));
|
|
42
|
+
return (_jsx("p", { "data-slot": "empty-description", className: cn('text-muted-foreground [&>a:hover]:text-primary text-sm/relaxed group-data-[variant=compact]/empty:text-xs/relaxed [&>a]:underline [&>a]:underline-offset-4', className), ...props }));
|
|
30
43
|
}
|
|
31
44
|
function EmptyContent({ className, ...props }) {
|
|
32
|
-
return (_jsx("div", { "data-slot": "empty-content", className: cn('flex w-full min-w-0 max-w-sm flex-col items-center gap-
|
|
45
|
+
return (_jsx("div", { "data-slot": "empty-content", className: cn('flex w-full min-w-0 max-w-sm flex-col items-center gap-3 text-balance text-sm group-data-[variant=compact]/empty:gap-2', className), ...props }));
|
|
33
46
|
}
|
|
34
|
-
export { Empty, EmptyHeader, EmptyTitle, EmptyDescription, EmptyContent, EmptyMedia, };
|
|
47
|
+
export { Empty, EmptyHeader, EmptyTitle, EmptyDescription, EmptyContent, EmptyMedia, emptyVariants, };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grid.d.ts","sourceRoot":"","sources":["../../../src/components/ui/grid.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"grid.d.ts","sourceRoot":"","sources":["../../../src/components/ui/grid.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAO9B,KAAK,iBAAiB,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAA;AAuCvD,KAAK,SAAS,GAAG,IAAI,CACnB,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAC3B,cAAc,GAAG,UAAU,CAC5B,GAAG;IACF,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,aAAa,CAAC,EAAE,iBAAiB,CAAA;IACjC,cAAc,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;IACjC,qBAAqB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;IACxC,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,KAAK,IAAI,CAAA;IACzD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,iBAAS,IAAI,CAAC,EACZ,SAAS,EACT,QAAQ,EACR,OAAW,EACX,aAAsB,EACtB,cAAc,EACd,qBAAqB,EACrB,iBAAiB,EACjB,QAAQ,EACR,IAAY,EACZ,QAAgB,EAChB,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,SAAS,2CAsRX;AAED,KAAK,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,GAAG;IAChE,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,iBAAS,QAAQ,CAAC,EAChB,SAAS,EACT,QAAQ,EACR,KAAK,EACL,QAAgB,EAChB,OAAO,EACP,aAAa,EACb,OAAO,EACP,GAAG,EACH,GAAG,KAAK,EACT,EAAE,aAAa,2CA4Ef;AAED,iBAAS,aAAa,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAW1E;AAED,iBAAS,eAAe,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAQ5E;AAED,iBAAS,aAAa,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAQ1E;AAED,iBAAS,mBAAmB,CAAC,EAC3B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,2CAQ3B;AAED,OAAO,EACL,IAAI,EACJ,QAAQ,EACR,eAAe,EACf,mBAAmB,EACnB,aAAa,EACb,aAAa,EACb,KAAK,SAAS,EACd,KAAK,iBAAiB,GACvB,CAAA"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { cn } from '../../lib/utils';
|
|
5
|
+
import { getCollectionItemsInDomOrder, isInteractiveDescendant, } from './collection-navigation';
|
|
5
6
|
const GridContext = React.createContext(null);
|
|
6
7
|
function useGridContext(component) {
|
|
7
8
|
const context = React.useContext(GridContext);
|
|
@@ -22,11 +23,6 @@ function sameSelection(a, b) {
|
|
|
22
23
|
}
|
|
23
24
|
return true;
|
|
24
25
|
}
|
|
25
|
-
function isInteractiveDescendant(target, currentTarget) {
|
|
26
|
-
if (!(target instanceof HTMLElement) || target === currentTarget)
|
|
27
|
-
return false;
|
|
28
|
-
return Boolean(target.closest('a,button,input,select,textarea,[contenteditable="true"],[role="button"],[role="link"]'));
|
|
29
|
-
}
|
|
30
26
|
function Grid({ className, children, columns = 1, selectionMode = 'none', selectedValues, defaultSelectedValues, onSelectionChange, onAction, loop = false, disabled = false, onKeyDown, style, ref, ...props }) {
|
|
31
27
|
const itemsRef = React.useRef(new Map());
|
|
32
28
|
const [activeValue, setActiveValueState] = React.useState(null);
|
|
@@ -40,18 +36,21 @@ function Grid({ className, children, columns = 1, selectionMode = 'none', select
|
|
|
40
36
|
if (!node)
|
|
41
37
|
return () => undefined;
|
|
42
38
|
itemsRef.current.set(value, { node, disabled: itemDisabled });
|
|
43
|
-
if (!disabled && !itemDisabled) {
|
|
44
|
-
setActiveValueState((current) => current ?? value);
|
|
45
|
-
}
|
|
46
39
|
return () => {
|
|
47
40
|
itemsRef.current.delete(value);
|
|
48
|
-
setActiveValueState((current) =>
|
|
49
|
-
if (current !== value)
|
|
50
|
-
return current;
|
|
51
|
-
return ([...itemsRef.current.entries()].find(([, item]) => !disabled && !item.disabled)?.[0] ?? null);
|
|
52
|
-
});
|
|
41
|
+
setActiveValueState((current) => (current === value ? null : current));
|
|
53
42
|
};
|
|
54
|
-
}, [
|
|
43
|
+
}, []);
|
|
44
|
+
React.useLayoutEffect(() => {
|
|
45
|
+
const items = getCollectionItemsInDomOrder(itemsRef.current).filter(([, item]) => !disabled && !item.disabled);
|
|
46
|
+
setActiveValueState((current) => {
|
|
47
|
+
if (current && items.some(([value]) => value === current))
|
|
48
|
+
return current;
|
|
49
|
+
return (items.find(([value]) => selection.has(value))?.[0] ??
|
|
50
|
+
items[0]?.[0] ??
|
|
51
|
+
null);
|
|
52
|
+
});
|
|
53
|
+
}, [children, disabled, selection]);
|
|
55
54
|
const setActiveValue = React.useCallback((value) => {
|
|
56
55
|
const item = itemsRef.current.get(value);
|
|
57
56
|
if (item && !item.disabled)
|
|
@@ -86,41 +85,61 @@ function Grid({ className, children, columns = 1, selectionMode = 'none', select
|
|
|
86
85
|
return;
|
|
87
86
|
onAction?.(value);
|
|
88
87
|
}, [disabled, onAction]);
|
|
89
|
-
const moveFocus = React.useCallback((
|
|
90
|
-
const entries =
|
|
88
|
+
const moveFocus = React.useCallback((direction) => {
|
|
89
|
+
const entries = getCollectionItemsInDomOrder(itemsRef.current);
|
|
91
90
|
if (entries.length === 0)
|
|
92
91
|
return;
|
|
93
92
|
const currentIndex = entries.findIndex(([value]) => value === activeValue);
|
|
94
93
|
const enabledAt = (index) => entries[index] && !disabled && !entries[index][1].disabled;
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
94
|
+
const startIndex = currentIndex < 0 ? 0 : currentIndex;
|
|
95
|
+
const currentRow = Math.floor(startIndex / safeColumns);
|
|
96
|
+
const currentColumn = startIndex % safeColumns;
|
|
97
|
+
const rowStart = currentRow * safeColumns;
|
|
98
|
+
const rowEnd = Math.min(entries.length - 1, rowStart + safeColumns - 1);
|
|
99
|
+
let candidates = [];
|
|
100
|
+
if (direction === 'first') {
|
|
101
|
+
candidates = Array.from({ length: entries.length }, (_, index) => index);
|
|
103
102
|
}
|
|
104
|
-
else {
|
|
105
|
-
|
|
103
|
+
else if (direction === 'last') {
|
|
104
|
+
candidates = Array.from({ length: entries.length }, (_, index) => entries.length - index - 1);
|
|
105
|
+
}
|
|
106
|
+
else if (direction === 'row-first') {
|
|
107
|
+
candidates = Array.from({ length: rowEnd - rowStart + 1 }, (_, index) => rowStart + index);
|
|
106
108
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
109
|
+
else if (direction === 'row-last') {
|
|
110
|
+
candidates = Array.from({ length: rowEnd - rowStart + 1 }, (_, index) => rowEnd - index);
|
|
111
|
+
}
|
|
112
|
+
else if (direction === 'left' || direction === 'right') {
|
|
113
|
+
const step = direction === 'left' ? -1 : 1;
|
|
114
|
+
for (let index = startIndex + step; index >= rowStart && index <= rowEnd; index += step) {
|
|
115
|
+
candidates.push(index);
|
|
114
116
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
+
if (loop && candidates.length === 0) {
|
|
118
|
+
candidates =
|
|
119
|
+
direction === 'left'
|
|
120
|
+
? Array.from({ length: entries.length }, (_, index) => (startIndex - index - 1 + entries.length) % entries.length)
|
|
121
|
+
: Array.from({ length: entries.length }, (_, index) => (startIndex + index + 1) % entries.length);
|
|
117
122
|
}
|
|
118
|
-
attempts += 1;
|
|
119
123
|
}
|
|
124
|
+
else {
|
|
125
|
+
const step = direction === 'up' ? -safeColumns : safeColumns;
|
|
126
|
+
for (let index = startIndex + step; index >= 0 && index < entries.length; index += step) {
|
|
127
|
+
candidates.push(index);
|
|
128
|
+
}
|
|
129
|
+
if (loop && candidates.length === 0) {
|
|
130
|
+
const sameColumn = entries
|
|
131
|
+
.map((_, index) => index)
|
|
132
|
+
.filter((index) => index % safeColumns === currentColumn);
|
|
133
|
+
candidates = direction === 'up' ? sameColumn.reverse() : sameColumn;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const nextIndex = candidates.find(enabledAt);
|
|
137
|
+
if (nextIndex === undefined || nextIndex === currentIndex)
|
|
138
|
+
return;
|
|
120
139
|
const [value, item] = entries[nextIndex];
|
|
121
140
|
setActiveValueState(value);
|
|
122
141
|
item.node.focus();
|
|
123
|
-
}, [activeValue, disabled, loop]);
|
|
142
|
+
}, [activeValue, disabled, loop, safeColumns]);
|
|
124
143
|
const handleKeyDown = (event) => {
|
|
125
144
|
onKeyDown?.(event);
|
|
126
145
|
if (event.defaultPrevented || disabled)
|
|
@@ -129,19 +148,24 @@ function Grid({ className, children, columns = 1, selectionMode = 'none', select
|
|
|
129
148
|
if (target.dataset.slot !== 'grid-item')
|
|
130
149
|
return;
|
|
131
150
|
const movement = {
|
|
132
|
-
ArrowLeft:
|
|
133
|
-
ArrowRight:
|
|
134
|
-
ArrowUp:
|
|
135
|
-
ArrowDown:
|
|
151
|
+
ArrowLeft: 'left',
|
|
152
|
+
ArrowRight: 'right',
|
|
153
|
+
ArrowUp: 'up',
|
|
154
|
+
ArrowDown: 'down',
|
|
136
155
|
};
|
|
137
|
-
const
|
|
138
|
-
if (
|
|
156
|
+
const direction = movement[event.key];
|
|
157
|
+
if (direction !== undefined) {
|
|
139
158
|
event.preventDefault();
|
|
140
|
-
moveFocus(
|
|
159
|
+
moveFocus(direction);
|
|
141
160
|
}
|
|
142
161
|
else if (event.key === 'Home' || event.key === 'End') {
|
|
143
162
|
event.preventDefault();
|
|
144
|
-
|
|
163
|
+
if (event.ctrlKey || event.metaKey) {
|
|
164
|
+
moveFocus(event.key === 'Home' ? 'first' : 'last');
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
moveFocus(event.key === 'Home' ? 'row-first' : 'row-last');
|
|
168
|
+
}
|
|
145
169
|
}
|
|
146
170
|
else if (event.key === ' ') {
|
|
147
171
|
event.preventDefault();
|
|
@@ -194,7 +218,7 @@ function GridItem({ className, children, value, disabled = false, onClick, onDou
|
|
|
194
218
|
ref.current = node;
|
|
195
219
|
}, [ref]);
|
|
196
220
|
React.useLayoutEffect(() => registerItem(value, itemRef.current, isDisabled), [isDisabled, registerItem, value]);
|
|
197
|
-
return (_jsx("div", { ref: setRef, role: "gridcell", tabIndex: isDisabled ? -1 : isActive ? 0 : -1, "aria-disabled": isDisabled || undefined, "aria-selected": context.selectionMode === 'none' ? undefined : isSelected, "data-slot": "grid-item", "data-active": isActive || undefined, "data-disabled": isDisabled || undefined, "data-selected": context.selectionMode === 'none' ? undefined : isSelected, "data-value": value, className: cn('group/grid-item relative min-w-0 cursor-default select-none overflow-hidden rounded-lg border
|
|
221
|
+
return (_jsx("div", { ref: setRef, role: "gridcell", tabIndex: isDisabled ? -1 : isActive ? 0 : -1, "aria-disabled": isDisabled || undefined, "aria-selected": context.selectionMode === 'none' ? undefined : isSelected, "data-slot": "grid-item", "data-active": isActive || undefined, "data-disabled": isDisabled || undefined, "data-selected": context.selectionMode === 'none' ? undefined : isSelected, "data-value": value, className: cn('group/grid-item border-border bg-card text-card-foreground relative min-w-0 cursor-default select-none overflow-hidden rounded-lg border outline-none transition-[background-color,border-color,box-shadow] duration-100', 'hover:bg-accent/40 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]', 'data-[selected=true]:border-ring data-[selected=true]:bg-accent/60', 'data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50', className), onClick: (event) => {
|
|
198
222
|
onClick?.(event);
|
|
199
223
|
if (event.defaultPrevented ||
|
|
200
224
|
isDisabled ||
|
|
@@ -17,11 +17,13 @@ export * from './collapsible';
|
|
|
17
17
|
export * from './color-well';
|
|
18
18
|
export * from './combobox';
|
|
19
19
|
export * from './command';
|
|
20
|
+
export * from './confirm-dialog';
|
|
20
21
|
export * from './context-menu';
|
|
21
22
|
export * from './dialog';
|
|
22
23
|
export * from './drawer';
|
|
23
24
|
export * from './dropdown-menu';
|
|
24
25
|
export * from './date-field';
|
|
26
|
+
export * from './date-picker';
|
|
25
27
|
export * from './empty';
|
|
26
28
|
export * from './edge-fade';
|
|
27
29
|
export * from './field';
|
|
@@ -38,8 +40,10 @@ export * from './kbd';
|
|
|
38
40
|
export * from './label';
|
|
39
41
|
export * from './list';
|
|
40
42
|
export * from './menubar';
|
|
43
|
+
export * from './material';
|
|
41
44
|
export * from './message-scroller';
|
|
42
45
|
export * from './navigation-menu';
|
|
46
|
+
export * from './navigation-button-group';
|
|
43
47
|
export * from './notification-dot';
|
|
44
48
|
export * from './number-input';
|
|
45
49
|
export * from './pagination';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/ui/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,SAAS,CAAA;AACvB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,cAAc,CAAA;AAC5B,cAAc,UAAU,CAAA;AACxB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,YAAY,CAAA;AAC1B,cAAc,QAAQ,CAAA;AACtB,cAAc,YAAY,CAAA;AAC1B,cAAc,SAAS,CAAA;AACvB,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,WAAW,CAAA;AACzB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,cAAc,CAAA;AAC5B,cAAc,SAAS,CAAA;AACvB,cAAc,aAAa,CAAA;AAC3B,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA;AACtB,cAAc,QAAQ,CAAA;AACtB,cAAc,cAAc,CAAA;AAC5B,cAAc,eAAe,CAAA;AAC7B,cAAc,SAAS,CAAA;AACvB,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,QAAQ,CAAA;AACtB,cAAc,OAAO,CAAA;AACrB,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA;AACtB,cAAc,WAAW,CAAA;AACzB,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA;AAClC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,cAAc,CAAA;AAC5B,cAAc,SAAS,CAAA;AACvB,cAAc,WAAW,CAAA;AACzB,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA;AACxB,cAAc,qBAAqB,CAAA;AACnC,cAAc,aAAa,CAAA;AAC3B,cAAc,SAAS,CAAA;AACvB,cAAc,WAAW,CAAA;AACzB,cAAc,YAAY,CAAA;AAC1B,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA;AACzB,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA;AACtB,cAAc,YAAY,CAAA;AAC1B,cAAc,QAAQ,CAAA;AACtB,cAAc,UAAU,CAAA;AACxB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/ui/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,SAAS,CAAA;AACvB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,cAAc,CAAA;AAC5B,cAAc,UAAU,CAAA;AACxB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,YAAY,CAAA;AAC1B,cAAc,QAAQ,CAAA;AACtB,cAAc,YAAY,CAAA;AAC1B,cAAc,SAAS,CAAA;AACvB,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,WAAW,CAAA;AACzB,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,cAAc,CAAA;AAC5B,cAAc,eAAe,CAAA;AAC7B,cAAc,SAAS,CAAA;AACvB,cAAc,aAAa,CAAA;AAC3B,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA;AACtB,cAAc,QAAQ,CAAA;AACtB,cAAc,cAAc,CAAA;AAC5B,cAAc,eAAe,CAAA;AAC7B,cAAc,SAAS,CAAA;AACvB,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,QAAQ,CAAA;AACtB,cAAc,OAAO,CAAA;AACrB,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA;AACtB,cAAc,WAAW,CAAA;AACzB,cAAc,YAAY,CAAA;AAC1B,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,2BAA2B,CAAA;AACzC,cAAc,oBAAoB,CAAA;AAClC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,cAAc,CAAA;AAC5B,cAAc,SAAS,CAAA;AACvB,cAAc,WAAW,CAAA;AACzB,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA;AACxB,cAAc,qBAAqB,CAAA;AACnC,cAAc,aAAa,CAAA;AAC3B,cAAc,SAAS,CAAA;AACvB,cAAc,WAAW,CAAA;AACzB,cAAc,YAAY,CAAA;AAC1B,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA;AACzB,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA;AACtB,cAAc,YAAY,CAAA;AAC1B,cAAc,QAAQ,CAAA;AACtB,cAAc,UAAU,CAAA;AACxB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA"}
|
|
@@ -17,11 +17,13 @@ export * from './collapsible';
|
|
|
17
17
|
export * from './color-well';
|
|
18
18
|
export * from './combobox';
|
|
19
19
|
export * from './command';
|
|
20
|
+
export * from './confirm-dialog';
|
|
20
21
|
export * from './context-menu';
|
|
21
22
|
export * from './dialog';
|
|
22
23
|
export * from './drawer';
|
|
23
24
|
export * from './dropdown-menu';
|
|
24
25
|
export * from './date-field';
|
|
26
|
+
export * from './date-picker';
|
|
25
27
|
export * from './empty';
|
|
26
28
|
export * from './edge-fade';
|
|
27
29
|
export * from './field';
|
|
@@ -38,8 +40,10 @@ export * from './kbd';
|
|
|
38
40
|
export * from './label';
|
|
39
41
|
export * from './list';
|
|
40
42
|
export * from './menubar';
|
|
43
|
+
export * from './material';
|
|
41
44
|
export * from './message-scroller';
|
|
42
45
|
export * from './navigation-menu';
|
|
46
|
+
export * from './navigation-button-group';
|
|
43
47
|
export * from './notification-dot';
|
|
44
48
|
export * from './number-input';
|
|
45
49
|
export * from './pagination';
|
|
@@ -11,6 +11,10 @@ type ListProps = Omit<React.ComponentProps<'div'>, 'defaultValue' | 'onChange'>
|
|
|
11
11
|
disabled?: boolean;
|
|
12
12
|
};
|
|
13
13
|
declare function List({ className, children, selectionMode, selectedValues, defaultSelectedValues, onSelectionChange, onAction, orientation, loop, disabled, role, onKeyDown, ref, ...props }: ListProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
type ListSectionProps = Omit<React.ComponentProps<'div'>, 'role'>;
|
|
15
|
+
declare function ListSection({ className, children, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, ...props }: ListSectionProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
type ListSectionHeaderProps = Omit<React.ComponentProps<'div'>, 'id'>;
|
|
17
|
+
declare function ListSectionHeader({ className, ...props }: ListSectionHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
14
18
|
type ListItemProps = Omit<React.ComponentProps<'div'>, 'value'> & {
|
|
15
19
|
value: string;
|
|
16
20
|
disabled?: boolean;
|
|
@@ -20,5 +24,5 @@ declare function ListItemContent({ className, ...props }: React.ComponentProps<'
|
|
|
20
24
|
declare function ListItemTitle({ className, ...props }: React.ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
|
|
21
25
|
declare function ListItemDescription({ className, ...props }: React.ComponentProps<'p'>): import("react/jsx-runtime").JSX.Element;
|
|
22
26
|
declare function ListItemActions({ className, ...props }: React.ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
|
|
23
|
-
export { List, ListItem, ListItemActions, ListItemContent, ListItemDescription, ListItemTitle, type ListProps, type ListSelectionMode, };
|
|
27
|
+
export { List, ListItem, ListItemActions, ListItemContent, ListItemDescription, ListItemTitle, ListSection, ListSectionHeader, type ListProps, type ListSectionHeaderProps, type ListSectionProps, type ListSelectionMode, };
|
|
24
28
|
//# sourceMappingURL=list.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/components/ui/list.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/components/ui/list.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAO9B,KAAK,iBAAiB,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAA;AA+CvD,KAAK,SAAS,GAAG,IAAI,CACnB,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAC3B,cAAc,GAAG,UAAU,CAC5B,GAAG;IACF,aAAa,CAAC,EAAE,iBAAiB,CAAA;IACjC,cAAc,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;IACjC,qBAAqB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;IACxC,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,KAAK,IAAI,CAAA;IACzD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAA;IACvC,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,iBAAS,IAAI,CAAC,EACZ,SAAS,EACT,QAAQ,EACR,aAAsB,EACtB,cAAc,EACd,qBAAqB,EACrB,iBAAiB,EACjB,QAAQ,EACR,WAAwB,EACxB,IAAY,EACZ,QAAgB,EAChB,IAAI,EACJ,SAAS,EACT,GAAG,EACH,GAAG,KAAK,EACT,EAAE,SAAS,2CAoMX;AAED,KAAK,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAA;AAEjE,iBAAS,WAAW,CAAC,EACnB,SAAS,EACT,QAAQ,EACR,YAAY,EAAE,SAAS,EACvB,iBAAiB,EAAE,cAAc,EACjC,GAAG,KAAK,EACT,EAAE,gBAAgB,2CAiBlB;AAED,KAAK,sBAAsB,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAA;AAErE,iBAAS,iBAAiB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,sBAAsB,2CAiBzE;AAED,KAAK,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,GAAG;IAChE,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,iBAAS,QAAQ,CAAC,EAChB,SAAS,EACT,QAAQ,EACR,KAAK,EACL,QAAgB,EAChB,OAAO,EACP,aAAa,EACb,OAAO,EACP,GAAG,EACH,IAAI,EACJ,GAAG,KAAK,EACT,EAAE,aAAa,2CA+Ef;AAED,iBAAS,eAAe,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAQ5E;AAED,iBAAS,aAAa,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAQ1E;AAED,iBAAS,mBAAmB,CAAC,EAC3B,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,2CAQ3B;AAED,iBAAS,eAAe,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,2CAQ5E;AAED,OAAO,EACL,IAAI,EACJ,QAAQ,EACR,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,KAAK,SAAS,EACd,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,GACvB,CAAA"}
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { cn } from '../../lib/utils';
|
|
5
|
+
import { getCollectionItemsInDomOrder, isInteractiveDescendant, } from './collection-navigation';
|
|
5
6
|
const ListContext = React.createContext(null);
|
|
7
|
+
const ListSectionContext = React.createContext(null);
|
|
6
8
|
function useListContext(component) {
|
|
7
9
|
const context = React.useContext(ListContext);
|
|
8
10
|
if (!context) {
|
|
@@ -22,11 +24,6 @@ function sameSelection(a, b) {
|
|
|
22
24
|
}
|
|
23
25
|
return true;
|
|
24
26
|
}
|
|
25
|
-
function isInteractiveDescendant(target, currentTarget) {
|
|
26
|
-
if (!(target instanceof HTMLElement) || target === currentTarget)
|
|
27
|
-
return false;
|
|
28
|
-
return Boolean(target.closest('a,button,input,select,textarea,[contenteditable="true"],[role="button"],[role="link"]'));
|
|
29
|
-
}
|
|
30
27
|
function List({ className, children, selectionMode = 'none', selectedValues, defaultSelectedValues, onSelectionChange, onAction, orientation = 'vertical', loop = false, disabled = false, role, onKeyDown, ref, ...props }) {
|
|
31
28
|
const rootRef = React.useRef(null);
|
|
32
29
|
const itemsRef = React.useRef(new Map());
|
|
@@ -45,18 +42,21 @@ function List({ className, children, selectionMode = 'none', selectedValues, def
|
|
|
45
42
|
if (!node)
|
|
46
43
|
return () => undefined;
|
|
47
44
|
itemsRef.current.set(value, { node, disabled: itemDisabled });
|
|
48
|
-
if (!disabled && !itemDisabled) {
|
|
49
|
-
setActiveValueState((current) => current ?? value);
|
|
50
|
-
}
|
|
51
45
|
return () => {
|
|
52
46
|
itemsRef.current.delete(value);
|
|
53
|
-
setActiveValueState((current) =>
|
|
54
|
-
if (current !== value)
|
|
55
|
-
return current;
|
|
56
|
-
return ([...itemsRef.current.entries()].find(([, item]) => !disabled && !item.disabled)?.[0] ?? null);
|
|
57
|
-
});
|
|
47
|
+
setActiveValueState((current) => (current === value ? null : current));
|
|
58
48
|
};
|
|
59
|
-
}, [
|
|
49
|
+
}, []);
|
|
50
|
+
React.useLayoutEffect(() => {
|
|
51
|
+
const items = getCollectionItemsInDomOrder(itemsRef.current).filter(([, item]) => !disabled && !item.disabled);
|
|
52
|
+
setActiveValueState((current) => {
|
|
53
|
+
if (current && items.some(([value]) => value === current))
|
|
54
|
+
return current;
|
|
55
|
+
return (items.find(([value]) => selection.has(value))?.[0] ??
|
|
56
|
+
items[0]?.[0] ??
|
|
57
|
+
null);
|
|
58
|
+
});
|
|
59
|
+
}, [children, disabled, selection]);
|
|
60
60
|
const setActiveValue = React.useCallback((value) => {
|
|
61
61
|
const item = itemsRef.current.get(value);
|
|
62
62
|
if (item && !item.disabled)
|
|
@@ -92,7 +92,7 @@ function List({ className, children, selectionMode = 'none', selectedValues, def
|
|
|
92
92
|
onAction?.(value);
|
|
93
93
|
}, [disabled, onAction]);
|
|
94
94
|
const moveFocus = React.useCallback((direction) => {
|
|
95
|
-
const items =
|
|
95
|
+
const items = getCollectionItemsInDomOrder(itemsRef.current).filter(([, item]) => !disabled && !item.disabled);
|
|
96
96
|
if (items.length === 0)
|
|
97
97
|
return;
|
|
98
98
|
const currentIndex = items.findIndex(([value]) => value === activeValue);
|
|
@@ -168,6 +168,17 @@ function List({ className, children, selectionMode = 'none', selectedValues, def
|
|
|
168
168
|
? 'flex-col gap-0.5'
|
|
169
169
|
: 'flex-row items-center gap-1', className), onKeyDown: handleKeyDown, ...props, children: children }) }));
|
|
170
170
|
}
|
|
171
|
+
function ListSection({ className, children, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, ...props }) {
|
|
172
|
+
const headerId = React.useId();
|
|
173
|
+
return (_jsx(ListSectionContext.Provider, { value: { headerId }, children: _jsx("div", { role: "group", "aria-label": ariaLabel, "aria-labelledby": ariaLabel ? undefined : (ariaLabelledBy ?? headerId), "data-slot": "list-section", className: cn('flex min-w-0 flex-col gap-0.5', className), ...props, children: children }) }));
|
|
174
|
+
}
|
|
175
|
+
function ListSectionHeader({ className, ...props }) {
|
|
176
|
+
const context = React.useContext(ListSectionContext);
|
|
177
|
+
if (!context) {
|
|
178
|
+
throw new Error('ListSectionHeader must be used inside ListSection');
|
|
179
|
+
}
|
|
180
|
+
return (_jsx("div", { id: context.headerId, "data-slot": "list-section-header", className: cn('text-muted-foreground px-2.5 py-1 text-xs font-medium', className), ...props }));
|
|
181
|
+
}
|
|
171
182
|
function ListItem({ className, children, value, disabled = false, onClick, onDoubleClick, onFocus, ref, role, ...props }) {
|
|
172
183
|
const context = useListContext('ListItem');
|
|
173
184
|
const { registerItem } = context;
|
|
@@ -221,4 +232,4 @@ function ListItemDescription({ className, ...props }) {
|
|
|
221
232
|
function ListItemActions({ className, ...props }) {
|
|
222
233
|
return (_jsx("div", { "data-slot": "list-item-actions", className: cn('ml-auto flex shrink-0 items-center gap-1', className), ...props }));
|
|
223
234
|
}
|
|
224
|
-
export { List, ListItem, ListItemActions, ListItemContent, ListItemDescription, ListItemTitle, };
|
|
235
|
+
export { List, ListItem, ListItemActions, ListItemContent, ListItemDescription, ListItemTitle, ListSection, ListSectionHeader, };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type VariantProps } from 'class-variance-authority';
|
|
3
|
+
declare const materialVariants: (props?: ({
|
|
4
|
+
shape?: "circle" | "rounded" | "capsule" | null | undefined;
|
|
5
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
6
|
+
export type MaterialVariant = 'regular' | 'clear';
|
|
7
|
+
export type MaterialShape = NonNullable<VariantProps<typeof materialVariants>['shape']>;
|
|
8
|
+
export type MaterialElevation = 'none' | 'panel' | 'overlay';
|
|
9
|
+
export interface MaterialProps extends React.ComponentPropsWithoutRef<'div'>, VariantProps<typeof materialVariants> {
|
|
10
|
+
/**
|
|
11
|
+
* `regular` is the default for toolbars and control chrome. Reserve `clear`
|
|
12
|
+
* for compact controls floating above media or a richly colored canvas.
|
|
13
|
+
*/
|
|
14
|
+
variant?: MaterialVariant;
|
|
15
|
+
elevation?: MaterialElevation;
|
|
16
|
+
interactive?: boolean;
|
|
17
|
+
asChild?: boolean;
|
|
18
|
+
}
|
|
19
|
+
declare function Material({ asChild, className, elevation, interactive, shape, variant, ...props }: MaterialProps): import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
declare const materialGroupSpacing: {
|
|
21
|
+
readonly compact: "gap-0.5 p-0.5";
|
|
22
|
+
readonly default: "gap-1 p-1";
|
|
23
|
+
readonly comfortable: "gap-1.5 p-1.5";
|
|
24
|
+
};
|
|
25
|
+
export interface MaterialGroupProps extends Omit<MaterialProps, 'asChild' | 'interactive'> {
|
|
26
|
+
spacing?: keyof typeof materialGroupSpacing;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* A single sampled material layer for a related control cluster. Children
|
|
30
|
+
* should be ordinary transparent or ghost controls, not nested Materials.
|
|
31
|
+
*/
|
|
32
|
+
declare function MaterialGroup({ className, spacing, ...props }: MaterialGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
33
|
+
export { Material, MaterialGroup, materialVariants };
|
|
34
|
+
//# sourceMappingURL=material.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"material.d.ts","sourceRoot":"","sources":["../../../src/components/ui/material.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAE,KAAK,YAAY,EAAO,MAAM,0BAA0B,CAAA;AAEjE,QAAA,MAAM,gBAAgB;;8EAWpB,CAAA;AAEF,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,OAAO,CAAA;AACjD,MAAM,MAAM,aAAa,GAAG,WAAW,CACrC,YAAY,CAAC,OAAO,gBAAgB,CAAC,CAAC,OAAO,CAAC,CAC/C,CAAA;AACD,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAA;AAE5D,MAAM,WAAW,aACf,SAAQ,KAAK,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAC3C,YAAY,CAAC,OAAO,gBAAgB,CAAC;IACvC;;;OAGG;IACH,OAAO,CAAC,EAAE,eAAe,CAAA;IACzB,SAAS,CAAC,EAAE,iBAAiB,CAAA;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,iBAAS,QAAQ,CAAC,EAChB,OAAe,EACf,SAAS,EACT,SAAmB,EACnB,WAAmB,EACnB,KAAK,EACL,OAAmB,EACnB,GAAG,KAAK,EACT,EAAE,aAAa,2CAcf;AAED,QAAA,MAAM,oBAAoB;;;;CAIhB,CAAA;AAEV,MAAM,WAAW,kBACf,SAAQ,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,aAAa,CAAC;IACtD,OAAO,CAAC,EAAE,MAAM,OAAO,oBAAoB,CAAA;CAC5C;AAED;;;GAGG;AACH,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,OAAmB,EACnB,GAAG,KAAK,EACT,EAAE,kBAAkB,2CAYpB;AAED,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,gBAAgB,EAAE,CAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
4
|
+
import { cn } from '../../lib/utils';
|
|
5
|
+
import { cva } from 'class-variance-authority';
|
|
6
|
+
const materialVariants = cva('moldable-material border text-inherit', {
|
|
7
|
+
variants: {
|
|
8
|
+
shape: {
|
|
9
|
+
rounded: 'rounded-overlay',
|
|
10
|
+
capsule: 'rounded-full',
|
|
11
|
+
circle: 'aspect-square rounded-full',
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
defaultVariants: {
|
|
15
|
+
shape: 'rounded',
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
function Material({ asChild = false, className, elevation = 'panel', interactive = false, shape, variant = 'regular', ...props }) {
|
|
19
|
+
const Comp = asChild ? Slot : 'div';
|
|
20
|
+
return (_jsx(Comp, { "data-slot": asChild ? undefined : 'material', "data-material": variant, "data-material-elevation": elevation, "data-material-interactive": interactive || undefined, "data-material-shape": shape ?? 'rounded', className: cn(materialVariants({ shape }), className), ...props }));
|
|
21
|
+
}
|
|
22
|
+
const materialGroupSpacing = {
|
|
23
|
+
compact: 'gap-0.5 p-0.5',
|
|
24
|
+
default: 'gap-1 p-1',
|
|
25
|
+
comfortable: 'gap-1.5 p-1.5',
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* A single sampled material layer for a related control cluster. Children
|
|
29
|
+
* should be ordinary transparent or ghost controls, not nested Materials.
|
|
30
|
+
*/
|
|
31
|
+
function MaterialGroup({ className, spacing = 'default', ...props }) {
|
|
32
|
+
return (_jsx(Material, { "data-slot": "material-group", className: cn('inline-flex min-w-0 items-center', materialGroupSpacing[spacing], className), ...props }));
|
|
33
|
+
}
|
|
34
|
+
export { Material, MaterialGroup, materialVariants };
|