Примитивы
18

SegmentedControl

Ряд взаимоисключающих вариантов — то есть radiogroup, и сделан именно как radiogroup. Радиокнопки скрыты только отрисовкой, но не display: none: это выкинуло бы их из таб-ордера и из группы, по которой ходят стрелки. Браузер по-прежнему даёт исключающий выбор и навигацию, а подпись только рисует.

чистая разметка — библиотеки на странице нет
отрендерил aura-react
отрендерил aura-vue
отрендерил aura-svelte
собрано из классов самого aura-angular

Код

index.html
<fieldset role="radiogroup" aria-label="Theme" class="aura-segmented">
  <label class="aura-segmented__option">
    <input type="radio" class="aura-segmented__input" name="theme" value="light" checked />Light
  </label>
  <label class="aura-segmented__option">
    <input type="radio" class="aura-segmented__input" name="theme" value="dark" />Dark
  </label>
  <label class="aura-segmented__option">
    <input type="radio" class="aura-segmented__input" name="theme" value="system" disabled />System
  </label>
</fieldset>
Demo.tsx
import { SegmentedControl } from '@ilomee/aura-react';

const OPTIONS = [
  { value: 'light', label: 'Light' },
  { value: 'dark', label: 'Dark' },
  { value: 'system', label: 'System', disabled: true },
];

export default function Demo() {
  return <SegmentedControl label="Theme" name="theme" options={OPTIONS} defaultValue="light" />;
}
Demo.vue
<script setup lang="ts">
import { ref } from 'vue';
import { SegmentedControl } from '@ilomee/aura-vue';

const theme = ref('light');
</script>

<template>
  <SegmentedControl
    v-model="theme"
    label="Theme"
    :options="[
      { value: 'light', label: 'Light' },
      { value: 'dark', label: 'Dark' },
    ]"
  />
</template>
Demo.svelte
<script lang="ts">
  import { SegmentedControl } from '@ilomee/aura-svelte';

  let theme = $state('light');
</script>

<SegmentedControl
  bind:value={theme}
  label="Theme"
  options={[
    { value: 'light', label: 'Light' },
    { value: 'dark', label: 'Dark' },
  ]}
/>

Используется как aura-segmented-control.

demo.component.ts
import { AuraSegmentedControl } from '@ilomee/aura-angular';

@Component({
  standalone: true,
  imports: [AuraSegmentedControl],
  template: `<aura-segmented-control label="Theme" [options]="options" [(value)]="theme" />`,
})
export class DemoComponent {
  theme = 'light';
  options = [
    { value: 'light', label: 'Light' },
    { value: 'dark', label: 'Dark' },
  ];
}

Пропсы

У чистой разметки нет пропсов — классы ниже и есть весь API. Четыре пакета не делают ничего сверх того, что проставляют вам те же самые классы.
ИмяТипПо умолчаниюПримечания
labelstring
optionsAuraOption[] | null
valuestring
defaultValuestring''
onValueChange(value: string) => void
namestringСгенерированный id берётся у самого фреймворка, поэтому он совпадает при SSR и гидратации.
disabledboolean
ИмяТипПо умолчаниюПримечания
labelstring
optionsAuraOption[] | null
modelValueдвустороннийstring
defaultValuestring''
namestringСгенерированный id берётся у самого фреймворка, поэтому он совпадает при SSR и гидратации.
disabledbooleanfalse
update:modelValueсобытие(value: string) => void
ИмяТипПо умолчаниюПримечания
labelstring
optionsAuraOption[] | null
valueдвустороннийstring''
namestringСгенерированный id берётся у самого фреймворка, поэтому он совпадает при SSR и гидратации.
disabledbooleanfalse
onchange(value: string) => void
ИмяТипПо умолчаниюПримечания
labelstring
optionsAuraOption[] | null[]
valuestring''
namestring
disabledbooleanfalse
valueChangeсобытиеEventEmitter<string>

Какие классы отдаёт

Все фреймворки отдают одни и те же классы — именно поэтому четыре библиотеки выглядят одинаково. Их можно использовать напрямую, вообще без библиотеки компонентов.

КлассРольПримечания
.aura-segmentedбазаОбязательный. Без него модификатор не работает.
.aura-segmented__optionэлемент
.aura-segmented__inputэлемент

Токены и правила

components.css
дорожка
var(--surface-2) · var(--r2)
выбран
var(--surface) + var(--shadow-1), via :has(:checked)
клавиатура
native — arrows move and select