{
  "name": "ButtonGroup",
  "source": "src/components/ButtonGroup.tsx",
  "propsType": "ButtonGroupProps",
  "description": "ButtonGroup — a row of actions: a dialog's Cancel and Confirm, a form's\nBack, Save and Next, the actions at the top of a record.\n\nWHAT IT OWNS, SO NO CALLER HAS TO\n\n  - Spacing: 8px between actions, everywhere. Before this, dialogs used\n    12, drawers and page headers 8, and forms whatever their author chose.\n  - Order: children are drawn in the order they are read. The primary\n    goes last, so it lands at the end of the row in either direction —\n    and at the bottom, nearest the thumb, when `stack` stacks them. There\n    is no `row-reverse`: an order that differs on screen and in the Tab\n    sequence fails WCAG 2.4.3.\n  - Overflow, when asked: `overflow=\"menu\"` measures the row and moves\n    the Buttons that do not fit into a MenuTrigger, first Button first. A\n    menu item presses the real Button, which stays in the page hidden —\n    so its `onPress`, its `onClick` and a `type=\"submit\"` all behave as\n    if it had been clicked.\n\nNOT A TOOLBAR. Every action here is its own tab stop, which is what a\nkeyboard user expects of two or three buttons. A row of many controls on\none thing — formatting, a table's batch actions — is a Toolbar: one tab\nstop, arrow keys inside.",
  "import": "import { ButtonGroup } from 'ionbase-ui';",
  "status": "stable",
  "summary": "A row of actions — a dialog's Cancel and Confirm, a form's Back, Save and Next, a record's header actions. Owns the gap, the order and what happens when the row runs out of room.",
  "useWhen": [
    "two or more actions sit together: a dialog or drawer footer, the end of a form, a page or card header",
    "one action is primary and the rest are alternatives to it",
    "the row may be narrower than its actions — a phone, a side panel — and has to wrap, stack or overflow rather than spill"
  ],
  "useInstead": [
    {
      "when": "many controls act on one thing — a table's batch actions, an editor's formatting",
      "use": "Toolbar",
      "why": "a toolbar is one tab stop with arrow keys inside; a ButtonGroup is a tab stop per action, which is right for two or three and tiring for ten"
    },
    {
      "when": "the buttons are one choice among options, one of them selected",
      "use": "SegmentedControl",
      "why": "that is a radio group with a value; a ButtonGroup holds independent actions"
    },
    {
      "when": "a single action",
      "use": "Button",
      "why": "a group of one adds nothing"
    }
  ],
  "composition": {
    "order": [
      "ButtonGroup",
      "Button"
    ],
    "note": "Children in reading order, least important first, the primary last. It is drawn in that order: the primary lands at the end of the row in either direction, and last in the stack on a phone.",
    "example": "<ButtonGroup stack start={<Button variant=\"tertiary\">Back</Button>}><Button variant=\"secondary\">Save and exit</Button><Button type=\"submit\">Next</Button></ButtonGroup>"
  },
  "variants": {
    "align": {
      "end": {
        "use": "the default — dialog, drawer and form footers"
      },
      "start": {
        "use": "actions under a left-aligned block of text"
      },
      "center": {
        "use": "a centred dialog or empty state"
      }
    },
    "overflow": {
      "wrap": {
        "use": "the default — actions that do not fit move to a second line, all still shown"
      },
      "menu": {
        "use": "a header row that must stay one line: the Buttons that do not fit move into More actions, first Button first; the primary and anything that is not a Button stay"
      }
    }
  },
  "slots": {
    "children": {
      "accepts": "Button, SplitButton, Link, AgentStop, MenuTrigger",
      "note": "the actions, primary last. With `overflow=\"menu\"` only Buttons move, and each needs a text label or `aria-label` — it is what the menu item says"
    },
    "start": {
      "accepts": "Button, text",
      "note": "pinned to the start edge, apart from the rest — Back in a wizard, a count in a save bar. It never collapses"
    }
  },
  "a11y": {
    "requires": [
      "the primary last among the children — the order is the reading, Tab and drawn order, and nothing reorders it",
      "with `overflow=\"menu\"`, a text label or `aria-label` on every Button that may move, and `moreLabel` translated"
    ],
    "guarantees": [
      "every action is its own tab stop, in the order it is read; no `row-reverse`, so the drawn order never contradicts the Tab order (WCAG 2.4.3)",
      "8px between actions, and between `start` and the rest",
      "the order mirrors in a right-to-left locale: the primary is at the start of the line there",
      "`stack` below 32rem of viewport: one action per line, full width, in reading order, the primary last and nearest the thumb",
      "`overflow=\"menu\"` keeps the row on one line and inside its box. The Buttons that do not fit move into a MenuTrigger named \"More actions\" at the row's start; hidden ones are out of the Tab order and the accessibility tree",
      "a menu item presses the real Button, so its `onPress`, its `onClick` and `type=\"submit\"` behave as if it were clicked; a disabled Button is a disabled menu item",
      "with room again, every action comes back and More goes — also in a parent that sizes to its content, such as PageHeader's actions"
    ],
    "notes": [
      "a menu item cannot show a Button's variant: a destructive action that must look destructive should not be allowed to overflow — make it the primary, or put it in `start`",
      "Enter in a form submits the first submit button in the DOM order; with the primary last, give the others `type=\"button\"` (IonBase's Button is `type=\"button\"` unless told otherwise)"
    ]
  },
  "antiPatterns": [
    {
      "dont": "<div style={{ display: 'flex', gap: 12, justifyContent: 'flex-end' }}>",
      "do": "<ButtonGroup>",
      "why": "hand-built rows each pick their own gap and none decides what happens on a phone — the demo had 8, 12 and a spacer span"
    },
    {
      "dont": "flex-direction: row-reverse, to put the primary on the right while it comes first in the markup",
      "do": "the primary last among the children",
      "why": "Tab then walks the row backwards from how it is drawn, and a screen reader reads the primary before the options it is chosen over"
    },
    {
      "dont": "<ButtonGroup overflow=\"menu\"> around icon-only Buttons with no `aria-label`",
      "do": "an `aria-label` on each, which becomes its menu item's text",
      "why": "a collapsed icon-only Button has nothing to be called in the menu"
    },
    {
      "dont": "a ButtonGroup of ten actions on one record",
      "do": "<Toolbar>, or a MenuTrigger for the rare ones",
      "why": "ten tab stops in a row is ten presses to get past it"
    }
  ],
  "stylesheet": "src/styles/button-group.css",
  "tokens": [
    "--spacing-8"
  ],
  "props": {
    "children": {
      "type": "React.ReactNode",
      "required": true,
      "origin": "own",
      "description": "The actions, least important first and the primary last — the order\nthey are read and tabbed in, and the order they are drawn. Nothing is\nreordered to put the primary on the right."
    },
    "start": {
      "type": "React.ReactNode",
      "required": false,
      "origin": "own",
      "description": "Actions pinned to the start edge, apart from the rest: Back in a\nwizard, a destructive \"Delete\" in an edit dialog. They never collapse."
    },
    "align": {
      "type": "ButtonGroupAlign | undefined",
      "required": false,
      "origin": "own",
      "description": "Where the actions sit. Default `end`, the dialog and form convention.",
      "values": [
        "start",
        "center",
        "end"
      ]
    },
    "overflow": {
      "type": "ButtonGroupOverflow | undefined",
      "required": false,
      "origin": "own",
      "description": "`wrap` (default): actions that do not fit move to a second line.\n`menu`: Buttons that do not fit move into a \"More actions\" menu at the\nstart of the row, the first Button first. The last child — the primary —\nnever moves, and neither does anything that is not a Button; the\nButtons after it still can.",
      "values": [
        "menu",
        "wrap"
      ]
    },
    "stack": {
      "type": "boolean | undefined",
      "required": false,
      "origin": "own",
      "description": "Below 32rem of viewport, every action takes the full width, one per\nline, still in reading order — so the primary is last, nearest the\nthumb. For dialog and form footers."
    },
    "moreLabel": {
      "type": "string | undefined",
      "required": false,
      "origin": "own",
      "description": "The overflow trigger's name. Default \"More actions\" — pass the translation."
    }
  },
  "propCounts": {
    "own": 6,
    "aria": 0,
    "dom": 277,
    "other": 0
  }
}
