Skip to content

Commit de403bc

Browse files
author
DavidQ
committed
Extend Palette Manager tile area to full height and align sort radio controls with swatch size selector - PR_26124_034-palette-layout-height-and-radio-controls
1 parent d670f16 commit de403bc

8 files changed

Lines changed: 338 additions & 383 deletions

File tree

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# PR_26124_034 Palette Layout Height And Radio Controls Report
2+
3+
## Scope
4+
- Updated Palette Manager V2 center palette layout and palette controls only.
5+
- Kept controls class-based and did not touch tools/shared, schemas, sample JSON, games, workspace, toolState, or session logic.
6+
7+
## Changes
8+
- Center Palette Manager layout now uses a fixed available-height shell with internal palette grid scrolling.
9+
- Center accordions stretch within the available tool area, and tile grids flex to fill their accordion content.
10+
- User Palette sort now uses the same radio-style button controls as Source Palette.
11+
- Source Palette sort remains radio-style buttons with Hue, Saturation, Brightness, and Name.
12+
- Swatch size controls now use compact Sm, Me, and Lg labels; Lg maps to the existing large tile size.
13+
- User and source size dropdowns are synced through in-memory UI state and do not mutate palette JSON.
14+
15+
## Validation
16+
- `node --check tools/palette-manager-v2/controls/UserPaletteControl.js`
17+
- `node --check tools/palette-manager-v2/controls/SourcePaletteBrowserControl.js`
18+
- `node --check tools/palette-manager-v2/modules/PaletteManagerApp.js`
19+
- `git diff --check`
20+
21+
## Packaging
22+
- Delta ZIP: `tmp/PR_26124_034-palette-layout-height-and-radio-controls_delta.zip`
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
docs/dev/reports/PR_26124_033_report.md
1+
docs/dev/reports/PR_26124_034_report.md
22
tools/palette-manager-v2/controls/SourcePaletteBrowserControl.js
33
tools/palette-manager-v2/controls/UserPaletteControl.js
44
tools/palette-manager-v2/index.html
55
tools/palette-manager-v2/modules/PaletteManagerApp.js
6-
tools/palette-manager-v2/modules/SwatchRow.js
76
tools/palette-manager-v2/paletteManagerV2.css

docs/dev/reports/codex_review.diff

Lines changed: 227 additions & 348 deletions
Large diffs are not rendered by default.

