Skip to content

Commit 410c21a

Browse files
authored
Implement css var related util functions (#1736)
<!-- How to write a good PR title: - Follow [the Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/). - Give as much context as necessary and as little as possible - Prefix it with [WIP] while it’s a work in progress --> ## Self Checklist - [x] I wrote a PR title in **English** and added an appropriate **label** to the PR. - [x] I wrote the commit message in **English** and to follow [**the Conventional Commits specification**](https://www.conventionalcommits.org/en/v1.0.0/). - [x] I [added the **changeset**](https://github.com/changesets/changesets/blob/main/docs/adding-a-changeset.md) about the changes that needed to be released. (or didn't have to) - [x] I wrote or updated **documentation** related to the changes. (or didn't have to) - [x] I wrote or updated **tests** related to the changes. (or didn't have to) - [x] I tested the changes in various browsers. (or didn't have to) - Windows: Chrome, Edge, (Optional) Firefox - macOS: Chrome, Edge, Safari, (Optional) Firefox ## Summary <!-- Please brief explanation of the changes made --> CSS variable과 관련된 유틸 함수를 개선 & 추가 구현합니다. ## Details <!-- Please elaborate description of the changes --> 중복 제거 & 일관적인 컨벤션을 위한 유틸 함수들을 구현했습니다. - 인라인 스타일로 주입하는 CSS Variable의 네이밍 컨벤션을 위한 함수 - 그 외: `px` unit을 붙이는 조건 체크 없이 쉽게 사용할 수 있도록 하는 함수 ### Breaking change? (Yes/No) <!-- If Yes, please describe the impact and migration path for users --> No
1 parent 0f5801b commit 410c21a

File tree

15 files changed

+145
-68
lines changed

15 files changed

+145
-68
lines changed

packages/bezier-react/src/components/AlphaSmoothCornersBox/AlphaSmoothCornersBox.tsx

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,17 @@ import {
99
} from '~/src/features'
1010
import {
1111
cssUrl,
12-
cssVar,
12+
cssVarName,
13+
cssVarValue,
14+
px,
1315
} from '~/src/utils/styleUtils'
1416

1517
import { type AlphaSmoothCornersBoxProps } from './AlphaSmoothCornersBox.types'
1618

1719
import * as Styled from './AlphaSmoothCornersBox.styled'
1820

21+
const cv = cssVarName('alpha-smooth-corners-box')
22+
1923
/**
2024
* `AlphaSmoothCornersBox` is a simple `div` element with smooth corners.
2125
* It is available by enabling the `SmoothCornersFeature`.
@@ -46,21 +50,21 @@ export const AlphaSmoothCornersBox = forwardRef<HTMLElement, AlphaSmoothCornersB
4650

4751
const style = useMemo(() => ({
4852
...styleProp,
49-
'--bezier-alpha-smooth-corners-box-border-radius': borderRadius,
50-
'--bezier-alpha-smooth-corners-box-border-radius-type': typeof borderRadius,
51-
'--bezier-alpha-smooth-corners-box-shadow-offset-x': shadow?.offsetX,
52-
'--bezier-alpha-smooth-corners-box-shadow-offset-y': shadow?.offsetY,
53-
'--bezier-alpha-smooth-corners-box-shadow-blur-radius': `${shadow?.blurRadius ?? 0}px`,
54-
'--bezier-alpha-smooth-corners-box-shadow-spread-radius': `${shadowSpreadRadius}px`,
55-
'--bezier-alpha-smooth-corners-box-shadow-color': cssVar(shadow?.color),
53+
[cv('border-radius')]: borderRadius,
54+
[cv('border-radius-type')]: typeof borderRadius,
55+
[cv('shadow-offset-x')]: shadow?.offsetX,
56+
[cv('shadow-offset-y')]: shadow?.offsetY,
57+
[cv('shadow-blur-radius')]: px(shadow?.blurRadius ?? 0),
58+
[cv('shadow-spread-radius')]: px(shadowSpreadRadius),
59+
[cv('shadow-color')]: cssVarValue(shadow?.color),
5660
/**
5761
* NOTE: Calculate in javascript because it cannot access calculated values via CSS calc() in the paint worklet.
5862
* @see {@link ~/src/features/SmoothCorners/smoothCornersScript.ts}
5963
*/
60-
'--bezier-alpha-smooth-corners-box-padding': `${shadowSpreadRadius * 2}px`,
61-
'--bezier-alpha-smooth-corners-box-margin': `${margin ?? 0}px`,
62-
'--bezier-alpha-smooth-corners-box-background-color': cssVar(backgroundColor),
63-
'--bezier-alpha-smooth-corners-box-background-image': cssUrl(backgroundImage),
64+
[cv('padding')]: px(shadowSpreadRadius * 2),
65+
[cv('margin')]: px(margin ?? 0),
66+
[cv('background-color')]: cssVarValue(backgroundColor),
67+
[cv('background-image')]: cssUrl(backgroundImage),
6468
}), [
6569
styleProp,
6670
borderRadius,

packages/bezier-react/src/components/AlphaStack/AlphaStack.tsx

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,19 @@ import React, {
44
useMemo,
55
} from 'react'
66

7+
import {
8+
cssVarName,
9+
px,
10+
} from '~/src/utils/styleUtils'
11+
712
import { flex } from '~/src/components/Stack/util'
813

914
import type { AlphaStackProps } from './AlphaStack.types'
1015

1116
import * as Styled from './AlphaStack.styled'
1217

18+
const cv = cssVarName('alpha-stack')
19+
1320
/**
1421
* `AlphaStack` provides an abstraction of **flex layout** so that
1522
* rendering of child elements **linearly** can be done
@@ -46,10 +53,10 @@ export const AlphaStack = forwardRef(function AlphaStack(
4653
) {
4754
const stackStyle = useMemo(() => ({
4855
...style,
49-
'--bezier-alpha-stack-direction': direction === 'horizontal' ? 'row' : 'column',
50-
'--bezier-alpha-stack-justify': flex(justify),
51-
'--bezier-alpha-stack-align': flex(align),
52-
'--bezier-alpha-stack-spacing': `${spacing}px`,
56+
[cv('direction')]: direction === 'horizontal' ? 'row' : 'column',
57+
[cv('justify')]: flex(justify),
58+
[cv('align')]: flex(align),
59+
[cv('spacing')]: px(spacing),
5360
} as React.CSSProperties),
5461
[
5562
align,

packages/bezier-react/src/components/Avatars/Avatar/Avatar.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ import React, {
55

66
import classNames from 'classnames'
77

8+
import {
9+
cssVarName,
10+
px,
11+
} from '~/src/utils/styleUtils'
812
import { isEmpty } from '~/src/utils/typeUtils'
913

1014
import { type BoxShadow } from '~/src/components/AlphaSmoothCornersBox'
@@ -24,6 +28,8 @@ import useProgressiveImage from './useProgressiveImage'
2428

2529
import * as Styled from './Avatar.styled'
2630

31+
const cv = cssVarName('avatar')
32+
2733
const shadow: BoxShadow = {
2834
spreadRadius: 2,
2935
color: 'bg-white-high',
@@ -90,7 +96,7 @@ export const Avatar = forwardRef(function Avatar({
9096
)
9197

9298
const avatarStyle = useMemo(() => ({
93-
'--bezier-avatar-status-gap': `${size >= AvatarSize.Size72 ? 4 : -2}px`,
99+
[cv('status-gap')]: px(size >= AvatarSize.Size72 ? 4 : -2),
94100
} as React.CSSProperties), [size])
95101

96102
return (

packages/bezier-react/src/components/Avatars/AvatarGroup/AvatarGroup.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ import { Typography } from '~/src/foundation'
1010

1111
import { isLastIndex } from '~/src/utils/arrayUtils'
1212
import { noop } from '~/src/utils/functionUtils'
13+
import {
14+
cssVarName,
15+
px,
16+
} from '~/src/utils/styleUtils'
1317

1418
import {
1519
type AvatarProps,
@@ -31,6 +35,8 @@ import {
3135

3236
import * as Styled from './AvatarGroup.styled'
3337

38+
const cv = cssVarName('avatar-group')
39+
3440
const MAX_AVATAR_LIST_COUNT = 99
3541

3642
export const AVATAR_GROUP_ELLIPSIS_ICON_TEST_ID = 'bezier-react-avatar-group-ellipsis-icon'
@@ -163,8 +169,8 @@ forwardedRef: React.Ref<HTMLDivElement>,
163169
{ AvatarElement }
164170
<Styled.AvatarEllipsisCountWrapper
165171
style={{
166-
'--bezier-avatar-group-ellipsis-mr': `${getProperEllipsisCountMarginRight(size)}px`,
167-
'--bezier-avatar-group-ellipsis-ml': `${Math.max(spacing, AVATAR_GROUP_DEFAULT_SPACING)}px`,
172+
[cv('ellipsis-mr')]: px(getProperEllipsisCountMarginRight(size)),
173+
[cv('ellipsis-ml')]: px(Math.max(spacing, AVATAR_GROUP_DEFAULT_SPACING)),
168174
} as React.CSSProperties}
169175
onMouseEnter={onMouseEnterEllipsis}
170176
onMouseLeave={onMouseLeaveEllipsis}
@@ -203,8 +209,8 @@ forwardedRef: React.Ref<HTMLDivElement>,
203209
className={className}
204210
style={{
205211
...style,
206-
'--bezier-avatar-group-spacing': `${spacing}px`,
207-
'--bezier-avatar-group-size': `${size}px`,
212+
[cv('spacing')]: px(spacing),
213+
[cv('size')]: px(size),
208214
} as React.CSSProperties}
209215
{...rest}
210216
>

packages/bezier-react/src/components/Forms/Checkbox/Checkbox.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ import {
77
import * as CheckboxPrimitive from '@radix-ui/react-checkbox'
88

99
import useId from '~/src/hooks/useId'
10+
import {
11+
cssVarName,
12+
px,
13+
} from '~/src/utils/styleUtils'
1014

1115
import { FormFieldSize } from '~/src/components/Forms'
1216
import useFormFieldProps from '~/src/components/Forms/useFormFieldProps'
@@ -19,6 +23,8 @@ import {
1923

2024
import * as Styled from './Checkbox.styled'
2125

26+
const cv = cssVarName('checkbox')
27+
2228
type CheckIconProps = {} | {
2329
style: React.CSSProperties
2430
'data-state': 'checked' | 'unchecked' | 'indeterminate'
@@ -61,7 +67,7 @@ function CheckboxImpl<Checked extends CheckedState>({
6167
const id = useId(idProp ?? formFieldId, 'bezier-checkbox')
6268

6369
const containerStyle = {
64-
'--bezier-checkbox-height': children ? `${FormFieldSize.M}px` : 'auto',
70+
[cv('height')]: children ? px(FormFieldSize.M) : 'auto',
6571
} as React.CSSProperties
6672

6773
return (

packages/bezier-react/src/components/Forms/FormControl/FormControl.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ import {
1212
omitBezierComponentProps,
1313
pickBezierComponentProps,
1414
} from '~/src/utils/propsUtils'
15+
import {
16+
cssVarName,
17+
px,
18+
} from '~/src/utils/styleUtils'
1519
import { isNil } from '~/src/utils/typeUtils'
1620

1721
import { AlphaStack } from '~/src/components/AlphaStack'
@@ -32,6 +36,8 @@ import { FormControlContextProvider } from './FormControlContext'
3236

3337
import * as Styled from './FormControl.styled'
3438

39+
const cv = cssVarName('form-control')
40+
3541
export const FORM_CONTROL_TEST_ID = 'bezier-react-form-control'
3642

3743
const Container = forwardRef<HTMLElement, ContainerProps>(function Container({
@@ -194,7 +200,7 @@ export const FormControl = forwardRef<HTMLElement, FormControlProps>(function Fo
194200

195201
const containerStyle = useMemo(() => ({
196202
...style,
197-
'--bezier-form-control-left-label-wrapper-height': `${leftLabelWrapperHeight}px`,
203+
[cv('left-label-wrapper-height')]: px(leftLabelWrapperHeight),
198204
} as React.CSSProperties), [
199205
style,
200206
leftLabelWrapperHeight,

packages/bezier-react/src/components/Forms/SegmentedControl/SegmentedControl.styled.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,22 @@ export const paddingBySegmentedControlSize = {
2929
}
3030

3131
export const Indicator = styled.div`
32-
--bezier-react-segmented-control-indicator-translateX: none;
33-
--bezier-react-segmented-control-indicator-left: auto;
34-
--bezier-react-segmented-control-indicator-width: auto;
35-
--bezier-react-segmented-control-indicator-height: auto;
32+
--bezier-segmented-control-indicator-translateX: none;
33+
--bezier-segmented-control-indicator-left: auto;
34+
--bezier-segmented-control-indicator-width: auto;
35+
--bezier-segmented-control-indicator-height: auto;
3636
3737
position: absolute;
3838
top: 50%;
39-
left: var(--bezier-react-segmented-control-indicator-left);
40-
width: var(--bezier-react-segmented-control-indicator-width);
41-
height: var(--bezier-react-segmented-control-indicator-height);
39+
left: var(--bezier-segmented-control-indicator-left);
40+
width: var(--bezier-segmented-control-indicator-width);
41+
height: var(--bezier-segmented-control-indicator-height);
4242
4343
${({ foundation }) => foundation?.elevation.ev1()}
4444
/* NOTE: (@ed) Overrides the elevation mixin. Do not change the order! */
4545
background-color: var(--bg-white-high);
4646
47-
transform: translateX(var(--bezier-react-segmented-control-indicator-translateX)) translateY(-50%);
47+
transform: translateX(var(--bezier-segmented-control-indicator-translateX)) translateY(-50%);
4848
${({ foundation }) => foundation?.transition?.getTransitionsCSS('transform', TransitionDuration.M)}
4949
`
5050

@@ -116,12 +116,12 @@ export const Item = styled.button`
116116
`
117117

118118
export const Container = styled(AlphaStack).attrs({ direction: 'horizontal' })`
119-
--bezier-react-segmented-control-width: auto;
119+
--bezier-segmented-control-width: auto;
120120
121121
position: relative;
122122
z-index: ${ZIndex.Base};
123123
box-sizing: border-box;
124-
width: var(--bezier-react-segmented-control-width);
124+
width: var(--bezier-segmented-control-width);
125125
background-color: var(--bg-black-lighter);
126126
127127
&.${SegmentedControlSize.XS} {

packages/bezier-react/src/components/Forms/SegmentedControl/SegmentedControl.test.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -138,16 +138,16 @@ describe('SegmentedControl >', () => {
138138
describe('"radiogroup" type', () => {
139139
it('when changing the width property, the width style should be applied to the outer wrapper', () => {
140140
const { getByRole } = renderComponent({ type: 'radiogroup', width: '100%' })
141-
expect(getByRole('radiogroup')).toHaveStyle('--bezier-react-segmented-control-width: 100%')
142-
expect(getByRole('radiogroup')).toHaveStyle('width: var(--bezier-react-segmented-control-width)')
141+
expect(getByRole('radiogroup')).toHaveStyle('--bezier-segmented-control-width: 100%')
142+
expect(getByRole('radiogroup')).toHaveStyle('width: var(--bezier-segmented-control-width)')
143143
})
144144
})
145145

146146
describe('"tabs" type', () => {
147147
it('when changing the width property, the width style should be applied to the outer wrapper', () => {
148148
const { getByRole } = renderComponent({ type: 'tabs', width: '100%' })
149-
expect(getByRole('tablist')).toHaveStyle('--bezier-react-segmented-control-width: 100%')
150-
expect(getByRole('tablist')).toHaveStyle('width: var(--bezier-react-segmented-control-width)')
149+
expect(getByRole('tablist')).toHaveStyle('--bezier-segmented-control-width: 100%')
150+
expect(getByRole('tablist')).toHaveStyle('width: var(--bezier-segmented-control-width)')
151151
})
152152
})
153153
})
@@ -313,9 +313,9 @@ describe('SegmentedControl >', () => {
313313

314314
const indicator = getByTestId(SEGMENTED_CONTROL_INDICATOR_TEST_ID)
315315

316-
expect(indicator).toHaveStyle('width: var(--bezier-react-segmented-control-indicator-width)')
317-
expect(indicator).toHaveStyle('height: var(--bezier-react-segmented-control-indicator-height)')
318-
expect(indicator).toHaveStyle('transform: translateX(var(--bezier-react-segmented-control-indicator-translateX)) translateY(-50%)')
316+
expect(indicator).toHaveStyle('width: var(--bezier-segmented-control-indicator-width)')
317+
expect(indicator).toHaveStyle('height: var(--bezier-segmented-control-indicator-height)')
318+
expect(indicator).toHaveStyle('transform: translateX(var(--bezier-segmented-control-indicator-translateX)) translateY(-50%)')
319319
})
320320
})
321321

