Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "slashed",
"type": "module",
Comment thread
coderabbitai[bot] marked this conversation as resolved.
"version": "0.5.0-beta5",
"description": "CSS framework",
"style": "dist/slashed.full.css",
Expand Down
4 changes: 2 additions & 2 deletions playwright.config.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
const { defineConfig, devices } = require('@playwright/test');
import { defineConfig, devices } from '@playwright/test';

// Token + a11y regression suite. No dev server — fixtures load the built
// bundle / demo over file://. The framework leans on bleeding-edge CSS
// (oklch relative colour, @property inherits, light-dark()), all within the
// documented support floor for Chromium, Firefox, and WebKit — so the suite
// runs on all three.
module.exports = defineConfig({
export default defineConfig({
testDir: './tests',
fullyParallel: true,
reporter: 'list',
Expand Down
12 changes: 6 additions & 6 deletions plugins/SLASHED-for-WP/dist/slashed.essential.css
Original file line number Diff line number Diff line change
Expand Up @@ -3483,12 +3483,12 @@
neutralisation in accessibility.css if a consumer accidentally
writes them outside the gate.

Browser support — animation-timeline is shipping in Chrome 115+
and Firefox 145+ (expected Nov 2026, not yet released as of May 2026).
Safari does not yet support it
(tracked at WebKit bug 264057); on those engines the @supports
block below is skipped, so the rule falls back to a one-shot
time-driven animation playing once at --sf-duration-slow.
Browser support — animation-timeline ships in Chrome/Edge 115+.
Firefox keeps it behind a flag (the scroll-driven-animations
preference) and Safari has not shipped it (tracked at WebKit
bug 264057); on those engines the @supports block below is
skipped, so the rule falls back to a one-shot time-driven
animation playing once at --sf-duration-slow.
animation-duration is set unconditionally because without it
a non-supporting engine would default to 0s and snap to the
end state instantly — there'd be no visible entrance at all.
Expand Down
12 changes: 6 additions & 6 deletions plugins/SLASHED-for-WP/dist/slashed.full.css
Original file line number Diff line number Diff line change
Expand Up @@ -3483,12 +3483,12 @@
neutralisation in accessibility.css if a consumer accidentally
writes them outside the gate.

Browser support — animation-timeline is shipping in Chrome 115+
and Firefox 145+ (expected Nov 2026, not yet released as of May 2026).
Safari does not yet support it
(tracked at WebKit bug 264057); on those engines the @supports
block below is skipped, so the rule falls back to a one-shot
time-driven animation playing once at --sf-duration-slow.
Browser support — animation-timeline ships in Chrome/Edge 115+.
Firefox keeps it behind a flag (the scroll-driven-animations
preference) and Safari has not shipped it (tracked at WebKit
bug 264057); on those engines the @supports block below is
skipped, so the rule falls back to a one-shot time-driven
animation playing once at --sf-duration-slow.
animation-duration is set unconditionally because without it
a non-supporting engine would default to 0s and snap to the
end state instantly — there'd be no visible entrance at all.
Expand Down
12 changes: 6 additions & 6 deletions plugins/SLASHED-for-WP/dist/slashed.optimal.css
Original file line number Diff line number Diff line change
Expand Up @@ -3483,12 +3483,12 @@
neutralisation in accessibility.css if a consumer accidentally
writes them outside the gate.

Browser support — animation-timeline is shipping in Chrome 115+
and Firefox 145+ (expected Nov 2026, not yet released as of May 2026).
Safari does not yet support it
(tracked at WebKit bug 264057); on those engines the @supports
block below is skipped, so the rule falls back to a one-shot
time-driven animation playing once at --sf-duration-slow.
Browser support — animation-timeline ships in Chrome/Edge 115+.
Firefox keeps it behind a flag (the scroll-driven-animations
preference) and Safari has not shipped it (tracked at WebKit
bug 264057); on those engines the @supports block below is
skipped, so the rule falls back to a one-shot time-driven
animation playing once at --sf-duration-slow.
animation-duration is set unconditionally because without it
a non-supporting engine would default to 0s and snap to the
end state instantly — there'd be no visible entrance at all.
Expand Down
11 changes: 4 additions & 7 deletions scripts/audit.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,11 @@
* by the framework itself (warnings only)
*/

'use strict';
import fs from 'node:fs';
import path from 'node:path';
import { TOKEN_FILES, CLASS_FILES } from './registry-sources.js';

const fs = require('node:fs');
const path = require('node:path');

const ROOT = path.resolve(__dirname, '..');

const { TOKEN_FILES, CLASS_FILES } = require('./registry-sources');
const ROOT = path.resolve(import.meta.dirname, '..');

// All framework source files — token files + class files + everything else
// in core/ and optional/ — used for the unused-token cross-reference.
Expand Down
12 changes: 7 additions & 5 deletions scripts/bundle.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
#!/usr/bin/env node

const fs = require('fs');
const path = require('path');
const zlib = require('zlib');
import fs from 'node:fs';
import path from 'node:path';
import zlib from 'node:zlib';
import { createRequire } from 'node:module';

const ROOT = path.resolve(__dirname, '..');
const _require = createRequire(import.meta.url);
const ROOT = path.resolve(import.meta.dirname, '..');
const CONFIG_PATH = path.join(ROOT, 'bundle.config.json');

// lightningcss is a maintainer-only dev dependency. If it's missing (e.g. a
// consumer cloned without dev deps), skip minification rather than fail.
let lightningcss = null;
try { lightningcss = require('lightningcss'); } catch { /* optional */ }
try { lightningcss = _require('lightningcss'); } catch { /* optional */ }

function sizeReport(buf) {
const raw = buf.length;
Expand Down
10 changes: 4 additions & 6 deletions scripts/check-artifacts.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,11 @@
* To register a new build artifact, add an entry to scripts/artifacts.json.
*/

'use strict';
import { execSync, execFileSync } from 'node:child_process';
import { readFileSync } from 'node:fs';
import { resolve } from 'node:path';

const { execSync, execFileSync } = require('child_process');
const { readFileSync } = require('fs');
const { resolve } = require('path');

const root = resolve(__dirname, '..');
const root = resolve(import.meta.dirname, '..');
const artifacts = JSON.parse(readFileSync(resolve(root, 'scripts/artifacts.json'), 'utf8'));
const mode = process.argv.includes('--check') ? 'check' : 'fix';

Expand Down
8 changes: 3 additions & 5 deletions scripts/check-cheatsheet.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,10 @@
* Usage: node scripts/check-cheatsheet.js
*/

'use strict';
import fs from 'node:fs';
import path from 'node:path';

const fs = require('node:fs');
const path = require('node:path');

const ROOT = path.resolve(__dirname, '..');
const ROOT = path.resolve(import.meta.dirname, '..');
const INV = path.join(ROOT, 'plugins', 'SLASHED-for-WP', 'integrations', 'bricks', 'data', 'inventory.json');
const SHEET = path.join(ROOT, 'plugins', 'SLASHED-for-WP', 'integrations', 'bricks', 'admin-app', 'src', 'lib', 'cheatsheet-data.js');

Expand Down
11 changes: 4 additions & 7 deletions scripts/gen-bricks-inventory.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,13 @@
* node scripts/gen-bricks-inventory.js
*/

'use strict';
import fs from 'node:fs';
import path from 'node:path';
import { TOKEN_FILES, CLASS_FILES } from './registry-sources.js';

const fs = require('node:fs');
const path = require('node:path');

const ROOT = path.resolve(__dirname, '..');
const ROOT = path.resolve(import.meta.dirname, '..');
const OUT = path.join(ROOT, 'plugins', 'SLASHED-for-WP', 'integrations', 'bricks', 'data', 'inventory.json');

const { TOKEN_FILES, CLASS_FILES } = require('./registry-sources');

function stripComments(css) {
return css.replace(/\/\*[\s\S]*?\*\//g, '');
}
Expand Down
8 changes: 3 additions & 5 deletions scripts/gen-class-hints.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,10 @@
* node scripts/gen-class-hints.js --check — exit 1 if file is stale
*/

'use strict';
import fs from 'node:fs';
import path from 'node:path';

const fs = require('node:fs');
const path = require('node:path');

const ROOT = path.resolve(__dirname, '..');
const ROOT = path.resolve(import.meta.dirname, '..');
const OUT = path.join(ROOT, 'plugins', 'SLASHED-for-WP', 'data', 'classes-hints.json');

// Files to parse, in generation order. Must match FILE_META in gen-class-reference.js.
Expand Down
11 changes: 4 additions & 7 deletions scripts/gen-class-reference.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,11 @@
* The reference is derived from source so it never drifts.
*/

'use strict';
import fs from 'node:fs';
import path from 'node:path';
import { CLASS_FILES } from './registry-sources.js';

const fs = require('node:fs');
const path = require('node:path');

const ROOT = path.resolve(__dirname, '..');

const { CLASS_FILES } = require('./registry-sources');
const ROOT = path.resolve(import.meta.dirname, '..');

const FILE_META = {
'core/layout.css': { title: 'Layout primitives', prefix: 'sf-' },
Expand Down
11 changes: 4 additions & 7 deletions scripts/gen-token-reference.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@
/* Generates docs/tokens.md from the token source files. Run: npm run docs:tokens
The reference is derived from source so it never drifts. */

'use strict';
import fs from 'node:fs';
import path from 'node:path';
import { TOKEN_FILES } from './registry-sources.js';

const fs = require('fs');
const path = require('path');

const ROOT = path.resolve(__dirname, '..');

const { TOKEN_FILES } = require('./registry-sources');
const ROOT = path.resolve(import.meta.dirname, '..');

const FILE_TITLES = {
'core/tokens.css': 'Core tokens',
Expand Down
4 changes: 1 addition & 3 deletions scripts/registry-sources.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
'use strict';

/**
* Canonical source-file lists for the SLASHED registry.
*
Expand Down Expand Up @@ -34,4 +32,4 @@ const CLASS_FILES = [
'optional/theme-example.css',
];

module.exports = { TOKEN_FILES, CLASS_FILES };
export { TOKEN_FILES, CLASS_FILES };
8 changes: 3 additions & 5 deletions scripts/version-sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@
// Run after every version bump: npm run version-sync
// Wired into .release-it.json hooks so it executes automatically during releases.

'use strict';
import fs from 'node:fs';
import path from 'node:path';

const fs = require('fs');
const path = require('path');

const ROOT = path.resolve(__dirname, '..');
const ROOT = path.resolve(import.meta.dirname, '..');

function readFile(rel) {
return fs.readFileSync(path.join(ROOT, rel), 'utf8');
Expand Down
10 changes: 5 additions & 5 deletions scripts/zip-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@
* output already lives in assets/.
*/

const fs = require('fs');
const path = require('path');
const { execSync, execFileSync } = require('child_process');
import fs from 'node:fs';
import path from 'node:path';
import zlib from 'node:zlib';
import { execSync, execFileSync } from 'node:child_process';

const ROOT = path.resolve(__dirname, '..');
const ROOT = path.resolve(import.meta.dirname, '..');
const OUTPUT = path.join(ROOT, 'dist', 'slashed.zip');
const STAGE = path.join(ROOT, '.tmp-plugin-stage');
const STAGE_PLUGIN = path.join(STAGE, 'slashed');
Expand Down Expand Up @@ -102,7 +103,6 @@ function main() {
* Handles files and directories with DEFLATE compression.
*/
function createZipFromDir(sourceDir, outputPath, rootName) {
const zlib = require('zlib');
const files = [];

function walk(dir, rel) {
Expand Down
4 changes: 2 additions & 2 deletions tests/a11y-patterns.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
// .sr-only, .sr-only-focusable, .skip-link,
// .sf-focus-parent, .sf-clickable-parent,
// touch-target token, forced-colors, disabled cursor.
const { test, expect } = require('@playwright/test');
const path = require('path');
import { test, expect } from '@playwright/test';
import path from 'node:path';

const BUNDLE = path.join(process.cwd(), 'dist', 'slashed.optimal.css');

Expand Down
10 changes: 5 additions & 5 deletions tests/a11y.spec.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
// @ts-check
// Automated accessibility audit of the demo page with axe-core.
// Catches WCAG regressions (contrast, ARIA, landmarks) in both themes.
const { test, expect } = require('@playwright/test');
const { AxeBuilder } = require('@axe-core/playwright');
const path = require('path');
const { pathToFileURL } = require('url');
import { test, expect } from '@playwright/test';
import { AxeBuilder } from '@axe-core/playwright';
import path from 'node:path';
import { pathToFileURL } from 'node:url';

// A focused fixture exercising real framework usage with correct semantics
// (labelled forms, heading order, landmarks). The kitchen-sink demo.html
// intentionally contains low-contrast helper text and unlabelled control
// samples, so it is not a fair axe target; this fixture is.
const DEMO_URL = pathToFileURL(path.resolve(__dirname, 'a11y-fixture.html')).href;
const DEMO_URL = pathToFileURL(path.resolve(import.meta.dirname, 'a11y-fixture.html')).href;

for (const theme of ['light', 'dark']) {
test(`axe: no WCAG A/AA violations (${theme})`, async ({ page, browserName }) => {
Expand Down
8 changes: 4 additions & 4 deletions tests/auto-color.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
//
// fixture.html loads dist/slashed.full.css, so both the `a:link` rules
// (base) and the .sf-surface--* / .sf-link--* macros are present.
const { test, expect } = require('@playwright/test');
const path = require('path');
const { pathToFileURL } = require('url');
import { test, expect } from '@playwright/test';
import path from 'node:path';
import { pathToFileURL } from 'node:url';

const FIXTURE = pathToFileURL(path.join(__dirname, 'fixture.html')).href;
const FIXTURE = pathToFileURL(path.join(import.meta.dirname, 'fixture.html')).href;

const SURFACES = [
'primary', 'secondary', 'tertiary', 'action', 'neutral',
Expand Down
8 changes: 4 additions & 4 deletions tests/behavior.spec.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// @ts-check
// Behavioural regression tests: reduced-motion, forced-colors, container
// queries, and a sample of state-class effects. Loads the demo over file://.
const { test, expect } = require('@playwright/test');
const path = require('path');
const { pathToFileURL } = require('url');
import { test, expect } from '@playwright/test';
import path from 'node:path';
import { pathToFileURL } from 'node:url';

const DEMO_URL = pathToFileURL(path.resolve(__dirname, '..', 'docs', 'demo.html')).href;
const DEMO_URL = pathToFileURL(path.resolve(import.meta.dirname, '..', 'docs', 'demo.html')).href;

test.describe('Reduced motion', () => {
test('transitions are neutralised under prefers-reduced-motion: reduce', async ({ page }) => {
Expand Down
10 changes: 5 additions & 5 deletions tests/bundle-size.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
// Bundle-size regression guard. Fails if a built bundle's gzip size exceeds
// its budget — catches accidental bloat. Budgets are deliberately loose
// headroom over current sizes, tightened as the framework stabilises.
const { test, expect } = require('@playwright/test');
const fs = require('fs');
const path = require('path');
const zlib = require('zlib');
import { test, expect } from '@playwright/test';
import fs from 'node:fs';
import path from 'node:path';
import zlib from 'node:zlib';

const DIST = path.resolve(__dirname, '..', 'dist');
const DIST = path.resolve(import.meta.dirname, '..', 'dist');

// gzip kB budgets per minified bundle.
const BUDGETS = {
Expand Down
8 changes: 4 additions & 4 deletions tests/color-semantic.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
// Verifies semantic colour-token pairs meet WCAG contrast requirements
// and that the palette scale and surface hierarchy are coherent.
// Runs in both light and dark themes.
const { test, expect } = require('@playwright/test');
const path = require('path');
const { pathToFileURL } = require('url');
import { test, expect } from '@playwright/test';
import path from 'node:path';
import { pathToFileURL } from 'node:url';

// fixture.html loads slashed.full.css (includes tokens.palette.css)
const FIXTURE = pathToFileURL(path.join(__dirname, 'fixture.html')).href;
const FIXTURE = pathToFileURL(path.join(import.meta.dirname, 'fixture.html')).href;

// ── Serialisable in-browser helpers ─────────────────────────────
// Functions passed directly to page.evaluate() must be self-contained
Expand Down
4 changes: 2 additions & 2 deletions tests/container-queries.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
// below 30em, between 30em–48em, and above 48em (1em = 16px by default).
// setupInContainer pins font-size to 16px so em-based CQ thresholds are stable
// across browsers (WebKit 26+ resolves em against inherited font-size, not 16px).
const { test, expect } = require('@playwright/test');
const path = require('path');
import { test, expect } from '@playwright/test';
import path from 'node:path';

const BUNDLE = path.join(process.cwd(), 'dist', 'slashed.essential.css');

Expand Down
Loading