framer-dalton 0.0.5 → 0.0.7

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.
@@ -1,3 +1,29 @@
1
+ ---
2
+ name: framer
3
+ description: "Single entry point for Framer tasks. Mandatory precondition: run `npx framer-dalton@latest setup` and let it complete BEFORE loading this skill."
4
+ ---
5
+
6
+ If you didn't run this command before loading the skill, run it now:
7
+
8
+ ```bash
9
+ npx framer-dalton@latest setup
10
+ ```
11
+
12
+ ## Capabilities
13
+
14
+ What you can do with the Framer CLI:
15
+
16
+ - **Canvas Editing** For design tasks - creating or editing pages, sections, layouts, recreating designs from screenshots, etc.
17
+ - **CMS**: Create, read, update, delete collections and items. Sync external databases.
18
+ - **Styles**: Manage color and text styles. Sync design systems.
19
+ - **Code Components**: Create, edit, type-check, and add custom React components to the canvas.
20
+ - **Assets**: Upload and manage images and files.
21
+ - **Localization**: Manage translations programmatically.
22
+ - **Data**: Store metadata on nodes and projects for plugin state.
23
+ - **Screenshots**: Capture node screenshots as PNG/JPEG. Export nodes as SVG.
24
+ - **Publishing**: Publish projects, manage deployments, track changes.
25
+ - **Low-level Node APIs**: Create and modify individual nodes. Only use these for targeted, surgical edits to specific nodes - not for building pages or layouts.
26
+
1
27
  ## CLI Usage
2
28
 
3
29
  ### Required Workflow
@@ -27,24 +53,46 @@ npx framer-dalton docs Collection.getItems # What are the parameters and return
27
53
  Only after checking docs:
28
54
 
29
55
  ```bash
30
- npx framer-dalton -s 1 -e "state.items = await collection.getItems(); console.log(state.items.length)"
56
+ npx framer-dalton -s 1 -e "state.collections = await framer.getCollections(); console.log(state.collections.length)"
31
57
  ```
32
58
 
33
59
  #### 4. Store results in `state`
34
60
 
35
61
  Always save results you'll need again. Don't repeat API calls.
36
62
 
37
- ---
38
-
39
63
  **Do not skip step 2.** The examples below are patterns only - always verify current signatures with `npx framer-dalton docs`.
40
64
 
41
- ### Communication style
65
+ ## Core Usage Principles
42
66
 
43
- Be concise. Don't narrate implementation details like field IDs, escaping, or internal steps. Just do the work and report what was accomplished in user-facing terms.
67
+ - Be concise. Don't narrate implementation details like field IDs, escaping, or internal steps. Just do the work and report what was accomplished in user-facing terms.
68
+ - Use `framer.*` for plugin API calls. Top-level methods are not globals.
44
69
 
45
- ---
70
+ ## Context Variables
71
+
72
+ - `framer` - Connected Framer Server API instance
73
+ - `state` - Object persisted between calls within your session
74
+ - `console` - For output (`console.log`, `console.error`)
75
+ - `require` - Sandboxed Node.js modules: fs, path, url, crypto, buffer, util, os
76
+ - Standard globals: `fetch`, `Buffer`, `URL`, `crypto`, `setTimeout`
77
+
78
+ **Note:** `fs` operations are sandboxed to cwd, /tmp, and os.tmpdir().
79
+
80
+ ## Use `state` to Avoid Repeated Calls
81
+
82
+ **Always store results in `state` when you'll need them again.** API calls are slow - don't repeat them.
83
+
84
+ ```bash
85
+ # First call: fetch and store
86
+ npx framer-dalton -s 1 -e "state.collections = await framer.getCollections()"
87
+
88
+ # Later calls: reuse from state
89
+ npx framer-dalton -s 1 -e "const team = state.collections.find(c => c.name === 'Team')"
90
+ npx framer-dalton -s 1 -e "state.teamItems = await state.collections.find(c => c.name === 'Team').getItems()"
91
+ ```
92
+
93
+ Store anything you'll reference again.
46
94
 
47
- ### Session Management
95
+ ## Session Management
48
96
 
