docs: add 100% framework coverage test pages - #253
Conversation
Add a six-page manual cross-browser test suite under docs/: - 1-colors: brand/status/surface colours, every variant ladder, palette 50-950 + alpha scales, gradients, scoped themes - 2-typography: type scale, weights, stacks, leading, tracking, spacing, shadows, radius, borders, blur/opacity, motion tokens, z-index, perspective, ratios - 3-layout: all 120 layout-primitive classes and modifiers - 4-macros-states: all 35 macros, 40 state classes, 3 a11y helpers, 15 motion classes - 5-forms-features: classless forms, container queries, scroll-driven entrances, colour functions, focus ring, layers, print, high contrast - 6-token-reference: live getComputedStyle dump of all 823 tokens Loads only the full variant via jsDelivr CDN plus an inline block that overrides 11 source colour tokens, so auto colour generation can be verified. Fully self-contained: no external JS, fonts, or images. Coverage: 214/214 classes, 823/823 tokens. Co-authored-by: Jack Granatowski <contact@codeslash.net>
|
Warning Review limit reached
More reviews will be available in 30 minutes. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
📝 WalkthroughWalkthroughThis PR adds six comprehensive static HTML documentation pages and an interactive token reference to the ChangesSLASHED Design System Coverage Documentation
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 11
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/test-coverage-1-colors.html`:
- Around line 447-455: Normalize persisted theme values by validating
localStorage.sfTheme before applying: in the apply/init logic
(functions/variables: apply, root, btn, localStorage.sfTheme) only accept
'light' or 'dark' and fallback to a safe default (e.g., 'light') when the stored
value is anything else or missing; ensure the same validation is used both when
initially reading localStorage (the try that calls apply(localStorage.sfTheme))
and when computing the next theme on btn click so root.dataset.theme and
btn.textContent always stay in sync.
- Line 9: Replace the mutable CDN href in the <link> tag with a pinned release
(specific tag or commit SHA) and add an integrity and crossorigin attribute to
enable SRI; then sanitize and whitelist the theme before applying it by reading
localStorage.sfTheme, checking it against allowed values ("light","dark"), and
only setting document.documentElement.dataset.theme when valid (otherwise fall
back to a known default) so unexpected values cannot desync the UI or bypass
core/themes.css styling.
In `@docs/test-coverage-2-typography.html`:
- Around line 347-363: Replace the non-form demo rows that use <label
class="demo-space-row"> with neutral container elements: change those <label
class="demo-space-row"> wrappers (the ones containing <span
class="demo-space-label"> and <span class="demo-tile demo-dur">, e.g. rows for
duration-instant, duration-fast, and the Easings (hover to move) rows like
ease-linear, ease-in, etc.) to <div class="demo-space-row"> while keeping all
inner spans, classes, inline style attributes and behavior unchanged so the
layout and hover motion remain identical.
- Around line 427-436: The code reapplies any stored localStorage.sfTheme value
without validation; update the startup logic so before calling
apply(localStorage.sfTheme) you check the stored value is exactly 'light' or
'dark' (the supported contract) and only then call apply; otherwise ignore it or
fall back to a default (e.g., 'light'). Specifically modify the block that reads
localStorage.sfTheme (the try that currently calls apply(localStorage.sfTheme))
to perform this validation, leaving the apply(t) function and the
btn.addEventListener flip logic unchanged.
In `@docs/test-coverage-3-layout.html`:
- Around line 390-399: Toggle logic treats current theme only as
root.dataset.theme, which fails when OS dark mode is active but no data-theme is
set; update the click handler to compute the current theme by checking
root.dataset.theme first and, if falsy, falling back to the user preference via
window.matchMedia('(prefers-color-scheme: dark)').matches (so use 'dark' when
that matches, otherwise 'light'), then derive next as the opposite and call
apply(next); reference the apply function, the btn.addEventListener click
handler, and the root.dataset.theme variable when making the change.
In `@docs/test-coverage-4-macros-states.html`:
- Around line 366-371: The persisted theme value from localStorage.sfTheme is
used without validation; update the logic around function apply and the initial
try that reads localStorage.sfTheme to only accept known themes (e.g., 'dark'
and 'light') before calling apply or setting root.dataset.theme; also ensure
apply only writes a validated value to localStorage.sfTheme and updates
btn.textContent accordingly so invalid values are rejected and a safe default is
used.
- Line 8: The stylesheet reference is using the mutable jsDelivr tag "`@dist`" and
lacks SRI; update the link element that currently points to
"https://cdn.jsdelivr.net/gh/codeslash-dev/SLASHED@dist/slashed.full.css" to
point to an immutable release (replace "`@dist`" with a specific version tag or
commit SHA) and add a matching integrity="sha384-..." attribute plus
crossorigin="anonymous"; ensure the integrity hash is computed from the exact
file you pin (or host the file locally and reference it with an integrity/hash
and crossorigin attribute).
In `@docs/test-coverage-5-forms-features.html`:
- Around line 126-131: Move the validation state classes from the wrapper divs
to the actual form controls: apply
.is-valid/.is-invalid/.is-error/.is-warning/.is-success/.is-info to the <input>
elements (not the container divs) in the examples and keep wrapper modifiers
(e.g., sf-stack sf-stack--xs) on the div; for invalid states add
aria-invalid="true" on the corresponding <input> and for any helper/error text
wire up aria-describedby on the input to the associated <span
class="form-helper"> or <span class="form-error"> id so assistive tech can
announce the message (ensure each span has a unique id referenced by the input).
In `@docs/test-coverage-6-token-reference.html`:
- Line 77: The theme toggle button with id "theme-toggle" does not expose its
state to assistive tech; set an initial aria-pressed value (true/false) on the
element and update that attribute whenever the theme toggle handler (the click
listener for element "theme-toggle") runs so aria-pressed reflects the current
on/off state; also ensure any theme-initialization code sets aria-pressed to
match the starting theme.
- Around line 100-103: The toggle currently reads theme only from
root.dataset.theme so if no data-theme is set (OS-level dark via
prefers-color-scheme) the first click can incorrectly reapply dark; change the
logic inside btn.addEventListener to compute the current effective theme by
checking root.dataset.theme and falling back to
window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light',
then set next to the opposite and call apply(next) (still using
document.startViewTransition when available); update references in the handler
for root.dataset.theme, btn.addEventListener, apply, and
document.startViewTransition accordingly.
- Around line 93-99: The startup restore may call apply() (which calls render())
before TOKENS, grid, and filter are initialized causing render() to access
filter.value and throw; fix by ensuring the saved theme is applied only after
initialization by moving the startup call "if (localStorage.sfTheme)
apply(localStorage.sfTheme)" to after TOKENS/grid/filter are set up or by
guarding inside apply()/render() to no-op if filter is not yet initialized
(check for existence of TOKENS/filter/grid before accessing filter.value) so
render() is safe during early startup.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 74e3601c-a773-4abb-8300-bb2f7377904f
📒 Files selected for processing (6)
docs/test-coverage-1-colors.htmldocs/test-coverage-2-typography.htmldocs/test-coverage-3-layout.htmldocs/test-coverage-4-macros-states.htmldocs/test-coverage-5-forms-features.htmldocs/test-coverage-6-token-reference.html
| <title>SLASHED Coverage 1 — Colors & Theming</title> | ||
|
|
||
| <!-- Full framework variant via CDN --> | ||
| <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/codeslash-dev/SLASHED@dist/slashed.full.css"> |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate the target file and print relevant sections with line numbers
FILE="docs/test-coverage-1-colors.html"
if [ ! -f "$FILE" ]; then
echo "Missing $FILE" >&2
exit 1
fi
echo "=== CDN link in $FILE ==="
rg -n "<link[^>]+slashed\.full\.css" "$FILE" || true
rg -n "localStorage\.sfTheme|dataset\.theme|startViewTransition" "$FILE" || true
echo
echo "=== Theme toggle block (around matches) ==="
# Print a reasonable window around the theme toggle code
rg -n "localStorage\.sfTheme" "$FILE" | head -n 5 | while read -r lnum _; do
start=$((lnum-25))
end=$((lnum+25))
sed -n "${start},${end}p" "$FILE" | nl -ba -w2 -s': '
done
echo
echo "=== Any existing validation/sanitization of sfTheme? ==="
# Pull the script section for any theme logic
rg -n "sfTheme|data-theme" "$FILE" -n --context 2 --no-heading || trueRepository: codeslash-dev/SLASHED
Length of output: 722
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="docs/test-coverage-1-colors.html"
echo "=== CDN link in $FILE ==="
sed -n '1,30p' "$FILE" | rg -n "<link[^>]+slashed\.full\.css" || true
rg -n "cdn\.jsdelivr\.net/gh/codeslash-dev/SLASHED@dist/slashed\.full\.css" "$FILE" || true
echo
echo "=== Theme toggle / apply() implementation ==="
sed -n '410,480p' "$FILE" | nl -ba -w3 -s': '
echo
echo "=== Search for any validation of sfTheme/localStorage values ==="
rg -n "sfTheme|dataset\.theme|apply\(" "$FILE" -n --context 1 --no-heading || trueRepository: codeslash-dev/SLASHED
Length of output: 441
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="docs/test-coverage-1-colors.html"
echo "=== Theme toggle / apply() implementation (lines 410-480) ==="
sed -n '410,480p' "$FILE" | cat -n -w3 -s': ' - > /tmp/theme_block.txt
head -n 120 /tmp/theme_block.txt
echo
echo "=== Any validation around sfTheme/localStorage? (search hits) ==="
rg -n --context 2 "sfTheme|dataset\.theme|apply\(" "$FILE" || true
echo
echo "=== CDN link in $FILE ==="
rg -n "<link[^>]+slashed\.full\.css" "$FILE" || trueRepository: codeslash-dev/SLASHED
Length of output: 211
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="docs/test-coverage-1-colors.html"
echo "=== Basic file info ==="
ls -l "$FILE" || exit 1
wc -l "$FILE"
echo
echo "=== CDN link ==="
sed -n '1,40p' "$FILE" | rg -n "<link[^>]+slashed\.full\.css" || true
echo
echo "=== Theme toggle matches (sfTheme/localStorage/dataset.theme) ==="
matches=$(rg -n "localStorage\.sfTheme|dataset\.theme|data-theme" "$FILE" || true)
echo "$matches"
# show ~60 lines around each match line
echo
echo "=== Theme code context ==="
echo "$matches" | while IFS=: read -r lnum rest; do
start=$((lnum>60 ? lnum-60 : 1))
end=$((lnum+120))
echo "--- context around line $lnum (showing $start-$end) ---"
sed -n "${start},${end}p" "$FILE" | sed -n '1,200p'
doneRepository: codeslash-dev/SLASHED
Length of output: 50377
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Find likely theme contract file(s)
fd -t f -a "themes.css" . | head -n 20 || true
fd -t f -a "theme*.css" . | head -n 20 || true
echo
echo "=== Search for [data-theme] contract ==="
rg -n "\\[data-theme(=|\\])" -S . -g'*.css' -g'*.html' -g'*.ts' -g'*.js' 2>/dev/null || true
echo
echo "=== Search explicitly for data-theme=\"dark\"/\"light\" ==="
rg -n "data-theme\\s*=\\s*\"(dark|light)\"" -S . -g'*.css' -g'*.html' 2>/dev/null || trueRepository: codeslash-dev/SLASHED
Length of output: 13483
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="docs/test-coverage-1-colors.html"
echo "=== Find theme-toggle element ==="
rg -n "id=[\"']theme-toggle[\"']" "$FILE" || true
echo
echo "=== Find any other dataset.theme manipulation ==="
rg -n "dataset\\.theme\\s*=" "$FILE" || trueRepository: codeslash-dev/SLASHED
Length of output: 328
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE="core/themes.css"
echo "=== core/themes.css data-theme rules (relevant section) ==="
# Print the area containing the explicit light/dark selectors and defaults
sed -n '1,120p' "$FILE" | cat -n
echo
echo "=== theme-transition / default handling region ==="
sed -n '120,240p' "$FILE" | cat -nRepository: codeslash-dev/SLASHED
Length of output: 15564
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== core/reset.css: look for --sf-is-dark / color-scheme defaults ==="
sed -n '1,220p' core/reset.css | rg -n "--sf-is-dark|color-scheme|data-theme" || true
echo
echo "=== core/tokens.css: look for --sf-is-dark usage ==="
sed -n '1,260p' core/tokens.css | rg -n "--sf-is-dark|light-dark\\(|data-theme|prefers-color-scheme" || true
echo
echo "=== core/tokens.css: broader search for --sf-is-dark references ==="
rg -n "--sf-is-dark" core/tokens.css core/reset.css core/themes.cssRepository: codeslash-dev/SLASHED
Length of output: 1590
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== core/reset.css: look for --sf-is-dark / color-scheme defaults ==="
rg -n -- '--sf-is-dark|color-scheme|data-theme' core/reset.css || true
rg -n -- 'prefers-color-scheme' core/reset.css || true
echo
echo "=== core/tokens.css: look for uses of --sf-is-dark ==="
rg -n -- '--sf-is-dark' core/tokens.css || true
rg -n -- 'light-dark\(|color-scheme|data-theme' core/tokens.css || true
echo
echo "=== core/themes.css: confirm default selection logic when :root has data-theme but not light/dark ==="
rg -n -- ':root:not\(\[data-theme\]\)|data-theme="light"|data-theme="dark"' core/themes.cssRepository: codeslash-dev/SLASHED
Length of output: 5007
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n -- "var\\(--sf-is-dark\\)|--sf-is-dark\\)" core/tokens.css core/themes.css core/reset.cssRepository: codeslash-dev/SLASHED
Length of output: 152
🏁 Script executed:
#!/bin/bash
set -euo pipefail
sed -n '1,120p' core/reset.css | cat -n -w3 -s': ' || true
echo
sed -n '140,230p' core/tokens.css | cat -n -w3 -s': ' || trueRepository: codeslash-dev/SLASHED
Length of output: 216
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== core/reset.css (top) ==="
sed -n '1,140p' core/reset.css | cat -n
echo
echo "=== core/tokens.css (around --sf-color-scheme) ==="
# Find the line range containing --sf-color-scheme and print a window
ln=$(rg -n -- "--sf-color-scheme" core/tokens.css | head -n 1 | cut -d: -f1)
start=$((ln>80 ? ln-60 : 1))
end=$((ln+120))
sed -n "${start},${end}p" core/tokens.css | cat -nRepository: codeslash-dev/SLASHED
Length of output: 17625
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n -- "sf-shadow-strength" core/tokens.css core/themes.css core/reset.cssRepository: codeslash-dev/SLASHED
Length of output: 3851
Pin the CDN stylesheet to an immutable version (optionally with SRI) and validate localStorage.sfTheme before applying it to data-theme.
docs/test-coverage-1-colors.htmlline 9 loadshttps://cdn.jsdelivr.net/.../@dist/...(mutable/unpinned) with nointegrity; pin to a specific release tag/commit SHA and addintegrity/crossoriginwhere possible.- The theme script applies
localStorage.sfThemedirectly todocumentElement.dataset.theme(no whitelist).core/themes.cssonly defines behavior fordata-theme="light"/"dark", so unexpected values can desync the toggle label and skip the explicit theme styling path.
Suggested change
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/codeslash-dev/SLASHED@dist/slashed.full.css">
+ <link
+ rel="stylesheet"
+ href="https://cdn.jsdelivr.net/gh/codeslash-dev/SLASHED@<immutable-tag-or-sha>/slashed.full.css"
+ integrity="<SRI_HASH>"
+ crossorigin="anonymous"
+ >🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/test-coverage-1-colors.html` at line 9, Replace the mutable CDN href in
the <link> tag with a pinned release (specific tag or commit SHA) and add an
integrity and crossorigin attribute to enable SRI; then sanitize and whitelist
the theme before applying it by reading localStorage.sfTheme, checking it
against allowed values ("light","dark"), and only setting
document.documentElement.dataset.theme when valid (otherwise fall back to a
known default) so unexpected values cannot desync the UI or bypass
core/themes.css styling.
| <div class="is-valid sf-stack sf-stack--xs"><label>Valid field<input type="text" value="looks good"></label><span class="form-helper">Field accepted</span></div> | ||
| <div class="is-invalid sf-stack sf-stack--xs"><label>Invalid field<input type="text" value="bad value" aria-invalid="true"></label><span class="form-error">Please correct this</span></div> | ||
| <div class="is-error sf-stack sf-stack--xs"><label>Error field<input type="text" value="error"></label><span class="form-error">Something went wrong</span></div> | ||
| <div class="is-warning sf-stack sf-stack--xs"><label>Warning field<input type="text" value="careful"></label><span class="form-helper">Double-check this</span></div> | ||
| <div class="is-success sf-stack sf-stack--xs"><label>Success field<input type="text" value="saved"></label><span class="form-helper">Saved</span></div> | ||
| <div class="is-info sf-stack sf-stack--xs"><label>Info field<input type="text" value="note"></label><span class="form-helper">For your information</span></div> |
There was a problem hiding this comment.
Apply validation state classes/ARIA on the form controls, not only wrappers.
This demo currently puts .is-valid/.is-invalid on container <div> elements, which under-covers the intended field-level validation contract and semantics. Move field-validation classes to the <input>s and include explicit ARIA state for the showcased valid/invalid examples.
Suggested adjustment
- <div class="is-valid sf-stack sf-stack--xs"><label>Valid field<input type="text" value="looks good"></label><span class="form-helper">Field accepted</span></div>
- <div class="is-invalid sf-stack sf-stack--xs"><label>Invalid field<input type="text" value="bad value" aria-invalid="true"></label><span class="form-error">Please correct this</span></div>
+ <div class="sf-stack sf-stack--xs"><label>Valid field<input class="is-valid" type="text" value="looks good" aria-invalid="false"></label><span class="form-helper">Field accepted</span></div>
+ <div class="sf-stack sf-stack--xs"><label>Invalid field<input class="is-invalid" type="text" value="bad value" aria-invalid="true"></label><span class="form-error">Please correct this</span></div>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/test-coverage-5-forms-features.html` around lines 126 - 131, Move the
validation state classes from the wrapper divs to the actual form controls:
apply .is-valid/.is-invalid/.is-error/.is-warning/.is-success/.is-info to the
<input> elements (not the container divs) in the examples and keep wrapper
modifiers (e.g., sf-stack sf-stack--xs) on the div; for invalid states add
aria-invalid="true" on the corresponding <input> and for any helper/error text
wire up aria-describedby on the input to the associated <span
class="form-helper"> or <span class="form-error"> id so assistive tech can
announce the message (ensure each span has a unique id referenced by the input).
- Harden theme toggle across all 6 pages:
- validate persisted localStorage.sfTheme (only light/dark applied)
- derive current theme from prefers-color-scheme when no data-theme
is set, so the first click toggles correctly for OS-dark users
- expose state via aria-pressed on the toggle button
- Fix page 6 startup crash: apply() could call render() before
TOKENS/grid/filter were initialized; restore now runs after setup
and render() is guarded
- Page 2: use <div> instead of <label> for non-form motion demo rows
Skipped (with reason): CDN SRI/version pinning (intentionally tracks the
live full variant for ongoing testing) and moving form .is-* validation
classes onto inputs (the framework contract places them on a wrapper so
the inherited --sf-field-* tokens cascade).
This pull request was created by @kiro-agent on behalf of @jackgranatowski 👻
Comment with /kiro fix to address specific feedback or /kiro all to address everything.
Learn about Kiro Web
Summary
Adds a six-page manual cross-browser test suite under
docs/, designed to exercise 100% of the framework in action. Loads only the full variant via the jsDelivr CDN plus an inline<style>that overrides 11 source colour tokens (6 brand + 5 status), so auto colour generation (tints, shades, dark-mode, on-colours, borders, links, surfaces) can be verified visually.Pages
50–950+ alphaa5–a95, gradients, on-colour text, borders, links, nested scoped themes (data-theme)..is-*state classes, 3 accessibility helpers, all 15 motion classes (+ replay button).light-dark()/ relative colour /color-mix(), selection & scrollbar, focus ring, cascade layers &@property, print, high contrast.getComputedStyledump of all 823 tokens with colour swatches and a name filter.Coverage
Constraints honoured
Testing
Verified via scripted checks that every class from
docs/classes.mdand every token fromdocs/tokens.mdappears, that no<script src>or non-CDN external resources are present, and that each document is structurally balanced. Open each page locally and use the browser theme toggle / Print Preview / OS reduced-motion & contrast settings to test behaviours manually.Summary by CodeRabbit