@mastergo/plugin-typings
Version:
2,029 lines (1,792 loc) • 72.1 kB
TypeScript
import { Properties, PropertiesHyphen } from 'csstype';
declare global {
namespace MGDSL {
interface MGDSLData {
/**
* 版本信息,遵循SemVer规则
*/
readonly version: string;
/**
* 框架类型
*/
framework: Framework;
readonly nodeMap: Record<NodeId, MGNode>;
readonly localStyleMap: StyleMap;
readonly fileMap: Record<FileId, MGDSLFile>;
root: MGLayerNode;
settings: DSLSettings;
entry: FileId;
/**
* 预览代码时所引入模块,需要将配置模型上的依赖模块引入
*/
importPath: ImportPath;
importType: 'GLOBAL' | 'IMPORT';
}
type ImportPath = {
name: string;
path: string;
type: 'script' | 'style';
importRule?: 'ALL' | 'DEFAULT' | 'NAMED';
}[];
// js dsl模板
interface JSDSLData extends MGDSLData {
/**
* 全局样式表
*/
globalStyleMap: {
[classId: string]: ClassStyle;
};
}
interface ReactDSLData extends JSDSLData {
readonly framework: 'REACT';
}
interface Vue3DSLData extends JSDSLData {
readonly framework: 'VUE3';
}
interface Vue2DSLData extends JSDSLData {
readonly framework: 'VUE2';
}
interface AndroidDSLData extends MGDSLData {
readonly framework: 'ANDROID';
/**
* 全局样式表
*/
globalStyleMap: {
[classId: string]: ClassStyle;
};
}
interface IOSDSLData extends MGDSLData {
readonly framework: 'IOS';
}
type Framework = 'REACT' | 'VUE2' | 'VUE3' | 'ANDROID' | 'IOS';
type TokenName = string;
type TokenVariable = string;
type TokenValue = MGDSL.StyleSet[keyof MGDSL.StyleSet];
/**
* 自定义样式
*/
type TokenItem = TokenCommonItem | TokenTextItem | TokenEffectItem;
type TokenCommonItem = {
id: string;
type: 'color' | 'padding' | 'border-radius' | 'border-width' | 'gap';
name: TokenName;
originName: string;
originAlias: string;
value: TokenValue;
variable: TokenVariable;
/**
* 是否是多段
*/
isMultiple?: boolean;
};
type TokenTextSubItemType = 'font' | 'fontfamily' | 'fontstyle' | 'fontsize' | 'lineheight' | 'decoration' | 'letterspacing';
type TokenTextItem = {
id: string;
type: 'text';
name: TokenName;
originName: string;
originAlias: string;
variable: TokenVariable;
textItems: Record<TokenTextSubItemType, TokenTextSubItem>;
};
type TokenTextSubItem = {
type: TokenTextSubItemType;
name: TokenName;
value: TokenValue;
};
type TokenEffectItem = {
id: string;
type: 'effect';
name: TokenName;
originName: string;
originAlias: string;
value: TokenValue;
variable: TokenVariable;
effectItems: Record<TokenEffectSubItemType, TokenEffectSubItem>;
};
type TokenEffectSubItemType = 'shadow' | 'filter' | 'backdropfilter';
type TokenEffectSubItem = {
type: TokenEffectSubItemType;
name: TokenName;
value: TokenValue;
};
/**
* TODO: 安卓自定义样式
*/
type AndroidStyleItem = any;
/**
* 自定义样式map
*/
type StyleMap = {
[styleId: string]: TokenItem | AndroidStyleItem;
};
/**
* 配置
*/
interface DSLSettings {
/**
* 是否使用自定义样式,默认为true
*/
useToken: boolean;
}
interface ClassStyle {
id: ClassId;
name: string;
scoped: boolean;
value: StyleSet;
// 伪类
pseudo?: 'HOVER' | 'ACTIVE' | 'FOCUS' | 'DISABLED';
/**
* css类型
* */
type: 'group' | 'class' | 'pseudo' | 'id' | 'attribute' | 'combinators';
}
type NodeId = LayerId | OperationId;
type LayerId = string;
type OperationId = string;
type MGNode = MGLayerNode | MGOperationNode;
interface MGLayerNode {
type: 'LAYER';
id: LayerId;
children: NodeId[];
name: string;
/**
* 图层在代码中的组件名
*/
componentName: string;
/**
* 图层实际类型名称 RECTANGLE TEXT FRAME...
*/
layerType: NodeType;
// 是否是蒙版
isMask: boolean;
// 是否隐藏
isVisible: boolean;
layout: NodeLayout;
style: CssNodeStyle | IOSNodeStyle | AndroidNodeStyle;
/**
* 是否是根元素
*/
isRoot: boolean;
parent?: NodeId;
/**
* 关联的文件
*/
relatedFile: FileId;
/**
* 是否拆分成新文件,默认false
*/
isNewFile?: boolean;
characters: string;
}
type DocumentationLink = {
url: string;
};
interface MGComponentNode extends MGLayerNode {
layerType: 'COMPONENT';
alias: string;
description: string;
documentationLinks: DocumentationLink[];
/**
* 是组件集子组件的话则存在
*/
componentSetId?: string;
componentSetDescription?: string;
componentSetDocumentationLinks?: DocumentationLink[];
}
interface MGInstanceNode extends MGLayerNode {
layerType: 'INSTANCE';
/**
* 实例的主组件Layer, 这里不开通用模型就不解析
*/
mainComponent?: LayerId;
description: string;
documentationLinks: DocumentationLink[];
componentSetDescription?: string;
componentSetDocumentationLinks?: DocumentationLink[];
}
interface MGCustomNode extends MGLayerNode {
layerType: 'CUSTOM';
tagName?: string;
props?: ComponentProp[];
imports: ImportItem[];
}
interface MGTextNode extends MGLayerNode {
characters: string;
}
type NodeType =
| 'GROUP'
| 'FRAME'
| 'RECTANGLE'
| 'TEXT'
| 'LINE'
| 'ELLIPSE'
| 'POLYGON'
| 'STAR'
| 'PEN'
| 'COMPONENT'
| 'COMPONENTSET'
| 'INSTANCE'
| 'BOOLEANOPERATION'
| 'SLICE'
| 'CONNECTOR'
| 'SECTION'
| 'CUSTOM'
| 'Input'
| 'TABLE'
| 'Select'
| 'Chart'
| 'TOGGLE'
| 'BUTTON'
| 'TREE'
| 'TEXTSHAPE'
/**
* 图层的布局信息
*/
interface NodeLayout {
/**
* 相对矩阵
*/
matrix?: Matrix;
width?: Dimension;
height?: Dimension;
/**
* 实际在画布渲染的宽 包括阴影外描边
*/
renderWidth?: Dimension;
/**
* 实际在画布渲染的高 包括阴影外描边
*/
renderHeight?: Dimension;
/**
* 自动布局
*/
autoLayout?: AutoLayout;
overflow?: 'HIDDEN' | 'VISIBLE';
/**
* 相对于父元素的布局
*/
relatedLayout?: AbsoluteLayout | RelatedAutoLayout;
}
/**
* 自动布局
*/
type AutoLayout = {
direction: 'COLUMN' | 'ROW';
layoutWrap: 'NO_WRAP' | 'WRAP';
// 轴距
itemSpacing: Dimension | 'AUTO';
// 交叉轴距, 只有在 layoutWrap = 'WRAP'时生效
crossAxisSpacing: Dimension | 'AUTO' | null;
paddingTop: Dimension;
paddingRight: Dimension;
paddingBottom: Dimension;
paddingLeft: Dimension;
/**
* 主轴对齐方式
*/
mainAxisAlignItems: AlignTypes;
/**
* 交叉轴对齐方式
*/
crossAxisAlignItems: Exclude<AlignTypes, 'SPACE_BETWEEN'>;
/**
* 仅当换行的时候,交叉轴的多行对齐方式
*/
crossAxisAlignContent: 'AUTO' | 'SPACE_BETWEEN';
/**
* 描边是否包含在布局内
*/
strokesIncludedInLayout: boolean;
itemReverseZIndex: boolean;
};
/**
* 绝对定位
*/
type AbsoluteLayout = {
type: 'ABSOLUTE';
bound: {
left?: Dimension;
right?: Dimension;
top?: Dimension;
bottom?: Dimension;
};
/**
* 包含外描边和阴影,实际渲染的bound
*/
renderBound: {
left?: Dimension;
right?: Dimension;
top?: Dimension;
bottom?: Dimension;
};
};
/**
* 相对于父元素的自动布局
*/
type RelatedAutoLayout = {
type: 'AUTO';
alignSelf: 'STRETCH' | 'INHERIT' | 'AUTO';
flexGrow: number;
};
type Matrix = [[number, number, number], [number, number, number]];
/**
* flex布局主轴
*/
type AlignTypes = 'START' | 'END' | 'CENTER' | 'SPACE_BETWEEN';
/**
* 尺寸单位
*/
type Dimension = {
type: 'PIXEL' | 'PERCENT' | 'CALC';
value: number | string;
};
interface NodeStyle {
/**
* 和localClassMap的key保持一致
*/
id: `style-${NodeId}`;
type: NodeStyleType;
disable?: boolean;
}
/**
* 分段样式
*/
type TextSegStyle = {
start: number;
end: number;
textStyleId: string;
textStyle: StyleSet;
};
interface CssNodeStyle extends NodeStyle {
/**
* css类名
*/
name: string;
/**
* UI样式
*/
value: StyleSet;
/**
* 布局样式
*/
layoutStyles: StyleSet;
/**
* key为属性名称
*/
attributes: Record<string, AttributeItem>;
/**
* 行内样式
*/
inlineStyles?: StyleSet;
/**
* 动态行内样式
*/
dynamicInlineStyles?: {
[key in keyof StyleSet]: string;
};
/**
* 文字分段样式
*/
textStyles?: TextSegStyle[];
/**
* 样式名数组
*/
classList?: ClassId[];
/**
* 标签名称
*/
tag?: 'IMG' | 'DIV' | 'TEXT' | 'BUTTON' | 'INPUT' | 'SLOT' | 'SVG' | 'OPTION';
/**
* 子选择器
*/
subSelectors?: Array<ClassStyle>;
/**
* 样式token关联
*/
styleTokenAlias?: {
backgroundTokenId?: string;
strokeColorTokenId?: string;
paddingTokenId?: string;
gapTokenId?: string;
crossGapTokenId?: string;
radiusTokenId?: string;
};
}
/**
* STATIC 静态属性
* DYNAMIC 动态属性
* METHOD 方法
* UNBIND 只定义,但没有使用的属性
*/
type Attribute = 'STATIC' | 'DYNAMIC' | 'METHOD' | 'UNBIND';
interface AttributeItem {
type: Attribute;
/**
* 属性名
*/
name: string;
/**
* 属性值或者是对应的函数名称
*/
value: string;
/**
* 参数类型
*/
valueType: keyof ComponentPropType;
/**
* 属性值的来源
*/
valueSource?: 'PROPS' | 'METHODS' | 'DATA';
/**
* 函数的表达式
*/
expression?: string;
/**
* 默认值
*/
defaultValue?: string | number | boolean;
/**
* 方法的传参
*/
arguments?: string[];
}
type IOSNodeStyle = NodeStyle;
interface AndroidNodeStyle extends NodeStyle {
/**
* android样式
*/
attributes: Record<string, string>;
/**
* 控件标签
*/
// eslint-disable-next-line
tag: 'View'
| 'Canvas'
| 'ImageView'
| 'TextView'
| 'EditText'
| 'Button'
| 'Spinner'
| 'RadioButton'
| 'CheckBox'
| 'androidx.recyclerview.widget.RecyclerView'
| 'ScrollView'
| 'HorizontalScrollView'
| 'androidx.constraintlayout.widget.ConstraintLayout'
| 'com.example.mapplication.utils.MSvg';
/**
* 关联的文件
*/
subFiles: AndroidFileType[];
/**
* 是否是slot
*/
slot: boolean;
/**
* 包路径
*/
package: string;
/**
* 溢出方向
*/
overflowDirection: number;
effect: any;
}
type AndroidFileType = AndroidXMLFile | AndroidJavaFile;
interface AndroidFile {
name: string;
type: string;
path: string;
}
interface AndroidXMLFile extends AndroidFile {
type: 'xml';
header: string;
footer: string;
content: AndroidXMLFileTag[];
}
interface AndroidXMLFileTag {
tag: string;
attributes: Record<string, string>;
children?: AndroidXMLFileTag[];
}
interface AndroidJavaFile extends AndroidFile {
type: 'java';
package: string;
imports: string[];
className: string;
variables: Record<string, string>;
}
interface AndroidKotlinFile extends AndroidFile {
type: 'kotlin';
package: string;
imports: string[];
className: string;
variables: Record<string, string>;
}
interface AndroidBitmapFile extends AndroidFile {
type: 'png' | 'jpeg';
imageRef: string;
}
interface StyleSet extends Properties<string | number>, PropertiesHyphen<string | number> {}
// style-class-xx
type ClassId = string;
type NodeStyleType = 'VIEW' | 'SVG' | 'IMAGE' | 'TEXT' | 'INPUT' | 'BUTTON' | 'SCROLLVIEW';
type AndroidTag = {
SVG: 'com.example.mapplication.utils.MSvg';
IMAGE: 'ImageView';
TEXT: 'TextView';
INPUT: 'EditText';
BUTTON: 'Button';
SELECT: 'Spinner';
RADIO: 'RadioButton';
CHECKBOX: 'CheckBox';
SCROLLVIEW: 'ScrollView';
LIST: 'androidx.recyclerview.widget.RecyclerView';
VIEW: 'androidx.constraintlayout.widget.ConstraintLayout';
};
/**
* 运算符
*/
type MGOperationNode = IfStatement | Iteration | Raw | TernaryExpression;
/**
* 条件判断
*/
interface IfStatement {
id: OperationId;
type: 'OPERATION';
operationType: 'If_STATEMENT';
// 表达式
condition: string;
consequent: {
type: 'MGNode' | 'EXPRESSION';
body: MGNode | string;
};
alternate: {
type: 'MGNode' | 'EXPRESSION';
body: MGNode | string;
};
}
/**
* 迭代器
*/
interface Iteration {
id: OperationId;
type: 'OPERATION';
operationType: 'ITERATOR';
// 迭代器的变量名
variable: string;
body: MGNode;
// 作为key的变量名,属于迭代变量中元素上的字段
key?: string;
}
/**
* 原始字符串
*/
interface Raw {
id: OperationId;
type: 'OPERATION';
operationType: 'RAW';
body: string;
}
/**
* 三目运算
*/
interface TernaryExpression {
id: OperationId;
type: 'OPERATION';
operationType: 'TERNARY_EXPRESSION';
condition: string;
trueExpression: {
type: 'MGNode' | 'EXPRESSION';
body: MGNode | string;
};
falseExpression: {
type: 'MGNode' | 'EXPRESSION';
body: MGNode | string;
};
}
type ImportItem = {
name: string;
path: string;
/**
* DEFAULT: import name from 'path'
* ALL: import * as name from 'path'
* NAMED: import { name } from 'path'
*/
type: 'DEFAULT' | 'ALL'; // | 'NAMED'
};
interface MGDSLFile {
id: FileId;
name: string;
entryLayerId: LayerId;
chunks: FileId[];
data: Record<string, Data>;
props: Record<string, Prop>;
methods: Record<string, Method>;
computed: Record<string, Computed>;
// 导入
imports: ImportItem[];
}
type FileId = string;
type ComponentPropType = {
STRING: string;
NUMBER: number;
BOOLEAN: boolean;
FUNCTION: string | MGLayerNode[];
OBJECT: Record<string, ComponentPropValue<keyof ComponentPropType>>;
ARRAY: ComponentPropValue<keyof ComponentPropType>[];
SLOT: string | MGLayerNode[];
};
type ComponentPropValue<T extends keyof ComponentPropType> = {
type: T;
value: ComponentPropType[T];
};
type ComponentPropItem<T extends keyof ComponentPropType> = {
/**
* 类型
*/
type: T;
/**
* 默认值,也可作为初始值使用
*/
defaultValue?: ComponentPropType[T];
/**
* 属性名,根据aliasName和originalName经过处理后的名称,用于最终的展示
*/
name: string;
};
type ComponentPropString = ComponentPropItem<'STRING'>;
type ComponentPropNumber = ComponentPropItem<'NUMBER'>;
type ComponentPropBoolean = ComponentPropItem<'BOOLEAN'>;
type ComponentPropFunction = ComponentPropItem<'FUNCTION'>;
type ComponentPropObject = ComponentPropItem<'OBJECT'>;
type ComponentPropArray = ComponentPropItem<'ARRAY'>;
type ComponentPropSlot = ComponentPropItem<'SLOT'>;
type ComponentProp =
| ComponentPropString
| ComponentPropNumber
| ComponentPropBoolean
| ComponentPropFunction
| ComponentPropObject
| ComponentPropArray
| ComponentPropSlot;
interface Method {
name: string;
args: Array<string>;
content: string;
returnValue?: string;
}
type DSLNumber = {
type: 'NUMBER';
/**
* 默认值,也可作为初始值使用
*/
defaultValue?: number | undefined;
name: string;
};
type DSLBoolean = {
type: 'BOOLEAN';
defaultValue?: boolean | undefined;
name: string;
};
type DSLString = {
type: 'STRING';
/**
* 默认值,也可作为初始值使用
*/
defaultValue?: string | undefined;
name: string;
};
type DSLFunction = {
type: 'FUNCTION';
defaultValue?: string | undefined;
name: string;
};
type DSLArray = {
type: 'ARRAY';
defaultValue?: Array<any> | undefined;
name: string;
};
type DSLObject = {
type: 'OBJECT';
/**
* 默认值,也可作为初始值使用
*/
defaultValue?: { [key: string]: any };
name: string;
};
type Data = DSLString | DSLNumber | DSLBoolean | DSLFunction | DSLArray | DSLObject;
type Prop = DSLString | DSLNumber | DSLBoolean | DSLFunction | DSLArray | DSLObject;
interface Computed {
name: string;
args: Array<string>;
content: string;
returnValue?: string;
dependencies?: Array<string>;
}
interface CustomCode {
type: 'custom';
data: {
title: string;
code: string;
// 暂时不设置类型
type: string;
}[];
}
}
}
declare global {
namespace MGTMP {
type RegExpString = string;
type PseudoType = 'HOVER' | 'ACTIVE' | 'FOCUS' | 'DISABLED';
/**
* 工具类样式,如:.flex-1 { flex: 1 }
* 通常为写死的样式,不会根据数据动态生成。当value与DSLToCode.StyleNode.value相同时,可以直接使用StyleRule.className作为DSLToCode.StyleNode.className
*/
type UtilityStyle = {
type: 'UTILITY';
className: string;
pseudo?: PseudoType;
value: Properties & PropertiesHyphen;
};
/**
* 配置类样式,如:.bg-color { background-color: var(--bg-color) },.bg-color:hover { background-color: var(--bg-color-hover) },
* 根据token的值按配置规则动态生成的样式。
*/
type ConfigStyle = {
type: 'CONFIG';
prefix: string;
output: (token: string, tokenNameWithoutPrefix: string) => UtilityStyle[];
};
type StyleRule = UtilityStyle | ConfigStyle;
type StyleTemplate = StyleRule[];
/**
* 组件属性类型
*/
type ComponentPropType = {
STRING: string;
NUMBER: number;
BOOLEAN: boolean;
FUNCTION: string | MGDSL.MGLayerNode[];
OBJECT: Record<string, MGDSL.ComponentPropValue<keyof ComponentPropType>>;
ARRAY: MGDSL.ComponentPropValue<keyof ComponentPropType>[];
SLOT: string | MGDSL.MGLayerNode[];
};
type GetValueType<T extends keyof ComponentPropType> = (
nodeId: MGDSL.LayerId,
nodeMap: Record<MGDSL.NodeId, MGDSL.MGNode>,
componentId?: string,
) => {
value: ComponentPropType[T] | undefined;
nodeMap: Record<string, MGDSL.MGLayerNode>;
};
type ComponentPropItem<T extends keyof ComponentPropType> = {
/**
* 类型
*/
type: T;
/**
* 默认值,也可作为初始值使用
*/
defaultValue?: ComponentPropType[T];
/**
* 该方法内部需要bridge函数支持,不适合在配置模板中使用,请尽量少的使用该函数作判断
*/
getValue?: GetValueType<T>;
/**
* 属性名,根据aliasName和originalName经过处理后的名称,用于最终的展示
*/
name: string;
/**
* 属性别名
*/
aliasName?: string;
/**
* 原始名称,区别于经过处理的name
*/
originalName?: string;
/**
* 属性枚举值对应关系。一般和aliasName配合使用,根据画布图层的属性值,映射到代码中的属性值
*/
aliasMap?: Record<string, ComponentPropType[T] | undefined>;
/**
* DSM属性枚举值对应关系
*/
dsmAlias?: Record<string, string>;
/**
* 组件库解析时,是否将大写属性值转换为小写
*/
lowerCase?: boolean;
/**
* 是否应用该属性
* @param aliasName 对应画布图层属性名,当前当前仅支持属性名的判断
* @param aliasMap 对应画布图层属性值
*/
visible?: {
aliasName: string;
aliasMap?: Record<string, boolean>;
};
};
/**
* 组件属性类型
* 泛型没有显式指定类型时,会被推断所有生命类型,起不到约束作用
*/
type ComponentPropString = ComponentPropItem<'STRING'> & {
/**
* 如果是string,允许已某个图层的content作为值
*/
nodePath?: SlotMatchType[];
};
type ComponentPropNumber = ComponentPropItem<'NUMBER'>;
type ComponentPropBoolean = ComponentPropItem<'BOOLEAN'>;
type ComponentPropFunction = ComponentPropItem<'FUNCTION'>;
type ComponentPropObject = ComponentPropItem<'OBJECT'>;
type ComponentPropArray = ComponentPropItem<'ARRAY'>;
type ComponentPropInstance = ComponentPropItem<'SLOT'> & {
/**
* react的INSTANCE视为Vue的SLOT效果,故这里提供nodePath属性,继续遍历图层并以此图层为属性内容
* 这里只能指向唯一图层才能向下遍历
*/
nodePath?: SlotMatchType[];
ignoreClass?: boolean;
};
/**
* 组件的虚拟路径,如:'@/components/xxx.vue'
* export default {} 为 DEFAULT
* export const xxx = {} 为 xxx
*/
type ComponentSource = {
path: string;
export: 'DEFAULT' | string;
};
/**
* 组件属性
* @param type 属性类型
* @param name 属性名称
* @param defaultValue 属性默认值
* @param aliasName 对应设计系统的组件别名,如能匹配则根据别名生成代码
*/
type ComponentProp =
| ComponentPropString
| ComponentPropNumber
| ComponentPropBoolean
| ComponentPropFunction
| ComponentPropObject
| ComponentPropArray
| ComponentPropInstance;
type ComponentData = {
name: string;
defaultValue: string | number | boolean;
type: keyof ComponentPropType;
};
type ComponentProps = {
name: string;
originalName?: string;
defaultValue?: string | number | boolean;
type: keyof ComponentPropType;
};
type SlotMatchType = RegExpString | number;
/**
* 组件插槽
* @param name 插槽名称
* @param relateNodeNames 关联的节点名称
*/
type ComponentSlot = {
name: string;
relateNodeNames: (SlotMatchType | SlotMatchType[])[];
ignoreClass?: boolean;
} & (
| { type?: '' }
| {
type: 'TEXT';
}
| {
type: 'CUSTOM';
// 返回MGDSL数据,id可为空
getValue: GetValueType<'SLOT'>;
}
);
/**
* 组件模板
* @param name 组件名称
* @param props 组件属性
* @param source 组件的虚拟路径
*/
type ComponentOrigin = {
name: string;
props: ComponentProp[];
slots?: ComponentSlot[];
source: ComponentSource;
ignoreRect?: boolean;
};
type ComponentItem = ComponentOrigin & { id: string; matchName?: string };
// 图标库
type Icons = {
/**
* 组件名适配正则
*/
reg: RegExpString;
getValue: (node: MGDSL.MGLayerNode) => MGDSL.MGCustomNode;
};
type ComponentTemplate = {
// 防止组件库解析,存储对应文件id
documentId: string;
// 暂时作为唯一标识
name: string;
/**
* 组件导入类型
* GLOBAL 全局引入
* IMPORT esm引入
*/
importType: 'GLOBAL' | 'IMPORT';
importPath: {
name: string;
importName: string;
path: string;
type: 'script' | 'style';
}[];
framework: 'VUE2' | 'VUE3' | 'REACT';
components: ComponentItem[];
icons?: Icons;
};
}
}
declare global {
/**
* @deprecated please use mg instead
*/
const mastergo: PluginAPI
const mg: PluginAPI
const console: Console
const __html__: string
function setTimeout(callback: Function, timeout: number): number
function clearTimeout(timeoutID: number): void
function setInterval(callback: Function, timeout: number): number
function clearInterval(timeoutID: number): void
function requestAnimationFrame(cb: (ts: number) => void): number
function cancelAnimationFrame(requestID: number): void
interface Console {
log(message?: any, ...optionalParams: any[]): void
error(message?: any, ...optionalParams: any[]): void
assert(condition?: boolean, message?: string, ...data: any[]): void
info(message?: any, ...optionalParams: any[]): void
warn(message?: any, ...optionalParams: any[]): void
clear(): void
}
interface ConfirmAction {
label: string
type: 'primary' | 'text'
action: () => void
}
interface PromptAction {
label: string
type: 'primary' | 'text'
action: (value: string) => void
}
interface Image {
readonly href: string
getBytesAsync(): Promise<Uint8Array>
}
type ThemeColor = 'dark' | 'light'
type LayoutInfo = {
leftbar: number;
rightbar: number;
canvas: number;
window: number;
height: number;
topbar: number;
}
type MGEventCallbackMap = {
'selectionchange': (selectionLayerIds: string[]) => void;
'layoutchange': (layoutInfo: LayoutInfo) => void;
'currentpagechange': (pageId: string) => void;
'themechange': (theme: ThemeColor) => void;
'drop': (event: DropEvent) => void;
'run': (command: { command: string }) => void;
'close': () => void;
'beforeReadyForDev': (sectionLayerId: string, callback: (setReady: boolean) => void) => void;
}
type PluginEventType = keyof MGEventCallbackMap
interface PluginAPI {
readonly document: DocumentNode
readonly ui: UIAPI
readonly themeColor: ThemeColor
readonly apiVersion: string
readonly documentId: number
readonly pluginId: number
readonly command: string
readonly mixed: string | symbol
readonly clientStorage: ClientStorageAPI
readonly currentUser: User | null
readonly viewport: ViewportAPI
/**
* @note only available in devMode
*/
readonly codegen?: CodegenAPI
readonly snippetgen?: SnippetgenAPI
readonly mode?: "inspect" | "design" | "codegen" | "snippetgen"
closePlugin(): void
on<T extends PluginEventType>(type: T, callback: MGEventCallbackMap[T]): void
once<T extends PluginEventType>(type: T, callback: MGEventCallbackMap[T]): void
off<T extends PluginEventType>(type?: T, callback?: MGEventCallbackMap[T]): void
commitUndo(): void
triggerUndo(): void
showUI(html: string, options?: ShowUIOptions): void
getNodeById<T extends SceneNode>(id: string): T | null
getNodeByPosition(position: { x: number, y: number }): SceneNode | null
createRectangle(): RectangleNode
createLine(): LineNode
createEllipse(): EllipseNode
createPolygon(): PolygonNode
createStar(): StarNode
createPen(): PenNode
createText(): TextNode
createFrame(children?: SceneNode[]): FrameNode
createComponent(children?: SceneNode[]): ComponentNode
createSection(): SectionNode
createPage(): PageNode
createSlice(): SliceNode
createConnector(): ConnectorNode
createNodeFromSvgAsync(svg: string): Promise<FrameNode>
combineAsVariants(nodes: ComponentNode[]): ComponentSetNode
getHoverLayer(): PageNode | SceneNode
/**
* @deprecated
* This function is deprecated, please use viewport.layoutGridVisible instead.
*/
showGrid(show: boolean): void
group(children: SceneNode[]): GroupNode
union(children: SceneNode[]): BooleanOperationNode
subtract(children: SceneNode[]): BooleanOperationNode
intersect(children: SceneNode[]): BooleanOperationNode
exclude(children: SceneNode[]): BooleanOperationNode
flatten(nodes: SceneNode[]): PenNode | null
saveVersionHistoryAsync(desc: string, title?: string): Promise<void>
notify(message: string, options?: NotifyOptions): NotificationHandler
getStyleById(id: string): Style | null
getStyleCodeById(id: string, options?: StyleCodeOptions): CodeString | null
getWebStyleCodeById(id: string, options?: WebStyleCodeOptions): CodeString | null
getAndroidStyleCodeById(id: string, options?: AndroidStyleCodeOptions): CodeString | null
getIOSStyleCodeById(id: string, options?: IOSStyleCodeOptions): CodeString | null
getTitleByFontFamilyAndStyle(fontFamily: string, fontStyle: string): FontAlias | null
createFillStyle(config: CreateStyleConfig): PaintStyle
createEffectStyle(config: CreateStyleConfig): EffectStyle
createTextStyle(config: CreateStyleConfig): TextStyle
createGridStyle(config: CreateStyleConfig): GridStyle
createCornerRadiusStyle(config: CreateStyleConfig): CornerRadiusStyle
createPaddingStyle(config: CreateStyleConfig): PaddingStyle
createSpacingStyle(config: CreateStyleConfig): SpacingStyle
/**
* @deprecated please use createStrokeFillStyle instead
*/
createStrokeStyle(config: CreateStyleConfig): PaintStyle
createStrokeFillStyle(config: CreateStyleConfig): PaintStyle
createStrokeWidthStyle(config: CreateStyleConfig): StrokeWidthStyle
/**
* createFillStyle/createStrokeFillStyle 这些函数的聚合函数,传入不同的 type,返回对应的 style
* @param layerId
* @param type NodeStyleType
* @param styleName
* @param description optional
*/
createStyleByLayer<T extends NodeStyleType>(layerId: string, type: T, styleName: string, description?: string): NodeStyleReturnType<T>
/**
* 创建一个新的默认样式,不依赖某一个图层中的样式,
* eg: createStyle('PAINT', 'New Style', 'This is a new style')
* @param type styleType
* @param styleName
* @param description optional
*/
createStyle<T extends StyleType>(type: T, styleName: string, description?: string): StyleReturnType<T>
/**
* 创建某一个样式的副本
* @param sourceStyleId 副本的源样式id
* @param type
* @param styleName
* @param description
*/
createStyleCopy<T extends StyleType = "PAINT">(sourceStyleId: string, styleName?: string, description?: string): StyleReturnType<T>
getLocalPaintStyles(): PaintStyle[]
getLocalEffectStyles(): EffectStyle[]
getLocalTextStyles(): TextStyle[]
getLocalGridStyles(): GridStyle[]
getLocalStrokeWidthStyles(): StrokeWidthStyle[]
getLocalCornerRadiusStyles(): CornerRadiusStyle[]
getLocalPaddingStyles(): PaddingStyle[]
getLocalSpacingStyles(): SpacingStyle[]
listAvailableFontsAsync(): Promise<Font[]>
loadFontAsync(fontName: FontName): Promise<boolean>
createImage(imageData: Uint8Array, isSync?: boolean): Promise<Image>
getImageByHref(href: string): Image
getTeamLibraryAsync(): Promise<TeamLibrary>,
importComponentByKeyAsync(ukey: string): Promise<ComponentNode>,
importComponentSetByKeyAsync(ukey: string): Promise<ComponentSetNode>,
importStyleByKeyAsync(ukey: string): Promise<Style>,
/**
* @deprecated
*
* This attribute is deprecated, please use getTeamLibraryAsync instead.
*/
teamLibrary: TeamLibrary,
hexToRGBA(hex: string): RGBA
RGBAToHex(rgba: RGBA): string
confirm: (message: string, options: [ConfirmAction, ...ConfirmAction[]]) => void
prompt: (message: string, defaultValue: string, options: [PromptAction, ...PromptAction[]]) => void
}
interface User {
id: string | null
name: string | 'Anonymous'
photoUrl: string | null
}
interface Rect extends Readonly<Bound> { }
interface NotificationHandler {
cancel: () => void
}
interface Layout {
canvas: number
leftbar: number
rightbar: number
window: number
}
interface PositionOnDom {
width: number
height: number
x: number
y: number
}
interface ViewportAPI {
center: Vector
zoom: number
readonly bound: Rect
/**
* @deprecated
*/
readonly layout: Layout
readonly positionOnDom: PositionOnDom
rulerVisible: boolean
layoutGridVisible: boolean
scrollAndZoomIntoView(nodes: SceneNode[]): void
}
interface ClientStorageAPI {
getAsync(key: string): Promise<any | undefined>
setAsync(key: string, value: any): Promise<void>
deleteAsync(key: string): Promise<void>
keysAsync(): Promise<string[]>
}
type ShowUIOptions = {
width?: number
height?: number
visible?: boolean
x?: number | string
y?: number | string
}
interface ExportSettingsConstraints {
type: 'SCALE' | 'WIDTH' | 'HEIGHT'
value: number
}
interface ExportSettingsImage {
readonly format: 'JPG' | 'PNG' | 'WEBP'
readonly isSuffix?: boolean
readonly fileName?: string
readonly constraint?: ExportSettingsConstraints
readonly useAbsoluteBounds?: boolean // defaults to true
readonly useRenderBounds?: boolean // default to true
}
interface ExportSettingsSVG {
readonly format: 'SVG'
readonly isSuffix?: boolean
readonly fileName?: string
}
interface ExportSettingsPDF {
readonly format: 'PDF'
readonly isSuffix?: string
readonly fileName?: string
readonly useAbsoluteBounds?: boolean // defaults to true
readonly useRenderBounds?: boolean // default to true
}
type ExportSettings = ExportSettingsImage | ExportSettingsSVG | ExportSettingsPDF
interface ExportMixin {
exportSettings: ReadonlyArray<ExportSettings>
export(settings?: ExportSettings): Uint8Array | string // Defaults to PNG format
exportAsync(settings?: ExportSettings): Promise<Uint8Array | string>
}
interface NotifyOptions {
position?: 'top' | 'bottom'
type?: 'normal' | 'highlight' | 'error' | 'warning' | 'success'
timeout?: number
isLoading?: boolean
}
type CodeType = 'Web' | 'iOS' | 'Android'
type WebCodeLang = 'css' | 'less' | 'sass'
type AndroidCodeLang = 'xml'
type IOSCodeLang = 'swift'
type CodeLang = WebCodeLang | AndroidCodeLang | IOSCodeLang
type WebCodeUnit = 'px' | 'rem' | 'rpx'
type AndroidCodeUnit = 'dp' | 'dp/sp'
type IOSCodeUnit = 'pt'
type CodeUnit = WebCodeUnit | AndroidCodeUnit | IOSCodeUnit
interface StyleCodeOptions {
codeType?: CodeType
codeLang?: CodeLang
unit?: CodeUnit
pixelRatio?: number
}
interface WebStyleCodeOptions {
codeLang?: WebCodeLang
unit?: WebCodeUnit
pixelRatio?: number
}
interface AndroidStyleCodeOptions {
pixelRatio?: number
}
interface IOSStyleCodeOptions {
pixelRatio?: number
}
type CodeData = {
layout?: string;
style?: string;
typography?: string;
other?: string;
}
interface CodeString {
type: 'CSS' | 'iOS' | 'Android'
data: CodeData | ''
}
interface UIViewport extends Bound {
readonly headerHeight: number
readonly visible: boolean
}
interface UIAPI {
show(): void
hide(): void
close(): void
resize(width: number, height: number): void
moveTo(x: number, y: number): void
viewport: UIViewport
postMessage(pluginMessage: any, origin?: string): void
onmessage: ((pluginMessage: any, origin: string) => void) | undefined
}
type PublishStatus = 'UNPUBLISHED' | 'CURRENT' | 'CHANGED'
interface DocumentationLink {
readonly uri: string
}
interface PublishableMixin {
description: string
documentationLinks: ReadonlyArray<DocumentationLink>
/**
* @description 组件或者组件集的别名
*/
alias: string
/**
* @description 是否为团队库组件/样式
*/
readonly isExternal: boolean
readonly ukey: string
readonly publishStatus: PublishStatus
}
// Styles
type StyleType = 'PAINT' | 'TEXT' | 'EFFECT' | 'GRID' | 'STROKE_WIDTH' | 'CORNER_RADIUS' | 'PADDING' | 'SPACING'
type NodeStyleType = 'fill' | 'strokeFill' | 'strokeWidth' | 'cornerRadius' | 'padding' | 'spacing'
interface BaseStyle extends Omit<PublishableMixin, 'documentationLinks'> {
readonly id: string
readonly type: StyleType
name: string
remove(): void
}
interface PaintStyle extends BaseStyle {
type: 'PAINT'
paints: ReadonlyArray<Paint>
}
interface StrokeWidthStyle extends BaseStyle {
type: 'STROKE_WIDTH'
value: StrokeWidth
}
interface CornerRadiusStyle extends BaseStyle {
type: 'CORNER_RADIUS'
value: CornerRadius
}
interface PaddingStyle extends BaseStyle {
type: 'PADDING'
value: Padding
}
interface SpacingStyle extends BaseStyle {
type: 'SPACING'
value: Spacing
}
interface NumValue {
value: number
unit: 'PIXELS' | 'PERCENT'
}
interface TextSegStyle {
start: number
end: number
textStyleId: string
textStyle: {
fontName: FontName
localizedFontName: FontName
referrer: FontReferrer
fontSize: number
letterSpacing: LetterSpacing
lineHeight: LineHeight
lineHeightByPx: number
textDecoration: TextDecoration
textCase: TextCase
fontWeight: number
}
fills: Paint[]
fillStyleId: string
}
interface ListStyle {
start: number
end: number
level: number
type: 'ORDERED' | 'BULLETED' | 'NONE'
}
interface EffectStyle extends BaseStyle {
type: 'EFFECT'
effects: ReadonlyArray<Effect>
}
interface TextStyle extends BaseStyle {
type: 'TEXT'
decoration: TextDecoration
fontSize: number
letterSpacing: number
letterSpacingUnit: NumValue['unit']
textCase: TextCase
lineHeight: LineHeight
fontName: FontName
}
interface FontAlias {
title: string
subtitle: string
}
interface GridStyle extends BaseStyle {
type: 'GRID'
layoutGrids: ReadonlyArray<LayoutGrid>
}
type Style = PaintStyle | EffectStyle | TextStyle |
GridStyle | StrokeWidthStyle | CornerRadiusStyle |
PaddingStyle | SpacingStyle
/// /////////////////////////////////////////////////////////////////////////////
// Datatypes
type Transform = [[number, number, number], [number, number, number]]
interface Vector {
readonly x: number
readonly y: number
}
interface RGB {
readonly r: number
readonly g: number
readonly b: number
}
interface RGBA {
readonly r: number
readonly g: number
readonly b: number
readonly a: number
}
interface FontName {
readonly family: string
readonly style: string
}
type TextCase = 'ORIGINAL' | 'UPPER' | 'LOWER' | 'TITLE';
type TextDecoration = 'NONE' | 'UNDERLINE' | 'STRIKETHROUGH'
interface ShadowEffect {
readonly type: 'DROP_SHADOW' | 'INNER_SHADOW'
readonly color: RGBA
// Effect的 x, y;
readonly offset: Vector
readonly spread: number
readonly radius: number
readonly isVisible: boolean
readonly blendMode: BlendMode
readonly showShadowBehindNode: boolean
readonly isEffectShow: boolean
}
interface BlurEffect {
readonly type: 'LAYER_BLUR' | 'BACKGROUND_BLUR'
readonly radius: number
readonly isVisible: boolean
readonly blendMode: BlendMode
}
type Effect = ShadowEffect | BlurEffect
// 待确认
type ConstraintType = 'START' | 'END' | 'STARTANDEND' | 'CENTER' | 'SCALE'
interface Constraints {
readonly horizontal: ConstraintType
readonly vertical: ConstraintType
}
interface ColorStop {
readonly position: number
readonly color: RGBA
}
interface SolidPaint {
readonly type: 'SOLID'
readonly color: RGBA
readonly isVisible?: boolean
/**
* It always be 1 when type is 'SOLID', please modify the alpha field in color instead.
* 纯色模式下alpha始终为1, 请设置color中的alpha.
*/
readonly alpha?: number
readonly blendMode?: BlendMode
readonly name?: string
}
interface GradientPaint {
readonly type:
| 'GRADIENT_LINEAR'
| 'GRADIENT_RADIAL'
| 'GRADIENT_ANGULAR'
| 'GRADIENT_DIAMOND'
readonly transform: Transform
readonly gradientStops: ReadonlyArray<ColorStop>
readonly gradientHandlePositions?: [{ x: number, y: number }, { x: number, y: number }];
readonly isVisible?: boolean
readonly alpha?: number
readonly blendMode?: BlendMode
readonly name?: string
}
interface ImageFilters {
exposure?: number
contrast?: number
saturation?: number
temperature?: number
tint?: number
highlights?: number
shadows?: number
hue?: number
}
interface ImagePaint {
readonly type: 'IMAGE'
readonly imageRef: string
readonly scaleMode?: 'FILL' | 'TILE' | 'STRETCH' | 'FIT' | 'CROP'
readonly filters?: ImageFilters
readonly isVisible?: boolean
readonly alpha?: number
readonly blendMode?: BlendMode
readonly name?: string
readonly ratio?: number
readonly rotation?: number
}
type Paint = SolidPaint | GradientPaint | ImagePaint
type CSSWidthSetter = number | [number, number] | [number, number, number] | [number, number, number, number]
interface StrokeWidth {
width: CSSWidthSetter,
}
interface Padding {
padding: CSSWidthSetter,
}
interface Spacing {
spacing: CSSWidthSetter,
}
interface CornerRadius {
cornerRadius: CSSWidthSetter,
}
type WindingRule = 'Nonzero' | 'Evenodd'
// 待确定
interface VectorVertex {
readonly x: number
readonly y: number
readonly strokeCap?: StrokeCap
readonly cornerRadius?: number
}
// 待确定
interface VectorRegion {
readonly windingRule: WindingRule
readonly loops: ReadonlyArray<VectorPaths>
}
interface VectorCtrl {
x: number
y: number
}
type LetterSpacing = {
readonly value: number
readonly unit: 'PIXELS' | 'PERCENT'
}
type LineHeight =
| {
readonly value: number
readonly unit: 'PIXELS' | 'PERCENT'
}
| {
readonly unit: 'AUTO'
}
type BlendMode =
| 'NORMAL'
| 'DARKEN'
| 'MULTIPLY'
| 'COLOR_BURN'
| 'LIGHTEN'
| 'SCREEN'
| 'COLOR_DODGE'
| 'OVERLAY'
| 'SOFT_LIGHT'
| 'HARD_LIGHT'
| 'DIFFERENCE'
| 'EXCLUSION'
| 'HUE'
| 'SATURATION'
| 'COLOR'
| 'LUMINOSITY'
| 'PLUS_DARKER'
| 'PLUS_LIGHTER'
| 'PASS_THROUGH'
type FontReferrer = 'team' | 'org' | 'local' | 'official'
interface Font {
fontName: FontName
localizedFontName: FontName
referrer: FontReferrer
}
/// /////////////////////////////////////////////////////////////////////////////
// Mixins
interface BaseNodeMixin {
readonly id: string
readonly parent: (BaseNode & ChildrenMixin) | null
name: string
removed: boolean
remove(): void
getPluginData(key: string): string
setPluginData(key: string, value: string): void
getPluginDataKeys(): string[]
removePluginData(key: string): void
clearPluginData(): void
getSharedPluginData(namespace: string, key: string): string
setSharedPluginData(namespace: string, key: string, value: string): void
getSharedPluginDataKeys(namespace: string): string[]
removeSharedPluginData(namespace: string, key: string): void
clearSharedPluginData(namespace: string): void
}
interface SceneNodeMixin {
isVisible: boolean
isLocked: boolean
readonly attachedConnectors: ConnectorNode[]
componentPropertyReferences: {
isVisible?: string,
characters?: string,
mainComponent?: string
} | null
slotInfo: { slotName: string; slotAlias: string } | null
}
interface ChildrenMixin<ChildrenNode = SceneNode> {
readonly children: ReadonlyArray<ChildrenNode>
appendChild(child: SceneNode): void
insertChild(index: number, child: SceneNode): void
findChildren(
callback?: (node: SceneNode) => boolean
): ReadonlyArray<SceneNode>
findChild(callback: (node: SceneNode) => boolean): SceneNode | null
findAll(callback?: (node: SceneNode) => boolean): ReadonlyArray<SceneNode>
findOne(callback: (node: SceneNode) => boolean): SceneNode | null
findAllWithCriteria<T extends NodeType[]>(criteria: { types: T }): Array<{ type: T[number] } & SceneNode>
}
interface ConstraintMixin {
constraints: Constraints
}
interface Bound {
x: number
y: number
width: number
height: number
}
type ScaleCenter = 'TOPLEFT' | 'TOP' | 'TOPRIGHT' | 'LEFT' | 'CENTER' | 'RIGHT' | 'BOTTOMLEFT' | 'BOTTOM' | 'BOTTOMRIGHT'
interface ScaleOption {
scaleCenter?: ScaleCenter
}
interface LayoutMixin {
absoluteTransform: Transform
relativeTransform: Transform
readonly absoluteRenderBounds: Bound | null
readonly absoluteBoundingBox: Bound
bound: Bound
x: number
y: number
width: number
height: number
minWidth: number | null
maxWidth: number | null
minHeight: number | null
maxHeight: number | null
rotation: number // In degrees
constrainProportions: boolean
layoutPositioning: 'AUTO' | 'ABSOLUTE' // applicable only inside auto-layout frames
alignSelf: 'STRETCH' | 'INHERIT' // applicable only inside auto-layout frames
flexGrow: 0 | 1 // applicable only inside auto-layout frames
rescale(scale: number, scaleOption?: ScaleOption): void
scaleFactor: number // The default value is 1
flip(direction: 'VERTICAL' | 'HORIZONTAL'): void
}
interface BlendMixin {
opacity: number
blendMode: BlendMode
isMask: boolean
isMaskOutline: boolean
isMaskVisible: boolean
effects: ReadonlyArray<Effect>
effectStyleId: string
}
type StrokeCap = 'NONE' | 'ROUND' | 'SQUARE' | 'LINE_ARROW' | 'TRIANGLE_ARROW' | 'ROUND_ARROW' | 'RING' | 'DIAMOND' | 'LINE'
type StrokeJoin = 'MITER' | 'BEVEL' | 'ROUND'
type StrokeAlign = 'CENTER' | 'INSIDE' | 'OUTSIDE'
type DashCap = 'NONE' | 'ROUND' | 'SQUARE'
type StrokeStyle = 'SOLID' | 'DASH' | 'CUSTOM'
type ConnectorStrokeCap = StrokeCap
interface ConnectorEndpointPosition {
readonly position: { x: number; y: number }
}
interface ConnectorEndpointConnected {
readonly position: { x: number; y: number }
readonly endpointNodeId: string
readonly magnet: 'TOP' | 'LEFT' | 'BOTTOM' | 'RIGHT'
}
type ConnectorEndpoint =
| ConnectorEndpointPosition
| ConnectorEndpointConnected
interface GeometryMixin {
fills: ReadonlyArray<Paint>
strokes: ReadonlyArray<Paint>
strokeWeight: number
strokeAlign: StrokeAlign
strokeCap: StrokeCap
strokeJoin: StrokeJoin
strokeStyle: StrokeStyle
dashCap: DashCap
strokeDashes: ReadonlyArray<number>
fillStyleId: string
/**
* @deprecated please use strokePaintStyleId instead
*/
strokeStyleId: string
strokeFillStyleId: string
strokeWidthStyleId: string
paddingStyleId: string
spacingStyleId: string
cornerRadiusStyleId: string
/**
* You have to ensure the layer has stroke before invoking this method.
* 在调用接口之前需要确保layer有描边.
*/
outlineStroke(): SceneNode | null
}
interface RectangleStrokeWeightMixin {
strokeTopWeight: number
strokeLeftWeight: number
strokeBottomWeight: number
strokeRightWeight: number
}
interface CornerMixin {
cornerSmooth: number
cornerRadius: number | PluginAPI['mixed']
topLeftRadius: number
topRightRadius: number
bottomLeftRadius: number
bottomRightRadius: number
}
interface DefaultShapeMixin
extends BaseNodeMixin,
SceneNodeMixin,
BlendMixin,
GeometryMixin,
LayoutMixin,
ReactionMixin,
ExportMixin { }
interface DefaultContainerMixin
extends BaseNodeMixin,
ContainerMixin,
ReactionMixin,
SceneNodeMixin,
ChildrenMixin,
BlendMixin,
CornerMixin,
ConstraintMixin,
LayoutMixin,
ExportMixin { }
interface ContainerMixin {
expanded: boolean
}
interface AutoLayout {
flexMode: 'NONE' | 'HORIZONTAL' | 'VERTICAL'
flexWrap: 'WRAP' | 'NO_WRAP'
itemSpacing: number
mainAxisAlignItems: 'FLEX_START' | 'FLEX_END' | 'CENTER' | 'SPACING_BETWEEN'
crossAxisAlignItems: 'FLEX_START' | 'FLEX_END' | 'CENTER'
mainAxisSizingMode: 'FIXED' | 'AUTO'
crossAxisSizingMode: 'FIXED' | 'AUTO'
crossAxisAlignContent: 'AUTO' | 'SPACE_BETWEEN'
crossAxisSpacing: number | null
strokesIncludedInLayout: boolean
itemReverseZIndex: boolean
paddingTop: number
paddingRight: number
paddingBottom: number
paddingLeft: number
}
interface RowsColsLayoutGrid {
readonly gridType: "ROWS" | "COLUMNS"
readonly alignment: "LEFT" | "RIGHT" | "STRETCH" | "CENTER"
readonly gutterSize: number
readonly count: number
readonly sectionSize?: number | null
readonly offset?: number
readonly isVisible?: boolean
readonly color?: RGBA
readonly id?: string
readonly name?: string
}
interface GridLayoutGrid {
readonly gridType: "GRID"
readonly sectionSize: number
readonly isVisible?: boolean
readonly color?: RGBA
readonly id?: string
readonly name?: string
}
type LayoutGrid = RowsColsLayoutGrid | GridLayoutGrid
interface FrameContainerMixin extends AutoLayout {
clipsContent: boolean
layoutGrids: ReadonlyArray<LayoutGrid>
gridStyleId: string
overflowDirection: OverflowDirection
}
type OverflowDirection = "NONE" | "HORIZONTAL" | "VERTICAL" | "BOTH"
interface ReactionMixin {
reactions: ReadonlyArray<Reaction>
}
interface OpaqueNodeMixin extends BaseNodeMixin, SceneNodeMixin, ExportMixin {
readonly absoluteTransform: Transform
readonly relativeTransform: Transform
readonly absoluteRenderBounds: Bound | null
readonly absoluteBoundingBox: Bound
x: number
y: number
readonly width: number
readonly height: number
readonly bound: Bound
}
interface MinimalBlendMixin {
opacity: number
blendMode: BlendMode
}
interface MinimalStrokesMixin {
strokes: ReadonlyArray<Paint>
strokeStyleId: string
strokeWeight: number
strokeJoin: StrokeJoin
strokeAlign: StrokeAlign
strokeStyle: StrokeStyle
strokeCap: StrokeCap
strokeDashes: ReadonlyArray<number>
dashCap: DashCap
}
interface MinimalFillsMixin {
fills: ReadonlyArray<Paint>
fillStyleId: string
}
/// /////////////////////////////////////////////////////////////////////////////
// Nodes
interface DocumentNode {
readonly type: 'DOCUMENT'
readonly id: string
name: string
currentPage: PageNode
readonly children: Read