npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@formily-design/formily-designer

v1.0.10

Published

基于 [Designable](https://github.com/alibaba/designable) 和 [Formily](https://formilyjs.org/) 的表单设计器组件库,提供可视化表单设计器和 Schema 渲染表单两个核心组件。

Downloads

1,440

Readme

@formily-design/formily-designer

基于 DesignableFormily 的表单设计器组件库,提供可视化表单设计器和 Schema 渲染表单两个核心组件。

安装

npm install @formily-design/formily-designer

Peer Dependencies

{
  "react": ">=16.8.0 || >=17.0.0",
  "react-dom": ">=16.8.0",
  "antd": "^5.29.3",
  "@formily/core": "^2.0.2",
  "@formily/react": "^2.0.2",
  "@formily/antd-v5": "^1.2.4",
  "@formily/reactive": "^2.0.2",
  "@formily/shared": "^2.0.2"
}

导出

import {
  // 核心组件
  FormilyDesigner,
  SchemaFormView,
  // 自定义组件
  FormButton,
  FormButtonGroup,
  LocationPicker,
  ClickEventSetter,
  ResourceIcon,
  Upload,
  // 工具函数
  transformSchema,
  transformScope,
  asyncLoadDataSource,
  executeFormApi,
  shallowCompile,
  parseStringVariables,
  getLocalStorageData,
  // 设计器 API(re-export from @formily-design/core)
  Engine,
  GlobalRegistry,
  TreeNode,
  createBehavior,
  createResource,
  createDesigner,
  createLocales,
  Shortcut,
  KeyCode,
  // 设计器 Hooks(re-export from @formily-design/react)
  useDesigner,
  DnFC,
  useTreeNode,
  useSelection,
  useHistory,
  useWorkspace,
  usePrefix,
  // 文本组件(多语言文本渲染组件,用于根据当前语言环境显示对应的界面文本)
  TextWidget,
  // Schema 转换(re-export from @formily-design/formily-transformer)
  transformToSchema,
  transformToTreeNode,
} from '@formily-design/formily-designer'

import type {
  IFormilyDesignerProps,
  ISchemaFormViewProps,
  IResourceGroup,
  ViewMode,
  IFormApiConfig,
  // 设计器类型
  ITreeNode,
  IBehavior,
  IBehaviorCreator,
  IResource,
  IResourceCreator,
  IDesignerLayoutProps,
  // 转换器类型
  ITransformerOptions,
  IFormilySchema,
} from '@formily-design/formily-designer'

FormilyDesigner

可视化表单设计器组件,提供拖拽设计、Schema 编辑、实时预览三种视图模式。

基础用法

import React from 'react'
import { FormilyDesigner } from '@formily-design/formily-designer'

export default () => <FormilyDesigner />

Props

| 属性 | 类型 | 默认值 | 说明 | | ------------------------- | ------------------------------------------ | --------------------------------------- | ----------------------------------------------------------------------------------------------------------- | | logo | ReactNode | - | 顶部左侧 Logo | | actions | ReactNode | - | 顶部右侧操作区 | | customComponents | Record<string, React.ComponentType<any>> | - | 自定义组件映射,key 为组件名(x-component),value 为 DnFC 组件(需有 .Behavior.Resource 静态属性) | | customResourceGroups | IResourceGroup[] | - | 自定义资源分组,追加在内置分组之后 | | extendResourceGroups | Record<string, any[]> | - | 扩展内置分组,key 为分组标题 locale key,value 为追加的 sources | | customPreviewComponents | Record<string, React.ComponentType<any>> | - | 额外预览组件映射(仅当预览组件与设计时组件不同时需要) | | customScope | Record<string, any> | - | 额外 SchemaField scope(用于预览和渲染时的表达式上下文) | | rootComponentName | string | 'Form' | 根组件名 | | viewModes | ViewMode[] | ['DESIGNABLE', 'JSONTREE', 'PREVIEW'] | 视图模式 | | shortcuts | Shortcut[] | - | 快捷键配置 | | position | 'fixed' \| 'absolute' \| 'relative' | 'fixed' | 设计器 position | | style | CSSProperties | - | 容器样式 | | className | string | - | 容器类名 | | engineRef | Ref<Engine> | - | 外部通过 ref 获取 Engine 实例 |

内置资源分组

| 分组 | locale key | 包含组件 | | -------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 输入控件 | sources.Inputs | Input, Password, NumberPicker, Rate, Slider, Select, TreeSelect, Cascader, Transfer, Checkbox, Radio, DatePicker, TimePicker, Upload, Switch, ObjectContainer, FormButtonGroup, FormButton, LocationPicker | | 布局组件 | sources.Layouts | Card, FormGrid, FormTab, FormLayout, FormCollapse, Space | | 自增组件 | sources.Arrays | ArrayCards, ArrayTable | | 展示组件 | sources.Displays | Text |

内置多语言

设计器内置了 zh-CNen-USko-KR 三种语言,组件加载时自动注册。


SchemaFormView

根据 Formily Schema 渲染表单的组件,支持创建、编辑、详情、只读四种表单模式,以及远程数据源和 API 提交。

基础用法

import React from 'react'
import { SchemaFormView } from '@formily-design/formily-designer'

const schema = {
  type: 'object',
  properties: {
    username: {
      type: 'string',
      title: '用户名',
      'x-decorator': 'FormItem',
      'x-component': 'Input',
    },
  },
}

export default () => (
  <SchemaFormView
    schema={schema}
    formMode="create"
    onSubmitSuccess={(form) => {
      console.log('提交数据:', form.values)
    }}
  />
)

Props

| 属性 | 类型 | 默认值 | 说明 | | ------------------ | ------------------------------------------------------------------------ | ------ | ------------------------------------------------------------------------------------------ | | schema | any | - | Formily Schema 对象 | | customComponents | Record<string, React.ComponentType<any>> | - | 额外组件映射,合并到 createSchemaField 的 components | | customScope | Record<string, any> | - | 额外 scope,用于表达式上下文 | | formMode | 'create' \| 'update' \| 'detail' \| 'view' | - | 表单模式 | | apiParams | Record<string, any> | {} | 表单 API 配置参数 | | onSubmitSuccess | (form: any) => void | - | 表单提交成功回调 | | formProps | { api?: IFormApiConfig; initApi?: IFormApiConfig; [key: string]: any } | - | 表单配置,api 用于提交,initApi 用于编辑/详情模式回填数据,其余属性透传给 Formily Form |

formMode 说明

| 模式 | readOnly | disabled | readPretty | 说明 | | -------- | -------- | -------- | ---------- | ------------------------------------------------- | | create | - | - | - | 新建模式,可编辑可提交 | | update | - | - | - | 编辑模式,可编辑可提交,支持 initApi 加载初始数据 | | detail | ✅ | ✅ | ✅ | 详情模式,只读展示,支持 initApi 加载数据 | | view | ✅ | - | - | 只读模式,不可编辑但可交互 |

内置 Scope 变量

SchemaFormView 在渲染时自动注入以下 scope 变量,可在 Schema 表达式中使用:

| 变量 | 类型 | 说明 | | --------------- | ------------------------- | ------------------------------------------- | | $localStorage | Record<string, any> | localStorage 全部数据对象 | | $globalData | Record<string, any> | 包含 apiParamsformMode 的全局数据 | | apiParams | Record<string, any> | 传入的 API 配置参数 | | submitFormApi | (formValues) => Promise | 表单提交 API 函数(需配置 formProps.api) |


高级场景

场景一:通过 engineRef 外部操作设计器

通过 engineRef 可以在组件外部获取 Engine 实例,使用 getCurrentTree / setCurrentTree 配合 transformToSchema / transformToTreeNode 实现获取/设置 Schema,通过 workspace.history 操作历史记录。

import React, { useRef } from 'react'
import {
  FormilyDesigner,
  Engine,
  transformToSchema,
  transformToTreeNode,
} from '@formily-design/formily-designer'

export default () => {
  const engineRef = useRef<Engine>(null)

  const getSchema = () => {
    const engine = engineRef.current
    if (!engine) return
    const tree = engine.getCurrentTree()
    if (!tree) return
    const { schema } = transformToSchema(tree)
    console.log('当前 Schema:', JSON.stringify(schema, null, 2))
  }

  const setSchema = (schema: any) => {
    const engine = engineRef.current
    if (!engine) return
    engine.setCurrentTree(transformToTreeNode({ schema }))
  }

  const handleUndo = () => {
    engineRef.current?.workbench?.currentWorkspace?.history?.undo()
  }

  const handleRedo = () => {
    engineRef.current?.workbench?.currentWorkspace?.history?.redo()
  }

  return (
    <div style={{ height: '100vh' }}>
      <div style={{ padding: 8, background: '#f0f0f0' }}>
        <button onClick={getSchema}>获取 Schema</button>
        <button onClick={() => setSchema(mockSchema)}>设置 Schema</button>
        <button onClick={handleUndo}>撤销</button>
        <button onClick={handleRedo}>重做</button>
      </div>
      <FormilyDesigner engineRef={engineRef} />
    </div>
  )
}

History API

历史记录实例挂载在 Workspace 上,通过 engine.workbench.currentWorkspace.history 访问。

| 方法 / 属性 | 签名 | 说明 | | ------------- | --------------------- | -------------------------- | | undo() | () | 撤销:回退到上一条历史记录 | | redo() | () | 重做:前进到下一条历史记录 | | goTo(index) | (index: number) | 跳转到指定索引的历史记录 | | push(type?) | (type?: string) | 将当前状态快照推入历史栈 | | clear() | () | 清空所有历史记录 | | list() | () => HistoryItem[] | 获取完整历史记录列表 | | allowUndo | get boolean | 是否可以撤销 | | allowRedo | get boolean | 是否可以重做 |

const history = engineRef.current?.workbench?.currentWorkspace?.history

history?.undo()
history?.redo()
history?.goTo(2)
history?.push('custom-type')
history?.clear()
history?.list()
history?.allowUndo
history?.allowRedo

场景二:自定义顶部操作区

通过 logoactions 属性自定义设计器顶栏。actions 传入的组件位于 Designer 容器内部,可使用 useDesigner Hook 跨组件获取 Engine 实例,从而读取 Schema 数据。

import React from 'react'
import {
  FormilyDesigner,
  useDesigner,
  transformToSchema,
} from '@formily-design/formily-designer'
import { Button, message } from 'antd'

/**
 * 自定义顶部操作区
 * 如果内部的 useDesigner 获取不到最新数据,试试引入 @formily/react 的 observer Hook 包裹 Actions 组件
 * @example
 * ```tsx
 * import { observer } from '@formily/react'
 * const Actions = observer(ActionsComponent)
 * ```
 */
const Actions = () => {
  const engine = useDesigner()

  const handleSave = () => {
    const tree = engine.getCurrentTree()
    if (!tree) return
    const { schema } = transformToSchema(tree)
    console.log('保存 Schema:', JSON.stringify(schema, null, 2))
    message.success('保存成功')
  }

  return (
    <div style={{ display: 'flex', gap: 8 }}>
      <Button type="primary" onClick={handleSave}>
        保存
      </Button>
      <Button onClick={() => console.log('取消')}>取消</Button>
    </div>
  )
}

export default () => (
  <FormilyDesigner
    logo={<span style={{ fontWeight: 700, fontSize: 16 }}>表单设计器</span>}
    actions={<Actions />}
  />
)

注意useDesigner 依赖 DesignerEngineContext,只能在 FormilyDesigner 内部的子组件中使用。如果需要在 FormilyDesigner 外部访问 Engine,请使用 engineRef(见场景一)。

场景三:扩展内置资源分组

通过 extendResourceGroups 向内置分组追加自定义组件资源,通过 customResourceGroups 添加全新的分组。

import React from 'react'
import {
  FormilyDesigner,
  createBehavior,
  createResource,
} from '@formily-design/formily-designer'

const MyCustomInput = (props) => <input {...props} />

MyCustomInput.Behavior = createBehavior({
  name: 'MyCustomInput',
  selector: (node) => node.props?.['x-component'] === 'MyCustomInput',
  designerProps: {
    propsSchema: {
      type: 'object',
      properties: {
        placeholder: { type: 'string', title: '占位符' },
      },
    },
  },
})

MyCustomInput.Resource = createResource({
  title: '自定义输入框',
  icon: 'Input',
  elements: [
    {
      componentName: 'Field',
      props: {
        type: 'string',
        title: '自定义输入框',
        'x-decorator': 'FormItem',
        'x-component': 'MyCustomInput',
      },
    },
  ],
})

export default () => (
  <FormilyDesigner
    customComponents={{ MyCustomInput }}
    extendResourceGroups={{
      'sources.Inputs': [MyCustomInput.Resource],
    }}
    customResourceGroups={[
      {
        title: 'sources.Custom',
        sources: [MyCustomInput.Resource],
      },
    ]}
  />
)

场景四:自定义预览组件

当设计时组件和预览时组件不同时(如设计时使用占位组件,预览时使用真实组件),可通过 customPreviewComponents 单独指定预览组件。

import React from 'react'
import { FormilyDesigner } from '@formily-design/formily-designer'

const DesignTimeChart = () => (
  <div
    style={{
      height: 200,
      background: '#f5f5f5',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
    }}
  >
    图表占位
  </div>
)
const RuntimeChart = ({ data }) => (
  <div>真实图表组件: {JSON.stringify(data)}</div>
)

export default () => (
  <FormilyDesigner
    customComponents={{ Chart: DesignTimeChart }}
    customPreviewComponents={{ Chart: RuntimeChart }}
  />
)

场景五:SchemaFormView 配合 API 提交与数据回填

SchemaFormView 支持通过 formProps 配置 API,实现表单提交和编辑/详情模式的数据回填。

import React from 'react'
import { SchemaFormView } from '@formily-design/formily-designer'

const schema = {
  type: 'object',
  properties: {
    username: {
      type: 'string',
      title: '用户名',
      'x-decorator': 'FormItem',
      'x-component': 'Input',
    },
    email: {
      type: 'string',
      title: '邮箱',
      'x-decorator': 'FormItem',
      'x-component': 'Input',
      'x-component-props': {
        type: 'email',
      },
    },
  },
}

const formProps = {
  initApi: {
    url: '/api/user/detail',
    method: 'GET',
  },
  api: {
    url: '/api/user/update',
    method: 'POST',
  },
}

export default () => (
  <SchemaFormView
    schema={schema}
    formMode="update"
    formProps={formProps}
    apiParams={{ id: '123' }}
    onSubmitSuccess={(form) => {
      console.log('提交成功:', form.values)
    }}
  />
)

场景六:自定义 Scope 实现表达式联动

通过 customScope 注入自定义函数和变量,在 Schema 的 x-reactions 等表达式中使用。

import React from 'react'
import { SchemaFormView } from '@formily-design/formily-designer'

const schema = {
  type: 'object',
  properties: {
    type: {
      type: 'string',
      title: '类型',
      'x-decorator': 'FormItem',
      'x-component': 'Select',
      'x-component-props': {
        options: [
          { label: '个人', value: 'personal' },
          { label: '企业', value: 'enterprise' },
        ],
      },
    },
    companyName: {
      type: 'string',
      title: '企业名称',
      'x-decorator': 'FormItem',
      'x-component': 'Input',
      'x-reactions': {
        dependencies: ['type'],
        fulfill: {
          state: {
            visible: '{{$deps[0] === "enterprise"}}',
          },
        },
      },
    },
  },
}

export default () => (
  <SchemaFormView
    schema={schema}
    formMode="create"
    customScope={{
      $currentUser: { name: '张三', role: 'admin' },
    }}
  />
)

场景七:设计器与渲染表单联动

将 FormilyDesigner 设计出的 Schema 传递给 SchemaFormView 渲染,实现设计-渲染闭环。

import React, { useRef, useState } from 'react'
import {
  FormilyDesigner,
  SchemaFormView,
  Engine,
  transformToSchema,
} from '@formily-design/formily-designer'
import { Button, Modal } from 'antd'

export default () => {
  const engineRef = useRef<Engine>(null)
  const [previewSchema, setPreviewSchema] = useState(null)
  const [modalOpen, setModalOpen] = useState(false)

  const handlePreview = () => {
    const engine = engineRef.current
    if (!engine) return
    const tree = engine.getCurrentTree()
    if (!tree) return
    const { schema } = transformToSchema(tree)
    setPreviewSchema(schema)
    setModalOpen(true)
  }

  return (
    <div style={{ height: '100vh' }}>
      <FormilyDesigner
        engineRef={engineRef}
        actions={
          <Button type="primary" onClick={handlePreview}>
            渲染预览
          </Button>
        }
      />
      <Modal
        title="渲染预览"
        open={modalOpen}
        onCancel={() => setModalOpen(false)}
        footer={null}
        width={800}
      >
        {previewSchema && (
          <SchemaFormView
            schema={previewSchema}
            formMode="create"
            onSubmitSuccess={(form) => {
              console.log('表单数据:', form.values)
            }}
          />
        )}
      </Modal>
    </div>
  )
}

场景八:远程数据源联动

Schema 中支持通过 x-datasource-effect 配置远程数据源,组件会自动将其转换为 x-reactions 实现异步数据加载。

import React from 'react'
import { SchemaFormView } from '@formily-design/formily-designer'

const schema = {
  type: 'object',
  properties: {
    city: {
      type: 'string',
      title: '城市',
      'x-decorator': 'FormItem',
      'x-component': 'Select',
      'x-datasource-effect': {
        url: '/api/cities',
        method: 'GET',
        headers: {},
        params: {},
        beforeRequest: '',
        dataHandler:
          'function(res){ return res.data.map(c => ({label: c.name, value: c.code})) }',
      },
    },
    district: {
      type: 'string',
      title: '区县',
      'x-decorator': 'FormItem',
      'x-component': 'Select',
      'x-datasource-effect': {
        url: '/api/districts',
        method: 'GET',
        headers: {},
        params: {
          cityCode: '{{$values.city}}',
        },
        beforeRequest: '',
        dataHandler:
          'function(res){ return res.data.map(d => ({label: d.name, value: d.code})) }',
      },
    },
  },
}

export default () => <SchemaFormView schema={schema} formMode="create" />

场景九:自定义 position 和样式

当设计器需要嵌入到非全屏容器中时,将 position 设为 absoluterelative

import React from 'react'
import { FormilyDesigner } from '@formily-design/formily-designer'

export default () => (
  <div style={{ height: 600, position: 'relative' }}>
    <FormilyDesigner
      position="absolute"
      style={{ top: 0, left: 0, right: 0, bottom: 0 }}
    />
  </div>
)

自定义组件

库内置了以下自定义组件,可直接在设计器中使用:

| 组件 | 说明 | | ------------------ | -------------------------------------------------------- | | FormButton | 表单按钮,支持配置点击事件(API 请求、页面跳转、下载等) | | FormButtonGroup | 按钮组容器 | | LocationPicker | 地图位置选择器(基于腾讯地图,需安装 tlbs-map-react) | | Upload | 文件上传组件 | | ClickEventSetter | 点击事件配置器(用于属性面板) | | ResourceIcon | 资源图标组件 |


工具函数

transformSchema(schema, scope)

遍历 Schema,将 x-datasource-effect 配置转换为 x-reactions 异步数据加载逻辑。

import { transformSchema } from '@formily-design/formily-designer'

const processedSchema = transformSchema(rawSchema, {
  $globalData: { formMode: 'create' },
})

transformScope(schema)

递归提取 Schema 中所有 x-datasource-effect 配置,生成 scope 函数映射。

import { transformScope } from '@formily-design/formily-designer'

const scope = transformScope(schema)

asyncLoadDataSource(service, options)

创建异步数据加载的 reaction 函数,支持搜索防抖。

import { asyncLoadDataSource } from '@formily-design/formily-designer'
import type { Field } from '@formily/core'

const service = async (field: Field, searchValue?: string) => {
  const res = await fetch(`/api/options?keyword=${searchValue ?? ''}`)
  const data = await res.json()
  return data
}

const reaction = asyncLoadDataSource(service, { fetchOnSearch: true })

executeFormApi(apiConfig, formValues, options)

执行表单 API 请求,支持 beforeRequest / dataHandler 钩子和自定义请求函数。

import { executeFormApi } from '@formily-design/formily-designer'

const result = await executeFormApi(
  { url: '/api/submit', method: 'POST' },
  { name: 'test' },
  {
    requestFn: async (url, params, options) => {
      const response = await fetch(url, {
        method: options?.method,
        headers: options?.headers,
        body: JSON.stringify(params),
      })
      return response.json()
    },
  }
)

shallowCompile(source, scope)

编译包含 {{}} 表达式的字符串。

import { shallowCompile } from '@formily-design/formily-designer'

shallowCompile('{{name}}', { name: 'hello' }) // 'hello'

parseStringVariables(str, scope)

解析字符串中的变量占位符并替换。

import { parseStringVariables } from '@formily-design/formily-designer'

parseStringVariables('/api/user/{{$localStorage.userId}}', {
  $localStorage: { userId: '123' },
})
// '/api/user/123'

getLocalStorageData()

获取 localStorage 中所有数据,返回一个对象。

import { getLocalStorageData } from '@formily-design/formily-designer'

const data = getLocalStorageData()
// { token: '"abc"', userId: '"123"', ... }