Skip to content

style: 유효하지 않은 Panda CSS 스타일 값 수정#1145

Merged
SimYunSup merged 2 commits into
DaleStudy:mainfrom
gwagjiug:main
Jun 23, 2026
Merged

style: 유효하지 않은 Panda CSS 스타일 값 수정#1145
SimYunSup merged 2 commits into
DaleStudy:mainfrom
gwagjiug:main

Conversation

@gwagjiug

@gwagjiug gwagjiug commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

변경 배경

일부 컴포넌트에서 Panda CSS의 텍스트 스타일과 디자인 토큰을 잘못된 CSS 속성 또는 토큰 경로로 사용하고 있었습니다.

현재 설정에서는 Panda CSS가 알 수 없는 문자열도 임의의 CSS 값으로 처리할 수 있어 TypeScript 검사와 빌드는 통과했습니다. 하지만 다음과 같이 브라우저가 해석할 수 없는 CSS가 생성되었습니다.

font-style: label.sm;
outline: borderWidths.lg solid;
color: fg.neutral.default;
color: fg.neutral.DEFAULT;

브라우저는 유효하지 않은 CSS 선언만 조용히 무시하기 때문에 컴포넌트 전체가 깨지지는 않았습니다. 기존 테스트도 주로 생성된 클래스의 존재 여부를 확인하고 있어 실제 CSS가 유효한지는 검증하지 못했습니다.

이번 PR에서는 새로운 디자인 값을 추가하거나 디자인을 변경하지 않고, 기존에 정의된 텍스트 스타일과 토큰이 올바르게 적용되도록 수정했습니다.

변경 내용

Select의 텍스트 스타일 적용 방식 수정

label.sm, label.md는 CSS의 font-style 값이 아니라 Panda CSS에 정의된 텍스트 스타일입니다.

기존에는 다음과 같이 사용하고 있었습니다.

fontStyle: "label.sm";
fontStyle: "label.md";

fontStylenormal, italic과 같은 CSS font-style 값을 받는 속성이기 때문에 다음과 같은 유효하지 않은 CSS가 생성되었습니다.

font-style: label.sm;
font-style: label.md;

이를 텍스트 스타일을 적용하는 textStyle 속성으로 변경했습니다.

textStyle: "label.sm";
textStyle: "label.md";

이제 Panda CSS가 해당 텍스트 스타일에 포함된 글꼴 크기, 굵기, 행간 등을 올바르게 적용합니다.

Link의 focus outline 너비 적용 방식 수정

기존 코드는 outline 단축 속성 안에서 Panda CSS 토큰 경로를 문자열로 사용하고 있었습니다.

outline: "borderWidths.lg solid";

단축 속성 문자열 내부의 borderWidths.lg는 토큰으로 변환되지 않고 그대로 CSS에 출력되었습니다.

outline: borderWidths.lg solid;

borderWidths.lg는 유효한 CSS 길이 값이 아니므로 브라우저가 해당 선언을 무시합니다.

Panda CSS가 토큰의 종류를 명확하게 인식할 수 있도록 outline 너비와 스타일을 각각 분리했습니다.

outlineWidth: "lg";
outlineStyle: "solid";

기존 outlineColor: "border.brand.focus"는 그대로 유지했습니다. 새로운 디자인 값을 추가하지 않고 기존 focus outline의 너비와 스타일이 정상적으로 적용되도록 수정했습니다.

PasswordInput의 색상 토큰 경로 수정

기존에는 다음 토큰 경로를 사용했습니다.

color: "fg.neutral.default";

하지만 생성된 Panda CSS 토큰에는 fg.neutral.default가 존재하지 않고, 기본 neutral 색상은 fg.neutral로 제공됩니다.

존재하지 않는 경로는 토큰으로 변환되지 않아 다음과 같은 유효하지 않은 CSS가 생성되었습니다.

color: fg.neutral.default;

따라서 실제로 존재하는 토큰을 사용하도록 수정했습니다.

color: "fg.neutral";

Label의 색상 토큰 경로 수정

semantic token 정의에서는 기본값을 나타내기 위해 DEFAULT 키를 사용할 수 있습니다.

neutral: {
  DEFAULT: {
    value: "...",
  },
}

