Skip to content

Adopt Platform.Bible (platform-bible-react) components in place of raw HTML #165

Description

@alex-rawlings-yyc

Summary

The WebView UI hand-rolls a number of interactive/form elements as raw HTML
(<button>, <input>, <textarea>, <label>, custom dropdowns) even though
platform-bible-react ships equivalents. Several of these raw elements are paired
with bespoke tw: CSS utilities (pill-btn-*, modal-form-input, modal-form-label,
icon-button) that duplicate styling the platform component already provides.

Migrating to the platform components improves visual/behavioral consistency with
the host app, lets us delete duplicated CSS, and gets us themeing/a11y for free.

The extension is already partly on-platform: Button (most modals), Tooltip
family, Label/Switch, Popover, and TabToolbar. There are no raw
<select>/<option> elements and no native title= tooltips — those are
already clean. This issue covers the remaining tail.

Scope

Tier 1 — direct swaps (start here; highest value, lowest risk)

<button>Button (map existing tw:pill-btn-* / tw:icon-button classes to variant/size):

  • src/components/controls/EditPhraseControls.tsx:37,46 — Done / Cancel
  • src/components/modals/UnlinkPhraseConfirm.tsx:45,53 — Unlink / Cancel (sibling modals already use Button)
  • src/components/modals/MorphemeEditor.tsx:198,209,216 — Delete / Cancel / Done
  • src/components/ContinuousView.tsx:969,1053, src/components/SegmentListView.tsx:376 — icon nav buttons
  • Icon buttons in PhraseBox.tsx:352,362, TokenChip.tsx:357,405,491,
    TokenLinkIcon.tsx:251,320, ArcOverlay.tsx:324, SegmentListView.tsx:67,
    PhraseStripParts.tsx:50 (BoundaryButton) → Button variant="ghost" + icon

<input>/<textarea>/<label>Input/Textarea/Label (all use tw:modal-form-input / tw:modal-form-label):

  • src/components/modals/CreateProjectModal.tsx
  • src/components/modals/ProjectMetadataModal.tsx
  • src/components/modals/SaveAsProjectModal.tsx

Once these land, remove the now-unused pill-btn-* / modal-form-* utilities from src/tailwind.css.

Tier 2 — needs care

  • src/components/modals/WipeModal.tsx:64–83 — raw two-radio group → RadioGroup/RadioGroupItem.
  • Content-sized gloss inputs in PhraseBox.tsx:51, MorphemeBox.tsx:189,
    TokenChip.tsx:442, SegmentFreeTranslationInput.tsx:51Input, only if
    platform Input forwards className/style so field-sizing: content (and,
    for TokenChip, the ARIA combobox wiring) survives. Verify before swapping.

Tier 3 — reimplemented platform patterns (design review, not mechanical)

  • src/components/controls/ViewOptionsDropdown.tsx:197–210 — raw backdrop <div>
    • portaled role="dialog" panel positioned via getBoundingClientRect
      platform Popover (already a proven dependency here). Good standalone cleanup.
  • src/components/SuggestionDropdown.tsx + the TokenChip.tsx combobox — portaled
    role="listbox"/role="option" popup with manual positioning, active-descendant
    highlighting, and keyboard nav. Platform ships ComboBox/Command/Select, but
    this is a real refactor with bespoke focus/keyboard UX — evaluate fit before
    committing
    , may warrant its own issue.

Suggested sequencing

  1. Tier 1: three project modals + confirm-bar buttons (EditPhraseControls,
    UnlinkPhraseConfirm), then delete the duplicated CSS utilities.
  2. Tier 3: ViewOptionsDropdownPopover.
  3. Tier 2 gloss inputs / WipeModal radios, gated on a props check of platform
    Input/RadioGroup.
  4. Split the combobox migration out if it proves nontrivial.

Out of scope / non-goals

  • Test doubles under src/__tests__/** and __mocks__/**.
  • Any element whose custom behavior can't be preserved on the platform component —
    keep raw and note why rather than regress UX.

Acceptance

  • Raw elements in Tier 1 replaced with platform components; duplicated tw:
    utilities removed; existing tests pass (mock __mocks__/platform-bible-react.tsx
    extended for any newly-used components).
  • Tier 2/3 either done or explicitly deferred with rationale.

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions