Take Tailwind out of the package, and its detection out of the guard
tests / feature (8.4) (push) Successful in 2m0s
tests / feature (8.5) (push) Successful in 2m0s
tests / browser (chrome, chromium) (push) Failing after 8m3s
tests / browser (firefox, firefox) (push) Failing after 12m58s
tests / browser (safari, webkit) (push) Failing after 13m8s
tests / feature (8.4) (push) Successful in 2m0s
tests / feature (8.5) (push) Successful in 2m0s
tests / browser (chrome, chromium) (push) Failing after 8m3s
tests / browser (firefox, firefox) (push) Failing after 12m58s
tests / browser (safari, webkit) (push) Failing after 13m8s
Tailwind left the stack in 2.0.0, but the package still carried about 330 mentions of it. What the guard's Tailwind detection protected — a class that compiles to nothing — is now protected by a check that does not care where a dead class came from. DesignGuard: about 500 lines of Tailwind tables, scales, palettes and "2.0.0 replacement" hints give way to one check — a class a view or PHP file writes that neither the application's stylesheets nor the package's own declare. It catches a utility of any framework, a typo and a class whose rules were deleted alike, so it also found two classes ReStride draws nothing with. A stylesheet has to be in reach for it: the `.css` files among the scanned paths, or what the `missingStylesheets()` entry imports. The class reader no longer mistakes an array index for a class list (`$block['base']`), and it reads the array a class helper is given, where it read nothing before. The package's own three Tailwind self-guards go with it. Only their one unique check stays, as a test of its own: every `matchMedia` width in resources/js is an M3 breakpoint. The pagination views are `material.blade.php` and `simple-material.blade.php`; only Laravel's and Livewire's default theme names ever made them `tailwind`. The provider sets `Paginator`'s default views and switches `livewire.pagination_theme` to `material` when it is still Livewire's own default, so no application can forget the config; a theme an application chose, and a component's own `$paginationTheme` or `paginationView()`, still win. The rest is prose: the layer-order guidance for an application that still builds Tailwind, the Tailwind wording in the README, the Boost guidelines and the development skill, and about 25 "this used to be a Tailwind utility" comments, along with every "plan step NN" pointer into a gitignored folder. The reset keeps its credit, and NOTICE now carries it too. Feature suite 1159 passed, Chrome browser suite 299 passed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
247c596c3a
commit
fb7007c976
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* An application's own CSS entry, the way plan step 37's claim is about: outside the package, the
|
||||
* foundation first, then the stylesheet of each component its views render. Split button, app bar,
|
||||
* modal and pagination each import button.css (and icon.css, through it), and the application
|
||||
* names button.css itself once more at the end. Built by tests/Fixtures/dedup.vite.config.mjs for
|
||||
* StylesheetsBundleTest.php, which expects every shared rule once, at its first position.
|
||||
* An application's own CSS entry: outside the package, the foundation first, then the stylesheet
|
||||
* of each component its views render. Split button, app bar, modal and pagination each import
|
||||
* button.css (and icon.css, through it), and the application names button.css itself once more
|
||||
* at the end. Built by tests/Fixtures/dedup.vite.config.mjs for StylesheetsBundleTest.php, which
|
||||
* expects every shared rule once, at its first position.
|
||||
*/
|
||||
|
||||
@import '../../resources/css/foundation.css';
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
import { defineConfig } from 'vite';
|
||||
|
||||
// Builds two CSS entries with no plugin in the graph, isolating Vite's own bundled postcss-import,
|
||||
// whose `skipDuplicates` option is the mechanism docs/plans/material-3-alignment.md's "Tailwind's
|
||||
// footprint" paragraph measured and StylesheetsBundleTest.php pins: resources/css/all.css, and
|
||||
// tests/Fixtures/dedup-app.css, an application-shaped entry importing per-component stylesheets
|
||||
// that share button.css. A stylesheet several files import lands once per entry, at its first
|
||||
// position.
|
||||
// whose `skipDuplicates` option is the deduplication StylesheetsBundleTest.php pins:
|
||||
// resources/css/all.css, and tests/Fixtures/dedup-app.css, an application-shaped entry importing
|
||||
// per-component stylesheets that share button.css. A stylesheet several files import lands once
|
||||
// per entry, at its first position.
|
||||
//
|
||||
// Not the Workbench's config: `@tailwindcss/vite` inlines the imports of any entry that uses
|
||||
// Tailwind itself, without that deduplication, so a shared stylesheet repeats there. The Workbench
|
||||
// keeps the package's CSS in an entry of its own (workbench/resources/css/package.css) for that
|
||||
// reason, until plan step 39 removes Tailwind.
|
||||
// Not the Workbench's config: this one carries no plugin, which is what isolates Vite's own
|
||||
// postcss-import above. The Workbench's config carries laravel-vite-plugin, so its build is not
|
||||
// this dedup test's to run.
|
||||
//
|
||||
// DEDUP_OUT_DIR is required: the test builds into a temporary directory and deletes it, and nothing
|
||||
// should land in the package's own tree, least of all workbench/public/build.
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
<div class="sm:flex md:grid lg:hidden xl:block 2xl:contents">
|
||||
<span class="max-sm:hidden max-md:flex max-lg:grid max-xl:block max-2xl:contents"></span>
|
||||
</div>
|
||||
@@ -1,6 +0,0 @@
|
||||
<div class="bg-[#1d7afc] text-[rgb(0_0_0)] border-[hsl(210_80%_50%)]">
|
||||
<span class="fill-[oklch(0.7_0.1_250)] ring-[color-mix(in_oklab,var(--x)_50%,transparent)]"></span>
|
||||
<span class="bg-white text-black border-white"></span>
|
||||
<span class="text-on-surface/60 bg-on-surface/12 border-outline/38"></span>
|
||||
<span class="md-ink md-type-body-md">M3's own are fine</span>
|
||||
</div>
|
||||
+4
@@ -5,3 +5,7 @@
|
||||
.bg-brand {
|
||||
background: var(--brand);
|
||||
}
|
||||
|
||||
.dashboard-hero {
|
||||
padding: var(--md-sys-measurement-space200);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<div x-data="{ view: 'grid' }" :class="{ 'is-open': open, collapsed: !open, 'md-ink': view === 'grid' }" wire:loading.class="dashboard-busy"
|
||||
x-transition:enter="dashboard-enter" x-transition:enter-start="dashboard-enter-start">
|
||||
<ul @class(['dashboard-hero', 'share-list', 'md-ink-quiet' => $status === 'hidden', 'md-ink' => isActive('block')])
|
||||
{{ $attributes->merge(['class' => 'dashboard-lead']) }}>
|
||||
<li class="md-truncate
|
||||
share-list">Row</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -0,0 +1,10 @@
|
||||
{{-- Real application lines: a quoted string that is an array index ($block['base'],
|
||||
$header['class'], $tab['iconClass']) reads a value, not a class list. The keys around it and
|
||||
both branches of a ternary are classes, and are read. --}}
|
||||
<div @class(['product-shot-base' => $block['base']])></div>
|
||||
<x-sort-header :sort-by="$sortBy" :column="$header['key']" :class="$header['class'] ?? null" />
|
||||
<x-icon :name="$tab['icon']" size="20" :class="$tab['iconClass']" />
|
||||
<x-row :class="$band['easy'] ? 'md-type-title-sm' : 'md-type-body-md'" />
|
||||
<div @class(['routes-show-run-chosen' => $referenceRunId === $run['id']])></div>
|
||||
<x-badge :class="\Illuminate\Support\Arr::toCssClasses(['shot-helper-one', 'shot-helper-two' => $on])" />
|
||||
<span :class="$on ? 'shot-tern-a' : ($off ? 'shot-tern-b' : 'shot-tern-c')"></span>
|
||||
@@ -0,0 +1 @@
|
||||
<p class="md-type-title-md md-ink-variant showcase-w-narrow">Every one of these is a package rule.</p>
|
||||
@@ -1,4 +0,0 @@
|
||||
{{-- Running text is not a class list: none of Tailwind's bare-word utilities should be read out
|
||||
of prose just because they share a spelling with one. --}}
|
||||
<p>This creates a grid of cards, in a flex layout that stays hidden below medium and stacks into a
|
||||
block once the pane narrows. Nothing here truncates or grows, and the sample is not a table.</p>
|
||||
@@ -1,5 +0,0 @@
|
||||
<div class="rounded-none rounded-xs rounded-sm rounded-md rounded-lg">
|
||||
<span class="rounded-xl rounded-2xl rounded-3xl rounded-4xl rounded-full"></span>
|
||||
<span class="rounded-t-lg rounded-se-2xl"></span>
|
||||
<span class="md-type-body-md" style="border-radius: var(--md-sys-shape-corner-lg)">M3's own are fine</span>
|
||||
</div>
|
||||
@@ -1,4 +0,0 @@
|
||||
<div class="shadow-2xs shadow-xs shadow-sm shadow-md">
|
||||
<span class="shadow-lg shadow-xl shadow-2xl"></span>
|
||||
<span class="md-type-body-md" style="box-shadow: var(--md-sys-elevation-1)">M3's own are fine</span>
|
||||
</div>
|
||||
@@ -1,4 +0,0 @@
|
||||
<div class="ease-linear ease-in ease-out ease-in-out">
|
||||
<span class="duration-75 duration-300 duration-1000"></span>
|
||||
<span class="md-type-body-md">M3's own are fine</span>
|
||||
</div>
|
||||
@@ -1,4 +0,0 @@
|
||||
// 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;
|
||||
@@ -1,7 +0,0 @@
|
||||
<div class="text-xs text-sm text-base text-lg text-xl text-2xl text-9xl">
|
||||
<span class="font-thin font-extralight font-light font-normal font-medium"></span>
|
||||
<span class="font-semibold font-bold font-extrabold font-black"></span>
|
||||
<span class="leading-none leading-tight leading-snug leading-normal leading-relaxed leading-loose leading-6"></span>
|
||||
<span class="tracking-tighter tracking-tight tracking-normal tracking-wide tracking-wider tracking-widest"></span>
|
||||
<span class="md-type-body-md md-type-title-lg md-type-emphasized-label-lg">M3's own are fine</span>
|
||||
</div>
|
||||
@@ -1,4 +1,4 @@
|
||||
@import 'tailwindcss';
|
||||
@import '@fontsource/roboto';
|
||||
@import url('https://fonts.googleapis.com/css2?family=Roboto');
|
||||
@import './app-theme.css' layer(app);
|
||||
@import '../../../../resources/css/foundation.css';
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
<div class="top-[10px] grid-cols-[1fr_2fr]">
|
||||
<span class="flex!"></span>
|
||||
</div>
|
||||
<div class="[--material-bottom-bar:5rem] [font-variation-settings:'ROND'_100]"></div>
|
||||
@@ -1,8 +0,0 @@
|
||||
<div x-data="{ view: 'grid' }" :class="{ 'is-open': open, hidden: !open, 'md-ink': view === 'grid' }" wire:loading.class="opacity-50"
|
||||
x-transition:enter="transition ease-out" x-transition:enter-start="scale-95">
|
||||
<ul @class(["gap-2", 'share-list', 'md-ink-quiet' => $status === 'hidden', 'md-ink' => isActive('block')])
|
||||
{{ $attributes->merge(['class' => 'mt-2']) }}>
|
||||
<li class="md-truncate
|
||||
flex">Row</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -1 +0,0 @@
|
||||
<span class="duration-(--md-sys-motion-spatial-fast-duration)"></span>
|
||||
@@ -1,3 +0,0 @@
|
||||
<div class="hidden block">
|
||||
<span class="inline-block invisible"></span>
|
||||
</div>
|
||||
@@ -1 +0,0 @@
|
||||
<span class="text-on-primary-container bg-background text-current md-ink-variant"></span>
|
||||
@@ -1,3 +0,0 @@
|
||||
<div class="flex grid inline-flex flex-col">
|
||||
<span class="grid-cols-3 col-span-2 items-center justify-between gap-4"></span>
|
||||
</div>
|
||||
@@ -1,2 +0,0 @@
|
||||
<div class="text-on-surface-variant border-outline-variant"></div>
|
||||
<span class="bg-surface-container bg-primary"></span>
|
||||
@@ -1,3 +0,0 @@
|
||||
<div class="w-full h-screen min-w-0 max-w-md">
|
||||
<span class="size-4"></span>
|
||||
</div>
|
||||
@@ -1,3 +0,0 @@
|
||||
<div class="p-4 px-2 mt-2 space-y-4">
|
||||
<span class="m-4 space-x-2"></span>
|
||||
</div>
|
||||
@@ -1,3 +0,0 @@
|
||||
<p class="text-center truncate">
|
||||
<span class="sr-only whitespace-nowrap line-clamp-2 tabular-nums"></span>
|
||||
</p>
|
||||
@@ -1,8 +0,0 @@
|
||||
<div class="bg-off-plan text-sport-run from-brand to-brand-end text-brand-ink">
|
||||
<span class="border-route-reference bg-route-reference/8 border-l-zone-4 ring-offset-brand/[0.4]"></span>
|
||||
<p class="text-balance text-pretty text-wrap text-nowrap text-ellipsis text-clip"></p>
|
||||
<table class="border-collapse border-separate border-solid border-dashed border-dotted border-none"></table>
|
||||
<span class="shadow-none outline-none outline-dashed ring-inset decoration-wavy from-0% via-none"></span>
|
||||
<span class="bg-clip-text bg-fixed bg-cover bg-center bg-no-repeat bg-top-left text-inherit text-shadow-sm fill-none accent-auto"></span>
|
||||
<span class="bg-mauve-500 border-bs-2"></span>
|
||||
</div>
|
||||
@@ -1,4 +0,0 @@
|
||||
<div class="relative inset-0 -top-2 z-10 overflow-hidden shrink-0 col-start-2 justify-self-end container">
|
||||
<span class="border border-t-2 rounded shadow outline-none ring-2 transition opacity-50 -rotate-45 cursor-pointer select-none"></span>
|
||||
<span class="aspect-video object-cover font-mono font-sans antialiased underline uppercase text-end list-disc table bg-clip-text"></span>
|
||||
</div>
|
||||
@@ -1,3 +0,0 @@
|
||||
<div class="hover:underline dark:opacity-50">
|
||||
<span class="group-hover:flex focus:md:gap-2"></span>
|
||||
</div>
|
||||
@@ -3,7 +3,7 @@
|
||||
<x-icon name="o-home" />
|
||||
<x-button icon="calendar_month" icon-right="not_a_symbol" label="Fine" />
|
||||
<span>text-red-600</span>
|
||||
<p class="text-tertiary focus-ring">Tailwind's and ours</p>
|
||||
<p class="text-tertiary focus-ring">Classes no stylesheet declares</p>
|
||||
<x-icon :name="$dynamic" />
|
||||
<x-icon name="home" @class(['size-4']) />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user