@beydesign/storybook 0.4.10 → 0.4.12
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/stories/Buttons/MainButton.js +2 -2
- package/dist/stories/Buttons/types.d.ts +4 -0
- package/dist/stories/EntityCard/EntityCard.js +6 -4
- package/dist/stories/EntityCard/EntityCard.stories.js +1 -1
- package/dist/stories/EntityCard/types.d.ts +3 -1
- package/dist/stories/UI/ButtonCard.js +9 -6
- package/dist/stories/UI/types.d.ts +2 -0
- package/package.json +1 -1
|
@@ -248,7 +248,7 @@ const StyledButton = styled.button `
|
|
|
248
248
|
var(--global-shadows-shadow-xs-color);
|
|
249
249
|
}
|
|
250
250
|
`;
|
|
251
|
-
export const MainButton = ({ onClick, text, disabled = false, loading = false, type = ButtonType.Button, style, size = ButtonSize.xl, hierarchy = ButtonHierarchy.Primary, displayIcon, iconWeight = 'regular', displayIconMode = ButtonDisplayMode.Default, state = ButtonState.Default, shape = ButtonShape.Square, destructive = false, showLeadingIcon = false, showTrailingIcon = false, leadingIcon = 'Circle', trailingIcon = 'Circle', trailingIconSlot, testId, }) => {
|
|
251
|
+
export const MainButton = ({ onClick, text, disabled = false, loading = false, type = ButtonType.Button, style, size = ButtonSize.xl, hierarchy = ButtonHierarchy.Primary, displayIcon, iconWeight = 'regular', displayIconMode = ButtonDisplayMode.Default, state = ButtonState.Default, shape = ButtonShape.Square, destructive = false, showLeadingIcon = false, showTrailingIcon = false, leadingIcon = 'Circle', trailingIcon = 'Circle', trailingIconSlot, id, className, testId, }) => {
|
|
252
252
|
// Figma draws a 20px icon at every button size.
|
|
253
253
|
const iconSize = 20;
|
|
254
254
|
// Vertical padding comes from TEXT_BUTTON_HEIGHT; only the horizontal value
|
|
@@ -332,5 +332,5 @@ export const MainButton = ({ onClick, text, disabled = false, loading = false, t
|
|
|
332
332
|
(trailingIconSlot ??
|
|
333
333
|
(trailingIcon && getIconComponent(trailingIcon, iconProps)))] }));
|
|
334
334
|
};
|
|
335
|
-
return (_jsx(StyledButton, { onClick: onClick, type: type, disabled: state === ButtonState.Disabled || disabled, "$size": size, "$hierarchy": hierarchy, "$state": state, "$shape": shape, "$destructive": destructive, "$disabled": disabled, "$displayIconMode": displayIconMode, "$sizeStyles": sizeStyles, style: style, "data-testid": testId, children: renderContent() }));
|
|
335
|
+
return (_jsx(StyledButton, { onClick: onClick, type: type, disabled: state === ButtonState.Disabled || disabled, "$size": size, "$hierarchy": hierarchy, "$state": state, "$shape": shape, "$destructive": destructive, "$disabled": disabled, "$displayIconMode": displayIconMode, "$sizeStyles": sizeStyles, style: style, id: id, className: className, "data-testid": testId, children: renderContent() }));
|
|
336
336
|
};
|
|
@@ -112,6 +112,10 @@ export interface MainButtonProps {
|
|
|
112
112
|
* keeping the button's icon slot and spacing intact.
|
|
113
113
|
*/
|
|
114
114
|
trailingIconSlot?: React.ReactNode;
|
|
115
|
+
/** DOM id set on the rendered `<button>` — used by analytics click triggers */
|
|
116
|
+
id?: string;
|
|
117
|
+
/** Extra class names merged onto the rendered `<button>` */
|
|
118
|
+
className?: string;
|
|
115
119
|
/** Test Id */
|
|
116
120
|
testId?: string;
|
|
117
121
|
}
|
|
@@ -16,7 +16,7 @@ const WIDTH_BY_VIEW = {
|
|
|
16
16
|
/** Default image aspect ratio per view variant. */
|
|
17
17
|
const ASPECT_RATIO_BY_VIEW = {
|
|
18
18
|
avatar: '203 / 264',
|
|
19
|
-
agent: '
|
|
19
|
+
agent: '264 / 268',
|
|
20
20
|
video: '16 / 9',
|
|
21
21
|
};
|
|
22
22
|
/** Hook the root's hover/focus rules use to reveal the action buttons. */
|
|
@@ -27,7 +27,7 @@ const spin = keyframes `
|
|
|
27
27
|
`;
|
|
28
28
|
/** A continuously rotating refresh icon, matching the AgentCard processing spinner. */
|
|
29
29
|
const Spinner = () => (_jsx(Box, { display: 'flex', sx: { animation: `${spin} 1.5s linear infinite` }, children: _jsx(ArrowsClockwise, { size: 24, color: 'var(--color-text-text-white)' }) }));
|
|
30
|
-
export const EntityCard = ({ view = 'avatar', name, image, description = '', showDescription = false, date, aspectRatio, processing = false, processingText = 'Please wait', error = false, errorText = 'Something went wrong', onPreview, previewButtonText, previewIcon = 'Play', showStatusBadge = false, statusBadgeText = '', statusBadgeColor = BadgeColor.Green, menuItems = [], showMenu = false, width, testId, }) => {
|
|
30
|
+
export const EntityCard = ({ view = 'avatar', name, image, description = '', showDescription = false, date, aspectRatio, processing = false, processingText = 'Please wait', error = false, errorText = 'Something went wrong', onPreview, previewButtonText, previewIcon = 'Play', previewButtonClassName, showStatusBadge = false, statusBadgeText = '', statusBadgeColor = BadgeColor.Green, menuItems = [], showMenu = false, width, testId, }) => {
|
|
31
31
|
const [hovered, setHovered] = useState(false);
|
|
32
32
|
const [menuOpen, setMenuOpen] = useState(false);
|
|
33
33
|
const [imageError, setImageError] = useState(false);
|
|
@@ -63,7 +63,9 @@ export const EntityCard = ({ view = 'avatar', name, image, description = '', sho
|
|
|
63
63
|
opacity: 1,
|
|
64
64
|
pointerEvents: 'auto',
|
|
65
65
|
},
|
|
66
|
-
}, "data-testid": resolvedTestId, children: [_jsxs(Box, { position: 'relative', width: '100%', borderRadius: 'var(--spacing-tokens-size-in-px-spacing-spacing-sm)', overflow: 'hidden', sx: { aspectRatio: imageAspectRatio }, children: [error ? (_jsx(Box, { width: '100%', height: '100%', bgcolor: 'var(--color-background-bg-badge-accent-red)', display: 'flex', justifyContent: 'center', alignItems: 'center', role: 'img', "aria-label": errorText, title: errorText, children: _jsx(Warning, { size: 50, color: 'var(--color-foreground-fg-error)' }) })) : showImage ? (_jsx("img", { src: image, alt: name, width: '100%', height: '100%', style: { objectFit: 'cover', height: '100%', width: '100%' }, onError: () => setImageError(true) })) : (_jsx(Box, { position: 'relative', width: '100%', height: '100%', overflow: 'hidden', bgcolor:
|
|
66
|
+
}, "data-testid": resolvedTestId, children: [_jsxs(Box, { position: 'relative', width: '100%', borderRadius: 'var(--spacing-tokens-size-in-px-spacing-spacing-sm)', overflow: 'hidden', sx: { aspectRatio: imageAspectRatio }, children: [error ? (_jsx(Box, { width: '100%', height: '100%', bgcolor: 'var(--color-background-bg-badge-accent-red)', display: 'flex', justifyContent: 'center', alignItems: 'center', role: 'img', "aria-label": errorText, title: errorText, children: _jsx(Warning, { size: 50, color: 'var(--color-foreground-fg-error)' }) })) : showImage ? (_jsx("img", { src: image, alt: name, width: '100%', height: '100%', style: { objectFit: 'cover', height: '100%', width: '100%' }, onError: () => setImageError(true) })) : (_jsx(Box, { position: 'relative', width: '100%', height: '100%', overflow: 'hidden', bgcolor: view === 'agent'
|
|
67
|
+
? 'var(--color-background-bg-component-disabled)'
|
|
68
|
+
: 'var(--color-background-bg-button-disabled)', children: _jsx(Box, { position: 'absolute', bottom: 0, left: '50%', sx: {
|
|
67
69
|
transform: 'translateX(-50%)',
|
|
68
70
|
color: 'var(--color-border-border-subtle)',
|
|
69
71
|
aspectRatio: '206 / 224',
|
|
@@ -87,7 +89,7 @@ export const EntityCard = ({ view = 'avatar', name, image, description = '', sho
|
|
|
87
89
|
},
|
|
88
90
|
}),
|
|
89
91
|
}, children: [canPreview &&
|
|
90
|
-
(previewButtonText ? (_jsx(MainButton, { text: previewButtonText, showLeadingIcon: true, leadingIcon: previewIcon, iconWeight: 'fill', hierarchy: ButtonHierarchy.SecondaryTransparent, size: ButtonSize.
|
|
92
|
+
(previewButtonText ? (_jsx(MainButton, { text: previewButtonText, showLeadingIcon: true, leadingIcon: previewIcon, iconWeight: 'fill', hierarchy: ButtonHierarchy.SecondaryTransparent, size: ButtonSize.xxs, onClick: handlePreviewButtonClick, className: previewButtonClassName, testId: `${entityKey}-preview-button` })) : (_jsx(MainButton, { displayIcon: previewIcon, displayIconMode: ButtonDisplayMode.Only, hierarchy: ButtonHierarchy.SecondaryTransparent, size: ButtonSize.xxs, onClick: handlePreviewButtonClick, className: previewButtonClassName, testId: `${entityKey}-preview-button` }))), hasMenu && (_jsx(Box, { onClick: (event) => event.stopPropagation(), children: _jsx(Menu, { items: menuItems, testKey: entityKey, size: ButtonSize.xxs, onOpenChange: setMenuOpen }) }))] })), isVideo ? (_jsxs(Box, { position: 'absolute', left: 0, right: 0, bottom: 0, display: 'flex', flexDirection: 'row', alignItems: 'flex-end', justifyContent: 'space-between', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', padding: 'var(--spacing-tokens-size-in-px-spacing-spacing-3xl) var(--spacing-tokens-size-in-px-spacing-spacing-lg) var(--spacing-tokens-size-in-px-spacing-spacing-lg)', sx: {
|
|
91
93
|
zIndex: 2,
|
|
92
94
|
pointerEvents: 'none',
|
|
93
95
|
backgroundImage: 'linear-gradient(rgba(45, 38, 55, 0) 0%, rgba(45, 38, 55, 0.16) 34%, rgba(45, 38, 55, 0.64) 100%)',
|
|
@@ -51,7 +51,7 @@ const meta = {
|
|
|
51
51
|
description: 'Aspect ratio of the image — overrides the per-view default',
|
|
52
52
|
table: {
|
|
53
53
|
type: { summary: 'string' },
|
|
54
|
-
defaultValue: { summary: '203 / 264 ·
|
|
54
|
+
defaultValue: { summary: '203 / 264 · 264 / 268 · 16 / 9' },
|
|
55
55
|
},
|
|
56
56
|
},
|
|
57
57
|
processing: {
|
|
@@ -23,7 +23,7 @@ export interface EntityCardProps {
|
|
|
23
23
|
showDescription?: boolean;
|
|
24
24
|
/** Secondary text shown to the right of the name (`video` view, e.g. formatted created date) */
|
|
25
25
|
date?: string;
|
|
26
|
-
/** Aspect ratio of the image — overrides the per-view default (`203 / 264` avatar, `
|
|
26
|
+
/** Aspect ratio of the image — overrides the per-view default (`203 / 264` avatar, `264 / 268` agent, `16 / 9` video) */
|
|
27
27
|
aspectRatio?: string;
|
|
28
28
|
/** Show the processing overlay (spinner + label) over the image */
|
|
29
29
|
processing?: boolean;
|
|
@@ -39,6 +39,8 @@ export interface EntityCardProps {
|
|
|
39
39
|
previewButtonText?: string;
|
|
40
40
|
/** Icon for the action button (defaults to `Play`) */
|
|
41
41
|
previewIcon?: IconName;
|
|
42
|
+
/** Extra class names merged onto the action button — used by analytics click triggers */
|
|
43
|
+
previewButtonClassName?: string;
|
|
42
44
|
/** Whether to show the status badge (top-left) */
|
|
43
45
|
showStatusBadge?: boolean;
|
|
44
46
|
/** Status badge text (e.g. "Active") */
|
|
@@ -8,13 +8,13 @@ import { getIconComponent } from '../../utils';
|
|
|
8
8
|
* a short description and an optional corner action button. Matches the Figma
|
|
9
9
|
* "Button card" component with its default and hover states.
|
|
10
10
|
*/
|
|
11
|
-
export const ButtonCard = ({ title, description, icon = 'UserFocus', iconColor = 'var(--color-foreground-fg-accent-yellow)', iconBackgroundColor = 'var(--color-background-bg-badge-accent-yellow)', onClick, showActionButton = false, actionButtonText = 'Contact Us', onActionClick, disabled = false, width = '294px', style, testId, }) => {
|
|
11
|
+
export const ButtonCard = ({ title, description, icon = 'UserFocus', iconColor = 'var(--color-foreground-fg-accent-yellow)', iconBackgroundColor = 'var(--color-background-bg-badge-accent-yellow)', onClick, showActionButton = false, actionButtonText = 'Contact Us', onActionClick, disabled = false, width = '294px', style, id, testId, }) => {
|
|
12
12
|
const cardKey = title?.toLowerCase()?.replace(/\s+/g, '-');
|
|
13
13
|
const isInteractive = !disabled && !!onClick;
|
|
14
|
-
return (_jsxs(Box, { width: width, display: 'flex', alignItems: 'flex-start', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', paddingX: 'var(--spacing-tokens-size-in-px-spacing-spacing-xl)',
|
|
15
|
-
xs: 'var(--spacing-tokens-size-in-px-spacing-spacing-
|
|
16
|
-
sm: 'var(--spacing-tokens-size-in-px-spacing-spacing-
|
|
17
|
-
}, borderRadius: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', bgcolor: 'var(--color-background-bg-component)', boxSizing: 'border-box', position: 'relative', onClick: isInteractive ? onClick : undefined, style: style, "data-testid": testId ?? `${cardKey}-button-card`, sx: {
|
|
14
|
+
return (_jsxs(Box, { width: width, display: 'flex', alignItems: 'flex-start', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', paddingX: 'var(--spacing-tokens-size-in-px-spacing-spacing-xl)', paddingTop: {
|
|
15
|
+
xs: 'var(--spacing-tokens-size-in-px-spacing-spacing-2xl)',
|
|
16
|
+
sm: 'var(--spacing-tokens-size-in-px-spacing-spacing-3xl)',
|
|
17
|
+
}, paddingBottom: 'var(--spacing-tokens-size-in-px-spacing-spacing-xl)', borderRadius: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', bgcolor: 'var(--color-background-bg-component)', boxSizing: 'border-box', position: 'relative', onClick: isInteractive ? onClick : undefined, style: style, id: id, "data-testid": testId ?? `${cardKey}-button-card`, sx: {
|
|
18
18
|
opacity: disabled ? 0.5 : 1,
|
|
19
19
|
cursor: isInteractive ? 'pointer' : 'default',
|
|
20
20
|
pointerEvents: disabled ? 'none' : 'auto',
|
|
@@ -31,7 +31,10 @@ export const ButtonCard = ({ title, description, icon = 'UserFocus', iconColor =
|
|
|
31
31
|
// each side); Figma sizes the tile at a fixed 34×34. The 24px icon
|
|
32
32
|
// must not shrink to fit the 18px content box — like Figma it stays
|
|
33
33
|
// 24px and overflows the nominal padding, centered in the tile.
|
|
34
|
-
boxSizing: 'border-box', sx: { '& svg': { flexShrink: 0 } }, children: getIconComponent(icon, { size: 24, color: iconColor }) }), _jsxs(Box, { display: 'flex', flex: '1 0 0', minWidth: 0, flexDirection: 'column', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-xs)', alignItems: 'flex-start', sx: { wordBreak: 'break-word' }, children: [_jsx(Typography, { size: TypographySize.HeadingS, weight: TypographyWeight.Bold, color: 'var(--color-text-text-title)', textStyle: { textAlign: 'left' }, children: title }), description && (_jsx(Typography, { size: TypographySize.TextXS, weight: TypographyWeight.Regular, color: 'var(--color-text-text-paragraph)', textStyle: { textAlign: 'left' }, children: description }))] })] }), showActionButton && (_jsx(Box, { position: 'absolute', top: '
|
|
34
|
+
boxSizing: 'border-box', sx: { '& svg': { flexShrink: 0 } }, children: getIconComponent(icon, { size: 24, color: iconColor }) }), _jsxs(Box, { display: 'flex', flex: '1 0 0', minWidth: 0, flexDirection: 'column', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-xs)', alignItems: 'flex-start', sx: { wordBreak: 'break-word' }, children: [_jsx(Typography, { size: TypographySize.HeadingS, weight: TypographyWeight.Bold, color: 'var(--color-text-text-title)', textStyle: { textAlign: 'left' }, children: title }), description && (_jsx(Typography, { size: TypographySize.TextXS, weight: TypographyWeight.Regular, color: 'var(--color-text-text-paragraph)', textStyle: { textAlign: 'left' }, children: description }))] })] }), showActionButton && (_jsx(Box, { position: 'absolute', top: '4px', right: '8px', children: _jsx(MainButton, { text: actionButtonText, hierarchy: ButtonHierarchy.TertiaryColor, size: ButtonSize.xxs, style: {
|
|
35
|
+
minHeight: 'unset',
|
|
36
|
+
padding: '0 var(--spacing-tokens-size-in-px-spacing-spacing-xxs)',
|
|
37
|
+
}, onClick: (e) => {
|
|
35
38
|
e.stopPropagation();
|
|
36
39
|
onActionClick?.();
|
|
37
40
|
}, testId: `${cardKey}-action-button` }) }))] }));
|