Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Form: let Form.Item own label, extra and messages for every form control

Abierto
#69 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
5/5
Tiempo estimado
Más de una semana
Aptitud para principiantes
10/100
Tipo de issue
Nueva funcionalidad
Claridad
Bastante claro
Estado de actividad
Activo
Stack tecnológico
react, typescript

Línea de trabajo

Start with how Form.Item clones props onto its child and where FormItemInputContext is published, then check one shadowed control such as TextInput and the exports.exclude.json mapping used for Dialog to Modal. Read Form.acceptance.test.tsx, which currently uses a plain <input>, to see what acceptance coverage must add. Done means a Form.Item with a failing rule shows one label linked by htmlFor, a red border with one message, and disabled state from <Form disabled>, across every shadowed control.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Problem

Every Astryx form control we re-export (TextInput, TextArea, NumberInput, Switch, CheckboxInput, CheckboxList, RadioList, Selector, MultiSelector, Typeahead, Date/Time inputs, Slider, FileInput, Tokenizer, the ComplexSelector fork) requires its own label and renders its own label, description and status message. Form.Item renders the same things. Inside a Form.Item the control and the item compete, so backend.ai-webui wraps each control in an adapter instead of using it directly:

  • react/src/components/astryxFormControls.tsx: 10 adapters, ~320 call sites. A second, drifted copy lives in packages/backend.ai-ui/src/components/astryxFormControls.tsx.
  • BAISelect, BAICheckbox, BAIUncontrolledInput, BAIDynamicUnitInputNumber, InputNumberWithSlider, plus about 10 one-off local adapters in feature files.
  • ~218 call sites pass the same string to Form.Item label and to the control's label with isLabelHidden. Our own stories and README teach the same pattern (<Form.Item label="Name"><TextInput label="Name" isLabelHidden /></Form.Item>).

What the adapters work around, all of which belong in ui-common:

  1. Label. label: string is required and rendered, so callers duplicate it and hide one copy.
  2. Status never reaches the control. Form.Item publishes FormItemInputContext, but no ui-common component reads it. A failed rule shows the message and leaves the border neutral. README:394 and Form.doc.mjs:105 say controls read it, which nothing does. The webui host adapters read the context and pass { type } with no message and statusVariant="detached", so the result is a red border only. The BUI copy, BAISelect and the local adapters don't, so they have no red border.
  3. Injected props are dropped. Form.Item clones id, disabled, aria-describedby, aria-invalid and aria-required onto the child. Astryx 0.7.0:
    • Selector, MultiSelector, Switch, CheckboxInput and RadioList ignore id, so the item's <label htmlFor> points at nothing.
    • Every control reads isDisabled, not disabled, so <Form disabled> does nothing.
    • aria-invalid follows status only.
  4. Value shape. value is required and non-nullable, so every call site writes ?? '', ?? false or ?? []. Value-first onChange already works with defaultGetValueFromEvent.
  5. Own components.
    • StepNumberInput and ColorPicker have no status.
    • StepNumberInput requires label.
    • UncontrolledInput has no value/onChange pair.
    • BulkEditFormItem passes a placeholder label plus isLabelHidden.

Proposal: match antd's contract

In antd, the item owns the label, extra, help and messages, and injects value/onChange/id. The control reads FormItemInputContext and paints only its border. Apply the same contract to every control that can sit in a Form.Item.

  • Shadow the form controls with ui-common wrappers under the same names, through exports.exclude.json like Dialog→Modal.
  • Don't expose field-chrome props: label, isLabelHidden, description, labelTooltip, labelIcon, isRequired/isOptional, statusVariant, and status.message. They go to Form.Item (label, tooltip, labelExtra, extra, help, required). Outside a form, the accessible name comes from aria-label or aria-labelledby.
  • Status:
    • Read FormItemInputContext when the control sits in a Form.Item.
    • Also accept an antd-style status prop: 'error' | 'warning' | ''.
    • Map it to { type } with no message and a stable statusVariant. Making statusVariant conditional remounts the input and loses focus, as webui learned.
    • validating and success map to no border.
  • Honour injected id, disabled and aria-*. Upstream the id fix where Astryx drops it.
  • Make value optional: undefined means empty.
  • Bring own form components in line: StepNumberInput, ColorPicker, PagedSelector, ComplexSelector fork and UncontrolledInput.
  • Fix docs and stories: the README and Form.doc.mjs examples, and every story using isLabelHidden inside Form.Item.

Decisions needed

  • Checkbox and Switch inline text. It is not the field label; antd uses children. Decide whether to keep it as children or as a renamed prop.

  • Out of scope here, but they keep webui adapters alive:

    • antd prop aliases: allowClear, loading, size.
    • NumberInput clamp on blur.
    • IME Enter guard.
    • tokenSeparators.
    • Selector popup placement.

    Decide whether to add them to ui-common or leave them in the app.

  • Breaking change for 0.2 consumers: needs an upgrade codemod. It should move the control's label/description to the enclosing Form.Item and drop isLabelHidden.

Done when

  • <Form.Item label="Name" name="name" rules={[{ required: true }]}><TextInput /></Form.Item> works with no adapter:
    • one label, linked by htmlFor;
    • a red border and a single message on error;
    • disabled by <Form disabled>.
  • The same holds for every shadowed control.
  • Form.acceptance.test.tsx covers these with real Astryx controls; today it deliberately uses a plain <input>.
  • webui can delete astryxFormControls.tsx (both copies) and the status bridging in BAISelect and BAICheckbox.
Lenguaje dominante
TypeScript
Estrellas
2
Forks
0
Merge medio
1 d 14 h
PR fusionados (30 d)
36

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de lablup/ui-common

Todos los issues de lablup/ui-common

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.