버그 이슈: https://github.com/shadcn-ui/ui/issues/4654#issue-2491018149
버그 이슈에 대한 제 코멘트: https://github.com/shadcn-ui/ui/issues/4654#issuecomment-2323113138
이를 기반으로 올린 PR: https://github.com/shadcn-ui/ui/pull/4745#issue-2506748491
배경
평소처럼 shadcn-ui를 사용하고 있었고, 위의 이슈와는 다른 이슈로 shadcn-ui 깃허브 이슈 탭을 살펴보던 와중에 간단해보이는 버그 이슈를 발견하였습니다 (위 링크 이슈)
이를 해결해보기 위해 우선 문제 상황을 재현해보려 했습니다.
위의 버그 제보자가 버그를 재현하기 위해서 해보라고 한 지침을 그대로 수행하였지만, 저한테는 해당 문제가 발생하지 않았습니다.
How to reproduce
enter pnpm dlx shadcn-ui@latest add checkbox or radio-group on your project.
go to ui/checkbox...ui/radio-group
you'll see the error.
(버그 제보자 글 중,,)
그래서 왜 나한테는 일어나지 않는 일이 저분한테는 일어날까 해서, 이분의 깃허브를 보았습니다.
그중에 한 프로젝트에서 shadcn-ui를 사용하고 계셨고, 저랑 다른 점을 발견했습니다.
바로 shadcn init 과정에서 css 변수를 추가할거냐는 물음에 저는 yes를, 저분은 아마 no를 선택하신거같았습니다 (저 분 프로젝트 globals.css를 보고 추정)
그래서 저도 위의 옵션을 no로 하니 같은 버그가 발생하였습니다.
해결해보기
우선 이 문제는 init 과정에서 발생한 문제로 shadcn을 사용하는 파일에서는 수정이 불가능하다고 판단하였습니다.
그래서 shadcn 레포를 포크한 후 코드들을 살펴봤습니다.
또한 무작정 모든 코드를 살펴본것이 아닌, 위의 이슈 글에서도 언급되어있지만, 이미 비슷한 이슈 - 해결에 관한 글이 있었습니다
저기서 많은 이야기가 나왔지만, 핵심은 "transformCssVars" 이 부분이 문제라는 점을 알수있었습니다.
그래서 포크한 파일들에서 해당 부분을 찾아봤습니다.
결과적으로 "utils/transformers/transform-csss-vars.ts"에서 "applyColorMapping"이라는 함수가 css 변수를 변환해준다는 것을 알았고, 이 부분을 살펴보았습니다.
문제 코드
if (input.includes(” border ”)) {
input = input.replace(” border ‘, ’ border border-border ”)
}
위의 코드에서 알수있듯이 "border"에 대한 특별한 처리가 이루어지고있었습니다.
뱐환하려는 tailwind에서 "border가 있으면 "border boder-boder"로 바꾸라는 분기 처리였습니다.
이제 문제가 되는 shadcn 컴포넌트("checkbox")의 tailwind 코드를 보았습니다.
"peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
여기 집중한 부분은 "border boder-primary"였습니다.
다시 위의 if문으로 돌아가서, 위의 checkbox 코드를 넣고 변환한다고 가정해보면 아래처럼 나올것입니다 (border 부분만)
"border border-boder boder-primary"
이러면 "applyColorMapping" 함수에서 boder에 대한 처리를 두 번하게 됩니다 "boder-boder" -> "boder-xxx" / "boder-primary" -> "border-yyy"
만약 이 "boder-xxx"와 "boder-yyy"가 겹치면 "applyColorMapping"의 로직중에 중복제거 코드에 의해서 문제가 발생하지 않지만 (실제로 input의 경우도 boder boder-input이 있지만, boder-input과 boder-boder는 같은 tailwind로 변환되어 문제가 없습니다)
"border-primary"의 경우는 "neutral-900"으로, "border-boder"는 "neutral-200"으로 변환됩니다 (neutral 테마에 light 기준)
따라서 중복제거가 되지 않고 결과적으로는 아래처럼 변환됩니다
"border-neutral-200 border-neutral-900" ...
그러면 이제 해결을 해야하는데, 제가 생각한 해결법은 아래와 같았습니다.
단순히 "boder-primary"는 저 if문을 안통하게 하면 되겠다
if (input.includes(" border ") && !input.includes("border-primary")) {
input = input.replace(" border ", " border border-border ")
}
이를 기반으로 테스트를 돌려봤습니다
import { describe, expect, it } from "vitest"
import { applyColorMapping } from "../utils/transformers/transform-css-vars"
import neutral from "./neutral.json"
describe("applyColorMapping transformation", () => {
const realMapping = neutral.inlineColors
it("should correctly transform class names with color mapping", () => {
const input =
"peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground"
const expectedOutput =
"peer h-4 w-4 shrink-0 rounded-sm border border-neutral-900 ring-offset-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-400 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-neutral-900 data-[state=checked]:text-neutral-50 dark:border-neutral-50 dark:ring-offset-neutral-950 dark:focus-visible:ring-neutral-800 dark:data-[state=checked]:bg-neutral-50 dark:data-[state=checked]:text-neutral-900"
const result = applyColorMapping(input, realMapping)
expect(result).toBe(expectedOutput)
})
})
테스트를 통과하는 결론이 나왔습니다.
물론 위의 해결책이 100% 해결책이 아닐수 있고, 틀린 해결책일수도있지만, 문제의 원인이 될수있는 부분을 찾았다는 거에서 의미를 두고싶습니다
'기타' 카테고리의 다른 글
[Project_react-router-file-routing] 01 - 프로젝트 구성하기 (0) | 2024.10.09 |
---|---|
[radix-ui] radix-ui 깃허브에 올라온 버그 이슈 수정해보기 (0) | 2024.09.19 |
[기타] 네이버 카페 페이지 이동 시 url에 반영하기 (0) | 2024.08.24 |
[Frontend] 요구사항에 따른 디자인 시스템 설계하기 (0) | 2023.07.15 |