49
97
  Each session maintains a persistent connection to a Framer project. Use sessions to:
50
98
 
@@ -67,13 +115,19 @@ List active sessions:
67
115
  npx framer-dalton session list
68
116
  ```
69
117
 
70
- ### Execute Code
118
+ ## Canvas Editing
119
+
120
+ For design tasks, do not try to build or restyle pages with low-level node APIs. Instead, load the dynamically created project-scoped canvas skill and follow its `readProjectForAgent` plus `applyAgentChanges` flow.
121
+
122
+ After session creation, load the dynamically created project-scoped skill `framer-canvas-editing-project-<projectId>` for canvas editing on the connected project. It contains the canvas editing guidance, the live agent system prompt, and the live project context for `pagePath: "/"`.
123
+
124
+ ## Execute Code
71
125
 
72
126
  ```bash
73
127
  npx framer-dalton -s <sessionId> -e "<code>"
74
128
  ```
75
129
 
76
- **Escaping:** For code with HTML, quotes, or special characters, use a heredoc (see below). For simple strings, use `$'...'` syntax.
130
+ **Escaping:** For code containing `$` (e.g. `$control__` properties), HTML, or nested quotes, use a heredoc (see below). `-e "..."` works for everything else, including multiline.
77
131
 
78
132
  **Examples:**
79
133
 
@@ -108,22 +162,23 @@ The `<<'EOF'` syntax (with quotes around EOF) prevents shell interpolation.
108
162
  cat script.js | npx framer-dalton -s 1
109
163
  ```
110
164
 
111
- **Simple inline code:**
165
+ **Multiline inline code:**
112
166
 
113
167
  ```bash
114
- npx framer-dalton -s 1 -e $'
168
+ npx framer-dalton -s 1 -e "
115
169
  const collections = await framer.getCollections();
116
170
  for (const c of collections) {
117
171
  const items = await c.getItems();
118
172
  console.log(c.name, items.length);
119
173
  }
120
- '
174
+ "
121
175
  ```
122
176
 
123
- ### API Documentation
177
+ ## API Documentation
124
178
 
125
179
  ```bash
126
180
  npx framer-dalton docs # List all available methods
181
+ npx framer-dalton docs framer.getCollections # Show top level method
127
182
  npx framer-dalton docs Collection # Show class with all method signatures
128
183
  npx framer-dalton docs Collection.addItems # Show method + recursively expand all referenced types
129
184
  npx framer-dalton docs ScreenshotOptions # Show type + recursively expand all referenced types
@@ -131,46 +186,15 @@ npx framer-dalton docs ScreenshotOptions # Show type + recursively expa
131
186
 
132
187
  `docs` with no arguments lists available methods. Looking up a class shows its full definition without expanding referenced types. Looking up a specific method or type automatically expands all referenced types recursively.
133
188
 
134
- ---
135
-
136
- ## Context Variables
137
-
138
- - `framer` - Connected Framer Server API instance
139
- - `state` - Object persisted between calls within your session
140
- - `console` - For output (`console.log`, `console.error`)
141
- - `require` - Sandboxed Node.js modules: fs, path, url, crypto, buffer, util, os
142
- - Standard globals: `fetch`, `Buffer`, `URL`, `crypto`, `setTimeout`
143
-
144
- **Note:** `fs` operations are sandboxed to cwd, /tmp, and os.tmpdir().
145
-
146
- ### Use `state` to Avoid Repeated Calls
147
-
148
- **Always store results in `state` when you'll need them again.** API calls are slow - don't repeat them.
149
-
150
- ```bash
151
- # First call: fetch and store
152
- npx framer-dalton -s 1 -e "state.collections = await framer.getCollections()"
153
-
154
- # Later calls: reuse from state
155
- npx framer-dalton -s 1 -e "const team = state.collections.find(c => c.name === 'Team')"
156
- npx framer-dalton -s 1 -e "state.teamItems = await state.collections.find(c => c.name === 'Team').getItems()"
157
- ```
158
-
159
- Store anything you'll reference again: collections, items, nodes, fields.
160
-
161
- ---
162
-
163
189
  ## API Examples
164
190
 
165
191
  **STOP: These are patterns only. Before using any method below, run `npx framer-dalton docs <ClassName>` to verify the current signature.**
166
192
 
167
- ---
168
-
169
- ## Working with Collections (CMS)
193
+ ### Working with Collections (CMS)
170
194
 
171
195
  Collections are Framer's CMS. Each collection has fields (columns) and items (rows).
172
196
 
173
- ### Reading Collections
197
+ #### Reading Collections
174
198
 
175
199
  ```js
