SplitButton
Головна дія плюс каретка з альтернативами — складена з Button і Menu, без власного позиціонування.
«Зберегти» і поруч каретка: зберегти як чернетку, як шаблон, з дублюванням. Одна дія очевидна й потрібна в 90 % випадків, решта — поруч, але не займають місця.
Остання дія: —
Композиція, а не власна реалізація
Компонент не має ні власного позиціонування, ні власної клавіатури для
панелі: він складений із UiButton і
UiMenu. Меню вже вміє фліпатись біля краю вікна,
брати z-index зі спільного стеку і закриватись по Escape — повторювати це
означало б завести другу реалізацію, яка розійдеться з першою.
Обидві кнопки живуть усередині слота trigger меню. Це не примха
розкладки: APG вимагає, щоб ArrowDown на головній кнопці теж відкривав
меню, а toggle доступний лише всередині цього слота. triggerAttrs
при цьому йде тільки на каретку — панеллю керує вона, а не група.
Шов
Дві кнопки з rounded-control поруч дають подвоєну лінію на outline і
видимий стик на solid. Тому в головної зрізаний правий кут, у каретки —
лівий, і каретка підтягнута на -1px.
focus-visible:z-10 на обох обов'язковий: без нього сусідня кнопка
підрізає кільце фокуса рівно з того боку, де вони стикаються.
API
Props
| Назва | Тип | Типово | Опис |
|---|---|---|---|
items | SplitButtonItem[] | [] | Альтернативні дії в меню під кареткою. |
variant | solidsoftoutlineghostdanger | "solid" | Візуальна вага. Обидві кнопки завжди в одному варіанті. |
size | mdsmlg | "md" | Висота обох кнопок. |
type | buttonsubmitreset | "button" | Тип головної кнопки. Ігнорується, коли задано `to`. |
groupLabel | string | "Дія з варіантами" | Доступна назва ГРУПИ. Без неї скрінрідер читає дві сусідні кнопки як незв'язані, і призначення каретки лишається невідомим. |
menuLabel | string | "Інші дії" | Доступна назва каретки — власного тексту вона не має. |
placement | bottom-endbottom-startbottomtopright | "bottom-end" | Куди відкривати меню. Проксується в `UiMenu`. |
label | string | — | Підпис головної дії. Складніший вміст — слот `default`. |
to | string | — | Робить головну кнопку посиланням. Каретка лишається кнопкою. |
menuWidth | string | — | Ширина панелі меню, напр. `"14rem"`. |
loading | boolean | — | Індикатор на ГОЛОВНІЙ кнопці. Каретка лишається доступною. |
menuDisabled | boolean | — | Блокує лише каретку: головна дія працює, альтернатив зараз немає. |
disabled | boolean | — | — |
Події
| Назва | Payload | Опис |
|---|---|---|
click | [event: MouseEvent] | Натиснуто головну кнопку. |
select | [item: SplitButtonItem] | Обрано пункт із меню альтернатив. Приходить сам пункт, а не лише його id. |
Слоти
| Назва | Опис |
|---|---|
default | Текст головної дії. Перекриває `label`. |
leading | Іконка перед текстом головної дії. |
menu | Власний вміст меню замість `items`. `toggle` закриває панель. |
Доступно через ref
| Назва | Тип | Опис |
|---|---|---|
focus | () => void | Ставить фокус на головну кнопку. |
Коли використовувати
- Одна дія явно переважає, але поруч є 2–5 споріднених варіантів.
- Панель запису: «Зберегти» з варіантами збереження.
- Експорт із вибором формату, де один формат — типовий.
Коли НЕ використовувати
- Коли рівноцінних варіантів більше п'яти або вони не споріднені: це вже
UiMenuз нейтральним тригером. - Коли головної дії немає — усі варіанти рівні. Тоді кнопка з кареткою бреше про пріоритет.
- Для перемикання вигляду —
UiToggleGroup.
Доступність
Група має role="group" з aria-label: без нього скрінрідер читає дві
сусідні кнопки як незв'язані, і призначення каретки лишається невідомим.
Каретка не має власного тексту, тож її ім'я приходить із menuLabel, а
символ ▼ прихований через aria-hidden.
ArrowDown на головній кнопці відкриває меню. Далі працює клавіатура
UiMenu: стрілки по пунктах, Escape закриває й повертає фокус на тригер.