@wireweave/core 1.0.0-beta.20260107130355
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 +351 -0
- package/dist/index.cjs +56106 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +252 -0
- package/dist/index.d.ts +252 -0
- package/dist/index.js +55985 -0
- package/dist/index.js.map +1 -0
- package/dist/parser.cjs +5417 -0
- package/dist/parser.cjs.map +1 -0
- package/dist/parser.d.cts +89 -0
- package/dist/parser.d.ts +89 -0
- package/dist/parser.js +5387 -0
- package/dist/parser.js.map +1 -0
- package/dist/renderer.cjs +50244 -0
- package/dist/renderer.cjs.map +1 -0
- package/dist/renderer.d.cts +497 -0
- package/dist/renderer.d.ts +497 -0
- package/dist/renderer.js +50202 -0
- package/dist/renderer.js.map +1 -0
- package/dist/types-DtovIYS6.d.cts +419 -0
- package/dist/types-DtovIYS6.d.ts +419 -0
- package/package.json +59 -0
- package/src/ast/guards.ts +361 -0
- package/src/ast/index.ts +9 -0
- package/src/ast/types.ts +661 -0
- package/src/ast/utils.ts +238 -0
- package/src/grammar/wireframe.peggy +677 -0
- package/src/icons/lucide-icons.ts +46422 -0
- package/src/index.ts +20 -0
- package/src/parser/generated-parser.js +5199 -0
- package/src/parser/index.ts +214 -0
- package/src/renderer/html/base.ts +186 -0
- package/src/renderer/html/components.ts +1092 -0
- package/src/renderer/html/index.ts +1608 -0
- package/src/renderer/html/layout.ts +392 -0
- package/src/renderer/index.ts +143 -0
- package/src/renderer/styles-components.ts +1232 -0
- package/src/renderer/styles.ts +382 -0
- package/src/renderer/svg/index.ts +1050 -0
- package/src/renderer/types.ts +173 -0
- package/src/types/index.ts +138 -0
- package/src/viewport/index.ts +17 -0
- package/src/viewport/presets.ts +181 -0
package/README.md
ADDED
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="logo.svg" width="128" height="128" alt="Wireweave Core">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">@wireweave/core</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">Core parser and renderers for Wireweave DSL</p>
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @wireweave/core
|
|
13
|
+
# or
|
|
14
|
+
pnpm add @wireweave/core
|
|
15
|
+
# or
|
|
16
|
+
yarn add @wireweave/core
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Quick Start
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { parse, render, renderToSvg, renderToHtml } from '@wireweave/core';
|
|
23
|
+
|
|
24
|
+
const source = `
|
|
25
|
+
page "Hello" {
|
|
26
|
+
card p=4 {
|
|
27
|
+
title "Welcome"
|
|
28
|
+
text "Hello, wireweave!"
|
|
29
|
+
button "Get Started" primary
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
`;
|
|
33
|
+
|
|
34
|
+
// Parse DSL to AST
|
|
35
|
+
const doc = parse(source);
|
|
36
|
+
|
|
37
|
+
// Render to HTML + CSS
|
|
38
|
+
const { html, css } = render(doc);
|
|
39
|
+
|
|
40
|
+
// Render to complete HTML document
|
|
41
|
+
const fullHtml = renderToHtml(doc);
|
|
42
|
+
|
|
43
|
+
// Render to SVG
|
|
44
|
+
const { svg, width, height } = renderToSvg(doc);
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## API Reference
|
|
48
|
+
|
|
49
|
+
### Parser
|
|
50
|
+
|
|
51
|
+
#### `parse(source: string): WireframeDocument`
|
|
52
|
+
|
|
53
|
+
Parses wireframe DSL source code into an AST (Abstract Syntax Tree).
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { parse } from '@wireweave/core';
|
|
57
|
+
|
|
58
|
+
const doc = parse('page { text "Hello" }');
|
|
59
|
+
console.log(doc.children[0].type); // 'Page'
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Throws**: `ParseError` if the source contains syntax errors.
|
|
63
|
+
|
|
64
|
+
### HTML Renderer
|
|
65
|
+
|
|
66
|
+
#### `render(doc: WireframeDocument, options?: RenderOptions): RenderResult`
|
|
67
|
+
|
|
68
|
+
Renders the AST to HTML and CSS.
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
import { parse, render } from '@wireweave/core';
|
|
72
|
+
|
|
73
|
+
const doc = parse('page { card { text "Hello" } }');
|
|
74
|
+
const { html, css } = render(doc);
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Options**:
|
|
78
|
+
| Option | Type | Default | Description |
|
|
79
|
+
|--------|------|---------|-------------|
|
|
80
|
+
| `theme` | `'light' \| 'dark'` | `'light'` | Color theme |
|
|
81
|
+
|
|
82
|
+
**Returns**: `{ html: string, css: string }`
|
|
83
|
+
|
|
84
|
+
#### `renderToHtml(doc: WireframeDocument, options?: RenderOptions): string`
|
|
85
|
+
|
|
86
|
+
Renders the AST to a complete HTML document with embedded CSS.
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import { parse, renderToHtml } from '@wireweave/core';
|
|
90
|
+
|
|
91
|
+
const doc = parse('page "Test" { text "Hello" }');
|
|
92
|
+
const html = renderToHtml(doc, { theme: 'dark' });
|
|
93
|
+
// Returns: <!DOCTYPE html><html>...</html>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### SVG Renderer
|
|
97
|
+
|
|
98
|
+
#### `renderToSvg(doc: WireframeDocument, options?: SvgRenderOptions): SvgRenderResult`
|
|
99
|
+
|
|
100
|
+
Renders the AST to SVG format.
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
import { parse, renderToSvg } from '@wireweave/core';
|
|
104
|
+
|
|
105
|
+
const doc = parse('page { button "Click" primary }');
|
|
106
|
+
const { svg, width, height } = renderToSvg(doc, {
|
|
107
|
+
width: 800,
|
|
108
|
+
padding: 20
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**Options**:
|
|
113
|
+
| Option | Type | Default | Description |
|
|
114
|
+
|--------|------|---------|-------------|
|
|
115
|
+
| `width` | `number` | `1200` | SVG width in pixels |
|
|
116
|
+
| `padding` | `number` | `24` | Padding around content |
|
|
117
|
+
| `theme` | `'light' \| 'dark'` | `'light'` | Color theme |
|
|
118
|
+
|
|
119
|
+
**Returns**: `{ svg: string, width: number, height: number }`
|
|
120
|
+
|
|
121
|
+
### AST Utilities
|
|
122
|
+
|
|
123
|
+
#### `walk(node: ASTNode, callback: WalkCallback): void`
|
|
124
|
+
|
|
125
|
+
Traverses the AST tree depth-first.
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
import { parse } from '@wireweave/core';
|
|
129
|
+
import { walk } from '@wireweave/core/ast';
|
|
130
|
+
|
|
131
|
+
const doc = parse('page { card { text "A" text "B" } }');
|
|
132
|
+
walk(doc.children[0], (node, parent, depth) => {
|
|
133
|
+
console.log(`${node.type} at depth ${depth}`);
|
|
134
|
+
});
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
#### `find(node: ASTNode, predicate: (n: ASTNode) => boolean): ASTNode | undefined`
|
|
138
|
+
|
|
139
|
+
Finds the first node matching the predicate.
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
import { find } from '@wireweave/core/ast';
|
|
143
|
+
|
|
144
|
+
const button = find(doc.children[0], n => n.type === 'Button');
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
#### `findAll(node: ASTNode, predicate: (n: ASTNode) => boolean): ASTNode[]`
|
|
148
|
+
|
|
149
|
+
Finds all nodes matching the predicate.
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
import { findAll } from '@wireweave/core/ast';
|
|
153
|
+
|
|
154
|
+
const buttons = findAll(doc.children[0], n => n.type === 'Button');
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
#### `findByType<T>(node: ASTNode, type: string): T[]`
|
|
158
|
+
|
|
159
|
+
Finds all nodes of a specific type.
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
import { findByType } from '@wireweave/core/ast';
|
|
163
|
+
import type { ButtonNode } from '@wireweave/core';
|
|
164
|
+
|
|
165
|
+
const buttons = findByType<ButtonNode>(doc.children[0], 'Button');
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
#### `countNodes(node: ASTNode): number`
|
|
169
|
+
|
|
170
|
+
Counts all nodes in the tree.
|
|
171
|
+
|
|
172
|
+
#### `getMaxDepth(node: ASTNode): number`
|
|
173
|
+
|
|
174
|
+
Returns the maximum nesting depth.
|
|
175
|
+
|
|
176
|
+
#### `cloneNode<T>(node: T): T`
|
|
177
|
+
|
|
178
|
+
Creates a deep copy of a node.
|
|
179
|
+
|
|
180
|
+
## Type Definitions
|
|
181
|
+
|
|
182
|
+
### WireframeDocument
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
interface WireframeDocument {
|
|
186
|
+
type: 'Document';
|
|
187
|
+
children: PageNode[];
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### PageNode
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
interface PageNode {
|
|
195
|
+
type: 'Page';
|
|
196
|
+
title?: string;
|
|
197
|
+
children: ASTNode[];
|
|
198
|
+
// ... spacing attributes
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Common Node Properties
|
|
203
|
+
|
|
204
|
+
All nodes include:
|
|
205
|
+
- `type: string` - Node type (e.g., 'Button', 'Card')
|
|
206
|
+
- `location?: Location` - Source location info
|
|
207
|
+
- Spacing: `p`, `px`, `py`, `pt`, `pr`, `pb`, `pl`, `m`, `mx`, `my`, `mt`, `mr`, `mb`, `ml`
|
|
208
|
+
- Size: `w`, `h`
|
|
209
|
+
|
|
210
|
+
### Component-Specific Properties
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
// Button
|
|
214
|
+
interface ButtonNode {
|
|
215
|
+
type: 'Button';
|
|
216
|
+
content: string;
|
|
217
|
+
primary?: boolean;
|
|
218
|
+
secondary?: boolean;
|
|
219
|
+
outline?: boolean;
|
|
220
|
+
ghost?: boolean;
|
|
221
|
+
danger?: boolean;
|
|
222
|
+
disabled?: boolean;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Input
|
|
226
|
+
interface InputNode {
|
|
227
|
+
type: 'Input';
|
|
228
|
+
label?: string;
|
|
229
|
+
placeholder?: string;
|
|
230
|
+
inputType?: 'text' | 'email' | 'password' | 'search' | 'tel' | 'url' | 'number';
|
|
231
|
+
required?: boolean;
|
|
232
|
+
disabled?: boolean;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Card
|
|
236
|
+
interface CardNode {
|
|
237
|
+
type: 'Card';
|
|
238
|
+
title?: string;
|
|
239
|
+
children: ASTNode[];
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Col
|
|
243
|
+
interface ColNode {
|
|
244
|
+
type: 'Col';
|
|
245
|
+
span?: number;
|
|
246
|
+
sm?: number;
|
|
247
|
+
md?: number;
|
|
248
|
+
lg?: number;
|
|
249
|
+
xl?: number;
|
|
250
|
+
children: ASTNode[];
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## DSL Syntax Reference
|
|
255
|
+
|
|
256
|
+
### Page Structure
|
|
257
|
+
|
|
258
|
+
```
|
|
259
|
+
page "Title" {
|
|
260
|
+
header { }
|
|
261
|
+
main { }
|
|
262
|
+
footer { }
|
|
263
|
+
sidebar { }
|
|
264
|
+
aside { }
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Layout
|
|
269
|
+
|
|
270
|
+
```
|
|
271
|
+
// Grid columns (12-column system)
|
|
272
|
+
row {
|
|
273
|
+
col span=6 { } // 50% width
|
|
274
|
+
col span=6 { } // 50% width
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Responsive breakpoints
|
|
278
|
+
col span=12 sm=6 md=4 lg=3 xl=2 { }
|
|
279
|
+
|
|
280
|
+
// Flexbox
|
|
281
|
+
row flex justify=center align=center gap=4 wrap { }
|
|
282
|
+
// justify: start, end, center, between, around, evenly
|
|
283
|
+
// align: start, end, center, stretch, baseline
|
|
284
|
+
// direction: row, row-reverse, column, column-reverse
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Spacing Scale
|
|
288
|
+
|
|
289
|
+
Values use a 4px base: `1 = 4px`, `2 = 8px`, `4 = 16px`, etc.
|
|
290
|
+
|
|
291
|
+
```
|
|
292
|
+
card p=4 m=2 { } // padding: 16px, margin: 8px
|
|
293
|
+
button mt=4 mb=2 // margin-top: 16px, margin-bottom: 8px
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### Size
|
|
297
|
+
|
|
298
|
+
```
|
|
299
|
+
image w=400 h=300 // width: 400px, height: 300px
|
|
300
|
+
card w=full // width: 100%
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Comments
|
|
304
|
+
|
|
305
|
+
```
|
|
306
|
+
// Single line comment
|
|
307
|
+
|
|
308
|
+
/* Multi-line
|
|
309
|
+
comment */
|
|
310
|
+
|
|
311
|
+
page {
|
|
312
|
+
// Comment inside block
|
|
313
|
+
text "Hello"
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
## Error Handling
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
import { parse } from '@wireweave/core';
|
|
321
|
+
|
|
322
|
+
try {
|
|
323
|
+
const doc = parse('page { invalid }');
|
|
324
|
+
} catch (error) {
|
|
325
|
+
if (error.name === 'ParseError') {
|
|
326
|
+
console.log(error.message);
|
|
327
|
+
// "Syntax error at line 1, column 8: ..."
|
|
328
|
+
console.log(error.location);
|
|
329
|
+
// { start: { line: 1, column: 8 }, end: { ... } }
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## Browser Support
|
|
335
|
+
|
|
336
|
+
The core library works in both Node.js and browser environments. For browser usage:
|
|
337
|
+
|
|
338
|
+
```html
|
|
339
|
+
<script type="module">
|
|
340
|
+
import { parse, render } from '@wireweave/core';
|
|
341
|
+
|
|
342
|
+
const doc = parse('page { text "Hello" }');
|
|
343
|
+
const { html, css } = render(doc);
|
|
344
|
+
|
|
345
|
+
document.body.innerHTML = `<style>${css}</style>${html}`;
|
|
346
|
+
</script>
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
## License
|
|
350
|
+
|
|
351
|
+
MIT
|