/** 百分比 */ export type Percentage = `${number}%` /** 计量原语 */ export type Unit = | number // 根据情况,大多数情况下被作为逻辑像素使用 | Percentage /** 对称策略 */ export interface Symmetric { vertical?: T horizontal?: T } /** 四边策略 */ export interface Direction { left?: T right?: T top?: T bottom?: T } /** 四角策略 */ export interface Corners { topLeft?: T // 左上角 topRight?: T // 右上角 bottomLeft?: T // 左下角 bottomRight?: T // 右下角 } /** * 线性渐变 * * 不支持 sweep 和 radial 风格。 * * 属性 stops 要么不设置,要么其数量必须与 colors 的数量一致。 */ export interface Gradient { /** 渐变角度 */ angle?: string /** 颜色组,至少 2 个颜色值 */ colors: string[] /** 颜色停顿位置组 */ stops?: number[] /** 是否重复渲染 */ repeatable?: boolean } /** 边距,用于内外边距 */ export type EdgeInsets = | Direction // 四边 | Symmetric // 对称 | Unit | 'auto' // 原语 /** 边框样式 */ export type BorderStyle = | 'solid' | 'dashed' | 'dotted' | 'double' | 'groove' | 'ridge' | 'outset' | 'inset' | 'none' /** 边框的边 */ export interface BorderSide { color?: string style?: BorderStyle width?: number } /** 边框 */ export type Border = | Direction // 四边 | Symmetric // 对称 | BorderSide // 统一设置 /** 圆角原语 */ export type RadiusPrimitive = | number | [number, number] /** 圆角双值 */ export type RadiusDouble = [ RadiusPrimitive, RadiusPrimitive, ] /** 圆角 */ export type Radius = | Corners | RadiusPrimitive | RadiusDouble /** 阴影 */ export interface Shadow { x: number y: number blur?: number spread?: number color: string inset?: boolean } /** * 主轴对齐方式(子元素布局方向) * * 用于 Flex 布局,对应 CSS 属性 justify-content 的值。 */ export type MainAlign = | 'start' // 左对齐,默认值 | 'end' // 右对齐 | 'center' // 居中 | 'between' // 两端对齐,项目之间的间隔都相等。 | 'around' // 每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。 /** * 交叉轴对齐方式(与主轴垂直的方向) * * 用于 Flex 布局,对应 CSS 属性 align-items 的值。 */ export type CrossAlign = | 'start' // 交叉轴的起点对齐。 | 'end' // 交叉轴的终点对齐。 | 'center' // 交叉轴的中点对齐。 | 'baseline' // 项目的第一行文字的基线对齐。 | 'stretch' // 默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。 /** 文本方向 */ export type TextAlign = | 'left' | 'center' | 'right' /** * 描述主轴方向 * * x - 横轴 * y - 纵轴 */ export type Axis = 'x' | 'y' export type Attach = { [p in keyof Data]: Data[p] | Append } /** * 文本 * * 描述与文本外观相关的属性 */ export interface Textual { /** 文本颜色 */ textColor?: string /** 字体大小 */ fontSize?: number /** 字体粗细 */ fontWeight?: 400 | 500 | 600 | 700 | 800 | 900 /** 文本方向 */ textAlign?: TextAlign /** 行高,行高比较特殊,需要转换单位 */ lineHeight?: number | Percentage | string } /** * 弹性布局策略 * * 描述与弹性布局相关的属性 */ export interface Flexible { /** * 主轴方向,对应 CSS 属性 flex-direction。 * 如果值为 'x' 表示 `row`;值为 'y' 表示 `column`。 */ axis?: Axis /** 主轴对齐方式 */ mainAlign?: MainAlign /** 交叉轴对齐方式 */ crossAlign?: CrossAlign /** 是否自动换行 */ wrap?: boolean /** * 子组件间隔 * * 当值未数组时: * * - 第一个值表示水平方向上子视图的间隔; * - 第二个值表示垂直方向上的子视图间隔。 */ gap?: number | [number, number] } /** * 装饰策略 * * 描述与视图外观相关的属性 */ export interface Decoration { /** 组件颜色,背景颜色 */ color?: string /** 组件图片,背景图片 */ image?: string /** 组件边框 */ border?: Border /** 组件圆角 */ radius?: Radius /** 组件阴影效果 */ shadow?: Shadow | Shadow[] /** 组件渐变,背景渐变 */ gradient?: Gradient } /** * 盒子模型块级元素或行级块元素 * */ export interface BoxBlock { display?: 'block' | 'inline-block' | 'flex' whiteSpace?: 'nowrap' | 'pre' } /** * 空间分配策略 * * 能够用在弹性布局子视图上的属性 */ export interface Spatial { /** 当组件作为 Flex 的子组件时,视图在主轴方向上的初始大小 */ basis?: number /** 在 Flex 布局下的增长系数,对应 flex-grow */ grow?: number /** 在 Flex 布局下的收缩规则 */ shrink?: number } /** * 盒子策略 * * 描述与盒子模型相关的属性 */ export interface Boxed { /** 组件内边距 */ padding?: EdgeInsets /** 组件外边距 */ margin?: EdgeInsets /** 组件宽度,若在 Flex 布局下可能会被作为主轴方向上的初始大小 */ width?: number | Percentage | 'auto' /** 组件高度,若在 Flex 布局下可能会被作为主轴方向上的初始大小 */ height?: number | Percentage | 'auto' } export type ViewPosition = | "absolute" | "fixed" | "relative" | "static" | "sticky" export interface Stacked extends Direction { position?: ViewPosition zIndex?: number } // /** // * 相关框架组件 // * // * 建议尽量使用业务组件。 // */ // export interface Widget { // /** 组件名称 */ // name: string // /** 组件属性 */ // props?: Record // /** 相关插槽,不包括默认插槽 */ // slots?: Omit // } /** * 内容超出视图的剪切行为 */ export type ClipBehavior = | 'hidden' | 'visible' | 'auto' | 'autoX' // overflow-x: auto; overflow-y: hidden | 'autoY' // overflow-y: hidden; overflow-y: auto /** * 视图数据 * * 描述了视图的基本布局和外观表现。 */ export interface Theme extends Textual, Flexible, BoxBlock, Boxed, Decoration, Spatial, Flexible, Stacked { /** * 是否强制开启弹性布局 * * 当未给出该属性时,如果指定了 Flexible 中的属性,引擎会自动启用弹性布局。 */ flexible?: boolean /** * 超出视图剪切方式 * * 对应 overflow 属性 */ clip?: ClipBehavior } export type DynamicTheme = Attach export type DynamicValue = T | `@@${string}` export type ToStatic = (v: DynamicValue) => T /** 文本配置引用 */ export interface TextRefer { /** 标识为文本专用类型 */ type: 'text' /** 对应的数据键名称 */ key: string } // https://developer.mozilla.org/zh-CN/docs/Web/CSS/object-fit export type ObjectFit = | 'fill' | 'contain' | 'cover' | 'none' | 'scale-down' /** 图片配置引用 */ export interface ImageRefer { /** 图片引用类型专用类型 */ type: 'image' /** 图片地址键 */ key: string /** 图片标题键 */ title?: string /** 图片跳转链接键 */ link?: string /** 图片填充方式 */ fit?: ObjectFit /** 图片圆角 */ radius?: Radius } /** 视频配置引用 */ export interface VideoRefer { /** 视频引用类型专用类型 */ type: 'video' /** 视频地址键 */ key: string /** 视频封片图片键 */ poster?: string /** 视频标题键 */ title?: string /** 视频填充方式 */ fit?: ObjectFit // todo 其它配置实现,比如自动播放、控件配置等 } /** 音频配置引用 */ export interface AudioRefer { /** 音频引用类型专用 */ type: 'audio' /** 音频地址键 */ key: string /** 音频标题键,todo 是否需要显示?如何显示? */ title: string // todo 其它配置实现,比如自动播放、控件配置等 } export interface EachRefer { type: 'each' /** 循环数据地址键 */ key: string handle: ViewChildren } export interface TemplateRefer { type: 'template' /** 模板数据地址键 */ key: string } /** 目前支持的 4 中配置引用 */ export type DataRefer = | TextRefer | ImageRefer | VideoRefer | AudioRefer | EachRefer | TemplateRefer export type ViewChild = | string | number | DataRefer | View export type ViewChildren = ViewChild | Array /** * 视图 * * 用于构建页面的基本元素 */ export interface View { /** 视图唯一标识 */ vid?: string /** * 视图数据列表 * * 如果存在同类型的,属性会根据顺序被覆盖。 */ // theme?: Theme | Widget theme?: DynamicTheme title?: string // /** // * 关联数据源 // */ // source?: string /** 子视图 */ children?: ViewChildren } /** 装修视图块 */ export interface Block extends View { /** 视图唯一标识 */ vid: string /** 模块唯一标识 */ mid: string } /** 装修模块 */ export interface Module extends Block { /** 标题 */ title: string /** 组件预览图 */ image?: string /** 允许最大引用次数,如果值为负数则表示没有限制 */ maxReferenceCount?: number /** 被引用次数,运行时属性 */ referenceCount?: number /** 模块配置 */ configs: ModuleConfig[] /** 初始化数据 */ init?: Record /** 关联模板 */ templates?: Record } export type ModuleConfig = | ListConfig | ObjectConfig | BackgroundConfig | BooleanConfig | MarkConfig | ImageConfig | BaseConfig export interface BaseConfig { type: string field: string label: string help?: string required?: boolean } export interface ListConfig extends BaseConfig { type: 'list' addable?: boolean min?: number max?: number configs: ModuleConfig[] } export interface ObjectConfig extends BaseConfig { type: 'object' configs: ModuleConfig[] } export interface BackgroundConfig extends BaseConfig { type: 'background' features: Array<'color' | 'gradient' | 'image'> } export interface ConfigValue { label: string value: T /** 帮助信息 */ help?: string /** 以图标形式渲染 */ icon?: string } /** 针对单选或多选 */ export interface MarkConfig extends BaseConfig { type: 'mark' multiple?: boolean values: ConfigValue[] } export interface BooleanConfig extends BaseConfig { type: 'bool' } export interface ImageConfig extends BaseConfig { type: 'image' /** 内联,表示相关联的数据 */ inlines?: ModuleConfig[] } /** 模块分类 */ export interface Category { /** 分类图标 */ icon: string /** 分类名称 */ text: string /** 模块列表 */ modules: Module[] } /** * 亮度模式 * * todo 考虑对比模式 contrast */ export type Brightness = | 'dark' | 'light' /** 页面头尾固定区域配置 */ export interface StickyConfig { /** 是否开启 */ enabled: boolean /** 高度 */ height: number /** 背景颜色 */ color: string /** 文本颜色 */ textColor: string /** 是否开启边框 */ bordered: boolean /** 边框颜色 */ borderColor: string } /** 页面头部配置 */ export interface PageHeader extends StickyConfig { /** 页面标题 */ title?: string /** 页面标题是否居中显示,在小程序上非自定义头部时无效 */ centerTitle?: boolean /** 自定义视图 */ custom?: View } /** 页面底部配置 */ export interface PageFooter extends StickyConfig { /** 自定义视图,todo 小程序底部怎么弄?使用额外配置? */ view?: View } /** * 页面配置 * * 包含组成页面的视图树和API接口 */ export interface Page { /** 亮度模式,支持暗模式和亮模式 */ brightness?: Brightness /** 是否全屏模式 */ fullscreen?: boolean /** 是否开启顶部安全区域(屏幕状态栏) */ safeAreaInsetTop?: boolean /** 是否开启底部安全区域(底部操作条) */ safeAreaInsetBottom?: boolean /** 页面背景颜色 */ backgroundColor?: string /** 页面头部配置 */ header: PageHeader /** 页面主体部分 */ body: Block[] /** 页面底部配置 */ footer: PageFooter } // /** 交互类型 */ // export type Interaction = // | 'carousel' // 轮播图 // | 'collapse' // 折叠面板 // | 'dialog' // 弹出层 // | 'drawer' // 抽屉 // | 'marquee' // 跑马灯(比如滚动通知) // | 'count' // 计数(比如秒杀倒计时、短信验证码倒计时、数字滚动等) // | 'keyboard' // 打开虚拟键盘 // | 'picker' // 打开 picker 面板 // | 'gesture' // 手势(长按、点击、双击、滑动等) // | 'sticky' // 吸顶 // // export interface Interop { // /** 交互方式 */ // type: Interaction // /** // * 交互视图数据列表 // */ // effect?: ViewData[] // /** // * 交互关联视图列表 // * // * 如果存在同类型的,属性会根据顺序被覆盖。 // */ // attach?: ViewData[] // } // // /** 描述视图动画 */ // export interface Motion { // /** 动画类型 */ // type: string // }