@beydesign/storybook 0.2.13 → 0.2.15
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.
|
@@ -220,7 +220,7 @@ const StyledButton = styled.button `
|
|
|
220
220
|
var(--global-shadows-shadow-xs-color);
|
|
221
221
|
}
|
|
222
222
|
`;
|
|
223
|
-
export const MainButton = ({ onClick, text, disabled = false, loading = false, type = ButtonType.Button, style, size = ButtonSize.xl, hierarchy = ButtonHierarchy.Primary, displayIcon, displayIconMode = ButtonDisplayMode.Default, state = ButtonState.Default, shape = ButtonShape.Square, destructive = false, showLeadingIcon = false, showTrailingIcon = false, leadingIcon = 'Circle', trailingIcon = 'Circle', testId, }) => {
|
|
223
|
+
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', testId, }) => {
|
|
224
224
|
const getIconSize = () => {
|
|
225
225
|
const sizes = {
|
|
226
226
|
[ButtonSize.xl]: 24,
|
|
@@ -282,7 +282,7 @@ export const MainButton = ({ onClick, text, disabled = false, loading = false, t
|
|
|
282
282
|
const iconProps = {
|
|
283
283
|
size: getIconSize(),
|
|
284
284
|
color: disabled ? 'var(--color-text-text-disabled)' : 'currentColor',
|
|
285
|
-
weight:
|
|
285
|
+
weight: iconWeight,
|
|
286
286
|
};
|
|
287
287
|
const sizeStyles = getButtonSize();
|
|
288
288
|
const renderContent = () => {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CSSProperties } from 'react';
|
|
2
|
+
import type { IconWeight } from '@phosphor-icons/react';
|
|
2
3
|
import { IconName } from '../../utils';
|
|
3
4
|
import { SxProps } from '@mui/material';
|
|
4
5
|
import { Theme } from '@mui/material';
|
|
@@ -86,6 +87,8 @@ export interface MainButtonProps {
|
|
|
86
87
|
hierarchy?: ButtonHierarchy;
|
|
87
88
|
/** Icon to display when in icon mode */
|
|
88
89
|
displayIcon?: IconName;
|
|
90
|
+
/** Weight of the rendered icons (defaults to `regular`) */
|
|
91
|
+
iconWeight?: IconWeight;
|
|
89
92
|
/** How to display the icon */
|
|
90
93
|
displayIconMode?: ButtonDisplayMode;
|
|
91
94
|
/** Current state of the button */
|
|
@@ -17,12 +17,13 @@ export const EntityCard = ({ view = 'avatar', name, image, description = '', sho
|
|
|
17
17
|
const showBadge = showStatusBadge && !!statusBadgeText;
|
|
18
18
|
return (_jsxs(Box, { width: cardWidth, display: 'flex', flexDirection: 'column', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', padding: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', borderRadius: 'var(--spacing-tokens-size-in-px-spacing-spacing-sm)', bgcolor: hovered
|
|
19
19
|
? 'var(--color-background-bg-card-highlight-hover)'
|
|
20
|
-
: 'var(--color-background-bg-card-highlight)', border: '1px solid var(--color-border-border-subtle)', boxSizing: 'border-box', overflow: 'hidden', onMouseEnter: () => setHovered(true), onMouseLeave: () => setHovered(false), sx: { transition: 'background-color 0.15s ease-in-out' }, "data-testid": `${entityKey}-entity-card`, children: [_jsxs(Box, { position: 'relative', width: '100%', borderRadius: 'var(--spacing-tokens-size-in-px-spacing-spacing-sm)', overflow: 'hidden', sx: { aspectRatio: imageAspectRatio }, children: [image && !imageError ? (_jsx("img", { src: image, alt: name, width: '100%', height: '100%', style: { objectFit: 'cover', height: '100%', width: '100%' }, onError: () => setImageError(true) })) : (_jsx(Box, { width: '100%', height: '100%', bgcolor: 'var(--color-background-bg-element)', display: 'flex', justifyContent: 'center', alignItems: 'center', children: _jsx(UserCircle, { size: 74, weight: 'thin', color: 'var(--color-text-text-subtle)' }) })), _jsx(Box, { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0,
|
|
20
|
+
: 'var(--color-background-bg-card-highlight)', border: '1px solid var(--color-border-border-subtle)', boxSizing: 'border-box', overflow: 'hidden', onMouseEnter: () => setHovered(true), onMouseLeave: () => setHovered(false), sx: { transition: 'background-color 0.15s ease-in-out' }, "data-testid": `${entityKey}-entity-card`, children: [_jsxs(Box, { position: 'relative', width: '100%', borderRadius: 'var(--spacing-tokens-size-in-px-spacing-spacing-sm)', overflow: 'hidden', sx: { aspectRatio: imageAspectRatio }, children: [image && !imageError ? (_jsx("img", { src: image, alt: name, width: '100%', height: '100%', style: { objectFit: 'cover', height: '100%', width: '100%' }, onError: () => setImageError(true) })) : (_jsx(Box, { width: '100%', height: '100%', bgcolor: 'var(--color-background-bg-element)', display: 'flex', justifyContent: 'center', alignItems: 'center', children: _jsx(UserCircle, { size: 74, weight: 'thin', color: 'var(--color-text-text-subtle)' }) })), _jsx(Box, { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, borderRadius: 'var(--spacing-tokens-size-in-px-spacing-spacing-sm)', sx: {
|
|
21
|
+
backgroundImage: 'linear-gradient(180deg, rgba(21, 0, 73, 0) 0%, rgba(72, 29, 180, 0.152) 16.76%, rgba(32, 13, 82, 0.36) 100%)',
|
|
21
22
|
opacity: hovered ? 1 : 0,
|
|
22
23
|
transition: 'opacity 0.15s ease-in-out',
|
|
23
24
|
pointerEvents: 'none',
|
|
24
25
|
} }), _jsx(Box, { position: 'absolute', left: 0, right: 0, bottom: 0, display: 'flex', alignItems: 'center', 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: {
|
|
25
26
|
backgroundImage: 'linear-gradient(rgba(45, 38, 55, 0) 0%, rgba(45, 38, 55, 0.16) 34%, rgba(45, 38, 55, 0.64) 100%)',
|
|
26
27
|
}, children: _jsx(Typography, { size: TypographySize.HeadingXS, weight: TypographyWeight.SemiBold, color: 'var(--color-text-text-white)', textStyle: { wordBreak: 'break-word' }, children: name }) }), showBadge && (_jsx(Box, { position: 'absolute', top: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', left: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', sx: { zIndex: 2 }, children: _jsx(Badge, { text: statusBadgeText, color: statusBadgeColor, size: BadgeSize.md, showIcon: true, icon: 'Circle', iconWeight: 'fill', iconSize: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', iconColor: 'var(--color-foreground-fg-accent-success)' }) })), showActions && (_jsxs(Box, { position: 'absolute', top: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', right: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', display: 'flex', flexDirection: 'row', alignItems: 'center', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', sx: { zIndex: 2 }, children: [onPreview &&
|
|
27
|
-
(previewButtonText ? (_jsx(MainButton, { text: previewButtonText, showLeadingIcon: true, leadingIcon: previewIcon, hierarchy: ButtonHierarchy.
|
|
28
|
+
(previewButtonText ? (_jsx(MainButton, { text: previewButtonText, showLeadingIcon: true, leadingIcon: previewIcon, iconWeight: 'fill', hierarchy: ButtonHierarchy.SecondaryTransparent, size: ButtonSize.sm, onClick: onPreview, testId: `${entityKey}-preview-button` })) : (_jsx(MainButton, { displayIcon: previewIcon, displayIconMode: ButtonDisplayMode.Only, hierarchy: ButtonHierarchy.SecondaryTransparent, size: ButtonSize.sm, onClick: onPreview, testId: `${entityKey}-preview-button` }))), hasMenu && (_jsx(Menu, { items: menuItems, testKey: entityKey, size: ButtonSize.sm }))] }))] }), showDescription && description && (_jsx(Box, { display: 'flex', alignItems: 'center', padding: '0 var(--spacing-tokens-size-in-px-spacing-spacing-lg)', width: '100%', boxSizing: 'border-box', children: _jsx(Typography, { size: TypographySize.TextS, weight: TypographyWeight.Regular, color: 'var(--color-text-text-label)', textStyle: { wordBreak: 'break-word' }, children: description }) }))] }));
|
|
28
29
|
};
|
package/dist/stories/UI/Menu.js
CHANGED
|
@@ -4,7 +4,7 @@ import { Fragment, useState } from 'react';
|
|
|
4
4
|
import { MainButton, ButtonDisplayMode, ButtonHierarchy, ButtonType, ButtonSize, } from '../Buttons';
|
|
5
5
|
import { Typography, TypographySize, TypographyWeight } from '../Typography';
|
|
6
6
|
import { getIconComponent } from '../../utils';
|
|
7
|
-
export const Menu = ({ icon = '
|
|
7
|
+
export const Menu = ({ icon = 'DotsThreeOutline', iconWeight = 'bold', items, style, testKey, size = ButtonSize.xl, hierarchy = ButtonHierarchy.Tertiary, }) => {
|
|
8
8
|
const [anchorEl, setAnchorEl] = useState(null);
|
|
9
9
|
const open = Boolean(anchorEl);
|
|
10
10
|
const handleClick = (event) => {
|
|
@@ -24,7 +24,14 @@ export const Menu = ({ icon = 'DotsThree', items, style, testKey, size = ButtonS
|
|
|
24
24
|
return 'var(--color-text-text-error)';
|
|
25
25
|
return 'var(--color-text-text-title)';
|
|
26
26
|
};
|
|
27
|
-
return (_jsxs(Fragment, { children: [_jsx(MainButton, { displayIcon: icon, onClick: handleClick, type: ButtonType.Button, displayIconMode: ButtonDisplayMode.Only, hierarchy: hierarchy, size: size, style:
|
|
27
|
+
return (_jsxs(Fragment, { children: [_jsx(MainButton, { displayIcon: icon, iconWeight: iconWeight, onClick: handleClick, type: ButtonType.Button, displayIconMode: ButtonDisplayMode.Only, hierarchy: hierarchy, size: size, style: {
|
|
28
|
+
// The menu trigger sits on top of media (cards, images), so it uses a
|
|
29
|
+
// theme-aware translucent overlay (white 30% in light, black 30% in
|
|
30
|
+
// dark) with no shadow. Consumer `style` can still override.
|
|
31
|
+
background: 'var(--color-background-bg-button-overlay)',
|
|
32
|
+
boxShadow: 'none',
|
|
33
|
+
...style,
|
|
34
|
+
}, testId: `${testKey}-menu-button` }), _jsx(MuiMenu, { id: "basic-menu", "data-testid": `${testKey}-menu`, anchorEl: anchorEl, open: open, onClose: handleClose, MenuListProps: {
|
|
28
35
|
'aria-labelledby': 'basic-button',
|
|
29
36
|
style: {
|
|
30
37
|
padding: 'var(--spacing-tokens-size-in-px-spacing-spacing-xs)',
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
2
|
import { Menu } from './Menu';
|
|
2
3
|
import { ButtonSize, ButtonHierarchy } from '../Buttons';
|
|
4
|
+
// The Menu trigger uses a theme-aware translucent overlay background
|
|
5
|
+
// (`bg-button-overlay`), so it's designed to sit on top of media. This backdrop
|
|
6
|
+
// mirrors how it appears on cards (EntityCard / AgentCard) — without it, the
|
|
7
|
+
// overlay reads as a faint box against the plain page.
|
|
8
|
+
const mediaBackdrop = 'https://images.unsplash.com/photo-1494790108377-be9c29b29330?fm=jpg&q=60&w=600&ixlib=rb-4.0.3';
|
|
3
9
|
const meta = {
|
|
4
10
|
title: 'Design System/Components/UI/Menu',
|
|
5
11
|
component: Menu,
|
|
@@ -7,16 +13,38 @@ const meta = {
|
|
|
7
13
|
layout: 'centered',
|
|
8
14
|
},
|
|
9
15
|
tags: ['autodocs'],
|
|
16
|
+
decorators: [
|
|
17
|
+
(Story) => (_jsx("div", { style: {
|
|
18
|
+
width: 240,
|
|
19
|
+
height: 160,
|
|
20
|
+
borderRadius: 8,
|
|
21
|
+
overflow: 'hidden',
|
|
22
|
+
backgroundImage: `url(${mediaBackdrop})`,
|
|
23
|
+
backgroundSize: 'cover',
|
|
24
|
+
backgroundPosition: 'center',
|
|
25
|
+
display: 'flex',
|
|
26
|
+
alignItems: 'flex-start',
|
|
27
|
+
justifyContent: 'flex-end',
|
|
28
|
+
padding: 8,
|
|
29
|
+
}, children: _jsx(Story, {}) })),
|
|
30
|
+
],
|
|
10
31
|
argTypes: {
|
|
11
32
|
icon: {
|
|
12
33
|
control: 'select',
|
|
13
|
-
options: ['DotsThree', 'Pencil', 'Trash'],
|
|
14
|
-
|
|
15
|
-
description: 'The icon to display in the menu',
|
|
34
|
+
options: ['DotsThreeOutline', 'DotsThree', 'Pencil', 'Trash'],
|
|
35
|
+
description: 'The icon to display in the menu trigger',
|
|
16
36
|
table: {
|
|
17
|
-
type: {
|
|
18
|
-
|
|
19
|
-
|
|
37
|
+
type: { summary: 'IconName' },
|
|
38
|
+
defaultValue: { summary: 'DotsThreeOutline' },
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
iconWeight: {
|
|
42
|
+
control: 'select',
|
|
43
|
+
options: ['thin', 'light', 'regular', 'bold', 'fill', 'duotone'],
|
|
44
|
+
description: 'Weight of the trigger icon',
|
|
45
|
+
table: {
|
|
46
|
+
type: { summary: 'IconWeight' },
|
|
47
|
+
defaultValue: { summary: 'bold' },
|
|
20
48
|
},
|
|
21
49
|
},
|
|
22
50
|
items: {
|
|
@@ -50,7 +78,7 @@ const meta = {
|
|
|
50
78
|
description: 'Hierarchy of the trigger button',
|
|
51
79
|
table: {
|
|
52
80
|
type: { summary: 'ButtonHierarchy' },
|
|
53
|
-
defaultValue: { summary: ButtonHierarchy.
|
|
81
|
+
defaultValue: { summary: ButtonHierarchy.Tertiary },
|
|
54
82
|
},
|
|
55
83
|
},
|
|
56
84
|
},
|
|
@@ -58,7 +86,6 @@ const meta = {
|
|
|
58
86
|
export default meta;
|
|
59
87
|
export const Default = {
|
|
60
88
|
args: {
|
|
61
|
-
icon: 'DotsThree',
|
|
62
89
|
items: [
|
|
63
90
|
{ label: 'Edit', onClick: () => { }, destructive: false, icon: 'Pencil' },
|
|
64
91
|
{ label: 'Delete', onClick: () => { }, destructive: true, icon: 'Trash' },
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Theme, SxProps, TooltipProps } from '@mui/material';
|
|
2
2
|
import { ReactElement, ReactNode } from 'react';
|
|
3
|
+
import type { IconWeight } from '@phosphor-icons/react';
|
|
3
4
|
import { IconName } from '../../utils';
|
|
4
5
|
import { ButtonSize, ButtonHierarchy } from '../Buttons';
|
|
5
6
|
/**
|
|
@@ -200,6 +201,8 @@ export interface MenuItemProps {
|
|
|
200
201
|
export type MenuProps = {
|
|
201
202
|
/** Icon */
|
|
202
203
|
icon?: IconName;
|
|
204
|
+
/** Weight of the trigger icon (defaults to `bold`) */
|
|
205
|
+
iconWeight?: IconWeight;
|
|
203
206
|
/** Items */
|
|
204
207
|
items?: MenuItemProps[];
|
|
205
208
|
/** Style */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@beydesign/storybook",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.15",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.js",
|
|
@@ -35,10 +35,12 @@
|
|
|
35
35
|
"@mui/icons-material": "^5.18.0",
|
|
36
36
|
"@mui/material": "^5.18.0",
|
|
37
37
|
"@phosphor-icons/react": "^2.1.10",
|
|
38
|
-
"react": "^18.3.1",
|
|
39
|
-
"react-dom": "^18.3.1",
|
|
40
38
|
"typescript": "~5.9.3"
|
|
41
39
|
},
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"react": "^18.3.1 || ^19.0.0",
|
|
42
|
+
"react-dom": "^18.3.1 || ^19.0.0"
|
|
43
|
+
},
|
|
42
44
|
"devDependencies": {
|
|
43
45
|
"@chromatic-com/storybook": "^3.2.7",
|
|
44
46
|
"@storybook/addon-designs": "^8.2.1",
|
|
@@ -66,6 +68,8 @@
|
|
|
66
68
|
"eslint-plugin-storybook": "^0.11.6",
|
|
67
69
|
"postcss": "^8.5.8",
|
|
68
70
|
"prettier": "^3.8.1",
|
|
71
|
+
"react": "^18.3.1",
|
|
72
|
+
"react-dom": "^18.3.1",
|
|
69
73
|
"storybook": "^8.6.17",
|
|
70
74
|
"typescript-eslint": "^7.18.0",
|
|
71
75
|
"vite": "^5.4.21"
|