Skip to content

Commit e8b7e14

Browse files
committed
feat(ItemBadge): add component
1 parent b78ff54 commit e8b7e14

File tree

11 files changed

+401
-46
lines changed

11 files changed

+401
-46
lines changed

src/components/Item.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { ReactElement } from 'react';
22
import { Item, ItemProps } from 'react-stately';
33

44
import { ItemAction } from './actions/ItemAction';
5+
import { ItemBadge } from './content/ItemBadge';
56
import { CubeItemBaseProps } from './content/ItemBase/ItemBase';
67

78
export interface CubeItemProps<T>
@@ -16,6 +17,7 @@ const _Item = Object.assign(
1617
Item as <T>(props: CubeItemProps<T>) => ReactElement,
1718
{
1819
Action: ItemAction,
20+
Badge: ItemBadge,
1921
},
2022
);
2123

src/components/actions/ItemAction/ItemAction.tsx

Lines changed: 2 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
DEFAULT_NEUTRAL_STYLES,
1818
DEFAULT_PRIMARY_STYLES,
1919
DEFAULT_SECONDARY_STYLES,
20+
ITEM_ACTION_BASE_STYLES,
2021
SPECIAL_CLEAR_STYLES,
2122
SPECIAL_NEUTRAL_STYLES,
2223
SPECIAL_PRIMARY_STYLES,
@@ -70,56 +71,11 @@ type ItemActionVariant =
7071
const ItemActionElement = tasty({
7172
qa: 'ItemAction',
7273
styles: {
73-
display: 'inline-grid',
74-
flow: 'column',
75-
placeItems: 'center',
76-
placeContent: 'center',
77-
gap: '.75x',
78-
position: 'relative',
79-
margin: {
80-
'': '0 1bw 0 1bw',
81-
':last-child & !:first-child': '0 $side-padding 0 0',
82-
'!:last-child & :first-child': '0 0 0 $side-padding',
83-
':last-child & :first-child': '0 $side-padding',
84-
context: '0',
85-
},
86-
padding: 0,
74+
...ITEM_ACTION_BASE_STYLES,
8775
reset: 'button',
8876
outline: 0,
8977
outlineOffset: 1,
9078
cursor: { '': 'pointer', disabled: 'default' },
91-
radius: true,
92-
transition: 'theme',
93-
flexShrink: 0,
94-
textDecoration: 'none',
95-
boxSizing: 'border-box',
96-
whiteSpace: 'nowrap',
97-
border: 0,
98-
height: '$action-size',
99-
width: {
100-
'': '$action-size',
101-
'with-label': 'auto',
102-
},
103-
placeSelf: 'center',
104-
105-
// Size using custom property
106-
'$action-size': 'min(max((2x + 2bw), ($size - 1x - 2bw)), (3x - 2bw))',
107-
// Side padding for the button
108-
'$side-padding': 'max(min(.5x, (($size - 3x + 2bw) / 2)), 1bw)',
109-
110-
// Icon styles
111-
Icon: {
112-
display: 'grid',
113-
placeItems: 'center',
114-
aspectRatio: '1 / 1',
115-
width: '$action-size',
116-
opacity: {
117-
'': 1,
118-
'checkbox & selected': 1,
119-
'checkbox & !selected': 0,
120-
'checkbox & !selected & hovered': 0.4,
121-
},
122-
},
12379
},
12480
variants: {
12581
// Default theme

src/components/actions/ItemButton/ItemButton.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { useHover } from 'react-aria';
1212

1313
import { Styles, tasty } from '../../../tasty';
1414
import { mergeProps } from '../../../utils/react';
15+
import { ItemBadge } from '../../content/ItemBadge';
1516
import { CubeItemBaseProps, ItemBase } from '../../content/ItemBase';
1617
import { DisplayTransition } from '../../helpers';
1718
import { CubeItemActionProps, ItemAction } from '../ItemAction';
@@ -209,6 +210,7 @@ const ItemButton = forwardRef(function ItemButton(
209210

210211
const _ItemButton = Object.assign(ItemButton, {
211212
Action: ItemAction,
213+
Badge: ItemBadge,
212214
});
213215

214216
export { _ItemButton as ItemButton };
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import { Meta, StoryObj } from '@storybook/react-vite';
2+
3+
import { CheckIcon } from '../../../icons/CheckIcon';
4+
import { KeyIcon } from '../../../icons/KeyIcon';
5+
import { ItemBase } from '../ItemBase';
6+
7+
import { ItemBadge } from './ItemBadge';
8+
9+
const meta: Meta<typeof ItemBadge> = {
10+
title: 'Content/ItemBadge',
11+
component: ItemBadge,
12+
tags: ['autodocs'],
13+
parameters: {
14+
layout: 'centered',
15+
},
16+
};
17+
18+
export default meta;
19+
type Story = StoryObj<typeof ItemBadge>;
20+
21+
export const Default: Story = {
22+
args: {
23+
icon: <KeyIcon />,
24+
tooltip: 'Information',
25+
},
26+
};
27+
28+
export const WithLabel: Story = {
29+
args: {
30+
icon: <CheckIcon />,
31+
children: 'Success',
32+
},
33+
};
34+
35+
export const Types: Story = {
36+
render: () => (
37+
<div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>
38+
<ItemBadge icon={<KeyIcon />} type="primary" tooltip="Primary" />
39+
<ItemBadge icon={<KeyIcon />} type="secondary" tooltip="Secondary" />
40+
<ItemBadge icon={<KeyIcon />} type="neutral" tooltip="Neutral" />
41+
<ItemBadge icon={<KeyIcon />} type="clear" tooltip="Clear" />
42+
</div>
43+
),
44+
};
45+
46+
export const Themes: Story = {
47+
render: () => (
48+
<div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>
49+
<ItemBadge icon={<KeyIcon />} theme="default" tooltip="Default" />
50+
<ItemBadge icon={<KeyIcon />} theme="danger" tooltip="Danger" />
51+
<ItemBadge icon={<KeyIcon />} theme="success" tooltip="Success" />
52+
<ItemBadge icon={<KeyIcon />} theme="special" tooltip="Special" />
53+
</div>
54+
),
55+
};
56+
57+
export const Loading: Story = {
58+
args: {
59+
icon: <KeyIcon />,
60+
isLoading: true,
61+
tooltip: 'Loading...',
62+
},
63+
};
64+
65+
export const Selected: Story = {
66+
args: {
67+
icon: 'checkbox',
68+
isSelected: true,
69+
tooltip: 'Selected',
70+
},
71+
};
72+
73+
export const WithItemBase: Story = {
74+
render: () => (
75+
<ItemBase
76+
size="large"
77+
actions={
78+
<>
79+
<ItemBase.Badge icon={<KeyIcon />} tooltip="Primary" />
80+
<ItemBase.Badge
81+
icon={<CheckIcon />}
82+
theme="success"
83+
tooltip="Success"
84+
/>
85+
</>
86+
}
87+
>
88+
Item with badges
89+
</ItemBase>
90+
),
91+
};
92+
93+
export const InContext: Story = {
94+
render: () => (
95+
<ItemBase
96+
size="large"
97+
type="primary"
98+
theme="success"
99+
actions={
100+
<>
101+
<ItemBase.Badge icon={<CheckIcon />} tooltip="Verified" />
102+
<ItemBase.Badge icon={<KeyIcon />} tooltip="Primary" />
103+
</>
104+
}
105+
>
106+
Item with badges in context
107+
</ItemBase>
108+
),
109+
};

0 commit comments

Comments
 (0)