framer-dalton 0.0.2 → 0.0.5

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.
@@ -0,0 +1,1535 @@
1
+ # Framer Property Controls
2
+
3
+ Control types for property controls in Framer code components. Each control type specifies a different user interface for receiving input. All control types accept `title`, `description`, and `hidden` properties.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Boolean](#boolean)
8
+ - [Number](#number)
9
+ - [String](#string)
10
+ - [Enum](#enum)
11
+ - [Color](#color)
12
+ - [ResponsiveImage](#responsiveimage)
13
+ - [File](#file)
14
+ - [Array](#array)
15
+ - [Slot](#slot)
16
+ - [EventHandler](#eventhandler)
17
+ - [Font](#font)
18
+ - [Transition](#transition)
19
+ - [BoxShadow](#boxshadow)
20
+ - [Link](#link)
21
+ - [Date](#date)
22
+ - [Object](#object)
23
+ - [Border](#border)
24
+ - [Cursor](#cursor)
25
+ - [Padding](#padding)
26
+ - [BorderRadius](#borderradius)
27
+ - [Gap](#gap)
28
+ - [TrackingId](#trackingid)
29
+ - [Deprecated Controls](#deprecated-controls)
30
+ - [TypeScript Interfaces](#typescript-interfaces)
31
+
32
+ ## Boolean
33
+
34
+ A control that displays an on/off checkbox. The associated property will be `true` or `false`, depending on the state of the checkbox.
35
+
36
+ **Properties:**
37
+
38
+ - `defaultValue`: Set to `true` by default
39
+ - `optional`: Whether the control value is optional
40
+ - `enabledTitle`: Customize the label when enabled _(deprecated)_
41
+ - `disabledTitle`: Customize the label when disabled _(deprecated)_
42
+
43
+ **Example:**
44
+
45
+ ```javascript
46
+ export function MyComponent(props) {
47
+ return <Frame size={"100%"}>{props.showText ? "Hello World" : null}</Frame>;
48
+ }
49
+
50
+ addPropertyControls(MyComponent, {
51
+ showText: {
52
+ type: ControlType.Boolean,
53
+ title: "Show Text",
54
+ defaultValue: true,
55
+ },
56
+ });
57
+ ```
58
+
59
+ ## Number
60
+
61
+ A control that accepts any numeric value. This will be provided directly as a property. Displays an input field with a range slider by default.
62
+
63
+ **Properties:**
64
+
65
+ - `defaultValue`: The default numeric value
66
+ - `min`: Minimum allowed value
67
+ - `max`: Maximum allowed value
68
+ - `unit`: Unit label (e.g., "deg", "px")
69
+ - `step`: Increment value for the slider
70
+ - `displayStepper`: Enable to show a stepper control instead
71
+ - `optional`: Whether the control value is optional
72
+
73
+ **Example:**
74
+
75
+ ```javascript
76
+ export function MyComponent(props) {
77
+ return (
78
+ <Frame rotateZ={props.rotation} size={"100%"}>
79
+ {props.rotation}
80
+ </Frame>
81
+ );
82
+ }
83
+
84
+ addPropertyControls(MyComponent, {
85
+ rotation: {
86
+ type: ControlType.Number,
87
+ defaultValue: 0,
88
+ min: 0,
89
+ max: 360,
90
+ unit: "deg",
91
+ step: 0.1,
92
+ displayStepper: true,
93
+ },
94
+ });
95
+ ```
96
+
97
+ ## String
98
+
99
+ A control that accepts plain text values. Displays an input field with an optional placeholder value.
100
+
101
+ **Properties:**
102
+
103
+ - `defaultValue`: The default text value
104
+ - `placeholder`: Placeholder text
105
+ - `obscured`: Set to true to use a password input field
106
+ - `displayTextArea`: Enable for a multi-line input area
107
+ - `preventLocalization`: Prevents automatic translation of the text
108
+ - `optional`: Whether the control value is optional
109
+
110
+ **Example:**
111
+
112
+ ```javascript
113
+ export function MyComponent(props) {
114
+ return (
115
+ <Frame>
116
+ {props.title} — {props.body}
117
+ </Frame>
118
+ );
119
+ }
120
+
121
+ addPropertyControls(MyComponent, {
122
+ title: {
123
+ type: ControlType.String,
124
+ defaultValue: "Framer",
125
+ placeholder: "Type something…",
126
+ },
127
+ body: {
128
+ type: ControlType.String,
129
+ defaultValue: "Lorem ipsum dolor sit amet.",
130
+ placeholder: "Type something…",
131
+ displayTextArea: true,
132
+ },
133
+ });
134
+ ```
135
+
136
+ ## Enum
137
+
138
+ A property control that represents a list of options. The selected option will be provided as a property. Displayed as a dropdown menu.
139
+
140
+ **Properties:**
141
+
142
+ - `defaultValue`: The default selected option (string, boolean, number, or null)
143
+ - `options`: Array of unique values (string, boolean, number, or null)
144
+ - `optionTitles`: Display names for the options
145
+ - `displaySegmentedControl`: Enable to display a segmented control instead
146
+ - `segmentedControlDirection`: Direction of the segmented control ('horizontal' or 'vertical')
147
+
148
+ **Example:**
149
+
150
+ ```javascript
151
+ export function MyComponent(props) {
152
+ const value = props.value || "a";
153
+ const colors = { a: "red", b: "green", c: "blue" };
154
+ return (
155
+ <Frame background={colors[value]} size={"100%"}>
156
+ {value}
157
+ </Frame>
158
+ );
159
+ }
160
+
161
+ addPropertyControls(MyComponent, {
162
+ value: {
163
+ type: ControlType.Enum,
164
+ defaultValue: "a",
165
+ options: ["a", "b", "c"],
166
+ optionTitles: ["Option A", "Option B", "Option C"],
167
+ },
168
+ });
169
+ ```
170
+
171
+ **Example with Segmented Control:**
172
+
173
+ ```javascript
174
+ addPropertyControls(MyComponent, {
175
+ alignment: {
176
+ type: ControlType.Enum,
177
+ defaultValue: "left",
178
+ options: ["left", "center", "right"],
179
+ optionTitles: ["Left", "Center", "Right"],
180
+ displaySegmentedControl: true,
181
+ segmentedControlDirection: "horizontal",
182
+ },
183
+ });
184
+ ```
185
+
186
+ ## Color
187
+
188
+ A control that represents a color value. The selected color is provided as a string in either HEX (`"#fff"`) or HSL (`hsla(203, 87%, 50%, 0.5)`) notation, depending on whether there is an alpha channel.
189
+
190
+ **Properties:**
191
+
192
+ - `defaultValue`: The default color value
193
+ - `optional`: Whether the color is optional
194
+
195
+ **Example:**
196
+
197
+ ```javascript
198
+ function MyComponent(props) {
199
+ return <Frame background={props.background} size={"100%"} />;
200
+ }
201
+
202
+ addPropertyControls(MyComponent, {
203
+ background: {
204
+ type: ControlType.Color,
205
+ defaultValue: "#fff",
206
+ },
207
+ });
208
+ ```
209
+
210
+ ## ResponsiveImage
211
+
212
+ A control that allows the user to pick an image resource. Displayed as an image picker with associated file picker.
213
+
214
+ **Returns an object with:**
215
+
216
+ - `src`: URL string of the full resolution image
217
+ - `srcSet`: Optional string with scaled image variants (for `<img srcSet>`)
218
+ - `alt`: Optional description of the image
219
+
220
+ **Example:**
221
+
222
+ ```javascript
223
+ function MyComponent(props) {
224
+ return (
225
+ <img
226
+ src={props.image?.src}
227
+ srcSet={props.image?.srcSet}
228
+ alt={props.image?.alt}
229
+ />
230
+ );
231
+ }
232
+
233
+ addPropertyControls(MyComponent, {
234
+ image: {
235
+ type: ControlType.ResponsiveImage,
236
+ },
237
+ });
238
+ ```
239
+
240
+ ## File
241
+
242
+ A control that allows the user to pick a file resource. The selected file will be provided as a fully qualified URL.
243
+
244
+ **Properties:**
245
+
246
+ - `allowedFileTypes`: Array specifying acceptable file types. Supported formats:
247
+ - Media types (`"image/png"`, `"audio/*"`, `"*/*"`)
248
+ - File extensions with dot (`".png"`, `".mov"`)
249
+ - File extensions without dot (`"png"`) for backward compatibility
250
+ - Wildcard (`"*"`) to allow everything
251
+
252
+ **Example:**
253
+
254
+ ```javascript
255
+ export function MyComponent(props) {
256
+ return (
257
+ <Frame size={"100%"}>
258
+ <video
259
+ style={{
260
+ objectFit: "contain",
261
+ width: props.width,
262
+ height: props.height,
263
+ }}
264
+ src={props.filepath}
265
+ controls
266
+ />
267
+ </Frame>
268
+ );
269
+ }
270
+
271
+ addPropertyControls(MyComponent, {
272
+ filepath: {
273
+ type: ControlType.File,
274
+ allowedFileTypes: ["mov", "mp4"],
275
+ },
276
+ });
277
+ ```
278
+
279
+ ## Array
280
+
281
+ A control that allows multiple values per `ControlType`, provided as an array via properties. Displays as an additional section in the properties panel.
282
+
283
+ **Properties:**
284
+
285
+ - `control`: The control type to repeat
286
+ - `minCount`: Minimum number of items
287
+ - `maxCount`: Maximum number of items
288
+ - `defaultValue`: Default array values
289
+
290
+ **Example with Objects:**
291
+
292
+ ```javascript
293
+ export function MyComponent(props) {
294
+ return (
295
+ <Stack size={"100%"}>
296
+ {props.items.map((item, index) => (
297
+ <div key={index}>{item.title}</div>
298
+ ))}
299
+ </Stack>
300
+ );
301
+ }
302
+
303
+ addPropertyControls(MyComponent, {
304
+ items: {
305
+ type: ControlType.Array,
306
+ control: {
307
+ type: ControlType.Object,
308
+ controls: {
309
+ title: { type: ControlType.String, defaultValue: "Item" },
310
+ image: { type: ControlType.ResponsiveImage },
311
+ },
312
+ },
313
+ defaultValue: [{ title: "First" }, { title: "Second" }],
314
+ maxCount: 10,
315
+ },
316
+ });
317
+ ```
318
+
319
+ ## Slot
320
+
321
+ A control that references one or more other components on the canvas, included in the component props as a React node. By default allows any number of components to be linked.
322
+
323
+ **Properties:**
324
+
325
+ - `maxCount`: Maximum number of components to be linked
326
+
327
+ **Example:**
328
+
329
+ ```javascript
330
+ export function MyComponent(props) {
331
+ return <Stack size={"100%"}>{props.children}</Stack>;
332
+ }
333
+
334
+ addPropertyControls(MyComponent, {
335
+ children: {
336
+ type: ControlType.Slot,
337
+ maxCount: 5,
338
+ },
339
+ });
340
+ ```
341
+
342
+ ## EventHandler
343
+
344
+ A control that exposes events in the prototyping panel within the Framer UI. When choosing an event, you can select from a list of actions to trigger.
345
+
346
+ **Example:**
347
+
348
+ ```javascript
349
+ export function MyComponent(props) {
350
+ return <Frame onTap={props.onTap} size={"100%"} />;
351
+ }
352
+
353
+ addPropertyControls(MyComponent, {
354
+ onTap: {
355
+ type: ControlType.EventHandler,
356
+ },
357
+ });
358
+ ```
359
+
360
+ ## Font
361
+
362
+ A control that allows for selecting a font to be used in the component.
363
+
364
+ **Properties:**
365
+
366
+ - `defaultValue`: Default font settings
367
+ - `controls`: Specifies control options ("basic" or "extended")
368
+ - `defaultFontType`: Default font type ("sans-serif", "serif", or "monospace")
369
+ - `displayTextAlignment`: Whether to display text alignment options
370
+ - `displayFontSize`: Whether to display font size options
371
+
372
+ **Default Value Options:**
373
+
374
+ - `textAlign`: "left", "right", "center", or "justify"
375
+ - `fontSize`: string or number (e.g., "16px", 16)
376
+ - `letterSpacing`: string or number (e.g., "-0.01em", 0.1)
377
+ - `lineHeight`: string or number (e.g., "1.5em", 1.5, "150%")
378
+ - `variant`: Font variant (only for "sans-serif" font type)
379
+
380
+ **Example:**
381
+
382
+ ```javascript
383
+ export function MyComponent(props) {
384
+ return <div style={props.customFont}>Hello World</div>;
385
+ }
386
+
387
+ addPropertyControls(MyComponent, {
388
+ customFont: {
389
+ type: ControlType.Font,
390
+ defaultValue: {
391
+ fontSize: "16px",
392
+ variant: "Medium",
393
+ letterSpacing: "-0.01em",
394
+ lineHeight: "1.2em",
395
+ textAlign: "left",
396
+ },
397
+ controls: "extended",
398
+ defaultFontType: "sans-serif",
399
+ },
400
+ });
401
+ ```
402
+
403
+ ## Transition
404
+
405
+ A control that allows for editing Framer Motion transition options within the Framer UI.
406
+
407
+ **Properties:**
408
+
409
+ - `defaultValue`: Default transition (null or Transition object)
410
+
411
+ **Example:**
412
+
413
+ ```javascript
414
+ export function MyComponent(props) {
415
+ return <Frame animate={{ scale: 2 }} transition={props.transition} />;
416
+ }
417
+
418
+ addPropertyControls(MyComponent, {
419
+ transition: {
420
+ type: ControlType.Transition,
421
+ },
422
+ });
423
+ ```
424
+
425
+ ## BoxShadow
426
+
427
+ A control that allows for exposing shadows. The value will be provided as a string with valid CSS box-shadow values.
428
+
429
+ **Properties:**
430
+
431
+ - `defaultValue`: Default shadow (string or BoxShadow array)
432
+
433
+ **Example:**
434
+
435
+ ```javascript
436
+ export function MyComponent(props) {
437
+ return <motion.div style={{ boxShadow: props.shadow }} />;
438
+ }
439
+
440
+ addPropertyControls(MyComponent, {
441
+ shadow: {
442
+ type: ControlType.BoxShadow,
443
+ },
444
+ });
445
+ ```
446
+
447
+ ## Link
448
+
449
+ A control that allows for exposing web links.
450
+
451
+ **Properties:**
452
+
453
+ - `defaultValue`: Default URL as string
454
+
455
+ **Example:**
456
+
457
+ ```javascript
458
+ export function MyComponent(props) {
459
+ return <a href={props.link}>My Link</a>;
460
+ }
461
+
462
+ addPropertyControls(MyComponent, {
463
+ link: {
464
+ type: ControlType.Link,
465
+ },
466
+ });
467
+ ```
468
+
469
+ ## Date
470
+
471
+ A control that allows for exposing dates. The value will be provided in toJSON() string format.
472
+
473
+ **Properties:**
474
+
475
+ - `displayTime`: Whether to include time selection
476
+ - `defaultValue`: Default date as ISO string
477
+ - `optional`: Whether the date is optional
478
+
479
+ **Example:**
480
+
481
+ ```javascript
482
+ export function MyComponent(props) {
483
+ const formattedDate = React.useMemo(() => {
484
+ return props.date ? new Date(props.date).toLocaleDateString() : "No date";
485
+ }, [props.date]);
486
+ return <div>{formattedDate}</div>;
487
+ }
488
+
489
+ addPropertyControls(MyComponent, {
490
+ date: {
491
+ type: ControlType.Date,
492
+ displayTime: true,
493
+ optional: true,
494
+ },
495
+ });
496
+ ```
497
+
498
+ ## Object
499
+
500
+ A control that allows for grouping multiple properties as an object.
501
+
502
+ **Properties:**
503
+
504
+ - `controls`: Object containing nested controls
505
+ - `defaultValue`: Default object values
506
+ - `buttonTitle`: Custom button title
507
+ - `optional`: Whether the object is optional
508
+ - `icon`: Icon to display ('object', 'effect', 'color', 'interaction', or 'boolean')
509
+
510
+ **Example:**
511
+
512
+ ```javascript
513
+ export function MyComponent(props) {
514
+ return (
515
+ <Frame opacity={props.style?.opacity} background={props.style?.tint} />
516
+ );
517
+ }
518
+
519
+ addPropertyControls(MyComponent, {
520
+ style: {
521
+ type: ControlType.Object,
522
+ optional: true,
523
+ icon: "effect",
524
+ controls: {
525
+ opacity: { type: ControlType.Number, defaultValue: 1, min: 0, max: 1 },
526
+ tint: { type: ControlType.Color, defaultValue: "#000" },
527
+ },
528
+ },
529
+ });
530
+ ```
531
+
532
+ ## Border
533
+
534
+ A control that represents a border.
535
+
536
+ **Properties:**
537
+
538
+ - `defaultValue`: Default border settings
539
+ - `optional`: Whether the border is optional
540
+
541
+ **Border Value Object:**
542
+
543
+ - `borderColor`: CSS color string
544
+ - `borderStyle`: "solid", "dashed", "dotted", or "double"
545
+ - `borderWidth`: Uniform width (number)
546
+ - `borderTopWidth`, `borderLeftWidth`, `borderRightWidth`, `borderBottomWidth`: Per-side widths
547
+
548
+ **Example:**
549
+
550
+ ```javascript
551
+ function MyComponent(props) {
552
+ return <div style={props.border} />;
553
+ }
554
+
555
+ addPropertyControls(MyComponent, {
556
+ border: {
557
+ type: ControlType.Border,
558
+ defaultValue: {
559
+ borderWidth: 1,
560
+ borderStyle: "solid",
561
+ borderColor: "rgba(0, 0, 0, 0.5)",
562
+ },
563
+ },
564
+ });
565
+ ```
566
+
567
+ ## Cursor
568
+
569
+ A control that allows specifying a web cursor that should be shown when mousing over the element assigned.
570
+
571
+ **Properties:**
572
+
573
+ - `defaultValue`: Default cursor value (CSS cursor string)
574
+
575
+ **Example:**
576
+
577
+ ```javascript
578
+ function MyComponent(props) {
579
+ return <div style={{ cursor: props.cursor }}>Hover me</div>;
580
+ }
581
+
582
+ addPropertyControls(MyComponent, {
583
+ cursor: {
584
+ type: ControlType.Cursor,
585
+ defaultValue: "pointer",
586
+ },
587
+ });
588
+ ```
589
+
590
+ ## Padding
591
+
592
+ A control that represents CSS padding.
593
+
594
+ **Properties:**
595
+
596
+ - `defaultValue`: Default padding value (e.g., "8px", "10px 20px", "10px 20px 30px 40px")
597
+
598
+ **Example:**
599
+
600
+ ```javascript
601
+ function MyComponent({ padding }) {
602
+ return <div style={{ padding }}>Content</div>;
603
+ }
604
+
605
+ addPropertyControls(MyComponent, {
606
+ padding: {
607
+ type: ControlType.Padding,
608
+ defaultValue: "8px",
609
+ },
610
+ });
611
+ ```
612
+
613
+ ## BorderRadius
614
+
615
+ A control that represents CSS border radius.
616
+
617
+ **Properties:**
618
+
619
+ - `defaultValue`: Default border radius value (e.g., "16px", "8px 16px")
620
+
621
+ **Example:**
622
+
623
+ ```javascript
624
+ function MyComponent({ borderRadius }) {
625
+ return <div style={{ borderRadius, background: "red" }} />;
626
+ }
627
+
628
+ addPropertyControls(MyComponent, {
629
+ borderRadius: {
630
+ type: ControlType.BorderRadius,
631
+ defaultValue: "16px",
632
+ title: "Radius",
633
+ },
634
+ });
635
+ ```
636
+
637
+ ## Gap
638
+
639
+ A control that represents CSS gap for grid/flex layouts.
640
+
641
+ **Properties:**
642
+
643
+ - `defaultValue`: Default gap value (e.g., "8px", "8px 16px")
644
+
645
+ **Example:**
646
+
647
+ ```javascript
648
+ function MyComponent({ gap, children }) {
649
+ return <div style={{ display: "flex", gap }}>{children}</div>;
650
+ }
651
+
652
+ addPropertyControls(MyComponent, {
653
+ gap: {
654
+ type: ControlType.Gap,
655
+ defaultValue: "8px",
656
+ },
657
+ children: {
658
+ type: ControlType.Slot,
659
+ },
660
+ });
661
+ ```
662
+
663
+ ## TrackingId
664
+
665
+ A control that represents an ID for tracking events.
666
+
667
+ **Format Requirements:**
668
+
669
+ - Lowercase letters (a-z) and numbers (0-9) only
670
+ - Hyphens (-) as separators (no leading/trailing or consecutive hyphens)
671
+ - Valid: "button-click", "form-submit", "video-play", "nav-item-1"
672
+ - Invalid: "Button-Click", "form--submit", "-button-click", "button_utils"
673
+
674
+ **Properties:**
675
+
676
+ - `defaultValue`: Default tracking ID string
677
+
678
+ **Example:**
679
+
680
+ ```javascript
681
+ function MyComponent(props) {
682
+ const handleClick = () => {
683
+ // Track the event using props.trackingId
684
+ analytics.track(props.trackingId);
685
+ };
686
+ return <button onClick={handleClick}>Click me</button>;
687
+ }
688
+
689
+ addPropertyControls(MyComponent, {
690
+ trackingId: {
691
+ type: ControlType.TrackingId,
692
+ defaultValue: "button-click",
693
+ },
694
+ });
695
+ ```
696
+
697
+ ## Deprecated Controls
698
+
699
+ ### ControlType.Image
700
+
701
+ **Deprecated.** Use `ControlType.ResponsiveImage` instead. The `src` field provides the image URL.
702
+
703
+ ### ControlType.ComponentInstance
704
+
705
+ **Deprecated.** Use `ControlType.Slot` instead. The new Slot type doesn't need to be nested within an array control for multiple items. By default, Slot allows infinite items; use `maxCount` to limit.
706
+
707
+ ### ControlType.SegmentedEnum
708
+
709
+ **Deprecated.** Use `ControlType.Enum` with `displaySegmentedControl: true` instead.
710
+
711
+ ### ControlType.FusedNumber
712
+
713
+ **Deprecated.** Use `ControlType.Padding` and `ControlType.BorderRadius` instead. These new controls provide a single value (e.g., "10px" or "10px 20px 30px 40px").
714
+
715
+ ---
716
+
717
+ # Framer Property Control Types
718
+
719
+ TypeScript interfaces for all Framer property control types. ## Base Control Description
720
+
721
+ All control descriptions extend this base interface:
722
+
723
+ ```typescript
724
+ export interface BaseControlDescription<P = any> {
725
+ title?: string;
726
+ description?: string;
727
+ hidden?: ((props: P, rootProps: any) => boolean) | boolean;
728
+ }
729
+
730
+ export interface WithOptional {
731
+ optional?: boolean;
732
+ }
733
+ ```
734
+
735
+ ## Control Type Interfaces
736
+
737
+ ### Boolean Control
738
+
739
+ ```typescript
740
+ export interface BooleanControlDescription<P = any>
741
+ extends BaseControlDescription<P>, WithOptional {
742
+ type: ControlType.Boolean;
743
+ defaultValue?: boolean;
744
+ /** @deprecated */
745
+ disabledTitle?: string;
746
+ /** @deprecated */
747
+ enabledTitle?: string;
748
+ }
749
+ ```
750
+
751
+ ### Number Control
752
+
753
+ ```typescript
754
+ export interface NumberControlDescription<P = any>
755
+ extends BaseControlDescription<P>, WithOptional {
756
+ type: ControlType.Number;
757
+ defaultValue?: number;
758
+ max?: number;
759
+ min?: number;
760
+ unit?: string;
761
+ step?: number;
762
+ displayStepper?: boolean;
763
+ }
764
+ ```
765
+
766
+ ### String Control
767
+
768
+ ```typescript
769
+ export interface StringControlDescription<P = any>
770
+ extends BaseControlDescription<P>, WithOptional {
771
+ type: ControlType.String;
772
+ defaultValue?: string;
773
+ placeholder?: string;
774
+ obscured?: boolean;
775
+ displayTextArea?: boolean;
776
+ preventLocalization?: boolean;
777
+ }
778
+ ```
779
+
780
+ ### Enum Control
781
+
782
+ ```typescript
783
+ export interface EnumControlDescription<
784
+ P = any,
785
+ > extends BaseControlDescription<P> {
786
+ type: ControlType.Enum;
787
+ defaultValue?: string | boolean | number | null;
788
+ options: (string | boolean | number | null)[];
789
+ optionTitles?: string[];
790
+ displaySegmentedControl?: boolean;
791
+ segmentedControlDirection?: "horizontal" | "vertical";
792
+ }
793
+ ```
794
+
795
+ ### Color Control
796
+
797
+ ```typescript
798
+ export interface ColorControlDescription<P = any>
799
+ extends BaseControlDescription<P>, WithOptional {
800
+ type: ControlType.Color;
801
+ defaultValue?: string;
802
+ }
803
+ ```
804
+
805
+ ### ResponsiveImage Control
806
+
807
+ ```typescript
808
+ export interface ResponsiveImageControlDescription<
809
+ P = any,
810
+ > extends BaseControlDescription<P> {
811
+ type: ControlType.ResponsiveImage;
812
+ }
813
+ ```
814
+
815
+ ### File Control
816
+
817
+ ```typescript
818
+ export type AllowedFileTypes = readonly string[];
819
+
820
+ export interface FileControlDescription<
821
+ P = any,
822
+ > extends BaseControlDescription<P> {
823
+ type: ControlType.File;
824
+ allowedFileTypes: AllowedFileTypes;
825
+ }
826
+ ```
827
+
828
+ ### Slot Control
829
+
830
+ ```typescript
831
+ export interface SlotControlDescription<
832
+ P = any,
833
+ > extends BaseControlDescription<P> {
834
+ type: ControlType.Slot;
835
+ maxCount?: number;
836
+ }
837
+ ```
838
+
839
+ ### Array Control
840
+
841
+ ```typescript
842
+ export interface ArrayControlDescription<
843
+ P = any,
844
+ > extends BaseControlDescription<P> {
845
+ type: ControlType.Array;
846
+ control: ArrayItemControlDescription<P>;
847
+ minCount?: number;
848
+ maxCount?: number;
849
+ defaultValue?: any[];
850
+ }
851
+ ```
852
+
853
+ ### Object Control
854
+
855
+ ```typescript
856
+ export type ObjectControlIcon =
857
+ | "object"
858
+ | "effect"
859
+ | "color"
860
+ | "interaction"
861
+ | "boolean";
862
+
863
+ export interface ObjectControlDescription<P = any>
864
+ extends BaseControlDescription<P>, WithOptional {
865
+ type: ControlType.Object;
866
+ controls: { [key: string]: ObjectPropertyControlDescription };
867
+ defaultValue?: { [key: string]: any };
868
+ buttonTitle?: string;
869
+ icon?: ObjectControlIcon;
870
+ }
871
+ ```
872
+
873
+ ### Event Handler Control
874
+
875
+ ```typescript
876
+ export interface EventHandlerControlDescription<
877
+ P = any,
878
+ > extends BaseControlDescription<P> {
879
+ type: ControlType.EventHandler;
880
+ }
881
+ ```
882
+
883
+ ### Transition Control
884
+
885
+ ```typescript
886
+ import type { Transition } from "framer-motion";
887
+
888
+ export interface TransitionControlDescription<
889
+ P = any,
890
+ > extends BaseControlDescription<P> {
891
+ type: ControlType.Transition;
892
+ defaultValue?: null | Transition;
893
+ }
894
+ ```
895
+
896
+ ### BoxShadow Control
897
+
898
+ ```typescript
899
+ export interface BoxShadowControlDescription<
900
+ P = any,
901
+ > extends BaseControlDescription<P> {
902
+ type: ControlType.BoxShadow;
903
+ defaultValue?: string | readonly BoxShadow[];
904
+ }
905
+ ```
906
+
907
+ ### Link Control
908
+
909
+ ```typescript
910
+ export interface LinkControlDescription<
911
+ P = any,
912
+ > extends BaseControlDescription<P> {
913
+ type: ControlType.Link;
914
+ defaultValue?: string;
915
+ }
916
+ ```
917
+
918
+ ### Date Control
919
+
920
+ ```typescript
921
+ export interface DateControlDescription<P = any>
922
+ extends BaseControlDescription<P>, WithOptional {
923
+ type: ControlType.Date;
924
+ displayTime?: boolean;
925
+ defaultValue?: string;
926
+ }
927
+ ```
928
+
929
+ ### Border Control
930
+
931
+ ```typescript
932
+ export type BorderStyle = "solid" | "dashed" | "dotted" | "double";
933
+
934
+ export interface Border {
935
+ borderColor?: string;
936
+ borderStyle?: BorderStyle;
937
+ borderWidth?: number;
938
+ borderTopWidth?: number;
939
+ borderLeftWidth?: number;
940
+ borderRightWidth?: number;
941
+ borderBottomWidth?: number;
942
+ }
943
+
944
+ export interface BorderControlDescription<P = any>
945
+ extends BaseControlDescription<P>, WithOptional {
946
+ type: ControlType.Border;
947
+ defaultValue?: Border;
948
+ }
949
+ ```
950
+
951
+ ### Cursor Control
952
+
953
+ ```typescript
954
+ export interface CursorControlDescription<
955
+ P = any,
956
+ > extends BaseControlDescription<P> {
957
+ type: ControlType.Cursor;
958
+ defaultValue?: string;
959
+ }
960
+ ```
961
+
962
+ ### Padding Control
963
+
964
+ ```typescript
965
+ export interface PaddingControlDescription<
966
+ P = any,
967
+ > extends BaseControlDescription<P> {
968
+ type: ControlType.Padding;
969
+ defaultValue?: string;
970
+ }
971
+ ```
972
+
973
+ ### Border Radius Control
974
+
975
+ ```typescript
976
+ export interface BorderRadiusControlDescription<
977
+ P = any,
978
+ > extends BaseControlDescription<P> {
979
+ type: ControlType.BorderRadius;
980
+ defaultValue?: string;
981
+ }
982
+ ```
983
+
984
+ ### Gap Control
985
+
986
+ ```typescript
987
+ export interface GapControlDescription<
988
+ P = any,
989
+ > extends BaseControlDescription<P> {
990
+ type: ControlType.Gap;
991
+ defaultValue?: string;
992
+ }
993
+ ```
994
+
995
+ ### Tracking ID Control
996
+
997
+ ```typescript
998
+ export interface TrackingIdControlDescription<
999
+ P = any,
1000
+ > extends BaseControlDescription<P> {
1001
+ type: ControlType.TrackingId;
1002
+ defaultValue?: string;
1003
+ }
1004
+ ```
1005
+
1006
+ ### Font Control
1007
+
1008
+ ```typescript
1009
+ interface FontControlDescriptionBase<
1010
+ P = any,
1011
+ > extends BaseControlDescription<P> {
1012
+ type: ControlType.Font;
1013
+ controls?: "basic" | "extended";
1014
+ displayTextAlignment?: boolean;
1015
+ displayFontSize?: boolean;
1016
+ defaultValue?: FontControlDefaultValueBase;
1017
+ }
1018
+
1019
+ interface FontControlDescriptionSansSerif<
1020
+ P = any,
1021
+ > extends FontControlDescriptionBase<P> {
1022
+ defaultFontType?: "sans-serif";
1023
+ defaultValue?: FontControlDefaultValueWithVariant;
1024
+ }
1025
+
1026
+ interface FontControlDescriptionSerif<
1027
+ P = any,
1028
+ > extends FontControlDescriptionBase<P> {
1029
+ defaultFontType?: "serif";
1030
+ defaultValue?: FontControlDefaultValueBase;
1031
+ }
1032
+
1033
+ interface FontControlDescriptionMonospace<
1034
+ P = any,
1035
+ > extends FontControlDescriptionBase<P> {
1036
+ defaultFontType?: "monospace";
1037
+ defaultValue?: FontControlDefaultValueBase;
1038
+ }
1039
+
1040
+ export type FontControlDescription<P = any> =
1041
+ | FontControlDescriptionSansSerif<P>
1042
+ | FontControlDescriptionSerif<P>
1043
+ | FontControlDescriptionMonospace<P>;
1044
+
1045
+ interface FontControlDefaultValueBase {
1046
+ textAlign?: "left" | "right" | "center" | "justify";
1047
+ fontSize?: string | number;
1048
+ letterSpacing?: string | number;
1049
+ lineHeight?: string | number;
1050
+ }
1051
+
1052
+ interface FontControlDefaultValueWithVariant extends FontControlDefaultValueBase {
1053
+ variant?: FramerFontVariant;
1054
+ }
1055
+
1056
+ export const framerFontVariants = [
1057
+ "Regular",
1058
+ "Thin",
1059
+ "Extra Light",
1060
+ "Light",
1061
+ "Medium",
1062
+ "Semibold",
1063
+ "Bold",
1064
+ "Extra Bold",
1065
+ "Black",
1066
+ "Thin Italic",
1067
+ "Extra Light Italic",
1068
+ "Light Italic",
1069
+ "Italic",
1070
+ "Medium Italic",
1071
+ "Semibold Italic",
1072
+ "Bold Italic",
1073
+ "Extra Bold Italic",
1074
+ "Black Italic",
1075
+ "Regular Italic",
1076
+ "Variable",
1077
+ "Variable Italic",
1078
+ ] as const;
1079
+
1080
+ export type FramerFontVariant = (typeof framerFontVariants)[number];
1081
+ ```
1082
+
1083
+ ## Composite Types
1084
+
1085
+ ### All Control Types
1086
+
1087
+ ```typescript
1088
+ export type ControlDescription<P = any> =
1089
+ | NumberControlDescription<P>
1090
+ | EnumControlDescription<P>
1091
+ | BooleanControlDescription<P>
1092
+ | StringControlDescription<P>
1093
+ | ColorControlDescription<P>
1094
+ | ResponsiveImageControlDescription<P>
1095
+ | FileControlDescription<P>
1096
+ | SlotControlDescription<P>
1097
+ | ArrayControlDescription<P>
1098
+ | EventHandlerControlDescription<P>
1099
+ | TransitionControlDescription<P>
1100
+ | BoxShadowControlDescription<P>
1101
+ | LinkControlDescription<P>
1102
+ | DateControlDescription<P>
1103
+ | ObjectControlDescription<P>
1104
+ | FontControlDescription<P>
1105
+ | BorderControlDescription<P>
1106
+ | CursorControlDescription<P>
1107
+ | PaddingControlDescription<P>
1108
+ | BorderRadiusControlDescription<P>
1109
+ | GapControlDescription<P>
1110
+ | TrackingIdControlDescription<P>;
1111
+ ```
1112
+
1113
+ ### Property Controls
1114
+
1115
+ ```typescript
1116
+ export type PropertyControls<ComponentProps = any, ArrayTypes = any> = {
1117
+ [K in keyof ComponentProps]?: ControlDescription<Partial<ComponentProps>>;
1118
+ };
1119
+ ```
1120
+
1121
+ ## Associated Methods and Types
1122
+
1123
+ ### addPropertyControls
1124
+
1125
+ ```typescript
1126
+ export declare function addPropertyControls<Props = any>(
1127
+ component:
1128
+ | React.ComponentType<Props>
1129
+ | React.ForwardRefExoticComponent<Props>,
1130
+ propertyControls: PropertyControls<Props>,
1131
+ ): void;
1132
+ ```
1133
+
1134
+ ### addFonts
1135
+
1136
+ ```typescript
1137
+ export declare function addFonts(
1138
+ component: React.ComponentType<unknown>,
1139
+ fonts: any[],
1140
+ flags?: { supportsExplicitInterCodegen?: boolean },
1141
+ ): void;
1142
+ ```
1143
+
1144
+ ### Data API
1145
+
1146
+ ```typescript
1147
+ export declare const Data: {
1148
+ <T extends object = object>(initial?: Partial<T> | object): T;
1149
+ };
1150
+ ```
1151
+
1152
+ ### Renderer Detection APIs
1153
+
1154
+ ```typescript
1155
+ export declare type RenderTarget = RenderTargetName;
1156
+
1157
+ export declare const RenderTarget: {
1158
+ canvas: RenderTargetName;
1159
+ export: RenderTargetName;
1160
+ thumbnail: RenderTargetName;
1161
+ preview: RenderTargetName;
1162
+ current: () => RenderTargetName;
1163
+ hasRestrictions: () => boolean;
1164
+ };
1165
+
1166
+ /** Check if executed in a Framer Canvas or Export Canvas environment */
1167
+ export declare function isStaticRenderer(): boolean;
1168
+
1169
+ /** Hook to check if in a static renderer (Canvas or Export) */
1170
+ export declare function useIsStaticRenderer(): boolean;
1171
+
1172
+ /** Hook to observe data changes */
1173
+ export declare function useObserveData(): boolean;
1174
+ ```
1175
+
1176
+ ### Color Interface and Utilities
1177
+
1178
+ ```typescript
1179
+ export interface Color {
1180
+ r: number;
1181
+ g: number;
1182
+ b: number;
1183
+ h: number;
1184
+ s: number;
1185
+ l: number;
1186
+ a: number;
1187
+ roundA: number;
1188
+ format: ColorFormat;
1189
+ initialValue?: string;
1190
+ isValid?: boolean;
1191
+ mix: any;
1192
+ toValue: () => string;
1193
+ }
1194
+
1195
+ export enum ColorFormat {
1196
+ RGB = "rgb",
1197
+ HSL = "hsl",
1198
+ HSV = "hsv",
1199
+ HEX = "hex",
1200
+ NAME = "name",
1201
+ }
1202
+ ```
1203
+
1204
+ ---
1205
+
1206
+ # Property Control Guide
1207
+
1208
+ Font styling patterns, variant mapping, and recommended default values for Framer property controls. ## Styling of text elements
1209
+
1210
+ 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:
1211
+ - `FontControlDescription.defaultValue.fontSize` for `font-size`
1212
+ - `FontControlDescription.defaultValue.textAlignment` for `text-alignment`
1213
+ - `FontControlDescription.defaultValue.letterSpacing` for `letter-spacing`
1214
+ - `FontControlDescription.defaultValue.lineHeight` for `line-height`
1215
+ - `FontControlDescription.defaultValue.variant` for `font-weight` and/or `font-style`
1216
+ - `FontControlDescription.defaultValue.variant` can be set only if `FontControlDescription.defaultFontType` is set to `"sans-serif"`
1217
+
1218
+ Remarks:
1219
+ - `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.
1220
+ - Set `FontControlDescription.controls` to `"extended"` to expose full typography options (size, weight, spacing, alignment).
1221
+
1222
+ When you need to use font weight you should use `FontControlDescription.defaultValue.variant`.
1223
+ 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:
1224
+
1225
+ ```ts
1226
+ interface ResolvedFontVariant {
1227
+ fontStyle: "normal" | "italic"
1228
+ weight: number
1229
+ }
1230
+
1231
+ const variantNameToFontWeight: Record<FramerFontVariant, ResolvedFontVariant> = {
1232
+ Regular: { fontStyle: "normal", fontWeight: 400 },
1233
+ Thin: { fontStyle: "normal", fontWeight: 100 },
1234
+ "Extra Light": { fontStyle: "normal", fontWeight: 200 },
1235
+ Light: { fontStyle: "normal", fontWeight: 300 },
1236
+ Medium: { fontStyle: "normal", fontWeight: 500 },
1237
+ Semibold: { fontStyle: "normal", fontWeight: 600 },
1238
+ Bold: { fontStyle: "normal", fontWeight: 700 },
1239
+ "Extra Bold": { fontStyle: "normal", fontWeight: 800 },
1240
+ Black: { fontStyle: "normal", fontWeight: 900 },
1241
+ "Thin Italic": { fontStyle: "italic", fontWeight: 100 },
1242
+ "Extra Light Italic": { fontStyle: "italic", fontWeight: 200 },
1243
+ "Light Italic": { fontStyle: "italic", fontWeight: 300 },
1244
+ Italic: { fontStyle: "italic", fontWeight: 400 },
1245
+ "Medium Italic": { fontStyle: "italic", fontWeight: 500 },
1246
+ "Semibold Italic": { fontStyle: "italic", fontWeight: 600 },
1247
+ "Bold Italic": { fontStyle: "italic", fontWeight: 700 },
1248
+ "Extra Bold Italic": { fontStyle: "italic", fontWeight: 800 },
1249
+ "Black Italic": { fontStyle: "italic", fontWeight: 900 },
1250
+ "Regular Italic": { fontStyle: "italic", fontWeight: 400 },
1251
+ }
1252
+ ```
1253
+
1254
+ Example of a simple text component in Framer which demonstrates how to use Property Control of type `ControlType.Font`.
1255
+
1256
+ ```tsx
1257
+ import { addPropertyControls, ControlType } from "framer"
1258
+
1259
+ /**
1260
+ * @framerSupportedLayoutWidth auto
1261
+ * @framerSupportedLayoutHeight auto
1262
+ */
1263
+ export default function SimpleText(props) {
1264
+ const { label, heading } = props
1265
+ return (
1266
+ <span
1267
+ style={{
1268
+ fontSize: heading.fontSize,
1269
+ textAlign: heading.textAlign,
1270
+ fontWeight: heading.fontWeight,
1271
+ fontFamily: heading.fontFamily,
1272
+ lineHeight: heading.lineHeight,
1273
+ letterSpacing: heading.letterSpacing,
1274
+ fontStyle: heading.fontStyle,
1275
+ }}
1276
+ >
1277
+ {label}
1278
+ </span>
1279
+ )
1280
+ }
1281
+
1282
+ addPropertyControls(SimpleText, {
1283
+ heading: {
1284
+ type: ControlType.Font,
1285
+ title: "Heading 2 Font",
1286
+ defaultValue: {
1287
+ textAlign: "right",
1288
+ fontSize: 40,
1289
+ variant: "Extra Bold",
1290
+ letterSpacing: "-0.03em",
1291
+ lineHeight: "1em",
1292
+ },
1293
+ controls: "extended",
1294
+ defaultFontType: "sans-serif",
1295
+ },
1296
+ label: {
1297
+ title: "Label",
1298
+ type: ControlType.String,
1299
+ defaultValue: "Hello",
1300
+ },
1301
+ })
1302
+ ```
1303
+
1304
+ ## Default Control Values
1305
+
1306
+ Recommended default values for common control types.
1307
+
1308
+ ### Colors
1309
+
1310
+ Recommended color defaults:
1311
+
1312
+ ```typescript
1313
+ const colors: Record<string, ColorControlDescription> = {
1314
+ /** Use for main container backgrounds, cards, and primary surfaces */
1315
+ background: {
1316
+ type: ControlType.Color,
1317
+ defaultValue: "#FFFFFF", // White: backgrounds
1318
+ },
1319
+ /** Use for secondary backgrounds, input fields, and subtle visual elements */
1320
+ subtleBackground: {
1321
+ type: ControlType.Color,
1322
+ defaultValue: "#F5F5F5", // Very light gray: subtle backgrounds, placeholders
1323
+ },
1324
+ /** Use for borders, dividers, and visual separators */
1325
+ darkBackground: {
1326
+ type: ControlType.Color,
1327
+ defaultValue: "#EEEEEE", // Light gray: borders, separators
1328
+ },
1329
+ /** Use for secondary text, icons, and less prominent UI elements */
1330
+ tertiary: {
1331
+ type: ControlType.Color,
1332
+ defaultValue: "#CCCCCC", // Medium gray: text, icons
1333
+ },
1334
+ /** Use for primary text, icons, and key UI elements that need emphasis */
1335
+ primary: {
1336
+ type: ControlType.Color,
1337
+ defaultValue: "#000000", // Black: text, icons
1338
+ },
1339
+ }
1340
+ ```
1341
+
1342
+ ### Images
1343
+
1344
+ To provide a default image, set it via destructuring in the component body (`ControlType.ResponsiveImage` does not support `defaultValue`):
1345
+ ```tsx
1346
+ const { image = { src: "https://framerusercontent.com/images/GfGkADagM4KEibNcIiRUWlfrR0.jpg", alt: "Gradient 1 - Blue" } } = props
1347
+ ```
1348
+ When applying image properties to elements, use spreads like `{...image}`.
1349
+
1350
+ Recommended image sources (gradient series — use in sequence when multiple are needed):
1351
+
1352
+ ```typescript
1353
+ const images = {
1354
+ /** Use for professional or corporate contexts, informational content, or quinary image slot */
1355
+ image1: {
1356
+ src: "https://framerusercontent.com/images/GfGkADagM4KEibNcIiRUWlfrR0.jpg",
1357
+ alt: "Gradient 1 - Blue"
1358
+ },
1359
+ /** Use for creative or innovative contexts, feature highlights, or quaternary image slot */
1360
+ image2: {
1361
+ src: "https://framerusercontent.com/images/aNsAT3jCvt4zglbWCUoFe33Q.jpg",
1362
+ alt: "Gradient 2 - Purple"
1363
+ },
1364
+ /** Use for energetic contexts, call-to-action backgrounds, or tertiary image slot */
1365
+ image3: {
1366
+ src: "https://framerusercontent.com/images/BYnxEV1zjYb9bhWh1IwBZ1ZoS60.jpg",
1367
+ alt: "Gradient 3 - Orange"
1368
+ },
1369
+ /** Use for warm-toned contexts, product showcases, or secondary image slot */
1370
+ image4: {
1371
+ src: "https://framerusercontent.com/images/2uTNEj5aTl2K3NJaEFWMbnrA.jpg",
1372
+ alt: "Gradient 4 - Yellow"
1373
+ },
1374
+ /** Use for nature-themed components, environmental contexts, or primary image slot */
1375
+ image5: {
1376
+ src: "https://framerusercontent.com/images/f9RiWoNpmlCMqVRIHz8l8wYfeI.jpg",
1377
+ alt: "Gradient 5 - Green"
1378
+ }
1379
+ }
1380
+ ```
1381
+
1382
+ ### Typography
1383
+
1384
+ Use these exact font definitions for all text elements
1385
+
1386
+ ```typescript
1387
+ const typography: Record<string, FontControlDescription> = {
1388
+ /** Use for main page titles and primary headlines */
1389
+ heading1: {
1390
+ type: ControlType.Font,
1391
+ title: "Heading 1 Font",
1392
+ defaultValue: {
1393
+ fontSize: "40px",
1394
+ variant: "Bold",
1395
+ letterSpacing: "-0.04em",
1396
+ lineHeight: "1em",
1397
+ },
1398
+ controls: "extended",
1399
+ defaultFontType: "sans-serif",
1400
+ },
1401
+ /** Use for section titles and secondary headlines */
1402
+ heading2: {
1403
+ type: ControlType.Font,
1404
+ title: "Heading 2 Font",
1405
+ defaultValue: {
1406
+ fontSize: "32px",
1407
+ variant: "Semibold",
1408
+ letterSpacing: "-0.03em",
1409
+ lineHeight: "1em",
1410
+ },
1411
+ controls: "extended",
1412
+ defaultFontType: "sans-serif",
1413
+ },
1414
+ /** Use for subsection titles and feature headings */
1415
+ heading3: {
1416
+ type: ControlType.Font,
1417
+ title: "Heading 3 Font",
1418
+ defaultValue: {
1419
+ fontSize: "22px",
1420
+ variant: "Semibold",
1421
+ letterSpacing: "-0.01em",
1422
+ lineHeight: "1.2em",
1423
+ },
1424
+ controls: "extended",
1425
+ defaultFontType: "sans-serif",
1426
+ },
1427
+ /** Use for card titles, list headings, and UI element headers */
1428
+ heading4: {
1429
+ type: ControlType.Font,
1430
+ title: "Heading 4 Font",
1431
+ defaultValue: {
1432
+ fontSize: "15px",
1433
+ variant: "Medium",
1434
+ letterSpacing: "-0.01em",
1435
+ lineHeight: "1em",
1436
+ },
1437
+ controls: "extended",
1438
+ defaultFontType: "sans-serif",
1439
+ },
1440
+ /** Use for body text, descriptions, and general content */
1441
+ paragraph: {
1442
+ type: ControlType.Font,
1443
+ title: "Paragraph Font",
1444
+ defaultValue: {
1445
+ fontSize: "15px",
1446
+ variant: "Medium",
1447
+ letterSpacing: "-0.01em",
1448
+ lineHeight: "1.3em",
1449
+ },
1450
+ controls: "extended",
1451
+ defaultFontType: "sans-serif",
1452
+ },
1453
+ /** Use for buttons, links, and interactive text elements */
1454
+ buttonText: {
1455
+ type: ControlType.Font,
1456
+ title: "Button Text Font",
1457
+ defaultValue: {
1458
+ variant: "Semibold",
1459
+ fontSize: "14px",
1460
+ letterSpacing: "-0.01em",
1461
+ lineHeight: "1em",
1462
+ },
1463
+ controls: "extended",
1464
+ defaultFontType: "sans-serif",
1465
+ },
1466
+ }
1467
+ ```
1468
+
1469
+ ### File Types
1470
+
1471
+ `ControlType.File` does not support `defaultValue` in its property control. Set default values through component parameter destructuring instead.
1472
+
1473
+ ```typescript
1474
+ const fileTypes: Record<string, FileControlDescription> = {
1475
+ /** Use for image upload fields, gallery components, and avatar selectors */
1476
+ images: {
1477
+ type: ControlType.File,
1478
+ allowedFileTypes: ["jpg", "jpeg", "png", "gif", "webp", "svg"],
1479
+ },
1480
+ /** Use for video players, media galleries, and promotional content */
1481
+ videos: {
1482
+ type: ControlType.File,
1483
+ allowedFileTypes: ["mp4", "webm", "mov"],
1484
+ },
1485
+ /** Use for document viewers, file download components, and resource sections */
1486
+ documents: {
1487
+ type: ControlType.File,
1488
+ allowedFileTypes: ["pdf", "doc", "docx", "txt"],
1489
+ },
1490
+ /** Use for audio players, podcast components, and music interfaces */
1491
+ audio: {
1492
+ type: ControlType.File,
1493
+ allowedFileTypes: ["mp3", "wav", "ogg"],
1494
+ },
1495
+ }
1496
+ ```
1497
+
1498
+ Use the following values for each file type as default values:
1499
+
1500
+ ```typescript
1501
+ const defaultValues: Record<keyof typeof fileTypes, string> = {
1502
+ images: "https://framerusercontent.com/images/GfGkADagM4KEibNcIiRUWlfrR0.jpg",
1503
+ videos: "https://framerusercontent.com/assets/MLWPbW1dUQawJLhhun3dBwpgJak.mp4",
1504
+ audio: "https://framerusercontent.com/assets/8w3IUatLX9a5JVJ6XPCVuHi94.mp3",
1505
+ }
1506
+ ```
1507
+
1508
+ Recommended pattern for file control defaults:
1509
+
1510
+ ```tsx
1511
+ function MyComponent(props) {
1512
+ // CORRECT: Set file defaults through parameter destructuring
1513
+ const {
1514
+ imageFile = "https://framerusercontent.com/images/GfGkADagM4KEibNcIiRUWlfrR0.jpg",
1515
+ videoFile = "https://framerusercontent.com/assets/MLWPbW1dUQawJLhhun3dBwpgJak.mp4",
1516
+ audioFile = "https://framerusercontent.com/assets/8w3IUatLX9a5JVJ6XPCVuHi94.mp3",
1517
+ } = props
1518
+
1519
+ return (
1520
+ <div>
1521
+ <img src={imageFile} />
1522
+ <video src={videoFile} />
1523
+ <audio src={audioFile} />
1524
+ </div>
1525
+ )
1526
+ }
1527
+
1528
+ addPropertyControls(MyComponent, {
1529
+ imageFile: {
1530
+ type: ControlType.File,
1531
+ allowedFileTypes: ["jpg", "jpeg", "png", "gif", "webp", "svg"],
1532
+ },
1533
+ // Additional file controls...
1534
+ })
1535
+ ```