Match easing and duration Tailwind classes only in a class list
outsideTheScale() read ease-in/ease-out/ease-in-out/duration-* line by line across every file, the way it still reads its other scale steps — but a plain CSS keyword read out of an API into a JS string (matchMedia(…) ? 'linear' : 'ease-out') names a real value, not a Tailwind class, and the same line scan read the words back out of a stylesheet test's own regex literals (`ease-in`, `ease-out`) as if they were Tailwind too. Tested both ways per the plan's instruction: Blade/PHP class lists have the identical false-positive shape, so the two families move to FAMILIES, matched only through a class list (literalClasses()/tailwindFamilyHint()) as the newer families already are, in Blade and PHP as much as in JavaScript. Plan step 42 (Phase F), Part B. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
9cfb24f419
commit
b243222e26
@@ -133,6 +133,14 @@ class DesignGuard
|
|||||||
['/^shadow-elevation-(?<level>[0-5])$/', '1.x utility `%s` compiles to nothing — use `var(--md-sys-elevation-{level})` in your own CSS'],
|
['/^shadow-elevation-(?<level>[0-5])$/', '1.x utility `%s` compiles to nothing — use `var(--md-sys-elevation-{level})` in your own CSS'],
|
||||||
['/^ease-(?<easing>(?:spatial|effects)-(?:fast|default|slow))$/', '1.x utility `%s` compiles to nothing — pair `var(--md-sys-motion-{easing})` with `var(--md-sys-motion-{easing}-duration)` in your own `transition`'],
|
['/^ease-(?<easing>(?:spatial|effects)-(?:fast|default|slow))$/', '1.x utility `%s` compiles to nothing — pair `var(--md-sys-motion-{easing})` with `var(--md-sys-motion-{easing}-duration)` in your own `transition`'],
|
||||||
['/^ease-(?<easing>standard|emphasized)(?<phase>-accelerate|-decelerate)?$/', '1.x utility `%s` compiles to nothing — use `var(--md-sys-motion-easing-{easing}{phase})` in your own `transition`'],
|
['/^ease-(?<easing>standard|emphasized)(?<phase>-accelerate|-decelerate)?$/', '1.x utility `%s` compiles to nothing — use `var(--md-sys-motion-easing-{easing}{phase})` in your own `transition`'],
|
||||||
|
// Tailwind's cleared easing and duration scale: matched only here, in a class list a
|
||||||
|
// Blade or PHP file writes literally (never line-by-line across every file, the way
|
||||||
|
// outsideTheScale() still reads its other scale steps) — a plain PHP or JS string such as
|
||||||
|
// `matchMedia(…) ? 'linear' : 'ease-out'` names a real CSS keyword, not a Tailwind class,
|
||||||
|
// and reading every line for the bare word flagged both that and the word appearing inside
|
||||||
|
// a stylesheet test's own regex literal (`ease-in`, `ease-out`) as if it were one.
|
||||||
|
['/^ease-(?:in-out|linear|in|out)$/', 'value outside the M3 scale `%s` — pair `var(--md-sys-motion-spatial-*)`/`var(--md-sys-motion-effects-*)` with its `-duration` in your own `transition`'],
|
||||||
|
['/^duration-\d+$/', 'value outside the M3 scale `%s` — pair `var(--md-sys-motion-…-duration)` with its easing in your own `transition`'],
|
||||||
['/^[a-z][a-z-]*-\((?<property>--[\w-]+)\)$/', 'Tailwind custom-property utility `%s` compiles to nothing — write `var({property})` in your own CSS'],
|
['/^[a-z][a-z-]*-\((?<property>--[\w-]+)\)$/', 'Tailwind custom-property utility `%s` compiles to nothing — write `var({property})` in your own CSS'],
|
||||||
|
|
||||||
['/^(?:static|fixed|absolute|relative|sticky)$/', "Tailwind position utility `%s` compiles to nothing — write `position` in your own CSS (a FAB goes in `<x-scaffold>`'s `fab` slot)"],
|
['/^(?:static|fixed|absolute|relative|sticky)$/', "Tailwind position utility `%s` compiles to nothing — write `position` in your own CSS (a FAB goes in `<x-scaffold>`'s `fab` slot)"],
|
||||||
@@ -566,8 +574,9 @@ class DesignGuard
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The radius, shadow, type-size, weight, leading, tracking, easing and duration utilities
|
* The radius, shadow, type-size, weight, leading and tracking utilities Tailwind shipped and
|
||||||
* Tailwind shipped and M3's own scales replace.
|
* M3's own scales replace. The easing and duration steps of the same Tailwind scale are not
|
||||||
|
* read here — see the class header's note by the `ease-*`/`duration-*` entries of `FAMILIES`.
|
||||||
*
|
*
|
||||||
* @return list<string>
|
* @return list<string>
|
||||||
*/
|
*/
|
||||||
@@ -581,8 +590,6 @@ class DesignGuard
|
|||||||
.'|font-(?<weight>thin|extralight|light|normal|medium|semibold|bold|extrabold|black)'
|
.'|font-(?<weight>thin|extralight|light|normal|medium|semibold|bold|extrabold|black)'
|
||||||
.'|leading-(?<leading>none|tight|snug|normal|relaxed|loose|\d+(?:\.\d+)?)'
|
.'|leading-(?<leading>none|tight|snug|normal|relaxed|loose|\d+(?:\.\d+)?)'
|
||||||
.'|tracking-(?<tracking>tighter|tight|normal|wider|widest|wide)'
|
.'|tracking-(?<tracking>tighter|tight|normal|wider|widest|wide)'
|
||||||
.'|ease-(?<easing>in-out|linear|in|out)'
|
|
||||||
.'|duration-(?<duration>\d+)'
|
|
||||||
.')(?![\w-])/';
|
.')(?![\w-])/';
|
||||||
|
|
||||||
preg_match_all($pattern, $text, $matches, PREG_SET_ORDER | PREG_UNMATCHED_AS_NULL);
|
preg_match_all($pattern, $text, $matches, PREG_SET_ORDER | PREG_UNMATCHED_AS_NULL);
|
||||||
@@ -606,8 +613,6 @@ class DesignGuard
|
|||||||
isset($match['corner']) => 'use `var(--md-sys-shape-corner-'.self::CORNERS[$match['corner']].')` in your own CSS, or `<x-surface corner="'.self::CORNERS[$match['corner']].'">`',
|
isset($match['corner']) => 'use `var(--md-sys-shape-corner-'.self::CORNERS[$match['corner']].')` in your own CSS, or `<x-surface corner="'.self::CORNERS[$match['corner']].'">`',
|
||||||
isset($match['elevation']) => 'use `var(--md-sys-elevation-'.self::ELEVATIONS[$match['elevation']].')` in your own CSS',
|
isset($match['elevation']) => 'use `var(--md-sys-elevation-'.self::ELEVATIONS[$match['elevation']].')` in your own CSS',
|
||||||
isset($match['weight']) => 'use one of the `md-type-emphasized-*` classes (text.css), or a `md-type-*` size already at the right weight',
|
isset($match['weight']) => 'use one of the `md-type-emphasized-*` classes (text.css), or a `md-type-*` size already at the right weight',
|
||||||
isset($match['easing']) => 'pair `var(--md-sys-motion-spatial-*)`/`var(--md-sys-motion-effects-*)` with its `-duration` in your own `transition`',
|
|
||||||
isset($match['duration']) => 'pair `var(--md-sys-motion-…-duration)` with its easing in your own `transition`',
|
|
||||||
default => 'use one of the `md-type-*` classes (text.css), which set size, line height and tracking together',
|
default => 'use one of the `md-type-*` classes (text.css), which set size, line height and tracking together',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,6 +150,16 @@ it('sends an easing and a duration to the motion tokens', function () {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('leaves an easing or a duration word alone in a JavaScript string outside a class list', function () {
|
||||||
|
// scale/motion.js reads a real CSS keyword out of matchMedia() into a variable named `easing`
|
||||||
|
// (`'linear'`/`'ease-out'`), the shape the plan calls out as a false positive: nothing here
|
||||||
|
// is a class list, so the class-context match above never sees it, and the family is off
|
||||||
|
// outsideTheScale()'s line scan since the fix (see DesignGuard::outsideTheScale()'s header).
|
||||||
|
$violations = DesignGuard::scan(realpath(GUARD_FIXTURES.'/scale/motion.js'))->violations();
|
||||||
|
|
||||||
|
expect($violations)->toBe([]);
|
||||||
|
});
|
||||||
|
|
||||||
it('finds a colour written as a value', function () {
|
it('finds a colour written as a value', function () {
|
||||||
expect(fixtureRelative(DesignGuard::scan(realpath(GUARD_FIXTURES.'/colour'))->violations()))->toBe([
|
expect(fixtureRelative(DesignGuard::scan(realpath(GUARD_FIXTURES.'/colour'))->violations()))->toBe([
|
||||||
'colour/badge.blade.php:1 arbitrary colour `bg-[#1d7afc]`, use an M3 role',
|
'colour/badge.blade.php:1 arbitrary colour `bg-[#1d7afc]`, use an M3 role',
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
// A plain CSS keyword read out of an API, not a Tailwind class: matches DesignGuard's easing and
|
||||||
|
// duration families only in a class list, never a bare JS string like this one.
|
||||||
|
const easing = matchMedia('(prefers-reduced-motion: reduce)').matches ? 'linear' : 'ease-out';
|
||||||
|
const duration = matchMedia('(prefers-reduced-motion: reduce)').matches ? 0 : 300;
|
||||||
Reference in New Issue
Block a user