eidos: focus ring uses box-shadow (project kills outlines globally),
dialog overlay self-positions
Two bugs surfaced by Playwright verification at /test/eidos:
1) Focus ring: archetypes.css used `outline: ...` for the focus-visible
ring. The project's layout.css has a Tailwind layer/components rule
`*:not(body):not(.focus-override) { outline: none !important }` that
kills every outline. The eidos rule was never visible.
Switch to a two-layer box-shadow ring (inner transparent gap +
outer color). Box-shadow follows border-radius, so the ring also
looks right on pills (Switch) and rounded corners (Toggle, Dialog
buttons). Ring also stands out against accent-filled states because
it sits OUTSIDE the element, not on top of it.
2) Dialog overlay: the recipe relied on [data-archetype='overlay']
from archetypes.css for `position: fixed; inset: 0`, but Dialog isn't
migrated to MorfoRuntime yet — its provider uses legacy createAttrs
which doesn't read morfo's `archetype` field. The overlay element
had `position: static, height: 0`, so the backdrop was invisible.
Inline `position: fixed; inset: 0` directly in the recipe. Component
recipes shouldn't depend on archetype rules for foundational behavior;
archetype is a transversal extra, not a foundation.
Adds scripts/check-eidos-recipes.ts — Playwright script that opens
/test/eidos, tabs into Toggle/Switch, opens the dialog, prints
computed styles + saves screenshots to g:/tmp/eidos. Used to catch
both bugs; reproducible for future visual checks.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
/**
|
|
|
|
|
* Verifies eidos recipes render correctly in /uix/components.
|
eidos: focus ring uses box-shadow (project kills outlines globally),
dialog overlay self-positions
Two bugs surfaced by Playwright verification at /test/eidos:
1) Focus ring: archetypes.css used `outline: ...` for the focus-visible
ring. The project's layout.css has a Tailwind layer/components rule
`*:not(body):not(.focus-override) { outline: none !important }` that
kills every outline. The eidos rule was never visible.
Switch to a two-layer box-shadow ring (inner transparent gap +
outer color). Box-shadow follows border-radius, so the ring also
looks right on pills (Switch) and rounded corners (Toggle, Dialog
buttons). Ring also stands out against accent-filled states because
it sits OUTSIDE the element, not on top of it.
2) Dialog overlay: the recipe relied on [data-archetype='overlay']
from archetypes.css for `position: fixed; inset: 0`, but Dialog isn't
migrated to MorfoRuntime yet — its provider uses legacy createAttrs
which doesn't read morfo's `archetype` field. The overlay element
had `position: static, height: 0`, so the backdrop was invisible.
Inline `position: fixed; inset: 0` directly in the recipe. Component
recipes shouldn't depend on archetype rules for foundational behavior;
archetype is a transversal extra, not a foundation.
Adds scripts/check-eidos-recipes.ts — Playwright script that opens
/test/eidos, tabs into Toggle/Switch, opens the dialog, prints
computed styles + saves screenshots to g:/tmp/eidos. Used to catch
both bugs; reproducible for future visual checks.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
*
|
|
|
|
|
* 1. Toggle (★) — has data-archetype + focus ring on Tab.
|
|
|
|
|
* 2. Switch — has data-archetype + focus ring on Tab.
|
|
|
|
|
* 3. Dialog — opens via click, content + overlay visible, persists.
|
|
|
|
|
*
|
|
|
|
|
* Saves screenshots to /tmp/eidos-*.png so I can inspect.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import { chromium } from 'playwright';
|
|
|
|
|
import { mkdir } from 'node:fs/promises';
|
|
|
|
|
|
|
|
|
|
const OUT = 'g:/tmp/eidos';
|
|
|
|
|
|
|
|
|
|
async function probePort(): Promise<string | null> {
|
|
|
|
|
for (let port = 5173; port <= 5180; port++) {
|
eidos: focus ring uses box-shadow (project kills outlines globally),
dialog overlay self-positions
Two bugs surfaced by Playwright verification at /test/eidos:
1) Focus ring: archetypes.css used `outline: ...` for the focus-visible
ring. The project's layout.css has a Tailwind layer/components rule
`*:not(body):not(.focus-override) { outline: none !important }` that
kills every outline. The eidos rule was never visible.
Switch to a two-layer box-shadow ring (inner transparent gap +
outer color). Box-shadow follows border-radius, so the ring also
looks right on pills (Switch) and rounded corners (Toggle, Dialog
buttons). Ring also stands out against accent-filled states because
it sits OUTSIDE the element, not on top of it.
2) Dialog overlay: the recipe relied on [data-archetype='overlay']
from archetypes.css for `position: fixed; inset: 0`, but Dialog isn't
migrated to MorfoRuntime yet — its provider uses legacy createAttrs
which doesn't read morfo's `archetype` field. The overlay element
had `position: static, height: 0`, so the backdrop was invisible.
Inline `position: fixed; inset: 0` directly in the recipe. Component
recipes shouldn't depend on archetype rules for foundational behavior;
archetype is a transversal extra, not a foundation.
Adds scripts/check-eidos-recipes.ts — Playwright script that opens
/test/eidos, tabs into Toggle/Switch, opens the dialog, prints
computed styles + saves screenshots to g:/tmp/eidos. Used to catch
both bugs; reproducible for future visual checks.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
try {
|
|
|
|
|
const r = await fetch(`http://localhost:${port}/`, { signal: AbortSignal.timeout(500) });
|
|
|
|
|
if (r.ok || r.status === 404 || r.status === 500) return `http://localhost:${port}`;
|
eidos: focus ring uses box-shadow (project kills outlines globally),
dialog overlay self-positions
Two bugs surfaced by Playwright verification at /test/eidos:
1) Focus ring: archetypes.css used `outline: ...` for the focus-visible
ring. The project's layout.css has a Tailwind layer/components rule
`*:not(body):not(.focus-override) { outline: none !important }` that
kills every outline. The eidos rule was never visible.
Switch to a two-layer box-shadow ring (inner transparent gap +
outer color). Box-shadow follows border-radius, so the ring also
looks right on pills (Switch) and rounded corners (Toggle, Dialog
buttons). Ring also stands out against accent-filled states because
it sits OUTSIDE the element, not on top of it.
2) Dialog overlay: the recipe relied on [data-archetype='overlay']
from archetypes.css for `position: fixed; inset: 0`, but Dialog isn't
migrated to MorfoRuntime yet — its provider uses legacy createAttrs
which doesn't read morfo's `archetype` field. The overlay element
had `position: static, height: 0`, so the backdrop was invisible.
Inline `position: fixed; inset: 0` directly in the recipe. Component
recipes shouldn't depend on archetype rules for foundational behavior;
archetype is a transversal extra, not a foundation.
Adds scripts/check-eidos-recipes.ts — Playwright script that opens
/test/eidos, tabs into Toggle/Switch, opens the dialog, prints
computed styles + saves screenshots to g:/tmp/eidos. Used to catch
both bugs; reproducible for future visual checks.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
} catch {}
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function main() {
|
|
|
|
|
const base = await probePort();
|
|
|
|
|
if (!base) {
|
|
|
|
|
console.error('No dev server. Run npm run dev.');
|
|
|
|
|
process.exit(2);
|
|
|
|
|
}
|
|
|
|
|
await mkdir(OUT, { recursive: true });
|
|
|
|
|
|
|
|
|
|
const browser = await chromium.launch();
|
|
|
|
|
const ctx = await browser.newContext({ viewport: { width: 900, height: 1100 } });
|
|
|
|
|
const page = await ctx.newPage();
|
|
|
|
|
|
|
|
|
|
page.on('console', (msg) => {
|
|
|
|
|
if (msg.type() === 'error') console.log(`[console error] ${msg.text()}`);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// ── 1. Toggle ────────────────────────────────────────────────────────────
|
|
|
|
|
await page.goto(`${base}/uix/components/toggle`, { waitUntil: 'networkidle' });
|
eidos: drop legacy hand-rolled tokens.css, consume air-translated tokens
Replace the V1.5 hand-rolled motion/easing/tint/opacity/focus-ring
tokens with the air-translated equivalents already in eidos/themes/
base/_static.css and eidos/themes/base/light.css.
Substitutions applied to archetypes.css, events.css, components/
dialog.css:
--eidos-motion-fast → --eidos-duration-fast (120ms)
--eidos-motion-base → --eidos-duration-slow (320ms)
--eidos-easing-standard → --eidos-ease-default
--eidos-easing-decelerate → --eidos-ease-out
--eidos-easing-emphasized → --eidos-ease-spring
--eidos-tint-neutral → --eidos-color-neutral-element
--eidos-tint-affirm → --eidos-color-success-element
--eidos-tint-fulfill → --eidos-color-success-element
--eidos-tint-risk → --eidos-color-warning-element
--eidos-tint-threat → --eidos-color-danger-element
var(--eidos-opacity-hover) → 0.85 (single-site, archetype-internal)
var(--eidos-opacity-disabled) → 0.5 (single-site, archetype-internal)
Focus ring tokens (--eidos-focus-ring-{color,width,offset}) unchanged
— same names already exist in air's _static.css/light.css.
`affirm` and `fulfill` collapse to the same `success-element` because
air's intent vocabulary doesn't distinguish them. The morfo's
data-intent attr still preserves the distinction at the structural
layer; the visual mapping is just the same color.
Updated scripts/check-eidos-recipes.ts to navigate to the per-component
demo URLs (/test/eidos/{toggle,switch,dialog}) since the index page
no longer renders the recipes directly.
Verification: smoke 68/68, morfo-check 66/66. Playwright entrance/exit
curves intact (opacity interpolates over the configured durations).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
await page.waitForTimeout(300);
|
eidos: focus ring uses box-shadow (project kills outlines globally),
dialog overlay self-positions
Two bugs surfaced by Playwright verification at /test/eidos:
1) Focus ring: archetypes.css used `outline: ...` for the focus-visible
ring. The project's layout.css has a Tailwind layer/components rule
`*:not(body):not(.focus-override) { outline: none !important }` that
kills every outline. The eidos rule was never visible.
Switch to a two-layer box-shadow ring (inner transparent gap +
outer color). Box-shadow follows border-radius, so the ring also
looks right on pills (Switch) and rounded corners (Toggle, Dialog
buttons). Ring also stands out against accent-filled states because
it sits OUTSIDE the element, not on top of it.
2) Dialog overlay: the recipe relied on [data-archetype='overlay']
from archetypes.css for `position: fixed; inset: 0`, but Dialog isn't
migrated to MorfoRuntime yet — its provider uses legacy createAttrs
which doesn't read morfo's `archetype` field. The overlay element
had `position: static, height: 0`, so the backdrop was invisible.
Inline `position: fixed; inset: 0` directly in the recipe. Component
recipes shouldn't depend on archetype rules for foundational behavior;
archetype is a transversal extra, not a foundation.
Adds scripts/check-eidos-recipes.ts — Playwright script that opens
/test/eidos, tabs into Toggle/Switch, opens the dialog, prints
computed styles + saves screenshots to g:/tmp/eidos. Used to catch
both bugs; reproducible for future visual checks.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
const toggle = page.locator('[data-toggle]').first();
|
|
|
|
|
const toggleAttrs = await toggle.evaluate((el) => ({
|
|
|
|
|
dataToggle: el.getAttribute('data-toggle'),
|
|
|
|
|
dataArchetype: el.getAttribute('data-archetype'),
|
|
|
|
|
tag: el.tagName.toLowerCase()
|
|
|
|
|
}));
|
|
|
|
|
console.log('Toggle attrs:', toggleAttrs);
|
|
|
|
|
|
|
|
|
|
// Click body first so we have a focus origin, then tab into the toggle.
|
|
|
|
|
await page.locator('body').click({ position: { x: 5, y: 5 } });
|
|
|
|
|
await page.waitForTimeout(50);
|
|
|
|
|
// Tab until we hit the toggle button (skip the Soma layout bar if present).
|
|
|
|
|
for (let i = 0; i < 10; i++) {
|
|
|
|
|
await page.keyboard.press('Tab');
|
|
|
|
|
const isToggle = await page.evaluate(() => document.activeElement?.hasAttribute('data-toggle') ?? false);
|
|
|
|
|
if (isToggle) break;
|
|
|
|
|
}
|
|
|
|
|
await page.waitForTimeout(100);
|
|
|
|
|
const toggleFocusOutline = await toggle.evaluate((el) => {
|
|
|
|
|
const cs = getComputedStyle(el);
|
|
|
|
|
return {
|
|
|
|
|
matchesFocusVisible: el.matches(':focus-visible'),
|
|
|
|
|
outlineStyle: cs.outlineStyle,
|
|
|
|
|
outlineWidth: cs.outlineWidth,
|
|
|
|
|
boxShadow: cs.boxShadow
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
console.log('Toggle ring (Tab focused):', toggleFocusOutline);
|
|
|
|
|
await page.screenshot({ path: `${OUT}/01-toggle-focused.png`, fullPage: false });
|
|
|
|
|
|
|
|
|
|
// ── 2. Switch ────────────────────────────────────────────────────────────
|
|
|
|
|
await page.goto(`${base}/uix/components/switch`, { waitUntil: 'networkidle' });
|
eidos: drop legacy hand-rolled tokens.css, consume air-translated tokens
Replace the V1.5 hand-rolled motion/easing/tint/opacity/focus-ring
tokens with the air-translated equivalents already in eidos/themes/
base/_static.css and eidos/themes/base/light.css.
Substitutions applied to archetypes.css, events.css, components/
dialog.css:
--eidos-motion-fast → --eidos-duration-fast (120ms)
--eidos-motion-base → --eidos-duration-slow (320ms)
--eidos-easing-standard → --eidos-ease-default
--eidos-easing-decelerate → --eidos-ease-out
--eidos-easing-emphasized → --eidos-ease-spring
--eidos-tint-neutral → --eidos-color-neutral-element
--eidos-tint-affirm → --eidos-color-success-element
--eidos-tint-fulfill → --eidos-color-success-element
--eidos-tint-risk → --eidos-color-warning-element
--eidos-tint-threat → --eidos-color-danger-element
var(--eidos-opacity-hover) → 0.85 (single-site, archetype-internal)
var(--eidos-opacity-disabled) → 0.5 (single-site, archetype-internal)
Focus ring tokens (--eidos-focus-ring-{color,width,offset}) unchanged
— same names already exist in air's _static.css/light.css.
`affirm` and `fulfill` collapse to the same `success-element` because
air's intent vocabulary doesn't distinguish them. The morfo's
data-intent attr still preserves the distinction at the structural
layer; the visual mapping is just the same color.
Updated scripts/check-eidos-recipes.ts to navigate to the per-component
demo URLs (/test/eidos/{toggle,switch,dialog}) since the index page
no longer renders the recipes directly.
Verification: smoke 68/68, morfo-check 66/66. Playwright entrance/exit
curves intact (opacity interpolates over the configured durations).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
await page.waitForTimeout(300);
|
eidos: focus ring uses box-shadow (project kills outlines globally),
dialog overlay self-positions
Two bugs surfaced by Playwright verification at /test/eidos:
1) Focus ring: archetypes.css used `outline: ...` for the focus-visible
ring. The project's layout.css has a Tailwind layer/components rule
`*:not(body):not(.focus-override) { outline: none !important }` that
kills every outline. The eidos rule was never visible.
Switch to a two-layer box-shadow ring (inner transparent gap +
outer color). Box-shadow follows border-radius, so the ring also
looks right on pills (Switch) and rounded corners (Toggle, Dialog
buttons). Ring also stands out against accent-filled states because
it sits OUTSIDE the element, not on top of it.
2) Dialog overlay: the recipe relied on [data-archetype='overlay']
from archetypes.css for `position: fixed; inset: 0`, but Dialog isn't
migrated to MorfoRuntime yet — its provider uses legacy createAttrs
which doesn't read morfo's `archetype` field. The overlay element
had `position: static, height: 0`, so the backdrop was invisible.
Inline `position: fixed; inset: 0` directly in the recipe. Component
recipes shouldn't depend on archetype rules for foundational behavior;
archetype is a transversal extra, not a foundation.
Adds scripts/check-eidos-recipes.ts — Playwright script that opens
/test/eidos, tabs into Toggle/Switch, opens the dialog, prints
computed styles + saves screenshots to g:/tmp/eidos. Used to catch
both bugs; reproducible for future visual checks.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
const sw = page.locator('[data-switch]').first();
|
|
|
|
|
const swAttrs = await sw.evaluate((el) => ({
|
|
|
|
|
dataSwitch: el.getAttribute('data-switch'),
|
|
|
|
|
dataArchetype: el.getAttribute('data-archetype'),
|
|
|
|
|
dataState: el.getAttribute('data-state'),
|
|
|
|
|
tag: el.tagName.toLowerCase()
|
|
|
|
|
}));
|
|
|
|
|
console.log('Switch attrs:', swAttrs);
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < 5; i++) {
|
|
|
|
|
await page.keyboard.press('Tab');
|
|
|
|
|
const isSwitch = await page.evaluate(() => document.activeElement?.hasAttribute('data-switch') ?? false);
|
|
|
|
|
if (isSwitch) break;
|
|
|
|
|
}
|
|
|
|
|
await page.waitForTimeout(100);
|
|
|
|
|
const swFocusOutline = await sw.evaluate((el) => {
|
|
|
|
|
const cs = getComputedStyle(el);
|
|
|
|
|
return {
|
|
|
|
|
matchesFocusVisible: el.matches(':focus-visible'),
|
|
|
|
|
boxShadow: cs.boxShadow,
|
|
|
|
|
width: cs.width,
|
|
|
|
|
height: cs.height,
|
|
|
|
|
background: cs.backgroundColor
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
console.log('Switch ring (Tab focused):', swFocusOutline);
|
|
|
|
|
await page.screenshot({ path: `${OUT}/02-switch-focused.png`, fullPage: false });
|
|
|
|
|
|
|
|
|
|
// ── 3. Dialog ────────────────────────────────────────────────────────────
|
|
|
|
|
await page.goto(`${base}/uix/components/dialog`, { waitUntil: 'networkidle' });
|
eidos: drop legacy hand-rolled tokens.css, consume air-translated tokens
Replace the V1.5 hand-rolled motion/easing/tint/opacity/focus-ring
tokens with the air-translated equivalents already in eidos/themes/
base/_static.css and eidos/themes/base/light.css.
Substitutions applied to archetypes.css, events.css, components/
dialog.css:
--eidos-motion-fast → --eidos-duration-fast (120ms)
--eidos-motion-base → --eidos-duration-slow (320ms)
--eidos-easing-standard → --eidos-ease-default
--eidos-easing-decelerate → --eidos-ease-out
--eidos-easing-emphasized → --eidos-ease-spring
--eidos-tint-neutral → --eidos-color-neutral-element
--eidos-tint-affirm → --eidos-color-success-element
--eidos-tint-fulfill → --eidos-color-success-element
--eidos-tint-risk → --eidos-color-warning-element
--eidos-tint-threat → --eidos-color-danger-element
var(--eidos-opacity-hover) → 0.85 (single-site, archetype-internal)
var(--eidos-opacity-disabled) → 0.5 (single-site, archetype-internal)
Focus ring tokens (--eidos-focus-ring-{color,width,offset}) unchanged
— same names already exist in air's _static.css/light.css.
`affirm` and `fulfill` collapse to the same `success-element` because
air's intent vocabulary doesn't distinguish them. The morfo's
data-intent attr still preserves the distinction at the structural
layer; the visual mapping is just the same color.
Updated scripts/check-eidos-recipes.ts to navigate to the per-component
demo URLs (/test/eidos/{toggle,switch,dialog}) since the index page
no longer renders the recipes directly.
Verification: smoke 68/68, morfo-check 66/66. Playwright entrance/exit
curves intact (opacity interpolates over the configured durations).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
await page.waitForTimeout(300);
|
eidos: focus ring uses box-shadow (project kills outlines globally),
dialog overlay self-positions
Two bugs surfaced by Playwright verification at /test/eidos:
1) Focus ring: archetypes.css used `outline: ...` for the focus-visible
ring. The project's layout.css has a Tailwind layer/components rule
`*:not(body):not(.focus-override) { outline: none !important }` that
kills every outline. The eidos rule was never visible.
Switch to a two-layer box-shadow ring (inner transparent gap +
outer color). Box-shadow follows border-radius, so the ring also
looks right on pills (Switch) and rounded corners (Toggle, Dialog
buttons). Ring also stands out against accent-filled states because
it sits OUTSIDE the element, not on top of it.
2) Dialog overlay: the recipe relied on [data-archetype='overlay']
from archetypes.css for `position: fixed; inset: 0`, but Dialog isn't
migrated to MorfoRuntime yet — its provider uses legacy createAttrs
which doesn't read morfo's `archetype` field. The overlay element
had `position: static, height: 0`, so the backdrop was invisible.
Inline `position: fixed; inset: 0` directly in the recipe. Component
recipes shouldn't depend on archetype rules for foundational behavior;
archetype is a transversal extra, not a foundation.
Adds scripts/check-eidos-recipes.ts — Playwright script that opens
/test/eidos, tabs into Toggle/Switch, opens the dialog, prints
computed styles + saves screenshots to g:/tmp/eidos. Used to catch
both bugs; reproducible for future visual checks.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
const dialogTrigger = page.locator('[data-dialog-trigger]').first();
|
|
|
|
|
const triggerExists = (await dialogTrigger.count()) > 0;
|
|
|
|
|
console.log('Dialog trigger exists:', triggerExists);
|
|
|
|
|
if (triggerExists) {
|
|
|
|
|
// Inject a sampler that records opacity at every rAF after the click.
|
|
|
|
|
await page.evaluate(`(() => {
|
|
|
|
|
window.__samples = [];
|
|
|
|
|
const trigger = document.querySelector('[data-dialog-trigger]');
|
|
|
|
|
const t0 = performance.now();
|
|
|
|
|
trigger.click();
|
|
|
|
|
const tick = () => {
|
|
|
|
|
const t = performance.now() - t0;
|
|
|
|
|
const el = document.querySelector('[data-dialog-content]');
|
|
|
|
|
if (el) {
|
|
|
|
|
const cs = getComputedStyle(el);
|
|
|
|
|
window.__samples.push({
|
|
|
|
|
t: Math.round(t),
|
|
|
|
|
opacity: parseFloat(cs.opacity),
|
|
|
|
|
hasStartingStyle: el.hasAttribute('data-starting-style')
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
if (t < 500) requestAnimationFrame(tick);
|
|
|
|
|
};
|
|
|
|
|
requestAnimationFrame(tick);
|
|
|
|
|
})()`);
|
|
|
|
|
await page.waitForTimeout(550);
|
|
|
|
|
const entranceSamples = await page.evaluate('window.__samples') as Array<{
|
|
|
|
|
t: number;
|
|
|
|
|
opacity: number;
|
|
|
|
|
hasStartingStyle: boolean;
|
|
|
|
|
}>;
|
|
|
|
|
const decimated = entranceSamples.filter((_, i) => i % 3 === 0 || i === entranceSamples.length - 1);
|
|
|
|
|
console.log('Entrance samples (t-ms, opacity, hasStartingStyle):');
|
|
|
|
|
for (const s of decimated) {
|
|
|
|
|
console.log(` t=${s.t}ms opacity=${s.opacity.toFixed(3)} starting=${s.hasStartingStyle}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const dialogContent = page.locator('[data-dialog-content]');
|
|
|
|
|
await page.screenshot({ path: `${OUT}/03a-dialog-entrance-mid.png`, fullPage: false });
|
eidos: focus ring uses box-shadow (project kills outlines globally),
dialog overlay self-positions
Two bugs surfaced by Playwright verification at /test/eidos:
1) Focus ring: archetypes.css used `outline: ...` for the focus-visible
ring. The project's layout.css has a Tailwind layer/components rule
`*:not(body):not(.focus-override) { outline: none !important }` that
kills every outline. The eidos rule was never visible.
Switch to a two-layer box-shadow ring (inner transparent gap +
outer color). Box-shadow follows border-radius, so the ring also
looks right on pills (Switch) and rounded corners (Toggle, Dialog
buttons). Ring also stands out against accent-filled states because
it sits OUTSIDE the element, not on top of it.
2) Dialog overlay: the recipe relied on [data-archetype='overlay']
from archetypes.css for `position: fixed; inset: 0`, but Dialog isn't
migrated to MorfoRuntime yet — its provider uses legacy createAttrs
which doesn't read morfo's `archetype` field. The overlay element
had `position: static, height: 0`, so the backdrop was invisible.
Inline `position: fixed; inset: 0` directly in the recipe. Component
recipes shouldn't depend on archetype rules for foundational behavior;
archetype is a transversal extra, not a foundation.
Adds scripts/check-eidos-recipes.ts — Playwright script that opens
/test/eidos, tabs into Toggle/Switch, opens the dialog, prints
computed styles + saves screenshots to g:/tmp/eidos. Used to catch
both bugs; reproducible for future visual checks.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
|
|
|
|
|
const dialogOverlay = page.locator('[data-dialog-overlay]');
|
|
|
|
|
const overlayCount = await dialogOverlay.count();
|
|
|
|
|
const contentCount = await dialogContent.count();
|
|
|
|
|
console.log(`Dialog opened — overlay count: ${overlayCount}, content count: ${contentCount}`);
|
|
|
|
|
|
|
|
|
|
if (contentCount > 0) {
|
|
|
|
|
const contentBox = await dialogContent.first().boundingBox();
|
|
|
|
|
const overlayBox = await dialogOverlay.first().boundingBox();
|
|
|
|
|
const overlayStyles = await dialogOverlay.first().evaluate((el) => {
|
|
|
|
|
const cs = getComputedStyle(el);
|
|
|
|
|
return {
|
|
|
|
|
position: cs.position,
|
|
|
|
|
inset: cs.inset,
|
|
|
|
|
top: cs.top,
|
|
|
|
|
left: cs.left,
|
|
|
|
|
right: cs.right,
|
|
|
|
|
bottom: cs.bottom,
|
|
|
|
|
width: cs.width,
|
|
|
|
|
height: cs.height,
|
|
|
|
|
background: cs.backgroundColor,
|
|
|
|
|
zIndex: cs.zIndex,
|
|
|
|
|
display: cs.display,
|
|
|
|
|
visibility: cs.visibility,
|
|
|
|
|
opacity: cs.opacity,
|
|
|
|
|
dataArchetype: el.getAttribute('data-archetype'),
|
|
|
|
|
parentTag: el.parentElement?.tagName.toLowerCase()
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
const contentStyles = await dialogContent.first().evaluate((el) => {
|
|
|
|
|
const cs = getComputedStyle(el);
|
|
|
|
|
return {
|
|
|
|
|
position: cs.position,
|
|
|
|
|
top: cs.top,
|
|
|
|
|
left: cs.left,
|
|
|
|
|
transform: cs.transform,
|
|
|
|
|
background: cs.backgroundColor,
|
|
|
|
|
zIndex: cs.zIndex,
|
|
|
|
|
display: cs.display,
|
|
|
|
|
visibility: cs.visibility,
|
|
|
|
|
opacity: cs.opacity
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
console.log('Dialog content box:', contentBox);
|
|
|
|
|
console.log('Dialog overlay box:', overlayBox);
|
|
|
|
|
console.log('Dialog overlay styles:', overlayStyles);
|
|
|
|
|
console.log('Dialog content styles:', contentStyles);
|
|
|
|
|
}
|
|
|
|
|
await page.screenshot({ path: `${OUT}/03-dialog-open.png`, fullPage: false });
|
|
|
|
|
|
|
|
|
|
await page.evaluate(`(() => {
|
|
|
|
|
window.__exitSamples = [];
|
|
|
|
|
const closeBtn = document.querySelector('[data-dialog-close]');
|
|
|
|
|
const t0 = performance.now();
|
|
|
|
|
closeBtn.click();
|
|
|
|
|
const tick = () => {
|
|
|
|
|
const t = performance.now() - t0;
|
|
|
|
|
const el = document.querySelector('[data-dialog-content]');
|
|
|
|
|
if (el) {
|
|
|
|
|
const cs = getComputedStyle(el);
|
|
|
|
|
window.__exitSamples.push({
|
|
|
|
|
t: Math.round(t),
|
|
|
|
|
opacity: parseFloat(cs.opacity),
|
|
|
|
|
hasEndingStyle: el.hasAttribute('data-ending-style'),
|
|
|
|
|
lastAction: el.getAttribute('data-last-action'),
|
|
|
|
|
borderTopColor: cs.borderTopColor,
|
|
|
|
|
mounted: true
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
window.__exitSamples.push({
|
|
|
|
|
t: Math.round(t), opacity: 0, hasEndingStyle: false, lastAction: null,
|
|
|
|
|
borderTopColor: '', mounted: false
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
if (t < 500) requestAnimationFrame(tick);
|
|
|
|
|
};
|
|
|
|
|
requestAnimationFrame(tick);
|
|
|
|
|
})()`);
|
|
|
|
|
await page.waitForTimeout(550);
|
|
|
|
|
const exitSamples = await page.evaluate('window.__exitSamples') as Array<{
|
|
|
|
|
t: number;
|
|
|
|
|
opacity: number;
|
|
|
|
|
hasEndingStyle: boolean;
|
|
|
|
|
lastAction: string | null;
|
|
|
|
|
borderTopColor: string;
|
|
|
|
|
mounted: boolean;
|
|
|
|
|
}>;
|
|
|
|
|
const exitDecimated = exitSamples.filter((_, i) => i % 3 === 0 || i === exitSamples.length - 1);
|
|
|
|
|
console.log('Exit samples (t-ms, opacity, hasEndingStyle, lastAction, borderTop, mounted):');
|
|
|
|
|
for (const s of exitDecimated) {
|
|
|
|
|
console.log(
|
|
|
|
|
` t=${s.t}ms opacity=${s.opacity.toFixed(3)} ending=${s.hasEndingStyle} lastAction=${s.lastAction} border=${s.borderTopColor} mounted=${s.mounted}`
|
|
|
|
|
);
|
eidos: focus ring uses box-shadow (project kills outlines globally),
dialog overlay self-positions
Two bugs surfaced by Playwright verification at /test/eidos:
1) Focus ring: archetypes.css used `outline: ...` for the focus-visible
ring. The project's layout.css has a Tailwind layer/components rule
`*:not(body):not(.focus-override) { outline: none !important }` that
kills every outline. The eidos rule was never visible.
Switch to a two-layer box-shadow ring (inner transparent gap +
outer color). Box-shadow follows border-radius, so the ring also
looks right on pills (Switch) and rounded corners (Toggle, Dialog
buttons). Ring also stands out against accent-filled states because
it sits OUTSIDE the element, not on top of it.
2) Dialog overlay: the recipe relied on [data-archetype='overlay']
from archetypes.css for `position: fixed; inset: 0`, but Dialog isn't
migrated to MorfoRuntime yet — its provider uses legacy createAttrs
which doesn't read morfo's `archetype` field. The overlay element
had `position: static, height: 0`, so the backdrop was invisible.
Inline `position: fixed; inset: 0` directly in the recipe. Component
recipes shouldn't depend on archetype rules for foundational behavior;
archetype is a transversal extra, not a foundation.
Adds scripts/check-eidos-recipes.ts — Playwright script that opens
/test/eidos, tabs into Toggle/Switch, opens the dialog, prints
computed styles + saves screenshots to g:/tmp/eidos. Used to catch
both bugs; reproducible for future visual checks.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
}
|
|
|
|
|
await page.screenshot({ path: `${OUT}/04-dialog-closed.png`, fullPage: false });
|
eidos: focus ring uses box-shadow (project kills outlines globally),
dialog overlay self-positions
Two bugs surfaced by Playwright verification at /test/eidos:
1) Focus ring: archetypes.css used `outline: ...` for the focus-visible
ring. The project's layout.css has a Tailwind layer/components rule
`*:not(body):not(.focus-override) { outline: none !important }` that
kills every outline. The eidos rule was never visible.
Switch to a two-layer box-shadow ring (inner transparent gap +
outer color). Box-shadow follows border-radius, so the ring also
looks right on pills (Switch) and rounded corners (Toggle, Dialog
buttons). Ring also stands out against accent-filled states because
it sits OUTSIDE the element, not on top of it.
2) Dialog overlay: the recipe relied on [data-archetype='overlay']
from archetypes.css for `position: fixed; inset: 0`, but Dialog isn't
migrated to MorfoRuntime yet — its provider uses legacy createAttrs
which doesn't read morfo's `archetype` field. The overlay element
had `position: static, height: 0`, so the backdrop was invisible.
Inline `position: fixed; inset: 0` directly in the recipe. Component
recipes shouldn't depend on archetype rules for foundational behavior;
archetype is a transversal extra, not a foundation.
Adds scripts/check-eidos-recipes.ts — Playwright script that opens
/test/eidos, tabs into Toggle/Switch, opens the dialog, prints
computed styles + saves screenshots to g:/tmp/eidos. Used to catch
both bugs; reproducible for future visual checks.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await browser.close();
|
|
|
|
|
console.log(`\nScreenshots saved to ${OUT}/`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
main().catch((e) => {
|
|
|
|
|
console.error(e);
|
|
|
|
|
process.exit(1);
|
|
|
|
|
});
|