Примитивы
08

Field

Текстовое поле с подписью. Если id не передан, подпись связывается с полем через сгенерированный id.

чистая разметка — библиотеки на странице нет
отрендерил aura-react
отрендерил aura-vue
отрендерил aura-svelte
собрано из классов самого aura-angular
Lowercase letters and dashes.
We never share this. That is not an email address.
Type to see the controlled value.
Lowercase letters and dashes.
We never share this.That is not an email address.
Type to see the controlled value.
Lowercase letters and dashes.
We never share this. That is not an email address.
Type to see the controlled value.
Lowercase letters and dashes.
We never share this.That is not an email address.
Type to see the controlled value.
Lowercase letters and dashes.
We never share this.That is not an email address.
Type to see the controlled value.

Код

index.html
<div class="aura-stack" style="--aura-dir:column;--aura-gap:var(--space-3);min-width:260px;">
  <div class="aura-field-group">
    <label class="aura-label" for="aura-field-1">Workspace name</label>
    <input id="aura-field-1" class="aura-field" value placeholder="Acme" aria-describedby="aura-field-1-hint">
    <span class="aura-field-hint" id="aura-field-1-hint">Lowercase letters and dashes.</span>
  </div>
  <div class="aura-field-group">
    <label class="aura-label" for="owner">Owner email</label>
    <input id="owner" class="aura-field" value="ann@" aria-invalid="true" aria-describedby="owner-hint owner-error">
    <span class="aura-field-hint" id="owner-hint">We never share this.</span>
    <span class="aura-field-error" id="owner-error">That is not an email address.</span>
  </div>
  <span class="aura-text aura-text--caption aura-text--muted" style="">Type to see the controlled value.</span>
</div>
Demo.tsx
import { useState } from 'react';
import { Field, Stack, Typography } from '@ilomee/aura-react';

export default function Demo() {
  const [name, setName] = useState('');

  return (
    <Stack gap={3} style={{ minWidth: 260 }}>
      <Field
        label="Workspace name"
        value={name}
        onValueChange={setName}
        placeholder="Acme"
        hint="Lowercase letters and dashes."
      />
      {/* Both messages, to show they coexist: a hint is a standing instruction and an error is
          what is wrong now, so hiding the first when the second appears removes the sentence
          that was helping. `id` is pinned only because the stacks are diffed against each
          other — left out, each framework generates its own. */}
      <Field label="Owner email" id="owner" defaultValue="ann@" hint="We never share this." error="That is not an email address." />
      <Typography variant="caption" tone="muted">
        {name ? `Hello, ${name}` : 'Type to see the controlled value.'}
      </Typography>
    </Stack>
  );
}

Сгенерированный id берётся из useId(), поэтому он совпадает при SSR и гидратации.

Demo.vue
<script setup lang="ts">
import { ref } from 'vue';
import { Field } from '@ilomee/aura-vue';

const name = ref('');
</script>

<template>
  <Field label="Name" v-model="name" />
</template>

Сгенерированный id берётся у самого фреймворка, поэтому он совпадает при SSR и гидратации.

Demo.svelte
<script lang="ts">
  import { Field } from '@ilomee/aura-svelte';

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

<Field label="Name" bind:value={name} />

Сгенерированный id берётся у самого фреймворка, поэтому он совпадает при SSR и гидратации.

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

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

@Component({
  standalone: true,
  imports: [AuraField],
  template: `<aura-field label="Name" [(value)]="name"></aura-field>`,
})
export class DemoComponent {
  name = '';
}

Сгенерированный id берётся из счётчика в корневом сервисе. Angular создаёт новый корневой инжектор на каждый запрос, поэтому счётчик стартует заново при каждом SSR-рендере и сходится с клиентом.

Пропсы

У чистой разметки нет пропсов — классы ниже и есть весь API. Четыре пакета не делают ничего сверх того, что проставляют вам те же самые классы.
ИмяТипПо умолчаниюПримечания
labelstring
hintstringПостоянная подсказка под контролом, показывается всегда.
errorstringЧто не так прямо сейчас. Ставит контролу aria-invalid и добавляет сообщение в его aria-describedby — после подсказки. Без живого региона: role="alert" объявляет себя при монтировании, поэтому форма с тремя ошибками, отрисованная на сервере, перебила бы читателя трижды ещё до первого поля.
valuestringУправляемое значение.
defaultValuestringНачальное значение для неуправляемого режима.
onValueChange(value: string) => void
inputClassNamestringКласс для самого input (className попадает на обёртку).
…InputHTMLAttributesатрибутыInputHTMLAttributes<HTMLInputElement>Пробрасываются на input.
ИмяТипПо умолчаниюПримечания
labelstring
hintstringПостоянная подсказка под контролом, показывается всегда.
errorstringЧто не так прямо сейчас. Ставит контролу aria-invalid и добавляет сообщение в его aria-describedby — после подсказки. Без живого региона: role="alert" объявляет себя при монтировании, поэтому форма с тремя ошибками, отрисованная на сервере, перебила бы читателя трижды ещё до первого поля.
modelValueдвустороннийstringРаботает через v-model.
defaultValuestringНачальное значение для неуправляемого режима.
idstring
update:modelValueсобытие(value: string) => void
…attrsатрибутыInputHTMLAttributesПробрасываются на input.
ИмяТипПо умолчаниюПримечания
labelstring
hintstringПостоянная подсказка под контролом, показывается всегда.
errorstringЧто не так прямо сейчас. Ставит контролу aria-invalid и добавляет сообщение в его aria-describedby — после подсказки. Без живого региона: role="alert" объявляет себя при монтировании, поэтому форма с тремя ошибками, отрисованная на сервере, перебила бы читателя трижды ещё до первого поля.
valueдвустороннийstring''$bindable — используйте bind:value.
idstring
…restатрибутыHTMLInputAttributesПробрасываются на input.
ИмяТипПо умолчаниюПримечания
labelstring
hintstringПостоянная подсказка под контролом, показывается всегда.
errorstringЧто не так прямо сейчас. Ставит контролу aria-invalid и добавляет сообщение в его aria-describedby — после подсказки. Без живого региона: role="alert" объявляет себя при монтировании, поэтому форма с тремя ошибками, отрисованная на сервере, перебила бы читателя трижды ещё до первого поля.
valueдвустороннийstring''Двусторонняя привязка через [(value)].
idstring
valueChangeсобытиеEventEmitter<string>
…attributesатрибутыHTMLInputElementАтрибуты, поставленные на <aura-field>, переносятся на внутренний <input>.

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

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

КлассРольПримечания
.aura-labelбазаОбязательный. Без него модификатор не работает.
.aura-fieldбазаОбязательный. Без него модификатор не работает.
.aura-field-hintбазаОбязательный. Без него модификатор не работает.
.aura-field-errorбазаОбязательный. Без него модификатор не работает.

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

components.css
высота
var(--control-h)
паддинг
0 var(--control-px)
рамка
var(--field-border)
радиус
var(--field-radius)
фон
var(--surface)
фокус
var(--accent) + var(--focus-ring)
невалидное
var(--danger-border-hover) + var(--danger) ring
подсказка / ошибка
500 13px · var(--text-muted) / var(--danger-text)
плейсхолдер
var(--text-faint)
отступ лейбла
var(--label-gap)