sh-ui-cli 0.59.5 → 0.59.6
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 +14 -0
- package/data/registry/react/components/checkbox/index.tailwind.tsx +1 -1
- package/data/registry/react/components/radio/index.tailwind.tsx +2 -2
- package/data/registry/react/components/switch/index.tailwind.tsx +2 -2
- package/data/registry/react/components/tabs/index.tailwind.tsx +3 -3
- package/data/registry/react/components/toggle/index.tailwind.tsx +1 -1
- package/package.json +1 -1
|
@@ -2,6 +2,20 @@
|
|
|
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.6",
|
|
7
|
+
"date": "2026-05-06",
|
|
8
|
+
"title": "접근성 라운드 6 — Tailwind variant forced-colors",
|
|
9
|
+
"type": "patch",
|
|
10
|
+
"highlights": [
|
|
11
|
+
"**Tailwind variant 의 5 컴포넌트에 `forced-colors:` utility 추가** — Checkbox / Radio / Switch / Tabs / Toggle. v0.59.4 에서 plain CSS · CSS Modules variant 에만 들어갔던 시스템 컬러 폴백을 Tailwind 사용자도 동일하게 받음.",
|
|
12
|
+
"**arbitrary property 문법 사용** — `forced-colors:[border-color:ButtonBorder]`, `forced-colors:data-[checked]:[background:Highlight]` 등. system color identifier 는 Tailwind 색상 토큰이 아니라 CSS 키워드라 arbitrary 가 가장 안전.",
|
|
13
|
+
"**Switch Thumb 분리 처리** — 스위치 토글의 thumb (이동하는 원) 도 별도 cva. `forced-colors:[background:ButtonText]` 기본 + `data-[checked]:[background:HighlightText]` 로 on 상태 구분.",
|
|
14
|
+
"**prefers-contrast: high** — 추가 작업 0. 토큰 레벨에서 처리되므로 Tailwind 의 `bg-primary`/`border-border` 같은 utility 가 자동으로 강화된 값을 픽업.",
|
|
15
|
+
"**일관성 회복** — 이제 3 variant (plain · CSS Modules · Tailwind) 모두 동일한 접근성 fallback 보유."
|
|
16
|
+
],
|
|
17
|
+
"url": "https://github.com/sanghyeonKim0201/sh-ui/releases/tag/v0.59.6"
|
|
18
|
+
},
|
|
5
19
|
{
|
|
6
20
|
"version": "0.59.5",
|
|
7
21
|
"date": "2026-05-06",
|
|
@@ -16,7 +16,7 @@ export const Checkbox = React.forwardRef<HTMLElement, CheckboxProps>(
|
|
|
16
16
|
<BaseCheckbox.Root
|
|
17
17
|
ref={ref}
|
|
18
18
|
className={cn(
|
|
19
|
-
"inline-flex items-center justify-center w-[1.125rem] h-[1.125rem] border border-border-strong rounded-[calc(var(--radius)-2px)] bg-background text-primary-foreground cursor-pointer shrink-0 transition-[background-color,border-color] duration-[var(--duration-fast)] hover:not-data-[disabled]:border-foreground focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 data-[checked]:bg-primary data-[checked]:border-primary data-[indeterminate]:bg-primary data-[indeterminate]:border-primary data-[disabled]:opacity-[var(--opacity-disabled)] data-[disabled]:cursor-not-allowed motion-reduce:transition-none [@media(hover:none)_and_(pointer:coarse)]:w-5 [@media(hover:none)_and_(pointer:coarse)]:h-5",
|
|
19
|
+
"inline-flex items-center justify-center w-[1.125rem] h-[1.125rem] border border-border-strong rounded-[calc(var(--radius)-2px)] bg-background text-primary-foreground cursor-pointer shrink-0 transition-[background-color,border-color] duration-[var(--duration-fast)] hover:not-data-[disabled]:border-foreground focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 data-[checked]:bg-primary data-[checked]:border-primary data-[indeterminate]:bg-primary data-[indeterminate]:border-primary data-[disabled]:opacity-[var(--opacity-disabled)] data-[disabled]:cursor-not-allowed motion-reduce:transition-none [@media(hover:none)_and_(pointer:coarse)]:w-5 [@media(hover:none)_and_(pointer:coarse)]:h-5 forced-colors:[border-color:ButtonBorder] forced-colors:focus-visible:[outline-color:Highlight] forced-colors:data-[checked]:[background:Highlight] forced-colors:data-[checked]:[border-color:Highlight] forced-colors:data-[checked]:[color:HighlightText] forced-colors:data-[indeterminate]:[background:Highlight] forced-colors:data-[indeterminate]:[border-color:Highlight] forced-colors:data-[indeterminate]:[color:HighlightText] forced-colors:data-[disabled]:[border-color:GrayText] forced-colors:data-[disabled]:[color:GrayText]",
|
|
20
20
|
className,
|
|
21
21
|
)}
|
|
22
22
|
{...props}
|
|
@@ -16,12 +16,12 @@ export const Radio = React.forwardRef<HTMLElement, RadioProps>(
|
|
|
16
16
|
<BaseRadio.Root
|
|
17
17
|
ref={ref}
|
|
18
18
|
className={cn(
|
|
19
|
-
"inline-flex items-center justify-center w-[1.125rem] h-[1.125rem] border border-border-strong rounded-full bg-background cursor-pointer shrink-0 transition-[border-color] duration-[var(--duration-fast)] hover:not-data-[disabled]:border-foreground focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 data-[checked]:border-primary data-[disabled]:opacity-[var(--opacity-disabled)] data-[disabled]:cursor-not-allowed motion-reduce:transition-none [@media(hover:none)_and_(pointer:coarse)]:w-5 [@media(hover:none)_and_(pointer:coarse)]:h-5",
|
|
19
|
+
"inline-flex items-center justify-center w-[1.125rem] h-[1.125rem] border border-border-strong rounded-full bg-background cursor-pointer shrink-0 transition-[border-color] duration-[var(--duration-fast)] hover:not-data-[disabled]:border-foreground focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 data-[checked]:border-primary data-[disabled]:opacity-[var(--opacity-disabled)] data-[disabled]:cursor-not-allowed motion-reduce:transition-none [@media(hover:none)_and_(pointer:coarse)]:w-5 [@media(hover:none)_and_(pointer:coarse)]:h-5 forced-colors:[border-color:ButtonBorder] forced-colors:focus-visible:[outline-color:Highlight] forced-colors:data-[checked]:[border-color:Highlight] forced-colors:data-[disabled]:[border-color:GrayText]",
|
|
20
20
|
className,
|
|
21
21
|
)}
|
|
22
22
|
{...props}
|
|
23
23
|
>
|
|
24
|
-
<BaseRadio.Indicator className="w-2 h-2 rounded-full bg-primary scale-0 transition-transform duration-[var(--duration-fast)] ease-out data-[checked]:scale-100 motion-reduce:transition-none" />
|
|
24
|
+
<BaseRadio.Indicator className="w-2 h-2 rounded-full bg-primary scale-0 transition-transform duration-[var(--duration-fast)] ease-out data-[checked]:scale-100 motion-reduce:transition-none forced-colors:[background:Highlight] forced-colors:group-data-[disabled]:[background:GrayText]" />
|
|
25
25
|
</BaseRadio.Root>
|
|
26
26
|
),
|
|
27
27
|
);
|
|
@@ -5,7 +5,7 @@ import { cva, type VariantProps } from "class-variance-authority";
|
|
|
5
5
|
|
|
6
6
|
import { cn } from "@SH_UI_UTILS@";
|
|
7
7
|
const switchRoot = cva(
|
|
8
|
-
"inline-flex items-center border-none rounded-full bg-background-muted cursor-pointer shrink-0 p-0.5 transition-colors duration-150 hover:not-data-[disabled]:bg-border-strong focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 data-[checked]:bg-primary data-[checked]:hover:not-data-[disabled]:bg-primary-hover data-[disabled]:opacity-[var(--opacity-disabled)] data-[disabled]:cursor-not-allowed motion-reduce:transition-none",
|
|
8
|
+
"inline-flex items-center border-none rounded-full bg-background-muted cursor-pointer shrink-0 p-0.5 transition-colors duration-150 hover:not-data-[disabled]:bg-border-strong focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 data-[checked]:bg-primary data-[checked]:hover:not-data-[disabled]:bg-primary-hover data-[disabled]:opacity-[var(--opacity-disabled)] data-[disabled]:cursor-not-allowed motion-reduce:transition-none forced-colors:[border:1px_solid_ButtonBorder] forced-colors:[background:ButtonFace] forced-colors:focus-visible:[outline-color:Highlight] forced-colors:data-[checked]:[background:Highlight] forced-colors:data-[checked]:[border-color:Highlight] forced-colors:data-[disabled]:[border-color:GrayText]",
|
|
9
9
|
{
|
|
10
10
|
variants: {
|
|
11
11
|
size: {
|
|
@@ -18,7 +18,7 @@ const switchRoot = cva(
|
|
|
18
18
|
);
|
|
19
19
|
|
|
20
20
|
const switchThumb = cva(
|
|
21
|
-
"block rounded-full bg-white shadow-[0_1px_2px_rgba(0,0,0,0.12)] transition-transform duration-150 ease-out motion-reduce:transition-none",
|
|
21
|
+
"block rounded-full bg-white shadow-[0_1px_2px_rgba(0,0,0,0.12)] transition-transform duration-150 ease-out motion-reduce:transition-none forced-colors:[background:ButtonText] forced-colors:data-[checked]:[background:HighlightText] forced-colors:data-[disabled]:[background:GrayText]",
|
|
22
22
|
{
|
|
23
23
|
variants: {
|
|
24
24
|
size: {
|
|
@@ -65,7 +65,7 @@ export const TabsTrigger = React.forwardRef<
|
|
|
65
65
|
<BaseTabs.Tab
|
|
66
66
|
ref={ref}
|
|
67
67
|
className={cn(
|
|
68
|
-
"relative z-[1] inline-flex items-center justify-center gap-1.5 py-[var(--space-2)] px-[var(--space-3)] bg-transparent text-foreground-muted border-0 text-[length:var(--text-sm)] font-medium leading-none cursor-pointer transition-[color,background-color] duration-[var(--duration-fast)] select-none whitespace-nowrap hover:not-disabled:not-data-[selected]:text-foreground focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 data-[selected]:text-foreground disabled:opacity-[var(--opacity-disabled)] disabled:cursor-not-allowed",
|
|
68
|
+
"relative z-[1] inline-flex items-center justify-center gap-1.5 py-[var(--space-2)] px-[var(--space-3)] bg-transparent text-foreground-muted border-0 text-[length:var(--text-sm)] font-medium leading-none cursor-pointer transition-[color,background-color] duration-[var(--duration-fast)] select-none whitespace-nowrap hover:not-disabled:not-data-[selected]:text-foreground focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 data-[selected]:text-foreground disabled:opacity-[var(--opacity-disabled)] disabled:cursor-not-allowed forced-colors:focus-visible:[outline-color:Highlight] forced-colors:data-[selected]:[color:Highlight] forced-colors:data-[selected]:[[data-variant=plain]_&]:[outline:1px_solid_Highlight]",
|
|
69
69
|
triggerVariantClasses,
|
|
70
70
|
className,
|
|
71
71
|
)}
|
|
@@ -75,7 +75,7 @@ export const TabsTrigger = React.forwardRef<
|
|
|
75
75
|
TabsTrigger.displayName = "TabsTrigger";
|
|
76
76
|
|
|
77
77
|
const indicatorVariantClasses =
|
|
78
|
-
"[[data-variant=underline]_&]:shadow-[inset_0_-2px_0_var(--primary)] [[data-variant=pill]_&]:bg-background [[data-variant=pill]_&]:rounded-[calc(var(--radius)-2px)] [[data-variant=pill]_&]:shadow-[0_1px_2px_rgba(0,0,0,0.06)] [[data-variant=plain]_&]:hidden [[data-orientation=vertical][data-variant=underline]_&]:shadow-[inset_-2px_0_0_var(--primary)]";
|
|
78
|
+
"[[data-variant=underline]_&]:shadow-[inset_0_-2px_0_var(--primary)] [[data-variant=pill]_&]:bg-background [[data-variant=pill]_&]:rounded-[calc(var(--radius)-2px)] [[data-variant=pill]_&]:shadow-[0_1px_2px_rgba(0,0,0,0.06)] [[data-variant=plain]_&]:hidden [[data-orientation=vertical][data-variant=underline]_&]:shadow-[inset_-2px_0_0_var(--primary)] forced-colors:[[data-variant=underline]_&]:shadow-[inset_0_-2px_0_Highlight] forced-colors:[[data-variant=pill]_&]:[border:1px_solid_Highlight] forced-colors:[[data-variant=pill]_&]:[background:ButtonFace] forced-colors:[[data-orientation=vertical][data-variant=underline]_&]:shadow-[inset_-2px_0_0_Highlight]";
|
|
79
79
|
|
|
80
80
|
export const TabsIndicator = React.forwardRef<
|
|
81
81
|
HTMLSpanElement,
|
|
@@ -100,7 +100,7 @@ export const TabsContent = React.forwardRef<
|
|
|
100
100
|
<BaseTabs.Panel
|
|
101
101
|
ref={ref}
|
|
102
102
|
className={cn(
|
|
103
|
-
"outline-none focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 focus-visible:rounded-[var(--radius)]",
|
|
103
|
+
"outline-none focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 focus-visible:rounded-[var(--radius)] forced-colors:focus-visible:[outline-color:Highlight]",
|
|
104
104
|
className,
|
|
105
105
|
)}
|
|
106
106
|
{...props}
|
|
@@ -8,7 +8,7 @@ import { cva, type VariantProps } from "class-variance-authority";
|
|
|
8
8
|
|
|
9
9
|
import { cn } from "@SH_UI_UTILS@";
|
|
10
10
|
const toggleVariants = cva(
|
|
11
|
-
"inline-flex items-center justify-center gap-1.5 border border-transparent rounded-[var(--radius)] font-medium leading-none cursor-pointer text-foreground-muted bg-transparent transition-[background-color,color,border-color] duration-[var(--duration-fast)] select-none focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 disabled:opacity-[var(--opacity-disabled)] disabled:pointer-events-none data-[pressed]:bg-background-muted data-[pressed]:text-foreground motion-reduce:transition-none",
|
|
11
|
+
"inline-flex items-center justify-center gap-1.5 border border-transparent rounded-[var(--radius)] font-medium leading-none cursor-pointer text-foreground-muted bg-transparent transition-[background-color,color,border-color] duration-[var(--duration-fast)] select-none focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 disabled:opacity-[var(--opacity-disabled)] disabled:pointer-events-none data-[pressed]:bg-background-muted data-[pressed]:text-foreground motion-reduce:transition-none forced-colors:focus-visible:[outline-color:Highlight] forced-colors:data-[pressed]:[background:Highlight] forced-colors:data-[pressed]:[color:HighlightText] forced-colors:data-[pressed]:[border-color:Highlight] forced-colors:disabled:[color:GrayText] forced-colors:disabled:[border-color:GrayText]",
|
|
12
12
|
{
|
|
13
13
|
variants: {
|
|
14
14
|
variant: {
|