-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Migrate
Button
component with scss (#1882)
<!-- 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 ## Related Issue <!-- Please link to issue if one exists --> - #1733 ## Summary <!-- Please brief explanation of the changes made --> Migrate Button component with scss ## Details <!-- Please elaborate description of the changes --> - Button 컴포넌트는 style 베리언츠와 color 베리언츠로 다양한 스타일의 조합이 나올 수 있어서, 마이그레이션하기가 조금 복잡했습니다. 코드 리뷰로 파악하기에도 쉽지 않을 거 같아, 마이그레이션된 스타일에 대응되는 부분을 셀프 코드리뷰로 남겨둡니다. - Button 단위 테스트는 모두 스타일 + 스냅샷 테스트로 이루어져있어, 유의미한 테스트가 아니라고 판단했습니다. 제거합니다. (추후 시각적 회귀 테스트가 잘 적용되면 좋은 부분) - Button이 Margin prop을 지원하도록 개선하고, 코드를 정리했습니다. ### Breaking change? (Yes/No) <!-- If Yes, please describe the impact and migration path for users --> Yes. - Button에서 as, interpolation prop을 제거합니다. - Button의 enum value 값들을 파스칼 케이스로 통일합니다. ## References <!-- Please list any other resources or points the reviewer should be aware of --> 없음
- Loading branch information
1 parent
cfcfe70
commit 1b333bf
Showing
12 changed files
with
457 additions
and
3,424 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
--- | ||
"@channel.io/bezier-react": major | ||
--- | ||
|
||
`Button`'s interface changes. | ||
|
||
- `Button` no longer supports `as` and `interpolation` prop. | ||
- The enum values of `ButtonSize` and `ButtonColorVariant` are changed to kebab case. | ||
- `Button` now supports common margin props. |
319 changes: 319 additions & 0 deletions
319
packages/bezier-react/src/components/Button/Button.module.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,319 @@ | ||
$chromaticColorVariants: "blue", "red", "green", "cobalt", "orange", "pink", "purple"; | ||
$activeSelector: ":where(.active, :hover):where(:not(:disabled))"; | ||
|
||
.Button { | ||
position: relative; | ||
box-sizing: border-box; | ||
cursor: pointer; | ||
transition: background-color var(--transition-s), box-shadow var(--transition-s); | ||
|
||
&:disabled { | ||
cursor: not-allowed; | ||
opacity: var(--opacity-disabled); | ||
} | ||
|
||
&:focus:not(:disabled) { | ||
outline: 3px solid var(--bgtxt-cobalt-light); | ||
} | ||
|
||
&:focus:not(:focus-visible) { | ||
outline: none; | ||
} | ||
|
||
/* Size */ | ||
&:where(.size-xs) { | ||
padding: 0 2px; | ||
min-width: 20px; | ||
height: 20px; | ||
|
||
&:where(.style-floating, .style-floating-alt) { | ||
padding: 0 7px; | ||
} | ||
} | ||
|
||
&:where(.size-s) { | ||
padding: 0 4px; | ||
min-width: 24px; | ||
height: 24px; | ||
|
||
&:where(.style-floating, .style-floating-alt) { | ||
padding: 0 9px; | ||
} | ||
} | ||
|
||
&:where(.size-m) { | ||
padding: 0 10px; | ||
min-width: 36px; | ||
height: 36px; | ||
|
||
&:where(.style-floating, .style-floating-alt) { | ||
padding: 0 14px; | ||
} | ||
} | ||
|
||
&:where(.size-l) { | ||
padding: 0 12px; | ||
min-width: 44px; | ||
height: 44px; | ||
|
||
&:where(.style-floating, .style-floating-alt) { | ||
padding: 0 18px; | ||
} | ||
} | ||
|
||
&:where(.size-xl) { | ||
padding: 0 20px; | ||
min-width: 54px; | ||
height: 54px; | ||
|
||
&:where(.style-floating, .style-floating-alt) { | ||
padding: 0 23px; | ||
} | ||
} | ||
|
||
/* NOTE: If there is no text, button is square, so padding is 0 */ | ||
&:not(:has(.ButtonText)) { | ||
padding: 0; | ||
} | ||
|
||
&:where(.size-xs, .size-s) { | ||
& :where(.ButtonText) { | ||
padding: 0 3px; | ||
} | ||
} | ||
|
||
&:where(.size-m, .size-l, .size-xl) { | ||
& :where(.ButtonContent) { | ||
gap: 2px; | ||
} | ||
|
||
& :where(.ButtonText) { | ||
padding: 0 4px; | ||
} | ||
} | ||
|
||
/* Color variants */ | ||
&:where(.style-primary) { | ||
@each $colorVariant in $chromaticColorVariants { | ||
&:where(.color-#{$colorVariant}) { | ||
color: var(--bgtxt-absolute-white-dark); | ||
background-color: var(--bgtxt-#{$colorVariant}-normal); | ||
|
||
&#{$activeSelector} { | ||
background-color: var(--bgtxt-#{$colorVariant}-dark); | ||
} | ||
} | ||
} | ||
|
||
&:where(.color-monochrome) { | ||
color: var(--bgtxt-absolute-white-dark); | ||
background-color: var(--bgtxt-absolute-black-lightest); | ||
|
||
&#{$activeSelector} { | ||
background-color: var(--bgtxt-absolute-black-lighter); | ||
} | ||
} | ||
|
||
&:where(.color-monochrome-light) { | ||
color: var(--bgtxt-absolute-white-dark); | ||
background-color: var(--bg-black-darker); | ||
} | ||
|
||
&:where(.color-monochrome-dark) { | ||
color: var(--txt-white-normal); | ||
background-color: var(--bg-grey-darkest); | ||
} | ||
} | ||
|
||
&:where(.style-secondary) { | ||
@each $colorVariant in $chromaticColorVariants { | ||
&:where(.color-#{$colorVariant}) { | ||
color: var(--bgtxt-#{$colorVariant}-normal); | ||
background-color: var(--bgtxt-#{$colorVariant}-lightest); | ||
|
||
&#{$activeSelector} { | ||
background-color: var(--bgtxt-#{$colorVariant}-lighter); | ||
} | ||
} | ||
} | ||
|
||
&:where(.color-monochrome) { | ||
color: var(--txt-black-darkest); | ||
background-color: var(--bg-black-lighter); | ||
|
||
&#{$activeSelector} { | ||
background-color: var(--bg-black-light); | ||
} | ||
} | ||
|
||
&:where(.color-monochrome-light) { | ||
color: var(--txt-black-darker); | ||
background-color: var(--bg-black-lighter); | ||
|
||
&#{$activeSelector} { | ||
background-color: var(--bg-black-light); | ||
} | ||
} | ||
|
||
&:where(.color-monochrome-dark) { | ||
color: var(--txt-black-darkest); | ||
background-color: var(--bg-black-lighter); | ||
|
||
&#{$activeSelector} { | ||
background-color: var(--bg-black-light); | ||
} | ||
} | ||
} | ||
|
||
&:where(.style-tertiary) { | ||
background-color: transparent; | ||
|
||
@each $colorVariant in $chromaticColorVariants { | ||
&:where(.color-#{$colorVariant}) { | ||
color: var(--bgtxt-#{$colorVariant}-normal); | ||
|
||
&#{$activeSelector} { | ||
color: var(--bgtxt-#{$colorVariant}-dark); | ||
background-color: var(--bgtxt-#{$colorVariant}-lightest); | ||
} | ||
} | ||
} | ||
|
||
&:where(.color-monochrome) { | ||
color: var(--txt-black-darkest); | ||
|
||
&#{$activeSelector} { | ||
background-color: var(--bg-black-lightest); | ||
} | ||
} | ||
|
||
&:where(.color-monochrome-light) { | ||
color: var(--txt-black-darker); | ||
|
||
&#{$activeSelector} { | ||
background-color: var(--bg-black-lighter); | ||
} | ||
} | ||
|
||
&:where(.color-monochrome-dark) { | ||
color: var(--txt-black-darkest); | ||
|
||
&#{$activeSelector} { | ||
background-color: var(--bg-black-lighter); | ||
} | ||
} | ||
} | ||
|
||
&:where(.style-floating, .style-floating-alt) { | ||
@each $colorVariant in $chromaticColorVariants { | ||
&:where(.color-#{$colorVariant}) { | ||
color: var(--bgtxt-absolute-white-dark); | ||
background-color: var(--bgtxt-#{$colorVariant}-normal); | ||
|
||
&#{$activeSelector} { | ||
background-color: var(--bgtxt-#{$colorVariant}-dark); | ||
} | ||
} | ||
} | ||
|
||
&:where(.color-monochrome) { | ||
color: var(--txt-black-darkest); | ||
background-color: var(--bg-white-low); | ||
} | ||
|
||
&:where(.color-monochrome-light) { | ||
color: var(--txt-black-darker); | ||
background-color: var(--bg-white-high); | ||
} | ||
|
||
&:where(.color-monochrome-dark) { | ||
color: var(--txt-black-darkest); | ||
background-color: var(--bg-white-high); | ||
} | ||
} | ||
|
||
/* Effect */ | ||
&:where(.style-primary, .style-secondary, .style-tertiary) { | ||
&:where(.size-xs) { | ||
border-radius: var(--radius-6); | ||
} | ||
|
||
&:where(.size-s, .size-m) { | ||
border-radius: var(--radius-8); | ||
} | ||
|
||
&:where(.size-l) { | ||
border-radius: var(--radius-12); | ||
} | ||
|
||
&:where(.size-xl) { | ||
border-radius: var(--radius-16); | ||
} | ||
} | ||
|
||
&:is(.style-floating, .style-floating-alt) { | ||
box-shadow: var(--ev-2); | ||
|
||
&:hover { | ||
box-shadow: var(--ev-3); | ||
} | ||
} | ||
|
||
&:where(.style-floating) { | ||
overflow: hidden; | ||
border-radius: 9999px; | ||
} | ||
|
||
&:where(.style-floating-alt) { | ||
border-radius: var(--radius-8); | ||
} | ||
|
||
/* Hover styles for text, icon, and loader */ | ||
&:where(.color-monochrome):where(.style-secondary, .style-tertiary):where(:not(.active):not(:hover)) { | ||
&:where(.size-s, .size-xs) .ButtonText { | ||
color: var(--txt-black-darker); | ||
} | ||
|
||
&:where(.size-s, .size-xs) :is(.ButtonIcon, .ButtonLoader) { | ||
color: var(--txt-black-dark); | ||
} | ||
|
||
&:where(.size-m, .size-l, .size-xl) :is(.ButtonIcon, .ButtonLoader) { | ||
color: var(--txt-black-darker); | ||
} | ||
} | ||
|
||
&:where(.color-monochrome-light):where(.style-secondary, .style-tertiary, .style-floating):where(:not(.active):not(:hover)) { | ||
& :is(.ButtonIcon, .ButtonLoader) { | ||
color: var(--txt-black-dark); | ||
} | ||
} | ||
|
||
&:where(.color-monochrome-dark):where(.style-secondary, .style-tertiary, .style-floating):where(:not(.active):not(:hover)) { | ||
& :is(.ButtonIcon, .ButtonLoader) { | ||
color: var(--txt-black-darker); | ||
} | ||
} | ||
} | ||
|
||
.ButtonContent { | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
|
||
/* NOTE: Using the visibility property to preserve content area while loading */ | ||
&:where(.loading) { | ||
visibility: hidden; | ||
} | ||
} | ||
|
||
.ButtonLoader { | ||
position: absolute; | ||
top: 0; | ||
right: 0; | ||
bottom: 0; | ||
left: 0; | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.