sh-ui-cli 0.58.3 → 0.58.4
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 +13 -0
- 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/color-picker/index.tailwind.tsx +1 -1
- package/data/registry/react/components/color-picker/styles.css +2 -2
- package/data/registry/react/components/color-picker/styles.module.css +2 -2
- package/data/registry/react/components/date-picker/index.tailwind.tsx +1 -1
- package/data/registry/react/components/date-picker/styles.css +2 -2
- package/data/registry/react/components/date-picker/styles.module.css +2 -2
- package/data/registry/react/components/file-upload/index.tailwind.tsx +1 -1
- package/data/registry/react/components/input/index.tailwind.tsx +2 -2
- package/data/registry/react/components/input/styles.css +4 -4
- package/data/registry/react/components/input/styles.css.ts +2 -2
- package/data/registry/react/components/input/styles.module.css +4 -4
- package/data/registry/react/components/numeric-input/index.tailwind.tsx +1 -1
- package/data/registry/react/components/numeric-input/styles.css +1 -1
- package/data/registry/react/components/numeric-input/styles.module.css +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 +1 -1
- package/data/registry/react/components/textarea/index.tailwind.tsx +1 -1
- package/data/registry/react/components/textarea/styles.css +2 -2
- package/data/registry/react/components/textarea/styles.module.css +2 -2
- package/package.json +1 -1
|
@@ -2,6 +2,19 @@
|
|
|
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.4",
|
|
7
|
+
"date": "2026-05-06",
|
|
8
|
+
"title": "디자인 디폴트 개편 3라운드 — 폼 필드의 focus·hover 색을 primary 로",
|
|
9
|
+
"type": "patch",
|
|
10
|
+
"highlights": [
|
|
11
|
+
"**input / textarea / numeric-input / date-picker / color-picker / checkbox / radio 의 focus·hover 색 통일** — 기존 `border-color: var(--foreground)` + `box-shadow: 0 0 0 1px var(--foreground)` 는 다크에서 순백 강조라 stark. `--primary` 로 변경 — 폼 필드의 활성 시 브랜드 톤으로 자연스럽게 표시.",
|
|
12
|
+
"**v0.58.3 의 ring 패턴과 정렬** — 버튼 / 컴포넌트 focus ring 은 `--ring` (primary 50%), 폼 필드 inline focus 는 `--primary` solid (1px 이라 풀 포화). 두 layer 가 brand 톤으로 일관.",
|
|
13
|
+
"**4 variant + 듀얼 카피본 + 템플릿 모두 동기화** — Tailwind / plain CSS / CSS Modules / vanilla-extract.",
|
|
14
|
+
"**Button danger 의 `hover:brightness-95` 는 다음 라운드** — `--danger-hover` 토큰 추가 필요해서 별도 검토 후 진행."
|
|
15
|
+
],
|
|
16
|
+
"url": "https://github.com/sanghyeonKim0201/sh-ui/releases/tag/v0.58.4"
|
|
17
|
+
},
|
|
5
18
|
{
|
|
6
19
|
"version": "0.58.3",
|
|
7
20
|
"date": "2026-05-06",
|
|
@@ -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-
|
|
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-primary 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}
|
|
@@ -262,7 +262,7 @@ export function ColorPickerHex({ className, showSwatch = true, ...rest }: ColorP
|
|
|
262
262
|
<input
|
|
263
263
|
ref={inputRef}
|
|
264
264
|
type="text"
|
|
265
|
-
className="flex-1 min-w-0 h-7 px-[var(--space-2)] border border-border rounded-[calc(var(--radius)-2px)] bg-background text-foreground font-mono text-[0.8125rem] uppercase focus:outline-none focus:border-
|
|
265
|
+
className="flex-1 min-w-0 h-7 px-[var(--space-2)] border border-border rounded-[calc(var(--radius)-2px)] bg-background text-foreground font-mono text-[0.8125rem] uppercase focus:outline-none focus:border-primary focus:shadow-[0_0_0_1px_var(--primary)]"
|
|
266
266
|
value={draft}
|
|
267
267
|
onChange={(e) => setDraft(e.target.value)}
|
|
268
268
|
onBlur={onCommit}
|
|
@@ -134,8 +134,8 @@
|
|
|
134
134
|
}
|
|
135
135
|
.sh-ui-color-picker__hex:focus {
|
|
136
136
|
outline: none;
|
|
137
|
-
border-color: var(--
|
|
138
|
-
box-shadow: 0 0 0 1px var(--
|
|
137
|
+
border-color: var(--primary);
|
|
138
|
+
box-shadow: 0 0 0 1px var(--primary);
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
/* ───────────── Swatches ───────────── */
|
|
@@ -134,8 +134,8 @@
|
|
|
134
134
|
}
|
|
135
135
|
.color-picker__hex:focus {
|
|
136
136
|
outline: none;
|
|
137
|
-
border-color: var(--
|
|
138
|
-
box-shadow: 0 0 0 1px var(--
|
|
137
|
+
border-color: var(--primary);
|
|
138
|
+
box-shadow: 0 0 0 1px var(--primary);
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
/* ───────────── Swatches ───────────── */
|
|
@@ -22,7 +22,7 @@ function defaultRangePlaceholder(locale: string): string {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
const triggerClasses =
|
|
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-
|
|
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
28
|
"bg-background border border-border rounded-[var(--radius)] shadow-[0_8px_24px_rgba(0,0,0,0.12)] 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";
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
|
|
33
33
|
.sh-ui-date-picker__trigger:focus-visible {
|
|
34
34
|
outline: none;
|
|
35
|
-
border-color: var(--
|
|
36
|
-
box-shadow: 0 0 0 1px var(--
|
|
35
|
+
border-color: var(--primary);
|
|
36
|
+
box-shadow: 0 0 0 1px var(--primary);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
.sh-ui-date-picker__trigger:disabled {
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
|
|
33
33
|
.date-picker__trigger:focus-visible {
|
|
34
34
|
outline: none;
|
|
35
|
-
border-color: var(--
|
|
36
|
-
box-shadow: 0 0 0 1px var(--
|
|
35
|
+
border-color: var(--primary);
|
|
36
|
+
box-shadow: 0 0 0 1px var(--primary);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
.date-picker__trigger:disabled {
|
|
@@ -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-ring focus-visible:outline-offset-2 focus-visible:border-
|
|
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-primary 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,
|
|
@@ -14,13 +14,13 @@ export interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElem
|
|
|
14
14
|
/* ───────── Base utility 묶음 (반복 줄이기) ───────── */
|
|
15
15
|
|
|
16
16
|
const baseInputClasses =
|
|
17
|
-
"block 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 transition-[border-color,box-shadow] duration-[var(--duration-fast)] placeholder:text-foreground-subtle hover:not-disabled:not-focus:border-border-strong focus:outline-none focus:border-
|
|
17
|
+
"block 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 transition-[border-color,box-shadow] duration-[var(--duration-fast)] placeholder:text-foreground-subtle hover:not-disabled:not-focus:border-border-strong focus:outline-none focus:border-primary focus:shadow-[0_0_0_1px_var(--primary)] disabled:opacity-[var(--opacity-disabled)] disabled:cursor-not-allowed disabled:bg-background-subtle read-only:bg-background-subtle aria-[invalid=true]:border-danger aria-[invalid=true]:focus:shadow-[0_0_0_1px_var(--danger)]";
|
|
18
18
|
|
|
19
19
|
const inGroupOverrides =
|
|
20
20
|
"data-[in-group]:flex-1 data-[in-group]:min-w-0 data-[in-group]:h-auto data-[in-group]:p-0 data-[in-group]:bg-transparent data-[in-group]:border-none data-[in-group]:rounded-none data-[in-group]:shadow-none data-[in-group]:hover:border-none data-[in-group]:focus:border-none data-[in-group]:focus:outline-none data-[in-group]:focus:shadow-none data-[in-group]:disabled:bg-transparent";
|
|
21
21
|
|
|
22
22
|
const baseGroupClasses =
|
|
23
|
-
"flex items-center w-full min-h-[var(--control-md)] px-[var(--space-2)] gap-[var(--space-2)] bg-background text-foreground border border-border rounded-[var(--radius)] transition-[border-color,box-shadow] duration-[var(--duration-fast)] cursor-text hover:not-data-[disabled]:not-focus-within:border-border-strong focus-within:border-
|
|
23
|
+
"flex items-center w-full min-h-[var(--control-md)] px-[var(--space-2)] gap-[var(--space-2)] bg-background text-foreground border border-border rounded-[var(--radius)] transition-[border-color,box-shadow] duration-[var(--duration-fast)] cursor-text hover:not-data-[disabled]:not-focus-within:border-border-strong focus-within:border-primary focus-within:shadow-[0_0_0_1px_var(--primary)] aria-[invalid=true]:border-danger aria-[invalid=true]:focus-within:shadow-[0_0_0_1px_var(--danger)] data-[disabled]:opacity-[var(--opacity-disabled)] data-[disabled]:cursor-not-allowed data-[disabled]:bg-background-subtle";
|
|
24
24
|
|
|
25
25
|
/* ───────── InputGroup + InputAdornment (compound) ───────── */
|
|
26
26
|
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
|
|
33
33
|
.sh-ui-input:focus {
|
|
34
34
|
outline: none;
|
|
35
|
-
border-color: var(--
|
|
36
|
-
box-shadow: 0 0 0 1px var(--
|
|
35
|
+
border-color: var(--primary);
|
|
36
|
+
box-shadow: 0 0 0 1px var(--primary);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
.sh-ui-input:disabled {
|
|
@@ -143,8 +143,8 @@
|
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
.sh-ui-input-group:focus-within {
|
|
146
|
-
border-color: var(--
|
|
147
|
-
box-shadow: 0 0 0 1px var(--
|
|
146
|
+
border-color: var(--primary);
|
|
147
|
+
box-shadow: 0 0 0 1px var(--primary);
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
.sh-ui-input-group[aria-invalid="true"] {
|
|
@@ -25,7 +25,7 @@ export const input = style({
|
|
|
25
25
|
"&:focus": {
|
|
26
26
|
outline: "none",
|
|
27
27
|
borderColor: "var(--foreground)",
|
|
28
|
-
boxShadow: "0 0 0 1px var(--
|
|
28
|
+
boxShadow: "0 0 0 1px var(--primary)",
|
|
29
29
|
},
|
|
30
30
|
"&:disabled": {
|
|
31
31
|
opacity: "var(--opacity-disabled)",
|
|
@@ -164,7 +164,7 @@ export const group = style({
|
|
|
164
164
|
},
|
|
165
165
|
"&:focus-within": {
|
|
166
166
|
borderColor: "var(--foreground)",
|
|
167
|
-
boxShadow: "0 0 0 1px var(--
|
|
167
|
+
boxShadow: "0 0 0 1px var(--primary)",
|
|
168
168
|
},
|
|
169
169
|
'&[aria-invalid="true"]': {
|
|
170
170
|
borderColor: "var(--danger)",
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
|
|
33
33
|
.input:focus {
|
|
34
34
|
outline: none;
|
|
35
|
-
border-color: var(--
|
|
36
|
-
box-shadow: 0 0 0 1px var(--
|
|
35
|
+
border-color: var(--primary);
|
|
36
|
+
box-shadow: 0 0 0 1px var(--primary);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
.input:disabled {
|
|
@@ -141,8 +141,8 @@
|
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
.group:focus-within {
|
|
144
|
-
border-color: var(--
|
|
145
|
-
box-shadow: 0 0 0 1px var(--
|
|
144
|
+
border-color: var(--primary);
|
|
145
|
+
box-shadow: 0 0 0 1px var(--primary);
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
.group[aria-invalid="true"] {
|
|
@@ -19,7 +19,7 @@ export interface NumericInputProps
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
const inputClasses =
|
|
22
|
-
"w-10 px-1 py-0.5 font-mono text-[length:var(--text-xs)] leading-tight text-right border border-transparent rounded-[calc(var(--radius)-4px)] bg-transparent text-foreground appearance-none [-moz-appearance:textfield] transition-[border-color,background-color] duration-[var(--duration-fast)] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:m-0 [&::-webkit-outer-spin-button]:m-0 hover:not-disabled:not-focus:border-border focus:outline-none focus:border-
|
|
22
|
+
"w-10 px-1 py-0.5 font-mono text-[length:var(--text-xs)] leading-tight text-right border border-transparent rounded-[calc(var(--radius)-4px)] bg-transparent text-foreground appearance-none [-moz-appearance:textfield] transition-[border-color,background-color] duration-[var(--duration-fast)] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:m-0 [&::-webkit-outer-spin-button]:m-0 hover:not-disabled:not-focus:border-border focus:outline-none focus:border-primary focus:bg-background focus-visible:outline-none focus-visible:border-primary disabled:cursor-not-allowed disabled:opacity-[var(--opacity-disabled)]";
|
|
23
23
|
|
|
24
24
|
export const NumericInput = React.forwardRef<HTMLInputElement, NumericInputProps>(
|
|
25
25
|
(
|
|
@@ -67,7 +67,7 @@ export function RichTextEditor({
|
|
|
67
67
|
return (
|
|
68
68
|
<div
|
|
69
69
|
className={cn(
|
|
70
|
-
"sh-ui-rte flex flex-col border border-border rounded-[var(--radius)] bg-background overflow-hidden transition-[border-color] duration-[var(--duration-fast)] focus-within:border-
|
|
70
|
+
"sh-ui-rte flex flex-col border border-border rounded-[var(--radius)] bg-background overflow-hidden transition-[border-color] duration-[var(--duration-fast)] focus-within:border-primary 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",
|
|
71
71
|
className,
|
|
72
72
|
)}
|
|
73
73
|
data-readonly={readOnly || undefined}
|
|
@@ -9,7 +9,7 @@ export const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
|
|
|
9
9
|
<textarea
|
|
10
10
|
ref={ref}
|
|
11
11
|
className={cn(
|
|
12
|
-
"block w-full min-h-20 px-[var(--space-3)] py-[var(--space-2)] bg-background text-foreground border border-border rounded-[var(--radius)] font-[inherit] text-[length:var(--text-sm)] leading-normal resize-y transition-[border-color,box-shadow] duration-[var(--duration-fast)] placeholder:text-foreground-subtle hover:not-disabled:not-focus:border-border-strong focus:outline-none focus:border-
|
|
12
|
+
"block w-full min-h-20 px-[var(--space-3)] py-[var(--space-2)] bg-background text-foreground border border-border rounded-[var(--radius)] font-[inherit] text-[length:var(--text-sm)] leading-normal resize-y transition-[border-color,box-shadow] duration-[var(--duration-fast)] placeholder:text-foreground-subtle hover:not-disabled:not-focus:border-border-strong focus:outline-none focus:border-primary focus:shadow-[0_0_0_1px_var(--primary)] disabled:opacity-[var(--opacity-disabled)] disabled:cursor-not-allowed disabled:bg-background-subtle read-only:bg-background-subtle aria-[invalid=true]:border-danger aria-[invalid=true]:focus:shadow-[0_0_0_1px_var(--danger)] [@media(hover:none)_and_(pointer:coarse)]:text-[length:var(--text-base)]",
|
|
13
13
|
className,
|
|
14
14
|
)}
|
|
15
15
|
{...props}
|