하지만 DEFAULT는 토큰을 정의할 때 사용하는 예약 키이며, 컴포넌트에서 사용하는 최종 토큰 경로에는 포함되지 않습니다.

따라서 다음 경로는 존재하지 않는 토큰을 참조하고 있었습니다.

color: "fg.neutral.DEFAULT";

생성된 토큰과 CSS 변수에는 fg.neutral.DEFAULT가 아니라 fg.neutral만 존재하므로 다음과 같이 수정했습니다.

color: "fg.neutral";

테스트 보강

수정된 스타일이 올바른 Panda CSS 클래스로 변환되는지 확인하도록 관련 테스트를 변경하거나 추가했습니다.

  • Select가 textStyle_label.md 클래스를 사용하는지 확인
  • Link의 focus 상태에 outline 너비와 solid 스타일 클래스가 생성되는지 확인
  • PasswordInput이 fg.neutral 색상 클래스를 사용하는지 확인
  • Label이 존재하지 않는 fg.neutral.DEFAULT 대신 fg.neutral을 사용하는지 확인

기존 Label 테스트는 잘못된 클래스 이름 자체를 기대하고 있었기 때문에 구현과 테스트가 함께 통과하고 있었습니다. 이번 변경에서는 실제로 생성되는 유효한 토큰 클래스를 기준으로 테스트를 수정했습니다.

영향 범위

  • 컴포넌트의 공개 API와 props에는 변경이 없습니다.
  • 새로운 디자인 토큰을 추가하지 않았습니다.
  • 기존에 정의된 텍스트 스타일과 색상 토큰을 사용했습니다.
  • 브라우저가 무시하던 스타일이 정상적으로 적용되므로 UI 스냅샷에 차이가 발생할 수 있습니다.
  • Button에서 사용하는 fg.danger.hover, fg.danger.active는 새로운 토큰 추가 또는 기존 토큰 대체에 대한 디자인 결정이 필요하므로 이번 PR 범위에서는 제외했습니다.

테스팅

다음 명령어로 변경 사항을 확인했습니다.

bun run format
bun run lint
bun run test --run
bun run build

확인 결과:

  • 포맷 검사 통과
  • 린트 통과
    • 기존 Fast Refresh 관련 경고 3건은 이번 변경과 관련이 없어 그대로 유지했습니다.
  • 단위 테스트 21개 파일, 총 576개 테스트 통과
  • 프로덕션 빌드 통과
  • 빌드 결과에서 다음의 유효하지 않은 CSS가 더 이상 생성되지 않는 것을 확인
    • font-style: label.sm
    • font-style: label.md
    • outline: borderWidths.lg solid
    • color: fg.neutral.default
    • color: fg.neutral.DEFAULT

Storybook에서 Select, Link, PasswordInput, Label의 실제 계산 스타일과 화면 표시를 확인했습니다.

  • Select에 label.md 텍스트 스타일이 적용되는 것을 확인
  • 오버플로 툴팁에 label.sm 텍스트 스타일이 적용되는 것을 확인
  • Link의 focus outline이 2px solid로 표시되는 것을 확인
  • PasswordInput과 Label에 fg.neutral 색상 토큰이 적용되는 것을 확인

체크 리스트

  • 코드 리뷰를 요청하기 전에 반드시 CI가 통과하는지 확인해주세요.
  • 컴포넌트나 스토리 변경이 있는 경우 PR에 ui 태그를 달아주세요. (UI 변경이 포함되어 있습니다. Chromatic 실행을 위해 ui 라벨 추가 부탁드립니다.)
    • UI Tests를 통해 스냅샷 차이가 의도된 것인지 확인해주세요.
    • UI Review를 통해 디자이너에게 리뷰를 요청하고 승인을 받으세요.

@gwagjiug gwagjiug requested a review from a team as a code owner June 22, 2026 05:00
@SimYunSup

Copy link
Copy Markdown
Member

PR 잘 봤습니다. Link의 outline 정리된 부분 좋은데, 바로 아래 focus 색상 쪽도 같이 보면 좋을 것 같습니다. 무효 토큰을 써서 무효 CSS가 나오고 브라우저가 조용히 무시하는 케이스가 몇 군데 더 남아 있는 것 같아서요.

Link.tsx

  • L91 color: "fg.brand.focus"
  • L100 color: "fg.neutral.focus"

