sh-ui-cli 0.82.2 → 0.83.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.
@@ -2,6 +2,28 @@
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.83.0",
7
+ "date": "2026-05-13",
8
+ "title": "Sidebar — data-when-collapsed 컨벤션 (custom JSX 의 collapsed/icon 자동 적응)",
9
+ "type": "minor",
10
+ "highlights": [
11
+ "**`<SidebarHeader>` / `<SidebarFooter>` 안 사용자 custom JSX 가 `collapsible=\"icon\"` 모드 전환 시 `useSidebar()` 훅 + 조건부 렌더 ceremony 없이 attribute 한 줄로 자동 적응** — 새 export 0개, 발견성 좋은 plain CSS 컨벤션. 값 (공백 구분 다중 토큰, `~=` 매처): `hide` (display:none) · `center` (가운데 정렬 + 좌우 padding 제거) · `strip-chrome` (border / background 투명). 워크스페이스 스위처 · 브랜드 카드 · 유저 프로필 등 admin/dashboard sidebar 의 흔한 패턴에 매번 박던 수동 처리 일소.",
12
+ "예시 — `<button data-when-collapsed=\"center strip-chrome\"> <Avatar /> <div data-when-collapsed=\"hide\">{name}</div> <ChevronsUpDown data-when-collapsed=\"hide\" /></button>` — collapsed 모드에선 Avatar 만 가운데 정렬돼 보이고 카드 chrome 사라짐.",
13
+ "**3 변종 모두 지원** — plain `styles.css` / module `styles.module.css` 에 직접 룰. tailwind 변종은 CSS import 없어 `SidebarProvider` mount 시 1회 head 에 `<style id=\"sh-ui-sidebar-helpers\">` inject (모듈 레벨 dedup). 사용자 코드는 변종 무관 동일 attribute 만 박으면 됨."
14
+ ],
15
+ "url": "https://github.com/sanghyeonKim0201/sh-ui/releases/tag/v0.83.0"
16
+ },
17
+ {
18
+ "version": "0.82.3",
19
+ "date": "2026-05-13",
20
+ "title": "스캐폴드 dependencies 에서 미사용 zustand 제거",
21
+ "type": "patch",
22
+ "highlights": [
23
+ "**`nextjs-app` / `nextjs-standalone` 템플릿의 `dependencies` 에서 `zustand@^5.0.11` 제거** — 두 템플릿에 박혀 있었지만 어디서도 import / store 정의 없이 dep 만 설치되던 노이즈. 필요할 때 사용자가 `pnpm add zustand` 한 줄로 추가. 번들 영향은 처음부터 없었지만 (tree-shaken) `pnpm install` 시간 / lockfile / dep 표면적이 줄어듦."
24
+ ],
25
+ "url": "https://github.com/sanghyeonKim0201/sh-ui/releases/tag/v0.82.3"
26
+ },
5
27
  {
6
28
  "version": "0.82.2",
7
29
  "date": "2026-05-13",
@@ -10,6 +10,29 @@ const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
10
10
  const SIDEBAR_KEYBOARD_SHORTCUT = "b";
11
11
  const MOBILE_BREAKPOINT = 768;
12
12
 
13
+ /**
14
+ * v0.83.0+ — `data-when-collapsed` 컨벤션을 위한 CSS 룰 inject.
15
+ *
16
+ * plain/module 변종은 styles.css/.module.css 가 import 되며 자동으로 룰이 깔리는데,
17
+ * tailwind 변종은 별도 CSS import 가 없으므로 SidebarProvider mount 시 한 번만 head
18
+ * 에 <style> 박는다. id="sh-ui-sidebar-helpers" 로 중복 inject 방지.
19
+ *
20
+ * 토큰: hide(display:none) · center(가운데 정렬 + 좌우 padding 0) · strip-chrome
21
+ * (border/bg 투명). `~=` 매처로 공백 구분 다중 토큰 지원.
22
+ */
23
+ const SIDEBAR_HELPER_STYLE_ID = "sh-ui-sidebar-helpers";
24
+ const SIDEBAR_HELPER_CSS = `[data-state="collapsed"][data-collapsible="icon"] [data-when-collapsed~="hide"]{display:none}[data-state="collapsed"][data-collapsible="icon"] [data-when-collapsed~="center"]{justify-content:center;padding-left:0;padding-right:0}[data-state="collapsed"][data-collapsible="icon"] [data-when-collapsed~="strip-chrome"]{border-color:transparent;background-color:transparent}`;
25
+ function useSidebarHelperStyles() {
26
+ React.useEffect(() => {
27
+ if (typeof document === "undefined") return;
28
+ if (document.getElementById(SIDEBAR_HELPER_STYLE_ID)) return;
29
+ const style = document.createElement("style");
30
+ style.id = SIDEBAR_HELPER_STYLE_ID;
31
+ style.textContent = SIDEBAR_HELPER_CSS;
32
+ document.head.appendChild(style);
33
+ }, []);
34
+ }
35
+
13
36
  const FOCUSABLE_SELECTOR =
14
37
  'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';
15
38
 
@@ -77,6 +100,7 @@ export interface SidebarProviderProps extends React.HTMLAttributes<HTMLDivElemen
77
100
  export function SidebarProvider({
78
101
  defaultOpen = true, open: openProp, onOpenChange: setOpenProp, className, style, children, embedded, ...props
79
102
  }: SidebarProviderProps) {
103
+ useSidebarHelperStyles();
80
104
  const isMobile = useIsMobile();
81
105
  const [openMobile, setOpenMobile] = React.useState(false);
82
106
  const [_open, _setOpen] = React.useState(defaultOpen);
@@ -288,6 +288,36 @@
288
288
  border-bottom: 1px solid var(--sidebar-border);
289
289
  }
290
290
 
291
+ /* ───────────── data-when-collapsed 컨벤션 (v0.83.0+) ─────────────
292
+ * SidebarHeader / SidebarFooter 안의 사용자 custom JSX (WorkspaceSwitcher,
293
+ * 브랜드 카드, 유저 프로필 등) 가 collapsible="icon" 모드 전환 시 자동
294
+ * 적응하도록 일반 attribute 컨벤션 제공. 사용자가 useSidebar() 훅 + 조건부
295
+ * 렌더 ceremony 없이 attribute 한 줄로 처리.
296
+ *
297
+ * 사용:
298
+ * <button data-when-collapsed="center strip-chrome">
299
+ * <Avatar />
300
+ * <div data-when-collapsed="hide">{name}</div>
301
+ * <ChevronsUpDown data-when-collapsed="hide" />
302
+ * </button>
303
+ *
304
+ * 값(공백 구분 토큰 — `~=` 매처):
305
+ * hide — collapsed/icon 모드에서 display:none
306
+ * center — 가로 가운데 정렬 + 좌우 padding 제거
307
+ * strip-chrome — border / background 투명화 (카드 chrome 제거) */
308
+ .sh-ui-sidebar[data-state="collapsed"][data-collapsible="icon"] [data-when-collapsed~="hide"] {
309
+ display: none;
310
+ }
311
+ .sh-ui-sidebar[data-state="collapsed"][data-collapsible="icon"] [data-when-collapsed~="center"] {
312
+ justify-content: center;
313
+ padding-left: 0;
314
+ padding-right: 0;
315
+ }
316
+ .sh-ui-sidebar[data-state="collapsed"][data-collapsible="icon"] [data-when-collapsed~="strip-chrome"] {
317
+ border-color: transparent;
318
+ background-color: transparent;
319
+ }
320
+
291
321
  .sh-ui-sidebar__content {
292
322
  display: flex;
293
323
  flex-direction: column;
@@ -285,6 +285,22 @@
285
285
  border-bottom: 1px solid var(--sidebar-border);
286
286
  }
287
287
 
288
+ /* data-when-collapsed 컨벤션 (v0.83.0+) — 사용자 custom JSX (WorkspaceSwitcher 등) 가
289
+ * collapsible="icon" 모드 전환 시 자동 적응. 값: hide / center / strip-chrome.
290
+ * 자세한 설명은 plain 변종 styles.css 참고. */
291
+ .sidebar[data-state="collapsed"][data-collapsible="icon"] [data-when-collapsed~="hide"] {
292
+ display: none;
293
+ }
294
+ .sidebar[data-state="collapsed"][data-collapsible="icon"] [data-when-collapsed~="center"] {
295
+ justify-content: center;
296
+ padding-left: 0;
297
+ padding-right: 0;
298
+ }
299
+ .sidebar[data-state="collapsed"][data-collapsible="icon"] [data-when-collapsed~="strip-chrome"] {
300
+ border-color: transparent;
301
+ background-color: transparent;
302
+ }
303
+
288
304
  .sidebar__content {
289
305
  display: flex;
290
306
  flex-direction: column;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sh-ui-cli",
3
- "version": "0.82.2",
3
+ "version": "0.83.0",
4
4
  "description": "sh-ui CLI — 프로젝트 스캐폴드(create) + 컴포넌트 추가(add/list/remove) + IDE-내 AI용 MCP 서버",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -24,8 +24,7 @@
24
24
  "react-dom": "^19.2.4",
25
25
  "server-only": "^0.0.1",
26
26
  "sonner": "^2.0.7",
27
- "zod": "^4.3.6",
28
- "zustand": "^5.0.11"
27
+ "zod": "^4.3.6"
29
28
  },
30
29
  "devDependencies": {
31
30
  "@tailwindcss/postcss": "^4.1.18",
@@ -26,8 +26,7 @@
26
26
  "react-dom": "^19.2.4",
27
27
  "sonner": "^2.0.7",
28
28
  "tailwind-merge": "^3.5.0",
29
- "zod": "^4.3.6",
30
- "zustand": "^5.0.11"
29
+ "zod": "^4.3.6"
31
30
  },
32
31
  "devDependencies": {
33
32
  "@eslint/js": "^9.39.2",