Draw the progress indicator without Tailwind

Plan step 36 (actions). <x-progress> renders data-md-progress with
data-md-color and data-md-circular/-wavy/-thick, and
data-md-value/-max in place of data-value/data-max; no class list.
progress.css draws LinearProgressIndicatorTokens and
CircularProgressIndicatorTokens' stroke, sizes and colours, and the
linear indicator's unconditional right-to-left mirror. Its sizing is
a default only, same as loading.css: a caller's own class, unlayered
or in Tailwind's utilities layer, still outranks it, so the width/
size detection regex the view carried is gone with it.

resources/js/progress.js's WATCHED array and its reads follow the
renamed hooks. ProgressTest (Feature and Browser) is rewritten on the
hooks and ComponentStylesheet.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
Andreas Reinhold / reini
2026-09-14 16:46:52 +02:00
co-authored by Claude Opus 5
parent ce8ac4d316
commit 15cd306aba
7 changed files with 211 additions and 99 deletions
+113
View File
@@ -0,0 +1,113 @@
/*
* <x-progress>: M3 Expressive's progress indicator, drawn on the server for its first frame and
* frame by frame in the browser after.
*
* ProgressIndicatorTokens, LinearProgressIndicatorTokens, CircularProgressIndicatorTokens (androidx
* Compose Material 3, Apache-2.0): 4px stroke (`data-md-thick` 8px), linear 4px tall (8px thick,
* 10px `data-md-wavy`, 14px wavy thick — the container grows by the extra stroke, keeping the
* wave's own height put), circular 40px (44px thick, 48px wavy, 52px wavy thick). `data-md-color`
* is the active indicator's `color` and the track's `stroke`; the track is secondary-container for
* primary and secondary, and the colour's own container otherwise.
*
* Linear mirrors in a right-to-left document unconditionally — M3's own rule for this indicator,
* not the `mirror-rtl` a caller opts an icon into. The sizing here is a default only: an
* application's own class, unlayered or in Tailwind's `utilities` layer, always outranks
* `material.components`, so `w-*`/`size-*` still narrows or grows the indicator exactly as it did
* before this file existed.
*
* resources/js/progress.js reads and writes `data-md-value`, `data-md-max`, `data-md-circular`,
* `data-md-wavy` and `data-md-thick` — ProgressIndicator.kt, WavyProgressIndicator.kt and its
* Linear/CircularWavyProgressModifiers, ported at commit 27cf9a7d5788aa0f5f2d8b6699ce279560daf326
* — and draws every frame straight onto the SVG's own attributes; nothing here reads a class or
* runs a transition.
*/
@layer material.reset, material.tokens, material.base, material.layout, material.components, material.text, material.visibility;
@layer material.components {
[data-md-progress] {
color: var(--md-sys-color-primary);
stroke: var(--md-sys-color-secondary-container);
& > svg {
display: block;
width: 100%;
height: 100%;
}
}
[data-md-progress]:not([data-md-circular]) {
display: block;
width: 100%;
height: 4px;
}
[data-md-progress]:not([data-md-circular]):dir(rtl) {
rotate: 180deg;
}
[data-md-progress]:not([data-md-circular])[data-md-thick] {
height: 8px;
}
[data-md-progress]:not([data-md-circular])[data-md-wavy] {
height: 10px;
}
[data-md-progress]:not([data-md-circular])[data-md-wavy][data-md-thick] {
height: 14px;
}
[data-md-progress][data-md-circular] {
display: inline-block;
flex-shrink: 0;
vertical-align: middle;
width: 40px;
height: 40px;
}
[data-md-progress][data-md-circular][data-md-thick] {
width: 44px;
height: 44px;
}
[data-md-progress][data-md-circular][data-md-wavy] {
width: 48px;
height: 48px;
}
[data-md-progress][data-md-circular][data-md-wavy][data-md-thick] {
width: 52px;
height: 52px;
}
[data-md-progress][data-md-color='secondary'] {
color: var(--md-sys-color-secondary);
stroke: var(--md-sys-color-secondary-container);
}
[data-md-progress][data-md-color='tertiary'] {
color: var(--md-sys-color-tertiary);
stroke: var(--md-sys-color-tertiary-container);
}
[data-md-progress][data-md-color='error'] {
color: var(--md-sys-color-error);
stroke: var(--md-sys-color-error-container);
}
[data-md-progress][data-md-color='success'] {
color: var(--md-sys-color-success);
stroke: var(--md-sys-color-success-container);
}
[data-md-progress][data-md-color='warning'] {
color: var(--md-sys-color-warning);
stroke: var(--md-sys-color-warning-container);
}
[data-md-progress][data-md-color='info'] {
color: var(--md-sys-color-info);
stroke: var(--md-sys-color-info-container);
}
}