Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions assets/theme-v2/css/buttons.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,36 @@
border-color: var(--orange-border-strong)
}

.btn--with-icon {
gap: var(--space-8)
}

.btn--with-icon .theme-icon {
height: var(--icon-size-sm);
width: var(--icon-size-sm)
}

.btn--icon-only {
border-radius: var(--radius-pill);
height: var(--space-44);
min-width: var(--space-44);
padding: var(--space-0);
width: var(--space-44)
}

.btn--icon-only .theme-icon {
height: var(--icon-size-md);
width: var(--icon-size-md)
}

.btn--icon-danger {
color: var(--red)
}

.btn--icon-success {
color: var(--green)
}

.btn--compact {
margin: var(--space-0);
min-width: calc(var(--space-44) + var(--space-28));
Expand Down
42 changes: 42 additions & 0 deletions assets/theme-v2/css/icons.css
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,22 @@
--theme-v2-icon-url: url("/assets/theme-v2/svg/gfs-close.svg")
}

.theme-icon--delete {
--theme-v2-icon-url: url("/assets/theme-v2/svg/gfs-trash.svg")
}

.theme-icon--edit {
--theme-v2-icon-url: url("/assets/theme-v2/svg/gfs-settings.svg")
}

.theme-icon--error {
--theme-v2-icon-url: url("/assets/theme-v2/svg/gfs-error.svg")
}

.theme-icon--external-link {
--theme-v2-icon-url: url("/assets/theme-v2/svg/gfs-chevron-right.svg")
}

.theme-icon--exit-fullscreen {
--theme-v2-icon-url: url("/assets/theme-v2/svg/gfs-exit-fullscreen.svg")
}
Expand All @@ -63,6 +75,10 @@
--theme-v2-icon-url: url("/assets/theme-v2/svg/gfs-menu.svg")
}

.theme-icon--save {
--theme-v2-icon-url: url("/assets/theme-v2/svg/gfs-success.svg")
}

.theme-icon--search {
--theme-v2-icon-url: url("/assets/theme-v2/svg/gfs-search.svg")
}
Expand All @@ -83,6 +99,32 @@
--theme-v2-icon-url: url("/assets/theme-v2/svg/gfs-trash.svg")
}

.theme-icon--validation {
--theme-v2-icon-url: url("/assets/theme-v2/svg/gfs-warning.svg")
}

.theme-icon--warning {
--theme-v2-icon-url: url("/assets/theme-v2/svg/gfs-warning.svg")
}

.status-icon {
height: var(--icon-size-sm);
width: var(--icon-size-sm)
}

.status-icon--error {
color: var(--red)
}

.status-icon--info {
color: var(--cyan)
}

.status-icon--save {
color: var(--green)
}

.status-icon--validation,
.status-icon--warning {
color: var(--gold)
}
8 changes: 8 additions & 0 deletions assets/theme-v2/css/status.css
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,20 @@
}

.toolbox-status-bar__message {
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--space-8);
margin: var(--space-0);
max-width: var(--measure-lg);
line-height: var(--line-height-copy);
overflow-wrap: anywhere
}

.toolbox-status-bar__status-icon {
flex: 0 0 auto
}

