Lynx/Modules/Zero/Field
@sigx/lynx-zero · Beta · Component library

Field#

The wiring hub for a labelled form control, on zero's field anatomy and zero's own FieldContext. A control inside a Field adopts its disabled, invalid, required and readonly flags and, when it sets no size of its own, its size. A tap on Field.Label focuses the control.

The parts are the same as the web component's. See Field in @sigx/zero for the shared contract. This page covers what is different on Lynx.

Import#

TSX
import { Field } from '@sigx/lynx-zero';

Field is a compound with Root, Label, Description and Error. <Field> is the same component as <Field.Root>.

Usage#

TSX
import { component, signal } from '@sigx/lynx';
import { Field, Input } from '@sigx/lynx-zero';

export const EmailField = component(() => {
    const form = signal({ email: '', error: '' });
    return () => (
        <Field.Root invalid={!!form.error} required size="sm">
            <Field.Label>Email</Field.Label>
            <Input.Root model={() => form.email} type="email">
                <Input.Control>
                    <Input.Input placeholder="you@example.com" />
                </Input.Control>
            </Input.Root>
            {form.error
                ? <Field.Error>{form.error}</Field.Error>
                : <Field.Description>We never share it.</Field.Description>}
        </Field.Root>
    );
});

Field.Label, Field.Description and Field.Error render as <text>, so pass them strings.

What adopts the Field#

These @sigx/lynx-zero controls read the Field's flags, each ORed with the control's own prop:

A Field also takes the flags of an enclosing Fieldset: a Field inside a disabled fieldset is disabled, and so is its control.

Label taps#

Lynx has no <label for>. A text field registers itself with the Field when it mounts, and a tap on Field.Label focuses the first control that registered, through the native field's focus UI method. A disabled Field ignores the tap. This works for Input, Textarea and NumberInput.

visuallyHidden keeps the label for a screen reader but takes it off screen. On Lynx that is a 1px transparent absolute box that takes no taps.

Errors#

Lynx has no constraint validation: no forms and no ValidityState. invalid is yours to set, and a Field.Error renders whenever it is mounted. Mount one while there is an error to say, as in the example above. Field.Error carries the Field's invalid flag.

Props#

Field.Root#

PropTypeDefaultDescription
disabledbooleanfalseAdopted by every control inside. ORed with an enclosing Fieldset's.
invalidbooleanfalseAdopted by every control inside. ORed with an enclosing Fieldset's.
requiredbooleanfalseAdopted by the controls that take it.
readonlybooleanfalseAnnounced, never edited. ORed with an enclosing Fieldset's.
colorstringskin defaultAccents the label.
sizestringskin defaultThe whole field's size. A control without its own renders this one.
classstring—Extra classes, appended after the computed ones.

Field.Label#

PropTypeDefaultDescription
visuallyHiddenbooleanfalseKeep it for the reader, off screen. Stamps data-visually-hidden.
classstring—Extra classes.

Field.Description and Field.Error take class and a default slot.

Anatomy on Lynx#

PartElementFlagsNotes
rootviewdisabled, invalid, required, readonlyCarries the axes.
labeltextdisabled, invalid, requiredA tap focuses the first registered control.
descriptiontext—
errortextinvalidRendered whenever it is mounted.

Not taken on Lynx:

  • validate and validateOn, and Field.Error's match. There is no constraint validation to drive them.
  • aria-describedby. The ids are still minted on the context, but nothing on Lynx resolves an id reference.
  • The required-label asterisk. The web skin draws it with an ::after pseudo-element, which Lynx does not have, so required reaches the label only as its flag class.

See also#