@dxos/react-ui 0.8.4-main.74a063c4e0 → 0.8.4-main.765dc60934
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-KRSEIVRM.mjs → chunk-BDBC6H6V.mjs} +74 -2
- package/dist/lib/browser/{chunk-KRSEIVRM.mjs.map → chunk-BDBC6H6V.mjs.map} +4 -4
- package/dist/lib/browser/index.mjs +653 -422
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +20 -13
- 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-ENYC4TYH.mjs → chunk-3JSJK2ZY.mjs} +74 -2
- package/dist/lib/node-esm/{chunk-ENYC4TYH.mjs.map → chunk-3JSJK2ZY.mjs.map} +4 -4
- 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 +653 -422
- 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 +20 -13
- 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.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.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.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 +23 -49
- package/dist/types/src/components/Card/Card.d.ts.map +1 -1
- package/dist/types/src/components/Card/Card.stories.d.ts.map +1 -1
- package/dist/types/src/components/Carousel/Carousel.d.ts +90 -0
- package/dist/types/src/components/Carousel/Carousel.d.ts.map +1 -0
- package/dist/types/src/components/Carousel/index.d.ts +2 -0
- package/dist/types/src/components/Carousel/index.d.ts.map +1 -0
- package/dist/types/src/components/Clipboard/ClipboardProvider.d.ts.map +1 -1
- package/dist/types/src/components/Clipboard/CopyButton.d.ts.map +1 -1
- package/dist/types/src/components/Clipboard/index.d.ts +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 +21 -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 +22 -24
- package/dist/types/src/components/Dialog/Dialog.d.ts.map +1 -1
- 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 +2 -10
- package/dist/types/src/components/Focus/Focus.d.ts.map +1 -1
- package/dist/types/src/components/Focus/Focus.stories.d.ts.map +1 -1
- package/dist/types/src/components/Icon/Icon.d.ts +1 -0
- package/dist/types/src/components/Icon/Icon.d.ts.map +1 -1
- package/dist/types/src/components/Icon/Icon.stories.d.ts +1 -1
- 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.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 +2 -6
- package/dist/types/src/components/List/List.d.ts.map +1 -1
- package/dist/types/src/components/List/List.stories.d.ts +2 -6
- 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 +1 -5
- 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 +30 -0
- package/dist/types/src/components/MediaPlayer/MediaPlayer.d.ts.map +1 -0
- package/dist/types/src/components/MediaPlayer/MediaPlayer.stories.d.ts +15 -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 +11 -3
- package/dist/types/src/components/Menu/DropdownMenu.d.ts.map +1 -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.map +1 -1
- package/dist/types/src/components/Popover/Popover.d.ts +10 -2
- 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 +2 -10
- package/dist/types/src/components/ScrollArea/ScrollArea.d.ts.map +1 -1
- package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts +2 -10
- package/dist/types/src/components/ScrollArea/ScrollArea.stories.d.ts.map +1 -1
- package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts +11 -15
- package/dist/types/src/components/ScrollContainer/ScrollContainer.d.ts.map +1 -1
- package/dist/types/src/components/ScrollContainer/ScrollContainer.stories.d.ts.map +1 -1
- package/dist/types/src/components/Select/Select.d.ts.map +1 -1
- package/dist/types/src/components/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 +3 -11
- 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.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.map +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 +5 -13
- 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 +2 -2
- package/dist/types/src/components/Tooltip/Tooltip.d.ts.map +1 -1
- package/dist/types/src/components/Tooltip/Tooltip.stories.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +2 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/exemplars/generics.stories.d.ts +1 -5
- package/dist/types/src/exemplars/generics.stories.d.ts.map +1 -1
- 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.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 +11 -29
- package/dist/types/src/primitives/Column/Column.d.ts.map +1 -1
- package/dist/types/src/primitives/Column/Column.stories.d.ts +7 -7
- package/dist/types/src/primitives/Column/Column.stories.d.ts.map +1 -1
- package/dist/types/src/primitives/Container/Container.d.ts +1 -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 +1 -5
- 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 +1 -5
- 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 +4 -20
- 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.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 +27 -25
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +1 -1
- package/src/components/Button/IconButton.stories.tsx +1 -1
- package/src/components/Button/IconButton.tsx +3 -2
- package/src/components/Card/Card.stories.tsx +3 -3
- package/src/components/Card/Card.tsx +42 -20
- package/src/components/Carousel/Carousel.tsx +339 -0
- package/src/components/Carousel/index.ts +5 -0
- package/src/components/Clipboard/CopyButton.tsx +2 -2
- package/src/components/Dialog/Dialog.stories.tsx +2 -2
- package/src/components/Dialog/Dialog.tsx +29 -29
- package/src/components/ErrorFallback/ErrorStack.tsx +36 -2
- package/src/components/Icon/Icon.tsx +10 -3
- package/src/components/Image/Image.tsx +31 -8
- package/src/components/Input/Input.tsx +3 -3
- package/src/components/List/List.stories.tsx +1 -1
- package/src/components/List/List.tsx +1 -1
- package/src/components/List/ListDropIndicator.tsx +0 -1
- package/src/components/List/Tree.stories.tsx +1 -1
- package/src/components/MediaPlayer/MediaPlayer.stories.tsx +42 -0
- package/src/components/MediaPlayer/MediaPlayer.tsx +97 -0
- package/src/components/MediaPlayer/index.ts +5 -0
- package/src/components/Message/Message.stories.tsx +1 -1
- package/src/components/Message/Message.tsx +24 -7
- package/src/components/ScrollArea/ScrollArea.stories.tsx +1 -5
- package/src/components/ScrollContainer/ScrollContainer.tsx +1 -3
- package/src/components/ThemeProvider/index.ts +1 -1
- package/src/components/Toolbar/Toolbar.tsx +4 -2
- package/src/components/Tooltip/Tooltip.stories.tsx +1 -1
- package/src/components/index.ts +2 -0
- package/src/exemplars/slot.stories.tsx +2 -4
- package/src/exemplars/virtualizer.stories.tsx +0 -1
- package/src/playground/Custom.stories.tsx +13 -6
- package/src/primitives/Column/AUDIT.md +105 -311
- package/src/primitives/Column/Column.stories.tsx +58 -59
- package/src/primitives/Column/Column.tsx +54 -58
- package/src/testing/Loading.tsx +24 -4
- package/src/testing/decorators/withLayout.tsx +7 -17
- package/src/translations.ts +5 -0
|
@@ -4,17 +4,17 @@
|
|
|
4
4
|
|
|
5
5
|
import { createContext } from '@radix-ui/react-context';
|
|
6
6
|
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
7
|
+
import { Primitive } from '@radix-ui/react-primitive';
|
|
8
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
7
9
|
import React, {
|
|
8
10
|
type ComponentPropsWithRef,
|
|
9
11
|
type ForwardRefExoticComponent,
|
|
10
12
|
type FunctionComponent,
|
|
11
|
-
type PropsWithChildren,
|
|
12
13
|
forwardRef,
|
|
13
14
|
} from 'react';
|
|
14
15
|
import { useTranslation } from 'react-i18next';
|
|
15
16
|
|
|
16
|
-
import { type DialogSize, osTranslations } from '@dxos/ui-theme';
|
|
17
|
-
import { slottable } from '@dxos/ui-theme';
|
|
17
|
+
import { composableProps, type DialogSize, osTranslations, slottable } from '@dxos/ui-theme';
|
|
18
18
|
import { type SlottableProps } from '@dxos/ui-types';
|
|
19
19
|
|
|
20
20
|
import { useThemeContext } from '../../hooks';
|
|
@@ -138,18 +138,18 @@ DialogContent.displayName = DIALOG_CONTENT_NAME;
|
|
|
138
138
|
// Header
|
|
139
139
|
//
|
|
140
140
|
|
|
141
|
-
type DialogHeaderProps =
|
|
141
|
+
type DialogHeaderProps = SlottableProps;
|
|
142
142
|
|
|
143
|
-
const DialogHeader
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
);
|
|
143
|
+
const DialogHeader = slottable<HTMLDivElement>(({ children, asChild, ...props }, forwardedRef) => {
|
|
144
|
+
const { className, ...rest } = composableProps(props);
|
|
145
|
+
const Comp = asChild ? Slot : Primitive.div;
|
|
146
|
+
const { tx } = useThemeContext();
|
|
147
|
+
return (
|
|
148
|
+
<Comp {...rest} className={tx('dialog.header', {}, className)} ref={forwardedRef}>
|
|
149
|
+
{children}
|
|
150
|
+
</Comp>
|
|
151
|
+
);
|
|
152
|
+
});
|
|
153
153
|
|
|
154
154
|
//
|
|
155
155
|
// CloseIconButton
|
|
@@ -181,11 +181,13 @@ const DialogCloseIconButton = forwardRef<HTMLButtonElement, DialogCloseIconButto
|
|
|
181
181
|
type DialogBodyProps = SlottableProps;
|
|
182
182
|
|
|
183
183
|
const DialogBody = slottable<HTMLDivElement>(({ children, asChild, ...props }, forwardedRef) => {
|
|
184
|
+
const { className, ...rest } = composableProps(props);
|
|
185
|
+
const Comp = asChild ? Slot : Primitive.div;
|
|
184
186
|
const { tx } = useThemeContext();
|
|
185
187
|
return (
|
|
186
|
-
<
|
|
188
|
+
<Comp {...rest} className={tx('dialog.body', {}, className)} ref={forwardedRef}>
|
|
187
189
|
{children}
|
|
188
|
-
</
|
|
190
|
+
</Comp>
|
|
189
191
|
);
|
|
190
192
|
});
|
|
191
193
|
|
|
@@ -227,20 +229,18 @@ const DialogDescription = forwardRef<HTMLParagraphElement, DialogDescriptionProp
|
|
|
227
229
|
// ActionBar
|
|
228
230
|
//
|
|
229
231
|
|
|
230
|
-
type DialogActionBarProps =
|
|
232
|
+
type DialogActionBarProps = SlottableProps;
|
|
231
233
|
|
|
232
|
-
const DialogActionBar =
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
},
|
|
243
|
-
);
|
|
234
|
+
const DialogActionBar = slottable<HTMLDivElement>(({ children, asChild, ...props }, forwardedRef) => {
|
|
235
|
+
const { className: classNames, ...rest } = composableProps(props);
|
|
236
|
+
const Comp = asChild ? Slot : Primitive.div;
|
|
237
|
+
const { tx } = useThemeContext();
|
|
238
|
+
return (
|
|
239
|
+
<Comp {...rest} className={tx('dialog.actionbar', {}, classNames)} ref={forwardedRef}>
|
|
240
|
+
{children}
|
|
241
|
+
</Comp>
|
|
242
|
+
);
|
|
243
|
+
});
|
|
244
244
|
|
|
245
245
|
//
|
|
246
246
|
// Close
|
|
@@ -9,11 +9,45 @@ import { mx } from '@dxos/ui-theme';
|
|
|
9
9
|
|
|
10
10
|
type LocalFrame = { href: string; fileName: string };
|
|
11
11
|
|
|
12
|
+
export type ParsedStackFrame = ReturnType<typeof ErrorStackParser.parse>[number];
|
|
13
|
+
|
|
14
|
+
export type ErrorStackProps = {
|
|
15
|
+
/** When set, these frames are shown instead of parsing `error`. */
|
|
16
|
+
frames?: ParsedStackFrame[];
|
|
17
|
+
/** Used when `frames` is omitted. */
|
|
18
|
+
error?: Error;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Parses `captureOwnerStack()` output (React dev) into frames for {@link ErrorStack}.
|
|
23
|
+
* Prefixes a synthetic Error line when needed so `error-stack-parser` can read V8-style stacks.
|
|
24
|
+
*/
|
|
25
|
+
export const parseCaptureOwnerStack = (stack: string | null): ParsedStackFrame[] | null => {
|
|
26
|
+
if (stack == null || stack.length === 0) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
const err = new Error();
|
|
30
|
+
err.stack = stack;
|
|
31
|
+
try {
|
|
32
|
+
return ErrorStackParser.parse(err);
|
|
33
|
+
} catch {
|
|
34
|
+
err.stack = `Error\n${stack}`;
|
|
35
|
+
try {
|
|
36
|
+
return ErrorStackParser.parse(err);
|
|
37
|
+
} catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
12
43
|
/**
|
|
13
44
|
* Renders a parsed error stack trace with tree connector symbols and clickable vscode:// links for local frames.
|
|
14
45
|
*/
|
|
15
|
-
export const ErrorStack = ({ error
|
|
16
|
-
const frames = ErrorStackParser.parse(error);
|
|
46
|
+
export const ErrorStack = ({ error, frames: framesProp }: ErrorStackProps) => {
|
|
47
|
+
const frames = framesProp ?? (error ? ErrorStackParser.parse(error) : []);
|
|
48
|
+
if (frames.length === 0) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
17
51
|
|
|
18
52
|
return (
|
|
19
53
|
<div className='font-mono text-sm'>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { type Primitive } from '@radix-ui/react-primitive';
|
|
6
|
-
import React, { type ComponentPropsWithRef, forwardRef, memo } from 'react';
|
|
6
|
+
import React, { type ComponentPropsWithRef, forwardRef, memo, useMemo } from 'react';
|
|
7
7
|
|
|
8
8
|
import { type Size } from '@dxos/ui-types';
|
|
9
9
|
|
|
@@ -13,18 +13,25 @@ import { type ThemedClassName } from '../../util';
|
|
|
13
13
|
export type IconProps = ThemedClassName<ComponentPropsWithRef<typeof Primitive.svg>> & {
|
|
14
14
|
icon: string;
|
|
15
15
|
size?: Size;
|
|
16
|
+
synchronized?: boolean;
|
|
16
17
|
};
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* The Icon's size can be set directly or inherited from the `--dx-icon-size` CSS variable.
|
|
20
21
|
*/
|
|
21
22
|
export const Icon = memo(
|
|
22
|
-
forwardRef<SVGSVGElement, IconProps>(({
|
|
23
|
+
forwardRef<SVGSVGElement, IconProps>(({ classNames, icon, size, synchronized, style, ...props }, forwardedRef) => {
|
|
23
24
|
const { tx } = useThemeContext();
|
|
25
|
+
const spinDelay = useMemo(() => (synchronized ? `${-(Date.now() % 1_000)}ms` : undefined), [synchronized]);
|
|
24
26
|
const href = useIconHref(icon);
|
|
25
27
|
|
|
26
28
|
return (
|
|
27
|
-
<svg
|
|
29
|
+
<svg
|
|
30
|
+
{...props}
|
|
31
|
+
style={{ ...style, animationDelay: spinDelay }}
|
|
32
|
+
className={tx('icon.root', { size }, classNames)}
|
|
33
|
+
ref={forwardedRef}
|
|
34
|
+
>
|
|
28
35
|
<use href={href} />
|
|
29
36
|
</svg>
|
|
30
37
|
);
|
|
@@ -13,15 +13,16 @@ export type ImageProps = ThemedClassName<
|
|
|
13
13
|
{
|
|
14
14
|
src: string;
|
|
15
15
|
alt?: string;
|
|
16
|
+
fit?: 'contain' | 'cover';
|
|
16
17
|
crossOrigin?: 'anonymous' | 'use-credentials' | '';
|
|
17
18
|
} & ColorOptions
|
|
18
19
|
>;
|
|
19
20
|
|
|
20
|
-
// TODO(burdon): Option for neutral background color.
|
|
21
21
|
export const Image = ({
|
|
22
22
|
classNames,
|
|
23
23
|
src,
|
|
24
24
|
alt = '',
|
|
25
|
+
fit = 'contain',
|
|
25
26
|
crossOrigin = 'anonymous',
|
|
26
27
|
sampleSize = 64,
|
|
27
28
|
contrast = 0.9,
|
|
@@ -68,7 +69,16 @@ export const Image = ({
|
|
|
68
69
|
|
|
69
70
|
return (
|
|
70
71
|
<div
|
|
71
|
-
|
|
72
|
+
// `isolate` (`isolation: isolate`) creates a new stacking context so
|
|
73
|
+
// the inner <img>'s `z-10` stays scoped to this wrapper. Without it
|
|
74
|
+
// the z-10 leaks into the parent's stacking context and elevates the
|
|
75
|
+
// image above any pseudo-element rings (e.g. Focus.Item's
|
|
76
|
+
// `dx-ring-pseudo` `::after`) painted on ancestors — most visibly,
|
|
77
|
+
// the focus ring on a Card containing a Card.Poster.
|
|
78
|
+
className={mx(
|
|
79
|
+
`relative flex w-full justify-center overflow-hidden transition-all duration-700 isolate`,
|
|
80
|
+
classNames,
|
|
81
|
+
)}
|
|
72
82
|
style={{
|
|
73
83
|
backgroundColor: dominantColor,
|
|
74
84
|
}}
|
|
@@ -94,7 +104,10 @@ export const Image = ({
|
|
|
94
104
|
crossOrigin={crossOriginState}
|
|
95
105
|
onError={handleImageError}
|
|
96
106
|
onLoad={handleImageLoad}
|
|
97
|
-
className=
|
|
107
|
+
className={mx(
|
|
108
|
+
'z-10 transition-opacity duration-500',
|
|
109
|
+
fit === 'cover' ? 'w-full h-full object-cover' : 'object-contain',
|
|
110
|
+
)}
|
|
98
111
|
style={{
|
|
99
112
|
opacity: imageLoaded ? 1 : 0,
|
|
100
113
|
}}
|
|
@@ -162,7 +175,9 @@ const extractDominantColor = (
|
|
|
162
175
|
const alpha = pixels[i + 3];
|
|
163
176
|
|
|
164
177
|
// Skip transparent pixels.
|
|
165
|
-
if (alpha === 0)
|
|
178
|
+
if (alpha === 0) {
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
166
181
|
|
|
167
182
|
// Calculate saturation to weight vibrant colors more.
|
|
168
183
|
const max = Math.max(red, green, blue);
|
|
@@ -202,21 +217,29 @@ const isTransparent = (pixels: Uint8ClampedArray, sampleSize: number, threshold:
|
|
|
202
217
|
for (let x = 0; x < sampleSize; x++) {
|
|
203
218
|
// Top edge.
|
|
204
219
|
const topIndex = x * 4;
|
|
205
|
-
if (pixels[topIndex + 3] === 0)
|
|
220
|
+
if (pixels[topIndex + 3] === 0) {
|
|
221
|
+
edgeTransparentPixels++;
|
|
222
|
+
}
|
|
206
223
|
|
|
207
224
|
// Bottom edge.
|
|
208
225
|
const bottomIndex = ((sampleSize - 1) * sampleSize + x) * 4;
|
|
209
|
-
if (pixels[bottomIndex + 3] === 0)
|
|
226
|
+
if (pixels[bottomIndex + 3] === 0) {
|
|
227
|
+
edgeTransparentPixels++;
|
|
228
|
+
}
|
|
210
229
|
}
|
|
211
230
|
|
|
212
231
|
for (let y = 1; y < sampleSize - 1; y++) {
|
|
213
232
|
// Left edge.
|
|
214
233
|
const leftIndex = y * sampleSize * 4;
|
|
215
|
-
if (pixels[leftIndex + 3] === 0)
|
|
234
|
+
if (pixels[leftIndex + 3] === 0) {
|
|
235
|
+
edgeTransparentPixels++;
|
|
236
|
+
}
|
|
216
237
|
|
|
217
238
|
// Right edge.
|
|
218
239
|
const rightIndex = (y * sampleSize + sampleSize - 1) * 4;
|
|
219
|
-
if (pixels[rightIndex + 3] === 0)
|
|
240
|
+
if (pixels[rightIndex + 3] === 0) {
|
|
241
|
+
edgeTransparentPixels++;
|
|
242
|
+
}
|
|
220
243
|
}
|
|
221
244
|
|
|
222
245
|
return edgeTransparentPixels / edgePixels > threshold;
|
|
@@ -130,13 +130,13 @@ type TextInputProps = InputSharedProps & ThemedClassName<TextInputPrimitiveProps
|
|
|
130
130
|
|
|
131
131
|
const TextInput = forwardRef<HTMLInputElement, InputScopedProps<TextInputProps>>(
|
|
132
132
|
(
|
|
133
|
-
{ __inputScope, classNames, density:
|
|
133
|
+
{ __inputScope, classNames, density: densityProp, elevation: elevationProp, variant, noAutoFill, ...props },
|
|
134
134
|
forwardedRef,
|
|
135
135
|
) => {
|
|
136
136
|
const { hasIosKeyboard } = useThemeContext();
|
|
137
137
|
const { tx } = useThemeContext();
|
|
138
|
-
const density = useDensityContext(
|
|
139
|
-
const elevation = useElevationContext(
|
|
138
|
+
const density = useDensityContext(densityProp);
|
|
139
|
+
const elevation = useElevationContext(elevationProp);
|
|
140
140
|
const { validationValence } = useInputContext(INPUT_NAME, __inputScope);
|
|
141
141
|
|
|
142
142
|
return (
|
|
@@ -176,7 +176,7 @@ export const Collapsible: Story = {
|
|
|
176
176
|
<List {...args}>
|
|
177
177
|
{items.map(({ id, text, body }, index) => (
|
|
178
178
|
<ListItem.Root key={id} id={id} collapsible={index !== 2} defaultOpen={index % 2 === 0}>
|
|
179
|
-
<div
|
|
179
|
+
<div className='grow flex'>
|
|
180
180
|
{index !== 2 ? <ListItem.OpenTrigger /> : <ListItem.MockOpenTrigger />}
|
|
181
181
|
<ListItem.Heading classNames='grow pt-2'>{text}</ListItem.Heading>
|
|
182
182
|
<ListItem.Endcap>
|
|
@@ -75,7 +75,7 @@ const MockListItemOpenTrigger = ({
|
|
|
75
75
|
}: ThemedClassName<Omit<ComponentPropsWithoutRef<'div'>, 'children'>>) => {
|
|
76
76
|
const density = useDensityContext();
|
|
77
77
|
const { tx } = useThemeContext();
|
|
78
|
-
return <div
|
|
78
|
+
return <div {...props} className={tx('list.item.openTrigger', { density }, classNames)} />;
|
|
79
79
|
};
|
|
80
80
|
|
|
81
81
|
type ListItemHeadingProps = ThemedClassName<ListPrimitiveItemHeadingProps>;
|
|
@@ -32,7 +32,7 @@ const StorybookTreeItem = ({ data, prefix }: StorybookTreeItemProps) => {
|
|
|
32
32
|
|
|
33
33
|
return (
|
|
34
34
|
<TreeItem.Root key={id} id={id} collapsible={!valueIsScalar} defaultOpen>
|
|
35
|
-
<div
|
|
35
|
+
<div className='grow flex'>
|
|
36
36
|
{valueIsScalar ? <TreeItem.MockOpenTrigger /> : <TreeItem.OpenTrigger />}
|
|
37
37
|
<TreeItem.Heading classNames='grow pt-1'>{valueIsScalar ? String(value) : key}</TreeItem.Heading>
|
|
38
38
|
</div>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
|
+
|
|
7
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
8
|
+
|
|
9
|
+
import { MediaPlayer } from './MediaPlayer';
|
|
10
|
+
|
|
11
|
+
const meta = {
|
|
12
|
+
title: 'ui/react-ui/MediaPlayer',
|
|
13
|
+
component: MediaPlayer,
|
|
14
|
+
decorators: [withTheme()],
|
|
15
|
+
parameters: { layout: 'centered' },
|
|
16
|
+
} satisfies Meta<typeof MediaPlayer>;
|
|
17
|
+
|
|
18
|
+
export default meta;
|
|
19
|
+
|
|
20
|
+
type Story = StoryObj<typeof meta>;
|
|
21
|
+
|
|
22
|
+
export const Video: Story = {
|
|
23
|
+
args: {
|
|
24
|
+
src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
|
|
25
|
+
classNames: 'max-w-[640px]',
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const Audio: Story = {
|
|
30
|
+
args: {
|
|
31
|
+
src: 'https://commondatastorage.googleapis.com/codeskulptor-demos/DDR_assets/Kangaroo_MusiQue_-_The_Neverwritten_Role_Playing_Game.mp3',
|
|
32
|
+
classNames: 'min-w-[480px]',
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const ExplicitKind: Story = {
|
|
37
|
+
args: {
|
|
38
|
+
src: 'https://commondatastorage.googleapis.com/codeskulptor-demos/DDR_assets/Kangaroo_MusiQue_-_The_Neverwritten_Role_Playing_Game.mp3',
|
|
39
|
+
kind: 'audio',
|
|
40
|
+
classNames: 'min-w-[480px]',
|
|
41
|
+
},
|
|
42
|
+
};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
import { mx } from '@dxos/ui-theme';
|
|
8
|
+
|
|
9
|
+
import { type ThemedClassName } from '../../util';
|
|
10
|
+
|
|
11
|
+
export type MediaKind = 'video' | 'audio';
|
|
12
|
+
|
|
13
|
+
export type MediaPlayerProps = ThemedClassName<{
|
|
14
|
+
src: string;
|
|
15
|
+
/** Override auto-detection. When omitted, `detectMediaKind(src)` is used and falls back to 'video'. */
|
|
16
|
+
kind?: MediaKind;
|
|
17
|
+
controls?: boolean;
|
|
18
|
+
autoPlay?: boolean;
|
|
19
|
+
loop?: boolean;
|
|
20
|
+
muted?: boolean;
|
|
21
|
+
/** Accessible label for the `<video>` / `<audio>` element. */
|
|
22
|
+
alt?: string;
|
|
23
|
+
/** Defaults to 'anonymous' for cross-origin sources (e.g. signed S3 URLs). */
|
|
24
|
+
crossOrigin?: 'anonymous' | 'use-credentials' | '';
|
|
25
|
+
}>;
|
|
26
|
+
|
|
27
|
+
const VIDEO_EXTENSIONS = ['.mp4', '.webm', '.ogv', '.mov', '.m4v'];
|
|
28
|
+
const AUDIO_EXTENSIONS = ['.mp3', '.wav', '.ogg', '.m4a', '.aac', '.flac'];
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Best-effort detection of `video` vs `audio` from a media URL.
|
|
32
|
+
* Inspects the pathname's extension (ignoring query/hash). Returns `undefined`
|
|
33
|
+
* when the URL doesn't look like a recognised media file — callers should
|
|
34
|
+
* default to 'video' or render a fallback (e.g. iframe / img).
|
|
35
|
+
*/
|
|
36
|
+
export const detectMediaKind = (src: string): MediaKind | undefined => {
|
|
37
|
+
// Strip query and hash, then take the last path segment's extension.
|
|
38
|
+
const pathname = src.split(/[?#]/, 1)[0]!;
|
|
39
|
+
const lower = pathname.toLowerCase();
|
|
40
|
+
if (VIDEO_EXTENSIONS.some((extension) => lower.endsWith(extension))) {
|
|
41
|
+
return 'video';
|
|
42
|
+
}
|
|
43
|
+
if (AUDIO_EXTENSIONS.some((extension) => lower.endsWith(extension))) {
|
|
44
|
+
return 'audio';
|
|
45
|
+
}
|
|
46
|
+
return undefined;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Renders a generated or remotely-hosted media artefact as a native
|
|
51
|
+
* `<video>` or `<audio>` element. `kind` defaults to the auto-detected
|
|
52
|
+
* kind from the URL extension (and falls back to 'video' for ambiguous URLs).
|
|
53
|
+
*/
|
|
54
|
+
export const MediaPlayer = ({
|
|
55
|
+
classNames,
|
|
56
|
+
src,
|
|
57
|
+
kind,
|
|
58
|
+
controls = true,
|
|
59
|
+
autoPlay = false,
|
|
60
|
+
loop = false,
|
|
61
|
+
muted = false,
|
|
62
|
+
alt,
|
|
63
|
+
crossOrigin = 'anonymous',
|
|
64
|
+
}: MediaPlayerProps) => {
|
|
65
|
+
const resolved = kind ?? detectMediaKind(src) ?? 'video';
|
|
66
|
+
if (resolved === 'audio') {
|
|
67
|
+
return (
|
|
68
|
+
// TODO(burdon): Move to ui-theme.
|
|
69
|
+
<audio
|
|
70
|
+
className={mx('w-full', classNames)}
|
|
71
|
+
src={src}
|
|
72
|
+
controls={controls}
|
|
73
|
+
autoPlay={autoPlay}
|
|
74
|
+
loop={loop}
|
|
75
|
+
muted={muted}
|
|
76
|
+
crossOrigin={crossOrigin}
|
|
77
|
+
aria-label={alt}
|
|
78
|
+
/>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return (
|
|
83
|
+
// TODO(burdon): Move to ui-theme.
|
|
84
|
+
<div className={mx('dx-container flex items-center justify-center', classNames)}>
|
|
85
|
+
<video
|
|
86
|
+
className='aspect-video max-w-full max-h-full'
|
|
87
|
+
src={src}
|
|
88
|
+
controls={controls}
|
|
89
|
+
autoPlay={autoPlay}
|
|
90
|
+
loop={loop}
|
|
91
|
+
muted={muted}
|
|
92
|
+
crossOrigin={crossOrigin}
|
|
93
|
+
aria-label={alt}
|
|
94
|
+
/>
|
|
95
|
+
</div>
|
|
96
|
+
);
|
|
97
|
+
};
|
|
@@ -22,7 +22,7 @@ type DefaultStoryProps = {
|
|
|
22
22
|
const DefaultStory = ({ valence, title, body }: DefaultStoryProps) => (
|
|
23
23
|
<div className='w-[30rem]'>
|
|
24
24
|
<Message.Root valence={valence}>
|
|
25
|
-
{title && <Message.Title>{title}</Message.Title>}
|
|
25
|
+
{title && <Message.Title onClose={() => console.log('close')}>{title}</Message.Title>}
|
|
26
26
|
{body && <Message.Content>{body}</Message.Content>}
|
|
27
27
|
</Message.Root>
|
|
28
28
|
</div>
|
|
@@ -6,12 +6,16 @@ import { createContext } from '@radix-ui/react-context';
|
|
|
6
6
|
import { Primitive } from '@radix-ui/react-primitive';
|
|
7
7
|
import { Slot } from '@radix-ui/react-slot';
|
|
8
8
|
import React, { type ComponentPropsWithRef, forwardRef } from 'react';
|
|
9
|
+
import { useTranslation } from 'react-i18next';
|
|
9
10
|
|
|
10
11
|
import { useId } from '@dxos/react-hooks';
|
|
11
12
|
import { type Elevation, type MessageValence } from '@dxos/ui-types';
|
|
12
13
|
|
|
14
|
+
import { translationKey } from '#translations';
|
|
15
|
+
|
|
13
16
|
import { useElevationContext, useThemeContext } from '../../hooks';
|
|
14
17
|
import { type ThemedClassName } from '../../util';
|
|
18
|
+
import { IconButton } from '../Button';
|
|
15
19
|
import { Icon } from '../Icon';
|
|
16
20
|
|
|
17
21
|
const messageIcons: Record<MessageValence, string> = {
|
|
@@ -84,23 +88,36 @@ MessageRoot.displayName = MESSAGE_NAME;
|
|
|
84
88
|
//
|
|
85
89
|
|
|
86
90
|
type MessageTitleProps = Omit<ThemedClassName<ComponentPropsWithRef<typeof Primitive.h2>>, 'id'> & {
|
|
87
|
-
asChild?: boolean;
|
|
88
91
|
icon?: string;
|
|
92
|
+
onClose?: () => void;
|
|
89
93
|
};
|
|
90
94
|
|
|
91
95
|
const MESSAGE_TITLE_NAME = 'MessageTitle';
|
|
92
96
|
|
|
93
97
|
const MessageTitle = forwardRef<HTMLHeadingElement, MessageTitleProps>(
|
|
94
|
-
({
|
|
98
|
+
({ classNames, children, icon: iconProp, onClose }, forwardedRef) => {
|
|
99
|
+
const { t } = useTranslation(translationKey);
|
|
95
100
|
const { tx } = useThemeContext();
|
|
96
101
|
const { titleId, valence } = useMessageContext(MESSAGE_TITLE_NAME);
|
|
97
|
-
const Comp = asChild ? Slot : Primitive.h2;
|
|
98
102
|
const icon = iconProp ?? messageIcons[valence];
|
|
99
103
|
return (
|
|
100
|
-
<
|
|
101
|
-
{
|
|
102
|
-
|
|
103
|
-
|
|
104
|
+
<div className={tx('message.header', {}, classNames)} id={titleId} ref={forwardedRef}>
|
|
105
|
+
{icon && (
|
|
106
|
+
<div className={tx('message.icon', { valence })}>
|
|
107
|
+
<Icon icon={icon} />
|
|
108
|
+
</div>
|
|
109
|
+
)}
|
|
110
|
+
<h2 className={tx('message.title', {}, classNames)}>{children}</h2>
|
|
111
|
+
{onClose && (
|
|
112
|
+
<IconButton
|
|
113
|
+
variant='ghost'
|
|
114
|
+
icon='ph--x--regular'
|
|
115
|
+
iconOnly
|
|
116
|
+
label={t('toolbar-close.label')}
|
|
117
|
+
onClick={onClose}
|
|
118
|
+
/>
|
|
119
|
+
)}
|
|
120
|
+
</div>
|
|
104
121
|
);
|
|
105
122
|
},
|
|
106
123
|
);
|
|
@@ -48,11 +48,7 @@ const Row = ({ items = 50 }: { items?: number }) => (
|
|
|
48
48
|
);
|
|
49
49
|
|
|
50
50
|
const Container = ({ classNames, children }: ThemedClassName<PropsWithChildren>) => {
|
|
51
|
-
return (
|
|
52
|
-
<div role='none' className={mx('border border-separator rounded-md overflow-hidden', classNames)}>
|
|
53
|
-
{children}
|
|
54
|
-
</div>
|
|
55
|
-
);
|
|
51
|
+
return <div className={mx('border border-separator rounded-md overflow-hidden', classNames)}>{children}</div>;
|
|
56
52
|
};
|
|
57
53
|
|
|
58
54
|
export const Vertical = {
|
|
@@ -276,13 +276,12 @@ const Fade = () => {
|
|
|
276
276
|
|
|
277
277
|
return (
|
|
278
278
|
<div
|
|
279
|
-
role='none'
|
|
280
279
|
data-visible={overflow}
|
|
281
280
|
className={mx(
|
|
282
281
|
// NOTE: Gradients may not be visible with dark reader extensions.
|
|
283
282
|
'z-10 absolute top-0 inset-x-0 h-24 w-full',
|
|
284
283
|
'opacity-0 duration-200 transition-opacity data-[visible="true"]:opacity-100',
|
|
285
|
-
'bg-gradient-to-b from-(--surface
|
|
284
|
+
'bg-gradient-to-b from-(--color-base-surface) to-transparent pointer-events-none',
|
|
286
285
|
)}
|
|
287
286
|
/>
|
|
288
287
|
);
|
|
@@ -303,7 +302,6 @@ const ScrollDownButton = ({ classNames }: ScrollDownButtonProps) => {
|
|
|
303
302
|
|
|
304
303
|
return (
|
|
305
304
|
<div
|
|
306
|
-
role='none'
|
|
307
305
|
className={mx(
|
|
308
306
|
'absolute bottom-2 right-4 opacity-100 transition-opacity duration-300',
|
|
309
307
|
pinned && 'opacity-0',
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
export { type Label, isLabel, toLocalizedString } from '@dxos/ui-types';
|
|
5
|
+
export { type Label, isLabel, toLocalizedString } from '@dxos/ui-types/translations';
|
|
6
6
|
|
|
7
7
|
export * from './ThemeProvider';
|
|
8
8
|
export { useTranslation } from './TranslationsProvider';
|
|
@@ -12,8 +12,9 @@ import { useTranslation } from 'react-i18next';
|
|
|
12
12
|
import { composable, composableProps, slottable, type ToolbarStyleProps } from '@dxos/ui-theme';
|
|
13
13
|
import { type SlottableProps } from '@dxos/ui-types';
|
|
14
14
|
|
|
15
|
+
import { translationKey } from '#translations';
|
|
16
|
+
|
|
15
17
|
import { useThemeContext } from '../../hooks';
|
|
16
|
-
import { translationKey } from '../../translations';
|
|
17
18
|
import {
|
|
18
19
|
Button,
|
|
19
20
|
ButtonGroup,
|
|
@@ -160,7 +161,7 @@ const ToolbarToggleGroupItem = forwardRef<HTMLButtonElement, ToolbarToggleGroupI
|
|
|
160
161
|
type ToolbarToggleGroupIconItemProps = Omit<ToggleGroupItemPrimitiveProps, 'className'> & IconButtonProps;
|
|
161
162
|
|
|
162
163
|
const ToolbarToggleGroupIconItem = forwardRef<HTMLButtonElement, ToolbarToggleGroupIconItemProps>(
|
|
163
|
-
({ variant, density, elevation, classNames, icon, label, iconOnly, ...props }, forwardedRef) => {
|
|
164
|
+
({ variant, density, elevation, classNames, icon, label, iconOnly, iconClassNames, ...props }, forwardedRef) => {
|
|
164
165
|
return (
|
|
165
166
|
<ToolbarPrimitive.ToolbarToggleItem {...props} asChild>
|
|
166
167
|
<IconButton
|
|
@@ -172,6 +173,7 @@ const ToolbarToggleGroupIconItem = forwardRef<HTMLButtonElement, ToolbarToggleGr
|
|
|
172
173
|
icon,
|
|
173
174
|
label,
|
|
174
175
|
iconOnly,
|
|
176
|
+
iconClassNames,
|
|
175
177
|
}}
|
|
176
178
|
ref={forwardedRef}
|
|
177
179
|
/>
|
|
@@ -19,7 +19,7 @@ type DefaultStoryProps = {
|
|
|
19
19
|
const DefaultStory = ({ tooltips, defaultOpen }: DefaultStoryProps) => {
|
|
20
20
|
return (
|
|
21
21
|
<Tooltip.Provider defaultOpen={defaultOpen}>
|
|
22
|
-
<div
|
|
22
|
+
<div className='w-32'>
|
|
23
23
|
{tooltips.map(({ label, content }, i) => (
|
|
24
24
|
<Tooltip.Trigger asChild key={i} content={content} side='right'>
|
|
25
25
|
<Button classNames='block w-full'>{label}</Button>
|
package/src/components/index.ts
CHANGED
|
@@ -10,6 +10,7 @@ export * from './Avatars';
|
|
|
10
10
|
export * from './Breadcrumb';
|
|
11
11
|
export * from './Button';
|
|
12
12
|
export * from './Card';
|
|
13
|
+
export * from './Carousel';
|
|
13
14
|
export * from './Clipboard';
|
|
14
15
|
export * from './Dialog';
|
|
15
16
|
export * from './ErrorFallback';
|
|
@@ -20,6 +21,7 @@ export * from './Input';
|
|
|
20
21
|
export * from './Link';
|
|
21
22
|
export * from './List';
|
|
22
23
|
export * from './Main';
|
|
24
|
+
export * from './MediaPlayer';
|
|
23
25
|
export * from './Menu';
|
|
24
26
|
export * from './Message';
|
|
25
27
|
export * from './Popover';
|