@hex-core/components 1.9.0 → 1.10.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.
- package/dist/_tsup-dts-rollup.d.ts +575 -18
- package/dist/accordion.js.map +1 -1
- package/dist/alert-dialog.js.map +1 -1
- package/dist/alert.js.map +1 -1
- package/dist/arc.js.map +1 -1
- package/dist/attachment.js.map +1 -1
- package/dist/audio-player.js.map +1 -1
- package/dist/audio-waveform.js.map +1 -1
- package/dist/auth-forgot-password.js.map +1 -1
- package/dist/auth-reset-password.js.map +1 -1
- package/dist/auth-sign-in-split.js.map +1 -1
- package/dist/auth-sign-up-card.js.map +1 -1
- package/dist/auth-verify-email.js.map +1 -1
- package/dist/auth-verify-otp.js.map +1 -1
- package/dist/avatar.js.map +1 -1
- package/dist/badge.js.map +1 -1
- package/dist/branch.d.ts +2 -0
- package/dist/branch.js +136 -0
- package/dist/branch.js.map +1 -0
- package/dist/breadcrumb.js.map +1 -1
- package/dist/button.js.map +1 -1
- package/dist/calendar.js.map +1 -1
- package/dist/canvas.js.map +1 -1
- package/dist/card.js.map +1 -1
- package/dist/chain-of-thought.d.ts +3 -0
- package/dist/chain-of-thought.js +119 -0
- package/dist/chain-of-thought.js.map +1 -0
- package/dist/checkbox.js.map +1 -1
- package/dist/chord.js.map +1 -1
- package/dist/citation.js.map +1 -1
- package/dist/cloze.js.map +1 -1
- package/dist/cluster.js.map +1 -1
- package/dist/code-block-copy.js.map +1 -1
- package/dist/code-block.js.map +1 -1
- package/dist/color-picker.js.map +1 -1
- package/dist/combobox.js.map +1 -1
- package/dist/command.js.map +1 -1
- package/dist/compare-table.js.map +1 -1
- package/dist/composer.js.map +1 -1
- package/dist/container.js.map +1 -1
- package/dist/context-menu.js.map +1 -1
- package/dist/conversation.d.ts +3 -0
- package/dist/conversation.js +358 -0
- package/dist/conversation.js.map +1 -0
- package/dist/data-table.js.map +1 -1
- package/dist/date-picker.js.map +1 -1
- package/dist/deck.js.map +1 -1
- package/dist/dendrogram.js.map +1 -1
- package/dist/diagram.js.map +1 -1
- package/dist/dialog.js.map +1 -1
- package/dist/drawer.js.map +1 -1
- package/dist/dropdown-menu.js.map +1 -1
- package/dist/dropzone.js.map +1 -1
- package/dist/empty.js.map +1 -1
- package/dist/error-state.js.map +1 -1
- package/dist/file-tree.js.map +1 -1
- package/dist/flashcard.js.map +1 -1
- package/dist/flowchart.js.map +1 -1
- package/dist/form.js.map +1 -1
- package/dist/funnel.js.map +1 -1
- package/dist/gantt.js.map +1 -1
- package/dist/grid.js.map +1 -1
- package/dist/hover-card.js.map +1 -1
- package/dist/image-occlusion.js.map +1 -1
- package/dist/index.d.ts +21 -0
- package/dist/index.js +1011 -13
- package/dist/index.js.map +1 -1
- package/dist/inline-citation.d.ts +2 -0
- package/dist/inline-citation.js +108 -0
- package/dist/inline-citation.js.map +1 -0
- package/dist/input-otp.js.map +1 -1
- package/dist/input.js.map +1 -1
- package/dist/label.js.map +1 -1
- package/dist/loading-indicator.js.map +1 -1
- package/dist/loading.js.map +1 -1
- package/dist/markdown.d.ts +1 -0
- package/dist/markdown.js +784 -4
- package/dist/markdown.js.map +1 -1
- package/dist/matrix.js.map +1 -1
- package/dist/menubar.js.map +1 -1
- package/dist/message-actions.js.map +1 -1
- package/dist/message-list.js.map +1 -1
- package/dist/message.js.map +1 -1
- package/dist/mind-map.js.map +1 -1
- package/dist/multi-combobox.js.map +1 -1
- package/dist/navigation-menu.js.map +1 -1
- package/dist/org-chart.js.map +1 -1
- package/dist/pagination.js.map +1 -1
- package/dist/plan.d.ts +3 -0
- package/dist/plan.js +183 -0
- package/dist/plan.js.map +1 -0
- package/dist/popover.js.map +1 -1
- package/dist/progress.js.map +1 -1
- package/dist/pyramid.js.map +1 -1
- package/dist/quiz.js.map +1 -1
- package/dist/radio-group.js.map +1 -1
- package/dist/reasoning.js.map +1 -1
- package/dist/resizable.js.map +1 -1
- package/dist/sankey.js.map +1 -1
- package/dist/schemas.d.ts +8 -0
- package/dist/schemas.js +774 -17
- package/dist/schemas.js.map +1 -1
- package/dist/scroll-area.js.map +1 -1
- package/dist/select.js.map +1 -1
- package/dist/separator.js.map +1 -1
- package/dist/sequence.js.map +1 -1
- package/dist/sheet.js.map +1 -1
- package/dist/shimmer.d.ts +2 -0
- package/dist/shimmer.js +39 -0
- package/dist/shimmer.js.map +1 -0
- package/dist/sidebar.js.map +1 -1
- package/dist/skeleton.js.map +1 -1
- package/dist/slider.js.map +1 -1
- package/dist/sources.d.ts +3 -0
- package/dist/sources.js +164 -0
- package/dist/sources.js.map +1 -0
- package/dist/spaced-repetition.js.map +1 -1
- package/dist/spacer.js.map +1 -1
- package/dist/speech-recognition.js.map +1 -1
- package/dist/stack.js.map +1 -1
- package/dist/stepper.js.map +1 -1
- package/dist/suggestion.js.map +1 -1
- package/dist/sunburst.js.map +1 -1
- package/dist/switch.js.map +1 -1
- package/dist/table.js.map +1 -1
- package/dist/tabs.js.map +1 -1
- package/dist/tag.js.map +1 -1
- package/dist/task.d.ts +3 -0
- package/dist/task.js +189 -0
- package/dist/task.js.map +1 -0
- package/dist/terminal.js +11 -0
- package/dist/terminal.js.map +1 -1
- package/dist/textarea.js.map +1 -1
- package/dist/time-axis.js.map +1 -1
- package/dist/time-picker.js.map +1 -1
- package/dist/timeline.js.map +1 -1
- package/dist/toggle-group.js.map +1 -1
- package/dist/toggle.js.map +1 -1
- package/dist/tool-call.js +5 -6
- package/dist/tool-call.js.map +1 -1
- package/dist/toolbar.js.map +1 -1
- package/dist/tooltip.js.map +1 -1
- package/dist/tree-map.js.map +1 -1
- package/dist/tree.js.map +1 -1
- package/dist/venn.js.map +1 -1
- package/package.json +8 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/utils.ts","../src/components/command/command.tsx","../src/components/popover/popover.tsx","../src/components/multi-combobox/multi-combobox.tsx"],"names":["CommandPrimitive","React2","jsx","React3","jsxs"],"mappings":"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","file":"multi-combobox.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport { Command as CommandPrimitive } from \"cmdk\";\nimport * as React from \"react\";\nimport {\n\tDialog,\n\tDialogContent,\n\tDialogDescription,\n\tDialogHeader,\n\tDialogTitle,\n} from \"../dialog/dialog.js\";\nimport { cn } from \"../../lib/utils.js\";\n\n/** Root Command container — drives search, filtering, and keyboard navigation over items. */\nconst Command = React.forwardRef<\n\tReact.ComponentRef<typeof CommandPrimitive>,\n\tReact.ComponentPropsWithoutRef<typeof CommandPrimitive>\n>(({ className, ...props }, ref) => (\n\t<CommandPrimitive\n\t\tref={ref}\n\t\tclassName={cn(\n\t\t\t\"flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground\",\n\t\t\tclassName,\n\t\t)}\n\t\t{...props}\n\t/>\n));\nCommand.displayName = \"Command\";\n\ninterface CommandDialogProps extends React.ComponentPropsWithoutRef<typeof Dialog> {\n\t/** Command children (CommandInput + CommandList + CommandItem, etc.) */\n\tchildren: React.ReactNode;\n\t/** Accessible title for the dialog (screen-reader only by default). */\n\ttitle?: string;\n\t/** Accessible description for the dialog (screen-reader only by default). */\n\tdescription?: string;\n}\n\n/**\n * Command menu rendered inside a Dialog — a ⌘K-style launcher.\n * @param props - Forwarded to the underlying Dialog (open, onOpenChange, etc.)\n * @returns A Dialog containing a Command menu.\n */\nfunction CommandDialog({\n\ttitle = \"Command Palette\",\n\tdescription = \"Search for a command to run.\",\n\tchildren,\n\t...props\n}: CommandDialogProps) {\n\treturn (\n\t\t<Dialog {...props}>\n\t\t\t<DialogHeader className=\"sr-only\">\n\t\t\t\t<DialogTitle>{title}</DialogTitle>\n\t\t\t\t<DialogDescription>{description}</DialogDescription>\n\t\t\t</DialogHeader>\n\t\t\t<DialogContent className=\"overflow-hidden p-0\" scrollable={false}>\n\t\t\t\t<Command className=\"[&_[cmdk-group-heading]]:px-[var(--space-2,0.5rem)] [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-[var(--space-2,0.5rem)] [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-[var(--space-2,0.5rem)] [&_[cmdk-item]]:py-[var(--space-3,0.75rem)] [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5\">\n\t\t\t\t\t{children}\n\t\t\t\t</Command>\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n}\n\n/** Search input for the Command menu. Fires onValueChange as the user types. */\nconst CommandInput = React.forwardRef<\n\tReact.ComponentRef<typeof CommandPrimitive.Input>,\n\tReact.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>\n>(({ className, ...props }, ref) => (\n\t<div className=\"flex items-center border-b border-b-foreground/[0.08] px-[var(--space-3,0.75rem)]\" cmdk-input-wrapper=\"\">\n\t\t<svg\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\tstroke=\"currentColor\"\n\t\t\tstrokeWidth=\"2\"\n\t\t\tstrokeLinecap=\"round\"\n\t\t\tstrokeLinejoin=\"round\"\n\t\t\tclassName=\"mr-[var(--space-2,0.5rem)] h-4 w-4 shrink-0 opacity-50\"\n\t\t\taria-hidden=\"true\"\n\t\t>\n\t\t\t<circle cx=\"11\" cy=\"11\" r=\"8\" />\n\t\t\t<line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\" />\n\t\t</svg>\n\t\t<CommandPrimitive.Input\n\t\t\tref={ref}\n\t\t\tclassName={cn(\n\t\t\t\t\"flex h-[var(--control-height-lg,2.75rem)] w-full rounded-md bg-transparent py-[var(--space-3,0.75rem)] text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t</div>\n));\nCommandInput.displayName = \"CommandInput\";\n\n/** Scrollable list that contains CommandGroup / CommandItem / CommandEmpty. */\nconst CommandList = React.forwardRef<\n\tReact.ComponentRef<typeof CommandPrimitive.List>,\n\tReact.ComponentPropsWithoutRef<typeof CommandPrimitive.List>\n>(({ className, ...props }, ref) => (\n\t<CommandPrimitive.List\n\t\tref={ref}\n\t\tclassName={cn(\"max-h-[300px] overflow-y-auto overflow-x-hidden\", className)}\n\t\t{...props}\n\t/>\n));\nCommandList.displayName = \"CommandList\";\n\n/** Rendered when no items match the current search. */\nconst CommandEmpty = React.forwardRef<\n\tReact.ComponentRef<typeof CommandPrimitive.Empty>,\n\tReact.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>\n>((props, ref) => (\n\t<CommandPrimitive.Empty ref={ref} className=\"py-[var(--space-6,1.5rem)] text-center text-sm\" {...props} />\n));\nCommandEmpty.displayName = \"CommandEmpty\";\n\n/** Logical group of items — renders a heading and filters as a unit. */\nconst CommandGroup = React.forwardRef<\n\tReact.ComponentRef<typeof CommandPrimitive.Group>,\n\tReact.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>\n>(({ className, ...props }, ref) => (\n\t<CommandPrimitive.Group\n\t\tref={ref}\n\t\tclassName={cn(\n\t\t\t\"overflow-hidden p-[var(--space-1,0.25rem)] text-foreground [&_[cmdk-group-heading]]:px-[var(--space-2,0.5rem)] [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground\",\n\t\t\tclassName,\n\t\t)}\n\t\t{...props}\n\t/>\n));\nCommandGroup.displayName = \"CommandGroup\";\n\n/**\n * Horizontal rule between groups. Renders as a presentational `<div>` (no role)\n * so it can sit inside CommandList (role=listbox) without violating ARIA's\n * required-children rule for listbox. The line is purely decorative — cmdk's\n * built-in Separator hardcodes `role=\"separator\"`, which axe rejects in this\n * context, so we render the divider directly.\n *\n * The `data-cmdk-separator` attribute is preserved so existing CSS / test\n * selectors that target cmdk's separator continue to match.\n */\nconst CommandSeparator = React.forwardRef<\n\tHTMLDivElement,\n\tReact.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n\t<div\n\t\tref={ref}\n\t\trole=\"none\"\n\t\tdata-cmdk-separator=\"\"\n\t\tclassName={cn(\"-mx-[var(--space-1,0.25rem)] h-px bg-foreground/[0.12]\", className)}\n\t\t{...props}\n\t/>\n));\nCommandSeparator.displayName = \"CommandSeparator\";\n\n/** Selectable item. onSelect fires on Enter or click. */\nconst CommandItem = React.forwardRef<\n\tReact.ComponentRef<typeof CommandPrimitive.Item>,\n\tReact.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>\n>(({ className, ...props }, ref) => (\n\t<CommandPrimitive.Item\n\t\tref={ref}\n\t\tclassName={cn(\n\t\t\t\"relative flex cursor-default select-none items-center gap-[var(--gap-sm,0.5rem)] rounded-sm px-[var(--space-2,0.5rem)] py-1.5 text-sm outline-none transition-all duration-[var(--duration-normal,200ms)] ease-out\",\n\t\t\t\"data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50\",\n\t\t\t\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground\",\n\t\t\t\"[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n\t\t\tclassName,\n\t\t)}\n\t\t{...props}\n\t/>\n));\nCommandItem.displayName = \"CommandItem\";\n\n/**\n * Keyboard shortcut hint (e.g. '⌘K') aligned to the right of an item.\n * @returns A muted inline span rendered at the end of a CommandItem.\n */\nfunction CommandShortcut({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) {\n\treturn (\n\t\t<span\n\t\t\tclassName={cn(\n\t\t\t\t\"ml-auto text-xs tracking-widest text-muted-foreground\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\nCommandShortcut.displayName = \"CommandShortcut\";\n\nexport {\n\tCommand,\n\tCommandDialog,\n\tCommandInput,\n\tCommandList,\n\tCommandEmpty,\n\tCommandGroup,\n\tCommandItem,\n\tCommandShortcut,\n\tCommandSeparator,\n};\n","\"use client\";\n\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\n/** Root container for a popover. */\nconst Popover = PopoverPrimitive.Root;\n\n/** The element that anchors and opens the popover. */\nconst PopoverTrigger = PopoverPrimitive.Trigger;\n\n/** Helper to explicitly anchor the popover to a different element. */\nconst PopoverAnchor = PopoverPrimitive.Anchor;\n\n/** The floating popover content panel. */\nconst PopoverContent = React.forwardRef<\n\tReact.ComponentRef<typeof PopoverPrimitive.Content>,\n\tReact.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>\n>(({ className, align = \"center\", sideOffset = 4, ...props }, ref) => (\n\t<PopoverPrimitive.Portal>\n\t\t<PopoverPrimitive.Content\n\t\t\tref={ref}\n\t\t\talign={align}\n\t\t\tsideOffset={sideOffset}\n\t\t\tclassName={cn(\n\t\t\t\t\"z-50 w-72 rounded-md border border-foreground/[0.08] bg-popover p-[var(--space-4,1rem)] text-popover-foreground shadow-md outline-none\",\n\t\t\t\t\"data-[state=open]:animate-in data-[state=closed]:animate-out\",\n\t\t\t\t\"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n\t\t\t\t\"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95\",\n\t\t\t\t\"data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t</PopoverPrimitive.Portal>\n));\nPopoverContent.displayName = \"PopoverContent\";\n\nexport { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };\n","\"use client\";\n\nimport * as React from \"react\";\nimport {\n\tCommand,\n\tCommandEmpty,\n\tCommandGroup,\n\tCommandInput,\n\tCommandItem,\n\tCommandList,\n} from \"../command/command.js\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../popover/popover.js\";\nimport { cn } from \"../../lib/utils.js\";\n\ninterface MultiComboboxOption {\n\t/** The value returned in the onChange array (stable, unique). */\n\tvalue: string;\n\t/** The display label shown in the list and the trigger. */\n\tlabel: string;\n\t/** Mark as non-selectable. */\n\tdisabled?: boolean;\n}\n\ninterface MultiComboboxProps {\n\t/** The list of selectable options. */\n\toptions: MultiComboboxOption[];\n\t/** Controlled selected values. */\n\tvalue?: string[];\n\t/** Fired when the user toggles an option: (values: string[]) => void */\n\tonChange?: (values: string[]) => void;\n\t/** Text shown on the trigger when nothing is selected. */\n\tplaceholder?: string;\n\t/** Input placeholder inside the popover list. */\n\tsearchPlaceholder?: string;\n\t/** Text shown when no options match the search. */\n\temptyText?: string;\n\t/** Soft cap on selections. Once reached, unselected options become non-selectable. */\n\tmaxSelected?: number;\n\t/** Close the popover after every pick. Default false (multi-select UX expects staying open). */\n\tcloseOnSelect?: boolean;\n\t/** Disable the trigger. */\n\tdisabled?: boolean;\n\t/** Extra class names on the trigger button. */\n\tclassName?: string;\n\t/** Accessible label for the trigger (required when no adjacent visible label). */\n\t\"aria-label\"?: string;\n\t/** Id of an external visible label that names this combobox. */\n\t\"aria-labelledby\"?: string;\n}\n\n/**\n * Searchable multi-select input built on Command + Popover.\n *\n * Pass `options` with `{ value, label }` and bind `value` (string[]) +\n * `onChange`. The trigger shows \"{n} selected\" once any option is picked, with\n * the comma-separated label list mirrored into the `title` attribute for\n * pointer/screen-reader fallback. Each option is announced with `aria-selected`.\n * @returns A trigger button that opens a multi-select option list.\n */\nfunction MultiCombobox({\n\toptions,\n\tvalue,\n\tonChange,\n\tplaceholder = \"Select…\",\n\tsearchPlaceholder = \"Search…\",\n\temptyText = \"No results found.\",\n\tmaxSelected,\n\tcloseOnSelect = false,\n\tdisabled,\n\tclassName,\n\t\"aria-label\": ariaLabel,\n\t\"aria-labelledby\": ariaLabelledBy,\n}: MultiComboboxProps) {\n\tconst [open, setOpen] = React.useState(false);\n\tconst listboxId = React.useId();\n\tconst selected = React.useMemo(() => new Set(value ?? []), [value]);\n\tconst selectedLabels = React.useMemo(\n\t\t() => options.filter((o) => selected.has(o.value)).map((o) => o.label),\n\t\t[options, selected],\n\t);\n\tconst triggerLabel =\n\t\tselected.size === 0 ? placeholder : `${selected.size} selected`;\n\tconst capReached =\n\t\ttypeof maxSelected === \"number\" && selected.size >= maxSelected;\n\n\tconst toggle = React.useCallback(\n\t\t(optionValue: string) => {\n\t\t\tconst next = new Set(selected);\n\t\t\tif (next.has(optionValue)) {\n\t\t\t\tnext.delete(optionValue);\n\t\t\t} else {\n\t\t\t\tif (capReached) return;\n\t\t\t\tnext.add(optionValue);\n\t\t\t}\n\t\t\tonChange?.(Array.from(next));\n\t\t\tif (closeOnSelect) setOpen(false);\n\t\t},\n\t\t[selected, capReached, onChange, closeOnSelect],\n\t);\n\n\treturn (\n\t\t<>\n\t\t\t<Popover open={open} onOpenChange={setOpen}>\n\t\t\t\t<PopoverTrigger asChild>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\trole=\"combobox\"\n\t\t\t\t\t\taria-expanded={open}\n\t\t\t\t\t\taria-haspopup=\"listbox\"\n\t\t\t\t\t\t/*\n\t\t\t\t\t\t * Only reference the listbox id when the popover is open.\n\t\t\t\t\t\t * The CommandList is portal-mounted by Radix Popover and\n\t\t\t\t\t\t * does not exist in the DOM while closed; pointing at a\n\t\t\t\t\t\t * missing id confuses some screen readers.\n\t\t\t\t\t\t */\n\t\t\t\t\t\taria-controls={open ? listboxId : undefined}\n\t\t\t\t\t\taria-label={ariaLabel}\n\t\t\t\t\t\taria-labelledby={ariaLabelledBy}\n\t\t\t\t\t\ttitle={selectedLabels.length > 0 ? selectedLabels.join(\", \") : undefined}\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\"inline-flex h-[var(--control-height-md,2.5rem)] w-[240px] items-center justify-between gap-[var(--gap-sm,0.5rem)] rounded-md border border-input bg-background px-[var(--space-3,0.75rem)] py-[var(--space-2,0.5rem)] text-sm font-normal transition-all duration-[var(--duration-normal,200ms)] ease-out\",\n\t\t\t\t\t\t\t\"hover:bg-accent hover:text-accent-foreground\",\n\t\t\t\t\t\t\t\"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n\t\t\t\t\t\t\t\"disabled:pointer-events-none disabled:opacity-50\",\n\t\t\t\t\t\t\tselected.size === 0 && \"text-muted-foreground\",\n\t\t\t\t\t\t\tclassName,\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<span className=\"truncate\">{triggerLabel}</span>\n\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\t\tstrokeWidth=\"2\"\n\t\t\t\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\t\t\t\tclassName=\"h-4 w-4 shrink-0 opacity-50\"\n\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<polyline points=\"6 9 12 15 18 9\" />\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t</button>\n\t\t\t\t</PopoverTrigger>\n\t\t\t\t<PopoverContent className=\"w-[240px] p-0\" align=\"start\">\n\t\t\t\t\t<Command>\n\t\t\t\t\t\t<CommandInput placeholder={searchPlaceholder} />\n\t\t\t\t\t\t<CommandList id={listboxId}>\n\t\t\t\t\t\t\t<CommandEmpty>{emptyText}</CommandEmpty>\n\t\t\t\t\t\t\t<CommandGroup>\n\t\t\t\t\t\t\t\t{options.map((option) => {\n\t\t\t\t\t\t\t\t\tconst isSelected = selected.has(option.value);\n\t\t\t\t\t\t\t\t\tconst isCapped = !isSelected && capReached;\n\t\t\t\t\t\t\t\t\tconst itemDisabled = option.disabled || isCapped;\n\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t<CommandItem\n\t\t\t\t\t\t\t\t\t\t\tkey={option.value}\n\t\t\t\t\t\t\t\t\t\t\tvalue={option.label}\n\t\t\t\t\t\t\t\t\t\t\taria-selected={isSelected}\n\t\t\t\t\t\t\t\t\t\t\taria-disabled={itemDisabled || undefined}\n\t\t\t\t\t\t\t\t\t\t\tdisabled={itemDisabled}\n\t\t\t\t\t\t\t\t\t\t\tonSelect={() => {\n\t\t\t\t\t\t\t\t\t\t\t\tif (itemDisabled) return;\n\t\t\t\t\t\t\t\t\t\t\t\ttoggle(option.value);\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\t\t\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\t\t\t\t\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\t\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\t\t\t\t\t\t\tstrokeWidth=\"2\"\n\t\t\t\t\t\t\t\t\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\t\t\t\t\t\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"mr-[var(--space-2,0.5rem)] h-4 w-4\",\n\t\t\t\t\t\t\t\t\t\t\t\t\tisSelected ? \"opacity-100\" : \"opacity-0\",\n\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t<polyline points=\"20 6 9 17 4 12\" />\n\t\t\t\t\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t\t\t\t\t{option.label}\n\t\t\t\t\t\t\t\t\t\t</CommandItem>\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t</CommandGroup>\n\t\t\t\t\t\t</CommandList>\n\t\t\t\t\t</Command>\n\t\t\t\t</PopoverContent>\n\t\t\t</Popover>\n\t\t\t{/*\n\t\t\t * Live region lives outside the trigger so its text is NOT pulled\n\t\t\t * into the button's accessible name (sr-only spans inside a button\n\t\t\t * concatenate via the AccName algorithm). Polite announcements fire\n\t\t\t * only on selection-count changes.\n\t\t\t */}\n\t\t\t<span className=\"sr-only\" aria-live=\"polite\">\n\t\t\t\t{selected.size === 0\n\t\t\t\t\t? \"No items selected\"\n\t\t\t\t\t: `${selected.size} item${selected.size === 1 ? \"\" : \"s\"} selected`}\n\t\t\t</span>\n\t\t</>\n\t);\n}\nMultiCombobox.displayName = \"MultiCombobox\";\n\nexport { MultiCombobox };\nexport type { MultiComboboxOption, MultiComboboxProps };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/components/command/command.tsx","../src/components/popover/popover.tsx","../src/components/multi-combobox/multi-combobox.tsx"],"names":["CommandPrimitive","React2","jsx","React3","jsxs"],"mappings":"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","file":"multi-combobox.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n\nconst SAFE_URL_SCHEMES = [\"http:\", \"https:\", \"mailto:\"] as const;\n\n/**\n * Allowlist a URL for use as an `<a href>` against untrusted input.\n *\n * Returns the raw string when it's `http(s):` / `mailto:` / a relative\n * URL (no scheme); returns `undefined` otherwise. Defends against\n * `javascript:` / `data:` / `vbscript:` injection from streamed model\n * output or third-party JSON payloads that flow into citation chips.\n *\n * Inside a Markdown render path, `rehype-sanitize` already strips\n * `javascript:` from inline-link hrefs — but it does NOT introspect\n * JSON nested inside attribute values (e.g. `<sources data='[…]'/>`),\n * so the components that consume that data must guard themselves.\n *\n * @param raw - The candidate URL, or `undefined` when none was supplied.\n * @returns The URL when safe to render, otherwise `undefined`.\n */\nexport function safeUrl(raw: string | undefined): string | undefined {\n\tif (raw === undefined || raw === \"\") return undefined;\n\t// Relative URLs have no scheme — `new URL(relative)` throws without a base,\n\t// so a thrown URL means either malformed input OR a relative path. Treat\n\t// \"throws + does not contain a colon\" as a relative path (safe).\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(raw);\n\t} catch {\n\t\treturn raw.includes(\":\") ? undefined : raw;\n\t}\n\treturn SAFE_URL_SCHEMES.some((scheme) => scheme === parsed.protocol) ? raw : undefined;\n}\n","\"use client\";\n\nimport { Command as CommandPrimitive } from \"cmdk\";\nimport * as React from \"react\";\nimport {\n\tDialog,\n\tDialogContent,\n\tDialogDescription,\n\tDialogHeader,\n\tDialogTitle,\n} from \"../dialog/dialog.js\";\nimport { cn } from \"../../lib/utils.js\";\n\n/** Root Command container — drives search, filtering, and keyboard navigation over items. */\nconst Command = React.forwardRef<\n\tReact.ComponentRef<typeof CommandPrimitive>,\n\tReact.ComponentPropsWithoutRef<typeof CommandPrimitive>\n>(({ className, ...props }, ref) => (\n\t<CommandPrimitive\n\t\tref={ref}\n\t\tclassName={cn(\n\t\t\t\"flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground\",\n\t\t\tclassName,\n\t\t)}\n\t\t{...props}\n\t/>\n));\nCommand.displayName = \"Command\";\n\ninterface CommandDialogProps extends React.ComponentPropsWithoutRef<typeof Dialog> {\n\t/** Command children (CommandInput + CommandList + CommandItem, etc.) */\n\tchildren: React.ReactNode;\n\t/** Accessible title for the dialog (screen-reader only by default). */\n\ttitle?: string;\n\t/** Accessible description for the dialog (screen-reader only by default). */\n\tdescription?: string;\n}\n\n/**\n * Command menu rendered inside a Dialog — a ⌘K-style launcher.\n * @param props - Forwarded to the underlying Dialog (open, onOpenChange, etc.)\n * @returns A Dialog containing a Command menu.\n */\nfunction CommandDialog({\n\ttitle = \"Command Palette\",\n\tdescription = \"Search for a command to run.\",\n\tchildren,\n\t...props\n}: CommandDialogProps) {\n\treturn (\n\t\t<Dialog {...props}>\n\t\t\t<DialogHeader className=\"sr-only\">\n\t\t\t\t<DialogTitle>{title}</DialogTitle>\n\t\t\t\t<DialogDescription>{description}</DialogDescription>\n\t\t\t</DialogHeader>\n\t\t\t<DialogContent className=\"overflow-hidden p-0\" scrollable={false}>\n\t\t\t\t<Command className=\"[&_[cmdk-group-heading]]:px-[var(--space-2,0.5rem)] [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-[var(--space-2,0.5rem)] [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-[var(--space-2,0.5rem)] [&_[cmdk-item]]:py-[var(--space-3,0.75rem)] [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5\">\n\t\t\t\t\t{children}\n\t\t\t\t</Command>\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n}\n\n/** Search input for the Command menu. Fires onValueChange as the user types. */\nconst CommandInput = React.forwardRef<\n\tReact.ComponentRef<typeof CommandPrimitive.Input>,\n\tReact.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>\n>(({ className, ...props }, ref) => (\n\t<div className=\"flex items-center border-b border-b-foreground/[0.08] px-[var(--space-3,0.75rem)]\" cmdk-input-wrapper=\"\">\n\t\t<svg\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\tstroke=\"currentColor\"\n\t\t\tstrokeWidth=\"2\"\n\t\t\tstrokeLinecap=\"round\"\n\t\t\tstrokeLinejoin=\"round\"\n\t\t\tclassName=\"mr-[var(--space-2,0.5rem)] h-4 w-4 shrink-0 opacity-50\"\n\t\t\taria-hidden=\"true\"\n\t\t>\n\t\t\t<circle cx=\"11\" cy=\"11\" r=\"8\" />\n\t\t\t<line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\" />\n\t\t</svg>\n\t\t<CommandPrimitive.Input\n\t\t\tref={ref}\n\t\t\tclassName={cn(\n\t\t\t\t\"flex h-[var(--control-height-lg,2.75rem)] w-full rounded-md bg-transparent py-[var(--space-3,0.75rem)] text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t</div>\n));\nCommandInput.displayName = \"CommandInput\";\n\n/** Scrollable list that contains CommandGroup / CommandItem / CommandEmpty. */\nconst CommandList = React.forwardRef<\n\tReact.ComponentRef<typeof CommandPrimitive.List>,\n\tReact.ComponentPropsWithoutRef<typeof CommandPrimitive.List>\n>(({ className, ...props }, ref) => (\n\t<CommandPrimitive.List\n\t\tref={ref}\n\t\tclassName={cn(\"max-h-[300px] overflow-y-auto overflow-x-hidden\", className)}\n\t\t{...props}\n\t/>\n));\nCommandList.displayName = \"CommandList\";\n\n/** Rendered when no items match the current search. */\nconst CommandEmpty = React.forwardRef<\n\tReact.ComponentRef<typeof CommandPrimitive.Empty>,\n\tReact.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>\n>((props, ref) => (\n\t<CommandPrimitive.Empty ref={ref} className=\"py-[var(--space-6,1.5rem)] text-center text-sm\" {...props} />\n));\nCommandEmpty.displayName = \"CommandEmpty\";\n\n/** Logical group of items — renders a heading and filters as a unit. */\nconst CommandGroup = React.forwardRef<\n\tReact.ComponentRef<typeof CommandPrimitive.Group>,\n\tReact.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>\n>(({ className, ...props }, ref) => (\n\t<CommandPrimitive.Group\n\t\tref={ref}\n\t\tclassName={cn(\n\t\t\t\"overflow-hidden p-[var(--space-1,0.25rem)] text-foreground [&_[cmdk-group-heading]]:px-[var(--space-2,0.5rem)] [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground\",\n\t\t\tclassName,\n\t\t)}\n\t\t{...props}\n\t/>\n));\nCommandGroup.displayName = \"CommandGroup\";\n\n/**\n * Horizontal rule between groups. Renders as a presentational `<div>` (no role)\n * so it can sit inside CommandList (role=listbox) without violating ARIA's\n * required-children rule for listbox. The line is purely decorative — cmdk's\n * built-in Separator hardcodes `role=\"separator\"`, which axe rejects in this\n * context, so we render the divider directly.\n *\n * The `data-cmdk-separator` attribute is preserved so existing CSS / test\n * selectors that target cmdk's separator continue to match.\n */\nconst CommandSeparator = React.forwardRef<\n\tHTMLDivElement,\n\tReact.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n\t<div\n\t\tref={ref}\n\t\trole=\"none\"\n\t\tdata-cmdk-separator=\"\"\n\t\tclassName={cn(\"-mx-[var(--space-1,0.25rem)] h-px bg-foreground/[0.12]\", className)}\n\t\t{...props}\n\t/>\n));\nCommandSeparator.displayName = \"CommandSeparator\";\n\n/** Selectable item. onSelect fires on Enter or click. */\nconst CommandItem = React.forwardRef<\n\tReact.ComponentRef<typeof CommandPrimitive.Item>,\n\tReact.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>\n>(({ className, ...props }, ref) => (\n\t<CommandPrimitive.Item\n\t\tref={ref}\n\t\tclassName={cn(\n\t\t\t\"relative flex cursor-default select-none items-center gap-[var(--gap-sm,0.5rem)] rounded-sm px-[var(--space-2,0.5rem)] py-1.5 text-sm outline-none transition-all duration-[var(--duration-normal,200ms)] ease-out\",\n\t\t\t\"data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50\",\n\t\t\t\"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground\",\n\t\t\t\"[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n\t\t\tclassName,\n\t\t)}\n\t\t{...props}\n\t/>\n));\nCommandItem.displayName = \"CommandItem\";\n\n/**\n * Keyboard shortcut hint (e.g. '⌘K') aligned to the right of an item.\n * @returns A muted inline span rendered at the end of a CommandItem.\n */\nfunction CommandShortcut({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) {\n\treturn (\n\t\t<span\n\t\t\tclassName={cn(\n\t\t\t\t\"ml-auto text-xs tracking-widest text-muted-foreground\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\nCommandShortcut.displayName = \"CommandShortcut\";\n\nexport {\n\tCommand,\n\tCommandDialog,\n\tCommandInput,\n\tCommandList,\n\tCommandEmpty,\n\tCommandGroup,\n\tCommandItem,\n\tCommandShortcut,\n\tCommandSeparator,\n};\n","\"use client\";\n\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\n/** Root container for a popover. */\nconst Popover = PopoverPrimitive.Root;\n\n/** The element that anchors and opens the popover. */\nconst PopoverTrigger = PopoverPrimitive.Trigger;\n\n/** Helper to explicitly anchor the popover to a different element. */\nconst PopoverAnchor = PopoverPrimitive.Anchor;\n\n/** The floating popover content panel. */\nconst PopoverContent = React.forwardRef<\n\tReact.ComponentRef<typeof PopoverPrimitive.Content>,\n\tReact.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>\n>(({ className, align = \"center\", sideOffset = 4, ...props }, ref) => (\n\t<PopoverPrimitive.Portal>\n\t\t<PopoverPrimitive.Content\n\t\t\tref={ref}\n\t\t\talign={align}\n\t\t\tsideOffset={sideOffset}\n\t\t\tclassName={cn(\n\t\t\t\t\"z-50 w-72 rounded-md border border-foreground/[0.08] bg-popover p-[var(--space-4,1rem)] text-popover-foreground shadow-md outline-none\",\n\t\t\t\t\"data-[state=open]:animate-in data-[state=closed]:animate-out\",\n\t\t\t\t\"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n\t\t\t\t\"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95\",\n\t\t\t\t\"data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t</PopoverPrimitive.Portal>\n));\nPopoverContent.displayName = \"PopoverContent\";\n\nexport { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };\n","\"use client\";\n\nimport * as React from \"react\";\nimport {\n\tCommand,\n\tCommandEmpty,\n\tCommandGroup,\n\tCommandInput,\n\tCommandItem,\n\tCommandList,\n} from \"../command/command.js\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../popover/popover.js\";\nimport { cn } from \"../../lib/utils.js\";\n\ninterface MultiComboboxOption {\n\t/** The value returned in the onChange array (stable, unique). */\n\tvalue: string;\n\t/** The display label shown in the list and the trigger. */\n\tlabel: string;\n\t/** Mark as non-selectable. */\n\tdisabled?: boolean;\n}\n\ninterface MultiComboboxProps {\n\t/** The list of selectable options. */\n\toptions: MultiComboboxOption[];\n\t/** Controlled selected values. */\n\tvalue?: string[];\n\t/** Fired when the user toggles an option: (values: string[]) => void */\n\tonChange?: (values: string[]) => void;\n\t/** Text shown on the trigger when nothing is selected. */\n\tplaceholder?: string;\n\t/** Input placeholder inside the popover list. */\n\tsearchPlaceholder?: string;\n\t/** Text shown when no options match the search. */\n\temptyText?: string;\n\t/** Soft cap on selections. Once reached, unselected options become non-selectable. */\n\tmaxSelected?: number;\n\t/** Close the popover after every pick. Default false (multi-select UX expects staying open). */\n\tcloseOnSelect?: boolean;\n\t/** Disable the trigger. */\n\tdisabled?: boolean;\n\t/** Extra class names on the trigger button. */\n\tclassName?: string;\n\t/** Accessible label for the trigger (required when no adjacent visible label). */\n\t\"aria-label\"?: string;\n\t/** Id of an external visible label that names this combobox. */\n\t\"aria-labelledby\"?: string;\n}\n\n/**\n * Searchable multi-select input built on Command + Popover.\n *\n * Pass `options` with `{ value, label }` and bind `value` (string[]) +\n * `onChange`. The trigger shows \"{n} selected\" once any option is picked, with\n * the comma-separated label list mirrored into the `title` attribute for\n * pointer/screen-reader fallback. Each option is announced with `aria-selected`.\n * @returns A trigger button that opens a multi-select option list.\n */\nfunction MultiCombobox({\n\toptions,\n\tvalue,\n\tonChange,\n\tplaceholder = \"Select…\",\n\tsearchPlaceholder = \"Search…\",\n\temptyText = \"No results found.\",\n\tmaxSelected,\n\tcloseOnSelect = false,\n\tdisabled,\n\tclassName,\n\t\"aria-label\": ariaLabel,\n\t\"aria-labelledby\": ariaLabelledBy,\n}: MultiComboboxProps) {\n\tconst [open, setOpen] = React.useState(false);\n\tconst listboxId = React.useId();\n\tconst selected = React.useMemo(() => new Set(value ?? []), [value]);\n\tconst selectedLabels = React.useMemo(\n\t\t() => options.filter((o) => selected.has(o.value)).map((o) => o.label),\n\t\t[options, selected],\n\t);\n\tconst triggerLabel =\n\t\tselected.size === 0 ? placeholder : `${selected.size} selected`;\n\tconst capReached =\n\t\ttypeof maxSelected === \"number\" && selected.size >= maxSelected;\n\n\tconst toggle = React.useCallback(\n\t\t(optionValue: string) => {\n\t\t\tconst next = new Set(selected);\n\t\t\tif (next.has(optionValue)) {\n\t\t\t\tnext.delete(optionValue);\n\t\t\t} else {\n\t\t\t\tif (capReached) return;\n\t\t\t\tnext.add(optionValue);\n\t\t\t}\n\t\t\tonChange?.(Array.from(next));\n\t\t\tif (closeOnSelect) setOpen(false);\n\t\t},\n\t\t[selected, capReached, onChange, closeOnSelect],\n\t);\n\n\treturn (\n\t\t<>\n\t\t\t<Popover open={open} onOpenChange={setOpen}>\n\t\t\t\t<PopoverTrigger asChild>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\trole=\"combobox\"\n\t\t\t\t\t\taria-expanded={open}\n\t\t\t\t\t\taria-haspopup=\"listbox\"\n\t\t\t\t\t\t/*\n\t\t\t\t\t\t * Only reference the listbox id when the popover is open.\n\t\t\t\t\t\t * The CommandList is portal-mounted by Radix Popover and\n\t\t\t\t\t\t * does not exist in the DOM while closed; pointing at a\n\t\t\t\t\t\t * missing id confuses some screen readers.\n\t\t\t\t\t\t */\n\t\t\t\t\t\taria-controls={open ? listboxId : undefined}\n\t\t\t\t\t\taria-label={ariaLabel}\n\t\t\t\t\t\taria-labelledby={ariaLabelledBy}\n\t\t\t\t\t\ttitle={selectedLabels.length > 0 ? selectedLabels.join(\", \") : undefined}\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\"inline-flex h-[var(--control-height-md,2.5rem)] w-[240px] items-center justify-between gap-[var(--gap-sm,0.5rem)] rounded-md border border-input bg-background px-[var(--space-3,0.75rem)] py-[var(--space-2,0.5rem)] text-sm font-normal transition-all duration-[var(--duration-normal,200ms)] ease-out\",\n\t\t\t\t\t\t\t\"hover:bg-accent hover:text-accent-foreground\",\n\t\t\t\t\t\t\t\"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n\t\t\t\t\t\t\t\"disabled:pointer-events-none disabled:opacity-50\",\n\t\t\t\t\t\t\tselected.size === 0 && \"text-muted-foreground\",\n\t\t\t\t\t\t\tclassName,\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<span className=\"truncate\">{triggerLabel}</span>\n\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\t\tstrokeWidth=\"2\"\n\t\t\t\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\t\t\t\tclassName=\"h-4 w-4 shrink-0 opacity-50\"\n\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<polyline points=\"6 9 12 15 18 9\" />\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t</button>\n\t\t\t\t</PopoverTrigger>\n\t\t\t\t<PopoverContent className=\"w-[240px] p-0\" align=\"start\">\n\t\t\t\t\t<Command>\n\t\t\t\t\t\t<CommandInput placeholder={searchPlaceholder} />\n\t\t\t\t\t\t<CommandList id={listboxId}>\n\t\t\t\t\t\t\t<CommandEmpty>{emptyText}</CommandEmpty>\n\t\t\t\t\t\t\t<CommandGroup>\n\t\t\t\t\t\t\t\t{options.map((option) => {\n\t\t\t\t\t\t\t\t\tconst isSelected = selected.has(option.value);\n\t\t\t\t\t\t\t\t\tconst isCapped = !isSelected && capReached;\n\t\t\t\t\t\t\t\t\tconst itemDisabled = option.disabled || isCapped;\n\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t<CommandItem\n\t\t\t\t\t\t\t\t\t\t\tkey={option.value}\n\t\t\t\t\t\t\t\t\t\t\tvalue={option.label}\n\t\t\t\t\t\t\t\t\t\t\taria-selected={isSelected}\n\t\t\t\t\t\t\t\t\t\t\taria-disabled={itemDisabled || undefined}\n\t\t\t\t\t\t\t\t\t\t\tdisabled={itemDisabled}\n\t\t\t\t\t\t\t\t\t\t\tonSelect={() => {\n\t\t\t\t\t\t\t\t\t\t\t\tif (itemDisabled) return;\n\t\t\t\t\t\t\t\t\t\t\t\ttoggle(option.value);\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\t\t\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\t\t\t\t\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\t\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\t\t\t\t\t\t\tstrokeWidth=\"2\"\n\t\t\t\t\t\t\t\t\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\t\t\t\t\t\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"mr-[var(--space-2,0.5rem)] h-4 w-4\",\n\t\t\t\t\t\t\t\t\t\t\t\t\tisSelected ? \"opacity-100\" : \"opacity-0\",\n\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t<polyline points=\"20 6 9 17 4 12\" />\n\t\t\t\t\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t\t\t\t\t{option.label}\n\t\t\t\t\t\t\t\t\t\t</CommandItem>\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t</CommandGroup>\n\t\t\t\t\t\t</CommandList>\n\t\t\t\t\t</Command>\n\t\t\t\t</PopoverContent>\n\t\t\t</Popover>\n\t\t\t{/*\n\t\t\t * Live region lives outside the trigger so its text is NOT pulled\n\t\t\t * into the button's accessible name (sr-only spans inside a button\n\t\t\t * concatenate via the AccName algorithm). Polite announcements fire\n\t\t\t * only on selection-count changes.\n\t\t\t */}\n\t\t\t<span className=\"sr-only\" aria-live=\"polite\">\n\t\t\t\t{selected.size === 0\n\t\t\t\t\t? \"No items selected\"\n\t\t\t\t\t: `${selected.size} item${selected.size === 1 ? \"\" : \"s\"} selected`}\n\t\t\t</span>\n\t\t</>\n\t);\n}\nMultiCombobox.displayName = \"MultiCombobox\";\n\nexport { MultiCombobox };\nexport type { MultiComboboxOption, MultiComboboxProps };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/utils.ts","../src/components/navigation-menu/navigation-menu.tsx"],"names":[],"mappings":"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","file":"navigation-menu.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as NavigationMenuPrimitive from \"@radix-ui/react-navigation-menu\";\nimport { cva } from \"class-variance-authority\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\n/** Root container for a navigation menu. Renders a viewport for content panels. */\nconst NavigationMenu = React.forwardRef<\n\tReact.ComponentRef<typeof NavigationMenuPrimitive.Root>,\n\tReact.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Root>\n>(({ className, children, ...props }, ref) => (\n\t<NavigationMenuPrimitive.Root\n\t\tref={ref}\n\t\tclassName={cn(\"relative z-10 flex max-w-max flex-1 items-center justify-center\", className)}\n\t\t{...props}\n\t>\n\t\t{children}\n\t\t<NavigationMenuViewport />\n\t</NavigationMenuPrimitive.Root>\n));\nNavigationMenu.displayName = \"NavigationMenu\";\n\n/** List of top-level NavigationMenu items. */\nconst NavigationMenuList = React.forwardRef<\n\tReact.ComponentRef<typeof NavigationMenuPrimitive.List>,\n\tReact.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.List>\n>(({ className, ...props }, ref) => (\n\t<NavigationMenuPrimitive.List\n\t\tref={ref}\n\t\tclassName={cn(\"group flex flex-1 list-none items-center justify-center gap-1\", className)}\n\t\t{...props}\n\t/>\n));\nNavigationMenuList.displayName = \"NavigationMenuList\";\n\n/** A single top-level item (wraps trigger + content). */\nconst NavigationMenuItem = NavigationMenuPrimitive.Item;\n\nconst navigationMenuTriggerStyle = cva(\n\t\"group inline-flex h-[var(--control-height-md,2.5rem)] w-max items-center justify-center rounded-md bg-background px-[var(--space-4,1rem)] py-[var(--space-2,0.5rem)] text-sm font-medium transition-all duration-[var(--duration-normal,200ms)] ease-out hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50\",\n);\n\n/** The clickable trigger that opens a nav-menu content panel. */\nconst NavigationMenuTrigger = React.forwardRef<\n\tReact.ComponentRef<typeof NavigationMenuPrimitive.Trigger>,\n\tReact.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Trigger>\n>(({ className, children, ...props }, ref) => (\n\t<NavigationMenuPrimitive.Trigger\n\t\tref={ref}\n\t\tclassName={cn(navigationMenuTriggerStyle(), \"group\", className)}\n\t\t{...props}\n\t>\n\t\t{children}\n\t\t<svg\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\tstroke=\"currentColor\"\n\t\t\tstrokeWidth=\"2\"\n\t\t\tstrokeLinecap=\"round\"\n\t\t\tstrokeLinejoin=\"round\"\n\t\t\tclassName=\"relative top-[1px] ml-[var(--space-1,0.25rem)] h-3 w-3 transition duration-[var(--duration-normal,200ms)] group-data-[state=open]:rotate-180\"\n\t\t\taria-hidden=\"true\"\n\t\t>\n\t\t\t<polyline points=\"6 9 12 15 18 9\" />\n\t\t</svg>\n\t</NavigationMenuPrimitive.Trigger>\n));\nNavigationMenuTrigger.displayName = \"NavigationMenuTrigger\";\n\n/** The content panel (e.g. mega-menu). */\nconst NavigationMenuContent = React.forwardRef<\n\tReact.ComponentRef<typeof NavigationMenuPrimitive.Content>,\n\tReact.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Content>\n>(({ className, ...props }, ref) => (\n\t<NavigationMenuPrimitive.Content\n\t\tref={ref}\n\t\tclassName={cn(\n\t\t\t\"left-0 top-0 w-full data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 md:absolute md:w-auto\",\n\t\t\tclassName,\n\t\t)}\n\t\t{...props}\n\t/>\n));\nNavigationMenuContent.displayName = \"NavigationMenuContent\";\n\n/** A direct link (no content panel). */\nconst NavigationMenuLink = NavigationMenuPrimitive.Link;\n\n/** The viewport that hosts the active content panel. Rendered inside NavigationMenu. */\nconst NavigationMenuViewport = React.forwardRef<\n\tReact.ComponentRef<typeof NavigationMenuPrimitive.Viewport>,\n\tReact.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Viewport>\n>(({ className, ...props }, ref) => (\n\t<div className=\"absolute left-0 top-full flex justify-center\">\n\t\t<NavigationMenuPrimitive.Viewport\n\t\t\tclassName={cn(\n\t\t\t\t\"origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border border-foreground/[0.08] bg-popover text-popover-foreground shadow-lg\",\n\t\t\t\t\"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90\",\n\t\t\t\t\"md:w-[var(--radix-navigation-menu-viewport-width)]\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\tref={ref}\n\t\t\t{...props}\n\t\t/>\n\t</div>\n));\nNavigationMenuViewport.displayName = \"NavigationMenuViewport\";\n\n/** Visual indicator (arrow) pointing at the active trigger. */\nconst NavigationMenuIndicator = React.forwardRef<\n\tReact.ComponentRef<typeof NavigationMenuPrimitive.Indicator>,\n\tReact.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Indicator>\n>(({ className, ...props }, ref) => (\n\t<NavigationMenuPrimitive.Indicator\n\t\tref={ref}\n\t\tclassName={cn(\n\t\t\t\"top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in\",\n\t\t\tclassName,\n\t\t)}\n\t\t{...props}\n\t>\n\t\t<div className=\"relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-foreground/[0.12] shadow-md\" />\n\t</NavigationMenuPrimitive.Indicator>\n));\nNavigationMenuIndicator.displayName = \"NavigationMenuIndicator\";\n\nexport {\n\tnavigationMenuTriggerStyle,\n\tNavigationMenu,\n\tNavigationMenuList,\n\tNavigationMenuItem,\n\tNavigationMenuContent,\n\tNavigationMenuTrigger,\n\tNavigationMenuLink,\n\tNavigationMenuIndicator,\n\tNavigationMenuViewport,\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/components/navigation-menu/navigation-menu.tsx"],"names":[],"mappings":"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","file":"navigation-menu.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n\nconst SAFE_URL_SCHEMES = [\"http:\", \"https:\", \"mailto:\"] as const;\n\n/**\n * Allowlist a URL for use as an `<a href>` against untrusted input.\n *\n * Returns the raw string when it's `http(s):` / `mailto:` / a relative\n * URL (no scheme); returns `undefined` otherwise. Defends against\n * `javascript:` / `data:` / `vbscript:` injection from streamed model\n * output or third-party JSON payloads that flow into citation chips.\n *\n * Inside a Markdown render path, `rehype-sanitize` already strips\n * `javascript:` from inline-link hrefs — but it does NOT introspect\n * JSON nested inside attribute values (e.g. `<sources data='[…]'/>`),\n * so the components that consume that data must guard themselves.\n *\n * @param raw - The candidate URL, or `undefined` when none was supplied.\n * @returns The URL when safe to render, otherwise `undefined`.\n */\nexport function safeUrl(raw: string | undefined): string | undefined {\n\tif (raw === undefined || raw === \"\") return undefined;\n\t// Relative URLs have no scheme — `new URL(relative)` throws without a base,\n\t// so a thrown URL means either malformed input OR a relative path. Treat\n\t// \"throws + does not contain a colon\" as a relative path (safe).\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(raw);\n\t} catch {\n\t\treturn raw.includes(\":\") ? undefined : raw;\n\t}\n\treturn SAFE_URL_SCHEMES.some((scheme) => scheme === parsed.protocol) ? raw : undefined;\n}\n","\"use client\";\n\nimport * as NavigationMenuPrimitive from \"@radix-ui/react-navigation-menu\";\nimport { cva } from \"class-variance-authority\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\n/** Root container for a navigation menu. Renders a viewport for content panels. */\nconst NavigationMenu = React.forwardRef<\n\tReact.ComponentRef<typeof NavigationMenuPrimitive.Root>,\n\tReact.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Root>\n>(({ className, children, ...props }, ref) => (\n\t<NavigationMenuPrimitive.Root\n\t\tref={ref}\n\t\tclassName={cn(\"relative z-10 flex max-w-max flex-1 items-center justify-center\", className)}\n\t\t{...props}\n\t>\n\t\t{children}\n\t\t<NavigationMenuViewport />\n\t</NavigationMenuPrimitive.Root>\n));\nNavigationMenu.displayName = \"NavigationMenu\";\n\n/** List of top-level NavigationMenu items. */\nconst NavigationMenuList = React.forwardRef<\n\tReact.ComponentRef<typeof NavigationMenuPrimitive.List>,\n\tReact.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.List>\n>(({ className, ...props }, ref) => (\n\t<NavigationMenuPrimitive.List\n\t\tref={ref}\n\t\tclassName={cn(\"group flex flex-1 list-none items-center justify-center gap-1\", className)}\n\t\t{...props}\n\t/>\n));\nNavigationMenuList.displayName = \"NavigationMenuList\";\n\n/** A single top-level item (wraps trigger + content). */\nconst NavigationMenuItem = NavigationMenuPrimitive.Item;\n\nconst navigationMenuTriggerStyle = cva(\n\t\"group inline-flex h-[var(--control-height-md,2.5rem)] w-max items-center justify-center rounded-md bg-background px-[var(--space-4,1rem)] py-[var(--space-2,0.5rem)] text-sm font-medium transition-all duration-[var(--duration-normal,200ms)] ease-out hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50\",\n);\n\n/** The clickable trigger that opens a nav-menu content panel. */\nconst NavigationMenuTrigger = React.forwardRef<\n\tReact.ComponentRef<typeof NavigationMenuPrimitive.Trigger>,\n\tReact.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Trigger>\n>(({ className, children, ...props }, ref) => (\n\t<NavigationMenuPrimitive.Trigger\n\t\tref={ref}\n\t\tclassName={cn(navigationMenuTriggerStyle(), \"group\", className)}\n\t\t{...props}\n\t>\n\t\t{children}\n\t\t<svg\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\tstroke=\"currentColor\"\n\t\t\tstrokeWidth=\"2\"\n\t\t\tstrokeLinecap=\"round\"\n\t\t\tstrokeLinejoin=\"round\"\n\t\t\tclassName=\"relative top-[1px] ml-[var(--space-1,0.25rem)] h-3 w-3 transition duration-[var(--duration-normal,200ms)] group-data-[state=open]:rotate-180\"\n\t\t\taria-hidden=\"true\"\n\t\t>\n\t\t\t<polyline points=\"6 9 12 15 18 9\" />\n\t\t</svg>\n\t</NavigationMenuPrimitive.Trigger>\n));\nNavigationMenuTrigger.displayName = \"NavigationMenuTrigger\";\n\n/** The content panel (e.g. mega-menu). */\nconst NavigationMenuContent = React.forwardRef<\n\tReact.ComponentRef<typeof NavigationMenuPrimitive.Content>,\n\tReact.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Content>\n>(({ className, ...props }, ref) => (\n\t<NavigationMenuPrimitive.Content\n\t\tref={ref}\n\t\tclassName={cn(\n\t\t\t\"left-0 top-0 w-full data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 md:absolute md:w-auto\",\n\t\t\tclassName,\n\t\t)}\n\t\t{...props}\n\t/>\n));\nNavigationMenuContent.displayName = \"NavigationMenuContent\";\n\n/** A direct link (no content panel). */\nconst NavigationMenuLink = NavigationMenuPrimitive.Link;\n\n/** The viewport that hosts the active content panel. Rendered inside NavigationMenu. */\nconst NavigationMenuViewport = React.forwardRef<\n\tReact.ComponentRef<typeof NavigationMenuPrimitive.Viewport>,\n\tReact.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Viewport>\n>(({ className, ...props }, ref) => (\n\t<div className=\"absolute left-0 top-full flex justify-center\">\n\t\t<NavigationMenuPrimitive.Viewport\n\t\t\tclassName={cn(\n\t\t\t\t\"origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border border-foreground/[0.08] bg-popover text-popover-foreground shadow-lg\",\n\t\t\t\t\"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90\",\n\t\t\t\t\"md:w-[var(--radix-navigation-menu-viewport-width)]\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\tref={ref}\n\t\t\t{...props}\n\t\t/>\n\t</div>\n));\nNavigationMenuViewport.displayName = \"NavigationMenuViewport\";\n\n/** Visual indicator (arrow) pointing at the active trigger. */\nconst NavigationMenuIndicator = React.forwardRef<\n\tReact.ComponentRef<typeof NavigationMenuPrimitive.Indicator>,\n\tReact.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Indicator>\n>(({ className, ...props }, ref) => (\n\t<NavigationMenuPrimitive.Indicator\n\t\tref={ref}\n\t\tclassName={cn(\n\t\t\t\"top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in\",\n\t\t\tclassName,\n\t\t)}\n\t\t{...props}\n\t>\n\t\t<div className=\"relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-foreground/[0.12] shadow-md\" />\n\t</NavigationMenuPrimitive.Indicator>\n));\nNavigationMenuIndicator.displayName = \"NavigationMenuIndicator\";\n\nexport {\n\tnavigationMenuTriggerStyle,\n\tNavigationMenu,\n\tNavigationMenuList,\n\tNavigationMenuItem,\n\tNavigationMenuContent,\n\tNavigationMenuTrigger,\n\tNavigationMenuLink,\n\tNavigationMenuIndicator,\n\tNavigationMenuViewport,\n};\n"]}
|
package/dist/org-chart.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/utils.ts","../src/artifacts/org-chart/org-chart.tsx"],"names":[],"mappings":"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","file":"org-chart.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\n/**\n * Top-down organizational chart. Pass a hierarchy of people / teams / units\n * and the component lays them out vertically using d3-hierarchy's tree\n * layout. Nodes can be collapsed by clicking; collapsed branches contribute\n * a \"+N\" badge but no further layout.\n *\n * Heavy peer: requires `d3-hierarchy` (~3 KB gzip).\n *\n * @example\n * <OrgChart\n * root={{\n * id: \"ceo\",\n * label: \"Jane Doe\",\n * subtitle: \"CEO\",\n * children: [\n * { id: \"cto\", label: \"Bob Smith\", subtitle: \"CTO\" },\n * ],\n * }}\n * />\n */\nexport type OrgNode = {\n\tid: string;\n\tlabel: string;\n\tsubtitle?: string;\n\tavatarUrl?: string;\n\tchildren?: OrgNode[];\n};\n\nexport interface OrgChartProps extends Omit<React.SVGAttributes<SVGSVGElement>, \"children\"> {\n\t/** Root of the org hierarchy. */\n\troot: OrgNode;\n\t/** Allow nodes to be clicked to collapse their subtree. Default true. */\n\tcollapsible?: boolean;\n\t/** All nodes deeper than this depth render collapsed by default. Default Infinity (all expanded). */\n\tdefaultExpandedDepth?: number;\n\t/** Pixel width of each node card. Default 180. */\n\tnodeWidth?: number;\n\t/** Pixel height of each node card. Default 64. */\n\tnodeHeight?: number;\n\t/** Pixel width of the rendered SVG. Default 800. */\n\twidth?: number;\n\t/** Pixel height of the rendered SVG. Default 480. */\n\theight?: number;\n\t/** Fired when a node is clicked. Fires before any internal collapse toggle. */\n\tonNodeClick?: (node: OrgNode) => void;\n}\n\ninterface LaidOut {\n\tnode: OrgNode;\n\tx: number;\n\ty: number;\n\tdepth: number;\n\tcollapsedCount: number;\n}\n\ninterface LaidOutLink {\n\tsource: { x: number; y: number };\n\ttarget: { x: number; y: number };\n\tid: string;\n}\n\ntype D3HierarchyMod = typeof import(\"d3-hierarchy\");\n\nfunction OrgChart({\n\troot,\n\tcollapsible = true,\n\tdefaultExpandedDepth = Number.POSITIVE_INFINITY,\n\tnodeWidth = 180,\n\tnodeHeight = 64,\n\twidth = 800,\n\theight = 480,\n\tonNodeClick,\n\tclassName,\n\t...rest\n}: OrgChartProps) {\n\tconst [d3h, setD3h] = React.useState<D3HierarchyMod | null>(null);\n\tconst [collapsed, setCollapsed] = React.useState<Set<string>>(() => seedCollapsed(root, defaultExpandedDepth));\n\n\tReact.useEffect(() => {\n\t\tlet cancelled = false;\n\t\tvoid import(\"d3-hierarchy\").then((mod) => {\n\t\t\tif (!cancelled) setD3h(mod);\n\t\t});\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, []);\n\n\t// Reset collapsed state when the root reference changes — otherwise stale\n\t// ids accumulate across data swaps (memory leak + phantom collapses if ids\n\t// happen to be reused). Mirrors Sunburst's focusId reset.\n\tReact.useEffect(() => {\n\t\tsetCollapsed(seedCollapsed(root, defaultExpandedDepth));\n\t}, [root, defaultExpandedDepth]);\n\n\tif (!d3h) {\n\t\treturn (\n\t\t\t<div\n\t\t\t\tdata-hex-org-chart-loading\n\t\t\t\taria-busy=\"true\"\n\t\t\t\tclassName={cn(\"inline-block bg-muted/20\", className)}\n\t\t\t\tstyle={{ width, height }}\n\t\t\t/>\n\t\t);\n\t}\n\n\tconst { nodes, links } = layout(d3h, root, collapsed, width, height, nodeHeight);\n\tconst desc = `Organizational chart with ${nodes.length} visible node${nodes.length === 1 ? \"\" : \"s\"}, rooted at \"${root.label}\"`;\n\n\tconst handleClick = (node: OrgNode) => {\n\t\tonNodeClick?.(node);\n\t\tif (!collapsible) return;\n\t\tconst hasChildren = node.children && node.children.length > 0;\n\t\tif (!hasChildren) return;\n\t\tsetCollapsed((prev) => {\n\t\t\tconst next = new Set(prev);\n\t\t\tif (next.has(node.id)) next.delete(node.id);\n\t\t\telse next.add(node.id);\n\t\t\treturn next;\n\t\t});\n\t};\n\n\treturn (\n\t\t<svg\n\t\t\t{...rest}\n\t\t\tdata-hex-org-chart\n\t\t\trole=\"img\"\n\t\t\twidth={width}\n\t\t\theight={height}\n\t\t\tviewBox={`0 0 ${width} ${height}`}\n\t\t\tclassName={cn(\"block\", className)}\n\t\t>\n\t\t\t<title>Org chart</title>\n\t\t\t<desc>{desc}</desc>\n\t\t\t<g data-hex-org-chart-links>\n\t\t\t\t{links.map((l) => (\n\t\t\t\t\t<path\n\t\t\t\t\t\tkey={l.id}\n\t\t\t\t\t\td={`M${l.source.x},${l.source.y} C${l.source.x},${(l.source.y + l.target.y) / 2} ${l.target.x},${(l.source.y + l.target.y) / 2} ${l.target.x},${l.target.y}`}\n\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\tstroke=\"hsl(var(--muted-foreground))\"\n\t\t\t\t\t\tstrokeOpacity={0.5}\n\t\t\t\t\t\tstrokeWidth={1}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</g>\n\t\t\t<g data-hex-org-chart-nodes>\n\t\t\t\t{nodes.map((n) => (\n\t\t\t\t\t<g\n\t\t\t\t\t\tkey={n.node.id}\n\t\t\t\t\t\tdata-hex-org-chart-node\n\t\t\t\t\t\tdata-depth={n.depth}\n\t\t\t\t\t\ttransform={`translate(${n.x - nodeWidth / 2},${n.y - nodeHeight / 2})`}\n\t\t\t\t\t\tstyle={collapsible || onNodeClick ? { cursor: \"pointer\" } : undefined}\n\t\t\t\t\t\tonClick={collapsible || onNodeClick ? () => handleClick(n.node) : undefined}\n\t\t\t\t\t>\n\t\t\t\t\t\t<rect\n\t\t\t\t\t\t\twidth={nodeWidth}\n\t\t\t\t\t\t\theight={nodeHeight}\n\t\t\t\t\t\t\trx={8}\n\t\t\t\t\t\t\try={8}\n\t\t\t\t\t\t\tfill=\"hsl(var(--card))\"\n\t\t\t\t\t\t\tstroke=\"hsl(var(--border))\"\n\t\t\t\t\t\t\tstrokeWidth={1}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<text\n\t\t\t\t\t\t\tx={12}\n\t\t\t\t\t\t\ty={24}\n\t\t\t\t\t\t\tfontSize={13}\n\t\t\t\t\t\t\tfontWeight={600}\n\t\t\t\t\t\t\tfill=\"hsl(var(--foreground))\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{truncate(n.node.label, Math.floor((nodeWidth - 24) / 7))}\n\t\t\t\t\t\t</text>\n\t\t\t\t\t\t{n.node.subtitle ? (\n\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\tx={12}\n\t\t\t\t\t\t\t\ty={42}\n\t\t\t\t\t\t\t\tfontSize={11}\n\t\t\t\t\t\t\t\tfill=\"hsl(var(--muted-foreground))\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{truncate(n.node.subtitle, Math.floor((nodeWidth - 24) / 6))}\n\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{n.collapsedCount > 0 ? (\n\t\t\t\t\t\t\t<g transform={`translate(${nodeWidth - 28},${nodeHeight - 18})`}>\n\t\t\t\t\t\t\t\t<rect\n\t\t\t\t\t\t\t\t\twidth={20}\n\t\t\t\t\t\t\t\t\theight={14}\n\t\t\t\t\t\t\t\t\trx={7}\n\t\t\t\t\t\t\t\t\try={7}\n\t\t\t\t\t\t\t\t\tfill=\"hsl(var(--primary))\"\n\t\t\t\t\t\t\t\t\topacity={0.85}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\t\tx={10}\n\t\t\t\t\t\t\t\t\ty={10}\n\t\t\t\t\t\t\t\t\tfontSize={9}\n\t\t\t\t\t\t\t\t\tfontWeight={600}\n\t\t\t\t\t\t\t\t\tfill=\"hsl(var(--primary-foreground))\"\n\t\t\t\t\t\t\t\t\ttextAnchor=\"middle\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{`+${n.collapsedCount}`}\n\t\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t\t</g>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</g>\n\t\t\t\t))}\n\t\t\t</g>\n\t\t</svg>\n\t);\n}\n\nfunction seedCollapsed(root: OrgNode, maxDepth: number): Set<string> {\n\tif (!Number.isFinite(maxDepth)) return new Set();\n\tconst collapsed = new Set<string>();\n\tconst walk = (n: OrgNode, depth: number) => {\n\t\tif (depth >= maxDepth && n.children && n.children.length > 0) {\n\t\t\tcollapsed.add(n.id);\n\t\t\treturn;\n\t\t}\n\t\tn.children?.forEach((c) => walk(c, depth + 1));\n\t};\n\twalk(root, 0);\n\treturn collapsed;\n}\n\nfunction layout(\n\td3h: D3HierarchyMod,\n\troot: OrgNode,\n\tcollapsed: Set<string>,\n\twidth: number,\n\theight: number,\n\tnodeHeight: number,\n): { nodes: LaidOut[]; links: LaidOutLink[] } {\n\t// Pre-build an id → original-node map so collapsed-count lookup is O(1) per\n\t// node (vs O(N) DFS), keeping the whole layout pass O(N) for trees up to a\n\t// few thousand nodes.\n\tconst indexById = new Map<string, OrgNode>();\n\tindexNodes(root, indexById);\n\n\tconst visible = pruneCollapsed(root, collapsed);\n\tconst hierarchy = d3h.hierarchy<OrgNode>(visible);\n\tconst layoutRoot = d3h.tree<OrgNode>().size([width - 32, height - nodeHeight])(hierarchy);\n\tconst nodes: LaidOut[] = [];\n\tlayoutRoot.each((d) => {\n\t\tconst original = indexById.get(d.data.id);\n\t\tconst collapsedCount = collapsed.has(d.data.id) && original ? countDescendants(original) : 0;\n\t\tnodes.push({ node: d.data, x: d.x + 16, y: d.y + nodeHeight / 2, depth: d.depth, collapsedCount });\n\t});\n\tconst links: LaidOutLink[] = layoutRoot.links().map((link, i) => ({\n\t\tsource: { x: link.source.x + 16, y: link.source.y + nodeHeight / 2 },\n\t\ttarget: { x: link.target.x + 16, y: link.target.y + nodeHeight / 2 },\n\t\tid: `l-${i}`,\n\t}));\n\treturn { nodes, links };\n}\n\nfunction pruneCollapsed(node: OrgNode, collapsed: Set<string>): OrgNode {\n\tif (collapsed.has(node.id)) {\n\t\treturn { ...node, children: undefined };\n\t}\n\tif (!node.children || node.children.length === 0) return node;\n\treturn { ...node, children: node.children.map((c) => pruneCollapsed(c, collapsed)) };\n}\n\nfunction indexNodes(node: OrgNode, out: Map<string, OrgNode>): void {\n\tout.set(node.id, node);\n\tif (!node.children) return;\n\tfor (const c of node.children) indexNodes(c, out);\n}\n\nfunction countDescendants(node: OrgNode): number {\n\tif (!node.children || node.children.length === 0) return 0;\n\treturn node.children.reduce((sum, c) => sum + 1 + countDescendants(c), 0);\n}\n\nfunction truncate(s: string, max: number): string {\n\tif (s.length <= max) return s;\n\treturn `${s.slice(0, Math.max(1, max - 1))}…`;\n}\n\nexport { OrgChart };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/artifacts/org-chart/org-chart.tsx"],"names":[],"mappings":"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","file":"org-chart.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n\nconst SAFE_URL_SCHEMES = [\"http:\", \"https:\", \"mailto:\"] as const;\n\n/**\n * Allowlist a URL for use as an `<a href>` against untrusted input.\n *\n * Returns the raw string when it's `http(s):` / `mailto:` / a relative\n * URL (no scheme); returns `undefined` otherwise. Defends against\n * `javascript:` / `data:` / `vbscript:` injection from streamed model\n * output or third-party JSON payloads that flow into citation chips.\n *\n * Inside a Markdown render path, `rehype-sanitize` already strips\n * `javascript:` from inline-link hrefs — but it does NOT introspect\n * JSON nested inside attribute values (e.g. `<sources data='[…]'/>`),\n * so the components that consume that data must guard themselves.\n *\n * @param raw - The candidate URL, or `undefined` when none was supplied.\n * @returns The URL when safe to render, otherwise `undefined`.\n */\nexport function safeUrl(raw: string | undefined): string | undefined {\n\tif (raw === undefined || raw === \"\") return undefined;\n\t// Relative URLs have no scheme — `new URL(relative)` throws without a base,\n\t// so a thrown URL means either malformed input OR a relative path. Treat\n\t// \"throws + does not contain a colon\" as a relative path (safe).\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(raw);\n\t} catch {\n\t\treturn raw.includes(\":\") ? undefined : raw;\n\t}\n\treturn SAFE_URL_SCHEMES.some((scheme) => scheme === parsed.protocol) ? raw : undefined;\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\n/**\n * Top-down organizational chart. Pass a hierarchy of people / teams / units\n * and the component lays them out vertically using d3-hierarchy's tree\n * layout. Nodes can be collapsed by clicking; collapsed branches contribute\n * a \"+N\" badge but no further layout.\n *\n * Heavy peer: requires `d3-hierarchy` (~3 KB gzip).\n *\n * @example\n * <OrgChart\n * root={{\n * id: \"ceo\",\n * label: \"Jane Doe\",\n * subtitle: \"CEO\",\n * children: [\n * { id: \"cto\", label: \"Bob Smith\", subtitle: \"CTO\" },\n * ],\n * }}\n * />\n */\nexport type OrgNode = {\n\tid: string;\n\tlabel: string;\n\tsubtitle?: string;\n\tavatarUrl?: string;\n\tchildren?: OrgNode[];\n};\n\nexport interface OrgChartProps extends Omit<React.SVGAttributes<SVGSVGElement>, \"children\"> {\n\t/** Root of the org hierarchy. */\n\troot: OrgNode;\n\t/** Allow nodes to be clicked to collapse their subtree. Default true. */\n\tcollapsible?: boolean;\n\t/** All nodes deeper than this depth render collapsed by default. Default Infinity (all expanded). */\n\tdefaultExpandedDepth?: number;\n\t/** Pixel width of each node card. Default 180. */\n\tnodeWidth?: number;\n\t/** Pixel height of each node card. Default 64. */\n\tnodeHeight?: number;\n\t/** Pixel width of the rendered SVG. Default 800. */\n\twidth?: number;\n\t/** Pixel height of the rendered SVG. Default 480. */\n\theight?: number;\n\t/** Fired when a node is clicked. Fires before any internal collapse toggle. */\n\tonNodeClick?: (node: OrgNode) => void;\n}\n\ninterface LaidOut {\n\tnode: OrgNode;\n\tx: number;\n\ty: number;\n\tdepth: number;\n\tcollapsedCount: number;\n}\n\ninterface LaidOutLink {\n\tsource: { x: number; y: number };\n\ttarget: { x: number; y: number };\n\tid: string;\n}\n\ntype D3HierarchyMod = typeof import(\"d3-hierarchy\");\n\nfunction OrgChart({\n\troot,\n\tcollapsible = true,\n\tdefaultExpandedDepth = Number.POSITIVE_INFINITY,\n\tnodeWidth = 180,\n\tnodeHeight = 64,\n\twidth = 800,\n\theight = 480,\n\tonNodeClick,\n\tclassName,\n\t...rest\n}: OrgChartProps) {\n\tconst [d3h, setD3h] = React.useState<D3HierarchyMod | null>(null);\n\tconst [collapsed, setCollapsed] = React.useState<Set<string>>(() => seedCollapsed(root, defaultExpandedDepth));\n\n\tReact.useEffect(() => {\n\t\tlet cancelled = false;\n\t\tvoid import(\"d3-hierarchy\").then((mod) => {\n\t\t\tif (!cancelled) setD3h(mod);\n\t\t});\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, []);\n\n\t// Reset collapsed state when the root reference changes — otherwise stale\n\t// ids accumulate across data swaps (memory leak + phantom collapses if ids\n\t// happen to be reused). Mirrors Sunburst's focusId reset.\n\tReact.useEffect(() => {\n\t\tsetCollapsed(seedCollapsed(root, defaultExpandedDepth));\n\t}, [root, defaultExpandedDepth]);\n\n\tif (!d3h) {\n\t\treturn (\n\t\t\t<div\n\t\t\t\tdata-hex-org-chart-loading\n\t\t\t\taria-busy=\"true\"\n\t\t\t\tclassName={cn(\"inline-block bg-muted/20\", className)}\n\t\t\t\tstyle={{ width, height }}\n\t\t\t/>\n\t\t);\n\t}\n\n\tconst { nodes, links } = layout(d3h, root, collapsed, width, height, nodeHeight);\n\tconst desc = `Organizational chart with ${nodes.length} visible node${nodes.length === 1 ? \"\" : \"s\"}, rooted at \"${root.label}\"`;\n\n\tconst handleClick = (node: OrgNode) => {\n\t\tonNodeClick?.(node);\n\t\tif (!collapsible) return;\n\t\tconst hasChildren = node.children && node.children.length > 0;\n\t\tif (!hasChildren) return;\n\t\tsetCollapsed((prev) => {\n\t\t\tconst next = new Set(prev);\n\t\t\tif (next.has(node.id)) next.delete(node.id);\n\t\t\telse next.add(node.id);\n\t\t\treturn next;\n\t\t});\n\t};\n\n\treturn (\n\t\t<svg\n\t\t\t{...rest}\n\t\t\tdata-hex-org-chart\n\t\t\trole=\"img\"\n\t\t\twidth={width}\n\t\t\theight={height}\n\t\t\tviewBox={`0 0 ${width} ${height}`}\n\t\t\tclassName={cn(\"block\", className)}\n\t\t>\n\t\t\t<title>Org chart</title>\n\t\t\t<desc>{desc}</desc>\n\t\t\t<g data-hex-org-chart-links>\n\t\t\t\t{links.map((l) => (\n\t\t\t\t\t<path\n\t\t\t\t\t\tkey={l.id}\n\t\t\t\t\t\td={`M${l.source.x},${l.source.y} C${l.source.x},${(l.source.y + l.target.y) / 2} ${l.target.x},${(l.source.y + l.target.y) / 2} ${l.target.x},${l.target.y}`}\n\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\tstroke=\"hsl(var(--muted-foreground))\"\n\t\t\t\t\t\tstrokeOpacity={0.5}\n\t\t\t\t\t\tstrokeWidth={1}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</g>\n\t\t\t<g data-hex-org-chart-nodes>\n\t\t\t\t{nodes.map((n) => (\n\t\t\t\t\t<g\n\t\t\t\t\t\tkey={n.node.id}\n\t\t\t\t\t\tdata-hex-org-chart-node\n\t\t\t\t\t\tdata-depth={n.depth}\n\t\t\t\t\t\ttransform={`translate(${n.x - nodeWidth / 2},${n.y - nodeHeight / 2})`}\n\t\t\t\t\t\tstyle={collapsible || onNodeClick ? { cursor: \"pointer\" } : undefined}\n\t\t\t\t\t\tonClick={collapsible || onNodeClick ? () => handleClick(n.node) : undefined}\n\t\t\t\t\t>\n\t\t\t\t\t\t<rect\n\t\t\t\t\t\t\twidth={nodeWidth}\n\t\t\t\t\t\t\theight={nodeHeight}\n\t\t\t\t\t\t\trx={8}\n\t\t\t\t\t\t\try={8}\n\t\t\t\t\t\t\tfill=\"hsl(var(--card))\"\n\t\t\t\t\t\t\tstroke=\"hsl(var(--border))\"\n\t\t\t\t\t\t\tstrokeWidth={1}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<text\n\t\t\t\t\t\t\tx={12}\n\t\t\t\t\t\t\ty={24}\n\t\t\t\t\t\t\tfontSize={13}\n\t\t\t\t\t\t\tfontWeight={600}\n\t\t\t\t\t\t\tfill=\"hsl(var(--foreground))\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{truncate(n.node.label, Math.floor((nodeWidth - 24) / 7))}\n\t\t\t\t\t\t</text>\n\t\t\t\t\t\t{n.node.subtitle ? (\n\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\tx={12}\n\t\t\t\t\t\t\t\ty={42}\n\t\t\t\t\t\t\t\tfontSize={11}\n\t\t\t\t\t\t\t\tfill=\"hsl(var(--muted-foreground))\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{truncate(n.node.subtitle, Math.floor((nodeWidth - 24) / 6))}\n\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{n.collapsedCount > 0 ? (\n\t\t\t\t\t\t\t<g transform={`translate(${nodeWidth - 28},${nodeHeight - 18})`}>\n\t\t\t\t\t\t\t\t<rect\n\t\t\t\t\t\t\t\t\twidth={20}\n\t\t\t\t\t\t\t\t\theight={14}\n\t\t\t\t\t\t\t\t\trx={7}\n\t\t\t\t\t\t\t\t\try={7}\n\t\t\t\t\t\t\t\t\tfill=\"hsl(var(--primary))\"\n\t\t\t\t\t\t\t\t\topacity={0.85}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\t\tx={10}\n\t\t\t\t\t\t\t\t\ty={10}\n\t\t\t\t\t\t\t\t\tfontSize={9}\n\t\t\t\t\t\t\t\t\tfontWeight={600}\n\t\t\t\t\t\t\t\t\tfill=\"hsl(var(--primary-foreground))\"\n\t\t\t\t\t\t\t\t\ttextAnchor=\"middle\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{`+${n.collapsedCount}`}\n\t\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t\t</g>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</g>\n\t\t\t\t))}\n\t\t\t</g>\n\t\t</svg>\n\t);\n}\n\nfunction seedCollapsed(root: OrgNode, maxDepth: number): Set<string> {\n\tif (!Number.isFinite(maxDepth)) return new Set();\n\tconst collapsed = new Set<string>();\n\tconst walk = (n: OrgNode, depth: number) => {\n\t\tif (depth >= maxDepth && n.children && n.children.length > 0) {\n\t\t\tcollapsed.add(n.id);\n\t\t\treturn;\n\t\t}\n\t\tn.children?.forEach((c) => walk(c, depth + 1));\n\t};\n\twalk(root, 0);\n\treturn collapsed;\n}\n\nfunction layout(\n\td3h: D3HierarchyMod,\n\troot: OrgNode,\n\tcollapsed: Set<string>,\n\twidth: number,\n\theight: number,\n\tnodeHeight: number,\n): { nodes: LaidOut[]; links: LaidOutLink[] } {\n\t// Pre-build an id → original-node map so collapsed-count lookup is O(1) per\n\t// node (vs O(N) DFS), keeping the whole layout pass O(N) for trees up to a\n\t// few thousand nodes.\n\tconst indexById = new Map<string, OrgNode>();\n\tindexNodes(root, indexById);\n\n\tconst visible = pruneCollapsed(root, collapsed);\n\tconst hierarchy = d3h.hierarchy<OrgNode>(visible);\n\tconst layoutRoot = d3h.tree<OrgNode>().size([width - 32, height - nodeHeight])(hierarchy);\n\tconst nodes: LaidOut[] = [];\n\tlayoutRoot.each((d) => {\n\t\tconst original = indexById.get(d.data.id);\n\t\tconst collapsedCount = collapsed.has(d.data.id) && original ? countDescendants(original) : 0;\n\t\tnodes.push({ node: d.data, x: d.x + 16, y: d.y + nodeHeight / 2, depth: d.depth, collapsedCount });\n\t});\n\tconst links: LaidOutLink[] = layoutRoot.links().map((link, i) => ({\n\t\tsource: { x: link.source.x + 16, y: link.source.y + nodeHeight / 2 },\n\t\ttarget: { x: link.target.x + 16, y: link.target.y + nodeHeight / 2 },\n\t\tid: `l-${i}`,\n\t}));\n\treturn { nodes, links };\n}\n\nfunction pruneCollapsed(node: OrgNode, collapsed: Set<string>): OrgNode {\n\tif (collapsed.has(node.id)) {\n\t\treturn { ...node, children: undefined };\n\t}\n\tif (!node.children || node.children.length === 0) return node;\n\treturn { ...node, children: node.children.map((c) => pruneCollapsed(c, collapsed)) };\n}\n\nfunction indexNodes(node: OrgNode, out: Map<string, OrgNode>): void {\n\tout.set(node.id, node);\n\tif (!node.children) return;\n\tfor (const c of node.children) indexNodes(c, out);\n}\n\nfunction countDescendants(node: OrgNode): number {\n\tif (!node.children || node.children.length === 0) return 0;\n\treturn node.children.reduce((sum, c) => sum + 1 + countDescendants(c), 0);\n}\n\nfunction truncate(s: string, max: number): string {\n\tif (s.length <= max) return s;\n\treturn `${s.slice(0, Math.max(1, max - 1))}…`;\n}\n\nexport { OrgChart };\n"]}
|
package/dist/pagination.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/primitives/button/button-variants.ts","../src/lib/utils.ts","../src/components/pagination/pagination.tsx"],"names":[],"mappings":"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","file":"pagination.js","sourcesContent":["import { type VariantProps, cva } from \"class-variance-authority\";\n\n/**\n * CVA variants for the Button component.\n *\n * Lives in its own module so RSC-safe consumers (`Pagination`, future\n * link-styled buttons in static layouts) can import variants without\n * pulling in the full `Button` runtime — `Button` itself is client-only\n * because of `Slot` + `forwardRef` + the loading spinner. Splitting the\n * variants out keeps `dist/pagination.js` free of `@radix-ui/react-slot`.\n */\nexport const buttonVariants = cva(\n\t[\n\t\t\"inline-flex items-center justify-center gap-[var(--gap-sm,0.5rem)] whitespace-nowrap rounded-md text-sm font-medium\",\n\t\t\"transition-all duration-[var(--duration-normal,200ms)] ease-out\",\n\t\t\"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n\t\t\"disabled:pointer-events-none disabled:opacity-50\",\n\t\t\"active:scale-[0.98]\",\n\t\t\"[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n\t].join(\" \"),\n\t{\n\t\tvariants: {\n\t\t\tvariant: {\n\t\t\t\tdefault: [\n\t\t\t\t\t\"bg-primary text-primary-foreground\",\n\t\t\t\t\t\"shadow-sm shadow-primary/20\",\n\t\t\t\t\t\"hover:bg-primary/90 hover:shadow-md hover:shadow-primary/25\",\n\t\t\t\t].join(\" \"),\n\t\t\t\tdestructive: [\n\t\t\t\t\t\"bg-destructive text-destructive-foreground\",\n\t\t\t\t\t\"shadow-sm shadow-destructive/20\",\n\t\t\t\t\t\"hover:bg-destructive/90 hover:shadow-md hover:shadow-destructive/25\",\n\t\t\t\t].join(\" \"),\n\t\t\t\toutline: [\n\t\t\t\t\t\"border border-input bg-background\",\n\t\t\t\t\t\"shadow-sm inset-ring-1 inset-ring-foreground/[0.06]\",\n\t\t\t\t\t\"hover:bg-accent hover:text-accent-foreground hover:shadow-md hover:inset-ring-foreground/12\",\n\t\t\t\t].join(\" \"),\n\t\t\t\tsecondary: [\n\t\t\t\t\t\"bg-secondary text-secondary-foreground\",\n\t\t\t\t\t\"shadow-sm inset-ring-1 inset-ring-foreground/[0.08]\",\n\t\t\t\t\t\"hover:bg-secondary/80 hover:shadow-md hover:inset-ring-foreground/15\",\n\t\t\t\t].join(\" \"),\n\t\t\t\tghost: \"hover:bg-accent hover:text-accent-foreground\",\n\t\t\t\tlink: \"text-primary underline-offset-4 hover:underline\",\n\t\t\t},\n\t\t\tsize: {\n\t\t\t\tdefault:\n\t\t\t\t\t\"h-[var(--control-height-md,2.5rem)] px-[var(--space-4,1rem)] py-[var(--space-2,0.5rem)]\",\n\t\t\t\tsm: \"h-[var(--control-height-sm,2.25rem)] rounded-md px-[var(--space-3,0.75rem)]\",\n\t\t\t\tlg: \"h-[var(--control-height-lg,2.75rem)] rounded-md px-[var(--space-8,2rem)] text-base\",\n\t\t\t\ticon: \"h-[var(--control-height-md,2.5rem)] w-[var(--control-height-md,2.5rem)]\",\n\t\t\t},\n\t\t},\n\t\tdefaultVariants: {\n\t\t\tvariant: \"default\",\n\t\t\tsize: \"default\",\n\t\t},\n\t},\n);\n\nexport type ButtonVariantsProps = VariantProps<typeof buttonVariants>;\n","import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\nimport {\n\ttype ButtonVariantsProps,\n\tbuttonVariants,\n} from \"../../primitives/button/button-variants.js\";\nimport { cn } from \"../../lib/utils.js\";\n\n/**\n * Root nav landmark for pagination controls.\n * @returns A centered nav element with aria-label='pagination'\n */\nfunction Pagination({ className, ...props }: React.ComponentProps<\"nav\">) {\n\treturn (\n\t\t<nav\n\t\t\trole=\"navigation\"\n\t\t\taria-label=\"pagination\"\n\t\t\tclassName={cn(\"mx-auto flex w-full justify-center\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\n/** Ordered list wrapper for pagination links. */\nconst PaginationContent = React.forwardRef<HTMLUListElement, React.ComponentProps<\"ul\">>(\n\t({ className, ...props }, ref) => (\n\t\t<ul\n\t\t\tref={ref}\n\t\t\tclassName={cn(\"flex flex-row items-center gap-1\", className)}\n\t\t\t{...props}\n\t\t/>\n\t),\n);\nPaginationContent.displayName = \"PaginationContent\";\n\n/** A pagination list item wrapper. */\nconst PaginationItem = React.forwardRef<HTMLLIElement, React.ComponentProps<\"li\">>(\n\t({ className, ...props }, ref) => <li ref={ref} className={className} {...props} />,\n);\nPaginationItem.displayName = \"PaginationItem\";\n\ntype PaginationLinkProps = {\n\tisActive?: boolean;\n} & Pick<ButtonVariantsProps, \"size\"> &\n\tReact.ComponentProps<\"a\">;\n\n/**\n * A pagination link styled as a button. Mark the current page with isActive.\n * @returns An anchor element styled via buttonVariants\n */\nfunction PaginationLink({\n\tclassName,\n\tisActive,\n\tsize = \"icon\",\n\t...props\n}: PaginationLinkProps) {\n\treturn (\n\t\t<a\n\t\t\taria-current={isActive ? \"page\" : undefined}\n\t\t\tclassName={cn(\n\t\t\t\tbuttonVariants({ variant: isActive ? \"outline\" : \"ghost\", size }),\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\n/**\n * Previous-page link with chevron-left icon.\n * @returns A PaginationLink with aria-label='Go to previous page'\n */\nfunction PaginationPrevious({ className, ...props }: React.ComponentProps<typeof PaginationLink>) {\n\treturn (\n\t\t<PaginationLink\n\t\t\taria-label=\"Go to previous page\"\n\t\t\tsize=\"default\"\n\t\t\tclassName={cn(\"gap-1 pl-2.5\", className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<svg\n\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\tfill=\"none\"\n\t\t\t\tstroke=\"currentColor\"\n\t\t\t\tstrokeWidth=\"2\"\n\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\tclassName=\"h-4 w-4\"\n\t\t\t\taria-hidden=\"true\"\n\t\t\t>\n\t\t\t\t<polyline points=\"15 18 9 12 15 6\" />\n\t\t\t</svg>\n\t\t\t<span>Previous</span>\n\t\t</PaginationLink>\n\t);\n}\n\n/**\n * Next-page link with chevron-right icon.\n * @returns A PaginationLink with aria-label='Go to next page'\n */\nfunction PaginationNext({ className, ...props }: React.ComponentProps<typeof PaginationLink>) {\n\treturn (\n\t\t<PaginationLink\n\t\t\taria-label=\"Go to next page\"\n\t\t\tsize=\"default\"\n\t\t\tclassName={cn(\"gap-1 pr-2.5\", className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<span>Next</span>\n\t\t\t<svg\n\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\tfill=\"none\"\n\t\t\t\tstroke=\"currentColor\"\n\t\t\t\tstrokeWidth=\"2\"\n\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\tclassName=\"h-4 w-4\"\n\t\t\t\taria-hidden=\"true\"\n\t\t\t>\n\t\t\t\t<polyline points=\"9 18 15 12 9 6\" />\n\t\t\t</svg>\n\t\t</PaginationLink>\n\t);\n}\n\n/**\n * Ellipsis placeholder for truncated page ranges (e.g. 1 … 5 6 7 … 99).\n * @returns A span containing a decorative SVG (aria-hidden) plus a sr-only \"More pages\" label for AT.\n */\nfunction PaginationEllipsis({ className, ...props }: React.ComponentProps<\"span\">) {\n\t// Wrapper stays reachable by AT; only the decorative SVG is aria-hidden so the\n\t// sr-only \"More pages\" label actually reaches screen readers.\n\treturn (\n\t\t<span\n\t\t\tclassName={cn(\"flex h-[var(--control-height-sm,2.25rem)] w-[var(--control-height-sm,2.25rem)] items-center justify-center\", className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<svg\n\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\tfill=\"none\"\n\t\t\t\tstroke=\"currentColor\"\n\t\t\t\tstrokeWidth=\"2\"\n\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\tclassName=\"h-4 w-4\"\n\t\t\t\taria-hidden=\"true\"\n\t\t\t>\n\t\t\t\t<circle cx=\"12\" cy=\"12\" r=\"1\" />\n\t\t\t\t<circle cx=\"19\" cy=\"12\" r=\"1\" />\n\t\t\t\t<circle cx=\"5\" cy=\"12\" r=\"1\" />\n\t\t\t</svg>\n\t\t\t<span className=\"sr-only\">More pages</span>\n\t\t</span>\n\t);\n}\n\nexport {\n\tPagination,\n\tPaginationContent,\n\tPaginationEllipsis,\n\tPaginationItem,\n\tPaginationLink,\n\tPaginationNext,\n\tPaginationPrevious,\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/primitives/button/button-variants.ts","../src/lib/utils.ts","../src/components/pagination/pagination.tsx"],"names":[],"mappings":"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","file":"pagination.js","sourcesContent":["import { type VariantProps, cva } from \"class-variance-authority\";\n\n/**\n * CVA variants for the Button component.\n *\n * Lives in its own module so RSC-safe consumers (`Pagination`, future\n * link-styled buttons in static layouts) can import variants without\n * pulling in the full `Button` runtime — `Button` itself is client-only\n * because of `Slot` + `forwardRef` + the loading spinner. Splitting the\n * variants out keeps `dist/pagination.js` free of `@radix-ui/react-slot`.\n */\nexport const buttonVariants = cva(\n\t[\n\t\t\"inline-flex items-center justify-center gap-[var(--gap-sm,0.5rem)] whitespace-nowrap rounded-md text-sm font-medium\",\n\t\t\"transition-all duration-[var(--duration-normal,200ms)] ease-out\",\n\t\t\"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n\t\t\"disabled:pointer-events-none disabled:opacity-50\",\n\t\t\"active:scale-[0.98]\",\n\t\t\"[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n\t].join(\" \"),\n\t{\n\t\tvariants: {\n\t\t\tvariant: {\n\t\t\t\tdefault: [\n\t\t\t\t\t\"bg-primary text-primary-foreground\",\n\t\t\t\t\t\"shadow-sm shadow-primary/20\",\n\t\t\t\t\t\"hover:bg-primary/90 hover:shadow-md hover:shadow-primary/25\",\n\t\t\t\t].join(\" \"),\n\t\t\t\tdestructive: [\n\t\t\t\t\t\"bg-destructive text-destructive-foreground\",\n\t\t\t\t\t\"shadow-sm shadow-destructive/20\",\n\t\t\t\t\t\"hover:bg-destructive/90 hover:shadow-md hover:shadow-destructive/25\",\n\t\t\t\t].join(\" \"),\n\t\t\t\toutline: [\n\t\t\t\t\t\"border border-input bg-background\",\n\t\t\t\t\t\"shadow-sm inset-ring-1 inset-ring-foreground/[0.06]\",\n\t\t\t\t\t\"hover:bg-accent hover:text-accent-foreground hover:shadow-md hover:inset-ring-foreground/12\",\n\t\t\t\t].join(\" \"),\n\t\t\t\tsecondary: [\n\t\t\t\t\t\"bg-secondary text-secondary-foreground\",\n\t\t\t\t\t\"shadow-sm inset-ring-1 inset-ring-foreground/[0.08]\",\n\t\t\t\t\t\"hover:bg-secondary/80 hover:shadow-md hover:inset-ring-foreground/15\",\n\t\t\t\t].join(\" \"),\n\t\t\t\tghost: \"hover:bg-accent hover:text-accent-foreground\",\n\t\t\t\tlink: \"text-primary underline-offset-4 hover:underline\",\n\t\t\t},\n\t\t\tsize: {\n\t\t\t\tdefault:\n\t\t\t\t\t\"h-[var(--control-height-md,2.5rem)] px-[var(--space-4,1rem)] py-[var(--space-2,0.5rem)]\",\n\t\t\t\tsm: \"h-[var(--control-height-sm,2.25rem)] rounded-md px-[var(--space-3,0.75rem)]\",\n\t\t\t\tlg: \"h-[var(--control-height-lg,2.75rem)] rounded-md px-[var(--space-8,2rem)] text-base\",\n\t\t\t\ticon: \"h-[var(--control-height-md,2.5rem)] w-[var(--control-height-md,2.5rem)]\",\n\t\t\t},\n\t\t},\n\t\tdefaultVariants: {\n\t\t\tvariant: \"default\",\n\t\t\tsize: \"default\",\n\t\t},\n\t},\n);\n\nexport type ButtonVariantsProps = VariantProps<typeof buttonVariants>;\n","import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n\nconst SAFE_URL_SCHEMES = [\"http:\", \"https:\", \"mailto:\"] as const;\n\n/**\n * Allowlist a URL for use as an `<a href>` against untrusted input.\n *\n * Returns the raw string when it's `http(s):` / `mailto:` / a relative\n * URL (no scheme); returns `undefined` otherwise. Defends against\n * `javascript:` / `data:` / `vbscript:` injection from streamed model\n * output or third-party JSON payloads that flow into citation chips.\n *\n * Inside a Markdown render path, `rehype-sanitize` already strips\n * `javascript:` from inline-link hrefs — but it does NOT introspect\n * JSON nested inside attribute values (e.g. `<sources data='[…]'/>`),\n * so the components that consume that data must guard themselves.\n *\n * @param raw - The candidate URL, or `undefined` when none was supplied.\n * @returns The URL when safe to render, otherwise `undefined`.\n */\nexport function safeUrl(raw: string | undefined): string | undefined {\n\tif (raw === undefined || raw === \"\") return undefined;\n\t// Relative URLs have no scheme — `new URL(relative)` throws without a base,\n\t// so a thrown URL means either malformed input OR a relative path. Treat\n\t// \"throws + does not contain a colon\" as a relative path (safe).\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(raw);\n\t} catch {\n\t\treturn raw.includes(\":\") ? undefined : raw;\n\t}\n\treturn SAFE_URL_SCHEMES.some((scheme) => scheme === parsed.protocol) ? raw : undefined;\n}\n","import * as React from \"react\";\nimport {\n\ttype ButtonVariantsProps,\n\tbuttonVariants,\n} from \"../../primitives/button/button-variants.js\";\nimport { cn } from \"../../lib/utils.js\";\n\n/**\n * Root nav landmark for pagination controls.\n * @returns A centered nav element with aria-label='pagination'\n */\nfunction Pagination({ className, ...props }: React.ComponentProps<\"nav\">) {\n\treturn (\n\t\t<nav\n\t\t\trole=\"navigation\"\n\t\t\taria-label=\"pagination\"\n\t\t\tclassName={cn(\"mx-auto flex w-full justify-center\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\n/** Ordered list wrapper for pagination links. */\nconst PaginationContent = React.forwardRef<HTMLUListElement, React.ComponentProps<\"ul\">>(\n\t({ className, ...props }, ref) => (\n\t\t<ul\n\t\t\tref={ref}\n\t\t\tclassName={cn(\"flex flex-row items-center gap-1\", className)}\n\t\t\t{...props}\n\t\t/>\n\t),\n);\nPaginationContent.displayName = \"PaginationContent\";\n\n/** A pagination list item wrapper. */\nconst PaginationItem = React.forwardRef<HTMLLIElement, React.ComponentProps<\"li\">>(\n\t({ className, ...props }, ref) => <li ref={ref} className={className} {...props} />,\n);\nPaginationItem.displayName = \"PaginationItem\";\n\ntype PaginationLinkProps = {\n\tisActive?: boolean;\n} & Pick<ButtonVariantsProps, \"size\"> &\n\tReact.ComponentProps<\"a\">;\n\n/**\n * A pagination link styled as a button. Mark the current page with isActive.\n * @returns An anchor element styled via buttonVariants\n */\nfunction PaginationLink({\n\tclassName,\n\tisActive,\n\tsize = \"icon\",\n\t...props\n}: PaginationLinkProps) {\n\treturn (\n\t\t<a\n\t\t\taria-current={isActive ? \"page\" : undefined}\n\t\t\tclassName={cn(\n\t\t\t\tbuttonVariants({ variant: isActive ? \"outline\" : \"ghost\", size }),\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\n/**\n * Previous-page link with chevron-left icon.\n * @returns A PaginationLink with aria-label='Go to previous page'\n */\nfunction PaginationPrevious({ className, ...props }: React.ComponentProps<typeof PaginationLink>) {\n\treturn (\n\t\t<PaginationLink\n\t\t\taria-label=\"Go to previous page\"\n\t\t\tsize=\"default\"\n\t\t\tclassName={cn(\"gap-1 pl-2.5\", className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<svg\n\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\tfill=\"none\"\n\t\t\t\tstroke=\"currentColor\"\n\t\t\t\tstrokeWidth=\"2\"\n\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\tclassName=\"h-4 w-4\"\n\t\t\t\taria-hidden=\"true\"\n\t\t\t>\n\t\t\t\t<polyline points=\"15 18 9 12 15 6\" />\n\t\t\t</svg>\n\t\t\t<span>Previous</span>\n\t\t</PaginationLink>\n\t);\n}\n\n/**\n * Next-page link with chevron-right icon.\n * @returns A PaginationLink with aria-label='Go to next page'\n */\nfunction PaginationNext({ className, ...props }: React.ComponentProps<typeof PaginationLink>) {\n\treturn (\n\t\t<PaginationLink\n\t\t\taria-label=\"Go to next page\"\n\t\t\tsize=\"default\"\n\t\t\tclassName={cn(\"gap-1 pr-2.5\", className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<span>Next</span>\n\t\t\t<svg\n\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\tfill=\"none\"\n\t\t\t\tstroke=\"currentColor\"\n\t\t\t\tstrokeWidth=\"2\"\n\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\tclassName=\"h-4 w-4\"\n\t\t\t\taria-hidden=\"true\"\n\t\t\t>\n\t\t\t\t<polyline points=\"9 18 15 12 9 6\" />\n\t\t\t</svg>\n\t\t</PaginationLink>\n\t);\n}\n\n/**\n * Ellipsis placeholder for truncated page ranges (e.g. 1 … 5 6 7 … 99).\n * @returns A span containing a decorative SVG (aria-hidden) plus a sr-only \"More pages\" label for AT.\n */\nfunction PaginationEllipsis({ className, ...props }: React.ComponentProps<\"span\">) {\n\t// Wrapper stays reachable by AT; only the decorative SVG is aria-hidden so the\n\t// sr-only \"More pages\" label actually reaches screen readers.\n\treturn (\n\t\t<span\n\t\t\tclassName={cn(\"flex h-[var(--control-height-sm,2.25rem)] w-[var(--control-height-sm,2.25rem)] items-center justify-center\", className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<svg\n\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\tfill=\"none\"\n\t\t\t\tstroke=\"currentColor\"\n\t\t\t\tstrokeWidth=\"2\"\n\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\tclassName=\"h-4 w-4\"\n\t\t\t\taria-hidden=\"true\"\n\t\t\t>\n\t\t\t\t<circle cx=\"12\" cy=\"12\" r=\"1\" />\n\t\t\t\t<circle cx=\"19\" cy=\"12\" r=\"1\" />\n\t\t\t\t<circle cx=\"5\" cy=\"12\" r=\"1\" />\n\t\t\t</svg>\n\t\t\t<span className=\"sr-only\">More pages</span>\n\t\t</span>\n\t);\n}\n\nexport {\n\tPagination,\n\tPaginationContent,\n\tPaginationEllipsis,\n\tPaginationItem,\n\tPaginationLink,\n\tPaginationNext,\n\tPaginationPrevious,\n};\n"]}
|
package/dist/plan.d.ts
ADDED
package/dist/plan.js
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { clsx } from 'clsx';
|
|
5
|
+
import { twMerge } from 'tailwind-merge';
|
|
6
|
+
import { cva } from 'class-variance-authority';
|
|
7
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
8
|
+
|
|
9
|
+
function cn(...inputs) {
|
|
10
|
+
return twMerge(clsx(inputs));
|
|
11
|
+
}
|
|
12
|
+
var buttonVariants = cva(
|
|
13
|
+
[
|
|
14
|
+
"inline-flex items-center justify-center gap-[var(--gap-sm,0.5rem)] whitespace-nowrap rounded-md text-sm font-medium",
|
|
15
|
+
"transition-all duration-[var(--duration-normal,200ms)] ease-out",
|
|
16
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
17
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
18
|
+
"active:scale-[0.98]",
|
|
19
|
+
"[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0"
|
|
20
|
+
].join(" "),
|
|
21
|
+
{
|
|
22
|
+
variants: {
|
|
23
|
+
variant: {
|
|
24
|
+
default: [
|
|
25
|
+
"bg-primary text-primary-foreground",
|
|
26
|
+
"shadow-sm shadow-primary/20",
|
|
27
|
+
"hover:bg-primary/90 hover:shadow-md hover:shadow-primary/25"
|
|
28
|
+
].join(" "),
|
|
29
|
+
destructive: [
|
|
30
|
+
"bg-destructive text-destructive-foreground",
|
|
31
|
+
"shadow-sm shadow-destructive/20",
|
|
32
|
+
"hover:bg-destructive/90 hover:shadow-md hover:shadow-destructive/25"
|
|
33
|
+
].join(" "),
|
|
34
|
+
outline: [
|
|
35
|
+
"border border-input bg-background",
|
|
36
|
+
"shadow-sm inset-ring-1 inset-ring-foreground/[0.06]",
|
|
37
|
+
"hover:bg-accent hover:text-accent-foreground hover:shadow-md hover:inset-ring-foreground/12"
|
|
38
|
+
].join(" "),
|
|
39
|
+
secondary: [
|
|
40
|
+
"bg-secondary text-secondary-foreground",
|
|
41
|
+
"shadow-sm inset-ring-1 inset-ring-foreground/[0.08]",
|
|
42
|
+
"hover:bg-secondary/80 hover:shadow-md hover:inset-ring-foreground/15"
|
|
43
|
+
].join(" "),
|
|
44
|
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
45
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
46
|
+
},
|
|
47
|
+
size: {
|
|
48
|
+
default: "h-[var(--control-height-md,2.5rem)] px-[var(--space-4,1rem)] py-[var(--space-2,0.5rem)]",
|
|
49
|
+
sm: "h-[var(--control-height-sm,2.25rem)] rounded-md px-[var(--space-3,0.75rem)]",
|
|
50
|
+
lg: "h-[var(--control-height-lg,2.75rem)] rounded-md px-[var(--space-8,2rem)] text-base",
|
|
51
|
+
icon: "h-[var(--control-height-md,2.5rem)] w-[var(--control-height-md,2.5rem)]"
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
defaultVariants: {
|
|
55
|
+
variant: "default",
|
|
56
|
+
size: "default"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
);
|
|
60
|
+
var Button = React.forwardRef(
|
|
61
|
+
({ className, variant, size, asChild = false, loading = false, children, disabled, ...props }, ref) => {
|
|
62
|
+
const Comp = asChild ? Slot : "button";
|
|
63
|
+
return /* @__PURE__ */ jsx(
|
|
64
|
+
Comp,
|
|
65
|
+
{
|
|
66
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
67
|
+
ref,
|
|
68
|
+
disabled: disabled || loading,
|
|
69
|
+
"aria-busy": loading || void 0,
|
|
70
|
+
...props,
|
|
71
|
+
children: loading ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
72
|
+
/* @__PURE__ */ jsxs(
|
|
73
|
+
"svg",
|
|
74
|
+
{
|
|
75
|
+
className: "animate-spin h-4 w-4",
|
|
76
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
77
|
+
fill: "none",
|
|
78
|
+
viewBox: "0 0 24 24",
|
|
79
|
+
"aria-hidden": "true",
|
|
80
|
+
children: [
|
|
81
|
+
/* @__PURE__ */ jsx(
|
|
82
|
+
"circle",
|
|
83
|
+
{
|
|
84
|
+
className: "opacity-25",
|
|
85
|
+
cx: "12",
|
|
86
|
+
cy: "12",
|
|
87
|
+
r: "10",
|
|
88
|
+
stroke: "currentColor",
|
|
89
|
+
strokeWidth: "4"
|
|
90
|
+
}
|
|
91
|
+
),
|
|
92
|
+
/* @__PURE__ */ jsx(
|
|
93
|
+
"path",
|
|
94
|
+
{
|
|
95
|
+
className: "opacity-75",
|
|
96
|
+
fill: "currentColor",
|
|
97
|
+
d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
|
98
|
+
}
|
|
99
|
+
)
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
),
|
|
103
|
+
children
|
|
104
|
+
] }) : children
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
);
|
|
109
|
+
Button.displayName = "Button";
|
|
110
|
+
function Plan({
|
|
111
|
+
label,
|
|
112
|
+
description,
|
|
113
|
+
steps,
|
|
114
|
+
onApprove,
|
|
115
|
+
onCancel,
|
|
116
|
+
approveLabel = "Approve",
|
|
117
|
+
cancelLabel = "Cancel",
|
|
118
|
+
className
|
|
119
|
+
}) {
|
|
120
|
+
const showFooter = typeof onApprove === "function" || typeof onCancel === "function";
|
|
121
|
+
return /* @__PURE__ */ jsxs(
|
|
122
|
+
"div",
|
|
123
|
+
{
|
|
124
|
+
className: cn(
|
|
125
|
+
"overflow-hidden rounded-md border border-border bg-card",
|
|
126
|
+
className
|
|
127
|
+
),
|
|
128
|
+
children: [
|
|
129
|
+
label || description ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5 border-b border-foreground/[0.06] px-3 py-2", children: [
|
|
130
|
+
label ? /* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-foreground", children: label }) : null,
|
|
131
|
+
description ? /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: description }) : null
|
|
132
|
+
] }) : null,
|
|
133
|
+
/* @__PURE__ */ jsx(
|
|
134
|
+
"ol",
|
|
135
|
+
{
|
|
136
|
+
"aria-label": label ? `${label} steps` : "Plan steps",
|
|
137
|
+
className: "my-0 ml-0 flex list-none flex-col gap-2 py-3 pr-3 pl-3",
|
|
138
|
+
children: steps.map((step, index) => (
|
|
139
|
+
/*
|
|
140
|
+
* `before:content-none` defeats Tailwind Typography's
|
|
141
|
+
* default `<li>::before` markers when this card lands
|
|
142
|
+
* inside a `prose` block (assistant turn, MDX page).
|
|
143
|
+
* Don't strip — the indicator handles ordinal display.
|
|
144
|
+
*/
|
|
145
|
+
/* @__PURE__ */ jsxs(
|
|
146
|
+
"li",
|
|
147
|
+
{
|
|
148
|
+
className: "flex items-start gap-3 text-sm before:content-none",
|
|
149
|
+
children: [
|
|
150
|
+
/* @__PURE__ */ jsx(
|
|
151
|
+
"span",
|
|
152
|
+
{
|
|
153
|
+
"aria-hidden": true,
|
|
154
|
+
className: cn(
|
|
155
|
+
"mt-0.5 inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-full",
|
|
156
|
+
"border border-input bg-background text-[0.65rem] font-medium tabular-nums text-muted-foreground"
|
|
157
|
+
),
|
|
158
|
+
children: index + 1
|
|
159
|
+
}
|
|
160
|
+
),
|
|
161
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col gap-0.5", children: [
|
|
162
|
+
/* @__PURE__ */ jsx("span", { className: "leading-snug text-foreground", children: step.label }),
|
|
163
|
+
step.detail ? /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: step.detail }) : null
|
|
164
|
+
] })
|
|
165
|
+
]
|
|
166
|
+
},
|
|
167
|
+
step.id
|
|
168
|
+
)
|
|
169
|
+
))
|
|
170
|
+
}
|
|
171
|
+
),
|
|
172
|
+
showFooter ? /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-2 border-t border-foreground/[0.06] bg-muted/20 px-3 py-2", children: [
|
|
173
|
+
typeof onCancel === "function" ? /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: onCancel, children: cancelLabel }) : null,
|
|
174
|
+
typeof onApprove === "function" ? /* @__PURE__ */ jsx(Button, { variant: "default", size: "sm", onClick: onApprove, children: approveLabel }) : null
|
|
175
|
+
] }) : null
|
|
176
|
+
]
|
|
177
|
+
}
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export { Plan };
|
|
182
|
+
//# sourceMappingURL=plan.js.map
|
|
183
|
+
//# sourceMappingURL=plan.js.map
|
package/dist/plan.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/primitives/button/button-variants.ts","../src/primitives/button/button.tsx","../src/ai/plan/plan.tsx"],"names":["jsxs","jsx"],"mappings":"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","file":"plan.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n\nconst SAFE_URL_SCHEMES = [\"http:\", \"https:\", \"mailto:\"] as const;\n\n/**\n * Allowlist a URL for use as an `<a href>` against untrusted input.\n *\n * Returns the raw string when it's `http(s):` / `mailto:` / a relative\n * URL (no scheme); returns `undefined` otherwise. Defends against\n * `javascript:` / `data:` / `vbscript:` injection from streamed model\n * output or third-party JSON payloads that flow into citation chips.\n *\n * Inside a Markdown render path, `rehype-sanitize` already strips\n * `javascript:` from inline-link hrefs — but it does NOT introspect\n * JSON nested inside attribute values (e.g. `<sources data='[…]'/>`),\n * so the components that consume that data must guard themselves.\n *\n * @param raw - The candidate URL, or `undefined` when none was supplied.\n * @returns The URL when safe to render, otherwise `undefined`.\n */\nexport function safeUrl(raw: string | undefined): string | undefined {\n\tif (raw === undefined || raw === \"\") return undefined;\n\t// Relative URLs have no scheme — `new URL(relative)` throws without a base,\n\t// so a thrown URL means either malformed input OR a relative path. Treat\n\t// \"throws + does not contain a colon\" as a relative path (safe).\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(raw);\n\t} catch {\n\t\treturn raw.includes(\":\") ? undefined : raw;\n\t}\n\treturn SAFE_URL_SCHEMES.some((scheme) => scheme === parsed.protocol) ? raw : undefined;\n}\n","import { type VariantProps, cva } from \"class-variance-authority\";\n\n/**\n * CVA variants for the Button component.\n *\n * Lives in its own module so RSC-safe consumers (`Pagination`, future\n * link-styled buttons in static layouts) can import variants without\n * pulling in the full `Button` runtime — `Button` itself is client-only\n * because of `Slot` + `forwardRef` + the loading spinner. Splitting the\n * variants out keeps `dist/pagination.js` free of `@radix-ui/react-slot`.\n */\nexport const buttonVariants = cva(\n\t[\n\t\t\"inline-flex items-center justify-center gap-[var(--gap-sm,0.5rem)] whitespace-nowrap rounded-md text-sm font-medium\",\n\t\t\"transition-all duration-[var(--duration-normal,200ms)] ease-out\",\n\t\t\"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n\t\t\"disabled:pointer-events-none disabled:opacity-50\",\n\t\t\"active:scale-[0.98]\",\n\t\t\"[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n\t].join(\" \"),\n\t{\n\t\tvariants: {\n\t\t\tvariant: {\n\t\t\t\tdefault: [\n\t\t\t\t\t\"bg-primary text-primary-foreground\",\n\t\t\t\t\t\"shadow-sm shadow-primary/20\",\n\t\t\t\t\t\"hover:bg-primary/90 hover:shadow-md hover:shadow-primary/25\",\n\t\t\t\t].join(\" \"),\n\t\t\t\tdestructive: [\n\t\t\t\t\t\"bg-destructive text-destructive-foreground\",\n\t\t\t\t\t\"shadow-sm shadow-destructive/20\",\n\t\t\t\t\t\"hover:bg-destructive/90 hover:shadow-md hover:shadow-destructive/25\",\n\t\t\t\t].join(\" \"),\n\t\t\t\toutline: [\n\t\t\t\t\t\"border border-input bg-background\",\n\t\t\t\t\t\"shadow-sm inset-ring-1 inset-ring-foreground/[0.06]\",\n\t\t\t\t\t\"hover:bg-accent hover:text-accent-foreground hover:shadow-md hover:inset-ring-foreground/12\",\n\t\t\t\t].join(\" \"),\n\t\t\t\tsecondary: [\n\t\t\t\t\t\"bg-secondary text-secondary-foreground\",\n\t\t\t\t\t\"shadow-sm inset-ring-1 inset-ring-foreground/[0.08]\",\n\t\t\t\t\t\"hover:bg-secondary/80 hover:shadow-md hover:inset-ring-foreground/15\",\n\t\t\t\t].join(\" \"),\n\t\t\t\tghost: \"hover:bg-accent hover:text-accent-foreground\",\n\t\t\t\tlink: \"text-primary underline-offset-4 hover:underline\",\n\t\t\t},\n\t\t\tsize: {\n\t\t\t\tdefault:\n\t\t\t\t\t\"h-[var(--control-height-md,2.5rem)] px-[var(--space-4,1rem)] py-[var(--space-2,0.5rem)]\",\n\t\t\t\tsm: \"h-[var(--control-height-sm,2.25rem)] rounded-md px-[var(--space-3,0.75rem)]\",\n\t\t\t\tlg: \"h-[var(--control-height-lg,2.75rem)] rounded-md px-[var(--space-8,2rem)] text-base\",\n\t\t\t\ticon: \"h-[var(--control-height-md,2.5rem)] w-[var(--control-height-md,2.5rem)]\",\n\t\t\t},\n\t\t},\n\t\tdefaultVariants: {\n\t\t\tvariant: \"default\",\n\t\t\tsize: \"default\",\n\t\t},\n\t},\n);\n\nexport type ButtonVariantsProps = VariantProps<typeof buttonVariants>;\n","\"use client\";\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\nimport { type ButtonVariantsProps, buttonVariants } from \"./button-variants.js\";\n\nexport interface ButtonProps\n\textends React.ButtonHTMLAttributes<HTMLButtonElement>,\n\t\tButtonVariantsProps {\n\tasChild?: boolean;\n\tloading?: boolean;\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n\t(\n\t\t{ className, variant, size, asChild = false, loading = false, children, disabled, ...props },\n\t\tref,\n\t) => {\n\t\tconst Comp = asChild ? Slot : \"button\";\n\t\treturn (\n\t\t\t<Comp\n\t\t\t\tclassName={cn(buttonVariants({ variant, size, className }))}\n\t\t\t\tref={ref}\n\t\t\t\tdisabled={disabled || loading}\n\t\t\t\taria-busy={loading || undefined}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{loading ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\tclassName=\"animate-spin h-4 w-4\"\n\t\t\t\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<circle\n\t\t\t\t\t\t\t\tclassName=\"opacity-25\"\n\t\t\t\t\t\t\t\tcx=\"12\"\n\t\t\t\t\t\t\t\tcy=\"12\"\n\t\t\t\t\t\t\t\tr=\"10\"\n\t\t\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\t\t\tstrokeWidth=\"4\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\tclassName=\"opacity-75\"\n\t\t\t\t\t\t\t\tfill=\"currentColor\"\n\t\t\t\t\t\t\t\td=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t{children}\n\t\t\t\t\t</>\n\t\t\t\t) : (\n\t\t\t\t\tchildren\n\t\t\t\t)}\n\t\t\t</Comp>\n\t\t);\n\t},\n);\nButton.displayName = \"Button\";\n\nexport { Button, buttonVariants };\n","\"use client\";\n\nimport * as React from \"react\";\nimport { Button } from \"../../primitives/button/button.js\";\nimport { cn } from \"../../lib/utils.js\";\n\n/**\n * Pre-execution plan card. Shown BEFORE the agent starts executing —\n * the body lists the proposed steps; an optional `onApprove` /\n * `onCancel` footer renders an approval gate.\n *\n * Distinct from `<Task>`: Task is during/post-execution status (steps\n * carry a lifecycle state); Plan is pre-execution intent (steps are\n * just labels). Once approved, consumers typically swap the rendered\n * `<Plan>` for a `<Task>` driven by the running agent.\n *\n * @example\n * <Plan\n * label=\"Refactor auth module\"\n * description=\"Three-step refactor with tests.\"\n * steps={[\n * { id: \"read\", label: \"Read existing auth\" },\n * { id: \"apply\", label: \"Apply changes\" },\n * { id: \"test\", label: \"Run tests\" },\n * ]}\n * onApprove={() => execute()}\n * onCancel={() => discard()}\n * />\n */\nexport interface PlanProps {\n\t/** Optional title shown above the step list. */\n\tlabel?: string;\n\t/** Optional secondary description shown under the label. */\n\tdescription?: string;\n\t/** Ordered list of steps. Each carries an id, label, and optional detail. */\n\tsteps: PlanStep[];\n\t/** When provided, an \"Approve\" button is rendered in the footer. */\n\tonApprove?: () => void;\n\t/** When provided, a \"Cancel\" button is rendered in the footer. */\n\tonCancel?: () => void;\n\t/** Override the approve button label. Defaults to \"Approve\". */\n\tapproveLabel?: string;\n\t/** Override the cancel button label. Defaults to \"Cancel\". */\n\tcancelLabel?: string;\n\tclassName?: string;\n}\n\n/** A single proposed step in a Plan. */\nexport interface PlanStep {\n\t/** Stable identifier — used for the React key. */\n\tid: string;\n\t/** Human-readable step label. */\n\tlabel: string;\n\t/** Optional secondary detail shown beneath the label. */\n\tdetail?: string;\n}\n\n/**\n * Render a pre-execution multi-step plan with an optional approval gate.\n * @param props - The plan label, steps, and optional approve/cancel handlers.\n * @returns A card wrapping a numbered step list and (optionally) an action footer.\n */\nfunction Plan({\n\tlabel,\n\tdescription,\n\tsteps,\n\tonApprove,\n\tonCancel,\n\tapproveLabel = \"Approve\",\n\tcancelLabel = \"Cancel\",\n\tclassName,\n}: PlanProps) {\n\tconst showFooter = typeof onApprove === \"function\" || typeof onCancel === \"function\";\n\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t\"overflow-hidden rounded-md border border-border bg-card\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t>\n\t\t\t{label || description ? (\n\t\t\t\t<div className=\"flex flex-col gap-0.5 border-b border-foreground/[0.06] px-3 py-2\">\n\t\t\t\t\t{label ? (\n\t\t\t\t\t\t<span className=\"text-sm font-medium text-foreground\">{label}</span>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{description ? (\n\t\t\t\t\t\t<span className=\"text-xs text-muted-foreground\">{description}</span>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t\t<ol\n\t\t\t\taria-label={label ? `${label} steps` : \"Plan steps\"}\n\t\t\t\tclassName=\"my-0 ml-0 flex list-none flex-col gap-2 py-3 pr-3 pl-3\"\n\t\t\t>\n\t\t\t\t{steps.map((step, index) => (\n\t\t\t\t\t/*\n\t\t\t\t\t * `before:content-none` defeats Tailwind Typography's\n\t\t\t\t\t * default `<li>::before` markers when this card lands\n\t\t\t\t\t * inside a `prose` block (assistant turn, MDX page).\n\t\t\t\t\t * Don't strip — the indicator handles ordinal display.\n\t\t\t\t\t */\n\t\t\t\t\t<li\n\t\t\t\t\t\tkey={step.id}\n\t\t\t\t\t\tclassName=\"flex items-start gap-3 text-sm before:content-none\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<span\n\t\t\t\t\t\t\taria-hidden\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\"mt-0.5 inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-full\",\n\t\t\t\t\t\t\t\t\"border border-input bg-background text-[0.65rem] font-medium tabular-nums text-muted-foreground\",\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{index + 1}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<div className=\"flex min-w-0 flex-col gap-0.5\">\n\t\t\t\t\t\t\t<span className=\"leading-snug text-foreground\">{step.label}</span>\n\t\t\t\t\t\t\t{step.detail ? (\n\t\t\t\t\t\t\t\t<span className=\"text-xs text-muted-foreground\">{step.detail}</span>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</li>\n\t\t\t\t))}\n\t\t\t</ol>\n\t\t\t{showFooter ? (\n\t\t\t\t<div className=\"flex items-center justify-end gap-2 border-t border-foreground/[0.06] bg-muted/20 px-3 py-2\">\n\t\t\t\t\t{typeof onCancel === \"function\" ? (\n\t\t\t\t\t\t<Button variant=\"ghost\" size=\"sm\" onClick={onCancel}>\n\t\t\t\t\t\t\t{cancelLabel}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{typeof onApprove === \"function\" ? (\n\t\t\t\t\t\t<Button variant=\"default\" size=\"sm\" onClick={onApprove}>\n\t\t\t\t\t\t\t{approveLabel}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n\nexport { Plan };\n"]}
|
package/dist/popover.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/utils.ts","../src/components/popover/popover.tsx"],"names":[],"mappings":";;;;;;AAQO,SAAS,MAAM,MAAA,EAAsB;AAC3C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC5B;ACHA,IAAM,OAAA,GAA2B,gBAAA,CAAA;AAGjC,IAAM,cAAA,GAAkC,gBAAA,CAAA;AAGxC,IAAM,aAAA,GAAiC,gBAAA,CAAA;AAGvC,IAAM,cAAA,GAAuB,KAAA,CAAA,UAAA,CAG3B,CAAC,EAAE,WAAW,KAAA,GAAQ,QAAA,EAAU,UAAA,GAAa,CAAA,EAAG,GAAG,KAAA,EAAM,EAAG,GAAA,qBAC7D,GAAA,CAAkB,yBAAjB,EACA,QAAA,kBAAA,GAAA;AAAA,EAAkB,gBAAA,CAAA,OAAA;AAAA,EAAjB;AAAA,IACA,GAAA;AAAA,IACA,KAAA;AAAA,IACA,UAAA;AAAA,IACA,SAAA,EAAW,EAAA;AAAA,MACV,wIAAA;AAAA,MACA,8DAAA;AAAA,MACA,4DAAA;AAAA,MACA,8DAAA;AAAA,MACA,6JAAA;AAAA,MACA;AAAA,KACD;AAAA,IACC,GAAG;AAAA;AACL,CAAA,EACD,CACA;AACD,cAAA,CAAe,WAAA,GAAc,gBAAA","file":"popover.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\n/** Root container for a popover. */\nconst Popover = PopoverPrimitive.Root;\n\n/** The element that anchors and opens the popover. */\nconst PopoverTrigger = PopoverPrimitive.Trigger;\n\n/** Helper to explicitly anchor the popover to a different element. */\nconst PopoverAnchor = PopoverPrimitive.Anchor;\n\n/** The floating popover content panel. */\nconst PopoverContent = React.forwardRef<\n\tReact.ComponentRef<typeof PopoverPrimitive.Content>,\n\tReact.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>\n>(({ className, align = \"center\", sideOffset = 4, ...props }, ref) => (\n\t<PopoverPrimitive.Portal>\n\t\t<PopoverPrimitive.Content\n\t\t\tref={ref}\n\t\t\talign={align}\n\t\t\tsideOffset={sideOffset}\n\t\t\tclassName={cn(\n\t\t\t\t\"z-50 w-72 rounded-md border border-foreground/[0.08] bg-popover p-[var(--space-4,1rem)] text-popover-foreground shadow-md outline-none\",\n\t\t\t\t\"data-[state=open]:animate-in data-[state=closed]:animate-out\",\n\t\t\t\t\"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n\t\t\t\t\"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95\",\n\t\t\t\t\"data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t</PopoverPrimitive.Portal>\n));\nPopoverContent.displayName = \"PopoverContent\";\n\nexport { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/components/popover/popover.tsx"],"names":[],"mappings":";;;;;;AAQO,SAAS,MAAM,MAAA,EAAsB;AAC3C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC5B;ACHA,IAAM,OAAA,GAA2B,gBAAA,CAAA;AAGjC,IAAM,cAAA,GAAkC,gBAAA,CAAA;AAGxC,IAAM,aAAA,GAAiC,gBAAA,CAAA;AAGvC,IAAM,cAAA,GAAuB,KAAA,CAAA,UAAA,CAG3B,CAAC,EAAE,WAAW,KAAA,GAAQ,QAAA,EAAU,UAAA,GAAa,CAAA,EAAG,GAAG,KAAA,EAAM,EAAG,GAAA,qBAC7D,GAAA,CAAkB,yBAAjB,EACA,QAAA,kBAAA,GAAA;AAAA,EAAkB,gBAAA,CAAA,OAAA;AAAA,EAAjB;AAAA,IACA,GAAA;AAAA,IACA,KAAA;AAAA,IACA,UAAA;AAAA,IACA,SAAA,EAAW,EAAA;AAAA,MACV,wIAAA;AAAA,MACA,8DAAA;AAAA,MACA,4DAAA;AAAA,MACA,8DAAA;AAAA,MACA,6JAAA;AAAA,MACA;AAAA,KACD;AAAA,IACC,GAAG;AAAA;AACL,CAAA,EACD,CACA;AACD,cAAA,CAAe,WAAA,GAAc,gBAAA","file":"popover.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n\nconst SAFE_URL_SCHEMES = [\"http:\", \"https:\", \"mailto:\"] as const;\n\n/**\n * Allowlist a URL for use as an `<a href>` against untrusted input.\n *\n * Returns the raw string when it's `http(s):` / `mailto:` / a relative\n * URL (no scheme); returns `undefined` otherwise. Defends against\n * `javascript:` / `data:` / `vbscript:` injection from streamed model\n * output or third-party JSON payloads that flow into citation chips.\n *\n * Inside a Markdown render path, `rehype-sanitize` already strips\n * `javascript:` from inline-link hrefs — but it does NOT introspect\n * JSON nested inside attribute values (e.g. `<sources data='[…]'/>`),\n * so the components that consume that data must guard themselves.\n *\n * @param raw - The candidate URL, or `undefined` when none was supplied.\n * @returns The URL when safe to render, otherwise `undefined`.\n */\nexport function safeUrl(raw: string | undefined): string | undefined {\n\tif (raw === undefined || raw === \"\") return undefined;\n\t// Relative URLs have no scheme — `new URL(relative)` throws without a base,\n\t// so a thrown URL means either malformed input OR a relative path. Treat\n\t// \"throws + does not contain a colon\" as a relative path (safe).\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(raw);\n\t} catch {\n\t\treturn raw.includes(\":\") ? undefined : raw;\n\t}\n\treturn SAFE_URL_SCHEMES.some((scheme) => scheme === parsed.protocol) ? raw : undefined;\n}\n","\"use client\";\n\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\n/** Root container for a popover. */\nconst Popover = PopoverPrimitive.Root;\n\n/** The element that anchors and opens the popover. */\nconst PopoverTrigger = PopoverPrimitive.Trigger;\n\n/** Helper to explicitly anchor the popover to a different element. */\nconst PopoverAnchor = PopoverPrimitive.Anchor;\n\n/** The floating popover content panel. */\nconst PopoverContent = React.forwardRef<\n\tReact.ComponentRef<typeof PopoverPrimitive.Content>,\n\tReact.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>\n>(({ className, align = \"center\", sideOffset = 4, ...props }, ref) => (\n\t<PopoverPrimitive.Portal>\n\t\t<PopoverPrimitive.Content\n\t\t\tref={ref}\n\t\t\talign={align}\n\t\t\tsideOffset={sideOffset}\n\t\t\tclassName={cn(\n\t\t\t\t\"z-50 w-72 rounded-md border border-foreground/[0.08] bg-popover p-[var(--space-4,1rem)] text-popover-foreground shadow-md outline-none\",\n\t\t\t\t\"data-[state=open]:animate-in data-[state=closed]:animate-out\",\n\t\t\t\t\"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n\t\t\t\t\"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95\",\n\t\t\t\t\"data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t</PopoverPrimitive.Portal>\n));\nPopoverContent.displayName = \"PopoverContent\";\n\nexport { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };\n"]}
|