Files
pastilhas be29ae7aa7 delete two unreferenced components from another codebase
MarkdownEditor and ui/start-confetti-button had no importers anywhere in the repo
and both carried a different product's content: MarkdownEditor hardcoded
https://app.pertento.ai/logo.png with alt="Pertento", and start-confetti-button
spoke about 'the experiment' and 'Draft/Created' statuses.

Translating either would have put feature words into ui.*, which D6 forbids —
a shared namespace may not name a feature.

todo/inputs-outside-forms named MarkdownEditor as deliberately-unwrapped, so that
entry is updated rather than left pointing at a deleted file.
2026-08-23 04:18:08 +00:00

75 lines
5.4 KiB
Markdown

---
theme: inputs-outside-forms
heading: "Inputs outside forms (2026-08-19) — swept, fixed, closed"
kind: theme
---
The "19 files" count in the previous version of this entry came from one grep
(`components/ui/input`) and was a starting point, not the answer. A wider sweep — bare `<input>` and
`<textarea>` too, across the platform and every installed plugin — found **87 files with a matching
element and no enclosing `<form>`**. Three were false positives (the `Input`/`Textarea` primitives
themselves, and a `DataTable` test file). Of the remaining 84, **41 were fixed** (real forms, single
fields with an obvious action, or multi-field editors) and **43 were left alone**, almost all because
they're a search/filter box with nothing to submit.
**Fixed — platform (24 files, one commit):** `CapabilityPage`, `ApifyConfig`, `ApiKeys`,
`DavAppPasswords`, `GoogleOAuthConfig`, `AIHarnessesSection` (local-provider connect, its auth step,
and both API-key edit rows), `OCRSection`, `SMTPSection` (split into two independent forms — save vs.
send-test-email, since one form would have made Enter in the test-email field trigger Save),
`STTSection`, `TTSSection`, `AppStoreDetail`, `ChatHeader`, `BackgroundJobDialog`, `QuestionActivity`,
`WebpageDialog`, `DirPickerModal`, `SessionRow`, `CommandHqCategories`, `FileItem`, `NewEntryDialog`,
`TaskRunnerModal` (the Agentic and Pipeline ready phases), `PreviewHeader`, `widgets/DailyGoals`,
`widgets/Pomodoro`.
**Fixed — plugins (17 files, one commit per plugin, each pushed to its own remote):**
`bitcoin-wallet` (`ChainSourceCard`, `RescanCard`, `WalletSettingsView`), `email` (`Compose`,
`EmailAccounts`), `invoices` (`DocumentEditor`, `RecordEditors`, `SendDocumentDialog`), `offscale`
(`NodesView` — rename and tags fields), `soulseek` (`SoulseekConnection`), `transmission`
(`ConnectionView`, `SettingsView`, `AddTorrentDialog`, `MoveTorrentDialog`, `RenameDialog`,
`TorrentOptionsDialog`), `vault` (`VaultPanel`). `jellyfin` and `music` needed no changes.
**Left alone — search/filter boxes with no submit action** (the large majority of the 43): `JobsPage`,
`SettingsPanel`, `SearchInput`, `sounds/Catalog`, `widgets/QuickNotes`, `Dashboards/DashboardListApp`,
`SystemMonitor/DockerView`, `FileBrowser*` toolbar/header/view-container files, `ChatHistory` list
filters, `invoices`' six list views (`CustomersListView`, `EstimatesListView`, `ExpensesListView`,
`InvoicesListView`, `ItemsListView`, `ReportsView`, `components.tsx`), `jellyfin` (`PlayerControls` —
range sliders, not text fields — and `SearchSection`), `music` (`MusicBrowser`, `MusicPlayerHost`),
`offscale` (`Cards`, `PolicyAssistant` — already handles Enter/Shift+Enter correctly, `PolicyView` — a
textarea, never auto-submits), `soulseek` (`SearchResults`, `SharesBrowser`), `transmission`
(`TorrentToolbar`), `FileViewer` renderers (`AudioRenderer`/`VideoRenderer` — volume/seek sliders), and
the main chat composers (`InputArea`, `ChatLauncher`, `SoulseekChat`) — all textareas with their own
Enter-sends/Shift+Enter-newlines handling, where a `<form>` would add nothing and risks regressing that
handling.
**Left alone — genuinely ambiguous, flagged rather than guessed:**
- `TaskRunnerModal`'s `ScriptRunner` ready phase offers three simultaneously-visible, non-equivalent
primary actions ("Run here" / "Queue" / "Run as job"); there's no single canonical action for Enter to
trigger.
- `Dashboards/DashboardPreview`'s `NamePanel` (name + description) has its submit button in a
_different_, independently-mounted panel (`CreatePanel`) elsewhere in the workspace layout tree — a
`<form>` can't span two panels without restructuring the wizard.
- `ColorPicker` has zero call sites anywhere in the repo right now; it is shaped to be embedded in a
future caller's own form (uncontrolled inputs with `name` attributes), so there's nothing to wrap yet.
`MarkdownEditor` was named here too and was deleted on 2026-08-23 during the localization pass — it
had no call sites and hardcoded another product's logo URL.
- `widgets/Weather`'s `LocationSetup` is a live autocomplete with several result rows and no single
obvious Enter target (which of N matches?).
**Noticed, out of scope, not fixed:**
- `ModelSelector`'s provider-picker button has no `type` attribute — harmless today only because it
currently sits outside every `<form>`; a landmine if that layout changes.
- `MusicBrowser`'s filter input uses `(e) =>` instead of the house `ev` convention — pre-existing, not
touched since the file needed no fix.
- `EmailList.tsx`, and a few plugin files touched by this sweep (`VaultPanel`, `ConnectionView`,
`SoulseekConnection`, `ChainSourceCard`), have pre-existing `prettier --check` drift outside the lines
this pass touched — left as found, not reformatted, per "don't reformat what you're not fixing."
Relatedly: **`prettier --write` on a `plugins/<name>/…` path silently no-ops when run from the
platform root**, because Prettier v3 respects the root `.gitignore` and `/plugins/*/` is in it — it
exits 0 with no diff and no error. Formatting a plugin file requires running prettier from inside
that plugin's own directory (still resolves the platform's `.prettierrc` by walking up).
- A few "Save"/"I've saved it"-style buttons (`ApiKeys`, `DavAppPasswords`, `DirPickerModal`) have no
`type` attribute but currently sit outside any `<form>`, so it's harmless today — worth remembering if
a future edit wraps that region.