@jogak/ui 0.1.0-alpha.8 → 0.1.0-alpha.9.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jogak/ui",
3
- "version": "0.1.0-alpha.8",
3
+ "version": "0.1.0-alpha.9.1",
4
4
  "description": "Showcase viewer UI for Jogak — Sidebar / Preview / Controls / Actions and the JogakApp shell.",
5
5
  "keywords": [
6
6
  "jogak",
@@ -24,19 +24,19 @@
24
24
  },
25
25
  "type": "module",
26
26
  "sideEffects": false,
27
- "main": "./dist/index.js",
27
+ "main": "./dist/index.cjs",
28
28
  "module": "./dist/index.mjs",
29
29
  "types": "./dist/index.d.ts",
30
30
  "exports": {
31
31
  ".": {
32
32
  "types": "./dist/index.d.ts",
33
33
  "import": "./dist/index.mjs",
34
- "require": "./dist/index.js"
34
+ "require": "./dist/index.cjs"
35
35
  },
36
36
  "./host": {
37
37
  "types": "./dist/host/index.d.ts",
38
38
  "import": "./dist/host/index.mjs",
39
- "require": "./dist/host/index.js"
39
+ "require": "./dist/host/index.cjs"
40
40
  }
41
41
  },
42
42
  "files": [
@@ -65,8 +65,8 @@
65
65
  "prism-react-renderer": "^2.4.1",
66
66
  "tailwindcss": "^4.0.0",
67
67
  "@tailwindcss/vite": "^4.0.0",
68
- "@jogak/core": "0.1.0-alpha.8",
69
- "@jogak/react": "0.1.0-alpha.8"
68
+ "@jogak/core": "0.1.0-alpha.9.1",
69
+ "@jogak/react": "0.1.0-alpha.9.1"
70
70
  },
