@nocoo/basalt 2.1.7 → 2.2.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/ai/INTEGRATION.md +66 -28
- package/ai/RECIPES.md +46 -1
- package/ai/USAGE.md +2 -2
- package/ai/registry.json +65 -23
- package/dist/assets/brand-mark.js.map +1 -1
- package/dist/charts/area.js.map +1 -1
- package/dist/charts/bar.js.map +1 -1
- package/dist/charts/bullet.js.map +1 -1
- package/dist/charts/charts.js.map +1 -1
- package/dist/charts/config.js.map +1 -1
- package/dist/charts/custom-chart.js.map +1 -1
- package/dist/charts/date-navigation.js.map +1 -1
- package/dist/charts/donut.js.map +1 -1
- package/dist/charts/frame.js.map +1 -1
- package/dist/charts/funnel.js.map +1 -1
- package/dist/charts/gauge.js.map +1 -1
- package/dist/charts/grouped-bar.js.map +1 -1
- package/dist/charts/heatmap-calendar.js.map +1 -1
- package/dist/charts/heatmap-matrix.js.map +1 -1
- package/dist/charts/item-list.js.map +1 -1
- package/dist/charts/legend.js.map +1 -1
- package/dist/charts/line.js.map +1 -1
- package/dist/charts/palette.js.map +1 -1
- package/dist/charts/radar.js.map +1 -1
- package/dist/charts/sample.js.map +1 -1
- package/dist/charts/sankey.js.map +1 -1
- package/dist/charts/series.js.map +1 -1
- package/dist/charts/slot-bar.js.map +1 -1
- package/dist/charts/sparkline.js.map +1 -1
- package/dist/charts/stacked-bar.js.map +1 -1
- package/dist/charts/stat-card.js.map +1 -1
- package/dist/charts/timeline.js.map +1 -1
- package/dist/charts/timeseries.js.map +1 -1
- package/dist/charts/tooltip.js.map +1 -1
- package/dist/components/accordion.js.map +1 -1
- package/dist/components/alert-dialog.js.map +1 -1
- package/dist/components/app-header.d.ts +5 -1
- package/dist/components/app-header.js +12 -4
- package/dist/components/app-header.js.map +1 -1
- package/dist/components/app-shell.d.ts +4 -1
- package/dist/components/app-shell.js +7 -4
- package/dist/components/app-shell.js.map +1 -1
- package/dist/components/autocomplete.js.map +1 -1
- package/dist/components/avatar.js.map +1 -1
- package/dist/components/badge.js.map +1 -1
- package/dist/components/banner.js.map +1 -1
- package/dist/components/basalt-mark.js.map +1 -1
- package/dist/components/battery-meter.js.map +1 -1
- package/dist/components/breadcrumbs.js.map +1 -1
- package/dist/components/button.js +2 -2
- package/dist/components/button.js.map +1 -1
- package/dist/components/chat-bubble.js.map +1 -1
- package/dist/components/chat-composer.js.map +1 -1
- package/dist/components/chat-header.js.map +1 -1
- package/dist/components/chat-inbox.js.map +1 -1
- package/dist/components/checkbox.js.map +1 -1
- package/dist/components/clipboard-text.js.map +1 -1
- package/dist/components/code.js.map +1 -1
- package/dist/components/collapsible.js.map +1 -1
- package/dist/components/combobox.js.map +1 -1
- package/dist/components/command-palette.js.map +1 -1
- package/dist/components/confirm-dialog.d.ts +4 -1
- package/dist/components/confirm-dialog.js +20 -18
- package/dist/components/confirm-dialog.js.map +1 -1
- package/dist/components/context-menu.js.map +1 -1
- package/dist/components/data-table.js +1 -1
- package/dist/components/data-table.js.map +1 -1
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/delete-resource.js +1 -1
- package/dist/components/delete-resource.js.map +1 -1
- package/dist/components/description-list.js.map +1 -1
- package/dist/components/dialog.js.map +1 -1
- package/dist/components/dock.js.map +1 -1
- package/dist/components/dropdown-menu.js.map +1 -1
- package/dist/components/editable-nav-item.js.map +1 -1
- package/dist/components/empty.js.map +1 -1
- package/dist/components/fab.js.map +1 -1
- package/dist/components/field.js.map +1 -1
- package/dist/components/file-dropzone.js.map +1 -1
- package/dist/components/filter-bar.js.map +1 -1
- package/dist/components/flow.js.map +1 -1
- package/dist/components/grid.js.map +1 -1
- package/dist/components/hover-card.js.map +1 -1
- package/dist/components/icon-picker.js.map +1 -1
- package/dist/components/inline-editable.js.map +1 -1
- package/dist/components/input-area.js.map +1 -1
- package/dist/components/input-group.js.map +1 -1
- package/dist/components/input.js.map +1 -1
- package/dist/components/label.js.map +1 -1
- package/dist/components/layer-card.js.map +1 -1
- package/dist/components/link.js.map +1 -1
- package/dist/components/loader.js.map +1 -1
- package/dist/components/loading-screen.js.map +1 -1
- package/dist/components/menu-bar.js.map +1 -1
- package/dist/components/meter.js.map +1 -1
- package/dist/components/multi-select.js.map +1 -1
- package/dist/components/navigation-menu.js.map +1 -1
- package/dist/components/overlay.js.map +1 -1
- package/dist/components/page-header.js.map +1 -1
- package/dist/components/pagination.js.map +1 -1
- package/dist/components/popover.js.map +1 -1
- package/dist/components/radio.js.map +1 -1
- package/dist/components/resource-list.js.map +1 -1
- package/dist/components/responsive-master-detail.js +5 -5
- package/dist/components/responsive-master-detail.js.map +1 -1
- package/dist/components/scroll-area.js.map +1 -1
- package/dist/components/section-rule.js.map +1 -1
- package/dist/components/segment-control.js.map +1 -1
- package/dist/components/select.js.map +1 -1
- package/dist/components/sensitive-input.js.map +1 -1
- package/dist/components/separator.js.map +1 -1
- package/dist/components/sheet.js +1 -0
- package/dist/components/sheet.js.map +1 -1
- package/dist/components/sidebar.d.ts +3 -1
- package/dist/components/sidebar.js +8 -5
- package/dist/components/sidebar.js.map +1 -1
- package/dist/components/skeleton-line.js.map +1 -1
- package/dist/components/slider.js.map +1 -1
- package/dist/components/stat-strip.js.map +1 -1
- package/dist/components/switch.js.map +1 -1
- package/dist/components/table-of-contents.js.map +1 -1
- package/dist/components/table-pager.js.map +1 -1
- package/dist/components/table.js.map +1 -1
- package/dist/components/tabs.js.map +1 -1
- package/dist/components/tag-badge.js.map +1 -1
- package/dist/components/tag-color-picker.js.map +1 -1
- package/dist/components/text.js.map +1 -1
- package/dist/components/theme-toggle.js.map +1 -1
- package/dist/components/toast.js.map +1 -1
- package/dist/components/toggle-group.js +2 -2
- package/dist/components/toggle-group.js.map +1 -1
- package/dist/components/toggle.js +1 -1
- package/dist/components/toggle.js.map +1 -1
- package/dist/components/toolbar.js.map +1 -1
- package/dist/components/tooltip.js +14 -13
- package/dist/components/tooltip.js.map +1 -1
- package/dist/components/typeahead-field.js.map +1 -1
- package/dist/components/upload-queue.js.map +1 -1
- package/dist/providers/accent.js +1 -1
- package/dist/providers/accent.js.map +1 -1
- package/dist/providers/link.js.map +1 -1
- package/dist/providers/theme.js +1 -1
- package/dist/providers/theme.js.map +1 -1
- package/dist/styles/base.css +116 -0
- package/dist/styles/standalone.css +161 -16
- package/dist/utils/cn.js.map +1 -1
- package/dist/utils/control-surface.js.map +1 -1
- package/dist/utils/preference-store.js +1 -1
- package/dist/utils/preference-store.js.map +1 -1
- package/dist/utils/selection-indicator.js +1 -1
- package/dist/utils/selection-indicator.js.map +1 -1
- package/dist/utils/use-checkable-group.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"label.js","names":[],"sources":["../../src/components/label.tsx"],"sourcesContent":["import * as LabelPrimitive from \"@radix-ui/react-label\";\nimport { Info } from \"lucide-react\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"./tooltip\";\n\nexport type LabelProps = React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> & {\n\t/**\n\t * Show gray (optional) after the label.\n\t * @default false\n\t */\n\tshowOptional?: boolean;\n\t/** Info icon with hover text. */\n\ttooltip?: React.ReactNode;\n};\n\nexport const Label = React.forwardRef<React.ElementRef<typeof LabelPrimitive.Root>, LabelProps>(\n\t({ className, children, showOptional = false, tooltip, ...props }, ref) => (\n\t\t<LabelPrimitive.Root\n\t\t\tref={ref}\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"inline-flex items-center gap-1 text-sm font-medium leading-none text-basalt-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-70\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t\t{showOptional ? (\n\t\t\t\t<span className=\"font-normal text-basalt-muted-foreground\">(optional)</span>\n\t\t\t) : null}\n\t\t\t{tooltip ? (\n\t\t\t\t<TooltipProvider>\n\t\t\t\t\t<Tooltip>\n\t\t\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\taria-label=\"More information\"\n\t\t\t\t\t\t\t\tclassName=\"inline-flex size-4 shrink-0 items-center justify-center text-basalt-muted-foreground hover:text-basalt-foreground\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Info className=\"size-3.5\" />\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</TooltipTrigger>\n\t\t\t\t\t\t<TooltipContent>{tooltip}</TooltipContent>\n\t\t\t\t\t</Tooltip>\n\t\t\t\t</TooltipProvider>\n\t\t\t) : null}\n\t\t</LabelPrimitive.Root>\n\t),\n);\nLabel.displayName = LabelPrimitive.Root.displayName;\n"],"mappings":";;;;;;;;;AAiBA,
|
|
1
|
+
{"version":3,"file":"label.js","names":["React","LabelPrimitive","Label","props","cn","BASALT_UI_CLASS","className","children","showOptional","tooltip","TooltipProvider","Tooltip","TooltipTrigger","Info","TooltipContent"],"sources":["../../src/components/label.tsx"],"sourcesContent":["import * as LabelPrimitive from \"@radix-ui/react-label\";\nimport { Info } from \"lucide-react\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"./tooltip\";\n\nexport type LabelProps = React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> & {\n\t/**\n\t * Show gray (optional) after the label.\n\t * @default false\n\t */\n\tshowOptional?: boolean;\n\t/** Info icon with hover text. */\n\ttooltip?: React.ReactNode;\n};\n\nexport const Label = React.forwardRef<React.ElementRef<typeof LabelPrimitive.Root>, LabelProps>(\n\t({ className, children, showOptional = false, tooltip, ...props }, ref) => (\n\t\t<LabelPrimitive.Root\n\t\t\tref={ref}\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"inline-flex items-center gap-1 text-sm font-medium leading-none text-basalt-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-70\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t\t{showOptional ? (\n\t\t\t\t<span className=\"font-normal text-basalt-muted-foreground\">(optional)</span>\n\t\t\t) : null}\n\t\t\t{tooltip ? (\n\t\t\t\t<TooltipProvider>\n\t\t\t\t\t<Tooltip>\n\t\t\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\taria-label=\"More information\"\n\t\t\t\t\t\t\t\tclassName=\"inline-flex size-4 shrink-0 items-center justify-center text-basalt-muted-foreground hover:text-basalt-foreground\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Info className=\"size-3.5\" />\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</TooltipTrigger>\n\t\t\t\t\t\t<TooltipContent>{tooltip}</TooltipContent>\n\t\t\t\t\t</Tooltip>\n\t\t\t\t</TooltipProvider>\n\t\t\t) : null}\n\t\t</LabelPrimitive.Root>\n\t),\n);\nLabel.displayName = LabelPrimitive.Root.displayName;\n"],"mappings":";;;;;;;;;AAiBA,IAAaE,IAAQF,EAAM,YACzB,EAAE,cAAW,aAAU,kBAAe,IAAO,YAAS,GAAGG,KAAS,MAClE,kBAACF,EAAe,MAAhB;CACM;CACL,WAAWG,EACVC,GACA,oJACAC,CACD;CACA,GAAIH;CAPL,UAAA;EASEI;EACAC,IACA,kBAAC,QAAD;GAAM,WAAU;GAA2C,UAAA;EAAgB,CAAA,IACxE;EACHC,IACA,kBAACC,GAAD,EAAA,UACC,kBAACC,GAAD,EAAA,UAAA,CACC,kBAACC,GAAD;GAAgB,SAAA;GACf,UAAA,kBAAC,UAAD;IACC,MAAK;IACL,cAAW;IACX,WAAU;IAEV,UAAA,kBAACC,GAAD,EAAM,WAAU,WAAY,CAAA;GACrB,CAAA;EACO,CAAA,GAChB,kBAACC,GAAD,EAAA,UAAiBL,EAAwB,CAAA,CACjC,EAAA,CAAA,EACO,CAAA,IACd;CACgB;AAEvB,CAAA,CAAA;AACA,EAAM,cAAcR,EAAe,KAAK"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layer-card.js","names":[],"sources":["../../src/components/layer-card.tsx"],"sourcesContent":["import {\n\tChildren,\n\tcloneElement,\n\tFragment,\n\tforwardRef,\n\ttype HTMLAttributes,\n\tisValidElement,\n\ttype ReactElement,\n\ttype ReactNode,\n} from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Empty } from \"./empty\";\nimport { SkeletonLine } from \"./skeleton-line\";\n\nconst ROOT_CLASSES = `${BASALT_UI_CLASS} overflow-hidden rounded-basalt-lg text-basalt-foreground`;\nconst PADDING_CLASSES = {\n\tnone: \"\",\n\tsm: \"p-3\",\n\tmd: \"p-4\",\n\tlg: \"p-6\",\n} as const;\n\nexport type LayerCardPadding = keyof typeof PADDING_CLASSES;\n\nexport type LayerCardProps = Omit<HTMLAttributes<HTMLDivElement>, \"className\"> & {\n\t/**\n\t * Additional classes for the card root.\n\t */\n\tclassName?: string;\n\t/**\n\t * Draw a hairline ring. Default grouping is luminance only.\n\t * @default false\n\t */\n\toutlined?: boolean;\n\t/**\n\t * Inner spacing for unstructured card content.\n\t * @default \"md\"\n\t */\n\tpadding?: LayerCardPadding;\n};\nexport type LayerCardSectionProps = HTMLAttributes<HTMLDivElement>;\nexport type LayerCardWellProps = LayerCardSectionProps & {\n\t/**\n\t * Draw a hairline ring on a nested well.\n\t * @default false\n\t */\n\toutlined?: boolean;\n};\nexport type LayerCardLoadingProps = Omit<HTMLAttributes<HTMLDivElement>, \"aria-label\"> & {\n\t/**\n\t * Accessible label announced for the loading state.\n\t * @default \"Loading\"\n\t */\n\tlabel?: string;\n};\nexport type LayerCardEmptyProps = Omit<HTMLAttributes<HTMLDivElement>, \"title\" | \"children\"> & {\n\t/**\n\t * Empty-state heading.\n\t * @default \"No content\"\n\t */\n\ttitle?: string;\n\t/**\n\t * Supporting empty-state text.\n\t */\n\tdescription?: string;\n\t/**\n\t * Optional empty-state icon.\n\t */\n\ticon?: ReactNode;\n\t/**\n\t * Optional interactive action element rendered below empty content.\n\t */\n\taction?: ReactNode;\n\t/**\n\t * Custom supporting content or custom layout rendered between description and action.\n\t */\n\tchildren?: ReactNode;\n};\n\nfunction isElement(child: ReactNode): child is ReactElement<{ children?: ReactNode }> {\n\treturn isValidElement(child);\n}\n\nfunction hasSlot(children: ReactNode, match: (type: unknown) => boolean): boolean {\n\treturn Children.toArray(children).some((child) => {\n\t\tif (!isElement(child)) {\n\t\t\treturn false;\n\t\t}\n\t\tif (match(child.type)) {\n\t\t\treturn true;\n\t\t}\n\t\tif (child.type === Fragment) {\n\t\t\treturn hasSlot(child.props.children, match);\n\t\t}\n\t\treturn false;\n\t});\n}\n\nfunction decorateHeaders(children: ReactNode, divided: boolean): ReactNode {\n\tif (!divided) {\n\t\treturn children;\n\t}\n\treturn Children.map(children, (child) => {\n\t\tif (!isElement(child)) {\n\t\t\treturn child;\n\t\t}\n\t\tif (child.type === Fragment) {\n\t\t\treturn cloneElement(child, {\n\t\t\t\tchildren: decorateHeaders(child.props.children, divided),\n\t\t\t});\n\t\t}\n\t\tif (child.type === LayerCardHeader || child.type === LayerCardSecondary) {\n\t\t\tconst typed = child as ReactElement<{ className?: string }>;\n\t\t\treturn cloneElement(typed, {\n\t\t\t\tclassName: cn(typed.props.className, \"border-b border-basalt-border\"),\n\t\t\t});\n\t\t}\n\t\treturn child;\n\t});\n}\n\nconst LayerCardRoot = forwardRef<HTMLDivElement, LayerCardProps>(\n\t({ className, children, outlined = false, padding = \"md\", ...props }, ref) => {\n\t\tconst structured = hasSlot(children, (type) => STRUCTURED_TYPES.has(type));\n\t\tconst hasWell = hasSlot(\n\t\t\tchildren,\n\t\t\t(type) => type === LayerCardWell || type === LayerCardPrimary,\n\t\t);\n\t\tconst hasBody = hasSlot(children, (type) => type === LayerCardBody);\n\t\tconst headerDivided = hasBody && !hasWell;\n\t\treturn (\n\t\t\t<div\n\t\t\t\tref={ref}\n\t\t\t\tdata-basalt-surface=\"\"\n\t\t\t\tclassName={cn(\n\t\t\t\t\tROOT_CLASSES,\n\t\t\t\t\tstructured ? \"flex w-full flex-col\" : PADDING_CLASSES[padding],\n\t\t\t\t\toutlined && \"ring-1 ring-basalt-border/40\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{decorateHeaders(children, headerDivided)}\n\t\t\t</div>\n\t\t);\n\t},\n);\nLayerCardRoot.displayName = \"LayerCard\";\n\nfunction LayerCardHeader({ className, ...props }: LayerCardSectionProps) {\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t\"flex min-w-0 items-start justify-between gap-4 px-4 py-3 text-basalt-muted-foreground\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\nLayerCardHeader.displayName = \"LayerCard.Header\";\n\nfunction LayerCardBody({ className, ...props }: LayerCardSectionProps) {\n\treturn <div className={cn(\"min-w-0 p-4\", className)} {...props} />;\n}\nLayerCardBody.displayName = \"LayerCard.Body\";\n\nfunction LayerCardWell({ className, outlined = false, ...props }: LayerCardWellProps) {\n\treturn (\n\t\t<div\n\t\t\tdata-basalt-surface=\"\"\n\t\t\tclassName={cn(\"min-w-0 p-4\", outlined && \"ring-1 ring-basalt-border/40\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\nLayerCardWell.displayName = \"LayerCard.Well\";\n\nfunction LayerCardPrimary(props: LayerCardWellProps) {\n\treturn <LayerCardWell {...props} />;\n}\nLayerCardPrimary.displayName = \"LayerCard.Primary\";\n\nfunction LayerCardSecondary(props: LayerCardSectionProps) {\n\treturn <LayerCardHeader {...props} />;\n}\nLayerCardSecondary.displayName = \"LayerCard.Secondary\";\n\nfunction LayerCardFooter({ className, ...props }: LayerCardSectionProps) {\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t\"flex flex-wrap items-center justify-end gap-2 border-t border-basalt-border px-4 py-3\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\nLayerCardFooter.displayName = \"LayerCard.Footer\";\n\nfunction LayerCardLoading({ label = \"Loading\", className, ...props }: LayerCardLoadingProps) {\n\treturn (\n\t\t<div role=\"status\" aria-label={label} className={cn(\"space-y-3 p-4\", className)} {...props}>\n\t\t\t<SkeletonLine minWidth={100} maxWidth={100} />\n\t\t\t<SkeletonLine minWidth={72} maxWidth={72} />\n\t\t\t<SkeletonLine minWidth={88} maxWidth={88} />\n\t\t</div>\n\t);\n}\nLayerCardLoading.displayName = \"LayerCard.Loading\";\n\nfunction LayerCardEmpty({ title = \"No content\", className, ...props }: LayerCardEmptyProps) {\n\treturn <Empty title={title} className={cn(\"p-8\", className)} {...props} />;\n}\nLayerCardEmpty.displayName = \"LayerCard.Empty\";\n\nconst STRUCTURED_TYPES = new Set<unknown>([\n\tLayerCardHeader,\n\tLayerCardBody,\n\tLayerCardWell,\n\tLayerCardFooter,\n\tLayerCardLoading,\n\tLayerCardEmpty,\n\tLayerCardPrimary,\n\tLayerCardSecondary,\n]);\n\nexport const LayerCard = Object.assign(LayerCardRoot, {\n\tPrimary: LayerCardPrimary,\n\tSecondary: LayerCardSecondary,\n\tHeader: LayerCardHeader,\n\tBody: LayerCardBody,\n\tWell: LayerCardWell,\n\tFooter: LayerCardFooter,\n\tLoading: LayerCardLoading,\n\tEmpty: LayerCardEmpty,\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"layer-card.js","names":["ROOT_CLASSES","BASALT_UI_CLASS","PADDING_CLASSES","isElement","isValidElement","child","hasSlot","Children","children","match","Fragment","decorateHeaders","divided","cloneElement","LayerCardHeader","LayerCardSecondary","typed","cn","LayerCardRoot","forwardRef","props","structured","STRUCTURED_TYPES","type","hasWell","LayerCardWell","LayerCardPrimary","headerDivided","LayerCardBody","padding","outlined","className","LayerCardFooter","LayerCardLoading","label","SkeletonLine","LayerCardEmpty","Empty","LayerCard"],"sources":["../../src/components/layer-card.tsx"],"sourcesContent":["import {\n\tChildren,\n\tcloneElement,\n\tFragment,\n\tforwardRef,\n\ttype HTMLAttributes,\n\tisValidElement,\n\ttype ReactElement,\n\ttype ReactNode,\n} from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Empty } from \"./empty\";\nimport { SkeletonLine } from \"./skeleton-line\";\n\nconst ROOT_CLASSES = `${BASALT_UI_CLASS} overflow-hidden rounded-basalt-lg text-basalt-foreground`;\nconst PADDING_CLASSES = {\n\tnone: \"\",\n\tsm: \"p-3\",\n\tmd: \"p-4\",\n\tlg: \"p-6\",\n} as const;\n\nexport type LayerCardPadding = keyof typeof PADDING_CLASSES;\n\nexport type LayerCardProps = Omit<HTMLAttributes<HTMLDivElement>, \"className\"> & {\n\t/**\n\t * Additional classes for the card root.\n\t */\n\tclassName?: string;\n\t/**\n\t * Draw a hairline ring. Default grouping is luminance only.\n\t * @default false\n\t */\n\toutlined?: boolean;\n\t/**\n\t * Inner spacing for unstructured card content.\n\t * @default \"md\"\n\t */\n\tpadding?: LayerCardPadding;\n};\nexport type LayerCardSectionProps = HTMLAttributes<HTMLDivElement>;\nexport type LayerCardWellProps = LayerCardSectionProps & {\n\t/**\n\t * Draw a hairline ring on a nested well.\n\t * @default false\n\t */\n\toutlined?: boolean;\n};\nexport type LayerCardLoadingProps = Omit<HTMLAttributes<HTMLDivElement>, \"aria-label\"> & {\n\t/**\n\t * Accessible label announced for the loading state.\n\t * @default \"Loading\"\n\t */\n\tlabel?: string;\n};\nexport type LayerCardEmptyProps = Omit<HTMLAttributes<HTMLDivElement>, \"title\" | \"children\"> & {\n\t/**\n\t * Empty-state heading.\n\t * @default \"No content\"\n\t */\n\ttitle?: string;\n\t/**\n\t * Supporting empty-state text.\n\t */\n\tdescription?: string;\n\t/**\n\t * Optional empty-state icon.\n\t */\n\ticon?: ReactNode;\n\t/**\n\t * Optional interactive action element rendered below empty content.\n\t */\n\taction?: ReactNode;\n\t/**\n\t * Custom supporting content or custom layout rendered between description and action.\n\t */\n\tchildren?: ReactNode;\n};\n\nfunction isElement(child: ReactNode): child is ReactElement<{ children?: ReactNode }> {\n\treturn isValidElement(child);\n}\n\nfunction hasSlot(children: ReactNode, match: (type: unknown) => boolean): boolean {\n\treturn Children.toArray(children).some((child) => {\n\t\tif (!isElement(child)) {\n\t\t\treturn false;\n\t\t}\n\t\tif (match(child.type)) {\n\t\t\treturn true;\n\t\t}\n\t\tif (child.type === Fragment) {\n\t\t\treturn hasSlot(child.props.children, match);\n\t\t}\n\t\treturn false;\n\t});\n}\n\nfunction decorateHeaders(children: ReactNode, divided: boolean): ReactNode {\n\tif (!divided) {\n\t\treturn children;\n\t}\n\treturn Children.map(children, (child) => {\n\t\tif (!isElement(child)) {\n\t\t\treturn child;\n\t\t}\n\t\tif (child.type === Fragment) {\n\t\t\treturn cloneElement(child, {\n\t\t\t\tchildren: decorateHeaders(child.props.children, divided),\n\t\t\t});\n\t\t}\n\t\tif (child.type === LayerCardHeader || child.type === LayerCardSecondary) {\n\t\t\tconst typed = child as ReactElement<{ className?: string }>;\n\t\t\treturn cloneElement(typed, {\n\t\t\t\tclassName: cn(typed.props.className, \"border-b border-basalt-border\"),\n\t\t\t});\n\t\t}\n\t\treturn child;\n\t});\n}\n\nconst LayerCardRoot = forwardRef<HTMLDivElement, LayerCardProps>(\n\t({ className, children, outlined = false, padding = \"md\", ...props }, ref) => {\n\t\tconst structured = hasSlot(children, (type) => STRUCTURED_TYPES.has(type));\n\t\tconst hasWell = hasSlot(\n\t\t\tchildren,\n\t\t\t(type) => type === LayerCardWell || type === LayerCardPrimary,\n\t\t);\n\t\tconst hasBody = hasSlot(children, (type) => type === LayerCardBody);\n\t\tconst headerDivided = hasBody && !hasWell;\n\t\treturn (\n\t\t\t<div\n\t\t\t\tref={ref}\n\t\t\t\tdata-basalt-surface=\"\"\n\t\t\t\tclassName={cn(\n\t\t\t\t\tROOT_CLASSES,\n\t\t\t\t\tstructured ? \"flex w-full flex-col\" : PADDING_CLASSES[padding],\n\t\t\t\t\toutlined && \"ring-1 ring-basalt-border/40\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{decorateHeaders(children, headerDivided)}\n\t\t\t</div>\n\t\t);\n\t},\n);\nLayerCardRoot.displayName = \"LayerCard\";\n\nfunction LayerCardHeader({ className, ...props }: LayerCardSectionProps) {\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t\"flex min-w-0 items-start justify-between gap-4 px-4 py-3 text-basalt-muted-foreground\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\nLayerCardHeader.displayName = \"LayerCard.Header\";\n\nfunction LayerCardBody({ className, ...props }: LayerCardSectionProps) {\n\treturn <div className={cn(\"min-w-0 p-4\", className)} {...props} />;\n}\nLayerCardBody.displayName = \"LayerCard.Body\";\n\nfunction LayerCardWell({ className, outlined = false, ...props }: LayerCardWellProps) {\n\treturn (\n\t\t<div\n\t\t\tdata-basalt-surface=\"\"\n\t\t\tclassName={cn(\"min-w-0 p-4\", outlined && \"ring-1 ring-basalt-border/40\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\nLayerCardWell.displayName = \"LayerCard.Well\";\n\nfunction LayerCardPrimary(props: LayerCardWellProps) {\n\treturn <LayerCardWell {...props} />;\n}\nLayerCardPrimary.displayName = \"LayerCard.Primary\";\n\nfunction LayerCardSecondary(props: LayerCardSectionProps) {\n\treturn <LayerCardHeader {...props} />;\n}\nLayerCardSecondary.displayName = \"LayerCard.Secondary\";\n\nfunction LayerCardFooter({ className, ...props }: LayerCardSectionProps) {\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t\"flex flex-wrap items-center justify-end gap-2 border-t border-basalt-border px-4 py-3\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\nLayerCardFooter.displayName = \"LayerCard.Footer\";\n\nfunction LayerCardLoading({ label = \"Loading\", className, ...props }: LayerCardLoadingProps) {\n\treturn (\n\t\t<div role=\"status\" aria-label={label} className={cn(\"space-y-3 p-4\", className)} {...props}>\n\t\t\t<SkeletonLine minWidth={100} maxWidth={100} />\n\t\t\t<SkeletonLine minWidth={72} maxWidth={72} />\n\t\t\t<SkeletonLine minWidth={88} maxWidth={88} />\n\t\t</div>\n\t);\n}\nLayerCardLoading.displayName = \"LayerCard.Loading\";\n\nfunction LayerCardEmpty({ title = \"No content\", className, ...props }: LayerCardEmptyProps) {\n\treturn <Empty title={title} className={cn(\"p-8\", className)} {...props} />;\n}\nLayerCardEmpty.displayName = \"LayerCard.Empty\";\n\nconst STRUCTURED_TYPES = new Set<unknown>([\n\tLayerCardHeader,\n\tLayerCardBody,\n\tLayerCardWell,\n\tLayerCardFooter,\n\tLayerCardLoading,\n\tLayerCardEmpty,\n\tLayerCardPrimary,\n\tLayerCardSecondary,\n]);\n\nexport const LayerCard = Object.assign(LayerCardRoot, {\n\tPrimary: LayerCardPrimary,\n\tSecondary: LayerCardSecondary,\n\tHeader: LayerCardHeader,\n\tBody: LayerCardBody,\n\tWell: LayerCardWell,\n\tFooter: LayerCardFooter,\n\tLoading: LayerCardLoading,\n\tEmpty: LayerCardEmpty,\n});\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link.js","names":[],"sources":["../../src/components/link.tsx"],"sourcesContent":["import type * as React from \"react\";\nimport { useLinkComponent } from \"../providers/link\";\nimport { cn } from \"../utils/cn\";\n\nexport type LinkProps = Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"href\"> &\n\tRecord<string, unknown> & {\n\t\t/**\n\t\t * The link destination.\n\t\t */\n\t\thref: string;\n\t};\n\nexport function Link({ className, href, children, ...props }: LinkProps) {\n\tconst Comp = useLinkComponent();\n\treturn (\n\t\t<Comp\n\t\t\thref={href}\n\t\t\tclassName={cn(\"text-basalt-primary underline-offset-4 hover:underline\", className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</Comp>\n\t);\n}\n"],"mappings":";;;;;AAYA,
|
|
1
|
+
{"version":3,"file":"link.js","names":["Link","props","Comp","useLinkComponent","cn","className"],"sources":["../../src/components/link.tsx"],"sourcesContent":["import type * as React from \"react\";\nimport { useLinkComponent } from \"../providers/link\";\nimport { cn } from \"../utils/cn\";\n\nexport type LinkProps = Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"href\"> &\n\tRecord<string, unknown> & {\n\t\t/**\n\t\t * The link destination.\n\t\t */\n\t\thref: string;\n\t};\n\nexport function Link({ className, href, children, ...props }: LinkProps) {\n\tconst Comp = useLinkComponent();\n\treturn (\n\t\t<Comp\n\t\t\thref={href}\n\t\t\tclassName={cn(\"text-basalt-primary underline-offset-4 hover:underline\", className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</Comp>\n\t);\n}\n"],"mappings":";;;;;AAYA,SAAgBA,EAAK,EAAE,cAAW,SAAM,aAAU,GAAGC,KAAoB;CACxE,IAAMC,IAAOC,EAAiB;CAC9B,OACC,kBAACD,GAAD;EACO;EACN,WAAWE,EAAG,0DAA0DC,CAAS;EACjF,GAAIJ;EAEH;CACI,CAAA;AAER"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","names":[],"sources":["../../src/components/loader.tsx"],"sourcesContent":["import { type SVGAttributes, useId } from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport interface LoaderProps extends SVGAttributes<SVGSVGElement> {\n\t/**\n\t * Width and height of the loader spinner in pixels.\n\t *\n\t * Note: Controls both the SVG width and height dimensions.\n\t *\n\t * @default 24\n\t */\n\tsize?: number;\n}\n\nexport function Loader({ className, size = 24, ...props }: LoaderProps) {\n\tconst gradientId = `basalt-loader-${useId().replace(/:/g, \"\")}`;\n\treturn (\n\t\t<svg\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\trole=\"status\"\n\t\t\taria-label=\"Loading\"\n\t\t\t{...props}\n\t\t\twidth={size}\n\t\t\theight={size}\n\t\t\tclassName={cn(\n\t\t\t\t\"origin-center animate-basalt-loader text-basalt-primary motion-reduce:animate-none\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t>\n\t\t\t<defs>\n\t\t\t\t<linearGradient id={gradientId} x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\">\n\t\t\t\t\t<stop offset=\"0%\" stopColor=\"currentColor\" stopOpacity=\"0\" />\n\t\t\t\t\t<stop offset=\"55%\" stopColor=\"currentColor\" stopOpacity=\"0.35\" />\n\t\t\t\t\t<stop offset=\"100%\" stopColor=\"currentColor\" stopOpacity=\"1\" />\n\t\t\t\t</linearGradient>\n\t\t\t</defs>\n\t\t\t<circle\n\t\t\t\tcx=\"12\"\n\t\t\t\tcy=\"12\"\n\t\t\t\tr=\"9.5\"\n\t\t\t\tfill=\"none\"\n\t\t\t\topacity=\"0.12\"\n\t\t\t\tstroke=\"currentColor\"\n\t\t\t\tstrokeWidth=\"2.25\"\n\t\t\t/>\n\t\t\t<circle\n\t\t\t\tcx=\"12\"\n\t\t\t\tcy=\"12\"\n\t\t\t\tr=\"9.5\"\n\t\t\t\tfill=\"none\"\n\t\t\t\tstroke={`url(#${gradientId})`}\n\t\t\t\tstrokeWidth=\"2.25\"\n\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\tstrokeDasharray=\"36 60\"\n\t\t\t/>\n\t\t</svg>\n\t);\n}\n"],"mappings":";;;;;AAcA,
|
|
1
|
+
{"version":3,"file":"loader.js","names":["Loader","props","gradientId","useId","size","cn","className"],"sources":["../../src/components/loader.tsx"],"sourcesContent":["import { type SVGAttributes, useId } from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport interface LoaderProps extends SVGAttributes<SVGSVGElement> {\n\t/**\n\t * Width and height of the loader spinner in pixels.\n\t *\n\t * Note: Controls both the SVG width and height dimensions.\n\t *\n\t * @default 24\n\t */\n\tsize?: number;\n}\n\nexport function Loader({ className, size = 24, ...props }: LoaderProps) {\n\tconst gradientId = `basalt-loader-${useId().replace(/:/g, \"\")}`;\n\treturn (\n\t\t<svg\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\trole=\"status\"\n\t\t\taria-label=\"Loading\"\n\t\t\t{...props}\n\t\t\twidth={size}\n\t\t\theight={size}\n\t\t\tclassName={cn(\n\t\t\t\t\"origin-center animate-basalt-loader text-basalt-primary motion-reduce:animate-none\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t>\n\t\t\t<defs>\n\t\t\t\t<linearGradient id={gradientId} x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\">\n\t\t\t\t\t<stop offset=\"0%\" stopColor=\"currentColor\" stopOpacity=\"0\" />\n\t\t\t\t\t<stop offset=\"55%\" stopColor=\"currentColor\" stopOpacity=\"0.35\" />\n\t\t\t\t\t<stop offset=\"100%\" stopColor=\"currentColor\" stopOpacity=\"1\" />\n\t\t\t\t</linearGradient>\n\t\t\t</defs>\n\t\t\t<circle\n\t\t\t\tcx=\"12\"\n\t\t\t\tcy=\"12\"\n\t\t\t\tr=\"9.5\"\n\t\t\t\tfill=\"none\"\n\t\t\t\topacity=\"0.12\"\n\t\t\t\tstroke=\"currentColor\"\n\t\t\t\tstrokeWidth=\"2.25\"\n\t\t\t/>\n\t\t\t<circle\n\t\t\t\tcx=\"12\"\n\t\t\t\tcy=\"12\"\n\t\t\t\tr=\"9.5\"\n\t\t\t\tfill=\"none\"\n\t\t\t\tstroke={`url(#${gradientId})`}\n\t\t\t\tstrokeWidth=\"2.25\"\n\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\tstrokeDasharray=\"36 60\"\n\t\t\t/>\n\t\t</svg>\n\t);\n}\n"],"mappings":";;;;;AAcA,SAAgBA,EAAO,EAAE,cAAW,UAAO,IAAI,GAAGC,KAAsB;CACvE,IAAMC,IAAa,iBAAiBC,EAAM,CAAC,CAAC,QAAQ,MAAM,EAAE;CAC5D,OACC,kBAAC,OAAD;EACC,SAAQ;EACR,MAAK;EACL,cAAW;EACX,GAAIF;EACJ,OAAOG;EACP,QAAQA;EACR,WAAWC,EACV,sFACAC,CACD;EAVD,UAAA;GAYC,kBAAC,QAAD,EAAA,UACC,kBAAC,kBAAD;IAAgB,IAAIJ;IAAY,IAAG;IAAK,IAAG;IAAK,IAAG;IAAO,IAAG;IAA7D,UAAA;KACC,kBAAC,QAAD;MAAM,QAAO;MAAK,WAAU;MAAe,aAAY;KAAK,CAAA;KAC5D,kBAAC,QAAD;MAAM,QAAO;MAAM,WAAU;MAAe,aAAY;KAAQ,CAAA;KAChE,kBAAC,QAAD;MAAM,QAAO;MAAO,WAAU;MAAe,aAAY;KAAK,CAAA;IAC/C;GACX,CAAA,EAAA,CAAA;GACN,kBAAC,UAAD;IACC,IAAG;IACH,IAAG;IACH,GAAE;IACF,MAAK;IACL,SAAQ;IACR,QAAO;IACP,aAAY;GACZ,CAAA;GACD,kBAAC,UAAD;IACC,IAAG;IACH,IAAG;IACH,GAAE;IACF,MAAK;IACL,QAAQ,QAAQA,EAAW;IAC3B,aAAY;IACZ,eAAc;IACd,iBAAgB;GAChB,CAAA;EACG;;AAEP"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loading-screen.js","names":[],"sources":["../../src/components/loading-screen.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BasaltMark } from \"./basalt-mark\";\n\nexport function LoadingScreen({\n\tlabel = \"Loading\",\n\tmark,\n\tclassName,\n\t...props\n}: HTMLAttributes<HTMLDivElement> & {\n\tlabel?: string;\n\tmark?: ReactNode;\n}) {\n\treturn (\n\t\t<div\n\t\t\trole=\"status\"\n\t\t\taria-label={label}\n\t\t\tclassName={cn(\n\t\t\t\t\"fixed inset-0 z-50 flex items-center justify-center bg-basalt-background\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<div className=\"flex flex-col items-center gap-4\">\n\t\t\t\t{mark ?? <BasaltMark className=\"h-8 w-8 text-basalt-foreground\" />}\n\t\t\t\t<div\n\t\t\t\t\tclassName=\"relative h-px overflow-hidden rounded-full bg-basalt-border\"\n\t\t\t\t\tstyle={{ width: \"6rem\" }}\n\t\t\t\t>\n\t\t\t\t\t<span\n\t\t\t\t\t\tclassName=\"absolute inset-0 animate-basalt-shimmer motion-reduce:animate-none\"\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tbackground:\n\t\t\t\t\t\t\t\t\"linear-gradient(to right, transparent, hsl(var(--basalt-foreground) / 0.5), transparent)\",\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;;AAIA,
|
|
1
|
+
{"version":3,"file":"loading-screen.js","names":["LoadingScreen","props","label","cn","className","mark","BasaltMark"],"sources":["../../src/components/loading-screen.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BasaltMark } from \"./basalt-mark\";\n\nexport function LoadingScreen({\n\tlabel = \"Loading\",\n\tmark,\n\tclassName,\n\t...props\n}: HTMLAttributes<HTMLDivElement> & {\n\tlabel?: string;\n\tmark?: ReactNode;\n}) {\n\treturn (\n\t\t<div\n\t\t\trole=\"status\"\n\t\t\taria-label={label}\n\t\t\tclassName={cn(\n\t\t\t\t\"fixed inset-0 z-50 flex items-center justify-center bg-basalt-background\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<div className=\"flex flex-col items-center gap-4\">\n\t\t\t\t{mark ?? <BasaltMark className=\"h-8 w-8 text-basalt-foreground\" />}\n\t\t\t\t<div\n\t\t\t\t\tclassName=\"relative h-px overflow-hidden rounded-full bg-basalt-border\"\n\t\t\t\t\tstyle={{ width: \"6rem\" }}\n\t\t\t\t>\n\t\t\t\t\t<span\n\t\t\t\t\t\tclassName=\"absolute inset-0 animate-basalt-shimmer motion-reduce:animate-none\"\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tbackground:\n\t\t\t\t\t\t\t\t\"linear-gradient(to right, transparent, hsl(var(--basalt-foreground) / 0.5), transparent)\",\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;;AAIA,SAAgBA,EAAc,EAC7B,WAAQ,WACR,SACA,cACA,GAAGC,KAID;CACF,OACC,kBAAC,OAAD;EACC,MAAK;EACL,cAAYC;EACZ,WAAWC,EACV,4EACAC,CACD;EACA,GAAIH;EAEJ,UAAA,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACEI,KAAQ,kBAACC,GAAD,EAAY,WAAU,iCAAkC,CAAA,GACjE,kBAAC,OAAD;IACC,WAAU;IACV,OAAO,EAAE,OAAO,OAAO;IAEvB,UAAA,kBAAC,QAAD;KACC,WAAU;KACV,OAAO,EACN,YACC,2FACF;IACA,CAAA;GACG,CAAA,CACD;;CACD,CAAA;AAEP"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu-bar.js","names":[],"sources":["../../src/components/menu-bar.tsx"],"sourcesContent":["import * as MenubarPrimitive from \"@radix-ui/react-menubar\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { MENU_GAP, overlayItemClass, overlayPanelClass } from \"./overlay\";\n\ntype RadixMenubarProps = React.ComponentProps<typeof MenubarPrimitive.Root>;\ntype RadixMenubarMenuProps = React.ComponentProps<typeof MenubarPrimitive.Menu>;\ntype RadixMenubarTriggerProps = React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Trigger>;\ntype RadixMenubarContentProps = React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Content>;\ntype RadixMenubarItemProps = React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Item>;\n\nexport interface MenuBarProps\n\textends Omit<\n\t\tRadixMenubarProps,\n\t\t\"value\" | \"defaultValue\" | \"onValueChange\" | \"loop\" | \"dir\" | \"asChild\"\n\t> {\n\t/**\n\t * Controlled value of the currently open menu.\n\t */\n\tvalue?: RadixMenubarProps[\"value\"];\n\t/**\n\t * Uncontrolled initial value of the open menu.\n\t * @default \"\"\n\t */\n\tdefaultValue?: RadixMenubarProps[\"defaultValue\"];\n\t/**\n\t * Callback invoked when the open menu value changes.\n\t */\n\tonValueChange?: RadixMenubarProps[\"onValueChange\"];\n\t/**\n\t * Whether keyboard navigation loops around when reaching ends.\n\t * @default true\n\t */\n\tloop?: RadixMenubarProps[\"loop\"];\n\t/**\n\t * Reading direction of the menubar.\n\t * @default \"ltr\"\n\t */\n\tdir?: RadixMenubarProps[\"dir\"];\n\t/**\n\t * Change the default rendered div element to the child element, merging props and behavior.\n\t * MenuBar forwards ref to HTMLDivElement and inherits native div attributes.\n\t * @default false\n\t */\n\tasChild?: RadixMenubarProps[\"asChild\"];\n}\n\nexport function MenuBar(props: MenuBarProps) {\n\treturn <MenuBarRoot {...props} />;\n}\n\nexport interface MenuBarMenuProps extends Omit<RadixMenubarMenuProps, \"value\"> {\n\t/**\n\t * Unique identifier value for this menu within the menubar.\n\t */\n\tvalue?: RadixMenubarMenuProps[\"value\"];\n}\n\nexport function MenuBarMenu(props: MenuBarMenuProps) {\n\treturn <MenubarPrimitive.Menu {...props} />;\n}\n\nexport interface MenuBarTriggerProps\n\textends Omit<RadixMenubarTriggerProps, \"disabled\" | \"asChild\"> {\n\t/**\n\t * Disable the menubar trigger button.\n\t * @default false\n\t */\n\tdisabled?: RadixMenubarTriggerProps[\"disabled\"];\n\t/**\n\t * Change the default rendered button element to the child element, merging props and behavior.\n\t * Trigger forwards ref to HTMLButtonElement and inherits native button attributes.\n\t * @default false\n\t */\n\tasChild?: RadixMenubarTriggerProps[\"asChild\"];\n}\n\nexport const MenuBarTrigger = React.forwardRef<\n\tReact.ElementRef<typeof MenubarPrimitive.Trigger>,\n\tMenuBarTriggerProps\n>(({ className, ...props }, ref) => (\n\t<MenubarPrimitive.Trigger\n\t\tref={ref}\n\t\tclassName={cn(\n\t\t\tBASALT_UI_CLASS,\n\t\t\t\"inline-flex h-8 items-center rounded-basalt-sm px-3 text-sm font-medium outline-hidden hover:bg-basalt-accent data-[state=open]:bg-basalt-accent\",\n\t\t\tclassName,\n\t\t)}\n\t\t{...props}\n\t/>\n));\nMenuBarTrigger.displayName = MenubarPrimitive.Trigger.displayName;\n\nexport interface MenuBarContentProps\n\textends Omit<\n\t\tRadixMenubarContentProps,\n\t\t| \"loop\"\n\t\t| \"side\"\n\t\t| \"sideOffset\"\n\t\t| \"align\"\n\t\t| \"alignOffset\"\n\t\t| \"avoidCollisions\"\n\t\t| \"collisionBoundary\"\n\t\t| \"collisionPadding\"\n\t\t| \"arrowPadding\"\n\t\t| \"sticky\"\n\t\t| \"hideWhenDetached\"\n\t\t| \"forceMount\"\n\t\t| \"asChild\"\n\t\t| \"onCloseAutoFocus\"\n\t\t| \"onEscapeKeyDown\"\n\t\t| \"onPointerDownOutside\"\n\t\t| \"onFocusOutside\"\n\t\t| \"onInteractOutside\"\n\t> {\n\t/**\n\t * Whether keyboard navigation loops around when reaching the start or end item.\n\t * @default false\n\t */\n\tloop?: RadixMenubarContentProps[\"loop\"];\n\t/**\n\t * Preferred placement side relative to the menu trigger.\n\t * @default \"bottom\"\n\t */\n\tside?: RadixMenubarContentProps[\"side\"];\n\t/**\n\t * Distance in pixels between trigger and floating content panel.\n\t * @default 4\n\t */\n\tsideOffset?: RadixMenubarContentProps[\"sideOffset\"];\n\t/**\n\t * Preferred alignment along the side axis.\n\t * @default \"start\"\n\t */\n\talign?: RadixMenubarContentProps[\"align\"];\n\t/**\n\t * Offset in pixels from the start or end alignment position.\n\t * @default 0\n\t */\n\talignOffset?: RadixMenubarContentProps[\"alignOffset\"];\n\t/**\n\t * Whether to reposition content to avoid viewport boundary collisions.\n\t * @default true\n\t */\n\tavoidCollisions?: RadixMenubarContentProps[\"avoidCollisions\"];\n\t/**\n\t * Element or elements bounding boundary collision calculations.\n\t * @default []\n\t */\n\tcollisionBoundary?: RadixMenubarContentProps[\"collisionBoundary\"];\n\t/**\n\t * Virtual padding from collision boundaries in pixels.\n\t * @default 0\n\t */\n\tcollisionPadding?: RadixMenubarContentProps[\"collisionPadding\"];\n\t/**\n\t * Padding in pixels between popper arrow and floating panel edge.\n\t * @default 0\n\t */\n\tarrowPadding?: RadixMenubarContentProps[\"arrowPadding\"];\n\t/**\n\t * Sticky positioning behavior along the align axis when overflowing.\n\t * @default \"partial\"\n\t */\n\tsticky?: RadixMenubarContentProps[\"sticky\"];\n\t/**\n\t * Whether to hide content completely when trigger is fully occluded.\n\t * @default false\n\t */\n\thideWhenDetached?: RadixMenubarContentProps[\"hideWhenDetached\"];\n\t/**\n\t * Force mounting content in DOM for external animation controls.\n\t * When forceMount is true, the content remains mounted even when closed.\n\t * The caller is responsible for visibility transitions and unmounting after animation completes.\n\t */\n\tforceMount?: true;\n\t/**\n\t * Change the default rendered div element to the child element, merging props and behavior.\n\t * Content forwards ref to HTMLDivElement and inherits native div attributes.\n\t * @default false\n\t */\n\tasChild?: RadixMenubarContentProps[\"asChild\"];\n\t/**\n\t * Callback fired when auto-focusing on close. Can be prevented.\n\t */\n\tonCloseAutoFocus?: RadixMenubarContentProps[\"onCloseAutoFocus\"];\n\t/**\n\t * Callback fired when the Escape key is down on the dismissable layer. Can be prevented.\n\t */\n\tonEscapeKeyDown?: RadixMenubarContentProps[\"onEscapeKeyDown\"];\n\t/**\n\t * Callback fired when a pointerdown event happens outside the bounds of the dismissable layer. Can be prevented.\n\t */\n\tonPointerDownOutside?: RadixMenubarContentProps[\"onPointerDownOutside\"];\n\t/**\n\t * Callback fired when focus moves outside the bounds of the dismissable layer. Can be prevented.\n\t */\n\tonFocusOutside?: RadixMenubarContentProps[\"onFocusOutside\"];\n\t/**\n\t * Callback fired when an interaction (pointerdown or focus) happens outside the bounds of the dismissable layer. Can be prevented.\n\t */\n\tonInteractOutside?: RadixMenubarContentProps[\"onInteractOutside\"];\n}\n\nexport const MenuBarContent = React.forwardRef<\n\tReact.ElementRef<typeof MenubarPrimitive.Content>,\n\tMenuBarContentProps\n>(({ className, sideOffset = MENU_GAP, ...props }, ref) => (\n\t<MenubarPrimitive.Portal forceMount={props.forceMount}>\n\t\t<MenubarPrimitive.Content\n\t\t\tref={ref}\n\t\t\tsideOffset={sideOffset}\n\t\t\tclassName={overlayPanelClass(cn(\"min-w-40\", className))}\n\t\t\t{...props}\n\t\t/>\n\t</MenubarPrimitive.Portal>\n));\nMenuBarContent.displayName = MenubarPrimitive.Content.displayName;\n\nexport interface MenuBarItemProps\n\textends Omit<RadixMenubarItemProps, \"disabled\" | \"onSelect\" | \"textValue\" | \"asChild\"> {\n\t/**\n\t * Disable the menubar item.\n\t * @default false\n\t */\n\tdisabled?: RadixMenubarItemProps[\"disabled\"];\n\t/**\n\t * Event handler called when the menubar item is selected (via click or keyboard).\n\t */\n\tonSelect?: RadixMenubarItemProps[\"onSelect\"];\n\t/**\n\t * Optional text used for typeahead navigation. By default typeahead uses item text content.\n\t */\n\ttextValue?: RadixMenubarItemProps[\"textValue\"];\n\t/**\n\t * Change the default rendered div element to the child element, merging props and behavior.\n\t * Item forwards ref to HTMLDivElement and inherits native div attributes.\n\t * @default false\n\t */\n\tasChild?: RadixMenubarItemProps[\"asChild\"];\n}\n\nexport const MenuBarItem = React.forwardRef<\n\tReact.ElementRef<typeof MenubarPrimitive.Item>,\n\tMenuBarItemProps\n>(({ className, ...props }, ref) => (\n\t<MenubarPrimitive.Item\n\t\tref={ref}\n\t\tclassName={overlayItemClass(cn(\"relative outline-hidden focus:bg-basalt-accent\", className))}\n\t\t{...props}\n\t/>\n));\nMenuBarItem.displayName = MenubarPrimitive.Item.displayName;\n\nexport interface MenuBarRootProps extends MenuBarProps {}\n\nexport function MenuBarRoot({ className, ...props }: MenuBarRootProps) {\n\treturn (\n\t\t<MenubarPrimitive.Root\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"flex h-9 items-center gap-0.5 rounded-basalt-md border border-basalt-border bg-basalt-popover px-1\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n"],"mappings":";;;;;;;;AAgDA,SAAgB,EAAQ,GAAqB;CAC5C,OAAO,kBAAC,GAAD,EAAa,GAAI,EAAQ,CAAA;AACjC;AASA,SAAgB,EAAY,GAAyB;CACpD,OAAO,kBAAC,EAAiB,MAAlB,EAAuB,GAAI,EAAQ,CAAA;AAC3C;AAiBA,IAAa,IAAiB,EAAM,YAGjC,EAAE,cAAW,GAAG,KAAS,MAC3B,kBAAC,EAAiB,SAAlB;CACM;CACL,WAAW,EACV,GACA,oJACA,CACD;CACA,GAAI;AACJ,CAAA,CACD;AACD,EAAe,cAAc,EAAiB,QAAQ;AAiHtD,IAAa,IAAiB,EAAM,YAGjC,EAAE,cAAW,gBAAA,GAAuB,GAAG,KAAS,MAClD,kBAAC,EAAiB,QAAlB;CAAyB,YAAY,EAAM;CAC1C,UAAA,kBAAC,EAAiB,SAAlB;EACM;EACO;EACZ,WAAW,EAAkB,EAAG,YAAY,CAAS,CAAC;EACtD,GAAI;CACJ,CAAA;AACuB,CAAA,CACzB;AACD,EAAe,cAAc,EAAiB,QAAQ;AAyBtD,IAAa,IAAc,EAAM,YAG9B,EAAE,cAAW,GAAG,KAAS,MAC3B,kBAAC,EAAiB,MAAlB;CACM;CACL,WAAW,EAAiB,EAAG,kDAAkD,CAAS,CAAC;CAC3F,GAAI;AACJ,CAAA,CACD;AACD,EAAY,cAAc,EAAiB,KAAK;AAIhD,SAAgB,EAAY,EAAE,cAAW,GAAG,KAA2B;CACtE,OACC,kBAAC,EAAiB,MAAlB;EACC,WAAW,EACV,GACA,sGACA,CACD;EACA,GAAI;CACJ,CAAA;AAEH"}
|
|
1
|
+
{"version":3,"file":"menu-bar.js","names":["React","MenubarPrimitive","MenuBar","MenuBarRoot","props","MenuBarMenu","MenuBarTrigger","cn","BASALT_UI_CLASS","className","MenuBarContent","overlayPanelClass","MenuBarItem","overlayItemClass"],"sources":["../../src/components/menu-bar.tsx"],"sourcesContent":["import * as MenubarPrimitive from \"@radix-ui/react-menubar\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { MENU_GAP, overlayItemClass, overlayPanelClass } from \"./overlay\";\n\ntype RadixMenubarProps = React.ComponentProps<typeof MenubarPrimitive.Root>;\ntype RadixMenubarMenuProps = React.ComponentProps<typeof MenubarPrimitive.Menu>;\ntype RadixMenubarTriggerProps = React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Trigger>;\ntype RadixMenubarContentProps = React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Content>;\ntype RadixMenubarItemProps = React.ComponentPropsWithoutRef<typeof MenubarPrimitive.Item>;\n\nexport interface MenuBarProps\n\textends Omit<\n\t\tRadixMenubarProps,\n\t\t\"value\" | \"defaultValue\" | \"onValueChange\" | \"loop\" | \"dir\" | \"asChild\"\n\t> {\n\t/**\n\t * Controlled value of the currently open menu.\n\t */\n\tvalue?: RadixMenubarProps[\"value\"];\n\t/**\n\t * Uncontrolled initial value of the open menu.\n\t * @default \"\"\n\t */\n\tdefaultValue?: RadixMenubarProps[\"defaultValue\"];\n\t/**\n\t * Callback invoked when the open menu value changes.\n\t */\n\tonValueChange?: RadixMenubarProps[\"onValueChange\"];\n\t/**\n\t * Whether keyboard navigation loops around when reaching ends.\n\t * @default true\n\t */\n\tloop?: RadixMenubarProps[\"loop\"];\n\t/**\n\t * Reading direction of the menubar.\n\t * @default \"ltr\"\n\t */\n\tdir?: RadixMenubarProps[\"dir\"];\n\t/**\n\t * Change the default rendered div element to the child element, merging props and behavior.\n\t * MenuBar forwards ref to HTMLDivElement and inherits native div attributes.\n\t * @default false\n\t */\n\tasChild?: RadixMenubarProps[\"asChild\"];\n}\n\nexport function MenuBar(props: MenuBarProps) {\n\treturn <MenuBarRoot {...props} />;\n}\n\nexport interface MenuBarMenuProps extends Omit<RadixMenubarMenuProps, \"value\"> {\n\t/**\n\t * Unique identifier value for this menu within the menubar.\n\t */\n\tvalue?: RadixMenubarMenuProps[\"value\"];\n}\n\nexport function MenuBarMenu(props: MenuBarMenuProps) {\n\treturn <MenubarPrimitive.Menu {...props} />;\n}\n\nexport interface MenuBarTriggerProps\n\textends Omit<RadixMenubarTriggerProps, \"disabled\" | \"asChild\"> {\n\t/**\n\t * Disable the menubar trigger button.\n\t * @default false\n\t */\n\tdisabled?: RadixMenubarTriggerProps[\"disabled\"];\n\t/**\n\t * Change the default rendered button element to the child element, merging props and behavior.\n\t * Trigger forwards ref to HTMLButtonElement and inherits native button attributes.\n\t * @default false\n\t */\n\tasChild?: RadixMenubarTriggerProps[\"asChild\"];\n}\n\nexport const MenuBarTrigger = React.forwardRef<\n\tReact.ElementRef<typeof MenubarPrimitive.Trigger>,\n\tMenuBarTriggerProps\n>(({ className, ...props }, ref) => (\n\t<MenubarPrimitive.Trigger\n\t\tref={ref}\n\t\tclassName={cn(\n\t\t\tBASALT_UI_CLASS,\n\t\t\t\"inline-flex h-8 items-center rounded-basalt-sm px-3 text-sm font-medium outline-hidden hover:bg-basalt-accent data-[state=open]:bg-basalt-accent\",\n\t\t\tclassName,\n\t\t)}\n\t\t{...props}\n\t/>\n));\nMenuBarTrigger.displayName = MenubarPrimitive.Trigger.displayName;\n\nexport interface MenuBarContentProps\n\textends Omit<\n\t\tRadixMenubarContentProps,\n\t\t| \"loop\"\n\t\t| \"side\"\n\t\t| \"sideOffset\"\n\t\t| \"align\"\n\t\t| \"alignOffset\"\n\t\t| \"avoidCollisions\"\n\t\t| \"collisionBoundary\"\n\t\t| \"collisionPadding\"\n\t\t| \"arrowPadding\"\n\t\t| \"sticky\"\n\t\t| \"hideWhenDetached\"\n\t\t| \"forceMount\"\n\t\t| \"asChild\"\n\t\t| \"onCloseAutoFocus\"\n\t\t| \"onEscapeKeyDown\"\n\t\t| \"onPointerDownOutside\"\n\t\t| \"onFocusOutside\"\n\t\t| \"onInteractOutside\"\n\t> {\n\t/**\n\t * Whether keyboard navigation loops around when reaching the start or end item.\n\t * @default false\n\t */\n\tloop?: RadixMenubarContentProps[\"loop\"];\n\t/**\n\t * Preferred placement side relative to the menu trigger.\n\t * @default \"bottom\"\n\t */\n\tside?: RadixMenubarContentProps[\"side\"];\n\t/**\n\t * Distance in pixels between trigger and floating content panel.\n\t * @default 4\n\t */\n\tsideOffset?: RadixMenubarContentProps[\"sideOffset\"];\n\t/**\n\t * Preferred alignment along the side axis.\n\t * @default \"start\"\n\t */\n\talign?: RadixMenubarContentProps[\"align\"];\n\t/**\n\t * Offset in pixels from the start or end alignment position.\n\t * @default 0\n\t */\n\talignOffset?: RadixMenubarContentProps[\"alignOffset\"];\n\t/**\n\t * Whether to reposition content to avoid viewport boundary collisions.\n\t * @default true\n\t */\n\tavoidCollisions?: RadixMenubarContentProps[\"avoidCollisions\"];\n\t/**\n\t * Element or elements bounding boundary collision calculations.\n\t * @default []\n\t */\n\tcollisionBoundary?: RadixMenubarContentProps[\"collisionBoundary\"];\n\t/**\n\t * Virtual padding from collision boundaries in pixels.\n\t * @default 0\n\t */\n\tcollisionPadding?: RadixMenubarContentProps[\"collisionPadding\"];\n\t/**\n\t * Padding in pixels between popper arrow and floating panel edge.\n\t * @default 0\n\t */\n\tarrowPadding?: RadixMenubarContentProps[\"arrowPadding\"];\n\t/**\n\t * Sticky positioning behavior along the align axis when overflowing.\n\t * @default \"partial\"\n\t */\n\tsticky?: RadixMenubarContentProps[\"sticky\"];\n\t/**\n\t * Whether to hide content completely when trigger is fully occluded.\n\t * @default false\n\t */\n\thideWhenDetached?: RadixMenubarContentProps[\"hideWhenDetached\"];\n\t/**\n\t * Force mounting content in DOM for external animation controls.\n\t * When forceMount is true, the content remains mounted even when closed.\n\t * The caller is responsible for visibility transitions and unmounting after animation completes.\n\t */\n\tforceMount?: true;\n\t/**\n\t * Change the default rendered div element to the child element, merging props and behavior.\n\t * Content forwards ref to HTMLDivElement and inherits native div attributes.\n\t * @default false\n\t */\n\tasChild?: RadixMenubarContentProps[\"asChild\"];\n\t/**\n\t * Callback fired when auto-focusing on close. Can be prevented.\n\t */\n\tonCloseAutoFocus?: RadixMenubarContentProps[\"onCloseAutoFocus\"];\n\t/**\n\t * Callback fired when the Escape key is down on the dismissable layer. Can be prevented.\n\t */\n\tonEscapeKeyDown?: RadixMenubarContentProps[\"onEscapeKeyDown\"];\n\t/**\n\t * Callback fired when a pointerdown event happens outside the bounds of the dismissable layer. Can be prevented.\n\t */\n\tonPointerDownOutside?: RadixMenubarContentProps[\"onPointerDownOutside\"];\n\t/**\n\t * Callback fired when focus moves outside the bounds of the dismissable layer. Can be prevented.\n\t */\n\tonFocusOutside?: RadixMenubarContentProps[\"onFocusOutside\"];\n\t/**\n\t * Callback fired when an interaction (pointerdown or focus) happens outside the bounds of the dismissable layer. Can be prevented.\n\t */\n\tonInteractOutside?: RadixMenubarContentProps[\"onInteractOutside\"];\n}\n\nexport const MenuBarContent = React.forwardRef<\n\tReact.ElementRef<typeof MenubarPrimitive.Content>,\n\tMenuBarContentProps\n>(({ className, sideOffset = MENU_GAP, ...props }, ref) => (\n\t<MenubarPrimitive.Portal forceMount={props.forceMount}>\n\t\t<MenubarPrimitive.Content\n\t\t\tref={ref}\n\t\t\tsideOffset={sideOffset}\n\t\t\tclassName={overlayPanelClass(cn(\"min-w-40\", className))}\n\t\t\t{...props}\n\t\t/>\n\t</MenubarPrimitive.Portal>\n));\nMenuBarContent.displayName = MenubarPrimitive.Content.displayName;\n\nexport interface MenuBarItemProps\n\textends Omit<RadixMenubarItemProps, \"disabled\" | \"onSelect\" | \"textValue\" | \"asChild\"> {\n\t/**\n\t * Disable the menubar item.\n\t * @default false\n\t */\n\tdisabled?: RadixMenubarItemProps[\"disabled\"];\n\t/**\n\t * Event handler called when the menubar item is selected (via click or keyboard).\n\t */\n\tonSelect?: RadixMenubarItemProps[\"onSelect\"];\n\t/**\n\t * Optional text used for typeahead navigation. By default typeahead uses item text content.\n\t */\n\ttextValue?: RadixMenubarItemProps[\"textValue\"];\n\t/**\n\t * Change the default rendered div element to the child element, merging props and behavior.\n\t * Item forwards ref to HTMLDivElement and inherits native div attributes.\n\t * @default false\n\t */\n\tasChild?: RadixMenubarItemProps[\"asChild\"];\n}\n\nexport const MenuBarItem = React.forwardRef<\n\tReact.ElementRef<typeof MenubarPrimitive.Item>,\n\tMenuBarItemProps\n>(({ className, ...props }, ref) => (\n\t<MenubarPrimitive.Item\n\t\tref={ref}\n\t\tclassName={overlayItemClass(cn(\"relative outline-hidden focus:bg-basalt-accent\", className))}\n\t\t{...props}\n\t/>\n));\nMenuBarItem.displayName = MenubarPrimitive.Item.displayName;\n\nexport interface MenuBarRootProps extends MenuBarProps {}\n\nexport function MenuBarRoot({ className, ...props }: MenuBarRootProps) {\n\treturn (\n\t\t<MenubarPrimitive.Root\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"flex h-9 items-center gap-0.5 rounded-basalt-md border border-basalt-border bg-basalt-popover px-1\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n"],"mappings":";;;;;;;;AAgDA,SAAgBE,EAAQ,GAAqB;CAC5C,OAAO,kBAACC,GAAD,EAAa,GAAIC,EAAQ,CAAA;AACjC;AASA,SAAgBC,EAAY,GAAyB;CACpD,OAAO,kBAACJ,EAAiB,MAAlB,EAAuB,GAAIG,EAAQ,CAAA;AAC3C;AAiBA,IAAaE,IAAiBN,EAAM,YAGjC,EAAE,cAAW,GAAGI,KAAS,MAC3B,kBAACH,EAAiB,SAAlB;CACM;CACL,WAAWM,EACVC,GACA,oJACAC,CACD;CACA,GAAIL;AACJ,CAAA,CACD;AACD,EAAe,cAAcH,EAAiB,QAAQ;AAiHtD,IAAaS,IAAiBV,EAAM,YAGjC,EAAE,cAAW,gBAAA,GAAuB,GAAGI,KAAS,MAClD,kBAACH,EAAiB,QAAlB;CAAyB,YAAYG,EAAM;CAC1C,UAAA,kBAACH,EAAiB,SAAlB;EACM;EACO;EACZ,WAAWU,EAAkBJ,EAAG,YAAYE,CAAS,CAAC;EACtD,GAAIL;CACJ,CAAA;AACuB,CAAA,CACzB;AACD,EAAe,cAAcH,EAAiB,QAAQ;AAyBtD,IAAaW,IAAcZ,EAAM,YAG9B,EAAE,cAAW,GAAGI,KAAS,MAC3B,kBAACH,EAAiB,MAAlB;CACM;CACL,WAAWY,EAAiBN,EAAG,kDAAkDE,CAAS,CAAC;CAC3F,GAAIL;AACJ,CAAA,CACD;AACD,EAAY,cAAcH,EAAiB,KAAK;AAIhD,SAAgBE,EAAY,EAAE,cAAW,GAAGC,KAA2B;CACtE,OACC,kBAACH,EAAiB,MAAlB;EACC,WAAWM,EACVC,GACA,sGACAC,CACD;EACA,GAAIL;CACJ,CAAA;AAEH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"meter.js","names":[],"sources":["../../src/components/meter.tsx"],"sourcesContent":["import * as Progress from \"@radix-ui/react-progress\";\nimport { cn } from \"../utils/cn\";\n\nexport interface MeterProps {\n\t/**\n\t * Percentage value representing current meter progress (0..100).\n\t *\n\t * Note: Rendered bar width is clamped to [0, 100]%; callers should provide 0..100,\n\t * while underlying Radix validates and manages accessible value attributes.\n\t * Does not support arbitrary native HTML props, ref forwarding, min/max, or change callbacks.\n\t * @default 0\n\t */\n\tvalue?: number;\n\t/**\n\t * Text label displayed above the meter bar and used as accessible name fallback.\n\t */\n\tlabel?: string;\n\t/**\n\t * Custom text overriding the displayed percentage value text next to the label.\n\t */\n\tcustomValue?: string;\n\t/**\n\t * Whether to hide the displayed value text next to the label.\n\t * @default false\n\t */\n\thideValue?: boolean;\n\t/**\n\t * Additional CSS classes applied to the root container.\n\t */\n\tclassName?: string;\n\t/**\n\t * Accessible label announced for assistive technologies. Takes precedence over `label`.\n\t */\n\t\"aria-label\"?: string;\n}\n\nexport function Meter({\n\tvalue = 0,\n\tlabel,\n\tcustomValue,\n\thideValue = false,\n\tclassName,\n\t\"aria-label\": ariaLabel,\n}: MeterProps) {\n\treturn (\n\t\t<div className={cn(\"w-full space-y-1\", className)}>\n\t\t\t{label || (!hideValue && customValue) ? (\n\t\t\t\t<div className=\"flex justify-between text-xs text-basalt-muted-foreground\">\n\t\t\t\t\t<span>{label}</span>\n\t\t\t\t\t{hideValue ? null : <span>{customValue ?? `${value}%`}</span>}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t\t<Progress.Root\n\t\t\t\tvalue={value}\n\t\t\t\taria-label={ariaLabel ?? label}\n\t\t\t\tclassName=\"relative h-2 overflow-hidden rounded-full bg-basalt-muted\"\n\t\t\t>\n\t\t\t\t<Progress.Indicator\n\t\t\t\t\tclassName=\"h-full bg-basalt-primary transition-[width]\"\n\t\t\t\t\tstyle={{ width: `${Math.min(100, Math.max(0, value))}%` }}\n\t\t\t\t/>\n\t\t\t</Progress.Root>\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;;AAoCA,
|
|
1
|
+
{"version":3,"file":"meter.js","names":["Progress","Meter","ariaLabel","cn","className","label","hideValue","customValue","value"],"sources":["../../src/components/meter.tsx"],"sourcesContent":["import * as Progress from \"@radix-ui/react-progress\";\nimport { cn } from \"../utils/cn\";\n\nexport interface MeterProps {\n\t/**\n\t * Percentage value representing current meter progress (0..100).\n\t *\n\t * Note: Rendered bar width is clamped to [0, 100]%; callers should provide 0..100,\n\t * while underlying Radix validates and manages accessible value attributes.\n\t * Does not support arbitrary native HTML props, ref forwarding, min/max, or change callbacks.\n\t * @default 0\n\t */\n\tvalue?: number;\n\t/**\n\t * Text label displayed above the meter bar and used as accessible name fallback.\n\t */\n\tlabel?: string;\n\t/**\n\t * Custom text overriding the displayed percentage value text next to the label.\n\t */\n\tcustomValue?: string;\n\t/**\n\t * Whether to hide the displayed value text next to the label.\n\t * @default false\n\t */\n\thideValue?: boolean;\n\t/**\n\t * Additional CSS classes applied to the root container.\n\t */\n\tclassName?: string;\n\t/**\n\t * Accessible label announced for assistive technologies. Takes precedence over `label`.\n\t */\n\t\"aria-label\"?: string;\n}\n\nexport function Meter({\n\tvalue = 0,\n\tlabel,\n\tcustomValue,\n\thideValue = false,\n\tclassName,\n\t\"aria-label\": ariaLabel,\n}: MeterProps) {\n\treturn (\n\t\t<div className={cn(\"w-full space-y-1\", className)}>\n\t\t\t{label || (!hideValue && customValue) ? (\n\t\t\t\t<div className=\"flex justify-between text-xs text-basalt-muted-foreground\">\n\t\t\t\t\t<span>{label}</span>\n\t\t\t\t\t{hideValue ? null : <span>{customValue ?? `${value}%`}</span>}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t\t<Progress.Root\n\t\t\t\tvalue={value}\n\t\t\t\taria-label={ariaLabel ?? label}\n\t\t\t\tclassName=\"relative h-2 overflow-hidden rounded-full bg-basalt-muted\"\n\t\t\t>\n\t\t\t\t<Progress.Indicator\n\t\t\t\t\tclassName=\"h-full bg-basalt-primary transition-[width]\"\n\t\t\t\t\tstyle={{ width: `${Math.min(100, Math.max(0, value))}%` }}\n\t\t\t\t/>\n\t\t\t</Progress.Root>\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;;AAoCA,SAAgBC,EAAM,EACrB,WAAQ,GACR,UACA,gBACA,eAAY,IACZ,cACA,cAAcC,KACA;CACd,OACC,kBAAC,OAAD;EAAK,WAAWC,EAAG,oBAAoBC,CAAS;EAAhD,UAAA,CACEC,KAAU,CAACC,KAAaC,IACxB,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACC,kBAAC,QAAD,EAAA,UAAOF,EAAY,CAAA,GAClBC,IAAY,OAAO,kBAAC,QAAD,EAAA,UAAOC,KAAe,GAAGC,EAAM,GAAS,CAAA,CACxD;EACF,CAAA,IAAA,MACJ,kBAACR,EAAS,MAAV;GACQ;GACP,cAAYE,KAAaG;GACzB,WAAU;GAEV,UAAA,kBAACL,EAAS,WAAV;IACC,WAAU;IACV,OAAO,EAAE,OAAO,GAAG,KAAK,IAAI,KAAK,KAAK,IAAI,GAAGQ,CAAK,CAAC,EAAE,GAAG;GACxD,CAAA;EACa,CAAA,CACX;;AAEP"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multi-select.js","names":[],"sources":["../../src/components/multi-select.tsx"],"sourcesContent":["import { Check, ChevronDown, X } from \"lucide-react\";\nimport { type ReactNode, useEffect, useId, useRef, useState } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Button } from \"./button\";\nimport { Input } from \"./input\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"./popover\";\n\nexport interface MultiSelectOption {\n\t/** Stable identifier, independent of the display label. */\n\tvalue: string;\n\t/** Searchable and accessible display name. */\n\tlabel: string;\n\t/** Optional secondary searchable text. */\n\tdescription?: string;\n\t/** Caller-provided icon or avatar. */\n\tleading?: ReactNode;\n\t/** Prevent adding or removing this option. */\n\tdisabled?: boolean;\n}\n\nexport interface MultiSelectProps {\n\t/** Accessible field and popup name. */\n\tlabel: string;\n\t/** Available options; retain selected options to preserve their display labels. */\n\toptions: readonly MultiSelectOption[];\n\t/** Controlled selected identifiers. */\n\tvalue?: readonly string[];\n\t/** Initial uncontrolled selection. @default [] */\n\tdefaultValue?: readonly string[];\n\t/** Selection requests; controlled values change only when accepted by the caller. */\n\tonValueChange?: (value: string[]) => void;\n\t/** Controlled search text; asynchronous requests belong to the caller. */\n\tquery?: string;\n\t/** Initial uncontrolled search text. @default \"\" */\n\tdefaultQuery?: string;\n\t/** Search text requests. */\n\tonQueryChange?: (query: string) => void;\n\t/** Controlled popup visibility. */\n\topen?: boolean;\n\t/** Initial uncontrolled popup visibility. @default false */\n\tdefaultOpen?: boolean;\n\t/** Popup visibility requests. */\n\tonOpenChange?: (open: boolean) => void;\n\t/** Use local label/description filtering; disable for server-filtered options. @default true */\n\tfilterOptions?: boolean;\n\t/** Loading content replaces the option list. @default false */\n\tloading?: boolean;\n\t/** Disables the trigger, chips, and native form entries. @default false */\n\tdisabled?: boolean;\n\t/** Repeated native form entry name, one entry per selected identifier. */\n\tname?: string;\n\t/** Optional external native form owner. Uncontrolled state respects uncancelled form resets. */\n\tform?: string;\n\t/** Empty selection prompt. @default \"Select options\" */\n\tplaceholder?: string;\n\t/** Search input prompt. @default \"Search options…\" */\n\tsearchPlaceholder?: string;\n\t/** Empty search result text. @default \"No options found.\" */\n\temptyLabel?: string;\n\t/** Loading announcement. @default \"Loading options…\" */\n\tloadingLabel?: string;\n\t/** Chip removal label prefix. @default \"Remove\" */\n\tremoveLabel?: string;\n\t/** Show removable selection chips; disable when a FilterBar renders its own chips. @default true */\n\tshowChips?: boolean;\n\t/** Selection count formatter, including localization. */\n\tformatSelectionCount?: (count: number) => string;\n\t/** Additional root classes. */\n\tclassName?: string;\n}\n\nexport function MultiSelect({\n\tlabel,\n\toptions,\n\tvalue,\n\tdefaultValue = [],\n\tonValueChange,\n\tquery,\n\tdefaultQuery = \"\",\n\tonQueryChange,\n\topen,\n\tdefaultOpen = false,\n\tonOpenChange,\n\tfilterOptions = true,\n\tloading = false,\n\tdisabled = false,\n\tname,\n\tform,\n\tplaceholder = \"Select options\",\n\tsearchPlaceholder = \"Search options…\",\n\temptyLabel = \"No options found.\",\n\tloadingLabel = \"Loading options…\",\n\tremoveLabel = \"Remove\",\n\tshowChips = true,\n\tformatSelectionCount,\n\tclassName,\n}: MultiSelectProps) {\n\tconst [localValue, setLocalValue] = useState(defaultValue);\n\tconst [localQuery, setLocalQuery] = useState(defaultQuery);\n\tconst [localOpen, setLocalOpen] = useState(defaultOpen);\n\tconst [active, setActive] = useState<string | null>(null);\n\tconst input = useRef<HTMLInputElement>(null);\n\tconst trigger = useRef<HTMLButtonElement>(null);\n\tconst list = useRef<HTMLDivElement>(null);\n\tconst pointer = useRef<{ x: number; y: number } | null>(null);\n\tconst resetConfig = useRef({ value, defaultValue, query, defaultQuery, open });\n\tuseEffect(() => {\n\t\tresetConfig.current = { value, defaultValue, query, defaultQuery, open };\n\t});\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: form changes the native owner of the same trigger and requires rebinding its reset listener.\n\tuseEffect(() => {\n\t\tconst owner = trigger.current?.form;\n\t\tif (!owner) return;\n\t\tconst timers = new Set<ReturnType<typeof setTimeout>>();\n\t\tfunction reset(event: Event) {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\ttimers.delete(timer);\n\t\t\t\tif (event.defaultPrevented) return;\n\t\t\t\tconst config = resetConfig.current;\n\t\t\t\tif (config.value === undefined) setLocalValue(config.defaultValue);\n\t\t\t\tif (config.query === undefined) setLocalQuery(config.defaultQuery);\n\t\t\t\tif (config.open === undefined) setLocalOpen(false);\n\t\t\t\tsetActive(null);\n\t\t\t}, 0);\n\t\t\ttimers.add(timer);\n\t\t}\n\t\towner.addEventListener(\"reset\", reset);\n\t\treturn () => {\n\t\t\tfor (const timer of timers) clearTimeout(timer);\n\t\t\towner.removeEventListener(\"reset\", reset);\n\t\t};\n\t}, [form]);\n\tconst id = useId();\n\tconst selected = value ?? localValue;\n\tconst search = query ?? localQuery;\n\tconst expanded = (open ?? localOpen) && !disabled;\n\tconst visible = options.filter(\n\t\t(option) =>\n\t\t\t!filterOptions ||\n\t\t\t`${option.label} ${option.description ?? \"\"}`\n\t\t\t\t.toLocaleLowerCase()\n\t\t\t\t.includes(search.trim().toLocaleLowerCase()),\n\t);\n\tconst enabled = visible.filter((option) => !option.disabled);\n\tconst activeValue = enabled.some((option) => option.value === active)\n\t\t? active\n\t\t: enabled[0]?.value;\n\tconst activeIndex = visible.findIndex((option) => option.value === activeValue);\n\tconst countText = formatSelectionCount\n\t\t? formatSelectionCount(selected.length)\n\t\t: `${selected.length} selected`;\n\n\tfunction changeOpen(next: boolean) {\n\t\tif (disabled) return;\n\t\tif (open === undefined) setLocalOpen(next);\n\t\tonOpenChange?.(next);\n\t}\n\tfunction changeValue(next: string[]) {\n\t\tif (disabled) return;\n\t\tif (value === undefined) setLocalValue(next);\n\t\tonValueChange?.(next);\n\t}\n\tfunction toggle(option: MultiSelectOption) {\n\t\tif (option.disabled) return;\n\t\tchangeValue(\n\t\t\tselected.includes(option.value)\n\t\t\t\t? selected.filter((item) => item !== option.value)\n\t\t\t\t: [...selected, option.value],\n\t\t);\n\t}\n\tfunction removeLast() {\n\t\tif (search) return;\n\t\tconst item = [...selected]\n\t\t\t.reverse()\n\t\t\t.find((value) => !options.find((option) => option.value === value)?.disabled);\n\t\tif (item !== undefined) changeValue(selected.filter((value) => value !== item));\n\t}\n\n\treturn (\n\t\t<div className={cn(BASALT_UI_CLASS, \"min-w-0 space-y-2\", className)}>\n\t\t\t{showChips && selected.length > 0 && (\n\t\t\t\t<div role=\"group\" className=\"flex flex-wrap gap-1.5\" aria-label={`${label}: ${countText}`}>\n\t\t\t\t\t{selected.map((item) => {\n\t\t\t\t\t\tconst option = options.find((option) => option.value === item);\n\t\t\t\t\t\tconst text = option?.label ?? item;\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tkey={item}\n\t\t\t\t\t\t\t\tclassName=\"inline-flex max-w-full items-center gap-1 rounded-basalt-md border border-basalt-border bg-basalt-accent py-0.5 pl-2 text-xs\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span className=\"min-w-0 break-words\">{text}</span>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tdisabled={disabled || option?.disabled}\n\t\t\t\t\t\t\t\t\taria-label={`${removeLabel} ${text}`}\n\t\t\t\t\t\t\t\t\tclassName=\"rounded p-1 focus-visible:outline-2 focus-visible:outline-basalt-ring disabled:opacity-50\"\n\t\t\t\t\t\t\t\t\tonClick={() => changeValue(selected.filter((value) => value !== item))}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<X className=\"size-3\" aria-hidden=\"true\" />\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t{!disabled &&\n\t\t\t\tname &&\n\t\t\t\tselected.map((item) => (\n\t\t\t\t\t<input key={item} type=\"hidden\" name={name} form={form} value={item} />\n\t\t\t\t))}\n\t\t\t<Popover open={expanded} onOpenChange={changeOpen}>\n\t\t\t\t<PopoverTrigger asChild>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tref={trigger}\n\t\t\t\t\t\tform={form}\n\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\taria-label={label}\n\t\t\t\t\t\taria-describedby={`${id}-count`}\n\t\t\t\t\t\tclassName=\"w-full justify-between\"\n\t\t\t\t\t\tonKeyDown={(event) => {\n\t\t\t\t\t\t\tif (event.nativeEvent.isComposing) return;\n\t\t\t\t\t\t\tif (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tchangeOpen(true);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (event.key === \"Backspace\") {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tremoveLast();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<span className=\"truncate\">{selected.length ? countText : placeholder}</span>\n\t\t\t\t\t\t<ChevronDown aria-hidden=\"true\" />\n\t\t\t\t\t</Button>\n\t\t\t\t</PopoverTrigger>\n\t\t\t\t<PopoverContent\n\t\t\t\t\talign=\"start\"\n\t\t\t\t\tclassName=\"w-72 max-w-[calc(100vw-2rem)] p-2\"\n\t\t\t\t\taria-label={label}\n\t\t\t\t\tonOpenAutoFocus={(event) => {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\tinput.current?.focus();\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<Input\n\t\t\t\t\t\tref={input}\n\t\t\t\t\t\trole=\"combobox\"\n\t\t\t\t\t\taria-label={`${label}: search`}\n\t\t\t\t\t\taria-expanded={expanded}\n\t\t\t\t\t\taria-autocomplete=\"list\"\n\t\t\t\t\t\taria-controls={`${id}-list`}\n\t\t\t\t\t\taria-activedescendant={\n\t\t\t\t\t\t\t!loading && activeIndex >= 0 ? `${id}-option-${activeIndex}` : undefined\n\t\t\t\t\t\t}\n\t\t\t\t\t\tplaceholder={searchPlaceholder}\n\t\t\t\t\t\tvalue={search}\n\t\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\t\tif (query === undefined) setLocalQuery(event.target.value);\n\t\t\t\t\t\t\tonQueryChange?.(event.target.value);\n\t\t\t\t\t\t\tsetActive(null);\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonKeyDown={(event) => {\n\t\t\t\t\t\t\tif (event.nativeEvent.isComposing) return;\n\t\t\t\t\t\t\tif (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tif (!loading && enabled.length) {\n\t\t\t\t\t\t\t\t\tconst index = enabled.findIndex((option) => option.value === activeValue);\n\t\t\t\t\t\t\t\t\tconst next =\n\t\t\t\t\t\t\t\t\t\tenabled[\n\t\t\t\t\t\t\t\t\t\t\t(index + (event.key === \"ArrowDown\" ? 1 : -1) + enabled.length) %\n\t\t\t\t\t\t\t\t\t\t\t\tenabled.length\n\t\t\t\t\t\t\t\t\t\t];\n\t\t\t\t\t\t\t\t\tsetActive(next.value);\n\t\t\t\t\t\t\t\t\tlist.current\n\t\t\t\t\t\t\t\t\t\t?.querySelector<HTMLElement>(`[data-option-index=\"${visible.indexOf(next)}\"]`)\n\t\t\t\t\t\t\t\t\t\t?.scrollIntoView({ block: \"nearest\" });\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if (event.key === \"Enter\") {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tconst option = enabled.find((option) => option.value === activeValue);\n\t\t\t\t\t\t\t\tif (!loading && option) toggle(option);\n\t\t\t\t\t\t\t} else if (event.key === \"Backspace\" && !search) {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tremoveLast();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t\t<div\n\t\t\t\t\t\tref={list}\n\t\t\t\t\t\tid={`${id}-list`}\n\t\t\t\t\t\trole=\"listbox\"\n\t\t\t\t\t\taria-label={label}\n\t\t\t\t\t\taria-multiselectable=\"true\"\n\t\t\t\t\t\taria-busy={loading}\n\t\t\t\t\t\tclassName=\"mt-2 max-h-60 overflow-y-auto\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{!loading &&\n\t\t\t\t\t\t\tvisible.map((option, index) => (\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\trole=\"option\"\n\t\t\t\t\t\t\t\t\tid={`${id}-option-${index}`}\n\t\t\t\t\t\t\t\t\tdata-option-index={index}\n\t\t\t\t\t\t\t\t\tkey={option.value}\n\t\t\t\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\t\t\t\taria-selected={selected.includes(option.value)}\n\t\t\t\t\t\t\t\t\taria-disabled={option.disabled || undefined}\n\t\t\t\t\t\t\t\t\tdisabled={option.disabled}\n\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\"flex w-full items-center gap-2 rounded-basalt-md px-2 py-2 text-left text-sm disabled:opacity-40\",\n\t\t\t\t\t\t\t\t\t\tactiveValue === option.value && \"bg-basalt-accent\",\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\tonPointerMove={(event) => {\n\t\t\t\t\t\t\t\t\t\tconst previous = pointer.current;\n\t\t\t\t\t\t\t\t\t\tif (previous?.x === event.clientX && previous.y === event.clientY) return;\n\t\t\t\t\t\t\t\t\t\tpointer.current = { x: event.clientX, y: event.clientY };\n\t\t\t\t\t\t\t\t\t\tif (!option.disabled) setActive(option.value);\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\tonMouseDown={(event) => event.preventDefault()}\n\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\ttoggle(option);\n\t\t\t\t\t\t\t\t\t\tinput.current?.focus();\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\t\t{option.leading}\n\t\t\t\t\t\t\t\t\t<span className=\"min-w-0 flex-1\">\n\t\t\t\t\t\t\t\t\t\t<span className=\"block break-words\">{option.label}</span>\n\t\t\t\t\t\t\t\t\t\t{option.description && (\n\t\t\t\t\t\t\t\t\t\t\t<span className=\"block text-xs text-basalt-muted-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t\t{option.description}\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t{selected.includes(option.value) && (\n\t\t\t\t\t\t\t\t\t\t<Check className=\"size-4 shrink-0\" aria-hidden=\"true\" />\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\t\t\t\t\t{(loading || visible.length === 0) && (\n\t\t\t\t\t\t<p role=\"status\" className=\"px-2 py-4 text-sm text-basalt-muted-foreground\">\n\t\t\t\t\t\t\t{loading ? loadingLabel : emptyLabel}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t)}\n\t\t\t\t</PopoverContent>\n\t\t\t</Popover>\n\t\t\t<span id={`${id}-count`} className=\"sr-only\" aria-live=\"polite\">\n\t\t\t\t{countText}\n\t\t\t</span>\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"multi-select.js","names":["MultiSelect","localValue","setLocalValue","useState","defaultValue","localQuery","setLocalQuery","defaultQuery","localOpen","setLocalOpen","defaultOpen","active","setActive","input","useRef","trigger","list","pointer","resetConfig","useEffect","owner","timers","reset","timer","event","config","form","id","useId","selected","value","search","query","expanded","open","disabled","visible","options","filterOptions","option","enabled","activeValue","activeIndex","countText","formatSelectionCount","changeOpen","next","onOpenChange","changeValue","onValueChange","toggle","item","removeLast","cn","BASALT_UI_CLASS","className","showChips","label","text","removeLabel","X","name","Popover","PopoverTrigger","Button","placeholder","ChevronDown","PopoverContent","Input","loading","searchPlaceholder","onQueryChange","index","previous","Check","loadingLabel","emptyLabel"],"sources":["../../src/components/multi-select.tsx"],"sourcesContent":["import { Check, ChevronDown, X } from \"lucide-react\";\nimport { type ReactNode, useEffect, useId, useRef, useState } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Button } from \"./button\";\nimport { Input } from \"./input\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"./popover\";\n\nexport interface MultiSelectOption {\n\t/** Stable identifier, independent of the display label. */\n\tvalue: string;\n\t/** Searchable and accessible display name. */\n\tlabel: string;\n\t/** Optional secondary searchable text. */\n\tdescription?: string;\n\t/** Caller-provided icon or avatar. */\n\tleading?: ReactNode;\n\t/** Prevent adding or removing this option. */\n\tdisabled?: boolean;\n}\n\nexport interface MultiSelectProps {\n\t/** Accessible field and popup name. */\n\tlabel: string;\n\t/** Available options; retain selected options to preserve their display labels. */\n\toptions: readonly MultiSelectOption[];\n\t/** Controlled selected identifiers. */\n\tvalue?: readonly string[];\n\t/** Initial uncontrolled selection. @default [] */\n\tdefaultValue?: readonly string[];\n\t/** Selection requests; controlled values change only when accepted by the caller. */\n\tonValueChange?: (value: string[]) => void;\n\t/** Controlled search text; asynchronous requests belong to the caller. */\n\tquery?: string;\n\t/** Initial uncontrolled search text. @default \"\" */\n\tdefaultQuery?: string;\n\t/** Search text requests. */\n\tonQueryChange?: (query: string) => void;\n\t/** Controlled popup visibility. */\n\topen?: boolean;\n\t/** Initial uncontrolled popup visibility. @default false */\n\tdefaultOpen?: boolean;\n\t/** Popup visibility requests. */\n\tonOpenChange?: (open: boolean) => void;\n\t/** Use local label/description filtering; disable for server-filtered options. @default true */\n\tfilterOptions?: boolean;\n\t/** Loading content replaces the option list. @default false */\n\tloading?: boolean;\n\t/** Disables the trigger, chips, and native form entries. @default false */\n\tdisabled?: boolean;\n\t/** Repeated native form entry name, one entry per selected identifier. */\n\tname?: string;\n\t/** Optional external native form owner. Uncontrolled state respects uncancelled form resets. */\n\tform?: string;\n\t/** Empty selection prompt. @default \"Select options\" */\n\tplaceholder?: string;\n\t/** Search input prompt. @default \"Search options…\" */\n\tsearchPlaceholder?: string;\n\t/** Empty search result text. @default \"No options found.\" */\n\temptyLabel?: string;\n\t/** Loading announcement. @default \"Loading options…\" */\n\tloadingLabel?: string;\n\t/** Chip removal label prefix. @default \"Remove\" */\n\tremoveLabel?: string;\n\t/** Show removable selection chips; disable when a FilterBar renders its own chips. @default true */\n\tshowChips?: boolean;\n\t/** Selection count formatter, including localization. */\n\tformatSelectionCount?: (count: number) => string;\n\t/** Additional root classes. */\n\tclassName?: string;\n}\n\nexport function MultiSelect({\n\tlabel,\n\toptions,\n\tvalue,\n\tdefaultValue = [],\n\tonValueChange,\n\tquery,\n\tdefaultQuery = \"\",\n\tonQueryChange,\n\topen,\n\tdefaultOpen = false,\n\tonOpenChange,\n\tfilterOptions = true,\n\tloading = false,\n\tdisabled = false,\n\tname,\n\tform,\n\tplaceholder = \"Select options\",\n\tsearchPlaceholder = \"Search options…\",\n\temptyLabel = \"No options found.\",\n\tloadingLabel = \"Loading options…\",\n\tremoveLabel = \"Remove\",\n\tshowChips = true,\n\tformatSelectionCount,\n\tclassName,\n}: MultiSelectProps) {\n\tconst [localValue, setLocalValue] = useState(defaultValue);\n\tconst [localQuery, setLocalQuery] = useState(defaultQuery);\n\tconst [localOpen, setLocalOpen] = useState(defaultOpen);\n\tconst [active, setActive] = useState<string | null>(null);\n\tconst input = useRef<HTMLInputElement>(null);\n\tconst trigger = useRef<HTMLButtonElement>(null);\n\tconst list = useRef<HTMLDivElement>(null);\n\tconst pointer = useRef<{ x: number; y: number } | null>(null);\n\tconst resetConfig = useRef({ value, defaultValue, query, defaultQuery, open });\n\tuseEffect(() => {\n\t\tresetConfig.current = { value, defaultValue, query, defaultQuery, open };\n\t});\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: form changes the native owner of the same trigger and requires rebinding its reset listener.\n\tuseEffect(() => {\n\t\tconst owner = trigger.current?.form;\n\t\tif (!owner) return;\n\t\tconst timers = new Set<ReturnType<typeof setTimeout>>();\n\t\tfunction reset(event: Event) {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\ttimers.delete(timer);\n\t\t\t\tif (event.defaultPrevented) return;\n\t\t\t\tconst config = resetConfig.current;\n\t\t\t\tif (config.value === undefined) setLocalValue(config.defaultValue);\n\t\t\t\tif (config.query === undefined) setLocalQuery(config.defaultQuery);\n\t\t\t\tif (config.open === undefined) setLocalOpen(false);\n\t\t\t\tsetActive(null);\n\t\t\t}, 0);\n\t\t\ttimers.add(timer);\n\t\t}\n\t\towner.addEventListener(\"reset\", reset);\n\t\treturn () => {\n\t\t\tfor (const timer of timers) clearTimeout(timer);\n\t\t\towner.removeEventListener(\"reset\", reset);\n\t\t};\n\t}, [form]);\n\tconst id = useId();\n\tconst selected = value ?? localValue;\n\tconst search = query ?? localQuery;\n\tconst expanded = (open ?? localOpen) && !disabled;\n\tconst visible = options.filter(\n\t\t(option) =>\n\t\t\t!filterOptions ||\n\t\t\t`${option.label} ${option.description ?? \"\"}`\n\t\t\t\t.toLocaleLowerCase()\n\t\t\t\t.includes(search.trim().toLocaleLowerCase()),\n\t);\n\tconst enabled = visible.filter((option) => !option.disabled);\n\tconst activeValue = enabled.some((option) => option.value === active)\n\t\t? active\n\t\t: enabled[0]?.value;\n\tconst activeIndex = visible.findIndex((option) => option.value === activeValue);\n\tconst countText = formatSelectionCount\n\t\t? formatSelectionCount(selected.length)\n\t\t: `${selected.length} selected`;\n\n\tfunction changeOpen(next: boolean) {\n\t\tif (disabled) return;\n\t\tif (open === undefined) setLocalOpen(next);\n\t\tonOpenChange?.(next);\n\t}\n\tfunction changeValue(next: string[]) {\n\t\tif (disabled) return;\n\t\tif (value === undefined) setLocalValue(next);\n\t\tonValueChange?.(next);\n\t}\n\tfunction toggle(option: MultiSelectOption) {\n\t\tif (option.disabled) return;\n\t\tchangeValue(\n\t\t\tselected.includes(option.value)\n\t\t\t\t? selected.filter((item) => item !== option.value)\n\t\t\t\t: [...selected, option.value],\n\t\t);\n\t}\n\tfunction removeLast() {\n\t\tif (search) return;\n\t\tconst item = [...selected]\n\t\t\t.reverse()\n\t\t\t.find((value) => !options.find((option) => option.value === value)?.disabled);\n\t\tif (item !== undefined) changeValue(selected.filter((value) => value !== item));\n\t}\n\n\treturn (\n\t\t<div className={cn(BASALT_UI_CLASS, \"min-w-0 space-y-2\", className)}>\n\t\t\t{showChips && selected.length > 0 && (\n\t\t\t\t<div role=\"group\" className=\"flex flex-wrap gap-1.5\" aria-label={`${label}: ${countText}`}>\n\t\t\t\t\t{selected.map((item) => {\n\t\t\t\t\t\tconst option = options.find((option) => option.value === item);\n\t\t\t\t\t\tconst text = option?.label ?? item;\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tkey={item}\n\t\t\t\t\t\t\t\tclassName=\"inline-flex max-w-full items-center gap-1 rounded-basalt-md border border-basalt-border bg-basalt-accent py-0.5 pl-2 text-xs\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span className=\"min-w-0 break-words\">{text}</span>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tdisabled={disabled || option?.disabled}\n\t\t\t\t\t\t\t\t\taria-label={`${removeLabel} ${text}`}\n\t\t\t\t\t\t\t\t\tclassName=\"rounded p-1 focus-visible:outline-2 focus-visible:outline-basalt-ring disabled:opacity-50\"\n\t\t\t\t\t\t\t\t\tonClick={() => changeValue(selected.filter((value) => value !== item))}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<X className=\"size-3\" aria-hidden=\"true\" />\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t{!disabled &&\n\t\t\t\tname &&\n\t\t\t\tselected.map((item) => (\n\t\t\t\t\t<input key={item} type=\"hidden\" name={name} form={form} value={item} />\n\t\t\t\t))}\n\t\t\t<Popover open={expanded} onOpenChange={changeOpen}>\n\t\t\t\t<PopoverTrigger asChild>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tref={trigger}\n\t\t\t\t\t\tform={form}\n\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\taria-label={label}\n\t\t\t\t\t\taria-describedby={`${id}-count`}\n\t\t\t\t\t\tclassName=\"w-full justify-between\"\n\t\t\t\t\t\tonKeyDown={(event) => {\n\t\t\t\t\t\t\tif (event.nativeEvent.isComposing) return;\n\t\t\t\t\t\t\tif (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tchangeOpen(true);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (event.key === \"Backspace\") {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tremoveLast();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<span className=\"truncate\">{selected.length ? countText : placeholder}</span>\n\t\t\t\t\t\t<ChevronDown aria-hidden=\"true\" />\n\t\t\t\t\t</Button>\n\t\t\t\t</PopoverTrigger>\n\t\t\t\t<PopoverContent\n\t\t\t\t\talign=\"start\"\n\t\t\t\t\tclassName=\"w-72 max-w-[calc(100vw-2rem)] p-2\"\n\t\t\t\t\taria-label={label}\n\t\t\t\t\tonOpenAutoFocus={(event) => {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\tinput.current?.focus();\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<Input\n\t\t\t\t\t\tref={input}\n\t\t\t\t\t\trole=\"combobox\"\n\t\t\t\t\t\taria-label={`${label}: search`}\n\t\t\t\t\t\taria-expanded={expanded}\n\t\t\t\t\t\taria-autocomplete=\"list\"\n\t\t\t\t\t\taria-controls={`${id}-list`}\n\t\t\t\t\t\taria-activedescendant={\n\t\t\t\t\t\t\t!loading && activeIndex >= 0 ? `${id}-option-${activeIndex}` : undefined\n\t\t\t\t\t\t}\n\t\t\t\t\t\tplaceholder={searchPlaceholder}\n\t\t\t\t\t\tvalue={search}\n\t\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\t\tif (query === undefined) setLocalQuery(event.target.value);\n\t\t\t\t\t\t\tonQueryChange?.(event.target.value);\n\t\t\t\t\t\t\tsetActive(null);\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonKeyDown={(event) => {\n\t\t\t\t\t\t\tif (event.nativeEvent.isComposing) return;\n\t\t\t\t\t\t\tif (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tif (!loading && enabled.length) {\n\t\t\t\t\t\t\t\t\tconst index = enabled.findIndex((option) => option.value === activeValue);\n\t\t\t\t\t\t\t\t\tconst next =\n\t\t\t\t\t\t\t\t\t\tenabled[\n\t\t\t\t\t\t\t\t\t\t\t(index + (event.key === \"ArrowDown\" ? 1 : -1) + enabled.length) %\n\t\t\t\t\t\t\t\t\t\t\t\tenabled.length\n\t\t\t\t\t\t\t\t\t\t];\n\t\t\t\t\t\t\t\t\tsetActive(next.value);\n\t\t\t\t\t\t\t\t\tlist.current\n\t\t\t\t\t\t\t\t\t\t?.querySelector<HTMLElement>(`[data-option-index=\"${visible.indexOf(next)}\"]`)\n\t\t\t\t\t\t\t\t\t\t?.scrollIntoView({ block: \"nearest\" });\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if (event.key === \"Enter\") {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tconst option = enabled.find((option) => option.value === activeValue);\n\t\t\t\t\t\t\t\tif (!loading && option) toggle(option);\n\t\t\t\t\t\t\t} else if (event.key === \"Backspace\" && !search) {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tremoveLast();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t\t<div\n\t\t\t\t\t\tref={list}\n\t\t\t\t\t\tid={`${id}-list`}\n\t\t\t\t\t\trole=\"listbox\"\n\t\t\t\t\t\taria-label={label}\n\t\t\t\t\t\taria-multiselectable=\"true\"\n\t\t\t\t\t\taria-busy={loading}\n\t\t\t\t\t\tclassName=\"mt-2 max-h-60 overflow-y-auto\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{!loading &&\n\t\t\t\t\t\t\tvisible.map((option, index) => (\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\trole=\"option\"\n\t\t\t\t\t\t\t\t\tid={`${id}-option-${index}`}\n\t\t\t\t\t\t\t\t\tdata-option-index={index}\n\t\t\t\t\t\t\t\t\tkey={option.value}\n\t\t\t\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\t\t\t\taria-selected={selected.includes(option.value)}\n\t\t\t\t\t\t\t\t\taria-disabled={option.disabled || undefined}\n\t\t\t\t\t\t\t\t\tdisabled={option.disabled}\n\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\"flex w-full items-center gap-2 rounded-basalt-md px-2 py-2 text-left text-sm disabled:opacity-40\",\n\t\t\t\t\t\t\t\t\t\tactiveValue === option.value && \"bg-basalt-accent\",\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\tonPointerMove={(event) => {\n\t\t\t\t\t\t\t\t\t\tconst previous = pointer.current;\n\t\t\t\t\t\t\t\t\t\tif (previous?.x === event.clientX && previous.y === event.clientY) return;\n\t\t\t\t\t\t\t\t\t\tpointer.current = { x: event.clientX, y: event.clientY };\n\t\t\t\t\t\t\t\t\t\tif (!option.disabled) setActive(option.value);\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\tonMouseDown={(event) => event.preventDefault()}\n\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\ttoggle(option);\n\t\t\t\t\t\t\t\t\t\tinput.current?.focus();\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\t\t{option.leading}\n\t\t\t\t\t\t\t\t\t<span className=\"min-w-0 flex-1\">\n\t\t\t\t\t\t\t\t\t\t<span className=\"block break-words\">{option.label}</span>\n\t\t\t\t\t\t\t\t\t\t{option.description && (\n\t\t\t\t\t\t\t\t\t\t\t<span className=\"block text-xs text-basalt-muted-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t\t{option.description}\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t{selected.includes(option.value) && (\n\t\t\t\t\t\t\t\t\t\t<Check className=\"size-4 shrink-0\" aria-hidden=\"true\" />\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\t\t\t\t\t{(loading || visible.length === 0) && (\n\t\t\t\t\t\t<p role=\"status\" className=\"px-2 py-4 text-sm text-basalt-muted-foreground\">\n\t\t\t\t\t\t\t{loading ? loadingLabel : emptyLabel}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t)}\n\t\t\t\t</PopoverContent>\n\t\t\t</Popover>\n\t\t\t<span id={`${id}-count`} className=\"sr-only\" aria-live=\"polite\">\n\t\t\t\t{countText}\n\t\t\t</span>\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;;;;;;;AAwEA,SAAgBA,EAAY,EAC3B,UACA,YACA,UACA,kBAAe,CAAC,GAChB,kBACA,UACA,kBAAe,IACf,mBACA,SACA,kBAAc,IACd,kBACA,oBAAgB,IAChB,aAAU,IACV,cAAW,IACX,SACA,SACA,kBAAc,kBACd,wBAAoB,mBACpB,gBAAa,qBACb,kBAAe,oBACf,iBAAc,UACd,eAAY,IACZ,yBACA,gBACoB;CACpB,IAAM,CAACC,IAAYC,KAAiBC,EAASC,CAAY,GACnD,CAACC,IAAYC,KAAiBH,EAASI,CAAY,GACnD,CAACC,IAAWC,KAAgBN,EAASO,EAAW,GAChD,CAACC,GAAQC,KAAaT,EAAwB,IAAI,GAClDU,IAAQC,EAAyB,IAAI,GACrCC,IAAUD,EAA0B,IAAI,GACxCE,IAAOF,EAAuB,IAAI,GAClCG,IAAUH,EAAwC,IAAI,GACtDI,IAAcJ,EAAO;EAAE;EAAO;EAAc;EAAO;EAAc;CAAK,CAAC;CAK7E,AAJAK,QAAgB;EACf,EAAY,UAAU;GAAE;GAAO;GAAc;GAAO;GAAc;EAAK;CACxE,CAAC,GAEDA,QAAgB;EACf,IAAMC,IAAQL,EAAQ,SAAS;EAC/B,IAAI,CAACK,GAAO;EACZ,IAAMC,oBAAS,IAAI,IAAmC;EACtD,SAASC,EAAM,GAAc;GAC5B,IAAMC,IAAQ,iBAAiB;IAE9B,IADAF,EAAO,OAAOE,CAAK,GACfC,EAAM,kBAAkB;IAC5B,IAAMC,IAASP,EAAY;IAI3B,AAHIO,EAAO,UAAU,KAAA,KAAWvB,EAAcuB,EAAO,YAAY,GAC7DA,EAAO,UAAU,KAAA,KAAWnB,EAAcmB,EAAO,YAAY,GAC7DA,EAAO,SAAS,KAAA,KAAWhB,EAAa,EAAK,GACjDG,EAAU,IAAI;GACf,GAAG,CAAC;GACJ,EAAO,IAAIW,CAAK;EACjB;EAEA,OADAH,EAAM,iBAAiB,SAASE,CAAK,SACxB;GACZ,KAAK,IAAMC,KAASF,GAAQ,aAAaE,CAAK;GAC9C,EAAM,oBAAoB,SAASD,CAAK;EACzC;CACD,GAAG,CAACI,CAAI,CAAC;CACT,IAAMC,IAAKC,EAAM,GACXC,IAAWC,KAAS7B,IACpB8B,IAASC,KAAS3B,IAClB4B,KAAYC,KAAQ1B,OAAc,CAAC2B,GACnCC,IAAUC,EAAQ,QACtB,MACA,CAACC,MACD,GAAGC,EAAO,MAAM,GAAGA,EAAO,eAAe,KACvC,kBAAkB,CAAC,CACnB,SAASR,EAAO,KAAK,CAAC,CAAC,kBAAkB,CAAC,CAC9C,GACMS,IAAUJ,EAAQ,QAAQ,MAAW,CAACG,EAAO,QAAQ,GACrDE,IAAcD,EAAQ,MAAM,MAAWD,EAAO,UAAU5B,CAAM,IACjEA,IACA6B,EAAQ,EAAE,EAAE,OACTE,IAAcN,EAAQ,WAAW,MAAWG,EAAO,UAAUE,CAAW,GACxEE,IAAYC,IACfA,EAAqBf,EAAS,MAAM,IACpC,GAAGA,EAAS,OAAO;CAEtB,SAASgB,EAAW,GAAe;EAClC,AAAIV,MACAD,MAAS,KAAA,KAAWzB,EAAaqC,CAAI,GACzCC,KAAeD,CAAI;CACpB;CACA,SAASE,EAAY,GAAgB;EACpC,AAAIb,MACAL,MAAU,KAAA,KAAW5B,EAAc4C,CAAI,GAC3CG,IAAgBH,CAAI;CACrB;CACA,SAASI,EAAO,GAA2B;EAC1C,AAAIX,EAAO,YACXS,EACCnB,EAAS,SAASU,EAAO,KAAK,IAC3BV,EAAS,QAAQ,MAASsB,MAASZ,EAAO,KAAK,IAC/C,CAAC,GAAGV,GAAUU,EAAO,KAAK,CAC9B;CACD;CACA,SAASa,IAAa;EACrB,IAAIrB,GAAQ;EACZ,IAAMoB,IAAO,CAAC,GAAGtB,CAAQ,CAAC,CACxB,QAAQ,CAAC,CACT,MAAM,MAAU,CAACQ,EAAQ,MAAM,MAAWE,EAAO,UAAUT,CAAK,CAAC,EAAE,QAAQ;EAC7E,AAAIqB,MAAS,KAAA,KAAWH,EAAYnB,EAAS,QAAQ,MAAUC,MAAUqB,CAAI,CAAC;CAC/E;CAEA,OACC,kBAAC,OAAD;EAAK,WAAWE,EAAGC,GAAiB,qBAAqBC,CAAS;EAAlE,UAAA;GACEC,KAAa3B,EAAS,SAAS,KAC/B,kBAAC,OAAD;IAAK,MAAK;IAAQ,WAAU;IAAyB,cAAY,GAAG4B,EAAM,IAAId;IAC5E,UAAAd,EAAS,KAAK,MAAS;KACvB,IAAMU,IAASF,EAAQ,MAAM,MAAWE,EAAO,UAAUY,CAAI,GACvDO,IAAOnB,GAAQ,SAASY;KAC9B,OACC,kBAAC,QAAD;MAEC,WAAU;MAFX,UAAA,CAIC,kBAAC,QAAD;OAAM,WAAU;OAAuB,UAAAO;MAAW,CAAA,GAClD,kBAAC,UAAD;OACC,MAAK;OACL,UAAUvB,KAAYI,GAAQ;OAC9B,cAAY,GAAGoB,EAAY,GAAGD;OAC9B,WAAU;OACV,eAAeV,EAAYnB,EAAS,QAAQ,MAAUC,MAAUqB,CAAI,CAAC;OAErE,UAAA,kBAACS,GAAD;QAAG,WAAU;QAAS,eAAY;OAAQ,CAAA;MACnC,CAAA,CACH;KAbA,GAAAT,CAaA;IAER,CAAC;GACG,CAAA;GAEL,CAAChB,KACD0B,KACAhC,EAAS,KAAK,MACb,kBAAC,SAAD;IAAkB,MAAK;IAAe;IAAY;IAAM,OAAOsB;GAAO,GAA1DA,CAA0D,CACtE;GACF,kBAACW,IAAD;IAAS,MAAM7B;IAAU,cAAcY;IAAvC,UAAA,CACC,kBAACkB,IAAD;KAAgB,SAAA;KACf,UAAA,kBAACC,GAAD;MACC,KAAKjD;MACC;MACN,SAAQ;MACE;MACV,cAAY0C;MACZ,oBAAkB,GAAG9B,EAAG;MACxB,WAAU;MACV,YAAY,MAAU;OACrB,AAAIH,EAAM,YAAY,iBAClBA,EAAM,QAAQ,eAAeA,EAAM,QAAQ,eAC9CA,EAAM,eAAe,GACrBqB,EAAW,EAAI,IAEZrB,EAAM,QAAQ,gBACjBA,EAAM,eAAe,GACrB4B,EAAW;MAEb;MAlBD,UAAA,CAoBC,kBAAC,QAAD;OAAM,WAAU;OAAY,UAAAvB,EAAS,SAASc,IAAYsB;MAAkB,CAAA,GAC5E,kBAACC,GAAD,EAAa,eAAY,OAAQ,CAAA,CAC1B;;IACO,CAAA,GAChB,kBAACC,IAAD;KACC,OAAM;KACN,WAAU;KACV,cAAYV;KACZ,kBAAkB,MAAU;MAE3B,AADAjC,EAAM,eAAe,GACrBX,EAAM,SAAS,MAAM;KACtB;KAPD,UAAA;MASC,kBAACuD,GAAD;OACC,KAAKvD;OACL,MAAK;OACL,cAAY,GAAG4C,EAAM;OACrB,iBAAexB;OACf,qBAAkB;OAClB,iBAAe,GAAGN,EAAG;OACrB,yBACC,CAAC0C,KAAW3B,KAAe,IAAI,GAAGf,EAAG,UAAUe,MAAgB,KAAA;OAEhE,aAAa4B;OACb,OAAOvC;OACP,WAAW,MAAU;QAGpB,AAFIC,MAAU,KAAA,KAAW1B,EAAckB,EAAM,OAAO,KAAK,GACzD+C,KAAgB/C,EAAM,OAAO,KAAK,GAClCZ,EAAU,IAAI;OACf;OACA,YAAY,MAAU;QACrB,IAAI,GAAM,YAAY,aACtB;aAAIY,EAAM,QAAQ,eAAeA,EAAM,QAAQ,WAE9C;cADAA,EAAM,eAAe,GACjB,CAAC6C,KAAW7B,EAAQ,QAAQ;WAC/B,IAAMgC,IAAQhC,EAAQ,WAAW,MAAWD,EAAO,UAAUE,CAAW,GAClEK,IACLN,GACEgC,KAAShD,EAAM,QAAQ,cAAc,IAAI,MAAMgB,EAAQ,UACvDA,EAAQ;WAGX,AADA5B,EAAUkC,EAAK,KAAK,GACpB9B,EAAK,SACF,cAA2B,uBAAuBoB,EAAQ,QAAQU,CAAI,EAAE,GAAG,CAAC,EAC5E,eAAe,EAAE,OAAO,UAAU,CAAC;UACvC;gBACM,IAAItB,EAAM,QAAQ,SAAS;UACjC,EAAM,eAAe;UACrB,IAAMe,IAASC,EAAQ,MAAM,MAAWD,EAAO,UAAUE,CAAW;UACpE,AAAI,CAAC4B,KAAW9B,KAAQW,EAAOX,CAAM;SACtC,OAAO,AAAIf,EAAM,QAAQ,eAAe,CAACO,MACxCP,EAAM,eAAe,GACrB4B,EAAW;QACZ;OACD;MACA,CAAA;MACD,kBAAC,OAAD;OACC,KAAKpC;OACL,IAAI,GAAGW,EAAG;OACV,MAAK;OACL,cAAY8B;OACZ,wBAAqB;OACrB,aAAWY;OACX,WAAU;OAET,UAAA,CAACA,KACDjC,EAAQ,KAAK,GAAQ,MACpB,kBAAC,UAAD;QACC,MAAK;QACL,MAAK;QACL,IAAI,GAAGT,EAAG,UAAU6C;QACpB,qBAAmBA;QAEnB,UAAU;QACV,iBAAe3C,EAAS,SAASU,EAAO,KAAK;QAC7C,iBAAeA,EAAO,YAAY,KAAA;QAClC,UAAUA,EAAO;QACjB,WAAWc,EACV,oGACAZ,MAAgBF,EAAO,SAAS,kBACjC;QACA,gBAAgB,MAAU;SACzB,IAAMkC,IAAWxD,EAAQ;SACzB,CAAIwD,GAAU,MAAMjD,EAAM,WAAWiD,EAAS,MAAMjD,EAAM,aAC1D,EAAQ,UAAU;UAAE,GAAGA,EAAM;UAAS,GAAGA,EAAM;SAAQ,GAClDe,EAAO,YAAU3B,EAAU2B,EAAO,KAAK;QAC7C;QACA,cAAc,MAAUf,EAAM,eAAe;QAC7C,eAAe;SAEd,AADA0B,EAAOX,CAAM,GACb1B,EAAM,SAAS,MAAM;QACtB;QAxBD,UAAA;SA0BE0B,EAAO;SACR,kBAAC,QAAD;UAAM,WAAU;UAAhB,UAAA,CACC,kBAAC,QAAD;WAAM,WAAU;WAAqB,UAAAA,EAAO;UAAY,CAAA,GACvDA,EAAO,eACP,kBAAC,QAAD;WAAM,WAAU;WACd,UAAAA,EAAO;UACH,CAAA,CAEF;;SACLV,EAAS,SAASU,EAAO,KAAK,KAC9B,kBAACmC,GAAD;UAAO,WAAU;UAAkB,eAAY;SAAQ,CAAA;QAEjD;OAjCF,GAAAnC,EAAO,KAiCL,CACR;MACE,CAAA;OACH8B,KAAWjC,EAAQ,WAAW,MAC/B,kBAAC,KAAD;OAAG,MAAK;OAAS,WAAU;OACzB,UAAAiC,IAAUM,IAAeC;MACxB,CAAA;KAEW;IACR,CAAA,CAAA;;GACT,kBAAC,QAAD;IAAM,IAAI,GAAGjD,EAAG;IAAS,WAAU;IAAU,aAAU;IACrD,UAAAgB;GACI,CAAA;EACF;;AAEP"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation-menu.js","names":[],"sources":["../../src/components/navigation-menu.tsx"],"sourcesContent":["import * as NavigationMenuPrimitive from \"@radix-ui/react-navigation-menu\";\nimport type * as React from \"react\";\nimport { cn } from \"../utils/cn\";\n\ntype RadixNavigationMenuProps = React.ComponentProps<typeof NavigationMenuPrimitive.Root>;\ntype RadixNavigationMenuListProps = React.ComponentProps<typeof NavigationMenuPrimitive.List>;\ntype RadixNavigationMenuItemProps = React.ComponentProps<typeof NavigationMenuPrimitive.Item>;\ntype RadixNavigationMenuLinkProps = React.ComponentProps<typeof NavigationMenuPrimitive.Link>;\n\nexport interface NavigationMenuProps\n\textends Omit<\n\t\tRadixNavigationMenuProps,\n\t\t| \"value\"\n\t\t| \"defaultValue\"\n\t\t| \"onValueChange\"\n\t\t| \"dir\"\n\t\t| \"orientation\"\n\t\t| \"delayDuration\"\n\t\t| \"skipDelayDuration\"\n\t\t| \"asChild\"\n\t> {\n\t/**\n\t * Controlled value of the currently active navigation item.\n\t */\n\tvalue?: RadixNavigationMenuProps[\"value\"];\n\t/**\n\t * Uncontrolled initial active navigation item value.\n\t */\n\tdefaultValue?: RadixNavigationMenuProps[\"defaultValue\"];\n\t/**\n\t * Callback invoked when active navigation item value changes.\n\t */\n\tonValueChange?: RadixNavigationMenuProps[\"onValueChange\"];\n\t/**\n\t * Reading direction of the navigation menu. Inherits from nearest DirectionProvider or ltr.\n\t * @default \"ltr\"\n\t */\n\tdir?: RadixNavigationMenuProps[\"dir\"];\n\t/**\n\t * Orientation of the navigation menu items and keyboard navigation axis.\n\t * @default \"horizontal\"\n\t */\n\torientation?: RadixNavigationMenuProps[\"orientation\"];\n\t/**\n\t * Duration in milliseconds from pointer entering trigger until menu opens.\n\t * @default 200\n\t */\n\tdelayDuration?: RadixNavigationMenuProps[\"delayDuration\"];\n\t/**\n\t * Duration in milliseconds to move between triggers without re-triggering delay.\n\t * @default 300\n\t */\n\tskipDelayDuration?: RadixNavigationMenuProps[\"skipDelayDuration\"];\n\t/**\n\t * Change the default rendered nav element to the child element, merging props and behavior.\n\t * NavigationMenu forwards ref to HTMLElement and inherits native nav attributes.\n\t * @default false\n\t */\n\tasChild?: RadixNavigationMenuProps[\"asChild\"];\n}\n\nexport const NavigationMenu = NavigationMenuPrimitive.Root;\n\nexport interface NavigationMenuListProps extends Omit<RadixNavigationMenuListProps, \"asChild\"> {\n\t/**\n\t * Change the default rendered ul element to the child element, merging props and behavior.\n\t * NavigationMenuList forwards ref to HTMLUListElement and inherits native ul attributes.\n\t * @default false\n\t */\n\tasChild?: RadixNavigationMenuListProps[\"asChild\"];\n}\n\nexport const NavigationMenuList = NavigationMenuPrimitive.List;\n\nexport interface NavigationMenuItemProps\n\textends Omit<RadixNavigationMenuItemProps, \"value\" | \"asChild\"> {\n\t/**\n\t * Unique value that associates the item with sub-navigation state.\n\t */\n\tvalue?: RadixNavigationMenuItemProps[\"value\"];\n\t/**\n\t * Change the default rendered li element to the child element, merging props and behavior.\n\t * NavigationMenuItem forwards ref to HTMLLIElement and inherits native li attributes.\n\t * @default false\n\t */\n\tasChild?: RadixNavigationMenuItemProps[\"asChild\"];\n}\n\nexport const NavigationMenuItem = NavigationMenuPrimitive.Item;\n\nexport interface NavigationMenuLinkProps\n\textends Omit<RadixNavigationMenuLinkProps, \"active\" | \"onSelect\" | \"asChild\"> {\n\t/**\n\t * Whether the link represents the currently active destination.\n\t * Adds data-active attribute for styling.\n\t * @default false\n\t */\n\tactive?: RadixNavigationMenuLinkProps[\"active\"];\n\t/**\n\t * Event handler called when the navigation link is selected via pointer or keyboard.\n\t */\n\tonSelect?: RadixNavigationMenuLinkProps[\"onSelect\"];\n\t/**\n\t * Change the default rendered anchor element to the child element, merging props and behavior.\n\t * NavigationMenuLink forwards ref to HTMLAnchorElement and inherits native anchor attributes.\n\t * @default false\n\t */\n\tasChild?: RadixNavigationMenuLinkProps[\"asChild\"];\n}\n\nexport function NavigationMenuLink({ className, ...props }: NavigationMenuLinkProps) {\n\treturn (\n\t\t<NavigationMenuPrimitive.Link\n\t\t\tclassName={cn(\"rounded-basalt-md px-3 py-2 text-sm hover:bg-basalt-accent\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n"],"mappings":";;;;;AA6DA,
|
|
1
|
+
{"version":3,"file":"navigation-menu.js","names":["NavigationMenuPrimitive","NavigationMenu","NavigationMenuList","NavigationMenuItem","NavigationMenuLink","props","cn","className"],"sources":["../../src/components/navigation-menu.tsx"],"sourcesContent":["import * as NavigationMenuPrimitive from \"@radix-ui/react-navigation-menu\";\nimport type * as React from \"react\";\nimport { cn } from \"../utils/cn\";\n\ntype RadixNavigationMenuProps = React.ComponentProps<typeof NavigationMenuPrimitive.Root>;\ntype RadixNavigationMenuListProps = React.ComponentProps<typeof NavigationMenuPrimitive.List>;\ntype RadixNavigationMenuItemProps = React.ComponentProps<typeof NavigationMenuPrimitive.Item>;\ntype RadixNavigationMenuLinkProps = React.ComponentProps<typeof NavigationMenuPrimitive.Link>;\n\nexport interface NavigationMenuProps\n\textends Omit<\n\t\tRadixNavigationMenuProps,\n\t\t| \"value\"\n\t\t| \"defaultValue\"\n\t\t| \"onValueChange\"\n\t\t| \"dir\"\n\t\t| \"orientation\"\n\t\t| \"delayDuration\"\n\t\t| \"skipDelayDuration\"\n\t\t| \"asChild\"\n\t> {\n\t/**\n\t * Controlled value of the currently active navigation item.\n\t */\n\tvalue?: RadixNavigationMenuProps[\"value\"];\n\t/**\n\t * Uncontrolled initial active navigation item value.\n\t */\n\tdefaultValue?: RadixNavigationMenuProps[\"defaultValue\"];\n\t/**\n\t * Callback invoked when active navigation item value changes.\n\t */\n\tonValueChange?: RadixNavigationMenuProps[\"onValueChange\"];\n\t/**\n\t * Reading direction of the navigation menu. Inherits from nearest DirectionProvider or ltr.\n\t * @default \"ltr\"\n\t */\n\tdir?: RadixNavigationMenuProps[\"dir\"];\n\t/**\n\t * Orientation of the navigation menu items and keyboard navigation axis.\n\t * @default \"horizontal\"\n\t */\n\torientation?: RadixNavigationMenuProps[\"orientation\"];\n\t/**\n\t * Duration in milliseconds from pointer entering trigger until menu opens.\n\t * @default 200\n\t */\n\tdelayDuration?: RadixNavigationMenuProps[\"delayDuration\"];\n\t/**\n\t * Duration in milliseconds to move between triggers without re-triggering delay.\n\t * @default 300\n\t */\n\tskipDelayDuration?: RadixNavigationMenuProps[\"skipDelayDuration\"];\n\t/**\n\t * Change the default rendered nav element to the child element, merging props and behavior.\n\t * NavigationMenu forwards ref to HTMLElement and inherits native nav attributes.\n\t * @default false\n\t */\n\tasChild?: RadixNavigationMenuProps[\"asChild\"];\n}\n\nexport const NavigationMenu = NavigationMenuPrimitive.Root;\n\nexport interface NavigationMenuListProps extends Omit<RadixNavigationMenuListProps, \"asChild\"> {\n\t/**\n\t * Change the default rendered ul element to the child element, merging props and behavior.\n\t * NavigationMenuList forwards ref to HTMLUListElement and inherits native ul attributes.\n\t * @default false\n\t */\n\tasChild?: RadixNavigationMenuListProps[\"asChild\"];\n}\n\nexport const NavigationMenuList = NavigationMenuPrimitive.List;\n\nexport interface NavigationMenuItemProps\n\textends Omit<RadixNavigationMenuItemProps, \"value\" | \"asChild\"> {\n\t/**\n\t * Unique value that associates the item with sub-navigation state.\n\t */\n\tvalue?: RadixNavigationMenuItemProps[\"value\"];\n\t/**\n\t * Change the default rendered li element to the child element, merging props and behavior.\n\t * NavigationMenuItem forwards ref to HTMLLIElement and inherits native li attributes.\n\t * @default false\n\t */\n\tasChild?: RadixNavigationMenuItemProps[\"asChild\"];\n}\n\nexport const NavigationMenuItem = NavigationMenuPrimitive.Item;\n\nexport interface NavigationMenuLinkProps\n\textends Omit<RadixNavigationMenuLinkProps, \"active\" | \"onSelect\" | \"asChild\"> {\n\t/**\n\t * Whether the link represents the currently active destination.\n\t * Adds data-active attribute for styling.\n\t * @default false\n\t */\n\tactive?: RadixNavigationMenuLinkProps[\"active\"];\n\t/**\n\t * Event handler called when the navigation link is selected via pointer or keyboard.\n\t */\n\tonSelect?: RadixNavigationMenuLinkProps[\"onSelect\"];\n\t/**\n\t * Change the default rendered anchor element to the child element, merging props and behavior.\n\t * NavigationMenuLink forwards ref to HTMLAnchorElement and inherits native anchor attributes.\n\t * @default false\n\t */\n\tasChild?: RadixNavigationMenuLinkProps[\"asChild\"];\n}\n\nexport function NavigationMenuLink({ className, ...props }: NavigationMenuLinkProps) {\n\treturn (\n\t\t<NavigationMenuPrimitive.Link\n\t\t\tclassName={cn(\"rounded-basalt-md px-3 py-2 text-sm hover:bg-basalt-accent\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n"],"mappings":";;;;;AA6DA,IAAaC,IAAiBD,EAAwB,MAWzCE,IAAqBF,EAAwB,MAgB7CG,IAAqBH,EAAwB;AAsB1D,SAAgBI,EAAmB,EAAE,cAAW,GAAGC,KAAkC;CACpF,OACC,kBAACL,EAAwB,MAAzB;EACC,WAAWM,EAAG,8DAA8DC,CAAS;EACrF,GAAIF;CACJ,CAAA;AAEH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overlay.js","names":[],"sources":["../../src/components/overlay.ts"],"sourcesContent":["import { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\n\n/** Gap between a field trigger and its list. Matches Kumo Select/Combobox. */\nexport const OVERLAY_GAP = 4;\n/** Gap between a menu trigger and its panel. Matches Kumo Dropdown/Popover. */\nexport const MENU_GAP = 8;\n/** Shared stacking layer for portals, menus, and chrome overlays. */\nexport const OVERLAY_LAYER = \"z-50\";\n/** Kill CSS animation and transition when the user prefers reduced motion. */\nexport const OVERLAY_MOTION = \"motion-reduce:animate-none motion-reduce:transition-none\";\n\n/** Recolor the existing 1px border. No extra ring, no layout shift. */\nexport const FOCUS_BORDER = \"outline-hidden focus-visible:border-basalt-ring\";\n/** Inset 1px theme ring for borderless controls. Outer size stays put. */\nexport const FOCUS_INSET =\n\t\"outline-hidden focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-basalt-ring\";\n/** Offset ring stays visible on primary fills (ring token equals primary). */\nexport const FOCUS_RING =\n\t\"outline-hidden focus-visible:ring-2 focus-visible:ring-basalt-ring focus-visible:ring-offset-2 focus-visible:ring-offset-basalt-background\";\n\nexport function overlayPanelClass(className?: string) {\n\treturn cn(\n\t\tBASALT_UI_CLASS,\n\t\tOVERLAY_LAYER,\n\t\t\"overflow-hidden rounded-basalt-md border border-basalt-border bg-basalt-popover py-1.5 text-sm text-basalt-popover-foreground shadow-md\",\n\t\tOVERLAY_MOTION,\n\t\tclassName,\n\t);\n}\n\nexport function overlayItemClass(className?: string) {\n\treturn cn(\n\t\t\"mx-1.5 flex w-[calc(100%-0.75rem)] cursor-default items-center rounded-basalt-sm px-2 py-1.5 text-left text-sm outline-hidden select-none\",\n\t\tclassName,\n\t);\n}\n"],"mappings":";;;;AAIA,
|
|
1
|
+
{"version":3,"file":"overlay.js","names":["OVERLAY_GAP","MENU_GAP","OVERLAY_LAYER","OVERLAY_MOTION","FOCUS_BORDER","FOCUS_INSET","FOCUS_RING","overlayPanelClass","cn","BASALT_UI_CLASS","className","overlayItemClass"],"sources":["../../src/components/overlay.ts"],"sourcesContent":["import { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\n\n/** Gap between a field trigger and its list. Matches Kumo Select/Combobox. */\nexport const OVERLAY_GAP = 4;\n/** Gap between a menu trigger and its panel. Matches Kumo Dropdown/Popover. */\nexport const MENU_GAP = 8;\n/** Shared stacking layer for portals, menus, and chrome overlays. */\nexport const OVERLAY_LAYER = \"z-50\";\n/** Kill CSS animation and transition when the user prefers reduced motion. */\nexport const OVERLAY_MOTION = \"motion-reduce:animate-none motion-reduce:transition-none\";\n\n/** Recolor the existing 1px border. No extra ring, no layout shift. */\nexport const FOCUS_BORDER = \"outline-hidden focus-visible:border-basalt-ring\";\n/** Inset 1px theme ring for borderless controls. Outer size stays put. */\nexport const FOCUS_INSET =\n\t\"outline-hidden focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-basalt-ring\";\n/** Offset ring stays visible on primary fills (ring token equals primary). */\nexport const FOCUS_RING =\n\t\"outline-hidden focus-visible:ring-2 focus-visible:ring-basalt-ring focus-visible:ring-offset-2 focus-visible:ring-offset-basalt-background\";\n\nexport function overlayPanelClass(className?: string) {\n\treturn cn(\n\t\tBASALT_UI_CLASS,\n\t\tOVERLAY_LAYER,\n\t\t\"overflow-hidden rounded-basalt-md border border-basalt-border bg-basalt-popover py-1.5 text-sm text-basalt-popover-foreground shadow-md\",\n\t\tOVERLAY_MOTION,\n\t\tclassName,\n\t);\n}\n\nexport function overlayItemClass(className?: string) {\n\treturn cn(\n\t\t\"mx-1.5 flex w-[calc(100%-0.75rem)] cursor-default items-center rounded-basalt-sm px-2 py-1.5 text-left text-sm outline-hidden select-none\",\n\t\tclassName,\n\t);\n}\n"],"mappings":";;;;AAIA,IAAaA,IAAc,GAEdC,IAAW,GAEXC,IAAgB,QAEhBC,IAAiB,4DAGjBC,IAAe,mDAEfC,IACZ,+FAEYC,IACZ;AAED,SAAgBC,EAAkB,GAAoB;CACrD,OAAOC,EACNC,GACAP,GACA,2IACAC,GACAO,CACD;AACD;AAEA,SAAgBC,EAAiB,GAAoB;CACpD,OAAOH,EACN,6IACAE,CACD;AACD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page-header.js","names":[],"sources":["../../src/components/page-header.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Breadcrumbs } from \"./breadcrumbs\";\n\nexport interface PageHeaderBreadcrumb {\n\thref?: string;\n\tlabel: React.ReactNode;\n\ticon?: React.ReactNode;\n}\n\nexport interface PageHeaderProps {\n\t/** The page title, rendered as the only heading. */\n\ttitle: React.ReactNode;\n\t/** Supporting text below the title. */\n\tdescription?: React.ReactNode;\n\t/** Trail of parent pages. */\n\tbreadcrumbs?: readonly PageHeaderBreadcrumb[];\n\t/** Right-side title-row actions. Put the create button last. */\n\tactions?: React.ReactNode;\n\t/** Own-row filters. Keep short filters in actions. */\n\tfilters?: React.ReactNode;\n}\n\nexport function PageHeader({ actions, breadcrumbs, description, filters, title }: PageHeaderProps) {\n\tconst titleId = React.useId();\n\n\treturn (\n\t\t// biome-ignore lint/a11y/useAriaPropsSupportedByRole: the title heading names this header\n\t\t<header aria-labelledby={titleId} className={cn(BASALT_UI_CLASS, \"space-y-4\")}>\n\t\t\t{breadcrumbs && breadcrumbs.length > 0 ? <Breadcrumbs items={[...breadcrumbs]} /> : null}\n\t\t\t<div className=\"flex flex-col gap-4 md:flex-row md:items-start md:justify-between\">\n\t\t\t\t<div className=\"min-w-0 flex-1 space-y-1\">\n\t\t\t\t\t<h1 id={titleId} className=\"text-2xl font-semibold tracking-tight text-basalt-foreground\">\n\t\t\t\t\t\t{title}\n\t\t\t\t\t</h1>\n\t\t\t\t\t{description ? (\n\t\t\t\t\t\t<p className=\"text-sm text-basalt-muted-foreground\">{description}</p>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t\t{actions ? (\n\t\t\t\t\t<div className=\"flex flex-wrap items-center justify-end gap-2\">{actions}</div>\n\t\t\t\t) : null}\n\t\t\t</div>\n\t\t\t{filters ? <div className=\"flex flex-wrap items-center gap-2\">{filters}</div> : null}\n\t\t</header>\n\t);\n}\n"],"mappings":";;;;;;;AAwBA,
|
|
1
|
+
{"version":3,"file":"page-header.js","names":["React","PageHeader","titleId","cn","BASALT_UI_CLASS","breadcrumbs","Breadcrumbs","title","description","actions","filters"],"sources":["../../src/components/page-header.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Breadcrumbs } from \"./breadcrumbs\";\n\nexport interface PageHeaderBreadcrumb {\n\thref?: string;\n\tlabel: React.ReactNode;\n\ticon?: React.ReactNode;\n}\n\nexport interface PageHeaderProps {\n\t/** The page title, rendered as the only heading. */\n\ttitle: React.ReactNode;\n\t/** Supporting text below the title. */\n\tdescription?: React.ReactNode;\n\t/** Trail of parent pages. */\n\tbreadcrumbs?: readonly PageHeaderBreadcrumb[];\n\t/** Right-side title-row actions. Put the create button last. */\n\tactions?: React.ReactNode;\n\t/** Own-row filters. Keep short filters in actions. */\n\tfilters?: React.ReactNode;\n}\n\nexport function PageHeader({ actions, breadcrumbs, description, filters, title }: PageHeaderProps) {\n\tconst titleId = React.useId();\n\n\treturn (\n\t\t// biome-ignore lint/a11y/useAriaPropsSupportedByRole: the title heading names this header\n\t\t<header aria-labelledby={titleId} className={cn(BASALT_UI_CLASS, \"space-y-4\")}>\n\t\t\t{breadcrumbs && breadcrumbs.length > 0 ? <Breadcrumbs items={[...breadcrumbs]} /> : null}\n\t\t\t<div className=\"flex flex-col gap-4 md:flex-row md:items-start md:justify-between\">\n\t\t\t\t<div className=\"min-w-0 flex-1 space-y-1\">\n\t\t\t\t\t<h1 id={titleId} className=\"text-2xl font-semibold tracking-tight text-basalt-foreground\">\n\t\t\t\t\t\t{title}\n\t\t\t\t\t</h1>\n\t\t\t\t\t{description ? (\n\t\t\t\t\t\t<p className=\"text-sm text-basalt-muted-foreground\">{description}</p>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t\t{actions ? (\n\t\t\t\t\t<div className=\"flex flex-wrap items-center justify-end gap-2\">{actions}</div>\n\t\t\t\t) : null}\n\t\t\t</div>\n\t\t\t{filters ? <div className=\"flex flex-wrap items-center gap-2\">{filters}</div> : null}\n\t\t</header>\n\t);\n}\n"],"mappings":";;;;;;;AAwBA,SAAgBC,EAAW,EAAE,YAAS,gBAAa,gBAAa,YAAS,YAA0B;CAClG,IAAMC,IAAUF,EAAM,MAAM;CAE5B,OAEC,kBAAC,UAAD;EAAQ,mBAAiBE;EAAS,WAAWC,EAAGC,GAAiB,WAAW;EAA5E,UAAA;GACEC,KAAeA,EAAY,SAAS,IAAI,kBAACC,GAAD,EAAa,OAAO,CAAC,GAAGD,CAAW,EAAI,CAAA,IAAI;GACpF,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACC,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACC,kBAAC,MAAD;MAAI,IAAIH;MAAS,WAAU;MACzB,UAAAK;KACE,CAAA,GACHC,IACA,kBAAC,KAAD;MAAG,WAAU;MAAwC,UAAAA;KAAe,CAAA,IACjE,IACA;IACJ,CAAA,GAAAC,IACA,kBAAC,OAAD;KAAK,WAAU;KAAiD,UAAAA;IAAa,CAAA,IAC1E,IACA;;GACJC,IAAU,kBAAC,OAAD;IAAK,WAAU;IAAqC,UAAAA;GAAa,CAAA,IAAI;EACzE;;AAEV"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pagination.js","names":[],"sources":["../../src/components/pagination.tsx"],"sourcesContent":["import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from \"lucide-react\";\nimport { useState } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { controlSurfaceClass } from \"../utils/control-surface\";\nimport { Button } from \"./button\";\n\nconst itemClass = cn(\n\t\"relative h-full w-9 shrink-0 rounded-none border-0 bg-transparent shadow-none first:rounded-l-basalt-md last:rounded-r-basalt-md\",\n\t\"hover:bg-basalt-accent focus-visible:bg-basalt-accent active:bg-basalt-accent\",\n\t\"disabled:pointer-events-none disabled:opacity-100 disabled:text-basalt-muted-foreground\",\n);\n\nexport type PaginationProps = {\n\t/**\n\t * Controlled 1-based page.\n\t */\n\tpage?: number;\n\t/**\n\t * Uncontrolled initial page.\n\t * @default 1\n\t */\n\tdefaultPage?: number;\n\t/**\n\t * Last page number.\n\t * @default 10\n\t */\n\tpageCount?: number;\n\t/**\n\t * Called when the page changes.\n\t */\n\tonPageChange?: (page: number) => void;\n\t/**\n\t * Hide first, last, and page number controls.\n\t * @default false\n\t */\n\tsimple?: boolean;\n\t/**\n\t * Disable every control.\n\t * @default false\n\t */\n\tdisabled?: boolean;\n\t/**\n\t * Additional classes for the nav.\n\t */\n\tclassName?: string;\n};\n\nexport function Pagination({\n\tpage,\n\tdefaultPage = 1,\n\tpageCount = 10,\n\tonPageChange,\n\tsimple = false,\n\tdisabled = false,\n\tclassName,\n}: PaginationProps) {\n\tconst [uncontrolled, setUncontrolled] = useState(defaultPage);\n\tconst last = Math.max(1, pageCount);\n\tconst current = Math.min(last, Math.max(1, page ?? uncontrolled));\n\tconst go = (next: number) => {\n\t\tif (page === undefined) {\n\t\t\tsetUncontrolled(next);\n\t\t}\n\t\tonPageChange?.(next);\n\t};\n\tconst atStart = current <= 1;\n\tconst atEnd = current >= last;\n\tconst startDisabled = disabled || atStart;\n\tconst endDisabled = disabled || atEnd;\n\n\treturn (\n\t\t<nav aria-label=\"Pagination\" className={className}>\n\t\t\t<div\n\t\t\t\tclassName={controlSurfaceClass(\n\t\t\t\t\tcn(\n\t\t\t\t\t\t\"inline-flex h-9 items-stretch\",\n\t\t\t\t\t\t\"[&>*:not(:first-child)]:border-l [&>*:not(:first-child)]:border-basalt-border\",\n\t\t\t\t\t\t\"[&>:first-child]:rounded-l-basalt-md [&>:last-child]:rounded-r-basalt-md\",\n\t\t\t\t\t),\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t{simple ? null : (\n\t\t\t\t\t<Button\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\ticon={<ChevronsLeft />}\n\t\t\t\t\t\tclassName={itemClass}\n\t\t\t\t\t\taria-label=\"First page\"\n\t\t\t\t\t\tdisabled={startDisabled}\n\t\t\t\t\t\tonClick={() => go(1)}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t<Button\n\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\ticon={<ChevronLeft />}\n\t\t\t\t\tclassName={itemClass}\n\t\t\t\t\taria-label=\"Previous page\"\n\t\t\t\t\tdisabled={startDisabled}\n\t\t\t\t\tonClick={() => go(Math.max(1, current - 1))}\n\t\t\t\t/>\n\t\t\t\t{simple ? null : (\n\t\t\t\t\t<span\n\t\t\t\t\t\taria-current=\"page\"\n\t\t\t\t\t\tclassName=\"flex h-full min-w-9 items-center justify-center px-3 text-sm font-medium tabular-nums text-basalt-foreground\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{current}\n\t\t\t\t\t</span>\n\t\t\t\t)}\n\t\t\t\t<Button\n\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\ticon={<ChevronRight />}\n\t\t\t\t\tclassName={itemClass}\n\t\t\t\t\taria-label=\"Next page\"\n\t\t\t\t\tdisabled={endDisabled}\n\t\t\t\t\tonClick={() => go(Math.min(last, current + 1))}\n\t\t\t\t/>\n\t\t\t\t{simple ? null : (\n\t\t\t\t\t<Button\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\ticon={<ChevronsRight />}\n\t\t\t\t\t\tclassName={itemClass}\n\t\t\t\t\t\taria-label=\"Last page\"\n\t\t\t\t\t\tdisabled={endDisabled}\n\t\t\t\t\t\tonClick={() => go(last)}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</nav>\n\t);\n}\n"],"mappings":";;;;;;;;AAMA,
|
|
1
|
+
{"version":3,"file":"pagination.js","names":["itemClass","cn","Pagination","uncontrolled","setUncontrolled","useState","defaultPage","last","pageCount","current","page","go","next","onPageChange","atStart","atEnd","startDisabled","disabled","endDisabled","controlSurfaceClass","simple","Button","ChevronsLeft","ChevronLeft","ChevronRight","ChevronsRight"],"sources":["../../src/components/pagination.tsx"],"sourcesContent":["import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from \"lucide-react\";\nimport { useState } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { controlSurfaceClass } from \"../utils/control-surface\";\nimport { Button } from \"./button\";\n\nconst itemClass = cn(\n\t\"relative h-full w-9 shrink-0 rounded-none border-0 bg-transparent shadow-none first:rounded-l-basalt-md last:rounded-r-basalt-md\",\n\t\"hover:bg-basalt-accent focus-visible:bg-basalt-accent active:bg-basalt-accent\",\n\t\"disabled:pointer-events-none disabled:opacity-100 disabled:text-basalt-muted-foreground\",\n);\n\nexport type PaginationProps = {\n\t/**\n\t * Controlled 1-based page.\n\t */\n\tpage?: number;\n\t/**\n\t * Uncontrolled initial page.\n\t * @default 1\n\t */\n\tdefaultPage?: number;\n\t/**\n\t * Last page number.\n\t * @default 10\n\t */\n\tpageCount?: number;\n\t/**\n\t * Called when the page changes.\n\t */\n\tonPageChange?: (page: number) => void;\n\t/**\n\t * Hide first, last, and page number controls.\n\t * @default false\n\t */\n\tsimple?: boolean;\n\t/**\n\t * Disable every control.\n\t * @default false\n\t */\n\tdisabled?: boolean;\n\t/**\n\t * Additional classes for the nav.\n\t */\n\tclassName?: string;\n};\n\nexport function Pagination({\n\tpage,\n\tdefaultPage = 1,\n\tpageCount = 10,\n\tonPageChange,\n\tsimple = false,\n\tdisabled = false,\n\tclassName,\n}: PaginationProps) {\n\tconst [uncontrolled, setUncontrolled] = useState(defaultPage);\n\tconst last = Math.max(1, pageCount);\n\tconst current = Math.min(last, Math.max(1, page ?? uncontrolled));\n\tconst go = (next: number) => {\n\t\tif (page === undefined) {\n\t\t\tsetUncontrolled(next);\n\t\t}\n\t\tonPageChange?.(next);\n\t};\n\tconst atStart = current <= 1;\n\tconst atEnd = current >= last;\n\tconst startDisabled = disabled || atStart;\n\tconst endDisabled = disabled || atEnd;\n\n\treturn (\n\t\t<nav aria-label=\"Pagination\" className={className}>\n\t\t\t<div\n\t\t\t\tclassName={controlSurfaceClass(\n\t\t\t\t\tcn(\n\t\t\t\t\t\t\"inline-flex h-9 items-stretch\",\n\t\t\t\t\t\t\"[&>*:not(:first-child)]:border-l [&>*:not(:first-child)]:border-basalt-border\",\n\t\t\t\t\t\t\"[&>:first-child]:rounded-l-basalt-md [&>:last-child]:rounded-r-basalt-md\",\n\t\t\t\t\t),\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t{simple ? null : (\n\t\t\t\t\t<Button\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\ticon={<ChevronsLeft />}\n\t\t\t\t\t\tclassName={itemClass}\n\t\t\t\t\t\taria-label=\"First page\"\n\t\t\t\t\t\tdisabled={startDisabled}\n\t\t\t\t\t\tonClick={() => go(1)}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t<Button\n\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\ticon={<ChevronLeft />}\n\t\t\t\t\tclassName={itemClass}\n\t\t\t\t\taria-label=\"Previous page\"\n\t\t\t\t\tdisabled={startDisabled}\n\t\t\t\t\tonClick={() => go(Math.max(1, current - 1))}\n\t\t\t\t/>\n\t\t\t\t{simple ? null : (\n\t\t\t\t\t<span\n\t\t\t\t\t\taria-current=\"page\"\n\t\t\t\t\t\tclassName=\"flex h-full min-w-9 items-center justify-center px-3 text-sm font-medium tabular-nums text-basalt-foreground\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{current}\n\t\t\t\t\t</span>\n\t\t\t\t)}\n\t\t\t\t<Button\n\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\ticon={<ChevronRight />}\n\t\t\t\t\tclassName={itemClass}\n\t\t\t\t\taria-label=\"Next page\"\n\t\t\t\t\tdisabled={endDisabled}\n\t\t\t\t\tonClick={() => go(Math.min(last, current + 1))}\n\t\t\t\t/>\n\t\t\t\t{simple ? null : (\n\t\t\t\t\t<Button\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\t\ticon={<ChevronsRight />}\n\t\t\t\t\t\tclassName={itemClass}\n\t\t\t\t\t\taria-label=\"Last page\"\n\t\t\t\t\t\tdisabled={endDisabled}\n\t\t\t\t\t\tonClick={() => go(last)}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</nav>\n\t);\n}\n"],"mappings":";;;;;;;;AAMA,IAAMA,IAAYC,EACjB,oIACA,iFACA,yFACD;AAqCA,SAAgBC,EAAW,EAC1B,SACA,iBAAc,GACd,eAAY,IACZ,iBACA,YAAS,IACT,cAAW,IACX,gBACmB;CACnB,IAAM,CAACC,GAAcC,KAAmBC,EAASC,CAAW,GACtDC,IAAO,KAAK,IAAI,GAAGC,CAAS,GAC5BC,IAAU,KAAK,IAAIF,GAAM,KAAK,IAAI,GAAGG,KAAQP,CAAY,CAAC,GAC1DQ,KAAM,MAAiB;EAI5B,AAHID,MAAS,KAAA,KACZN,EAAgBQ,CAAI,GAErBC,IAAeD,CAAI;CACpB,GACME,IAAUL,KAAW,GACrBM,IAAQN,KAAWF,GACnBS,IAAgBC,KAAYH,GAC5BI,IAAcD,KAAYF;CAEhC,OACC,kBAAC,OAAD;EAAK,cAAW;EAAwB;EACvC,UAAA,kBAAC,OAAD;GACC,WAAWI,EACVlB,EACC,iCACA,iFACA,0EACD,CACD;GAPD,UAAA;IASEmB,IAAS,OACT,kBAACC,GAAD;KACC,SAAQ;KACR,MAAK;KACL,MAAM,kBAACC,GAAD,CAAe,CAAA;KACrB,WAAWtB;KACX,cAAW;KACX,UAAUgB;KACV,eAAeL,EAAG,CAAC;IACnB,CAAA;IAEF,kBAACU,GAAD;KACC,SAAQ;KACR,MAAK;KACL,MAAM,kBAACE,GAAD,CAAc,CAAA;KACpB,WAAWvB;KACX,cAAW;KACX,UAAUgB;KACV,eAAeL,EAAG,KAAK,IAAI,GAAGF,IAAU,CAAC,CAAC;IAC1C,CAAA;IACAW,IAAS,OACT,kBAAC,QAAD;KACC,gBAAa;KACb,WAAU;KAET,UAAAX;IACI,CAAA;IAEP,kBAACY,GAAD;KACC,SAAQ;KACR,MAAK;KACL,MAAM,kBAACG,GAAD,CAAe,CAAA;KACrB,WAAWxB;KACX,cAAW;KACX,UAAUkB;KACV,eAAeP,EAAG,KAAK,IAAIJ,GAAME,IAAU,CAAC,CAAC;IAC7C,CAAA;IACAW,IAAS,OACT,kBAACC,GAAD;KACC,SAAQ;KACR,MAAK;KACL,MAAM,kBAACI,GAAD,CAAgB,CAAA;KACtB,WAAWzB;KACX,cAAW;KACX,UAAUkB;KACV,eAAeP,EAAGJ,CAAI;IACtB,CAAA;GAEE;;CACD,CAAA;AAEP"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"popover.js","names":[],"sources":["../../src/components/popover.tsx"],"sourcesContent":["import * as PopoverPrimitive from \"@radix-ui/react-popover\";\nimport { Slottable } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { MENU_GAP, OVERLAY_LAYER, OVERLAY_MOTION } from \"./overlay\";\n\nexport const POPOVER_SIDES = [\"top\", \"bottom\", \"left\", \"right\"] as const;\nexport type PopoverSide = (typeof POPOVER_SIDES)[number];\n\ntype RadixPopoverProps = React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Root>;\ntype RadixPopoverTriggerProps = React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Trigger>;\ntype RadixPopoverCloseProps = React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Close>;\ntype RadixPopoverContentProps = React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>;\n\nexport interface PopoverProps\n\textends Omit<RadixPopoverProps, \"children\" | \"open\" | \"defaultOpen\" | \"onOpenChange\" | \"modal\"> {\n\t/**\n\t * Popover structure elements, typically PopoverTrigger and PopoverContent.\n\t */\n\tchildren?: React.ReactNode;\n\t/**\n\t * Controlled open state of the popover.\n\t */\n\topen?: RadixPopoverProps[\"open\"];\n\t/**\n\t * Uncontrolled initial open state of the popover.\n\t * @default false\n\t */\n\tdefaultOpen?: RadixPopoverProps[\"defaultOpen\"];\n\t/**\n\t * Callback called when the open state changes.\n\t */\n\tonOpenChange?: RadixPopoverProps[\"onOpenChange\"];\n\t/**\n\t * Whether the popover renders modally, preventing outside interaction and hiding background content from screen readers.\n\t * @default false\n\t */\n\tmodal?: RadixPopoverProps[\"modal\"];\n}\n\nexport const Popover: React.FC<PopoverProps> = PopoverPrimitive.Root;\n\nexport interface PopoverTriggerProps extends Omit<RadixPopoverTriggerProps, \"asChild\"> {\n\t/**\n\t * Change the default rendered button element to the child element, merging props and behavior.\n\t * PopoverTrigger forwards ref to HTMLButtonElement and inherits native button attributes.\n\t * @default false\n\t */\n\tasChild?: RadixPopoverTriggerProps[\"asChild\"];\n}\n\nexport const PopoverTrigger = PopoverPrimitive.Trigger;\n\nexport interface PopoverCloseProps extends Omit<RadixPopoverCloseProps, \"asChild\"> {\n\t/**\n\t * Change the default rendered button element to the child element, merging props and behavior.\n\t * PopoverClose forwards ref to HTMLButtonElement and inherits native button attributes.\n\t * @default false\n\t */\n\tasChild?: RadixPopoverCloseProps[\"asChild\"];\n}\n\nexport const PopoverClose = PopoverPrimitive.Close;\n\nexport interface PopoverContentProps\n\textends Omit<\n\t\tRadixPopoverContentProps,\n\t\t| \"side\"\n\t\t| \"sideOffset\"\n\t\t| \"align\"\n\t\t| \"alignOffset\"\n\t\t| \"avoidCollisions\"\n\t\t| \"collisionBoundary\"\n\t\t| \"collisionPadding\"\n\t\t| \"arrowPadding\"\n\t\t| \"sticky\"\n\t\t| \"hideWhenDetached\"\n\t\t| \"updatePositionStrategy\"\n\t\t| \"forceMount\"\n\t\t| \"asChild\"\n\t\t| \"onOpenAutoFocus\"\n\t\t| \"onCloseAutoFocus\"\n\t\t| \"onEscapeKeyDown\"\n\t\t| \"onPointerDownOutside\"\n\t\t| \"onFocusOutside\"\n\t\t| \"onInteractOutside\"\n\t> {\n\t/**\n\t * Preferred placement side relative to trigger.\n\t * @default \"bottom\"\n\t */\n\tside?: RadixPopoverContentProps[\"side\"];\n\t/**\n\t * Distance in pixels between trigger and floating content panel.\n\t * @default 8\n\t */\n\tsideOffset?: RadixPopoverContentProps[\"sideOffset\"];\n\t/**\n\t * Preferred alignment along the side axis.\n\t * @default \"center\"\n\t */\n\talign?: RadixPopoverContentProps[\"align\"];\n\t/**\n\t * Offset in pixels from the start or end alignment position.\n\t * @default 0\n\t */\n\talignOffset?: RadixPopoverContentProps[\"alignOffset\"];\n\t/**\n\t * Whether to reposition content to avoid viewport boundary collisions.\n\t * @default true\n\t */\n\tavoidCollisions?: RadixPopoverContentProps[\"avoidCollisions\"];\n\t/**\n\t * Element or elements bounding boundary collision calculations.\n\t * @default []\n\t */\n\tcollisionBoundary?: RadixPopoverContentProps[\"collisionBoundary\"];\n\t/**\n\t * Virtual padding from collision boundaries in pixels.\n\t * @default 0\n\t */\n\tcollisionPadding?: RadixPopoverContentProps[\"collisionPadding\"];\n\t/**\n\t * Padding in pixels between popper arrow and floating panel edge.\n\t * @default 0\n\t */\n\tarrowPadding?: RadixPopoverContentProps[\"arrowPadding\"];\n\t/**\n\t * Sticky positioning behavior along the align axis when overflowing.\n\t * @default \"partial\"\n\t */\n\tsticky?: RadixPopoverContentProps[\"sticky\"];\n\t/**\n\t * Whether to hide content completely when trigger is fully occluded.\n\t * @default false\n\t */\n\thideWhenDetached?: RadixPopoverContentProps[\"hideWhenDetached\"];\n\t/**\n\t * Strategy used to calculate and update popper position.\n\t * @default \"optimized\"\n\t */\n\tupdatePositionStrategy?: RadixPopoverContentProps[\"updatePositionStrategy\"];\n\t/**\n\t * Force mounting content in DOM for external animation controls.\n\t * When forceMount is true, the content remains mounted even when closed.\n\t * The caller is responsible for visibility transitions and unmounting after animation completes.\n\t * Note: Keeping modal content forceMounted may isolate background interactions until unmounted.\n\t */\n\tforceMount?: true;\n\t/**\n\t * Change the default rendered div element to the child element, merging props and behavior.\n\t * PopoverContent forwards ref to HTMLDivElement and inherits native div attributes.\n\t * @default false\n\t */\n\tasChild?: RadixPopoverContentProps[\"asChild\"];\n\t/**\n\t * Callback fired when auto-focusing on open. Can be prevented.\n\t */\n\tonOpenAutoFocus?: RadixPopoverContentProps[\"onOpenAutoFocus\"];\n\t/**\n\t * Callback fired when auto-focusing on close. Can be prevented.\n\t */\n\tonCloseAutoFocus?: RadixPopoverContentProps[\"onCloseAutoFocus\"];\n\t/**\n\t * Callback fired when the Escape key is down on the dismissable layer. Can be prevented.\n\t */\n\tonEscapeKeyDown?: RadixPopoverContentProps[\"onEscapeKeyDown\"];\n\t/**\n\t * Callback fired when a pointerdown event happens outside the bounds of the dismissable layer. Can be prevented.\n\t */\n\tonPointerDownOutside?: RadixPopoverContentProps[\"onPointerDownOutside\"];\n\t/**\n\t * Callback fired when focus moves outside the bounds of the dismissable layer. Can be prevented.\n\t */\n\tonFocusOutside?: RadixPopoverContentProps[\"onFocusOutside\"];\n\t/**\n\t * Callback fired when an interaction (pointerdown or focus) happens outside the bounds of the dismissable layer. Can be prevented.\n\t */\n\tonInteractOutside?: RadixPopoverContentProps[\"onInteractOutside\"];\n\t/**\n\t * Show the pointing arrow.\n\t * @default true\n\t */\n\tarrow?: boolean;\n}\n\nexport const PopoverContent = React.forwardRef<\n\tReact.ElementRef<typeof PopoverPrimitive.Content>,\n\tPopoverContentProps\n>(\n\t(\n\t\t{\n\t\t\tclassName,\n\t\t\talign = \"center\",\n\t\t\tside = \"bottom\",\n\t\t\tsideOffset = MENU_GAP,\n\t\t\tarrow = true,\n\t\t\tchildren,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => (\n\t\t<PopoverPrimitive.Portal forceMount={props.forceMount}>\n\t\t\t<PopoverPrimitive.Content\n\t\t\t\tref={ref}\n\t\t\t\talign={align}\n\t\t\t\tside={side}\n\t\t\t\tsideOffset={sideOffset}\n\t\t\t\tclassName={cn(\n\t\t\t\t\tOVERLAY_LAYER,\n\t\t\t\t\tOVERLAY_MOTION,\n\t\t\t\t\t\"rounded-basalt-md border border-basalt-border bg-basalt-popover px-4 py-3 text-sm text-basalt-popover-foreground shadow-md outline-hidden\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<Slottable>{children}</Slottable>\n\t\t\t\t{arrow ? (\n\t\t\t\t\t<PopoverPrimitive.Arrow asChild width={20} height={10}>\n\t\t\t\t\t\t<ArrowSvg />\n\t\t\t\t\t</PopoverPrimitive.Arrow>\n\t\t\t\t) : null}\n\t\t\t</PopoverPrimitive.Content>\n\t\t</PopoverPrimitive.Portal>\n\t),\n);\nPopoverContent.displayName = PopoverPrimitive.Content.displayName;\n\nexport interface PopoverTitleProps extends React.HTMLAttributes<HTMLHeadingElement> {}\n\nexport const PopoverTitle = React.forwardRef<HTMLHeadingElement, PopoverTitleProps>(\n\t({ className, ...props }, ref) => (\n\t\t<h2\n\t\t\tref={ref}\n\t\t\tclassName={cn(\"m-0 text-base font-medium leading-6 text-basalt-foreground\", className)}\n\t\t\t{...props}\n\t\t/>\n\t),\n);\nPopoverTitle.displayName = \"PopoverTitle\";\n\nexport interface PopoverDescriptionProps extends React.HTMLAttributes<HTMLParagraphElement> {}\n\nexport const PopoverDescription = React.forwardRef<HTMLParagraphElement, PopoverDescriptionProps>(\n\t({ className, ...props }, ref) => (\n\t\t<p\n\t\t\tref={ref}\n\t\t\tclassName={cn(\"m-0 text-base leading-6 text-basalt-muted-foreground\", className)}\n\t\t\t{...props}\n\t\t/>\n\t),\n);\nPopoverDescription.displayName = \"PopoverDescription\";\n\nfunction ArrowSvg(props: React.ComponentProps<\"svg\">) {\n\treturn (\n\t\t<svg width={20} height={10} aria-hidden {...props}>\n\t\t\t<svg width=\"100%\" height=\"100%\" viewBox=\"0 0 20 10\" preserveAspectRatio=\"none\" aria-hidden>\n\t\t\t\t<path\n\t\t\t\t\td=\"M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z\"\n\t\t\t\t\tclassName=\"fill-basalt-popover\"\n\t\t\t\t/>\n\t\t\t\t<path\n\t\t\t\t\td=\"M8.99542 1.85876C9.75604 1.17425 10.9106 1.17422 11.6713 1.85878L16.5281 6.22989C17.0789 6.72568 17.7938 7.00001 18.5349 7.00001L15.89 7L11.0023 2.60207C10.622 2.2598 10.0447 2.2598 9.66436 2.60207L4.77734 7L2.13171 7.00001C2.87284 7.00001 3.58774 6.72568 4.13861 6.22989L8.99542 1.85876Z\"\n\t\t\t\t\tclassName=\"fill-basalt-border\"\n\t\t\t\t/>\n\t\t\t</svg>\n\t\t</svg>\n\t);\n}\n"],"mappings":";;;;;;;;AAMA,IAAa,IAAgB;CAAC;CAAO;CAAU;CAAQ;AAAO,GAkCjD,IAAkC,EAAiB,MAWnD,IAAiB,EAAiB,SAWlC,IAAe,EAAiB,OA4HhC,IAAiB,EAAM,YAKlC,EACC,cACA,WAAQ,UACR,UAAO,UACP,gBAAA,GACA,WAAQ,IACR,aACA,GAAG,KAEJ,MAEA,kBAAC,EAAiB,QAAlB;CAAyB,YAAY,EAAM;CAC1C,UAAA,kBAAC,EAAiB,SAAlB;EACM;EACE;EACD;EACM;EACZ,WAAW,EACV,GACA,GACA,6IACA,CACD;EACA,GAAI;EAXL,UAAA,CAaC,kBAAC,GAAD,EAAY,YAAoB,CAAA,GAC/B,IACA,kBAAC,EAAiB,OAAlB;GAAwB,SAAA;GAAQ,OAAO;GAAI,QAAQ;GAClD,UAAA,kBAAC,GAAD,CAAW,CAAA;EACY,CAAA,IACrB,IACqB;;AACF,CAAA,CAE3B;AACA,EAAe,cAAc,EAAiB,QAAQ;AAItD,IAAa,IAAe,EAAM,YAChC,EAAE,cAAW,GAAG,KAAS,MACzB,kBAAC,MAAD;CACM;CACL,WAAW,EAAG,8DAA8D,CAAS;CACrF,GAAI;AACJ,CAAA,CAEH;AACA,EAAa,cAAc;AAI3B,IAAa,IAAqB,EAAM,YACtC,EAAE,cAAW,GAAG,KAAS,MACzB,kBAAC,KAAD;CACM;CACL,WAAW,EAAG,wDAAwD,CAAS;CAC/E,GAAI;AACJ,CAAA,CAEH;AACA,EAAmB,cAAc;AAEjC,SAAS,EAAS,GAAoC;CACrD,OACC,kBAAC,OAAD;EAAK,OAAO;EAAI,QAAQ;EAAI,eAAA;EAAY,GAAI;EAC3C,UAAA,kBAAC,OAAD;GAAK,OAAM;GAAO,QAAO;GAAO,SAAQ;GAAY,qBAAoB;GAAO,eAAA;GAA/E,UAAA,CACC,kBAAC,QAAD;IACC,GAAE;IACF,WAAU;GACV,CAAA,GACD,kBAAC,QAAD;IACC,GAAE;IACF,WAAU;GACV,CAAA,CACG;;CACD,CAAA;AAEP"}
|
|
1
|
+
{"version":3,"file":"popover.js","names":["React","PopoverPrimitive","POPOVER_SIDES","Popover","PopoverTrigger","PopoverClose","PopoverContent","props","cn","OVERLAY_LAYER","OVERLAY_MOTION","className","Slottable","arrow","ArrowSvg","PopoverTitle","PopoverDescription"],"sources":["../../src/components/popover.tsx"],"sourcesContent":["import * as PopoverPrimitive from \"@radix-ui/react-popover\";\nimport { Slottable } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { MENU_GAP, OVERLAY_LAYER, OVERLAY_MOTION } from \"./overlay\";\n\nexport const POPOVER_SIDES = [\"top\", \"bottom\", \"left\", \"right\"] as const;\nexport type PopoverSide = (typeof POPOVER_SIDES)[number];\n\ntype RadixPopoverProps = React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Root>;\ntype RadixPopoverTriggerProps = React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Trigger>;\ntype RadixPopoverCloseProps = React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Close>;\ntype RadixPopoverContentProps = React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>;\n\nexport interface PopoverProps\n\textends Omit<RadixPopoverProps, \"children\" | \"open\" | \"defaultOpen\" | \"onOpenChange\" | \"modal\"> {\n\t/**\n\t * Popover structure elements, typically PopoverTrigger and PopoverContent.\n\t */\n\tchildren?: React.ReactNode;\n\t/**\n\t * Controlled open state of the popover.\n\t */\n\topen?: RadixPopoverProps[\"open\"];\n\t/**\n\t * Uncontrolled initial open state of the popover.\n\t * @default false\n\t */\n\tdefaultOpen?: RadixPopoverProps[\"defaultOpen\"];\n\t/**\n\t * Callback called when the open state changes.\n\t */\n\tonOpenChange?: RadixPopoverProps[\"onOpenChange\"];\n\t/**\n\t * Whether the popover renders modally, preventing outside interaction and hiding background content from screen readers.\n\t * @default false\n\t */\n\tmodal?: RadixPopoverProps[\"modal\"];\n}\n\nexport const Popover: React.FC<PopoverProps> = PopoverPrimitive.Root;\n\nexport interface PopoverTriggerProps extends Omit<RadixPopoverTriggerProps, \"asChild\"> {\n\t/**\n\t * Change the default rendered button element to the child element, merging props and behavior.\n\t * PopoverTrigger forwards ref to HTMLButtonElement and inherits native button attributes.\n\t * @default false\n\t */\n\tasChild?: RadixPopoverTriggerProps[\"asChild\"];\n}\n\nexport const PopoverTrigger = PopoverPrimitive.Trigger;\n\nexport interface PopoverCloseProps extends Omit<RadixPopoverCloseProps, \"asChild\"> {\n\t/**\n\t * Change the default rendered button element to the child element, merging props and behavior.\n\t * PopoverClose forwards ref to HTMLButtonElement and inherits native button attributes.\n\t * @default false\n\t */\n\tasChild?: RadixPopoverCloseProps[\"asChild\"];\n}\n\nexport const PopoverClose = PopoverPrimitive.Close;\n\nexport interface PopoverContentProps\n\textends Omit<\n\t\tRadixPopoverContentProps,\n\t\t| \"side\"\n\t\t| \"sideOffset\"\n\t\t| \"align\"\n\t\t| \"alignOffset\"\n\t\t| \"avoidCollisions\"\n\t\t| \"collisionBoundary\"\n\t\t| \"collisionPadding\"\n\t\t| \"arrowPadding\"\n\t\t| \"sticky\"\n\t\t| \"hideWhenDetached\"\n\t\t| \"updatePositionStrategy\"\n\t\t| \"forceMount\"\n\t\t| \"asChild\"\n\t\t| \"onOpenAutoFocus\"\n\t\t| \"onCloseAutoFocus\"\n\t\t| \"onEscapeKeyDown\"\n\t\t| \"onPointerDownOutside\"\n\t\t| \"onFocusOutside\"\n\t\t| \"onInteractOutside\"\n\t> {\n\t/**\n\t * Preferred placement side relative to trigger.\n\t * @default \"bottom\"\n\t */\n\tside?: RadixPopoverContentProps[\"side\"];\n\t/**\n\t * Distance in pixels between trigger and floating content panel.\n\t * @default 8\n\t */\n\tsideOffset?: RadixPopoverContentProps[\"sideOffset\"];\n\t/**\n\t * Preferred alignment along the side axis.\n\t * @default \"center\"\n\t */\n\talign?: RadixPopoverContentProps[\"align\"];\n\t/**\n\t * Offset in pixels from the start or end alignment position.\n\t * @default 0\n\t */\n\talignOffset?: RadixPopoverContentProps[\"alignOffset\"];\n\t/**\n\t * Whether to reposition content to avoid viewport boundary collisions.\n\t * @default true\n\t */\n\tavoidCollisions?: RadixPopoverContentProps[\"avoidCollisions\"];\n\t/**\n\t * Element or elements bounding boundary collision calculations.\n\t * @default []\n\t */\n\tcollisionBoundary?: RadixPopoverContentProps[\"collisionBoundary\"];\n\t/**\n\t * Virtual padding from collision boundaries in pixels.\n\t * @default 0\n\t */\n\tcollisionPadding?: RadixPopoverContentProps[\"collisionPadding\"];\n\t/**\n\t * Padding in pixels between popper arrow and floating panel edge.\n\t * @default 0\n\t */\n\tarrowPadding?: RadixPopoverContentProps[\"arrowPadding\"];\n\t/**\n\t * Sticky positioning behavior along the align axis when overflowing.\n\t * @default \"partial\"\n\t */\n\tsticky?: RadixPopoverContentProps[\"sticky\"];\n\t/**\n\t * Whether to hide content completely when trigger is fully occluded.\n\t * @default false\n\t */\n\thideWhenDetached?: RadixPopoverContentProps[\"hideWhenDetached\"];\n\t/**\n\t * Strategy used to calculate and update popper position.\n\t * @default \"optimized\"\n\t */\n\tupdatePositionStrategy?: RadixPopoverContentProps[\"updatePositionStrategy\"];\n\t/**\n\t * Force mounting content in DOM for external animation controls.\n\t * When forceMount is true, the content remains mounted even when closed.\n\t * The caller is responsible for visibility transitions and unmounting after animation completes.\n\t * Note: Keeping modal content forceMounted may isolate background interactions until unmounted.\n\t */\n\tforceMount?: true;\n\t/**\n\t * Change the default rendered div element to the child element, merging props and behavior.\n\t * PopoverContent forwards ref to HTMLDivElement and inherits native div attributes.\n\t * @default false\n\t */\n\tasChild?: RadixPopoverContentProps[\"asChild\"];\n\t/**\n\t * Callback fired when auto-focusing on open. Can be prevented.\n\t */\n\tonOpenAutoFocus?: RadixPopoverContentProps[\"onOpenAutoFocus\"];\n\t/**\n\t * Callback fired when auto-focusing on close. Can be prevented.\n\t */\n\tonCloseAutoFocus?: RadixPopoverContentProps[\"onCloseAutoFocus\"];\n\t/**\n\t * Callback fired when the Escape key is down on the dismissable layer. Can be prevented.\n\t */\n\tonEscapeKeyDown?: RadixPopoverContentProps[\"onEscapeKeyDown\"];\n\t/**\n\t * Callback fired when a pointerdown event happens outside the bounds of the dismissable layer. Can be prevented.\n\t */\n\tonPointerDownOutside?: RadixPopoverContentProps[\"onPointerDownOutside\"];\n\t/**\n\t * Callback fired when focus moves outside the bounds of the dismissable layer. Can be prevented.\n\t */\n\tonFocusOutside?: RadixPopoverContentProps[\"onFocusOutside\"];\n\t/**\n\t * Callback fired when an interaction (pointerdown or focus) happens outside the bounds of the dismissable layer. Can be prevented.\n\t */\n\tonInteractOutside?: RadixPopoverContentProps[\"onInteractOutside\"];\n\t/**\n\t * Show the pointing arrow.\n\t * @default true\n\t */\n\tarrow?: boolean;\n}\n\nexport const PopoverContent = React.forwardRef<\n\tReact.ElementRef<typeof PopoverPrimitive.Content>,\n\tPopoverContentProps\n>(\n\t(\n\t\t{\n\t\t\tclassName,\n\t\t\talign = \"center\",\n\t\t\tside = \"bottom\",\n\t\t\tsideOffset = MENU_GAP,\n\t\t\tarrow = true,\n\t\t\tchildren,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => (\n\t\t<PopoverPrimitive.Portal forceMount={props.forceMount}>\n\t\t\t<PopoverPrimitive.Content\n\t\t\t\tref={ref}\n\t\t\t\talign={align}\n\t\t\t\tside={side}\n\t\t\t\tsideOffset={sideOffset}\n\t\t\t\tclassName={cn(\n\t\t\t\t\tOVERLAY_LAYER,\n\t\t\t\t\tOVERLAY_MOTION,\n\t\t\t\t\t\"rounded-basalt-md border border-basalt-border bg-basalt-popover px-4 py-3 text-sm text-basalt-popover-foreground shadow-md outline-hidden\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<Slottable>{children}</Slottable>\n\t\t\t\t{arrow ? (\n\t\t\t\t\t<PopoverPrimitive.Arrow asChild width={20} height={10}>\n\t\t\t\t\t\t<ArrowSvg />\n\t\t\t\t\t</PopoverPrimitive.Arrow>\n\t\t\t\t) : null}\n\t\t\t</PopoverPrimitive.Content>\n\t\t</PopoverPrimitive.Portal>\n\t),\n);\nPopoverContent.displayName = PopoverPrimitive.Content.displayName;\n\nexport interface PopoverTitleProps extends React.HTMLAttributes<HTMLHeadingElement> {}\n\nexport const PopoverTitle = React.forwardRef<HTMLHeadingElement, PopoverTitleProps>(\n\t({ className, ...props }, ref) => (\n\t\t<h2\n\t\t\tref={ref}\n\t\t\tclassName={cn(\"m-0 text-base font-medium leading-6 text-basalt-foreground\", className)}\n\t\t\t{...props}\n\t\t/>\n\t),\n);\nPopoverTitle.displayName = \"PopoverTitle\";\n\nexport interface PopoverDescriptionProps extends React.HTMLAttributes<HTMLParagraphElement> {}\n\nexport const PopoverDescription = React.forwardRef<HTMLParagraphElement, PopoverDescriptionProps>(\n\t({ className, ...props }, ref) => (\n\t\t<p\n\t\t\tref={ref}\n\t\t\tclassName={cn(\"m-0 text-base leading-6 text-basalt-muted-foreground\", className)}\n\t\t\t{...props}\n\t\t/>\n\t),\n);\nPopoverDescription.displayName = \"PopoverDescription\";\n\nfunction ArrowSvg(props: React.ComponentProps<\"svg\">) {\n\treturn (\n\t\t<svg width={20} height={10} aria-hidden {...props}>\n\t\t\t<svg width=\"100%\" height=\"100%\" viewBox=\"0 0 20 10\" preserveAspectRatio=\"none\" aria-hidden>\n\t\t\t\t<path\n\t\t\t\t\td=\"M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z\"\n\t\t\t\t\tclassName=\"fill-basalt-popover\"\n\t\t\t\t/>\n\t\t\t\t<path\n\t\t\t\t\td=\"M8.99542 1.85876C9.75604 1.17425 10.9106 1.17422 11.6713 1.85878L16.5281 6.22989C17.0789 6.72568 17.7938 7.00001 18.5349 7.00001L15.89 7L11.0023 2.60207C10.622 2.2598 10.0447 2.2598 9.66436 2.60207L4.77734 7L2.13171 7.00001C2.87284 7.00001 3.58774 6.72568 4.13861 6.22989L8.99542 1.85876Z\"\n\t\t\t\t\tclassName=\"fill-basalt-border\"\n\t\t\t\t/>\n\t\t\t</svg>\n\t\t</svg>\n\t);\n}\n"],"mappings":";;;;;;;;AAMA,IAAaE,IAAgB;CAAC;CAAO;CAAU;CAAQ;AAAO,GAkCjDC,IAAkCF,EAAiB,MAWnDG,IAAiBH,EAAiB,SAWlCI,IAAeJ,EAAiB,OA4HhCK,IAAiBN,EAAM,YAKlC,EACC,cACA,WAAQ,UACR,UAAO,UACP,gBAAA,GACA,WAAQ,IACR,aACA,GAAGO,KAEJ,MAEA,kBAACN,EAAiB,QAAlB;CAAyB,YAAYM,EAAM;CAC1C,UAAA,kBAACN,EAAiB,SAAlB;EACM;EACE;EACD;EACM;EACZ,WAAWO,EACVC,GACAC,GACA,6IACAC,CACD;EACA,GAAIJ;EAXL,UAAA,CAaC,kBAACK,GAAD,EAAY,YAAoB,CAAA,GAC/BC,IACA,kBAACZ,EAAiB,OAAlB;GAAwB,SAAA;GAAQ,OAAO;GAAI,QAAQ;GAClD,UAAA,kBAACa,GAAD,CAAW,CAAA;EACY,CAAA,IACrB,IACqB;;AACF,CAAA,CAE3B;AACA,EAAe,cAAcb,EAAiB,QAAQ;AAItD,IAAac,IAAef,EAAM,YAChC,EAAE,cAAW,GAAGO,KAAS,MACzB,kBAAC,MAAD;CACM;CACL,WAAWC,EAAG,8DAA8DG,CAAS;CACrF,GAAIJ;AACJ,CAAA,CAEH;AACA,EAAa,cAAc;AAI3B,IAAaS,IAAqBhB,EAAM,YACtC,EAAE,cAAW,GAAGO,KAAS,MACzB,kBAAC,KAAD;CACM;CACL,WAAWC,EAAG,wDAAwDG,CAAS;CAC/E,GAAIJ;AACJ,CAAA,CAEH;AACA,EAAmB,cAAc;AAEjC,SAASO,EAAS,GAAoC;CACrD,OACC,kBAAC,OAAD;EAAK,OAAO;EAAI,QAAQ;EAAI,eAAA;EAAY,GAAIP;EAC3C,UAAA,kBAAC,OAAD;GAAK,OAAM;GAAO,QAAO;GAAO,SAAQ;GAAY,qBAAoB;GAAO,eAAA;GAA/E,UAAA,CACC,kBAAC,QAAD;IACC,GAAE;IACF,WAAU;GACV,CAAA,GACD,kBAAC,QAAD;IACC,GAAE;IACF,WAAU;GACV,CAAA,CACG;;CACD,CAAA;AAEP"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radio.js","names":[],"sources":["../../src/components/radio.tsx"],"sourcesContent":["import * as RadioGroupPrimitive from \"@radix-ui/react-radio-group\";\nimport { Circle } from \"lucide-react\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { FOCUS_RING } from \"./overlay\";\n\nexport type RadioSize = \"sm\" | \"default\";\n\nconst RADIO_SIZE_CLASS: Record<RadioSize, string> = {\n\tsm: \"h-3 w-3\",\n\tdefault: \"h-4 w-4\",\n};\n\nconst RADIO_INDICATOR_CLASS: Record<RadioSize, string> = {\n\tsm: \"h-1.5 w-1.5 fill-current text-current\",\n\tdefault: \"h-2.5 w-2.5 fill-current text-current\",\n};\n\nexport type RadioGroupProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>,\n\t\"disabled\" | \"value\" | \"defaultValue\" | \"onValueChange\"\n> & {\n\t/**\n\t * The controlled selected value.\n\t */\n\tvalue?: string;\n\t/**\n\t * The initially selected value.\n\t */\n\tdefaultValue?: string;\n\t/**\n\t * Called when the selected value changes.\n\t */\n\tonValueChange?: (value: string) => void;\n\t/**\n\t * Marks the group invalid and shows alert copy.\n\t */\n\terror?: React.ReactNode;\n\t/**\n\t * Disable every item in the group.\n\t * @default false\n\t */\n\tdisabled?: boolean;\n};\n\nexport type RadioLegendProps = React.ComponentPropsWithoutRef<\"legend\">;\n\nexport type RadioProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>,\n\t\"value\"\n> & {\n\t/**\n\t * The value associated with the radio item.\n\t */\n\tvalue: string;\n\t/**\n\t * The visual size of the radio.\n\t * @default default\n\t */\n\tsize?: RadioSize;\n};\n\nconst RadioLegend = React.forwardRef<HTMLLegendElement, RadioLegendProps>(\n\t({ className, ...props }, ref) => (\n\t\t<legend\n\t\t\tref={ref}\n\t\t\tclassName={cn(\"text-sm font-medium text-basalt-foreground\", className)}\n\t\t\t{...props}\n\t\t/>\n\t),\n);\nRadioLegend.displayName = \"Radio.Legend\";\n\nexport const RadioGroup = React.forwardRef<\n\tReact.ElementRef<typeof RadioGroupPrimitive.Root>,\n\tRadioGroupProps\n>(\n\t(\n\t\t{\n\t\t\tclassName,\n\t\t\terror,\n\t\t\tdisabled = false,\n\t\t\tchildren,\n\t\t\t\"aria-describedby\": describedBy,\n\t\t\t\"aria-invalid\": ariaInvalid,\n\t\t\t\"aria-labelledby\": labelledBy,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst generatedId = React.useId();\n\t\tconst invalid = Boolean(error);\n\t\tconst errorId = `${generatedId}-error`;\n\t\tconst defaultLegendId = `${generatedId}-legend`;\n\t\tconst legends: React.ReactElement<RadioLegendProps>[] = [];\n\t\tconst items: React.ReactNode[] = [];\n\t\tReact.Children.forEach(children, (child) => {\n\t\t\tif (React.isValidElement(child) && child.type === RadioLegend) {\n\t\t\t\tlegends.push(child as React.ReactElement<RadioLegendProps>);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\titems.push(child);\n\t\t});\n\t\tconst labeledLegends = legends.map((legend, index) => {\n\t\t\tconst legendId =\n\t\t\t\tlegend.props.id ?? (index === 0 ? defaultLegendId : `${defaultLegendId}-${index}`);\n\t\t\treturn React.cloneElement(legend, { key: legendId, id: legendId });\n\t\t});\n\t\tconst legendIds = labeledLegends\n\t\t\t.map((legend) => legend.props.id)\n\t\t\t.filter(Boolean)\n\t\t\t.join(\" \");\n\t\tconst mergedLabelledBy = [legendIds, labelledBy].filter(Boolean).join(\" \") || undefined;\n\t\tconst mergedDescribedBy =\n\t\t\t[invalid ? errorId : null, describedBy].filter(Boolean).join(\" \") || undefined;\n\t\treturn (\n\t\t\t<fieldset disabled={disabled} className=\"flex flex-col gap-2\">\n\t\t\t\t{labeledLegends}\n\t\t\t\t<RadioGroupPrimitive.Root\n\t\t\t\t\tref={ref}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tclassName={cn(\"grid gap-2\", className)}\n\t\t\t\t\t{...props}\n\t\t\t\t\taria-labelledby={mergedLabelledBy}\n\t\t\t\t\taria-describedby={mergedDescribedBy}\n\t\t\t\t\taria-invalid={invalid ? true : ariaInvalid}\n\t\t\t\t>\n\t\t\t\t\t{items}\n\t\t\t\t</RadioGroupPrimitive.Root>\n\t\t\t\t{invalid ? (\n\t\t\t\t\t<p id={errorId} className=\"text-xs text-basalt-destructive\" role=\"alert\">\n\t\t\t\t\t\t{error}\n\t\t\t\t\t</p>\n\t\t\t\t) : null}\n\t\t\t</fieldset>\n\t\t);\n\t},\n);\nRadioGroup.displayName = \"Radio.Group\";\n\nconst RadioRoot = React.forwardRef<React.ElementRef<typeof RadioGroupPrimitive.Item>, RadioProps>(\n\t({ className, size = \"default\", ...props }, ref) => (\n\t\t<RadioGroupPrimitive.Item\n\t\t\tref={ref}\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"aspect-square shrink-0 rounded-full border border-basalt-primary text-basalt-primary disabled:cursor-not-allowed disabled:opacity-50\",\n\t\t\t\tRADIO_SIZE_CLASS[size],\n\t\t\t\tFOCUS_RING,\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<RadioGroupPrimitive.Indicator className=\"flex items-center justify-center\">\n\t\t\t\t<Circle className={RADIO_INDICATOR_CLASS[size]} />\n\t\t\t</RadioGroupPrimitive.Indicator>\n\t\t</RadioGroupPrimitive.Item>\n\t),\n);\nRadioRoot.displayName = RadioGroupPrimitive.Item.displayName;\n\nexport const Radio = Object.assign(RadioRoot, {\n\tGroup: RadioGroup,\n\tLegend: RadioLegend,\n\tItem: RadioRoot,\n});\n"],"mappings":";;;;;;;;;AASA,
|
|
1
|
+
{"version":3,"file":"radio.js","names":["React","RadioGroupPrimitive","RADIO_SIZE_CLASS","RADIO_INDICATOR_CLASS","RadioLegend","props","cn","className","RadioGroup","describedBy","ariaInvalid","labelledBy","generatedId","invalid","error","errorId","defaultLegendId","legends","items","children","child","labeledLegends","legendId","legend","index","mergedLabelledBy","mergedDescribedBy","RadioRoot","BASALT_UI_CLASS","size","FOCUS_RING","Circle","Radio"],"sources":["../../src/components/radio.tsx"],"sourcesContent":["import * as RadioGroupPrimitive from \"@radix-ui/react-radio-group\";\nimport { Circle } from \"lucide-react\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { FOCUS_RING } from \"./overlay\";\n\nexport type RadioSize = \"sm\" | \"default\";\n\nconst RADIO_SIZE_CLASS: Record<RadioSize, string> = {\n\tsm: \"h-3 w-3\",\n\tdefault: \"h-4 w-4\",\n};\n\nconst RADIO_INDICATOR_CLASS: Record<RadioSize, string> = {\n\tsm: \"h-1.5 w-1.5 fill-current text-current\",\n\tdefault: \"h-2.5 w-2.5 fill-current text-current\",\n};\n\nexport type RadioGroupProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>,\n\t\"disabled\" | \"value\" | \"defaultValue\" | \"onValueChange\"\n> & {\n\t/**\n\t * The controlled selected value.\n\t */\n\tvalue?: string;\n\t/**\n\t * The initially selected value.\n\t */\n\tdefaultValue?: string;\n\t/**\n\t * Called when the selected value changes.\n\t */\n\tonValueChange?: (value: string) => void;\n\t/**\n\t * Marks the group invalid and shows alert copy.\n\t */\n\terror?: React.ReactNode;\n\t/**\n\t * Disable every item in the group.\n\t * @default false\n\t */\n\tdisabled?: boolean;\n};\n\nexport type RadioLegendProps = React.ComponentPropsWithoutRef<\"legend\">;\n\nexport type RadioProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>,\n\t\"value\"\n> & {\n\t/**\n\t * The value associated with the radio item.\n\t */\n\tvalue: string;\n\t/**\n\t * The visual size of the radio.\n\t * @default default\n\t */\n\tsize?: RadioSize;\n};\n\nconst RadioLegend = React.forwardRef<HTMLLegendElement, RadioLegendProps>(\n\t({ className, ...props }, ref) => (\n\t\t<legend\n\t\t\tref={ref}\n\t\t\tclassName={cn(\"text-sm font-medium text-basalt-foreground\", className)}\n\t\t\t{...props}\n\t\t/>\n\t),\n);\nRadioLegend.displayName = \"Radio.Legend\";\n\nexport const RadioGroup = React.forwardRef<\n\tReact.ElementRef<typeof RadioGroupPrimitive.Root>,\n\tRadioGroupProps\n>(\n\t(\n\t\t{\n\t\t\tclassName,\n\t\t\terror,\n\t\t\tdisabled = false,\n\t\t\tchildren,\n\t\t\t\"aria-describedby\": describedBy,\n\t\t\t\"aria-invalid\": ariaInvalid,\n\t\t\t\"aria-labelledby\": labelledBy,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst generatedId = React.useId();\n\t\tconst invalid = Boolean(error);\n\t\tconst errorId = `${generatedId}-error`;\n\t\tconst defaultLegendId = `${generatedId}-legend`;\n\t\tconst legends: React.ReactElement<RadioLegendProps>[] = [];\n\t\tconst items: React.ReactNode[] = [];\n\t\tReact.Children.forEach(children, (child) => {\n\t\t\tif (React.isValidElement(child) && child.type === RadioLegend) {\n\t\t\t\tlegends.push(child as React.ReactElement<RadioLegendProps>);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\titems.push(child);\n\t\t});\n\t\tconst labeledLegends = legends.map((legend, index) => {\n\t\t\tconst legendId =\n\t\t\t\tlegend.props.id ?? (index === 0 ? defaultLegendId : `${defaultLegendId}-${index}`);\n\t\t\treturn React.cloneElement(legend, { key: legendId, id: legendId });\n\t\t});\n\t\tconst legendIds = labeledLegends\n\t\t\t.map((legend) => legend.props.id)\n\t\t\t.filter(Boolean)\n\t\t\t.join(\" \");\n\t\tconst mergedLabelledBy = [legendIds, labelledBy].filter(Boolean).join(\" \") || undefined;\n\t\tconst mergedDescribedBy =\n\t\t\t[invalid ? errorId : null, describedBy].filter(Boolean).join(\" \") || undefined;\n\t\treturn (\n\t\t\t<fieldset disabled={disabled} className=\"flex flex-col gap-2\">\n\t\t\t\t{labeledLegends}\n\t\t\t\t<RadioGroupPrimitive.Root\n\t\t\t\t\tref={ref}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tclassName={cn(\"grid gap-2\", className)}\n\t\t\t\t\t{...props}\n\t\t\t\t\taria-labelledby={mergedLabelledBy}\n\t\t\t\t\taria-describedby={mergedDescribedBy}\n\t\t\t\t\taria-invalid={invalid ? true : ariaInvalid}\n\t\t\t\t>\n\t\t\t\t\t{items}\n\t\t\t\t</RadioGroupPrimitive.Root>\n\t\t\t\t{invalid ? (\n\t\t\t\t\t<p id={errorId} className=\"text-xs text-basalt-destructive\" role=\"alert\">\n\t\t\t\t\t\t{error}\n\t\t\t\t\t</p>\n\t\t\t\t) : null}\n\t\t\t</fieldset>\n\t\t);\n\t},\n);\nRadioGroup.displayName = \"Radio.Group\";\n\nconst RadioRoot = React.forwardRef<React.ElementRef<typeof RadioGroupPrimitive.Item>, RadioProps>(\n\t({ className, size = \"default\", ...props }, ref) => (\n\t\t<RadioGroupPrimitive.Item\n\t\t\tref={ref}\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"aspect-square shrink-0 rounded-full border border-basalt-primary text-basalt-primary disabled:cursor-not-allowed disabled:opacity-50\",\n\t\t\t\tRADIO_SIZE_CLASS[size],\n\t\t\t\tFOCUS_RING,\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<RadioGroupPrimitive.Indicator className=\"flex items-center justify-center\">\n\t\t\t\t<Circle className={RADIO_INDICATOR_CLASS[size]} />\n\t\t\t</RadioGroupPrimitive.Indicator>\n\t\t</RadioGroupPrimitive.Item>\n\t),\n);\nRadioRoot.displayName = RadioGroupPrimitive.Item.displayName;\n\nexport const Radio = Object.assign(RadioRoot, {\n\tGroup: RadioGroup,\n\tLegend: RadioLegend,\n\tItem: RadioRoot,\n});\n"],"mappings":";;;;;;;;;AASA,IAAME,IAA8C;CACnD,IAAI;CACJ,SAAS;AACV,GAEMC,IAAmD;CACxD,IAAI;CACJ,SAAS;AACV,GA8CMC,IAAcJ,EAAM,YACxB,EAAE,cAAW,GAAGK,KAAS,MACzB,kBAAC,UAAD;CACM;CACL,WAAWC,EAAG,8CAA8CC,CAAS;CACrE,GAAIF;AACJ,CAAA,CAEH;AACA,EAAY,cAAc;AAE1B,IAAaG,IAAaR,EAAM,YAK9B,EACC,cACA,UACA,cAAW,IACX,aACA,oBAAoBS,GACpB,gBAAgBC,GAChB,mBAAmBC,GACnB,GAAGN,KAEJ,MACI;CACJ,IAAMO,IAAcZ,EAAM,MAAM,GAC1Ba,IAAU,EAAQC,GAClBC,IAAU,GAAGH,EAAY,SACzBI,IAAkB,GAAGJ,EAAY,UACjCK,IAAkD,CAAC,GACnDC,IAA2B,CAAC;CAClC,EAAM,SAAS,QAAQC,IAAW,MAAU;EAC3C,IAAInB,EAAM,eAAeoB,CAAK,KAAKA,EAAM,SAAShB,GAAa;GAC9D,EAAQ,KAAKgB,CAA6C;GAC1D;EACD;EACA,EAAM,KAAKA,CAAK;CACjB,CAAC;CACD,IAAMC,IAAiBJ,EAAQ,KAAK,GAAQ,MAAU;EACrD,IAAMK,IACLC,EAAO,MAAM,OAAOC,MAAU,IAAIR,IAAkB,GAAGA,EAAgB,GAAGQ;EAC3E,OAAOxB,EAAM,aAAauB,GAAQ;GAAE,KAAKD;GAAU,IAAIA;EAAS,CAAC;CAClE,CAAC,GAKKG,IAAmB,CAJPJ,EAChB,KAAK,MAAWE,EAAO,MAAM,EAAE,CAAC,CAChC,OAAO,OAAO,CAAC,CACf,KAAK,GACmB,GAAWZ,CAAU,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,KAAK,KAAA,GACxEe,IACL,CAACb,IAAUE,IAAU,MAAMN,CAAW,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,KAAK,KAAA;CACtE,OACC,kBAAC,YAAD;EAAoB;EAAU,WAAU;EAAxC,UAAA;GACEY;GACD,kBAACpB,EAAoB,MAArB;IACM;IACK;IACV,WAAWK,EAAG,cAAcC,CAAS;IACrC,GAAIF;IACJ,mBAAiBoB;IACjB,oBAAkBC;IAClB,gBAAcb,IAAU,KAAOH;IAE9B,UAAAQ;GACwB,CAAA;GACzBL,IACA,kBAAC,KAAD;IAAG,IAAIE;IAAS,WAAU;IAAkC,MAAK;IAC/D,UAAAD;GACC,CAAA,IACA;EACK;;AAEZ,CACD;AACA,EAAW,cAAc;AAEzB,IAAMa,IAAY3B,EAAM,YACtB,EAAE,cAAW,UAAO,WAAW,GAAGK,KAAS,MAC3C,kBAACJ,EAAoB,MAArB;CACM;CACL,WAAWK,EACVsB,GACA,wIACA1B,EAAiB2B,IACjBC,GACAvB,CACD;CACA,GAAIF;CAEJ,UAAA,kBAACJ,EAAoB,WAArB;EAA+B,WAAU;EACxC,UAAA,kBAAC8B,GAAD,EAAQ,WAAW5B,EAAsB0B,GAAQ,CAAA;CACnB,CAAA;AACN,CAAA,CAE5B;AACA,EAAU,cAAc5B,EAAoB,KAAK;AAEjD,IAAa+B,IAAQ,OAAO,OAAOL,GAAW;CAC7C,OAAOnB;CACP,QAAQJ;CACR,MAAMuB;AACP,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource-list.js","names":[],"sources":["../../src/components/resource-list.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { DataTable, type DataTableColumn } from \"./data-table\";\nimport { PageHeader } from \"./page-header\";\n\nexport type ResourceListRow = {\n\tname: string;\n\tstatus: string;\n};\n\nexport type ResourceListProps = {\n\ttitle: string;\n\tdescription?: string;\n\tdata: ResourceListRow[];\n\t/** Custom heading; falls back to PageHeader. */\n\theader?: ReactNode;\n\t/** Search and primary actions below the heading. */\n\ttoolbar?: ReactNode;\n\t/** Active filters and their controls. */\n\tfilters?: ReactNode;\n\t/** Selection-dependent actions. */\n\tbulkActions?: ReactNode;\n\t/** State content replacing the results; undefined falls through to children/data. */\n\tstate?: ReactNode;\n\t/** Custom results such as a typed DataTable. */\n\tchildren?: ReactNode;\n\t/** Pagination or result summary after the results. */\n\tfooter?: ReactNode;\n\t/** Classes for the root region. */\n\tclassName?: string;\n\t/** Show the default table loading state. @default false */\n\tloading?: boolean;\n\t/** Content shown when default data is empty. */\n\tempty?: ReactNode;\n\t/** Default table error content. */\n\terror?: ReactNode;\n\t/** Retry callback for the default table. */\n\tonRetry?: () => void;\n};\n\nconst COLUMNS: DataTableColumn<ResourceListRow>[] = [\n\t{ id: \"name\", header: \"Name\", accessor: (row) => row.name },\n\t{ id: \"status\", header: \"Status\", accessor: (row) => row.status },\n];\n\nexport function ResourceList({\n\ttitle,\n\tdescription,\n\tdata,\n\theader,\n\ttoolbar,\n\tfilters,\n\tbulkActions,\n\tstate,\n\tchildren,\n\tfooter,\n\tclassName,\n\tloading,\n\tempty,\n\terror,\n\tonRetry,\n}: ResourceListProps) {\n\treturn (\n\t\t<div className={cn(\"min-w-0 space-y-4\", className)}>\n\t\t\t{header ?? <PageHeader title={title} description={description} />}\n\t\t\t{toolbar != null ? <div>{toolbar}</div> : null}\n\t\t\t{filters != null ? <div>{filters}</div> : null}\n\t\t\t{bulkActions != null ? <div>{bulkActions}</div> : null}\n\t\t\t{state ?? children ?? (\n\t\t\t\t<DataTable\n\t\t\t\t\tdata={data}\n\t\t\t\t\tcolumns={COLUMNS}\n\t\t\t\t\tloading={loading}\n\t\t\t\t\tempty={empty}\n\t\t\t\t\terror={error}\n\t\t\t\t\tonRetry={onRetry}\n\t\t\t\t\taria-label={title}\n\t\t\t\t/>\n\t\t\t)}\n\t\t\t{footer != null ? <div>{footer}</div> : null}\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;;;AAwCA,
|
|
1
|
+
{"version":3,"file":"resource-list.js","names":["COLUMNS","row","ResourceList","cn","className","header","PageHeader","toolbar","filters","bulkActions","state","children","DataTable","title","footer"],"sources":["../../src/components/resource-list.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { DataTable, type DataTableColumn } from \"./data-table\";\nimport { PageHeader } from \"./page-header\";\n\nexport type ResourceListRow = {\n\tname: string;\n\tstatus: string;\n};\n\nexport type ResourceListProps = {\n\ttitle: string;\n\tdescription?: string;\n\tdata: ResourceListRow[];\n\t/** Custom heading; falls back to PageHeader. */\n\theader?: ReactNode;\n\t/** Search and primary actions below the heading. */\n\ttoolbar?: ReactNode;\n\t/** Active filters and their controls. */\n\tfilters?: ReactNode;\n\t/** Selection-dependent actions. */\n\tbulkActions?: ReactNode;\n\t/** State content replacing the results; undefined falls through to children/data. */\n\tstate?: ReactNode;\n\t/** Custom results such as a typed DataTable. */\n\tchildren?: ReactNode;\n\t/** Pagination or result summary after the results. */\n\tfooter?: ReactNode;\n\t/** Classes for the root region. */\n\tclassName?: string;\n\t/** Show the default table loading state. @default false */\n\tloading?: boolean;\n\t/** Content shown when default data is empty. */\n\tempty?: ReactNode;\n\t/** Default table error content. */\n\terror?: ReactNode;\n\t/** Retry callback for the default table. */\n\tonRetry?: () => void;\n};\n\nconst COLUMNS: DataTableColumn<ResourceListRow>[] = [\n\t{ id: \"name\", header: \"Name\", accessor: (row) => row.name },\n\t{ id: \"status\", header: \"Status\", accessor: (row) => row.status },\n];\n\nexport function ResourceList({\n\ttitle,\n\tdescription,\n\tdata,\n\theader,\n\ttoolbar,\n\tfilters,\n\tbulkActions,\n\tstate,\n\tchildren,\n\tfooter,\n\tclassName,\n\tloading,\n\tempty,\n\terror,\n\tonRetry,\n}: ResourceListProps) {\n\treturn (\n\t\t<div className={cn(\"min-w-0 space-y-4\", className)}>\n\t\t\t{header ?? <PageHeader title={title} description={description} />}\n\t\t\t{toolbar != null ? <div>{toolbar}</div> : null}\n\t\t\t{filters != null ? <div>{filters}</div> : null}\n\t\t\t{bulkActions != null ? <div>{bulkActions}</div> : null}\n\t\t\t{state ?? children ?? (\n\t\t\t\t<DataTable\n\t\t\t\t\tdata={data}\n\t\t\t\t\tcolumns={COLUMNS}\n\t\t\t\t\tloading={loading}\n\t\t\t\t\tempty={empty}\n\t\t\t\t\terror={error}\n\t\t\t\t\tonRetry={onRetry}\n\t\t\t\t\taria-label={title}\n\t\t\t\t/>\n\t\t\t)}\n\t\t\t{footer != null ? <div>{footer}</div> : null}\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;;;AAwCA,IAAMA,IAA8C,CACnD;CAAE,IAAI;CAAQ,QAAQ;CAAQ,WAAW,MAAQC,EAAI;AAAK,GAC1D;CAAE,IAAI;CAAU,QAAQ;CAAU,WAAW,MAAQA,EAAI;AAAO,CACjE;AAEA,SAAgBC,EAAa,EAC5B,UACA,gBACA,SACA,WACA,YACA,YACA,gBACA,UACA,aACA,WACA,cACA,YACA,UACA,UACA,cACqB;CACrB,OACC,kBAAC,OAAD;EAAK,WAAWC,EAAG,qBAAqBC,CAAS;EAAjD,UAAA;GACEC,KAAU,kBAACC,GAAD;IAAmB;IAAoB;GAAc,CAAA;GAC/DC,KAAW,OAA8B,OAAvB,kBAAC,OAAD,EAAA,UAAMA,EAAa,CAAA;GACrCC,KAAW,OAA8B,OAAvB,kBAAC,OAAD,EAAA,UAAMA,EAAa,CAAA;GACrCC,KAAe,OAAkC,OAA3B,kBAAC,OAAD,EAAA,UAAMA,EAAiB,CAAA;GAC7CC,KAASC,KACT,kBAACC,GAAD;IACO;IACN,SAASZ;IACA;IACF;IACA;IACE;IACT,cAAYa;GACZ,CAAA;GAEDC,KAAU,OAA6B,OAAtB,kBAAC,OAAD,EAAA,UAAMA,EAAY,CAAA;EAChC;;AAEP"}
|
|
@@ -36,16 +36,16 @@ function u({ label: u, list: d, children: f, detailOpen: p, onDetailOpenChange:
|
|
|
36
36
|
]), /* @__PURE__ */ l("div", {
|
|
37
37
|
role: "group",
|
|
38
38
|
"aria-label": u,
|
|
39
|
-
className: e(t, "grid min-w-0 grid-cols-1
|
|
39
|
+
className: e(t, "grid min-h-0 min-w-0 grid-cols-1 rounded-basalt-lg border border-basalt-border md:grid-cols-[minmax(12rem,20rem)_minmax(0,1fr)] md:overflow-hidden", b),
|
|
40
40
|
children: [/* @__PURE__ */ c("section", {
|
|
41
41
|
ref: C,
|
|
42
42
|
"aria-label": g,
|
|
43
43
|
tabIndex: -1,
|
|
44
44
|
hidden: x && p,
|
|
45
45
|
inert: x && p,
|
|
46
|
-
className: e("min-w-0 bg-basalt-card focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-basalt-ring md:border-r md:border-basalt-border", p && "hidden md:block"),
|
|
46
|
+
className: e("min-h-0 min-w-0 bg-basalt-card focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-basalt-ring md:overflow-y-auto md:overscroll-y-contain md:border-r md:border-basalt-border", p && "hidden md:block"),
|
|
47
47
|
onFocusCapture: (e) => {
|
|
48
|
-
T.current = e.target;
|
|
48
|
+
e.target !== e.currentTarget && (T.current = e.target);
|
|
49
49
|
},
|
|
50
50
|
onPointerDownCapture: (e) => {
|
|
51
51
|
let t = e.target.closest("button, a[href], input, [tabindex]");
|
|
@@ -58,12 +58,12 @@ function u({ label: u, list: d, children: f, detailOpen: p, onDetailOpenChange:
|
|
|
58
58
|
tabIndex: -1,
|
|
59
59
|
hidden: x && !p,
|
|
60
60
|
inert: x && !p,
|
|
61
|
-
className: e("min-w-0 bg-basalt-background focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-basalt-ring", !p && "hidden md:block"),
|
|
61
|
+
className: e("min-h-0 min-w-0 bg-basalt-background focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-basalt-ring md:overflow-y-auto md:overscroll-y-contain", !p && "hidden md:block"),
|
|
62
62
|
children: [
|
|
63
63
|
x && p && /* @__PURE__ */ c("div", {
|
|
64
64
|
className: "border-b border-basalt-border p-2",
|
|
65
65
|
children: /* @__PURE__ */ l(n, {
|
|
66
|
-
|
|
66
|
+
className: "min-h-11",
|
|
67
67
|
variant: "ghost",
|
|
68
68
|
onClick: () => m(!1),
|
|
69
69
|
children: [/* @__PURE__ */ c(s, {}), v]
|