176
200
  // Get all collections
@@ -191,11 +215,11 @@ console.log(items);
191
215
  // [{ id: "XTM8FSHGs", slug: "post-1", draft: false, fieldData: {...} }, ...]
192
216
  ```
193
217
 
194
- ### Field Types
218
+ #### Field Types
195
219
 
196
220
  `boolean`, `color`, `number`, `string`, `formattedText` (HTML), `image`, `file`, `link`, `date`, `enum`, `collectionReference`, `multiCollectionReference`, `array` (galleries)
197
221
 
198
- ### Updating Collection Items
222
+ #### Updating Collection Items
199
223
 
200
224
  ```js
201
225
  // Add or update items (if id matches existing item, it updates)
@@ -215,7 +239,7 @@ const ids = items.map((i) => i.id).reverse();
215
239
  await collection.setItemOrder(ids);
216
240
  ```
217
241
 
218
- ### Working with CollectionItem
242
+ #### Working with CollectionItem
219
243
 
220
244
  ```js
221
245
  const items = await collection.getItems();
@@ -231,7 +255,7 @@ await item.navigateTo();
231
255
  await item.remove();
232
256
  ```
233
257
 
234
- ### Managed Collections
258
+ #### Managed Collections
235
259
 
236
260
  Managed collections are fully controlled by code - users can't edit them directly. Use for syncing external data sources.
237
261
 
@@ -260,13 +284,11 @@ await managed.setPluginData("lastSync", new Date().toISOString());
260
284
  const lastSync = await managed.getPluginData("lastSync");
261
285
  ```
262
286
 
263
- ---
264
-
265
- ## Working with Nodes
287
+ ### Working with Nodes
266
288
 
267
289
  Nodes are layers on the canvas: frames, text, images, components, etc.
268
290
 
269
- ### Getting Nodes
291
+ #### Getting Nodes
270
292
 
271
293
  ```js
272
294
  // Get current selection
@@ -293,7 +315,7 @@ const nodesWithBg = await framer.getNodesWithAttributeSet("backgroundColor");
293
315
  const nodesWithImage = await framer.getNodesWithAttributeSet("backgroundImage");
294
316
  ```
295
317
 
296
- ### Creating Nodes
318
+ #### Creating Nodes
297
319
 
298
320
  ```js
299
321
  // Create a frame
@@ -312,7 +334,7 @@ await textNode.setText("Hello World");
312
334
  const child = await framer.createFrameNode({ name: "Child" }, parentNode.id);
313
335
  ```
314
336
 
315
- ### Modifying Nodes
337
+ #### Modifying Nodes
316
338
 
317
339
  ```js
318
340
  // Update attributes
@@ -335,7 +357,7 @@ const clone = await node.clone();
335
357
  await framer.removeNodes([node.id]);
336
358
  ```
337
359
 
338
- ### Working with Text
360
+ #### Working with Text
339
361
 
340
362
  ```js
341
363
  // Get text content
@@ -347,9 +369,7 @@ await framer.setText("New text"); // on selection
347
369
  await textNode.setText("Hello World");
348
370
  ```
349
371
 
350
- ---
351
-
352
- ## Working with Images
372
+ ### Working with Images
353
373
 
354
374
  ```js
355
375
  // Add image to canvas
@@ -386,11 +406,9 @@ await framer.addSVG({
386
406
  });
387
407
  ```
388
408
 
389
- ---
390
-
391
- ## Working with Styles
409
+ ### Working with Styles
392
410
 
393
- ### Color Styles
411
+ #### Color Styles
394
412
 
395
413
  ```js
396
414
  // List all color styles
@@ -413,7 +431,7 @@ await style.setAttributes({ light: "rgba(0, 100, 200, 1)" });
413
431
  await style.remove();
414
432
  ```
