@dxos/react-ui 0.8.4-main.2e9d522 → 0.8.4-main.3c1ae3b
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-2COVUP44.mjs → chunk-BFCXP6YC.mjs} +656 -319
- package/dist/lib/browser/chunk-BFCXP6YC.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +12 -1
- package/dist/lib/browser/index.mjs.map +2 -2
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +57 -29
- package/dist/lib/browser/testing/index.mjs.map +4 -4
- package/dist/lib/node-esm/{chunk-GHXHND5V.mjs → chunk-F4Z46DD6.mjs} +656 -319
- package/dist/lib/node-esm/chunk-F4Z46DD6.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +12 -1
- package/dist/lib/node-esm/index.mjs.map +2 -2
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +57 -29
- package/dist/lib/node-esm/testing/index.mjs.map +4 -4
- 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 +5 -31
- package/dist/types/src/components/Avatars/Avatar.stories.d.ts.map +1 -1
- package/dist/types/src/components/Avatars/AvatarGroup.stories.d.ts +5 -11
- package/dist/types/src/components/Avatars/AvatarGroup.stories.d.ts.map +1 -1
- package/dist/types/src/components/Breadcrumb/Breadcrumb.d.ts +1 -1
- package/dist/types/src/components/Breadcrumb/Breadcrumb.d.ts.map +1 -1
- package/dist/types/src/components/Breadcrumb/Breadcrumb.stories.d.ts +8 -20
- package/dist/types/src/components/Breadcrumb/Breadcrumb.stories.d.ts.map +1 -1
- package/dist/types/src/components/{Buttons → Button}/Button.d.ts +1 -1
- package/dist/types/src/components/Button/Button.d.ts.map +1 -0
- package/dist/types/src/components/Button/Button.stories.d.ts +17 -0
- package/dist/types/src/components/Button/Button.stories.d.ts.map +1 -0
- package/dist/types/src/components/{Buttons → Button}/IconButton.d.ts +4 -4
- package/dist/types/src/components/Button/IconButton.d.ts.map +1 -0
- package/dist/types/src/components/Button/IconButton.stories.d.ts +13 -0
- package/dist/types/src/components/Button/IconButton.stories.d.ts.map +1 -0
- package/dist/types/src/components/Button/Toggle.d.ts.map +1 -0
- package/dist/types/src/components/Button/Toggle.stories.d.ts +16 -0
- package/dist/types/src/components/Button/Toggle.stories.d.ts.map +1 -0
- package/dist/types/src/components/{Buttons → Button}/ToggleGroup.d.ts +7 -8
- package/dist/types/src/components/Button/ToggleGroup.d.ts.map +1 -0
- package/dist/types/src/components/Button/ToggleGroup.stories.d.ts +27 -0
- package/dist/types/src/components/Button/ToggleGroup.stories.d.ts.map +1 -0
- package/dist/types/src/components/Button/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 +1 -1
- package/dist/types/src/components/Clipboard/CopyButton.d.ts.map +1 -1
- package/dist/types/src/components/DensityProvider/DensityProvider.d.ts.map +1 -1
- package/dist/types/src/components/{Dialogs → Dialog}/AlertDialog.d.ts +1 -1
- package/dist/types/src/components/Dialog/AlertDialog.d.ts.map +1 -0
- package/dist/types/src/components/Dialog/AlertDialog.stories.d.ts +11 -0
- package/dist/types/src/components/Dialog/AlertDialog.stories.d.ts.map +1 -0
- package/dist/types/src/components/{Dialogs → Dialog}/Dialog.d.ts +3 -3
- package/dist/types/src/components/Dialog/Dialog.d.ts.map +1 -0
- package/dist/types/src/components/Dialog/Dialog.stories.d.ts +25 -0
- package/dist/types/src/components/Dialog/Dialog.stories.d.ts.map +1 -0
- package/dist/types/src/components/Dialog/index.d.ts.map +1 -0
- package/dist/types/src/components/ElevationProvider/ElevationProvider.d.ts.map +1 -1
- package/dist/types/src/components/Icon/Icon.d.ts +1 -1
- package/dist/types/src/components/Icon/Icon.d.ts.map +1 -1
- package/dist/types/src/components/Icon/Icon.stories.d.ts +17 -0
- package/dist/types/src/components/Icon/Icon.stories.d.ts.map +1 -0
- package/dist/types/src/components/Input/Input.d.ts +6 -5
- package/dist/types/src/components/Input/Input.d.ts.map +1 -1
- package/dist/types/src/components/Input/Input.stories.d.ts +10 -11
- package/dist/types/src/components/Input/Input.stories.d.ts.map +1 -1
- package/dist/types/src/components/Link/Link.stories.d.ts +8 -8
- package/dist/types/src/components/Link/Link.stories.d.ts.map +1 -1
- package/dist/types/src/components/{Lists → List}/List.d.ts +2 -2
- package/dist/types/src/components/List/List.d.ts.map +1 -0
- package/dist/types/src/components/List/List.stories.d.ts +14 -0
- package/dist/types/src/components/List/List.stories.d.ts.map +1 -0
- package/dist/types/src/components/List/ListDropIndicator.d.ts.map +1 -0
- package/dist/types/src/components/{Lists → List}/Tree.d.ts +1 -1
- package/dist/types/src/components/List/Tree.d.ts.map +1 -0
- package/dist/types/src/components/List/Tree.stories.d.ts +15 -0
- package/dist/types/src/components/List/Tree.stories.d.ts.map +1 -0
- package/dist/types/src/components/List/TreeDropIndicator.d.ts.map +1 -0
- package/dist/types/src/components/{Lists → List}/Treegrid.d.ts +1 -1
- package/dist/types/src/components/{Lists → List}/Treegrid.d.ts.map +1 -1
- package/dist/types/src/components/List/Treegrid.stories.d.ts +12 -0
- package/dist/types/src/components/List/Treegrid.stories.d.ts.map +1 -0
- package/dist/types/src/components/List/index.d.ts.map +1 -0
- package/dist/types/src/components/Main/Main.d.ts +10 -19
- package/dist/types/src/components/Main/Main.d.ts.map +1 -1
- package/dist/types/src/components/Main/Main.stories.d.ts +6 -7
- package/dist/types/src/components/Main/Main.stories.d.ts.map +1 -1
- package/dist/types/src/components/Menus/ContextMenu.d.ts.map +1 -1
- package/dist/types/src/components/Menus/ContextMenu.stories.d.ts +6 -44
- package/dist/types/src/components/Menus/ContextMenu.stories.d.ts.map +1 -1
- package/dist/types/src/components/Menus/DropdownMenu.d.ts +8 -8
- package/dist/types/src/components/Menus/DropdownMenu.d.ts.map +1 -1
- package/dist/types/src/components/Menus/DropdownMenu.stories.d.ts +6 -41
- package/dist/types/src/components/Menus/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 +7 -16
- package/dist/types/src/components/Message/Message.stories.d.ts.map +1 -1
- package/dist/types/src/components/Popover/Popover.d.ts +2 -2
- package/dist/types/src/components/Popover/Popover.d.ts.map +1 -1
- package/dist/types/src/components/Popover/Popover.stories.d.ts +6 -34
- package/dist/types/src/components/Popover/Popover.stories.d.ts.map +1 -1
- package/dist/types/src/components/ScrollArea/ScrollArea.d.ts +1 -1
- package/dist/types/src/components/ScrollArea/ScrollArea.d.ts.map +1 -1
- package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts +6 -32
- package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts.map +1 -1
- package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts +39 -0
- package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts.map +1 -0
- package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts +19 -0
- package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts.map +1 -0
- package/dist/types/src/components/ScrollContainer/index.d.ts +2 -0
- package/dist/types/src/components/ScrollContainer/index.d.ts.map +1 -0
- package/dist/types/src/components/Select/Select.d.ts +1 -1
- package/dist/types/src/components/Select/Select.d.ts.map +1 -1
- package/dist/types/src/components/Select/Select.stories.d.ts +4 -9
- package/dist/types/src/components/Select/Select.stories.d.ts.map +1 -1
- package/dist/types/src/components/Status/Status.stories.d.ts +2 -8
- package/dist/types/src/components/Status/Status.stories.d.ts.map +1 -1
- package/dist/types/src/components/Tag/Tag.stories.d.ts +12 -12
- 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/TranslationsProvider.d.ts +1 -1
- package/dist/types/src/components/ThemeProvider/TranslationsProvider.d.ts.map +1 -1
- package/dist/types/src/components/Toast/Toast.d.ts +1 -1
- package/dist/types/src/components/Toast/Toast.d.ts.map +1 -1
- package/dist/types/src/components/Toast/Toast.stories.d.ts +6 -44
- package/dist/types/src/components/Toast/Toast.stories.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.d.ts +12 -12
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +6 -50
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
- package/dist/types/src/components/Tooltip/Tooltip.d.ts +2 -4
- package/dist/types/src/components/Tooltip/Tooltip.d.ts.map +1 -1
- package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts +8 -61
- package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +4 -3
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useSafeArea.d.ts.map +1 -1
- package/dist/types/src/hooks/useVisualViewport.d.ts +2 -2
- package/dist/types/src/hooks/useVisualViewport.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/playground/Controls.stories.d.ts +5 -9
- package/dist/types/src/playground/Controls.stories.d.ts.map +1 -1
- package/dist/types/src/playground/Custom.stories.d.ts +12 -4
- package/dist/types/src/playground/Custom.stories.d.ts.map +1 -1
- package/dist/types/src/playground/Typography.stories.d.ts +5 -11
- package/dist/types/src/playground/Typography.stories.d.ts.map +1 -1
- package/dist/types/src/testing/decorators/index.d.ts +2 -1
- package/dist/types/src/testing/decorators/index.d.ts.map +1 -1
- package/dist/types/src/testing/decorators/withLayout.d.ts +15 -0
- package/dist/types/src/testing/decorators/withLayout.d.ts.map +1 -0
- package/dist/types/src/testing/decorators/{withSurfaceVariantsLayout.d.ts → withLayoutVariants.d.ts} +2 -2
- package/dist/types/src/testing/decorators/withLayoutVariants.d.ts.map +1 -0
- package/dist/types/src/testing/decorators/withTheme.d.ts +3 -0
- package/dist/types/src/testing/decorators/withTheme.d.ts.map +1 -1
- package/dist/types/src/util/domino.d.ts +18 -0
- package/dist/types/src/util/domino.d.ts.map +1 -0
- package/dist/types/src/util/index.d.ts +2 -0
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/usePx.d.ts +8 -0
- package/dist/types/src/util/usePx.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +26 -23
- package/src/components/Avatars/Avatar.stories.tsx +19 -10
- package/src/components/Avatars/Avatar.tsx +3 -3
- package/src/components/Avatars/AvatarGroup.stories.tsx +10 -6
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +17 -12
- package/src/components/Breadcrumb/Breadcrumb.tsx +1 -1
- package/src/components/{Buttons → Button}/Button.stories.tsx +8 -9
- package/src/components/{Buttons → Button}/IconButton.stories.tsx +11 -8
- package/src/components/{Buttons → Button}/IconButton.tsx +19 -15
- package/src/components/{Buttons → Button}/Toggle.stories.tsx +13 -9
- package/src/components/{Buttons → Button}/ToggleGroup.stories.tsx +10 -7
- package/src/components/{Buttons → Button}/ToggleGroup.tsx +17 -4
- package/src/components/Clipboard/ClipboardProvider.tsx +1 -1
- package/src/components/Clipboard/CopyButton.tsx +3 -2
- package/src/components/DensityProvider/DensityProvider.tsx +1 -1
- package/src/components/{Dialogs → Dialog}/AlertDialog.stories.tsx +15 -12
- package/src/components/{Dialogs → Dialog}/AlertDialog.tsx +13 -13
- package/src/components/{Dialogs → Dialog}/Dialog.stories.tsx +17 -15
- package/src/components/{Dialogs → Dialog}/Dialog.tsx +20 -14
- package/src/components/ElevationProvider/ElevationProvider.tsx +1 -1
- package/src/components/Icon/Icon.stories.tsx +113 -0
- package/src/components/Icon/Icon.tsx +1 -1
- package/src/components/Input/Input.stories.tsx +12 -14
- package/src/components/Input/Input.tsx +27 -18
- package/src/components/Link/Link.stories.tsx +10 -6
- package/src/components/{Lists → List}/List.stories.tsx +16 -14
- package/src/components/{Lists → List}/List.tsx +16 -12
- package/src/components/{Lists → List}/ListDropIndicator.tsx +1 -1
- package/src/components/{Lists → List}/Tree.stories.tsx +11 -8
- package/src/components/{Lists → List}/Tree.tsx +4 -3
- package/src/components/{Lists → List}/TreeDropIndicator.tsx +1 -1
- package/src/components/{Lists → List}/Treegrid.stories.tsx +12 -6
- package/src/components/{Lists → List}/Treegrid.tsx +58 -17
- package/src/components/Main/Main.stories.tsx +17 -9
- package/src/components/Main/Main.tsx +43 -28
- package/src/components/Menus/ContextMenu.stories.tsx +11 -8
- package/src/components/Menus/ContextMenu.tsx +1 -0
- package/src/components/Menus/DropdownMenu.stories.tsx +12 -9
- package/src/components/Menus/DropdownMenu.tsx +45 -16
- package/src/components/Message/Message.stories.tsx +11 -7
- package/src/components/Message/Message.tsx +3 -1
- package/src/components/Popover/Popover.stories.tsx +12 -9
- package/src/components/Popover/Popover.tsx +29 -12
- package/src/components/ScrollArea/ScrollArea.stories.tsx +12 -9
- package/src/components/ScrollArea/ScrollArea.tsx +4 -4
- package/src/components/ScrollContainer/ScrollContainer.stories.tsx +70 -0
- package/src/components/ScrollContainer/ScrollContainer.tsx +233 -0
- package/src/components/ScrollContainer/index.ts +5 -0
- package/src/components/Select/Select.stories.tsx +15 -12
- package/src/components/Select/Select.tsx +9 -8
- package/src/components/Status/Status.stories.tsx +9 -6
- package/src/components/Tag/Tag.stories.tsx +18 -9
- package/src/components/ThemeProvider/ThemeProvider.tsx +3 -2
- package/src/components/ThemeProvider/TranslationsProvider.tsx +3 -3
- package/src/components/Toast/Toast.stories.tsx +12 -9
- package/src/components/Toast/Toast.tsx +9 -9
- package/src/components/Toolbar/Toolbar.stories.tsx +14 -12
- package/src/components/Toolbar/Toolbar.tsx +20 -8
- package/src/components/Tooltip/Tooltip.stories.tsx +16 -12
- package/src/components/Tooltip/Tooltip.tsx +5 -4
- package/src/components/index.ts +4 -3
- package/src/hooks/useSafeArea.ts +3 -2
- package/src/hooks/useVisualViewport.ts +4 -4
- package/src/index.ts +1 -1
- package/src/playground/Controls.stories.tsx +12 -8
- package/src/playground/Custom.stories.tsx +13 -24
- package/src/playground/Typography.stories.tsx +8 -6
- package/src/testing/decorators/index.ts +2 -1
- package/src/testing/decorators/withLayout.tsx +56 -0
- package/src/testing/decorators/{withSurfaceVariantsLayout.tsx → withLayoutVariants.tsx} +3 -3
- package/src/testing/decorators/withTheme.tsx +31 -0
- package/src/util/domino.ts +53 -0
- package/src/util/index.ts +2 -0
- package/src/util/usePx.ts +61 -0
- package/dist/lib/browser/chunk-2COVUP44.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-GHXHND5V.mjs.map +0 -7
- package/dist/types/src/components/Buttons/Button.d.ts.map +0 -1
- package/dist/types/src/components/Buttons/Button.stories.d.ts +0 -12
- package/dist/types/src/components/Buttons/Button.stories.d.ts.map +0 -1
- package/dist/types/src/components/Buttons/IconButton.d.ts.map +0 -1
- package/dist/types/src/components/Buttons/IconButton.stories.d.ts +0 -22
- package/dist/types/src/components/Buttons/IconButton.stories.d.ts.map +0 -1
- package/dist/types/src/components/Buttons/Toggle.d.ts.map +0 -1
- package/dist/types/src/components/Buttons/Toggle.stories.d.ts +0 -19
- package/dist/types/src/components/Buttons/Toggle.stories.d.ts.map +0 -1
- package/dist/types/src/components/Buttons/ToggleGroup.d.ts.map +0 -1
- package/dist/types/src/components/Buttons/ToggleGroup.stories.d.ts +0 -39
- package/dist/types/src/components/Buttons/ToggleGroup.stories.d.ts.map +0 -1
- package/dist/types/src/components/Buttons/index.d.ts.map +0 -1
- package/dist/types/src/components/Dialogs/AlertDialog.d.ts.map +0 -1
- package/dist/types/src/components/Dialogs/AlertDialog.stories.d.ts +0 -43
- package/dist/types/src/components/Dialogs/AlertDialog.stories.d.ts.map +0 -1
- package/dist/types/src/components/Dialogs/Dialog.d.ts.map +0 -1
- package/dist/types/src/components/Dialogs/Dialog.stories.d.ts +0 -48
- package/dist/types/src/components/Dialogs/Dialog.stories.d.ts.map +0 -1
- package/dist/types/src/components/Dialogs/index.d.ts.map +0 -1
- package/dist/types/src/components/Lists/List.d.ts.map +0 -1
- package/dist/types/src/components/Lists/List.stories.d.ts +0 -37
- package/dist/types/src/components/Lists/List.stories.d.ts.map +0 -1
- package/dist/types/src/components/Lists/ListDropIndicator.d.ts.map +0 -1
- package/dist/types/src/components/Lists/Tree.d.ts.map +0 -1
- package/dist/types/src/components/Lists/Tree.stories.d.ts +0 -41
- package/dist/types/src/components/Lists/Tree.stories.d.ts.map +0 -1
- package/dist/types/src/components/Lists/TreeDropIndicator.d.ts.map +0 -1
- package/dist/types/src/components/Lists/Treegrid.stories.d.ts +0 -10
- package/dist/types/src/components/Lists/Treegrid.stories.d.ts.map +0 -1
- package/dist/types/src/components/Lists/index.d.ts.map +0 -1
- package/dist/types/src/testing/decorators/withSurfaceVariantsLayout.d.ts.map +0 -1
- package/src/testing/decorators/withTheme.ts +0 -25
- /package/dist/types/src/components/{Buttons → Button}/Toggle.d.ts +0 -0
- /package/dist/types/src/components/{Buttons → Button}/index.d.ts +0 -0
- /package/dist/types/src/components/{Dialogs → Dialog}/index.d.ts +0 -0
- /package/dist/types/src/components/{Lists → List}/ListDropIndicator.d.ts +0 -0
- /package/dist/types/src/components/{Lists → List}/TreeDropIndicator.d.ts +0 -0
- /package/dist/types/src/components/{Lists → List}/index.d.ts +0 -0
- /package/src/components/{Buttons → Button}/Button.tsx +0 -0
- /package/src/components/{Buttons → Button}/Toggle.tsx +0 -0
- /package/src/components/{Buttons → Button}/index.ts +0 -0
- /package/src/components/{Dialogs → Dialog}/index.ts +0 -0
- /package/src/components/{Lists → List}/index.ts +0 -0
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@
|
|
6
|
-
|
|
5
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
7
6
|
import React from 'react';
|
|
8
7
|
|
|
9
8
|
import { type MessageValence } from '@dxos/react-ui-types';
|
|
10
9
|
|
|
11
|
-
import { Callout } from './Message';
|
|
12
10
|
import { withTheme } from '../../testing';
|
|
13
11
|
|
|
12
|
+
import { Callout } from './Message';
|
|
13
|
+
|
|
14
14
|
type StoryProps = {
|
|
15
15
|
valence: MessageValence;
|
|
16
16
|
title: string;
|
|
@@ -24,9 +24,9 @@ const DefaultStory = ({ valence, title, body }: StoryProps) => (
|
|
|
24
24
|
</Callout.Root>
|
|
25
25
|
);
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
const meta = {
|
|
28
28
|
title: 'ui/react-ui-core/Callout',
|
|
29
|
-
component: Callout,
|
|
29
|
+
component: Callout.Root as any,
|
|
30
30
|
render: DefaultStory,
|
|
31
31
|
decorators: [withTheme],
|
|
32
32
|
parameters: { chromatic: { disableSnapshot: false } },
|
|
@@ -36,9 +36,13 @@ export default {
|
|
|
36
36
|
options: ['success', 'info', 'warning', 'error', 'neutral'],
|
|
37
37
|
},
|
|
38
38
|
},
|
|
39
|
-
}
|
|
39
|
+
} satisfies Meta<typeof DefaultStory>;
|
|
40
|
+
|
|
41
|
+
export default meta;
|
|
42
|
+
|
|
43
|
+
type Story = StoryObj<typeof meta>;
|
|
40
44
|
|
|
41
|
-
export const Default = {
|
|
45
|
+
export const Default: Story = {
|
|
42
46
|
args: {
|
|
43
47
|
valence: 'neutral',
|
|
44
48
|
title: 'Alert title',
|
|
@@ -8,7 +8,7 @@ import { Slot } from '@radix-ui/react-slot';
|
|
|
8
8
|
import React, { type ComponentPropsWithRef, forwardRef } from 'react';
|
|
9
9
|
|
|
10
10
|
import { useId } from '@dxos/react-hooks';
|
|
11
|
-
import { type
|
|
11
|
+
import { type Elevation, type MessageValence } from '@dxos/react-ui-types';
|
|
12
12
|
|
|
13
13
|
import { useElevationContext, useThemeContext } from '../../hooks';
|
|
14
14
|
import { type ThemedClassName } from '../../util';
|
|
@@ -53,6 +53,7 @@ const MessageRoot = forwardRef<HTMLDivElement, MessageRootProps>(
|
|
|
53
53
|
const descriptionId = useId('message__description', propsDescriptionId);
|
|
54
54
|
const elevation = useElevationContext(propsElevation);
|
|
55
55
|
const Root = asChild ? Slot : Primitive.div;
|
|
56
|
+
|
|
56
57
|
return (
|
|
57
58
|
<MessageProvider {...{ titleId, descriptionId, valence }}>
|
|
58
59
|
<Root
|
|
@@ -84,6 +85,7 @@ const MessageTitle = forwardRef<HTMLHeadingElement, MessageTitleProps>(
|
|
|
84
85
|
const { tx } = useThemeContext();
|
|
85
86
|
const { titleId, valence } = useMessageContext(MESSAGE_TITLE_NAME);
|
|
86
87
|
const Root = asChild ? Slot : Primitive.h2;
|
|
88
|
+
|
|
87
89
|
return (
|
|
88
90
|
<Root
|
|
89
91
|
{...props}
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@
|
|
6
|
-
|
|
5
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
7
6
|
import React, { type PropsWithChildren, type ReactNode, useRef, useState } from 'react';
|
|
8
7
|
|
|
9
8
|
import { faker } from '@dxos/random';
|
|
10
9
|
|
|
11
|
-
import { Popover } from './Popover';
|
|
12
10
|
import { withTheme } from '../../testing';
|
|
13
|
-
import { Button } from '../
|
|
11
|
+
import { Button } from '../Button';
|
|
12
|
+
|
|
13
|
+
import { Popover } from './Popover';
|
|
14
14
|
|
|
15
15
|
faker.seed(1234);
|
|
16
16
|
|
|
@@ -28,15 +28,18 @@ const DefaultStory = ({ openTrigger, children }: PropsWithChildren<{ openTrigger
|
|
|
28
28
|
);
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
const meta = {
|
|
32
32
|
title: 'ui/react-ui-core/Popover',
|
|
33
|
-
component: Popover,
|
|
33
|
+
component: Popover.Root,
|
|
34
34
|
render: DefaultStory,
|
|
35
35
|
decorators: [withTheme],
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
} satisfies Meta<typeof DefaultStory>;
|
|
37
|
+
|
|
38
|
+
export default meta;
|
|
39
|
+
|
|
40
|
+
type Story = StoryObj<typeof meta>;
|
|
38
41
|
|
|
39
|
-
export const Default = {
|
|
42
|
+
export const Default: Story = {
|
|
40
43
|
args: {
|
|
41
44
|
openTrigger: <Button>Open popover</Button>,
|
|
42
45
|
children: faker.lorem.paragraphs(3),
|
|
@@ -22,17 +22,18 @@ import { useControllableState } from '@radix-ui/react-use-controllable-state';
|
|
|
22
22
|
import { hideOthers } from 'aria-hidden';
|
|
23
23
|
import React, {
|
|
24
24
|
type ComponentPropsWithRef,
|
|
25
|
-
|
|
25
|
+
type ComponentPropsWithoutRef,
|
|
26
26
|
type ElementRef,
|
|
27
|
-
type
|
|
27
|
+
type FC,
|
|
28
|
+
type MutableRefObject,
|
|
28
29
|
type ReactNode,
|
|
29
|
-
|
|
30
|
+
type RefObject,
|
|
31
|
+
forwardRef,
|
|
30
32
|
useCallback,
|
|
31
|
-
type ComponentPropsWithoutRef,
|
|
32
|
-
type FC,
|
|
33
|
-
useState,
|
|
34
33
|
useEffect,
|
|
35
|
-
|
|
34
|
+
useMemo,
|
|
35
|
+
useRef,
|
|
36
|
+
useState,
|
|
36
37
|
} from 'react';
|
|
37
38
|
import { RemoveScroll } from 'react-remove-scroll';
|
|
38
39
|
|
|
@@ -182,7 +183,7 @@ PopoverTrigger.displayName = TRIGGER_NAME;
|
|
|
182
183
|
const VIRTUAL_TRIGGER_NAME = 'PopoverVirtualTrigger';
|
|
183
184
|
|
|
184
185
|
interface PopoverVirtualTriggerProps {
|
|
185
|
-
virtualRef: RefObject<PopoverTriggerElement>;
|
|
186
|
+
virtualRef: RefObject<PopoverTriggerElement | null>;
|
|
186
187
|
}
|
|
187
188
|
|
|
188
189
|
const PopoverVirtualTrigger = (props: ScopedProps<PopoverVirtualTriggerProps>) => {
|
|
@@ -194,7 +195,7 @@ const PopoverVirtualTrigger = (props: ScopedProps<PopoverVirtualTriggerProps>) =
|
|
|
194
195
|
context.triggerRef.current = virtualRef.current;
|
|
195
196
|
}
|
|
196
197
|
});
|
|
197
|
-
return <PopperPrimitive.Anchor {...popperScope} virtualRef={virtualRef} />;
|
|
198
|
+
return <PopperPrimitive.Anchor {...popperScope} virtualRef={virtualRef as RefObject<PopoverTriggerElement>} />;
|
|
198
199
|
};
|
|
199
200
|
|
|
200
201
|
PopoverVirtualTrigger.displayName = VIRTUAL_TRIGGER_NAME;
|
|
@@ -396,6 +397,7 @@ type PopoverContentImplElement = ElementRef<typeof PopperPrimitive.Content>;
|
|
|
396
397
|
type FocusScopeProps = ComponentPropsWithoutRef<typeof FocusScope>;
|
|
397
398
|
type DismissableLayerProps = ComponentPropsWithoutRef<typeof DismissableLayer>;
|
|
398
399
|
type PopperContentProps = ThemedClassName<ComponentPropsWithoutRef<typeof PopperPrimitive.Content>>;
|
|
400
|
+
|
|
399
401
|
interface PopoverContentImplProps
|
|
400
402
|
extends Omit<PopperContentProps, 'onPlaced'>,
|
|
401
403
|
Omit<DismissableLayerProps, 'onDismiss'> {
|
|
@@ -431,6 +433,7 @@ const PopoverContentImpl = forwardRef<PopoverContentImplElement, PopoverContentI
|
|
|
431
433
|
onFocusOutside,
|
|
432
434
|
onInteractOutside,
|
|
433
435
|
collisionPadding = 8,
|
|
436
|
+
collisionBoundary,
|
|
434
437
|
classNames,
|
|
435
438
|
...contentProps
|
|
436
439
|
} = props;
|
|
@@ -440,10 +443,23 @@ const PopoverContentImpl = forwardRef<PopoverContentImplElement, PopoverContentI
|
|
|
440
443
|
const elevation = useElevationContext();
|
|
441
444
|
const safeCollisionPadding = useSafeCollisionPadding(collisionPadding);
|
|
442
445
|
|
|
443
|
-
// Make sure the whole tree has focus guards as our `Popover` may be
|
|
444
|
-
// the last element in the DOM (because of the `Portal`)
|
|
446
|
+
// Make sure the whole tree has focus guards as our `Popover` may be the last element in the DOM (because of the `Portal`)
|
|
445
447
|
useFocusGuards();
|
|
446
448
|
|
|
449
|
+
// Check for the closest annotated collision boundary in the DOM tree.
|
|
450
|
+
const computedCollisionBoundary = useMemo(() => {
|
|
451
|
+
const closestBoundary = context.triggerRef.current?.closest(
|
|
452
|
+
'[data-popover-collision-boundary]',
|
|
453
|
+
) as HTMLElement | null;
|
|
454
|
+
return closestBoundary
|
|
455
|
+
? Array.isArray(collisionBoundary)
|
|
456
|
+
? [closestBoundary, ...collisionBoundary]
|
|
457
|
+
: collisionBoundary
|
|
458
|
+
? [closestBoundary, collisionBoundary]
|
|
459
|
+
: [closestBoundary]
|
|
460
|
+
: collisionBoundary;
|
|
461
|
+
}, [context.open, collisionBoundary, context.triggerRef.current]);
|
|
462
|
+
|
|
447
463
|
return (
|
|
448
464
|
<FocusScope
|
|
449
465
|
asChild
|
|
@@ -468,11 +484,12 @@ const PopoverContentImpl = forwardRef<PopoverContentImplElement, PopoverContentI
|
|
|
468
484
|
{...popperScope}
|
|
469
485
|
{...contentProps}
|
|
470
486
|
collisionPadding={safeCollisionPadding}
|
|
487
|
+
collisionBoundary={computedCollisionBoundary}
|
|
471
488
|
className={tx('popover.content', 'popover', { elevation }, classNames)}
|
|
472
489
|
ref={forwardedRef}
|
|
473
490
|
style={{
|
|
474
491
|
...contentProps.style,
|
|
475
|
-
//
|
|
492
|
+
// Re-namespace exposed content custom properties.
|
|
476
493
|
...{
|
|
477
494
|
'--radix-popover-content-transform-origin': 'var(--radix-popper-transform-origin)',
|
|
478
495
|
'--radix-popover-content-available-width': 'var(--radix-popper-available-width)',
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@
|
|
6
|
-
|
|
5
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
7
6
|
import React, { type PropsWithChildren } from 'react';
|
|
8
7
|
|
|
9
8
|
import { faker } from '@dxos/random';
|
|
10
9
|
import { activeSurface, surfaceShadow } from '@dxos/react-ui-theme';
|
|
11
10
|
|
|
12
|
-
import { ScrollArea } from './ScrollArea';
|
|
13
11
|
import { withTheme } from '../../testing';
|
|
14
12
|
|
|
13
|
+
import { ScrollArea } from './ScrollArea';
|
|
14
|
+
|
|
15
15
|
faker.seed(1234);
|
|
16
16
|
|
|
17
17
|
const DefaultStory = ({ children }: PropsWithChildren<{}>) => {
|
|
@@ -33,15 +33,18 @@ const DefaultStory = ({ children }: PropsWithChildren<{}>) => {
|
|
|
33
33
|
);
|
|
34
34
|
};
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
title: 'ui/react-ui-core/
|
|
38
|
-
component: ScrollArea,
|
|
36
|
+
const meta = {
|
|
37
|
+
title: 'ui/react-ui-core/ScrollArea',
|
|
38
|
+
component: ScrollArea as any,
|
|
39
39
|
render: DefaultStory,
|
|
40
40
|
decorators: [withTheme],
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
} satisfies Meta<typeof DefaultStory>;
|
|
42
|
+
|
|
43
|
+
export default meta;
|
|
44
|
+
|
|
45
|
+
type Story = StoryObj<typeof meta>;
|
|
43
46
|
|
|
44
|
-
export const Default = {
|
|
47
|
+
export const Default: Story = {
|
|
45
48
|
args: {
|
|
46
49
|
children: faker.lorem.paragraphs(5),
|
|
47
50
|
},
|
|
@@ -3,16 +3,16 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
|
+
Corner as ScrollAreaPrimitiveCorner,
|
|
7
|
+
type ScrollAreaCornerProps as ScrollAreaPrimitiveCornerProps,
|
|
6
8
|
Root as ScrollAreaPrimitiveRoot,
|
|
7
9
|
type ScrollAreaProps as ScrollAreaPrimitiveRootProps,
|
|
8
|
-
Viewport as ScrollAreaPrimitiveViewport,
|
|
9
|
-
type ScrollAreaViewportProps as ScrollAreaPrimitiveViewportProps,
|
|
10
10
|
Scrollbar as ScrollAreaPrimitiveScrollbar,
|
|
11
11
|
type ScrollAreaScrollbarProps as ScrollAreaPrimitiveScrollbarProps,
|
|
12
12
|
Thumb as ScrollAreaPrimitiveThumb,
|
|
13
13
|
type ScrollAreaThumbProps as ScrollAreaPrimitiveThumbProps,
|
|
14
|
-
|
|
15
|
-
type
|
|
14
|
+
Viewport as ScrollAreaPrimitiveViewport,
|
|
15
|
+
type ScrollAreaViewportProps as ScrollAreaPrimitiveViewportProps,
|
|
16
16
|
} from '@radix-ui/react-scroll-area';
|
|
17
17
|
import React, { forwardRef } from 'react';
|
|
18
18
|
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
|
+
import React, { useEffect, useRef, useState } from 'react';
|
|
7
|
+
|
|
8
|
+
import { faker } from '@dxos/random';
|
|
9
|
+
|
|
10
|
+
import { withLayout, withTheme } from '../../testing';
|
|
11
|
+
import { Button } from '../Button';
|
|
12
|
+
import { Toolbar } from '../Toolbar';
|
|
13
|
+
|
|
14
|
+
import { ScrollContainer, type ScrollContainerRootProps, type ScrollController } from './ScrollContainer';
|
|
15
|
+
|
|
16
|
+
const DefaultStory = (props: ScrollContainerRootProps) => {
|
|
17
|
+
const [lines, setLines] = useState<string[]>([]);
|
|
18
|
+
const [running, setRunning] = useState(true);
|
|
19
|
+
const scroller = useRef<ScrollController>(null);
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (!running) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const i = setInterval(() => {
|
|
26
|
+
setLines((lines) => [...lines, faker.lorem.paragraph()]);
|
|
27
|
+
}, 500);
|
|
28
|
+
|
|
29
|
+
return () => clearInterval(i);
|
|
30
|
+
}, [running]);
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<div className='flex flex-col bs-full overflow-hidden'>
|
|
34
|
+
<Toolbar.Root>
|
|
35
|
+
<Button onClick={() => setRunning((running) => !running)}>{running ? 'Stop' : 'Start'}</Button>
|
|
36
|
+
<Button onClick={() => scroller.current?.scrollToBottom()}>Scroll to bottom</Button>
|
|
37
|
+
<div className='flex-1' />
|
|
38
|
+
<div>{lines.length}</div>
|
|
39
|
+
</Toolbar.Root>
|
|
40
|
+
<ScrollContainer.Root {...props} ref={scroller}>
|
|
41
|
+
<ScrollContainer.Viewport>
|
|
42
|
+
{lines.map((line, index) => (
|
|
43
|
+
<div key={index} className='p-2'>
|
|
44
|
+
{line}
|
|
45
|
+
</div>
|
|
46
|
+
))}
|
|
47
|
+
</ScrollContainer.Viewport>
|
|
48
|
+
<ScrollContainer.ScrollDownButton />
|
|
49
|
+
</ScrollContainer.Root>
|
|
50
|
+
</div>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const meta = {
|
|
55
|
+
title: 'ui/react-ui-core/ScrollContainer',
|
|
56
|
+
component: ScrollContainer.Root,
|
|
57
|
+
render: DefaultStory,
|
|
58
|
+
decorators: [withTheme, withLayout({ container: 'column', classNames: 'is-[30rem]' })],
|
|
59
|
+
} satisfies Meta<typeof DefaultStory>;
|
|
60
|
+
|
|
61
|
+
export default meta;
|
|
62
|
+
|
|
63
|
+
type Story = StoryObj<typeof meta>;
|
|
64
|
+
|
|
65
|
+
export const Default: Story = {
|
|
66
|
+
args: {
|
|
67
|
+
pin: true,
|
|
68
|
+
fade: true,
|
|
69
|
+
},
|
|
70
|
+
};
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { useState } from '@preact-signals/safe-react/react';
|
|
6
|
+
import { createContext } from '@radix-ui/react-context';
|
|
7
|
+
import React, {
|
|
8
|
+
type HTMLAttributes,
|
|
9
|
+
type PropsWithChildren,
|
|
10
|
+
forwardRef,
|
|
11
|
+
useCallback,
|
|
12
|
+
useEffect,
|
|
13
|
+
useImperativeHandle,
|
|
14
|
+
useMemo,
|
|
15
|
+
useRef,
|
|
16
|
+
} from 'react';
|
|
17
|
+
|
|
18
|
+
// TODO(burdon): Move these deps to @dxos/dom-util.
|
|
19
|
+
import { addEventListener, combine } from '@dxos/async';
|
|
20
|
+
import { invariant } from '@dxos/invariant';
|
|
21
|
+
import { useForwardedRef } from '@dxos/react-hooks';
|
|
22
|
+
import { mx } from '@dxos/react-ui-theme';
|
|
23
|
+
|
|
24
|
+
import { type ThemedClassName } from '../../util';
|
|
25
|
+
import { IconButton } from '../Button';
|
|
26
|
+
|
|
27
|
+
const isBottom = (el: HTMLElement | null) => {
|
|
28
|
+
return !!(el && el.scrollHeight - el.scrollTop === el.clientHeight);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export interface ScrollController {
|
|
32
|
+
viewport: HTMLDivElement | null;
|
|
33
|
+
scrollToTop: (behavior?: ScrollBehavior) => void;
|
|
34
|
+
scrollToBottom: (behavior?: ScrollBehavior) => void;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
type ScrollContainerContextValue = {
|
|
38
|
+
scrollToBottom: (behavior?: ScrollBehavior) => void;
|
|
39
|
+
controller?: ScrollController;
|
|
40
|
+
pinned?: boolean;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const [ScrollContainerProvider, useScrollContainerContext] =
|
|
44
|
+
createContext<ScrollContainerContextValue>('ScrollContainer');
|
|
45
|
+
|
|
46
|
+
//
|
|
47
|
+
// Root
|
|
48
|
+
//
|
|
49
|
+
|
|
50
|
+
type RootProps = ThemedClassName<
|
|
51
|
+
PropsWithChildren<{
|
|
52
|
+
pin?: boolean;
|
|
53
|
+
fade?: boolean;
|
|
54
|
+
behavior?: ScrollBehavior;
|
|
55
|
+
}>
|
|
56
|
+
>;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Scroll container that automatically scrolls to the bottom when new content is added.
|
|
60
|
+
*/
|
|
61
|
+
const Root = forwardRef<ScrollController, RootProps>(
|
|
62
|
+
({ children, classNames, pin, fade, behavior: behaviorProp = 'smooth' }, forwardedRef) => {
|
|
63
|
+
const scrollerRef = useRef<HTMLDivElement>(null);
|
|
64
|
+
const autoScrollRef = useRef(false);
|
|
65
|
+
const [overflow, setOverflow] = useState(false);
|
|
66
|
+
const [pinned, setPinned] = useState(pin);
|
|
67
|
+
|
|
68
|
+
const timeoutRef = useRef<NodeJS.Timeout>(undefined);
|
|
69
|
+
const scrollToBottom = useCallback((behavior: ScrollBehavior = behaviorProp) => {
|
|
70
|
+
if (scrollerRef.current) {
|
|
71
|
+
// Temporarily hide scrollbar to prevent flicker.
|
|
72
|
+
autoScrollRef.current = true;
|
|
73
|
+
scrollerRef.current.classList.add('scrollbar-none');
|
|
74
|
+
scrollerRef.current.scrollTo({
|
|
75
|
+
top: scrollerRef.current.scrollHeight,
|
|
76
|
+
behavior,
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
clearTimeout(timeoutRef.current);
|
|
80
|
+
if (behavior !== 'instant') {
|
|
81
|
+
timeoutRef.current = setTimeout(() => {
|
|
82
|
+
scrollerRef.current?.classList.remove('scrollbar-none');
|
|
83
|
+
autoScrollRef.current = false;
|
|
84
|
+
}, 500);
|
|
85
|
+
}
|
|
86
|
+
setPinned(true);
|
|
87
|
+
}
|
|
88
|
+
}, []);
|
|
89
|
+
|
|
90
|
+
const controller = useMemo(
|
|
91
|
+
() => ({
|
|
92
|
+
viewport: scrollerRef.current,
|
|
93
|
+
scrollToTop: () => {
|
|
94
|
+
invariant(scrollerRef.current);
|
|
95
|
+
scrollerRef.current.scrollTo({ top: 0, behavior: 'smooth' });
|
|
96
|
+
setPinned(false);
|
|
97
|
+
},
|
|
98
|
+
scrollToBottom: () => {
|
|
99
|
+
scrollToBottom('smooth');
|
|
100
|
+
},
|
|
101
|
+
}),
|
|
102
|
+
[scrollToBottom, scrollerRef.current],
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
// Scroll controller imperative ref.
|
|
106
|
+
useImperativeHandle(forwardedRef, () => controller, [controller]);
|
|
107
|
+
|
|
108
|
+
// Listen for scroll events.
|
|
109
|
+
useEffect(() => {
|
|
110
|
+
if (!scrollerRef.current) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return combine(
|
|
115
|
+
// Check if user scrolls.
|
|
116
|
+
addEventListener(scrollerRef.current, 'wheel', () => {
|
|
117
|
+
setPinned(isBottom(scrollerRef.current));
|
|
118
|
+
}),
|
|
119
|
+
// Check if scrolls.
|
|
120
|
+
addEventListener(scrollerRef.current, 'scroll', () => {
|
|
121
|
+
setOverflow((scrollerRef.current?.scrollTop ?? 0) > 0);
|
|
122
|
+
}),
|
|
123
|
+
);
|
|
124
|
+
}, []);
|
|
125
|
+
|
|
126
|
+
return (
|
|
127
|
+
<ScrollContainerProvider pinned={pinned} controller={controller} scrollToBottom={scrollToBottom}>
|
|
128
|
+
<div className='relative grid flex-1 min-bs-0 overflow-hidden'>
|
|
129
|
+
{fade && (
|
|
130
|
+
<div
|
|
131
|
+
role='none'
|
|
132
|
+
data-visible={overflow}
|
|
133
|
+
className={mx(
|
|
134
|
+
// NOTE: Gradients may not be visible with dark reader extensions.
|
|
135
|
+
'z-10 absolute block-start-0 inset-inline-0 bs-24 is-full',
|
|
136
|
+
'opacity-0 duration-200 transition-opacity data-[visible="true"]:opacity-100',
|
|
137
|
+
'bg-gradient-to-b from-[--surface-bg] to-transparent pointer-events-none',
|
|
138
|
+
)}
|
|
139
|
+
/>
|
|
140
|
+
)}
|
|
141
|
+
<div className={mx('flex flex-col min-bs-0 overflow-y-auto scrollbar-thin', classNames)} ref={scrollerRef}>
|
|
142
|
+
{children}
|
|
143
|
+
</div>
|
|
144
|
+
</div>
|
|
145
|
+
</ScrollContainerProvider>
|
|
146
|
+
);
|
|
147
|
+
},
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
Root.displayName = 'ScrollContainer.Root';
|
|
151
|
+
|
|
152
|
+
//
|
|
153
|
+
// Viewport
|
|
154
|
+
//
|
|
155
|
+
|
|
156
|
+
type ViewportProps = ThemedClassName<PropsWithChildren<Omit<HTMLAttributes<HTMLDivElement>, 'className'>>>;
|
|
157
|
+
|
|
158
|
+
const Viewport = forwardRef<HTMLDivElement, ViewportProps>(({ classNames, children, ...props }, forwardedRef) => {
|
|
159
|
+
const contentRef = useForwardedRef(forwardedRef);
|
|
160
|
+
const { pinned, scrollToBottom } = useScrollContainerContext(Viewport.displayName!);
|
|
161
|
+
|
|
162
|
+
useEffect(() => {
|
|
163
|
+
if (!pinned || !contentRef.current) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Scroll instantly otherwise it might move while we're scrolling.
|
|
168
|
+
scrollToBottom();
|
|
169
|
+
|
|
170
|
+
// Setup resize observer to detect content changes.
|
|
171
|
+
const resizeObserver = new ResizeObserver(() => scrollToBottom());
|
|
172
|
+
resizeObserver.observe(contentRef.current);
|
|
173
|
+
return () => resizeObserver.disconnect();
|
|
174
|
+
}, [pinned, scrollToBottom]);
|
|
175
|
+
|
|
176
|
+
return (
|
|
177
|
+
<div className={mx('is-full', classNames)} {...props} ref={contentRef}>
|
|
178
|
+
{children}
|
|
179
|
+
</div>
|
|
180
|
+
);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
Viewport.displayName = 'ScrollContainer.Viewport';
|
|
184
|
+
|
|
185
|
+
//
|
|
186
|
+
// ScrollDownButton
|
|
187
|
+
//
|
|
188
|
+
|
|
189
|
+
type ScrollDownButtonProps = ThemedClassName;
|
|
190
|
+
|
|
191
|
+
const ScrollDownButton = ({ classNames }: ScrollDownButtonProps) => {
|
|
192
|
+
const { pinned, scrollToBottom } = useScrollContainerContext(ScrollDownButton.displayName!);
|
|
193
|
+
|
|
194
|
+
return (
|
|
195
|
+
<div
|
|
196
|
+
role='none'
|
|
197
|
+
className={mx(
|
|
198
|
+
'absolute bottom-2 right-4 opacity-100 transition-opacity duration-300',
|
|
199
|
+
pinned && 'opacity-0',
|
|
200
|
+
classNames,
|
|
201
|
+
)}
|
|
202
|
+
>
|
|
203
|
+
<IconButton
|
|
204
|
+
variant='primary'
|
|
205
|
+
icon='ph--arrow-down--regular'
|
|
206
|
+
iconOnly
|
|
207
|
+
size={4}
|
|
208
|
+
label='Scroll down'
|
|
209
|
+
onClick={() => scrollToBottom()}
|
|
210
|
+
/>
|
|
211
|
+
</div>
|
|
212
|
+
);
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
ScrollDownButton.displayName = 'ScrollContainer.ScrollDownButton';
|
|
216
|
+
|
|
217
|
+
//
|
|
218
|
+
// ScrollContainer
|
|
219
|
+
//
|
|
220
|
+
|
|
221
|
+
export { useScrollContainerContext };
|
|
222
|
+
|
|
223
|
+
export const ScrollContainer = {
|
|
224
|
+
Root,
|
|
225
|
+
Viewport,
|
|
226
|
+
ScrollDownButton,
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
export type {
|
|
230
|
+
RootProps as ScrollContainerRootProps,
|
|
231
|
+
ViewportProps as ScrollContainerViewportProps,
|
|
232
|
+
ScrollDownButtonProps as ScrollContainerScrollDownButtonProps,
|
|
233
|
+
};
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@
|
|
6
|
-
|
|
7
|
-
import { type StoryObj } from '@storybook/react-vite';
|
|
5
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
8
6
|
import React, { useState } from 'react';
|
|
9
7
|
|
|
10
8
|
import { faker } from '@dxos/random';
|
|
11
9
|
|
|
10
|
+
import { withTheme } from '../../testing';
|
|
11
|
+
import { withLayoutVariants } from '../../testing';
|
|
12
|
+
|
|
12
13
|
import { Select } from './Select';
|
|
13
|
-
import { withSurfaceVariantsLayout, withTheme } from '../../testing';
|
|
14
14
|
|
|
15
15
|
faker.seed(1234);
|
|
16
16
|
|
|
@@ -41,15 +41,18 @@ const DefaultStory = ({ items = [] }: StoryProps) => {
|
|
|
41
41
|
);
|
|
42
42
|
};
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
const meta = {
|
|
45
|
+
title: 'ui/react-ui-core/Select',
|
|
46
|
+
render: DefaultStory,
|
|
47
|
+
decorators: [withTheme, withLayoutVariants()],
|
|
48
|
+
} satisfies Meta<typeof DefaultStory>;
|
|
49
|
+
|
|
50
|
+
export default meta;
|
|
51
|
+
|
|
52
|
+
type Story = StoryObj<typeof meta>;
|
|
53
|
+
|
|
54
|
+
export const Default: Story = {
|
|
45
55
|
args: {
|
|
46
56
|
items: Array.from({ length: 16 }).map((_, i) => ({ id: `item-${i}`, text: faker.lorem.word() })),
|
|
47
57
|
},
|
|
48
58
|
};
|
|
49
|
-
|
|
50
|
-
export default {
|
|
51
|
-
title: 'ui/react-ui-core/Select',
|
|
52
|
-
render: DefaultStory,
|
|
53
|
-
decorators: [withSurfaceVariantsLayout(), withTheme],
|
|
54
|
-
parameters: { chromatic: { disableSnapshot: false } },
|
|
55
|
-
};
|