ply-css 1.6.1 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +17 -0
- package/PLY.md +37 -1
- package/README.md +50 -2
- package/bin/ply-purge.js +172 -0
- package/dist/css/ply-core.css +29 -47
- package/dist/css/ply-core.min.css +1 -1
- package/dist/css/ply-essentials.min.css +1 -1
- package/dist/css/ply-helpers.min.css +1 -1
- package/dist/css/ply.css +34 -123
- package/dist/css/ply.min.css +1 -1
- package/dist/css/ply.purged.min.css +1 -0
- package/dist/css/styles.css +34 -123
- package/dist/css/styles.min.css +1 -1
- package/llms-full.txt +38 -6
- package/llms.txt +1 -1
- package/package.json +18 -1
- package/ply-classes.json +18 -21
- package/purge.js +81 -0
- package/safelist.js +43 -0
- package/snippets/custom-theme.html +3 -3
- package/snippets/starter-page.html +2 -2
- package/src/scss/_ply.scss +0 -2
- package/src/scss/components/_colors.scss +22 -35
- package/src/scss/components/_forms.scss +5 -6
- package/src/scss/components/_helpers-core.scss +3 -3
- package/src/scss/components/_multi-step-form.scss +5 -5
- package/src/scss/components/_rtl.scss +0 -11
- package/src/scss/components/_tables.scss +2 -1
- package/src/scss/components/_dropdown.scss +0 -68
package/llms-full.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# plycss (ply) — Complete Documentation
|
|
2
2
|
|
|
3
|
-
> ply is a ratio-based, AI-ready CSS framework with built-in dark mode, WCAG 2.1 AA accessibility, and a small footprint (~21KB gzipped). 458 utility classes, 120+ CSS custom properties, 13 auto-styled semantic elements. No JavaScript. No build step. Install via npm as `
|
|
3
|
+
> ply is a ratio-based, AI-ready CSS framework with built-in dark mode, WCAG 2.1 AA accessibility, and a small footprint (~21KB gzipped, ~5KB with tree-shaking). 458 utility classes, 120+ CSS custom properties, 13 auto-styled semantic elements. No JavaScript. No build step required. Optional tree-shaking via `ply-purge` CLI or PostCSS plugin. Install via npm as `ply-css` or use the CDN.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -35,13 +35,13 @@ SCSS source: `src/scss/components/_colors.scss` (full color palette), `_variable
|
|
|
35
35
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ply-css@1/dist/css/ply.min.css">
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
Core bundle (no labels,
|
|
38
|
+
Core bundle (no labels, loaders, print):
|
|
39
39
|
|
|
40
40
|
```html
|
|
41
41
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ply-css@1/dist/css/ply-core.min.css">
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
Bundles: `ply.min.css` (~21KB gzip, everything), `ply-core.min.css` (~17KB, grid+buttons+forms+nav+alerts+tables+typography+helpers), `ply-essentials.min.css` (~7KB, grid+helpers), `ply-helpers.min.css` (~5KB, helpers only).
|
|
44
|
+
Bundles: `ply.min.css` (~21KB gzip, everything), `ply-core.min.css` (~17KB, grid+buttons+forms+nav+alerts+tables+typography+helpers), `ply-essentials.min.css` (~7KB, grid+helpers), `ply-helpers.min.css` (~5KB, helpers only). For production, use `ply-purge` to tree-shake unused classes (~5KB gzipped for a typical page). See the Tree-Shaking section below.
|
|
45
45
|
|
|
46
46
|
---
|
|
47
47
|
|
|
@@ -493,7 +493,7 @@ ply auto-styles `<table>` with borders, padding, and readable spacing. No classe
|
|
|
493
493
|
|---|---|
|
|
494
494
|
| `table-bordered` | Borders on all cells |
|
|
495
495
|
| `table-stroked` | Bottom borders only |
|
|
496
|
-
| `table-
|
|
496
|
+
| `table-striped` | Striped odd rows |
|
|
497
497
|
| `table-hovered` | Row highlight on hover |
|
|
498
498
|
| `table-simple` | Remove borders and left padding |
|
|
499
499
|
| `table-flat` | Remove all borders and padding |
|
|
@@ -505,7 +505,7 @@ ply auto-styles `<table>` with borders, padding, and readable spacing. No classe
|
|
|
505
505
|
|
|
506
506
|
```html
|
|
507
507
|
<div class="table-container">
|
|
508
|
-
<table class="table-
|
|
508
|
+
<table class="table-striped table-hovered">
|
|
509
509
|
<thead>
|
|
510
510
|
<tr>
|
|
511
511
|
<th class="sortable sort-asc">Name</th>
|
|
@@ -521,7 +521,7 @@ ply auto-styles `<table>` with borders, padding, and readable spacing. No classe
|
|
|
521
521
|
</div>
|
|
522
522
|
```
|
|
523
523
|
|
|
524
|
-
Tables respond to dark mode automatically — borders, stripe colors, and hover colors adapt via `--ply-color-table-border`, `--ply-color-table-
|
|
524
|
+
Tables respond to dark mode automatically — borders, stripe colors, and hover colors adapt via `--ply-color-table-border`, `--ply-color-table-striped`, and `--ply-color-table-hovered`. Combine classes freely: `table-striped table-hovered table-bordered` gives striped rows with hover highlights and full borders.
|
|
525
525
|
|
|
526
526
|
Wrap any table in `<div class="table-container">` to get horizontal scrolling on small screens instead of layout overflow.
|
|
527
527
|
|
|
@@ -895,6 +895,38 @@ ply is built for AI code generation:
|
|
|
895
895
|
|
|
896
896
|
---
|
|
897
897
|
|
|
898
|
+
## Tree-Shaking (Purge Unused CSS)
|
|
899
|
+
|
|
900
|
+
For production, purge unused ply classes to get ~5KB gzipped (typical single page).
|
|
901
|
+
|
|
902
|
+
**PostCSS plugin** (recommended for build pipelines):
|
|
903
|
+
|
|
904
|
+
```js
|
|
905
|
+
// postcss.config.js
|
|
906
|
+
const plyPurge = require('ply-css/purge');
|
|
907
|
+
module.exports = {
|
|
908
|
+
plugins: [
|
|
909
|
+
plyPurge({ content: ['./src/**/*.{html,jsx,tsx,vue}'] }),
|
|
910
|
+
],
|
|
911
|
+
};
|
|
912
|
+
```
|
|
913
|
+
|
|
914
|
+
Requires: `npm install -D @fullhuman/postcss-purgecss`
|
|
915
|
+
|
|
916
|
+
**CLI** (standalone or CI):
|
|
917
|
+
|
|
918
|
+
```sh
|
|
919
|
+
npx ply-purge --css node_modules/ply-css/dist/css/ply.min.css \
|
|
920
|
+
--content 'src/**/*.{html,jsx,tsx}' \
|
|
921
|
+
-o public/ply.css
|
|
922
|
+
```
|
|
923
|
+
|
|
924
|
+
Requires: `npm install -D purgecss`
|
|
925
|
+
|
|
926
|
+
The purge tool auto-safelists dynamically-toggled classes (`active`, `sort-asc`, responsive grid variants) so they aren't incorrectly removed. Extend with `--safelist <class>` (CLI) or `safelist` option (PostCSS).
|
|
927
|
+
|
|
928
|
+
---
|
|
929
|
+
|
|
898
930
|
## Anti-Patterns
|
|
899
931
|
|
|
900
932
|
- **DON'T** use Tailwind, Bootstrap, or other frameworks with ply
|
package/llms.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# plycss (ply)
|
|
2
2
|
|
|
3
|
-
> ply is a ratio-based, AI-ready CSS framework with dark mode, WCAG 2.1 AA accessibility, and a small footprint (~21KB gzipped). 458 utility classes, 120+ CSS custom properties, 13 auto-styled semantic elements. No JavaScript. No build step.
|
|
3
|
+
> ply is a ratio-based, AI-ready CSS framework with dark mode, WCAG 2.1 AA accessibility, and a small footprint (~21KB gzipped, ~5KB with tree-shaking). 458 utility classes, 120+ CSS custom properties, 13 auto-styled semantic elements. No JavaScript. No build step required. Optional tree-shaking via `ply-purge` CLI or PostCSS plugin.
|
|
4
4
|
|
|
5
5
|
ply is standalone — do not use Tailwind, Bootstrap, or other CSS frameworks alongside it. Class names are single-dash and human-readable: `btn-primary`, `unit-50`, `padding-lg`, `text-secondary`. Install via npm (`plycss`) or CDN.
|
|
6
6
|
|
package/package.json
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ply-css",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.1",
|
|
4
4
|
"description": "ply — A ratio-based, AI-ready CSS framework with dark mode, accessibility, and a small footprint",
|
|
5
5
|
"main": "dist/css/ply.css",
|
|
6
6
|
"style": "dist/css/ply.min.css",
|
|
7
|
+
"bin": {
|
|
8
|
+
"ply-purge": "bin/ply-purge.js"
|
|
9
|
+
},
|
|
7
10
|
"files": [
|
|
8
11
|
"dist/",
|
|
9
12
|
"src/scss/",
|
|
13
|
+
"bin/",
|
|
14
|
+
"purge.js",
|
|
15
|
+
"safelist.js",
|
|
10
16
|
"CLAUDE.md",
|
|
11
17
|
"PLY.md",
|
|
12
18
|
"ply-classes.json",
|
|
@@ -33,9 +39,19 @@
|
|
|
33
39
|
"url": "git+https://github.com/thatgibbyguy/ply.git"
|
|
34
40
|
},
|
|
35
41
|
"homepage": "https://github.com/thatgibbyguy/ply",
|
|
42
|
+
"peerDependencies": {
|
|
43
|
+
"@fullhuman/postcss-purgecss": ">=6.0.0"
|
|
44
|
+
},
|
|
45
|
+
"peerDependenciesMeta": {
|
|
46
|
+
"@fullhuman/postcss-purgecss": {
|
|
47
|
+
"optional": true
|
|
48
|
+
}
|
|
49
|
+
},
|
|
36
50
|
"devDependencies": {
|
|
51
|
+
"@fullhuman/postcss-purgecss": "^6.0.0",
|
|
37
52
|
"autoprefixer": "^10.4.21",
|
|
38
53
|
"cssnano": "^7.0.6",
|
|
54
|
+
"purgecss": "^6.0.0",
|
|
39
55
|
"postcss": "^8.5.3",
|
|
40
56
|
"postcss-cli": "^11.0.1",
|
|
41
57
|
"sass": "^1.86.0",
|
|
@@ -60,6 +76,7 @@
|
|
|
60
76
|
"watch": "sass --watch src/scss/styles.scss:dist/css/styles.css src/scss/styles.scss:dist/css/styles.min.css src/scss/ply-essentials.scss:dist/css/ply-essentials.min.css --no-source-map",
|
|
61
77
|
"lint": "stylelint \"src/scss/**/*.scss\"",
|
|
62
78
|
"validate": "node scripts/validate-classes.js snippets/*.html examples/*.html",
|
|
79
|
+
"purge:demo": "node bin/ply-purge.js --css dist/css/ply.min.css --content 'snippets/*.html' -o dist/css/ply.purged.min.css",
|
|
63
80
|
"prepublishOnly": "npm run build && npm run lint"
|
|
64
81
|
},
|
|
65
82
|
"author": "John Gibby",
|
package/ply-classes.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.
|
|
2
|
+
"version": "1.7.1",
|
|
3
3
|
"framework": "ply",
|
|
4
4
|
"totalClasses": 457,
|
|
5
5
|
"uniqueClasses": 457,
|
|
@@ -34,10 +34,12 @@
|
|
|
34
34
|
"--ply-color-focus",
|
|
35
35
|
"--ply-color-input-bg",
|
|
36
36
|
"--ply-color-input-border",
|
|
37
|
+
"--ply-color-error",
|
|
38
|
+
"--ply-color-success",
|
|
37
39
|
"--ply-color-code-bg",
|
|
38
40
|
"--ply-color-code-border",
|
|
39
41
|
"--ply-color-table-border",
|
|
40
|
-
"--ply-color-table-
|
|
42
|
+
"--ply-color-table-striped",
|
|
41
43
|
"--ply-nav-color",
|
|
42
44
|
"--ply-nav-hover",
|
|
43
45
|
"--ply-layer-0",
|
|
@@ -61,7 +63,7 @@
|
|
|
61
63
|
},
|
|
62
64
|
"themeTemplate": {
|
|
63
65
|
"description": "Copy-paste starting point for custom themes. Replace placeholder values with your design colors. Every ply component respects these variables.",
|
|
64
|
-
"css": "[data-theme=\"my-theme\"] {\n /* Background */\n --ply-bg-body: #___;\n --ply-bg-surface: #___;\n --ply-bg-surface-alt: #___;\n --ply-bg-muted: #___;\n\n /* Text */\n --ply-color-body: #___;\n --ply-color-headings: #___;\n --ply-color-secondary: #___;\n --ply-color-muted: #___;\n --ply-color-placeholder: #___;\n --ply-color-text-inverse: #___;\n\n /* Borders */\n --ply-border-color: #___;\n --ply-border-strong: #___;\n --ply-border-radius: 0.25rem;\n\n /* Interactive */\n --ply-color-accent: #___;\n --ply-color-focus: #___;\n --ply-color-link-hover: #___;\n\n /* Buttons */\n --ply-btn-default-bg: #___;\n --ply-btn-default-color: #___;\n --ply-btn-default-bg-hover: #___;\n --ply-btn-default-bg-active: #___;\n --ply-btn-secondary-bg: #___;\n --ply-btn-secondary-color: #___;\n --ply-btn-secondary-bg-hover: #___;\n --ply-btn-secondary-bg-active: #___;\n --ply-btn-border-radius: 2rem;\n --ply-btn-font-size: 1em;\n --ply-btn-gap: 0.5em;\n\n /* Forms */\n --ply-color-input-bg: #___;\n --ply-color-input-border: #___;\n\n /* Navigation */\n --ply-nav-bg: #___;\n --ply-nav-color: #___;\n --ply-nav-border: #___;\n --ply-nav-hover: #___;\n\n /* Code */\n --ply-color-code-bg: #___;\n --ply-color-code-border: #___;\n\n /* Tables */\n --ply-color-table-border: #___;\n --ply-color-table-
|
|
66
|
+
"css": "[data-theme=\"my-theme\"] {\n /* Background */\n --ply-bg-body: #___;\n --ply-bg-surface: #___;\n --ply-bg-surface-alt: #___;\n --ply-bg-muted: #___;\n\n /* Text */\n --ply-color-body: #___;\n --ply-color-headings: #___;\n --ply-color-secondary: #___;\n --ply-color-muted: #___;\n --ply-color-placeholder: #___;\n --ply-color-text-inverse: #___;\n\n /* Borders */\n --ply-border-color: #___;\n --ply-border-strong: #___;\n --ply-border-radius: 0.25rem;\n\n /* Interactive */\n --ply-color-accent: #___;\n --ply-color-focus: #___;\n --ply-color-link-hover: #___;\n\n /* Buttons */\n --ply-btn-default-bg: #___;\n --ply-btn-default-color: #___;\n --ply-btn-default-bg-hover: #___;\n --ply-btn-default-bg-active: #___;\n --ply-btn-secondary-bg: #___;\n --ply-btn-secondary-color: #___;\n --ply-btn-secondary-bg-hover: #___;\n --ply-btn-secondary-bg-active: #___;\n --ply-btn-border-radius: 2rem;\n --ply-btn-font-size: 1em;\n --ply-btn-gap: 0.5em;\n\n /* Forms */\n --ply-color-input-bg: #___;\n --ply-color-input-border: #___;\n --ply-color-error: #___;\n --ply-color-success: #___;\n\n /* Navigation */\n --ply-nav-bg: #___;\n --ply-nav-color: #___;\n --ply-nav-border: #___;\n --ply-nav-hover: #___;\n\n /* Code */\n --ply-color-code-bg: #___;\n --ply-color-code-border: #___;\n\n /* Tables */\n --ply-color-table-border: #___;\n --ply-color-table-striped: #___;\n\n /* Elevation */\n --ply-layer-0: #___;\n --ply-layer-1: #___;\n --ply-layer-2: #___;\n --ply-layer-3: #___;\n --ply-shadow-1: rgba(0, 0, 0, 0.08);\n --ply-shadow-2: rgba(0, 0, 0, 0.1);\n --ply-shadow-3: rgba(0, 0, 0, 0.12);\n\n /* Typography (optional) */\n --ply-font-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n --ply-font-heading: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n --ply-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;\n}"
|
|
65
67
|
},
|
|
66
68
|
"classes": {
|
|
67
69
|
"units-container": {
|
|
@@ -1563,10 +1565,14 @@
|
|
|
1563
1565
|
"category": "tables",
|
|
1564
1566
|
"description": "Table with bottom borders only on cells."
|
|
1565
1567
|
},
|
|
1566
|
-
"table-
|
|
1568
|
+
"table-striped": {
|
|
1567
1569
|
"category": "tables",
|
|
1568
1570
|
"description": "Striped table rows (odd rows get background color). Applied to table element.",
|
|
1569
|
-
"example": "<table class=\"table-
|
|
1571
|
+
"example": "<table class=\"table-striped\"><tbody><tr><td>Row 1</td></tr><tr><td>Row 2</td></tr></tbody></table>"
|
|
1572
|
+
},
|
|
1573
|
+
"table-stripped": {
|
|
1574
|
+
"category": "tables",
|
|
1575
|
+
"description": "Deprecated alias for table-striped. Use table-striped instead."
|
|
1570
1576
|
},
|
|
1571
1577
|
"table-hovered": {
|
|
1572
1578
|
"category": "tables",
|
|
@@ -1943,18 +1949,6 @@
|
|
|
1943
1949
|
"category": "forms",
|
|
1944
1950
|
"description": "Autocomplete dropdown container for form inputs."
|
|
1945
1951
|
},
|
|
1946
|
-
"dropdown": {
|
|
1947
|
-
"category": "helpers",
|
|
1948
|
-
"description": "Positioned absolute dropdown panel. Appears below trigger element."
|
|
1949
|
-
},
|
|
1950
|
-
"caret": {
|
|
1951
|
-
"category": "helpers",
|
|
1952
|
-
"description": "Downward-pointing dropdown arrow indicator."
|
|
1953
|
-
},
|
|
1954
|
-
"caret-up": {
|
|
1955
|
-
"category": "helpers",
|
|
1956
|
-
"description": "Upward-pointing caret. Modifier on caret."
|
|
1957
|
-
},
|
|
1958
1952
|
"label": {
|
|
1959
1953
|
"category": "notifications",
|
|
1960
1954
|
"description": "Inline label/tag. Small, uppercase, bold text with background color."
|
|
@@ -2479,9 +2473,11 @@
|
|
|
2479
2473
|
"--ply-btn-border-radius": "Button border-radius. Default: 2rem (pill shape). Override for square or rounded buttons."
|
|
2480
2474
|
},
|
|
2481
2475
|
"forms": {
|
|
2482
|
-
"--ply-color-field-bg": "Field background.
|
|
2483
|
-
"--ply-color-input-border": "Input border.
|
|
2484
|
-
"--ply-color-input-bg": "Input background.
|
|
2476
|
+
"--ply-color-field-bg": "Field background. Defaults to var(--ply-bg-surface-alt). Override for custom field backgrounds.",
|
|
2477
|
+
"--ply-color-input-border": "Input border. Defaults to var(--ply-border-strong). Override for custom input borders.",
|
|
2478
|
+
"--ply-color-input-bg": "Input background. Defaults to var(--ply-bg-surface-alt). Override for custom input backgrounds.",
|
|
2479
|
+
"--ply-color-error": "Error state color for borders and text. Defaults to var(--ply-red-1). Used by .input-error, .error, .required, and stepper error states.",
|
|
2480
|
+
"--ply-color-success": "Success state color for borders and text. Defaults to var(--ply-green-1). Used by .input-success, .success, and stepper completed states."
|
|
2485
2481
|
},
|
|
2486
2482
|
"code": {
|
|
2487
2483
|
"--ply-color-code-bg": "Inline code background. Light: #f4f4f4, Dark: #333333",
|
|
@@ -2489,7 +2485,8 @@
|
|
|
2489
2485
|
},
|
|
2490
2486
|
"tables": {
|
|
2491
2487
|
"--ply-color-table-border": "Table cell border. Light: #e0e0e0, Dark: #525252",
|
|
2492
|
-
"--ply-color-table-
|
|
2488
|
+
"--ply-color-table-striped": "Striped row background. Light: #f4f4f4, Dark: #1c1c1c",
|
|
2489
|
+
"--ply-color-table-stripped": "Deprecated alias for --ply-color-table-striped.",
|
|
2493
2490
|
"--ply-color-table-hovered": "Hovered row background. Light: #e8e8e8, Dark: #333333"
|
|
2494
2491
|
},
|
|
2495
2492
|
"buttons": {
|
package/purge.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ply PostCSS purge plugin — tree-shake unused ply CSS.
|
|
3
|
+
*
|
|
4
|
+
* Wraps @fullhuman/postcss-purgecss with ply-specific defaults:
|
|
5
|
+
* - Safelists dynamically-toggled classes (active, sort-asc, etc.)
|
|
6
|
+
* - Preserves responsive grid variants that static analysis may miss
|
|
7
|
+
* - Keeps CSS custom properties (:root), element resets, and @media blocks
|
|
8
|
+
*
|
|
9
|
+
* Usage in postcss.config.js:
|
|
10
|
+
*
|
|
11
|
+
* const plyPurge = require('ply-css/purge');
|
|
12
|
+
*
|
|
13
|
+
* module.exports = {
|
|
14
|
+
* plugins: [
|
|
15
|
+
* plyPurge({ content: ['./src/**\/*.{html,jsx,tsx,vue}'] }),
|
|
16
|
+
* ],
|
|
17
|
+
* };
|
|
18
|
+
*
|
|
19
|
+
* Requires: npm install -D @fullhuman/postcss-purgecss
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
"use strict";
|
|
23
|
+
|
|
24
|
+
const { safelistClasses, safelistPatterns } = require("./safelist");
|
|
25
|
+
|
|
26
|
+
function plyPurge(options = {}) {
|
|
27
|
+
const { content, safelist = {}, ...rest } = options;
|
|
28
|
+
|
|
29
|
+
if (!content || content.length === 0) {
|
|
30
|
+
throw new Error(
|
|
31
|
+
"ply purge: `content` is required. Pass an array of glob patterns " +
|
|
32
|
+
"pointing to your template/component files.\n" +
|
|
33
|
+
"Example: plyPurge({ content: ['./src/**/*.{html,jsx,tsx,vue}'] })"
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
let purgecss;
|
|
38
|
+
try {
|
|
39
|
+
purgecss = require("@fullhuman/postcss-purgecss");
|
|
40
|
+
} catch {
|
|
41
|
+
throw new Error(
|
|
42
|
+
"ply purge requires @fullhuman/postcss-purgecss.\n" +
|
|
43
|
+
"Install it: npm install -D @fullhuman/postcss-purgecss"
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const userSafelist = Array.isArray(safelist)
|
|
48
|
+
? { standard: safelist }
|
|
49
|
+
: safelist;
|
|
50
|
+
|
|
51
|
+
return purgecss({
|
|
52
|
+
content,
|
|
53
|
+
safelist: {
|
|
54
|
+
standard: [
|
|
55
|
+
...safelistClasses,
|
|
56
|
+
...(userSafelist.standard || []),
|
|
57
|
+
],
|
|
58
|
+
greedy: [
|
|
59
|
+
// Preserve all :root, html, body rules (custom properties, resets)
|
|
60
|
+
/^:root$/,
|
|
61
|
+
/^html$/,
|
|
62
|
+
/^body$/,
|
|
63
|
+
...(userSafelist.greedy || []),
|
|
64
|
+
],
|
|
65
|
+
deep: [...safelistPatterns, ...(userSafelist.deep || [])],
|
|
66
|
+
},
|
|
67
|
+
// ply uses single-dash BEM-ish names; default extractor works well
|
|
68
|
+
// but we add a custom one to also catch class names in JSX/TSX
|
|
69
|
+
defaultExtractor: (content) => {
|
|
70
|
+
// Match class="...", className="...", className={`...`}, and
|
|
71
|
+
// bare words that look like ply classes
|
|
72
|
+
const broadMatches = content.match(/[^<>"'`\s]*[^<>"'`\s:]/g) || [];
|
|
73
|
+
const innerMatches =
|
|
74
|
+
content.match(/[^<>"'`\s.(){}[\]#,;]+/g) || [];
|
|
75
|
+
return [...new Set([...broadMatches, ...innerMatches])];
|
|
76
|
+
},
|
|
77
|
+
...rest,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
module.exports = plyPurge;
|
package/safelist.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ply safelist — classes and patterns that should never be purged.
|
|
3
|
+
*
|
|
4
|
+
* These are either toggled dynamically via JavaScript (e.g. `active`, `on`)
|
|
5
|
+
* or generated via SCSS loops (responsive variants) where static analysis
|
|
6
|
+
* of content files might miss them.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
"use strict";
|
|
10
|
+
|
|
11
|
+
const safelistClasses = [
|
|
12
|
+
// Dynamic state classes (toggled via JS)
|
|
13
|
+
"active",
|
|
14
|
+
"on",
|
|
15
|
+
"open",
|
|
16
|
+
"accordion-title-opened",
|
|
17
|
+
"accordion-toggle-opened",
|
|
18
|
+
"accordion-toggle-closed",
|
|
19
|
+
"sort-asc",
|
|
20
|
+
"sort-desc",
|
|
21
|
+
"btn-active",
|
|
22
|
+
"btn-disabled",
|
|
23
|
+
"input-error",
|
|
24
|
+
"input-success",
|
|
25
|
+
"input-gray",
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
const safelistPatterns = [
|
|
29
|
+
// Responsive grid units: tablet-unit-50, phone-unit-100, etc.
|
|
30
|
+
/^(tablet|phone|large-phone|small-desktop|large-screen|x-large-screen|forever)-unit-(100|90|88|80|75|70|66|65|62|60|50|40|38|35|33|30|25|20|12|10|auto)$/,
|
|
31
|
+
// Container query units
|
|
32
|
+
/^container-(phone|large-phone|tablet|small-desktop)-unit-(100|90|88|80|75|70|66|65|62|60|50|40|38|35|33|30|25|20|12|10|auto)$/,
|
|
33
|
+
// Responsive width helpers
|
|
34
|
+
/^(tablet|phone|large-phone|small-desktop)-width-(100|90|80|75|70|66|50|40|33|25|20|10)$/,
|
|
35
|
+
// Responsive block helpers
|
|
36
|
+
/^blocks-mobile-(50|33)$/,
|
|
37
|
+
// Dialog layers
|
|
38
|
+
/^dialog-layer-[1-3]$/,
|
|
39
|
+
// Step form states
|
|
40
|
+
/^step-panel$/,
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
module.exports = { safelistClasses, safelistPatterns };
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
|
|
58
58
|
/* Tables */
|
|
59
59
|
--ply-color-table-border: #334155;
|
|
60
|
-
--ply-color-table-
|
|
60
|
+
--ply-color-table-striped: #162032;
|
|
61
61
|
--ply-color-table-hovered: #253349;
|
|
62
62
|
|
|
63
63
|
/* Buttons */
|
|
@@ -121,7 +121,7 @@
|
|
|
121
121
|
|
|
122
122
|
/* Tables */
|
|
123
123
|
--ply-color-table-border: #d6d3d1;
|
|
124
|
-
--ply-color-table-
|
|
124
|
+
--ply-color-table-striped: #faf8f5;
|
|
125
125
|
--ply-color-table-hovered: #f0ebe4;
|
|
126
126
|
|
|
127
127
|
/* Buttons */
|
|
@@ -245,7 +245,7 @@
|
|
|
245
245
|
</div>
|
|
246
246
|
|
|
247
247
|
<h2>Available tokens</h2>
|
|
248
|
-
<table class="table-
|
|
248
|
+
<table class="table-striped">
|
|
249
249
|
<thead>
|
|
250
250
|
<tr><th>Token</th><th>Purpose</th></tr>
|
|
251
251
|
</thead>
|
|
@@ -239,7 +239,7 @@
|
|
|
239
239
|
<div class="unit-100">
|
|
240
240
|
<div class="card">
|
|
241
241
|
<h4>Table</h4>
|
|
242
|
-
<table class="table-
|
|
242
|
+
<table class="table-striped table-hovered">
|
|
243
243
|
<thead>
|
|
244
244
|
<tr>
|
|
245
245
|
<th>Feature</th>
|
|
@@ -704,7 +704,7 @@
|
|
|
704
704
|
<div class="unit-100">
|
|
705
705
|
<div class="card">
|
|
706
706
|
<h4>Token reference</h4>
|
|
707
|
-
<table class="table-
|
|
707
|
+
<table class="table-striped">
|
|
708
708
|
<thead>
|
|
709
709
|
<tr><th>Token</th><th>Purpose</th></tr>
|
|
710
710
|
</thead>
|
package/src/scss/_ply.scss
CHANGED
|
@@ -51,17 +51,20 @@ $btn-secondary-dark-active: #bebebe;
|
|
|
51
51
|
--ply-color-focus: #0f62fe;
|
|
52
52
|
|
|
53
53
|
// Fields
|
|
54
|
-
--ply-color-field-bg:
|
|
55
|
-
--ply-color-input-border:
|
|
56
|
-
--ply-color-input-bg:
|
|
54
|
+
--ply-color-field-bg: var(--ply-bg-surface-alt);
|
|
55
|
+
--ply-color-input-border: var(--ply-border-strong);
|
|
56
|
+
--ply-color-input-bg: var(--ply-bg-surface-alt);
|
|
57
|
+
--ply-color-error: var(--ply-red-1);
|
|
58
|
+
--ply-color-success: var(--ply-green-1);
|
|
57
59
|
|
|
58
60
|
// Code
|
|
59
|
-
--ply-color-code-bg:
|
|
60
|
-
--ply-color-code-border:
|
|
61
|
+
--ply-color-code-bg: var(--ply-bg-surface-alt);
|
|
62
|
+
--ply-color-code-border: var(--ply-border-color);
|
|
61
63
|
|
|
62
64
|
// Tables
|
|
63
|
-
--ply-color-table-border:
|
|
64
|
-
--ply-color-table-
|
|
65
|
+
--ply-color-table-border: var(--ply-border-color);
|
|
66
|
+
--ply-color-table-striped: #f4f4f4;
|
|
67
|
+
--ply-color-table-stripped: var(--ply-color-table-striped); // deprecated alias
|
|
65
68
|
--ply-color-table-hovered: #e8e8e8;
|
|
66
69
|
|
|
67
70
|
// Accent (brand-neutral — for icons, badges, focus rings. Independent of button color.)
|
|
@@ -82,16 +85,16 @@ $btn-secondary-dark-active: #bebebe;
|
|
|
82
85
|
--ply-btn-border-radius: #{variables.$button-radius};
|
|
83
86
|
|
|
84
87
|
// Navigation
|
|
85
|
-
--ply-nav-bg:
|
|
86
|
-
--ply-nav-color:
|
|
87
|
-
--ply-nav-border:
|
|
88
|
+
--ply-nav-bg: var(--ply-bg-body);
|
|
89
|
+
--ply-nav-color: var(--ply-color-body);
|
|
90
|
+
--ply-nav-border: var(--ply-color-body);
|
|
88
91
|
--ply-nav-hover: #e8e8e8;
|
|
89
92
|
--ply-nav-active-color: #525252;
|
|
90
93
|
|
|
91
94
|
// Layers (elevation)
|
|
92
|
-
--ply-layer-0:
|
|
93
|
-
--ply-layer-1:
|
|
94
|
-
--ply-layer-2:
|
|
95
|
+
--ply-layer-0: var(--ply-bg-body);
|
|
96
|
+
--ply-layer-1: var(--ply-bg-surface-alt);
|
|
97
|
+
--ply-layer-2: var(--ply-bg-muted);
|
|
95
98
|
--ply-layer-3: #c6c6c6;
|
|
96
99
|
--ply-shadow-1: 0 1px 3px rgba(0, 0, 0, 0.08);
|
|
97
100
|
--ply-shadow-2: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
@@ -209,18 +212,9 @@ $btn-secondary-dark-active: #bebebe;
|
|
|
209
212
|
--ply-color-link-hover: color-mix(in oklch, #{$btn-primary-dark}, white 15%);
|
|
210
213
|
--ply-color-focus: #0f62fe;
|
|
211
214
|
|
|
212
|
-
//
|
|
213
|
-
--ply-color-
|
|
214
|
-
--ply-color-
|
|
215
|
-
--ply-color-input-bg: #262626;
|
|
216
|
-
|
|
217
|
-
// Code
|
|
218
|
-
--ply-color-code-bg: #262626;
|
|
219
|
-
--ply-color-code-border: #393939;
|
|
220
|
-
|
|
221
|
-
// Tables
|
|
222
|
-
--ply-color-table-border: #393939;
|
|
223
|
-
--ply-color-table-stripped: #1c1c1c;
|
|
215
|
+
// Tables (table-striped intentionally differs from surface-alt in dark)
|
|
216
|
+
--ply-color-table-striped: #1c1c1c;
|
|
217
|
+
--ply-color-table-stripped: var(--ply-color-table-striped); // deprecated alias
|
|
224
218
|
--ply-color-table-hovered: #353535;
|
|
225
219
|
|
|
226
220
|
// Accent
|
|
@@ -241,17 +235,9 @@ $btn-secondary-dark-active: #bebebe;
|
|
|
241
235
|
--ply-btn-secondary-color: #161616;
|
|
242
236
|
--ply-btn-ghost-color: #{$btn-primary-dark};
|
|
243
237
|
|
|
244
|
-
// Navigation
|
|
245
|
-
--ply-nav-bg: #161616;
|
|
246
|
-
--ply-nav-color: #f4f4f4;
|
|
247
|
-
--ply-nav-border: #f4f4f4;
|
|
238
|
+
// Navigation (nav-hover and nav-active-color intentionally differ from structural tokens in dark)
|
|
248
239
|
--ply-nav-hover: #353535;
|
|
249
240
|
--ply-nav-active-color: #a8a8a8;
|
|
250
|
-
|
|
251
|
-
// Layers (elevation)
|
|
252
|
-
--ply-layer-0: #161616;
|
|
253
|
-
--ply-layer-1: #262626;
|
|
254
|
-
--ply-layer-2: #393939;
|
|
255
241
|
--ply-layer-3: #525252;
|
|
256
242
|
--ply-shadow-1: 0 1px 3px rgba(0, 0, 0, 0.2);
|
|
257
243
|
--ply-shadow-2: 0 2px 8px rgba(0, 0, 0, 0.3);
|
|
@@ -474,7 +460,8 @@ $color-neutral-900: #171717;
|
|
|
474
460
|
|
|
475
461
|
// Table Color
|
|
476
462
|
$color-table-border: $border-color;
|
|
477
|
-
$color-table-
|
|
463
|
+
$color-table-striped: #f8f8f8;
|
|
464
|
+
$color-table-stripped: $color-table-striped; // deprecated alias
|
|
478
465
|
$color-table-hovered: #f4f4f4;
|
|
479
466
|
|
|
480
467
|
// Fieldset
|
|
@@ -184,17 +184,16 @@ input.input-error,
|
|
|
184
184
|
textarea.input-error,
|
|
185
185
|
select.input-error,
|
|
186
186
|
.input-error {
|
|
187
|
-
border-color:
|
|
188
|
-
box-shadow: 0 0 0 2px
|
|
187
|
+
border-color: var(--ply-color-error);
|
|
188
|
+
box-shadow: 0 0 0 2px color-mix(in srgb, var(--ply-color-error) 30%, transparent), 0 1px 2px rgba(0, 0, 0, .2) inset;
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
input.input-success,
|
|
192
192
|
textarea.input-success,
|
|
193
193
|
select.input-success,
|
|
194
|
-
.input-success
|
|
195
|
-
border-color:
|
|
196
|
-
box-shadow: 0 0 0 2px
|
|
197
|
-
|
|
194
|
+
.input-success {
|
|
195
|
+
border-color: var(--ply-color-success);
|
|
196
|
+
box-shadow: 0 0 0 2px color-mix(in srgb, var(--ply-color-success) 30%, transparent), 0 1px 2px rgba(0, 0, 0, .2) inset;
|
|
198
197
|
}
|
|
199
198
|
|
|
200
199
|
input.input-gray,
|
|
@@ -219,15 +219,15 @@
|
|
|
219
219
|
.req,
|
|
220
220
|
.required {
|
|
221
221
|
font-weight: normal;
|
|
222
|
-
color: var(--ply-
|
|
222
|
+
color: var(--ply-color-error);
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
.error {
|
|
226
|
-
color: var(--ply-
|
|
226
|
+
color: var(--ply-color-error);
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
.success {
|
|
230
|
-
color: var(--ply-
|
|
230
|
+
color: var(--ply-color-success);
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
// Typography — Size Utilities
|
|
@@ -83,8 +83,8 @@
|
|
|
83
83
|
&.completed {
|
|
84
84
|
&::before {
|
|
85
85
|
border-color: var(--ply-border-color);
|
|
86
|
-
background: color-mix(in srgb,
|
|
87
|
-
color:
|
|
86
|
+
background: color-mix(in srgb, var(--ply-color-success) 13%, var(--ply-bg-surface, #fff));
|
|
87
|
+
color: var(--ply-color-success);
|
|
88
88
|
content: "\2713";
|
|
89
89
|
}
|
|
90
90
|
|
|
@@ -100,14 +100,14 @@
|
|
|
100
100
|
// Error step — red border and exclamation, transparent background
|
|
101
101
|
&.step-error {
|
|
102
102
|
&::before {
|
|
103
|
-
border-color:
|
|
103
|
+
border-color: var(--ply-color-error);
|
|
104
104
|
background: transparent;
|
|
105
|
-
color:
|
|
105
|
+
color: var(--ply-color-error);
|
|
106
106
|
content: "!";
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
.step-label {
|
|
110
|
-
color:
|
|
110
|
+
color: var(--ply-color-error);
|
|
111
111
|
font-weight: variables.$font-weight-semibold;
|
|
112
112
|
}
|
|
113
113
|
}
|
|
@@ -73,17 +73,6 @@
|
|
|
73
73
|
padding-right: 0;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
// Dropdown positioning
|
|
77
|
-
.dropdown-menu {
|
|
78
|
-
left: auto;
|
|
79
|
-
right: 0;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
.dropdown-menu-right {
|
|
83
|
-
right: auto;
|
|
84
|
-
left: 0;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
76
|
// Forms — search icon positioning, select arrow
|
|
88
77
|
.form select {
|
|
89
78
|
background-position: left 0.75em center;
|
|
@@ -23,8 +23,9 @@ table.table-stroked td,
|
|
|
23
23
|
table.table-stroked th {
|
|
24
24
|
border-bottom: 1px solid var(--ply-color-table-border, colors.$color-table-border);
|
|
25
25
|
}
|
|
26
|
+
table.table-striped tbody tr:nth-child(odd) td,
|
|
26
27
|
table.table-stripped tbody tr:nth-child(odd) td {
|
|
27
|
-
background: var(--ply-color-table-stripped, colors.$color-table-stripped);
|
|
28
|
+
background: var(--ply-color-table-striped, var(--ply-color-table-stripped, colors.$color-table-stripped));
|
|
28
29
|
}
|
|
29
30
|
table.table-hovered tbody tr:hover td {
|
|
30
31
|
background-color: var(--ply-color-table-hovered, colors.$color-table-hovered);
|