framer-code-link 0.7.0 → 0.8.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/dist/index.mjs +115 -4
- package/package.json +3 -2
- package/skills/SKILL.md +133 -0
- package/skills/references/EXAMPLES.md +869 -0
- package/skills/references/PROPERTY_CONTROLS.md +715 -0
- package/skills/references/PROPERTY_CONTROL_GUIDE.md +332 -0
- package/skills/references/PROPERTY_CONTROL_TYPES.md +488 -0
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
# Property Control Guide
|
|
2
|
+
|
|
3
|
+
Font styling patterns, variant mapping, and recommended default values for Framer property controls. For core rules, see [SKILL.md](../SKILL.md).
|
|
4
|
+
|
|
5
|
+
## Styling of text elements
|
|
6
|
+
|
|
7
|
+
When using Control Properties on text elements, do not introduce any new control properties for styles which can be applied with `ControlType.Font` and `FontControlDescription` respectively. Specifically:
|
|
8
|
+
- `FontControlDescription.defaultValue.fontSize` for `font-size`
|
|
9
|
+
- `FontControlDescription.defaultValue.textAlignment` for `text-alignment`
|
|
10
|
+
- `FontControlDescription.defaultValue.letterSpacing` for `letter-spacing`
|
|
11
|
+
- `FontControlDescription.defaultValue.lineHeight` for `line-height`
|
|
12
|
+
- `FontControlDescription.defaultValue.variant` for `font-weight` and/or `font-style`
|
|
13
|
+
- `FontControlDescription.defaultValue.variant` can be set only if `FontControlDescription.defaultFontType` is set to `"sans-serif"`
|
|
14
|
+
|
|
15
|
+
Remarks:
|
|
16
|
+
- `FontControlDescription.defaultValue.fontFamily` is not a valid default value. Font family cannot be set via `defaultValue` — it can only be selected by the user through the font control UI.
|
|
17
|
+
- Set `FontControlDescription.controls` to `"extended"` to expose full typography options (size, weight, spacing, alignment).
|
|
18
|
+
|
|
19
|
+
When you need to use font weight you should use `FontControlDescription.defaultValue.variant`.
|
|
20
|
+
The variant encapsulates both the font weight and style together. Refer to the following object to determine the correct variant for a given font weight:
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
interface ResolvedFontVariant {
|
|
24
|
+
fontStyle: "normal" | "italic"
|
|
25
|
+
weight: number
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const variantNameToFontWeight: Record<FramerFontVariant, ResolvedFontVariant> = {
|
|
29
|
+
Regular: { fontStyle: "normal", fontWeight: 400 },
|
|
30
|
+
Thin: { fontStyle: "normal", fontWeight: 100 },
|
|
31
|
+
"Extra Light": { fontStyle: "normal", fontWeight: 200 },
|
|
32
|
+
Light: { fontStyle: "normal", fontWeight: 300 },
|
|
33
|
+
Medium: { fontStyle: "normal", fontWeight: 500 },
|
|
34
|
+
Semibold: { fontStyle: "normal", fontWeight: 600 },
|
|
35
|
+
Bold: { fontStyle: "normal", fontWeight: 700 },
|
|
36
|
+
"Extra Bold": { fontStyle: "normal", fontWeight: 800 },
|
|
37
|
+
Black: { fontStyle: "normal", fontWeight: 900 },
|
|
38
|
+
"Thin Italic": { fontStyle: "italic", fontWeight: 100 },
|
|
39
|
+
"Extra Light Italic": { fontStyle: "italic", fontWeight: 200 },
|
|
40
|
+
"Light Italic": { fontStyle: "italic", fontWeight: 300 },
|
|
41
|
+
Italic: { fontStyle: "italic", fontWeight: 400 },
|
|
42
|
+
"Medium Italic": { fontStyle: "italic", fontWeight: 500 },
|
|
43
|
+
"Semibold Italic": { fontStyle: "italic", fontWeight: 600 },
|
|
44
|
+
"Bold Italic": { fontStyle: "italic", fontWeight: 700 },
|
|
45
|
+
"Extra Bold Italic": { fontStyle: "italic", fontWeight: 800 },
|
|
46
|
+
"Black Italic": { fontStyle: "italic", fontWeight: 900 },
|
|
47
|
+
"Regular Italic": { fontStyle: "italic", fontWeight: 400 },
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Example of a simple text component in Framer which demonstrates how to use Property Control of type `ControlType.Font`.
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
import { addPropertyControls, ControlType } from "framer"
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @framerSupportedLayoutWidth auto
|
|
58
|
+
* @framerSupportedLayoutHeight auto
|
|
59
|
+
*/
|
|
60
|
+
export default function SimpleText(props) {
|
|
61
|
+
const { label, heading } = props
|
|
62
|
+
return (
|
|
63
|
+
<span
|
|
64
|
+
style={{
|
|
65
|
+
fontSize: heading.fontSize,
|
|
66
|
+
textAlign: heading.textAlign,
|
|
67
|
+
fontWeight: heading.fontWeight,
|
|
68
|
+
fontFamily: heading.fontFamily,
|
|
69
|
+
lineHeight: heading.lineHeight,
|
|
70
|
+
letterSpacing: heading.letterSpacing,
|
|
71
|
+
fontStyle: heading.fontStyle,
|
|
72
|
+
}}
|
|
73
|
+
>
|
|
74
|
+
{label}
|
|
75
|
+
</span>
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
addPropertyControls(SimpleText, {
|
|
80
|
+
heading: {
|
|
81
|
+
type: ControlType.Font,
|
|
82
|
+
title: "Heading 2 Font",
|
|
83
|
+
defaultValue: {
|
|
84
|
+
textAlign: "right",
|
|
85
|
+
fontSize: 40,
|
|
86
|
+
variant: "Extra Bold",
|
|
87
|
+
letterSpacing: "-0.03em",
|
|
88
|
+
lineHeight: "1em",
|
|
89
|
+
},
|
|
90
|
+
controls: "extended",
|
|
91
|
+
defaultFontType: "sans-serif",
|
|
92
|
+
},
|
|
93
|
+
label: {
|
|
94
|
+
title: "Label",
|
|
95
|
+
type: ControlType.String,
|
|
96
|
+
defaultValue: "Hello",
|
|
97
|
+
},
|
|
98
|
+
})
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Default Control Values
|
|
102
|
+
|
|
103
|
+
Recommended default values for common control types.
|
|
104
|
+
|
|
105
|
+
### Colors
|
|
106
|
+
|
|
107
|
+
Recommended color defaults:
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
const colors: Record<string, ColorControlDescription> = {
|
|
111
|
+
/** Use for main container backgrounds, cards, and primary surfaces */
|
|
112
|
+
background: {
|
|
113
|
+
type: ControlType.Color,
|
|
114
|
+
defaultValue: "#FFFFFF", // White: backgrounds
|
|
115
|
+
},
|
|
116
|
+
/** Use for secondary backgrounds, input fields, and subtle visual elements */
|
|
117
|
+
subtleBackground: {
|
|
118
|
+
type: ControlType.Color,
|
|
119
|
+
defaultValue: "#F5F5F5", // Very light gray: subtle backgrounds, placeholders
|
|
120
|
+
},
|
|
121
|
+
/** Use for borders, dividers, and visual separators */
|
|
122
|
+
darkBackground: {
|
|
123
|
+
type: ControlType.Color,
|
|
124
|
+
defaultValue: "#EEEEEE", // Light gray: borders, separators
|
|
125
|
+
},
|
|
126
|
+
/** Use for secondary text, icons, and less prominent UI elements */
|
|
127
|
+
tertiary: {
|
|
128
|
+
type: ControlType.Color,
|
|
129
|
+
defaultValue: "#CCCCCC", // Medium gray: text, icons
|
|
130
|
+
},
|
|
131
|
+
/** Use for primary text, icons, and key UI elements that need emphasis */
|
|
132
|
+
primary: {
|
|
133
|
+
type: ControlType.Color,
|
|
134
|
+
defaultValue: "#000000", // Black: text, icons
|
|
135
|
+
},
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Images
|
|
140
|
+
|
|
141
|
+
To provide a default image, set it via destructuring in the component body (`ControlType.ResponsiveImage` does not support `defaultValue`):
|
|
142
|
+
```tsx
|
|
143
|
+
const { image = { src: "https://framerusercontent.com/images/GfGkADagM4KEibNcIiRUWlfrR0.jpg", alt: "Gradient 1 - Blue" } } = props
|
|
144
|
+
```
|
|
145
|
+
When applying image properties to elements, use spreads like `{...image}`.
|
|
146
|
+
|
|
147
|
+
Recommended image sources (gradient series — use in sequence when multiple are needed):
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
const images = {
|
|
151
|
+
/** Use for professional or corporate contexts, informational content, or quinary image slot */
|
|
152
|
+
image1: {
|
|
153
|
+
src: "https://framerusercontent.com/images/GfGkADagM4KEibNcIiRUWlfrR0.jpg",
|
|
154
|
+
alt: "Gradient 1 - Blue"
|
|
155
|
+
},
|
|
156
|
+
/** Use for creative or innovative contexts, feature highlights, or quaternary image slot */
|
|
157
|
+
image2: {
|
|
158
|
+
src: "https://framerusercontent.com/images/aNsAT3jCvt4zglbWCUoFe33Q.jpg",
|
|
159
|
+
alt: "Gradient 2 - Purple"
|
|
160
|
+
},
|
|
161
|
+
/** Use for energetic contexts, call-to-action backgrounds, or tertiary image slot */
|
|
162
|
+
image3: {
|
|
163
|
+
src: "https://framerusercontent.com/images/BYnxEV1zjYb9bhWh1IwBZ1ZoS60.jpg",
|
|
164
|
+
alt: "Gradient 3 - Orange"
|
|
165
|
+
},
|
|
166
|
+
/** Use for warm-toned contexts, product showcases, or secondary image slot */
|
|
167
|
+
image4: {
|
|
168
|
+
src: "https://framerusercontent.com/images/2uTNEj5aTl2K3NJaEFWMbnrA.jpg",
|
|
169
|
+
alt: "Gradient 4 - Yellow"
|
|
170
|
+
},
|
|
171
|
+
/** Use for nature-themed components, environmental contexts, or primary image slot */
|
|
172
|
+
image5: {
|
|
173
|
+
src: "https://framerusercontent.com/images/f9RiWoNpmlCMqVRIHz8l8wYfeI.jpg",
|
|
174
|
+
alt: "Gradient 5 - Green"
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Typography
|
|
180
|
+
|
|
181
|
+
Use these exact font definitions for all text elements
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
const typography: Record<string, FontControlDescription> = {
|
|
185
|
+
/** Use for main page titles and primary headlines */
|
|
186
|
+
heading1: {
|
|
187
|
+
type: ControlType.Font,
|
|
188
|
+
title: "Heading 1 Font",
|
|
189
|
+
defaultValue: {
|
|
190
|
+
fontSize: "40px",
|
|
191
|
+
variant: "Bold",
|
|
192
|
+
letterSpacing: "-0.04em",
|
|
193
|
+
lineHeight: "1em",
|
|
194
|
+
},
|
|
195
|
+
controls: "extended",
|
|
196
|
+
defaultFontType: "sans-serif",
|
|
197
|
+
},
|
|
198
|
+
/** Use for section titles and secondary headlines */
|
|
199
|
+
heading2: {
|
|
200
|
+
type: ControlType.Font,
|
|
201
|
+
title: "Heading 2 Font",
|
|
202
|
+
defaultValue: {
|
|
203
|
+
fontSize: "32px",
|
|
204
|
+
variant: "Semibold",
|
|
205
|
+
letterSpacing: "-0.03em",
|
|
206
|
+
lineHeight: "1em",
|
|
207
|
+
},
|
|
208
|
+
controls: "extended",
|
|
209
|
+
defaultFontType: "sans-serif",
|
|
210
|
+
},
|
|
211
|
+
/** Use for subsection titles and feature headings */
|
|
212
|
+
heading3: {
|
|
213
|
+
type: ControlType.Font,
|
|
214
|
+
title: "Heading 3 Font",
|
|
215
|
+
defaultValue: {
|
|
216
|
+
fontSize: "22px",
|
|
217
|
+
variant: "Semibold",
|
|
218
|
+
letterSpacing: "-0.01em",
|
|
219
|
+
lineHeight: "1.2em",
|
|
220
|
+
},
|
|
221
|
+
controls: "extended",
|
|
222
|
+
defaultFontType: "sans-serif",
|
|
223
|
+
},
|
|
224
|
+
/** Use for card titles, list headings, and UI element headers */
|
|
225
|
+
heading4: {
|
|
226
|
+
type: ControlType.Font,
|
|
227
|
+
title: "Heading 4 Font",
|
|
228
|
+
defaultValue: {
|
|
229
|
+
fontSize: "15px",
|
|
230
|
+
variant: "Medium",
|
|
231
|
+
letterSpacing: "-0.01em",
|
|
232
|
+
lineHeight: "1em",
|
|
233
|
+
},
|
|
234
|
+
controls: "extended",
|
|
235
|
+
defaultFontType: "sans-serif",
|
|
236
|
+
},
|
|
237
|
+
/** Use for body text, descriptions, and general content */
|
|
238
|
+
paragraph: {
|
|
239
|
+
type: ControlType.Font,
|
|
240
|
+
title: "Paragraph Font",
|
|
241
|
+
defaultValue: {
|
|
242
|
+
fontSize: "15px",
|
|
243
|
+
variant: "Medium",
|
|
244
|
+
letterSpacing: "-0.01em",
|
|
245
|
+
lineHeight: "1.3em",
|
|
246
|
+
},
|
|
247
|
+
controls: "extended",
|
|
248
|
+
defaultFontType: "sans-serif",
|
|
249
|
+
},
|
|
250
|
+
/** Use for buttons, links, and interactive text elements */
|
|
251
|
+
buttonText: {
|
|
252
|
+
type: ControlType.Font,
|
|
253
|
+
title: "Button Text Font",
|
|
254
|
+
defaultValue: {
|
|
255
|
+
variant: "Semibold",
|
|
256
|
+
fontSize: "14px",
|
|
257
|
+
letterSpacing: "-0.01em",
|
|
258
|
+
lineHeight: "1em",
|
|
259
|
+
},
|
|
260
|
+
controls: "extended",
|
|
261
|
+
defaultFontType: "sans-serif",
|
|
262
|
+
},
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### File Types
|
|
267
|
+
|
|
268
|
+
`ControlType.File` does not support `defaultValue` in its property control. Set default values through component parameter destructuring instead.
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
const fileTypes: Record<string, FileControlDescription> = {
|
|
272
|
+
/** Use for image upload fields, gallery components, and avatar selectors */
|
|
273
|
+
images: {
|
|
274
|
+
type: ControlType.File,
|
|
275
|
+
allowedFileTypes: ["jpg", "jpeg", "png", "gif", "webp", "svg"],
|
|
276
|
+
},
|
|
277
|
+
/** Use for video players, media galleries, and promotional content */
|
|
278
|
+
videos: {
|
|
279
|
+
type: ControlType.File,
|
|
280
|
+
allowedFileTypes: ["mp4", "webm", "mov"],
|
|
281
|
+
},
|
|
282
|
+
/** Use for document viewers, file download components, and resource sections */
|
|
283
|
+
documents: {
|
|
284
|
+
type: ControlType.File,
|
|
285
|
+
allowedFileTypes: ["pdf", "doc", "docx", "txt"],
|
|
286
|
+
},
|
|
287
|
+
/** Use for audio players, podcast components, and music interfaces */
|
|
288
|
+
audio: {
|
|
289
|
+
type: ControlType.File,
|
|
290
|
+
allowedFileTypes: ["mp3", "wav", "ogg"],
|
|
291
|
+
},
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
Use the following values for each file type as default values:
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
const defaultValues: Record<keyof typeof fileTypes, string> = {
|
|
299
|
+
images: "https://framerusercontent.com/images/GfGkADagM4KEibNcIiRUWlfrR0.jpg",
|
|
300
|
+
videos: "https://framerusercontent.com/assets/MLWPbW1dUQawJLhhun3dBwpgJak.mp4",
|
|
301
|
+
audio: "https://framerusercontent.com/assets/8w3IUatLX9a5JVJ6XPCVuHi94.mp3",
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
Recommended pattern for file control defaults:
|
|
306
|
+
|
|
307
|
+
```tsx
|
|
308
|
+
function MyComponent(props) {
|
|
309
|
+
// CORRECT: Set file defaults through parameter destructuring
|
|
310
|
+
const {
|
|
311
|
+
imageFile = "https://framerusercontent.com/images/GfGkADagM4KEibNcIiRUWlfrR0.jpg",
|
|
312
|
+
videoFile = "https://framerusercontent.com/assets/MLWPbW1dUQawJLhhun3dBwpgJak.mp4",
|
|
313
|
+
audioFile = "https://framerusercontent.com/assets/8w3IUatLX9a5JVJ6XPCVuHi94.mp3",
|
|
314
|
+
} = props
|
|
315
|
+
|
|
316
|
+
return (
|
|
317
|
+
<div>
|
|
318
|
+
<img src={imageFile} />
|
|
319
|
+
<video src={videoFile} />
|
|
320
|
+
<audio src={audioFile} />
|
|
321
|
+
</div>
|
|
322
|
+
)
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
addPropertyControls(MyComponent, {
|
|
326
|
+
imageFile: {
|
|
327
|
+
type: ControlType.File,
|
|
328
|
+
allowedFileTypes: ["jpg", "jpeg", "png", "gif", "webp", "svg"],
|
|
329
|
+
},
|
|
330
|
+
// Additional file controls...
|
|
331
|
+
})
|
|
332
|
+
```
|