{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"toolbar","title":"Toolbar","description":"Keyboard-navigable group of application controls.","dependencies":["@base-ui/react@1.7.0"],"registryDependencies":["@siteplane/base","@siteplane/button","@siteplane/input","@siteplane/separator"],"files":[{"path":"packages/ui/src/components/toolbar/toolbar.tsx","content":"\"use client\";\n\nimport { Toolbar as ToolbarPrimitive } from \"@base-ui/react/toolbar\";\nimport * as React from \"react\";\nimport {\n  type SiteplaneControlSize,\n  useResolvedControlSize,\n} from \"../../system/provider/siteplane-ui-provider\";\nimport { cn, type WithStringClassName } from \"../../system/utils/cn\";\nimport { slotClass } from \"../../system/utils/slot-class\";\nimport { Button, type ButtonStandardProps } from \"../button\";\nimport { Input, type InputProps } from \"../input\";\nimport { Separator } from \"../separator\";\n\n/** The size of the enclosing Toolbar, which its parts take by default. */\nconst ToolbarSizeContext = React.createContext<SiteplaneControlSize | null>(\n  null,\n);\n\n/** A part's own size, else the Toolbar's, else the provider's (S1). */\nfunction useToolbarSize(\n  size: SiteplaneControlSize | undefined,\n): SiteplaneControlSize {\n  const toolbarSize = React.useContext(ToolbarSizeContext);\n  return useResolvedControlSize(size ?? toolbarSize);\n}\n\nexport function Toolbar({\n  className,\n  size,\n  ...props\n}: WithStringClassName<ToolbarPrimitive.Root.Props> & {\n  /** The control size of the toolbar's buttons, links, groups and input. */\n  size?: SiteplaneControlSize | undefined;\n}): React.ReactElement {\n  const resolvedSize = useToolbarSize(size);\n  return (\n    <ToolbarSizeContext.Provider value={resolvedSize}>\n      <ToolbarPrimitive.Root\n        className={cn(\n          // A bare icon takes the icon of the control scale, like the Buttons\n          // and Toggles beside it: 16 px, 20 px at xl.\n          slotClass(\"toolbar\", props),\n          \"relative flex flex-wrap items-center gap-2 data-[orientation=vertical]:w-fit data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch [&>svg]:pointer-events-none [&>svg]:shrink-0 [&>svg:not([class*='opacity-'])]:opacity-80 [&>svg:not([class*='size-'])]:size-(--sp-rw-control-icon)\",\n          resolvedSize === \"xl\" &&\n            \"[&>svg:not([class*='size-'])]:size-(--sp-rw-control-icon-xl)\",\n          className,\n        )}\n        data-size={resolvedSize}\n        data-slot=\"toolbar\"\n        {...props}\n      />\n    </ToolbarSizeContext.Provider>\n  );\n}\nexport function ToolbarButton({\n  className,\n  render,\n  size,\n  ...props\n}: WithStringClassName<ToolbarPrimitive.Button.Props> & {\n  size?: SiteplaneControlSize | undefined;\n}): React.ReactElement {\n  const resolvedSize = useToolbarSize(size);\n  return (\n    <ToolbarPrimitive.Button\n      className={cn(slotClass(\"toolbar-button\", props, render), className)}\n      data-slot=\"toolbar-button\"\n      render={\n        render ??\n        ((toolbarProps, state) => (\n          <Button\n            {...(toolbarProps as ButtonStandardProps)}\n            aria-disabled={state.disabled || undefined}\n            disabled={state.disabled && !state.focusable}\n            size={resolvedSize}\n            variant=\"ghost\"\n          />\n        ))\n      }\n      {...props}\n    />\n  );\n}\nexport function ToolbarLink({\n  className,\n  render,\n  size,\n  ...props\n}: WithStringClassName<ToolbarPrimitive.Link.Props> & {\n  size?: SiteplaneControlSize | undefined;\n}): React.ReactElement {\n  const resolvedSize = useToolbarSize(size);\n  return (\n    <ToolbarPrimitive.Link\n      className={cn(slotClass(\"toolbar-link\", props), className)}\n      data-slot=\"toolbar-link\"\n      render={\n        typeof render === \"function\" ? (\n          (toolbarProps, toolbarState) => (\n            <Button\n              {...(toolbarProps as unknown as ButtonStandardProps)}\n              render={(buttonProps) =>\n                render(\n                  buttonProps as React.ComponentPropsWithRef<\"a\">,\n                  toolbarState,\n                )\n              }\n              size={resolvedSize}\n              variant=\"ghost\"\n            />\n          )\n        ) : (\n          <Button\n            render={render ?? <a />}\n            size={resolvedSize}\n            variant=\"ghost\"\n          />\n        )\n      }\n      {...props}\n    />\n  );\n}\nexport function ToolbarInput({\n  className,\n  insetStart,\n  insetEnd,\n  render,\n  ...props\n}: WithStringClassName<ToolbarPrimitive.Input.Props> &\n  Pick<InputProps, \"insetStart\" | \"insetEnd\">): React.ReactElement {\n  const resolvedSize = useToolbarSize(undefined);\n  return (\n    <ToolbarPrimitive.Input\n      className={cn(\n        slotClass(\"toolbar-input\", props),\n        \"min-w-0 flex-1\",\n        className,\n      )}\n      data-slot=\"toolbar-input\"\n      render={\n        typeof render === \"function\" ? (\n          (toolbarProps, toolbarState) => (\n            <Input\n              size={resolvedSize}\n              {...(toolbarProps as InputProps)}\n              insetStart={insetStart}\n              insetEnd={insetEnd}\n              render={(inputProps) => render(inputProps, toolbarState)}\n            />\n          )\n        ) : (\n          <Input\n            insetStart={insetStart}\n            insetEnd={insetEnd}\n            render={render}\n            size={resolvedSize}\n          />\n        )\n      }\n      {...props}\n    />\n  );\n}\nexport function ToolbarGroup({\n  className,\n  size,\n  ...props\n}: WithStringClassName<ToolbarPrimitive.Group.Props> & {\n  size?: SiteplaneControlSize | undefined;\n}): React.ReactElement {\n  const resolvedSize = useToolbarSize(size);\n  return (\n    <ToolbarSizeContext.Provider value={resolvedSize}>\n      <ToolbarPrimitive.Group\n        className={cn(\n          slotClass(\"toolbar-group\", props),\n          \"flex min-w-0 items-center gap-1 [&>svg]:pointer-events-none [&>svg]:shrink-0 [&>svg:not([class*='opacity-'])]:opacity-80 [&>svg:not([class*='size-'])]:size-(--sp-rw-control-icon)\",\n          resolvedSize === \"xl\" &&\n            \"[&>svg:not([class*='size-'])]:size-(--sp-rw-control-icon-xl)\",\n          className,\n        )}\n        data-size={resolvedSize}\n        data-slot=\"toolbar-group\"\n        {...props}\n      />\n    </ToolbarSizeContext.Provider>\n  );\n}\nexport function ToolbarSeparator({\n  className,\n  ...props\n}: WithStringClassName<ToolbarPrimitive.Separator.Props>): React.ReactElement {\n  return (\n    <ToolbarPrimitive.Separator\n      className={cn(\n        slotClass(\"toolbar-separator\", props),\n        \"data-[orientation=horizontal]:my-0.5\",\n        className,\n      )}\n      data-slot=\"toolbar-separator\"\n      render={<Separator />}\n      {...props}\n    />\n  );\n}\nexport { ToolbarPrimitive };\n","type":"registry:ui","target":"~/src/siteplane/components/toolbar/toolbar.tsx"},{"path":"packages/ui/src/components/toolbar/index.ts","content":"export * from \"./toolbar\";\n","type":"registry:ui","target":"~/src/siteplane/components/toolbar/index.ts"}],"type":"registry:ui","docs":"https://ui.siteplane.io/docs-markdown/components/toolbar.md","categories":["Actions"],"meta":{"avoidWhen":["Avoid for a few unrelated buttons; use plain Buttons or Group.","Avoid for choosing among options; use Toggle Group."],"description":"Keyboard-navigable group of application controls.","knownLimitations":[],"providerNotes":[],"releaseStatus":"stable","searchTerms":["toolbar"],"useWhen":["Use for a group of related actions that share one tab stop and arrow-key navigation, such as the formatting controls of an editor."]}}