feat(remix): add textarea component - #107
Merged
Merged
Conversation
# Conflicts: # packages/remix/test/public_api_compatibility_test.dart # packages/remix/test/public_api_test.dart
leoafarias
marked this pull request as ready for review
August 5, 2026 19:09
Move `_buildResolved` from `RemixTextField` onto `_RemixTextFieldBodyState`. Its only caller was that state, and every argument it took — the style controller, the effective focus node, and two press callbacks — was already state-owned. The callbacks existed solely to bridge back to `_updatePressSource`. No behavior change. Record the two non-obvious invariants in the same file so a later simplification pass does not undo them: - The obsolete internal focus node must be disposed in a post-frame callback. This state's `didUpdateWidget` runs before `NakedTextField`'s, and Naked reads the outgoing node's `hasFocus` to decide whether to move focus onto the incoming one. A synchronous dispose detaches and unfocuses first, so focus would be dropped across a null -> external swap. - The `joinedSemanticHint == effectiveSemanticErrorText` check is not dead code. `NakedTextField` concatenates `semanticHint` and `semanticErrorText` unconditionally without deduplicating, so an identical hint and error would be announced twice. Document that `fortalTextFieldStyle()` must not be applied to `RemixTextArea`: it pins the input container to a single-line height, so taller content scrolls inside a one-line box with no layout error to signal it. There is no Fortal TextArea preset because Radix Themes' TextArea is not in this package's mapped parity surface, so its metrics have no reference data to derive from.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds
RemixTextAreaas a constructor-only multiline facade overRemixTextField. It shares the sameTextFieldSpec,TextFieldStyler,NakedTextField, controller, focus, editing, selection, and semantics implementation—there is no second editable pipeline or TextArea-specific generated style machinery.Component API
RemixTextAreasupplies safe multiline defaults:minLines: 2maxLines: nullkeyboardType: TextInputType.multilinetextInputAction: TextInputAction.newlineexpands: falseobscureText: falseIt forwards the supported TextField controller, focus, editing, selection, scrolling, restoration, IME, accessory, semantics, style, and raw style-spec surface.
Shared TextField corrections
NakedTextField.CrossAxisAlignment.baselineuses Flutter's alphabetic baseline and renders real text/accessories without the priorRowassertion.Mix/code-generation surface
containeris nowStyleSpec<BoxSpec>and acceptsBoxStyler, matching the actual outer renderer.spacingandcrossAxisAlignmentare generated top-level fields.layoutremainsStyleSpec<FlexBoxSpec>.Migration example:
Visual Evidence
Captured and visually verified locally; the PNGs are ignored and are not part of the package diff:
.context/screenshots/textarea-light.png— 368×796, SHA-256fed0cd66eb4e9d01fe79dcf829c5997a26ed467055d3502b49ff222e94c97eec.context/screenshots/textarea-dark.png— 368×796, SHA-256e2edf10274afa5b07bb220de9d83bd15e4a2b34ca5c3f3d2d41b6078f65ddee0The captures include focused empty, filled multiline, error, disabled, read-only, and custom-styled states. Hosted GitHub attachment upload remains pending because the connector and CLI do not expose the issue-attachment endpoint.
Validation
fvm flutter test packages/remix/test/components/textfield packages/remix/test/public_api_test.dart packages/remix/test/public_api_compatibility_test.dart— 170/170 passed on hostednaked_ui 1.0.0-beta.9, including multiline scrolling, selection-drag, and rapid double-tap pressed-state regressions.fvm dart run melos run generate:check— 25 generated artifacts reproduced byte-for-byte.fvm flutter analyze --fatal-infos— clean.naked_ui 1.0.0-beta.9resolution while retaining the compatible^1.0.0-beta.8package constraint.test / Run tests for all packageson final headd1a06e269— passed.git diff --check— clean.naked_ui 1.0.0-beta.9contains the pressed-state lifecycle fix from conceptadev/naked_ui#84, and this branch's lockfile now resolves that hosted release.Related Issues
naked_ui 1.0.0-beta.9.Draft gates
Breaking Change
Does this PR require users of the package to manually update their code?
Consumers styling TextField input-row layout through
container(FlexBoxStyler(...))must migrate container visuals toBoxStylerand use the generated top-levelspacingandcrossAxisAlignmentmethods.