framer-api 0.1.1 → 0.1.2-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -46,9 +46,11 @@ type LintIssueSeverityValue = "error" | "warning";
46
46
  /** @deprecated The lintCode API was removed. This type will be removed in the near future. */
47
47
  type LintConfig = Record<LintRuleNameValue, LintIssueSeverityValue>;
48
48
  interface DiagnosticBase {
49
+ /** The error or warning message describing the diagnostic. */
49
50
  message: string;
50
51
  span?: DiagnosticSpan;
51
52
  }
53
+ /** A span of characters in a code file, used to locate a diagnostic. */
52
54
  interface DiagnosticSpan {
53
55
  /** The first character, counted from the beginning of the file, 0-based. */
54
56
  offset: number;
@@ -67,18 +69,23 @@ interface LintLink {
67
69
  interface LintDiagnostic extends DiagnosticBase {
68
70
  /** The span of the invalid code in the file. */
69
71
  span: DiagnosticSpan;
72
+ /** Issue severity: `"error"` or `"warning"`. */
70
73
  severity: LintIssueSeverityValue;
74
+ /** Optional documentation link for the diagnostic issue. */
71
75
  link?: LintLink;
72
76
  }
77
+ /** A diagnostic produced by type-checking a code file. */
73
78
  interface TypecheckDiagnostic extends DiagnosticBase {
74
79
  /**
75
80
  * The span of the invalid code in the file.
76
81
  * Could be undefined if the diagnostic is system-level (and not file-specific), like e.g. an error about invalid TS options.
77
82
  */
78
83
  span?: DiagnosticSpan;
79
- /** Could be undefined if the diagnostic is system-level (and not file-specific), like e.g. an error about invalid TS options */
84
+ /** Source file name. Could be undefined if the diagnostic is system-level (and not file-specific), like e.g. an error about invalid TS options. */
80
85
  fileName?: string;
86
+ /** TypeScript error code. */
81
87
  code: number;
88
+ /** Error category from the TypeScript compiler. */
82
89
  category: ts.DiagnosticCategory;
83
90
  }
84
91
 
@@ -108,40 +115,94 @@ declare const getHTMLForNodeMessageType = "INTERNAL_getHTMLForNode";
108
115
  declare const setHTMLForNodeMessageType = "INTERNAL_setHTMLForNode";
109
116
 
110
117
  type LocaleId = string;
118
+ /**
119
+ * A locale configured in the project for localization. Locales represent
120
+ * a language paired with an optional region (e.g. English, or English (Canada)).
121
+ */
111
122
  interface Locale {
123
+ /** A unique identifier for the locale. */
112
124
  id: LocaleId;
125
+ /** The BCP 47 language code, e.g. `"en-US"` or `"nl"`. */
113
126
  code: string;
127
+ /** The display name of the locale, e.g. `"English (US)"`. */
114
128
  name: string;
129
+ /** The URL slug used for this locale, e.g. `"en"`. */
115
130
  slug: string;
131
+ /**
132
+ * The ID of the fallback locale. When a Localization Source does not have
133
+ * a localized value set for this locale, Framer will fall back to the value
134
+ * defined in the fallback locale.
135
+ */
116
136
  fallbackLocaleId?: string;
117
137
  }
138
+ /**
139
+ * Input for creating a new locale.
140
+ * @alpha
141
+ */
142
+ interface CreateLocaleInput {
143
+ /** The language code (e.g., "en", "fr", "zh-Hans"). Use `getLocaleLanguages()` to get the list of valid codes. */
144
+ language: string;
145
+ /** The optional region code (e.g., "US", "CA"). Use `getLocaleRegions(language)` to get the list of valid codes. */
146
+ region?: string;
147
+ /** ID of the fallback locale. Must reference an existing locale. */
148
+ fallbackLocaleId?: LocaleId;
149
+ /** URL slug for the locale (e.g., "en"). If not provided, one is derived from the code. */
150
+ slug?: string;
151
+ /** Display Name for the locale (e.g., "English (US)"). If not provided, one is derived from the code. */
152
+ name?: string;
153
+ /** Flag to mark the locale as a draft. Defaults to `false`. */
154
+ draft?: boolean;
155
+ }
118
156
  interface LocalizationValueBase {
119
- /** A `value` of `null` means that the value explicitly falls back to the fallback locale */
157
+ /**
158
+ * The actual text of the localized value. A `value` of `null` means that
159
+ * the value will fall back to the value set in the fallback locale.
160
+ */
120
161
  value: string | null;
162
+ /** The timestamp (in milliseconds since epoch) of when this localized value was last edited. */
121
163
  lastEdited: number;
122
164
  /**
123
165
  * Whether the value is read only and therefore cannot be updated.
124
166
  *
125
167
  * For example, this is the case for localized values that were set
126
168
  * when syncing a managed collection. To update these values, you must
127
- * sync using the plugin that manages the collection.
169
+ * provide them when syncing the plugin that manages the collection.
128
170
  */
129
171
  readonly: boolean;
130
172
  }
173
+ /** A localization value that has not been set yet. */
131
174
  interface LocalizationValueNew {
175
+ /** Always `null` for new (unset) localization values. */
132
176
  value: null;
177
+ /** Indicates this value is currently not set. */
133
178
  status: "new";
134
179
  }
180
+ /** A localization value that has been set but needs review, either manually flagged or because the default locale value changed. */
135
181
  interface LocalizationValueNeedsReview extends LocalizationValueBase {
182
+ /** Indicates this value needs review. */
136
183
  status: "needsReview";
137
184
  }
185
+ /** A localization value that has been set and is considered complete. */
138
186
  interface LocalizationValueDone extends LocalizationValueBase {
187
+ /** Indicates this value has been set. */
139
188
  status: "done";
140
189
  }
190
+ /** A localization value that has been set but has warnings. */
141
191
  interface LocalizationValueWarning extends LocalizationValueBase {
192
+ /** Indicates this value has warnings. */
142
193
  status: "warning";
194
+ /** A message describing why the localized value has a warning status. Only set when status is `"warning"`. */
143
195
  warning: string;
144
196
  }
197
+ /**
198
+ * The localized value and associated metadata for a specific locale. Use the `status`
199
+ * discriminator to narrow the type:
200
+ *
201
+ * - `"new"` - A value that is currently not set.
202
+ * - `"needsReview"` - A value that has been set but marked as needing review.
203
+ * - `"warning"` - A value that has been set but has warnings.
204
+ * - `"done"` - A value that has been set and is complete.
205
+ */
145
206
  type LocalizationValue = LocalizationValueNew | LocalizationValueNeedsReview | LocalizationValueDone | LocalizationValueWarning;
146
207
  type LocalizationValueByLocale = Record<LocaleId, LocalizationValue>;
147
208
  type InlineLocalizationValueByLocale = Record<LocaleId, LocalizationValue>;
@@ -149,24 +210,45 @@ type LocalizationGroupId = string;
149
210
  type LocalizationSourceId = string;
150
211
  type LocalizedValueStatus = LocalizationValue["status"];
151
212
  type LocalizationSourceType = "string" | "formattedText" | "altText" | "slug" | "link";
213
+ /**
214
+ * A localizable string on your site. Localization sources are the actual
215
+ * translatable strings from your site, along with their localized values.
216
+ */
152
217
  interface LocalizationSource {
153
- /** A stable ID of the localization source that can be used for updating and synchronizing */
218
+ /** A unique identifier for the localization source, stable across syncs. */
154
219
  id: LocalizationSourceId;
155
- /** The type of value for this source */
220
+ /** The type of value for this source, such as `"string"`, `"formattedText"`, `"altText"`, `"slug"`, or `"link"`. */
156
221
  type: LocalizationSourceType;
157
- /** Current Source value */
222
+ /** The current value of the localization source in the default locale. */
158
223
  value: string;
159
- /** Localized values and metadata for each locale */
224
+ /** Localized values and metadata for each locale, keyed by locale ID. */
160
225
  valueByLocale: LocalizationValueByLocale;
161
226
  }
162
227
  type LocalizationGroupStatus = "excluded" | "ready";
163
228
  type LocalizationGroupStatusByLocale = Record<LocaleId, LocalizationGroupStatus>;
229
+ /**
230
+ * A group of related localization sources, such as all translatable content for a
231
+ * page or collection item. Localization groups are things like pages or CMS items
232
+ * that contain one or more localization sources.
233
+ *
234
+ * A group can have a different status in each locale. For example, you may want to
235
+ * show a blog post in your French locale but exclude it in your Dutch locale.
236
+ */
164
237
  interface LocalizationGroup {
238
+ /** A unique identifier for the localization group. */
165
239
  id: LocalizationGroupId;
240
+ /** The name of the localization group. */
166
241
  name: string;
242
+ /** The kind of content this group represents. */
167
243
  type: "collection" | "collection-item" | "component" | "page" | "settings" | "template";
244
+ /** Whether this group supports the `"excluded"` status for locales. */
168
245
  supportsExcludedStatus: boolean;
246
+ /** The localization sources within this group. */
169
247
  sources: LocalizationSource[];
248
+ /**
249
+ * The status of each locale for this group. A localization group can have
250
+ * a different status in each locale (`"excluded"` or `"ready"`).
251
+ */
170
252
  statusByLocale: LocalizationGroupStatusByLocale;
171
253
  }
172
254
  type LocalizedValueUpdate = {
@@ -270,6 +352,7 @@ declare const fontWeights: readonly [100, 200, 300, 400, 500, 600, 700, 800, 900
270
352
  * - `900` - Black (Heavy)
271
353
  * */
272
354
  type FontWeight = (typeof fontWeights)[number];
355
+ /** A font available in the project, including custom uploaded fonts. */
273
356
  declare class Font {
274
357
  /** An identifier used internally for differentiating fonts. */
275
358
  readonly selector: string;
@@ -546,9 +629,13 @@ interface WithReplicaInfoTrait {
546
629
  readonly originalId: string | null;
547
630
  }
548
631
  interface WithComponentVariantTrait {
632
+ /** Whether this is a component variant. Supported by FrameNode. */
549
633
  readonly isVariant: boolean;
634
+ /** Whether this is the primary variant. Supported by FrameNode. */
550
635
  readonly isPrimaryVariant: boolean;
636
+ /** Gesture state for component variants: `"hover"`, `"pressed"`, `"loading"`, or `"error"`. Supported by FrameNode. */
551
637
  readonly gesture: Gesture | null;
638
+ /** ID of the node this variant inherits from. Supported by FrameNode. */
552
639
  readonly inheritsFromId: string | null;
553
640
  }
554
641
  interface IsComponentVariant {
@@ -560,16 +647,31 @@ interface IsComponentGestureVariant extends IsComponentVariant {
560
647
  readonly gesture: Gesture;
561
648
  }
562
649
  interface WithNameTrait {
650
+ /**
651
+ * The name of the node displayed in the layers panel.
652
+ * Supported by FrameNode, TextNode, SVGNode, ComponentInstanceNode,
653
+ * ComponentNode, VectorSetNode, VectorSetItemNode.
654
+ */
563
655
  readonly name: string | null;
564
656
  }
565
657
  interface WithVisibleTrait {
658
+ /**
659
+ * Whether the node is visible on the canvas. Defaults to `true`.
660
+ * Supported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.
661
+ */
566
662
  readonly visible: boolean;
567
663
  }
568
664
  interface WithLockedTrait {
665
+ /**
666
+ * Whether the node is locked for editing. Defaults to `false`.
667
+ * Supported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.
668
+ */
569
669
  readonly locked: boolean;
570
670
  }
571
671
  interface WithBreakpointTrait {
672
+ /** Whether this is a breakpoint. Supported by FrameNode. */
572
673
  readonly isBreakpoint: boolean;
674
+ /** Whether this is the primary breakpoint. Supported by FrameNode. */
573
675
  readonly isPrimaryBreakpoint: boolean;
574
676
  }
575
677
  interface IsBreakpoint {
@@ -577,23 +679,41 @@ interface IsBreakpoint {
577
679
  readonly isPrimaryBreakpoint: boolean;
578
680
  }
579
681
  interface WithBackgroundColorTrait<T extends TraitVariant> {
580
- /** Color of the frame in RGBA format, e.g `rgba(242, 59, 57, 1)`, or as a `ColorStyle` instance. */
682
+ /**
683
+ * Background color in RGBA format (e.g. `rgba(242, 59, 57, 1)`) or as a {@link ColorStyle} instance.
684
+ * Setting to `null` removes the background color. Supported by FrameNode.
685
+ */
581
686
  readonly backgroundColor: (T extends TraitVariantData ? ColorStyleData : ColorStyle) | string | null;
582
687
  }
583
688
  interface WithBackgroundImageTrait<T extends TraitVariant> {
689
+ /** Background image asset. Supported by FrameNode. */
584
690
  readonly backgroundImage: (T extends TraitVariantData ? ImageAssetData : ImageAsset) | null;
585
691
  }
586
692
  interface WithBackgroundGradientTrait<T extends TraitVariant> {
693
+ /** Background gradient (linear, radial, or conic). Supported by FrameNode. */
587
694
  readonly backgroundGradient: (T extends TraitVariantData ? GradientData : Gradient) | null;
588
695
  }
589
696
  interface WithRotationTrait {
697
+ /**
698
+ * Rotation angle in degrees. Defaults to `0`.
699
+ * Supported by FrameNode, TextNode, SVGNode, ComponentInstanceNode.
700
+ */
590
701
  readonly rotation: number;
591
702
  }
592
703
  interface WithOpacityTrait {
704
+ /**
705
+ * Opacity of the node, from `0` (fully transparent) to `1` (fully opaque). Defaults to `1`.
706
+ * Supported by FrameNode, TextNode, SVGNode, ComponentInstanceNode.
707
+ */
593
708
  readonly opacity: number;
594
709
  }
595
710
  type BorderRadius = CSSDimension<CSSUnit.Percentage | CSSUnit.Pixel> | `${CSSDimension<CSSUnit.Pixel>} ${CSSDimension<CSSUnit.Pixel>} ${CSSDimension<CSSUnit.Pixel>} ${CSSDimension<CSSUnit.Pixel>}` | null;
596
711
  interface WithBorderRadiusTrait {
712
+ /**
713
+ * Border radius for rounded corners. Single value (e.g. `"10px"` or `"50%"`)
714
+ * or per-corner (e.g. `"10px 20px 30px 40px"` for top-left, top-right, bottom-right, bottom-left).
715
+ * Setting to `null` removes the border radius. Supported by FrameNode.
716
+ */
597
717
  readonly borderRadius: BorderRadius;
598
718
  }
599
719
  type BorderWidth = CSSDimension<CSSUnit.Pixel> | `${CSSDimension<CSSUnit.Pixel>} ${CSSDimension<CSSUnit.Pixel>} ${CSSDimension<CSSUnit.Pixel>} ${CSSDimension<CSSUnit.Pixel>}`;
@@ -604,123 +724,271 @@ interface Border {
604
724
  style: BorderStyle;
605
725
  }
606
726
  interface WithBorderTrait<T extends TraitVariant> {
727
+ /**
728
+ * Border properties including width, color, and style.
729
+ * Styles: `"solid"`, `"dashed"`, `"dotted"`, `"double"`.
730
+ * Width can be per-side (e.g. `"1px 2px 3px 4px"`).
731
+ * Setting to `null` removes the border. Supported by FrameNode.
732
+ */
607
733
  readonly border: (T extends TraitVariantData ? Marshaled<Border> : Border) | null;
608
734
  }
735
+ /** Controls how images are rendered. Use `"pixelated"` for pixel art. */
609
736
  type ImageRendering = "auto" | "pixelated";
610
737
  interface WithImageRenderingTrait {
738
+ /**
739
+ * How images should be rendered when scaled: `"auto"` or `"pixelated"`.
740
+ * Only applies to frames with image backgrounds.
741
+ * Setting to `null` uses default rendering. Supported by FrameNode.
742
+ */
611
743
  readonly imageRendering: ImageRendering | null;
612
744
  }
745
+ /** Controls whether content that overflows the frame is clipped. */
613
746
  type Overflow = "visible" | "hidden" | "auto" | "clip";
614
747
  type AxisOverflow = Overflow;
615
748
  interface WithOverflowTrait {
749
+ /**
750
+ * Controls how content that exceeds the element's box is handled.
751
+ * Setting to `null` removes the overflow property. Will overwrite `overflowX` or `overflowY`.
752
+ * Supported by FrameNode, TextNode.
753
+ */
616
754
  readonly overflow: Overflow | null;
755
+ /**
756
+ * Controls horizontal overflow behavior.
757
+ * Setting to `null` removes the overflow X property. Supported by FrameNode, TextNode.
758
+ */
617
759
  readonly overflowX: AxisOverflow | null;
760
+ /**
761
+ * Controls vertical overflow behavior.
762
+ * Setting to `null` removes the overflow Y property. Supported by FrameNode, TextNode.
763
+ */
618
764
  readonly overflowY: AxisOverflow | null;
619
765
  }
620
766
  interface WithTextTruncationTrait {
767
+ /**
768
+ * Maximum number of lines a text node can display before being truncated with an ellipsis.
769
+ * Must be used alongside `overflow`. Setting to `null` removes the text truncation property.
770
+ * Supported by TextNode.
771
+ */
621
772
  readonly textTruncation: number | null;
622
773
  }
623
774
  interface WithZIndexTrait {
775
+ /**
776
+ * Stacking order of positioned elements. Higher values appear on top of lower values.
777
+ * Setting to `null` removes the z-index property. Supported by FrameNode, TextNode.
778
+ */
624
779
  readonly zIndex: number | null;
625
780
  }
626
781
  interface WithRequiredComponentInfoTrait {
782
+ /** Identifier of the component. Supported by ComponentInstanceNode, ComponentNode. */
627
783
  readonly componentIdentifier: string;
628
784
  }
629
785
  interface WithNullableComponentInfoTrait {
630
786
  readonly insertURL: string | null;
787
+ /** Name of the component. Supported by ComponentInstanceNode, ComponentNode. */
631
788
  readonly componentName: string | null;
632
789
  }
633
790
  interface WithComponentInfoTrait extends WithRequiredComponentInfoTrait, WithNullableComponentInfoTrait {
634
791
  }
635
792
  interface WithWebPageInfoTrait {
793
+ /** URL path for the web page. Supported by WebPageNode. */
636
794
  readonly path: string | null;
795
+ /** Collection ID for the web page. Supported by WebPageNode. */
637
796
  readonly collectionId: string | null;
638
797
  }
639
798
  interface WithLinkTrait {
799
+ /**
800
+ * URL or internal page link. External: `"https://example.com"`, internal: `"/about"`,
801
+ * email: `"mailto:user@example.com"`. Setting to `null` removes the link.
802
+ * Supported by FrameNode, TextNode.
803
+ */
640
804
  readonly link: string | null;
805
+ /**
806
+ * Whether to open the link in a new tab. Default is automatically determined based on link type.
807
+ * Supported by FrameNode, TextNode.
808
+ */
641
809
  readonly linkOpenInNewTab: boolean | null;
642
810
  }
643
811
  type ControlAttributes = Record<string, unknown>;
644
812
  interface WithControlAttributesTrait {
813
+ /** Property control values for code components. Supported by ComponentInstanceNode. */
645
814
  readonly controls: ControlAttributes;
646
815
  }
647
816
  interface WithSVGTrait {
817
+ /** SVG markup content. Supported by SVGNode. */
648
818
  readonly svg: string;
649
819
  }
820
+ /** The CSS position property for a node. */
650
821
  type Position = "relative" | "absolute" | "fixed" | "sticky";
651
822
  interface WithPositionTrait {
823
+ /**
824
+ * Positioning behavior of the node.
825
+ * - `"relative"`: Default for nodes in stack/grid layouts
826
+ * - `"absolute"`: Positioned relative to parent
827
+ * - `"fixed"`: Positioned relative to viewport
828
+ * - `"sticky"`: Sticks to viewport edges when scrolling
829
+ *
830
+ * Supported by FrameNode, TextNode, SVGNode, ComponentInstanceNode.
831
+ */
652
832
  position: Position;
653
833
  }
654
834
  type FitContent = "fit-content";
655
835
  type FitImage = "fit-image";
656
836
  interface WithPinsTrait {
837
+ /**
838
+ * Distance from top edge when using absolute/fixed positioning.
839
+ * Only applies when position is not `"relative"`.
840
+ * Supported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.
841
+ */
657
842
  top: CSSDimension<CSSUnit.Pixel> | null;
843
+ /**
844
+ * Distance from right edge when using absolute/fixed positioning.
845
+ * Only applies when position is not `"relative"`.
846
+ * Supported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.
847
+ */
658
848
  right: CSSDimension<CSSUnit.Pixel> | null;
849
+ /**
850
+ * Distance from bottom edge when using absolute/fixed positioning.
851
+ * Only applies when position is not `"relative"`.
852
+ * Supported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.
853
+ */
659
854
  bottom: CSSDimension<CSSUnit.Pixel> | null;
855
+ /**
856
+ * Distance from left edge when using absolute/fixed positioning.
857
+ * Only applies when position is not `"relative"`.
858
+ * Supported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.
859
+ */
660
860
  left: CSSDimension<CSSUnit.Pixel> | null;
861
+ /**
862
+ * Center anchor horizontal position as percentage (e.g. `"50%"`).
863
+ * Used when pins are not set.
864
+ * Supported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.
865
+ */
661
866
  centerX: CSSDimension<CSSUnit.Percentage> | null;
867
+ /**
868
+ * Center anchor vertical position as percentage (e.g. `"50%"`).
869
+ * Used when pins are not set.
870
+ * Supported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.
871
+ */
662
872
  centerY: CSSDimension<CSSUnit.Percentage> | null;
663
873
  }
664
874
  type Length = CSSDimension<CSSUnit.Pixel | CSSUnit.Percentage | CSSUnit.Fraction>;
665
875
  type WidthLength = Length | FitContent | FitImage;
666
876
  type HeightLength = Length | FitContent | CSSDimension<CSSUnit.ViewportHeight> | FitImage;
667
877
  interface WithSizeTrait {
878
+ /**
879
+ * Width of the node. Accepts pixel, percentage, fraction values, or `"fit-content"`.
880
+ * Supported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.
881
+ */
668
882
  width: WidthLength | null;
883
+ /**
884
+ * Height of the node. Accepts pixel, percentage, fraction, viewport-height values, or `"fit-content"`.
885
+ * Supported by FrameNode, TextNode, SVGNode, ComponentInstanceNode, VectorSetItemNode.
886
+ */
669
887
  height: HeightLength | null;
670
888
  }
671
889
  interface WithAspectRatioTrait {
890
+ /**
891
+ * Width-to-height ratio (e.g. `1.5` for 3:2).
892
+ * Setting to `null` removes the aspect ratio constraint.
893
+ * Supported by FrameNode, ComponentInstanceNode.
894
+ */
672
895
  aspectRatio: number | null;
673
896
  }
674
897
  type WidthConstraint = CSSDimension<CSSUnit.Pixel | CSSUnit.Percentage>;
675
898
  type HeightConstraint = CSSDimension<CSSUnit.Pixel | CSSUnit.Percentage | CSSUnit.ViewportHeight>;
676
899
  interface WithSizeConstraintsTrait {
900
+ /** Maximum width constraint. Supported by FrameNode, TextNode, ComponentInstanceNode. */
677
901
  maxWidth: WidthConstraint | null;
902
+ /** Minimum width constraint. Supported by FrameNode, TextNode, ComponentInstanceNode. */
678
903
  minWidth: WidthConstraint | null;
904
+ /** Maximum height constraint. Supported by FrameNode, TextNode, ComponentInstanceNode. */
679
905
  maxHeight: HeightConstraint | null;
906
+ /** Minimum height constraint. Supported by FrameNode, TextNode, ComponentInstanceNode. */
680
907
  minHeight: HeightConstraint | null;
681
908
  }
682
909
  interface WithInlineTextStyleTrait<T extends TraitVariant> {
910
+ /**
911
+ * Apply a text style preset. Setting to `null` removes the text style.
912
+ * Supported by TextNode.
913
+ */
683
914
  readonly inlineTextStyle: (T extends TraitVariantData ? TextStyleData : TextStyle) | null;
684
915
  }
685
916
  interface WithFontTrait<T extends TraitVariant> {
917
+ /** Font selection for text. Supported by TextNode. */
686
918
  readonly font: (T extends TraitVariantData ? FontData : Font) | null;
687
919
  }
688
920
  type TraitVariantData = "data";
689
921
  type TraitVariantNode = "node";
922
+ /** The direction children are laid out in a stack. */
690
923
  type StackDirection = "horizontal" | "vertical";
924
+ /** How children are distributed along the main axis of a stack. */
691
925
  type StackDistribution = "start" | "center" | "end" | "space-between" | "space-around" | "space-evenly";
926
+ /** How children are aligned along the cross axis of a stack. */
692
927
  type StackAlignment = "start" | "center" | "end";
928
+ /** The layout type for a frame: `"stack"` (flex) or `"grid"` (CSS grid). */
693
929
  type LayoutType = "stack" | "grid";
694
930
  interface StackLayout {
931
+ /** Direction of items in a stack layout. Requires `layout: "stack"`. Supported by FrameNode. */
695
932
  stackDirection: StackDirection | null;
933
+ /** How items are distributed in a stack layout. Requires `layout: "stack"`. Supported by FrameNode. */
696
934
  stackDistribution: StackDistribution | null;
935
+ /** How items are aligned perpendicular to the stack direction. Requires `layout: "stack"`. Supported by FrameNode. */
697
936
  stackAlignment: StackAlignment | null;
937
+ /** Whether items should wrap to the next line. Requires `layout: "stack"`. Supported by FrameNode. */
698
938
  stackWrapEnabled: boolean | null;
699
939
  }
700
940
  type GridContentAlignment = "start" | "center" | "end";
701
941
  interface GridLayout {
942
+ /** Number of columns in the grid. Requires `layout: "grid"`. Supported by FrameNode. */
702
943
  gridColumnCount: number | "auto-fill" | null;
944
+ /** Number of rows in the grid. Requires `layout: "grid"`. Supported by FrameNode. */
703
945
  gridRowCount: number | null;
946
+ /** How items are aligned within the grid. Requires `layout: "grid"`. Supported by FrameNode. */
704
947
  gridAlignment: GridContentAlignment | null;
948
+ /** Type of column width sizing: `"fixed"` or `"minmax"`. Requires `layout: "grid"`. Supported by FrameNode. */
705
949
  gridColumnWidthType: "fixed" | "minmax" | null;
950
+ /** Width of grid columns in pixels. Requires `layout: "grid"`. Supported by FrameNode. */
706
951
  gridColumnWidth: number | null;
952
+ /** Minimum width of grid columns in pixels. Requires `layout: "grid"`. Supported by FrameNode. */
707
953
  gridColumnMinWidth: number | null;
954
+ /** Type of row height sizing: `"fixed"`, `"auto"`, or `"fit"`. Requires `layout: "grid"`. Supported by FrameNode. */
708
955
  gridRowHeightType: "fixed" | "auto" | "fit" | null;
956
+ /** Height of grid rows in pixels. Requires `layout: "grid"`. Supported by FrameNode. */
709
957
  gridRowHeight: number | null;
710
958
  }
711
959
  interface WithLayoutTrait extends StackLayout, GridLayout {
960
+ /**
961
+ * Enables stack or grid layout. Setting to `null` disables any applied layout.
962
+ * Operation is deferred and applied after the current update cycle. Supported by FrameNode.
963
+ */
712
964
  layout: LayoutType | null;
965
+ /**
966
+ * Spacing between items in a layout. Single value (e.g. `"10px"`) applies to both axes;
967
+ * two values (e.g. `"10px 20px"`) set horizontal and vertical separately.
968
+ * Only works with layout enabled. Supported by FrameNode.
969
+ */
713
970
  gap: CSSDimension<CSSUnit.Pixel> | `${CSSDimension<CSSUnit.Pixel>} ${CSSDimension<CSSUnit.Pixel>}` | null;
971
+ /**
972
+ * Inner spacing of a container with layout. Single value (e.g. `"10px"`) applies to all sides;
973
+ * four values (e.g. `"10px 20px 30px 40px"`) set top, right, bottom, left.
974
+ * Only works with layout enabled. Supported by FrameNode.
975
+ */
714
976
  padding: CSSDimension<CSSUnit.Pixel> | `${CSSDimension<CSSUnit.Pixel>} ${CSSDimension<CSSUnit.Pixel>} ${CSSDimension<CSSUnit.Pixel>} ${CSSDimension<CSSUnit.Pixel>}` | null;
715
977
  }
716
978
  type GridItemAlignment = "start" | "center" | "end";
717
979
  type GridItemColumnSpan = number | "all";
718
980
  interface WithGridItemTrait {
981
+ /** Whether to fill the grid cell width. For nodes inside a grid container. Defaults to `true`. Supported by FrameNode, TextNode. */
719
982
  gridItemFillCellWidth: boolean | null;
983
+ /** Whether to fill the grid cell height. For nodes inside a grid container. Defaults to `true`. Supported by FrameNode, TextNode. */
720
984
  gridItemFillCellHeight: boolean | null;
985
+ /** Horizontal alignment within grid cell. For nodes inside a grid container. Defaults to `"center"`. Supported by FrameNode, TextNode. */
721
986
  gridItemHorizontalAlignment: GridItemAlignment | null;
987
+ /** Vertical alignment within grid cell. For nodes inside a grid container. Defaults to `"center"`. Supported by FrameNode, TextNode. */
722
988
  gridItemVerticalAlignment: GridItemAlignment | null;
989
+ /** Number of columns to span, or `"all"` for all columns. For nodes inside a grid container. Defaults to `1`. Supported by FrameNode, TextNode. */
723
990
  gridItemColumnSpan: GridItemColumnSpan | null;
991
+ /** Number of rows to span. For nodes inside a grid container. Defaults to `1`. Supported by FrameNode, TextNode. */
724
992
  gridItemRowSpan: number | null;
725
993
  }
726
994
  type TraitVariant = TraitVariantData | TraitVariantNode;
@@ -789,8 +1057,42 @@ interface ColorStyleData extends RequiredColorStyleAttributes, OptionalColorStyl
789
1057
  path: string;
790
1058
  }
791
1059
  type ColorStyleAttributes = Prettify<RequiredColorStyleAttributes & Partial<OptionalColorStyleAttributes> & AssetPath>;
1060
+ /**
1061
+ * A reusable color style defined in the project. Supports light and dark
1062
+ * theme variants. Color styles let you manage color appearances from one
1063
+ * place in a project. In the UI, you can find them in the Assets panel.
1064
+ * Plugins can use these styles to do things like sync design systems or
1065
+ * check accessibility.
1066
+ *
1067
+ * Colors are stored in RGBA format, e.g. `rgba(242, 59, 57, 1)`. The
1068
+ * `light` attribute is the default color used in light theme. The `dark`
1069
+ * attribute is an optional color used in the dark theme.
1070
+ *
1071
+ * To organize color styles into folders, use `/` as a separator in the
1072
+ * name, e.g. `"My Plugin/My Cool Color"`.
1073
+ *
1074
+ * @example
1075
+ * ```ts
1076
+ * // Create a new color style with light and dark variants.
1077
+ * const colorStyle = await framer.createColorStyle({
1078
+ * name: "My Cool Color",
1079
+ * light: "rgba(242, 59, 57, 1)",
1080
+ * dark: "rgba(120, 22, 11, 1)"
1081
+ * })
1082
+ *
1083
+ * // Update an existing color style.
1084
+ * await colorStyle.setAttributes({ dark: "rgba(10, 10, 10, 0.2)" })
1085
+ *
1086
+ * // Remove a color style from the project.
1087
+ * await colorStyle.remove()
1088
+ *
1089
+ * // Store plugin data on a color style.
1090
+ * await colorStyle.setPluginData("key", "value")
1091
+ * ```
1092
+ */
792
1093
  declare class ColorStyle {
793
1094
  #private;
1095
+ /** A unique identifier for the color style. */
794
1096
  readonly id: NodeId;
795
1097
  readonly name: string;
796
1098
  /**
@@ -807,29 +1109,57 @@ declare class ColorStyle {
807
1109
  static [$framerInternal.unmarshal](engine: PluginEngine, data: ColorStyleData): ColorStyle;
808
1110
  [$framerInternal.marshal](): ColorStyleData;
809
1111
  /**
810
- * Set the attributes of a color style.
1112
+ * Set the attributes of a color style. Attributes are merged with existing
1113
+ * values, so only the provided attributes are updated.
1114
+ *
1115
+ * @param update - The attributes to update.
1116
+ * @returns The updated color style, or `null` if the style was not found.
811
1117
  *
812
1118
  * Use `"ColorStyle.setAttributes"` to check if this method is allowed.
1119
+ *
1120
+ * @example
1121
+ * ```ts
1122
+ * await colorStyle.setAttributes({ dark: "rgba(10, 10, 10, 0.2)" })
1123
+ * ```
813
1124
  */
814
1125
  setAttributes(update: Partial<ColorStyleAttributes>): Promise<ColorStyle | null>;
815
1126
  /**
816
1127
  * Get plugin data for this color style by key.
1128
+ *
1129
+ * @param key - The plugin data key.
1130
+ * @returns The stored value, or `null` if no data exists for the key.
817
1131
  */
818
1132
  getPluginData(key: string): Promise<string | null>;
819
1133
  /**
820
1134
  * Set plugin data on this color style by key.
821
1135
  *
1136
+ * @param key - The plugin data key.
1137
+ * @param value - The value to set, or `null` to remove.
1138
+ *
822
1139
  * Use `"ColorStyle.setPluginData"` to check if this method is allowed.
1140
+ *
1141
+ * @example
1142
+ * ```ts
1143
+ * await colorStyle.setPluginData("key", "value")
1144
+ * ```
823
1145
  */
824
1146
  setPluginData(key: string, value: string | null): Promise<void>;
825
1147
  /**
826
1148
  * Get all plugin data keys for this color style.
1149
+ *
1150
+ * @returns An array of all plugin data keys set on this color style.
827
1151
  */
828
1152
  getPluginDataKeys(): Promise<string[]>;
829
1153
  /**
830
- * Deletes the color style from the project.
1154
+ * Deletes the color style from the project. You need a reference to the
1155
+ * style to call this method.
831
1156
  *
832
1157
  * Use `"ColorStyle.remove"` to check if this method is allowed.
1158
+ *
1159
+ * @example
1160
+ * ```ts
1161
+ * await colorStyle.remove()
1162
+ * ```
833
1163
  */
834
1164
  remove(): Promise<void>;
835
1165
  }
@@ -885,6 +1215,60 @@ type TextStyleAttributes = Prettify<Partial<Omit<TextStyleData, "id" | "color" |
885
1215
  boldItalicFont: Font | null;
886
1216
  breakpoints: TextStyleBreakpointAttributes[];
887
1217
  }> & AssetPath>;
1218
+ /**
1219
+ * A reusable text style defined in the project, including font, size,
1220
+ * color, and responsive breakpoints. Text styles let you manage text
1221
+ * appearances from one place in a project. In the UI, you can find them
1222
+ * in the Assets panel.
1223
+ *
1224
+ * Text styles support responsive breakpoints that apply different values
1225
+ * at different window widths. A maximum of four breakpoints can be added.
1226
+ * Breakpoints are automatically ordered from largest to smallest `minWidth`.
1227
+ * Each breakpoint must have a unique `minWidth` value.
1228
+ *
1229
+ * By default, text styles use a built-in font. Use
1230
+ * {@link Font} to customize a text style's typeface. All font variants
1231
+ * (bold, italic, boldItalic) must share the same font family as the base
1232
+ * font.
1233
+ *
1234
+ * To organize text styles into folders, use `/` as a separator in the
1235
+ * name, e.g. `"My Plugin/Heading"`.
1236
+ *
1237
+ * @example
1238
+ * ```ts
1239
+ * // Create a new text style.
1240
+ * const textStyle = await framer.createTextStyle({
1241
+ * name: "Heading",
1242
+ * tag: "h1",
1243
+ * fontSize: "30px",
1244
+ * lineHeight: "1.6em",
1245
+ * })
1246
+ *
1247
+ * // Create a text style with responsive breakpoints.
1248
+ * const textStyle = await framer.createTextStyle({
1249
+ * fontSize: "24px",
1250
+ * minWidth: 1280,
1251
+ * breakpoints: [
1252
+ * { minWidth: 1024, fontSize: "18px" },
1253
+ * { minWidth: 320, fontSize: "16px" }
1254
+ * ]
1255
+ * })
1256
+ *
1257
+ * // Update an existing text style.
1258
+ * await textStyle.setAttributes({
1259
+ * color: "rgba(242, 59, 57, 1)"
1260
+ * })
1261
+ *
1262
+ * // Create a text style with a custom font.
1263
+ * const font = await framer.getFont("Open Sans")
1264
+ * if (font) {
1265
+ * const textStyle = await framer.createTextStyle({ font })
1266
+ * }
1267
+ *
1268
+ * // Remove a text style from the project.
1269
+ * await textStyle.remove()
1270
+ * ```
1271
+ */
888
1272
  declare class TextStyle {
889
1273
  #private;
890
1274
  readonly id: NodeId;
@@ -980,33 +1364,85 @@ declare class TextStyle {
980
1364
  static [$framerInternal.unmarshal](engine: PluginEngine, data: TextStyleData): TextStyle;
981
1365
  [$framerInternal.marshal](): TextStyleData;
982
1366
  /**
983
- * Set the attributes of the text style.
1367
+ * Set the attributes of the text style. All attributes except
1368
+ * `breakpoints` are merged with existing values. When setting
1369
+ * `breakpoints`, the provided array replaces any existing breakpoints
1370
+ * entirely. To update breakpoints without overriding them all, iterate
1371
+ * over the existing breakpoints and merge them.
984
1372
  *
1373
+ * @param attributes - The attributes to update.
1374
+ * @returns The updated text style, or `null` if the style was not found.
985
1375
  * @throws If the number of breakpoints is bigger than the limit of 4.
986
1376
  * @throws If any of the font families used for `boldFont`, `italicFont` and
987
1377
  * `boldItalicFont` do not match the family of `font`.
988
1378
  *
989
1379
  * Use `"TextStyle.setAttributes"` to check if this method is allowed.
1380
+ *
1381
+ * @example
1382
+ * ```ts
1383
+ * // Update the color of a text style.
1384
+ * const textStyle = await framer.getTextStyle("text-style-id")
1385
+ * if (textStyle) {
1386
+ * await textStyle.setAttributes({
1387
+ * color: "rgba(242, 59, 57, 1)"
1388
+ * })
1389
+ * }
1390
+ *
1391
+ * // Replace breakpoints on a text style.
1392
+ * await textStyle.setAttributes({
1393
+ * breakpoints: [
1394
+ * { minWidth: 320, fontSize: "24px" }
1395
+ * ]
1396
+ * })
1397
+ *
1398
+ * // Scale font sizes across all breakpoints without losing them.
1399
+ * await textStyle.setAttributes({
1400
+ * fontSize: parseInt(textStyle.fontSize) * 0.8 + "px",
1401
+ * breakpoints: textStyle.breakpoints.map((bp) => ({
1402
+ * ...bp,
1403
+ * fontSize: parseInt(bp.fontSize) * 0.8 + "px"
1404
+ * }))
1405
+ * })
1406
+ * ```
990
1407
  */
991
1408
  setAttributes(attributes: TextStyleAttributes): Promise<TextStyle | null>;
992
1409
  /**
993
1410
  * Get plugin data for this text style by key.
1411
+ *
1412
+ * @param key - The plugin data key.
1413
+ * @returns The stored value, or `null` if no data exists for the key.
994
1414
  */
995
1415
  getPluginData(key: string): Promise<string | null>;
996
1416
  /**
997
1417
  * Set plugin data on this text style by key.
998
1418
  *
1419
+ * @param key - The plugin data key.
1420
+ * @param value - The value to set, or `null` to remove.
1421
+ *
999
1422
  * Use `"TextStyle.setPluginData"` to check if this method is allowed.
1423
+ *
1424
+ * @example
1425
+ * ```ts
1426
+ * await textStyle.setPluginData("key", "value")
1427
+ * ```
1000
1428
  */
1001
1429
  setPluginData(key: string, value: string | null): Promise<void>;
1002
1430
  /**
1003
1431
  * Get all plugin data keys for this text style.
1432
+ *
1433
+ * @returns An array of all plugin data keys set on this text style.
1004
1434
  */
1005
1435
  getPluginDataKeys(): Promise<string[]>;
1006
1436
  /**
1007
- * Deletes the text style from the project.
1437
+ * Deletes the text style from the project. You need a reference to
1438
+ * the style to call this method.
1008
1439
  *
1009
1440
  * Use `"TextStyle.remove"` to check if this method is allowed.
1441
+ *
1442
+ * @example
1443
+ * ```ts
1444
+ * await textStyle.remove()
1445
+ * ```
1010
1446
  */
1011
1447
  remove(): Promise<void>;
1012
1448
  }
@@ -1303,20 +1739,49 @@ interface EnumCaseData extends WithId, WithName, WithNameByLocale {
1303
1739
  }
1304
1740
  interface UpdateEnumCase extends Partial<WithName>, Partial<WithNameByLocaleUpdate> {
1305
1741
  }
1742
+ /** An individual case (option) within an Enum Field or Enum Variable. */
1306
1743
  declare class EnumCase {
1307
1744
  #private;
1745
+ /** A unique identifier for the enum case. */
1308
1746
  get id(): string;
1747
+ /** The display name of the enum case. */
1309
1748
  get name(): string;
1749
+ /**
1750
+ * Localized values for the name of this enum case.
1751
+ *
1752
+ * @example
1753
+ * ```ts
1754
+ * const dutchName = enumCase.nameByLocale[dutchLocale.id] // "Naam"
1755
+ * ```
1756
+ */
1310
1757
  get nameByLocale(): InlineLocalizationValueByLocale;
1311
1758
  constructor(engine: PluginEngine, nodeId: string, variableId: string, enumCaseData: EnumCaseData);
1312
1759
  /**
1313
- * Update a mutable enum case property, for example the name.
1760
+ * Update the attributes of this enum case.
1761
+ *
1762
+ * @example
1763
+ * ```ts
1764
+ * enumCase.setAttributes({
1765
+ * name: "New Name",
1766
+ * nameByLocale: {
1767
+ * nl: { action: "set", value: "Nieuwe naam" }
1768
+ * }
1769
+ * })
1770
+ * ```
1771
+ *
1772
+ * @param attributes - The attributes to update: `name` and/or `nameByLocale`.
1773
+ * @returns The updated `EnumCase`, or `null` if the case was removed before the update.
1314
1774
  *
1315
1775
  * Use `"EnumCase.setAttributes"` to check if this method is allowed.
1316
1776
  */
1317
1777
  setAttributes(attributes: UpdateEnumCase): Promise<EnumCase | null>;
1318
1778
  /**
1319
- * Remove the enum case.
1779
+ * Remove this enum case from its parent enum field.
1780
+ *
1781
+ * @example
1782
+ * ```ts
1783
+ * enumCase.remove()
1784
+ * ```
1320
1785
  *
1321
1786
  * Use `"EnumCase.remove"` to check if this method is allowed.
1322
1787
  */
@@ -1574,10 +2039,16 @@ type UpdateFieldAttributes<T extends {
1574
2039
  }>, // This is NOT the same as Extract<UpdateField, T>
1575
2040
  // This is NOT the same as Extract<UpdateField, T>
1576
2041
  "id" | "type">;
2042
+ /**
2043
+ * Base class for all CMS Collection field types. Use the `type` property
2044
+ * to narrow to a specific field class.
2045
+ */
1577
2046
  declare abstract class FieldBase {
1578
2047
  #private;
1579
2048
  abstract readonly type: FieldDefinitionData["type"];
2049
+ /** The unique identifier of the field. */
1580
2050
  get id(): string;
2051
+ /** The display name of the field as shown in the UI. */
1581
2052
  get name(): string;
1582
2053
  constructor(engine: PluginEngine, collectionId: string, data: FieldDefinitionBase);
1583
2054
  /**
@@ -1597,6 +2068,8 @@ declare abstract class FieldBase {
1597
2068
  * Returns the updated field on success, and `null` in the unlikely event of it being removed
1598
2069
  * between getting it and calling this method.
1599
2070
  *
2071
+ * @param attributes - The attributes to update.
2072
+ *
1600
2073
  * Use `"Field.setAttributes"` to check if this method is allowed.
1601
2074
  */
1602
2075
  setAttributes(attributes: UpdateFieldAttributes<typeof this>): Promise<typeof this | null>;
@@ -1609,88 +2082,143 @@ declare abstract class FieldBase {
1609
2082
  }
1610
2083
  declare abstract class FieldBaseWithRequired extends FieldBase implements WithFieldRequired {
1611
2084
  #private;
2085
+ /** Whether this field is required. Required fields must have a value set on every CMS item. */
1612
2086
  get required(): boolean;
1613
2087
  constructor(engine: PluginEngine, collectionId: string, data: FieldDefinitionBase & WithFieldRequired);
1614
2088
  }
2089
+ /** A CMS Collection field that stores a boolean (true or false) value. */
1615
2090
  declare class BooleanField extends FieldBase {
1616
2091
  readonly type = "boolean";
1617
2092
  }
2093
+ /** A CMS Collection field that stores a color value (RGBA/HSL/HEX format). */
1618
2094
  declare class ColorField extends FieldBase {
1619
2095
  readonly type = "color";
1620
2096
  }
2097
+ /** A CMS Collection field that stores a numeric value. */
1621
2098
  declare class NumberField extends FieldBase {
1622
2099
  readonly type = "number";
1623
2100
  }
2101
+ /** A CMS Collection field that stores a text string value. */
1624
2102
  declare class StringField extends FieldBaseWithRequired implements WithFieldBasedOn {
1625
2103
  #private;
1626
2104
  readonly type = "string";
1627
2105
  constructor(engine: PluginEngine, collectionId: string, data: StringFieldDefinitionData);
1628
2106
  get basedOn(): string | null;
1629
2107
  }
2108
+ /** A CMS Collection field that stores HTML-formatted text content (H1-H6, P, and other standard content elements). */
1630
2109
  declare class FormattedTextField extends FieldBaseWithRequired {
1631
2110
  readonly type = "formattedText";
1632
2111
  }
2112
+ /** A CMS Collection field that stores an image asset (`ImageAsset`). */
1633
2113
  declare class ImageField extends FieldBaseWithRequired {
1634
2114
  readonly type = "image";
1635
2115
  }
2116
+ /** A CMS Collection field that stores a URL in string format. */
1636
2117
  declare class LinkField extends FieldBaseWithRequired {
1637
2118
  readonly type = "link";
1638
2119
  }
2120
+ /** A CMS Collection field that stores a date in UTC format. Optionally displays time. */
1639
2121
  declare class DateField extends FieldBaseWithRequired {
1640
2122
  #private;
1641
2123
  readonly type = "date";
2124
+ /** Controls whether time is enabled on this date field. */
1642
2125
  get displayTime(): boolean | undefined;
1643
2126
  constructor(engine: PluginEngine, collectionId: string, data: DateFieldDefinitionData);
1644
2127
  }
2128
+ /** A visual divider between fields in the CMS UI. Not a data field. */
1645
2129
  declare class FieldDivider extends FieldBase {
1646
2130
  readonly type = "divider";
1647
2131
  }
2132
+ /**
2133
+ * A field type that is not yet supported by the plugin API.
2134
+ * Returned when Framer uses a field type that the plugin API does not recognize.
2135
+ */
1648
2136
  declare class UnsupportedField extends FieldBase {
1649
2137
  readonly type = "unsupported";
1650
2138
  }
2139
+ /** A CMS Collection field that stores a file asset (`FileAsset`). */
1651
2140
  declare class FileField extends FieldBaseWithRequired implements WithAllowedFileTypes {
1652
2141
  #private;
1653
2142
  readonly type = "file";
1654
- /** @inheritdoc */
2143
+ /** The file extensions that are allowed for uploads to this field, e.g. `["pdf", "txt"]`. */
1655
2144
  get allowedFileTypes(): string[];
1656
2145
  constructor(engine: PluginEngine, collectionId: string, data: FileFieldDefinitionData);
1657
2146
  }
2147
+ /**
2148
+ * A CMS Collection field with a fixed set of enum cases (options) that the user
2149
+ * can choose from. Enum cases must be defined as options before they can be
2150
+ * assigned to CMS items.
2151
+ */
1658
2152
  declare class EnumField extends FieldBase {
1659
2153
  #private;
1660
2154
  readonly type = "enum";
2155
+ /** The available enum cases for this field. */
1661
2156
  get cases(): readonly EnumCase[];
1662
2157
  constructor(engine: PluginEngine, collectionId: string, data: EnumFieldDefinitionData);
1663
2158
  /**
1664
- * Add a new enum case.
2159
+ * Add a new enum case to this field.
2160
+ *
2161
+ * @example
2162
+ * ```ts
2163
+ * await enumField.addCase({
2164
+ * name: "Name",
2165
+ * nameByLocale: {
2166
+ * nl: { action: "set", value: "Naam" }
2167
+ * }
2168
+ * })
2169
+ * ```
2170
+ *
2171
+ * @param attributes - An object with the enum case name and optional localized names.
2172
+ * @returns The newly created `EnumCase`, or `null` if the case could not be added.
1665
2173
  *
1666
2174
  * Use `"EnumField.addCase"` to check if this method is allowed.
1667
2175
  */
1668
2176
  addCase(attributes: CreateEnumCase): Promise<EnumCase | null>;
1669
2177
  /**
1670
- * Arrange enum cases in a specific order.
2178
+ * Set the order of the enum field's cases.
2179
+ *
2180
+ * @example
2181
+ * ```ts
2182
+ * const alphabeticalCaseOrder = enumField.cases
2183
+ * .toSorted((a, b) => a.name.localeCompare(b.name))
2184
+ * .map(({ id }) => id)
2185
+ * await enumField.setCaseOrder(alphabeticalCaseOrder)
2186
+ * ```
2187
+ *
2188
+ * @param caseIds - An array of the IDs of all enum cases, in the desired new order.
1671
2189
  *
1672
2190
  * Use `"EnumField.setCaseOrder"` to check if this method is allowed.
1673
2191
  */
1674
2192
  setCaseOrder(caseIds: string[]): Promise<void>;
1675
2193
  }
2194
+ /** A field that references an item in another collection. */
1676
2195
  declare class CollectionReferenceField extends FieldBaseWithRequired implements WithFieldCollectionId {
1677
2196
  #private;
1678
2197
  readonly type = "collectionReference";
2198
+ /** The ID of the referenced collection. */
1679
2199
  get collectionId(): string;
1680
2200
  constructor(engine: PluginEngine, collectionId: string, data: CollectionReferenceFieldDefinitionData);
1681
2201
  }
2202
+ /** A field that references multiple items in another collection. */
1682
2203
  declare class MultiCollectionReferenceField extends FieldBaseWithRequired implements WithFieldCollectionId {
1683
2204
  #private;
1684
2205
  readonly type = "multiCollectionReference";
2206
+ /** The ID of the referenced collection. */
1685
2207
  get collectionId(): string;
1686
2208
  constructor(engine: PluginEngine, collectionId: string, data: MultiCollectionReferenceFieldDefinitionData);
1687
2209
  }
1688
2210
  type ArrayItemField = ImageField;
2211
+ /**
2212
+ * A CMS Collection field that stores an array of nested fields. Currently only
2213
+ * supports a single image field, which creates a Gallery in the CMS.
2214
+ */
1689
2215
  declare class ArrayField extends FieldBaseWithRequired {
1690
2216
  readonly type = "array";
2217
+ /** The nested fields within this array field. Currently limited to a single image field. */
1691
2218
  readonly fields: readonly [ArrayItemField];
1692
2219
  constructor(engine: PluginEngine, collectionId: string, data: ArrayFieldDefinitionData);
1693
2220
  }
2221
+ /** Union of all CMS Collection field types. */
1694
2222
  type Field = BooleanField | ColorField | NumberField | StringField | FormattedTextField | ImageField | LinkField | DateField | FieldDivider | UnsupportedField | FileField | EnumField | CollectionReferenceField | MultiCollectionReferenceField | ArrayField;
1695
2223
  declare function isField(value: unknown): value is FieldBase;
1696
2224
 
@@ -2253,6 +2781,18 @@ interface WithUserEditable {
2253
2781
  type ManagedCollectionField = SupportedFieldDefinitionData & WithUserEditable;
2254
2782
  /** @deprecated Use `ManagedCollectionFieldInput` instead. */
2255
2783
  type EditableManagedCollectionField = ManagedCollectionFieldInputData;
2784
+ /**
2785
+ * A CMS Collection that is fully controlled by a plugin. Managed Collections
2786
+ * allow plugins to define fields and sync items programmatically. Fields and
2787
+ * items can only be added, edited, and deleted by the owning plugin, not by
2788
+ * the user (unless a field is marked `userEditable`).
2789
+ *
2790
+ * A Managed Collection plugin becomes available within the CMS when it supports
2791
+ * both `configureManagedCollection` and `syncManagedCollection` modes.
2792
+ *
2793
+ * Use `framer.getManagedCollection()` to obtain an instance when the plugin is
2794
+ * launched in either of those modes.
2795
+ */
2256
2796
  declare class ManagedCollection implements Navigable {
2257
2797
  #private;
2258
2798
  readonly id: NodeId;
@@ -2264,54 +2804,161 @@ declare class ManagedCollection implements Navigable {
2264
2804
  */
2265
2805
  readonly readonly: boolean;
2266
2806
  /**
2267
- * Collections managed by other plugins should are read-only.
2807
+ * Returns who manages this Collection.
2808
+ *
2809
+ * - `"thisPlugin"` if the Collection is managed by the current plugin.
2810
+ * - `"anotherPlugin"` if the Collection is managed by a different plugin.
2811
+ *
2812
+ * Collections managed by other plugins are read-only.
2268
2813
  */
2269
2814
  readonly managedBy: ManagedCollectionManagedBy;
2270
2815
  constructor(data: CollectionData, engine: PluginEngine);
2271
2816
  /**
2272
- * Get item keys in their set order.
2817
+ * Retrieve all item IDs in this Managed Collection, in their current order.
2818
+ *
2819
+ * @returns An array of item IDs.
2820
+ *
2821
+ * @example
2822
+ * ```ts
2823
+ * const itemIds = await collection.getItemIds()
2824
+ * ```
2273
2825
  */
2274
2826
  getItemIds(): Promise<string[]>;
2275
2827
  /**
2276
- * Arrange items in a specific order.
2828
+ * Arrange CMS items in a specific order.
2277
2829
  *
2278
2830
  * Use `"ManagedCollection.setItemOrder"` to check if this method is allowed.
2831
+ *
2832
+ * @param ids - An array of item IDs in the desired order. Unknown IDs are ignored.
2833
+ *
2834
+ * @example
2835
+ * ```ts
2836
+ * await collection.setItemOrder([item3.id, item1.id, item2.id])
2837
+ * ```
2279
2838
  */
2280
2839
  setItemOrder(ids: string[]): Promise<void>;
2281
2840
  /**
2282
- * Get all fields.
2841
+ * Get all fields defined on this Managed Collection.
2842
+ *
2843
+ * @returns An array of managed collection field definitions.
2844
+ *
2845
+ * @example
2846
+ * ```ts
2847
+ * const fields = await collection.getFields()
2848
+ * ```
2283
2849
  */
2284
2850
  getFields(): Promise<ManagedCollectionField[]>;
2285
2851
  /**
2286
- * Create, update or remove all fields in one go.
2852
+ * Add, update, or remove Collection fields. Fields not included in the
2853
+ * array will be removed. You can configure up to 30 custom fields.
2854
+ *
2855
+ * Each field requires an `id`, `name`, and `type`. For the `id`, use a
2856
+ * unique identifier that stays the same across future synchronizations.
2857
+ * Any change in `id` can break data assignments on the canvas. The maximum
2858
+ * length for an `id` is 64 characters.
2859
+ *
2860
+ * By default, managed collection fields set by a plugin are not editable by
2861
+ * users. Set `userEditable: true` on a field to allow user editing. Note
2862
+ * that fields marked as `userEditable` can no longer have their values set
2863
+ * by the plugin when using `addItems`.
2287
2864
  *
2288
2865
  * Use `"ManagedCollection.setFields"` to check if this method is allowed.
2866
+ *
2867
+ * @param fields - The array of fields that should be used for the collection.
2868
+ *
2869
+ * @example
2870
+ * ```ts
2871
+ * await collection.setFields([
2872
+ * { id: "1", type: "string", name: "Name" },
2873
+ * { id: "2", type: "number", name: "Age" },
2874
+ * { id: "3", type: "string", name: "Description", userEditable: true },
2875
+ * ])
2876
+ * ```
2289
2877
  */
2290
2878
  setFields(fields: ManagedCollectionFieldInput[]): Promise<void>;
2291
2879
  /**
2292
- * Add new items or update existing ones if their IDs match.
2880
+ * Add new items or update existing ones if their IDs match. This method
2881
+ * performs an upsert: items with matching IDs are updated, new IDs are
2882
+ * inserted.
2883
+ *
2884
+ * Each item requires an `id` and `slug`. Custom field data is provided via
2885
+ * the `fieldData` object, using field IDs as keys.
2886
+ *
2887
+ * Currently, calling `addItems` with existing item IDs merges the provided
2888
+ * field data with the existing items' current field data, meaning any
2889
+ * omitted fields remain unchanged. In version 4.0.0, this behavior will
2890
+ * change to fully replace items, removing any fields not explicitly
2891
+ * included. Always include all fields when updating existing items to avoid
2892
+ * unexpected behavior.
2293
2893
  *
2294
2894
  * Use `"ManagedCollection.addItems"` to check if this method is allowed.
2895
+ *
2896
+ * @param items - An array of items to add or update.
2897
+ *
2898
+ * @example
2899
+ * ```ts
2900
+ * await collection.addItems([
2901
+ * {
2902
+ * id: "1",
2903
+ * slug: "item-1",
2904
+ * fieldData: {
2905
+ * [nameField.id]: { type: "string", value: "Eric" },
2906
+ * [ageField.id]: { type: "number", value: 47 },
2907
+ * },
2908
+ * },
2909
+ * ])
2910
+ * ```
2295
2911
  */
2296
2912
  addItems(items: ManagedCollectionItemInput[]): Promise<void>;
2297
2913
  /**
2298
- * Remove items by their ID.
2914
+ * Remove CMS items by their ID.
2299
2915
  *
2300
2916
  * Use `"ManagedCollection.removeItems"` to check if this method is allowed.
2917
+ *
2918
+ * @param itemIds - The IDs of the items to remove.
2919
+ *
2920
+ * @example
2921
+ * ```ts
2922
+ * await collection.removeItems([item1.id, item5.id])
2923
+ * ```
2301
2924
  */
2302
2925
  removeItems(itemIds: string[]): Promise<void>;
2303
2926
  /**
2304
- * Make this the active collection.
2927
+ * Open this Collection in the Editor, making it the active selection in
2928
+ * the Framer UI.
2929
+ *
2930
+ * @example
2931
+ * ```ts
2932
+ * await collection.setAsActive()
2933
+ * ```
2305
2934
  */
2306
2935
  setAsActive(): Promise<void>;
2307
2936
  /**
2308
- * Set plugin data by key.
2937
+ * Set plugin data by key. Similar to local storage, you can store custom
2938
+ * data on the Managed Collection (e.g., the last synchronization date or a
2939
+ * connected database ID).
2309
2940
  *
2310
2941
  * Use `"ManagedCollection.setPluginData"` to check if this method is allowed.
2942
+ *
2943
+ * @param key - The plugin data key.
2944
+ * @param value - The value to set, or `null` to remove.
2945
+ *
2946
+ * @example
2947
+ * ```ts
2948
+ * const currentDate = new Date().toISOString()
2949
+ * await collection.setPluginData("lastSynchronizedAt", currentDate)
2950
+ * ```
2311
2951
  */
2312
2952
  setPluginData(key: string, value: string | null): Promise<void>;
2313
2953
  /**
2314
2954
  * Get plugin data by key.
2955
+ *
2956
+ * @param key - The plugin data key.
2957
+ *
2958
+ * @example
2959
+ * ```ts
2960
+ * const lastSynchronized = await collection.getPluginData("lastSynchronizedAt")
2961
+ * ```
2315
2962
  */
2316
2963
  getPluginData(key: string): Promise<string | null>;
2317
2964
  /**
@@ -2323,93 +2970,222 @@ declare class ManagedCollection implements Navigable {
2323
2970
  */
2324
2971
  navigateTo(opts?: NavigableOptions): Promise<void>;
2325
2972
  }
2973
+ /**
2974
+ * A CMS Collection in the project. Collections can be created by users or
2975
+ * managed by plugins. Use `managedBy` to check the owner.
2976
+ *
2977
+ * Any kind of Collection can be read from. Unmanaged Collections are those
2978
+ * created and updated by people. Use the `collection` mode to access CMS
2979
+ * data from your plugin.
2980
+ */
2326
2981
  declare class Collection implements Navigable {
2327
2982
  #private;
2328
2983
  readonly id: NodeId;
2329
2984
  readonly name: string;
2985
+ /**
2986
+ * The name of the field used as the slug.
2987
+ *
2988
+ * - Only Collections that are not managed by a Plugin will have this value set.
2989
+ */
2330
2990
  readonly slugFieldName: string | null;
2991
+ /**
2992
+ * The ID of the field the slug is based on.
2993
+ *
2994
+ * - Only Collections that are not managed by a Plugin will have this value set.
2995
+ */
2331
2996
  readonly slugFieldBasedOn: string | null;
2332
2997
  /**
2998
+ * Whether this Collection is read-only.
2999
+ *
3000
+ * A Collection is considered read-only if:
3001
+ * - The plugin operates in a view-only mode (e.g., user does not have
3002
+ * permission to edit content).
3003
+ * - The Collection is managed by another plugin.
3004
+ *
3005
+ * Read-only Collections cannot be modified via the API.
3006
+ *
2333
3007
  * @deprecated Use `managedBy` instead and the [Permissions
2334
3008
  * API](https://www.framer.com/developers/plugins-permissions) to check if users can edit the
2335
3009
  * collection.
2336
3010
  */
2337
3011
  readonly readonly: boolean;
2338
3012
  /**
2339
- * Collections managed by plugins are read-only. To be able to modify them use
2340
- * `ManagedCollection` (which is only possible in `configureManagedCollection` or
3013
+ * Returns who manages this Collection.
3014
+ *
3015
+ * - `"user"` if the Collection is user-created.
3016
+ * - `"thisPlugin"` if the Collection is managed by the current plugin.
3017
+ * - `"anotherPlugin"` if the Collection is managed by another plugin.
3018
+ *
3019
+ * Collections managed by plugins are read-only. To modify them, use
3020
+ * `ManagedCollection` (only possible in `configureManagedCollection` or
2341
3021
  * `syncManagedCollection` modes).
2342
- */
2343
- readonly managedBy: CollectionManagedBy;
2344
- constructor(data: CollectionData, engine: PluginEngine);
2345
- /**
2346
- * Arrange items in a specific order.
2347
3022
  *
2348
- * Use `"Collection.setItemOrder"` to check if this method is allowed.
3023
+ * Note: the plugin still needs to check if the user has permission to edit
3024
+ * content via `framer.isAllowedTo`.
3025
+ *
3026
+ * @example
3027
+ * ```ts
3028
+ * const collection = await framer.getActiveCollection()
3029
+ *
3030
+ * if (framer.mode === "collection" && collection.managedBy !== "user") {
3031
+ * framer.notify("This Collection cannot be modified.", { variant: "warning" })
3032
+ * }
3033
+ * ```
3034
+ */
3035
+ readonly managedBy: CollectionManagedBy;
3036
+ constructor(data: CollectionData, engine: PluginEngine);
3037
+ /**
3038
+ * Reorder the items in this Collection based on an array of item IDs.
3039
+ * Unknown item IDs are ignored.
3040
+ *
3041
+ * Use `"Collection.setItemOrder"` to check if this method is allowed.
3042
+ *
3043
+ * @param ids - An array of item IDs representing the desired order.
3044
+ *
3045
+ * @example
3046
+ * ```ts
3047
+ * await collection.setItemOrder([item3.id, item1.id, item2.id])
3048
+ * ```
2349
3049
  */
2350
3050
  setItemOrder(ids: NodeId[]): Promise<void>;
2351
3051
  /**
2352
- * Get all fields.
3052
+ * Fetch all fields defined on this Collection, including dividers.
3053
+ *
3054
+ * Some fields might not be fully supported by the API; unsupported fields
3055
+ * will be returned with an `unsupported` field type.
3056
+ *
3057
+ * @returns An array of Field instances.
3058
+ *
3059
+ * @example
3060
+ * ```ts
3061
+ * const fields = await collection.getFields()
3062
+ * ```
2353
3063
  */
2354
3064
  getFields(): Promise<Field[]>;
2355
3065
  /**
2356
- * Create new fields. Use `Field.setAttributes` to update.
3066
+ * Create new unmanaged Collection fields. Use `Field.setAttributes` to
3067
+ * update existing fields.
2357
3068
  *
2358
3069
  * Use `"Collection.addFields"` to check if this method is allowed.
3070
+ *
3071
+ * @param fields - The array of fields that should be added to the collection.
3072
+ * @returns The newly created Field instances.
3073
+ *
3074
+ * @example
3075
+ * ```ts
3076
+ * const createdFields = await collection.addFields([
3077
+ * { type: "string", name: "Name" },
3078
+ * { type: "enum", name: "Status", cases: [{ name: "New" }, { name: "Done" }] },
3079
+ * { type: "file", name: "Text", allowedFileTypes: ["md"] },
3080
+ * { type: "collectionReference", name: "Author", collectionId: "ASh5SZOh" },
3081
+ * ])
3082
+ * ```
2359
3083
  */
2360
3084
  addFields(fields: CreateField[]): Promise<Field[]>;
2361
3085
  /**
2362
- * Remove fields by their ID.
3086
+ * Remove fields from this Collection by their IDs.
2363
3087
  *
2364
3088
  * Use `"Collection.removeFields"` to check if this method is allowed.
3089
+ *
3090
+ * @param fieldIds - An array of field IDs to remove.
3091
+ *
3092
+ * @example
3093
+ * ```ts
3094
+ * await collection.removeFields([field3.id, field4.id])
3095
+ * ```
2365
3096
  */
2366
3097
  removeFields(fieldIds: string[]): Promise<void>;
2367
3098
  /**
2368
- * Arrange fields in a specific order.
3099
+ * Reorder the fields in this Collection based on an array of field IDs.
3100
+ * Unknown field IDs are ignored.
2369
3101
  *
2370
3102
  * Use `"Collection.setFieldOrder"` to check if this method is allowed.
3103
+ *
3104
+ * @param fieldIds - An array of field IDs representing the desired order.
3105
+ *
3106
+ * @example
3107
+ * ```ts
3108
+ * await collection.setFieldOrder([nameField.id, ageField.id])
3109
+ * ```
2371
3110
  */
2372
3111
  setFieldOrder(fieldIds: string[]): Promise<void>;
2373
3112
  /**
2374
- * Get all items in their set order.
3113
+ * Retrieve all items within this Collection, in their current order.
3114
+ * Items may include drafts (unpublished items).
3115
+ *
3116
+ * @returns An array of CollectionItem instances.
3117
+ *
3118
+ * @example
3119
+ * ```ts
3120
+ * const items = await collection.getItems()
3121
+ * ```
2375
3122
  */
2376
3123
  getItems(): Promise<CollectionItem[]>;
2377
3124
  /**
2378
- * Add new items or update existing ones if their IDs are provided.
3125
+ * Add new items to this Collection, or update existing ones if their IDs
3126
+ * match.
2379
3127
  *
2380
- * This creates a new item with "foo" as its slug:
3128
+ * - If an `id` is provided and matches an existing item, that item will be
3129
+ * updated.
3130
+ * - Items without an `id` are created as new records.
3131
+ * - `slug` should be unique.
2381
3132
  *
2382
- * ```ts
2383
- * collection.addItems([{ slug: "foo" }])
2384
- * ```
3133
+ * Use `"Collection.addItems"` to check if this method is allowed.
2385
3134
  *
2386
- * This updates an existing item with ID "aBc123" to have "bar" as its slug:
3135
+ * @param items - An array of items to add or update.
2387
3136
  *
3137
+ * @example
2388
3138
  * ```ts
2389
- * collection.addItems([{ id: "aBc123", slug: "bar" }])
2390
- * ```
3139
+ * // Create a new item
3140
+ * await collection.addItems([{
3141
+ * slug: "eric",
3142
+ * fieldData: {
3143
+ * [nameField.id]: { type: "string", value: "Eric" },
3144
+ * [ageField.id]: { type: "number", value: 47 },
3145
+ * },
3146
+ * }])
2391
3147
  *
2392
- * Use `"Collection.addItems"` to check if this method is allowed.
3148
+ * // Update an existing item
3149
+ * await collection.addItems([{ id: "aBc123", slug: "bar" }])
3150
+ * ```
2393
3151
  */
2394
3152
  addItems(items: CollectionItemInput[]): Promise<void>;
2395
3153
  /**
2396
- * Remove items by their ID.
3154
+ * Remove items from this Collection by their IDs.
2397
3155
  *
2398
3156
  * Use `"Collection.removeItems"` to check if this method is allowed.
3157
+ *
3158
+ * @param itemIds - An array of item IDs to remove.
3159
+ *
3160
+ * @example
3161
+ * ```ts
3162
+ * await collection.removeItems([item3.id, item4.id])
3163
+ * ```
2399
3164
  */
2400
3165
  removeItems(itemIds: NodeId[]): Promise<void>;
2401
3166
  /**
2402
- * Make this the active collection.
3167
+ * Set this Collection as active, changing the selected Collection in the
3168
+ * Framer UI.
3169
+ *
3170
+ * @example
3171
+ * ```ts
3172
+ * await collection.setAsActive()
3173
+ * ```
2403
3174
  */
2404
3175
  setAsActive(): Promise<void>;
2405
3176
  /**
2406
3177
  * Set plugin data by key.
2407
3178
  *
2408
3179
  * Use `"Collection.setPluginData"` to check if this method is allowed.
3180
+ *
3181
+ * @param key - The plugin data key.
3182
+ * @param value - The value to set, or `null` to remove.
2409
3183
  */
2410
3184
  setPluginData(key: string, value: string | null): Promise<void>;
2411
3185
  /**
2412
3186
  * Get plugin data by key.
3187
+ *
3188
+ * @param key - The plugin data key.
2413
3189
  */
2414
3190
  getPluginData(key: string): Promise<string | null>;
2415
3191
  /**
@@ -2421,36 +3197,77 @@ declare class Collection implements Navigable {
2421
3197
  */
2422
3198
  navigateTo(opts?: NavigableOptions): Promise<void>;
2423
3199
  }
3200
+ /**
3201
+ * An item (row) in a CMS Collection. Each item contains field data keyed by
3202
+ * field ID, a unique slug, and a draft status.
3203
+ */
2424
3204
  declare class CollectionItem implements Navigable {
2425
3205
  #private;
3206
+ /** A unique identifier for this Collection item. */
2426
3207
  readonly id: NodeId;
2427
3208
  /** External ID for managed collections, unique node ID otherwise. */
2428
3209
  readonly nodeId: NodeId;
3210
+ /** Slug value of the CMS item. Slugs should be unique within a Collection. */
2429
3211
  readonly slug: string;
2430
3212
  readonly slugByLocale: InlineLocalizationValueByLocale;
3213
+ /** Drafts are excluded from publishing. */
2431
3214
  readonly draft: boolean;
3215
+ /**
3216
+ * The fields and corresponding values of this Collection item. Field data
3217
+ * uses the field `id` as keys in an object.
3218
+ *
3219
+ * @example
3220
+ * ```ts
3221
+ * const titleFieldData = collectionItem.fieldData[titleField.id]
3222
+ * console.log(titleFieldData.value) // "Getting Started"
3223
+ * ```
3224
+ */
2432
3225
  readonly fieldData: Readonly<FieldData>;
2433
3226
  constructor(collectionItemData: CollectionItemSerializableData, engine: PluginEngine);
2434
3227
  /**
2435
- * Remove this item.
3228
+ * Remove this item from the Collection.
2436
3229
  *
2437
3230
  * Use `"CollectionItem.remove"` to check if this method is allowed.
3231
+ *
3232
+ * @example
3233
+ * ```ts
3234
+ * await collectionItem.remove()
3235
+ * ```
2438
3236
  */
2439
3237
  remove(): Promise<void>;
2440
3238
  /**
2441
- * Update the item.
3239
+ * Set the values of the fields of this CMS item. May return `null` if the
3240
+ * item was deleted before this method was called.
2442
3241
  *
2443
3242
  * Use `"CollectionItem.setAttributes"` to check if this method is allowed.
3243
+ *
3244
+ * @param update - The updated attributes for the collection item.
3245
+ * @returns The updated CollectionItem, or `null` if the item no longer exists.
3246
+ *
3247
+ * @example
3248
+ * ```ts
3249
+ * const updatedItem = await collectionItem.setAttributes({
3250
+ * slug: "new-slug",
3251
+ * fieldData: {
3252
+ * [ageField.id]: { type: "number", value: 48 },
3253
+ * },
3254
+ * })
3255
+ * ```
2444
3256
  */
2445
3257
  setAttributes(update: EditableCollectionItemAttributes): Promise<CollectionItem | null>;
2446
3258
  /**
2447
3259
  * Set plugin data by key.
2448
3260
  *
2449
3261
  * Use `"CollectionItem.setPluginData"` to check if this method is allowed.
3262
+ *
3263
+ * @param key - The plugin data key.
3264
+ * @param value - The value to set, or `null` to remove.
2450
3265
  */
2451
3266
  setPluginData(key: string, value: string | null): Promise<void>;
2452
3267
  /**
2453
3268
  * Get plugin data by key.
3269
+ *
3270
+ * @param key - The plugin data key.
2454
3271
  */
2455
3272
  getPluginData(key: string): Promise<string | null>;
2456
3273
  /**
@@ -2458,11 +3275,23 @@ declare class CollectionItem implements Navigable {
2458
3275
  */
2459
3276
  getPluginDataKeys(): Promise<string[]>;
2460
3277
  /**
2461
- * Navigate to this collection item. May switch modes to reveal the relevant view.
3278
+ * Navigate the UI to this Collection item. May switch modes to reveal the
3279
+ * relevant view, such as the CMS editor.
3280
+ *
3281
+ * @param opts - Optional navigation options, such as scrolling to a
3282
+ * specific field.
3283
+ *
3284
+ * @example
3285
+ * ```ts
3286
+ * await collectionItem.navigateTo({
3287
+ * scrollTo: { collectionFieldId: fieldId },
3288
+ * })
3289
+ * ```
2462
3290
  */
2463
3291
  navigateTo(opts?: NavigableOptions): Promise<void>;
2464
3292
  }
2465
3293
 
3294
+ /** Options for controlling the `zoomIntoView` behavior. */
2466
3295
  interface ZoomIntoViewOptions {
2467
3296
  /**
2468
3297
  * Set a percentage limit for the maximum zoom level.
@@ -2505,6 +3334,34 @@ interface NodeClassToEditableAttributes {
2505
3334
  VectorSetItemNode: EditableVectorSetItemNodeAttributes;
2506
3335
  UnknownNode: object;
2507
3336
  }
3337
+ /**
3338
+ * Base class providing common methods shared by all node types. Nodes are
3339
+ * the building blocks that make up the content in a project. They are
3340
+ * represented as "layers" in the editor UI.
3341
+ *
3342
+ * Every node has a unique {@link NodeMethods.id | id}. Nodes support
3343
+ * plugin data storage, tree traversal (parent/children), cloning,
3344
+ * removal, and attribute updates.
3345
+ *
3346
+ * Every node has an {@link NodeMethods.isReplica | isReplica} property
3347
+ * that indicates if the node is a replica. Replica nodes are used within
3348
+ * non-primary breakpoints and component variants, and inherit attributes
3349
+ * from the primary variant or breakpoint. Once a specific attribute is
3350
+ * overridden on a replica node, it is no longer inherited from the
3351
+ * primary node.
3352
+ *
3353
+ * @example
3354
+ * ```ts
3355
+ * // Get selected nodes.
3356
+ * const selection = await framer.getSelection()
3357
+ *
3358
+ * // Get a node by ID.
3359
+ * const node = await framer.getNode("some-node-id")
3360
+ *
3361
+ * // Get all frame nodes in a project.
3362
+ * const frameNodes = await framer.getNodesWithType("FrameNode")
3363
+ * ```
3364
+ */
2508
3365
  declare abstract class NodeMethods implements WithIdTrait, Navigable {
2509
3366
  #private;
2510
3367
  abstract readonly [classKey]: PluginNodeClass;
@@ -2513,33 +3370,45 @@ declare abstract class NodeMethods implements WithIdTrait, Navigable {
2513
3370
  constructor(data: SomeNodeData, engine: PluginEngine);
2514
3371
  get isReplica(): boolean;
2515
3372
  /**
2516
- * Remove this node.
3373
+ * Remove this node from the canvas tree.
2517
3374
  *
2518
3375
  * Use `"Node.remove"` to check if this method is allowed.
2519
3376
  */
2520
3377
  remove(): Promise<void>;
2521
3378
  /**
2522
- * Select this node.
3379
+ * Select this node on the canvas.
2523
3380
  */
2524
3381
  select(): Promise<void>;
2525
3382
  /**
2526
- * Clone this node.
3383
+ * Clone this node, creating a duplicate in the canvas tree.
3384
+ *
3385
+ * @returns The cloned node, or `null` if the clone failed.
3386
+ * @throws If the node is an `UnknownNode`.
2527
3387
  *
2528
3388
  * Use `"Node.clone"` to check if this method is allowed.
2529
3389
  */
2530
3390
  clone(): Promise<(typeof this)[ClassKey] extends "UnknownNode" ? never : typeof this | null>;
2531
3391
  /**
2532
- * Set the attributes of this node.
3392
+ * Set the attributes of this node. Attributes are merged with existing
3393
+ * values, so only the provided attributes are updated.
3394
+ *
3395
+ * @param update - The attributes to update.
3396
+ * @returns The updated node, or `null` if the node was not found.
3397
+ * @throws If the node is an `UnknownNode`.
2533
3398
  *
2534
3399
  * Use `"Node.setAttributes"` to check if this method is allowed.
2535
3400
  */
2536
3401
  setAttributes(update: Partial<NodeClassToEditableAttributes[(typeof this)[ClassKey]]>): Promise<(typeof this)[ClassKey] extends "UnknownNode" ? never : typeof this | null>;
2537
3402
  /**
2538
3403
  * Get the bounding box of this node.
3404
+ *
3405
+ * @returns The bounding rectangle, or `null` if unavailable.
2539
3406
  */
2540
3407
  getRect(): Promise<Rect$1 | null>;
2541
3408
  /**
2542
3409
  * Pans and zooms the viewport to center the node.
3410
+ *
3411
+ * @param options - Options like `maxZoom` and `skipIfVisible`.
2543
3412
  */
2544
3413
  zoomIntoView(options?: ZoomIntoViewOptions): Promise<void>;
2545
3414
  /**
@@ -2547,15 +3416,35 @@ declare abstract class NodeMethods implements WithIdTrait, Navigable {
2547
3416
  */
2548
3417
  navigateTo(opts?: Pick<NavigableOptions, "select" | "zoomIntoView">): Promise<void>;
2549
3418
  /**
2550
- * Get the parent of this node.
3419
+ * Get the parent of this node in the canvas tree.
3420
+ *
3421
+ * @returns The parent node, or `null` if this is a root node.
2551
3422
  */
2552
3423
  getParent(): Promise<AnyNode | null>;
2553
3424
  /**
2554
- * Get the children of this node.
3425
+ * Get the children of this node in the canvas tree.
3426
+ *
3427
+ * @returns An array of child nodes. Returns an empty array for `UnknownNode`.
2555
3428
  */
2556
3429
  getChildren(): Promise<CanvasNode[]>;
2557
3430
  /**
2558
- * Get `type` descendants of this node.
3431
+ * Get descendants of this node that match the given type. This can
3432
+ * also be used to query within a selection subtree.
3433
+ *
3434
+ * @param type - The node type to search for.
3435
+ * @returns An array of matching descendant nodes.
3436
+ *
3437
+ * @example
3438
+ * ```ts
3439
+ * // Get all frame nodes in a project.
3440
+ * const frameNodes = await framer.getNodesWithType("FrameNode")
3441
+ *
3442
+ * // Query within a selection subtree.
3443
+ * const selection = await framer.getSelection()
3444
+ * if (selection.length === 1) {
3445
+ * const frameNodes = await selection[0].getNodesWithType("FrameNode")
3446
+ * }
3447
+ * ```
2559
3448
  */
2560
3449
  getNodesWithType(type: "FrameNode"): Promise<FrameNode[]>;
2561
3450
  getNodesWithType(type: "TextNode"): Promise<TextNode[]>;
@@ -2565,29 +3454,61 @@ declare abstract class NodeMethods implements WithIdTrait, Navigable {
2565
3454
  getNodesWithType(type: "WebPageNode"): Promise<WebPageNode[]>;
2566
3455
  getNodesWithType(type: "ComponentNode"): Promise<ComponentNode[]>;
2567
3456
  /**
2568
- * Get the descendants of this node that support `attribute`.
3457
+ * Get the descendants of this node that support `attribute`. This
3458
+ * returns nodes that have the given attribute defined in their type,
3459
+ * regardless of whether it has been set.
3460
+ *
3461
+ * @param attribute - The attribute name to filter by.
3462
+ * @returns An array of nodes that support the attribute.
3463
+ *
3464
+ * @example
3465
+ * ```ts
3466
+ * // Get any kind of node that has a background color attribute.
3467
+ * const nodes = await framer.getNodesWithAttribute("backgroundColor")
3468
+ * ```
2569
3469
  */
2570
3470
  getNodesWithAttribute<T extends NodeAttributeKey, Node = NodeWithAttribute<T>>(attribute: T): Promise<Node[]>;
2571
3471
  /**
2572
- * Get the descendants of this node that have `attribute` set.
3472
+ * Get the descendants of this node that have `attribute` set to a
3473
+ * non-null value.
3474
+ *
3475
+ * @param attribute - The attribute name to filter by.
3476
+ * @returns An array of nodes that have the attribute set.
3477
+ *
3478
+ * @example
3479
+ * ```ts
3480
+ * // Get all nodes with a background image set.
3481
+ * const nodes = await framer.getNodesWithAttributeSet("backgroundImage")
3482
+ * ```
2573
3483
  */
2574
3484
  getNodesWithAttributeSet<T extends NodeAttributeKey, Node = NodeWithAttribute<T>>(attribute: T): Promise<Node[]>;
2575
3485
  /**
2576
- * Walk this node and its descendants recursively.
3486
+ * Walk this node and its descendants recursively using an async
3487
+ * generator. Yields nodes depth-first.
2577
3488
  */
2578
3489
  walk(this: AnyNode): AsyncGenerator<AnyNode>;
2579
3490
  /**
2580
- * Get plugin data by key.
3491
+ * Get plugin data by key. Plugin data lets you store arbitrary
3492
+ * string values on individual nodes, scoped to your plugin.
3493
+ *
3494
+ * @param key - The plugin data key.
3495
+ * @returns The stored value, or `null` if no data exists for the key.
2581
3496
  */
2582
3497
  getPluginData(key: string): Promise<string | null>;
2583
3498
  /**
2584
- * Set plugin data by key.
3499
+ * Set plugin data by key. Plugin data lets you store arbitrary
3500
+ * string values on individual nodes, scoped to your plugin.
3501
+ *
3502
+ * @param key - The plugin data key.
3503
+ * @param value - The value to set, or `null` to remove.
2585
3504
  *
2586
3505
  * Use `"Node.setPluginData"` to check if this method is allowed.
2587
3506
  */
2588
3507
  setPluginData(key: string, value: string | null): Promise<void>;
2589
3508
  /**
2590
- * Get all plugin data keys.
3509
+ * Get all plugin data keys stored on this node.
3510
+ *
3511
+ * @returns An array of all plugin data keys.
2591
3512
  */
2592
3513
  getPluginDataKeys(): Promise<string[]>;
2593
3514
  }
@@ -2598,6 +3519,11 @@ interface EditableFrameNodeAttributes extends DrawableNode, WithPositionTrait, W
2598
3519
  interface FrameNodeData extends CommonNodeData, Partial<DrawableNode>, WithPositionTrait, Partial<WithComponentVariantTrait>, Partial<WithPinsTrait>, Partial<WithSizeTrait>, Partial<WithSizeConstraintsTrait>, Partial<WithAspectRatioTrait>, Partial<WithZIndexTrait>, Partial<WithOverflowTrait>, Partial<WithBackgroundColorTrait<TraitVariantData>>, Partial<WithBackgroundImageTrait<TraitVariantData>>, Partial<WithBackgroundGradientTrait<TraitVariantData>>, Partial<WithRotationTrait>, Partial<WithLinkTrait>, Partial<WithBorderRadiusTrait>, Partial<WithBorderTrait<TraitVariantData>>, Partial<WithLayoutTrait>, Partial<WithGridItemTrait>, Partial<WithBreakpointTrait>, Partial<WithImageRenderingTrait> {
2599
3520
  [classKey]: "FrameNode";
2600
3521
  }
3522
+ /**
3523
+ * A frame layer on the canvas, the most common container node. Frames
3524
+ * can contain children, have layout settings, backgrounds, borders, and
3525
+ * can serve as breakpoint or component variants.
3526
+ */
2601
3527
  declare class FrameNode extends NodeMethods implements EditableFrameNodeAttributes, WithBreakpointTrait {
2602
3528
  readonly [classKey]: FrameNodeData[ClassKey];
2603
3529
  readonly name: string | null;
@@ -2665,6 +3591,22 @@ interface EditableTextNodeAttributes extends DrawableNode, WithPositionTrait, Wi
2665
3591
  interface TextNodeData extends CommonNodeData, Partial<DrawableNode>, WithPositionTrait, Partial<WithPinsTrait>, Partial<WithSizeTrait>, Partial<WithSizeConstraintsTrait>, Partial<WithRotationTrait>, Partial<WithZIndexTrait>, Partial<WithLinkTrait>, Partial<WithOverflowTrait>, Partial<WithTextTruncationTrait>, Partial<WithFontTrait<TraitVariantData>>, Partial<WithInlineTextStyleTrait<TraitVariantData>>, Partial<WithGridItemTrait> {
2666
3592
  [classKey]: "TextNode";
2667
3593
  }
3594
+ /**
3595
+ * A text layer on the canvas. Use {@link TextNode.setText | setText} and
3596
+ * {@link TextNode.getText | getText} to work with plain text, or
3597
+ * {@link TextNode.setHTML | setHTML} and {@link TextNode.getHTML | getHTML}
3598
+ * for rich text content.
3599
+ *
3600
+ * @example
3601
+ * ```ts
3602
+ * const selection = await framer.getSelection()
3603
+ * for (const node of selection) {
3604
+ * if (isTextNode(node)) {
3605
+ * node.setText("Hello!")
3606
+ * }
3607
+ * }
3608
+ * ```
3609
+ */
2668
3610
  declare class TextNode extends NodeMethods implements EditableTextNodeAttributes {
2669
3611
  #private;
2670
3612
  readonly [classKey]: TextNodeData[ClassKey];
@@ -2730,6 +3672,10 @@ interface EditableSVGNodeAttributes extends DrawableNode, WithPositionTrait, Wit
2730
3672
  interface SVGNodeData extends CommonNodeData, Partial<DrawableNode>, WithPositionTrait, Partial<WithPinsTrait>, Partial<WithSizeTrait>, WithSVGTrait, Partial<WithRotationTrait> {
2731
3673
  [classKey]: "SVGNode";
2732
3674
  }
3675
+ /**
3676
+ * An SVG graphic layer on the canvas. Contains the raw SVG string and
3677
+ * supports positioning, sizing, rotation, and visibility.
3678
+ */
2733
3679
  declare class SVGNode extends NodeMethods implements EditableSVGNodeAttributes {
2734
3680
  readonly [classKey]: SVGNodeData[ClassKey];
2735
3681
  readonly name: string | null;
@@ -2754,6 +3700,7 @@ interface EditableVectorSetItemNodeAttributes extends WithNameTrait, WithVisible
2754
3700
  interface VectorSetItemNodeData extends CommonNodeData, Partial<WithNameTrait>, Partial<WithVisibleTrait>, Partial<WithLockedTrait>, Partial<WithPinsTrait>, Partial<WithSizeTrait> {
2755
3701
  [classKey]: "VectorSetItemNode";
2756
3702
  }
3703
+ /** An individual item within a VectorSet node. */
2757
3704
  declare class VectorSetItemNode extends NodeMethods implements EditableVectorSetItemNodeAttributes {
2758
3705
  #private;
2759
3706
  readonly [classKey]: VectorSetItemNodeData[ClassKey];
@@ -2776,6 +3723,21 @@ interface EditableComponentInstanceNodeAttributes extends DrawableNode, WithPosi
2776
3723
  interface ComponentInstanceNodeData extends CommonNodeData, Partial<DrawableNode>, WithPositionTrait, Partial<WithPinsTrait>, Partial<WithSizeTrait>, Partial<WithSizeConstraintsTrait>, Partial<WithAspectRatioTrait>, Partial<WithControlAttributesTrait>, Partial<WithTypedControlsTrait>, WithRequiredComponentInfoTrait, Partial<WithNullableComponentInfoTrait>, Partial<WithRotationTrait> {
2777
3724
  [classKey]: "ComponentInstanceNode";
2778
3725
  }
3726
+ /**
3727
+ * An instance of a code or design component on the canvas. Component
3728
+ * instances are identified by their {@link ComponentInstanceNode.componentIdentifier | componentIdentifier}
3729
+ * and can have their control properties updated via
3730
+ * {@link NodeMethods.setAttributes | setAttributes}.
3731
+ *
3732
+ * @example
3733
+ * ```ts
3734
+ * if (isCodeComponentNode(selection)) {
3735
+ * selection.setAttributes({
3736
+ * controls: { radius: 10 }
3737
+ * })
3738
+ * }
3739
+ * ```
3740
+ */
2779
3741
  declare class ComponentInstanceNode extends NodeMethods implements EditableComponentInstanceNodeAttributes, WithComponentInfoTrait {
2780
3742
  #private;
2781
3743
  readonly [classKey]: ComponentInstanceNodeData[ClassKey];
@@ -2816,6 +3778,11 @@ type EditableWebPageNodeAttributes = object;
2816
3778
  interface WebPageNodeData extends CommonNodeData, Partial<WithWebPageInfoTrait> {
2817
3779
  [classKey]: "WebPageNode";
2818
3780
  }
3781
+ /**
3782
+ * A web page in the project's site map. Web pages have a
3783
+ * {@link WebPageNode.path | path} and may be associated with a CMS
3784
+ * collection when used as a detail page.
3785
+ */
2819
3786
  declare class WebPageNode extends NodeMethods implements EditableWebPageNodeAttributes, WithWebPageInfoTrait {
2820
3787
  #private;
2821
3788
  readonly [classKey]: WebPageNodeData[ClassKey];
@@ -2854,6 +3821,11 @@ type EditableComponentNodeAttributes = WithNameTrait;
2854
3821
  interface ComponentNodeData extends CommonNodeData, Partial<WithNameTrait>, WithRequiredComponentInfoTrait, Partial<WithNullableComponentInfoTrait> {
2855
3822
  [classKey]: "ComponentNode";
2856
3823
  }
3824
+ /**
3825
+ * A reusable design component definition. Component nodes contain
3826
+ * variants, gesture states, and variables. They can be inserted as
3827
+ * instances via their module URL.
3828
+ */
2857
3829
  declare class ComponentNode extends NodeMethods implements EditableComponentNodeAttributes, WithComponentInfoTrait {
2858
3830
  #private;
2859
3831
  readonly [classKey]: ComponentNodeData[ClassKey];
@@ -2920,6 +3892,7 @@ type EditableVectorSetNodeAttributes = WithNameTrait;
2920
3892
  interface VectorSetNodeData extends CommonNodeData, Partial<WithNameTrait> {
2921
3893
  [classKey]: "VectorSetNode";
2922
3894
  }
3895
+ /** A container node for a set of vector icons. */
2923
3896
  declare class VectorSetNode extends NodeMethods implements EditableVectorSetNodeAttributes {
2924
3897
  readonly [classKey]: VectorSetNodeData[ClassKey];
2925
3898
  readonly name: string | null;
@@ -2929,6 +3902,7 @@ type EditableDesignPageNodeAttributes = WithNameTrait;
2929
3902
  interface DesignPageNodeData extends CommonNodeData, Partial<WithNameTrait> {
2930
3903
  [classKey]: "DesignPageNode";
2931
3904
  }
3905
+ /** A design page (non-web canvas) in the project. */
2932
3906
  declare class DesignPageNode extends NodeMethods implements EditableDesignPageNodeAttributes {
2933
3907
  readonly [classKey]: DesignPageNodeData[ClassKey];
2934
3908
  readonly name: string | null;
@@ -2937,6 +3911,11 @@ declare class DesignPageNode extends NodeMethods implements EditableDesignPageNo
2937
3911
  interface UnknownNodeData extends CommonNodeData {
2938
3912
  [classKey]: "UnknownNode";
2939
3913
  }
3914
+ /**
3915
+ * A node whose type is not recognized by the current plugin API version.
3916
+ * Unknown nodes cannot be cloned, have their attributes set, or return
3917
+ * children.
3918
+ */
2940
3919
  declare class UnknownNode extends NodeMethods {
2941
3920
  readonly [classKey]: UnknownNodeData[ClassKey];
2942
3921
  constructor(rawData: UnknownNodeData, engine: PluginEngine);
@@ -2989,27 +3968,37 @@ interface ApiVersion1User {
2989
3968
  /** Hashed user id */
2990
3969
  id: string;
2991
3970
  }
3971
+ /** Information about a Framer user. */
2992
3972
  interface User extends ApiVersion1User {
2993
3973
  /** Hashed user id served by API version 1, use for migration only */
2994
3974
  apiVersion1Id: string;
3975
+ /** URL to the user's avatar image, if available. */
2995
3976
  avatarUrl?: string | undefined;
2996
- /** For when there is no avatar. */
3977
+ /** Initials of the user's name, for use when no avatar is available. */
2997
3978
  initials: string;
2998
3979
  }
2999
3980
 
3000
3981
  interface CodeExportCommon {
3982
+ /** The export name. */
3001
3983
  name: string;
3984
+ /** Whether this is the default export of the file. */
3002
3985
  isDefaultExport: boolean;
3003
3986
  }
3987
+ /** A component export from a code file. */
3004
3988
  interface CodeFileComponentExport extends CodeExportCommon {
3989
+ /** URL that can be used with `addComponentInstance` to insert this export onto the canvas. */
3005
3990
  insertURL: string;
3991
+ /** Discriminator indicating this is a component export. */
3006
3992
  type: "component";
3007
3993
  }
3994
+ /** An override export from a code file. */
3008
3995
  interface CodeFileOverrideExport extends CodeExportCommon {
3996
+ /** Discriminator indicating this is an override export. */
3009
3997
  type: "override";
3010
3998
  }
3011
3999
  declare function isCodeFileComponentExport(exportItem: CodeFileExport): exportItem is CodeFileComponentExport;
3012
4000
  declare function isCodeFileOverrideExport(exportItem: CodeFileExport): exportItem is CodeFileOverrideExport;
4001
+ /** Union of possible code file export types: component or override. */
3013
4002
  type CodeFileExport = CodeFileComponentExport | CodeFileOverrideExport;
3014
4003
  /** @alpha */
3015
4004
  type ShowProgressOnInstancesAttributes = Pick<ComponentInstancePlaceholderAttributes, "title" | "codePreview">;
@@ -3026,44 +4015,103 @@ interface CodeFileVersionData extends Pick<CodeFileData, "id" | "name"> {
3026
4015
  createdAt: string;
3027
4016
  createdBy: User;
3028
4017
  }
4018
+ /**
4019
+ * A saved version (snapshot) of a code file.
4020
+ */
3029
4021
  declare class CodeFileVersion {
3030
4022
  #private;
4023
+ /** The unique identifier of the version. */
3031
4024
  get id(): string;
4025
+ /** The file name at this version. */
3032
4026
  get name(): string;
4027
+ /** The ISO 8601 timestamp of when the version was created. */
3033
4028
  get createdAt(): string;
4029
+ /** The user who created this version. */
3034
4030
  get createdBy(): Readonly<User>;
3035
4031
  constructor(data: CodeFileVersionData, engine: PluginEngine);
4032
+ /**
4033
+ * Retrieve the source code content of this version.
4034
+ *
4035
+ * @example
4036
+ * ```ts
4037
+ * const previousContent = await version.getContent()
4038
+ * ```
4039
+ *
4040
+ * @returns The file content as a string.
4041
+ */
3036
4042
  getContent(): Promise<string>;
3037
4043
  }
4044
+ /**
4045
+ * Represents a code file in the Framer project, such as a code component
4046
+ * or code override.
4047
+ */
3038
4048
  declare class CodeFile implements Navigable {
3039
4049
  #private;
4050
+ /** The unique identifier of the code file. */
3040
4051
  get id(): string;
4052
+ /** The name of the code file (e.g., `"MyComponent.tsx"`). */
3041
4053
  get name(): string;
4054
+ /** The file system path of the code file within the project. */
3042
4055
  get path(): string;
4056
+ /** The current source code content of the file. */
3043
4057
  get content(): string;
4058
+ /** The array of exports available in this code file (components and overrides). */
3044
4059
  get exports(): readonly CodeFileExport[];
3045
4060
  get versionId(): string;
3046
4061
  constructor(data: CodeFileData, engine: PluginEngine);
3047
4062
  /**
3048
- * Set the content of this code file.
4063
+ * Set the content of this code file. Creates a new version.
4064
+ *
4065
+ * @example
4066
+ * ```ts
4067
+ * const updatedFile = await codeFile.setFileContent(
4068
+ * `export default function MyComponent() {
4069
+ * return <div>Hello World</div>
4070
+ * }`
4071
+ * )
4072
+ * ```
3049
4073
  *
3050
4074
  * Use `"CodeFile.setFileContent"` to check if this method is allowed.
4075
+ *
4076
+ * @param code - The new source code content.
4077
+ * @returns The updated CodeFile instance.
3051
4078
  */
3052
4079
  setFileContent(code: string): Promise<CodeFile>;
3053
4080
  /**
3054
4081
  * Rename this code file.
3055
4082
  *
4083
+ * @example
4084
+ * ```ts
4085
+ * const renamedFile = await codeFile.rename("NewComponentName.tsx")
4086
+ * ```
4087
+ *
3056
4088
  * Use `"CodeFile.rename"` to check if this method is allowed.
4089
+ *
4090
+ * @param newName - The new name for the file.
4091
+ * @returns The updated CodeFile instance.
3057
4092
  */
3058
4093
  rename(newName: string): Promise<CodeFile>;
3059
4094
  /**
3060
- * Remove this code file.
4095
+ * Remove this code file from the project.
4096
+ *
4097
+ * @example
4098
+ * ```ts
4099
+ * await codeFile.remove()
4100
+ * ```
3061
4101
  *
3062
4102
  * Use `"CodeFile.remove"` to check if this method is allowed.
3063
4103
  */
3064
4104
  remove(): Promise<void>;
3065
4105
  /**
3066
- * Get all versions of this code file.
4106
+ * Get all versions (history) of this code file.
4107
+ *
4108
+ * @example
4109
+ * ```ts
4110
+ * const versions = await codeFile.getVersions()
4111
+ * console.log(`File has ${versions.length} versions`)
4112
+ * ```
4113
+ *
4114
+ * @returns An array of CodeFileVersion instances.
3067
4115
  */
3068
4116
  getVersions(): Promise<readonly CodeFileVersion[]>;
3069
4117
  /** @alpha */
@@ -3074,18 +4122,41 @@ declare class CodeFile implements Navigable {
3074
4122
  * @deprecated The implementation of this method was removed. The method will always return an empty array. The method will be removed in the near future.
3075
4123
  */
3076
4124
  lint(_rules: LintConfig): Promise<LintDiagnostic[]>;
4125
+ /**
4126
+ * Run TypeScript type checking on this code file.
4127
+ *
4128
+ * @example
4129
+ * ```ts
4130
+ * const typeErrors = await codeFile.typecheck({
4131
+ * strict: true
4132
+ * })
4133
+ * ```
4134
+ *
4135
+ * @param compilerOptions - Optional TypeScript compiler options. See the TypeScript
4136
+ * CompilerOptions reference for all available options.
4137
+ * @returns An array of `TypecheckDiagnostic` results.
4138
+ */
3077
4139
  typecheck(compilerOptions?: ts.server.protocol.CompilerOptions): Promise<TypecheckDiagnostic[]>;
3078
4140
  /**
3079
- * Navigate to this code file. May switch modes to reveal the relevant view.
4141
+ * Navigate to this code file in the Code Editor. May switch modes to
4142
+ * reveal the relevant view.
4143
+ *
4144
+ * @example
4145
+ * ```ts
4146
+ * await codeFile.navigateTo()
4147
+ * ```
3080
4148
  */
3081
4149
  navigateTo(): Promise<void>;
3082
4150
  }
3083
4151
 
4152
+ /** Where in the HTML document the custom code is injected. */
3084
4153
  type CustomCodeLocation = "headStart" | "headEnd" | "bodyStart" | "bodyEnd";
4154
+ /** Options for setting custom HTML code on the site. A plugin can only set custom code once per location. */
3085
4155
  interface SetCustomCodeOptions {
3086
4156
  html: string | null;
3087
4157
  location: CustomCodeLocation;
3088
4158
  }
4159
+ /** Custom HTML code settings for all injection locations, including disabled state. */
3089
4160
  type CustomCode = Record<CustomCodeLocation, {
3090
4161
  disabled: boolean;
3091
4162
  html: string | null;
@@ -3118,6 +4189,16 @@ interface DetachedComponentLayersDragData extends WithOptionalName$1, WithOption
3118
4189
  layout?: boolean;
3119
4190
  attributes?: Partial<EditableComponentInstanceNodeAttributes>;
3120
4191
  }
4192
+ /**
4193
+ * Data describing what is being dragged onto the canvas. Different types
4194
+ * of drag data result in different canvas insertions.
4195
+ *
4196
+ * Supported drag types:
4197
+ * - `"image"` - An image with an optional preview image, alt text, and resolution.
4198
+ * - `"svg"` - An SVG string with an optional preview image. Use `invertInDarkMode` to invert the drag preview in dark mode.
4199
+ * - `"componentInstance"` - A component instance identified by its module URL.
4200
+ * - `"detachedComponentLayers"` - Detached layers from a component designed in Framer. Use `layout: true` to insert as a layout block.
4201
+ */
3121
4202
  type DragData = SvgDragData | ImageDragData | ComponentInstanceDragData | DetachedComponentLayersDragData;
3122
4203
  interface Point {
3123
4204
  x: number;
@@ -3146,16 +4227,37 @@ type DragEndInfo = DragSessionId & {
3146
4227
  interface DragCompleteSuccess {
3147
4228
  /** Whether the drag was successful or not. */
3148
4229
  status: "success";
3149
- /** The inserted node id. */
4230
+ /** The ID of the node that was inserted. Only available when the drag succeeded. */
3150
4231
  nodeId: NodeId;
3151
4232
  }
3152
4233
  interface DragCompleteError {
3153
4234
  /** Whether the drag was successful or not. */
3154
4235
  status: "error";
3155
- /** Reason for the error, if available. */
4236
+ /** The reason why the drag failed. Only available when the drag failed. */
3156
4237
  reason?: string;
3157
4238
  }
4239
+ /**
4240
+ * The result of a drag operation, indicating success or failure.
4241
+ *
4242
+ * @example
4243
+ * ```ts
4244
+ * onDragComplete={(result) => {
4245
+ * if (result.status === "error") {
4246
+ * framer.notify(result.reason ?? "Unknown error");
4247
+ * return;
4248
+ * }
4249
+ *
4250
+ * framer.notify("Image uploaded successfully");
4251
+ * }}
4252
+ * ```
4253
+ */
3158
4254
  type DragCompleteResult = DragCompleteSuccess | DragCompleteError;
4255
+ /**
4256
+ * Callback invoked when a drag operation completes. Receives a
4257
+ * {@link DragCompleteResult} indicating whether the drag was successful
4258
+ * or not, including the inserted node ID on success or an error reason
4259
+ * on failure.
4260
+ */
3159
4261
  type DragCompleteCallback = (result: DragCompleteResult) => void;
3160
4262
 
3161
4263
  declare const publish: unique symbol;
@@ -3198,14 +4300,29 @@ interface VectorSetItemVariable {
3198
4300
  id: string;
3199
4301
  name: string;
3200
4302
  }
4303
+ /**
4304
+ * A set of vector icons available in the project.
4305
+ *
4306
+ * @alpha
4307
+ */
3201
4308
  declare class VectorSet {
3202
4309
  #private;
3203
4310
  id: string;
3204
4311
  name: string;
3205
4312
  owner: Ownership;
3206
4313
  constructor(data: VectorSetData, engine: PluginEngine);
4314
+ /**
4315
+ * Get all vector items in this set.
4316
+ *
4317
+ * @returns An array of VectorSetItem instances.
4318
+ */
3207
4319
  getItems(): Promise<VectorSetItem[]>;
3208
4320
  }
4321
+ /**
4322
+ * An individual vector icon within a VectorSet.
4323
+ *
4324
+ * @alpha
4325
+ */
3209
4326
  declare class VectorSetItem {
3210
4327
  #private;
3211
4328
  id: string;
@@ -3213,6 +4330,11 @@ declare class VectorSetItem {
3213
4330
  insertUrl: string;
3214
4331
  iconUrl: string;
3215
4332
  constructor(data: VectorSetItemData, engine: PluginEngine);
4333
+ /**
4334
+ * Get the customizable variables (e.g. color, stroke width) for this vector item.
4335
+ *
4336
+ * @returns An array of variable definitions.
4337
+ */
3216
4338
  getVariables(): Promise<VectorSetItemVariable[]>;
3217
4339
  }
3218
4340
 
@@ -3223,7 +4345,7 @@ type NamespaceMembers<Class, Namespace extends string, Parent = undefined> = {
3223
4345
  [Member in Exclude<keyof Class, keyof Parent> as Member extends string ? `${Namespace}.${Member}` : never]: Class[Member];
3224
4346
  };
3225
4347
  type AllMembers = Omit<FramerPluginAPIAlpha, "isAllowedTo" | "subscribeToIsAllowedTo"> & NamespaceMembers<ImageAsset, "ImageAsset"> & NamespaceMembers<CodeFile, "CodeFile"> & NamespaceMembers<CodeFileVersion, "CodeFileVersion"> & NamespaceMembers<ComponentInstancePlaceholder, "ComponentInstancePlaceholder"> & NamespaceMembers<Field, "Field"> & NamespaceMembers<BooleanField, "BooleanField", Field> & NamespaceMembers<ColorField, "ColorField", Field> & NamespaceMembers<NumberField, "NumberField", Field> & NamespaceMembers<StringField, "StringField", Field> & NamespaceMembers<FormattedTextField, "FormattedTextField", Field> & NamespaceMembers<ImageField, "ImageField", Field> & NamespaceMembers<LinkField, "LinkField", Field> & NamespaceMembers<DateField, "DateField", Field> & NamespaceMembers<FieldDivider, "FieldDivider", Field> & NamespaceMembers<UnsupportedField, "UnsupportedField", Field> & NamespaceMembers<FileField, "FileField", Field> & NamespaceMembers<EnumField, "EnumField", Field> & NamespaceMembers<CollectionReferenceField, "CollectionReferenceField", Field> & NamespaceMembers<MultiCollectionReferenceField, "MultiCollectionReferenceField", Field> & NamespaceMembers<ManagedCollection, "ManagedCollection"> & NamespaceMembers<Collection, "Collection"> & NamespaceMembers<CollectionItem, "CollectionItem"> & NamespaceMembers<NodeMethods, "Node"> & NamespaceMembers<FrameNode, "FrameNode", NodeMethods> & NamespaceMembers<TextNode, "TextNode", NodeMethods> & NamespaceMembers<SVGNode, "SVGNode", NodeMethods> & NamespaceMembers<ComponentInstanceNode, "ComponentInstanceNode", NodeMethods> & NamespaceMembers<WebPageNode, "WebPageNode", NodeMethods> & NamespaceMembers<ComponentNode, "ComponentNode", NodeMethods> & NamespaceMembers<UnknownNode, "UnknownNode", NodeMethods> & NamespaceMembers<ColorStyle, "ColorStyle"> & NamespaceMembers<TextStyle, "TextStyle"> & NamespaceMembers<Variable, "Variable"> & NamespaceMembers<BooleanVariable, "BooleanVariable", Variable> & NamespaceMembers<NumberVariable, "NumberVariable", Variable> & NamespaceMembers<StringVariable, "StringVariable", Variable> & NamespaceMembers<FormattedTextVariable, "FormattedTextVariable", Variable> & NamespaceMembers<EnumCase, "EnumCase"> & NamespaceMembers<EnumVariable, "EnumVariable", Variable> & NamespaceMembers<ColorVariable, "ColorVariable", Variable> & NamespaceMembers<ImageVariable, "ImageVariable", Variable> & NamespaceMembers<FileVariable, "FileVariable", Variable> & NamespaceMembers<LinkVariable, "LinkVariable", Variable> & NamespaceMembers<DateVariable, "DateVariable", Variable> & NamespaceMembers<BorderVariable, "BorderVariable", Variable> & NamespaceMembers<UnsupportedVariable, "UnsupportedVariable", Variable> & NamespaceMembers<VectorSet, "VectorSet"> & NamespaceMembers<VectorSetItem, "VectorSetItem">;
3226
- declare const unprotectedMessageTypesSource: ["closeNotification", "closePlugin", "setCloseWarning", "getActiveCollection", "getActiveLocale", "getActiveManagedCollection", "getCanvasRoot", "getChildren", "getCollection", "getCollectionFields", "getCollectionFields2", "getCollectionItems", "getCollectionItems2", "getCollections", "getColorStyle", "getColorStyles", "getCurrentUser", "getCurrentUser2", "getCustomCode", "getDefaultLocale", "getFont", "getFonts", "getImage", "getImageData", "getLocales", "getLocalizationGroups", "getManagedCollection", "getManagedCollectionFields", "getManagedCollectionFields2", "getManagedCollectionItemIds", "getManagedCollections", "getNode", "getNodesWithAttribute", "getNodesWithAttributeSet", "getNodesWithType", "getParent", "getPluginData", "getPluginDataForNode", "getPluginDataKeys", "getPluginDataKeysForNode", "getProjectInfo", "getProjectInfo2", "getPublishInfo", "getRect", "getSelection", "getSVGForNode", "getText", "getTextForNode", "getTextStyle", "getTextStyles", "hideUI", "setBackgroundMessage", "notify", "onPointerDown", "setActiveCollection", "setSelection", "showUI", "getCodeFileVersionContent", "typecheckCode", "getCodeFileVersions", "getCodeFiles", "getCodeFile", "getRedirects", "uploadFile", "uploadFiles", "uploadImage", "uploadImages", "zoomIntoView", "navigateTo", "getRuntimeErrorForModule", "getRuntimeErrorForCodeComponentNode", "showProgressOnInstances", "removeProgressFromInstances", "addComponentInstancePlaceholder", "updateComponentInstancePlaceholder", "removeComponentInstancePlaceholder", "setMenu", "showContextMenu", "getBreakpointSuggestionsForWebPage", "getActiveCollectionItemForWebPage", "getVariables", "getVectorSets", "getVectorSetItems", "getVectorSetItemVariables", "getChangedPaths", "getChangeContributors", "getDeployments", "INTERNAL_getAiServiceInfo", "INTERNAL_sendTrackingEvent", "INTERNAL_getHTMLForNode", "getAiServiceInfo", "sendTrackingEvent", "unstable_getCodeFile", "unstable_getCodeFiles", "unstable_getCodeFileVersionContent", "unstable_getCodeFileLint2", "unstable_getCodeFileTypecheck2", "unstable_getCodeFileVersions", "lintCode"];
4348
+ declare const unprotectedMessageTypesSource: ["closeNotification", "closePlugin", "setCloseWarning", "getActiveCollection", "getActiveLocale", "getActiveManagedCollection", "getCanvasRoot", "getChildren", "getCollection", "getCollectionFields", "getCollectionFields2", "getCollectionItems", "getCollectionItems2", "getCollections", "getColorStyle", "getColorStyles", "getCurrentUser", "getCurrentUser2", "getCustomCode", "getDefaultLocale", "getFont", "getFonts", "getImage", "getImageData", "getLocales", "getLocaleLanguages", "getLocaleRegions", "getLocalizationGroups", "getManagedCollection", "getManagedCollectionFields", "getManagedCollectionFields2", "getManagedCollectionItemIds", "getManagedCollections", "getNode", "getNodesWithAttribute", "getNodesWithAttributeSet", "getNodesWithType", "getParent", "getPluginData", "getPluginDataForNode", "getPluginDataKeys", "getPluginDataKeysForNode", "getProjectInfo", "getProjectInfo2", "getPublishInfo", "getRect", "getSelection", "getSVGForNode", "getText", "getTextForNode", "getTextStyle", "getTextStyles", "hideUI", "setBackgroundMessage", "notify", "onPointerDown", "setActiveCollection", "setSelection", "showUI", "getCodeFileVersionContent", "typecheckCode", "getCodeFileVersions", "getCodeFiles", "getCodeFile", "getRedirects", "uploadFile", "uploadFiles", "uploadImage", "uploadImages", "zoomIntoView", "navigateTo", "getRuntimeErrorForModule", "getRuntimeErrorForCodeComponentNode", "showProgressOnInstances", "removeProgressFromInstances", "addComponentInstancePlaceholder", "updateComponentInstancePlaceholder", "removeComponentInstancePlaceholder", "setMenu", "showContextMenu", "getBreakpointSuggestionsForWebPage", "getActiveCollectionItemForWebPage", "getVariables", "getVectorSets", "getVectorSetItems", "getVectorSetItemVariables", "getChangedPaths", "getChangeContributors", "getDeployments", "INTERNAL_getAiServiceInfo", "INTERNAL_sendTrackingEvent", "INTERNAL_getHTMLForNode", "getAiServiceInfo", "sendTrackingEvent", "unstable_getCodeFile", "unstable_getCodeFiles", "unstable_getCodeFileVersionContent", "unstable_getCodeFileLint2", "unstable_getCodeFileTypecheck2", "unstable_getCodeFileVersions", "lintCode"];
3227
4349
  type UnprotectedMessageType = (typeof unprotectedMessageTypesSource)[number];
3228
4350
  type ProtectedMessageType = Exclude<keyof PluginMessageAPI, UnprotectedMessageType>;
3229
4351
  type Method = keyof {
@@ -3286,7 +4408,6 @@ declare const methodToMessageTypes: {
3286
4408
  readonly getTextStyle: [];
3287
4409
  readonly getTextStyles: [];
3288
4410
  readonly hideUI: [];
3289
- /** @beta */
3290
4411
  readonly setBackgroundMessage: [];
3291
4412
  readonly setCloseWarning: [];
3292
4413
  /** @deprecated The lintCode API was removed. */
@@ -3302,6 +4423,9 @@ declare const methodToMessageTypes: {
3302
4423
  readonly setCustomCode: ["setCustomCode"];
3303
4424
  readonly setImage: ["setImage"];
3304
4425
  readonly setLocalizationData: ["setLocalizationData"];
4426
+ readonly createLocale: ["createLocale"];
4427
+ readonly getLocaleLanguages: [];
4428
+ readonly getLocaleRegions: [];
3305
4429
  readonly setMenu: [];
3306
4430
  readonly showContextMenu: [];
3307
4431
  readonly setParent: ["setParent"];
@@ -3527,25 +4651,65 @@ interface UpdateRedirect extends Partial<RedirectAttributes>, Partial<WithToFiel
3527
4651
  id: string;
3528
4652
  }
3529
4653
  type RedirectInput = Prettify<CreateRedirect | UpdateRedirect>;
4654
+ /**
4655
+ * A URL redirect configured in the project. Redirects are applied when
4656
+ * the site is published.
4657
+ */
3530
4658
  declare class Redirect {
3531
4659
  #private;
3532
- /** The id of the redirect. */
4660
+ /** A unique identifier for the redirect. */
3533
4661
  get id(): string;
3534
- /** The source path to redirect from. */
4662
+ /** The source path of the redirect. */
3535
4663
  get from(): string;
3536
- /** The destination path to redirect to. */
4664
+ /**
4665
+ * The destination path of the redirect.
4666
+ *
4667
+ * When a redirect points to an existing page, the `to` value will
4668
+ * always point to that page. This property will be set to `null` if
4669
+ * the page it points to was removed.
4670
+ */
3537
4671
  get to(): string | null;
3538
- /** Whether to expand the redirect to all locales. */
4672
+ /**
4673
+ * Whether the redirect is expanded to all locales. When enabled, the
4674
+ * redirect will apply not only in the base locale, but also in all
4675
+ * other locales in the project.
4676
+ *
4677
+ * For example, for a project with a Spanish locale, the following
4678
+ * would redirect both `/business` to `/enterprise`, and
4679
+ * `/es/business` to `/es/enterprise`.
4680
+ *
4681
+ * @example
4682
+ * ```ts
4683
+ * await framer.addRedirects([
4684
+ * { from: "/business", to: "/enterprise", expandToAllLocales: true }
4685
+ * ])
4686
+ * ```
4687
+ */
3539
4688
  get expandToAllLocales(): boolean;
3540
4689
  constructor(data: RedirectData, engine: PluginEngine);
3541
4690
  /**
3542
4691
  * Remove the redirect.
4692
+ *
4693
+ * @returns A promise that resolves when the redirect is removed.
4694
+ *
4695
+ * @example
4696
+ * ```ts
4697
+ * await redirect.remove()
4698
+ * ```
3543
4699
  */
3544
4700
  remove(): Promise<void>;
3545
4701
  /**
3546
- * Update the redirect attributes.
4702
+ * Set the attributes of a redirect.
3547
4703
  *
4704
+ * @param attributes - The updated attributes and their new values.
3548
4705
  * @returns The updated redirect, or `null` if the redirect was not found.
4706
+ * @throws When the current user does not have permission to edit Site Settings, a `FramerPluginError` is thrown.
4707
+ * @throws When the current project is not on a plan that includes redirects, a `FramerPluginError` is thrown.
4708
+ *
4709
+ * @example
4710
+ * ```ts
4711
+ * await redirect.setAttributes({ from: "/new-url" })
4712
+ * ```
3549
4713
  */
3550
4714
  setAttributes(attributes: Partial<CreateRedirect>): Promise<Redirect | null>;
3551
4715
  }
@@ -3679,9 +4843,11 @@ type InitialState = {
3679
4843
  intent: "collection/add";
3680
4844
  };
3681
4845
 
4846
+ /** A visual separator between menu items. */
3682
4847
  interface SeparatorMenuItem {
3683
4848
  type: "separator";
3684
4849
  }
4850
+ /** An actionable menu item with a label and optional submenu. */
3685
4851
  interface NormalMenuItem {
3686
4852
  type?: never;
3687
4853
  label: string;
@@ -3692,6 +4858,7 @@ interface NormalMenuItem {
3692
4858
  submenu?: MenuItem[];
3693
4859
  onAction?: () => void;
3694
4860
  }
4861
+ /** A menu item, either a normal action item or a separator. */
3695
4862
  type MenuItem = NormalMenuItem | SeparatorMenuItem;
3696
4863
  type NormalMenuItemSerializable = Omit<NormalMenuItem, "onAction" | "submenu"> & {
3697
4864
  actionId?: number;
@@ -3701,6 +4868,7 @@ type MenuItemSerializable = NormalMenuItemSerializable | SeparatorMenuItem;
3701
4868
  type MenuPlacementVertical = "top" | "bottom";
3702
4869
  type MenuPlacementHorizontal = "left" | "right";
3703
4870
  type MenuPlacement = MenuPlacementVertical | MenuPlacementHorizontal | `${MenuPlacementVertical}-${MenuPlacementHorizontal}`;
4871
+ /** Configuration for positioning and sizing a context menu. */
3704
4872
  interface ContextMenuConfig {
3705
4873
  /**
3706
4874
  * Coordinates of the anchor point.
@@ -3725,6 +4893,7 @@ interface NotifyOptionsBase {
3725
4893
  variant?: NotificationVariant;
3726
4894
  durationMs?: number;
3727
4895
  }
4896
+ /** Options for customizing a notification. */
3728
4897
  interface NotifyOptions extends NotifyOptionsBase {
3729
4898
  /** A button to be displayed on the notification */
3730
4899
  button?: {
@@ -3740,10 +4909,12 @@ interface NotifyOptionsData extends NotifyOptionsBase {
3740
4909
  buttonText?: string;
3741
4910
  notificationId: string;
3742
4911
  }
4912
+ /** A handle to an active notification, allowing it to be closed programmatically. */
3743
4913
  interface Notification {
3744
4914
  close: () => Promise<void>;
3745
4915
  }
3746
4916
  type NotificationCloseReason = "timeoutReachedOrDismissed" | "actionButtonClicked";
4917
+ /** Function signature for displaying a notification message. */
3747
4918
  type Notify = (message: string, options?: NotifyOptions) => Notification;
3748
4919
 
3749
4920
  /**
@@ -3751,7 +4922,8 @@ type Notify = (message: string, options?: NotifyOptions) => Notification;
3751
4922
  */
3752
4923
  interface NavigableOptions {
3753
4924
  /**
3754
- * Selects the item after navigation (e.g., opens the editor for a CollectionItem or selects it on the canvas).
4925
+ * Selects the item after navigation. Selects the item on the canvas or opens
4926
+ * the editor sidebar on a collection item.
3755
4927
  * @default true
3756
4928
  */
3757
4929
  select?: boolean | undefined;
@@ -3800,7 +4972,19 @@ interface AiServiceInfo {
3800
4972
  declare class FramerPluginAPI {
3801
4973
  #private;
3802
4974
  constructor(engine: PluginEngine);
3803
- /** Get the current mode. A plugin can launch in a special mode where only a subset of the API is allowed. */
4975
+ /**
4976
+ * Get the current mode. A plugin can launch in a special mode where only a
4977
+ * subset of the API is allowed. The mode is set when the plugin launches
4978
+ * and never changes while the plugin is active.
4979
+ *
4980
+ * @example
4981
+ * ```ts
4982
+ * if (framer.mode === "image" || framer.mode === "editImage") {
4983
+ * // Do image mode specific logic
4984
+ * return
4985
+ * }
4986
+ * ```
4987
+ */
3804
4988
  get mode(): Mode;
3805
4989
  /**
3806
4990
  * Find out if user's permissions allow them to execute all of `methods`:
@@ -3810,8 +4994,18 @@ declare class FramerPluginAPI {
3810
4994
  * if (framer.isAllowedTo("Collection.setItemOrder")) await collection.setItemOrder(...)
3811
4995
  * ```
3812
4996
  *
4997
+ * For class instance methods (e.g., `CollectionItem.remove`), prefix with
4998
+ * the class name. Multiple methods can be checked at once; the result is
4999
+ * `true` only if all are allowed.
5000
+ *
3813
5001
  * Note that when the result of the permission check affects the UI, it's better to use the
3814
5002
  * `subscribeToIsAllowedTo` method, or `useIsAllowedTo` if using React.
5003
+ *
5004
+ * A `FramerPluginError` is thrown if a protected method is called without
5005
+ * sufficient permissions.
5006
+ *
5007
+ * @param methods - The methods to check, at least one.
5008
+ * @returns `true` if all of `methods` can be executed, `false` otherwise.
3815
5009
  */
3816
5010
  isAllowedTo(...methods: [ProtectedMethod, ...ProtectedMethod[]]): boolean;
3817
5011
  /**
@@ -3825,21 +5019,80 @@ declare class FramerPluginAPI {
3825
5019
  * ```
3826
5020
  *
3827
5021
  * Refer to `useIsAllowedTo` for a React hook version of this.
5022
+ *
5023
+ * @param methods - The methods to check, at least one.
5024
+ * @param callback - Called every time the isAllowed result changes, where `isAllowed` is `true` if all of `methods` can be executed.
5025
+ * @returns A function to call to unsubscribe.
3828
5026
  */
3829
5027
  subscribeToIsAllowedTo(...args: [...methods: [ProtectedMethod, ...ProtectedMethod[]], callback: (isAllowed: boolean) => void]): Unsubscribe$1;
3830
- /** Show the plugin UI. */
3831
- showUI(options?: UIOptions): Promise<void>;
3832
- /** Hide the plugin window, without stopping the plugin. */
3833
- hideUI(): Promise<void>;
3834
- /** Update the background status text shown while the plugin UI is hidden. */
3835
- setBackgroundMessage(status: string | null): Promise<void>;
3836
5028
  /**
3837
- * Stop the plugin. Throws `FramerPluginClosedError`, which should be ignored.
3838
- * @param message - Optional message to show in the notification (ignored if options.silent is true)
3839
- * @param options - Options to control the close behaviour
5029
+ * Show the plugin window.
5030
+ *
5031
+ * @param options - The options for how to show the UI.
5032
+ *
5033
+ * @example
5034
+ * ```ts
5035
+ * framer.showUI({
5036
+ * position: "center",
5037
+ * height: 300,
5038
+ * width: 220
5039
+ * })
5040
+ * ```
5041
+ */
5042
+ showUI(options?: UIOptions): Promise<void>;
5043
+ /**
5044
+ * Hide the plugin window, without stopping the plugin.
5045
+ *
5046
+ * The plugin continues to run in the background after hiding. Use
5047
+ * `setBackgroundMessage` to communicate status while hidden.
5048
+ *
5049
+ * @example
5050
+ * ```ts
5051
+ * framer.hideUI()
5052
+ * ```
5053
+ */
5054
+ hideUI(): Promise<void>;
5055
+ /**
5056
+ * Update the background status text shown while the plugin UI is hidden.
5057
+ * This allows plugins running in the background to communicate their current
5058
+ * status to users.
5059
+ *
5060
+ * Set to `null` to clear the message.
5061
+ *
5062
+ * @param status - The message to display, or `null` to clear.
5063
+ *
5064
+ * @example
5065
+ * ```ts
5066
+ * await framer.hideUI()
5067
+ * await framer.setBackgroundMessage("Syncing data...")
5068
+ *
5069
+ * // Clear the status message
5070
+ * await framer.setBackgroundMessage(null)
5071
+ * ```
5072
+ */
5073
+ setBackgroundMessage(status: string | null): Promise<void>;
5074
+ /**
5075
+ * Close and terminate the plugin. Throws `FramerPluginClosedError`, which should be ignored.
5076
+ *
5077
+ * @param message - Optional message to show in the notification (ignored if options.silent is true)
5078
+ * @param options - Options to control the close behaviour
5079
+ *
5080
+ * @example
5081
+ * ```ts
5082
+ * await framer.closePlugin("Synchronization successful", {
5083
+ * variant: "success",
5084
+ * })
5085
+ * ```
3840
5086
  */
3841
5087
  closePlugin(message?: string, options?: ClosePluginOptions): never;
3842
- /** Get the current user info like name and id. */
5088
+ /**
5089
+ * Get information about the user that's interacting with the plugin.
5090
+ *
5091
+ * @example
5092
+ * ```ts
5093
+ * const user = await framer.getCurrentUser();
5094
+ * ```
5095
+ */
3843
5096
  getCurrentUser(): Promise<User>;
3844
5097
  /** Get the project info like name and id. */
3845
5098
  getProjectInfo(): Promise<ProjectInfo>;
@@ -3853,9 +5106,33 @@ declare class FramerPluginAPI {
3853
5106
  getCanvasRoot(): Promise<CanvasRootNode>;
3854
5107
  /** Subscribe to canvas root changes */
3855
5108
  subscribeToCanvasRoot(rootUpdate: (root: CanvasRootNode) => void): Unsubscribe$1;
3856
- /** Get the current publish info. */
5109
+ /**
5110
+ * Get information about the published website, such as the time of the most
5111
+ * recent deploy, or the URL of the current page. Provides information about
5112
+ * both `staging` and `production` environments (either may be `null` if the
5113
+ * site has never been published).
5114
+ *
5115
+ * @returns The current publish info for both staging and production.
5116
+ */
3857
5117
  getPublishInfo(): Promise<PublishInfo>;
3858
- /** Subscribe to publish info changes. */
5118
+ /**
5119
+ * Subscribe to publish info changes. The callback is called whenever
5120
+ * publish info is updated (e.g., after a new deployment).
5121
+ *
5122
+ * @param publishInfoUpdate - Called when publish info changes.
5123
+ * @returns A function to unsubscribe from updates.
5124
+ *
5125
+ * @example
5126
+ * ```ts
5127
+ * function usePublishInfo() {
5128
+ * const [publishInfo, setPublishInfo] = useState<PublishInfo>()
5129
+ * useEffect(() => {
5130
+ * return framer.subscribeToPublishInfo(setPublishInfo)
5131
+ * }, [])
5132
+ * return publishInfo
5133
+ * }
5134
+ * ```
5135
+ */
3859
5136
  subscribeToPublishInfo(publishInfoUpdate: (info: PublishInfo) => void): Unsubscribe$1;
3860
5137
  /** Create a new node on the canvas. */
3861
5138
  createFrameNode(attributes: Partial<EditableFrameNodeAttributes>, parentId?: string): Promise<FrameNode | null>;
@@ -3873,7 +5150,21 @@ declare class FramerPluginAPI {
3873
5150
  getChildren(nodeId: NodeId): Promise<CanvasNode[]>;
3874
5151
  /** Get the rect of a node */
3875
5152
  getRect(nodeId: NodeId): Promise<Rect$1 | null>;
3876
- /** Pans and zooms the viewport to center a single or group of nodes. */
5153
+ /**
5154
+ * Pans and zooms the viewport to center a single or group of nodes.
5155
+ *
5156
+ * @param nodeIds - Node ID or array of node IDs to zoom into.
5157
+ * @param options - Options like `maxZoom` and `skipIfVisible`.
5158
+ *
5159
+ * @example
5160
+ * ```ts
5161
+ * // Scroll and zoom the viewport to show a specific node.
5162
+ * await framer.zoomIntoView("node-id")
5163
+ *
5164
+ * // Scroll and zoom to fit multiple nodes into the viewport.
5165
+ * await framer.zoomIntoView(["node-id-1", "node-id-2"])
5166
+ * ```
5167
+ */
3877
5168
  zoomIntoView(nodeIds: NodeId | Iterable<NodeId>, options?: ZoomIntoViewOptions): Promise<void>;
3878
5169
  /** Set the attributes of a node. */
3879
5170
  setAttributes(nodeId: NodeId, attributes: Partial<AnyEditableAttributes>): Promise<AnyNode | null>;
@@ -3891,13 +5182,23 @@ declare class FramerPluginAPI {
3891
5182
  getNodesWithAttribute<T extends NodeAttributeKey, Node = NodeWithAttribute<T>>(attribute: T): Promise<Node[]>;
3892
5183
  /** Get all nodes with a certain attribute which value is set. */
3893
5184
  getNodesWithAttributeSet<T extends NodeAttributeKey, Node = NodeWithAttribute<T>>(attribute: T): Promise<Node[]>;
3894
- /** Get the image of the current selection or null if there is no image. */
5185
+ /**
5186
+ * Get the image of the current selection or `null` if there is no image.
5187
+ *
5188
+ * In `editImage` mode, this returns the image the user already has set,
5189
+ * which your plugin can then modify.
5190
+ */
3895
5191
  getImage(): Promise<ImageAsset | null>;
3896
5192
  /** Subscribe to single image selection changes. */
3897
5193
  subscribeToImage(imageUpdate: (image: ImageAsset | null) => void): Unsubscribe$1;
3898
5194
  /** Upload an image, and insert on the canvas. */
3899
5195
  addImage(image: NamedImageAssetInput | File): Promise<void>;
3900
- /** Upload an image, and set on the selected node. */
5196
+ /**
5197
+ * Upload an image and set it on the selected node.
5198
+ *
5199
+ * In `image` or `editImage` mode, this is the primary method to send the
5200
+ * selected or edited image back to Framer.
5201
+ */
3901
5202
  setImage(image: NamedImageAssetInput | File): Promise<void>;
3902
5203
  /** Upload an image without assigning it to a property. */
3903
5204
  uploadImage(image: NamedImageAssetInput | File): Promise<ImageAsset>;
@@ -3911,7 +5212,14 @@ declare class FramerPluginAPI {
3911
5212
  uploadFiles(files: readonly NamedFileAssetInput[]): Promise<FileAsset[]>;
3912
5213
  /** Add an SVG, replacing the selected SVG, or insert on the canvas. */
3913
5214
  addSVG(svg: SVGData): Promise<void>;
3914
- /** Add a component instance by module URL. */
5215
+ /**
5216
+ * Add a component instance by module URL.
5217
+ *
5218
+ * @param url - The component module URL. Can be copied from the components panel.
5219
+ * @param attributes - Optional component attributes.
5220
+ *
5221
+ * @returns The newly created component instance node.
5222
+ */
3915
5223
  addComponentInstance({ url, attributes, parentId, }: AddComponentInstanceOptions): Promise<ComponentInstanceNode>;
3916
5224
  /** Adds the layers of a component by module URL. */
3917
5225
  addDetachedComponentLayers({ url, layout, attributes }: AddDetachedComponentLayersOptions): Promise<FrameNode>;
@@ -3926,13 +5234,50 @@ declare class FramerPluginAPI {
3926
5234
  /** Add a new text node to the canvas. */
3927
5235
  addText(text: string, options?: AddTextOptions): Promise<void>;
3928
5236
  /**
3929
- * Set Custom HTML to be loaded in the document. A plugin can only set custom HTML once per
3930
- * location.
5237
+ * Install a custom code snippet in the user's website via `<script>` tags.
5238
+ * A plugin can only set custom HTML once per location. Custom code should be
5239
+ * valid HTML. Setting `html` to `null` clears the installed code snippet.
5240
+ *
5241
+ * @param options - The custom code options including `html` and `location`.
5242
+ *
5243
+ * @example
5244
+ * ```ts
5245
+ * framer.setCustomCode({
5246
+ * html: '<script src="https://example.com/script.js"></script>',
5247
+ * location: "bodyEnd"
5248
+ * })
5249
+ * ```
3931
5250
  */
3932
5251
  setCustomCode(options: SetCustomCodeOptions): Promise<void>;
3933
- /** Get custom HTML settings set by the plugin. */
5252
+ /**
5253
+ * Get custom code settings set by the plugin. Your plugin can detect if
5254
+ * custom code was set and whether the user has disabled it.
5255
+ *
5256
+ * @example
5257
+ * ```ts
5258
+ * const customCode = await framer.getCustomCode()
5259
+ * if (customCode.bodyStart.disabled) {
5260
+ * // Custom code was disabled by the user in settings
5261
+ * }
5262
+ * ```
5263
+ */
3934
5264
  getCustomCode(): Promise<CustomCode>;
3935
- /** Subscribe to custom HTML changes set by the plugin. */
5265
+ /**
5266
+ * Subscribe to custom code changes. Called when custom code is registered
5267
+ * or when changes to the settings are made.
5268
+ *
5269
+ * @param callback - Called when custom code settings change.
5270
+ * @returns A function to unsubscribe from updates.
5271
+ *
5272
+ * @example
5273
+ * ```ts
5274
+ * function useCustomCode() {
5275
+ * const [customCode, setCustomCode] = useState<CustomCode | null>(null)
5276
+ * useEffect(() => framer.subscribeToCustomCode(setCustomCode), [])
5277
+ * return customCode
5278
+ * }
5279
+ * ```
5280
+ */
3936
5281
  subscribeToCustomCode(callback: (customHTML: CustomCode) => void): Unsubscribe$1;
3937
5282
  /** Subscribe to the current text selection. */
3938
5283
  subscribeToText(callback: (text: string | null) => void): Unsubscribe$1;
@@ -3942,23 +5287,75 @@ declare class FramerPluginAPI {
3942
5287
  * all of the added listeners.
3943
5288
  */
3944
5289
  makeDraggable(element: HTMLElement, getDragData: () => DragData, onDragComplete?: DragCompleteCallback): Cleanup;
3945
- /** Get the managed collection that is currently active and selected in the UI. */
5290
+ /**
5291
+ * Retrieve the currently active managed Collection from the UI.
5292
+ *
5293
+ * - Only applies when the Plugin is operating in a mode that supports managed Collections.
5294
+ *
5295
+ * @example
5296
+ * ```ts
5297
+ * const collection = await framer.getActiveManagedCollection();
5298
+ * ```
5299
+ */
3946
5300
  getActiveManagedCollection(): Promise<ManagedCollection>;
3947
5301
  /** @deprecated Use `getActiveManagedCollection` */
3948
5302
  getManagedCollection(): Promise<ManagedCollection>;
3949
- /** Get all collections managed by your plugin. */
5303
+ /**
5304
+ * Retrieve Collections that are managed by the current Plugin.
5305
+ *
5306
+ * - Only Collections created or controlled by your Plugin appear in this list.
5307
+ * - These Collections can be modified without the restrictions placed on user-created Collections.
5308
+ *
5309
+ * @example
5310
+ * ```ts
5311
+ * const managedCollections = await framer.getManagedCollections();
5312
+ * ```
5313
+ */
3950
5314
  getManagedCollections(): Promise<ManagedCollection[]>;
3951
5315
  /** Get a collection by its id. */
3952
5316
  getCollection(id: NodeId): Promise<Collection | null>;
3953
- /** Get the collection that is currently selected in the UI. */
5317
+ /**
5318
+ * Retrieve the Collection currently active (selected) in the Framer UI.
5319
+ *
5320
+ * - If the active Collection is managed by a Plugin, you may want to use `getActiveManagedCollection()` instead.
5321
+ * - The selection may change if the user interacts with the UI.
5322
+ *
5323
+ * @returns The active Collection or `null` if none is selected.
5324
+ *
5325
+ * @example
5326
+ * ```ts
5327
+ * const collection = await framer.getActiveCollection();
5328
+ * ```
5329
+ */
3954
5330
  getActiveCollection(): Promise<Collection | null>;
3955
5331
  /**
3956
- * Get all collections in the project. This includes collections created by the user or a
3957
- * plugin.
5332
+ * Get all Collections in the project, both managed and unmanaged.
5333
+ *
5334
+ * @example
5335
+ * ```ts
5336
+ * const collections = await framer.getCollections()
5337
+ * ```
3958
5338
  */
3959
5339
  getCollections(): Promise<Collection[]>;
3960
5340
  /**
3961
5341
  * Display a notification message. The message will be truncated if longer than 120 characters.
5342
+ *
5343
+ * @param message - The message to display. Truncated if longer than 120 characters.
5344
+ * @param options - Options like `variant` (`"info"`, `"success"`, `"warning"`, `"error"`), `durationMs`, `button`, and `onDisappear`.
5345
+ *
5346
+ * @returns A Notification handle that can be used to close the notification programmatically.
5347
+ *
5348
+ * @example
5349
+ * ```ts
5350
+ * const notification = framer.notify("An action was completed", {
5351
+ * button: { text: "Undo", onClick: handleUndo },
5352
+ * durationMs: 3000,
5353
+ * variant: "info",
5354
+ * })
5355
+ *
5356
+ * // Close the notification programmatically
5357
+ * notification.close()
5358
+ * ```
3962
5359
  */
3963
5360
  notify: Notify;
3964
5361
  /** Get plugin data by key. */
@@ -3983,43 +5380,226 @@ declare class FramerPluginAPI {
3983
5380
  createTextStyle(attributes: TextStyleAttributes): Promise<TextStyle>;
3984
5381
  /** Fired when a text style is added, edited or removed. */
3985
5382
  subscribeToTextStyles(callback: (styles: TextStyle[]) => void): Unsubscribe$1;
3986
- /** Get a specific font via it's family name, and optionally weight and style. */
5383
+ /**
5384
+ * Get a specific font from a family by name. This is not case sensitive.
5385
+ * By default, returns a font with normal weight and style. Returns `null`
5386
+ * if the font does not exist or lacks the requested weight/style combination.
5387
+ *
5388
+ * Note: Custom fonts are not available to plugins.
5389
+ *
5390
+ * @param family - The font family name (e.g., `"Noto Sans"`).
5391
+ * @param attributes - Optional weight and style attributes.
5392
+ * @returns The matched font or `null` if not found.
5393
+ *
5394
+ * @example
5395
+ * ```ts
5396
+ * // Get Noto Sans with default weight (400) and normal style
5397
+ * const font = await framer.getFont("Noto Sans")
5398
+ *
5399
+ * // Get Noto Sans with a specific weight and style
5400
+ * const font = await framer.getFont("Noto Sans", {
5401
+ * weight: 800,
5402
+ * style: "italic"
5403
+ * })
5404
+ * ```
5405
+ */
3987
5406
  getFont(family: string, attributes?: FontAttributes): Promise<Font | null>;
3988
- /** Get all available fonts. */
5407
+ /**
5408
+ * Get all available fonts. Unlike the Font Picker which groups fonts by
5409
+ * typeface, this lists individual fonts for each weight and style (each
5410
+ * representing a separate font file).
5411
+ *
5412
+ * Note: Custom fonts are not available to plugins.
5413
+ *
5414
+ * @returns An array of all available fonts.
5415
+ *
5416
+ * @example
5417
+ * ```ts
5418
+ * const fonts = await framer.getFonts()
5419
+ * ```
5420
+ */
3989
5421
  getFonts(): Promise<Font[]>;
3990
- /** Get all locales in the current Project */
5422
+ /**
5423
+ * Get all Locales in the project.
5424
+ *
5425
+ * Does not include the default Locale. See `getDefaultLocale`.
5426
+ *
5427
+ * @example
5428
+ * ```ts
5429
+ * const locales = await framer.getLocales()
5430
+ * ```
5431
+ */
3991
5432
  getLocales(): Promise<readonly Locale[]>;
3992
- /** Get the default locale of the current Project */
5433
+ /**
5434
+ * Get the default locale of the project.
5435
+ *
5436
+ * @example
5437
+ * ```ts
5438
+ * const defaultLocale = await framer.getDefaultLocale()
5439
+ * ```
5440
+ */
3993
5441
  getDefaultLocale(): Promise<Locale>;
3994
5442
  /**
3995
5443
  * Get the currently active locale.
3996
5444
  *
3997
5445
  * - In "localization" mode, the active locale is the locale selected in the Localizations panel.
3998
5446
  * - In "canvas" mode, the active locale is the locale selected in the toolbar.
3999
- * - Otherwise, the active locale is null.
5447
+ * - Otherwise, the active locale is `null`.
5448
+ *
5449
+ * @example
5450
+ * ```ts
5451
+ * const activeLocale = await framer.getActiveLocale()
5452
+ * ```
4000
5453
  */
4001
5454
  getActiveLocale(): Promise<Locale | null>;
4002
- /** Get all localization groups in the current Project */
5455
+ /**
5456
+ * Get all Localization Groups in the project.
5457
+ *
5458
+ * @example
5459
+ * ```ts
5460
+ * const groups = await framer.getLocalizationGroups()
5461
+ *
5462
+ * for (const group of groups) {
5463
+ * console.log(`Group: ${group.name}`)
5464
+ *
5465
+ * for (const source of group.sources) {
5466
+ * console.log(`Source: ${source.value}`)
5467
+ * }
5468
+ * }
5469
+ * ```
5470
+ */
4003
5471
  getLocalizationGroups(): Promise<readonly LocalizationGroup[]>;
4004
- /** Update localization data */
5472
+ /**
5473
+ * Update localization data.
5474
+ *
5475
+ * @param update - An object representing the localization update.
5476
+ *
5477
+ * @example
5478
+ * ```ts
5479
+ * await framer.setLocalizationData({
5480
+ * valuesBySource: {
5481
+ * [titleSourceId]: {
5482
+ * [dutchLocaleId]: { action: "set", value: "Hallo Wereld" }
5483
+ * }
5484
+ * },
5485
+ * statusByLocaleByGroup: {
5486
+ * [blogPostGroupId]: {
5487
+ * [dutchLocaleId]: "ready",
5488
+ * [frenchLocaleId]: "excluded"
5489
+ * }
5490
+ * }
5491
+ * })
5492
+ * ```
5493
+ */
4005
5494
  setLocalizationData(update: LocalizationData): Promise<SetLocalizationDataResult>;
4006
- /** Get all redirects in the project */
5495
+ /**
5496
+ * Get all Redirects in the project.
5497
+ *
5498
+ * @returns All of the Redirects in the project.
5499
+ *
5500
+ * @example
5501
+ * ```ts
5502
+ * const redirects = await framer.getRedirects()
5503
+ * ```
5504
+ */
4007
5505
  getRedirects(): Promise<readonly Redirect[]>;
4008
- /** Add new redirects or update existing ones if their IDs match */
5506
+ /** Subscribe to redirect changes. */
4009
5507
  subscribeToRedirects(callback: (redirects: Redirect[]) => void): Unsubscribe$1;
4010
- /** Add new redirects or update existing ones if their IDs match */
5508
+ /**
5509
+ * Add new redirects or update existing ones if their IDs match
5510
+ *
5511
+ * `from` paths can contain wildcards (`*`) which match any string, and
5512
+ * captured groups can be referenced in the `to` path using `:1`, `:2`,
5513
+ * etc.
5514
+ *
5515
+ * Throws a `FramerPluginError` when the user lacks Site Settings permissions,
5516
+ * when the project plan does not include Redirects, or when the maximum
5517
+ * redirect count (2500) is reached.
5518
+ *
5519
+ * @param redirects - An array of redirect objects to add.
5520
+ * @returns The added Redirects.
5521
+ *
5522
+ * @example
5523
+ * ```ts
5524
+ * await framer.addRedirects([
5525
+ * { from: "/business", to: "/enterprise", expandToAllLocales: true },
5526
+ * { from: "/posts/*", to: "/blog/:1", expandToAllLocales: false },
5527
+ * ])
5528
+ * ```
5529
+ */
4011
5530
  addRedirects(redirects: RedirectInput[]): Promise<Redirect[]>;
4012
- /** Remove a redirect from the project */
5531
+ /**
5532
+ * Remove Redirects from the project. Unknown Redirect IDs are ignored.
5533
+ *
5534
+ * Throws a `FramerPluginError` when the user lacks Site Settings permissions
5535
+ * or when the project plan does not include Redirects.
5536
+ *
5537
+ * @param redirectIds - An array of Redirect IDs to remove.
5538
+ *
5539
+ * @example
5540
+ * ```ts
5541
+ * await framer.removeRedirects([aboutPageRedirect.id, blogPageRedirect.id])
5542
+ * ```
5543
+ */
4013
5544
  removeRedirects(redirectIds: string[]): Promise<void>;
4014
- /** Set the order of redirects */
5545
+ /**
5546
+ * Set the order of Redirects in the list. Unknown Redirect IDs are ignored.
5547
+ *
5548
+ * Throws a `FramerPluginError` when the user lacks Site Settings permissions
5549
+ * or when the project plan does not include Redirects.
5550
+ *
5551
+ * @param redirectIds - An array of Redirect IDs representing the desired order.
5552
+ *
5553
+ * @example
5554
+ * ```ts
5555
+ * await framer.setRedirectOrder([aboutPageRedirect.id, blogPageRedirect.id])
5556
+ * ```
5557
+ */
4015
5558
  setRedirectOrder(redirectIds: string[]): Promise<void>;
4016
- /** Create a new code file */
5559
+ /**
5560
+ * Create a new code file in the project.
5561
+ *
5562
+ * @param name - The name of the code file (including extension).
5563
+ * @param code - The initial content of the code file.
5564
+ * @param options - Optional settings. `editViaPlugin`: when `true`, the "Edit Code" UI action will open the plugin which created the code file.
5565
+ * @returns The newly created code file instance.
5566
+ *
5567
+ * @example
5568
+ * ```ts
5569
+ * const newFile = await framer.createCodeFile(
5570
+ * "MyComponent",
5571
+ * `export default function MyComponent() {
5572
+ * return <div>Hello World</div>
5573
+ * }`
5574
+ * )
5575
+ * ```
5576
+ */
4017
5577
  createCodeFile(name: string, code: string, options?: {
4018
5578
  editViaPlugin?: boolean;
4019
5579
  }): Promise<CodeFile>;
4020
- /** Get an array of all code files */
5580
+ /**
5581
+ * Get all code files in the project.
5582
+ *
5583
+ * @returns An array of all CodeFile instances.
5584
+ *
5585
+ * @example
5586
+ * ```ts
5587
+ * const allFiles = await framer.getCodeFiles()
5588
+ * console.log(`Project has ${allFiles.length} code files`)
5589
+ * ```
5590
+ */
4021
5591
  getCodeFiles(): Promise<readonly CodeFile[]>;
4022
- /** Get a specific code file */
5592
+ /**
5593
+ * Get a specific code file by its ID.
5594
+ *
5595
+ * @param id - The unique identifier of the code file.
5596
+ * @returns The CodeFile instance or `null` if not found.
5597
+ *
5598
+ * @example
5599
+ * ```ts
5600
+ * const codeFile = await framer.getCodeFile("code-file-id")
5601
+ * ```
5602
+ */
4023
5603
  getCodeFile(id: string): Promise<CodeFile | null>;
4024
5604
  /**
4025
5605
  * Lint a code file and return the diagnostics.
@@ -4041,17 +5621,77 @@ declare class FramerPluginAPI {
4041
5621
  */
4042
5622
  typecheckCode(fileName: string, content: string, compilerOptions?: ts.server.protocol.CompilerOptions, sessionId?: string): Promise<TypecheckDiagnostic[]>;
4043
5623
  /**
4044
- * Subscribe to changes in code files.
4045
- * This will be called when code files are added, removed, or updated and will return an array of
4046
- * all code files in the project.
5624
+ * Subscribe to changes in code files across the project. The callback is
5625
+ * called when code files are added, removed, or updated, and receives an
5626
+ * array of all code files in the project.
5627
+ *
5628
+ * @param callback - Function called when code files change.
5629
+ * @returns A function to stop listening to changes.
5630
+ *
5631
+ * @example
5632
+ * ```ts
5633
+ * const unsubscribe = framer.subscribeToCodeFiles((codeFiles) => {
5634
+ * console.log(`Code files updated: ${codeFiles.length} total files`)
5635
+ * })
5636
+ *
5637
+ * // Later, stop listening
5638
+ * unsubscribe()
5639
+ * ```
4047
5640
  */
4048
5641
  subscribeToCodeFiles(callback: (codeFiles: readonly CodeFile[]) => void): Unsubscribe$1;
4049
5642
  /**
4050
5643
  * Set the plugin's menu, which is shown in the plugin window header.
5644
+ *
5645
+ * @param items - The entries to add to the menu.
5646
+ *
5647
+ * @example
5648
+ * ```ts
5649
+ * await framer.setMenu([
5650
+ * {
5651
+ * label: "New",
5652
+ * onAction: newFile,
5653
+ * },
5654
+ * {
5655
+ * type: "separator",
5656
+ * },
5657
+ * {
5658
+ * label: "Log Out",
5659
+ * onAction: logOut,
5660
+ * },
5661
+ * ])
5662
+ * ```
4051
5663
  */
4052
5664
  setMenu(menuItems: MenuItem[]): Promise<void>;
4053
5665
  /**
4054
5666
  * Show a context menu at the given location.
5667
+ *
5668
+ * Placement is relative to the location.
5669
+ *
5670
+ * @param menuItems - The entries to add to the context menu.
5671
+ * @param config - Configuration for positioning the context menu.
5672
+ *
5673
+ * @example
5674
+ * ```ts
5675
+ * await framer.showContextMenu(
5676
+ * [
5677
+ * {
5678
+ * label: "Edit",
5679
+ * enabled: item.isEditable,
5680
+ * onAction: () => editItem(item)
5681
+ * },
5682
+ * { type: "separator" },
5683
+ * {
5684
+ * label: "Remove",
5685
+ * onAction: () => removeItem(item),
5686
+ * },
5687
+ * ],
5688
+ * {
5689
+ * location: { x: event.clientX, y: event.clientY },
5690
+ * placement: "bottom-left",
5691
+ * width: 220,
5692
+ * }
5693
+ * )
5694
+ * ```
4055
5695
  */
4056
5696
  showContextMenu(menuItems: MenuItem[], config: ContextMenuConfig): Promise<void>;
4057
5697
  /**
@@ -4062,18 +5702,37 @@ declare class FramerPluginAPI {
4062
5702
  */
4063
5703
  unstable_ensureMinimumDependencyVersion(packageName: string, version: string): Promise<void>;
4064
5704
  /**
4065
- * Navigate to a node by ID with optional selection and zoom behaviour.
5705
+ * Navigate the Framer UI to a target by its ID. When the target isn't in the
5706
+ * current mode, it might terminate or restart the plugin in the new mode.
4066
5707
  *
4067
5708
  * @param nodeId - The ID of the node to navigate to.
4068
5709
  * @param opts - The options for the navigation.
4069
5710
  * @returns A promise that resolves when the navigation is complete.
5711
+ *
5712
+ * @example
5713
+ * ```ts
5714
+ * await framer.navigateTo(nodeId, opts)
5715
+ * ```
4070
5716
  */
4071
5717
  navigateTo(nodeId: string, opts?: NavigableOptions): Promise<void>;
4072
5718
  /**
4073
- * Subscribe to the currently open code file in the Code Editor.
5719
+ * Subscribe to changes in the Code Editor's active file. This function is
5720
+ * primarily useful when the plugin's mode is `"code"`.
5721
+ *
5722
+ * @param callback - Function called when the active code file changes.
5723
+ * @returns A function to stop listening to changes.
5724
+ *
5725
+ * @example
5726
+ * ```ts
5727
+ * const unsubscribe = framer.subscribeToOpenCodeFile((codeFile) => {
5728
+ * if (codeFile) {
5729
+ * console.log(`Currently open code file: ${codeFile.id}`)
5730
+ * }
5731
+ * })
4074
5732
  *
4075
- * @param callback - The callback to call when the code file changes.
4076
- * @returns A function to unsubscribe from the subscription.
5733
+ * // Later, stop listening
5734
+ * unsubscribe()
5735
+ * ```
4077
5736
  */
4078
5737
  subscribeToOpenCodeFile(callback: (codeFile: CodeFile | null) => void): Unsubscribe$1;
4079
5738
  /**
@@ -4081,6 +5740,8 @@ declare class FramerPluginAPI {
4081
5740
  *
4082
5741
  * If you want to open the newly created design page, you can `.navigateTo()` the page after creation.
4083
5742
  *
5743
+ * @param pageName - The name for the new design page.
5744
+ *
4084
5745
  * @example
4085
5746
  * ```ts
4086
5747
  * const designPage = await framer.createDesignPage("About")
@@ -4093,6 +5754,8 @@ declare class FramerPluginAPI {
4093
5754
  *
4094
5755
  * If you want to open the newly created web page, you can `.navigateTo()` the page after creation.
4095
5756
  *
5757
+ * @param pagePath - The path for the new web page (e.g., "/about").
5758
+ *
4096
5759
  * @example
4097
5760
  * ```ts
4098
5761
  * const webPage = await framer.createWebPage("/about")
@@ -4102,17 +5765,39 @@ declare class FramerPluginAPI {
4102
5765
  createWebPage(pagePath: string): Promise<WebPageNode>;
4103
5766
  /**
4104
5767
  * Create a new collection.
5768
+ *
5769
+ * @param name - The name to give the new collection.
4105
5770
  */
4106
5771
  createCollection(name: string): Promise<Collection>;
4107
5772
  /**
4108
- * Create a new managed collection.
5773
+ * Add a new plugin-managed CMS Collection.
5774
+ *
5775
+ * If a name is provided which matches an existing Collection, the promise will reject.
5776
+ *
5777
+ * @param name - The name to give the new collection.
5778
+ *
5779
+ * @example
5780
+ * ```ts
5781
+ * const newCollection = await framer.createManagedCollection(name)
5782
+ * ```
4109
5783
  */
4110
5784
  createManagedCollection(name: string): Promise<ManagedCollection>;
4111
5785
  /**
4112
- * Set a warning message to show when the user attempts to close the plugin. Set to false to disable.
4113
- * - `string` to enable with a custom message.
4114
- * - `false` to disable.
4115
- * */
5786
+ * When enabled, a modal confirmation will appear before close to confirm the action.
5787
+ *
5788
+ * Pass `false` to disable the warning.
5789
+ *
5790
+ * @param message - The message to show when attempting to close the plugin. `false` disables the warning.
5791
+ *
5792
+ * @example
5793
+ * ```ts
5794
+ * // Show a close warning when the user attempts to close the plugin
5795
+ * await framer.setCloseWarning("Are you sure?")
5796
+ *
5797
+ * // Remove the close warning
5798
+ * await framer.setCloseWarning(false)
5799
+ * ```
5800
+ */
4116
5801
  setCloseWarning(message: string | false): Promise<void>;
4117
5802
  /**
4118
5803
  * Initial state data passed from Vekter during handshake.
@@ -4172,6 +5857,36 @@ declare class FramerPluginAPIAlpha extends FramerPluginAPIBeta {
4172
5857
  * @alpha
4173
5858
  */
4174
5859
  getVectorSets(): Promise<VectorSet[]>;
5860
+ /**
5861
+ * Create a new locale in the project.
5862
+ *
5863
+ * @alpha
5864
+ * @param input - The locale configuration, use `getLocaleLanguages` and `getLocaleRegions` to get valid language and region codes.
5865
+ * @returns The created locale.
5866
+ */
5867
+ createLocale(input: CreateLocaleInput): Promise<Locale>;
5868
+ /**
5869
+ * Get all available locale languages.
5870
+ *
5871
+ * @alpha
5872
+ * @returns A list of language codes and their display names, sorted by name.
5873
+ */
5874
+ getLocaleLanguages(): Promise<{
5875
+ code: string;
5876
+ name: string;
5877
+ }[]>;
5878
+ /**
5879
+ * Get all available locale regions for a given language.
5880
+ *
5881
+ * @alpha
5882
+ * @param languageCode - The language code to get regions for. Use `getLocaleLanguages` to get valid language codes.
5883
+ * @returns A list of region codes, their display names, and whether they are commonly paired with the given language.
5884
+ */
5885
+ getLocaleRegions(languageCode: string): Promise<{
5886
+ code: string;
5887
+ name: string;
5888
+ isCommon: boolean;
5889
+ }[]>;
4175
5890
  /** @internal - Available only through framer-api */
4176
5891
  [$framerApiOnly.publish](): Promise<PublishResult>;
4177
5892
  /** @internal - Available only through framer-api */
@@ -4290,6 +6005,19 @@ interface PluginMessageAPI {
4290
6005
  getActiveLocale: FramerPluginAPI["getActiveLocale"];
4291
6006
  getLocalizationGroups: FramerPluginAPI["getLocalizationGroups"];
4292
6007
  setLocalizationData: FramerPluginAPI["setLocalizationData"];
6008
+ /** @alpha */
6009
+ createLocale: (input: CreateLocaleInput) => Promise<Locale>;
6010
+ /** @alpha */
6011
+ getLocaleLanguages: () => Promise<{
6012
+ code: string;
6013
+ name: string;
6014
+ }[]>;
6015
+ /** @alpha */
6016
+ getLocaleRegions: (language: string) => Promise<{
6017
+ code: string;
6018
+ name: string;
6019
+ isCommon: boolean;
6020
+ }[]>;
4293
6021
  unstable_ensureMinimumDependencyVersion: FramerPluginAPI["unstable_ensureMinimumDependencyVersion"];
4294
6022
  showUI: (options?: UIOptions) => Promise<void>;
4295
6023
  notify: (message: string, options: NotifyOptionsData) => Promise<NotificationCloseReason>;
@@ -4581,6 +6309,7 @@ declare const fileAssetDiscriminator: "FileAsset";
4581
6309
  interface FileAssetData extends AssetIdentifier, FileAssetDataFields {
4582
6310
  [classKey]: typeof fileAssetDiscriminator;
4583
6311
  }
6312
+ /** A file asset uploaded to the Framer project. */
4584
6313
  declare class FileAsset implements AssetIdentifier, FileAssetDataFields {
4585
6314
  readonly id: AssetId;
4586
6315
  readonly url: string;
@@ -4620,6 +6349,10 @@ interface Size {
4620
6349
  */
4621
6350
  height: number;
4622
6351
  }
6352
+ /**
6353
+ * An image that has been uploaded to the Framer project. Provides methods
6354
+ * to access image data, measure dimensions, and load as bitmap or HTML element.
6355
+ */
4623
6356
  declare class ImageAsset implements ImageDataFields, AssetIdentifier {
4624
6357
  #private;
4625
6358
  readonly id: AssetId;
@@ -4631,11 +6364,14 @@ declare class ImageAsset implements ImageDataFields, AssetIdentifier {
4631
6364
  static [$framerInternal.unmarshal](engine: PluginEngine, data: ImageAssetData): ImageAsset;
4632
6365
  [$framerInternal.marshal](): ImageAssetData;
4633
6366
  /**
4634
- * Clone this image, optionally overriding its attributes.
6367
+ * Clone this image asset, optionally overriding `altText` or `resolution`.
6368
+ * The clone shares the same underlying image data.
4635
6369
  */
4636
6370
  cloneWithAttributes({ altText, resolution, }: Prettify<Partial<Pick<ImageAssetData, "altText" | "resolution">>>): ImageAsset;
4637
6371
  /**
4638
- * Measure this image.
6372
+ * Measure this image's natural dimensions.
6373
+ *
6374
+ * @returns The width and height in pixels. Warning: values may be zero.
4639
6375
  */
4640
6376
  measure(): Promise<Size>;
4641
6377
  /**
@@ -4781,6 +6517,9 @@ declare const enabledMethods: {
4781
6517
  getDefaultLocale: true;
4782
6518
  getLocalizationGroups: true;
4783
6519
  setLocalizationData: true;
6520
+ createLocale: true;
6521
+ getLocaleLanguages: true;
6522
+ getLocaleRegions: true;
4784
6523
  getCurrentUser: true;
4785
6524
  getProjectInfo: true;
4786
6525
  setSelection: true;