{"name":"button-group","title":"Button Group","description":"A container that groups related buttons together with consistent styling.","installCommand":"bunx marko-ui add button-group -y","usageTags":"<ButtonGroup>","importSnippet":"import ButtonGroup from \"@/components/ui/button-group/button-group.marko\";","usageSnippet":"<ButtonGroup>\n  <Button>Button 1</Button>\n  <Button>Button 2</Button>\n</ButtonGroup>","tags":["ButtonGroup","ButtonGroupSeparator","ButtonGroupText"],"parts":[],"props":[{"name":"orientation","type":"'horizontal' | 'vertical' | null | undefined","required":false,"default":"horizontal"}],"events":[],"keyboard":[{"keys":"Tab / Shift+Tab","description":"Moves focus between the buttons in the group, same as any sequence of focusable elements."}],"accessibilityNotes":["The `ButtonGroup` root renders `role=\"group\"` so assistive tech announces the buttons as one related set.","Use `aria-label` or `aria-labelledby` on `ButtonGroup` to give the group an accessible name, especially when it has no visible heading.","Icon-only buttons inside a group (a split-button's second button, a dropdown or popover trigger) need their own `aria-label` — the group's label does not substitute for a per-button accessible name."],"examples":[{"id":"button-group-demo","title":"Basic","source":"import ButtonGroup from \"@marko-ui/shadcn/ui/button-group/button-group.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\n\n<ButtonGroup>\n  <Button type=\"button\" variant=\"outline\">Back</Button>\n  <Button type=\"button\" variant=\"outline\">Next</Button>\n</ButtonGroup>","description":"Buttons that share adjacent borders and merge their corners."},{"id":"button-group-orientation","title":"Orientation","source":"import ButtonGroup from \"@marko-ui/shadcn/ui/button-group/button-group.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\n\n<ButtonGroup orientation=\"vertical\" aria-label=\"Clipboard actions\" class=\"h-fit\">\n  <Button type=\"button\" variant=\"outline\">Copy</Button>\n  <Button type=\"button\" variant=\"outline\">Paste</Button>\n  <Button type=\"button\" variant=\"outline\">Duplicate</Button>\n</ButtonGroup>","description":"Set `orientation=\"vertical\"` to stack the group instead of rowing it."},{"id":"button-group-size","title":"Size","source":"import ButtonGroup from \"@marko-ui/shadcn/ui/button-group/button-group.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\n\n<div class=\"flex flex-col items-start gap-8\">\n  <ButtonGroup>\n    <Button type=\"button\" variant=\"outline\" size=\"sm\">Small</Button>\n    <Button type=\"button\" variant=\"outline\" size=\"sm\">Button</Button>\n    <Button type=\"button\" variant=\"outline\" size=\"sm\">Group</Button>\n  </ButtonGroup>\n  <ButtonGroup>\n    <Button type=\"button\" variant=\"outline\">Default</Button>\n    <Button type=\"button\" variant=\"outline\">Button</Button>\n    <Button type=\"button\" variant=\"outline\">Group</Button>\n  </ButtonGroup>\n  <ButtonGroup>\n    <Button type=\"button\" variant=\"outline\" size=\"lg\">Large</Button>\n    <Button type=\"button\" variant=\"outline\" size=\"lg\">Button</Button>\n    <Button type=\"button\" variant=\"outline\" size=\"lg\">Group</Button>\n  </ButtonGroup>\n</div>","description":"Control the size of the whole group through the `size` prop on each `Button`."},{"id":"button-group-nested","title":"Nested","source":"import ButtonGroup from \"@marko-ui/shadcn/ui/button-group/button-group.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\n\n<ButtonGroup>\n  <ButtonGroup>\n    <Button type=\"button\" variant=\"outline\" size=\"sm\">1</Button>\n    <Button type=\"button\" variant=\"outline\" size=\"sm\">2</Button>\n    <Button type=\"button\" variant=\"outline\" size=\"sm\">3</Button>\n    <Button type=\"button\" variant=\"outline\" size=\"sm\">4</Button>\n    <Button type=\"button\" variant=\"outline\" size=\"sm\">5</Button>\n  </ButtonGroup>\n  <ButtonGroup>\n    <Button type=\"button\" variant=\"outline\" size=\"sm\" aria-label=\"Previous\">Prev</Button>\n    <Button type=\"button\" variant=\"outline\" size=\"sm\" aria-label=\"Next\">Next</Button>\n  </ButtonGroup>\n</ButtonGroup>","description":"Nest `ButtonGroup` components to add spacing between related clusters of buttons."},{"id":"button-group-separator","title":"Separator","source":"import ButtonGroup from \"@marko-ui/shadcn/ui/button-group/button-group.marko\";\nimport ButtonGroupSeparator from \"@marko-ui/shadcn/ui/button-group/separator.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\n\n<ButtonGroup>\n  <Button type=\"button\" variant=\"secondary\" size=\"sm\">Copy</Button>\n  <ButtonGroupSeparator/>\n  <Button type=\"button\" variant=\"secondary\" size=\"sm\">Paste</Button>\n</ButtonGroup>","description":"`ButtonGroupSeparator` visually divides buttons within a group. Buttons with the `outline` variant already have a border and rarely need one; other variants benefit from it."},{"id":"button-group-split","title":"Split","source":"import ButtonGroup from \"@marko-ui/shadcn/ui/button-group/button-group.marko\";\nimport ButtonGroupSeparator from \"@marko-ui/shadcn/ui/button-group/separator.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\n\n<ButtonGroup>\n  <Button type=\"button\" variant=\"secondary\">Button</Button>\n  <ButtonGroupSeparator/>\n  <Button type=\"button\" variant=\"secondary\" size=\"icon\" aria-label=\"Add\">+</Button>\n</ButtonGroup>","description":"A split button: two buttons separated by a `ButtonGroupSeparator`."},{"id":"button-group-input","title":"Input","source":"import ButtonGroup from \"@marko-ui/shadcn/ui/button-group/button-group.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\nimport TextInput from \"@marko-ui/shadcn/ui/input/input.marko\";\nimport Icon from \"@marko-ui/shadcn/ui/icon/icon.marko\";\n\n<ButtonGroup>\n  <TextInput placeholder=\"Search...\"/>\n  <Button type=\"button\" variant=\"outline\" aria-label=\"Search\">\n    <Icon name=\"SearchIcon\"/>\n  </Button>\n</ButtonGroup>","description":"Wrap an `Input` with buttons."},{"id":"button-group-input-group","title":"Input Group","source":"import ButtonGroup from \"@marko-ui/shadcn/ui/button-group/button-group.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\nimport InputGroup from \"@marko-ui/shadcn/ui/input-group/input-group.marko\";\nimport InputGroupInput from \"@marko-ui/shadcn/ui/input-group/input.marko\";\nimport InputGroupAddon from \"@marko-ui/shadcn/ui/input-group/addon.marko\";\nimport InputGroupButton from \"@marko-ui/shadcn/ui/input-group/button.marko\";\nimport Tooltip from \"@marko-ui/shadcn/ui/tooltip/tooltip.marko\";\nimport Icon from \"@marko-ui/shadcn/ui/icon/icon.marko\";\n\n<let/voiceEnabled=false/>\n\n<ButtonGroup class=\"[--radius:9999rem]\">\n  <ButtonGroup>\n    <Button type=\"button\" variant=\"outline\" size=\"icon\" aria-label=\"Add\">\n      <Icon name=\"PlusIcon\"/>\n    </Button>\n  </ButtonGroup>\n  <ButtonGroup>\n    <InputGroup>\n      <InputGroupInput\n        placeholder=(voiceEnabled ? \"Record and send audio...\" : \"Send a message...\")\n        disabled=voiceEnabled\n      />\n      <InputGroupAddon align=\"inline-end\">\n        <Tooltip content=\"Voice Mode\">\n          <@trigger|triggerProps|>\n            <InputGroupButton\n              ...triggerProps\n              onClick() { voiceEnabled = !voiceEnabled; }\n              size=\"icon-xs\"\n              data-active=String(voiceEnabled)\n              class=\"data-[active=true]:bg-orange-100 data-[active=true]:text-orange-700 dark:data-[active=true]:bg-orange-800 dark:data-[active=true]:text-orange-100\"\n              aria-pressed=(voiceEnabled ? \"true\" : \"false\")\n              aria-label=\"Voice Mode\"\n            >\n              <Icon name=\"AudioLinesIcon\"/>\n            </InputGroupButton>\n          </@trigger>\n        </Tooltip>\n      </InputGroupAddon>\n    </InputGroup>\n  </ButtonGroup>\n</ButtonGroup>","description":"Wrap an `InputGroup` to create complex input layouts."},{"id":"button-group-dropdown","title":"Dropdown Menu","source":"import ButtonGroup from \"@marko-ui/shadcn/ui/button-group/button-group.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\nimport DropdownMenu from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport type { DropdownMenuItem } from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport Icon from \"@marko-ui/shadcn/ui/icon/icon.marko\";\n\nstatic const ITEMS = [\n  { value: \"mute\", label: \"Mute Conversation\" },\n  { value: \"read\", label: \"Mark as Read\" },\n  { value: \"report\", label: \"Report Conversation\" },\n  { value: \"block\", label: \"Block User\" },\n  { value: \"share\", label: \"Share Conversation\" },\n  { value: \"copy\", label: \"Copy Conversation\" },\n  { type: \"separator\" },\n  { value: \"delete\", label: \"Delete Conversation\", variant: \"destructive\" },\n] satisfies DropdownMenuItem[];\n\n<ButtonGroup>\n  <Button type=\"button\" variant=\"outline\">Follow</Button>\n  <DropdownMenu items=ITEMS class=\"w-44\">\n    <@trigger|triggerProps|>\n      <Button type=\"button\" variant=\"outline\" ...triggerProps class=\"pl-2!\" aria-label=\"More Options\">\n        <Icon name=\"ChevronDownIcon\"/>\n      </Button>\n    </@trigger>\n  </DropdownMenu>\n</ButtonGroup>","description":"Create a split button group with a `DropdownMenu`."},{"id":"button-group-select","title":"Select","source":"import ButtonGroup from \"@marko-ui/shadcn/ui/button-group/button-group.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\nimport TextInput from \"@marko-ui/shadcn/ui/input/input.marko\";\nimport Select from \"@marko-ui/shadcn/ui/select/select.marko\";\nimport Icon from \"@marko-ui/shadcn/ui/icon/icon.marko\";\n\nstatic const CURRENCIES = [\n  { value: \"$\", label: \"US Dollar\" },\n  { value: \"€\", label: \"Euro\" },\n  { value: \"£\", label: \"British Pound\" },\n];\n\n<let/currency=[\"$\"]/>\n\n<ButtonGroup>\n  <ButtonGroup>\n    <Select\n      items=CURRENCIES\n      value=currency\n      valueChange=(next) => { currency = next; }\n    />\n    <TextInput placeholder=\"10.00\" pattern=\"[0-9]*\"/>\n  </ButtonGroup>\n  <ButtonGroup>\n    <Button type=\"button\" aria-label=\"Send\" size=\"icon\" variant=\"outline\">\n      <Icon name=\"ArrowRightIcon\"/>\n    </Button>\n  </ButtonGroup>\n</ButtonGroup>","description":"Pair with a `Select`. Upstream's `SelectTrigger` accepts arbitrary children and renders the bare currency symbol via a `font-mono` class; ours always shows the selected item's `label` (`valueAsString || placeholder`) with no custom-content slot, so the trigger reads 'US Dollar' rather than a bare '$'.","essential":true},{"id":"button-group-popover","title":"Popover","source":"import ButtonGroup from \"@marko-ui/shadcn/ui/button-group/button-group.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\nimport Icon from \"@marko-ui/shadcn/ui/icon/icon.marko\";\nimport Popover from \"@marko-ui/shadcn/ui/popover/popover.marko\";\nimport PopoverHeader from \"@marko-ui/shadcn/ui/popover/header.marko\";\nimport PopoverTitle from \"@marko-ui/shadcn/ui/popover/title.marko\";\nimport PopoverDescription from \"@marko-ui/shadcn/ui/popover/description.marko\";\nimport Field from \"@marko-ui/shadcn/ui/field/field.marko\";\nimport FieldLabel from \"@marko-ui/shadcn/ui/field/field-label.marko\";\nimport FieldDescription from \"@marko-ui/shadcn/ui/field/field-description.marko\";\nimport Textarea from \"@marko-ui/shadcn/ui/textarea/textarea.marko\";\n\n<ButtonGroup>\n  <Button type=\"button\" variant=\"outline\">\n    <Icon name=\"BotIcon\"/> Copilot\n  </Button>\n  <Popover>\n    <@trigger|triggerProps|>\n      <Button type=\"button\" variant=\"outline\" size=\"icon\" ...triggerProps aria-label=\"Open Popover\">\n        <Icon name=\"ChevronDownIcon\"/>\n      </Button>\n    </@trigger>\n    <div class=\"rounded-xl text-sm\">\n      <PopoverHeader>\n        <PopoverTitle>Start a new task with Copilot</PopoverTitle>\n        <PopoverDescription>\n          Describe your task in natural language.\n        </PopoverDescription>\n      </PopoverHeader>\n      <Field>\n        <FieldLabel for=\"task\" class=\"sr-only\">Task Description</FieldLabel>\n        <Textarea id=\"task\" placeholder=\"I need to...\" class=\"resize-none\"/>\n        <FieldDescription>\n          Copilot will open a pull request for review.\n        </FieldDescription>\n      </Field>\n    </div>\n  </Popover>\n</ButtonGroup>","description":"Use with a `Popover`."},{"id":"button-group-rtl","title":"RTL","source":"import ButtonGroup from \"@marko-ui/shadcn/ui/button-group/button-group.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\nimport DropdownMenu from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport type { DropdownMenuItem } from \"@marko-ui/shadcn/ui/dropdown-menu/dropdown-menu.marko\";\nimport Icon from \"@marko-ui/shadcn/ui/icon/icon.marko\";\n\n<let/label=\"personal\"/>\n\n<const/items=[\n  { value: \"read\", label: \"وضع علامة كمقروء\" },\n  { value: \"archive\", label: \"أرشفة\" },\n  { type: \"separator\" },\n  { value: \"snooze\", label: \"تأجيل\" },\n  { value: \"calendar\", label: \"إضافة إلى التقويم\" },\n  { value: \"list\", label: \"إضافة إلى القائمة\" },\n  {\n    type: \"sub\",\n    label: \"تصنيف كـ...\",\n    subEntries: [\n      { value: \"personal\", label: \"شخصي\", radioGroup: \"label\", checked: label === \"personal\" },\n      { value: \"work\", label: \"عمل\", radioGroup: \"label\", checked: label === \"work\" },\n      { value: \"other\", label: \"آخر\", radioGroup: \"label\", checked: label === \"other\" },\n    ],\n  },\n  { type: \"separator\" },\n  { value: \"trash\", label: \"سلة المهملات\", variant: \"destructive\" },\n] satisfies DropdownMenuItem[]/>\n\n<div dir=\"rtl\" class=\"flex justify-center\">\n  <ButtonGroup>\n    <ButtonGroup class=\"hidden sm:flex\">\n      <Button type=\"button\" variant=\"outline\" size=\"icon\" aria-label=\"Go Back\">\n        <Icon name=\"ArrowLeftIcon\" class=\"rtl:rotate-180\"/>\n      </Button>\n    </ButtonGroup>\n    <ButtonGroup>\n      <Button type=\"button\" variant=\"outline\">أرشفة</Button>\n      <Button type=\"button\" variant=\"outline\">تقرير</Button>\n    </ButtonGroup>\n    <ButtonGroup>\n      <Button type=\"button\" variant=\"outline\">تأجيل</Button>\n      <DropdownMenu\n        items=items\n        class=\"w-40\"\n        select(value) {\n          if (value === \"personal\" || value === \"work\" || value === \"other\") label = value;\n        }\n      >\n        <@trigger|triggerProps|>\n          <Button type=\"button\" variant=\"outline\" size=\"icon\" ...triggerProps aria-label=\"More Options\">\n            <Icon name=\"MoreHorizontalIcon\"/>\n          </Button>\n        </@trigger>\n      </DropdownMenu>\n    </ButtonGroup>\n  </ButtonGroup>\n</div>","description":"Set `dir=\"rtl\"` on a wrapping element for RTL text and logical-property layout. `DropdownMenu` doesn't expose the underlying Zag menu's `dir` prop, so this doesn't drive floating-ui's own RTL placement flip. Upstream's RTL demo also drives a live language switcher (English/Arabic/Hebrew); this one is static Arabic content, like every other RTL example on this site."},{"id":"button-group-text","title":"With Text","source":"import ButtonGroup from \"@marko-ui/shadcn/ui/button-group/button-group.marko\";\nimport ButtonGroupText from \"@marko-ui/shadcn/ui/button-group/text.marko\";\nimport Button from \"@marko-ui/shadcn/ui/button/button.marko\";\n\n<ButtonGroup>\n  <ButtonGroupText>Page 1 of 10</ButtonGroupText>\n  <Button type=\"button\" variant=\"outline\">Prev</Button>\n  <Button type=\"button\" variant=\"outline\">Next</Button>\n</ButtonGroup>","description":"`ButtonGroupText` renders a non-interactive label inside the group."}],"importInstallCommand":"bun add @marko-ui/shadcn marko-zag","requires":["button"],"nativeAttributes":"div","subcomponents":[{"name":"separator","props":[{"name":"orientation","type":"'horizontal' | 'vertical'","required":false}],"nativeAttributes":"div"},{"name":"text","props":[],"nativeAttributes":"div"}]}
