@texturehq/edges 0.1.8 → 1.0.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@texturehq/edges",
3
- "version": "0.1.8",
3
+ "version": "1.0.1",
4
4
  "author": "Nicholas Brown <nick@texturehq.com>",
5
5
  "description": "A shared component library for Texture",
6
6
  "type": "module",
@@ -16,9 +16,15 @@
16
16
  "exports": {
17
17
  ".": {
18
18
  "types": "./dist/index.d.ts",
19
+ "react-server": "./dist/server.js",
19
20
  "import": "./dist/index.js",
20
21
  "default": "./dist/index.js"
21
22
  },
23
+ "./server": {
24
+ "types": "./dist/server.d.ts",
25
+ "import": "./dist/server.js",
26
+ "default": "./dist/server.js"
27
+ },
22
28
  "./styles.css": "./dist/styles.css",
23
29
  "./dist/styles.css": "./dist/styles.css",
24
30
  "./theme.css": "./dist/theme.css",
@@ -27,14 +33,22 @@
27
33
  "scripts": {
28
34
  "dev": "yarn watch",
29
35
  "watch": "tsup --watch",
30
- "build": "tsup",
36
+ "build": "yarn tokens:build && tsup && yarn build:post",
37
+ "build:post": "postcss src/styles.css -o dist/styles.css && node scripts/copy-assets.js && node scripts/generate-components-manifest.js",
38
+ "tokens:build": "node style-dictionary.config.mjs",
39
+ "tokens:build:tailwind": "node style-dictionary.config.mjs",
40
+ "tokens:watch": "nodemon --watch tokens --ext json --exec 'yarn tokens:build'",
41
+ "tokens:watch:tailwind": "nodemon --watch tokens --ext json --exec 'yarn tokens:build:tailwind'",
42
+ "tokens:validate": "node scripts/validate-tokens.js",
31
43
  "build:yalc": "yarn build && npx yalc publish && npx yalc push",
32
44
  "dev:yalc": "yarn build && npx yalc publish && npx yalc push && echo 'Package updated! Run in target project: yarn install && yarn dev'",
33
45
  "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'",
34
46
  "clean": "rm -rf dist",
35
- "lint": "eslint --ext .ts,.tsx src/",
36
- "lint:quiet": "eslint --ext .ts,.tsx src/ --quiet",
37
- "lint:fix": "eslint --fix --ext .ts,.tsx src/",
47
+ "lint": "biome check src/",
48
+ "lint:quiet": "biome check --reporter=github src/",
49
+ "lint:fix": "biome check --write src/",
50
+ "format": "biome format --write src/",
51
+ "format:check": "biome format src/",
38
52
  "test": "vitest run",
39
53
  "test:watch": "vitest",
40
54
  "test:coverage": "vitest run --coverage",
@@ -44,50 +58,73 @@
44
58
  "postinstall": "node scripts/setup-cursor-rules.js || echo \"! setup-cursor-rules: non-fatal error\""
45
59
  },
46
60
  "peerDependencies": {
61
+ "next": "*",
47
62
  "react": "^18.2.0",
48
63
  "react-dom": "^18.2.0"
49
64
  },
50
65
  "dependencies": {
51
66
  "@phosphor-icons/react": "^2.1.7",
67
+ "@tiptap/core": "^3.4.5",
68
+ "@tiptap/extension-link": "^3.4.5",
69
+ "@tiptap/pm": "^3.4.5",
70
+ "@tiptap/react": "^3.4.5",
71
+ "@tiptap/starter-kit": "^3.4.5",
72
+ "@types/react-map-gl": "6.1.6",
73
+ "@visx/axis": "^3.10.1",
74
+ "@visx/curve": "^3.3.0",
75
+ "@visx/event": "^3.3.0",
76
+ "@visx/responsive": "^3.10.2",
77
+ "@visx/scale": "^3.5.0",
78
+ "@visx/shape": "^3.5.0",
79
+ "@visx/tooltip": "^3.3.0",
80
+ "ace-builds": "^1.43.3",
81
+ "d3-array": "^3.2.4",
82
+ "file-saver": "^2.0.5",
52
83
  "filestack-react": "^6.0.0",
53
- "lucide-react": "^0.487.0",
84
+ "framer-motion": "^12.23.18",
85
+ "lucide-react": "^0.544.0",
54
86
  "luxon": "^3.4.4",
87
+ "mapbox-gl": "3.7.0",
55
88
  "next-intl": "^4.0.2",
89
+ "papaparse": "^5.5.3",
56
90
  "react-ace": "^14.0.1",
57
91
  "react-aria-components": "^1.7.1",
92
+ "react-map-gl": "7.1.7",
58
93
  "react-stately": "^3.35.0",
59
94
  "tailwind-merge": "^3.2.0"
60
95
  },
61
96
  "devDependencies": {
62
- "@storybook/addon-essentials": "^8.6.12",
63
- "@storybook/addon-interactions": "^8.6.12",
97
+ "@biomejs/biome": "^2.2.4",
98
+ "@storybook/addon-essentials": "^8.6.14",
99
+ "@storybook/addon-interactions": "^8.6.14",
64
100
  "@storybook/addon-styling-webpack": "^1.0.1",
65
- "@storybook/blocks": "^8.6.12",
66
- "@storybook/react": "^8.6.12",
67
- "@storybook/react-vite": "^8.6.12",
68
- "@storybook/test": "^8.6.12",
101
+ "@storybook/addon-themes": "^8.6.14",
102
+ "@storybook/blocks": "^8.6.14",
103
+ "@storybook/react": "^8.6.14",
104
+ "@storybook/react-vite": "^8.6.14",
105
+ "@storybook/test": "^8.6.14",
69
106
  "@tailwindcss/postcss": "^4.1.4",
70
107
  "@testing-library/dom": "^10.4.0",
71
108
  "@testing-library/jest-dom": "^6.4.2",
72
109
  "@testing-library/react": "^14.2.1",
73
110
  "@testing-library/user-event": "^14.5.2",
74
111
  "@types/file-saver": "^2.0.7",
112
+ "@types/luxon": "^3.7.1",
75
113
  "@types/node": "^20.11.30",
76
- "@types/papaparse": "^5.3.15",
114
+ "@types/papaparse": "^5.3.16",
77
115
  "@types/react": "^18.2.67",
78
116
  "@types/react-dom": "^18.2.22",
79
117
  "@vitejs/plugin-react": "^4.2.1",
80
118
  "@vitest/coverage-v8": "^3.1.1",
81
119
  "@vitest/ui": "^3.1.1",
82
120
  "autoprefixer": "^10.4.19",
83
- "eslint": "^8.57.0",
84
- "eslint-plugin-storybook": "^0.12.0",
85
121
  "jsdom": "^24.0.0",
86
122
  "postcss": "^8.4.35",
87
123
  "postcss-cli": "^11.0.0",
88
124
  "react": "^18.2.0",
89
125
  "react-dom": "^18.2.0",
90
- "storybook": "^8.6.12",
126
+ "storybook": "^8.6.14",
127
+ "style-dictionary": "^5.0.4",
91
128
  "tailwindcss": "^4.1.3",
92
129
  "tsup": "^8.0.2",
93
130
  "typescript": "~5.9.2",
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env node
2
+
3
+ import fs from "fs";
4
+
5
+ console.log("šŸ“ Copying assets to dist...");
6
+
7
+ try {
8
+ // Copy theme.css to dist
9
+ fs.copyFileSync("src/theme.css", "dist/theme.css");
10
+ console.log("āœ… Theme CSS copied to dist");
11
+
12
+ // Copy style layer files to dist
13
+ const styleFiles = ["src/styles/animations.css", "src/styles/computed.css", "src/styles/utilities.css"];
14
+
15
+ // Create styles directory in dist
16
+ if (!fs.existsSync("dist/styles")) {
17
+ fs.mkdirSync("dist/styles", { recursive: true });
18
+ }
19
+
20
+ styleFiles.forEach((file) => {
21
+ if (fs.existsSync(file)) {
22
+ const filename = file.split("/").pop();
23
+ fs.copyFileSync(file, `dist/styles/${filename}`);
24
+ console.log(`āœ… Style file ${filename} copied to dist/styles`);
25
+ }
26
+ });
27
+
28
+ // Copy generated token CSS to dist (if they exist)
29
+ const tokenFiles = ["src/generated/tailwind-tokens-light.css", "src/generated/tailwind-tokens-dark.css"];
30
+
31
+ // Create generated directory in dist
32
+ if (!fs.existsSync("dist/generated")) {
33
+ fs.mkdirSync("dist/generated", { recursive: true });
34
+ }
35
+
36
+ tokenFiles.forEach((file) => {
37
+ if (fs.existsSync(file)) {
38
+ const filename = file.split("/").pop();
39
+ fs.copyFileSync(file, `dist/generated/${filename}`);
40
+ console.log(`āœ… Token CSS ${filename} copied to dist/generated`);
41
+ }
42
+ });
43
+
44
+ console.log("šŸŽ‰ All assets copied successfully!");
45
+ } catch (error) {
46
+ console.error("āŒ Failed to copy assets:", error.message);
47
+ process.exitCode = 1;
48
+ }
@@ -0,0 +1,178 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Validates design tokens against DTCG (Design Tokens Community Group) spec
5
+ * https://tr.designtokens.org/format/
6
+ */
7
+
8
+ import { readFileSync, readdirSync, statSync } from 'fs';
9
+ import { join, extname } from 'path';
10
+
11
+ const TOKENS_DIR = './tokens';
12
+ const REQUIRED_SCHEMA = 'https://tr.designtokens.org/format/0.1/';
13
+
14
+ // DTCG spec required properties for different token types
15
+ const TOKEN_TYPE_REQUIREMENTS = {
16
+ color: ['$value'],
17
+ dimension: ['$value'],
18
+ fontFamily: ['$value'],
19
+ fontWeight: ['$value'],
20
+ duration: ['$value'],
21
+ number: ['$value'],
22
+ // Add more as needed
23
+ };
24
+
25
+ // Valid top-level properties
26
+ const VALID_TOP_LEVEL = ['$schema', '$name', '$description', '$type', '$value', '$extensions'];
27
+
28
+ // Validation results
29
+ const errors = [];
30
+ const warnings = [];
31
+ const successes = [];
32
+
33
+ /**
34
+ * Get all JSON files recursively
35
+ */
36
+ function getTokenFiles(dir) {
37
+ const files = [];
38
+ const items = readdirSync(dir);
39
+
40
+ for (const item of items) {
41
+ const path = join(dir, item);
42
+ const stat = statSync(path);
43
+
44
+ if (stat.isDirectory()) {
45
+ files.push(...getTokenFiles(path));
46
+ } else if (extname(path) === '.json') {
47
+ files.push(path);
48
+ }
49
+ }
50
+
51
+ return files;
52
+ }
53
+
54
+ /**
55
+ * Validate a single token
56
+ */
57
+ function validateToken(token, path, parentType = null) {
58
+ const type = token.$type || parentType;
59
+
60
+ // Check for $value
61
+ if (!token.$value && !hasNestedTokens(token)) {
62
+ errors.push(`${path}: Token missing $value property`);
63
+ return;
64
+ }
65
+
66
+ // If has $value, validate based on type
67
+ if (token.$value && type) {
68
+ const requirements = TOKEN_TYPE_REQUIREMENTS[type];
69
+ if (requirements) {
70
+ for (const req of requirements) {
71
+ if (!(req in token)) {
72
+ errors.push(`${path}: Token of type "${type}" missing required property "${req}"`);
73
+ }
74
+ }
75
+ }
76
+ }
77
+
78
+ // Check for $description (recommended but not required)
79
+ if (!token.$description && token.$value) {
80
+ warnings.push(`${path}: Token missing $description (recommended)`);
81
+ }
82
+
83
+ // Validate nested tokens
84
+ for (const key in token) {
85
+ if (!key.startsWith('$') && typeof token[key] === 'object') {
86
+ validateToken(token[key], `${path}.${key}`, type);
87
+ }
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Check if object has nested tokens
93
+ */
94
+ function hasNestedTokens(obj) {
95
+ for (const key in obj) {
96
+ if (!key.startsWith('$') && typeof obj[key] === 'object') {
97
+ return true;
98
+ }
99
+ }
100
+ return false;
101
+ }
102
+
103
+ /**
104
+ * Validate a token file
105
+ */
106
+ function validateFile(filepath) {
107
+ console.log(`\nValidating: ${filepath}`);
108
+
109
+ try {
110
+ const content = readFileSync(filepath, 'utf8');
111
+ const tokens = JSON.parse(content);
112
+
113
+ // Check for $schema
114
+ if (!tokens.$schema) {
115
+ warnings.push(`${filepath}: Missing $schema declaration`);
116
+ } else if (!tokens.$schema.includes('designtokens.org')) {
117
+ warnings.push(`${filepath}: Non-standard schema: ${tokens.$schema}`);
118
+ }
119
+
120
+ // Check for $name
121
+ if (!tokens.$name) {
122
+ warnings.push(`${filepath}: Missing $name property (recommended)`);
123
+ }
124
+
125
+ // Validate all tokens
126
+ for (const key in tokens) {
127
+ if (!key.startsWith('$') && typeof tokens[key] === 'object') {
128
+ validateToken(tokens[key], `${filepath}:${key}`, tokens.$type);
129
+ }
130
+ }
131
+
132
+ successes.push(`${filepath}: Valid DTCG token file`);
133
+
134
+ } catch (error) {
135
+ errors.push(`${filepath}: ${error.message}`);
136
+ }
137
+ }
138
+
139
+ /**
140
+ * Main validation
141
+ */
142
+ function main() {
143
+ console.log('šŸ” DTCG Token Validation\n');
144
+ console.log('==========================');
145
+
146
+ const files = getTokenFiles(TOKENS_DIR);
147
+ console.log(`Found ${files.length} token files\n`);
148
+
149
+ for (const file of files) {
150
+ validateFile(file);
151
+ }
152
+
153
+ // Report results
154
+ console.log('\n==========================');
155
+ console.log('šŸ“Š Validation Results\n');
156
+
157
+ if (successes.length > 0) {
158
+ console.log('āœ… Valid Files:');
159
+ successes.forEach(s => console.log(` ${s}`));
160
+ }
161
+
162
+ if (warnings.length > 0) {
163
+ console.log('\nāš ļø Warnings:');
164
+ warnings.forEach(w => console.log(` ${w}`));
165
+ }
166
+
167
+ if (errors.length > 0) {
168
+ console.log('\nāŒ Errors:');
169
+ errors.forEach(e => console.log(` ${e}`));
170
+ process.exit(1);
171
+ } else {
172
+ console.log('\n✨ All tokens are DTCG compliant!');
173
+ }
174
+ }
175
+
176
+ // Run validation
177
+ main();
178
+
@@ -53,7 +53,7 @@ The theme is imported via CSS:
53
53
 
54
54
  ## Dark Mode
55
55
 
56
- All colors automatically adapt to dark mode when `.dark` class is present.
56
+ All colors automatically adapt to dark mode when `.theme-dark` class is present.
57
57
 
58
58
  ## Available Variables
59
59
 
@@ -52,7 +52,7 @@ The theme is imported via CSS:
52
52
  ```
53
53
 
54
54
  ## Dark Mode
55
- All colors automatically adapt to dark mode when `.dark` class is present.
55
+ All colors automatically adapt to dark mode when `.theme-dark` class is present.
56
56
 
57
57
  ## Available Variables
58
58
  All CSS variables from the theme file are automatically available. The theme includes: