@dxos/react-ui 0.9.0 → 0.9.1-staging.ee54ba693a
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-5SPBSIWS.mjs → chunk-CMHHVHX3.mjs} +14 -1
- package/dist/lib/browser/chunk-CMHHVHX3.mjs.map +7 -0
- package/dist/lib/browser/{chunk-7JFD5ZHZ.mjs → chunk-GTHV4WYK.mjs} +141 -254
- package/dist/lib/browser/chunk-GTHV4WYK.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +1553 -1274
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +5 -5
- package/dist/lib/browser/testing/index.mjs.map +2 -2
- package/dist/lib/browser/translations.mjs +1 -1
- package/dist/lib/node-esm/{chunk-TTEL2FP2.mjs → chunk-3VSKWNCQ.mjs} +141 -254
- package/dist/lib/node-esm/chunk-3VSKWNCQ.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-FPVTVXND.mjs → chunk-P4KFQGJI.mjs} +14 -1
- package/dist/lib/node-esm/chunk-P4KFQGJI.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +1553 -1274
- 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 +5 -5
- package/dist/lib/node-esm/testing/index.mjs.map +2 -2
- package/dist/lib/node-esm/translations.mjs +1 -1
- 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/Breadcrumb/Breadcrumb.d.ts +3 -3
- package/dist/types/src/components/Breadcrumb/Breadcrumb.d.ts.map +1 -1
- package/dist/types/src/components/Button/Button.d.ts +4 -2
- package/dist/types/src/components/Button/Button.d.ts.map +1 -1
- package/dist/types/src/components/Button/IconButton.d.ts +0 -1
- package/dist/types/src/components/Button/IconButton.d.ts.map +1 -1
- package/dist/types/src/components/Button/IconButton.stories.d.ts +37 -0
- package/dist/types/src/components/Button/IconButton.stories.d.ts.map +1 -1
- package/dist/types/src/components/Button/MicButton.d.ts +24 -0
- package/dist/types/src/components/Button/MicButton.d.ts.map +1 -0
- package/dist/types/src/components/Button/MicButton.stories.d.ts +57 -0
- package/dist/types/src/components/Button/MicButton.stories.d.ts.map +1 -0
- package/dist/types/src/components/Button/SystemIconButton.d.ts +33 -0
- package/dist/types/src/components/Button/SystemIconButton.d.ts.map +1 -0
- package/dist/types/src/components/Button/SystemIconButton.stories.d.ts +51 -0
- package/dist/types/src/components/Button/SystemIconButton.stories.d.ts.map +1 -0
- package/dist/types/src/components/Button/ToggleGroup.d.ts +2 -2
- package/dist/types/src/components/Button/ToggleGroup.d.ts.map +1 -1
- package/dist/types/src/components/Button/ToggleIconButton.d.ts +15 -0
- package/dist/types/src/components/Button/ToggleIconButton.d.ts.map +1 -0
- package/dist/types/src/components/Button/index.d.ts +3 -0
- package/dist/types/src/components/Button/index.d.ts.map +1 -1
- package/dist/types/src/components/Calendar/Calendar.d.ts.map +1 -1
- package/dist/types/src/components/Calendar/Calendar.theme.d.ts.map +1 -1
- package/dist/types/src/components/Card/Card.d.ts +32 -26
- package/dist/types/src/components/Card/Card.d.ts.map +1 -1
- package/dist/types/src/components/Card/Card.stories.d.ts +3 -3
- package/dist/types/src/components/Card/Card.stories.d.ts.map +1 -1
- package/dist/types/src/components/Card/Card.theme.d.ts.map +1 -1
- package/dist/types/src/components/Carousel/Carousel.d.ts +29 -6
- package/dist/types/src/components/Carousel/Carousel.d.ts.map +1 -1
- package/dist/types/src/components/Carousel/Carousel.stories.d.ts +48 -2
- package/dist/types/src/components/Carousel/Carousel.stories.d.ts.map +1 -1
- package/dist/types/src/components/Clipboard/index.d.ts +1 -0
- package/dist/types/src/components/Clipboard/index.d.ts.map +1 -1
- package/dist/types/src/components/Column/Column.d.ts +20 -2
- package/dist/types/src/components/Column/Column.d.ts.map +1 -1
- package/dist/types/src/components/Column/Column.theme.d.ts +8 -0
- package/dist/types/src/components/Column/Column.theme.d.ts.map +1 -1
- package/dist/types/src/components/Dialog/AlertDialog.d.ts +2 -2
- package/dist/types/src/components/Dialog/AlertDialog.d.ts.map +1 -1
- package/dist/types/src/components/Dialog/Dialog.d.ts +1 -1
- package/dist/types/src/components/Dialog/Dialog.d.ts.map +1 -1
- package/dist/types/src/components/Dialog/Dialog.stories.d.ts +2 -2
- package/dist/types/src/components/Dialog/Dialog.stories.d.ts.map +1 -1
- package/dist/types/src/components/Icon/Icon.stories.d.ts +5 -0
- package/dist/types/src/components/Icon/Icon.stories.d.ts.map +1 -1
- package/dist/types/src/components/Input/Input.d.ts +4 -1
- 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/Input/Input.theme.d.ts +10 -10
- package/dist/types/src/components/Input/Input.theme.d.ts.map +1 -1
- package/dist/types/src/components/Input/SegmentedInput.d.ts +8 -8
- package/dist/types/src/components/Input/SegmentedInput.d.ts.map +1 -1
- package/dist/types/src/components/Input/index.d.ts +0 -1
- package/dist/types/src/components/Input/index.d.ts.map +1 -1
- package/dist/types/src/components/Main/Main.d.ts +3 -3
- package/dist/types/src/components/Main/Main.d.ts.map +1 -1
- package/dist/types/src/components/Menu/ContextMenu.d.ts +1 -1
- package/dist/types/src/components/Menu/ContextMenu.d.ts.map +1 -1
- package/dist/types/src/components/Menu/DropdownMenu.d.ts +2 -2
- package/dist/types/src/components/Menu/DropdownMenu.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/Message/Message.theme.d.ts.map +1 -1
- package/dist/types/src/components/Panel/Panel.d.ts +1 -1
- package/dist/types/src/components/Panel/Panel.d.ts.map +1 -1
- package/dist/types/src/components/Panel/Panel.theme.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/ScrollArea/ScrollArea.d.ts +2 -0
- package/dist/types/src/components/ScrollArea/ScrollArea.d.ts.map +1 -1
- package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts +1 -0
- package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts.map +1 -1
- package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts +1 -1
- package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts.map +1 -1
- package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts +2 -2
- package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts.map +1 -1
- 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 +2 -2
- package/dist/types/src/components/Select/Select.stories.d.ts.map +1 -1
- package/dist/types/src/components/Separator/Separator.d.ts.map +1 -1
- package/dist/types/src/components/Splitter/Splitter.d.ts +30 -16
- package/dist/types/src/components/Splitter/Splitter.d.ts.map +1 -1
- package/dist/types/src/components/Splitter/Splitter.stories.d.ts +6 -1
- package/dist/types/src/components/Splitter/Splitter.stories.d.ts.map +1 -1
- package/dist/types/src/components/Splitter/Splitter.theme.d.ts +3 -1
- package/dist/types/src/components/Splitter/Splitter.theme.d.ts.map +1 -1
- package/dist/types/src/components/Tag/Tag.d.ts +1 -1
- package/dist/types/src/components/Tag/Tag.d.ts.map +1 -1
- package/dist/types/src/components/Tag/Tag.theme.d.ts +1 -1
- package/dist/types/src/components/Tag/Tag.theme.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.theme.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.d.ts +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/types/src/components/Tooltip/TextTooltip.d.ts +19 -0
- package/dist/types/src/components/Tooltip/TextTooltip.d.ts.map +1 -0
- package/dist/types/src/components/Tooltip/Tooltip.d.ts +3 -3
- 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/Tooltip/index.d.ts +1 -0
- package/dist/types/src/components/Tooltip/index.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +0 -1
- package/dist/types/src/components/index.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/primitives/ThemeProvider/TranslationsProvider.d.ts +1 -8
- package/dist/types/src/primitives/ThemeProvider/TranslationsProvider.d.ts.map +1 -1
- package/dist/types/src/testing/Loading.d.ts.map +1 -1
- package/dist/types/src/theme/defaultTheme.d.ts.map +1 -1
- package/dist/types/src/theme/index.d.ts +0 -2
- package/dist/types/src/theme/index.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +13 -0
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/util/slots.d.ts +1 -1
- package/dist/types/src/util/slots.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +22 -21
- package/src/components/Avatars/Avatar.stories.tsx +2 -2
- package/src/components/Avatars/Avatar.theme.ts +1 -1
- package/src/components/Avatars/Avatar.tsx +3 -3
- package/src/components/Breadcrumb/Breadcrumb.tsx +6 -6
- package/src/components/Button/Button.tsx +25 -4
- package/src/components/Button/IconButton.stories.tsx +81 -1
- package/src/components/Button/IconButton.tsx +2 -4
- package/src/components/Button/MicButton.stories.tsx +60 -0
- package/src/components/Button/MicButton.tsx +117 -0
- package/src/components/Button/SystemIconButton.stories.tsx +91 -0
- package/src/components/Button/SystemIconButton.tsx +264 -0
- package/src/components/Button/ToggleGroup.tsx +2 -2
- package/src/components/Button/ToggleIconButton.tsx +32 -0
- package/src/components/Button/index.ts +3 -0
- package/src/components/Calendar/Calendar.theme.ts +2 -0
- package/src/components/Calendar/Calendar.tsx +3 -3
- package/src/components/Card/Card.stories.tsx +71 -29
- package/src/components/Card/Card.theme.ts +27 -9
- package/src/components/Card/Card.tsx +176 -99
- package/src/components/Carousel/Carousel.stories.tsx +42 -18
- package/src/components/Carousel/Carousel.tsx +169 -33
- package/src/components/Column/Column.theme.ts +32 -4
- package/src/components/Column/Column.tsx +39 -7
- package/src/components/Dialog/AlertDialog.stories.tsx +2 -2
- package/src/components/Dialog/AlertDialog.tsx +13 -13
- package/src/components/Dialog/Dialog.stories.tsx +3 -4
- package/src/components/Dialog/Dialog.theme.ts +1 -1
- package/src/components/Dialog/Dialog.tsx +12 -12
- package/src/components/Icon/Icon.stories.tsx +23 -0
- package/src/components/Icon/Icon.theme.ts +1 -1
- package/src/components/Input/Input.stories.tsx +13 -5
- package/src/components/Input/Input.theme.ts +17 -39
- package/src/components/Input/Input.tsx +30 -13
- package/src/components/Input/SegmentedInput.tsx +50 -41
- package/src/components/Input/index.ts +0 -1
- package/src/components/Main/Main.tsx +3 -3
- package/src/components/MediaPlayer/MediaPlayer.tsx +4 -4
- package/src/components/Menu/ContextMenu.tsx +8 -8
- package/src/components/Menu/DropdownMenu.tsx +12 -13
- package/src/components/Message/Message.stories.tsx +2 -2
- package/src/components/Message/Message.theme.ts +1 -11
- package/src/components/Message/Message.tsx +6 -6
- package/src/components/Panel/Panel.theme.ts +2 -1
- package/src/components/Panel/Panel.tsx +1 -1
- package/src/components/Popover/Popover.theme.ts +1 -1
- package/src/components/Popover/Popover.tsx +9 -9
- package/src/components/ScrollArea/ScrollArea.tsx +7 -4
- package/src/components/ScrollContainer/ScrollContainer.stories.tsx +2 -2
- package/src/components/ScrollContainer/ScrollContainer.tsx +2 -2
- package/src/components/Select/Select.stories.tsx +2 -2
- package/src/components/Select/Select.theme.ts +1 -1
- package/src/components/Select/Select.tsx +14 -14
- package/src/components/Separator/Separator.tsx +1 -0
- package/src/components/Splitter/Splitter.stories.tsx +84 -20
- package/src/components/Splitter/Splitter.theme.ts +20 -3
- package/src/components/Splitter/Splitter.tsx +320 -47
- package/src/components/Tag/Tag.stories.tsx +1 -1
- package/src/components/Tag/Tag.theme.ts +1 -1
- package/src/components/Tag/Tag.tsx +3 -5
- package/src/components/Toast/Toast.theme.ts +3 -8
- package/src/components/Toast/Toast.tsx +16 -15
- package/src/components/Toolbar/Toolbar.tsx +10 -10
- package/src/components/Tooltip/TextTooltip.tsx +54 -0
- package/src/components/Tooltip/Tooltip.stories.tsx +2 -2
- package/src/components/Tooltip/Tooltip.tsx +3 -3
- package/src/components/Tooltip/index.ts +1 -0
- package/src/components/index.ts +0 -1
- package/src/exemplars/tabster.stories.tsx +1 -1
- package/src/index.ts +1 -1
- package/src/primitives/ThemeProvider/TranslationsProvider.tsx +10 -30
- package/src/testing/Loading.tsx +2 -1
- package/src/testing/decorators/withLayout.tsx +2 -2
- package/src/theme/defaultTheme.ts +0 -4
- package/src/theme/index.ts +0 -2
- package/src/translations.ts +18 -0
- package/src/util/slots.ts +5 -5
- package/dist/lib/browser/chunk-5SPBSIWS.mjs.map +0 -7
- package/dist/lib/browser/chunk-7JFD5ZHZ.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-FPVTVXND.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-TTEL2FP2.mjs.map +0 -7
- package/dist/types/src/components/Input/constants.d.ts +0 -2
- package/dist/types/src/components/Input/constants.d.ts.map +0 -1
- package/dist/types/src/components/List/List.d.ts +0 -29
- package/dist/types/src/components/List/List.d.ts.map +0 -1
- package/dist/types/src/components/List/List.stories.d.ts +0 -16
- package/dist/types/src/components/List/List.stories.d.ts.map +0 -1
- package/dist/types/src/components/List/List.theme.d.ts +0 -7
- package/dist/types/src/components/List/List.theme.d.ts.map +0 -1
- package/dist/types/src/components/List/ListDropIndicator.d.ts +0 -13
- package/dist/types/src/components/List/ListDropIndicator.d.ts.map +0 -1
- package/dist/types/src/components/List/Tree.d.ts +0 -23
- package/dist/types/src/components/List/Tree.d.ts.map +0 -1
- package/dist/types/src/components/List/Tree.stories.d.ts +0 -15
- package/dist/types/src/components/List/Tree.stories.d.ts.map +0 -1
- package/dist/types/src/components/List/TreeDropIndicator.d.ts +0 -8
- package/dist/types/src/components/List/TreeDropIndicator.d.ts.map +0 -1
- package/dist/types/src/components/List/Treegrid.d.ts +0 -33
- package/dist/types/src/components/List/Treegrid.d.ts.map +0 -1
- package/dist/types/src/components/List/Treegrid.stories.d.ts +0 -12
- package/dist/types/src/components/List/Treegrid.stories.d.ts.map +0 -1
- package/dist/types/src/components/List/Treegrid.theme.d.ts +0 -7
- package/dist/types/src/components/List/Treegrid.theme.d.ts.map +0 -1
- package/dist/types/src/components/List/index.d.ts +0 -4
- package/dist/types/src/components/List/index.d.ts.map +0 -1
- package/src/components/Input/constants.ts +0 -5
- package/src/components/List/List.stories.tsx +0 -234
- package/src/components/List/List.theme.ts +0 -47
- package/src/components/List/List.tsx +0 -171
- package/src/components/List/ListDropIndicator.tsx +0 -69
- package/src/components/List/Tree.stories.tsx +0 -87
- package/src/components/List/Tree.tsx +0 -74
- package/src/components/List/TreeDropIndicator.tsx +0 -70
- package/src/components/List/Treegrid.stories.tsx +0 -156
- package/src/components/List/Treegrid.theme.ts +0 -35
- package/src/components/List/Treegrid.tsx +0 -187
- package/src/components/List/index.ts +0 -7
|
@@ -5,25 +5,23 @@
|
|
|
5
5
|
import { Primitive } from '@radix-ui/react-primitive';
|
|
6
6
|
import { Slot } from '@radix-ui/react-slot';
|
|
7
7
|
import DOMPurify from 'dompurify';
|
|
8
|
-
import React, { CSSProperties,
|
|
8
|
+
import React, { CSSProperties, MouseEventHandler, type ReactNode, forwardRef, useId, useMemo } from 'react';
|
|
9
|
+
import { useTranslation } from 'react-i18next';
|
|
9
10
|
|
|
10
11
|
import { iconSize } from '@dxos/ui-theme';
|
|
11
|
-
import { type Density } from '@dxos/ui-types';
|
|
12
|
+
import { type Density, type SlottableProps } from '@dxos/ui-types';
|
|
13
|
+
|
|
14
|
+
import { translationKey } from '#translations';
|
|
12
15
|
|
|
13
16
|
import { useThemeContext } from '../../hooks';
|
|
14
17
|
import { composable, composableProps, slottable } from '../../util';
|
|
15
18
|
import { type ThemedClassName } from '../../util';
|
|
16
|
-
import { Button } from '../Button';
|
|
19
|
+
import { Button, IconButton } from '../Button';
|
|
17
20
|
import { Column } from '../Column';
|
|
18
|
-
import { Icon
|
|
21
|
+
import { Icon } from '../Icon';
|
|
19
22
|
import { Image, type ImageProps } from '../Image';
|
|
20
|
-
import {
|
|
21
|
-
|
|
22
|
-
type ToolbarActionIconButtonProps,
|
|
23
|
-
ToolbarDragHandleProps,
|
|
24
|
-
type ToolbarMenuProps,
|
|
25
|
-
type ToolbarRootProps,
|
|
26
|
-
} from '../Toolbar';
|
|
23
|
+
import { DropdownMenu } from '../Menu';
|
|
24
|
+
import { type ToolbarActionIconButtonProps, type ToolbarDragHandleProps, type ToolbarMenuProps } from '../Toolbar';
|
|
27
25
|
|
|
28
26
|
//
|
|
29
27
|
// Root
|
|
@@ -32,13 +30,13 @@ import {
|
|
|
32
30
|
const CARD_ROOT_NAME = 'Card.Root';
|
|
33
31
|
|
|
34
32
|
type CardRootProps = {
|
|
35
|
-
id?: string;
|
|
36
|
-
border?: boolean;
|
|
37
|
-
fullWidth?: boolean;
|
|
38
|
-
density?: Density;
|
|
39
|
-
style?: CSSProperties;
|
|
40
|
-
tabIndex?: number;
|
|
41
|
-
onClick?: MouseEventHandler<HTMLDivElement>;
|
|
33
|
+
'id'?: string;
|
|
34
|
+
'border'?: boolean;
|
|
35
|
+
'fullWidth'?: boolean;
|
|
36
|
+
'density'?: Density;
|
|
37
|
+
'style'?: CSSProperties;
|
|
38
|
+
'tabIndex'?: number;
|
|
39
|
+
'onClick'?: MouseEventHandler<HTMLDivElement>;
|
|
42
40
|
'data-selected'?: boolean;
|
|
43
41
|
'data-testid'?: string;
|
|
44
42
|
};
|
|
@@ -62,7 +60,7 @@ const CardRoot = composable<HTMLDivElement, CardRootProps>(
|
|
|
62
60
|
return (
|
|
63
61
|
<Column.Root
|
|
64
62
|
asChild
|
|
65
|
-
gutter=
|
|
63
|
+
gutter='lg'
|
|
66
64
|
classNames={tx('card.root', { border, fullWidth }, className)}
|
|
67
65
|
role={role ?? 'group'}
|
|
68
66
|
>
|
|
@@ -82,22 +80,34 @@ CardRoot.displayName = CARD_ROOT_NAME;
|
|
|
82
80
|
|
|
83
81
|
const CARD_HEADER_NAME = 'Card.Header';
|
|
84
82
|
|
|
85
|
-
type CardHeaderProps =
|
|
83
|
+
type CardHeaderProps = SlottableProps;
|
|
86
84
|
|
|
87
85
|
/**
|
|
88
|
-
* Top
|
|
89
|
-
*
|
|
90
|
-
*
|
|
86
|
+
* Top header row of a Card. Renders as a `<header>` and shares `Card.Row`'s subgrid +
|
|
87
|
+
* `data-slot` layout: `Card.Block` children land in the gutters, anonymous children
|
|
88
|
+
* (e.g. `Card.Title`) in the center. Sets `--icon-size` 5 — header icons are larger than
|
|
89
|
+
* row icons (which use 4). Not a toolbar: most headers carry 0–1 controls, so `role="toolbar"`
|
|
90
|
+
* was inaccurate; controls are reached by normal tab order.
|
|
91
91
|
*/
|
|
92
|
-
const CardHeader =
|
|
93
|
-
|
|
92
|
+
const CardHeader = slottable<HTMLDivElement, CardHeaderProps>(
|
|
93
|
+
({ children, asChild, style, ...props }, forwardedRef) => {
|
|
94
|
+
const { tx } = useThemeContext();
|
|
95
|
+
const { className, ...rest } = composableProps(props);
|
|
96
|
+
// `@radix-ui/react-primitive` has no `header` node; the intrinsic element handles asChild via Slot.
|
|
97
|
+
const Comp = asChild ? Slot : 'header';
|
|
94
98
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
99
|
+
return (
|
|
100
|
+
<Comp
|
|
101
|
+
{...rest}
|
|
102
|
+
style={{ ...iconSize(5), ...style }}
|
|
103
|
+
className={tx('card.header', {}, className)}
|
|
104
|
+
ref={forwardedRef}
|
|
105
|
+
>
|
|
106
|
+
{children}
|
|
107
|
+
</Comp>
|
|
108
|
+
);
|
|
109
|
+
},
|
|
110
|
+
);
|
|
101
111
|
|
|
102
112
|
CardHeader.displayName = CARD_HEADER_NAME;
|
|
103
113
|
|
|
@@ -109,13 +119,27 @@ const CARD_DRAG_HANDLE_NAME = 'Card.DragHandle';
|
|
|
109
119
|
|
|
110
120
|
type CardDragHandleProps = ToolbarDragHandleProps;
|
|
111
121
|
|
|
112
|
-
const CardDragHandle = forwardRef<HTMLButtonElement, CardDragHandleProps>(
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
122
|
+
const CardDragHandle = forwardRef<HTMLButtonElement, CardDragHandleProps>(
|
|
123
|
+
({ testId = 'drag-handle', label }, forwardedRef) => {
|
|
124
|
+
const { t } = useTranslation(translationKey);
|
|
125
|
+
return (
|
|
126
|
+
<CardBlock>
|
|
127
|
+
<IconButton
|
|
128
|
+
data-testid={testId}
|
|
129
|
+
tabIndex={-1}
|
|
130
|
+
noTooltip
|
|
131
|
+
iconOnly
|
|
132
|
+
icon='ph--dots-six-vertical--regular'
|
|
133
|
+
variant='ghost'
|
|
134
|
+
label={label ?? t('toolbar-drag-handle.label')}
|
|
135
|
+
classNames='dx-focus-ring-none cursor-pointer text-base-fg'
|
|
136
|
+
disabled={!forwardedRef}
|
|
137
|
+
ref={forwardedRef}
|
|
138
|
+
/>
|
|
139
|
+
</CardBlock>
|
|
140
|
+
);
|
|
141
|
+
},
|
|
142
|
+
);
|
|
119
143
|
|
|
120
144
|
CardDragHandle.displayName = CARD_DRAG_HANDLE_NAME;
|
|
121
145
|
|
|
@@ -127,13 +151,28 @@ const CARD_ACTION_ICON_BUTTON_NAME = 'Card.ActionIconButton';
|
|
|
127
151
|
|
|
128
152
|
type CardActionIconButtonProps = ToolbarActionIconButtonProps;
|
|
129
153
|
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
)
|
|
136
|
-
});
|
|
154
|
+
const CARD_ACTION_ICONS = { close: 'ph--x--regular', delete: 'ph--trash--regular' } as const;
|
|
155
|
+
|
|
156
|
+
const CARD_ACTION_LABEL_KEYS = { close: 'toolbar-close.label', delete: 'toolbar-delete.label' } as const;
|
|
157
|
+
|
|
158
|
+
const CardActionIconButton = forwardRef<HTMLButtonElement, CardActionIconButtonProps>(
|
|
159
|
+
({ action, onClick, label }, forwardedRef) => {
|
|
160
|
+
const { t } = useTranslation(translationKey);
|
|
161
|
+
return (
|
|
162
|
+
<CardBlock end>
|
|
163
|
+
<IconButton
|
|
164
|
+
iconOnly
|
|
165
|
+
icon={CARD_ACTION_ICONS[action]}
|
|
166
|
+
variant='ghost'
|
|
167
|
+
label={label ?? t(CARD_ACTION_LABEL_KEYS[action])}
|
|
168
|
+
classNames='cursor-pointer'
|
|
169
|
+
onClick={onClick}
|
|
170
|
+
ref={forwardedRef}
|
|
171
|
+
/>
|
|
172
|
+
</CardBlock>
|
|
173
|
+
);
|
|
174
|
+
},
|
|
175
|
+
);
|
|
137
176
|
|
|
138
177
|
CardActionIconButton.displayName = CARD_ACTION_ICON_BUTTON_NAME;
|
|
139
178
|
|
|
@@ -145,43 +184,67 @@ const CARD_MENU_NAME = 'Card.Menu';
|
|
|
145
184
|
|
|
146
185
|
type CardMenuProps<T extends any | void = void> = ToolbarMenuProps<T>;
|
|
147
186
|
|
|
148
|
-
function CardMenu<T extends any | void = void>({ context, items
|
|
187
|
+
function CardMenu<T extends any | void = void>({ context, items }: CardMenuProps<T>) {
|
|
188
|
+
const { t } = useTranslation(translationKey);
|
|
149
189
|
return (
|
|
150
|
-
<
|
|
151
|
-
<
|
|
152
|
-
|
|
190
|
+
<CardBlock end>
|
|
191
|
+
<DropdownMenu.Root>
|
|
192
|
+
<DropdownMenu.Trigger disabled={!items?.length} asChild>
|
|
193
|
+
<IconButton
|
|
194
|
+
iconOnly
|
|
195
|
+
variant='ghost'
|
|
196
|
+
icon='ph--dots-three-vertical--regular'
|
|
197
|
+
label={t('toolbar-menu.label')}
|
|
198
|
+
/>
|
|
199
|
+
</DropdownMenu.Trigger>
|
|
200
|
+
{(items?.length ?? 0) > 0 && (
|
|
201
|
+
<DropdownMenu.Portal>
|
|
202
|
+
<DropdownMenu.Content>
|
|
203
|
+
<DropdownMenu.Viewport>
|
|
204
|
+
{items?.map(({ label, onClick: onSelect }, index) => (
|
|
205
|
+
// `context` is the generic payload threaded to each handler; the cast is the
|
|
206
|
+
// generic boundary (T may be `void`, so `context` is typed `T | undefined`).
|
|
207
|
+
<DropdownMenu.Item key={index} onSelect={() => onSelect(context as T)}>
|
|
208
|
+
{label}
|
|
209
|
+
</DropdownMenu.Item>
|
|
210
|
+
))}
|
|
211
|
+
</DropdownMenu.Viewport>
|
|
212
|
+
<DropdownMenu.Arrow />
|
|
213
|
+
</DropdownMenu.Content>
|
|
214
|
+
</DropdownMenu.Portal>
|
|
215
|
+
)}
|
|
216
|
+
</DropdownMenu.Root>
|
|
217
|
+
</CardBlock>
|
|
153
218
|
);
|
|
154
219
|
}
|
|
155
220
|
|
|
156
221
|
CardMenu.displayName = CARD_MENU_NAME;
|
|
157
222
|
|
|
158
223
|
//
|
|
159
|
-
//
|
|
224
|
+
// Block
|
|
160
225
|
//
|
|
161
226
|
|
|
162
|
-
const
|
|
227
|
+
const CARD_BLOCK_NAME = 'Card.Block';
|
|
163
228
|
|
|
164
|
-
|
|
165
|
-
return (
|
|
166
|
-
<CardIconBlock>
|
|
167
|
-
<Icon {...props} />
|
|
168
|
-
</CardIconBlock>
|
|
169
|
-
);
|
|
170
|
-
}
|
|
229
|
+
type CardBlockProps = SlottableProps<{ end?: boolean; compact?: boolean; square?: boolean }>;
|
|
171
230
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
const
|
|
231
|
+
/**
|
|
232
|
+
* Leading (default) or trailing (`end`) gutter slot of a Card row/header. Sized to the
|
|
233
|
+
* rail-item square so a passive `<Icon>` aligns with an `IconButton`. Defaults text color to
|
|
234
|
+
* `subdued` so a decorative `<Icon>` child needs no styling; interactive children set their own.
|
|
235
|
+
*/
|
|
236
|
+
const CardBlock = composable<HTMLDivElement, CardBlockProps>(({ children, ...props }, forwardedRef) => {
|
|
237
|
+
const { tx } = useThemeContext();
|
|
238
|
+
const { className, ...rest } = composableProps(props);
|
|
179
239
|
|
|
180
|
-
|
|
181
|
-
|
|
240
|
+
return (
|
|
241
|
+
<Column.Block {...rest} classNames={tx('card.block', {}, className)} ref={forwardedRef}>
|
|
242
|
+
{children}
|
|
243
|
+
</Column.Block>
|
|
244
|
+
);
|
|
182
245
|
});
|
|
183
246
|
|
|
184
|
-
|
|
247
|
+
CardBlock.displayName = CARD_BLOCK_NAME;
|
|
185
248
|
|
|
186
249
|
//
|
|
187
250
|
// Title
|
|
@@ -271,32 +334,28 @@ CardSection.displayName = CARD_SECTION_NAME;
|
|
|
271
334
|
|
|
272
335
|
const CARD_ROW_NAME = 'Card.Row';
|
|
273
336
|
|
|
274
|
-
type CardRowProps = {
|
|
337
|
+
type CardRowProps = { fullWidth?: boolean };
|
|
275
338
|
|
|
276
339
|
/**
|
|
277
340
|
* A row inside a Card.
|
|
278
|
-
* - Default: spans all 3 columns
|
|
279
|
-
*
|
|
280
|
-
* - `fullWidth`: spans all columns without a subgrid — children do their own internal layout
|
|
281
|
-
*
|
|
341
|
+
* - Default: spans all 3 columns as a subgrid; children align via `data-slot` — `Card.Block`
|
|
342
|
+
* lands in the gutters (start/end), anonymous children in the center. Sets `--icon-size` 4.
|
|
343
|
+
* - `fullWidth`: spans all columns without a subgrid — children do their own internal layout;
|
|
344
|
+
* `Card.Block` placement is inert in this mode.
|
|
282
345
|
*/
|
|
283
346
|
const CardRow = slottable<HTMLDivElement, CardRowProps>(
|
|
284
|
-
({ children, asChild,
|
|
347
|
+
({ children, asChild, fullWidth, style, ...props }, forwardedRef) => {
|
|
285
348
|
const { tx } = useThemeContext();
|
|
286
349
|
const { className, ...rest } = composableProps(props);
|
|
287
350
|
const Comp = asChild ? Slot : Primitive.div;
|
|
288
|
-
const icon =
|
|
289
|
-
typeof iconProp === 'string' ? (
|
|
290
|
-
<CardIcon classNames='text-subdued' icon={iconProp as string} size={4} />
|
|
291
|
-
) : iconProp ? (
|
|
292
|
-
iconProp
|
|
293
|
-
) : (
|
|
294
|
-
<div />
|
|
295
|
-
);
|
|
296
351
|
|
|
297
352
|
return (
|
|
298
|
-
<Comp
|
|
299
|
-
{
|
|
353
|
+
<Comp
|
|
354
|
+
{...rest}
|
|
355
|
+
style={{ ...iconSize(4), ...style }}
|
|
356
|
+
className={tx('card.row', { fullWidth }, className)}
|
|
357
|
+
ref={forwardedRef}
|
|
358
|
+
>
|
|
300
359
|
{children}
|
|
301
360
|
</Comp>
|
|
302
361
|
);
|
|
@@ -379,15 +438,21 @@ type CardPosterProps = ThemedClassName<
|
|
|
379
438
|
Omit<ImageProps, 'src' | 'alt' | 'classNames'>
|
|
380
439
|
>;
|
|
381
440
|
|
|
382
|
-
function CardPoster({
|
|
441
|
+
function CardPoster({
|
|
442
|
+
classNames,
|
|
443
|
+
alt,
|
|
444
|
+
aspect: aspectProp,
|
|
445
|
+
image,
|
|
446
|
+
icon,
|
|
447
|
+
fit = 'cover',
|
|
448
|
+
...imageProps
|
|
449
|
+
}: CardPosterProps) {
|
|
383
450
|
const { tx } = useThemeContext();
|
|
384
451
|
const aspect = aspectProp === 'auto' ? 'aspect-auto' : 'aspect-video';
|
|
385
452
|
|
|
386
453
|
if (image) {
|
|
387
454
|
return (
|
|
388
|
-
<
|
|
389
|
-
<Image classNames={[tx('card.poster', {}), aspect, classNames]} src={image} alt={alt} {...imageProps} />
|
|
390
|
-
</div>
|
|
455
|
+
<Image classNames={[tx('card.poster', {}), aspect, classNames]} src={image} alt={alt} fit={fit} {...imageProps} />
|
|
391
456
|
);
|
|
392
457
|
}
|
|
393
458
|
|
|
@@ -414,9 +479,17 @@ function CardAction({ icon, actionIcon = 'ph--arrow-right--regular', label, onCl
|
|
|
414
479
|
const { tx } = useThemeContext();
|
|
415
480
|
return (
|
|
416
481
|
<Button variant='ghost' classNames={tx('card.action', {})} onClick={onClick}>
|
|
417
|
-
{icon
|
|
418
|
-
|
|
419
|
-
|
|
482
|
+
{icon && (
|
|
483
|
+
<CardBlock>
|
|
484
|
+
<Icon icon={icon} size={4} />
|
|
485
|
+
</CardBlock>
|
|
486
|
+
)}
|
|
487
|
+
<span className={tx('card.action-label', {})}>{label}</span>
|
|
488
|
+
{actionIcon && (
|
|
489
|
+
<CardBlock end>
|
|
490
|
+
<Icon icon={actionIcon} size={4} />
|
|
491
|
+
</CardBlock>
|
|
492
|
+
)}
|
|
420
493
|
</Button>
|
|
421
494
|
);
|
|
422
495
|
}
|
|
@@ -435,9 +508,13 @@ function CardLink({ label, href }: CardLinkProps) {
|
|
|
435
508
|
const { tx } = useThemeContext();
|
|
436
509
|
return (
|
|
437
510
|
<a className={tx('card.link', {})} data-variant='ghost' href={href} target='_blank' rel='noreferrer'>
|
|
438
|
-
<
|
|
511
|
+
<CardBlock>
|
|
512
|
+
<Icon icon='ph--link--regular' size={4} />
|
|
513
|
+
</CardBlock>
|
|
439
514
|
<span className={tx('card.link-label', {})}>{label}</span>
|
|
440
|
-
<
|
|
515
|
+
<CardBlock end classNames='invisible group-hover:visible'>
|
|
516
|
+
<Icon icon='ph--arrow-square-out--regular' size={4} />
|
|
517
|
+
</CardBlock>
|
|
441
518
|
</a>
|
|
442
519
|
);
|
|
443
520
|
}
|
|
@@ -454,12 +531,11 @@ export const Card = {
|
|
|
454
531
|
// Header
|
|
455
532
|
Header: CardHeader,
|
|
456
533
|
|
|
457
|
-
// Header parts
|
|
458
|
-
|
|
534
|
+
// Header / row parts
|
|
535
|
+
Block: CardBlock,
|
|
459
536
|
DragHandle: CardDragHandle,
|
|
460
537
|
ActionIconButton: CardActionIconButton,
|
|
461
538
|
Menu: CardMenu,
|
|
462
|
-
Icon: CardIcon,
|
|
463
539
|
Title: CardTitle,
|
|
464
540
|
|
|
465
541
|
// Body
|
|
@@ -476,10 +552,11 @@ export const Card = {
|
|
|
476
552
|
};
|
|
477
553
|
|
|
478
554
|
export type {
|
|
479
|
-
CardRootProps,
|
|
480
|
-
CardHeaderProps,
|
|
481
|
-
CardDragHandleProps,
|
|
482
555
|
CardActionIconButtonProps,
|
|
556
|
+
CardBlockProps,
|
|
557
|
+
CardDragHandleProps,
|
|
558
|
+
CardHeaderProps,
|
|
483
559
|
CardMenuProps,
|
|
560
|
+
CardRootProps,
|
|
484
561
|
CardSectionProps,
|
|
485
562
|
};
|
|
@@ -5,37 +5,49 @@
|
|
|
5
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
6
|
import React from 'react';
|
|
7
7
|
|
|
8
|
-
import { withTheme } from '../../testing';
|
|
9
|
-
import {
|
|
8
|
+
import { withLayout, withTheme } from '../../testing';
|
|
9
|
+
import { translations } from '../../translations';
|
|
10
|
+
import { Carousel, type CarouselTransition } from './Carousel';
|
|
10
11
|
|
|
11
12
|
// Stable placeholder images so the story renders without network fixtures.
|
|
12
13
|
const IMAGES = Array.from({ length: 5 }).map((_, index) => `https://placehold.co/640x360?text=Slide+${index + 1}`);
|
|
13
14
|
|
|
14
|
-
type
|
|
15
|
+
type StoryArgs = {
|
|
16
|
+
count?: number;
|
|
17
|
+
transition?: CarouselTransition;
|
|
18
|
+
continuous?: boolean;
|
|
19
|
+
autoAdvance?: number;
|
|
20
|
+
};
|
|
15
21
|
|
|
16
|
-
const DefaultStory = ({ count = IMAGES.length }:
|
|
22
|
+
const DefaultStory = ({ count = IMAGES.length, transition, continuous, autoAdvance }: StoryArgs) => {
|
|
17
23
|
const images = IMAGES.slice(0, count);
|
|
18
24
|
return (
|
|
19
|
-
<
|
|
20
|
-
<Carousel.
|
|
21
|
-
<Carousel.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
25
|
+
<div className='h-full flex items-center'>
|
|
26
|
+
<Carousel.Root count={images.length} transition={transition} continuous={continuous} autoAdvance={autoAdvance}>
|
|
27
|
+
<Carousel.Content>
|
|
28
|
+
<Carousel.Previous />
|
|
29
|
+
<Carousel.Viewport>
|
|
30
|
+
{images.map((src, index) => (
|
|
31
|
+
<Carousel.Slide key={src} index={index} src={src} alt={`Slide ${index + 1}`} />
|
|
32
|
+
))}
|
|
33
|
+
</Carousel.Viewport>
|
|
34
|
+
<Carousel.Next />
|
|
35
|
+
<Carousel.Indicators />
|
|
36
|
+
<Carousel.Caption>{(index) => `Slide ${index + 1} of ${images.length}`}</Carousel.Caption>
|
|
37
|
+
</Carousel.Content>
|
|
38
|
+
</Carousel.Root>
|
|
39
|
+
</div>
|
|
32
40
|
);
|
|
33
41
|
};
|
|
34
42
|
|
|
35
43
|
const meta = {
|
|
36
44
|
title: 'ui/react-ui-core/components/Carousel',
|
|
37
45
|
render: DefaultStory,
|
|
38
|
-
decorators: [withTheme()],
|
|
46
|
+
decorators: [withTheme(), withLayout({ layout: 'column' })],
|
|
47
|
+
parameters: {
|
|
48
|
+
layout: 'fullscreen',
|
|
49
|
+
translations,
|
|
50
|
+
},
|
|
39
51
|
} satisfies Meta<typeof DefaultStory>;
|
|
40
52
|
|
|
41
53
|
export default meta;
|
|
@@ -45,3 +57,15 @@ type Story = StoryObj<typeof meta>;
|
|
|
45
57
|
export const Default: Story = {
|
|
46
58
|
args: { count: 5 },
|
|
47
59
|
};
|
|
60
|
+
|
|
61
|
+
export const Sliding: Story = {
|
|
62
|
+
args: { count: 5, transition: 'slide' },
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export const Continuous: Story = {
|
|
66
|
+
args: { count: 5, transition: 'slide', continuous: true },
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const AutoAdvancing: Story = {
|
|
70
|
+
args: { count: 5, transition: 'slide', continuous: true, autoAdvance: 5_000 },
|
|
71
|
+
};
|