@rosettadash/web-components 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +103 -0
  3. package/browser/media.js +484 -0
  4. package/browser/media.js.map +7 -0
  5. package/package.json +125 -0
  6. package/src/catalog/_shared/catalog-variant.d.ts +5 -0
  7. package/src/catalog/_shared/catalog-variant.js +19 -0
  8. package/src/catalog/_shared/catalog-variant.js.map +1 -0
  9. package/src/catalog/_shared/markup-shared.d.ts +6 -0
  10. package/src/catalog/_shared/markup-shared.js +21 -0
  11. package/src/catalog/_shared/markup-shared.js.map +1 -0
  12. package/src/catalog/component-attribute/index.d.ts +2 -0
  13. package/src/catalog/component-attribute/index.js +2 -0
  14. package/src/catalog/component-attribute/index.js.map +1 -0
  15. package/src/catalog/component-attribute/rd-attribute.d.ts +20 -0
  16. package/src/catalog/component-attribute/rd-attribute.js +27 -0
  17. package/src/catalog/component-attribute/rd-attribute.js.map +1 -0
  18. package/src/catalog/component-name/index.d.ts +2 -0
  19. package/src/catalog/component-name/index.js +2 -0
  20. package/src/catalog/component-name/index.js.map +1 -0
  21. package/src/catalog/component-name/rd-component-name.d.ts +40 -0
  22. package/src/catalog/component-name/rd-component-name.js +219 -0
  23. package/src/catalog/component-name/rd-component-name.js.map +1 -0
  24. package/src/catalog/component-option/index.d.ts +2 -0
  25. package/src/catalog/component-option/index.js +2 -0
  26. package/src/catalog/component-option/index.js.map +1 -0
  27. package/src/catalog/component-option/rd-component-option.d.ts +25 -0
  28. package/src/catalog/component-option/rd-component-option.js +104 -0
  29. package/src/catalog/component-option/rd-component-option.js.map +1 -0
  30. package/src/catalog/component-port/index.d.ts +2 -0
  31. package/src/catalog/component-port/index.js +2 -0
  32. package/src/catalog/component-port/index.js.map +1 -0
  33. package/src/catalog/component-port/rd-component-port.d.ts +26 -0
  34. package/src/catalog/component-port/rd-component-port.js +109 -0
  35. package/src/catalog/component-port/rd-component-port.js.map +1 -0
  36. package/src/catalog/component-requirement/index.d.ts +2 -0
  37. package/src/catalog/component-requirement/index.js +2 -0
  38. package/src/catalog/component-requirement/index.js.map +1 -0
  39. package/src/catalog/component-requirement/rd-component-requirement.d.ts +17 -0
  40. package/src/catalog/component-requirement/rd-component-requirement.js +76 -0
  41. package/src/catalog/component-requirement/rd-component-requirement.js.map +1 -0
  42. package/src/catalog/component-spec/index.d.ts +2 -0
  43. package/src/catalog/component-spec/index.js +2 -0
  44. package/src/catalog/component-spec/index.js.map +1 -0
  45. package/src/catalog/component-spec/rd-component-spec.d.ts +40 -0
  46. package/src/catalog/component-spec/rd-component-spec.js +367 -0
  47. package/src/catalog/component-spec/rd-component-spec.js.map +1 -0
  48. package/src/catalog/index.d.ts +23 -0
  49. package/src/catalog/index.js +37 -0
  50. package/src/catalog/index.js.map +1 -0
  51. package/src/catalog/palette-catalog/index.d.ts +2 -0
  52. package/src/catalog/palette-catalog/index.js +2 -0
  53. package/src/catalog/palette-catalog/index.js.map +1 -0
  54. package/src/catalog/palette-catalog/rd-palette-catalog.d.ts +29 -0
  55. package/src/catalog/palette-catalog/rd-palette-catalog.js +114 -0
  56. package/src/catalog/palette-catalog/rd-palette-catalog.js.map +1 -0
  57. package/src/catalog/palette-group/index.d.ts +2 -0
  58. package/src/catalog/palette-group/index.js +2 -0
  59. package/src/catalog/palette-group/index.js.map +1 -0
  60. package/src/catalog/palette-group/rd-palette-group.d.ts +33 -0
  61. package/src/catalog/palette-group/rd-palette-group.js +179 -0
  62. package/src/catalog/palette-group/rd-palette-group.js.map +1 -0
  63. package/src/catalog/subcomponent-name/index.d.ts +1 -0
  64. package/src/catalog/subcomponent-name/index.js +2 -0
  65. package/src/catalog/subcomponent-name/index.js.map +1 -0
  66. package/src/catalog/subcomponent-name/rd-subcomponent-name.d.ts +12 -0
  67. package/src/catalog/subcomponent-name/rd-subcomponent-name.js +29 -0
  68. package/src/catalog/subcomponent-name/rd-subcomponent-name.js.map +1 -0
  69. package/src/index.d.ts +9 -0
  70. package/src/index.js +23 -0
  71. package/src/index.js.map +1 -0
  72. package/src/layout/accordion/index.d.ts +4 -0
  73. package/src/layout/accordion/index.js +7 -0
  74. package/src/layout/accordion/index.js.map +1 -0
  75. package/src/layout/accordion/rd-accordion.d.ts +26 -0
  76. package/src/layout/accordion/rd-accordion.js +94 -0
  77. package/src/layout/accordion/rd-accordion.js.map +1 -0
  78. package/src/layout/accordion-link-list/index.d.ts +4 -0
  79. package/src/layout/accordion-link-list/index.js +7 -0
  80. package/src/layout/accordion-link-list/index.js.map +1 -0
  81. package/src/layout/accordion-link-list/rd-accordion-link-list.d.ts +36 -0
  82. package/src/layout/accordion-link-list/rd-accordion-link-list.js +139 -0
  83. package/src/layout/accordion-link-list/rd-accordion-link-list.js.map +1 -0
  84. package/src/lib/element-utils.d.ts +8 -0
  85. package/src/lib/element-utils.js +46 -0
  86. package/src/lib/element-utils.js.map +1 -0
  87. package/src/lib/parse-link-items.d.ts +6 -0
  88. package/src/lib/parse-link-items.js +37 -0
  89. package/src/lib/parse-link-items.js.map +1 -0
  90. package/src/lib/shadow-base.d.ts +20 -0
  91. package/src/lib/shadow-base.js +81 -0
  92. package/src/lib/shadow-base.js.map +1 -0
  93. package/src/lib/shadow-resources.d.ts +10 -0
  94. package/src/lib/shadow-resources.js +38 -0
  95. package/src/lib/shadow-resources.js.map +1 -0
  96. package/src/register-shadow-bases.browser.d.ts +1 -0
  97. package/src/register-shadow-bases.browser.js +5 -0
  98. package/src/register-shadow-bases.browser.js.map +1 -0
  99. package/src/visual/link-list/index.d.ts +4 -0
  100. package/src/visual/link-list/index.js +7 -0
  101. package/src/visual/link-list/index.js.map +1 -0
  102. package/src/visual/link-list/rd-link-list.d.ts +26 -0
  103. package/src/visual/link-list/rd-link-list.js +68 -0
  104. package/src/visual/link-list/rd-link-list.js.map +1 -0
  105. package/src/visual/media/equirect-viewport/index.d.ts +1 -0
  106. package/src/visual/media/equirect-viewport/index.js +2 -0
  107. package/src/visual/media/equirect-viewport/index.js.map +1 -0
  108. package/src/visual/media/equirect-viewport/rd-equirect-viewport.d.ts +30 -0
  109. package/src/visual/media/equirect-viewport/rd-equirect-viewport.js +199 -0
  110. package/src/visual/media/equirect-viewport/rd-equirect-viewport.js.map +1 -0
  111. package/src/visual/media/index.d.ts +3 -0
  112. package/src/visual/media/index.js +9 -0
  113. package/src/visual/media/index.js.map +1 -0
  114. package/src/visual/media/video-source/index.d.ts +1 -0
  115. package/src/visual/media/video-source/index.js +2 -0
  116. package/src/visual/media/video-source/index.js.map +1 -0
  117. package/src/visual/media/video-source/rd-video-source.d.ts +19 -0
  118. package/src/visual/media/video-source/rd-video-source.js +105 -0
  119. package/src/visual/media/video-source/rd-video-source.js.map +1 -0
  120. package/src/wasm/index.d.ts +2 -0
  121. package/src/wasm/index.js +6 -0
  122. package/src/wasm/index.js.map +1 -0
  123. package/src/wasm/wasm-media/index.d.ts +1 -0
  124. package/src/wasm/wasm-media/index.js +2 -0
  125. package/src/wasm/wasm-media/index.js.map +1 -0
  126. package/src/wasm/wasm-media/rd-wasm-media.d.ts +30 -0
  127. package/src/wasm/wasm-media/rd-wasm-media.js +269 -0
  128. package/src/wasm/wasm-media/rd-wasm-media.js.map +1 -0
  129. package/styles/catalog.css +69 -0
  130. package/styles/styles.css +76 -0
  131. package/styles/tokens.css +19 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../packages/core/src/lib/media/equirect-filter.ts", "../../../../packages/web-components/src/lib/element-utils.ts", "../../../../packages/web-components/src/lib/shadow-resources.ts", "../../../../packages/web-components/src/lib/shadow-base.ts", "../../../../packages/web-components/src/visual/media/video-source/rd-video-source.ts", "../../../../packages/web-components/src/visual/media/equirect-viewport/rd-equirect-viewport.ts", "../../../../packages/web-components/src/visual/media/index.ts"],
