CLAUDE.md@bulma-ui/src/form · git:20261008.d152cd4 · 2026-10-08 · sha256 6051aa1e3f24eeba
CLAUDE.md@bulma-ui/src/form git:20261008.d152cd4A
Immutable. This exact content never changes and is served at /api/v1/blob/6051aa1e3f24eeba.
# form/ — form controls Bulma's Field/Control composition model: `Field` wraps label + control + help text; `Control` wraps a single input and handles icons/loading. Inputs compose inside them — there is **no form library** and none should be added; validation is userland (`skills/bestax-form` teaches the pattern). **Belongs here?** Anything a user types into or selects with. Display widgets go in `../components/`. Conventions: - `FormContext.tsx` is presence detection, not state: `useInsideField`/`useInsideControl` let an input skip rendering its own Field/Control wrapper when already inside one, and it backs group components (Radios). Preserve that skip-if-wrapped behavior in new inputs. Decide the Field with `rendersOwnField` rather than `!insideField` alone: `Control` provides no field context, so that test puts a `.field` inside a bare `.control` (#905). Pass it every prop that changes the Field's own markup, and add a new one to its list, or a bare `Control` silently drops it; a new wrapper also joins the table in `__tests__/bare-control.test.tsx`. `Autocomplete` and `Numberinput` still decide with `!insideField`, because the helper cannot fix them: Autocomplete's own markup carries a `.control`, and Numberinput's root is itself a `.field`, so either one still nests inside a bare `Control` with no Field of its own. Bringing them in means changing that markup first. Decide the Control with `rendersOwnControl` the same way: pass it every prop you hand your own `Control`, as the caller gave it rather than after a default, so that inside a caller's `Control`, where those props do nothing, it can warn about the ones set (#921). A picker passes its `inline` too, since inline it renders no Control in either place. A new Control-level prop joins `ControlLevelProps`, and `bare-control.test.tsx` fails until it does. - `*Base.tsx` files (`InputBase`, `SelectBase`, `DateInputBase`, `TimeInputBase`, …) are the raw controls without the Field/Control wrapping — deliberately exported from `src/index.ts` as escape hatches, so they are public API too. - Basic inputs (Input, Select, TextArea, …) ship no CSS, but more of this folder has SCSS than you'd guess: even Checkbox and Radio have themed partials, File has one for its keyboard focus ring and a boxed CTA's corners, and every extended input (Autocomplete, DateInput, Numberinput, Rate, Slider, Switch, Taginput, …) does too. Check `../scss/form/_index.scss` for the authoritative list before changing visuals. Follow the anatomy rule in `bulma-ui/CLAUDE.md` (test + story + docs page + export + catalog).