|
| 1 | +# palette-manager-v2 Reengineering Design |
| 2 | + |
| 3 | +Task: PR_26124_026 |
| 4 | + |
| 5 | +Source folder: `tools/palette-manager-v2` |
| 6 | +Runtime tool id: `palette-manager-v2` |
| 7 | +Global data key: `tools.palette-browser` |
| 8 | +Publish target: `tools.palette-browser` |
| 9 | + |
| 10 | +## Tool Purpose |
| 11 | +Palette Manager V2 owns global palette editing for `tools.palette-browser.swatches`. It has user-owned swatches plus browse-only source palettes (`crayola`, `w3c`, `javascript`) that can be pinned into the user palette. |
| 12 | + |
| 13 | +## Folder/Files Inspected |
| 14 | +- `tools/palette-manager-v2/index.html` |
| 15 | +- `tools/palette-manager-v2/main.js` |
| 16 | +- `tools/palette-manager-v2/paletteManagerV2.css` |
| 17 | +- `tools/palette-manager-v2/README.md` |
| 18 | +- `tools/palette-manager-v2/how_to_use.html` |
| 19 | + |
| 20 | +## Current Controls |
| 21 | +| Control | Action | JSON effect | |
| 22 | +|---|---|---| |
| 23 | +| `select#sourcePaletteSelect` | Chooses `crayola`, `w3c`, or `javascript` source list. | No JSON change; only changes browse source. | |
| 24 | +| `input#sourceSearchInput[type=search]` | Filters visible source swatches by symbol, hex, or name. | No JSON change. | |
| 25 | +| `input#swatchSymbolInput[type=text]` | Edits the draft user swatch symbol. | Sets `symbol` for add/update after validation. | |
| 26 | +| `input#swatchHexInput[type=text]` | Edits the draft user swatch hex. | Sets `hex` after `#RRGGBB` validation. | |
| 27 | +| `input#swatchNameInput[type=text]` | Edits the draft user swatch name. | Sets `name` for add/update after validation. | |
| 28 | +| `input#swatchSourceInput[type=text]` | Edits the draft user swatch source. | Sets `source` for add/update after validation. | |
| 29 | +| `button#addSwatchButton` | Adds the form swatch to the user palette. | Appends to `tools.palette-browser.swatches` when valid. | |
| 30 | +| `button#updateSwatchButton` | Updates the selected user swatch from the form. | Replaces the selected swatch when valid. | |
| 31 | +| `button#removeSwatchButton` | Removes the selected user swatch. | Deletes the selected swatch unless `isSwatchUsedByTool(swatch)` returns true. | |
| 32 | +| `button#clearFormButton` | Clears the editor form and selection. | No JSON change. | |
| 33 | +| source row tack button | Pins or unpins a source swatch. | Red tack appends a cloned source swatch; green tack removes the matching user swatch unless blocked by usage. | |
| 34 | +| user row tack button | Removes a user swatch. | Deletes that swatch unless blocked by usage. | |
| 35 | +| `button#importPaletteButton` + `input#importPaletteInput[type=file]` | Imports JSON from disk. | Replaces `tools.palette-browser.swatches` only after JSON and swatches validate. | |
| 36 | +| `button#copyPaletteButton` | Copies the export wrapper. | No state change; copies `{ tools: { "palette-browser": { swatches } } }`. | |
| 37 | +| `button#exportPaletteButton` | Downloads the export wrapper. | No state change; exports `{ tools: { "palette-browser": { swatches } } }`. | |
| 38 | + |
| 39 | +## Component/Class/Function Inventory |
| 40 | +- CSS/layout classes: `.palette-manager-v2`, `.palette-manager-v2__layout`, `.palette-manager-v2__panel`, `.palette-manager-v2__accordion`, `.palette-manager-v2__form-grid`, `.palette-manager-v2__controls`, `.palette-manager-v2__list`, `.palette-manager-v2__swatch-row`, `.palette-manager-v2__pin-button`, `.palette-manager-v2__json-preview`, `.palette-manager-v2__errors`. |
| 41 | +- Shared layout hooks: `#shared-theme-header`, `.tools-platform-layout-grid`, `.tools-platform-resize-panel`, `data-panel-side="left"`, `data-panel-side="right"`. |
| 42 | +- Functions in `main.js`: `sanitizeText`, `normalizeHex`, `swatchKey`, `cloneSwatch`, `isSwatchUsedByTool`, `validateSwatch`, `validateUserSwatches`, `buildGlobalPaletteValue`, `buildExportDocument`, `setErrors`, `setStatus`, `renderErrors`, `renderJsonPreview`, `renderSelectedSwatchPreview`, `setFormFromSwatch`, `clearForm`, `readFormSwatch`, `findUserSwatchIndex`, `getVisibleSourceSwatches`, `createSwatchRow`, `renderUserSwatches`, `renderSourceSwatches`, `renderValidation`, `render`, `addUserSwatch`, `updateSelectedSwatch`, `removeUserSwatch`, `removeSelectedSwatch`, `pinSourceSwatch`, `extractImportedPaletteDocument`, `importPaletteJsonFromFile`, `exportPaletteJson`, `copyPaletteJson`, `bindEvents`, `init`. |
| 43 | +- Global API: `window.paletteManagerV2App = { getPaletteValue, getExportDocument, isSwatchUsedByTool }`. |
| 44 | + |
| 45 | +## JSON Contract |
| 46 | +Owned swatch shape: |
| 47 | + |
| 48 | +```json |
| 49 | +{ |
| 50 | + "symbol": "R", |
| 51 | + "hex": "#ED0A3F", |
| 52 | + "name": "Red", |
| 53 | + "source": "crayola" |
| 54 | +} |
| 55 | +``` |
| 56 | + |
| 57 | +Required fields: `symbol`, `hex`, `name`, `source`. |
| 58 | +`hex` must match `#RRGGBB`. |
| 59 | + |
| 60 | +Published Output: |
| 61 | +```js |
| 62 | +tools.palette-browser = { |
| 63 | + swatches: [ |
| 64 | + { |
| 65 | + symbol: "R", |
| 66 | + hex: "#ED0A3F", |
| 67 | + name: "Red", |
| 68 | + source: "crayola" |
| 69 | + } |
| 70 | + ] |
| 71 | +} |
| 72 | +``` |
| 73 | + |
| 74 | +Export/copy wrapper: |
| 75 | + |
| 76 | +```js |
| 77 | +{ |
| 78 | + tools: { |
| 79 | + "palette-browser": { |
| 80 | + swatches: [] |
| 81 | + } |
| 82 | + } |
| 83 | +} |
| 84 | +``` |
| 85 | + |
| 86 | +## Valid JSON Behavior |
| 87 | +- Import accepts a JSON object with `tools.palette-browser.swatches`. |
| 88 | +- Every imported swatch must include `symbol`, `hex`, `name`, and `source`. |
| 89 | +- Valid import replaces the current user swatches and rerenders the user list, source pin states, preview JSON, and validation viewer. |
| 90 | + |
| 91 | +## Invalid JSON Rejection Behavior |
| 92 | +- Parse failures are rejected before any state change. |
| 93 | +- Missing `tools`, missing `tools.palette-browser`, non-array `swatches`, missing fields, and invalid hex values are rejected before render/update of imported data. |
| 94 | +- Add/update/export/copy are blocked while the affected swatch or swatch list is invalid. |
| 95 | + |
| 96 | +## Tool-Owned JSON Responsibilities |
| 97 | +- import/load: read selected JSON file, parse, require `tools.palette-browser.swatches`, validate every swatch, then replace user swatches. |
| 98 | +- validate: enforce `symbol`, `hex`, `name`, `source`; enforce `#RRGGBB`. |
| 99 | +- edit/process: add, update, remove, filter, and pin/unpin swatches inside the tool. |
| 100 | +- export/save: emit the wrapper with the unchanged global data key. |
| 101 | +- publish: `tools.palette-browser` only. |
| 102 | + |
| 103 | +## Workspace Integration Contract |
| 104 | +Tool receives validated payload and owns behavior. The global data key remains `tools.palette-browser`; the runtime id and launch route are `palette-manager-v2`. |
| 105 | + |
| 106 | +## Published tools.* Output Contract For Games/Samples |
| 107 | +Games and samples consume the global palette at `tools.palette-browser.swatches`. They do not consume a `tools.palette-manager-v2` key. |
| 108 | + |
| 109 | +## Playwright Expectations |
| 110 | +No workspace-v2 Playwright gate remains for this tool. Future Playwright coverage should launch `tools/palette-manager-v2/index.html`, add a user swatch, pin and unpin a source swatch, reject invalid import JSON, and assert copied/exported JSON uses `tools.palette-browser`. |
| 111 | + |
| 112 | +## Manual Test Expectations |
| 113 | +- Open `tools/palette-manager-v2/index.html` without console errors. |
| 114 | +- Add a user swatch with `symbol`, `hex`, `name`, `source`; confirm it appears in preview JSON. |
| 115 | +- Browse `crayola`, `w3c`, and `javascript`; confirm red tack pins and green tack unpins. |
| 116 | +- Confirm unpin calls `isSwatchUsedByTool(swatch)` and blocks if the stub is changed to return true. |
| 117 | +- Import invalid JSON and confirm the current swatches do not change. |
| 118 | +- Export/copy and confirm only `tools.palette-browser.swatches` is emitted. |
| 119 | + |
| 120 | +## Known Gaps |
| 121 | +- `isSwatchUsedByTool(swatch)` is a stub and does not scan repo data. |
| 122 | +- Source palettes are intentionally small browse-only seed lists. |
| 123 | +- Schema alignment for required `source` and `#RRGGBB` remains deferred to a schema-scoped PR. |
| 124 | + |
| 125 | +## Rebuild Order Priority |
| 126 | +Core-01. This is the palette-first rebuild anchor. |
0 commit comments