415
433
 
416
- ### Text Styles
434
+ #### Text Styles
417
435
 
418
436
  ```js
419
437
  // List all text styles
@@ -443,7 +461,7 @@ const responsive = await framer.createTextStyle({
443
461
  await heading.setAttributes({ fontSize: "52px" });
444
462
  ```
445
463
 
446
- ### Fonts
464
+ #### Fonts
447
465
 
448
466
  ```js
449
467
  // Get available fonts
@@ -461,9 +479,7 @@ await framer.createTextStyle({
461
479
  });
462
480
  ```
463
481
 
464
- ---
465
-
466
- ## Code Components
482
+ ### Code Components
467
483
 
468
484
  Code components are custom React components that run inside Framer. Use them when you need behavior that Framer's visual tools don't support:
469
485
 
@@ -475,7 +491,7 @@ Code components are custom React components that run inside Framer. Use them whe
475
491
 
476
492
  If the design can be built with Framer's built-in components, layout tools, and interactions — don't use a code component. Code components are harder to maintain and can't be visually edited.
477
493
 
478
- ### Workflow
494
+ #### Workflow
479
495
 
480
496
  1. **Create** a code file: `framer.createCodeFile("MyComponent.tsx", code)`
481
497
  2. **Edit** an existing code file: `codeFile.setFileContent(newCode)`
@@ -484,19 +500,11 @@ If the design can be built with Framer's built-in components, layout tools, and
484
500
 
485
501
  Use `npx framer-dalton docs CodeFile` and `npx framer-dalton docs Framer.createCodeFile` to look up the full API.
486
502
 
487
- ### Authoring guidance
488
-
489
- Before writing component code, read the relevant skill docs:
490
-
491
- ```bash
492
- npx framer-dalton skill code-components # Structure, constraints, layout annotations
493
- npx framer-dalton skill property-controls # All 20+ control types with examples
494
- npx framer-dalton skill component-examples # Complete reference components
495
- ```
503
+ #### Authoring guidance
496
504
 
497
- ---
505
+ Before writing component code, load the `framer-code-components` skill.
498
506
 
499
- ## Storing Data
507
+ ### Storing Data
500
508
 
501
509
  Store metadata on nodes or globally in the project.
502
510
 
@@ -517,9 +525,7 @@ const nodeKeys = await node.getPluginDataKeys();
517
525
  await framer.setPluginData("myKey", null);
518
526
  ```
519
527
 
520
- ---
521
-
522
- ## Localization
528
+ ### Localization
523
529
 
524
530
  ```js
525
531
  // Get all locales
@@ -540,11 +546,9 @@ await framer.setLocalizationData({
540
546
  });
541
547
  ```
542
548
 
543
- ---
544
-
545
- ## Common Patterns
549
+ ### Common Patterns
546
550
 
547
- ### Iterate over all nodes in project
551
+ #### Iterate over all nodes in project
548
552
 
549
553
  ```js
550
554
  const root = await framer.getCanvasRoot();
@@ -553,7 +557,7 @@ for await (const node of root.walk()) {
553
557
  }
554
558
  ```
555
559
 
556
- ### Sync external data to collection
560
+ #### Sync external data to collection
557
561
 
558
562
  ```js
559
563
  const collection = await framer.getManagedCollection();
@@ -579,7 +583,7 @@ if (toRemove.length) await collection.removeItems(toRemove);
579
583
  await collection.setPluginData("lastSync", new Date().toISOString());
580
584
  ```
581
585
 
582
- ### Batch update all images' alt text
586
+ #### Batch update all images' alt text
583
587
 
584
588
  ```js
585
589
  const nodes = await framer.getNodesWithAttributeSet("backgroundImage");
@@ -593,9 +597,7 @@ for (const node of nodes) {
593
597
  }
594
598
  ```
595
599
 
596
- ---
597
-
598
- ## Screenshots and SVG Export
600
+ ### Screenshots and SVG Export
599
601
 
600
602
  Server API exclusive methods for capturing visual output from nodes.
601
603
 
@@ -622,9 +624,7 @@ const svgString = await framer.exportSVG(node.id);
622
624
  await require("fs").promises.writeFile(os.tmpdir() + "/export.svg", svgString);
623
625
  ```
