@dxos/react-ui 0.8.4-main.bc674ce → 0.8.4-main.bd9b33e6c8
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/{chunk-CEKVHJ27.mjs → chunk-LUPEFGHJ.mjs} +119 -117
- package/dist/lib/browser/chunk-LUPEFGHJ.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +3021 -2087
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +59 -36
- package/dist/lib/browser/testing/index.mjs.map +4 -4
- package/dist/lib/node-esm/{chunk-2NHEX4AD.mjs → chunk-EQOBFLZC.mjs} +119 -117
- package/dist/lib/node-esm/chunk-EQOBFLZC.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +3021 -2087
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +59 -36
- package/dist/lib/node-esm/testing/index.mjs.map +4 -4
- package/dist/types/src/components/Avatars/Avatar.d.ts.map +1 -1
- package/dist/types/src/components/Avatars/Avatar.stories.d.ts.map +1 -1
- package/dist/types/src/components/Breadcrumb/Breadcrumb.d.ts.map +1 -1
- package/dist/types/src/components/Button/Button.d.ts +2 -2
- package/dist/types/src/components/Button/Button.d.ts.map +1 -1
- package/dist/types/src/components/Button/IconButton.d.ts.map +1 -1
- package/dist/types/src/components/Button/Toggle.d.ts +2 -2
- package/dist/types/src/components/Button/Toggle.d.ts.map +1 -1
- package/dist/types/src/components/Button/ToggleGroup.d.ts +6 -6
- package/dist/types/src/components/Button/ToggleGroup.d.ts.map +1 -1
- package/dist/types/src/components/Card/Card.d.ts +145 -0
- package/dist/types/src/components/Card/Card.d.ts.map +1 -0
- package/dist/types/src/components/Card/Card.stories.d.ts +21 -0
- package/dist/types/src/components/Card/Card.stories.d.ts.map +1 -0
- package/dist/types/src/components/Card/index.d.ts +2 -0
- package/dist/types/src/components/Card/index.d.ts.map +1 -0
- package/dist/types/src/components/Clipboard/index.d.ts +10 -1
- package/dist/types/src/components/Clipboard/index.d.ts.map +1 -1
- package/dist/types/src/components/Dialog/AlertDialog.d.ts +41 -19
- package/dist/types/src/components/Dialog/AlertDialog.d.ts.map +1 -1
- package/dist/types/src/components/Dialog/AlertDialog.stories.d.ts.map +1 -1
- package/dist/types/src/components/Dialog/Dialog.d.ts +48 -22
- package/dist/types/src/components/Dialog/Dialog.d.ts.map +1 -1
- package/dist/types/src/components/Dialog/Dialog.stories.d.ts +6 -8
- package/dist/types/src/components/Dialog/Dialog.stories.d.ts.map +1 -1
- package/dist/types/src/components/ErrorFallback/ErrorFallback.d.ts +11 -0
- package/dist/types/src/components/ErrorFallback/ErrorFallback.d.ts.map +1 -0
- package/dist/types/src/components/ErrorFallback/ErrorFallback.stories.d.ts +7 -0
- package/dist/types/src/components/ErrorFallback/ErrorFallback.stories.d.ts.map +1 -0
- package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts +8 -0
- package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts.map +1 -0
- package/dist/types/src/components/ErrorFallback/ThrowError.d.ts +9 -0
- package/dist/types/src/components/ErrorFallback/ThrowError.d.ts.map +1 -0
- package/dist/types/src/components/ErrorFallback/index.d.ts +5 -0
- package/dist/types/src/components/ErrorFallback/index.d.ts.map +1 -0
- package/dist/types/src/components/Focus/Focus.d.ts +44 -0
- package/dist/types/src/components/Focus/Focus.d.ts.map +1 -0
- package/dist/types/src/components/Focus/Focus.stories.d.ts +9 -0
- package/dist/types/src/components/Focus/Focus.stories.d.ts.map +1 -0
- package/dist/types/src/components/Focus/index.d.ts +2 -0
- package/dist/types/src/components/Focus/index.d.ts.map +1 -0
- package/dist/types/src/components/Icon/Icon.d.ts +3 -0
- package/dist/types/src/components/Icon/Icon.d.ts.map +1 -1
- package/dist/types/src/components/Icon/Icon.stories.d.ts +11 -3
- package/dist/types/src/components/Icon/Icon.stories.d.ts.map +1 -1
- package/dist/types/src/components/Image/Image.d.ts +14 -0
- package/dist/types/src/components/Image/Image.d.ts.map +1 -0
- package/dist/types/src/components/Image/Image.stories.d.ts +33 -0
- package/dist/types/src/components/Image/Image.stories.d.ts.map +1 -0
- package/dist/types/src/components/Image/index.d.ts +2 -0
- package/dist/types/src/components/Image/index.d.ts.map +1 -0
- package/dist/types/src/components/Input/Input.d.ts +4 -7
- 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/List/List.d.ts +9 -3
- package/dist/types/src/components/List/List.d.ts.map +1 -1
- package/dist/types/src/components/List/List.stories.d.ts +8 -2
- package/dist/types/src/components/List/List.stories.d.ts.map +1 -1
- package/dist/types/src/components/List/Treegrid.d.ts.map +1 -1
- package/dist/types/src/components/Main/Main.d.ts +6 -32
- package/dist/types/src/components/Main/Main.d.ts.map +1 -1
- package/dist/types/src/components/Main/Main.stories.d.ts +1 -5
- package/dist/types/src/components/Main/Main.stories.d.ts.map +1 -1
- package/dist/types/src/components/Menu/ContextMenu.d.ts.map +1 -1
- package/dist/types/src/components/Menu/DropdownMenu.d.ts +51 -50
- package/dist/types/src/components/Menu/DropdownMenu.d.ts.map +1 -1
- package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts +14 -1
- package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts.map +1 -1
- package/dist/types/src/components/Message/Message.d.ts.map +1 -1
- package/dist/types/src/components/Message/Message.stories.d.ts +4 -5
- package/dist/types/src/components/Message/Message.stories.d.ts.map +1 -1
- package/dist/types/src/components/Popover/Popover.d.ts +32 -23
- package/dist/types/src/components/Popover/Popover.d.ts.map +1 -1
- package/dist/types/src/components/ScrollArea/ScrollArea.d.ts +31 -25
- package/dist/types/src/components/ScrollArea/ScrollArea.d.ts.map +1 -1
- package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts +62 -9
- package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts.map +1 -1
- package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts +23 -7
- package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts.map +1 -1
- package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts +6 -2
- package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts.map +1 -1
- package/dist/types/src/components/Select/Select.d.ts.map +1 -1
- package/dist/types/src/components/Select/Select.stories.d.ts +2 -2
- package/dist/types/src/components/Select/Select.stories.d.ts.map +1 -1
- package/dist/types/src/components/Separator/Separator.d.ts +3 -3
- package/dist/types/src/components/Separator/Separator.d.ts.map +1 -1
- package/dist/types/src/components/Skeleton/Skeleton.d.ts +12 -0
- package/dist/types/src/components/Skeleton/Skeleton.d.ts.map +1 -0
- package/dist/types/src/components/Skeleton/Skeleton.stories.d.ts +17 -0
- package/dist/types/src/components/Skeleton/Skeleton.stories.d.ts.map +1 -0
- package/dist/types/src/components/Skeleton/index.d.ts +2 -0
- package/dist/types/src/components/Skeleton/index.d.ts.map +1 -0
- package/dist/types/src/components/Splitter/Splitter.d.ts +37 -0
- package/dist/types/src/components/Splitter/Splitter.d.ts.map +1 -0
- package/dist/types/src/components/Splitter/Splitter.stories.d.ts +7 -0
- package/dist/types/src/components/Splitter/Splitter.stories.d.ts.map +1 -0
- package/dist/types/src/components/Splitter/index.d.ts +2 -0
- package/dist/types/src/components/Splitter/index.d.ts.map +1 -0
- package/dist/types/src/components/Status/Status.d.ts +3 -4
- package/dist/types/src/components/Status/Status.d.ts.map +1 -1
- package/dist/types/src/components/Status/Status.stories.d.ts +4 -2
- 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 +0 -5
- package/dist/types/src/components/Tag/Tag.stories.d.ts.map +1 -1
- package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts +2 -1
- package/dist/types/src/components/ThemeProvider/ThemeProvider.d.ts.map +1 -1
- package/dist/types/src/components/ThemeProvider/ThemeProvider.stories.d.ts +12 -0
- package/dist/types/src/components/ThemeProvider/ThemeProvider.stories.d.ts.map +1 -0
- package/dist/types/src/components/Toast/Toast.d.ts +15 -15
- package/dist/types/src/components/Toast/Toast.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.d.ts +37 -11
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/types/src/components/Tooltip/Tooltip.d.ts +9 -9
- package/dist/types/src/components/Tooltip/Tooltip.d.ts.map +1 -1
- package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts +2 -2
- package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +9 -4
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/exemplars/generics.stories.d.ts +23 -0
- package/dist/types/src/exemplars/generics.stories.d.ts.map +1 -0
- package/dist/types/src/exemplars/slot.stories.d.ts +15 -0
- package/dist/types/src/exemplars/slot.stories.d.ts.map +1 -0
- package/dist/types/src/exemplars/tabster.stories.d.ts +8 -0
- package/dist/types/src/exemplars/tabster.stories.d.ts.map +1 -0
- package/dist/types/src/exemplars/virtualizer.stories.d.ts +11 -0
- package/dist/types/src/exemplars/virtualizer.stories.d.ts.map +1 -0
- 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/useDensityContext.d.ts +1 -1
- package/dist/types/src/hooks/useDensityContext.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/playground/Controls.stories.d.ts.map +1 -1
- package/dist/types/src/playground/Custom.stories.d.ts.map +1 -1
- package/dist/types/src/primitives/Column/Column.d.ts +51 -0
- package/dist/types/src/primitives/Column/Column.d.ts.map +1 -0
- package/dist/types/src/primitives/Column/Column.stories.d.ts +25 -0
- package/dist/types/src/primitives/Column/Column.stories.d.ts.map +1 -0
- package/dist/types/src/primitives/Column/index.d.ts +2 -0
- package/dist/types/src/primitives/Column/index.d.ts.map +1 -0
- package/dist/types/src/primitives/Container/Container.d.ts +11 -0
- package/dist/types/src/primitives/Container/Container.d.ts.map +1 -0
- package/dist/types/src/primitives/Container/Container.stories.d.ts +6 -0
- package/dist/types/src/primitives/Container/Container.stories.d.ts.map +1 -0
- package/dist/types/src/primitives/Container/index.d.ts +2 -0
- package/dist/types/src/primitives/Container/index.d.ts.map +1 -0
- package/dist/types/src/primitives/Flex/Flex.d.ts +15 -0
- package/dist/types/src/primitives/Flex/Flex.d.ts.map +1 -0
- package/dist/types/src/primitives/Flex/Flex.stories.d.ts +8 -0
- package/dist/types/src/primitives/Flex/Flex.stories.d.ts.map +1 -0
- package/dist/types/src/primitives/Flex/index.d.ts +2 -0
- package/dist/types/src/primitives/Flex/index.d.ts.map +1 -0
- package/dist/types/src/primitives/Grid/Grid.d.ts +14 -0
- package/dist/types/src/primitives/Grid/Grid.d.ts.map +1 -0
- package/dist/types/src/primitives/Grid/Grid.stories.d.ts +8 -0
- package/dist/types/src/primitives/Grid/Grid.stories.d.ts.map +1 -0
- package/dist/types/src/primitives/Grid/index.d.ts +2 -0
- package/dist/types/src/primitives/Grid/index.d.ts.map +1 -0
- package/dist/types/src/primitives/Panel/Panel.d.ts +46 -0
- package/dist/types/src/primitives/Panel/Panel.d.ts.map +1 -0
- package/dist/types/src/primitives/Panel/Panel.stories.d.ts +6 -0
- package/dist/types/src/primitives/Panel/Panel.stories.d.ts.map +1 -0
- package/dist/types/src/primitives/Panel/index.d.ts +2 -0
- package/dist/types/src/primitives/Panel/index.d.ts.map +1 -0
- package/dist/types/src/primitives/index.d.ts +6 -0
- package/dist/types/src/primitives/index.d.ts.map +1 -0
- package/dist/types/src/testing/Loading.d.ts +9 -0
- package/dist/types/src/testing/Loading.d.ts.map +1 -0
- package/dist/types/src/testing/decorators/withLayout.d.ts +1 -1
- package/dist/types/src/testing/decorators/withLayout.d.ts.map +1 -1
- package/dist/types/src/testing/decorators/withLayoutVariants.d.ts.map +1 -1
- package/dist/types/src/testing/decorators/withTheme.d.ts +3 -2
- package/dist/types/src/testing/decorators/withTheme.d.ts.map +1 -1
- package/dist/types/src/testing/index.d.ts +1 -0
- package/dist/types/src/testing/index.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +11 -0
- package/dist/types/src/translations.d.ts.map +1 -0
- package/dist/types/src/util/usePx.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +25 -21
- package/src/components/Avatars/Avatar.stories.tsx +7 -8
- package/src/components/Avatars/Avatar.tsx +5 -12
- package/src/components/Avatars/AvatarGroup.stories.tsx +2 -2
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +3 -3
- package/src/components/Breadcrumb/Breadcrumb.tsx +11 -37
- package/src/components/Button/Button.stories.tsx +3 -3
- package/src/components/Button/Button.tsx +11 -25
- package/src/components/Button/IconButton.stories.tsx +4 -4
- package/src/components/Button/IconButton.tsx +2 -3
- package/src/components/Button/Toggle.stories.tsx +2 -2
- package/src/components/Button/Toggle.tsx +4 -4
- package/src/components/Button/ToggleGroup.stories.tsx +2 -2
- package/src/components/Button/ToggleGroup.tsx +12 -16
- package/src/components/Card/Card.stories.tsx +151 -0
- package/src/components/Card/Card.tsx +394 -0
- package/src/components/Card/index.ts +5 -0
- package/src/components/Clipboard/CopyButton.tsx +3 -3
- package/src/components/Dialog/AlertDialog.stories.tsx +16 -16
- package/src/components/Dialog/AlertDialog.tsx +121 -82
- package/src/components/Dialog/Dialog.stories.tsx +98 -17
- package/src/components/Dialog/Dialog.tsx +108 -87
- package/src/components/ErrorFallback/ErrorFallback.stories.tsx +50 -0
- package/src/components/ErrorFallback/ErrorFallback.tsx +70 -0
- package/src/components/ErrorFallback/ErrorStack.tsx +80 -0
- package/src/components/ErrorFallback/ThrowError.tsx +37 -0
- package/src/components/ErrorFallback/index.ts +9 -0
- package/src/components/Focus/AUDIT.md +43 -0
- package/src/components/Focus/Focus.stories.tsx +230 -0
- package/src/components/Focus/Focus.tsx +201 -0
- package/src/components/Focus/index.ts +5 -0
- package/src/components/Icon/Icon.stories.tsx +45 -14
- package/src/components/Icon/Icon.tsx +6 -2
- package/src/components/Image/Image.stories.tsx +86 -0
- package/src/components/Image/Image.tsx +223 -0
- package/src/components/Image/index.ts +5 -0
- package/src/components/Input/Input.stories.tsx +20 -39
- package/src/components/Input/Input.tsx +24 -69
- package/src/components/Link/Link.stories.tsx +2 -2
- package/src/components/Link/Link.tsx +2 -2
- package/src/components/List/List.stories.tsx +15 -22
- package/src/components/List/List.tsx +15 -18
- package/src/components/List/ListDropIndicator.tsx +7 -7
- package/src/components/List/Tree.stories.tsx +5 -5
- package/src/components/List/TreeDropIndicator.tsx +6 -6
- package/src/components/List/Treegrid.stories.tsx +3 -3
- package/src/components/List/Treegrid.tsx +10 -15
- package/src/components/Main/Main.stories.tsx +6 -95
- package/src/components/Main/Main.tsx +61 -211
- package/src/components/Menu/ContextMenu.stories.tsx +2 -2
- package/src/components/Menu/ContextMenu.tsx +9 -33
- package/src/components/Menu/DropdownMenu.stories.tsx +2 -2
- package/src/components/Menu/DropdownMenu.tsx +58 -52
- package/src/components/Message/Message.stories.tsx +27 -12
- package/src/components/Message/Message.tsx +14 -30
- package/src/components/Popover/Popover.stories.tsx +4 -4
- package/src/components/Popover/Popover.tsx +62 -59
- package/src/components/ScrollArea/ScrollArea.stories.tsx +213 -73
- package/src/components/ScrollArea/ScrollArea.tsx +85 -113
- package/src/components/ScrollArea/index.ts +1 -1
- package/src/components/ScrollContainer/ScrollContainer.stories.tsx +43 -23
- package/src/components/ScrollContainer/ScrollContainer.tsx +174 -87
- package/src/components/Select/Select.stories.tsx +4 -4
- package/src/components/Select/Select.tsx +11 -27
- package/src/components/Separator/Separator.tsx +5 -8
- package/src/components/Skeleton/Skeleton.stories.tsx +52 -0
- package/src/components/Skeleton/Skeleton.tsx +26 -0
- package/src/components/Skeleton/index.ts +5 -0
- package/src/components/Splitter/Splitter.stories.tsx +83 -0
- package/src/components/Splitter/Splitter.tsx +140 -0
- package/src/components/Splitter/index.ts +5 -0
- package/src/components/Status/Status.stories.tsx +21 -17
- package/src/components/Status/Status.tsx +10 -7
- package/src/components/Tag/Tag.stories.tsx +4 -9
- package/src/components/Tag/Tag.tsx +2 -7
- package/src/components/ThemeProvider/ThemeProvider.stories.tsx +32 -0
- package/src/components/ThemeProvider/ThemeProvider.tsx +9 -6
- package/src/components/Toast/Toast.stories.tsx +2 -2
- package/src/components/Toast/Toast.tsx +22 -41
- package/src/components/Toolbar/Toolbar.stories.tsx +2 -2
- package/src/components/Toolbar/Toolbar.tsx +171 -25
- package/src/components/Tooltip/Tooltip.stories.tsx +16 -14
- package/src/components/Tooltip/Tooltip.tsx +18 -18
- package/src/components/index.ts +10 -5
- package/src/exemplars/generics.stories.tsx +41 -0
- package/src/exemplars/slot.stories.tsx +117 -0
- package/src/exemplars/tabster.stories.tsx +127 -0
- package/src/exemplars/virtualizer.stories.tsx +137 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useDensityContext.ts +2 -2
- package/src/index.ts +1 -0
- package/src/playground/Controls.stories.tsx +3 -10
- package/src/playground/Custom.stories.tsx +11 -21
- package/src/playground/Typography.stories.tsx +3 -3
- package/src/primitives/Column/AUDIT.md +354 -0
- package/src/primitives/Column/Column.stories.tsx +183 -0
- package/src/primitives/Column/Column.tsx +169 -0
- package/src/primitives/Column/index.ts +5 -0
- package/src/primitives/Container/Container.stories.tsx +30 -0
- package/src/primitives/Container/Container.tsx +19 -0
- package/src/primitives/Container/index.ts +5 -0
- package/src/primitives/Flex/Flex.stories.tsx +58 -0
- package/src/primitives/Flex/Flex.tsx +24 -0
- package/src/primitives/Flex/index.ts +5 -0
- package/src/primitives/Grid/Grid.stories.tsx +57 -0
- package/src/primitives/Grid/Grid.tsx +30 -0
- package/src/primitives/Grid/index.ts +5 -0
- package/src/primitives/Panel/Panel.stories.tsx +67 -0
- package/src/primitives/Panel/Panel.tsx +114 -0
- package/src/primitives/Panel/index.ts +5 -0
- package/src/primitives/index.ts +9 -0
- package/src/testing/Loading.tsx +26 -0
- package/src/testing/decorators/withLayout.tsx +21 -7
- package/src/testing/decorators/withLayoutVariants.tsx +18 -21
- package/src/testing/decorators/withTheme.tsx +24 -19
- package/src/testing/index.ts +2 -0
- package/src/translations.ts +19 -0
- package/src/util/usePx.ts +1 -0
- package/dist/lib/browser/chunk-CEKVHJ27.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-2NHEX4AD.mjs.map +0 -7
- package/dist/types/src/components/AnchoredOverflow/AnchoredOverflow.d.ts +0 -15
- package/dist/types/src/components/AnchoredOverflow/AnchoredOverflow.d.ts.map +0 -1
- package/dist/types/src/components/AnchoredOverflow/index.d.ts +0 -2
- package/dist/types/src/components/AnchoredOverflow/index.d.ts.map +0 -1
- package/src/components/AnchoredOverflow/AnchoredOverflow.tsx +0 -59
- package/src/components/AnchoredOverflow/index.ts +0 -5
|
@@ -2,24 +2,8 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
5
6
|
import { createContext } from '@radix-ui/react-context';
|
|
6
|
-
import {
|
|
7
|
-
DialogClose as DialogClosePrimitive,
|
|
8
|
-
type DialogCloseProps as DialogClosePrimitiveProps,
|
|
9
|
-
DialogContent as DialogContentPrimitive,
|
|
10
|
-
DialogDescription as DialogDescriptionPrimitive,
|
|
11
|
-
type DialogDescriptionProps as DialogDescriptionPrimitiveProps,
|
|
12
|
-
DialogOverlay as DialogOverlayPrimitive,
|
|
13
|
-
type DialogOverlayProps as DialogOverlayPrimitiveProps,
|
|
14
|
-
DialogPortal as DialogPortalPrimitive,
|
|
15
|
-
type DialogPortalProps as DialogPortalPrimitiveProps,
|
|
16
|
-
Root as DialogRootPrimitive,
|
|
17
|
-
type DialogProps as DialogRootPrimitiveProps,
|
|
18
|
-
DialogTitle as DialogTitlePrimitive,
|
|
19
|
-
type DialogTitleProps as DialogTitlePrimitiveProps,
|
|
20
|
-
DialogTrigger as DialogTriggerPrimitive,
|
|
21
|
-
type DialogTriggerProps as DialogTriggerPrimitiveProps,
|
|
22
|
-
} from '@radix-ui/react-dialog';
|
|
23
7
|
import React, {
|
|
24
8
|
type ComponentPropsWithRef,
|
|
25
9
|
type ForwardRefExoticComponent,
|
|
@@ -32,19 +16,22 @@ import { useTranslation } from 'react-i18next';
|
|
|
32
16
|
import { type DialogSize, osTranslations } from '@dxos/ui-theme';
|
|
33
17
|
|
|
34
18
|
import { useThemeContext } from '../../hooks';
|
|
19
|
+
import { Column } from '../../primitives';
|
|
35
20
|
import { type ThemedClassName } from '../../util';
|
|
36
|
-
import { IconButton
|
|
21
|
+
import { IconButton } from '../Button';
|
|
37
22
|
import { ElevationProvider } from '../ElevationProvider';
|
|
23
|
+
import { slottable } from '@dxos/ui-theme';
|
|
24
|
+
import { type SlottableProps } from '@dxos/ui-types';
|
|
38
25
|
|
|
39
26
|
//
|
|
40
27
|
// Root
|
|
41
28
|
//
|
|
42
29
|
|
|
43
|
-
type DialogRootProps =
|
|
30
|
+
type DialogRootProps = DialogPrimitive.DialogProps;
|
|
44
31
|
|
|
45
32
|
const DialogRoot: FunctionComponent<DialogRootProps> = (props) => (
|
|
46
33
|
<ElevationProvider elevation='dialog'>
|
|
47
|
-
<
|
|
34
|
+
<DialogPrimitive.Root {...props} />
|
|
48
35
|
</ElevationProvider>
|
|
49
36
|
);
|
|
50
37
|
|
|
@@ -52,17 +39,17 @@ const DialogRoot: FunctionComponent<DialogRootProps> = (props) => (
|
|
|
52
39
|
// Trigger
|
|
53
40
|
//
|
|
54
41
|
|
|
55
|
-
type DialogTriggerProps =
|
|
42
|
+
type DialogTriggerProps = DialogPrimitive.DialogTriggerProps;
|
|
56
43
|
|
|
57
|
-
const DialogTrigger: FunctionComponent<DialogTriggerProps> =
|
|
44
|
+
const DialogTrigger: FunctionComponent<DialogTriggerProps> = DialogPrimitive.Trigger;
|
|
58
45
|
|
|
59
46
|
//
|
|
60
47
|
// Portal
|
|
61
48
|
//
|
|
62
49
|
|
|
63
|
-
type DialogPortalProps =
|
|
50
|
+
type DialogPortalProps = DialogPrimitive.DialogPortalProps;
|
|
64
51
|
|
|
65
|
-
const DialogPortal: FunctionComponent<DialogPortalProps> =
|
|
52
|
+
const DialogPortal: FunctionComponent<DialogPortalProps> = DialogPrimitive.Portal;
|
|
66
53
|
|
|
67
54
|
//
|
|
68
55
|
// Overlay
|
|
@@ -77,21 +64,23 @@ const [OverlayLayoutProvider, useOverlayLayoutContext] = createContext<OverlayLa
|
|
|
77
64
|
{},
|
|
78
65
|
);
|
|
79
66
|
|
|
80
|
-
type DialogOverlayProps = ThemedClassName<
|
|
67
|
+
type DialogOverlayProps = ThemedClassName<
|
|
68
|
+
DialogPrimitive.DialogOverlayProps & { blockAlign?: 'center' | 'start' | 'end' }
|
|
69
|
+
>;
|
|
81
70
|
|
|
82
71
|
const DialogOverlay: ForwardRefExoticComponent<DialogOverlayProps> = forwardRef<HTMLDivElement, DialogOverlayProps>(
|
|
83
72
|
({ classNames, children, blockAlign, ...props }, forwardedRef) => {
|
|
84
73
|
const { tx } = useThemeContext();
|
|
85
74
|
|
|
86
75
|
return (
|
|
87
|
-
<
|
|
76
|
+
<DialogPrimitive.Overlay
|
|
88
77
|
{...props}
|
|
89
|
-
className={tx('dialog.overlay', 'dialog__overlay', {}, classNames)}
|
|
90
|
-
ref={forwardedRef}
|
|
91
78
|
data-block-align={blockAlign}
|
|
79
|
+
className={tx('dialog.overlay', {}, classNames)}
|
|
80
|
+
ref={forwardedRef}
|
|
92
81
|
>
|
|
93
82
|
<OverlayLayoutProvider inOverlayLayout>{children}</OverlayLayoutProvider>
|
|
94
|
-
</
|
|
83
|
+
</DialogPrimitive.Overlay>
|
|
95
84
|
);
|
|
96
85
|
},
|
|
97
86
|
);
|
|
@@ -104,32 +93,36 @@ DialogOverlay.displayName = DIALOG_OVERLAY_NAME;
|
|
|
104
93
|
|
|
105
94
|
const DIALOG_CONTENT_NAME = 'DialogContent';
|
|
106
95
|
|
|
107
|
-
type DialogContentProps = ThemedClassName<ComponentPropsWithRef<typeof
|
|
96
|
+
type DialogContentProps = ThemedClassName<ComponentPropsWithRef<typeof DialogPrimitive.Content>> & {
|
|
108
97
|
size?: DialogSize;
|
|
109
98
|
inOverlayLayout?: boolean;
|
|
110
99
|
};
|
|
111
100
|
|
|
112
101
|
const DialogContent: ForwardRefExoticComponent<DialogContentProps> = forwardRef<HTMLDivElement, DialogContentProps>(
|
|
113
|
-
({ classNames, children, size, inOverlayLayout: propsInOverlayLayout, ...props }, forwardedRef) => {
|
|
102
|
+
({ classNames, children, size = 'md', inOverlayLayout: propsInOverlayLayout, ...props }, forwardedRef) => {
|
|
114
103
|
const { tx } = useThemeContext();
|
|
115
104
|
const { inOverlayLayout } = useOverlayLayoutContext(DIALOG_CONTENT_NAME);
|
|
116
105
|
|
|
117
106
|
return (
|
|
118
|
-
<
|
|
107
|
+
<DialogPrimitive.Content
|
|
108
|
+
{...props}
|
|
119
109
|
// NOTE: Radix warning unless set to undefined.
|
|
120
110
|
// https://www.radix-ui.com/primitives/docs/components/dialog#description
|
|
121
111
|
aria-describedby={undefined}
|
|
122
|
-
{...props}
|
|
123
112
|
className={tx(
|
|
124
113
|
'dialog.content',
|
|
125
|
-
|
|
126
|
-
|
|
114
|
+
{
|
|
115
|
+
size,
|
|
116
|
+
inOverlayLayout: propsInOverlayLayout || inOverlayLayout,
|
|
117
|
+
},
|
|
127
118
|
classNames,
|
|
128
119
|
)}
|
|
129
120
|
ref={forwardedRef}
|
|
130
121
|
>
|
|
131
|
-
|
|
132
|
-
|
|
122
|
+
<Column.Root classNames='dx-expander' gutter='sm'>
|
|
123
|
+
{children}
|
|
124
|
+
</Column.Root>
|
|
125
|
+
</DialogPrimitive.Content>
|
|
133
126
|
);
|
|
134
127
|
},
|
|
135
128
|
);
|
|
@@ -140,35 +133,36 @@ DialogContent.displayName = DIALOG_CONTENT_NAME;
|
|
|
140
133
|
// Header
|
|
141
134
|
//
|
|
142
135
|
|
|
143
|
-
type DialogHeaderProps =
|
|
136
|
+
type DialogHeaderProps = PropsWithChildren;
|
|
144
137
|
|
|
145
|
-
const DialogHeader: ForwardRefExoticComponent<
|
|
146
|
-
({
|
|
138
|
+
const DialogHeader: ForwardRefExoticComponent<DialogHeaderProps> = forwardRef<HTMLHeadingElement, DialogHeaderProps>(
|
|
139
|
+
({ children }, forwardedRef) => {
|
|
147
140
|
const { tx } = useThemeContext();
|
|
148
141
|
return (
|
|
149
|
-
<
|
|
150
|
-
{
|
|
151
|
-
|
|
152
|
-
className={tx('dialog.header', 'dialog__header', { srOnly }, classNames)}
|
|
153
|
-
ref={forwardedRef}
|
|
154
|
-
/>
|
|
142
|
+
<Column.Row className={tx('dialog.header')} center ref={forwardedRef}>
|
|
143
|
+
{children}
|
|
144
|
+
</Column.Row>
|
|
155
145
|
);
|
|
156
146
|
},
|
|
157
147
|
);
|
|
158
148
|
|
|
159
149
|
//
|
|
160
|
-
//
|
|
150
|
+
// CloseIconButton
|
|
161
151
|
//
|
|
162
152
|
|
|
163
|
-
type
|
|
153
|
+
type DialogCloseIconButtonProps = { label?: string };
|
|
164
154
|
|
|
165
|
-
const
|
|
166
|
-
({
|
|
167
|
-
const {
|
|
155
|
+
const DialogCloseIconButton = forwardRef<HTMLButtonElement, DialogCloseIconButtonProps>(
|
|
156
|
+
({ label, ...props }, forwardedRef) => {
|
|
157
|
+
const { t } = useTranslation(osTranslations);
|
|
168
158
|
return (
|
|
169
|
-
<
|
|
159
|
+
<IconButton
|
|
170
160
|
{...props}
|
|
171
|
-
|
|
161
|
+
label={label ?? t('close dialog label')}
|
|
162
|
+
icon='ph--x--regular'
|
|
163
|
+
iconOnly
|
|
164
|
+
size={4}
|
|
165
|
+
variant='ghost'
|
|
172
166
|
ref={forwardedRef}
|
|
173
167
|
/>
|
|
174
168
|
);
|
|
@@ -176,57 +170,80 @@ const DialogTitle: ForwardRefExoticComponent<DialogTitleProps> = forwardRef<HTML
|
|
|
176
170
|
);
|
|
177
171
|
|
|
178
172
|
//
|
|
179
|
-
//
|
|
173
|
+
// Body
|
|
180
174
|
//
|
|
181
175
|
|
|
182
|
-
type
|
|
176
|
+
type DialogBodyProps = SlottableProps;
|
|
183
177
|
|
|
184
|
-
const
|
|
185
|
-
HTMLParagraphElement,
|
|
186
|
-
DialogDescriptionProps
|
|
187
|
-
>(({ classNames, srOnly, ...props }, forwardedRef) => {
|
|
178
|
+
const DialogBody = slottable<HTMLDivElement>(({ children, asChild, ...props }, forwardedRef) => {
|
|
188
179
|
const { tx } = useThemeContext();
|
|
189
180
|
return (
|
|
190
|
-
<
|
|
191
|
-
{
|
|
192
|
-
|
|
193
|
-
ref={forwardedRef}
|
|
194
|
-
/>
|
|
181
|
+
<Column.Content {...props} asChild={asChild} className={tx('dialog.body', {})} ref={forwardedRef}>
|
|
182
|
+
{children}
|
|
183
|
+
</Column.Content>
|
|
195
184
|
);
|
|
196
185
|
});
|
|
197
186
|
|
|
198
187
|
//
|
|
199
|
-
//
|
|
188
|
+
// Title
|
|
200
189
|
//
|
|
201
190
|
|
|
202
|
-
type
|
|
191
|
+
type DialogTitleProps = ThemedClassName<DialogPrimitive.DialogTitleProps> & { srOnly?: boolean };
|
|
203
192
|
|
|
204
|
-
const
|
|
193
|
+
const DialogTitle = forwardRef<HTMLHeadingElement, DialogTitleProps>(
|
|
194
|
+
({ classNames, srOnly, ...props }, forwardedRef) => {
|
|
195
|
+
const { tx } = useThemeContext();
|
|
196
|
+
return (
|
|
197
|
+
<DialogPrimitive.Title {...props} className={tx('dialog.title', { srOnly }, classNames)} ref={forwardedRef} />
|
|
198
|
+
);
|
|
199
|
+
},
|
|
200
|
+
);
|
|
205
201
|
|
|
206
202
|
//
|
|
207
|
-
//
|
|
203
|
+
// Description
|
|
208
204
|
//
|
|
209
205
|
|
|
210
|
-
type
|
|
206
|
+
type DialogDescriptionProps = ThemedClassName<DialogPrimitive.DialogDescriptionProps> & { srOnly?: boolean };
|
|
211
207
|
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
208
|
+
const DialogDescription = forwardRef<HTMLParagraphElement, DialogDescriptionProps>(
|
|
209
|
+
({ classNames, srOnly, ...props }, forwardedRef) => {
|
|
210
|
+
const { tx } = useThemeContext();
|
|
211
|
+
return (
|
|
212
|
+
<DialogPrimitive.Description
|
|
213
|
+
{...props}
|
|
214
|
+
className={tx('dialog.description', { srOnly }, classNames)}
|
|
215
|
+
ref={forwardedRef}
|
|
216
|
+
/>
|
|
217
|
+
);
|
|
218
|
+
},
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
//
|
|
222
|
+
// ActionBar
|
|
223
|
+
//
|
|
224
|
+
|
|
225
|
+
type DialogActionBarProps = ThemedClassName<PropsWithChildren>;
|
|
226
|
+
|
|
227
|
+
const DialogActionBar = forwardRef<HTMLDivElement, DialogActionBarProps>(
|
|
228
|
+
({ children, classNames, ...props }, forwardedRef) => {
|
|
229
|
+
const { tx } = useThemeContext();
|
|
230
|
+
return (
|
|
231
|
+
<Column.Row center>
|
|
232
|
+
<div {...props} className={tx('dialog.actionbar', {}, classNames)} ref={forwardedRef}>
|
|
233
|
+
{children}
|
|
234
|
+
</div>
|
|
235
|
+
</Column.Row>
|
|
236
|
+
);
|
|
237
|
+
},
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
//
|
|
241
|
+
// Close
|
|
242
|
+
//
|
|
243
|
+
|
|
244
|
+
type DialogCloseProps = DialogPrimitive.DialogCloseProps;
|
|
245
|
+
|
|
246
|
+
const DialogClose: FunctionComponent<DialogCloseProps> = DialogPrimitive.Close;
|
|
230
247
|
|
|
231
248
|
//
|
|
232
249
|
// Dialog
|
|
@@ -239,8 +256,10 @@ export const Dialog = {
|
|
|
239
256
|
Overlay: DialogOverlay,
|
|
240
257
|
Content: DialogContent,
|
|
241
258
|
Header: DialogHeader,
|
|
259
|
+
Body: DialogBody,
|
|
242
260
|
Title: DialogTitle,
|
|
243
261
|
Description: DialogDescription,
|
|
262
|
+
ActionBar: DialogActionBar,
|
|
244
263
|
Close: DialogClose,
|
|
245
264
|
CloseIconButton: DialogCloseIconButton,
|
|
246
265
|
};
|
|
@@ -252,8 +271,10 @@ export type {
|
|
|
252
271
|
DialogOverlayProps,
|
|
253
272
|
DialogContentProps,
|
|
254
273
|
DialogHeaderProps,
|
|
274
|
+
DialogBodyProps,
|
|
255
275
|
DialogTitleProps,
|
|
256
276
|
DialogDescriptionProps,
|
|
277
|
+
DialogActionBarProps,
|
|
257
278
|
DialogCloseProps,
|
|
258
279
|
DialogCloseIconButtonProps,
|
|
259
280
|
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
|
+
import React from 'react';
|
|
7
|
+
|
|
8
|
+
import { ErrorBoundary } from '@dxos/react-error-boundary';
|
|
9
|
+
|
|
10
|
+
import { withLayout, withTheme } from '../../testing';
|
|
11
|
+
|
|
12
|
+
import { ErrorFallback } from './ErrorFallback';
|
|
13
|
+
import { ThrowError } from './ThrowError';
|
|
14
|
+
|
|
15
|
+
const BasicStory = () => {
|
|
16
|
+
return (
|
|
17
|
+
<ErrorBoundary name='story' FallbackComponent={ErrorFallback}>
|
|
18
|
+
<ThrowError />
|
|
19
|
+
</ErrorBoundary>
|
|
20
|
+
);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const StringErrorStory = () => {
|
|
24
|
+
return <ErrorFallback error='This is a string error message' data={{ context: 'story' }} />;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const meta: Meta = {
|
|
28
|
+
title: 'ui/react-ui-core/components/ErrorFallback',
|
|
29
|
+
component: ErrorFallback,
|
|
30
|
+
decorators: [withTheme(), withLayout({ layout: 'column' })],
|
|
31
|
+
parameters: {
|
|
32
|
+
layout: 'fullscreen',
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export default meta;
|
|
37
|
+
|
|
38
|
+
type Story = StoryObj<typeof meta>;
|
|
39
|
+
|
|
40
|
+
export const Default: Story = {
|
|
41
|
+
render: BasicStory,
|
|
42
|
+
play: async () => {
|
|
43
|
+
// This story intentionally renders an ErrorBoundary fallback; clear the smoke-test error flag.
|
|
44
|
+
(window as any).__ERROR_BOUNDARY_ERRORS__ = [];
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const StringError: Story = {
|
|
49
|
+
render: StringErrorStory,
|
|
50
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React, { type PropsWithChildren } from 'react';
|
|
6
|
+
import { type FallbackProps } from 'react-error-boundary';
|
|
7
|
+
|
|
8
|
+
import { safeStringify } from '@dxos/util';
|
|
9
|
+
|
|
10
|
+
import { ErrorStack } from './ErrorStack';
|
|
11
|
+
|
|
12
|
+
export type ErrorFallbackProps = PropsWithChildren<Pick<FallbackProps, 'error'> & { title?: string; data?: any }>;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Themed fallback component for `ErrorBoundary`.
|
|
16
|
+
*/
|
|
17
|
+
export const ErrorFallback = ({ children, error, title, data }: ErrorFallbackProps) => {
|
|
18
|
+
const isDev = process.env.NODE_ENV === 'development';
|
|
19
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<div role='alert' data-testid='error-boundary-fallback' className='flex flex-col p-4 gap-4 overflow-auto'>
|
|
23
|
+
<h1 className='text-lg text-info-text'>{title ?? 'Runtime Error'}</h1>
|
|
24
|
+
<p>{message}</p>
|
|
25
|
+
|
|
26
|
+
{isDev && error instanceof Error && (
|
|
27
|
+
<Section
|
|
28
|
+
title='Stack'
|
|
29
|
+
onClick={() => {
|
|
30
|
+
const text = error instanceof Error ? (error.stack ?? error.message) : String(error);
|
|
31
|
+
void navigator.clipboard.writeText(text);
|
|
32
|
+
}}
|
|
33
|
+
>
|
|
34
|
+
<ErrorStack error={error} />
|
|
35
|
+
</Section>
|
|
36
|
+
)}
|
|
37
|
+
|
|
38
|
+
{data && (
|
|
39
|
+
<Section
|
|
40
|
+
title='Data'
|
|
41
|
+
onClick={() => {
|
|
42
|
+
void navigator.clipboard.writeText(JSON.stringify(data, undefined, 2));
|
|
43
|
+
}}
|
|
44
|
+
>
|
|
45
|
+
<pre className='overflow-x-auto text-xs'>{safeStringify(data, undefined, 2)}</pre>
|
|
46
|
+
</Section>
|
|
47
|
+
)}
|
|
48
|
+
|
|
49
|
+
{children}
|
|
50
|
+
</div>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const Section = ({ children, title, onClick }: PropsWithChildren<{ title?: string; onClick?: () => void }>) => {
|
|
55
|
+
return (
|
|
56
|
+
<div className='flex flex-col gap-1'>
|
|
57
|
+
{onClick && (
|
|
58
|
+
<button
|
|
59
|
+
type='button'
|
|
60
|
+
onClick={onClick}
|
|
61
|
+
className='flex items-center gap-1 text-xs text-subdued hover:text-primary-500 transition-colors'
|
|
62
|
+
title={`Copy ${title}`}
|
|
63
|
+
>
|
|
64
|
+
<h2 className='text-xs uppercase text-subdued'>{title}</h2>
|
|
65
|
+
</button>
|
|
66
|
+
)}
|
|
67
|
+
{children}
|
|
68
|
+
</div>
|
|
69
|
+
);
|
|
70
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import ErrorStackParser from 'error-stack-parser';
|
|
6
|
+
import React from 'react';
|
|
7
|
+
|
|
8
|
+
import { mx } from '@dxos/ui-theme';
|
|
9
|
+
|
|
10
|
+
type LocalFrame = { href: string; fileName: string };
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Renders a parsed error stack trace with tree connector symbols and clickable vscode:// links for local frames.
|
|
14
|
+
*/
|
|
15
|
+
export const ErrorStack = ({ error }: { error: Error }) => {
|
|
16
|
+
const frames = ErrorStackParser.parse(error);
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<div className='font-mono text-sm'>
|
|
20
|
+
{frames.map((frame, i) => {
|
|
21
|
+
const isLast = i === frames.length - 1;
|
|
22
|
+
const local = frame.fileName
|
|
23
|
+
? parseLocalFrame(frame.fileName, frame.lineNumber, frame.columnNumber)
|
|
24
|
+
: undefined;
|
|
25
|
+
const name = frame.functionName ?? '<anonymous>';
|
|
26
|
+
return (
|
|
27
|
+
<div
|
|
28
|
+
key={i}
|
|
29
|
+
className={mx(
|
|
30
|
+
'grid grid-cols-[16px_1fr_auto_auto] items-stretch gap-x-2',
|
|
31
|
+
local && 'cursor-pointer hover:bg-hover-surface',
|
|
32
|
+
)}
|
|
33
|
+
>
|
|
34
|
+
{/* Tree connector: vertical line full-height + horizontal branch at midpoint */}
|
|
35
|
+
<div className='relative'>
|
|
36
|
+
<div
|
|
37
|
+
className={mx(
|
|
38
|
+
'absolute left-1/2 -translate-x-1/2 w-px bg-neutral-500',
|
|
39
|
+
isLast ? 'top-0 h-1/2' : 'inset-y-0',
|
|
40
|
+
)}
|
|
41
|
+
/>
|
|
42
|
+
<div className='absolute top-1/2 -translate-y-1/2 left-1/2 right-0 h-px bg-neutral-500' />
|
|
43
|
+
</div>
|
|
44
|
+
{local ? (
|
|
45
|
+
<a href={local.href} className='truncate self-center'>
|
|
46
|
+
{name}
|
|
47
|
+
</a>
|
|
48
|
+
) : (
|
|
49
|
+
<span className='text-subdued truncate self-center'>{name}</span>
|
|
50
|
+
)}
|
|
51
|
+
<span className='text-xs text-subdued truncate self-center'>{local?.fileName ?? ''}</span>
|
|
52
|
+
<span className='text-xs text-subdued text-right self-center'>
|
|
53
|
+
{local ? `${frame.lineNumber}:${frame.columnNumber}` : ''}
|
|
54
|
+
</span>
|
|
55
|
+
</div>
|
|
56
|
+
);
|
|
57
|
+
})}
|
|
58
|
+
</div>
|
|
59
|
+
);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Parses a Vite `/@fs/` URL into a `vscode://` deep link and short filename.
|
|
64
|
+
* Returns undefined if the URL cannot be resolved to a local file.
|
|
65
|
+
*/
|
|
66
|
+
const parseLocalFrame = (fileUrl: string, line?: number, col?: number): LocalFrame | undefined => {
|
|
67
|
+
try {
|
|
68
|
+
const { pathname } = new URL(fileUrl);
|
|
69
|
+
if (!pathname.startsWith('/@fs/')) {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
const localPath = pathname.slice(4); // /@fs/Users/... → /Users/...
|
|
73
|
+
return {
|
|
74
|
+
href: `vscode://file/${localPath}:${line ?? 1}:${col ?? 1}`,
|
|
75
|
+
fileName: pathname.split('/').pop() ?? localPath,
|
|
76
|
+
};
|
|
77
|
+
} catch {
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { useEffect, useState } from 'react';
|
|
6
|
+
|
|
7
|
+
export type ThrowErrorProps = {
|
|
8
|
+
error?: () => Error;
|
|
9
|
+
delay?: number;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Use this to debug the error boundary.
|
|
14
|
+
*/
|
|
15
|
+
export const ThrowError = ({ delay = 1_000, ...props }: ThrowErrorProps) => {
|
|
16
|
+
const [error, setError] = useState<Error>();
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (delay < 0) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const t = setTimeout(() => {
|
|
23
|
+
setError(generator({ delay, ...props }));
|
|
24
|
+
}, delay);
|
|
25
|
+
return () => clearTimeout(t);
|
|
26
|
+
}, [delay, generator]);
|
|
27
|
+
|
|
28
|
+
if (error) {
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return null;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const generator = ({ error, delay }: ThrowErrorProps) => {
|
|
36
|
+
return error?.() ?? new Error(`Error generated after ${delay}ms`);
|
|
37
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Focus
|
|
2
|
+
|
|
3
|
+
## Problem
|
|
4
|
+
|
|
5
|
+
Grid cells use `overflow-hidden` which clips outward CSS `ring` (box-shadow) and `outline` styles.
|
|
6
|
+
Using `border` for focus indicators creates doubled lines at grid cell boundaries.
|
|
7
|
+
Inset `box-shadow` alone is obscured by child elements with backgrounds (e.g., toolbar headers).
|
|
8
|
+
|
|
9
|
+
## Solution
|
|
10
|
+
|
|
11
|
+
Uses a `::after` pseudo-element overlay with `ring-inset` to paint the focus ring above all child content.
|
|
12
|
+
The pseudo-element is absolutely positioned, `pointer-events-none`, and inherits `border-radius`.
|
|
13
|
+
|
|
14
|
+
- **Default**: ring is transparent (invisible until focused).
|
|
15
|
+
- **`border` prop**: shows a CSS `border-separator` when unfocused (e.g., for grid cell edges).
|
|
16
|
+
- **Focus/active/error states**: ring color changes to the appropriate indicator color.
|
|
17
|
+
|
|
18
|
+
Both `Focus.Group` and `Focus.Item` support the `border` prop.
|
|
19
|
+
|
|
20
|
+
## Why `::after` overlay
|
|
21
|
+
|
|
22
|
+
| Approach | Clipped? | Obscured by children? | Notes |
|
|
23
|
+
| ------------------------ | -------- | --------------------- | --------------------------------------------------------------------- |
|
|
24
|
+
| `ring` (outward) | Yes | N/A | Extends outside bounds, clipped by parent `overflow-hidden`. |
|
|
25
|
+
| `ring-inset` | No | Yes | Inset box-shadow is part of background layer; children paint over it. |
|
|
26
|
+
| `::after` + `ring-inset` | No | No | Pseudo-element paints above children. Requires `position: relative`. |
|
|
27
|
+
|
|
28
|
+
## Relationship to `dx-focus-ring-inset-over-all`
|
|
29
|
+
|
|
30
|
+
The CSS class `dx-focus-ring-inset-over-all` (in `focus-ring.css`) uses the same `::after` technique
|
|
31
|
+
but only reacts to `:focus-visible`. `Focus.Group/Item` additionally support programmatic states
|
|
32
|
+
via `data-focus-state` (`active`, `error`).
|
|
33
|
+
|
|
34
|
+
## Clean-up
|
|
35
|
+
|
|
36
|
+
- [ ] Unify: extend `dx-focus-ring-inset-over-all` to support `data-focus-state` attributes,
|
|
37
|
+
then have `Focus.Group/Item` use the CSS class instead of inline Tailwind utilities.
|
|
38
|
+
Consumers: Plank, StackItem, Tabs, AttentionProvider, main sidebar.
|
|
39
|
+
|
|
40
|
+
## Audit
|
|
41
|
+
|
|
42
|
+
- [ ] Create a list of all container components (outside of `react-ui`) that directly use `overflow-hidden`;
|
|
43
|
+
Consider containers to be components that have `children` and expand (e.g., `grid`, `grow`, `h-full`, `w-full`).
|