@dxos/react-ui 0.8.4-main.8360d9e660 → 0.8.4-main.8baae0fced
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-EJSGYGYH.mjs → chunk-LY5XDQR5.mjs} +84 -12
- package/dist/lib/browser/chunk-LY5XDQR5.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +1322 -811
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +30 -24
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/browser/translations.mjs +9 -0
- package/dist/lib/browser/translations.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-B7MXDDMJ.mjs → chunk-NGKLIKP3.mjs} +84 -12
- 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 +1322 -811
- 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 +30 -24
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- 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.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.stories.d.ts.map +1 -1
- package/dist/types/src/components/Button/ToggleGroup.d.ts +2 -2
- 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 +59 -42
- package/dist/types/src/components/Card/Card.d.ts.map +1 -1
- package/dist/types/src/components/Card/Card.stories.d.ts +2 -2
- package/dist/types/src/components/Card/Card.stories.d.ts.map +1 -1
- package/dist/types/src/components/Carousel/Carousel.d.ts +106 -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 +1 -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 +34 -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 +38 -21
- package/dist/types/src/components/Dialog/Dialog.d.ts.map +1 -1
- package/dist/types/src/components/Dialog/Dialog.stories.d.ts +3 -2
- 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.map +1 -1
- package/dist/types/src/components/ErrorFallback/ErrorFallback.stories.d.ts.map +1 -1
- package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts +14 -3
- package/dist/types/src/components/ErrorFallback/ErrorStack.d.ts.map +1 -1
- package/dist/types/src/components/ErrorFallback/ThrowError.d.ts.map +1 -1
- 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 +2 -1
- package/dist/types/src/components/Image/Image.d.ts.map +1 -1
- package/dist/types/src/components/Image/Image.stories.d.ts +3 -2
- package/dist/types/src/components/Image/Image.stories.d.ts.map +1 -1
- package/dist/types/src/components/Input/Input.d.ts +12 -15
- package/dist/types/src/components/Input/Input.d.ts.map +1 -1
- package/dist/types/src/components/Input/Input.stories.d.ts +3 -3
- package/dist/types/src/components/Input/Input.stories.d.ts.map +1 -1
- package/dist/types/src/components/Link/Link.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 +7 -3
- package/dist/types/src/components/Main/Main.d.ts.map +1 -1
- 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 +13 -6
- package/dist/types/src/components/Menu/DropdownMenu.d.ts.map +1 -1
- package/dist/types/src/components/Menu/DropdownMenu.stories.d.ts +9 -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 +2 -2
- package/dist/types/src/components/Message/Message.stories.d.ts.map +1 -1
- package/dist/types/src/components/Popover/Popover.d.ts +14 -3
- 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 -9
- package/dist/types/src/components/ScrollArea/ScrollArea.d.ts.map +1 -1
- package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts +18 -5
- 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 +5 -6
- 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/Skeleton/Skeleton.stories.d.ts.map +1 -1
- package/dist/types/src/components/Splitter/Splitter.d.ts +19 -17
- 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.map +1 -1
- 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 +1 -1
- package/dist/types/src/components/ThemeProvider/ThemeProvider.stories.d.ts.map +1 -1
- 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 +4 -4
- 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 +11 -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 +8 -8
- 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 +3 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/exemplars/generics.stories.d.ts +6 -5
- 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.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 +21 -14
- package/dist/types/src/primitives/Column/Column.d.ts.map +1 -1
- package/dist/types/src/primitives/Column/Column.stories.d.ts +19 -0
- package/dist/types/src/primitives/Column/Column.stories.d.ts.map +1 -1
- package/dist/types/src/primitives/Container/Container.d.ts +4 -5
- package/dist/types/src/primitives/Container/Container.d.ts.map +1 -1
- package/dist/types/src/primitives/Container/Container.stories.d.ts.map +1 -1
- package/dist/types/src/primitives/Flex/Flex.d.ts +5 -7
- package/dist/types/src/primitives/Flex/Flex.d.ts.map +1 -1
- package/dist/types/src/primitives/Flex/Flex.stories.d.ts.map +1 -1
- package/dist/types/src/primitives/Grid/Grid.d.ts +3 -8
- package/dist/types/src/primitives/Grid/Grid.d.ts.map +1 -1
- package/dist/types/src/primitives/Grid/Grid.stories.d.ts.map +1 -1
- package/dist/types/src/primitives/Panel/Panel.d.ts +24 -15
- package/dist/types/src/primitives/Panel/Panel.d.ts.map +1 -1
- package/dist/types/src/primitives/Panel/Panel.stories.d.ts.map +1 -1
- package/dist/types/src/testing/Loading.d.ts.map +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/translations.d.ts +8 -3
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/util/usePx.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +29 -26
- package/src/components/Avatars/Avatar.stories.tsx +2 -3
- package/src/components/Avatars/Avatar.tsx +1 -2
- package/src/components/Avatars/AvatarGroup.stories.tsx +0 -1
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +1 -2
- package/src/components/Button/Button.stories.tsx +0 -1
- package/src/components/Button/Button.tsx +3 -11
- package/src/components/Button/IconButton.stories.tsx +6 -4
- package/src/components/Button/IconButton.tsx +3 -3
- package/src/components/Button/Toggle.stories.tsx +0 -1
- package/src/components/Button/ToggleGroup.stories.tsx +0 -1
- package/src/components/Card/Card.stories.tsx +15 -15
- package/src/components/Card/Card.tsx +190 -66
- package/src/components/Carousel/Carousel.tsx +379 -0
- package/src/components/Carousel/index.ts +5 -0
- package/src/components/Clipboard/CopyButton.tsx +5 -6
- package/src/components/Dialog/AlertDialog.stories.tsx +5 -6
- package/src/components/Dialog/AlertDialog.tsx +51 -93
- package/src/components/Dialog/Dialog.stories.tsx +64 -9
- package/src/components/Dialog/Dialog.tsx +66 -56
- package/src/components/ErrorFallback/ErrorFallback.stories.tsx +3 -8
- package/src/components/ErrorFallback/ErrorStack.tsx +36 -2
- 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 +13 -3
- package/src/components/Image/Image.stories.tsx +3 -3
- package/src/components/Image/Image.tsx +31 -8
- package/src/components/Input/Input.stories.tsx +3 -4
- package/src/components/Input/Input.tsx +3 -3
- package/src/components/Link/Link.stories.tsx +0 -1
- package/src/components/Link/Link.tsx +10 -2
- package/src/components/List/List.stories.tsx +1 -2
- package/src/components/List/List.tsx +7 -6
- package/src/components/List/ListDropIndicator.tsx +0 -1
- package/src/components/List/Tree.stories.tsx +2 -3
- package/src/components/List/Tree.tsx +0 -1
- package/src/components/List/Treegrid.stories.tsx +26 -27
- package/src/components/List/Treegrid.tsx +14 -14
- package/src/components/Main/Main.stories.tsx +0 -1
- package/src/components/Main/Main.tsx +0 -1
- 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/DropdownMenu.stories.tsx +0 -1
- package/src/components/Menu/DropdownMenu.tsx +3 -3
- package/src/components/Message/Message.stories.tsx +7 -8
- package/src/components/Message/Message.tsx +23 -10
- package/src/components/Popover/Popover.stories.tsx +4 -5
- package/src/components/Popover/Popover.tsx +1 -1
- package/src/components/ScrollArea/ScrollArea.stories.tsx +89 -30
- package/src/components/ScrollArea/ScrollArea.tsx +39 -23
- package/src/components/ScrollContainer/ScrollContainer.stories.tsx +19 -17
- package/src/components/ScrollContainer/ScrollContainer.tsx +199 -92
- package/src/components/Select/Select.stories.tsx +5 -6
- package/src/components/Skeleton/Skeleton.stories.tsx +0 -1
- package/src/components/Splitter/Splitter.stories.tsx +29 -29
- package/src/components/Splitter/Splitter.tsx +35 -34
- package/src/components/Status/Status.stories.tsx +0 -1
- package/src/components/Status/Status.tsx +8 -5
- package/src/components/Tag/Tag.stories.tsx +0 -1
- package/src/components/ThemeProvider/ThemeProvider.stories.tsx +0 -1
- package/src/components/ThemeProvider/ThemeProvider.tsx +5 -4
- package/src/components/ThemeProvider/index.ts +1 -1
- package/src/components/Toast/Toast.stories.tsx +0 -1
- package/src/components/Toolbar/Toolbar.stories.tsx +0 -1
- package/src/components/Toolbar/Toolbar.tsx +19 -15
- package/src/components/Tooltip/Tooltip.stories.tsx +7 -8
- package/src/components/Tooltip/Tooltip.tsx +14 -13
- package/src/components/index.ts +3 -0
- package/src/exemplars/generics.stories.tsx +7 -15
- package/src/exemplars/slot.stories.tsx +65 -57
- package/src/exemplars/tabster.stories.tsx +1 -1
- package/src/exemplars/virtualizer.stories.tsx +4 -5
- package/src/hooks/useDensityContext.ts +2 -2
- package/src/playground/Custom.stories.tsx +6 -9
- package/src/primitives/Column/AUDIT.md +148 -0
- package/src/primitives/Column/Column.stories.tsx +122 -19
- package/src/primitives/Column/Column.tsx +73 -41
- package/src/primitives/Container/Container.stories.tsx +0 -1
- package/src/primitives/Container/Container.tsx +5 -8
- package/src/primitives/Flex/Flex.stories.tsx +0 -1
- package/src/primitives/Flex/Flex.tsx +10 -12
- package/src/primitives/Grid/Grid.stories.tsx +0 -1
- package/src/primitives/Grid/Grid.tsx +4 -9
- package/src/primitives/Panel/Panel.stories.tsx +8 -7
- package/src/primitives/Panel/Panel.tsx +64 -63
- package/src/testing/Loading.tsx +25 -4
- package/src/testing/decorators/withLayout.tsx +7 -17
- package/src/testing/decorators/withTheme.tsx +10 -7
- package/src/translations.ts +8 -3
- package/src/util/usePx.ts +1 -0
- package/dist/lib/browser/chunk-EJSGYGYH.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-B7MXDDMJ.mjs.map +0 -7
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { useArrowNavigationGroup } from '@fluentui/react-tabster';
|
|
6
|
+
import React, {
|
|
7
|
+
createContext,
|
|
8
|
+
type KeyboardEvent,
|
|
9
|
+
type PropsWithChildren,
|
|
10
|
+
type ReactNode,
|
|
11
|
+
useCallback,
|
|
12
|
+
useContext,
|
|
13
|
+
useEffect,
|
|
14
|
+
useMemo,
|
|
15
|
+
useState,
|
|
16
|
+
} from 'react';
|
|
17
|
+
|
|
18
|
+
import { mx } from '@dxos/ui-theme';
|
|
19
|
+
|
|
20
|
+
import { translationKey } from '../../translations';
|
|
21
|
+
import { type ThemedClassName } from '../../util';
|
|
22
|
+
import { IconButton } from '../Button';
|
|
23
|
+
import { MediaPlayer, type MediaKind } from '../MediaPlayer';
|
|
24
|
+
import { useTranslation } from '../ThemeProvider';
|
|
25
|
+
|
|
26
|
+
// TODO(burdon): Move per-element class strings to `@dxos/ui-theme` (theme tokens)
|
|
27
|
+
// so callers can re-theme via the same mechanism the rest of `react-ui` uses.
|
|
28
|
+
|
|
29
|
+
//
|
|
30
|
+
// Context
|
|
31
|
+
//
|
|
32
|
+
|
|
33
|
+
type CarouselContextValue = {
|
|
34
|
+
index: number;
|
|
35
|
+
count: number;
|
|
36
|
+
setIndex: (index: number) => void;
|
|
37
|
+
next: () => void;
|
|
38
|
+
prev: () => void;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const CarouselContext = createContext<CarouselContextValue | null>(null);
|
|
42
|
+
|
|
43
|
+
/** Returns the current carousel state. Must be used within {@link Carousel.Root}. */
|
|
44
|
+
export const useCarousel = (): CarouselContextValue => {
|
|
45
|
+
const context = useContext(CarouselContext);
|
|
46
|
+
if (!context) {
|
|
47
|
+
throw new Error('useCarousel must be used within Carousel.Root');
|
|
48
|
+
}
|
|
49
|
+
return context;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
//
|
|
53
|
+
// Root
|
|
54
|
+
//
|
|
55
|
+
|
|
56
|
+
export type CarouselRootProps = ThemedClassName<
|
|
57
|
+
PropsWithChildren<{
|
|
58
|
+
/** Total number of slides; drives auto-advance and indicator counts. */
|
|
59
|
+
count: number;
|
|
60
|
+
/** Whether to auto-advance slides on mount. Defaults to `false`. */
|
|
61
|
+
autorun?: boolean;
|
|
62
|
+
/** Auto-advance interval in milliseconds. Set 0 to disable. */
|
|
63
|
+
intervalMs?: number;
|
|
64
|
+
defaultIndex?: number;
|
|
65
|
+
}>
|
|
66
|
+
>;
|
|
67
|
+
|
|
68
|
+
const CarouselRoot = ({
|
|
69
|
+
classNames,
|
|
70
|
+
children,
|
|
71
|
+
count,
|
|
72
|
+
autorun = false,
|
|
73
|
+
intervalMs = 5_000,
|
|
74
|
+
defaultIndex = 0,
|
|
75
|
+
}: CarouselRootProps) => {
|
|
76
|
+
const [index, setIndexState] = useState(defaultIndex);
|
|
77
|
+
const [autoAdvance, setAutoAdvance] = useState(autorun);
|
|
78
|
+
|
|
79
|
+
// Reset to first slide if the slide count shrinks below the current index.
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
if (index >= count) {
|
|
82
|
+
setIndexState(0);
|
|
83
|
+
}
|
|
84
|
+
}, [count, index]);
|
|
85
|
+
|
|
86
|
+
// Auto-advance — stops permanently once the user interacts with any control.
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
if (!autoAdvance || count <= 1 || intervalMs <= 0) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const handle = setInterval(() => setIndexState((i) => (i + 1) % count), intervalMs);
|
|
92
|
+
return () => clearInterval(handle);
|
|
93
|
+
}, [autoAdvance, count, intervalMs]);
|
|
94
|
+
|
|
95
|
+
const setIndex = useCallback((next: number) => {
|
|
96
|
+
setAutoAdvance(false);
|
|
97
|
+
setIndexState(next);
|
|
98
|
+
}, []);
|
|
99
|
+
const next = useCallback(() => {
|
|
100
|
+
setAutoAdvance(false);
|
|
101
|
+
setIndexState((i) => (i + 1) % count);
|
|
102
|
+
}, [count]);
|
|
103
|
+
const prev = useCallback(() => {
|
|
104
|
+
setAutoAdvance(false);
|
|
105
|
+
setIndexState((i) => (i - 1 + count) % count);
|
|
106
|
+
}, [count]);
|
|
107
|
+
|
|
108
|
+
const value = useMemo(() => ({ index, count, setIndex, next, prev }), [index, count, setIndex, next, prev]);
|
|
109
|
+
|
|
110
|
+
if (count === 0) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return (
|
|
115
|
+
<CarouselContext.Provider value={value}>
|
|
116
|
+
{/*
|
|
117
|
+
* Rows are `[1fr, auto]`: row 1 (Previous|Viewport|Next) stretches when the parent
|
|
118
|
+
* gives the carousel a definite height, and row 2 (Indicators / Caption) sticks to
|
|
119
|
+
* its content height. With no parent height constraint, the `1fr` row simply tracks
|
|
120
|
+
* row-1 content — preserving the existing aspect-video behaviour for unbounded use.
|
|
121
|
+
*/}
|
|
122
|
+
{/* TODO(burdon): Move to ui-theme. */}
|
|
123
|
+
<div
|
|
124
|
+
className={mx(
|
|
125
|
+
'w-full grid grid-cols-[min-content_1fr_min-content] grid-rows-[minmax(0,1fr)_auto] gap-4 items-center',
|
|
126
|
+
classNames,
|
|
127
|
+
)}
|
|
128
|
+
>
|
|
129
|
+
{children}
|
|
130
|
+
</div>
|
|
131
|
+
</CarouselContext.Provider>
|
|
132
|
+
);
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
CarouselRoot.displayName = 'Carousel.Root';
|
|
136
|
+
|
|
137
|
+
//
|
|
138
|
+
// Viewport
|
|
139
|
+
//
|
|
140
|
+
|
|
141
|
+
export type CarouselViewportProps = ThemedClassName<PropsWithChildren<{}>>;
|
|
142
|
+
|
|
143
|
+
const CarouselViewport = ({ children, classNames }: CarouselViewportProps) => {
|
|
144
|
+
const { t } = useTranslation(translationKey);
|
|
145
|
+
const { count, next, prev } = useCarousel();
|
|
146
|
+
const handleKeyDown = useCallback(
|
|
147
|
+
(event: KeyboardEvent<HTMLDivElement>) => {
|
|
148
|
+
if (count <= 1) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (event.key === 'ArrowLeft') {
|
|
152
|
+
event.preventDefault();
|
|
153
|
+
prev();
|
|
154
|
+
} else if (event.key === 'ArrowRight') {
|
|
155
|
+
event.preventDefault();
|
|
156
|
+
next();
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
[count, next, prev],
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
return (
|
|
163
|
+
<div
|
|
164
|
+
// TODO(burdon): Move to ui-theme.
|
|
165
|
+
className={mx(
|
|
166
|
+
'relative w-full aspect-video overflow-hidden',
|
|
167
|
+
'focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500',
|
|
168
|
+
classNames,
|
|
169
|
+
)}
|
|
170
|
+
tabIndex={0}
|
|
171
|
+
role='region'
|
|
172
|
+
aria-roledescription='carousel'
|
|
173
|
+
aria-label={t('carousel-viewport.label')}
|
|
174
|
+
onKeyDown={handleKeyDown}
|
|
175
|
+
>
|
|
176
|
+
{children}
|
|
177
|
+
</div>
|
|
178
|
+
);
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
CarouselViewport.displayName = 'Carousel.Viewport';
|
|
182
|
+
|
|
183
|
+
//
|
|
184
|
+
// Slide
|
|
185
|
+
//
|
|
186
|
+
|
|
187
|
+
export type CarouselSlideProps = ThemedClassName<{
|
|
188
|
+
index: number;
|
|
189
|
+
/** Media source URL — rendered via the embedded {@link MediaPlayer}. */
|
|
190
|
+
src: string;
|
|
191
|
+
/** Override media auto-detection (`'video' | 'audio'`). */
|
|
192
|
+
kind?: MediaKind;
|
|
193
|
+
/** Accessible label / `<img alt>` fallback. */
|
|
194
|
+
alt?: string;
|
|
195
|
+
/** Class names forwarded to the inner `<img>` when MediaPlayer resolves to an image. */
|
|
196
|
+
imgClassNames?: string;
|
|
197
|
+
/** Class names forwarded to the inner `<video>` / `<audio>` / `<iframe>`. */
|
|
198
|
+
mediaClassNames?: string;
|
|
199
|
+
controls?: boolean;
|
|
200
|
+
autoPlay?: boolean;
|
|
201
|
+
loop?: boolean;
|
|
202
|
+
muted?: boolean;
|
|
203
|
+
crossOrigin?: 'anonymous' | 'use-credentials' | '';
|
|
204
|
+
}>;
|
|
205
|
+
|
|
206
|
+
const CarouselSlide = ({
|
|
207
|
+
index,
|
|
208
|
+
classNames,
|
|
209
|
+
src,
|
|
210
|
+
kind,
|
|
211
|
+
alt,
|
|
212
|
+
imgClassNames,
|
|
213
|
+
mediaClassNames,
|
|
214
|
+
controls,
|
|
215
|
+
autoPlay,
|
|
216
|
+
loop,
|
|
217
|
+
muted,
|
|
218
|
+
crossOrigin,
|
|
219
|
+
}: CarouselSlideProps) => {
|
|
220
|
+
const { index: active } = useCarousel();
|
|
221
|
+
if (active !== index) {
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return (
|
|
226
|
+
<div className={mx('absolute inset-0 w-full h-full bg-baseSurface', classNames)}>
|
|
227
|
+
<MediaPlayer
|
|
228
|
+
src={src}
|
|
229
|
+
kind={kind}
|
|
230
|
+
alt={alt}
|
|
231
|
+
classNames='w-full h-full'
|
|
232
|
+
imgClassNames={mx('object-cover', imgClassNames)}
|
|
233
|
+
mediaClassNames={mediaClassNames}
|
|
234
|
+
controls={controls}
|
|
235
|
+
autoPlay={autoPlay}
|
|
236
|
+
loop={loop}
|
|
237
|
+
muted={muted}
|
|
238
|
+
crossOrigin={crossOrigin}
|
|
239
|
+
/>
|
|
240
|
+
</div>
|
|
241
|
+
);
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
CarouselSlide.displayName = 'Carousel.Slide';
|
|
245
|
+
|
|
246
|
+
//
|
|
247
|
+
// Previous / Next
|
|
248
|
+
//
|
|
249
|
+
|
|
250
|
+
export type CarouselButtonProps = ThemedClassName<{}>;
|
|
251
|
+
|
|
252
|
+
const CarouselPrevious = ({ classNames }: CarouselButtonProps) => {
|
|
253
|
+
const { t } = useTranslation(translationKey);
|
|
254
|
+
const { count, prev } = useCarousel();
|
|
255
|
+
if (count <= 1) {
|
|
256
|
+
return <div />;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return (
|
|
260
|
+
<IconButton
|
|
261
|
+
classNames={mx('self-center', classNames)}
|
|
262
|
+
square
|
|
263
|
+
variant='ghost'
|
|
264
|
+
icon='ph--caret-left--regular'
|
|
265
|
+
iconOnly
|
|
266
|
+
label={t('carousel-prev.label')}
|
|
267
|
+
onClick={prev}
|
|
268
|
+
/>
|
|
269
|
+
);
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
CarouselPrevious.displayName = 'Carousel.Previous';
|
|
273
|
+
|
|
274
|
+
const CarouselNext = ({ classNames }: CarouselButtonProps) => {
|
|
275
|
+
const { t } = useTranslation(translationKey);
|
|
276
|
+
const { count, next } = useCarousel();
|
|
277
|
+
if (count <= 1) {
|
|
278
|
+
return <div />;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return (
|
|
282
|
+
<IconButton
|
|
283
|
+
classNames={mx('self-center', classNames)}
|
|
284
|
+
square
|
|
285
|
+
variant='ghost'
|
|
286
|
+
icon='ph--caret-right--regular'
|
|
287
|
+
iconOnly
|
|
288
|
+
label={t('carousel-next.label')}
|
|
289
|
+
onClick={next}
|
|
290
|
+
/>
|
|
291
|
+
);
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
CarouselNext.displayName = 'Carousel.Next';
|
|
295
|
+
|
|
296
|
+
//
|
|
297
|
+
// Indicators
|
|
298
|
+
//
|
|
299
|
+
|
|
300
|
+
export type CarouselIndicatorsProps = ThemedClassName<{}>;
|
|
301
|
+
|
|
302
|
+
/** Tab-strip of slide indicators. Sits in the centre column so it matches the viewport's width. */
|
|
303
|
+
const CarouselIndicators = ({ classNames }: CarouselIndicatorsProps) => {
|
|
304
|
+
const { t } = useTranslation(translationKey);
|
|
305
|
+
const { count, index, setIndex } = useCarousel();
|
|
306
|
+
const arrowNavigationAttrs = useArrowNavigationGroup({ axis: 'horizontal', memorizeCurrent: true });
|
|
307
|
+
if (count <= 1) {
|
|
308
|
+
return null;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
return (
|
|
312
|
+
<div className='col-start-2 overflow-hidden'>
|
|
313
|
+
<div
|
|
314
|
+
{...arrowNavigationAttrs}
|
|
315
|
+
className={mx('flex items-center justify-center', classNames)}
|
|
316
|
+
role='tablist'
|
|
317
|
+
aria-label={t('carousel-indicators.label')}
|
|
318
|
+
>
|
|
319
|
+
{Array.from({ length: count }).map((_, i) => (
|
|
320
|
+
<IconButton
|
|
321
|
+
key={i}
|
|
322
|
+
role='tab'
|
|
323
|
+
aria-selected={i === index}
|
|
324
|
+
classNames={i === index ? 'text-primary-500' : 'text-description'}
|
|
325
|
+
icon={i === index ? 'ph--circle--fill' : 'ph--circle--regular'}
|
|
326
|
+
iconOnly
|
|
327
|
+
label={t('carousel-go-to.label', { index: i + 1 })}
|
|
328
|
+
onClick={() => setIndex(i)}
|
|
329
|
+
onFocus={() => setIndex(i)}
|
|
330
|
+
size={3}
|
|
331
|
+
variant='ghost'
|
|
332
|
+
/>
|
|
333
|
+
))}
|
|
334
|
+
</div>
|
|
335
|
+
</div>
|
|
336
|
+
);
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
CarouselIndicators.displayName = 'Carousel.Indicators';
|
|
340
|
+
|
|
341
|
+
//
|
|
342
|
+
// Caption
|
|
343
|
+
//
|
|
344
|
+
|
|
345
|
+
export type CarouselCaptionProps = ThemedClassName<{
|
|
346
|
+
/** Render prop receiving the active slide index. */
|
|
347
|
+
children: (index: number) => ReactNode;
|
|
348
|
+
}>;
|
|
349
|
+
|
|
350
|
+
/** Caption sized to the viewport's column. */
|
|
351
|
+
const CarouselCaption = ({ children, classNames }: CarouselCaptionProps) => {
|
|
352
|
+
const { index } = useCarousel();
|
|
353
|
+
const content = children(index);
|
|
354
|
+
if (content == null || content === false || content === '') {
|
|
355
|
+
return null;
|
|
356
|
+
}
|
|
357
|
+
return (
|
|
358
|
+
// TODO(burdon): Move to ui-theme.
|
|
359
|
+
<div className='col-start-2'>
|
|
360
|
+
<p className={mx('text-center text-description', classNames)}>{content}</p>
|
|
361
|
+
</div>
|
|
362
|
+
);
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
CarouselCaption.displayName = 'Carousel.Caption';
|
|
366
|
+
|
|
367
|
+
//
|
|
368
|
+
// Carousel
|
|
369
|
+
//
|
|
370
|
+
|
|
371
|
+
export const Carousel = {
|
|
372
|
+
Root: CarouselRoot,
|
|
373
|
+
Viewport: CarouselViewport,
|
|
374
|
+
Slide: CarouselSlide,
|
|
375
|
+
Previous: CarouselPrevious,
|
|
376
|
+
Next: CarouselNext,
|
|
377
|
+
Indicators: CarouselIndicators,
|
|
378
|
+
Caption: CarouselCaption,
|
|
379
|
+
};
|
|
@@ -10,7 +10,6 @@ import { Button, type ButtonProps, IconButton } from '../Button';
|
|
|
10
10
|
import { Icon, type IconProps } from '../Icon';
|
|
11
11
|
import { useTranslation } from '../ThemeProvider';
|
|
12
12
|
import { type TooltipScopedProps, useTooltipContext } from '../Tooltip';
|
|
13
|
-
|
|
14
13
|
import { useClipboard } from './ClipboardProvider';
|
|
15
14
|
|
|
16
15
|
export type CopyButtonProps = ButtonProps &
|
|
@@ -31,12 +30,12 @@ export const CopyButton = ({ classNames, value, size = 5, ...props }: CopyButton
|
|
|
31
30
|
onClick={() => setTextValue(value)}
|
|
32
31
|
data-testid='copy-invitation'
|
|
33
32
|
>
|
|
34
|
-
<div
|
|
35
|
-
<span className='px-1'>{t('copy
|
|
33
|
+
<div className={mx('flex gap-1 items-center', isCopied && inactiveLabelStyles)}>
|
|
34
|
+
<span className='px-1'>{t('copy.label')}</span>
|
|
36
35
|
<Icon icon='ph--copy--regular' size={size} />
|
|
37
36
|
</div>
|
|
38
|
-
<div
|
|
39
|
-
<span className='px-1'>{t('copy
|
|
37
|
+
<div className={mx('flex gap-1 items-center', !isCopied && inactiveLabelStyles)}>
|
|
38
|
+
<span className='px-1'>{t('copy-success.label')}</span>
|
|
40
39
|
<Icon icon='ph--check--regular' size={size} />
|
|
41
40
|
</div>
|
|
42
41
|
</Button>
|
|
@@ -58,7 +57,7 @@ export const CopyButtonIconOnly = ({
|
|
|
58
57
|
const { t } = useTranslation(osTranslations);
|
|
59
58
|
const { textValue, setTextValue } = useClipboard();
|
|
60
59
|
const isCopied = textValue === value;
|
|
61
|
-
const label = isCopied ? t('copy
|
|
60
|
+
const label = isCopied ? t('copy-success.label') : (props.label ?? t('copy.label'));
|
|
62
61
|
const { onOpen } = useTooltipContext('CopyButton', __scopeTooltip);
|
|
63
62
|
return (
|
|
64
63
|
<IconButton
|
|
@@ -5,14 +5,13 @@
|
|
|
5
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
6
|
import React from 'react';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { random } from '@dxos/random';
|
|
9
9
|
|
|
10
10
|
import { withTheme } from '../../testing';
|
|
11
11
|
import { Button } from '../Button';
|
|
12
|
-
|
|
13
12
|
import { AlertDialog } from './AlertDialog';
|
|
14
13
|
|
|
15
|
-
type
|
|
14
|
+
type DefaultStoryProps = Partial<{
|
|
16
15
|
title: string;
|
|
17
16
|
description: string;
|
|
18
17
|
openTrigger: string;
|
|
@@ -20,7 +19,7 @@ type StoryProps = Partial<{
|
|
|
20
19
|
actionTrigger: string;
|
|
21
20
|
}>;
|
|
22
21
|
|
|
23
|
-
const DefaultStory = ({ title, description, openTrigger, cancelTrigger, actionTrigger }:
|
|
22
|
+
const DefaultStory = ({ title, description, openTrigger, cancelTrigger, actionTrigger }: DefaultStoryProps) => {
|
|
24
23
|
return (
|
|
25
24
|
<AlertDialog.Root defaultOpen>
|
|
26
25
|
<AlertDialog.Trigger asChild>
|
|
@@ -60,8 +59,8 @@ type Story = StoryObj<typeof meta>;
|
|
|
60
59
|
|
|
61
60
|
export const Default: Story = {
|
|
62
61
|
args: {
|
|
63
|
-
title:
|
|
64
|
-
description:
|
|
62
|
+
title: random.lorem.sentence(3),
|
|
63
|
+
description: random.lorem.paragraph(1),
|
|
65
64
|
openTrigger: 'Open AlertDialog',
|
|
66
65
|
cancelTrigger: 'Cancel',
|
|
67
66
|
actionTrigger: 'Action',
|
|
@@ -4,12 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
|
|
6
6
|
import { createContext } from '@radix-ui/react-context';
|
|
7
|
-
import React, {
|
|
8
|
-
type ForwardRefExoticComponent,
|
|
9
|
-
type FunctionComponent,
|
|
10
|
-
type PropsWithChildren,
|
|
11
|
-
forwardRef,
|
|
12
|
-
} from 'react';
|
|
7
|
+
import React, { type ForwardRefExoticComponent, type FunctionComponent, forwardRef } from 'react';
|
|
13
8
|
|
|
14
9
|
import { type DialogSize } from '@dxos/ui-theme';
|
|
15
10
|
|
|
@@ -17,6 +12,13 @@ import { useThemeContext } from '../../hooks';
|
|
|
17
12
|
import { Column } from '../../primitives';
|
|
18
13
|
import { type ThemedClassName } from '../../util';
|
|
19
14
|
import { ElevationProvider } from '../ElevationProvider';
|
|
15
|
+
import {
|
|
16
|
+
Dialog,
|
|
17
|
+
type DialogHeaderProps,
|
|
18
|
+
type DialogBodyProps,
|
|
19
|
+
type DialogActionBarProps,
|
|
20
|
+
type DialogCloseIconButtonProps,
|
|
21
|
+
} from './Dialog';
|
|
20
22
|
|
|
21
23
|
//
|
|
22
24
|
// Root
|
|
@@ -63,68 +65,26 @@ type AlertDialogActionProps = AlertDialogPrimitive.AlertDialogActionProps;
|
|
|
63
65
|
const AlertDialogAction: FunctionComponent<AlertDialogActionProps> = AlertDialogPrimitive.Action;
|
|
64
66
|
|
|
65
67
|
//
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
|
|
69
|
-
type AlertDialogTitleProps = ThemedClassName<AlertDialogPrimitive.AlertDialogTitleProps> & { srOnly?: boolean };
|
|
70
|
-
|
|
71
|
-
const AlertDialogTitle: ForwardRefExoticComponent<AlertDialogTitleProps> = forwardRef<
|
|
72
|
-
HTMLHeadingElement,
|
|
73
|
-
AlertDialogTitleProps
|
|
74
|
-
>(({ classNames, srOnly, ...props }, forwardedRef) => {
|
|
75
|
-
const { tx } = useThemeContext();
|
|
76
|
-
return (
|
|
77
|
-
<AlertDialogPrimitive.Title {...props} className={tx('dialog.title', { srOnly }, classNames)} ref={forwardedRef} />
|
|
78
|
-
);
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
//
|
|
82
|
-
// Description
|
|
68
|
+
// Context
|
|
83
69
|
//
|
|
84
70
|
|
|
85
|
-
type AlertDialogDescriptionProps = ThemedClassName<AlertDialogPrimitive.AlertDialogDescriptionProps> & {
|
|
86
|
-
srOnly?: boolean;
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
const AlertDialogDescription: ForwardRefExoticComponent<AlertDialogTitleProps> = forwardRef<
|
|
90
|
-
HTMLParagraphElement,
|
|
91
|
-
AlertDialogDescriptionProps
|
|
92
|
-
>(({ classNames, srOnly, ...props }, forwardedRef) => {
|
|
93
|
-
const { tx } = useThemeContext();
|
|
94
|
-
return (
|
|
95
|
-
<AlertDialogPrimitive.Description
|
|
96
|
-
{...props}
|
|
97
|
-
className={tx('dialog.description', { srOnly }, classNames)}
|
|
98
|
-
ref={forwardedRef}
|
|
99
|
-
/>
|
|
100
|
-
);
|
|
101
|
-
});
|
|
102
|
-
|
|
103
71
|
type OverlayLayoutContextValue = { inOverlayLayout?: boolean };
|
|
104
72
|
|
|
105
|
-
//
|
|
106
|
-
// Context
|
|
107
|
-
//
|
|
108
|
-
|
|
109
73
|
const ALERT_DIALOG_OVERLAY_NAME = 'AlertDialogOverlay';
|
|
110
74
|
const ALERT_DIALOG_CONTENT_NAME = 'AlertDialogContent';
|
|
111
|
-
const ALERT_DIALOG_BODY_NAME = 'AlertDialogBody';
|
|
112
|
-
const ALERT_DIALOG_ACTIONBAR_NAME = 'AlertDialogActionBar';
|
|
113
75
|
|
|
114
76
|
const [OverlayLayoutProvider, useOverlayLayoutContext] = createContext<OverlayLayoutContextValue>(
|
|
115
77
|
ALERT_DIALOG_OVERLAY_NAME,
|
|
116
|
-
{
|
|
117
|
-
inOverlayLayout: false,
|
|
118
|
-
},
|
|
78
|
+
{ inOverlayLayout: false },
|
|
119
79
|
);
|
|
120
80
|
|
|
121
81
|
//
|
|
122
82
|
// Overlay
|
|
123
83
|
//
|
|
124
84
|
|
|
125
|
-
type AlertDialogOverlayProps = ThemedClassName<
|
|
126
|
-
blockAlign?: 'center' | 'start' | 'end'
|
|
127
|
-
|
|
85
|
+
type AlertDialogOverlayProps = ThemedClassName<
|
|
86
|
+
AlertDialogPrimitive.AlertDialogOverlayProps & { blockAlign?: 'center' | 'start' | 'end' }
|
|
87
|
+
>;
|
|
128
88
|
|
|
129
89
|
const AlertDialogOverlay: ForwardRefExoticComponent<AlertDialogOverlayProps> = forwardRef<
|
|
130
90
|
HTMLDivElement,
|
|
@@ -135,15 +95,7 @@ const AlertDialogOverlay: ForwardRefExoticComponent<AlertDialogOverlayProps> = f
|
|
|
135
95
|
<AlertDialogPrimitive.Overlay
|
|
136
96
|
{...props}
|
|
137
97
|
data-block-align={blockAlign}
|
|
138
|
-
className={tx(
|
|
139
|
-
'dialog.overlay',
|
|
140
|
-
{},
|
|
141
|
-
classNames,
|
|
142
|
-
// TODO(burdon): Move to dialog.ts.
|
|
143
|
-
'data-[h-align=start]:justify-center',
|
|
144
|
-
'data-[h-align=start]:items-start',
|
|
145
|
-
'data-[h-align=center]:place-content-center',
|
|
146
|
-
)}
|
|
98
|
+
className={tx('dialog.overlay', {}, classNames)}
|
|
147
99
|
ref={forwardedRef}
|
|
148
100
|
>
|
|
149
101
|
<OverlayLayoutProvider inOverlayLayout>{children}</OverlayLayoutProvider>
|
|
@@ -169,9 +121,14 @@ const AlertDialogContent: ForwardRefExoticComponent<AlertDialogContentProps> = f
|
|
|
169
121
|
<AlertDialogPrimitive.Content
|
|
170
122
|
{...props}
|
|
171
123
|
className={tx('dialog.content', { inOverlayLayout, size }, classNames)}
|
|
124
|
+
// NOTE: Radix warning unless set to undefined.
|
|
125
|
+
// https://www.radix-ui.com/primitives/docs/components/dialog#description
|
|
126
|
+
aria-describedby={undefined}
|
|
172
127
|
ref={forwardedRef}
|
|
173
128
|
>
|
|
174
|
-
<Column.Root>
|
|
129
|
+
<Column.Root classNames='dx-expander' gutter='sm'>
|
|
130
|
+
{children}
|
|
131
|
+
</Column.Root>
|
|
175
132
|
</AlertDialogPrimitive.Content>
|
|
176
133
|
);
|
|
177
134
|
});
|
|
@@ -179,49 +136,43 @@ const AlertDialogContent: ForwardRefExoticComponent<AlertDialogContentProps> = f
|
|
|
179
136
|
AlertDialogContent.displayName = ALERT_DIALOG_CONTENT_NAME;
|
|
180
137
|
|
|
181
138
|
//
|
|
182
|
-
//
|
|
139
|
+
// Title
|
|
183
140
|
//
|
|
184
141
|
|
|
185
|
-
type
|
|
142
|
+
type AlertDialogTitleProps = ThemedClassName<AlertDialogPrimitive.AlertDialogTitleProps> & { srOnly?: boolean };
|
|
186
143
|
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
>(({
|
|
144
|
+
const AlertDialogTitle: ForwardRefExoticComponent<AlertDialogTitleProps> = forwardRef<
|
|
145
|
+
HTMLHeadingElement,
|
|
146
|
+
AlertDialogTitleProps
|
|
147
|
+
>(({ classNames, srOnly, ...props }, forwardedRef) => {
|
|
191
148
|
const { tx } = useThemeContext();
|
|
192
149
|
return (
|
|
193
|
-
<
|
|
194
|
-
<div role='none' {...props} className={tx('dialog.body')} ref={forwardedRef}>
|
|
195
|
-
{children}
|
|
196
|
-
</div>
|
|
197
|
-
</Column.Segment>
|
|
150
|
+
<AlertDialogPrimitive.Title {...props} className={tx('dialog.title', { srOnly }, classNames)} ref={forwardedRef} />
|
|
198
151
|
);
|
|
199
152
|
});
|
|
200
153
|
|
|
201
|
-
AlertDialogBody.displayName = ALERT_DIALOG_BODY_NAME;
|
|
202
|
-
|
|
203
154
|
//
|
|
204
|
-
//
|
|
155
|
+
// Description
|
|
205
156
|
//
|
|
206
157
|
|
|
207
|
-
type
|
|
158
|
+
type AlertDialogDescriptionProps = ThemedClassName<AlertDialogPrimitive.AlertDialogDescriptionProps> & {
|
|
159
|
+
srOnly?: boolean;
|
|
160
|
+
};
|
|
208
161
|
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
>(({
|
|
162
|
+
const AlertDialogDescription: ForwardRefExoticComponent<AlertDialogDescriptionProps> = forwardRef<
|
|
163
|
+
HTMLParagraphElement,
|
|
164
|
+
AlertDialogDescriptionProps
|
|
165
|
+
>(({ classNames, srOnly, ...props }, forwardedRef) => {
|
|
213
166
|
const { tx } = useThemeContext();
|
|
214
167
|
return (
|
|
215
|
-
<
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
168
|
+
<AlertDialogPrimitive.Description
|
|
169
|
+
{...props}
|
|
170
|
+
className={tx('dialog.description', { srOnly }, classNames)}
|
|
171
|
+
ref={forwardedRef}
|
|
172
|
+
/>
|
|
220
173
|
);
|
|
221
174
|
});
|
|
222
175
|
|
|
223
|
-
AlertDialogActionBar.displayName = ALERT_DIALOG_ACTIONBAR_NAME;
|
|
224
|
-
|
|
225
176
|
//
|
|
226
177
|
// AlertDialog
|
|
227
178
|
//
|
|
@@ -232,10 +183,14 @@ export const AlertDialog = {
|
|
|
232
183
|
Portal: AlertDialogPortal,
|
|
233
184
|
Overlay: AlertDialogOverlay,
|
|
234
185
|
Content: AlertDialogContent,
|
|
235
|
-
|
|
186
|
+
// Shared with Dialog.
|
|
187
|
+
Header: Dialog.Header,
|
|
188
|
+
Body: Dialog.Body,
|
|
236
189
|
Title: AlertDialogTitle,
|
|
237
190
|
Description: AlertDialogDescription,
|
|
238
|
-
ActionBar:
|
|
191
|
+
ActionBar: Dialog.ActionBar,
|
|
192
|
+
CloseIconButton: Dialog.CloseIconButton,
|
|
193
|
+
// AlertDialog-specific dismissal.
|
|
239
194
|
Cancel: AlertDialogCancel,
|
|
240
195
|
Action: AlertDialogAction,
|
|
241
196
|
};
|
|
@@ -246,10 +201,13 @@ export type {
|
|
|
246
201
|
AlertDialogPortalProps,
|
|
247
202
|
AlertDialogOverlayProps,
|
|
248
203
|
AlertDialogContentProps,
|
|
249
|
-
AlertDialogBodyProps,
|
|
250
204
|
AlertDialogTitleProps,
|
|
251
205
|
AlertDialogDescriptionProps,
|
|
252
|
-
AlertDialogActionBarProps,
|
|
253
206
|
AlertDialogCancelProps,
|
|
254
207
|
AlertDialogActionProps,
|
|
208
|
+
// Re-export shared types.
|
|
209
|
+
DialogHeaderProps as AlertDialogHeaderProps,
|
|
210
|
+
DialogBodyProps as AlertDialogBodyProps,
|
|
211
|
+
DialogActionBarProps as AlertDialogActionBarProps,
|
|
212
|
+
DialogCloseIconButtonProps as AlertDialogCloseIconButtonProps,
|
|
255
213
|
};
|