{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "provider",
  "type": "registry:lib",
  "title": "Link and image provider",
  "description": "IrisProvider: lets an app swap the link and image elements Iris UI components render, such as next/link and next/image.",
  "categories": [
    "foundation"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "src/lib/provider.tsx",
      "content": "\"use client\";\n\n/**\n * Lets an app swap the link and image elements Iris UI components render.\n *\n * Without a provider, Iris UI renders a plain `<a>` and `<img>`, so components work in any React app (Vite, Remix, Astro,\n * plain React). Wrap the app once to use your framework's or your own components instead:\n *\n *   import Link from \"next/link\";\n *   import Image from \"next/image\";\n *   import { IrisProvider } from \"@/components/iris/lib/provider\";\n *\n *   <IrisProvider link={Link} image={Image}>{children}</IrisProvider>\n *\n * Any component that accepts these props works, such as a locale-aware Link from next-intl or a React Router Link\n * wrapped to map `href` to `to`.\n */\nimport {\n  createContext,\n  createElement,\n  useContext,\n  useMemo,\n  type AnchorHTMLAttributes,\n  type ComponentType,\n  type ImgHTMLAttributes,\n  type ReactNode,\n  type Ref,\n} from \"react\";\n\n/** The props Iris UI passes to a link: an href plus ordinary anchor attributes. */\nexport interface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {\n  href: string;\n  ref?: Ref<HTMLAnchorElement>;\n}\n\n/**\n * The props Iris UI passes to an image. A subset of next/image's props, so next/image can be passed as is: either `fill`\n * (cover the positioned parent) or `width` and `height`, plus `sizes` and `priority` as hints.\n */\nexport interface ImageProps extends Omit<\n  ImgHTMLAttributes<HTMLImageElement>,\n  \"src\" | \"alt\" | \"width\" | \"height\" | \"loading\" | \"srcSet\"\n> {\n  src: string;\n  alt: string;\n  width?: number;\n  height?: number;\n  /** Fills the nearest positioned parent, like next/image's `fill`. */\n  fill?: boolean;\n  /** Loads the image eagerly with high priority, like next/image's `priority`. */\n  priority?: boolean;\n  loading?: \"eager\" | \"lazy\";\n  ref?: Ref<HTMLImageElement>;\n}\n\nexport type LinkComponent = ComponentType<LinkProps>;\nexport type ImageComponent = ComponentType<ImageProps>;\n\n/** The default link: a plain anchor. */\nexport function DefaultLink({ children, ...props }: LinkProps) {\n  return <a {...props}>{children}</a>;\n}\n\nconst fillStyle = { position: \"absolute\", inset: 0, width: \"100%\", height: \"100%\" } as const;\n\n/** The default image: a plain, lazily decoded `<img>` that understands `fill` and `priority`. */\nexport function DefaultImage({ alt, fill, priority, loading, style, ...props }: ImageProps) {\n  return (\n    // eslint-disable-next-line @next/next/no-img-element -- the framework-free default; pass next/image through IrisProvider instead.\n    <img\n      alt={alt}\n      decoding=\"async\"\n      {...props}\n      loading={loading ?? (priority ? \"eager\" : \"lazy\")}\n      fetchPriority={priority ? \"high\" : props.fetchPriority}\n      style={fill ? { ...fillStyle, ...style } : style}\n    />\n  );\n}\n\ninterface ProviderComponents {\n  link: LinkComponent;\n  image: ImageComponent;\n}\n\nconst ProviderContext = createContext<ProviderComponents>({ link: DefaultLink, image: DefaultImage });\n\nexport interface IrisProviderProps {\n  /** The link component Iris UI renders for navigation, such as next/link or your own wrapped Link. Defaults to `<a>`. */\n  link?: LinkComponent;\n  /** The image component Iris UI renders for photos, such as next/image. Defaults to `<img>`. */\n  image?: ImageComponent;\n  children: ReactNode;\n}\n\n/** Sets the link and image components for every Iris UI component inside it. Nested providers inherit what they do not set. */\nexport function IrisProvider({ link, image, children }: IrisProviderProps) {\n  const parent = useContext(ProviderContext);\n  const value = useMemo(() => ({ link: link ?? parent.link, image: image ?? parent.image }), [link, image, parent]);\n  return <ProviderContext.Provider value={value}>{children}</ProviderContext.Provider>;\n}\n\n/** The link component from the nearest IrisProvider, or a plain anchor. */\nexport const useLinkComponent = () => useContext(ProviderContext).link;\n/** The image component from the nearest IrisProvider, or a plain img. */\nexport const useImageComponent = () => useContext(ProviderContext).image;\n\n/** What Iris UI components render for a link: the provider's link component, or a plain anchor. */\nexport function ProvidedLink(props: LinkProps) {\n  return createElement(useLinkComponent(), props);\n}\n\n/** What Iris UI components render for an image: the provider's image component, or a plain img. */\nexport function ProvidedImage(props: ImageProps) {\n  return createElement(useImageComponent(), props);\n}\n",
      "type": "registry:lib",
      "target": "@components/iris/lib/provider.tsx"
    }
  ],
  "docs": "Docs and live preview: https://irisui.dev/components/provider",
  "meta": {
    "kind": "lib",
    "docs": "https://irisui.dev/components/provider"
  }
}
