sh-ui-cli 0.45.3 → 0.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/data/changelog/versions.json +26 -0
  2. package/data/registry/react/components/accordion/index.module.tsx +97 -0
  3. package/data/registry/react/components/accordion/styles.module.css +111 -0
  4. package/data/registry/react/components/avatar/index.module.tsx +73 -0
  5. package/data/registry/react/components/avatar/styles.module.css +36 -0
  6. package/data/registry/react/components/badge/index.module.tsx +40 -0
  7. package/data/registry/react/components/badge/styles.module.css +57 -0
  8. package/data/registry/react/components/breadcrumb/index.module.tsx +152 -0
  9. package/data/registry/react/components/breadcrumb/styles.module.css +82 -0
  10. package/data/registry/react/components/button/index.module.tsx +45 -0
  11. package/data/registry/react/components/button/styles.module.css +92 -0
  12. package/data/registry/react/components/calendar/index.module.tsx +806 -0
  13. package/data/registry/react/components/calendar/styles.module.css +213 -0
  14. package/data/registry/react/components/card/index.module.tsx +63 -0
  15. package/data/registry/react/components/card/styles.module.css +73 -0
  16. package/data/registry/react/components/carousel/index.module.tsx +430 -0
  17. package/data/registry/react/components/carousel/styles.module.css +155 -0
  18. package/data/registry/react/components/checkbox/index.module.tsx +96 -0
  19. package/data/registry/react/components/checkbox/styles.module.css +75 -0
  20. package/data/registry/react/components/code-editor/index.module.tsx +230 -0
  21. package/data/registry/react/components/code-editor/styles.module.css +76 -0
  22. package/data/registry/react/components/code-panel/index.module.tsx +191 -0
  23. package/data/registry/react/components/code-panel/styles.module.css +124 -0
  24. package/data/registry/react/components/color-picker/index.module.tsx +467 -0
  25. package/data/registry/react/components/color-picker/styles.module.css +166 -0
  26. package/data/registry/react/components/combobox/index.module.tsx +165 -0
  27. package/data/registry/react/components/combobox/styles.module.css +151 -0
  28. package/data/registry/react/components/context-menu/index.module.tsx +251 -0
  29. package/data/registry/react/components/context-menu/styles.module.css +140 -0
  30. package/data/registry/react/components/date-picker/index.module.tsx +520 -0
  31. package/data/registry/react/components/date-picker/styles.module.css +103 -0
  32. package/data/registry/react/components/dialog/index.module.tsx +95 -0
  33. package/data/registry/react/components/dialog/styles.module.css +127 -0
  34. package/data/registry/react/components/dropdown-menu/index.module.tsx +255 -0
  35. package/data/registry/react/components/dropdown-menu/styles.module.css +150 -0
  36. package/data/registry/react/components/file-upload/index.module.tsx +487 -0
  37. package/data/registry/react/components/file-upload/styles.module.css +170 -0
  38. package/data/registry/react/components/form/index.module.tsx +61 -0
  39. package/data/registry/react/components/form/styles.module.css +47 -0
  40. package/data/registry/react/components/header/index.module.tsx +805 -0
  41. package/data/registry/react/components/header/styles.module.css +350 -0
  42. package/data/registry/react/components/input/index.module.tsx +486 -0
  43. package/data/registry/react/components/input/styles.module.css +200 -0
  44. package/data/registry/react/components/label/index.module.tsx +52 -0
  45. package/data/registry/react/components/label/styles.module.css +90 -0
  46. package/data/registry/react/components/markdown-editor/index.module.tsx +119 -0
  47. package/data/registry/react/components/markdown-editor/styles.module.css +160 -0
  48. package/data/registry/react/components/menubar/index.module.tsx +32 -0
  49. package/data/registry/react/components/menubar/styles.module.css +45 -0
  50. package/data/registry/react/components/numeric-input/index.module.tsx +148 -0
  51. package/data/registry/react/components/numeric-input/styles.module.css +56 -0
  52. package/data/registry/react/components/page-toc/index.module.tsx +174 -0
  53. package/data/registry/react/components/page-toc/styles.module.css +82 -0
  54. package/data/registry/react/components/pagination/index.module.tsx +269 -0
  55. package/data/registry/react/components/pagination/styles.module.css +105 -0
  56. package/data/registry/react/components/popover/index.module.tsx +113 -0
  57. package/data/registry/react/components/popover/styles.module.css +65 -0
  58. package/data/registry/react/components/progress/index.module.tsx +54 -0
  59. package/data/registry/react/components/progress/styles.module.css +41 -0
  60. package/data/registry/react/components/radio/index.module.tsx +65 -0
  61. package/data/registry/react/components/radio/styles.module.css +80 -0
  62. package/data/registry/react/components/rich-text-editor/index.module.tsx +348 -0
  63. package/data/registry/react/components/rich-text-editor/styles.module.css +196 -0
  64. package/data/registry/react/components/select/index.module.tsx +234 -0
  65. package/data/registry/react/components/select/styles.module.css +193 -0
  66. package/data/registry/react/components/separator/index.module.tsx +46 -0
  67. package/data/registry/react/components/separator/styles.module.css +15 -0
  68. package/data/registry/react/components/sidebar/index.module.tsx +1067 -0
  69. package/data/registry/react/components/sidebar/styles.module.css +502 -0
  70. package/data/registry/react/components/skeleton/index.module.tsx +22 -0
  71. package/data/registry/react/components/skeleton/styles.module.css +24 -0
  72. package/data/registry/react/components/slider/index.module.tsx +298 -0
  73. package/data/registry/react/components/slider/styles.module.css +64 -0
  74. package/data/registry/react/components/spinner/index.module.tsx +38 -0
  75. package/data/registry/react/components/spinner/styles.module.css +37 -0
  76. package/data/registry/react/components/switch/index.module.tsx +39 -0
  77. package/data/registry/react/components/switch/styles.module.css +83 -0
  78. package/data/registry/react/components/tabs/index.module.tsx +91 -0
  79. package/data/registry/react/components/tabs/styles.module.css +148 -0
  80. package/data/registry/react/components/textarea/index.module.tsx +23 -0
  81. package/data/registry/react/components/textarea/styles.module.css +54 -0
  82. package/data/registry/react/components/toast/index.module.tsx +258 -0
  83. package/data/registry/react/components/toast/styles.module.css +290 -0
  84. package/data/registry/react/components/toggle/index.module.tsx +131 -0
  85. package/data/registry/react/components/toggle/styles.module.css +85 -0
  86. package/data/registry/react/components/tooltip/index.module.tsx +83 -0
  87. package/data/registry/react/components/tooltip/styles.module.css +44 -0
  88. package/data/registry/react/registry.json +604 -1
  89. package/data/tokens/build.mjs +4 -0
  90. package/package.json +1 -1
  91. package/src/add.mjs +12 -12
  92. package/src/api.d.ts +4 -3
  93. package/src/constants.js +4 -3