624
626
 
625
- ---
626
-
627
- ## Publishing and Deployments
627
+ ### Publishing and Deployments
628
628
 
629
629
  Server API exclusive methods for publishing and managing deployments.
630
630
 
@@ -649,9 +649,7 @@ console.log(info.production?.url); // Production URL
649
649
  console.log(info.staging?.url); // Staging URL
650
650
  ```
651
651
 
652
- ---
653
-
654
- ## Change Tracking
652
+ ### Change Tracking
655
653
 
656
654
  Server API exclusive methods for tracking project changes.
657
655
 
@@ -666,89 +664,7 @@ console.log(changes.removed); // Removed paths
666
664
  const contributors = await framer.getChangeContributors();
667
665
  ```
668
666
 
669
- ---
670
-
671
- ## Canvas Editing
672
-
673
- **Use this for all design tasks** — creating pages, building sections, recreating designs from screenshots, or any task that involves layout or visual styling on the canvas.
674
-
675
- **Hard rule:** For design/layout work, do **not** use low-level node APIs (`createNode`, `setAttributes`, `setRect`, etc.). Always use the canvas editing flow (`getAgentSystemPrompt` + `getAgentContext` + `readProjectForAgent` + `applyAgentChanges`). If you start writing low-level node code for design work, stop and switch to canvas editing methods.
676
-
677
- **Access note:** Canvas editing `agent` methods are employee-only. If these methods fail or are unavailable, the account likely does not have employee access.
678
-
679
- ### Methods
680
-
681
- **`framer.getAgentSystemPrompt()`** — Returns the command reference, design rules, layout patterns, and examples. This is the sole documentation for the command syntax and query types. It is static (same for every project) — fetch once per session and persist to a file.
682
-
683
- **`framer.getAgentContext({ pagePath })`** — Returns the project's available fonts, components, color tokens, text style presets, and icon sets for the target page scope. Fetch before generating commands and use the same `pagePath` across context/read/apply calls.
684
-
685
- **`framer.readProjectForAgent(queries, { pagePath })`** — Reads project state. Query types are documented in the system prompt. Use liberally — query the page tree, icon sets, components, and examples before generating commands. Multiple queries can be batched in a single call. Never guess at names for examples, icon sets, or fonts — always look them up first.
686
-
687
- **`framer.applyAgentChanges(dsl, { pagePath })`** — Applies commands to the canvas. Node IDs you assign are temporary — re-read the page tree via `readProjectForAgent` if you need actual IDs after applying.
688
-
689
- ### Workflow
690
-
691
- ```js
692
- // 1. Save the system prompt to a file (once per session).
693
- const fs = require("fs");
694
- const prompt = await framer.getAgentSystemPrompt();
695
- fs.writeFileSync("/tmp/framer-canvas-reference.txt", prompt);
696
- console.log("Saved to /tmp/framer-canvas-reference.txt —", prompt.length, "chars");
697
-
698
- // 2. Get project context
699
- const projectCtx = await framer.getAgentContext({ pagePath: "/" });
700
- console.log(projectCtx);
701
-
702
- // 3. Read project state (query types are in the prompt)
703
- const { results } = await framer.readProjectForAgent(
704
- [{ type: "page", path: "/" }],
705
- { pagePath: "/" }
706
- );
707
-
708
- // 4. Apply changes
709
- await framer.applyAgentChanges(dsl, { pagePath: "/" });
710
- ```
711
-
712
- **You must read the entire system prompt file before writing any commands.** It contains command syntax, design rules, layout patterns, examples, and query documentation. Skipping sections will cause incorrect output.
713
-
714
- After applying changes, take screenshots to inspect the result. Check padding, spacing, typography, icon choice, and alignment. Iterate with additional `readProjectForAgent` + `applyAgentChanges` passes until visually accurate.
715
-
716
- When setting text content, use raw Unicode characters directly (e.g. `→` not `\u2192`).
717
-
718
- Always fetch fresh context per session — the format may change between versions.
719
-
720
- ### What canvas editing can do
721
-
722
- Beyond basic page layout, the command language supports:
723
-
724
- - **Colour tokens** — Create color tokens (`ColorStyleTokenNode`) with light/dark mode variants. Reference them across the project for consistent theming.
725
- - **Text style presets** — Create reusable typography presets (`TextStylePresetNode`) and apply them to text nodes. Build full typographic systems (headings, body, captions, etc.).
726
- - **Smart components** — Author reusable components (`ComponentNode`) with multiple visual variants, scoped variables, and property controls. Instantiate them anywhere with `ComponentInstanceNode`.
727
- - **Interactive effects** — Add hover effects (scale, opacity, color), tap effects, scroll-triggered appear animations, transitions between component variants, and event handlers.
728
- - **Icon sets** — Insert icons from named vector sets. Query available sets and icons via `readProjectForAgent`.
729
- - **Responsive breakpoints** — Create page breakpoints (Desktop, Tablet, Mobile) using the replica/variant system, with per-breakpoint overrides.
730
- - **Complex layouts** — Stack and grid layouts with auto-fill, fractional units, space-between distribution, and nested grids for asymmetric layouts.
731
-
732
- ---
733
-
734
- ## Capabilities
735
-
736
- What you can do with the Framer CLI:
737
-
738
- - **Canvas Editing** For design tasks — creating or editing pages, sections, layouts, recreating designs from screenshots, etc.
739
- - **CMS**: Create, read, update, delete collections and items. Sync external databases.
740
- - **Styles**: Manage color and text styles. Sync design systems.
741
- - **Code Components**: Create, edit, type-check, and add custom React components to the canvas.
742
- - **Assets**: Upload and manage images and files.
743
- - **Localization**: Manage translations programmatically.
744
- - **Data**: Store metadata on nodes and projects for plugin state.
745
- - **Screenshots**: Capture node screenshots as PNG/JPEG. Export nodes as SVG.
746
- - **Publishing**: Publish projects, manage deployments, track changes.
747
- - **Low-level Node APIs**: Create and modify individual nodes. Only use these for targeted, surgical edits to specific nodes — not for building pages or layouts.
748
-
749
- ---
750
-
751
- ## Known Limitations
667
+ ### Known Limitations
752
668
 
