fix(clip): a time's error line sits in the flow, the remove button off the cut, and every player surface rings amber
- useTimecodeField holds a time field's draft for its caller, which places TimecodeError (role alert) in its own flow under the fields' row: it no longer lies over the crop row taking its clicks, runs out of the editor's card, or joins the field's <label> name. - The editor's remove-cut buttons sit in a row under the track at their cut (trackLeft), off the cut's grab area, where a press drags it; RangeTrack's adornment slot is gone. - media-focus re-points --focus to the media amber on the Plex player, the YouTube stage and every bg-media-chrome surface; a contract test holds each such class string to media-focus or media-scope, the field's focus edge to the focus token, and --color-focus to the inline theme. - An upload's quota headline says the converted file does not fit, not "Storage full". - DESIGN.md: the tokens paragraph says what is re-pointed where; the decision row measures all three colours on the chrome.
This commit is contained in:
@@ -68,7 +68,33 @@ describe("the media colours", () => {
|
||||
expect(scope).toMatch(/--danger:\s*var\(--media-danger\);/);
|
||||
expect(scope).toMatch(/--focus:\s*var\(--media-mark\);/);
|
||||
expect(css).toMatch(/outline: 2px solid var\(--focus, var\(--accent\)\);/);
|
||||
expect(css).toMatch(/--color-focus: var\(--focus, var\(--accent\)\);/);
|
||||
// In the `inline` theme block, so `focus-*` utilities read --focus where they are used — a plain
|
||||
// @theme resolves it once on :root, and a scope's own --focus never reaches them.
|
||||
const at2 = css.indexOf("@theme inline {");
|
||||
expect(css.slice(at2, css.indexOf("\n}", at2))).toMatch(
|
||||
/--color-focus: var\(--focus, var\(--accent\)\);/,
|
||||
);
|
||||
// A field's focus edge is that colour too, not the accent's.
|
||||
const field = readFileSync(new URL("../components/ui/fieldStyles.ts", import.meta.url), "utf8");
|
||||
expect(field).toMatch(/\bfocus-within:border-focus\b/);
|
||||
expect(field).toMatch(/\bfocus-within:ring-focus\b/);
|
||||
expect(field).not.toMatch(/\bfocus-within:(border|ring)-accent\b/);
|
||||
});
|
||||
|
||||
it("every surface painted the player chrome names its focus colour", () => {
|
||||
const at = css.indexOf("@utility media-focus {");
|
||||
expect(css.slice(at, css.indexOf("\n}", at))).toMatch(/--focus:\s*var\(--media-mark\);/);
|
||||
// A class string that paints the chrome carries the media focus (media-scope re-points it too):
|
||||
// the theme's accent ring fell under 3:1 on it in a light scheme.
|
||||
const root = new URL("../", import.meta.url);
|
||||
const offenders: string[] = [];
|
||||
for (const f of readdirSync(root, { recursive: true, encoding: "utf8" })) {
|
||||
if (!/\.tsx?$/.test(f) || /\.test\.tsx?$/.test(f)) continue;
|
||||
const src = readFileSync(new URL(f.replace(/\\/g, "/"), root), "utf8");
|
||||
for (const m of src.matchAll(/["'`]([^"'`]*\bbg-media-chrome\b[^"'`]*)["'`]/g))
|
||||
if (!/\bmedia-(scope|focus)\b/.test(m[1]!)) offenders.push(`${f}: ${m[1]}`);
|
||||
}
|
||||
expect(offenders).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user