import type { DesignDocument, DocumentDiagnostic, DocumentDuplicateMetadataRemapper, DocumentNode, DocumentNodeKind, DocumentNodePatch, DocumentTransaction, DocumentValue } from './contracts.js'; /** * Component model on top of the document engine's component commands. * * Everything here is stored in `node.properties` so that the document contract is unchanged: * - a component set is a container with `properties.componentSet === true` whose children are the * variant components; each variant carries `properties.variant`, a map of axis name to value, and its * layer name is the Figma-style `Axis=Value, Axis=Value` string; * - a main component may declare `properties.componentProperties` (text, boolean and instance-swap * properties), each bound to layer addresses inside the definition; an instance's property value is * the override on those layers, so the document never stores a second copy of the value; * - a nested instance inside a definition may set `properties.exposeInstanceProperties === true` so * that its definition's properties appear on every outer instance; * - `properties.hidden === true` hides a layer; boolean properties toggle it. * * Override addresses are the definition node id (`layer`) or a slash-joined path through nested * instances (`nestedInstance/layer`). Exact canonical IDs take precedence over nested paths. * An address shadowed by an exact canonical ID is not exposed as an editable nested target. */ export declare const COMPONENT_SET_KEY = "componentSet"; export declare const VARIANT_KEY = "variant"; export declare const COMPONENT_PROPERTIES_KEY = "componentProperties"; export declare const EXPOSE_PROPERTIES_KEY = "exposeInstanceProperties"; export declare const HIDDEN_KEY = "hidden"; export declare const COMPONENT_DESCRIPTION_KEY = "componentDescription"; export declare const COMPONENT_DOCUMENTATION_KEY = "componentDocumentationLink"; export declare const OVERRIDE_ADDRESS_SEPARATOR = "/"; export declare const VARIANT_NAME_LIMIT = 64; export type ComponentVariantValues = Record; export interface ComponentVariantAxis { name: string; values: string[]; } export interface ComponentVariantSet { setId: string; name: string; variantIds: string[]; axes: ComponentVariantAxis[]; diagnostics: DocumentDiagnostic[]; } export type ComponentPropertyType = 'text' | 'boolean' | 'instanceSwap'; export interface ComponentPropertyDefinition { id: string; name: string; type: ComponentPropertyType; /** Override addresses inside the definition that the property writes. */ targets: string[]; /** Instance-swap properties may list component ids to offer first. */ preferredValues?: string[]; } export type InstanceOverrideField = 'name' | 'width' | 'height' | 'transform' | 'layout' | 'constraints' | 'definitionId' | `properties.${string}`; export interface InstanceOverride { /** Override address, or the instance's own definition id for size and direct properties. */ address: string; layerName: string; field: InstanceOverrideField; value: DocumentValue | undefined; /** A property written on the instance node itself rather than through `overrides`. */ direct: boolean; } export interface InstanceLayer { address: string; nodeId: string; name: string; kind: DocumentNodeKind; depth: number; /** Nested instance addresses crossed to reach the layer; empty for the definition's own layers. */ through: string[]; resolved: DocumentNode; definition: DocumentNode; overridden: boolean; } export interface InstanceProperty { id: string; definition: ComponentPropertyDefinition; /** Address prefix of the nested instance that exposes the property; empty for the definition's own. */ prefix: string; targets: string[]; value: DocumentValue; overridden: boolean; mixed: boolean; } export interface OverrideAddressEntry { address: string; nodeId: string; name: string; kind: DocumentNodeKind; parentAddress: string | null; } export interface ComponentSwapPlan { status: 'ready' | 'unchanged' | 'blocked'; instanceId: string; definitionId: string; /** Explicit definition-relative mapping handed to `swapInstance`; names are matched here, never in the engine. */ overrideTargets: Record; /** Override addresses with no compatible target in the new definition; dropped only on explicit request. */ unmatched: string[]; diagnostics: DocumentDiagnostic[]; } export declare const componentPropertyField: Readonly>; export declare function overrideAddressSegments(address: string): string[]; export declare function joinOverrideAddress(...segments: readonly string[]): string; /** * Every address an instance of `definitionId` can override: the definition's descendants and, through * each nested instance, its definition's descendants prefixed with the nested instance's address. */ export declare function definitionOverrideAddresses(document: DesignDocument, definitionId: string, options?: { nested?: boolean; }): OverrideAddressEntry[]; export declare function isComponentSet(node: DocumentNode | undefined | null): boolean; export declare function isVariantValues(value: unknown): value is ComponentVariantValues; export declare function variantValuesOf(node: DocumentNode | undefined | null): ComponentVariantValues | null; /** `Size=Large, State=Hover` becomes `{ Size: 'Large', State: 'Hover' }`; any other name is not a variant name. */ export declare function parseVariantName(name: string): ComponentVariantValues | null; export declare function formatVariantName(values: ComponentVariantValues): string; export declare function componentSetOf(document: DesignDocument, componentId: string): DocumentNode | null; export declare function describeComponentVariantSet(document: DesignDocument, setId: string): ComponentVariantSet; export declare function validateComponentSet(document: DesignDocument, setId: string): DocumentDiagnostic[]; export declare function findVariant(document: DesignDocument, set: ComponentVariantSet, values: ComponentVariantValues): string | null; /** The variant reached by changing one axis of an instance's current variant; other axes keep their values. */ export declare function variantSwitchTarget(document: DesignDocument, instanceId: string, axis: string, value: string): string | null; /** One container becomes the main component in place; any other selection is wrapped first, as in Figma. */ export declare function createComponentFromLayers(tx: DocumentTransaction, document: DesignDocument, nodeIds: readonly string[], allocateId: (sourceNodeId: string) => string, name?: string): string; /** Wraps sibling components in a component set; names in `Axis=Value` form keep their axes, others become `Property 1`. */ export declare function combineAsVariants(tx: DocumentTransaction, document: DesignDocument, componentIds: readonly string[], setId: string, name?: string): void; /** Duplicates a variant into its set below the existing variants and names it by its values. */ export declare function addVariant(tx: DocumentTransaction, document: DesignDocument, setId: string, sourceVariantId: string, allocateId: (sourceNodeId: string) => string, values: ComponentVariantValues, options?: { remapMetadata?: DocumentDuplicateMetadataRemapper; }): string; export declare function setVariantValues(tx: DocumentTransaction, document: DesignDocument, variantId: string, values: ComponentVariantValues): void; export declare function addVariantAxis(tx: DocumentTransaction, document: DesignDocument, setId: string, axis: string, defaultValue: string): void; export declare function renameVariantAxis(tx: DocumentTransaction, document: DesignDocument, setId: string, from: string, to: string): void; export declare function removeVariantAxis(tx: DocumentTransaction, document: DesignDocument, setId: string, axis: string): void; export declare function renameVariantValue(tx: DocumentTransaction, document: DesignDocument, setId: string, axis: string, from: string, to: string): void; /** Matches overrides to the new definition by address, then by unique layer name and kind; the engine receives the explicit result. */ export declare function planInstanceSwap(document: DesignDocument, instanceId: string, definitionId: string): ComponentSwapPlan; export declare function applyInstanceSwap(tx: DocumentTransaction, plan: ComponentSwapPlan, options?: { discardUnmatched?: boolean; }): void; export declare function planVariantSwitch(document: DesignDocument, instanceId: string, axis: string, value: string): ComponentSwapPlan; export declare function instanceLayers(document: DesignDocument, instanceId: string, options?: { nested?: boolean; }): InstanceLayer[]; export declare function listInstanceOverrides(document: DesignDocument, instanceId: string): InstanceOverride[]; export declare function setInstanceOverride(tx: DocumentTransaction, instanceId: string, address: string, patch: DocumentNodePatch): void; /** Resets one layer, or one field of one layer; a direct instance property is removed from the instance node. */ export declare function resetInstanceOverride(tx: DocumentTransaction, document: DesignDocument, instanceId: string, address: string, field?: InstanceOverrideField, direct?: boolean): void; export declare function resetInstanceSize(tx: DocumentTransaction, document: DesignDocument, instanceId: string): void; export declare function resetAllInstanceOverrides(tx: DocumentTransaction, instanceId: string, preserveProperties?: readonly string[]): void; /** Writes an instance's overrides into the shared definition and clears them; nested addresses become the nested instance's own overrides. */ export declare function pushOverridesToMainComponent(tx: DocumentTransaction, document: DesignDocument, instanceId: string): void; export declare function isComponentPropertyDefinition(value: unknown): value is ComponentPropertyDefinition; export declare function componentPropertyDefinitions(node: DocumentNode | undefined | null): ComponentPropertyDefinition[]; export declare function validateComponentProperties(document: DesignDocument, componentId: string): DocumentDiagnostic[]; /** Adds a property, or replaces the one with the same id. */ export declare function defineComponentProperty(tx: DocumentTransaction, document: DesignDocument, componentId: string, definition: ComponentPropertyDefinition): void; export declare function removeComponentProperty(tx: DocumentTransaction, document: DesignDocument, componentId: string, propertyId: string): void; /** The definition's own properties, then those exposed by nested instances, each read from the current overrides. */ export declare function instanceProperties(document: DesignDocument, instanceId: string): InstanceProperty[]; /** Writes the value as overrides on every target; a value equal to the definition's own removes the override instead. */ export declare function setInstanceProperty(tx: DocumentTransaction, document: DesignDocument, instanceId: string, property: InstanceProperty, value: DocumentValue): void; export declare function resetInstanceProperty(tx: DocumentTransaction, document: DesignDocument, instanceId: string, property: InstanceProperty): void; /** Instances whose definition is `componentId`, in document order; nested instances inside other definitions included. */ export declare function componentInstances(document: DesignDocument, componentId: string): string[]; /** The main component a canonical layer belongs to (itself for a component), or null outside any definition. */ export declare function mainComponentOf(document: DesignDocument, nodeId: string): string | null; export declare function validateDocumentComponents(document: DesignDocument): DocumentDiagnostic[]; /** Component authoring metadata is draft-only until a source component codec is declared. */ export declare function componentsSourceDiagnostics(after: DesignDocument, before: DesignDocument): DocumentDiagnostic[];