Skip to content

Commit f45ed91

Browse files
committed
feat: use css for placement
1 parent d3ca214 commit f45ed91

File tree

3 files changed

+54
-20
lines changed

3 files changed

+54
-20
lines changed

packages/css/badge.css

+5-9
Original file line numberDiff line numberDiff line change
@@ -26,32 +26,28 @@
2626
}
2727

2828
.ds-badge--float {
29-
transform-origin: center;
3029
position: absolute;
30+
transform: translate(-50%, -50%);
3131
}
3232

3333
.ds-badge--float.ds-badge--top-right {
3434
top: 0;
35-
right: 0;
36-
transform: translateX(50%) translateY(-50%);
35+
left: 100%;
3736
}
3837

3938
.ds-badge--float.ds-badge--top-left {
4039
top: 0;
4140
left: 0;
42-
transform: translateX(-50%) translateY(-50%);
4341
}
4442

4543
.ds-badge--float.ds-badge--bottom-right {
46-
bottom: 0;
47-
right: 0;
48-
transform: translateX(50%) translateY(50%);
44+
top: 100%;
45+
left: 100%;
4946
}
5047

5148
.ds-badge--float.ds-badge--bottom-left {
52-
bottom: 0;
49+
top: 100%;
5350
left: 0;
54-
transform: translateX(-50%) translateY(50%);
5551
}
5652

5753
.ds-bade--accent {

packages/react/src/components/Badge/Badge.stories.tsx

+23-5
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,13 @@ const meta: Meta<typeof Badge> = {
2424
control: { type: 'select' },
2525
},
2626
placement: {
27-
options: ['top-right', 'top-left', 'bottom-right', 'bottom-left'],
27+
options: [
28+
'right top',
29+
'left top',
30+
'right bottom',
31+
'left bottom',
32+
'10% 90%',
33+
],
2834
control: { type: 'radio' },
2935
},
3036
},
@@ -48,16 +54,28 @@ export const Floating: Story = (args) => (
4854
gap: 'var(--ds-spacing-6)',
4955
}}
5056
>
51-
<Badge color='accent' size='md' placement='top-right'>
57+
<Badge color='accent' size='md' placement='right top'>
5258
<EnvelopeClosedFillIcon fontSize='2rem' />
5359
</Badge>
54-
<Badge color='accent' size='md' placement='top-left'>
60+
<Badge color='accent' size='md' placement='left top'>
5561
<EnvelopeClosedFillIcon fontSize='2rem' />
5662
</Badge>
57-
<Badge color='accent' size='md' placement='bottom-right'>
63+
<Badge color='accent' size='md' placement='right bottom'>
5864
<EnvelopeClosedFillIcon fontSize='2rem' />
5965
</Badge>
60-
<Badge color='accent' size='md' placement='bottom-left'>
66+
<Badge color='accent' size='md' placement='left bottom'>
67+
<EnvelopeClosedFillIcon fontSize='2rem' />
68+
</Badge>
69+
<Badge color='accent' size='md' placement='90% 25%'>
70+
<EnvelopeClosedFillIcon fontSize='2rem' />
71+
</Badge>
72+
<Badge color='accent' size='md' placement='10% 25%'>
73+
<EnvelopeClosedFillIcon fontSize='2rem' />
74+
</Badge>
75+
<Badge color='accent' size='md' placement='.25em 1.5em'>
76+
<EnvelopeClosedFillIcon fontSize='2rem' />
77+
</Badge>
78+
<Badge color='accent' size='md' placement='1.75em 1.5em'>
6179
<EnvelopeClosedFillIcon fontSize='2rem' />
6280
</Badge>
6381
</div>

packages/react/src/components/Badge/Badge.tsx

+26-6
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,12 @@ export type BadgeProps = {
2828
*
2929
* @default top-right
3030
*/
31-
placement?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
31+
placement?:
32+
| 'right top'
33+
| 'left top'
34+
| 'right bottom'
35+
| 'left bottom'
36+
| (CSSStyleDeclaration['backgroundPosition'] & {}); // For better IntelliSense - see https://stackoverflow.com/a/61048124
3237
/**
3338
* The badge will float on top of the children
3439
*/
@@ -61,13 +66,14 @@ const paragraphSizeMap: {
6166
export const Badge = forwardRef<HTMLSpanElement, BadgeProps>(
6267
(
6368
{
69+
children,
70+
className,
6471
color = 'accent',
65-
size = 'md',
66-
placement = 'top-right',
6772
count,
6873
maxCount,
69-
children,
70-
className,
74+
placement = 'top right',
75+
size = 'md',
76+
style,
7177
...rest
7278
},
7379
ref,
@@ -82,9 +88,11 @@ export const Badge = forwardRef<HTMLSpanElement, BadgeProps>(
8288
`ds-badge--${size}`,
8389
`ds-badge--${color}`,
8490
count && 'ds-badge--count',
85-
children && `ds-badge--${placement}`,
8691
children && 'ds-badge--float',
8792
)}
93+
style={
94+
children ? { ...parsePlacement(placement), ...style } : style
95+
}
8896
ref={ref}
8997
{...rest}
9098
>
@@ -97,3 +105,15 @@ export const Badge = forwardRef<HTMLSpanElement, BadgeProps>(
97105
);
98106

99107
Badge.displayName = 'Badge';
108+
109+
function parsePlacement(placement: BadgeProps['placement']) {
110+
const parts = placement?.toLowerCase().split(/[\s-]+/) || [];
111+
let [left = '100%', top = '0%'] = parts;
112+
113+
if (parts.includes('bottom')) top = '100%';
114+
if (parts.includes('left')) left = '0%';
115+
if (parts.includes('right')) left = '100%';
116+
if (parts.includes('top')) top = '0%';
117+
118+
return { left, top };
119+
}

0 commit comments

Comments
 (0)