@dxos/react-ui 0.7.5-main.499c70c → 0.7.5-main.6a330ac
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/lib/browser/index.mjs +290 -216
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +663 -592
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +290 -216
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/Avatars/Avatar.d.ts +6 -10
- package/dist/types/src/components/Avatars/Avatar.d.ts.map +1 -1
- package/dist/types/src/components/Avatars/Avatar.stories.d.ts +12 -13
- package/dist/types/src/components/Avatars/Avatar.stories.d.ts.map +1 -1
- package/dist/types/src/components/Avatars/AvatarGroup.d.ts +1 -1
- package/dist/types/src/components/Avatars/AvatarGroup.stories.d.ts +2 -2
- package/dist/types/src/components/Breadcrumb/Breadcrumb.d.ts +1 -1
- package/dist/types/src/components/Breadcrumb/Breadcrumb.stories.d.ts +3 -3
- package/dist/types/src/components/Buttons/Button.stories.d.ts +2 -2
- package/dist/types/src/components/Buttons/IconButton.d.ts +7 -2
- package/dist/types/src/components/Buttons/IconButton.d.ts.map +1 -1
- package/dist/types/src/components/Buttons/IconButton.stories.d.ts +2 -2
- package/dist/types/src/components/Buttons/Toggle.stories.d.ts +2 -2
- package/dist/types/src/components/Buttons/ToggleGroup.d.ts +4 -4
- package/dist/types/src/components/Buttons/ToggleGroup.stories.d.ts +6 -6
- package/dist/types/src/components/Clipboard/ClipboardProvider.d.ts +1 -1
- package/dist/types/src/components/Clipboard/ClipboardProvider.d.ts.map +1 -1
- package/dist/types/src/components/Clipboard/CopyButton.d.ts +6 -3
- package/dist/types/src/components/Clipboard/CopyButton.d.ts.map +1 -1
- package/dist/types/src/components/Clipboard/index.d.ts +8 -3
- package/dist/types/src/components/Clipboard/index.d.ts.map +1 -1
- package/dist/types/src/components/DensityProvider/DensityProvider.d.ts +1 -1
- package/dist/types/src/components/DensityProvider/DensityProvider.d.ts.map +1 -1
- package/dist/types/src/components/Dialogs/AlertDialog.d.ts +1 -1
- package/dist/types/src/components/Dialogs/AlertDialog.d.ts.map +1 -1
- package/dist/types/src/components/Dialogs/AlertDialog.stories.d.ts +2 -2
- package/dist/types/src/components/Dialogs/Dialog.d.ts +4 -2
- package/dist/types/src/components/Dialogs/Dialog.d.ts.map +1 -1
- package/dist/types/src/components/Dialogs/Dialog.stories.d.ts +2 -2
- package/dist/types/src/components/ElevationProvider/ElevationProvider.d.ts +1 -1
- package/dist/types/src/components/ElevationProvider/ElevationProvider.d.ts.map +1 -1
- package/dist/types/src/components/Icon/Icon.d.ts.map +1 -1
- package/dist/types/src/components/Input/Input.d.ts +1 -1
- package/dist/types/src/components/Input/Input.d.ts.map +1 -1
- package/dist/types/src/components/Input/Input.stories.d.ts +7 -7
- package/dist/types/src/components/Input/Input.stories.d.ts.map +1 -1
- package/dist/types/src/components/Lists/List.stories.d.ts +5 -5
- package/dist/types/src/components/Lists/ListDropIndicator.d.ts +3 -2
- package/dist/types/src/components/Lists/ListDropIndicator.d.ts.map +1 -1
- package/dist/types/src/components/Lists/Tree.stories.d.ts +3 -3
- package/dist/types/src/components/Lists/TreeDropIndicator.d.ts +1 -2
- package/dist/types/src/components/Lists/TreeDropIndicator.d.ts.map +1 -1
- package/dist/types/src/components/Lists/Treegrid.stories.d.ts +2 -2
- package/dist/types/src/components/Main/Main.d.ts +35 -24
- package/dist/types/src/components/Main/Main.d.ts.map +1 -1
- package/dist/types/src/components/Main/Main.stories.d.ts +3 -4
- package/dist/types/src/components/Main/Main.stories.d.ts.map +1 -1
- package/dist/types/src/components/Menus/ContextMenu.d.ts +6 -6
- package/dist/types/src/components/Menus/ContextMenu.d.ts.map +1 -1
- package/dist/types/src/components/Menus/ContextMenu.stories.d.ts +8 -8
- package/dist/types/src/components/Menus/DropdownMenu.d.ts +3 -7
- package/dist/types/src/components/Menus/DropdownMenu.d.ts.map +1 -1
- package/dist/types/src/components/Menus/DropdownMenu.stories.d.ts +4 -4
- package/dist/types/src/components/Message/Message.stories.d.ts +2 -2
- package/dist/types/src/components/Popover/Popover.d.ts +1 -1
- package/dist/types/src/components/Popover/Popover.d.ts.map +1 -1
- package/dist/types/src/components/Popover/Popover.stories.d.ts +5 -5
- package/dist/types/src/components/ScrollArea/ScrollArea.d.ts +5 -5
- package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts +7 -7
- package/dist/types/src/components/Select/Select.d.ts +9 -9
- package/dist/types/src/components/Select/Select.d.ts.map +1 -1
- package/dist/types/src/components/Select/Select.stories.d.ts +2 -3
- package/dist/types/src/components/Select/Select.stories.d.ts.map +1 -1
- package/dist/types/src/components/Separator/Separator.d.ts +3 -1
- package/dist/types/src/components/Separator/Separator.d.ts.map +1 -1
- package/dist/types/src/components/Status/Status.stories.d.ts +3 -3
- package/dist/types/src/components/Status/Status.stories.d.ts.map +1 -1
- package/dist/types/src/components/Tag/Tag.d.ts.map +1 -1
- package/dist/types/src/components/Tag/Tag.stories.d.ts +12 -5
- package/dist/types/src/components/Tag/Tag.stories.d.ts.map +1 -1
- package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts +5 -3
- package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts.map +1 -1
- package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts +1 -1
- package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts.map +1 -1
- package/dist/types/src/components/Toast/Toast.d.ts +4 -4
- package/dist/types/src/components/Toast/Toast.stories.d.ts +8 -8
- package/dist/types/src/components/Toolbar/Toolbar.d.ts +20 -10
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +17 -12
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
- package/dist/types/src/components/Tooltip/Tooltip.d.ts +2 -2
- package/dist/types/src/components/Tooltip/Tooltip.d.ts.map +1 -1
- package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts +16 -4
- package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +1 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useSafeArea.d.ts +9 -0
- package/dist/types/src/hooks/useSafeArea.d.ts.map +1 -0
- package/dist/types/src/hooks/useSafeCollisionPadding.d.ts +10 -0
- package/dist/types/src/hooks/useSafeCollisionPadding.d.ts.map +1 -0
- package/dist/types/src/hooks/useThemeContext.d.ts +1 -1
- package/dist/types/src/hooks/useThemeContext.d.ts.map +1 -1
- package/dist/types/src/hooks/useTranslationsContext.d.ts +1 -1
- package/dist/types/src/hooks/useVisualViewport.d.ts +1 -1
- package/dist/types/src/hooks/useVisualViewport.d.ts.map +1 -1
- package/dist/types/src/playground/Controls.stories.d.ts +2 -3
- package/dist/types/src/playground/Controls.stories.d.ts.map +1 -1
- package/dist/types/src/playground/Typography.stories.d.ts +2 -3
- package/dist/types/src/playground/Typography.stories.d.ts.map +1 -1
- package/dist/types/src/util/ThemedClassName.d.ts +1 -1
- package/dist/types/src/util/ThemedClassName.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +43 -42
- package/src/components/Avatars/Avatar.tsx +5 -13
- package/src/components/Buttons/IconButton.tsx +32 -7
- package/src/components/Clipboard/CopyButton.tsx +6 -2
- package/src/components/Dialogs/AlertDialog.tsx +3 -1
- package/src/components/Dialogs/Dialog.stories.tsx +1 -1
- package/src/components/Dialogs/Dialog.tsx +10 -13
- package/src/components/Icon/Icon.tsx +4 -1
- package/src/components/Input/Input.tsx +1 -1
- package/src/components/Lists/ListDropIndicator.tsx +15 -7
- package/src/components/Main/Main.stories.tsx +1 -1
- package/src/components/Main/Main.tsx +78 -108
- package/src/components/Menus/ContextMenu.tsx +4 -2
- package/src/components/Menus/DropdownMenu.tsx +4 -2
- package/src/components/Popover/Popover.tsx +4 -0
- package/src/components/Select/Select.tsx +4 -1
- package/src/components/Separator/Separator.tsx +14 -11
- package/src/components/Tag/Tag.stories.tsx +17 -31
- package/src/components/Tag/Tag.tsx +15 -6
- package/src/components/ThemeProvider/ThemeProvider.tsx +12 -3
- package/src/components/Toolbar/Toolbar.tsx +40 -10
- package/src/components/Tooltip/Tooltip.stories.tsx +13 -2
- package/src/components/Tooltip/Tooltip.tsx +17 -13
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useSafeArea.ts +25 -0
- package/src/hooks/useSafeCollisionPadding.ts +39 -0
- package/src/hooks/useVisualViewport.ts +11 -12
- package/src/util/ThemedClassName.ts +1 -1
|
@@ -95,7 +95,9 @@ const [OverlayLayoutProvider, useOverlayLayoutContext] = createContext<OverlayLa
|
|
|
95
95
|
},
|
|
96
96
|
);
|
|
97
97
|
|
|
98
|
-
type AlertDialogOverlayProps = ThemedClassName<AlertDialogOverlayPrimitiveProps> & {
|
|
98
|
+
type AlertDialogOverlayProps = ThemedClassName<AlertDialogOverlayPrimitiveProps> & {
|
|
99
|
+
blockAlign?: 'center' | 'start' | 'end';
|
|
100
|
+
};
|
|
99
101
|
|
|
100
102
|
const AlertDialogOverlay: ForwardRefExoticComponent<AlertDialogOverlayProps> = forwardRef<
|
|
101
103
|
HTMLDivElement,
|
|
@@ -85,7 +85,7 @@ const [OverlayLayoutProvider, useOverlayLayoutContext] = createContext<OverlayLa
|
|
|
85
85
|
inOverlayLayout: false,
|
|
86
86
|
});
|
|
87
87
|
|
|
88
|
-
type DialogOverlayProps = ThemedClassName<DialogOverlayPrimitiveProps> & { blockAlign?: 'center' | 'start' };
|
|
88
|
+
type DialogOverlayProps = ThemedClassName<DialogOverlayPrimitiveProps> & { blockAlign?: 'center' | 'start' | 'end' };
|
|
89
89
|
|
|
90
90
|
const DialogOverlay: ForwardRefExoticComponent<DialogOverlayProps> = forwardRef<HTMLDivElement, DialogOverlayProps>(
|
|
91
91
|
({ classNames, children, blockAlign, ...props }, forwardedRef) => {
|
|
@@ -94,15 +94,7 @@ const DialogOverlay: ForwardRefExoticComponent<DialogOverlayProps> = forwardRef<
|
|
|
94
94
|
return (
|
|
95
95
|
<DialogOverlayPrimitive
|
|
96
96
|
{...props}
|
|
97
|
-
className={tx(
|
|
98
|
-
'dialog.overlay',
|
|
99
|
-
'dialog__overlay',
|
|
100
|
-
{},
|
|
101
|
-
classNames,
|
|
102
|
-
'data-[block-align=start]:justify-center',
|
|
103
|
-
'data-[block-align=start]:items-start',
|
|
104
|
-
'data-[block-align=center]:place-content-center',
|
|
105
|
-
)}
|
|
97
|
+
className={tx('dialog.overlay', 'dialog__overlay', {}, classNames)}
|
|
106
98
|
ref={forwardedRef}
|
|
107
99
|
data-block-align={blockAlign}
|
|
108
100
|
>
|
|
@@ -114,17 +106,22 @@ const DialogOverlay: ForwardRefExoticComponent<DialogOverlayProps> = forwardRef<
|
|
|
114
106
|
|
|
115
107
|
DialogOverlay.displayName = DIALOG_OVERLAY_NAME;
|
|
116
108
|
|
|
117
|
-
type DialogContentProps = ThemedClassName<DialogContentPrimitiveProps
|
|
109
|
+
type DialogContentProps = ThemedClassName<DialogContentPrimitiveProps> & { inOverlayLayout?: boolean };
|
|
118
110
|
|
|
119
111
|
const DialogContent: ForwardRefExoticComponent<DialogContentProps> = forwardRef<HTMLDivElement, DialogContentProps>(
|
|
120
|
-
({ classNames, children, ...props }, forwardedRef) => {
|
|
112
|
+
({ classNames, children, inOverlayLayout: propsInOverlayLayout, ...props }, forwardedRef) => {
|
|
121
113
|
const { tx } = useThemeContext();
|
|
122
114
|
const { inOverlayLayout } = useOverlayLayoutContext(DIALOG_CONTENT_NAME);
|
|
123
115
|
|
|
124
116
|
return (
|
|
125
117
|
<DialogContentPrimitive
|
|
126
118
|
{...props}
|
|
127
|
-
className={tx(
|
|
119
|
+
className={tx(
|
|
120
|
+
'dialog.content',
|
|
121
|
+
'dialog',
|
|
122
|
+
{ inOverlayLayout: propsInOverlayLayout || inOverlayLayout },
|
|
123
|
+
classNames,
|
|
124
|
+
)}
|
|
128
125
|
ref={forwardedRef}
|
|
129
126
|
>
|
|
130
127
|
{children}
|
|
@@ -12,7 +12,10 @@ import { type ThemedClassName } from '../../util';
|
|
|
12
12
|
|
|
13
13
|
const ICONS_URL = '/icons.svg';
|
|
14
14
|
|
|
15
|
-
export type IconProps = ThemedClassName<ComponentPropsWithRef<typeof Primitive.svg>> & {
|
|
15
|
+
export type IconProps = ThemedClassName<ComponentPropsWithRef<typeof Primitive.svg>> & {
|
|
16
|
+
icon: string;
|
|
17
|
+
size?: Size;
|
|
18
|
+
};
|
|
16
19
|
|
|
17
20
|
export const Icon = memo(
|
|
18
21
|
forwardRef<SVGSVGElement, IconProps>(({ icon, classNames, size, ...props }, forwardedRef) => {
|
|
@@ -307,7 +307,7 @@ const Switch = forwardRef<HTMLInputElement, InputScopedProps<SwitchProps>>(
|
|
|
307
307
|
return (
|
|
308
308
|
<input
|
|
309
309
|
type='checkbox'
|
|
310
|
-
className='
|
|
310
|
+
className='dx-checkbox--switch dx-focus-ring'
|
|
311
311
|
checked={checked}
|
|
312
312
|
onChange={(event) => {
|
|
313
313
|
onCheckedChange(event.target.checked);
|
|
@@ -15,8 +15,10 @@ const edgeToOrientationMap: Record<Edge, Orientation> = {
|
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
const orientationStyles: Record<Orientation, HTMLAttributes<HTMLElement>['className']> = {
|
|
18
|
-
horizontal:
|
|
19
|
-
|
|
18
|
+
horizontal:
|
|
19
|
+
'h-[--line-thickness] left-[calc(var(--line-inset)+var(--terminal-radius))] right-[--line-inset] before:left-[--terminal-inset]',
|
|
20
|
+
vertical:
|
|
21
|
+
'w-[--line-thickness] top-[calc(var(--line-inset)+var(--terminal-radius))] bottom-[--line-inset] before:top-[--terminal-inset]',
|
|
20
22
|
};
|
|
21
23
|
|
|
22
24
|
const edgeStyles: Record<Edge, HTMLAttributes<HTMLElement>['className']> = {
|
|
@@ -33,14 +35,19 @@ const offsetToAlignTerminalWithLine = (strokeSize - terminalSize) / 2;
|
|
|
33
35
|
export type DropIndicatorProps = {
|
|
34
36
|
edge: Edge;
|
|
35
37
|
gap?: number;
|
|
38
|
+
terminalInset?: number;
|
|
39
|
+
lineInset?: number;
|
|
36
40
|
};
|
|
37
41
|
|
|
38
42
|
/**
|
|
39
43
|
* This is a tailwind port of `@atlaskit/pragmatic-drag-and-drop-react-drop-indicator/box`
|
|
40
44
|
*/
|
|
41
|
-
export const ListDropIndicator = ({
|
|
42
|
-
|
|
43
|
-
|
|
45
|
+
export const ListDropIndicator = ({
|
|
46
|
+
edge,
|
|
47
|
+
gap = 0,
|
|
48
|
+
lineInset = 0,
|
|
49
|
+
terminalInset = lineInset - terminalSize,
|
|
50
|
+
}: DropIndicatorProps) => {
|
|
44
51
|
const orientation = edgeToOrientationMap[edge];
|
|
45
52
|
|
|
46
53
|
return (
|
|
@@ -49,10 +56,11 @@ export const ListDropIndicator = ({ edge, gap = 0 }: DropIndicatorProps) => {
|
|
|
49
56
|
style={
|
|
50
57
|
{
|
|
51
58
|
'--line-thickness': `${strokeSize}px`,
|
|
52
|
-
'--line-offset':
|
|
59
|
+
'--line-offset': `calc(-0.5 * (${gap}px + ${strokeSize}px))`,
|
|
60
|
+
'--line-inset': `${lineInset}px`,
|
|
53
61
|
'--terminal-size': `${terminalSize}px`,
|
|
54
62
|
'--terminal-radius': `${terminalSize / 2}px`,
|
|
55
|
-
'--
|
|
63
|
+
'--terminal-inset': `${terminalInset}px`,
|
|
56
64
|
'--offset-terminal': `${offsetToAlignTerminalWithLine}px`,
|
|
57
65
|
} as CSSProperties
|
|
58
66
|
}
|
|
@@ -24,7 +24,7 @@ const ComplementarySidebarToggle = () => {
|
|
|
24
24
|
|
|
25
25
|
const StoryMain = (_args: StoryMainArgs) => {
|
|
26
26
|
return (
|
|
27
|
-
<Main.Root
|
|
27
|
+
<Main.Root>
|
|
28
28
|
<Main.Overlay />
|
|
29
29
|
<Main.NavigationSidebar classNames='p-4'>
|
|
30
30
|
<p>Navigation sidebar content, hi!</p>
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { useFocusableGroup } from '@fluentui/react-tabster';
|
|
6
|
-
import { useComposedRefs } from '@radix-ui/react-compose-refs';
|
|
7
6
|
import { createContext } from '@radix-ui/react-context';
|
|
8
7
|
import { Root as DialogRoot, DialogContent } from '@radix-ui/react-dialog';
|
|
9
8
|
import { Primitive } from '@radix-ui/react-primitive';
|
|
@@ -36,12 +35,14 @@ const COMPLEMENTARY_SIDEBAR_NAME = 'ComplementarySidebar';
|
|
|
36
35
|
const MAIN_NAME = 'Main';
|
|
37
36
|
const GENERIC_CONSUMER_NAME = 'GenericConsumer';
|
|
38
37
|
|
|
38
|
+
type SidebarState = 'expanded' | 'collapsed' | 'closed';
|
|
39
|
+
|
|
39
40
|
type MainContextValue = {
|
|
40
41
|
resizing: boolean;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
navigationSidebarState: SidebarState;
|
|
43
|
+
setNavigationSidebarState: Dispatch<SetStateAction<SidebarState | undefined>>;
|
|
44
|
+
complementarySidebarState: SidebarState;
|
|
45
|
+
setComplementarySidebarState: Dispatch<SetStateAction<SidebarState | undefined>>;
|
|
45
46
|
};
|
|
46
47
|
|
|
47
48
|
const landmarkAttr = 'data-main-landmark';
|
|
@@ -74,73 +75,77 @@ const useLandmarkMover = (propsOnKeyDown: ComponentPropsWithoutRef<'div'>['onKey
|
|
|
74
75
|
|
|
75
76
|
const [MainProvider, useMainContext] = createContext<MainContextValue>(MAIN_NAME, {
|
|
76
77
|
resizing: false,
|
|
77
|
-
|
|
78
|
-
|
|
78
|
+
navigationSidebarState: 'closed',
|
|
79
|
+
setNavigationSidebarState: (nextState) => {
|
|
79
80
|
// TODO(burdon): Standardize with other context missing errors using raise.
|
|
80
81
|
log.warn('Attempt to set sidebar state without initializing `MainRoot`');
|
|
81
82
|
},
|
|
82
|
-
|
|
83
|
-
|
|
83
|
+
complementarySidebarState: 'closed',
|
|
84
|
+
setComplementarySidebarState: (nextState) => {
|
|
84
85
|
// TODO(burdon): Standardize with other context missing errors using raise.
|
|
85
86
|
log.warn('Attempt to set sidebar state without initializing `MainRoot`');
|
|
86
87
|
},
|
|
87
88
|
});
|
|
88
89
|
|
|
89
90
|
const useSidebars = (consumerName = GENERIC_CONSUMER_NAME) => {
|
|
90
|
-
const {
|
|
91
|
+
const { setNavigationSidebarState, navigationSidebarState, setComplementarySidebarState, complementarySidebarState } =
|
|
91
92
|
useMainContext(consumerName);
|
|
92
93
|
return {
|
|
93
|
-
|
|
94
|
-
|
|
94
|
+
navigationSidebarState,
|
|
95
|
+
setNavigationSidebarState,
|
|
95
96
|
toggleNavigationSidebar: useCallback(
|
|
96
|
-
() =>
|
|
97
|
-
[
|
|
97
|
+
() => setNavigationSidebarState(navigationSidebarState === 'expanded' ? 'closed' : 'expanded'),
|
|
98
|
+
[navigationSidebarState, setNavigationSidebarState],
|
|
98
99
|
),
|
|
99
|
-
openNavigationSidebar: useCallback(() =>
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
openNavigationSidebar: useCallback(() => setNavigationSidebarState('expanded'), []),
|
|
101
|
+
collapseNavigationSidebar: useCallback(() => setNavigationSidebarState('collapsed'), []),
|
|
102
|
+
closeNavigationSidebar: useCallback(() => setNavigationSidebarState('closed'), []),
|
|
103
|
+
complementarySidebarState,
|
|
104
|
+
setComplementarySidebarState,
|
|
103
105
|
toggleComplementarySidebar: useCallback(
|
|
104
|
-
() =>
|
|
105
|
-
[
|
|
106
|
+
() => setComplementarySidebarState(complementarySidebarState === 'expanded' ? 'closed' : 'expanded'),
|
|
107
|
+
[complementarySidebarState, setComplementarySidebarState],
|
|
106
108
|
),
|
|
107
|
-
openComplementarySidebar: useCallback(() =>
|
|
108
|
-
|
|
109
|
+
openComplementarySidebar: useCallback(() => setComplementarySidebarState('expanded'), []),
|
|
110
|
+
collapseComplementarySidebar: useCallback(() => setComplementarySidebarState('collapsed'), []),
|
|
111
|
+
closeComplementarySidebar: useCallback(() => setComplementarySidebarState('closed'), []),
|
|
109
112
|
};
|
|
110
113
|
};
|
|
111
114
|
|
|
112
115
|
type MainRootProps = PropsWithChildren<{
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
116
|
+
navigationSidebarState?: SidebarState;
|
|
117
|
+
defaultNavigationSidebarState?: SidebarState;
|
|
118
|
+
onNavigationSidebarStateChange?: (nextState: SidebarState) => void;
|
|
119
|
+
complementarySidebarState?: SidebarState;
|
|
120
|
+
defaultComplementarySidebarState?: SidebarState;
|
|
121
|
+
onComplementarySidebarStateChange?: (nextState: SidebarState) => void;
|
|
119
122
|
}>;
|
|
120
123
|
|
|
121
124
|
const resizeDebounce = 3000;
|
|
122
125
|
|
|
123
126
|
const MainRoot = ({
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
127
|
+
navigationSidebarState: propsNavigationSidebarState,
|
|
128
|
+
defaultNavigationSidebarState,
|
|
129
|
+
onNavigationSidebarStateChange,
|
|
130
|
+
complementarySidebarState: propsComplementarySidebarState,
|
|
131
|
+
defaultComplementarySidebarState,
|
|
132
|
+
onComplementarySidebarStateChange,
|
|
130
133
|
children,
|
|
131
134
|
...props
|
|
132
135
|
}: MainRootProps) => {
|
|
133
136
|
const [isLg] = useMediaQuery('lg', { ssr: false });
|
|
134
|
-
const [
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
137
|
+
const [navigationSidebarState = isLg ? 'expanded' : 'collapsed', setNavigationSidebarState] =
|
|
138
|
+
useControllableState<SidebarState>({
|
|
139
|
+
prop: propsNavigationSidebarState,
|
|
140
|
+
defaultProp: defaultNavigationSidebarState,
|
|
141
|
+
onChange: onNavigationSidebarStateChange,
|
|
142
|
+
});
|
|
143
|
+
const [complementarySidebarState = isLg ? 'expanded' : 'collapsed', setComplementarySidebarState] =
|
|
144
|
+
useControllableState<SidebarState>({
|
|
145
|
+
prop: propsComplementarySidebarState,
|
|
146
|
+
defaultProp: defaultComplementarySidebarState,
|
|
147
|
+
onChange: onComplementarySidebarStateChange,
|
|
148
|
+
});
|
|
144
149
|
|
|
145
150
|
const [resizing, setResizing] = useState(false);
|
|
146
151
|
const resizeInterval = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
@@ -165,10 +170,10 @@ const MainRoot = ({
|
|
|
165
170
|
<MainProvider
|
|
166
171
|
{...props}
|
|
167
172
|
{...{
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
173
|
+
navigationSidebarState,
|
|
174
|
+
setNavigationSidebarState,
|
|
175
|
+
complementarySidebarState,
|
|
176
|
+
setComplementarySidebarState,
|
|
172
177
|
}}
|
|
173
178
|
resizing={resizing}
|
|
174
179
|
>
|
|
@@ -185,15 +190,15 @@ const handleOpenAutoFocus = (event: Event) => {
|
|
|
185
190
|
|
|
186
191
|
type MainSidebarProps = ThemedClassName<ComponentPropsWithRef<typeof DialogContent>> & {
|
|
187
192
|
swipeToDismiss?: boolean;
|
|
188
|
-
|
|
193
|
+
state?: SidebarState;
|
|
189
194
|
resizing?: boolean;
|
|
190
|
-
|
|
195
|
+
onStateChange?: (nextState: SidebarState) => void;
|
|
191
196
|
side: 'inline-start' | 'inline-end';
|
|
192
197
|
};
|
|
193
198
|
|
|
194
199
|
const MainSidebar = forwardRef<HTMLDivElement, MainSidebarProps>(
|
|
195
200
|
(
|
|
196
|
-
{ classNames, children, swipeToDismiss, onOpenAutoFocus,
|
|
201
|
+
{ classNames, children, swipeToDismiss, onOpenAutoFocus, state, resizing, onStateChange, side, ...props },
|
|
197
202
|
forwardedRef,
|
|
198
203
|
) => {
|
|
199
204
|
const [isLg] = useMediaQuery('lg', { ssr: false });
|
|
@@ -201,7 +206,7 @@ const MainSidebar = forwardRef<HTMLDivElement, MainSidebarProps>(
|
|
|
201
206
|
const ref = useForwardedRef(forwardedRef);
|
|
202
207
|
const noopRef = useRef(null);
|
|
203
208
|
useSwipeToDismiss(swipeToDismiss ? ref : noopRef, {
|
|
204
|
-
onDismiss: () =>
|
|
209
|
+
onDismiss: () => onStateChange?.('closed'),
|
|
205
210
|
});
|
|
206
211
|
const handleKeyDown = useCallback(
|
|
207
212
|
(event: KeyboardEvent<HTMLDivElement>) => {
|
|
@@ -214,16 +219,16 @@ const MainSidebar = forwardRef<HTMLDivElement, MainSidebarProps>(
|
|
|
214
219
|
);
|
|
215
220
|
const Root = isLg ? Primitive.div : DialogContent;
|
|
216
221
|
return (
|
|
217
|
-
<DialogRoot open={
|
|
222
|
+
<DialogRoot open={state !== 'closed'} modal={false}>
|
|
218
223
|
<Root
|
|
219
224
|
{...(!isLg && { forceMount: true, tabIndex: -1, onOpenAutoFocus: onOpenAutoFocus ?? handleOpenAutoFocus })}
|
|
220
225
|
{...props}
|
|
221
226
|
data-side={side === 'inline-end' ? 'ie' : 'is'}
|
|
222
|
-
data-state={
|
|
227
|
+
data-state={state}
|
|
223
228
|
data-resizing={resizing ? 'true' : 'false'}
|
|
224
229
|
className={tx('main.sidebar', 'main__sidebar', {}, classNames)}
|
|
225
230
|
onKeyDown={handleKeyDown}
|
|
226
|
-
{...(
|
|
231
|
+
{...(state === 'closed' && { inert: 'true' })}
|
|
227
232
|
ref={ref}
|
|
228
233
|
>
|
|
229
234
|
{children}
|
|
@@ -233,17 +238,17 @@ const MainSidebar = forwardRef<HTMLDivElement, MainSidebarProps>(
|
|
|
233
238
|
},
|
|
234
239
|
);
|
|
235
240
|
|
|
236
|
-
type MainNavigationSidebarProps = Omit<MainSidebarProps, '
|
|
241
|
+
type MainNavigationSidebarProps = Omit<MainSidebarProps, 'expanded' | 'side'>;
|
|
237
242
|
|
|
238
243
|
const MainNavigationSidebar = forwardRef<HTMLDivElement, MainNavigationSidebarProps>((props, forwardedRef) => {
|
|
239
|
-
const {
|
|
244
|
+
const { navigationSidebarState, setNavigationSidebarState, resizing } = useMainContext(NAVIGATION_SIDEBAR_NAME);
|
|
240
245
|
const mover = useLandmarkMover(props.onKeyDown, '0');
|
|
241
246
|
return (
|
|
242
247
|
<MainSidebar
|
|
243
248
|
{...mover}
|
|
244
249
|
{...props}
|
|
245
|
-
|
|
246
|
-
|
|
250
|
+
state={navigationSidebarState}
|
|
251
|
+
onStateChange={setNavigationSidebarState}
|
|
247
252
|
resizing={resizing}
|
|
248
253
|
side='inline-start'
|
|
249
254
|
ref={forwardedRef}
|
|
@@ -253,18 +258,18 @@ const MainNavigationSidebar = forwardRef<HTMLDivElement, MainNavigationSidebarPr
|
|
|
253
258
|
|
|
254
259
|
MainNavigationSidebar.displayName = NAVIGATION_SIDEBAR_NAME;
|
|
255
260
|
|
|
256
|
-
type MainComplementarySidebarProps = Omit<MainSidebarProps, '
|
|
261
|
+
type MainComplementarySidebarProps = Omit<MainSidebarProps, 'expanded' | 'side'>;
|
|
257
262
|
|
|
258
263
|
const MainComplementarySidebar = forwardRef<HTMLDivElement, MainComplementarySidebarProps>((props, forwardedRef) => {
|
|
259
|
-
const {
|
|
264
|
+
const { complementarySidebarState, setComplementarySidebarState, resizing } =
|
|
260
265
|
useMainContext(COMPLEMENTARY_SIDEBAR_NAME);
|
|
261
266
|
const mover = useLandmarkMover(props.onKeyDown, '2');
|
|
262
267
|
return (
|
|
263
268
|
<MainSidebar
|
|
264
269
|
{...mover}
|
|
265
270
|
{...props}
|
|
266
|
-
|
|
267
|
-
|
|
271
|
+
state={complementarySidebarState}
|
|
272
|
+
onStateChange={setComplementarySidebarState}
|
|
268
273
|
resizing={resizing}
|
|
269
274
|
side='inline-end'
|
|
270
275
|
ref={forwardedRef}
|
|
@@ -282,7 +287,7 @@ type MainProps = ThemedClassName<ComponentPropsWithRef<typeof Primitive.div>> &
|
|
|
282
287
|
|
|
283
288
|
const MainContent = forwardRef<HTMLDivElement, MainProps>(
|
|
284
289
|
({ asChild, classNames, bounce, handlesFocus, children, role, ...props }: MainProps, forwardedRef) => {
|
|
285
|
-
const {
|
|
290
|
+
const { navigationSidebarState, complementarySidebarState } = useMainContext(MAIN_NAME);
|
|
286
291
|
const { tx } = useThemeContext();
|
|
287
292
|
const Root = asChild ? Slot : role ? 'div' : 'main';
|
|
288
293
|
|
|
@@ -293,8 +298,8 @@ const MainContent = forwardRef<HTMLDivElement, MainProps>(
|
|
|
293
298
|
role={role}
|
|
294
299
|
{...(handlesFocus && { ...mover })}
|
|
295
300
|
{...props}
|
|
296
|
-
data-sidebar-inline-start-state={
|
|
297
|
-
data-sidebar-inline-end-state={
|
|
301
|
+
data-sidebar-inline-start-state={navigationSidebarState}
|
|
302
|
+
data-sidebar-inline-end-state={complementarySidebarState}
|
|
298
303
|
className={tx('main.content', 'main', { bounce, handlesFocus }, classNames)}
|
|
299
304
|
ref={forwardedRef}
|
|
300
305
|
>
|
|
@@ -310,72 +315,37 @@ type MainOverlayProps = ThemedClassName<Omit<ComponentPropsWithRef<typeof Primit
|
|
|
310
315
|
|
|
311
316
|
const MainOverlay = forwardRef<HTMLDivElement, MainOverlayProps>(({ classNames, ...props }, forwardedRef) => {
|
|
312
317
|
const [isLg] = useMediaQuery('lg', { ssr: false });
|
|
313
|
-
const {
|
|
318
|
+
const { navigationSidebarState, setNavigationSidebarState, complementarySidebarState, setComplementarySidebarState } =
|
|
314
319
|
useMainContext(MAIN_NAME);
|
|
315
320
|
const { tx } = useThemeContext();
|
|
316
321
|
return (
|
|
317
322
|
<div
|
|
318
323
|
onClick={() => {
|
|
319
|
-
|
|
320
|
-
|
|
324
|
+
setNavigationSidebarState('collapsed');
|
|
325
|
+
setComplementarySidebarState('collapsed');
|
|
321
326
|
}}
|
|
322
327
|
{...props}
|
|
323
328
|
className={tx(
|
|
324
329
|
'main.overlay',
|
|
325
330
|
'main__overlay',
|
|
326
|
-
{ isLg, inlineStartSidebarOpen:
|
|
331
|
+
{ isLg, inlineStartSidebarOpen: navigationSidebarState, inlineEndSidebarOpen: complementarySidebarState },
|
|
327
332
|
classNames,
|
|
328
333
|
)}
|
|
329
|
-
data-state={
|
|
334
|
+
data-state={navigationSidebarState === 'expanded' || complementarySidebarState === 'expanded' ? 'open' : 'closed'}
|
|
330
335
|
aria-hidden='true'
|
|
331
336
|
ref={forwardedRef}
|
|
332
337
|
/>
|
|
333
338
|
);
|
|
334
339
|
});
|
|
335
340
|
|
|
336
|
-
type MainNotchProps = ThemedClassName<ComponentPropsWithRef<typeof Primitive.div>>;
|
|
337
|
-
|
|
338
|
-
const MainNotch = forwardRef<HTMLDivElement, MainNotchProps>(({ classNames, ...props }, forwardedRef) => {
|
|
339
|
-
const { tx } = useThemeContext();
|
|
340
|
-
// Notch is concerned with the nav sidebar, whichever side it might be on.
|
|
341
|
-
const { navigationSidebarOpen } = useMainContext(MAIN_NAME);
|
|
342
|
-
const notchElement = useRef<HTMLDivElement | null>(null);
|
|
343
|
-
const ref = useComposedRefs(forwardedRef, notchElement);
|
|
344
|
-
|
|
345
|
-
const handleKeyDown = useCallback(
|
|
346
|
-
(event: KeyboardEvent<HTMLDivElement>) => {
|
|
347
|
-
switch (event.key) {
|
|
348
|
-
case 'Escape':
|
|
349
|
-
props?.onKeyDown?.(event);
|
|
350
|
-
notchElement.current?.focus();
|
|
351
|
-
}
|
|
352
|
-
},
|
|
353
|
-
[props?.onKeyDown],
|
|
354
|
-
);
|
|
355
|
-
|
|
356
|
-
const mover = useLandmarkMover(handleKeyDown, '3');
|
|
357
|
-
|
|
358
|
-
return (
|
|
359
|
-
<div
|
|
360
|
-
role='toolbar'
|
|
361
|
-
{...mover}
|
|
362
|
-
{...props}
|
|
363
|
-
data-nav-sidebar-state={navigationSidebarOpen ? 'open' : 'closed'}
|
|
364
|
-
className={tx('main.notch', 'main__notch', {}, classNames)}
|
|
365
|
-
ref={ref}
|
|
366
|
-
/>
|
|
367
|
-
);
|
|
368
|
-
});
|
|
369
|
-
|
|
370
341
|
export const Main = {
|
|
371
342
|
Root: MainRoot,
|
|
372
343
|
Content: MainContent,
|
|
373
344
|
Overlay: MainOverlay,
|
|
374
345
|
NavigationSidebar: MainNavigationSidebar,
|
|
375
346
|
ComplementarySidebar: MainComplementarySidebar,
|
|
376
|
-
Notch: MainNotch,
|
|
377
347
|
};
|
|
378
348
|
|
|
379
|
-
export { useMainContext, useSidebars };
|
|
349
|
+
export { useMainContext, useSidebars, useLandmarkMover };
|
|
380
350
|
|
|
381
|
-
export type { MainRootProps, MainProps, MainOverlayProps, MainNavigationSidebarProps };
|
|
351
|
+
export type { MainRootProps, MainProps, MainOverlayProps, MainNavigationSidebarProps, SidebarState };
|
|
@@ -7,6 +7,7 @@ import { Slot } from '@radix-ui/react-slot';
|
|
|
7
7
|
import React, { type ComponentPropsWithRef, forwardRef } from 'react';
|
|
8
8
|
|
|
9
9
|
import { useElevationContext, useThemeContext } from '../../hooks';
|
|
10
|
+
import { useSafeCollisionPadding } from '../../hooks/useSafeCollisionPadding';
|
|
10
11
|
import { type ThemedClassName } from '../../util';
|
|
11
12
|
|
|
12
13
|
type ContextMenuRootProps = ContextMenuPrimitive.ContextMenuProps;
|
|
@@ -26,13 +27,14 @@ type ContextMenuContentProps = ThemedClassName<ContextMenuPrimitive.ContextMenuC
|
|
|
26
27
|
};
|
|
27
28
|
|
|
28
29
|
const ContextMenuContent = forwardRef<HTMLDivElement, ContextMenuContentProps>(
|
|
29
|
-
({ classNames, children, ...props }, forwardedRef) => {
|
|
30
|
+
({ classNames, children, collisionPadding = 8, ...props }, forwardedRef) => {
|
|
30
31
|
const { tx } = useThemeContext();
|
|
31
32
|
const elevation = useElevationContext();
|
|
33
|
+
const safeCollisionPadding = useSafeCollisionPadding(collisionPadding);
|
|
32
34
|
return (
|
|
33
35
|
<ContextMenuPrimitive.Content
|
|
34
|
-
collisionPadding={8}
|
|
35
36
|
{...props}
|
|
37
|
+
collisionPadding={safeCollisionPadding}
|
|
36
38
|
className={tx('menu.content', 'menu', { elevation }, classNames)}
|
|
37
39
|
ref={forwardedRef}
|
|
38
40
|
>
|
|
@@ -29,6 +29,7 @@ import React, {
|
|
|
29
29
|
} from 'react';
|
|
30
30
|
|
|
31
31
|
import { useElevationContext, useThemeContext } from '../../hooks';
|
|
32
|
+
import { useSafeCollisionPadding } from '../../hooks/useSafeCollisionPadding';
|
|
32
33
|
import { type ThemedClassName } from '../../util';
|
|
33
34
|
|
|
34
35
|
type Direction = 'ltr' | 'rtl';
|
|
@@ -232,19 +233,20 @@ interface DropdownMenuContentProps extends Omit<MenuContentProps, 'onEntryFocus'
|
|
|
232
233
|
|
|
233
234
|
const DropdownMenuContent = forwardRef<DropdownMenuContentElement, DropdownMenuContentProps>(
|
|
234
235
|
(props: ScopedProps<DropdownMenuContentProps>, forwardedRef) => {
|
|
235
|
-
const { __scopeDropdownMenu, classNames, ...contentProps } = props;
|
|
236
|
+
const { __scopeDropdownMenu, classNames, collisionPadding = 8, ...contentProps } = props;
|
|
236
237
|
const { tx } = useThemeContext();
|
|
237
238
|
const context = useDropdownMenuContext(CONTENT_NAME, __scopeDropdownMenu);
|
|
238
239
|
const elevation = useElevationContext();
|
|
239
240
|
const menuScope = useMenuScope(__scopeDropdownMenu);
|
|
240
241
|
const hasInteractedOutsideRef = useRef(false);
|
|
241
|
-
|
|
242
|
+
const safeCollisionPadding = useSafeCollisionPadding(collisionPadding);
|
|
242
243
|
return (
|
|
243
244
|
<MenuPrimitive.Content
|
|
244
245
|
id={context.contentId}
|
|
245
246
|
aria-labelledby={context.triggerId}
|
|
246
247
|
{...menuScope}
|
|
247
248
|
{...contentProps}
|
|
249
|
+
collisionPadding={safeCollisionPadding}
|
|
248
250
|
ref={forwardedRef}
|
|
249
251
|
onCloseAutoFocus={composeEventHandlers(props.onCloseAutoFocus, (event) => {
|
|
250
252
|
if (!hasInteractedOutsideRef.current) {
|
|
@@ -37,6 +37,7 @@ import React, {
|
|
|
37
37
|
import { RemoveScroll } from 'react-remove-scroll';
|
|
38
38
|
|
|
39
39
|
import { useElevationContext, useThemeContext } from '../../hooks';
|
|
40
|
+
import { useSafeCollisionPadding } from '../../hooks/useSafeCollisionPadding';
|
|
40
41
|
import { type ThemedClassName } from '../../util';
|
|
41
42
|
|
|
42
43
|
/* -------------------------------------------------------------------------------------------------
|
|
@@ -428,6 +429,7 @@ const PopoverContentImpl = forwardRef<PopoverContentImplElement, PopoverContentI
|
|
|
428
429
|
onPointerDownOutside,
|
|
429
430
|
onFocusOutside,
|
|
430
431
|
onInteractOutside,
|
|
432
|
+
collisionPadding = 8,
|
|
431
433
|
classNames,
|
|
432
434
|
...contentProps
|
|
433
435
|
} = props;
|
|
@@ -435,6 +437,7 @@ const PopoverContentImpl = forwardRef<PopoverContentImplElement, PopoverContentI
|
|
|
435
437
|
const popperScope = usePopperScope(__scopePopover);
|
|
436
438
|
const { tx } = useThemeContext();
|
|
437
439
|
const elevation = useElevationContext();
|
|
440
|
+
const safeCollisionPadding = useSafeCollisionPadding(collisionPadding);
|
|
438
441
|
|
|
439
442
|
// Make sure the whole tree has focus guards as our `Popover` may be
|
|
440
443
|
// the last element in the DOM (because of the `Portal`)
|
|
@@ -463,6 +466,7 @@ const PopoverContentImpl = forwardRef<PopoverContentImplElement, PopoverContentI
|
|
|
463
466
|
id={context.contentId}
|
|
464
467
|
{...popperScope}
|
|
465
468
|
{...contentProps}
|
|
469
|
+
collisionPadding={safeCollisionPadding}
|
|
466
470
|
className={tx('popover.content', 'popover', { elevation }, classNames)}
|
|
467
471
|
ref={forwardedRef}
|
|
468
472
|
style={{
|
|
@@ -7,6 +7,7 @@ import * as SelectPrimitive from '@radix-ui/react-select';
|
|
|
7
7
|
import React, { forwardRef } from 'react';
|
|
8
8
|
|
|
9
9
|
import { useElevationContext, useThemeContext } from '../../hooks';
|
|
10
|
+
import { useSafeCollisionPadding } from '../../hooks/useSafeCollisionPadding';
|
|
10
11
|
import { type ThemedClassName } from '../../util';
|
|
11
12
|
import { Button, type ButtonProps } from '../Buttons';
|
|
12
13
|
import { Icon } from '../Icon';
|
|
@@ -53,12 +54,14 @@ const SelectTriggerButton = forwardRef<HTMLButtonElement, SelectTriggerButtonPro
|
|
|
53
54
|
type SelectContentProps = ThemedClassName<SelectPrimitive.SelectContentProps>;
|
|
54
55
|
|
|
55
56
|
const SelectContent = forwardRef<HTMLDivElement, SelectContentProps>(
|
|
56
|
-
({ classNames, children, ...props }, forwardedRef) => {
|
|
57
|
+
({ classNames, children, collisionPadding = 8, ...props }, forwardedRef) => {
|
|
57
58
|
const { tx } = useThemeContext();
|
|
58
59
|
const elevation = useElevationContext();
|
|
60
|
+
const safeCollisionPadding = useSafeCollisionPadding(collisionPadding);
|
|
59
61
|
return (
|
|
60
62
|
<SelectPrimitive.Content
|
|
61
63
|
{...props}
|
|
64
|
+
collisionPadding={safeCollisionPadding}
|
|
62
65
|
className={tx('select.content', 'select__content', { elevation }, classNames)}
|
|
63
66
|
position='popper'
|
|
64
67
|
ref={forwardedRef}
|