sh-ui-cli 0.58.7 → 0.59.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/changelog/versions.json +30 -0
- package/data/registry/react/components/tooltip/index.tailwind.tsx +1 -1
- package/data/registry/react/components/tooltip/styles.css +1 -1
- package/data/registry/react/components/tooltip/styles.module.css +1 -1
- package/data/tokens/build.mjs +2 -1
- package/data/tokens/src/primitives.json +22 -22
- package/package.json +1 -1
- package/src/create/theme/inject.js +11 -3
- package/templates/nextjs-standalone/_arch/flat/lib/styles/tokens.css +22 -22
- package/templates/nextjs-standalone/_arch/fsd/src/shared/styles/tokens.css +22 -22
- package/templates/ui-app-template/src/styles/tokens.css +22 -22
|
@@ -2,6 +2,36 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$description": "sh-ui 릴리즈 노트 단일 소스. docs(React)와 showcase(Flutter)가 함께 읽는다. 새 릴리즈마다 맨 앞에 추가.",
|
|
4
4
|
"versions": [
|
|
5
|
+
{
|
|
6
|
+
"version": "0.59.0",
|
|
7
|
+
"date": "2026-05-06",
|
|
8
|
+
"title": "토큰 정책 전환 — px → rem (접근성 / 유저 글꼴 확대 반응)",
|
|
9
|
+
"type": "minor",
|
|
10
|
+
"highlights": [
|
|
11
|
+
"**dimension 토큰을 PX → REM 으로 일괄 전환** — `--space-2: 0.5rem`, `--text-sm: 0.875rem`, `--control-md: 2.5rem` 등. 1rem = 16px 가정. 사용자가 브라우저 글꼴 키울 때 컴포넌트가 비례 반응 (WCAG 1.4.4 준수). 사용자 root font-size 안 건드리면 시각적 no-op.",
|
|
12
|
+
"**PX 유지 예외** — `--border-width: 1px/2px` (1px 미만 정밀도), shadow offset (`--shadow-sm: 0 1px 2px ...`), breakpoint (`640px/768px/...`, MQ 호환성). 거의 1~2 token 한정.",
|
|
13
|
+
"**`packages/tokens/src/primitives.json` 마이그레이션** — spacing/fontSize/controlHeight 의 \"4px\" 등 dimension 값을 rem 으로 변경. build.mjs 의 dimensionToDart 가 \"0\" 도 처리.",
|
|
14
|
+
"**`inject.js` 의 spacing/typography/controls emit 함수에 toRem 헬퍼 추가** — 1rem=16px 변환 + trailing zero 제거 (0.50→0.5, 1.00→1).",
|
|
15
|
+
"**Dart (Flutter) 측은 PX 유지** — Flutter 는 logical pixel 단위라 dimension 그대로. CSS 만 rem 화.",
|
|
16
|
+
"**CLAUDE.md 규칙 v2** — \"토큰 정의부 PX 허용\" → \"토큰 정의부 REM 사용 (border/shadow 만 PX 예외)\". 향후 신규 토큰도 이 정책 따라야 함.",
|
|
17
|
+
"**기존 사용자 마이그레이션 가이드** — 기존 프로젝트의 정적 tokens.css 는 그대로 동작 (PX). REM 의 이점을 받으려면 `sh-ui add tokens` 재설치 또는 수동 마이그레이션 필요. patch release 가 아닌 minor 라 대응 시간 확보."
|
|
18
|
+
],
|
|
19
|
+
"url": "https://github.com/sanghyeonKim0201/sh-ui/releases/tag/v0.59.0"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"version": "0.58.8",
|
|
23
|
+
"date": "2026-05-06",
|
|
24
|
+
"title": "디자인 디폴트 개편 7라운드 — Tooltip 의 duration·shadow 를 토큰으로",
|
|
25
|
+
"type": "patch",
|
|
26
|
+
"highlights": [
|
|
27
|
+
"**Tooltip 의 `duration-[120ms]` → `duration-[var(--duration-fast)]`** — 정확히 같은 값(120ms = `--duration-fast`)을 하드코딩하던 걸 토큰으로. 향후 token 단에서 motion 속도를 일괄 조정 가능.",
|
|
28
|
+
"**Tooltip 의 `shadow-[0_4px_12px_rgba(0,0,0,0.12)]` → `shadow-[var(--shadow-md)]`** — 토큰 `--shadow-md` 와 정확히 동일한 값을 하드코딩하던 걸 정리. 향후 elevation 일괄 조정 가능.",
|
|
29
|
+
"**다른 컴포넌트들의 shadow 는 별도로 보존** — Popover/Toast/DropdownMenu 등은 component-specific tuning (multi-layer, negative spread 등) 이라 토큰과 정확히 매칭되지 않음. 무리한 표준화는 visual diff 손실로 보류.",
|
|
30
|
+
"**Heading typography / hover state 일관성** — audit 결과 모두 의도된 차이 (Dialog/Card/Popover 의 size 차등 = 컨텍스트, hover 는 이미 모두 token-driven). 변경 안 함.",
|
|
31
|
+
"**4 variant + 듀얼 카피본 동기화** — Tooltip Tailwind / plain CSS / CSS Modules / vanilla-extract."
|
|
32
|
+
],
|
|
33
|
+
"url": "https://github.com/sanghyeonKim0201/sh-ui/releases/tag/v0.58.8"
|
|
34
|
+
},
|
|
5
35
|
{
|
|
6
36
|
"version": "0.58.7",
|
|
7
37
|
"date": "2026-05-06",
|
|
@@ -38,7 +38,7 @@ export const TooltipContent = React.forwardRef<HTMLDivElement, TooltipContentPro
|
|
|
38
38
|
<BaseTooltip.Popup
|
|
39
39
|
ref={ref}
|
|
40
40
|
className={cn(
|
|
41
|
-
"px-2.5 py-1.5 bg-foreground text-background rounded-[calc(var(--radius)-2px)] text-[length:var(--text-xs)] leading-snug max-w-xs shadow-[
|
|
41
|
+
"px-2.5 py-1.5 bg-foreground text-background rounded-[calc(var(--radius)-2px)] text-[length:var(--text-xs)] leading-snug max-w-xs shadow-[var(--shadow-md)] origin-[var(--transform-origin)] outline-none transition-[opacity,transform] duration-[var(--duration-fast)] ease-out motion-reduce:transition-none data-[starting-style]:opacity-0 data-[starting-style]:scale-95 data-[ending-style]:opacity-0 data-[ending-style]:scale-95 motion-reduce:data-[starting-style]:scale-100 motion-reduce:data-[ending-style]:scale-100",
|
|
42
42
|
className,
|
|
43
43
|
)}
|
|
44
44
|
{...props}
|
package/data/tokens/build.mjs
CHANGED
|
@@ -194,8 +194,9 @@ function cssColorToDart(css) {
|
|
|
194
194
|
throw new Error(`지원하지 않는 CSS 색상: ${css}`);
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
-
/** "0.5rem" → 8.0, "16px" → 16.0 */
|
|
197
|
+
/** "0.5rem" → 8.0, "16px" → 16.0, "0" → 0.0 */
|
|
198
198
|
function dimensionToDart(value) {
|
|
199
|
+
if (value === "0" || value === 0) return "0.0";
|
|
199
200
|
const rem = /^(-?\d*\.?\d+)rem$/.exec(value);
|
|
200
201
|
if (rem) return (parseFloat(rem[1]) * 16).toFixed(1);
|
|
201
202
|
const px = /^(-?\d*\.?\d+)px$/.exec(value);
|
|
@@ -53,17 +53,17 @@
|
|
|
53
53
|
},
|
|
54
54
|
|
|
55
55
|
"spacing": {
|
|
56
|
-
"0": { "$value": "
|
|
57
|
-
"1": { "$value": "
|
|
58
|
-
"2": { "$value": "
|
|
59
|
-
"3": { "$value": "
|
|
60
|
-
"4": { "$value": "
|
|
61
|
-
"5": { "$value": "
|
|
62
|
-
"6": { "$value": "
|
|
63
|
-
"8": { "$value": "
|
|
64
|
-
"10": { "$value": "
|
|
65
|
-
"12": { "$value": "
|
|
66
|
-
"16": { "$value": "
|
|
56
|
+
"0": { "$value": "0", "$type": "dimension" },
|
|
57
|
+
"1": { "$value": "0.25rem", "$type": "dimension" },
|
|
58
|
+
"2": { "$value": "0.5rem", "$type": "dimension" },
|
|
59
|
+
"3": { "$value": "0.75rem", "$type": "dimension" },
|
|
60
|
+
"4": { "$value": "1rem", "$type": "dimension" },
|
|
61
|
+
"5": { "$value": "1.25rem", "$type": "dimension" },
|
|
62
|
+
"6": { "$value": "1.5rem", "$type": "dimension" },
|
|
63
|
+
"8": { "$value": "2rem", "$type": "dimension" },
|
|
64
|
+
"10": { "$value": "2.5rem", "$type": "dimension" },
|
|
65
|
+
"12": { "$value": "3rem", "$type": "dimension" },
|
|
66
|
+
"16": { "$value": "4rem", "$type": "dimension" }
|
|
67
67
|
},
|
|
68
68
|
|
|
69
69
|
"radius": {
|
|
@@ -76,14 +76,14 @@
|
|
|
76
76
|
},
|
|
77
77
|
|
|
78
78
|
"fontSize": {
|
|
79
|
-
"xs": { "$value": "
|
|
80
|
-
"sm": { "$value": "
|
|
81
|
-
"base":{ "$value": "
|
|
82
|
-
"lg": { "$value": "
|
|
83
|
-
"xl": { "$value": "
|
|
84
|
-
"2xl": { "$value": "
|
|
85
|
-
"3xl": { "$value": "
|
|
86
|
-
"4xl": { "$value": "
|
|
79
|
+
"xs": { "$value": "0.75rem", "$type": "dimension" },
|
|
80
|
+
"sm": { "$value": "0.875rem", "$type": "dimension" },
|
|
81
|
+
"base":{ "$value": "1rem", "$type": "dimension" },
|
|
82
|
+
"lg": { "$value": "1.125rem", "$type": "dimension" },
|
|
83
|
+
"xl": { "$value": "1.25rem", "$type": "dimension" },
|
|
84
|
+
"2xl": { "$value": "1.5rem", "$type": "dimension" },
|
|
85
|
+
"3xl": { "$value": "1.875rem", "$type": "dimension" },
|
|
86
|
+
"4xl": { "$value": "2.25rem", "$type": "dimension" }
|
|
87
87
|
},
|
|
88
88
|
|
|
89
89
|
"fontWeight": {
|
|
@@ -112,9 +112,9 @@
|
|
|
112
112
|
},
|
|
113
113
|
|
|
114
114
|
"controlHeight": {
|
|
115
|
-
"sm": { "$value": "
|
|
116
|
-
"md": { "$value": "
|
|
117
|
-
"lg": { "$value": "
|
|
115
|
+
"sm": { "$value": "2rem", "$type": "dimension" },
|
|
116
|
+
"md": { "$value": "2.5rem", "$type": "dimension" },
|
|
117
|
+
"lg": { "$value": "3rem", "$type": "dimension" }
|
|
118
118
|
},
|
|
119
119
|
|
|
120
120
|
"borderWidth": {
|
package/package.json
CHANGED
|
@@ -126,9 +126,17 @@ export const buildDartRadiusBlock = (theme) => {
|
|
|
126
126
|
|
|
127
127
|
const SPACING_KEYS = ['0', '1', '2', '3', '4', '5', '6', '8', '10', '12', '16'];
|
|
128
128
|
|
|
129
|
+
// 1rem = 16px 가정. 0 은 unit 없이 emit (CSS 권장).
|
|
130
|
+
// trailing zero 제거 (0.50 → 0.5, 1.00 → 1).
|
|
131
|
+
const toRem = (px) => {
|
|
132
|
+
if (px === 0) return '0';
|
|
133
|
+
return `${parseFloat((px / 16).toFixed(4))}rem`;
|
|
134
|
+
};
|
|
135
|
+
|
|
129
136
|
export const buildCssSpacingBlock = (spacing) =>
|
|
130
|
-
SPACING_KEYS.map((k) => ` --space-${k}: ${spacing[k]}
|
|
137
|
+
SPACING_KEYS.map((k) => ` --space-${k}: ${toRem(spacing[k])};`).join('\n');
|
|
131
138
|
|
|
139
|
+
// Flutter 는 logical pixel 사용. Dart 측은 PX 그대로 유지.
|
|
132
140
|
export const buildDartSpacingBlock = (spacing) =>
|
|
133
141
|
SPACING_KEYS.map((k) => ` s${k}: ${spacing[k].toFixed(1)},`).join('\n');
|
|
134
142
|
|
|
@@ -137,7 +145,7 @@ export const buildDartSpacingBlock = (spacing) =>
|
|
|
137
145
|
const TYPOGRAPHY_KEYS = ['xs', 'sm', 'base', 'lg', 'xl', '2xl', '3xl', '4xl'];
|
|
138
146
|
|
|
139
147
|
export const buildCssTypographyBlock = (typography) =>
|
|
140
|
-
TYPOGRAPHY_KEYS.map((k) => ` --text-${k}: ${typography[k]}
|
|
148
|
+
TYPOGRAPHY_KEYS.map((k) => ` --text-${k}: ${toRem(typography[k])};`).join('\n');
|
|
141
149
|
|
|
142
150
|
// Dart 클래스는 'xl2'/'xl3'/'xl4' 명명 규칙 사용 (숫자 prefix 회피).
|
|
143
151
|
const DART_TEXT_FIELD_NAMES = {
|
|
@@ -165,7 +173,7 @@ export const buildDartWeightsBlock = (weights) =>
|
|
|
165
173
|
const CONTROL_KEYS = ['sm', 'md', 'lg'];
|
|
166
174
|
|
|
167
175
|
export const buildCssControlsBlock = (controls) =>
|
|
168
|
-
CONTROL_KEYS.map((k) => ` --control-${k}: ${controls[k]}
|
|
176
|
+
CONTROL_KEYS.map((k) => ` --control-${k}: ${toRem(controls[k])};`).join('\n');
|
|
169
177
|
|
|
170
178
|
export const buildDartControlsBlock = (controls) =>
|
|
171
179
|
CONTROL_KEYS.map((k) => ` ${k}: ${controls[k].toFixed(1)},`).join('\n');
|
|
@@ -66,27 +66,27 @@
|
|
|
66
66
|
--radius: 0.5rem;
|
|
67
67
|
/* sh-ui:theme-radius-end */
|
|
68
68
|
/* sh-ui:theme-space-start */
|
|
69
|
-
--space-0:
|
|
70
|
-
--space-1:
|
|
71
|
-
--space-2:
|
|
72
|
-
--space-3:
|
|
73
|
-
--space-4:
|
|
74
|
-
--space-5:
|
|
75
|
-
--space-6:
|
|
76
|
-
--space-8:
|
|
77
|
-
--space-10:
|
|
78
|
-
--space-12:
|
|
79
|
-
--space-16:
|
|
69
|
+
--space-0: 0;
|
|
70
|
+
--space-1: 0.25rem;
|
|
71
|
+
--space-2: 0.5rem;
|
|
72
|
+
--space-3: 0.75rem;
|
|
73
|
+
--space-4: 1rem;
|
|
74
|
+
--space-5: 1.25rem;
|
|
75
|
+
--space-6: 1.5rem;
|
|
76
|
+
--space-8: 2rem;
|
|
77
|
+
--space-10: 2.5rem;
|
|
78
|
+
--space-12: 3rem;
|
|
79
|
+
--space-16: 4rem;
|
|
80
80
|
/* sh-ui:theme-space-end */
|
|
81
81
|
/* sh-ui:theme-text-start */
|
|
82
|
-
--text-xs:
|
|
83
|
-
--text-sm:
|
|
84
|
-
--text-base:
|
|
85
|
-
--text-lg:
|
|
86
|
-
--text-xl:
|
|
87
|
-
--text-2xl:
|
|
88
|
-
--text-3xl:
|
|
89
|
-
--text-4xl:
|
|
82
|
+
--text-xs: 0.75rem;
|
|
83
|
+
--text-sm: 0.875rem;
|
|
84
|
+
--text-base: 1rem;
|
|
85
|
+
--text-lg: 1.125rem;
|
|
86
|
+
--text-xl: 1.25rem;
|
|
87
|
+
--text-2xl: 1.5rem;
|
|
88
|
+
--text-3xl: 1.875rem;
|
|
89
|
+
--text-4xl: 2.25rem;
|
|
90
90
|
/* sh-ui:theme-text-end */
|
|
91
91
|
/* sh-ui:theme-weight-start */
|
|
92
92
|
--weight-regular: 400;
|
|
@@ -110,9 +110,9 @@
|
|
|
110
110
|
--ease-emphasized: cubic-bezier(0.2, 0, 0, 1);
|
|
111
111
|
/* sh-ui:theme-ease-end */
|
|
112
112
|
/* sh-ui:theme-control-start */
|
|
113
|
-
--control-sm:
|
|
114
|
-
--control-md:
|
|
115
|
-
--control-lg:
|
|
113
|
+
--control-sm: 2rem;
|
|
114
|
+
--control-md: 2.5rem;
|
|
115
|
+
--control-lg: 3rem;
|
|
116
116
|
/* sh-ui:theme-control-end */
|
|
117
117
|
/* sh-ui:theme-border-width-start */
|
|
118
118
|
--border-width: 1px;
|
|
@@ -66,27 +66,27 @@
|
|
|
66
66
|
--radius: 0.5rem;
|
|
67
67
|
/* sh-ui:theme-radius-end */
|
|
68
68
|
/* sh-ui:theme-space-start */
|
|
69
|
-
--space-0:
|
|
70
|
-
--space-1:
|
|
71
|
-
--space-2:
|
|
72
|
-
--space-3:
|
|
73
|
-
--space-4:
|
|
74
|
-
--space-5:
|
|
75
|
-
--space-6:
|
|
76
|
-
--space-8:
|
|
77
|
-
--space-10:
|
|
78
|
-
--space-12:
|
|
79
|
-
--space-16:
|
|
69
|
+
--space-0: 0;
|
|
70
|
+
--space-1: 0.25rem;
|
|
71
|
+
--space-2: 0.5rem;
|
|
72
|
+
--space-3: 0.75rem;
|
|
73
|
+
--space-4: 1rem;
|
|
74
|
+
--space-5: 1.25rem;
|
|
75
|
+
--space-6: 1.5rem;
|
|
76
|
+
--space-8: 2rem;
|
|
77
|
+
--space-10: 2.5rem;
|
|
78
|
+
--space-12: 3rem;
|
|
79
|
+
--space-16: 4rem;
|
|
80
80
|
/* sh-ui:theme-space-end */
|
|
81
81
|
/* sh-ui:theme-text-start */
|
|
82
|
-
--text-xs:
|
|
83
|
-
--text-sm:
|
|
84
|
-
--text-base:
|
|
85
|
-
--text-lg:
|
|
86
|
-
--text-xl:
|
|
87
|
-
--text-2xl:
|
|
88
|
-
--text-3xl:
|
|
89
|
-
--text-4xl:
|
|
82
|
+
--text-xs: 0.75rem;
|
|
83
|
+
--text-sm: 0.875rem;
|
|
84
|
+
--text-base: 1rem;
|
|
85
|
+
--text-lg: 1.125rem;
|
|
86
|
+
--text-xl: 1.25rem;
|
|
87
|
+
--text-2xl: 1.5rem;
|
|
88
|
+
--text-3xl: 1.875rem;
|
|
89
|
+
--text-4xl: 2.25rem;
|
|
90
90
|
/* sh-ui:theme-text-end */
|
|
91
91
|
/* sh-ui:theme-weight-start */
|
|
92
92
|
--weight-regular: 400;
|
|
@@ -110,9 +110,9 @@
|
|
|
110
110
|
--ease-emphasized: cubic-bezier(0.2, 0, 0, 1);
|
|
111
111
|
/* sh-ui:theme-ease-end */
|
|
112
112
|
/* sh-ui:theme-control-start */
|
|
113
|
-
--control-sm:
|
|
114
|
-
--control-md:
|
|
115
|
-
--control-lg:
|
|
113
|
+
--control-sm: 2rem;
|
|
114
|
+
--control-md: 2.5rem;
|
|
115
|
+
--control-lg: 3rem;
|
|
116
116
|
/* sh-ui:theme-control-end */
|
|
117
117
|
/* sh-ui:theme-border-width-start */
|
|
118
118
|
--border-width: 1px;
|
|
@@ -66,27 +66,27 @@
|
|
|
66
66
|
--radius: 0.5rem;
|
|
67
67
|
/* sh-ui:theme-radius-end */
|
|
68
68
|
/* sh-ui:theme-space-start */
|
|
69
|
-
--space-0:
|
|
70
|
-
--space-1:
|
|
71
|
-
--space-2:
|
|
72
|
-
--space-3:
|
|
73
|
-
--space-4:
|
|
74
|
-
--space-5:
|
|
75
|
-
--space-6:
|
|
76
|
-
--space-8:
|
|
77
|
-
--space-10:
|
|
78
|
-
--space-12:
|
|
79
|
-
--space-16:
|
|
69
|
+
--space-0: 0;
|
|
70
|
+
--space-1: 0.25rem;
|
|
71
|
+
--space-2: 0.5rem;
|
|
72
|
+
--space-3: 0.75rem;
|
|
73
|
+
--space-4: 1rem;
|
|
74
|
+
--space-5: 1.25rem;
|
|
75
|
+
--space-6: 1.5rem;
|
|
76
|
+
--space-8: 2rem;
|
|
77
|
+
--space-10: 2.5rem;
|
|
78
|
+
--space-12: 3rem;
|
|
79
|
+
--space-16: 4rem;
|
|
80
80
|
/* sh-ui:theme-space-end */
|
|
81
81
|
/* sh-ui:theme-text-start */
|
|
82
|
-
--text-xs:
|
|
83
|
-
--text-sm:
|
|
84
|
-
--text-base:
|
|
85
|
-
--text-lg:
|
|
86
|
-
--text-xl:
|
|
87
|
-
--text-2xl:
|
|
88
|
-
--text-3xl:
|
|
89
|
-
--text-4xl:
|
|
82
|
+
--text-xs: 0.75rem;
|
|
83
|
+
--text-sm: 0.875rem;
|
|
84
|
+
--text-base: 1rem;
|
|
85
|
+
--text-lg: 1.125rem;
|
|
86
|
+
--text-xl: 1.25rem;
|
|
87
|
+
--text-2xl: 1.5rem;
|
|
88
|
+
--text-3xl: 1.875rem;
|
|
89
|
+
--text-4xl: 2.25rem;
|
|
90
90
|
/* sh-ui:theme-text-end */
|
|
91
91
|
/* sh-ui:theme-weight-start */
|
|
92
92
|
--weight-regular: 400;
|
|
@@ -110,9 +110,9 @@
|
|
|
110
110
|
--ease-emphasized: cubic-bezier(0.2, 0, 0, 1);
|
|
111
111
|
/* sh-ui:theme-ease-end */
|
|
112
112
|
/* sh-ui:theme-control-start */
|
|
113
|
-
--control-sm:
|
|
114
|
-
--control-md:
|
|
115
|
-
--control-lg:
|
|
113
|
+
--control-sm: 2rem;
|
|
114
|
+
--control-md: 2.5rem;
|
|
115
|
+
--control-lg: 3rem;
|
|
116
116
|
/* sh-ui:theme-control-end */
|
|
117
117
|
/* sh-ui:theme-border-width-start */
|
|
118
118
|
--border-width: 1px;
|