71
71
  "devDependencies": {
72
72
  "@types/node": "^20.14.0",
package/src/app/App.tsx CHANGED
@@ -31,9 +31,17 @@ export interface JogakAppProps {
31
31
  */
32
32
  readonly previewIsolation?: 'none' | 'shadow' | 'iframe'
33
33
  /**
34
- * 알파.8: 사용자 vite spawn URL. iframe `src` base로 사용.
34
+ * 알파.9: 어댑터 dev URL. iframe `src` base.
35
35
  * 빈 문자열 시 fallback (jogak SPA Vite scope의 preview-frame.tsx).
36
36
  */
37
+ readonly userPreviewUrl?: string
38
+ /**
39
+ * 알파.9: iframe entry path (예: `/__jogak_preview__/index.html`).
40
+ */
41
+ readonly previewEntryPath?: string
42
+ /**
43
+ * @deprecated 알파.10 제거 예정. `userPreviewUrl` 사용.
44
+ */
37
45
  readonly userViteUrl?: string
38
46
  }
39
47
 
@@ -58,8 +66,12 @@ export function JogakApp({
58
66
  metas,
59
67
  codeTheme = 'vsDark',
60
68
  previewIsolation = 'iframe',
61
- userViteUrl = '',
69
+ userPreviewUrl = '',
70
+ previewEntryPath = '/__jogak_preview__/index.html',
71
+ userViteUrl,
62
72
  }: JogakAppProps = {}): ReactElement {
73
+ // 알파.9: userViteUrl alias (deprecated). userPreviewUrl 우선.
74
+ const resolvedPreviewUrl = userPreviewUrl !== '' ? userPreviewUrl : (userViteUrl ?? '')
63
75
  // ── 4가지 모드 결정 (계약 §5.2) ─────────────────────────────────────
64
76
  // 1) entries가 주어지면: 새 ComponentRegistry에 register (eager, 기존 동작)
65
77
  // 2) metas만 주어지면: defaultRegistry 사용 + metas를 registerMeta로 등록
@@ -162,7 +174,8 @@ export function JogakApp({
162
174
  codeTheme={codeTheme}
163
175
  onResolveJogak={handleResolveJogak}
164
176
  previewIsolation={previewIsolation}
165
- userViteUrl={userViteUrl}
177
+ userPreviewUrl={resolvedPreviewUrl}
178
+ previewEntryPath={previewEntryPath}
166
179
  />
167
180
  ) : (
168
181
  <div className="jogak:flex jogak:items-center jogak:justify-center jogak:h-full jogak:text-[var(--jogak-color-fg-subtle)]">
package/src/app/main.tsx CHANGED
@@ -4,16 +4,14 @@ import 'virtual:jogak'
4
4
  import {
5
5
  _jogakCodeTheme,
6
6
  _jogakPreviewIsolation,
7
- _jogakUserViteUrl,
7
+ _jogakUserPreviewUrl,
8
+ _jogakPreviewEntryPath,
8
9
  } from 'virtual:jogak'
9
10
  import '../styles/jogak.css'
10
11
  import { JogakApp } from './App.js'
11
12
 
12
- // 알파.8: 사용자 globalCss는 사용자 vite scope(iframe entry)에서 처리되므로
13
- // jogak SPA outer document에는 import하지 않는다 chrome 격리 보존.
14
- //
15
- // 'none' 모드(deprecated): 알파.7.1 동작 유지가 필요한 사용자만 명시 사용.
16
- // 이 경우만 outer document에 사용자 globalCss inject.
13
+ // 알파.9: 사용자 globalCss는 어댑터 scope(iframe entry)에서 처리되므로 jogak SPA outer
14
+ // document에는 import하지 않는다. 'none' 모드(deprecated)에서만 outer inject.
17
15
  if (_jogakPreviewIsolation === 'none') {
18
16
  await import('virtual:jogak/global-css')
19
17
  }
@@ -26,7 +24,8 @@ createRoot(rootEl).render(
26
24
  <JogakApp
27
25
  codeTheme={_jogakCodeTheme}
28
26
  previewIsolation={_jogakPreviewIsolation}
29
- userViteUrl={_jogakUserViteUrl}
27
+ userPreviewUrl={_jogakUserPreviewUrl}
28
+ previewEntryPath={_jogakPreviewEntryPath}
30
29
  />
31
30
  </StrictMode>,
32
31
  )
@@ -1,46 +1,61 @@
1
1
  /**
2
- * 알파.7: previewIsolation='iframe' 모드 iframe document entry.
2
+ * 알파.9: standalone-adapter 또는 fallback 시 사용되는 same-origin iframe entry.
3
3
  *
4
- * - 부모 Preview 컴포넌트의 `<IframeMount>`가 `iframe.contentWindow.__jogak_setProps__`
5
- * 호출해 entry/args를 주입한다.
6
- * - iframe 부모는 동일 origin (Vite dev server) → contentWindow 직접 접근 가능.
7
- * postMessage는 cross-origin/iframe sandbox 시나리오에서만 필요.
8
- * - 사용자 globalCss(`virtual:jogak/global-css`)만 import jogak.css는 chrome 전용
9
- * 이라 iframe에서는 미필요. 사용자 reset이 iframe document에 free하게 적용됨.
4
+ * `IframeMount`는 알파.9에서 postMessage 프로토콜로 통일됐다 (cross-origin 어댑터와 동일).
5
+ * preview-frame.tsx도 같은 프로토콜을 따라야 한다 — 부모는 `jogak:setProps` 메시지를,
6
+ * iframe `jogak:ready` / `jogak:rendered` / `jogak:error`를 emit한다.
7
+ *
8
+ * jogak host vite scope에서 동작하므로 `virtual:jogak` (registry metas + entry loader)와
9
+ * `virtual:jogak/global-css` (사용자 globalCss) 가상 모듈을 그대로 사용한다.
10
10
  */
11
11
  import { reactAdapter } from '@jogak/react'
12
- import type { RegistryEntry } from '@jogak/core'
12
+ import { defaultRegistry } from '@jogak/core'
13
13
  import 'virtual:jogak'
14
14
  import 'virtual:jogak/global-css'
15
15
 
16
- interface SetPropsArgs {
17
- readonly entry: RegistryEntry
18
- readonly args: Readonly<Record<string, unknown>>
19
- }
20
-
21
- declare global {
22
- interface Window {
23
- __jogak_setProps__?: (args: SetPropsArgs) => void
24
- __jogak_unmount__?: () => void
25
- }
26
- }
27
-
28
16
  const rootEl = document.getElementById('jogak-preview-root')
29
17
  if (rootEl === null) throw new Error('#jogak-preview-root not found')
30
18
 
31
- let currentEl: HTMLDivElement | null = null
19
+ let currentContainer: HTMLDivElement | null = null
32
20
 
33
- window.__jogak_setProps__ = ({ entry, args }) => {
34
- if (currentEl === null) {
35
- currentEl = document.createElement('div')
36
- rootEl.replaceChildren(currentEl)
21
+ async function renderEntry(
22
+ entryId: string,
23
+ args: Readonly<Record<string, unknown>>,
24
+ ): Promise<void> {
25
+ const entry = await defaultRegistry.requestEntry(entryId)
26
+ if (currentContainer === null) {
27
+ currentContainer = document.createElement('div')
28
+ rootEl?.replaceChildren(currentContainer)
37
29
  }
38
- reactAdapter.render(entry, args, currentEl)
30
+ reactAdapter.render(entry, args, currentContainer)
39
31
  }
40
32
 
41
- window.__jogak_unmount__ = () => {
42
- if (currentEl !== null) {
43
- reactAdapter.unmount(currentEl)
44
- currentEl = null
33
+ function unmount(): void {
34
+ if (currentContainer !== null) {
35
+ reactAdapter.unmount(currentContainer)
36
+ currentContainer = null
45
37
  }
46
38
  }
39
+
40
+ window.addEventListener('message', (event: MessageEvent) => {
41
+ const data = event.data as { type?: unknown; entryId?: unknown; args?: unknown } | null
42
+ if (data === null || typeof data !== 'object') return
43
+ if (data.type === 'jogak:setProps' && typeof data.entryId === 'string') {
44
+ const args = (data.args ?? {}) as Readonly<Record<string, unknown>>
45
+ void renderEntry(data.entryId, args)
46
+ .then(() => {
47
+ window.parent.postMessage(
48
+ { type: 'jogak:rendered', entryId: data.entryId },
49
+ '*',
50
+ )
51
+ })
52
+ .catch((err: unknown) => {
53
+ const message = err instanceof Error ? err.message : String(err)
54
+ window.parent.postMessage({ type: 'jogak:error', message }, '*')
55
+ })
56
+ } else if (data.type === 'jogak:unmount') {
57
+ unmount()
58
+ }
59
+ })
60
+
61
+ window.parent.postMessage({ type: 'jogak:ready' }, '*')
@@ -6,10 +6,15 @@ export interface IframeMountProps {
6
6
  readonly entry: RegistryEntry
7
7
  readonly args: Readonly<Record<string, unknown>>
8
8
  /**
9
- * 알파.8: 사용자 vite spawn URL (예: `http://localhost:5174`).
9
+ * 알파.9: 어댑터 dev URL (예: `http://localhost:5174`).
10
10
  * 빈 문자열 시 fallback (jogak SPA Vite scope의 `/preview-frame.html`).
11
11
  */
12
- readonly userViteUrl: string
12
+ readonly userPreviewUrl: string
13
+ /**
14
+ * 알파.9: iframe entry path (예: `/__jogak_preview__/index.html`).
15
+ * 어댑터의 `previewEntryMeta.devEntryPath`.
16
+ */
17
+ readonly previewEntryPath: string
13
18
  readonly className?: string
14
19
  readonly 'data-testid'?: string
15
20
  }
@@ -33,7 +38,8 @@ export interface IframeMountProps {
33
38
  export function IframeMount({
34
39
  entry,
35
40
  args,
36
- userViteUrl,
41
+ userPreviewUrl,
42
+ previewEntryPath,
37
43
  className,
38
44
  'data-testid': dataTestId,
39
45
  }: IframeMountProps): ReactElement {
@@ -41,8 +47,8 @@ export function IframeMount({
41
47
  const [ready, setReady] = useState(false)
42
48
 
43
49
  const src =
44
- userViteUrl !== ''
45
- ? `${userViteUrl}/__jogak_preview__/index.html`
50
+ userPreviewUrl !== ''
51
+ ? `${userPreviewUrl}${previewEntryPath}`
46
52
  : '/preview-frame.html'
47
53
 
48
54
  // postMessage 리스너 — iframe contentWindow 일치성 검증 후 처리.
@@ -32,10 +32,14 @@ export interface PreviewProps {
32
32
  */
33
33
  readonly previewIsolation?: 'none' | 'shadow' | 'iframe'
34
34
  /**
35
- * 알파.8: 사용자 vite spawn URL. iframe `src` base.
35
+ * 알파.9: 어댑터 dev URL. iframe `src` base.
36
36
  * 빈 문자열 시 fallback (jogak SPA Vite scope의 `/preview-frame.html`).
37
37
  */
38
- readonly userViteUrl?: string
38
+ readonly userPreviewUrl?: string
39
+ /**
40
+ * 알파.9: iframe entry path.
41
+ */
42
+ readonly previewEntryPath?: string
39
43
  }
40
44
 
41
45
  type ViewportKey = 'mobile' | 'tablet' | 'desktop'
@@ -126,7 +130,8 @@ export function Preview({
126
130
  codeTheme,
127
131
  onResolveJogak,
128
132
  previewIsolation = 'iframe',
129
- userViteUrl = '',
133
+ userPreviewUrl = '',
134
+ previewEntryPath = '/__jogak_preview__/index.html',
130
135
  }: PreviewProps): ReactElement {
131
136
  const state = useEntry(entryId)
132
137
  const [viewport, setViewport] = useState<ViewportKey>('desktop')
@@ -193,7 +198,8 @@ export function Preview({
193
198
  onBottomTabChange={setBottomTab}
194
199
  prismTheme={prismTheme}
195
200
  previewIsolation={previewIsolation}
196
- userViteUrl={userViteUrl}
201
+ userPreviewUrl={userPreviewUrl}
202
+ previewEntryPath={previewEntryPath}
197
203
  />
198
204
  )
199
205
  }
@@ -282,7 +288,8 @@ interface ReadyFrameProps {
282
288
  readonly onBottomTabChange: (tab: 'controls' | 'actions') => void
283
289
  readonly prismTheme: PrismTheme
284
290
  readonly previewIsolation: 'none' | 'shadow' | 'iframe'
285
- readonly userViteUrl: string
291
+ readonly userPreviewUrl: string
292
+ readonly previewEntryPath: string
286
293
  }
287
294
 
288
295
  function ReadyFrame({
@@ -300,7 +307,8 @@ function ReadyFrame({
300
307
  onBottomTabChange,
301
308
  prismTheme,
302
309
  previewIsolation,
303
- userViteUrl,
310
+ userPreviewUrl,
311
+ previewEntryPath,
304
312
  }: ReadyFrameProps): ReactElement {
305
313
  // jogakName이 비어있으면 (deep link `?entry=...&jogak` 누락) 첫 jogak로 보정.
306
314
  const resolvedJogakName = jogakName ?? entry.jogaks[0]?.name ?? null
@@ -373,7 +381,8 @@ function ReadyFrame({
373
381
  source={entry.source}
374
382
  theme={prismTheme}
375
383
  previewIsolation={previewIsolation}
376
- userViteUrl={userViteUrl}
384
+ userPreviewUrl={userPreviewUrl}
385
+ previewEntryPath={previewEntryPath}
377
386
  />
378
387
  </div>
379
388
  </div>
@@ -524,19 +533,18 @@ interface JogakRendererProps {
524
533
  readonly source: string | undefined
525
534
  readonly theme: PrismTheme
526
535
  readonly previewIsolation: 'none' | 'shadow' | 'iframe'
527
- readonly userViteUrl: string
536
+ readonly userPreviewUrl: string
537
+ readonly previewEntryPath: string
528
538
  }
529
539
 
530
540
  /**
531
- * 알파.8: previewIsolation 모드별로 사용자 콘텐츠 마운트 방식을 분기한다.
541
+ * 알파.9: previewIsolation 모드별로 사용자 콘텐츠 마운트 방식을 분기한다.
532
542
  *
533
- * - `'iframe'` (default) — 사용자 vite scope의 `<IframeMount>`로 별도 document.
543
+ * - `'iframe'` (default) — 어댑터 dev URL의 `<IframeMount>`로 별도 document.
534
544
  * - `'shadow'` (deprecated) — `<ShadowMount>` 안에 마운트.
535
545
  * - `'none'` (deprecated) — 같은 document에 직접 마운트.
536
- *
537
- * Show source 토글, 코드 패널 등 chrome 부분은 모드 무관하게 외부에 둔다.
538
546
  */
539
- function JogakRenderer({ entry, args, source, theme, previewIsolation, userViteUrl }: JogakRendererProps): ReactElement {
547
+ function JogakRenderer({ entry, args, source, theme, previewIsolation, userPreviewUrl, previewEntryPath }: JogakRendererProps): ReactElement {
540
548
  const [showCode, setShowCode] = useState(false)
541
549
 
542
550
  const previewBody = (
@@ -545,7 +553,8 @@ function JogakRenderer({ entry, args, source, theme, previewIsolation, userViteU
545
553
  entry={entry}
546
554
  args={args}
547
555
  previewIsolation={previewIsolation}
548
- userViteUrl={userViteUrl}
556
+ userPreviewUrl={userPreviewUrl}
557
+ previewEntryPath={previewEntryPath}
549
558
  />
550
559
  <button
551
560
  type="button"
@@ -587,14 +596,15 @@ interface PreviewMountProps {
587
596
  readonly entry: RegistryEntry
588
597
  readonly args: Readonly<Record<string, unknown>>
589
598
  readonly previewIsolation: 'none' | 'shadow' | 'iframe'
590
- readonly userViteUrl: string
599
+ readonly userPreviewUrl: string
600
+ readonly previewEntryPath: string
591
601
  }
592
602
 
593
603
  const PREVIEW_HOST_CLASS =
594
604
  'jogak:border jogak:border-dashed jogak:border-[var(--jogak-color-border)] ' +
595
605
  'jogak:rounded-[var(--jogak-radius-xl)] jogak:p-4 jogak:pb-9'
596
606
 
597
- function PreviewMount({ entry, args, previewIsolation, userViteUrl }: PreviewMountProps): ReactElement {
607
+ function PreviewMount({ entry, args, previewIsolation, userPreviewUrl, previewEntryPath }: PreviewMountProps): ReactElement {
598
608
  if (previewIsolation === 'shadow') {
599
609
  return (
600
610
  <ShadowMount
@@ -611,7 +621,8 @@ function PreviewMount({ entry, args, previewIsolation, userViteUrl }: PreviewMou
611
621
  <IframeMount
612
622
  entry={entry}
613
623
  args={args}
614
- userViteUrl={userViteUrl}
624
+ userPreviewUrl={userPreviewUrl}
625
+ previewEntryPath={previewEntryPath}
615
626
  data-testid="preview-content"
616
627
  className={`${PREVIEW_HOST_CLASS} jogak:block jogak:w-full jogak:bg-transparent jogak:min-h-[256px]`}
617
628
  />
package/src/vite-env.d.ts CHANGED
@@ -9,9 +9,19 @@ declare module 'virtual:jogak' {
9
9
  */
10
10
  export const _jogakPreviewIsolation: 'none' | 'shadow' | 'iframe'
11
11
  /**
12
- * 알파.8: 사용자 vite spawn URL. iframe `src` base로 사용 (예: `http://localhost:5174`).
12
+ * 알파.9: 어댑터 dev URL. iframe `src` base로 사용 (예: `http://localhost:5174`).
13
13
  * 빈 문자열 시 fallback (jogak SPA Vite scope의 preview-frame.tsx).
14
14
  */
15
+ export const _jogakUserPreviewUrl: string
16
+ /**
17
+ * 알파.9: iframe entry path (`BuilderAdapter.previewEntryMeta.devEntryPath`).
18
+ * 어댑터별 routing (vite: `/__jogak_preview__/index.html`).
19
+ */
20
+ export const _jogakPreviewEntryPath: string
21
+ /**
22
+ * @deprecated 알파.10 제거 예정. `_jogakUserPreviewUrl` 사용.
23
+ * 알파.8 호환 alias.
24
+ */
15
25
  export const _jogakUserViteUrl: string
16
26
  }
17
27
 
@@ -1 +0,0 @@
1
- "use strict";var S=Object.create;var m=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var B=Object.getPrototypeOf,H=Object.prototype.hasOwnProperty;var N=(t,e,o,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of A(e))!H.call(t,r)&&r!==o&&m(t,r,{get:()=>e[r],enumerable:!(n=k(e,r))||n.enumerable});return t};var a=(t,e,o)=>(o=t!=null?S(B(t)):{},N(e||!t||!t.__esModule?m(o,"default",{value:t,enumerable:!0}):o,t));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const x=require("node:url"),s=require("node:path");var f=typeof document<"u"?document.currentScript:null;const F=x.fileURLToPath(typeof document>"u"?require("url").pathToFileURL(__filename).href:f&&f.tagName.toUpperCase()==="SCRIPT"&&f.src||new URL("host/index.js",document.baseURI).href),i=s.resolve(s.dirname(F),"..",".."),E=s.resolve(i,"index.html"),V=s.resolve(i,"src/app/main.tsx");async function Y(t){const e=await import("vite"),o=await import("@vitejs/plugin-react"),n=await import("@jogak/core/vite"),r=await import("@tailwindcss/vite"),{createServer:v,build:h}=e,b=o.default,w=r.default,{jogak:_}=n,C=t.codeTheme??"vsDark",u={patterns:t.patterns,codeTheme:C,cwd:t.userRoot};t.tsConfigFilePath!==void 0&&(u.tsConfigFilePath=t.tsConfigFilePath),t.globalCss!==void 0&&(u.globalCss=t.globalCss),t.previewIsolation!==void 0&&(u.previewIsolation=t.previewIsolation),t.userViteUrl!==void 0&&(u.userViteUrl=t.userViteUrl);const U=t.extraPlugins??[],d={root:i,configFile:!1,plugins:[b(),w(),_(u),...U],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:[i,t.userRoot]}},L={...d,server:D},l=await v(L);await l.listen();const p=l.config.server.port??t.port??5173,c=t.host??"localhost",M=`http://${typeof c=="boolean"?c?"0.0.0.0":"localhost":c}:${p.toString()}/`;let g=!1;return{url:M,port:p,close:async()=>{g||(g=!0,await l.close())},printUrls:()=>{l.printUrls()}}}const R={...d,base:t.base??"./",build:{outDir:t.outDir,emptyOutDir:!0,sourcemap:t.sourcemap??!1,minify:t.minify??"esbuild",rollupOptions:{input:{main:s.resolve(i,"index.html"),preview:s.resolve(i,"preview-frame.html")}}}},I=Date.now(),P=await h(R),T=Date.now()-I,{assetCount:O,totalBytes:j}=q(P);return{outDir:t.outDir,elapsedMs:T,assetCount:O,totalBytes:j}}function q(t){const e=z(t);if(e===void 0)return{assetCount:0,totalBytes:0};let o=0,n=0;for(const r of e)o+=1,n+=$(r);return{assetCount:o,totalBytes:n}}function y(t){return typeof t=="object"&&t!==null&&Array.isArray(t.output)}function z(t){if(Array.isArray(t)){const e=[];for(const o of t)y(o)&&e.push(...o.output);return e}if(y(t))return t.output}function $(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=V;exports.runHost=Y;
package/dist/index.js DELETED
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),j=require("react"),y=require("@jogak/core"),b=require("@jogak/react"),E=require("prism-react-renderer"),U=require("react-dom");function q(a){var e,t,r="";if(typeof a=="string"||typeof a=="number")r+=a;else if(typeof a=="object")if(Array.isArray(a)){var g=a.length;for(e=0;e<g;e++)a[e]&&(t=q(a[e]))&&(r&&(r+=" "),r+=t)}else for(t in a)a[t]&&(r&&(r+=" "),r+=t);return r}function v(){for(var a,e,t=0,r="",g=arguments.length;t<g;t++)(a=arguments[t])&&(e=q(a))&&(r&&(r+=" "),r+=e);return r}function B({selectedEntryId:a,selectedJogakName:e,onSelect:t}){const[r,g]=j.useState(""),{metaTree:n,searchMeta:s}=b.useRegistryMeta(),l=r.trim().length>0?s(r):null;return o.jsxs("aside",{"data-testid":"sidebar",className:"jogak:flex jogak:flex-col jogak:h-full jogak:overflow-auto jogak:border-r jogak:border-[var(--jogak-color-border)]",children:[o.jsx("div",{className:"jogak:p-3 jogak:border-b jogak:border-[var(--jogak-color-border)]",children:o.jsx("input",{type:"search",placeholder:"Search components...",value:r,onChange:k=>{g(k.target.value)},className:"jogak:w-full jogak:px-2 jogak:py-1.5 jogak:border jogak:border-[var(--jogak-color-border-strong)] jogak:rounded-[var(--jogak-radius-md)]","aria-label":"Search components"})}),o.jsx("nav",{className:"jogak:flex-1 jogak:overflow-auto jogak:py-2",children:l!==null?o.jsx(Q,{metas:l,selectedEntryId:a,selectedJogakName:e,onSelect:t}):o.jsx(V,{node:n,selectedEntryId:a,selectedJogakName:e,onSelect:t})})]})}function Q({metas:a,selectedEntryId:e,selectedJogakName:t,onSelect:r}){return a.length===0?o.jsx("p",{className:"jogak:px-3 jogak:text-[var(--jogak-color-fg-subtle)] jogak:text-[13px]",children:"No results"}):o.jsx("ul",{className:"jogak:list-none jogak:m-0 jogak:p-0",children:a.map(g=>o.jsx("li",{children:o.jsx(W,{meta:g,selectedEntryId:e,selectedJogakName:t,onSelect:r,indent:0})},g.id))})}function V({node:a,selectedEntryId:e,selectedJogakName:t,onSelect:r,depth:g=0}){return o.jsx("ul",{className:"jogak:list-none jogak:m-0 jogak:pr-0 jogak:py-0 jogak:pl-[var(--jogak-tree-pl)]",style:{"--jogak-tree-pl":`${g*12}px`},children:Object.entries(a).map(([n,s])=>o.jsx("li",{children:"id"in s?o.jsx(W,{meta:s,selectedEntryId:e,selectedJogakName:t,onSelect:r,indent:0}):o.jsx(X,{label:n,node:s,selectedEntryId:e,selectedJogakName:t,onSelect:r,depth:g+1})},n))})}function X({label:a,node:e,selectedEntryId:t,selectedJogakName:r,onSelect:g,depth:n}){const[s,l]=j.useState(!0);return o.jsxs("div",{children:[o.jsxs("button",{type:"button",onClick:()=>{l(k=>!k)},className:"jogak:flex jogak:items-center jogak:gap-1 jogak:w-full jogak:px-3 jogak:py-1 jogak:bg-transparent jogak:border-none jogak:cursor-pointer jogak:text-[12px] jogak:font-semibold jogak:text-[var(--jogak-color-fg-muted)] jogak:uppercase jogak:tracking-wider","aria-expanded":s,children:[o.jsx("span",{children:s?"▾":"▸"}),a]}),s&&o.jsx(V,{node:e,selectedEntryId:t,selectedJogakName:r,onSelect:g,depth:n})]})}function W({meta:a,selectedEntryId:e,selectedJogakName:t,onSelect:r,indent:g}){const n=a.id===e,[s,l]=j.useState(n);j.useEffect(()=>{n&&l(!0)},[n]);const k=a.title.split("/").pop()??a.title,i=16+g*12;return o.jsxs("div",{children:[o.jsxs("button",{type:"button",onClick:()=>{if(n)l(c=>!c);else{l(!0);const c=a.jogakNames[0];c!==void 0&&r(a.id,c)}},className:v("jogak:flex jogak:items-center jogak:gap-1.5 jogak:w-full jogak:pr-3 jogak:py-[5px]","jogak:pl-[var(--jogak-entry-pl)]","jogak:border-none jogak:cursor-pointer jogak:text-left jogak:text-[13px]",n?"jogak:bg-[var(--jogak-color-accent-bg)] jogak:text-[var(--jogak-color-accent)] jogak:font-medium":"jogak:bg-transparent jogak:text-[var(--jogak-color-fg)] jogak:font-normal"),style:{"--jogak-entry-pl":`${i}px`},"aria-expanded":s,children:[o.jsx("span",{className:"jogak:text-[10px] jogak:shrink-0 jogak:leading-none",children:s?"▾":"▸"}),k]}),s&&o.jsx("ul",{className:"jogak:list-none jogak:m-0 jogak:p-0",children:a.jogakNames.map(c=>{const x=n&&c===t;return o.jsx("li",{children:o.jsx("button",{type:"button",onClick:()=>{r(a.id,c)},className:v("jogak:block jogak:w-full jogak:text-left jogak:pr-3 jogak:py-1","jogak:pl-[var(--jogak-jogak-pl)]","jogak:border-none jogak:cursor-pointer jogak:text-[12px]",x?"jogak:bg-[var(--jogak-color-accent-bg-soft)] jogak:text-[var(--jogak-color-accent-fg)] jogak:font-medium":"jogak:bg-transparent jogak:text-[var(--jogak-color-fg-muted)] jogak:font-normal"),style:{"--jogak-jogak-pl":`${i+18}px`},"aria-current":x?"true":void 0,children:c})},c)})})]})}function Y(a,e){const t=e==null?void 0:e.control,r=(e==null?void 0:e.action)!==void 0&&e.action!==!1,g=(e==null?void 0:e.type)==="function"||typeof a=="function";return r||g?"action":t==="boolean"||typeof a=="boolean"?"boolean":t==="number"||t==="range"||typeof a=="number"?"number":t==="select"||t==="radio"||(e==null?void 0:e.options)!==void 0&&e.options.length>0?"select":t==="text"||t==="color"||typeof a=="string"?"text":"json"}const C="jogak:px-2 jogak:py-1 jogak:border jogak:border-[var(--jogak-color-border-strong)] jogak:rounded-[var(--jogak-radius-md)] jogak:text-[13px] jogak:w-full jogak:max-w-[280px]",R="jogak:px-5 jogak:py-1.5 jogak:text-left jogak:text-[var(--jogak-color-fg-muted)] jogak:font-medium jogak:text-[12px] jogak:border-b jogak:border-[var(--jogak-color-border)]",A="jogak:px-5 jogak:py-2 jogak:align-middle jogak:border-b jogak:border-[var(--jogak-color-border-muted)]";function Z({argKey:a,value:e,argType:t,onArgChange:r}){switch(Y(e,t)){case"boolean":return o.jsx("input",{type:"checkbox",checked:e===!0,onChange:n=>{r(a,n.target.checked)},className:"jogak:cursor-pointer jogak:w-4 jogak:h-4 jogak:accent-[var(--jogak-color-accent)]"});case"number":return o.jsx("input",{type:"number",value:typeof e=="number"?e:"",onChange:n=>{r(a,n.target.valueAsNumber)},className:C});case"select":{const n=(t==null?void 0:t.options)??[];return o.jsx("select",{value:String(e??""),onChange:s=>{r(a,s.target.value)},className:C,children:n.map(s=>o.jsx("option",{value:String(s),children:String(s)},String(s)))})}case"text":return o.jsx("input",{type:"text",value:typeof e=="string"?e:String(e??""),onChange:n=>{r(a,n.target.value)},className:C});case"action":return o.jsx("span",{className:"jogak:inline-block jogak:px-2 jogak:py-0.5 jogak:text-[11px] jogak:font-semibold jogak:text-[var(--jogak-color-violet)] jogak:bg-[var(--jogak-color-violet-bg)] jogak:border jogak:border-[var(--jogak-color-violet-border)] jogak:rounded-[var(--jogak-radius-md)] jogak:font-[family-name:var(--jogak-font-mono)] jogak:leading-none",children:"(action)"});case"json":return o.jsx("code",{className:"jogak:text-[12px] jogak:text-[var(--jogak-color-fg-muted)] jogak:font-[family-name:var(--jogak-font-mono)]",children:JSON.stringify(e)})}}function z({args:a,argTypes:e,onArgChange:t}){const g=Array.from(new Set([...Object.keys(a),...Object.keys(e)])).map(n=>[n,a[n]]);return o.jsxs("div",{className:"jogak:border-t-2 jogak:border-[var(--jogak-color-border)]",children:[o.jsx("div",{className:"jogak:px-5 jogak:py-1.5 jogak:text-[11px] jogak:font-bold jogak:text-[var(--jogak-color-fg-subtle)] jogak:uppercase jogak:tracking-[0.08em] jogak:border-b jogak:border-[var(--jogak-color-border)] jogak:bg-[var(--jogak-color-bg-subtle)]",children:"Controls"}),g.length===0?o.jsx("div",{className:"jogak:px-5 jogak:py-3 jogak:text-[var(--jogak-color-fg-subtle)] jogak:text-[13px]",children:"No args defined"}):o.jsxs("table",{className:"jogak:w-full jogak:border-collapse jogak:text-[13px]",children:[o.jsx("thead",{children:o.jsxs("tr",{children:[o.jsx("th",{className:R,children:"Name"}),o.jsx("th",{className:R,children:"Control"}),o.jsx("th",{className:R,children:"Description"})]})}),o.jsx("tbody",{children:g.map(([n,s])=>{const l=e[n];return o.jsxs("tr",{children:[o.jsx("td",{className:v(A,"jogak:font-[family-name:var(--jogak-font-mono)] jogak:text-[12px] jogak:text-[var(--jogak-color-fg)] jogak:whitespace-nowrap"),children:n}),o.jsx("td",{className:A,children:o.jsx(Z,{argKey:n,value:s,argType:l,onArgChange:t})}),o.jsx("td",{className:v(A,"jogak:text-[var(--jogak-color-fg-subtle)]"),children:(l==null?void 0:l.description)??""})]},n)})})]})]})}function K(a){if(a.length===0)return"()";try{return a.map(e=>{var t;if(e===null)return"null";if(e===void 0)return"undefined";if(typeof e=="function")return"[Function]";if(typeof e=="object"){const r=((t=e.constructor)==null?void 0:t.name)??"Object";return r!=="Object"&&r!=="Array"?`[${r}]`:JSON.stringify(e)}return JSON.stringify(e)}).join(", ")}catch{return"[unserializable]"}}function T(a){const e=new Date(a),t=e.getHours().toString().padStart(2,"0"),r=e.getMinutes().toString().padStart(2,"0"),g=e.getSeconds().toString().padStart(2,"0"),n=e.getMilliseconds().toString().padStart(3,"0");return`${t}:${r}:${g}.${n}`}function D(){const[a,e]=j.useState(()=>y.defaultActionChannel.getLogs());j.useEffect(()=>y.defaultActionChannel.subscribe(e),[]);const t=a.length===0;return o.jsxs("div",{className:"jogak:h-full jogak:flex jogak:flex-col",children:[o.jsxs("div",{className:"jogak:px-5 jogak:py-1.5 jogak:text-[11px] jogak:font-bold jogak:text-[var(--jogak-color-fg-subtle)] jogak:uppercase jogak:tracking-[0.08em] jogak:border-b jogak:border-[var(--jogak-color-border)] jogak:bg-[var(--jogak-color-bg-subtle)] jogak:flex jogak:items-center jogak:justify-between jogak:shrink-0",children:[o.jsxs("span",{children:["Actions ",a.length>0&&`(${a.length.toString()})`]}),o.jsx("button",{type:"button",onClick:()=>{y.defaultActionChannel.clear()},disabled:t,className:v("jogak:text-[10px] jogak:font-semibold jogak:px-2 jogak:py-0.5 jogak:border jogak:border-[var(--jogak-color-border-strong)] jogak:rounded-[var(--jogak-radius-sm)] jogak:bg-[var(--jogak-color-bg)] jogak:normal-case jogak:tracking-normal",t?"jogak:text-[var(--jogak-color-fg-subtle)] jogak:cursor-default":"jogak:text-[var(--jogak-color-fg)] jogak:cursor-pointer"),children:"Clear"})]}),o.jsx("div",{className:"jogak:flex-1 jogak:overflow-auto",children:t?o.jsx("div",{className:"jogak:px-5 jogak:py-3 jogak:text-[var(--jogak-color-fg-subtle)] jogak:text-[13px] jogak:leading-none",children:"함수 prop이 호출되면 여기에 기록됩니다"}):o.jsx("ul",{className:"jogak:list-none jogak:m-0 jogak:p-0 jogak:font-[family-name:var(--jogak-font-mono)] jogak:text-[12px]",children:a.map(r=>o.jsxs("li",{className:"jogak:flex jogak:items-baseline jogak:gap-[10px] jogak:px-5 jogak:py-1.5 jogak:border-b jogak:border-[var(--jogak-color-border-muted)]",children:[o.jsx("span",{className:"jogak:text-[var(--jogak-color-fg-subtle)] jogak:text-[11px] jogak:min-w-[92px]",children:T(r.timestamp)}),o.jsx("span",{className:"jogak:text-[var(--jogak-color-violet)] jogak:font-semibold",children:r.name}),o.jsxs("span",{className:"jogak:text-[var(--jogak-color-fg)] jogak:break-all jogak:flex-1",children:["(",K(r.args),")"]})]},r.id))})})]})}function oo({children:a,className:e,style:t,"data-testid":r}){const g=j.useRef(null),[n,s]=j.useState(null);return j.useEffect(()=>{const l=g.current;if(l===null)return;const k=l.shadowRoot??l.attachShadow({mode:"open"});s(k)},[]),o.jsx("div",{ref:g,className:e,"data-testid":r,style:t,children:n!==null?U.createPortal(a,n):null})}function ao({entry:a,args:e,userViteUrl:t,className:r,"data-testid":g}){const n=j.useRef(null),[s,l]=j.useState(!1),k=t!==""?`${t}/__jogak_preview__/index.html`:"/preview-frame.html";return j.useEffect(()=>{const i=c=>{const x=n.current;if(x===null||c.source!==x.contentWindow)return;const p=c.data;p==null||typeof p!="object"||p.type==="jogak:ready"&&l(!0)};return window.addEventListener("message",i),()=>{window.removeEventListener("message",i)}},[]),j.useEffect(()=>{var c;if(!s)return;const i=n.current;i!==null&&((c=i.contentWindow)==null||c.postMessage({type:"jogak:setProps",entryId:a.id,args:e},"*"))},[s,a,e]),j.useEffect(()=>{const i=n.current;return()=>{i!==null&&queueMicrotask(()=>{var c;(c=i.contentWindow)==null||c.postMessage({type:"jogak:unmount"},"*")})}},[]),o.jsx("iframe",{ref:n,src:k,title:"Preview",className:r,"data-testid":g})}const F={mobile:375,tablet:768,desktop:"none"},eo={mobile:"Mobile",tablet:"Tablet",desktop:"Desktop"},M={white:{"--jogak-canvas-bg":"#ffffff","--jogak-canvas-bg-image":"none","--jogak-canvas-bg-size":"auto","--jogak-canvas-bg-position":"0 0"},dark:{"--jogak-canvas-bg":"#1f2937","--jogak-canvas-bg-image":"none","--jogak-canvas-bg-size":"auto","--jogak-canvas-bg-position":"0 0"},transparent:{"--jogak-canvas-bg":"#ffffff","--jogak-canvas-bg-image":"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%)","--jogak-canvas-bg-size":"16px 16px","--jogak-canvas-bg-position":"0 0, 0 8px, 8px -8px, -8px 0px"}},$="jogak:bg-[var(--jogak-canvas-bg)] jogak:bg-[image:var(--jogak-canvas-bg-image)] jogak:bg-[length:var(--jogak-canvas-bg-size)] jogak:bg-[position:var(--jogak-canvas-bg-position)]";function to(a){return E.themes[a]??E.themes.vsDark}function H({entryId:a,jogakName:e,overrideArgs:t,onArgChange:r,onReset:g,codeTheme:n,onResolveJogak:s,previewIsolation:l="iframe",userViteUrl:k=""}){const i=b.useEntry(a),[c,x]=j.useState("desktop"),[p,w]=j.useState("white"),[S,m]=j.useState("controls"),h=to(n);return i.status==="unknown"?o.jsxs("div",{"data-testid":"preview-not-found",className:"jogak:p-6 jogak:text-[var(--jogak-color-error)]",children:["Entry not found: ",a]}):i.status==="error"?o.jsxs("div",{"data-testid":"preview-error",className:"jogak:p-6 jogak:text-[var(--jogak-color-error-fg)] jogak:bg-[var(--jogak-color-bg-error)] jogak:h-full jogak:flex jogak:flex-col jogak:gap-3 jogak:items-start",children:[o.jsxs("div",{className:"jogak:font-semibold",children:["Failed to load entry: ",a]}),o.jsx("pre",{className:"jogak:m-0 jogak:p-3 jogak:bg-[var(--jogak-color-bg)] jogak:border jogak:border-[var(--jogak-color-error-border)] jogak:rounded-[var(--jogak-radius-lg)] jogak:text-[12px] jogak:whitespace-pre-wrap jogak:max-w-full",children:i.error.message})]}):i.status==="loading"?o.jsx(ro,{meta:i.meta,jogakName:e,viewport:c,bgMode:p,onViewportChange:x,onBgModeChange:w}):o.jsx(no,{entry:i.entry,jogakName:e,overrideArgs:t,onArgChange:r,onReset:g,onResolveJogak:s,viewport:c,bgMode:p,bottomTab:S,onViewportChange:x,onBgModeChange:w,onBottomTabChange:m,prismTheme:h,previewIsolation:l,userViteUrl:k})}function ro({meta:a,jogakName:e,viewport:t,bgMode:r,onViewportChange:g,onBgModeChange:n}){const s=e??a.jogakNames[0]??"...",l=F[t];return o.jsxs("div",{"data-testid":"preview-loading",className:"jogak:flex jogak:flex-col jogak:h-full",children:[o.jsx(G,{title:a.title,jogakName:s,viewport:t,bgMode:r,onViewportChange:g,onBgModeChange:n,showReset:!1,onReset:()=>{}}),o.jsx("div",{className:`jogak:flex-1 jogak:overflow-auto jogak:min-h-[320px] ${$}`,style:M[r],children:o.jsx("div",{className:"jogak:mx-auto jogak:p-6 jogak:max-w-[var(--jogak-canvas-mw)]",style:{"--jogak-canvas-mw":l==="none"?"100%":`${l}px`},children:o.jsxs("div",{className:"jogak-skeleton-shimmer jogak:border jogak:border-dashed jogak:border-[var(--jogak-color-border)] jogak:rounded-[var(--jogak-radius-xl)] jogak:p-4 jogak:flex jogak:items-center jogak:justify-center jogak:text-[var(--jogak-color-fg-subtle)] jogak:text-[13px] jogak:min-h-[256px]",children:["Loading ",a.title,"…"]})})})]})}function no({entry:a,jogakName:e,overrideArgs:t,onArgChange:r,onReset:g,onResolveJogak:n,viewport:s,bgMode:l,bottomTab:k,onViewportChange:i,onBgModeChange:c,onBottomTabChange:x,prismTheme:p,previewIsolation:w,userViteUrl:S}){var L;const m=e??((L=a.jogaks[0])==null?void 0:L.name)??null;if(j.useEffect(()=>{e===null&&m!==null&&n!==void 0&&n(a.id,m)},[e,m,a.id,n]),m===null)return o.jsxs("div",{className:"jogak:p-6 jogak:text-[var(--jogak-color-error)]",children:["Entry has no jogaks: ",a.id]});const h=a.jogaks.find(N=>N.name===m);if(h===void 0)return o.jsxs("div",{className:"jogak:p-6 jogak:text-[var(--jogak-color-error)]",children:["Jogak not found: ",m]});const u={...h.args??{},...t},f={...a.meta.argTypes??{},...h.argTypes??{}},I=Object.keys(t).length>0,O=F[s];return o.jsxs("div",{className:"jogak:flex jogak:flex-col jogak:h-full",children:[o.jsx(G,{title:a.title,jogakName:h.name,viewport:s,bgMode:l,onViewportChange:i,onBgModeChange:c,showReset:I,onReset:g}),o.jsx("div",{className:`jogak:flex-1 jogak:overflow-auto jogak:min-h-[320px] ${$}`,style:M[l],children:o.jsx("div",{"data-jogak-content":!0,className:"jogak:mx-auto jogak:p-6 jogak:max-w-[var(--jogak-canvas-mw)]",style:{"--jogak-canvas-mw":O==="none"?"100%":`${O}px`},children:o.jsx(so,{entry:a,args:u,source:a.source,theme:p,previewIsolation:w,userViteUrl:S},`${a.id}/${h.name}`)})}),o.jsxs("div",{"data-testid":"bottom-panel",className:"jogak:h-[260px] jogak:shrink-0 jogak:flex jogak:flex-col jogak:border-t-2 jogak:border-[var(--jogak-color-border)]",children:[o.jsx("div",{role:"tablist",className:"jogak:flex jogak:gap-1 jogak:pt-1 jogak:px-3 jogak:pb-0 jogak:bg-[var(--jogak-color-bg)] jogak:border-b jogak:border-[var(--jogak-color-border)] jogak:shrink-0",children:["controls","actions"].map(N=>{const P=k===N;return o.jsx("button",{type:"button",role:"tab","aria-selected":P,onClick:()=>{x(N)},className:v("jogak:px-[14px] jogak:py-[6px] jogak:text-[12px] jogak:bg-transparent jogak:border-x-0 jogak:border-t-0 jogak:border-b-2 jogak:border-solid jogak:-mb-px jogak:cursor-pointer jogak:capitalize",P?"jogak:font-semibold jogak:text-[var(--jogak-color-fg-strong)] jogak:border-[var(--jogak-color-accent)]":"jogak:font-medium jogak:text-[var(--jogak-color-fg-muted)] jogak:border-transparent"),children:N},N)})}),o.jsx("div",{className:"jogak:flex-1 jogak:min-h-0 jogak:overflow-auto",children:k==="controls"?o.jsx(z,{args:u,argTypes:f,onArgChange:r}):o.jsx(D,{})})]})]})}function G({title:a,jogakName:e,viewport:t,bgMode:r,onViewportChange:g,onBgModeChange:n,showReset:s,onReset:l}){return o.jsxs("div",{className:"jogak:flex jogak:items-center jogak:gap-[10px] jogak:px-[14px] jogak:py-[7px] jogak:border-b jogak:border-[var(--jogak-color-border)] jogak:bg-[var(--jogak-color-bg)] jogak:shrink-0",children:[o.jsxs("div",{className:"jogak:flex-1 jogak:text-[13px]",children:[o.jsx("span",{className:"jogak:text-[var(--jogak-color-fg-subtle)]",children:a}),o.jsx("span",{className:"jogak:text-[var(--jogak-color-border-strong)] jogak:mx-1.5 jogak:leading-none",children:"/"}),o.jsx("span",{className:"jogak:text-[var(--jogak-color-fg-strong)] jogak:font-semibold",children:e})]}),o.jsx("div",{className:"jogak:flex jogak:gap-0.5 jogak:bg-[var(--jogak-color-bg-subtle)] jogak:rounded-[var(--jogak-radius-lg)] jogak:p-0.5",children:["mobile","tablet","desktop"].map(k=>o.jsx("button",{type:"button",onClick:()=>{g(k)},"aria-pressed":t===k,className:v("jogak:px-[9px] jogak:py-[3px] jogak:text-[12px] jogak:border-none jogak:rounded-[var(--jogak-radius-md)] jogak:cursor-pointer jogak:transition-all jogak:duration-100",t===k?"jogak:bg-[var(--jogak-color-bg-elevated)] jogak:text-[var(--jogak-color-fg-strong)] jogak:font-semibold jogak:shadow-[0_1px_2px_rgba(0,0,0,0.08)]":"jogak:bg-transparent jogak:text-[var(--jogak-color-fg-muted)] jogak:font-normal jogak:shadow-none"),children:eo[k]},k))}),o.jsx("div",{className:"jogak:flex jogak:gap-1 jogak:items-center",children:["white","dark","transparent"].map(k=>o.jsx("button",{type:"button",onClick:()=>{n(k)},"aria-pressed":r===k,"aria-label":`${k} background`,className:v("jogak:w-5 jogak:h-5 jogak:rounded-[var(--jogak-radius-md)] jogak:border-2 jogak:cursor-pointer jogak:p-0 jogak:shrink-0",$,r===k?"jogak:border-[var(--jogak-color-accent)]":"jogak:border-[var(--jogak-color-border-strong)]"),style:M[k]},k))}),s&&o.jsx("button",{type:"button",onClick:l,className:"jogak:px-[10px] jogak:py-[3px] jogak:text-[12px] jogak:border jogak:border-[var(--jogak-color-border-strong)] jogak:rounded-[var(--jogak-radius-md)] jogak:bg-[var(--jogak-color-bg)] jogak:cursor-pointer jogak:text-[var(--jogak-color-fg)] jogak:leading-none",children:"Reset"})]})}function so({entry:a,args:e,source:t,theme:r,previewIsolation:g,userViteUrl:n}){const[s,l]=j.useState(!1),k=o.jsxs("div",{className:"jogak:relative",children:[o.jsx(go,{entry:a,args:e,previewIsolation:g,userViteUrl:n}),o.jsx("button",{type:"button",onClick:()=>{l(i=>!i)},"aria-pressed":s,"aria-label":s?"Hide source code":"Show source code",className:v("jogak:absolute jogak:bottom-2 jogak:right-2 jogak:px-[9px] jogak:py-1","jogak:text-[11px] jogak:font-[family-name:var(--jogak-font-mono)] jogak:font-semibold jogak:tracking-[0.02em]","jogak:text-[var(--jogak-color-bg)] jogak:border-none jogak:rounded-[5px] jogak:cursor-pointer","jogak:shadow-[0_1px_4px_rgba(0,0,0,0.2)] jogak:transition-[background-color] jogak:duration-150 jogak:leading-none",s?"jogak:bg-[var(--jogak-color-accent)]":"jogak:bg-[#1e293b]"),children:"</>"})]});return o.jsxs("div",{children:[k,s&&o.jsx("div",{className:"jogak:mt-2 jogak:rounded-[var(--jogak-radius-xl)] jogak:overflow-hidden jogak:h-[320px] jogak:shadow-[0_0_0_1px_rgba(0,0,0,0.08),_0_4px_16px_rgba(0,0,0,0.12)]",children:o.jsx(ko,{source:t,theme:r})})]})}const _="jogak:border jogak:border-dashed jogak:border-[var(--jogak-color-border)] jogak:rounded-[var(--jogak-radius-xl)] jogak:p-4 jogak:pb-9";function go({entry:a,args:e,previewIsolation:t,userViteUrl:r}){return t==="shadow"?o.jsx(oo,{"data-testid":"preview-content",className:_,children:o.jsx(lo,{entry:a,args:e})}):t==="iframe"?o.jsx(ao,{entry:a,args:e,userViteUrl:r,"data-testid":"preview-content",className:`${_} jogak:block jogak:w-full jogak:bg-transparent jogak:min-h-[256px]`}):o.jsx(jo,{entry:a,args:e})}function jo({entry:a,args:e}){const t=j.useRef(null);return j.useEffect(()=>{const r=t.current;if(r!==null)return b.reactAdapter.render(a,e,r),()=>{queueMicrotask(()=>{b.reactAdapter.unmount(r)})}},[a]),j.useEffect(()=>{const r=t.current;r!==null&&b.reactAdapter.render(a,e,r)},[a,e]),o.jsx("div",{ref:t,"data-testid":"preview-content",className:_})}function lo({entry:a,args:e}){const t=j.useRef(null);return j.useEffect(()=>{const r=t.current;if(r!==null)return b.reactAdapter.render(a,e,r),()=>{queueMicrotask(()=>{b.reactAdapter.unmount(r)})}},[a]),j.useEffect(()=>{const r=t.current;r!==null&&b.reactAdapter.render(a,e,r)},[a,e]),o.jsx("div",{ref:t,"data-testid":"preview-content-shadow"})}function ko({source:a,theme:e}){const[t,r]=j.useState(!1),g=e.plain.backgroundColor??"#1e293b";if(a===void 0)return o.jsx("div",{className:"jogak:h-full jogak:flex jogak:items-center jogak:justify-center jogak:bg-[var(--jogak-source-bg)] jogak:text-[#94a3b8] jogak:text-[13px]",style:{"--jogak-source-bg":g},children:"Source not available"});const n=()=>{navigator.clipboard.writeText(a).then(()=>{r(!0),setTimeout(()=>{r(!1)},2e3)})};return o.jsxs("div",{className:"jogak:relative jogak:h-full",children:[o.jsx("button",{type:"button",onClick:n,className:"jogak:absolute jogak:top-[10px] jogak:right-3 jogak:z-[1] jogak:px-[9px] jogak:py-[3px] jogak:text-[11px] jogak:bg-[rgba(255,255,255,0.1)] jogak:text-[#e2e8f0] jogak:border jogak:border-[rgba(255,255,255,0.18)] jogak:rounded-[var(--jogak-radius-md)] jogak:cursor-pointer jogak:leading-none",children:t?"✓ Copied":"Copy"}),o.jsx(E.Highlight,{code:a.trim(),language:"tsx",theme:e,children:({style:s,tokens:l,getLineProps:k,getTokenProps:i})=>o.jsx("pre",{className:"jogak:m-0 jogak:py-3 jogak:px-0 jogak:text-[12.5px] jogak:leading-[1.7] jogak:font-[family-name:var(--jogak-font-mono)] jogak:h-full jogak:box-border jogak:overflow-auto",style:s,children:l.map((c,x)=>o.jsxs("div",{...k({line:c}),className:"jogak:flex jogak:pr-6",style:k({line:c}).style,children:[o.jsx("span",{className:"jogak:select-none jogak:min-w-10 jogak:pl-[14px] jogak:pr-[14px] jogak:text-right jogak:text-[rgba(148,163,184,0.45)] jogak:shrink-0 jogak:leading-[1.7]",children:x+1}),o.jsx("span",{children:c.map((p,w)=>o.jsx("span",{...i({token:p})},w))})]},x))})})]})}function J(){if(typeof window>"u")return null;const a=new URLSearchParams(window.location.search),e=a.get("entry");if(e===null)return null;const t=a.get("jogak");return{entryId:e,jogakName:t}}function co(a,e){const t=new URLSearchParams;t.set("entry",a),t.set("jogak",e),window.history.pushState({},"",`?${t.toString()}`)}function io({entries:a,metas:e,codeTheme:t="vsDark",previewIsolation:r="iframe",userViteUrl:g=""}={}){const n=j.useMemo(()=>{if(a!==void 0){e!==void 0&&console.warn("[jogak] JogakApp received both `entries` and `metas` — `entries` (eager) takes precedence.");const d=new y.ComponentRegistry;for(const u of a)d.register(u);return d}if(e!==void 0)for(const d of e)y.defaultRegistry.registerMeta(d);return y.defaultRegistry},[a,e]),s=j.useMemo(()=>J(),[]),[l,k]=j.useState((s==null?void 0:s.entryId)??null),[i,c]=j.useState((s==null?void 0:s.jogakName)??null),[x,p]=j.useState({});j.useEffect(()=>{const d=()=>{const u=J();u!==null?(k(u.entryId),c(u.jogakName),p({})):(k(null),c(null))};return window.addEventListener("popstate",d),()=>{window.removeEventListener("popstate",d)}},[]);const w=j.useCallback((d,u)=>{k(d),c(u),p({}),co(d,u)},[]),S=j.useCallback((d,u)=>{if(k(f=>f===d?d:f),c(f=>f??u),typeof window<"u"){const f=new URLSearchParams(window.location.search);f.get("entry")===d&&f.get("jogak")===null&&(f.set("jogak",u),window.history.replaceState({},"",`?${f.toString()}`))}},[]),m=j.useCallback((d,u)=>{p(f=>({...f,[d]:u}))},[]),h=j.useCallback(()=>{p({})},[]);return o.jsx(b.JogakProvider,{registry:n,children:o.jsxs("div",{"data-jogak-shell":!0,className:"jogak:grid jogak:grid-cols-[260px_1fr] jogak:h-dvh jogak:overflow-hidden",children:[o.jsx(B,{selectedEntryId:l,selectedJogakName:i,onSelect:w}),o.jsx("main",{className:"jogak:overflow-hidden jogak:min-h-0",children:l!==null?o.jsx(H,{entryId:l,jogakName:i,overrideArgs:x,onArgChange:m,onReset:h,codeTheme:t,onResolveJogak:S,previewIsolation:r,userViteUrl:g}):o.jsx("div",{className:"jogak:flex jogak:items-center jogak:justify-center jogak:h-full jogak:text-[var(--jogak-color-fg-subtle)]",children:"Select a component from the sidebar"})})]})})}function uo(){const a=b.useRegistry(),e=j.useMemo(()=>a.getAll(),[a]),t=j.useMemo(()=>a.getTree(),[a]),r=j.useMemo(()=>g=>a.search(g),[a]);return{entries:e,tree:t,search:r}}exports.Actions=D;exports.Controls=z;exports.JogakApp=io;exports.Preview=H;exports.Sidebar=B;exports.useRegistry=uo;