@jogak/ui 0.1.0-alpha.2 → 0.1.0-alpha.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/CHANGELOG.md CHANGED
@@ -5,6 +5,37 @@ All notable changes to Jogak packages are documented here. The repository follow
5
5
 
6
6
  Version numbers apply to all packages in the workspace (synchronized release).
7
7
 
8
+ ## [0.1.0-alpha.4] — 2026-05-08
9
+
10
+ ### Internal
11
+
12
+ - `@jogak/ui` SPA 빌드 파이프라인에 Tailwind v4 + `prefix(jogak)` 도입 (인프라 단계).
13
+ 사용자 번들 / publish 산출물에는 영향 없음.
14
+ - jogak 디자인 토큰을 `--jogak-*` CSS variable로 정의 (알파.5 컴포넌트 마이그레이션 대비).
15
+ - jogak SPA에 `data-jogak-shell` / `data-jogak-content` wrapper 추가 (알파.6 사용자 globalCss
16
+ scope 정책 hook).
17
+
18
+ ### Notes
19
+
20
+ - jogak UI 컴포넌트(Sidebar/Preview/Controls/Actions)는 여전히 inline style 사용. Tailwind class
21
+ 마이그레이션은 알파.5에서 진행.
22
+ - 사용자 프로젝트의 globalCss(예: `src/index.css`)는 **현재 jogak SPA에 적용되지 않습니다**. 알파.6에서
23
+ `JogakPluginOptions.globalCss` opt-in으로 지원 예정.
24
+ - 사용자 프로젝트가 Tailwind를 사용해도 jogak prefix(`jogak:`)와 충돌하지 않음.
25
+
26
+ ## [0.1.0-alpha.3] — 2026-05-07
27
+
28
+ ### Added
29
+
30
+ - **`@jogak/core`**: Vite plugin now auto-detects user `tsconfig.json` (and `tsconfig.app.json` for the Vite scaffold-default split-references layout) and converts `compilerOptions.paths` into `vite resolve.alias`. This makes `runHost`-driven dev/build work zero-config for projects that use path aliases (shadcn/ui's `@/lib/utils` etc.). Without this, `runHost` ignored the user's `vite.config.ts` (`configFile: false`) and any `@/...` import inside a user component failed to resolve.
31
+ - **`JogakPluginOptions.resolveAlias`**: explicit user-provided alias map for cases the auto-extraction can't handle (extends chains, complex glob patterns). Explicit entries override auto-extracted ones. Relative paths are resolved against the user root.
32
+
33
+ ### Fixed
34
+
35
+ - Path aliases declared in user `tsconfig` are now respected during `jogak dev` and `jogak build`. Previously, every `*.jogak.tsx` that imported a component using `@/`-style imports would fail with `Failed to resolve import "@/..."` in the browser dev overlay.
36
+
37
+ Other packages: no source changes; version bumped to keep the workspace synchronized.
38
+
8
39
  ## [0.1.0-alpha.2] — 2026-05-07
9
40
 
10
41
  ### Fixed
package/README.md CHANGED
@@ -62,6 +62,21 @@ import { runHost } from '@jogak/ui/host' // Node-only, used by @jogak/cli
62
62
 
63
63
  See the [main README](https://github.com/devclib/jogak#readme) for the full host embedding guide.
64
64
 
65
+ ## Styling roadmap
66
+
67
+ | 단계 | 상태 | 내용 |
68
+ |------|------|------|
69
+ | alpha.4 | ✅ 본 릴리즈 | jogak UI 빌드 파이프라인에 Tailwind v4 + `jogak:` prefix 도입 (인프라) |
70
+ | alpha.5 | 예정 | jogak UI 컴포넌트를 Tailwind class로 마이그레이션 |
71
+ | alpha.6 | 예정 | 사용자 `globalCss` 옵션 지원 (`JogakPluginOptions.globalCss`) |
72
+ | alpha.7+ | 검토 | preview Shadow DOM / iframe 격리 옵션 |
73
+
74
+ ### 현 한계 (alpha.4)
75
+
76
+ - jogak SPA는 사용자 프로젝트의 globalCss(예: Tailwind, shadcn/ui)를 자동 import하지 않습니다.
77
+ jogak chrome은 자체 스타일만 사용하며, preview 안의 사용자 컴포넌트도 jogak 빌드 환경에서 렌더됩니다.
78
+ - 사용자 globalCss를 적용하려면 알파.6을 기다려 주세요.
79
+
65
80
  - Repository: https://github.com/devclib/jogak
66
81
  - Issues: https://github.com/devclib/jogak/issues
67
82
  - License: [MIT](./LICENSE)
@@ -1 +1 @@
1
- "use strict";var L=Object.create;var g=Object.defineProperty;var M=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var k=Object.getPrototypeOf,A=Object.prototype.hasOwnProperty;var B=(t,e,o,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of S(e))!A.call(t,n)&&n!==o&&g(t,n,{get:()=>e[n],enumerable:!(r=M(e,n))||r.enumerable});return t};var a=(t,e,o)=>(o=t!=null?L(k(t)):{},B(e||!t||!t.__esModule?g(o,"default",{value:t,enumerable:!0}):o,t));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const H=require("node:url"),i=require("node:path");var l=typeof document<"u"?document.currentScript:null;const N=H.fileURLToPath(typeof document>"u"?require("url").pathToFileURL(__filename).href:l&&l.tagName.toUpperCase()==="SCRIPT"&&l.src||new URL("host/index.js",document.baseURI).href),u=i.resolve(i.dirname(N),"..",".."),x=i.resolve(u,"index.html"),F=i.resolve(u,"src/app/main.tsx");async function E(t){const e=await import("vite"),o=await import("@vitejs/plugin-react"),r=await import("@jogak/core/vite"),{createServer:n,build:h}=e,b=o.default,{jogak:v}=r,_=t.codeTheme??"vsDark",f={patterns:t.patterns,codeTheme:_,cwd:t.userRoot};t.tsConfigFilePath!==void 0&&(f.tsConfigFilePath=t.tsConfigFilePath);const R=t.extraPlugins??[],d={root:u,configFile:!1,plugins:[b(),v(f),...R],optimizeDeps:{include:["react","react-dom/client","@jogak/core","@jogak/react"]}};if(t.mode==="dev"){const O={port:t.port??5173,host:t.host??"localhost",open:t.open??!1,fs:{allow:[u,t.userRoot]}},j={...d,server:O},s=await n(j);await s.listen();const p=s.config.server.port??t.port??5173,c=t.host??"localhost",D=`http://${typeof c=="boolean"?c?"0.0.0.0":"localhost":c}:${p.toString()}/`;let y=!1;return{url:D,port:p,close:async()=>{y||(y=!0,await s.close())},printUrls:()=>{s.printUrls()}}}const w={...d,base:t.base??"./",build:{outDir:t.outDir,emptyOutDir:!0,sourcemap:t.sourcemap??!1,minify:t.minify??"esbuild"}},C=Date.now(),T=await h(w),U=Date.now()-C,{assetCount:P,totalBytes:I}=Y(T);return{outDir:t.outDir,elapsedMs:U,assetCount:P,totalBytes:I}}function Y(t){const e=q(t);if(e===void 0)return{assetCount:0,totalBytes:0};let o=0,r=0;for(const n of e)o+=1,r+=z(n);return{assetCount:o,totalBytes:r}}function m(t){return typeof t=="object"&&t!==null&&Array.isArray(t.output)}function q(t){if(Array.isArray(t)){const e=[];for(const o of t)m(o)&&e.push(...o.output);return e}if(m(t))return t.output}function z(t){if(typeof t!="object"||t===null)return 0;const e=t;if(e.type==="chunk"&&typeof e.code=="string")return Buffer.byteLength(e.code,"utf8");if(e.type==="asset"){const o=e.source;if(typeof o=="string")return Buffer.byteLength(o,"utf8");if(o instanceof Uint8Array)return o.byteLength}return 0}exports.UI_HTML_ENTRY=x;exports.UI_MAIN_ENTRY=F;exports.runHost=E;
1
+ "use strict";var S=Object.create;var y=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var B=Object.getPrototypeOf,H=Object.prototype.hasOwnProperty;var N=(t,e,o,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of A(e))!H.call(t,n)&&n!==o&&y(t,n,{get:()=>e[n],enumerable:!(r=k(e,n))||r.enumerable});return t};var i=(t,e,o)=>(o=t!=null?S(B(t)):{},N(e||!t||!t.__esModule?y(o,"default",{value:t,enumerable:!0}):o,t));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const x=require("node:url"),u=require("node:path");var l=typeof document<"u"?document.currentScript:null;const F=x.fileURLToPath(typeof document>"u"?require("url").pathToFileURL(__filename).href:l&&l.tagName.toUpperCase()==="SCRIPT"&&l.src||new URL("host/index.js",document.baseURI).href),c=u.resolve(u.dirname(F),"..",".."),E=u.resolve(c,"index.html"),Y=u.resolve(c,"src/app/main.tsx");async function q(t){const e=await import("vite"),o=await import("@vitejs/plugin-react"),r=await import("@jogak/core/vite"),n=await import("@tailwindcss/vite"),{createServer:h,build:b}=e,v=o.default,_=n.default,{jogak:w}=r,R=t.codeTheme??"vsDark",f={patterns:t.patterns,codeTheme:R,cwd:t.userRoot};t.tsConfigFilePath!==void 0&&(f.tsConfigFilePath=t.tsConfigFilePath);const C=t.extraPlugins??[],d={root:c,configFile:!1,plugins:[v(),_(),w(f),...C],optimizeDeps:{include:["react","react-dom/client","@jogak/core","@jogak/react"]}};if(t.mode==="dev"){const D={port:t.port??5173,host:t.host??"localhost",open:t.open??!1,fs:{allow:[c,t.userRoot]}},L={...d,server:D},s=await h(L);await s.listen();const p=s.config.server.port??t.port??5173,a=t.host??"localhost",M=`http://${typeof a=="boolean"?a?"0.0.0.0":"localhost":a}:${p.toString()}/`;let g=!1;return{url:M,port:p,close:async()=>{g||(g=!0,await s.close())},printUrls:()=>{s.printUrls()}}}const P={...d,base:t.base??"./",build:{outDir:t.outDir,emptyOutDir:!0,sourcemap:t.sourcemap??!1,minify:t.minify??"esbuild"}},T=Date.now(),U=await b(P),I=Date.now()-T,{assetCount:O,totalBytes:j}=z(U);return{outDir:t.outDir,elapsedMs:I,assetCount:O,totalBytes:j}}function z(t){const e=$(t);if(e===void 0)return{assetCount:0,totalBytes:0};let o=0,r=0;for(const n of e)o+=1,r+=G(n);return{assetCount:o,totalBytes:r}}function m(t){return typeof t=="object"&&t!==null&&Array.isArray(t.output)}function $(t){if(Array.isArray(t)){const e=[];for(const o of t)m(o)&&e.push(...o.output);return e}if(m(t))return t.output}function G(t){if(typeof t!="object"||t===null)return 0;const e=t;if(e.type==="chunk"&&typeof e.code=="string")return Buffer.byteLength(e.code,"utf8");if(e.type==="asset"){const o=e.source;if(typeof o=="string")return Buffer.byteLength(o,"utf8");if(o instanceof Uint8Array)return o.byteLength}return 0}exports.UI_HTML_ENTRY=E;exports.UI_MAIN_ENTRY=Y;exports.runHost=q;
@@ -1,47 +1,47 @@
1
- import { fileURLToPath as k } from "node:url";
2
- import { resolve as u, dirname as B } from "node:path";
3
- const T = k(import.meta.url), s = u(B(T), "..", ".."), F = u(s, "index.html"), z = u(s, "src/app/main.tsx");
4
- async function N(t) {
5
- const e = await import("vite"), o = await import("@vitejs/plugin-react"), r = await import("@jogak/core/vite"), { createServer: i, build: g } = e, m = o.default, { jogak: y } = r, h = t.codeTheme ?? "vsDark", a = {
1
+ import { fileURLToPath as T } from "node:url";
2
+ import { resolve as u, dirname as U } from "node:path";
3
+ const A = T(import.meta.url), i = u(U(A), "..", ".."), N = u(i, "index.html"), S = u(i, "src/app/main.tsx");
4
+ async function $(t) {
5
+ const o = await import("vite"), e = await import("@vitejs/plugin-react"), n = await import("@jogak/core/vite"), s = await import("@tailwindcss/vite"), { createServer: g, build: m } = o, y = e.default, h = s.default, { jogak: b } = n, w = t.codeTheme ?? "vsDark", a = {
6
6
  patterns: t.patterns,
7
- codeTheme: h,
7
+ codeTheme: w,
8
8
  cwd: t.userRoot
9
9
  };
10
10
  t.tsConfigFilePath !== void 0 && (a.tsConfigFilePath = t.tsConfigFilePath);
11
- const b = t.extraPlugins ?? [], l = {
12
- root: s,
11
+ const v = t.extraPlugins ?? [], l = {
12
+ root: i,
13
13
  configFile: !1,
14
14
  // ui/vite.config.ts 무시
15
- plugins: [m(), y(a), ...b],
15
+ plugins: [y(), h(), b(a), ...v],
16
16
  optimizeDeps: {
17
17
  include: ["react", "react-dom/client", "@jogak/core", "@jogak/react"]
18
18
  }
19
19
  };
20
20
  if (t.mode === "dev") {
21
- const R = {
21
+ const j = {
22
22
  port: t.port ?? 5173,
23
23
  host: t.host ?? "localhost",
24
24
  open: t.open ?? !1,
25
- fs: { allow: [s, t.userRoot] }
26
- }, _ = {
25
+ fs: { allow: [i, t.userRoot] }
26
+ }, k = {
27
27
  ...l,
28
- server: R
29
- }, n = await i(_);
30
- await n.listen();
31
- const f = n.config.server.port ?? t.port ?? 5173, c = t.host ?? "localhost", j = `http://${typeof c == "boolean" ? c ? "0.0.0.0" : "localhost" : c}:${f.toString()}/`;
28
+ server: j
29
+ }, r = await g(k);
30
+ await r.listen();
31
+ const f = r.config.server.port ?? t.port ?? 5173, c = t.host ?? "localhost", B = `http://${typeof c == "boolean" ? c ? "0.0.0.0" : "localhost" : c}:${f.toString()}/`;
32
32
  let d = !1;
33
33
  return {
34
- url: j,
34
+ url: B,
35
35
  port: f,
36
36
  close: async () => {
37
- d || (d = !0, await n.close());
37
+ d || (d = !0, await r.close());
38
38
  },
39
39
  printUrls: () => {
40
- n.printUrls();
40
+ r.printUrls();
41
41
  }
42
42
  };
43
43
  }
44
- const v = {
44
+ const P = {
45
45
  ...l,
46
46
  base: t.base ?? "./",
47
47
  build: {
@@ -50,50 +50,50 @@ async function N(t) {
50
50
  sourcemap: t.sourcemap ?? !1,
51
51
  minify: t.minify ?? "esbuild"
52
52
  }
53
- }, w = Date.now(), C = await g(v), P = Date.now() - w, { assetCount: D, totalBytes: O } = U(C);
53
+ }, C = Date.now(), D = await m(P), O = Date.now() - C, { assetCount: R, totalBytes: _ } = L(D);
54
54
  return {
55
55
  outDir: t.outDir,
56
- elapsedMs: P,
57
- assetCount: D,
58
- totalBytes: O
56
+ elapsedMs: O,
57
+ assetCount: R,
58
+ totalBytes: _
59
59
  };
60
60
  }
61
- function U(t) {
62
- const e = A(t);
63
- if (e === void 0)
61
+ function L(t) {
62
+ const o = M(t);
63
+ if (o === void 0)
64
64
  return { assetCount: 0, totalBytes: 0 };
65
- let o = 0, r = 0;
66
- for (const i of e)
67
- o += 1, r += L(i);
68
- return { assetCount: o, totalBytes: r };
65
+ let e = 0, n = 0;
66
+ for (const s of o)
67
+ e += 1, n += x(s);
68
+ return { assetCount: e, totalBytes: n };
69
69
  }
70
70
  function p(t) {
71
71
  return typeof t == "object" && t !== null && Array.isArray(t.output);
72
72
  }
73
- function A(t) {
73
+ function M(t) {
74
74
  if (Array.isArray(t)) {
75
- const e = [];
76
- for (const o of t)
77
- p(o) && e.push(...o.output);
78
- return e;
75
+ const o = [];
76
+ for (const e of t)
77
+ p(e) && o.push(...e.output);
78
+ return o;
79
79
  }
80
80
  if (p(t))
81
81
  return t.output;
82
82
  }
83
- function L(t) {
83
+ function x(t) {
84
84
  if (typeof t != "object" || t === null) return 0;
85
- const e = t;
86
- if (e.type === "chunk" && typeof e.code == "string")
87
- return Buffer.byteLength(e.code, "utf8");
88
- if (e.type === "asset") {
89
- const o = e.source;
90
- if (typeof o == "string") return Buffer.byteLength(o, "utf8");
91
- if (o instanceof Uint8Array) return o.byteLength;
85
+ const o = t;
86
+ if (o.type === "chunk" && typeof o.code == "string")
87
+ return Buffer.byteLength(o.code, "utf8");
88
+ if (o.type === "asset") {
89
+ const e = o.source;
90
+ if (typeof e == "string") return Buffer.byteLength(e, "utf8");
91
+ if (e instanceof Uint8Array) return e.byteLength;
92
92
  }
93
93
  return 0;
94
94
  }
95
95
  export {
96
- F as UI_HTML_ENTRY,
97
- z as UI_MAIN_ENTRY,
98
- N as runHost
96
+ N as UI_HTML_ENTRY,
97
+ S as UI_MAIN_ENTRY,
98
+ $ as runHost
99
99
  };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),c=require("react"),k=require("@jogak/core"),j=require("@jogak/react"),z=require("prism-react-renderer");function I({selectedEntryId:t,selectedJogakName:n,onSelect:o}){const[i,s]=c.useState(""),{metaTree:r,searchMeta:l}=j.useRegistryMeta(),d=i.trim().length>0?l(i):null;return e.jsxs("aside",{"data-testid":"sidebar",style:{borderRight:"1px solid #e5e7eb",height:"100%",overflow:"auto",display:"flex",flexDirection:"column"},children:[e.jsx("div",{style:{padding:"12px",borderBottom:"1px solid #e5e7eb"},children:e.jsx("input",{type:"search",placeholder:"Search components...",value:i,onChange:a=>{s(a.target.value)},style:{width:"100%",padding:"6px 8px",border:"1px solid #d1d5db",borderRadius:4},"aria-label":"Search components"})}),e.jsx("nav",{style:{flex:1,overflow:"auto",padding:"8px 0"},children:d!==null?e.jsx(J,{metas:d,selectedEntryId:t,selectedJogakName:n,onSelect:o}):e.jsx(O,{node:r,selectedEntryId:t,selectedJogakName:n,onSelect:o})})]})}function J({metas:t,selectedEntryId:n,selectedJogakName:o,onSelect:i}){return t.length===0?e.jsx("p",{style:{padding:"0 12px",color:"#9ca3af",fontSize:13},children:"No results"}):e.jsx("ul",{style:{listStyle:"none",margin:0,padding:0},children:t.map(s=>e.jsx("li",{children:e.jsx($,{meta:s,selectedEntryId:n,selectedJogakName:o,onSelect:i,indent:0})},s.id))})}function O({node:t,selectedEntryId:n,selectedJogakName:o,onSelect:i,depth:s=0}){return e.jsx("ul",{style:{listStyle:"none",margin:0,padding:`0 0 0 ${s*12}px`},children:Object.entries(t).map(([r,l])=>e.jsx("li",{children:"id"in l?e.jsx($,{meta:l,selectedEntryId:n,selectedJogakName:o,onSelect:i,indent:0}):e.jsx(V,{label:r,node:l,selectedEntryId:n,selectedJogakName:o,onSelect:i,depth:s+1})},r))})}function V({label:t,node:n,selectedEntryId:o,selectedJogakName:i,onSelect:s,depth:r}){const[l,d]=c.useState(!0);return e.jsxs("div",{children:[e.jsxs("button",{type:"button",onClick:()=>{d(a=>!a)},style:{display:"flex",alignItems:"center",gap:4,width:"100%",padding:"4px 12px",background:"none",border:"none",cursor:"pointer",fontSize:12,fontWeight:600,color:"#6b7280",textTransform:"uppercase",letterSpacing:"0.05em"},"aria-expanded":l,children:[e.jsx("span",{children:l?"▾":"▸"}),t]}),l&&e.jsx(O,{node:n,selectedEntryId:o,selectedJogakName:i,onSelect:s,depth:r})]})}function $({meta:t,selectedEntryId:n,selectedJogakName:o,onSelect:i,indent:s}){const r=t.id===n,[l,d]=c.useState(r);c.useEffect(()=>{r&&d(!0)},[r]);const a=t.title.split("/").pop()??t.title,b=16+s*12;return e.jsxs("div",{children:[e.jsxs("button",{type:"button",onClick:()=>{if(r)d(p=>!p);else{d(!0);const p=t.jogakNames[0];p!==void 0&&i(t.id,p)}},style:{display:"flex",alignItems:"center",gap:6,width:"100%",padding:`5px 12px 5px ${b}px`,background:r?"#eff6ff":"none",border:"none",cursor:"pointer",fontSize:13,color:r?"#2563eb":"#374151",fontWeight:r?500:400,textAlign:"left"},"aria-expanded":l,children:[e.jsx("span",{style:{fontSize:10,flexShrink:0,lineHeight:1},children:l?"▾":"▸"}),a]}),l&&e.jsx("ul",{style:{listStyle:"none",margin:0,padding:0},children:t.jogakNames.map(p=>{const x=r&&p===o;return e.jsx("li",{children:e.jsx("button",{type:"button",onClick:()=>{i(t.id,p)},style:{display:"block",width:"100%",textAlign:"left",padding:`4px 12px 4px ${b+18}px`,background:x?"#dbeafe":"none",border:"none",cursor:"pointer",fontSize:12,color:x?"#1d4ed8":"#6b7280",fontWeight:x?500:400},"aria-current":x?"true":void 0,children:p})},p)})})]})}function q(t,n){const o=n==null?void 0:n.control,i=(n==null?void 0:n.action)!==void 0&&n.action!==!1,s=(n==null?void 0:n.type)==="function"||typeof t=="function";return i||s?"action":o==="boolean"||typeof t=="boolean"?"boolean":o==="number"||o==="range"||typeof t=="number"?"number":o==="select"||o==="radio"||(n==null?void 0:n.options)!==void 0&&n.options.length>0?"select":o==="text"||o==="color"||typeof t=="string"?"text":"json"}function U({argKey:t,value:n,argType:o,onArgChange:i}){switch(q(n,o)){case"boolean":return e.jsx("input",{type:"checkbox",checked:n===!0,onChange:r=>{i(t,r.target.checked)},style:{cursor:"pointer",width:16,height:16,accentColor:"#2563eb"}});case"number":return e.jsx("input",{type:"number",value:typeof n=="number"?n:"",onChange:r=>{i(t,r.target.valueAsNumber)},style:w});case"select":{const r=(o==null?void 0:o.options)??[];return e.jsx("select",{value:String(n??""),onChange:l=>{i(t,l.target.value)},style:w,children:r.map(l=>e.jsx("option",{value:String(l),children:String(l)},String(l)))})}case"text":return e.jsx("input",{type:"text",value:typeof n=="string"?n:String(n??""),onChange:r=>{i(t,r.target.value)},style:w});case"action":return e.jsx("span",{style:{display:"inline-block",padding:"2px 8px",fontSize:11,fontWeight:600,color:"#7c3aed",background:"#f5f3ff",border:"1px solid #ddd6fe",borderRadius:4,fontFamily:"monospace"},children:"(action)"});case"json":return e.jsx("code",{style:{fontSize:12,color:"#6b7280",fontFamily:"monospace"},children:JSON.stringify(n)})}}const w={padding:"4px 8px",border:"1px solid #d1d5db",borderRadius:4,fontSize:13,width:"100%",maxWidth:280},C={padding:"6px 20px",textAlign:"left",color:"#6b7280",fontWeight:500,fontSize:12,borderBottom:"1px solid #e5e7eb"},R={padding:"8px 20px",verticalAlign:"middle",borderBottom:"1px solid #f3f4f6"};function F({args:t,argTypes:n,onArgChange:o}){const s=Array.from(new Set([...Object.keys(t),...Object.keys(n)])).map(r=>[r,t[r]]);return e.jsxs("div",{style:{borderTop:"2px solid #e5e7eb"},children:[e.jsx("div",{style:{padding:"6px 20px",fontSize:11,fontWeight:700,color:"#9ca3af",textTransform:"uppercase",letterSpacing:"0.08em",borderBottom:"1px solid #e5e7eb",background:"#f9fafb"},children:"Controls"}),s.length===0?e.jsx("div",{style:{padding:"12px 20px",color:"#9ca3af",fontSize:13},children:"No args defined"}):e.jsxs("table",{style:{width:"100%",borderCollapse:"collapse",fontSize:13},children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{style:C,children:"Name"}),e.jsx("th",{style:C,children:"Control"}),e.jsx("th",{style:C,children:"Description"})]})}),e.jsx("tbody",{children:s.map(([r,l])=>{const d=n[r];return e.jsxs("tr",{children:[e.jsx("td",{style:{...R,fontFamily:"monospace",fontSize:12,color:"#374151",whiteSpace:"nowrap"},children:r}),e.jsx("td",{style:R,children:e.jsx(U,{argKey:r,value:l,argType:d,onArgChange:o})}),e.jsx("td",{style:{...R,color:"#9ca3af"},children:(d==null?void 0:d.description)??""})]},r)})})]})]})}function _(t){if(t.length===0)return"()";try{return t.map(n=>{var o;if(n===null)return"null";if(n===void 0)return"undefined";if(typeof n=="function")return"[Function]";if(typeof n=="object"){const i=((o=n.constructor)==null?void 0:o.name)??"Object";return i!=="Object"&&i!=="Array"?`[${i}]`:JSON.stringify(n)}return JSON.stringify(n)}).join(", ")}catch{return"[unserializable]"}}function G(t){const n=new Date(t),o=n.getHours().toString().padStart(2,"0"),i=n.getMinutes().toString().padStart(2,"0"),s=n.getSeconds().toString().padStart(2,"0"),r=n.getMilliseconds().toString().padStart(3,"0");return`${o}:${i}:${s}.${r}`}function L(){const[t,n]=c.useState(()=>k.defaultActionChannel.getLogs());return c.useEffect(()=>k.defaultActionChannel.subscribe(n),[]),e.jsxs("div",{style:{height:"100%",display:"flex",flexDirection:"column"},children:[e.jsxs("div",{style:{padding:"6px 20px",fontSize:11,fontWeight:700,color:"#9ca3af",textTransform:"uppercase",letterSpacing:"0.08em",borderBottom:"1px solid #e5e7eb",background:"#f9fafb",display:"flex",alignItems:"center",justifyContent:"space-between",flexShrink:0},children:[e.jsxs("span",{children:["Actions ",t.length>0&&`(${t.length.toString()})`]}),e.jsx("button",{type:"button",onClick:()=>{k.defaultActionChannel.clear()},disabled:t.length===0,style:{fontSize:10,fontWeight:600,padding:"2px 8px",border:"1px solid #d1d5db",borderRadius:3,background:"#fff",color:t.length===0?"#9ca3af":"#374151",cursor:t.length===0?"default":"pointer",textTransform:"none",letterSpacing:0},children:"Clear"})]}),e.jsx("div",{style:{flex:1,overflow:"auto"},children:t.length===0?e.jsx("div",{style:{padding:"12px 20px",color:"#9ca3af",fontSize:13},children:"함수 prop이 호출되면 여기에 기록됩니다"}):e.jsx("ul",{style:{listStyle:"none",margin:0,padding:0,fontFamily:"monospace",fontSize:12},children:t.map(o=>e.jsxs("li",{style:{display:"flex",alignItems:"baseline",gap:10,padding:"6px 20px",borderBottom:"1px solid #f3f4f6"},children:[e.jsx("span",{style:{color:"#9ca3af",fontSize:11,minWidth:92},children:G(o.timestamp)}),e.jsx("span",{style:{color:"#7c3aed",fontWeight:600},children:o.name}),e.jsxs("span",{style:{color:"#374151",wordBreak:"break-all",flex:1},children:["(",_(o.args),")"]})]},o.id))})})]})}const H={mobile:375,tablet:768,desktop:"none"},T={mobile:"Mobile",tablet:"Tablet",desktop:"Desktop"},W={white:{background:"#ffffff"},dark:{background:"#1f2937"},transparent:{backgroundImage:["linear-gradient(45deg, #e2e8f0 25%, transparent 25%)","linear-gradient(-45deg, #e2e8f0 25%, transparent 25%)","linear-gradient(45deg, transparent 75%, #e2e8f0 75%)","linear-gradient(-45deg, transparent 75%, #e2e8f0 75%)"].join(", "),backgroundSize:"16px 16px",backgroundPosition:"0 0, 0 8px, 8px -8px, -8px 0px",backgroundColor:"#ffffff"}},A=320;function Q(t){return z.themes[t]??z.themes.vsDark}function D({entryId:t,jogakName:n,overrideArgs:o,onArgChange:i,onReset:s,codeTheme:r,onResolveJogak:l}){const d=j.useEntry(t),[a,b]=c.useState("desktop"),[p,x]=c.useState("white"),[y,h]=c.useState("controls"),m=Q(r);return d.status==="unknown"?e.jsxs("div",{"data-testid":"preview-not-found",style:{padding:24,color:"#ef4444"},children:["Entry not found: ",t]}):d.status==="error"?e.jsxs("div",{"data-testid":"preview-error",style:{padding:24,color:"#b91c1c",background:"#fef2f2",height:"100%",display:"flex",flexDirection:"column",gap:12,alignItems:"flex-start"},children:[e.jsxs("div",{style:{fontWeight:600},children:["Failed to load entry: ",t]}),e.jsx("pre",{style:{margin:0,padding:12,background:"#fff",border:"1px solid #fecaca",borderRadius:6,fontSize:12,whiteSpace:"pre-wrap",maxWidth:"100%"},children:d.error.message})]}):d.status==="loading"?e.jsx(Y,{meta:d.meta,jogakName:n,viewport:a,bgMode:p,onViewportChange:b,onBgModeChange:x}):e.jsx(X,{entry:d.entry,jogakName:n,overrideArgs:o,onArgChange:i,onReset:s,onResolveJogak:l,viewport:a,bgMode:p,bottomTab:y,onViewportChange:b,onBgModeChange:x,onBottomTabChange:h,prismTheme:m})}function Y({meta:t,jogakName:n,viewport:o,bgMode:i,onViewportChange:s,onBgModeChange:r}){const l=n??t.jogakNames[0]??"...",d=H[o];return e.jsxs("div",{"data-testid":"preview-loading",style:{display:"flex",flexDirection:"column",height:"100%"},children:[e.jsx(N,{title:t.title,jogakName:l,viewport:o,bgMode:i,onViewportChange:s,onBgModeChange:r,showReset:!1,onReset:()=>{}}),e.jsx("div",{style:{flex:1,minHeight:A,overflow:"auto",...W[i]},children:e.jsx("div",{style:{maxWidth:d==="none"?"100%":d,margin:"0 auto",padding:24},children:e.jsxs("div",{style:{border:"1px dashed #e5e7eb",borderRadius:8,padding:16,minHeight:A-64,display:"flex",alignItems:"center",justifyContent:"center",color:"#9ca3af",fontSize:13,background:"linear-gradient(90deg, rgba(229,231,235,0) 0%, rgba(229,231,235,0.45) 50%, rgba(229,231,235,0) 100%)",backgroundSize:"200% 100%",animation:"jogakSkeleton 1.4s ease-in-out infinite"},children:["Loading ",t.title,"…"]})})}),e.jsx("style",{children:"@keyframes jogakSkeleton { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }"})]})}function X({entry:t,jogakName:n,overrideArgs:o,onArgChange:i,onReset:s,onResolveJogak:r,viewport:l,bgMode:d,bottomTab:a,onViewportChange:b,onBgModeChange:p,onBottomTabChange:x,prismTheme:y}){var B;const h=n??((B=t.jogaks[0])==null?void 0:B.name)??null;if(c.useEffect(()=>{n===null&&h!==null&&r!==void 0&&r(t.id,h)},[n,h,t.id,r]),h===null)return e.jsxs("div",{style:{padding:24,color:"#ef4444"},children:["Entry has no jogaks: ",t.id]});const m=t.jogaks.find(S=>S.name===h);if(m===void 0)return e.jsxs("div",{style:{padding:24,color:"#ef4444"},children:["Jogak not found: ",h]});const f={...m.args??{},...o},g={...t.meta.argTypes??{},...m.argTypes??{}},P=Object.keys(o).length>0,M=H[l];return e.jsxs("div",{style:{display:"flex",flexDirection:"column",height:"100%"},children:[e.jsx(N,{title:t.title,jogakName:m.name,viewport:l,bgMode:d,onViewportChange:b,onBgModeChange:p,showReset:P,onReset:s}),e.jsx("div",{style:{flex:1,minHeight:A,overflow:"auto",...W[d]},children:e.jsx("div",{style:{maxWidth:M==="none"?"100%":M,margin:"0 auto",padding:24},children:e.jsx(Z,{entry:t,args:f,source:t.source,theme:y},`${t.id}/${m.name}`)})}),e.jsxs("div",{style:{height:260,flexShrink:0,display:"flex",flexDirection:"column",borderTop:"2px solid #e5e7eb"},children:[e.jsx("div",{role:"tablist",style:{display:"flex",gap:4,padding:"4px 12px 0",background:"#fff",borderBottom:"1px solid #e5e7eb",flexShrink:0},children:["controls","actions"].map(S=>{const v=a===S;return e.jsx("button",{type:"button",role:"tab","aria-selected":v,onClick:()=>{x(S)},style:{padding:"6px 14px",fontSize:12,fontWeight:v?600:500,color:v?"#111827":"#6b7280",background:"transparent",border:"none",borderBottom:v?"2px solid #2563eb":"2px solid transparent",marginBottom:-1,cursor:"pointer",textTransform:"capitalize"},children:S},S)})}),e.jsx("div",{style:{flex:1,minHeight:0,overflow:"auto"},children:a==="controls"?e.jsx(F,{args:f,argTypes:g,onArgChange:i}):e.jsx(L,{})})]})]})}function N({title:t,jogakName:n,viewport:o,bgMode:i,onViewportChange:s,onBgModeChange:r,showReset:l,onReset:d}){return e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,padding:"7px 14px",borderBottom:"1px solid #e5e7eb",background:"#fff",flexShrink:0},children:[e.jsxs("div",{style:{flex:1,fontSize:13},children:[e.jsx("span",{style:{color:"#9ca3af"},children:t}),e.jsx("span",{style:{color:"#d1d5db",margin:"0 6px"},children:"/"}),e.jsx("span",{style:{color:"#111827",fontWeight:600},children:n})]}),e.jsx("div",{style:{display:"flex",gap:2,background:"#f3f4f6",borderRadius:6,padding:2},children:["mobile","tablet","desktop"].map(a=>e.jsx("button",{type:"button",onClick:()=>{s(a)},"aria-pressed":o===a,style:{padding:"3px 9px",fontSize:12,border:"none",borderRadius:4,cursor:"pointer",background:o===a?"#fff":"transparent",color:o===a?"#111827":"#6b7280",fontWeight:o===a?600:400,boxShadow:o===a?"0 1px 2px rgba(0,0,0,0.08)":"none",transition:"all 0.1s"},children:T[a]},a))}),e.jsx("div",{style:{display:"flex",gap:4,alignItems:"center"},children:["white","dark","transparent"].map(a=>e.jsx("button",{type:"button",onClick:()=>{r(a)},"aria-pressed":i===a,"aria-label":`${a} background`,style:{width:20,height:20,borderRadius:4,border:i===a?"2px solid #2563eb":"2px solid #d1d5db",cursor:"pointer",padding:0,flexShrink:0,...W[a]}},a))}),l&&e.jsx("button",{type:"button",onClick:d,style:{padding:"3px 10px",fontSize:12,border:"1px solid #d1d5db",borderRadius:4,background:"#fff",cursor:"pointer",color:"#374151"},children:"Reset"})]})}function Z({entry:t,args:n,source:o,theme:i}){const s=c.useRef(null),[r,l]=c.useState(!1);return c.useEffect(()=>{const d=s.current;if(d!==null)return j.reactAdapter.render(t,n,d),()=>{j.reactAdapter.unmount(d)}},[t]),c.useEffect(()=>{const d=s.current;d!==null&&j.reactAdapter.render(t,n,d)},[t,n]),e.jsxs("div",{children:[e.jsxs("div",{style:{position:"relative"},children:[e.jsx("div",{ref:s,"data-testid":"preview-content",style:{border:"1px dashed #e5e7eb",borderRadius:8,padding:16,paddingBottom:36}}),e.jsx("button",{type:"button",onClick:()=>{l(d=>!d)},"aria-pressed":r,"aria-label":r?"Hide source code":"Show source code",style:{position:"absolute",bottom:8,right:8,padding:"4px 9px",fontSize:11,fontFamily:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",fontWeight:600,letterSpacing:"0.02em",background:r?"#2563eb":"#1e293b",color:"#fff",border:"none",borderRadius:5,cursor:"pointer",boxShadow:"0 1px 4px rgba(0,0,0,0.2)",transition:"background 0.15s"},children:"</>"})]}),r&&e.jsx("div",{style:{marginTop:8,borderRadius:8,overflow:"hidden",height:320,boxShadow:"0 0 0 1px rgba(0,0,0,0.08), 0 4px 16px rgba(0,0,0,0.12)"},children:e.jsx(K,{source:o,theme:i})})]})}function K({source:t,theme:n}){const[o,i]=c.useState(!1),s=n.plain.backgroundColor??"#1e293b";if(t===void 0)return e.jsx("div",{style:{height:"100%",display:"flex",alignItems:"center",justifyContent:"center",background:s,color:"#94a3b8",fontSize:13},children:"Source not available"});const r=()=>{navigator.clipboard.writeText(t).then(()=>{i(!0),setTimeout(()=>{i(!1)},2e3)})};return e.jsxs("div",{style:{position:"relative",height:"100%"},children:[e.jsx("button",{type:"button",onClick:r,style:{position:"absolute",top:10,right:12,zIndex:1,padding:"3px 9px",fontSize:11,background:"rgba(255,255,255,0.1)",color:"#e2e8f0",border:"1px solid rgba(255,255,255,0.18)",borderRadius:4,cursor:"pointer"},children:o?"✓ Copied":"Copy"}),e.jsx(z.Highlight,{code:t.trim(),language:"tsx",theme:n,children:({style:l,tokens:d,getLineProps:a,getTokenProps:b})=>e.jsx("pre",{style:{...l,margin:0,padding:"12px 0",fontSize:12.5,lineHeight:1.7,fontFamily:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",height:"100%",boxSizing:"border-box",overflow:"auto"},children:d.map((p,x)=>e.jsxs("div",{...a({line:p}),style:{...a({line:p}).style,display:"flex",paddingRight:24},children:[e.jsx("span",{style:{userSelect:"none",minWidth:40,paddingLeft:14,paddingRight:14,textAlign:"right",color:"rgba(148,163,184,0.45)",flexShrink:0},children:x+1}),e.jsx("span",{children:p.map((y,h)=>e.jsx("span",{...b({token:y})},h))})]},x))})})]})}function E(){if(typeof window>"u")return null;const t=new URLSearchParams(window.location.search),n=t.get("entry");if(n===null)return null;const o=t.get("jogak");return{entryId:n,jogakName:o}}function ee(t,n){const o=new URLSearchParams;o.set("entry",t),o.set("jogak",n),window.history.pushState({},"",`?${o.toString()}`)}function te({entries:t,metas:n,codeTheme:o="vsDark"}={}){const i=c.useMemo(()=>{if(t!==void 0){n!==void 0&&console.warn("[jogak] JogakApp received both `entries` and `metas` — `entries` (eager) takes precedence.");const u=new k.ComponentRegistry;for(const f of t)u.register(f);return u}if(n!==void 0)for(const u of n)k.defaultRegistry.registerMeta(u);return k.defaultRegistry},[t,n]),s=c.useMemo(()=>E(),[]),[r,l]=c.useState((s==null?void 0:s.entryId)??null),[d,a]=c.useState((s==null?void 0:s.jogakName)??null),[b,p]=c.useState({});c.useEffect(()=>{const u=()=>{const f=E();f!==null?(l(f.entryId),a(f.jogakName),p({})):(l(null),a(null))};return window.addEventListener("popstate",u),()=>{window.removeEventListener("popstate",u)}},[]);const x=c.useCallback((u,f)=>{l(u),a(f),p({}),ee(u,f)},[]),y=c.useCallback((u,f)=>{if(l(g=>g===u?u:g),a(g=>g??f),typeof window<"u"){const g=new URLSearchParams(window.location.search);g.get("entry")===u&&g.get("jogak")===null&&(g.set("jogak",f),window.history.replaceState({},"",`?${g.toString()}`))}},[]),h=c.useCallback((u,f)=>{p(g=>({...g,[u]:f}))},[]),m=c.useCallback(()=>{p({})},[]);return e.jsx(j.JogakProvider,{registry:i,children:e.jsxs("div",{style:{display:"grid",gridTemplateColumns:"260px 1fr",height:"100dvh",overflow:"hidden"},children:[e.jsx(I,{selectedEntryId:r,selectedJogakName:d,onSelect:x}),e.jsx("main",{style:{overflow:"hidden",minHeight:0},children:r!==null?e.jsx(D,{entryId:r,jogakName:d,overrideArgs:b,onArgChange:h,onReset:m,codeTheme:o,onResolveJogak:y}):e.jsx("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",height:"100%",color:"#9ca3af"},children:"Select a component from the sidebar"})})]})})}function ne(){const t=j.useRegistry(),n=c.useMemo(()=>t.getAll(),[t]),o=c.useMemo(()=>t.getTree(),[t]),i=c.useMemo(()=>s=>t.search(s),[t]);return{entries:n,tree:o,search:i}}exports.Actions=L;exports.Controls=F;exports.JogakApp=te;exports.Preview=D;exports.Sidebar=I;exports.useRegistry=ne;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),c=require("react"),k=require("@jogak/core"),j=require("@jogak/react"),z=require("prism-react-renderer");function I({selectedEntryId:t,selectedJogakName:n,onSelect:o}){const[i,s]=c.useState(""),{metaTree:r,searchMeta:l}=j.useRegistryMeta(),d=i.trim().length>0?l(i):null;return e.jsxs("aside",{"data-testid":"sidebar",style:{borderRight:"1px solid #e5e7eb",height:"100%",overflow:"auto",display:"flex",flexDirection:"column"},children:[e.jsx("div",{style:{padding:"12px",borderBottom:"1px solid #e5e7eb"},children:e.jsx("input",{type:"search",placeholder:"Search components...",value:i,onChange:a=>{s(a.target.value)},style:{width:"100%",padding:"6px 8px",border:"1px solid #d1d5db",borderRadius:4},"aria-label":"Search components"})}),e.jsx("nav",{style:{flex:1,overflow:"auto",padding:"8px 0"},children:d!==null?e.jsx(J,{metas:d,selectedEntryId:t,selectedJogakName:n,onSelect:o}):e.jsx(O,{node:r,selectedEntryId:t,selectedJogakName:n,onSelect:o})})]})}function J({metas:t,selectedEntryId:n,selectedJogakName:o,onSelect:i}){return t.length===0?e.jsx("p",{style:{padding:"0 12px",color:"#9ca3af",fontSize:13},children:"No results"}):e.jsx("ul",{style:{listStyle:"none",margin:0,padding:0},children:t.map(s=>e.jsx("li",{children:e.jsx($,{meta:s,selectedEntryId:n,selectedJogakName:o,onSelect:i,indent:0})},s.id))})}function O({node:t,selectedEntryId:n,selectedJogakName:o,onSelect:i,depth:s=0}){return e.jsx("ul",{style:{listStyle:"none",margin:0,padding:`0 0 0 ${s*12}px`},children:Object.entries(t).map(([r,l])=>e.jsx("li",{children:"id"in l?e.jsx($,{meta:l,selectedEntryId:n,selectedJogakName:o,onSelect:i,indent:0}):e.jsx(V,{label:r,node:l,selectedEntryId:n,selectedJogakName:o,onSelect:i,depth:s+1})},r))})}function V({label:t,node:n,selectedEntryId:o,selectedJogakName:i,onSelect:s,depth:r}){const[l,d]=c.useState(!0);return e.jsxs("div",{children:[e.jsxs("button",{type:"button",onClick:()=>{d(a=>!a)},style:{display:"flex",alignItems:"center",gap:4,width:"100%",padding:"4px 12px",background:"none",border:"none",cursor:"pointer",fontSize:12,fontWeight:600,color:"#6b7280",textTransform:"uppercase",letterSpacing:"0.05em"},"aria-expanded":l,children:[e.jsx("span",{children:l?"▾":"▸"}),t]}),l&&e.jsx(O,{node:n,selectedEntryId:o,selectedJogakName:i,onSelect:s,depth:r})]})}function $({meta:t,selectedEntryId:n,selectedJogakName:o,onSelect:i,indent:s}){const r=t.id===n,[l,d]=c.useState(r);c.useEffect(()=>{r&&d(!0)},[r]);const a=t.title.split("/").pop()??t.title,b=16+s*12;return e.jsxs("div",{children:[e.jsxs("button",{type:"button",onClick:()=>{if(r)d(p=>!p);else{d(!0);const p=t.jogakNames[0];p!==void 0&&i(t.id,p)}},style:{display:"flex",alignItems:"center",gap:6,width:"100%",padding:`5px 12px 5px ${b}px`,background:r?"#eff6ff":"none",border:"none",cursor:"pointer",fontSize:13,color:r?"#2563eb":"#374151",fontWeight:r?500:400,textAlign:"left"},"aria-expanded":l,children:[e.jsx("span",{style:{fontSize:10,flexShrink:0,lineHeight:1},children:l?"▾":"▸"}),a]}),l&&e.jsx("ul",{style:{listStyle:"none",margin:0,padding:0},children:t.jogakNames.map(p=>{const x=r&&p===o;return e.jsx("li",{children:e.jsx("button",{type:"button",onClick:()=>{i(t.id,p)},style:{display:"block",width:"100%",textAlign:"left",padding:`4px 12px 4px ${b+18}px`,background:x?"#dbeafe":"none",border:"none",cursor:"pointer",fontSize:12,color:x?"#1d4ed8":"#6b7280",fontWeight:x?500:400},"aria-current":x?"true":void 0,children:p})},p)})})]})}function q(t,n){const o=n==null?void 0:n.control,i=(n==null?void 0:n.action)!==void 0&&n.action!==!1,s=(n==null?void 0:n.type)==="function"||typeof t=="function";return i||s?"action":o==="boolean"||typeof t=="boolean"?"boolean":o==="number"||o==="range"||typeof t=="number"?"number":o==="select"||o==="radio"||(n==null?void 0:n.options)!==void 0&&n.options.length>0?"select":o==="text"||o==="color"||typeof t=="string"?"text":"json"}function U({argKey:t,value:n,argType:o,onArgChange:i}){switch(q(n,o)){case"boolean":return e.jsx("input",{type:"checkbox",checked:n===!0,onChange:r=>{i(t,r.target.checked)},style:{cursor:"pointer",width:16,height:16,accentColor:"#2563eb"}});case"number":return e.jsx("input",{type:"number",value:typeof n=="number"?n:"",onChange:r=>{i(t,r.target.valueAsNumber)},style:w});case"select":{const r=(o==null?void 0:o.options)??[];return e.jsx("select",{value:String(n??""),onChange:l=>{i(t,l.target.value)},style:w,children:r.map(l=>e.jsx("option",{value:String(l),children:String(l)},String(l)))})}case"text":return e.jsx("input",{type:"text",value:typeof n=="string"?n:String(n??""),onChange:r=>{i(t,r.target.value)},style:w});case"action":return e.jsx("span",{style:{display:"inline-block",padding:"2px 8px",fontSize:11,fontWeight:600,color:"#7c3aed",background:"#f5f3ff",border:"1px solid #ddd6fe",borderRadius:4,fontFamily:"monospace"},children:"(action)"});case"json":return e.jsx("code",{style:{fontSize:12,color:"#6b7280",fontFamily:"monospace"},children:JSON.stringify(n)})}}const w={padding:"4px 8px",border:"1px solid #d1d5db",borderRadius:4,fontSize:13,width:"100%",maxWidth:280},C={padding:"6px 20px",textAlign:"left",color:"#6b7280",fontWeight:500,fontSize:12,borderBottom:"1px solid #e5e7eb"},R={padding:"8px 20px",verticalAlign:"middle",borderBottom:"1px solid #f3f4f6"};function F({args:t,argTypes:n,onArgChange:o}){const s=Array.from(new Set([...Object.keys(t),...Object.keys(n)])).map(r=>[r,t[r]]);return e.jsxs("div",{style:{borderTop:"2px solid #e5e7eb"},children:[e.jsx("div",{style:{padding:"6px 20px",fontSize:11,fontWeight:700,color:"#9ca3af",textTransform:"uppercase",letterSpacing:"0.08em",borderBottom:"1px solid #e5e7eb",background:"#f9fafb"},children:"Controls"}),s.length===0?e.jsx("div",{style:{padding:"12px 20px",color:"#9ca3af",fontSize:13},children:"No args defined"}):e.jsxs("table",{style:{width:"100%",borderCollapse:"collapse",fontSize:13},children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{style:C,children:"Name"}),e.jsx("th",{style:C,children:"Control"}),e.jsx("th",{style:C,children:"Description"})]})}),e.jsx("tbody",{children:s.map(([r,l])=>{const d=n[r];return e.jsxs("tr",{children:[e.jsx("td",{style:{...R,fontFamily:"monospace",fontSize:12,color:"#374151",whiteSpace:"nowrap"},children:r}),e.jsx("td",{style:R,children:e.jsx(U,{argKey:r,value:l,argType:d,onArgChange:o})}),e.jsx("td",{style:{...R,color:"#9ca3af"},children:(d==null?void 0:d.description)??""})]},r)})})]})]})}function _(t){if(t.length===0)return"()";try{return t.map(n=>{var o;if(n===null)return"null";if(n===void 0)return"undefined";if(typeof n=="function")return"[Function]";if(typeof n=="object"){const i=((o=n.constructor)==null?void 0:o.name)??"Object";return i!=="Object"&&i!=="Array"?`[${i}]`:JSON.stringify(n)}return JSON.stringify(n)}).join(", ")}catch{return"[unserializable]"}}function G(t){const n=new Date(t),o=n.getHours().toString().padStart(2,"0"),i=n.getMinutes().toString().padStart(2,"0"),s=n.getSeconds().toString().padStart(2,"0"),r=n.getMilliseconds().toString().padStart(3,"0");return`${o}:${i}:${s}.${r}`}function L(){const[t,n]=c.useState(()=>k.defaultActionChannel.getLogs());return c.useEffect(()=>k.defaultActionChannel.subscribe(n),[]),e.jsxs("div",{style:{height:"100%",display:"flex",flexDirection:"column"},children:[e.jsxs("div",{style:{padding:"6px 20px",fontSize:11,fontWeight:700,color:"#9ca3af",textTransform:"uppercase",letterSpacing:"0.08em",borderBottom:"1px solid #e5e7eb",background:"#f9fafb",display:"flex",alignItems:"center",justifyContent:"space-between",flexShrink:0},children:[e.jsxs("span",{children:["Actions ",t.length>0&&`(${t.length.toString()})`]}),e.jsx("button",{type:"button",onClick:()=>{k.defaultActionChannel.clear()},disabled:t.length===0,style:{fontSize:10,fontWeight:600,padding:"2px 8px",border:"1px solid #d1d5db",borderRadius:3,background:"#fff",color:t.length===0?"#9ca3af":"#374151",cursor:t.length===0?"default":"pointer",textTransform:"none",letterSpacing:0},children:"Clear"})]}),e.jsx("div",{style:{flex:1,overflow:"auto"},children:t.length===0?e.jsx("div",{style:{padding:"12px 20px",color:"#9ca3af",fontSize:13},children:"함수 prop이 호출되면 여기에 기록됩니다"}):e.jsx("ul",{style:{listStyle:"none",margin:0,padding:0,fontFamily:"monospace",fontSize:12},children:t.map(o=>e.jsxs("li",{style:{display:"flex",alignItems:"baseline",gap:10,padding:"6px 20px",borderBottom:"1px solid #f3f4f6"},children:[e.jsx("span",{style:{color:"#9ca3af",fontSize:11,minWidth:92},children:G(o.timestamp)}),e.jsx("span",{style:{color:"#7c3aed",fontWeight:600},children:o.name}),e.jsxs("span",{style:{color:"#374151",wordBreak:"break-all",flex:1},children:["(",_(o.args),")"]})]},o.id))})})]})}const H={mobile:375,tablet:768,desktop:"none"},T={mobile:"Mobile",tablet:"Tablet",desktop:"Desktop"},W={white:{background:"#ffffff"},dark:{background:"#1f2937"},transparent:{backgroundImage:["linear-gradient(45deg, #e2e8f0 25%, transparent 25%)","linear-gradient(-45deg, #e2e8f0 25%, transparent 25%)","linear-gradient(45deg, transparent 75%, #e2e8f0 75%)","linear-gradient(-45deg, transparent 75%, #e2e8f0 75%)"].join(", "),backgroundSize:"16px 16px",backgroundPosition:"0 0, 0 8px, 8px -8px, -8px 0px",backgroundColor:"#ffffff"}},A=320;function Q(t){return z.themes[t]??z.themes.vsDark}function D({entryId:t,jogakName:n,overrideArgs:o,onArgChange:i,onReset:s,codeTheme:r,onResolveJogak:l}){const d=j.useEntry(t),[a,b]=c.useState("desktop"),[p,x]=c.useState("white"),[y,h]=c.useState("controls"),m=Q(r);return d.status==="unknown"?e.jsxs("div",{"data-testid":"preview-not-found",style:{padding:24,color:"#ef4444"},children:["Entry not found: ",t]}):d.status==="error"?e.jsxs("div",{"data-testid":"preview-error",style:{padding:24,color:"#b91c1c",background:"#fef2f2",height:"100%",display:"flex",flexDirection:"column",gap:12,alignItems:"flex-start"},children:[e.jsxs("div",{style:{fontWeight:600},children:["Failed to load entry: ",t]}),e.jsx("pre",{style:{margin:0,padding:12,background:"#fff",border:"1px solid #fecaca",borderRadius:6,fontSize:12,whiteSpace:"pre-wrap",maxWidth:"100%"},children:d.error.message})]}):d.status==="loading"?e.jsx(Y,{meta:d.meta,jogakName:n,viewport:a,bgMode:p,onViewportChange:b,onBgModeChange:x}):e.jsx(X,{entry:d.entry,jogakName:n,overrideArgs:o,onArgChange:i,onReset:s,onResolveJogak:l,viewport:a,bgMode:p,bottomTab:y,onViewportChange:b,onBgModeChange:x,onBottomTabChange:h,prismTheme:m})}function Y({meta:t,jogakName:n,viewport:o,bgMode:i,onViewportChange:s,onBgModeChange:r}){const l=n??t.jogakNames[0]??"...",d=H[o];return e.jsxs("div",{"data-testid":"preview-loading",style:{display:"flex",flexDirection:"column",height:"100%"},children:[e.jsx(N,{title:t.title,jogakName:l,viewport:o,bgMode:i,onViewportChange:s,onBgModeChange:r,showReset:!1,onReset:()=>{}}),e.jsx("div",{style:{flex:1,minHeight:A,overflow:"auto",...W[i]},children:e.jsx("div",{style:{maxWidth:d==="none"?"100%":d,margin:"0 auto",padding:24},children:e.jsxs("div",{style:{border:"1px dashed #e5e7eb",borderRadius:8,padding:16,minHeight:A-64,display:"flex",alignItems:"center",justifyContent:"center",color:"#9ca3af",fontSize:13,background:"linear-gradient(90deg, rgba(229,231,235,0) 0%, rgba(229,231,235,0.45) 50%, rgba(229,231,235,0) 100%)",backgroundSize:"200% 100%",animation:"jogakSkeleton 1.4s ease-in-out infinite"},children:["Loading ",t.title,"…"]})})}),e.jsx("style",{children:"@keyframes jogakSkeleton { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }"})]})}function X({entry:t,jogakName:n,overrideArgs:o,onArgChange:i,onReset:s,onResolveJogak:r,viewport:l,bgMode:d,bottomTab:a,onViewportChange:b,onBgModeChange:p,onBottomTabChange:x,prismTheme:y}){var B;const h=n??((B=t.jogaks[0])==null?void 0:B.name)??null;if(c.useEffect(()=>{n===null&&h!==null&&r!==void 0&&r(t.id,h)},[n,h,t.id,r]),h===null)return e.jsxs("div",{style:{padding:24,color:"#ef4444"},children:["Entry has no jogaks: ",t.id]});const m=t.jogaks.find(S=>S.name===h);if(m===void 0)return e.jsxs("div",{style:{padding:24,color:"#ef4444"},children:["Jogak not found: ",h]});const f={...m.args??{},...o},g={...t.meta.argTypes??{},...m.argTypes??{}},P=Object.keys(o).length>0,M=H[l];return e.jsxs("div",{style:{display:"flex",flexDirection:"column",height:"100%"},children:[e.jsx(N,{title:t.title,jogakName:m.name,viewport:l,bgMode:d,onViewportChange:b,onBgModeChange:p,showReset:P,onReset:s}),e.jsx("div",{style:{flex:1,minHeight:A,overflow:"auto",...W[d]},children:e.jsx("div",{"data-jogak-content":!0,style:{maxWidth:M==="none"?"100%":M,margin:"0 auto",padding:24},children:e.jsx(Z,{entry:t,args:f,source:t.source,theme:y},`${t.id}/${m.name}`)})}),e.jsxs("div",{style:{height:260,flexShrink:0,display:"flex",flexDirection:"column",borderTop:"2px solid #e5e7eb"},children:[e.jsx("div",{role:"tablist",style:{display:"flex",gap:4,padding:"4px 12px 0",background:"#fff",borderBottom:"1px solid #e5e7eb",flexShrink:0},children:["controls","actions"].map(S=>{const v=a===S;return e.jsx("button",{type:"button",role:"tab","aria-selected":v,onClick:()=>{x(S)},style:{padding:"6px 14px",fontSize:12,fontWeight:v?600:500,color:v?"#111827":"#6b7280",background:"transparent",border:"none",borderBottom:v?"2px solid #2563eb":"2px solid transparent",marginBottom:-1,cursor:"pointer",textTransform:"capitalize"},children:S},S)})}),e.jsx("div",{style:{flex:1,minHeight:0,overflow:"auto"},children:a==="controls"?e.jsx(F,{args:f,argTypes:g,onArgChange:i}):e.jsx(L,{})})]})]})}function N({title:t,jogakName:n,viewport:o,bgMode:i,onViewportChange:s,onBgModeChange:r,showReset:l,onReset:d}){return e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,padding:"7px 14px",borderBottom:"1px solid #e5e7eb",background:"#fff",flexShrink:0},children:[e.jsxs("div",{style:{flex:1,fontSize:13},children:[e.jsx("span",{style:{color:"#9ca3af"},children:t}),e.jsx("span",{style:{color:"#d1d5db",margin:"0 6px"},children:"/"}),e.jsx("span",{style:{color:"#111827",fontWeight:600},children:n})]}),e.jsx("div",{style:{display:"flex",gap:2,background:"#f3f4f6",borderRadius:6,padding:2},children:["mobile","tablet","desktop"].map(a=>e.jsx("button",{type:"button",onClick:()=>{s(a)},"aria-pressed":o===a,style:{padding:"3px 9px",fontSize:12,border:"none",borderRadius:4,cursor:"pointer",background:o===a?"#fff":"transparent",color:o===a?"#111827":"#6b7280",fontWeight:o===a?600:400,boxShadow:o===a?"0 1px 2px rgba(0,0,0,0.08)":"none",transition:"all 0.1s"},children:T[a]},a))}),e.jsx("div",{style:{display:"flex",gap:4,alignItems:"center"},children:["white","dark","transparent"].map(a=>e.jsx("button",{type:"button",onClick:()=>{r(a)},"aria-pressed":i===a,"aria-label":`${a} background`,style:{width:20,height:20,borderRadius:4,border:i===a?"2px solid #2563eb":"2px solid #d1d5db",cursor:"pointer",padding:0,flexShrink:0,...W[a]}},a))}),l&&e.jsx("button",{type:"button",onClick:d,style:{padding:"3px 10px",fontSize:12,border:"1px solid #d1d5db",borderRadius:4,background:"#fff",cursor:"pointer",color:"#374151"},children:"Reset"})]})}function Z({entry:t,args:n,source:o,theme:i}){const s=c.useRef(null),[r,l]=c.useState(!1);return c.useEffect(()=>{const d=s.current;if(d!==null)return j.reactAdapter.render(t,n,d),()=>{j.reactAdapter.unmount(d)}},[t]),c.useEffect(()=>{const d=s.current;d!==null&&j.reactAdapter.render(t,n,d)},[t,n]),e.jsxs("div",{children:[e.jsxs("div",{style:{position:"relative"},children:[e.jsx("div",{ref:s,"data-testid":"preview-content",style:{border:"1px dashed #e5e7eb",borderRadius:8,padding:16,paddingBottom:36}}),e.jsx("button",{type:"button",onClick:()=>{l(d=>!d)},"aria-pressed":r,"aria-label":r?"Hide source code":"Show source code",style:{position:"absolute",bottom:8,right:8,padding:"4px 9px",fontSize:11,fontFamily:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",fontWeight:600,letterSpacing:"0.02em",background:r?"#2563eb":"#1e293b",color:"#fff",border:"none",borderRadius:5,cursor:"pointer",boxShadow:"0 1px 4px rgba(0,0,0,0.2)",transition:"background 0.15s"},children:"</>"})]}),r&&e.jsx("div",{style:{marginTop:8,borderRadius:8,overflow:"hidden",height:320,boxShadow:"0 0 0 1px rgba(0,0,0,0.08), 0 4px 16px rgba(0,0,0,0.12)"},children:e.jsx(K,{source:o,theme:i})})]})}function K({source:t,theme:n}){const[o,i]=c.useState(!1),s=n.plain.backgroundColor??"#1e293b";if(t===void 0)return e.jsx("div",{style:{height:"100%",display:"flex",alignItems:"center",justifyContent:"center",background:s,color:"#94a3b8",fontSize:13},children:"Source not available"});const r=()=>{navigator.clipboard.writeText(t).then(()=>{i(!0),setTimeout(()=>{i(!1)},2e3)})};return e.jsxs("div",{style:{position:"relative",height:"100%"},children:[e.jsx("button",{type:"button",onClick:r,style:{position:"absolute",top:10,right:12,zIndex:1,padding:"3px 9px",fontSize:11,background:"rgba(255,255,255,0.1)",color:"#e2e8f0",border:"1px solid rgba(255,255,255,0.18)",borderRadius:4,cursor:"pointer"},children:o?"✓ Copied":"Copy"}),e.jsx(z.Highlight,{code:t.trim(),language:"tsx",theme:n,children:({style:l,tokens:d,getLineProps:a,getTokenProps:b})=>e.jsx("pre",{style:{...l,margin:0,padding:"12px 0",fontSize:12.5,lineHeight:1.7,fontFamily:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",height:"100%",boxSizing:"border-box",overflow:"auto"},children:d.map((p,x)=>e.jsxs("div",{...a({line:p}),style:{...a({line:p}).style,display:"flex",paddingRight:24},children:[e.jsx("span",{style:{userSelect:"none",minWidth:40,paddingLeft:14,paddingRight:14,textAlign:"right",color:"rgba(148,163,184,0.45)",flexShrink:0},children:x+1}),e.jsx("span",{children:p.map((y,h)=>e.jsx("span",{...b({token:y})},h))})]},x))})})]})}function E(){if(typeof window>"u")return null;const t=new URLSearchParams(window.location.search),n=t.get("entry");if(n===null)return null;const o=t.get("jogak");return{entryId:n,jogakName:o}}function ee(t,n){const o=new URLSearchParams;o.set("entry",t),o.set("jogak",n),window.history.pushState({},"",`?${o.toString()}`)}function te({entries:t,metas:n,codeTheme:o="vsDark"}={}){const i=c.useMemo(()=>{if(t!==void 0){n!==void 0&&console.warn("[jogak] JogakApp received both `entries` and `metas` — `entries` (eager) takes precedence.");const u=new k.ComponentRegistry;for(const f of t)u.register(f);return u}if(n!==void 0)for(const u of n)k.defaultRegistry.registerMeta(u);return k.defaultRegistry},[t,n]),s=c.useMemo(()=>E(),[]),[r,l]=c.useState((s==null?void 0:s.entryId)??null),[d,a]=c.useState((s==null?void 0:s.jogakName)??null),[b,p]=c.useState({});c.useEffect(()=>{const u=()=>{const f=E();f!==null?(l(f.entryId),a(f.jogakName),p({})):(l(null),a(null))};return window.addEventListener("popstate",u),()=>{window.removeEventListener("popstate",u)}},[]);const x=c.useCallback((u,f)=>{l(u),a(f),p({}),ee(u,f)},[]),y=c.useCallback((u,f)=>{if(l(g=>g===u?u:g),a(g=>g??f),typeof window<"u"){const g=new URLSearchParams(window.location.search);g.get("entry")===u&&g.get("jogak")===null&&(g.set("jogak",f),window.history.replaceState({},"",`?${g.toString()}`))}},[]),h=c.useCallback((u,f)=>{p(g=>({...g,[u]:f}))},[]),m=c.useCallback(()=>{p({})},[]);return e.jsx(j.JogakProvider,{registry:i,children:e.jsxs("div",{"data-jogak-shell":!0,style:{display:"grid",gridTemplateColumns:"260px 1fr",height:"100dvh",overflow:"hidden"},children:[e.jsx(I,{selectedEntryId:r,selectedJogakName:d,onSelect:x}),e.jsx("main",{style:{overflow:"hidden",minHeight:0},children:r!==null?e.jsx(D,{entryId:r,jogakName:d,overrideArgs:b,onArgChange:h,onReset:m,codeTheme:o,onResolveJogak:y}):e.jsx("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",height:"100%",color:"#9ca3af"},children:"Select a component from the sidebar"})})]})})}function ne(){const t=j.useRegistry(),n=c.useMemo(()=>t.getAll(),[t]),o=c.useMemo(()=>t.getTree(),[t]),i=c.useMemo(()=>s=>t.search(s),[t]);return{entries:n,tree:o,search:i}}exports.Actions=L;exports.Controls=F;exports.JogakApp=te;exports.Preview=D;exports.Sidebar=I;exports.useRegistry=ne;
package/dist/index.mjs CHANGED
@@ -8,7 +8,7 @@ function Y({
8
8
  selectedJogakName: t,
9
9
  onSelect: o
10
10
  }) {
11
- const [i, d] = x(""), { metaTree: r, searchMeta: s } = _(), l = i.trim().length > 0 ? s(i) : null;
11
+ const [i, d] = x(""), { metaTree: r, searchMeta: a } = _(), l = i.trim().length > 0 ? a(i) : null;
12
12
  return /* @__PURE__ */ c(
13
13
  "aside",
14
14
  {
@@ -27,8 +27,8 @@ function Y({
27
27
  type: "search",
28
28
  placeholder: "Search components...",
29
29
  value: i,
30
- onChange: (a) => {
31
- d(a.target.value);
30
+ onChange: (s) => {
31
+ d(s.target.value);
32
32
  },
33
33
  style: {
34
34
  width: "100%",
@@ -92,10 +92,10 @@ function H({
92
92
  margin: 0,
93
93
  padding: `0 0 0 ${d * 12}px`
94
94
  },
95
- children: Object.entries(e).map(([r, s]) => /* @__PURE__ */ n("li", { children: "id" in s ? /* @__PURE__ */ n(
95
+ children: Object.entries(e).map(([r, a]) => /* @__PURE__ */ n("li", { children: "id" in a ? /* @__PURE__ */ n(
96
96
  D,
97
97
  {
98
- meta: s,
98
+ meta: a,
99
99
  selectedEntryId: t,
100
100
  selectedJogakName: o,
101
101
  onSelect: i,
@@ -105,7 +105,7 @@ function H({
105
105
  Z,
106
106
  {
107
107
  label: r,
108
- node: s,
108
+ node: a,
109
109
  selectedEntryId: t,
110
110
  selectedJogakName: o,
111
111
  onSelect: i,
@@ -123,14 +123,14 @@ function Z({
123
123
  onSelect: d,
124
124
  depth: r
125
125
  }) {
126
- const [s, l] = x(!0);
126
+ const [a, l] = x(!0);
127
127
  return /* @__PURE__ */ c("div", { children: [
128
128
  /* @__PURE__ */ c(
129
129
  "button",
130
130
  {
131
131
  type: "button",
132
132
  onClick: () => {
133
- l((a) => !a);
133
+ l((s) => !s);
134
134
  },
135
135
  style: {
136
136
  display: "flex",
@@ -147,14 +147,14 @@ function Z({
147
147
  textTransform: "uppercase",
148
148
  letterSpacing: "0.05em"
149
149
  },
150
- "aria-expanded": s,
150
+ "aria-expanded": a,
151
151
  children: [
152
- /* @__PURE__ */ n("span", { children: s ? "▾" : "▸" }),
152
+ /* @__PURE__ */ n("span", { children: a ? "▾" : "▸" }),
153
153
  e
154
154
  ]
155
155
  }
156
156
  ),
157
- s && /* @__PURE__ */ n(
157
+ a && /* @__PURE__ */ n(
158
158
  H,
159
159
  {
160
160
  node: t,
@@ -173,11 +173,11 @@ function D({
173
173
  onSelect: i,
174
174
  indent: d
175
175
  }) {
176
- const r = e.id === t, [s, l] = x(r);
176
+ const r = e.id === t, [a, l] = x(r);
177
177
  v(() => {
178
178
  r && l(!0);
179
179
  }, [r]);
180
- const a = e.title.split("/").pop() ?? e.title, m = 16 + d * 12;
180
+ const s = e.title.split("/").pop() ?? e.title, m = 16 + d * 12;
181
181
  return /* @__PURE__ */ c("div", { children: [
182
182
  /* @__PURE__ */ c(
183
183
  "button",
@@ -206,14 +206,14 @@ function D({
206
206
  fontWeight: r ? 500 : 400,
207
207
  textAlign: "left"
208
208
  },
209
- "aria-expanded": s,
209
+ "aria-expanded": a,
210
210
  children: [
211
- /* @__PURE__ */ n("span", { style: { fontSize: 10, flexShrink: 0, lineHeight: 1 }, children: s ? "▾" : "▸" }),
212
- a
211
+ /* @__PURE__ */ n("span", { style: { fontSize: 10, flexShrink: 0, lineHeight: 1 }, children: a ? "▾" : "▸" }),
212
+ s
213
213
  ]
214
214
  }
215
215
  ),
216
- s && /* @__PURE__ */ n("ul", { style: { listStyle: "none", margin: 0, padding: 0 }, children: e.jogakNames.map((p) => {
216
+ a && /* @__PURE__ */ n("ul", { style: { listStyle: "none", margin: 0, padding: 0 }, children: e.jogakNames.map((p) => {
217
217
  const h = r && p === o;
218
218
  return /* @__PURE__ */ n("li", { children: /* @__PURE__ */ n(
219
219
  "button",
@@ -277,11 +277,11 @@ function ee({ argKey: e, value: t, argType: o, onArgChange: i }) {
277
277
  "select",
278
278
  {
279
279
  value: String(t ?? ""),
280
- onChange: (s) => {
281
- i(e, s.target.value);
280
+ onChange: (a) => {
281
+ i(e, a.target.value);
282
282
  },
283
283
  style: W,
284
- children: r.map((s) => /* @__PURE__ */ n("option", { value: String(s), children: String(s) }, String(s)))
284
+ children: r.map((a) => /* @__PURE__ */ n("option", { value: String(a), children: String(a) }, String(a)))
285
285
  }
286
286
  );
287
287
  }
@@ -363,7 +363,7 @@ function te({ args: e, argTypes: t, onArgChange: o }) {
363
363
  /* @__PURE__ */ n("th", { style: A, children: "Control" }),
364
364
  /* @__PURE__ */ n("th", { style: A, children: "Description" })
365
365
  ] }) }),
366
- /* @__PURE__ */ n("tbody", { children: d.map(([r, s]) => {
366
+ /* @__PURE__ */ n("tbody", { children: d.map(([r, a]) => {
367
367
  const l = t[r];
368
368
  return /* @__PURE__ */ c("tr", { children: [
369
369
  /* @__PURE__ */ n(
@@ -383,7 +383,7 @@ function te({ args: e, argTypes: t, onArgChange: o }) {
383
383
  ee,
384
384
  {
385
385
  argKey: r,
386
- value: s,
386
+ value: a,
387
387
  argType: l,
388
388
  onArgChange: o
389
389
  }
@@ -534,9 +534,9 @@ function le({
534
534
  onArgChange: i,
535
535
  onReset: d,
536
536
  codeTheme: r,
537
- onResolveJogak: s
537
+ onResolveJogak: a
538
538
  }) {
539
- const l = G(e), [a, m] = x("desktop"), [p, h] = x("white"), [S, b] = x("controls"), y = de(r);
539
+ const l = G(e), [s, m] = x("desktop"), [p, h] = x("white"), [S, b] = x("controls"), y = de(r);
540
540
  return l.status === "unknown" ? /* @__PURE__ */ c("div", { "data-testid": "preview-not-found", style: { padding: 24, color: "#ef4444" }, children: [
541
541
  "Entry not found: ",
542
542
  e
@@ -578,25 +578,25 @@ function le({
578
578
  ]
579
579
  }
580
580
  ) : l.status === "loading" ? /* @__PURE__ */ n(
581
- se,
581
+ ae,
582
582
  {
583
583
  meta: l.meta,
584
584
  jogakName: t,
585
- viewport: a,
585
+ viewport: s,
586
586
  bgMode: p,
587
587
  onViewportChange: m,
588
588
  onBgModeChange: h
589
589
  }
590
590
  ) : /* @__PURE__ */ n(
591
- ae,
591
+ se,
592
592
  {
593
593
  entry: l.entry,
594
594
  jogakName: t,
595
595
  overrideArgs: o,
596
596
  onArgChange: i,
597
597
  onReset: d,
598
- onResolveJogak: s,
599
- viewport: a,
598
+ onResolveJogak: a,
599
+ viewport: s,
600
600
  bgMode: p,
601
601
  bottomTab: S,
602
602
  onViewportChange: m,
@@ -606,7 +606,7 @@ function le({
606
606
  }
607
607
  );
608
608
  }
609
- function se({
609
+ function ae({
610
610
  meta: e,
611
611
  jogakName: t,
612
612
  viewport: o,
@@ -614,7 +614,7 @@ function se({
614
614
  onViewportChange: d,
615
615
  onBgModeChange: r
616
616
  }) {
617
- const s = t ?? e.jogakNames[0] ?? "...", l = N[o];
617
+ const a = t ?? e.jogakNames[0] ?? "...", l = N[o];
618
618
  return /* @__PURE__ */ c(
619
619
  "div",
620
620
  {
@@ -625,7 +625,7 @@ function se({
625
625
  J,
626
626
  {
627
627
  title: e.title,
628
- jogakName: s,
628
+ jogakName: a,
629
629
  viewport: o,
630
630
  bgMode: i,
631
631
  onViewportChange: d,
@@ -685,16 +685,16 @@ function se({
685
685
  }
686
686
  );
687
687
  }
688
- function ae({
688
+ function se({
689
689
  entry: e,
690
690
  jogakName: t,
691
691
  overrideArgs: o,
692
692
  onArgChange: i,
693
693
  onReset: d,
694
694
  onResolveJogak: r,
695
- viewport: s,
695
+ viewport: a,
696
696
  bgMode: l,
697
- bottomTab: a,
697
+ bottomTab: s,
698
698
  onViewportChange: m,
699
699
  onBgModeChange: p,
700
700
  onBottomTabChange: h,
@@ -718,14 +718,14 @@ function ae({
718
718
  const u = { ...y.args ?? {}, ...o }, g = {
719
719
  ...e.meta.argTypes ?? {},
720
720
  ...y.argTypes ?? {}
721
- }, P = Object.keys(o).length > 0, O = N[s];
721
+ }, P = Object.keys(o).length > 0, O = N[a];
722
722
  return /* @__PURE__ */ c("div", { style: { display: "flex", flexDirection: "column", height: "100%" }, children: [
723
723
  /* @__PURE__ */ n(
724
724
  J,
725
725
  {
726
726
  title: e.title,
727
727
  jogakName: y.name,
728
- viewport: s,
728
+ viewport: a,
729
729
  bgMode: l,
730
730
  onViewportChange: m,
731
731
  onBgModeChange: p,
@@ -745,6 +745,7 @@ function ae({
745
745
  children: /* @__PURE__ */ n(
746
746
  "div",
747
747
  {
748
+ "data-jogak-content": !0,
748
749
  style: {
749
750
  maxWidth: O === "none" ? "100%" : O,
750
751
  margin: "0 auto",
@@ -788,7 +789,7 @@ function ae({
788
789
  flexShrink: 0
789
790
  },
790
791
  children: ["controls", "actions"].map((k) => {
791
- const C = a === k;
792
+ const C = s === k;
792
793
  return /* @__PURE__ */ n(
793
794
  "button",
794
795
  {
@@ -817,7 +818,7 @@ function ae({
817
818
  })
818
819
  }
819
820
  ),
820
- /* @__PURE__ */ n("div", { style: { flex: 1, minHeight: 0, overflow: "auto" }, children: a === "controls" ? /* @__PURE__ */ n(
821
+ /* @__PURE__ */ n("div", { style: { flex: 1, minHeight: 0, overflow: "auto" }, children: s === "controls" ? /* @__PURE__ */ n(
821
822
  te,
822
823
  {
823
824
  args: u,
@@ -837,7 +838,7 @@ function J({
837
838
  bgMode: i,
838
839
  onViewportChange: d,
839
840
  onBgModeChange: r,
840
- showReset: s,
841
+ showReset: a,
841
842
  onReset: l
842
843
  }) {
843
844
  return /* @__PURE__ */ c(
@@ -868,55 +869,55 @@ function J({
868
869
  borderRadius: 6,
869
870
  padding: 2
870
871
  },
871
- children: ["mobile", "tablet", "desktop"].map((a) => /* @__PURE__ */ n(
872
+ children: ["mobile", "tablet", "desktop"].map((s) => /* @__PURE__ */ n(
872
873
  "button",
873
874
  {
874
875
  type: "button",
875
876
  onClick: () => {
876
- d(a);
877
+ d(s);
877
878
  },
878
- "aria-pressed": o === a,
879
+ "aria-pressed": o === s,
879
880
  style: {
880
881
  padding: "3px 9px",
881
882
  fontSize: 12,
882
883
  border: "none",
883
884
  borderRadius: 4,
884
885
  cursor: "pointer",
885
- background: o === a ? "#fff" : "transparent",
886
- color: o === a ? "#111827" : "#6b7280",
887
- fontWeight: o === a ? 600 : 400,
888
- boxShadow: o === a ? "0 1px 2px rgba(0,0,0,0.08)" : "none",
886
+ background: o === s ? "#fff" : "transparent",
887
+ color: o === s ? "#111827" : "#6b7280",
888
+ fontWeight: o === s ? 600 : 400,
889
+ boxShadow: o === s ? "0 1px 2px rgba(0,0,0,0.08)" : "none",
889
890
  transition: "all 0.1s"
890
891
  },
891
- children: ie[a]
892
+ children: ie[s]
892
893
  },
893
- a
894
+ s
894
895
  ))
895
896
  }
896
897
  ),
897
- /* @__PURE__ */ n("div", { style: { display: "flex", gap: 4, alignItems: "center" }, children: ["white", "dark", "transparent"].map((a) => /* @__PURE__ */ n(
898
+ /* @__PURE__ */ n("div", { style: { display: "flex", gap: 4, alignItems: "center" }, children: ["white", "dark", "transparent"].map((s) => /* @__PURE__ */ n(
898
899
  "button",
899
900
  {
900
901
  type: "button",
901
902
  onClick: () => {
902
- r(a);
903
+ r(s);
903
904
  },
904
- "aria-pressed": i === a,
905
- "aria-label": `${a} background`,
905
+ "aria-pressed": i === s,
906
+ "aria-label": `${s} background`,
906
907
  style: {
907
908
  width: 20,
908
909
  height: 20,
909
910
  borderRadius: 4,
910
- border: i === a ? "2px solid #2563eb" : "2px solid #d1d5db",
911
+ border: i === s ? "2px solid #2563eb" : "2px solid #d1d5db",
911
912
  cursor: "pointer",
912
913
  padding: 0,
913
914
  flexShrink: 0,
914
- ...M[a]
915
+ ...M[s]
915
916
  }
916
917
  },
917
- a
918
+ s
918
919
  )) }),
919
- s && /* @__PURE__ */ n(
920
+ a && /* @__PURE__ */ n(
920
921
  "button",
921
922
  {
922
923
  type: "button",
@@ -938,7 +939,7 @@ function J({
938
939
  );
939
940
  }
940
941
  function ce({ entry: e, args: t, source: o, theme: i }) {
941
- const d = V(null), [r, s] = x(!1);
942
+ const d = V(null), [r, a] = x(!1);
942
943
  return v(() => {
943
944
  const l = d.current;
944
945
  if (l !== null)
@@ -968,7 +969,7 @@ function ce({ entry: e, args: t, source: o, theme: i }) {
968
969
  {
969
970
  type: "button",
970
971
  onClick: () => {
971
- s((l) => !l);
972
+ a((l) => !l);
972
973
  },
973
974
  "aria-pressed": r,
974
975
  "aria-label": r ? "Hide source code" : "Show source code",
@@ -1052,11 +1053,11 @@ function pe({ source: e, theme: t }) {
1052
1053
  children: o ? "✓ Copied" : "Copy"
1053
1054
  }
1054
1055
  ),
1055
- /* @__PURE__ */ n(Q, { code: e.trim(), language: "tsx", theme: t, children: ({ style: s, tokens: l, getLineProps: a, getTokenProps: m }) => /* @__PURE__ */ n(
1056
+ /* @__PURE__ */ n(Q, { code: e.trim(), language: "tsx", theme: t, children: ({ style: a, tokens: l, getLineProps: s, getTokenProps: m }) => /* @__PURE__ */ n(
1056
1057
  "pre",
1057
1058
  {
1058
1059
  style: {
1059
- ...s,
1060
+ ...a,
1060
1061
  margin: 0,
1061
1062
  padding: "12px 0",
1062
1063
  fontSize: 12.5,
@@ -1069,9 +1070,9 @@ function pe({ source: e, theme: t }) {
1069
1070
  children: l.map((p, h) => /* @__PURE__ */ c(
1070
1071
  "div",
1071
1072
  {
1072
- ...a({ line: p }),
1073
+ ...s({ line: p }),
1073
1074
  style: {
1074
- ...a({ line: p }).style,
1075
+ ...s({ line: p }).style,
1075
1076
  display: "flex",
1076
1077
  paddingRight: 24
1077
1078
  },
@@ -1128,24 +1129,24 @@ function me({
1128
1129
  if (t !== void 0)
1129
1130
  for (const f of t) F.registerMeta(f);
1130
1131
  return F;
1131
- }, [e, t]), d = w(() => E(), []), [r, s] = x(
1132
+ }, [e, t]), d = w(() => E(), []), [r, a] = x(
1132
1133
  (d == null ? void 0 : d.entryId) ?? null
1133
- ), [l, a] = x(
1134
+ ), [l, s] = x(
1134
1135
  (d == null ? void 0 : d.jogakName) ?? null
1135
1136
  ), [m, p] = x({});
1136
1137
  v(() => {
1137
1138
  const f = () => {
1138
1139
  const u = E();
1139
- u !== null ? (s(u.entryId), a(u.jogakName), p({})) : (s(null), a(null));
1140
+ u !== null ? (a(u.entryId), s(u.jogakName), p({})) : (a(null), s(null));
1140
1141
  };
1141
1142
  return window.addEventListener("popstate", f), () => {
1142
1143
  window.removeEventListener("popstate", f);
1143
1144
  };
1144
1145
  }, []);
1145
1146
  const h = R((f, u) => {
1146
- s(f), a(u), p({}), fe(f, u);
1147
+ a(f), s(u), p({}), fe(f, u);
1147
1148
  }, []), S = R((f, u) => {
1148
- if (s((g) => g === f ? f : g), a((g) => g ?? u), typeof window < "u") {
1149
+ if (a((g) => g === f ? f : g), s((g) => g ?? u), typeof window < "u") {
1149
1150
  const g = new URLSearchParams(window.location.search);
1150
1151
  g.get("entry") === f && g.get("jogak") === null && (g.set("jogak", u), window.history.replaceState({}, "", `?${g.toString()}`));
1151
1152
  }
@@ -1157,6 +1158,7 @@ function me({
1157
1158
  return /* @__PURE__ */ n(T, { registry: i, children: /* @__PURE__ */ c(
1158
1159
  "div",
1159
1160
  {
1161
+ "data-jogak-shell": !0,
1160
1162
  style: {
1161
1163
  display: "grid",
1162
1164
  gridTemplateColumns: "260px 1fr",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jogak/ui",
3
- "version": "0.1.0-alpha.2",
3
+ "version": "0.1.0-alpha.4",
4
4
  "description": "Showcase viewer UI for Jogak — Sidebar / Preview / Controls / Actions and the JogakApp shell.",
5
5
  "keywords": [
6
6
  "jogak",
@@ -45,6 +45,7 @@
45
45
  "src/app",
46
46
  "src/components",
47
47
  "src/hooks",
48
+ "src/styles",
48
49
  "src/index.ts",
49
50
  "src/vite-env.d.ts",
50
51
  "README.md",
@@ -60,8 +61,10 @@
60
61
  },
61
62
  "dependencies": {
62
63
  "prism-react-renderer": "^2.4.1",
63
- "@jogak/core": "0.1.0-alpha.2",
64
- "@jogak/react": "0.1.0-alpha.2"
64
+ "tailwindcss": "^4.0.0",
65
+ "@tailwindcss/vite": "^4.0.0",
66
+ "@jogak/core": "0.1.0-alpha.4",
67
+ "@jogak/react": "0.1.0-alpha.4"
65
68
  },
66
69
  "devDependencies": {
67
70
  "@types/node": "^20.14.0",
package/src/app/App.tsx CHANGED
@@ -126,6 +126,7 @@ export function JogakApp({
126
126
  return (
127
127
  <JogakProvider registry={registry}>
128
128
  <div
129
+ data-jogak-shell
129
130
  style={{
130
131
  display: 'grid',
131
132
  gridTemplateColumns: '260px 1fr',
package/src/app/main.tsx CHANGED
@@ -2,6 +2,7 @@ import { StrictMode } from 'react'
2
2
  import { createRoot } from 'react-dom/client'
3
3
  import 'virtual:jogak'
4
4
  import { _jogakCodeTheme } from 'virtual:jogak'
5
+ import '../styles/jogak.css'
5
6
  import { JogakApp } from './App.js'
6
7
 
7
8
  const rootEl = document.getElementById('root')
@@ -336,6 +336,7 @@ function ReadyFrame({
336
336
  }}
337
337
  >
338
338
  <div
339
+ data-jogak-content
339
340
  style={{
340
341
  maxWidth: maxWidth === 'none' ? '100%' : maxWidth,
341
342
  margin: '0 auto',
@@ -0,0 +1,88 @@
1
+ /*
2
+ * jogak SPA 전용 스타일.
3
+ *
4
+ * 본 파일은 `packages/ui/src/app/main.tsx`에서만 import된다.
5
+ * lib mode build entry(`src/index.ts`, `src/host/index.ts`)에는 import되지 않으므로
6
+ * publish되는 `dist/index.{mjs,js}` / `dist/host/index.{mjs,js}` 산출물에 css 흔적이
7
+ * 들어가지 않는다 (사용자 번들 영향 zero — api-contracts §2.4, §7).
8
+ *
9
+ * Tailwind v4: preflight를 의도적으로 import하지 않고 `theme.css` + `utilities.css`만
10
+ * 분리 import한다. preflight의 globals(`*`, `html`, `body`)는 사용자 css와 prefix
11
+ * 무관하게 충돌 가능 — jogak SPA는 `index.html`의 inline reset(`box-sizing`,
12
+ * `body margin:0`)으로 충분하다 (api-contracts §6.2).
13
+ *
14
+ * `prefix(jogak)` — 모든 utility/variant/theme variable에 `jogak:` prefix가 적용된다.
15
+ * 사용자가 v4(no prefix)나 v3(`tw-` prefix)를 써도 selector 충돌 zero.
16
+ */
17
+
18
+ @import "tailwindcss/theme.css" layer(theme) prefix(jogak);
19
+ @import "tailwindcss/utilities.css" layer(utilities) prefix(jogak);
20
+
21
+ /*
22
+ * jogak 디자인 토큰 (`--jogak-*`).
23
+ *
24
+ * 정의 위치는 `:root` — preview 내부의 사용자 컴포넌트도 var() 참조 가능 (원하면).
25
+ * `--jogak-*` prefix가 충분한 namespace를 제공하므로 사용자 globalCss(알파.6 예정)
26
+ * 와 충돌 zero.
27
+ *
28
+ * 알파.4에서는 변수만 정의하고 컴포넌트는 inline style을 그대로 둔다.
29
+ * 알파.5에서 `style={{ color: '#374151' }}` → `className="jogak:text-[var(--jogak-color-fg)]"`
30
+ * 형태로 마이그레이션한다 (api-contracts §4.4).
31
+ */
32
+ @layer base {
33
+ :root {
34
+ /* color */
35
+ --jogak-color-bg: #ffffff;
36
+ --jogak-color-fg: #374151;
37
+ --jogak-color-fg-muted: #6b7280;
38
+ --jogak-color-fg-subtle: #9ca3af;
39
+ --jogak-color-fg-strong: #111827;
40
+ --jogak-color-bg-subtle: #f9fafb;
41
+ --jogak-color-bg-elevated: #ffffff;
42
+ --jogak-color-bg-error: #fef2f2;
43
+
44
+ --jogak-color-accent: #2563eb;
45
+ --jogak-color-accent-bg: #eff6ff;
46
+ --jogak-color-accent-fg: #1d4ed8;
47
+ --jogak-color-accent-bg-soft: #dbeafe;
48
+
49
+ --jogak-color-violet: #7c3aed;
50
+ --jogak-color-violet-bg: #f5f3ff;
51
+ --jogak-color-violet-border:#ddd6fe;
52
+
53
+ --jogak-color-error: #ef4444;
54
+ --jogak-color-error-fg: #b91c1c;
55
+ --jogak-color-error-border: #fecaca;
56
+
57
+ --jogak-color-border: #e5e7eb;
58
+ --jogak-color-border-muted: #f3f4f6;
59
+ --jogak-color-border-strong:#d1d5db;
60
+ --jogak-color-checker: #e2e8f0;
61
+
62
+ /* spacing */
63
+ --jogak-space-1: 4px;
64
+ --jogak-space-2: 8px;
65
+ --jogak-space-3: 12px;
66
+ --jogak-space-4: 16px;
67
+ --jogak-space-5: 20px;
68
+ --jogak-space-6: 24px;
69
+
70
+ /* radius */
71
+ --jogak-radius-sm: 3px;
72
+ --jogak-radius-md: 4px;
73
+ --jogak-radius-lg: 6px;
74
+ --jogak-radius-xl: 8px;
75
+
76
+ /* typography */
77
+ --jogak-font-sans: system-ui, sans-serif;
78
+ --jogak-font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;
79
+ --jogak-text-xs: 10px;
80
+ --jogak-text-sm: 11px;
81
+ --jogak-text-base: 12px;
82
+ --jogak-text-md: 13px;
83
+ --jogak-text-lg: 14px;
84
+
85
+ /* layout 상수 */
86
+ --jogak-sidebar-width: 260px;
87
+ }
88
+ }