mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-10 09:19:42 +02:00
fix(header): keep open Tiles and Split pressed in the boxed header styles
#538's Compact and Tiles header styles give every header icon button a box through `html[data-header-stats] .header-right > .btn-icon-header` (0,3,1, hover 0,4,1), which sets background, border and colour. That outranks the open-state accent of #561's Tiles button (`.tiles-open`, 0,3,0) and of the Split button (`.split-open`), hover included, so under the default Tiles style an open grid or split looked exactly like a closed one and nothing said the next click would close it. The boxed styles now restate the pressed look for both buttons, hover included (accent fill, accent border, accent ink), as comma-grouped selectors built on the box rule's own selector so they always outrank it. Classic is untouched and keeps the buttons' own rules. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { JSDOM } from 'jsdom';
|
||||
import postcss from 'postcss';
|
||||
import { beforeAll, beforeEach, describe, expect, it } from 'vitest';
|
||||
|
||||
const PUBLIC = join(process.cwd(), 'src/web/public');
|
||||
@@ -225,6 +226,40 @@ describe('header stats wiring (static)', () => {
|
||||
expect(css).toMatch(/html\[data-header-stats='tiles'\] \.header-right > \.btn-icon-header > svg \{\s*width: 18px;/);
|
||||
});
|
||||
|
||||
it('keeps the open Tiles and Split buttons pressed (accent) in the boxed styles, hover included', () => {
|
||||
// The box rule (html[data-header-stats] .header-right > .btn-icon-header)
|
||||
// outranks the buttons' own open-state accent, so nothing would show that
|
||||
// the next click closes the grid or the split.
|
||||
const found = new Map<string, Record<string, string>>();
|
||||
postcss.parse(css).walkRules((rule) => {
|
||||
const decls: Record<string, string> = {};
|
||||
rule.walkDecls((d) => {
|
||||
decls[d.prop] = d.value;
|
||||
});
|
||||
for (const sel of rule.selectors) found.set(sel, { ...found.get(sel), ...decls });
|
||||
});
|
||||
const missing: string[] = [];
|
||||
for (const style of ['tiles', 'compact']) {
|
||||
for (const open of ['btn-tile-grid.tiles-open', 'btn-split.split-open']) {
|
||||
for (const hover of ['', ':hover']) {
|
||||
// Starting from the box rule's own selector keeps it the more specific one.
|
||||
const sel = `html[data-header-stats='${style}'] .header-right > .btn-icon-header.${open}${hover}`;
|
||||
const d = found.get(sel);
|
||||
if (
|
||||
d?.background !== 'var(--accent)' ||
|
||||
d['border-color'] !== 'var(--accent)' ||
|
||||
d.color !== 'var(--accent-ink)'
|
||||
)
|
||||
missing.push(sel);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect(missing).toEqual([]);
|
||||
// Classic keeps the buttons' own rules: nothing scoped to it touches them.
|
||||
expect([...found.keys()].filter((s) => s.includes("'classic'") && /tiles-open|split-open/.test(s))).toEqual([]);
|
||||
expect([...found.keys()].filter((s) => /(tiles|split)-open/.test(s) && s.includes(':is('))).toEqual([]);
|
||||
});
|
||||
|
||||
it('stamps data-header-stats before first paint, tiles by default and classic on narrow screens', () => {
|
||||
expect(INDEX).toContain(
|
||||
"dataset.headerStats=(window.innerWidth<768||solo)?'classic':(H==='classic'||H==='compact')?H:'tiles'"
|
||||
|
||||
Reference in New Issue
Block a user