@seed-ship/mcp-ui-solid 6.1.0 → 6.3.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 (58) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/dist/components/CarouselRenderer.cjs +41 -30
  3. package/dist/components/CarouselRenderer.cjs.map +1 -1
  4. package/dist/components/CarouselRenderer.d.ts.map +1 -1
  5. package/dist/components/CarouselRenderer.js +42 -31
  6. package/dist/components/CarouselRenderer.js.map +1 -1
  7. package/dist/components/CodeBlockRenderer.cjs +88 -25
  8. package/dist/components/CodeBlockRenderer.cjs.map +1 -1
  9. package/dist/components/CodeBlockRenderer.d.ts.map +1 -1
  10. package/dist/components/CodeBlockRenderer.js +89 -26
  11. package/dist/components/CodeBlockRenderer.js.map +1 -1
  12. package/dist/components/ExpandableWrapper.cjs +2 -1
  13. package/dist/components/ExpandableWrapper.cjs.map +1 -1
  14. package/dist/components/ExpandableWrapper.d.ts +10 -0
  15. package/dist/components/ExpandableWrapper.d.ts.map +1 -1
  16. package/dist/components/ExpandableWrapper.js +3 -2
  17. package/dist/components/ExpandableWrapper.js.map +1 -1
  18. package/dist/components/ImageGalleryRenderer.cjs +101 -77
  19. package/dist/components/ImageGalleryRenderer.cjs.map +1 -1
  20. package/dist/components/ImageGalleryRenderer.d.ts.map +1 -1
  21. package/dist/components/ImageGalleryRenderer.js +102 -78
  22. package/dist/components/ImageGalleryRenderer.js.map +1 -1
  23. package/dist/components/MapRenderer.cjs +94 -34
  24. package/dist/components/MapRenderer.cjs.map +1 -1
  25. package/dist/components/MapRenderer.d.ts.map +1 -1
  26. package/dist/components/MapRenderer.js +107 -47
  27. package/dist/components/MapRenderer.js.map +1 -1
  28. package/dist/components/UIResourceRenderer.cjs +27 -12
  29. package/dist/components/UIResourceRenderer.cjs.map +1 -1
  30. package/dist/components/UIResourceRenderer.d.ts.map +1 -1
  31. package/dist/components/UIResourceRenderer.js +27 -12
  32. package/dist/components/UIResourceRenderer.js.map +1 -1
  33. package/dist/components/VideoRenderer.cjs +95 -74
  34. package/dist/components/VideoRenderer.cjs.map +1 -1
  35. package/dist/components/VideoRenderer.d.ts.map +1 -1
  36. package/dist/components/VideoRenderer.js +96 -75
  37. package/dist/components/VideoRenderer.js.map +1 -1
  38. package/dist/index.cjs +3 -3
  39. package/dist/index.js +1 -1
  40. package/dist/mcp-ui-spec/dist/schemas.cjs +8 -1
  41. package/dist/mcp-ui-spec/dist/schemas.cjs.map +1 -1
  42. package/dist/mcp-ui-spec/dist/schemas.js +8 -1
  43. package/dist/mcp-ui-spec/dist/schemas.js.map +1 -1
  44. package/dist/types/index.d.ts +11 -0
  45. package/dist/types/index.d.ts.map +1 -1
  46. package/dist/types.d.cts +11 -0
  47. package/dist/types.d.ts +11 -0
  48. package/package.json +2 -2
  49. package/src/components/CarouselRenderer.tsx +9 -1
  50. package/src/components/CodeBlockRenderer.tsx +65 -5
  51. package/src/components/ExpandableWrapper.tsx +16 -2
  52. package/src/components/ImageGalleryRenderer.test.tsx +18 -7
  53. package/src/components/ImageGalleryRenderer.tsx +22 -3
  54. package/src/components/MapRenderer.tsx +68 -14
  55. package/src/components/UIResourceRenderer.tsx +19 -10
  56. package/src/components/VideoRenderer.tsx +14 -4
  57. package/src/types/index.ts +11 -0
  58. package/tsconfig.tsbuildinfo +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ExpandableWrapper.js","sources":["../../src/components/ExpandableWrapper.tsx"],"sourcesContent":["/**\n * ExpandableWrapper - Generic expand/fullscreen wrapper for components\n * v2.2.0: Reusable wrapper that adds expand button + fullscreen modal\n *\n * Uses DOM reparenting to avoid rendering children twice — critical for\n * imperative components like ChartJS that bind instances to DOM nodes.\n */\n\nimport { Component, Show, createSignal, createEffect, onCleanup, JSX, createContext, useContext, Accessor } from 'solid-js'\nimport { Portal } from 'solid-js/web'\n\n/** Context for child components to know if they're in expanded/fullscreen view */\nconst ExpandedContext = createContext<Accessor<boolean>>(() => false)\n\n/** Hook for child components to read expanded state */\nexport const useExpanded = () => useContext(ExpandedContext)\n\nexport interface ExpandableWrapperProps {\n /** Content to render inline (and in expanded view) */\n children: JSX.Element\n /** Title shown in the expanded modal header */\n title?: string\n /** Data string for copy-to-clipboard in expanded view */\n copyData?: string\n /** Label for copy button tooltip */\n copyLabel?: string\n}\n\n/**\n * Wraps any component with an expand button (top-right corner).\n * Opens a fullscreen Portal modal. The children's DOM is physically\n * reparented into the modal (not duplicated), so imperative bindings\n * like Chart.js canvas refs stay intact.\n *\n * @example\n * <ExpandableWrapper title=\"Sales Data\" copyData={tsvData}>\n * <TableRenderer ... />\n * </ExpandableWrapper>\n */\nexport const ExpandableWrapper: Component<ExpandableWrapperProps> = (props) => {\n const [isExpanded, setIsExpanded] = createSignal(false)\n const [copied, setCopied] = createSignal(false)\n let dialogRef: HTMLDivElement | undefined\n let contentRef: HTMLDivElement | undefined\n let inlineSlotRef: HTMLDivElement | undefined\n let modalSlotRef: HTMLDivElement | undefined\n\n const handleOpen = () => setIsExpanded(true)\n const handleClose = () => setIsExpanded(false)\n\n // Reparent content DOM between inline and modal slots\n createEffect(() => {\n if (!contentRef) return\n\n if (isExpanded()) {\n // Move content into modal\n modalSlotRef?.appendChild(contentRef)\n } else {\n // Move content back to inline\n inlineSlotRef?.appendChild(contentRef)\n }\n })\n\n // Keyboard: Escape to close\n createEffect(() => {\n if (!isExpanded()) return\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n e.preventDefault()\n handleClose()\n }\n }\n\n document.addEventListener('keydown', onKeyDown)\n onCleanup(() => document.removeEventListener('keydown', onKeyDown))\n })\n\n // Prevent body scroll when expanded\n createEffect(() => {\n if (isExpanded()) {\n const prev = document.body.style.overflow\n document.body.style.overflow = 'hidden'\n // Focus the dialog\n setTimeout(() => dialogRef?.focus(), 10)\n onCleanup(() => {\n document.body.style.overflow = prev\n })\n }\n })\n\n const handleBackdropClick = (e: MouseEvent) => {\n if (e.target === e.currentTarget) handleClose()\n }\n\n const handleCopy = async () => {\n if (!props.copyData) return\n try {\n await navigator.clipboard.writeText(props.copyData)\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n } catch (err) {\n console.error('Failed to copy:', err)\n }\n }\n\n return (\n <div class=\"relative group\">\n {/* Inline slot — content lives here when not expanded */}\n <div ref={inlineSlotRef}>\n <div ref={contentRef}>\n <ExpandedContext.Provider value={isExpanded}>\n {props.children}\n </ExpandedContext.Provider>\n </div>\n </div>\n\n {/* Expand button — visible on hover */}\n <button\n onClick={handleOpen}\n class=\"absolute top-2 right-2 z-10 opacity-0 group-hover:opacity-70 hover:!opacity-100 p-1.5 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 rounded-full hover:bg-gray-100 dark:hover:bg-gray-700 transition-all shadow-sm\"\n title=\"Expand\"\n aria-label=\"Expand to fullscreen\"\n >\n <svg class=\"w-3.5 h-3.5 text-gray-500 dark:text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5v-4m0 4h-4m4 0l-5-5\" />\n </svg>\n </button>\n\n {/* Fullscreen modal via Portal */}\n <Show when={isExpanded()}>\n <Portal>\n <div\n class=\"fixed inset-0 z-50 flex flex-col bg-black/50 backdrop-blur-sm\"\n style={{ animation: 'expandable-fade-in 0.15s ease-out' }}\n onClick={handleBackdropClick}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={props.title || 'Expanded view'}\n tabIndex={-1}\n ref={dialogRef}\n >\n {/* Modal panel */}\n <div\n class=\"relative flex flex-col m-4 flex-1 bg-white dark:bg-gray-800 rounded-lg shadow-xl overflow-hidden\"\n style={{ animation: 'expandable-scale-in 0.15s ease-out' }}\n onClick={(e) => e.stopPropagation()}\n >\n {/* Header */}\n <div class=\"flex items-center justify-between px-4 py-3 border-b border-gray-200 dark:border-gray-700 flex-shrink-0\">\n <h2 class=\"text-lg font-semibold text-gray-900 dark:text-white truncate\">\n {props.title || 'Expanded View'}\n </h2>\n <div class=\"flex items-center gap-2\">\n {/* Copy button */}\n <Show when={props.copyData}>\n <button\n onClick={handleCopy}\n class=\"p-1.5 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 rounded-full hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors\"\n title={props.copyLabel || 'Copy to clipboard'}\n aria-label={props.copyLabel || 'Copy to clipboard'}\n >\n <Show\n when={!copied()}\n fallback={\n <svg class=\"w-5 h-5 text-green-500\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13l4 4L19 7\" />\n </svg>\n }\n >\n <svg class=\"w-5 h-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\" />\n </svg>\n </Show>\n </button>\n </Show>\n {/* Close button */}\n <button\n onClick={handleClose}\n class=\"p-1.5 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 rounded-full hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors\"\n aria-label=\"Close expanded view\"\n >\n <svg class=\"w-5 h-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n </div>\n\n {/* Modal slot — content is reparented here when expanded.\n v6.1.0 : `flex flex-col` lets aware children opt into\n `flex-1 min-h-0` to fill the modal vertically (chart,\n table, map, graph). Unaware children keep working\n thanks to `overflow-auto` (their natural height\n scrolls if it overflows the slot). */}\n <div class=\"flex-1 min-h-0 overflow-auto p-4 flex flex-col\" ref={modalSlotRef} />\n </div>\n </div>\n\n <style>{`\n @keyframes expandable-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n @keyframes expandable-scale-in {\n from { opacity: 0; transform: scale(0.97); }\n to { opacity: 1; transform: scale(1); }\n }\n `}</style>\n </Portal>\n </Show>\n </div>\n )\n}\n"],"names":["ExpandedContext","createContext","useExpanded","useContext","ExpandableWrapper","props","isExpanded","setIsExpanded","createSignal","copied","setCopied","dialogRef","contentRef","inlineSlotRef","modalSlotRef","handleOpen","handleClose","createEffect","appendChild","onKeyDown","e","key","preventDefault","document","addEventListener","onCleanup","removeEventListener","prev","body","style","overflow","setTimeout","focus","handleBackdropClick","target","currentTarget","handleCopy","copyData","navigator","clipboard","writeText","err","console","error","_el$","_$getNextElement","_tmpl$5","_el$2","firstChild","_el$3","_el$4","nextSibling","_el$15","_el$16","_co$2","_$getNextMarker","_ref$","_$use","_ref$2","_$insert","_$createComponent","Provider","value","children","$$click","Show","when","Portal","_el$5","_tmpl$3","_el$6","_el$7","_el$8","_el$9","_el$11","_el$12","_co$","_el$10","_el$13","_ref$3","stopPropagation","title","_el$0","_tmpl$2","fallback","_tmpl$6","_tmpl$","_$effect","_p$","_v$","copyLabel","_v$2","_$setAttribute","t","undefined","_$runHydrationEvents","_ref$4","_tmpl$4","_$delegateEvents"],"mappings":"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"}
1
+ {"version":3,"file":"ExpandableWrapper.js","sources":["../../src/components/ExpandableWrapper.tsx"],"sourcesContent":["/**\n * ExpandableWrapper - Generic expand/fullscreen wrapper for components\n * v2.2.0: Reusable wrapper that adds expand button + fullscreen modal\n *\n * Uses DOM reparenting to avoid rendering children twice — critical for\n * imperative components like ChartJS that bind instances to DOM nodes.\n */\n\nimport { Component, Show, createSignal, createEffect, onCleanup, JSX, createContext, useContext, Accessor } from 'solid-js'\nimport { Portal } from 'solid-js/web'\n\n/** Context for child components to know if they're in expanded/fullscreen view */\nconst ExpandedContext = createContext<Accessor<boolean>>(() => false)\n\n/** Hook for child components to read expanded state */\nexport const useExpanded = () => useContext(ExpandedContext)\n\nexport interface ExpandableWrapperProps {\n /** Content to render inline (and in expanded view) */\n children: JSX.Element\n /** Title shown in the expanded modal header */\n title?: string\n /** Data string for copy-to-clipboard in expanded view */\n copyData?: string\n /** Label for copy button tooltip */\n copyLabel?: string\n /**\n * Visibility behavior of the inline expand button (v6.3.0 — axe 4 deposium handoff).\n * - `'hover'` (default) : opacity 0, fades to 0.7 on parent group hover.\n * Backwards-compatible — pre-v6.3.0 behavior.\n * - `'always-visible'` : opacity 0.6 permanent, 1 on hover. Use this when\n * the inline button needs to be discoverable without hovering — esp.\n * on touch surfaces and consumer themes where the hover-only pattern\n * hides the affordance.\n */\n toolbarVariant?: 'hover' | 'always-visible'\n}\n\n/**\n * Wraps any component with an expand button (top-right corner).\n * Opens a fullscreen Portal modal. The children's DOM is physically\n * reparented into the modal (not duplicated), so imperative bindings\n * like Chart.js canvas refs stay intact.\n *\n * @example\n * <ExpandableWrapper title=\"Sales Data\" copyData={tsvData}>\n * <TableRenderer ... />\n * </ExpandableWrapper>\n */\nexport const ExpandableWrapper: Component<ExpandableWrapperProps> = (props) => {\n const [isExpanded, setIsExpanded] = createSignal(false)\n const [copied, setCopied] = createSignal(false)\n let dialogRef: HTMLDivElement | undefined\n let contentRef: HTMLDivElement | undefined\n let inlineSlotRef: HTMLDivElement | undefined\n let modalSlotRef: HTMLDivElement | undefined\n\n const handleOpen = () => setIsExpanded(true)\n const handleClose = () => setIsExpanded(false)\n\n // Reparent content DOM between inline and modal slots\n createEffect(() => {\n if (!contentRef) return\n\n if (isExpanded()) {\n // Move content into modal\n modalSlotRef?.appendChild(contentRef)\n } else {\n // Move content back to inline\n inlineSlotRef?.appendChild(contentRef)\n }\n })\n\n // Keyboard: Escape to close\n createEffect(() => {\n if (!isExpanded()) return\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n e.preventDefault()\n handleClose()\n }\n }\n\n document.addEventListener('keydown', onKeyDown)\n onCleanup(() => document.removeEventListener('keydown', onKeyDown))\n })\n\n // Prevent body scroll when expanded\n createEffect(() => {\n if (isExpanded()) {\n const prev = document.body.style.overflow\n document.body.style.overflow = 'hidden'\n // Focus the dialog\n setTimeout(() => dialogRef?.focus(), 10)\n onCleanup(() => {\n document.body.style.overflow = prev\n })\n }\n })\n\n const handleBackdropClick = (e: MouseEvent) => {\n if (e.target === e.currentTarget) handleClose()\n }\n\n const handleCopy = async () => {\n if (!props.copyData) return\n try {\n await navigator.clipboard.writeText(props.copyData)\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n } catch (err) {\n console.error('Failed to copy:', err)\n }\n }\n\n return (\n <div class=\"relative group\">\n {/* Inline slot — content lives here when not expanded */}\n <div ref={inlineSlotRef}>\n <div ref={contentRef}>\n <ExpandedContext.Provider value={isExpanded}>\n {props.children}\n </ExpandedContext.Provider>\n </div>\n </div>\n\n {/* Expand button — visibility per `toolbarVariant` (default 'hover') */}\n <button\n onClick={handleOpen}\n class={`absolute top-2 right-2 z-10 ${\n props.toolbarVariant === 'always-visible'\n ? 'opacity-60 hover:opacity-100'\n : 'opacity-0 group-hover:opacity-70 hover:!opacity-100'\n } p-1.5 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 rounded-full hover:bg-gray-100 dark:hover:bg-gray-700 transition-all shadow-sm`}\n title=\"Expand\"\n aria-label=\"Expand to fullscreen\"\n >\n <svg class=\"w-3.5 h-3.5 text-gray-500 dark:text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5v-4m0 4h-4m4 0l-5-5\" />\n </svg>\n </button>\n\n {/* Fullscreen modal via Portal */}\n <Show when={isExpanded()}>\n <Portal>\n <div\n class=\"fixed inset-0 z-50 flex flex-col bg-black/50 backdrop-blur-sm\"\n style={{ animation: 'expandable-fade-in 0.15s ease-out' }}\n onClick={handleBackdropClick}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={props.title || 'Expanded view'}\n tabIndex={-1}\n ref={dialogRef}\n >\n {/* Modal panel */}\n <div\n class=\"relative flex flex-col m-4 flex-1 bg-white dark:bg-gray-800 rounded-lg shadow-xl overflow-hidden\"\n style={{ animation: 'expandable-scale-in 0.15s ease-out' }}\n onClick={(e) => e.stopPropagation()}\n >\n {/* Header */}\n <div class=\"flex items-center justify-between px-4 py-3 border-b border-gray-200 dark:border-gray-700 flex-shrink-0\">\n <h2 class=\"text-lg font-semibold text-gray-900 dark:text-white truncate\">\n {props.title || 'Expanded View'}\n </h2>\n <div class=\"flex items-center gap-2\">\n {/* Copy button */}\n <Show when={props.copyData}>\n <button\n onClick={handleCopy}\n class=\"p-1.5 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 rounded-full hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors\"\n title={props.copyLabel || 'Copy to clipboard'}\n aria-label={props.copyLabel || 'Copy to clipboard'}\n >\n <Show\n when={!copied()}\n fallback={\n <svg class=\"w-5 h-5 text-green-500\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 13l4 4L19 7\" />\n </svg>\n }\n >\n <svg class=\"w-5 h-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\" />\n </svg>\n </Show>\n </button>\n </Show>\n {/* Close button */}\n <button\n onClick={handleClose}\n class=\"p-1.5 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 rounded-full hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors\"\n aria-label=\"Close expanded view\"\n >\n <svg class=\"w-5 h-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n </div>\n\n {/* Modal slot — content is reparented here when expanded.\n v6.1.0 : `flex flex-col` lets aware children opt into\n `flex-1 min-h-0` to fill the modal vertically (chart,\n table, map, graph). Unaware children keep working\n thanks to `overflow-auto` (their natural height\n scrolls if it overflows the slot). */}\n <div class=\"flex-1 min-h-0 overflow-auto p-4 flex flex-col\" ref={modalSlotRef} />\n </div>\n </div>\n\n <style>{`\n @keyframes expandable-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n @keyframes expandable-scale-in {\n from { opacity: 0; transform: scale(0.97); }\n to { opacity: 1; transform: scale(1); }\n }\n `}</style>\n </Portal>\n </Show>\n </div>\n )\n}\n"],"names":["ExpandedContext","createContext","useExpanded","useContext","ExpandableWrapper","props","isExpanded","setIsExpanded","createSignal","copied","setCopied","dialogRef","contentRef","inlineSlotRef","modalSlotRef","handleOpen","handleClose","createEffect","appendChild","onKeyDown","e","key","preventDefault","document","addEventListener","onCleanup","removeEventListener","prev","body","style","overflow","setTimeout","focus","handleBackdropClick","target","currentTarget","handleCopy","copyData","navigator","clipboard","writeText","err","console","error","_el$","_$getNextElement","_tmpl$5","_el$2","firstChild","_el$3","_el$4","nextSibling","_el$15","_el$16","_co$2","_$getNextMarker","_ref$","_$use","_ref$2","_$insert","_$createComponent","Provider","value","children","$$click","Show","when","Portal","_el$5","_tmpl$3","_el$6","_el$7","_el$8","_el$9","_el$11","_el$12","_co$","_el$10","_el$13","_ref$3","stopPropagation","title","_el$0","_tmpl$2","fallback","_tmpl$6","_tmpl$","_$effect","_p$","_v$","copyLabel","_v$2","_$setAttribute","t","undefined","_$runHydrationEvents","_ref$4","_tmpl$4","_$className","toolbarVariant","_$delegateEvents"],"mappings":"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"}
@@ -3,9 +3,15 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const web = require("solid-js/web");
4
4
  const solidJs = require("solid-js");
5
5
  const LightboxOverlay = require("./LightboxOverlay.cjs");
6
- var _tmpl$ = /* @__PURE__ */ web.template(`<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700"><h3 class="text-sm font-semibold text-gray-900 dark:text-white">`), _tmpl$2 = /* @__PURE__ */ web.template(`<div class="w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden"><!$><!/><div></div><!$><!/>`), _tmpl$3 = /* @__PURE__ */ web.template(`<div class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/70 to-transparent text-white text-xs p-2 pt-4"><span class="truncate block">`), _tmpl$4 = /* @__PURE__ */ web.template(`<div class="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200"><div class="bg-white/90 dark:bg-gray-800/90 rounded-full p-2"><svg class="w-5 h-5 text-gray-700 dark:text-gray-200"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v3m0 0v3m0-3h3m-3 0H7">`), _tmpl$5 = /* @__PURE__ */ web.template(`<button type=button><img class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-200"loading=lazy><div class="absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors duration-200"></div><!$><!/><!$><!/>`, true, false, false);
6
+ const ExpandableWrapper = require("./ExpandableWrapper.cjs");
7
+ var _tmpl$ = /* @__PURE__ */ web.template(`<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700 flex-shrink-0"><h3 class="text-sm font-semibold text-gray-900 dark:text-white">`), _tmpl$2 = /* @__PURE__ */ web.template(`<div><!$><!/><div></div><!$><!/>`), _tmpl$3 = /* @__PURE__ */ web.template(`<div class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/70 to-transparent text-white text-xs p-2 pt-4"><span class="truncate block">`), _tmpl$4 = /* @__PURE__ */ web.template(`<div class="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200"><div class="bg-white/90 dark:bg-gray-800/90 rounded-full p-2"><svg class="w-5 h-5 text-gray-700 dark:text-gray-200"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v3m0 0v3m0-3h3m-3 0H7">`), _tmpl$5 = /* @__PURE__ */ web.template(`<button type=button><img class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-200"loading=lazy><div class="absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors duration-200"></div><!$><!/><!$><!/>`, true, false, false);
8
+ function imagesToTextList(p) {
9
+ if (!p) return "";
10
+ return (p.images ?? []).map((img) => img.caption ? `${img.url} ${img.caption}` : img.url).join("\n");
11
+ }
7
12
  const ImageGalleryRenderer = (props) => {
8
13
  const [selectedIndex, setSelectedIndex] = solidJs.createSignal(null);
14
+ const isExpanded = ExpandableWrapper.useExpanded();
9
15
  const params = () => {
10
16
  var _a;
11
17
  return props.params || ((_a = props.component) == null ? void 0 : _a.params);
@@ -57,82 +63,100 @@ const ImageGalleryRenderer = (props) => {
57
63
  setSelectedIndex(index);
58
64
  }
59
65
  };
60
- return (() => {
61
- var _el$ = web.getNextElement(_tmpl$2), _el$5 = _el$.firstChild, [_el$6, _co$] = web.getNextMarker(_el$5.nextSibling), _el$4 = _el$6.nextSibling, _el$7 = _el$4.nextSibling, [_el$8, _co$2] = web.getNextMarker(_el$7.nextSibling);
62
- web.insert(_el$, web.createComponent(solidJs.Show, {
63
- get when() {
64
- var _a;
65
- return (_a = params()) == null ? void 0 : _a.title;
66
- },
67
- get children() {
68
- var _el$2 = web.getNextElement(_tmpl$), _el$3 = _el$2.firstChild;
69
- web.insert(_el$3, () => params().title);
70
- return _el$2;
71
- }
72
- }), _el$6, _co$);
73
- web.insert(_el$4, web.createComponent(solidJs.For, {
74
- get each() {
75
- var _a;
76
- return (_a = params()) == null ? void 0 : _a.images;
77
- },
78
- children: (image, index) => (() => {
79
- var _el$9 = web.getNextElement(_tmpl$5), _el$0 = _el$9.firstChild, _el$1 = _el$0.nextSibling, _el$13 = _el$1.nextSibling, [_el$14, _co$3] = web.getNextMarker(_el$13.nextSibling), _el$15 = _el$14.nextSibling, [_el$16, _co$4] = web.getNextMarker(_el$15.nextSibling);
80
- _el$9.$$click = () => handleImageClick(index());
81
- web.insert(_el$9, web.createComponent(solidJs.Show, {
82
- get when() {
83
- var _a;
84
- return web.memo(() => !!image.caption)() && ((_a = params()) == null ? void 0 : _a.showCaptions);
85
- },
86
- get children() {
87
- var _el$10 = web.getNextElement(_tmpl$3), _el$11 = _el$10.firstChild;
88
- web.insert(_el$11, () => image.caption);
89
- return _el$10;
90
- }
91
- }), _el$14, _co$3);
92
- web.insert(_el$9, web.createComponent(solidJs.Show, {
93
- get when() {
94
- var _a;
95
- return ((_a = params()) == null ? void 0 : _a.lightbox) !== false;
96
- },
97
- get children() {
98
- return web.getNextElement(_tmpl$4);
99
- }
100
- }), _el$16, _co$4);
101
- web.effect((_p$) => {
102
- var _v$ = `relative overflow-hidden rounded-md focus:ring-2 focus:ring-blue-500 focus:outline-none group ${aspectClass()}`, _v$2 = image.alt || `View image ${index() + 1}`, _v$3 = image.thumbnail || image.url, _v$4 = image.alt || `Image ${index() + 1}`, _v$5 = image.srcset, _v$6 = image.sizes;
103
- _v$ !== _p$.e && web.className(_el$9, _p$.e = _v$);
104
- _v$2 !== _p$.t && web.setAttribute(_el$9, "aria-label", _p$.t = _v$2);
105
- _v$3 !== _p$.a && web.setAttribute(_el$0, "src", _p$.a = _v$3);
106
- _v$4 !== _p$.o && web.setAttribute(_el$0, "alt", _p$.o = _v$4);
107
- _v$5 !== _p$.i && web.setAttribute(_el$0, "srcset", _p$.i = _v$5);
108
- _v$6 !== _p$.n && web.setAttribute(_el$0, "sizes", _p$.n = _v$6);
109
- return _p$;
110
- }, {
111
- e: void 0,
112
- t: void 0,
113
- a: void 0,
114
- o: void 0,
115
- i: void 0,
116
- n: void 0
117
- });
118
- web.runHydrationEvents();
119
- return _el$9;
120
- })()
121
- }));
122
- web.insert(_el$, web.createComponent(LightboxOverlay.LightboxOverlay, {
123
- get images() {
124
- var _a;
125
- return ((_a = params()) == null ? void 0 : _a.images) || [];
126
- },
127
- get selectedIndex() {
128
- return selectedIndex();
129
- },
130
- onClose: () => setSelectedIndex(null),
131
- onNavigate: setSelectedIndex
132
- }), _el$8, _co$2);
133
- web.effect(() => web.className(_el$4, `grid ${columnsClass()} ${gapClass()} p-4`));
134
- return _el$;
135
- })();
66
+ return web.createComponent(ExpandableWrapper.ExpandableWrapper, {
67
+ get title() {
68
+ var _a;
69
+ return ((_a = params()) == null ? void 0 : _a.title) || "Gallery";
70
+ },
71
+ get copyData() {
72
+ return imagesToTextList(params());
73
+ },
74
+ copyLabel: "Copy image URLs",
75
+ get children() {
76
+ var _el$ = web.getNextElement(_tmpl$2), _el$5 = _el$.firstChild, [_el$6, _co$] = web.getNextMarker(_el$5.nextSibling), _el$4 = _el$6.nextSibling, _el$7 = _el$4.nextSibling, [_el$8, _co$2] = web.getNextMarker(_el$7.nextSibling);
77
+ web.insert(_el$, web.createComponent(solidJs.Show, {
78
+ get when() {
79
+ var _a;
80
+ return (_a = params()) == null ? void 0 : _a.title;
81
+ },
82
+ get children() {
83
+ var _el$2 = web.getNextElement(_tmpl$), _el$3 = _el$2.firstChild;
84
+ web.insert(_el$3, () => params().title);
85
+ return _el$2;
86
+ }
87
+ }), _el$6, _co$);
88
+ web.insert(_el$4, web.createComponent(solidJs.For, {
89
+ get each() {
90
+ var _a;
91
+ return (_a = params()) == null ? void 0 : _a.images;
92
+ },
93
+ children: (image, index) => (() => {
94
+ var _el$9 = web.getNextElement(_tmpl$5), _el$0 = _el$9.firstChild, _el$1 = _el$0.nextSibling, _el$13 = _el$1.nextSibling, [_el$14, _co$3] = web.getNextMarker(_el$13.nextSibling), _el$15 = _el$14.nextSibling, [_el$16, _co$4] = web.getNextMarker(_el$15.nextSibling);
95
+ _el$9.$$click = () => handleImageClick(index());
96
+ web.insert(_el$9, web.createComponent(solidJs.Show, {
97
+ get when() {
98
+ var _a;
99
+ return web.memo(() => !!image.caption)() && ((_a = params()) == null ? void 0 : _a.showCaptions);
100
+ },
101
+ get children() {
102
+ var _el$10 = web.getNextElement(_tmpl$3), _el$11 = _el$10.firstChild;
103
+ web.insert(_el$11, () => image.caption);
104
+ return _el$10;
105
+ }
106
+ }), _el$14, _co$3);
107
+ web.insert(_el$9, web.createComponent(solidJs.Show, {
108
+ get when() {
109
+ var _a;
110
+ return ((_a = params()) == null ? void 0 : _a.lightbox) !== false;
111
+ },
112
+ get children() {
113
+ return web.getNextElement(_tmpl$4);
114
+ }
115
+ }), _el$16, _co$4);
116
+ web.effect((_p$) => {
117
+ var _v$3 = `relative overflow-hidden rounded-md focus:ring-2 focus:ring-blue-500 focus:outline-none group ${aspectClass()}`, _v$4 = image.alt || `View image ${index() + 1}`, _v$5 = image.thumbnail || image.url, _v$6 = image.alt || `Image ${index() + 1}`, _v$7 = image.srcset, _v$8 = image.sizes;
118
+ _v$3 !== _p$.e && web.className(_el$9, _p$.e = _v$3);
119
+ _v$4 !== _p$.t && web.setAttribute(_el$9, "aria-label", _p$.t = _v$4);
120
+ _v$5 !== _p$.a && web.setAttribute(_el$0, "src", _p$.a = _v$5);
121
+ _v$6 !== _p$.o && web.setAttribute(_el$0, "alt", _p$.o = _v$6);
122
+ _v$7 !== _p$.i && web.setAttribute(_el$0, "srcset", _p$.i = _v$7);
123
+ _v$8 !== _p$.n && web.setAttribute(_el$0, "sizes", _p$.n = _v$8);
124
+ return _p$;
125
+ }, {
126
+ e: void 0,
127
+ t: void 0,
128
+ a: void 0,
129
+ o: void 0,
130
+ i: void 0,
131
+ n: void 0
132
+ });
133
+ web.runHydrationEvents();
134
+ return _el$9;
135
+ })()
136
+ }));
137
+ web.insert(_el$, web.createComponent(LightboxOverlay.LightboxOverlay, {
138
+ get images() {
139
+ var _a;
140
+ return ((_a = params()) == null ? void 0 : _a.images) || [];
141
+ },
142
+ get selectedIndex() {
143
+ return selectedIndex();
144
+ },
145
+ onClose: () => setSelectedIndex(null),
146
+ onNavigate: setSelectedIndex
147
+ }), _el$8, _co$2);
148
+ web.effect((_p$) => {
149
+ var _v$ = `w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden ${isExpanded() ? "flex-1 min-h-0 flex flex-col" : ""}`, _v$2 = `grid ${columnsClass()} ${gapClass()} p-4 ${isExpanded() ? "flex-1 min-h-0 overflow-auto" : ""}`;
150
+ _v$ !== _p$.e && web.className(_el$, _p$.e = _v$);
151
+ _v$2 !== _p$.t && web.className(_el$4, _p$.t = _v$2);
152
+ return _p$;
153
+ }, {
154
+ e: void 0,
155
+ t: void 0
156
+ });
157
+ return _el$;
158
+ }
159
+ });
136
160
  };
137
161
  web.delegateEvents(["click"]);
138
162
  exports.ImageGalleryRenderer = ImageGalleryRenderer;
@@ -1 +1 @@
1
- {"version":3,"file":"ImageGalleryRenderer.cjs","sources":["../../src/components/ImageGalleryRenderer.tsx"],"sourcesContent":["/**\n * ImageGalleryRenderer - Gallery view for multiple images\n * Sprint 5: Media Components\n */\n\nimport { Component, createSignal, For, Show } from 'solid-js'\nimport type { UIComponent, ImageGalleryParams } from '../types'\nimport { LightboxOverlay } from './LightboxOverlay'\n\nexport interface ImageGalleryRendererProps {\n /**\n * UIComponent containing gallery params\n */\n component?: UIComponent\n\n /**\n * Direct gallery params (alternative to component)\n */\n params?: ImageGalleryParams\n}\n\nexport const ImageGalleryRenderer: Component<ImageGalleryRendererProps> = (props) => {\n const [selectedIndex, setSelectedIndex] = createSignal<number | null>(null)\n\n const params = () => props.params || (props.component?.params as ImageGalleryParams)\n\n const columnsClass = () => {\n switch (params()?.columns) {\n case 2:\n return 'grid-cols-2'\n case 3:\n return 'grid-cols-3'\n case 4:\n return 'grid-cols-4'\n case 5:\n return 'grid-cols-5'\n default:\n return 'grid-cols-3'\n }\n }\n\n const gapClass = () => {\n switch (params()?.gap) {\n case 'none':\n return 'gap-0'\n case 'sm':\n return 'gap-1'\n case 'lg':\n return 'gap-4'\n default:\n return 'gap-2'\n }\n }\n\n const aspectClass = () => {\n switch (params()?.aspectRatio) {\n case '1:1':\n return 'aspect-square'\n case '16:9':\n return 'aspect-video'\n case '4:3':\n return 'aspect-[4/3]'\n default:\n return ''\n }\n }\n\n const handleImageClick = (index: number) => {\n if (params()?.lightbox !== false) {\n setSelectedIndex(index)\n }\n }\n\n return (\n <div class=\"w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden\">\n {/* Title */}\n <Show when={params()?.title}>\n <div class=\"px-4 py-3 border-b border-gray-200 dark:border-gray-700\">\n <h3 class=\"text-sm font-semibold text-gray-900 dark:text-white\">{params()!.title}</h3>\n </div>\n </Show>\n\n {/* Gallery Grid */}\n <div class={`grid ${columnsClass()} ${gapClass()} p-4`}>\n <For each={params()?.images}>\n {(image, index) => (\n <button\n class={`relative overflow-hidden rounded-md focus:ring-2 focus:ring-blue-500 focus:outline-none group ${aspectClass()}`}\n onClick={() => handleImageClick(index())}\n type=\"button\"\n aria-label={image.alt || `View image ${index() + 1}`}\n >\n <img\n src={image.thumbnail || image.url}\n alt={image.alt || `Image ${index() + 1}`}\n srcset={image.srcset}\n sizes={image.sizes}\n class=\"w-full h-full object-cover group-hover:scale-105 transition-transform duration-200\"\n loading=\"lazy\"\n />\n\n {/* Hover overlay */}\n <div class=\"absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors duration-200\" />\n\n {/* Caption overlay */}\n <Show when={image.caption && params()?.showCaptions}>\n <div class=\"absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/70 to-transparent text-white text-xs p-2 pt-4\">\n <span class=\"truncate block\">{image.caption}</span>\n </div>\n </Show>\n\n {/* Zoom icon on hover */}\n <Show when={params()?.lightbox !== false}>\n <div class=\"absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200\">\n <div class=\"bg-white/90 dark:bg-gray-800/90 rounded-full p-2\">\n <svg\n class=\"w-5 h-5 text-gray-700 dark:text-gray-200\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v3m0 0v3m0-3h3m-3 0H7\"\n />\n </svg>\n </div>\n </div>\n </Show>\n </button>\n )}\n </For>\n </div>\n\n {/* Lightbox */}\n <LightboxOverlay\n images={params()?.images || []}\n selectedIndex={selectedIndex()}\n onClose={() => setSelectedIndex(null)}\n onNavigate={setSelectedIndex}\n />\n </div>\n )\n}\n"],"names":["ImageGalleryRenderer","props","selectedIndex","setSelectedIndex","createSignal","params","component","columnsClass","columns","gapClass","gap","aspectClass","aspectRatio","handleImageClick","index","lightbox","_el$","_$getNextElement","_tmpl$2","_el$5","firstChild","_el$6","_co$","_$getNextMarker","nextSibling","_el$4","_el$7","_el$8","_co$2","_$insert","_$createComponent","Show","when","title","children","_el$2","_tmpl$","_el$3","For","each","images","image","_el$9","_tmpl$5","_el$0","_el$1","_el$13","_el$14","_co$3","_el$15","_el$16","_co$4","$$click","_$memo","caption","showCaptions","_el$10","_tmpl$3","_el$11","_tmpl$4","_$effect","_p$","_v$","_v$2","alt","_v$3","thumbnail","url","_v$4","_v$5","srcset","_v$6","sizes","e","_$className","t","_$setAttribute","a","o","i","n","undefined","_$runHydrationEvents","LightboxOverlay","onClose","onNavigate","_$delegateEvents"],"mappings":"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"}
1
+ {"version":3,"file":"ImageGalleryRenderer.cjs","sources":["../../src/components/ImageGalleryRenderer.tsx"],"sourcesContent":["/**\n * ImageGalleryRenderer - Gallery view for multiple images\n * Sprint 5: Media Components\n */\n\nimport { Component, createSignal, For, Show } from 'solid-js'\nimport type { UIComponent, ImageGalleryParams } from '../types'\nimport { LightboxOverlay } from './LightboxOverlay'\nimport { ExpandableWrapper, useExpanded } from './ExpandableWrapper'\n\nexport interface ImageGalleryRendererProps {\n /**\n * UIComponent containing gallery params\n */\n component?: UIComponent\n\n /**\n * Direct gallery params (alternative to component)\n */\n params?: ImageGalleryParams\n}\n\n/** Build a newline-separated list of image URLs (with captions when present)\n * for the ExpandableWrapper copy button. v6.2.0. */\nfunction imagesToTextList(p: ImageGalleryParams | undefined): string {\n if (!p) return ''\n return (p.images ?? [])\n .map((img) => (img.caption ? `${img.url}\\t${img.caption}` : img.url))\n .join('\\n')\n}\n\nexport const ImageGalleryRenderer: Component<ImageGalleryRendererProps> = (props) => {\n const [selectedIndex, setSelectedIndex] = createSignal<number | null>(null)\n const isExpanded = useExpanded()\n\n const params = () => props.params || (props.component?.params as ImageGalleryParams)\n\n const columnsClass = () => {\n switch (params()?.columns) {\n case 2:\n return 'grid-cols-2'\n case 3:\n return 'grid-cols-3'\n case 4:\n return 'grid-cols-4'\n case 5:\n return 'grid-cols-5'\n default:\n return 'grid-cols-3'\n }\n }\n\n const gapClass = () => {\n switch (params()?.gap) {\n case 'none':\n return 'gap-0'\n case 'sm':\n return 'gap-1'\n case 'lg':\n return 'gap-4'\n default:\n return 'gap-2'\n }\n }\n\n const aspectClass = () => {\n switch (params()?.aspectRatio) {\n case '1:1':\n return 'aspect-square'\n case '16:9':\n return 'aspect-video'\n case '4:3':\n return 'aspect-[4/3]'\n default:\n return ''\n }\n }\n\n const handleImageClick = (index: number) => {\n if (params()?.lightbox !== false) {\n setSelectedIndex(index)\n }\n }\n\n return (\n <ExpandableWrapper\n title={params()?.title || 'Gallery'}\n copyData={imagesToTextList(params())}\n copyLabel=\"Copy image URLs\"\n >\n <div class={`w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden ${\n isExpanded() ? 'flex-1 min-h-0 flex flex-col' : ''\n }`}>\n {/* Title */}\n <Show when={params()?.title}>\n <div class=\"px-4 py-3 border-b border-gray-200 dark:border-gray-700 flex-shrink-0\">\n <h3 class=\"text-sm font-semibold text-gray-900 dark:text-white\">{params()!.title}</h3>\n </div>\n </Show>\n\n {/* Gallery Grid */}\n <div class={`grid ${columnsClass()} ${gapClass()} p-4 ${isExpanded() ? 'flex-1 min-h-0 overflow-auto' : ''}`}>\n <For each={params()?.images}>\n {(image, index) => (\n <button\n class={`relative overflow-hidden rounded-md focus:ring-2 focus:ring-blue-500 focus:outline-none group ${aspectClass()}`}\n onClick={() => handleImageClick(index())}\n type=\"button\"\n aria-label={image.alt || `View image ${index() + 1}`}\n >\n <img\n src={image.thumbnail || image.url}\n alt={image.alt || `Image ${index() + 1}`}\n srcset={image.srcset}\n sizes={image.sizes}\n class=\"w-full h-full object-cover group-hover:scale-105 transition-transform duration-200\"\n loading=\"lazy\"\n />\n\n {/* Hover overlay */}\n <div class=\"absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors duration-200\" />\n\n {/* Caption overlay */}\n <Show when={image.caption && params()?.showCaptions}>\n <div class=\"absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/70 to-transparent text-white text-xs p-2 pt-4\">\n <span class=\"truncate block\">{image.caption}</span>\n </div>\n </Show>\n\n {/* Zoom icon on hover */}\n <Show when={params()?.lightbox !== false}>\n <div class=\"absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200\">\n <div class=\"bg-white/90 dark:bg-gray-800/90 rounded-full p-2\">\n <svg\n class=\"w-5 h-5 text-gray-700 dark:text-gray-200\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v3m0 0v3m0-3h3m-3 0H7\"\n />\n </svg>\n </div>\n </div>\n </Show>\n </button>\n )}\n </For>\n </div>\n\n {/* Lightbox */}\n <LightboxOverlay\n images={params()?.images || []}\n selectedIndex={selectedIndex()}\n onClose={() => setSelectedIndex(null)}\n onNavigate={setSelectedIndex}\n />\n </div>\n </ExpandableWrapper>\n )\n}\n"],"names":["imagesToTextList","p","images","map","img","caption","url","join","ImageGalleryRenderer","props","selectedIndex","setSelectedIndex","createSignal","isExpanded","useExpanded","params","component","columnsClass","columns","gapClass","gap","aspectClass","aspectRatio","handleImageClick","index","lightbox","_$createComponent","ExpandableWrapper","title","copyData","copyLabel","children","_el$","_$getNextElement","_tmpl$2","_el$5","firstChild","_el$6","_co$","_$getNextMarker","nextSibling","_el$4","_el$7","_el$8","_co$2","_$insert","Show","when","_el$2","_tmpl$","_el$3","For","each","image","_el$9","_tmpl$5","_el$0","_el$1","_el$13","_el$14","_co$3","_el$15","_el$16","_co$4","$$click","_$memo","showCaptions","_el$10","_tmpl$3","_el$11","_tmpl$4","_$effect","_p$","_v$3","_v$4","alt","_v$5","thumbnail","_v$6","_v$7","srcset","_v$8","sizes","e","_$className","t","_$setAttribute","a","o","i","n","undefined","_$runHydrationEvents","LightboxOverlay","onClose","onNavigate","_v$","_v$2","_$delegateEvents"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ImageGalleryRenderer.d.ts","sourceRoot":"","sources":["../../src/components/ImageGalleryRenderer.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAA2B,MAAM,UAAU,CAAA;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAG/D,MAAM,WAAW,yBAAyB;IACxC;;OAEG;IACH,SAAS,CAAC,EAAE,WAAW,CAAA;IAEvB;;OAEG;IACH,MAAM,CAAC,EAAE,kBAAkB,CAAA;CAC5B;AAED,eAAO,MAAM,oBAAoB,EAAE,SAAS,CAAC,yBAAyB,CA4HrE,CAAA"}
1
+ {"version":3,"file":"ImageGalleryRenderer.d.ts","sourceRoot":"","sources":["../../src/components/ImageGalleryRenderer.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAA2B,MAAM,UAAU,CAAA;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAI/D,MAAM,WAAW,yBAAyB;IACxC;;OAEG;IACH,SAAS,CAAC,EAAE,WAAW,CAAA;IAEvB;;OAEG;IACH,MAAM,CAAC,EAAE,kBAAkB,CAAA;CAC5B;AAWD,eAAO,MAAM,oBAAoB,EAAE,SAAS,CAAC,yBAAyB,CAqIrE,CAAA"}
@@ -1,9 +1,15 @@
1
- import { delegateEvents, getNextElement, template, getNextMarker, insert, createComponent, memo, effect, className, setAttribute, runHydrationEvents } from "solid-js/web";
1
+ import { delegateEvents, createComponent, getNextElement, template, getNextMarker, insert, memo, effect, className, setAttribute, runHydrationEvents } from "solid-js/web";
2
2
  import { createSignal, Show, For } from "solid-js";
3
3
  import { LightboxOverlay } from "./LightboxOverlay.js";
4
- var _tmpl$ = /* @__PURE__ */ template(`<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700"><h3 class="text-sm font-semibold text-gray-900 dark:text-white">`), _tmpl$2 = /* @__PURE__ */ template(`<div class="w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden"><!$><!/><div></div><!$><!/>`), _tmpl$3 = /* @__PURE__ */ template(`<div class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/70 to-transparent text-white text-xs p-2 pt-4"><span class="truncate block">`), _tmpl$4 = /* @__PURE__ */ template(`<div class="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200"><div class="bg-white/90 dark:bg-gray-800/90 rounded-full p-2"><svg class="w-5 h-5 text-gray-700 dark:text-gray-200"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v3m0 0v3m0-3h3m-3 0H7">`), _tmpl$5 = /* @__PURE__ */ template(`<button type=button><img class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-200"loading=lazy><div class="absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors duration-200"></div><!$><!/><!$><!/>`, true, false, false);
4
+ import { useExpanded, ExpandableWrapper } from "./ExpandableWrapper.js";
5
+ var _tmpl$ = /* @__PURE__ */ template(`<div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700 flex-shrink-0"><h3 class="text-sm font-semibold text-gray-900 dark:text-white">`), _tmpl$2 = /* @__PURE__ */ template(`<div><!$><!/><div></div><!$><!/>`), _tmpl$3 = /* @__PURE__ */ template(`<div class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/70 to-transparent text-white text-xs p-2 pt-4"><span class="truncate block">`), _tmpl$4 = /* @__PURE__ */ template(`<div class="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200"><div class="bg-white/90 dark:bg-gray-800/90 rounded-full p-2"><svg class="w-5 h-5 text-gray-700 dark:text-gray-200"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v3m0 0v3m0-3h3m-3 0H7">`), _tmpl$5 = /* @__PURE__ */ template(`<button type=button><img class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-200"loading=lazy><div class="absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors duration-200"></div><!$><!/><!$><!/>`, true, false, false);
6
+ function imagesToTextList(p) {
7
+ if (!p) return "";
8
+ return (p.images ?? []).map((img) => img.caption ? `${img.url} ${img.caption}` : img.url).join("\n");
9
+ }
5
10
  const ImageGalleryRenderer = (props) => {
6
11
  const [selectedIndex, setSelectedIndex] = createSignal(null);
12
+ const isExpanded = useExpanded();
7
13
  const params = () => {
8
14
  var _a;
9
15
  return props.params || ((_a = props.component) == null ? void 0 : _a.params);
@@ -55,82 +61,100 @@ const ImageGalleryRenderer = (props) => {
55
61
  setSelectedIndex(index);
56
62
  }
57
63
  };
58
- return (() => {
59
- var _el$ = getNextElement(_tmpl$2), _el$5 = _el$.firstChild, [_el$6, _co$] = getNextMarker(_el$5.nextSibling), _el$4 = _el$6.nextSibling, _el$7 = _el$4.nextSibling, [_el$8, _co$2] = getNextMarker(_el$7.nextSibling);
60
- insert(_el$, createComponent(Show, {
61
- get when() {
62
- var _a;
63
- return (_a = params()) == null ? void 0 : _a.title;
64
- },
65
- get children() {
66
- var _el$2 = getNextElement(_tmpl$), _el$3 = _el$2.firstChild;
67
- insert(_el$3, () => params().title);
68
- return _el$2;
69
- }
70
- }), _el$6, _co$);
71
- insert(_el$4, createComponent(For, {
72
- get each() {
73
- var _a;
74
- return (_a = params()) == null ? void 0 : _a.images;
75
- },
76
- children: (image, index) => (() => {
77
- var _el$9 = getNextElement(_tmpl$5), _el$0 = _el$9.firstChild, _el$1 = _el$0.nextSibling, _el$13 = _el$1.nextSibling, [_el$14, _co$3] = getNextMarker(_el$13.nextSibling), _el$15 = _el$14.nextSibling, [_el$16, _co$4] = getNextMarker(_el$15.nextSibling);
78
- _el$9.$$click = () => handleImageClick(index());
79
- insert(_el$9, createComponent(Show, {
80
- get when() {
81
- var _a;
82
- return memo(() => !!image.caption)() && ((_a = params()) == null ? void 0 : _a.showCaptions);
83
- },
84
- get children() {
85
- var _el$10 = getNextElement(_tmpl$3), _el$11 = _el$10.firstChild;
86
- insert(_el$11, () => image.caption);
87
- return _el$10;
88
- }
89
- }), _el$14, _co$3);
90
- insert(_el$9, createComponent(Show, {
91
- get when() {
92
- var _a;
93
- return ((_a = params()) == null ? void 0 : _a.lightbox) !== false;
94
- },
95
- get children() {
96
- return getNextElement(_tmpl$4);
97
- }
98
- }), _el$16, _co$4);
99
- effect((_p$) => {
100
- var _v$ = `relative overflow-hidden rounded-md focus:ring-2 focus:ring-blue-500 focus:outline-none group ${aspectClass()}`, _v$2 = image.alt || `View image ${index() + 1}`, _v$3 = image.thumbnail || image.url, _v$4 = image.alt || `Image ${index() + 1}`, _v$5 = image.srcset, _v$6 = image.sizes;
101
- _v$ !== _p$.e && className(_el$9, _p$.e = _v$);
102
- _v$2 !== _p$.t && setAttribute(_el$9, "aria-label", _p$.t = _v$2);
103
- _v$3 !== _p$.a && setAttribute(_el$0, "src", _p$.a = _v$3);
104
- _v$4 !== _p$.o && setAttribute(_el$0, "alt", _p$.o = _v$4);
105
- _v$5 !== _p$.i && setAttribute(_el$0, "srcset", _p$.i = _v$5);
106
- _v$6 !== _p$.n && setAttribute(_el$0, "sizes", _p$.n = _v$6);
107
- return _p$;
108
- }, {
109
- e: void 0,
110
- t: void 0,
111
- a: void 0,
112
- o: void 0,
113
- i: void 0,
114
- n: void 0
115
- });
116
- runHydrationEvents();
117
- return _el$9;
118
- })()
119
- }));
120
- insert(_el$, createComponent(LightboxOverlay, {
121
- get images() {
122
- var _a;
123
- return ((_a = params()) == null ? void 0 : _a.images) || [];
124
- },
125
- get selectedIndex() {
126
- return selectedIndex();
127
- },
128
- onClose: () => setSelectedIndex(null),
129
- onNavigate: setSelectedIndex
130
- }), _el$8, _co$2);
131
- effect(() => className(_el$4, `grid ${columnsClass()} ${gapClass()} p-4`));
132
- return _el$;
133
- })();
64
+ return createComponent(ExpandableWrapper, {
65
+ get title() {
66
+ var _a;
67
+ return ((_a = params()) == null ? void 0 : _a.title) || "Gallery";
68
+ },
69
+ get copyData() {
70
+ return imagesToTextList(params());
71
+ },
72
+ copyLabel: "Copy image URLs",
73
+ get children() {
74
+ var _el$ = getNextElement(_tmpl$2), _el$5 = _el$.firstChild, [_el$6, _co$] = getNextMarker(_el$5.nextSibling), _el$4 = _el$6.nextSibling, _el$7 = _el$4.nextSibling, [_el$8, _co$2] = getNextMarker(_el$7.nextSibling);
75
+ insert(_el$, createComponent(Show, {
76
+ get when() {
77
+ var _a;
78
+ return (_a = params()) == null ? void 0 : _a.title;
79
+ },
80
+ get children() {
81
+ var _el$2 = getNextElement(_tmpl$), _el$3 = _el$2.firstChild;
82
+ insert(_el$3, () => params().title);
83
+ return _el$2;
84
+ }
85
+ }), _el$6, _co$);
86
+ insert(_el$4, createComponent(For, {
87
+ get each() {
88
+ var _a;
89
+ return (_a = params()) == null ? void 0 : _a.images;
90
+ },
91
+ children: (image, index) => (() => {
92
+ var _el$9 = getNextElement(_tmpl$5), _el$0 = _el$9.firstChild, _el$1 = _el$0.nextSibling, _el$13 = _el$1.nextSibling, [_el$14, _co$3] = getNextMarker(_el$13.nextSibling), _el$15 = _el$14.nextSibling, [_el$16, _co$4] = getNextMarker(_el$15.nextSibling);
93
+ _el$9.$$click = () => handleImageClick(index());
94
+ insert(_el$9, createComponent(Show, {
95
+ get when() {
96
+ var _a;
97
+ return memo(() => !!image.caption)() && ((_a = params()) == null ? void 0 : _a.showCaptions);
98
+ },
99
+ get children() {
100
+ var _el$10 = getNextElement(_tmpl$3), _el$11 = _el$10.firstChild;
101
+ insert(_el$11, () => image.caption);
102
+ return _el$10;
103
+ }
104
+ }), _el$14, _co$3);
105
+ insert(_el$9, createComponent(Show, {
106
+ get when() {
107
+ var _a;
108
+ return ((_a = params()) == null ? void 0 : _a.lightbox) !== false;
109
+ },
110
+ get children() {
111
+ return getNextElement(_tmpl$4);
112
+ }
113
+ }), _el$16, _co$4);
114
+ effect((_p$) => {
115
+ var _v$3 = `relative overflow-hidden rounded-md focus:ring-2 focus:ring-blue-500 focus:outline-none group ${aspectClass()}`, _v$4 = image.alt || `View image ${index() + 1}`, _v$5 = image.thumbnail || image.url, _v$6 = image.alt || `Image ${index() + 1}`, _v$7 = image.srcset, _v$8 = image.sizes;
116
+ _v$3 !== _p$.e && className(_el$9, _p$.e = _v$3);
117
+ _v$4 !== _p$.t && setAttribute(_el$9, "aria-label", _p$.t = _v$4);
118
+ _v$5 !== _p$.a && setAttribute(_el$0, "src", _p$.a = _v$5);
119
+ _v$6 !== _p$.o && setAttribute(_el$0, "alt", _p$.o = _v$6);
120
+ _v$7 !== _p$.i && setAttribute(_el$0, "srcset", _p$.i = _v$7);
121
+ _v$8 !== _p$.n && setAttribute(_el$0, "sizes", _p$.n = _v$8);
122
+ return _p$;
123
+ }, {
124
+ e: void 0,
125
+ t: void 0,
126
+ a: void 0,
127
+ o: void 0,
128
+ i: void 0,
129
+ n: void 0
130
+ });
131
+ runHydrationEvents();
132
+ return _el$9;
133
+ })()
134
+ }));
135
+ insert(_el$, createComponent(LightboxOverlay, {
136
+ get images() {
137
+ var _a;
138
+ return ((_a = params()) == null ? void 0 : _a.images) || [];
139
+ },
140
+ get selectedIndex() {
141
+ return selectedIndex();
142
+ },
143
+ onClose: () => setSelectedIndex(null),
144
+ onNavigate: setSelectedIndex
145
+ }), _el$8, _co$2);
146
+ effect((_p$) => {
147
+ var _v$ = `w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden ${isExpanded() ? "flex-1 min-h-0 flex flex-col" : ""}`, _v$2 = `grid ${columnsClass()} ${gapClass()} p-4 ${isExpanded() ? "flex-1 min-h-0 overflow-auto" : ""}`;
148
+ _v$ !== _p$.e && className(_el$, _p$.e = _v$);
149
+ _v$2 !== _p$.t && className(_el$4, _p$.t = _v$2);
150
+ return _p$;
151
+ }, {
152
+ e: void 0,
153
+ t: void 0
154
+ });
155
+ return _el$;
156
+ }
157
+ });
134
158
  };
135
159
  delegateEvents(["click"]);
136
160
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"ImageGalleryRenderer.js","sources":["../../src/components/ImageGalleryRenderer.tsx"],"sourcesContent":["/**\n * ImageGalleryRenderer - Gallery view for multiple images\n * Sprint 5: Media Components\n */\n\nimport { Component, createSignal, For, Show } from 'solid-js'\nimport type { UIComponent, ImageGalleryParams } from '../types'\nimport { LightboxOverlay } from './LightboxOverlay'\n\nexport interface ImageGalleryRendererProps {\n /**\n * UIComponent containing gallery params\n */\n component?: UIComponent\n\n /**\n * Direct gallery params (alternative to component)\n */\n params?: ImageGalleryParams\n}\n\nexport const ImageGalleryRenderer: Component<ImageGalleryRendererProps> = (props) => {\n const [selectedIndex, setSelectedIndex] = createSignal<number | null>(null)\n\n const params = () => props.params || (props.component?.params as ImageGalleryParams)\n\n const columnsClass = () => {\n switch (params()?.columns) {\n case 2:\n return 'grid-cols-2'\n case 3:\n return 'grid-cols-3'\n case 4:\n return 'grid-cols-4'\n case 5:\n return 'grid-cols-5'\n default:\n return 'grid-cols-3'\n }\n }\n\n const gapClass = () => {\n switch (params()?.gap) {\n case 'none':\n return 'gap-0'\n case 'sm':\n return 'gap-1'\n case 'lg':\n return 'gap-4'\n default:\n return 'gap-2'\n }\n }\n\n const aspectClass = () => {\n switch (params()?.aspectRatio) {\n case '1:1':\n return 'aspect-square'\n case '16:9':\n return 'aspect-video'\n case '4:3':\n return 'aspect-[4/3]'\n default:\n return ''\n }\n }\n\n const handleImageClick = (index: number) => {\n if (params()?.lightbox !== false) {\n setSelectedIndex(index)\n }\n }\n\n return (\n <div class=\"w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden\">\n {/* Title */}\n <Show when={params()?.title}>\n <div class=\"px-4 py-3 border-b border-gray-200 dark:border-gray-700\">\n <h3 class=\"text-sm font-semibold text-gray-900 dark:text-white\">{params()!.title}</h3>\n </div>\n </Show>\n\n {/* Gallery Grid */}\n <div class={`grid ${columnsClass()} ${gapClass()} p-4`}>\n <For each={params()?.images}>\n {(image, index) => (\n <button\n class={`relative overflow-hidden rounded-md focus:ring-2 focus:ring-blue-500 focus:outline-none group ${aspectClass()}`}\n onClick={() => handleImageClick(index())}\n type=\"button\"\n aria-label={image.alt || `View image ${index() + 1}`}\n >\n <img\n src={image.thumbnail || image.url}\n alt={image.alt || `Image ${index() + 1}`}\n srcset={image.srcset}\n sizes={image.sizes}\n class=\"w-full h-full object-cover group-hover:scale-105 transition-transform duration-200\"\n loading=\"lazy\"\n />\n\n {/* Hover overlay */}\n <div class=\"absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors duration-200\" />\n\n {/* Caption overlay */}\n <Show when={image.caption && params()?.showCaptions}>\n <div class=\"absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/70 to-transparent text-white text-xs p-2 pt-4\">\n <span class=\"truncate block\">{image.caption}</span>\n </div>\n </Show>\n\n {/* Zoom icon on hover */}\n <Show when={params()?.lightbox !== false}>\n <div class=\"absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200\">\n <div class=\"bg-white/90 dark:bg-gray-800/90 rounded-full p-2\">\n <svg\n class=\"w-5 h-5 text-gray-700 dark:text-gray-200\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v3m0 0v3m0-3h3m-3 0H7\"\n />\n </svg>\n </div>\n </div>\n </Show>\n </button>\n )}\n </For>\n </div>\n\n {/* Lightbox */}\n <LightboxOverlay\n images={params()?.images || []}\n selectedIndex={selectedIndex()}\n onClose={() => setSelectedIndex(null)}\n onNavigate={setSelectedIndex}\n />\n </div>\n )\n}\n"],"names":["ImageGalleryRenderer","props","selectedIndex","setSelectedIndex","createSignal","params","component","columnsClass","columns","gapClass","gap","aspectClass","aspectRatio","handleImageClick","index","lightbox","_el$","_$getNextElement","_tmpl$2","_el$5","firstChild","_el$6","_co$","_$getNextMarker","nextSibling","_el$4","_el$7","_el$8","_co$2","_$insert","_$createComponent","Show","when","title","children","_el$2","_tmpl$","_el$3","For","each","images","image","_el$9","_tmpl$5","_el$0","_el$1","_el$13","_el$14","_co$3","_el$15","_el$16","_co$4","$$click","_$memo","caption","showCaptions","_el$10","_tmpl$3","_el$11","_tmpl$4","_$effect","_p$","_v$","_v$2","alt","_v$3","thumbnail","url","_v$4","_v$5","srcset","_v$6","sizes","e","_$className","t","_$setAttribute","a","o","i","n","undefined","_$runHydrationEvents","LightboxOverlay","onClose","onNavigate","_$delegateEvents"],"mappings":"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"}
1
+ {"version":3,"file":"ImageGalleryRenderer.js","sources":["../../src/components/ImageGalleryRenderer.tsx"],"sourcesContent":["/**\n * ImageGalleryRenderer - Gallery view for multiple images\n * Sprint 5: Media Components\n */\n\nimport { Component, createSignal, For, Show } from 'solid-js'\nimport type { UIComponent, ImageGalleryParams } from '../types'\nimport { LightboxOverlay } from './LightboxOverlay'\nimport { ExpandableWrapper, useExpanded } from './ExpandableWrapper'\n\nexport interface ImageGalleryRendererProps {\n /**\n * UIComponent containing gallery params\n */\n component?: UIComponent\n\n /**\n * Direct gallery params (alternative to component)\n */\n params?: ImageGalleryParams\n}\n\n/** Build a newline-separated list of image URLs (with captions when present)\n * for the ExpandableWrapper copy button. v6.2.0. */\nfunction imagesToTextList(p: ImageGalleryParams | undefined): string {\n if (!p) return ''\n return (p.images ?? [])\n .map((img) => (img.caption ? `${img.url}\\t${img.caption}` : img.url))\n .join('\\n')\n}\n\nexport const ImageGalleryRenderer: Component<ImageGalleryRendererProps> = (props) => {\n const [selectedIndex, setSelectedIndex] = createSignal<number | null>(null)\n const isExpanded = useExpanded()\n\n const params = () => props.params || (props.component?.params as ImageGalleryParams)\n\n const columnsClass = () => {\n switch (params()?.columns) {\n case 2:\n return 'grid-cols-2'\n case 3:\n return 'grid-cols-3'\n case 4:\n return 'grid-cols-4'\n case 5:\n return 'grid-cols-5'\n default:\n return 'grid-cols-3'\n }\n }\n\n const gapClass = () => {\n switch (params()?.gap) {\n case 'none':\n return 'gap-0'\n case 'sm':\n return 'gap-1'\n case 'lg':\n return 'gap-4'\n default:\n return 'gap-2'\n }\n }\n\n const aspectClass = () => {\n switch (params()?.aspectRatio) {\n case '1:1':\n return 'aspect-square'\n case '16:9':\n return 'aspect-video'\n case '4:3':\n return 'aspect-[4/3]'\n default:\n return ''\n }\n }\n\n const handleImageClick = (index: number) => {\n if (params()?.lightbox !== false) {\n setSelectedIndex(index)\n }\n }\n\n return (\n <ExpandableWrapper\n title={params()?.title || 'Gallery'}\n copyData={imagesToTextList(params())}\n copyLabel=\"Copy image URLs\"\n >\n <div class={`w-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden ${\n isExpanded() ? 'flex-1 min-h-0 flex flex-col' : ''\n }`}>\n {/* Title */}\n <Show when={params()?.title}>\n <div class=\"px-4 py-3 border-b border-gray-200 dark:border-gray-700 flex-shrink-0\">\n <h3 class=\"text-sm font-semibold text-gray-900 dark:text-white\">{params()!.title}</h3>\n </div>\n </Show>\n\n {/* Gallery Grid */}\n <div class={`grid ${columnsClass()} ${gapClass()} p-4 ${isExpanded() ? 'flex-1 min-h-0 overflow-auto' : ''}`}>\n <For each={params()?.images}>\n {(image, index) => (\n <button\n class={`relative overflow-hidden rounded-md focus:ring-2 focus:ring-blue-500 focus:outline-none group ${aspectClass()}`}\n onClick={() => handleImageClick(index())}\n type=\"button\"\n aria-label={image.alt || `View image ${index() + 1}`}\n >\n <img\n src={image.thumbnail || image.url}\n alt={image.alt || `Image ${index() + 1}`}\n srcset={image.srcset}\n sizes={image.sizes}\n class=\"w-full h-full object-cover group-hover:scale-105 transition-transform duration-200\"\n loading=\"lazy\"\n />\n\n {/* Hover overlay */}\n <div class=\"absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors duration-200\" />\n\n {/* Caption overlay */}\n <Show when={image.caption && params()?.showCaptions}>\n <div class=\"absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/70 to-transparent text-white text-xs p-2 pt-4\">\n <span class=\"truncate block\">{image.caption}</span>\n </div>\n </Show>\n\n {/* Zoom icon on hover */}\n <Show when={params()?.lightbox !== false}>\n <div class=\"absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200\">\n <div class=\"bg-white/90 dark:bg-gray-800/90 rounded-full p-2\">\n <svg\n class=\"w-5 h-5 text-gray-700 dark:text-gray-200\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v3m0 0v3m0-3h3m-3 0H7\"\n />\n </svg>\n </div>\n </div>\n </Show>\n </button>\n )}\n </For>\n </div>\n\n {/* Lightbox */}\n <LightboxOverlay\n images={params()?.images || []}\n selectedIndex={selectedIndex()}\n onClose={() => setSelectedIndex(null)}\n onNavigate={setSelectedIndex}\n />\n </div>\n </ExpandableWrapper>\n )\n}\n"],"names":["imagesToTextList","p","images","map","img","caption","url","join","ImageGalleryRenderer","props","selectedIndex","setSelectedIndex","createSignal","isExpanded","useExpanded","params","component","columnsClass","columns","gapClass","gap","aspectClass","aspectRatio","handleImageClick","index","lightbox","_$createComponent","ExpandableWrapper","title","copyData","copyLabel","children","_el$","_$getNextElement","_tmpl$2","_el$5","firstChild","_el$6","_co$","_$getNextMarker","nextSibling","_el$4","_el$7","_el$8","_co$2","_$insert","Show","when","_el$2","_tmpl$","_el$3","For","each","image","_el$9","_tmpl$5","_el$0","_el$1","_el$13","_el$14","_co$3","_el$15","_el$16","_co$4","$$click","_$memo","showCaptions","_el$10","_tmpl$3","_el$11","_tmpl$4","_$effect","_p$","_v$3","_v$4","alt","_v$5","thumbnail","_v$6","_v$7","srcset","_v$8","sizes","e","_$className","t","_$setAttribute","a","o","i","n","undefined","_$runHydrationEvents","LightboxOverlay","onClose","onNavigate","_v$","_v$2","_$delegateEvents"],"mappings":"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"}