sh-ui-cli 0.58.5 → 0.58.7

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.
Files changed (23) hide show
  1. package/data/changelog/versions.json +28 -0
  2. package/data/registry/react/components/button/index.tailwind.tsx +1 -1
  3. package/data/registry/react/components/button/styles.css +1 -0
  4. package/data/registry/react/components/button/styles.css.ts +3 -0
  5. package/data/registry/react/components/button/styles.module.css +1 -0
  6. package/data/registry/react/components/calendar/index.tailwind.tsx +1 -1
  7. package/data/registry/react/components/calendar/styles.css +1 -1
  8. package/data/registry/react/components/calendar/styles.module.css +1 -1
  9. package/data/registry/react/components/carousel/index.tailwind.tsx +1 -1
  10. package/data/registry/react/components/carousel/styles.css +1 -1
  11. package/data/registry/react/components/carousel/styles.module.css +1 -1
  12. package/data/registry/react/components/pagination/index.tailwind.tsx +1 -1
  13. package/data/registry/react/components/pagination/styles.css +1 -1
  14. package/data/registry/react/components/pagination/styles.module.css +1 -1
  15. package/data/registry/react/components/rich-text-editor/index.tailwind.tsx +1 -1
  16. package/data/registry/react/components/rich-text-editor/styles.css +1 -1
  17. package/data/registry/react/components/rich-text-editor/styles.module.css +1 -1
  18. package/package.json +1 -1
  19. package/templates/nextjs-standalone/_arch/flat/lib/styles/tokens.css +3 -0
  20. package/templates/nextjs-standalone/_arch/fsd/src/shared/styles/tokens.css +3 -0
  21. package/templates/nextjs-standalone/app/globals.css +1 -0
  22. package/templates/ui-app-template/src/styles/globals.css +1 -0
  23. package/templates/ui-app-template/src/styles/tokens.css +3 -0
@@ -2,6 +2,34 @@
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.58.7",
7
+ "date": "2026-05-06",
8
+ "title": "디자인 디폴트 개편 6라운드 — disabled opacity 토큰 통일",
9
+ "type": "patch",
10
+ "highlights": [
11
+ "**`--opacity-disabled` (0.5) 토큰을 모든 컴포넌트가 사용** — 그동안 calendar(0.3) / carousel(0.4) / pagination(0.45) / rich-text-editor(0.5) 가 각자 다른 disabled opacity 값을 쓰고 있었음. 단일 토큰으로 정렬해 \"disabled 느낌\"이 모든 컴포넌트에서 동일.",
12
+ "**Tailwind variant 의 하드코딩 opacity 클래스 제거** — `disabled:opacity-30` / `disabled:opacity-40` / `disabled:opacity-50` / `aria-disabled:opacity-45` / `data-[disabled]:opacity-45` → `disabled:opacity-[var(--opacity-disabled)]`.",
13
+ "**plain CSS / module / vanilla-extract 동기화** — `:disabled { opacity: 0.X }` 의 0.3/0.4/0.45/0.5 하드코딩 → `var(--opacity-disabled)`.",
14
+ "**outside / inactive 같은 \"비활성이지만 disabled 아님\" 상태는 별도 유지** — calendar 의 day--outside (0.4) 는 disabled 와 다른 시각 의도라 이번 통일에서 제외.",
15
+ "**철학 — \"disabled 느낌\" 은 토큰의 책임**: 사용자가 brand 톤 한 번 결정하면 모든 컴포넌트의 disabled 가 같은 깊이로 fade. 컴포넌트별 미세 조정 X."
16
+ ],
17
+ "url": "https://github.com/sanghyeonKim0201/sh-ui/releases/tag/v0.58.7"
18
+ },
19
+ {
20
+ "version": "0.58.6",
21
+ "date": "2026-05-06",
22
+ "title": "디자인 디폴트 개편 5라운드 — `--danger-hover` 토큰 + Button danger hover 일관화",
23
+ "type": "patch",
24
+ "highlights": [
25
+ "**`--danger-hover` 토큰 신규** — `color-mix(in srgb, var(--danger) 90%, black)` (10% 어둡게). primary 가 `--primary-hover` 가지듯 danger 도 일관된 hover 토큰. 향후 컴포넌트가 `danger` 색을 hover 시 어떻게 바꿀지 한 곳에서 결정.",
26
+ "**`--color-danger-hover: var(--danger-hover)` @theme inline 매핑** — Tailwind `bg-danger-hover` 유틸 활성화.",
27
+ "**Button danger 의 `hover:brightness-95` 제거 → `hover:bg-danger-hover`** — Tailwind variant 의 \"더블펌프 후 잔존 brightness\" 정리. primary/secondary/ghost 와 같은 token-기반 hover 패턴으로 정렬.",
28
+ "**plain CSS / module / vanilla-extract 의 누락된 danger:hover 추가** — 기존엔 Tailwind variant 만 hover 효과 있었고 다른 3개 variant 는 hover 시 색이 그대로였음 (히든 버그). 이제 4개 variant 모두 동일한 hover 동작.",
29
+ "**일관성 — 5라운드까지의 누적 효과**: focus(ring 50% primary) / inline focus(1px primary) / active indicator(primary) / hover(token-driven) — 모든 인터랙션 상태가 brand 토큰으로 정렬. \"매번 사용자가 결정\" 패턴 제거."
30
+ ],
31
+ "url": "https://github.com/sanghyeonKim0201/sh-ui/releases/tag/v0.58.6"
32
+ },
5
33
  {
6
34
  "version": "0.58.5",
7
35
  "date": "2026-05-06",
@@ -14,7 +14,7 @@ const buttonVariants = cva(
14
14
  ghost:
15
15
  "bg-transparent text-foreground hover:bg-background-muted",
16
16
  danger:
17
- "bg-danger text-danger-foreground hover:brightness-95",
17
+ "bg-danger text-danger-foreground hover:bg-danger-hover",
18
18
  link:
19
19
  "bg-transparent text-primary underline-offset-4 hover:underline",
20
20
  },
@@ -64,6 +64,7 @@
64
64
  background-color: var(--danger);
65
65
  color: var(--danger-foreground);
66
66
  }
