@dxos/react-ui 0.8.4-main.ef1bc66f44 → 0.8.4-main.f466a3d56e
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/LICENSE +102 -5
- package/README.md +1 -1
- package/dist/lib/browser/chunk-A5QCIG5R.mjs +24 -0
- package/dist/lib/browser/chunk-A5QCIG5R.mjs.map +7 -0
- package/dist/lib/browser/{chunk-EJYV4HAH.mjs → chunk-LY5XDQR5.mjs} +189 -117
- package/dist/lib/browser/chunk-LY5XDQR5.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +3257 -2048
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +70 -41
- package/dist/lib/browser/testing/index.mjs.map +4 -4
- package/dist/lib/browser/translations.mjs +9 -0
- package/dist/lib/browser/translations.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-YTLZCZ2M.mjs → chunk-NGKLIKP3.mjs} +189 -117
- package/dist/lib/node-esm/chunk-NGKLIKP3.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-XCFLA74M.mjs +26 -0
- package/dist/lib/node-esm/chunk-XCFLA74M.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +3257 -2048
- 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 +70 -41
- package/dist/lib/node-esm/testing/index.mjs.map +4 -4
- package/dist/lib/node-esm/translations.mjs +10 -0
- package/dist/lib/node-esm/translations.mjs.map +7 -0
- package/dist/types/src/components/Avatars/Avatar.d.ts +1 -1
- 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/Avatars/AvatarGroup.stories.d.ts.map +1 -1
- package/dist/types/src/components/Breadcrumb/Breadcrumb.d.ts.map +1 -1
- package/dist/types/src/components/Breadcrumb/Breadcrumb.stories.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/Button.stories.d.ts +1 -1
- package/dist/types/src/components/Button/Button.stories.d.ts.map +1 -1
- package/dist/types/src/components/Button/IconButton.d.ts +1 -0
- package/dist/types/src/components/Button/IconButton.d.ts.map +1 -1
- package/dist/types/src/components/Button/IconButton.stories.d.ts +3 -0
- package/dist/types/src/components/Button/IconButton.stories.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/Toggle.stories.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/Button/ToggleGroup.stories.d.ts +2 -2
- package/dist/types/src/components/Button/ToggleGroup.stories.d.ts.map +1 -1
- package/dist/types/src/components/Card/Card.d.ts +124 -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/Carousel/Carousel.d.ts +90 -0
- package/dist/types/src/components/Carousel/Carousel.d.ts.map +1 -0
- package/dist/types/src/components/Carousel/index.d.ts +2 -0
- package/dist/types/src/components/Carousel/index.d.ts.map +1 -0
- package/dist/types/src/components/Clipboard/ClipboardProvider.d.ts.map +1 -1
- package/dist/types/src/components/Clipboard/CopyButton.d.ts.map +1 -1
- 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/DensityProvider/DensityProvider.d.ts.map +1 -1
- package/dist/types/src/components/Dialog/AlertDialog.d.ts +43 -23
- 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 -30
- 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/ElevationProvider/ElevationProvider.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 +19 -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 +36 -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 +4 -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 +15 -0
- package/dist/types/src/components/Image/Image.d.ts.map +1 -0
- package/dist/types/src/components/Image/Image.stories.d.ts +34 -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 +16 -22
- package/dist/types/src/components/Input/Input.d.ts.map +1 -1
- package/dist/types/src/components/Input/Input.stories.d.ts +6 -6
- package/dist/types/src/components/Input/Input.stories.d.ts.map +1 -1
- package/dist/types/src/components/Link/Link.stories.d.ts.map +1 -1
- package/dist/types/src/components/List/List.d.ts +5 -3
- package/dist/types/src/components/List/List.d.ts.map +1 -1
- package/dist/types/src/components/List/List.stories.d.ts +3 -1
- package/dist/types/src/components/List/List.stories.d.ts.map +1 -1
- package/dist/types/src/components/List/ListDropIndicator.d.ts.map +1 -1
- package/dist/types/src/components/List/Tree.d.ts +2 -2
- package/dist/types/src/components/List/Tree.d.ts.map +1 -1
- package/dist/types/src/components/List/Tree.stories.d.ts.map +1 -1
- package/dist/types/src/components/List/TreeDropIndicator.d.ts.map +1 -1
- package/dist/types/src/components/List/Treegrid.d.ts +5 -9
- package/dist/types/src/components/List/Treegrid.d.ts.map +1 -1
- package/dist/types/src/components/List/Treegrid.stories.d.ts.map +1 -1
- package/dist/types/src/components/Main/Main.d.ts +11 -7
- package/dist/types/src/components/Main/Main.d.ts.map +1 -1
- package/dist/types/src/components/Main/Main.stories.d.ts +0 -3
- package/dist/types/src/components/Main/Main.stories.d.ts.map +1 -1
- package/dist/types/src/components/Main/useSwipeToDismiss.d.ts.map +1 -1
- package/dist/types/src/components/MediaPlayer/MediaPlayer.d.ts +46 -0
- package/dist/types/src/components/MediaPlayer/MediaPlayer.d.ts.map +1 -0
- package/dist/types/src/components/MediaPlayer/MediaPlayer.stories.d.ts +16 -0
- package/dist/types/src/components/MediaPlayer/MediaPlayer.stories.d.ts.map +1 -0
- package/dist/types/src/components/MediaPlayer/index.d.ts +2 -0
- package/dist/types/src/components/MediaPlayer/index.d.ts.map +1 -0
- package/dist/types/src/components/Menu/ContextMenu.d.ts.map +1 -1
- package/dist/types/src/components/Menu/ContextMenu.stories.d.ts.map +1 -1
- package/dist/types/src/components/Menu/DropdownMenu.d.ts +58 -49
- 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 +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 +39 -22
- package/dist/types/src/components/Popover/Popover.d.ts.map +1 -1
- package/dist/types/src/components/Popover/Popover.stories.d.ts.map +1 -1
- package/dist/types/src/components/ScrollArea/ScrollArea.d.ts +12 -11
- package/dist/types/src/components/ScrollArea/ScrollArea.d.ts.map +1 -1
- package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts +21 -10
- package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts.map +1 -1
- package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts +42 -13
- package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts.map +1 -1
- package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts +9 -5
- 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.stories.d.ts.map +1 -1
- package/dist/types/src/components/Splitter/Splitter.d.ts +23 -15
- package/dist/types/src/components/Splitter/Splitter.d.ts.map +1 -1
- package/dist/types/src/components/Splitter/Splitter.stories.d.ts.map +1 -1
- 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 +1 -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/ThemeProvider/TranslationsProvider.d.ts +54 -55
- package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts.map +1 -1
- package/dist/types/src/components/ThemeProvider/index.d.ts +1 -1
- package/dist/types/src/components/ThemeProvider/index.d.ts.map +1 -1
- package/dist/types/src/components/Toast/Toast.d.ts +16 -16
- package/dist/types/src/components/Toast/Toast.d.ts.map +1 -1
- package/dist/types/src/components/Toast/Toast.stories.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.d.ts +32 -15
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
- package/dist/types/src/components/Tooltip/Tooltip.d.ts +16 -16
- 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 +8 -6
- package/dist/types/src/exemplars/generics.stories.d.ts.map +1 -1
- package/dist/types/src/exemplars/slot.stories.d.ts +1 -0
- package/dist/types/src/exemplars/slot.stories.d.ts.map +1 -1
- package/dist/types/src/exemplars/tabster.stories.d.ts.map +1 -1
- 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/hooks/useElevationContext.d.ts.map +1 -1
- package/dist/types/src/hooks/useIconHref.d.ts.map +1 -1
- package/dist/types/src/hooks/useSafeArea.d.ts.map +1 -1
- package/dist/types/src/hooks/useSafeCollisionPadding.d.ts.map +1 -1
- package/dist/types/src/hooks/useVisualViewport.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 +1 -1
- package/dist/types/src/playground/Custom.stories.d.ts.map +1 -1
- package/dist/types/src/playground/Typography.stories.d.ts.map +1 -1
- package/dist/types/src/primitives/Column/Column.d.ts +33 -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 +6 -22
- package/dist/types/src/primitives/Container/Container.d.ts.map +1 -1
- package/dist/types/src/primitives/Container/Container.stories.d.ts +2 -7
- package/dist/types/src/primitives/Container/Container.stories.d.ts.map +1 -1
- package/dist/types/src/primitives/Container/index.d.ts +0 -1
- package/dist/types/src/primitives/Container/index.d.ts.map +1 -1
- package/dist/types/src/primitives/Flex/Flex.d.ts +8 -5
- package/dist/types/src/primitives/Flex/Flex.d.ts.map +1 -1
- 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/Grid/Grid.d.ts +10 -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 +35 -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 +3 -0
- package/dist/types/src/primitives/index.d.ts.map +1 -1
- 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 +1 -1
- 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 +16 -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 +34 -27
- package/src/components/Avatars/Avatar.stories.tsx +5 -7
- package/src/components/Avatars/Avatar.tsx +6 -14
- package/src/components/Avatars/AvatarGroup.stories.tsx +0 -1
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +1 -2
- package/src/components/Breadcrumb/Breadcrumb.tsx +11 -37
- package/src/components/Button/Button.stories.tsx +1 -2
- package/src/components/Button/Button.tsx +11 -25
- package/src/components/Button/IconButton.stories.tsx +6 -4
- package/src/components/Button/IconButton.tsx +3 -4
- package/src/components/Button/Toggle.stories.tsx +0 -1
- package/src/components/Button/Toggle.tsx +4 -4
- package/src/components/Button/ToggleGroup.stories.tsx +0 -1
- package/src/components/Button/ToggleGroup.tsx +12 -16
- package/src/components/Card/Card.stories.tsx +151 -0
- package/src/components/Card/Card.tsx +514 -0
- package/src/components/Card/index.ts +5 -0
- package/src/components/Carousel/Carousel.tsx +337 -0
- package/src/components/Carousel/index.ts +5 -0
- package/src/components/Clipboard/CopyButton.tsx +6 -7
- package/src/components/Dialog/AlertDialog.stories.tsx +14 -15
- package/src/components/Dialog/AlertDialog.tsx +123 -82
- package/src/components/Dialog/Dialog.stories.tsx +90 -14
- package/src/components/Dialog/Dialog.tsx +98 -113
- package/src/components/ErrorFallback/ErrorFallback.stories.tsx +45 -0
- package/src/components/ErrorFallback/ErrorFallback.tsx +70 -0
- package/src/components/ErrorFallback/ErrorStack.tsx +114 -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 +43 -13
- package/src/components/Icon/Icon.tsx +14 -3
- package/src/components/Image/Image.stories.tsx +86 -0
- package/src/components/Image/Image.tsx +246 -0
- package/src/components/Image/index.ts +5 -0
- package/src/components/Input/Input.stories.tsx +17 -38
- package/src/components/Input/Input.tsx +27 -71
- package/src/components/Link/Link.stories.tsx +0 -1
- package/src/components/Link/Link.tsx +2 -2
- package/src/components/List/List.stories.tsx +14 -22
- package/src/components/List/List.tsx +16 -20
- package/src/components/List/ListDropIndicator.tsx +7 -8
- package/src/components/List/Tree.stories.tsx +4 -5
- package/src/components/List/Tree.tsx +0 -1
- package/src/components/List/TreeDropIndicator.tsx +6 -6
- package/src/components/List/Treegrid.stories.tsx +27 -28
- package/src/components/List/Treegrid.tsx +22 -27
- package/src/components/Main/Main.stories.tsx +3 -7
- package/src/components/Main/Main.tsx +57 -48
- package/src/components/MediaPlayer/MediaPlayer.stories.tsx +50 -0
- package/src/components/MediaPlayer/MediaPlayer.tsx +153 -0
- package/src/components/MediaPlayer/index.ts +5 -0
- package/src/components/Menu/ContextMenu.stories.tsx +0 -1
- package/src/components/Menu/ContextMenu.tsx +9 -33
- package/src/components/Menu/DropdownMenu.stories.tsx +0 -1
- package/src/components/Menu/DropdownMenu.tsx +58 -52
- package/src/components/Message/Message.stories.tsx +25 -11
- package/src/components/Message/Message.tsx +30 -29
- package/src/components/Popover/Popover.stories.tsx +5 -6
- package/src/components/Popover/Popover.tsx +62 -59
- package/src/components/ScrollArea/ScrollArea.stories.tsx +98 -39
- package/src/components/ScrollArea/ScrollArea.tsx +45 -33
- package/src/components/ScrollContainer/ScrollContainer.stories.tsx +46 -25
- package/src/components/ScrollContainer/ScrollContainer.tsx +199 -92
- package/src/components/Select/Select.stories.tsx +5 -6
- package/src/components/Select/Select.tsx +11 -27
- package/src/components/Separator/Separator.tsx +5 -8
- package/src/components/Skeleton/Skeleton.stories.tsx +12 -13
- package/src/components/Skeleton/Skeleton.tsx +1 -1
- package/src/components/Splitter/Splitter.stories.tsx +47 -37
- package/src/components/Splitter/Splitter.tsx +44 -40
- package/src/components/Status/Status.stories.tsx +19 -16
- package/src/components/Status/Status.tsx +10 -7
- package/src/components/Tag/Tag.stories.tsx +3 -9
- package/src/components/Tag/Tag.tsx +2 -7
- package/src/components/ThemeProvider/ThemeProvider.stories.tsx +31 -0
- package/src/components/ThemeProvider/ThemeProvider.tsx +8 -7
- package/src/components/ThemeProvider/index.ts +1 -1
- package/src/components/Toast/Toast.stories.tsx +0 -1
- package/src/components/Toast/Toast.tsx +22 -41
- package/src/components/Toolbar/Toolbar.stories.tsx +0 -1
- package/src/components/Toolbar/Toolbar.tsx +175 -30
- package/src/components/Tooltip/Tooltip.stories.tsx +18 -17
- package/src/components/Tooltip/Tooltip.tsx +32 -31
- package/src/components/index.ts +10 -5
- package/src/exemplars/generics.stories.tsx +12 -15
- package/src/exemplars/slot.stories.tsx +68 -61
- package/src/exemplars/tabster.stories.tsx +5 -5
- package/src/exemplars/virtualizer.stories.tsx +136 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useDensityContext.ts +2 -2
- package/src/playground/Controls.stories.tsx +0 -6
- package/src/playground/Custom.stories.tsx +13 -16
- package/src/playground/Typography.stories.tsx +1 -1
- package/src/primitives/Column/AUDIT.md +148 -0
- package/src/primitives/Column/Column.stories.tsx +181 -0
- package/src/primitives/Column/Column.tsx +165 -0
- package/src/primitives/Column/index.ts +5 -0
- package/src/primitives/Container/Container.stories.tsx +13 -51
- package/src/primitives/Container/Container.tsx +14 -77
- package/src/primitives/Container/index.ts +0 -1
- package/src/primitives/Flex/Flex.stories.tsx +57 -0
- package/src/primitives/Flex/Flex.tsx +20 -19
- package/src/primitives/Grid/Grid.stories.tsx +56 -0
- package/src/primitives/Grid/Grid.tsx +30 -0
- package/src/primitives/Grid/index.ts +5 -0
- package/src/primitives/Panel/Panel.stories.tsx +68 -0
- package/src/primitives/Panel/Panel.tsx +120 -0
- package/src/primitives/Panel/index.ts +5 -0
- package/src/primitives/index.ts +3 -0
- package/src/testing/Loading.tsx +47 -0
- package/src/testing/decorators/withLayout.tsx +15 -11
- package/src/testing/decorators/withLayoutVariants.tsx +18 -21
- package/src/testing/decorators/withTheme.tsx +10 -7
- package/src/testing/index.ts +2 -0
- package/src/translations.ts +24 -0
- package/src/util/usePx.ts +1 -0
- package/dist/lib/browser/chunk-EJYV4HAH.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-YTLZCZ2M.mjs.map +0 -7
- package/dist/types/src/components/AnchoredOverflow/AnchoredOverflow.d.ts +0 -22
- 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/dist/types/src/primitives/Container/Layout.d.ts +0 -18
- package/dist/types/src/primitives/Container/Layout.d.ts.map +0 -1
- package/dist/types/src/primitives/Container/Layout.stories.d.ts +0 -10
- package/dist/types/src/primitives/Container/Layout.stories.d.ts.map +0 -1
- package/src/components/AnchoredOverflow/AnchoredOverflow.tsx +0 -67
- package/src/components/AnchoredOverflow/index.ts +0 -5
- package/src/primitives/Container/Layout.stories.tsx +0 -57
- package/src/primitives/Container/Layout.tsx +0 -61
|
@@ -3,48 +3,40 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { createContext } from '@radix-ui/react-context';
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
|
|
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';
|
|
6
|
+
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
7
|
+
import { Primitive } from '@radix-ui/react-primitive';
|
|
8
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
23
9
|
import React, {
|
|
24
10
|
type ComponentPropsWithRef,
|
|
25
11
|
type ForwardRefExoticComponent,
|
|
26
12
|
type FunctionComponent,
|
|
27
|
-
type PropsWithChildren,
|
|
28
13
|
forwardRef,
|
|
29
14
|
} from 'react';
|
|
30
15
|
import { useTranslation } from 'react-i18next';
|
|
31
16
|
|
|
32
|
-
import { type DialogSize, osTranslations } from '@dxos/ui-theme';
|
|
17
|
+
import { composableProps, type DialogSize, osTranslations, slottable } from '@dxos/ui-theme';
|
|
18
|
+
import { type SlottableProps } from '@dxos/ui-types';
|
|
33
19
|
|
|
34
20
|
import { useThemeContext } from '../../hooks';
|
|
21
|
+
import { Column } from '../../primitives';
|
|
35
22
|
import { type ThemedClassName } from '../../util';
|
|
36
|
-
import { IconButton
|
|
23
|
+
import { IconButton } from '../Button';
|
|
37
24
|
import { ElevationProvider } from '../ElevationProvider';
|
|
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
|
|
35
|
+
// NOTE: Radix warning unless set to undefined.
|
|
36
|
+
// https://www.radix-ui.com/primitives/docs/components/dialog#description
|
|
37
|
+
aria-describedby={undefined}
|
|
38
|
+
{...props}
|
|
39
|
+
/>
|
|
48
40
|
</ElevationProvider>
|
|
49
41
|
);
|
|
50
42
|
|
|
@@ -52,17 +44,17 @@ const DialogRoot: FunctionComponent<DialogRootProps> = (props) => (
|
|
|
52
44
|
// Trigger
|
|
53
45
|
//
|
|
54
46
|
|
|
55
|
-
type DialogTriggerProps =
|
|
47
|
+
type DialogTriggerProps = DialogPrimitive.DialogTriggerProps;
|
|
56
48
|
|
|
57
|
-
const DialogTrigger: FunctionComponent<DialogTriggerProps> =
|
|
49
|
+
const DialogTrigger: FunctionComponent<DialogTriggerProps> = DialogPrimitive.Trigger;
|
|
58
50
|
|
|
59
51
|
//
|
|
60
52
|
// Portal
|
|
61
53
|
//
|
|
62
54
|
|
|
63
|
-
type DialogPortalProps =
|
|
55
|
+
type DialogPortalProps = DialogPrimitive.DialogPortalProps;
|
|
64
56
|
|
|
65
|
-
const DialogPortal: FunctionComponent<DialogPortalProps> =
|
|
57
|
+
const DialogPortal: FunctionComponent<DialogPortalProps> = DialogPrimitive.Portal;
|
|
66
58
|
|
|
67
59
|
//
|
|
68
60
|
// Overlay
|
|
@@ -77,21 +69,23 @@ const [OverlayLayoutProvider, useOverlayLayoutContext] = createContext<OverlayLa
|
|
|
77
69
|
{},
|
|
78
70
|
);
|
|
79
71
|
|
|
80
|
-
type DialogOverlayProps = ThemedClassName<
|
|
72
|
+
type DialogOverlayProps = ThemedClassName<
|
|
73
|
+
DialogPrimitive.DialogOverlayProps & { blockAlign?: 'center' | 'start' | 'end' }
|
|
74
|
+
>;
|
|
81
75
|
|
|
82
76
|
const DialogOverlay: ForwardRefExoticComponent<DialogOverlayProps> = forwardRef<HTMLDivElement, DialogOverlayProps>(
|
|
83
77
|
({ classNames, children, blockAlign, ...props }, forwardedRef) => {
|
|
84
78
|
const { tx } = useThemeContext();
|
|
85
79
|
|
|
86
80
|
return (
|
|
87
|
-
<
|
|
81
|
+
<DialogPrimitive.Overlay
|
|
88
82
|
{...props}
|
|
89
|
-
className={tx('dialog.overlay', 'dialog__overlay', {}, classNames)}
|
|
90
|
-
ref={forwardedRef}
|
|
91
83
|
data-block-align={blockAlign}
|
|
84
|
+
className={tx('dialog.overlay', {}, classNames)}
|
|
85
|
+
ref={forwardedRef}
|
|
92
86
|
>
|
|
93
87
|
<OverlayLayoutProvider inOverlayLayout>{children}</OverlayLayoutProvider>
|
|
94
|
-
</
|
|
88
|
+
</DialogPrimitive.Overlay>
|
|
95
89
|
);
|
|
96
90
|
},
|
|
97
91
|
);
|
|
@@ -104,32 +98,36 @@ DialogOverlay.displayName = DIALOG_OVERLAY_NAME;
|
|
|
104
98
|
|
|
105
99
|
const DIALOG_CONTENT_NAME = 'DialogContent';
|
|
106
100
|
|
|
107
|
-
type DialogContentProps = ThemedClassName<ComponentPropsWithRef<typeof
|
|
101
|
+
type DialogContentProps = ThemedClassName<ComponentPropsWithRef<typeof DialogPrimitive.Content>> & {
|
|
108
102
|
size?: DialogSize;
|
|
109
103
|
inOverlayLayout?: boolean;
|
|
110
104
|
};
|
|
111
105
|
|
|
112
106
|
const DialogContent: ForwardRefExoticComponent<DialogContentProps> = forwardRef<HTMLDivElement, DialogContentProps>(
|
|
113
|
-
({ classNames, children, size, inOverlayLayout: propsInOverlayLayout, ...props }, forwardedRef) => {
|
|
107
|
+
({ classNames, children, size = 'md', inOverlayLayout: propsInOverlayLayout, ...props }, forwardedRef) => {
|
|
114
108
|
const { tx } = useThemeContext();
|
|
115
109
|
const { inOverlayLayout } = useOverlayLayoutContext(DIALOG_CONTENT_NAME);
|
|
116
110
|
|
|
117
111
|
return (
|
|
118
|
-
<
|
|
112
|
+
<DialogPrimitive.Content
|
|
113
|
+
{...props}
|
|
119
114
|
// NOTE: Radix warning unless set to undefined.
|
|
120
115
|
// https://www.radix-ui.com/primitives/docs/components/dialog#description
|
|
121
116
|
aria-describedby={undefined}
|
|
122
|
-
{...props}
|
|
123
117
|
className={tx(
|
|
124
118
|
'dialog.content',
|
|
125
|
-
|
|
126
|
-
|
|
119
|
+
{
|
|
120
|
+
size,
|
|
121
|
+
inOverlayLayout: propsInOverlayLayout || inOverlayLayout,
|
|
122
|
+
},
|
|
127
123
|
classNames,
|
|
128
124
|
)}
|
|
129
125
|
ref={forwardedRef}
|
|
130
126
|
>
|
|
131
|
-
|
|
132
|
-
|
|
127
|
+
<Column.Root classNames='dx-expander' gutter='sm'>
|
|
128
|
+
{children}
|
|
129
|
+
</Column.Root>
|
|
130
|
+
</DialogPrimitive.Content>
|
|
133
131
|
);
|
|
134
132
|
},
|
|
135
133
|
);
|
|
@@ -140,16 +138,36 @@ DialogContent.displayName = DIALOG_CONTENT_NAME;
|
|
|
140
138
|
// Header
|
|
141
139
|
//
|
|
142
140
|
|
|
143
|
-
type DialogHeaderProps =
|
|
141
|
+
type DialogHeaderProps = SlottableProps;
|
|
144
142
|
|
|
145
|
-
const DialogHeader
|
|
146
|
-
|
|
147
|
-
|
|
143
|
+
const DialogHeader = slottable<HTMLDivElement>(({ children, asChild, ...props }, forwardedRef) => {
|
|
144
|
+
const { className, ...rest } = composableProps(props);
|
|
145
|
+
const Comp = asChild ? Slot : Primitive.div;
|
|
146
|
+
const { tx } = useThemeContext();
|
|
147
|
+
return (
|
|
148
|
+
<Comp {...rest} className={tx('dialog.header', {}, className)} ref={forwardedRef}>
|
|
149
|
+
{children}
|
|
150
|
+
</Comp>
|
|
151
|
+
);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
//
|
|
155
|
+
// CloseIconButton
|
|
156
|
+
//
|
|
157
|
+
|
|
158
|
+
type DialogCloseIconButtonProps = { label?: string };
|
|
159
|
+
|
|
160
|
+
const DialogCloseIconButton = forwardRef<HTMLButtonElement, DialogCloseIconButtonProps>(
|
|
161
|
+
({ label, ...props }, forwardedRef) => {
|
|
162
|
+
const { t } = useTranslation(osTranslations);
|
|
148
163
|
return (
|
|
149
|
-
<
|
|
164
|
+
<IconButton
|
|
150
165
|
{...props}
|
|
151
|
-
|
|
152
|
-
|
|
166
|
+
label={label ?? t('close-dialog.label')}
|
|
167
|
+
icon='ph--x--regular'
|
|
168
|
+
iconOnly
|
|
169
|
+
size={4}
|
|
170
|
+
variant='ghost'
|
|
153
171
|
ref={forwardedRef}
|
|
154
172
|
/>
|
|
155
173
|
);
|
|
@@ -160,75 +178,67 @@ const DialogHeader: ForwardRefExoticComponent<DialogTitleProps> = forwardRef<HTM
|
|
|
160
178
|
// Body
|
|
161
179
|
//
|
|
162
180
|
|
|
163
|
-
type DialogBodyProps =
|
|
181
|
+
type DialogBodyProps = SlottableProps;
|
|
182
|
+
|
|
183
|
+
const DialogBody = slottable<HTMLDivElement>(({ children, asChild, ...props }, forwardedRef) => {
|
|
184
|
+
const { className, ...rest } = composableProps(props);
|
|
185
|
+
const Comp = asChild ? Slot : Primitive.div;
|
|
186
|
+
const { tx } = useThemeContext();
|
|
187
|
+
return (
|
|
188
|
+
<Comp {...rest} className={tx('dialog.body', {}, className)} ref={forwardedRef}>
|
|
189
|
+
{children}
|
|
190
|
+
</Comp>
|
|
191
|
+
);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
//
|
|
195
|
+
// Title
|
|
196
|
+
//
|
|
164
197
|
|
|
165
|
-
|
|
166
|
-
|
|
198
|
+
type DialogTitleProps = ThemedClassName<DialogPrimitive.DialogTitleProps> & { srOnly?: boolean };
|
|
199
|
+
|
|
200
|
+
const DialogTitle = forwardRef<HTMLHeadingElement, DialogTitleProps>(
|
|
201
|
+
({ classNames, srOnly, ...props }, forwardedRef) => {
|
|
167
202
|
const { tx } = useThemeContext();
|
|
168
203
|
return (
|
|
169
|
-
<
|
|
170
|
-
{children}
|
|
171
|
-
</div>
|
|
204
|
+
<DialogPrimitive.Title {...props} className={tx('dialog.title', { srOnly }, classNames)} ref={forwardedRef} />
|
|
172
205
|
);
|
|
173
206
|
},
|
|
174
207
|
);
|
|
175
208
|
|
|
176
|
-
// TODO(burdon): Add ActionBar.
|
|
177
|
-
|
|
178
209
|
//
|
|
179
|
-
//
|
|
210
|
+
// Description
|
|
180
211
|
//
|
|
181
212
|
|
|
182
|
-
type
|
|
213
|
+
type DialogDescriptionProps = ThemedClassName<DialogPrimitive.DialogDescriptionProps> & { srOnly?: boolean };
|
|
183
214
|
|
|
184
|
-
const
|
|
215
|
+
const DialogDescription = forwardRef<HTMLParagraphElement, DialogDescriptionProps>(
|
|
185
216
|
({ classNames, srOnly, ...props }, forwardedRef) => {
|
|
186
217
|
const { tx } = useThemeContext();
|
|
187
218
|
return (
|
|
188
|
-
<
|
|
219
|
+
<DialogPrimitive.Description
|
|
189
220
|
{...props}
|
|
190
|
-
className={tx('dialog.
|
|
221
|
+
className={tx('dialog.description', { srOnly }, classNames)}
|
|
191
222
|
ref={forwardedRef}
|
|
192
223
|
/>
|
|
193
224
|
);
|
|
194
225
|
},
|
|
195
226
|
);
|
|
196
227
|
|
|
197
|
-
//
|
|
198
|
-
// Description
|
|
199
|
-
//
|
|
200
|
-
|
|
201
|
-
type DialogDescriptionProps = ThemedClassName<DialogDescriptionPrimitiveProps> & { srOnly?: boolean };
|
|
202
|
-
|
|
203
|
-
const DialogDescription: ForwardRefExoticComponent<DialogTitleProps> = forwardRef<
|
|
204
|
-
HTMLParagraphElement,
|
|
205
|
-
DialogDescriptionProps
|
|
206
|
-
>(({ classNames, srOnly, ...props }, forwardedRef) => {
|
|
207
|
-
const { tx } = useThemeContext();
|
|
208
|
-
return (
|
|
209
|
-
<DialogDescriptionPrimitive
|
|
210
|
-
{...props}
|
|
211
|
-
className={tx('dialog.description', 'dialog__description', { srOnly }, classNames)}
|
|
212
|
-
ref={forwardedRef}
|
|
213
|
-
/>
|
|
214
|
-
);
|
|
215
|
-
});
|
|
216
|
-
|
|
217
228
|
//
|
|
218
229
|
// ActionBar
|
|
219
230
|
//
|
|
220
231
|
|
|
221
|
-
type DialogActionBarProps =
|
|
232
|
+
type DialogActionBarProps = SlottableProps;
|
|
222
233
|
|
|
223
|
-
const DialogActionBar
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
>(({ children, classNames, ...props }, forwardedRef) => {
|
|
234
|
+
const DialogActionBar = slottable<HTMLDivElement>(({ children, asChild, ...props }, forwardedRef) => {
|
|
235
|
+
const { className: classNames, ...rest } = composableProps(props);
|
|
236
|
+
const Comp = asChild ? Slot : Primitive.div;
|
|
227
237
|
const { tx } = useThemeContext();
|
|
228
238
|
return (
|
|
229
|
-
<
|
|
239
|
+
<Comp {...rest} className={tx('dialog.actionbar', {}, classNames)} ref={forwardedRef}>
|
|
230
240
|
{children}
|
|
231
|
-
</
|
|
241
|
+
</Comp>
|
|
232
242
|
);
|
|
233
243
|
});
|
|
234
244
|
|
|
@@ -236,34 +246,9 @@ const DialogActionBar: ForwardRefExoticComponent<DialogActionBarProps> = forward
|
|
|
236
246
|
// Close
|
|
237
247
|
//
|
|
238
248
|
|
|
239
|
-
type DialogCloseProps =
|
|
240
|
-
|
|
241
|
-
const DialogClose: FunctionComponent<DialogCloseProps> = DialogClosePrimitive;
|
|
242
|
-
|
|
243
|
-
//
|
|
244
|
-
// Close Button
|
|
245
|
-
//
|
|
249
|
+
type DialogCloseProps = DialogPrimitive.DialogCloseProps;
|
|
246
250
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
const DialogCloseIconButton: ForwardRefExoticComponent<DialogCloseIconButtonProps> = forwardRef<
|
|
250
|
-
HTMLButtonElement,
|
|
251
|
-
DialogCloseIconButtonProps
|
|
252
|
-
>((props, forwardedRef) => {
|
|
253
|
-
const { t } = useTranslation(osTranslations);
|
|
254
|
-
return (
|
|
255
|
-
<IconButton
|
|
256
|
-
{...props}
|
|
257
|
-
label={props.label ?? t('close dialog label')}
|
|
258
|
-
icon='ph--x--regular'
|
|
259
|
-
iconOnly
|
|
260
|
-
size={4}
|
|
261
|
-
density='fine'
|
|
262
|
-
variant='ghost'
|
|
263
|
-
ref={forwardedRef}
|
|
264
|
-
/>
|
|
265
|
-
);
|
|
266
|
-
});
|
|
251
|
+
const DialogClose: FunctionComponent<DialogCloseProps> = DialogPrimitive.Close;
|
|
267
252
|
|
|
268
253
|
//
|
|
269
254
|
// Dialog
|
|
@@ -0,0 +1,45 @@
|
|
|
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
|
+
import { ErrorFallback } from './ErrorFallback';
|
|
12
|
+
import { ThrowError } from './ThrowError';
|
|
13
|
+
|
|
14
|
+
const DefaultStory = () => {
|
|
15
|
+
return (
|
|
16
|
+
<ErrorBoundary name='story' FallbackComponent={ErrorFallback}>
|
|
17
|
+
<ThrowError />
|
|
18
|
+
</ErrorBoundary>
|
|
19
|
+
);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const meta: Meta = {
|
|
23
|
+
title: 'ui/react-ui-core/components/ErrorFallback',
|
|
24
|
+
component: ErrorFallback,
|
|
25
|
+
decorators: [withTheme(), withLayout({ layout: 'column' })],
|
|
26
|
+
parameters: {
|
|
27
|
+
layout: 'fullscreen',
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export default meta;
|
|
32
|
+
|
|
33
|
+
type Story = StoryObj<typeof meta>;
|
|
34
|
+
|
|
35
|
+
export const Default: Story = {
|
|
36
|
+
render: DefaultStory,
|
|
37
|
+
play: async () => {
|
|
38
|
+
// This story intentionally renders an ErrorBoundary fallback; clear the smoke-test error flag.
|
|
39
|
+
(window as any).__ERROR_BOUNDARY_ERRORS__ = [];
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const StringError: Story = {
|
|
44
|
+
render: () => <ErrorFallback error='This is a string error message' data={{ context: 'story' }} />,
|
|
45
|
+
};
|
|
@@ -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,114 @@
|
|
|
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
|
+
export type ParsedStackFrame = ReturnType<typeof ErrorStackParser.parse>[number];
|
|
13
|
+
|
|
14
|
+
export type ErrorStackProps = {
|
|
15
|
+
/** When set, these frames are shown instead of parsing `error`. */
|
|
16
|
+
frames?: ParsedStackFrame[];
|
|
17
|
+
/** Used when `frames` is omitted. */
|
|
18
|
+
error?: Error;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Parses `captureOwnerStack()` output (React dev) into frames for {@link ErrorStack}.
|
|
23
|
+
* Prefixes a synthetic Error line when needed so `error-stack-parser` can read V8-style stacks.
|
|
24
|
+
*/
|
|
25
|
+
export const parseCaptureOwnerStack = (stack: string | null): ParsedStackFrame[] | null => {
|
|
26
|
+
if (stack == null || stack.length === 0) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
const err = new Error();
|
|
30
|
+
err.stack = stack;
|
|
31
|
+
try {
|
|
32
|
+
return ErrorStackParser.parse(err);
|
|
33
|
+
} catch {
|
|
34
|
+
err.stack = `Error\n${stack}`;
|
|
35
|
+
try {
|
|
36
|
+
return ErrorStackParser.parse(err);
|
|
37
|
+
} catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Renders a parsed error stack trace with tree connector symbols and clickable vscode:// links for local frames.
|
|
45
|
+
*/
|
|
46
|
+
export const ErrorStack = ({ error, frames: framesProp }: ErrorStackProps) => {
|
|
47
|
+
const frames = framesProp ?? (error ? ErrorStackParser.parse(error) : []);
|
|
48
|
+
if (frames.length === 0) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<div className='font-mono text-sm'>
|
|
54
|
+
{frames.map((frame, i) => {
|
|
55
|
+
const isLast = i === frames.length - 1;
|
|
56
|
+
const local = frame.fileName
|
|
57
|
+
? parseLocalFrame(frame.fileName, frame.lineNumber, frame.columnNumber)
|
|
58
|
+
: undefined;
|
|
59
|
+
const name = frame.functionName ?? '<anonymous>';
|
|
60
|
+
return (
|
|
61
|
+
<div
|
|
62
|
+
key={i}
|
|
63
|
+
className={mx(
|
|
64
|
+
'grid grid-cols-[16px_1fr_auto_auto] items-stretch gap-x-2',
|
|
65
|
+
local && 'cursor-pointer hover:bg-hover-surface',
|
|
66
|
+
)}
|
|
67
|
+
>
|
|
68
|
+
{/* Tree connector: vertical line full-height + horizontal branch at midpoint */}
|
|
69
|
+
<div className='relative'>
|
|
70
|
+
<div
|
|
71
|
+
className={mx(
|
|
72
|
+
'absolute left-1/2 -translate-x-1/2 w-px bg-neutral-500',
|
|
73
|
+
isLast ? 'top-0 h-1/2' : 'inset-y-0',
|
|
74
|
+
)}
|
|
75
|
+
/>
|
|
76
|
+
<div className='absolute top-1/2 -translate-y-1/2 left-1/2 right-0 h-px bg-neutral-500' />
|
|
77
|
+
</div>
|
|
78
|
+
{local ? (
|
|
79
|
+
<a href={local.href} className='truncate self-center'>
|
|
80
|
+
{name}
|
|
81
|
+
</a>
|
|
82
|
+
) : (
|
|
83
|
+
<span className='text-subdued truncate self-center'>{name}</span>
|
|
84
|
+
)}
|
|
85
|
+
<span className='text-xs text-subdued truncate self-center'>{local?.fileName ?? ''}</span>
|
|
86
|
+
<span className='text-xs text-subdued text-right self-center'>
|
|
87
|
+
{local ? `${frame.lineNumber}:${frame.columnNumber}` : ''}
|
|
88
|
+
</span>
|
|
89
|
+
</div>
|
|
90
|
+
);
|
|
91
|
+
})}
|
|
92
|
+
</div>
|
|
93
|
+
);
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Parses a Vite `/@fs/` URL into a `vscode://` deep link and short filename.
|
|
98
|
+
* Returns undefined if the URL cannot be resolved to a local file.
|
|
99
|
+
*/
|
|
100
|
+
const parseLocalFrame = (fileUrl: string, line?: number, col?: number): LocalFrame | undefined => {
|
|
101
|
+
try {
|
|
102
|
+
const { pathname } = new URL(fileUrl);
|
|
103
|
+
if (!pathname.startsWith('/@fs/')) {
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
const localPath = pathname.slice(4); // /@fs/Users/... → /Users/...
|
|
107
|
+
return {
|
|
108
|
+
href: `vscode://file/${localPath}:${line ?? 1}:${col ?? 1}`,
|
|
109
|
+
fileName: pathname.split('/').pop() ?? localPath,
|
|
110
|
+
};
|
|
111
|
+
} catch {
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
};
|
|
@@ -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`).
|