tools/palette-manager-v2/controls/SourcePaletteBrowserControl.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ export class SourcePaletteBrowserControl {
1717
this.refs.sourceSearchInput.addEventListener("input", () => {
1818
this.app.setSourceSearch(this.refs.sourceSearchInput.value);
1919
});
20-
this.refs.swatchSizeSelect.addEventListener("change", () => {
21-
this.app.setSwatchSize(this.refs.swatchSizeSelect.value);
20+
this.refs.sourceSwatchSizeSelect.addEventListener("change", () => {
21+
this.app.setSwatchSize(this.refs.sourceSwatchSizeSelect.value);
2222
});
2323
}
2424

2525
render() {
2626
this.refs.sourcePaletteSelect.value = this.app.getCurrentSourcePaletteId();
2727
this.refs.sourceSearchInput.value = this.app.getSourceSearch();
28-
this.refs.swatchSizeSelect.value = this.app.getSwatchSize();
28+
this.refs.sourceSwatchSizeSelect.value = this.app.getSwatchSize();
2929
this.refs.sourceSwatchList.dataset.swatchSize = this.app.getSwatchSize();
3030
this.renderActiveSortButton();
3131
this.refs.sourceSwatchList.replaceChildren();
@@ -72,6 +72,7 @@ export class SourcePaletteBrowserControl {
7272
button.type = "button";
7373
button.className = "palette-manager-v2__sort-button";
7474
button.dataset.sortMode = mode.value;
75+
button.setAttribute("role", "radio");
7576
button.textContent = mode.label;
7677
button.addEventListener("click", () => {
7778
this.app.setSourceSortMode(mode.value);
@@ -82,12 +83,12 @@ export class SourcePaletteBrowserControl {
8283
}
8384

8485
renderSizeOptions() {
85-
this.refs.swatchSizeSelect.replaceChildren();
86+
this.refs.sourceSwatchSizeSelect.replaceChildren();
8687
this.app.getSwatchSizeOptions().forEach((size) => {
8788
const option = this.document.createElement("option");
8889
option.value = size.value;
8990
option.textContent = size.label;
90-
this.refs.swatchSizeSelect.appendChild(option);
91+
this.refs.sourceSwatchSizeSelect.appendChild(option);
9192
});
9293
}
9394

@@ -96,7 +97,7 @@ export class SourcePaletteBrowserControl {
9697
this.refs.sourcePaletteSortControls.querySelectorAll("[data-sort-mode]").forEach((button) => {
9798
const isActive = button.dataset.sortMode === activeMode;
9899
button.classList.toggle("is-active", isActive);
99-
button.setAttribute("aria-pressed", String(isActive));
100+
button.setAttribute("aria-checked", String(isActive));
100101
});
101102
}
102103
}

tools/palette-manager-v2/controls/UserPaletteControl.js

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,18 @@ export class UserPaletteControl {
99

1010
bind() {
1111
this.renderSortOptions();
12-
this.refs.userPaletteSortSelect.addEventListener("change", () => {
13-
this.app.setUserSortMode(this.refs.userPaletteSortSelect.value);
12+
this.renderSizeOptions();
13+
this.refs.userSwatchSizeSelect.addEventListener("change", () => {
14+
this.app.setSwatchSize(this.refs.userSwatchSizeSelect.value);
1415
});
1516
}
1617

1718
render() {
1819
const swatches = this.app.getUserSwatches();
1920
this.refs.userPaletteCount.textContent = `${swatches.length} user swatches`;
20-
this.refs.userPaletteSortSelect.value = this.app.getUserSortMode();
21+
this.refs.userSwatchSizeSelect.value = this.app.getSwatchSize();
2122
this.refs.userSwatchList.dataset.swatchSize = this.app.getSwatchSize();
23+
this.renderActiveSortButton();
2224
this.refs.userSwatchList.replaceChildren();
2325

2426
if (swatches.length === 0) {
@@ -40,12 +42,38 @@ export class UserPaletteControl {
4042
}
4143

4244
renderSortOptions() {
43-
this.refs.userPaletteSortSelect.replaceChildren();
45+
this.refs.userPaletteSortControls.replaceChildren();
4446
this.app.getSortModes().forEach((mode) => {
47+
const button = this.document.createElement("button");
48+
button.type = "button";
49+
button.className = "palette-manager-v2__sort-button";
50+
button.dataset.sortMode = mode.value;
51+
button.setAttribute("role", "radio");
52+
button.textContent = mode.label;
53+
button.addEventListener("click", () => {
54+
this.app.setUserSortMode(mode.value);
55+
});
56+
this.refs.userPaletteSortControls.appendChild(button);
57+
});
58+
this.renderActiveSortButton();
59+
}
60+
61+
renderSizeOptions() {
62+
this.refs.userSwatchSizeSelect.replaceChildren();
63+
this.app.getSwatchSizeOptions().forEach((size) => {
4564
const option = this.document.createElement("option");
46-
option.value = mode.value;
47-
option.textContent = mode.label;
48-
this.refs.userPaletteSortSelect.appendChild(option);
65+
option.value = size.value;
66+
option.textContent = size.label;
67+
this.refs.userSwatchSizeSelect.appendChild(option);
68+
});
69+
}
70+
71+
renderActiveSortButton() {
72+
const activeMode = this.app.getUserSortMode();
73+
this.refs.userPaletteSortControls.querySelectorAll("[data-sort-mode]").forEach((button) => {
74+
const isActive = button.dataset.sortMode === activeMode;
75+
button.classList.toggle("is-active", isActive);
76+
button.setAttribute("aria-checked", String(isActive));
4977
});
5078
}
5179
}

tools/palette-manager-v2/index.html

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,16 @@ <h2 id="editorTitle">Selected Swatch</h2>
6464
<span class="palette-manager-v2__accordion-icon" aria-hidden="true">+</span>
6565
</summary>
6666
<div class="palette-manager-v2__accordion-content">
67-
<label class="palette-manager-v2__field">
68-
Sort user palette
69-
<select id="userPaletteSortSelect"></select>
70-
</label>
67+
<div class="palette-manager-v2__sort-row">
68+
<div class="palette-manager-v2__field">
69+
<span>Sort user palette</span>
70+
<div id="userPaletteSortControls" class="palette-manager-v2__sort-buttons" role="radiogroup" aria-label="Sort user palette"></div>
71+
</div>
72+
<label class="palette-manager-v2__field palette-manager-v2__size-field">
73+
Size
74+
<select id="userSwatchSizeSelect"></select>
75+
</label>
76+
</div>
7177
<div id="userPaletteCount" class="palette-manager-v2__meta">0 user swatches</div>
7278
<div id="userSwatchList" class="palette-manager-v2__tile-grid palette-manager-v2__tile-grid--user" aria-label="User palette swatches"></div>
7379
</div>
@@ -90,11 +96,11 @@ <h2 id="editorTitle">Selected Swatch</h2>
9096
<div class="palette-manager-v2__sort-row">
9197
<div class="palette-manager-v2__field">
9298
<span>Sort source palette</span>
93-
<div id="sourcePaletteSortControls" class="palette-manager-v2__sort-buttons" role="group" aria-label="Sort source palette"></div>
99+
<div id="sourcePaletteSortControls" class="palette-manager-v2__sort-buttons" role="radiogroup" aria-label="Sort source palette"></div>
94100
</div>
95101
<label class="palette-manager-v2__field palette-manager-v2__size-field">
96-
Swatch size
97-
<select id="swatchSizeSelect"></select>
102+
Size
103+
<select id="sourceSwatchSizeSelect"></select>
98104
</label>
99105
</div>
100106
<div id="sourceSwatchList" class="palette-manager-v2__tile-grid palette-manager-v2__tile-grid--source" aria-label="Browse palette swatches"></div>

tools/palette-manager-v2/modules/PaletteManagerApp.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ import { cloneSwatch, normalizeHex, sanitizeText, swatchKey } from "./paletteUti
88

99
const REQUIRED_REF_IDS = Object.freeze([
1010
"userPaletteCount",
11-
"userPaletteSortSelect",
11+
"userPaletteSortControls",
12+
"userSwatchSizeSelect",
1213
"userSwatchList",
1314
"sourcePaletteSelect",
1415
"sourceSearchInput",
1516
"sourcePaletteSortControls",
16-
"swatchSizeSelect",
17+
"sourceSwatchSizeSelect",
1718
"sourceSwatchList",
1819
"editorTitle",
1920
"selectedSwatchPreview",
@@ -35,9 +36,9 @@ const REQUIRED_REF_IDS = Object.freeze([
3536
]);
3637

3738
const SWATCH_SIZE_OPTIONS = Object.freeze([
38-
Object.freeze({ value: "small", label: "Small" }),
39-
Object.freeze({ value: "medium", label: "Medium" }),
40-
Object.freeze({ value: "large", label: "Large" })
39+
Object.freeze({ value: "small", label: "Sm" }),
40+
Object.freeze({ value: "medium", label: "Me" }),
41+
Object.freeze({ value: "large", label: "Lg" })
4142
]);
4243

4344
function collectRefs(documentRef) {

tools/palette-manager-v2/paletteManagerV2.css

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
.palette-manager-v2 {
2+
box-sizing: border-box;
3+
height: calc(100vh - 180px);
24
min-height: 0;
35
padding: 16px;
4-
overflow-x: hidden;
6+
overflow: hidden;
57
}
68

79
.palette-manager-v2__layout {
810
display: grid;
911
grid-template-columns: 340px minmax(0, 1fr) 360px;
1012
gap: 16px;
11-
min-height: calc(100vh - 180px);
13+
height: 100%;
14+
min-height: 0;
1215
}
1316

1417
.palette-manager-v2__panel {
18+
box-sizing: border-box;
1519
min-width: 0;
1620
min-height: 0;
21+
height: 100%;
1722
border: 1px solid var(--line, rgba(221, 214, 254, 0.26));
1823
border-radius: 8px;
1924
background: var(--panel, rgba(39, 18, 82, 0.86));
@@ -30,12 +35,25 @@
3035
display: flex;
3136
flex-direction: column;
3237
gap: 14px;
33-
overflow: visible;
38+
overflow: hidden;
39+
}
40+
41+
.palette-manager-v2__panel--center .palette-manager-v2__accordion {
42+
display: flex;
43+
flex-direction: column;
44+
min-height: 0;
45+
}
46+
47+
.palette-manager-v2__panel--center .palette-manager-v2__accordion[open] {
48+
flex: 1 1 0;
3449
}
3550

36-
.palette-manager-v2__panel--center .palette-manager-v2__accordion,
3751
.palette-manager-v2__panel--center .palette-manager-v2__accordion-content {
38-
overflow: visible;
52+
display: flex;
53+
flex: 1 1 auto;
54+
flex-direction: column;
55+
min-height: 0;
56+
overflow: hidden;
3957
}
4058

4159
.palette-manager-v2__accordion {
@@ -130,7 +148,7 @@
130148
}
131149

132150
.palette-manager-v2__size-field {
133-
flex: 0 0 150px;
151+
flex: 0 0 84px;
134152
margin-left: auto;
135153
}
136154

@@ -172,6 +190,7 @@
172190
display: grid;
173191
grid-template-columns: repeat(auto-fill, minmax(var(--swatch-tile-width), 1fr));
174192
gap: 10px;
193+
flex: 1 1 auto;
175194
min-height: 0;
176195
overflow-y: auto;
177196
overflow-x: visible;
@@ -202,11 +221,11 @@
202221
}
203222

204223
.palette-manager-v2__tile-grid--user {
205-
max-height: 520px;
224+
max-height: none;
206225
}
207226

208227
.palette-manager-v2__tile-grid--source {
209-
max-height: 620px;
228+
max-height: none;
210229
}
211230

212231
.palette-manager-v2__swatch-row {

0 commit comments

Comments
 (0)