feat(figma-api): add getNodeByIdAsync() and getMainComponentAsync() (#779)
Scripts written for Figma's dynamic-page mode can call figma.getNodeByIdAsync() and instance.getMainComponentAsync(); both resolve to the same nodes as their synchronous forms. getMainComponentAsync joins the instance surface type check against @figma/plugin-typings.
This commit is contained in:
parent
1aa10a4fed
commit
bb86d2ad7f
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
### Added
|
||||
|
||||
- Run scripts written for Figma's dynamic-page mode that call `figma.getNodeByIdAsync()` or `getMainComponentAsync()`; both resolve to the same nodes as their synchronous forms.
|
||||
- Export components to Storybook with `openpencil export -f storybook`: one CSF3 story file per component set or component for React, Vue, or HTML, with a story and `select` controls per variant, a design image per variant, and an `openpencil://` link that opens the variant in OpenPencil. `--watch` re-exports on every save and removes stories of deleted components (#727).
|
||||
- Export HTML and Tailwind JSX from the app's export options and through the IO registry, and export Tailwind JSX from the CLI with `-f tailwind-jsx` (`-f jsx --style tailwind` still works). HTML export of a single layer now includes the layer itself, as other formats do.
|
||||
- Choose PPTX in the Export panel's format list, alongside PNG, JPG, WEBP, SVG, and PDF.
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ type InstancePropertySurfaceMatch = Expect<
|
|||
| 'setProperties'
|
||||
| 'isExposedInstance'
|
||||
| 'exposedInstances'
|
||||
| 'getMainComponentAsync'
|
||||
>,
|
||||
Pick<
|
||||
InstanceNode,
|
||||
|
|
@ -78,6 +79,7 @@ type InstancePropertySurfaceMatch = Expect<
|
|||
| 'setProperties'
|
||||
| 'isExposedInstance'
|
||||
| 'exposedInstances'
|
||||
| 'getMainComponentAsync'
|
||||
>
|
||||
>
|
||||
>
|
||||
|
|
|
|||
|
|
@ -137,6 +137,11 @@ export class FigmaAPI implements NodeProxyHost {
|
|||
return node ? this.wrapNode(id) : null
|
||||
}
|
||||
|
||||
/** The async lookup that Figma requires in dynamic-page mode; same result as getNodeById. */
|
||||
async getNodeByIdAsync(id: string): Promise<FigmaNodeProxy | null> {
|
||||
return this.getNodeById(id)
|
||||
}
|
||||
|
||||
// --- Node Creation ---
|
||||
|
||||
private _createNode(type: NodeType): FigmaNodeProxy {
|
||||
|
|
|
|||
|
|
@ -222,6 +222,11 @@ export class FigmaNodeProxy {
|
|||
setPageBackgrounds(this[INTERNAL_GRAPH], this._raw(), value)
|
||||
}
|
||||
|
||||
/** The async form Figma requires in dynamic-page mode; same result as mainComponent. */
|
||||
async getMainComponentAsync(): Promise<FigmaNodeProxy | null> {
|
||||
return this.mainComponent
|
||||
}
|
||||
|
||||
get mainComponent(): FigmaNodeProxy | null {
|
||||
const n = this._raw()
|
||||
if (!n.componentId) return null
|
||||
|
|
|
|||
|
|
@ -162,6 +162,7 @@ Common node properties are readable/writable through the proxy, including:
|
|||
- `figma.createImage(data)`
|
||||
- `figma.loadFontAsync(fontName)` no-ops because OpenPencil does not gate text edits on plugin font loading
|
||||
- `figma.listAvailableFontsAsync()` returns host-provided fonts when available
|
||||
- `figma.getNodeByIdAsync(id)` and `instance.getMainComponentAsync()` resolve to the same nodes as `figma.getNodeById(id)` and `instance.mainComponent`, for scripts written for Figma's dynamic-page mode
|
||||
- `figma.notify(message)` logs a warning in headless mode
|
||||
- `figma.viewport`
|
||||
|
||||
|
|
|
|||
|
|
@ -61,4 +61,15 @@ describe('components', () => {
|
|||
expect(instance.type).toBe('INSTANCE')
|
||||
expect(expectDefined(instance.mainComponent, 'instance main component').id).toBe(comp.id)
|
||||
})
|
||||
|
||||
test('async lookups resolve like their synchronous forms', async () => {
|
||||
const api = createAPI()
|
||||
const component = api.createComponent()
|
||||
const instance = component.createInstance()
|
||||
|
||||
expect((await api.getNodeByIdAsync(instance.id))?.id).toBe(instance.id)
|
||||
expect(await api.getNodeByIdAsync('0:404')).toBeNull()
|
||||
expect((await instance.getMainComponentAsync())?.id).toBe(component.id)
|
||||
expect(await component.getMainComponentAsync()).toBeNull()
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in a new issue