sh-ui-cli 0.59.5 → 0.59.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.
- package/data/changelog/versions.json +28 -0
- package/data/registry/react/components/checkbox/index.tailwind.tsx +1 -1
- package/data/registry/react/components/combobox/index.tailwind.tsx +1 -1
- package/data/registry/react/components/combobox/styles.css +1 -1
- package/data/registry/react/components/combobox/styles.module.css +1 -1
- package/data/registry/react/components/context-menu/index.tailwind.tsx +1 -1
- package/data/registry/react/components/date-picker/index.tailwind.tsx +1 -1
- package/data/registry/react/components/date-picker/styles.css +1 -1
- package/data/registry/react/components/date-picker/styles.module.css +1 -1
- package/data/registry/react/components/dropdown-menu/index.tailwind.tsx +1 -1
- package/data/registry/react/components/menubar/index.tailwind.tsx +1 -1
- package/data/registry/react/components/menubar/styles.css +1 -1
- package/data/registry/react/components/menubar/styles.module.css +1 -1
- package/data/registry/react/components/popover/index.tailwind.tsx +1 -1
- package/data/registry/react/components/popover/styles.css +1 -1
- package/data/registry/react/components/popover/styles.module.css +1 -1
- package/data/registry/react/components/radio/index.tailwind.tsx +2 -2
- package/data/registry/react/components/select/index.tailwind.tsx +1 -1
- package/data/registry/react/components/sidebar/index.tailwind.tsx +1 -1
- package/data/registry/react/components/sidebar/styles.css +1 -1
- package/data/registry/react/components/sidebar/styles.module.css +1 -1
- package/data/registry/react/components/slider/index.tailwind.tsx +1 -1
- package/data/registry/react/components/slider/styles.css +1 -1
- package/data/registry/react/components/slider/styles.module.css +1 -1
- package/data/registry/react/components/switch/index.tailwind.tsx +2 -2
- package/data/registry/react/components/switch/styles.css +1 -1
- package/data/registry/react/components/switch/styles.module.css +1 -1
- package/data/registry/react/components/tabs/index.tailwind.tsx +3 -3
- package/data/registry/react/components/tabs/styles.css +1 -1
- package/data/registry/react/components/tabs/styles.module.css +1 -1
- package/data/registry/react/components/toast/index.tailwind.tsx +1 -1
- package/data/registry/react/components/toast/styles.css +1 -1
- package/data/registry/react/components/toast/styles.module.css +1 -1
- package/data/registry/react/components/toggle/index.tailwind.tsx +1 -1
- package/package.json +1 -1
- package/src/create/theme/inject.js +4 -1
- package/templates/nextjs-standalone/_arch/flat/lib/styles/tokens.css +1 -0
- package/templates/nextjs-standalone/_arch/fsd/src/shared/styles/tokens.css +1 -0
- package/templates/ui-app-template/src/styles/tokens.css +1 -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.59.7",
|
|
7
|
+
"date": "2026-05-06",
|
|
8
|
+
"title": "라운드 7 — Shadow 토큰 일관화",
|
|
9
|
+
"type": "patch",
|
|
10
|
+
"highlights": [
|
|
11
|
+
"**하드코딩된 `box-shadow: ... rgba(0,0,0,X)` 를 토큰으로 교체** — 11+ 컴포넌트가 직접 알파 값을 박아 두던 그림자를 `var(--shadow-sm/md/lg/xl)` 로 통일. 토큰 정의(`tokens.css`)만 바꾸면 전체 조정 가능.",
|
|
12
|
+
"**`--shadow-menu` 신규 토큰** — 드롭다운/콘텍스트 메뉴/셀렉트의 multi-layer crispy 그림자(`0 4px 6px -1px ..., 0 2px 4px -2px ...`)는 단일 sm/md 와 다른 elevation 시그니처라 별도 토큰화. 4 tokens.css 위치 + inject.js 에 추가.",
|
|
13
|
+
"**대상 컴포넌트** — Combobox / Context-Menu / Date-Picker / Dropdown-Menu / Menubar / Popover / Select / Sidebar / Slider / Switch / Tabs / Toast.",
|
|
14
|
+
"**유지한 예외** — Color-picker thumb 의 `0 0 0 1px rgba(0,0,0,0.4)` 는 그림자가 아니라 어떤 색 위에서도 보여야 하는 1px 테두리. Header dropdown 의 `0 8px 24px -8px ...` 는 negative spread 가 의도적 (사이드 절단).",
|
|
15
|
+
"**다크 모드 영향** — 토큰화로 향후 다크 전용 shadow 값 분기 (예: 더 강한 알파 + 컬러 시프트) 가 1 라인 변경으로 가능."
|
|
16
|
+
],
|
|
17
|
+
"url": "https://github.com/sanghyeonKim0201/sh-ui/releases/tag/v0.59.7"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"version": "0.59.6",
|
|
21
|
+
"date": "2026-05-06",
|
|
22
|
+
"title": "접근성 라운드 6 — Tailwind variant forced-colors",
|
|
23
|
+
"type": "patch",
|
|
24
|
+
"highlights": [
|
|
25
|
+
"**Tailwind variant 의 5 컴포넌트에 `forced-colors:` utility 추가** — Checkbox / Radio / Switch / Tabs / Toggle. v0.59.4 에서 plain CSS · CSS Modules variant 에만 들어갔던 시스템 컬러 폴백을 Tailwind 사용자도 동일하게 받음.",
|
|
26
|
+
"**arbitrary property 문법 사용** — `forced-colors:[border-color:ButtonBorder]`, `forced-colors:data-[checked]:[background:Highlight]` 등. system color identifier 는 Tailwind 색상 토큰이 아니라 CSS 키워드라 arbitrary 가 가장 안전.",
|
|
27
|
+
"**Switch Thumb 분리 처리** — 스위치 토글의 thumb (이동하는 원) 도 별도 cva. `forced-colors:[background:ButtonText]` 기본 + `data-[checked]:[background:HighlightText]` 로 on 상태 구분.",
|
|
28
|
+
"**prefers-contrast: high** — 추가 작업 0. 토큰 레벨에서 처리되므로 Tailwind 의 `bg-primary`/`border-border` 같은 utility 가 자동으로 강화된 값을 픽업.",
|
|
29
|
+
"**일관성 회복** — 이제 3 variant (plain · CSS Modules · Tailwind) 모두 동일한 접근성 fallback 보유."
|
|
30
|
+
],
|
|
31
|
+
"url": "https://github.com/sanghyeonKim0201/sh-ui/releases/tag/v0.59.6"
|
|
32
|
+
},
|
|
5
33
|
{
|
|
6
34
|
"version": "0.59.5",
|
|
7
35
|
"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}
|
|
@@ -48,7 +48,7 @@ export const ComboboxContent = React.forwardRef<
|
|
|
48
48
|
<BaseCombobox.Popup
|
|
49
49
|
ref={ref}
|
|
50
50
|
className={cn(
|
|
51
|
-
"max-h-[min(20rem,var(--available-height))] overflow-y-auto p-[var(--space-1)] bg-background text-foreground border border-border rounded-[var(--radius)] shadow-[
|
|
51
|
+
"max-h-[min(20rem,var(--available-height))] overflow-y-auto p-[var(--space-1)] bg-background text-foreground border border-border rounded-[var(--radius)] shadow-[var(--shadow-lg)] outline-none origin-[var(--transform-origin)] transition-[opacity,transform] duration-[140ms] ease-out motion-reduce:transition-none data-[starting-style]:opacity-0 data-[starting-style]:scale-[0.97] data-[ending-style]:opacity-0 data-[ending-style]:scale-[0.97]",
|
|
52
52
|
className,
|
|
53
53
|
)}
|
|
54
54
|
{...props}
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
color: var(--foreground);
|
|
45
45
|
border: 1px solid var(--border);
|
|
46
46
|
border-radius: var(--radius);
|
|
47
|
-
box-shadow:
|
|
47
|
+
box-shadow: var(--shadow-lg);
|
|
48
48
|
outline: none;
|
|
49
49
|
transform-origin: var(--transform-origin);
|
|
50
50
|
transition: opacity 140ms ease, transform 140ms ease;
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
color: var(--foreground);
|
|
45
45
|
border: 1px solid var(--border);
|
|
46
46
|
border-radius: var(--radius);
|
|
47
|
-
box-shadow:
|
|
47
|
+
box-shadow: var(--shadow-lg);
|
|
48
48
|
outline: none;
|
|
49
49
|
transform-origin: var(--transform-origin);
|
|
50
50
|
transition: opacity 140ms ease, transform 140ms ease;
|
|
@@ -9,7 +9,7 @@ const itemBase =
|
|
|
9
9
|
"relative flex items-center gap-[var(--space-2)] py-2 px-3 rounded-[calc(var(--radius)-2px)] cursor-pointer outline-none select-none transition-colors duration-[80ms] data-[highlighted]:bg-background-muted hover:bg-background-muted data-[disabled]:opacity-[var(--opacity-disabled)] data-[disabled]:pointer-events-none motion-reduce:transition-none";
|
|
10
10
|
const itemCheck = "pl-7";
|
|
11
11
|
const contentClasses =
|
|
12
|
-
"min-w-40 max-h-[min(24rem,var(--available-height,24rem))] overflow-y-auto p-[var(--space-1)] bg-background text-foreground border border-border rounded-[var(--radius)] shadow-[
|
|
12
|
+
"min-w-40 max-h-[min(24rem,var(--available-height,24rem))] overflow-y-auto p-[var(--space-1)] bg-background text-foreground border border-border rounded-[var(--radius)] shadow-[var(--shadow-menu)] text-[length:var(--text-sm)] origin-[var(--transform-origin)] animate-[sh-ui-cm-in_140ms_ease-out] data-[ending-style]:animate-[sh-ui-cm-out_100ms_ease-in_forwards] outline-none motion-reduce:animate-none motion-reduce:data-[ending-style]:animate-none";
|
|
13
13
|
|
|
14
14
|
export const ContextMenu = BaseContextMenu.Root;
|
|
15
15
|
|
|
@@ -25,7 +25,7 @@ const triggerClasses =
|
|
|
25
25
|
"inline-flex items-center justify-between w-full h-[var(--control-md)] px-[var(--space-3)] bg-background text-foreground border border-border rounded-[var(--radius)] font-[inherit] text-[length:var(--text-sm)] leading-none cursor-pointer transition-[border-color,box-shadow] duration-[var(--duration-fast)] hover:not-disabled:border-border-strong focus-visible:outline-none focus-visible:border-primary focus-visible:shadow-[0_0_0_1px_var(--primary)] disabled:opacity-[var(--opacity-disabled)] disabled:cursor-not-allowed disabled:bg-background-subtle aria-[invalid=true]:border-danger aria-[invalid=true]:focus-visible:shadow-[0_0_0_1px_var(--danger)] [@media(hover:none)_and_(pointer:coarse)]:h-11 [@media(hover:none)_and_(pointer:coarse)]:text-[length:var(--text-base)]";
|
|
26
26
|
|
|
27
27
|
const popupClasses =
|
|
28
|
-
"bg-background border border-border rounded-[var(--radius)] shadow-[
|
|
28
|
+
"bg-background border border-border rounded-[var(--radius)] shadow-[var(--shadow-lg)] outline-none p-[var(--space-3)] origin-[var(--transform-origin)] transition-[opacity,transform] duration-[140ms] 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";
|
|
29
29
|
|
|
30
30
|
function CalendarIcon() {
|
|
31
31
|
return (
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
background: var(--background);
|
|
78
78
|
border: 1px solid var(--border);
|
|
79
79
|
border-radius: var(--radius);
|
|
80
|
-
box-shadow:
|
|
80
|
+
box-shadow: var(--shadow-lg);
|
|
81
81
|
outline: none;
|
|
82
82
|
padding: var(--space-3);
|
|
83
83
|
transform-origin: var(--transform-origin);
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
background: var(--background);
|
|
78
78
|
border: 1px solid var(--border);
|
|
79
79
|
border-radius: var(--radius);
|
|
80
|
-
box-shadow:
|
|
80
|
+
box-shadow: var(--shadow-lg);
|
|
81
81
|
outline: none;
|
|
82
82
|
padding: var(--space-3);
|
|
83
83
|
transform-origin: var(--transform-origin);
|
|
@@ -53,7 +53,7 @@ export const DropdownMenuContent = React.forwardRef<HTMLDivElement, DropdownMenu
|
|
|
53
53
|
<BaseMenu.Popup
|
|
54
54
|
ref={ref}
|
|
55
55
|
className={cn(
|
|
56
|
-
"min-w-40 max-h-[min(24rem,var(--available-height,24rem))] overflow-y-auto p-[var(--space-1)] bg-background text-foreground border border-border rounded-[var(--radius)] shadow-[
|
|
56
|
+
"min-w-40 max-h-[min(24rem,var(--available-height,24rem))] overflow-y-auto p-[var(--space-1)] bg-background text-foreground border border-border rounded-[var(--radius)] shadow-[var(--shadow-menu)] text-[length:var(--text-sm)] origin-[var(--transform-origin)] animate-[sh-ui-dm-in_140ms_ease-out] data-[ending-style]:animate-[sh-ui-dm-out_100ms_ease-in_forwards] outline-none motion-reduce:animate-none motion-reduce:data-[ending-style]:animate-none",
|
|
57
57
|
className,
|
|
58
58
|
)}
|
|
59
59
|
{...props}
|
|
@@ -21,7 +21,7 @@ export const Menubar = React.forwardRef<
|
|
|
21
21
|
<BaseMenubar
|
|
22
22
|
ref={ref}
|
|
23
23
|
className={cn(
|
|
24
|
-
"inline-flex items-center gap-[var(--space-1)] p-[var(--space-1)] bg-background border border-border rounded-[var(--radius)] shadow-[
|
|
24
|
+
"inline-flex items-center gap-[var(--space-1)] p-[var(--space-1)] bg-background border border-border rounded-[var(--radius)] shadow-[var(--shadow-sm)]",
|
|
25
25
|
className,
|
|
26
26
|
)}
|
|
27
27
|
{...props}
|
|
@@ -34,7 +34,7 @@ export const PopoverContent = React.forwardRef<HTMLDivElement, PopoverContentPro
|
|
|
34
34
|
<BasePopover.Popup
|
|
35
35
|
ref={ref}
|
|
36
36
|
className={cn(
|
|
37
|
-
"min-w-48 p-[var(--space-2)] bg-background text-foreground border border-border rounded-[var(--radius)] shadow-[
|
|
37
|
+
"min-w-48 p-[var(--space-2)] bg-background text-foreground border border-border rounded-[var(--radius)] shadow-[var(--shadow-lg)] outline-none text-[length:var(--text-sm)] leading-snug origin-[var(--transform-origin)] transition-[opacity,transform] duration-[140ms] 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 focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2",
|
|
38
38
|
className,
|
|
39
39
|
)}
|
|
40
40
|
{...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
|
);
|
|
@@ -60,7 +60,7 @@ export const SelectContent = React.forwardRef<
|
|
|
60
60
|
<BaseSelect.Popup
|
|
61
61
|
ref={ref}
|
|
62
62
|
className={cn(
|
|
63
|
-
"min-w-[var(--anchor-width,10rem)] max-h-[min(24rem,var(--available-height,24rem))] overflow-y-auto p-[var(--space-1)] bg-background text-foreground border border-border rounded-[var(--radius)] shadow-[
|
|
63
|
+
"min-w-[var(--anchor-width,10rem)] max-h-[min(24rem,var(--available-height,24rem))] overflow-y-auto p-[var(--space-1)] bg-background text-foreground border border-border rounded-[var(--radius)] shadow-[var(--shadow-menu)] text-[length:var(--text-sm)] origin-[var(--transform-origin)] animate-[sh-ui-select-in_140ms_ease-out] data-[ending-style]:animate-[sh-ui-select-out_100ms_ease-in_forwards] motion-reduce:animate-none motion-reduce:data-[ending-style]:animate-none",
|
|
64
64
|
className,
|
|
65
65
|
)}
|
|
66
66
|
{...props}
|
|
@@ -262,7 +262,7 @@ export function SidebarPanel({ id, className, children, ...props }: SidebarPanel
|
|
|
262
262
|
return (
|
|
263
263
|
<aside
|
|
264
264
|
ref={ref}
|
|
265
|
-
className={cn("[--sidebar-panel-width:20rem] flex flex-col w-[var(--sidebar-panel-width)] shrink-0 bg-background border-r border-[var(--sidebar-border)] relative z-[4] overflow-hidden animate-[sh-ui-sidebar-panel-in_180ms_ease-out] data-[state=closed]:hidden max-md:fixed max-md:top-0 max-md:bottom-0 max-md:left-0 max-md:w-[min(var(--sidebar-panel-width),90vw)] max-md:z-[var(--z-modal)] max-md:shadow-[
|
|
265
|
+
className={cn("[--sidebar-panel-width:20rem] flex flex-col w-[var(--sidebar-panel-width)] shrink-0 bg-background border-r border-[var(--sidebar-border)] relative z-[4] overflow-hidden animate-[sh-ui-sidebar-panel-in_180ms_ease-out] data-[state=closed]:hidden max-md:fixed max-md:top-0 max-md:bottom-0 max-md:left-0 max-md:w-[min(var(--sidebar-panel-width),90vw)] max-md:z-[var(--z-modal)] max-md:shadow-[var(--shadow-xl)] motion-reduce:animate-none",
|
|
266
266
|
className)}
|
|
267
267
|
data-state={open ? "open" : "closed"}
|
|
268
268
|
role={isMobile ? "dialog" : undefined}
|
|
@@ -244,7 +244,7 @@
|
|
|
244
244
|
width: min(var(--sidebar-panel-width), 90vw);
|
|
245
245
|
z-index: var(--z-modal);
|
|
246
246
|
border-inline-end: 1px solid var(--sidebar-border);
|
|
247
|
-
box-shadow:
|
|
247
|
+
box-shadow: var(--shadow-xl);
|
|
248
248
|
}
|
|
249
249
|
}
|
|
250
250
|
.sh-ui-sidebar-wrapper[data-embedded] .sh-ui-sidebar__panel {
|
|
@@ -244,7 +244,7 @@
|
|
|
244
244
|
width: min(var(--sidebar-panel-width), 90vw);
|
|
245
245
|
z-index: var(--z-modal);
|
|
246
246
|
border-inline-end: 1px solid var(--sidebar-border);
|
|
247
|
-
box-shadow:
|
|
247
|
+
box-shadow: var(--shadow-xl);
|
|
248
248
|
}
|
|
249
249
|
}
|
|
250
250
|
.sidebar-wrapper[data-embedded] .sidebar__panel {
|
|
@@ -242,7 +242,7 @@ export const SliderThumb = React.forwardRef<
|
|
|
242
242
|
aria-disabled={disabled || undefined}
|
|
243
243
|
onKeyDown={onKeyDown}
|
|
244
244
|
className={cn(
|
|
245
|
-
"absolute top-1/2 w-4 h-4 -ml-2 -translate-y-1/2 bg-background border-2 border-primary rounded-full shadow-[
|
|
245
|
+
"absolute top-1/2 w-4 h-4 -ml-2 -translate-y-1/2 bg-background border-2 border-primary rounded-full shadow-[var(--shadow-sm)] cursor-grab transition-transform duration-[80ms] active:cursor-grabbing active:scale-110 active:-translate-y-1/2 focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 [@media(hover:none)_and_(pointer:coarse)]:w-5 [@media(hover:none)_and_(pointer:coarse)]:h-5 [@media(hover:none)_and_(pointer:coarse)]:-ml-2.5",
|
|
246
246
|
className,
|
|
247
247
|
)}
|
|
248
248
|
style={{ left: percent, ...style }}
|
|
@@ -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-[
|
|
21
|
+
"block rounded-full bg-white shadow-[var(--shadow-sm)] 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-[
|
|
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-[var(--shadow-sm)] [[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}
|
|
@@ -130,7 +130,7 @@
|
|
|
130
130
|
height: var(--active-tab-height);
|
|
131
131
|
background: var(--background);
|
|
132
132
|
border-radius: calc(var(--radius) - 2px);
|
|
133
|
-
box-shadow:
|
|
133
|
+
box-shadow: var(--shadow-sm);
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
/* ─────────────── variant: plain (컨테이너 없음) ─────────────── */
|
|
@@ -130,7 +130,7 @@
|
|
|
130
130
|
height: var(--active-tab-height);
|
|
131
131
|
background: var(--background);
|
|
132
132
|
border-radius: calc(var(--radius) - 2px);
|
|
133
|
-
box-shadow:
|
|
133
|
+
box-shadow: var(--shadow-sm);
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
/* ─────────────── variant: plain (컨테이너 없음) ─────────────── */
|
|
@@ -107,7 +107,7 @@ function ToastCard({ item, onDismiss }: { item: ToastItem; onDismiss: () => void
|
|
|
107
107
|
|
|
108
108
|
return (
|
|
109
109
|
<div
|
|
110
|
-
className="sh-ui-toast relative flex items-start gap-2.5 w-full pl-[var(--space-3)] pr-9 py-[var(--space-3)] bg-background text-foreground border border-border rounded-[var(--radius)] shadow-[
|
|
110
|
+
className="sh-ui-toast relative flex items-start gap-2.5 w-full pl-[var(--space-3)] pr-9 py-[var(--space-3)] bg-background text-foreground border border-border rounded-[var(--radius)] shadow-[var(--shadow-md)] pointer-events-auto motion-reduce:!animate-none"
|
|
111
111
|
role={item.variant === "danger" ? "alert" : "status"}
|
|
112
112
|
aria-live={item.variant === "danger" ? "assertive" : "polite"}
|
|
113
113
|
data-exiting={exiting || undefined}
|
|
@@ -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: {
|
package/package.json
CHANGED
|
@@ -303,7 +303,10 @@ const colorToARGBHex = ({ a, r, g, b }) => {
|
|
|
303
303
|
const SHADOW_KEYS = ['sm', 'md', 'lg', 'xl'];
|
|
304
304
|
|
|
305
305
|
export const buildCssShadowsBlock = (shadows) =>
|
|
306
|
-
|
|
306
|
+
[
|
|
307
|
+
...SHADOW_KEYS.map((k) => ` --shadow-${k}: ${shadows[k]};`),
|
|
308
|
+
` --shadow-menu: 0 4px 6px -1px rgba(0, 0, 0, 0.08), 0 2px 4px -2px rgba(0, 0, 0, 0.05);`,
|
|
309
|
+
].join('\n');
|
|
307
310
|
|
|
308
311
|
const parseSingleBoxShadow = (s) => {
|
|
309
312
|
const tokens = tokenizeSpaceAware(s);
|
|
@@ -99,6 +99,7 @@
|
|
|
99
99
|
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.12);
|
|
100
100
|
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.15);
|
|
101
101
|
--shadow-xl: 0 16px 48px rgba(0, 0, 0, 0.18);
|
|
102
|
+
--shadow-menu: 0 4px 6px -1px rgba(0, 0, 0, 0.08), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
|
|
102
103
|
/* sh-ui:theme-shadow-end */
|
|
103
104
|
/* sh-ui:theme-duration-start */
|
|
104
105
|
--duration-fast: 120ms;
|
|
@@ -99,6 +99,7 @@
|
|
|
99
99
|
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.12);
|
|
100
100
|
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.15);
|
|
101
101
|
--shadow-xl: 0 16px 48px rgba(0, 0, 0, 0.18);
|
|
102
|
+
--shadow-menu: 0 4px 6px -1px rgba(0, 0, 0, 0.08), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
|
|
102
103
|
/* sh-ui:theme-shadow-end */
|
|
103
104
|
/* sh-ui:theme-duration-start */
|
|
104
105
|
--duration-fast: 120ms;
|
|
@@ -99,6 +99,7 @@
|
|
|
99
99
|
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.12);
|
|
100
100
|
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.15);
|
|
101
101
|
--shadow-xl: 0 16px 48px rgba(0, 0, 0, 0.18);
|
|
102
|
+
--shadow-menu: 0 4px 6px -1px rgba(0, 0, 0, 0.08), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
|
|
102
103
|
/* sh-ui:theme-shadow-end */
|
|
103
104
|
/* sh-ui:theme-duration-start */
|
|
104
105
|
--duration-fast: 120ms;
|