Skip to content

Commit 159dbbd

Browse files
committed
Correct Palette Swatch Editor disabled state and User Defined field behavior - PR_26156_177-palette-swatch-editor-disable-correction
1 parent e87abb9 commit 159dbbd

8 files changed

Lines changed: 194 additions & 38 deletions

File tree

assets/theme-v2/css/buttons.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@
5050
align-items: center
5151
}
5252

53+
.action-group--tight {
54+
gap: calc(var(--space-10) / 2)
55+
}
56+
5357
.action-group--end {
5458
justify-content: flex-end
5559
}

assets/theme-v2/css/forms.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@ select {
6868
padding: var(--space-12)
6969
}
7070

71+
.field-value--readable-disabled:disabled {
72+
color: var(--text);
73+
-webkit-text-fill-color: var(--text);
74+
background: var(--panel);
75+
border-color: var(--line);
76+
opacity: 1
77+
}
78+
7179
input[type="checkbox"],
7280
input[type="radio"] {
7381
width: var(--icon-size-sm);
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# PR_26156_177 Palette Swatch Editor Disable Correction Report
2+
3+
## Result
4+
PASS
5+
6+
## Summary
7+
- Corrected Swatch Editor disabled/read-only selected value fields so selected Symbol, Hex, and Name remain visible without gray/color wash styling.
8+
- Kept Swatch Editor Symbol, Hex, and Name disabled/read-only.
9+
- Kept Tags editable only when a project palette color is selected.
10+
- Split the Swatch Editor tag input and rendered tag action area into two table rows.
11+
- Reduced the tag action-group spacing by 50% with a reusable tight action-group utility.
12+
- Updated User Defined Swatch so it only populates for selected user-defined palette colors.
13+
- Source-backed and harmony-backed Palette Colors now leave User Defined Swatch blank while still allowing new user-defined swatch creation.
14+
15+
## Theme V2 Gap
16+
Existing Theme V2 classes had no reusable way to show a disabled form value while preserving readable selected text, and no reusable half-gap action-group variant.
17+
18+
Reusable Theme V2 utilities were added:
19+
- `forms.css`: `.field-value--readable-disabled` keeps disabled input values readable with normal text color and opacity.
20+
- `buttons.css`: `.action-group--tight` reduces action-group gap to half of the standard action-group gap.
21+
22+
## Swatch Editor
23+
- Selected Palette Colors swatch text appears in Swatch Editor.
24+
- Symbol, Hex, and Name remain disabled and read-only.
25+
- Disabled selected-value fields use normal text color, normal text fill, and full opacity.
26+
- Tags are disabled with no selected project palette color and enabled for selected project palette colors.
27+
- Tags input and tag action display occupy separate rows under the same Tags label.
28+
29+
## User Defined Swatch
30+
- No selected swatch: blank fields remain enabled for creating a new user-defined swatch.
31+
- Selected user-defined swatch: Symbol, Hex, and Name populate and remain editable.
32+
- Selected non-user swatch: Symbol, Hex, and Name are blank and enabled for new user-defined swatch entry.
33+
- Non-user selected colors cannot be updated through User Defined Swatch base-value controls.
34+
35+
## Validation
36+
- `node --check toolbox/colors/colors.js`
37+
- PASS
38+
- `node --check toolbox/colors/palette-workspace-repository.js`
39+
- PASS
40+
- `node --check tests/playwright/tools/PaletteToolMockRepository.spec.mjs`
41+
- PASS
42+
- `rg "style=|<style|onclick|onchange|oninput|onsubmit" toolbox/colors/index.html toolbox/colors/colors.js toolbox/colors/palette-workspace-repository.js assets/theme-v2/css/forms.css assets/theme-v2/css/buttons.css tests/playwright/tools/PaletteToolMockRepository.spec.mjs`
43+
- PASS, no matches
44+
- `rg "readEditorForm|fillEditorForm|clearEditorForm|validateEditor|tagsFromText|elements\\.remove|data-palette-remove" toolbox/colors tests/playwright/tools/PaletteToolMockRepository.spec.mjs`
45+
- PASS, no matches
46+
- `rg "DEFAULT_SOURCE_PALETTES" toolbox/colors tests/playwright/tools/PaletteToolMockRepository.spec.mjs`
47+
- PASS, no matches
48+
- `npx playwright test tests/playwright/tools/PaletteToolMockRepository.spec.mjs --project=playwright --workers=1 --reporter=list`
49+
- PASS, 3 tests
50+
- `npm run test:playwright:static`
51+
- PASS
52+
53+
## Verification Coverage
54+
- Disabled Swatch Editor values remain readable and not color-washed.
55+
- Selected Palette Colors swatch text appears in Swatch Editor.
56+
- Symbol, Hex, and Name cannot be edited in Swatch Editor.
57+
- Tags are editable only for selected project palette colors.
58+
- Tag layout uses two rows and the tight action-group spacing.
59+
- User Defined Swatch fields populate for user-defined swatches.
60+
- Non-user selections leave User Defined Swatch blank, keep Add/Clear enabled, and keep Update Selected disabled.
61+
62+
## Skipped
63+
- Full samples smoke was not run, per BUILD instruction.

docs_build/dev/reports/playwright_v8_coverage_report.txt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,27 @@ Note: entry percentages use function coverage when available, otherwise line cov
1212
Note: coverage entries are aggregated across every page/tool where coverageReporter.start(page) and coverageReporter.stop(page) ran.
1313

1414
Exercised tool entry points detected:
15-
(85%) Toolbox Index - exercised 5 runtime JS files
15+
(86%) Toolbox Index - exercised 5 runtime JS files
1616
(0%) Tool Template V2 - not exercised by this Playwright run
1717
(83%) Theme V2 Shared JS - exercised 2 runtime JS files
1818

1919
Changed runtime JS files covered:
2020
(87%) toolbox/colors/palette-workspace-repository.js - executed lines 1190/1190; executed functions 113/130
21-
(95%) toolbox/colors/colors.js - executed lines 776/776; executed functions 75/79
21+
(95%) toolbox/colors/colors.js - executed lines 793/793; executed functions 77/81
2222

2323
Files with executed line/function counts where available:
2424
(65%) toolbox/project-workspace/project-workspace-mock-repository.js - executed lines 402/402; executed functions 20/31
2525
(75%) toolbox/toolRegistry.js - executed lines 1754/1754; executed functions 27/36
2626
(80%) assets/theme-v2/js/gamefoundry-partials.js - executed lines 205/205; executed functions 16/20
2727
(87%) assets/theme-v2/js/tool-display-mode.js - executed lines 201/201; executed functions 13/15
2828
(87%) toolbox/colors/palette-workspace-repository.js - executed lines 1190/1190; executed functions 113/130
29-
(95%) toolbox/colors/colors.js - executed lines 776/776; executed functions 75/79
29+
(95%) toolbox/colors/colors.js - executed lines 793/793; executed functions 77/81
3030
(100%) toolbox/colors/palette-source-mock-db.js - executed lines 927/927; executed functions 6/6
3131

3232
Uncovered or low-coverage changed JS files:
3333
(100%) none - no low-coverage changed runtime JS files
3434

3535
Changed JS files considered:
3636
(0%) tests/playwright/tools/PaletteToolMockRepository.spec.mjs - changed JS file not collected as browser runtime coverage
37-
(0%) tests/playwright/tools/ToolCenterFullscreenAccordion.spec.mjs - changed JS file not collected as browser runtime coverage
3837
(87%) toolbox/colors/palette-workspace-repository.js - changed JS file with browser V8 coverage
3938
(95%) toolbox/colors/colors.js - changed JS file with browser V8 coverage

docs_build/dev/reports/testing_lane_execution_report.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# PR_26156_176 Testing Lane Execution Report
1+
# PR_26156_177 Testing Lane Execution Report
22

33
## Result
44
PASS
@@ -10,7 +10,7 @@ PASS
1010
- PASS
1111
- `node --check tests/playwright/tools/PaletteToolMockRepository.spec.mjs`
1212
- PASS
13-
- `rg "style=|<style|onclick|onchange|oninput|onsubmit" toolbox/colors/index.html toolbox/colors/colors.js toolbox/colors/palette-workspace-repository.js tests/playwright/tools/PaletteToolMockRepository.spec.mjs`
13+
- `rg "style=|<style|onclick|onchange|oninput|onsubmit" toolbox/colors/index.html toolbox/colors/colors.js toolbox/colors/palette-workspace-repository.js assets/theme-v2/css/forms.css assets/theme-v2/css/buttons.css tests/playwright/tools/PaletteToolMockRepository.spec.mjs`
1414
- PASS, no matches
1515
- `rg "readEditorForm|fillEditorForm|clearEditorForm|validateEditor|tagsFromText|elements\\.remove|data-palette-remove" toolbox/colors tests/playwright/tools/PaletteToolMockRepository.spec.mjs`
1616
- PASS, no matches
@@ -28,26 +28,26 @@ PASS
2828
- Changed-file/static validation: PASS.
2929

3030
## Playwright Coverage
31-
- Source-pinned user Palette Colors start with empty tags: PASS.
32-
- Harmony-pinned user Palette Colors start with empty tags: PASS.
33-
- Manual Add Swatch starts user tags empty: PASS.
34-
- Rendered user tags appear side by side: PASS.
35-
- Clicking a rendered tag deletes it from the selected project palette color: PASS.
36-
- Pressing Enter adds only the user-entered tag: PASS.
37-
- Swatch Editor has disabled Symbol, Hex, and Name mirror fields: PASS.
38-
- Swatch Editor enables Tags only when a Palette Colors swatch is selected: PASS.
39-
- Swatch Editor has no Add, Update, Remove, or Clear actions: PASS.
40-
- User Defined Swatch has Symbol, Hex, and Name and no Tags: PASS.
41-
- Selected swatch removal clears selected editor fields and disables Tags: PASS.
31+
- Disabled Swatch Editor selected-value fields preserve normal text color, text fill, and opacity: PASS.
32+
- Selected source-backed Palette Colors swatch values appear in Swatch Editor: PASS.
33+
- Selected user-defined Palette Colors swatch values appear in Swatch Editor: PASS.
34+
- Swatch Editor Symbol, Hex, and Name remain disabled: PASS.
35+
- Tags are disabled with no selected project palette color and enabled with selected project palette colors: PASS.
36+
- Tag input and rendered tag action area are split across two rows: PASS.
37+
- Tag action-group uses the tight 50% gap utility: PASS.
38+
- User Defined Swatch remains enabled and blank for new user-defined swatch creation with no selected color: PASS.
39+
- User Defined Swatch is blank with Add/Clear enabled for selected non-user colors: PASS.
40+
- User Defined Swatch populates and enables for selected user-defined colors: PASS.
4241

4342
## Impacted Lane
4443
- Palette Tool runtime/UI lane.
44+
- Theme V2 static validation for reusable form/action-group utility classes used by Palette.
4545
- Changed-file/static validation lane.
4646

4747
## Skipped Lanes
4848
- Full samples smoke was skipped by BUILD instruction.
49-
- Shared Tool Center fullscreen UI lane was skipped because PR176 did not modify shared Tool Center or Theme V2 layout behavior.
50-
- Broader tool lanes were skipped because changes are confined to Palette Tool tag/editor behavior and the targeted Palette spec covers the changed runtime/UI paths.
49+
- Shared Tool Center fullscreen UI lane was skipped because PR177 did not modify shared Tool Center layout behavior.
50+
- Broader tool lanes were skipped because the new Theme V2 utilities are only used by Palette in this delta, and the targeted Palette spec verifies their rendered behavior.
5151

5252
## Not Run
5353
- Full samples smoke was not run, per BUILD instruction.

tests/playwright/tools/PaletteToolMockRepository.spec.mjs

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,24 @@ async function expectControlGroupsShareLine(page, sortSelector, sizeSelector) {
150150
expect(Math.abs(sortCenter - sizeCenter)).toBeLessThan(4);
151151
}
152152

153+
async function expectReadableDisabledField(page, selector, value) {
154+
const field = page.locator(selector);
155+
await expect(field).toBeDisabled();
156+
await expect(field).toHaveValue(value);
157+
const style = await field.evaluate((node) => {
158+
const computed = getComputedStyle(node);
159+
return {
160+
bodyColor: getComputedStyle(document.body).color,
161+
color: computed.color,
162+
opacity: computed.opacity,
163+
textFillColor: computed.webkitTextFillColor
164+
};
165+
});
166+
expect(style.opacity).toBe("1");
167+
expect(style.color).toBe(style.bodyColor);
168+
expect(style.textFillColor).toBe(style.bodyColor);
169+
}
170+
153171
async function expectSwatchRegionScrollsOnly(page, scrollSelector, controlsSelector, summarySelector) {
154172
const scrollRegion = page.locator(scrollSelector);
155173
const controls = page.locator(controlsSelector);
@@ -365,6 +383,19 @@ test("Palette Tool adds, updates, pins, validates, and shows project-owned detai
365383
await expect(page.locator("[data-palette-selected-name]")).toHaveValue("");
366384
await expect(page.locator("[data-palette-tags]")).toBeDisabled();
367385
await expect(page.locator("[data-palette-tags]")).toHaveValue("");
386+
await expect(page.locator("[data-palette-editor-tags-input-row] th")).toHaveAttribute("rowspan", "2");
387+
const tagInputRowBox = await page.locator("[data-palette-editor-tags-input-row]").boundingBox();
388+
const tagListRowBox = await page.locator("[data-palette-editor-tags-list-row]").boundingBox();
389+
expect(tagListRowBox?.y || 0).toBeGreaterThan((tagInputRowBox?.y || 0) + (tagInputRowBox?.height || 0) - 2);
390+
const tagActionLayout = await page.locator("[data-palette-editor-tags-list]").evaluate((node) => {
391+
const style = getComputedStyle(node);
392+
return {
393+
columnGap: style.columnGap,
394+
hasTightClass: node.classList.contains("action-group--tight")
395+
};
396+
});
397+
expect(tagActionLayout.hasTightClass).toBe(true);
398+
expect(tagActionLayout.columnGap).toBe("5px");
368399
await expect(page.locator("[data-palette-table-counts]")).toContainText("palette_colors");
369400
await expect(page.locator("[data-palette-project-accordion]")).toBeVisible();
370401
await expect(page.locator("[data-palette-source-accordion]")).toBeVisible();
@@ -411,6 +442,22 @@ test("Palette Tool adds, updates, pins, validates, and shows project-owned detai
411442
await expect(page.locator("[data-palette-user-list] [data-palette-swatch-name='Black']")).toHaveCount(1);
412443
await expect(page.locator("[data-palette-user-list] [data-palette-swatch-name='Black']")).toHaveAttribute("data-palette-selected", "true");
413444
await expect(page.locator("[data-palette-selected-summary]")).toHaveText("Black");
445+
const blackTile = page.locator("[data-palette-user-list] [data-palette-swatch-name='Black']");
446+
const blackSymbol = await blackTile.getAttribute("data-palette-swatch-row");
447+
const blackHex = await blackTile.getAttribute("data-palette-swatch-hex");
448+
await expectReadableDisabledField(page, "[data-palette-selected-symbol]", blackSymbol || "");
449+
await expectReadableDisabledField(page, "[data-palette-selected-hex]", blackHex || "");
450+
await expectReadableDisabledField(page, "[data-palette-selected-name]", "Black");
451+
await expect(page.locator("[data-palette-tags]")).toBeEnabled();
452+
await expect(page.locator("[data-palette-user-swatch-form] [data-palette-symbol]")).toBeEnabled();
453+
await expect(page.locator("[data-palette-user-swatch-form] [data-palette-hex]")).toBeEnabled();
454+
await expect(page.locator("[data-palette-user-swatch-form] [data-palette-name]")).toBeEnabled();
455+
await expect(page.locator("[data-palette-user-swatch-form] [data-palette-symbol]")).toHaveValue("");
456+
await expect(page.locator("[data-palette-user-swatch-form] [data-palette-hex]")).toHaveValue("");
457+
await expect(page.locator("[data-palette-user-swatch-form] [data-palette-name]")).toHaveValue("");
458+
await expect(page.locator("[data-palette-user-swatch-form]").getByRole("button", { name: "Add Swatch" })).toBeEnabled();
459+
await expect(page.locator("[data-palette-user-swatch-form]").getByRole("button", { name: "Update Selected" })).toBeDisabled();
460+
await expect(page.locator("[data-palette-user-swatch-form]").getByRole("button", { name: "Clear Form" })).toBeEnabled();
414461
await expect(page.locator("[data-palette-user-list] [data-palette-swatch-name='Black']")).toHaveAttribute("data-palette-swatch-tags", "");
415462
await expect(page.locator("[data-palette-user-list] [data-palette-swatch-name='Black']")).toHaveAttribute("title", /^Symbol: .+\nHex: #[0-9A-F]{6}\nName: Black\nTags: None$/);
416463
await expect(page.locator("[data-palette-source-index]").first()).toHaveAttribute("data-palette-pinned", "true");
@@ -430,6 +477,12 @@ test("Palette Tool adds, updates, pins, validates, and shows project-owned detai
430477
await expect(page.locator("[data-palette-selected-hex]")).toHaveValue("");
431478
await expect(page.locator("[data-palette-selected-name]")).toHaveValue("");
432479
await expect(page.locator("[data-palette-tags]")).toBeDisabled();
480+
await expect(page.locator("[data-palette-user-swatch-form] [data-palette-symbol]")).toBeEnabled();
481+
await expect(page.locator("[data-palette-user-swatch-form] [data-palette-hex]")).toBeEnabled();
482+
await expect(page.locator("[data-palette-user-swatch-form] [data-palette-name]")).toBeEnabled();
483+
await expect(page.locator("[data-palette-user-swatch-form]").getByRole("button", { name: "Add Swatch" })).toBeEnabled();
484+
await expect(page.locator("[data-palette-user-swatch-form]").getByRole("button", { name: "Update Selected" })).toBeDisabled();
485+
await expect(page.locator("[data-palette-user-swatch-form]").getByRole("button", { name: "Clear Form" })).toBeEnabled();
433486
await page.locator("[data-palette-source-search]").fill("");
434487
await expect(page.locator("[data-palette-source-index]")).toHaveCount(8);
435488
await expect(page.locator("[data-palette-harmony-choice]")).toHaveCount(0);
@@ -474,13 +527,16 @@ test("Palette Tool adds, updates, pins, validates, and shows project-owned detai
474527
await expect(page.locator("[data-palette-swatch-row='H']")).toHaveAttribute("title", "Symbol: H\nHex: #123456AA\nName: Hero Blue\nTags: None");
475528
await expect(page.locator("[data-palette-swatch-row='H']")).toHaveAttribute("data-palette-selected", "true");
476529
await expect(page.locator("[data-palette-swatch-row='H']")).toHaveAttribute("data-palette-swatch-tags", "");
477-
await expect(page.locator("[data-palette-selected-symbol]")).toHaveValue("H");
478-
await expect(page.locator("[data-palette-selected-hex]")).toHaveValue("#123456AA");
479-
await expect(page.locator("[data-palette-selected-name]")).toHaveValue("Hero Blue");
480-
await expect(page.locator("[data-palette-selected-symbol]")).toBeDisabled();
481-
await expect(page.locator("[data-palette-selected-hex]")).toBeDisabled();
482-
await expect(page.locator("[data-palette-selected-name]")).toBeDisabled();
530+
await expectReadableDisabledField(page, "[data-palette-selected-symbol]", "H");
531+
await expectReadableDisabledField(page, "[data-palette-selected-hex]", "#123456AA");
532+
await expectReadableDisabledField(page, "[data-palette-selected-name]", "Hero Blue");
483533
await expect(page.locator("[data-palette-tags]")).toBeEnabled();
534+
await expect(page.locator("[data-palette-user-swatch-form] [data-palette-symbol]")).toBeEnabled();
535+
await expect(page.locator("[data-palette-user-swatch-form] [data-palette-hex]")).toBeEnabled();
536+
await expect(page.locator("[data-palette-user-swatch-form] [data-palette-name]")).toBeEnabled();
537+
await expect(page.locator("[data-palette-user-swatch-form] [data-palette-symbol]")).toHaveValue("H");
538+
await expect(page.locator("[data-palette-user-swatch-form] [data-palette-hex]")).toHaveValue("#123456AA");
539+
await expect(page.locator("[data-palette-user-swatch-form] [data-palette-name]")).toHaveValue("Hero Blue");
484540
await expect(page.locator("[data-palette-editor-tags-list]")).toContainText("No tags added.");
485541
await expect(page.locator("[data-palette-user-swatch-form]").getByRole("button", { name: "Update Selected" })).toBeEnabled();
486542
await expect(page.locator("[data-palette-swatch-row='H']")).toHaveAttribute("aria-current", "true");
@@ -546,6 +602,9 @@ test("Palette Tool adds, updates, pins, validates, and shows project-owned detai
546602
await expect(page.locator("[data-palette-swatch-row='J']")).toHaveAttribute("data-palette-swatch-tags", "ui, feature");
547603
await expect(page.locator("[data-palette-swatch-row='J']")).toHaveAttribute("title", "Symbol: J\nHex: #ABCDEF\nName: Hero Updated\nTags: ui, feature");
548604
await expect(page.locator("[data-palette-selected-summary]")).toHaveText("Hero Updated");
605+
await expect(page.locator("[data-palette-user-swatch-form] [data-palette-symbol]")).toHaveValue("J");
606+
await expect(page.locator("[data-palette-user-swatch-form] [data-palette-hex]")).toHaveValue("#ABCDEF");
607+
await expect(page.locator("[data-palette-user-swatch-form] [data-palette-name]")).toHaveValue("Hero Updated");
549608
await expect(page.locator("[data-palette-user-list]")).not.toContainText(/Hero Updated|ui, feature|Symbol|Name|Hex|Source|Tags/);
550609

551610
await page.getByRole("button", { name: "Undo" }).click();

0 commit comments

Comments
 (0)