@dxos/react-ui 0.8.4-main.bc674ce → 0.8.4-main.c351d160a8
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-EJSGYGYH.mjs} +117 -117
- package/dist/lib/browser/chunk-EJSGYGYH.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +2747 -1997
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +56 -32
- package/dist/lib/browser/testing/index.mjs.map +4 -4
- package/dist/lib/node-esm/{chunk-2NHEX4AD.mjs → chunk-B7MXDDMJ.mjs} +117 -117
- package/dist/lib/node-esm/chunk-B7MXDDMJ.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +2747 -1997
- 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 +56 -32
- 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 +107 -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 +26 -17
- 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 +25 -18
- package/dist/types/src/components/Dialog/Dialog.d.ts.map +1 -1
- package/dist/types/src/components/Dialog/Dialog.stories.d.ts +3 -6
- 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/Icon/Icon.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.map +1 -1
- 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 -49
- package/dist/types/src/components/Menu/DropdownMenu.d.ts.map +1 -1
- package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts +6 -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 +2 -3
- package/dist/types/src/components/Message/Message.stories.d.ts.map +1 -1
- package/dist/types/src/components/Popover/Popover.d.ts +28 -22
- package/dist/types/src/components/Popover/Popover.d.ts.map +1 -1
- package/dist/types/src/components/ScrollArea/ScrollArea.d.ts +21 -26
- package/dist/types/src/components/ScrollArea/ScrollArea.d.ts.map +1 -1
- package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts +41 -9
- package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts.map +1 -1
- package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts.map +1 -1
- package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts +6 -1
- 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/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 +32 -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.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 +1 -0
- 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 +33 -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.map +1 -1
- package/dist/types/src/components/index.d.ts +8 -4
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/exemplars/generics.stories.d.ts +18 -0
- package/dist/types/src/exemplars/generics.stories.d.ts.map +1 -0
- package/dist/types/src/exemplars/slot.stories.d.ts +14 -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/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/primitives/Column/Column.d.ts +26 -0
- package/dist/types/src/primitives/Column/Column.d.ts.map +1 -0
- package/dist/types/src/primitives/Column/Column.stories.d.ts +6 -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 +8 -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 +13 -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 +15 -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 +26 -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/tsconfig.tsbuildinfo +1 -1
- package/package.json +25 -21
- package/src/components/Avatars/Avatar.stories.tsx +5 -6
- 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 +8 -14
- 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 +390 -0
- package/src/components/Card/index.ts +5 -0
- package/src/components/Clipboard/CopyButton.tsx +3 -3
- package/src/components/Dialog/AlertDialog.stories.tsx +15 -15
- package/src/components/Dialog/AlertDialog.tsx +137 -54
- package/src/components/Dialog/Dialog.stories.tsx +40 -15
- package/src/components/Dialog/Dialog.tsx +94 -78
- 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/Icon/Icon.stories.tsx +2 -2
- package/src/components/Icon/Icon.tsx +3 -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 +11 -16
- package/src/components/List/ListDropIndicator.tsx +7 -7
- package/src/components/List/Tree.stories.tsx +4 -4
- 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 +56 -50
- package/src/components/Message/Message.stories.tsx +25 -10
- package/src/components/Message/Message.tsx +17 -29
- package/src/components/Popover/Popover.stories.tsx +4 -4
- package/src/components/Popover/Popover.tsx +61 -58
- package/src/components/ScrollArea/ScrollArea.stories.tsx +152 -76
- package/src/components/ScrollArea/ScrollArea.tsx +72 -116
- package/src/components/ScrollArea/index.ts +1 -1
- package/src/components/ScrollContainer/ScrollContainer.stories.tsx +41 -22
- package/src/components/ScrollContainer/ScrollContainer.tsx +18 -13
- package/src/components/Select/Select.stories.tsx +2 -2
- 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 +126 -0
- package/src/components/Splitter/index.ts +5 -0
- package/src/components/Status/Status.stories.tsx +21 -17
- package/src/components/Status/Status.tsx +2 -2
- 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 +4 -3
- 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 +166 -21
- package/src/components/Tooltip/Tooltip.stories.tsx +15 -13
- package/src/components/Tooltip/Tooltip.tsx +18 -18
- package/src/components/index.ts +9 -5
- package/src/exemplars/generics.stories.tsx +49 -0
- package/src/exemplars/slot.stories.tsx +107 -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/index.ts +1 -0
- package/src/playground/Controls.stories.tsx +3 -10
- package/src/playground/Custom.stories.tsx +11 -11
- package/src/playground/Typography.stories.tsx +3 -3
- package/src/primitives/Column/Column.stories.tsx +78 -0
- package/src/primitives/Column/Column.tsx +133 -0
- package/src/primitives/Column/index.ts +5 -0
- package/src/primitives/Container/Container.stories.tsx +30 -0
- package/src/primitives/Container/Container.tsx +22 -0
- package/src/primitives/Container/index.ts +5 -0
- package/src/primitives/Flex/Flex.stories.tsx +58 -0
- package/src/primitives/Flex/Flex.tsx +29 -0
- package/src/primitives/Flex/index.ts +5 -0
- package/src/primitives/Grid/Grid.stories.tsx +57 -0
- package/src/primitives/Grid/Grid.tsx +35 -0
- package/src/primitives/Grid/index.ts +5 -0
- package/src/primitives/Panel/Panel.stories.tsx +67 -0
- package/src/primitives/Panel/Panel.tsx +119 -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 +19 -17
- package/src/testing/index.ts +2 -0
- package/src/translations.ts +19 -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,20 @@ 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';
|
|
38
23
|
|
|
39
24
|
//
|
|
40
25
|
// Root
|
|
41
26
|
//
|
|
42
27
|
|
|
43
|
-
type DialogRootProps =
|
|
28
|
+
type DialogRootProps = DialogPrimitive.DialogProps;
|
|
44
29
|
|
|
45
30
|
const DialogRoot: FunctionComponent<DialogRootProps> = (props) => (
|
|
46
31
|
<ElevationProvider elevation='dialog'>
|
|
47
|
-
<
|
|
32
|
+
<DialogPrimitive.Root {...props} />
|
|
48
33
|
</ElevationProvider>
|
|
49
34
|
);
|
|
50
35
|
|
|
@@ -52,17 +37,17 @@ const DialogRoot: FunctionComponent<DialogRootProps> = (props) => (
|
|
|
52
37
|
// Trigger
|
|
53
38
|
//
|
|
54
39
|
|
|
55
|
-
type DialogTriggerProps =
|
|
40
|
+
type DialogTriggerProps = DialogPrimitive.DialogTriggerProps;
|
|
56
41
|
|
|
57
|
-
const DialogTrigger: FunctionComponent<DialogTriggerProps> =
|
|
42
|
+
const DialogTrigger: FunctionComponent<DialogTriggerProps> = DialogPrimitive.Trigger;
|
|
58
43
|
|
|
59
44
|
//
|
|
60
45
|
// Portal
|
|
61
46
|
//
|
|
62
47
|
|
|
63
|
-
type DialogPortalProps =
|
|
48
|
+
type DialogPortalProps = DialogPrimitive.DialogPortalProps;
|
|
64
49
|
|
|
65
|
-
const DialogPortal: FunctionComponent<DialogPortalProps> =
|
|
50
|
+
const DialogPortal: FunctionComponent<DialogPortalProps> = DialogPrimitive.Portal;
|
|
66
51
|
|
|
67
52
|
//
|
|
68
53
|
// Overlay
|
|
@@ -77,21 +62,23 @@ const [OverlayLayoutProvider, useOverlayLayoutContext] = createContext<OverlayLa
|
|
|
77
62
|
{},
|
|
78
63
|
);
|
|
79
64
|
|
|
80
|
-
type DialogOverlayProps = ThemedClassName<
|
|
65
|
+
type DialogOverlayProps = ThemedClassName<
|
|
66
|
+
DialogPrimitive.DialogOverlayProps & { blockAlign?: 'center' | 'start' | 'end' }
|
|
67
|
+
>;
|
|
81
68
|
|
|
82
69
|
const DialogOverlay: ForwardRefExoticComponent<DialogOverlayProps> = forwardRef<HTMLDivElement, DialogOverlayProps>(
|
|
83
70
|
({ classNames, children, blockAlign, ...props }, forwardedRef) => {
|
|
84
71
|
const { tx } = useThemeContext();
|
|
85
72
|
|
|
86
73
|
return (
|
|
87
|
-
<
|
|
74
|
+
<DialogPrimitive.Overlay
|
|
88
75
|
{...props}
|
|
89
|
-
className={tx('dialog.overlay', 'dialog__overlay', {}, classNames)}
|
|
90
|
-
ref={forwardedRef}
|
|
91
76
|
data-block-align={blockAlign}
|
|
77
|
+
className={tx('dialog.overlay', {}, classNames)}
|
|
78
|
+
ref={forwardedRef}
|
|
92
79
|
>
|
|
93
80
|
<OverlayLayoutProvider inOverlayLayout>{children}</OverlayLayoutProvider>
|
|
94
|
-
</
|
|
81
|
+
</DialogPrimitive.Overlay>
|
|
95
82
|
);
|
|
96
83
|
},
|
|
97
84
|
);
|
|
@@ -104,32 +91,27 @@ DialogOverlay.displayName = DIALOG_OVERLAY_NAME;
|
|
|
104
91
|
|
|
105
92
|
const DIALOG_CONTENT_NAME = 'DialogContent';
|
|
106
93
|
|
|
107
|
-
type DialogContentProps = ThemedClassName<ComponentPropsWithRef<typeof
|
|
94
|
+
type DialogContentProps = ThemedClassName<ComponentPropsWithRef<typeof DialogPrimitive.Content>> & {
|
|
108
95
|
size?: DialogSize;
|
|
109
96
|
inOverlayLayout?: boolean;
|
|
110
97
|
};
|
|
111
98
|
|
|
112
99
|
const DialogContent: ForwardRefExoticComponent<DialogContentProps> = forwardRef<HTMLDivElement, DialogContentProps>(
|
|
113
|
-
({ classNames, children, size, inOverlayLayout: propsInOverlayLayout, ...props }, forwardedRef) => {
|
|
100
|
+
({ classNames, children, size = 'md', inOverlayLayout: propsInOverlayLayout, ...props }, forwardedRef) => {
|
|
114
101
|
const { tx } = useThemeContext();
|
|
115
102
|
const { inOverlayLayout } = useOverlayLayoutContext(DIALOG_CONTENT_NAME);
|
|
116
103
|
|
|
117
104
|
return (
|
|
118
|
-
<
|
|
105
|
+
<DialogPrimitive.Content
|
|
106
|
+
{...props}
|
|
119
107
|
// NOTE: Radix warning unless set to undefined.
|
|
120
108
|
// https://www.radix-ui.com/primitives/docs/components/dialog#description
|
|
121
109
|
aria-describedby={undefined}
|
|
122
|
-
{
|
|
123
|
-
className={tx(
|
|
124
|
-
'dialog.content',
|
|
125
|
-
'dialog',
|
|
126
|
-
{ inOverlayLayout: propsInOverlayLayout || inOverlayLayout, size },
|
|
127
|
-
classNames,
|
|
128
|
-
)}
|
|
110
|
+
className={tx('dialog.content', { inOverlayLayout: propsInOverlayLayout || inOverlayLayout, size }, classNames)}
|
|
129
111
|
ref={forwardedRef}
|
|
130
112
|
>
|
|
131
|
-
{children}
|
|
132
|
-
</
|
|
113
|
+
<Column.Root gutter='md'>{children}</Column.Root>
|
|
114
|
+
</DialogPrimitive.Content>
|
|
133
115
|
);
|
|
134
116
|
},
|
|
135
117
|
);
|
|
@@ -146,31 +128,67 @@ const DialogHeader: ForwardRefExoticComponent<DialogTitleProps> = forwardRef<HTM
|
|
|
146
128
|
({ classNames, srOnly, ...props }, forwardedRef) => {
|
|
147
129
|
const { tx } = useThemeContext();
|
|
148
130
|
return (
|
|
149
|
-
<
|
|
131
|
+
<Column.Segment asChild>
|
|
132
|
+
<div role='heading' {...props} className={tx('dialog.header', { srOnly }, [classNames])} ref={forwardedRef} />
|
|
133
|
+
</Column.Segment>
|
|
134
|
+
);
|
|
135
|
+
},
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
//
|
|
139
|
+
// CloseIconButton
|
|
140
|
+
//
|
|
141
|
+
|
|
142
|
+
type DialogCloseIconButtonProps = { label?: string };
|
|
143
|
+
|
|
144
|
+
const DialogCloseIconButton = forwardRef<HTMLButtonElement, DialogCloseIconButtonProps>(
|
|
145
|
+
({ label, ...props }, forwardedRef) => {
|
|
146
|
+
const { t } = useTranslation(osTranslations);
|
|
147
|
+
return (
|
|
148
|
+
<IconButton
|
|
150
149
|
{...props}
|
|
151
|
-
|
|
152
|
-
|
|
150
|
+
label={label ?? t('close dialog label')}
|
|
151
|
+
icon='ph--x--regular'
|
|
152
|
+
iconOnly
|
|
153
|
+
size={4}
|
|
154
|
+
density='fine'
|
|
155
|
+
variant='ghost'
|
|
153
156
|
ref={forwardedRef}
|
|
154
157
|
/>
|
|
155
158
|
);
|
|
156
159
|
},
|
|
157
160
|
);
|
|
158
161
|
|
|
162
|
+
//
|
|
163
|
+
// Body
|
|
164
|
+
//
|
|
165
|
+
|
|
166
|
+
type DialogBodyProps = PropsWithChildren;
|
|
167
|
+
|
|
168
|
+
const DialogBody: ForwardRefExoticComponent<DialogBodyProps> = forwardRef<HTMLDivElement, DialogBodyProps>(
|
|
169
|
+
({ children, ...props }, forwardedRef) => {
|
|
170
|
+
const { tx } = useThemeContext();
|
|
171
|
+
return (
|
|
172
|
+
<Column.Segment asChild>
|
|
173
|
+
<div role='none' {...props} className={tx('dialog.body')} ref={forwardedRef}>
|
|
174
|
+
{children}
|
|
175
|
+
</div>
|
|
176
|
+
</Column.Segment>
|
|
177
|
+
);
|
|
178
|
+
},
|
|
179
|
+
);
|
|
180
|
+
|
|
159
181
|
//
|
|
160
182
|
// Title
|
|
161
183
|
//
|
|
162
184
|
|
|
163
|
-
type DialogTitleProps = ThemedClassName<
|
|
185
|
+
type DialogTitleProps = ThemedClassName<DialogPrimitive.DialogTitleProps> & { srOnly?: boolean };
|
|
164
186
|
|
|
165
187
|
const DialogTitle: ForwardRefExoticComponent<DialogTitleProps> = forwardRef<HTMLHeadingElement, DialogTitleProps>(
|
|
166
188
|
({ classNames, srOnly, ...props }, forwardedRef) => {
|
|
167
189
|
const { tx } = useThemeContext();
|
|
168
190
|
return (
|
|
169
|
-
<
|
|
170
|
-
{...props}
|
|
171
|
-
className={tx('dialog.title', 'dialog__title', { srOnly }, classNames)}
|
|
172
|
-
ref={forwardedRef}
|
|
173
|
-
/>
|
|
191
|
+
<DialogPrimitive.Title {...props} className={tx('dialog.title', { srOnly }, classNames)} ref={forwardedRef} />
|
|
174
192
|
);
|
|
175
193
|
},
|
|
176
194
|
);
|
|
@@ -179,54 +197,49 @@ const DialogTitle: ForwardRefExoticComponent<DialogTitleProps> = forwardRef<HTML
|
|
|
179
197
|
// Description
|
|
180
198
|
//
|
|
181
199
|
|
|
182
|
-
type DialogDescriptionProps = ThemedClassName<
|
|
200
|
+
type DialogDescriptionProps = ThemedClassName<DialogPrimitive.DialogDescriptionProps> & { srOnly?: boolean };
|
|
183
201
|
|
|
184
|
-
const DialogDescription: ForwardRefExoticComponent<
|
|
202
|
+
const DialogDescription: ForwardRefExoticComponent<DialogDescriptionProps> = forwardRef<
|
|
185
203
|
HTMLParagraphElement,
|
|
186
204
|
DialogDescriptionProps
|
|
187
205
|
>(({ classNames, srOnly, ...props }, forwardedRef) => {
|
|
188
206
|
const { tx } = useThemeContext();
|
|
189
207
|
return (
|
|
190
|
-
<
|
|
208
|
+
<DialogPrimitive.Description
|
|
191
209
|
{...props}
|
|
192
|
-
className={tx('dialog.description',
|
|
210
|
+
className={tx('dialog.description', { srOnly }, classNames)}
|
|
193
211
|
ref={forwardedRef}
|
|
194
212
|
/>
|
|
195
213
|
);
|
|
196
214
|
});
|
|
197
215
|
|
|
198
216
|
//
|
|
199
|
-
//
|
|
217
|
+
// ActionBar
|
|
200
218
|
//
|
|
201
219
|
|
|
202
|
-
type
|
|
220
|
+
type DialogActionBarProps = ThemedClassName<PropsWithChildren>;
|
|
203
221
|
|
|
204
|
-
const
|
|
222
|
+
const DialogActionBar: ForwardRefExoticComponent<DialogActionBarProps> = forwardRef<
|
|
223
|
+
HTMLDivElement,
|
|
224
|
+
DialogActionBarProps
|
|
225
|
+
>(({ children, classNames, ...props }, forwardedRef) => {
|
|
226
|
+
const { tx } = useThemeContext();
|
|
227
|
+
return (
|
|
228
|
+
<Column.Segment asChild>
|
|
229
|
+
<div {...props} className={tx('dialog.actionbar', {}, classNames)} ref={forwardedRef}>
|
|
230
|
+
{children}
|
|
231
|
+
</div>
|
|
232
|
+
</Column.Segment>
|
|
233
|
+
);
|
|
234
|
+
});
|
|
205
235
|
|
|
206
236
|
//
|
|
207
|
-
// Close
|
|
237
|
+
// Close
|
|
208
238
|
//
|
|
209
239
|
|
|
210
|
-
type
|
|
240
|
+
type DialogCloseProps = DialogPrimitive.DialogCloseProps;
|
|
211
241
|
|
|
212
|
-
const
|
|
213
|
-
HTMLButtonElement,
|
|
214
|
-
DialogCloseIconButtonProps
|
|
215
|
-
>((props, forwardedRef) => {
|
|
216
|
-
const { t } = useTranslation(osTranslations);
|
|
217
|
-
return (
|
|
218
|
-
<IconButton
|
|
219
|
-
{...props}
|
|
220
|
-
label={props.label ?? t('close dialog label')}
|
|
221
|
-
icon='ph--x--regular'
|
|
222
|
-
iconOnly
|
|
223
|
-
size={4}
|
|
224
|
-
density='fine'
|
|
225
|
-
variant='ghost'
|
|
226
|
-
ref={forwardedRef}
|
|
227
|
-
/>
|
|
228
|
-
);
|
|
229
|
-
});
|
|
242
|
+
const DialogClose: FunctionComponent<DialogCloseProps> = DialogPrimitive.Close;
|
|
230
243
|
|
|
231
244
|
//
|
|
232
245
|
// Dialog
|
|
@@ -239,8 +252,10 @@ export const Dialog = {
|
|
|
239
252
|
Overlay: DialogOverlay,
|
|
240
253
|
Content: DialogContent,
|
|
241
254
|
Header: DialogHeader,
|
|
255
|
+
Body: DialogBody,
|
|
242
256
|
Title: DialogTitle,
|
|
243
257
|
Description: DialogDescription,
|
|
258
|
+
ActionBar: DialogActionBar,
|
|
244
259
|
Close: DialogClose,
|
|
245
260
|
CloseIconButton: DialogCloseIconButton,
|
|
246
261
|
};
|
|
@@ -252,8 +267,9 @@ export type {
|
|
|
252
267
|
DialogOverlayProps,
|
|
253
268
|
DialogContentProps,
|
|
254
269
|
DialogHeaderProps,
|
|
270
|
+
DialogBodyProps,
|
|
255
271
|
DialogTitleProps,
|
|
256
272
|
DialogDescriptionProps,
|
|
273
|
+
DialogActionBarProps,
|
|
257
274
|
DialogCloseProps,
|
|
258
|
-
DialogCloseIconButtonProps,
|
|
259
275
|
};
|
|
@@ -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
|
+
};
|
|
@@ -60,9 +60,9 @@ const DefaultStory = ({ CustomIcon }: { CustomIcon: FC<IconProps> }) => {
|
|
|
60
60
|
};
|
|
61
61
|
|
|
62
62
|
const meta = {
|
|
63
|
-
title: 'ui/react-ui-core/Icon',
|
|
63
|
+
title: 'ui/react-ui-core/components/Icon',
|
|
64
64
|
render: DefaultStory,
|
|
65
|
-
decorators: [withTheme],
|
|
65
|
+
decorators: [withTheme()],
|
|
66
66
|
parameters: {
|
|
67
67
|
layout: 'centered',
|
|
68
68
|
},
|
|
@@ -16,11 +16,12 @@ export type IconProps = ThemedClassName<ComponentPropsWithRef<typeof Primitive.s
|
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
export const Icon = memo(
|
|
19
|
-
forwardRef<SVGSVGElement, IconProps>(({ icon, classNames, size
|
|
19
|
+
forwardRef<SVGSVGElement, IconProps>(({ icon, classNames, size, ...props }, forwardedRef) => {
|
|
20
20
|
const { tx } = useThemeContext();
|
|
21
21
|
const href = useIconHref(icon);
|
|
22
|
+
|
|
22
23
|
return (
|
|
23
|
-
<svg {...props} className={tx('icon.root',
|
|
24
|
+
<svg {...props} className={tx('icon.root', { size }, classNames)} ref={forwardedRef}>
|
|
24
25
|
<use href={href} />
|
|
25
26
|
</svg>
|
|
26
27
|
);
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
|
+
import React, { useMemo } from 'react';
|
|
7
|
+
|
|
8
|
+
import { faker } from '@dxos/random';
|
|
9
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
10
|
+
|
|
11
|
+
import { Image } from './Image';
|
|
12
|
+
|
|
13
|
+
const seed = Math.random();
|
|
14
|
+
|
|
15
|
+
faker.seed(seed);
|
|
16
|
+
|
|
17
|
+
const meta = {
|
|
18
|
+
title: 'ui/react-ui-mosaic/Image',
|
|
19
|
+
component: Image,
|
|
20
|
+
render: (args) => (
|
|
21
|
+
<div className='absolute inset-0 flex justify-center items-center'>
|
|
22
|
+
<Image {...args} />
|
|
23
|
+
</div>
|
|
24
|
+
),
|
|
25
|
+
decorators: [withTheme()],
|
|
26
|
+
parameters: {
|
|
27
|
+
layout: 'centered',
|
|
28
|
+
},
|
|
29
|
+
} satisfies Meta<typeof Image>;
|
|
30
|
+
|
|
31
|
+
export default meta;
|
|
32
|
+
|
|
33
|
+
type Story = StoryObj<typeof meta>;
|
|
34
|
+
|
|
35
|
+
export const Default: Story = {
|
|
36
|
+
args: {
|
|
37
|
+
src: faker.image.url(),
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const classNames = 'h-[12rem] w-[18rem]';
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Access to image at 'https://dxos.network/dxos-logotype-blue.png'
|
|
45
|
+
* from origin 'http://localhost:9009' has been blocked by CORS policy:
|
|
46
|
+
* No 'Access-Control-Allow-Origin' header is present on the requested resource.
|
|
47
|
+
*/
|
|
48
|
+
export const Cors: Story = {
|
|
49
|
+
args: {
|
|
50
|
+
src: 'https://dxos.network/dxos-logotype-blue.png',
|
|
51
|
+
classNames,
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const Corners: Story = {
|
|
56
|
+
args: {
|
|
57
|
+
src: 'https://picsum.photos/seed/picsum/200/200',
|
|
58
|
+
classNames,
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export const SVG: Story = {
|
|
63
|
+
args: {
|
|
64
|
+
src: 'https://dxos.network/bg-kube.svg',
|
|
65
|
+
classNames,
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const Many: Story = {
|
|
70
|
+
args: {
|
|
71
|
+
src: 'https://dxos.network/bg-kube.svg',
|
|
72
|
+
},
|
|
73
|
+
render: () => {
|
|
74
|
+
const images = useMemo(
|
|
75
|
+
() => Array.from({ length: 9 }, (_, i) => `https://picsum.photos/seed/${seed + i}/500/500`),
|
|
76
|
+
[],
|
|
77
|
+
);
|
|
78
|
+
return (
|
|
79
|
+
<div className='w-[60rem] grid grid-cols-3 grid-rows-3 gap-8'>
|
|
80
|
+
{images.map((src, i) => (
|
|
81
|
+
<Image key={i} src={src} classNames={classNames} />
|
|
82
|
+
))}
|
|
83
|
+
</div>
|
|
84
|
+
);
|
|
85
|
+
},
|
|
86
|
+
};
|