packages/bezier-react/src/components/Forms/SegmentedControl/SegmentedControl.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ import * as RadioGroupPrimitive from '@radix-ui/react-radio-group'
88
import * as TabsPrimitive from '@radix-ui/react-tabs'
99
import classNames from 'classnames'
1010

11+
import {
12+
cssVarName,
13+
px,
14+
} from '~/src/utils/styleUtils'
1115
import { isNumber } from '~/src/utils/typeUtils'
1216

1317
import { Divider } from '~/src/components/Divider'
@@ -34,6 +38,8 @@ import { SegmentedControlIndicator } from './SegmentedControlIndicator'
3438

3539
import * as Styled from './SegmentedControl.styled'
3640

41+
const cv = cssVarName('segmented-control')
42+
3743
function SegmentedControlItemListImpl<
3844
Type extends SegmentedControlType,
3945
Value extends string,
@@ -62,7 +68,7 @@ function SegmentedControlItemListImpl<
6268

6369
const style = useMemo(() => ({
6470
...styleProp,
65-
'--bezier-react-segmented-control-width': isNumber(width) ? `${width}px` : width,
71+
[cv('width')]: isNumber(width) ? px(width) : width,
6672
} as React.CSSProperties), [
6773
styleProp,
6874
width,

packages/bezier-react/src/components/Forms/SegmentedControl/SegmentedControlIndicator.tsx

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import React from 'react'
22

3+
import {
4+
cssVarName,
5+
px,
6+
} from '~/src/utils/styleUtils'
7+
38
import { DIVIDER_THICKNESS } from '~/src/components/Divider'
49

510
import {
@@ -9,6 +14,8 @@ import {
914

1015
import * as Styled from './SegmentedControl.styled'
1116

17+
const cv = cssVarName('segmented-control-indicator')
18+
1219
export const SEGMENTED_CONTROL_INDICATOR_TEST_ID = 'bezier-react-segmented-control-indicator'
1320

1421
export function SegmentedControlIndicator() {
@@ -24,10 +31,10 @@ export function SegmentedControlIndicator() {
2431
const containerHorizontalPadding = `${2 * containerPadding}px`
2532

2633
const style = {
27-
'--bezier-react-segmented-control-indicator-translateX': `calc(${selectedItemIndex * 100}% + ${selectedItemIndex * DIVIDER_THICKNESS}px)`,
28-
'--bezier-react-segmented-control-indicator-width': `calc((100% - ${dividerTotalWidth} - ${containerHorizontalPadding}) / ${itemCount})`,
29-
'--bezier-react-segmented-control-indicator-height': `${containerHeight - (2 * containerPadding)}px`,
30-
'--bezier-react-segmented-control-indicator-left': `${containerPadding}px`,
34+
[cv('translateX')]: `calc(${selectedItemIndex * 100}% + ${selectedItemIndex * DIVIDER_THICKNESS}px)`,
35+
[cv('width')]: `calc((100% - ${dividerTotalWidth} - ${containerHorizontalPadding}) / ${itemCount})`,
36+
[cv('height')]: px(containerHeight - (2 * containerPadding)),
37+
[cv('left')]: px(containerPadding),
3138
} as React.CSSProperties
3239

3340
return (

packages/bezier-react/src/components/Forms/Slider/Slider.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ import React, {
55

66
import * as SliderPrimitive from '@radix-ui/react-slider'
77

8+
import {
9+
cssVarName,
10+
px,
11+
} from '~/src/utils/styleUtils'
812
import { isNumber } from '~/src/utils/typeUtils'
913

1014
import {
@@ -16,6 +20,8 @@ import type SliderProps from './Slider.types'
1620

1721
import * as Styled from './Slider.styled'
1822

23+
const cv = cssVarName('slider')
24+
1925
export const SLIDER_TEST_ID = 'bezier-react-slider'
2026

2127
const SliderGuide = memo<Record<'min' | 'max' | 'value', number>>(function SliderGuide({
@@ -26,7 +32,7 @@ const SliderGuide = memo<Record<'min' | 'max' | 'value', number>>(function Slide
2632
return (
2733
<Styled.SliderGuide
2834
style={{
29-
'--bezier-slider-guide-left': `${(value / (max - min)) * 100}%`,
35+
[cv('guide-left')]: `${(value / (max - min)) * 100}%`,
3036
} as React.CSSProperties}
3137
/>
3238
)
@@ -100,7 +106,7 @@ export const Slider = forwardRef<HTMLSpanElement, SliderProps>(function Slider({
100106
<Styled.SliderPrimitiveRoot
101107
style={{
102108
...style,
103-
'--bezier-slider-width': isNumber(width) ? `${width}px` : width,
109+
[cv('width')]: isNumber(width) ? px(width) : width,
104110
}}
105111
data-testid={SLIDER_TEST_ID}
106112
ref={forwardedRef}

0 commit comments

Comments
 (0)