{"version":3,"file":"ImageWidget-DZiXnBXp.mjs","names":[],"sources":["../../widgets/src/widgets/ImageWidget.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\";\nimport type React from \"react\";\nimport {\n  getBorderRadiusField,\n  getHeightField,\n  type WidgetPropertySchema,\n} from \"@fluid-app/portal-core/registries\";\nimport type {\n  BorderRadiusOptions,\n  BorderWidthOptions,\n  ColorOptions,\n  ShareableItem,\n} from \"@fluid-app/portal-core/types\";\nimport {\n  getBorderWidthField,\n  getBorderColorField,\n  borderWidthClasses,\n  borderColorClasses,\n} from \"../core/fields\";\nimport { MediaRenderer } from \"../components/MediaRenderer\";\nimport { useWidgetRenderState } from \"../contexts/WidgetRenderStateContext\";\nimport { useLinkAction } from \"../hooks/use-link-action\";\nimport type { LinkType, ShareSource } from \"../lib/link-type-utils\";\nimport { getLinkTypeFields } from \"../lib/link-type-schema-fields\";\n\ntype ImageWidgetProps = ComponentProps<\"div\"> & {\n  src?: string;\n  alt?: string;\n  borderRadius?: BorderRadiusOptions;\n  borderWidth?: BorderWidthOptions;\n  borderColor?: ColorOptions;\n  verticalSizing?: \"auto\" | \"fixed\";\n  fixedHeight?: string;\n  displayFit?: \"cover\" | \"contain\";\n  focusPoint?: string;\n  linkType?: LinkType;\n  href?: string;\n  openInNewTab?: boolean;\n  screenSlug?: string;\n  shareSource?: ShareSource;\n  shareResource?: ShareableItem;\n  shareUrl?: string;\n  /** @deprecated Use href instead. Kept for backward compat with existing widgets. */\n  linkUrl?: string;\n  resource?: ShareableItem;\n  useCustomUrl?: boolean;\n  // Builder render state is provided by WidgetRenderStateContext.\n  editMode?: boolean;\n};\n\nexport function ImageWidget({\n  src = \"\",\n  alt = \"\",\n  borderRadius = \"md\",\n  borderWidth = \"none\",\n  borderColor = \"muted\",\n  verticalSizing = \"auto\",\n  fixedHeight = \"200px\",\n  displayFit = \"cover\",\n  focusPoint,\n  linkType,\n  href,\n  openInNewTab = true,\n  screenSlug,\n  shareSource,\n  shareResource,\n  shareUrl,\n  linkUrl,\n  resource,\n  useCustomUrl,\n  editMode: _editMode,\n}: ImageWidgetProps): React.JSX.Element {\n  const renderState = useWidgetRenderState();\n  const editMode = _editMode ?? renderState.editMode;\n  const effectiveSrc = useCustomUrl ? src : (resource?.imageUrl ?? src);\n  const effectiveAlt = resource?.title ?? alt;\n\n  // Backward compat: only fall back to linkUrl for truly legacy widgets\n  // (linkType absent). Once linkType is set (seeded on first save),\n  // href is authoritative and linkUrl is ignored.\n  const effectiveHref = linkType != null ? (href ?? \"\") : href || linkUrl || \"\";\n\n  const { resolvedHref, handleClick, hasTarget, anchorProps } = useLinkAction({\n    linkType,\n    href: effectiveHref,\n    openInNewTab,\n    screenSlug,\n    shareSource,\n    shareResource,\n    shareUrl,\n  });\n\n  const isFixed = verticalSizing === \"fixed\";\n\n  const content = (\n    <div\n      className={`w-full rounded-${borderRadius} ${borderWidthClasses[borderWidth]} ${borderWidth !== \"none\" ? borderColorClasses[borderColor] : \"\"} overflow-hidden`}\n      style={isFixed ? { height: fixedHeight } : undefined}\n    >\n      <MediaRenderer\n        mediaType=\"image\"\n        src={effectiveSrc}\n        alt={effectiveAlt}\n        objectFit={isFixed ? displayFit : \"contain\"}\n        focusPoint={isFixed ? focusPoint : undefined}\n      />\n    </div>\n  );\n\n  if (editMode || !hasTarget) {\n    return content;\n  }\n\n  if (linkType === \"share\") {\n    return (\n      <button type=\"button\" onClick={handleClick} className=\"cursor-pointer\">\n        {content}\n      </button>\n    );\n  }\n\n  // handleClick handles screen navigation, plus URLs that point back into this\n  // portal; it's a no-op for URLs that lead elsewhere.\n  return (\n    <a href={resolvedHref} onClick={handleClick} {...anchorProps}>\n      {content}\n    </a>\n  );\n}\n\nexport const imageWidgetPropertySchema: WidgetPropertySchema = {\n  widgetType: \"ImageWidget\",\n  displayName: \"Image\",\n  fields: [\n    // Content\n    {\n      key: \"resource\",\n      label: \"Select Image\",\n      type: \"image\",\n      description: \"Browse and select an image\",\n      group: \"Content\",\n    },\n    {\n      key: \"useCustomUrl\",\n      label: \"Use Custom URL\",\n      type: \"boolean\",\n      description: \"Enter a custom image URL instead of selecting media\",\n      defaultValue: false,\n      group: \"Content\",\n    },\n    {\n      key: \"src\",\n      label: \"Image URL\",\n      type: \"text\",\n      description: \"The source URL of the image\",\n      defaultValue:\n        \"https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=800&auto=format&fit=crop\",\n      group: \"Content\",\n      requiresKeyToBeTrue: \"useCustomUrl\",\n    },\n    {\n      key: \"alt\",\n      label: \"Alt Text\",\n      type: \"text\",\n      description: \"Alternative text for the image (for accessibility)\",\n      defaultValue: \"Placeholder image\",\n      group: \"Content\",\n    },\n\n    // Design\n    getBorderRadiusField({\n      key: \"borderRadius\",\n      label: \"Border Radius\",\n      description: \"Border radius for the container\",\n      defaultValue: \"md\",\n      group: \"Design\",\n    }),\n    getBorderWidthField({\n      key: \"borderWidth\",\n      label: \"Border Width\",\n      description: \"Border width for the widget\",\n      defaultValue: \"none\",\n      group: \"Design\",\n    }),\n    getBorderColorField({\n      key: \"borderColor\",\n      label: \"Border Color\",\n      description: \"Border color for the widget\",\n      defaultValue: \"muted\",\n      group: \"Design\",\n    }),\n    {\n      key: \"verticalSizing\",\n      label: \"Vertical Sizing\",\n      type: \"buttonGroup\",\n      description: \"How the image height is determined\",\n      options: [\n        { label: \"Auto\", value: \"auto\" },\n        { label: \"Fixed\", value: \"fixed\" },\n      ],\n      defaultValue: \"auto\",\n      group: \"Design\",\n    },\n    getHeightField({\n      key: \"fixedHeight\",\n      label: \"Height\",\n      description: \"Fixed height of the image container\",\n      defaultValue: \"200px\",\n      group: \"Design\",\n      requiresKeyValue: { key: \"verticalSizing\", value: \"fixed\" },\n    }),\n    {\n      key: \"displayFit\",\n      label: \"Display Fit\",\n      type: \"buttonGroup\",\n      description: \"How the image fills its container\",\n      options: [\n        { label: \"Cover\", value: \"cover\" },\n        { label: \"Contain\", value: \"contain\" },\n      ],\n      defaultValue: \"cover\",\n      group: \"Design\",\n      requiresKeyValue: { key: \"verticalSizing\", value: \"fixed\" },\n    },\n    {\n      key: \"focusPoint\",\n      label: \"Focus Point\",\n      type: \"contentPosition\",\n      description: \"The focal point of the image within its container\",\n      defaultValue: \"center\",\n      group: \"Design\",\n      requiresKeyValue: { key: \"verticalSizing\", value: \"fixed\" },\n    },\n\n    // Link\n    ...getLinkTypeFields({ group: \"Link\" }),\n  ],\n};\n"],"mappings":"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"}