Skip to content

feat(components): forms.textarea no-op primitive + migrate 10 plain textareas#3562

Merged
marcelfolaron merged 2 commits into
masterfrom
feature/textarea-component
Jun 21, 2026
Merged

feat(components): forms.textarea no-op primitive + migrate 10 plain textareas#3562
marcelfolaron merged 2 commits into
masterfrom
feature/textarea-component

Conversation

@marcelfolaron

Copy link
Copy Markdown
Collaborator

What

Third componentization primitive after forms.button (#3531) and forms.text-input (#3558):
a no-op forms.textarea component plus migration of the 10 plain <textarea> tags to it.

No-op = zero visual/behaviour change. The component is:

<textarea {{ $attributes }}>{{ $slot }}</textarea>

Attributes pass through; the field's value is the slot (inner content), preserved exactly
textareas are whitespace-sensitive, so every migration keeps the slot tight.

Deferred (left RAW) — the Tiptap editors ⚠️

Per the do-not-touch rule (same as datepickers for text-input), the 19 rich-text editor textareas
are NOT migrated
. JS upgrades exactly textarea.tiptapSimple / textarea.tiptapComplex
(public/assets/js/app/core/tiptap/index.js) plus the Wiki .wiki-editor-textarea — routing those
through a component would break the editors. The component's docblock documents this.

Migrated (10 plain textareas / 6 files)

  • Help/projectDefinitionStep ×3 (onboarding prompts)
  • Ideas/ideaDialog + Wiki/articleDialognewMilestone
  • Timesheets/addTime + Timesheets/editTime + Tickets/.../timesheet — description
  • Widgets/.../myToDos ×2 — description-input (no JS coupling — verified)

No variant arm: plain textareas carry no distinct style class (the only textarea classes are
editor-coupled and deferred).

Verification

  • Full diff is pure <textarea><x-global::forms.textarea> tag swaps — every changed line
    only renames the element; all attributes + inner content preserved verbatim (14 ins / 14 del, symmetric).
  • view:cache (compile gate) + Pint clean.
  • Static audit: 0 plain textareas missed, 19 editors correctly deferred, 10 migrated.
  • Editor coupling traced in JS to confirm exactly which selectors TipTap consumes.

Next

forms.select (native), then the forms.field-row wrapper.

🤖 Generated with Claude Code

Third primitive after button (#3531) and text-input (#3558). A no-op textarea
component plus migration of the 10 plain <textarea> tags to it.

Component body is <textarea {{ $attributes }}>{{ $slot }}</textarea> — attributes
pass through and the field value is the slot (inner content), preserved exactly
(textareas are whitespace-sensitive). No variant arm: plain textareas carry no
distinct style class.

DEFERRED (left RAW) — the 19 Tiptap rich-text editor textareas. JS upgrades exactly
textarea.tiptapSimple / textarea.tiptapComplex (app/.../core/tiptap/index.js) plus the
Wiki .wiki-editor-textarea; routing those through the component would break the editors.

Migrated 10 plain textareas across 6 files (Help projectDefinitionStep x3, Ideas/Wiki
newMilestone, Timesheets add/edit + Tickets timesheet description, Widgets myToDos x2).

Verified: full diff is pure <textarea> <-> <x-global::forms.textarea> tag swaps
(14 ins / 14 del symmetric), view:cache + Pint clean, static audit = 0 plain missed,
19 editors deferred.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Introduces a new no-op Blade component primitive, forms.textarea, and migrates a small set of existing plain <textarea> usages to the component while explicitly deferring JS-coupled rich-text editor textareas.

Changes:

  • Added app/Views/Templates/components/forms/textarea.blade.php as a passthrough textarea component (<textarea {{ $attributes }}>{{ $slot }}</textarea>).
  • Migrated 10 plain <textarea> tags across several templates to <x-global::forms.textarea>.
  • Updated COMPONENTS.md tracker/status and documented the textarea migration + deferral rules.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
app/Views/Templates/components/forms/textarea.blade.php Adds new no-op textarea component and documentation.
app/Views/Templates/components/COMPONENTS.md Updates component tracker status/notes for text-input and textarea.
app/Domain/Wiki/Templates/articleDialog.blade.php Migrates newMilestone textarea to component.
app/Domain/Ideas/Templates/ideaDialog.blade.php Migrates newMilestone textarea to component.
app/Domain/Widgets/Templates/partials/myToDos.blade.php Migrates hidden description textareas to component.
app/Domain/Timesheets/Templates/addTime.blade.php Migrates description textarea to component.
app/Domain/Timesheets/Templates/editTime.blade.php Migrates description textarea to component.
app/Domain/Tickets/Templates/submodules/timesheet.blade.php Migrates description textarea to component.
app/Domain/Help/Templates/projectDefinitionStep.blade.php Migrates onboarding prompt textareas to component.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +24 to +26
Renders a plain <textarea> with the SAME attributes the app uses today; every attribute
(name, id, rows, cols, placeholder, style, class, data-*, hx-*, required, …) passes through
via $attributes, and the field's value is the slot (inner content), preserved EXACTLY.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — clarified the docblock: declared @props (state/contentRole/scale/labelText/…) are extracted by Blade and not emitted; only non-prop attributes pass through $attributes. Fixed in a4abf86.

@marcelfolaron marcelfolaron marked this pull request as ready for review June 21, 2026 03:03
@marcelfolaron marcelfolaron requested a review from a team as a code owner June 21, 2026 03:03
@marcelfolaron marcelfolaron requested review from broskees and removed request for a team June 21, 2026 03:03
…ot review)

Declared @props (state/contentRole/scale/labelText/…) are extracted by Blade and not
emitted as HTML; only non-prop attributes pass through $attributes. Docblock-only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@marcelfolaron marcelfolaron merged commit c61e4e7 into master Jun 21, 2026
12 checks passed
@marcelfolaron marcelfolaron deleted the feature/textarea-component branch June 21, 2026 13:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants