From 723f77d225e7980562307b9d9c41834ca268daaa Mon Sep 17 00:00:00 2001 From: Tim McMackin Date: Wed, 18 Mar 2026 11:39:15 -0400 Subject: [PATCH] [DEVREL-2687, DEVREL-2688]: Get component variants --- src/components/PermissionsMap.tsx | 2 + src/designer-extension-typings/api.d.ts | 1 + .../components.d.ts | 45 +++++++++++++++++++ src/examples/components.ts | 27 +++++++++++ 4 files changed, 75 insertions(+) diff --git a/src/components/PermissionsMap.tsx b/src/components/PermissionsMap.tsx index 837beba..a784482 100644 --- a/src/components/PermissionsMap.tsx +++ b/src/components/PermissionsMap.tsx @@ -51,6 +51,8 @@ export const permissionsMap: PermissionsMap = { registerComponent: { permissions: ['canCreateComponents'] }, unregisterComponent: { permissions: ['canCreateComponents'] }, getAllComponents: { permissions: ['canAccessCanvas'] }, + getVariants: { permissions: ['canAccessCanvas'] }, + getSelectedVariant: { permissions: ['canAccessCanvas'] }, enterComponent: { permissions: ['canModifyComponents'] }, exitComponent: { permissions: ['canAccessCanvas'] }, }, diff --git a/src/designer-extension-typings/api.d.ts b/src/designer-extension-typings/api.d.ts index 0e1c2ce..a4ff81f 100644 --- a/src/designer-extension-typings/api.d.ts +++ b/src/designer-extension-typings/api.d.ts @@ -138,6 +138,7 @@ interface WebflowApi { name: string, root: AnyElement | ElementPreset | Component ): Promise; + getComponentByName(string): Promise; /** * Delete a component from the Designer. If there are any instances of the Component within the site, they will * be converted to regular Elements. diff --git a/src/designer-extension-typings/components.d.ts b/src/designer-extension-typings/components.d.ts index ffd5917..1d047df 100644 --- a/src/designer-extension-typings/components.d.ts +++ b/src/designer-extension-typings/components.d.ts @@ -31,7 +31,52 @@ interface Component { * ``` */ setName(name: string): Promise; + /** + * Retrieve all variants of a component. + * @returns A Promise resolving to an array containing all variants of the component + * @example + * ```ts + * const component = (await webflow.getAllComponents())[0]; + * const variants = await component.getVariants(); + * console.log(variants); + * // [ + * // { id: 'base', name: 'Primary', isSelected: true }, + * // { id: 'xxxx', name: 'Secondary', isSelected: false }, + * // ] + * // Find which variant the user is currently editing + * const activeVariant = variants.find(v => v.isSelected); + * console.log(`Currently editing: ${activeVariant.name}`); + * ``` + */ + getVariants(): Promise>; + /** + * Retrieves the selected variant of a component. + * @returns A Promise resolving to a variant + * @example + * ```ts + * const selectedVariant = await heroComponent.getSelectedVariant(); + * // { + * // id: 'variant-123', + * // name: 'Secondary Hero', + * // isSelected: true, + * // } + * // // When no variant is explicitly selected, returns base + * // const base = await heroComponent.getSelectedVariant(); + * // { + * // id: 'base', + * // name: 'Primary', + * // isSelected: true, + * // } + * ``` + */ + getSelectedVariant(): Promise; getRootElement(): Promise; } type ComponentId = string; + +interface Variant { + id: string; + name: string; + isSelected: boolean; +} diff --git a/src/examples/components.ts b/src/examples/components.ts index 6a64903..3d3bbdf 100644 --- a/src/examples/components.ts +++ b/src/examples/components.ts @@ -52,6 +52,33 @@ export const Components = { } }, + getVariants: async () => { + const component = (await webflow.getAllComponents())[0] + const variants = await component.getVariants() + console.log(variants) + // [ + // { id: 'base', name: 'Primary', isSelected: true }, + // { id: 'xxxx', name: 'Secondary', isSelected: false }, + // ] + // Find which variant the user is currently editing + const activeVariant = variants.find(v => v.isSelected) + console.log(`Currently editing: ${activeVariant?.name}`) + }, + + getSelectedVariant: async () => { + const heroComponent = webflow.getComponentByName('hero') + // When no variant is explicitly selected, returns base + const base = await heroComponent.getSelectedVariant() + console.log(JSON.stringify(base)) + /* + { + id: 'base', + name: 'Primary', + isSelected: true, + } + */ + }, + createComponent: async () => { // Get selected element const rootElement = await webflow.getSelectedElement()