@@ -0,0 +1,350 @@
1
+ /* ───── Root ───── */
2
+ .header {
3
+ position: relative;
4
+ display: flex;
5
+ align-items: center;
6
+ gap: var(--space-4);
7
+ height: var(--control-md);
8
+ padding: 0 var(--space-3);
9
+ background: var(--background);
10
+ border-bottom: 1px solid var(--border);
11
+ transition: transform var(--duration-base) var(--ease-standard),
12
+ background-color var(--duration-base) var(--ease-standard);
13
+ /* hover/active 배경 — transparent/blur variant 가 currentColor 기반으로 재정의 */
14
+ --sh-ui-header-hover-bg: var(--background-muted);
15
+ /* blur variant 튜닝용 — instance 별 style 로 override 가능 */
16
+ --sh-ui-header-blur-opacity: 85%;
17
+ --sh-ui-header-blur-radius: 16px;
18
+ }
19
+
20
+ /* prefers-reduced-motion — stickyHide 슬라이드 애니메이션을 즉시 toggle 로 대체.
21
+ variant 전환의 background 트랜지션도 비활성화. */
22
+ @media (prefers-reduced-motion: reduce) {
23
+ .header {
24
+ transition: none;
25
+ }
26
+ }
27
+
28
+ /* variant */
29
+ .header--solid {
30
+ background: var(--background);
31
+ }
32
+ .header--transparent {
33
+ background: transparent;
34
+ border-bottom-color: transparent;
35
+ /* 컬러풀 배경 위에서도 자연스러운 hover — 텍스트 색의 14% 오버레이 */
36
+ --sh-ui-header-hover-bg: color-mix(in srgb, currentColor 14%, transparent);
37
+ }
38
+ .header--blur {
39
+ background: color-mix(in srgb, var(--background) var(--sh-ui-header-blur-opacity), transparent);
40
+ backdrop-filter: saturate(180%) blur(var(--sh-ui-header-blur-radius));
41
+ -webkit-backdrop-filter: saturate(180%) blur(var(--sh-ui-header-blur-radius));
42
+ --sh-ui-header-hover-bg: color-mix(in srgb, currentColor 14%, transparent);
43
+ }
44
+ /* backdrop-filter 미지원 브라우저 폴백 — 더 불투명한 배경으로 가독성 확보 */
45
+ @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
46
+ .header--blur {
47
+ background: var(--background);
48
+ }
49
+ }
50
+
51
+ /* sticky-hide — sticky 컨텍스트는 사용자가 직접 (예: position:sticky; top:0) 적용. */
52
+ .header[data-sticky-hide][data-hidden] {
53
+ transform: translateY(-100%);
54
+ }
55
+
56
+ /* ───── Brand ───── */
57
+ .header__brand {
58
+ display: inline-flex;
59
+ align-items: center;
60
+ gap: var(--space-2);
61
+ flex-shrink: 0;
62
+ }
63
+ .header__logo {
64
+ display: inline-flex;
65
+ align-items: center;
66
+ color: var(--foreground);
67
+ }
68
+ .header__title {
69
+ font-size: var(--text-base);
70
+ font-weight: var(--weight-bold);
71
+ color: var(--foreground);
72
+ letter-spacing: -0.3px;
73
+ }
74
+
75
+ /* ───── Trigger (햄버거) ───── */
76
+ .header__trigger {
77
+ display: none;
78
+ align-items: center;
79
+ justify-content: center;
80
+ width: 2.25rem;
81
+ height: 2.25rem;
82
+ padding: 0;
83
+ background: transparent;
84
+ border: 0;
85
+ color: var(--foreground);
86
+ border-radius: calc(var(--radius) - 2px);
87
+ cursor: pointer;
88
+ transition: background-color var(--duration-fast);
89
+ }
90
+ .header__trigger:hover {
91
+ background: var(--sh-ui-header-hover-bg);
92
+ }
93
+ .header__trigger:focus-visible {
94
+ outline: var(--border-width-strong) solid var(--foreground);
95
+ outline-offset: 2px;
96
+ }
97
+
98
+ /* ───── Inline Nav ───── */
99
+ .header__nav {
100
+ display: flex;
101
+ align-items: center;
102
+ gap: var(--space-1);
103
+ flex: 1;
104
+ min-width: 0;
105
+ overflow-x: auto;
106
+ scrollbar-width: none;
107
+ }
108
+ .header__nav::-webkit-scrollbar {
109
+ display: none;
110
+ }
111
+
112
+ /* ───── Item ───── */
113
+ .header__item {
114
+ display: inline-flex;
115
+ align-items: center;
116
+ gap: var(--space-1);
117
+ padding: var(--space-2) var(--space-3);
118
+ font-size: var(--text-sm);
119
+ font-weight: var(--weight-medium);
120
+ color: var(--foreground-muted);
121
+ text-decoration: none;
122
+ background: transparent;
123
+ border: 0;
124
+ border-radius: calc(var(--radius) - 2px);
125
+ cursor: pointer;
126
+ white-space: nowrap;
127
+ transition: color var(--duration-fast), background-color var(--duration-fast);
128
+ }
129
+ .header__item:hover {
130
+ color: var(--foreground);
131
+ background: var(--sh-ui-header-hover-bg);
132
+ }
133
+ .header__item[data-active] {
134
+ color: var(--foreground);
135
+ font-weight: var(--weight-semibold);
136
+ }
137
+ .header__item:focus-visible {
138
+ outline: var(--border-width-strong) solid var(--foreground);
139
+ outline-offset: 2px;
140
+ }
141
+
142
+ /* ───── Actions ───── */
143
+ .header__actions {
144
+ display: inline-flex;
145
+ align-items: center;
146
+ gap: var(--space-2);
147
+ margin-left: auto;
148
+ flex-shrink: 0;
149
+ }
150
+
151
+ /* ───── 반응형 가시성 유틸 (HeaderDesktopOnly / HeaderMobileOnly) ─────
152
+ * display: contents 로 wrapper 가 레이아웃에 잡히지 않게 함 — 부모(HeaderActions 등)의 flex 흐름 유지.
153
+ */
154
+ .header__desktop-only {
155
+ display: contents;
156
+ }
157
+ .header__mobile-only {
158
+ display: none;
159
+ }
160
+
161
+ /* ───── NavGroup ─────
162
+ * inline 모드에서는 자식만 펼친 것처럼 평면 렌더(라벨 숨김).
163
+ * drawer 모드에서는 라벨 + 들여쓴 항목.
164
+ */
165
+ .header__group--inline {
166
+ display: contents;
167
+ }
168
+ .header__group--drawer {
169
+ display: flex;
170
+ flex-direction: column;
171
+ margin-top: var(--space-3);
172
+ }
173
+ .header__group--drawer:first-child {
174
+ margin-top: 0;
175
+ }
176
+ .header__group-label {
177
+ display: flex;
178
+ align-items: center;
179
+ height: 2rem;
180
+ padding: 0 var(--space-2);
181
+ font-size: var(--text-xs);
182
+ font-weight: var(--weight-medium);
183
+ color: var(--foreground-muted);
184
+ }
185
+ .header__group-items {
186
+ display: flex;
187
+ flex-direction: column;
188
+ gap: 1px;
189
+ }
190
+
191
+ /* ───── Menu (서브메뉴) — inline 모드 = dropdown ───── */
192
+ .header__menu {
193
+ position: relative;
194
+ }
195
+ .header__menu--inline {
196
+ display: inline-block;
197
+ }
198
+ .header__menu-trigger {
199
+ display: inline-flex;
200
+ align-items: center;
201
+ gap: var(--space-1);
202
+ padding: var(--space-2) var(--space-3);
203
+ font-size: var(--text-sm);
204
+ font-weight: var(--weight-medium);
205
+ color: var(--foreground-muted);
206
+ background: transparent;
207
+ border: 0;
208
+ border-radius: calc(var(--radius) - 2px);
209
+ cursor: pointer;
210
+ white-space: nowrap;
211
+ transition: color var(--duration-fast), background-color var(--duration-fast);
212
+ }
213
+ .header__menu-trigger:hover,
214
+ .header__menu-trigger[data-open] {
215
+ color: var(--foreground);
216
+ background: var(--sh-ui-header-hover-bg);
217
+ }
218
+ .header__menu-trigger:focus-visible {
219
+ outline: var(--border-width-strong) solid var(--foreground);
220
+ outline-offset: 2px;
221
+ }
222
+ .header__chevron {
223
+ transition: transform var(--duration-fast) var(--ease-standard);
224
+ }
225
+ .header__menu-trigger[data-open] .header__chevron {
226
+ transform: rotate(180deg);
227
+ }
228
+
229
+ /* inline 모드 dropdown 은 portal 로 document.body 에 렌더된다 — 부모 overflow 영향 받지 않음. */
230
+ .header__menu-content--portal {
231
+ z-index: var(--z-dropdown, 50);
232
+ padding: var(--space-1);
233
+ background: var(--background);
234
+ border: 1px solid var(--border);
235
+ border-radius: var(--radius);
236
+ box-shadow: 0 8px 24px -8px rgba(0, 0, 0, 0.18);
237
+ display: flex;
238
+ flex-direction: column;
239
+ gap: 1px;
240
+ color: var(--foreground);
241
+ }
242
+ .header__menu-content--portal .header__item {
243
+ padding: var(--space-2) var(--space-3);
244
+ font-size: var(--text-sm);
245
+ }
246
+
247
+ /* ───── Drawer (backdrop + panel) — 기본 숨김 ───── */
248
+ .header__backdrop,
249
+ .header__drawer {
250
+ display: none;
251
+ }
252
+
253
+ /* ───── Mobile (< breakpoint.md) ───── */
254
+ @media (max-width: 767px) {
255
+ .header__trigger {
256
+ display: inline-flex;
257
+ order: -1;
258
+ }
259
+ .header__nav {
260
+ display: none;
261
+ }
262
+ .header {
263
+ gap: var(--space-2);
264
+ }
265
+ /* 가시성 유틸 토글 */
266
+ .header__desktop-only {
267
+ display: none;
268
+ }
269
+ .header__mobile-only {
270
+ display: contents;
271
+ }
272
+
273
+ /* backdrop */
274
+ .header__backdrop {
275
+ display: block;
276
+ position: fixed;
277
+ inset: 0;
278
+ background: rgba(0, 0, 0, 0.25);
279
+ backdrop-filter: blur(8px);
280
+ z-index: var(--z-overlay);
281
+ opacity: 0;
282
+ pointer-events: none;
283
+ transition: opacity var(--duration-base) var(--ease-standard);
284
+ }
285
+ .header__backdrop[data-open] {
286
+ opacity: 1;
287
+ pointer-events: auto;
288
+ }
289
+
290
+ /* drawer panel */
291
+ .header__drawer {
292
+ display: flex;
293
+ position: fixed;
294
+ left: 0;
295
+ top: 0;
296
+ bottom: 0;
297
+ width: min(17.5rem, 85vw);
298
+ background: var(--background-subtle);
299
+ border-right: 1px solid var(--border);
300
+ z-index: var(--z-modal);
301
+ transform: translateX(-100%);
302
+ transition: transform var(--duration-base) var(--ease-standard);
303
+ flex-direction: column;
304
+ overflow-y: auto;
305
+ }
306
+ .header__drawer[data-open] {
307
+ transform: translateX(0);
308
+ }
309
+
310
+ .header__drawer-head {
311
+ display: flex;
312
+ align-items: center;
313
+ justify-content: flex-end;
314
+ padding: var(--space-2) var(--space-2);
315
+ border-bottom: 1px solid var(--border);
316
+ }
317
+
318
+ .header__drawer-nav {
319
+ display: flex;
320
+ flex-direction: column;
321
+ padding: var(--space-2);
322
+ gap: 1px;
323
+ }
324
+
325
+ .header__drawer .header__item {
326
+ padding: var(--space-3) var(--space-3);
327
+ font-size: var(--text-sm);
328
+ border-radius: calc(var(--radius) - 2px);
329
+ }
330
+
331
+ /* Menu in drawer = collapsible */
332
+ .header__menu--drawer {
333
+ display: flex;
334
+ flex-direction: column;
335
+ }
336
+ .header__menu--drawer > .header__menu-trigger {
337
+ justify-content: space-between;
338
+ width: 100%;
339
+ padding: var(--space-3) var(--space-3);
340
+ }
341
+ .header__menu--drawer > .header__menu-content {
342
+ display: flex;
343
+ flex-direction: column;
344
+ padding: var(--space-1) 0 var(--space-1) var(--space-4);
345
+ gap: 1px;
346
+ }
347
+ .header__menu--drawer > .header__menu-content[hidden] {
348
+ display: none;
349
+ }
350
+ }