diff --git a/docs/superpowers/plans/2026-05-18-tier-a-native-components.md b/docs/superpowers/plans/2026-05-18-tier-a-native-components.md new file mode 100644 index 0000000..b0b2f30 --- /dev/null +++ b/docs/superpowers/plans/2026-05-18-tier-a-native-components.md @@ -0,0 +1,199 @@ +# Tier A Native-Component Migration Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Replace hand-rolled UI primitives in TubeSage's modals and settings tab with native Obsidian components (`setIcon`, `ExtraButtonComponent`, `ButtonComponent`, `TextComponent`, `DropdownComponent`) with no intended change to look and feel. + +**Architecture:** Four independent tasks in `main.ts`: the standalone info icon, the three icon buttons, the six text buttons, and the create-note modal's inputs. Each converts hand-built markup to a native component while preserving every existing behavior (click handlers, tooltips, placeholders, validation) and keeping bespoke CSS classes where they carry look-and-feel. + +**Tech Stack:** TypeScript, Obsidian Plugin API, esbuild. Verification is `npm run build` and `npm run lint`; there is no unit-test framework, so build, lint, and `grep` are the tests. The 1.3.3 release is the visual reference — no visible change is the acceptance bar. + +**Design reference:** `docs/superpowers/specs/2026-05-18-tier-a-native-components-design.md` + +**General rule for every task:** preserve behavior exactly. Do not change click handlers, tooltip text, copy, settings keys, or layout. When a native component replaces a raw element that carried a bespoke CSS class, re-apply that class to the component's element (`.buttonEl` / `.extraSettingsEl` / `.inputEl` / `.selectEl`) so the look is unchanged, unless the task says the class is now dead. + +--- + +### Task 1: Info icon via `setIcon` + +**Files:** +- Modify: `main.ts` — `createInfoIcon` (~lines 4971-5018) + +- [ ] **Step 1: Replace the hand-built info SVG with `setIcon`** + +In `createInfoIcon`, the body builds an info SVG with `createElementNS` (the `infoSvg`, `circle`, `line`, `dot` elements and the `infoSvgNamespace` constant, roughly lines 4979-5008). Replace that whole SVG-construction block with one call: + +```ts + setIcon(infoIcon, 'info'); +``` + +`setIcon` is a global Obsidian function. Add `setIcon` to the `import { ... } from 'obsidian'` line at the top of `main.ts` if it is not already imported (it is used elsewhere in the file, so it likely already is — verify). + +Keep the rest of `createInfoIcon` unchanged: the `infoIcon` span creation with class `tubesage-settings-info-icon` and the `aria-label`, the `setTooltip(infoIcon, tooltipText, ...)` call, and `return infoIcon`. + +- [ ] **Step 2: Build and lint** + +Run: `npm run build` — expect no TypeScript errors. +Run: `npm run lint` — expect 0 errors, 0 warnings. + +- [ ] **Step 3: Commit** + +```bash +git add main.ts +git commit -m "refactor(ui): render settings info icon with native setIcon" +``` + +--- + +### Task 2: Icon buttons via `ExtraButtonComponent` + +**Files:** +- Modify: `main.ts` — license-view button (~3792), README-view button (~3862), copy button (~6352) +- Modify: `styles.css` — `.tubesage-icon-button` / `.tubesage-icon-button-hover` if they become unused + +Three buttons are raw `