4
+ "sourcesContent": ["export interface EquirectFlatCropOptions {\n cropX: number;\n cropY: number;\n cropWidth: number;\n cropHeight: number;\n outputWidth: number;\n outputHeight: number;\n}\n\nexport interface EquirectRectilinearOptions {\n yaw: number;\n pitch: number;\n roll?: number;\n horizontalFov: number;\n outputWidth: number;\n outputHeight: number;\n}\n\n/** ffmpeg -vf filter for a rectangular crop on a flat 2:1 equirect frame, then scale. */\nexport function buildEquirectFlatCropFilter(options: EquirectFlatCropOptions): string {\n const cropX = Math.max(0, Math.round(options.cropX));\n const cropY = Math.max(0, Math.round(options.cropY));\n const cropWidth = Math.max(2, Math.round(options.cropWidth));\n const cropHeight = Math.max(2, Math.round(options.cropHeight));\n const outputWidth = Math.max(2, Math.round(options.outputWidth));\n const outputHeight = Math.max(2, Math.round(options.outputHeight));\n\n return `crop=${cropWidth}:${cropHeight}:${cropX}:${cropY},scale=${outputWidth}:${outputHeight}`;\n}\n\n/** ffmpeg -vf filter for rectilinear reprojection from equirect source. */\nexport function buildEquirectRectilinearFilter(options: EquirectRectilinearOptions): string {\n const yaw = Number(options.yaw) || 0;\n const pitch = Number(options.pitch) || 0;\n const roll = Number(options.roll ?? 0) || 0;\n const horizontalFov = Math.max(1, Number(options.horizontalFov) || 90);\n const outputWidth = Math.max(2, Math.round(options.outputWidth));\n const outputHeight = Math.max(2, Math.round(options.outputHeight));\n\n return [\n `v360=input=equirect:output=rectilinear:yaw=${yaw}:pitch=${pitch}:roll=${roll}:d_fov=${horizontalFov}`,\n `scale=${outputWidth}:${outputHeight}`,\n ].join(',');\n}\n\nexport function buildEquirectExtractFilter(\n mode: 'flat-crop' | 'rectilinear',\n options: EquirectFlatCropOptions & Partial<EquirectRectilinearOptions>,\n): string {\n if (mode === 'rectilinear') {\n return buildEquirectRectilinearFilter({\n yaw: options.yaw ?? 0,\n pitch: options.pitch ?? 0,\n roll: options.roll ?? 0,\n horizontalFov: options.horizontalFov ?? 90,\n outputWidth: options.outputWidth,\n outputHeight: options.outputHeight,\n });\n }\n\n return buildEquirectFlatCropFilter(options);\n}\n\n/** Default crop centered on a 4096\u00D72048 equirect frame. */\nexport const DEFAULT_EQUIRECT_SOURCE = { width: 4096, height: 2048 } as const;\n\nexport const DEFAULT_EQUIRECT_FLAT_CROP: EquirectFlatCropOptions = {\n cropX: Math.floor((DEFAULT_EQUIRECT_SOURCE.width - 1080) / 2),\n cropY: Math.floor((DEFAULT_EQUIRECT_SOURCE.height - 720) / 2),\n cropWidth: 1080,\n cropHeight: 720,\n outputWidth: 720,\n outputHeight: 480,\n};\n", "export interface DefineRosettaElementOptions {\n extends?: keyof HTMLElementTagNameMap;\n}\n\nexport function defineRosettaElement(\n tagName: string,\n ctor: CustomElementConstructor,\n options?: DefineRosettaElementOptions,\n): void {\n if (customElements.get(tagName)) {\n return;\n }\n if (options?.extends) {\n customElements.define(tagName, ctor, { extends: options.extends });\n } else {\n customElements.define(tagName, ctor);\n }\n}\n\nexport type DashRow = Record<string, string | number | boolean | null | undefined>;\n\nexport function readNumber(value: unknown, fallback: number): number {\n const next = Number(value);\n return Number.isFinite(next) ? next : fallback;\n}\n\nexport function readString(value: unknown, fallback: string): string {\n return typeof value === 'string' ? value : fallback;\n}\n\nexport const BASE_STYLES = `\n:host {\n display: block;\n font-family: var(--rd-font-family, system-ui, sans-serif);\n color: var(--rd-color-text, #1f2937);\n}\n.panel {\n border: 1px solid var(--rd-color-border, #d9dee7);\n border-radius: var(--rd-radius-md, 0.5rem);\n padding: 0.75rem;\n}\n.panel__header {\n display: flex;\n justify-content: space-between;\n align-items: baseline;\n gap: 0.75rem;\n margin-bottom: 0.75rem;\n}\n.panel__header h3 {\n margin: 0;\n font-size: 0.9375rem;\n}\n.panel__meta {\n font-size: 0.75rem;\n color: var(--rd-color-muted, #6b7280);\n}\n`;\n", "const textCache = new Map<string, Promise<string>>();\n\n/** Load co-located `.html` / `.css` for shadow roots (browser fetch). */\nexport function loadTextResource(relativePath: string, baseUrl: string): Promise<string> {\n const url = new URL(relativePath, baseUrl);\n const cacheKey = url.href;\n const cached = textCache.get(cacheKey);\n if (cached) {\n return cached;\n }\n\n const promise = (async () => {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to load ${url.href}: ${response.status}`);\n }\n return response.text();\n })();\n\n textCache.set(cacheKey, promise);\n return promise;\n}\n\nexport interface ShadowMountOptions {\n html: string;\n css: string;\n}\n\n/** Apply stylesheet + markup to an open shadow root. */\nexport function applyShadowMount(root: ShadowRoot, options: ShadowMountOptions): void {\n root.innerHTML = '';\n const style = document.createElement('style');\n style.textContent = options.css;\n root.appendChild(style);\n\n const template = document.createElement('template');\n template.innerHTML = options.html;\n root.appendChild(template.content.cloneNode(true));\n}\n\n/** Load paired `.html` + `.css` next to the calling module. */\nexport async function loadShadowPair(\n baseUrl: string,\n htmlFile: string,\n cssFile: string,\n): Promise<ShadowMountOptions> {\n const [html, css] = await Promise.all([\n loadTextResource(htmlFile, baseUrl),\n loadTextResource(cssFile, baseUrl),\n ]);\n return { html, css };\n}\n", "import { loadTextResource, type ShadowMountOptions } from './shadow-resources.js';\n\n/** Co-located shadow asset directories relative to `packages/web-components/src/`. */\nexport const SHADOW_ELEMENT_DIRS: Record<string, string> = {\n 'rd-accordion': 'layout/accordion',\n 'rd-accordion-link-list': 'layout/accordion-link-list',\n 'rd-link-list': 'visual/link-list',\n 'rd-video-source': 'visual/media/video-source',\n 'rd-equirect-viewport': 'visual/media/equirect-viewport',\n 'rd-wasm-media': 'wasm/wasm-media',\n 'rd-component-name': 'catalog/component-name',\n};\n\nconst tagToBaseUrl = new Map<string, string>();\nlet packageSrcRoot: string | null = null;\n\n/** Ensure a module/file URL resolves to a directory URL (trailing `/`). */\nexport function normalizeDirectoryUrl(urlString: string): string {\n const url = new URL(urlString);\n const lastSegment = url.pathname.split('/').pop() ?? '';\n if (/\\.[a-z0-9]+$/i.test(lastSegment)) {\n url.pathname = url.pathname.replace(/\\/[^/]+$/, '/');\n } else if (!url.pathname.endsWith('/')) {\n url.pathname = `${url.pathname}/`;\n }\n return url.href.endsWith('/') ? url.href : `${url.href}/`;\n}\n\n/** Register co-located asset directory for a custom element tag. */\nexport function registerShadowBase(tag: string, baseUrl: string): void {\n tagToBaseUrl.set(tag, normalizeDirectoryUrl(baseUrl));\n}\n\n/** Set package `src/` root (`file:` or `https:` URL ending in `/`). */\nexport function setShadowPackageSrcRoot(rootUrl: string): void {\n packageSrcRoot = normalizeDirectoryUrl(rootUrl);\n}\n\n/** Resolve `packages/web-components/src/` from a module URL (Vite-safe). */\nexport function resolvePackageSrcRootFromModule(moduleUrl: string): string {\n const marker = new URL('./register-shadow-bases.browser.js', moduleUrl);\n return normalizeDirectoryUrl(new URL('./', marker).href);\n}\n\n/** Register all known shadow bases from {@link setShadowPackageSrcRoot}. */\nexport function registerAllShadowBases(): void {\n if (!packageSrcRoot) {\n throw new Error('setShadowPackageSrcRoot must be called before registerAllShadowBases');\n }\n for (const [tag, dir] of Object.entries(SHADOW_ELEMENT_DIRS)) {\n registerShadowBase(tag, new URL(`./${dir}/`, packageSrcRoot).href);\n }\n}\n\n/** Register one shadow base when package root is configured (browser entry or Jest setup). */\nexport function ensureShadowBase(tag: string): void {\n if (tagToBaseUrl.has(tag)) {\n return;\n }\n if (!packageSrcRoot) {\n throw new Error(\n `Shadow base not registered for ${tag}. Import '@rosettadash/web-components' once in app code, or add the web-components Jest setup in test config.`,\n );\n }\n const dir = SHADOW_ELEMENT_DIRS[tag];\n if (!dir) {\n throw new Error(`Unknown shadow element tag: ${tag}`);\n }\n registerShadowBase(tag, new URL(`./${dir}/`, packageSrcRoot).href);\n}\n\n/** Resolve registered base URL for shadow asset loading. */\nexport function getShadowBase(tag: string): string {\n const base = tagToBaseUrl.get(tag);\n if (!base) {\n throw new Error(`Shadow base not registered for ${tag}`);\n }\n return base;\n}\n\n/** Load paired `.html` + `.css` for a registered element tag. */\nexport async function loadShadowPairForTag(\n tag: string,\n htmlFile: string,\n cssFile: string,\n): Promise<ShadowMountOptions> {\n ensureShadowBase(tag);\n const base = getShadowBase(tag);\n const [html, css] = await Promise.all([\n loadTextResource(htmlFile, base),\n loadTextResource(cssFile, base),\n ]);\n return { html, css };\n}\n\nexport { applyShadowMount } from './shadow-resources.js';\n", "import { DEFAULT_EQUIRECT_SOURCE } from '@rosettadash/core';\nimport { defineRosettaElement, type DashRow, readNumber, readString } from '../../../lib/element-utils.js';\nimport { applyShadowMount, ensureShadowBase, loadShadowPairForTag } from '../../../lib/shadow-base.js';\n\nexport const DB_VIDEO_SOURCE_TAG = 'rd-video-source';\n\nexport class RdVideoSourceElement extends HTMLElement {\n static readonly tagName = DB_VIDEO_SOURCE_TAG;\n\n private inputEl: HTMLInputElement | null = null;\n private resourcesReady: Promise<void> | null = null;\n private changeListener: (() => void) | null = null;\n\n connectedCallback(): void {\n if (!this.shadowRoot) {\n this.attachShadow({ mode: 'open' });\n }\n this.resourcesReady = this.mountShadow();\n void this.resourcesReady.then(() => this.paint());\n }\n\n disconnectedCallback(): void {\n if (this.inputEl && this.changeListener) {\n this.inputEl.removeEventListener('change', this.changeListener);\n }\n this.changeListener = null;\n this.inputEl = null;\n }\n\n setProperty(name: string, value: unknown): void {\n (this as Record<string, unknown>)[name] = value;\n if (this.resourcesReady) {\n void this.resourcesReady.then(() => this.paint());\n }\n }\n\n whenReady(): Promise<void> {\n return this.resourcesReady ?? Promise.resolve();\n }\n\n get label(): string {\n return readString(this.getAttribute('label'), 'Video source');\n }\n\n get accept(): string {\n return readString(this.getAttribute('accept'), 'video/*');\n }\n\n get sourceWidth(): number {\n return readNumber(this.getAttribute('source-width'), DEFAULT_EQUIRECT_SOURCE.width);\n }\n\n get sourceHeight(): number {\n return readNumber(this.getAttribute('source-height'), DEFAULT_EQUIRECT_SOURCE.height);\n }\n\n private async mountShadow(): Promise<void> {\n const root = this.shadowRoot;\n if (!root || root.querySelector('.video-source')) {\n return;\n }\n const pair = await loadShadowPairForTag(\n DB_VIDEO_SOURCE_TAG,\n './rd-video-source.html',\n './rd-video-source.css',\n );\n applyShadowMount(root, pair);\n this.inputEl = root.querySelector('[data-ref=\"input\"]');\n this.changeListener = () => this.handleFileSelected();\n this.inputEl?.addEventListener('change', this.changeListener);\n }\n\n private paint(): void {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const labelEl = root.querySelector('[data-ref=\"label\"]');\n const metaEl = root.querySelector('[data-ref=\"meta\"]');\n if (labelEl) {\n labelEl.textContent = this.label;\n }\n if (metaEl) {\n metaEl.textContent = `${this.sourceWidth}\u00D7${this.sourceHeight}`;\n }\n const input = root.querySelector('[data-ref=\"input\"]') as HTMLInputElement | null;\n if (input) {\n input.accept = this.accept;\n }\n }\n\n private handleFileSelected(): void {\n const file = this.inputEl?.files?.[0];\n if (!file) {\n return;\n }\n\n const nameEl = this.shadowRoot?.querySelector('[data-ref=\"file-name\"]');\n if (nameEl) {\n nameEl.textContent = file.name;\n }\n\n const metadata: DashRow = {\n name: file.name,\n sourceWidth: this.sourceWidth,\n sourceHeight: this.sourceHeight,\n size: file.size,\n };\n\n this.dispatchEvent(\n new CustomEvent('video-file', {\n detail: { file, metadata },\n bubbles: true,\n composed: true,\n }),\n );\n this.dispatchEvent(\n new CustomEvent('metadata', {\n detail: metadata,\n bubbles: true,\n composed: true,\n }),\n );\n }\n}\n\nexport function registerRdVideoSource(): void {\n ensureShadowBase(DB_VIDEO_SOURCE_TAG);\n defineRosettaElement(RdVideoSourceElement.tagName, RdVideoSourceElement);\n}\n", "import {\n buildEquirectExtractFilter,\n DEFAULT_EQUIRECT_FLAT_CROP,\n DEFAULT_EQUIRECT_SOURCE,\n} from '@rosettadash/core';\nimport { defineRosettaElement, type DashRow, readNumber, readString } from '../../../lib/element-utils.js';\nimport { applyShadowMount, ensureShadowBase, getShadowBase, loadShadowPairForTag } from '../../../lib/shadow-base.js';\nimport { loadTextResource } from '../../../lib/shadow-resources.js';\n\nexport const DB_EQUIRECT_VIEWPORT_TAG = 'rd-equirect-viewport';\n\nexport type EquirectPreviewMode = 'flat-crop' | 'rectilinear';\n\nexport class RdEquirectViewportElement extends HTMLElement {\n static readonly tagName = DB_EQUIRECT_VIEWPORT_TAG;\n\n private resourcesReady: Promise<void> | null = null;\n\n static get observedAttributes(): string[] {\n return [\n 'label',\n 'preview-mode',\n 'source-width',\n 'source-height',\n 'crop-x',\n 'crop-y',\n 'crop-width',\n 'crop-height',\n 'output-width',\n 'output-height',\n 'yaw',\n 'pitch',\n 'horizontal-fov',\n ];\n }\n\n connectedCallback(): void {\n if (!this.shadowRoot) {\n this.attachShadow({ mode: 'open' });\n }\n this.resourcesReady = this.mountShadow();\n void this.resourcesReady.then(() => {\n this.paint();\n this.emitCropRegion();\n });\n }\n\n attributeChangedCallback(): void {\n if (this.shadowRoot && this.resourcesReady) {\n void this.resourcesReady.then(() => {\n this.paint();\n this.emitCropRegion();\n });\n }\n }\n\n whenReady(): Promise<void> {\n return this.resourcesReady ?? Promise.resolve();\n }\n\n setProperty(name: string, value: unknown): void {\n const attrMap: Record<string, string> = {\n previewMode: 'preview-mode',\n sourceWidth: 'source-width',\n sourceHeight: 'source-height',\n cropX: 'crop-x',\n cropY: 'crop-y',\n cropWidth: 'crop-width',\n cropHeight: 'crop-height',\n outputWidth: 'output-width',\n outputHeight: 'output-height',\n horizontalFov: 'horizontal-fov',\n };\n\n const attr = attrMap[name] ?? name;\n if (value === null || value === undefined) {\n this.removeAttribute(attr);\n } else {\n this.setAttribute(attr, String(value));\n }\n }\n\n get previewMode(): EquirectPreviewMode {\n const mode = readString(this.getAttribute('preview-mode'), 'flat-crop');\n return mode === 'rectilinear' ? 'rectilinear' : 'flat-crop';\n }\n\n get label(): string {\n return readString(this.getAttribute('label'), 'Equirect viewport');\n }\n\n get cropRegion(): DashRow {\n return {\n cropX: this.cropX,\n cropY: this.cropY,\n cropWidth: this.cropWidth,\n cropHeight: this.cropHeight,\n outputWidth: this.outputWidth,\n outputHeight: this.outputHeight,\n yaw: this.yaw,\n pitch: this.pitch,\n horizontalFov: this.horizontalFov,\n previewMode: this.previewMode,\n filter: buildEquirectExtractFilter(this.previewMode, {\n cropX: this.cropX,\n cropY: this.cropY,\n cropWidth: this.cropWidth,\n cropHeight: this.cropHeight,\n outputWidth: this.outputWidth,\n outputHeight: this.outputHeight,\n yaw: this.yaw,\n pitch: this.pitch,\n horizontalFov: this.horizontalFov,\n }),\n };\n }\n\n private get sourceWidth(): number {\n return readNumber(this.getAttribute('source-width'), DEFAULT_EQUIRECT_SOURCE.width);\n }\n\n private get sourceHeight(): number {\n return readNumber(this.getAttribute('source-height'), DEFAULT_EQUIRECT_SOURCE.height);\n }\n\n private get cropX(): number {\n return readNumber(this.getAttribute('crop-x'), DEFAULT_EQUIRECT_FLAT_CROP.cropX);\n }\n\n private get cropY(): number {\n return readNumber(this.getAttribute('crop-y'), DEFAULT_EQUIRECT_FLAT_CROP.cropY);\n }\n\n private get cropWidth(): number {\n return readNumber(this.getAttribute('crop-width'), DEFAULT_EQUIRECT_FLAT_CROP.cropWidth);\n }\n\n private get cropHeight(): number {\n return readNumber(this.getAttribute('crop-height'), DEFAULT_EQUIRECT_FLAT_CROP.cropHeight);\n }\n\n private get outputWidth(): number {\n return readNumber(this.getAttribute('output-width'), DEFAULT_EQUIRECT_FLAT_CROP.outputWidth);\n }\n\n private get outputHeight(): number {\n return readNumber(this.getAttribute('output-height'), DEFAULT_EQUIRECT_FLAT_CROP.outputHeight);\n }\n\n private get yaw(): number {\n return readNumber(this.getAttribute('yaw'), 0);\n }\n\n private get pitch(): number {\n return readNumber(this.getAttribute('pitch'), 0);\n }\n\n private get horizontalFov(): number {\n return readNumber(this.getAttribute('horizontal-fov'), 90);\n }\n\n private async mountShadow(): Promise<void> {\n const root = this.shadowRoot;\n if (!root || root.querySelector('[data-ref=\"root\"]')) {\n return;\n }\n const pair = await loadShadowPairForTag(\n DB_EQUIRECT_VIEWPORT_TAG,\n './rd-equirect-viewport.html',\n './rd-equirect-viewport.css',\n );\n const panelCss = await loadTextResource('../../../lib/panel.css', getShadowBase(DB_EQUIRECT_VIEWPORT_TAG));\n applyShadowMount(root, { html: pair.html, css: `${panelCss}\\n${pair.css}` });\n }\n\n private paint(): void {\n const root = this.shadowRoot;\n if (!root) {\n return;\n }\n\n const cropLeftPct = (this.cropX / this.sourceWidth) * 100;\n const cropTopPct = (this.cropY / this.sourceHeight) * 100;\n const cropWidthPct = (this.cropWidth / this.sourceWidth) * 100;\n const cropHeightPct = (this.cropHeight / this.sourceHeight) * 100;\n\n const flatPreview = `\n <div class=\"equirect-frame\" style=\"aspect-ratio: ${this.sourceWidth} / ${this.sourceHeight}\">\n <div class=\"equirect-frame__crop\" style=\"left:${cropLeftPct}%;top:${cropTopPct}%;width:${cropWidthPct}%;height:${cropHeightPct}%\"></div>\n </div>\n `;\n\n const rectilinearPreview = `\n <div class=\"rectilinear-preview\">\n <div class=\"rectilinear-preview__cone\" style=\"transform: rotateY(${this.yaw}deg) rotateX(${-this.pitch}deg)\"></div>\n <dl class=\"rectilinear-preview__meta\">\n <div><dt>Yaw</dt><dd>${this.yaw}\u00B0</dd></div>\n <div><dt>Pitch</dt><dd>${this.pitch}\u00B0</dd></div>\n <div><dt>FOV</dt><dd>${this.horizontalFov}\u00B0</dd></div>\n </dl>\n </div>\n `;\n\n const labelEl = root.querySelector('[data-ref=\"label\"]');\n const modeEl = root.querySelector('[data-ref=\"mode\"]');\n if (labelEl) {\n labelEl.textContent = this.label;\n }\n if (modeEl) {\n modeEl.textContent = this.previewMode === 'flat-crop' ? 'Flat crop' : 'Rectilinear';\n }\n const preview = root.querySelector('[data-ref=\"preview\"]');\n if (preview) {\n preview.innerHTML = this.previewMode === 'flat-crop' ? flatPreview : rectilinearPreview;\n }\n const filterEl = root.querySelector('[data-ref=\"filter\"]');\n if (filterEl) {\n filterEl.textContent = String(this.cropRegion['filter']);\n }\n const outputEl = root.querySelector('[data-ref=\"output\"]');\n if (outputEl) {\n outputEl.textContent = `Output ${this.outputWidth}\u00D7${this.outputHeight}`;\n }\n }\n\n private emitCropRegion(): void {\n this.dispatchEvent(\n new CustomEvent('crop-region', {\n detail: this.cropRegion,\n bubbles: true,\n composed: true,\n }),\n );\n }\n}\n\nexport function registerRdEquirectViewport(): void {\n ensureShadowBase(DB_EQUIRECT_VIEWPORT_TAG);\n defineRosettaElement(RdEquirectViewportElement.tagName, RdEquirectViewportElement);\n}\n", "export { RdVideoSourceElement, DB_VIDEO_SOURCE_TAG, registerRdVideoSource } from './video-source/index.js';\nexport {\n RdEquirectViewportElement,\n DB_EQUIRECT_VIEWPORT_TAG,\n registerRdEquirectViewport,\n type EquirectPreviewMode,\n} from './equirect-viewport/index.js';\n\nimport { registerRdEquirectViewport } from './equirect-viewport/index.js';\nimport { registerRdVideoSource } from './video-source/index.js';\n\nexport function registerRosettaDashMediaElements(): void {\n registerRdVideoSource();\n registerRdEquirectViewport();\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
package/package.json ADDED
@@ -0,0 +1,125 @@
1
+ {
2
+ "name": "@rosettadash/web-components",
3
+ "version": "0.1.0",
4
+ "description": "RosettaDash Web Components runtime — typed custom elements with optional tokens.css / styles.css. Storybook catalog: clone github.com/KevinEverywhere/rosettadash (port 6006).",
5
+ "author": "Kevin Ready <kevin@planetkevin.com>",
6
+ "type": "module",
7
+ "license": "MIT",
8
+ "private": false,
9
+ "sideEffects": [
10
+ "**/*.css"
11
+ ],
12
+ "main": "./src/index.js",
13
+ "types": "./src/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./src/index.d.ts",
17
+ "import": "./src/index.js",
18
+ "default": "./src/index.js"
19
+ },
20
+ "./layout/accordion": {
21
+ "types": "./src/layout/accordion/index.d.ts",
22
+ "import": "./src/layout/accordion/index.js",
23
+ "default": "./src/layout/accordion/index.js"
24
+ },
25
+ "./layout/accordion-link-list": {
26
+ "types": "./src/layout/accordion-link-list/index.d.ts",
27
+ "import": "./src/layout/accordion-link-list/index.js",
28
+ "default": "./src/layout/accordion-link-list/index.js"
29
+ },
30
+ "./visual/link-list": {
31
+ "types": "./src/visual/link-list/index.d.ts",
32
+ "import": "./src/visual/link-list/index.js",
33
+ "default": "./src/visual/link-list/index.js"
34
+ },
35
+ "./media": {
36
+ "types": "./src/visual/media/index.d.ts",
37
+ "import": "./src/visual/media/index.js",
38
+ "default": "./src/visual/media/index.js"
39
+ },
40
+ "./wasm": {
41
+ "types": "./src/wasm/index.d.ts",
42
+ "import": "./src/wasm/index.js",
43
+ "default": "./src/wasm/index.js"
44
+ },
45
+ "./catalog": {
46
+ "types": "./src/catalog/index.d.ts",
47
+ "import": "./src/catalog/index.js",
48
+ "default": "./src/catalog/index.js"
49
+ },
50
+ "./catalog/palette-catalog": {
51
+ "types": "./src/catalog/index.d.ts",
52
+ "import": "./src/catalog/index.js",
53
+ "default": "./src/catalog/index.js"
54
+ },
55
+ "./catalog/component-spec": {
56
+ "types": "./src/catalog/component-spec/index.d.ts",
57
+ "import": "./src/catalog/component-spec/index.js",
58
+ "default": "./src/catalog/component-spec/index.js"
59
+ },
60
+ "./visual/media/video-source": {
61
+ "types": "./src/visual/media/video-source/index.d.ts",
62
+ "import": "./src/visual/media/video-source/index.js",
63
+ "default": "./src/visual/media/video-source/index.js"
64
+ },
65
+ "./visual/media/equirect-viewport": {
66
+ "types": "./src/visual/media/equirect-viewport/index.d.ts",
67
+ "import": "./src/visual/media/equirect-viewport/index.js",
68
+ "default": "./src/visual/media/equirect-viewport/index.js"
69
+ },
70
+ "./browser/media": {
71
+ "import": "./browser/media.js",
72
+ "default": "./browser/media.js"
73
+ },
74
+ "./tokens.css": "./styles/tokens.css",
75
+ "./styles.css": "./styles/styles.css",
76
+ "./package.json": "./package.json",
77
+ "./layout/accordion/index": "./src/layout/accordion/index.js",
78
+ "./layout/accordion-link-list/index": "./src/layout/accordion-link-list/index.js",
79
+ "./visual/link-list/index": "./src/visual/link-list/index.js",
80
+ "./visual/media": "./src/visual/media/index.js",
81
+ "./visual/media/index": "./src/visual/media/index.js",
82
+ "./visual/media/video-source/index": "./src/visual/media/video-source/index.js",
83
+ "./visual/media/equirect-viewport/index": "./src/visual/media/equirect-viewport/index.js",
84
+ "./wasm/index": "./src/wasm/index.js",
85
+ "./catalog/index": "./src/catalog/index.js",
86
+ "./catalog/component-spec/index": "./src/catalog/component-spec/index.js"
87
+ },
88
+ "files": [
89
+ "src",
90
+ "styles",
91
+ "media",
92
+ "browser",
93
+ "README.md",
94
+ "LICENSE"
95
+ ],
96
+ "peerDependencies": {
97
+ "@ffmpeg/ffmpeg": ">=0.12.0",
98
+ "@ffmpeg/util": ">=0.12.0"
99
+ },
100
+ "peerDependenciesMeta": {
101
+ "@ffmpeg/ffmpeg": {
102
+ "optional": true
103
+ },
104
+ "@ffmpeg/util": {
105
+ "optional": true
106
+ }
107
+ },
108
+ "dependencies": {
109
+ "@rosettadash/core": "0.1.0",
110
+ "tslib": "^2.3.0"
111
+ },
112
+ "publishConfig": {
113
+ "access": "public"
114
+ },
115
+ "repository": {
116
+ "type": "git",
117
+ "url": "git+https://github.com/KevinEverywhere/rosettadash.git",
118
+ "directory": "packages/web-components"
119
+ },
120
+ "homepage": "https://github.com/KevinEverywhere/rosettadash#component-examples-storybook",
121
+ "bugs": {
122
+ "url": "https://github.com/KevinEverywhere/rosettadash/issues"
123
+ },
124
+ "module": "./src/index.js"
125
+ }
@@ -0,0 +1,5 @@
1
+ /** Visual density / chrome for catalog meta elements — shared across runtimes via BEM modifiers. */
2
+ export type CatalogVariant = 'default' | 'compact' | 'plain';
3
+ export declare const CATALOG_VARIANTS: CatalogVariant[];
4
+ export declare function readCatalogVariant(value: string | null, fallback?: CatalogVariant): CatalogVariant;
5
+ export declare function applyCatalogVariant(el: HTMLElement, blockClass: string, variant: CatalogVariant): void;
@@ -0,0 +1,19 @@
1
+ export const CATALOG_VARIANTS = ['default', 'compact', 'plain'];
2
+ export function readCatalogVariant(value, fallback = 'default') {
3
+ if (value === 'compact' || value === 'plain' || value === 'default') {
4
+ return value;
5
+ }
6
+ return fallback;
7
+ }
8
+ export function applyCatalogVariant(el, blockClass, variant) {
9
+ el.classList.add(blockClass);
10
+ for (const name of CATALOG_VARIANTS) {
11
+ if (name !== 'default') {
12
+ el.classList.remove(`${blockClass}--${name}`);
13
+ }
14
+ }
15
+ if (variant !== 'default') {
16
+ el.classList.add(`${blockClass}--${variant}`);
17
+ }
18
+ }
19
+ //# sourceMappingURL=catalog-variant.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog-variant.js","sourceRoot":"","sources":["../../../../../../packages/web-components/src/catalog/_shared/catalog-variant.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,gBAAgB,GAAqB,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAElF,MAAM,UAAU,kBAAkB,CAAC,KAAoB,EAAE,WAA2B,SAAS;IAC3F,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACpE,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,EAAe,EAAE,UAAkB,EAAE,OAAuB;IAC9F,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC7B,KAAK,MAAM,IAAI,IAAI,gBAAgB,EAAE,CAAC;QACpC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,UAAU,KAAK,IAAI,EAAE,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IACD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,UAAU,KAAK,OAAO,EAAE,CAAC,CAAC;IAChD,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { type CatalogVariant } from '../_shared/catalog-variant.js';
2
+ /** Map taxonomy type to documented custom-element-style tag (rd-*). */
3
+ export declare function taxonomyToRdTag(componentType: string): string;
4
+ export declare function escapeHtml(value: string): string;
5
+ export declare function readMarkupVariant(el: HTMLElement): CatalogVariant;
6
+ export declare function applyMarkupVariant(el: HTMLElement, blockClass: string): void;
@@ -0,0 +1,21 @@
1
+ import { applyCatalogVariant, readCatalogVariant } from '../_shared/catalog-variant.js';
2
+ /** Map taxonomy type to documented custom-element-style tag (rd-*). */
3
+ export function taxonomyToRdTag(componentType) {
4
+ const stripped = componentType.replace(/^(visual|domain|layout|logic|infra)\./, '');
5
+ const kebab = stripped.replace(/\./g, '-');
6
+ return `rd-${kebab}`;
7
+ }
8
+ export function escapeHtml(value) {
9
+ return value
10
+ .replace(/&/g, '&amp;')
11
+ .replace(/</g, '&lt;')
12
+ .replace(/>/g, '&gt;')
13
+ .replace(/"/g, '&quot;');
14
+ }
15
+ export function readMarkupVariant(el) {
16
+ return readCatalogVariant(el.getAttribute('variant'));
17
+ }
18
+ export function applyMarkupVariant(el, blockClass) {
19
+ applyCatalogVariant(el, blockClass, readMarkupVariant(el));
20
+ }
21
+ //# sourceMappingURL=markup-shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markup-shared.js","sourceRoot":"","sources":["../../../../../../packages/web-components/src/catalog/_shared/markup-shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAuB,MAAM,+BAA+B,CAAC;AAE7G,uEAAuE;AACvE,MAAM,UAAU,eAAe,CAAC,aAAqB;IACnD,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,CAAC,uCAAuC,EAAE,EAAE,CAAC,CAAC;IACpF,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC3C,OAAO,MAAM,KAAK,EAAE,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,OAAO,KAAK;SACT,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,EAAe;IAC/C,OAAO,kBAAkB,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,EAAe,EAAE,UAAkB;IACpE,mBAAmB,CAAC,EAAE,EAAE,UAAU,EAAE,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,2 @@
1
+ export type { ComponentAttributeProps } from './rd-attribute.js';
2
+ export { RD_ATTRIBUTE_TAG, RdAttributeElement, registerRdAttribute } from './rd-attribute.js';
@@ -0,0 +1,2 @@
1
+ export { RD_ATTRIBUTE_TAG, RdAttributeElement, registerRdAttribute } from './rd-attribute.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../packages/web-components/src/catalog/component-attribute/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,20 @@
1
+ export declare const RD_ATTRIBUTE_TAG = "rd-attribute";
2
+ /** One documented attribute on a component or subcomponent (`required` = black, `optional` = grey). */
3
+ export interface ComponentAttributeProps {
4
+ name: string;
5
+ value?: string;
6
+ required?: boolean;
7
+ optional?: boolean;
8
+ /** When set, renders as output binding rather than rd-* property. */
9
+ output?: boolean;
10
+ }
11
+ export declare class RdAttributeElement extends HTMLElement {
12
+ static readonly tagName = "rd-attribute";
13
+ static get observedAttributes(): string[];
14
+ get attrName(): string;
15
+ get attrValue(): string;
16
+ get isOutput(): boolean;
17
+ get isRequired(): boolean;
18
+ get requirementClass(): 'required' | 'optional';
19
+ }
20
+ export declare function registerRdAttribute(): void;
@@ -0,0 +1,27 @@
1
+ import { defineRosettaElement, readString } from '../../lib/element-utils.js';
2
+ export const RD_ATTRIBUTE_TAG = 'rd-attribute';
3
+ export class RdAttributeElement extends HTMLElement {
4
+ static tagName = RD_ATTRIBUTE_TAG;
5
+ static get observedAttributes() {
6
+ return ['name', 'value', 'output'];
7
+ }
8
+ get attrName() {
9
+ return readString(this.getAttribute('name'), '');
10
+ }
11
+ get attrValue() {
12
+ return readString(this.getAttribute('value'), '');
13
+ }
14
+ get isOutput() {
15
+ return this.hasAttribute('output');
16
+ }
17
+ get isRequired() {
18
+ return this.hasAttribute('required');
19
+ }
20
+ get requirementClass() {
21
+ return this.hasAttribute('required') ? 'required' : 'optional';
22
+ }
23
+ }
24
+ export function registerRdAttribute() {
25
+ defineRosettaElement(RD_ATTRIBUTE_TAG, RdAttributeElement);
26
+ }
27
+ //# sourceMappingURL=rd-attribute.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rd-attribute.js","sourceRoot":"","sources":["../../../../../../packages/web-components/src/catalog/component-attribute/rd-attribute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAE9E,MAAM,CAAC,MAAM,gBAAgB,GAAG,cAAc,CAAC;AAY/C,MAAM,OAAO,kBAAmB,SAAQ,WAAW;IACjD,MAAM,CAAU,OAAO,GAAG,gBAAgB,CAAC;IAE3C,MAAM,KAAK,kBAAkB;QAC3B,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IACrC,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,IAAI,SAAS;QACX,OAAO,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC;IAED,IAAI,gBAAgB;QAClB,OAAO,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC;IACjE,CAAC;;AAGH,MAAM,UAAU,mBAAmB;IACjC,oBAAoB,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,2 @@
1
+ export type { BuildComponentMarkupOptions } from './rd-component-name.js';
2
+ export { RD_COMPONENT_NAME_TAG, RdComponentNameElement, registerRdComponentName, createComponentNameElement, } from './rd-component-name.js';
@@ -0,0 +1,2 @@
1
+ export { RD_COMPONENT_NAME_TAG, RdComponentNameElement, registerRdComponentName, createComponentNameElement, } from './rd-component-name.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../packages/web-components/src/catalog/component-name/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,40 @@
1
+ import type { ComponentDefinition } from '@rosettadash/core';
2
+ export declare const RD_COMPONENT_NAME_TAG = "rd-component-name";
3
+ export declare class RdComponentNameElement extends HTMLElement {
4
+ static readonly tagName = "rd-component-name";
5
+ private resourcesReady;
6
+ static get observedAttributes(): string[];
7
+ connectedCallback(): void;
8
+ attributeChangedCallback(): void;
9
+ whenReady(): Promise<void>;
10
+ get displayTag(): string;
11
+ get label(): string;
12
+ get description(): string;
13
+ private renderAttributeLine;
14
+ private renderSubcomponent;
15
+ private renderMarkupTree;
16
+ private hideMarkupChildren;
17
+ private mountShadow;
18
+ private paint;
19
+ }
20
+ export declare function registerRdComponentName(): void;
21
+ export interface BuildComponentMarkupOptions {
22
+ dependencies?: string[];
23
+ assumptions?: string[];
24
+ /** Map dependency text to subcomponent tag hints */
25
+ subcomponents?: Array<{
26
+ tag: string;
27
+ bind?: string;
28
+ required?: boolean;
29
+ attributes?: Array<{
30
+ name: string;
31
+ value?: string;
32
+ required?: boolean;
33
+ }>;
34
+ }>;
35
+ }
36
+ /** Build declarative markup tree from registry definition — no HTML strings. */
37
+ export declare function createComponentNameElement(definition: ComponentDefinition, options?: BuildComponentMarkupOptions & {
38
+ variant?: string;
39
+ navGroupId?: string;
40
+ }): RdComponentNameElement;
@@ -0,0 +1,219 @@
1
+ import { defineRosettaElement, readString } from '../../lib/element-utils.js';
2
+ import { applyShadowMount, ensureShadowBase, getShadowBase, loadShadowPairForTag } from '../../lib/shadow-base.js';
3
+ import { loadTextResource } from '../../lib/shadow-resources.js';
4
+ import { RD_ATTRIBUTE_TAG } from '../component-attribute/rd-attribute.js';
5
+ import { escapeHtml, applyMarkupVariant, taxonomyToRdTag } from '../_shared/markup-shared.js';
6
+ import { RD_SUBCOMPONENT_NAME_TAG } from '../subcomponent-name/rd-subcomponent-name.js';
7
+ export const RD_COMPONENT_NAME_TAG = 'rd-component-name';
8
+ export class RdComponentNameElement extends HTMLElement {
9
+ static tagName = RD_COMPONENT_NAME_TAG;
10
+ resourcesReady = null;
11
+ static get observedAttributes() {
12
+ return ['tag', 'label', 'description', 'component-type', 'variant', 'nav-group-id'];
13
+ }
14
+ connectedCallback() {
15
+ if (!this.shadowRoot) {
16
+ this.attachShadow({ mode: 'open' });
17
+ }
18
+ const nav = readString(this.getAttribute('nav-group-id'), '');
19
+ if (nav) {
20
+ this.setAttribute('data-nav-group', nav);
21
+ }
22
+ this.resourcesReady = this.mountShadow();
23
+ void this.resourcesReady.then(() => this.paint());
24
+ }
25
+ attributeChangedCallback() {
26
+ if (this.shadowRoot && this.resourcesReady) {
27
+ void this.resourcesReady.then(() => this.paint());
28
+ }
29
+ }
30
+ whenReady() {
31
+ return this.resourcesReady ?? Promise.resolve();
32
+ }
33
+ get displayTag() {
34
+ const explicit = readString(this.getAttribute('tag'), '');
35
+ if (explicit) {
36
+ return explicit.startsWith('rd-') ? explicit : `rd-${explicit}`;
37
+ }
38
+ const type = readString(this.getAttribute('component-type'), '');
39
+ return type ? taxonomyToRdTag(type) : 'rd-component';
40
+ }
41
+ get label() {
42
+ return readString(this.getAttribute('label'), '');
43
+ }
44
+ get description() {
45
+ return readString(this.getAttribute('description'), '');
46
+ }
47
+ renderAttributeLine(attr, indent) {
48
+ const reqClass = attr.requirementClass;
49
+ const flag = reqClass;
50
+ const prefix = attr.isOutput ? '' : 'rd-';
51
+ const name = escapeHtml(attr.attrName);
52
+ const value = attr.attrValue ? escapeHtml(attr.attrValue) : '';
53
+ const valuePart = value
54
+ ? `<span class="rd-markup-tree__punct">=</span><span class="rd-markup-tree__punct">"</span><span class="rd-markup-tree__attr--${reqClass}">${value}</span><span class="rd-markup-tree__punct">"</span>`
55
+ : '';
56
+ return `${indent}<span class="rd-markup-tree__attr--${reqClass}">${prefix}${name}</span>${valuePart} <span class="rd-markup-tree__flag rd-markup-tree__flag--${reqClass}">${flag}</span>`;
57
+ }
58
+ renderSubcomponent(sub, indent) {
59
+ const reqClass = sub.requirementClass;
60
+ const flag = reqClass;
61
+ const tag = escapeHtml(sub.subTag);
62
+ const attrs = sub.attributeElements;
63
+ const childSubs = [...sub.querySelectorAll(`:scope > ${RD_SUBCOMPONENT_NAME_TAG}`)];
64
+ if (attrs.length === 0 && childSubs.length === 0) {
65
+ const bind = sub.bindHint
66
+ ? ` <span class="rd-markup-tree__attr--${reqClass}">rd-bind="${escapeHtml(sub.bindHint)}"</span>`
67
+ : '';
68
+ return `${indent}<span class="rd-markup-tree__punct">&lt;</span><span class="rd-markup-tree__tag">${tag}</span>${bind} <span class="rd-markup-tree__flag rd-markup-tree__flag--${reqClass}">${flag}</span><span class="rd-markup-tree__punct"> /&gt;</span>`;
69
+ }
70
+ const innerIndent = `${indent} `;
71
+ const attrLines = attrs.map((a) => this.renderAttributeLine(a, innerIndent)).join('\n');
72
+ const childLines = childSubs.map((c) => this.renderSubcomponent(c, `${indent} `)).join('\n');
73
+ return `${indent}<span class="rd-markup-tree__punct">&lt;</span><span class="rd-markup-tree__tag">${tag}</span> <span class="rd-markup-tree__flag rd-markup-tree__flag--${reqClass}">${flag}</span><span class="rd-markup-tree__punct">&gt;</span>\n${attrLines}${childLines ? `\n${childLines}` : ''}\n${indent}<span class="rd-markup-tree__punct">&lt;/</span><span class="rd-markup-tree__tag">${tag}</span><span class="rd-markup-tree__punct">&gt;</span>`;
74
+ }
75
+ renderMarkupTree() {
76
+ const tag = escapeHtml(this.displayTag);
77
+ const rootAttrs = [...this.querySelectorAll(`:scope > ${RD_ATTRIBUTE_TAG}`)];
78
+ const rootSubs = [...this.querySelectorAll(`:scope > ${RD_SUBCOMPONENT_NAME_TAG}`)];
79
+ if (rootAttrs.length === 0 && rootSubs.length === 0) {
80
+ return `<span class="rd-markup-tree__punct">&lt;</span><span class="rd-markup-tree__tag">${tag}</span><span class="rd-markup-tree__punct"> /&gt;</span>`;
81
+ }
82
+ const openIndent = ' ';
83
+ const attrLines = rootAttrs.map((a) => this.renderAttributeLine(a, openIndent)).join('\n');
84
+ const subLines = rootSubs.map((s) => this.renderSubcomponent(s, ' ')).join('\n');
85
+ return `<span class="rd-markup-tree__punct">&lt;</span><span class="rd-markup-tree__tag">${tag}</span>\n${attrLines}\n<span class="rd-markup-tree__punct">&gt;</span>\n${subLines}\n<span class="rd-markup-tree__punct">&lt;/</span><span class="rd-markup-tree__tag">${tag}</span><span class="rd-markup-tree__punct">&gt;</span>`;
86
+ }
87
+ hideMarkupChildren() {
88
+ this.querySelectorAll(`${RD_ATTRIBUTE_TAG}, ${RD_SUBCOMPONENT_NAME_TAG}`).forEach((el) => {
89
+ el.hidden = true;
90
+ });
91
+ }
92
+ async mountShadow() {
93
+ const root = this.shadowRoot;
94
+ if (!root || root.querySelector('[data-ref="root"]')) {
95
+ return;
96
+ }
97
+ const pair = await loadShadowPairForTag(RD_COMPONENT_NAME_TAG, './rd-component-name.html', './rd-component-name.css');
98
+ const markupCss = await loadTextResource('../_shared/markup-tree.css', getShadowBase(RD_COMPONENT_NAME_TAG));
99
+ applyShadowMount(root, { html: pair.html, css: `${pair.css}\n${markupCss}` });
100
+ }
101
+ paint() {
102
+ const root = this.shadowRoot;
103
+ if (!root) {
104
+ return;
105
+ }
106
+ this.hideMarkupChildren();
107
+ const headerEl = root.querySelector('[data-ref="header"]');
108
+ if (headerEl) {
109
+ headerEl.innerHTML = this.label
110
+ ? `<header class="rd-component-name__header"><h3>${escapeHtml(this.label)}</h3>${this.description ? `<p>${escapeHtml(this.description)}</p>` : ''}</header>`
111
+ : '';
112
+ }
113
+ const tree = root.querySelector('[data-ref="tree"]');
114
+ if (tree) {
115
+ tree.innerHTML = this.renderMarkupTree();
116
+ }
117
+ applyMarkupVariant(this, 'rd-component-name');
118
+ }
119
+ }
120
+ export function registerRdComponentName() {
121
+ ensureShadowBase(RD_COMPONENT_NAME_TAG);
122
+ defineRosettaElement(RD_COMPONENT_NAME_TAG, RdComponentNameElement);
123
+ }
124
+ /** Build declarative markup tree from registry definition — no HTML strings. */
125
+ export function createComponentNameElement(definition, options = {}) {
126
+ const el = document.createElement(RD_COMPONENT_NAME_TAG);
127
+ el.setAttribute('component-type', definition.type);
128
+ el.setAttribute('label', definition.label);
129
+ if (definition.description) {
130
+ el.setAttribute('description', definition.description);
131
+ }
132
+ if (options.variant) {
133
+ el.setAttribute('variant', options.variant);
134
+ }
135
+ if (options.navGroupId) {
136
+ el.setAttribute('nav-group-id', options.navGroupId);
137
+ }
138
+ for (const port of definition.inputs) {
139
+ const attr = document.createElement(RD_ATTRIBUTE_TAG);
140
+ attr.setAttribute('name', port.name);
141
+ attr.setAttribute('value', port.dataType);
142
+ if (port.required) {
143
+ attr.setAttribute('required', '');
144
+ }
145
+ else {
146
+ attr.setAttribute('optional', '');
147
+ }
148
+ el.appendChild(attr);
149
+ }
150
+ for (const port of definition.outputs) {
151
+ const attr = document.createElement(RD_ATTRIBUTE_TAG);
152
+ attr.setAttribute('name', port.name);
153
+ attr.setAttribute('value', port.dataType);
154
+ attr.setAttribute('output', '');
155
+ attr.setAttribute('optional', '');
156
+ el.appendChild(attr);
157
+ }
158
+ for (const property of definition.properties) {
159
+ const attr = document.createElement(RD_ATTRIBUTE_TAG);
160
+ attr.setAttribute('name', property.key);
161
+ if (property.default !== undefined) {
162
+ attr.setAttribute('value', String(property.default));
163
+ }
164
+ else if (property.type) {
165
+ attr.setAttribute('value', property.type);
166
+ }
167
+ if (property.required) {
168
+ attr.setAttribute('required', '');
169
+ }
170
+ else {
171
+ attr.setAttribute('optional', '');
172
+ }
173
+ el.appendChild(attr);
174
+ }
175
+ for (const sub of options.subcomponents ?? []) {
176
+ const subEl = document.createElement(RD_SUBCOMPONENT_NAME_TAG);
177
+ subEl.setAttribute('tag', sub.tag);
178
+ if (sub.bind) {
179
+ subEl.setAttribute('bind', sub.bind);
180
+ }
181
+ if (sub.required) {
182
+ subEl.setAttribute('required', '');
183
+ }
184
+ else {
185
+ subEl.setAttribute('optional', '');
186
+ }
187
+ for (const a of sub.attributes ?? []) {
188
+ const attr = document.createElement(RD_ATTRIBUTE_TAG);
189
+ attr.setAttribute('name', a.name);
190
+ if (a.value) {
191
+ attr.setAttribute('value', a.value);
192
+ }
193
+ if (a.required) {
194
+ attr.setAttribute('required', '');
195
+ }
196
+ else {
197
+ attr.setAttribute('optional', '');
198
+ }
199
+ subEl.appendChild(attr);
200
+ }
201
+ el.appendChild(subEl);
202
+ }
203
+ for (const dep of options.dependencies ?? []) {
204
+ const attr = document.createElement(RD_ATTRIBUTE_TAG);
205
+ attr.setAttribute('name', 'depends-on');
206
+ attr.setAttribute('value', dep);
207
+ attr.setAttribute('optional', '');
208
+ el.appendChild(attr);
209
+ }
210
+ for (const assumption of options.assumptions ?? []) {
211
+ const attr = document.createElement(RD_ATTRIBUTE_TAG);
212
+ attr.setAttribute('name', 'assume');
213
+ attr.setAttribute('value', assumption);
214
+ attr.setAttribute('optional', '');
215
+ el.appendChild(attr);
216
+ }
217
+ return el;
218
+ }
219
+ //# sourceMappingURL=rd-component-name.js.map