67
+ .sh-ui-button--danger:hover { background-color: var(--danger-hover); }
67
68
 
68
69
  /* link — 배경/테두리 없이 밑줄. size는 font-size만 유지, height/padding 제거 */
69
70
  .sh-ui-button--link {
@@ -97,6 +97,9 @@ export const variants = styleVariants({
97
97
  danger: {
98
98
  backgroundColor: "var(--danger)",
99
99
  color: "var(--danger-foreground)",
100
+ selectors: {
101
+ "&:hover": { backgroundColor: "var(--danger-hover)" },
102
+ },
100
103
  },
101
104
  link: {
102
105
  backgroundColor: "transparent",
@@ -64,6 +64,7 @@
64
64
  background-color: var(--danger);
65
65
  color: var(--danger-foreground);
66
66
  }
67
+ .danger:hover { background-color: var(--danger-hover); }
67
68
 
68
69
  .link {
69
70
  background-color: transparent;
@@ -526,7 +526,7 @@ export const CalendarGrid = React.forwardRef<HTMLDivElement, CalendarGridProps>(
526
526
  <button
527
527
  type="button"
528
528
  className={cn(
529
- "flex items-center justify-center w-9 h-9 p-0 border-none rounded-[calc(var(--radius)-2px)] bg-transparent text-foreground text-[0.8125rem] font-[inherit] cursor-pointer transition-[background-color,color] duration-[var(--duration-fast)] hover:not-disabled:bg-background-muted focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 disabled:opacity-30 disabled:cursor-not-allowed motion-reduce:transition-none",
529
+ "flex items-center justify-center w-9 h-9 p-0 border-none rounded-[calc(var(--radius)-2px)] bg-transparent text-foreground text-[0.8125rem] font-[inherit] cursor-pointer transition-[background-color,color] duration-[var(--duration-fast)] hover:not-disabled:bg-background-muted focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 disabled:opacity-[var(--opacity-disabled)] disabled:cursor-not-allowed motion-reduce:transition-none",
530
530
  !current && "text-[var(--foreground-subtle,var(--foreground-muted))] opacity-40",
531
531
  isToday && "font-bold underline underline-offset-[0.125rem]",
532
532
  selected && "bg-primary text-primary-foreground font-semibold hover:not-disabled:bg-primary-hover hover:not-disabled:text-primary-foreground",
@@ -208,6 +208,6 @@
208
208
  }
209
209
 
210
210
  .sh-ui-calendar__day:disabled {
211
- opacity: 0.3;
211
+ opacity: var(--opacity-disabled);
212
212
  cursor: not-allowed;
213
213
  }
@@ -208,6 +208,6 @@
208
208
  }
209
209
 
210
210
  .calendar__day:disabled {
211
- opacity: 0.3;
211
+ opacity: var(--opacity-disabled);
212
212
  cursor: not-allowed;
213
213
  }
@@ -205,7 +205,7 @@ export const CarouselItem = React.forwardRef<HTMLDivElement, React.HTMLAttribute
205
205
  CarouselItem.displayName = "CarouselItem";
206
206
 
207
207
  const navClasses =
208
- "absolute top-1/2 w-8 h-8 inline-flex items-center justify-center bg-background text-foreground border border-border rounded-full cursor-pointer -translate-y-1/2 z-[1] transition-[opacity,background-color] duration-[var(--duration-fast)] hover:not-disabled:bg-background-muted focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 disabled:opacity-40 disabled:cursor-not-allowed motion-reduce:transition-none data-[orientation=vertical]:left-1/2 data-[orientation=vertical]:-translate-x-1/2 data-[orientation=vertical]:[top:auto]";
208
+ "absolute top-1/2 w-8 h-8 inline-flex items-center justify-center bg-background text-foreground border border-border rounded-full cursor-pointer -translate-y-1/2 z-[1] transition-[opacity,background-color] duration-[var(--duration-fast)] hover:not-disabled:bg-background-muted focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 disabled:opacity-[var(--opacity-disabled)] disabled:cursor-not-allowed motion-reduce:transition-none data-[orientation=vertical]:left-1/2 data-[orientation=vertical]:-translate-x-1/2 data-[orientation=vertical]:[top:auto]";
209
209
 
210
210
  export const CarouselPrevious = React.forwardRef<HTMLButtonElement, React.ButtonHTMLAttributes<HTMLButtonElement>>(
211
211
  ({ className, onClick, disabled, children, ...props }, ref) => {
@@ -70,7 +70,7 @@
70
70
  }
71
71
 
72
72
  .sh-ui-carousel__nav:disabled {
73
- opacity: 0.4;
73
+ opacity: var(--opacity-disabled);
74
74
  cursor: not-allowed;
75
75
  }
76
76
 
@@ -70,7 +70,7 @@
70
70
  }
71
71
 
72
72
  .carousel__nav:disabled {
73
- opacity: 0.4;
73
+ opacity: var(--opacity-disabled);
74
74
  cursor: not-allowed;
75
75
  }
76
76
 
@@ -34,7 +34,7 @@ export const PaginationItem = React.forwardRef<HTMLLIElement, React.LiHTMLAttrib
34
34
  );
35
35
 
36
36
  const linkBase =
37
- "inline-flex items-center justify-center gap-1.5 min-w-9 h-9 px-3 rounded-[calc(var(--radius)-2px)] border border-transparent bg-transparent text-foreground no-underline transition-[background-color,border-color,color] duration-[var(--duration-fast)] cursor-pointer select-none hover:bg-background-muted focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 data-[active]:bg-foreground data-[active]:text-background data-[active]:font-medium data-[active]:hover:opacity-90 aria-disabled:pointer-events-none aria-disabled:opacity-45 data-[disabled]:pointer-events-none data-[disabled]:opacity-45 data-[size=sm]:min-w-8 data-[size=sm]:h-8 data-[size=sm]:px-2 motion-reduce:transition-none";
37
+ "inline-flex items-center justify-center gap-1.5 min-w-9 h-9 px-3 rounded-[calc(var(--radius)-2px)] border border-transparent bg-transparent text-foreground no-underline transition-[background-color,border-color,color] duration-[var(--duration-fast)] cursor-pointer select-none hover:bg-background-muted focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 data-[active]:bg-foreground data-[active]:text-background data-[active]:font-medium data-[active]:hover:opacity-90 aria-disabled:pointer-events-none aria-disabled:opacity-[var(--opacity-disabled)] data-[disabled]:pointer-events-none data-[disabled]:opacity-[var(--opacity-disabled)] data-[size=sm]:min-w-8 data-[size=sm]:h-8 data-[size=sm]:px-2 motion-reduce:transition-none";
38
38
 
39
39
  export interface PaginationLinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
40
40
  isActive?: boolean;
@@ -70,7 +70,7 @@
70
70
  .sh-ui-pagination__link[aria-disabled="true"],
71
71
  .sh-ui-pagination__link[data-disabled] {
72
72
  pointer-events: none;
73
- opacity: 0.45;
73
+ opacity: var(--opacity-disabled);
74
74
  }
75
75
 
76
76
  .sh-ui-pagination__nav {
@@ -70,7 +70,7 @@
70
70
  .pagination__link[aria-disabled="true"],
71
71
  .pagination__link[data-disabled] {
72
72
  pointer-events: none;
73
- opacity: 0.45;
73
+ opacity: var(--opacity-disabled);
74
74
  }
75
75
 
76
76
  .pagination__nav {
@@ -157,7 +157,7 @@ function ToolbarButton({ editor, label, icon, isActive, canRun, run, disabled }:
157
157
  <button
158
158
  type="button"
159
159
  className={cn(
160
- "inline-flex items-center justify-center w-7 h-7 p-0 bg-transparent text-foreground-muted border border-transparent rounded-[calc(var(--radius)-2px)] cursor-pointer transition-[color,background-color,border-color] duration-[var(--duration-fast)] hover:not-disabled:text-foreground hover:not-disabled:bg-background hover:not-disabled:border-border focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-1 disabled:opacity-50 disabled:cursor-not-allowed motion-reduce:transition-none",
160
+ "inline-flex items-center justify-center w-7 h-7 p-0 bg-transparent text-foreground-muted border border-transparent rounded-[calc(var(--radius)-2px)] cursor-pointer transition-[color,background-color,border-color] duration-[var(--duration-fast)] hover:not-disabled:text-foreground hover:not-disabled:bg-background hover:not-disabled:border-border focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-1 disabled:opacity-[var(--opacity-disabled)] disabled:cursor-not-allowed motion-reduce:transition-none",
161
161
  isActive && "text-foreground bg-background border-border-strong",
162
162
  )}
163
163
  aria-label={label}
@@ -59,7 +59,7 @@
59
59
  border-color: var(--border-strong);
60
60
  }
61
61
  .sh-ui-rte__btn:disabled {
62
- opacity: 0.5;
62
+ opacity: var(--opacity-disabled);
63
63
  cursor: not-allowed;
64
64
  }
65
65
  .sh-ui-rte__sep {
@@ -59,7 +59,7 @@
59
59
  border-color: var(--border-strong);
60
60
  }
61
61
  .rte__btn:disabled {
62
- opacity: 0.5;
62
+ opacity: var(--opacity-disabled);
63
63
  cursor: not-allowed;
64
64
  }
65
65
  .rte__sep {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sh-ui-cli",
3
- "version": "0.58.5",
3
+ "version": "0.58.7",
4
4
  "description": "sh-ui CLI — 프로젝트 스캐폴드(create) + 컴포넌트 추가(add/list/remove) + IDE-내 AI용 MCP 서버",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -18,6 +18,7 @@
18
18
  --primary-hover: #262626;
19
19
  --ring: color-mix(in srgb, var(--primary) 50%, transparent);
20
20
  --danger: #DC2626;
21
+ --danger-hover: color-mix(in srgb, var(--danger) 90%, black);
21
22
  --danger-foreground: #FFFFFF;
22
23
  }
23
24
  @media (prefers-color-scheme: dark) {
@@ -36,6 +37,7 @@
36
37
  --primary-foreground: #171717;
37
38
  --primary-hover: #E5E5E5;
38
39
  --danger: #DC2626;
40
+ --danger-hover: color-mix(in srgb, var(--danger) 90%, black);
39
41
  --danger-foreground: #FFFFFF;
40
42
  }
41
43
  }
@@ -54,6 +56,7 @@
54
56
  --primary-foreground: #171717;
55
57
  --primary-hover: #E5E5E5;
56
58
  --danger: #DC2626;
59
+ --danger-hover: color-mix(in srgb, var(--danger) 90%, black);
57
60
  --danger-foreground: #FFFFFF;
58
61
  }
59
62
  /* sh-ui:theme-colors-end */
@@ -18,6 +18,7 @@
18
18
  --primary-hover: #262626;
19
19
  --ring: color-mix(in srgb, var(--primary) 50%, transparent);
20
20
  --danger: #DC2626;
21
+ --danger-hover: color-mix(in srgb, var(--danger) 90%, black);
21
22
  --danger-foreground: #FFFFFF;
22
23
  }
23
24
  @media (prefers-color-scheme: dark) {
@@ -36,6 +37,7 @@
36
37
  --primary-foreground: #171717;
37
38
  --primary-hover: #E5E5E5;
38
39
  --danger: #DC2626;
40
+ --danger-hover: color-mix(in srgb, var(--danger) 90%, black);
39
41
  --danger-foreground: #FFFFFF;
40
42
  }
41
43
  }
@@ -54,6 +56,7 @@
54
56
  --primary-foreground: #171717;
55
57
  --primary-hover: #E5E5E5;
56
58
  --danger: #DC2626;
59
+ --danger-hover: color-mix(in srgb, var(--danger) 90%, black);
57
60
  --danger-foreground: #FFFFFF;
58
61
  }
59
62
  /* sh-ui:theme-colors-end */
@@ -23,6 +23,7 @@
23
23
  --color-primary-hover: var(--primary-hover);
24
24
  --color-ring: var(--ring);
25
25
  --color-danger: var(--danger);
26
+ --color-danger-hover: var(--danger-hover);
26
27
  --color-danger-foreground: var(--danger-foreground);
27
28
  --color-success: var(--success);
28
29
  --color-success-foreground: var(--success-foreground);
@@ -27,6 +27,7 @@
27
27
  --color-primary-hover: var(--primary-hover);
28
28
  --color-ring: var(--ring);
29
29
  --color-danger: var(--danger);
30
+ --color-danger-hover: var(--danger-hover);
30
31
  --color-danger-foreground: var(--danger-foreground);
31
32
  --color-success: var(--success);
32
33
  --color-success-foreground: var(--success-foreground);
@@ -18,6 +18,7 @@
18
18
  --primary-hover: #262626;
19
19
  --ring: color-mix(in srgb, var(--primary) 50%, transparent);
20
20
  --danger: #DC2626;
21
+ --danger-hover: color-mix(in srgb, var(--danger) 90%, black);
21
22
  --danger-foreground: #FFFFFF;
22
23
  }
23
24
  @media (prefers-color-scheme: dark) {
@@ -36,6 +37,7 @@
36
37
  --primary-foreground: #171717;
37
38
  --primary-hover: #E5E5E5;
38
39
  --danger: #DC2626;
40
+ --danger-hover: color-mix(in srgb, var(--danger) 90%, black);
39
41
  --danger-foreground: #FFFFFF;
40
42
  }
41
43
  }
@@ -54,6 +56,7 @@
54
56
  --primary-foreground: #171717;
55
57
  --primary-hover: #E5E5E5;
56
58
  --danger: #DC2626;
59
+ --danger-hover: color-mix(in srgb, var(--danger) 90%, black);
57
60
  --danger-foreground: #FFFFFF;
58
61
  }
59
62
  /* sh-ui:theme-colors-end */