@texturehq/edges 1.24.2 → 1.25.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/README.md +9 -0
- package/dist/{colors-BYkYTR7E.d.ts → colors-Bw6dREwE.d.ts} +10 -1
- package/dist/{colors-ZfVYHdic.d.cts → colors-nZbxzpnU.d.cts} +10 -1
- package/dist/components.manifest.json +404 -313
- package/dist/form/index.cjs +1 -1
- package/dist/form/index.cjs.map +1 -1
- package/dist/form/index.js +1 -1
- package/dist/form/index.js.map +1 -1
- package/dist/index.cjs +14 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +374 -3
- package/dist/index.d.ts +374 -3
- package/dist/index.js +14 -8
- package/dist/index.js.map +1 -1
- package/dist/rhf/index.cjs +1 -1
- package/dist/rhf/index.cjs.map +1 -1
- 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 +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +2 -2
- package/dist/server.js.map +1 -1
- package/dist/styles.css +85 -13
- package/dist/utilities.manifest.json +1 -2
- package/package.json +2 -2
- package/scripts/generate-edges-docs.js +17 -6
- package/scripts/setup-cursor-rules.js +79 -31
- package/templates/codex-rules/codex.md +85 -0
package/dist/styles.css
CHANGED
|
@@ -1982,6 +1982,9 @@
|
|
|
1982
1982
|
.max-h-\[300px\] {
|
|
1983
1983
|
max-height: 300px;
|
|
1984
1984
|
}
|
|
1985
|
+
.max-h-\[500px\] {
|
|
1986
|
+
max-height: 500px;
|
|
1987
|
+
}
|
|
1985
1988
|
.min-h-0 {
|
|
1986
1989
|
min-height: var(--spacing-0);
|
|
1987
1990
|
}
|
|
@@ -2178,6 +2181,9 @@
|
|
|
2178
2181
|
.max-w-7xl {
|
|
2179
2182
|
max-width: var(--container-7xl);
|
|
2180
2183
|
}
|
|
2184
|
+
.max-w-\[90vw\] {
|
|
2185
|
+
max-width: 90vw;
|
|
2186
|
+
}
|
|
2181
2187
|
.max-w-\[150px\] {
|
|
2182
2188
|
max-width: 150px;
|
|
2183
2189
|
}
|
|
@@ -3693,9 +3699,6 @@
|
|
|
3693
3699
|
.p-\[1rem\] {
|
|
3694
3700
|
padding: 1rem;
|
|
3695
3701
|
}
|
|
3696
|
-
.\!px-1 {
|
|
3697
|
-
padding-inline: var(--spacing-1) !important;
|
|
3698
|
-
}
|
|
3699
3702
|
.\!px-2 {
|
|
3700
3703
|
padding-inline: var(--spacing-2) !important;
|
|
3701
3704
|
}
|
|
@@ -3828,9 +3831,6 @@
|
|
|
3828
3831
|
.pt-8 {
|
|
3829
3832
|
padding-top: var(--spacing-8);
|
|
3830
3833
|
}
|
|
3831
|
-
.pt-\[60px\] {
|
|
3832
|
-
padding-top: 60px;
|
|
3833
|
-
}
|
|
3834
3834
|
.pr-0 {
|
|
3835
3835
|
padding-right: var(--spacing-0);
|
|
3836
3836
|
}
|
|
@@ -3942,6 +3942,10 @@
|
|
|
3942
3942
|
.font-mono {
|
|
3943
3943
|
font-family: var(--font-mono);
|
|
3944
3944
|
}
|
|
3945
|
+
.\!text-base {
|
|
3946
|
+
font-size: var(--text-base) !important;
|
|
3947
|
+
line-height: var(--tw-leading, var(--text-base--line-height)) !important;
|
|
3948
|
+
}
|
|
3945
3949
|
.text-2xl {
|
|
3946
3950
|
font-size: var(--text-2xl);
|
|
3947
3951
|
line-height: var(--tw-leading, var(--text-2xl--line-height));
|
|
@@ -4793,6 +4797,11 @@
|
|
|
4793
4797
|
}
|
|
4794
4798
|
}
|
|
4795
4799
|
}
|
|
4800
|
+
.group-focus-visible\:opacity-100 {
|
|
4801
|
+
&:is(:where(.group):focus-visible *) {
|
|
4802
|
+
opacity: 100%;
|
|
4803
|
+
}
|
|
4804
|
+
}
|
|
4796
4805
|
.group-disabled\:text-gray-200 {
|
|
4797
4806
|
&:is(:where(.group):disabled *) {
|
|
4798
4807
|
color: var(--color-gray-200);
|
|
@@ -4803,6 +4812,11 @@
|
|
|
4803
4812
|
color: var(--color-text-disabled);
|
|
4804
4813
|
}
|
|
4805
4814
|
}
|
|
4815
|
+
.group-data-\[focused\]\:opacity-100 {
|
|
4816
|
+
&:is(:where(.group)[data-focused] *) {
|
|
4817
|
+
opacity: 100%;
|
|
4818
|
+
}
|
|
4819
|
+
}
|
|
4806
4820
|
.peer-checked\/category\:block {
|
|
4807
4821
|
&:is(:where(.peer\/category):checked ~ *) {
|
|
4808
4822
|
display: block;
|
|
@@ -5136,6 +5150,13 @@
|
|
|
5136
5150
|
}
|
|
5137
5151
|
}
|
|
5138
5152
|
}
|
|
5153
|
+
.hover\:bg-background-surface {
|
|
5154
|
+
&:hover {
|
|
5155
|
+
@media (hover: hover) {
|
|
5156
|
+
background-color: var(--color-background-surface);
|
|
5157
|
+
}
|
|
5158
|
+
}
|
|
5159
|
+
}
|
|
5139
5160
|
.hover\:bg-black\/10 {
|
|
5140
5161
|
&:hover {
|
|
5141
5162
|
@media (hover: hover) {
|
|
@@ -5259,13 +5280,6 @@
|
|
|
5259
5280
|
}
|
|
5260
5281
|
}
|
|
5261
5282
|
}
|
|
5262
|
-
.hover\:bg-transparent {
|
|
5263
|
-
&:hover {
|
|
5264
|
-
@media (hover: hover) {
|
|
5265
|
-
background-color: transparent;
|
|
5266
|
-
}
|
|
5267
|
-
}
|
|
5268
|
-
}
|
|
5269
5283
|
.hover\:bg-white\/10 {
|
|
5270
5284
|
&:hover {
|
|
5271
5285
|
@media (hover: hover) {
|
|
@@ -5484,6 +5498,11 @@
|
|
|
5484
5498
|
outline-style: none;
|
|
5485
5499
|
}
|
|
5486
5500
|
}
|
|
5501
|
+
.focus-visible\:bg-brand-light {
|
|
5502
|
+
&:focus-visible {
|
|
5503
|
+
background-color: var(--color-brand-light);
|
|
5504
|
+
}
|
|
5505
|
+
}
|
|
5487
5506
|
.focus-visible\:ring-0 {
|
|
5488
5507
|
&:focus-visible {
|
|
5489
5508
|
--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
|
|
@@ -5942,11 +5961,21 @@
|
|
|
5942
5961
|
padding-bottom: var(--spacing-0);
|
|
5943
5962
|
}
|
|
5944
5963
|
}
|
|
5964
|
+
.md\:absolute {
|
|
5965
|
+
@media (width >= 48rem) {
|
|
5966
|
+
position: absolute;
|
|
5967
|
+
}
|
|
5968
|
+
}
|
|
5945
5969
|
.md\:relative {
|
|
5946
5970
|
@media (width >= 48rem) {
|
|
5947
5971
|
position: relative;
|
|
5948
5972
|
}
|
|
5949
5973
|
}
|
|
5974
|
+
.md\:left-1\/2 {
|
|
5975
|
+
@media (width >= 48rem) {
|
|
5976
|
+
left: calc(1/2 * 100%);
|
|
5977
|
+
}
|
|
5978
|
+
}
|
|
5950
5979
|
.md\:order-1 {
|
|
5951
5980
|
@media (width >= 48rem) {
|
|
5952
5981
|
order: 1;
|
|
@@ -6072,6 +6101,11 @@
|
|
|
6072
6101
|
display: none;
|
|
6073
6102
|
}
|
|
6074
6103
|
}
|
|
6104
|
+
.md\:inline {
|
|
6105
|
+
@media (width >= 48rem) {
|
|
6106
|
+
display: inline;
|
|
6107
|
+
}
|
|
6108
|
+
}
|
|
6075
6109
|
.md\:h-10 {
|
|
6076
6110
|
@media (width >= 48rem) {
|
|
6077
6111
|
height: var(--spacing-10);
|
|
@@ -6117,6 +6151,11 @@
|
|
|
6117
6151
|
width: auto;
|
|
6118
6152
|
}
|
|
6119
6153
|
}
|
|
6154
|
+
.md\:max-w-4xl {
|
|
6155
|
+
@media (width >= 48rem) {
|
|
6156
|
+
max-width: var(--container-4xl);
|
|
6157
|
+
}
|
|
6158
|
+
}
|
|
6120
6159
|
.md\:max-w-none {
|
|
6121
6160
|
@media (width >= 48rem) {
|
|
6122
6161
|
max-width: none;
|
|
@@ -6142,6 +6181,12 @@
|
|
|
6142
6181
|
flex-shrink: 0;
|
|
6143
6182
|
}
|
|
6144
6183
|
}
|
|
6184
|
+
.md\:-translate-x-1\/2 {
|
|
6185
|
+
@media (width >= 48rem) {
|
|
6186
|
+
--tw-translate-x: calc(calc(1/2 * 100%) * -1);
|
|
6187
|
+
translate: var(--tw-translate-x) var(--tw-translate-y);
|
|
6188
|
+
}
|
|
6189
|
+
}
|
|
6145
6190
|
.md\:translate-x-0 {
|
|
6146
6191
|
@media (width >= 48rem) {
|
|
6147
6192
|
--tw-translate-x: var(--spacing-0);
|
|
@@ -6247,6 +6292,11 @@
|
|
|
6247
6292
|
}
|
|
6248
6293
|
}
|
|
6249
6294
|
}
|
|
6295
|
+
.md\:px-4 {
|
|
6296
|
+
@media (width >= 48rem) {
|
|
6297
|
+
padding-inline: var(--spacing-4);
|
|
6298
|
+
}
|
|
6299
|
+
}
|
|
6250
6300
|
.md\:px-6 {
|
|
6251
6301
|
@media (width >= 48rem) {
|
|
6252
6302
|
padding-inline: var(--spacing-6);
|
|
@@ -6267,6 +6317,28 @@
|
|
|
6267
6317
|
padding-bottom: var(--spacing-28);
|
|
6268
6318
|
}
|
|
6269
6319
|
}
|
|
6320
|
+
.md\:text-sm {
|
|
6321
|
+
@media (width >= 48rem) {
|
|
6322
|
+
font-size: var(--text-sm);
|
|
6323
|
+
line-height: var(--tw-leading, var(--text-sm--line-height));
|
|
6324
|
+
}
|
|
6325
|
+
}
|
|
6326
|
+
.md\:text-xs {
|
|
6327
|
+
@media (width >= 48rem) {
|
|
6328
|
+
font-size: var(--text-xs);
|
|
6329
|
+
line-height: var(--tw-leading, var(--text-xs--line-height));
|
|
6330
|
+
}
|
|
6331
|
+
}
|
|
6332
|
+
.md\:\!text-\[length\:var\(--control-text-md\)\] {
|
|
6333
|
+
@media (width >= 48rem) {
|
|
6334
|
+
font-size: var(--control-text-md) !important;
|
|
6335
|
+
}
|
|
6336
|
+
}
|
|
6337
|
+
.md\:\!text-\[length\:var\(--control-text-sm\)\] {
|
|
6338
|
+
@media (width >= 48rem) {
|
|
6339
|
+
font-size: var(--control-text-sm) !important;
|
|
6340
|
+
}
|
|
6341
|
+
}
|
|
6270
6342
|
.lg\:sticky {
|
|
6271
6343
|
@media (width >= 64rem) {
|
|
6272
6344
|
position: sticky;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@texturehq/edges",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.25.1",
|
|
4
4
|
"author": "Nicholas Brown <nick@texturehq.com>",
|
|
5
5
|
"description": "A shared component library for Texture",
|
|
6
6
|
"type": "module",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"test:watch": "vitest",
|
|
66
66
|
"test:coverage": "vitest run --coverage",
|
|
67
67
|
"test:ui": "vitest --ui",
|
|
68
|
-
"storybook": "VITE_MAPBOX_ACCESS_TOKEN=pk.eyJ1IjoidmljdG9yLXRleHR1cmUiLCJhIjoiY2x1cXM5dnVqMDFvYTJrcWszbnZmdGo4cCJ9.uEu0gqmITLtBMKEVW0aFtA storybook dev -p 6010 --no-open",
|
|
68
|
+
"storybook": "VITE_MAPBOX_ACCESS_TOKEN=pk.eyJ1IjoidmljdG9yLXRleHR1cmUiLCJhIjoiY2x1cXM5dnVqMDFvYTJrcWszbnZmdGo4cCJ9.uEu0gqmITLtBMKEVW0aFtA storybook dev -p ${STORYBOOK_PORT:-6010} --no-open",
|
|
69
69
|
"build-storybook": "storybook build",
|
|
70
70
|
"postinstall": "node scripts/setup-cursor-rules.js || echo \"! setup-cursor-rules: non-fatal error\""
|
|
71
71
|
},
|
|
@@ -37,6 +37,12 @@ function ensureDir(dir) {
|
|
|
37
37
|
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
function escapeMarkdownTableCell(text) {
|
|
41
|
+
// Only escape backslashes since the text will be wrapped in backticks (inline code).
|
|
42
|
+
// Pipes and backticks don't need escaping inside inline code spans.
|
|
43
|
+
return text.replace(/\\/g, "\\\\");
|
|
44
|
+
}
|
|
45
|
+
|
|
40
46
|
function writeFile(filePath, content) {
|
|
41
47
|
ensureDir(path.dirname(filePath));
|
|
42
48
|
fs.writeFileSync(filePath, content, "utf8");
|
|
@@ -242,6 +248,8 @@ function generateComponentsManifest() {
|
|
|
242
248
|
|
|
243
249
|
// Extract props
|
|
244
250
|
const props = extractProps(content, name);
|
|
251
|
+
// Sort props alphabetically for deterministic output
|
|
252
|
+
props.sort((a, b) => a.name.localeCompare(b.name));
|
|
245
253
|
|
|
246
254
|
// Extract Storybook metadata
|
|
247
255
|
const storyFile = findStorybookFile(relPath);
|
|
@@ -285,7 +293,8 @@ function generateComponentsManifest() {
|
|
|
285
293
|
|
|
286
294
|
const manifest = {
|
|
287
295
|
version: PACKAGE_VERSION,
|
|
288
|
-
generatedAt
|
|
296
|
+
// generatedAt removed to prevent unnecessary git churn
|
|
297
|
+
// Use version field to track which package version generated this
|
|
289
298
|
components: components,
|
|
290
299
|
categories: categories,
|
|
291
300
|
};
|
|
@@ -405,7 +414,8 @@ function generateUtilitiesManifest() {
|
|
|
405
414
|
|
|
406
415
|
const manifest = {
|
|
407
416
|
version: PACKAGE_VERSION,
|
|
408
|
-
generatedAt
|
|
417
|
+
// generatedAt removed to prevent unnecessary git churn
|
|
418
|
+
// Use version field to track which package version generated this
|
|
409
419
|
categories: {},
|
|
410
420
|
};
|
|
411
421
|
|
|
@@ -588,7 +598,8 @@ This document provides a complete reference of all ${components.length} componen
|
|
|
588
598
|
content += `| Prop | Type |\n`;
|
|
589
599
|
content += `|------|------|\n`;
|
|
590
600
|
for (const prop of component.props) {
|
|
591
|
-
|
|
601
|
+
const safeType = escapeMarkdownTableCell(prop.type);
|
|
602
|
+
content += `| \`${prop.name}\` | \`${safeType}\` |\n`;
|
|
592
603
|
}
|
|
593
604
|
content += `\n`;
|
|
594
605
|
}
|
|
@@ -823,7 +834,8 @@ function generateEdgesReadme(componentsManifest, utilitiesManifest) {
|
|
|
823
834
|
const componentCount = componentsManifest.components.length;
|
|
824
835
|
const categoryCount = Object.keys(componentsManifest.categories).length;
|
|
825
836
|
const hookCount = utilitiesManifest.categories.hooks?.utilities.length || 0;
|
|
826
|
-
|
|
837
|
+
// Use version instead of timestamp to avoid git churn
|
|
838
|
+
const version = componentsManifest.version || PACKAGE_VERSION;
|
|
827
839
|
|
|
828
840
|
let utilityCount = 0;
|
|
829
841
|
for (const cat in utilitiesManifest.categories) {
|
|
@@ -916,8 +928,7 @@ When building UI in \`apps/dashboard\`, reference:
|
|
|
916
928
|
|
|
917
929
|
---
|
|
918
930
|
|
|
919
|
-
**Package Version:** ${
|
|
920
|
-
**Generated:** ${generatedAt}
|
|
931
|
+
**Package Version:** ${version}
|
|
921
932
|
`;
|
|
922
933
|
|
|
923
934
|
writeFile(path.join(DOCS_AI_EDGES, "README.md"), content);
|
|
@@ -42,6 +42,10 @@ const setupCursorRules = () => {
|
|
|
42
42
|
path.dirname(new URL(import.meta.url).pathname),
|
|
43
43
|
"../templates/claude-rules"
|
|
44
44
|
);
|
|
45
|
+
const codexTemplatesDir = path.join(
|
|
46
|
+
path.dirname(new URL(import.meta.url).pathname),
|
|
47
|
+
"../templates/codex-rules"
|
|
48
|
+
);
|
|
45
49
|
const cursorDir = path.join(cwd, ".cursor");
|
|
46
50
|
const rulesDir = path.join(cursorDir, "rules");
|
|
47
51
|
|
|
@@ -80,31 +84,8 @@ const setupCursorRules = () => {
|
|
|
80
84
|
.readdirSync(claudeTemplatesDir)
|
|
81
85
|
.filter((file) => file.endsWith(".md"));
|
|
82
86
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
// Create .claude directory for namespaced files
|
|
87
|
-
const claudeDir = path.join(cwd, ".claude");
|
|
88
|
-
fs.mkdirSync(claudeDir, { recursive: true });
|
|
89
|
-
|
|
90
|
-
claudeTemplateFiles.forEach((file) => {
|
|
91
|
-
const templatePath = path.join(claudeTemplatesDir, file);
|
|
92
|
-
// Namespace the file as edges-specific
|
|
93
|
-
const namespacedFileName = "edges.md";
|
|
94
|
-
const targetPath = path.join(claudeDir, namespacedFileName);
|
|
95
|
-
|
|
96
|
-
// Always copy to ensure latest version
|
|
97
|
-
fs.copyFileSync(templatePath, targetPath);
|
|
98
|
-
claudeCopiedCount++;
|
|
99
|
-
console.log(`✅ Updated .claude/${namespacedFileName} for Claude`);
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
if (claudeCopiedCount > 0) {
|
|
103
|
-
console.log(
|
|
104
|
-
`🤖 Added ${claudeCopiedCount} namespaced Claude rule(s) for @texturehq/edges design system`
|
|
105
|
-
);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
87
|
+
// Claude template processing is done later with component injection (lines 221-236)
|
|
88
|
+
// so we don't need to copy templates here
|
|
108
89
|
}
|
|
109
90
|
|
|
110
91
|
// Also render edges-components.mdc from manifest when present
|
|
@@ -112,9 +93,17 @@ const setupCursorRules = () => {
|
|
|
112
93
|
path.join(cwd, "node_modules/@texturehq/edges/dist/components.manifest.json"),
|
|
113
94
|
].find((p) => fs.existsSync(p));
|
|
114
95
|
|
|
96
|
+
// Track what we generated for summary
|
|
97
|
+
let cursorComponentCount = 0;
|
|
98
|
+
let claudeComponentCount = 0;
|
|
99
|
+
let codexComponentCount = 0;
|
|
100
|
+
let packageVersion = "unknown";
|
|
101
|
+
|
|
115
102
|
if (manifestPath) {
|
|
116
103
|
try {
|
|
117
104
|
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
|
|
105
|
+
packageVersion = manifest.version || "unknown";
|
|
106
|
+
// Don't set counts yet - only set them when files are actually written
|
|
118
107
|
|
|
119
108
|
// Generate Cursor components list
|
|
120
109
|
const cursorLines = [
|
|
@@ -150,7 +139,9 @@ const setupCursorRules = () => {
|
|
|
150
139
|
|
|
151
140
|
if (c.props && c.props.length) {
|
|
152
141
|
cursorLines.push("**Props:**");
|
|
153
|
-
|
|
142
|
+
// Sort props alphabetically for deterministic output
|
|
143
|
+
const sortedProps = [...c.props].sort((a, b) => a.name.localeCompare(b.name));
|
|
144
|
+
sortedProps.forEach((prop) => {
|
|
154
145
|
cursorLines.push(`- \`${prop.name}: ${prop.type}\``);
|
|
155
146
|
});
|
|
156
147
|
cursorLines.push("");
|
|
@@ -161,8 +152,9 @@ const setupCursorRules = () => {
|
|
|
161
152
|
const cursorOutPath = path.join(rulesDir, "edges-components.mdc");
|
|
162
153
|
|
|
163
154
|
fs.writeFileSync(cursorOutPath, cursorLines.join("\n"), "utf8");
|
|
155
|
+
cursorComponentCount = manifest.components?.length || 0;
|
|
164
156
|
console.log(
|
|
165
|
-
`✅ Wrote .cursor/rules/edges-components.mdc from manifest (${
|
|
157
|
+
`✅ Wrote .cursor/rules/edges-components.mdc from manifest (${cursorComponentCount} components)`
|
|
166
158
|
);
|
|
167
159
|
|
|
168
160
|
// Generate Claude components list
|
|
@@ -192,7 +184,9 @@ const setupCursorRules = () => {
|
|
|
192
184
|
|
|
193
185
|
if (c.props && c.props.length) {
|
|
194
186
|
claudeLines.push("**Props:**");
|
|
195
|
-
|
|
187
|
+
// Sort props alphabetically for deterministic output
|
|
188
|
+
const sortedProps = [...c.props].sort((a, b) => a.name.localeCompare(b.name));
|
|
189
|
+
sortedProps.forEach((prop) => {
|
|
196
190
|
claudeLines.push(`- \`${prop.name}: ${prop.type}\``);
|
|
197
191
|
});
|
|
198
192
|
claudeLines.push("");
|
|
@@ -212,18 +206,72 @@ const setupCursorRules = () => {
|
|
|
212
206
|
|
|
213
207
|
const claudeOutPath = path.join(claudeDir, "edges.md");
|
|
214
208
|
fs.writeFileSync(claudeOutPath, claudeContent, "utf8");
|
|
209
|
+
claudeComponentCount = manifest.components?.length || 0;
|
|
210
|
+
console.log(
|
|
211
|
+
`✅ Wrote .claude/edges.md with components list (${claudeComponentCount} components)`
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Generate Codex docs using template
|
|
216
|
+
const codexTemplatePath = path.join(codexTemplatesDir, "codex.md");
|
|
217
|
+
if (fs.existsSync(codexTemplatePath)) {
|
|
218
|
+
const codexDir = path.join(cwd, ".codex");
|
|
219
|
+
fs.mkdirSync(codexDir, { recursive: true });
|
|
220
|
+
|
|
221
|
+
let codexContent = fs.readFileSync(codexTemplatePath, "utf8");
|
|
222
|
+
codexContent = codexContent.split("{{COMPONENTS_LIST}}").join(claudeLines.join("\n"));
|
|
223
|
+
|
|
224
|
+
const codexOutPath = path.join(codexDir, "edges.md");
|
|
225
|
+
fs.writeFileSync(codexOutPath, codexContent, "utf8");
|
|
226
|
+
codexComponentCount = manifest.components?.length || 0;
|
|
215
227
|
console.log(
|
|
216
|
-
`✅ Wrote .
|
|
228
|
+
`✅ Wrote .codex/edges.md with components list (${codexComponentCount} components)`
|
|
217
229
|
);
|
|
218
230
|
}
|
|
219
231
|
} catch (err) {
|
|
220
232
|
console.log("⚠️ Failed to read components.manifest.json:", err.message);
|
|
233
|
+
console.log(" This might mean:");
|
|
234
|
+
console.log(" 1. @texturehq/edges is not installed");
|
|
235
|
+
console.log(" 2. Package is installed but not built");
|
|
236
|
+
console.log(" 3. Try: cd packages/edges && yarn build");
|
|
221
237
|
}
|
|
222
238
|
}
|
|
239
|
+
|
|
240
|
+
// Return summary for outer handler
|
|
241
|
+
return {
|
|
242
|
+
cursorCount: cursorComponentCount,
|
|
243
|
+
claudeCount: claudeComponentCount,
|
|
244
|
+
codexCount: codexComponentCount,
|
|
245
|
+
version: packageVersion
|
|
246
|
+
};
|
|
223
247
|
};
|
|
224
248
|
|
|
225
249
|
try {
|
|
226
|
-
setupCursorRules();
|
|
250
|
+
const result = setupCursorRules();
|
|
251
|
+
|
|
252
|
+
// Print summary if we generated context
|
|
253
|
+
if (result && (result.cursorCount > 0 || result.claudeCount > 0 || result.codexCount > 0)) {
|
|
254
|
+
console.log("\n" + "=".repeat(60));
|
|
255
|
+
console.log("🤖 Agent Context Generated Successfully");
|
|
256
|
+
console.log("=".repeat(60));
|
|
257
|
+
|
|
258
|
+
if (result.cursorCount > 0) {
|
|
259
|
+
console.log(` ✅ Cursor: ${result.cursorCount} components (v${result.version})`);
|
|
260
|
+
}
|
|
261
|
+
if (result.claudeCount > 0) {
|
|
262
|
+
console.log(` ✅ Claude: ${result.claudeCount} components (v${result.version})`);
|
|
263
|
+
}
|
|
264
|
+
if (result.codexCount > 0) {
|
|
265
|
+
console.log(` ✅ Codex: ${result.codexCount} components (v${result.version})`);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
console.log(` 📦 Source: @texturehq/edges v${result.version}`);
|
|
269
|
+
console.log("\n💡 Tip: Reload your AI agent to use the latest context");
|
|
270
|
+
console.log(" Cursor: Cmd+Shift+P → 'Developer: Reload Window'");
|
|
271
|
+
console.log(" Claude: Restart Claude Desktop / Reload project");
|
|
272
|
+
console.log("=".repeat(60) + "\n");
|
|
273
|
+
}
|
|
227
274
|
} catch (err) {
|
|
228
|
-
console.warn("setup-cursor-rules error:", err);
|
|
275
|
+
console.warn("⚠️ setup-cursor-rules error:", err);
|
|
276
|
+
console.warn(" Agent context may not be available");
|
|
229
277
|
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# @texturehq/edges Design System
|
|
2
|
+
|
|
3
|
+
This project uses the @texturehq/edges design system with Tailwind 4. The theme CSS file contains all design system variables that automatically become available as Tailwind classes.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
The theme is imported via CSS:
|
|
8
|
+
```css
|
|
9
|
+
@import "@texturehq/edges/theme.css";
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## How It Works
|
|
13
|
+
|
|
14
|
+
- CSS variables in the theme file automatically become Tailwind classes
|
|
15
|
+
- `--color-brand-primary` becomes available as `bg-brand-primary`, `text-brand-primary`, `border-brand-primary`, etc.
|
|
16
|
+
- `--spacing-md` becomes available as `p-md`, `m-md`, `gap-md`, etc.
|
|
17
|
+
- `--text-lg` becomes available as `text-lg`
|
|
18
|
+
- `--radius-lg` becomes available as `rounded-lg`
|
|
19
|
+
|
|
20
|
+
## Usage Guidelines
|
|
21
|
+
|
|
22
|
+
- **Use semantic classes over arbitrary values**
|
|
23
|
+
- Prefer: `bg-brand-primary`, `text-text-body`, `p-md`, `rounded-lg`
|
|
24
|
+
- Avoid: `bg-[#444ae1]`, `text-[#333333]`, `p-[1rem]`, `rounded-[0.5rem]`
|
|
25
|
+
|
|
26
|
+
## Naming Conventions
|
|
27
|
+
|
|
28
|
+
- Brand colors: `brand-primary`, `brand-light`, `brand-dark`
|
|
29
|
+
- Text colors: `text-body`, `text-heading`, `text-muted`, `text-caption`
|
|
30
|
+
- Background colors: `background-body`, `background-surface`, `background-muted`
|
|
31
|
+
- Border colors: `border-default`, `border-focus`, `border-muted`
|
|
32
|
+
- Action colors: `action-primary`, `action-secondary`, `action-destructive`
|
|
33
|
+
- Feedback colors: `feedback-success`, `feedback-error`, `feedback-warning`, `feedback-info`
|
|
34
|
+
- Spacing: `xs`, `sm`, `md`, `lg`, `xl`, `2xl`, `3xl`, `4xl`
|
|
35
|
+
- Typography: `xs`, `sm`, `base`, `lg`, `xl`, `2xl`, `3xl`, `4xl`
|
|
36
|
+
- Border radius: `xs`, `sm`, `md`, `lg`, `xl`, `2xl`, `3xl`, `4xl`
|
|
37
|
+
|
|
38
|
+
## Examples
|
|
39
|
+
|
|
40
|
+
```html
|
|
41
|
+
<!-- ✅ Good - Uses semantic classes -->
|
|
42
|
+
<div class="bg-brand-primary text-text-on-primary p-md rounded-lg shadow-md">
|
|
43
|
+
<h2 class="text-text-heading text-lg font-medium">Title</h2>
|
|
44
|
+
<p class="text-text-body text-base">Content</p>
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
<!-- ❌ Avoid - Uses arbitrary values -->
|
|
48
|
+
<div class="bg-[#444ae1] text-[#ffffff] p-[1rem] rounded-[0.5rem]">
|
|
49
|
+
<h2 class="text-[#111827] text-[1.125rem] font-[500]">Title</h2>
|
|
50
|
+
<p class="text-[#333333] text-[1rem]">Content</p>
|
|
51
|
+
</div>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Dark Mode
|
|
55
|
+
|
|
56
|
+
All colors automatically adapt to dark mode when `.theme-dark` class is present.
|
|
57
|
+
|
|
58
|
+
## Available Variables
|
|
59
|
+
|
|
60
|
+
All CSS variables from the theme file are automatically available. The theme includes:
|
|
61
|
+
- Complete color system (brand, text, background, border, action, feedback, device states, data visualization)
|
|
62
|
+
- Spacing scale
|
|
63
|
+
- Typography scale
|
|
64
|
+
- Border radius scale
|
|
65
|
+
- Shadow system
|
|
66
|
+
- Animation definitions
|
|
67
|
+
- Form control specifications
|
|
68
|
+
|
|
69
|
+
## Available Components
|
|
70
|
+
|
|
71
|
+
The following components are available from @texturehq/edges:
|
|
72
|
+
|
|
73
|
+
{{COMPONENTS_LIST}}
|
|
74
|
+
|
|
75
|
+
## Import Examples
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
// Import from package root
|
|
79
|
+
import { Button, TextField, Card } from "@texturehq/edges";
|
|
80
|
+
|
|
81
|
+
// Import individual components for tree-shaking
|
|
82
|
+
import { Button } from "@texturehq/edges/components/Button";
|
|
83
|
+
import { TextField } from "@texturehq/edges/components/TextField";
|
|
84
|
+
import { Card } from "@texturehq/edges/components/Card";
|
|
85
|
+
```
|