@texturehq/edges 1.33.2 → 1.34.0
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/README.md +57 -3
- package/dist/{RichTextEditor-CxrunTg7.d.cts → RichTextEditor-diZqy_s1.d.cts} +1 -1
- package/dist/{RichTextEditor-CxrunTg7.d.ts → RichTextEditor-diZqy_s1.d.ts} +1 -1
- package/dist/{TimeField-DRQshIHX.d.ts → TimeField-7pTUPh11.d.ts} +32 -17
- package/dist/{TimeField-WCmeiLu3.d.cts → TimeField-CqmVrAdn.d.cts} +32 -17
- package/dist/{colors-Cgs2MGZ8.d.ts → colors-CoULWZ5j.d.ts} +53 -18
- package/dist/{colors-DGRiGzgj.d.cts → colors-upTGgIQe.d.cts} +53 -18
- package/dist/form/index.cjs +1 -1
- package/dist/form/index.cjs.map +1 -1
- package/dist/form/index.d.cts +1 -1
- package/dist/form/index.d.ts +1 -1
- package/dist/form/index.js +1 -1
- package/dist/form/index.js.map +1 -1
- package/dist/{index-BqpWEc_N.d.ts → index-dofSwYId.d.cts} +5 -5
- package/dist/{index-BqpWEc_N.d.cts → index-dofSwYId.d.ts} +5 -5
- package/dist/index.cjs +10 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +161 -41
- package/dist/index.d.ts +161 -41
- package/dist/index.js +10 -10
- package/dist/index.js.map +1 -1
- package/dist/prose.css +202 -0
- package/dist/rhf/index.cjs +1 -1
- package/dist/rhf/index.cjs.map +1 -1
- package/dist/rhf/index.d.cts +2 -2
- package/dist/rhf/index.d.ts +2 -2
- package/dist/rhf/index.js +1 -1
- package/dist/rhf/index.js.map +1 -1
- package/dist/server.cjs +2 -2
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +2 -2
- package/dist/server.d.ts +2 -2
- package/dist/server.js +2 -2
- package/dist/server.js.map +1 -1
- package/dist/styles/computed.css +2 -2
- package/dist/styles/responsive-typography.css +9 -7
- package/dist/styles/theme-light-override.css +26 -15
- package/dist/styles.css +953 -877
- package/dist/theme.css +20 -7
- package/dist/typography.css +150 -0
- package/package.json +10 -12
- package/scripts/check-legacy-action-variants.mjs +96 -0
- package/scripts/check-legacy-font-colors.mjs +92 -0
- package/scripts/copy-assets.js +12 -0
- package/templates/claude-rules/.claude +5 -5
- package/templates/claude-rules/claude.md +5 -5
- package/templates/codex-rules/codex.md +5 -5
- package/dist/generated/tailwind-tokens-dark.css +0 -397
- package/dist/generated/tailwind-tokens-light.css +0 -611
- package/dist/generated/viz-runtime.css +0 -243
- package/scripts/generate-viz-runtime.js +0 -107
- package/scripts/validate-tokens.js +0 -176
package/dist/theme.css
CHANGED
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
*
|
|
4
4
|
* This file imports all theme layers in the correct order:
|
|
5
5
|
* 1. Design tokens (from @texturehq/edges-tokens)
|
|
6
|
-
* 2.
|
|
7
|
-
* 3.
|
|
8
|
-
* 4.
|
|
9
|
-
* 5.
|
|
6
|
+
* 2. Typography role utilities (from @texturehq/edges-tokens)
|
|
7
|
+
* 3. Legacy aliases (backward compat for old variable names)
|
|
8
|
+
* 4. Animation features
|
|
9
|
+
* 5. Computed values (derived from tokens)
|
|
10
|
+
* 6. Utility classes
|
|
10
11
|
*/
|
|
11
12
|
|
|
12
13
|
/* Layer 1: Design Tokens
|
|
@@ -15,9 +16,20 @@
|
|
|
15
16
|
@import "@texturehq/edges-tokens/css/light";
|
|
16
17
|
@import "@texturehq/edges-tokens/css/dark";
|
|
17
18
|
|
|
19
|
+
/* Typography role utilities
|
|
20
|
+
Generated from edges-tokens so full Edges consumers get the same lightweight
|
|
21
|
+
role classes marketing consumers can import directly. */
|
|
22
|
+
@import "@texturehq/edges-tokens/css/typography";
|
|
23
|
+
|
|
24
|
+
/* Prose: editorial composition wrapper for long-form content. Pairs with
|
|
25
|
+
the <Prose> component exported from this package. */
|
|
26
|
+
@import "@texturehq/edges-tokens/css/prose";
|
|
27
|
+
|
|
18
28
|
/* Layer 1b: Legacy Aliases
|
|
19
29
|
Backward-compat aliases from old variable names (--action-brand-background,
|
|
20
|
-
--feedback-*, --skeleton-*,
|
|
30
|
+
--feedback-*, --skeleton-*, and deprecated font color names) to new ones.
|
|
31
|
+
Font colors should use text-primary/text-secondary/text-inverse/text-disabled;
|
|
32
|
+
remove this import after the broader compatibility migration. */
|
|
21
33
|
@import "@texturehq/edges-tokens/css/legacy";
|
|
22
34
|
|
|
23
35
|
/* Layer 1b2: Legacy Bridge
|
|
@@ -25,8 +37,9 @@
|
|
|
25
37
|
Remove once utility classes are updated to reference --color-* directly. */
|
|
26
38
|
@import "./styles/legacy-bridge.css";
|
|
27
39
|
|
|
28
|
-
/* Layer 1c: Responsive Typography
|
|
29
|
-
|
|
40
|
+
/* Layer 1c: Legacy Responsive Typography Compatibility
|
|
41
|
+
Deprecated compatibility layer for primitive Tailwind size utilities.
|
|
42
|
+
Semantic typography roles now own responsive behavior at the token layer. */
|
|
30
43
|
@import "./styles/responsive-typography.css";
|
|
31
44
|
|
|
32
45
|
/* Layer 1d: Light Theme Override
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typography utilities — @texturehq/edges-tokens
|
|
3
|
+
* Generated by Style Dictionary. DO NOT EDIT.
|
|
4
|
+
*
|
|
5
|
+
* Import after @texturehq/edges-tokens/css/light so the referenced
|
|
6
|
+
* --text-* and --font-family-* custom properties are defined.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
.text-agent {
|
|
10
|
+
font: var(--text-agent);
|
|
11
|
+
letter-spacing: var(--text-agent-letter-spacing);
|
|
12
|
+
font-optical-sizing: auto;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.text-body-lg {
|
|
16
|
+
font: var(--text-body-lg);
|
|
17
|
+
letter-spacing: var(--text-body-lg-letter-spacing);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.text-body-md {
|
|
21
|
+
font: var(--text-body-md);
|
|
22
|
+
letter-spacing: var(--text-body-md-letter-spacing);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.text-body-sm {
|
|
26
|
+
font: var(--text-body-sm);
|
|
27
|
+
letter-spacing: var(--text-body-sm-letter-spacing);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.text-code {
|
|
31
|
+
font: var(--text-code);
|
|
32
|
+
letter-spacing: var(--text-code-letter-spacing);
|
|
33
|
+
font-variant-numeric: tabular-nums;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.text-display-lg {
|
|
37
|
+
font: var(--text-display-lg);
|
|
38
|
+
letter-spacing: var(--text-display-lg-letter-spacing);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.text-display-md {
|
|
42
|
+
font: var(--text-display-md);
|
|
43
|
+
letter-spacing: var(--text-display-md-letter-spacing);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.text-display-sm {
|
|
47
|
+
font: var(--text-display-sm);
|
|
48
|
+
letter-spacing: var(--text-display-sm-letter-spacing);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.text-display-xl {
|
|
52
|
+
font: var(--text-display-xl);
|
|
53
|
+
letter-spacing: var(--text-display-xl-letter-spacing);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.text-heading-lg {
|
|
57
|
+
font: var(--text-heading-lg);
|
|
58
|
+
letter-spacing: var(--text-heading-lg-letter-spacing);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.text-heading-md {
|
|
62
|
+
font: var(--text-heading-md);
|
|
63
|
+
letter-spacing: var(--text-heading-md-letter-spacing);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.text-heading-sm {
|
|
67
|
+
font: var(--text-heading-sm);
|
|
68
|
+
letter-spacing: var(--text-heading-sm-letter-spacing);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.text-heading-xl {
|
|
72
|
+
font: var(--text-heading-xl);
|
|
73
|
+
letter-spacing: var(--text-heading-xl-letter-spacing);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.text-label-lg {
|
|
77
|
+
font: var(--text-label-lg);
|
|
78
|
+
letter-spacing: var(--text-label-lg-letter-spacing);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.text-label-md {
|
|
82
|
+
font: var(--text-label-md);
|
|
83
|
+
letter-spacing: var(--text-label-md-letter-spacing);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.text-label-sm {
|
|
87
|
+
font: var(--text-label-sm);
|
|
88
|
+
letter-spacing: var(--text-label-sm-letter-spacing);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* Semantic text color utilities. Pair with role utilities above. */
|
|
92
|
+
.text-text-body {
|
|
93
|
+
color: var(--color-text-body);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.text-text-caption {
|
|
97
|
+
color: var(--color-text-caption);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.text-text-disabled {
|
|
101
|
+
color: var(--color-text-disabled);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.text-text-heading {
|
|
105
|
+
color: var(--color-text-heading);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.text-text-inverse {
|
|
109
|
+
color: var(--color-text-inverse);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.text-text-label {
|
|
113
|
+
color: var(--color-text-label);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.text-text-link-default {
|
|
117
|
+
color: var(--color-text-link-default);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.text-text-link-hover {
|
|
121
|
+
color: var(--color-text-link-hover);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.text-text-muted {
|
|
125
|
+
color: var(--color-text-muted);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.text-text-onBrand {
|
|
129
|
+
color: var(--color-text-onBrand);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.text-text-onPrimary {
|
|
133
|
+
color: var(--color-text-onPrimary);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.text-text-placeholder {
|
|
137
|
+
color: var(--color-text-placeholder);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.text-text-primary {
|
|
141
|
+
color: var(--color-text-primary);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.text-text-secondary {
|
|
145
|
+
color: var(--color-text-secondary);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.text-text-subtle {
|
|
149
|
+
color: var(--color-text-subtle);
|
|
150
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@texturehq/edges",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.34.0",
|
|
4
4
|
"author": "Nicholas Brown <nick@texturehq.com>",
|
|
5
5
|
"description": "A shared component library for Texture",
|
|
6
6
|
"type": "module",
|
|
@@ -39,23 +39,20 @@
|
|
|
39
39
|
"./dist/styles.css": "./dist/styles.css",
|
|
40
40
|
"./theme.css": "./dist/theme.css",
|
|
41
41
|
"./dist/theme.css": "./dist/theme.css",
|
|
42
|
-
"./responsive-typography.css": "./dist/styles/responsive-typography.css"
|
|
42
|
+
"./responsive-typography.css": "./dist/styles/responsive-typography.css",
|
|
43
|
+
"./typography.css": "./dist/typography.css",
|
|
44
|
+
"./prose.css": "./dist/prose.css"
|
|
43
45
|
},
|
|
44
46
|
"scripts": {
|
|
45
47
|
"dev": "yarn watch",
|
|
46
48
|
"watch": "tsup --watch",
|
|
47
|
-
"build": "
|
|
49
|
+
"build": "tsup && yarn build:post",
|
|
48
50
|
"build:post": "postcss src/styles.css -o dist/styles.css && node scripts/copy-assets.js",
|
|
49
|
-
"tokens:build": "node style-dictionary.config.mjs && node scripts/generate-viz-runtime.js",
|
|
50
|
-
"tokens:build:tailwind": "node style-dictionary.config.mjs",
|
|
51
|
-
"tokens:watch": "nodemon --watch tokens --ext json --exec 'yarn tokens:build'",
|
|
52
|
-
"tokens:watch:tailwind": "nodemon --watch tokens --ext json --exec 'yarn tokens:build:tailwind'",
|
|
53
|
-
"tokens:validate": "node scripts/validate-tokens.js",
|
|
54
51
|
"build:yalc": "yarn build && npx yalc publish && npx yalc push",
|
|
55
52
|
"dev:yalc": "yarn build && npx yalc publish && npx yalc push && echo 'Package updated! Run in target project: yarn install && yarn dev'",
|
|
56
53
|
"dev:yalc:force": "yarn build && npx yalc publish && npx yalc push && echo 'Package updated! Run in target project: rm -rf .vite && yarn cache clean && yarn dev --force'",
|
|
57
54
|
"clean": "rm -rf dist",
|
|
58
|
-
"lint": "biome check src/",
|
|
55
|
+
"lint": "biome check src/ && yarn lint:action-variants",
|
|
59
56
|
"lint:quiet": "biome check --reporter=github src/",
|
|
60
57
|
"lint:fix": "biome check --write src/",
|
|
61
58
|
"typecheck": "tsc --noEmit -p tsconfig.prod.json",
|
|
@@ -66,7 +63,9 @@
|
|
|
66
63
|
"test:coverage": "vitest run --coverage",
|
|
67
64
|
"test:ui": "vitest --ui",
|
|
68
65
|
"storybook": "VITE_MAPBOX_ACCESS_TOKEN=pk.eyJ1IjoidmljdG9yLXRleHR1cmUiLCJhIjoiY2x1cXM5dnVqMDFvYTJrcWszbnZmdGo4cCJ9.uEu0gqmITLtBMKEVW0aFtA storybook dev -p ${STORYBOOK_PORT:-6010} --no-open",
|
|
69
|
-
"build-storybook": "storybook build"
|
|
66
|
+
"build-storybook": "storybook build",
|
|
67
|
+
"lint:font-colors": "node scripts/check-legacy-font-colors.mjs",
|
|
68
|
+
"lint:action-variants": "node scripts/check-legacy-action-variants.mjs"
|
|
70
69
|
},
|
|
71
70
|
"peerDependencies": {
|
|
72
71
|
"@hookform/resolvers": "^3.x || ^5.x",
|
|
@@ -93,7 +92,7 @@
|
|
|
93
92
|
"@dnd-kit/utilities": "^3.2.2",
|
|
94
93
|
"@phosphor-icons/react": "^2.1.7",
|
|
95
94
|
"@tanstack/react-virtual": "^3.13.12",
|
|
96
|
-
"@texturehq/edges-tokens": "^0.3
|
|
95
|
+
"@texturehq/edges-tokens": "^0.4.3",
|
|
97
96
|
"@tiptap/core": "^3.4.5",
|
|
98
97
|
"@tiptap/extension-link": "^3.4.5",
|
|
99
98
|
"@tiptap/pm": "^3.4.5",
|
|
@@ -169,7 +168,6 @@
|
|
|
169
168
|
"react-dom": "19.2.0",
|
|
170
169
|
"react-hook-form": "^7.53.0",
|
|
171
170
|
"storybook": "^8.6.14",
|
|
172
|
-
"style-dictionary": "^5.0.4",
|
|
173
171
|
"tailwindcss": "^4.1.14",
|
|
174
172
|
"tsup": "^8.0.2",
|
|
175
173
|
"typescript": "~5.9.2",
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
3
|
+
import { join, relative } from "node:path";
|
|
4
|
+
|
|
5
|
+
const root = process.cwd();
|
|
6
|
+
const scanRoots = ["src/components", "src/form", "src/docs", "templates", "README.md"];
|
|
7
|
+
const ignoredParts = new Set(["node_modules", "dist", "generated"]);
|
|
8
|
+
const extensions = new Set([".ts", ".tsx", ".md", ".mdx"]);
|
|
9
|
+
|
|
10
|
+
const legacyPropPatterns = [
|
|
11
|
+
/\b(?:Button|TextLink|Chip|Badge|Checkbox|Switch|RadioGroup|RadioCard|Tabs|ToggleButton|SegmentedControl|ChipInputField|TextAreaWithChips|DeviceMetaDisplay|SiteMetaDisplay|ContactMetaDisplay)\b[^\n>]*variant=[{]?\s*["'](?:default|brand)["']/,
|
|
12
|
+
/chipVariant=[{]?\s*["'](?:default|brand)["']/,
|
|
13
|
+
/linkVariant=[{]?\s*["'](?:default|brand)["']/,
|
|
14
|
+
/\b(?:Button|TextLink|Chip|Badge|Checkbox|Switch|RadioGroup|RadioCard|Tabs|ToggleButton|SegmentedControl|ChipInputField|TextAreaWithChips|DeviceMetaDisplay|SiteMetaDisplay|ContactMetaDisplay)\b[^\n]*(?:variant|chipVariant|linkVariant):\s*["'](?:default|brand)["']/,
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
const legacyClassPatterns = [];
|
|
18
|
+
|
|
19
|
+
const allowlistedFiles = new Set([
|
|
20
|
+
// Compatibility aliases intentionally remain in the primitives while consumers migrate.
|
|
21
|
+
"src/components/Button/Button.test.tsx",
|
|
22
|
+
"src/components/Chip/Chip.test.tsx",
|
|
23
|
+
"src/components/TextLink/TextLink.tsx",
|
|
24
|
+
"src/components/Button/Button.tsx",
|
|
25
|
+
"src/components/Chip/Chip.tsx",
|
|
26
|
+
"src/components/Badge/Badge.tsx",
|
|
27
|
+
"src/components/Checkbox/Checkbox.tsx",
|
|
28
|
+
"src/components/Switch/Switch.tsx",
|
|
29
|
+
"src/components/RadioGroup/RadioGroup.tsx",
|
|
30
|
+
"src/components/RadioCard/RadioCard.tsx",
|
|
31
|
+
"src/components/Tabs/Tabs.tsx",
|
|
32
|
+
"src/components/ToggleButton/ToggleButton.tsx",
|
|
33
|
+
"src/components/SegmentedControl/SegmentedControl.tsx",
|
|
34
|
+
"src/components/ChipInputField/ChipInputField.tsx",
|
|
35
|
+
"src/components/TextAreaWithChips/TextAreaWithChips.tsx",
|
|
36
|
+
"src/components/TextAreaWithChips/ChipTextArea.tsx",
|
|
37
|
+
"src/components/DeviceMetaDisplay/DeviceMetaDisplay.tsx",
|
|
38
|
+
"src/components/SiteMetaDisplay/SiteMetaDisplay.tsx",
|
|
39
|
+
"src/components/ContactMetaDisplay/ContactMetaDisplay.tsx",
|
|
40
|
+
"src/components/DataTable/cells/TextCell.tsx",
|
|
41
|
+
"src/components/DataTable/cells/SiteMetaCell.tsx",
|
|
42
|
+
"src/components/DataTable/cells/ContactMetaCell.tsx",
|
|
43
|
+
"src/components/DataTable/cells/DeviceMetaCell.tsx",
|
|
44
|
+
"src/components/DataTable/cells/cellUtils.tsx",
|
|
45
|
+
]);
|
|
46
|
+
|
|
47
|
+
function hasSupportedExtension(path) {
|
|
48
|
+
if (path.endsWith("README.md")) return true;
|
|
49
|
+
return [...extensions].some((extension) => path.endsWith(extension));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function walk(path, files = []) {
|
|
53
|
+
const rel = relative(root, path);
|
|
54
|
+
if (rel.split("/").some((part) => ignoredParts.has(part))) return files;
|
|
55
|
+
|
|
56
|
+
const stat = statSync(path);
|
|
57
|
+
if (stat.isDirectory()) {
|
|
58
|
+
for (const entry of readdirSync(path)) walk(join(path, entry), files);
|
|
59
|
+
return files;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (stat.isFile() && hasSupportedExtension(path)) files.push(path);
|
|
63
|
+
return files;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const violations = [];
|
|
67
|
+
for (const scanRoot of scanRoots) {
|
|
68
|
+
const path = join(root, scanRoot);
|
|
69
|
+
if (!existsSync(path)) continue;
|
|
70
|
+
|
|
71
|
+
for (const file of walk(path)) {
|
|
72
|
+
const rel = relative(root, file);
|
|
73
|
+
if (allowlistedFiles.has(rel)) continue;
|
|
74
|
+
|
|
75
|
+
const contents = readFileSync(file, "utf8");
|
|
76
|
+
const lines = contents.split(/\r?\n/);
|
|
77
|
+
lines.forEach((line, index) => {
|
|
78
|
+
if (legacyPropPatterns.some((pattern) => pattern.test(line))) {
|
|
79
|
+
violations.push(`${rel}:${index + 1}: legacy default/brand variant prop`);
|
|
80
|
+
}
|
|
81
|
+
if (legacyClassPatterns.some((pattern) => pattern.test(line))) {
|
|
82
|
+
violations.push(`${rel}:${index + 1}: legacy action brand/default styling class`);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (violations.length > 0) {
|
|
89
|
+
console.error(
|
|
90
|
+
"Legacy action variant vocabulary found. Use primary/secondary APIs and action-primary/action-secondary tokens instead.\n"
|
|
91
|
+
);
|
|
92
|
+
console.error(violations.join("\n"));
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
console.log("No legacy action variant vocabulary found.");
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readdirSync, readFileSync, statSync } from "node:fs";
|
|
3
|
+
import { join, relative } from "node:path";
|
|
4
|
+
|
|
5
|
+
const root = process.cwd();
|
|
6
|
+
const scanRoots = ["src/components", "src/form", "src/docs", "src/utils", "templates", "README.md"];
|
|
7
|
+
const ignoredParts = new Set(["node_modules", "dist", "generated"]);
|
|
8
|
+
|
|
9
|
+
const deprecatedPatterns = [
|
|
10
|
+
"text-text-heading",
|
|
11
|
+
"text-text-body",
|
|
12
|
+
"text-text-muted",
|
|
13
|
+
"text-text-caption",
|
|
14
|
+
"text-text-placeholder",
|
|
15
|
+
"text-text-onPrimary",
|
|
16
|
+
"text-text-onBrand",
|
|
17
|
+
"text-textFaint",
|
|
18
|
+
"--color-text-heading",
|
|
19
|
+
"--color-text-body",
|
|
20
|
+
"--color-text-muted",
|
|
21
|
+
"--color-text-caption",
|
|
22
|
+
"--color-text-placeholder",
|
|
23
|
+
"--color-text-onPrimary",
|
|
24
|
+
"--color-text-onBrand",
|
|
25
|
+
"--color-text-label",
|
|
26
|
+
"--theme-text-label",
|
|
27
|
+
"fill-text-body",
|
|
28
|
+
"fill-text-muted",
|
|
29
|
+
"fill-text-caption",
|
|
30
|
+
"fill-text-heading",
|
|
31
|
+
"bg-text-caption",
|
|
32
|
+
"bg-text-muted",
|
|
33
|
+
"bg-text-heading",
|
|
34
|
+
"border-text-heading",
|
|
35
|
+
"hover:bg-text-body",
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
const extensions = new Set([".ts", ".tsx", ".css", ".md", ".mdx"]);
|
|
39
|
+
const allowlistedFiles = new Set([
|
|
40
|
+
"src/styles/theme-light-override.css",
|
|
41
|
+
"theme.css",
|
|
42
|
+
]);
|
|
43
|
+
|
|
44
|
+
function hasSupportedExtension(path) {
|
|
45
|
+
if (path.endsWith("README.md")) return true;
|
|
46
|
+
return [...extensions].some((extension) => path.endsWith(extension));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function walk(path, files = []) {
|
|
50
|
+
const rel = relative(root, path);
|
|
51
|
+
if (rel.split("/").some((part) => ignoredParts.has(part))) return files;
|
|
52
|
+
|
|
53
|
+
const stat = statSync(path);
|
|
54
|
+
if (stat.isDirectory()) {
|
|
55
|
+
for (const entry of readdirSync(path)) {
|
|
56
|
+
walk(join(path, entry), files);
|
|
57
|
+
}
|
|
58
|
+
return files;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (stat.isFile() && hasSupportedExtension(path)) {
|
|
62
|
+
files.push(path);
|
|
63
|
+
}
|
|
64
|
+
return files;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const violations = [];
|
|
68
|
+
for (const scanRoot of scanRoots) {
|
|
69
|
+
const path = join(root, scanRoot);
|
|
70
|
+
for (const file of walk(path)) {
|
|
71
|
+
const rel = relative(root, file);
|
|
72
|
+
if (allowlistedFiles.has(rel)) continue;
|
|
73
|
+
|
|
74
|
+
const contents = readFileSync(file, "utf8");
|
|
75
|
+
const lines = contents.split(/\r?\n/);
|
|
76
|
+
lines.forEach((line, index) => {
|
|
77
|
+
for (const pattern of deprecatedPatterns) {
|
|
78
|
+
if (line.includes(pattern)) {
|
|
79
|
+
violations.push(`${rel}:${index + 1}: ${pattern}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (violations.length > 0) {
|
|
87
|
+
console.error("Deprecated font color tokens found. Use text-primary/text-secondary/text-inverse/text-disabled instead.\n");
|
|
88
|
+
console.error(violations.join("\n"));
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
console.log("No deprecated font color tokens found.");
|
package/scripts/copy-assets.js
CHANGED
|
@@ -9,6 +9,18 @@ try {
|
|
|
9
9
|
fs.copyFileSync("src/theme.css", "dist/theme.css");
|
|
10
10
|
console.log("✅ Theme CSS copied to dist");
|
|
11
11
|
|
|
12
|
+
// Expose generated typography utilities as @texturehq/edges/typography.css.
|
|
13
|
+
// @texturehq/edges/theme.css already imports them for full Edges consumers,
|
|
14
|
+
// while this standalone file gives lighter consumers the same role classes.
|
|
15
|
+
fs.copyFileSync("../edges-tokens/dist/typography.css", "dist/typography.css");
|
|
16
|
+
console.log("✅ Typography utilities copied to dist");
|
|
17
|
+
|
|
18
|
+
// Expose the editorial Prose CSS as @texturehq/edges/prose.css for
|
|
19
|
+
// lightweight consumers. Full Edges consumers already get it bundled via
|
|
20
|
+
// @texturehq/edges/styles.css → theme.css.
|
|
21
|
+
fs.copyFileSync("../edges-tokens/dist/prose.css", "dist/prose.css");
|
|
22
|
+
console.log("✅ Prose CSS copied to dist");
|
|
23
|
+
|
|
12
24
|
// Copy style layer files to dist
|
|
13
25
|
const styleFiles = [
|
|
14
26
|
"src/styles/animations.css",
|
|
@@ -20,13 +20,13 @@ The theme is imported via CSS:
|
|
|
20
20
|
## Usage Guidelines
|
|
21
21
|
|
|
22
22
|
- **Use semantic classes over arbitrary values**
|
|
23
|
-
- Prefer: `bg-brand-primary`, `text-text-
|
|
23
|
+
- Prefer: `bg-brand-primary`, `text-text-primary`, `text-text-secondary`, `p-md`, `rounded-lg`
|
|
24
24
|
- Avoid: `bg-[#444ae1]`, `text-[#333333]`, `p-[1rem]`, `rounded-[0.5rem]`
|
|
25
25
|
|
|
26
26
|
## Naming Conventions
|
|
27
27
|
|
|
28
28
|
- Brand colors: `brand-primary`, `brand-light`, `brand-dark`
|
|
29
|
-
- Text colors: `text-body`, `text-heading`, `text-muted`, `text-caption`
|
|
29
|
+
- Text colors: `text-primary`, `text-secondary`, `text-inverse`, `text-disabled` (legacy aliases: `text-body`, `text-heading`, `text-muted`, `text-caption`)
|
|
30
30
|
- Background colors: `background-body`, `background-surface`, `background-muted`
|
|
31
31
|
- Border colors: `border-default`, `border-focus`, `border-muted`
|
|
32
32
|
- Action colors: `action-primary`, `action-secondary`, `action-destructive`
|
|
@@ -39,9 +39,9 @@ The theme is imported via CSS:
|
|
|
39
39
|
|
|
40
40
|
```html
|
|
41
41
|
<!-- ✅ Good - Uses semantic classes -->
|
|
42
|
-
<div class="bg-brand-primary text-text-
|
|
43
|
-
<h2 class="text-text-
|
|
44
|
-
<p class="text-text-
|
|
42
|
+
<div class="bg-brand-primary text-text-inverse p-md rounded-lg shadow-md">
|
|
43
|
+
<h2 class="text-text-primary text-lg font-medium">Title</h2>
|
|
44
|
+
<p class="text-text-primary text-base">Content</p>
|
|
45
45
|
</div>
|
|
46
46
|
|
|
47
47
|
<!-- ❌ Avoid - Uses arbitrary values -->
|
|
@@ -20,13 +20,13 @@ The theme is imported via CSS:
|
|
|
20
20
|
## Usage Guidelines
|
|
21
21
|
|
|
22
22
|
- **Use semantic classes over arbitrary values**
|
|
23
|
-
- Prefer: `bg-brand-primary`, `text-text-
|
|
23
|
+
- Prefer: `bg-brand-primary`, `text-text-primary`, `text-text-secondary`, `p-md`, `rounded-lg`
|
|
24
24
|
- Avoid: `bg-[#444ae1]`, `text-[#333333]`, `p-[1rem]`, `rounded-[0.5rem]`
|
|
25
25
|
|
|
26
26
|
## Naming Conventions
|
|
27
27
|
|
|
28
28
|
- Brand colors: `brand-primary`, `brand-light`, `brand-dark`
|
|
29
|
-
- Text colors: `text-body`, `text-heading`, `text-muted`, `text-caption`
|
|
29
|
+
- Text colors: `text-primary`, `text-secondary`, `text-inverse`, `text-disabled` (legacy aliases: `text-body`, `text-heading`, `text-muted`, `text-caption`)
|
|
30
30
|
- Background colors: `background-body`, `background-surface`, `background-muted`
|
|
31
31
|
- Border colors: `border-default`, `border-focus`, `border-muted`
|
|
32
32
|
- Action colors: `action-primary`, `action-secondary`, `action-destructive`
|
|
@@ -39,9 +39,9 @@ The theme is imported via CSS:
|
|
|
39
39
|
|
|
40
40
|
```html
|
|
41
41
|
<!-- ✅ Good - Uses semantic classes -->
|
|
42
|
-
<div class="bg-brand-primary text-text-
|
|
43
|
-
<h2 class="text-text-
|
|
44
|
-
<p class="text-text-
|
|
42
|
+
<div class="bg-brand-primary text-text-inverse p-md rounded-lg shadow-md">
|
|
43
|
+
<h2 class="text-text-primary text-lg font-medium">Title</h2>
|
|
44
|
+
<p class="text-text-primary text-base">Content</p>
|
|
45
45
|
</div>
|
|
46
46
|
|
|
47
47
|
<!-- ❌ Avoid - Uses arbitrary values -->
|
|
@@ -20,13 +20,13 @@ The theme is imported via CSS:
|
|
|
20
20
|
## Usage Guidelines
|
|
21
21
|
|
|
22
22
|
- **Use semantic classes over arbitrary values**
|
|
23
|
-
- Prefer: `bg-brand-primary`, `text-text-
|
|
23
|
+
- Prefer: `bg-brand-primary`, `text-text-primary`, `text-text-secondary`, `p-md`, `rounded-lg`
|
|
24
24
|
- Avoid: `bg-[#444ae1]`, `text-[#333333]`, `p-[1rem]`, `rounded-[0.5rem]`
|
|
25
25
|
|
|
26
26
|
## Naming Conventions
|
|
27
27
|
|
|
28
28
|
- Brand colors: `brand-primary`, `brand-light`, `brand-dark`
|
|
29
|
-
- Text colors: `text-body`, `text-heading`, `text-muted`, `text-caption`
|
|
29
|
+
- Text colors: `text-primary`, `text-secondary`, `text-inverse`, `text-disabled` (legacy aliases: `text-body`, `text-heading`, `text-muted`, `text-caption`)
|
|
30
30
|
- Background colors: `background-body`, `background-surface`, `background-muted`
|
|
31
31
|
- Border colors: `border-default`, `border-focus`, `border-muted`
|
|
32
32
|
- Action colors: `action-primary`, `action-secondary`, `action-destructive`
|
|
@@ -39,9 +39,9 @@ The theme is imported via CSS:
|
|
|
39
39
|
|
|
40
40
|
```html
|
|
41
41
|
<!-- ✅ Good - Uses semantic classes -->
|
|
42
|
-
<div class="bg-brand-primary text-text-
|
|
43
|
-
<h2 class="text-text-
|
|
44
|
-
<p class="text-text-
|
|
42
|
+
<div class="bg-brand-primary text-text-inverse p-md rounded-lg shadow-md">
|
|
43
|
+
<h2 class="text-text-primary text-lg font-medium">Title</h2>
|
|
44
|
+
<p class="text-text-primary text-base">Content</p>
|
|
45
45
|
</div>
|
|
46
46
|
|
|
47
47
|
<!-- ❌ Avoid - Uses arbitrary values -->
|