753
669
  - **Pages**: No list, delete, update, move, or settings APIs (create only)
754
670
  - **Code overrides**: Cannot assign overrides to nodes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "framer-dalton",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "framer-dalton": "./dist/cli.js"
@@ -35,8 +35,5 @@
35
35
  "tsx": "^4.19.0",
36
36
  "typescript": "^5.9.2",
37
37
  "vitest": "^4.0.18"
38
- },
39
- "publishConfig": {
40
- "registry": "https://registry.npmjs.org"
41
38
  }
42
39
  }
@@ -1,6 +0,0 @@
1
- ## All Skills
2
-
3
- - `npx framer-dalton skill` — Server API docs (sessions, collections, canvas, styles, publishing)
4
- - `npx framer-dalton skill code-components` — Code component authoring guide
5
- - `npx framer-dalton skill property-controls` — Property control reference (all 20+ types)
6
- - `npx framer-dalton skill component-examples` — Complete code component examples
@@ -1,115 +0,0 @@
1
- # Framer Code Components
2
-
3
- ## Best Practices
4
-
5
- ### Component Structure
6
-
7
- ```tsx
8
- import { addPropertyControls, ControlType } from "framer";
9
- import { motion } from "framer-motion"; // NOT from "framer"
10
-
11
- interface MyComponentProps {
12
- /* typed props */
13
- }
14
-
15
- /**
16
- * @framerSupportedLayoutWidth any-prefer-fixed
17
- * @framerSupportedLayoutHeight any-prefer-fixed
18
- */
19
- export default function MyComponent(props: MyComponentProps) {
20
- // component
21
- }
22
-
23
- addPropertyControls(MyComponent, {
24
- /* controls */
25
- });
26
- ```
27
-
28
- ### Platform Constraints
29
-
30
- These will cause errors if violated:
31
-
32
- 1. **Single file, default export** - Use named `function` syntax (not arrow functions), no named exports
33
- 2. **Imports** - Only `react`, `react-dom`, `framer`, `framer-motion`. Import `motion` from `"framer-motion"`, not `"framer"`
34
- 3. **Position** - Use `position: relative` on the root element, never `fixed`
35
- 4. **SSR** - Guard `window`/`document` access: `if (typeof window !== "undefined")`
36
- 5. **Annotations** - Include `@framerSupportedLayoutWidth/Height` in a `/** */` block comment immediately above the component function
37
- 6. **Types** - Provide a typed props interface (e.g. `MyComponentProps`). Avoid NodeJS types like `Timeout` — use `number` instead
38
-
39
- ### Layout Annotations
40
-
41
- | Content | Width | Height |
42
- | ----------------- | ------------------ | ------------------ |
43
- | No intrinsic size | `fixed` | `fixed` |
44
- | Text/auto-sizing | `auto` | `auto` |
45
- | Flexible | `any-prefer-fixed` | `any-prefer-fixed` |
46
-
47
- Detect auto vs fixed sizing: check if `style.width` or `style.height` is `"100%"`.
48
-
49
- ### Property Controls
50
-
51
- To make components configurable in Framer's properties panel, add property controls:
52
-
53
- - To make colors customizable, use `ControlType.Color`. Reuse the same prop for elements sharing a color.
54
- - To make text styling customizable, use `ControlType.Font` with `controls: "extended"` and `defaultFontType: "sans-serif"`.
55
- - For images, use `ControlType.ResponsiveImage`. Set defaults in the component body via destructuring (the control doesn't support `defaultValue`).
56
- - Provide a `defaultValue` for every prop so components render correctly in the Framer canvas. Include at least one item in `ControlType.Array` controls.
57
- - `ComponentName.defaultProps` is not supported in Framer — use `defaultValue` on the property control instead.
58
- - Use `hidden` for conditional visibility: `hidden: (props) => !props.showFeature`
59
- - Prefer sliders over steppers unless step values are large.
60
- - Keep controls focused — make key elements configurable, hardcode the rest.
61
- - See `npx framer-dalton skill property-controls` for the full property control reference.
62
-
63
- ### Image Defaults (in component body)
64
-
65
- ```tsx
66
- const {
67
- image = {
68
- src: "https://framerusercontent.com/images/GfGkADagM4KEibNcIiRUWlfrR0.jpg",
69
- alt: "Default",
70
- },
71
- } = props;
72
- ```
73
-
74
- ### Animation Performance
75
-
76
- ```tsx
77
- import { useIsStaticRenderer } from "framer";
78
- import { useInView } from "framer-motion";
79
-
80
- const isStatic = useIsStaticRenderer();
81
- const ref = useRef(null);
82
- const isInView = useInView(ref);
83
-
84
- if (isStatic) return <StaticPreview />; // Show useful static state
85
- // Pause animations when out of viewport
86
- ```
87
-
88
- - For very complex animations, consider WebGL instead of `framer-motion`.
89
- - Static preview should include visual effects, not just text.
90
- - Wrapping state updates in `startTransition()` prevents UI blocking and keeps interactions smooth.
91
-
92
- ### Text
93
-
94
- - For auto-sized components with text, apply `width: max-content` or `minWidth: max-content` to prevent text from collapsing.
95
-
96
- ### Common Errors
97
-
98
- - WebGL cross-origin: handle `SecurityError: Failed to execute 'texImage2D'` for cross-origin images.
99
- - Inverted Y-axis: check if WebGL images render upside down and accommodate.
100
-
101
- ### Accessibility
102
-
103
- - `aria` roles on interactive elements
104
- - Semantic HTML (`<nav>`, `<article>`, `<section>`)
105
- - `alt=""` on decorative images
106
- - 4.5:1 color contrast
107
-
108
- ## Term Interpretation
109
-
110
- - "responsive" → width/height 100%
111
- - "modern" → 8px radius, 16px spacing, subtle shadows
112
- - "minimal" → limited colors, whitespace
113
- - "interactive" → hover/active states
114
- - "accessible" → ARIA, semantic HTML
115
- - "props"/"properties" → Framer property controls