{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "block-ui",
  "title": "Block Ui",
  "type": "registry:ui",
  "files": [
    {
      "path": "packages/registry-svelte/components/block-ui/BlockUi.svelte",
      "content": "<script lang=\"ts\" module>\n  import type { Snippet } from 'svelte'\n  import type { HTMLAttributes } from 'svelte/elements'\n\n  export interface BlockUiProps extends HTMLAttributes<HTMLDivElement> {\n    /** Primary blocked API (React `blocking` parity). Bind it (`bind:blocking`). Wins over `value` when both are set. */\n    blocking?: boolean\n    /** Blocked state. Bind it (`bind:value`) to toggle from the parent.\n     * @deprecated Use `blocking`. Kept as an alias — both stay functional. */\n    value?: boolean\n    message?: string\n    opacity?: number\n    overlayColor?: string\n    blur?: boolean\n    showSpinner?: boolean\n    /** Override the default spinner icon. */\n    icon?: Snippet\n    /** Rich message content. Wins over the `message` string when provided. */\n    messageSnippet?: Snippet\n    /** The wrapper <div>, via `bind:ref`. */\n    ref?: HTMLDivElement | null\n  }\n</script>\n\n<script lang=\"ts\">\n  import { fade } from 'svelte/transition'\n  import { cn } from '$lib/utils'\n  import { Spinner } from '$lib/components/ui/spinner'\n  import { blockUiVariants } from './block-ui.variants'\n\n  let {\n    class: className,\n    blocking = $bindable<boolean | undefined>(),\n    value = $bindable<boolean | undefined>(),\n    message = 'Loading...',\n    opacity = 0.6,\n    overlayColor = '',\n    blur = false,\n    showSpinner = true,\n    icon,\n    messageSnippet,\n    children,\n    ref = $bindable(null),\n    ...restProps\n  }: BlockUiProps = $props()\n\n  const blocked = $derived(blocking ?? value ?? false)\n\n  const overlayStyle = $derived(\n    `--block-ui-opacity: ${opacity}; opacity: var(--block-ui-opacity)${overlayColor ? `; background-color: ${overlayColor}` : ''}`,\n  )\n</script>\n\n<div\n  bind:this={ref}\n  data-uipkge=\"\"\n  data-slot=\"block-ui\"\n  data-blocked={blocked ? '' : undefined}\n  class={cn(blockUiVariants(), className)}\n  {...restProps}\n>\n  <!-- Wrapped content — always non-interactive while blocked (not only when blur is on). -->\n  <div\n    class={cn('block-ui-content', blocked && 'pointer-events-none', blur && blocked && 'blur-sm transition-[filter]')}\n    inert={blocked || undefined}\n    aria-hidden={blocked || undefined}\n  >\n    {@render children?.()}\n  </div>\n\n  <!-- Blocking overlay -->\n  {#if blocked}\n    <div\n      class=\"absolute inset-0 z-50 flex flex-col items-center justify-center gap-3\"\n      role=\"status\"\n      aria-live=\"polite\"\n      aria-busy=\"true\"\n      transition:fade={{ duration: 200 }}\n    >\n      <!-- Background layer (opacity only affects this layer) -->\n      <div class=\"absolute inset-0\" class:bg-background={!overlayColor} style={overlayStyle}></div>\n      <!-- Content layer (spinner + message stay fully opaque) -->\n      {#if icon}\n        {@render icon()}\n      {:else if showSpinner}\n        <Spinner size=\"lg\" />\n      {/if}\n      <!-- Message snippet may contain block markup — keep it out of a <p>. -->\n      {#if messageSnippet}\n        <div class=\"text-foreground text-sm font-medium\">\n          {@render messageSnippet()}\n        </div>\n      {:else if message}\n        <p class=\"text-foreground text-sm font-medium\">{message}</p>\n      {/if}\n    </div>\n  {/if}\n</div>\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/block-ui/BlockUi.svelte"
    },
    {
      "path": "packages/registry-svelte/components/block-ui/block-ui.variants.ts",
      "content": "import type { VariantProps } from 'class-variance-authority'\nimport { cva } from 'class-variance-authority'\n\nexport const blockUiVariants = cva('relative inline-block')\n\nexport type BlockUiVariants = VariantProps<typeof blockUiVariants>\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/block-ui/block-ui.variants.ts"
    },
    {
      "path": "packages/registry-svelte/components/block-ui/index.ts",
      "content": "export { default as BlockUi, type BlockUiProps } from './BlockUi.svelte'\nexport { blockUiVariants, type BlockUiVariants } from './block-ui.variants'\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/block-ui/index.ts"
    }
  ],
  "dependencies": [
    "class-variance-authority"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/svelte/spinner.json"
  ],
  "description": "Overlay that blocks interaction during loading. Wraps content and shows a spinner + message overlay. `bind:value` toggles the blocked state with configurable overlay opacity, color, background blur, and custom icon/message snippets. Composes the spinner primitive.",
  "categories": [
    "feedback",
    "utility"
  ]
}