{
  "name": "selection-toolbar-demo",
  "type": "registry:example",
  "registryDependencies": [
    "selection-toolbar"
  ],
  "files": [
    {
      "path": "examples/selection-toolbar-demo.tsx",
      "type": "registry:example",
      "content": "\"use client\";\n\nimport { Bold, Copy, Italic, Link, Share2 } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport {\n  SelectionToolbar,\n  SelectionToolbarItem,\n  SelectionToolbarSeparator,\n} from \"@/registry/bases/radix/ui/selection-toolbar\";\n\nexport default function SelectionToolbarDemo() {\n  const containerRef = React.useRef<HTMLDivElement>(null);\n\n  const wrapSelection = React.useCallback((tagName: string) => {\n    const selection = window.getSelection();\n    if (!selection || selection.rangeCount === 0) return;\n\n    const range = selection.getRangeAt(0);\n    const selectedText = range.toString();\n    if (!selectedText) return;\n\n    const wrapper = document.createElement(tagName);\n    try {\n      range.surroundContents(wrapper);\n      // Re-select the wrapped content to allow multiple formatting actions\n      selection.removeAllRanges();\n      const newRange = document.createRange();\n      newRange.selectNodeContents(wrapper);\n      selection.addRange(newRange);\n    } catch {\n      // Fallback: extract, wrap, and insert\n      wrapper.textContent = selectedText;\n      range.deleteContents();\n      range.insertNode(wrapper);\n      // Re-select the wrapped content\n      selection.removeAllRanges();\n      const newRange = document.createRange();\n      newRange.selectNodeContents(wrapper);\n      selection.addRange(newRange);\n    }\n  }, []);\n\n  const onBold = React.useCallback(() => {\n    wrapSelection(\"strong\");\n    console.log({ action: \"bold\" });\n  }, [wrapSelection]);\n\n  const onItalic = React.useCallback(() => {\n    wrapSelection(\"em\");\n    console.log({ action: \"italic\" });\n  }, [wrapSelection]);\n\n  const onLink = React.useCallback(() => {\n    const selection = window.getSelection();\n    if (!selection || selection.rangeCount === 0) return;\n\n    const url = prompt(\"Enter URL:\");\n    if (!url) return;\n\n    const range = selection.getRangeAt(0);\n    const link = document.createElement(\"a\");\n    link.href = url;\n    link.className = \"text-primary underline hover:text-primary/80\";\n\n    try {\n      range.surroundContents(link);\n      // Re-select the linked content\n      selection.removeAllRanges();\n      const newRange = document.createRange();\n      newRange.selectNodeContents(link);\n      selection.addRange(newRange);\n    } catch {\n      link.textContent = range.toString();\n      range.deleteContents();\n      range.insertNode(link);\n      // Re-select the linked content\n      selection.removeAllRanges();\n      const newRange = document.createRange();\n      newRange.selectNodeContents(link);\n      selection.addRange(newRange);\n    }\n\n    console.log({ action: \"link\", url });\n  }, []);\n\n  const onCopy = React.useCallback((text: string) => {\n    navigator.clipboard.writeText(text);\n    console.log({ action: \"copy\", text });\n\n    // Clear selection to close the toolbar\n    const selection = window.getSelection();\n    if (selection) {\n      selection.removeAllRanges();\n    }\n  }, []);\n\n  const onShare = React.useCallback((text: string) => {\n    if (navigator.share) {\n      navigator.share({ text });\n    }\n    console.log({ action: \"share\", text });\n\n    // Clear selection to close the toolbar\n    const selection = window.getSelection();\n    if (selection) {\n      selection.removeAllRanges();\n    }\n  }, []);\n\n  return (\n    <div className=\"flex min-h-[400px] w-full items-center justify-center\">\n      <div\n        ref={containerRef}\n        contentEditable\n        suppressContentEditableWarning\n        className=\"max-w-2xl space-y-4 rounded-lg border bg-card p-8 text-card-foreground outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50\"\n      >\n        <h2 className=\"text-2xl font-semibold\">Medium-Style Text Selection</h2>\n        <p className=\"leading-relaxed text-muted-foreground\">\n          Select any text in this area to see the floating toolbar appear. The\n          toolbar automatically positions itself above the selection and\n          includes common formatting options like bold, italic, and link, as\n          well as utility actions like copy and share.\n        </p>\n        <p className=\"leading-relaxed text-muted-foreground\">\n          Try selecting text across multiple lines or near the edges of the\n          viewport. The menu will automatically adjust its position to stay\n          visible and accessible. This creates a seamless editing experience\n          similar to popular writing platforms.\n        </p>\n\n        <SelectionToolbar container={containerRef}>\n          <SelectionToolbarItem onSelect={onBold}>\n            <Bold />\n          </SelectionToolbarItem>\n          <SelectionToolbarItem onSelect={onItalic}>\n            <Italic />\n          </SelectionToolbarItem>\n          <SelectionToolbarItem onSelect={onLink}>\n            <Link />\n          </SelectionToolbarItem>\n          <SelectionToolbarSeparator />\n          <SelectionToolbarItem onSelect={onCopy}>\n            <Copy />\n          </SelectionToolbarItem>\n          <SelectionToolbarItem onSelect={onShare}>\n            <Share2 />\n          </SelectionToolbarItem>\n        </SelectionToolbar>\n      </div>\n    </div>\n  );\n}\n",
      "target": ""
    }
  ]
}