diff --git a/src/examples/assets.ts b/src/examples/assets.ts index 43992d3..3e25083 100644 --- a/src/examples/assets.ts +++ b/src/examples/assets.ts @@ -116,173 +116,196 @@ export enum ValidFileTypesEnum { } export const Assets = { - getAllAssets: async () => { - // Get all assets - const assets = await webflow.getAllAssets() + // Asset Management + assetManagement: { + getAllAssets: async () => { + // Get all assets + const assets = await webflow.getAllAssets() - // Loop to list assets in the console - for (const asset of assets) { - const name = await asset.getName() - const mimeType = await asset.getMimeType() - console.log(name, mimeType) - } - }, - getAssetName: async () => { - // Get Selected Element - const el = await webflow.getSelectedElement() - - // Check if element is selected and its type - if (!el || el.type !== 'Image') { - console.error('Please select an Image element on the canvas') - await webflow.notify({ - type: 'Error', - message: 'Please select an Image element on the canvas', - }) - } else { - const asset = await el.getAsset() // Get Asset - const assetName = await asset?.getName() // Get Asset Name - console.log(`Asset Name: ${assetName}`) - } + // Loop to list assets in the console + for (const asset of assets) { + const name = await asset.getName() + const mimeType = await asset.getMimeType() + console.log(name, mimeType) + } + }, + + getAssetById: async (asset_id: string) => { + const asset = await webflow.getAssetById(asset_id) + console.log('check') + console.log(asset) + }, + + getAssetName: async () => { + // Get Selected Element + const el = await webflow.getSelectedElement() + + // Check if element is selected and its type + if (!el || el.type !== 'Image') { + console.error('Please select an Image element on the canvas') + await webflow.notify({ + type: 'Error', + message: 'Please select an Image element on the canvas', + }) + } else { + const asset = await el.getAsset() // Get Asset + const assetName = await asset?.getName() // Get Asset Name + console.log(`Asset Name: ${assetName}`) + } + }, + + getAssetMimeType: async () => { + // Get Selected Element + const el = await webflow.getSelectedElement() + + // Check if element is selected and its type + if (!el || el.type !== 'Image') { + console.error('Please select an Image element on the canvas') + await webflow.notify({ + type: 'Error', + message: 'Please select an Image element on the canvas', + }) + } else { + const asset = await el.getAsset() // Get Asset + const assetMimeType = await asset?.getMimeType() // Get Asset MIME Type + console.log(`Asset MIME type: ${assetMimeType}`) + } + }, + + getAssetURL: async (assetId: string) => { + // Get Asset by ID + const asset = await webflow.getAssetById(assetId) + console.log(asset) + + if (asset) { + // Get asset URL + const url = await asset.getUrl() + console.log(`Asset URL: ${url}`) + } + }, }, - getAssetMimeType: async () => { - // Get Selected Element - const el = await webflow.getSelectedElement() + // Asset Creation + assetCreation: { + createAssetFromFileUpload: async (file: File) => { + if (file) { + const asset = await webflow.createAsset(file) + + console.log(`Asset ID: ${asset.id}`) + } + }, - // Check if element is selected and its type - if (!el || el.type !== 'Image') { - console.error('Please select an Image element on the canvas') - await webflow.notify({ - type: 'Error', - message: 'Please select an Image element on the canvas', + createAssetFromURL: async ( + url: string, + fileName: string, + fileTypeEnum: ValidFileTypesEnum, + ) => { + // Fetch image from remote source and build a Blob object + const response = await fetch(url) + const blob = await response.blob() + const file = new File([blob], fileName, { + type: fileTypeEnum, }) - } else { - const asset = await el.getAsset() // Get Asset - const assetMimeType = await asset?.getMimeType() // Get Asset MIME Type - console.log(`Asset MIME type: ${assetMimeType}`) - } - }, - createAssetFromFileUpload: async (file: File) => { - if (file) { - const asset = await webflow.createAsset(file) - console.log(`Asset ID: ${asset.id}`) - } + console.log('file', file) + + try { + // Create and upload the asset to webflow + const asset = await webflow.createAsset(file) + console.log(asset) + } catch (err) { + const error = err as { cause: { tag: string }; message: string } + console.error(`Cause:${error.cause.tag}`) + console.error(`Cause:${error.message}`) + } + }, }, - createAssetFromURL: async ( - url: string, - fileName: string, - fileTypeEnum: ValidFileTypesEnum, - ) => { - // Fetch image from remote source and buil a Blob object - const response = await fetch(url) - const blob = await response.blob() - const file = new File([blob], fileName, { - type: fileTypeEnum, - }) - - console.log('file', file) - - try { - // Create and upload the asset to webflow - const asset = await webflow.createAsset(file) + + // Alt Text + altText: { + getAltText: async (asset: Asset) => { + // Now asset is the actual Asset object, not wrapped + if (asset) { + // Get asset alt text + const altText = await asset.getAltText() + console.log(`Asset Alt Text: ${altText}`) + } + }, + + setAltText: async (assetId: string, altText: string) => { + // Get Asset by ID + const asset = await webflow.getAssetById(assetId) console.log(asset) - } catch (err) { - const error = err as { cause: { tag: string }; message: string } - console.error(`Cause:${error.cause.tag}`) - console.error(`Cause:${error.message}`) - } - }, - getAssetById: async (asset_id: string) => { - const asset = await webflow.getAssetById(asset_id) - console.log('check') - console.log(asset) - }, - getAssetURL: async (assetId: string) => { - // Get Asset by ID - const asset = await webflow.getAssetById(assetId) - console.log(asset) - - if (asset) { - // Get asset URL - const url = await asset.getUrl() - console.log(`Asset URL: ${url}`) - } - }, - getAltText: async (asset: Asset) => { - // Now asset is the actual Asset object, not wrapped - if (asset) { - // Get asset alt text - const altText = await asset.getAltText() - console.log(`Asset Alt Text: ${altText}`) - } - }, - setAltText: async (assetId: string, altText: string) => { - // Get Asset by ID - const asset = await webflow.getAssetById(assetId) - console.log(asset) - - if (asset) { - // Get asset URL - const originalAltText = await asset.getAltText() - await asset.setAltText(altText) - const newAltText = await asset.getAltText() - console.log(`Original Asset Alt Text: ${originalAltText}`) - console.log(`New Asset Alt Text: ${newAltText}`) - } - }, - addAssetToCanvas: async (assetId: string) => { - // Get Asset URL - const asset = await webflow.getAssetById(assetId) - const assetUrl = await asset?.getUrl() - - // Get selected element - const selectedElement = await webflow.getSelectedElement() - if (!selectedElement) { - webflow.notify({ type: 'Error', message: 'Please select an element' }) - return - } - - // Add DOM element with an image tag to selected element - if (selectedElement.children && assetUrl) { - const domElement = await selectedElement.append( - webflow.elementPresets.DOM, - ) - await domElement.setTag('img') - await domElement.setAttribute('src', assetUrl) - } + + if (asset) { + // Get asset URL + const originalAltText = await asset.getAltText() + await asset.setAltText(altText) + const newAltText = await asset.getAltText() + console.log(`Original Asset Alt Text: ${originalAltText}`) + console.log(`New Asset Alt Text: ${newAltText}`) + } + }, }, - getAllAssetFolders: async () => { - const folders = await webflow.getAllAssetFolders() - console.log(folders) + // Canvas + canvas: { + addAssetToCanvas: async (assetId: string) => { + // Get Asset URL + const asset = await webflow.getAssetById(assetId) + const assetUrl = await asset?.getUrl() + + // Get selected element + const selectedElement = await webflow.getSelectedElement() + if (!selectedElement) { + webflow.notify({ type: 'Error', message: 'Please select an element' }) + return + } + + // Add DOM element with an image tag to selected element + if (selectedElement.children && assetUrl) { + const domElement = await selectedElement.append( + webflow.elementPresets.DOM, + ) + await domElement.setTag('img') + await domElement.setAttribute('src', assetUrl) + } + }, }, - createAssetFolder: async (name: string, parentFolderName?: string) => { - // Get All Asset Folders - const folders = await webflow.getAllAssetFolders() - - // Find Parent Folder by Name - if (parentFolderName) { - const parentFolder = await Promise.all( - folders.map(async (folder) => { - const folderName = await folder.getName() - if (folderName === parentFolderName) { - return folder - } - return null - }), - ).then((results) => results.find((folder) => folder !== null)) - - // Create Asset Folder with parent folder - if (parentFolder) { - const newFolder = await webflow.createAssetFolder(name, parentFolder.id) + // Asset Folders + assetFolders: { + getAllAssetFolders: async () => { + const folders = await webflow.getAllAssetFolders() + console.log(folders) + }, + + createAssetFolder: async (name: string, parentFolderName?: string) => { + // Get All Asset Folders + const folders = await webflow.getAllAssetFolders() + + // Find Parent Folder by Name + if (parentFolderName) { + const parentFolder = await Promise.all( + folders.map(async (folder) => { + const folderName = await folder.getName() + if (folderName === parentFolderName) { + return folder + } + return null + }), + ).then((results) => results.find((folder) => folder !== null)) + + // Create Asset Folder with parent folder + if (parentFolder) { + const newFolder = await webflow.createAssetFolder(name, parentFolder.id) + console.log(newFolder) + } + } else { + // Create Asset Folder + const newFolder = await webflow.createAssetFolder(name) console.log(newFolder) } - } else { - // Create Asset Folder - const newFolder = await webflow.createAssetFolder(name) - console.log(newFolder) - } + }, }, } diff --git a/src/examples/components.ts b/src/examples/components.ts index 0f7822d..68390b3 100644 --- a/src/examples/components.ts +++ b/src/examples/components.ts @@ -33,773 +33,714 @@ export const getComponentByName = async ( } export const Components = { - getAllComponents: async () => { - // Get all components - const components = await webflow.getAllComponents() - - // Print Component Details - if (components.length > 0) { - console.log('List of registered components:') - - for (let component in components) { - const currentComponentName = await components[component].getName() - console.log( - `${component + 1}. Component Name: ${currentComponentName}, Component ID: ${components[component].id}`, - ) + // Component Management + componentManagement: { + getAllComponents: async () => { + // Get all components + const components = await webflow.getAllComponents() + + // Print Component Details + if (components.length > 0) { + console.log('List of registered components:') + + for (let component in components) { + const currentComponentName = await components[component].getName() + console.log( + `${component + 1}. Component Name: ${currentComponentName}, Component ID: ${components[component].id}`, + ) + } + } else { + console.log('No components are currently registered.') } - } else { - console.log('No components are currently registered.') - } - }, - - getComponentByName: async () => { - // Fetch a component by name only - const heroSection = await webflow.getComponentByName('Hero'); - console.log(heroSection.id); - }, - - getComponentByNameAndGroup: async () => { - // Fetch a component scoped to a group - const marketingHero = await webflow.getComponentByName('Marketing', 'Hero'); - console.log(marketingHero.id); - }, - - getCurrentComponent: async () => { - // Get the component currently being edited - const component = await webflow.getCurrentComponent(); - - if (component) { - const name = await component.getName(); - console.log(`Currently editing component: ${name}`); - - // Get all elements inside the active component - const root = await component.getRootElement(); - const children = await root.getChildren(); - console.log(`Root has ${children.length} child element(s)`); - } else { - console.log('Not currently editing a component.'); - } - }, - - searchComponents: async () => { - const heroes = await webflow.searchComponents({ q: 'Hero' }); - console.log(heroes); - }, - - getSettings: async () => { - // Get the first component's settings - const component = (await webflow.getAllComponents())[0] - const settings = await component.getSettings() - console.log(settings) - /* - { - name: 'Hero Section', - group: 'Sections', - description: 'A reusable hero with heading and CTA' - } - */ - }, - - setSettings: async () => { - const component = (await webflow.getAllComponents())[0] - - // Update only the description - await component.setSettings({ - description: 'Updated hero layout with video background', - }) - - // Move to a different group - await component.setSettings({ group: 'Legacy' }) - - // Update everything at once - await component.setSettings({ - name: 'Hero Section v2', - group: 'Sections', - description: 'Redesigned hero component', - }) - }, - - getInstanceCount: async () => { - // Audit component usage across the site - const components = await webflow.getAllComponents(); - for (const component of components) { - const name = await component.getName(); - const count = await component.getInstanceCount(); - console.log(`${name}: ${count} instances`); - } - // Guard against removing a component that's still in use - const hero = components[0]; - const instanceCount = await hero.getInstanceCount(); - if (instanceCount > 0) { - console.log(`Cannot safely remove — ${instanceCount} instances exist`); - } else { - await webflow.unregisterComponent(hero); - } - }, - - 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}`) - }, - - getVariantById: async () => { - const component = await webflow.getCurrentComponent() - - if (component) { - // Get a specific variant by ID - const variant = await component.getVariant('variant-123') - console.log(variant) - /* - { - id: 'variant-123', - name: 'Secondary Hero', - isSelected: true, + }, + + getComponentByName: async () => { + // Fetch a component by name only + const heroSection = await webflow.getComponentByName('Hero'); + console.log(heroSection.id); + }, + + getComponentByNameAndGroup: async () => { + // Fetch a component scoped to a group + const marketingHero = await webflow.getComponentByName('Marketing', 'Hero'); + console.log(marketingHero.id); + }, + + getCurrentComponent: async () => { + // Get the component currently being edited + const component = await webflow.getCurrentComponent(); + + if (component) { + const name = await component.getName(); + console.log(`Currently editing component: ${name}`); + + // Get all elements inside the active component + const root = await component.getRootElement(); + const children = await root.getChildren(); + console.log(`Root has ${children.length} child element(s)`); + } else { + console.log('Not currently editing a component.'); } - */ - - // Get the base variant - const base = await component.getVariant('base') - console.log(base) + }, + + searchComponents: async () => { + const heroes = await webflow.searchComponents({ q: 'Hero' }); + console.log(heroes); + }, + + getSettings: async () => { + // Get the first component's settings + const component = (await webflow.getAllComponents())[0] + const settings = await component.getSettings() + console.log(settings) /* { - id: 'base', - name: 'Primary', - isSelected: false, + name: 'Hero Section', + group: 'Sections', + description: 'A reusable hero with heading and CTA' } */ - } - }, + }, - 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, - } - */ - }, - - createVariant: async () => { - const component = await webflow.getCurrentComponent() + setSettings: async () => { + const component = (await webflow.getAllComponents())[0] - if (component) { - // Create a variant and select it immediately - const variant = await component.createVariant({ - name: 'Secondary Hero', - isSelected: true, + // Update only the description + await component.setSettings({ + description: 'Updated hero layout with video background', }) - console.log(variant) - // { id: 'variant-123', name: 'Secondary Hero', isSelected: true } - // Name conflicts auto-increment - const variant2 = await component.createVariant({ name: 'Secondary Hero' }) - console.log(variant2.name) // 'Secondary Hero 2' - } - }, - - duplicateVariant: async () => { - const component = await webflow.getCurrentComponent() + // Move to a different group + await component.setSettings({ group: 'Legacy' }) - if (component) { - // Get the selected variant or the base variant as default - const selectedVariant = await component.getSelectedVariant() + // Update everything at once + await component.setSettings({ + name: 'Hero Section v2', + group: 'Sections', + description: 'Redesigned hero component', + }) + }, + + getInstanceCount: async () => { + // Audit component usage across the site + const components = await webflow.getAllComponents(); + for (const component of components) { + const name = await component.getName(); + const count = await component.getInstanceCount(); + console.log(`${name}: ${count} instances`); + } + // Guard against removing a component that's still in use + const hero = components[0]; + const instanceCount = await hero.getInstanceCount(); + if (instanceCount > 0) { + console.log(`Cannot safely remove — ${instanceCount} instances exist`); + } else { + await webflow.unregisterComponent(hero); + } + }, + + getRootElement: async () => { + // Get Component + const all = await webflow.getAllComponents() + const firstComponent = all[0] + + // Get Root Element of Component + const root = await firstComponent?.getRootElement() + console.log(root) + }, + + getName: async (name: string) => { + const components = await webflow.getAllComponents() + + // Check if component exists + for (const c in components) { + const currentComponentName = await components[c].getName() + if (name === currentComponentName) { + console.log(`Found ${name} Component`) + } + } + }, - // Duplicate the selected variant - const duplicateVariant = await component.createVariant({ - name: 'Duplicate of Secondary Hero', - isSelected: true, - }, selectedVariant.id) - console.log(duplicateVariant.name) // 'Duplicate of Secondary Hero' - } - }, + setName: async () => { + // Get Component + const components = await webflow.getAllComponents() + const myComponent = components[0] - setVariantSettings: async () => { - const component = await webflow.getCurrentComponent() + // Set Component Name + await myComponent.setName('My New Component Name') + }, - if (component) { - const variant = await component.setVariant({ - id: 'variant-123', - name: 'Primary Hero', - }) - console.log(variant) - } - }, + createComponent: async () => { + // Get selected element + const rootElement = await webflow.getSelectedElement() - deleteVariant: async () => { - const component = await webflow.getCurrentComponent() + if (rootElement) { + // Create a component from the Root Element + const component = await webflow.registerComponent( + 'MyCustomComponent', + rootElement, + ) + console.log(`Component registered with ID: ${component.id}`) + } else { + console.log( + 'No element is currently selected. Please select a root element first.', + ) + } + }, + + createComponentWithoutRoot: async () => { + // Create a hero component in the Sections group that is not within an existing element + const hero = await webflow.registerComponent({ + name: 'Hero Section', + group: 'Sections', + description: 'A reusable hero section with heading and CTA', + }); + console.log(`Component registered with ID: ${hero.id}`) + }, + + createComponentFromElement: async () => { + // Convert an existing element into a component, by default replacing the element with the new component + const selectedElement = await webflow.getSelectedElement() + if (selectedElement) { + const heroComponent = await webflow.registerComponent( + { + name: 'Hero Section', + group: 'Sections', + description: 'Main hero with heading and CTA' + }, + selectedElement + ) + } + }, + + duplicateComponent: async () => { + // Duplicate a component + const [original] = await webflow.getAllComponents() + const copy = await webflow.registerComponent({ name: 'Card Copy' }, original) + }, + + deleteComponent: async () => { + // Get selected element + const selectedElement = await webflow.getSelectedElement() + + if (selectedElement) { + // Create component from selected element + const myNewComponent = await webflow.registerComponent( + 'Hero Component', + selectedElement, + ) - if (component) { - await component.deleteVariant({ id: 'variant-456' }) - } + // Delete Component + await webflow.unregisterComponent(myNewComponent) + } else { + console.log( + 'No element is currently selected. Please select a root element first.', + ) + } + }, }, - reorderVariants: async () => { - const component = await webflow.getCurrentComponent() - - if (component) { - // Before: base, variant-1, variant-2, variant-3 - await component.reorderVariants(['variant-1', 'variant-3']) - // After: base, variant-1, variant-3, variant-2 - } - }, + // Component Canvas + componentCanvas: { + openComponentCanvas: async () => { + // Open the canvas for the Component that has an instance selected in the Designer + const selected = await webflow.getSelectedElement(); + if (selected?.type === 'ComponentInstance') { + await webflow.openCanvas(selected); + } + }, - createComponent: async () => { - // Get selected element - const rootElement = await webflow.getSelectedElement() + selectComponent: async () => { + // Step 1: Fetch the currently selected element + const selectedElement = await webflow.getSelectedElement() - if (rootElement) { - // Create a component from the Root Element - const component = await webflow.registerComponent( - 'MyCustomComponent', - rootElement, - ) - console.log(`Component registered with ID: ${component.id}`) - } else { - console.log( - 'No element is currently selected. Please select a root element first.', - ) - } - }, + if (selectedElement && selectedElement.type === 'ComponentInstance') { + // Step 2: Enter the context of the selected ComponentElement + await webflow.enterComponent(selectedElement as ComponentElement) + console.log('Successfully entered the component context.') - createComponentWithoutRoot: async () => { - // Create a hero component in the Sections group that is not within an existing element - const hero = await webflow.registerComponent({ - name: 'Hero Section', - group: 'Sections', - description: 'A reusable hero section with heading and CTA', - }); - console.log(`Component registered with ID: ${hero.id}`) - }, + // Step 3: After entering the component's context, fetch the root element + const rootElement = await webflow.getRootElement() + if (rootElement) { + console.log('Root element of the component:', rootElement) + } else { + console.log('No root element found in this component context.') + } + } else { + console.log('The selected element is not a ComponentElement.') + } + }, - createComponentFromElement: async () => { - // Convert an existing element into a component, by default replacing the element with the new component - const selectedElement = await webflow.getSelectedElement() - if (selectedElement) { - const heroComponent = await webflow.registerComponent( - { - name: 'Hero Section', - group: 'Sections', - description: 'Main hero with heading and CTA' - }, - selectedElement - ) - } - }, + editComponent: async () => { + // Get Component + const all = await webflow.getAllComponents() + const firstComponent = all[0] - duplicateComponent: async () => { - // Duplicate a component - const [original] = await webflow.getAllComponents() - const copy = await webflow.registerComponent({ name: 'Card Copy' }, original) - }, + // Get Root Element on the Component + const root = (await firstComponent?.getRootElement()) as AnyElement - deleteComponent: async () => { - // Get selected element - const selectedElement = await webflow.getSelectedElement() + if (root.children) { + // Append DIV block to Root element + await root?.append('div') + } + }, - if (selectedElement) { - // Create component from selected element - const myNewComponent = await webflow.registerComponent( - 'Hero Component', - selectedElement, - ) + exitComponent: async () => { + await webflow.exitComponent() + const rootElement = await webflow.getRootElement() + const rootElementType = rootElement?.type - // Delete Component - await webflow.unregisterComponent(myNewComponent) - } else { - console.log( - 'No element is currently selected. Please select a root element first.', - ) - } + // Print Root Element Type. If element type is Body, the designer has exited out of the Component context + console.log(`Element Type: ${rootElementType}`) + }, }, - openComponentCanvas: async () => { - // Open the canvas for the Component that has an instance selected in the Designer - const selected = await webflow.getSelectedElement(); - if (selected?.type === 'ComponentInstance') { - await webflow.openCanvas(selected); - } - }, + // Component Instances + componentInstances: { + createComponentInstance: async () => { + // Get Selected Element + const selectedElement = await webflow.getSelectedElement() - selectComponent: async () => { - // Step 1: Fetch the currently selected element - const selectedElement = await webflow.getSelectedElement() + // Get Component + const allComponents = await webflow.getAllComponents() + const firstComponent = allComponents[0] - if (selectedElement && selectedElement.type === 'ComponentInstance') { - // Step 2: Enter the context of the selected ComponentElement - await webflow.enterComponent(selectedElement as ComponentElement) - console.log('Successfully entered the component context.') + // Add Component instance onto a page + await selectedElement?.before(firstComponent) + }, - // Step 3: After entering the component's context, fetch the root element - const rootElement = await webflow.getRootElement() - if (rootElement) { - console.log('Root element of the component:', rootElement) + getComponent: async () => { + // Select Component Element on Page + const elements = await webflow.getAllElements() + const componentInstance = elements?.find( + (el) => el.type === 'ComponentInstance', + ) + + if (componentInstance?.type === 'ComponentInstance') { + // Get Component object from instance + const component = await componentInstance?.getComponent() + const componentName = await component?.getName() + console.log(componentName) } else { - console.log('No root element found in this component context.') + console.log('No component element found') } - } else { - console.log('The selected element is not a ComponentElement.') - } - }, - - editComponent: async () => { - // Get Component - const all = await webflow.getAllComponents() - const firstComponent = all[0] - - // Get Root Element on the Component - const root = (await firstComponent?.getRootElement()) as AnyElement + }, + }, + + // Variants + variants: { + 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}`) + }, + + getVariantById: async () => { + const component = await webflow.getCurrentComponent() + + if (component) { + // Get a specific variant by ID + const variant = await component.getVariant('variant-123') + console.log(variant) + /* + { + id: 'variant-123', + name: 'Secondary Hero', + isSelected: true, + } + */ - if (root.children) { - // Append DIV block to Root element - await root?.append('div') - } - }, + // Get the base variant + const base = await component.getVariant('base') + console.log(base) + /* + { + id: 'base', + name: 'Primary', + isSelected: false, + } + */ + } + }, - createComponentInstance: async () => { - // Get Selected Element - const selectedElement = await webflow.getSelectedElement() + 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, + } + */ + }, - // Get Component - const allComponents = await webflow.getAllComponents() - const firstComponent = allComponents[0] + createVariant: async () => { + const component = await webflow.getCurrentComponent() - // Add Component instance onto a page - await selectedElement?.before(firstComponent) - }, + if (component) { + // Create a variant and select it immediately + const variant = await component.createVariant({ + name: 'Secondary Hero', + isSelected: true, + }) + console.log(variant) + // { id: 'variant-123', name: 'Secondary Hero', isSelected: true } - exitComponent: async () => { - await webflow.exitComponent() - const rootElement = await webflow.getRootElement() - const rootElementType = rootElement?.type + // Name conflicts auto-increment + const variant2 = await component.createVariant({ name: 'Secondary Hero' }) + console.log(variant2.name) // 'Secondary Hero 2' + } + }, - // Print Root Element Type. If element type is Body, the designer has exited out of the Component context - console.log(`Element Type: ${rootElementType}`) - }, + duplicateVariant: async () => { + const component = await webflow.getCurrentComponent() - getRootElement: async () => { - // Get Component - const all = await webflow.getAllComponents() - const firstComponent = all[0] + if (component) { + // Get the selected variant or the base variant as default + const selectedVariant = await component.getSelectedVariant() - // Get Root Element of Component - const root = await firstComponent?.getRootElement() - console.log(root) - }, + // Duplicate the selected variant + const duplicateVariant = await component.createVariant({ + name: 'Duplicate of Secondary Hero', + isSelected: true, + }, selectedVariant.id) + console.log(duplicateVariant.name) // 'Duplicate of Secondary Hero' + } + }, - getName: async (name: string) => { - const components = await webflow.getAllComponents() + setVariantSettings: async () => { + const component = await webflow.getCurrentComponent() - // Check if component exists - for (const c in components) { - const currentComponentName = await components[c].getName() - if (name === currentComponentName) { - console.log(`Found ${name} Component`) + if (component) { + const variant = await component.setVariant({ + id: 'variant-123', + name: 'Primary Hero', + }) + console.log(variant) } - } - }, + }, - setName: async () => { - // Get Component - const components = await webflow.getAllComponents() - const myComponent = components[0] + deleteVariant: async () => { + const component = await webflow.getCurrentComponent() - // Set Component Name - await myComponent.setName('My New Component Name') - }, + if (component) { + await component.deleteVariant({ id: 'variant-456' }) + } + }, - createProp: async () => { - const component = await webflow.getCurrentComponent() + reorderVariants: async () => { + const component = await webflow.getCurrentComponent() - if (component) { - const headingProp = await component.createProp({ - type: 'textContent', - name: 'Heading', - group: 'Content', - defaultValue: 'Welcome to our site', - tooltip: 'The main heading displayed in the hero section', - }) - console.log(headingProp) - } + if (component) { + // Before: base, variant-1, variant-2, variant-3 + await component.reorderVariants(['variant-1', 'variant-3']) + // After: base, variant-1, variant-3, variant-2 + } + }, }, - createProps: async () => { - const component = await webflow.getCurrentComponent() + // Props + props: { + createProp: async () => { + const component = await webflow.getCurrentComponent() - if (component) { - const props = await component.createProps([ - { + if (component) { + const headingProp = await component.createProp({ type: 'textContent', name: 'Heading', group: 'Content', defaultValue: 'Welcome to our site', - }, - { - type: 'textContent', - name: 'Subheading', - group: 'Content', - defaultValue: 'We build things', - }, - { - type: 'imageAsset', - name: 'Background Image', - group: 'Content', - }, - { - type: 'link', - name: 'CTA Link', - group: 'Content', - defaultValue: { - mode: 'url', - to: 'https://example.com/signup', - openInNewTab: true, + tooltip: 'The main heading displayed in the hero section', + }) + console.log(headingProp) + } + }, + + createProps: async () => { + const component = await webflow.getCurrentComponent() + + if (component) { + const props = await component.createProps([ + { + type: 'textContent', + name: 'Heading', + group: 'Content', + defaultValue: 'Welcome to our site', }, - }, - { - type: 'number', - name: 'Overlay Opacity', - group: 'Settings', - min: 0, - max: 100, - precision: 0, - defaultValue: 50, - }, - ]) - console.log(props) - } - }, - - getProps: async () => { - const component = await webflow.getCurrentComponent() - - if (component) { - const props = await component.getProps() - console.log(props) - - // Components with no props return an empty array - const blankComponent = await webflow.getComponentByName('Empty Component') - const emptyProps = await blankComponent?.getProps() - console.log(emptyProps) // [] - } else { - console.log('Not currently editing a component.') - } - }, - - getProp: async () => { - const component = await webflow.getCurrentComponent() - - if (component) { - const props = await component.getProps() - if (props.length > 0) { - const prop = await component.getProp(props[0].id) - console.log(prop) - } else { - console.log('This component has no props.') + { + type: 'textContent', + name: 'Subheading', + group: 'Content', + defaultValue: 'We build things', + }, + { + type: 'imageAsset', + name: 'Background Image', + group: 'Content', + }, + { + type: 'link', + name: 'CTA Link', + group: 'Content', + defaultValue: { + mode: 'url', + to: 'https://example.com/signup', + openInNewTab: true, + }, + }, + { + type: 'number', + name: 'Overlay Opacity', + group: 'Settings', + min: 0, + max: 100, + precision: 0, + defaultValue: 50, + }, + ]) + console.log(props) } - } else { - console.log('Not currently editing a component.') - } - }, + }, - getPropByName: async () => { - const component = await webflow.getCurrentComponent() - - if (component) { - // Look up by name — searches across all groups - const headingProp = await component.getPropByName('Heading') - console.log(headingProp) - - // Look up by group + name - const opacityProp = await component.getPropByName('Settings', 'Overlay Opacity') - console.log(opacityProp) - } else { - console.log('Not currently editing a component.') - } - }, + getProps: async () => { + const component = await webflow.getCurrentComponent() - setProp: async () => { - const component = await webflow.getCurrentComponent() + if (component) { + const props = await component.getProps() + console.log(props) - if (component) { - const props = await component.getProps() - if (props.length > 0) { - // Update name and tooltip using the ID + updates signature - const updated = await component.setProp(props[0].id, { - name: 'Updated Heading', - tooltip: 'The main heading for the hero section', - }) - console.log(updated) - - // Use the object-with-ID signature to move the prop to a different group - const moved = await component.setProp({ id: props[0].id, group: 'Layout' }) - console.log(moved.group) // 'Layout' + // Components with no props return an empty array + const blankComponent = await webflow.getComponentByName('Empty Component') + const emptyProps = await blankComponent?.getProps() + console.log(emptyProps) // [] } else { - console.log('This component has no props.') + console.log('Not currently editing a component.') } - } else { - console.log('Not currently editing a component.') - } - }, - - removeProp: async () => { - const component = await webflow.getCurrentComponent() + }, + + getInstanceProps: async () => { + // Get the selected component instance + const instanceEl = await webflow.getSelectedElement(); + + if (instanceEl?.type === 'ComponentInstance') { + const props = await instanceEl.getProps(); + + // Distinguish bound props from static values using the sourceType property + for (const prop of props) { + if (typeof prop.value === 'object' && prop.value !== null && 'sourceType' in prop.value) { + console.log(`${prop.propId}: bound to ${(prop.value as { sourceType: string }).sourceType}`); + } else { + console.log(`${prop.propId}: ${JSON.stringify(prop.value)}${prop.hasOverride ? ' (overridden)' : ''}`); + } + } - if (component) { - const props = await component.getProps() - const targetProp = props.find((p) => p.name === 'Old Heading') + // Round-trip: read current values, modify one, and write them back with setProps + const updatedProps = props.map((prop) => { + if (prop.propId === props[0].propId) { + return { propId: prop.propId, value: 'Updated value' }; + } + return { propId: prop.propId, value: prop.value }; + }); - if (targetProp) { - await component.removeProp(targetProp.id) - console.log(`Removed prop: ${targetProp.name}`) + await instanceEl.setProps(updatedProps); } else { - console.log('Prop not found.') + console.log('Please select a component instance.'); } - } else { - console.log('Not currently editing a component.') - } - }, + }, - getInstanceProps: async () => { - // Get the selected component instance - const instanceEl = await webflow.getSelectedElement(); + getResolvedProps: async () => { + // Get the selected component instance + const instanceEl = await webflow.getSelectedElement(); - if (instanceEl?.type === 'ComponentInstance') { - const props = await instanceEl.getProps(); + if (instanceEl?.type === 'ComponentInstance') { + // Get what each prop actually renders — bindings resolved to their output values + const resolvedProps = await instanceEl.getResolvedProps(); - // Distinguish bound props from static values using the sourceType property - for (const prop of props) { - if (typeof prop.value === 'object' && prop.value !== null && 'sourceType' in prop.value) { - console.log(`${prop.propId}: bound to ${(prop.value as { sourceType: string }).sourceType}`); - } else { - console.log(`${prop.propId}: ${JSON.stringify(prop.value)}${prop.hasOverride ? ' (overridden)' : ''}`); - } - } - - // Round-trip: read current values, modify one, and write them back with setProps - const updatedProps = props.map((prop) => { - if (prop.propId === props[0].propId) { - return { propId: prop.propId, value: 'Updated value' }; + for (const prop of resolvedProps) { + console.log(`${prop.propId}: ${JSON.stringify(prop.value)}`); } - return { propId: prop.propId, value: prop.value }; - }); - await instanceEl.setProps(updatedProps); - } else { - console.log('Please select a component instance.'); - } - }, + // Comparison of all three instance prop read APIs: - getResolvedProps: async () => { - // Get the selected component instance - const instanceEl = await webflow.getSelectedElement(); + // searchProps — full metadata: wrapped value, resolved value, display info, override status + const search = await instanceEl.searchProps(); + console.log(search[0].value); // { sourceType: 'static', value: 'My Custom Title' } + console.log(search[0].resolvedValue); // 'My Custom Title' + console.log(search[0].display); // { label: 'Heading', group: 'Content' } + console.log(search[0].hasOverride); // true - if (instanceEl?.type === 'ComponentInstance') { - // Get what each prop actually renders — bindings resolved to their output values - const resolvedProps = await instanceEl.getResolvedProps(); + // getProps — raw values with override status, no display metadata + const props = await instanceEl.getProps(); + console.log(props[0].value); // 'My Custom Title' (bare value) + console.log(props[0].hasOverride); // true - for (const prop of resolvedProps) { - console.log(`${prop.propId}: ${JSON.stringify(prop.value)}`); + // getResolvedProps — just the final resolved output, no binding metadata + const resolved = await instanceEl.getResolvedProps(); + console.log(resolved[0].value); // 'My Custom Title' + } else { + console.log('Please select a component instance.'); } + }, - // Comparison of all three instance prop read APIs: - - // searchProps — full metadata: wrapped value, resolved value, display info, override status - const search = await instanceEl.searchProps(); - console.log(search[0].value); // { sourceType: 'static', value: 'My Custom Title' } - console.log(search[0].resolvedValue); // 'My Custom Title' - console.log(search[0].display); // { label: 'Heading', group: 'Content' } - console.log(search[0].hasOverride); // true - - // getProps — raw values with override status, no display metadata - const props = await instanceEl.getProps(); - console.log(props[0].value); // 'My Custom Title' (bare value) - console.log(props[0].hasOverride); // true - - // getResolvedProps — just the final resolved output, no binding metadata - const resolved = await instanceEl.getResolvedProps(); - console.log(resolved[0].value); // 'My Custom Title' - } else { - console.log('Please select a component instance.'); - } - }, - - setProps: async () => { - // Get the selected component instance - const instanceEl = await webflow.getSelectedElement(); + setProps: async () => { + // Get the selected component instance + const instanceEl = await webflow.getSelectedElement(); - if (instanceEl?.type === 'ComponentInstance') { - // Read current prop values (round-trip: read, modify, write back) - const currentProps = await instanceEl.getProps(); - console.log('Current props:', currentProps); + if (instanceEl?.type === 'ComponentInstance') { + // Read current prop values (round-trip: read, modify, write back) + const currentProps = await instanceEl.getProps(); + console.log('Current props:', currentProps); - await instanceEl.setProps([ - // Static value override — set the first prop to a new string value - { propId: currentProps[0].propId, value: 'New Heading' }, + await instanceEl.setProps([ + // Static value override — set the first prop to a new string value + { propId: currentProps[0].propId, value: 'New Heading' }, - // Bind to a parent component prop - { propId: 'prop_2', value: { sourceType: 'prop', propId: 'parent_prop_5' } }, + // Bind to a parent component prop + { propId: 'prop_2', value: { sourceType: 'prop', propId: 'parent_prop_5' } }, - // Bind to a CMS field - { propId: 'prop_3', value: { sourceType: 'cms', collectionId: 'col_abc', fieldId: 'field_author' } }, + // Bind to a CMS field + { propId: 'prop_3', value: { sourceType: 'cms', collectionId: 'col_abc', fieldId: 'field_author' } }, - // Bind to a page field - { propId: 'prop_4', value: { sourceType: 'page', fieldKey: 'seoTitle' } }, + // Bind to a page field + { propId: 'prop_4', value: { sourceType: 'page', fieldKey: 'seoTitle' } }, - // Disconnect a binding / reset a prop to its component default - { propId: 'prop_5', value: null }, - ]); + // Disconnect a binding / reset a prop to its component default + { propId: 'prop_5', value: null }, + ]); - // Confirm updated values - const updatedProps = await instanceEl.getProps(); - console.log('Updated props:', updatedProps); - } else { - console.log('Please select a component instance.'); - } - }, + // Confirm updated values + const updatedProps = await instanceEl.getProps(); + console.log('Updated props:', updatedProps); + } else { + console.log('Please select a component instance.'); + } + }, - resetAllProps: async () => { - // Get the selected component instance - const instanceEl = await webflow.getSelectedElement(); + resetAllProps: async () => { + // Get the selected component instance + const instanceEl = await webflow.getSelectedElement(); - if (instanceEl?.type === 'ComponentInstance') { - // Get the instance's props to find a prop ID to override - const props = await instanceEl.searchProps(); + if (instanceEl?.type === 'ComponentInstance') { + // Get the instance's props to find a prop ID to override + const props = await instanceEl.searchProps(); - if (props.length > 0) { - const firstProp = props[0]; + if (props.length > 0) { + const firstProp = props[0]; - // Set an override on the first prop - await instanceEl.setProps([{ propId: firstProp.propId, value: 'Custom value' }]); + // Set an override on the first prop + await instanceEl.setProps([{ propId: firstProp.propId, value: 'Custom value' }]); - // Confirm the override is applied - const before = await instanceEl.getProps(); - console.log('Has override:', before[0].hasOverride); // true + // Confirm the override is applied + const before = await instanceEl.getProps(); + console.log('Has override:', before[0].hasOverride); // true - // Reset all overrides to component defaults in one call - await instanceEl.resetAllProps(); + // Reset all overrides to component defaults in one call + await instanceEl.resetAllProps(); - // All props now show defaults, no overrides - const after = await instanceEl.getProps(); - console.log('Has override after reset:', after[0].hasOverride); // false + // All props now show defaults, no overrides + const after = await instanceEl.getProps(); + console.log('Has override after reset:', after[0].hasOverride); // false + } else { + console.log('This component instance has no props.'); + } } else { - console.log('This component instance has no props.'); + console.log('Please select a component instance.'); } - } else { - console.log('Please select a component instance.'); - } - }, + }, - getComponent: async () => { - // Select Component Element on Page - const elements = await webflow.getAllElements() - const componentInstance = elements?.find( - (el) => el.type === 'ComponentInstance', - ) - - if (componentInstance?.type === 'ComponentInstance') { - // Get Component object from instance - const component = await componentInstance?.getComponent() - const componentName = await component?.getName() - console.log(componentName) - } else { - console.log('No component element found') - } - }, - - searchProps: async () => { - // Get the selected element and confirm it's a component instance - const selected = await webflow.getSelectedElement() + searchProps: async () => { + // Get the selected element and confirm it's a component instance + const selected = await webflow.getSelectedElement() - if (selected?.type !== 'ComponentInstance') { - console.log('Select a component instance first.') - return - } + if (selected?.type !== 'ComponentInstance') { + console.log('Select a component instance first.') + return + } - // Get all props on the instance with their current values and metadata - const props = await selected.searchProps() - console.log(props) - /* - [ - { - propId: "prop_1", - valueType: "textContent", - hasOverride: true, - value: { - sourceType: "static", - value: "My Custom Title" - }, - resolvedValue: "My Custom Title", - defaultValue: "Welcome to our site", - display: { - label: "Heading", - group: "Content" - } - }, - { - propId: "prop_3", - valueType: "textContent", - hasOverride: false, - value: { - sourceType: "cms", - collectionId: "col_abc123", - collectionName: "Blog Posts", - fieldId: "field_author", - fieldName: "Author Name", - fieldGroup: null, - fieldType: "plainText" + // Get all props on the instance with their current values and metadata + const props = await selected.searchProps() + console.log(props) + /* + [ + { + propId: "prop_1", + valueType: "textContent", + hasOverride: true, + value: { + sourceType: "static", + value: "My Custom Title" + }, + resolvedValue: "My Custom Title", + defaultValue: "Welcome to our site", + display: { + label: "Heading", + group: "Content" + } }, - resolvedValue: "Jane Doe", - defaultValue: "", - display: { - label: "Author", - group: "Content" - } - }, - { - propId: "prop_4", - valueType: "boolean", - hasOverride: false, - value: { - sourceType: "static", - value: true + { + propId: "prop_3", + valueType: "textContent", + hasOverride: false, + value: { + sourceType: "cms", + collectionId: "col_abc123", + collectionName: "Blog Posts", + fieldId: "field_author", + fieldName: "Author Name", + fieldGroup: null, + fieldType: "plainText" + }, + resolvedValue: "Jane Doe", + defaultValue: "", + display: { + label: "Author", + group: "Content" + } }, - resolvedValue: true, - defaultValue: true, - display: { - label: "Show CTA", - group: "Settings", - trueLabel: "Visible", - falseLabel: "Hidden" + { + propId: "prop_4", + valueType: "boolean", + hasOverride: false, + value: { + sourceType: "static", + value: true + }, + resolvedValue: true, + defaultValue: true, + display: { + label: "Show CTA", + group: "Settings", + trueLabel: "Visible", + falseLabel: "Hidden" + } } - } - ] - */ - }, + ] + */ + }, - searchPropsByValueType: async () => { - // Get the selected element and confirm it's a component instance - const selected = await webflow.getSelectedElement() + searchPropsByValueType: async () => { + // Get the selected element and confirm it's a component instance + const selected = await webflow.getSelectedElement() - if (selected?.type !== 'ComponentInstance') { - console.log('Select a component instance first.') - return - } + if (selected?.type !== 'ComponentInstance') { + console.log('Select a component instance first.') + return + } - // Filter to only props with a specific value type - const textProps = await selected.searchProps({ valueType: 'textContent' }) - console.log(textProps) - // Returns only props where valueType === 'textContent' + // Filter to only props with a specific value type + const textProps = await selected.searchProps({ valueType: 'textContent' }) + console.log(textProps) + // Returns only props where valueType === 'textContent' + }, }, } diff --git a/src/examples/examples.ts b/src/examples/examples.ts index a97235b..d511408 100644 --- a/src/examples/examples.ts +++ b/src/examples/examples.ts @@ -10,7 +10,7 @@ import { Assets } from './assets' import { ValidFileTypesEnum } from './assets' // Add default example for createAssetFromURL -Assets.createAssetFromURL.example = { +Assets.assetCreation.createAssetFromURL.example = { url: 'https://picsum.photos/200', fileName: 'example-image.jpg', fileTypeEnum: ValidFileTypesEnum.JPEG, diff --git a/src/examples/folders.ts b/src/examples/folders.ts index 7cc291b..0aa1a4c 100644 --- a/src/examples/folders.ts +++ b/src/examples/folders.ts @@ -1,72 +1,81 @@ export const Folders = { - createNewFolder: async (name: string) => { - // Create and name new folder - const newFolder = await webflow.createPageFolder() - await newFolder.setName(name) - // Print details - const folderName = await newFolder.getName() - console.log(folderName) - }, - getFolderName: async () => { - // Get all Pages and folders - const pagesAndFolders = await webflow.getAllPagesAndFolders() + folders: { + createNewFolder: async (name: string) => { + // Create and name new folder + const newFolder = await webflow.createPageFolder() + await newFolder.setName(name) - for (let folder of pagesAndFolders) { - const folderName = await folder.getName() - const type = folder.type - console.log(folderName, type) - } - }, - setFolderName: async (name: string) => { - // Create and name new folder - const newFolder = await webflow.createPageFolder() - await newFolder.setName(name) + // Print details + const folderName = await newFolder.getName() + console.log(folderName) + }, + getFolderName: async () => { + // Get all Pages and folders + const pagesAndFolders = await webflow.getAllPagesAndFolders() - // Print details - const folderName = await newFolder.getName() - console.log(folderName) - }, + for (let folder of pagesAndFolders) { + const folderName = await folder.getName() + const type = folder.type + console.log(folderName, type) + } + }, + setFolderName: async (name: string) => { + // Create and name new folder + const newFolder = await webflow.createPageFolder() + await newFolder.setName(name) - getslug: async () => { - // Get all Pages and folders - const pagesAndFolders = await webflow.getAllPagesAndFolders() + // Print details + const folderName = await newFolder.getName() + console.log(folderName) + }, - for (let folder of pagesAndFolders) { - const folderSlug = await folder.getSlug() - console.log('Slug', folderSlug) - } }, - setSlug: async (slug: string) => { - // Create and give slug to new folder - const newFolder = await webflow.createPageFolder() - await newFolder.setSlug(slug) - // Print details - const newSlug = await newFolder.getSlug() - console.log('Slug', newSlug) - }, - getParentFolder: async () => { - // Get all Pages and folders - const pagesAndFolders = await webflow.getAllPagesAndFolders() + slugs: { + getSlug: async () => { + // Get all Pages and folders + const pagesAndFolders = await webflow.getAllPagesAndFolders() - for (let folder of pagesAndFolders) { - const childName = await folder.getName() - const parent = await folder.getParent() - const parentName = await parent?.getName() - console.log(`Folder: ${childName}`, `Parent: ${parentName}`) - } + for (let folder of pagesAndFolders) { + const folderSlug = await folder.getSlug() + console.log('Slug', folderSlug) + } + }, + setSlug: async (slug: string) => { + // Create and give slug to new folder + const newFolder = await webflow.createPageFolder() + await newFolder.setSlug(slug) + + // Print details + const newSlug = await newFolder.getSlug() + console.log('Slug', newSlug) + }, }, - setParentFolder: async (folderName: string) => { - // Get all Pages and folders - const pagesAndFolders = await webflow.getAllPagesAndFolders() - // Create and name new folder - const newFolder = await webflow.createPageFolder() - await newFolder.setName(folderName) + parents: { + getParentFolder: async () => { + // Get all Pages and folders + const pagesAndFolders = await webflow.getAllPagesAndFolders() + + for (let folder of pagesAndFolders) { + const childName = await folder.getName() + const parent = await folder.getParent() + const parentName = await parent?.getName() + console.log(`Folder: ${childName}`, `Parent: ${parentName}`) + } + }, + setParentFolder: async (folderName: string) => { + // Get all Pages and folders + const pagesAndFolders = await webflow.getAllPagesAndFolders() + + // Create and name new folder + const newFolder = await webflow.createPageFolder() + await newFolder.setName(folderName) - for (let folder of pagesAndFolders) { - await folder.setParent(newFolder) - } + for (let folder of pagesAndFolders) { + await folder.setParent(newFolder) + } + }, }, } diff --git a/src/examples/payments.ts b/src/examples/payments.ts index 96bbf49..37e736e 100644 --- a/src/examples/payments.ts +++ b/src/examples/payments.ts @@ -1,9 +1,12 @@ export const Payments = { - getAppSubscriptions: async () => { + subscriptions: { + getAppSubscriptions: async () => { - const subcriptions = await webflow.getAppSubscriptions() - console.log(`Subscriptions: ${subcriptions}`) + const subcriptions = await webflow.getAppSubscriptions() + console.log(`Subscriptions: ${subcriptions}`) + }, }, + } \ No newline at end of file diff --git a/src/examples/utilities.ts b/src/examples/utilities.ts index 5b639bf..c9c2f7d 100644 --- a/src/examples/utilities.ts +++ b/src/examples/utilities.ts @@ -7,264 +7,273 @@ export enum ExtensionSizeEnum { } export const Utilities = { - getSiteInfo: async () => { - // Get Site Information - const siteInfo = await webflow.getSiteInfo() + // Site Info + siteInfo: { + getSiteInfo: async () => { + // Get Site Information + const siteInfo = await webflow.getSiteInfo() + + // Print Site Information + console.log(JSON.stringify(siteInfo, null, 2)) + }, + + getIdToken: async () => { + // Get ID Token + const idToken = await webflow.getIdToken() + + // Print ID Token + console.log(idToken) + }, + + checkAppMode: async () => { + const capabilities = await webflow.canForAppMode([ + webflow.appModes.canEdit, + webflow.appModes.canDesign, + ]) - // Print Site Information - console.log(JSON.stringify(siteInfo, null, 2)) - }, - - setExtensionSize: async (extensionSizeEnum: ExtensionSizeEnum) => { - // Set the extension UI size to "default", "comfortable", or "large" - await webflow.setExtensionSize(extensionSizeEnum.id) - - console.log(`Extension UI size set to: ${extensionSizeEnum.id}`) - }, - - displayCurrentMediaQuery: async () => { - const breakpointId = await webflow.getMediaQuery() - - switch (breakpointId) { - case 'xxl': - console.log( - 'The current view is for very large screens or high-resolution monitors.', - ) - break - case 'xl': - console.log('The current view is suitable for large desktop monitors.') - break - case 'large': - console.log('The current view fits standard desktop monitors.') - break - case 'main': - console.log( - 'The current view is suitable for smaller desktops or large tablets.', - ) - break - case 'medium': - console.log( - 'The current view is suitable for tablets and some large phones.', - ) - break - case 'small': - console.log('The current view is designed for larger mobile devices.') - break - case 'tiny': - console.log('The current view is for the smallest mobile devices.') - break - } - }, - - getIdToken: async () => { - // Get ID Token - const idToken = await webflow.getIdToken() - - // Print ID Token - console.log(idToken) + console.log(capabilities) + }, + + checkAppConnection: async () => { + // Check for current app connection + const appConnection = await webflow.getCurrentAppConnection() + console.log(appConnection) + }, + + getLaunchContext: async () => { + const context = await webflow.getLaunchContext() + console.log('Launch Context:', context) + + if (context) { + const contextType = context.type + const contextValue = context.value + + console.log('Launch Type:', contextType) + console.log('Launch Value:', contextValue) + + // Notify user of launch context + await webflow.notify({ + type: 'Info', + message: `App launched via ${contextType}${contextValue ? ` with ${JSON.stringify(contextValue)}` : ''}`, + }) + } else { + console.log('No specific launch context') + } + }, }, - checkAppMode: async () => { - const capabilities = await webflow.canForAppMode([ - webflow.appModes.canEdit, - webflow.appModes.canDesign, - ]) + // Display & UI + displayAndUI: { + setExtensionSize: async (extensionSizeEnum: ExtensionSizeEnum) => { + // Set the extension UI size to "default", "comfortable", or "large" + await webflow.setExtensionSize(extensionSizeEnum.id) + + console.log(`Extension UI size set to: ${extensionSizeEnum.id}`) + }, + + displayCurrentMediaQuery: async () => { + const breakpointId = await webflow.getMediaQuery() + + switch (breakpointId) { + case 'xxl': + console.log( + 'The current view is for very large screens or high-resolution monitors.', + ) + break + case 'xl': + console.log('The current view is suitable for large desktop monitors.') + break + case 'large': + console.log('The current view fits standard desktop monitors.') + break + case 'main': + console.log( + 'The current view is suitable for smaller desktops or large tablets.', + ) + break + case 'medium': + console.log( + 'The current view is suitable for tablets and some large phones.', + ) + break + case 'small': + console.log('The current view is designed for larger mobile devices.') + break + case 'tiny': + console.log('The current view is for the smallest mobile devices.') + break + } + }, - console.log(capabilities) - }, + getPseudoMode: async () => { + // Select a state in the designer to see the pseudo mode in the console + const pseudoMode = await webflow.getPseudoMode() + console.log('Pseudo Mode:', pseudoMode) + }, - checkAppConnection: async () => { - // Check for current app connection - const appConnection = await webflow.getCurrentAppConnection() - console.log(appConnection) - }, + notifyUser: async () => { + // General notification + await webflow.notify({ type: 'Info', message: 'Great work!' }) - notifyUser: async () => { - // General notification - await webflow.notify({ type: 'Info', message: 'Great work!' }) - - // Error notification - await webflow.notify({ - type: 'Error', - message: 'Something went wrong, try again!', - }) - - // Success notification - await webflow.notify({ - type: 'Success', - message: 'Successfully did something!', - }) - }, + // Error notification + await webflow.notify({ + type: 'Error', + message: 'Something went wrong, try again!', + }) - subscribeSelect: async () => { - // Subscribe to changes in the selected element - const selectedElementCallback = (element: AnyElement | null) => { - if (element) { - console.log('Selected Element:', element) + // Success notification + await webflow.notify({ + type: 'Success', + message: 'Successfully did something!', + }) + }, + + getElementSnapshot: async () => { + // Get the currently selected element + const selectedElement = await webflow.getSelectedElement() + + if (selectedElement) { + // Capture a screenshot of the element + console.log('Getting screenshot of element...') + const screenshot = await webflow.getElementSnapshot(selectedElement) + + if (screenshot) { + console.log('Screenshot captured successfully!') + console.log('Base64 string:', screenshot.substring(0, 100) + '...') + + console.log( + '%c ', + `font-size:400px; background:url(${screenshot}) no-repeat; background-size: contain;`, + ) + } else { + console.log('Failed to capture screenshot') + } } else { - console.log('No element is currently selected.') + console.log('No element selected. Please select an element first.') } - } - - const unsubscribeSelectedElement = webflow.subscribe( - 'selectedelement', - selectedElementCallback, - ) + }, }, - subscribeBreakpoint: async () => { - const unsubscribeMediaQuery = webflow.subscribe( - 'mediaquery', - (breakpoint) => { - switch (breakpoint) { - case 'xxl': - console.log( - 'The current view is for very large screens or high-resolution monitors.', - ) - break - case 'xl': - console.log( - 'The current view is suitable for large desktop monitors.', - ) - break - case 'large': - console.log('The current view fits standard desktop monitors.') - break - case 'main': - console.log( - 'The current view is suitable for smaller desktops or large tablets.', - ) - break - case 'medium': - console.log( - 'The current view is suitable for tablets and some large phones.', - ) - break - case 'small': - console.log( - 'The current view is designed for larger mobile devices.', - ) - break - case 'tiny': - console.log('The current view is for the smallest mobile devices.') - break - default: - console.log('Unknown breakpoint:', breakpoint) + // Subscriptions + subscriptions: { + subscribeSelect: async () => { + // Subscribe to changes in the selected element + const selectedElementCallback = (element: AnyElement | null) => { + if (element) { + console.log('Selected Element:', element) + } else { + console.log('No element is currently selected.') } - }, - ) - }, - - subscribePageChange: async () => { - // Subscribe to changes in the selected page - const selectedPageCallback = async (page: Page | null) => { - if (page) { - let pageName = await page.getName() - let pageSlug = await page.getSlug() - let pageParent = await page.getParent() - let searchDescription = await page.getSearchDescription() - - console.log(`Page Name: ${pageName}`) - console.log(`Page Slug: ${pageSlug}`) - console.log(`Page Description: ${searchDescription}`) - } else { - console.log('No element is currently selected.') } - } - const unsubscribeSelectedElement = webflow.subscribe( - 'currentpage', - selectedPageCallback, - ) - }, - - subscribeAppModes: async () => { - // Subscribe to changes in the selected page - const checkAppModes = async () => { - const capabilities = await webflow.canForAppMode( - Object.values(webflow.appModes), + const unsubscribeSelectedElement = webflow.subscribe( + 'selectedelement', + selectedElementCallback, ) - console.log(capabilities) - } - - const unsubscribeSelectedElement = webflow.subscribe( - 'currentappmode', - checkAppModes, - ) - }, - - subscribePseudoMode: async () => { - // Subscribe to changes in the pseudo mode - const pseudoModeCallback = (pseudoMode: PseudoStateKey | null) => { - console.log('Pseudo Mode:', pseudoMode) - } - - const unsubscribePseudoMode = webflow.subscribe( - 'pseudomode', - pseudoModeCallback, - ) - }, + }, + + subscribeBreakpoint: async () => { + const unsubscribeMediaQuery = webflow.subscribe( + 'mediaquery', + (breakpoint) => { + switch (breakpoint) { + case 'xxl': + console.log( + 'The current view is for very large screens or high-resolution monitors.', + ) + break + case 'xl': + console.log( + 'The current view is suitable for large desktop monitors.', + ) + break + case 'large': + console.log('The current view fits standard desktop monitors.') + break + case 'main': + console.log( + 'The current view is suitable for smaller desktops or large tablets.', + ) + break + case 'medium': + console.log( + 'The current view is suitable for tablets and some large phones.', + ) + break + case 'small': + console.log( + 'The current view is designed for larger mobile devices.', + ) + break + case 'tiny': + console.log('The current view is for the smallest mobile devices.') + break + default: + console.log('Unknown breakpoint:', breakpoint) + } + }, + ) + }, + + subscribePageChange: async () => { + // Subscribe to changes in the selected page + const selectedPageCallback = async (page: Page | null) => { + if (page) { + let pageName = await page.getName() + let pageSlug = await page.getSlug() + let pageParent = await page.getParent() + let searchDescription = await page.getSearchDescription() + + console.log(`Page Name: ${pageName}`) + console.log(`Page Slug: ${pageSlug}`) + console.log(`Page Description: ${searchDescription}`) + } else { + console.log('No element is currently selected.') + } + } - subscribeSelectedVariant: async () => { - // Subscribe to variant selection changes on the component canvas - const unsubscribe = webflow.subscribe('selectedvariant', (variant) => { - console.log('Selected variant:', variant.name) - console.log('Variant ID:', variant.id) - }) + const unsubscribeSelectedElement = webflow.subscribe( + 'currentpage', + selectedPageCallback, + ) + }, - // Stop listening after 10 seconds - setTimeout(unsubscribe, 10000) - }, + subscribeAppModes: async () => { + // Subscribe to changes in the selected page + const checkAppModes = async () => { + const capabilities = await webflow.canForAppMode( + Object.values(webflow.appModes), + ) + console.log(capabilities) + } - getLaunchContext: async () => { - const context = await webflow.getLaunchContext() - console.log('Launch Context:', context) + const unsubscribeSelectedElement = webflow.subscribe( + 'currentappmode', + checkAppModes, + ) + }, - if (context) { - const contextType = context.type - const contextValue = context.value + subscribePseudoMode: async () => { + // Subscribe to changes in the pseudo mode + const pseudoModeCallback = (pseudoMode: PseudoStateKey | null) => { + console.log('Pseudo Mode:', pseudoMode) + } - console.log('Launch Type:', contextType) - console.log('Launch Value:', contextValue) + const unsubscribePseudoMode = webflow.subscribe( + 'pseudomode', + pseudoModeCallback, + ) + }, - // Notify user of launch context - await webflow.notify({ - type: 'Info', - message: `App launched via ${contextType}${contextValue ? ` with ${JSON.stringify(contextValue)}` : ''}`, + subscribeSelectedVariant: async () => { + // Subscribe to variant selection changes on the component canvas + const unsubscribe = webflow.subscribe('selectedvariant', (variant) => { + console.log('Selected variant:', variant.name) + console.log('Variant ID:', variant.id) }) - } else { - console.log('No specific launch context') - } - }, - - getPseudoMode: async () => { - // Select a state in the designer to see the pseudo mode in the console - const pseudoMode = await webflow.getPseudoMode() - console.log('Pseudo Mode:', pseudoMode) - }, - - getElementSnapshot: async () => { - // Get the currently selected element - const selectedElement = await webflow.getSelectedElement() - - if (selectedElement) { - // Capture a screenshot of the element - console.log('Getting screenshot of element...') - const screenshot = await webflow.getElementSnapshot(selectedElement) - - if (screenshot) { - console.log('Screenshot captured successfully!') - console.log('Base64 string:', screenshot.substring(0, 100) + '...') - console.log( - '%c ', - `font-size:400px; background:url(${screenshot}) no-repeat; background-size: contain;`, - ) - } else { - console.log('Failed to capture screenshot') - } - } else { - console.log('No element selected. Please select an element first.') - } + // Stop listening after 10 seconds + setTimeout(unsubscribe, 10000) + }, }, }