sh-ui-cli 0.58.1 → 0.58.3
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/accordion/index.tailwind.tsx +1 -1
- package/data/registry/react/components/accordion/styles.css +1 -1
- package/data/registry/react/components/accordion/styles.module.css +1 -1
- package/data/registry/react/components/breadcrumb/index.tailwind.tsx +1 -1
- package/data/registry/react/components/breadcrumb/styles.css +1 -1
- package/data/registry/react/components/breadcrumb/styles.module.css +1 -1
- package/data/registry/react/components/button/index.tailwind.tsx +1 -1
- package/data/registry/react/components/button/styles.css +1 -2
- package/data/registry/react/components/button/styles.css.ts +1 -2
- package/data/registry/react/components/button/styles.module.css +1 -2
- package/data/registry/react/components/calendar/index.tailwind.tsx +3 -3
- package/data/registry/react/components/calendar/styles.css +3 -3
- package/data/registry/react/components/calendar/styles.module.css +3 -3
- package/data/registry/react/components/card/index.tailwind.tsx +1 -1
- package/data/registry/react/components/card/styles.css +1 -0
- package/data/registry/react/components/card/styles.css.ts +1 -0
- package/data/registry/react/components/card/styles.module.css +1 -0
- package/data/registry/react/components/carousel/index.tailwind.tsx +2 -2
- package/data/registry/react/components/carousel/styles.css +2 -2
- package/data/registry/react/components/carousel/styles.module.css +2 -2
- package/data/registry/react/components/checkbox/index.tailwind.tsx +1 -1
- package/data/registry/react/components/checkbox/styles.css +1 -1
- package/data/registry/react/components/checkbox/styles.module.css +1 -1
- package/data/registry/react/components/code-editor/index.tailwind.tsx +1 -1
- package/data/registry/react/components/code-editor/styles.css +1 -1
- package/data/registry/react/components/code-editor/styles.module.css +1 -1
- package/data/registry/react/components/code-panel/styles.css +1 -1
- package/data/registry/react/components/code-panel/styles.module.css +1 -1
- package/data/registry/react/components/color-picker/index.tailwind.tsx +1 -1
- package/data/registry/react/components/color-picker/styles.css +1 -1
- package/data/registry/react/components/color-picker/styles.module.css +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/dialog/index.tailwind.tsx +2 -2
- package/data/registry/react/components/dialog/styles.css +2 -2
- package/data/registry/react/components/dialog/styles.module.css +2 -2
- package/data/registry/react/components/dropdown-menu/index.tailwind.tsx +1 -1
- package/data/registry/react/components/dropdown-menu/styles.css +1 -1
- package/data/registry/react/components/dropdown-menu/styles.module.css +1 -1
- package/data/registry/react/components/file-upload/index.tailwind.tsx +3 -3
- package/data/registry/react/components/file-upload/styles.css +3 -3
- package/data/registry/react/components/file-upload/styles.module.css +3 -3
- package/data/registry/react/components/header/index.tailwind.tsx +3 -3
- package/data/registry/react/components/header/styles.css +3 -3
- package/data/registry/react/components/header/styles.module.css +3 -3
- package/data/registry/react/components/input/index.tailwind.tsx +1 -1
- package/data/registry/react/components/input/styles.css +1 -1
- package/data/registry/react/components/input/styles.css.ts +1 -1
- package/data/registry/react/components/input/styles.module.css +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/page-toc/index.tailwind.tsx +1 -1
- package/data/registry/react/components/page-toc/styles.css +1 -1
- package/data/registry/react/components/page-toc/styles.module.css +1 -1
- package/data/registry/react/components/pagination/index.tailwind.tsx +1 -1
- package/data/registry/react/components/pagination/styles.css +1 -1
- package/data/registry/react/components/pagination/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 +1 -1
- package/data/registry/react/components/radio/styles.css +1 -1
- package/data/registry/react/components/radio/styles.module.css +1 -1
- package/data/registry/react/components/rich-text-editor/index.tailwind.tsx +2 -2
- package/data/registry/react/components/rich-text-editor/styles.css +2 -2
- package/data/registry/react/components/rich-text-editor/styles.module.css +2 -2
- package/data/registry/react/components/select/index.tailwind.tsx +1 -1
- package/data/registry/react/components/select/styles.css +2 -2
- package/data/registry/react/components/select/styles.module.css +2 -2
- package/data/registry/react/components/sidebar/index.tailwind.tsx +3 -3
- package/data/registry/react/components/sidebar/styles.css +3 -3
- package/data/registry/react/components/sidebar/styles.module.css +3 -3
- 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 +1 -1
- 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 +2 -2
- package/data/registry/react/components/tabs/styles.css +2 -2
- package/data/registry/react/components/tabs/styles.module.css +2 -2
- 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/data/registry/react/components/toggle/styles.css +1 -1
- package/data/registry/react/components/toggle/styles.module.css +1 -1
- package/package.json +1 -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/nextjs-standalone/app/globals.css +1 -0
- package/templates/ui-app-template/src/styles/globals.css +1 -0
- package/templates/ui-app-template/src/styles/tokens.css +1 -0
|
@@ -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.58.3",
|
|
7
|
+
"date": "2026-05-06",
|
|
8
|
+
"title": "디자인 디폴트 개편 2라운드 — `--ring` 토큰 도입 + 모든 focus ring 통일",
|
|
9
|
+
"type": "patch",
|
|
10
|
+
"highlights": [
|
|
11
|
+
"**`--ring` 토큰 신규 — `color-mix(in srgb, var(--primary) 50%, transparent)`** — primary 의 50% 투명도로 부드러운 focus ring. solid primary 는 다크에서 너무 시끄러웠고, foreground 는 너무 stark 했음. 50% 투명도가 둘의 절충 — 키보드 사용자에게는 식별 가능, 시각적으로는 부드러움. shadcn/ui · Radix · Linear 의 ring 패턴과 일관.",
|
|
12
|
+
"**`--color-ring: var(--ring)` @theme inline 매핑 추가** — Tailwind v4 에서 `outline-ring` 유틸로 사용 가능. 템플릿 + apps/docs + ui-app-template 모두 동기화.",
|
|
13
|
+
"**27개 컴포넌트의 focus ring 을 `--ring` 으로 일괄 변경** — accordion / badge / breadcrumb / button / calendar / carousel / card / checkbox / code-editor / code-panel / color-picker / combobox / dialog / dropdown-menu / file-upload / header / input / menubar / page-toc / pagination / popover / radio / rich-text-editor / select / sidebar / slider / switch / tabs / toast / toggle. 모든 컴포넌트가 같은 ring 톤 사용 — 디자인 일관성 확보.",
|
|
14
|
+
"**4가지 variant + 듀얼 카피본 + 템플릿 모두 동기화** — Tailwind / plain CSS / CSS Modules / vanilla-extract + apps/docs + cli/templates. sed 일괄 패치로 110+ 파일 갱신.",
|
|
15
|
+
"**철학 — focus ring 은 별도 token 으로 분리** — 사용자가 brand color 를 바꿔도 focus ring 의 \"부드러움\" 은 유지됨 (color-mix 로 primary 의 투명도 형태 유지). 매번 컴포넌트마다 결정하지 않도록 디자인 시스템이 책임.",
|
|
16
|
+
"**FYI — `outline-primary` 단독 솔리드 (이번 PR 초기 커밋) 는 squash 머지로 사용자에게 도달하지 않음.** 최종 머지 결과는 `outline-ring` (반투명 primary) 로 통일."
|
|
17
|
+
],
|
|
18
|
+
"url": "https://github.com/sanghyeonKim0201/sh-ui/releases/tag/v0.58.3"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"version": "0.58.2",
|
|
22
|
+
"date": "2026-05-06",
|
|
23
|
+
"title": "디자인 디폴트 개편 1라운드 — Sidebar / Button / Card",
|
|
24
|
+
"type": "patch",
|
|
25
|
+
"highlights": [
|
|
26
|
+
"**`SidebarMenu` 기본 `gap` 0 → 2px** — 한글/긴 라벨에서 항목이 너무 촘촘하게 붙어 시각적으로 압축돼 보이던 문제. shadcn 의 `gap-0` 컨벤션과 살짝 갈리지만 sh-ui 의 한글 우선 + Linear 톤 정체성에 더 자연스러움.",
|
|
27
|
+
"**`Button` 의 `active:` 더블펌프 제거** — 기존 `active:scale-[0.97] + active:brightness-90` 두 효과 동시 적용으로 클릭이 cheap 한 느낌이었음. `brightness` 만 빼고 `scale` 유지 — Linear/Vercel/Radix 톤과 일관.",
|
|
28
|
+
"**`Button` focus ring 색 `foreground` → `primary`** — 다크모드에서 순백 outline 이 과해 사용자가 매번 override 하던 패턴. 브랜드 톤 + 자연스러움.",
|
|
29
|
+
"**`Card` 기본 `box-shadow: var(--shadow-sm)` 추가** — flat border-only 박스에서 미세 elevation 으로. 라이트 모드에서 임팩트 있고 다크에서도 무해함 (`0 1px 2px rgba(0,0,0,0.08)`). 모던 카드는 기본적으로 약간의 깊이를 가지는 게 자연스러움.",
|
|
30
|
+
"**4가지 variant + 듀얼 카피본 모두 동기화** — Tailwind / plain CSS / CSS Modules / vanilla-extract + apps/docs 카피본 + 템플릿. 사용자가 어떤 cssFramework 로 쓰든 동일한 톤.",
|
|
31
|
+
"**철학: 디자인 시스템 디폴트가 \"바로 보기 좋은\" 답을 줘야 함** — 사용자가 매번 같은 override 를 반복하면 그건 디폴트 책임. 이번 라운드는 sh-ui 사용 빈도 1·2·3 위 컴포넌트(Sidebar/Button/Card) 에 집중."
|
|
32
|
+
],
|
|
33
|
+
"url": "https://github.com/sanghyeonKim0201/sh-ui/releases/tag/v0.58.2"
|
|
34
|
+
},
|
|
5
35
|
{
|
|
6
36
|
"version": "0.58.1",
|
|
7
37
|
"date": "2026-05-06",
|
|
@@ -45,7 +45,7 @@ export const AccordionTrigger = React.forwardRef<
|
|
|
45
45
|
<BaseAccordion.Trigger
|
|
46
46
|
ref={ref}
|
|
47
47
|
className={cn(
|
|
48
|
-
"flex items-center justify-between gap-[var(--space-4)] w-full px-[var(--space-1)] py-[var(--space-4)] bg-transparent border-none text-foreground text-[0.9375rem] font-medium leading-snug text-left cursor-pointer transition-[background-color] duration-[var(--duration-fast)] hover:not-disabled:not-data-[disabled]:bg-background-muted focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-
|
|
48
|
+
"flex items-center justify-between gap-[var(--space-4)] w-full px-[var(--space-1)] py-[var(--space-4)] bg-transparent border-none text-foreground text-[0.9375rem] font-medium leading-snug text-left cursor-pointer transition-[background-color] duration-[var(--duration-fast)] hover:not-disabled:not-data-[disabled]:bg-background-muted focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 focus-visible:rounded-[calc(var(--radius)-2px)] disabled:cursor-not-allowed disabled:text-foreground-muted data-[disabled]:cursor-not-allowed data-[disabled]:text-foreground-muted [[data-size=sm]_&]:py-[var(--space-2)] [[data-size=sm]_&]:text-[length:var(--text-xs)] [[data-size=sm]_&]:leading-[1.2] motion-reduce:transition-none",
|
|
49
49
|
className,
|
|
50
50
|
)}
|
|
51
51
|
{...props}
|
|
@@ -53,7 +53,7 @@ export const BreadcrumbLink = React.forwardRef<
|
|
|
53
53
|
<a
|
|
54
54
|
ref={ref}
|
|
55
55
|
className={cn(
|
|
56
|
-
"text-foreground-muted no-underline rounded-[calc(var(--radius)-2px)] px-0.5 transition-colors duration-[var(--duration-fast)] hover:text-foreground hover:underline hover:underline-offset-[3px] focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-
|
|
56
|
+
"text-foreground-muted no-underline rounded-[calc(var(--radius)-2px)] px-0.5 transition-colors duration-[var(--duration-fast)] hover:text-foreground hover:underline hover:underline-offset-[3px] focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 motion-reduce:transition-none",
|
|
57
57
|
className,
|
|
58
58
|
)}
|
|
59
59
|
{...props}
|
|
@@ -3,7 +3,7 @@ import { cn } from "@SH_UI_UTILS@";
|
|
|
3
3
|
import { cva, type VariantProps } from "class-variance-authority";
|
|
4
4
|
|
|
5
5
|
const buttonVariants = cva(
|
|
6
|
-
"inline-flex items-center justify-center gap-[var(--space-2)] border border-transparent rounded-[var(--radius)] font-medium leading-none cursor-pointer select-none transition-[background-color,color,border-color] duration-[var(--duration-fast)] disabled:opacity-[var(--opacity-disabled)] disabled:pointer-events-none focus-visible:outline-2 focus-visible:outline-
|
|
6
|
+
"inline-flex items-center justify-center gap-[var(--space-2)] border border-transparent rounded-[var(--radius)] font-medium leading-none cursor-pointer select-none transition-[background-color,color,border-color] duration-[var(--duration-fast)] disabled:opacity-[var(--opacity-disabled)] disabled:pointer-events-none focus-visible:outline-2 focus-visible:outline-ring focus-visible:outline-offset-2 active:scale-[0.97]",
|
|
7
7
|
{
|
|
8
8
|
variants: {
|
|
9
9
|
variant: {
|
|
@@ -20,13 +20,12 @@
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
.sh-ui-button:focus-visible {
|
|
23
|
-
outline: var(--border-width-strong) solid var(--
|
|
23
|
+
outline: var(--border-width-strong) solid var(--ring);
|
|
24
24
|
outline-offset: 2px;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
.sh-ui-button:active:not(:disabled) {
|
|
28
28
|
transform: scale(0.97);
|
|
29
|
-
filter: brightness(0.92);
|
|
30
29
|
transition-duration: 40ms;
|
|
31
30
|
}
|
|
32
31
|
|
|
@@ -21,12 +21,11 @@ export const button = style({
|
|
|
21
21
|
pointerEvents: "none",
|
|
22
22
|
},
|
|
23
23
|
"&:focus-visible": {
|
|
24
|
-
outline: "var(--border-width-strong) solid var(--
|
|
24
|
+
outline: "var(--border-width-strong) solid var(--ring)",
|
|
25
25
|
outlineOffset: "2px",
|
|
26
26
|
},
|
|
27
27
|
"&:active:not(:disabled)": {
|
|
28
28
|
transform: "scale(0.97)",
|
|
29
|
-
filter: "brightness(0.92)",
|
|
30
29
|
transitionDuration: "40ms",
|
|
31
30
|
},
|
|
32
31
|
},
|
|
@@ -20,13 +20,12 @@
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
.button:focus-visible {
|
|
23
|
-
outline: var(--border-width-strong) solid var(--
|
|
23
|
+
outline: var(--border-width-strong) solid var(--ring);
|
|
24
24
|
outline-offset: 2px;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
.button:active:not(:disabled) {
|
|
28
28
|
transform: scale(0.97);
|
|
29
|
-
filter: brightness(0.92);
|
|
30
29
|
transition-duration: 40ms;
|
|
31
30
|
}
|
|
32
31
|
|
|
@@ -391,7 +391,7 @@ export const CalendarHeader = React.forwardRef<HTMLDivElement, CalendarHeaderPro
|
|
|
391
391
|
);
|
|
392
392
|
|
|
393
393
|
const navButtonClasses =
|
|
394
|
-
"inline-flex items-center justify-center w-7 h-7 p-0 border-none rounded-[calc(var(--radius)-2px)] bg-transparent text-foreground-muted cursor-pointer shrink-0 transition-[background-color,color] duration-[var(--duration-fast)] hover:not-disabled:bg-background-muted hover:not-disabled:text-foreground focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-
|
|
394
|
+
"inline-flex items-center justify-center w-7 h-7 p-0 border-none rounded-[calc(var(--radius)-2px)] bg-transparent text-foreground-muted cursor-pointer shrink-0 transition-[background-color,color] duration-[var(--duration-fast)] hover:not-disabled:bg-background-muted hover:not-disabled:text-foreground focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 motion-reduce:transition-none";
|
|
395
395
|
|
|
396
396
|
function CalendarNavPlaceholder() {
|
|
397
397
|
return <span className={cn(navButtonClasses, "invisible pointer-events-none")} aria-hidden />;
|
|
@@ -501,7 +501,7 @@ export const CalendarGrid = React.forwardRef<HTMLDivElement, CalendarGridProps>(
|
|
|
501
501
|
))}
|
|
502
502
|
</div>
|
|
503
503
|
<div
|
|
504
|
-
className="grid grid-cols-7 outline-none focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-
|
|
504
|
+
className="grid grid-cols-7 outline-none focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 focus-visible:rounded-[calc(var(--radius)-2px)]"
|
|
505
505
|
role="grid"
|
|
506
506
|
tabIndex={0}
|
|
507
507
|
onKeyDown={ctx.onKeyDown}
|
|
@@ -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-
|
|
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",
|
|
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",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
.sh-ui-calendar__nav:focus-visible {
|
|
59
|
-
outline: var(--border-width-strong) solid var(--
|
|
59
|
+
outline: var(--border-width-strong) solid var(--ring);
|
|
60
60
|
outline-offset: 2px;
|
|
61
61
|
}
|
|
62
62
|
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
.sh-ui-calendar__grid:focus-visible {
|
|
126
|
-
outline: var(--border-width-strong) solid var(--
|
|
126
|
+
outline: var(--border-width-strong) solid var(--ring);
|
|
127
127
|
outline-offset: 2px;
|
|
128
128
|
border-radius: calc(var(--radius) - 2px);
|
|
129
129
|
}
|
|
@@ -181,7 +181,7 @@
|
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
.sh-ui-calendar__day:focus-visible {
|
|
184
|
-
outline: var(--border-width-strong) solid var(--
|
|
184
|
+
outline: var(--border-width-strong) solid var(--ring);
|
|
185
185
|
outline-offset: 2px;
|
|
186
186
|
}
|
|
187
187
|
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
.calendar__nav:focus-visible {
|
|
59
|
-
outline: var(--border-width-strong) solid var(--
|
|
59
|
+
outline: var(--border-width-strong) solid var(--ring);
|
|
60
60
|
outline-offset: 2px;
|
|
61
61
|
}
|
|
62
62
|
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
.calendar__grid:focus-visible {
|
|
126
|
-
outline: var(--border-width-strong) solid var(--
|
|
126
|
+
outline: var(--border-width-strong) solid var(--ring);
|
|
127
127
|
outline-offset: 2px;
|
|
128
128
|
border-radius: calc(var(--radius) - 2px);
|
|
129
129
|
}
|
|
@@ -181,7 +181,7 @@
|
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
.calendar__day:focus-visible {
|
|
184
|
-
outline: var(--border-width-strong) solid var(--
|
|
184
|
+
outline: var(--border-width-strong) solid var(--ring);
|
|
185
185
|
outline-offset: 2px;
|
|
186
186
|
}
|
|
187
187
|
|
|
@@ -9,7 +9,7 @@ export const Card = React.forwardRef<HTMLDivElement, DivProps>(
|
|
|
9
9
|
<div
|
|
10
10
|
ref={ref}
|
|
11
11
|
className={cn(
|
|
12
|
-
"flex flex-col gap-[var(--space-6)] py-[var(--space-6)] bg-background text-foreground border border-border rounded-[var(--radius)] max-sm:gap-[var(--space-4)] max-sm:py-[var(--space-4)]",
|
|
12
|
+
"flex flex-col gap-[var(--space-6)] py-[var(--space-6)] bg-background text-foreground border border-border rounded-[var(--radius)] shadow-[var(--shadow-sm)] max-sm:gap-[var(--space-4)] max-sm:py-[var(--space-4)]",
|
|
13
13
|
className,
|
|
14
14
|
)}
|
|
15
15
|
{...props}
|
|
@@ -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-
|
|
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]";
|
|
209
209
|
|
|
210
210
|
export const CarouselPrevious = React.forwardRef<HTMLButtonElement, React.ButtonHTMLAttributes<HTMLButtonElement>>(
|
|
211
211
|
({ className, onClick, disabled, children, ...props }, ref) => {
|
|
@@ -295,7 +295,7 @@ export const CarouselIndicators = React.forwardRef<HTMLDivElement, CarouselIndic
|
|
|
295
295
|
role="tab"
|
|
296
296
|
aria-selected={i === index}
|
|
297
297
|
aria-label={labelFor ? labelFor(i) : `${i + 1}번 슬라이드`}
|
|
298
|
-
className="w-2 h-2 p-0 bg-border border-none rounded-full cursor-pointer transition-[background-color,transform] duration-[var(--duration-fast)] hover:bg-border-strong data-[active]:bg-foreground data-[active]:scale-[1.2] focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-
|
|
298
|
+
className="w-2 h-2 p-0 bg-border border-none rounded-full cursor-pointer transition-[background-color,transform] duration-[var(--duration-fast)] hover:bg-border-strong data-[active]:bg-foreground data-[active]:scale-[1.2] focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 motion-reduce:transition-none"
|
|
299
299
|
data-active={i === index || undefined}
|
|
300
300
|
onClick={() => goTo(i)}
|
|
301
301
|
/>
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
.sh-ui-carousel__nav:focus-visible {
|
|
68
|
-
outline: var(--border-width-strong) solid var(--
|
|
68
|
+
outline: var(--border-width-strong) solid var(--ring);
|
|
69
69
|
outline-offset: 2px;
|
|
70
70
|
}
|
|
71
71
|
|
|
@@ -140,7 +140,7 @@
|
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
.sh-ui-carousel__indicator:focus-visible {
|
|
143
|
-
outline: var(--border-width-strong) solid var(--
|
|
143
|
+
outline: var(--border-width-strong) solid var(--ring);
|
|
144
144
|
outline-offset: 2px;
|
|
145
145
|
}
|
|
146
146
|
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
.carousel__nav:focus-visible {
|
|
68
|
-
outline: var(--border-width-strong) solid var(--
|
|
68
|
+
outline: var(--border-width-strong) solid var(--ring);
|
|
69
69
|
outline-offset: 2px;
|
|
70
70
|
}
|
|
71
71
|
|
|
@@ -140,7 +140,7 @@
|
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
.carousel__indicator:focus-visible {
|
|
143
|
-
outline: var(--border-width-strong) solid var(--
|
|
143
|
+
outline: var(--border-width-strong) solid var(--ring);
|
|
144
144
|
outline-offset: 2px;
|
|
145
145
|
}
|
|
146
146
|
|
|
@@ -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-
|
|
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",
|
|
20
20
|
className,
|
|
21
21
|
)}
|
|
22
22
|
{...props}
|
|
@@ -135,7 +135,7 @@ export function CodeEditor({
|
|
|
135
135
|
<div
|
|
136
136
|
ref={hostRef}
|
|
137
137
|
className={cn(
|
|
138
|
-
"sh-ui-code-editor relative border border-border rounded-[var(--radius)] bg-background text-[0.8125rem] leading-relaxed overflow-hidden transition-[border-color] duration-[var(--duration-fast)] focus-within:border-foreground focus-within:outline-[length:var(--border-width-strong)] focus-within:outline-
|
|
138
|
+
"sh-ui-code-editor relative border border-border rounded-[var(--radius)] bg-background text-[0.8125rem] leading-relaxed overflow-hidden transition-[border-color] duration-[var(--duration-fast)] focus-within:border-foreground focus-within:outline-[length:var(--border-width-strong)] focus-within:outline-ring focus-within:outline-offset-2 data-[readonly]:bg-background-subtle motion-reduce:transition-none",
|
|
139
139
|
className,
|
|
140
140
|
)}
|
|
141
141
|
data-readonly={readOnly || undefined}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
}
|
|
11
11
|
.sh-ui-code-editor:focus-within {
|
|
12
12
|
border-color: var(--foreground);
|
|
13
|
-
outline: var(--border-width-strong) solid var(--
|
|
13
|
+
outline: var(--border-width-strong) solid var(--ring);
|
|
14
14
|
outline-offset: 2px;
|
|
15
15
|
}
|
|
16
16
|
.sh-ui-code-editor[data-readonly] {
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
border-color: var(--border-strong);
|
|
65
65
|
}
|
|
66
66
|
.sh-ui-code__copy:focus-visible {
|
|
67
|
-
outline: var(--border-width-strong) solid var(--
|
|
67
|
+
outline: var(--border-width-strong) solid var(--ring);
|
|
68
68
|
outline-offset: 2px;
|
|
69
69
|
}
|
|
70
70
|
.sh-ui-code__copy-label {
|
|
@@ -296,7 +296,7 @@ export function ColorPickerSwatches({ className, colors, ...rest }: ColorPickerS
|
|
|
296
296
|
<button
|
|
297
297
|
key={c}
|
|
298
298
|
type="button"
|
|
299
|
-
className="w-5 h-5 p-0 border border-border rounded-[calc(var(--radius)-4px)] cursor-pointer transition-[transform,box-shadow] duration-[var(--duration-fast)] hover:scale-110 focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-
|
|
299
|
+
className="w-5 h-5 p-0 border border-border rounded-[calc(var(--radius)-4px)] cursor-pointer transition-[transform,box-shadow] duration-[var(--duration-fast)] hover:scale-110 focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 data-[selected]:shadow-[0_0_0_2px_var(--background),0_0_0_3.5px_var(--foreground)]"
|
|
300
300
|
aria-label={c}
|
|
301
301
|
aria-pressed={selected}
|
|
302
302
|
data-selected={selected || undefined}
|
|
@@ -158,7 +158,7 @@
|
|
|
158
158
|
transform: scale(1.08);
|
|
159
159
|
}
|
|
160
160
|
.sh-ui-color-picker__swatch-btn:focus-visible {
|
|
161
|
-
outline: var(--border-width-strong) solid var(--
|
|
161
|
+
outline: var(--border-width-strong) solid var(--ring);
|
|
162
162
|
outline-offset: 2px;
|
|
163
163
|
}
|
|
164
164
|
.sh-ui-color-picker__swatch-btn[data-selected] {
|
|
@@ -158,7 +158,7 @@
|
|
|
158
158
|
transform: scale(1.08);
|
|
159
159
|
}
|
|
160
160
|
.color-picker__swatch-btn:focus-visible {
|
|
161
|
-
outline: var(--border-width-strong) solid var(--
|
|
161
|
+
outline: var(--border-width-strong) solid var(--ring);
|
|
162
162
|
outline-offset: 2px;
|
|
163
163
|
}
|
|
164
164
|
.color-picker__swatch-btn[data-selected] {
|
|
@@ -23,7 +23,7 @@ export const ComboboxInput = React.forwardRef<
|
|
|
23
23
|
<BaseCombobox.Input
|
|
24
24
|
ref={ref}
|
|
25
25
|
className={cn(
|
|
26
|
-
"inline-flex w-full min-w-40 h-[var(--control-md)] px-[var(--space-3)] bg-background text-foreground border border-border rounded-[var(--radius)] text-[length:var(--text-sm)] leading-none outline-none transition-[border-color] duration-[var(--duration-fast)] placeholder:text-foreground-subtle hover:not-disabled:border-border-strong focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-
|
|
26
|
+
"inline-flex w-full min-w-40 h-[var(--control-md)] px-[var(--space-3)] bg-background text-foreground border border-border rounded-[var(--radius)] text-[length:var(--text-sm)] leading-none outline-none transition-[border-color] duration-[var(--duration-fast)] placeholder:text-foreground-subtle hover:not-disabled:border-border-strong 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",
|
|
27
27
|
className,
|
|
28
28
|
)}
|
|
29
29
|
{...props}
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
border-color: var(--border-strong);
|
|
22
22
|
}
|
|
23
23
|
.sh-ui-combobox__input:focus-visible {
|
|
24
|
-
outline: var(--border-width-strong) solid var(--
|
|
24
|
+
outline: var(--border-width-strong) solid var(--ring);
|
|
25
25
|
outline-offset: 2px;
|
|
26
26
|
}
|
|
27
27
|
.sh-ui-combobox__input:disabled {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
border-color: var(--border-strong);
|
|
22
22
|
}
|
|
23
23
|
.combobox__input:focus-visible {
|
|
24
|
-
outline: var(--border-width-strong) solid var(--
|
|
24
|
+
outline: var(--border-width-strong) solid var(--ring);
|
|
25
25
|
outline-offset: 2px;
|
|
26
26
|
}
|
|
27
27
|
.combobox__input:disabled {
|
|
@@ -13,7 +13,7 @@ export function DialogCloseX({ className, children, ...props }: React.ButtonHTML
|
|
|
13
13
|
return (
|
|
14
14
|
<BaseDialog.Close
|
|
15
15
|
className={cn(
|
|
16
|
-
"absolute top-[var(--space-3)] right-[var(--space-3)] inline-flex items-center justify-center w-8 h-8 border-0 rounded-[calc(var(--radius)-2px)] bg-transparent text-foreground-muted text-[length:var(--text-lg)] leading-none cursor-pointer transition-[background-color,color] duration-[var(--duration-fast)] hover:bg-background-muted hover:text-foreground focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-
|
|
16
|
+
"absolute top-[var(--space-3)] right-[var(--space-3)] inline-flex items-center justify-center w-8 h-8 border-0 rounded-[calc(var(--radius)-2px)] bg-transparent text-foreground-muted text-[length:var(--text-lg)] leading-none cursor-pointer transition-[background-color,color] duration-[var(--duration-fast)] hover:bg-background-muted hover:text-foreground focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 motion-reduce:transition-none",
|
|
17
17
|
className,
|
|
18
18
|
)}
|
|
19
19
|
aria-label="닫기"
|
|
@@ -49,7 +49,7 @@ export const DialogContent = React.forwardRef<HTMLDivElement, DialogContentProps
|
|
|
49
49
|
<BaseDialog.Popup
|
|
50
50
|
ref={ref}
|
|
51
51
|
className={cn(
|
|
52
|
-
"fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-[var(--z-modal)] flex flex-col w-[calc(100%-2rem)] max-w-md max-h-[calc(100dvh-4rem)] p-[var(--space-6)] bg-background text-foreground border border-border rounded-[var(--radius)] shadow-[var(--shadow-xl)] outline-none overflow-y-auto transition-[opacity,transform] duration-[var(--duration-slow)] motion-reduce:transition-none data-[starting-style]:opacity-0 data-[starting-style]:translate-y-[calc(-50%+0.5rem)] data-[starting-style]:scale-[0.97] data-[ending-style]:opacity-0 data-[ending-style]:translate-y-[calc(-50%+0.25rem)] data-[ending-style]:scale-[0.98] motion-reduce:data-[starting-style]:translate-y-[-50%] motion-reduce:data-[starting-style]:scale-100 motion-reduce:data-[ending-style]:translate-y-[-50%] motion-reduce:data-[ending-style]:scale-100 focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-
|
|
52
|
+
"fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-[var(--z-modal)] flex flex-col w-[calc(100%-2rem)] max-w-md max-h-[calc(100dvh-4rem)] p-[var(--space-6)] bg-background text-foreground border border-border rounded-[var(--radius)] shadow-[var(--shadow-xl)] outline-none overflow-y-auto transition-[opacity,transform] duration-[var(--duration-slow)] motion-reduce:transition-none data-[starting-style]:opacity-0 data-[starting-style]:translate-y-[calc(-50%+0.5rem)] data-[starting-style]:scale-[0.97] data-[ending-style]:opacity-0 data-[ending-style]:translate-y-[calc(-50%+0.25rem)] data-[ending-style]:scale-[0.98] motion-reduce:data-[starting-style]:translate-y-[-50%] motion-reduce:data-[starting-style]:scale-100 motion-reduce:data-[ending-style]:translate-y-[-50%] motion-reduce:data-[ending-style]:scale-100 focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2",
|
|
53
53
|
className,
|
|
54
54
|
)}
|
|
55
55
|
{...props}
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
.sh-ui-dialog__content:focus-visible {
|
|
54
|
-
outline: var(--border-width-strong) solid var(--
|
|
54
|
+
outline: var(--border-width-strong) solid var(--ring);
|
|
55
55
|
outline-offset: 2px;
|
|
56
56
|
}
|
|
57
57
|
|
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
color: var(--foreground);
|
|
111
111
|
}
|
|
112
112
|
.sh-ui-dialog__close:focus-visible {
|
|
113
|
-
outline: var(--border-width-strong) solid var(--
|
|
113
|
+
outline: var(--border-width-strong) solid var(--ring);
|
|
114
114
|
outline-offset: 2px;
|
|
115
115
|
}
|
|
116
116
|
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
.dialog__content:focus-visible {
|
|
54
|
-
outline: var(--border-width-strong) solid var(--
|
|
54
|
+
outline: var(--border-width-strong) solid var(--ring);
|
|
55
55
|
outline-offset: 2px;
|
|
56
56
|
}
|
|
57
57
|
|
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
color: var(--foreground);
|
|
111
111
|
}
|
|
112
112
|
.dialog__close:focus-visible {
|
|
113
|
-
outline: var(--border-width-strong) solid var(--
|
|
113
|
+
outline: var(--border-width-strong) solid var(--ring);
|
|
114
114
|
outline-offset: 2px;
|
|
115
115
|
}
|
|
116
116
|
|
|
@@ -21,7 +21,7 @@ export const DropdownMenuTrigger = React.forwardRef<
|
|
|
21
21
|
<BaseMenu.Trigger
|
|
22
22
|
ref={ref}
|
|
23
23
|
className={cn(
|
|
24
|
-
"font-[inherit] cursor-pointer focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-
|
|
24
|
+
"font-[inherit] cursor-pointer focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2",
|
|
25
25
|
className,
|
|
26
26
|
)}
|
|
27
27
|
{...props}
|
|
@@ -153,7 +153,7 @@ export const FileUploadDropzone = React.forwardRef<HTMLDivElement, FileUploadDro
|
|
|
153
153
|
aria-disabled={disabled || undefined}
|
|
154
154
|
data-dragging={dragging || undefined}
|
|
155
155
|
className={cn(
|
|
156
|
-
"relative flex flex-col items-center justify-center gap-[var(--space-2)] py-[var(--space-8)] px-[var(--space-6)] min-h-40 bg-background-subtle text-foreground-muted border-[1.5px] border-dashed border-border rounded-[var(--radius)] cursor-pointer text-center transition-[border-color,background-color,color] duration-[var(--duration-fast)] hover:border-border-strong hover:text-foreground focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-
|
|
156
|
+
"relative flex flex-col items-center justify-center gap-[var(--space-2)] py-[var(--space-8)] px-[var(--space-6)] min-h-40 bg-background-subtle text-foreground-muted border-[1.5px] border-dashed border-border rounded-[var(--radius)] cursor-pointer text-center transition-[border-color,background-color,color] duration-[var(--duration-fast)] hover:border-border-strong hover:text-foreground focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-ring focus-visible:outline-offset-2 focus-visible:border-foreground motion-reduce:transition-none",
|
|
157
157
|
dragging && "border-foreground bg-background-muted text-foreground",
|
|
158
158
|
disabled && "opacity-[var(--opacity-disabled)] cursor-not-allowed pointer-events-none",
|
|
159
159
|
className,
|
|
@@ -189,7 +189,7 @@ export const FileUploadTrigger = React.forwardRef<HTMLButtonElement, FileUploadT
|
|
|
189
189
|
type={type ?? "button"}
|
|
190
190
|
disabled={disabled || rest.disabled}
|
|
191
191
|
className={cn(
|
|
192
|
-
"inline-flex items-center justify-center gap-[var(--space-2)] py-[var(--space-2)] px-[var(--space-3)] text-[length:var(--text-sm)] font-medium text-foreground bg-background border border-border rounded-[calc(var(--radius)-2px)] cursor-pointer transition-[background-color,border-color] duration-[var(--duration-fast)] hover:not-disabled:bg-background-muted hover:not-disabled:border-border-strong focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-
|
|
192
|
+
"inline-flex items-center justify-center gap-[var(--space-2)] py-[var(--space-2)] px-[var(--space-3)] text-[length:var(--text-sm)] font-medium text-foreground bg-background border border-border rounded-[calc(var(--radius)-2px)] cursor-pointer transition-[background-color,border-color] duration-[var(--duration-fast)] hover:not-disabled:bg-background-muted hover:not-disabled:border-border-strong 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",
|
|
193
193
|
className,
|
|
194
194
|
)}
|
|
195
195
|
onClick={(e) => {
|
|
@@ -250,7 +250,7 @@ export const FileUploadItem = React.forwardRef<HTMLLIElement, FileUploadItemProp
|
|
|
250
250
|
<span className="text-[length:var(--text-xs)] text-foreground-muted shrink-0">{formatBytes(file.size)}</span>
|
|
251
251
|
<button
|
|
252
252
|
type="button"
|
|
253
|
-
className="inline-flex items-center justify-center w-6 h-6 p-0 bg-transparent border-none rounded-[calc(var(--radius)-4px)] text-foreground-muted cursor-pointer transition-[color,background-color] duration-[var(--duration-fast)] shrink-0 hover:not-disabled:text-foreground hover:not-disabled:bg-background-muted focus-visible:outline-[length:var(--border-width-strong)] focus-visible:outline-
|
|
253
|
+
className="inline-flex items-center justify-center w-6 h-6 p-0 bg-transparent border-none rounded-[calc(var(--radius)-4px)] text-foreground-muted cursor-pointer transition-[color,background-color] duration-[var(--duration-fast)] shrink-0 hover:not-disabled:text-foreground 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"
|
|
254
254
|
onClick={() => remove(index)}
|
|
255
255
|
disabled={disabled}
|
|
256
256
|
aria-label={`${file.name} 제거`}
|