@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":"responsive-master-detail.js","names":[],"sources":["../../src/components/responsive-master-detail.tsx"],"sourcesContent":["import { ArrowLeft } from \"lucide-react\";\nimport { type ReactNode, useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Button } from \"./button\";\n\nexport interface ResponsiveMasterDetailProps {\n\t/** Accessible name of the composition. */\n\tlabel: string;\n\t/** Application-rendered list; selection, routing and data remain outside. */\n\tlist: ReactNode;\n\t/** Application-rendered detail content. */\n\tchildren: ReactNode;\n\t/** Controlled detail visibility. */\n\tdetailOpen: boolean;\n\t/** Requests opening/closing the detail; the caller accepts the change. */\n\tonDetailOpenChange: (open: boolean) => void;\n\t/** Current selection identity, used to focus newly selected mobile details. */\n\tselectedId?: string | null;\n\t/** List region name. @default \"Items\" */\n\tlistLabel?: string;\n\t/** Detail region name. @default \"Details\" */\n\tdetailLabel?: string;\n\t/** Mobile return action text. @default \"Back to items\" */\n\tbackLabel?: string;\n\t/** Desktop detail placeholder while no item is open. */\n\tempty?: ReactNode;\n\t/** Additional root classes; provide application-specific height/scrolling here. */\n\tclassName?: string;\n}\n/** Two columns at 768px and above; one visible, focusable pane below it. Not a modal. */\nexport function ResponsiveMasterDetail({\n\tlabel,\n\tlist,\n\tchildren,\n\tdetailOpen,\n\tonDetailOpenChange,\n\tselectedId,\n\tlistLabel = \"Items\",\n\tdetailLabel = \"Details\",\n\tbackLabel = \"Back to items\",\n\tempty = (\n\t\t<p className=\"p-6 text-sm text-basalt-muted-foreground\">Choose an item to see its details.</p>\n\t),\n\tclassName,\n}: ResponsiveMasterDetailProps) {\n\tconst [compact, setCompact] = useState(false);\n\tconst listRegion = useRef<HTMLElement>(null);\n\tconst detailRegion = useRef<HTMLElement>(null);\n\tconst opener = useRef<HTMLElement | null>(null);\n\tconst previous = useRef({ compact: false, detailOpen: false, selectedId });\n\tuseEffect(() => {\n\t\tconst query = window.matchMedia(\"(max-width: 767px)\");\n\t\tconst update = () => setCompact(query.matches);\n\t\tupdate();\n\t\tquery.addEventListener(\"change\", update);\n\t\treturn () => query.removeEventListener(\"change\", update);\n\t}, []);\n\tuseLayoutEffect(() => {\n\t\tconst before = previous.current;\n\t\tif (\n\t\t\tcompact &&\n\t\t\tdetailOpen &&\n\t\t\t(!before.compact || !before.detailOpen || before.selectedId !== selectedId)\n\t\t)\n\t\t\tdetailRegion.current?.focus();\n\t\tif (compact && !detailOpen && before.detailOpen) {\n\t\t\tconst target = opener.current;\n\t\t\tif (target?.isConnected && !target.closest(\"[hidden], [inert]\")) target.focus();\n\t\t\telse listRegion.current?.focus();\n\t\t}\n\t\tprevious.current = { compact, detailOpen, selectedId };\n\t}, [compact, detailOpen, selectedId]);\n\treturn (\n\t\t<div\n\t\t\trole=\"group\"\n\t\t\taria-label={label}\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"grid min-w-0 grid-cols-1
|
|
1
|
+
{"version":3,"file":"responsive-master-detail.js","names":["ResponsiveMasterDetail","compact","setCompact","useState","listRegion","useRef","detailRegion","opener","previous","useEffect","query","update","useLayoutEffect","before","detailOpen","selectedId","target","label","cn","BASALT_UI_CLASS","className","listLabel","event","list","detailLabel","Button","onDetailOpenChange","ArrowLeft","backLabel","empty"],"sources":["../../src/components/responsive-master-detail.tsx"],"sourcesContent":["import { ArrowLeft } from \"lucide-react\";\nimport { type ReactNode, useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Button } from \"./button\";\n\nexport interface ResponsiveMasterDetailProps {\n\t/** Accessible name of the composition. */\n\tlabel: string;\n\t/** Application-rendered list; selection, routing and data remain outside. */\n\tlist: ReactNode;\n\t/** Application-rendered detail content. */\n\tchildren: ReactNode;\n\t/** Controlled detail visibility. */\n\tdetailOpen: boolean;\n\t/** Requests opening/closing the detail; the caller accepts the change. */\n\tonDetailOpenChange: (open: boolean) => void;\n\t/** Current selection identity, used to focus newly selected mobile details. */\n\tselectedId?: string | null;\n\t/** List region name. @default \"Items\" */\n\tlistLabel?: string;\n\t/** Detail region name. @default \"Details\" */\n\tdetailLabel?: string;\n\t/** Mobile return action text. @default \"Back to items\" */\n\tbackLabel?: string;\n\t/** Desktop detail placeholder while no item is open. */\n\tempty?: ReactNode;\n\t/** Additional root classes; provide application-specific height/scrolling here. */\n\tclassName?: string;\n}\n/** Two columns at 768px and above; one visible, focusable pane below it. Not a modal. */\nexport function ResponsiveMasterDetail({\n\tlabel,\n\tlist,\n\tchildren,\n\tdetailOpen,\n\tonDetailOpenChange,\n\tselectedId,\n\tlistLabel = \"Items\",\n\tdetailLabel = \"Details\",\n\tbackLabel = \"Back to items\",\n\tempty = (\n\t\t<p className=\"p-6 text-sm text-basalt-muted-foreground\">Choose an item to see its details.</p>\n\t),\n\tclassName,\n}: ResponsiveMasterDetailProps) {\n\tconst [compact, setCompact] = useState(false);\n\tconst listRegion = useRef<HTMLElement>(null);\n\tconst detailRegion = useRef<HTMLElement>(null);\n\tconst opener = useRef<HTMLElement | null>(null);\n\tconst previous = useRef({ compact: false, detailOpen: false, selectedId });\n\tuseEffect(() => {\n\t\tconst query = window.matchMedia(\"(max-width: 767px)\");\n\t\tconst update = () => setCompact(query.matches);\n\t\tupdate();\n\t\tquery.addEventListener(\"change\", update);\n\t\treturn () => query.removeEventListener(\"change\", update);\n\t}, []);\n\tuseLayoutEffect(() => {\n\t\tconst before = previous.current;\n\t\tif (\n\t\t\tcompact &&\n\t\t\tdetailOpen &&\n\t\t\t(!before.compact || !before.detailOpen || before.selectedId !== selectedId)\n\t\t)\n\t\t\tdetailRegion.current?.focus();\n\t\tif (compact && !detailOpen && before.detailOpen) {\n\t\t\tconst target = opener.current;\n\t\t\tif (target?.isConnected && !target.closest(\"[hidden], [inert]\")) target.focus();\n\t\t\telse listRegion.current?.focus();\n\t\t}\n\t\tprevious.current = { compact, detailOpen, selectedId };\n\t}, [compact, detailOpen, selectedId]);\n\treturn (\n\t\t<div\n\t\t\trole=\"group\"\n\t\t\taria-label={label}\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\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\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t>\n\t\t\t<section\n\t\t\t\tref={listRegion}\n\t\t\t\taria-label={listLabel}\n\t\t\t\ttabIndex={-1}\n\t\t\t\thidden={compact && detailOpen}\n\t\t\t\tinert={compact && detailOpen}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"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\",\n\t\t\t\t\tdetailOpen && \"hidden md:block\",\n\t\t\t\t)}\n\t\t\t\tonFocusCapture={(event) => {\n\t\t\t\t\tif (event.target !== event.currentTarget) opener.current = event.target;\n\t\t\t\t}}\n\t\t\t\tonPointerDownCapture={(event) => {\n\t\t\t\t\tconst target = (event.target as Element).closest<HTMLElement>(\n\t\t\t\t\t\t\"button, a[href], input, [tabindex]\",\n\t\t\t\t\t);\n\t\t\t\t\tif (target) opener.current = target;\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{list}\n\t\t\t</section>\n\t\t\t<section\n\t\t\t\tref={detailRegion}\n\t\t\t\taria-label={detailLabel}\n\t\t\t\ttabIndex={-1}\n\t\t\t\thidden={compact && !detailOpen}\n\t\t\t\tinert={compact && !detailOpen}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"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\",\n\t\t\t\t\t!detailOpen && \"hidden md:block\",\n\t\t\t\t)}\n\t\t\t>\n\t\t\t\t{compact && detailOpen && (\n\t\t\t\t\t<div className=\"border-b border-basalt-border p-2\">\n\t\t\t\t\t\t<Button className=\"min-h-11\" variant=\"ghost\" onClick={() => onDetailOpenChange(false)}>\n\t\t\t\t\t\t\t<ArrowLeft />\n\t\t\t\t\t\t\t{backLabel}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t\t<div hidden={!detailOpen} inert={!detailOpen}>\n\t\t\t\t\t{children}\n\t\t\t\t</div>\n\t\t\t\t{!detailOpen && empty}\n\t\t\t</section>\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;;;;;AA+BA,SAAgBA,EAAuB,EACtC,UACA,SACA,aACA,eACA,uBACA,eACA,eAAY,SACZ,iBAAc,WACd,eAAY,iBACZ,WACC,kBAAC,KAAD;CAAG,WAAU;CAA2C,UAAA;AAAqC,CAAA,GAE9F,gBAC+B;CAC/B,IAAM,CAACC,GAASC,KAAcC,EAAS,EAAK,GACtCC,IAAaC,EAAoB,IAAI,GACrCC,IAAeD,EAAoB,IAAI,GACvCE,IAASF,EAA2B,IAAI,GACxCG,IAAWH,EAAO;EAAE,SAAS;EAAO,YAAY;EAAO;CAAW,CAAC;CAuBzE,OAtBAI,QAAgB;EACf,IAAMC,IAAQ,OAAO,WAAW,oBAAoB,GAC9CC,UAAeT,EAAWQ,EAAM,OAAO;EAG7C,OAFAC,EAAO,GACPD,EAAM,iBAAiB,UAAUC,CAAM,SAC1BD,EAAM,oBAAoB,UAAUC,CAAM;CACxD,GAAG,CAAC,CAAC,GACLC,QAAsB;EACrB,IAAMC,IAASL,EAAS;EAOxB,IALCP,KACAa,MACC,CAACD,EAAO,WAAW,CAACA,EAAO,cAAcA,EAAO,eAAeE,MAEhET,EAAa,SAAS,MAAM,GACzBL,KAAW,CAACa,KAAcD,EAAO,YAAY;GAChD,IAAMG,IAAST,EAAO;GACtB,AAAIS,GAAQ,eAAe,CAACA,EAAO,QAAQ,mBAAmB,IAAGA,EAAO,MAAM,IACzEZ,EAAW,SAAS,MAAM;EAChC;EACA,EAAS,UAAU;GAAE;GAAS;GAAY;EAAW;CACtD,GAAG;EAACH;EAASa;EAAYC;CAAU,CAAC,GAEnC,kBAAC,OAAD;EACC,MAAK;EACL,cAAYE;EACZ,WAAWC,EACVC,GACA,sJACAC,CACD;EAPD,UAAA,CASC,kBAAC,WAAD;GACC,KAAKhB;GACL,cAAYiB;GACZ,UAAU;GACV,QAAQpB,KAAWa;GACnB,OAAOb,KAAWa;GAClB,WAAWI,EACV,2MACAJ,KAAc,iBACf;GACA,iBAAiB,MAAU;IAC1B,AAAIQ,EAAM,WAAWA,EAAM,kBAAe,EAAO,UAAUA,EAAM;GAClE;GACA,uBAAuB,MAAU;IAChC,IAAMN,IAAUM,EAAM,OAAmB,QACxC,oCACD;IACA,AAAIN,MAAQ,EAAO,UAAUA;GAC9B;GAEC,UAAAO;EACO,CAAA,GACT,kBAAC,WAAD;GACC,KAAKjB;GACL,cAAYkB;GACZ,UAAU;GACV,QAAQvB,KAAW,CAACa;GACpB,OAAOb,KAAW,CAACa;GACnB,WAAWI,EACV,6KACA,CAACJ,KAAc,iBAChB;GATD,UAAA;IAWEb,KAAWa,KACX,kBAAC,OAAD;KAAK,WAAU;KACd,UAAA,kBAACW,GAAD;MAAQ,WAAU;MAAW,SAAQ;MAAQ,eAAeC,EAAmB,EAAK;MAApF,UAAA,CACC,kBAACC,GAAD,CAAY,CAAA,GACXC,CACM;;IACJ,CAAA;IAEN,kBAAC,OAAD;KAAK,QAAQ,CAACd;KAAY,OAAO,CAACA;KAChC;IACG,CAAA;IACJ,CAACA,KAAce;GACR;EACL,CAAA,CAAA;;AAEP"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scroll-area.js","names":[],"sources":["../../src/components/scroll-area.tsx"],"sourcesContent":["import * as ScrollAreaPrimitive from \"@radix-ui/react-scroll-area\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport type ScrollAreaOrientation = \"vertical\" | \"horizontal\" | \"both\";\n\ntype RootProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>,\n\t| \"aria-describedby\"\n\t| \"aria-label\"\n\t| \"aria-labelledby\"\n\t| \"asChild\"\n\t| \"children\"\n\t| \"className\"\n\t| \"onScroll\"\n\t| \"role\"\n\t| \"tabIndex\"\n>;\n\ntype ViewportProps = Pick<\n\tReact.ComponentPropsWithoutRef<\"div\">,\n\t| \"aria-describedby\"\n\t| \"aria-label\"\n\t| \"aria-labelledby\"\n\t| \"children\"\n\t| \"onScroll\"\n\t| \"role\"\n\t| \"tabIndex\"\n>;\n\nexport interface ScrollAreaProps extends RootProps, ViewportProps {\n\t/** Classes applied to the non-scrolling root. */\n\tclassName?: string;\n\t/** Axes that may scroll. @default \"vertical\" */\n\torientation?: ScrollAreaOrientation;\n\t/** Classes applied to the actual scrolling viewport. */\n\tviewportClassName?: string;\n}\n\nconst SCROLLBAR_CLASSES =\n\t\"flex touch-none select-none p-px transition-colors motion-reduce:transition-none\";\n\nfunction ScrollBar({ orientation }: { orientation: \"horizontal\" | \"vertical\" }) {\n\treturn (\n\t\t<ScrollAreaPrimitive.Scrollbar\n\t\t\tdata-slot=\"scroll-area-scrollbar\"\n\t\t\torientation={orientation}\n\t\t\tclassName={cn(\n\t\t\t\tSCROLLBAR_CLASSES,\n\t\t\t\torientation === \"vertical\"\n\t\t\t\t\t? \"h-full w-2.5 border-l border-l-transparent\"\n\t\t\t\t\t: \"h-2.5 flex-col border-t border-t-transparent\",\n\t\t\t)}\n\t\t>\n\t\t\t<ScrollAreaPrimitive.Thumb\n\t\t\t\tdata-slot=\"scroll-area-thumb\"\n\t\t\t\tclassName=\"relative flex-1 rounded-full bg-basalt-border\"\n\t\t\t/>\n\t\t</ScrollAreaPrimitive.Scrollbar>\n\t);\n}\n\nexport const ScrollArea = React.forwardRef<HTMLDivElement, ScrollAreaProps>(\n\t(\n\t\t{\n\t\t\t\"aria-describedby\": ariaDescribedBy,\n\t\t\t\"aria-label\": ariaLabel,\n\t\t\t\"aria-labelledby\": ariaLabelledBy,\n\t\t\tchildren,\n\t\t\tclassName,\n\t\t\tonScroll,\n\t\t\torientation = \"vertical\",\n\t\t\trole,\n\t\t\ttabIndex = 0,\n\t\t\tviewportClassName,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst hasVertical = orientation !== \"horizontal\";\n\t\tconst hasHorizontal = orientation !== \"vertical\";\n\t\tconst viewportRole = role ?? (ariaLabel || ariaLabelledBy ? \"region\" : undefined);\n\n\t\treturn (\n\t\t\t<ScrollAreaPrimitive.Root\n\t\t\t\tdata-slot=\"scroll-area\"\n\t\t\t\tclassName={cn(\"relative min-h-0 min-w-0 overflow-hidden\", className)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<ScrollAreaPrimitive.Viewport\n\t\t\t\t\tref={ref}\n\t\t\t\t\tdata-orientation={orientation}\n\t\t\t\t\tdata-slot=\"scroll-area-viewport\"\n\t\t\t\t\taria-describedby={ariaDescribedBy}\n\t\t\t\t\taria-label={ariaLabel}\n\t\t\t\t\taria-labelledby={ariaLabelledBy}\n\t\t\t\t\trole={viewportRole}\n\t\t\t\t\ttabIndex={tabIndex}\n\t\t\t\t\tonScroll={onScroll}\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"size-full rounded-[inherit] outline-hidden focus-visible:ring-2 focus-visible:ring-basalt-ring focus-visible:ring-offset-2 focus-visible:ring-offset-basalt-background\",\n\t\t\t\t\t\torientation === \"vertical\" && \"overflow-x-hidden!\",\n\t\t\t\t\t\torientation === \"horizontal\" && \"overflow-y-hidden!\",\n\t\t\t\t\t\tviewportClassName,\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t{children}\n\t\t\t\t</ScrollAreaPrimitive.Viewport>\n\t\t\t\t{hasVertical ? <ScrollBar orientation=\"vertical\" /> : null}\n\t\t\t\t{hasHorizontal ? <ScrollBar orientation=\"horizontal\" /> : null}\n\t\t\t\t{hasVertical && hasHorizontal ? (\n\t\t\t\t\t<ScrollAreaPrimitive.Corner data-slot=\"scroll-area-corner\" />\n\t\t\t\t) : null}\n\t\t\t</ScrollAreaPrimitive.Root>\n\t\t);\n\t},\n);\nScrollArea.displayName = \"ScrollArea\";\n"],"mappings":";;;;;;AAuCA,
|
|
1
|
+
{"version":3,"file":"scroll-area.js","names":["React","ScrollAreaPrimitive","SCROLLBAR_CLASSES","ScrollBar","cn","orientation","ScrollArea","ariaDescribedBy","ariaLabel","ariaLabelledBy","props","hasVertical","hasHorizontal","viewportRole","role","className","viewportClassName"],"sources":["../../src/components/scroll-area.tsx"],"sourcesContent":["import * as ScrollAreaPrimitive from \"@radix-ui/react-scroll-area\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport type ScrollAreaOrientation = \"vertical\" | \"horizontal\" | \"both\";\n\ntype RootProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>,\n\t| \"aria-describedby\"\n\t| \"aria-label\"\n\t| \"aria-labelledby\"\n\t| \"asChild\"\n\t| \"children\"\n\t| \"className\"\n\t| \"onScroll\"\n\t| \"role\"\n\t| \"tabIndex\"\n>;\n\ntype ViewportProps = Pick<\n\tReact.ComponentPropsWithoutRef<\"div\">,\n\t| \"aria-describedby\"\n\t| \"aria-label\"\n\t| \"aria-labelledby\"\n\t| \"children\"\n\t| \"onScroll\"\n\t| \"role\"\n\t| \"tabIndex\"\n>;\n\nexport interface ScrollAreaProps extends RootProps, ViewportProps {\n\t/** Classes applied to the non-scrolling root. */\n\tclassName?: string;\n\t/** Axes that may scroll. @default \"vertical\" */\n\torientation?: ScrollAreaOrientation;\n\t/** Classes applied to the actual scrolling viewport. */\n\tviewportClassName?: string;\n}\n\nconst SCROLLBAR_CLASSES =\n\t\"flex touch-none select-none p-px transition-colors motion-reduce:transition-none\";\n\nfunction ScrollBar({ orientation }: { orientation: \"horizontal\" | \"vertical\" }) {\n\treturn (\n\t\t<ScrollAreaPrimitive.Scrollbar\n\t\t\tdata-slot=\"scroll-area-scrollbar\"\n\t\t\torientation={orientation}\n\t\t\tclassName={cn(\n\t\t\t\tSCROLLBAR_CLASSES,\n\t\t\t\torientation === \"vertical\"\n\t\t\t\t\t? \"h-full w-2.5 border-l border-l-transparent\"\n\t\t\t\t\t: \"h-2.5 flex-col border-t border-t-transparent\",\n\t\t\t)}\n\t\t>\n\t\t\t<ScrollAreaPrimitive.Thumb\n\t\t\t\tdata-slot=\"scroll-area-thumb\"\n\t\t\t\tclassName=\"relative flex-1 rounded-full bg-basalt-border\"\n\t\t\t/>\n\t\t</ScrollAreaPrimitive.Scrollbar>\n\t);\n}\n\nexport const ScrollArea = React.forwardRef<HTMLDivElement, ScrollAreaProps>(\n\t(\n\t\t{\n\t\t\t\"aria-describedby\": ariaDescribedBy,\n\t\t\t\"aria-label\": ariaLabel,\n\t\t\t\"aria-labelledby\": ariaLabelledBy,\n\t\t\tchildren,\n\t\t\tclassName,\n\t\t\tonScroll,\n\t\t\torientation = \"vertical\",\n\t\t\trole,\n\t\t\ttabIndex = 0,\n\t\t\tviewportClassName,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst hasVertical = orientation !== \"horizontal\";\n\t\tconst hasHorizontal = orientation !== \"vertical\";\n\t\tconst viewportRole = role ?? (ariaLabel || ariaLabelledBy ? \"region\" : undefined);\n\n\t\treturn (\n\t\t\t<ScrollAreaPrimitive.Root\n\t\t\t\tdata-slot=\"scroll-area\"\n\t\t\t\tclassName={cn(\"relative min-h-0 min-w-0 overflow-hidden\", className)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<ScrollAreaPrimitive.Viewport\n\t\t\t\t\tref={ref}\n\t\t\t\t\tdata-orientation={orientation}\n\t\t\t\t\tdata-slot=\"scroll-area-viewport\"\n\t\t\t\t\taria-describedby={ariaDescribedBy}\n\t\t\t\t\taria-label={ariaLabel}\n\t\t\t\t\taria-labelledby={ariaLabelledBy}\n\t\t\t\t\trole={viewportRole}\n\t\t\t\t\ttabIndex={tabIndex}\n\t\t\t\t\tonScroll={onScroll}\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"size-full rounded-[inherit] outline-hidden focus-visible:ring-2 focus-visible:ring-basalt-ring focus-visible:ring-offset-2 focus-visible:ring-offset-basalt-background\",\n\t\t\t\t\t\torientation === \"vertical\" && \"overflow-x-hidden!\",\n\t\t\t\t\t\torientation === \"horizontal\" && \"overflow-y-hidden!\",\n\t\t\t\t\t\tviewportClassName,\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t{children}\n\t\t\t\t</ScrollAreaPrimitive.Viewport>\n\t\t\t\t{hasVertical ? <ScrollBar orientation=\"vertical\" /> : null}\n\t\t\t\t{hasHorizontal ? <ScrollBar orientation=\"horizontal\" /> : null}\n\t\t\t\t{hasVertical && hasHorizontal ? (\n\t\t\t\t\t<ScrollAreaPrimitive.Corner data-slot=\"scroll-area-corner\" />\n\t\t\t\t) : null}\n\t\t\t</ScrollAreaPrimitive.Root>\n\t\t);\n\t},\n);\nScrollArea.displayName = \"ScrollArea\";\n"],"mappings":";;;;;;AAuCA,IAAME,IACL;AAED,SAASC,EAAU,EAAE,kBAA2D;CAC/E,OACC,kBAACF,EAAoB,WAArB;EACC,aAAU;EACG;EACb,WAAWG,EACVF,GACAG,MAAgB,aACb,+CACA,8CACJ;EAEA,UAAA,kBAACJ,EAAoB,OAArB;GACC,aAAU;GACV,WAAU;EACV,CAAA;CAC6B,CAAA;AAEjC;AAEA,IAAaK,IAAaN,EAAM,YAE9B,EACC,oBAAoBO,GACpB,cAAcC,GACd,mBAAmBC,GACnB,aACA,cACA,aACA,iBAAc,YACd,SACA,cAAW,GACX,sBACA,GAAGC,KAEJ,MACI;CACJ,IAAMC,IAAcN,MAAgB,cAC9BO,IAAgBP,MAAgB,YAChCQ,IAAeC,MAASN,KAAaC,IAAiB,WAAW,KAAA;CAEvE,OACC,kBAACR,EAAoB,MAArB;EACC,aAAU;EACV,WAAWG,EAAG,4CAA4CW,CAAS;EACnE,GAAIL;EAHL,UAAA;GAKC,kBAACT,EAAoB,UAArB;IACM;IACL,oBAAkBI;IAClB,aAAU;IACV,oBAAkBE;IAClB,cAAYC;IACZ,mBAAiBC;IACjB,MAAMI;IACI;IACA;IACV,WAAWT,EACV,0KACAC,MAAgB,cAAc,sBAC9BA,MAAgB,gBAAgB,sBAChCW,CACD;IAEC;GAC4B,CAAA;GAC7BL,IAAc,kBAACR,GAAD,EAAW,aAAY,WAAY,CAAA,IAAI;GACrDS,IAAgB,kBAACT,GAAD,EAAW,aAAY,aAAc,CAAA,IAAI;GACzDQ,KAAeC,IACf,kBAACX,EAAoB,QAArB,EAA4B,aAAU,qBAAsB,CAAA,IACzD;EACqB;;AAE5B,CACD;AACA,EAAW,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"section-rule.js","names":[],"sources":["../../src/components/section-rule.tsx"],"sourcesContent":["import { Info } from \"lucide-react\";\nimport type { HTMLAttributes, ReactNode } 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 SectionRuleProps = Omit<HTMLAttributes<HTMLElement>, \"title\"> & {\n\t/** Section title shown before the dashed rule. */\n\ttitle: ReactNode;\n\t/** Info tooltip beside the title. */\n\thint?: ReactNode;\n\t/** Actions on the right of the dashed rule. */\n\tactions?: ReactNode;\n};\n\nexport function SectionRule({\n\ttitle,\n\thint,\n\tactions,\n\tclassName,\n\tchildren,\n\t...props\n}: SectionRuleProps) {\n\treturn (\n\t\t<section className={cn(BASALT_UI_CLASS, \"space-y-3\", className)} {...props}>\n\t\t\t<div className=\"flex flex-wrap items-center gap-3\">\n\t\t\t\t<div className=\"flex min-w-0 items-center gap-1.5\">\n\t\t\t\t\t<h2 className=\"text-xs font-medium tracking-wider text-basalt-muted-foreground uppercase\">\n\t\t\t\t\t\t{title}\n\t\t\t\t\t</h2>\n\t\t\t\t\t{hint ? (\n\t\t\t\t\t\t<TooltipProvider>\n\t\t\t\t\t\t\t<Tooltip>\n\t\t\t\t\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\taria-label=\"More information\"\n\t\t\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\t\t>\n\t\t\t\t\t\t\t\t\t\t<Info className=\"size-3.5\" />\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</TooltipTrigger>\n\t\t\t\t\t\t\t\t<TooltipContent>{hint}</TooltipContent>\n\t\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t</TooltipProvider>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t\t<div\n\t\t\t\t\tclassName=\"h-px min-w-4 flex-1 border-t border-dashed border-basalt-border\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t/>\n\t\t\t\t{actions ? (\n\t\t\t\t\t<div className=\"flex min-w-0 max-w-full shrink-0 flex-wrap items-center justify-end gap-2\">\n\t\t\t\t\t\t{actions}\n\t\t\t\t\t</div>\n\t\t\t\t) : null}\n\t\t\t</div>\n\t\t\t{children}\n\t\t</section>\n\t);\n}\n"],"mappings":";;;;;;;AAeA,
|
|
1
|
+
{"version":3,"file":"section-rule.js","names":["SectionRule","props","cn","BASALT_UI_CLASS","className","title","hint","TooltipProvider","Tooltip","TooltipTrigger","Info","TooltipContent","actions","children"],"sources":["../../src/components/section-rule.tsx"],"sourcesContent":["import { Info } from \"lucide-react\";\nimport type { HTMLAttributes, ReactNode } 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 SectionRuleProps = Omit<HTMLAttributes<HTMLElement>, \"title\"> & {\n\t/** Section title shown before the dashed rule. */\n\ttitle: ReactNode;\n\t/** Info tooltip beside the title. */\n\thint?: ReactNode;\n\t/** Actions on the right of the dashed rule. */\n\tactions?: ReactNode;\n};\n\nexport function SectionRule({\n\ttitle,\n\thint,\n\tactions,\n\tclassName,\n\tchildren,\n\t...props\n}: SectionRuleProps) {\n\treturn (\n\t\t<section className={cn(BASALT_UI_CLASS, \"space-y-3\", className)} {...props}>\n\t\t\t<div className=\"flex flex-wrap items-center gap-3\">\n\t\t\t\t<div className=\"flex min-w-0 items-center gap-1.5\">\n\t\t\t\t\t<h2 className=\"text-xs font-medium tracking-wider text-basalt-muted-foreground uppercase\">\n\t\t\t\t\t\t{title}\n\t\t\t\t\t</h2>\n\t\t\t\t\t{hint ? (\n\t\t\t\t\t\t<TooltipProvider>\n\t\t\t\t\t\t\t<Tooltip>\n\t\t\t\t\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\taria-label=\"More information\"\n\t\t\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\t\t>\n\t\t\t\t\t\t\t\t\t\t<Info className=\"size-3.5\" />\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</TooltipTrigger>\n\t\t\t\t\t\t\t\t<TooltipContent>{hint}</TooltipContent>\n\t\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t</TooltipProvider>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t\t<div\n\t\t\t\t\tclassName=\"h-px min-w-4 flex-1 border-t border-dashed border-basalt-border\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t/>\n\t\t\t\t{actions ? (\n\t\t\t\t\t<div className=\"flex min-w-0 max-w-full shrink-0 flex-wrap items-center justify-end gap-2\">\n\t\t\t\t\t\t{actions}\n\t\t\t\t\t</div>\n\t\t\t\t) : null}\n\t\t\t</div>\n\t\t\t{children}\n\t\t</section>\n\t);\n}\n"],"mappings":";;;;;;;AAeA,SAAgBA,EAAY,EAC3B,UACA,SACA,YACA,cACA,aACA,GAAGC,KACiB;CACpB,OACC,kBAAC,WAAD;EAAS,WAAWC,EAAGC,GAAiB,aAAaC,CAAS;EAAG,GAAIH;EAArE,UAAA,CACC,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA;IACC,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACC,kBAAC,MAAD;MAAI,WAAU;MACZ,UAAAI;KACE,CAAA,GACHC,IACA,kBAACC,GAAD,EAAA,UACC,kBAACC,GAAD,EAAA,UAAA,CACC,kBAACC,GAAD;MAAgB,SAAA;MACf,UAAA,kBAAC,UAAD;OACC,MAAK;OACL,cAAW;OACX,WAAU;OAEV,UAAA,kBAACC,GAAD,EAAM,WAAU,WAAY,CAAA;MACrB,CAAA;KACO,CAAA,GAChB,kBAACC,GAAD,EAAA,UAAiBL,EAAqB,CAAA,CAC9B,EAAA,CAAA,EACO,CAAA,IACd,IACA;;IACL,kBAAC,OAAD;KACC,WAAU;KACV,eAAY;IACZ,CAAA;IACAM,IACA,kBAAC,OAAD;KAAK,WAAU;KACb,UAAAA;IACG,CAAA,IACF;GACA;EACJ,CAAA,GAAAC,CACO;;AAEX"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"segment-control.js","names":[],"sources":["../../src/components/segment-control.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { ToggleGroup, ToggleGroupItem } from \"./toggle-group\";\n\nexport interface SegmentControlOption {\n\t/** The value selected when this segment is activated. */\n\tvalue: string;\n\t/** The visible label for the segment. */\n\tlabel: React.ReactNode;\n\t/** Disable only this segment. */\n\tdisabled?: boolean;\n}\n\nexport interface SegmentControlAllOption {\n\t/** The value representing the unfiltered selection. */\n\tvalue: string;\n\t/** The visible label for the leading segment. */\n\tlabel?: React.ReactNode;\n\t/** Disable only the leading segment. */\n\tdisabled?: boolean;\n}\n\nexport interface SegmentControlProps\n\textends Omit<React.HTMLAttributes<HTMLFieldSetElement>, \"children\" | \"onChange\"> {\n\t/** The currently selected value. */\n\tvalue: string;\n\t/** Called when the user selects a different segment. */\n\tonValueChange: (value: string) => void;\n\t/** The visible legend that names the control. */\n\tlegend: React.ReactNode;\n\t/** The selectable segments shown after the optional All segment. */\n\toptions: readonly SegmentControlOption[];\n\t/** Add a leading unfiltered segment, labelled All by default. */\n\tallOption?: SegmentControlAllOption;\n\t/**\n\t * Disable every segment.\n\t * @default false\n\t */\n\tdisabled?: boolean;\n}\n\nexport const SegmentControl = React.forwardRef<HTMLFieldSetElement, SegmentControlProps>(\n\t(\n\t\t{ allOption, className, disabled = false, legend, onValueChange, options, value, ...props },\n\t\tref,\n\t) => {\n\t\tconst legendId = React.useId();\n\t\tconst items: readonly SegmentControlOption[] = allOption\n\t\t\t? [{ ...allOption, label: allOption.label ?? \"All\" }, ...options]\n\t\t\t: options;\n\n\t\treturn (\n\t\t\t<fieldset\n\t\t\t\tref={ref}\n\t\t\t\tdisabled={disabled}\n\t\t\t\tclassName={cn(\"min-w-0 border-0 p-0\", className)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<legend\n\t\t\t\t\tid={legendId}\n\t\t\t\t\tclassName=\"mb-2 block text-xs font-medium text-basalt-muted-foreground\"\n\t\t\t\t>\n\t\t\t\t\t{legend}\n\t\t\t\t</legend>\n\t\t\t\t<div data-slot=\"segment-control-viewport\" className=\"max-w-full overflow-x-auto pb-1\">\n\t\t\t\t\t<ToggleGroup\n\t\t\t\t\t\ttype=\"single\"\n\t\t\t\t\t\tvalue={value}\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tonValueChange={(nextValue) => {\n\t\t\t\t\t\t\tif (nextValue) {\n\t\t\t\t\t\t\t\tonValueChange(nextValue);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t\taria-labelledby={legendId}\n\t\t\t\t\t\tclassName=\"w-max\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{items.map((item) => (\n\t\t\t\t\t\t\t<ToggleGroupItem key={item.value} value={item.value} disabled={item.disabled}>\n\t\t\t\t\t\t\t\t{item.label}\n\t\t\t\t\t\t\t</ToggleGroupItem>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ToggleGroup>\n\t\t\t\t</div>\n\t\t\t</fieldset>\n\t\t);\n\t},\n);\nSegmentControl.displayName = \"SegmentControl\";\n"],"mappings":";;;;;;AAyCA,
|
|
1
|
+
{"version":3,"file":"segment-control.js","names":["React","SegmentControl","props","legendId","items","allOption","options","cn","className","legend","ToggleGroup","nextValue","onValueChange","ToggleGroupItem","item"],"sources":["../../src/components/segment-control.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { ToggleGroup, ToggleGroupItem } from \"./toggle-group\";\n\nexport interface SegmentControlOption {\n\t/** The value selected when this segment is activated. */\n\tvalue: string;\n\t/** The visible label for the segment. */\n\tlabel: React.ReactNode;\n\t/** Disable only this segment. */\n\tdisabled?: boolean;\n}\n\nexport interface SegmentControlAllOption {\n\t/** The value representing the unfiltered selection. */\n\tvalue: string;\n\t/** The visible label for the leading segment. */\n\tlabel?: React.ReactNode;\n\t/** Disable only the leading segment. */\n\tdisabled?: boolean;\n}\n\nexport interface SegmentControlProps\n\textends Omit<React.HTMLAttributes<HTMLFieldSetElement>, \"children\" | \"onChange\"> {\n\t/** The currently selected value. */\n\tvalue: string;\n\t/** Called when the user selects a different segment. */\n\tonValueChange: (value: string) => void;\n\t/** The visible legend that names the control. */\n\tlegend: React.ReactNode;\n\t/** The selectable segments shown after the optional All segment. */\n\toptions: readonly SegmentControlOption[];\n\t/** Add a leading unfiltered segment, labelled All by default. */\n\tallOption?: SegmentControlAllOption;\n\t/**\n\t * Disable every segment.\n\t * @default false\n\t */\n\tdisabled?: boolean;\n}\n\nexport const SegmentControl = React.forwardRef<HTMLFieldSetElement, SegmentControlProps>(\n\t(\n\t\t{ allOption, className, disabled = false, legend, onValueChange, options, value, ...props },\n\t\tref,\n\t) => {\n\t\tconst legendId = React.useId();\n\t\tconst items: readonly SegmentControlOption[] = allOption\n\t\t\t? [{ ...allOption, label: allOption.label ?? \"All\" }, ...options]\n\t\t\t: options;\n\n\t\treturn (\n\t\t\t<fieldset\n\t\t\t\tref={ref}\n\t\t\t\tdisabled={disabled}\n\t\t\t\tclassName={cn(\"min-w-0 border-0 p-0\", className)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<legend\n\t\t\t\t\tid={legendId}\n\t\t\t\t\tclassName=\"mb-2 block text-xs font-medium text-basalt-muted-foreground\"\n\t\t\t\t>\n\t\t\t\t\t{legend}\n\t\t\t\t</legend>\n\t\t\t\t<div data-slot=\"segment-control-viewport\" className=\"max-w-full overflow-x-auto pb-1\">\n\t\t\t\t\t<ToggleGroup\n\t\t\t\t\t\ttype=\"single\"\n\t\t\t\t\t\tvalue={value}\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tonValueChange={(nextValue) => {\n\t\t\t\t\t\t\tif (nextValue) {\n\t\t\t\t\t\t\t\tonValueChange(nextValue);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t\taria-labelledby={legendId}\n\t\t\t\t\t\tclassName=\"w-max\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{items.map((item) => (\n\t\t\t\t\t\t\t<ToggleGroupItem key={item.value} value={item.value} disabled={item.disabled}>\n\t\t\t\t\t\t\t\t{item.label}\n\t\t\t\t\t\t\t</ToggleGroupItem>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ToggleGroup>\n\t\t\t\t</div>\n\t\t\t</fieldset>\n\t\t);\n\t},\n);\nSegmentControl.displayName = \"SegmentControl\";\n"],"mappings":";;;;;;AAyCA,IAAaC,IAAiBD,EAAM,YAElC,EAAE,cAAW,cAAW,cAAW,IAAO,WAAQ,kBAAe,YAAS,UAAO,GAAGE,KACpF,MACI;CACJ,IAAMC,IAAWH,EAAM,MAAM,GACvBI,IAAyCC,IAC5C,CAAC;EAAE,GAAGA;EAAW,OAAOA,EAAU,SAAS;CAAM,GAAG,GAAGC,CAAO,IAC9DA;CAEH,OACC,kBAAC,YAAD;EACM;EACK;EACV,WAAWC,EAAG,wBAAwBC,CAAS;EAC/C,GAAIN;EAJL,UAAA,CAMC,kBAAC,UAAD;GACC,IAAIC;GACJ,WAAU;GAET,UAAAM;EACM,CAAA,GACR,kBAAC,OAAD;GAAK,aAAU;GAA2B,WAAU;GACnD,UAAA,kBAACC,GAAD;IACC,MAAK;IACE;IACG;IACV,gBAAgB,MAAc;KAC7B,AAAIC,KACHC,EAAcD,CAAS;IAEzB;IACA,mBAAiBR;IACjB,WAAU;IAET,UAAAC,EAAM,KAAK,MACX,kBAACS,GAAD;KAAkC,OAAOC,EAAK;KAAO,UAAUA,EAAK;KAClE,UAAAA,EAAK;IACU,GAFKA,EAAK,KAEV,CACjB;GACW,CAAA;EACT,CAAA,CACI;;AAEZ,CACD;AACA,EAAe,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.js","names":[],"sources":["../../src/components/select.tsx"],"sourcesContent":["import * as SelectPrimitive from \"@radix-ui/react-select\";\nimport { Check, ChevronDown } from \"lucide-react\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { controlSurfaceClass } from \"../utils/control-surface\";\nimport { FOCUS_BORDER, OVERLAY_GAP, overlayItemClass, overlayPanelClass } from \"./overlay\";\n\nexport type SelectProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof SelectPrimitive.Root>,\n\t\"value\" | \"defaultValue\" | \"onValueChange\"\n> & {\n\t/**\n\t * The controlled value of the select.\n\t */\n\tvalue?: string;\n\t/**\n\t * The uncontrolled initial value of the select.\n\t */\n\tdefaultValue?: string;\n\t/**\n\t * Called when the selected value changes.\n\t */\n\tonValueChange?: (value: string) => void;\n};\nexport const Select: React.FC<SelectProps> = SelectPrimitive.Root;\n\nexport type SelectValueProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof SelectPrimitive.Value>,\n\t\"placeholder\"\n> & {\n\t/**\n\t * Content shown when no value is selected.\n\t */\n\tplaceholder?: React.ReactNode;\n};\nexport const SelectValue: React.ForwardRefExoticComponent<\n\tSelectValueProps & React.RefAttributes<React.ElementRef<typeof SelectPrimitive.Value>>\n> = SelectPrimitive.Value;\n\ntype RadixSelectGroupProps = React.ComponentPropsWithoutRef<typeof SelectPrimitive.Group>;\nexport type SelectGroupProps = Omit<RadixSelectGroupProps, \"asChild\"> & {\n\t/**\n\t * Change the default rendered div element to the child element, merging props and behavior.\n\t * Group forwards ref to HTMLDivElement and inherits native div attributes.\n\t * @default false\n\t */\n\tasChild?: RadixSelectGroupProps[\"asChild\"];\n};\nexport const SelectGroup: React.ForwardRefExoticComponent<\n\tSelectGroupProps & React.RefAttributes<React.ElementRef<typeof SelectPrimitive.Group>>\n> = SelectPrimitive.Group;\n\nexport type SelectSize = \"sm\" | \"default\" | \"lg\";\n\nconst SELECT_SIZE_CLASS: Record<SelectSize, string> = {\n\tsm: \"h-8 px-2.5 text-xs\",\n\tdefault: \"h-9 px-3 text-sm\",\n\tlg: \"h-10 px-4 text-base\",\n};\n\nexport type SelectTriggerProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>,\n\t\"disabled\"\n> & {\n\t/**\n\t * The visual size of the trigger.\n\t * @default default\n\t */\n\tsize?: SelectSize;\n\t/**\n\t * Disable the trigger and mark it busy.\n\t * @default false\n\t */\n\tloading?: boolean;\n\t/**\n\t * Disable the trigger.\n\t * @default false\n\t */\n\tdisabled?: boolean;\n};\n\nexport const SelectTrigger = React.forwardRef<\n\tReact.ElementRef<typeof SelectPrimitive.Trigger>,\n\tSelectTriggerProps\n>(({ className, children, size = \"default\", loading = false, disabled = false, ...props }, ref) => (\n\t<SelectPrimitive.Trigger\n\t\tref={ref}\n\t\t{...props}\n\t\tdisabled={disabled || loading}\n\t\taria-busy={loading || undefined}\n\t\tclassName={controlSurfaceClass(\n\t\t\tcn(\n\t\t\t\t\"flex w-full items-center justify-between\",\n\t\t\t\tSELECT_SIZE_CLASS[size],\n\t\t\t\tFOCUS_BORDER,\n\t\t\t\t\"aria-invalid:border-basalt-destructive aria-invalid:focus-visible:border-basalt-destructive\",\n\t\t\t\tclassName,\n\t\t\t),\n\t\t)}\n\t>\n\t\t{children}\n\t\t<ChevronDown className=\"h-4 w-4 opacity-50\" />\n\t</SelectPrimitive.Trigger>\n));\nSelectTrigger.displayName = SelectPrimitive.Trigger.displayName;\n\ntype RadixSelectLabelProps = React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>;\nexport type SelectLabelProps = Omit<RadixSelectLabelProps, \"asChild\"> & {\n\t/**\n\t * Change the default rendered div element to the child element, merging props and behavior.\n\t * Label forwards ref to HTMLDivElement and inherits native div attributes.\n\t * @default false\n\t */\n\tasChild?: RadixSelectLabelProps[\"asChild\"];\n};\n\nexport const SelectLabel = React.forwardRef<\n\tReact.ElementRef<typeof SelectPrimitive.Label>,\n\tSelectLabelProps\n>(({ className, ...props }, ref) => (\n\t<SelectPrimitive.Label\n\t\tref={ref}\n\t\tclassName={cn(\"px-2 py-1.5 text-xs text-basalt-muted-foreground\", className)}\n\t\t{...props}\n\t/>\n));\nSelectLabel.displayName = SelectPrimitive.Label.displayName;\n\nexport type SelectContentProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>,\n\t\"position\" | \"sideOffset\"\n> & {\n\t/**\n\t * The positioning mode for the select content.\n\t * @default popper\n\t */\n\tposition?: \"item-aligned\" | \"popper\";\n\t/**\n\t * The distance between the trigger and the select content.\n\t * @default 4\n\t */\n\tsideOffset?: number;\n};\n\nexport const SelectContent = React.forwardRef<\n\tReact.ElementRef<typeof SelectPrimitive.Content>,\n\tSelectContentProps\n>(({ className, children, position = \"popper\", sideOffset = OVERLAY_GAP, ...props }, ref) => (\n\t<SelectPrimitive.Portal>\n\t\t<SelectPrimitive.Content\n\t\t\tref={ref}\n\t\t\tposition={position}\n\t\t\tsideOffset={sideOffset}\n\t\t\tclassName={overlayPanelClass(\n\t\t\t\tcn(position === \"popper\" && \"w-[var(--radix-select-trigger-width)]\", className),\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<SelectPrimitive.Viewport>{children}</SelectPrimitive.Viewport>\n\t\t</SelectPrimitive.Content>\n\t</SelectPrimitive.Portal>\n));\nSelectContent.displayName = SelectPrimitive.Content.displayName;\n\nexport type SelectItemProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>,\n\t\"value\"\n> & {\n\t/**\n\t * The value associated with the select item.\n\t */\n\tvalue: string;\n};\n\nexport const SelectItem = React.forwardRef<\n\tReact.ElementRef<typeof SelectPrimitive.Item>,\n\tSelectItemProps\n>(({ className, children, ...props }, ref) => (\n\t<SelectPrimitive.Item\n\t\tref={ref}\n\t\tclassName={overlayItemClass(\n\t\t\tcn(\n\t\t\t\t\"relative pr-8 outline-hidden hover:bg-basalt-accent focus-visible:bg-basalt-accent data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[disabled]:hover:bg-transparent\",\n\t\t\t\tclassName,\n\t\t\t),\n\t\t)}\n\t\t{...props}\n\t>\n\t\t<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n\t\t<SelectPrimitive.ItemIndicator className=\"absolute right-2\">\n\t\t\t<Check className=\"h-3.5 w-3.5\" />\n\t\t</SelectPrimitive.ItemIndicator>\n\t</SelectPrimitive.Item>\n));\nSelectItem.displayName = SelectPrimitive.Item.displayName;\n"],"mappings":";;;;;;;;;AAwBA,
|
|
1
|
+
{"version":3,"file":"select.js","names":["React","SelectPrimitive","Select","SelectValue","SelectGroup","SELECT_SIZE_CLASS","SelectTrigger","props","disabled","loading","controlSurfaceClass","cn","size","FOCUS_BORDER","className","children","ChevronDown","SelectLabel","SelectContent","overlayPanelClass","position","SelectItem","overlayItemClass","Check"],"sources":["../../src/components/select.tsx"],"sourcesContent":["import * as SelectPrimitive from \"@radix-ui/react-select\";\nimport { Check, ChevronDown } from \"lucide-react\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { controlSurfaceClass } from \"../utils/control-surface\";\nimport { FOCUS_BORDER, OVERLAY_GAP, overlayItemClass, overlayPanelClass } from \"./overlay\";\n\nexport type SelectProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof SelectPrimitive.Root>,\n\t\"value\" | \"defaultValue\" | \"onValueChange\"\n> & {\n\t/**\n\t * The controlled value of the select.\n\t */\n\tvalue?: string;\n\t/**\n\t * The uncontrolled initial value of the select.\n\t */\n\tdefaultValue?: string;\n\t/**\n\t * Called when the selected value changes.\n\t */\n\tonValueChange?: (value: string) => void;\n};\nexport const Select: React.FC<SelectProps> = SelectPrimitive.Root;\n\nexport type SelectValueProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof SelectPrimitive.Value>,\n\t\"placeholder\"\n> & {\n\t/**\n\t * Content shown when no value is selected.\n\t */\n\tplaceholder?: React.ReactNode;\n};\nexport const SelectValue: React.ForwardRefExoticComponent<\n\tSelectValueProps & React.RefAttributes<React.ElementRef<typeof SelectPrimitive.Value>>\n> = SelectPrimitive.Value;\n\ntype RadixSelectGroupProps = React.ComponentPropsWithoutRef<typeof SelectPrimitive.Group>;\nexport type SelectGroupProps = Omit<RadixSelectGroupProps, \"asChild\"> & {\n\t/**\n\t * Change the default rendered div element to the child element, merging props and behavior.\n\t * Group forwards ref to HTMLDivElement and inherits native div attributes.\n\t * @default false\n\t */\n\tasChild?: RadixSelectGroupProps[\"asChild\"];\n};\nexport const SelectGroup: React.ForwardRefExoticComponent<\n\tSelectGroupProps & React.RefAttributes<React.ElementRef<typeof SelectPrimitive.Group>>\n> = SelectPrimitive.Group;\n\nexport type SelectSize = \"sm\" | \"default\" | \"lg\";\n\nconst SELECT_SIZE_CLASS: Record<SelectSize, string> = {\n\tsm: \"h-8 px-2.5 text-xs\",\n\tdefault: \"h-9 px-3 text-sm\",\n\tlg: \"h-10 px-4 text-base\",\n};\n\nexport type SelectTriggerProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>,\n\t\"disabled\"\n> & {\n\t/**\n\t * The visual size of the trigger.\n\t * @default default\n\t */\n\tsize?: SelectSize;\n\t/**\n\t * Disable the trigger and mark it busy.\n\t * @default false\n\t */\n\tloading?: boolean;\n\t/**\n\t * Disable the trigger.\n\t * @default false\n\t */\n\tdisabled?: boolean;\n};\n\nexport const SelectTrigger = React.forwardRef<\n\tReact.ElementRef<typeof SelectPrimitive.Trigger>,\n\tSelectTriggerProps\n>(({ className, children, size = \"default\", loading = false, disabled = false, ...props }, ref) => (\n\t<SelectPrimitive.Trigger\n\t\tref={ref}\n\t\t{...props}\n\t\tdisabled={disabled || loading}\n\t\taria-busy={loading || undefined}\n\t\tclassName={controlSurfaceClass(\n\t\t\tcn(\n\t\t\t\t\"flex w-full items-center justify-between\",\n\t\t\t\tSELECT_SIZE_CLASS[size],\n\t\t\t\tFOCUS_BORDER,\n\t\t\t\t\"aria-invalid:border-basalt-destructive aria-invalid:focus-visible:border-basalt-destructive\",\n\t\t\t\tclassName,\n\t\t\t),\n\t\t)}\n\t>\n\t\t{children}\n\t\t<ChevronDown className=\"h-4 w-4 opacity-50\" />\n\t</SelectPrimitive.Trigger>\n));\nSelectTrigger.displayName = SelectPrimitive.Trigger.displayName;\n\ntype RadixSelectLabelProps = React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>;\nexport type SelectLabelProps = Omit<RadixSelectLabelProps, \"asChild\"> & {\n\t/**\n\t * Change the default rendered div element to the child element, merging props and behavior.\n\t * Label forwards ref to HTMLDivElement and inherits native div attributes.\n\t * @default false\n\t */\n\tasChild?: RadixSelectLabelProps[\"asChild\"];\n};\n\nexport const SelectLabel = React.forwardRef<\n\tReact.ElementRef<typeof SelectPrimitive.Label>,\n\tSelectLabelProps\n>(({ className, ...props }, ref) => (\n\t<SelectPrimitive.Label\n\t\tref={ref}\n\t\tclassName={cn(\"px-2 py-1.5 text-xs text-basalt-muted-foreground\", className)}\n\t\t{...props}\n\t/>\n));\nSelectLabel.displayName = SelectPrimitive.Label.displayName;\n\nexport type SelectContentProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>,\n\t\"position\" | \"sideOffset\"\n> & {\n\t/**\n\t * The positioning mode for the select content.\n\t * @default popper\n\t */\n\tposition?: \"item-aligned\" | \"popper\";\n\t/**\n\t * The distance between the trigger and the select content.\n\t * @default 4\n\t */\n\tsideOffset?: number;\n};\n\nexport const SelectContent = React.forwardRef<\n\tReact.ElementRef<typeof SelectPrimitive.Content>,\n\tSelectContentProps\n>(({ className, children, position = \"popper\", sideOffset = OVERLAY_GAP, ...props }, ref) => (\n\t<SelectPrimitive.Portal>\n\t\t<SelectPrimitive.Content\n\t\t\tref={ref}\n\t\t\tposition={position}\n\t\t\tsideOffset={sideOffset}\n\t\t\tclassName={overlayPanelClass(\n\t\t\t\tcn(position === \"popper\" && \"w-[var(--radix-select-trigger-width)]\", className),\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<SelectPrimitive.Viewport>{children}</SelectPrimitive.Viewport>\n\t\t</SelectPrimitive.Content>\n\t</SelectPrimitive.Portal>\n));\nSelectContent.displayName = SelectPrimitive.Content.displayName;\n\nexport type SelectItemProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>,\n\t\"value\"\n> & {\n\t/**\n\t * The value associated with the select item.\n\t */\n\tvalue: string;\n};\n\nexport const SelectItem = React.forwardRef<\n\tReact.ElementRef<typeof SelectPrimitive.Item>,\n\tSelectItemProps\n>(({ className, children, ...props }, ref) => (\n\t<SelectPrimitive.Item\n\t\tref={ref}\n\t\tclassName={overlayItemClass(\n\t\t\tcn(\n\t\t\t\t\"relative pr-8 outline-hidden hover:bg-basalt-accent focus-visible:bg-basalt-accent data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[disabled]:hover:bg-transparent\",\n\t\t\t\tclassName,\n\t\t\t),\n\t\t)}\n\t\t{...props}\n\t>\n\t\t<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n\t\t<SelectPrimitive.ItemIndicator className=\"absolute right-2\">\n\t\t\t<Check className=\"h-3.5 w-3.5\" />\n\t\t</SelectPrimitive.ItemIndicator>\n\t</SelectPrimitive.Item>\n));\nSelectItem.displayName = SelectPrimitive.Item.displayName;\n"],"mappings":";;;;;;;;;AAwBA,IAAaE,IAAgCD,EAAgB,MAWhDE,IAETF,EAAgB,OAWPG,IAETH,EAAgB,OAIdI,IAAgD;CACrD,IAAI;CACJ,SAAS;CACT,IAAI;AACL,GAuBaC,IAAgBN,EAAM,YAGhC,EAAE,cAAW,aAAU,UAAO,WAAW,aAAU,IAAO,cAAW,IAAO,GAAGO,KAAS,MAC1F,kBAACN,EAAgB,SAAjB;CACM;CACL,GAAIM;CACJ,UAAUC,KAAYC;CACtB,aAAWA,KAAW,KAAA;CACtB,WAAWC,EACVC,EACC,4CACAN,EAAkBO,IAClBC,GACA,+FACAC,CACD,CACD;CAbD,UAAA,CAeEC,GACD,kBAACC,GAAD,EAAa,WAAU,qBAAsB,CAAA,CACrB;AACzB,CAAA,CAAA;AACD,EAAc,cAAcf,EAAgB,QAAQ;AAYpD,IAAagB,IAAcjB,EAAM,YAG9B,EAAE,cAAW,GAAGO,KAAS,MAC3B,kBAACN,EAAgB,OAAjB;CACM;CACL,WAAWU,EAAG,oDAAoDG,CAAS;CAC3E,GAAIP;AACJ,CAAA,CACD;AACD,EAAY,cAAcN,EAAgB,MAAM;AAkBhD,IAAaiB,IAAgBlB,EAAM,YAGhC,EAAE,cAAW,aAAU,cAAW,UAAU,gBAAA,GAA0B,GAAGO,KAAS,MACpF,kBAACN,EAAgB,QAAjB,EAAA,UACC,kBAACA,EAAgB,SAAjB;CACM;CACK;CACE;CACZ,WAAWkB,EACVR,EAAGS,MAAa,YAAY,yCAAyCN,CAAS,CAC/E;CACA,GAAIP;CAEJ,UAAA,kBAACN,EAAgB,UAAjB,EAA2B,YAAmC,CAAA;AACtC,CAAA,EACF,CAAA,CACxB;AACD,EAAc,cAAcA,EAAgB,QAAQ;AAYpD,IAAaoB,IAAarB,EAAM,YAG7B,EAAE,cAAW,aAAU,GAAGO,KAAS,MACrC,kBAACN,EAAgB,MAAjB;CACM;CACL,WAAWqB,EACVX,EACC,0LACAG,CACD,CACD;CACA,GAAIP;CARL,UAAA,CAUC,kBAACN,EAAgB,UAAjB,EAA2B,YAAmC,CAAA,GAC9D,kBAACA,EAAgB,eAAjB;EAA+B,WAAU;EACxC,UAAA,kBAACsB,GAAD,EAAO,WAAU,cAAe,CAAA;CACF,CAAA,CACV;AACtB,CAAA,CAAA;AACD,EAAW,cAActB,EAAgB,KAAK"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sensitive-input.js","names":[],"sources":["../../src/components/sensitive-input.tsx"],"sourcesContent":["import { Eye, EyeOff } from \"lucide-react\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { Button } from \"./button\";\nimport { Input, type InputSize } from \"./input\";\n\nconst TOGGLE_SIZE_CLASS: Record<InputSize, string> = {\n\tsm: \"h-8 w-8\",\n\tdefault: \"h-9 w-9\",\n\tlg: \"h-10 w-10\",\n};\n\nexport type SensitiveInputProps = Omit<React.ComponentProps<\"input\">, \"type\" | \"size\"> & {\n\t/**\n\t * Accessible label for the reveal action.\n\t */\n\trevealLabel: string;\n\t/**\n\t * Accessible label for the hide action.\n\t */\n\thideLabel: string;\n\t/**\n\t * The visual size of the field.\n\t * @default default\n\t */\n\tsize?: InputSize;\n\t/**\n\t * Ignore password managers on this field.\n\t * @default false\n\t */\n\tpasswordManagerIgnore?: boolean;\n};\n\nexport const SensitiveInput = React.forwardRef<HTMLInputElement, SensitiveInputProps>(\n\t(\n\t\t{\n\t\t\tclassName,\n\t\t\trevealLabel,\n\t\t\thideLabel,\n\t\t\tdisabled,\n\t\t\tsize = \"default\",\n\t\t\tpasswordManagerIgnore = false,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst [revealed, setRevealed] = React.useState(false);\n\t\treturn (\n\t\t\t<div className=\"relative\">\n\t\t\t\t<Input\n\t\t\t\t\tref={ref}\n\t\t\t\t\ttype={revealed ? \"text\" : \"password\"}\n\t\t\t\t\tsize={size}\n\t\t\t\t\tpasswordManagerIgnore={passwordManagerIgnore}\n\t\t\t\t\tclassName={cn(\"pr-10\", className)}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t{...props}\n\t\t\t\t/>\n\t\t\t\t<Button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\tclassName={cn(\"absolute right-0 top-0\", TOGGLE_SIZE_CLASS[size])}\n\t\t\t\t\taria-label={revealed ? hideLabel : revealLabel}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tonClick={() => setRevealed((value) => !value)}\n\t\t\t\t>\n\t\t\t\t\t{revealed ? (\n\t\t\t\t\t\t<EyeOff className=\"h-4 w-4\" aria-hidden=\"true\" />\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<Eye className=\"h-4 w-4\" aria-hidden=\"true\" />\n\t\t\t\t\t)}\n\t\t\t\t</Button>\n\t\t\t</div>\n\t\t);\n\t},\n);\nSensitiveInput.displayName = \"SensitiveInput\";\n"],"mappings":";;;;;;;;AAMA,
|
|
1
|
+
{"version":3,"file":"sensitive-input.js","names":["React","TOGGLE_SIZE_CLASS","SensitiveInput","props","revealed","setRevealed","Input","cn","className","Button","size","hideLabel","revealLabel","value","jsx","EyeOff","Eye"],"sources":["../../src/components/sensitive-input.tsx"],"sourcesContent":["import { Eye, EyeOff } from \"lucide-react\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { Button } from \"./button\";\nimport { Input, type InputSize } from \"./input\";\n\nconst TOGGLE_SIZE_CLASS: Record<InputSize, string> = {\n\tsm: \"h-8 w-8\",\n\tdefault: \"h-9 w-9\",\n\tlg: \"h-10 w-10\",\n};\n\nexport type SensitiveInputProps = Omit<React.ComponentProps<\"input\">, \"type\" | \"size\"> & {\n\t/**\n\t * Accessible label for the reveal action.\n\t */\n\trevealLabel: string;\n\t/**\n\t * Accessible label for the hide action.\n\t */\n\thideLabel: string;\n\t/**\n\t * The visual size of the field.\n\t * @default default\n\t */\n\tsize?: InputSize;\n\t/**\n\t * Ignore password managers on this field.\n\t * @default false\n\t */\n\tpasswordManagerIgnore?: boolean;\n};\n\nexport const SensitiveInput = React.forwardRef<HTMLInputElement, SensitiveInputProps>(\n\t(\n\t\t{\n\t\t\tclassName,\n\t\t\trevealLabel,\n\t\t\thideLabel,\n\t\t\tdisabled,\n\t\t\tsize = \"default\",\n\t\t\tpasswordManagerIgnore = false,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst [revealed, setRevealed] = React.useState(false);\n\t\treturn (\n\t\t\t<div className=\"relative\">\n\t\t\t\t<Input\n\t\t\t\t\tref={ref}\n\t\t\t\t\ttype={revealed ? \"text\" : \"password\"}\n\t\t\t\t\tsize={size}\n\t\t\t\t\tpasswordManagerIgnore={passwordManagerIgnore}\n\t\t\t\t\tclassName={cn(\"pr-10\", className)}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t{...props}\n\t\t\t\t/>\n\t\t\t\t<Button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\tclassName={cn(\"absolute right-0 top-0\", TOGGLE_SIZE_CLASS[size])}\n\t\t\t\t\taria-label={revealed ? hideLabel : revealLabel}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tonClick={() => setRevealed((value) => !value)}\n\t\t\t\t>\n\t\t\t\t\t{revealed ? (\n\t\t\t\t\t\t<EyeOff className=\"h-4 w-4\" aria-hidden=\"true\" />\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<Eye className=\"h-4 w-4\" aria-hidden=\"true\" />\n\t\t\t\t\t)}\n\t\t\t\t</Button>\n\t\t\t</div>\n\t\t);\n\t},\n);\nSensitiveInput.displayName = \"SensitiveInput\";\n"],"mappings":";;;;;;;;AAMA,IAAMC,IAA+C;CACpD,IAAI;CACJ,SAAS;CACT,IAAI;AACL,GAuBaC,IAAiBF,EAAM,YAElC,EACC,cACA,gBACA,cACA,aACA,UAAO,WACP,2BAAwB,IACxB,GAAGG,KAEJ,MACI;CACJ,IAAM,CAACC,GAAUC,KAAeL,EAAM,SAAS,EAAK;CACpD,OACC,kBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACC,kBAACM,GAAD;GACM;GACL,MAAMF,IAAW,SAAS;GACpB;GACiB;GACvB,WAAWG,EAAG,SAASC,CAAS;GACtB;GACV,GAAIL;EACJ,CAAA,GACD,kBAACM,GAAD;GACC,MAAK;GACL,SAAQ;GACR,WAAWF,EAAG,0BAA0BN,EAAkBS,EAAK;GAC/D,cAAYN,IAAWO,IAAYC;GACzB;GACV,eAAeP,GAAa,MAAU,CAACQ,CAAK;GAE3C,UACAC,EADAV,IACCW,IAEAC,GAFD;IAAQ,WAAU;IAAU,eAAY;GAAQ,CAEH;EAEvC,CAAA,CACJ;;AAEP,CACD;AACA,EAAe,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"separator.js","names":[],"sources":["../../src/components/separator.tsx"],"sourcesContent":["import * as SeparatorPrimitive from \"@radix-ui/react-separator\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport type SeparatorProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>,\n\t\"orientation\" | \"decorative\"\n> & {\n\t/**\n\t * The orientation of the separator.\n\t * @default horizontal\n\t */\n\torientation?: \"horizontal\" | \"vertical\";\n\t/**\n\t * Whether the separator is purely decorative.\n\t * @default true\n\t */\n\tdecorative?: boolean;\n};\n\nexport const Separator = React.forwardRef<\n\tReact.ElementRef<typeof SeparatorPrimitive.Root>,\n\tSeparatorProps\n>(({ className, orientation = \"horizontal\", decorative = true, ...props }, ref) => (\n\t<SeparatorPrimitive.Root\n\t\tref={ref}\n\t\tdecorative={decorative}\n\t\torientation={orientation}\n\t\tclassName={cn(\n\t\t\t\"shrink-0 bg-basalt-border\",\n\t\t\torientation === \"horizontal\" ? \"h-px w-full\" : \"h-full w-px\",\n\t\t\tclassName,\n\t\t)}\n\t\t{...props}\n\t/>\n));\nSeparator.displayName = SeparatorPrimitive.Root.displayName;\n"],"mappings":";;;;;;AAoBA,
|
|
1
|
+
{"version":3,"file":"separator.js","names":["React","SeparatorPrimitive","Separator","props","cn","orientation","className"],"sources":["../../src/components/separator.tsx"],"sourcesContent":["import * as SeparatorPrimitive from \"@radix-ui/react-separator\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport type SeparatorProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>,\n\t\"orientation\" | \"decorative\"\n> & {\n\t/**\n\t * The orientation of the separator.\n\t * @default horizontal\n\t */\n\torientation?: \"horizontal\" | \"vertical\";\n\t/**\n\t * Whether the separator is purely decorative.\n\t * @default true\n\t */\n\tdecorative?: boolean;\n};\n\nexport const Separator = React.forwardRef<\n\tReact.ElementRef<typeof SeparatorPrimitive.Root>,\n\tSeparatorProps\n>(({ className, orientation = \"horizontal\", decorative = true, ...props }, ref) => (\n\t<SeparatorPrimitive.Root\n\t\tref={ref}\n\t\tdecorative={decorative}\n\t\torientation={orientation}\n\t\tclassName={cn(\n\t\t\t\"shrink-0 bg-basalt-border\",\n\t\t\torientation === \"horizontal\" ? \"h-px w-full\" : \"h-full w-px\",\n\t\t\tclassName,\n\t\t)}\n\t\t{...props}\n\t/>\n));\nSeparator.displayName = SeparatorPrimitive.Root.displayName;\n"],"mappings":";;;;;;AAoBA,IAAaE,IAAYF,EAAM,YAG5B,EAAE,cAAW,iBAAc,cAAc,gBAAa,IAAM,GAAGG,KAAS,MAC1E,kBAACF,EAAmB,MAApB;CACM;CACO;CACC;CACb,WAAWG,EACV,6BACAC,MAAgB,eAAe,gBAAgB,eAC/CC,CACD;CACA,GAAIH;AACJ,CAAA,CACD;AACD,EAAU,cAAcF,EAAmB,KAAK"}
|
package/dist/components/sheet.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sheet.js","names":[],"sources":["../../src/components/sheet.tsx"],"sourcesContent":["import * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { OVERLAY_LAYER, OVERLAY_MOTION } from \"./overlay\";\n\ntype RadixDialogProps = React.ComponentPropsWithoutRef<typeof DialogPrimitive.Root>;\ntype RadixDialogTriggerProps = React.ComponentPropsWithoutRef<typeof DialogPrimitive.Trigger>;\ntype RadixDialogCloseProps = React.ComponentPropsWithoutRef<typeof DialogPrimitive.Close>;\ntype RadixDialogContentProps = React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>;\ntype RadixDialogTitleProps = React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>;\ntype RadixDialogDescriptionProps = React.ComponentPropsWithoutRef<\n\ttypeof DialogPrimitive.Description\n>;\n\nexport interface SheetProps\n\textends Omit<RadixDialogProps, \"open\" | \"defaultOpen\" | \"onOpenChange\" | \"modal\"> {\n\t/**\n\t * Controlled open state of the sheet drawer.\n\t */\n\topen?: RadixDialogProps[\"open\"];\n\t/**\n\t * Uncontrolled default open state of the sheet on initial render.\n\t * @default false\n\t */\n\tdefaultOpen?: RadixDialogProps[\"defaultOpen\"];\n\t/**\n\t * Callback invoked when the open state changes.\n\t */\n\tonOpenChange?: RadixDialogProps[\"onOpenChange\"];\n\t/**\n\t * Whether the sheet renders modally, preventing outside interaction and hiding background content from screen readers.\n\t * @default true\n\t */\n\tmodal?: RadixDialogProps[\"modal\"];\n}\n\nexport const Sheet: React.FC<SheetProps> = DialogPrimitive.Root;\n\nexport interface SheetTriggerProps extends Omit<RadixDialogTriggerProps, \"asChild\"> {\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?: RadixDialogTriggerProps[\"asChild\"];\n}\n\nexport const SheetTrigger = DialogPrimitive.Trigger;\n\nexport interface SheetCloseProps extends Omit<RadixDialogCloseProps, \"asChild\"> {\n\t/**\n\t * Change the default rendered button element to the child element, merging props and behavior.\n\t * Close forwards ref to HTMLButtonElement and inherits native button attributes.\n\t * @default false\n\t */\n\tasChild?: RadixDialogCloseProps[\"asChild\"];\n}\n\nexport const SheetClose = DialogPrimitive.Close;\n\nexport interface SheetTitleProps extends Omit<RadixDialogTitleProps, \"asChild\"> {\n\t/**\n\t * Change the default rendered heading element to the child element, merging props and behavior.\n\t * Title forwards ref to HTMLHeadingElement and inherits native h2 attributes.\n\t * @default false\n\t */\n\tasChild?: RadixDialogTitleProps[\"asChild\"];\n}\n\nexport const SheetTitle = React.forwardRef<\n\tReact.ElementRef<typeof DialogPrimitive.Title>,\n\tSheetTitleProps\n>(({ className, ...props }, ref) => (\n\t<DialogPrimitive.Title\n\t\tref={ref}\n\t\tclassName={cn(\"text-lg font-semibold leading-none tracking-tight\", className)}\n\t\t{...props}\n\t/>\n));\nSheetTitle.displayName = DialogPrimitive.Title.displayName;\n\nexport interface SheetDescriptionProps extends Omit<RadixDialogDescriptionProps, \"asChild\"> {\n\t/**\n\t * Change the default rendered paragraph element to the child element, merging props and behavior.\n\t * Description forwards ref to HTMLParagraphElement and inherits native p attributes.\n\t * @default false\n\t */\n\tasChild?: RadixDialogDescriptionProps[\"asChild\"];\n}\n\nexport const SheetDescription = React.forwardRef<\n\tReact.ElementRef<typeof DialogPrimitive.Description>,\n\tSheetDescriptionProps\n>(({ className, ...props }, ref) => (\n\t<DialogPrimitive.Description\n\t\tref={ref}\n\t\tclassName={cn(\"text-sm text-basalt-muted-foreground\", className)}\n\t\t{...props}\n\t/>\n));\nSheetDescription.displayName = DialogPrimitive.Description.displayName;\n\nconst SIDE = {\n\tright: `fixed inset-y-0 right-0 ${BASALT_UI_CLASS} flex h-full w-80 flex-col gap-3 border-l border-basalt-border p-6 text-sm text-basalt-foreground shadow-lg`,\n\tleft: `fixed inset-y-0 left-0 ${BASALT_UI_CLASS} flex h-full w-80 flex-col gap-3 border-r border-basalt-border p-6 text-sm text-basalt-foreground shadow-lg`,\n\ttop: `fixed inset-x-0 top-0 ${BASALT_UI_CLASS} flex h-80 w-full flex-col gap-3 border-b border-basalt-border p-6 text-sm text-basalt-foreground shadow-lg`,\n\tbottom: `fixed inset-x-0 bottom-0 ${BASALT_UI_CLASS} flex h-80 w-full flex-col gap-3 border-t border-basalt-border p-6 text-sm text-basalt-foreground shadow-lg`,\n} as const;\n\nexport type SheetSide = keyof typeof SIDE;\n\nexport interface SheetContentProps\n\textends Omit<\n\t\tRadixDialogContentProps,\n\t\t| \"side\"\n\t\t| \"asChild\"\n\t\t| \"forceMount\"\n\t\t| \"trapFocus\"\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 * Edge of the screen where the drawer panel is positioned and anchored.\n\t * @default \"right\"\n\t */\n\tside?: SheetSide;\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?: RadixDialogContentProps[\"asChild\"];\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?: RadixDialogContentProps[\"forceMount\"];\n\t/**\n\t * Event handler called when auto-focusing the first element on open. Can be prevented with event.preventDefault().\n\t */\n\tonOpenAutoFocus?: RadixDialogContentProps[\"onOpenAutoFocus\"];\n\t/**\n\t * Event handler called when restoring focus on close. Can be prevented with event.preventDefault().\n\t */\n\tonCloseAutoFocus?: RadixDialogContentProps[\"onCloseAutoFocus\"];\n\t/**\n\t * Event handler called when the Escape key is pressed. Can be prevented with event.preventDefault().\n\t */\n\tonEscapeKeyDown?: RadixDialogContentProps[\"onEscapeKeyDown\"];\n\t/**\n\t * Event handler called when a pointer event occurs outside the sheet bounds.\n\t */\n\tonPointerDownOutside?: RadixDialogContentProps[\"onPointerDownOutside\"];\n\t/**\n\t * Event handler called when focus moves outside the sheet bounds.\n\t */\n\tonFocusOutside?: RadixDialogContentProps[\"onFocusOutside\"];\n\t/**\n\t * Event handler called when any interaction (pointer or focus) occurs outside the sheet bounds.\n\t */\n\tonInteractOutside?: RadixDialogContentProps[\"onInteractOutside\"];\n}\n\nexport const SheetContent = React.forwardRef<\n\tReact.ElementRef<typeof DialogPrimitive.Content>,\n\tSheetContentProps\n>(({ className, side = \"right\", children, ...props }, ref) => (\n\t<DialogPrimitive.Portal forceMount={props.forceMount}>\n\t\t<DialogPrimitive.Overlay\n\t\t\tforceMount={props.forceMount}\n\t\t\tclassName={cn(\"fixed inset-0 bg-black/50 backdrop-blur-xs\", OVERLAY_LAYER, OVERLAY_MOTION)}\n\t\t/>\n\t\t<DialogPrimitive.Content\n\t\t\tref={ref}\n\t\t\tdata-basalt-surface-root=\"\"\n\t\t\tclassName={cn(OVERLAY_LAYER, OVERLAY_MOTION, SIDE[side], className)}\n\t\t\t{...props}\n\t\t\tstyle={{ boxSizing: \"border-box\", ...props.style }}\n\t\t>\n\t\t\t{children}\n\t\t</DialogPrimitive.Content>\n\t</DialogPrimitive.Portal>\n));\nSheetContent.displayName = \"SheetContent\";\n\nexport interface SheetHeaderProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nexport const SheetHeader = ({ className, ...props }: SheetHeaderProps) => (\n\t<div className={cn(\"flex flex-col space-y-2 text-left\", className)} {...props} />\n);\nSheetHeader.displayName = \"SheetHeader\";\n\nexport interface SheetFooterProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nexport const SheetFooter = ({ className, ...props }: SheetFooterProps) => (\n\t<div\n\t\tclassName={cn(\"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\", className)}\n\t\t{...props}\n\t/>\n);\nSheetFooter.displayName = \"SheetFooter\";\n"],"mappings":";;;;;;;;AAqCA,
|
|
1
|
+
{"version":3,"file":"sheet.js","names":["React","DialogPrimitive","Sheet","SheetTrigger","SheetClose","SheetTitle","props","cn","className","SheetDescription","SIDE","BASALT_UI_CLASS","SheetContent","OVERLAY_LAYER","OVERLAY_MOTION","side","SheetHeader","SheetFooter"],"sources":["../../src/components/sheet.tsx"],"sourcesContent":["import * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { OVERLAY_LAYER, OVERLAY_MOTION } from \"./overlay\";\n\ntype RadixDialogProps = React.ComponentPropsWithoutRef<typeof DialogPrimitive.Root>;\ntype RadixDialogTriggerProps = React.ComponentPropsWithoutRef<typeof DialogPrimitive.Trigger>;\ntype RadixDialogCloseProps = React.ComponentPropsWithoutRef<typeof DialogPrimitive.Close>;\ntype RadixDialogContentProps = React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>;\ntype RadixDialogTitleProps = React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>;\ntype RadixDialogDescriptionProps = React.ComponentPropsWithoutRef<\n\ttypeof DialogPrimitive.Description\n>;\n\nexport interface SheetProps\n\textends Omit<RadixDialogProps, \"open\" | \"defaultOpen\" | \"onOpenChange\" | \"modal\"> {\n\t/**\n\t * Controlled open state of the sheet drawer.\n\t */\n\topen?: RadixDialogProps[\"open\"];\n\t/**\n\t * Uncontrolled default open state of the sheet on initial render.\n\t * @default false\n\t */\n\tdefaultOpen?: RadixDialogProps[\"defaultOpen\"];\n\t/**\n\t * Callback invoked when the open state changes.\n\t */\n\tonOpenChange?: RadixDialogProps[\"onOpenChange\"];\n\t/**\n\t * Whether the sheet renders modally, preventing outside interaction and hiding background content from screen readers.\n\t * @default true\n\t */\n\tmodal?: RadixDialogProps[\"modal\"];\n}\n\nexport const Sheet: React.FC<SheetProps> = DialogPrimitive.Root;\n\nexport interface SheetTriggerProps extends Omit<RadixDialogTriggerProps, \"asChild\"> {\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?: RadixDialogTriggerProps[\"asChild\"];\n}\n\nexport const SheetTrigger = DialogPrimitive.Trigger;\n\nexport interface SheetCloseProps extends Omit<RadixDialogCloseProps, \"asChild\"> {\n\t/**\n\t * Change the default rendered button element to the child element, merging props and behavior.\n\t * Close forwards ref to HTMLButtonElement and inherits native button attributes.\n\t * @default false\n\t */\n\tasChild?: RadixDialogCloseProps[\"asChild\"];\n}\n\nexport const SheetClose = DialogPrimitive.Close;\n\nexport interface SheetTitleProps extends Omit<RadixDialogTitleProps, \"asChild\"> {\n\t/**\n\t * Change the default rendered heading element to the child element, merging props and behavior.\n\t * Title forwards ref to HTMLHeadingElement and inherits native h2 attributes.\n\t * @default false\n\t */\n\tasChild?: RadixDialogTitleProps[\"asChild\"];\n}\n\nexport const SheetTitle = React.forwardRef<\n\tReact.ElementRef<typeof DialogPrimitive.Title>,\n\tSheetTitleProps\n>(({ className, ...props }, ref) => (\n\t<DialogPrimitive.Title\n\t\tref={ref}\n\t\tclassName={cn(\"text-lg font-semibold leading-none tracking-tight\", className)}\n\t\t{...props}\n\t/>\n));\nSheetTitle.displayName = DialogPrimitive.Title.displayName;\n\nexport interface SheetDescriptionProps extends Omit<RadixDialogDescriptionProps, \"asChild\"> {\n\t/**\n\t * Change the default rendered paragraph element to the child element, merging props and behavior.\n\t * Description forwards ref to HTMLParagraphElement and inherits native p attributes.\n\t * @default false\n\t */\n\tasChild?: RadixDialogDescriptionProps[\"asChild\"];\n}\n\nexport const SheetDescription = React.forwardRef<\n\tReact.ElementRef<typeof DialogPrimitive.Description>,\n\tSheetDescriptionProps\n>(({ className, ...props }, ref) => (\n\t<DialogPrimitive.Description\n\t\tref={ref}\n\t\tclassName={cn(\"text-sm text-basalt-muted-foreground\", className)}\n\t\t{...props}\n\t/>\n));\nSheetDescription.displayName = DialogPrimitive.Description.displayName;\n\nconst SIDE = {\n\tright: `fixed inset-y-0 right-0 ${BASALT_UI_CLASS} flex h-full w-80 flex-col gap-3 border-l border-basalt-border p-6 text-sm text-basalt-foreground shadow-lg`,\n\tleft: `fixed inset-y-0 left-0 ${BASALT_UI_CLASS} flex h-full w-80 flex-col gap-3 border-r border-basalt-border p-6 text-sm text-basalt-foreground shadow-lg`,\n\ttop: `fixed inset-x-0 top-0 ${BASALT_UI_CLASS} flex h-80 w-full flex-col gap-3 border-b border-basalt-border p-6 text-sm text-basalt-foreground shadow-lg`,\n\tbottom: `fixed inset-x-0 bottom-0 ${BASALT_UI_CLASS} flex h-80 w-full flex-col gap-3 border-t border-basalt-border p-6 text-sm text-basalt-foreground shadow-lg`,\n} as const;\n\nexport type SheetSide = keyof typeof SIDE;\n\nexport interface SheetContentProps\n\textends Omit<\n\t\tRadixDialogContentProps,\n\t\t| \"side\"\n\t\t| \"asChild\"\n\t\t| \"forceMount\"\n\t\t| \"trapFocus\"\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 * Edge of the screen where the drawer panel is positioned and anchored.\n\t * @default \"right\"\n\t */\n\tside?: SheetSide;\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?: RadixDialogContentProps[\"asChild\"];\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?: RadixDialogContentProps[\"forceMount\"];\n\t/**\n\t * Event handler called when auto-focusing the first element on open. Can be prevented with event.preventDefault().\n\t */\n\tonOpenAutoFocus?: RadixDialogContentProps[\"onOpenAutoFocus\"];\n\t/**\n\t * Event handler called when restoring focus on close. Can be prevented with event.preventDefault().\n\t */\n\tonCloseAutoFocus?: RadixDialogContentProps[\"onCloseAutoFocus\"];\n\t/**\n\t * Event handler called when the Escape key is pressed. Can be prevented with event.preventDefault().\n\t */\n\tonEscapeKeyDown?: RadixDialogContentProps[\"onEscapeKeyDown\"];\n\t/**\n\t * Event handler called when a pointer event occurs outside the sheet bounds.\n\t */\n\tonPointerDownOutside?: RadixDialogContentProps[\"onPointerDownOutside\"];\n\t/**\n\t * Event handler called when focus moves outside the sheet bounds.\n\t */\n\tonFocusOutside?: RadixDialogContentProps[\"onFocusOutside\"];\n\t/**\n\t * Event handler called when any interaction (pointer or focus) occurs outside the sheet bounds.\n\t */\n\tonInteractOutside?: RadixDialogContentProps[\"onInteractOutside\"];\n}\n\nexport const SheetContent = React.forwardRef<\n\tReact.ElementRef<typeof DialogPrimitive.Content>,\n\tSheetContentProps\n>(({ className, side = \"right\", children, ...props }, ref) => (\n\t<DialogPrimitive.Portal forceMount={props.forceMount}>\n\t\t<DialogPrimitive.Overlay\n\t\t\tforceMount={props.forceMount}\n\t\t\tclassName={cn(\"fixed inset-0 bg-black/50 backdrop-blur-xs\", OVERLAY_LAYER, OVERLAY_MOTION)}\n\t\t/>\n\t\t<DialogPrimitive.Content\n\t\t\tref={ref}\n\t\t\tdata-basalt-sheet=\"\"\n\t\t\tdata-basalt-surface-root=\"\"\n\t\t\tclassName={cn(OVERLAY_LAYER, OVERLAY_MOTION, SIDE[side], className)}\n\t\t\t{...props}\n\t\t\tstyle={{ boxSizing: \"border-box\", ...props.style }}\n\t\t>\n\t\t\t{children}\n\t\t</DialogPrimitive.Content>\n\t</DialogPrimitive.Portal>\n));\nSheetContent.displayName = \"SheetContent\";\n\nexport interface SheetHeaderProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nexport const SheetHeader = ({ className, ...props }: SheetHeaderProps) => (\n\t<div className={cn(\"flex flex-col space-y-2 text-left\", className)} {...props} />\n);\nSheetHeader.displayName = \"SheetHeader\";\n\nexport interface SheetFooterProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nexport const SheetFooter = ({ className, ...props }: SheetFooterProps) => (\n\t<div\n\t\tclassName={cn(\"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\", className)}\n\t\t{...props}\n\t/>\n);\nSheetFooter.displayName = \"SheetFooter\";\n"],"mappings":";;;;;;;;AAqCA,IAAaE,IAA8BD,EAAgB,MAW9CE,IAAeF,EAAgB,SAW/BG,IAAaH,EAAgB,OAW7BI,IAAaL,EAAM,YAG7B,EAAE,cAAW,GAAGM,KAAS,MAC3B,kBAACL,EAAgB,OAAjB;CACM;CACL,WAAWM,EAAG,qDAAqDC,CAAS;CAC5E,GAAIF;AACJ,CAAA,CACD;AACD,EAAW,cAAcL,EAAgB,MAAM;AAW/C,IAAaQ,IAAmBT,EAAM,YAGnC,EAAE,cAAW,GAAGM,KAAS,MAC3B,kBAACL,EAAgB,aAAjB;CACM;CACL,WAAWM,EAAG,wCAAwCC,CAAS;CAC/D,GAAIF;AACJ,CAAA,CACD;AACD,EAAiB,cAAcL,EAAgB,YAAY;AAE3D,IAAMS,IAAO;CACZ,OAAO,2BAA2BC,EAAgB;CAClD,MAAM,0BAA0BA,EAAgB;CAChD,KAAK,yBAAyBA,EAAgB;CAC9C,QAAQ,4BAA4BA,EAAgB;AACrD,GA8DaC,IAAeZ,EAAM,YAG/B,EAAE,cAAW,UAAO,SAAS,aAAU,GAAGM,KAAS,MACrD,kBAACL,EAAgB,QAAjB;CAAwB,YAAYK,EAAM;CAA1C,UAAA,CACC,kBAACL,EAAgB,SAAjB;EACC,YAAYK,EAAM;EAClB,WAAWC,EAAG,8CAA8CM,GAAeC,CAAc;CACzF,CAAA,GACD,kBAACb,EAAgB,SAAjB;EACM;EACL,qBAAkB;EAClB,4BAAyB;EACzB,WAAWM,EAAGM,GAAeC,GAAgBJ,EAAKK,IAAOP,CAAS;EAClE,GAAIF;EACJ,OAAO;GAAE,WAAW;GAAc,GAAGA,EAAM;EAAM;EAEhD;CACuB,CAAA,CACF;AACxB,CAAA,CAAA;AACD,EAAa,cAAc;AAI3B,IAAaU,KAAe,EAAE,cAAW,GAAGV,QAC3C,kBAAC,OAAD;CAAK,WAAWC,EAAG,qCAAqCC,CAAS;CAAG,GAAIF;AAAQ,CAAA;AAEjF,EAAY,cAAc;AAI1B,IAAaW,KAAe,EAAE,cAAW,GAAGX,QAC3C,kBAAC,OAAD;CACC,WAAWC,EAAG,0DAA0DC,CAAS;CACjF,GAAIF;AACJ,CAAA;AAEF,EAAY,cAAc"}
|
|
@@ -189,5 +189,7 @@ export interface SidebarUserProps {
|
|
|
189
189
|
}
|
|
190
190
|
export declare function SidebarUser({ name, email, avatar, action, className }: SidebarUserProps): import("react").JSX.Element;
|
|
191
191
|
export interface ContentIslandProps extends HTMLAttributes<HTMLDivElement> {
|
|
192
|
+
/** Mobile surface treatment; desktop remains an inset L1 island. @default "inset" */
|
|
193
|
+
mobileSurface?: "inset" | "edge-to-edge";
|
|
192
194
|
}
|
|
193
|
-
export declare function ContentIsland({ className, ...props }: ContentIslandProps): import("react").JSX.Element;
|
|
195
|
+
export declare function ContentIsland({ mobileSurface, className, ...props }: ContentIslandProps): import("react").JSX.Element;
|
|
@@ -88,11 +88,12 @@ function D({ collapsed: s, className: c, children: l, onMouseEnter: d, onMouseLe
|
|
|
88
88
|
side: v,
|
|
89
89
|
width: g.width,
|
|
90
90
|
onWidth: g.setWidth
|
|
91
|
-
}) : null, O = e(t, "relative flex
|
|
91
|
+
}) : null, O = e(t, "relative flex shrink-0 flex-col bg-basalt-background text-sm text-basalt-foreground", r, c);
|
|
92
92
|
return C && g ? /* @__PURE__ */ y(i, {
|
|
93
93
|
open: !g.collapsed,
|
|
94
94
|
onOpenChange: (e) => g.setCollapsed(!e),
|
|
95
95
|
children: /* @__PURE__ */ b(o, { children: [/* @__PURE__ */ y(a, {}), /* @__PURE__ */ b(x.Content, {
|
|
96
|
+
"data-basalt-sidebar": "",
|
|
96
97
|
"aria-label": "Sidebar",
|
|
97
98
|
"data-overlay": "",
|
|
98
99
|
"data-side": v,
|
|
@@ -118,6 +119,7 @@ function D({ collapsed: s, className: c, children: l, onMouseEnter: d, onMouseLe
|
|
|
118
119
|
children: [T, D]
|
|
119
120
|
})] })
|
|
120
121
|
}) : /* @__PURE__ */ b("aside", {
|
|
122
|
+
"data-basalt-sidebar": "",
|
|
121
123
|
"data-collapsed": _ ? "" : void 0,
|
|
122
124
|
"data-side": v,
|
|
123
125
|
"aria-busy": g?.loading || void 0,
|
|
@@ -127,7 +129,7 @@ function D({ collapsed: s, className: c, children: l, onMouseEnter: d, onMouseLe
|
|
|
127
129
|
onMouseLeave: (e) => {
|
|
128
130
|
g?.peek && g.setPeeking(!1), f?.(e);
|
|
129
131
|
},
|
|
130
|
-
className: e(O, "sticky
|
|
132
|
+
className: e(O, "sticky transition-all duration-300 ease-in-out", v === "right" ? "order-last" : void 0, _ ? "w-[68px] overflow-y-hidden" : "overflow-hidden"),
|
|
131
133
|
style: _ ? m : {
|
|
132
134
|
width: w,
|
|
133
135
|
...m
|
|
@@ -249,11 +251,12 @@ function I({ name: t, email: n, avatar: r, action: i, className: a }) {
|
|
|
249
251
|
]
|
|
250
252
|
});
|
|
251
253
|
}
|
|
252
|
-
function L({
|
|
254
|
+
function L({ mobileSurface: t = "inset", className: n, ...r }) {
|
|
253
255
|
return /* @__PURE__ */ y("div", {
|
|
254
256
|
"data-basalt-surface-root": "",
|
|
255
|
-
|
|
256
|
-
|
|
257
|
+
"data-basalt-island": t,
|
|
258
|
+
className: e("min-h-0 min-w-0 flex-1 bg-basalt-card text-basalt-card-foreground md:rounded-basalt-island md:p-5", t === "inset" ? "rounded-[16px] p-3 shadow-sm ring-1 ring-basalt-border/40" : "md:shadow-sm md:ring-1 md:ring-basalt-border/40", n),
|
|
259
|
+
...r
|
|
257
260
|
});
|
|
258
261
|
}
|
|
259
262
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sidebar.js","names":[],"sources":["../../src/components/sidebar.tsx"],"sourcesContent":["import * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { ChevronUp, Search } from \"lucide-react\";\nimport {\n\ttype ButtonHTMLAttributes,\n\tcreateContext,\n\ttype HTMLAttributes,\n\ttype ReactNode,\n\ttype PointerEvent as ReactPointerEvent,\n\ttype RefObject,\n\tuseCallback,\n\tuseContext,\n\tuseLayoutEffect,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"./collapsible\";\nimport { Dialog, DialogOverlay, DialogPortal } from \"./dialog\";\nimport { OVERLAY_LAYER, OVERLAY_MOTION } from \"./overlay\";\nimport { SkeletonLine } from \"./skeleton-line\";\n\nexport type SidebarSide = \"left\" | \"right\";\n\nexport interface SidebarContextValue {\n\t/**\n\t * Whether the sidebar is currently collapsed.\n\t */\n\tcollapsed: boolean;\n\t/**\n\t * Callback to update the collapsed state.\n\t */\n\tsetCollapsed: (next: boolean) => void;\n\t/**\n\t * Which edge the sidebar occupies.\n\t */\n\tside: SidebarSide;\n\t/**\n\t * Whether the sidebar is currently displaying a loading skeleton.\n\t */\n\tloading: boolean;\n\t/**\n\t * Whether the sidebar rail expands on pointer hover.\n\t */\n\tpeek: boolean;\n\t/**\n\t * Whether the sidebar is actively hovering in peek preview mode.\n\t */\n\tpeeking: boolean;\n\t/**\n\t * Callback to update the peek preview state.\n\t */\n\tsetPeeking: (next: boolean) => void;\n\t/**\n\t * Whether the sidebar is rendering as a modal overlay drawer instead of in-flow layout chrome.\n\t */\n\toverlay: boolean;\n\t/**\n\t * Current expanded width in pixels, clamped between 180 and 400.\n\t */\n\twidth: number;\n\t/**\n\t * Callback to update the sidebar width. Value is clamped between 180 and 400 pixels.\n\t */\n\tsetWidth: (next: number) => void;\n\t/**\n\t * Reference to the last active element that held focus before opening the sidebar drawer.\n\t */\n\tlastFocusRef: RefObject<HTMLElement | null>;\n}\n\nconst SidebarContext = createContext<SidebarContextValue | null>(null);\n\n/**\n * Accesses the sidebar context value. Must be used within a `SidebarProvider`; throws an error if called outside.\n * Returns the active sidebar state and control callbacks.\n */\nexport function useSidebar(): SidebarContextValue {\n\tconst context = useContext(SidebarContext);\n\tif (!context) {\n\t\tthrow new Error(\"useSidebar must be used within SidebarProvider\");\n\t}\n\treturn context;\n}\n\nexport type SidebarProviderProps = {\n\t/**\n\t * The controlled collapsed state.\n\t */\n\tcollapsed?: boolean;\n\t/**\n\t * The uncontrolled initial collapsed state.\n\t * @default false\n\t */\n\tdefaultCollapsed?: boolean;\n\t/**\n\t * Called when the collapsed state changes.\n\t */\n\tonCollapsedChange?: (collapsed: boolean) => void;\n\t/**\n\t * Which edge the sidebar occupies.\n\t * @default left\n\t */\n\tside?: SidebarSide;\n\t/**\n\t * Replace the nav with a loading skeleton.\n\t * @default false\n\t */\n\tloading?: boolean;\n\t/**\n\t * Expand the collapsed rail on hover.\n\t * @default false\n\t */\n\tpeek?: boolean;\n\t/**\n\t * Render as an overlay instead of in-flow chrome.\n\t * @default false\n\t */\n\toverlay?: boolean;\n\t/**\n\t * Initial expanded width in pixels, clamped between 180 and 400.\n\t * @default 260\n\t */\n\tdefaultWidth?: number;\n\t/**\n\t * Sidebar chrome and page content.\n\t */\n\tchildren: ReactNode;\n};\n\nexport function SidebarProvider({\n\tcollapsed,\n\tdefaultCollapsed = false,\n\tonCollapsedChange,\n\tside = \"left\",\n\tloading = false,\n\tpeek = false,\n\toverlay = false,\n\tdefaultWidth = 260,\n\tchildren,\n}: SidebarProviderProps) {\n\tconst [uncontrolled, setUncontrolled] = useState(defaultCollapsed);\n\tconst [peeking, setPeeking] = useState(false);\n\tconst [width, setWidthState] = useState(() => clampSidebarWidth(defaultWidth));\n\tconst setWidth = useCallback((next: number) => {\n\t\tsetWidthState(clampSidebarWidth(next));\n\t}, []);\n\tconst lastFocusRef = useRef<HTMLElement | null>(null);\n\tconst prevCollapsed = useRef(collapsed ?? defaultCollapsed);\n\tconst prevOverlay = useRef(overlay);\n\tconst resolved = collapsed ?? uncontrolled;\n\tuseLayoutEffect(() => {\n\t\tif (\n\t\t\toverlay &&\n\t\t\t!resolved &&\n\t\t\t(prevCollapsed.current || !prevOverlay.current) &&\n\t\t\tdocument.activeElement instanceof HTMLElement\n\t\t) {\n\t\t\tlastFocusRef.current = document.activeElement;\n\t\t}\n\t\tprevCollapsed.current = resolved;\n\t\tprevOverlay.current = overlay;\n\t});\n\tconst setCollapsed = useCallback(\n\t\t(next: boolean) => {\n\t\t\tif (!next && document.activeElement instanceof HTMLElement) {\n\t\t\t\tlastFocusRef.current = document.activeElement;\n\t\t\t}\n\t\t\tif (collapsed === undefined) {\n\t\t\t\tsetUncontrolled(next);\n\t\t\t}\n\t\t\tonCollapsedChange?.(next);\n\t\t},\n\t\t[collapsed, onCollapsedChange],\n\t);\n\treturn (\n\t\t<SidebarContext.Provider\n\t\t\tvalue={{\n\t\t\t\tcollapsed: resolved,\n\t\t\t\tsetCollapsed,\n\t\t\t\tside,\n\t\t\t\tloading,\n\t\t\t\tpeek,\n\t\t\t\tpeeking,\n\t\t\t\tsetPeeking,\n\t\t\t\toverlay,\n\t\t\t\twidth,\n\t\t\t\tsetWidth,\n\t\t\t\tlastFocusRef,\n\t\t\t}}\n\t\t>\n\t\t\t{children}\n\t\t</SidebarContext.Provider>\n\t);\n}\n\nexport type SidebarProps = HTMLAttributes<HTMLElement> & {\n\t/**\n\t * Collapse the rail when no provider is present.\n\t * @default false\n\t */\n\tcollapsed?: boolean;\n};\n\nfunction clampSidebarWidth(next: number) {\n\treturn Math.min(400, Math.max(180, next));\n}\n\nfunction SidebarResize({\n\tside,\n\twidth,\n\tonWidth,\n}: {\n\tside: SidebarSide;\n\twidth: number;\n\tonWidth: (next: number) => void;\n}) {\n\tconst onPointerDown = (event: ReactPointerEvent<HTMLDivElement>) => {\n\t\tevent.preventDefault();\n\t\tevent.currentTarget.setPointerCapture(event.pointerId);\n\t\tconst startX = event.clientX;\n\t\tconst startWidth = width;\n\t\tconst target = event.currentTarget;\n\t\tconst onMove = (move: PointerEvent) => {\n\t\t\tconst delta = side === \"right\" ? startX - move.clientX : move.clientX - startX;\n\t\t\tonWidth(clampSidebarWidth(startWidth + delta));\n\t\t};\n\t\tconst onUp = () => {\n\t\t\ttarget.removeEventListener(\"pointermove\", onMove);\n\t\t\ttarget.removeEventListener(\"pointerup\", onUp);\n\t\t\ttarget.removeEventListener(\"pointercancel\", onUp);\n\t\t};\n\t\ttarget.addEventListener(\"pointermove\", onMove);\n\t\ttarget.addEventListener(\"pointerup\", onUp);\n\t\ttarget.addEventListener(\"pointercancel\", onUp);\n\t};\n\treturn (\n\t\t<div\n\t\t\trole=\"separator\"\n\t\t\taria-orientation=\"vertical\"\n\t\t\taria-valuenow={width}\n\t\t\taria-valuemin={180}\n\t\t\taria-valuemax={400}\n\t\t\taria-label=\"Resize sidebar\"\n\t\t\ttabIndex={0}\n\t\t\tclassName={cn(\n\t\t\t\t\"absolute top-0 h-full w-1 cursor-col-resize bg-transparent\",\n\t\t\t\tside === \"right\" ? \"left-0\" : \"right-0\",\n\t\t\t)}\n\t\t\tonPointerDown={onPointerDown}\n\t\t\tonKeyDown={(event) => {\n\t\t\t\tif (event.key !== \"ArrowLeft\" && event.key !== \"ArrowRight\") {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tevent.preventDefault();\n\t\t\t\tconst dir = event.key === \"ArrowRight\" ? 1 : -1;\n\t\t\t\tconst delta = side === \"right\" ? -dir * 8 : dir * 8;\n\t\t\t\tonWidth(clampSidebarWidth(width + delta));\n\t\t\t}}\n\t\t/>\n\t);\n}\n\nexport function Sidebar({\n\tcollapsed: collapsedProp,\n\tclassName,\n\tchildren,\n\tonMouseEnter,\n\tonMouseLeave,\n\tstyle,\n\t...props\n}: SidebarProps) {\n\tconst context = useContext(SidebarContext);\n\tconst collapsed = context\n\t\t? context.collapsed && !(context.peek && context.peeking)\n\t\t: (collapsedProp ?? false);\n\tconst side = context?.side ?? \"left\";\n\tconst overlay = context?.overlay ?? false;\n\tconst width = context?.width ?? 260;\n\tconst body = context?.loading ? (\n\t\t<div className=\"flex flex-col gap-2 p-3\" role=\"status\" aria-live=\"polite\">\n\t\t\t<SkeletonLine />\n\t\t\t<SkeletonLine />\n\t\t\t<SkeletonLine />\n\t\t</div>\n\t) : (\n\t\tchildren\n\t);\n\tconst resize =\n\t\tcontext && !collapsed ? (\n\t\t\t<SidebarResize side={side} width={context.width} onWidth={context.setWidth} />\n\t\t) : null;\n\tconst frameClass = cn(\n\t\tBASALT_UI_CLASS,\n\t\t\"relative flex h-screen shrink-0 flex-col bg-basalt-background text-sm text-basalt-foreground\",\n\t\tOVERLAY_MOTION,\n\t\tclassName,\n\t);\n\tif (overlay && context) {\n\t\treturn (\n\t\t\t<Dialog open={!context.collapsed} onOpenChange={(open) => context.setCollapsed(!open)}>\n\t\t\t\t<DialogPortal>\n\t\t\t\t\t<DialogOverlay />\n\t\t\t\t\t<DialogPrimitive.Content\n\t\t\t\t\t\taria-label=\"Sidebar\"\n\t\t\t\t\t\tdata-overlay=\"\"\n\t\t\t\t\t\tdata-side={side}\n\t\t\t\t\t\taria-busy={context.loading || undefined}\n\t\t\t\t\t\tonMouseEnter={onMouseEnter}\n\t\t\t\t\t\tonMouseLeave={onMouseLeave}\n\t\t\t\t\t\tref={(node) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tnode &&\n\t\t\t\t\t\t\t\tdocument.activeElement instanceof HTMLElement &&\n\t\t\t\t\t\t\t\t!node.contains(document.activeElement)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tcontext.lastFocusRef.current = document.activeElement;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonOpenAutoFocus={(event) => {\n\t\t\t\t\t\t\tconst from = \"relatedTarget\" in event ? event.relatedTarget : null;\n\t\t\t\t\t\t\tif (from instanceof HTMLElement) {\n\t\t\t\t\t\t\t\tcontext.lastFocusRef.current = from;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonCloseAutoFocus={(event) => {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tcontext.lastFocusRef.current?.focus();\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\tframeClass,\n\t\t\t\t\t\t\tOVERLAY_LAYER,\n\t\t\t\t\t\t\t\"fixed inset-y-0 overflow-hidden shadow-md\",\n\t\t\t\t\t\t\tside === \"right\" ? \"right-0\" : \"left-0\",\n\t\t\t\t\t\t)}\n\t\t\t\t\t\tstyle={{ width, ...style }}\n\t\t\t\t\t\t{...props}\n\t\t\t\t\t>\n\t\t\t\t\t\t{body}\n\t\t\t\t\t\t{resize}\n\t\t\t\t\t</DialogPrimitive.Content>\n\t\t\t\t</DialogPortal>\n\t\t\t</Dialog>\n\t\t);\n\t}\n\treturn (\n\t\t<aside\n\t\t\tdata-collapsed={collapsed ? \"\" : undefined}\n\t\t\tdata-side={side}\n\t\t\taria-busy={context?.loading || undefined}\n\t\t\tonMouseEnter={(event) => {\n\t\t\t\tif (context?.peek && context.collapsed) {\n\t\t\t\t\tcontext.setPeeking(true);\n\t\t\t\t}\n\t\t\t\tonMouseEnter?.(event);\n\t\t\t}}\n\t\t\tonMouseLeave={(event) => {\n\t\t\t\tif (context?.peek) {\n\t\t\t\t\tcontext.setPeeking(false);\n\t\t\t\t}\n\t\t\t\tonMouseLeave?.(event);\n\t\t\t}}\n\t\t\tclassName={cn(\n\t\t\t\tframeClass,\n\t\t\t\t\"sticky top-0 transition-all duration-300 ease-in-out\",\n\t\t\t\tside === \"right\" ? \"order-last\" : undefined,\n\t\t\t\tcollapsed ? \"w-[68px] overflow-y-hidden\" : \"overflow-hidden\",\n\t\t\t)}\n\t\t\tstyle={!collapsed ? { width, ...style } : style}\n\t\t\t{...props}\n\t\t>\n\t\t\t{body}\n\t\t\t{resize}\n\t\t</aside>\n\t);\n}\n\nexport interface SidebarHeaderProps extends HTMLAttributes<HTMLDivElement> {}\n\nexport function SidebarHeader({ className, ...props }: SidebarHeaderProps) {\n\treturn <div className={cn(\"flex h-14 shrink-0 items-center px-3\", className)} {...props} />;\n}\n\n/**\n * Props for `SidebarSearch`. Renders a native `<button>` element and accepts all standard button HTML attributes and click handlers.\n */\nexport interface SidebarSearchProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n\t/**\n\t * Shortcut key display label rendered inside the trailing kbd tag. Note: this is a visual label only and does not register a global keyboard shortcut.\n\t * @default \"⌘K\"\n\t */\n\tshortcut?: string;\n}\n\nexport function SidebarSearch({\n\tshortcut = \"⌘K\",\n\tclassName,\n\tchildren,\n\t...props\n}: SidebarSearchProps) {\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"flex w-full cursor-pointer items-center gap-3 rounded-lg bg-basalt-secondary px-3 py-1.5 transition-colors hover:bg-basalt-accent\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<Search className=\"h-4 w-4 text-basalt-muted-foreground\" strokeWidth={1.5} />\n\t\t\t<span className=\"flex-1 text-left text-sm text-basalt-muted-foreground\">{children}</span>\n\t\t\t<kbd className=\"pointer-events-none hidden rounded-sm border border-basalt-border bg-basalt-card px-1.5 py-0.5 text-[10px] font-medium text-basalt-muted-foreground sm:inline-block\">\n\t\t\t\t{shortcut}\n\t\t\t</kbd>\n\t\t</button>\n\t);\n}\n\nexport interface SidebarNavProps extends HTMLAttributes<HTMLElement> {}\n\nexport function SidebarNav({ className, ...props }: SidebarNavProps) {\n\treturn (\n\t\t<nav\n\t\t\tclassName={cn(\"flex min-h-0 flex-1 flex-col overflow-y-auto overscroll-y-contain\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport interface SidebarPartitionProps extends HTMLAttributes<HTMLParagraphElement> {}\n\nexport function SidebarPartition({ className, ...props }: SidebarPartitionProps) {\n\treturn (\n\t\t<p\n\t\t\tclassName={cn(\n\t\t\t\t\"px-6 pt-3 pb-1 text-[11px] font-medium tracking-[0.14em] text-basalt-muted-foreground uppercase\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport type SidebarItemProps = ButtonHTMLAttributes<HTMLButtonElement> & {\n\t/**\n\t * Mark the item as the current page.\n\t * @default false\n\t */\n\tactive?: boolean;\n};\n\nexport function SidebarItem({ active = false, className, ...props }: SidebarItemProps) {\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\taria-current={active ? \"page\" : undefined}\n\t\t\tclassName={cn(\n\t\t\t\t\"flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-normal transition-colors\",\n\t\t\t\tactive\n\t\t\t\t\t? \"bg-basalt-accent text-basalt-foreground\"\n\t\t\t\t\t: \"text-basalt-muted-foreground hover:bg-basalt-accent hover:text-basalt-foreground\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\n/**\n * Props for `SidebarIconItem`. Accepts standard button HTML attributes. The caller is responsible for providing accessible labeling via `aria-label` or `aria-labelledby` as icon buttons do not automatically generate accessible names.\n */\nexport interface SidebarIconItemProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n\t/**\n\t * Mark the icon button as active page item.\n\t * @default false\n\t */\n\tactive?: boolean;\n}\n\nexport function SidebarIconItem({ active = false, className, ...props }: SidebarIconItemProps) {\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\taria-current={active ? \"page\" : undefined}\n\t\t\tclassName={cn(\n\t\t\t\t\"relative flex h-10 w-10 items-center justify-center rounded-lg transition-colors\",\n\t\t\t\tactive\n\t\t\t\t\t? \"bg-basalt-accent text-basalt-foreground\"\n\t\t\t\t\t: \"text-basalt-muted-foreground hover:bg-basalt-accent hover:text-basalt-foreground\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\n/**\n * Props for `SidebarGroup`. Uncontrolled collapsible section that accepts only the documented properties. It does not accept controlled open props or arbitrary DOM attributes.\n */\nexport interface SidebarGroupProps {\n\t/**\n\t * Section label displayed on the group trigger.\n\t */\n\tlabel: ReactNode;\n\t/**\n\t * Uncontrolled initial open state for the collapsible group.\n\t * @default true\n\t */\n\tdefaultOpen?: boolean;\n\t/**\n\t * Navigation items rendered inside the group.\n\t */\n\tchildren: ReactNode;\n}\n\nexport function SidebarGroup({ label, defaultOpen = true, children }: SidebarGroupProps) {\n\tconst [open, setOpen] = useState(defaultOpen);\n\treturn (\n\t\t<Collapsible open={open} onOpenChange={setOpen}>\n\t\t\t<div className=\"mt-2 px-3\">\n\t\t\t\t<CollapsibleTrigger asChild>\n\t\t\t\t\t<button type=\"button\" className=\"flex w-full items-center justify-between px-3 py-2.5\">\n\t\t\t\t\t\t<span className=\"text-sm font-normal text-basalt-muted-foreground\">{label}</span>\n\t\t\t\t\t\t<span className=\"flex h-7 w-7 shrink-0 items-center justify-center\">\n\t\t\t\t\t\t\t<ChevronUp\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\"h-4 w-4 text-basalt-muted-foreground transition-transform duration-200\",\n\t\t\t\t\t\t\t\t\tOVERLAY_MOTION,\n\t\t\t\t\t\t\t\t\t!open && \"rotate-180\",\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\tstrokeWidth={1.5}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</button>\n\t\t\t\t</CollapsibleTrigger>\n\t\t\t</div>\n\t\t\t<CollapsibleContent unstyled>\n\t\t\t\t<div className=\"flex flex-col gap-0.5 px-3\">{children}</div>\n\t\t\t</CollapsibleContent>\n\t\t</Collapsible>\n\t);\n}\n\nexport interface SidebarFooterProps extends HTMLAttributes<HTMLDivElement> {}\n\nexport function SidebarFooter({ className, ...props }: SidebarFooterProps) {\n\treturn <div className={cn(\"shrink-0 px-4 py-3\", className)} {...props} />;\n}\n\nexport interface SidebarUserProps {\n\t/**\n\t * User display name.\n\t */\n\tname: ReactNode;\n\t/**\n\t * Optional user email or secondary text.\n\t */\n\temail?: ReactNode;\n\t/**\n\t * Avatar element slot.\n\t */\n\tavatar?: ReactNode;\n\t/**\n\t * Trailing action slot (e.g. settings or logout button).\n\t */\n\taction?: ReactNode;\n\t/**\n\t * Additional CSS class name.\n\t */\n\tclassName?: string;\n}\n\nexport function SidebarUser({ name, email, avatar, action, className }: SidebarUserProps) {\n\treturn (\n\t\t<div className={cn(\"flex items-center gap-3\", className)}>\n\t\t\t{avatar}\n\t\t\t<div className=\"min-w-0 flex-1\">\n\t\t\t\t<p className=\"truncate text-sm font-medium text-basalt-foreground\">{name}</p>\n\t\t\t\t{email ? <p className=\"truncate text-xs text-basalt-muted-foreground\">{email}</p> : null}\n\t\t\t</div>\n\t\t\t{action}\n\t\t</div>\n\t);\n}\n\nexport interface ContentIslandProps extends HTMLAttributes<HTMLDivElement> {}\n\nexport function ContentIsland({ className, ...props }: ContentIslandProps) {\n\treturn (\n\t\t<div\n\t\t\tdata-basalt-surface-root=\"\"\n\t\t\tclassName={cn(\n\t\t\t\t\"min-h-0 flex-1 overflow-y-auto overscroll-y-contain rounded-[16px] bg-basalt-card p-3 text-basalt-card-foreground shadow-sm ring-1 ring-basalt-border/40 md:rounded-basalt-island md:p-5\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sidebar.js","names":["DialogPrimitive","SidebarContext","createContext","useSidebar","context","useContext","SidebarProvider","uncontrolled","setUncontrolled","useState","defaultCollapsed","peeking","setPeeking","width","setWidthState","clampSidebarWidth","defaultWidth","setWidth","useCallback","next","lastFocusRef","useRef","prevCollapsed","collapsed","prevOverlay","overlay","resolved","setCollapsed","onCollapsedChange","SidebarResize","cn","side","event","startX","startWidth","target","onMove","delta","move","onUp","dir","Sidebar","collapsedProp","props","body","SkeletonLine","children","resize","frameClass","BASALT_UI_CLASS","OVERLAY_MOTION","className","Dialog","open","DialogPortal","DialogOverlay","node","from","OVERLAY_LAYER","style","onMouseEnter","onMouseLeave","SidebarHeader","SidebarSearch","Search","shortcut","SidebarNav","SidebarPartition","SidebarItem","active","SidebarIconItem","SidebarGroup","setOpen","defaultOpen","Collapsible","CollapsibleTrigger","label","ChevronUp","CollapsibleContent","SidebarFooter","SidebarUser","avatar","name","email","action","ContentIsland","mobileSurface"],"sources":["../../src/components/sidebar.tsx"],"sourcesContent":["import * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { ChevronUp, Search } from \"lucide-react\";\nimport {\n\ttype ButtonHTMLAttributes,\n\tcreateContext,\n\ttype HTMLAttributes,\n\ttype ReactNode,\n\ttype PointerEvent as ReactPointerEvent,\n\ttype RefObject,\n\tuseCallback,\n\tuseContext,\n\tuseLayoutEffect,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"./collapsible\";\nimport { Dialog, DialogOverlay, DialogPortal } from \"./dialog\";\nimport { OVERLAY_LAYER, OVERLAY_MOTION } from \"./overlay\";\nimport { SkeletonLine } from \"./skeleton-line\";\n\nexport type SidebarSide = \"left\" | \"right\";\n\nexport interface SidebarContextValue {\n\t/**\n\t * Whether the sidebar is currently collapsed.\n\t */\n\tcollapsed: boolean;\n\t/**\n\t * Callback to update the collapsed state.\n\t */\n\tsetCollapsed: (next: boolean) => void;\n\t/**\n\t * Which edge the sidebar occupies.\n\t */\n\tside: SidebarSide;\n\t/**\n\t * Whether the sidebar is currently displaying a loading skeleton.\n\t */\n\tloading: boolean;\n\t/**\n\t * Whether the sidebar rail expands on pointer hover.\n\t */\n\tpeek: boolean;\n\t/**\n\t * Whether the sidebar is actively hovering in peek preview mode.\n\t */\n\tpeeking: boolean;\n\t/**\n\t * Callback to update the peek preview state.\n\t */\n\tsetPeeking: (next: boolean) => void;\n\t/**\n\t * Whether the sidebar is rendering as a modal overlay drawer instead of in-flow layout chrome.\n\t */\n\toverlay: boolean;\n\t/**\n\t * Current expanded width in pixels, clamped between 180 and 400.\n\t */\n\twidth: number;\n\t/**\n\t * Callback to update the sidebar width. Value is clamped between 180 and 400 pixels.\n\t */\n\tsetWidth: (next: number) => void;\n\t/**\n\t * Reference to the last active element that held focus before opening the sidebar drawer.\n\t */\n\tlastFocusRef: RefObject<HTMLElement | null>;\n}\n\nconst SidebarContext = createContext<SidebarContextValue | null>(null);\n\n/**\n * Accesses the sidebar context value. Must be used within a `SidebarProvider`; throws an error if called outside.\n * Returns the active sidebar state and control callbacks.\n */\nexport function useSidebar(): SidebarContextValue {\n\tconst context = useContext(SidebarContext);\n\tif (!context) {\n\t\tthrow new Error(\"useSidebar must be used within SidebarProvider\");\n\t}\n\treturn context;\n}\n\nexport type SidebarProviderProps = {\n\t/**\n\t * The controlled collapsed state.\n\t */\n\tcollapsed?: boolean;\n\t/**\n\t * The uncontrolled initial collapsed state.\n\t * @default false\n\t */\n\tdefaultCollapsed?: boolean;\n\t/**\n\t * Called when the collapsed state changes.\n\t */\n\tonCollapsedChange?: (collapsed: boolean) => void;\n\t/**\n\t * Which edge the sidebar occupies.\n\t * @default left\n\t */\n\tside?: SidebarSide;\n\t/**\n\t * Replace the nav with a loading skeleton.\n\t * @default false\n\t */\n\tloading?: boolean;\n\t/**\n\t * Expand the collapsed rail on hover.\n\t * @default false\n\t */\n\tpeek?: boolean;\n\t/**\n\t * Render as an overlay instead of in-flow chrome.\n\t * @default false\n\t */\n\toverlay?: boolean;\n\t/**\n\t * Initial expanded width in pixels, clamped between 180 and 400.\n\t * @default 260\n\t */\n\tdefaultWidth?: number;\n\t/**\n\t * Sidebar chrome and page content.\n\t */\n\tchildren: ReactNode;\n};\n\nexport function SidebarProvider({\n\tcollapsed,\n\tdefaultCollapsed = false,\n\tonCollapsedChange,\n\tside = \"left\",\n\tloading = false,\n\tpeek = false,\n\toverlay = false,\n\tdefaultWidth = 260,\n\tchildren,\n}: SidebarProviderProps) {\n\tconst [uncontrolled, setUncontrolled] = useState(defaultCollapsed);\n\tconst [peeking, setPeeking] = useState(false);\n\tconst [width, setWidthState] = useState(() => clampSidebarWidth(defaultWidth));\n\tconst setWidth = useCallback((next: number) => {\n\t\tsetWidthState(clampSidebarWidth(next));\n\t}, []);\n\tconst lastFocusRef = useRef<HTMLElement | null>(null);\n\tconst prevCollapsed = useRef(collapsed ?? defaultCollapsed);\n\tconst prevOverlay = useRef(overlay);\n\tconst resolved = collapsed ?? uncontrolled;\n\tuseLayoutEffect(() => {\n\t\tif (\n\t\t\toverlay &&\n\t\t\t!resolved &&\n\t\t\t(prevCollapsed.current || !prevOverlay.current) &&\n\t\t\tdocument.activeElement instanceof HTMLElement\n\t\t) {\n\t\t\tlastFocusRef.current = document.activeElement;\n\t\t}\n\t\tprevCollapsed.current = resolved;\n\t\tprevOverlay.current = overlay;\n\t});\n\tconst setCollapsed = useCallback(\n\t\t(next: boolean) => {\n\t\t\tif (!next && document.activeElement instanceof HTMLElement) {\n\t\t\t\tlastFocusRef.current = document.activeElement;\n\t\t\t}\n\t\t\tif (collapsed === undefined) {\n\t\t\t\tsetUncontrolled(next);\n\t\t\t}\n\t\t\tonCollapsedChange?.(next);\n\t\t},\n\t\t[collapsed, onCollapsedChange],\n\t);\n\treturn (\n\t\t<SidebarContext.Provider\n\t\t\tvalue={{\n\t\t\t\tcollapsed: resolved,\n\t\t\t\tsetCollapsed,\n\t\t\t\tside,\n\t\t\t\tloading,\n\t\t\t\tpeek,\n\t\t\t\tpeeking,\n\t\t\t\tsetPeeking,\n\t\t\t\toverlay,\n\t\t\t\twidth,\n\t\t\t\tsetWidth,\n\t\t\t\tlastFocusRef,\n\t\t\t}}\n\t\t>\n\t\t\t{children}\n\t\t</SidebarContext.Provider>\n\t);\n}\n\nexport type SidebarProps = HTMLAttributes<HTMLElement> & {\n\t/**\n\t * Collapse the rail when no provider is present.\n\t * @default false\n\t */\n\tcollapsed?: boolean;\n};\n\nfunction clampSidebarWidth(next: number) {\n\treturn Math.min(400, Math.max(180, next));\n}\n\nfunction SidebarResize({\n\tside,\n\twidth,\n\tonWidth,\n}: {\n\tside: SidebarSide;\n\twidth: number;\n\tonWidth: (next: number) => void;\n}) {\n\tconst onPointerDown = (event: ReactPointerEvent<HTMLDivElement>) => {\n\t\tevent.preventDefault();\n\t\tevent.currentTarget.setPointerCapture(event.pointerId);\n\t\tconst startX = event.clientX;\n\t\tconst startWidth = width;\n\t\tconst target = event.currentTarget;\n\t\tconst onMove = (move: PointerEvent) => {\n\t\t\tconst delta = side === \"right\" ? startX - move.clientX : move.clientX - startX;\n\t\t\tonWidth(clampSidebarWidth(startWidth + delta));\n\t\t};\n\t\tconst onUp = () => {\n\t\t\ttarget.removeEventListener(\"pointermove\", onMove);\n\t\t\ttarget.removeEventListener(\"pointerup\", onUp);\n\t\t\ttarget.removeEventListener(\"pointercancel\", onUp);\n\t\t};\n\t\ttarget.addEventListener(\"pointermove\", onMove);\n\t\ttarget.addEventListener(\"pointerup\", onUp);\n\t\ttarget.addEventListener(\"pointercancel\", onUp);\n\t};\n\treturn (\n\t\t<div\n\t\t\trole=\"separator\"\n\t\t\taria-orientation=\"vertical\"\n\t\t\taria-valuenow={width}\n\t\t\taria-valuemin={180}\n\t\t\taria-valuemax={400}\n\t\t\taria-label=\"Resize sidebar\"\n\t\t\ttabIndex={0}\n\t\t\tclassName={cn(\n\t\t\t\t\"absolute top-0 h-full w-1 cursor-col-resize bg-transparent\",\n\t\t\t\tside === \"right\" ? \"left-0\" : \"right-0\",\n\t\t\t)}\n\t\t\tonPointerDown={onPointerDown}\n\t\t\tonKeyDown={(event) => {\n\t\t\t\tif (event.key !== \"ArrowLeft\" && event.key !== \"ArrowRight\") {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tevent.preventDefault();\n\t\t\t\tconst dir = event.key === \"ArrowRight\" ? 1 : -1;\n\t\t\t\tconst delta = side === \"right\" ? -dir * 8 : dir * 8;\n\t\t\t\tonWidth(clampSidebarWidth(width + delta));\n\t\t\t}}\n\t\t/>\n\t);\n}\n\nexport function Sidebar({\n\tcollapsed: collapsedProp,\n\tclassName,\n\tchildren,\n\tonMouseEnter,\n\tonMouseLeave,\n\tstyle,\n\t...props\n}: SidebarProps) {\n\tconst context = useContext(SidebarContext);\n\tconst collapsed = context\n\t\t? context.collapsed && !(context.peek && context.peeking)\n\t\t: (collapsedProp ?? false);\n\tconst side = context?.side ?? \"left\";\n\tconst overlay = context?.overlay ?? false;\n\tconst width = context?.width ?? 260;\n\tconst body = context?.loading ? (\n\t\t<div className=\"flex flex-col gap-2 p-3\" role=\"status\" aria-live=\"polite\">\n\t\t\t<SkeletonLine />\n\t\t\t<SkeletonLine />\n\t\t\t<SkeletonLine />\n\t\t</div>\n\t) : (\n\t\tchildren\n\t);\n\tconst resize =\n\t\tcontext && !collapsed ? (\n\t\t\t<SidebarResize side={side} width={context.width} onWidth={context.setWidth} />\n\t\t) : null;\n\tconst frameClass = cn(\n\t\tBASALT_UI_CLASS,\n\t\t\"relative flex shrink-0 flex-col bg-basalt-background text-sm text-basalt-foreground\",\n\t\tOVERLAY_MOTION,\n\t\tclassName,\n\t);\n\tif (overlay && context) {\n\t\treturn (\n\t\t\t<Dialog open={!context.collapsed} onOpenChange={(open) => context.setCollapsed(!open)}>\n\t\t\t\t<DialogPortal>\n\t\t\t\t\t<DialogOverlay />\n\t\t\t\t\t<DialogPrimitive.Content\n\t\t\t\t\t\tdata-basalt-sidebar=\"\"\n\t\t\t\t\t\taria-label=\"Sidebar\"\n\t\t\t\t\t\tdata-overlay=\"\"\n\t\t\t\t\t\tdata-side={side}\n\t\t\t\t\t\taria-busy={context.loading || undefined}\n\t\t\t\t\t\tonMouseEnter={onMouseEnter}\n\t\t\t\t\t\tonMouseLeave={onMouseLeave}\n\t\t\t\t\t\tref={(node) => {\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tnode &&\n\t\t\t\t\t\t\t\tdocument.activeElement instanceof HTMLElement &&\n\t\t\t\t\t\t\t\t!node.contains(document.activeElement)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tcontext.lastFocusRef.current = document.activeElement;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonOpenAutoFocus={(event) => {\n\t\t\t\t\t\t\tconst from = \"relatedTarget\" in event ? event.relatedTarget : null;\n\t\t\t\t\t\t\tif (from instanceof HTMLElement) {\n\t\t\t\t\t\t\t\tcontext.lastFocusRef.current = from;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonCloseAutoFocus={(event) => {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tcontext.lastFocusRef.current?.focus();\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\tframeClass,\n\t\t\t\t\t\t\tOVERLAY_LAYER,\n\t\t\t\t\t\t\t\"fixed inset-y-0 overflow-hidden shadow-md\",\n\t\t\t\t\t\t\tside === \"right\" ? \"right-0\" : \"left-0\",\n\t\t\t\t\t\t)}\n\t\t\t\t\t\tstyle={{ width, ...style }}\n\t\t\t\t\t\t{...props}\n\t\t\t\t\t>\n\t\t\t\t\t\t{body}\n\t\t\t\t\t\t{resize}\n\t\t\t\t\t</DialogPrimitive.Content>\n\t\t\t\t</DialogPortal>\n\t\t\t</Dialog>\n\t\t);\n\t}\n\treturn (\n\t\t<aside\n\t\t\tdata-basalt-sidebar=\"\"\n\t\t\tdata-collapsed={collapsed ? \"\" : undefined}\n\t\t\tdata-side={side}\n\t\t\taria-busy={context?.loading || undefined}\n\t\t\tonMouseEnter={(event) => {\n\t\t\t\tif (context?.peek && context.collapsed) {\n\t\t\t\t\tcontext.setPeeking(true);\n\t\t\t\t}\n\t\t\t\tonMouseEnter?.(event);\n\t\t\t}}\n\t\t\tonMouseLeave={(event) => {\n\t\t\t\tif (context?.peek) {\n\t\t\t\t\tcontext.setPeeking(false);\n\t\t\t\t}\n\t\t\t\tonMouseLeave?.(event);\n\t\t\t}}\n\t\t\tclassName={cn(\n\t\t\t\tframeClass,\n\t\t\t\t\"sticky transition-all duration-300 ease-in-out\",\n\t\t\t\tside === \"right\" ? \"order-last\" : undefined,\n\t\t\t\tcollapsed ? \"w-[68px] overflow-y-hidden\" : \"overflow-hidden\",\n\t\t\t)}\n\t\t\tstyle={!collapsed ? { width, ...style } : style}\n\t\t\t{...props}\n\t\t>\n\t\t\t{body}\n\t\t\t{resize}\n\t\t</aside>\n\t);\n}\n\nexport interface SidebarHeaderProps extends HTMLAttributes<HTMLDivElement> {}\n\nexport function SidebarHeader({ className, ...props }: SidebarHeaderProps) {\n\treturn <div className={cn(\"flex h-14 shrink-0 items-center px-3\", className)} {...props} />;\n}\n\n/**\n * Props for `SidebarSearch`. Renders a native `<button>` element and accepts all standard button HTML attributes and click handlers.\n */\nexport interface SidebarSearchProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n\t/**\n\t * Shortcut key display label rendered inside the trailing kbd tag. Note: this is a visual label only and does not register a global keyboard shortcut.\n\t * @default \"⌘K\"\n\t */\n\tshortcut?: string;\n}\n\nexport function SidebarSearch({\n\tshortcut = \"⌘K\",\n\tclassName,\n\tchildren,\n\t...props\n}: SidebarSearchProps) {\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"flex w-full cursor-pointer items-center gap-3 rounded-lg bg-basalt-secondary px-3 py-1.5 transition-colors hover:bg-basalt-accent\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<Search className=\"h-4 w-4 text-basalt-muted-foreground\" strokeWidth={1.5} />\n\t\t\t<span className=\"flex-1 text-left text-sm text-basalt-muted-foreground\">{children}</span>\n\t\t\t<kbd className=\"pointer-events-none hidden rounded-sm border border-basalt-border bg-basalt-card px-1.5 py-0.5 text-[10px] font-medium text-basalt-muted-foreground sm:inline-block\">\n\t\t\t\t{shortcut}\n\t\t\t</kbd>\n\t\t</button>\n\t);\n}\n\nexport interface SidebarNavProps extends HTMLAttributes<HTMLElement> {}\n\nexport function SidebarNav({ className, ...props }: SidebarNavProps) {\n\treturn (\n\t\t<nav\n\t\t\tclassName={cn(\"flex min-h-0 flex-1 flex-col overflow-y-auto overscroll-y-contain\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport interface SidebarPartitionProps extends HTMLAttributes<HTMLParagraphElement> {}\n\nexport function SidebarPartition({ className, ...props }: SidebarPartitionProps) {\n\treturn (\n\t\t<p\n\t\t\tclassName={cn(\n\t\t\t\t\"px-6 pt-3 pb-1 text-[11px] font-medium tracking-[0.14em] text-basalt-muted-foreground uppercase\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport type SidebarItemProps = ButtonHTMLAttributes<HTMLButtonElement> & {\n\t/**\n\t * Mark the item as the current page.\n\t * @default false\n\t */\n\tactive?: boolean;\n};\n\nexport function SidebarItem({ active = false, className, ...props }: SidebarItemProps) {\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\taria-current={active ? \"page\" : undefined}\n\t\t\tclassName={cn(\n\t\t\t\t\"flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-normal transition-colors\",\n\t\t\t\tactive\n\t\t\t\t\t? \"bg-basalt-accent text-basalt-foreground\"\n\t\t\t\t\t: \"text-basalt-muted-foreground hover:bg-basalt-accent hover:text-basalt-foreground\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\n/**\n * Props for `SidebarIconItem`. Accepts standard button HTML attributes. The caller is responsible for providing accessible labeling via `aria-label` or `aria-labelledby` as icon buttons do not automatically generate accessible names.\n */\nexport interface SidebarIconItemProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n\t/**\n\t * Mark the icon button as active page item.\n\t * @default false\n\t */\n\tactive?: boolean;\n}\n\nexport function SidebarIconItem({ active = false, className, ...props }: SidebarIconItemProps) {\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\taria-current={active ? \"page\" : undefined}\n\t\t\tclassName={cn(\n\t\t\t\t\"relative flex h-10 w-10 items-center justify-center rounded-lg transition-colors\",\n\t\t\t\tactive\n\t\t\t\t\t? \"bg-basalt-accent text-basalt-foreground\"\n\t\t\t\t\t: \"text-basalt-muted-foreground hover:bg-basalt-accent hover:text-basalt-foreground\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\n/**\n * Props for `SidebarGroup`. Uncontrolled collapsible section that accepts only the documented properties. It does not accept controlled open props or arbitrary DOM attributes.\n */\nexport interface SidebarGroupProps {\n\t/**\n\t * Section label displayed on the group trigger.\n\t */\n\tlabel: ReactNode;\n\t/**\n\t * Uncontrolled initial open state for the collapsible group.\n\t * @default true\n\t */\n\tdefaultOpen?: boolean;\n\t/**\n\t * Navigation items rendered inside the group.\n\t */\n\tchildren: ReactNode;\n}\n\nexport function SidebarGroup({ label, defaultOpen = true, children }: SidebarGroupProps) {\n\tconst [open, setOpen] = useState(defaultOpen);\n\treturn (\n\t\t<Collapsible open={open} onOpenChange={setOpen}>\n\t\t\t<div className=\"mt-2 px-3\">\n\t\t\t\t<CollapsibleTrigger asChild>\n\t\t\t\t\t<button type=\"button\" className=\"flex w-full items-center justify-between px-3 py-2.5\">\n\t\t\t\t\t\t<span className=\"text-sm font-normal text-basalt-muted-foreground\">{label}</span>\n\t\t\t\t\t\t<span className=\"flex h-7 w-7 shrink-0 items-center justify-center\">\n\t\t\t\t\t\t\t<ChevronUp\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\"h-4 w-4 text-basalt-muted-foreground transition-transform duration-200\",\n\t\t\t\t\t\t\t\t\tOVERLAY_MOTION,\n\t\t\t\t\t\t\t\t\t!open && \"rotate-180\",\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\tstrokeWidth={1.5}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</button>\n\t\t\t\t</CollapsibleTrigger>\n\t\t\t</div>\n\t\t\t<CollapsibleContent unstyled>\n\t\t\t\t<div className=\"flex flex-col gap-0.5 px-3\">{children}</div>\n\t\t\t</CollapsibleContent>\n\t\t</Collapsible>\n\t);\n}\n\nexport interface SidebarFooterProps extends HTMLAttributes<HTMLDivElement> {}\n\nexport function SidebarFooter({ className, ...props }: SidebarFooterProps) {\n\treturn <div className={cn(\"shrink-0 px-4 py-3\", className)} {...props} />;\n}\n\nexport interface SidebarUserProps {\n\t/**\n\t * User display name.\n\t */\n\tname: ReactNode;\n\t/**\n\t * Optional user email or secondary text.\n\t */\n\temail?: ReactNode;\n\t/**\n\t * Avatar element slot.\n\t */\n\tavatar?: ReactNode;\n\t/**\n\t * Trailing action slot (e.g. settings or logout button).\n\t */\n\taction?: ReactNode;\n\t/**\n\t * Additional CSS class name.\n\t */\n\tclassName?: string;\n}\n\nexport function SidebarUser({ name, email, avatar, action, className }: SidebarUserProps) {\n\treturn (\n\t\t<div className={cn(\"flex items-center gap-3\", className)}>\n\t\t\t{avatar}\n\t\t\t<div className=\"min-w-0 flex-1\">\n\t\t\t\t<p className=\"truncate text-sm font-medium text-basalt-foreground\">{name}</p>\n\t\t\t\t{email ? <p className=\"truncate text-xs text-basalt-muted-foreground\">{email}</p> : null}\n\t\t\t</div>\n\t\t\t{action}\n\t\t</div>\n\t);\n}\n\nexport interface ContentIslandProps extends HTMLAttributes<HTMLDivElement> {\n\t/** Mobile surface treatment; desktop remains an inset L1 island. @default \"inset\" */\n\tmobileSurface?: \"inset\" | \"edge-to-edge\";\n}\n\nexport function ContentIsland({\n\tmobileSurface = \"inset\",\n\tclassName,\n\t...props\n}: ContentIslandProps) {\n\treturn (\n\t\t<div\n\t\t\tdata-basalt-surface-root=\"\"\n\t\t\tdata-basalt-island={mobileSurface}\n\t\t\tclassName={cn(\n\t\t\t\t\"min-h-0 min-w-0 flex-1 bg-basalt-card text-basalt-card-foreground md:rounded-basalt-island md:p-5\",\n\t\t\t\tmobileSurface === \"inset\"\n\t\t\t\t\t? \"rounded-[16px] p-3 shadow-sm ring-1 ring-basalt-border/40\"\n\t\t\t\t\t: \"md:shadow-sm md:ring-1 md:ring-basalt-border/40\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skeleton-line.js","names":[],"sources":["../../src/components/skeleton-line.tsx"],"sourcesContent":["import type { CSSProperties, HTMLAttributes } from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport interface SkeletonLineProps extends HTMLAttributes<HTMLDivElement> {\n\t/**\n\t * Minimum width percentage used for deterministic width computation.\n\t *\n\t * Note: Averaged with maxWidth to compute the midpoint width percentage.\n\t *\n\t * @default 30\n\t */\n\tminWidth?: number;\n\n\t/**\n\t * Maximum width percentage used for deterministic width computation.\n\t *\n\t * Note: Averaged with minWidth to compute the midpoint width percentage.\n\t *\n\t * @default 100\n\t */\n\tmaxWidth?: number;\n\n\t/**\n\t * Explicit height of the skeleton line in pixels.\n\t *\n\t * Note: When omitted, default height is governed by CSS class tokens (h-2).\n\t */\n\theight?: number;\n}\n\nexport function SkeletonLine({\n\tclassName,\n\tminWidth = 30,\n\tmaxWidth = 100,\n\theight,\n\tstyle,\n\t...props\n}: SkeletonLineProps) {\n\tconst width = (minWidth + maxWidth) / 2;\n\tconst lineStyle: CSSProperties = {\n\t\twidth: `${width}%`,\n\t\t...(height !== undefined ? { height } : {}),\n\t\t...style,\n\t};\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\"relative h-2 overflow-hidden rounded-sm bg-basalt-muted\", className)}\n\t\t\tstyle={lineStyle}\n\t\t\taria-hidden=\"true\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<span className=\"pointer-events-none absolute inset-0 animate-basalt-shimmer bg-gradient-to-r from-transparent via-black/10 to-transparent motion-reduce:animate-none\" />\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;AA8BA,
|
|
1
|
+
{"version":3,"file":"skeleton-line.js","names":["SkeletonLine","props","lineStyle","minWidth","maxWidth","height","style","cn","className"],"sources":["../../src/components/skeleton-line.tsx"],"sourcesContent":["import type { CSSProperties, HTMLAttributes } from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport interface SkeletonLineProps extends HTMLAttributes<HTMLDivElement> {\n\t/**\n\t * Minimum width percentage used for deterministic width computation.\n\t *\n\t * Note: Averaged with maxWidth to compute the midpoint width percentage.\n\t *\n\t * @default 30\n\t */\n\tminWidth?: number;\n\n\t/**\n\t * Maximum width percentage used for deterministic width computation.\n\t *\n\t * Note: Averaged with minWidth to compute the midpoint width percentage.\n\t *\n\t * @default 100\n\t */\n\tmaxWidth?: number;\n\n\t/**\n\t * Explicit height of the skeleton line in pixels.\n\t *\n\t * Note: When omitted, default height is governed by CSS class tokens (h-2).\n\t */\n\theight?: number;\n}\n\nexport function SkeletonLine({\n\tclassName,\n\tminWidth = 30,\n\tmaxWidth = 100,\n\theight,\n\tstyle,\n\t...props\n}: SkeletonLineProps) {\n\tconst width = (minWidth + maxWidth) / 2;\n\tconst lineStyle: CSSProperties = {\n\t\twidth: `${width}%`,\n\t\t...(height !== undefined ? { height } : {}),\n\t\t...style,\n\t};\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\"relative h-2 overflow-hidden rounded-sm bg-basalt-muted\", className)}\n\t\t\tstyle={lineStyle}\n\t\t\taria-hidden=\"true\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<span className=\"pointer-events-none absolute inset-0 animate-basalt-shimmer bg-gradient-to-r from-transparent via-black/10 to-transparent motion-reduce:animate-none\" />\n\t\t</div>\n\t);\n}\n"],"mappings":";;;;AA8BA,SAAgBA,EAAa,EAC5B,cACA,cAAW,IACX,cAAW,KACX,WACA,UACA,GAAGC,KACkB;CAErB,IAAMC,IAA2B;EAChC,OAAO,IAFOC,IAAWC,KAAY,EAErB;EAChB,GAAIC,MAAW,KAAA,IAAyB,CAAC,IAAd,EAAE,UAAO;EACpC,GAAGC;CACJ;CACA,OACC,kBAAC,OAAD;EACC,WAAWC,EAAG,2DAA2DC,CAAS;EAClF,OAAON;EACP,eAAY;EACZ,GAAID;EAEJ,UAAA,kBAAC,QAAD,EAAM,WAAU,uJAAwJ,CAAA;CACpK,CAAA;AAEP"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slider.js","names":[],"sources":["../../src/components/slider.tsx"],"sourcesContent":["import * as SliderPrimitive from \"@radix-ui/react-slider\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { FOCUS_RING } from \"./overlay\";\n\ntype RadixSliderRootProps = React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root>;\n\nexport interface SliderProps\n\textends Omit<\n\t\tRadixSliderRootProps,\n\t\t| \"value\"\n\t\t| \"defaultValue\"\n\t\t| \"onValueChange\"\n\t\t| \"onValueCommit\"\n\t\t| \"disabled\"\n\t\t| \"name\"\n\t\t| \"min\"\n\t\t| \"max\"\n\t\t| \"step\"\n\t\t| \"orientation\"\n\t> {\n\t/**\n\t * Controlled value array for the slider. Forwards ref to root span element.\n\t * When multiple values are provided, renders a thumb for each value.\n\t */\n\tvalue?: RadixSliderRootProps[\"value\"];\n\t/**\n\t * Uncontrolled default value array for the slider.\n\t * When multiple values are provided, renders a thumb for each value.\n\t * @default [min ?? 0]\n\t */\n\tdefaultValue?: RadixSliderRootProps[\"defaultValue\"];\n\t/**\n\t * Callback invoked when slider value changes during interaction.\n\t */\n\tonValueChange?: RadixSliderRootProps[\"onValueChange\"];\n\t/**\n\t * Callback invoked when slider interaction finishes and value is committed.\n\t */\n\tonValueCommit?: RadixSliderRootProps[\"onValueCommit\"];\n\t/**\n\t * Whether the slider is disabled from user interaction.\n\t * @default false\n\t */\n\tdisabled?: RadixSliderRootProps[\"disabled\"];\n\t/**\n\t * Form field name submitted with the slider values.\n\t */\n\tname?: RadixSliderRootProps[\"name\"];\n\t/**\n\t * Minimum allowable value.\n\t * @default 0\n\t */\n\tmin?: RadixSliderRootProps[\"min\"];\n\t/**\n\t * Maximum allowable value.\n\t * @default 100\n\t */\n\tmax?: RadixSliderRootProps[\"max\"];\n\t/**\n\t * Step interval between selectable values.\n\t * @default 1\n\t */\n\tstep?: RadixSliderRootProps[\"step\"];\n\t/**\n\t * Layout orientation of the slider track.\n\t * When set to `\"vertical\"`, the slider track and range align vertically. A container with an explicit height is required.\n\t * @default \"horizontal\"\n\t */\n\torientation?: RadixSliderRootProps[\"orientation\"];\n\t/**\n\t * Accessible labels for thumbs when rendering single or multiple values.\n\t * When provided, thumb at index `i` receives `labels[i]`. For a single thumb, `labels[0]` takes precedence over `aria-label`.\n\t * When omitted on a multi-value slider, the root `aria-label` provides a contextual fallback (e.g. `ariaLabel + \" minimum\"`),\n\t * or falls back to Radix default names (`\"Minimum\"`, `\"Maximum\"`, or `\"Value N of Total\"`).\n\t */\n\tlabels?: string[];\n}\n\nexport const Slider = React.forwardRef<React.ElementRef<typeof SliderPrimitive.Root>, SliderProps>(\n\t(\n\t\t{\n\t\t\tclassName,\n\t\t\tvalue,\n\t\t\tdefaultValue,\n\t\t\tmin = 0,\n\t\t\tmax = 100,\n\t\t\torientation = \"horizontal\",\n\t\t\tlabels,\n\t\t\t\"aria-label\": ariaLabel,\n\t\t\t\"aria-labelledby\": ariaLabelledBy,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst isVertical = orientation === \"vertical\";\n\t\tconst isControlled = value !== undefined;\n\n\t\tconst initialUncontrolledCountRef = React.useRef(defaultValue?.length ?? 1);\n\t\tconst thumbCount = isControlled ? (value?.length ?? 0) : initialUncontrolledCountRef.current;\n\n\t\treturn (\n\t\t\t<SliderPrimitive.Root\n\t\t\t\tref={ref}\n\t\t\t\tmin={min}\n\t\t\t\tmax={max}\n\t\t\t\torientation={orientation}\n\t\t\t\tvalue={value}\n\t\t\t\tdefaultValue={defaultValue}\n\t\t\t\taria-label={ariaLabel}\n\t\t\t\taria-labelledby={ariaLabelledBy}\n\t\t\t\tclassName={cn(\n\t\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\t\"relative flex touch-none select-none items-center\",\n\t\t\t\t\tisVertical ? \"h-full w-auto flex-col justify-center\" : \"h-auto w-full\",\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<SliderPrimitive.Track\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"relative grow overflow-hidden rounded-full bg-basalt-muted\",\n\t\t\t\t\t\tisVertical ? \"h-full w-2\" : \"h-2 w-full\",\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t<SliderPrimitive.Range\n\t\t\t\t\t\tclassName={cn(\"absolute bg-basalt-primary\", isVertical ? \"w-full\" : \"h-full\")}\n\t\t\t\t\t/>\n\t\t\t\t</SliderPrimitive.Track>\n\t\t\t\t{Array.from({ length: thumbCount }, (_, index) => {\n\t\t\t\t\tlet thumbLabel: string | undefined;\n\t\t\t\t\tlet thumbLabelledBy: string | undefined;\n\n\t\t\t\t\tif (thumbCount === 1) {\n\t\t\t\t\t\tthumbLabel = labels?.[0] ?? ariaLabel;\n\t\t\t\t\t\tthumbLabelledBy = ariaLabelledBy;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (labels?.[index] !== undefined) {\n\t\t\t\t\t\t\tthumbLabel = labels[index];\n\t\t\t\t\t\t} else if (ariaLabel) {\n\t\t\t\t\t\t\tif (thumbCount === 2) {\n\t\t\t\t\t\t\t\tconst suffix = index === 0 ? \"minimum\" : \"maximum\";\n\t\t\t\t\t\t\t\tthumbLabel = `${ariaLabel} ${suffix}`;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthumbLabel = `${ariaLabel} thumb ${index + 1} of ${thumbCount}`;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst thumbProps: React.ComponentPropsWithoutRef<typeof SliderPrimitive.Thumb> = {\n\t\t\t\t\t\tclassName: cn(\n\t\t\t\t\t\t\t\"block h-4 w-4 rounded-full border border-basalt-primary bg-basalt-background shadow\",\n\t\t\t\t\t\t\tFOCUS_RING,\n\t\t\t\t\t\t),\n\t\t\t\t\t};\n\t\t\t\t\tif (thumbLabel !== undefined) {\n\t\t\t\t\t\tthumbProps[\"aria-label\"] = thumbLabel;\n\t\t\t\t\t}\n\t\t\t\t\tif (thumbLabelledBy !== undefined) {\n\t\t\t\t\t\tthumbProps[\"aria-labelledby\"] = thumbLabelledBy;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn <SliderPrimitive.Thumb key={index} {...thumbProps} />;\n\t\t\t\t})}\n\t\t\t</SliderPrimitive.Root>\n\t\t);\n\t},\n);\nSlider.displayName = SliderPrimitive.Root.displayName;\n"],"mappings":";;;;;;;;AAgFA,
|
|
1
|
+
{"version":3,"file":"slider.js","names":["React","SliderPrimitive","Slider","ariaLabel","ariaLabelledBy","props","isVertical","orientation","isControlled","value","initialUncontrolledCountRef","defaultValue","thumbCount","cn","BASALT_UI_CLASS","className","thumbLabel","thumbLabelledBy","labels","index","thumbProps","FOCUS_RING"],"sources":["../../src/components/slider.tsx"],"sourcesContent":["import * as SliderPrimitive from \"@radix-ui/react-slider\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { FOCUS_RING } from \"./overlay\";\n\ntype RadixSliderRootProps = React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root>;\n\nexport interface SliderProps\n\textends Omit<\n\t\tRadixSliderRootProps,\n\t\t| \"value\"\n\t\t| \"defaultValue\"\n\t\t| \"onValueChange\"\n\t\t| \"onValueCommit\"\n\t\t| \"disabled\"\n\t\t| \"name\"\n\t\t| \"min\"\n\t\t| \"max\"\n\t\t| \"step\"\n\t\t| \"orientation\"\n\t> {\n\t/**\n\t * Controlled value array for the slider. Forwards ref to root span element.\n\t * When multiple values are provided, renders a thumb for each value.\n\t */\n\tvalue?: RadixSliderRootProps[\"value\"];\n\t/**\n\t * Uncontrolled default value array for the slider.\n\t * When multiple values are provided, renders a thumb for each value.\n\t * @default [min ?? 0]\n\t */\n\tdefaultValue?: RadixSliderRootProps[\"defaultValue\"];\n\t/**\n\t * Callback invoked when slider value changes during interaction.\n\t */\n\tonValueChange?: RadixSliderRootProps[\"onValueChange\"];\n\t/**\n\t * Callback invoked when slider interaction finishes and value is committed.\n\t */\n\tonValueCommit?: RadixSliderRootProps[\"onValueCommit\"];\n\t/**\n\t * Whether the slider is disabled from user interaction.\n\t * @default false\n\t */\n\tdisabled?: RadixSliderRootProps[\"disabled\"];\n\t/**\n\t * Form field name submitted with the slider values.\n\t */\n\tname?: RadixSliderRootProps[\"name\"];\n\t/**\n\t * Minimum allowable value.\n\t * @default 0\n\t */\n\tmin?: RadixSliderRootProps[\"min\"];\n\t/**\n\t * Maximum allowable value.\n\t * @default 100\n\t */\n\tmax?: RadixSliderRootProps[\"max\"];\n\t/**\n\t * Step interval between selectable values.\n\t * @default 1\n\t */\n\tstep?: RadixSliderRootProps[\"step\"];\n\t/**\n\t * Layout orientation of the slider track.\n\t * When set to `\"vertical\"`, the slider track and range align vertically. A container with an explicit height is required.\n\t * @default \"horizontal\"\n\t */\n\torientation?: RadixSliderRootProps[\"orientation\"];\n\t/**\n\t * Accessible labels for thumbs when rendering single or multiple values.\n\t * When provided, thumb at index `i` receives `labels[i]`. For a single thumb, `labels[0]` takes precedence over `aria-label`.\n\t * When omitted on a multi-value slider, the root `aria-label` provides a contextual fallback (e.g. `ariaLabel + \" minimum\"`),\n\t * or falls back to Radix default names (`\"Minimum\"`, `\"Maximum\"`, or `\"Value N of Total\"`).\n\t */\n\tlabels?: string[];\n}\n\nexport const Slider = React.forwardRef<React.ElementRef<typeof SliderPrimitive.Root>, SliderProps>(\n\t(\n\t\t{\n\t\t\tclassName,\n\t\t\tvalue,\n\t\t\tdefaultValue,\n\t\t\tmin = 0,\n\t\t\tmax = 100,\n\t\t\torientation = \"horizontal\",\n\t\t\tlabels,\n\t\t\t\"aria-label\": ariaLabel,\n\t\t\t\"aria-labelledby\": ariaLabelledBy,\n\t\t\t...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst isVertical = orientation === \"vertical\";\n\t\tconst isControlled = value !== undefined;\n\n\t\tconst initialUncontrolledCountRef = React.useRef(defaultValue?.length ?? 1);\n\t\tconst thumbCount = isControlled ? (value?.length ?? 0) : initialUncontrolledCountRef.current;\n\n\t\treturn (\n\t\t\t<SliderPrimitive.Root\n\t\t\t\tref={ref}\n\t\t\t\tmin={min}\n\t\t\t\tmax={max}\n\t\t\t\torientation={orientation}\n\t\t\t\tvalue={value}\n\t\t\t\tdefaultValue={defaultValue}\n\t\t\t\taria-label={ariaLabel}\n\t\t\t\taria-labelledby={ariaLabelledBy}\n\t\t\t\tclassName={cn(\n\t\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\t\"relative flex touch-none select-none items-center\",\n\t\t\t\t\tisVertical ? \"h-full w-auto flex-col justify-center\" : \"h-auto w-full\",\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<SliderPrimitive.Track\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"relative grow overflow-hidden rounded-full bg-basalt-muted\",\n\t\t\t\t\t\tisVertical ? \"h-full w-2\" : \"h-2 w-full\",\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t<SliderPrimitive.Range\n\t\t\t\t\t\tclassName={cn(\"absolute bg-basalt-primary\", isVertical ? \"w-full\" : \"h-full\")}\n\t\t\t\t\t/>\n\t\t\t\t</SliderPrimitive.Track>\n\t\t\t\t{Array.from({ length: thumbCount }, (_, index) => {\n\t\t\t\t\tlet thumbLabel: string | undefined;\n\t\t\t\t\tlet thumbLabelledBy: string | undefined;\n\n\t\t\t\t\tif (thumbCount === 1) {\n\t\t\t\t\t\tthumbLabel = labels?.[0] ?? ariaLabel;\n\t\t\t\t\t\tthumbLabelledBy = ariaLabelledBy;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (labels?.[index] !== undefined) {\n\t\t\t\t\t\t\tthumbLabel = labels[index];\n\t\t\t\t\t\t} else if (ariaLabel) {\n\t\t\t\t\t\t\tif (thumbCount === 2) {\n\t\t\t\t\t\t\t\tconst suffix = index === 0 ? \"minimum\" : \"maximum\";\n\t\t\t\t\t\t\t\tthumbLabel = `${ariaLabel} ${suffix}`;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthumbLabel = `${ariaLabel} thumb ${index + 1} of ${thumbCount}`;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst thumbProps: React.ComponentPropsWithoutRef<typeof SliderPrimitive.Thumb> = {\n\t\t\t\t\t\tclassName: cn(\n\t\t\t\t\t\t\t\"block h-4 w-4 rounded-full border border-basalt-primary bg-basalt-background shadow\",\n\t\t\t\t\t\t\tFOCUS_RING,\n\t\t\t\t\t\t),\n\t\t\t\t\t};\n\t\t\t\t\tif (thumbLabel !== undefined) {\n\t\t\t\t\t\tthumbProps[\"aria-label\"] = thumbLabel;\n\t\t\t\t\t}\n\t\t\t\t\tif (thumbLabelledBy !== undefined) {\n\t\t\t\t\t\tthumbProps[\"aria-labelledby\"] = thumbLabelledBy;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn <SliderPrimitive.Thumb key={index} {...thumbProps} />;\n\t\t\t\t})}\n\t\t\t</SliderPrimitive.Root>\n\t\t);\n\t},\n);\nSlider.displayName = SliderPrimitive.Root.displayName;\n"],"mappings":";;;;;;;;AAgFA,IAAaE,IAASF,EAAM,YAE1B,EACC,cACA,UACA,iBACA,SAAM,GACN,SAAM,KACN,iBAAc,cACd,WACA,cAAcG,GACd,mBAAmBC,GACnB,GAAGC,KAEJ,MACI;CACJ,IAAMC,IAAaC,MAAgB,YAC7BC,IAAeC,MAAU,KAAA,GAEzBC,IAA8BV,EAAM,OAAOW,GAAc,UAAU,CAAC,GACpEC,IAAaJ,IAAgBC,GAAO,UAAU,IAAKC,EAA4B;CAErF,OACC,kBAACT,EAAgB,MAAjB;EACM;EACA;EACA;EACQ;EACN;EACO;EACd,cAAYE;EACZ,mBAAiBC;EACjB,WAAWS,EACVC,GACA,qDACAR,IAAa,0CAA0C,iBACvDS,CACD;EACA,GAAIV;EAfL,UAAA,CAiBC,kBAACJ,EAAgB,OAAjB;GACC,WAAWY,EACV,8DACAP,IAAa,eAAe,YAC7B;GAEA,UAAA,kBAACL,EAAgB,OAAjB,EACC,WAAWY,EAAG,8BAA8BP,IAAa,WAAW,QAAQ,EAC5E,CAAA;EACqB,CAAA,GACtB,MAAM,KAAK,EAAE,QAAQM,EAAW,IAAI,GAAG,MAAU;GACjD,IAAII,GACAC;GAEJ,AAAIL,MAAe,KAClB,IAAaM,IAAS,MAAMf,GAC5B,IAAkBC,KAEdc,IAASC,OAAW,KAAA,IAEbhB,MACV,AAICa,IAJGJ,MAAe,IAEL,GAAGT,EAAU,GADXgB,MAAU,IAAI,YAAY,cAG5B,GAAGhB,EAAU,SAASgB,IAAQ,EAAE,MAAMP,OANpD,IAAaM,EAAOC;GAWtB,IAAMC,IAA2E,EAChF,WAAWP,EACV,uFACAQ,CACD,EACD;GAQA,OAPIL,MAAe,KAAA,MAClB,EAAW,gBAAgBA,IAExBC,MAAoB,KAAA,MACvB,EAAW,qBAAqBA,IAG1B,kBAAChB,EAAgB,OAAjB,EAAmC,GAAImB,EAAa,GAAxBD,CAAwB;EAC5D,CAAC,CACoB;;AAExB,CACD;AACA,EAAO,cAAclB,EAAgB,KAAK"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stat-strip.js","names":[],"sources":["../../src/components/stat-strip.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { SkeletonLine } from \"./skeleton-line\";\n\nexport interface StatStripItem {\n\t/** The visible label for this statistic. */\n\tlabel: React.ReactNode;\n\t/** The visible value for this statistic. */\n\tvalue: React.ReactNode;\n}\n\nexport interface StatStripProps\n\textends Omit<React.HTMLAttributes<HTMLDListElement>, \"children\" | \"className\"> {\n\t/** Additional classes for the definition list. */\n\tclassName?: string;\n\t/** The labelled values shown in the strip. */\n\titems: readonly StatStripItem[];\n\t/**\n\t * Replace each value with a skeleton while keeping labels visible.\n\t * @default false\n\t */\n\tloading?: boolean;\n}\n\nexport const StatStrip = React.forwardRef<HTMLDListElement, StatStripProps>(\n\t({ \"aria-busy\": ariaBusy, className, items, loading = false, ...props }, ref) => {\n\t\treturn (\n\t\t\t<dl\n\t\t\t\tref={ref}\n\t\t\t\tclassName={cn(BASALT_UI_CLASS, \"grid grid-cols-2 gap-3 md:grid-cols-4\", className)}\n\t\t\t\t{...props}\n\t\t\t\taria-busy={loading ? true : ariaBusy}\n\t\t\t>\n\t\t\t\t{items.map((item, index) => (\n\t\t\t\t\t<div\n\t\t\t\t\t\tkey={index}\n\t\t\t\t\t\tclassName=\"rounded-basalt-lg bg-basalt-muted p-4 ring-1 ring-basalt-border\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<dt className=\"text-sm font-medium text-basalt-muted-foreground\">{item.label}</dt>\n\t\t\t\t\t\t<dd className=\"mt-1 text-lg font-medium tabular-nums text-basalt-foreground\">\n\t\t\t\t\t\t\t{loading ? <SkeletonLine /> : item.value}\n\t\t\t\t\t\t</dd>\n\t\t\t\t\t</div>\n\t\t\t\t))}\n\t\t\t</dl>\n\t\t);\n\t},\n);\nStatStrip.displayName = \"StatStrip\";\n"],"mappings":";;;;;;;AAyBA,
|
|
1
|
+
{"version":3,"file":"stat-strip.js","names":["React","StatStrip","ariaBusy","props","cn","BASALT_UI_CLASS","className","loading","items","item","SkeletonLine","index"],"sources":["../../src/components/stat-strip.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { SkeletonLine } from \"./skeleton-line\";\n\nexport interface StatStripItem {\n\t/** The visible label for this statistic. */\n\tlabel: React.ReactNode;\n\t/** The visible value for this statistic. */\n\tvalue: React.ReactNode;\n}\n\nexport interface StatStripProps\n\textends Omit<React.HTMLAttributes<HTMLDListElement>, \"children\" | \"className\"> {\n\t/** Additional classes for the definition list. */\n\tclassName?: string;\n\t/** The labelled values shown in the strip. */\n\titems: readonly StatStripItem[];\n\t/**\n\t * Replace each value with a skeleton while keeping labels visible.\n\t * @default false\n\t */\n\tloading?: boolean;\n}\n\nexport const StatStrip = React.forwardRef<HTMLDListElement, StatStripProps>(\n\t({ \"aria-busy\": ariaBusy, className, items, loading = false, ...props }, ref) => {\n\t\treturn (\n\t\t\t<dl\n\t\t\t\tref={ref}\n\t\t\t\tclassName={cn(BASALT_UI_CLASS, \"grid grid-cols-2 gap-3 md:grid-cols-4\", className)}\n\t\t\t\t{...props}\n\t\t\t\taria-busy={loading ? true : ariaBusy}\n\t\t\t>\n\t\t\t\t{items.map((item, index) => (\n\t\t\t\t\t<div\n\t\t\t\t\t\tkey={index}\n\t\t\t\t\t\tclassName=\"rounded-basalt-lg bg-basalt-muted p-4 ring-1 ring-basalt-border\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<dt className=\"text-sm font-medium text-basalt-muted-foreground\">{item.label}</dt>\n\t\t\t\t\t\t<dd className=\"mt-1 text-lg font-medium tabular-nums text-basalt-foreground\">\n\t\t\t\t\t\t\t{loading ? <SkeletonLine /> : item.value}\n\t\t\t\t\t\t</dd>\n\t\t\t\t\t</div>\n\t\t\t\t))}\n\t\t\t</dl>\n\t\t);\n\t},\n);\nStatStrip.displayName = \"StatStrip\";\n"],"mappings":";;;;;;;AAyBA,IAAaC,IAAYD,EAAM,YAC7B,EAAE,aAAaE,GAAU,cAAW,UAAO,aAAU,IAAO,GAAGC,KAAS,MAEvE,kBAAC,MAAD;CACM;CACL,WAAWC,EAAGC,GAAiB,yCAAyCC,CAAS;CACjF,GAAIH;CACJ,aAAWI,IAAU,KAAOL;CAE3B,UAAAM,EAAM,KAAK,GAAM,MACjB,kBAAC,OAAD;EAEC,WAAU;EAFX,UAAA,CAIC,kBAAC,MAAD;GAAI,WAAU;GAAoD,UAAAC,EAAK;EAAU,CAAA,GACjF,kBAAC,MAAD;GAAI,WAAU;GACZ,UAAAF,IAAU,kBAACG,GAAD,CAAe,CAAA,IAAID,EAAK;EAChC,CAAA,CACA;CAPC,GAAAE,CAOD,CACL;AACE,CAAA,CAGP;AACA,EAAU,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switch.js","names":[],"sources":["../../src/components/switch.tsx"],"sourcesContent":["import * as SwitchPrimitives from \"@radix-ui/react-switch\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { useCheckableGroup } from \"../utils/use-checkable-group\";\nimport { FOCUS_RING } from \"./overlay\";\n\ntype SwitchGroupContextValue = {\n\tvalue: string[];\n\tsetValue: (next: string[]) => void;\n\tdisabled: boolean;\n\tinvalid: boolean;\n};\n\nconst SwitchGroupContext = React.createContext<SwitchGroupContextValue | null>(null);\n\nfunction nextSwitchGroupValue(current: string[], itemValue: string, checked: boolean): string[] {\n\tif (checked) {\n\t\treturn current.includes(itemValue) ? current : [...current, itemValue];\n\t}\n\treturn current.filter((entry) => entry !== itemValue);\n}\n\nexport type SwitchProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>,\n\t\"checked\"\n> & {\n\t/**\n\t * The controlled checked state of the switch.\n\t */\n\tchecked?: boolean;\n\t/**\n\t * The visual size of the switch.\n\t * @default default\n\t */\n\tsize?: \"default\" | \"sm\";\n};\n\nexport type SwitchGroupProps = Omit<\n\tReact.ComponentPropsWithoutRef<\"fieldset\">,\n\t\"onChange\" | \"defaultValue\" | \"disabled\"\n> & {\n\t/**\n\t * The controlled selected values.\n\t */\n\tvalue?: string[];\n\t/**\n\t * The initially selected values.\n\t */\n\tdefaultValue?: string[];\n\t/**\n\t * Called when the selected values change.\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 SwitchLegendProps = React.ComponentPropsWithoutRef<\"legend\">;\n\nexport type SwitchItemProps = Omit<\n\tSwitchProps,\n\t\"checked\" | \"defaultChecked\" | \"onCheckedChange\" | \"value\"\n> & {\n\t/**\n\t * The value stored in the group when this item is on.\n\t */\n\tvalue: string;\n};\n\nconst SwitchRoot = React.forwardRef<React.ElementRef<typeof SwitchPrimitives.Root>, SwitchProps>(\n\t({ className, size = \"default\", ...props }, ref) => (\n\t\t<SwitchPrimitives.Root\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"peer inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors data-[state=checked]:bg-basalt-primary data-[state=unchecked]:bg-basalt-input disabled:cursor-not-allowed disabled:opacity-50\",\n\t\t\t\tFOCUS_RING,\n\t\t\t\tsize === \"sm\" ? \"h-4 w-7\" : \"h-6 w-11\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t\tref={ref}\n\t\t>\n\t\t\t<SwitchPrimitives.Thumb\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"pointer-events-none block rounded-full bg-white shadow-lg ring-0 transition-transform data-[state=unchecked]:translate-x-0\",\n\t\t\t\t\tsize === \"sm\"\n\t\t\t\t\t\t? \"h-3 w-3 data-[state=checked]:translate-x-3\"\n\t\t\t\t\t\t: \"h-5 w-5 data-[state=checked]:translate-x-5\",\n\t\t\t\t)}\n\t\t\t/>\n\t\t</SwitchPrimitives.Root>\n\t),\n);\nSwitchRoot.displayName = SwitchPrimitives.Root.displayName;\n\nconst SwitchGroup = React.forwardRef<HTMLFieldSetElement, SwitchGroupProps>(\n\t(\n\t\t{\n\t\t\tclassName,\n\t\t\tvalue,\n\t\t\tdefaultValue,\n\t\t\tonValueChange,\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...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst group = useCheckableGroup({\n\t\t\tvalue,\n\t\t\tdefaultValue,\n\t\t\tonValueChange,\n\t\t\terror,\n\t\t\tdescribedBy,\n\t\t\tariaInvalid,\n\t\t\tform: props.form,\n\t\t\tref,\n\t\t});\n\t\treturn (\n\t\t\t<SwitchGroupContext.Provider\n\t\t\t\tvalue={{ value: group.current, setValue: group.setValue, disabled, invalid: group.invalid }}\n\t\t\t>\n\t\t\t\t<fieldset\n\t\t\t\t\tref={group.setRefs}\n\t\t\t\t\t{...props}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\taria-invalid={group.ariaInvalid}\n\t\t\t\t\taria-describedby={group.mergedDescribedBy}\n\t\t\t\t\tclassName={cn(\"flex flex-col gap-2\", className)}\n\t\t\t\t>\n\t\t\t\t\t{children}\n\t\t\t\t\t{group.invalid ? (\n\t\t\t\t\t\t<p id={group.errorId} className=\"text-xs text-basalt-destructive\" role=\"alert\">\n\t\t\t\t\t\t\t{error}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t) : null}\n\t\t\t\t</fieldset>\n\t\t\t</SwitchGroupContext.Provider>\n\t\t);\n\t},\n);\nSwitchGroup.displayName = \"Switch.Group\";\n\nconst SwitchLegend = React.forwardRef<HTMLLegendElement, SwitchLegendProps>(\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);\nSwitchLegend.displayName = \"Switch.Legend\";\n\nconst SwitchItem = React.forwardRef<\n\tReact.ElementRef<typeof SwitchPrimitives.Root>,\n\tSwitchItemProps\n>(({ className, value, children, disabled, size, id, ...props }, ref) => {\n\tconst group = React.useContext(SwitchGroupContext);\n\tconst grouped = group != null;\n\tconst generatedId = React.useId();\n\tconst controlId = id ?? generatedId;\n\tconst isChecked = grouped ? group.value.includes(value) : undefined;\n\tconst box = (\n\t\t<SwitchRoot\n\t\t\tref={ref}\n\t\t\t{...props}\n\t\t\tid={controlId}\n\t\t\tvalue={value}\n\t\t\tsize={size}\n\t\t\tchecked={isChecked}\n\t\t\tdefaultChecked={grouped ? isChecked : undefined}\n\t\t\tdisabled={disabled || group?.disabled}\n\t\t\taria-invalid={group?.invalid || undefined}\n\t\t\tclassName={className}\n\t\t\tonCheckedChange={(next) => {\n\t\t\t\tif (grouped) {\n\t\t\t\t\tgroup.setValue(nextSwitchGroupValue(group.value, value, next));\n\t\t\t\t}\n\t\t\t}}\n\t\t/>\n\t);\n\tif (children == null) {\n\t\treturn box;\n\t}\n\treturn (\n\t\t<label htmlFor={controlId} className=\"flex items-center gap-2 text-sm text-basalt-foreground\">\n\t\t\t{box}\n\t\t\t{children}\n\t\t</label>\n\t);\n});\nSwitchItem.displayName = \"Switch.Item\";\n\nexport const Switch = Object.assign(SwitchRoot, {\n\tGroup: SwitchGroup,\n\tLegend: SwitchLegend,\n\tItem: SwitchItem,\n});\n"],"mappings":";;;;;;;;;AAcA,
|
|
1
|
+
{"version":3,"file":"switch.js","names":["React","SwitchPrimitives","SwitchGroupContext","nextSwitchGroupValue","checked","current","itemValue","entry","SwitchRoot","props","cn","BASALT_UI_CLASS","FOCUS_RING","size","className","SwitchGroup","describedBy","ariaInvalid","group","useCheckableGroup","children","error","SwitchLegend","SwitchItem","grouped","generatedId","controlId","id","isChecked","value","box","disabled","next","Switch"],"sources":["../../src/components/switch.tsx"],"sourcesContent":["import * as SwitchPrimitives from \"@radix-ui/react-switch\";\nimport * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { useCheckableGroup } from \"../utils/use-checkable-group\";\nimport { FOCUS_RING } from \"./overlay\";\n\ntype SwitchGroupContextValue = {\n\tvalue: string[];\n\tsetValue: (next: string[]) => void;\n\tdisabled: boolean;\n\tinvalid: boolean;\n};\n\nconst SwitchGroupContext = React.createContext<SwitchGroupContextValue | null>(null);\n\nfunction nextSwitchGroupValue(current: string[], itemValue: string, checked: boolean): string[] {\n\tif (checked) {\n\t\treturn current.includes(itemValue) ? current : [...current, itemValue];\n\t}\n\treturn current.filter((entry) => entry !== itemValue);\n}\n\nexport type SwitchProps = Omit<\n\tReact.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>,\n\t\"checked\"\n> & {\n\t/**\n\t * The controlled checked state of the switch.\n\t */\n\tchecked?: boolean;\n\t/**\n\t * The visual size of the switch.\n\t * @default default\n\t */\n\tsize?: \"default\" | \"sm\";\n};\n\nexport type SwitchGroupProps = Omit<\n\tReact.ComponentPropsWithoutRef<\"fieldset\">,\n\t\"onChange\" | \"defaultValue\" | \"disabled\"\n> & {\n\t/**\n\t * The controlled selected values.\n\t */\n\tvalue?: string[];\n\t/**\n\t * The initially selected values.\n\t */\n\tdefaultValue?: string[];\n\t/**\n\t * Called when the selected values change.\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 SwitchLegendProps = React.ComponentPropsWithoutRef<\"legend\">;\n\nexport type SwitchItemProps = Omit<\n\tSwitchProps,\n\t\"checked\" | \"defaultChecked\" | \"onCheckedChange\" | \"value\"\n> & {\n\t/**\n\t * The value stored in the group when this item is on.\n\t */\n\tvalue: string;\n};\n\nconst SwitchRoot = React.forwardRef<React.ElementRef<typeof SwitchPrimitives.Root>, SwitchProps>(\n\t({ className, size = \"default\", ...props }, ref) => (\n\t\t<SwitchPrimitives.Root\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"peer inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors data-[state=checked]:bg-basalt-primary data-[state=unchecked]:bg-basalt-input disabled:cursor-not-allowed disabled:opacity-50\",\n\t\t\t\tFOCUS_RING,\n\t\t\t\tsize === \"sm\" ? \"h-4 w-7\" : \"h-6 w-11\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t\tref={ref}\n\t\t>\n\t\t\t<SwitchPrimitives.Thumb\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"pointer-events-none block rounded-full bg-white shadow-lg ring-0 transition-transform data-[state=unchecked]:translate-x-0\",\n\t\t\t\t\tsize === \"sm\"\n\t\t\t\t\t\t? \"h-3 w-3 data-[state=checked]:translate-x-3\"\n\t\t\t\t\t\t: \"h-5 w-5 data-[state=checked]:translate-x-5\",\n\t\t\t\t)}\n\t\t\t/>\n\t\t</SwitchPrimitives.Root>\n\t),\n);\nSwitchRoot.displayName = SwitchPrimitives.Root.displayName;\n\nconst SwitchGroup = React.forwardRef<HTMLFieldSetElement, SwitchGroupProps>(\n\t(\n\t\t{\n\t\t\tclassName,\n\t\t\tvalue,\n\t\t\tdefaultValue,\n\t\t\tonValueChange,\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...props\n\t\t},\n\t\tref,\n\t) => {\n\t\tconst group = useCheckableGroup({\n\t\t\tvalue,\n\t\t\tdefaultValue,\n\t\t\tonValueChange,\n\t\t\terror,\n\t\t\tdescribedBy,\n\t\t\tariaInvalid,\n\t\t\tform: props.form,\n\t\t\tref,\n\t\t});\n\t\treturn (\n\t\t\t<SwitchGroupContext.Provider\n\t\t\t\tvalue={{ value: group.current, setValue: group.setValue, disabled, invalid: group.invalid }}\n\t\t\t>\n\t\t\t\t<fieldset\n\t\t\t\t\tref={group.setRefs}\n\t\t\t\t\t{...props}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\taria-invalid={group.ariaInvalid}\n\t\t\t\t\taria-describedby={group.mergedDescribedBy}\n\t\t\t\t\tclassName={cn(\"flex flex-col gap-2\", className)}\n\t\t\t\t>\n\t\t\t\t\t{children}\n\t\t\t\t\t{group.invalid ? (\n\t\t\t\t\t\t<p id={group.errorId} className=\"text-xs text-basalt-destructive\" role=\"alert\">\n\t\t\t\t\t\t\t{error}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t) : null}\n\t\t\t\t</fieldset>\n\t\t\t</SwitchGroupContext.Provider>\n\t\t);\n\t},\n);\nSwitchGroup.displayName = \"Switch.Group\";\n\nconst SwitchLegend = React.forwardRef<HTMLLegendElement, SwitchLegendProps>(\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);\nSwitchLegend.displayName = \"Switch.Legend\";\n\nconst SwitchItem = React.forwardRef<\n\tReact.ElementRef<typeof SwitchPrimitives.Root>,\n\tSwitchItemProps\n>(({ className, value, children, disabled, size, id, ...props }, ref) => {\n\tconst group = React.useContext(SwitchGroupContext);\n\tconst grouped = group != null;\n\tconst generatedId = React.useId();\n\tconst controlId = id ?? generatedId;\n\tconst isChecked = grouped ? group.value.includes(value) : undefined;\n\tconst box = (\n\t\t<SwitchRoot\n\t\t\tref={ref}\n\t\t\t{...props}\n\t\t\tid={controlId}\n\t\t\tvalue={value}\n\t\t\tsize={size}\n\t\t\tchecked={isChecked}\n\t\t\tdefaultChecked={grouped ? isChecked : undefined}\n\t\t\tdisabled={disabled || group?.disabled}\n\t\t\taria-invalid={group?.invalid || undefined}\n\t\t\tclassName={className}\n\t\t\tonCheckedChange={(next) => {\n\t\t\t\tif (grouped) {\n\t\t\t\t\tgroup.setValue(nextSwitchGroupValue(group.value, value, next));\n\t\t\t\t}\n\t\t\t}}\n\t\t/>\n\t);\n\tif (children == null) {\n\t\treturn box;\n\t}\n\treturn (\n\t\t<label htmlFor={controlId} className=\"flex items-center gap-2 text-sm text-basalt-foreground\">\n\t\t\t{box}\n\t\t\t{children}\n\t\t</label>\n\t);\n});\nSwitchItem.displayName = \"Switch.Item\";\n\nexport const Switch = Object.assign(SwitchRoot, {\n\tGroup: SwitchGroup,\n\tLegend: SwitchLegend,\n\tItem: SwitchItem,\n});\n"],"mappings":";;;;;;;;;AAcA,IAAME,IAAqBF,EAAM,cAA8C,IAAI;AAEnF,SAASG,EAAqB,GAAmB,GAAmB,GAA4B;CAI/F,OAHIC,IACIC,EAAQ,SAASC,CAAS,IAAID,IAAU,CAAC,GAAGA,GAASC,CAAS,IAE/DD,EAAQ,QAAQ,MAAUE,MAAUD,CAAS;AACrD;AAwDA,IAAME,IAAaR,EAAM,YACvB,EAAE,cAAW,UAAO,WAAW,GAAGS,KAAS,MAC3C,kBAACR,EAAiB,MAAlB;CACC,WAAWS,EACVC,GACA,kPACAC,GACAC,MAAS,OAAO,YAAY,YAC5BC,CACD;CACA,GAAIL;CACC;CAEL,UAAA,kBAACR,EAAiB,OAAlB,EACC,WAAWS,EACV,8HACAG,MAAS,OACN,+CACA,4CACJ,EACA,CAAA;AACqB,CAAA,CAEzB;AACA,EAAW,cAAcZ,EAAiB,KAAK;AAE/C,IAAMc,IAAcf,EAAM,YAExB,EACC,cACA,UACA,iBACA,kBACA,UACA,cAAW,IACX,aACA,oBAAoBgB,GACpB,gBAAgBC,GAChB,GAAGR,KAEJ,MACI;CACJ,IAAMS,IAAQC,EAAkB;EAC/B;EACA;EACA;EACA;EACA;EACA;EACA,MAAMV,EAAM;EACZ;CACD,CAAC;CACD,OACC,kBAACP,EAAmB,UAApB;EACC,OAAO;GAAE,OAAOgB,EAAM;GAAS,UAAUA,EAAM;GAAU;GAAU,SAASA,EAAM;EAAQ;EAE1F,UAAA,kBAAC,YAAD;GACC,KAAKA,EAAM;GACX,GAAIT;GACM;GACV,gBAAcS,EAAM;GACpB,oBAAkBA,EAAM;GACxB,WAAWR,EAAG,uBAAuBI,CAAS;GAN/C,UAAA,CAQEM,GACAF,EAAM,UACN,kBAAC,KAAD;IAAG,IAAIA,EAAM;IAAS,WAAU;IAAkC,MAAK;IACrE,UAAAG;GACC,CAAA,IACA,IACK;;CACkB,CAAA;AAE/B,CACD;AACA,EAAY,cAAc;AAE1B,IAAMC,IAAetB,EAAM,YACzB,EAAE,cAAW,GAAGS,KAAS,MACzB,kBAAC,UAAD;CACM;CACL,WAAWC,EAAG,8CAA8CI,CAAS;CACrE,GAAIL;AACJ,CAAA,CAEH;AACA,EAAa,cAAc;AAE3B,IAAMc,IAAavB,EAAM,YAGtB,EAAE,cAAW,UAAO,aAAU,aAAU,SAAM,OAAI,GAAGS,KAAS,MAAQ;CACxE,IAAMS,IAAQlB,EAAM,WAAWE,CAAkB,GAC3CsB,IAAUN,KAAS,MACnBO,IAAczB,EAAM,MAAM,GAC1B0B,IAAYC,KAAMF,GAClBG,IAAYJ,IAAUN,EAAM,MAAM,SAASW,CAAK,IAAI,KAAA,GACpDC,IACL,kBAACtB,GAAD;EACM;EACL,GAAIC;EACJ,IAAIiB;EACG;EACD;EACN,SAASE;EACT,gBAAgBJ,IAAUI,IAAY,KAAA;EACtC,UAAUG,KAAYb,GAAO;EAC7B,gBAAcA,GAAO,WAAW,KAAA;EACrB;EACX,kBAAkB,MAAS;GAC1B,AAAIM,KACHN,EAAM,SAASf,EAAqBe,EAAM,OAAOW,GAAOG,CAAI,CAAC;EAE/D;CACA,CAAA;CAKF,OAHIZ,KAAY,OACRU,IAGP,kBAAC,SAAD;EAAO,SAASJ;EAAW,WAAU;EAArC,UAAA,CACEI,GACAV,CACK;;AAET,CAAC;AACD,EAAW,cAAc;AAEzB,IAAaa,IAAS,OAAO,OAAOzB,GAAY;CAC/C,OAAOO;CACP,QAAQO;CACR,MAAMC;AACP,CAAC"}
|