.toolbox-status-bar__progress {
min-width: var(--space-0);
max-width: var(--toolbox-status-progress-max);
Expand Down
5 changes: 5 additions & 0 deletions assets/theme-v2/js/theme-icons.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,21 @@ const themeV2IconRegistry = Object.freeze({
"chevron-right": "gfs-chevron-right.svg",
"chevron-up": "gfs-chevron-up.svg",
close: "gfs-close.svg",
delete: "gfs-trash.svg",
edit: "gfs-settings.svg",
error: "gfs-error.svg",
"external-link": "gfs-chevron-right.svg",
"exit-fullscreen": "gfs-exit-fullscreen.svg",
fullscreen: "gfs-fullscreen.svg",
info: "gfs-info.svg",
menu: "gfs-menu.svg",
save: "gfs-success.svg",
search: "gfs-search.svg",
settings: "gfs-settings.svg",
subtract: "gfs-subtract.svg",
success: "gfs-success.svg",
trash: "gfs-trash.svg",
validation: "gfs-warning.svg",
warning: "gfs-warning.svg",
});

Expand Down
43 changes: 37 additions & 6 deletions assets/theme-v2/js/toolbox-status-bar.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { readGameJourneyCompletionMetrics } from "/src/api/game-journey-completion-api-client.js";
import { createServerRepositoryClient } from "/src/api/server-api-client.js";
import { getToolBySlug } from "/src/shared/toolbox/tool-metadata-inventory.js";
import { createThemeIcon } from "/assets/theme-v2/js/theme-icons.js";

const EXCLUDED_SELECTED_GAME_TOOLS = new Set(["idea-board"]);
const STATUS_BAR_SELECTOR = "[data-toolbox-status-bar]";
const STATUS_ICON_BY_CONTEXT_KIND = Object.freeze({
action: "add",
delete: "delete",
error: "error",
info: "info",
save: "save",
validation: "validation",
warning: "warning",
});
const TOOL_PROGRESS_BUCKET_BY_SLUG = Object.freeze({
"achievements": "Progression",
"assets": "Graphics",
Expand Down Expand Up @@ -262,10 +272,31 @@ function classifyToolContext(messageText, state, required) {
if (/\b(validation|requirement|requirements|missing|required|open or seed)\b/i.test(text)) {
return { kind: "validation" };
}
if (/\b(saved|created|deleted|updated|loaded|save changes)\b/i.test(text)) {
if (/\b(deleted)\b/i.test(text)) {
return { kind: "delete" };
}
if (/\b(saved|created|updated|loaded|save changes)\b/i.test(text)) {
return { kind: "save" };
}
return { kind: "action" };
return { kind: "info" };
}

function statusIconNameForKind(kind) {
return STATUS_ICON_BY_CONTEXT_KIND[kind] || STATUS_ICON_BY_CONTEXT_KIND.info;
}

function renderStatusMessage(message, text, context) {
if (!message) {
return;
}
const kind = context?.kind || "info";
const iconName = statusIconNameForKind(kind);
const icon = createThemeIcon(iconName, {
className: ["status-icon", `status-icon--${kind}`, "toolbox-status-bar__status-icon"],
});
message.dataset.toolboxStatusIcon = iconName;
message.dataset.toolboxStatusKind = kind;
message.replaceChildren(icon, document.createTextNode(text));
}

function normalizeTextKey(value) {
Expand Down Expand Up @@ -387,24 +418,24 @@ function renderSelectedGame(bar, selectedGame, state, messageText) {

if (selectedGame) {
name.textContent = selectedGame.name;
message.textContent = nextMessage;
renderStatusMessage(message, nextMessage, context);
return;
}

if (!required) {
name.textContent = "No game selected";
message.textContent = nextMessage;
renderStatusMessage(message, nextMessage, context);
return;
}

if (state === "error") {
name.textContent = "Unavailable";
message.textContent = nextMessage;
renderStatusMessage(message, nextMessage, context);
return;
}

name.textContent = "No game selected";
message.textContent = "Select or create a game in Game Hub before using this toolbox page.";
renderStatusMessage(message, "Select or create a game in Game Hub before using this toolbox page.", context);
}

export function refreshToolboxStatusBar() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# PR_26175_ALFA_049-theme-v2-status-action-icons Manual Validation Notes

- Confirmed Theme V2 registry aliases map semantic status/action names to the existing authoritative SVG files without adding or modifying SVG artwork.
- Confirmed generated status bar icons preserve the existing visible status message text.
- Confirmed the Game Hub save, warning prompt, and missing-game prompt states render the expected registry-backed status icons.
- Confirmed shared icon button classes support paired visible text and icon-only aria-label patterns.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# PR_26175_ALFA_049-theme-v2-status-action-icons Report

## Summary
- Added semantic Theme V2 icon registry aliases for status/action affordances: save, validation, delete, edit, and external-link.
- Added shared icon button and status icon CSS classes in the Theme V2 CSS layer.
- Updated the shared toolbox status bar to render a registry-backed semantic status icon while preserving the existing selected-game, message, and progress text behavior.

## Branch Validation
PASS

## Notes
- Icons supplement existing text and accessible button names; no visible status labels removed by ALFA_009 were reintroduced.
- No large banners, modal-style messages, row highlights, inline styles, style blocks, or page-local CSS were added.
- A local ignored .env from the original checkout was used only to run database-dependent Playwright lanes. It is ignored and is not included in the delta package.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# PR_26175_ALFA_049-theme-v2-status-action-icons Requirements Checklist

- PASS: Add shared icon button CSS classes in buttons.css.
- PASS: Add shared status icon CSS classes in icons.css and status.css.
- PASS: Add helper usage in toolbox-status-bar.js only for semantic status icons.
- PASS: Keep status bar left, center, and right text behavior intact.
- PASS: Preserve creator-facing language and avoid reintroducing removed visible status labels.
- PASS: Ensure action icons have accessible names through paired visible text or aria-label.
- PASS: Keep status/action icon usage consistent for save, warning, error, validation, info, add, edit, delete, close, and external-link affordances covered by the scoped files.
- PASS: No large banners or modal-style messages introduced.
- PASS: No row highlights introduced.
- PASS: No inline styles, style blocks, or page-local CSS introduced.
- PASS: Exact required validation lane is green.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# PR_26175_ALFA_049-theme-v2-status-action-icons Validation Lane

## Static Checks
- PASS: node --check assets/theme-v2/js/theme-icons.js
- PASS: node --check assets/theme-v2/js/toolbox-status-bar.js

## Playwright
- PASS: npx playwright test tests/playwright/tools/ThemeV2SvgIconRegistry.spec.mjs --workers=1 (8 passed)
- PASS: npx playwright test tests/playwright/tools/ToolboxSelectedGameStatusBar.spec.mjs --workers=1 (7 passed)

## Pattern Scan
- PASS: rg -n "<[s]tyle|[s]tyle=" assets/theme-v2/js/theme-icons.js assets/theme-v2/js/toolbox-status-bar.js assets/theme-v2/css/icons.css assets/theme-v2/css/buttons.css assets/theme-v2/css/status.css tests/playwright/tools/ThemeV2SvgIconRegistry.spec.mjs tests/playwright/tools/ToolboxSelectedGameStatusBar.spec.mjs

## Branch Validation
PASS
18 changes: 8 additions & 10 deletions docs_build/dev/reports/codex_changed_files.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
assets/theme-v2/css/accordion.css
assets/theme-v2/css/buttons.css
assets/theme-v2/css/icons.css
assets/theme-v2/css/panels.css
assets/theme-v2/css/tables.css
assets/theme-v2/css/theme.css
assets/theme-v2/css/status.css
assets/theme-v2/js/theme-icons.js
assets/theme-v2/js/tool-display-mode.js
assets/toolbox/idea-board/js/index.js
assets/theme-v2/js/toolbox-status-bar.js
tests/playwright/tools/ThemeV2SvgIconRegistry.spec.mjs
docs_build/dev/reports/PR_26175_ALFA_048-theme-v2-chevron-conversion_manual-validation-notes.md
docs_build/dev/reports/PR_26175_ALFA_048-theme-v2-chevron-conversion_report.md
docs_build/dev/reports/PR_26175_ALFA_048-theme-v2-chevron-conversion_requirements-checklist.md
docs_build/dev/reports/PR_26175_ALFA_048-theme-v2-chevron-conversion_validation-lane.md
tests/playwright/tools/ToolboxSelectedGameStatusBar.spec.mjs
docs_build/dev/reports/PR_26175_ALFA_049-theme-v2-status-action-icons_report.md
docs_build/dev/reports/PR_26175_ALFA_049-theme-v2-status-action-icons_validation-lane.md
docs_build/dev/reports/PR_26175_ALFA_049-theme-v2-status-action-icons_requirements-checklist.md
docs_build/dev/reports/PR_26175_ALFA_049-theme-v2-status-action-icons_manual-validation-notes.md
docs_build/dev/reports/codex_changed_files.txt
docs_build/dev/reports/codex_review.diff
Loading
Loading