@kekonic/diagrams-element 1.0.0-rc.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/LICENSE +21 -0
- package/README.md +94 -0
- package/dist/index.d.mts +129 -0
- package/dist/index.mjs +1097 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["#isFullscreen","#controller","#animList","#animState","#revealControls","#scheduleControlsHide","#onAnimKeydown","#syncHostHeight","#onFullscreenChange","#watchAutoTheme","#mountController","#themeObserver","#clearControlsIdleTimer","#destroyController","#ready","#applyTheme","#applySource","#syncAnimationHostPrefs","#error","#activeTheme","#appliedTheme","#stats","#emitRender","#animUnsub","#controlsIdleTimer","#controlsVisible","#mountGen","#viewport","#bindAnimations","#busy","#toggleFullscreen","#onStageKeydown","#onStagePointerDown","#onStagePointerActivity","#onStagePointerLeave","#onStageFocusIn","#onStageFocusOut","#icon","#toggleTheme"],"sources":["../src/k-diagram.ts","../src/index.ts"],"sourcesContent":["import { LitElement, html, svg, css, nothing, type PropertyValues, type TemplateResult } from \"lit\";\nimport type {\n AnimationListItem,\n AnimationPlayerState,\n InteractiveRenderOptions,\n RenderController,\n RenderStats,\n ThemeMode,\n} from \"@kekonic/diagrams\";\n\nconst boolFromAttribute = {\n fromAttribute: (value: string | null) => value !== \"false\",\n toAttribute: (value: boolean) => (value ? \"\" : \"false\"),\n};\n\nfunction readSiteTheme(): ThemeMode {\n if (typeof document === \"undefined\") return \"dark\";\n return document.documentElement.dataset.theme === \"light\" ? \"light\" : \"dark\";\n}\n\nfunction resolveTheme(theme: ThemeMode | \"auto\"): ThemeMode {\n if (theme === \"auto\") return readSiteTheme();\n return theme;\n}\n\nfunction formatMs(ms: number): string {\n return ms >= 100 ? `${Math.round(ms)}ms` : `${ms.toFixed(1)}ms`;\n}\n\nfunction cssHeight(height: string | number): string {\n return typeof height === \"number\" ? `${height}px` : height;\n}\n\nconst CONTROLS_IDLE_MS = 2_400;\nconst CONTROLS_LEAVE_MS = 400;\n\n/**\n * Interactive Kekonic Diagrams diagram as a Lit custom element.\n * Wraps `KDiagram.renderToElement` — pan/zoom, theme, live `source` updates.\n */\nexport class KDiagramElement extends LitElement {\n static override properties = {\n source: { type: String },\n theme: { type: String },\n height: {},\n frameless: {\n type: Boolean,\n converter: boolFromAttribute,\n reflect: true,\n },\n showThemeToggle: {\n type: Boolean,\n attribute: \"show-theme-toggle\",\n converter: boolFromAttribute,\n },\n showViewControls: {\n type: Boolean,\n attribute: \"show-view-controls\",\n converter: boolFromAttribute,\n },\n showStats: {\n type: Boolean,\n attribute: \"show-stats\",\n converter: boolFromAttribute,\n },\n showAnimationControls: {\n type: Boolean,\n attribute: \"animation-controls\",\n converter: boolFromAttribute,\n },\n autoplay: {\n type: Boolean,\n converter: boolFromAttribute,\n },\n animationLoop: {\n type: Boolean,\n attribute: \"loop\",\n converter: boolFromAttribute,\n },\n animation: { type: String },\n options: { attribute: false },\n };\n\n static override styles = css`\n :host {\n display: flex;\n flex-direction: column;\n position: relative;\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n min-height: 0;\n border: 1px solid var(--border, color-mix(in oklch, currentColor 18%, transparent));\n background: var(--bg-panel, var(--bg, transparent));\n color: var(--text, inherit);\n overflow: hidden;\n font-family: var(--font-ui, inherit);\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n :host(:fullscreen) {\n width: 100%;\n height: 100% !important;\n background: var(--bg, #0b0f14);\n border: 0;\n }\n\n :host([frameless]:not([frameless=\"false\"]):not(:fullscreen)) {\n border: 0;\n background: transparent;\n }\n\n :host([frameless]:not([frameless=\"false\"]):not(:fullscreen)) .viewport {\n background: transparent;\n }\n\n .sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n\n .error {\n margin: 0;\n padding: 0.55rem 0.75rem;\n border-bottom: 1px solid\n var(--border-soft, color-mix(in oklch, currentColor 12%, transparent));\n color: var(--danger, #f87171);\n font-size: 0.85rem;\n }\n\n .stage {\n position: relative;\n display: flex;\n flex-direction: column;\n flex: 1 1 0;\n min-height: 0;\n width: 100%;\n height: 100%;\n }\n\n .stage:focus {\n outline: none;\n }\n\n .viewport {\n position: relative;\n flex: 1 1 0;\n width: 100%;\n min-height: 0;\n background: var(--bg, transparent);\n z-index: 0;\n }\n\n .viewport .kdiagram-viewport,\n .viewport .kdiagram-canvas,\n .viewport svg {\n width: 100%;\n height: 100%;\n display: block;\n }\n\n .overlay {\n position: absolute;\n z-index: 2;\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n pointer-events: none;\n opacity: 1;\n transform: translateY(0);\n transition:\n opacity 180ms ease,\n transform 180ms ease;\n }\n\n .overlay > * {\n pointer-events: auto;\n }\n\n .stage[data-controls-visible=\"false\"] .overlay {\n opacity: 0;\n pointer-events: none;\n }\n\n .stage[data-controls-visible=\"false\"] .overlay > * {\n pointer-events: none;\n }\n\n .stage[data-controls-visible=\"false\"] .overlay--tools {\n transform: translateY(-4px);\n }\n\n .stage[data-controls-visible=\"false\"] .overlay--animation,\n .stage[data-controls-visible=\"false\"] .overlay--stats {\n transform: translateY(4px);\n }\n\n .overlay--tools {\n top: 0.55rem;\n right: 0.55rem;\n padding: 0.15rem;\n border: 1px solid var(--border-soft, color-mix(in oklch, currentColor 12%, transparent));\n background: color-mix(in oklch, var(--bg-elevated, var(--bg, #111)) 92%, transparent);\n }\n\n .overlay--stats {\n left: 0.55rem;\n bottom: 0.55rem;\n padding: 0.2rem 0.45rem;\n border: 1px solid var(--border-soft, color-mix(in oklch, currentColor 12%, transparent));\n background: color-mix(in oklch, var(--bg-elevated, var(--bg, #111)) 88%, transparent);\n color: var(--text-muted, color-mix(in oklch, currentColor 70%, transparent));\n font-size: 0.68rem;\n font-variant-numeric: tabular-nums;\n gap: 0.55rem;\n }\n\n .tools {\n display: inline-flex;\n gap: 0.25rem;\n }\n\n .icon-btn {\n appearance: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 1.85rem;\n height: 1.85rem;\n padding: 0;\n border: 1px solid transparent;\n background: transparent;\n color: var(--text-muted, color-mix(in oklch, currentColor 70%, transparent));\n cursor: pointer;\n flex: 0 0 auto;\n }\n\n .icon-btn:hover {\n color: var(--text, inherit);\n border-color: var(--border, color-mix(in oklch, currentColor 18%, transparent));\n background: color-mix(in oklch, var(--bg-elevated, currentColor) 8%, transparent);\n }\n\n .icon-btn:focus-visible {\n color: var(--text, inherit);\n outline: none;\n border-color: var(--accent, #5b9fd4);\n box-shadow: 0 0 0 1px color-mix(in oklch, var(--accent, #5b9fd4) 55%, transparent);\n }\n\n .icon-btn svg {\n width: 16px;\n height: 16px;\n display: block;\n flex: none;\n }\n\n .overlay--animation {\n left: 0.55rem;\n right: 0.55rem;\n bottom: 0.55rem;\n justify-content: center;\n }\n\n .anim-bar {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n max-width: min(44rem, 100%);\n padding: 0.3rem 0.45rem;\n border: 1px solid var(--border-soft, color-mix(in oklch, currentColor 12%, transparent));\n background: color-mix(in oklch, var(--bg-elevated, var(--bg, #111)) 92%, transparent);\n color: var(--text, inherit);\n font-size: 0.72rem;\n font-variant-numeric: tabular-nums;\n border-radius: 0;\n }\n\n .anim-select {\n position: relative;\n display: inline-flex;\n align-items: center;\n gap: 0.28rem;\n height: 1.85rem;\n min-width: 0;\n max-width: 12rem;\n padding: 0 1.25rem 0 0.4rem;\n border: 1px solid transparent;\n border-radius: 0;\n background: transparent;\n color: var(--text-muted, color-mix(in oklch, currentColor 78%, transparent));\n flex: 0 1 auto;\n box-sizing: border-box;\n }\n\n .anim-select--speed {\n max-width: 4.75rem;\n padding-left: 0.4rem;\n }\n\n .anim-select:hover {\n color: var(--text, inherit);\n border-color: var(--border, color-mix(in oklch, currentColor 18%, transparent));\n background: color-mix(in oklch, var(--bg-elevated, currentColor) 8%, transparent);\n }\n\n /* Keyboard focus only — mouse/open must not stack a second system ring. */\n .anim-select:has(select:focus-visible) {\n color: var(--text, inherit);\n border-color: var(--accent, #5b9fd4);\n background: color-mix(in oklch, var(--bg-elevated, currentColor) 8%, transparent);\n outline: none;\n box-shadow: 0 0 0 1px color-mix(in oklch, var(--accent, #5b9fd4) 55%, transparent);\n }\n\n .anim-select__glyph {\n display: inline-flex;\n flex: 0 0 auto;\n opacity: 0.8;\n pointer-events: none;\n color: inherit;\n }\n\n .anim-select__glyph svg {\n width: 14px;\n height: 14px;\n display: block;\n }\n\n .anim-select select {\n appearance: none;\n -webkit-appearance: none;\n -moz-appearance: none;\n border: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n font-size: inherit;\n line-height: 1.2;\n padding: 0;\n margin: 0;\n min-width: 0;\n max-width: 100%;\n flex: 1 1 auto;\n cursor: pointer;\n outline: none;\n box-shadow: none;\n }\n\n .anim-select select:focus,\n .anim-select select:focus-visible,\n .anim-select select:active {\n outline: none;\n outline-offset: 0;\n box-shadow: none;\n border: 0;\n }\n\n .anim-select select::-moz-focus-inner {\n border: 0;\n }\n\n .anim-select__caret {\n position: absolute;\n right: 0.3rem;\n top: 50%;\n transform: translateY(-50%);\n display: inline-flex;\n pointer-events: none;\n opacity: 0.75;\n color: inherit;\n }\n\n .anim-select__caret svg {\n width: 12px;\n height: 12px;\n display: block;\n }\n\n .anim-scrub {\n -webkit-appearance: none;\n appearance: none;\n width: min(14rem, 32vw);\n height: 1.85rem;\n margin: 0 0.25rem;\n background: transparent;\n cursor: pointer;\n flex: 1 1 auto;\n min-width: 6rem;\n border-radius: 0;\n }\n\n .anim-scrub:focus {\n outline: none;\n }\n\n .anim-scrub:focus-visible {\n box-shadow: 0 0 0 1px var(--accent, #5b9fd4);\n }\n\n .anim-scrub::-webkit-slider-runnable-track {\n height: 6px;\n border-radius: 0;\n background: color-mix(in oklch, var(--text, currentColor) 16%, transparent);\n }\n\n .anim-scrub::-webkit-slider-thumb {\n -webkit-appearance: none;\n appearance: none;\n width: 12px;\n height: 12px;\n margin-top: -3px;\n border-radius: 0;\n border: 2px solid var(--bg-elevated, var(--bg, #111));\n background: var(--accent, #a195f7);\n box-shadow: 0 0 0 1px color-mix(in oklch, var(--accent, #a195f7) 55%, transparent);\n }\n\n .anim-scrub::-moz-range-track {\n height: 6px;\n border-radius: 0;\n background: color-mix(in oklch, var(--text, currentColor) 16%, transparent);\n }\n\n .anim-scrub::-moz-range-thumb {\n width: 12px;\n height: 12px;\n border-radius: 0;\n border: 2px solid var(--bg-elevated, var(--bg, #111));\n background: var(--accent, #a195f7);\n box-shadow: 0 0 0 1px color-mix(in oklch, var(--accent, #a195f7) 55%, transparent);\n }\n\n .anim-time {\n color: var(--text-muted, color-mix(in oklch, currentColor 70%, transparent));\n min-width: 4.5rem;\n text-align: center;\n }\n\n .icon-btn.is-pressed,\n .icon-btn[aria-pressed=\"true\"] {\n color: var(--accent-contrast, #0b0f14);\n background: var(--accent, #a195f7);\n border-color: var(--accent, #a195f7);\n }\n\n .icon-btn.is-pressed:hover,\n .icon-btn[aria-pressed=\"true\"]:hover {\n color: var(--accent-contrast, #0b0f14);\n background: color-mix(in oklch, var(--accent, #a195f7) 85%, white);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .overlay {\n transition: none;\n }\n }\n `;\n\n source = \"\";\n theme: ThemeMode | \"auto\" = \"auto\";\n height: string | number = 420;\n /** Remove the host border and panel background for ambient or page-level compositions. */\n frameless = false;\n showThemeToggle = true;\n showViewControls = true;\n showStats = false;\n /** Animation chrome when an animation exists (auto or authored). Default on. */\n showAnimationControls = true;\n autoplay = false;\n animationLoop = false;\n /** Preferred authored animation name or id. */\n animation = \"\";\n options?: Omit<InteractiveRenderOptions, \"theme\">;\n\n #controller: RenderController | null = null;\n #mountGen = 0;\n #appliedTheme: ThemeMode | null = null;\n #themeObserver: MutationObserver | null = null;\n #activeTheme: ThemeMode = \"dark\";\n #ready = false;\n #busy = false;\n #error: string | null = null;\n #stats: RenderStats | null = null;\n #isFullscreen = false;\n #controlsVisible = true;\n #controlsIdleTimer: ReturnType<typeof setTimeout> | null = null;\n #animList: AnimationListItem[] = [];\n #animState: AnimationPlayerState = {\n id: null,\n playing: false,\n timeMs: 0,\n durationMs: 0,\n loop: false,\n speed: 1,\n };\n #animUnsub: (() => void) | null = null;\n #onFullscreenChange = () => {\n this.#isFullscreen = document.fullscreenElement != null && document.fullscreenElement === this;\n this.requestUpdate();\n requestAnimationFrame(() => {\n requestAnimationFrame(() => this.#controller?.fit());\n });\n };\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.#syncHostHeight();\n document.addEventListener(\"fullscreenchange\", this.#onFullscreenChange);\n this.#watchAutoTheme();\n // Remount after reconnect (firstUpdated only runs once).\n if (this.hasUpdated) void this.#mountController();\n }\n\n override disconnectedCallback(): void {\n document.removeEventListener(\"fullscreenchange\", this.#onFullscreenChange);\n this.#themeObserver?.disconnect();\n this.#themeObserver = null;\n this.#clearControlsIdleTimer();\n this.#destroyController();\n super.disconnectedCallback();\n }\n\n override firstUpdated(): void {\n this.#revealControls();\n void this.#mountController();\n }\n\n override updated(changed: PropertyValues): void {\n if (changed.has(\"height\")) {\n this.#syncHostHeight();\n if (this.#ready) requestAnimationFrame(() => this.#controller?.fit());\n }\n if (changed.has(\"theme\")) {\n this.#watchAutoTheme();\n void this.#applyTheme();\n }\n if ((changed.has(\"source\") || changed.has(\"options\")) && this.#ready) {\n void this.#applySource();\n }\n if (\n this.#ready &&\n (changed.has(\"autoplay\") ||\n changed.has(\"animationLoop\") ||\n changed.has(\"animation\") ||\n changed.has(\"showAnimationControls\"))\n ) {\n this.#syncAnimationHostPrefs();\n }\n }\n\n /** Height lives on the host so flex parents (playground) can fill the pane. */\n #syncHostHeight(): void {\n this.style.height = cssHeight(this.height);\n }\n\n /** Resolves when the first interactive render finishes. */\n async ready(): Promise<void> {\n await this.updateComplete;\n if (!this.#controller) await this.#mountController();\n if (!this.#controller) {\n throw new Error(this.#error ?? \"k-diagram failed to mount\");\n }\n await this.#controller.ready();\n }\n\n fit(): void {\n this.#controller?.fit();\n }\n\n zoomIn(): void {\n this.#controller?.zoomIn();\n }\n\n zoomOut(): void {\n this.#controller?.zoomOut();\n }\n\n resetView(): void {\n this.#controller?.resetView();\n }\n\n /** Interactive animation controller (auto path or authored blocks). */\n get animations() {\n return this.#controller?.animations;\n }\n\n /**\n * Re-apply the current theme name (picks up `registerTheme` token updates\n * even when the theme id is unchanged).\n */\n async refreshTheme(): Promise<void> {\n if (!this.#ready || !this.#controller) return;\n const next = resolveTheme(this.theme === \"auto\" ? \"auto\" : this.theme);\n this.#activeTheme = next;\n this.#appliedTheme = next;\n const result = await this.#controller.setTheme(next);\n this.#stats = result.stats;\n this.#emitRender(result);\n this.requestUpdate();\n requestAnimationFrame(() => this.#controller?.fit());\n }\n\n #emitRender(result: import(\"@kekonic/diagrams\").RenderResult): void {\n this.dispatchEvent(\n new CustomEvent(\"kdiagram-render\", {\n detail: result,\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n #bindAnimations(controller: RenderController): void {\n this.#animUnsub?.();\n this.#animList = controller.animations.list();\n let lastUiMs = 0;\n let lastSig = \"\";\n this.#animUnsub = controller.animations.subscribe((state) => {\n this.#animState = state;\n this.#animList = controller.animations.list();\n this.dispatchEvent(\n new CustomEvent(\"kdiagram-animation-timeupdate\", {\n detail: state,\n bubbles: true,\n composed: true,\n }),\n );\n const sig = `${state.id}|${state.playing}|${state.loop}|${state.speed}|${state.durationMs}`;\n const now = performance.now();\n // Always refresh on control-state changes; throttle scrubber text while playing.\n if (sig !== lastSig || !state.playing || now - lastUiMs > 50) {\n lastSig = sig;\n lastUiMs = now;\n this.requestUpdate();\n }\n });\n this.#syncAnimationHostPrefs();\n }\n\n #syncAnimationHostPrefs(): void {\n const anim = this.#controller?.animations;\n if (!anim) return;\n this.#animList = anim.list();\n if (this.animationLoop) anim.setLoop(true);\n const preferred = (this.animation ?? \"\").trim();\n if (preferred) {\n const match = this.#animList.find(\n (a) => a.id === preferred || a.name.toLowerCase() === preferred.toLowerCase(),\n );\n if (match && this.#animState.id !== match.id) {\n anim.play(match.id);\n if (!this.autoplay) anim.pause();\n this.dispatchEvent(\n new CustomEvent(\"kdiagram-animation-change\", {\n detail: { id: match.id },\n bubbles: true,\n composed: true,\n }),\n );\n }\n }\n if (this.autoplay && this.#animList.length > 0) {\n anim.play(this.#animState.id ?? this.#animList[0]!.id);\n }\n }\n\n #onAnimKeydown = (e: KeyboardEvent): void => {\n if (!this.showAnimationControls || this.#animList.length === 0) return;\n const anim = this.#controller?.animations;\n if (!anim) return;\n if (e.key === \" \" || e.code === \"Space\") {\n e.preventDefault();\n if (this.#animState.playing) anim.pause();\n else anim.play();\n } else if (e.key === \"ArrowRight\") {\n e.preventDefault();\n anim.step(1);\n } else if (e.key === \"ArrowLeft\") {\n e.preventDefault();\n anim.step(-1);\n }\n };\n\n #clearControlsIdleTimer(): void {\n if (this.#controlsIdleTimer == null) return;\n clearTimeout(this.#controlsIdleTimer);\n this.#controlsIdleTimer = null;\n }\n\n #scheduleControlsHide(delay = CONTROLS_IDLE_MS): void {\n this.#clearControlsIdleTimer();\n this.#controlsIdleTimer = setTimeout(() => {\n this.#controlsIdleTimer = null;\n const root = this.renderRoot;\n const focused = root instanceof ShadowRoot ? root.activeElement : null;\n if (focused instanceof Element && focused.closest(\".overlay\")) return;\n this.#controlsVisible = false;\n this.requestUpdate();\n }, delay);\n }\n\n #revealControls(persist = false): void {\n if (!this.#controlsVisible) {\n this.#controlsVisible = true;\n this.requestUpdate();\n }\n this.#clearControlsIdleTimer();\n if (!persist) this.#scheduleControlsHide();\n }\n\n #onStagePointerActivity = (): void => {\n this.#revealControls();\n };\n\n #onStagePointerLeave = (): void => {\n this.#scheduleControlsHide(CONTROLS_LEAVE_MS);\n };\n\n #onStageFocusIn = (event: FocusEvent): void => {\n // Keep chrome visible while a real control has focus. The stage itself is\n // focusable for keyboard playback, but should still become idle.\n this.#revealControls(event.target !== event.currentTarget);\n };\n\n #onStageFocusOut = (): void => {\n queueMicrotask(() => {\n const root = this.renderRoot;\n const focused = root instanceof ShadowRoot ? root.activeElement : null;\n if (focused instanceof Element && focused.closest(\".overlay\")) return;\n this.#scheduleControlsHide(CONTROLS_LEAVE_MS);\n });\n };\n\n #onStageKeydown = (event: KeyboardEvent): void => {\n this.#revealControls(event.target !== event.currentTarget);\n this.#onAnimKeydown(event);\n };\n\n /** Pan/zoom the canvas should release select/scrub focus like clicking the page backdrop. */\n #onStagePointerDown = (e: PointerEvent): void => {\n this.#revealControls();\n const onChrome = e\n .composedPath()\n .some(\n (n) =>\n n instanceof Element &&\n (n.classList.contains(\"overlay--animation\") ||\n n.classList.contains(\"overlay--tools\") ||\n n.classList.contains(\"overlay--stats\")),\n );\n if (onChrome) return;\n\n const root = this.renderRoot;\n const focused = root instanceof ShadowRoot ? root.activeElement : null;\n if (focused instanceof HTMLElement) focused.blur();\n\n const stage = e.currentTarget;\n if (stage instanceof HTMLElement) stage.focus({ preventScroll: true });\n };\n\n #watchAutoTheme(): void {\n this.#themeObserver?.disconnect();\n this.#themeObserver = null;\n if (this.theme === \"auto\") {\n this.#activeTheme = readSiteTheme();\n this.#themeObserver = new MutationObserver(() => {\n const next = readSiteTheme();\n if (next === this.#activeTheme) return;\n this.#activeTheme = next;\n void this.#applyTheme();\n this.requestUpdate();\n });\n this.#themeObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: [\"data-theme\"],\n });\n } else {\n this.#activeTheme = resolveTheme(this.theme);\n }\n }\n\n #viewport(): HTMLElement | null {\n return this.renderRoot.querySelector<HTMLElement>(\".viewport\");\n }\n\n #destroyController(): void {\n this.#animUnsub?.();\n this.#animUnsub = null;\n this.#animList = [];\n this.#mountGen += 1;\n this.#controller?.destroy();\n this.#controller = null;\n this.#ready = false;\n this.#appliedTheme = null;\n }\n\n async #mountController(): Promise<void> {\n const viewport = this.#viewport();\n if (!viewport || !this.isConnected) return;\n\n const gen = ++this.#mountGen;\n this.#animUnsub?.();\n this.#animUnsub = null;\n this.#controller?.destroy();\n this.#controller = null;\n this.#ready = false;\n this.#appliedTheme = null;\n\n try {\n const { KDiagram } = await import(\"@kekonic/diagrams\");\n try {\n await KDiagram.ensureFonts();\n } catch {\n // Font URLs may be unavailable in some test/SSR hosts; layout still runs.\n }\n if (gen !== this.#mountGen || !this.isConnected) return;\n\n const host = this.#viewport();\n if (!host) return;\n host.replaceChildren();\n\n const mountedSource = this.source;\n const theme = resolveTheme(this.theme === \"auto\" ? \"auto\" : this.theme);\n this.#activeTheme = theme;\n\n const controller = KDiagram.renderToElement(mountedSource, host, {\n ...this.options,\n theme,\n });\n if (gen !== this.#mountGen) {\n controller.destroy();\n return;\n }\n\n this.#controller = controller;\n const result = await controller.ready();\n if (gen !== this.#mountGen) return;\n\n this.#appliedTheme = theme;\n this.#stats = result.stats;\n this.#ready = true;\n this.#error = result.ok ? null : (result.diagnostics[0]?.message ?? \"Render failed\");\n this.#bindAnimations(controller);\n this.#emitRender(result);\n this.requestUpdate();\n requestAnimationFrame(() => controller.fit());\n } catch (err) {\n if (gen !== this.#mountGen) return;\n this.#error = err instanceof Error ? err.message : String(err);\n this.requestUpdate();\n }\n }\n\n async #applyTheme(): Promise<void> {\n if (!this.#ready || !this.#controller) return;\n const next = resolveTheme(this.theme === \"auto\" ? \"auto\" : this.theme);\n this.#activeTheme = next;\n if (this.#appliedTheme === next) {\n this.requestUpdate();\n return;\n }\n this.#appliedTheme = next;\n const result = await this.#controller.setTheme(next);\n this.#stats = result.stats;\n this.#emitRender(result);\n this.requestUpdate();\n requestAnimationFrame(() => this.#controller?.fit());\n }\n\n async #applySource(): Promise<void> {\n const controller = this.#controller;\n if (!this.#ready || !controller) return;\n this.#busy = true;\n this.requestUpdate();\n try {\n const result = await controller.update(this.source, this.options);\n this.#stats = result.stats;\n this.#error = result.ok ? null : (result.diagnostics[0]?.message ?? \"Update failed\");\n this.#animList = controller.animations.list();\n this.#syncAnimationHostPrefs();\n this.#emitRender(result);\n requestAnimationFrame(() => controller.fit());\n } catch (err) {\n this.#error = err instanceof Error ? err.message : String(err);\n } finally {\n this.#busy = false;\n this.requestUpdate();\n }\n }\n\n async #toggleFullscreen(): Promise<void> {\n try {\n if (document.fullscreenElement) {\n await document.exitFullscreen();\n } else {\n await this.requestFullscreen();\n }\n } catch {\n // Fullscreen may be blocked by the host page.\n }\n }\n\n #toggleTheme(): void {\n this.theme = this.#activeTheme === \"dark\" ? \"light\" : \"dark\";\n }\n\n #icon(paths: TemplateResult | TemplateResult[], size = 16): TemplateResult {\n return html`\n <svg\n width=${size}\n height=${size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.75\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n ${paths}\n </svg>\n `;\n }\n\n override render() {\n const panHint = this.#busy ? \"Updating…\" : \"Drag to pan / scroll to zoom\";\n const showTools = this.showThemeToggle || this.showViewControls;\n const showStatsBadge = this.showStats && this.#stats;\n const showAnim =\n this.showAnimationControls && this.#animList.length > 0 && this.#controller != null;\n const duration = Math.max(this.#animState.durationMs, 1);\n const timeLabel = `${formatAnimClock(this.#animState.timeMs)} / ${formatAnimClock(this.#animState.durationMs)}`;\n\n return html`\n <span class=\"sr-only\">Live diagram. ${panHint}.</span>\n ${this.#error ? html`<p class=\"error\" role=\"status\">${this.#error}</p>` : nothing}\n <div\n class=\"stage\"\n data-controls-visible=${String(this.#controlsVisible)}\n tabindex=\"0\"\n @keydown=${this.#onStageKeydown}\n @pointerdown=${this.#onStagePointerDown}\n @pointermove=${this.#onStagePointerActivity}\n @pointerenter=${this.#onStagePointerActivity}\n @pointerleave=${this.#onStagePointerLeave}\n @focusin=${this.#onStageFocusIn}\n @focusout=${this.#onStageFocusOut}\n >\n <div class=\"viewport\" data-theme=${this.#activeTheme}></div>\n ${showStatsBadge && this.#stats\n ? html`\n <div\n class=\"overlay overlay--stats\"\n aria-label=\"${this.#stats.layoutAlgorithm} / ${this.#stats.routerAlgorithm}\"\n >\n <span>${this.#stats.nodeCount}n</span>\n <span>${this.#stats.edgeCount}e</span>\n <span>${formatMs(this.#stats.totalMs)}</span>\n </div>\n `\n : nothing}\n ${showAnim\n ? html`\n <div\n class=\"overlay overlay--animation\"\n role=\"toolbar\"\n aria-label=\"Animation controls\"\n >\n <div class=\"anim-bar\">\n ${this.#animList.length > 1\n ? html`\n <label class=\"anim-select\">\n <span class=\"anim-select__glyph\" aria-hidden=\"true\">\n ${this.#icon(\n [\n svg`<path d=\"M20.2 6 3 11l-.9-2.4c-.3-1.1.3-2.2 1.3-2.5l13.5-4c1.1-.3 2.2.3 2.5 1.3Z\"></path>`,\n svg`<path d=\"m6.2 5.3 3.1 3.9\"></path>`,\n svg`<path d=\"m12.4 3.4 3.1 4\"></path>`,\n svg`<path d=\"M3 11h18v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2Z\"></path>`,\n ],\n 14,\n )}\n </span>\n <select\n aria-label=\"Animation\"\n @change=${(e: Event) => {\n const id = (e.target as HTMLSelectElement).value;\n this.#controller?.animations.play(id);\n this.dispatchEvent(\n new CustomEvent(\"kdiagram-animation-change\", {\n detail: { id },\n bubbles: true,\n composed: true,\n }),\n );\n }}\n >\n ${this.#animList.map(\n (a) => html`\n <option\n value=${a.id}\n ?selected=${a.id ===\n (this.#animState.id ?? this.#animList[0]?.id)}\n >\n ${a.name}\n </option>\n `,\n )}\n </select>\n <span class=\"anim-select__caret\" aria-hidden=\"true\">\n ${this.#icon(svg`<path d=\"M6 9l6 6 6-6\"></path>`, 12)}\n </span>\n </label>\n `\n : nothing}\n <button\n type=\"button\"\n class=\"icon-btn\"\n aria-label=\"Previous step\"\n @click=${() => this.#controller?.animations.step(-1)}\n >\n ${this.#icon(svg`<path d=\"M15 18l-6-6 6-6\"></path>`)}\n </button>\n <button\n type=\"button\"\n class=\"icon-btn\"\n aria-label=${this.#animState.playing ? \"Pause\" : \"Play\"}\n @click=${() => {\n if (this.#animState.playing) this.#controller?.animations.pause();\n else this.#controller?.animations.play();\n }}\n >\n ${this.#animState.playing\n ? this.#icon(\n svg`<path d=\"M6 4h4v16H6zM14 4h4v16h-4z\" fill=\"currentColor\" stroke=\"none\"></path>`,\n )\n : this.#icon(\n svg`<path d=\"M8 5v14l11-7z\" fill=\"currentColor\" stroke=\"none\"></path>`,\n )}\n </button>\n <button\n type=\"button\"\n class=\"icon-btn\"\n aria-label=\"Next step\"\n @click=${() => this.#controller?.animations.step(1)}\n >\n ${this.#icon(svg`<path d=\"M9 18l6-6-6-6\"></path>`)}\n </button>\n <input\n class=\"anim-scrub\"\n type=\"range\"\n min=\"0\"\n max=${duration}\n step=\"16\"\n .value=${String(this.#animState.timeMs)}\n aria-label=\"Scrub animation\"\n @input=${(e: Event) => {\n const ms = Number((e.target as HTMLInputElement).value);\n this.#controller?.animations.seek(ms);\n }}\n />\n <span class=\"anim-time\">${timeLabel}</span>\n <label class=\"anim-select anim-select--speed\">\n <select\n aria-label=\"Playback speed\"\n @change=${(e: Event) => {\n const rate = Number((e.target as HTMLSelectElement).value);\n this.#controller?.animations.setSpeed(rate);\n }}\n >\n ${SPEED_OPTIONS.map((rate) => {\n const value = formatSpeedValue(rate);\n return html`\n <option\n value=${value}\n ?selected=${value === formatSpeedValue(this.#animState.speed)}\n >\n ${formatSpeedLabel(rate)}\n </option>\n `;\n })}\n </select>\n <span class=\"anim-select__caret\" aria-hidden=\"true\">\n ${this.#icon(svg`<path d=\"M6 9l6 6 6-6\"></path>`, 12)}\n </span>\n </label>\n <button\n type=\"button\"\n class=\"icon-btn ${this.#animState.loop ? \"is-pressed\" : \"\"}\"\n aria-label=${this.#animState.loop ? \"Loop on\" : \"Loop off\"}\n aria-pressed=${this.#animState.loop ? \"true\" : \"false\"}\n title=${this.#animState.loop ? \"Loop on\" : \"Loop off\"}\n @click=${() => this.#controller?.animations.setLoop(!this.#animState.loop)}\n >\n ${this.#icon(\n svg`<path d=\"M17 1l4 4-4 4M3 11V9a4 4 0 0 1 4-4h14M7 23l-4-4 4-4M21 13v2a4 4 0 0 1-4 4H3\"></path>`,\n )}\n </button>\n </div>\n </div>\n `\n : nothing}\n ${showTools\n ? html`\n <div class=\"overlay overlay--tools\" role=\"toolbar\" aria-label=\"Diagram controls\">\n ${this.showViewControls\n ? html`\n <div class=\"tools\" role=\"group\" aria-label=\"View\">\n <button\n type=\"button\"\n class=\"icon-btn\"\n aria-label=\"Zoom out\"\n @click=${() => this.zoomOut()}\n >\n ${this.#icon(svg`<path d=\"M5 12h14\"></path>`)}\n </button>\n <button\n type=\"button\"\n class=\"icon-btn\"\n aria-label=\"Zoom in\"\n @click=${() => this.zoomIn()}\n >\n ${this.#icon(svg`<path d=\"M12 5v14M5 12h14\"></path>`)}\n </button>\n <button\n type=\"button\"\n class=\"icon-btn\"\n aria-label=\"Fit to view\"\n @click=${() => this.fit()}\n >\n ${this.#icon(\n svg`<path d=\"M8 3H5a2 2 0 0 0-2 2v3M16 3h3a2 2 0 0 1 2 2v3M8 21H5a2 2 0 0 1-2-2v-3M16 21h3a2 2 0 0 0 2-2v-3\"></path>`,\n )}\n </button>\n <button\n type=\"button\"\n class=\"icon-btn\"\n aria-label=${this.#isFullscreen ? \"Exit fullscreen\" : \"Fullscreen\"}\n @click=${() => void this.#toggleFullscreen()}\n >\n ${this.#isFullscreen\n ? this.#icon(\n svg`<path d=\"M4 14h6v6M20 10h-6V4M14 10l7-7M3 21l7-7\"></path>`,\n )\n : this.#icon(\n svg`<path d=\"M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7\"></path>`,\n )}\n </button>\n </div>\n `\n : nothing}\n ${this.showThemeToggle\n ? html`\n <button\n type=\"button\"\n class=\"icon-btn\"\n aria-label=${this.#activeTheme === \"dark\"\n ? \"Switch to light theme\"\n : \"Switch to dark theme\"}\n @click=${() => this.#toggleTheme()}\n >\n ${this.#activeTheme === \"dark\"\n ? this.#icon([\n svg`<circle cx=\"12\" cy=\"12\" r=\"4\"></circle>`,\n svg`<path d=\"M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41\"></path>`,\n ])\n : this.#icon(\n svg`<path d=\"M21 14.5A8.5 8.5 0 1 1 9.5 3a7 7 0 0 0 11.5 11.5z\"></path>`,\n )}\n </button>\n `\n : nothing}\n </div>\n `\n : nothing}\n </div>\n `;\n }\n}\n\nfunction formatAnimClock(ms: number): string {\n const total = Math.max(0, Math.round(ms / 1000));\n const m = Math.floor(total / 60);\n const s = total % 60;\n return `${m}:${String(s).padStart(2, \"0\")}`;\n}\n\nconst SPEED_OPTIONS = [0.5, 0.75, 1, 1.25, 1.5, 2] as const;\n\nfunction formatSpeedValue(rate: number): string {\n const snapped =\n SPEED_OPTIONS.find((o) => Math.abs(o - rate) < 0.01) ??\n SPEED_OPTIONS.reduce((best, o) => (Math.abs(o - rate) < Math.abs(best - rate) ? o : best));\n return String(snapped);\n}\n\nfunction formatSpeedLabel(rate: number): string {\n return `${rate}×`;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"k-diagram\": KDiagramElement;\n }\n}\n","import { KDiagramElement } from \"./k-diagram.ts\";\n\nexport { KDiagramElement } from \"./k-diagram.ts\";\nexport type { InteractiveRenderOptions, ThemeMode } from \"@kekonic/diagrams\";\n\n/** Tag name for `<k-diagram>`. */\nexport const K_DIAGRAM_TAG = \"k-diagram\";\n\n/** Register `<k-diagram>` (idempotent). Called on package import. */\nexport function registerKDiagramElements(): void {\n if (!customElements.get(K_DIAGRAM_TAG)) {\n customElements.define(K_DIAGRAM_TAG, KDiagramElement);\n }\n}\n\nregisterKDiagramElements();\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kekonic/diagrams-element",
|
|
3
|
+
"version": "1.0.0-rc.4",
|
|
4
|
+
"description": "Lit web components for embedding KDiagram diagrams — framework-agnostic custom elements on renderToElement.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"architecture",
|
|
7
|
+
"diagram",
|
|
8
|
+
"lit",
|
|
9
|
+
"svg",
|
|
10
|
+
"web-component"
|
|
11
|
+
],
|
|
12
|
+
"homepage": "https://github.com/kekonic/diagrams#readme",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/kekonic/diagrams/issues"
|
|
15
|
+
},
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/kekonic/diagrams.git",
|
|
20
|
+
"directory": "packages/diagrams-element"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"type": "module",
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./dist/index.d.mts",
|
|
29
|
+
"import": "./dist/index.mjs"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"lit": "^3.3.0",
|
|
37
|
+
"@kekonic/diagrams": "1.0.0-rc.4"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/node": "^26",
|
|
41
|
+
"happy-dom": "^20.11.1",
|
|
42
|
+
"typescript": "^5",
|
|
43
|
+
"vite": "npm:@voidzero-dev/vite-plus-core@0.2.2",
|
|
44
|
+
"vite-plus": "0.2.2",
|
|
45
|
+
"vitest": "^4"
|
|
46
|
+
},
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=22.18.0"
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "vp pack",
|
|
52
|
+
"test": "vp test"
|
|
53
|
+
}
|
|
54
|
+
}
|