fg.brand / fg.neutral 둘 다 focus 키가 아예 없습니다. 그래서 포커스 시 글자색이 바뀌는 게 실제로는 안 먹고 있어요. focus 표시를 outline이 맡고 있어서 그동안 티가 안 났던 것 같습니다.

Button.tsx

  • fg.danger.hover / fg.danger.active (L263, 267, 333, 337)

이건 좀 헷갈리는데, bg.danger.hover / bgSolid.danger.hover는 실제로 있습니다. 다만 fg.danger만 상태 없는 단일 토큰이라 fg.danger.hover / fg.danger.active는 없는 토큰이고, 그래서 호버·액티브 때 글자색이 안 바뀝니다. 이 부분은 PR에서도 "디자인 결정 필요"로 일부러 빼둔 영역인 건 알고 있습니다.

방향은 이렇게 가면 될 것 같습니다. 굳이 fg.danger.hover/activefg.*.focus 같은 새 상태 토큰을 만들기보다, focus·danger 글자색을 기존 토큰으로 통일하거나 죽은 :focus 블록 자체를 빼는 쪽이 깔끔할 것 같아요. focus는 어차피 outline이 표시를 맡고 있고, danger도 fg.danger 단일 토큰으로 충분해서 호버·액티브에서 글자색까지 바꿀 이유는 딱히 없어 보입니다. 그러면 토큰을 늘리지 않고 무효 CSS만 정리됩니다.

src/tokens 실제 정의를 로드해서 컴포넌트 사용처랑 전부 대조한 결과인데, 이 버그 클래스는 위 6개가 전부였습니다.

@gwagjiug

Copy link
Copy Markdown
Contributor Author

@SimYunSup 확인 감사합니다. 말씀해주신 것처럼 fg.brand.focus, fg.neutral.focus, fg.danger.hover, fg.danger.active는 실제 토큰 정의에 없는 값이네요.

이 부분은 새 상태 토큰을 추가하기보다는 죽은 CSS 선언을 정리하는 방향으로 수정하겠습니다.

  • Link의 :focus 글자색 변경은 제거하고, focus 표시는 기존 outline 스타일에만 맡기겠습니다.
  • Button의 danger outline/ghost 상태에서는 fg.danger 단일 토큰을 유지하고, hover/active에서는 실제 존재하는 bg.danger.hover, bg.danger.active만 적용되도록 정리하겠습니다.

추가로 이런 무효 토큰 사용을 막기 위해서는 Panda의 strictTokens/strictPropertyValues 옵션을 검토하거나, 생성된 CSS에 토큰 문자열이 그대로 남아 있는지 확인하는 검증 스크립트를 CI에 추가하는 방법이 있을 것 같습니다. 다만 strict 옵션은 영향 범위가 있을 수 있어서 이번 PR과는 분리해서 다루는 게 좋아 보입니다.

@gwagjiug

Copy link
Copy Markdown
Contributor Author

@SimYunSup

반영했습니다. 72185c0

새 토큰을 추가하지 않고 죽은 CSS 선언을 제거하는 방향으로 정리했습니다. Link의 focus 글자색 변경은 제거하고 기존 outline에만 focus 표시를 맡겼고, Button danger 상태에서는 fg.danger 단일 토큰을 유지하면서 hover/active 배경 토큰만 적용되도록 수정했습니다.

format, lint, test, build도 다시 확인했습니다.

@SimYunSup SimYunSup left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다!

@gwagjiug gwagjiug removed their assignment Jun 23, 2026
@gwagjiug

gwagjiug commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

@gwagjiug gwagjiug removed their assignment

@SimYunSup 실수로 unassign 했는데 권한이 없어서 다시 못 하고 있어요. 다시 assign 부탁드립니다!👍

@SimYunSup SimYunSup added this pull request to the merge queue Jun 23, 2026
Merged via the queue into DaleStudy:main with commit f75d532 Jun 23, 2026
6 checks passed
@github-actions github-actions Bot mentioned this pull request Jun 26, 2026
@DaleSeo

DaleSeo commented Jun 27, 2026

Copy link
Copy Markdown
Member

@all-contributors please add @gwagjiug for code

@allcontributors

Copy link
Copy Markdown
Contributor

@DaleSeo

I've put up a pull request to add @gwagjiug! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants