Repository: alibaba/lowcode-materials Branch: main Commit: 8d0d912e5872 Files: 879 Total size: 2.2 MB Directory structure: gitextract_p86v3tr9/ ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .markdownlint.json ├── .markdownlintignore ├── .prettierrc.js ├── .stylelintignore ├── .stylelintrc.js ├── LICENSE ├── README.md ├── commitlint.config.js ├── f2elint.config.js ├── package.json ├── packages/ │ ├── antd-lowcode-materials/ │ │ ├── README.md │ │ ├── build.json │ │ ├── build.lowcode.js │ │ ├── lowcode/ │ │ │ ├── _setters/ │ │ │ │ ├── antd-icon-setter/ │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── style.less │ │ │ │ └── index.tsx │ │ │ ├── _utils/ │ │ │ │ ├── hoc.tsx │ │ │ │ ├── transform-meta.ts │ │ │ │ └── utils.ts │ │ │ ├── affix/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── alert/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── anchor/ │ │ │ │ └── snippets.ts │ │ │ ├── anchor.link/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── auto-complete/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── avatar/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── back-top/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── badge/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── breadcrumb/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── button/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── calendar/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── card/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── carousel/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── cascader/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── checkbox/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── checkbox.group/ │ │ │ │ └── meta.ts │ │ │ ├── collapse/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── collapse.pane/ │ │ │ │ └── meta.ts │ │ │ ├── comment/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── config-provider/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── date-picker/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── date-picker.range-picker/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── descriptions/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── descriptions.item/ │ │ │ │ └── meta.ts │ │ │ ├── divider/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── drawer/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── dropdown/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── empty/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── form/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── form.item/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── form.list/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── grid.col/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── grid.row/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── icon/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── image/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── input/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── input-number/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── input.group/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── input.password/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── input.search/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── input.text-area/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── list/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── list.item/ │ │ │ │ └── meta.ts │ │ │ ├── list.item.meta/ │ │ │ │ └── meta.ts │ │ │ ├── mentions/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── menu/ │ │ │ │ ├── meta.ts │ │ │ │ ├── snippets.ts │ │ │ │ └── utils.ts │ │ │ ├── menu.item/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── menu.item-group/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── menu.sub-menu/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── modal/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── page-header/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── pagination/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── popconfirm/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── popover/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── progress/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── radio/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── radio.group/ │ │ │ │ └── meta.ts │ │ │ ├── rate/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── result/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── segmented/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── select/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── skeleton/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── slider/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── slot/ │ │ │ │ ├── meta.ts │ │ │ │ └── view.tsx │ │ │ ├── space/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── spin/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── statistic/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── steps/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── steps.step/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── switch/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── table/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── tabs/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── tabs.tab-pane/ │ │ │ │ └── meta.ts │ │ │ ├── tag/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── time-picker/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── timeline/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── timeline.item/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── tooltip/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── transfer/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── tree/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── tree-select/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── typography.link/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── typography.paragraph/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── typography.text/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── typography.title/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ └── upload/ │ │ │ ├── meta.ts │ │ │ └── snippets.ts │ │ ├── package.json │ │ └── src/ │ │ ├── components/ │ │ │ ├── auto-complete/ │ │ │ │ └── index.tsx │ │ │ ├── button/ │ │ │ │ └── index.tsx │ │ │ ├── calendar/ │ │ │ │ └── index.tsx │ │ │ ├── cascader/ │ │ │ │ └── index.tsx │ │ │ ├── checkbox/ │ │ │ │ └── index.tsx │ │ │ ├── config-provider/ │ │ │ │ └── index.tsx │ │ │ ├── date-picker/ │ │ │ │ └── index.tsx │ │ │ ├── drawer/ │ │ │ │ └── index.tsx │ │ │ ├── dropdown/ │ │ │ │ └── index.tsx │ │ │ ├── form/ │ │ │ │ └── index.tsx │ │ │ ├── icon/ │ │ │ │ └── index.tsx │ │ │ ├── input/ │ │ │ │ └── index.tsx │ │ │ ├── modal/ │ │ │ │ └── index.tsx │ │ │ ├── popover/ │ │ │ │ └── index.tsx │ │ │ ├── radio/ │ │ │ │ └── index.tsx │ │ │ ├── select/ │ │ │ │ └── index.tsx │ │ │ ├── skeleton/ │ │ │ │ └── index.tsx │ │ │ ├── slider/ │ │ │ │ └── index.tsx │ │ │ ├── table/ │ │ │ │ └── index.tsx │ │ │ ├── tabs/ │ │ │ │ └── index.tsx │ │ │ ├── time-picker/ │ │ │ │ └── index.tsx │ │ │ ├── tree-select/ │ │ │ │ └── index.tsx │ │ │ └── upload/ │ │ │ └── index.tsx │ │ ├── index.scss │ │ ├── index.tsx │ │ └── utils/ │ │ ├── hoc.tsx │ │ └── warning.ts │ ├── fusion-lowcode-materials/ │ │ ├── HISTORY.md │ │ ├── README.md │ │ ├── build.json │ │ ├── build.lowcode.js │ │ ├── demo/ │ │ │ ├── Image.md │ │ │ ├── Link.md │ │ │ ├── NoteWrapper.md │ │ │ ├── RichText.md │ │ │ └── Video.md │ │ ├── lowcode/ │ │ │ ├── alert/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── avatar/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── badge/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── balloon/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ ├── snippets.design.ts │ │ │ │ └── snippets.ts │ │ │ ├── balloon-inner/ │ │ │ │ └── meta.ts │ │ │ ├── box/ │ │ │ │ ├── meta.design.tsx │ │ │ │ └── meta.tsx │ │ │ ├── breadcrumb/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── breadcrumb-item/ │ │ │ │ └── meta.ts │ │ │ ├── button/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ ├── snippets.design.ts │ │ │ │ └── snippets.ts │ │ │ ├── button-group/ │ │ │ │ └── meta.ts │ │ │ ├── calendar/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── card/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── card-actions/ │ │ │ │ └── meta.ts │ │ │ ├── card-bullet-header/ │ │ │ │ └── meta.ts │ │ │ ├── card-collaspe-content/ │ │ │ │ └── meta.ts │ │ │ ├── card-content/ │ │ │ │ └── meta.ts │ │ │ ├── card-divider/ │ │ │ │ └── meta.ts │ │ │ ├── card-header/ │ │ │ │ └── meta.ts │ │ │ ├── card-media/ │ │ │ │ └── meta.ts │ │ │ ├── cascader/ │ │ │ │ ├── meta.design.ts │ │ │ │ └── meta.ts │ │ │ ├── cascader-select/ │ │ │ │ ├── adaptor.ts │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ ├── snippets.design.ts │ │ │ │ └── snippets.ts │ │ │ ├── checkbox/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ ├── snippets.design.ts │ │ │ │ └── snippets.ts │ │ │ ├── checkbox-group/ │ │ │ │ ├── meta.design.ts │ │ │ │ └── meta.ts │ │ │ ├── checkbox-item/ │ │ │ │ └── meta.ts │ │ │ ├── collapse/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ ├── snippets.design.ts │ │ │ │ └── view.tsx │ │ │ ├── collapse-panel/ │ │ │ │ └── meta.ts │ │ │ ├── date-picker/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── dialog/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ ├── snippets.design.ts │ │ │ │ └── snippets.ts │ │ │ ├── div/ │ │ │ │ └── meta.ts │ │ │ ├── divider/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── drawer/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ ├── snippets.design.ts │ │ │ │ └── snippets.ts │ │ │ ├── drawer-inner/ │ │ │ │ └── meta.ts │ │ │ ├── dropdown/ │ │ │ │ └── meta.ts │ │ │ ├── error-boundary/ │ │ │ │ └── meta.ts │ │ │ ├── field/ │ │ │ │ └── meta.ts │ │ │ ├── form/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── form-error/ │ │ │ │ └── meta.ts │ │ │ ├── form-item/ │ │ │ │ └── meta.ts │ │ │ ├── form-reset/ │ │ │ │ └── meta.ts │ │ │ ├── form-submit/ │ │ │ │ └── meta.ts │ │ │ ├── group/ │ │ │ │ └── meta.ts │ │ │ ├── icon/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── img/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── inner/ │ │ │ │ └── meta.ts │ │ │ ├── input/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ ├── snippets.design.ts │ │ │ │ ├── snippets.ts │ │ │ │ └── view.tsx │ │ │ ├── input-group/ │ │ │ │ └── meta.ts │ │ │ ├── input-password/ │ │ │ │ └── meta.ts │ │ │ ├── input-text-area/ │ │ │ │ └── meta.ts │ │ │ ├── link/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── list/ │ │ │ │ └── meta.ts │ │ │ ├── list-item/ │ │ │ │ └── meta.ts │ │ │ ├── loading/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── menu/ │ │ │ │ ├── adaptor.ts │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.design.ts │ │ │ ├── menu-button/ │ │ │ │ ├── adaptor.ts │ │ │ │ ├── meta.design.ts │ │ │ │ └── meta.ts │ │ │ ├── menu-divider/ │ │ │ │ └── meta.ts │ │ │ ├── menu-group/ │ │ │ │ └── meta.ts │ │ │ ├── menu-item/ │ │ │ │ └── meta.ts │ │ │ ├── menu-popup-item/ │ │ │ │ └── meta.ts │ │ │ ├── month-picker/ │ │ │ │ └── meta.ts │ │ │ ├── nav/ │ │ │ │ └── meta.ts │ │ │ ├── nav-item/ │ │ │ │ └── meta.ts │ │ │ ├── next-table/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── next-text/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── note-wrapper/ │ │ │ │ └── meta.ts │ │ │ ├── number-picker/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ ├── snippets.ts │ │ │ │ └── view.tsx │ │ │ ├── page/ │ │ │ │ └── meta.ts │ │ │ ├── pagination/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── paragraph/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── popup-item/ │ │ │ │ └── meta.ts │ │ │ ├── progress/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── radio/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ ├── snippets.design.ts │ │ │ │ └── snippets.ts │ │ │ ├── radio-group/ │ │ │ │ ├── meta.design.ts │ │ │ │ └── meta.ts │ │ │ ├── radio-item/ │ │ │ │ └── meta.ts │ │ │ ├── range/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── range-calendar/ │ │ │ │ └── meta.ts │ │ │ ├── range-picker/ │ │ │ │ └── meta.ts │ │ │ ├── rating/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── responsive-grid/ │ │ │ │ └── meta.ts │ │ │ ├── responsive-grid-cell/ │ │ │ │ └── meta.ts │ │ │ ├── rich-text/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── search/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ ├── snippets.design.ts │ │ │ │ └── snippets.ts │ │ │ ├── select/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ ├── snippets.design.ts │ │ │ │ └── snippets.ts │ │ │ ├── select-option/ │ │ │ │ └── meta.ts │ │ │ ├── slider/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── slot/ │ │ │ │ ├── meta.ts │ │ │ │ └── view.tsx │ │ │ ├── split-button/ │ │ │ │ ├── adaptor.ts │ │ │ │ ├── meta.design.ts │ │ │ │ └── meta.ts │ │ │ ├── step/ │ │ │ │ ├── adaptor.ts │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ ├── snippets.design.ts │ │ │ │ └── snippets.ts │ │ │ ├── step-item/ │ │ │ │ └── meta.ts │ │ │ ├── sub-menu/ │ │ │ │ └── meta.ts │ │ │ ├── sub-nav/ │ │ │ │ └── meta.ts │ │ │ ├── switch/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── tab/ │ │ │ │ ├── adaptor.ts │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ ├── snippets.design.ts │ │ │ │ └── snippets.ts │ │ │ ├── tab-item/ │ │ │ │ ├── meta.design.ts │ │ │ │ └── meta.ts │ │ │ ├── tab-tab-pane/ │ │ │ │ └── meta.ts │ │ │ ├── table/ │ │ │ │ └── meta.ts │ │ │ ├── table-column/ │ │ │ │ └── meta.ts │ │ │ ├── tag/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── tag-closeable/ │ │ │ │ └── meta.ts │ │ │ ├── tag-selectable/ │ │ │ │ └── meta.ts │ │ │ ├── time-picker/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── timeline/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── timeline-item/ │ │ │ │ ├── meta.design.ts │ │ │ │ └── meta.ts │ │ │ ├── toast/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── tooltip/ │ │ │ │ └── meta.ts │ │ │ ├── transfer/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ ├── snippets.design.ts │ │ │ │ └── snippets.ts │ │ │ ├── tree/ │ │ │ │ ├── adaptor.ts │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ ├── snippets.design.ts │ │ │ │ └── snippets.ts │ │ │ ├── tree-node/ │ │ │ │ └── meta.ts │ │ │ ├── tree-select/ │ │ │ │ ├── adaptor.ts │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ ├── snippets.design.ts │ │ │ │ └── snippets.ts │ │ │ ├── typography/ │ │ │ │ └── meta.ts │ │ │ ├── typography-text/ │ │ │ │ └── meta.ts │ │ │ ├── upload/ │ │ │ │ ├── meta.design.ts │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── upload-dragger/ │ │ │ │ └── meta.ts │ │ │ ├── upload-list/ │ │ │ │ └── meta.ts │ │ │ ├── upload-selecter/ │ │ │ │ └── meta.ts │ │ │ ├── utils/ │ │ │ │ ├── component-wrapper.ts │ │ │ │ ├── icons.ts │ │ │ │ ├── index.ts │ │ │ │ └── parse-data.ts │ │ │ ├── video/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.ts │ │ │ ├── week-picker/ │ │ │ │ └── meta.ts │ │ │ └── year-picker/ │ │ │ └── meta.ts │ │ ├── package.json │ │ ├── plugins/ │ │ │ └── compatible.build.js │ │ ├── scripts/ │ │ │ └── utils.js │ │ └── src/ │ │ ├── components/ │ │ │ ├── balloon/ │ │ │ │ └── index.tsx │ │ │ ├── calendar/ │ │ │ │ └── index.tsx │ │ │ ├── div/ │ │ │ │ └── index.tsx │ │ │ ├── image/ │ │ │ │ └── index.tsx │ │ │ ├── link/ │ │ │ │ └── index.tsx │ │ │ ├── next-table/ │ │ │ │ ├── component/ │ │ │ │ │ ├── field/ │ │ │ │ │ │ ├── baseTableField.tsx │ │ │ │ │ │ ├── customField.tsx │ │ │ │ │ │ ├── dateField.tsx │ │ │ │ │ │ ├── dateRangeField.tsx │ │ │ │ │ │ ├── inputField.tsx │ │ │ │ │ │ ├── radioField.tsx │ │ │ │ │ │ └── selectField.tsx │ │ │ │ │ ├── webCustomColumnDrawer.tsx │ │ │ │ │ ├── webLinkBar.tsx │ │ │ │ │ ├── webNextTableActionCell.tsx │ │ │ │ │ ├── webNextTableCell.tsx │ │ │ │ │ ├── webPagination.tsx │ │ │ │ │ ├── webRowOrder.tsx │ │ │ │ │ └── webToolbar.tsx │ │ │ │ ├── index.scss │ │ │ │ ├── index.tsx │ │ │ │ ├── interface/ │ │ │ │ │ └── index.ts │ │ │ │ ├── locale/ │ │ │ │ │ ├── en-us.ts │ │ │ │ │ └── zh-cn.ts │ │ │ │ ├── mixin/ │ │ │ │ │ ├── columnMethods.tsx │ │ │ │ │ ├── commonMethods.ts │ │ │ │ │ ├── editableMethods.ts │ │ │ │ │ └── loadMethods.ts │ │ │ │ ├── scss/ │ │ │ │ │ └── variables.scss │ │ │ │ ├── table/ │ │ │ │ │ └── webTable.tsx │ │ │ │ └── utils/ │ │ │ │ ├── buildNextTableMethod.ts │ │ │ │ ├── buildTableProps.ts │ │ │ │ ├── chainAccess.ts │ │ │ │ ├── convertData.ts │ │ │ │ ├── delegateFunctions.ts │ │ │ │ ├── dispatchResizeEvent.ts │ │ │ │ ├── filterActionColumn.ts │ │ │ │ ├── filterActionColumnByDevice.ts │ │ │ │ ├── filterColumn.ts │ │ │ │ ├── formatter.ts │ │ │ │ ├── getCleanRowData.ts │ │ │ │ ├── getColumnsFromChildern.tsx │ │ │ │ ├── getDataSource.ts │ │ │ │ ├── hasRowAction.ts │ │ │ │ ├── render/ │ │ │ │ │ ├── actionTitleRender.tsx │ │ │ │ │ ├── cascadeTimestampRender.tsx │ │ │ │ │ ├── commonTableCellRender.tsx │ │ │ │ │ ├── defaultRender.tsx │ │ │ │ │ ├── enumRender.tsx │ │ │ │ │ ├── errorRender.tsx │ │ │ │ │ ├── fileRender.tsx │ │ │ │ │ ├── imageRender.tsx │ │ │ │ │ ├── linkRender.tsx │ │ │ │ │ ├── moneyRangeRender.tsx │ │ │ │ │ ├── moneyRender.tsx │ │ │ │ │ ├── timestampRender.tsx │ │ │ │ │ └── titleMessageRender.tsx │ │ │ │ ├── runColumnActionCallback.ts │ │ │ │ ├── runToolbarActionCallback.ts │ │ │ │ └── tableProps.ts │ │ │ ├── next-text/ │ │ │ │ ├── index.scss │ │ │ │ └── index.tsx │ │ │ ├── note-wrapper/ │ │ │ │ ├── index.scss │ │ │ │ └── index.tsx │ │ │ ├── rich-text/ │ │ │ │ └── index.tsx │ │ │ └── video/ │ │ │ └── index.tsx │ │ ├── index.scss │ │ ├── index.tsx │ │ └── utils.js │ ├── fusion-ui/ │ │ ├── .editorconfig │ │ ├── .eslintignore │ │ ├── .eslintrc.js │ │ ├── .gitignore │ │ ├── .markdownlint.json │ │ ├── .markdownlintignore │ │ ├── .prettierrc.js │ │ ├── .stylelintignore │ │ ├── .stylelintrc.js │ │ ├── README.md │ │ ├── build.json │ │ ├── build.lowcode.js │ │ ├── commitlint.config.js │ │ ├── docs/ │ │ │ ├── .dumi/ │ │ │ │ └── theme/ │ │ │ │ ├── builtins/ │ │ │ │ │ ├── API.tsx │ │ │ │ │ └── index.scss │ │ │ │ └── layout.tsx │ │ │ ├── .fatherrc.ts │ │ │ ├── .umirc.ts │ │ │ └── src/ │ │ │ ├── BarChart/ │ │ │ │ └── index.md │ │ │ ├── ColumnChart/ │ │ │ │ └── index.md │ │ │ ├── DonutChart/ │ │ │ │ └── index.md │ │ │ ├── EditTable/ │ │ │ │ ├── index.md │ │ │ │ └── index.tsx │ │ │ ├── ExpandTable/ │ │ │ │ ├── index.md │ │ │ │ └── index.tsx │ │ │ ├── Filter/ │ │ │ │ ├── index.md │ │ │ │ └── index.tsx │ │ │ ├── GroupTable/ │ │ │ │ ├── index.md │ │ │ │ └── index.tsx │ │ │ ├── LineChart/ │ │ │ │ ├── basic.tsx │ │ │ │ ├── index.md │ │ │ │ └── slider.tsx │ │ │ ├── PageHeader/ │ │ │ │ ├── basic.tsx │ │ │ │ ├── breadcrumb.tsx │ │ │ │ └── index.md │ │ │ ├── PieChart/ │ │ │ │ ├── basic.tsx │ │ │ │ ├── index.md │ │ │ │ └── percent.tsx │ │ │ ├── ProDialog/ │ │ │ │ ├── basic.tsx │ │ │ │ ├── index.md │ │ │ │ └── large-content.tsx │ │ │ ├── ProDrawer/ │ │ │ │ ├── basic.tsx │ │ │ │ └── index.md │ │ │ ├── ProForm/ │ │ │ │ ├── basic.tsx │ │ │ │ ├── index.md │ │ │ │ └── operations.tsx │ │ │ ├── ProTable/ │ │ │ │ ├── basic.tsx │ │ │ │ ├── index.md │ │ │ │ └── service.ts │ │ │ ├── StepForm/ │ │ │ │ ├── basic.tsx │ │ │ │ └── index.md │ │ │ ├── TabContainer/ │ │ │ │ ├── basic.tsx │ │ │ │ └── index.md │ │ │ ├── anchorForm/ │ │ │ │ └── index.md │ │ │ ├── areaChart/ │ │ │ │ └── index.md │ │ │ └── childForm/ │ │ │ └── index.md │ │ ├── f2elint.config.js │ │ ├── jest.config.js │ │ ├── lowcode/ │ │ │ ├── anchor/ │ │ │ │ └── meta.ts │ │ │ ├── anchor-form/ │ │ │ │ └── meta.ts │ │ │ ├── area-chart/ │ │ │ │ └── meta.ts │ │ │ ├── bar-chart/ │ │ │ │ └── meta.ts │ │ │ ├── cascader-select/ │ │ │ │ ├── meta.js │ │ │ │ └── snippets.js │ │ │ ├── checkbox-group/ │ │ │ │ └── meta.js │ │ │ ├── child-form/ │ │ │ │ └── meta.ts │ │ │ ├── column-chart/ │ │ │ │ └── meta.ts │ │ │ ├── common/ │ │ │ │ ├── actions.ts │ │ │ │ ├── button-groups.ts │ │ │ │ ├── chart-action.ts │ │ │ │ ├── chart-plot.ts │ │ │ │ ├── index.ts │ │ │ │ └── operations.ts │ │ │ ├── date-picker/ │ │ │ │ ├── meta.ts │ │ │ │ └── snippets.js │ │ │ ├── donut-chart/ │ │ │ │ └── meta.ts │ │ │ ├── edit-table/ │ │ │ │ └── meta.ts │ │ │ ├── expand-table/ │ │ │ │ └── meta.ts │ │ │ ├── filter/ │ │ │ │ └── meta.ts │ │ │ ├── filter-item/ │ │ │ │ └── meta.ts │ │ │ ├── group-table/ │ │ │ │ └── meta.ts │ │ │ ├── input/ │ │ │ │ └── meta.ts │ │ │ ├── line-chart/ │ │ │ │ └── meta.ts │ │ │ ├── month-picker/ │ │ │ │ └── meta.js │ │ │ ├── number-picker/ │ │ │ │ └── meta.ts │ │ │ ├── page-header/ │ │ │ │ ├── common/ │ │ │ │ │ └── props.ts │ │ │ │ ├── meta.design.js │ │ │ │ └── meta.ts │ │ │ ├── pie-chart/ │ │ │ │ └── meta.ts │ │ │ ├── pro-dialog/ │ │ │ │ └── meta.ts │ │ │ ├── pro-drawer/ │ │ │ │ └── meta.ts │ │ │ ├── pro-form/ │ │ │ │ ├── common/ │ │ │ │ │ ├── form-base-props.ts │ │ │ │ │ ├── form-item-props.ts │ │ │ │ │ └── props.ts │ │ │ │ ├── components/ │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── password.ts │ │ │ │ │ └── text-area.ts │ │ │ │ └── meta.ts │ │ │ ├── pro-table/ │ │ │ │ ├── actionColumnFields.ts │ │ │ │ ├── columns-field.ts │ │ │ │ ├── global-style.ts │ │ │ │ ├── meta.ts │ │ │ │ ├── pro-table-meta.ts │ │ │ │ └── utils.ts │ │ │ ├── pro-table-slot/ │ │ │ │ └── meta.ts │ │ │ ├── radio-group/ │ │ │ │ └── meta.js │ │ │ ├── range-picker/ │ │ │ │ └── meta.js │ │ │ ├── rating/ │ │ │ │ ├── meta.js │ │ │ │ └── snippets.js │ │ │ ├── select/ │ │ │ │ ├── meta.js │ │ │ │ └── snippets.js │ │ │ ├── step-form/ │ │ │ │ ├── meta.ts │ │ │ │ └── step-props.ts │ │ │ ├── story-placeholder/ │ │ │ │ └── meta.ts │ │ │ ├── tab-container/ │ │ │ │ ├── meta.ts │ │ │ │ └── props.ts │ │ │ ├── tree-select/ │ │ │ │ ├── meta.js │ │ │ │ └── snippets.js │ │ │ ├── types/ │ │ │ │ └── index.ts │ │ │ ├── upload/ │ │ │ │ └── meta.js │ │ │ ├── utils/ │ │ │ │ ├── form-utils.ts │ │ │ │ ├── index.ts │ │ │ │ └── keybindingService.ts │ │ │ ├── week-picker/ │ │ │ │ └── meta.js │ │ │ └── year-picker/ │ │ │ └── meta.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── common/ │ │ │ │ └── operations/ │ │ │ │ ├── index.scss │ │ │ │ └── index.tsx │ │ │ ├── components/ │ │ │ │ ├── anchor/ │ │ │ │ │ ├── components/ │ │ │ │ │ │ ├── HozAnchor/ │ │ │ │ │ │ │ ├── index.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ └── VerAnchor/ │ │ │ │ │ │ ├── AnchorList/ │ │ │ │ │ │ │ ├── AnchorLink.tsx │ │ │ │ │ │ │ ├── index.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── index.scss │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── index.scss │ │ │ │ │ ├── index.tsx │ │ │ │ │ ├── theme-dark.scss │ │ │ │ │ └── util.ts │ │ │ │ ├── area-chart/ │ │ │ │ │ └── index.tsx │ │ │ │ ├── bar-chart/ │ │ │ │ │ └── index.tsx │ │ │ │ ├── button/ │ │ │ │ │ ├── Button.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── button-group/ │ │ │ │ │ ├── ButtonGroup.tsx │ │ │ │ │ ├── i18n.ts │ │ │ │ │ └── index.tsx │ │ │ │ ├── column-chart/ │ │ │ │ │ └── index.tsx │ │ │ │ ├── container/ │ │ │ │ │ ├── Grid.tsx │ │ │ │ │ ├── Space.tsx │ │ │ │ │ ├── i18n.ts │ │ │ │ │ └── index.tsx │ │ │ │ ├── donut-chart/ │ │ │ │ │ └── index.tsx │ │ │ │ ├── ellipsis/ │ │ │ │ │ ├── index.scss │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── theme-dark.scss │ │ │ │ ├── expand-table/ │ │ │ │ │ ├── index.scss │ │ │ │ │ └── index.tsx │ │ │ │ ├── filter/ │ │ │ │ │ ├── index.scss │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── theme-dark.scss │ │ │ │ ├── line-chart/ │ │ │ │ │ └── index.tsx │ │ │ │ ├── menu/ │ │ │ │ │ ├── Menu.tsx │ │ │ │ │ ├── MenuItem.tsx │ │ │ │ │ ├── MenuItemText.tsx │ │ │ │ │ ├── i18n.ts │ │ │ │ │ ├── index.scss │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── theme-dark.scss │ │ │ │ ├── menu-button/ │ │ │ │ │ ├── index.scss │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── scss/ │ │ │ │ │ └── variable.scss │ │ │ │ ├── page-header/ │ │ │ │ │ ├── index.scss │ │ │ │ │ └── index.tsx │ │ │ │ ├── pie-chart/ │ │ │ │ │ └── index.tsx │ │ │ │ ├── pro-card/ │ │ │ │ │ ├── components/ │ │ │ │ │ │ ├── button-group/ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── card/ │ │ │ │ │ │ │ ├── index.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── card-collapse/ │ │ │ │ │ │ │ ├── index.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── card-header/ │ │ │ │ │ │ │ ├── index.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ └── card-section/ │ │ │ │ │ │ ├── index.scss │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── index.scss │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── theme-dark.scss │ │ │ │ ├── pro-dialog/ │ │ │ │ │ ├── dialog.tsx │ │ │ │ │ ├── index.scss │ │ │ │ │ └── index.tsx │ │ │ │ ├── pro-drawer/ │ │ │ │ │ ├── drawer.tsx │ │ │ │ │ ├── index.scss │ │ │ │ │ └── index.tsx │ │ │ │ ├── pro-form/ │ │ │ │ │ ├── components/ │ │ │ │ │ │ ├── Input.tsx │ │ │ │ │ │ ├── form-item/ │ │ │ │ │ │ │ ├── index.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ └── next-wrapper.tsx │ │ │ │ │ ├── index.scss │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── layouts/ │ │ │ │ │ ├── anchor-form/ │ │ │ │ │ │ ├── container.tsx │ │ │ │ │ │ ├── index.scss │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── child-form/ │ │ │ │ │ │ ├── index.scss │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── pro-form/ │ │ │ │ │ │ ├── index.scss │ │ │ │ │ │ └── index.tsx │ │ │ │ │ └── step-form/ │ │ │ │ │ ├── index.scss │ │ │ │ │ └── index.tsx │ │ │ │ ├── pro-table/ │ │ │ │ │ ├── components/ │ │ │ │ │ │ ├── edit-table/ │ │ │ │ │ │ │ ├── index.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── group-table/ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── pro-table/ │ │ │ │ │ │ │ ├── index.scss │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── pro-table-action-bar-buttons.tsx │ │ │ │ │ │ ├── pro-table-base/ │ │ │ │ │ │ │ ├── columns/ │ │ │ │ │ │ │ │ ├── useActionColumn.tsx │ │ │ │ │ │ │ │ ├── useIndexColumn.tsx │ │ │ │ │ │ │ │ └── useRowSelection.tsx │ │ │ │ │ │ │ ├── index.scss │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ └── utils.tsx │ │ │ │ │ │ ├── pro-table-button-group/ │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ └── payload-button.ts │ │ │ │ │ │ ├── pro-table-cell/ │ │ │ │ │ │ │ ├── cell-label.tsx │ │ │ │ │ │ │ ├── pro-table-cell.tsx │ │ │ │ │ │ │ └── pro-table-tree-cell.tsx │ │ │ │ │ │ ├── pro-table-cells/ │ │ │ │ │ │ │ └── utils.ts │ │ │ │ │ │ ├── pro-table-column/ │ │ │ │ │ │ │ ├── defaultColumnFormatters.tsx │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ └── pro-table-column-formatter.tsx │ │ │ │ │ │ ├── pro-table-column-title/ │ │ │ │ │ │ │ ├── index.scss │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ ├── pro-table-column-title-filter-panel.tsx │ │ │ │ │ │ │ ├── pro-table-column-title-filter.tsx │ │ │ │ │ │ │ ├── pro-table-column-title-sortter.tsx │ │ │ │ │ │ │ └── utils.ts │ │ │ │ │ │ ├── pro-table-compact-button.tsx │ │ │ │ │ │ ├── pro-table-fullscreen-button.tsx │ │ │ │ │ │ ├── pro-table-setting-button/ │ │ │ │ │ │ │ ├── index.scss │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ ├── pro-table-setting-overlay.tsx │ │ │ │ │ │ │ ├── pro-table-setting-sortable-list.tsx │ │ │ │ │ │ │ └── types.ts │ │ │ │ │ │ ├── pro-table-slot.tsx │ │ │ │ │ │ └── pro-table-zebra-button.tsx │ │ │ │ │ ├── contexts/ │ │ │ │ │ │ ├── pro-table-columns-context.tsx │ │ │ │ │ │ ├── pro-table-columns-filters-context.tsx │ │ │ │ │ │ ├── pro-table-columns-setting-context.tsx │ │ │ │ │ │ ├── pro-table-context.tsx │ │ │ │ │ │ ├── pro-table-pagination-context.tsx │ │ │ │ │ │ ├── pro-table-row-selection-context.tsx │ │ │ │ │ │ └── pro-table-setting-context.tsx │ │ │ │ │ ├── hooks.ts │ │ │ │ │ ├── i18n.ts │ │ │ │ │ ├── index.scss │ │ │ │ │ ├── index.tsx │ │ │ │ │ ├── theme-dark.scss │ │ │ │ │ └── types/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── instance.ts │ │ │ │ ├── segment/ │ │ │ │ │ ├── index.scss │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── theme-dark.scss │ │ │ │ ├── story-placeholder/ │ │ │ │ │ └── index.tsx │ │ │ │ ├── tab-container/ │ │ │ │ │ ├── index.scss │ │ │ │ │ └── index.tsx │ │ │ │ └── toggle-icon/ │ │ │ │ ├── index.scss │ │ │ │ ├── index.tsx │ │ │ │ └── theme-dark.scss │ │ │ ├── index.scss │ │ │ ├── index.tsx │ │ │ ├── provider/ │ │ │ │ ├── contexts/ │ │ │ │ │ ├── locale-context/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── util.ts │ │ │ │ │ └── theme-context/ │ │ │ │ │ └── index.ts │ │ │ │ ├── index.tsx │ │ │ │ └── provider.tsx │ │ │ ├── types/ │ │ │ │ ├── dataSource.ts │ │ │ │ ├── enum.ts │ │ │ │ └── index.ts │ │ │ ├── utils/ │ │ │ │ ├── checkComName.ts │ │ │ │ ├── constants.ts │ │ │ │ ├── currency.ts │ │ │ │ ├── dataSource/ │ │ │ │ │ ├── data-source-label.tsx │ │ │ │ │ ├── hooks.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── utils.ts │ │ │ │ ├── formatters.ts │ │ │ │ ├── hooks/ │ │ │ │ │ └── useFiledState.ts │ │ │ │ ├── index.ts │ │ │ │ ├── locales/ │ │ │ │ │ └── index.ts │ │ │ │ ├── object.ts │ │ │ │ ├── util/ │ │ │ │ │ ├── date.js │ │ │ │ │ ├── dom.js │ │ │ │ │ ├── env.js │ │ │ │ │ ├── events.js │ │ │ │ │ ├── focus.js │ │ │ │ │ ├── func.js │ │ │ │ │ ├── guid.js │ │ │ │ │ ├── htmlId.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── keycode.js │ │ │ │ │ ├── log.js │ │ │ │ │ ├── mobile/ │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── object.js │ │ │ │ │ ├── pick-attrs.js │ │ │ │ │ ├── string.js │ │ │ │ │ └── support.js │ │ │ │ └── variables.scss │ │ │ ├── variables.scss │ │ │ └── variables.tsx │ │ └── tsconfig.json │ └── graph-x6-materials/ │ ├── .editorconfig │ ├── .eslintignore │ ├── .eslintrc.js │ ├── .gitignore │ ├── .markdownlint.json │ ├── .markdownlintignore │ ├── .prettierrc.js │ ├── .stylelintignore │ ├── .stylelintrc.js │ ├── README.md │ ├── build.json │ ├── build.lowcode.js │ ├── commitlint.config.js │ ├── f2elint.config.js │ ├── jest.config.js │ ├── lowcode/ │ │ ├── line/ │ │ │ └── meta.ts │ │ ├── send-email/ │ │ │ └── meta.ts │ │ └── start-end/ │ │ └── meta.ts │ ├── package.json │ ├── src/ │ │ ├── components/ │ │ │ ├── line/ │ │ │ │ └── index.tsx │ │ │ ├── send-email/ │ │ │ │ └── index.tsx │ │ │ └── start-end/ │ │ │ └── index.tsx │ │ ├── index.scss │ │ ├── index.tsx │ │ ├── sync-oss.js │ │ ├── variables.scss │ │ └── variables.tsx │ └── tsconfig.json ├── scripts/ │ └── update-readme.js ├── tsconfig.json └── typings.d.ts ================================================ FILE CONTENTS ================================================ ================================================ FILE: .editorconfig ================================================ root = true [*] indent_style = space indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true quote_type = single [*.md] trim_trailing_whitespace = false ================================================ FILE: .eslintignore ================================================ build/ coverage/ dist/ es/ lib/ node_modules/ **/*.min.js **/*-min.js **/*.bundle.js ================================================ FILE: .eslintrc.js ================================================ module.exports = { extends: [ 'eslint-config-ali/typescript/react', 'prettier', 'prettier/@typescript-eslint', 'prettier/react', ], }; ================================================ FILE: .gitignore ================================================ lowcode_es/ lowcode_lib/ # project custom build dist site .tmp es public/resources/meta.json packages/*/lib/ packages/*/es/ packages/*/dist/ packages/*/output/ package-lock.json yarn.lock deploy-space/packages deploy-space/.env # IDE .vscode .idea # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* lerna-debug.log* # Runtime data pids *.pid *.seed *.pid.lock # Directory for instrumented libs generated by jscoverage/JSCover lib-cov # Coverage directory used by tools like istanbul coverage # nyc test coverage .nyc_output # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) .grunt # Bower dependency directory (https://bower.io/) bower_components # node-waf configuration .lock-wscript # Compiled binary addons (https://nodejs.org/api/addons.html) build/Release lib # Dependency directories node_modules/ jspm_packages/ # TypeScript v1 declaration files typings/ # Optional npm cache directory .npm # Optional eslint cache .eslintcache # Optional REPL history .node_repl_history # Output of 'npm pack' *.tgz # Yarn Integrity file .yarn-integrity # dotenv environment variables file .env .env.test # parcel-bundler cache (https://parceljs.org/) .cache # next.js build output .next # nuxt.js build output .nuxt # vuepress build output .vuepress/dist # Serverless directories .serverless/ # FuseBox cache .fusebox/ # DynamoDB Local files .dynamodb/ # mac config files .DS_Store # codealike codealike.json src/assets.js src/assets.json src/assets.container.js src/assets.container.json assets.json assets.container.json material-meta.json ================================================ FILE: .markdownlint.json ================================================ { "extends": "markdownlint-config-ali" } ================================================ FILE: .markdownlintignore ================================================ node_modules/ build/ dist/ coverage/ es/ lib/ ================================================ FILE: .prettierrc.js ================================================ module.exports = { printWidth: 100, tabWidth: 2, semi: true, singleQuote: true, trailingComma: 'all', arrowParens: 'always', }; ================================================ FILE: .stylelintignore ================================================ node_modules/ build/ dist/ coverage/ es/ lib/ **/*.min.css **/*-min.css **/*.bundle.css ================================================ FILE: .stylelintrc.js ================================================ module.exports = { extends: 'stylelint-config-ali', }; ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2021 Alibaba Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================

Lowcode Materials

基于 [Fusion Design](https://fusion.design) 和 [Ant Design](https://ant.design) 设计规范的低代码基础物料库
## 介绍 / Introduce 物料(Material)是指能够被沉淀下来的前端能力,一般表现为组件、区块和模板。而低代码物料库,则是一套专门用于低代码开发模式(Lowcode)的物料,它除了包含物料组件,还有一套描述组件信息的低代码引擎物料协议。简单来说,低代码物料库包含了两个部分: - 组件的实现,即组件的代码和样式 - 遵循[《低代码引擎物料协议规范》](https://lowcode-engine.cn/material)的物料协议 低代码物料应该配合[低代码引擎](https://lowcode-engine.cn/)使用,如果你还不了解低代码引擎,请先阅读相关文档。 在使用中遇到的任何问题,请在[lowcode-engine](https://github.com/alibaba/lowcode-engine)项目中反馈。

Fusion Design For Lowcode

[![NPM version][npm-image-fusion]][npm-url-fusion] ### [在线示例 / DEMO](https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.2.1/build/lowcode/index.html) ### 使用 / Usage #### NPM ```js const { material } from '@alilc/lowcode-engine'; const assets = require('@alilc/lowcode-materials/dist/assets.json'); // in GeneralWorkbench init material.setAssets(assets); ``` #### CDN ```js // in GeneralWorkbench init const assets = await fetch( `https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.2.1/dist/assets.json`, ).then((res) => res.json()); material.setAssets(assets); ``` [npm-image-fusion]: https://img.shields.io/npm/v/@alilc/lowcode-materials.svg?style=flat-square [npm-url-fusion]: http://npmjs.org/package/@alilc/lowcode-materials

Ant Design For Lowcode

[![NPM version][npm-image-antd]][npm-url-antd] ### [在线示例 / DEMO](https://alifd.alicdn.com/npm/@alilc/antd-lowcode-materials@1.2.2/build/lowcode/index.html) ### 使用 / Usage #### NPM ```js const { material } from '@alilc/lowcode-engine'; const assets = require('@alilc/antd-lowcode-materials/build/lowcode/assets-prod.json'); // in GeneralWorkbench init material.setAssets(assets); ``` #### CDN ```js // in GeneralWorkbench init const assets = await fetch( `https://alifd.alicdn.com/npm/@alilc/antd-lowcode-materials@1.2.2/build/lowcode/assets-prod.json`, ).then((res) => res.json()); material.setAssets(assets); ``` [npm-image-antd]: https://img.shields.io/npm/v/@alilc/antd-lowcode-materials.svg?style=flat-square [npm-url-antd]: http://npmjs.org/package/@alilc/antd-lowcode-materials ## 如何贡献 / How-to-contribute ### 目录结构 / Structure ``` |-packages |-{package-name} // fusion 或 antd 低代码组件包 |-lowcode // 组件低代码描述文件 |-{component-name} |-meta.ts // 组件低代码描述协议 |-meta.design.ts // 【可选】面向设计者的组件低代码描述,移除面向研发的高级配置能力,可做静态搭建和简单的交互 |-src |-index.tsx // 组件库导出文件 |-components // 组件库源码 |-{component-name} |-index.tsx |-index.scss |-build.lowcode.js // 低代码调试和构建使用的配置文件 |-build.json // 源码调试和构建使用的配置文件 ``` ### 常用命令 / Commands #### 低代码 / LowCode ```bash cd packages/fusion-lowcode-materilas # OR `cd packages/antd-lowcode-materilas` npm run lowcode:dev npm run lowcode:build ``` #### 源码 / ProCode ```bash npm start npm run build ``` #### 其他命令 / Other Commands ```bash # 更新 README 中的版本号 npm run update-readme ``` ### 贡献者 / Contributors 因无法保留开源前的提交记录,这里列出开源前的贡献者(花名): @荣彬 @度城 @屹凡 @启剑 @春希 @梧忌 @褚天 @莫夭 @金禅 @默吉 @旅途 @斩鲌 @永元 @听鸿 @晓吉 @与白 @若泉 @独寒 @尤恩 @馨焱 ================================================ FILE: commitlint.config.js ================================================ module.exports = { extends: ['ali'], }; ================================================ FILE: f2elint.config.js ================================================ module.exports = { enableStylelint: true, enableMarkdownlint: true, enablePrettier: true, }; ================================================ FILE: package.json ================================================ { "name": "lowcode-materials", "private": true, "version": "0.0.0", "description": "Materials for LowCode", "scripts": { "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'", "f2elint-scan": "f2elint scan", "f2elint-fix": "f2elint fix", "update-readme": "node scripts/update-readme.js", "prepublishOnly": "npm run build && npm run lowcode:build && npm run lowcode:antd:build" }, "lint-staged": { "*.ts?(x)": [ "prettier --parser=typescript --write" ], "*.{js,jsx,less,md,json}": [ "prettier --write" ] }, "devDependencies": { "f2elint": "^2.2.0", "glob": "^11.0.0", "lint-staged": "^10.5.3", "prettier": "^1.19.1", "typescript": "^3.9.3", "yorkie": "^2.0.0" }, "authors": [ { "name": "金禅" }, { "name": "荣彬" }, { "name": "屹凡" }, { "name": "启剑" }, { "name": "春希" }, { "name": "度城" }, { "name": "梧忌" }, { "name": "莫夭" } ], "license": "MIT", "husky": { "hooks": { "pre-commit": "f2elint commit-file-scan", "commit-msg": "f2elint commit-msg-scan" } } } ================================================ FILE: packages/antd-lowcode-materials/README.md ================================================

Ant Design For Lowcode

[![NPM version][npm-image-antd]][npm-url-antd] ### [在线示例 / DEMO](https://alifd.alicdn.com/npm/@alilc/antd-lowcode-materials@1.2.2/build/lowcode/index.html) ### 使用 / Usage #### NPM ```js const { material } from '@alilc/lowcode-engine'; const assets = require('@alilc/antd-lowcode-materials/build/lowcode/assets-prod.json'); // in GeneralWorkbench init material.setAssets(assets); ``` #### CDN ```js // in GeneralWorkbench init const assets = await (await fetch(`https://alifd.alicdn.com/npm/@alilc/antd-lowcode-materials@1.2.2/build/lowcode/assets-prod.json`)).json(); material.setAssets(assets); ``` [npm-image-antd]: https://img.shields.io/npm/v/@alilc/antd-lowcode-materials.svg?style=flat-square [npm-url-antd]: http://npmjs.org/package/@alilc/antd-lowcode-materials ================================================ FILE: packages/antd-lowcode-materials/build.json ================================================ { "sourceMap": false, "alias": { "@": "./src", "@components": "./src/components" }, "plugins": [["build-plugin-component"]] } ================================================ FILE: packages/antd-lowcode-materials/build.lowcode.js ================================================ const { name, version } = require("./package.json"); const library = 'AntdLowcode'; module.exports = { sourceMap: false, alias: { '@': './src', lowcode: './lowcode' }, plugins: [ [ '@alifd/build-plugin-lowcode', { noParse: true, engineScope: '@alilc', library, staticResources: { engineCoreCssUrl: 'https://alifd.alicdn.com/npm/@alilc/lowcode-engine@1.2.1/dist/css/engine-core.css', engineExtCssUrl: 'https://alifd.alicdn.com/npm/@alilc/lowcode-engine-ext@1.0.6/dist/css/engine-ext.css', engineCoreJsUrl: 'https://alifd.alicdn.com/npm/@alilc/lowcode-engine@1.2.1/dist/js/engine-core.js', engineExtJsUrl: 'https://alifd.alicdn.com/npm/@alilc/lowcode-engine-ext@1.0.6/dist/js/engine-ext.js', }, npmInfo: { package: name, version, }, lowcodeDir: 'lowcode', entryPath: 'src/index.tsx', categories: ['通用', '导航', '信息输入', '信息展示', '信息反馈'], baseUrl: { prod: `https://alifd.alicdn.com/npm/${name}@${version}`, daily: `https://alifd.alicdn.com/npm/${name}@${version}`, }, builtinAssets: [ { packages: [ { package: 'moment', version: '2.24.0', urls: ['https://g.alicdn.com/mylib/moment/2.24.0/min/moment.min.js'], library: 'moment', }, { package: 'lodash', library: '_', urls: ['https://g.alicdn.com/platform/c/lodash/4.6.1/lodash.min.js'], }, { package: 'iconfont-icons', urls: '//at.alicdn.com/t/font_2369445_ukrtsovd92r.js', }, { package: '@ant-design/icons', version: '4.7.0', urls: [`//g.alicdn.com/code/npm/@ali/ant-design-icons-cdn/4.5.0/index.umd.min.js`], library: 'icons', }, { package: 'antd', version: '4.23.0', urls: [ `//g.alicdn.com/code/lib/antd/4.23.0/antd.min.js`, `//g.alicdn.com/code/lib/antd/4.23.0/antd.min.css`, ], library: 'antd', }, ], components: [], }, ], }, ], ], }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/_setters/antd-icon-setter/index.tsx ================================================ import React, { useState, useEffect, Component } from 'react'; // setter使用@alifd/next,和编辑器保持一致 import { Input, Icon as NextIcon, Radio, Balloon, Search } from '@alifd/next'; import { get } from '../../_utils/utils'; import './style.less'; type IconGroup = 'outlined' | 'filled' | 'two-tone' | 'iconfont'; const IconGroupNameMap: Record = { outlined: '线框风格', filled: '实底风格', 'two-tone': '双色风格', iconfont: 'Iconfont', }; function getIconfontIconList() { const iframe = document.querySelector( 'iframe.lc-simulator-content-frame', )!; const antdIcons = get(iframe, 'contentWindow.icons', {}) as Record< string, any >; // iconfont的js会在页面中添加svg元素 const symbols = Array.prototype.slice.call( iframe.contentDocument!.querySelectorAll( 'svg[style="position: absolute; width: 0px; height: 0px; overflow: hidden;"][aria-hidden="true"] > symbol', ), ); const Icon = antdIcons.createFromIconfontCN(); return symbols.map(symbol => { const { id } = symbol; return { name: id, group: 'iconfont', icon: (props: any) => ( ), }; }); } function getAntdIconList() { const iframe = document.querySelector( 'iframe.lc-simulator-content-frame', ); const icons: Record = {}; // document.querySelectorAll('svg[style="position: absolute; width: 0px; height: 0px; overflow: hidden;"][aria-hidden="true"]') const antdIcons = get(iframe, 'contentWindow.icons', {}) as Record< string, any >; return Object.keys(antdIcons) .map(key => { const item = (antdIcons as any)[key]; if (typeof item !== 'object') { return null; } const name = item?.displayName ?? item?.render?.displayName ?? key; let group: IconGroup = 'outlined'; const lowercaseName = name.toLowerCase(); if (/outlined$/.test(lowercaseName)) { group = 'outlined'; } else if (/filled$/.test(lowercaseName)) { group = 'filled'; } else if (/twotone$/.test(lowercaseName)) { group = 'two-tone'; } else { return null; } return { name, group, icon: item, }; }) .filter(Boolean); } function getIconList() { const iconfontIconList = getIconfontIconList(); const antdIconList = getAntdIconList(); return [...antdIconList, ...iconfontIconList]; } const Icon = (props: any) => { const { type, icons = {}, ...rest } = props; const Comp = icons[type]; if (!Comp) return null; return ; }; interface AntdIconSetterProps { value: string; type: string; defaultValue: string; placeholder: string; hasClear: boolean; onChange: (icon: string | object) => undefined; icons: string[]; } const Tooltip = Balloon.Tooltip; const AntdIconSetter = (props: AntdIconSetterProps) => { const [search, setSearch] = useState(''); const [icons, setIcons] = useState>({}); const [groups, setGroups] = useState<{ group: IconGroup; list: any[] }[]>([]); const [selectedGroup, setSelectedGroup] = useState('outlined'); const [firstLoad, setFirstLoad] = useState(true); const [list, setList] = useState([]); const { value, defaultValue, type, onChange, placeholder, hasClear } = props; const _value = typeof value === 'object' ? (value as any)?.props?.type : value; if (firstLoad && defaultValue && typeof value === 'undefined') { onChange(defaultValue); setFirstLoad(false); } const handleChange = (icon: string) => { if (type === 'string') { onChange(icon); } else if (type === 'node') { onChange({ componentName: 'Icon', props: { type: icon, }, }); } }; useEffect(() => { const iconList = getIconList(); const groups: { group: IconGroup; list: any[] }[] = []; const icons: any = {}; iconList.forEach(item => { const { group, name, icon } = item!; if (groups.every(item => item.group !== group)) { groups.push({ group: group as IconGroup, list: [] }); } const target = groups.find(item => item.group === group)!; target.list.push(item); icons[item!.name] = item?.icon; }); setIcons(icons); setGroups(groups); setSelectedGroup(groups[0]?.group); }, []); useEffect(() => { const currentGroup = groups.find(item => item.group === selectedGroup); setList( (currentGroup?.list ?? []).filter(item => { return search ? item.name.toLowerCase().indexOf(search.toLowerCase()) > -1 : true; }), ); }, [selectedGroup, search, groups]); const currentIcon = ( ); const clearIcon = hasClear && ( { e.preventDefault(); e.stopPropagation(); handleChange(''); }} /> ); const triggerNode = (
); return (
setSelectedGroup(value as any)} > {groups.map(item => ( {IconGroupNameMap[item.group]} ))}
    {list.map(item => (
  • handleChange(item.name)} > } popupStyle= {{backgroundColor: "#fff"}}> {item.name}
  • ))}
); }; AntdIconSetter.defaultProps = { value: undefined, type: 'string', defaultValue: '', hasClear: false, placeholder: '请点击选择 Icon', onChange: () => undefined, }; // 因为下面这个问题,setter必须使用class组件 // http://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/issues/109046 export default class extends Component { render() { return ; } } ================================================ FILE: packages/antd-lowcode-materials/lowcode/_setters/antd-icon-setter/style.less ================================================ .lc-antd-icon-setter { &-header { &-style { width: 100%; margin-bottom: 12px; display: flex; > label { flex: 1; text-align: center; } } &-search { width: 100%; margin-bottom: 12px; padding-bottom: 12px; border-bottom: 1px solid #ddd; } } &-list { display: block; max-height: 400px; overflow-y: auto; overflow-x: hidden; &-item { display: inline-block; position: relative; width: 36px; height: 36px; line-height: 36px; text-align: center; font-size: 24px; border-radius: 4px; transition: background-color 0.2s; &-name { display: none; font-size: 14px; position: absolute; height: 30px; word-break: keep-all; white-space: nowrap; bottom: -24px; left: 50%; z-index: 100; height: 24px; line-height: 24px; padding: 0 5px; border-radius: 4px; background-color: #fff; pointer-events: none; transform: translateX(-50%); box-shadow: 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 9px 28px 8px rgba(0, 0, 0, 0.05); } &:hover { background-color: #f1f2f3; .lc-antd-icon-setter-list-item-name { display: block; } } } } } ================================================ FILE: packages/antd-lowcode-materials/lowcode/_setters/index.tsx ================================================ export { default as AntdIconSetter } from './antd-icon-setter'; ================================================ FILE: packages/antd-lowcode-materials/lowcode/_utils/hoc.tsx ================================================ import React, { ComponentType, ReactNode, useState } from 'react'; import moment from 'moment'; import { get, set, has } from './utils'; function convertProps( props: Record, list: string[], mapper: (v: any, key: string) => any, ) { const out: Record = {}; list.forEach(key => { if (has(props, key)) { set(out, key, mapper(get(props, key), key)); } }); return out; } /** * 简单包装,不做任何处理 * 部分组件ref比较特殊,包一层会解决这个问题 */ export function withWrap(Comp: ComponentType) { return (props: any) => { return ; }; } /** * 某些组件会用React.Children.only检查子节点 * 需要做处理避免报错 */ export function withSingleChild( Comp: ComponentType, needsConvert = ['children'], ) { return (props: any) => { const convertedProps = convertProps(props, needsConvert, prop => { let node = React.Children.toArray(prop)[0]; if (node === null || typeof node !== 'object') { node =
{node}
; } return node; }); return ; }; } export function withSingleFunctionChild(Comp: ComponentType) { return (props: any) => { const { children } = props; let node; if (typeof children === 'function') { node = children; } if ( Array.isArray(children) && children.length === 1 && typeof children[0] === 'function' ) { node = children[0]; } if (node) { return {node}; } return
{children}
; }; } /** * moment对象在序列化后会被转为字符串 * 需要让日期类组件支持接受字符串值 */ export function withMomentProps( Comp: ComponentType, needsConvert = ['value', 'defaultValue'], ) { return (props: any) => { const convertedProps = convertProps(props, needsConvert, prop => { if (prop) { if (Array.isArray(prop)) { return prop.map(v => (moment.isMoment(v) ? v : moment(v))); } return moment.isMoment(prop) ? prop : moment(prop); } }); return ; }; } ================================================ FILE: packages/antd-lowcode-materials/lowcode/_utils/transform-meta.ts ================================================ import { FieldConfig, PropConfig, PropType, SetterType, OneOf, ObjectOf, ArrayOf, TransformedComponentMetadata, } from '@ali/lowcode-types'; // http://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/merge_requests/1054678 // 这个MR合并后可以去掉这个文件 function propConfigToFieldConfig( propConfig: PropConfig, supportVariable: boolean, ): FieldConfig { const { name, description } = propConfig; const title = { label: { type: 'i18n', 'en-US': name, 'zh-CN': description?.slice(0, 10) || name, }, tip: description ? `${name} | ${description}` : undefined, }; let setter = (propConfig as any).setter || propTypeToSetter(propConfig.propType, supportVariable); if (supportVariable && (propConfig as any).supportVariable !== false) { if ( setter.componentName === 'MixedSetter' && setter.props?.setters && setter.props?.setters?.every((setter: any) => { return ( setter?.componentName !== 'VariableSetter' && setter !== 'VariableSetter' ); }) ) { setter.props.setters.push('VariableSetter'); } else if ( setter && setter !== 'VariableSetter' && setter.componentName !== 'VariableSetter' ) { setter = { componentName: 'MixedSetter', props: { setters: [setter, 'VariableSetter'], }, }; } } return { title, ...propConfig, // TODO 这边直接用propConfig,将setter丢在propconfig里,需要确认是否在PropConfig扩展还是换实现 setter, }; } function propTypeToSetter( propType: PropType, supportVariable: boolean, ): SetterType { let typeName: string; let isRequired: boolean | undefined = false; if (typeof propType === 'string') { typeName = propType; } else if (typeof propType === 'object') { typeName = propType.type; isRequired = propType.isRequired; } else { typeName = 'string'; } // TODO: use mixinSetter wrapper switch (typeName) { case 'string': return { componentName: 'StringSetter', isRequired, initialValue: '', }; case 'number': return { componentName: 'NumberSetter', isRequired, initialValue: 0, }; case 'bool': return { componentName: 'BoolSetter', isRequired, initialValue: false, }; case 'oneOf': const dataSource = ((propType as OneOf).value || []).map( (value, index) => { const t = typeof value; return { label: t === 'string' || t === 'number' || t === 'boolean' ? String(value) : `value ${index}`, value, }; }, ); const componentName = dataSource.length >= 4 ? 'SelectSetter' : 'RadioGroupSetter'; return { componentName, props: { dataSource, options: dataSource }, isRequired, initialValue: dataSource[0] ? dataSource[0].value : null, }; case 'element': case 'node': // TODO: use Mixin return { // slotSetter componentName: 'SlotSetter', props: { mode: typeName, }, isRequired, initialValue: { type: 'JSSlot', value: [], }, }; case 'shape': case 'exact': const items = ((propType as any).value || []).map((item: any) => propConfigToFieldConfig(item, supportVariable), ); return { componentName: 'ObjectSetter', props: { config: { items, extraSetter: typeName === 'shape' ? propTypeToSetter('any', supportVariable) : null, }, }, isRequired, initialValue: (field: any) => { const data: any = {}; items.forEach((item: any) => { let initial = item.defaultValue; if ( initial == null && item.setter && typeof item.setter === 'object' ) { initial = (item.setter as any).initialValue; } data[item.name] = initial ? typeof initial === 'function' ? initial(field) : initial : null; }); return data; }, }; case 'object': case 'objectOf': return { componentName: 'ObjectSetter', props: { config: { extraSetter: propTypeToSetter( typeName === 'objectOf' ? (propType as ObjectOf).value : 'any', supportVariable, ), }, }, isRequired, initialValue: {}, }; case 'array': case 'arrayOf': return { componentName: 'ArraySetter', props: { itemSetter: propTypeToSetter( typeName === 'arrayOf' ? (propType as ArrayOf).value : 'any', supportVariable, ), }, isRequired, initialValue: [], }; case 'func': return { componentName: 'FunctionSetter', isRequired, }; case 'color': return { componentName: 'ColorSetter', isRequired, }; case 'oneOfType': return { componentName: 'MixedSetter', props: { // TODO: setters: (propType as any).value.map((item: any) => propTypeToSetter(item, supportVariable), ), }, isRequired, }; default: // do nothing } return { componentName: 'MixedSetter', isRequired, props: {}, }; } const NO_EVENTS = ['beforeUpload']; const EVENT_RE = /^on|after|before[A-Z][\w]*$/; export default function( metadata: TransformedComponentMetadata, supportVariable: boolean, ): TransformedComponentMetadata { const { configure = {} } = metadata; // TODO types后续补充 let extendsProps: any = null; if (configure.props) { if (Array.isArray(configure.props)) { return metadata; } const { isExtends, override = [] } = configure.props; // 不开启继承时,直接返回configure配置 if (!isExtends) { return { ...metadata, configure: { ...configure, props: [...override], }, }; } extendsProps = {}; // 开启继承后,缓存重写内容的配置 override.forEach((prop: any) => { extendsProps[prop.name] = prop; }); } if (!metadata.props) { return { ...metadata, configure: { ...configure, props: [], }, }; } const { component = {}, supports = {} } = configure; const supportedEvents: any[] | null = (supports as any).events ? null : []; const props: FieldConfig[] = []; metadata.props.forEach(prop => { const { name, propType, description } = prop; if ( name === 'children' && (component.isContainer || propType === 'node' || propType === 'element' || propType === 'any') ) { if (component.isContainer !== false) { component.isContainer = true; props.push(propConfigToFieldConfig(prop, supportVariable)); return; } } if ( EVENT_RE.test(name) && NO_EVENTS.indexOf(name) < 0 && (propType === 'func' || propType === 'any') ) { if (supportedEvents) { supportedEvents.push({ name, description, }); (supports as any).events = supportedEvents; } return; } if (name === 'className' && (propType === 'string' || propType === 'any')) { if ((supports as any).className == null) { (supports as any).className = true; } return; } if (name === 'style' && (propType === 'object' || propType === 'any')) { if ((supports as any).style == null) { (supports as any).style = true; } return; } // 存在覆盖配置时 if (extendsProps) { if (name in extendsProps) { prop = extendsProps[name]; } } props.push(propConfigToFieldConfig(prop, supportVariable)); }); return { ...metadata, configure: { ...configure, props, supports, component, }, } as any; } ================================================ FILE: packages/antd-lowcode-materials/lowcode/_utils/utils.ts ================================================ export { get, set, has } from 'lodash'; // simple uuid export function uuid() { return ((Math.random() * 1e6) >> 0).toString(36); } ================================================ FILE: packages/antd-lowcode-materials/lowcode/affix/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Affix', title: '固钉', category: '导航', props: [ { name: 'offsetBottom', title: { label: '底部触发距离', tip: '距离窗口底部达到指定偏移量后触发' }, propType: 'number', }, { name: 'offsetTop', title: { label: '顶部触发距离', tip: '距离窗口顶部达到指定偏移量后触发' }, propType: 'number', }, { name: 'target', title: { label: '获取触发元素', tip: '设置 `Affix` 需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数', }, propType: 'func', }, { name: 'onChange', title: { label: '监听状态改变', tip: '固定状态改变时触发的回调函数' }, propType: 'func', }, ], configure: { supports: { style: true, events: [ { name: 'onChange', template: "onChange(affixed,${extParams}){\n// 固定状态变更回调函数\nconsole.log('onChange', affixed);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/affix/snippets.ts ================================================ export default [ { title: '固钉', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/affix-1.jpg', schema: { componentName: 'Affix', props: { offsetTop: 100, }, children: [ { componentName: 'Button', props: { children: 'Affix Top', }, }, ], }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/alert/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Alert', title: '警告提示', category: '反馈', props: [ { name: 'afterClose', title: { label: '关闭动画结束后触发的回调函数', tip: '关闭动画结束后触发的回调函数', }, propType: 'func', }, { name: 'banner', title: { label: '顶部公告', tip: '是否用作顶部公告' }, propType: 'bool', defaultValue: false, }, { name: 'closable', title: { label: '可关闭', tip: '默认不显示关闭按钮' }, propType: 'bool', }, { name: 'closeText', title: { label: '自定义关闭按钮', tip: '自定义关闭按钮' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'description', title: { label: '描述信息', tip: '警告提示的辅助性文字介绍', }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'icon', title: { label: '图标', tip: '自定义图标,`showIcon` 为 true 时有效', }, propType: 'node', }, { name: 'message', title: { label: '警告提示内容', tip: '警告提示内容' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'showIcon', title: { label: '显示图标', tip: '是否显示辅助图标' }, propType: 'bool', }, { name: 'type', title: { label: '类型', tip: '类型' }, propType: { type: 'oneOf', value: ['success', 'info', 'warning', 'error'], }, }, { name: 'onClose', title: { label: '关闭时触发的回调函数', tip: '关闭时触发的回调函数' }, propType: 'func', }, ], configure: { supports: { style: true, events: [ { name: 'onClose', template: "onChange(event,${extParams}){\n// 关闭时触发的回调函数\nconsole.log('onChange');}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/alert/snippets.ts ================================================ export default [ { title: '成功提示', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/alert-1.png', schema: { componentName: 'Alert', props: { message: 'Success Tips', description: 'Detailed description and advice about successful copywriting.', type: 'success', showIcon: true, }, }, }, { title: '信息提示', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/alert-2.png', schema: { componentName: 'Alert', props: { message: 'Informational Notes', description: 'Additional description and information about copywriting.', type: 'info', showIcon: true, }, }, }, { title: '警告提示', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/alert-3.png', schema: { componentName: 'Alert', props: { message: 'Warning', description: 'This is a warning notice about copywriting.', type: 'warning', showIcon: true, }, }, }, { title: '错误提示', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/alert-4.png', schema: { componentName: 'Alert', props: { message: 'Error', description: 'This is an error message about copywriting.', type: 'error', showIcon: true, }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/anchor/snippets.ts ================================================ export default [ { title: '锚点', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/anchor-1.png', schema: { componentName: 'Anchor', props: {}, children: [ { componentName: 'Anchor.Link', props: { title: 'Document', }, }, { componentName: 'Anchor.Link', props: { title: 'API', }, }, { componentName: 'Anchor.Link', props: { title: 'Demo', }, }, ], }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/anchor.link/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Anchor.Link', title: '锚点链接', category: '其他', props: [ { name: 'href', title: { label: '锚点链接', tip: '锚点链接' }, propType: 'string', }, { name: 'target', title: { label: 'target', tip: '该属性指定在何处显示链接的资源', }, propType: 'string', }, { name: 'title', title: { label: '内容', tip: '内容' }, propType: 'string', }, ], configure: { supports: { style: true } }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/anchor.link/snippets.ts ================================================ export default []; ================================================ FILE: packages/antd-lowcode-materials/lowcode/auto-complete/meta.ts ================================================ import { uuid } from '../_utils/utils'; import snippets from './snippets'; export default { snippets, componentName: 'AutoComplete', title: '辅助提示输入框', category: '表单', props: [ { name: 'defaultValue', title: { label: '默认值', tip: '默认选中值' }, propType: 'string', }, { name: 'value', title: { label: '当前值', tip: '当前选中值' }, propType: 'string', }, { name: 'allowClear', title: { label: '支持清除', tip: '是否允许清除' }, propType: 'bool', defaultValue: false, }, { name: 'options', title: { label: '选项内容', tip: '选项列表' }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'label', title: '选项名', setter: 'StringSetter', }, { name: 'value', title: '选项值', setter: 'StringSetter', }, ], }, }, initialValue: () => { return { label: '选项名', value: uuid(), }; }, }, }, }, }, { name: 'autoFocus', title: { label: '自动聚焦', tip: '自动获取焦点' }, propType: 'bool', defaultValue: false, }, { name: 'backfill', title: { label: '键盘选中回填', tip: '使用键盘选择选项的时候把选中项回填到输入框中', }, propType: 'bool', defaultValue: false, }, { name: 'defaultActiveFirstOption', title: { label: '默认高亮首个选项', tip: '是否默认高亮第一个选项' }, propType: 'bool', defaultValue: true, }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态' }, propType: 'bool', defaultValue: false, }, { name: 'filterOption', title: { label: '可选项筛选', tip: '是否根据输入项进行筛选' }, propType: 'bool', }, { name: 'placeholder', title: { label: '输入框提示', tip: '输入框提示' }, propType: 'string', }, { name: 'onBlur', title: { label: '失去焦点时的回调', tip: '失去焦点时的回调' }, propType: 'func', }, { name: 'onChange', title: { label: 'value变化时的回调', tip: '选中 option,或 input 的 value 变化时,调用此函数', }, propType: 'func', }, { name: 'onFocus', title: { label: '获得焦点时的回调', tip: '获得焦点时的回调' }, propType: 'func', }, { name: 'onSearch', title: { label: '搜索补全项的时候调用', tip: '搜索补全项的时候调用' }, propType: 'func', }, { name: 'onSelect', title: { label: '被选中时的回调', tip: '被选中时调用,参数为选中项的 value 值', }, propType: 'func', }, { name: 'defaultOpen', title: { label: '默认展开菜单', tip: '是否默认展开下拉菜单' }, propType: 'bool', }, // { // name: 'open', // title: { label: '展开下拉菜单', tip: '是否展开下拉菜单' }, // propType: 'bool', // }, { name: 'onDropdownVisibleChange', title: { label: '展开下拉菜单的回调', tip: '展开下拉菜单的回调' }, propType: 'func', }, { name: 'notFoundContent', title: { label: '无数据展示', tip: '当下拉列表为空时显示的内容' }, propType: 'string', }, ], configure: { props: [ { name: 'defaultValue', title: { label: { type: 'i18n', zh_CN: '默认值', en_US: 'Default Value', }, tip: { type: 'i18n', zh_CN: '属性: defaultValue | 说明: 默认值', en_US: 'prop: defaultValue | description: defaultValue', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'value', title: { label: { type: 'i18n', zh_CN: '当前值', en_US: 'Value', }, tip: { type: 'i18n', zh_CN: '属性: Value | 说明: 当前值', en_US: 'prop: Value | description: Value', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'allowClear', title: { label: { type: 'i18n', zh_CN: '支持清除', en_US: 'Allow Clear', }, tip: { type: 'i18n', zh_CN: '属性: allowClear | 说明:是否允许清除', en_US: 'prop: allowClear | description: Allow Clear', } }, setter: 'BoolSetter', supportVariable: true, }, { name: 'options', title: { label: { type: 'i18n', zh_CN: '选项内容', en_US: 'Options', }, tip: { type: 'i18n', zh_CN: '属性: options | 说明:选项列表', en_US: 'prop: options | description: Options', } }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'label', title: '选项名', setter: 'StringSetter', isRequired: true }, { name: 'value', title: '选项值', setter: 'StringSetter', isRequired: true }, ], }, }, initialValue: () => { return { label: '选项名', value: uuid(), }; }, }, }, }, }, { name: 'autoFocus', title: { label: { type: 'i18n', zh_CN: '自动聚焦', en_US: 'Auto Focus', }, tip: { type: 'i18n', zh_CN: '属性: autoFocus | 说明:自动获取焦点', en_US: 'prop: autoFocus | description: Auto Focus', } }, setter: 'BoolSetter', supportVariable: true, }, { name: 'backfill', title: { label: { type: 'i18n', zh_CN: '键盘选中回填', en_US: 'Backfill', }, tip: { type: 'i18n', zh_CN: '属性: backfill | 说明:使用键盘选择选项的时候把选中项回填到输入框中', en_US: 'prop: backfill | description: When using the keyboard to select options, backfill the selected items into the input box', } }, setter: 'BoolSetter', supportVariable: true, }, { name: 'defaultActiveFirstOption', title: { label: { type: 'i18n', zh_CN: '默认高亮首个选项', en_US: 'Default Active First Option', }, tip: { type: 'i18n', zh_CN: '属性: defaultActiveFirstOption | 说明:是否默认高亮第一个选项', en_US: 'prop: defaultActiveFirstOption | description: Whether to highlight the first option by default', } }, setter: 'BoolSetter', defaultValue: true, supportVariable: true, }, { name: 'disabled', title: { label: { type: 'i18n', zh_CN: '是否禁用', en_US: 'Disabled', }, tip: { type: 'i18n', zh_CN: '属性: disabled | 说明:是否为禁用状态', en_US: 'prop: disabled | description: Disable', } }, setter: 'BoolSetter', supportVariable: true, }, { name: 'filterOption', title: { label: { type: 'i18n', zh_CN: '可选项筛选', en_US: 'Filter Option', }, tip: { type: 'i18n', zh_CN: '属性: filterOption | 说明:是否根据输入项进行筛选', en_US: 'prop: filterOption | description: Filter based on input', } }, setter: 'BoolSetter', supportVariable: true, }, { name: 'placeholder', title: { label: { type: 'i18n', zh_CN: '输入框提示', en_US: 'Placeholder', }, tip: { type: 'i18n', zh_CN: '属性: placeholder | 说明: 输入框提示', en_US: 'prop: placeholder | description: Placeholder', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'defaultOpen', propType: 'bool', title: { label: { type: 'i18n', zh_CN: '默认展开菜单', en_US: 'Default Open', }, tip: { type: 'i18n', zh_CN: '属性: defaultOpen | 说明:是否默认展开下拉菜单', en_US: 'prop: defaultOpen | description: Expand drop-down menu by default', } }, setter: 'BoolSetter', supportVariable: true, }, // { // name: 'open', // title: { // label: { // type: 'i18n', // zh_CN: '展开下拉菜单', // en_US: 'Open', // }, // tip: { // type: 'i18n', // zh_CN: '属性: open | 说明:是否展开下拉菜单', // en_US: 'prop: open | description: Expand drop-down menu', // } // }, // setter: 'BoolSetter', // supportVariable: true, // }, { name: 'notFoundContent', title: { label: { type: 'i18n', zh_CN: '无数据展示', en_US: 'Not Found Content', }, tip: { type: 'i18n', zh_CN: '属性: notFoundContent | 说明: 当下拉列表为空时显示的内容', en_US: 'prop: notFoundContent | description: Content displayed when the drop-down list is empty', }, }, setter: 'StringSetter', supportVariable: true, }, ], supports: { style: true, events: [ { name: 'onBlur', template: "onBlur(${extParams}){\n// 失去焦点时的回调\nconsole.log('onBlur');}", }, { name: 'onChange', template: "onChange(value,${extParams}){\n// 选中 option,或 input 的 value 变化时,调用此函数\nconsole.log('onChange', value);}", }, { name: 'onFocus', template: "onFocus(${extParams}){\n// 选中 option,或 input 的 value 变化时,调用此函数\nconsole.log('onFocus')}", }, { name: 'onSearch', template: "onSearch(value,${extParams}){\n// 搜索补全项的时候调用\nconsole.log('onSearch',value);}", }, { name: 'onSelect', template: "onSelect(value,option,${extParams}){\n// 被选中时调用\nconsole.log('onSelect', value, option);}", }, { name: 'onDropdownVisibleChange', template: "onDropdownVisibleChange(open,${extParams}){\n// 展开下拉菜单的回调\nconsole.log('onDropdownVisibleChange', open);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/auto-complete/snippets.ts ================================================ export default [ { title: '辅助提示输入框', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/auto-complete-1.png', schema: { componentName: 'AutoComplete', props: { placeholder: '请输入', options: [ { label: '测试1', value: 'aaa', }, { label: '测试2', value: 'bbb', }, ], filterOption: true, style: { width: '200px', }, }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/avatar/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Avatar', title: '头像', category: '数据展示', props: [ { name: 'icon', title: { label: '头像图标', tip: '设置头像的自定义图标' }, propType: 'node', }, { name: 'shape', title: { label: '头像形状', tip: '指定头像的形状' }, propType: { type: 'oneOf', value: ['circle', 'square'] }, }, { name: 'size', title: { label: '尺寸', tip: '设置头像的大小' }, propType: { type: 'oneOfType', value: ['number', { type: 'oneOf', value: ['large', 'small', 'default'] }], }, defaultValue: 'default', }, { name: 'src', title: { label: '图片地址', tip: '图片类头像的资源地址' }, propType: 'string', }, { name: 'alt', title: { label: '替代文本', tip: '图像无法显示时的替代文本', }, propType: 'string', }, { name: 'onError', title: { label: '图片加载失败的事件', tip: '图片加载失败的事件,返回 false 会关闭组件默认的 fallback 行为', }, propType: 'func', }, { name: 'gap', title: { label: '文字边距', tip: '字符类型距离左右两侧边界单位像素', }, propType: 'number', }, ], configure: { supports: { style: true, events: [ { name: 'onError', template: "onError(${extParams}){\n// 图片加载失败的事件\nconsole.log('onError');}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/avatar/snippets.ts ================================================ export default [ { title: '头像', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/avatar-1.jpg', schema: { componentName: 'Avatar', props: { src: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png', }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/back-top/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'BackTop', title: '回到顶部', category: '其他', props: [ { name: 'target', title: { label: '监听元素', tip: '设置需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数', }, propType: 'func', }, { name: 'visibilityHeight', title: { label: '可见高度', tip: '滚动高度达到此参数值才出现 BackTop', }, propType: 'number', }, { name: 'onClick', title: { label: '点击按钮的回调函数', tip: '点击按钮的回调函数' }, propType: 'func', }, { name: 'duration', title: { label: '滚动时间', tip: '回到顶部所需时间(ms)' }, propType: 'number', }, ], configure: { supports: { style: true, events: [ { name: 'onClick', template: "onClick(${extParams}){\n// 点击按钮的回调函数\nconsole.log('onClick');}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/back-top/snippets.ts ================================================ export default [ { title: '回到顶部', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/back-top-1.jpg', schema: { componentName: 'BackTop', props: {}, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/badge/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Badge', title: '徽标数', category: '数据展示', props: [ { name: 'color', title: { label: '圆点颜色', tip: '自定义小圆点的颜色' }, propType: 'string', }, { name: 'count', title: { label: '展示数字', tip: '展示的数字,大于 overflowCount 时显示为 `${overflowCount}+`,为 0 时隐藏', }, propType: 'node', }, { name: 'dot', title: { label: '展示圆点', tip: '不展示数字,只有一个小红点', }, propType: 'bool', defaultValue: false, }, { name: 'offset', title: { label: '圆点偏移', tip: '设置状态点的位置偏移 [number, number]', }, propType: { type: 'arrayOf', value: 'number' }, }, { name: 'overflowCount', title: { label: '封顶值', tip: '展示封顶的数字值' }, propType: 'number', }, { name: 'showZero', title: { label: '展示零值', tip: '当数值为 0 时,是否展示 Badge', }, propType: 'bool', defaultValue: false, }, { name: 'status', title: { label: '状态', tip: '设置 Badge 为状态点' }, propType: { type: 'oneOf', value: ['success', 'processing', 'default', 'error', 'warning'], }, }, { name: 'text', title: { label: '状态文本', tip: '在设置了 `status` 的前提下有效,设置状态点的文本', }, condition(target) { return !!target.getProps().getPropValue('status'); }, propType: 'string', }, { name: 'title', title: { label: '悬浮提示', tip: '设置鼠标放在状态点上时显示的文字', }, propType: 'string', }, ], configure: { supports: { style: true } }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/badge/snippets.ts ================================================ export default [ { title: '徽标数', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/badge-1.png', schema: { componentName: 'Badge', props: { count: 25, }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/breadcrumb/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Breadcrumb', title: '面包屑', category: '导航', props: [ { title: '基础', display: 'block', type: 'group', items: [ { name: 'routes', title: { label: '路由栈信息', tip: 'router 的路由栈信息' }, propType: { type: 'arrayOf', value: { type: 'shape', value: [ { name: 'path', propType: 'string' }, { name: 'breadcrumbName', propType: 'string' }, ], }, }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'path', title: { label: '路由路径', tip: 'path | 路由路径' }, propType: 'string', setter: 'StringSetter', isRequired: true }, { name: 'breadcrumbName', title: { label: '路由名称', tip: 'breadcrumbName | 路由名称', }, propType: 'string', setter: 'StringSetter', isRequired: true }, ], }, }, initialValue: { path: 'path', breadcrumbName: 'breadcrumbName', }, }, }, }, }, { name: 'params', title: { label: '路由的参数', tip: '路由的参数' }, propType: 'object', setter: 'JsonSetter', }, { name: 'separator', title: { label: '分隔符自定义', tip: '分隔符自定义' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, setter: [ 'StringSetter', { componentName: 'SlotSetter', initialValue: { type: 'JSSlot', value: [], }, }, 'VariableSetter', ], }, ], }, { title: '扩展', display: 'block', type: 'group', items: [ { name: 'itemRender', title: { label: '自定义渲染', tip: 'itemRender | 自定义渲染', }, propType: { type: 'oneOfType', value: ['func', 'node'] }, setter: [ { componentName: 'SlotSetter', title: '自定义渲染插槽', initialValue: { type: 'JSSlot', params: ['route', 'params', 'routes', 'paths'], value: [], }, }, { componentName: 'FunctionSetter', props: { template: 'itemRender(route, params, routes, paths,${extParams}){\n// 自定义渲染\nreturn `${route.breadcrumbName}`}', }, }, 'VariableSetter', ], }, ], }, ], configure: { supports: { style: true } }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/breadcrumb/snippets.ts ================================================ export default [ { title: '面包屑', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/breadcrumb-1.jpg', schema: { componentName: 'Breadcrumb', props: { routes: [ { path: 'a', breadcrumbName: 'Home', }, { path: 'center', breadcrumbName: 'Application Center', }, { path: 'app', breadcrumbName: 'An Application', }, ], itemRender: { type: 'JSSlot', params: ['route', 'params', 'routes', 'paths'], value: [ { componentName: 'Typography.Link', props: { href: { type: 'JSExpression', value: 'this.route.path', }, children: { type: 'JSExpression', value: 'this.route.breadcrumbName', }, }, }, ], }, }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/button/meta.ts ================================================ import snippets from './snippets'; export default { componentName: 'Button', title: '按钮', category: '通用', props: [ { title: '功能', display: 'block', type: 'group', items: [ { name: 'children', title: { label: '内容', tip: 'children | 内容', }, propType: { type: 'oneOfType', value: ['node', 'string'], }, setter: ['SlotSetter', 'StringSetter', 'VariableSetter'], }, { name: 'htmlType', title: { label: '原生类型', tip: 'htmlType | 设置 `button` 原生的 `type` 值', }, propType: { type: 'oneOf', value: ['submit', 'reset', 'button'], }, setter: [ { componentName: 'RadioGroupSetter', props: { options: [ { title: 'Submit', value: 'submit', }, { title: 'Reset', value: 'reset', }, { title: 'Button', value: 'button', }, ], }, }, 'VariableSetter', ], defaultValue: 'button', }, { name: 'href', title: { label: '跳转地址', tip: 'href | 点击跳转的地址,指定此属性 button 的行为和 a 链接一致', }, propType: 'string', setter: ['StringSetter', 'VariableSetter'], }, { name: 'target', title: { label: 'Target', tip: 'target | 相当于 a 链接的 target 属性,href 存在时生效', }, propType: { type: 'oneOf', value: ['_self', '_blank', '_parent', '_top'], }, setter: [ { componentName: 'SelectSetter', props: { options: [ { title: '本窗口跳转', value: '_self', }, { title: '打开新标签页', value: '_blank', }, { title: '父窗口跳转', value: '_parent', }, { title: '顶层窗口跳转', value: '_top', }, ], }, }, 'StringSetter', 'VariableSetter', ], condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("href")?.trim()', }, }, ], }, { title: '外观', display: 'block', type: 'group', items: [ { name: 'type', title: { label: '类型', tip: 'type | 设置按钮类型' }, propType: { type: 'oneOf', value: ['primary', 'ghost', 'dashed', 'danger', 'link', 'text'], }, setter: [ { componentName: 'SelectSetter', props: { options: [ { title: '主按钮', value: 'primary', }, { title: '虚线框按钮', value: 'dashed', }, { title: '危险按钮', value: 'danger', }, { title: '链接按钮', value: 'link', }, { title: '类文本按钮', value: 'text', }, ], }, }, 'VariableSetter', ], }, { name: 'size', title: { label: '尺寸', tip: 'size | 设置按钮大小' }, propType: { type: 'oneOf', value: ['large', 'middle', 'small'] }, setter: [ { componentName: 'RadioGroupSetter', props: { options: [ { title: '大', value: 'large', }, { title: '中', value: 'middle', }, { title: '小', value: 'small', }, ], }, }, 'VariableSetter', ], defaultValue: 'middle', }, { name: 'shape', title: { label: '形状', tip: 'shape | 设置按钮形状,可选值为 `circle`、 `round` 或者不设', }, propType: { type: 'oneOf', value: ['default', 'circle', 'round'] }, defaultValue: 'default', setter: [ { componentName: 'RadioGroupSetter', props: { options: [ { title: '默认', value: 'default', }, { title: '圆形', value: 'circle', }, { title: '圆角', value: 'round', }, ], }, }, 'VariableSetter', ], }, { name: 'icon', title: { label: '图标', tip: 'icon | 设置按钮的图标组件' }, propType: 'node', setter: { componentName: 'SlotSetter', initialValue: { type: 'JSSlot', value: [ { componentName: 'Icon', props: { type: 'SmileOutlined', size: 20, rotate: 0, spin: false, }, }, ], }, }, }, { name: 'block', title: { label: '自适应', tip: 'block | 将按钮宽度调整为其父宽度的选项', }, propType: 'bool', setter: 'BoolSetter', defaultValue: false, }, { name: 'danger', title: { label: '危险按钮', tip: 'danger | 设置危险按钮' }, propType: 'bool', setter: 'BoolSetter', defaultValue: false, }, { name: 'ghost', title: { label: '幽灵属性', tip: 'ghost | 幽灵属性,使按钮背景透明' }, propType: 'bool', setter: 'BoolSetter', defaultValue: false, }, ], }, { title: '状态', display: 'block', type: 'group', items: [ { name: 'loading', title: { label: '载入状态', tip: 'loading | 设置按钮载入状态' }, propType: 'bool', setter: ['BoolSetter', 'VariableSetter'], }, { name: 'disabled', title: { label: '是否禁用', tip: 'disabled | 是否为禁用状态' }, propType: 'bool', setter: ['BoolSetter', 'VariableSetter'], defaultValue: false, }, ], }, { name: 'onClick', title: { label: '点击回调', tip: '点击按钮时的回调' }, propType: 'func', }, ], configure: { supports: { events: [ { name: 'onClick', template: "onClick(event,${extParams}){\n// 点击按钮时的回调\nconsole.log('onClick', event);}", }, ], style: true, }, }, snippets, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/button/snippets.ts ================================================ export default [ { title: '主按钮', screenshot: require('./__screenshots__/button-1.png'), schema: { componentName: 'Button', props: { type: 'primary', children: '主按钮', }, }, }, { title: '次按钮', screenshot: require('./__screenshots__/button-2.png'), schema: { componentName: 'Button', props: { type: 'default', children: '次按钮', }, }, }, { title: '危险按钮', screenshot: require('./__screenshots__/button-3.png'), schema: { componentName: 'Button', props: { type: 'danger', children: '危险按钮', }, }, }, { title: '文字按钮', screenshot: require('./__screenshots__/button-4.png'), schema: { componentName: 'Button', props: { type: 'text', children: '文字按钮', }, }, }, { title: '虚框按钮', screenshot: require('./__screenshots__/button-5.png'), schema: { componentName: 'Button', props: { type: 'dashed', children: '虚框按钮', }, }, }, { title: '链接按钮', screenshot: require('./__screenshots__/button-6.png'), schema: { componentName: 'Button', props: { type: 'link', children: '链接按钮', }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/calendar/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Calendar', title: '日历', category: '数据展示', props: [ { name: 'defaultValue', title: { label: '默认值', tip: '默认展示的日期' }, propType: 'date', setter: 'DateSetter', }, // { // name: 'dateCellRender', // title: { // label: '自定义日期追加渲染', // tip: '自定义渲染日期单元格,返回内容会被追加到单元格', // }, // propType: 'func', // }, // { // name: 'dateFullCellRender', // title: { // label: '自定义渲染日期单元格,返回内容覆盖单元格', // tip: '自定义渲染日期单元格,返回内容覆盖单元格', // }, // propType: 'func', // }, { name: 'disabledDate', title: { label: '不可选日期', tip: '不可选择的日期' }, propType: 'func', }, { name: 'fullscreen', title: { label: '全屏显示', tip: '是否全屏显示' }, propType: 'bool', defaultValue: true, }, // { // name: 'locale', // title: { label: '国际化配置', tip: '国际化配置' }, // propType: 'object', // }, { name: 'mode', title: { label: '初始模式', tip: '初始模式' }, propType: { type: 'oneOf', value: ['month', 'year'] }, defaultValue: 'month', }, // { // name: 'monthCellRender', // title: { // label: '自定义渲染月单元格,返回内容会被追加到单元格', // tip: '自定义渲染月单元格,返回内容会被追加到单元格', // }, // propType: 'func', // }, // { // name: 'monthFullCellRender', // title: { // label: '自定义渲染月单元格,返回内容覆盖单元格', // tip: '自定义渲染月单元格,返回内容覆盖单元格', // }, // propType: 'func', // }, // { // name: 'validRange', // title: { label: '设置可以显示的日期', tip: '设置可以显示的日期' }, // propType: { type: 'arrayOf', value: 'object' }, // }, // { // name: 'value', // title: { label: '当前值', tip: '展示日期' }, // propType: 'object', // }, { name: 'onPanelChange', title: { label: '日期面板变化回调', tip: '日期面板变化回调' }, propType: 'func', }, { name: 'onSelect', title: { label: '点击选择日期回调', tip: '点击选择日期回调' }, propType: 'func', }, { name: 'onChange', title: { label: '日期变化回调', tip: '日期变化回调' }, propType: 'func', }, // { // name: 'headerRender', // title: { label: '自定义头部内容', tip: '自定义头部内容' }, // propType: 'func', // }, ], configure: { supports: { style: true, events: [ { name: 'onPanelChange', template: "onPanelChange(date,mode,${extParams}){\n// 日期面板变化回调\nconsole.log('onPanelChange', date, mode);}", }, { name: 'onSelect', template: "onSelect(date,${extParams}){\n// 点击选择日期回调\nconsole.log('onSelect', date);}", }, { name: 'onChange', template: "onChange(date,${extParams}){\n// 日期变化回调\nconsole.log('onChange', date);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/calendar/snippets.ts ================================================ export default [ { title: '日历', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/calendar-1.jpg', schema: { componentName: 'Calendar', props: {}, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/card/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Card', title: '卡片', category: '数据展示', props: [ { name: 'title', title: { label: '卡片标题', tip: '卡片标题' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, // { // name: 'actions', // title: { label: '卡片操作组', tip: '卡片操作组,位置在卡片底部' }, // propType: { type: 'arrayOf', value: 'node' }, // }, // { // name: 'headStyle', // title: { label: '标题区域样式', tip: '自定义标题区域样式' }, // propType: 'object', // }, // { // name: 'bodyStyle', // title: { label: '内容区域样式', tip: '内容区域自定义样式' }, // propType: 'object', // }, { name: 'bordered', title: { label: '显示边框', tip: '是否有边框' }, propType: 'bool', defaultValue: true, }, { name: 'cover', title: { label: '卡片封面', tip: '卡片封面' }, propType: 'node', }, { name: 'extra', title: { label: '额外元素', tip: '卡片右上角的操作区域' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'hoverable', title: { label: '可浮起', tip: '鼠标移过时可浮起' }, propType: 'bool', defaultValue: false, }, { name: 'loading', title: { label: 'loading', tip: '当卡片内容还在加载中时,可以用 loading 展示一个占位', }, propType: 'bool', defaultValue: false, }, { name: 'size', title: { label: '尺寸', tip: 'card 的尺寸' }, propType: { type: 'oneOf', value: ['default', 'small'] }, defaultValue: 'default', }, { name: 'type', title: { label: '卡片类型', tip: '卡片类型' }, propType: { type: 'oneOf', value: ['default', 'inner'] }, defaultValue: 'default', }, ], configure: { component: { isContainer: true }, supports: { style: true, events: [ { name: 'onTabChange', template: "onTabChange(key,${extParams}){\n// 页签切换的回调\nconsole.log('onTabChange', key);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/card/snippets.ts ================================================ export default [ { title: '卡片', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/card-1.png', schema: { componentName: 'Card', props: { title: 'Default size card', }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/carousel/meta.ts ================================================ import { uuid } from '../_utils/utils'; import snippets from './snippets'; export default { snippets, componentName: 'Carousel', title: '走马灯', category: '数据展示', props: [ { name: 'afterChange', title: { label: '切换面板的回调', tip: '切换面板的回调' }, propType: 'func', }, { name: 'autoplay', title: { label: '是否自动切换', tip: '是否自动切换' }, propType: 'bool', defaultValue: false, }, { name: 'beforeChange', title: { label: '切换面板的回调', tip: '切换面板的回调' }, propType: 'func', }, { name: 'dotPosition', title: { label: '指示点位置', tip: '面板指示点位置,可选 `top` `bottom` `left` `right`', }, propType: { type: 'oneOf', value: ['top', 'bottom', 'left', 'right'], }, }, { name: 'dots', title: { label: '显示指示点', tip: '是否显示面板指示点', }, propType: { type: 'oneOfType', value: ['bool', 'object'] }, }, { name: 'easing', title: { label: '动画效果', tip: '动画效果' }, propType: 'string', }, { name: 'effect', title: { label: '动画效果函数', tip: '动画效果函数' }, propType: { type: 'oneOf', value: ['scrollx', 'fade'] }, }, { name: 'items', title: '折叠项', setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', initialValue: () => { return { key: uuid(), }; }, }, }, }, extraProps: { getValue(target, fieldValue) { console.log('getValue', target.node.children.length); const map = target.node.children.map((child) => { const key = child.getPropValue('key') ? String(child.getPropValue('key')) : child.id; return { key }; }); return map; }, setValue(target, value) { const { node } = target; const map = {}; if (!Array.isArray(value)) { value = []; } value.forEach((item) => { const tabItem = Object.assign({}, item); map[item.key] = tabItem; }); node.children.mergeChildren( (child) => { const key = String(child.getPropValue('key')); if (Object.hasOwnProperty.call(map, key)) { delete map[key]; return false; } return true; }, () => { const items = []; for (const key in map) { if (Object.hasOwnProperty.call(map, key)) { items.push({ componentName: 'Card', props: map[key], }); } } return items; }, (child1, child2) => { const a = value.findIndex( (item) => String(item.key) === String(child1.getPropValue('key')), ); const b = value.findIndex( (item) => String(item.key) === String(child2.getPropValue('key')), ); return a - b; }, ); }, }, }, ], configure: { supports: { style: true }, component: { isContainer: true, }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/carousel/snippets.ts ================================================ export default [ { title: '走马灯', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/carousel-1.jpg', schema: { componentName: 'Carousel', children: [ { componentName: 'Card', props: { key: 'panel-1', }, }, { componentName: 'Card', props: { key: 'panel-2', }, }, ], }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/cascader/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Cascader', title: '级联选择', category: '表单', props: [ { name: 'defaultValue', title: { label: '默认的选中项', tip: '默认的选中项' }, propType: { type: 'arrayOf', value: { type: 'oneOfType', value: ['string', 'number'] }, }, }, { name: 'value', title: { label: '当前选中项', tip: '当前选中项' }, propType: { type: 'arrayOf', value: { type: 'oneOfType', value: ['string', 'number'] }, }, }, { name: 'options', title: { label: '选项数据', tip: '可选项数据源' }, setter: 'JsonSetter', }, { name: 'allowClear', title: { label: '支持清除', tip: '是否允许清除' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter' }, { name: 'autoFocus', title: { label: '自动聚焦', tip: '自动获取焦点' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'bordered', title: { label: '显示边框', tip: '是否有边框' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter' }, { name: 'changeOnSelect', title: { label: '点选触发', tip: '点选每级菜单选项值都会触发onChange', }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'className', title: { label: '自定义类名', tip: '自定义类名' }, propType: 'string', setter: 'StringSetter' }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'expandTrigger', title: { label: '菜单触发方式', tip: '触发次级菜单的展开的方式' }, propType: { type: 'oneOf', value: ['click', 'hover'] }, }, { name: 'notFoundContent', title: { label: '无数据展示', tip: '无数据' }, propType: 'string', setter: 'StringSetter' }, { name: 'placeholder', title: { label: '输入框占位文本', tip: '输入框占位文本' }, propType: 'string', setter: 'StringSetter' }, { name: 'placement', title: { label: '浮层预设位置', tip: '浮层预设位置' }, propType: { type: 'oneOf', value: ['bottomLeft', 'bottomRight', 'topLeft', 'topRight'], }, }, { name: 'showSearch', title: { label: '支持搜索', tip: '在选择框中显示搜索框' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'size', title: { label: '尺寸', tip: '输入框大小' }, propType: { type: 'oneOf', value: ['large', 'middle', 'small'] }, setter: { componentName: 'SelectSetter', props: { options: [ { title: '大', value: 'large', }, { title: '中', value: 'middle', }, { title: '小', value: 'small', }, ], }, }, defaultValue: 'middle', }, { name: 'style', title: { label: '自定义样式', tip: '自定义样式' }, propType: 'object', }, { name: 'onChange', title: { label: '选择完成后的回调', tip: '选择完成后的回调' }, propType: 'func', }, { name: 'onPopupVisibleChange', title: { label: '显示/隐藏浮层的回调', tip: '显示/隐藏浮层的回调' }, propType: 'func', }, ], configure: { supports: { style: true, events: [ { name: 'onChange', template: "onChange(value,selectedOptions,${extParams}){\n// 选择完成后的回调\nconsole.log('onChange', value, selectedOptions);}", }, { name: 'onPopupVisibleChange', template: "onPopupVisibleChange(value,selectedOptions,${extParams}){\n// 显示/隐藏浮层的回调\nconsole.log('onPopupVisibleChange', value, selectedOptions);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/cascader/snippets.ts ================================================ export default [ { title: '级联选择', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/cascader-1.png', schema: { componentName: 'Cascader', props: { options: [ { value: 'zhejiang', label: 'Zhejiang', children: [ { value: 'hangzhou', label: 'Hangzhou', children: [ { value: 'xihu', label: 'West Lake', }, ], }, ], }, { value: 'jiangsu', label: 'Jiangsu', children: [ { value: 'nanjing', label: 'Nanjing', children: [ { value: 'zhonghuamen', label: 'Zhong Hua Men', }, ], }, ], }, ], placeholder: '请选择', }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/checkbox/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Checkbox', title: '多选框', category: '表单', props: [ { name: 'children', title: { label: '内容', tip: '内容' }, propType: 'string', setter: 'StringSetter', supportVariable: true }, { name: 'autoFocus', title: { label: '自动聚焦', tip: '自动获取焦点' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', supportVariable: true }, { name: 'checked', title: { label: '当前值', tip: '指定当前是否选中' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', supportVariable: true }, { name: 'defaultChecked', title: { label: '默认值', tip: '初始是否选中' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', supportVariable: true }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', supportVariable: true }, { name: 'indeterminate', title: { label: '不确定状态', tip: 'indeterminate状态' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', supportVariable: true }, { name: 'onChange', title: { label: '变化时回调函数', tip: '变化时回调函数' }, propType: 'func', }, ], configure: { supports: { style: true, events: [ { name: 'onChange', template: "onChange(event,${extParams}){\n// 变化时回调函数\nconsole.log('onChange', event);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/checkbox/snippets.ts ================================================ export default [ { title: '多选框', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/checkbox-1.png', schema: { componentName: 'Checkbox', props: { children: 'Checkbox', }, }, }, { title: '多选框组', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/checkbox-group-1.png', schema: { componentName: 'Checkbox.Group', props: { options: [ { label: 'A', value: 'A', }, { label: 'B', value: 'B', }, { label: 'C', value: 'C', }, ], }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/checkbox.group/meta.ts ================================================ import { uuid } from '../_utils/utils'; export default { componentName: 'Checkbox.Group', title: '多选框组', category: '表单', props: [ { name: 'defaultValue', title: { label: '默认值', tip: '默认选中值' }, propType: { type: 'arrayOf', value: 'string' }, defaultValue: [], setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'StringSetter', } } }, supportVariable: true }, { name: 'value', title: { label: '当前值', tip: '当前选中的选项' }, propType: { type: 'arrayOf', value: 'string' }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'StringSetter', } } }, supportVariable: true }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', supportVariable: true }, { name: 'name', title: { label: 'name属性', tip: 'name属性' }, propType: 'string', setter: 'StringSetter', supportVariable: true }, { name: 'options', title: { label: '指定可选项', tip: '指定可选项' }, propType: { type: 'arrayOf', value: { type: 'shape', value: [ { name: 'label', description: '选项名', propType: 'string', defaultValue: '选项名', }, { name: 'value', description: '选项值', propType: 'string', defaultValue: '选项值', }, { name: 'disabled', description: '是否禁用', propType: 'bool', defaultValue: false, }, ], }, }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'label', title: '选项名', setter: 'StringSetter', isRequired: true }, { name: 'value', title: '选项值', setter: 'StringSetter', isRequired: true }, { name: 'disabled', title: '是否禁用', setter: 'BoolSetter', }, ], }, }, initialValue: () => { return { label: '选项名', value: uuid(), disabled: false, }; }, }, }, }, supportVariable: true }, { name: 'onChange', title: { label: '变化时回调函数', tip: '变化时回调函数' }, propType: 'func', }, ], configure: { supports: { style: true, events: [ { name: 'onChange', template: "onChange(checkedValue,${extParams}){\n// 变化时回调函数\nconsole.log('onChange', checkedValue);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/collapse/meta.ts ================================================ import { uuid } from '../_utils/utils'; import snippets from './snippets'; export default { snippets, componentName: 'Collapse', title: '折叠面板', category: '数据展示', props: [ { name: 'bordered', title: { label: '显示边框', tip: '带边框风格的折叠面板' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter', supportVariable: true }, { name: 'accordion', title: { label: '手风琴模式', tip: '手风琴模式' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', supportVariable: true }, { name: 'collapsible', title: '可折叠触发区域', propType: { type: 'oneOf', value: ['-', 'header', 'disabled'], }, }, // { // name: 'expandIcon', // title: { label: '自定义切换图标', tip: '自定义切换图标' }, // propType: 'func', // }, { name: 'expandIconPosition', title: { label: '图标位置', tip: '设置图标位置' }, propType: { type: 'oneOf', value: ['left', 'right'] }, }, { name: 'destroyInactivePanel', title: { label: '隐藏时销毁', tip: '销毁折叠隐藏的面板' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', supportVariable: true }, { name: 'ghost', title: { label: '透明无边框', tip: '使折叠面板透明且无边框' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', supportVariable: true }, { name: 'collapses', title: '折叠项', setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'key', title: 'key', setter: 'StringSetter', initialValue: (val) => val || uuid() }, { name: 'header', title: '面板头内容', setter: 'StringSetter', initialValue: '折叠项' }, ], }, }, initialValue: () => { return { key: uuid(), header: '折叠项', showArrow: true, collapsible: undefined, forceRender: false, }; }, }, }, }, extraProps: { getValue(target, fieldValue) { console.log('getValue', target.node.children.length); const map = target.node.children.map((child) => { const key = child.getPropValue('key') ? String(child.getPropValue('key')) : child.id; return { key, header: child.getPropValue('header'), showArrow: child.getPropValue('showArrow'), collapsible: child.getPropValue('collapsible'), forceRender: child.getPropValue('forceRender'), }; }); return map; }, setValue(target, value) { const { node } = target; const map = {}; // console.log('setValue',value); if (!Array.isArray(value)) { value = []; } value.forEach((item) => { const tabItem = Object.assign({}, item); map[item.key] = tabItem; }); node.children.mergeChildren( (child) => { const key = String(child.getPropValue('key')); if (Object.hasOwnProperty.call(map, key)) { child.setPropValue('header', map[key].header); child.setPropValue('showArrow', map[key].showArrow); child.setPropValue('collapsible', map[key].collapsible); child.setPropValue('forceRender', map[key].forceRender); delete map[key]; return false; } return true; }, () => { const items = []; for (const key in map) { if (Object.hasOwnProperty.call(map, key)) { items.push({ componentName: 'Collapse.Panel', props: map[key], }); } } return items; }, (child1, child2) => { const a = value.findIndex( (item) => String(item.key) === String(child1.getPropValue('key')), ); const b = value.findIndex( (item) => String(item.key) === String(child2.getPropValue('key')), ); return a - b; }, ); }, }, }, { name: 'defaultActiveKey', title: { label: '初始化选中面板的 key', tip: '初始化选中面板的 key' }, propType: { type: 'oneOfType', value: [ 'string', { type: 'arrayOf', value: 'string' }, 'number', { type: 'arrayOf', value: 'number' }, ], }, }, { name: 'activeKey', title: { label: '当前激活 tab 面板的 key', tip: '当前激活 tab 面板的 key', }, propType: { type: 'oneOfType', value: [ 'string', { type: 'arrayOf', value: 'string' }, 'number', { type: 'arrayOf', value: 'number' }, ], }, }, ], configure: { supports: { style: true, events: [ { name: 'onChange', template: "onChange(${extParams}){\n// 切换面板的回调\nconsole.log('onChange');}", }, ], }, component: { isContainer: true, }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/collapse/snippets.ts ================================================ export default [ { title: '折叠面板', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/collapse-1.png', schema: { componentName: 'Collapse', props: { defaultActiveKey: ['collapse-item-1'], }, children: [ { componentName: 'Collapse.Panel', props: { header: '折叠项1', key: 'collapse-item-1', }, }, { componentName: 'Collapse.Panel', props: { header: '折叠项2', key: 'collapse-item-2', }, }, ], }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/collapse.pane/meta.ts ================================================ // FIXME: 选中tabPane点复制,会出问题,因为复制的组件key一样 export default { componentName: 'Collapse.Panel', title: '折叠项', category: '', props: [ { name: 'key', title: { label: 'key', tip: 'key', }, propType: 'string', setter: 'StringSetter', supportVariable: true }, { name: 'header', title: { label: '标题', tip: '标题', }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'extra', title: { label: '右上角内容', tip: '自定义渲染每个面板右上角的内容', }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'collapsible', title: '可折叠触发区域', propType: { type: 'oneOf', value: ['-', 'header', 'disabled'], }, }, { name: 'showArrow', title: { label: '显示折叠图标', tip: '是否展示当前面板上的箭头', }, propType: 'bool', defaultValue: true, setter: 'BoolSetter', supportVariable: true }, { name: 'forceRender', title: { label: '隐藏时渲染', tip: '被隐藏时是否渲染 DOM 结构', }, propType: 'bool', setter: 'BoolSetter', supportVariable: true }, ], configure: { component: { isContainer: true, nestingRule: { parentWhitelist: ['Collapse'], }, }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/comment/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Comment', title: '评论', category: '数据展示', props: [ { name: 'actions', title: { label: '操作列表', tip: '在评论内容下面呈现的操作项列表', }, propType: { type: 'arrayOf', value: 'node' }, }, { name: 'author', title: { label: '要显示为注释作者的元素', tip: '要显示为注释作者的元素' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'avatar', title: { label: '头像元素', tip: '要显示为评论头像的元素 - 通常是 antd Avatar 或者 src', }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'children', title: { label: '子节点', tip: '嵌套注释应作为注释的子项提供', }, propType: 'node', }, { name: 'content', title: { label: '评论的主要内容', tip: '评论的主要内容' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'datetime', title: { label: '展示时间描述', tip: '展示时间描述' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, ], configure: { supports: { style: true } }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/comment/snippets.ts ================================================ export default [ { title: '评论', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/comment-1.png', schema: { componentName: 'Comment', props: {}, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/config-provider/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'ConfigProvider', title: '全局化配置', category: '其他', props: [ { name: 'autoInsertSpaceInButton', title: { label: '按钮插入空格', tip: '自动在按钮中 2 个汉字之间插入空格', }, propType: 'bool', defaultValue: true, }, { name: 'componentSize', title: { label: '组件大小', tip: '设置 antd 组件大小' }, propType: { type: 'oneOf', value: ['small', 'middle', 'large'] }, default: 'middle', }, { name: 'csp', title: { label: 'CSP配置', tip: '设置Content Security Policy配置', }, propType: 'object', setter: 'JsonSetter', }, { name: 'form', title: { label: 'Form通用属性', tip: '设置 Form 组件的通用属性', }, propType: 'object', setter: 'JsonSetter', }, { name: 'input', title: { label: 'Input通用属性', tip: '设置 Input 组件的通用属性', }, propType: 'object', setter: 'JsonSetter', }, // { // name: 'renderEmpty', // title: { label: '自定义组件空状态', tip: '自定义组件空状态' }, // propType: 'func', // }, { name: 'getPopupContainer', title: { label: '弹出框父节点', tip: '弹出框渲染父节点,默认渲染到 body 上。', }, propType: 'func', }, { name: 'getTargetContainer', title: { label: '滚动监听容器', tip: '配置 Affix、Anchor 滚动监听容器。', }, propType: 'func', }, { name: 'locale', title: { label: '语言', tip: '语言' }, propType: { type: 'oneOf', value: ['zh-CN', 'en-US'], }, defaultValue: 'en-US', }, { name: 'prefixCls', title: { label: '样式前缀', tip: '设置统一样式前缀。`注意:这将不会应用由 antd 提供的默认样式`', }, propType: 'string', }, { name: 'pageHeader', title: { label: '统一设置 PageHeader 的 ghost', tip: '统一设置 PageHeader 的 ghost', }, propType: 'object', setter: 'JsonSetter', }, { name: 'direction', title: { label: '文本方向', tip: '设置文本展示方向' }, propType: { type: 'oneOf', value: ['ltr', 'rtl'] }, }, { name: 'space', title: { label: '设置 Space 的 尺寸', tip: '设置 Space 的 `size`' }, propType: { type: 'oneOf', value: ['small', 'middle', 'large', 'number'], }, }, { name: 'virtual', title: { label: '虚拟滚动', tip: '设置 `false` 时关闭虚拟滚动', }, propType: 'bool', defaultValue: true, }, { name: 'dropdownMatchSelectWidth', title: { label: '下拉菜单和选择器同宽', tip: '下拉菜单和选择器同宽' }, propType: { type: 'oneOfType', value: ['bool', 'number'] }, }, ], configure: { component: { isContainer: true } }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/config-provider/snippets.ts ================================================ export default [ { title: '全局化配置', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/config-provider-1.jpg', schema: { componentName: 'ConfigProvider', props: {}, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/date-picker/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'DatePicker', title: '日期选择框', category: '表单', props: [ { title: '值设置', display: 'block', type: 'group', items: [ { name: 'defaultValue', title: { label: '默认值', tip: 'defaultValue | 默认值', }, propType: 'date', setter: 'DateSetter', }, { name: 'value', title: { label: '当前值', tip: 'value | 当前值', }, propType: 'date', setter: 'DateSetter', }, ], }, { title: '功能选项', display: 'block', type: 'group', items: [ { name: 'size', title: { label: '尺寸', tip: 'size | 输入框大小', }, propType: { type: 'oneOf', value: ['large', 'middle', 'small'], }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '大', value: 'large', }, { title: '中', value: 'middle', }, { title: '小', value: 'small', }, ], }, }, defaultValue: 'middle', }, { name: 'picker', title: { label: '日期类型', tip: 'picker | 选择器日期类型', }, setter: { componentName: 'SelectSetter', props: { options: [ { title: '日期', value: 'date', }, { title: '周', value: 'week', }, { title: '月份', value: 'month', }, { title: '季度', value: 'quarter', }, { title: '年份', value: 'year', }, ], }, }, propType: { type: 'oneOf', value: ['date', 'week', 'month', 'quarter', 'year'], }, }, { name: 'format', title: { label: '日期格式', tip: 'format | 设置日期格式', }, propType: 'string', defaultValue: 'YYYY-MM-DD', setter: 'StringSetter', }, { name: 'placeholder', title: { label: '提示文字', tip: 'placeholder | 输入框提示文字', }, propType: 'string', setter: 'StringSetter', }, { name: 'allowClear', title: { label: '支持清除', tip: 'allowClear | 是否允许清除', }, propType: 'bool', defaultValue: true, setter: 'BoolSetter', }, { name: 'bordered', title: { label: '显示边框', tip: 'bordered | 是否有边框', }, propType: 'bool', defaultValue: true, setter: 'BoolSetter', }, { name: 'showToday', title: { label: '展示今天按钮', tip: 'showToday | 是否展示今天按钮', }, propType: 'bool', defaultValue: true, setter: 'BoolSetter', }, { name: 'autoFocus', title: { label: '自动聚焦', tip: 'autoFocus | 自动获取焦点', }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', }, { name: 'disabled', title: { label: '是否禁用', tip: 'disabled | 是否为禁用状态', }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', }, { name: 'inputReadOnly', title: { label: '是否只读', tip: 'inputReadOnly | 避免在移动设备上打开虚拟键盘', }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', }, { name: 'showTime', title: { label: '时间选择', tip: 'showTime | 是否能选择时间', }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', }, ], }, { title: '高级', display: 'block', type: 'group', items: [ { name: 'disabledDate', title: { label: '不可选日期', tip: 'disabledDate | 不可选择的日期', }, propType: 'func', setter: [ { componentName: 'FunctionSetter', props: { template: 'disabledDate(currentDate,${extParams}){\n// 设置不可选择的日期\nreturn true\n}', }, }, 'VariableSetter', ], }, ], }, // { // name: 'dropdownClassName', // title: { // label: '额外的弹出日历 className', // tip: '额外的弹出日历 className', // }, // setter: 'ClassNameSetter', // }, // { // name: 'popupStyle', // title: { label: '额外的弹出日历样式', tip: '额外的弹出日历样式' }, // setter: 'JsonSetter', // }, // { // name: 'suffixIcon', // title: { label: '自定义的选择框后缀图标', tip: '自定义的选择框后缀图标' }, // setter: 'IconSetter', // }, // { // name: 'style', // title: { label: '自定义输入框样式', tip: '自定义输入框样式' }, // setter: 'JsonSetter', // }, ], configure: { supports: { style: true, events: [ { name: 'onChange', template: "onChange(date,dateString,${extParams}){\n// 时间发生变化的回调\nconsole.log('onChange',date,dateString);}", }, { name: 'onOpenChange', template: "onOpenChange(open,${extParams}){\n// 弹出日历和关闭日历的回调\nconsole.log('onOpenChange',open);}", }, { name: 'onPanelChange', template: "onPanelChange(value,mode,${extParams}){\n// 日历面板切换的回调\nconsole.log('onPanelChange',value,mode);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/date-picker/snippets.ts ================================================ export default [ { title: '选择日期', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/date-picker-1.png', schema: { componentName: 'DatePicker', props: {}, }, }, { title: '选择周', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/date-picker-2.png', schema: { componentName: 'DatePicker', props: { picker: 'week', }, }, }, { title: '选择月份', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/date-picker-3.png', schema: { componentName: 'DatePicker', props: { picker: 'month', }, }, }, { title: '选择季度', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/date-picker-4.png', schema: { componentName: 'DatePicker', props: { picker: 'quarter', }, }, }, { title: '选择年份', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/date-picker-5.png', schema: { componentName: 'DatePicker', props: { picker: 'year', }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/date-picker.range-picker/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'DatePicker.RangePicker', title: '日期区间选择', category: '表单', props: [ { title: '值设置', display: 'block', type: 'group', items: [ { name: 'defaultValue', title: { label: '默认值', tip: 'defaultValue | 默认值', }, propType: 'object', setter: 'JsonSetter', }, { name: 'value', title: { label: '当前值', tip: 'value | 当前值', }, propType: 'object', setter: 'JsonSetter', }, { name: 'defaultPickerValue', title: { label: '默认面板日期', tip: 'defaultPickerValue | 默认面板日期', }, propType: 'object', setter: 'JsonSetter', }, ], }, { title: '功能选项', display: 'block', type: 'group', items: [ { name: 'size', title: { label: '尺寸', tip: 'size | 输入框大小,large 高度为 40px,small 为 24px,默认是 32px', }, propType: { type: 'oneOf', value: ['large', 'middle', 'small'], }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '大', value: 'large', }, { title: '中', value: 'middle', }, { title: '小', value: 'small', }, ], }, }, defaultValue: 'middle', }, { name: 'picker', title: { label: '选择器类型', tip: 'picker | 设置选择器类型', }, propType: { type: 'oneOf', value: ['date', 'week', 'month', 'quarter', 'year'], }, defaultValue: 'date', setter: { componentName: 'SelectSetter', props: { options: [ { title: '日期', value: 'date', }, { title: '周', value: 'week', }, { title: '月份', value: 'month', }, { title: '季度', value: 'quarter', }, { title: '年份', value: 'year', }, ], }, }, }, { name: 'mode', title: { label: '面板模式', tip: 'mode | 日期面板的状态', }, propType: { type: 'oneOf', value: ['time', 'date', 'month', 'year', 'decade'], }, setter: { componentName: 'SelectSetter', props: { options: [ { title: '日期', value: 'date', }, { title: '周', value: 'week', }, { title: '月份', value: 'month', }, { title: '年份', value: 'year', }, { title: '十年间隔', value: 'decade', }, ], }, }, }, { name: 'format', title: { label: '日期格式', tip: 'format | 展示的日期格式,配置参考 moment.js', }, propType: 'string', setter: 'StringSetter', }, { name: 'placeholder', title: { label: '提示文字', tip: 'placeholder | 输入框提示文字', }, propType: 'string', setter: 'StringSetter', }, { name: 'allowClear', title: { label: '支持清除', tip: 'allowClear | 是否允许清除', }, propType: 'bool', defaultValue: true, setter: 'BoolSetter', }, { name: 'bordered', title: { label: '显示边框', tip: 'bordered | 是否有边框', }, propType: 'bool', defaultValue: true, setter: 'BoolSetter', }, { name: 'autoFocus', title: { label: '自动聚焦', tip: 'autoFocus | 自动获取焦点', }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', }, { name: 'disabled', title: { label: '是否禁用', tip: 'disabled | 是否为禁用状态', }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', }, // { // name: 'open', // title: { // label: '弹层是否展开', // tip: 'open | 控制弹层是否展开', // }, // propType: 'bool', // setter: 'BoolSetter', // }, { name: 'showTime', title: { label: '时间选择', tip: 'showTime | 时间选择', }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', }, { name: 'inputReadOnly', title: { label: '输入框只读', tip: 'inputReadOnly | 设置输入框为只读(避免在移动设备上打开虚拟键盘)', }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', }, ], }, { title: '高级', display: 'block', type: 'group', items: [ { name: 'ranges', title: { label: '预设范围', tip: 'ranges | 预设时间范围快捷选择', }, propType: 'object', setter: 'JsonSetter', }, { name: 'disabledDate', title: { label: '不可选日期', tip: 'disabledDate | 不可选择的日期', }, propType: 'func', setter: [ { componentName: 'FunctionSetter', props: { template: 'disabledDate(currentDate,${extParams}){\n// 设置不可选择的日期\nreturn true\n}', }, }, 'VariableSetter', ], }, ], }, // { // name: 'renderExtraFooter', // title: { label: '在面板中添加额外的页脚', tip: '在面板中添加额外的页脚' }, // propType: 'func', // }, // { // name: 'className', // title: { label: '选择器 className', tip: '选择器 className' }, // propType: 'string', // }, // { // name: 'dropdownClassName', // title: { // label: '额外的弹出日历 className', // tip: '额外的弹出日历 className', // }, // propType: 'string', // }, // { // name: 'getPopupContainer', // title: { // label: '定义浮层的容器,默认为 body 上新建 div', // tip: '定义浮层的容器,默认为 body 上新建 div', // }, // propType: 'func', // }, // { // name: 'locale', // title: { label: '国际化配置', tip: '国际化配置' }, // propType: 'object', // }, // { // name: 'popupStyle', // title: { label: '额外的弹出日历样式', tip: '额外的弹出日历样式' }, // propType: 'CSSProperties', // defaultValue: '{}', // }, // { // name: 'style', // title: { label: '自定义输入框样式', tip: '自定义输入框样式' }, // propType: 'CSSProperties', // defaultValue: '{}', // }, ], configure: { supports: { style: true, events: [ { name: 'onChange', template: "onChange(dates,dateStrings,${extParams}){\n// 日期范围发生变化的回调\nconsole.log('onChange',dates,dateStrings);}", }, { name: 'onOpenChange', template: "onOpenChange(open,${extParams}){\n// 弹出日历和关闭日历的回调\nconsole.log('onOpenChange',open);}", }, { name: 'onPanelChange', template: "onPanelChange(value,mode,${extParams}){\n// 日历面板切换的回调\nconsole.log('onPanelChange',value,mode);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/date-picker.range-picker/snippets.ts ================================================ export default [ { title: '日期区间', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/date-picker-range-picker-1.png', schema: { componentName: 'DatePicker.RangePicker', props: {}, }, }, { title: '周区间', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/date-picker-range-picker-2.png', schema: { componentName: 'DatePicker.RangePicker', props: { picker: 'week', }, }, }, { title: '月区间', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/date-picker-range-picker-3.png', schema: { componentName: 'DatePicker.RangePicker', props: { picker: 'month', }, }, }, { title: '年区间', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/date-picker-range-picker-4.png', schema: { componentName: 'DatePicker.RangePicker', props: { picker: 'year', }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/descriptions/meta.ts ================================================ import { uuid } from '../_utils/utils'; import snippets from './snippets'; export default { snippets, componentName: 'Descriptions', title: '描述列表', category: '数据展示', props: [ { name: 'title', title: { label: '标题', tip: '描述列表的标题,显示在最顶部', }, propType: { type: 'oneOfType', value: ['string', 'node'], }, }, { name: 'items', title: { label: '列表项', tip: '列表项', }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'key', title: 'key', setter: 'StringSetter', initialValue: (val) => val || uuid(), condition: () => false, }, { name: 'label', title: '标题', setter: 'StringSetter', initialValue: '列表项', }, { name: 'span', title: '所占列数', setter: 'NumberSetter', initialValue: 1, }, { name: 'children', title: '内容', setter: { componentName: 'SlotSetter', initialValue: { type: 'JSSlot', value: [], }, }, }, ], }, }, initialValue: () => { return { key: uuid(), label: '标签项', span: 1, children: { type: 'JSSlot', value: [], }, }; }, }, }, }, extraProps: { getValue(target, fieldValue) { const map = target.node.children.map((child) => { const key = child.getPropValue('key') ? String(child.getPropValue('key')) : child.id; return { key, label: child.getPropValue('label'), span: child.getPropValue('span'), children: child.getPropValue('children'), }; }); return map; }, setValue(target, value) { const { node } = target; const map = {}; if (!Array.isArray(value)) { value = []; } value.forEach((item) => { const tabItem = Object.assign({}, item); map[item.key] = tabItem; }); node.children.mergeChildren( (child) => { const key = String(child.getPropValue('key')); if (Object.hasOwnProperty.call(map, key)) { child.setPropValue('label', map[key].label); child.setPropValue('span', map[key].span); child.setPropValue('children', map[key].children); delete map[key]; return false; } return true; }, () => { const items = []; for (const key in map) { if (Object.hasOwnProperty.call(map, key)) { items.push({ componentName: 'Descriptions.Item', props: map[key], }); } } return items; }, (child1, child2) => { const a = value.findIndex( (item) => String(item.key) === String(child1.getPropValue('key')), ); const b = value.findIndex( (item) => String(item.key) === String(child2.getPropValue('key')), ); return a - b; }, ); }, // getValue(target, fieldValue) { // // const node = target.nodes[0]; // // const children = node.getChildren(); // const map = target.node.children.map(child => { // return { // key: child.getPropValue('key') || uuid(), // label: child.getPropValue('label'), // span: child.getPropValue('span'), // children: child.getPropValue('children'), // }; // }); // return map; // }, // setValue(target, value) { // const node = target.node; // if (!Array.isArray(value)) { // value = []; // } // node.children.mergeChildren( // () => true, // () => { // return value.map(item => ({ // componentName: 'Descriptions.Item', // props: Object.assign({}, item), // })); // } // ); // }, }, }, { name: 'bordered', title: { label: '显示边框', tip: '是否展示边框' }, propType: 'bool', defaultValue: false, }, { name: 'column', title: { label: '列数', tip: '一行的列表项数量', }, propType: 'number', defaultValue: 3, }, { name: 'size', title: { label: '尺寸', tip: '设置列表的大小。可以设置为 `middle` 、`small`, 或不填(只有设置 `bordered={true}` 生效)', }, propType: { type: 'oneOf', value: ['default', 'middle', 'small'] }, defaultValue: 'middle', }, { name: 'layout', title: { label: '布局方向', tip: '描述布局' }, propType: { type: 'oneOf', value: ['horizontal', 'vertical'] }, defaultValue: 'horizontal', }, { name: 'colon', title: { label: '展示冒号', tip: '配置 `Descriptions.Item` 的 `colon` 的默认值', }, propType: 'bool', defaultValue: true, }, ], configure: { supports: { style: true }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/descriptions/snippets.ts ================================================ export default [ { title: '描述列表', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/descriptions-1.jpg', schema: { componentName: 'Descriptions', props: { title: '用户信息', items: [ { label: '用户名', children: 'Mo Yao', }, ], }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/descriptions.item/meta.ts ================================================ export default { componentName: 'Descriptions.Item', title: '描述列表项', props: [ { name: 'key', title: { label: 'key', tip: 'key', }, propType: 'string', }, { name: 'tab', title: { label: '标题', tip: '标题', }, propType: 'string', }, ], configure: { component: { isContainer: true }, supports: { style: true }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/divider/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Divider', title: '分割线', category: '布局', props: [ { name: 'className', title: { label: '分割线样式类', tip: '分割线样式类' }, propType: 'string', }, { name: 'dashed', title: { label: '是否虚线', tip: '是否虚线' }, propType: 'bool', defaultValue: false, }, { name: 'orientation', title: { label: '标题位置', tip: '分割线标题的位置' }, propType: { type: 'oneOf', value: ['left', 'right', 'center'] }, }, { name: 'orientationMargin', title: { label: '标题边距', tip: '标题和最近 left/right 边框之间的距离,去除了分割线,同时 orientation 必须为 left 或 right', }, propType: { type: 'oneOfType', value: ['string', 'number'] }, }, { name: 'style', title: { label: '分割线样式对象', tip: '分割线样式对象' }, propType: 'object', }, { name: 'type', title: { label: '方向', tip: '水平还是垂直类型' }, propType: { type: 'oneOf', value: ['horizontal', 'vertical'] }, }, { name: 'plain', title: { label: '普通正文样式', tip: '文字是否显示为普通正文样式', }, propType: 'bool', defaultValue: false, }, ], configure: { component: { isContainer: true, }, supports: { style: true, className: true }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/divider/snippets.ts ================================================ export default [ { title: '分割线', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/divider-1.png', schema: { componentName: 'Divider', props: {}, }, }, { title: '带文字分割线', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/divider-2.png', schema: { componentName: 'Divider', props: { children: [ { componentName: 'Typography.Text', props: { children: '分割文字', }, }, ], }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/drawer/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Drawer', title: '抽屉', category: '反馈', props: [ { title: '基础', display: 'block', type: 'group', items: [ { name: 'open', title: { label: '是否可见', tip: 'open | Drawer 是否可见' }, propType: 'bool', setter: 'BoolSetter', }, { name: 'title', title: { label: '标题', tip: 'title | 标题' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, setter: [ 'StringSetter', { componentName: 'SlotSetter', title: '标题插槽', initialValue: { type: 'JSSlot', value: [], }, }, 'VariableSetter', ], }, ], }, { title: '外观', display: 'block', type: 'group', items: [ { name: 'placement', title: { label: '位置', tip: 'placement | 抽屉的显示位置' }, propType: { type: 'oneOf', value: ['top', 'right', 'bottom', 'left'], }, defaultValue: 'right', setter: { componentName: 'SelectSetter', props: { options: [ { title: '上方', value: 'top', }, { title: '右侧', value: 'right', }, { title: '下方', value: 'bottom', }, { title: '左侧', value: 'left', }, ], }, }, }, { name: 'size', title: { label: '大小', tip: 'size | 抽屉的大小' }, propType: { type: 'oneOf', value: ['default', 'large'] }, defaultValue: 'default', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '默认', value: 'default', }, { title: '超大', value: 'large', }, ], }, }, }, { name: 'width', title: { label: '宽度', tip: 'width | 宽度' }, propType: { type: 'oneOfType', value: ['string', 'number'] }, setter: ['StringSetter', 'NumberSetter', 'VariableSetter'], }, { name: 'height', title: { label: '高度', tip: 'height | 高度, 在 placement 为 top 或 bottom 时使用', }, propType: { type: 'oneOfType', value: ['string', 'number'] }, setter: ['StringSetter', 'NumberSetter', 'VariableSetter'], }, { name: 'zIndex', title: { label: 'z-index', tip: '设置 Drawer 的 `z-index`' }, propType: 'number', setter: 'NumberSetter', }, ], }, { title: '功能', display: 'block', type: 'group', items: [ { name: 'mask', title: { label: '显示遮罩', tip: 'mask | 是否显示遮罩' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter', }, { name: 'maskClosable', title: { label: '点击遮罩关闭', tip: 'maskClosable | 点击遮罩是否关闭抽屉', }, propType: 'bool', defaultValue: true, setter: 'BoolSetter', }, { name: 'autoFocus', title: { label: '自动获得焦点', tip: 'autoFocus | 抽屉展开后是否将焦点切换至其 Dom 节点', }, propType: 'bool', defaultValue: true, setter: 'BoolSetter', }, { name: 'keyboard', title: { label: '键盘Esc关闭', tip: 'keyboard | 是否支持键盘按 Esc 关闭', }, propType: 'bool', defaultValue: true, setter: 'BoolSetter', }, { name: 'destroyOnClose', title: { label: '关闭时销毁', tip: 'destroyOnClose | 关闭时销毁 Drawer 里的子元素', }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', }, { name: 'closable', title: { label: '关闭按钮', tip: 'closable | 是否显示左上角的关闭按钮', }, propType: 'bool', defaultValue: true, setter: 'BoolSetter', }, { name: 'forceRender', title: { label: '预渲染', tip: 'forceRender | 预渲染 Drawer 内元素' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', }, ], }, { title: '插槽扩展', display: 'block', type: 'group', items: [ { name: 'closeIcon', title: { label: '关闭图标', tip: 'closeIcon | 自定义关闭图标' }, propType: 'node', setter: { componentName: 'SlotSetter', title: '关闭图标插槽', initialValue: { type: 'JSSlot', value: [ { componentName: 'Icon', props: { type: 'CloseOutlined', size: 16 }, }, ], }, }, }, { name: 'extra', title: { label: '操作区域', tip: 'extra | 抽屉右上角的操作区域' }, propType: 'node', setter: { componentName: 'SlotSetter', title: '操作区域插槽', initialValue: { type: 'JSSlot', value: [], }, }, }, { name: 'footer', title: { label: '抽屉的页脚', tip: 'footer | 抽屉的页脚' }, propType: 'node', setter: { componentName: 'SlotSetter', title: '抽屉页脚插槽', initialValue: { type: 'JSSlot', value: [], }, }, }, ], }, { title: '其它', display: 'block', type: 'group', items: [ { name: 'className', title: { label: '容器类名', tip: 'className | 对话框外层容器的类名' }, propType: 'string', setter: 'StringSetter', }, { name: 'drawerStyle', title: '弹出层样式', type: 'group', extraProps: { display: 'entry', }, items: [ { name: 'drawerStyle', title: { label: '样式设置', tip: 'drawerStyle | 用于设置 Drawer 弹出层的样式', }, setter: 'StyleSetter', extraProps: { display: 'block', }, }, ], }, { name: 'contentWrapperStyle', title: '包裹层样式', type: 'group', extraProps: { display: 'entry', }, items: [ { name: 'contentWrapperStyle', title: { label: '样式设置', tip: 'contentWrapperStyle | 可用于设置 Drawer 包裹内容部分的样式', }, setter: 'StyleSetter', extraProps: { display: 'block', }, }, ], }, { name: 'headerStyle', title: '头部样式', type: 'group', extraProps: { display: 'entry', }, items: [ { name: 'headerStyle', title: { label: '样式设置', tip: 'headerStyle | 用于设置 Drawer 头部的样式', }, setter: 'StyleSetter', extraProps: { display: 'block', }, }, ], }, { name: 'bodyStyle', title: '内容样式', type: 'group', extraProps: { display: 'entry', }, items: [ { name: 'bodyStyle', title: { label: '样式设置', tip: 'bodyStyle | 可用于设置 Drawer 内容部分的样式', }, setter: 'StyleSetter', extraProps: { display: 'block', }, }, ], }, { name: 'footerStyle', title: '页脚样式', type: 'group', extraProps: { display: 'entry', }, items: [ { name: 'footerStyle', title: { label: '样式设置', tip: 'footerStyle | 抽屉页脚部件的样式', }, setter: 'StyleSetter', extraProps: { display: 'block', }, }, ], }, { name: 'maskStyle', title: '遮罩样式', type: 'group', extraProps: { display: 'entry', }, items: [ { name: 'maskStyle', title: { label: '样式设置', tip: 'maskStyle | 遮罩样式', }, setter: 'StyleSetter', extraProps: { display: 'block', }, }, ], }, ], }, ], configure: { component: { isContainer: true, isModal: true, nestingRule: { parentWhitelist: ['Page', 'Component'], }, }, supports: { style: true, events: [ { name: 'onClose', template: "onClose(event,${extParams}){\n// 点击遮罩层或右上角叉或取消按钮的回调\nconsole.log('onClose',event);}", }, { name: 'afterOpenChange', template: "afterOpenChange(open,${extParams}){\n// 切换抽屉时动画结束后的回调\nconsole.log('afterOpenChange',open);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/drawer/snippets.ts ================================================ export default [ { title: '侧边抽屉', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/drawer-1.png', schema: { componentName: 'Drawer', props: { title: 'Basic Drawer', open: true, placement: 'right', destroyOnClose: true, }, children: [ { componentName: 'Typography.Paragraph', children: 'Some contents...', }, ], }, }, { title: '底部抽屉', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/drawer-2.png', schema: { componentName: 'Drawer', props: { title: 'Basic Drawer', open: true, placement: 'bottom', destroyOnClose: true, }, children: [ { componentName: 'Typography.Paragraph', children: 'Some contents...', }, ], }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/dropdown/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Dropdown', title: '下拉菜单', category: '导航', props: [ { name: 'open', title: { label: '菜单是否显示', tip: '菜单是否显示' }, propType: { type: 'oneOf', value: [true, false, '-'] }, defaultValue: '-', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '默认非受控', value: '-', }, { title: '显示', value: true, }, { title: '不显示', value: false, }, ], }, }, extraProps: { getValue(target, fieldValue) { const { node } = target; let value = node.getPropValue('open'); if (value === undefined) { value = '-'; } return value; }, setValue(target, value) { const { node } = target; if (value === '-') { setTimeout(() => { node.clearPropValue('open'); }); } }, }, }, { name: 'arrow', title: { label: '显示下拉箭头', tip: '是否显示下拉箭头' }, propType: 'bool', defaultValue: false, }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态' }, propType: 'bool', }, // { // name: 'getPopupContainer', // title: { // label: '渲染父节点', // tip: // '菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。[示例](https://codepen.io/afc163/pen/zEjNOy?editors=0010)', // }, // propType: 'func', // }, { name: 'overlay', title: { label: '菜单', tip: '菜单' }, propType: { type: 'oneOfType', value: ['node', 'func'] }, }, // { // name: 'overlayClassName', // title: { label: '根元素的类名称', tip: '根元素的类名称' }, // propType: 'string', // }, // { // name: 'overlayStyle', // title: { label: '根元素的样式', tip: '根元素的样式' }, // propType: 'object', // }, { name: 'placement', title: { label: '弹出位置', tip: '菜单弹出位置:`bottomLeft` `bottomCenter` `bottomRight` `topLeft` `topCenter` `topRight`', }, propType: { type: 'oneOf', value: ['bottomLeft', 'bottomCenter', 'bottomRight', 'topLeft', 'topCenter', 'topRight'], }, }, { name: 'trigger', title: { label: '触发下拉的行为', tip: '触发下拉的行为, 移动端不支持 hover', }, propType: { type: 'arrayOf', value: { type: 'oneOf', value: ['click', 'hover', 'contextMenu'] }, }, }, { name: 'onOpenChange', title: { label: '显示状态回调', tip: '菜单显示状态改变时调用,参数为 `open`', }, propType: 'func', }, ], configure: { component: { isContainer: true }, supports: { style: true, events: [ { name: 'onOpenChange', template: "onOpenChange(open,${extParams}){\n// 菜单显示状态改变时调用\nconsole.log('onOpenChange',open);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/dropdown/snippets.ts ================================================ export default [ { title: '下拉菜单', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/dropdown-1.png', schema: { componentName: 'Dropdown', props: { overlay: { type: 'JSSlot', value: [ { componentName: 'Menu', props: { items: [ { key: 'timeLinei5wd', category: 'Item', title: '菜单名', }, ], }, children: [ { componentName: 'Menu.Item', id: 'node_ocky01yzdq3', props: { key: 'timeLinei5wd', category: 'Item', title: '菜单名', children: '菜单名', }, }, ], }, ], }, }, children: [ { componentName: 'Button', props: { type: 'link', children: { type: 'JSSlot', value: [ { componentName: 'Typography.Text', props: { children: 'Hover me', style: { color: 'inherit', }, }, }, { componentName: 'Icon', props: { type: 'DownOutlined', size: 15, style: { marginLeft: 4, verticalAlign: 'middle', }, }, }, ], }, }, }, ], }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/empty/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Empty', title: '空状态', category: '数据展示', props: [ { name: 'description', title: { label: '内容描述', tip: '自定义描述内容' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, // { // name: 'imageStyle', // title: { label: '图片样式', tip: '图片样式' }, // propType: 'object', // }, { name: 'image', title: { label: '图片地址', tip: '设置显示图片,为string时表示自定义图片地址。', }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, ], configure: { supports: { style: true } }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/empty/snippets.ts ================================================ export default [ { title: '空状态', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/empty-1.png', schema: { componentName: 'Empty', props: {}, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/form/meta.ts ================================================ import snippets from './snippets'; import { uuid } from '../_utils/utils' export default { snippets, componentName: 'Form', title: '表单容器', category: '表单', props: [ { name: 'ref', title: { label: 'ref', tip: 'ref | 通过 this.$(\'xxx\') 获取到组件实例', }, defaultValue: () => { return `form_${uuid()}` }, setter: 'StringSetter', supportVariable: true }, { name: 'values', title: { label: '表单数据源', tip: '表单数据源' }, propType: 'object', setter: 'JsonSetter', supportVariable: true }, { name: 'colon', title: { label: '展示冒号', tip: '' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter', supportVariable: true }, { name: 'hideRequiredMark', title: { label: '隐藏必填标记', tip: '隐藏必填标记' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', supportVariable: true }, { type: 'group', title: '布局', display: 'accordion', items: [ { name: 'labelCol', title: '标签栅格布局设置', display: 'inline', setter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'span', title: '宽度', setter: { componentName: 'NumberSetter', props: { min: 0, max: 24, }, }, }, { name: 'offset', title: '偏移', setter: { componentName: 'NumberSetter', props: { min: 0, max: 24, }, }, }, ], }, }, }, description: 'label 标签布局,同 `` 组件,设置 span offset 值,如 {span: 8, offset: 16},该项仅在垂直表单有效', }, { name: 'wrapperCol', title: '内容栅格布局设置', display: 'inline', setter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'span', title: '宽度', setter: { componentName: 'NumberSetter', props: { min: 0, max: 24, }, }, }, { name: 'offset', title: '偏移', setter: { componentName: 'NumberSetter', props: { min: 0, max: 24, }, }, }, ], }, }, }, description: '需要为输入控件设置布局样式时,使用该属性,用法同 labelCol', }, ], }, { name: 'labelAlign', title: { label: '标签对齐', tip: 'label 标签的文本对齐方式', }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '左', value: 'left', }, { title: '右', value: 'right', }, ], }, }, propType: { type: 'oneOf', value: ['left', 'right'] }, defaultValue: 'right', }, { name: 'layout', title: { label: '表单布局', tip: '表单布局' }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '水平', value: 'horizontal', }, { title: '垂直', value: 'vertical', }, { title: '行内', value: 'inline', }, ], }, }, propType: { type: 'oneOf', value: ['horizontal', 'vertical', 'inline'] }, defaultValue: 'horizontal', }, { name: 'name', title: { label: '表单名称', tip: '表单名称,会作为表单字段 `id` 前缀使用', }, propType: 'string', setter: 'StringSetter', supportVariable: true }, { name: 'preserve', title: { label: '删除时保留值', tip: '当字段被删除时保留字段值', }, propType: 'bool', defaultValue: true, setter: 'BoolSetter', supportVariable: true }, { name: 'scrollToFirstError', title: { label: '滚至错误', tip: '提交失败自动滚动到第一个错误字段', }, propType: 'bool', defaultValue: true, setter: 'BoolSetter', supportVariable: true }, { name: 'size', title: { label: '字段组件尺寸', tip: '设置字段组件的尺寸(仅限 antd 组件)', }, propType: { type: 'oneOf', value: ['small', 'middle', 'large'] }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '大', value: 'large', }, { title: '中', value: 'middle', }, { title: '小', value: 'small', }, ], }, }, defaultValue: 'middle', }, { name: 'validateMessages', title: { label: '验证提示模板', tip: '验证提示模板' }, setter: 'JsonSetter', defaultValue: { required: "'${name}' 不能为空" }, }, { name: 'validateTrigger', title: { label: '校验时机', tip: '所有字段校验触发时机' }, propType: { type: 'oneOf', value: ['onChange', 'onBlur'], }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '当前值变化时', value: 'onChange', }, { title: '失去焦点时', value: 'onBlur', }, ], }, }, }, { name: 'onFinish', title: { label: '提交表单且数据验证成功后回调事件', tip: '提交表单且数据验证成功后回调事件', }, propType: 'func', }, { name: 'onFinishFailed', title: { label: '提交表单且数据验证失败后回调事件', tip: '提交表单且数据验证失败后回调事件', }, propType: 'func', }, { name: 'onFieldsChange', title: { label: '字段更新时触发回调事件', tip: '字段更新时触发回调事件' }, propType: 'func', }, { name: 'onValuesChange', title: { label: '字段值更新时触发回调事件', tip: '字段值更新时触发回调事件', }, propType: 'func', }, ], configure: { component: { isContainer: true }, supports: { style: true, events: [ { name: 'onFinish', template: "onFinish(values,${extParams}){\n// 提交表单且数据验证成功后回调事件\nconsole.log('onFinish',values);}", }, { name: 'onFinishFailed', template: "onFinishFailed({values,errorFields,outOfDate},${extParams}){\n// 提交表单且数据验证失败后回调事件\nconsole.log('onFinishFailed',values, errorFields, outOfDate);}", }, { name: 'onFieldsChange', template: "onFieldsChange(changedFields,allFields,${extParams}){\n// 字段更新时触发回调事件\nconsole.log('onFieldsChange',changedFields,allFields);}", }, { name: 'onValuesChange', template: "onValuesChange(changedValues,allValues,${extParams}){\n// 字段值更新时触发回调事件\nconsole.log('onValuesChange',changedValues,allValues);}", }, ], }, advanced: { callbacks: { onNodeAdd: (dragment, currentNode) => { const comps = [ 'Input', 'Select', 'Radio', 'Checkbox', 'Switch', 'Upload', 'Datepicker', 'Rate', 'Transfer', ]; if ( !dragment || !dragment.componentMeta || !dragment.componentMeta.npm || !dragment.componentMeta.npm.package || dragment.componentMeta.npm.package.indexOf('@alilc/antd-lowcode-materials') === -1 || comps.every((comp) => dragment.componentName.indexOf(comp) === -1) ) { return; } // 为目标元素包裹一层P const layoutPNode = currentNode.document.createNode({ componentName: 'Form.Item', props: { label: '表单项: ', }, children: [dragment.exportSchema()], }); // 当前dragment还未添加入node子节点,需要setTimeout处理 setTimeout(() => { currentNode.replaceChild( dragment, layoutPNode.exportSchema(), // 避免生成新的 nodeId { reserveSchemaNodeId: true }, ); }, 1); }, }, }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/form/snippets.ts ================================================ export default [ { "title": "表单容器", "screenshot": "https://alifd.alicdn.com/fusion-cool/icons/icon-antd/form-1.png", "schema": { "componentName": "Form", "props": { "labelCol": { "span": 6 }, "wrapperCol": { "span": 14 }, "onValuesChange": { "type": "JSFunction", "value": "function onValuesChange(changedValues, allValues) {\n console.log('onValuesChange', changedValues, allValues);\n}" }, "onFinish": { "type": "JSFunction", "value": "function onFinish(values) {\n console.log('onFinish', values);\n}" }, "onFinishFailed": { "type": "JSFunction", "value": "function onFinishFailed({ values, errorFields, outOfDate }) {\n console.log('onFinishFailed', values, errorFields, outOfDate);\n}" }, "name": "basic" }, "children": [ { "componentName": "Form.Item", "props": { "label": "表单项", "labelAlign": "right", "colon": true, "required": true, "noStyle": false, "valuePropName": "value", "name": "a", "requiredobj": { "required": true, "message": "必填" }, "typeobj": { "type": null, "message": null }, "lenobj": { "max": null, "min": null, "message": null }, "patternobj": { "pattern": null, "message": null } }, "children": [ { "componentName": "Input", "props": { "placeholder": "请输入", "bordered": true, "disabled": false, "size": "middle" } } ] }, { "componentName": "Form.Item", "props": { "label": "表单项", "labelAlign": "right", "colon": true, "required": false, "noStyle": false, "valuePropName": "value", "requiredobj": { "required": null, "message": null }, "typeobj": { "type": null, "message": null }, "lenobj": { "max": null, "min": null, "message": null }, "patternobj": { "pattern": null, "message": null }, "name": "b" }, "children": [ { "componentName": "InputNumber", "props": { "placeholder": "请输入", "autoFocus": false, "disabled": false, "controls": true, "bordered": true, "size": "middle" } } ] }, { "componentName": "Form.Item", "props": { "label": "表单项", "labelAlign": "right", "colon": true, "required": false, "noStyle": false, "valuePropName": "value", "requiredobj": { "required": null, "message": null }, "typeobj": { "type": null, "message": null }, "lenobj": { "max": null, "min": null, "message": null }, "patternobj": { "pattern": null, "message": null }, "name": "c" }, "children": [ { "componentName": "Input.Password", "props": { "bordered": true, "disabled": false, "visibilityToggle": true, "placeholder": "请输入", "size": "middle" } } ] }, { "componentName": "Form.Item", "props": { "label": "表单项", "labelAlign": "right", "colon": true, "required": false, "noStyle": false, "valuePropName": "value", "requiredobj": { "required": null, "message": null }, "typeobj": { "type": null, "message": null }, "lenobj": { "max": null, "min": null, "message": null }, "patternobj": { "pattern": null, "message": null }, "name": "d" }, "children": [ { "componentName": "Input.TextArea", "props": { "autoSize": { "minRows": 3, "maxRows": 3 }, "placeholder": "请输入", "bordered": true, "disabled": false, "showCount": false, "size": "middle" } } ] }, { "componentName": "Form.Item", "props": { "label": "表单项", "name": "e", "labelAlign": "right", "colon": true, "required": false, "noStyle": false, "valuePropName": "value", "requiredobj": { "required": null, "message": null }, "typeobj": { "type": null, "message": null }, "lenobj": { "max": null, "min": null, "message": null }, "patternobj": { "pattern": null, "message": null } }, "children": [ { "componentName": "Select", "props": { "style": { "width": 200 }, "options": [ { "label": "A", "value": "A" }, { "label": "B", "value": "B" }, { "label": "C", "value": "C" } ], "allowClear": false, "autoFocus": false, "defaultActiveFirstOption": true, "disabled": false, "labelInValue": false, "showSearch": false, "size": "middle", "loading": false, "bordered": true, "filterOption": true, "optionFilterProp": "value", "tokenSeparators": [] } } ] }, { "componentName": "Form.Item", "props": { "label": "表单项", "labelAlign": "right", "colon": true, "required": false, "noStyle": false, "valuePropName": "value", "requiredobj": { "required": null, "message": null }, "typeobj": { "type": null, "message": null }, "lenobj": { "max": null, "min": null, "message": null }, "patternobj": { "pattern": null, "message": null }, "name": "f" }, "children": [ { "componentName": "Slider", "props": { "defaultValue": 30, "range": false, "disabled": false, "dots": false, "reverse": false, "vertical": false } } ] }, { "componentName": "Form.Item", "props": { "label": "表单项", "name": "g", "initialValue": "A", "colon": true, "required": false, "noStyle": false, "valuePropName": "value", "requiredobj": { "required": null, "message": null }, "typeobj": { "type": null, "message": null }, "lenobj": { "max": null, "min": null, "message": null }, "patternobj": { "pattern": null, "message": null } }, "children": [ { "componentName": "Checkbox.Group", "props": { "options": [ { "label": "A", "value": "A" }, { "label": "B", "value": "B" }, { "label": "C", "value": "C" } ] } } ] }, { "componentName": "Form.Item", "props": { "label": "表单项", "labelAlign": "right", "colon": true, "required": false, "noStyle": false, "valuePropName": "checked", "requiredobj": { "required": null, "message": null }, "typeobj": { "type": null, "message": null }, "lenobj": { "max": null, "min": null, "message": null }, "patternobj": { "pattern": null, "message": null }, "name": "i" }, "children": [ { "componentName": "Switch", "props": { "defaultChecked": false, "autoFocus": false, "disabled": false, "loading": false, "size": "default" } } ] }, { "componentName": "Form.Item", "props": { "label": "表单项", "labelAlign": "right", "colon": true, "required": false, "noStyle": false, "valuePropName": "value", "requiredobj": { "required": null, "message": null }, "typeobj": { "type": null, "message": null }, "lenobj": { "max": null, "min": null, "message": null }, "patternobj": { "pattern": null, "message": null }, "name": "j" }, "children": [ { "componentName": "TimePicker", "props": { "allowClear": true, "autoFocus": false, "bordered": true, "disabled": false, "hideDisabledOptions": false, "inputReadOnly": false, "use12Hours": false } } ] }, { "componentName": "Form.Item", "props": { "label": "表单项", "labelAlign": "right", "colon": true, "required": false, "noStyle": false, "valuePropName": "value", "requiredobj": { "required": null, "message": null }, "typeobj": { "type": null, "message": null }, "lenobj": { "max": null, "min": null, "message": null }, "patternobj": { "pattern": null, "message": null }, "name": "k" }, "children": [ { "componentName": "Rate", "props": { "defaultValue": 3, "allowClear": true, "allowHalf": false, "autoFocus": false, "count": 5, "disabled": false, "tooltips": [] } } ] }, { "componentName": "Form.Item", "props": { "wrapperCol": { "offset": 6 } }, "children": [ { "componentName": "Button", "props": { "type": "primary", "children": "提交", "htmlType": "submit" } }, { "componentName": "Button", "props": { "style": { "marginLeft": 20 }, "children": "取消" } } ] } ] } } ] ================================================ FILE: packages/antd-lowcode-materials/lowcode/form.item/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Form.Item', title: '表单项', category: '表单', props: [ { name: 'name', title: { label: '字段名', tip: '字段名' }, isRequired: true, propType: 'string', setter: 'StringSetter', supportVariable: true }, { name: 'label', title: { label: '标签', tip: '标签的文本' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'labelAlign', title: { label: '标签对齐', tip: '标签文本对齐方式' }, propType: { type: 'oneOf', value: ['left', 'right'] }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '左', value: 'left', }, { title: '右', value: 'right', }, ], }, }, defaultValue: 'right', }, { name: 'colon', title: { label: '显示冒号', tip: '配合 label 属性使用,表示是否显示 label 后面的冒号', }, propType: 'bool', defaultValue: true, setter: 'BoolSetter', supportVariable: true }, { name: 'extra', title: { label: '提示信息', tip: '额外的提示信息,和 help 类似,当需要错误信息和提示文案同时出现时,可以使用这个。', }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'tooltip', title: { label: '标签提示信息', tip: '标签提示信息,当需要对标签进行解释时,可以使用这个。', }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'required', title: { label: '必填标记', tip: '必填样式设置。如不设置,则会根据校验规则自动生成', }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', supportVariable: true }, // { // name: 'hasFeedback', // title: { // label: '校验状态图标', // tip: // '配合 validateStatus 属性使用,展示校验状态图标,建议只配合 Input 组件使用', // }, // propType: 'bool', // defaultValue: false, // }, { name: 'initialValue', title: { label: '默认值', tip: '设置子元素默认值,如果与 Form 的 initialValues 冲突则以 Form 为准', }, propType: 'string', setter: 'StringSetter', supportVariable: true }, { name: 'noStyle', title: { label: '隐藏标签', tip: '为 true 时不带样式,作为纯字段控件使用', }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', supportVariable: true }, { name: 'valuePropName', title: { label: '子组件值字段', tip: `子节点的值的字段,如 Switch 的是 'checked'`, }, propType: 'string', defaultValue: 'value', setter: 'StringSetter', supportVariable: true }, { name: 'getValueFromEvent', title: { label: 'event转换器', tip: `设置如何将 event 的值转换成字段值,如将上传组件的fileList作为value值传出`, }, propType: 'func', }, { type: 'group', title: '布局', display: 'accordion', items: [ { name: 'labelCol', title: '标签栅格布局设置', display: 'inline', setter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'span', title: '宽度', setter: { componentName: 'NumberSetter', props: { min: 0, max: 24, }, }, }, { name: 'offset', title: '偏移', setter: { componentName: 'NumberSetter', props: { min: 0, max: 24, }, }, }, ], }, }, }, description: 'label 标签布局,同 `` 组件,设置 span offset 值,如 {span: 8, offset: 16},该项仅在垂直表单有效', }, { name: 'wrapperCol', title: '内容栅格布局设置', display: 'inline', setter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'span', title: '宽度', setter: { componentName: 'NumberSetter', props: { min: 0, max: 24, }, }, }, { name: 'offset', title: '偏移', setter: { componentName: 'NumberSetter', props: { min: 0, max: 24, }, }, }, ], }, }, }, description: '需要为输入控件设置布局样式时,使用该属性,用法同 labelCol', }, ], }, { name: 'requiredobj', title: { label: '必填设置', tip: '必填设置' }, propType: { type: 'shape', value: [ { name: 'required', title: '是否必填', propType: 'bool', setter: 'BoolSetter', supportVariable: true, extraProps: { setValue(target: any, value: boolean) { // 同步 必填标记 target.parent.parent.setPropValue('required', value); } } }, { name: 'message', title: '错误信息提示', propType: 'string', setter: 'StringSetter', supportVariable: true }, ], }, }, { name: 'typeobj', title: { label: '输入类型设置', tip: '输入类型设置' }, propType: { type: 'shape', value: [ { name: 'type', title: '输入类型', setter: { componentName: 'SelectSetter', props: { options: [ { title: '字符串', value: 'string', }, // { // title: '纯数字', // value: 'number', // }, { title: '邮箱', value: 'email', }, { title: '网址', value: 'url', }, ], }, }, propType: { type: 'oneOf', value: ['string', 'number', 'email', 'url'], }, }, { name: 'message', title: '错误信息提示', propType: 'string' }, ], }, }, { name: 'lenobj', title: { label: '长度校验设置', tip: '长度校验设置' }, propType: { type: 'shape', value: [ // { name: 'len', title: '固定长度', propType: 'string' }, { name: 'max', title: '最大长度', propType: 'number' }, { name: 'min', title: '最小长度', propType: 'number' }, { name: 'message', title: '错误信息提示', propType: 'string' }, ], }, }, { name: 'patternobj', title: { label: '正则设置', tip: '正则设置' }, propType: { type: 'shape', value: [ { name: 'pattern', title: '正则', propType: 'string' }, { name: 'message', title: '错误信息提示', propType: 'string' }, ], }, }, { name: 'validator', title: { label: '自定义校验函数', tip: '自定义校验,接收 Promise 作为返回值', }, propType: 'func', }, ], configure: { component: { isContainer: true, nestingRule: { childWhitelist: [], parentWhitelist: [] }, }, supports: { style: true }, advanced: { callbacks: { onNodeRemove: (removedNode, currentNode) => { if (!removedNode || !currentNode) { return; } const { children } = currentNode; // 若无children,则说明当前P组件内已为空,需要删除P组件本身 if (children && children.length === 0) { currentNode.remove(); } }, }, }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/form.item/snippets.ts ================================================ export default [ { title: '表单项', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/form-item-1.jpg', schema: { componentName: 'Form.Item', props: { label: '表单项', }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/form.list/meta.ts ================================================ import snippets from './snippets'; export default { componentName: 'Form.List', title: '表单列表', category: '表单', snippets, props: [ { name: 'name', title: { label: '字段名', tip: '字段名' }, isRequired: true, propType: 'string', }, { name: 'initialValue', title: { label: '默认值', tip: '设置子元素默认值,如果与 Form 的 initialValues 冲突则以 Form 为准', }, propType: 'object', setter: 'JsonSetter', }, ], configure: { component: { isContainer: true, }, supports: { className: true, style: true }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/form.list/snippets.ts ================================================ export default [ { title: '表单列表', // TODO: 换成国内OSS地址 screenshot: 'https://user-images.githubusercontent.com/5419886/221425341-e982c944-8af4-4bad-9c17-1b2fd3fda835.png', schema: { componentName: 'Form.List', props: {}, } } ] ================================================ FILE: packages/antd-lowcode-materials/lowcode/grid.col/meta.ts ================================================ import snippets from './snippets'; function clamp(value, min, max) { return Math.max(min, Math.min(max, value)); } export default { snippets, componentName: 'Col', title: '栅格-列', props: [ { name: 'span', title: { label: '占位格数', tip: '栅格占位格数' }, propType: 'number', setter: { componentName: 'NumberSetter', props: { min: 0, max: 24, }, }, }, { name: 'order', title: { label: '栅格顺序', tip: '栅格顺序' }, propType: 'number', }, { name: 'pull', title: { label: '右侧偏移', tip: '栅格往右移动格数' }, propType: 'number', setter: { componentName: 'NumberSetter', props: { min: 0, max: 24, }, }, }, { name: 'push', title: { label: '左侧偏移', tip: '栅格往左移动格数' }, propType: 'number', setter: { componentName: 'NumberSetter', props: { min: 0, max: 24, }, }, }, ], configure: { component: { isContainer: true, nestingRule: { parentWhitelist: ['Row'] } }, supports: { style: true }, advanced: { getResizingHandlers: () => { return ['e']; }, callbacks: { onResizeStart: (e, currentNode) => { const parent = currentNode.parent; if (parent) { const parentNode = parent.getDOMNode(); if (parentNode) { currentNode.parentRect = parentNode.getBoundingClientRect(); } } currentNode.beforeSpan = currentNode.getPropValue('span') || 24; currentNode.startRect = currentNode.getRect(); }, onResize: (e, currentNode) => { const { deltaX } = e; const startWidth = currentNode.startRect ? currentNode.startRect.width : currentNode.beforeSpan * (currentNode.parentRect.width / 24); let width = startWidth + deltaX; if (!currentNode.startRect) { currentNode.startRect = { width }; } width = clamp(width, 0, currentNode.parentRect.width); const allowMoveX = Math.round(width - startWidth); // 实际被允许的x轴移动 currentNode.moveColumn = Math.round(allowMoveX / (currentNode.parentRect.width / 24)); // 计算移动距离所占的列 if (allowMoveX > 0) { currentNode.moveColumn++; } else { currentNode.moveColumn--; } currentNode.targetColumn = clamp(currentNode.beforeSpan + currentNode.moveColumn, 1, 24); // currentNode.setPropValue('span', currentNode.targetColumn); const dom = currentNode.getDOMNode(); dom.style.width = `${Math.round(width)}px`; dom.style.flex = 'none'; dom.style.maxWidth = '100%'; }, onResizeEnd: (e, currentNode) => { currentNode.getDOMNode().style.cssText = ''; currentNode.targetColumn = clamp(currentNode.targetColumn, 1, 24); currentNode.setPropValue('span', currentNode.targetColumn); }, }, }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/grid.col/snippets.ts ================================================ export default []; ================================================ FILE: packages/antd-lowcode-materials/lowcode/grid.row/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Row', title: '栅格-行', category: '布局', props: [ { name: 'align', title: { label: '垂直对齐方式', tip: '垂直对齐方式' }, propType: { type: 'oneOf', value: ['top', 'middle', 'bottom'] }, }, { name: 'h-gutter', title: { label: '水平间隔', tip: '栅格水平间隔,单位为像素(px)', }, propType: 'number', setter: { componentName: 'NumberSetter', props: { min: 0, }, }, defaultValue: 0, extraProps: { getValue(target) { const { node } = target; const gutter = node.getPropValue('gutter'); if (typeof gutter === 'number') { return gutter; } else if (Array.isArray(gutter)) { return gutter[0]; } return 0; }, setValue(target, value) { const { node } = target; const gutter = node.getPropValue('gutter'); if (Array.isArray(gutter)) { gutter[0] = value; node.setPropValue('gutter', gutter); } else { node.setPropValue('gutter', [value, 0]); } }, }, }, { name: 'v-gutter', title: { label: '垂直间隔', tip: '栅格垂直间隔,单位为像素(px)', }, propType: 'number', setter: { componentName: 'NumberSetter', props: { min: 0, }, }, defaultValue: 0, extraProps: { getValue(target) { const { node } = target; const gutter = node.getPropValue('gutter'); if (typeof gutter === 'number') { return 0; } else if (Array.isArray(gutter)) { return gutter[1]; } return 0; }, setValue(target, value) { const { node } = target; const gutter = node.getPropValue('gutter'); if (Array.isArray(gutter)) { gutter[1] = value; node.setPropValue('gutter', gutter); } else { node.setPropValue('gutter', [gutter, value]); } }, }, }, { name: 'justify', title: { label: '水平排列方式', tip: '水平排列方式' }, propType: { type: 'oneOf', value: ['start', 'end', 'center', 'space-around', 'space-between'], }, }, { name: 'wrap', title: { label: '自动换行', tip: '是否自动换行' }, propType: 'bool', defaultValue: true, }, ], configure: { component: { isContainer: true, nestingRule: { childWhitelist: ['Col'] } }, supports: { style: true }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/grid.row/snippets.ts ================================================ export default [ { title: '两栏', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/1-1.png', schema: { componentName: 'Row', props: {}, children: [ { componentName: 'Col', props: { span: 12, }, }, { componentName: 'Col', props: { span: 12, }, }, ], }, }, { title: '三栏', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/1-1-1.png', schema: { componentName: 'Row', props: {}, children: [ { componentName: 'Col', props: { span: 8, }, }, { componentName: 'Col', props: { span: 8, }, }, { componentName: 'Col', props: { span: 8, }, }, ], }, }, { title: '四栏', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/1-1-1-1.png', schema: { componentName: 'Row', props: {}, children: [ { componentName: 'Col', props: { span: 6, }, }, { componentName: 'Col', props: { span: 6, }, }, { componentName: 'Col', props: { span: 6, }, }, { componentName: 'Col', props: { span: 6, }, }, ], }, }, { title: '1:3', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/1-3.png', schema: { componentName: 'Row', props: {}, children: [ { componentName: 'Col', props: { span: 6, }, }, { componentName: 'Col', props: { span: 18, }, }, ], }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/icon/meta.ts ================================================ import snippets from './snippets'; import { AntdIconSetter } from '../_setters'; export default { snippets, componentName: 'Icon', title: '图标', category: '通用', props: [ { name: 'className', title: { label: '设置图标的样式名', tip: '设置图标的样式名' }, propType: 'string', }, { name: 'style', title: { label: '设置图标的样式,例如 `fontSize` 和 `color`', tip: '设置图标的样式,例如 `fontSize` 和 `color`', }, propType: 'object', }, { name: 'type', description: '图标', propType: 'string', setter: AntdIconSetter, }, { name: 'size', description: '大小', propType: 'number', defaultValue: 20, }, { name: 'color', description: '颜色', propType: 'string', setter: 'ColorSetter', }, { name: 'rotate', title: { label: '旋转角度', tip: '图标旋转角度', }, propType: 'number', defaultValue: 0, }, { name: 'spin', title: { label: '旋转动画', tip: '是否有旋转动画' }, propType: 'bool', defaultValue: false, }, { name: 'onClick', title: { label: '点击回调', tip: '点击按钮时的回调' }, propType: 'func', }, ], configure: { supports: { style: true } }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/icon/snippets.ts ================================================ export default [ { title: '图标', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/icon-1.jpg', schema: { componentName: 'Icon', props: { type: 'SmileOutlined', size: 20, }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/image/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Image', title: '图片', category: '数据展示', props: [ { name: 'src', title: { label: '图片地址', tip: '图片地址' }, propType: { type: 'string', isRequired: true }, }, { name: 'alt', title: { label: '替换文本', tip: '替换文本' }, propType: 'string', }, { name: 'preview', title: { label: '支持预览', tip: '支持预览' }, defaultValue: true, propType: 'bool', }, { name: 'fallback', title: { label: '失败地址', tip: '加载失败容错地址' }, propType: 'string', }, { name: 'width', title: { label: '宽度', tip: '宽度' }, propType: 'number', }, { name: 'height', title: { label: '高度', tip: '高度' }, propType: 'number', }, ], configure: { supports: { style: true } }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/image/snippets.ts ================================================ export default [ { title: '图片', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/image-1.png', schema: { componentName: 'Image', props: { src: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png', height: 120, width: 120, }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/input/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Input', title: '输入框', category: '表单', props: [ { name: 'defaultValue', title: { label: '默认值', tip: '默认内容' }, propType: 'string', setter: 'StringSetter', }, { name: 'value', title: { label: '当前值', tip: '当前值' }, propType: 'string', setter: 'StringSetter' }, { name: 'allowClear', title: { label: '支持清除', tip: '是否允许清除' }, propType: 'bool', setter: 'BoolSetter', }, { name: 'bordered', title: { label: '显示边框', tip: '是否有边框' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter', }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', }, { name: 'placeholder', title: { label: '占位提示', tip: '占位提示' }, propType: 'string', defaultValue: '请输入', setter: 'StringSetter' }, // { // name: 'id', // title: { label: '输入框ID', tip: '输入框的ID' }, // propType: 'string', // }, { name: 'maxLength', title: { label: '最大长度', tip: '最大长度' }, propType: 'number', setter: 'NumberSetter', }, { name: 'size', title: { label: '控件大小', tip: '控件大小' }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '大', value: 'large', }, { title: '中', value: 'middle', }, { title: '小', value: 'small', }, ], }, }, propType: { type: 'oneOf', value: ['large', 'middle', 'small'] }, defaultValue: 'middle', }, { name: 'addonAfter', title: { label: '后置标签', tip: '后置标签' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'addonBefore', title: { label: '前置标签', tip: '前置标签' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'prefix', title: { label: '前缀', tip: '前缀' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'suffix', title: { label: '后缀', tip: '后缀' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'onChange', title: { label: '输入框内容变化时的回调', tip: '输入框内容变化时的回调' }, propType: 'func', }, { name: 'onPressEnter', title: { label: '按下回车的回调', tip: '按下回车的回调' }, propType: 'func', }, { name: 'onFocus', title: { label: '获取焦点回调', tip: '获取焦点回调' }, propType: 'func', }, { name: 'onKeyDown', title: { label: '按键按下时的回调', tip: '按键按下时的回调' }, propType: 'func', }, { name: 'onKeyPress', title: { label: '按键按下后的回调', tip: '按键按下之后释放之前的回调' }, propType: 'func', }, { name: 'onKeyUp', title: { label: '按键释放回调', tip: '按键释放之后的回调' }, propType: 'func', }, { name: 'onBlur', title: { label: '失去焦点回调', tip: '失去焦点回调' }, propType: 'func', }, ], configure: { supports: { style: true, events: [ { name: 'onChange', template: "onChange(event,${extParams}){\n// 输入框内容变化时的回调\nconsole.log('onChange',event);}", }, { name: 'onPressEnter', template: "onPressEnter(event,${extParams}){\n// 按下回车的回调\nconsole.log('onPressEnter',event);}", }, { name: 'onFocus', template: "onFocus(event,${extParams}){\n// 获取焦点回调\nconsole.log('onFocus',event);}", }, { name: 'onKeyDown', template: "onKeyDown(event,${extParams}){\n// 按键按下时的回调\nconsole.log('onKeyDown',event);}", }, { name: 'onKeyPress', template: "onKeyPress(event,${extParams}){\n// 按键按下后的回调\nconsole.log('onKeyPress',event);}", }, { name: 'onKeyUp', template: "onKeyUp(event,${extParams}){\n// 按键释放回调\nconsole.log('onKeyUp',event);}", }, { name: 'onBlur', template: "onBlur(event,${extParams}){\n// 按键释放回调\nconsole.log('onBlur',event);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/input/snippets.ts ================================================ export default [ { title: '输入框', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/input-1.png', schema: { componentName: 'Input', props: { placeholder: '请输入', }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/input-number/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'InputNumber', title: '数字输入框', category: '表单', props: [ { name: 'defaultValue', title: { label: '默认值', tip: '默认值' }, propType: 'number', setter: 'NumberSetter', }, { name: 'value', title: { label: '当前值', tip: '当前值' }, propType: 'number', setter: 'NumberSetter', }, { name: 'autoFocus', title: { label: '自动聚焦', tip: '自动获取焦点' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'placeholder', title: { label: '占位提示', tip: '占位提示' }, propType: 'string', defaultValue: '请输入', setter: 'StringSetter' }, { name: 'controls', title: { label: '是否显示增减按钮', tip: '是否显示增减按钮' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter' }, { name: 'bordered', title: { label: '显示边框', tip: '是否有边框' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter' }, { name: 'addonAfter', title: { label: '后置标签', tip: '后置标签' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'addonBefore', title: { label: '前置标签', tip: '前置标签' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, // { // name: 'formatter', // title: { // label: '指定输入框展示值的格式', // tip: '指定输入框展示值的格式', // }, // propType: 'func', // }, { name: 'max', title: { label: '最大值', tip: '最大值' }, propType: 'number', setter: 'NumberSetter' }, { name: 'min', title: { label: '最小值', tip: '最小值' }, propType: 'number', setter: 'NumberSetter' }, { name: 'precision', title: { label: '数值精度', tip: '数值精度' }, propType: 'number', setter: 'NumberSetter' }, // { // name: 'decimalSeparator', // title: { label: '小数点', tip: '小数点' }, // propType: 'string', // }, { name: 'size', title: { label: '尺寸', tip: '输入框大小' }, propType: { type: 'oneOf', value: ['large', 'middle', 'small'] }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '大', value: 'large', }, { title: '中', value: 'middle', }, { title: '小', value: 'small', }, ], }, }, defaultValue: 'middle', }, { name: 'step', title: { label: '单步长', tip: '每次改变步数' }, propType: 'number', setter: 'NumberSetter' }, { name: 'onChange', title: { label: '变化回调', tip: '变化回调' }, propType: 'func', }, { name: 'onPressEnter', title: { label: '按下回车的回调', tip: '按下回车的回调' }, propType: 'func', }, { name: 'onFocus', title: { label: '获取焦点回调', tip: '获取焦点回调' }, propType: 'func', }, { name: 'onKeyDown', title: { label: '按键按下时的回调', tip: '按键按下时的回调' }, propType: 'func', }, { name: 'onKeyPress', title: { label: '按键按下后的回调', tip: '按键按下之后释放之前的回调' }, propType: 'func', }, { name: 'onKeyUp', title: { label: '按键释放回调', tip: '按键释放之后的回调' }, propType: 'func', }, { name: 'onBlur', title: { label: '失去焦点回调', tip: '失去焦点回调' }, propType: 'func', }, ], configure: { supports: { style: true, events: [ { name: 'onChange', template: "onChange(value,${extParams}){\n// 变化回调\nconsole.log('onChange',value);}", }, { name: 'onPressEnter', template: "onPressEnter(event,${extParams}){\n// 按下回车的回调\nconsole.log('onPressEnter',event);}", }, { name: 'onFocus', template: "onFocus(event,${extParams}){\n// 获取焦点回调\nconsole.log('onFocus',event);}", }, { name: 'onKeyDown', template: "onKeyDown(event,${extParams}){\n// 按键按下时的回调\nconsole.log('onKeyDown',event);}", }, { name: 'onKeyPress', template: "onKeyPress(event,${extParams}){\n// 按键按下后的回调\nconsole.log('onKeyPress',event);}", }, { name: 'onKeyUp', template: "onKeyUp(event,${extParams}){\n// 按键释放回调\nconsole.log('onKeyUp',event);}", }, { name: 'onBlur', template: "onBlur(event,${extParams}){\n// 按键释放回调\nconsole.log('onBlur',event);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/input-number/snippets.ts ================================================ export default [ { title: '数字输入框', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/input-number-1.png', schema: { componentName: 'InputNumber', props: { placeholder: '请输入', }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/input.group/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Input.Group', title: '输入框组合', category: '表单', props: [ { name: 'compact', title: { label: '紧凑模式', tip: '是否用紧凑模式' }, propType: 'bool', setter: 'BoolSetter' }, { name: 'size', title: { label: '尺寸', tip: '尺寸大小' }, propType: { type: 'oneOf', value: ['large', 'default', 'small'] }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '大', value: 'large', }, { title: '中', value: 'middle', }, { title: '小', value: 'small', }, ], }, }, defaultValue: 'default', }, ], configure: { component: { isContainer: true }, supports: { style: true } }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/input.group/snippets.ts ================================================ export default [ { title: '输入框组合', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/input-group-1.jpg', schema: { componentName: 'Input.Group', props: {}, children: [ { componentName: 'Input', props: { placeholder: '请输入', }, }, { componentName: 'Input', props: { placeholder: '请输入', }, }, ], }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/input.password/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Input.Password', title: '密码框', category: '表单', props: [ { name: 'defaultValue', title: { label: '默认值', tip: '默认内容' }, propType: 'string', setter: 'StringSetter', }, { name: 'value', title: { label: '当前值', tip: '当前值' }, propType: 'string', setter: 'StringSetter', }, { name: 'allowClear', title: { label: '支持清除', tip: '是否允许清除' }, propType: 'bool', setter: 'BoolSetter', }, { name: 'bordered', title: { label: '显示边框', tip: '是否有边框' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter' }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'visibilityToggle', title: { label: '切换按钮', tip: '是否显示切换按钮' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter' }, { name: 'placeholder', title: { label: '占位提示', tip: '占位提示' }, propType: 'string', defaultValue: '请输入', setter: 'StringSetter' }, // { // name: 'id', // title: { label: '输入框ID', tip: '输入框的ID' }, // propType: 'string', // }, { name: 'maxLength', title: { label: '最大长度', tip: '最大长度' }, propType: 'number', setter: 'NumberSetter' }, { name: 'size', title: { label: '控件大小', tip: '控件大小' }, propType: { type: 'oneOf', value: ['large', 'middle', 'small'] }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '大', value: 'large', }, { title: '中', value: 'middle', }, { title: '小', value: 'small', }, ], }, }, defaultValue: 'middle', }, { name: 'addonAfter', title: { label: '后置标签', tip: '后置标签' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'addonBefore', title: { label: '前置标签', tip: '前置标签' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'prefix', title: { label: '前缀', tip: '前缀' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'onChange', title: { label: '输入框内容变化时的回调', tip: '输入框内容变化时的回调' }, propType: 'func', }, { name: 'onPressEnter', title: { label: '按下回车的回调', tip: '按下回车的回调' }, propType: 'func', }, { name: 'onFocus', title: { label: '获取焦点回调', tip: '获取焦点回调' }, propType: 'func', }, { name: 'onKeyDown', title: { label: '按键按下时的回调', tip: '按键按下时的回调' }, propType: 'func', }, { name: 'onKeyPress', title: { label: '按键按下后的回调', tip: '按键按下之后释放之前的回调' }, propType: 'func', }, { name: 'onKeyUp', title: { label: '按键释放回调', tip: '按键释放之后的回调' }, propType: 'func', }, { name: 'onBlur', title: { label: '失去焦点回调', tip: '失去焦点回调' }, propType: 'func', }, ], configure: { supports: { style: true, events: [ { name: 'onChange', template: "onChange(event,${extParams}){\n// 输入框内容变化时的回调\nconsole.log('onChange',event);}", }, { name: 'onPressEnter', template: "onPressEnter(event,${extParams}){\n// 按下回车的回调\nconsole.log('onPressEnter',event);}", }, { name: 'onFocus', template: "onFocus(event,${extParams}){\n// 获取焦点回调\nconsole.log('onFocus',event);}", }, { name: 'onKeyDown', template: "onKeyDown(event,${extParams}){\n// 按键按下时的回调\nconsole.log('onKeyDown',event);}", }, { name: 'onKeyPress', template: "onKeyPress(event,${extParams}){\n// 按键按下后的回调\nconsole.log('onKeyPress',event);}", }, { name: 'onKeyUp', template: "onKeyUp(event,${extParams}){\n// 按键释放回调\nconsole.log('onKeyUp',event);}", }, { name: 'onBlur', template: "onBlur(event,${extParams}){\n// 按键释放回调\nconsole.log('onBlur',event);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/input.password/snippets.ts ================================================ export default [ { title: '密码框', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/input-password-1.png', schema: { componentName: 'Input.Password', props: { // defaultValue: '123456', }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/input.search/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Input.Search', title: '搜索框', category: '表单', props: [ { name: 'defaultValue', title: { label: '默认值', tip: '默认值' }, propType: 'string', setter: 'StringSetter' }, { name: 'value', title: { label: '当前值', tip: '当前值' }, propType: 'string', setter: 'StringSetter' }, { name: 'bordered', title: { label: '显示边框', tip: '是否有边框' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter' }, { name: 'loading', title: { label: '加载状态', tip: 'loading' }, propType: 'bool', setter: 'BoolSetter' }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'placeholder', title: { label: '占位提示', tip: '占位提示' }, propType: 'string', defaultValue: '请输入', setter: 'StringSetter' }, // { // name: 'id', // title: { label: '输入框ID', tip: '输入框的ID' }, // propType: 'string', // }, { name: 'size', title: { label: '控件大小', tip: '控件大小' }, propType: { type: 'oneOf', value: ['large', 'middle', 'small'] }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '大', value: 'large', }, { title: '中', value: 'middle', }, { title: '小', value: 'small', }, ], }, }, defaultValue: 'middle', }, { name: 'enterButton', title: { label: '确认按钮', tip: '是否有确认按钮,可设为按钮文字。该属性会与 addonAfter 冲突。', }, propType: { type: 'oneOfType', value: ['bool', 'node'] }, defaultValue: false, }, { name: 'addonAfter', title: { label: '后置标签', tip: '后置标签' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'addonBefore', title: { label: '前置标签', tip: '前置标签' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'prefix', title: { label: '前缀', tip: '前缀' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'suffix', title: { label: '后缀', tip: '后缀' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'onChange', title: { label: '输入框内容变化时的回调', tip: '输入框内容变化时的回调' }, propType: 'func', }, { name: 'onPressEnter', title: { label: '按下回车的回调', tip: '按下回车的回调' }, propType: 'func', }, { name: 'onSearch', title: { label: '点击搜索或按下回车键时的回调', tip: '点击搜索或按下回车键时的回调', }, propType: 'func', }, { name: 'onFocus', title: { label: '获取焦点回调', tip: '获取焦点回调' }, propType: 'func', }, { name: 'onKeyDown', title: { label: '按键按下时的回调', tip: '按键按下时的回调' }, propType: 'func', }, { name: 'onKeyPress', title: { label: '按键按下后的回调', tip: '按键按下之后释放之前的回调' }, propType: 'func', }, { name: 'onKeyUp', title: { label: '按键释放回调', tip: '按键释放之后的回调' }, propType: 'func', }, { name: 'onBlur', title: { label: '失去焦点回调', tip: '失去焦点回调' }, propType: 'func', }, ], configure: { supports: { style: true, events: [ { name: 'onChange', template: "onChange(event,${extParams}){\n// 输入框内容变化时的回调\nconsole.log('onChange',event);}", }, { name: 'onPressEnter', template: "onPressEnter(event,${extParams}){\n// 按下回车的回调\nconsole.log('onPressEnter',event);}", }, { name: 'onSearch', template: "onSearch(value,event,${extParams}){\n// 点击搜索图标、清除图标,或按下回车键时的回调\nconsole.log('onSearch',value,event);}", }, { name: 'onFocus', template: "onFocus(event,${extParams}){\n// 获取焦点回调\nconsole.log('onFocus',event);}", }, { name: 'onKeyDown', template: "onKeyDown(event,${extParams}){\n// 按键按下时的回调\nconsole.log('onKeyDown',event);}", }, { name: 'onKeyPress', template: "onKeyPress(event,${extParams}){\n// 按键按下后的回调\nconsole.log('onKeyPress',event);}", }, { name: 'onKeyUp', template: "onKeyUp(event,${extParams}){\n// 按键释放回调\nconsole.log('onKeyUp',event);}", }, { name: 'onBlur', template: "onBlur(event,${extParams}){\n// 按键释放回调\nconsole.log('onBlur',event);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/input.search/snippets.ts ================================================ export default [ { title: '搜索框', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/input-search-1.png', schema: { componentName: 'Input.Search', props: { placeholder: '搜索...', }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/input.text-area/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Input.TextArea', title: '长文本', category: '表单', props: [ { name: 'defaultValue', title: { label: '默认值', tip: '默认内容' }, propType: 'string', setter: 'TextAreaSetter', }, { name: 'value', title: { label: '当前值', tip: '当前值' }, propType: 'string', setter: 'TextAreaSetter', }, { name: 'bordered', title: { label: '显示边框', tip: '是否有边框' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter' }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'placeholder', title: { label: '占位提示', tip: '占位提示' }, propType: 'string', defaultValue: '请输入', setter: 'StringSetter' }, { name: 'showCount', title: { label: '展示字数', tip: '是否展示字数' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'id', title: { label: '输入框ID', tip: '输入框的ID' }, propType: 'string', setter: 'StringSetter' }, { name: 'maxLength', title: { label: '最大长度', tip: '最大长度' }, propType: 'number', setter: 'NumberSetter' }, { name: 'size', title: { label: '控件大小', tip: '控件大小' }, propType: { type: 'oneOf', value: ['large', 'middle', 'small'] }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '大', value: 'large', }, { title: '中', value: 'middle', }, { title: '小', value: 'small', }, ], }, }, defaultValue: 'middle', }, { name: 'autoSize', title: { label: '高度自适应设置', tip: '高度自适应设置' }, propType: { type: 'oneOfType', value: [ 'bool', { type: 'shape', value: [ { name: 'minRows', title: '最小行数', setter: 'NumberSetter', defaultValue: 3, }, { name: 'maxRows', title: '最大行数', setter: 'NumberSetter', defaultValue: 3, }, ], }, ], }, defaultValue: false, }, { name: 'onChange', title: { label: '输入框内容变化时的回调', tip: '输入框内容变化时的回调' }, propType: 'func', }, { name: 'onPressEnter', title: { label: '按下回车的回调', tip: '按下回车的回调' }, propType: 'func', }, { name: 'onResize', title: { label: 'resize 回调', tip: 'resize 回调' }, propType: 'func', }, { name: 'onFocus', title: { label: '获取焦点回调', tip: '获取焦点回调' }, propType: 'func', }, { name: 'onKeyDown', title: { label: '按键按下时的回调', tip: '按键按下时的回调' }, propType: 'func', }, { name: 'onKeyPress', title: { label: '按键按下后的回调', tip: '按键按下之后释放之前的回调' }, propType: 'func', }, { name: 'onKeyUp', title: { label: '按键释放回调', tip: '按键释放之后的回调' }, propType: 'func', }, { name: 'onBlur', title: { label: '失去焦点回调', tip: '失去焦点回调' }, propType: 'func', }, ], configure: { supports: { style: true, events: [ { name: 'onChange', template: "onChange(event,${extParams}){\n// 输入框内容变化时的回调\nconsole.log('onChange',event);}", }, { name: 'onPressEnter', template: "onPressEnter(event,${extParams}){\n// 按下回车的回调\nconsole.log('onPressEnter',event);}", }, { name: 'onResize', template: "onResize({width,height},${extParams}){\n// resize 回调\nconsole.log('onResize',width,height);}", }, { name: 'onFocus', template: "onFocus(event,${extParams}){\n// 获取焦点回调\nconsole.log('onFocus',event);}", }, { name: 'onKeyDown', template: "onKeyDown(event,${extParams}){\n// 按键按下时的回调\nconsole.log('onKeyDown',event);}", }, { name: 'onKeyPress', template: "onKeyPress(event,${extParams}){\n// 按键按下后的回调\nconsole.log('onKeyPress',event);}", }, { name: 'onKeyUp', template: "onKeyUp(event,${extParams}){\n// 按键释放回调\nconsole.log('onKeyUp',event);}", }, { name: 'onBlur', template: "onBlur(event,${extParams}){\n// 按键释放回调\nconsole.log('onBlur',event);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/input.text-area/snippets.ts ================================================ export default [ { title: '长文本', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/input-text-area-1.png', schema: { componentName: 'Input.TextArea', props: { autoSize: { minRows: 3, maxRows: 3, }, placeholder: '请输入', }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/list/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'List', title: '列表', category: '数据展示', props: [ { title: '数据源', display: 'block', type: 'group', items: [ { name: 'dataSource', title: { label: '列表数据源', tip: '列表数据源' }, propType: { type: 'arrayOf', value: 'any' }, setter: ['JsonSetter', 'VariableSetter'], }, { name: 'loading', title: { label: '是否加载中', tip: 'loading | 当卡片内容还在加载中时,可以用 loading 展示一个占位', }, propType: 'bool', defaultValue: false, setter: ['BoolSetter', 'VariableSetter'], }, { name: 'rowKey', title: { label: '行Key', tip: 'rowKey | 当 renderItem 自定义渲染列表项有效时,自定义每一行的 key 的获取方式', }, propType: { type: 'oneOfType', value: ['string', 'function'], }, defaultValue: 'id', setter: [ 'StringSetter', { componentName: 'FunctionSetter', props: { template: 'rowKey(item,${extParams}){\n// 自定义每一行的 key\nreturn `key-${item.id}`;\n}', }, }, 'VariableSetter', ], }, ], }, { title: '外观', display: 'block', type: 'group', items: [ { name: 'itemLayout', title: { label: '尺寸', tip: 'itemLayout | 设置 List.Item 布局, 设置成 vertical 则竖直样式显示, 默认横排', }, propType: { type: 'oneOf', value: ['horizontal', 'vertical'] }, defaultValue: 'horizontal', setter: [ { componentName: 'RadioGroupSetter', props: { options: [ { title: '水平', value: 'horizontal', }, { title: '垂直', value: 'vertical', }, ], }, }, 'VariableSetter', ], }, { name: 'size', title: { label: '尺寸', tip: 'size | 列表的尺寸' }, propType: { type: 'oneOf', value: ['default', 'large', 'small'] }, defaultValue: 'default', setter: [ { componentName: 'RadioGroupSetter', props: { options: [ { title: '默认', value: 'default', }, { title: '大', value: 'large', }, { title: '小', value: 'small', }, ], }, }, 'VariableSetter', ], }, { name: 'bordered', title: { label: '显示边框', tip: 'bordered | 是否展示边框' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter', }, { name: 'split', title: { label: '展示分割线', tip: 'split | 是否展示分割线' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter', }, ], }, { title: '栅格', display: 'block', type: 'group', items: [ { name: 'gridEnable', title: { label: '启用栅格', tip: 'grid | 是否启用栅格' }, propType: 'bool', setter: 'BoolSetter', extraProps: { setValue(target, value) { if (value === false) { const { node } = target; node.setPropValue('grid', false); } }, }, }, { name: 'grid.column', title: { label: '列数', tip: 'grid.column | 栅格的列数' }, propType: 'number', setter: 'NumberSetter', defaultValue: 4, condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("gridEnable")', }, }, { name: 'grid.gutter', title: { label: '间隔', tip: 'grid.gutter | 栅格的间隔' }, propType: 'number', setter: 'NumberSetter', defaultValue: 0, condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("gridEnable")', }, }, ], }, { title: '分页', display: 'block', type: 'group', items: [ { name: 'pagination', title: { label: '显示分页', tip: 'pagination | 显示分页' }, propType: 'object', setter: 'BoolSetter', extraProps: { setValue: (target, value) => { if (value) { target.parent.setPropValue('pagination', { pageSize: 5, }); } }, }, }, { name: 'pagination.pageSize', title: { label: '每页条数', tip: 'pagination.pageSize | 每页条数' }, setter: 'NumberSetter', condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("pagination")', }, }, { name: 'pagination.total', title: { label: '数据总数', tip: 'pagination.total | 数据总数' }, setter: 'NumberSetter', condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("pagination")', }, }, // { // name: 'pagination.defaultCurrent', // title: { // label: '默认当前页', // tip: 'pagination.defaultCurrent | 默认的当前页数', // }, // setter: [ // { // componentName: 'NumberSetter', // props: { // initialValue: 1, // }, // }, // 'VariableSetter', // ], // condition: { // type: 'JSFunction', // value: 'target => !!target.getProps().getPropValue("pagination")', // }, // }, { name: 'pagination.current', title: { label: '当前页数', tip: 'pagination.current | 当前页数' }, setter: 'NumberSetter', condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("pagination")', }, }, { name: 'pagination.showTotal', title: { label: '显示总数', tip: 'pagination.showTotal | 用于显示数据总量和当前数据顺序', }, propType: 'func', setter: [ { componentName: 'FunctionSetter', props: { template: 'showTotal(total,range,${extParams}){\n// 用于格式化显示表格数据总量\nreturn `共 ${total} 条`;\n}', }, }, 'VariableSetter', ], condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("pagination")', }, }, { name: 'pagination.showSizeChanger', title: { label: '页数切换', tip: 'pagination.showSizeChanger | 是否展示 pageSize 切换器', }, propType: 'bool', setter: 'BoolSetter', defaultValue: false, condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("pagination")', }, }, { name: 'pagination.showQuickJumper', title: { label: '快速跳转', tip: 'pagination.showQuickJumper | 是否可以快速跳转至某页', }, propType: 'bool', setter: 'BoolSetter', defaultValue: false, condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("pagination")', }, }, { name: 'pagination.simple', title: { label: '简单分页', tip: 'pagination.simple | 简单分页' }, propType: 'bool', setter: 'BoolSetter', defaultValue: false, condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("pagination")', }, }, { name: 'pagination.size', title: { label: '分页尺寸', tip: 'pagination.size | 分页尺寸' }, propType: { type: 'oneOf', value: ['default', 'small'], }, setter: [ { componentName: 'RadioGroupSetter', props: { options: [ { title: '默认', value: 'default', }, { title: '小', value: 'small', }, ], }, }, 'VariableSetter', ], defaultValue: 'default', condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("pagination")', }, }, { name: 'pagination.position', title: { label: '分页位置', tip: 'pagination.position | 分页位置' }, setter: { componentName: 'SelectSetter', props: { options: [ { title: '上', value: 'top', }, { title: '下', value: 'bottom', }, { title: '上下', value: 'both', }, ], }, initialValue: 'bottomRight', }, condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("pagination")', }, }, ], }, { title: '扩展', display: 'block', type: 'group', items: [ { name: 'renderItem', title: { label: '渲染函数', tip: 'renderItem | 当使用 dataSource 时,可以用 `renderItem` 自定义渲染列表项', }, propType: 'func', setter: [ { componentName: 'SlotSetter', title: '渲染函数插槽', initialValue: { type: 'JSSlot', params: ['item'], value: [ { componentName: 'List.Item', props: {}, children: { componentName: 'Typography.Text', props: { children: { type: 'JSExpression', value: 'this.item.text', }, }, }, }, ], }, }, { componentName: 'FunctionSetter', props: { template: 'renderItem(item,${extParams}){\n// 自定义渲染列表项\nreturn `item`;\n}', }, }, 'VariableSetter', ], }, { name: 'header', title: { label: '列表头部', tip: 'header | 列表头部', }, propType: 'node', setter: { componentName: 'SlotSetter', initialValue: { type: 'JSSlot', value: [ { componentName: 'Typography.Text', props: { children: '列表头部', }, }, ], }, }, }, { name: 'footer', title: { label: '列表底部', tip: 'footer | 列表底部', }, propType: 'node', setter: { componentName: 'SlotSetter', initialValue: { type: 'JSSlot', value: [ { componentName: 'Typography.Text', props: { children: '列表底部', }, }, ], }, }, }, { name: 'loadMore', title: { label: '加载更多', tip: 'loadMore | 加载更多', }, propType: 'node', setter: { componentName: 'SlotSetter', initialValue: { type: 'JSSlot', value: [ { componentName: 'Button', props: { children: 'loading more', }, }, ], }, }, }, ], }, ], configure: { supports: { style: true, events: [ { name: 'pagination.onChange', template: 'onChange(page,pageSize,${extParams}){\n// 页码或 pageSize 改变的回调\n}', }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/list/snippets.ts ================================================ export default [ { title: '简单列表', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/list-1.png', schema: { componentName: 'List', props: { dataSource: [ { id: 1, text: 'Racing car sprays burning fuel into crowd.', }, { id: 2, text: 'Japanese princess to wed commoner.', }, { id: 3, text: 'Australian walks 100km after outback crash.', }, { id: 4, text: 'Man charged over missing wedding girl.', }, { id: 5, text: 'Los Angeles battles huge wildfires.', }, ], renderItem: { type: 'JSSlot', params: ['item'], value: [ { componentName: 'List.Item', props: {}, children: { componentName: 'Typography.Text', props: { children: { type: 'JSExpression', value: 'this.item.text', }, }, }, }, ], }, header: { type: 'JSSlot', value: [ { componentName: 'Typography.Text', props: { children: '列表头部', }, }, ], }, footer: { type: 'JSSlot', value: [ { componentName: 'Typography.Text', props: { children: '列表底部', }, }, ], }, itemLayout: 'horizontal', size: 'default', bordered: true, split: true, pagination: { pageSize: 5, total: 10, current: 1, }, }, }, }, { title: '基础列表', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/list-1.png', schema: { componentName: 'List', props: { dataSource: [ { id: 1, title: 'Ant Design Title 1', avatar: 'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png', description: 'Ant Design, a design language for background applications, is refined by Ant UED Team', }, { id: 2, title: 'Ant Design Title 2', avatar: 'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png', description: 'Ant Design, a design language for background applications, is refined by Ant UED Team', }, { id: 3, title: 'Ant Design Title 3', avatar: 'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png', description: 'Ant Design, a design language for background applications, is refined by Ant UED Team', }, { id: 4, title: 'Ant Design Title 4', avatar: 'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png', description: 'Ant Design, a design language for background applications, is refined by Ant UED Team', }, { id: 5, title: 'Ant Design Title 5', avatar: 'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png', description: 'Ant Design, a design language for background applications, is refined by Ant UED Team', }, ], renderItem: { type: 'JSSlot', params: ['item'], value: [ { componentName: 'List.Item', props: {}, children: { componentName: 'List.Item.Meta', props: { avatar: { type: 'JSSlot', value: [ { componentName: 'Avatar', props: { icon: { componentName: 'Icon', props: { type: 'UserOutlined', }, }, src: { type: 'JSExpression', value: 'this.item.avatar', }, }, }, ], }, title: { type: 'JSSlot', value: [ { componentName: 'Typography.Link', props: { children: { type: 'JSExpression', value: 'this.item.title', }, }, }, ], }, description: { type: 'JSSlot', value: [ { componentName: 'Typography.Text', props: { children: { type: 'JSExpression', value: 'this.item.description', }, }, }, ], }, }, }, }, ], }, itemLayout: 'horizontal', size: 'default', bordered: true, split: true, pagination: { pageSize: 10, total: 15, current: 1, }, }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/list.item/meta.ts ================================================ // FIXME: 选中tabPane点复制,会出问题,因为复制的组件key一样 export default { componentName: 'List.Item', title: '列表项', category: '', props: [ { name: 'actions', title: { label: '列表操作组', tip: '列表操作组', }, propType: { type: 'arrayOf', value: 'node' }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'SlotSetter', title: '操作组插槽', initialValue: { type: 'JSSlot', value: [], }, }, }, }, }, { name: 'extra', title: { label: '额外内容', tip: '额外内容', }, propType: 'node', setter: 'SlotSetter', }, ], configure: { component: { isContainer: true, nestingRule: { parentWhitelist: ['List'], }, }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/list.item.meta/meta.ts ================================================ export default { componentName: 'List.Item.Meta', title: '列表项内容', category: '', props: [ { name: 'avatar', title: { label: '列表元素图标', tip: '列表元素的图标', }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'title', title: { label: '列表元素标题', tip: '列表元素的标题', }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'avatar', title: { label: '列表元素描述内容', tip: '列表元素的描述内容', }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, ], configure: { component: { nestingRule: { parentWhitelist: ['List'], }, }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/mentions/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Mentions', title: '提及', category: '表单', props: [ { name: 'defaultValue', title: { label: '默认值', tip: '默认值' }, propType: 'string', setter: 'StringSetter' }, { name: 'autoFocus', title: { label: '自动聚焦', tip: '自动获得焦点' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'filterOption', title: { label: '自定义过滤逻辑', tip: '自定义过滤逻辑' }, propType: { type: 'oneOfType', value: ['bool', 'func'] }, }, { name: 'notFoundContent', title: { label: '空值展示', tip: '当下拉列表为空时显示的内容', }, propType: 'node', }, { name: 'placement', title: { label: '弹出层展示位置', tip: '弹出层展示位置' }, propType: { type: 'oneOf', value: ['top', 'bottom'] }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '上', value: 'top', }, { title: '下', value: 'bottom', }, ], }, }, }, { name: 'prefix', title: { label: '设置触发关键字', tip: '设置触发关键字' }, propType: { type: 'oneOfType', value: ['string', { type: 'arrayOf', value: 'string' }], }, }, { name: 'split', title: { label: '设置选中项前后分隔符', tip: '设置选中项前后分隔符' }, propType: 'string', }, { name: 'validateSearch', title: { label: '自定义触发验证逻辑', tip: '自定义触发验证逻辑' }, propType: 'func', }, // { // name: 'value', // title: { label: '设置值', tip: '设置值' }, // propType: 'string', // }, { name: 'onChange', title: { label: '值改变时触发', tip: '值改变时触发' }, propType: 'func', }, { name: 'onSelect', title: { label: '选择选项时触发', tip: '选择选项时触发' }, propType: 'func', }, { name: 'onSearch', title: { label: '搜索时触发', tip: '搜索时触发' }, propType: 'func', }, { name: 'onFocus', title: { label: '获得焦点时触发', tip: '获得焦点时触发' }, propType: 'func', }, { name: 'onBlur', title: { label: '失去焦点时触发', tip: '失去焦点时触发' }, propType: 'func', }, // { // name: 'getPopupContainer', // title: { // label: '指定建议框挂载的 HTML 节点', // tip: '指定建议框挂载的 HTML 节点', // }, // propType: 'func', // }, { name: 'autoSize', title: { label: '内容高度', tip: '自适应内容高度,可设置为 true | false 或对象:{ minRows: 2, maxRows: 6 }', }, propType: { type: 'oneOfType', value: ['bool', 'object'] }, }, { name: 'onResize', title: { label: 'resize 回调', tip: 'resize 回调' }, propType: 'func', }, ], configure: { supports: { style: true, events: [ { name: 'onChange', template: "onChange(text,${extParams}){\n// 值改变时触发\nconsole.log('onChange',text);}", }, { name: 'onSelect', template: "onSelect(option,prefix,${extParams}){\n// 选择选项时触发\nconsole.log('onSelect',option,prefix);}", }, { name: 'onSearch', template: "onSearch(text,prefix,${extParams}){\n// 搜索时触发\nconsole.log('onSearch',text,prefix);}", }, { name: 'onFocus', template: "onFocus(${extParams}){\n// 获得焦点时触发\nconsole.log('onFocus');}", }, { name: 'onBlur', template: "onBlur(${extParams}){\n// 失去焦点时触发\nconsole.log('onBlur');}", }, { name: 'onResize', template: "onResize({width,height},${extParams}){\n// resize 回调\nconsole.log('onResize',width,height);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/mentions/snippets.ts ================================================ export default [ { title: '提及', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/mentions-1.png', schema: { componentName: 'Mentions', props: {}, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/menu/meta.ts ================================================ import { uuid } from '../_utils/utils'; import { itemsExtraProps } from './utils'; import snippets from './snippets'; export default { snippets, componentName: 'Menu', title: '导航菜单', category: '导航', props: [ { name: 'items', title: '菜单项', setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'key', title: 'key', setter: 'StringSetter', initialValue: (val) => val || uuid(), }, { name: 'children', title: '菜单名称', setter: 'StringSetter', }, { name: 'category', title: { label: '类型', tip: '菜单项类型', }, propType: { type: 'oneOf', value: ['Menu.Item', 'Menu.SubMenu', 'Menu.ItemGroup'], }, setter: [ { componentName: 'RadioGroupSetter', props: { options: [ { title: 'Item', value: 'Menu.Item', }, { title: 'SubMenu', value: 'Menu.SubMenu', }, { title: 'ItemGroup', value: 'Menu.ItemGroup', }, ], }, }, 'VariableSetter', ], }, ], }, }, initialValue: () => { return { key: 'item-' + uuid(), category: 'Menu.Item', children: '菜单名', }; }, }, }, }, extraProps: itemsExtraProps, }, { name: 'defaultOpenKeys', title: { label: '初始展开菜单项', tip: '初始展开的 SubMenu 菜单项 key 数组', }, propType: { type: 'arrayOf', value: 'string' }, }, { name: 'defaultSelectedKeys', title: { label: '初始选中的菜单项', tip: '初始选中的菜单项 key 数组' }, propType: { type: 'arrayOf', value: 'string' }, }, { name: 'forceSubMenuRender', title: { label: '子菜单预渲染', tip: '在子菜单展示之前就渲染进 DOM', }, propType: 'bool', defaultValue: false, }, { name: 'inlineCollapsed', title: { label: '是否收起', tip: 'inline 时菜单是否收起状态' }, propType: 'bool', }, { name: 'inlineIndent', title: { label: '缩进宽度', tip: 'inline 模式的菜单缩进宽度' }, propType: 'number', }, { name: 'mode', title: { label: '菜单类型', tip: '菜单类型,现在支持垂直、水平、和内嵌模式三种', }, propType: { type: 'oneOf', value: ['vertical', 'horizontal', 'inline'] }, }, { name: 'multiple', title: { label: '是否允许多选', tip: '是否允许多选' }, propType: 'bool', defaultValue: false, }, { name: 'openKeys', title: { label: '当前展开的菜单项', tip: '当前展开的 SubMenu 菜单项 key 数组', }, propType: { type: 'arrayOf', value: 'string' }, }, { name: 'selectable', title: { label: '是否允许选中', tip: '是否允许选中' }, propType: 'bool', defaultValue: true, }, { name: 'selectedKeys', title: { label: '当前选中项', tip: '当前选中的菜单项 key 数组' }, propType: { type: 'arrayOf', value: 'string' }, }, { name: 'style', title: { label: '根节点样式', tip: '根节点样式' }, propType: 'object', }, { name: 'subMenuCloseDelay', title: { label: '关闭延时', tip: '用户鼠标离开子菜单后关闭延时,单位:秒', }, propType: 'number', }, { name: 'subMenuOpenDelay', title: { label: '开启延时', tip: '用户鼠标进入子菜单后开启延时,单位:秒', }, propType: 'number', }, { name: 'theme', title: { label: '主题颜色', tip: '主题颜色' }, propType: { type: 'oneOf', value: ['light', 'dark'] }, }, { name: 'onClick', title: { label: '点击 MenuItem 调用函数', tip: '点击 MenuItem 调用函数' }, propType: 'func', }, { name: 'onDeselect', title: { label: '取消选中时调用函数', tip: '取消选中时调用,仅在 multiple 生效', }, propType: 'func', }, { name: 'triggerSubMenuAction', title: { label: '触发方式', tip: '展开/关闭的触发行为', }, propType: { type: 'oneOf', value: ['hover', 'click'] }, }, { name: 'onOpenChange', title: { label: 'SubMenu 展开/关闭的回调', tip: '展开/关闭的回调' }, propType: 'func', }, { name: 'onSelect', title: { label: '被选中时调用函数', tip: '被选中时调用函数' }, propType: 'func', }, { name: 'overflowedIndicator', title: { label: '折叠图标', tip: '自定义 Menu 折叠时的图标' }, propType: 'node', }, ], configure: { supports: { style: true, events: [ { name: 'onClick', template: "onClick({item,key,keyPath,domEvent},${extParams}){\n// 点击 MenuItem 调用此函数\nconsole.log('onClick',item,key,keyPath,domEvent);}", }, { name: 'onDeselect', template: "onDeselect({item,key,keyPath,selectedKeys,domEvent},${extParams}){\n// 取消选中时调用,仅在 multiple 生效\nconsole.log('onDeselect',item,key,keyPath,selectedKeys,domEvent);}", }, { name: 'onOpenChange', template: "onOpenChange(openKeys,${extParams}){\n// SubMenu 展开/关闭的回调\nconsole.log('onOpenChange',openKeys);}", }, { name: 'onSelect', template: "onSelect({item,key,keyPath,selectedKeys,domEvent},${extParams}){\n// 被选中时调用\nconsole.log('onSelect',item,key,keyPath,selectedKeys,domEvent);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/menu/snippets.ts ================================================ export default [ { title: '导航菜单', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/menu-1.jpg', schema: { componentName: 'Menu', props: { mode: 'inline', defaultSelectedKeys: ['1'], defaultOpenKeys: ['sub1'], theme: 'dark', items: [ { key: 'item-i5wd', category: 'Menu.Item', children: '菜单名', }, ], }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/menu/utils.ts ================================================ import { uuid } from '../_utils/utils'; export const itemsExtraProps = { getValue(target, fieldValue) { const map = target.node.children.map((child) => { const key = child.getPropValue('key') ? String(child.getPropValue('key')) : child.id; const result = { key, category: child.componentName, }; ['children', 'items', 'title'].forEach((propKey) => { if (child.getPropValue(propKey)) { result[propKey] = child.getPropValue(propKey); } }); return result; }); return map.length === 0 ? fieldValue : map; }, setValue(target, value) { const { node } = target; const map = {}; if (!Array.isArray(value)) { value = []; } value.forEach((item) => { const tabItem = Object.assign({}, item); map[item.key] = tabItem; }); node.children.mergeChildren( (child) => { const key = String(child.getPropValue('key')); if ( Object.hasOwnProperty.call(map, key) && child.componentName.includes(map[key].category) ) { if (map[key].category === 'Menu.Item') { child.setPropValue('children', map[key].children); } else { child.setPropValue('title', map[key].title || map[key].children); } delete map[key]; return false; } return true; }, () => { const items = []; for (const key in map) { const itemProps = map[key]; if (Object.hasOwnProperty.call(map, key)) { if (itemProps.category === 'Menu.Item') { items.push({ componentName: 'Menu.Item', props: { key: itemProps.key, children: itemProps.children, }, }); } else { items.push({ componentName: 'Menu.SubMenu', props: { key: itemProps.key, title: itemProps.title || itemProps.children, items: itemProps.items && itemProps.items.length === 0 ? itemProps.items : [ { key: `item-${uuid()}`, category: 'Menu.Item', children: '子菜单名', }, ], }, }); } } } return items; }, (child1, child2) => { const a = value.findIndex( (item) => String(item.key) === String(child1.getPropValue('key')), ); const b = value.findIndex( (item) => String(item.key) === String(child2.getPropValue('key')), ); return a - b; }, ); }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/menu.item/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Menu.Item', title: '菜单项', props: [ { name: 'children', title: { label: '内容', tip: '内容' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'danger', title: { label: '错误状态', tip: '展示错误状态样式' }, propType: 'bool', defaultValue: false, }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态' }, propType: 'bool', defaultValue: false, }, { name: 'icon', title: { label: '菜单图标', tip: '菜单图标' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, defaultValue: false, }, { name: 'key', title: { label: '唯一标志', tip: 'item 的唯一标志' }, propType: 'string', }, { name: 'title', title: { label: '悬浮标题', tip: '设置收缩时展示的悬浮标题', }, propType: 'string', }, ], configure: { component: { isContainer: true, nestingRule: { parentWhitelist: ['Menu'] }, }, supports: { style: true }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/menu.item/snippets.ts ================================================ export default []; ================================================ FILE: packages/antd-lowcode-materials/lowcode/menu.item-group/meta.ts ================================================ import { uuid } from '../_utils/utils'; import { itemsExtraProps } from '../menu/utils'; import snippets from './snippets'; export default { snippets, componentName: 'Menu.ItemGroup', title: '菜单组', props: [ { name: 'items', title: '菜单组项', setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'key', title: 'key', setter: 'StringSetter', initialValue: (val) => val || uuid(), }, { name: 'children', tite: '菜单名', setter: 'StringSetter', }, { name: 'category', title: { label: '类型', tip: '菜单项类型', }, propType: { type: 'oneOf', value: ['Menu.Item', 'Menu.SubMenu', 'Menu.ItemGroup'], }, setter: [ { componentName: 'RadioGroupSetter', props: { options: [ { title: 'Item', value: 'Menu.Item', }, { title: 'SubMenu', value: 'Menu.SubMenu', }, { title: 'ItemGroup', value: 'Menu.ItemGroup', }, ], }, }, 'VariableSetter', ], }, ], }, }, initialValue: () => { return { key: `item-${uuid()}`, category: 'Menu.Item', children: '子菜单名', }; }, }, }, }, extraProps: itemsExtraProps, }, { name: 'children', title: { label: '分组的菜单项', tip: '分组的菜单项' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'title', title: { label: '分组标题', tip: '分组标题' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, ], configure: { component: { isContainer: true, nestingRule: { parentWhitelist: ['Menu', 'Menu.SubMenu'] }, }, supports: { style: true }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/menu.item-group/snippets.ts ================================================ export default []; ================================================ FILE: packages/antd-lowcode-materials/lowcode/menu.sub-menu/meta.ts ================================================ import { uuid } from '../_utils/utils'; import { itemsExtraProps } from '../menu/utils'; import snippets from './snippets'; export default { snippets, componentName: 'Menu.SubMenu', title: '子菜单', props: [ { name: 'items', title: '子菜单项', setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'key', title: 'key', setter: 'StringSetter', initialValue: (val) => val || uuid(), }, { name: 'children', title: '子菜单名', setter: 'StringSetter', }, { name: 'category', title: { label: '类型', tip: '菜单项类型', }, propType: { type: 'oneOf', value: ['Menu.Item', 'Menu.SubMenu', 'Menu.ItemGroup'], }, setter: [ { componentName: 'RadioGroupSetter', props: { options: [ { title: 'Item', value: 'Menu.Item', }, { title: 'SubMenu', value: 'Menu.SubMenu', }, { title: 'ItemGroup', value: 'Menu.ItemGroup', }, ], }, }, 'VariableSetter', ], }, ], }, }, initialValue: () => { return { key: `item-${uuid()}`, category: 'Menu.Item', children: '子菜单名', }; }, }, }, }, extraProps: itemsExtraProps, }, { name: 'danger', title: { label: '错误状态', tip: '展示错误状态样式' }, propType: 'bool', defaultValue: true, }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态' }, propType: 'bool', defaultValue: false, }, { name: 'icon', title: { label: '菜单图标', tip: '菜单图标' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, defaultValue: false, }, { name: 'key', title: { label: '唯一标志', tip: 'item 的唯一标志' }, propType: 'string', }, { name: 'title', title: { label: '悬浮标题', tip: '设置收缩时展示的悬浮标题', }, propType: 'string', }, ], configure: { component: { isContainer: true, nestingRule: { parentWhitelist: ['Menu'] }, }, supports: { style: true }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/menu.sub-menu/snippets.ts ================================================ export default []; ================================================ FILE: packages/antd-lowcode-materials/lowcode/modal/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Modal', title: '对话框', category: '反馈', props: [ { name: 'title', title: { label: '标题', tip: '标题' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'cancelText', title: { label: '取消按钮文字', tip: '取消按钮文字' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'okText', title: { label: '确认按钮文字', tip: '确认按钮文字' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'open', title: { label: '是否可见', tip: '对话框是否可见' }, propType: 'bool', setter: 'BoolSetter', supportVariable: true }, { name: 'centered', title: { label: '垂直居中', tip: '垂直居中展示 Modal' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', supportVariable: true }, { name: 'closable', title: { label: '显示关闭按钮', tip: '是否显示右上角的关闭按钮' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter', supportVariable: true }, { name: 'closeIcon', title: { label: '关闭图标', tip: '自定义关闭图标' }, propType: 'node', }, { name: 'confirmLoading', title: { label: '确定按钮loading', tip: '确定按钮loading' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', supportVariable: true }, { name: 'destroyOnClose', title: { label: '销毁子元素', tip: '关闭时销毁 Modal 里的子元素' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', supportVariable: true }, { name: 'forceRender', title: { label: '强制渲染Modal', tip: '强制渲染Modal' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', supportVariable: true }, { name: 'keyboard', title: { label: 'esc关闭', tip: '是否支持键盘 esc 关闭' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter', supportVariable: true }, { name: 'mask', title: { label: '是否展示遮罩', tip: '是否展示遮罩' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter', supportVariable: true }, { name: 'maskClosable', title: { label: '点击蒙层关闭', tip: '点击蒙层是否允许关闭' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter', supportVariable: true }, { name: 'zIndex', title: { label: 'z-index', tip: '设置 Modal 的 `z-index`' }, propType: 'number', setter: 'NumberSetter', supportVariable: true }, { name: 'width', title: { label: '宽度', tip: '宽度' }, propType: { type: 'oneOfType', value: ['string', 'number'] }, }, { name: 'footer', title: { label: '底部内容', tip: '底部内容,当不需要默认底部按钮时,可以设为 `footer={null}`', }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'okType', title: { label: '确认按钮类型', tip: '确认按钮类型' }, propType: { type: 'oneOf', value: ['default', 'small'] }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: 'primary', value: 'primary', }, { title: 'ghost', value: 'ghost', }, { title: 'dashed', value: 'dashed', }, { title: 'link', value: 'link', }, { title: 'text', value: 'text', }, { title: 'default', value: 'default', }, ], }, }, }, { name: 'okButtonProps', title: { label: '确认按钮props', tip: '确认按钮props' }, propType: 'object', setter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'disabled', title: { label: '是否可点击', tip: 'disabled' }, propType: 'bool', setter: [ { componentName: 'BoolSetter', initialValue: false, }, 'VariableSetter', ], isRequired: true, }, ], }, }, }, }, { name: 'bodyStyle', title: { label: 'body样式', tip: 'Modal body 样式' }, propType: 'object', }, { name: 'maskStyle', title: { label: '遮罩样式', tip: '遮罩样式' }, propType: 'object', }, { name: 'style', title: { label: '浮层样式', tip: '可用于设置浮层的样式,调整浮层位置等', }, propType: 'object', }, { name: 'wrapClassName', title: { label: '外层容器类名', tip: '对话框外层容器的类名' }, propType: 'string', setter: 'StringSetter', supportVariable: true }, { name: 'getContainer', title: { label: '指定挂载节点', tip: '指定 Modal 挂载的 HTML 节点, false 为挂载在当前 dom', }, propType: { type: 'oneOfType', value: ['node', 'func'] }, }, { name: 'onCancel', title: { label: '取消按钮回调', tip: '点击遮罩层或右上角叉或取消按钮的回调', }, propType: 'func', }, { name: 'onOk', title: { label: '点击确定回调', tip: '点击确定回调' }, propType: 'func', }, ], configure: { component: { isContainer: true, isModal: true, rootSelector: '.ant-modal-content', nestingRule: { parentWhitelist: ['Page', 'Component'], }, }, supports: { style: true, events: [ { name: 'afterClose', templete: "onCancel(${extParams}){\n// 完全关闭后的回调\nconsole.log('afterClose');}", }, { name: 'onCancel', template: "onCancel(${extParams}){\n// 点击遮罩层或右上角叉或取消按钮的回调\nconsole.log('onCancel');}", }, { name: 'onOk', template: "onOk(${extParams}){\n// 点击确定回调\nconsole.log('onOk');}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/modal/snippets.ts ================================================ export default [ { title: '普通型', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/modal-1.png', schema: { componentName: 'Modal', props: { title: 'Basic Modal', okText: '确认', cancelText: '取消', open: true, destroyOnClose: true, }, children: [], }, }, { title: '隐藏底部', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/modal-2.png', schema: { componentName: 'Modal', props: { title: 'Basic Modal', okText: '确认', cancelText: '取消', open: true, footer: null, destroyOnClose: true, }, children: [], }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/page-header/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'PageHeader', title: '页头', category: '导航', props: [ { name: 'title', title: { label: '标题', tip: '自定义标题文字' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'subTitle', title: { label: '二级标题', tip: '自定义的二级标题文字' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'ghost', title: { label: 'ghost风格', tip: 'ghost风格' }, propType: 'bool', defaultValue: true, }, // { // name: 'backIcon', // title: { // label: '返回按钮', // tip: '自定义 back icon ,如果为 false 不渲染 back icon', // }, // propType: { type: 'oneOfType', value: ['node', 'bool'] }, // }, { name: 'tags', title: { label: 'tag 列表', tip: 'title 旁的 tag 列表' }, propType: 'node', }, { name: 'extra', title: { label: '操作区', tip: '操作区,位于 title 行的行尾' }, propType: 'node', }, { name: 'footer', title: { label: '页脚', tip: 'PageHeader 的页脚,一般用于渲染 TabBar' }, propType: 'node', }, { name: 'avatar', title: { label: '头像', tip: '标题栏旁的头像' }, propType: 'object', supportVariable: false, setter: [ { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'src', title: { label: '地址', tip: '头像地址' }, setter: { componentName: 'StringSetter', }, }, ], }, }, }, 'JsonSetter', ], }, { name: 'breadcrumb', title: { label: '面包屑的配置', tip: '面包屑的配置' }, propType: 'object', supportVariable: false, setter: [ { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'routes', title: { label: '路由栈信息', tip: '路由栈信息' }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', initialValue: { path: 'path', breadcrumbName: 'pathName', }, isRequired: true, props: { config: { items: [ { name: 'path', defaultValue: 'path', title: { label: '路径', tip: 'path | 路径' }, setter: 'StringSetter', }, { name: 'breadcrumbName', defaultValue: 'pathName', title: { label: '名称', tip: 'breadcrumbName | 名称', }, setter: 'StringSetter', }, ], }, }, }, }, }, }, ], }, }, }, 'JsonSetter', ], }, { name: 'onBack', title: { label: '返回按钮的点击事件', tip: '返回按钮的点击事件' }, propType: 'func', }, ], configure: { supports: { style: true, events: [ { name: 'onBack', template: "onBack(${extParams}){\n// 返回按钮的点击事件\nconsole.log('onBack');}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/page-header/snippets.ts ================================================ export default [ { title: '页头', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/page-header-1.jpg', schema: { componentName: 'PageHeader', props: { title: 'Title', subTitle: 'This is a subtitle', }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/pagination/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Pagination', title: '分页', category: '导航', props: [ { title: '数据', display: 'block', type: 'group', items: [ { name: 'defaultPageSize', title: { label: '默认每页条数', tip: 'defaultPageSize | 默认每页条数', }, propType: 'number', setter: 'NumberSetter', defaultValue: 10, }, { name: 'pageSize', title: { label: '每页条数', tip: 'pageSize | 每页条数' }, propType: 'number', setter: 'NumberSetter', defaultValue: 10, }, { name: 'total', title: { label: '数据总数', tip: 'total | 数据总数' }, propType: 'number', setter: 'NumberSetter', defaultValue: 15, }, { name: 'defaultCurrent', title: { label: '默认当前页', tip: 'defaultCurrent | 默认的当前页数', }, propType: 'number', setter: 'NumberSetter', defaultValue: 1, }, { name: 'current', title: { label: '当前页数', tip: 'current | 当前页数' }, propType: 'number', setter: 'NumberSetter', defaultValue: 1, }, ], }, { title: '功能', display: 'block', type: 'group', items: [ { name: 'disabled', title: { label: '是否禁用', tip: 'disabled | 是否禁用', }, propType: 'bool', setter: 'BoolSetter', defaultValue: false, }, { name: 'showSizeChanger', title: { label: '页数切换', tip: 'showSizeChanger | 是否展示 pageSize 切换器', }, propType: 'bool', setter: 'BoolSetter', defaultValue: false, }, { name: 'showQuickJumper', title: { label: '快速跳转', tip: 'showQuickJumper | 是否可以快速跳转至某页', }, propType: 'bool', setter: 'BoolSetter', defaultValue: false, }, { name: 'hideOnSinglePage', title: { label: '单页隐藏', tip: 'hideOnSinglePage | 只有一页时是否隐藏分页器', }, propType: 'bool', setter: 'BoolSetter', defaultValue: false, }, { name: 'showLessItems', title: { label: '显示较少页面', tip: 'showLessItems | 是否显示较少页面内容', }, propType: 'bool', setter: 'BoolSetter', defaultValue: false, }, { name: 'pageSizeOptions', title: { label: '可选分页数', tip: 'pageSizeOptions | 指定 pageSize切换器 可选择的每页条数', }, propType: 'object', setter: 'JsonSetter', }, ], }, { title: '外观', display: 'block', type: 'group', items: [ { name: 'simple', title: { label: '简单分页', tip: 'simple | 简单分页' }, propType: 'bool', setter: 'BoolSetter', defaultValue: false, }, { name: 'size', title: { label: '分页尺寸', tip: 'size | 分页尺寸' }, propType: { type: 'oneOf', value: ['default', 'small'], }, setter: [ { componentName: 'RadioGroupSetter', props: { options: [ { title: '默认', value: 'default', }, { title: '小', value: 'small', }, ], }, }, 'VariableSetter', ], defaultValue: 'default', }, { name: 'showTotal', title: { label: '显示总数', tip: 'showTotal | 用于显示数据总量和当前数据顺序', }, propType: 'func', setter: [ { componentName: 'FunctionSetter', props: { template: 'showTotal(total,range,${extParams}){\n// 用于格式化显示表格数据总量\nreturn `共 ${total} 条`;\n}', }, }, 'VariableSetter', ], }, { name: 'showTitle', title: { label: '页码提示', tip: 'showTitle | 是否显示原生 tooltip 页码提示', }, propType: 'bool', setter: 'BoolSetter', defaultValue: false, }, { name: 'responsive', title: { label: '宽度自适应', tip: 'responsive | 当 size 未指定时,根据屏幕宽度自动调整尺寸', }, propType: 'bool', setter: 'BoolSetter', defaultValue: false, }, ], }, ], configure: { supports: { style: true, events: [ { name: 'onChange', template: "onChange(page,pageSize,${extParams}){\n// 页码或 pageSize 改变的回调\nconsole.log('onChange',page,pageSize);}", }, { name: 'onShowSizeChange', template: "onShowSizeChange(current,size,${extParams}){\n// pageSize 变化的回调\nconsole.log('onShowSizeChange',current,size);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/pagination/snippets.ts ================================================ export default [ { title: '分页', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/pagination-1.jpg', schema: { componentName: 'Pagination', props: { pageSize: 10, total: 50, current: 1, }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/popconfirm/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Popconfirm', title: '气泡确认框', category: '反馈', props: [ { name: 'title', title: { label: '确认框内容', tip: '确认框内容' }, propType: { type: 'oneOfType', value: ['string', 'node', 'func'] }, }, { name: 'okText', title: { label: '确认按钮文字', tip: '确认按钮文字' }, propType: 'string', setter: 'StringSetter', supportVariable: true }, { name: 'cancelText', title: { label: '取消按钮文字', tip: '取消按钮文字' }, propType: 'string', setter: 'StringSetter', supportVariable: true }, { name: 'onConfirm', title: { label: '点击确认回调', tip: '点击确认回调' }, propType: 'func', }, // { // name: 'okType', // title: { label: '确认按钮类型', tip: '确认按钮类型' }, // propType: { // type: 'oneOf', // value: ['primary', 'ghost', 'dashed', 'danger', 'link', 'text'], // }, // setter: { // componentName: 'SelectSetter', // props: { // options: [ // { // title: '主按钮', // value: 'primary', // }, // { // title: '虚线框按钮', // value: 'dashed', // }, // { // title: '危险按钮', // value: 'danger', // }, // { // title: '链接按钮', // value: 'link', // }, // { // title: '类文本按钮', // value: 'text', // }, // ], // }, // }, // }, // { // name: 'okButtonProps', // title: { label: 'ok按钮props', tip: 'ok按钮props' }, // propType: 'object', // }, // { // name: 'cancelButtonProps', // title: { label: 'cancel按钮props', tip: 'cancel按钮props' }, // propType: 'object', // }, // { // name: 'onCancel', // title: { label: '点击取消回调', tip: '点击取消回调' }, // propType: 'func', // }, // { // name: 'icon', // title: { label: '自定义Icon图标', tip: '自定义弹出气泡Icon图标' }, // propType: 'node', // }, // { // name: 'disabled', // title: { // label: '是否禁用', // tip: '是否为禁用状态', // }, // propType: 'bool', // defaultValue: false, // }, ], configure: { component: { isContainer: true }, supports: { style: true, events: [ { name: 'onConfirm', template: "onConfirm(${extParams}){\n// 点击确认的回调\nconsole.log('onConfirm');}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/popconfirm/snippets.ts ================================================ export default [ { title: '气泡确认框', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/popconfirm-1.jpg', schema: { componentName: 'Popconfirm', props: { title: '确定删除?', okType: 'primary', okText: '确定', cancelText: '取消', }, children: { componentName: 'Button', props: { children: '删除', }, }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/popover/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Popover', title: '气泡卡片', category: '数据展示', props: [ { title: '内容', display: 'block', type: 'group', items: [ { name: 'title', title: { label: '卡片标题', tip: 'title | 卡片标题', }, propType: { type: 'oneOfType', value: ['string', 'node', 'func'], }, setter: ['StringSetter', 'SlotSetter', 'FunctionSetter', 'VariableSetter'], }, { name: 'content', title: { label: '卡片内容', tip: 'content | 卡片内容', }, propType: { type: 'oneOfType', value: ['string', 'node', 'func'], }, setter: ['StringSetter', 'SlotSetter', 'FunctionSetter', 'VariableSetter'], }, ], }, { title: '控制', display: 'block', type: 'group', items: [ { name: 'defaultOpen', title: { label: '默认显隐', tip: 'defaultOpen | 默认是否显隐', }, propType: 'bool', setter: 'BoolSetter', defaultValue: false, }, { name: 'open', title: { label: '手动显隐', tip: 'open | 手动控制浮层显隐', }, propType: 'bool', setter: 'BoolSetter', }, ], }, { title: '外观', display: 'block', type: 'group', items: [ { name: 'placement', title: { label: '气泡位置', tip: 'placement | 气泡位置', }, propType: { type: 'oneOf', value: [ 'top', 'left', 'right', 'bottom', 'topLeft', 'topRight', 'bottomLeft', 'bottomRight', 'leftTop', 'leftBottom', 'rightTop', 'rightBottom', ], }, defaultValue: 'top', setter: { componentName: 'SelectSetter', props: { options: [ { title: '上', value: 'top', }, { title: '左', value: 'left', }, { title: '右', value: 'right', }, { title: '下', value: 'bottom', }, { title: '上左', value: 'topLeft', }, { title: '上右', value: 'topRight', }, { title: '下左', value: 'bottomLeft', }, { title: '下右', value: 'bottomRight', }, { title: '左上', value: 'leftTop', }, { title: '左下', value: 'leftBottom', }, { title: '右上', value: 'rightTop', }, { title: '右下', value: 'rightBottom', }, ], }, }, }, { name: 'autoAdjustOverflow', title: { label: '自动调整', tip: 'autoAdjustOverflow | 气泡被遮挡时自动调整位置', }, propType: 'bool', setter: 'BoolSetter', defaultValue: true, }, { name: 'arrowPointAtCenter', title: { label: '指向中心', tip: 'arrowPointAtCenter | 箭头是否指向目标元素中心', }, propType: 'bool', setter: 'BoolSetter', defaultValue: false, }, { name: 'color', title: { label: '背景颜色', tip: 'color | 背景颜色', }, propType: 'string', setter: 'ColorSetter', }, { name: 'zIndex', title: { label: 'zIndex', tip: 'zIndex | 设置 Tooltip 的 z-index值', }, propType: 'number', setter: 'NumberSetter', }, ], }, { name: 'overlayStyle', title: '卡片样式', type: 'group', extraProps: { display: 'entry', }, items: [ { name: 'overlayStyle', title: { label: '样式设置', tip: 'overlayStyle | 卡片样式', }, setter: 'StyleSetter', extraProps: { display: 'block', }, }, ], }, { name: 'overlayInnerStyle', title: '卡片内容样式', type: 'group', extraProps: { display: 'entry', }, items: [ { name: 'overlayInnerStyle', title: { label: '样式设置', tip: 'overlayStyle | 卡片内容区域的样式', }, setter: 'StyleSetter', extraProps: { display: 'block', }, }, ], }, { title: '行为', display: 'block', type: 'group', items: [ { name: 'trigger', title: { label: '触发行为', tip: 'trigger | 触发行为', }, propType: { type: 'oneOf', value: ['hover', 'focus', 'click', 'contextMenu'], }, defaultValue: 'hover', setter: { componentName: 'SelectSetter', props: { options: [ { title: '鼠标悬停', value: 'hover', }, { title: '获得焦点', value: 'focus', }, { title: '鼠标点击', value: 'click', }, { title: '右键菜单', value: 'contextMenu', }, ], }, }, }, { name: 'mouseEnterDelay', title: { label: '展示延时', tip: 'mouseEnterDelay | 鼠标移入后延时多少才显示 Tooltip,单位:秒', }, propType: 'number', defaultValue: 0.1, setter: { componentName: 'NumberSetter', props: { step: 0.1, }, }, }, { name: 'mouseLeaveDelay', title: { label: '隐藏延时', tip: 'mouseLeaveDelay | 鼠标移出后延时多少才隐藏 Tooltip,单位:秒', }, propType: 'number', defaultValue: 0.1, setter: { componentName: 'NumberSetter', props: { step: 0.1, }, }, }, ], }, ], configure: { component: { isContainer: true, }, supports: { style: true, events: [ { name: 'onOpenChange', template: "onOpenChange(open,${extParams}){\n// 显示隐藏的回调\nconsole.log('onOpenChange',open);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/popover/snippets.ts ================================================ export default [ { title: '气泡卡片', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/popover-1.jpg', schema: { componentName: 'Popover', props: {}, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/progress/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Progress', title: '进度条', category: '反馈', props: [ { name: 'type', title: { label: '类型', tip: '类型' }, propType: { type: 'oneOf', value: ['line', 'circle', 'dashboard'] }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '线型', value: 'line' }, { title: '圆型', value: 'circle' }, { title: '仪表盘', value: 'dashboard' }, ], }, }, defaultValue: 'line', }, { name: 'format', title: { label: '内容格式', tip: '内容格式' }, propType: 'func', }, { name: 'percent', title: { label: '百分比', tip: '百分比' }, propType: 'number', }, { name: 'showInfo', title: { label: '显示数值或图标', tip: '显示数值或图标' }, propType: 'bool', defaultValue: true, }, { name: 'status', title: { label: '状态', tip: '状态' }, propType: { type: 'oneOf', value: ['success', 'exception', 'normal', 'active'], }, }, { name: 'steps', title: { label: '总步数', tip: '进度条总共步数' }, condition(target) { // 仅线型有效 return target.getProps().getPropValue('type') === 'line'; }, propType: 'number', }, { name: 'strokeLinecap', title: { label: '进度条的样式', tip: '进度条的样式' }, propType: { type: 'oneOf', value: ['round', 'square'], }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '圆角', value: 'round' }, { title: '方角', value: 'square' }, ], }, }, defaultValue: 'round', }, { name: 'strokeWidth', title: { label: '线宽度', tip: '线宽度' }, propType: 'number', }, { name: 'strokeColor', title: { label: '进度条的颜色', tip: '进度条的颜色' }, propType: 'string', condition(target) { // 仪表盘样式无效 return target.getProps().getPropValue('type') !== 'dashboard'; }, setter: 'ColorSetter', }, { name: 'trailColor', title: { label: '未完成的分段的颜色', tip: '未完成的分段的颜色', }, propType: 'string', setter: 'ColorSetter', }, { name: 'gapDegree', title: { label: '缺口角度', tip: '仪表盘进度条缺口角度,可取值 0 ~ 295', }, condition(target) { // 仅仪表盘样式有效 return target.getProps().getPropValue('type') === 'dashboard'; }, propType: 'number', defaultValue: 75, }, { name: 'gapPosition', title: { label: '缺口位置', tip: '仪表盘进度条缺口位置', }, condition(target) { // 仅仪表盘样式有效 return target.getProps().getPropValue('type') === 'dashboard'; }, propType: { type: 'oneOf', value: ['top', 'bottom', 'left', 'right'], }, defaultValue: 'bottom', }, ], configure: { supports: { style: true } }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/progress/snippets.ts ================================================ export default [ { title: '进度条', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/progress-1.png', schema: { componentName: 'Progress', props: { percent: 20, status: 'active', }, }, }, { title: '进度圈', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/progress-2.png', schema: { componentName: 'Progress', props: { percent: 20, type: 'circle', }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/radio/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Radio', title: '单选框', category: '表单', props: [ { name: 'children', title: { label: '内容', tip: '内容' }, propType: 'string', setter: 'StringSetter', supportVariable: true }, { name: 'autoFocus', title: { label: '自动聚焦', tip: '自动获取焦点' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', supportVariable: true }, { name: 'defaultChecked', title: { label: '默认选中', tip: '初始是否选中' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', supportVariable: true }, { name: 'checked', title: { label: '是否选中', tip: '指定当前是否选中' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', supportVariable: true }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', supportVariable: true }, // { // name: 'value', // title: { // label: '根据值判断', // tip: '根据 value 进行比较,判断是否选中', // }, // propType: 'string', // }, ], configure: { supports: { style: true } }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/radio/snippets.ts ================================================ export default [ { title: '单选框', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/radio-1.png', schema: { componentName: 'Radio', props: { children: 'Radio', }, }, }, { title: '单选框组', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/radio-group-1.png', schema: { componentName: 'Radio.Group', props: { options: [ { label: 'A', value: 'A', }, { label: 'B', value: 'B', }, { label: 'C', value: 'C', }, ], }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/radio.group/meta.ts ================================================ import { uuid } from '../_utils/utils'; export default { componentName: 'Radio.Group', title: '单选框组', category: '表单', props: [ { name: 'defaultValue', title: { label: '默认值', tip: '默认选中值' }, propType: 'string', setter: 'StringSetter', supportVariable: true }, { name: 'value', title: { label: '当前值', tip: '指定选中的选项' }, propType: 'string', setter: 'StringSetter', supportVariable: true }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', supportVariable: true }, { name: 'name', title: { label: 'name 属性', tip: 'RadioGroup 下所有 input[type="radio"] 的 name 属性', }, propType: 'string', setter: 'StringSetter', supportVariable: true }, { name: 'options', title: { label: '指定可选项', tip: '指定可选项' }, propType: { type: 'arrayOf', value: { type: 'shape', value: [ { name: 'label', propType: 'string', description: '选项名', defaultValue: '选项名', }, { name: 'value', propType: 'string', description: '选项值', defaultValue: '选项值', }, { name: 'disabled', propType: 'bool', description: '是否禁用', defaultValue: false, }, ], }, }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'label', title: '选项名', setter: 'StringSetter', isRequired: true }, { name: 'value', title: '选项值', setter: 'StringSetter', isRequired: true }, { name: 'disabled', title: '是否禁用', setter: 'BoolSetter', }, ], }, }, initialValue: () => { return { label: '选项名', value: uuid(), disabled: false, }; }, }, }, }, }, { name: 'optionType', title: { label: '类型', tip: '类型' }, propType: { type: 'oneOf', value: ['default', 'button'] }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '默认类型', value: 'default', }, { title: '按钮类型', value: 'button', }, ], }, }, defaultValue: 'default', }, { name: 'size', title: { label: '尺寸', tip: '大小,只对按钮样式生效' }, condition(target) { return target.getProps().getPropValue('optionType') === 'button'; }, propType: { type: 'oneOf', value: ['large', 'middle', 'small'] }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '大', value: 'large', }, { title: '中', value: 'middle', }, { title: '小', value: 'small', }, ], }, }, defaultValue: 'middle', }, { name: 'buttonStyle', title: { label: '按钮风格', tip: 'RadioButton 的风格样式,目前有描边和填色两种风格', }, condition(target) { return target.getProps().getPropValue('optionType') === 'button'; }, propType: { type: 'oneOf', value: ['outline', 'solid'] }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '描边', value: 'outline', }, { title: '填色', value: 'solid', }, ], }, }, defaultValue: 'outline', }, { name: 'onChange', title: { label: '变化时回调函数', tip: '变化时回调函数' }, propType: 'func', }, ], configure: { supports: { style: true, events: [ { name: 'onChange', template: "onChange(event,${extParams}){\n// 选项变化时的回调函数\nconsole.log('onChange',event);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/rate/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Rate', title: '评分', category: '表单', props: [ { name: 'defaultValue', title: { label: '默认值', tip: '默认值' }, propType: 'number', setter: 'NumberSetter' }, { name: 'allowClear', title: { label: '支持清除', tip: '是否允许清除' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter' }, { name: 'allowHalf', title: { label: '支持半选', tip: '支持半选' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'autoFocus', title: { label: '自动聚焦', tip: '自动获取焦点' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'character', title: { label: '符号', tip: '自定义字符' }, propType: 'node', }, { name: 'count', title: { label: '总数', tip: 'star 总数' }, propType: 'number', defaultValue: 5, setter: 'NumberSetter' }, // { // name: 'value', // title: { label: '当前值', tip: '当前数' }, // propType: 'number', // }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'tooltips', title: { label: '提示信息', tip: '自定义每项的提示信息' }, propType: { type: 'arrayOf', value: 'string' }, }, { name: 'onBlur', title: { label: '失去焦点时的回调', tip: '失去焦点时的回调' }, propType: 'func', }, { name: 'onChange', title: { label: '选择时的回调', tip: '选择时的回调' }, propType: 'func', }, { name: 'onFocus', title: { label: '获取焦点时的回调', tip: '获取焦点时的回调' }, propType: 'func', }, { name: 'onHoverChange', title: { label: '鼠标经过时回调', tip: '鼠标经过时数值变化的回调' }, propType: 'func', }, { name: 'onKeyDown', title: { label: '按键回调', tip: '按键回调' }, propType: 'func', }, ], configure: { supports: { style: true, events: [ { name: 'onBlur', template: "onBlur(${extParams}){\n// 失去焦点时的回调\nconsole.log('onBlur');}", }, { name: 'onChange', template: "onChange(value,${extParams}){\n// 选择时的回调\nconsole.log('onChange',value);}", }, { name: 'onFocus', template: "onFocus(${extParams}){\n// 获取焦点时的回调\nconsole.log('onFocus');}", }, { name: 'onHoverChange', template: "onHoverChange(value,${extParams}){\n// 鼠标经过时数值变化的回调\nconsole.log('onHoverChange',value);}", }, { name: 'onKeyDown', template: "onKeyDown(event,${extParams}){\n// 按键回调\nconsole.log('onKeyDown',event);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/rate/snippets.ts ================================================ export default [ { title: '评分', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/rate-1.png', schema: { componentName: 'Rate', props: { defaultValue: 3, }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/result/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Result', title: '结果', category: '反馈', props: [ { name: 'title', title: { label: '标题', tip: 'title 文字' }, propType: 'node', }, { name: 'subTitle', title: { label: '副标题', tip: 'subTitle 文字' }, propType: 'node', }, { name: 'status', title: { label: '状态', tip: '结果的状态,决定图标和颜色', }, propType: { type: 'oneOf', value: ['success', 'error', 'info', 'warning', '404', '403', '500'], }, }, { name: 'icon', title: { label: '自定义 icon', tip: '自定义 icon' }, propType: 'node', }, { name: 'extra', title: { label: '操作区', tip: '操作区' }, propType: 'node', }, ], configure: { supports: { style: true } }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/result/snippets.ts ================================================ export default [ { title: '结果', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/result-1.png', schema: { componentName: 'Result', props: { status: 'success', title: 'Success!', subTitle: 'Order number: 123', }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/segmented/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Segmented', title: '分段控制器', category: '数据展示', group: '基础组件', props: [ { name: 'block', title: { label: 'block ', tip: '将宽度调整为父元素宽度的选项 ' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', }, { name: 'defaultValue', title: { label: '默认值', tip: '默认的选中项' }, setter: ['StringSetter', 'NumberSetter'], }, { name: 'disabled', title: { label: '禁用', tip: '是否禁用' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', }, { name: 'options', title: { label: '配置内容', tip: '数据化配置选项内容' }, setter: ['JsonSetter', 'VariableSetter'], }, { name: 'size', title: { label: '控件尺寸', tip: '控件尺寸' }, propType: { type: 'oneOf', value: ['large', 'middle', 'small'] }, setter: { componentName: 'SelectSetter', props: { options: [ { title: '大', value: 'large', }, { title: '中', value: 'middle', }, { title: '小', value: 'small', }, ], }, }, defaultValue: 'middle', }, // { // name: 'value', // title: { label: '选中项', tip: '当前选中项' }, // propType: { // type: 'arrayOf', // value: { type: 'oneOfType', value: ['string', 'number'] }, // }, // }, ], configure: { supports: { style: true, events: [ { name: 'onChange', template: "onChange(value,selectedOptions,${extParams}){\n// 选择完成后的回调\nconsole.log('onChange', value, selectedOptions);}", } ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/segmented/snippets.ts ================================================ export default [ { title: '分段控制器', screenshot: require('./__screenshots__/segmented.png'), schema: { componentName: 'Segmented', props: { options: ['Daily', 'Weekly', 'Monthly'], // value: 'Daily', defaultValue: 'Daily', }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/select/meta.ts ================================================ import { uuid } from '../_utils/utils'; import snippets from './snippets'; export default { snippets, componentName: 'Select', title: '选择器', category: '表单', props: [ { name: 'defaultValue', title: { label: '默认值', tip: '默认选中值' }, propType: { type: 'oneOfType', value: [ 'string', { type: 'arrayOf', value: 'string' }, 'number', { type: 'arrayOf', value: 'number' }, ], }, }, { name: 'value', title: { label: '当前值', tip: '当前值' }, propType: { type: 'oneOfType', value: [ 'string', { type: 'arrayOf', value: 'string' }, 'number', { type: 'arrayOf', value: 'number' }, ], }, }, { name: 'options', title: { label: '可选项', tip: '可选项' }, propType: { type: 'arrayOf', value: { type: 'shape', value: [ { name: 'label', propType: 'string', description: '选项名', defaultValue: '选项名', }, { name: 'value', propType: ['string', 'number'], description: '选项值', defaultValue: '选项值', }, { name: 'disabled', propType: 'bool', description: '是否禁用', defaultValue: false, }, ], }, }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'label', title: '选项名', setter: ['StringSetter', 'VariableSetter'], isRequired: true }, { name: 'value', title: '选项值', setter: ['StringSetter', 'NumberSetter', 'VariableSetter'], isRequired: true }, { name: 'disabled', title: '是否禁用', setter: ['BoolSetter', 'VariableSetter'], }, ], }, }, initialValue: () => { return { label: '选项名', value: uuid(), disabled: false, }; }, }, }, }, }, { name: 'allowClear', title: { label: '支持清除', tip: '是否允许清除' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'autoFocus', title: { label: '自动聚焦', tip: '默认获取焦点' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'defaultActiveFirstOption', title: { label: '高亮首个选项', tip: '是否默认高亮第一个选项' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter' }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'labelInValue', title: { label: '值包含label', tip: '把每个选项的 label 包装到 value 中', }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'mode', title: { label: '多选/单选', tip: '多选/单选' }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '单选', value: 'single', }, { title: '多选', value: 'multiple', }, { title: '任意内容', value: 'tags', }, ], }, }, propType: { type: 'oneOf', value: ['single', 'multiple', 'tags'] }, }, { name: 'maxTagCount', title: { label: '最大tag数', tip: '最多显示多少个tag' }, condition(target) { return target.getProps().getPropValue('mode') === 'tags'; }, propType: 'number', }, { name: 'maxTagTextLength', title: { label: 'tag文本长度', tip: '最大显示的tag文本长度' }, condition(target) { return target.getProps().getPropValue('mode') === 'tags'; }, propType: 'number', }, { name: 'notFoundContent', title: { label: '搜索为空提示文案', tip: '搜索为空提示文案' }, propType: 'string', setter: 'StringSetter' }, { name: 'placeholder', title: { label: '选择框默认文字', tip: '选择框默认文字' }, propType: 'string', setter: 'StringSetter' }, { name: 'showArrow', title: { label: '是否显示下拉箭头', tip: '是否显示下拉小箭头' }, propType: 'bool', setter: 'BoolSetter' }, { name: 'showSearch', title: { label: '是否可搜索', tip: '是否可搜索' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'size', title: { label: '尺寸', tip: '选择框大小' }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '大', value: 'large', }, { title: '中', value: 'middle', }, { title: '小', value: 'small', }, ], }, }, propType: { type: 'oneOf', value: ['large', 'middle', 'small'] }, defaultValue: 'middle', }, { name: 'loading', title: { label: '加载中', tip: '加载中状态' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'bordered', title: { label: '显示边框', tip: '是否有边框' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter' }, { name: 'filterOption', title: { label: '筛选可选项', tip: '是否根据输入进行筛选' }, propType: { type: 'oneOfType', value: ['bool', 'func'], }, defaultValue: true, }, { name: 'optionFilterProp', title: { label: '用于筛选的字段', tip: '用于过滤的字段' }, propType: { type: 'oneOf', value: ['value', 'label'], }, defaultValue: 'value', }, // { // name: 'suffixIcon', // title: { label: '自后缀图标', tip: '自定义的选择框后缀图标' }, // propType: 'node', // }, // { // name: 'removeIcon', // title: { label: '清除图标', tip: '自定义的多选框清除图标' }, // propType: 'node', // }, // { // name: 'clearIcon', // title: { label: '自定义的多选框清空图标', tip: '自定义的多选框清空图标' }, // propType: 'node', // }, // { // name: 'menuItemSelectedIcon', // title: { // label: '自定义多选时当前选中的条目图标', // tip: '自定义多选时当前选中的条目图标', // }, // propType: 'node', // }, { name: 'tokenSeparators', title: { label: '自动分词的分隔符', tip: '自动分词的分隔符' }, propType: { type: 'arrayOf', value: 'string' }, }, { name: 'onBlur', title: { label: '失去焦点时回调', tip: '失去焦点时回调' }, propType: 'func', }, { name: 'onChange', title: { label: '选中回调函数', tip: '选中 option,或 input 的 value 变化时,调用此函数', }, propType: 'func', }, { name: 'onDeselect', title: { label: '取消选中时回调', tip: '取消选中时调用,参数为选中项的 value (或 key) 值,仅在 multiple 或 tags 模式下生效', }, propType: 'func', }, { name: 'onFocus', title: { label: '获得焦点时回调', tip: '获得焦点时回调' }, propType: 'func', }, { name: 'onInputKeyDown', title: { label: '按键按下时回调', tip: '按键按下时回调' }, propType: 'func', }, { name: 'onMouseEnter', title: { label: '鼠标移入时回调', tip: '鼠标移入时回调' }, propType: 'func', }, { name: 'onMouseLeave', title: { label: '鼠标移出时回调', tip: '鼠标移出时回调' }, propType: 'func', }, { name: 'onPopupScroll', title: { label: '下拉列表滚动时的回调', tip: '下拉列表滚动时的回调' }, propType: 'func', }, { name: 'onSearch', title: { label: '文本框值变化时回调', tip: '文本框值变化时回调' }, propType: 'func', }, { name: 'onSelect', title: { label: '被选中时回调', tip: '被选中时调用,参数为选中项的 value (或 key) 值', }, propType: 'func', }, { name: 'onDropdownVisibleChange', title: { label: '展开下拉菜单的回调', tip: '展开下拉菜单的回调' }, propType: 'func', }, ], configure: { supports: { style: true, events: [ { name: 'onBlur', template: "onBlur(${extParams}){\n// 失去焦点时回调\nconsole.log('onBlur');}", }, { name: 'onChange', template: "onChange(value,option,${extParams}){\n// 选中 option,或 input 的 value 变化时,调用此函数\nconsole.log('onChange',value,option);}", }, { name: 'onDeselect', template: "onDeselect(value,${extParams}){\n// 取消选中时调用\nconsole.log('onDeselect',value);}", }, { name: 'onFocus', template: "onFocus(${extParams}){\n// 获得焦点时回调\nconsole.log('onFocus');}", }, { name: 'onInputKeyDown', template: "onInputKeyDown(${extParams}){\n// 按键按下时回调\nconsole.log('onInputKeyDown');}", }, { name: 'onMouseEnter', template: "onMouseEnter(${extParams}){\n// 鼠标移入时回调\nconsole.log('onMouseEnter');}", }, { name: 'onMouseLeave', template: "onMouseLeave(${extParams}){\n// 鼠标移出时回调\nconsole.log('onMouseLeave');}", }, { name: 'onPopupScroll', template: "onPopupScroll(${extParams}){\n// 下拉列表滚动时的回调\nconsole.log('onPopupScroll');}", }, { name: 'onSearch', template: "onSearch(value,${extParams}){\n// 文本框值变化时回调\nconsole.log('onSearch',value);}", }, { name: 'onSelect', template: "onSelect(value,option,${extParams}){\n// 被选中时调用\nconsole.log('onSelect',value,option);}", }, { name: 'onDropdownVisibleChange', template: "onDropdownVisibleChange(open,${extParams}){\n// 展开下拉菜单的回调\nconsole.log('onDropdownVisibleChange',open);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/select/snippets.ts ================================================ export default [ { title: '选择器', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/select-1.png', schema: { componentName: 'Select', props: { style: { width: 200, }, options: [ { label: 'A', value: 'A', }, { label: 'B', value: 'B', }, { label: 'C', value: 'C', }, ], }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/skeleton/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Skeleton', title: '骨架屏', category: '反馈', props: [ { name: 'active', title: { label: '动画效果', tip: '是否展示动画效果' }, propType: 'bool', defaultValue: false, }, { name: 'avatar', title: { label: '头像占位图', tip: '是否显示头像占位图' }, propType: { type: 'oneOfType', value: ['bool', 'object'] }, }, { name: 'loading', title: { label: '加载中', tip: '为 true 时,显示占位图。反之则直接展示子组件', }, propType: 'bool', }, { name: 'paragraph', title: { label: '段落占位图', tip: '是否显示段落占位图' }, propType: { type: 'oneOfType', value: ['bool', 'object'] }, }, { name: 'title', title: { label: '标题占位图', tip: '是否显示标题占位图' }, propType: { type: 'oneOfType', value: ['bool', 'object'] }, }, { name: 'round', title: { label: '圆角', tip: '为 true 时,段落和标题显示圆角', }, propType: 'bool', defaultValue: false, }, ], configure: { component: { isContainer: true }, supports: { style: true } }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/skeleton/snippets.ts ================================================ export default [ { title: '骨架屏', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/skeleton-1.png', schema: { componentName: 'Skeleton', props: { active: true, loading: true }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/slider/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Slider', title: '滑动输入条', category: '表单', props: [ { name: 'defaultValue', title: { label: '默认值', tip: '设置初始取值。当 `range` 为 false 时,使用 number,否则用 \\[number, number]', }, propType: { type: 'oneOfType', value: ['number', { type: 'arrayOf', value: 'number' }], }, }, { name: 'range', title: { label: '双滑块模式', tip: '双滑块模式' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', setValue(target, range) { let defaultValue = target.node.getPropValue('defaultValue'); if (range) { defaultValue = Array.isArray(defaultValue) ? defaultValue : [0, defaultValue]; } else { defaultValue = Array.isArray(defaultValue) ? defaultValue[1] || defaultValue[0] : defaultValue; } target.node.setPropValue('defaultValue', defaultValue); }, }, // { // name: 'value', // title: { // label: '当前值', // tip: // '设置当前取值。当 `range` 为 false 时,使用 number,否则用 \\[number, number]', // }, // propType: { // type: 'oneOfType', // value: ['number', { type: 'arrayOf', value: 'number' }], // }, // }, { name: 'allowClear', title: { label: '支持清除', tip: '是否允许清除' }, condition(target) { return target.getProps().getPropValue('range') === true; }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态', }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'dots', title: { label: '对齐刻度', tip: '是否只能拖拽到刻度上' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, // { // name: 'included', // title: { // label: // '`marks` 不为空对象时有效,值为 true 时表示值为包含关系,false 表示并列', // tip: // '`marks` 不为空对象时有效,值为 true 时表示值为包含关系,false 表示并列', // }, // propType: 'bool', // defaultValue: true, // }, // { // name: 'marks', // title: { // label: // '刻度标记,key 的类型必须为 `number` 且取值在闭区间 \\[min, max] 内,每个标签可以单独设置样式', // tip: // '刻度标记,key 的类型必须为 `number` 且取值在闭区间 \\[min, max] 内,每个标签可以单独设置样式', // }, // propType: 'object', // }, { name: 'max', title: { label: '最大值', tip: '最大值' }, propType: 'number', setter: 'NumberSetter' }, { name: 'min', title: { label: '最小值', tip: '最小值' }, propType: 'number', setter: 'NumberSetter' }, { name: 'reverse', title: { label: '反向坐标轴', tip: '反向坐标轴' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'step', title: { label: '步长', tip: '步长,取值必须大于 0,并且可被 (max - min) 整除。当 `marks` 不为空对象时,可以设置 `step` 为 null,此时 Slider 的可选值仅有 marks 标出来的部分', }, propType: 'number', setter: 'NumberSetter' }, // { // name: 'tipFormatter', // title: { // label: // 'Slider 会把当前值传给 `tipFormatter`,并在 Tooltip 中显示 `tipFormatter` 的返回值,若为 null,则隐藏 Tooltip', // tip: // 'Slider 会把当前值传给 `tipFormatter`,并在 Tooltip 中显示 `tipFormatter` 的返回值,若为 null,则隐藏 Tooltip', // }, // propType: 'func', // }, { name: 'vertical', title: { label: '垂直方向', tip: '值为 true 时,Slider 为垂直方向', }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'onAfterChange', title: { label: '与 `onmouseup` 触发时机一致,把当前值作为参数传入', tip: '与 `onmouseup` 触发时机一致,把当前值作为参数传入', }, propType: 'func', }, { name: 'onChange', title: { label: '当 Slider 的值发生改变时,会触发 onChange 事件,并把改变后的值作为参数传入', tip: '当 Slider 的值发生改变时,会触发 onChange 事件,并把改变后的值作为参数传入', }, propType: 'func', }, // { // name: 'tooltipPlacement', // title: { // label: '设置 Tooltip 展示位置。参考 [Tooltip](/components/tooltip/)', // tip: '设置 Tooltip 展示位置。参考 [Tooltip](/components/tooltip/)', // }, // propType: 'string', // }, // { // name: 'tooltipVisible', // title: { // label: // '值为 true 时,Tooltip 将会始终显示;否则始终不显示,哪怕在拖拽及移入时', // tip: // '值为 true 时,Tooltip 将会始终显示;否则始终不显示,哪怕在拖拽及移入时', // }, // propType: 'bool', // }, // { // name: 'getTooltipPopupContainer', // title: { // label: 'Tooltip 渲染父节点,默认渲染到 body 上', // tip: 'Tooltip 渲染父节点,默认渲染到 body 上', // }, // propType: 'func', // }, ], configure: { supports: { style: true, events: [ { name: 'onAfterChange', template: "onAfterChange(value,${extParams}){\n// 与 onmouseup 触发时机一致\nconsole.log('onAfterChange',value);}", }, { name: 'onChange', template: "onChange(value,${extParams}){\n// 当 Slider 的值发生改变时触发回调\nconsole.log('onChange',value);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/slider/snippets.ts ================================================ export default [ { title: '滑动输入条', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/slider-1.png', schema: { componentName: 'Slider', props: { defaultValue: 30, }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/slot/meta.ts ================================================ module.exports = { componentName: 'Slot', npm: { package: '@alilc/antd-lowcode-materials', version: 'latest', exportName: 'Slot', main: '', destructuring: true, subName: '', }, configure: { props: [ { name: '___title', title: { type: 'i18n', 'en-US': 'Slot Title', 'zh-CN': '插槽标题', }, setter: 'StringSetter', defaultValue: '插槽容器', }, { name: '___params', title: { type: 'i18n', 'en-US': 'Slot Params', 'zh-CN': '插槽入参', }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'StringSetter', props: { placeholder: { type: 'i18n', 'zh-CN': '参数名称', 'en-US': 'Argument Name', }, }, }, }, }, }, ], component: { isContainer: true, disableBehaviors: '*', }, // events/className/style/general/directives supports: false, advanced: { callbacks: { onHoverHook: () => false, onMouseDownHook: () => false, onClickHook: () => false, }, }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/slot/view.tsx ================================================ import { Component } from 'react'; class Slot extends Component { static displayName = 'Slot'; static componentMetadata = { componentName: 'Slot', configure: { props: [ { name: '___title', title: { type: 'i18n', 'en-US': 'Slot Title', 'zh-CN': '插槽标题', }, setter: 'StringSetter', defaultValue: '插槽容器', }, { name: '___params', title: { type: 'i18n', 'en-US': 'Slot Params', 'zh-CN': '插槽入参', }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'StringSetter', props: { placeholder: { type: 'i18n', 'zh-CN': '参数名称', 'en-US': 'Argument Name', }, }, }, }, }, }, ], component: { isContainer: true, }, // events/className/style/general/directives supports: false, }, }; render() { const { children } = this.props; return <>{children}; } } export default Slot; ================================================ FILE: packages/antd-lowcode-materials/lowcode/space/meta.ts ================================================ import { ComponentMetadata } from "@alilc/lowcode-types"; import snippets from './snippets'; export default { snippets, componentName: 'Space', title: '间距', category: '布局', props: [ { name: 'align', title: { label: '对齐方式', tip: '对齐方式' }, propType: { type: 'oneOf', value: ['start', 'end', 'center', 'baseline'], }, }, { name: 'direction', title: { label: '间距方向', tip: '间距方向' }, propType: { type: 'oneOf', value: ['vertical', 'horizontal'] }, }, { name: 'size', title: { label: '间距大小', tip: '间距大小' }, propType: { type: 'oneOfType', value: [ { type: 'oneOf', value: ['small', 'middle', 'large'], }, 'number', ], }, defaultValue: 'middle', }, { name: 'wrap', title: { label: '是否自动换行', tip: '是否自动换行' }, propType: "bool", condition: { type: 'JSFunction', value: 'target => target.getProps().getPropValue("direction")==="horizontal"', }, }, { name: 'split', title: { label: '间隔组件', tip: '间隔组件,可拖组件进来, 常用的有竖向分隔线' }, propType: "node", }, ], configure: { component: { isContainer: true }, supports: { style: true } }, } as ComponentMetadata | any; ================================================ FILE: packages/antd-lowcode-materials/lowcode/space/snippets.ts ================================================ export default [ { title: '间距', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/space-1.png', schema: { componentName: 'Space', props: {}, children: [ { componentName: 'Button', props: { children: 'Button-1', }, }, { componentName: 'Button', props: { children: 'Button-2', }, }, ], }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/spin/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Spin', title: '加载中', category: '反馈', props: [ { name: 'delay', title: { label: '延迟显示', tip: '延迟显示加载效果的时间(防止闪烁)' }, propType: 'number', }, { name: 'indicator', title: { label: '加载指示符', tip: '加载指示符' }, propType: 'node', }, { name: 'size', title: { label: '尺寸', tip: '组件大小', }, propType: { type: 'oneOf', value: ['small', 'default', 'large'] }, defaultValue: 'default', }, { name: 'spinning', title: { label: '加载状态', tip: '是否为加载中状态' }, propType: 'bool', defaultValue: true, }, { name: 'tip', title: { label: '描述文案', tip: '当作为包裹元素时,可以自定义描述文案' }, propType: 'string', }, { name: 'wrapperClassName', title: { label: '包装器的类属性', tip: '包装器的类属性' }, propType: 'string', }, ], configure: { component: { isContainer: true }, supports: { style: true }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/spin/snippets.ts ================================================ export default [ { title: '加载中', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/spin-1.png', schema: { componentName: 'Spin', props: { size: 'large', tip: 'loading...', }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/statistic/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Statistic', title: '统计数值', category: '数据展示', props: [ { name: 'decimalSeparator', title: { label: '设置小数点', tip: '设置小数点' }, propType: 'string', }, { name: 'formatter', title: { label: '自定义数值展示', tip: '自定义数值展示' }, propType: 'func', }, { name: 'groupSeparator', title: { label: '设置千分位标识符', tip: '设置千分位标识符' }, propType: 'string', }, { name: 'precision', title: { label: '数值精度', tip: '数值精度' }, propType: 'number', }, { name: 'prefix', title: { label: '设置数值的前缀', tip: '设置数值的前缀' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'suffix', title: { label: '设置数值的后缀', tip: '设置数值的后缀' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'title', title: { label: '数值的标题', tip: '数值的标题' }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'value', title: { label: '数值内容', tip: '数值内容' }, propType: { type: 'oneOfType', value: ['string', 'number'] }, }, { name: 'valueStyle', title: { label: '设置数值的样式', tip: '设置数值的样式' }, propType: 'object', }, ], configure: { supports: { style: true } }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/statistic/snippets.ts ================================================ export default [ { title: '统计数值', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/statistic-1.png', schema: { componentName: 'Statistic', props: { title: 'Active Users', value: 16589, }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/steps/meta.ts ================================================ import { uuid } from '../_utils/utils'; import snippets from './snippets'; export default { snippets, componentName: 'Steps', title: '步骤条', category: '导航', props: [ { name: 'steps', title: '步骤配置', setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'key', title: 'key', setter: 'StringSetter', initialValue: (val) => val || uuid(), }, { name: 'title', title: '标题', setter: 'StringSetter', }, { name: 'subTitle', title: '子标题', setter: 'StringSetter', }, { name: 'description', title: '详细描述', setter: 'StringSetter', }, { name: 'disabled', title: '禁用', setter: 'BoolSetter', initialValue: false, }, { name: 'status', title: { label: '状态', tip: '选择框大小' }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: 'wait', value: 'wait', }, { title: 'process', value: 'process', }, { title: 'finish', value: 'finish', }, { title: 'error', value: 'error', }, ], }, }, propType: { type: 'oneOf', value: ['wait', 'process', 'finish', 'error'], }, defaultValue: 'wait', }, ], }, }, initialValue: () => { return { key: `Steps${uuid()}`, title: '步骤', disabled: false, }; }, }, }, }, extraProps: { getValue(target, fieldValue) { const map = target.node.children.map((child) => { const key = child.getPropValue('key') ? String(child.getPropValue('key')) : child.id; return { key, title: child.getPropValue('title'), subTitle: child.getPropValue('subTitle'), description: child.getPropValue('description'), disabled: child.getPropValue('disabled'), status: child.getPropValue('status'), }; }); return map; }, setValue(target, value) { const { node } = target; const map = {}; if (!Array.isArray(value)) { value = []; } value.forEach((item) => { const tabItem = Object.assign({}, item); map[item.key] = tabItem; }); node.children.mergeChildren( (child) => { const key = String(child.getPropValue('key')); if (Object.hasOwnProperty.call(map, key)) { child.setPropValue('title', map[key].title); child.setPropValue('subTitle', map[key].subTitle); child.setPropValue('description', map[key].description); child.setPropValue('disabled', map[key].disabled); child.setPropValue('status', map[key].status); delete map[key]; return false; } return true; }, () => { const items = []; for (const key in map) { if (Object.hasOwnProperty.call(map, key)) { items.push({ componentName: 'Steps.Step', props: map[key], }); } } return items; }, (child1, child2) => { const a = value.findIndex( (item) => String(item.key) === String(child1.getPropValue('key')), ); const b = value.findIndex( (item) => String(item.key) === String(child2.getPropValue('key')), ); return a - b; }, ); }, }, }, { name: 'className', title: { label: '步骤条类名', tip: '步骤条类名' }, propType: 'string', }, { name: 'type', title: { label: '类型', tip: '步骤条类型,有 `default` 和 `navigation` 两种', }, propType: { type: 'oneOf', value: ['default', 'navigation'] }, defaultValue: 'default', }, { name: 'current', title: { label: '当前步骤', tip: '指定当前步骤,从 0 开始记数。在子 Step 元素中,可以通过 `status` 属性覆盖状态', }, propType: 'number', }, { name: 'direction', title: { label: '步骤条方向', tip: '指定步骤条方向。目前支持水平(`horizontal`)和竖直(`vertical`)两种方向', }, propType: { type: 'oneOf', value: ['horizontal', 'vertical'], }, }, { name: 'labelPlacement', title: { label: '标签放置位置', tip: '指定标签放置位置,默认水平放图标右侧,可选 `vertical` 放图标下方', }, propType: { type: 'oneOf', value: ['horizontal', 'vertical'], }, defaultValue: 'horizontal', }, { name: 'progressDot', title: { label: '点状步骤条', tip: '点状步骤条,可以设置为一个 func', }, propType: { type: 'oneOfType', value: ['bool', 'func'] }, }, { name: 'size', title: { label: '尺寸', tip: '指定大小', }, propType: { type: 'oneOf', value: ['default', 'small'], }, defaultValue: 'default', }, { name: 'status', title: { label: '当前步骤状态', tip: '指定当前步骤的状态,可选 `wait` `process` `finish` `error`', }, propType: { type: 'oneOf', value: ['wait', 'process', 'finish', 'error'], }, defaultValue: 'process', }, { name: 'initial', title: { label: '起始序号', tip: '起始序号,从 0 开始记数', }, propType: 'number', defaultValue: 0, }, { name: 'onChange', title: { label: '点击切换步骤时触发', tip: '点击切换步骤时触发' }, propType: 'func', }, ], configure: { component: { isContainer: true, nestingRule: { childWhitelist: ['Steps.Step'] }, }, supports: { style: true, events: [ { name: 'onChange', template: "onChange(current,${extParams}){\n// 点击切换步骤时触发\nconsole.log('onChange',current);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/steps/snippets.ts ================================================ export default [ { title: '步骤条', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/steps-1.png', schema: { componentName: 'Steps', props: { current: 1, }, children: [ { componentName: 'Steps.Step', props: { title: 'Finished', description: 'This is a description.', }, }, { componentName: 'Steps.Step', props: { title: 'In Progress', subTitle: 'Left 00:00:08', description: 'This is a description.', }, }, { componentName: 'Steps.Step', props: { title: 'Waiting', description: 'This is a description.', }, }, ], }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/steps.step/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Steps.Step', title: '步骤项', props: [ { name: 'title', title: { label: '标题', tip: '标题' }, propType: 'string', }, { name: 'subTitle', title: { label: '子标题', tip: '子标题' }, propType: 'string', }, { name: 'description', title: { label: '步骤描述', tip: '步骤描述' }, propType: 'string', }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态' }, propType: 'bool', }, { name: 'icon', title: { label: '图标', tip: '图标' }, propType: 'node', }, { name: 'status', title: { label: '状态', tip: '状态' }, propType: 'string', }, ], configure: { component: { nestingRule: { parentWhitelist: ['Steps'] } }, supports: { style: true }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/steps.step/snippets.ts ================================================ export default []; ================================================ FILE: packages/antd-lowcode-materials/lowcode/switch/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Switch', title: '开关', category: '表单', props: [ { name: 'defaultChecked', title: { label: '默认选中', tip: '默认是否选中' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'checked', title: { label: '是否选中', tip: '当前是否选中' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', supportVariable: true, }, { name: 'autoFocus', title: { label: '自动聚焦', tip: '组件自动获取焦点' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'checkedChildren', title: { label: '选中时内容', tip: '选中时的内容' }, propType: 'string', setter: 'StringSetter' }, { name: 'unCheckedChildren', title: { label: '非选中时内容', tip: '非选中时的内容' }, propType: 'string', setter: 'StringSetter' }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'loading', title: { label: '加载中', tip: '加载中' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'size', title: { label: '尺寸', tip: '开关大小' }, propType: { type: 'oneOf', value: ['default', 'small'] }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '默认', value: 'default', }, { title: '小', value: 'small', }, ], }, }, defaultValue: 'default', }, { name: 'onChange', title: { label: '变化时回调函数', tip: '变化时回调函数' }, propType: 'func', }, { name: 'onClick', title: { label: '点击时回调函数', tip: '点击时回调函数' }, propType: 'func', }, // { // name: 'className', // title: { label: '类名', tip: '类名' }, // propType: 'string', // }, ], configure: { supports: { style: true, events: [ { name: 'onChange', template: "onChange(checked,event,${extParams}){\n// 变化时回调函数\nconsole.log('onChange',checked,event);}", }, { name: 'onClick', template: "onClick(checked,event,${extParams}){\n// 点击时回调函数\nconsole.log('onClick',checked,event);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/switch/snippets.ts ================================================ export default [ { title: '开关', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/switch-1.png', schema: { componentName: 'Switch', props: { defaultChecked: true, }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/table/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Table', title: '表格', category: '数据展示', props: [ { title: '数据源', display: 'block', type: 'group', items: [ { name: 'dataSource', title: { label: '表格数据', tip: 'dataSource | 表格数据' }, propType: 'object', setter: 'JsonSetter', supportVariable: true, }, { name: 'loading', title: { label: '加载中', tip: 'loading | 是否加载中' }, propType: 'bool', setter: 'BoolSetter', defaultValue: false, supportVariable: true, }, { name: 'rowKey', title: { label: '行Key', tip: 'rowKey | 表格行 key 的取值,可以是字符串或一个函数', }, propType: { type: 'oneOfType', value: ['string', 'func'] }, setter: [ 'StringSetter', { componentName: 'FunctionSetter', props: { template: 'getRowKey(record,index,${extParams}){\n// 通过函数获取表格行 key\nreturn record.id;\n}', }, }, 'VariableSetter', ], defaultValue: 'id', }, ], }, { name: 'columns', title: { label: '表格列', tip: '表格列的配置描述,具体项见下表' }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'title', title: { label: '列标题', tip: 'title | 列标题' }, propType: { type: 'oneOfType', value: ['string', 'func'] }, setter: [ 'StringSetter', { componentName: 'SlotSetter', title: '列标题插槽', initialValue: { type: 'JSSlot', params: ['options'], value: [], }, }, ], }, { name: 'dataIndex', title: { label: '数据字段', tip: 'dataIndex | 数据字段' }, propType: 'string', setter: 'StringSetter', isRequired: true, }, { name: 'key', title: { label: 'React key', tip: 'key | React需要的key' }, propType: 'string', setter: 'StringSetter', }, { name: 'align', title: { label: '对齐方式', tip: 'align | 对齐方式' }, propType: { type: 'oneOf', value: ['left', 'right', 'center'], }, defaultValue: 'left', setter: [ { componentName: 'RadioGroupSetter', props: { options: [ { title: 'left', value: 'left', }, { title: 'right', value: 'right', }, { title: 'center', value: 'center', }, ], }, }, 'VariableSetter', ], }, { name: 'fixed', title: { label: '列是否固定', tip: 'fixed | 列是否固定' }, description: '(IE 下无效)列是否固定,可选 true (等效于 left) left right', defaultValue: '', propType: { type: 'oneOf', value: ['', 'left', 'right'], }, setter: [ { componentName: 'RadioGroupSetter', props: { options: [ { title: '不固定', value: '', }, { title: '固定在左侧', value: 'left', }, { title: '固定在右侧', value: 'right', }, ], }, }, 'VariableSetter', ], }, { name: 'className', title: { label: '列样式类名', tip: 'className | 列样式类名', }, propType: 'string', setter: 'StringSetter', }, { name: 'width', title: { label: '宽度', tip: 'width | 宽度' }, propType: { type: 'oneOfType', value: ['number', 'string'], }, setter: ['NumberSetter', 'StringSetter', 'VariableSetter'], }, { name: 'sorter', title: { label: '排序规则', tip: 'sorter | 排序函数,本地排序使用一个函数,需要服务端排序可设为 true', }, propType: { type: 'oneOfType', value: ['bool', 'func'] }, setter: ['BoolSetter', 'FunctionSetter', 'VariableSetter'], }, { name: 'hidden', title: { label: '是否隐藏', tip: 'hidden | 是否隐藏当前列', }, propType: 'bool', setter: 'BoolSetter', }, { name: 'filters', title: { label: '筛选菜单项', tip: 'filters | 表头的筛选菜单项', }, propType: 'object', setter: 'JsonSetter', }, { name: 'render', title: { label: '自定义渲染', tip: 'render | 插槽内的物料表达式可通过this.record获取当前行数据,this.index获取索引', }, propType: 'func', setter: [ { componentName: 'SlotSetter', title: '单元格插槽', initialValue: { type: 'JSSlot', params: ['text', 'record', 'index'], value: [], }, }, 'VariableSetter', ], }, ], }, }, initialValue: { title: '标题' }, }, }, }, }, { title: '外观', display: 'block', type: 'group', items: [ { name: 'showHeader', title: { label: '显示表头', tip: 'showHeader | 是否显示表头' }, propType: 'bool', setter: 'BoolSetter', defaultValue: true, }, { name: 'bordered', title: { label: '显示边框', tip: 'bordered | 是否展示外边框和列边框', }, propType: 'bool', setter: 'BoolSetter', }, { name: 'size', title: { label: '表格大小', tip: 'size | 表格大小' }, propType: { type: 'oneOf', value: ['default', 'middle', 'small'], }, setter: [ { componentName: 'RadioGroupSetter', props: { options: [ { title: '默认', value: 'default', }, { title: '中', value: 'middle', }, { title: '小', value: 'small', }, ], }, }, 'VariableSetter', ], defaultValue: 'default', }, { name: 'tableLayout', title: { label: '表格布局', tip: 'tableLayout | 表格布局' }, defaultValue: '', propType: { type: 'oneOf', value: ['', 'auto', 'fixed'], }, setter: [ { componentName: 'RadioGroupSetter', props: { options: [ { title: '默认', value: '', }, { title: '自动', value: 'auto', }, { title: '固定', value: 'fixed', }, ], }, }, 'VariableSetter', ], }, ], }, { title: '分页', display: 'block', type: 'group', items: [ { name: 'pagination', title: { label: '显示分页', tip: 'pagination | 显示分页' }, propType: 'object', setter: 'BoolSetter', extraProps: { setValue: (target, value) => { if (value) { target.parent.setPropValue('pagination', { pageSize: 10, size: 'default' }); } }, }, }, { name: 'pagination.pageSize', title: { label: '每页条数', tip: 'pagination.pageSize | 每页条数' }, propType: 'number', setter: 'NumberSetter', condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("pagination")', }, }, { name: 'pagination.total', title: { label: '数据总数', tip: 'pagination.total | 数据总数' }, propType: 'number', setter: 'NumberSetter', condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("pagination")', }, }, { name: 'pagination.defaultCurrent', title: { label: '默认当前页', tip: 'pagination.defaultCurrent | 默认的当前页数', }, propType: 'number', setter: 'NumberSetter', condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("pagination")', }, }, { name: 'pagination.current', title: { label: '当前页数', tip: 'pagination.current | 当前页数' }, propType: 'number', setter: 'NumberSetter', condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("pagination")', }, }, { name: 'pagination.showTotal', title: { label: '显示总数', tip: 'pagination.showTotal | 用于显示数据总量和当前数据顺序', }, propType: 'func', setter: [ { componentName: 'FunctionSetter', props: { template: 'showTotal(total,range,${extParams}){\n// 用于格式化显示表格数据总量\nreturn `共 ${total} 条`;\n}', }, }, 'VariableSetter', ], condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("pagination")', }, }, { name: 'pagination.showSizeChanger', title: { label: '页数切换', tip: 'pagination.showSizeChanger | 是否展示 pageSize 切换器', }, propType: 'bool', setter: 'BoolSetter', condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("pagination")', }, }, { name: 'pagination.showQuickJumper', title: { label: '快速跳转', tip: 'pagination.showQuickJumper | 是否可以快速跳转至某页', }, propType: 'bool', setter: 'BoolSetter', condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("pagination")', }, }, { name: 'pagination.simple', title: { label: '简单分页', tip: 'pagination.simple | 简单分页' }, propType: 'bool', setter: 'BoolSetter', condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("pagination")', }, }, { name: 'pagination.size', title: { label: '分页尺寸', tip: 'pagination.size | 分页尺寸' }, propType: { type: 'oneOf', value: ['default', 'small'], }, setter: [ { componentName: 'RadioGroupSetter', props: { options: [ { title: '默认', value: 'default', }, { title: '小', value: 'small', }, ], }, }, 'VariableSetter', ], condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("pagination")', }, }, { name: 'pagination.position', title: { label: '分页位置', tip: 'pagination.position | 分页位置' }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'SelectSetter', props: { options: [ { title: '上左', value: 'topLeft', }, { title: '上中', value: 'topCenter', }, { title: '上右', value: 'topRight', }, { title: '下左', value: 'bottomLeft', }, { title: '下中', value: 'bottomCenter', }, { title: '下右', value: 'bottomRight', }, ], }, initialValue: 'bottomRight', }, }, }, condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("pagination")', }, }, ], }, { title: '滚动', display: 'block', type: 'group', items: [ { name: 'scroll.scrollToFirstRowOnChange', title: { label: '自动滚动', tip: 'scroll.scrollToFirstRowOnChange | 是否自动滚动到表格顶部', }, propType: 'bool', setter: 'BoolSetter', defaultValue: true, }, { name: 'scroll.x', title: { label: '横向滚动', tip: 'scroll.x | 设置横向滚动,也可用于指定滚动区域的宽,可以设置为像素值,百分比,true 和 max-content', }, propType: { type: 'oneOfType', value: ['number', 'bool'] }, setter: ['NumberSetter', 'BoolSetter', 'VariableSetter'], }, { name: 'scroll.y', title: { label: '纵向滚动', tip: 'scroll.y | 设置纵向滚动,也可用于指定滚动区域的高,可以设置为像素值', }, propType: 'number', setter: ['NumberSetter', 'VariableSetter'], }, ], }, { title: '行选择器', display: 'block', type: 'group', items: [ { name: 'rowSelection', title: { label: '行选择', tip: 'rowSelection | 行选择' }, propType: 'object', setter: 'BoolSetter', extraProps: { setValue: (target, value) => { if (value) { target.parent.setPropValue('rowSelection', { type: 'radio', }); } }, }, }, { name: 'rowSelection.type', title: { label: '行选择类型', tip: 'rowSelection.type | 多选/单选' }, propType: { type: 'oneOf', value: ['checkbox', 'radio'], }, setter: [ { componentName: 'RadioGroupSetter', props: { options: [ { title: '多选', value: 'checkbox', }, { title: '单选', value: 'radio', }, ], }, }, 'VariableSetter', ], condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("rowSelection")', }, }, { name: 'rowSelection.fixed', title: { label: '固定左边', tip: 'rowSelection.fixed | 把选择框列固定在左边', }, propType: 'bool', setter: 'BoolSetter', condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("rowSelection")', }, }, { name: 'rowSelection.selectedRowKeys', title: { label: '选中行Key', tip: 'rowSelection.selectedRowKeys | 指定选中项的 key 数组', }, propType: 'object', setter: 'JsonSetter', condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("rowSelection")', }, }, { name: 'rowSelection.preserveSelectedRowKeys', title: { label: '保留选项', tip: 'rowSelection.preserveSelectedRowKeys | 当数据被删除时仍然保留选项' }, propType: 'bool', setter: 'BoolSetter', condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("rowSelection")', }, }, { name: 'rowSelection.getCheckboxProps', title: { label: '默认属性', tip: 'rowSelection.getCheckboxProps | 选择框的默认属性配置', }, propType: 'func', setter: [ { componentName: 'FunctionSetter', props: { template: 'getCheckboxProps(record,${extParams}){\n// 选择框的默认属性配置\nreturn { disabled: false };\n}', }, }, 'VariableSetter', ], condition: { type: 'JSFunction', value: 'target => !!target.getProps().getPropValue("rowSelection")', }, }, ], }, { title: '行展开', display: 'block', type: 'group', items: [ { name: 'expandable.expandedRowRender', title: { label: '展开行渲染', tip: 'expandable.expandedRowRender | 额外的展开行', }, propType: 'func', setter: [ { componentName: 'SlotSetter', title: '展开行插槽', initialValue: { type: 'JSSlot', params: ['record', 'index', 'indent', 'expanded'], value: [], }, }, { componentName: 'FunctionSetter', props: { template: 'expandedRowRender(record,index,indent,expanded,${extParams}){\n// 展开行渲染\nreturn `${record.id}`}', }, }, 'VariableSetter', ], }, { name: 'expandable.rowExpandable', title: { label: '是否可展开', tip: 'expandable.rowExpandable | 行是否可展开', }, propType: 'func', setter: [ { componentName: 'FunctionSetter', props: { template: 'rowExpandable(record,${extParams}){\n// 行是否可展开\nreturn true;\n}', }, }, 'VariableSetter', ], }, ], }, { title: '扩展', display: 'block', type: 'group', items: [ { name: 'title', title: { label: '表格标题', tip: 'title | 表格标题' }, propType: 'func', setter: [ { componentName: 'SlotSetter', title: '表格标题插槽', initialValue: { type: 'JSSlot', params: ['currentPageData'], value: [], }, }, { componentName: 'FunctionSetter', props: { template: 'renderTitle(currentPageData,${extParams}){\n// 自定义渲染表格顶部\nreturn "表格顶部";\n}', }, }, 'VariableSetter', ], }, { name: 'footer', title: { label: '表格尾部', tip: 'footer | 表格尾部' }, propType: 'func', setter: [ { componentName: 'SlotSetter', title: '表格尾部插槽', initialValue: { type: 'JSSlot', params: ['currentPageData'], value: [], }, }, { componentName: 'FunctionSetter', props: { template: 'renderFooter(currentPageData,${extParams}){\n// 自定义渲染表格尾部\nreturn "表格尾部";\n}', }, }, 'VariableSetter', ], }, { name: 'onHeaderRow', title: { label: '头部行属性', tip: 'onHeaderRow | 设置头部行属性' }, propType: 'func', setter: [ { componentName: 'FunctionSetter', props: { template: 'onHeaderRow(columns,index,${extParams}){\n// 设置头部行属性\nreturn {onClick:()=>{}};\n}', }, }, 'VariableSetter', ], }, { name: 'onRow', title: { label: '行属性', tip: 'onRow | 设置行属性' }, propType: 'func', setter: [ { componentName: 'FunctionSetter', props: { template: 'onRow(record,index,${extParams}){\n// 设置行属性\nreturn {onClick:event=>{}};\n}', }, }, 'VariableSetter', ], }, { name: 'rowClassName', title: { label: '行类名', tip: 'rowClassName | 表格行的类名' }, propType: 'func', setter: [ { componentName: 'FunctionSetter', props: { template: 'rowClassName(record,index,${extParams}){\n// 表格行的类名\nreturn `className-${record.type}`;\n}', }, }, 'VariableSetter', ], }, ], }, ], configure: { supports: { style: true, events: [ { name: 'onChange', template: "onChange(pagination,filters,sorter,extra,${extParams}){\n// 表格翻页事件\nconsole.log('onChange', pagination);}", }, { name: 'rowSelection.onChange', template: "onRowSelectionChange(selectedRowKeys,selectedRows,${extParams}){\n// 选中项发生变化时的回调\nconsole.log('onRowSelectionChange', selectedRowKeys, selectedRows);}", }, { name: 'expandable.onExpand', template: "onExpandableExpand(expanded,record){\n// 点击展开图标时触发\nconsole.log('onRowSelectionChange', expanded, record);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/table/snippets.ts ================================================ export default [ { title: '表格', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/table-1.png', schema: { componentName: 'Table', props: { dataSource: [ { id: '1', name: '胡彦斌', age: 32, address: '西湖区湖底公园1号', }, { id: '2', name: '王一博', age: 28, address: '滨江区网商路699号', }, ], columns: [ { title: '姓名', dataIndex: 'name', key: 'name', }, { title: '年龄', dataIndex: 'age', key: 'age', }, ], rowKey: 'id', pagination: { pageSize: 10, total: 15, current: 1, }, }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/tabs/meta.ts ================================================ import { uuid } from '../_utils/utils'; import snippets from './snippets'; export default { snippets, componentName: 'Tabs', title: '标签页', category: '数据展示', props: [ { name: 'items', title: '标签项', setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'key', title: 'key', setter: 'StringSetter', initialValue: (val) => val || uuid(), supportVariable: true }, { name: 'label', title: '标题', setter: 'StringSetter', initialValue: '标签项', supportVariable: true }, // { // name: 'closeable', // title: '是否可删除', // condition(target) { // return target.getProps().getPropValue('type') === 'editable-card'; // }, // setter: 'BoolSetter', // initialValue: true, // }, { name: 'disabled', title: '禁用', setter: 'BoolSetter', initialValue: false, supportVariable: true }, { name: 'forceRender', title: '隐藏时保留', propType: 'bool', setter: 'BoolSetter', initialValue: false, supportVariable: true }, { name: 'children', title: '内容', setter: { componentName: 'SlotSetter', initialValue: { type: 'JSSlot', value: [], }, }, }, ], }, }, initialValue: () => { return { key: uuid(), label: '标签项', disabled: false, forceRender: false, children: { type: 'JSSlot', value: [], }, }; }, }, }, } }, // { // name: 'tabs', // title: '标签项', // setter: { // componentName: 'ArraySetter', // props: { // itemSetter: { // componentName: 'ObjectSetter', // props: { // config: { // items: [ // { // name: 'key', // title: 'key', // setter: 'StringSetter', // initialValue: (val) => val || uuid(), // supportVariable: true // }, // { // name: 'tab', // title: '标题', // setter: 'StringSetter', // initialValue: '标签项', // supportVariable: true // }, // // { // // name: 'closeable', // // title: '是否可删除', // // condition(target) { // // return target.getProps().getPropValue('type') === 'editable-card'; // // }, // // setter: 'BoolSetter', // // initialValue: true, // // }, // { // name: 'disabled', // title: '禁用', // setter: 'BoolSetter', // initialValue: false, // supportVariable: true // }, // { // name: 'forceRender', // title: '隐藏时保留', // propType: 'bool', // setter: 'BoolSetter', // initialValue: false, // supportVariable: true // }, // ], // }, // }, // initialValue: () => { // return { // key: uuid(), // tab: '标签项', // closeable: true, // disabled: false, // forceRender: false, // }; // }, // }, // }, // }, // extraProps: { // getValue(target, fieldValue) { // const map = target.node.children.map((child) => { // const key = child.getPropValue('key') ? String(child.getPropValue('key')) : child.id; // return { // key, // tab: child.getPropValue('tab'), // closeable: child.getPropValue('closeable'), // disabled: child.getPropValue('disabled'), // forceRender: child.getPropValue('forceRender'), // }; // }); // return map; // }, // setValue(target, value) { // const { node } = target; // const map = {}; // if (!Array.isArray(value)) { // value = []; // } // value.forEach((item) => { // const tabItem = Object.assign({}, item); // map[item.key] = tabItem; // }); // node.children.mergeChildren( // (child) => { // const key = String(child.getPropValue('key')); // if (Object.hasOwnProperty.call(map, key)) { // child.setPropValue('tab', map[key].tab); // child.setPropValue('closeable', map[key].closeable); // child.setPropValue('disabled', map[key].disabled); // child.setPropValue('forceRender', map[key].forceRender); // delete map[key]; // return false; // } // return true; // }, // () => { // const items = []; // for (const key in map) { // if (Object.hasOwnProperty.call(map, key)) { // items.push({ // componentName: 'Tabs.TabPane', // props: map[key], // }); // } // } // return items; // }, // (child1, child2) => { // const a = value.findIndex( // (item) => String(item.key) === String(child1.getPropValue('key')), // ); // const b = value.findIndex( // (item) => String(item.key) === String(child2.getPropValue('key')), // ); // return a - b; // }, // ); // }, // }, // }, // { // name: 'addIcon', // title: { label: '自定义添加按钮', tip: '自定义添加按钮' }, // propType: 'node', // }, { name: 'animated', title: { label: '切换动画', tip: '是否使用动画切换Tabs', }, propType: 'bool', setter: 'BoolSetter', supportVariable: true }, // { // name: 'renderTabBar', // title: { label: '替换TabBar', tip: '替换TabBar,用于二次封装标签头' }, // propType: 'func', // }, { name: 'defaultActiveKey', title: { label: '初始选中', tip: '初始化选中面板的key,如果没有设置activeKey', }, propType: 'string', setter: 'StringSetter', supportVariable: true }, // { // name: 'activeKey', // title: { label: '当前激活tab面板', tip: '当前激活tab面板,注意配置了这个属性就需要自己处理点击切换' }, // propType: 'string', // }, { name: 'hideAdd', title: { label: '隐藏加号', tip: '是否隐藏加号图标,在`type="editable-card"`时有效', }, condition(target) { return target.getProps().getPropValue('type') === 'editable-card'; }, propType: 'bool', setter: 'BoolSetter', defaultValue: false, supportVariable: true }, { name: 'size', title: { label: '尺寸', tip: '大小,提供 `large` `default` 和 `small` 三种大小', }, propType: { type: 'oneOf', value: ['large', 'default', 'small'], }, defaultValue: 'default', }, { name: 'centered', title: { label: '标签居中', tip: '标签居中展示' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', supportVariable: true }, { name: 'tabBarExtraContent', title: { label: '额外元素', tip: 'tab bar上额外的元素' }, propType: 'node', }, { name: 'tabBarGutter', title: { label: '标签间隙', tip: 'tabs之间的间隙' }, propType: 'number', setter: 'NumberSetter', supportVariable: true }, // { // name: 'tabBarStyle', // title: { label: 'tab bar的样式对象', tip: 'tab bar的样式对象' }, // propType: 'object', // }, { name: 'tabPosition', title: { label: '页签位置', tip: '页签位置', }, propType: { type: 'oneOf', value: ['top', 'right', 'bottom', 'left'], }, defaultValue: 'top', }, { name: 'type', title: { label: '页签样式', tip: '页签的基本样式,可选`line`、`card`、`editable-card`类型', }, propType: { type: 'oneOf', value: ['line', 'card', 'editable-card'], }, defaultValue: 'line', }, { name: 'onChange', title: { label: '切换面板的回调', tip: '切换面板的回调' }, propType: 'func', }, { name: 'onEdit', title: { label: '新增删除回调', tip: '新增和删除页签的回调,在`type="editable-card"`时有效', }, condition(target) { return target.getProps().getPropValue('type') === 'editable-card'; }, propType: 'func', }, { name: 'onTabClick', title: { label: 'tab点击回调', tip: 'tab被点击的回调' }, propType: 'func', }, { name: 'onTabScroll', title: { label: 'tab滚动触发', tip: 'tab滚动时触发' }, propType: 'func', }, { name: 'keyboard', title: { label: '键盘切换', tip: '开启键盘切换功能' }, propType: 'bool', defaultValue: true, }, ], configure: { component: { isContainer: true, }, supports: { style: true, events: [ { name: 'onChange', template: "onChange(activeKey,${extParams}){\n// 切换面板的回调\nconsole.log('onChange',activeKey);}", }, { name: 'onEdit', template: "onEdit(targetKey,action,${extParams}){\n// 新增和删除页签的回调\nconsole.log('onEdit',targetKey,action);}", }, { name: 'onTabClick', template: "onTabClick(key,event,${extParams}){\n// tab 被点击的回调\nconsole.log('onTabClick',key,event);}", }, { name: 'onTabScroll', template: "onTabScroll({direction},${extParams}){\n// tab 滚动时触\nconsole.log('onTabScroll',direction);}", }, ], }, advanced: { // initialChildren: [ // { // componentName: 'Tabs.TabPane', // props: { key: 'item1', tab: 'Item 1' }, // }, // { // componentName: 'Tabs.TabPane', // props: { key: 'item2', tab: 'Item 2' }, // }, // ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/tabs/snippets.ts ================================================ export default [ { title: '普通型', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/tabs-1.jpg', schema: { componentName: 'Tabs', props: { type: 'line', items: [ { label: '标签项1', key: 'tab-item-1', children: { type: 'JSSlot', value: [], }, }, { label: '标签项2', key: 'tab-item-2', children: { type: 'JSSlot', value: [], }, } ] } }, }, { title: '卡片型', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/tabs-2.jpg', schema: { componentName: 'Tabs', props: { type: 'card', items: [ { label: '标签项1', key: 'tab-item-1', children: { type: 'JSSlot', value: [], }, }, { label: '标签项2', key: 'tab-item-2', children: { type: 'JSSlot', value: [], }, } ] } }, }, { title: '可编辑卡片', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/tabs-3.jpg', schema: { componentName: 'Tabs', props: { type: 'editable-card', items: [ { label: '标签项1', key: 'tab-item-1', children: { type: 'JSSlot', value: [], }, }, { label: '标签项2', key: 'tab-item-2', children: { type: 'JSSlot', value: [], }, } ] } }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/tabs.tab-pane/meta.ts ================================================ // FIXME: 选中tabPane点复制,会出问题,因为复制的组件key一样 export default { componentName: 'Tabs.TabPane', title: '标签页项', category: '', props: [ { name: 'key', title: { label: 'key', tip: 'key', }, propType: 'string', setter: 'StringSetter', supportVariable: true }, { name: 'tab', title: { label: '标题', tip: '标题', }, propType: 'string', setter: 'StringSetter', supportVariable: true }, // { // name: 'closeable', // title: { // label: '可删除', // tip: '是否可删除', // }, // propType: 'bool', // defaultValue: true, // }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态', }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', supportVariable: true }, { name: 'forceRender', title: { label: '隐藏时保留', tip: '被隐藏时是否渲染 DOM 结构', }, propType: 'bool', setter: 'BoolSetter', supportVariable: true }, ], configure: { component: { isContainer: true, nestingRule: { parentWhitelist: ['Tab'], }, }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/tag/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Tag', title: '标签', category: '数据展示', props: [ { name: 'children', title: { label: '内容', tip: '内容' }, propType: 'string', }, { name: 'closable', title: { label: '可关闭', tip: '标签是否可以关闭' }, propType: 'bool', defaultValue: false, }, { name: 'color', title: { label: '标签色', tip: '标签色' }, propType: 'string', }, // { // name: 'closeIcon', // title: { label: '自定义关闭按钮', tip: '自定义关闭按钮' }, // propType: 'node', // }, { name: 'onClose', title: { label: '关闭时的回调', tip: '关闭时的回调' }, propType: 'func', }, // { // name: 'visible', // title: { label: '是否显示标签', tip: '是否显示标签' }, // propType: 'bool', // defaultValue: true, // }, { name: 'icon', title: { label: '设置图标', tip: '设置图标' }, propType: 'node', }, ], configure: { supports: { style: true, events: [ { name: 'onClose', template: "onClose(event,${extParams}){\n// 关闭时的回调\nconsole.log('onClose',event);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/tag/snippets.ts ================================================ export default [ { title: '标签', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/tag-1.png', schema: { componentName: 'Tag', props: { color: 'magenta', children: 'tag', }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/time-picker/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'TimePicker', title: '时间选择框', category: '表单', props: [ { name: 'defaultValue', title: { label: '默认时间', tip: '默认时间' }, propType: 'date', setter: 'DateSetter', }, { name: 'value', title: { label: '当前时间', tip: '当前时间' }, propType: 'date', setter: 'DateSetter', }, { name: 'allowClear', title: { label: '支持清除', tip: '是否允许清除' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter' }, { name: 'autoFocus', title: { label: '自动聚焦', tip: '自动获取焦点' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'bordered', title: { label: '显示边框', tip: '是否有边框' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter' }, { name: 'className', title: { label: '选择器类名', tip: '选择器类名' }, propType: 'string', setter: 'StringSetter' }, { name: 'clearText', title: { label: '清除按钮的提示文案', tip: '清除按钮的提示文案' }, propType: 'string', setter: 'StringSetter' }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'disabledHours', title: { label: '禁止选择部分小时选项', tip: '禁止选择部分小时选项' }, propType: 'func', }, { name: 'disabledMinutes', title: { label: '禁止选择部分分钟选项', tip: '禁止选择部分分钟选项' }, propType: 'func', }, { name: 'disabledSeconds', title: { label: '禁止选择部分秒选项', tip: '禁止选择部分秒选项' }, propType: 'func', }, { name: 'format', title: { label: '展示的时间格式', tip: '展示的时间格式' }, propType: 'string', setter: 'StringSetter' }, { name: 'getPopupContainer', title: { label: '定义浮层的容器', tip: '定义浮层的容器,默认为 body 上新建 div', }, propType: 'func', }, { name: 'hideDisabledOptions', title: { label: '隐藏禁止选择的选项', tip: '隐藏禁止选择的选项' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'hourStep', title: { label: '小时选项间隔', tip: '小时选项间隔' }, propType: 'number', setter: 'NumberSetter' }, { name: 'inputReadOnly', title: { label: '只读', tip: '设置输入框为只读(避免在移动设备上打开虚拟键盘)', }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'minuteStep', title: { label: '分钟选项间隔', tip: '分钟选项间隔' }, propType: 'number', setter: 'NumberSetter' }, // { // name: 'open', // title: { label: '面板是否打开', tip: '面板是否打开' }, // propType: 'bool', // // defaultValue: false, // setter: 'BoolSetter' // }, { name: 'placeholder', title: { label: '空值提示', tip: '没有值的时候显示的内容' }, propType: { type: 'oneOfType', value: ['string', { type: 'arrayOf', value: 'string' }], }, }, { name: 'popupClassName', title: { label: '弹出层类名', tip: '弹出层类名' }, propType: 'string', setter: 'StringSetter' }, // { // name: 'popupStyle', // title: { label: '弹出层样式对象', tip: '弹出层样式对象' }, // propType: 'object', // }, { name: 'secondStep', title: { label: '秒选项间隔', tip: '秒选项间隔' }, propType: 'number', setter: 'NumberSetter' }, // { // name: 'suffixIcon', // title: { label: '自定义的选择框后缀图标', tip: '自定义的选择框后缀图标' }, // propType: 'node', // }, // { // name: 'clearIcon', // title: { label: '自定义的清除图标', tip: '自定义的清除图标' }, // propType: 'node', // }, // { // name: 'renderExtraFooter', // title: { // label: '选择框底部显示自定义的内容', // tip: '选择框底部显示自定义的内容', // }, // propType: 'func', // }, { name: 'use12Hours', title: { label: '12小时制', tip: '使用 12 小时制,为 true 时 `format` 默认为 `h:mm:ss a`', }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'onChange', title: { label: '时间发生变化的回调', tip: '时间发生变化的回调' }, propType: 'func', }, { name: 'onOpenChange', title: { label: '面板打开/关闭时的回调', tip: '面板打开/关闭时的回调' }, propType: 'func', }, { name: 'showNow', title: { label: '“此刻”按钮', tip: '面板是否显示“此刻”按钮' }, propType: 'bool', setter: 'BoolSetter' }, ], configure: { supports: { style: true, events: [ { name: 'onChange', template: "onChange(time,timeString,${extParams}){\n// 时间发生变化的回调\nconsole.log('onChange',time,timeString);}", }, { name: 'onOpenChange', template: "onOpenChange(open,${extParams}){\n// 面板打开/关闭时的回调\nconsole.log('onOpenChange',open);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/time-picker/snippets.ts ================================================ export default [ { title: '时间选择框', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/time-picker-1.png', schema: { componentName: 'TimePicker', props: {}, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/timeline/meta.ts ================================================ import { uuid } from '../_utils/utils'; import snippets from './snippets'; export default { snippets, componentName: 'Timeline', title: '时间轴', category: '数据展示', props: [ { name: 'steps', title: '步骤配置', setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'key', title: 'key', setter: 'StringSetter', initialValue: (val) => val || uuid(), }, { name: 'color', title: '圆圈颜色', setter: 'StringSetter', }, { name: 'dot', title: '自定义时间轴点', setter: 'node', }, { name: 'label', title: '设置标签', setter: 'StringSetter', }, { name: 'position', title: { label: '自定义节点位置', tip: '自定义节点位置', }, propType: { type: 'oneOf', value: ['left', 'right'], }, setter: [ { componentName: 'RadioGroupSetter', props: { options: [ { title: 'left', value: 'left', }, { title: 'right', value: 'right', }, ], }, }, 'VariableSetter', ], }, ], }, }, initialValue: () => { return { key: `timeLine${uuid()}`, label: '时间轴', }; }, }, }, }, extraProps: { getValue(target, fieldValue, a, b, c) { const map = target.node.children.map((child) => { const key = child.getPropValue('key') ? String(child.getPropValue('key')) : child.id; const result = { key }; ['color', 'dot', 'label', 'position'].forEach((propKey) => { result[propKey] = child.getPropValue(propKey); }); return result; }); return map.length === 0 ? fieldValue : map; }, setValue(target, value) { const { node } = target; const map = {}; if (!Array.isArray(value)) { value = []; } value.forEach((item) => { const tabItem = Object.assign({}, item); map[item.key] = tabItem; }); node.children.mergeChildren( (child) => { const key = String(child.getPropValue('key')); if (Object.hasOwnProperty.call(map, key)) { ['color', 'dot', 'label', 'position'].forEach((propKey) => { child.setPropValue(propKey, map[key][propKey]); }); delete map[key]; return false; } return true; }, () => { const items = []; for (const key in map) { if (Object.hasOwnProperty.call(map, key)) { items.push({ componentName: 'Timeline.Item', props: map[key], }); } } return items; }, (child1, child2) => { const a = value.findIndex( (item) => String(item.key) === String(child1.getPropValue('key')), ); const b = value.findIndex( (item) => String(item.key) === String(child2.getPropValue('key')), ); return a - b; }, ); }, }, }, { name: 'mode', title: { label: '模式', tip: '通过设置 `mode` 可以改变时间轴和内容的相对位置', }, propType: { type: 'oneOf', value: ['left', 'alternate', 'right'] }, }, { name: 'pending', title: { label: '存在最后节点', tip: '指定最后一个幽灵节点是否存在', }, propType: 'bool', }, { name: 'pendingDot', title: { label: '当最后一个幽灵节点存在時,指定其时间图点', tip: '当最后一个幽灵节点存在時,指定其时间图点', }, propType: { type: 'oneOfType', value: ['string', 'node'] }, }, { name: 'reverse', title: { label: '节点排序', tip: '节点排序' }, propType: 'bool', defaultValue: false, }, ], configure: { supports: { style: true } }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/timeline/snippets.ts ================================================ export default [ { title: '时间轴', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/timeline-1.jpg', schema: { componentName: 'Timeline', props: { steps: [ { key: 'timeLinei5wd', label: '时间轴', }, { key: 'timeLinei5wx', label: '时间轴', }, ], }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/timeline.item/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Timeline.Item', title: '时间轴项', category: '', props: [ { name: 'color', title: { label: '颜色', tip: '颜色' }, propType: 'string', defaultValue: '#00f', setter: 'ColorSetter', }, { name: 'dot', title: { label: '时间轴点', tip: '时间轴点', }, propType: 'node', }, { name: 'label', title: { label: '标签', tip: '标签', }, propType: { type: 'oneOfType', value: ['string', 'node', 'func'] }, }, { name: 'position', title: { label: '位置', tip: '位置', }, propType: { type: 'oneOf', value: ['left', 'right'] }, }, ], configure: { supports: { style: true } }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/timeline.item/snippets.ts ================================================ export default [ // { // title: '时间轴', // screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/timeline-1.jpg', // schema: { // componentName: 'Timeline', // props: {}, // }, // }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/tooltip/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Tooltip', title: '文字提示', category: '数据展示', props: [ { title: '内容', display: 'block', type: 'group', items: [ { name: 'title', title: { label: '提示文字', tip: 'title | 提示文字', }, propType: { type: 'oneOfType', value: ['string', 'node'] }, setter: ['StringSetter', 'SlotSetter', 'VariableSetter'], }, ], }, { title: '控制', display: 'block', type: 'group', items: [ { name: 'defaultOpen', title: { label: '默认显隐', tip: 'defaultOpen | 默认是否显隐', }, propType: 'bool', setter: 'BoolSetter', defaultValue: false, }, { name: 'open', title: { label: '当前显隐', tip: 'open | 当前是否显隐', }, propType: 'bool', setter: 'BoolSetter', }, ], }, { title: '外观', display: 'block', type: 'group', items: [ { name: 'placement', title: { label: '气泡位置', tip: 'placement | 气泡位置' }, propType: { type: 'oneOf', value: [ 'top', 'left', 'right', 'bottom', 'topLeft', 'topRight', 'bottomLeft', 'bottomRight', 'leftTop', 'leftBottom', 'rightTop', 'rightBottom', ], }, defaultValue: 'top', setter: { componentName: 'SelectSetter', props: { options: [ { title: '上', value: 'top', }, { title: '左', value: 'left', }, { title: '右', value: 'right', }, { title: '下', value: 'bottom', }, { title: '上左', value: 'topLeft', }, { title: '上右', value: 'topRight', }, { title: '下左', value: 'bottomLeft', }, { title: '下右', value: 'bottomRight', }, { title: '左上', value: 'leftTop', }, { title: '左下', value: 'leftBottom', }, { title: '右上', value: 'rightTop', }, { title: '右下', value: 'rightBottom', }, ], }, }, }, { name: 'autoAdjustOverflow', title: { label: '自动调整', tip: 'autoAdjustOverflow | 气泡被遮挡时自动调整位置', }, propType: 'bool', setter: 'BoolSetter', defaultValue: true, }, { name: 'arrowPointAtCenter', title: { label: '指向中心', tip: 'arrowPointAtCenter | 箭头是否指向目标元素中心', }, propType: 'bool', setter: 'BoolSetter', defaultValue: false, }, { name: 'color', title: { label: '背景颜色', tip: 'color | 背景颜色', }, propType: 'string', setter: 'ColorSetter', }, { name: 'zIndex', title: { label: 'zIndex', tip: 'zIndex | 设置 Tooltip 的 z-index值', }, propType: 'number', setter: 'NumberSetter', }, ], }, { name: 'overlayStyle', title: '卡片样式', type: 'group', extraProps: { display: 'entry', }, items: [ { name: 'overlayStyle', title: { label: '样式设置', tip: 'overlayStyle | 卡片样式' }, setter: 'StyleSetter', extraProps: { display: 'block', }, }, ], }, { name: 'overlayInnerStyle', title: '卡片内容样式', type: 'group', extraProps: { display: 'entry', }, items: [ { name: 'overlayInnerStyle', title: { label: '样式设置', tip: 'overlayStyle | 卡片内容区域的样式', }, setter: 'StyleSetter', extraProps: { display: 'block', }, }, ], }, { title: '行为', display: 'block', type: 'group', items: [ { name: 'trigger', title: { label: '触发行为', tip: 'trigger | 触发行为' }, propType: { type: 'oneOf', value: ['hover', 'focus', 'click', 'contextMenu'], }, defaultValue: 'hover', setter: { componentName: 'SelectSetter', props: { options: [ { title: '鼠标悬停', value: 'hover', }, { title: '获得焦点', value: 'focus', }, { title: '鼠标点击', value: 'click', }, { title: '右键菜单', value: 'contextMenu', }, ], }, }, }, { name: 'mouseEnterDelay', title: { label: '展示延时', tip: 'mouseEnterDelay | 鼠标移入后延时多少才显示 Tooltip,单位:秒', }, propType: 'number', defaultValue: 0.1, setter: { componentName: 'NumberSetter', props: { step: 0.1, }, }, }, { name: 'mouseLeaveDelay', title: { label: '隐藏延时', tip: 'mouseLeaveDelay | 鼠标移出后延时多少才隐藏 Tooltip,单位:秒', }, propType: 'number', defaultValue: 0.1, setter: { componentName: 'NumberSetter', props: { step: 0.1, }, }, }, ], }, ], configure: { component: { isContainer: true }, supports: { style: true, events: [ { name: 'onOpenChange', template: "onOpenChange(open,${extParams}){\n// 显示隐藏的回调\nconsole.log('onOpenChange',open);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/tooltip/snippets.ts ================================================ export default [ { title: '文字提示', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/tooltip-1.jpg', schema: { componentName: 'Tooltip', props: { title: '提示内容', }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/transfer/meta.ts ================================================ import { uuid } from '../_utils/utils'; import snippets from './snippets'; export default { snippets, componentName: 'Transfer', title: '穿梭框', category: '表单', props: [ { name: 'dataSource', title: { label: '数据源', tip: '数据源,其中的数据将会被渲染到左边一栏中,`targetKeys` 中指定的除外', }, propType: { type: 'arrayOf', value: 'object' }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', initialValue: () => { return { key: uuid(), }; }, props: { config: { items: [ { name: 'key', title: 'key', setter: 'StringSetter', initialValue: (val: any) => val || uuid(), }, { name: 'title', title: 'title', setter: 'StringSetter', isRequired: true, }, { name: 'description', title: '描述', setter: 'StringSetter', }, { name: 'disabled', title: '禁止穿梭', setter: ['BoolSetter', 'FunctionSetter'], }, ], }, }, }, }, }, }, { name: 'selectedKeys', title: { label: '选中项', tip: '设置哪些项应该被选中' }, propType: { type: 'arrayOf', value: 'string' }, setter: { componentName: 'ArraySetter', props: { itemSetter: 'StringSetter' } }, supportVariable: true, }, { name: 'targetKeys', title: { label: '右侧框数据', tip: '显示在右侧框数据的 key 集合', }, propType: { type: 'arrayOf', value: 'string' }, setter: { componentName: 'ArraySetter', props: { itemSetter: 'StringSetter' } }, supportVariable: true, }, { title: '常用设置', display: 'block', type: 'group', items: [ { name: 'oneWay', title: { label: '展示为单向样式', tip: '展示为单向样式' }, propType: 'bool', setter: 'BoolSetter', defaultValue: false, }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态' }, propType: 'bool', setter: 'BoolSetter', defaultValue: false, }, { name: 'showSearch', title: { label: '是否显示搜索框', tip: '是否显示搜索框' }, propType: 'bool', setter: 'BoolSetter', defaultValue: false, }, { name: 'showSelectAll', title: { label: '是否展示全选勾选框', tip: '是否展示全选勾选框' }, propType: 'bool', setter: 'BoolSetter', defaultValue: true, }, { name: 'pagination', title: { label: '分页设置', tip: '使用分页样式,自定义渲染列表下无效', }, setter: [ 'BoolSetter', { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'pageSize', title: '单页条数', setter: 'NumberSetter', }, { name: 'simple', title: '简单模式', setter: 'BoolSetter', }, { name: 'showSizeChanger', title: '展示条数切换器', setter: 'BoolSetter', }, ], }, }, } ], propType: { type: 'oneOfType', value: ['bool', 'object'] }, defaultValue: false, }, { name: 'render', title: { label: '每行数据渲染函数', tip: '每行数据渲染函数,该函数的入参为 `dataSource` 中的项,返回值为 ReactElement。或者返回一个普通对象,其中 `label` 字段为 ReactElement,`value` 字段为 title', }, propType: 'func', setter: [ { componentName: 'FunctionSetter', props: { template: 'renderItem(record,${extParams}){\n// 每行数据渲染函数\nreturn record.title;\n}', }, }, 'VariableSetter', ], }, { name: 'filterOption', title: { label: '过滤选项', tip: '接收 `inputValue` `option` 两个参数,当 `option` 符合筛选条件时,应返回 true,反之则返回 false', }, propType: 'func', setter: [ { componentName: 'FunctionSetter', props: { template: 'filterOption(inputValue,option,${extParams}){\n// 接收 inputValue option 两个参数,当 option 符合筛选条件时,应返回 true,反之则返回 false\n\n}', }, }, 'VariableSetter', ], }, { name: 'footer', title: { label: '底部', tip: 'footer | 底部', }, propType: 'func', setter: [ { componentName: 'FunctionSetter', props: { template: 'renderItem(item,${extParams}){\n// 自定义渲染列表项\nreturn `item`;\n}', }, }, { componentName: 'SlotSetter', title: '渲染函数插槽', initialValue: { type: 'JSSlot', value: [], params: ['props', 'info'] }, }, 'VariableSetter', ], }, ], }, // { // name: 'listStyle', // title: { label: '两个穿梭框的自定义样式', tip: '两个穿梭框的自定义样式' }, // propType: { type: 'oneOfType', value: ['object', 'func'] }, // }, // { // name: 'locale', // title: { label: '各种语言', tip: '各种语言' }, // propType: 'object', // }, { name: 'operations', title: { label: '操作文案', tip: '操作文案集合,顺序从上至下', }, propType: { type: 'arrayOf', value: 'string' }, }, { name: 'titles', title: { label: '标题集合', tip: '标题集合,顺序从左至右' }, propType: { type: 'arrayOf', value: 'node' }, }, { name: 'selectAllLabels', title: { label: '多选框标题集合', tip: '自定义顶部多选框标题的集合', }, propType: { type: 'arrayOf', value: { type: 'oneOfType', value: ['node', 'func'] }, }, }, ], configure: { supports: { style: true, events: [ { name: 'onChange', template: "onChange(targetKeys,direction,moveKeys,${extParams}){\n// 选项在两栏之间转移时的回调函数\nconsole.log('onChange',targetKeys,direction,moveKeys);}", }, { name: 'onScroll', template: "onScroll(direction,event,${extParams}){\n// 选项列表滚动时的回调函数\nconsole.log('onScroll',direction,event);}", }, { name: 'onSearch', template: "onSearch(direction,value,${extParams}){\n// 搜索框内容时改变时的回调函数\nconsole.log('onSearch',direction,value);}", }, { name: 'onSelectChange', template: "onSelectChange(sourceSelectedKeys,targetSelectedKeys,${extParams}){\n// 选中项发生改变时的回调函数\nconsole.log('onSelectChange',sourceSelectedKeys,targetSelectedKeys);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/transfer/snippets.ts ================================================ import { uuid } from '../_utils/utils'; export default [ { title: '穿梭框', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/transfer-1.png', schema: { componentName: 'Transfer', props: { dataSource: [ { key: uuid(), title: 'content1', }, { key: uuid(), title: 'content2', }, { key: uuid(), title: 'content3', }, { key: uuid(), title: 'content4', }, { key: uuid(), title: 'content5', }, ], render: { type: 'JSFunction', value: `function renderItem(record, extParams) { return record.title; }`, }, }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/tree/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Tree', title: '树形控件', category: '数据展示', props: [ { name: 'treeData', title: { label: '数据', tip: 'treeNodes 数据,如果设置则不需要手动构造 TreeNode 节点(key 在整个树范围内唯一)', }, propType: { type: 'arrayOf', value: 'object' }, setter: 'JsonSetter', }, { name: 'autoExpandParent', title: { label: '是否自动展开父节点', tip: '是否自动展开父节点' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter' }, { name: 'blockNode', title: { label: '是否节点占据一行', tip: '是否节点占据一行' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'checkable', title: { label: '节点前添加 Checkbox 复选框', tip: '节点前添加 Checkbox 复选框', }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'checkedKeys', title: { label: '复选框节点', tip: '(受控)选中复选框的树节点(注意:父子节点有关联,如果传入父节点 key,则子节点自动选中;相应当子节点 key 都传入,父节点也自动选中。当设置`checkable`和`checkStrictly`,它是一个有`checked`和`halfChecked`属性的对象,并且父子节点的选中与否不再关联', }, propType: { type: 'oneOfType', value: [{ value: 'arrayOf', type: 'string' }, 'object'], }, }, { name: 'checkStrictly', title: { label: '完全受控', tip: 'checkable 状态下节点选择完全受控(父子节点选中状态不再关联)', }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'defaultCheckedKeys', title: { label: '默认选中值', tip: '默认选中值' }, propType: { type: 'arrayOf', value: 'string' }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'StringSetter', } } }, }, { name: 'defaultExpandAll', title: { label: '默认展开所有树节点', tip: '默认展开所有树节点' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'defaultExpandedKeys', title: { label: '默认展开指定的树节点', tip: '默认展开指定的树节点' }, propType: { type: 'arrayOf', value: 'string' }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'StringSetter', } } }, }, { name: 'defaultExpandParent', title: { label: '默认展开父节点', tip: '默认展开父节点' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter' }, { name: 'defaultSelectedKeys', title: { label: '默认选中值', tip: '默认选中值' }, propType: { type: 'arrayOf', value: 'string' }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'StringSetter', } } }, }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'draggable', title: { label: '节点可拖拽', tip: '设置节点可拖拽(IE>8)' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'expandedKeys', title: { label: '展开指定节点', tip: '(受控)展开指定的树节点', }, propType: { type: 'arrayOf', value: 'string' }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'StringSetter', } } }, }, { name: 'filterTreeNode', title: { label: '筛选树节点', tip: '按需筛选树节点(高亮),返回 true', }, propType: 'func', }, { name: 'loadData', title: { label: '异步加载数据', tip: '异步加载数据' }, propType: 'func', }, { name: 'loadedKeys', title: { label: '已经加载节点', tip: '(受控)已经加载的节点,需要配合 `loadData` 使用', }, propType: { type: 'arrayOf', value: 'string' }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'StringSetter', } } }, }, { name: 'multiple', title: { label: '支持多选', tip: '支持点选多个节点(节点本身)', }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'selectable', title: { label: '是否可选中', tip: '是否可选中' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter' }, { name: 'selectedKeys', title: { label: '选中的树节点', tip: '(受控)设置选中的树节点', }, propType: { type: 'arrayOf', value: 'string' }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'StringSetter', } } }, }, { name: 'showIcon', title: { label: '展示图标', tip: '是否展示 TreeNode title 前的图标,没有默认样式,如设置为 true,需要自行定义图标相关样式', }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, // { // name: 'switcherIcon', // title: { // label: '自定义树节点的展开/折叠图标', // tip: '自定义树节点的展开/折叠图标', // }, // propType: 'node', // }, { name: 'showLine', title: { label: '是否展示连接线', tip: '是否展示连接线' }, propType: { type: 'oneOfType', value: ['bool', 'object'] }, }, { name: 'virtual', title: { label: '虚拟滚动', tip: '设置 false 时关闭虚拟滚动', }, propType: 'bool', defaultValue: true, setter: 'BoolSetter' }, { name: 'onCheck', title: { label: '点击复选框触发', tip: '点击复选框触发' }, propType: 'func', }, { name: 'onDragEnd', title: { label: 'dragend 触发时调用', tip: 'dragend 触发时调用' }, propType: 'func', }, { name: 'onDragEnter', title: { label: 'dragenter 触发时调用', tip: 'dragenter 触发时调用' }, propType: 'func', }, { name: 'onDragLeave', title: { label: 'dragleave 触发时调用', tip: 'dragleave 触发时调用' }, propType: 'func', }, { name: 'onDragOver', title: { label: 'dragover 触发时调用', tip: 'dragover 触发时调用' }, propType: 'func', }, { name: 'onDragStart', title: { label: '开始拖拽时调用', tip: '开始拖拽时调用' }, propType: 'func', }, { name: 'onDrop', title: { label: 'drop 触发时调用', tip: 'drop 触发时调用' }, propType: 'func', }, { name: 'onExpand', title: { label: '展开/收起节点时触发', tip: '展开/收起节点时触发' }, propType: 'func', }, { name: 'onLoad', title: { label: '节点加载完毕时触发', tip: '节点加载完毕时触发' }, propType: 'func', }, { name: 'onRightClick', title: { label: '响应右键点击', tip: '响应右键点击' }, propType: 'func', }, { name: 'onSelect', title: { label: '点击树节点触发', tip: '点击树节点触发' }, propType: 'func', }, { name: 'icon', title: { label: '自定义树节点图标', tip: '自定义树节点图标' }, propType: { type: 'oneOfType', value: ['node', 'func'] }, }, ], configure: { supports: { style: true, events: [ { name: 'onCheck', template: "onCheck(checkedKeys,event,${extParams}){\n// 点击复选框触发\nconsole.log('onCheck',checkedKeys,event);}", }, { name: 'onDragEnd', template: "onDragEnd({event,node},${extParams}){\n// dragend 触发时调用\nconsole.log('onDragEnd',event,node);}", }, { name: 'onDragEnter', template: "onDragEnter({event,node,expandedKeys},${extParams}){\n// dragenter 触发时调用\nconsole.log('onDragEnter',event,node,expandedKeys);}", }, { name: 'onDragLeave', template: "onDragLeave({event,node},${extParams}){\n// dragleave 触发时调用\nconsole.log('onDragLeave',event,node);}", }, { name: 'onDragOver', template: "onDragOver({event,node},${extParams}){\n// dragover 触发时调用\nconsole.log('onDragOver',event,node);}", }, { name: 'onDragStart', template: "onDragStart({event,node},${extParams}){\n// 开始拖拽时调用\nconsole.log('onDragStart',event,node);}", }, { name: 'onDrop', template: "onDrop({event,node,dragNode,dragNodesKeys},${extParams}){\n// drop 触发时调用\nconsole.log('onDrop',event,node,dragNode,dragNodesKeys);}", }, { name: 'onExpand', template: "onExpand(expandedKeys,{expanded,node},${extParams}){\n// 展开/收起节点时触发\nconsole.log('onExpand',expandedKeys,expanded,node);}", }, { name: 'onLoad', template: "onLoad(loadedKeys,{event,node},${extParams}){\n// 节点加载完毕时触发\nconsole.log('onLoad',loadedKeys,event,node);}", }, { name: 'onRightClick', template: "onRightClick({event,node},${extParams}){\n// 响应右键点击\nconsole.log('onRightClick',event,node);}", }, { name: 'onSelect', template: "onSelect(selectedKeys,event,${extParams}){\n// 点击树节点触发\nconsole.log('onSelect',selectedKeys,event);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/tree/snippets.ts ================================================ export default [ { title: '树形控件', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/tree-1.jpg', schema: { componentName: 'Tree', props: { treeData: [ { title: 'parent 0', key: '0-0', children: [ { title: 'leaf 0-0', key: '0-0-0', isLeaf: true }, { title: 'leaf 0-1', key: '0-0-1', isLeaf: true }, ], }, { title: 'parent 1', key: '0-1', children: [ { title: 'leaf 1-0', key: '0-1-0', isLeaf: true }, { title: 'leaf 1-1', key: '0-1-1', isLeaf: true }, ], }, ], defaultExpandAll: true, }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/tree-select/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'TreeSelect', title: '树选择', category: '表单', props: [ { name: 'treeData', title: { label: '数据源', tip: '数据源' }, setter: 'JsonSetter', }, { name: 'defaultValue', title: { label: '默认值', tip: '默认选中值' }, propType: { type: 'oneOfType', value: ['string', { type: 'arrayOf', value: 'string' }], }, }, { name: 'value', title: { label: '当前值', tip: '当前值' }, propType: { type: 'oneOfType', value: ['string', { type: 'arrayOf', value: 'string' }], }, }, { name: 'allowClear', title: { label: '支持清除', tip: '是否允许清除' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'autoClearSearchValue', title: { label: '自动清空搜索', tip: '当多选模式下值被选择,自动清空搜索框', }, propType: 'bool', defaultValue: true, setter: 'BoolSetter' }, { name: 'bordered', title: { label: '显示边框', tip: '是否显示边框' }, propType: 'bool', defaultValue: true, setter: 'BoolSetter' }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, // { // name: 'dropdownClassName', // title: { // label: '下拉菜单的 className 属性', // tip: '下拉菜单的 className 属性', // }, // propType: 'string', // }, { name: 'dropdownMatchSelectWidth', title: { label: '下拉列表同款', tip: '下拉菜单和选择器同宽', }, propType: 'bool', setter: 'BoolSetter' }, // { // name: 'dropdownStyle', // title: { label: '下拉菜单的样式', tip: '下拉菜单的样式' }, // setter: 'JsonSetter', // }, { name: 'filterTreeNode', title: { label: '筛选节点', tip: '是否根据输入项进行筛选,默认用 treeNodeFilterProp 的值作为要筛选的 TreeNode 的属性值', }, propType: { type: 'oneOfType', value: ['bool', 'func'] }, }, { name: 'labelInValue', title: { label: '值包含标签', tip: '是否把每个选项的 label 包装到 value 中,会把 value 类型从 `string` 变为 {value: string, label: ReactNode, halfChecked(treeCheckStrictly 时有效): string[] } 的格式', }, propType: 'bool', defaultValue: true, setter: 'BoolSetter' }, { name: 'listHeight', title: { label: '设置弹窗滚动高度', tip: '设置弹窗滚动高度' }, propType: 'number', setter: 'NumberSetter' }, { name: 'loadData', title: { label: '异步加载数据', tip: '异步加载数据' }, propType: 'func', }, { name: 'maxTagCount', title: { label: '最多显示多少个 tag', tip: '最多显示多少个 tag' }, propType: 'number', setter: 'NumberSetter' }, { name: 'maxTagPlaceholder', title: { label: '隐藏 tag 时显示的内容', tip: '隐藏 tag 时显示的内容' }, propType: { type: 'oneOfType', value: ['node', 'func'] }, }, { name: 'multiple', title: { label: '支持多选', tip: '支持多选(当设置 treeCheckable 时自动变为 true)', }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'placeholder', title: { label: '选择框默认文字', tip: '选择框默认文字' }, propType: 'string', setter: 'StringSetter' }, { name: 'showCheckedStrategy', title: { label: '定义选中项回填的方式', tip: '定义选中项回填的方式。`SHOW_ALL`: 显示所有选中节点(包括父节点)。`SHOW_PARENT`: 只显示父节点(当父节点下所有子节点都选中时)。 默认只显示子节点', }, propType: { type: 'oneOf', value: ['SHOW_ALL', 'SHOW_PARENT', 'SHOW_CHILD'], }, }, { name: 'showSearch', title: { label: '是否支持搜索框', tip: '是否支持搜索框' }, propType: 'bool', setter: 'BoolSetter' }, { name: 'size', title: { label: '尺寸', tip: '选择框大小' }, propType: { type: 'oneOf', value: ['large', 'middle', 'small'] }, setter: { componentName: 'SelectSetter', props: { options: [ { title: '大', value: 'large', }, { title: '中', value: 'middle', }, { title: '小', value: 'small', }, ], }, }, defaultValue: 'middle', }, { name: 'showArrow', title: { label: '下拉图标', tip: '是否显示下拉图标,单选模式下默认 `true`', }, propType: 'bool', setter: 'BoolSetter' }, // { // name: 'suffixIcon', // title: { // label: // '暂废--自定义的选择框后缀图标, 多选模式下必须同时设置 `showArrow` 为 true', // tip: // '暂废--自定义的选择框后缀图标, 多选模式下必须同时设置 `showArrow` 为 true', // }, // propType: 'node', // }, { name: 'treeCheckable', title: { label: '显示勾选框', tip: '显示勾选框' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'treeDefaultExpandAll', title: { label: '默认展开所有树节点', tip: '默认展开所有树节点' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter' }, { name: 'treeDefaultExpandedKeys', title: { label: '默认展开的树节点', tip: '默认展开的树节点' }, propType: { type: 'arrayOf', value: 'string' }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'StringSetter', } } } }, { name: 'treeExpandedKeys', title: { label: '设置展开的树节点', tip: '设置展开的树节点' }, propType: { type: 'arrayOf', value: 'string' }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'StringSetter', } } } }, { name: 'virtual', title: { label: '设置 false 时关闭虚拟滚动', tip: '设置 false 时关闭虚拟滚动', }, propType: 'bool', defaultValue: true, setter: 'BoolSetter' }, { name: 'onChange', title: { label: '选中树节点时调用此函数', tip: '选中树节点时调用此函数' }, propType: 'func', }, { name: 'onSearch', title: { label: '文本框值变化时回调', tip: '文本框值变化时回调' }, propType: 'func', }, { name: 'onSelect', title: { label: '被选中时调用', tip: '被选中时调用' }, propType: 'func', }, { name: 'onTreeExpand', title: { label: '展示节点时调用', tip: '展示节点时调用' }, propType: 'func', }, ], configure: { supports: { style: true, events: [ { name: 'onChange', template: "onChange(value,label,extra,${extParams}){\n// 选中树节点时调用此函数\nconsole.log('onChange',value,label,extra);}", }, { name: 'onSearch', template: "onSearch(value,${extParams}){\n// 文本框值变化时回调\nconsole.log('onSearch',value);}", }, { name: 'onSelect', template: "onSelect(value,node,extra,${extParams}){\n// 被选中时调用\nconsole.log('onSelect',value,node,extra);}", }, { name: 'onTreeExpand', template: "onTreeExpand(expandedKeys,${extParams}){\n// 展示节点时调用\nconsole.log('onTreeExpand',expandedKeys);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/tree-select/snippets.ts ================================================ export default [ { title: '树选择', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/tree-select-1.png', schema: { componentName: 'TreeSelect', props: { treeData: [ { title: 'parent 0', value: '0-0', children: [ { title: 'leaf 0-0', value: '0-0-0', isLeaf: true }, { title: 'leaf 0-1', value: '0-0-1', isLeaf: true }, ], }, { title: 'parent 1', value: '0-1', children: [ { title: 'leaf 1-0', value: '0-1-0', isLeaf: true }, { title: 'leaf 1-1', value: '0-1-1', isLeaf: true }, ], }, ], treeDefaultExpandAll: true, placeholder: '请选择', style: { width: '300px', }, }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/typography.link/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Typography.Link', title: '链接', category: '基础', props: [ { name: 'children', title: { label: '内容', tip: '内容' }, propType: 'string', defaultValue: '', supportVariable: true, }, { name: 'href', title: { label: '跳转链接', tip: '跳转链接' }, propType: 'string', defaultValue: '', }, { name: 'target', title: { label: '跳转位置', tip: '在何处显示链接的资源' }, propType: { type: 'oneOf', value: ['_self', '_blank', '_parent', '_top'], }, defaultValue: '_self', }, ], configure: { supports: { style: true } }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/typography.link/snippets.ts ================================================ export default [ { title: '链接', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/typography-link-1.png', schema: { componentName: 'Typography.Link', props: { href: 'https://alibaba.com', target: '_blank', children: '链接', }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/typography.paragraph/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Typography.Paragraph', title: '段落', category: '基础', props: [ { name: 'children', title: { label: '内容', tip: '内容' }, propType: 'string', defaultValue: '', supportVariable: true, }, { name: 'code', title: { label: '添加代码样式', tip: '添加代码样式' }, propType: 'bool', defaultValue: false, }, { name: 'copyable', title: { label: '是否可拷贝', tip: '是否可拷贝,为对象时可进行各种自定义', }, propType: 'bool', defaultValue: false, }, { name: 'delete', title: { label: '添加删除线样式', tip: '添加删除线样式' }, propType: 'bool', defaultValue: false, }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态' }, propType: 'bool', defaultValue: false, }, { name: 'editable', title: { label: '是否可编辑', tip: '是否可编辑' }, propType: 'bool', defaultValue: false, }, { name: 'ellipsis', title: { label: '自动溢出省略', tip: '自动溢出省略' }, propType: 'bool', defaultValue: false, }, { name: 'mark', title: { label: '添加标记样式', tip: '添加标记样式' }, propType: 'bool', defaultValue: false, }, { name: 'underline', title: { label: '添加下划线样式', tip: '添加下划线样式' }, propType: 'bool', defaultValue: false, }, { name: 'onChange', title: { label: '当用户提交编辑内容时触发', tip: '当用户提交编辑内容时触发', }, propType: 'func', }, { name: 'strong', title: { label: '是否加粗', tip: '是否加粗' }, propType: 'bool', defaultValue: false, }, { name: 'type', title: { label: '文本类型', tip: '文本类型' }, propType: { type: 'oneOf', value: ['default', 'secondary', 'success', 'warning', 'danger'], }, setter: { componentName: 'SelectSetter', props: { options: [ { title: '默认', value: 'default', }, { title: '弱提示', value: 'secondary', }, { title: '成功', value: 'success', }, { title: '警告', value: 'warning', }, { title: '错误', value: 'danger', }, ], }, }, }, ], configure: { supports: { style: true, events: ['onChange'] } }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/typography.paragraph/snippets.ts ================================================ export default [ { title: '段落', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/typography-paragraph-1.png', schema: { componentName: 'Typography.Paragraph', props: { ellipsis: true, children: '蚂蚁的企业级产品是一个庞大且复杂的体系。这类产品不仅量级巨大且功能复杂,而且变动和并发频繁,常常需要设计与开发能够快速的做出响应。同时这类产品中有存在很多类似的页面以及组件,可以通过抽象得到一些稳定且高复用性的内容。', }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/typography.text/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Typography.Text', title: '文本', category: '基础', props: [ { name: 'children', title: { label: '内容', tip: '内容' }, propType: 'string', defaultValue: '', supportVariable: true, }, { name: 'code', title: { label: '添加代码样式', tip: '添加代码样式' }, propType: 'bool', defaultValue: false, }, { name: 'delete', title: { label: '添加删除线样式', tip: '添加删除线样式' }, propType: 'bool', defaultValue: false, }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态' }, propType: 'bool', defaultValue: false, }, { name: 'mark', title: { label: '添加标记样式', tip: '添加标记样式' }, propType: 'bool', defaultValue: false, }, { name: 'keyboard', title: { label: '添加键盘样式', tip: '添加键盘样式' }, propType: 'bool', defaultValue: false, }, { name: 'underline', title: { label: '添加下划线样式', tip: '添加下划线样式' }, propType: 'bool', defaultValue: false, }, { name: 'strong', title: { label: '是否加粗', tip: '是否加粗' }, propType: 'bool', defaultValue: false, }, { name: 'type', title: { label: '文本类型', tip: '文本类型' }, propType: { type: 'oneOf', value: ['secondary', 'warning', 'danger'] }, setter: { componentName: 'SelectSetter', props: { options: [ { title: '默认', value: 'default', }, { title: '弱提示', value: 'secondary', }, { title: '成功', value: 'success', }, { title: '警告', value: 'warning', }, { title: '错误', value: 'danger', }, ], }, }, }, { title: '高级', type: 'group', display: 'accordion', items: [ { name: 'copyable', title: { label: '是否可拷贝', tip: '是否可拷贝' }, propType: { type: 'oneOfType', value: ['bool', 'object'] }, setter: [ { componentName: 'BoolSetter', isRequired: false, initialValue: false, }, { componentName: 'JsonSetter', isRequired: false, }, ], }, { name: 'editable', title: { label: '是否可编辑', tip: '是否可编辑' }, propType: { type: 'oneOfType', value: ['bool', 'object'] }, setter: [ { componentName: 'BoolSetter', isRequired: false, initialValue: false, }, { componentName: 'JsonSetter', isRequired: false, }, ], }, { name: 'ellipsis', title: { label: '自动溢出省略', tip: '设置自动溢出省略,需要设置元素宽度', }, propType: { type: 'oneOfType', value: ['bool', 'object'] }, setter: [ { componentName: 'BoolSetter', isRequired: false, initialValue: false, }, { componentName: 'JsonSetter', isRequired: false, }, ], }, ], }, ], configure: { supports: { style: true, events: [ { name: 'copyable.onCopy', template: "onCopy(${extParams}){\n// 拷贝成功的回调函数\nconsole.log('onCopy');}", }, { name: 'editable.onStart', template: "onStart(${extParams}){\n// 进入编辑中状态时触发\nconsole.log('onStart');}", }, { name: 'editable.onChange', template: "onChange(event,${extParams}){\n// 文本域编辑时触发\nconsole.log('onChange', event);}", }, { name: 'editable.onEnd', template: "onEnd(${extParams}){\n// 按 ENTER 结束编辑状态时触发\nconsole.log('onEnd');}", }, { name: 'editable.onCancel', template: "onCancel(${extParams}){\n// 按 ESC 退出编辑状态时触发\nconsole.log('onCancel');}", }, { name: 'ellipsis.onEllipsis', template: "onEllipsis(ellipsis,${extParams}){\n// 触发省略时的回调\nconsole.log('onEllipsis', ellipsis);}", }, { name: 'ellipsis.onExpand', template: "onExpand(event,${extParams}){\n// 点击展开时的回调\nconsole.log('onExpand', event);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/typography.text/snippets.ts ================================================ export default [ { title: '文本', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/typography-text-1.png', schema: { componentName: 'Typography.Text', props: { children: 'text', }, }, }, { title: '可复制文本', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/typography-text-2.png', schema: { componentName: 'Typography.Text', props: { copyable: true, children: 'text', }, }, }, { title: '可编辑文本', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/typography-text-3.png', schema: { componentName: 'Typography.Text', props: { editable: true, children: 'text', }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/typography.title/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Typography.Title', title: '标题', category: '基础', props: [ { name: 'children', title: { label: '内容', tip: '内容' }, propType: 'string', defaultValue: '', supportVariable: true, }, { name: 'level', title: { label: '重要程度', tip: '重要程度(1-5)' }, propType: 'number', defaultValue: 1, }, { name: 'code', title: { label: '添加代码样式', tip: '添加代码样式' }, propType: 'bool', defaultValue: false, }, { name: 'copyable', title: { label: '是否可拷贝', tip: '是否可拷贝' }, propType: 'bool', defaultValue: false, }, { name: 'delete', title: { label: '添加删除线样式', tip: '添加删除线样式' }, propType: 'bool', defaultValue: false, }, { name: 'disabled', title: { label: '是否禁用', tip: '是否为禁用状态' }, propType: 'bool', defaultValue: false, }, { name: 'editable', title: { label: '是否可编辑', tip: '是否可编辑' }, propType: 'bool', defaultValue: false, }, { name: 'ellipsis', title: { label: '自动溢出省略', tip: '设置自动溢出省略,需要设置元素宽度', }, propType: 'bool', defaultValue: false, }, { name: 'mark', title: { label: '添加标记样式', tip: '添加标记样式' }, propType: 'bool', defaultValue: false, }, { name: 'keyboard', title: { label: '添加键盘样式', tip: '添加键盘样式' }, propType: 'bool', defaultValue: false, }, { name: 'underline', title: { label: '添加下划线样式', tip: '添加下划线样式' }, propType: 'bool', defaultValue: false, }, { name: 'strong', title: { label: '是否加粗', tip: '是否加粗' }, propType: 'bool', defaultValue: false, }, { name: 'type', title: { label: '文本类型', tip: '文本类型' }, propType: { type: 'oneOf', value: ['secondary', 'warning', 'danger'] }, setter: { componentName: 'SelectSetter', props: { options: [ { title: '默认', value: 'default', }, { title: '弱提示', value: 'secondary', }, { title: '成功', value: 'success', }, { title: '警告', value: 'warning', }, { title: '错误', value: 'danger', }, ], }, }, }, ], configure: { supports: { style: true } }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/typography.title/snippets.ts ================================================ export default [ { title: '一级标题', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/typography-title-1.png', schema: { componentName: 'Typography.Title', props: { level: 1, children: '一级标题', }, }, }, { title: '二级标题', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/typography-title-2.png', schema: { componentName: 'Typography.Title', props: { level: 2, children: '二级标题', }, }, }, { title: '三级标题', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/typography-title-3.png', schema: { componentName: 'Typography.Title', props: { level: 3, children: '三级标题', }, }, }, { title: '四级标题', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/typography-title-4.png', schema: { componentName: 'Typography.Title', props: { level: 4, children: '四级标题', }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/lowcode/upload/meta.ts ================================================ import snippets from './snippets'; export default { snippets, componentName: 'Upload', title: '上传', category: '表单', props: [ { title: '基本', display: 'block', type: 'group', items: [ { name: 'defaultFileList', title: { label: '默认上传文件', tip: 'defaultFileList | 默认已经上传的文件列表', }, propType: { type: 'arrayOf', value: 'object' }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'name', title: '文件名', setter: 'StringSetter', }, { name: 'status', title: '状态', setter: { componentName: 'SelectSetter', props: { options: [ 'error', 'success', 'done', 'uploading', 'removed', ].map((v) => ({ label: v, value: v })), }, }, }, { name: 'url', title: '下载地址', setter: 'StringSetter', }, { name: 'url', title: '下载地址', setter: 'StringSetter', }, { name: 'response', title: '错误信息', setter: 'StringSetter', }, ], }, }, }, }, }, }, { name: 'fileList', title: { label: '当前上传文件', tip: 'fileList | 当前上传的文件列表(受控)', }, propType: { type: 'arrayOf', value: 'object' }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'name', title: '文件名', setter: 'StringSetter', }, { name: 'status', title: '状态', setter: { componentName: 'SelectSetter', props: { options: [ 'error', 'success', 'done', 'uploading', 'removed', ].map((v) => ({ label: v, value: v })), }, }, }, { name: 'url', title: '下载地址', setter: 'StringSetter', }, { name: 'url', title: '下载地址', setter: 'StringSetter', }, { name: 'response', title: '错误信息', setter: 'StringSetter', }, ], }, }, }, }, }, }, { name: 'multiple', title: { label: '支持多选文件', tip: 'multiple | 是否支持多选文件,`ie10+` 支持。开启后按住 ctrl 可选择多个文件', }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', }, { name: 'maxCount', title: { label: '上传数量限制', tip: 'maxCount | 限制上传数量。当为 1 时,始终用最新上传的文件代替当前文件', }, propType: 'number', setter: 'NumberSetter', }, { name: 'accept', title: { label: '上传文件类型', tip: 'accept | 接受上传的文件类型, 例如 .doc,.docx,application/msword', }, propType: 'string', setter: 'StringSetter', }, { name: 'directory', title: { label: '文件夹上传', tip: 'directory | 支持上传文件夹', }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', }, { name: 'disabled', title: { label: '是否禁用', tip: 'disabled | 是否为禁用状态' }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', }, ], }, { title: '高级', display: 'block', type: 'group', items: [ { name: 'openFileDialogOnClick', title: { label: '打开文件对话框', tip: 'openFileDialogOnClick | 点击打开文件对话框', }, propType: 'bool', defaultValue: true, setter: 'BoolSetter', }, { name: 'showUploadList', title: { label: '显示上传列表', tip: 'showUploadList | 是否显示上传的文件列表,', }, propType: 'bool', defaultValue: true, setter: 'BoolSetter', }, { name: 'listType', title: { label: '上传列表样式', tip: 'listType | 上传列表的内建样式,支持三种基本样式 `text`, `picture` 和 `picture-card`', }, propType: { type: 'oneOf', value: ['text', 'picture', 'picture-card'], }, defaultValue: 'text', setter: [ { componentName: 'RadioGroupSetter', props: { options: [ { title: '文本', value: 'text', }, { title: '图片', value: 'picture', }, { title: '图片卡片', value: 'picture-card', }, ], }, }, 'VariableSetter', ], }, { name: 'iconRender', title: { label: '自定义图标', tip: 'iconRender | 自定义显示 icon' }, propType: 'func', setter: { componentName: 'SlotSetter', title: '自定义图标插槽', initialValue: { type: 'JSSlot', params: ['file', 'listType'], value: [], }, }, }, { name: 'itemRender', title: { label: '自定义列表项', tip: 'itemRender | 自定义上传列表项', }, propType: 'func', setter: { componentName: 'SlotSetter', title: '自定义列表项插槽', initialValue: { type: 'JSSlot', params: ['originNode', 'file', 'fileList', 'actions'], value: [], }, }, }, { name: 'progress', title: { label: '自定义进度条', tip: 'progress | 自定义进度条样式' }, propType: 'object', setter: 'JsonSetter', }, ], }, { title: '上传参数', display: 'block', type: 'group', items: [ { name: 'action', title: { label: '上传地址', tip: 'action | 上传的地址或方法' }, propType: { type: 'oneOfType', value: ['string', 'func'] }, setter: ['StringSetter', 'FunctionSetter', 'VariableSetter'], }, { name: 'name', title: { label: '文件参数名', tip: 'name | 发到后台的文件参数名' }, propType: 'string', setter: 'StringSetter', }, { name: 'method', title: { label: '请求Method', tip: 'method | 上传请求的 http method', }, propType: { type: 'oneOf', value: ['get', 'post', 'put', 'head', 'options', 'patch', 'delete'], }, defaultValue: 'post', setter: 'StringSetter', }, { name: 'headers', title: { label: '上传请求头', tip: 'headers | 设置上传的请求头部,IE10 以上有效', }, propType: 'object', setter: 'JsonSetter', }, { name: 'withCredentials', title: { label: '携带Cookie', tip: 'withCredentials | 上传请求时是否携带 cookie', }, propType: 'bool', defaultValue: false, setter: 'BoolSetter', }, { name: 'data', title: { label: '额外参数', tip: 'data | 上传所需额外参数或返回上传额外参数的方法', }, propType: { type: 'oneOfType', value: ['object', 'func'] }, setter: [ 'JsonSetter', { componentName: 'FunctionSetter', props: { template: 'onData(file,${extParams}){\n// 上传所需额外参数\nreturn {};\n}', }, }, 'VariableSetter', ], }, ], }, { title: '回调函数', display: 'block', type: 'group', items: [ { name: 'beforeUpload', title: { label: '上传前回调', tip: 'beforeUpload | 上传文件之前的回调函数', }, propType: 'func', setter: { componentName: 'FunctionSetter', props: { template: 'beforeUpload(file,fileList,${extParams}){\n// 上传文件之前的钩子\nreturn false;\n}', }, }, }, { name: 'customRequest', title: { label: '自定义上传', tip: 'customRequest | 通过覆盖默认的上传行为,可以自定义自己的上传实现', }, propType: 'func', setter: 'FunctionSetter', }, { name: 'isImageUrl', title: { label: '是否为图片', tip: 'isImageUrl | 自定义缩略图是否使用 标签进行显示', }, propType: 'func', setter: { componentName: 'FunctionSetter', props: { template: 'isImageUrl(file,${extParams}){\n// 判断是否为图片\nreturn true;\n}', }, }, }, { name: 'previewFile', title: { label: '自定义文件预览', tip: 'previewFile | 自定义文件预览逻辑', }, propType: 'func', setter: 'FunctionSetter', }, ], }, ], configure: { component: { isContainer: true }, supports: { style: true, events: [ { name: 'onChange', template: "onChange({file,fileList,event},${extParams}){\n// 上传文件改变时的回调\nconsole.log('onChange',file,fileList,event);}", }, { name: 'onPreview', template: "onPreview(file,${extParams}){\n// 点击文件链接或预览图标时的回调\nconsole.log('onPreview',file);}", }, { name: 'onRemove', template: "onRemove(file,${extParams}){\n// 点击移除文件时的回调\nconsole.log('onRemove',file);}", }, { name: 'onDownload', template: "onDownload(file,${extParams}){\n// 点击下载文件时的回调\nconsole.log('onDownload',file);}", }, ], }, }, }; ================================================ FILE: packages/antd-lowcode-materials/lowcode/upload/snippets.ts ================================================ export default [ { title: '上传', screenshot: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/upload-1.png', schema: { componentName: 'Upload', props: {}, children: { componentName: 'Button', props: { children: 'Upload', }, }, }, }, ]; ================================================ FILE: packages/antd-lowcode-materials/package.json ================================================ { "name": "@alilc/antd-lowcode-materials", "version": "1.2.2", "description": "Antd for LowCode", "main": "lib/index.js", "scripts": { "build": "build-scripts build", "lowcode:dev": "build-scripts start --config ./build.lowcode.js", "lowcode:build": "build-scripts build --config ./build.lowcode.js", "prepublishOnly": "npm run build && npm run lowcode:build" }, "files": [ "es/", "lib/", "dist/", "build/", "lowcode/", "lowcode_lib/", "lowcode_es/" ], "devDependencies": { "@alib/build-scripts": "^0.1.23", "@alifd/build-plugin-lowcode": "^0.4.0", "@ant-design/icons": "^4.7.0", "@types/lodash": "^4.14.181", "@types/react": "^18.0.1", "@types/react-dom": "^18.0.0", "build-plugin-component": "^1.10.0", "build-plugin-moment-locales": "^0.1.0", "lodash": "^4.17.21", "react": "^17.0.1", "react-dom": "^17.0.1", "style-loader": "^2.0.0", "tsconfig-paths-webpack-plugin": "^3.3.0", "typescript": "^3.9.3", "yorkie": "^2.0.0" }, "authors": [ { "name": "莫夭" }, { "name": "金禅" } ], "dependencies": { "@ant-design/icons": "^4.6.2", "antd": "^4.24.7", "moment": "^2.29.1", "@babel/runtime": "^7.0.0" }, "peerDependencies": { "react": "^16.0.0", "react-dom": "^16.0.0" }, "componentConfig": { "materialSchema": "https://alifd.alicdn.com/npm/@alilc/antd-lowcode-materials@1.2.2/build/lowcode/assets-prod.json" }, "license": "MIT", "homepage": "https://unpkg.com/@alilc/antd-lowcode-materials@1.2.2/build/index.html", "repository": "https://github.com/alibaba/lowcode-materials.git", "exports": { "./prototype": { "require": "./lowcode_lib/meta.js", "import": "./lowcode_es/meta.js" }, "./prototypeView": { "require": "./lowcode_lib/view.js", "import": "./lowcode_es/view.js" }, "./*": "./*", ".": { "import": "./es/index.js", "require": "./lib/index.js" } }, "lcMeta": { "type": "component" } } ================================================ FILE: packages/antd-lowcode-materials/src/components/auto-complete/index.tsx ================================================ import { AutoComplete as OriginalAutoComplete } from 'antd'; import { withWrap } from '../../utils/hoc'; const AutoComplete = withWrap(OriginalAutoComplete); export default AutoComplete; ================================================ FILE: packages/antd-lowcode-materials/src/components/button/index.tsx ================================================ import React, { forwardRef, Ref } from 'react'; import { Button as OriginalButton } from 'antd'; const Button: any = (props: any, ref: Ref) => { const innerProps: any = {}; if (!props.href?.trim() || props.__designMode === 'design') { // 解决低代码编辑器中按钮设置href属性造成按钮点击重定向问题 innerProps.href = undefined; } return ; }; export default forwardRef(Button); ================================================ FILE: packages/antd-lowcode-materials/src/components/calendar/index.tsx ================================================ import { Calendar as OriginalCalendar } from 'antd'; import { withMomentProps } from '../../utils/hoc'; const Calendar = withMomentProps(OriginalCalendar, [ 'defaultValue', 'validRange', 'value.defaultValue', ]); export default Calendar; ================================================ FILE: packages/antd-lowcode-materials/src/components/cascader/index.tsx ================================================ import { Cascader as OriginalCascader } from 'antd'; import { withWrap } from '../../utils/hoc'; const Cascader = withWrap(OriginalCascader); export default Cascader; ================================================ FILE: packages/antd-lowcode-materials/src/components/checkbox/index.tsx ================================================ import { Checkbox as OriginalCheckbok } from 'antd'; import { withWrap } from '../../utils/hoc'; const Checkbox = withWrap(OriginalCheckbok); (Checkbox as any).Group = OriginalCheckbok.Group; export default Checkbox; ================================================ FILE: packages/antd-lowcode-materials/src/components/config-provider/index.tsx ================================================ import React from 'react'; import { ConfigProvider as OriginalConfigProvider } from 'antd'; import moment from 'moment'; import 'moment/locale/zh-cn'; import zhCN from 'antd/es/locale/zh_CN'; const ConfigProvider = (props: any) => { const { locale, ...rest } = props; let localeData = locale; if (typeof locale === 'string') { if (locale.toLowerCase() === 'zh-cn') { moment.locale('zh-cn'); localeData = zhCN; } else if (locale.toLowerCase() === 'en-us') { moment.locale('en'); // 默认为英文 localeData = undefined; } } return ; }; export default ConfigProvider; ================================================ FILE: packages/antd-lowcode-materials/src/components/date-picker/index.tsx ================================================ import { DatePicker as OriginalDatePicker } from 'antd'; import { withMomentProps } from '../../utils/hoc'; const OriginalRangePicker = OriginalDatePicker.RangePicker; const DatePicker = withMomentProps(OriginalDatePicker, [ 'defaultPickerValue', 'defaultValue', 'showTime.defaultValue', 'value', ]); const RangePicker = withMomentProps(OriginalRangePicker, [ 'defaultPickerValue', 'defaultValue', 'showTime.defaultValue', 'value', ]); (DatePicker as any).RangePicker = RangePicker; export default DatePicker; ================================================ FILE: packages/antd-lowcode-materials/src/components/drawer/index.tsx ================================================ import React from 'react'; import { Drawer as OriginalDrawer } from 'antd'; const Drawer: any = (props: any) => { const innerProps: any = {}; if (props.__designMode === 'design') { // 低代码编辑态中强制显示,将控制权交给引擎侧 innerProps.open = true; } return ; }; export default Drawer; ================================================ FILE: packages/antd-lowcode-materials/src/components/dropdown/index.tsx ================================================ import React from 'react'; import { Dropdown as OriginalDropdown } from 'antd'; import { withSingleChild } from '../../utils/hoc'; const Dropdown: any = (props: any) => { const innerProps: any = {}; if (props.__designMode === 'design') { // 低代码编辑态中强制显示,将控制权交给引擎侧 innerProps.open = true; } return ; }; export default withSingleChild(Dropdown, ['children', 'overlay']); ================================================ FILE: packages/antd-lowcode-materials/src/components/form/index.tsx ================================================ import React, { Component, createRef } from 'react'; import { Form as OriginalForm } from 'antd'; import { withSingleFunctionChild } from '../../utils/hoc'; class Form extends Component { formRef = createRef(); componentDidUpdate(prevProps: any) { const { values: prevValues } = prevProps; const { values: currentValues } = this.props; if (prevValues !== currentValues) { if (currentValues && Object.keys(currentValues).length > 0) { this.formRef.current!.setFieldsValue(currentValues); } else { this.formRef.current!.resetFields(); } } } componentDidMount() { const { values } = this.props; Object.defineProperties( this, Object.keys(this.formRef.current).reduce((out, key) => { const property = this.formRef.current[key]; let getter = () => property; if (typeof property === 'function') { getter = () => property.bind(this.formRef.current); } out[key] = { get: getter }; return out; }, {} as Record), ); // 绑定表达式的时候,初次不生效,需要第一次调用一下 setFieldsValue if (values) { this.formRef.current!.setFieldsValue(values); } } render() { const { values, ...rest } = this.props; return ; } } (Form as any).Item = (props: any) => { const { name, requiredobj, typeobj, patternobj, lenobj, validator } = props; const rules = []; if (requiredobj && requiredobj.required) { rules.push(requiredobj); } if (typeobj && typeobj.type) { rules.push(typeobj); } if (patternobj && patternobj.pattern) { rules.push(patternobj); } if (lenobj && (lenobj.max || lenobj.min)) { rules.push(lenobj); } if (validator && typeof validator === 'function') { rules.push({ validator: (_: any, value: any) => validator(value), }); } const namePath = typeof name === 'string' && name.indexOf('.') > 0 ? name.split('.') : name; // https://ant.design/components/form-cn/#components-form-demo-complex-form-control // 只会对它的直接子元素绑定表单功能 const { children, ...other } = props let node = children if (Array.isArray(children) && children.length === 1) { // 如果 children.length > 1, 说明 Form.Item 只充当布局的作用 node = children[0] } return ( { node } ); }; (Form as any).List = withSingleFunctionChild(OriginalForm.List); export default Form; ================================================ FILE: packages/antd-lowcode-materials/src/components/icon/index.tsx ================================================ import React, { forwardRef, Ref } from 'react'; import * as icons from '@ant-design/icons'; const createFromIconfontCN = icons.createFromIconfontCN; interface IconProps { type: string; className?: string; size?: number; color?: string; rotate?: number; spin?: boolean; style?: React.CSSProperties; } const Icon = (props: IconProps, ref: Ref) => { const { type = '', size, color, ...rest } = props; const IconComp = ((icons || {}) as any)[type]; const style = { ...rest.style, fontSize: size, color, }; if (!IconComp) { const IconFont = createFromIconfontCN(); return ; } return ; }; export default forwardRef(Icon); ================================================ FILE: packages/antd-lowcode-materials/src/components/input/index.tsx ================================================ import { Input as OriginalInput } from 'antd'; import { withWrap } from '../../utils/hoc'; const { Group: OriginalGroup, TextArea: OriginalTextArea, Password: OriginalPassword, Search: OriginalSearch, } = OriginalInput; const Input = withWrap(OriginalInput); (Input as any).Group = OriginalGroup; (Input as any).TextArea = withWrap(OriginalTextArea); (Input as any).Password = withWrap(OriginalPassword); (Input as any).Search = withWrap(OriginalSearch); export default Input; ================================================ FILE: packages/antd-lowcode-materials/src/components/modal/index.tsx ================================================ import React from 'react'; import { Modal as OriginalModal } from 'antd'; const Modal: any = (props: any) => { const innerProps: any = {}; if (props.__designMode === 'design') { // 低代码编辑态中强制显示,将控制权交给引擎侧 innerProps.open = true; } return ; }; Modal.info = OriginalModal.info; Modal.success = OriginalModal.success; Modal.error = OriginalModal.error; Modal.warning = OriginalModal.warning; Modal.warn = OriginalModal.warn; Modal.confirm = OriginalModal.confirm; export default Modal; ================================================ FILE: packages/antd-lowcode-materials/src/components/popover/index.tsx ================================================ import React from 'react'; import { Popover as OriginalPopover } from 'antd'; interface PopoverProps { open?: boolean; } const Popover = (props: PopoverProps) => { return ; }; export default Popover; ================================================ FILE: packages/antd-lowcode-materials/src/components/radio/index.tsx ================================================ import { Radio as OriginalRadio } from 'antd'; import { withWrap } from '../../utils/hoc'; const Radio = withWrap(OriginalRadio); (Radio as any).Group = OriginalRadio.Group; export default Radio; ================================================ FILE: packages/antd-lowcode-materials/src/components/select/index.tsx ================================================ import { Select as OriginalSelect } from 'antd'; import { withWrap } from '../../utils/hoc'; const Select = withWrap(OriginalSelect); export default Select; ================================================ FILE: packages/antd-lowcode-materials/src/components/skeleton/index.tsx ================================================ import { Skeleton as OriginalSleleton } from 'antd'; import { withSingleChild } from '../../utils/hoc'; const Skeleton = withSingleChild(OriginalSleleton, ['children']); export default Skeleton; ================================================ FILE: packages/antd-lowcode-materials/src/components/slider/index.tsx ================================================ import React from 'react'; import { Slider } from 'antd'; const SliderOuter = (props: any) => { const { range } = props; let { defaultValue } = props; if (range) { defaultValue = Array.isArray(defaultValue) ? defaultValue : [0, defaultValue]; } else { defaultValue = Array.isArray(defaultValue) ? defaultValue[1] || defaultValue[0] : defaultValue; } return ; }; export default SliderOuter; ================================================ FILE: packages/antd-lowcode-materials/src/components/table/index.tsx ================================================ import React from 'react'; import { Table as OriginalTable } from 'antd'; const Table = (props: any) => { const columns = (props.columns || []).filter((item: any) => !item?.hidden); return ; }; export default Table; ================================================ FILE: packages/antd-lowcode-materials/src/components/tabs/index.tsx ================================================ import React, { Component } from 'react'; import { TabPaneProps, Tabs as OriginalTabs } from 'antd'; import { warning } from '../../utils/warning' import type { Tab } from 'rc-tabs/lib/interface'; class Tabs extends Component { state = { activeKey: this.props.activeKey ?? this.props.defaultActiveKey, }; private _handleChange = (key: string) => { this.setActiveKey(key); }; // 编辑器里可以通过 this.$(refId).setActiveKey(key) 调用 setActiveKey = (key: string) => { const { onChange = () => {} } = this.props; this.setState({ activeKey: key }); onChange(key); }; // 编辑器里可以通过 this.$(refId).getActiveKey() 调用 getActiveKey = () => { return this.state.activeKey; }; render() { const { props } = this; const { activeKey } = this.state; const { children } = props let items = props.items // props.items 存在,只认 props.items // 兼容代码:props.childrens 反推 props.items if (!props.items && Array.isArray(children) && children.length > 0) { warning('Tabs.TabPane is deprecated. Please use `items` directly.') items = children.map((node: React.ReactElement) => { if (React.isValidElement(node)) { const { key, props } = node; const { tab, ...restProps } = props || {}; const item: Tab = { key: String(key), ...restProps, label: tab, }; return item; } return null }).filter(Boolean) } return ( ); } } (Tabs as any).TabPane = OriginalTabs.TabPane; export default Tabs; ================================================ FILE: packages/antd-lowcode-materials/src/components/time-picker/index.tsx ================================================ import { TimePicker as OriginalTimePicker } from 'antd'; import { withMomentProps } from '../../utils/hoc'; const TimePicker = withMomentProps(OriginalTimePicker, [ 'defaultValue', 'value', ]); export default TimePicker; ================================================ FILE: packages/antd-lowcode-materials/src/components/tree-select/index.tsx ================================================ import React from 'react'; import { TreeSelect as OriginTreeSelect } from 'antd'; const TreeSelect: any = (props: any) => { return ; }; export default TreeSelect; ================================================ FILE: packages/antd-lowcode-materials/src/components/upload/index.tsx ================================================ import { Upload as OriginalUpload } from 'antd'; import { withSingleChild } from '../../utils/hoc'; const Upload = withSingleChild(OriginalUpload, ['children']); export default Upload; ================================================ FILE: packages/antd-lowcode-materials/src/index.scss ================================================ ================================================ FILE: packages/antd-lowcode-materials/src/index.tsx ================================================ export { Affix } from 'antd'; export { Anchor } from 'antd'; // export { AutoComplete } from 'antd'; export { Alert } from 'antd'; export { Avatar } from 'antd'; export { BackTop } from 'antd'; export { Badge } from 'antd'; export { Breadcrumb } from 'antd'; export { Card } from 'antd'; export { Collapse } from 'antd'; export { Carousel } from 'antd'; // export { Cascader } from 'antd'; // export { Checkbox } from 'antd'; export { Col } from 'antd'; export { Comment } from 'antd'; export { Descriptions } from 'antd'; export { Divider } from 'antd'; // export { Drawer } from 'antd'; export { Empty } from 'antd'; export { Grid } from 'antd'; // export { Input } from 'antd'; export { Image } from 'antd'; export { InputNumber } from 'antd'; export { List } from 'antd'; export { message } from 'antd'; export { Menu } from 'antd'; export { Mentions } from 'antd'; // export { Modal } from 'antd'; export { Statistic } from 'antd'; export { notification } from 'antd'; export { PageHeader } from 'antd'; export { Pagination } from 'antd'; export { Popconfirm } from 'antd'; export { default as Popover } from './components/popover'; export { Progress } from 'antd'; // export { Radio } from 'antd'; export { Rate } from 'antd'; export { Result } from 'antd'; export { Row } from 'antd'; export { Segmented } from 'antd'; // export { Skeleton } from 'antd'; export { Space } from 'antd'; export { Spin } from 'antd'; export { Steps } from 'antd'; export { Switch } from 'antd'; export { Transfer } from 'antd'; export { Tree } from 'antd'; // export { TreeSelect } from 'antd'; // export { Tabs } from 'antd'; export { Tag } from 'antd'; export { Timeline } from 'antd'; export { Tooltip } from 'antd'; export { Typography } from 'antd'; export { version } from 'antd'; export { default as Skeleton } from './components/skeleton'; export { default as Checkbox } from './components/checkbox'; export { default as Button } from './components/button'; export { default as Radio } from './components/radio'; export { default as Upload } from './components/upload'; export { default as Icon } from './components/icon'; export { default as Form } from './components/form'; export { default as Dropdown } from './components/dropdown'; export { default as Calendar } from './components/calendar'; export { default as ConfigProvider } from './components/config-provider'; export { default as DatePicker } from './components/date-picker'; export { default as Tabs } from './components/tabs'; export { default as TimePicker } from './components/time-picker'; export { default as Slider } from './components/slider'; export { default as Table } from './components/table'; export { default as Modal } from './components/modal'; export { default as Drawer } from './components/drawer'; export { default as TreeSelect } from './components/tree-select'; export { default as Input } from './components/input'; export { default as Select } from './components/select' export { default as Cascader } from './components/cascader'; export { default as AutoComplete } from './components/auto-complete'; ================================================ FILE: packages/antd-lowcode-materials/src/utils/hoc.tsx ================================================ import React, { ComponentType, forwardRef, Ref } from 'react'; import moment from 'moment'; import { get, set, has } from 'lodash'; function convertProps( props: Record, list: string[], mapper: (v: any, key: string) => any, ) { const out: Record = {}; list.forEach(key => { if (has(props, key)) { set(out, key, mapper(get(props, key), key)); } }); return out; } /** * 简单包装,不做任何处理 * 部分组件ref比较特殊,包一层会解决这个问题 */ export function withWrap(Comp: ComponentType) { return forwardRef((props: any, ref: Ref) => { return ; }); } /** * 某些组件会用React.Children.only检查子节点 * 需要做处理避免报错 */ export function withSingleChild( Comp: ComponentType, needsConvert = ['children'], ) { return (props: any) => { const convertedProps = convertProps(props, needsConvert, prop => { let node = React.Children.toArray(prop)[0]; if (node === null || typeof node !== 'object') { node =
{node}
; } return node; }); return ; }; } export function withSingleFunctionChild(Comp: ComponentType) { return (props: any) => { const { children } = props; let node; if (typeof children === 'function') { node = children; } if ( Array.isArray(children) && children.length === 1 && typeof children[0] === 'function' ) { node = children[0]; } if (node) { return {node}; } return
{children}
; }; } /** * moment对象在序列化后会被转为字符串 * 需要让日期类组件支持接受字符串值 */ export function withMomentProps( Comp: ComponentType, needsConvert = ['value', 'defaultValue'], ) { return (props: any) => { const convertedProps = convertProps(props, needsConvert, prop => { if (prop) { if (Array.isArray(prop)) { return prop.map(v => (moment.isMoment(v) ? v : moment(v))); } return moment.isMoment(prop) ? prop : moment(prop); } }); return ; }; } ================================================ FILE: packages/antd-lowcode-materials/src/utils/warning.ts ================================================ export const warning = (...args: any[]) => { console.warn(args) } ================================================ FILE: packages/fusion-lowcode-materials/HISTORY.md ================================================ ## 1.2.1 * `feat` 修改 NextTable Snippets 一些不合理的默认值 ================================================ FILE: packages/fusion-lowcode-materials/README.md ================================================

Fusion Design For Lowcode

[![NPM version][npm-image-fusion]][npm-url-fusion] ### [在线示例 / DEMO](https://alifd.alicdn.com/npm/@alilc/antd-lowcode-materials@1.2.2/build/lowcode/index.html) ### 使用 / Usage #### NPM ```js const { material } from '@alilc/lowcode-engine'; const assets = require('@alilc/lowcode-materials/dist/assets.json'); // in GeneralWorkbench init material.setAssets(assets); ``` #### CDN ```js // in GeneralWorkbench init const assets = await (await fetch(`https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.2.1/dist/assets.json`)).json(); material.setAssets(assets); ``` [npm-image-fusion]: https://img.shields.io/npm/v/@alilc/lowcode-materials.svg?style=flat-square [npm-url-fusion]: http://npmjs.org/package/@alilc/lowcode-materials ================================================ FILE: packages/fusion-lowcode-materials/build.json ================================================ { "library": "AlilcLowcodeMaterials", "libraryTarget": "umd", "sourceMap": false, "alias": { "@": "./src", "@components": "./src/components" }, "plugins": [ [ "build-plugin-component", { "themePackage": "@alifd/theme-2" } ], [ "build-plugin-fusion", { "uniteBaseComponent": "@alifd/next", "importOptions": { "libraryDirectory": "lib" } } ] ] } ================================================ FILE: packages/fusion-lowcode-materials/build.lowcode.js ================================================ const { name, version } = require('./package.json'); module.exports = { sourceMap: false, alias: { '@': './src', lowcode: './lowcode', }, plugins: [ [ '@alifd/build-plugin-lowcode', { noParse: true, builtinAssets: [ { packages: [ { package: 'moment', version: '2.24.0', urls: ['https://g.alicdn.com/mylib/moment/2.24.0/min/moment.min.js'], library: 'moment', }, { package: 'lodash', library: '_', urls: ['https://g.alicdn.com/platform/c/lodash/4.6.1/lodash.min.js'], }, { title: 'fusion组件库', package: '@alifd/next', version: '1.25.23', urls: [ 'https://g.alicdn.com/code/lib/alifd__next/1.25.23/next.min.css', 'https://g.alicdn.com/code/lib/alifd__next/1.25.23/next-with-locales.min.js', ], library: 'Next', }, ], components: [], }, ], baseUrl: { prod: `https://alifd.alicdn.com/npm/${name}@${version}`, daily: `https://alifd.alicdn.com/npm/${name}@${version}`, }, categories: ['通用', '导航', '信息输入', '信息展示', '信息反馈', '常用'], engineScope: '@alilc', }, ], [ 'build-plugin-fusion', { uniteBaseComponent: '@alifd/next', importOptions: { libraryDirectory: 'lib', }, }, ], './plugins/compatible.build.js', ], }; ================================================ FILE: packages/fusion-lowcode-materials/demo/Image.md ================================================ --- title: Image order: 2 --- 图片组件。 ```jsx import React, { Component } from 'react'; import ReactDOM from 'react-dom'; import { Image } from '@alilc/lowcode-materials'; class App extends Component { render() { return (
); } } ReactDOM.render(, mountNode); ``` ================================================ FILE: packages/fusion-lowcode-materials/demo/Link.md ================================================ --- title: Link order: 1 --- 超链接组件。 ```jsx import React, { Component } from 'react'; import ReactDOM from 'react-dom'; import { Link } from '@alilc/lowcode-materials'; class App extends Component { render() { return (
这是一个超链接
); } } ReactDOM.render(, mountNode); ``` ================================================ FILE: packages/fusion-lowcode-materials/demo/NoteWrapper.md ================================================ --- title: NoteWrapper order: 4 --- 备注容器组件 ```jsx import React, { Component } from 'react'; import ReactDOM from 'react-dom'; import { NoteWrapper } from '@alilc/lowcode-materials'; class App extends Component { render() { return (
hello world
); } } ReactDOM.render(, mountNode); ``` ================================================ FILE: packages/fusion-lowcode-materials/demo/RichText.md ================================================ --- title: RichText order: 3 --- 需求占位组件 ```jsx import React, { Component } from 'react'; import ReactDOM from 'react-dom'; import { RichText } from '@alilc/lowcode-materials'; class App extends Component { render() { return (
); } } ReactDOM.render(, mountNode); ``` ================================================ FILE: packages/fusion-lowcode-materials/demo/Video.md ================================================ --- title: Video order: 3 --- 视频组件。 ```jsx import React, { Component } from 'react'; import ReactDOM from 'react-dom'; import { Video } from '@alilc/lowcode-materials'; class App extends Component { render() { return (
); } } ReactDOM.render(, mountNode); ``` ================================================ FILE: packages/fusion-lowcode-materials/lowcode/alert/meta.design.ts ================================================ export default { group: '原子组件', componentName: 'Message', title: '提示', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Message', main: '', destructuring: true, subName: '', }, props: [ { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, { name: 'title', title: { label: { type: 'i18n', zh_CN: '标题', en_US: 'Title', }, tip: { type: 'i18n', zh_CN: '属性: title | 说明: 标题', en_US: 'prop: title | description: Title', }, }, propType: 'string', description: '标题', defaultValue: '标题', }, { name: 'type', title: { label: { type: 'i18n', zh_CN: '类型', en_US: 'Type', }, tip: { type: 'i18n', zh_CN: '属性: type | 说明: 反馈类型', en_US: 'prop: type | description: message type', }, }, propType: { type: 'oneOf', value: ['success', 'warning', 'error', 'notice', 'help', 'loading'], }, description: '反馈类型', defaultValue: 'success', }, { name: 'shape', title: { label: { type: 'i18n', zh_CN: '形状', en_US: 'Shape', }, tip: { type: 'i18n', zh_CN: '属性: shape | 说明: 外观', en_US: 'prop: shape | description: message shape', }, }, propType: { type: 'oneOf', value: ['inline', 'addon', 'toast'], }, description: '外观', defaultValue: 'inline', }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 尺寸', en_US: 'prop: size | description: message size', }, }, propType: { type: 'oneOf', value: ['medium', 'large'], }, description: '尺寸', defaultValue: 'medium', }, { name: 'children', title: { label: { type: 'i18n', zh_CN: '文本', en_US: 'Content', }, tip: { type: 'i18n', zh_CN: '属性: children | 说明: 文本内容', en_US: 'prop: children | description: message content', }, }, propType: { type: 'oneOfType', value: ['string', 'node'], }, description: '内容', }, { name: 'visible', title: { label: { type: 'i18n', zh_CN: '是否显示', en_US: 'Visible', }, tip: { type: 'i18n', zh_CN: '属性: visible | 说明: 当前是否显示', en_US: 'prop: visible | description: visible', }, }, propType: 'bool', description: '当前是否显示', }, { name: 'iconType', propType: 'string', description: '显示的图标类型,会覆盖内部设置的IconType', }, { name: 'closeable', title: { label: { type: 'i18n', zh_CN: '显示 Close', en_US: 'Show Close', }, tip: { type: 'i18n', zh_CN: '属性: closeable | 说明: 显示关闭按钮', en_US: 'prop: closeable | description: show close button', }, }, propType: 'bool', description: '显示关闭按钮', defaultValue: false, }, { name: 'onClose', propType: 'func', description: '关闭按钮的回调', }, { name: 'afterClose', propType: 'func', description: '关闭之后调用的函数', }, { name: 'animation', title: { label: { type: 'i18n', zh_CN: '开启动效', en_US: 'Animation', }, tip: { type: 'i18n', zh_CN: '属性: animation | 说明: 是否开启动效', en_US: 'prop: animation | description: enable animation', }, }, propType: 'bool', description: '收起动画', defaultValue: true, }, ], configure: { props: [ { name: 'shape', title: { label: { type: 'i18n', zh_CN: '形状', en_US: 'Shape', }, tip: { type: 'i18n', zh_CN: '属性: shape | 说明: 外观', en_US: 'prop: shape | description: message shape', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: 'Inline', value: 'inline', }, { label: 'Addon', value: 'addon', }, { label: 'Toast', value: 'toast', }, ], }, }, description: '外观', defaultValue: 'inline', }, { name: 'type', title: { label: { type: 'i18n', zh_CN: '类型', en_US: 'Type', }, tip: { type: 'i18n', zh_CN: '属性: type | 说明: 反馈类型', en_US: 'prop: type | description: message type', }, }, setter: { componentName: 'SelectSetter', props: { options: [ { label: '成功', value: 'success', }, { label: '警告', value: 'warning', }, { label: '失败', value: 'error', }, { label: '提示', value: 'notice', }, { label: '帮助', value: 'help', }, { label: '加载', value: 'loading', }, ], }, }, description: '反馈类型', defaultValue: 'success', }, { name: 'title', title: { label: { type: 'i18n', zh_CN: '标题', en_US: 'Title', }, tip: { type: 'i18n', zh_CN: '属性: title | 说明: 标题', en_US: 'prop: title | description: Title', }, }, setter: 'StringSetter', description: '标题', defaultValue: '标题', }, { name: 'iconType', title: { label: { type: 'i18n', zh_CN: '图标', en_US: 'Icon', }, tip: { type: 'i18n', zh_CN: '属性: iconType | 说明: 显示的图标类型', en_US: 'prop: iconType | description: icon type', }, }, setter: { componentName: 'IconSetter', }, }, { name: 'children', title: { label: { type: 'i18n', zh_CN: '文本', en_US: 'Content', }, tip: { type: 'i18n', zh_CN: '属性: children | 说明: 文本内容', en_US: 'prop: children | description: message content', }, }, setter: 'TextAreaSetter', description: '内容', }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 尺寸', en_US: 'prop: size | description: message size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '中', value: 'medium', }, { label: '大', value: 'large', }, ], }, }, description: '尺寸', defaultValue: 'medium', }, { name: 'style.width', title: '宽度', setter: 'NumberSetter', }, { name: 'visible', title: { label: { type: 'i18n', zh_CN: '是否显示', en_US: 'Visible', }, tip: { type: 'i18n', zh_CN: '属性: visible | 说明: 当前是否显示', en_US: 'prop: visible | description: visible', }, }, setter: 'BoolSetter', description: '当前是否显示', }, { name: 'closeable', title: { label: { type: 'i18n', zh_CN: '关闭按钮', en_US: 'Show Close', }, tip: { type: 'i18n', zh_CN: '属性: closeable | 说明: 显示关闭按钮', en_US: 'prop: closeable | description: show close button', }, }, setter: 'BoolSetter', description: '显示关闭按钮', defaultValue: false, }, { name: 'animation', title: { label: { type: 'i18n', zh_CN: '开启动效', en_US: 'Animation', }, tip: { type: 'i18n', zh_CN: '属性: animation | 说明: 是否开启动效', en_US: 'prop: animation | description: enable animation', }, }, setter: 'BoolSetter', description: '收起动画', defaultValue: true, }, ], }, icon: '', category: '信息反馈', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/alert/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Message', title: '提示', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Message', main: '', destructuring: true, subName: '', }, props: [ { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, { name: 'title', title: { label: { type: 'i18n', zh_CN: '标题', en_US: 'Title', }, tip: { type: 'i18n', zh_CN: '属性: title | 说明: 标题', en_US: 'prop: title | description: Title', }, }, propType: 'string', description: '标题', defaultValue: '标题', }, { name: 'type', title: { label: { type: 'i18n', zh_CN: '类型', en_US: 'Type', }, tip: { type: 'i18n', zh_CN: '属性: type | 说明: 反馈类型', en_US: 'prop: type | description: message type', }, }, propType: { type: 'oneOf', value: ['success', 'warning', 'error', 'notice', 'help', 'loading'], }, description: '反馈类型', defaultValue: 'success', }, { name: 'shape', title: { label: { type: 'i18n', zh_CN: '形状', en_US: 'Shape', }, tip: { type: 'i18n', zh_CN: '属性: shape | 说明: 外观', en_US: 'prop: shape | description: message shape', }, }, propType: { type: 'oneOf', value: ['inline', 'addon', 'toast'], }, description: '外观', defaultValue: 'inline', }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 尺寸', en_US: 'prop: size | description: message size', }, }, propType: { type: 'oneOf', value: ['medium', 'large'], }, description: '尺寸', defaultValue: 'medium', }, { name: 'children', title: { label: { type: 'i18n', zh_CN: '文本', en_US: 'Content', }, tip: { type: 'i18n', zh_CN: '属性: children | 说明: 文本内容', en_US: 'prop: children | description: message content', }, }, propType: { type: 'oneOfType', value: ['string', 'node'], }, description: '内容', }, { name: 'visible', title: { label: { type: 'i18n', zh_CN: '是否显示', en_US: 'Visible', }, tip: { type: 'i18n', zh_CN: '属性: visible | 说明: 当前是否显示', en_US: 'prop: visible | description: visible', }, }, propType: 'bool', description: '当前是否显示', }, { name: 'iconType', propType: 'string', description: '显示的图标类型,会覆盖内部设置的IconType', }, { name: 'closeable', title: { label: { type: 'i18n', zh_CN: '显示 Close', en_US: 'Show Close', }, tip: { type: 'i18n', zh_CN: '属性: closeable | 说明: 显示关闭按钮', en_US: 'prop: closeable | description: show close button', }, }, propType: 'bool', description: '显示关闭按钮', defaultValue: false, }, { name: 'onClose', propType: 'func', description: '关闭按钮的回调', }, { name: 'afterClose', propType: 'func', description: '关闭之后调用的函数', }, { name: 'animation', title: { label: { type: 'i18n', zh_CN: '开启动效', en_US: 'Animation', }, tip: { type: 'i18n', zh_CN: '属性: animation | 说明: 是否开启动效', en_US: 'prop: animation | description: enable animation', }, }, propType: 'bool', description: '收起动画', defaultValue: true, }, ], configure: { props: { isExtends: true, override: [ { name: 'iconType', title: { label: { type: 'i18n', zh_CN: '图标', en_US: 'Icon', }, tip: { type: 'i18n', zh_CN: '属性: iconType | 说明: 显示的图标类型', en_US: 'prop: iconType | description: icon type', }, }, setter: { componentName: 'IconSetter', }, }, ], }, }, icon: '', category: '信息反馈', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/alert/snippets.ts ================================================ module.exports = [ { title: '提示', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_message.png', schema: { componentName: 'Message', props: { title: 'Alert', type: 'warning', shape: 'inline', size: 'medium', visible: true, animation: true, children: 'This item already has the label "travel", you can add a new label.', }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/avatar/meta.design.ts ================================================ export default { group: '原子组件', componentName: 'Avatar', title: '头像', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Avatar', main: '', destructuring: true, subName: '', }, props: [ { name: 'children', title: { label: { type: 'i18n', zh_CN: '文本内容', en_US: 'Content', }, tip: { type: 'i18n', zh_CN: '属性: children | 说明: 文本内容', en_US: 'prop: children | description: avatar content', }, }, propType: 'string', }, { name: 'className', propType: 'string', }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '头像尺寸', en_US: 'Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 头像的大小', en_US: 'prop: size | description: avatar size', }, }, propType: { type: 'oneOfType', value: [ { type: 'oneOf', value: ['small', 'medium', 'large'], }, 'number', ], }, description: '头像的大小', defaultValue: 'medium', }, { name: 'shape', title: { label: { type: 'i18n', zh_CN: '头像形状', en_US: 'Shape', }, tip: { type: 'i18n', zh_CN: '属性: shape | 说明: 头像的形状', en_US: 'prop: shape | description: avatar shape', }, }, propType: { type: 'oneOf', value: ['circle', 'square'], }, description: '头像的形状', defaultValue: 'circle', }, { name: 'icon', title: 'icon', propType: 'string', description: 'icon 类头像的图标类型,可设为 Icon 的 `type` 或 `ReactNode`', }, { name: 'src', title: { label: { type: 'i18n', zh_CN: '头像地址', en_US: 'Src', }, tip: { type: 'i18n', zh_CN: '属性: src | 说明: 图片类头像的资源地址', en_US: 'prop: src | description: resource address', }, }, propType: 'string', description: '图片类头像的资源地址', }, { name: 'onError', propType: 'func', description: '图片加载失败的事件,返回 false 会关闭组件默认的 fallback 行为', }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: true, }, props: [ { name: 'shape', title: { label: { type: 'i18n', zh_CN: '类型', en_US: 'Shape', }, tip: { type: 'i18n', zh_CN: '属性: shape | 说明: 头像的形状', en_US: 'prop: shape | description: avatar shape', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['circle', 'square'] }, }, description: '头像的形状', defaultValue: 'circle', }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 尺寸', en_US: 'prop: size | description: size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '小', value: 'small', }, { label: '中', value: 'medium', }, { label: '大', value: 'large', }, ], }, }, defaultValue: 'medium', }, { name: 'icon', title: { label: { type: 'i18n', zh_CN: '图标', en_US: 'Icon', }, tip: { type: 'i18n', zh_CN: '属性: icon | 说明: 图标类型', en_US: 'prop: icon | description: icon type', }, }, setter: { componentName: 'IconSetter', }, }, { name: 'src', title: { label: { type: 'i18n', zh_CN: '头像地址', en_US: 'Src', }, tip: { type: 'i18n', zh_CN: '属性: src | 说明: 图片类头像的资源地址', en_US: 'prop: src | description: resource address', }, }, setter: 'StringSetter', }, ], }, icon: '', category: '信息展示', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/avatar/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Avatar', title: '头像', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Avatar', main: '', destructuring: true, subName: '', }, props: [ { name: 'children', title: { label: { type: 'i18n', zh_CN: '文本内容', en_US: 'Content', }, tip: { type: 'i18n', zh_CN: '属性: children | 说明: 文本内容', en_US: 'prop: children | description: avatar content', }, }, propType: 'string', }, { name: 'className', propType: 'string', }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '头像尺寸', en_US: 'Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 头像的大小', en_US: 'prop: size | description: avatar size', }, }, propType: { type: 'oneOfType', value: [ { type: 'oneOf', value: ['small', 'medium', 'large'], }, 'number', ], }, description: '头像的大小', defaultValue: 'medium', }, { name: 'shape', title: { label: { type: 'i18n', zh_CN: '头像形状', en_US: 'Shape', }, tip: { type: 'i18n', zh_CN: '属性: shape | 说明: 头像的形状', en_US: 'prop: shape | description: avatar shape', }, }, propType: { type: 'oneOf', value: ['circle', 'square'], }, description: '头像的形状', defaultValue: 'circle', }, { name: 'icon', title: 'icon', propType: 'string', description: 'icon 类头像的图标类型,可设为 Icon 的 `type` 或 `ReactNode`', }, { name: 'src', title: { label: { type: 'i18n', zh_CN: '头像地址', en_US: 'Src', }, tip: { type: 'i18n', zh_CN: '属性: src | 说明: 图片类头像的资源地址', en_US: 'prop: src | description: resource address', }, }, propType: 'string', description: '图片类头像的资源地址', }, { name: 'onError', propType: 'func', description: '图片加载失败的事件,返回 false 会关闭组件默认的 fallback 行为', }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: true, }, props: { isExtends: true, override: [ { name: 'icon', title: { label: { type: 'i18n', zh_CN: '图标', en_US: 'Icon', }, tip: { type: 'i18n', zh_CN: '属性: icon | 说明: 图标类型', en_US: 'prop: icon | description: icon type', }, }, setter: { componentName: 'IconSetter', }, }, ], }, }, icon: '', category: '信息展示', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/avatar/snippets.ts ================================================ module.exports = [ { title: '头像', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_avatar.png', schema: { componentName: 'Avatar', props: { prefix: 'next-', size: 'medium', shape: 'circle', icon: 'smile', }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/badge/meta.design.ts ================================================ module.exports = { group: '原子组件', componentName: 'Badge', title: '徽标数', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Badge', main: '', destructuring: true, subName: '', }, props: [ { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, { name: 'count', title: 'count', propType: 'string', description: '展示的数字,大于 overflowCount 时显示为 ${overflowCount}+,为 0 时默认隐藏', defaultValue: 0, }, { name: 'content', title: '内容', propType: 'node', description: '自定义节点内容', }, { name: 'overflowCount', title: '封顶数字', propType: { type: 'oneOfType', value: ['number', 'string'], }, description: '展示的封顶的数字', defaultValue: 99, }, { name: 'showZero', title: { label: '展示零', tip: 'showZero|当count为 0 时,是否显示 count', }, propType: 'bool', description: '当count为 0 时,是否显示 count', defaultValue: true, }, { name: 'dot', title: { label: '红点', tip: 'dot|不展示数字,只展示一个小红点', }, propType: 'bool', description: '不展示数字,只展示一个小红点', defaultValue: false, }, ], configure: { component: { isContainer: true, }, props: [ { name: 'dot', title: { label: '类型', tip: 'dot|不展示数字,只展示一个小红点', }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '点', value: true, }, { label: '数字', value: false, }, ], }, }, description: '不展示数字,只展示一个小红点', defaultValue: false, }, { name: 'count', title: { label: '展示数字', tip: 'count|大于 overflowCount 时显示为 ${overflowCount}+,为 0 时默认隐藏', docUrl: 'https://fusion.alibaba-inc.com/pc/component/basic/badge', }, setter: 'NumberSetter', }, { name: 'overflowCount', title: '封顶数字', setter: 'NumberSetter', defaultValue: 99, }, ], }, icon: '', category: '信息展示', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/badge/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Badge', title: '徽标数', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Badge', main: '', destructuring: true, subName: '', }, props: [ { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, { name: 'count', title: 'count', propType: 'string', description: '展示的数字,大于 overflowCount 时显示为 ${overflowCount}+,为 0 时默认隐藏', defaultValue: 0, }, { name: 'content', title: '内容', propType: 'node', description: '自定义节点内容', }, { name: 'overflowCount', title: '封顶数字', propType: { type: 'oneOfType', value: ['number', 'string'], }, description: '展示的封顶的数字', defaultValue: 99, }, { name: 'showZero', title: { label: '展示零', tip: 'showZero|当count为 0 时,是否显示 count', }, propType: 'bool', description: '当count为 0 时,是否显示 count', defaultValue: true, }, { name: 'dot', title: { label: '红点', tip: 'dot|不展示数字,只展示一个小红点', }, propType: 'bool', description: '不展示数字,只展示一个小红点', defaultValue: false, }, ], configure: { component: { isContainer: true, }, props: { isExtends: true, override: [ { name: 'count', title: { label: '展示的数字', tip: 'count|大于 overflowCount 时显示为 ${overflowCount}+,为 0 时默认隐藏', docUrl: 'https://fusion.alibaba-inc.com/pc/component/basic/badge', }, setter: { componentName: 'MixedSetter', props: { setters: ['StringSetter', 'ExpressionSetter'], }, }, }, ], }, }, icon: '', category: '信息展示', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/badge/snippets.ts ================================================ module.exports = [ { title: '徽标数', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_badge.png', schema: { componentName: 'Badge', props: { prefix: 'next-', showZero: true, }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/balloon/meta.design.ts ================================================ import snippets from './snippets.design'; export default { group: '原子组件', componentName: 'Balloon', title: '气泡框', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: 'latest', exportName: 'Balloon', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'pure', propType: 'bool', defaultValue: false, }, { name: 'rtl', propType: 'bool', }, { name: 'className', propType: 'string', description: '自定义类名', }, { name: 'style', propType: 'object', description: '自定义内敛样式', }, { name: 'type', propType: { type: 'oneOf', value: ['normal', 'primary'], }, description: '样式类型', defaultValue: 'normal', }, { name: 'triggerType', title: '触发行为', propType: { type: 'oneOf', value: ['hover', 'click'], }, description: "触发行为\n鼠标悬浮, 鼠标点击('hover','click')或者它们组成的数组,如 ['hover', 'click'], 强烈不建议使用'focus',若弹窗内容有复杂交互请使用click", defaultValue: 'hover', }, { name: 'visible', propType: 'bool', description: '弹层当前显示的状态', }, { name: 'onVisibleChange', propType: 'func', description: '弹层在显示和隐藏触发的事件\n@param {Boolean} visible 弹层是否隐藏和显示\n@param {String} type 触发弹层显示或隐藏的来源, closeClick 表示由自带的关闭按钮触发; fromTrigger 表示由trigger的点击触发; docClick 表示由document的点击触发', }, { name: 'align', title: '弹出位置', propType: { type: 'oneOf', value: ['t', 'r', 'b', 'l', 'tl', 'tr', 'bl', 'br', 'lt', 'lb', 'rt', 'rb'], }, description: '弹出层位置\n@enumdesc 上, 右, 下, 左, 上左, 上右, 下左, 下右, 左上, 左下, 右上, 右下 及其 两两组合', defaultValue: 'b', }, { name: 'offset', propType: { type: 'arrayOf', value: 'number', }, description: '弹层相对于trigger的定位的微调, 接收数组[hoz, ver], 表示弹层在 left / top 上的增量\ne.g. [100, 100] 表示往右(RTL 模式下是往左) 、下分布偏移100px', defaultValue: [0, 0], }, { name: 'popupContainer', propType: 'any', description: '弹层容器\n@param {Element} target 目标元素\n@return {Element} 弹层的容器元素', }, { name: 'delay', title: '延迟显示', propType: 'number', description: '弹层在触发以后的延时显示, 单位毫秒 ms', }, { name: 'trigger', propType: 'node', description: '触发元素', }, { name: 'onClick', propType: 'func', }, { name: 'onClose', propType: 'func', description: '任何visible为false时会触发的事件', }, { name: 'onHover', propType: 'func', }, { name: 'defaultVisible', title: '默认显示', propType: 'bool', description: '弹层默认显示的状态', defaultValue: false, }, { name: 'alignEdge', title: '边缘对齐', propType: 'bool', description: '弹出层对齐方式, 是否为边缘对齐', defaultValue: false, }, { name: 'closable', title: '关闭按钮', propType: 'bool', description: '是否显示关闭按钮', defaultValue: true, }, { name: 'needAdjust', title: '自动调整', propType: 'bool', description: '是否进行自动位置调整', defaultValue: false, }, { name: 'afterClose', propType: 'func', description: '浮层关闭后触发的事件, 如果有动画,则在动画结束后触发', }, { name: 'shouldUpdatePosition', propType: 'bool', description: '强制更新定位信息', }, { name: 'autoFocus', title: '自动聚焦', propType: 'bool', description: '弹层出现后是否自动focus到内部第一个元素', defaultValue: true, }, { name: 'followTrigger', title: '跟随滚动', propType: 'bool', description: '是否跟随滚动', }, ], configure: { component: { isContainer: true, }, props: [ { name: 'mode', title: '模式', setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '气泡', value: 'Balloon', }, { label: '提示', value: 'Tooltip', }, ], }, }, }, { name: 'type', title: '样式类型', setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '普通', value: 'normal', }, { label: '主要', value: 'primary', }, ], }, }, defaultValue: 'normal', }, { name: 'triggerType', title: '触发行为', setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '悬停', value: 'hover', }, { label: '点击', value: 'click', }, ], }, }, description: "触发行为\n鼠标悬浮, 鼠标点击('hover','click')或者它们组成的数组,如 ['hover', 'click'], 强烈不建议使用'focus',若弹窗内容有复杂交互请使用click", defaultValue: 'hover', }, { name: 'align', title: '弹出位置', setter: { componentName: 'SelectSetter', props: { options: [ { label: '顶部', value: 't', }, { label: '右侧', value: 'r', }, { label: '底部', value: 'b', }, { label: '左侧', value: 'l', }, { label: '顶部左侧', value: 'tl', }, { label: '顶部右侧', value: 'tr', }, { label: '底部左侧', value: 'bl', }, { label: '底部右侧', value: 'br', }, { label: '左侧顶部', value: 'lt', }, { label: '左侧底部', value: 'lb', }, { label: '右侧顶部', value: 'rt', }, { label: '右侧底部', value: 'rb', }, ], }, }, description: '弹出层位置\n@enumdesc 上, 右, 下, 左, 上左, 上右, 下左, 下右, 左上, 左下, 右上, 右下 及其 两两组合', defaultValue: 'b', }, { name: 'closable', title: '关闭按钮', setter: 'BoolSetter', }, { name: 'followTrigger', title: '跟随滚动', setter: 'BoolSetter', }, { name: 'defaultVisible', title: '展示弹层', setter: 'BoolSetter', description: '弹层当前显示的状态', }, { name: 'children', title: '弹层内容', setter: 'TextAreaSetter', }, ], }, icon: '', category: '信息反馈', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/balloon/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Balloon', title: '气泡框', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Balloon', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'pure', propType: 'bool', defaultValue: false, }, { name: 'rtl', propType: 'bool', }, { name: 'className', propType: 'string', description: '自定义类名', }, { name: 'style', propType: 'object', description: '自定义内敛样式', }, { name: 'type', propType: { type: 'oneOf', value: ['normal', 'primary'], }, description: '样式类型', defaultValue: 'normal', }, { name: 'triggerType', title: '触发行为', propType: { type: 'oneOf', value: ['hover', 'click'], }, description: "触发行为\n鼠标悬浮, 鼠标点击('hover','click')或者它们组成的数组,如 ['hover', 'click'], 强烈不建议使用'focus',若弹窗内容有复杂交互请使用click", defaultValue: 'hover', }, { name: 'visible', propType: 'bool', description: '弹层当前显示的状态', }, { name: 'onVisibleChange', propType: 'func', description: '弹层在显示和隐藏触发的事件\n@param {Boolean} visible 弹层是否隐藏和显示\n@param {String} type 触发弹层显示或隐藏的来源, closeClick 表示由自带的关闭按钮触发; fromTrigger 表示由trigger的点击触发; docClick 表示由document的点击触发', }, { name: 'align', title: '弹出位置', propType: { type: 'oneOf', value: ['t', 'r', 'b', 'l', 'tl', 'tr', 'bl', 'br', 'lt', 'lb', 'rt', 'rb'], }, description: '弹出层位置\n@enumdesc 上, 右, 下, 左, 上左, 上右, 下左, 下右, 左上, 左下, 右上, 右下 及其 两两组合', defaultValue: 'b', }, { name: 'offset', propType: { type: 'arrayOf', value: 'number', }, description: '弹层相对于trigger的定位的微调, 接收数组[hoz, ver], 表示弹层在 left / top 上的增量\ne.g. [100, 100] 表示往右(RTL 模式下是往左) 、下分布偏移100px', defaultValue: [0, 0], }, { name: 'popupContainer', propType: 'any', description: '弹层容器\n@param {Element} target 目标元素\n@return {Element} 弹层的容器元素', }, { name: 'delay', title: '延迟显示', propType: 'number', description: '弹层在触发以后的延时显示, 单位毫秒 ms', }, { name: 'trigger', propType: 'node', description: '触发元素', }, { name: 'onClick', propType: 'func', }, { name: 'onClose', propType: 'func', description: '任何visible为false时会触发的事件', }, { name: 'onHover', propType: 'func', }, { name: 'defaultVisible', title: '默认显示', propType: 'bool', description: '弹层默认显示的状态', defaultValue: false, }, { name: 'alignEdge', title: '边缘对齐', propType: 'bool', description: '弹出层对齐方式, 是否为边缘对齐', defaultValue: false, }, { name: 'closable', title: '关闭按钮', propType: 'bool', description: '是否显示关闭按钮', defaultValue: true, }, { name: 'needAdjust', title: '自动调整', propType: 'bool', description: '是否进行自动位置调整', defaultValue: false, }, { name: 'afterClose', propType: 'func', description: '浮层关闭后触发的事件, 如果有动画,则在动画结束后触发', }, { name: 'shouldUpdatePosition', propType: 'bool', description: '强制更新定位信息', }, { name: 'autoFocus', title: '自动聚焦', propType: 'bool', description: '弹层出现后是否自动focus到内部第一个元素', defaultValue: true, }, { name: 'followTrigger', title: '跟随滚动', propType: 'bool', description: '是否跟随滚动', }, ], configure: { component: { isContainer: true, }, props: { isExtends: true, override: [ { name: 'prefix', condition: () => false, }, { name: 'rtl', condition: () => false, }, { name: 'pure', condition: () => false, }, { name: 'visible', condition: () => false, }, { name: 'offset', condition: () => false, }, { name: 'shouldUpdatePosition', condition: () => false, }, { name: 'popupContainer', title: { docUrl: 'https://fusion.alibaba-inc.com/pc/component/basic/balloon#demo-api', label: '弹层容器', tip: '指定浮层渲染的父节点, 可以为节点id的字符串,也可以返回节点的函数()。', }, setter: { componentName: 'MixedSetter', props: { setters: ['StringSetter', 'FunctionSetter'], }, }, }, ], }, }, icon: '', category: '信息反馈', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/balloon/snippets.design.ts ================================================ export default [ { title: '气泡框', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_balloon.png', schema: { componentName: 'Balloon', props: { defaultVisible: true, prefix: 'next-', size: 'medium', type: 'normal', closable: true, align: 'b', offset: [0, 0], triggerType: 'hover', autoFocus: true, children: 'Balloon content replace holder.', mode: 'Balloon', trigger: { type: 'JSSlot', props: { title: '触发元素', }, }, }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/balloon/snippets.ts ================================================ module.exports = [ { title: '气泡框', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_balloon.png', schema: { componentName: 'Balloon', props: { defaultVisible: true, prefix: 'next-', size: 'medium', type: 'normal', closable: true, align: 'b', offset: [0, 0], triggerType: 'hover', autoFocus: true, trigger: { type: 'JSSlot', props: { title: '触发元素', }, }, }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/balloon-inner/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'BalloonInner', title: 'BalloonInner', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Balloon', main: '', destructuring: true, subName: 'Inner', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'rtl', propType: 'bool', }, { name: 'closable', propType: 'bool', defaultValue: true, }, { name: 'children', propType: 'any', }, { name: 'className', propType: 'string', }, { name: 'alignEdge', propType: 'bool', defaultValue: false, }, { name: 'onClose', propType: 'func', }, { name: 'style', propType: 'any', }, { name: 'align', propType: 'string', defaultValue: 'b', }, { name: 'type', propType: 'string', defaultValue: 'normal', }, { name: 'isTooltip', propType: 'bool', }, { name: 'locale', propType: 'object', }, { name: 'pure', propType: 'bool', defaultValue: false, }, ], configure: { component: { isContainer: true, }, }, category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/box/meta.design.tsx ================================================ module.exports = { group: '原子组件', componentName: 'Box', title: '容器', category: '布局容器类', hidden: true, icon: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_table.png', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Box', main: '', destructuring: true, subName: '', }, props: [ { name: 'style', propType: 'object', description: '自定义内敛样式', }, { name: 'direction', title: '对齐方向', defaultValue: 'column', initialValue: 'column', setter: { componentName: 'RadioGroupSetter', initialValue: 'column', defaultValue: 'column', props: { defaultValue: 'column', options: [ { // "title": "| 垂直", title: ( ), value: 'column', }, { // "title": "- 水平", title: ( ), value: 'row', }, ], }, }, }, { name: 'justify', title: '主轴对齐', defaultValue: 'center', initialValue: 'center', condition: (target) => { return target.getProps().getPropValue('direction') === 'row'; }, setter: { componentName: 'RadioGroupSetter', initialValue: 'center', defaultValue: 'center', props: { defaultValue: 'center', options: [ { // "title": "| 左", title: ( ), value: 'flex-start', }, { // "title": "中", title: ( ), value: 'center', }, { // "title": "右 |", title: ( ), value: 'flex-end', }, { // "title": "两端", title: ( ), value: 'space-between', }, { // "title": "等分", title: ( ), value: 'space-around', }, ], }, }, }, { name: 'justify', title: '主轴对齐', defaultValue: 'center', initialValue: 'center', condition: (target) => { return target.getProps().getPropValue('direction') === 'column'; }, setter: { componentName: 'RadioGroupSetter', initialValue: 'center', defaultValue: 'center', props: { defaultValue: 'center', options: [ { // "title": "上", title: ( ), value: 'flex-start', }, { // "title": "中", title: ( ), value: 'center', }, { // "title": "下", title: ( ), value: 'flex-end', }, { // "title": "两端", title: ( ), value: 'space-between', }, { // "title": "等分", title: ( ), value: 'space-around', }, ], }, }, }, { name: 'align', title: '交叉轴对齐', defaultValue: 'center', initialValue: 'center', condition: (target) => { return target.getProps().getPropValue('direction') === 'row'; }, setter: { componentName: 'RadioGroupSetter', initialValue: 'center', props: { defaultValue: 'center', options: [ { // "title": "上", title: ( ), value: 'flex-start', }, { // "title": "中", title: ( ), value: 'center', }, { // "title": "下", title: ( ), value: 'flex-end', }, { // "title": "等高", title: ( ), value: 'stretch', }, { // "title": "基线", title: ( ), value: 'baseline', }, ], }, }, }, { name: 'align', title: '交叉轴对齐', defaultValue: 'center', initialValue: 'center', condition: (target) => { return target.getProps().getPropValue('direction') === 'column'; }, setter: { componentName: 'RadioGroupSetter', initialValue: 'center', props: { defaultValue: 'center', options: [ { // "title": '| 左', title: ( ), value: 'flex-start', }, { // "title": "中", title: ( ), value: 'center', }, { // "title": "右 |", title: ( ), value: 'flex-end', }, { // "title": "等宽", title: ( ), value: 'stretch', }, { // "title": "基线", title: ( ), value: 'baseline', }, ], }, }, }, { name: 'style.width', title: '宽度', defaultValue: '', initialValue: '', setter: { componentName: 'RadioGroupSetter', initialValue: '', props: { defaultValue: '', options: [ { title: '默认', value: '', }, { title: '铺满', value: '100%', }, ], }, }, }, { name: 'spacing', title: '内容间距', defaultValue: 0, initialValue: 0, setter: { componentName: 'NumberSetter', props: { step: 4, }, }, }, ], configure: { component: { isContainer: true, }, supports: { style: true, loop: false, }, }, snippets: [ { title: 'Box', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_table.png', schema: { componentName: 'Box', props: {}, }, }, ], }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/box/meta.tsx ================================================ module.exports = { group: '原子组件', componentName: 'Box', title: '容器', category: '布局容器类', icon: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_table.png', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Box', main: '', destructuring: true, subName: '', }, props: [ { name: 'style', propType: 'object', description: '自定义内敛样式', }, { name: 'direction', title: '对齐方向', defaultValue: 'column', initialValue: 'column', setter: { componentName: 'RadioGroupSetter', initialValue: 'column', defaultValue: 'column', props: { defaultValue: 'column', options: [ { // "title": "| 垂直", title: ( ), value: 'column', }, { // "title": "- 水平", title: ( ), value: 'row', }, ], }, }, }, { name: 'justify', title: '主轴对齐', defaultValue: 'center', initialValue: 'center', condition: (target) => { return target.parent.getPropValue('direction') === 'row'; }, setter: { componentName: 'RadioGroupSetter', initialValue: 'center', defaultValue: 'center', props: { defaultValue: 'center', options: [ { // "title": "| 左", title: ( ), value: 'flex-start', }, { // "title": "中", title: ( ), value: 'center', }, { // "title": "右 |", title: ( ), value: 'flex-end', }, { // "title": "两端", title: ( ), value: 'space-between', }, { // "title": "等分", title: ( ), value: 'space-around', }, ], }, }, }, { name: 'justify', title: '主轴对齐', defaultValue: 'center', initialValue: 'center', condition: (target) => { return target.parent.getPropValue('direction') === 'column'; }, setter: { componentName: 'RadioGroupSetter', initialValue: 'center', defaultValue: 'center', props: { defaultValue: 'center', options: [ { // "title": "上", title: ( ), value: 'flex-start', }, { // "title": "中", title: ( ), value: 'center', }, { // "title": "下", title: ( ), value: 'flex-end', }, { // "title": "两端", title: ( ), value: 'space-between', }, { // "title": "等分", title: ( ), value: 'space-around', }, ], }, }, }, { name: 'align', title: '交叉轴对齐', defaultValue: 'center', initialValue: 'center', condition: (target) => { return target.parent.getPropValue('direction') === 'row'; }, setter: { componentName: 'RadioGroupSetter', initialValue: 'center', props: { defaultValue: 'center', options: [ { // "title": "上", title: ( ), value: 'flex-start', }, { // "title": "中", title: ( ), value: 'center', }, { // "title": "下", title: ( ), value: 'flex-end', }, { // "title": "等高", title: ( ), value: 'stretch', }, { // "title": "基线", title: ( ), value: 'baseline', }, ], }, }, }, { name: 'align', title: '交叉轴对齐', defaultValue: 'center', initialValue: 'center', condition: (target) => { return target.parent.getPropValue('direction') === 'column'; }, setter: { componentName: 'RadioGroupSetter', initialValue: 'center', props: { defaultValue: 'center', options: [ { // "title": '| 左', title: ( ), value: 'flex-start', }, { // "title": "中", title: ( ), value: 'center', }, { // "title": "右 |", title: ( ), value: 'flex-end', }, { // "title": "等宽", title: ( ), value: 'stretch', }, { // "title": "基线", title: ( ), value: 'baseline', }, ], }, }, }, { name: 'style.width', title: '宽度', defaultValue: '', initialValue: '', setter: { componentName: 'RadioGroupSetter', initialValue: '', props: { defaultValue: '', options: [ { title: '默认', value: '', }, { title: '铺满', value: '100%', }, ], }, }, }, { name: 'spacing', title: '内容间距', defaultValue: 0, initialValue: 0, setter: { componentName: 'NumberSetter', props: { step: 4, }, }, }, ], configure: { component: { isContainer: true, }, supports: { style: true, loop: false, }, }, snippets: [ { title: 'Box', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_table.png', schema: { componentName: 'Box', props: {}, }, }, ], }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/breadcrumb/meta.design.ts ================================================ export default { group: '原子组件', componentName: 'Breadcrumb', title: '面包屑', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Breadcrumb', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', description: '样式类名的品牌前缀', defaultValue: 'next-', }, { name: 'rtl', propType: 'bool', }, { name: 'children', propType: { type: 'instanceOf', value: 'node', }, description: '面包屑子节点,需传入 Breadcrumb.Item', }, { name: 'maxNode', propType: { type: 'oneOfType', value: [ 'number', { type: 'oneOf', value: ['auto'], }, ], }, description: '面包屑最多显示个数,超出部分会被隐藏, 设置为 auto 会自动根据父元素的宽度适配。', defaultValue: 100, }, { name: 'separator', propType: { type: 'instanceOf', value: 'node', }, description: '分隔符,可以是文本或 Icon', }, { name: 'component', propType: { type: 'oneOfType', value: ['string', 'func'], }, description: '设置标签类型', defaultValue: 'nav', }, { name: 'className', propType: 'any', }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: true, nestingRule: { childWhitelist: ['Breadcrumb.Item'], }, }, props: [ { name: 'maxNode', title: { label: '最大节点数', tip: '默认 100', }, setter: 'NumberSetter', }, { name: '!items', title: '内容', setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'primaryKey', title: '面包屑项编号', condition: () => false, initialValue: (val) => { if (val) return val; return String(Math.floor(Math.random() * 10000)); }, setter: 'StringSetter', supportVariable: true, }, { name: 'children', title: '标题', important: true, initialValue: { zh_CN: '', en_US: '', type: 'i18n', }, setter: 'StringSetter', }, { name: 'link', title: '链接', initialValue: { zh_CN: '', en_US: '', type: 'i18n', }, setter: 'StringSetter', supportVariable: true, }, { name: 'target', title: '打开方式', initialValue: { zh_CN: '', en_US: '', type: 'i18n', }, setter: { componentName: 'RadioGroupSetter', initialValue: '_self', props: { options: [ { title: '新开页面', value: '_blank', }, { title: '当前页面', value: '_self', }, ], }, }, }, ], }, }, initialValue: () => { return { primaryKey: String(Math.floor(Math.random() * 10000)), children: 'Title', target: '_self', }; }, }, }, }, extraProps: { virtual: () => true, getValue: (target, value) => { console.log('getValue: ', target, value); return target.node.children.map((child) => { return { primaryKey: String(child.getPropValue('primaryKey')), children: child.getPropValue('children'), link: child.getPropValue('link'), target: child.getPropValue('target'), }; }); }, setValue: (target, value) => { console.log('setValue: ', target, value); const { node } = target; const map = {}; if (!Array.isArray(value)) { value = []; } value.forEach((item) => { const BreadcrumbItem = Object.assign({}, item); map[item.primaryKey] = BreadcrumbItem; }); node.children.mergeChildren( (child) => { const primaryKey = String(child.getPropValue('primaryKey')); console.log(`${child.id}----${primaryKey}`); if (Object.hasOwnProperty.call(map, primaryKey)) { child.setPropValue('children', map[primaryKey].children); child.setPropValue('link', map[primaryKey].link); child.setPropValue('target', map[primaryKey].target); delete map[primaryKey]; return false; } return true; }, () => { const items = []; for (const primaryKey in map) { if (Object.hasOwnProperty.call(map, primaryKey)) { items.push({ componentName: 'Breadcrumb.Item', props: map[primaryKey], }); } } console.log('adder: ', items); return items; }, (child1, child2) => { const a = value.findIndex( (item) => String(item.primaryKey) === String(child1.getPropValue('primaryKey')), ); const b = value.findIndex( (item) => String(item.primaryKey) === String(child2.getPropValue('primaryKey')), ); console.log('a: ', a); console.log('b: ', b); return a - b; }, ); }, onChange: () => { console.log('onChange: ', arguments); }, }, }, ], supports: { style: true, }, }, icon: '', category: '导航', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/breadcrumb/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Breadcrumb', title: '面包屑', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Breadcrumb', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', description: '样式类名的品牌前缀', defaultValue: 'next-', }, { name: 'rtl', propType: 'bool', }, { name: 'children', propType: { type: 'instanceOf', value: 'node', }, description: '面包屑子节点,需传入 Breadcrumb.Item', }, { name: 'maxNode', propType: { type: 'oneOfType', value: [ 'number', { type: 'oneOf', value: ['auto'], }, ], }, description: '面包屑最多显示个数,超出部分会被隐藏, 设置为 auto 会自动根据父元素的宽度适配。', defaultValue: 100, }, { name: 'separator', propType: { type: 'instanceOf', value: 'node', }, description: '分隔符,可以是文本或 Icon', }, { name: 'component', propType: { type: 'oneOfType', value: ['string', 'func'], }, description: '设置标签类型', defaultValue: 'nav', }, { name: 'className', propType: 'any', }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: true, nestingRule: { childWhitelist: ['Breadcrumb.Item'], }, }, props: [ { name: 'maxNode', title: { label: '最大节点数', tip: '默认 100', }, setter: 'NumberSetter', supportVariable: true, }, { name: 'separator', title: '分隔符', setter: 'StringSetter', supportVariable: true, }, { name: 'Breadcrumb.Item', title: '面包屑项', setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'primaryKey', title: '面包屑项编号', condition: () => false, initialValue: (val) => { if (val) return val; return String(Math.floor(Math.random() * 10000)); }, setter: 'StringSetter', supportVariable: true, }, { name: 'children', title: '标题', initialValue: { zh_CN: '', en_US: '', type: 'i18n', }, setter: 'StringSetter', supportVariable: true, }, { name: 'link', title: '链接', initialValue: { zh_CN: '', en_US: '', type: 'i18n', }, setter: 'StringSetter', supportVariable: true, }, { name: 'target', title: '打开方式', initialValue: { zh_CN: '', en_US: '', type: 'i18n', }, setter: { componentName: 'RadioGroupSetter', initialValue: '_self', props: { options: [ { title: '新开页面', value: '_blank', }, { title: '当前页面', value: '_self', }, ], }, }, }, ], }, }, initialValue: () => { return { primaryKey: String(Math.floor(Math.random() * 10000)), children: 'Title', target: '_self', }; }, }, }, }, extraProps: { virtual: () => true, getValue: (target, value) => { console.log('getValue: ', target, value); return target.node.children.map((child) => { return { primaryKey: String(child.getPropValue('primaryKey')), children: child.getPropValue('children'), link: child.getPropValue('link'), target: child.getPropValue('target'), }; }); }, setValue: (target, value) => { console.log('setValue: ', target, value); const { node } = target; const map = {}; if (!Array.isArray(value)) { value = []; } value.forEach((item) => { const BreadcrumbItem = Object.assign({}, item); map[item.primaryKey] = BreadcrumbItem; }); node.children.mergeChildren( (child) => { const primaryKey = String(child.getPropValue('primaryKey')); console.log(`${child.id}----${primaryKey}`); if (Object.hasOwnProperty.call(map, primaryKey)) { child.setPropValue('children', map[primaryKey].children); child.setPropValue('link', map[primaryKey].link); child.setPropValue('target', map[primaryKey].target); delete map[primaryKey]; return false; } return true; }, () => { const items = []; for (const primaryKey in map) { if (Object.hasOwnProperty.call(map, primaryKey)) { items.push({ componentName: 'Breadcrumb.Item', props: map[primaryKey], }); } } console.log('adder: ', items); return items; }, (child1, child2) => { const a = value.findIndex( (item) => String(item.primaryKey) === String(child1.getPropValue('primaryKey')), ); const b = value.findIndex( (item) => String(item.primaryKey) === String(child2.getPropValue('primaryKey')), ); console.log('a: ', a); console.log('b: ', b); return a - b; }, ); }, onChange: () => { console.log('onChange: ', arguments); }, }, }, ], supports: { style: true, }, }, icon: '', category: '引导', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/breadcrumb/snippets.ts ================================================ module.exports = [ { title: '面包屑', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_breadcrumb.png', schema: { componentName: 'Breadcrumb', props: { maxNode: 100, component: 'nav', }, children: [ { componentName: 'Breadcrumb.Item', props: { children: '一级', primaryKey: 'breadcrumb-item-1', target: '_self', }, }, { componentName: 'Breadcrumb.Item', props: { children: '二级', primaryKey: 'breadcrumb-item-2', target: '_self', }, }, { componentName: 'Breadcrumb.Item', props: { children: '三级', primaryKey: 'breadcrumb-item-3', target: '_self', }, }, ], }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/breadcrumb-item/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Breadcrumb.Item', title: '面包屑 Item', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Breadcrumb', main: '', destructuring: true, subName: 'Item', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'rtl', propType: 'bool', }, { name: 'children', description: '内容', propType: 'string', }, { name: 'link', propType: 'string', description: '面包屑节点链接,如果设置这个属性,则该节点为`` ,否则是``', }, { name: 'activated', propType: 'bool', }, { name: 'separator', propType: { type: 'instanceOf', value: 'node', }, }, { name: 'className', propType: 'any', }, { name: 'style', propType: 'object', }, ], configure: { props: [ { name: 'children', title: '文本内容', setter: 'StringSetter', supportVariable: true, }, ], }, icon: '', category: '引导', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/button/meta.design.ts ================================================ import snippets from './snippets.design'; export default [ { group: '原子组件', componentName: 'Button', title: '按钮', icon: 'https://img.alicdn.com/tfs/TB1rT0gPQL0gK0jSZFAXXcA9pXa-200-200.svg', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Button', main: '', destructuring: true, subName: '', }, props: [ { name: 'children', title: '内容', propType: 'string', }, { name: 'icon', propType: 'string', description: '自定义内联样式', }, { name: 'type', title: { label: { type: 'i18n', zh_CN: '按钮类型', en_US: 'Button Type', }, tip: { type: 'i18n', zh_CN: '属性: type | 说明: 按钮类型', en_US: 'prop: type | description: button type', }, }, propType: { type: 'oneOf', value: ['primary', 'secondary', 'normal'], }, description: '按钮的类型', defaultValue: 'normal', }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '按钮尺寸', en_US: 'Button Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 按钮尺寸', en_US: 'prop: size | description: button size', }, }, propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '按钮的尺寸', defaultValue: 'medium', }, { name: 'iconSize', title: { label: { type: 'i18n', zh_CN: '图标尺寸', en_US: 'Icon Size', }, tip: { type: 'i18n', zh_CN: '属性: iconSize | 说明: 图标尺寸', en_US: 'prop: iconSize | description: icon size', }, }, propType: { type: 'oneOf', value: ['xxs', 'xs', 'small', 'medium', 'large', 'xl', 'xxl', 'xxxl'], }, defaultValue: 'small', description: '按钮中 Icon 的尺寸,用于替代 Icon 的默认大小', }, { name: 'ghost', title: { type: 'i18n', zh_CN: '幽灵按钮', en_US: 'ghost', }, propType: { type: 'oneOf', value: [true, false, 'light', 'dark'], }, description: '是否为幽灵按钮', defaultValue: false, }, { name: 'loading', title: 'loading', propType: 'bool', description: '设置按钮的载入状态', defaultValue: false, }, { name: 'text', title: { type: 'i18n', zh_CN: '文本按钮', en_US: 'text', }, propType: 'bool', description: '是否为文本按钮', defaultValue: false, }, { name: 'warning', title: 'warning', propType: 'bool', description: '是否为警告按钮', defaultValue: false, }, { name: 'disabled', title: { type: 'i18n', zh_CN: '禁用', en_US: 'disabled', }, propType: 'bool', description: '是否禁用', defaultValue: false, }, { name: 'onClick', title: 'onClick', propType: 'func', description: '点击按钮的回调\n@param {Object} e Event Object', }, { name: 'className', propType: 'string', }, { name: 'onMouseUp', propType: 'func', }, { name: 'style', propType: 'object', description: '自定义内联样式', }, ], configure: { props: [ { name: 'children', title: { label: { type: 'i18n', zh_CN: '内容', en_US: 'Content', }, tip: { type: 'i18n', zh_CN: '属性: children | 说明: 按钮文本', en_US: 'prop: children | description: button content', }, }, setter: 'StringSetter', }, { name: 'icon', title: { label: { type: 'i18n', zh_CN: '图标', en_US: 'Icon', }, tip: { type: 'i18n', zh_CN: '属性: icon | 说明: 图标类型', en_US: 'prop: icon | description: icon type', }, }, setter: 'IconSetter', supportVariable: false, setValue: (target, value) => { target.node.children.importSchema( value && { componentName: 'Icon', props: { type: value, style: { marginRight: 5 } }, }, true, ); }, }, { name: '!type', title: { type: 'i18n', zh_CN: '类型', en_US: 'type', }, getValue: (target) => { const parentTarget = target.parent; const isTextButton = parentTarget.getPropValue('text'); const isWarningButton = parentTarget.getPropValue('warning'); const ghostConfig = parentTarget.getPropValue('ghost'); if (isTextButton) { return 'text'; } else if (isWarningButton) { return 'warning'; } else if (typeof ghostConfig !== 'undefined' && ghostConfig !== false) { return 'ghost'; } else { return 'normal'; } }, setValue: (target, value) => { const parentTarget = target.parent; parentTarget.setPropValue('text', false); parentTarget.setPropValue('warning', false); parentTarget.setPropValue('ghost', false); switch (value) { case 'normal': break; case 'text': parentTarget.setPropValue('text', true); break; case 'warning': parentTarget.setPropValue('warning', true); break; case 'ghost': parentTarget.setPropValue('ghost', true); break; default: break; } }, setter: { componentName: 'SelectSetter', props: { options: [ { title: '普通按钮', value: 'normal', }, { title: '文本按钮', value: 'text', }, { title: '提示按钮', value: 'warning', }, { title: '幽灵按钮', value: 'ghost', }, // { // title: "按钮组", // value: "group" // }, ], }, }, defaultValue: 'normal', }, { name: 'type', title: { label: { type: 'i18n', zh_CN: '形式', en_US: 'Button Type', }, tip: { type: 'i18n', zh_CN: '属性: type | 说明: 按钮类型', en_US: 'prop: type | description: button type', }, }, condition: (target) => target?.parent?.getPropValue('!type') !== 'ghost', setter: { componentName: 'RadioGroupSetter', props: (target) => { const _type = target?.parent?.getPropValue('!type'); let options = [ { label: '主要', value: 'primary', }, { label: '次要', value: 'secondary', }, { label: '普通', value: 'normal', }, ]; if (_type === 'warning') { options = [ { label: '主要', value: 'primary', }, { label: '普通', value: 'normal', }, ]; } return { options }; }, }, defaultValue: 'normal', }, { name: 'ghost', title: { label: { type: 'i18n', zh_CN: '形式', en_US: 'Button Type', }, tip: { type: 'i18n', zh_CN: '属性: type | 说明: 按钮类型', en_US: 'prop: type | description: button type', }, }, condition: (target) => target?.parent?.getPropValue('!type') === 'ghost', setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: 'Light', value: 'light', }, { label: 'Dark', value: 'dark', }, ], }, }, }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Button Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 按钮尺寸', en_US: 'prop: size | description: button size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '小', value: 'small', }, { label: '中', value: 'medium', }, { label: '大', value: 'large', }, ], }, }, defaultValue: 'medium', }, { name: '!status', title: { label: { type: 'i18n', zh_CN: '状态', en_US: 'Button Status', }, tip: { type: 'i18n', zh_CN: '属性: 虚拟属性 | 说明: 按钮状态', en_US: 'prop: virtual | description: button status', }, }, setter: { componentName: 'SelectSetter', props: { options: [ { title: '普通', value: 'normal', }, // { // title: "悬停", // value: 'hover' // }, // { // title: "激活", // value: "active" // }, { title: '禁用', value: 'disabled', }, { title: '加载', value: 'loading', }, ], }, }, getValue: (target) => { const parentTarget = target.parent; const loading = parentTarget.getPropValue('loading'); const disabled = parentTarget.getPropValue('disabled'); if (loading) { return 'loading'; } else if (disabled) { return 'disabled'; } else { return 'normal'; } }, setValue: (target, value) => { const parentTarget = target.parent; parentTarget.setPropValue('loading', false); parentTarget.setPropValue('disabled', false); switch (value) { case 'normal': break; case 'loading': parentTarget.setPropValue('loading', true); break; case 'disabled': parentTarget.setPropValue('disabled', true); break; default: break; } }, defaultValue: 'normal', }, ], }, category: '通用', snippets, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/button/meta.ts ================================================ import snippets from './snippets'; export default { group: '原子组件', componentName: 'Button', title: '按钮', icon: 'https://img.alicdn.com/tfs/TB1rT0gPQL0gK0jSZFAXXcA9pXa-200-200.svg', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Button', main: '', destructuring: true, subName: '', }, props: [ { name: 'children', title: '内容', propType: 'string', }, { name: 'icon', propType: 'string', description: '自定义内联样式', }, { name: 'type', title: { label: { type: 'i18n', zh_CN: '按钮类型', en_US: 'Button Type', }, tip: { type: 'i18n', zh_CN: '属性: type | 说明: 按钮类型', en_US: 'prop: type | description: button type', }, }, propType: { type: 'oneOf', value: ['primary', 'secondary', 'normal'], }, description: '按钮的类型', defaultValue: 'normal', }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '按钮尺寸', en_US: 'Button Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 按钮尺寸', en_US: 'prop: size | description: button size', }, }, propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '按钮的尺寸', defaultValue: 'medium', }, { name: 'iconSize', title: { label: { type: 'i18n', zh_CN: '图标尺寸', en_US: 'Icon Size', }, tip: { type: 'i18n', zh_CN: '属性: iconSize | 说明: 图标尺寸', en_US: 'prop: iconSize | description: icon size', }, }, propType: { type: 'oneOf', value: ['xxs', 'xs', 'small', 'medium', 'large', 'xl', 'xxl', 'xxxl'], }, defaultValue: 'small', description: '按钮中 Icon 的尺寸,用于替代 Icon 的默认大小', }, { name: 'ghost', title: { type: 'i18n', zh_CN: '幽灵按钮', en_US: 'ghost', }, propType: { type: 'oneOf', value: [true, false, 'light', 'dark'], }, description: '是否为幽灵按钮', defaultValue: false, }, { name: 'loading', title: 'loading', propType: 'bool', description: '设置按钮的载入状态', defaultValue: false, }, { name: 'text', title: { type: 'i18n', zh_CN: '文本按钮', en_US: 'text', }, propType: 'bool', description: '是否为文本按钮', defaultValue: false, }, { name: 'warning', title: 'warning', propType: 'bool', description: '是否为警告按钮', defaultValue: false, }, { name: 'disabled', title: { type: 'i18n', zh_CN: '禁用', en_US: 'disabled', }, propType: 'bool', description: '是否禁用', defaultValue: false, }, { name: 'onClick', title: 'onClick', propType: 'func', description: '点击按钮的回调\n@param {Object} e Event Object', }, { name: 'className', propType: 'string', }, { name: 'onMouseUp', propType: 'func', }, { name: 'style', propType: 'object', description: '自定义内联样式', }, ], configure: { props: { isExtends: true, override: [ { name: 'icon', title: { label: { type: 'i18n', zh_CN: '图标', en_US: 'Icon', }, tip: { type: 'i18n', zh_CN: '属性: icon | 说明: 图标类型', en_US: 'prop: icon | description: icon type', }, }, setter: 'IconSetter', supportVariable: true, setValue: (target, value) => { target.node.children.importSchema( value && { componentName: 'Icon', props: { type: value, style: { marginRight: 5 } }, }, true, ); }, }, { name: 'ghost', title: { type: 'i18n', zh_CN: '幽灵按钮', en_US: 'ghost', }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: 'True', value: true, }, { title: 'False', value: false, }, { title: 'Light', value: 'light', }, { title: 'Dark', value: 'dark', }, ], }, }, description: '是否为幽灵按钮', defaultValue: false, }, { name: 'children', title: { label: { type: 'i18n', zh_CN: '按钮内容', en_US: 'Content', }, tip: { type: 'i18n', zh_CN: '属性: children | 说明: 按钮文本', en_US: 'prop: children | description: button content', }, }, setter: { componentName: 'MixedSetter', props: { setters: ['StringSetter', 'ExpressionSetter'], }, }, }, ], }, }, category: '通用', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/button/snippets.design.ts ================================================ import { getDataFromPlainText } from '../split-button/adaptor'; const plainData = 'Edit Document\n\tUndo\n\tRedo\n\tCut\n\tCopy\n\tPaste'; const { label, children, selectedKeys } = getDataFromPlainText(plainData); const splitButtonProps = { prefix: 'next-', type: 'normal', size: 'medium', label: label, defaultSelectedKeys: [], autoWidth: true, popupTriggerType: 'click', plainData, }; if (selectedKeys && selectedKeys.length) { splitButtonProps.selectedKeys = selectedKeys; } const menuButtonProps = splitButtonProps; const snippets = [ { title: '按钮', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_button.png', schema: { componentName: 'Button', props: { prefix: 'next-', type: 'normal', size: 'medium', htmlType: 'button', component: 'button', children: '取消', }, }, }, { title: '分隔按钮', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_split-button.png', schema: { componentName: 'SplitButton', props: splitButtonProps, children, }, }, { title: '菜单按钮', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_menu-button.png', schema: { componentName: 'MenuButton', props: menuButtonProps, children, }, }, ]; export default snippets; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/button/snippets.ts ================================================ import { getDataFromPlainText } from '../split-button/adaptor'; const plainData = 'Edit Document\n\tUndo\n\tRedo\n\tCut\n\tCopy\n\tPaste'; const { label, children, selectedKeys } = getDataFromPlainText(plainData); const splitButtonProps = { prefix: 'next-', type: 'normal', size: 'medium', label: label, defaultSelectedKeys: [], autoWidth: true, popupTriggerType: 'click', plainData, }; if (selectedKeys && selectedKeys.length) { splitButtonProps.selectedKeys = selectedKeys; } const menuButtonProps = splitButtonProps; const snippets = [ { title: '按钮', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_button.png', schema: { componentName: 'Button', props: { prefix: 'next-', type: 'primary', size: 'medium', htmlType: 'button', component: 'button', children: '取消', }, }, }, { title: '分隔按钮', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_split-button.png', schema: { componentName: 'SplitButton', props: splitButtonProps, children, }, }, { title: '菜单按钮', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_split-button.png', schema: { componentName: 'MenuButton', props: menuButtonProps, children, }, }, { title: '按钮组', screenshot: 'https://img.alicdn.com/tfs/TB1t6dhvV67gK0jSZPfXXahhFXa-310-122.png', schema: { componentName: 'Button.Group', props: {}, children: [ { componentName: 'Button', props: { type: 'primary', style: { margin: '0 5px 0 5px', }, htmlType: 'submit', children: '提交', }, children: [ { componentName: 'Icon', props: { type: 'success', }, }, ], }, { componentName: 'Button', props: { type: 'normal', style: { margin: '0 5px 0 5px', }, htmlType: 'reset', children: '重置', }, }, ], }, }, ]; export default snippets; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/button-group/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Button.Group', title: '按钮组', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Button', main: '', destructuring: true, subName: 'Group', }, props: [ { name: 'rtl', propType: 'bool', }, { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'size', propType: 'string', description: '统一设置 Button 组件的按钮大小', defaultValue: 'medium', }, { name: 'className', propType: 'string', }, { name: 'children', propType: { type: 'instanceOf', value: 'node', }, }, { name: 'style', propType: 'object', description: '自定义内联样式', }, ], configure: { component: { isContainer: true, nestingRule: { childWhitelist: ['Button'], }, }, props: [ { name: 'size', display: 'block', title: { label: { type: 'i18n', zh_CN: '统一设置子按钮的尺寸', en_US: 'Button Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 统一设置子按钮的尺寸', en_US: 'prop: size | description: button size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['small', 'medium', 'large'] }, }, defaultValue: 'medium', }, ], }, icon: '', category: '常用', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/calendar/meta.design.ts ================================================ import * as moment from 'moment'; moment?.locale?.('zh-cn'); export default { group: '原子组件', componentName: 'Calendar', title: '日历', docUrl: '', screenshot: 'https://img.alicdn.com/imgextra/i3/O1CN01IAguy71sM0UGdpChd_!!6000000005751-55-tps-56-56.svg', npm: { package: '@alilc/lowcode-materials', version: 'latest', exportName: 'Calendar', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'rtl', propType: 'bool', defaultValue: false, }, { name: 'defaultValue', propType: { type: 'instanceOf', value: 'custom', }, description: '默认选中的日期(moment 对象)', }, { name: 'value', propType: { type: 'instanceOf', value: 'custom', }, description: '选中的日期值 (moment 对象)', }, { name: 'modes', propType: { type: 'instanceOf', value: 'array', }, }, { name: 'disableChangeMode', propType: 'bool', defaultValue: false, }, { name: 'format', propType: 'string', defaultValue: 'YYYY-MM-DD', }, { name: 'showOtherMonth', propType: 'bool', description: '是否展示非本月的日期', defaultValue: true, }, { name: 'defaultVisibleMonth', propType: 'func', description: '默认展示的月份', }, { name: 'shape', propType: { type: 'oneOf', value: ['card', 'fullscreen', 'panel'], }, description: '展现形态', defaultValue: 'fullscreen', }, { name: 'onSelect', propType: 'func', description: '选择日期单元格时的回调\n@param {Object} value 对应的日期值 (moment 对象)', }, { name: 'onModeChange', propType: 'func', description: '面板模式变化时的回调\n@param {String} mode 对应面板模式 date month year', }, { name: 'onVisibleMonthChange', propType: 'func', description: '展现的月份变化时的回调\n@param {Object} value 显示的月份 (moment 对象)\n@param {String} reason 触发月份改变原因', }, { name: 'className', propType: 'string', description: '自定义样式类', }, { name: 'dateCellRender', propType: 'func', description: '自定义日期渲染函数\n@param {Object} value 日期值(moment对象)\n@returns {ReactNode}', }, { name: 'monthCellRender', propType: 'func', description: '自定义月份渲染函数\n@param {Object} calendarDate 对应 Calendar 返回的自定义日期对象\n@returns {ReactNode}', }, { name: 'yearCellRender', propType: 'func', }, { name: 'disabledDate', propType: 'func', description: '不可选择的日期\n@param {Object} calendarDate 对应 Calendar 返回的自定义日期对象\n@param {String} view 当前视图类型,year: 年, month: 月, date: 日\n@returns {Boolean}', }, { name: 'locale', propType: 'object', description: '国际化配置', }, { name: 'style', propType: 'object', }, ], configure: { props: [ { name: 'shape', title: '展现形态', setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '卡片', value: 'card', }, { label: '全屏', value: 'fullscreen', }, { label: '面板', value: 'panel', }, ], }, }, }, { name: 'mode', title: '类型', defaultValue: 'date', setter: (target) => { const options = [ { label: '月', value: 'month', }, { label: '日', value: 'date', }, ]; const shape = target?.parent?.getPropValue?.('shape'); if (shape !== 'fullscreen') { options.unshift({ label: '年', value: 'year', }); } return { componentName: 'RadioGroupSetter', props: { options, }, }; }, }, { name: 'style.width', title: '宽度', setter: 'NumberSetter', }, { name: 'showOtherMonth', title: '非本月日期', setter: { componentName: 'BoolSetter', }, }, { name: 'defaultValue', title: '当前日期', setter: 'DateSetter', }, ], }, icon: 'https://img.alicdn.com/imgextra/i3/O1CN01IAguy71sM0UGdpChd_!!6000000005751-55-tps-56-56.svg', category: '信息展示', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/calendar/meta.ts ================================================ import * as moment from 'moment'; moment?.locale?.('zh-cn'); export default { group: '原子组件', componentName: 'Calendar', title: '日历', docUrl: '', screenshot: 'https://img.alicdn.com/imgextra/i3/O1CN01IAguy71sM0UGdpChd_!!6000000005751-55-tps-56-56.svg', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Calendar', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'rtl', propType: 'bool', defaultValue: false, }, { name: 'defaultValue', propType: { type: 'instanceOf', value: 'custom', }, description: '默认选中的日期(moment 对象)', }, { name: 'value', propType: { type: 'instanceOf', value: 'custom', }, description: '选中的日期值 (moment 对象)', }, { name: 'modes', propType: { type: 'instanceOf', value: 'array', }, }, { name: 'disableChangeMode', propType: 'bool', defaultValue: false, }, { name: 'format', propType: 'string', defaultValue: 'YYYY-MM-DD', }, { name: 'showOtherMonth', propType: 'bool', description: '是否展示非本月的日期', defaultValue: true, }, { name: 'defaultVisibleMonth', propType: 'func', description: '默认展示的月份', }, { name: 'shape', propType: { type: 'oneOf', value: ['card', 'fullscreen', 'panel'], }, description: '展现形态', defaultValue: 'fullscreen', }, { name: 'onSelect', propType: 'func', description: '选择日期单元格时的回调\n@param {Object} value 对应的日期值 (moment 对象)', }, { name: 'onModeChange', propType: 'func', description: '面板模式变化时的回调\n@param {String} mode 对应面板模式 date month year', }, { name: 'onVisibleMonthChange', propType: 'func', description: '展现的月份变化时的回调\n@param {Object} value 显示的月份 (moment 对象)\n@param {String} reason 触发月份改变原因', }, { name: 'className', propType: 'string', description: '自定义样式类', }, { name: 'dateCellRender', propType: 'func', description: '自定义日期渲染函数\n@param {Object} value 日期值(moment对象)\n@returns {ReactNode}', }, { name: 'monthCellRender', propType: 'func', description: '自定义月份渲染函数\n@param {Object} calendarDate 对应 Calendar 返回的自定义日期对象\n@returns {ReactNode}', }, { name: 'yearCellRender', propType: 'func', }, { name: 'disabledDate', propType: 'func', description: '不可选择的日期\n@param {Object} calendarDate 对应 Calendar 返回的自定义日期对象\n@param {String} view 当前视图类型,year: 年, month: 月, date: 日\n@returns {Boolean}', }, { name: 'locale', propType: 'object', description: '国际化配置', }, { name: 'style', propType: 'object', }, ], configure: { props: [ { name: 'shape', title: '展现形态', setter: { componentName: 'RadioGroupSetter', props: { options: ['card', 'fullscreen', 'panel'] }, }, }, { name: 'showOtherMonth', display: 'block', title: '展示非本月日期', setter: { componentName: 'BoolSetter', }, }, ], }, icon: 'https://img.alicdn.com/imgextra/i3/O1CN01IAguy71sM0UGdpChd_!!6000000005751-55-tps-56-56.svg', category: '信息展示', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/calendar/snippets.ts ================================================ module.exports = [ { screenshot: 'https://img.alicdn.com/imgextra/i3/O1CN01IAguy71sM0UGdpChd_!!6000000005751-55-tps-56-56.svg', title: '卡片型', schema: { componentName: 'Calendar', props: { shape: 'card', }, }, }, { screenshot: 'https://img.alicdn.com/imgextra/i3/O1CN01IAguy71sM0UGdpChd_!!6000000005751-55-tps-56-56.svg', title: '面板型', schema: { componentName: 'Calendar', props: { shape: 'panel', }, }, }, { screenshot: 'https://img.alicdn.com/imgextra/i3/O1CN01IAguy71sM0UGdpChd_!!6000000005751-55-tps-56-56.svg', title: '全屏型', schema: { componentName: 'Calendar', props: { shape: 'fullscreen', }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/card/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Card', title: '卡片', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Card', main: '', destructuring: true, subName: '', }, props: [ { name: 'id', propType: 'string', }, { name: 'showTitleBullet', title: '标题符号', propType: 'bool', description: '标题的项目符号', defaultValue: true, }, { name: 'showHeadDivider', title: '分割线', propType: 'bool', description: '头部分隔线', defaultValue: true, }, { name: 'title', propType: { type: 'oneOfType', value: ['node', 'string'], }, description: '标题', }, { name: 'subTitle', propType: { type: 'oneOfType', value: ['node', 'string'], }, description: '副标题', }, { name: 'extra', title: { label: '自定义内容', tip: '标题栏用户自定义内容', }, propType: { type: 'oneOfType', value: ['node', 'string'], }, description: '标题栏用户自定义内容', }, { name: 'contentHeight', title: '内容高度', propType: { type: 'oneOfType', value: ['string', 'number'], }, description: '内容区域的固定高度', defaultValue: 120, }, { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, { name: 'rtl', propType: 'bool', description: '文本方向是从右向左', }, ], configure: { component: { isContainer: true, }, props: { isExtends: true, override: [ { name: 'id', condition: () => false, }, { name: 'rtl', condition: () => false, }, ], }, }, icon: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_card.png', category: '信息输入', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/card/snippets.ts ================================================ module.exports = [ { screenshot: 'https://img.alicdn.com/tfs/TB1CHN3u4z1gK0jSZSgXXavwpXa-112-64.png', title: '普通型', schema: { componentName: 'Card', props: { title: '普通型卡片', }, children: [], }, }, { screenshot: 'https://img.alicdn.com/tfs/TB1.Ut6u4D1gK0jSZFKXXcJrVXa-112-64.png', title: '自定义', schema: { componentName: 'Card', props: { title: '自定义卡片', extra: { type: 'JSSlot', }, }, children: [], }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/card-actions/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'CardActions', title: 'CardActions', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Card', main: '', destructuring: true, subName: 'Actions', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'component', propType: { type: 'instanceOf', value: 'elementType', }, description: '设置标签类型', defaultValue: 'div', }, { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, ], category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/card-bullet-header/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'CardBulletHeader', title: 'CardBulletHeader', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Card', main: '', destructuring: true, subName: 'BulletHeader', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'title', propType: { type: 'instanceOf', value: 'node', }, description: '卡片的标题', }, { name: 'subTitle', propType: { type: 'instanceOf', value: 'node', }, description: '卡片的副标题', }, { name: 'showTitleBullet', propType: 'bool', description: '是否显示标题的项目符号', defaultValue: true, }, { name: 'extra', propType: { type: 'instanceOf', value: 'node', }, description: '标题区域的用户自定义内容', }, { name: 'style', propType: 'object', }, ], category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/card-collaspe-content/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'CardCollaspeContent', title: 'CardCollaspeContent', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Card', main: '', destructuring: true, subName: 'CollaspeContent', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'contentHeight', propType: { type: 'oneOfType', value: ['string', 'number'], }, description: '内容区域的固定高度', defaultValue: 120, }, { name: 'locale', propType: 'object', }, { name: 'children', propType: { type: 'instanceOf', value: 'node', }, }, { name: 'style', propType: 'object', }, ], category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/card-content/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'CardContent', title: 'CardContent', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Card', main: '', destructuring: true, subName: 'Content', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'component', propType: { type: 'instanceOf', value: 'elementType', }, description: '设置标签类型', defaultValue: 'div', }, { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, ], category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/card-divider/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'CardDivider', title: 'CardDivider', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Card', main: '', destructuring: true, subName: 'Divider', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'component', propType: { type: 'instanceOf', value: 'elementType', }, description: '设置标签类型', defaultValue: 'hr', }, { name: 'inset', propType: 'bool', description: '分割线是否向内缩进', }, { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, ], category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/card-header/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'CardHeader', title: 'CardHeader', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Card', main: '', destructuring: true, subName: 'Header', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'title', propType: { type: 'instanceOf', value: 'node', }, description: '卡片的标题', }, { name: 'subTitle', propType: { type: 'instanceOf', value: 'node', }, description: '卡片的副标题', }, { name: 'extra', propType: { type: 'instanceOf', value: 'node', }, description: '标题区域的用户自定义内容', }, { name: 'component', propType: { type: 'instanceOf', value: 'elementType', }, description: '设置标签类型', defaultValue: 'div', }, { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, ], category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/card-media/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'CardMedia', title: 'CardMedia', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Card', main: '', destructuring: true, subName: 'Media', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'component', propType: { type: 'instanceOf', value: 'elementType', }, description: '设置标签类型', defaultValue: 'div', }, { name: 'image', propType: 'string', description: '背景图片地址', }, { name: 'src', propType: 'string', description: '媒体源文件地址', }, { name: 'style', propType: 'object', }, { name: 'className', propType: 'string', }, ], category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/cascader/meta.design.ts ================================================ import parseData from '../utils/parse-data'; import { createDataSource } from '../cascader-select/adaptor'; export default { group: '原子组件', componentName: 'Cascader', title: '级联', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Cascader', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'label', title: { label: 'label', tip: '自定义内联 label', }, propType: 'string', description: '自定义内联 label', }, { name: 'className', propType: 'string', }, { name: 'size', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '大小', defaultValue: 'medium', }, { name: 'placeholder', propType: 'string', description: '占位符', }, { name: 'dataSource', propType: { type: 'arrayOf', value: 'object', }, }, { name: 'disabled', propType: 'bool', description: '是否禁用', defaultValue: false, }, { name: 'hasArrow', propType: 'bool', description: '下拉箭头', defaultValue: true, }, { name: 'hasBorder', propType: 'bool', description: '边框', defaultValue: true, }, { name: 'hasClear', propType: 'bool', description: '清除按钮', defaultValue: false, }, { name: 'notFoundContent', title: { label: '无数据时显示内容', tip: 'notFoundContent', }, propType: { type: 'oneOfType', value: ['node', 'string'], }, description: '无数据时显示内容', defaultValue: 'Not Found', }, { name: 'loadData', propType: 'func', description: '异步加载数据函数\n@param {Object} data 当前点击异步加载的数据', }, { name: 'header', propType: 'node', description: '自定义下拉框头部', }, { name: 'footer', propType: 'node', description: '自定义下拉框底部', }, { name: 'defaultVisible', title: { label: '初始下拉框是否显示', tip: 'defaultVisible', }, propType: 'bool', description: '初始下拉框是否显示', defaultValue: false, }, { name: 'visible', title: { label: '当前下拉框是否显示', tip: 'visible', }, propType: 'bool', description: '当前下拉框是否显示', }, { name: 'readOnly', propType: 'bool', description: '是否只读', }, { name: 'onChange', propType: 'func', description: '选中值改变时触发的回调函数\n@param {String|Array} value 选中的值,单选时返回单个值,多选时返回数组\n@param {Object|Array} data 选中的数据,包括 value 和 label,单选时返回单个值,多选时返回数组,父子节点选中关联时,同时选中,只返回父节点\n@param {Object} extra 额外参数\n@param {Array} extra.selectedPath 单选时选中的数据的路径\n@param {Boolean} extra.checked 多选时当前的操作是选中还是取消选中\n@param {Object} extra.currentData 多选时当前操作的数据\n@param {Array} extra.checkedData 多选时所有被选中的数据\n@param {Array} extra.indeterminateData 多选时半选的数据', }, { name: 'expandTriggerType', propType: { type: 'oneOf', value: ['click', 'hover'], }, description: '展开触发方式', defaultValue: 'click', }, { name: 'onExpand', propType: 'func', }, { name: 'useVirtual', propType: 'bool', description: '虚拟滚动', defaultValue: false, }, { name: 'multiple', propType: 'bool', description: '是否多选', defaultValue: false, }, { name: 'changeOnSelect', title: { label: '选中即改变', tip: 'changeOnSelect|是否选中即发生改变, 该属性仅在单选模式下有效', }, propType: 'bool', description: '是否选中即发生改变, 该属性仅在单选模式下有效', defaultValue: false, }, { name: 'canOnlyCheckLeaf', title: { label: 'canOnlyCheckLeaf', tip: '是否只能勾选叶子项的checkbox,该属性仅在多选模式下有效', }, propType: 'bool', description: '是否只能勾选叶子项的checkbox,该属性仅在多选模式下有效', defaultValue: false, }, { name: 'checkStrictly', title: { label: 'checkStrictly', tip: '父子节点是否选中不关联', }, propType: 'bool', description: '父子节点是否选中不关联', defaultValue: false, }, { name: 'listStyle', propType: 'object', description: '每列列表样式对象', }, { name: 'resultAutoWidth', title: { label: 'resultAutoWidth', tip: '搜索结果列表是否和选择框等宽', }, propType: 'bool', description: '搜索结果列表是否和选择框等宽', defaultValue: true, }, { name: 'showSearch', propType: 'bool', description: '搜索框', defaultValue: false, }, { name: 'filter', propType: 'func', description: '自定义搜索函数\n@param {String} searchValue 搜索的关键字\n@param {Array} path 节点路径\n@return {Boolean} 是否匹配\n@default 根据路径所有节点的文本值模糊匹配', }, { name: 'onVisibleChange', propType: 'func', description: '下拉框显示或关闭时触发事件的回调函数\n@param {Boolean} visible 是否显示\n@param {String} type 触发显示关闭的操作类型, fromTrigger 表示由trigger的点击触发; docClick 表示由document的点击触发', }, { name: 'popupStyle', propType: 'object', description: '下拉框自定义样式对象', }, { name: 'popupProps', propType: 'object', description: '透传到 Popup 的属性对象', }, { name: 'followTrigger', title: { label: '是否跟随滚动', tip: 'followTrigger', }, propType: 'bool', description: '是否跟随滚动', }, { name: 'isPreview', title: { label: '是否为预览态', tip: 'isPreview', }, propType: 'bool', description: '是否为预览态', }, { name: 'style', propType: 'object', }, { name: 'popupContainer', propType: 'any', description: '弹层容器\n@param {Element} target 目标元素\n@return {Element} 弹层的容器元素', }, ], configure: { supports: { style: true, events: ['onChange', 'onExpand', 'onVisibleChange'], }, props: [ { name: 'expandTriggerType', title: { label: '触发方式', tip: 'expandTriggerType | 展开触发的方式', }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '点击', value: 'click', }, { label: '悬浮', value: 'hover', }, ], }, }, description: '展开触发的方式', defaultValue: 'click', }, { name: 'style.width', title: '宽度', setter: 'NumberSetter', }, { name: 'useVirtual', title: { label: '虚拟滚动', tip: 'useVirtual | 是否开启虚拟滚动', }, setter: 'BoolSetter', defaultValue: false, }, { name: 'multiple', title: '是否多选', setter: 'BoolSetter', defaultValue: false, }, { name: 'plainData', display: 'block', title: '内容', tip: { title: '数据格式', url: '', }, setValue: (target, value) => { const list = parseData(value).filter(({ type }) => 'node' === type); const keys = { selected: [], expanded: [] }; const dataSource = createDataSource(list, keys); target.parent.setPropValue('dataSource', dataSource); target.parent.setPropValue('value', keys.selected); }, setter: { componentName: 'MagicEditorSetter', props: { toolbar: ['normal', 'active', 'disable'], disableIcon: true, }, }, }, ], }, icon: '', category: '信息输入', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/cascader/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Cascader', title: '级联', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Cascader', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'rtl', propType: 'bool', defaultValue: false, }, { name: 'className', propType: 'string', }, { name: 'onChange', propType: 'func', description: '选中值改变时触发的回调函数\n@param {String|Array} value 选中的值,单选时返回单个值,多选时返回数组\n@param {Object|Array} data 选中的数据,包括 value 和 label,单选时返回单个值,多选时返回数组,父子节点选中关联时,同时选中,只返回父节点\n@param {Object} extra 额外参数\n@param {Array} extra.selectedPath 单选时选中的数据的路径\n@param {Boolean} extra.checked 多选时当前的操作是选中还是取消选中\n@param {Object} extra.currentData 多选时当前操作的数据\n@param {Array} extra.checkedData 多选时所有被选中的数据\n@param {Array} extra.indeterminateData 多选时半选的数据', }, { name: 'onSelect', propType: 'func', }, { name: 'dataSource', propType: 'array', }, { name: 'expandTriggerType', title: { label: '触发方式', tip: 'expandTriggerType | 展开触发的方式', }, propType: { type: 'oneOf', value: ['click', 'hover'], }, description: '展开触发的方式', defaultValue: 'click', }, { name: 'onExpand', propType: 'func', description: '展开时触发的回调函数\n@param {Array} expandedValue 各列展开值的数组', }, { name: 'useVirtual', title: { label: '虚拟滚动', tip: 'useVirtual | 是否开启虚拟滚动', }, propType: 'bool', description: '是否开启虚拟滚动', defaultValue: false, }, { name: 'multiple', propType: 'bool', description: '是否多选', defaultValue: false, }, { name: 'canOnlySelectLeaf', title: { label: '单选时是否只能选中叶子节点', tip: 'canOnlySelectLeaf', }, propType: 'bool', description: '单选时是否只能选中叶子节点', defaultValue: false, }, { name: 'canOnlyCheckLeaf', title: { label: '多选时是否只能选中叶子节点', tip: 'canOnlyCheckLeaf', }, propType: 'bool', description: '多选时是否只能选中叶子节点', defaultValue: false, }, { name: 'checkStrictly', title: { tip: 'checkStrictly', label: '父子节点是否选中不关联', }, propType: 'bool', description: '父子节点是否选中不关联', defaultValue: false, }, { name: 'listStyle', propType: 'object', description: '每列列表样式对象', }, { name: 'loadData', title: { label: 'loadData', tip: '异步加载数据函数\n@param {Object} data 当前点击异步加载的数据\n@param {Object} source 当前点击数据,source是原始对象', }, propType: 'func', description: '异步加载数据函数\n@param {Object} data 当前点击异步加载的数据\n@param {Object} source 当前点击数据,source是原始对象', }, { name: 'onBlur', propType: 'func', }, { name: 'style', propType: 'object', }, ], configure: { props: { isExtends: true, override: [ { name: 'rtl', condition: () => false, }, { name: 'prefix', condition: () => false, }, { name: 'loadData', condition: () => false, }, { name: 'listStyle', setter: 'ObjectSetter', condition: () => false, }, { name: 'dataSource', title: '级联数据', setter: 'JsonSetter', supportVariable: true, }, { name: 'canOnlySelectLeaf', display: 'block', title: { label: '单选时是否只能选中叶子节点', tip: 'canOnlySelectLeaf', }, setter: 'BoolSetter', supportVariable: true, defaultValue: false, }, { name: 'canOnlyCheckLeaf', display: 'block', title: { label: '多选时是否只能选中叶子节点', tip: 'canOnlyCheckLeaf', }, setter: 'BoolSetter', supportVariable: true, defaultValue: false, }, { name: 'checkStrictly', display: 'block', title: { tip: 'checkStrictly', label: '父子节点是否选中不关联', }, setter: 'BoolSetter', supportVariable: true, defaultValue: false, }, ], }, }, icon: '', category: '信息输入', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/cascader-select/adaptor.ts ================================================ let index = 1000; export const createDataSource = (list, map = {}) => { if (!list) return []; return list .filter((item) => item.type === 'node') .map(({ value, children, state }) => { const key = String(index++); if (state === 'active') { if (!children || children.length === 0) { map.selected.push(key); } else { map.expanded.push(key); } } return { value: key, label: value, disabled: state === 'disabled', children: createDataSource(children, map), }; }); }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/cascader-select/meta.design.ts ================================================ import snippets from './snippets.design'; import parseData from '../utils/parse-data'; import { createDataSource } from './adaptor'; export default { group: '原子组件', componentName: 'CascaderSelect', title: '级联选择器', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'CascaderSelect', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'label', title: { label: 'label', tip: '自定义内联 label', }, propType: 'string', description: '自定义内联 label', }, { name: 'className', propType: 'string', }, { name: 'size', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '大小', defaultValue: 'medium', }, { name: 'placeholder', propType: 'string', description: '占位符', }, { name: 'dataSource', propType: { type: 'arrayOf', value: 'object', }, }, { name: 'disabled', propType: 'bool', description: '是否禁用', defaultValue: false, }, { name: 'hasArrow', propType: 'bool', description: '下拉箭头', defaultValue: true, }, { name: 'hasBorder', propType: 'bool', description: '边框', defaultValue: true, }, { name: 'hasClear', propType: 'bool', description: '清除按钮', defaultValue: false, }, { name: 'notFoundContent', title: { label: '无数据时显示内容', tip: 'notFoundContent', }, propType: { type: 'oneOfType', value: ['node', 'string'], }, description: '无数据时显示内容', defaultValue: 'Not Found', }, { name: 'loadData', propType: 'func', description: '异步加载数据函数\n@param {Object} data 当前点击异步加载的数据', }, { name: 'header', propType: 'node', description: '自定义下拉框头部', }, { name: 'footer', propType: 'node', description: '自定义下拉框底部', }, { name: 'defaultVisible', title: { label: '初始下拉框是否显示', tip: 'defaultVisible', }, propType: 'bool', description: '初始下拉框是否显示', defaultValue: false, }, { name: 'visible', title: { label: '当前下拉框是否显示', tip: 'visible', }, propType: 'bool', description: '当前下拉框是否显示', }, { name: 'readOnly', propType: 'bool', description: '是否只读', }, { name: 'onChange', propType: 'func', description: '选中值改变时触发的回调函数\n@param {String|Array} value 选中的值,单选时返回单个值,多选时返回数组\n@param {Object|Array} data 选中的数据,包括 value 和 label,单选时返回单个值,多选时返回数组,父子节点选中关联时,同时选中,只返回父节点\n@param {Object} extra 额外参数\n@param {Array} extra.selectedPath 单选时选中的数据的路径\n@param {Boolean} extra.checked 多选时当前的操作是选中还是取消选中\n@param {Object} extra.currentData 多选时当前操作的数据\n@param {Array} extra.checkedData 多选时所有被选中的数据\n@param {Array} extra.indeterminateData 多选时半选的数据', }, { name: 'expandTriggerType', propType: { type: 'oneOf', value: ['click', 'hover'], }, description: '展开触发方式', defaultValue: 'click', }, { name: 'onExpand', propType: 'func', }, { name: 'useVirtual', propType: 'bool', description: '虚拟滚动', defaultValue: false, }, { name: 'multiple', propType: 'bool', description: '是否多选', defaultValue: false, }, { name: 'changeOnSelect', title: { label: '选中即改变', tip: 'changeOnSelect|是否选中即发生改变, 该属性仅在单选模式下有效', }, propType: 'bool', description: '是否选中即发生改变, 该属性仅在单选模式下有效', defaultValue: false, }, { name: 'canOnlyCheckLeaf', title: { label: 'canOnlyCheckLeaf', tip: '是否只能勾选叶子项的checkbox,该属性仅在多选模式下有效', }, propType: 'bool', description: '是否只能勾选叶子项的checkbox,该属性仅在多选模式下有效', defaultValue: false, }, { name: 'checkStrictly', title: { label: 'checkStrictly', tip: '父子节点是否选中不关联', }, propType: 'bool', description: '父子节点是否选中不关联', defaultValue: false, }, { name: 'listStyle', propType: 'object', description: '每列列表样式对象', }, { name: 'resultAutoWidth', title: { label: 'resultAutoWidth', tip: '搜索结果列表是否和选择框等宽', }, propType: 'bool', description: '搜索结果列表是否和选择框等宽', defaultValue: true, }, { name: 'showSearch', propType: 'bool', description: '搜索框', defaultValue: false, }, { name: 'filter', propType: 'func', description: '自定义搜索函数\n@param {String} searchValue 搜索的关键字\n@param {Array} path 节点路径\n@return {Boolean} 是否匹配\n@default 根据路径所有节点的文本值模糊匹配', }, { name: 'onVisibleChange', propType: 'func', description: '下拉框显示或关闭时触发事件的回调函数\n@param {Boolean} visible 是否显示\n@param {String} type 触发显示关闭的操作类型, fromTrigger 表示由trigger的点击触发; docClick 表示由document的点击触发', }, { name: 'popupStyle', propType: 'object', description: '下拉框自定义样式对象', }, { name: 'popupProps', propType: 'object', description: '透传到 Popup 的属性对象', }, { name: 'followTrigger', title: { label: '是否跟随滚动', tip: 'followTrigger', }, propType: 'bool', description: '是否跟随滚动', }, { name: 'isPreview', title: { label: '是否为预览态', tip: 'isPreview', }, propType: 'bool', description: '是否为预览态', }, { name: 'style', propType: 'object', }, { name: 'popupContainer', propType: 'any', description: '弹层容器\n@param {Element} target 目标元素\n@return {Element} 弹层的容器元素', }, ], configure: { supports: { style: true, events: ['onChange', 'onExpand', 'onVisibleChange'], }, props: [ { name: 'label', title: { label: '内联文案', tip: 'label|输入框内置标签', }, setter: 'StringSetter', }, { name: 'placeholder', title: { label: '占位提示', tip: '属性: placeholder', }, defaultValue: '请选择', // 不生效 setter: 'StringSetter', }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Button Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 按钮尺寸', en_US: 'prop: size | description: button size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '小', value: 'small', }, { label: '中', value: 'medium', }, { label: '大', value: 'large', }, ], }, }, defaultValue: 'medium', }, { name: 'visible', title: { label: '状态', tip: '属性: visible', }, setter: { componentName: 'RadioGroupSetter', props: { defaultValue: 'single', options: [ { value: false, title: '普通' }, { value: true, title: '展开' }, ], }, }, }, { name: 'hasBorder', title: { label: { type: 'i18n', zh_CN: '显示边框', en_US: 'ShowBorder', }, tip: { type: 'i18n', zh_CN: '属性: hasBorder | 说明: 是否有边框', en_US: 'prop: hasBorder | description: HasBorder', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '无', value: false, }, { label: '有', value: true, }, ], }, }, }, { name: 'multiple', title: '复选框', setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '无', value: false, }, { label: '有', value: true, }, ], }, }, defaultValue: false, }, { name: 'style.width', title: '宽度', setter: 'NumberSetter', }, { name: 'showSearch', title: { label: '可搜索', tip: '属性: showSearch', }, setter: 'BoolSetter', defaultValue: false, }, { name: 'disabled', title: '是否禁用', setter: 'BoolSetter', defaultValue: false, }, { name: 'plainData', display: 'block', title: '内容', tip: { title: '数据格式', url: '', }, setValue: (target, value) => { const list = parseData(value).filter(({ type }) => 'node' === type); const keys = { selected: [], expanded: [] }; const dataSource = createDataSource(list, keys); target.parent.setPropValue('dataSource', dataSource); target.parent.setPropValue('value', keys.selected); }, setter: { componentName: 'MagicEditorSetter', props: { toolbar: ['normal', 'active', 'disable'], disableIcon: true, }, }, }, ], }, icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/cascader-select/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'CascaderSelect', title: '级联选择器', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'CascaderSelect', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'label', title: { label: 'label', tip: '自定义内联 label', }, propType: 'string', description: '自定义内联 label', }, { name: 'className', propType: 'string', }, { name: 'size', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '大小', defaultValue: 'medium', }, { name: 'placeholder', propType: 'string', description: '占位符', }, { name: 'dataSource', propType: { type: 'arrayOf', value: 'object', }, }, { name: 'disabled', propType: 'bool', description: '是否禁用', defaultValue: false, }, { name: 'hasArrow', propType: 'bool', description: '下拉箭头', defaultValue: true, }, { name: 'hasBorder', propType: 'bool', description: '边框', defaultValue: true, }, { name: 'hasClear', propType: 'bool', description: '清除按钮', defaultValue: false, }, { name: 'notFoundContent', title: { label: '无数据时显示内容', tip: 'notFoundContent', }, propType: { type: 'oneOfType', value: ['node', 'string'], }, description: '无数据时显示内容', defaultValue: 'Not Found', }, { name: 'loadData', propType: 'func', description: '异步加载数据函数\n@param {Object} data 当前点击异步加载的数据', }, { name: 'header', propType: 'node', description: '自定义下拉框头部', }, { name: 'footer', propType: 'node', description: '自定义下拉框底部', }, { name: 'defaultVisible', title: { label: '初始下拉框是否显示', tip: 'defaultVisible', }, propType: 'bool', description: '初始下拉框是否显示', defaultValue: false, }, { name: 'visible', title: { label: '当前下拉框是否显示', tip: 'visible', }, propType: 'bool', description: '当前下拉框是否显示', }, { name: 'readOnly', propType: 'bool', description: '是否只读', }, { name: 'onChange', propType: 'func', description: '选中值改变时触发的回调函数\n@param {String|Array} value 选中的值,单选时返回单个值,多选时返回数组\n@param {Object|Array} data 选中的数据,包括 value 和 label,单选时返回单个值,多选时返回数组,父子节点选中关联时,同时选中,只返回父节点\n@param {Object} extra 额外参数\n@param {Array} extra.selectedPath 单选时选中的数据的路径\n@param {Boolean} extra.checked 多选时当前的操作是选中还是取消选中\n@param {Object} extra.currentData 多选时当前操作的数据\n@param {Array} extra.checkedData 多选时所有被选中的数据\n@param {Array} extra.indeterminateData 多选时半选的数据', }, { name: 'expandTriggerType', propType: { type: 'oneOf', value: ['click', 'hover'], }, description: '展开触发方式', defaultValue: 'click', }, { name: 'onExpand', propType: 'func', }, { name: 'useVirtual', propType: 'bool', description: '虚拟滚动', defaultValue: false, }, { name: 'multiple', propType: 'bool', description: '是否多选', defaultValue: false, }, { name: 'changeOnSelect', title: { label: '选中即改变', tip: 'changeOnSelect|是否选中即发生改变, 该属性仅在单选模式下有效', }, propType: 'bool', description: '是否选中即发生改变, 该属性仅在单选模式下有效', defaultValue: false, }, { name: 'canOnlyCheckLeaf', title: { label: 'canOnlyCheckLeaf', tip: '是否只能勾选叶子项的checkbox,该属性仅在多选模式下有效', }, propType: 'bool', description: '是否只能勾选叶子项的checkbox,该属性仅在多选模式下有效', defaultValue: false, }, { name: 'checkStrictly', title: { label: 'checkStrictly', tip: '父子节点是否选中不关联', }, propType: 'bool', description: '父子节点是否选中不关联', defaultValue: false, }, { name: 'listStyle', propType: 'object', description: '每列列表样式对象', }, { name: 'resultAutoWidth', title: { label: 'resultAutoWidth', tip: '搜索结果列表是否和选择框等宽', }, propType: 'bool', description: '搜索结果列表是否和选择框等宽', defaultValue: true, }, { name: 'showSearch', propType: 'bool', description: '搜索框', defaultValue: false, }, { name: 'filter', propType: 'func', description: '自定义搜索函数\n@param {String} searchValue 搜索的关键字\n@param {Array} path 节点路径\n@return {Boolean} 是否匹配\n@default 根据路径所有节点的文本值模糊匹配', }, { name: 'onVisibleChange', propType: 'func', description: '下拉框显示或关闭时触发事件的回调函数\n@param {Boolean} visible 是否显示\n@param {String} type 触发显示关闭的操作类型, fromTrigger 表示由trigger的点击触发; docClick 表示由document的点击触发', }, { name: 'popupStyle', propType: 'object', description: '下拉框自定义样式对象', }, { name: 'popupProps', propType: 'object', description: '透传到 Popup 的属性对象', }, { name: 'followTrigger', title: { label: '是否跟随滚动', tip: 'followTrigger', }, propType: 'bool', description: '是否跟随滚动', }, { name: 'isPreview', title: { label: '是否为预览态', tip: 'isPreview', }, propType: 'bool', description: '是否为预览态', }, { name: 'style', propType: 'object', }, { name: 'popupContainer', propType: 'any', description: '弹层容器\n@param {Element} target 目标元素\n@return {Element} 弹层的容器元素', }, ], configure: { supports: { style: true, events: ['onChange', 'onExpand', 'onVisibleChange'], }, props: [ { name: 'label', title: { label: '内联文案', tip: '自定义内联 label', }, setter: 'StringSetter', supportVariable: true, }, { name: 'size', title: '尺寸', setter: { componentName: 'RadioGroupSetter', props: { options: ['small', 'medium', 'large'] }, }, defaultValue: 'medium', }, { name: 'placeholder', title: '占位提示', setter: 'StringSetter', supportVariable: true, }, { name: 'dataSource', title: '级联数据', setter: 'JsonSetter', supportVariable: true, }, { name: 'disabled', setter: 'BoolSetter', supportVariable: true, title: '是否禁用', defaultValue: false, }, { name: 'hasArrow', setter: 'BoolSetter', supportVariable: true, title: '下拉箭头', defaultValue: true, }, { name: 'hasBorder', setter: 'BoolSetter', supportVariable: true, title: '边框', defaultValue: true, }, { name: 'hasClear', setter: 'BoolSetter', supportVariable: true, title: '清除按钮', defaultValue: false, }, { name: 'readOnly', setter: 'BoolSetter', supportVariable: true, title: '是否只读', }, { name: 'multiple', setter: 'BoolSetter', supportVariable: true, title: '是否多选', defaultValue: false, }, { name: 'showSearch', setter: 'BoolSetter', supportVariable: true, title: '搜索框', defaultValue: false, }, { name: 'followTrigger', title: { label: '跟随滚动', tip: 'followTrigger', }, setter: 'BoolSetter', supportVariable: true, description: '是否跟随滚动', }, { name: 'isPreview', title: { label: '预览态', tip: 'isPreview', }, setter: 'BoolSetter', supportVariable: true, description: '是否为预览态', }, { name: 'expandTriggerType', display: 'block', setter: { componentName: 'RadioGroupSetter', props: { options: ['click', 'hover'] }, }, title: '展开触发方式', defaultValue: 'click', }, { name: 'notFoundContent', display: 'block', title: { label: '无数据时显示内容', tip: 'notFoundContent', }, setter: { componentName: 'MixedSetter', props: { setters: ['StringSetter', 'SlotSetter'], }, }, defaultValue: 'Not Found', }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', supportVariable: true, }, ], }, ], }, icon: '', category: '信息输入', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/cascader-select/snippets.design.ts ================================================ import parseData from '../utils/parse-data'; import { createDataSource } from './adaptor'; const plainData = '*1\n\t*1-1\n\t\t1-1-1\n\t\t1-1-2\n\t\t1-1-3\n\t\t1-1-4\n\t\t*1-1-5\n\t1-2\n\t1-3\n\t1-4\n\t1-5\n2\n\t2-1\n\t2-2\n\t2-3\n\t2-4\n\t2-5\n3\n\t3-1\n\t3-2\n\t3-3\n\t3-4\n\t3-5\n4\n\t4-1\n\t4-2\n\t4-3\n\t4-4\n\t4-5\n5\n\t5-1\n\t5-2\n\t5-3\n\t5-4\n\t5-5'; const list = parseData(plainData).filter(({ type }) => 'node' === type); const keys = { selected: [], expanded: [] }; const dataSource = createDataSource(list, keys); export default [ { title: '级联选择器', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_cascader-select.png', schema: { componentName: 'CascaderSelect', props: { prefix: 'next-', size: 'medium', hasArrow: true, hasBorder: true, expandTriggerType: 'click', resultAutoWidth: true, notFoundContent: 'Not Found', plainData, dataSource, value: keys.selected, }, }, }, { title: '级联', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_cascader.png', schema: { componentName: 'Cascader', props: { prefix: 'next-', expandTriggerType: 'click', plainData, dataSource, value: keys.selected, }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/cascader-select/snippets.ts ================================================ module.exports = [ { title: '级联选择器', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_cascader-select.png', schema: { componentName: 'CascaderSelect', props: { prefix: 'next-', size: 'medium', hasArrow: true, hasBorder: true, expandTriggerType: 'click', resultAutoWidth: true, notFoundContent: 'Not Found', dataSource: [ { value: '2974', label: '西安', children: [ { value: '2975', label: '西安市', }, { value: '2976', label: '高陵县', }, { value: '2977', label: '蓝田县', }, ], }, ], }, }, }, { title: '级联', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_cascader.png', schema: { componentName: 'Cascader', props: { prefix: 'next-', expandTriggerType: 'click', dataSource: [ { value: '2974', label: '西安', children: [ { value: '2975', label: '西安市', }, { value: '2976', label: '高陵县', }, { value: '2977', label: '蓝田县', }, ], }, ], }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/checkbox/meta.design.ts ================================================ import snippets from './snippets.design'; export default { group: '原子组件', componentName: 'Checkbox', title: '复选按钮', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Checkbox', main: '', destructuring: true, subName: '', }, props: [ { name: 'className', propType: 'string', description: '自定义类名', }, { name: 'id', propType: 'string', description: 'ID', }, { name: 'name', propType: 'string', description: 'name', }, { name: 'style', propType: 'object', description: '自定义内敛样式', }, { name: 'checked', propType: 'bool', description: '选中状态', }, { name: 'defaultChecked', propType: 'bool', description: '默认选中状态', defaultValue: false, }, { name: 'disabled', propType: 'bool', description: '禁用', }, { name: 'label', propType: 'string', description: 'label', }, { name: 'indeterminate', propType: 'bool', description: '中间状态', }, { name: 'defaultIndeterminate', propType: 'bool', description: '默认中间态', defaultValue: false, }, { name: 'value', propType: { type: 'oneOfType', value: ['string'], }, description: 'value', }, ], configure: { props: [ { name: 'label', title: '标题', setter: { componentName: 'MixedSetter', props: { setters: ['StringSetter', 'ExpressionSetter'], }, }, }, { name: 'value', title: 'Value', setter: { componentName: 'MixedSetter', props: { setters: ['StringSetter', 'ExpressionSetter'], }, }, }, { name: 'indeterminate', title: '半选状态', setter: { componentName: 'MixedSetter', props: { setters: ['BoolSetter', 'ExpressionSetter'], }, }, }, { name: 'disabled', title: '是否禁用', setter: { componentName: 'MixedSetter', props: { setters: ['BoolSetter', 'ExpressionSetter'], }, }, }, { name: 'controlChecked', display: 'block', title: { label: '外部控制选中', tip: '外部控制选中后,选中状态需要开发者自己根据 onChange 回传的值重新设置给组件才能生效', }, setter: 'BoolSetter', supportVariable: true, }, { name: 'checked', title: '选中状态', setter: { componentName: 'MixedSetter', props: { setters: ['BoolSetter', 'ExpressionSetter'], }, }, condition(target) { return target.getProps().getPropValue('controlChecked') || false; }, }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', supportVariable: true, }, ], }, ], supports: { style: true, events: ['onChange', 'onMouseEnter', 'onMouseLeave'], }, }, icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/checkbox/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Checkbox', title: '复选按钮', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Checkbox', main: '', destructuring: true, subName: '', }, props: [ { name: 'className', propType: 'string', description: '自定义类名', }, { name: 'id', propType: 'string', description: 'ID', }, { name: 'name', propType: 'string', description: 'name', }, { name: 'style', propType: 'object', description: '自定义内敛样式', }, { name: 'checked', propType: 'bool', description: '选中状态', }, { name: 'defaultChecked', propType: 'bool', description: '默认选中状态', defaultValue: false, }, { name: 'disabled', propType: 'bool', description: '禁用', }, { name: 'label', propType: 'string', description: 'label', }, { name: 'indeterminate', propType: 'bool', description: '中间状态', }, { name: 'defaultIndeterminate', propType: 'bool', description: '默认中间态', defaultValue: false, }, { name: 'value', propType: { type: 'oneOfType', value: ['string'], }, description: 'value', }, ], configure: { props: [ { name: 'label', title: '标题', setter: { componentName: 'MixedSetter', props: { setters: ['StringSetter', 'ExpressionSetter'], }, }, }, { name: 'value', title: 'Value', setter: { componentName: 'MixedSetter', props: { setters: ['StringSetter', 'ExpressionSetter'], }, }, }, { name: 'indeterminate', title: '半选状态', setter: { componentName: 'MixedSetter', props: { setters: ['BoolSetter', 'ExpressionSetter'], }, }, }, { name: 'disabled', title: '是否禁用', setter: { componentName: 'MixedSetter', props: { setters: ['BoolSetter', 'ExpressionSetter'], }, }, }, { name: 'controlChecked', display: 'block', title: { label: '外部控制选中', tip: '外部控制选中后,选中状态需要开发者自己根据 onChange 回传的值重新设置给组件才能生效', }, setter: 'BoolSetter', supportVariable: true, }, { name: 'checked', title: '选中状态', setter: { componentName: 'MixedSetter', props: { setters: ['BoolSetter', 'ExpressionSetter'], }, }, condition(target) { return target.parent.getPropValue('controlChecked') || false; }, }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', supportVariable: true, }, ], }, ], supports: { style: true, events: ['onChange', 'onMouseEnter', 'onMouseLeave'], }, }, icon: '', category: '信息输入', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/checkbox/snippets.design.ts ================================================ export default [ { title: '复选按钮组', screenshot: 'https://img.alicdn.com/tfs/TB1EJN7uYY1gK0jSZTEXXXDQVXa-112-64.png', schema: { componentName: 'CheckboxGroup', props: { prefix: 'next-', dataSource: [ { label: '选项一', value: '1', }, { label: '选项二', value: '2', }, { label: '选项三', value: '3', }, ], }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/checkbox/snippets.ts ================================================ module.exports = [ { title: '复选按钮', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_menu.png', schema: { componentName: 'Checkbox', props: { label: 'Check Option', }, }, }, { title: '复选按钮组', screenshot: 'https://img.alicdn.com/tfs/TB1EJN7uYY1gK0jSZTEXXXDQVXa-112-64.png', schema: { componentName: 'CheckboxGroup', props: { prefix: 'next-', dataSource: [ { label: '选项一', value: '1', }, { label: '选项二', value: '2', }, { label: '选项三', value: '3', }, ], }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/checkbox-group/meta.design.ts ================================================ export default { group: '原子组件', componentName: 'CheckboxGroup', title: '复选按钮组', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Checkbox', main: '', destructuring: true, subName: 'Group', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'rtl', propType: 'bool', }, { name: 'className', propType: 'string', description: '自定义类名', }, { name: 'style', propType: 'object', description: '自定义内敛样式', }, { name: 'disabled', propType: 'bool', description: '整体禁用', }, { name: 'value', propType: { type: 'oneOfType', value: [ { type: 'instanceOf', value: 'array', }, 'string', 'number', ], }, description: '被选中的值列表', }, { name: 'defaultValue', propType: { type: 'oneOfType', value: [ { type: 'instanceOf', value: 'array', }, 'string', 'number', ], }, description: '默认被选中的值列表', }, { name: 'onChange', propType: 'func', description: '选中值改变时的事件\n@param {Array} value 选中项列表\n@param {Event} e Dom 事件对象', }, { name: 'itemDirection', propType: { type: 'oneOf', value: ['hoz', 'ver'], }, description: '子项目的排列方式\n- hoz: 水平排列 (default)\n- ver: 垂直排列', defaultValue: 'hoz', }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', defaultValue: false, }, { name: 'renderPreview', propType: 'func', description: '预览态模式下渲染的内容\n@param {number} value 评分值', }, ], configure: { props: [ { name: 'itemDirection', title: '排列方式', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '水平排列', value: 'hoz' }, { title: '垂直排列', value: 'ver' }, ], }, }, defaultValue: 'hoz', }, { name: 'dataSource', display: 'block', title: '选项', setter: { componentName: 'MixedSetter', props: { setters: [ { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'label', title: 'label', setter: 'StringSetter', important: true, }, { name: 'value', title: 'value', setter: 'StringSetter', }, ], }, }, initialValue: { label: '选项一', value: '1', }, }, }, }, 'ExpressionSetter', ], }, }, }, ], supports: { style: true, events: ['onChange'], }, }, icon: '', category: '信息输入', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/checkbox-group/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'CheckboxGroup', title: '复选按钮组', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Checkbox', main: '', destructuring: true, subName: 'Group', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'rtl', propType: 'bool', }, { name: 'className', propType: 'string', description: '自定义类名', }, { name: 'style', propType: 'object', description: '自定义内敛样式', }, { name: 'disabled', propType: 'bool', description: '整体禁用', }, { name: 'value', propType: { type: 'oneOfType', value: [ { type: 'instanceOf', value: 'array', }, 'string', 'number', ], }, description: '被选中的值列表', }, { name: 'defaultValue', propType: { type: 'oneOfType', value: [ { type: 'instanceOf', value: 'array', }, 'string', 'number', ], }, description: '默认被选中的值列表', }, { name: 'onChange', propType: 'func', description: '选中值改变时的事件\n@param {Array} value 选中项列表\n@param {Event} e Dom 事件对象', }, { name: 'itemDirection', propType: { type: 'oneOf', value: ['hoz', 'ver'], }, description: '子项目的排列方式\n- hoz: 水平排列 (default)\n- ver: 垂直排列', defaultValue: 'hoz', }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', defaultValue: false, }, { name: 'renderPreview', propType: 'func', description: '预览态模式下渲染的内容\n@param {number} value 评分值', }, ], configure: { props: [ { name: 'disabled', title: '是否禁用', setter: { componentName: 'MixedSetter', props: { setters: ['BoolSetter', 'ExpressionSetter'], }, }, }, { name: 'itemDirection', title: '排列方式', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '水平排列', value: 'hoz' }, { title: '垂直排列', value: 'ver' }, ], }, }, defaultValue: 'hoz', }, { name: 'isPreview', title: '预览态', setter: { componentName: 'BoolSetter', }, }, { name: 'defaultValue', title: '默认值', defaultValue: '[]', setter: { componentName: 'MixedSetter', props: { setters: ['JsonSetter', 'ExpressionSetter'], }, }, }, { name: 'dataSource', display: 'block', title: '选项', setter: { componentName: 'MixedSetter', props: { setters: [ { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'label', title: 'label', setter: 'StringSetter', supportVariable: true, }, { name: 'value', title: 'value', setter: 'StringSetter', supportVariable: true, }, ], }, }, initialValue: { label: '选项一', value: '1', }, }, }, }, 'ExpressionSetter', ], }, }, }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', supportVariable: true, }, ], }, // { // name: "renderPreview", // title: "预览态模式下渲染的内容", // display: "block", // setter: { // componentName: "FunctionSetter" // }, // condition(target) { // return target.parent.getPropValue("isPreview") || false; // } // } ], supports: { style: true, events: ['onChange'], }, }, icon: '', category: '信息输入', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/checkbox-item/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'CheckboxItem', title: '复选框', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Menu', main: '', destructuring: true, subName: 'CheckboxItem', }, props: [ { name: 'checked', propType: 'bool', description: '是否选中', defaultValue: false, }, { name: 'indeterminate', propType: 'bool', description: '是否半选中', defaultValue: false, }, { name: 'disabled', propType: 'bool', description: '是否禁用', defaultValue: false, }, { name: 'onChange', propType: 'func', description: '选中或取消选中触发的回调函数\n@param {Boolean} checked 是否选中\n@param {Object} event 选中事件对象', }, { name: 'helper', propType: 'node', description: '帮助文本', }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: true, nestingRule: { parentWhitelist: ['Menu', 'SubMenu', 'Menu.Group', 'MenuButton'], }, }, }, icon: '', category: '信息输入', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/collapse/meta.design.ts ================================================ import snippets from './snippets.design'; import { parseData } from '../utils/parse-data'; export default { group: '原子组件', componentName: 'Collapse', title: '折叠面板', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: 'latest', exportName: 'Collapse', main: '', destructuring: true, subName: '', }, props: [ { name: 'dataSource', propType: 'array', description: '使用数据模型构建', }, { name: 'defaultExpandedKeys', propType: { type: 'arrayOf', value: 'string', }, description: '默认展开keys', }, { name: 'expandedKeys', propType: { type: 'arrayOf', value: 'string', }, description: '受控展开keys', }, { name: 'onExpand', propType: 'func', description: '展开状态发升变化时候的回调', }, { name: 'disabled', propType: 'bool', description: '所有禁用', }, { name: 'className', propType: 'string', description: '扩展class', }, { name: 'style', propType: 'object', description: '组件接受行内样式', }, { name: 'accordion', propType: 'bool', description: '手风琴模式,一次只能打开一个', defaultValue: false, }, { name: 'rtl', propType: 'bool', }, ], configure: { component: { isContainer: true, }, props: [ { name: 'disabled', title: { label: '状态', tip: 'disabled | 是否禁用', }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '普通', value: false, }, { label: '禁用', value: true, }, ], }, }, defaultValue: false, }, { name: 'style.width', title: '宽度', setter: 'NumberSetter', }, { name: 'plainData', display: 'block', title: '内容', tip: { title: '数据格式', url: '', }, setValue: (target, value) => { const list = parseData(value).filter((node) => node.type === 'node'); const defaultExpandedKeys: any[] = []; const dataSource = list.map((item, index) => { if (item.state === 'active') { defaultExpandedKeys.push(`panel_${index}`); } return { key: `panel_${index}`, title: item.value, content: item.children.map(({ type, value: v }) => (type === 'node' ? v : '')), disabled: item.state === 'disabled', }; }); target.parent.setPropValue('defaultExpandedKeys', defaultExpandedKeys); target.parent.setPropValue('dataSource', dataSource); }, setter: { componentName: 'MagicEditorSetter', props: { toolbar: ['normal', 'active', 'disable'], disableIcon: true, }, }, }, ], }, icon: '', category: '信息展示', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/collapse/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Collapse', title: '折叠面板', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Collapse', main: '', destructuring: true, subName: '', }, props: [ { name: 'dataSource', propType: 'array', description: '使用数据模型构建', }, { name: 'defaultExpandedKeys', propType: { type: 'arrayOf', value: 'string', }, description: '默认展开keys', }, { name: 'expandedKeys', propType: { type: 'arrayOf', value: 'string', }, description: '受控展开keys', }, { name: 'onExpand', propType: 'func', description: '展开状态发升变化时候的回调', }, { name: 'disabled', propType: 'bool', description: '所有禁用', }, { name: 'className', propType: 'string', description: '扩展class', }, { name: 'style', propType: 'object', description: '组件接受行内样式', }, { name: 'accordion', propType: 'bool', description: '手风琴模式,一次只能打开一个', defaultValue: false, }, { name: 'rtl', propType: 'bool', }, ], configure: { component: { isContainer: true, }, props: { isExtends: true, override: [ { name: 'dataSource', setter: { componentName: 'MixedSetter', props: { setters: ['JsonSetter', 'ExpressionSetter'], }, }, }, ], }, }, icon: '', category: '信息输入', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/collapse/snippets.design.ts ================================================ import parseData from '../utils/parse-data'; const plainData = '*Panel Header 1\n\tPeople always make mistakes, frustrated, nerve-racking, but cannot remain stagnant.\nPanel Header 2\n\tPeople always make mistakes, frustrated, nerve-racking, but cannot remain stagnant.\nPanel Header 3\n\tPeople always make mistakes, frustrated, nerve-racking, but cannot remain stagnant.\n'; const list = parseData(plainData).filter((node) => 'node' === node.type); const defaultExpandedKeys = []; const dataSource = list.map((item, index) => { if (item.state === 'active') { defaultExpandedKeys.push(`panel_${index}`); } return { key: `panel_${index}`, title: item.value, content: item.children.map(({ type, value }) => (type === 'node' ? value : '')), disabled: item.state === 'disabled', }; }); export default [ { title: '折叠面板', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_dialog.png', schema: { componentName: 'Collapse', props: { accordion: false, plainData, dataSource, defaultExpandedKeys, }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/collapse/view.tsx ================================================ import * as React from 'react'; import { Collapse } from '@alifd/next'; import { DynamicPropWrapper } from 'lowcode/utils/component-wrapper'; export default DynamicPropWrapper('expandedKeys', Collapse, 'Collapse'); ================================================ FILE: packages/fusion-lowcode-materials/lowcode/collapse-panel/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Collapse.Panel', title: '折叠面板Panel', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Collapse', main: '', destructuring: true, subName: 'Panel', }, props: [ { name: 'children', propType: 'any', }, { name: 'style', propType: 'object', description: '子组件接受行内样式', }, { name: 'disabled', propType: 'bool', description: '是否禁止用户操作', }, { name: 'title', propType: { type: 'instanceOf', value: 'node', }, description: '标题', }, ], configure: { component: { nestingRule: { parentWhitelist: ['Collapse'], }, }, advanced: { callbacks: { onHoverHook: () => false, onMouseDownHook: () => false, onClickHook: () => false, onMove: () => false, }, }, }, icon: '', category: '信息输入', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/date-picker/meta.design.ts ================================================ import snippets from './snippets'; export default { group: '原子组件', componentName: 'DatePicker', title: '日期选择框', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'DatePicker', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'rtl', propType: 'bool', defaultValue: false, }, { name: 'name', title: { label: '名称', tip: 'name|表单相关', }, propType: 'string', description: 'name|表单相关', }, { name: 'label', title: { label: '标签', tip: 'label|输入框内置标签', }, propType: 'string', description: 'label|输入框内置标签', }, { name: 'state', title: { label: '状态', tip: 'state|输入框状态', }, propType: { type: 'oneOf', value: ['success', 'loading', 'error'], }, description: 'state|输入框状态', }, { name: 'placeholder', title: { label: '占位提示', tip: 'placeholder|输入提示', }, propType: 'string', description: '输入提示', }, { name: 'value', title: { label: 'value', tip: 'value|日期值(受控)', }, propType: { type: 'instanceOf', value: 'custom', }, description: '日期值(受控)moment 对象', }, { name: 'defaultValue', title: { label: '默认值', tip: 'defaultValue|初始日期值,moment 对象', }, propType: 'date', description: 'defaultValue|初始日期值,moment 对象', }, { name: 'format', title: { label: '格式', tip: 'format|日期值的格式(用于限定用户输入和展示)', }, propType: 'string', description: 'format|日期值的格式(用于限定用户输入和展示)', defaultValue: 'YYYY-MM-DD', }, { name: 'onChange', propType: 'func', description: '日期值改变时的回调\n@param {MomentObject|String} value 日期值', }, { name: 'onOk', propType: 'func', description: '点击确认按钮时的回调\n@return {MomentObject|String} 日期值', }, { name: 'size', title: { label: '尺寸', tip: 'size|输入框尺寸', }, propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: 'size|输入框尺寸', defaultValue: 'medium', }, { name: 'disabled', title: { label: '是否禁用', tip: 'disabled|是否禁用', }, propType: 'bool', description: '是否禁用', }, { name: 'hasClear', title: { label: '清除按钮', tip: 'hasClear|是否显示清空按钮', }, propType: 'bool', description: 'hasClear|是否显示清空按钮', defaultValue: true, }, { name: 'followTrigger', propType: 'bool', description: '跟随滚动', }, { name: 'defaultVisible', title: { label: '弹层显示', tip: 'defaultVisible|弹层默认是否显示', }, propType: 'bool', description: 'defaultVisible|弹层默认是否显示', defaultValue: false, }, { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, { name: 'form', propType: 'object', }, ], configure: { props: [ { name: 'showTime', title: '模式', setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '日期选择', value: false, }, { label: '时间选择', value: true, }, ], }, }, }, { name: 'visible', title: { label: '状态', tip: '属性: visible', }, defaultValue: false, setter: { componentName: 'RadioGroupSetter', props: { options: [ { value: false, label: '普通' }, { value: true, label: '展开' }, ], }, }, }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Button Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 按钮尺寸', en_US: 'prop: size | description: button size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '小', value: 'small', }, { label: '中', value: 'medium', }, { label: '大', value: 'large', }, ], }, }, defaultValue: 'medium', }, { name: 'style.width', title: '宽度', setter: 'NumberSetter', }, { name: 'label', title: { label: '内联文案', tip: 'label|输入框内置标签', }, setter: { componentName: 'StringSetter', props: { placeholder: '请输入', }, }, }, { name: 'placeholder', title: { label: '占位提示', tip: 'placeholder|输入提示', }, setter: { componentName: 'StringSetter', props: { placeholder: '请输入', }, }, }, { name: 'disabled', title: { label: '是否禁用', tip: 'disabled|是否禁用', }, setter: 'BoolSetter', defaultValue: false, }, ], }, icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/date-picker/meta.ts ================================================ import snippets from './snippets'; export default { group: '原子组件', componentName: 'DatePicker', title: '日期选择框', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'DatePicker', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'rtl', propType: 'bool', defaultValue: false, }, { name: 'name', title: { label: '名称', tip: 'name|表单相关', }, propType: 'string', description: 'name|表单相关', }, { name: 'label', title: { label: '标签', tip: 'label|输入框内置标签', }, propType: 'string', description: 'label|输入框内置标签', }, { name: 'state', title: { label: '状态', tip: 'state|输入框状态', }, propType: { type: 'oneOf', value: ['success', 'loading', 'error'], }, description: 'state|输入框状态', }, { name: 'placeholder', title: { label: '占位提示', tip: 'placeholder|输入提示', }, propType: 'string', description: '输入提示', }, { name: 'value', title: { label: 'value', tip: 'value|日期值(受控)', }, propType: { type: 'instanceOf', value: 'custom', }, description: '日期值(受控)moment 对象', }, { name: 'defaultValue', title: { label: '默认值', tip: 'defaultValue|初始日期值,moment 对象', }, propType: 'date', description: 'defaultValue|初始日期值,moment 对象', }, { name: 'format', title: { label: '格式', tip: 'format|日期值的格式(用于限定用户输入和展示)', }, propType: 'string', description: 'format|日期值的格式(用于限定用户输入和展示)', defaultValue: 'YYYY-MM-DD', }, { name: 'onChange', propType: 'func', description: '日期值改变时的回调\n@param {MomentObject|String} value 日期值', }, { name: 'onOk', propType: 'func', description: '点击确认按钮时的回调\n@return {MomentObject|String} 日期值', }, { name: 'size', title: { label: '尺寸', tip: 'size|输入框尺寸', }, propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: 'size|输入框尺寸', defaultValue: 'medium', }, { name: 'disabled', title: { label: '是否禁用', tip: 'disabled|是否禁用', }, propType: 'bool', description: '是否禁用', }, { name: 'hasClear', title: { label: '清除按钮', tip: 'hasClear|是否显示清空按钮', }, propType: 'bool', description: 'hasClear|是否显示清空按钮', defaultValue: true, }, { name: 'followTrigger', propType: 'bool', description: '跟随滚动', }, { name: 'defaultVisible', title: { label: '弹层显示', tip: 'defaultVisible|弹层默认是否显示', }, propType: 'bool', description: 'defaultVisible|弹层默认是否显示', defaultValue: false, }, { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, { name: 'form', propType: 'object', }, ], configure: { props: { isExtends: true, override: [ { name: 'prefix', condition: () => false, }, { name: 'rtl', condition: () => false, }, { name: 'value', condition: () => false, }, { name: 'name', condition: () => false, }, { name: 'defaultValue', title: { label: '默认值', tip: 'defaultValue|初始日期值,moment 对象', }, setter: 'DateSetter', supportVariable: true, }, { name: 'form', type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', supportVariable: true, }, ], }, ], }, }, icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/date-picker/snippets.ts ================================================ export default [ { title: '日期选择框', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_date-picker.png', schema: { componentName: 'DatePicker', props: { prefix: 'next-', format: 'YYYY-MM-DD', size: 'medium', hasClear: false, popupTriggerType: 'click', popupAlign: 'tl tl', followTrigger: true, }, }, }, { title: '日期区间', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_date-picker.png', schema: { componentName: 'RangePicker', props: { prefix: 'next-', format: 'YYYY-MM-DD', size: 'medium', type: 'date', hasClear: false, popupTriggerType: 'click', popupAlign: 'tl tl', followTrigger: true, }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/dialog/meta.design.ts ================================================ import snippets from './snippets.design'; export default { group: '原子组件', componentName: 'Dialog', title: '对话框', docUrl: '', screenshot: '', keywords: ['弹窗', '模态'], npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Dialog', main: '', destructuring: true, subName: '', }, props: [ { name: 'id', propType: 'string', }, { name: 'visible', propType: { type: 'oneOfType', value: ['JSExpression', 'bool'], }, description: '是否显示', defaultValue: false, }, { name: 'title', propType: { type: 'oneOfType', value: ['string', 'node'], }, description: '标题', }, { name: 'children', propType: { type: 'oneOfType', value: [ 'bool', { type: 'instanceOf', value: 'node', }, ], }, description: '内容', }, { name: 'footer', propType: { type: 'oneOfType', value: ['bool'], }, description: '底部按钮', }, { name: 'footerAlign', propType: { type: 'oneOf', value: ['left', 'center', 'right'], }, description: '操作对齐方式', defaultValue: 'right', }, { name: 'closeable', propType: { type: 'oneOf', value: ['close', 'mask', 'esc,close', 'close,esc,mask', 'esc'], }, description: '关闭方式', defaultValue: 'esc,close', }, { name: 'onClose', propType: 'func', description: '对话框关闭时触发的回调函数\n@param {String} trigger 关闭触发行为的描述字符串\n@param {Object} event 关闭时事件对象', }, { name: 'hasMask', propType: 'bool', description: '是否显示遮罩', defaultValue: true, }, { name: 'animation', propType: { type: 'oneOfType', value: ['object', 'bool'], }, description: '显示隐藏时动画的播放方式\n@property {String} in 进场动画\n@property {String} out 出场动画', }, { name: 'autoFocus', propType: 'bool', description: '是否获得焦点', defaultValue: false, }, { name: 'isFullScreen', propType: 'bool', description: '是否全屏', defaultValue: false, }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: true, isModal: true, rootSelector: 'div.next-dialog', nestingRule: { parentWhitelist: ['Page'], }, }, props: [ { name: 'title', title: '标题', setter: 'StringSetter', initialValue: '标题', }, { name: 'visible', title: '是否显示', setter: 'BoolSetter', initialValue: false, }, { name: 'hasMask', title: '显示遮罩', setter: 'BoolSetter', initialValue: true, }, { name: 'closeMode', title: '关闭方式', setter: { componentName: 'SelectSetter', mutiple: true, props: { options: [ { title: '关闭按钮', value: 'close', }, { title: '遮罩', value: 'mask', }, { title: 'ESC', value: 'esc', }, ], }, }, initialValue: ['esc', 'close'], }, { name: 'autoFocus', title: '自动聚焦', setter: 'BoolSetter', initialValue: false, }, { name: 'buttons', title: '底部按钮配置', type: 'group', extraProps: { display: 'block', }, items: [ { name: 'footer', title: '是否显示', setter: 'BoolSetter', initialValue: true, }, { name: 'footerAlign', title: '对齐方式', initialValue: 'right', condition: (target) => { return target.getProps().getPropValue('footer'); }, setter: { componentName: 'RadioGroupSetter', initialValue: 'right', props: { options: [ { title: '左', value: 'left', }, { title: '中', value: 'center', }, { title: '右', value: 'right', }, ], }, }, }, { name: 'footerActions', title: '排列方式', initialValue: ['ok', 'cancel'], condition: (target) => { return target.getProps().getPropValue('footer'); }, setter: { componentName: 'SelectSetter', initialValue: ['ok', 'cancel'], props: { options: [ { title: 'ok, cancel', value: ['ok', 'cancel'], }, { title: 'cancel, ok', value: ['cancel', 'ok'], }, { title: 'cancel', value: ['cancel'], }, { title: 'ok', value: ['ok'], }, ], }, }, }, ], }, ], supports: { events: ['onOk', 'onCancel', 'onClose'], style: true, }, advanced: { callbacks: { // 与 next-page 的 onNodeAdd 一模一样 onNodeAdd: (dragment, currentNode) => { // 拖入的组件为 P、Block、Slot(把NextPage拖入到面板里时,NextPage的Slot也会触发onNodeAdd事件) 时,不进行包裹 // 拖入的组件 isModal为true时(例如drawer dialog 这类有单独组件树结构的),不进行包裹 if ( !dragment || ['NextP', 'NextBlock', 'Slot'].includes(dragment.componentName) || (dragment.isModal && dragment.isModal()) ) { console.log( `[${dragment.componentName}] doesn\'n need to wrap with NextBlock > NextBlockCell`, ); return; } const NextPProps = { wrap: false, type: 'body2', verAlign: 'middle', textSpacing: true, align: 'left', }; if ( [ 'Form', 'ResponsiveGrid', 'Box', 'Card', 'List', 'Message', 'Slider', 'NextTable', ].includes(dragment.componentName) || dragment.getPropValue('isFillContainer') ) { NextPProps.full = true; } const layoutPSchema = { componentName: 'NextP', title: '段落', props: NextPProps, children: [dragment.exportSchema()], }; // 为目标元素包裹一层 Block const layoutBlockNode = (len) => currentNode.document.createNode({ componentName: 'NextBlock', title: '区块', props: { childTotalColumns: len || 12, }, children: [ { componentName: 'NextBlockCell', title: '子区块', props: { isAutoContainer: true, colSpan: 12, rowSpan: 1, }, children: [layoutPSchema], }, ], }); const { dropLocation } = dragment.document.designer; if (!dropLocation) { // 没有 dropLocation 一般是 slot, slot 元素不用特殊处理 不做任何包裹 return; } const dropTarget = dropLocation.target; const dropTargetName = dropLocation.target.componentName || ''; // 找到要拖入进去的节点 ID const targetId = (dropLocation && dropLocation.target.id) || ''; // 找到要拖入进去的节点 const slotTarget = currentNode.slots.length > 0 && currentNode.slots.find((item) => item.id === targetId); const layoutPNode = currentNode.document.createNode(layoutPSchema); // 是否为 aside slot const isAsideSlot = slotTarget && ['aside'].indexOf(slotTarget._slotFor.key) > -1; // 是否为需要被 P 包裹的 Slot const isNeedPSlot = slotTarget && ['header', 'footer', 'nav'].indexOf(slotTarget._slotFor.key) > -1; const wrapWithBlock = (dragment, node, dropTargetName, blockLen) => { setTimeout(() => { console.log( `[${dragment.componentName}] to [${dropTargetName}] need to wrap with NextBlock > NextBlockCell > NextP [from NextPage2]`, ); const newNode = node.document.createNode(layoutBlockNode(blockLen).exportSchema()); node.insertBefore(newNode, dragment, false); dragment.remove(false); newNode .getChildren() .get(0) .getChildren() .get(0) .getChildren() .get(0) .select(); }, 1); }; const wrapWithP = (dragment, node, dropTargetName) => { setTimeout(() => { // const dragmentTarget = dropTarget; // 要拖入的地方如果是 NextP 那就 不再自动包裹 P了 if (dropTargetName === 'NextP') { console.log( `[${dragment.componentName}] to [${dropTargetName}] does't need to wrap with NextP. [from NextPage3]`, ); return; } console.log( `[${dragment.componentName}] to [${dropTargetName}] need to wrap with NextP [from NextPage3]`, ); const newNode = node.document.createNode(Object.assign(layoutPNode.exportSchema())); node.insertBefore(newNode, dragment, false); dragment.remove(false); newNode .getChildren() .get(0) .select(); }, 1); }; // 需要包裹 Block BlockCell P 的情况: // 1. 组件拖入到 NextPage,的直接子元素下(不包括slot), 此时Block宽度为12 if (['NextPage'].includes(dropTargetName) && currentNode.getChildren().has(dragment)) { wrapWithBlock(dragment, currentNode, dropTargetName, 12); // 需要包裹 Block BlockCell P 的情况: // 2. 组件拖入到 NextPage 的 aside slot, 的直接子元素下 (不包括slot下的进一步内容),此时Block宽度为1 } else if (isAsideSlot && slotTarget && slotTarget.getChildren().has(dragment)) { wrapWithBlock(dragment, slotTarget, dropTargetName, 1); // 需要包裹 P 的情况: // 1. 如果是处于,开启了自然布局模式的容器组件中 (或者Tab里) // 这里的Tab主要是给纪元epoch使用的,因为他们用到了 @ali/vc-deep 的TabLayout组件,没办法在这个组件上再增加属性 isAutoContainer } else if (dropTarget.getPropValue('isAutoContainer') || dropTargetName === 'Tab.Item') { wrapWithP(dragment, dropTarget, dropTargetName); // 需要包裹 P 的情况: // 2. 如果是处于,Page 的 nav header footer 中 } else if (isNeedPSlot && slotTarget) { wrapWithP(dragment, slotTarget, dropTargetName); } // 其他维持原状,不进行其他设置 }, }, }, }, icon: '', category: '信息反馈', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/dialog/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Dialog', title: '对话框', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Dialog', main: '', destructuring: true, subName: '', }, props: [ { name: 'id', propType: 'string', }, { name: 'visible', propType: { type: 'oneOfType', value: ['JSExpression', 'bool'], }, description: '是否显示', defaultValue: false, }, { name: 'title', propType: { type: 'oneOfType', value: ['string', 'node'], }, description: '标题', }, { name: 'children', propType: { type: 'oneOfType', value: [ 'bool', { type: 'instanceOf', value: 'node', }, ], }, description: '内容', }, { name: 'footer', propType: { type: 'oneOfType', value: ['bool'], }, description: '底部按钮', }, { name: 'footerAlign', propType: { type: 'oneOf', value: ['left', 'center', 'right'], }, description: '操作对齐方式', defaultValue: 'right', }, { name: 'closeable', propType: { type: 'oneOf', value: ['close', 'mask', 'esc,close', 'close,esc,mask', 'esc'], }, description: '关闭方式', defaultValue: 'esc,close', }, { name: 'onClose', propType: 'func', description: '对话框关闭时触发的回调函数\n@param {String} trigger 关闭触发行为的描述字符串\n@param {Object} event 关闭时事件对象', }, { name: 'hasMask', propType: 'bool', description: '是否显示遮罩', defaultValue: true, }, { name: 'animation', propType: { type: 'oneOfType', value: ['object', 'bool'], }, description: '显示隐藏时动画的播放方式\n@property {String} in 进场动画\n@property {String} out 出场动画', }, { name: 'autoFocus', propType: 'bool', description: '是否获得焦点', defaultValue: false, }, { name: 'isFullScreen', propType: 'bool', description: '是否全屏', defaultValue: false, }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: true, isModal: true, rootSelector: 'div.next-dialog', nestingRule: { parentWhitelist: ['Page'], }, }, props: [ { name: 'title', title: '标题', setter: 'StringSetter', supportVariable: true, initialValue: '标题', }, { name: 'visible', title: '是否显示', setter: 'BoolSetter', supportVariable: true, initialValue: false, }, { name: 'hasMask', title: '显示遮罩', setter: 'BoolSetter', supportVariable: true, initialValue: true, }, { name: 'closeMode', title: '关闭方式', setter: { componentName: 'SelectSetter', mutiple: true, props: { options: [ { title: 'close', value: 'close', }, { title: 'mask', value: 'mask', }, { title: 'esc', value: 'esc', }, ], }, }, initialValue: ['esc', 'close'], }, { name: 'autoFocus', title: '自动聚焦', setter: 'BoolSetter', supportVariable: true, initialValue: false, }, { name: 'buttons', title: '底部按钮配置', type: 'group', extraProps: { display: 'block', }, items: [ { name: 'footer', title: '是否显示', setter: 'BoolSetter', supportVariable: true, initialValue: true, }, { name: 'footerAlign', title: '对齐方式', initialValue: 'right', condition: (target) => { return target.parent.getPropValue('footer'); }, setter: { componentName: 'RadioGroupSetter', initialValue: 'right', props: { options: [ { title: 'left', value: 'left', }, { title: 'center', value: 'center', }, { title: 'right', value: 'right', }, ], }, }, }, { name: 'footerActions', title: '排列方式', initialValue: ['ok', 'cancel'], condition: (target) => { return target.parent.getPropValue('footer'); }, setter: { componentName: 'SelectSetter', initialValue: ['ok', 'cancel'], props: { options: [ { title: 'ok, cancel', value: ['ok', 'cancel'], }, { title: 'cancel, ok', value: ['cancel', 'ok'], }, { title: 'cancel', value: ['cancel'], }, { title: 'ok', value: ['ok'], }, ], }, }, }, ], }, ], supports: { events: ['onOk', 'onCancel', 'onClose'], style: true, }, advanced: { callbacks: { // 与 next-page 的 onNodeAdd 一模一样 onNodeAdd: (dragment, currentNode) => { // 拖入的组件为 P、Block、Slot(把NextPage拖入到面板里时,NextPage的Slot也会触发onNodeAdd事件) 时,不进行包裹 // 拖入的组件 isModal为true时(例如drawer dialog 这类有单独组件树结构的),不进行包裹 if ( !dragment || ['NextP', 'NextBlock', 'Slot'].includes(dragment.componentName) || (dragment.componentMeta.isModal && dragment.componentMeta.isModal()) ) { console.log( `[${dragment.componentName}] doesn\'n need to wrap with NextBlock > NextBlockCell`, ); return; } const NextPProps = { wrap: false, type: 'body2', verAlign: 'middle', textSpacing: true, align: 'left', }; if ( [ 'Form', 'ResponsiveGrid', 'Box', 'Card', 'List', 'Message', 'Slider', 'NextTable', ].includes(dragment.componentName) || dragment.getPropValue('isFillContainer') ) { NextPProps.full = true; } const layoutPSchema = { componentName: 'NextP', title: '段落', props: NextPProps, children: [dragment.exportSchema()], }; // 为目标元素包裹一层 Block const layoutBlockNode = (len) => currentNode.document.createNode({ componentName: 'NextBlock', title: '区块', props: { childTotalColumns: len || 12, }, children: [ { componentName: 'NextBlockCell', title: '子区块', props: { isAutoContainer: true, colSpan: 12, rowSpan: 1, }, children: [layoutPSchema], }, ], }); const dropLocation = dragment.document.canvas.dropLocation; if (!dropLocation) { // 没有 dropLocation 一般是 slot, slot 元素不用特殊处理 不做任何包裹 return; } const dropTarget = dropLocation.target; const dropTargetName = dropLocation.target.componentName || ''; // 找到要拖入进去的节点 ID const targetId = (dropLocation && dropLocation.target.id) || ''; // 找到要拖入进去的节点 let slotTarget = currentNode.slots.length > 0 && currentNode.slots.find((item) => item.id === targetId); const layoutPNode = currentNode.document.createNode(layoutPSchema); // 是否为 aside slot const isAsideSlot = slotTarget && ['aside'].indexOf(slotTarget._slotFor.key) > -1; // 是否为需要被 P 包裹的 Slot const isNeedPSlot = slotTarget && ['header', 'footer', 'nav'].indexOf(slotTarget._slotFor.key) > -1; const wrapWithBlock = (dragment, node, dropTargetName, blockLen) => { setTimeout(() => { console.log( `[${dragment.componentName}] to [${dropTargetName}] need to wrap with NextBlock > NextBlockCell > NextP [from NextPage2]`, ); const newNode = node.document.createNode(layoutBlockNode(blockLen).exportSchema()); node.insertBefore(newNode, dragment, false); dragment.remove(false); newNode.children.get(0).children.get(0).children.get(0).select(); }, 1); }; const wrapWithP = (dragment, node, dropTargetName) => { setTimeout(() => { // const dragmentTarget = dropTarget; // 要拖入的地方如果是 NextP 那就 不再自动包裹 P了 if (dropTargetName === 'NextP') { console.log( `[${dragment.componentName}] to [${dropTargetName}] does't need to wrap with NextP. [from NextPage3]`, ); return; } console.log( `[${dragment.componentName}] to [${dropTargetName}] need to wrap with NextP [from NextPage3]`, ); const newNode = node.document.createNode(Object.assign(layoutPNode.exportSchema())); node.insertBefore(newNode, dragment, false); dragment.remove(false); newNode.children.get(0).select(); }, 1); }; // 需要包裹 Block BlockCell P 的情况: // 1. 组件拖入到 NextPage,的直接子元素下(不包括slot), 此时Block宽度为12 if (['NextPage'].includes(dropTargetName) && currentNode.children.has(dragment)) { wrapWithBlock(dragment, currentNode, dropTargetName, 12); // 需要包裹 Block BlockCell P 的情况: // 2. 组件拖入到 NextPage 的 aside slot, 的直接子元素下 (不包括slot下的进一步内容),此时Block宽度为1 } else if (isAsideSlot && slotTarget && slotTarget.children.has(dragment)) { wrapWithBlock(dragment, slotTarget, dropTargetName, 1); // 需要包裹 P 的情况: // 1. 如果是处于,开启了自然布局模式的容器组件中 (或者Tab里) // 这里的Tab主要是给纪元epoch使用的,因为他们用到了 @ali/vc-deep 的TabLayout组件,没办法在这个组件上再增加属性 isAutoContainer } else if (dropTarget.getPropValue('isAutoContainer') || dropTargetName === 'Tab.Item') { wrapWithP(dragment, dropTarget, dropTargetName); // 需要包裹 P 的情况: // 2. 如果是处于,Page 的 nav header footer 中 } else if (isNeedPSlot && slotTarget) { wrapWithP(dragment, slotTarget, dropTargetName); } // 其他维持原状,不进行其他设置 }, }, }, }, icon: '', category: '布局容器类', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/dialog/snippets.design.ts ================================================ export default [ { title: '对话框', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_dialog.png', schema: { componentName: 'Dialog', props: { prefix: 'next-', footerAlign: 'right', title: 'Title', footer: true, footerActions: ['ok', 'cancel'], closeable: 'esc,close', hasMask: true, align: 'cc cc', minMargin: 40, isAutoContainer: true, visible: true, }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/dialog/snippets.ts ================================================ module.exports = [ { title: '对话框', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_dialog.png', schema: { componentName: 'Dialog', props: { prefix: 'next-', footerAlign: 'right', title: 'Title', footer: true, footerActions: ['ok', 'cancel'], closeable: 'esc,close', hasMask: true, align: 'cc cc', minMargin: 40, isAutoContainer: true, visible: true, }, }, }, { title: '隐藏底部', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_dialog.png', schema: { componentName: 'Dialog', props: { prefix: 'next-', footerAlign: 'right', title: 'Title', footer: false, closeable: 'esc,close', hasMask: true, align: 'cc cc', minMargin: 40, isAutoContainer: true, visible: true, }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/div/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Div', title: 'Div', configure: { component: { isContainer: true, }, }, category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/divider/meta.design.ts ================================================ export default { group: '原子组件', componentName: 'Divider', title: '分隔符', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Divider', main: '', destructuring: true, subName: '', }, props: [ { name: 'style', propType: 'object', description: '自定义内敛样式', }, { name: 'children', propType: 'string', description: '文案', defaultValue: '分隔符', }, { name: 'dashed', title: { label: { type: 'i18n', zh_CN: '是否虚线', en_US: 'Dashed', }, }, propType: { type: 'bool', }, description: '是否为虚线', defaultValue: false, }, { name: 'direction', title: { label: { type: 'i18n', zh_CN: '朝向', en_US: 'Direction', }, }, propType: { type: 'oneOf', value: ['hoz', 'ver'], }, description: '线是水平还是垂直类型', defaultValue: 'hoz', }, { name: 'orientation', title: { label: { type: 'i18n', zh_CN: '标题位置', en_US: 'Orientation', }, }, propType: { type: 'oneOf', value: ['left', 'right', 'center'], }, description: '分割线标题的位置', defaultValue: 'center', }, ], configure: { props: [ { name: 'direction', title: { label: { type: 'i18n', zh_CN: '方向', en_US: 'Direction', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '水平', value: 'hoz', }, { label: '垂直', value: 'ver', }, ], }, }, setValue: (target, value) => { if (value === 'ver') { target.parent.setPropValue('children', ''); } }, defaultValue: 'hoz', }, { name: 'children', setter: 'StringSetter', title: '文本内容', defaultValue: '分隔符', condition: (target) => target?.parent?.getPropValue?.('direction') !== 'ver', }, { name: 'orientation', title: { label: { type: 'i18n', zh_CN: '对齐方式', en_US: 'Orientation', }, }, condition: (target) => target?.parent?.getPropValue?.('direction') !== 'ver', setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '居中', value: 'center', }, { label: '居左', value: 'left', }, { label: '居右', value: 'right', }, ], }, }, defaultValue: 'center', }, { name: 'dashed', title: { label: { type: 'i18n', zh_CN: '样式', en_US: 'Dashed', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '实线', value: false, }, { label: '虚线', value: true, }, ], }, }, defaultValue: true, }, ], }, icon: '', category: '通用', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/divider/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Divider', title: '分隔符', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Divider', main: '', destructuring: true, subName: '', }, props: [ { name: 'style', propType: 'object', description: '自定义内敛样式', }, { name: 'children', propType: 'string', description: '文案', defaultValue: '分隔符', }, { name: 'dashed', title: { label: { type: 'i18n', zh_CN: '是否虚线', en_US: 'Dashed', }, }, propType: { type: 'bool', }, description: '是否为虚线', defaultValue: false, }, { name: 'direction', title: { label: { type: 'i18n', zh_CN: '朝向', en_US: 'Direction', }, }, propType: { type: 'oneOf', value: ['hoz', 'ver'], }, description: '线是水平还是垂直类型', defaultValue: 'hoz', }, { name: 'orientation', title: { label: { type: 'i18n', zh_CN: '标题位置', en_US: 'Orientation', }, }, propType: { type: 'oneOf', value: ['left', 'right', 'center'], }, description: '分割线标题的位置', defaultValue: 'center', }, ], icon: '', category: '通用', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/divider/snippets.ts ================================================ module.exports = [ { title: '分隔线', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_divider.png', schema: { componentName: 'Divider', props: { prefix: 'next-', direction: 'hoz', orientation: 'center', children: '分隔符', }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/drawer/meta.design.ts ================================================ module.exports = { group: '原子组件', componentName: 'Drawer', title: '抽屉', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Drawer', main: '', destructuring: true, subName: '', }, props: [ { name: 'id', propType: 'string', }, { name: 'prefix', title: { type: 'i18n', zh_CN: '前缀', en_US: 'prefix', }, propType: 'string', defaultValue: 'next-', }, { name: 'style', propType: 'object', }, { name: 'rtl', propType: 'bool', }, { name: 'width', title: { type: 'i18n', zh_CN: '宽度', en_US: 'width', tip: 'width|仅在 placement是 left right 的时候生效', }, propType: { type: 'oneOfType', value: ['number', 'string'], }, description: '宽度,仅在 placement是 left right 的时候生效', }, { name: 'height', title: { type: 'i18n', zh_CN: '高度', en_US: 'height', tip: 'height|仅在 placement是 top bottom 的时候生效', }, propType: { type: 'oneOfType', value: ['number', 'string'], }, description: '高度,仅在 placement是 top bottom 的时候生效', }, { name: 'placement', propType: { type: 'oneOf', value: ['top', 'right', 'bottom', 'left'], }, description: '位于页面的位置', defaultValue: 'right', }, { name: 'title', propType: { type: 'oneOfType', value: ['string', 'node'], }, description: '标题', }, { name: 'headerStyle', propType: 'object', description: 'header上的样式', }, { name: 'bodyStyle', propType: 'object', description: 'body上的样式', }, { name: 'visible', propType: 'bool', description: '是否显示', }, { name: 'hasMask', propType: 'bool', description: '是否显示遮罩', defaultValue: true, }, { name: 'onVisibleChange', propType: 'func', }, { name: 'animation', title: { label: '动画', tip: 'animation', }, propType: 'bool', description: '显示隐藏时动画的播放方式\n@property {String} in 进场动画\n@property {String} out 出场动画', }, { name: 'closeable', propType: { type: 'oneOfType', value: ['string', 'bool'], }, description: "控制对话框关闭的方式,值可以为字符串或者布尔值,其中字符串是由以下值组成:\n**close** 表示点击关闭按钮可以关闭对话框\n**mask** 表示点击遮罩区域可以关闭对话框\n**esc** 表示按下 esc 键可以关闭对话框\n如 'close' 或 'close,esc,mask'\n如果设置为 true,则以上关闭方式全部生效\n如果设置为 false,则以上关闭方式全部失效", defaultValue: true, }, { name: 'onClose', propType: 'func', description: '对话框关闭时触发的回调函数\n@param {String} trigger 关闭触发行为的描述字符串\n@param {Object} event 关闭时事件对象', }, { name: 'popupContainer', propType: 'any', description: '弹层容器\n@param {Element} target 目标元素\n@return {Element} 弹层的容器元素', }, ], configure: { component: { isContainer: true, isModal: true, rootSelector: '.next-drawer', nestingRule: { parentWhitelist: (testNode, currentNode) => { return testNode.componentName === 'Page'; }, }, }, props: [ { name: 'title', title: { label: { type: 'i18n', zh_CN: '标题', en_US: 'Title', }, tip: { type: 'i18n', zh_CN: '属性: title | 说明: 标题', en_US: 'prop: title | description: title', }, }, setter: { componentName: 'StringSetter', }, description: '标题', }, { name: 'width', title: { label: { type: 'i18n', zh_CN: '宽度', en_US: 'width', }, tip: { type: 'i18n', zh_CN: '属性: width | 说明: 宽度', en_US: 'prop: width | description: 仅在 placement是 left right 的时候生效', }, }, setter: { componentName: 'NumberSetter', }, description: '宽度,仅在 placement是 left right 的时候生效', }, { name: 'height', title: { label: { type: 'i18n', zh_CN: '高度', en_US: 'height', }, tip: { type: 'i18n', zh_CN: '属性: height | 说明: 高度', en_US: 'prop: height | description: 仅在 placement是 top bottom 的时候生效', }, }, setter: { componentName: 'NumberSetter', }, description: '高度,仅在 placement是 top bottom 的时候生效', }, { name: 'placement', title: { label: { type: 'i18n', zh_CN: '弹出位置', en_US: 'height', }, tip: { type: 'i18n', zh_CN: '属性: placement | 说明: 位于页面的位置', en_US: 'prop: placement | description: drawer placement', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['top', 'right', 'bottom', 'left'], }, }, description: '位于页面的位置', defaultValue: 'right', }, { name: 'visible', title: { label: { type: 'i18n', zh_CN: '是否显示', en_US: 'visible', }, tip: { type: 'i18n', zh_CN: '属性: visible | 说明: 是否显示', en_US: 'prop: visible | description: drawer visible', }, }, setter: 'BoolSetter', supportVariable: true, description: '是否显示', }, { name: 'hasMask', title: { label: { type: 'i18n', zh_CN: '显示遮罩', en_US: 'hasMask', }, tip: { type: 'i18n', zh_CN: '属性: hasMask | 说明: 是否显示遮罩', en_US: 'prop: hasMask | description: drawer hasMask', }, }, setter: { componentName: 'BoolSetter', }, description: '是否显示遮罩', defaultValue: true, }, { name: 'closeable', title: { label: { type: 'i18n', zh_CN: '显示遮罩', en_US: 'closeable', }, tip: { type: 'i18n', zh_CN: "属性: closeable | 说明: 控制对话框关闭的方式,值可以为字符串或者布尔值,其中字符串是由以下值组成:\n**close** 表示点击关闭按钮可以关闭对话框\n**mask** 表示点击遮罩区域可以关闭对话框\n**esc** 表示按下 esc 键可以关闭对话框\n如 'close' 或 'close,esc,mask'\n如果设置为 true,则以上关闭方式全部生效\n如果设置为 false,则以上关闭方式全部失效", en_US: 'prop: closeable | description: drawer closeable', }, }, setter: { componentName: 'BoolSetter', }, description: "控制对话框关闭的方式,值可以为字符串或者布尔值,其中字符串是由以下值组成:\n**close** 表示点击关闭按钮可以关闭对话框\n**mask** 表示点击遮罩区域可以关闭对话框\n**esc** 表示按下 esc 键可以关闭对话框\n如 'close' 或 'close,esc,mask'\n如果设置为 true,则以上关闭方式全部生效\n如果设置为 false,则以上关闭方式全部失效", defaultValue: true, }, ], advanced: { callbacks: { // 与 next-page 的 onNodeAdd 一模一样 onNodeAdd: (dragment, currentNode) => { // 拖入的组件为 P、Block、Slot(把NextPage拖入到面板里时,NextPage的Slot也会触发onNodeAdd事件) 时,不进行包裹 // 拖入的组件 isModal为true时(例如drawer dialog 这类有单独组件树结构的),不进行包裹 if ( !dragment || ['NextP', 'NextBlock', 'Slot'].includes(dragment.componentName) || (dragment.isModal && dragment.isModal()) ) { console.log( `[${dragment.componentName}] doesn\'n need to wrap with NextBlock > NextBlockCell`, ); return; } const NextPProps = { wrap: false, type: 'body2', verAlign: 'middle', textSpacing: true, align: 'left', }; if ( [ 'Form', 'ResponsiveGrid', 'Box', 'Card', 'List', 'Message', 'Slider', 'NextTable', ].includes(dragment.componentName) || dragment.getPropValue('isFillContainer') ) { NextPProps.full = true; } const layoutPSchema = { componentName: 'NextP', title: '段落', props: NextPProps, children: [dragment.exportSchema()], }; // 为目标元素包裹一层 Block const layoutBlockNode = (len) => currentNode.document.createNode({ componentName: 'NextBlock', title: '区块', props: { childTotalColumns: len || 12, }, children: [ { componentName: 'NextBlockCell', title: '子区块', props: { isAutoContainer: true, colSpan: 12, rowSpan: 1, }, children: [layoutPSchema], }, ], }); const { dropLocation } = dragment.document.designer; if (!dropLocation) { // 没有 dropLocation 一般是 slot, slot 元素不用特殊处理 不做任何包裹 return; } const dropTarget = dropLocation.target; const dropTargetName = dropLocation.target.componentName || ''; // 找到要拖入进去的节点 ID const targetId = (dropLocation && dropLocation.target.id) || ''; // 找到要拖入进去的节点 const slotTarget = currentNode.slots.length > 0 && currentNode.slots.find((item) => item.id === targetId); const layoutPNode = currentNode.document.createNode(layoutPSchema); // 是否为 aside slot const isAsideSlot = slotTarget && ['aside'].indexOf(slotTarget._slotFor.key) > -1; // 是否为需要被 P 包裹的 Slot const isNeedPSlot = slotTarget && ['header', 'footer', 'nav'].indexOf(slotTarget._slotFor.key) > -1; const wrapWithBlock = (dragment, node, dropTargetName, blockLen) => { setTimeout(() => { console.log( `[${dragment.componentName}] to [${dropTargetName}] need to wrap with NextBlock > NextBlockCell > NextP [from NextPage2]`, ); const newNode = node.document.createNode(layoutBlockNode(blockLen).exportSchema()); node.insertBefore(newNode, dragment, false); dragment.remove(false); newNode .getChildren() .get(0) .getChildren() .get(0) .getChildren() .get(0) .select(); }, 1); }; const wrapWithP = (dragment, node, dropTargetName) => { setTimeout(() => { // const dragmentTarget = dropTarget; // 要拖入的地方如果是 NextP 那就 不再自动包裹 P了 if (dropTargetName === 'NextP') { console.log( `[${dragment.componentName}] to [${dropTargetName}] does't need to wrap with NextP. [from NextPage3]`, ); return; } console.log( `[${dragment.componentName}] to [${dropTargetName}] need to wrap with NextP [from NextPage3]`, ); const newNode = node.document.createNode(Object.assign(layoutPNode.exportSchema())); node.insertBefore(newNode, dragment, false); dragment.remove(false); newNode .getChildren() .get(0) .select(); }, 1); }; // 需要包裹 Block BlockCell P 的情况: // 1. 组件拖入到 NextPage,的直接子元素下(不包括slot), 此时Block宽度为12 if (['NextPage'].includes(dropTargetName) && currentNode.getChildren().has(dragment)) { wrapWithBlock(dragment, currentNode, dropTargetName, 12); // 需要包裹 Block BlockCell P 的情况: // 2. 组件拖入到 NextPage 的 aside slot, 的直接子元素下 (不包括slot下的进一步内容),此时Block宽度为1 } else if (isAsideSlot && slotTarget && slotTarget.getChildren().has(dragment)) { wrapWithBlock(dragment, slotTarget, dropTargetName, 1); // 需要包裹 P 的情况: // 1. 如果是处于,开启了自然布局模式的容器组件中 (或者Tab里) // 这里的Tab主要是给纪元epoch使用的,因为他们用到了 @ali/vc-deep 的TabLayout组件,没办法在这个组件上再增加属性 isAutoContainer } else if (dropTarget.getPropValue('isAutoContainer') || dropTargetName === 'Tab.Item') { wrapWithP(dragment, dropTarget, dropTargetName); // 需要包裹 P 的情况: // 2. 如果是处于,Page 的 nav header footer 中 } else if (isNeedPSlot && slotTarget) { wrapWithP(dragment, slotTarget, dropTargetName); } // 其他维持原状,不进行其他设置 }, }, }, }, icon: '', category: '信息反馈', snippets: require('./snippets.design'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/drawer/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Drawer', title: '抽屉', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Drawer', main: '', destructuring: true, subName: '', }, props: [ { name: 'id', propType: 'string', }, { name: 'prefix', title: { type: 'i18n', zh_CN: '前缀', en_US: 'prefix', }, propType: 'string', defaultValue: 'next-', }, { name: 'style', propType: 'object', }, { name: 'rtl', propType: 'bool', }, { name: 'width', title: { type: 'i18n', zh_CN: '宽度', en_US: 'width', tip: 'width|仅在 placement是 left right 的时候生效', }, propType: { type: 'oneOfType', value: ['number', 'string'], }, description: '宽度,仅在 placement是 left right 的时候生效', }, { name: 'height', title: { type: 'i18n', zh_CN: '高度', en_US: 'height', tip: 'height|仅在 placement是 top bottom 的时候生效', }, propType: { type: 'oneOfType', value: ['number', 'string'], }, description: '高度,仅在 placement是 top bottom 的时候生效', }, { name: 'placement', propType: { type: 'oneOf', value: ['top', 'right', 'bottom', 'left'], }, description: '位于页面的位置', defaultValue: 'right', }, { name: 'title', propType: { type: 'oneOfType', value: ['string', 'node'], }, description: '标题', }, { name: 'headerStyle', propType: 'object', description: 'header上的样式', }, { name: 'bodyStyle', propType: 'object', description: 'body上的样式', }, { name: 'visible', propType: 'bool', description: '是否显示', }, { name: 'hasMask', propType: 'bool', description: '是否显示遮罩', defaultValue: true, }, { name: 'onVisibleChange', propType: 'func', }, { name: 'animation', title: { label: '动画', tip: 'animation', }, propType: 'bool', description: '显示隐藏时动画的播放方式\n@property {String} in 进场动画\n@property {String} out 出场动画', }, { name: 'closeable', propType: { type: 'oneOfType', value: ['string', 'bool'], }, description: "控制对话框关闭的方式,值可以为字符串或者布尔值,其中字符串是由以下值组成:\n**close** 表示点击关闭按钮可以关闭对话框\n**mask** 表示点击遮罩区域可以关闭对话框\n**esc** 表示按下 esc 键可以关闭对话框\n如 'close' 或 'close,esc,mask'\n如果设置为 true,则以上关闭方式全部生效\n如果设置为 false,则以上关闭方式全部失效", defaultValue: true, }, { name: 'onClose', propType: 'func', description: '对话框关闭时触发的回调函数\n@param {String} trigger 关闭触发行为的描述字符串\n@param {Object} event 关闭时事件对象', }, { name: 'popupContainer', propType: 'any', description: '弹层容器\n@param {Element} target 目标元素\n@return {Element} 弹层的容器元素', }, ], configure: { component: { isContainer: true, isModal: true, rootSelector: '.next-drawer', nestingRule: { parentWhitelist: (testNode, currentNode) => { return testNode.componentName === 'Page'; }, }, }, props: [ { name: 'title', title: { label: { type: 'i18n', zh_CN: '标题', en_US: 'Title', }, tip: { type: 'i18n', zh_CN: '属性: title | 说明: 标题', en_US: 'prop: title | description: title', }, }, setter: { componentName: 'StringSetter', }, description: '标题', }, { name: 'width', title: { label: { type: 'i18n', zh_CN: '宽度', en_US: 'width', }, tip: { type: 'i18n', zh_CN: '属性: width | 说明: 宽度', en_US: 'prop: width | description: 仅在 placement是 left right 的时候生效', }, }, setter: { componentName: 'NumberSetter', }, description: '宽度,仅在 placement是 left right 的时候生效', }, { name: 'height', title: { label: { type: 'i18n', zh_CN: '高度', en_US: 'height', }, tip: { type: 'i18n', zh_CN: '属性: height | 说明: 高度', en_US: 'prop: height | description: 仅在 placement是 top bottom 的时候生效', }, }, setter: { componentName: 'NumberSetter', }, description: '高度,仅在 placement是 top bottom 的时候生效', }, { name: 'placement', title: { label: { type: 'i18n', zh_CN: '弹出位置', en_US: 'height', }, tip: { type: 'i18n', zh_CN: '属性: placement | 说明: 位于页面的位置', en_US: 'prop: placement | description: drawer placement', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['top', 'right', 'bottom', 'left'], }, }, description: '位于页面的位置', defaultValue: 'right', }, { name: 'visible', title: { label: { type: 'i18n', zh_CN: '是否显示', en_US: 'visible', }, tip: { type: 'i18n', zh_CN: '属性: visible | 说明: 是否显示', en_US: 'prop: visible | description: drawer visible', }, }, setter: 'BoolSetter', supportVariable: true, description: '是否显示', }, { name: 'hasMask', title: { label: { type: 'i18n', zh_CN: '显示遮罩', en_US: 'hasMask', }, tip: { type: 'i18n', zh_CN: '属性: hasMask | 说明: 是否显示遮罩', en_US: 'prop: hasMask | description: drawer hasMask', }, }, setter: { componentName: 'BoolSetter', }, description: '是否显示遮罩', defaultValue: true, }, { name: 'closeable', title: { label: { type: 'i18n', zh_CN: '显示遮罩', en_US: 'closeable', }, tip: { type: 'i18n', zh_CN: "属性: closeable | 说明: 控制对话框关闭的方式,值可以为字符串或者布尔值,其中字符串是由以下值组成:\n**close** 表示点击关闭按钮可以关闭对话框\n**mask** 表示点击遮罩区域可以关闭对话框\n**esc** 表示按下 esc 键可以关闭对话框\n如 'close' 或 'close,esc,mask'\n如果设置为 true,则以上关闭方式全部生效\n如果设置为 false,则以上关闭方式全部失效", en_US: 'prop: closeable | description: drawer closeable', }, }, setter: { componentName: 'BoolSetter', }, description: "控制对话框关闭的方式,值可以为字符串或者布尔值,其中字符串是由以下值组成:\n**close** 表示点击关闭按钮可以关闭对话框\n**mask** 表示点击遮罩区域可以关闭对话框\n**esc** 表示按下 esc 键可以关闭对话框\n如 'close' 或 'close,esc,mask'\n如果设置为 true,则以上关闭方式全部生效\n如果设置为 false,则以上关闭方式全部失效", defaultValue: true, }, ], advanced: { callbacks: { // 与 next-page 的 onNodeAdd 一模一样 onNodeAdd: (dragment, currentNode) => { // 拖入的组件为 P、Block、Slot(把NextPage拖入到面板里时,NextPage的Slot也会触发onNodeAdd事件) 时,不进行包裹 // 拖入的组件 isModal为true时(例如drawer dialog 这类有单独组件树结构的),不进行包裹 if ( !dragment || ['NextP', 'NextBlock', 'Slot'].includes(dragment.componentName) || (dragment.componentMeta.isModal && dragment.componentMeta.isModal()) ) { console.log( `[${dragment.componentName}] doesn\'n need to wrap with NextBlock > NextBlockCell`, ); return; } const NextPProps = { wrap: false, type: 'body2', verAlign: 'middle', textSpacing: true, align: 'left', }; if ( [ 'Form', 'ResponsiveGrid', 'Box', 'Card', 'List', 'Message', 'Slider', 'NextTable', ].includes(dragment.componentName) || dragment.getPropValue('isFillContainer') ) { NextPProps.full = true; } const layoutPSchema = { componentName: 'NextP', title: '段落', props: NextPProps, children: [dragment.exportSchema()], }; // 为目标元素包裹一层 Block const layoutBlockNode = (len) => currentNode.document.createNode({ componentName: 'NextBlock', title: '区块', props: { childTotalColumns: len || 12, }, children: [ { componentName: 'NextBlockCell', title: '子区块', props: { isAutoContainer: true, colSpan: 12, rowSpan: 1, }, children: [layoutPSchema], }, ], }); const dropLocation = dragment.document.canvas.dropLocation; if (!dropLocation) { // 没有 dropLocation 一般是 slot, slot 元素不用特殊处理 不做任何包裹 return; } const dropTarget = dropLocation.target; const dropTargetName = dropLocation.target.componentName || ''; // 找到要拖入进去的节点 ID const targetId = (dropLocation && dropLocation.target.id) || ''; // 找到要拖入进去的节点 let slotTarget = currentNode.slots.length > 0 && currentNode.slots.find((item) => item.id === targetId); const layoutPNode = currentNode.document.createNode(layoutPSchema); // 是否为 aside slot const isAsideSlot = slotTarget && ['aside'].indexOf(slotTarget._slotFor.key) > -1; // 是否为需要被 P 包裹的 Slot const isNeedPSlot = slotTarget && ['header', 'footer', 'nav'].indexOf(slotTarget._slotFor.key) > -1; const wrapWithBlock = (dragment, node, dropTargetName, blockLen) => { setTimeout(() => { console.log( `[${dragment.componentName}] to [${dropTargetName}] need to wrap with NextBlock > NextBlockCell > NextP [from NextPage2]`, ); const newNode = node.document.createNode(layoutBlockNode(blockLen).exportSchema()); node.insertBefore(newNode, dragment, false); dragment.remove(false); newNode.children.get(0).children.get(0).children.get(0).select(); }, 1); }; const wrapWithP = (dragment, node, dropTargetName) => { setTimeout(() => { // const dragmentTarget = dropTarget; // 要拖入的地方如果是 NextP 那就 不再自动包裹 P了 if (dropTargetName === 'NextP') { console.log( `[${dragment.componentName}] to [${dropTargetName}] does't need to wrap with NextP. [from NextPage3]`, ); return; } console.log( `[${dragment.componentName}] to [${dropTargetName}] need to wrap with NextP [from NextPage3]`, ); const newNode = node.document.createNode(Object.assign(layoutPNode.exportSchema())); node.insertBefore(newNode, dragment, false); dragment.remove(false); newNode.children.get(0).select(); }, 1); }; // 需要包裹 Block BlockCell P 的情况: // 1. 组件拖入到 NextPage,的直接子元素下(不包括slot), 此时Block宽度为12 if (['NextPage'].includes(dropTargetName) && currentNode.children.has(dragment)) { wrapWithBlock(dragment, currentNode, dropTargetName, 12); // 需要包裹 Block BlockCell P 的情况: // 2. 组件拖入到 NextPage 的 aside slot, 的直接子元素下 (不包括slot下的进一步内容),此时Block宽度为1 } else if (isAsideSlot && slotTarget && slotTarget.children.has(dragment)) { wrapWithBlock(dragment, slotTarget, dropTargetName, 1); // 需要包裹 P 的情况: // 1. 如果是处于,开启了自然布局模式的容器组件中 (或者Tab里) // 这里的Tab主要是给纪元epoch使用的,因为他们用到了 @ali/vc-deep 的TabLayout组件,没办法在这个组件上再增加属性 isAutoContainer } else if (dropTarget.getPropValue('isAutoContainer') || dropTargetName === 'Tab.Item') { wrapWithP(dragment, dropTarget, dropTargetName); // 需要包裹 P 的情况: // 2. 如果是处于,Page 的 nav header footer 中 } else if (isNeedPSlot && slotTarget) { wrapWithP(dragment, slotTarget, dropTargetName); } // 其他维持原状,不进行其他设置 }, }, }, }, icon: '', category: '布局容器类', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/drawer/snippets.design.ts ================================================ module.exports = [ { title: '侧抽屉', screenshot: 'https://img.alicdn.com/tfs/TB1o0t4u9f2gK0jSZFPXXXsopXa-112-64.png', schema: { componentName: 'Drawer', props: { prefix: 'next-', triggerType: 'click', closeable: true, placement: 'right', hasMask: true, isAutoContainer: true, visible: true, }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/drawer/snippets.ts ================================================ module.exports = [ { title: '侧抽屉', screenshot: 'https://img.alicdn.com/tfs/TB1o0t4u9f2gK0jSZFPXXXsopXa-112-64.png', schema: { componentName: 'Drawer', props: { prefix: 'next-', triggerType: 'click', closeable: true, placement: 'right', hasMask: true, isAutoContainer: true, visible: true, }, }, }, { title: '底部抽屉', screenshot: 'https://img.alicdn.com/tfs/TB1YOd2u2b2gK0jSZK9XXaEgFXa-112-64.png', schema: { componentName: 'Drawer', props: { prefix: 'next-', triggerType: 'click', closeable: true, placement: 'bottom', hasMask: true, isAutoContainer: true, visible: true, }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/drawer-inner/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Drawer.Inner', title: 'Drawer.Inner', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Drawer', main: '', destructuring: true, subName: 'Inner', }, props: [ { name: 'className', propType: 'string', }, { name: 'closeable', propType: 'bool', defaultValue: true, }, { name: 'role', propType: 'string', defaultValue: 'dialog', }, { name: 'title', propType: 'string', }, { name: 'placement', propType: { type: 'oneOf', value: ['top', 'right', 'bottom', 'left'], }, }, { name: 'rtl', propType: 'bool', }, { name: 'onClose', propType: 'func', }, { name: 'locale', propType: 'object', }, { name: 'headerStyle', propType: 'object', }, { name: 'bodyStyle', propType: 'object', }, { name: 'afterClose', propType: 'func', }, { name: 'beforeOpen', propType: 'func', }, { name: 'beforeClose', propType: 'func', }, { name: 'cache', propType: 'bool', }, { name: 'shouldUpdatePosition', propType: 'bool', }, ], category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/dropdown/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Dropdown', title: '下拉菜单', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Dropdown', main: '', destructuring: true, subName: '', }, props: [ { name: 'id', propType: 'string', }, { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'pure', propType: 'bool', defaultValue: false, }, { name: 'rtl', propType: 'bool', }, { name: 'className', propType: 'string', }, { name: 'visible', propType: 'bool', description: '弹层当前是否显示', }, { name: 'defaultVisible', propType: 'bool', description: '弹层默认是否显示', defaultValue: false, }, { name: 'onVisibleChange', propType: 'func', description: '弹层显示或隐藏时触发的回调函数\n@param {Boolean} visible 弹层是否显示\n@param {String} type 触发弹层显示或隐藏的来源 fromContent 表示由Dropdown内容触发; fromTrigger 表示由trigger的点击触发; docClick 表示由document的点击触发', }, { name: 'triggerType', propType: { type: 'oneOfType', value: [ 'string', { type: 'instanceOf', value: 'array', }, ], }, description: "触发弹层显示或隐藏的操作类型,可以是 'click','hover',或者它们组成的数组,如 ['hover', 'click']", defaultValue: 'hover', }, { name: 'disabled', propType: 'bool', description: '设置此属性,弹层无法显示或隐藏', defaultValue: false, }, { name: 'align', propType: 'string', description: '弹层相对于触发元素的定位, 详见 Overlay 的定位部分', defaultValue: 'tl bl', }, { name: 'offset', propType: { type: 'instanceOf', value: 'array', }, description: '弹层相对于trigger的定位的微调, 接收数组[hoz, ver], 表示弹层在 left / top 上的增量\ne.g. [100, 100] 表示往右(RTL 模式下是往左) 、下分布偏移100px', defaultValue: [0, 0], }, { name: 'delay', propType: 'number', description: '弹层显示或隐藏的延时时间(以毫秒为单位),在 triggerType 被设置为 hover 时生效', defaultValue: 200, }, { name: 'autoFocus', propType: 'bool', description: '弹层打开时是否让其中的元素自动获取焦点', }, { name: 'hasMask', propType: 'bool', description: '是否显示遮罩', defaultValue: false, }, { name: 'cache', propType: 'bool', description: '隐藏时是否保留子节点', defaultValue: false, }, { name: 'animation', propType: { type: 'oneOfType', value: ['object', 'bool'], }, description: "配置动画的播放方式,支持 { in: 'enter-class', out: 'leave-class' } 的对象参数,如果设置为 false,则不播放动画\n@default { in: 'expandInDown', out: 'expandOutUp' }", }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: true, }, props: { isExtends: true, override: [ { name: 'trigger', title: { label: '触发元素', tip: '', }, setter: { componentName: 'SlotSetter', initialValue: { type: 'JSSlot', value: [], }, }, supportVariable: true, }, { name: 'animation', title: { label: 'animation', tip: "配置动画的播放方式,支持 { in: 'enter-class', out: 'leave-class' } 的对象参数,如果设置为 false,则不播放动画\n@default { in: 'expandInDown', out: 'expandOutUp' }", }, setter: { componentName: 'MixedSetter', props: { setters: [ { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'in', description: '', setter: 'StringSetter', supportVariable: true, defaultValue: 'enter-class', }, { name: 'out', description: '', setter: 'StringSetter', supportVariable: true, defaultValue: 'leave-class', }, ], }, }, initialValue: { in: 'enter-class', out: 'leave-class', }, }, { componentName: 'BoolSetter', initialValue: true, }, ], }, }, }, ], }, }, icon: '', category: '信息输入', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/error-boundary/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'ErrorBoundary', title: 'ErrorBoundary', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'ConfigProvider', main: '', destructuring: true, subName: 'ErrorBoundary', }, props: [ { name: 'children', propType: { type: 'instanceOf', value: 'element', }, }, { name: 'afterCatch', propType: 'func', description: '捕获错误后的自定义处理, 比如埋点上传\n@param {Object} error 错误\n@param {Object} errorInfo 错误详细信息', }, { name: 'fallbackUI', propType: 'func', description: '捕获错误后的展现 自定义组件\n@param {Object} error 错误\n@param {Object} errorInfo 错误详细信息\n@returns {Element} 捕获错误后的处理', }, { name: 'style', propType: 'object', }, ], category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/field/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Field', title: 'Field', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Field', main: '', destructuring: true, subName: '', }, props: [ { name: 'this', propType: 'any', }, ], category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/form/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Form', title: '表单容器', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Form', main: '', destructuring: true, subName: '', }, props: [ { name: 'inline', propType: 'bool', description: '内联表单', }, { name: 'size', title: { label: 'Size', tip: '单个 Item 的 size 自定义,优先级高于 Form 的 size, 并且当组件与 Item 一起使用时,组件自身设置 size 属性无效。\n@enumdesc 大, 中, 小', }, propType: { type: 'oneOf', value: ['large', 'medium', 'small'], }, description: '单个 Item 的 size 自定义,优先级高于 Form 的 size, 并且当组件与 Item 一起使用时,组件自身设置 size 属性无效。\n@enumdesc 大, 中, 小', defaultValue: 'medium', }, { name: 'fullWidth', propType: 'bool', description: '单个 Item 中表单类组件宽度是否是100%', }, { name: 'labelAlign', title: { label: '标签的位置', tip: '上, 左, 内', }, propType: { type: 'oneOf', value: ['top', 'left', 'inset'], }, description: '标签的位置\n@enumdesc 上, 左, 内', defaultValue: 'left', }, { name: 'labelTextAlign', propType: { type: 'oneOf', value: ['left', 'right'], }, description: '标签的左右对齐方式\n@enumdesc 左, 右', }, { name: 'onSubmit', propType: 'func', description: 'form内有 `htmlType="submit"` 的元素的时候会触发', }, { name: 'className', propType: 'string', description: '扩展class', }, { name: 'style', propType: 'object', description: '自定义内联样式', }, { name: 'value', propType: { type: 'oneOfType', value: ['Json', 'JSExpression'], }, description: '表单数值', }, { name: 'onChange', propType: 'func', description: '表单变化回调\n@param {Object} values 表单数据\n@param {Object} item 详细\n@param {String} item.name 变化的组件名\n@param {String} item.value 变化的数据\n@param {Object} item.field field 实例', }, { name: 'rtl', propType: 'bool', }, { name: 'device', propType: { type: 'oneOf', value: ['phone', 'tablet', 'desktop'], }, description: '预设屏幕宽度', defaultValue: 'desktop', }, { name: 'responsive', propType: 'bool', description: '是否开启内置的响应式布局 (使用ResponsiveGrid)', }, { name: 'isPreview', propType: 'bool', description: '是否开启预览态', }, { name: 'field', propType: 'any', description: 'field 实例', }, ], configure: { component: { isContainer: true, }, props: [ { name: 'inline', title: { label: { type: 'i18n', zh_CN: '内联表单', en_US: 'Inline', }, tip: { type: 'i18n', zh_CN: '属性: inline | 说明: 内联表单', en_US: 'prop: inline | description: inline form', }, }, setter: { componentName: 'MixedSetter', props: { setters: ['BoolSetter', 'ExpressionSetter'], }, }, setValue: (target, value) => { if (value === true) { target.parent.setPropValue('labelCol', null); target.parent.setPropValue('wrapperCol', null); } else { target.parent.setPropValue('labelCol', { span: 2 }); target.parent.setPropValue('wrapperCol', { span: 14 }); } return target.parent.setPropValue('inline', value); }, }, { name: 'fullWidth', title: { label: { type: 'i18n', zh_CN: '宽度占满', en_US: 'FullWidth', }, tip: { type: 'i18n', zh_CN: '属性: fullWidth | 说明: 单个 Item 中表单类组件宽度是否是100%', en_US: 'prop: fullWidth | description: full width', }, }, setter: 'BoolSetter', supportVariable: true, }, { name: 'isPreview', title: { label: { type: 'i18n', zh_CN: '预览态', en_US: 'Preview Mode', }, tip: { type: 'i18n', zh_CN: '属性: isPreview | 说明: 是否开启预览态', en_US: 'prop: isPreview | description: preview mode', }, }, setter: 'BoolSetter', supportVariable: true, description: '是否开启预览态', }, { name: 'field', title: { label: { type: 'i18n', zh_CN: 'Field 实例', en_US: 'Field', }, tip: { type: 'i18n', zh_CN: '属性: field | 说明: 传入 Field 实例', en_US: 'prop: field | description: field instance', }, docUrl: 'https://fusion.alibaba-inc.com/pc/component/basic/form#%E5%A4%8D%E6%9D%82%E5%8A%9F%E8%83%BD(Field)', }, setter: { componentName: 'ExpressionSetter', }, }, { name: 'value', title: { label: { type: 'i18n', zh_CN: '表单值', en_US: 'value', }, tip: { type: 'i18n', zh_CN: '属性: value | 说明: 表单值', en_US: 'prop: value | description: value instance', }, }, setter: { componentName: 'MixedSetter', props: { setters: ['JsonSetter', 'ExpressionSetter'], }, }, }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 单个 Item 的 size 自定义,优先级高于 Form 的 size, 并且当组件与 Item 一起使用时,组件自身设置 size 属性无效。\n@enumdesc 大, 中, 小', en_US: 'prop: size | description: size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['large', 'medium', 'small'], }, }, description: '单个 Item 的 size 自定义,优先级高于 Form 的 size, 并且当组件与 Item 一起使用时,组件自身设置 size 属性无效。\n@enumdesc 大, 中, 小', defaultValue: 'medium', }, { name: 'labelAlign', title: { label: { type: 'i18n', zh_CN: '标签位置', en_US: 'Label Align', }, tip: { type: 'i18n', zh_CN: '属性: labelAlign | 说明: 标签的位置\n@enumdesc 上, 左, 内', en_US: 'prop: labelAlign | description: label align', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['top', 'left', 'inset'], }, }, defaultValue: 'left', }, { name: 'labelTextAlign', title: { label: { type: 'i18n', zh_CN: '标签对齐', en_US: 'Text Align', }, tip: { type: 'i18n', zh_CN: '属性: labelTextAlign | 说明: 标签的左右对齐方式\n@enumdesc 左, 右', en_US: 'prop: labelTextAlign | description: label text align', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['left', 'right'], }, }, defaultValue: 'left', }, { name: 'device', title: { label: { type: 'i18n', zh_CN: '设备', en_US: 'Device', }, tip: { type: 'i18n', zh_CN: '属性: device | 说明: 预设屏幕宽度', en_US: 'prop: device | description: device', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['phone', 'tablet', 'desktop'], }, }, defaultValue: 'desktop', }, { type: 'group', title: '布局', display: 'accordion', items: [ { name: 'labelCol', display: 'inline', setter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'span', description: 'span', setter: 'NumberSetter', supportVariable: true, }, { name: 'offset', description: 'offset', setter: 'NumberSetter', supportVariable: true, }, ], }, }, }, description: 'label 标签布局,通 `` 组件,设置 span offset 值,如 {span: 8, offset: 16},该项仅在垂直表单有效', }, { name: 'wrapperCol', display: 'inline', setter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'span', description: 'span', setter: 'NumberSetter', supportVariable: true, }, { name: 'offset', description: 'offset', setter: 'NumberSetter', supportVariable: true, }, ], }, }, }, description: '需要为输入控件设置布局样式时,使用该属性,用法同 labelCol', }, ], }, ], supports: { style: true, events: ['saveField', 'onSubmit', 'onChange'], }, advanced: { callbacks: { onNodeAdd: (dragment, currentNode) => { // 拖入的内容为LayoutP时,不做包裹动作 if (!dragment || dragment.componentName === 'Form.Item') { return; } // 为目标元素包裹一层P const layoutPNode = currentNode.document.createNode({ componentName: 'Form.Item', title: '表单项', props: { label: '表单项: ', }, children: [dragment.exportSchema()], }); // 当前dragment还未添加入node子节点,需要setTimeout处理 setTimeout(() => { if (!currentNode.children.has(dragment)) { return; } const newNode = currentNode.document.createNode( Object.assign(layoutPNode.exportSchema()), ); currentNode.insertBefore(newNode, dragment, false); dragment.remove(false); newNode.children.get(0).select(); }, 1); }, }, }, }, icon: 'https://img.alicdn.com/tfs/TB1oH02u2b2gK0jSZK9XXaEgFXa-112-64.png', category: '信息输入', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/form/snippets.ts ================================================ module.exports = [ { title: '表单容器', screenshot: 'https://img.alicdn.com/tfs/TB1oH02u2b2gK0jSZK9XXaEgFXa-112-64.png', schema: { componentName: 'Form', props: { labelCol: { span: 2, }, wrapperCol: { span: 14, }, labelAlign: 'left', }, children: [ { componentName: 'Form.Item', props: { label: 'Email: ', required: true, }, children: [ { componentName: 'Input', props: { name: 'email', size: 'medium', placeholder: '用户名', }, }, ], }, { componentName: 'Form.Item', props: { label: 'Password: ', required: true, }, children: [ { componentName: 'Input.Password', props: { name: 'password', placeholder: '请输入密码', size: 'medium', }, }, ], }, { componentName: 'Form.Item', props: { label: '\b', }, children: [ { componentName: 'Form.Submit', props: { type: 'primary', validate: true, children: 'Submit', }, }, { componentName: 'Form.Reset', props: { style: { marginLeft: 10, }, children: 'Reset', }, }, ], }, ], }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/form-error/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Form.Error', title: 'Form.Error', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Form', main: '', destructuring: true, subName: 'Error', }, props: [ { name: 'name', propType: { type: 'oneOfType', value: [ 'string', { type: 'instanceOf', value: 'array', }, ], }, description: '表单名', }, { name: 'field', propType: 'object', description: '自定义 field (在 Form 内不需要设置)', }, { name: 'style', propType: 'object', }, { name: 'className', propType: 'string', }, { name: 'children', propType: { type: 'oneOfType', value: [ { type: 'instanceOf', value: 'node', }, 'func', ], }, description: '自定义错误渲染, 可以是 node 或者 function(errors, state)', }, { name: 'prefix', propType: 'string', defaultValue: 'next-', }, ], category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/form-item/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Form.Item', title: '表单项', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Form', main: '', destructuring: true, subName: 'Item', }, props: [ { name: 'id', propType: 'string', }, { name: 'rtl', propType: 'bool', }, { name: 'label', propType: 'string', description: '标签', }, { name: 'labelCol', propType: { type: 'shape', value: [ { name: 'span', description: 'span', propType: 'number', }, { name: 'offset', description: 'offset', propType: 'number', }, ], }, description: 'label 标签布局,通 `` 组件,设置 span offset 值,如 {span: 8, offset: 16},该项仅在垂直表单有效', }, { name: 'wrapperCol', propType: { type: 'shape', value: [ { name: 'span', description: 'span', propType: 'number', }, { name: 'offset', description: 'offset', propType: 'number', }, ], }, description: '需要为输入控件设置布局样式时,使用该属性,用法同 labelCol', }, { name: 'help', title: { label: '自定义提示信息', tip: '如不设置,则会根据校验规则自动生成.', }, propType: 'string', description: '自定义提示信息,如不设置,则会根据校验规则自动生成.', }, { name: 'extra', title: { label: '额外的提示信息', tip: '和 help 类似,当需要错误信息和提示文案同时出现时,可以使用这个。 位于错误信息后面', }, propType: 'string', description: '额外的提示信息,和 help 类似,当需要错误信息和提示文案同时出现时,可以使用这个。 位于错误信息后面', }, { name: 'validateState', title: { label: '校验状态', tip: '如不设置,则会根据校验规则自动生成\n@enumdesc 失败, 成功, 校验中, 警告', }, propType: { type: 'oneOf', value: ['error', 'success', 'loading', 'warning'], }, description: '校验状态,如不设置,则会根据校验规则自动生成\n@enumdesc 失败, 成功, 校验中, 警告', }, { name: 'style', propType: 'object', description: '自定义内联样式', }, { name: 'size', title: { label: 'Size', tip: '单个 Item 的 size 自定义,优先级高于 Form 的 size, 并且当组件与 Item 一起使用时,组件自身设置 size 属性无效。', }, propType: { type: 'oneOf', value: ['large', 'small', 'medium'], }, description: '单个 Item 的 size 自定义,优先级高于 Form 的 size, 并且当组件与 Item 一起使用时,组件自身设置 size 属性无效。', }, { name: 'fullWidth', title: { label: 'fullWidth', tip: '单个 Item 中表单类组件宽度是否是100%', }, propType: 'bool', description: '单个 Item 中表单类组件宽度是否是100%', }, { name: 'labelAlign', title: { label: '标签的位置', tip: '上, 左, 内', }, propType: { type: 'oneOf', value: ['top', 'left', 'inset'], }, description: '标签的位置\n@enumdesc 上, 左, 内', }, { name: 'labelTextAlign', title: { label: '标签的左右对齐方式', tip: '左, 右', }, propType: { type: 'oneOf', value: ['left', 'right'], }, description: '标签的左右对齐方式\n@enumdesc 左, 右', }, { name: 'className', propType: 'string', description: '扩展class', }, { name: 'required', title: { label: '不能为空', tip: '[表单校验] 不能为空', }, propType: 'bool', description: '[表单校验] 不能为空', }, { name: 'requiredMessage', title: { label: '自定义错误信息', tip: '[表单校验]为空时自定义错误信息', }, propType: 'string', description: 'required 自定义错误信息', }, { name: 'min', title: { label: '最小值', tip: '[表单校验] 最小值', }, propType: 'number', description: '[表单校验] 最小值', }, { name: 'max', title: { label: '最大值', tip: '[表单校验] 最大值', }, propType: 'number', description: '[表单校验] 最大值', }, { name: 'minmaxMessage', title: { label: 'min/max message', tip: '[表单校验] min/max 自定义错误信息', }, propType: 'string', description: 'min/max 自定义错误信息', }, { name: 'minLength', title: { label: '最小长度', tip: '[表单校验] 字符串最小长度 / 数组最小个数', }, propType: 'number', description: '[表单校验] 字符串最小长度 / 数组最小个数', }, { name: 'maxLength', title: { label: '最大长度', tip: '[表单校验] 字符串最大长度 / 数组最大个数', }, propType: 'number', description: '[表单校验] 字符串最大长度 / 数组最大个数', }, { name: 'minmaxLengthMessage', title: { label: 'max|min length error message', tip: '[表单校验] minLength/maxLength 自定义错误信息', }, propType: 'string', description: 'minLength/maxLength 自定义错误信息', }, { name: 'length', title: { label: '长度', tip: '[表单校验] 字符串精确长度 / 数组精确个数', }, propType: 'number', description: '[表单校验] 字符串精确长度 / 数组精确个数', }, { name: 'lengthMessage', title: { label: 'length error message', tip: '[表单校验] minLength/maxLength 自定义错误信息', }, propType: 'string', description: 'length 自定义错误信息', }, { name: 'pattern', title: { label: '正则', tip: '[表单校验] 正则校验', }, propType: 'string', description: '正则校验', }, { name: 'patternMessage', title: { label: 'pattern error message', tip: '[表单校验] pattern 自定义错误信息', }, propType: 'string', description: 'pattern 自定义错误信息', }, { name: 'format', title: { label: 'format', tip: '[表单校验] 四种常用的 pattern', }, propType: { type: 'oneOf', value: ['number', 'email', 'url', 'tel'], }, description: '[表单校验] 四种常用的 pattern', }, { name: 'formatMessage', title: { label: 'format error message', tip: '[表单校验] format 自定义错误信息', }, propType: 'string', description: 'format 自定义错误信息', }, { name: 'validator', propType: 'func', description: '[表单校验] 自定义校验函数', }, { name: 'autoValidate', propType: 'bool', description: '是否修改数据时自动触发校验', }, { name: 'device', propType: { type: 'oneOf', value: ['phone', 'tablet', 'desktop'], }, description: '预设屏幕宽度', }, { name: 'responsive', propType: 'bool', }, { name: 'colSpan', propType: 'number', description: '在响应式布局模式下,表单项占多少列', }, { name: 'labelWidth', propType: { type: 'oneOfType', value: ['string', 'number'], }, description: '在响应式布局下,且label在左边时,label的宽度是多少', defaultValue: 100, }, { name: 'isPreview', propType: 'bool', description: '是否开启预览态', }, ], configure: { component: { isContainer: true, nestingRule: { parentWhitelist: ['Form'], }, }, supports: { style: true, }, props: [ { name: 'label', title: { label: { type: 'i18n', zh_CN: '标签文本', en_US: 'Label', }, tip: { type: 'i18n', zh_CN: '属性: label | 说明: 标签文本内容', en_US: 'prop: label | description: label content', }, }, setter: 'StringSetter', supportVariable: true, description: '标签', }, { name: 'help', title: { label: { type: 'i18n', zh_CN: '错误提示', en_US: 'Help Info', }, tip: { type: 'i18n', zh_CN: '属性: help | 说明: 自定义提示信息, 如不设置,则会根据校验规则自动生成.', en_US: 'prop: help | description: help infomation', }, }, setter: 'StringSetter', supportVariable: true, description: '自定义提示信息,如不设置,则会根据校验规则自动生成.', }, { name: 'extra', title: { label: { type: 'i18n', zh_CN: '帮助提示', en_US: 'Extra Info', }, tip: { type: 'i18n', zh_CN: '属性: extra | 说明: 额外的提示信息, 和 help 类似,当需要错误信息和提示文案同时出现时,可以使用这个。 位于错误信息后面', en_US: 'prop: extra | description: extra infomation', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'validateState', title: { label: '校验状态', tip: '如不设置,则会根据校验规则自动生成\n@enumdesc 失败, 成功, 校验中, 警告', }, setter: { componentName: 'RadioGroupSetter', props: { options: ['error', 'success', 'loading', 'warning'], }, }, }, { name: 'size', title: { label: '尺寸', tip: '单个 Item 的 size 自定义,优先级高于 Form 的 size, 并且当组件与 Item 一起使用时,组件自身设置 size 属性无效。', }, setter: { componentName: 'RadioGroupSetter', props: { options: ['small', 'medium', 'large'], }, }, defaultValue: 'medium', }, { name: 'labelAlign', title: { label: '标签位置', tip: '上, 左, 内', }, setter: { componentName: 'RadioGroupSetter', props: { options: ['top', 'left', 'inset'], }, }, defaultValue: 'left', }, { name: 'labelTextAlign', title: { label: '标签对齐', tip: '左, 右', }, setter: { componentName: 'RadioGroupSetter', props: { options: ['left', 'right'], }, }, defaultValue: 'left', }, { name: 'device', title: { label: '设备', }, setter: { componentName: 'RadioGroupSetter', props: { options: ['phone', 'tablet', 'desktop'], }, }, defaultValue: 'desktop', }, { name: 'fullWidth', title: { label: '宽度占满', tip: '单个 Item 中表单类组件宽度是否是100%', }, setter: 'BoolSetter', supportVariable: true, description: '单个 Item 中表单类组件宽度是否是100%', }, { name: 'isPreview', title: { label: '预览态', }, setter: 'BoolSetter', supportVariable: true, description: '是否开启预览态', }, { name: 'autoValidate', title: { label: '自动校验', }, setter: 'BoolSetter', supportVariable: true, description: '是否修改数据时自动触发校验', }, { type: 'group', display: 'accordion', title: '校验', items: [ { type: 'group', display: 'popup', title: '非空校验', items: [ { name: 'required', title: { label: '不能为空', tip: '[表单校验] 不能为空', }, setter: 'BoolSetter', supportVariable: true, description: '[表单校验] 不能为空', }, { name: 'requiredMessage', title: { label: '错误信息', tip: '[表单校验]为空时自定义错误信息', }, setter: 'StringSetter', supportVariable: true, description: 'required 自定义错误信息', }, ], }, { type: 'group', display: 'popup', title: '最大/最小值校验', items: [ { name: 'min', title: { label: '最小值', tip: '[表单校验] 最小值', }, setter: 'NumberSetter', supportVariable: true, description: '[表单校验] 最小值', }, { name: 'max', title: { label: '最大值', tip: '[表单校验] 最大值', }, setter: 'NumberSetter', supportVariable: true, description: '[表单校验] 最大值', }, { name: 'minmaxMessage', title: { label: '错误信息', tip: '[表单校验] min/max 自定义错误信息', }, setter: 'StringSetter', supportVariable: true, }, ], }, { type: 'group', display: 'popup', title: '最大/最小长度校验', items: [ { name: 'minLength', title: { label: '最小长度', tip: '[表单校验] 字符串最小长度 / 数组最小个数', }, setter: 'NumberSetter', supportVariable: true, description: '[表单校验] 字符串最小长度 / 数组最小个数', }, { name: 'maxLength', title: { label: '最大长度', tip: '[表单校验] 字符串最大长度 / 数组最大个数', }, setter: 'NumberSetter', supportVariable: true, description: '[表单校验] 字符串最大长度 / 数组最大个数', }, { name: 'minmaxLengthMessage', title: { label: '错误信息', tip: '[表单校验] minLength/maxLength 自定义错误信息', }, setter: 'StringSetter', supportVariable: true, description: 'minLength/maxLength 自定义错误信息', }, ], }, { type: 'group', display: 'popup', title: '长度校验', items: [ { name: 'length', title: { label: '长度', tip: '[表单校验] 字符串精确长度 / 数组精确个数', }, setter: 'NumberSetter', supportVariable: true, description: '[表单校验] 字符串精确长度 / 数组精确个数', }, { name: 'lengthMessage', title: { label: '错误信息', tip: '[表单校验] minLength/maxLength 自定义错误信息', }, setter: 'StringSetter', supportVariable: true, description: 'length 自定义错误信息', }, ], }, { type: 'group', display: 'popup', title: '正则校验', items: [ { name: 'pattern', title: { label: '正则', tip: '[表单校验] 正则校验', }, setter: 'StringSetter', supportVariable: true, description: '正则校验', }, { name: 'patternMessage', title: { label: '错误信息', tip: '[表单校验] pattern 自定义错误信息', }, setter: 'StringSetter', supportVariable: true, description: 'pattern 自定义错误信息', }, ], }, { type: 'group', display: 'popup', title: '格式化校验', items: [ { name: 'format', title: { label: 'format', tip: '[表单校验] 四种常用的 pattern', }, setter: { componentName: 'RadioGroupSetter', props: { options: ['number', 'email', 'url', 'tel'], }, }, description: '[表单校验] 四种常用的 pattern', }, { name: 'formatMessage', title: { label: '错误信息', tip: '[表单校验] format 自定义错误信息', }, setter: 'StringSetter', supportVariable: true, description: 'format 自定义错误信息', }, ], }, { name: 'validator', display: 'popup', title: { label: '自定义校验函数', }, setter: 'FunctionSetter', supportVariable: true, description: '[表单校验] 自定义校验函数', }, ], }, { type: 'group', title: '布局', display: 'accordion', items: [ { name: 'labelCol', display: 'inline', setter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'span', description: 'span', setter: 'NumberSetter', supportVariable: true, }, { name: 'offset', description: 'offset', setter: 'NumberSetter', supportVariable: true, }, ], }, }, }, description: 'label 标签布局,通 `` 组件,设置 span offset 值,如 {span: 8, offset: 16},该项仅在垂直表单有效', }, { name: 'wrapperCol', display: 'inline', setter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'span', description: 'span', setter: 'NumberSetter', supportVariable: true, }, { name: 'offset', description: 'offset', setter: 'NumberSetter', supportVariable: true, }, ], }, }, }, description: '需要为输入控件设置布局样式时,使用该属性,用法同 labelCol', }, ], }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', supportVariable: true, }, ], }, ], advanced: { callbacks: { onNodeRemove: (removedNode, currentNode) => { if (!removedNode || !currentNode) { return; } const children = currentNode.children; // 若无children,则说明当前P组件内已为空,需要删除P组件本身 if (children && children.length === 0) { currentNode.remove(); } }, }, }, }, icon: 'https://img.alicdn.com/tfs/TB1nYqOuW61gK0jSZFlXXXDKFXa-112-64.png', category: '信息输入', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/form-reset/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Form.Reset', title: '重置按钮', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Form', main: '', destructuring: true, subName: 'Reset', }, props: [ { name: 'onClick', propType: 'func', description: '点击提交后触发', }, { name: 'style', propType: 'object', }, { name: 'children', title: '内容', propType: 'string', }, { name: 'icon', propType: 'string', description: '自定义内联样式', }, { name: 'type', title: '类型', propType: { type: 'oneOf', value: ['primary', 'secondary', 'normal'], }, description: '按钮的类型', defaultValue: 'normal', }, { name: 'size', title: '尺寸', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '按钮的尺寸', defaultValue: 'medium', }, { name: 'iconSize', title: 'Icon 尺寸', propType: { type: 'oneOf', value: ['xxs', 'xs', 'small', 'medium', 'large', 'xl', 'xxl', 'xxxl'], }, defaultValue: 'small', description: '按钮中 Icon 的尺寸,用于替代 Icon 的默认大小', }, { name: 'ghost', title: 'ghost', propType: { type: 'oneOf', value: [true, false, 'light', 'dark'], }, description: '是否为幽灵按钮', defaultValue: false, initialValue: false, }, { name: 'toDefault', propType: 'bool', description: '返回默认值', }, { name: 'loading', title: 'loading', propType: 'bool', description: '设置按钮的载入状态', defaultValue: false, }, { name: 'text', title: 'text', propType: 'bool', description: '是否为文本按钮', defaultValue: false, }, { name: 'warning', title: 'warning', propType: 'bool', description: '是否为警告按钮', defaultValue: false, }, { name: 'disabled', title: 'disabled', propType: 'bool', description: '是否禁用', defaultValue: false, }, { name: 'className', propType: 'string', }, { name: 'onMouseUp', propType: 'func', }, { name: 'style', propType: 'object', description: '自定义内联样式', }, ], configure: { props: { isExtends: true, override: [ { name: 'icon', setter: 'IconSetter', supportVariable: true, setValue: (target, value) => { target.node.children.importSchema( value && { componentName: 'Icon', props: { type: value, style: { marginRight: 5 } }, }, true, ); }, }, { name: 'children', title: { label: { type: 'i18n', zh_CN: '文本内容', en_US: 'content', }, tip: '按钮文本内容', }, setter: { componentName: 'MixedSetter', props: { setters: ['StringSetter', 'ExpressionSetter'], }, }, }, ], }, }, category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/form-submit/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Form.Submit', title: '提交按钮', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Form', main: '', destructuring: true, subName: 'Submit', }, props: [ { name: 'onClick', propType: 'func', description: '点击提交后触发\n@param {Object} value 数据\n@param {Object} errors 错误数据\n@param {class} field 实例', }, { name: 'style', propType: 'object', }, { name: 'children', title: '内容', propType: 'string', }, { name: 'icon', propType: 'string', description: '自定义内联样式', }, { name: 'type', title: '类型', propType: { type: 'oneOf', value: ['primary', 'secondary', 'normal'], }, description: '按钮的类型', defaultValue: 'normal', }, { name: 'size', title: '尺寸', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '按钮的尺寸', defaultValue: 'medium', }, { name: 'iconSize', title: 'Icon 尺寸', propType: { type: 'oneOf', value: ['xxs', 'xs', 'small', 'medium', 'large', 'xl', 'xxl', 'xxxl'], }, defaultValue: 'small', description: '按钮中 Icon 的尺寸,用于替代 Icon 的默认大小', }, { name: 'ghost', title: 'ghost', propType: { type: 'oneOf', value: [true, false, 'light', 'dark'], }, description: '是否为幽灵按钮', defaultValue: false, initialValue: false, }, { name: 'validate', title: { label: { type: 'i18n', zh_CN: '是否校验', en_US: 'Validate', }, tip: { type: 'i18n', zh_CN: '属性: validate | 说明: 是否校验/需要校验的 name 数组', en_US: 'prop: validate | description: validate or validate array', }, }, propType: { type: 'oneOfType', value: [ 'bool', { type: 'instanceOf', value: 'array', }, ], }, description: '是否校验/需要校验的 name 数组', }, { name: 'loading', title: 'loading', propType: 'bool', description: '设置按钮的载入状态', defaultValue: false, }, { name: 'text', title: 'text', propType: 'bool', description: '是否为文本按钮', defaultValue: false, }, { name: 'warning', title: 'warning', propType: 'bool', description: '是否为警告按钮', defaultValue: false, }, { name: 'disabled', title: 'disabled', propType: 'bool', description: '是否禁用', defaultValue: false, }, { name: 'className', propType: 'string', }, { name: 'htmlType', propType: 'string', defaultValue: 'submit', }, { name: 'onMouseUp', propType: 'func', }, { name: 'style', propType: 'object', description: '自定义内联样式', }, ], configure: { props: { isExtends: true, override: [ { name: 'disabled', setter: { componentName: 'MixedSetter', props: { setters: ['ExpressionSetter', 'BoolSetter'], }, }, }, { name: 'icon', setter: 'IconSetter', supportVariable: true, extraProps: { defaultValue: '', onChange: { type: 'JSFunction', value: '(val, field, editor) => {\n field.node.children.importSchema(val && {"componentName": "Icon", "props": {"type": val, "style": {"marginRight": 5}}}, true); //field.top.setPropValue(\'children\', [{"componentName": "Icon", "props": {"type": val}}, (field.top.getPropValue(\'children\') || []).slice(-1)]);\n}', }, }, }, { name: 'children', title: { label: { type: 'i18n', zh_CN: '文本内容', en_US: 'content', }, tip: '按钮文本内容', }, setter: { componentName: 'MixedSetter', props: { setters: ['StringSetter', 'ExpressionSetter'], }, }, }, ], }, }, category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/group/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Group', title: 'Group', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Nav', main: '', destructuring: true, subName: 'Group', }, props: [ { name: 'className', propType: 'string', description: '自定义类名', }, { name: 'label', propType: { type: 'instanceOf', value: 'node', }, description: '标签内容', }, { name: 'children', propType: { type: 'instanceOf', value: 'node', }, description: '导航项和子导航', }, { name: 'style', propType: 'object', }, ], category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/icon/meta.design.ts ================================================ import { IPublicModelNode } from '@alilc/lowcode-types'; import snippets from './snippets'; export default { group: '原子组件', componentName: 'Icon', title: '图标', docUrl: '', screenshot: 'https://img.alicdn.com/imgextra/i1/O1CN01yR8vcY1M504YbHxzo_!!6000000001382-55-tps-56-56.svg', icon: 'https://img.alicdn.com/imgextra/i1/O1CN01yR8vcY1M504YbHxzo_!!6000000001382-55-tps-56-56.svg', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Icon', main: '', destructuring: true, subName: '', }, props: [ { name: 'type', propType: 'string', description: '指定显示哪种图标', }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '图标尺寸', en_US: 'Icon Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 指定图标大小', en_US: 'prop: size | description: icon size', }, }, propType: { type: 'oneOfType', value: [ { type: 'oneOf', value: ['xxs', 'xs', 'small', 'medium', 'large', 'xl', 'xxl', 'xxxl', 'inherit'], }, 'number', ], }, description: '指定图标大小', defaultValue: 'medium', }, { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, ], configure: { props: [ { name: 'type', title: { label: { type: 'i18n', zh_CN: '图标类型', en_US: 'Icon', }, tip: { type: 'i18n', zh_CN: '属性: type | 说明: 图标类型', en_US: 'prop: type | description: icon type', }, }, setter: { componentName: 'IconSetter', props: { hasClear: false, }, }, }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '图标尺寸', en_US: 'Icon Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 指定图标大小', en_US: 'prop: size | description: icon size', }, }, setter: { componentName: 'SelectSetter', props: { options: [ { label: 'xxs', value: 'xxs', }, { label: 'xs', value: 'xs', }, { label: 'small', value: 'small', }, { label: 'medium', value: 'medium', }, { label: 'large', value: 'large', }, { label: 'xl', value: 'xl', }, { label: 'xxl', value: 'xxl', }, { label: 'xxxl', value: 'xxxl', }, { label: 'inherit', value: 'inherit', }, ], }, }, description: '指定图标大小', defaultValue: 'medium', }, ], advanced: { callbacks: { onHoverHook: (currentNode: IPublicModelNode) => { return !currentNode?.getPropValue('disabled'); }, onMouseDownHook: (e: MouseEvent, currentNode: IPublicModelNode) => { return !currentNode?.getPropValue('disabled'); }, onClickHook: (e: MouseEvent, currentNode: IPublicModelNode) => { return !currentNode?.getPropValue('disabled'); }, onMoveHook: (currentNode: IPublicModelNode) => { return !currentNode?.getPropValue('disabled'); }, }, }, }, category: '通用', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/icon/meta.ts ================================================ import { IPublicModelNode } from '@alilc/lowcode-types'; import snippets from './snippets'; export default { group: '原子组件', componentName: 'Icon', title: '图标', docUrl: '', screenshot: 'https://img.alicdn.com/imgextra/i1/O1CN01yR8vcY1M504YbHxzo_!!6000000001382-55-tps-56-56.svg', icon: 'https://img.alicdn.com/imgextra/i1/O1CN01yR8vcY1M504YbHxzo_!!6000000001382-55-tps-56-56.svg', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Icon', main: '', destructuring: true, subName: '', }, props: [ { name: 'type', propType: 'string', description: '指定显示哪种图标', }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '图标尺寸', en_US: 'Icon Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 指定图标大小', en_US: 'prop: size | description: icon size', }, }, propType: { type: 'oneOfType', value: [ { type: 'oneOf', value: ['xxs', 'xs', 'small', 'medium', 'large', 'xl', 'xxl', 'xxxl', 'inherit'], }, 'number', ], }, description: '指定图标大小', defaultValue: 'medium', }, { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, ], configure: { props: { isExtends: true, override: [ { name: 'type', title: { label: { type: 'i18n', zh_CN: '图标类型', en_US: 'Icon', }, tip: { type: 'i18n', zh_CN: '属性: type | 说明: 图标类型', en_US: 'prop: type | description: icon type', }, }, setter: { componentName: 'IconSetter', props: { hasClear: false, }, }, }, ], }, advanced: { callbacks: { onHoverHook: (currentNode: IPublicModelNode) => { return !currentNode?.getPropValue('disabled'); }, onMouseDownHook: (e: MouseEvent, currentNode: IPublicModelNode) => { return !currentNode?.getPropValue('disabled'); }, onClickHook: (e: MouseEvent, currentNode: IPublicModelNode) => { return !currentNode?.getPropValue('disabled'); }, onMoveHook: (currentNode: IPublicModelNode) => { return !currentNode?.getPropValue('disabled'); }, }, }, }, category: '通用', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/icon/snippets.ts ================================================ export default [ { title: '图标', screenshot: 'https://img.alicdn.com/imgextra/i1/O1CN01yR8vcY1M504YbHxzo_!!6000000001382-55-tps-56-56.svg', schema: { componentName: 'Icon', props: { type: 'smile', }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/img/meta.ts ================================================ module.exports = { componentName: 'Image', title: '图片', npm: { package: '@alilc/lowcode-materials', version: 'latest', exportName: 'Image', main: '', destructuring: true, subName: '', }, props: [ { name: 'src', title: { label: { type: 'i18n', zh_CN: '图片链接', en_US: 'Image Address', }, tip: { type: 'i18n', zh_CN: '属性: src | 说明: 图片链接', en_US: 'prop: src | description: image address', }, }, propType: 'string', defaultValue: 'https://img.alicdn.com/tps/TB16TQvOXXXXXbiaFXXXXXXXXXX-120-120.svg', }, { name: 'title', title: { label: { type: 'i18n', zh_CN: '标题', en_US: 'Title', }, }, propType: 'string', }, { name: 'alt', title: { label: { type: 'i18n', zh_CN: '代替文本', en_US: 'Alt', }, }, propType: 'string', }, { name: 'style', propType: 'object', }, ], icon: 'https://img.alicdn.com/imgextra/i3/O1CN01tnhXhk1GUIFhsXwzA_!!6000000000625-55-tps-56-56.svg', category: '基础元素', group: '精选组件', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/img/snippets.ts ================================================ module.exports = [ { title: '图片', screenshot: 'https://img.alicdn.com/imgextra/i3/O1CN01tnhXhk1GUIFhsXwzA_!!6000000000625-55-tps-56-56.svg', schema: { title: '图片', componentName: 'Image', props: { src: 'https://img.alicdn.com/tps/TB16TQvOXXXXXbiaFXXXXXXXXXX-120-120.svg', }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/inner/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Inner', title: 'Inner', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Dialog', main: '', destructuring: true, subName: 'Inner', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'className', propType: 'string', }, { name: 'title', propType: { type: 'instanceOf', value: 'node', }, }, { name: 'children', propType: { type: 'instanceOf', value: 'node', }, }, { name: 'footer', propType: { type: 'oneOfType', value: [ 'bool', { type: 'instanceOf', value: 'node', }, ], }, }, { name: 'footerAlign', propType: { type: 'oneOf', value: ['left', 'center', 'right'], }, defaultValue: 'right', }, { name: 'footerActions', propType: { type: 'instanceOf', value: 'array', }, defaultValue: ['ok', 'cancel'], }, { name: 'onOk', propType: 'func', }, { name: 'onCancel', propType: 'func', }, { name: 'okProps', propType: 'object', }, { name: 'cancelProps', propType: 'object', }, { name: 'closeable', propType: 'bool', defaultValue: true, }, { name: 'onClose', propType: 'func', }, { name: 'locale', propType: 'object', }, { name: 'role', propType: 'string', defaultValue: 'dialog', }, { name: 'rtl', propType: 'bool', }, { name: 'height', propType: 'string', }, { name: 'style', propType: 'object', }, ], category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/input/meta.design.ts ================================================ import snippets from './snippets.design'; export default { group: '原子组件', componentName: 'Input', title: '输入框', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: 'latest', exportName: 'Input', main: '', destructuring: true, subName: '', }, props: [ { name: 'label', propType: 'string', title: '标签文案', description: 'label', }, { name: 'id', propType: 'string', description: 'ID', }, { name: 'name', propType: 'string', }, { name: 'hasClear', propType: 'bool', description: '是否出现清除按钮', }, { name: 'state', title: '状态', propType: { type: 'oneOf', value: ['error', 'loading', 'success', 'warning'], }, description: '状态\n@enumdesc 错误, 校验中, 成功, 警告', }, { name: 'size', title: '尺寸', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '尺寸\n@enumdesc 小, 中, 大', defaultValue: 'medium', }, { name: 'disabled', propType: 'bool', description: '是否禁用', }, { name: 'maxLength', propType: 'number', description: '最大长度', }, { name: 'showLimitHint', propType: 'bool', description: '是否展现最大长度样式', }, { name: 'cutString', propType: 'bool', description: '是否截断超出字符串', }, { name: 'readOnly', propType: 'bool', description: '是否只读', }, { name: 'trim', propType: 'bool', description: 'onChange返回会自动去除头尾空字符', }, { name: 'placeholder', propType: 'string', description: '输入提示', }, { name: 'hasBorder', propType: 'bool', description: '是否有边框', }, { name: 'onPressEnter', propType: 'func', description: '按下回车的回调', }, { name: 'onClear', propType: 'func', }, { name: 'onChange', propType: 'func', }, { name: 'onKeyDown', propType: 'func', }, { name: 'onFocus', propType: 'func', }, { name: 'onBlur', propType: 'func', }, { name: 'hint', title: 'Icon 水印', propType: 'string', description: '水印 (Icon的type类型,和hasClear占用一个地方)', }, { name: 'innerBefore', propType: 'string', description: '文字前附加内容', }, { name: 'innerAfter', propType: 'string', description: '文字后附加内容', }, { name: 'addonBefore', propType: 'string', description: '输入框前附加内容', }, { name: 'addonAfter', propType: 'string', description: '输入框后附加内容', }, { name: 'addonTextBefore', propType: 'string', description: '输入框前附加文字', }, { name: 'addonTextAfter', propType: 'string', description: '输入框后附加文字', }, { name: 'autoFocus', propType: 'bool', description: '自动聚焦', }, { name: 'style', propType: 'object', }, ], configure: { props: [ { name: 'defaultValue', title: '内容', setter: { componentName: 'StringSetter', props: { placeholder: '请输入', }, }, }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Button Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 按钮尺寸', en_US: 'prop: size | description: button size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '小', value: 'small', }, { label: '中', value: 'medium', }, { label: '大', value: 'large', }, ], }, }, defaultValue: 'medium', }, { name: 'state', title: { label: { type: 'i18n', zh_CN: '状态', en_US: 'State', }, tip: { type: 'i18n', zh_CN: '属性: state | 说明: 状态\n@enumdesc 错误, 校验中, 成功, 警告', en_US: 'prop: state | description: input state', }, }, setter: { componentName: 'SelectSetter', props: { options: [ { value: 'error', title: '错误', }, { value: 'loading', title: '加载', }, { value: 'success', title: '成功', }, { value: 'warning', title: '警告', }, { value: '', title: '默认', }, ], }, }, }, { name: '!widget', title: '部件', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '无', value: 'default', }, { title: '数字', value: 'number', }, { value: 'clear', title: '清除', }, ], }, }, getValue: (target) => { const parentTarget = target.parent; const hasClear = parentTarget.getPropValue('hasClear'); const showLimitHint = parentTarget.getPropValue('showLimitHint'); if (hasClear) { return 'clear'; } else if (showLimitHint) { return 'number'; } else { return 'default'; } }, setValue: (target, value) => { const parentTarget = target.parent; parentTarget.setPropValue('hasClear', false); parentTarget.setPropValue('showLimitHint', false); switch (value) { case 'default': break; case 'clear': parentTarget.setPropValue('hasClear', true); break; case 'number': parentTarget.setPropValue('showLimitHint', true); break; default: break; } }, }, { name: 'maxLength', title: '限制字数', condition: (target) => target?.parent?.getPropValue('showLimitHint'), setter: 'NumberSetter', defaultValue: 20, }, { name: 'style.width', title: '宽度', setter: 'NumberSetter', }, { name: 'hasBorder', title: { label: { type: 'i18n', zh_CN: '显示边框', en_US: 'ShowBorder', }, tip: { type: 'i18n', zh_CN: '属性: hasBorder | 说明: 是否有边框', en_US: 'prop: hasBorder | description: HasBorder', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '无', value: false, }, { label: '有', value: true, }, ], }, }, }, { name: 'label', title: { label: '内联文案', tip: 'label|输入框内置标签', }, setter: { componentName: 'StringSetter', props: { placeholder: '请输入', }, }, }, { name: 'placeholder', title: { label: '占位提示', tip: 'placeholder|输入提示', }, setter: { componentName: 'StringSetter', props: { placeholder: '请输入', }, }, defaultValue: '请输入', }, ], supports: { style: true, events: ['onPressEnter', 'onClear', 'onChange', 'onKeyDown', 'onFocus', 'onBlur'], }, }, icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/input/meta.ts ================================================ import snippets from './snippets'; export default { group: '原子组件', componentName: 'Input', title: '输入框', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Input', main: '', destructuring: true, subName: '', }, props: [ { name: 'label', propType: 'string', title: '标签文案', description: 'label', }, { name: 'id', propType: 'string', description: 'ID', }, { name: 'name', propType: 'string', }, { name: 'hasClear', propType: 'bool', description: '是否出现清除按钮', }, { name: 'state', title: '状态', propType: { type: 'oneOf', value: ['error', 'loading', 'success', 'warning'], }, description: '状态\n@enumdesc 错误, 校验中, 成功, 警告', }, { name: 'size', title: '尺寸', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '尺寸\n@enumdesc 小, 中, 大', defaultValue: 'medium', }, { name: 'disabled', propType: 'bool', description: '是否禁用', }, { name: 'maxLength', propType: 'number', description: '最大长度', }, { name: 'hasLimitHint', propType: 'bool', description: '是否展现最大长度样式', }, { name: 'cutString', propType: 'bool', description: '是否截断超出字符串', }, { name: 'readOnly', propType: 'bool', description: '是否只读', }, { name: 'trim', propType: 'bool', description: 'onChange返回会自动去除头尾空字符', }, { name: 'placeholder', propType: 'string', description: '输入提示', }, { name: 'hasBorder', propType: 'bool', description: '是否有边框', }, { name: 'onPressEnter', propType: 'func', description: '按下回车的回调', }, { name: 'onClear', propType: 'func', }, { name: 'onChange', propType: 'func', }, { name: 'onKeyDown', propType: 'func', }, { name: 'onFocus', propType: 'func', }, { name: 'onBlur', propType: 'func', }, { name: 'hint', title: 'Icon 水印', propType: 'string', description: '水印 (Icon的type类型,和hasClear占用一个地方)', }, { name: 'innerBefore', propType: 'string', description: '文字前附加内容', }, { name: 'innerAfter', propType: 'string', description: '文字后附加内容', }, { name: 'addonBefore', propType: 'string', description: '输入框前附加内容', }, { name: 'addonAfter', propType: 'string', description: '输入框后附加内容', }, { name: 'addonTextBefore', propType: 'string', description: '输入框前附加文字', }, { name: 'addonTextAfter', propType: 'string', description: '输入框后附加文字', }, { name: 'autoFocus', propType: 'bool', description: '自动聚焦', }, { name: 'style', propType: 'object', }, ], configure: { props: [ { name: 'label', setter: 'StringSetter', supportVariable: true, title: { label: { type: 'i18n', zh_CN: '标签文本', en_US: 'Label', }, tip: { type: 'i18n', zh_CN: '属性: label | 说明: 标签文本内容', en_US: 'prop: label | description: label content', }, }, description: 'label', }, { name: 'placeholder', title: { label: { type: 'i18n', zh_CN: '输入提示', en_US: 'Placeholder', }, tip: { type: 'i18n', zh_CN: '属性: placeholder | 说明: 输入提示', en_US: 'prop: placeholder | description: placeholder', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'state', title: { label: { type: 'i18n', zh_CN: '状态', en_US: 'State', }, tip: { type: 'i18n', zh_CN: '属性: state | 说明: 状态\n@enumdesc 错误, 校验中, 成功, 警告', en_US: 'prop: state | description: input state', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { value: 'error', title: 'error', }, { value: 'loading', title: 'loading', }, { value: 'success', title: 'success', }, { value: 'warning', title: 'warning', }, { value: '', title: '默认', }, ], }, }, }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 尺寸\n@enumdesc 小, 中, 大', en_US: 'prop: size | description: size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['small', 'medium', 'large'], }, }, defaultValue: 'medium', }, { name: 'maxLength', title: { label: { type: 'i18n', zh_CN: '最大长度', en_US: 'MaxLength', }, tip: { type: 'i18n', zh_CN: '属性: maxLength | 说明: 最大长度', en_US: 'prop: maxLength | description: max length', }, }, setter: 'NumberSetter', supportVariable: true, description: '最大长度', }, { name: 'hasClear', title: { label: { type: 'i18n', zh_CN: '显示清除', en_US: 'Show Clear', }, tip: { type: 'i18n', zh_CN: '属性: hasClear | 说明: 是否出现清除按钮', en_US: 'prop: hasClear | description: show clear icon', }, }, setter: 'BoolSetter', supportVariable: true, description: '是否出现清除按钮', }, { name: 'disabled', title: { label: { type: 'i18n', zh_CN: '是否禁用', en_US: 'Disabled', }, tip: { type: 'i18n', zh_CN: '属性: disabled | 说明: 是否被禁用', en_US: 'prop: disabled | description: disabled', }, }, setter: 'BoolSetter', supportVariable: true, description: '是否禁用', }, { name: 'hasLimitHint', title: { label: { type: 'i18n', zh_CN: '展示限制', en_US: 'ShowLimit', }, tip: { type: 'i18n', zh_CN: '属性: hasLimitHint | 说明: 是否展现最大长度样式', en_US: 'prop: hasLimitHint | description: hasLimitHint', }, }, setter: 'BoolSetter', supportVariable: true, description: '是否展现最大长度样式', }, { name: 'cutString', title: { label: { type: 'i18n', zh_CN: '是否截断', en_US: 'Cut Off', }, tip: { type: 'i18n', zh_CN: '属性: cutString | 说明: 是否截断超出字符串', en_US: 'prop: cutString | description: whether cut off string', }, }, setter: 'BoolSetter', supportVariable: true, description: '是否截断超出字符串', }, { name: 'readOnly', title: { label: { type: 'i18n', zh_CN: '是否只读', en_US: 'ReadOnly', }, tip: { type: 'i18n', zh_CN: '属性: readOnly | 说明: 是否只读', en_US: 'prop: readOnly | description: ReadOnly', }, }, setter: 'BoolSetter', supportVariable: true, description: '是否只读', }, { name: 'trim', title: { label: { type: 'i18n', zh_CN: '是否 Trim', en_US: 'Trim', }, tip: { type: 'i18n', zh_CN: '属性: trim | 说明: onChange返回会自动去除头尾空字符', en_US: 'prop: trim | description: whether trim when onChange called', }, }, setter: 'BoolSetter', supportVariable: true, }, { name: 'hasBorder', title: { label: { type: 'i18n', zh_CN: '显示边框', en_US: 'ShowBorder', }, tip: { type: 'i18n', zh_CN: '属性: hasBorder | 说明: 是否有边框', en_US: 'prop: hasBorder | description: HasBorder', }, }, setter: 'BoolSetter', supportVariable: true, }, { name: 'autoFocus', title: { label: { type: 'i18n', zh_CN: '自动聚焦', en_US: 'Auto Focus', }, tip: { type: 'i18n', zh_CN: '属性: autoFocus | 说明: 自动聚焦', en_US: 'prop: autoFocus | description: autoFocus', }, }, setter: 'BoolSetter', supportVariable: true, description: '自动聚焦', }, { name: 'hint', title: { label: { type: 'i18n', zh_CN: 'Icon 水印', en_US: 'IconHint', }, tip: { type: 'i18n', zh_CN: '属性: hint | 说明: Icon 水印', en_US: 'prop: hint | description: Icon hint', }, }, setter: { componentName: 'IconSetter', }, }, { name: 'innerBefore', display: 'block', title: { label: { type: 'i18n', zh_CN: '文字前附加内容', en_US: 'Inner Before', }, tip: { type: 'i18n', zh_CN: '属性: innerBefore | 说明: 文字前附加内容', en_US: 'prop: innerBefore | description: innerBefore', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'innerAfter', display: 'block', title: { label: { type: 'i18n', zh_CN: '文字后附加内容', en_US: 'Inner After', }, tip: { type: 'i18n', zh_CN: '属性: innerAfter | 说明: 文字后附加内容', en_US: 'prop: innerAfter | description: innerAfter', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'addonBefore', display: 'block', title: { label: { type: 'i18n', zh_CN: '输入框前附加内容', en_US: 'Addon Before', }, tip: { type: 'i18n', zh_CN: '属性: addonBefore | 说明: 输入框前附加内容', en_US: 'prop: addonBefore | description: addonBefore', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'addonAfter', display: 'block', title: { label: { type: 'i18n', zh_CN: '输入框后附加内容', en_US: 'Addon After', }, tip: { type: 'i18n', zh_CN: '属性: addonAfter | 说明: 输入框后附加内容', en_US: 'prop: addonAfter | description: addonAfter', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'addonTextBefore', display: 'block', title: { label: { type: 'i18n', zh_CN: '输入框前附加文字', en_US: 'Text Before', }, tip: { type: 'i18n', zh_CN: '属性: addonTextBefore | 说明: 输入框前附加文字', en_US: 'prop: addonTextBefore | description: addonTextBefore', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'addonTextAfter', display: 'block', title: { label: { type: 'i18n', zh_CN: '输入框后附加文字', en_US: 'Text After', }, tip: { type: 'i18n', zh_CN: '属性: addonTextAfter | 说明: 输入框后附加文字', en_US: 'prop: addonTextAfter | description: addonTextAfter', }, }, setter: 'StringSetter', supportVariable: true, }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', supportVariable: true, }, ], }, ], supports: { style: true, events: ['onPressEnter', 'onClear', 'onChange', 'onKeyDown', 'onFocus', 'onBlur'], }, }, icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/input/snippets.design.ts ================================================ export default [ { title: '输入框', screenshot: 'https://img.alicdn.com/tfs/TB1ysp3u8v0gK0jSZKbXXbK2FXa-112-64.png', schema: { componentName: 'Input', props: { hasBorder: true, size: 'medium', autoComplete: 'off', placeholder: '请输入', maxLength: 20, }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/input/snippets.ts ================================================ export default [ { title: '输入框', screenshot: 'https://img.alicdn.com/tfs/TB1ysp3u8v0gK0jSZKbXXbK2FXa-112-64.png', schema: { componentName: 'Input', props: { hasBorder: true, size: 'medium', autoComplete: 'off', placeholder: '请输入', }, }, }, { title: '密码框', screenshot: 'https://img.alicdn.com/tfs/TB1ikF3u7P2gK0jSZPxXXacQpXa-112-64.png', schema: { componentName: 'Input.Password', props: { hasBorder: true, size: 'medium', autoComplete: 'off', }, }, }, { title: 'TextArea', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_input.png', schema: { componentName: 'Input.TextArea', props: { hasBorder: true, size: 'medium', autoComplete: 'off', }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/input/view.tsx ================================================ import * as React from 'react'; import { Input } from '@alifd/next'; import { ValueWrapper } from 'lowcode/utils/component-wrapper'; export default ValueWrapper(Input, 'Input'); ================================================ FILE: packages/fusion-lowcode-materials/lowcode/input-group/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Input.Group', title: 'Input.Group', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Input', main: '', destructuring: true, subName: 'Group', }, props: [ { name: 'prefix', propType: 'string', description: '样式前缀', defaultValue: 'next-', }, { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, { name: 'children', propType: { type: 'instanceOf', value: 'node', }, }, { name: 'addonBefore', propType: { type: 'instanceOf', value: 'node', }, description: '输入框前附加内容', }, { name: 'addonBeforeClassName', propType: 'string', description: '输入框前附加内容css', }, { name: 'addonAfter', propType: { type: 'instanceOf', value: 'node', }, description: '输入框后附加内容', }, { name: 'addonAfterClassName', propType: 'string', description: '输入框后额外css', }, { name: 'rtl', propType: 'bool', description: 'rtl', }, ], category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/input-password/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Input.Password', title: '密码框', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Input', main: '', destructuring: true, subName: 'Password', }, props: [ { name: 'name', propType: 'string', }, { name: 'showToggle', propType: 'bool', description: '是否展示切换按钮', defaultValue: true, }, { name: 'label', propType: 'string', title: '标签文案', description: 'label', }, { name: 'hasClear', propType: 'bool', description: '是否出现清除按钮', }, { name: 'state', title: '状态', propType: { type: 'oneOf', value: ['error', 'loading', 'success', 'warning'], }, description: '状态\n@enumdesc 错误, 校验中, 成功, 警告', }, { name: 'size', title: '尺寸', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '尺寸\n@enumdesc 小, 中, 大', defaultValue: 'medium', }, { name: 'disabled', propType: 'bool', description: '是否禁用', }, { name: 'maxLength', propType: 'number', description: '最大长度', }, { name: 'hasLimitHint', propType: 'bool', description: '是否展现最大长度样式', }, { name: 'cutString', propType: 'bool', description: '是否截断超出字符串', }, { name: 'readOnly', propType: 'bool', description: '是否只读', }, { name: 'trim', propType: 'bool', description: 'onChange返回会自动去除头尾空字符', }, { name: 'placeholder', propType: 'string', description: '输入提示', }, { name: 'hasBorder', propType: 'bool', description: '是否有边框', }, { name: 'onPressEnter', propType: 'func', description: '按下回车的回调', }, { name: 'onClear', propType: 'func', }, { name: 'onChange', propType: 'func', }, { name: 'onKeyDown', propType: 'func', }, { name: 'onFocus', propType: 'func', }, { name: 'onBlur', propType: 'func', }, { name: 'hint', title: 'Icon 水印', propType: 'string', description: '水印 (Icon的type类型,和hasClear占用一个地方)', }, { name: 'innerBefore', propType: 'string', description: '文字前附加内容', }, { name: 'innerAfter', propType: 'string', description: '文字后附加内容', }, { name: 'addonBefore', propType: 'string', description: '输入框前附加内容', }, { name: 'addonAfter', propType: 'string', description: '输入框后附加内容', }, { name: 'addonTextBefore', propType: 'string', description: '输入框前附加文字', }, { name: 'addonTextAfter', propType: 'string', description: '输入框后附加文字', }, { name: 'autoFocus', propType: 'bool', description: '自动聚焦', }, { name: 'style', propType: 'object', }, ], configure: { props: [ { name: 'label', setter: 'StringSetter', supportVariable: true, title: { label: { type: 'i18n', zh_CN: '标签文本', en_US: 'Label', }, tip: { type: 'i18n', zh_CN: '属性: label | 说明: 标签文本内容', en_US: 'prop: label | description: label content', }, }, description: 'label', }, { name: 'maxLength', title: { label: { type: 'i18n', zh_CN: '最大长度', en_US: 'MaxLength', }, tip: { type: 'i18n', zh_CN: '属性: maxLength | 说明: 最大长度', en_US: 'prop: maxLength | description: max length', }, }, setter: 'NumberSetter', supportVariable: true, description: '最大长度', }, { name: 'placeholder', title: { label: { type: 'i18n', zh_CN: '输入提示', en_US: 'Placeholder', }, tip: { type: 'i18n', zh_CN: '属性: placeholder | 说明: 输入提示', en_US: 'prop: placeholder | description: placeholder', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'state', title: { label: { type: 'i18n', zh_CN: '状态', en_US: 'State', }, tip: { type: 'i18n', zh_CN: '属性: state | 说明: 状态\n@enumdesc 错误, 校验中, 成功, 警告', en_US: 'prop: state | description: input state', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['error', 'loading', 'success', 'warning'], }, }, }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 尺寸\n@enumdesc 小, 中, 大', en_US: 'prop: size | description: size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['small', 'medium', 'large'], }, }, defaultValue: 'medium', }, { name: 'showToggle', title: { label: { type: 'i18n', zh_CN: '显示切换', en_US: 'Show Togger', }, tip: { type: 'i18n', zh_CN: '属性: showToggle | 说明: 是否展示切换按钮', en_US: 'prop: showToggle | description: show togger icon', }, }, setter: 'BoolSetter', supportVariable: true, defaultValue: true, }, { name: 'hasClear', title: { label: { type: 'i18n', zh_CN: '显示清除', en_US: 'Show Clear', }, tip: { type: 'i18n', zh_CN: '属性: hasClear | 说明: 是否出现清除按钮', en_US: 'prop: hasClear | description: show clear icon', }, }, setter: 'BoolSetter', supportVariable: true, description: '是否出现清除按钮', }, { name: 'disabled', title: { label: { type: 'i18n', zh_CN: '是否禁用', en_US: 'Disabled', }, tip: { type: 'i18n', zh_CN: '属性: disabled | 说明: 是否被禁用', en_US: 'prop: disabled | description: disabled', }, }, setter: 'BoolSetter', supportVariable: true, description: '是否禁用', }, { name: 'hasLimitHint', title: { label: { type: 'i18n', zh_CN: '展示限制', en_US: 'ShowLimit', }, tip: { type: 'i18n', zh_CN: '属性: hasLimitHint | 说明: 是否展现最大长度样式', en_US: 'prop: hasLimitHint | description: hasLimitHint', }, }, setter: 'BoolSetter', supportVariable: true, description: '是否展现最大长度样式', }, { name: 'cutString', title: { label: { type: 'i18n', zh_CN: '是否截断', en_US: 'Cut Off', }, tip: { type: 'i18n', zh_CN: '属性: cutString | 说明: 是否截断超出字符串', en_US: 'prop: cutString | description: whether cut off string', }, }, setter: 'BoolSetter', supportVariable: true, description: '是否截断超出字符串', }, { name: 'readOnly', title: { label: { type: 'i18n', zh_CN: '是否只读', en_US: 'ReadOnly', }, tip: { type: 'i18n', zh_CN: '属性: readOnly | 说明: 是否只读', en_US: 'prop: readOnly | description: ReadOnly', }, }, setter: 'BoolSetter', supportVariable: true, description: '是否只读', }, { name: 'trim', title: { label: { type: 'i18n', zh_CN: '是否 Trim', en_US: 'Trim', }, tip: { type: 'i18n', zh_CN: '属性: trim | 说明: onChange返回会自动去除头尾空字符', en_US: 'prop: trim | description: whether trim when onChange called', }, }, setter: 'BoolSetter', supportVariable: true, }, { name: 'hasBorder', title: { label: { type: 'i18n', zh_CN: '显示边框', en_US: 'ShowBorder', }, tip: { type: 'i18n', zh_CN: '属性: hasBorder | 说明: 是否有边框', en_US: 'prop: hasBorder | description: HasBorder', }, }, setter: 'BoolSetter', supportVariable: true, }, { name: 'autoFocus', title: { label: { type: 'i18n', zh_CN: '自动聚焦', en_US: 'Auto Focus', }, tip: { type: 'i18n', zh_CN: '属性: autoFocus | 说明: 自动聚焦', en_US: 'prop: autoFocus | description: autoFocus', }, }, setter: 'BoolSetter', supportVariable: true, description: '自动聚焦', }, { name: 'hint', title: { label: { type: 'i18n', zh_CN: 'Icon 水印', en_US: 'IconHint', }, tip: { type: 'i18n', zh_CN: '属性: hint | 说明: Icon 水印', en_US: 'prop: hint | description: Icon hint', }, }, setter: { componentName: 'IconSetter', }, }, { name: 'innerBefore', display: 'block', title: { label: { type: 'i18n', zh_CN: '文字前附加内容', en_US: 'Inner Before', }, tip: { type: 'i18n', zh_CN: '属性: innerBefore | 说明: 文字前附加内容', en_US: 'prop: innerBefore | description: innerBefore', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'innerAfter', display: 'block', title: { label: { type: 'i18n', zh_CN: '文字后附加内容', en_US: 'Inner After', }, tip: { type: 'i18n', zh_CN: '属性: innerAfter | 说明: 文字后附加内容', en_US: 'prop: innerAfter | description: innerAfter', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'addonBefore', display: 'block', title: { label: { type: 'i18n', zh_CN: '输入框前附加内容', en_US: 'Addon Before', }, tip: { type: 'i18n', zh_CN: '属性: addonBefore | 说明: 输入框前附加内容', en_US: 'prop: addonBefore | description: addonBefore', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'addonAfter', display: 'block', title: { label: { type: 'i18n', zh_CN: '输入框后附加内容', en_US: 'Addon After', }, tip: { type: 'i18n', zh_CN: '属性: addonAfter | 说明: 输入框后附加内容', en_US: 'prop: addonAfter | description: addonAfter', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'addonTextBefore', display: 'block', title: { label: { type: 'i18n', zh_CN: '输入框前附加文字', en_US: 'Text Before', }, tip: { type: 'i18n', zh_CN: '属性: addonTextBefore | 说明: 输入框前附加文字', en_US: 'prop: addonTextBefore | description: addonTextBefore', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'addonTextAfter', display: 'block', title: { label: { type: 'i18n', zh_CN: '输入框后附加文字', en_US: 'Text After', }, tip: { type: 'i18n', zh_CN: '属性: addonTextAfter | 说明: 输入框后附加文字', en_US: 'prop: addonTextAfter | description: addonTextAfter', }, }, setter: 'StringSetter', supportVariable: true, }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', supportVariable: true, }, ], }, ], supports: { style: true, events: ['onPressEnter', 'onClear', 'onChange', 'onKeyDown', 'onFocus', 'onBlur'], }, }, category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/input-text-area/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Input.TextArea', title: '多行文本框', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Input', main: '', destructuring: true, subName: 'TextArea', }, props: [ { name: 'hasBorder', propType: 'bool', description: '是否有边框', defaultValue: true, }, { name: 'state', propType: { type: 'oneOf', value: ['error', 'warning'], }, description: '状态\n@enumdesc 错误', }, { name: 'autoHeight', propType: 'bool', description: '自动高度 true / {minRows: 2, maxRows: 4}', defaultValue: false, }, { name: 'rows', propType: 'number', description: '多行文本框高度
(不要直接用height设置多行文本框的高度, ie9 10会有兼容性问题)', defaultValue: 4, }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', defaultValue: false, }, { name: 'style', propType: 'object', }, { name: 'onClear', propType: 'func', }, { name: 'onChange', propType: 'func', }, { name: 'onKeyDown', propType: 'func', }, { name: 'onFocus', propType: 'func', }, { name: 'onBlur', propType: 'func', }, ], configure: { props: [ { name: 'rows', title: { label: { type: 'i18n', zh_CN: '行数', en_US: 'Rows', }, tip: { type: 'i18n', zh_CN: '属性: rows | 说明: 多行文本框高度
(不要直接用height设置多行文本框的高度, ie9 10会有兼容性问题)', en_US: 'prop: rows | description: row numbers', }, }, setter: 'NumberSetter', supportVariable: true, defaultValue: 4, }, { name: 'maxLength', title: { label: { type: 'i18n', zh_CN: '最大长度', en_US: 'MaxLength', }, tip: { type: 'i18n', zh_CN: '属性: maxLength | 说明: 最大长度', en_US: 'prop: maxLength | description: max length', }, }, setter: 'NumberSetter', supportVariable: true, description: '最大长度', }, { name: 'placeholder', title: { label: { type: 'i18n', zh_CN: '输入提示', en_US: 'Placeholder', }, tip: { type: 'i18n', zh_CN: '属性: placeholder | 说明: 输入提示', en_US: 'prop: placeholder | description: placeholder', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'state', title: { label: { type: 'i18n', zh_CN: '状态', en_US: 'State', }, tip: { type: 'i18n', zh_CN: '属性: state | 说明: 状态\n@enumdesc 错误', en_US: 'prop: state | description: input state', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['error', 'warning'], }, }, }, { name: 'autoHeight', title: { label: { type: 'i18n', zh_CN: '自动高度', en_US: 'Auto Height', }, tip: { type: 'i18n', zh_CN: '属性: autoHeight | 说明: 自动高度 true / {minRows: 2, maxRows: 4}', en_US: 'prop: autoHeight | description: auto height', }, }, setter: 'BoolSetter', supportVariable: true, defaultValue: false, }, { name: 'isPreview', title: { label: { type: 'i18n', zh_CN: '预览态', en_US: 'Preview', }, tip: { type: 'i18n', zh_CN: '属性: isPreview | 说明: 是否为预览态', en_US: 'prop: isPreview | description: preview', }, }, setter: 'BoolSetter', supportVariable: true, defaultValue: false, }, { name: 'disabled', title: { label: { type: 'i18n', zh_CN: '是否禁用', en_US: 'Disabled', }, tip: { type: 'i18n', zh_CN: '属性: disabled | 说明: 是否被禁用', en_US: 'prop: disabled | description: disabled', }, }, setter: 'BoolSetter', supportVariable: true, description: '是否禁用', }, { name: 'hasLimitHint', title: { label: { type: 'i18n', zh_CN: '展示限制', en_US: 'ShowLimit', }, tip: { type: 'i18n', zh_CN: '属性: hasLimitHint | 说明: 是否展现最大长度样式', en_US: 'prop: hasLimitHint | description: hasLimitHint', }, }, setter: 'BoolSetter', supportVariable: true, description: '是否展现最大长度样式', }, { name: 'cutString', title: { label: { type: 'i18n', zh_CN: '是否截断', en_US: 'Cut Off', }, tip: { type: 'i18n', zh_CN: '属性: cutString | 说明: 是否截断超出字符串', en_US: 'prop: cutString | description: whether cut off string', }, }, setter: 'BoolSetter', supportVariable: true, description: '是否截断超出字符串', }, { name: 'readOnly', title: { label: { type: 'i18n', zh_CN: '是否只读', en_US: 'ReadOnly', }, tip: { type: 'i18n', zh_CN: '属性: readOnly | 说明: 是否只读', en_US: 'prop: readOnly | description: ReadOnly', }, }, setter: 'BoolSetter', supportVariable: true, description: '是否只读', }, { name: 'trim', title: { label: { type: 'i18n', zh_CN: '是否 Trim', en_US: 'Trim', }, tip: { type: 'i18n', zh_CN: '属性: trim | 说明: onChange返回会自动去除头尾空字符', en_US: 'prop: trim | description: whether trim when onChange called', }, }, setter: 'BoolSetter', supportVariable: true, }, { name: 'hasBorder', title: { label: { type: 'i18n', zh_CN: '显示边框', en_US: 'ShowBorder', }, tip: { type: 'i18n', zh_CN: '属性: hasBorder | 说明: 是否有边框', en_US: 'prop: hasBorder | description: HasBorder', }, }, setter: 'BoolSetter', supportVariable: true, }, { name: 'autoFocus', title: { label: { type: 'i18n', zh_CN: '自动聚焦', en_US: 'Auto Focus', }, tip: { type: 'i18n', zh_CN: '属性: autoFocus | 说明: 自动聚焦', en_US: 'prop: autoFocus | description: autoFocus', }, }, setter: 'BoolSetter', supportVariable: true, description: '自动聚焦', }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', supportVariable: true, }, ], }, ], supports: { style: true, events: ['onPressEnter', 'onClear', 'onChange', 'onKeyDown', 'onFocus', 'onBlur'], }, }, category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/link/meta.design.ts ================================================ export default { group: '原子组件', componentName: 'Link', title: '链接', npm: { package: '@alilc/lowcode-materials', version: 'latest', exportName: 'Link', main: '', destructuring: true, subName: '', }, props: [ { name: 'href', title: { label: { type: 'i18n', zh_CN: '超链接', en_US: 'Link', }, tip: { type: 'i18n', zh_CN: '属性:href | 说明:超链接地址', en_US: 'prop: href | description: link address', }, }, propType: 'string', defaultValue: 'https://fusion.design', }, { name: 'children', title: { label: { type: 'i18n', zh_CN: '链接文案', en_US: 'Text', }, tip: { type: 'i18n', zh_CN: '属性:children | 说明:超链接文案', en_US: 'prop: children | description: text of the link', }, }, propType: { type: 'oneOfType', value: ['string', 'node'], }, defaultValue: '这是一个超链接', }, { name: 'style', propType: 'object', }, { name: 'target', title: { label: { type: 'i18n', zh_CN: '页面目标', en_US: 'Target', }, tip: { type: 'i18n', zh_CN: '属性:target | 说明:跳转页面目标', en_US: 'prop: target | description: target of new page', }, }, propType: { type: 'oneOf', value: ['_blank', '_self'], }, }, ], configure: { supports: { style: true, events: ['onClick'], }, component: { isContainer: true, }, props: [ { name: 'children', title: { label: { type: 'i18n', zh_CN: '链接文案', en_US: 'Text', }, tip: { type: 'i18n', zh_CN: '属性:children | 说明:超链接文案', en_US: 'prop: children | description: text of the link', }, }, setter: 'StringSetter', defaultValue: '这是一个超链接', }, { name: '!configType', title: '配置方式', defaultValue: 'link', condition: () => { return AliLowCodeEngine.setters.getSetter('BehaviorSetter'); }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '交互配置', value: 'behavior', }, { label: '链接配置', value: 'link', }, ], }, }, }, { name: 'behavior', title: '交互设置', display: 'block', condition: (target) => { const configType = target.parent.getPropValue('!configType'); console.log('configType: ', configType); return configType === 'behavior' && AliLowCodeEngine.setters.getSetter('BehaviorSetter'); }, setter: { componentName: 'BehaviorSetter', props: () => { return { actions: ['onClick'], type: 'link', }; }, }, }, { name: 'target', title: { label: { type: 'i18n', zh_CN: '页面目标', en_US: 'Target', }, tip: { type: 'i18n', zh_CN: '属性:target | 说明:跳转页面目标', en_US: 'prop: target | description: target of new page', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { value: '_self', title: '当前页面', }, { value: '_blank', title: '新开页面', }, ], }, }, condition: (target) => { const configType = target.parent.getPropValue('!configType'); return !configType || configType === 'link'; }, }, { name: 'href', title: { label: { type: 'i18n', zh_CN: '跳转链接', en_US: 'Link', }, tip: { type: 'i18n', zh_CN: '属性:href | 说明:超链接地址', en_US: 'prop: href | description: link address', }, }, setter: 'StringSetter', condition: (target) => { const configType = target.parent.getPropValue('!configType'); return !configType || configType === 'link'; }, }, ], }, icon: 'https://img.alicdn.com/imgextra/i4/O1CN01aGiT9s1ScmzUSmn4s_!!6000000002268-55-tps-56-56.svg', category: '通用', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/link/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Link', title: '链接', npm: { package: '@alilc/lowcode-materials', version: 'latest', exportName: 'Link', main: '', destructuring: true, subName: '', }, props: [ { name: 'href', title: { label: { type: 'i18n', zh_CN: '超链接', en_US: 'Link', }, tip: { type: 'i18n', zh_CN: '属性:href | 说明:超链接地址', en_US: 'prop: href | description: link address', }, }, propType: 'string', defaultValue: 'https://fusion.design', }, { name: 'children', title: { label: { type: 'i18n', zh_CN: '链接文案', en_US: 'Text', }, tip: { type: 'i18n', zh_CN: '属性:children | 说明:超链接文案', en_US: 'prop: children | description: text of the link', }, }, propType: { type: 'oneOfType', value: ['string', 'node'], }, defaultValue: '这是一个超链接', }, { name: 'style', propType: 'object', }, { name: 'target', title: { label: { type: 'i18n', zh_CN: '页面目标', en_US: 'Target', }, tip: { type: 'i18n', zh_CN: '属性:target | 说明:跳转页面目标', en_US: 'prop: target | description: target of new page', }, }, propType: { type: 'oneOf', value: ['_blank', '_self'], }, }, ], configure: { supports: { style: true, events: ['onClick'], }, component: { isContainer: true, }, props: [ { name: 'children', title: { label: { type: 'i18n', zh_CN: '链接文案', en_US: 'Text', }, tip: { type: 'i18n', zh_CN: '属性:children | 说明:超链接文案', en_US: 'prop: children | description: text of the link', }, }, setter: 'StringSetter', supportVariable: true, defaultValue: '这是一个超链接', }, { name: '!configType', title: '配置方式', defaultValue: 'link', condition: () => { return AliLowCodeEngine.setters.getSetter('BehaviorSetter'); }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '交互配置', value: 'behavior', }, { label: '链接配置', value: 'link', }, ], }, }, }, { name: 'behavior', title: '交互设置', display: 'block', condition: (target) => { const configType = target.parent.getPropValue('!configType'); console.log('configType: ', configType); return configType === 'behavior' && AliLowCodeEngine.setters.getSetter('BehaviorSetter'); }, setter: { componentName: 'BehaviorSetter', props: (target) => { return { actions: ['onClick'], type: 'link', }; }, }, }, { name: 'target', condition: () => false, title: { label: { type: 'i18n', zh_CN: '页面目标', en_US: 'Target', }, tip: { type: 'i18n', zh_CN: '属性:target | 说明:跳转页面目标', en_US: 'prop: target | description: target of new page', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { value: '_self', title: '当前页面', }, { value: '_blank', title: '新开页面', }, ], }, }, condition: (target) => { const configType = target.parent.getPropValue('!configType'); return !configType || configType === 'link'; }, }, { name: 'href', title: { label: { type: 'i18n', zh_CN: '跳转链接', en_US: 'Link', }, tip: { type: 'i18n', zh_CN: '属性:href | 说明:超链接地址', en_US: 'prop: href | description: link address', }, }, setter: 'StringSetter', condition: (target) => { const configType = target.parent.getPropValue('!configType'); return !configType || configType === 'link'; }, supportVariable: true, }, ], }, icon: 'https://img.alicdn.com/imgextra/i4/O1CN01aGiT9s1ScmzUSmn4s_!!6000000002268-55-tps-56-56.svg', category: '通用', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/link/snippets.ts ================================================ module.exports = [ { title: '链接', screenshot: 'https://img.alicdn.com/imgextra/i4/O1CN01aGiT9s1ScmzUSmn4s_!!6000000002268-55-tps-56-56.svg', schema: { componentName: 'Link', title: '链接', props: { href: 'https://fusion.design', target: '_blank', children: '这是一个超链接', }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/list/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'List', title: '列表', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'List', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'style', propType: 'object', }, { name: 'header', propType: { type: 'oneOfType', value: ['string', 'node'], }, }, { name: 'size', propType: { type: 'oneOf', value: ['small', 'medium'], }, }, { name: 'footer', propType: { type: 'oneOfType', value: ['string', 'node'], }, }, { name: 'divider', propType: { type: 'oneOfType', value: ['string', 'node'], }, }, ], configure: { component: { isContainer: true, }, }, icon: '', category: '信息输入', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/list-item/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'List.Item', title: '列表项', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'List', main: '', destructuring: true, subName: 'Item', }, props: [ { name: 'style', propType: 'object', }, { name: 'title', propType: { type: 'oneOfType', value: ['string', 'node'], }, }, { name: 'description', propType: { type: 'oneOfType', value: ['string', 'node'], }, }, { name: 'media', propType: { type: 'oneOfType', value: ['string', 'node'], }, }, { name: 'extra', propType: { type: 'oneOfType', value: ['string', 'node'], }, }, ], icon: '', category: '信息输入', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/loading/meta.design.ts ================================================ import snippets from './snippets'; export default { group: '原子组件', componentName: 'Loading', title: '加载', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Loading', main: '', destructuring: true, subName: '', }, props: [ { name: 'tip', propType: 'string', description: '自定义内容', }, { name: 'tipAlign', propType: { type: 'oneOf', value: ['right', 'bottom'], }, description: '自定义内容位置', defaultValue: 'bottom', }, { name: 'visible', propType: 'bool', description: 'loading 状态, 默认 true', defaultValue: true, }, { name: 'onVisibleChange', propType: 'func', }, { name: 'className', propType: 'string', description: '自定义class', }, { name: 'style', propType: 'object', description: '自定义内联样式', }, { name: 'size', propType: { type: 'oneOf', value: ['large', 'medium'], }, description: '设置动画尺寸\n@description 仅仅对默认动画效果起作用\n@enumdesc 大号, 中号', defaultValue: 'large', }, { name: 'color', propType: 'string', description: '动画颜色', }, { name: 'fullScreen', propType: 'bool', description: '全屏展示', }, { name: 'inline', title: 'inline', propType: 'bool', description: 'should loader be displayed inline', defaultValue: true, }, ], configure: { component: { isContainer: true, }, props: [ { name: 'tip', title: { label: '自定义内容', tip: '', }, setter: 'StringSetter', }, { name: 'tipAlign', title: { label: '内容位置', tip: '自定义内容位置', }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '动画右边', value: 'right', }, { title: '动画下面', value: 'bottom', }, ], }, }, }, { name: 'size', title: { label: '动画尺寸', }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '大', value: 'large', }, { title: '中', value: 'medium', }, ], }, }, }, { name: 'color', title: '动画颜色', setter: { componentName: 'ColorSetter', }, }, { name: 'visible', title: { label: '是否显示', }, setter: 'BoolSetter', }, { name: 'fullScreen', title: '全屏显示', setter: 'BoolSetter', }, { name: 'inline', title: '行内显示', setter: 'BoolSetter', }, ], supports: { style: true, events: ['onVisibleChange'], }, }, icon: '', category: '信息反馈', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/loading/meta.ts ================================================ import snippets from './snippets'; export default { group: '原子组件', componentName: 'Loading', title: '加载', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Loading', main: '', destructuring: true, subName: '', }, props: [ { name: 'tip', propType: 'string', description: '自定义内容', }, { name: 'tipAlign', propType: { type: 'oneOf', value: ['right', 'bottom'], }, description: '自定义内容位置', defaultValue: 'bottom', }, { name: 'visible', propType: 'bool', description: 'loading 状态, 默认 true', defaultValue: true, }, { name: 'onVisibleChange', propType: 'func', }, { name: 'className', propType: 'string', description: '自定义class', }, { name: 'style', propType: 'object', description: '自定义内联样式', }, { name: 'size', propType: { type: 'oneOf', value: ['large', 'medium'], }, description: '设置动画尺寸\n@description 仅仅对默认动画效果起作用\n@enumdesc 大号, 中号', defaultValue: 'large', }, { name: 'color', propType: 'string', description: '动画颜色', }, { name: 'fullScreen', propType: 'bool', description: '全屏展示', }, { name: 'inline', title: 'inline', propType: 'bool', description: 'should loader be displayed inline', defaultValue: true, }, ], configure: { component: { isContainer: true, }, props: [ { name: 'tip', title: { label: '自定义内容', tip: '', }, setter: { componentName: 'MixedSetter', props: { setters: ['StringSetter', 'ExpressionSetter'], }, }, }, { name: 'tipAlign', title: { label: '内容位置', tip: '自定义内容位置', }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '动画右边', value: 'right', }, { title: '动画下面', value: 'bottom', }, ], }, }, }, { name: 'visible', title: { label: '是否显示', }, setter: { componentName: 'MixedSetter', props: { setters: ['BoolSetter', 'ExpressionSetter'], }, }, }, { name: 'size', title: { label: '动画尺寸', }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: 'large', value: 'large', }, { title: 'medium', value: 'medium', }, ], }, }, }, { name: 'color', title: '动画颜色', setter: { componentName: 'ColorSetter', }, }, { name: 'fullScreen', title: '全屏显示', setter: 'BoolSetter', supportVariable: true, }, { name: 'inline', title: '行内显示', setter: 'BoolSetter', supportVariable: true, }, ], supports: { style: true, events: ['onVisibleChange'], }, }, icon: '', category: '信息反馈', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/loading/snippets.ts ================================================ export default [ { title: '加载', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_loading.png', schema: { componentName: 'Loading', props: { color: 'red', prefix: 'next-', tipAlign: 'bottom', visible: true, size: 'large', inline: true, }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/menu/adaptor.ts ================================================ import parseData from '../utils/parse-data'; export const createDataSource = ( list, keys = { selected: [], expanded: {} }, level = 0, prefix = '', ) => { const array = []; let group = []; let grouping = false; let index = 0; list.forEach((item) => { switch (item.type) { // eslint-disable-next-line no-case-declarations case 'node': const key = `${prefix || level}-${index++}`; if (item.children && item.children.length > 0) { item.children = createDataSource(item.children, keys, level + 1, key); } if (grouping) { group.push({ ...item, key, }); } else { array.push({ ...item, key, }); } if (item.state === 'active') { if (item.children && item.children.length > 0) { keys.expanded.push(key); } else { keys.selected.push(key); } } return; case 'comment': if (group.length > 0) { array.push({ type: 'group', value: grouping, children: group, key: `${prefix || level}-${index++}`, }); group = []; } grouping = item.value; return; case 'divider': if (group.length > 0) { array.push({ type: 'group', value: grouping, children: group, key: `${prefix || level}-${index++}`, }); group = []; } grouping = false; array.push({ type: 'divider', key: `${prefix || level}-${index++}`, }); return; default: return; } }); if (group.length > 0) { array.push({ type: 'group', value: grouping, children: group, key: `${prefix || level}-${index++}`, }); group = []; } return array; }; const createMenuItem = (item) => { if (item.children.length > 0) { // return ( // type === ContentType.text).map(({ value }) => value).join('') : ''}> // {createContents(item.children)} // // ); return { componentName: 'SubMenu', props: { key: item.key, disabled: item.state === 'disabled', label: item.value ? item.value .filter(({ type }) => type === 'text') .map(({ value }) => value) .join('') : '', }, children: createContents(item.children), }; } // return type === 'icon' ? : value)} />; return { componentName: 'Menu.Item', props: { key: item.key, checked: item.state === 'active', disabled: item.state === 'disabled', onItemClick: () => { console.log('menu item clicked'); }, }, children: item.value.map(({ type, value }, index) => type === 'icon' ? { componentName: 'Icon', props: { key: `icon_${index}`, type: value, size: 'small', style: { marginRight: '4px' }, }, } : value, ), }; }; export const createContents = (array = []) => { return array.map((item) => { if (item.type === 'group' && item.children.length > 0) { // return {item.children.map(it => createMenuItem(it))}; return { componentName: 'Menu.Group', props: { key: item.key, label: item.value, }, children: item.children.map((it) => createMenuItem(it)), }; } if (item.type === 'divider') { // return ; return { componentName: 'Menu.Divider', props: { key: item.key, }, }; } return createMenuItem(item); }); }; export function getDataFromPlainText(value) { const keys = { selected: [], expanded: [] }; const list = parseData(value, { parseContent: true }); const dataSource = createDataSource(list, keys); const children = createContents(dataSource); return { children, selectedKeys: keys.selected }; } // const _propsValue = ({ shape, level, size, data, ...others}) =>{ // const list = parseData(data, { parseContent: true }); // const buttonItem = list[0] ? list[0] : { value: []}; // const keys = { selected: [], expanded: [] }; // if (buttonItem.type !== 'node') return null; // const label = buttonItem.value.map(({ type, value}) => { // if (type === 'icon') return ; // return value; // }); // return { // ...others, // size, // disabled: buttonItem.state === 'disabled', // visible: buttonItem.state === 'active', // type: shape === 'ghost' ? 'normal' : level, // popupProps: { needAdjust: false, container: node => node }, // ghost: shape === 'ghost' ? level : false, // selectMode: "multiple", // menuProps: { openKeys: keys.expanded, style: { textAlign: 'left' } }, // selectedKeys: keys.selected, // label: label // }; // }; // export default { // name: 'SplitButton', // shape: ['normal', 'ghost'], // editor: (shape = 'normal') => ({ // props: [{ // name: 'level', // type: Types.enum, // options: shape === 'ghost' ? ['light', 'dark'] : ['normal', 'primary', 'secondary'], // default: shape === 'ghost' ? 'light' : 'normal', // }, { // name: 'size', // type: Types.enum, // options: ['large', 'medium', 'small'], // default: 'medium' // }], // data: { // icon: true, // active: true, // disable: true, // default: 'Edit Document\n\tUndo\n\t*Redo\n\tCut\n\tCopy\n\tPaste' // } // }), // propsValue: _propsValue, // adaptor: (args) => { // const list = parseData(args.data, { parseContent: true }); // const keys = { selected: [], expanded: [] }; // const dataSouce = createDataSource(list[0] ? list[0].children : [], keys); // const props = _propsValue(args); // return ( // // {createContents(dataSouce)} // // ); // }, // demoOptions: (demo) => { // const { node = { props: {} } } = demo; // const { level, data } = node.props; // if (data.indexOf('*') === 0) { // demo = { // ...demo, // height: 250 // }; // } // if (level === 'dark') { // demo = { // ...demo, // background: '#333' // }; // } else if(level === 'light') { // demo = { // ...demo, // background: 'rgb(235, 236, 240)', // }; // } // return demo; // } // }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/menu/meta.design.ts ================================================ import snippets from './snippets.design'; import { getDataFromPlainText } from './adaptor'; export default { group: '原子组件', componentName: 'Menu', title: '菜单', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Menu', main: '', destructuring: true, subName: '', }, props: [ { name: 'dataSource', propType: 'array', description: '使用数据模型构建', }, { name: 'defaultExpandedKeys', propType: { type: 'arrayOf', value: 'string', }, description: '默认展开keys', }, { name: 'expandedKeys', propType: { type: 'arrayOf', value: 'string', }, description: '受控展开keys', }, { name: 'onExpand', propType: 'func', description: '展开状态发升变化时候的回调', }, { name: 'disabled', propType: 'bool', description: '所有禁用', }, { name: 'className', propType: 'string', description: '扩展class', }, { name: 'style', propType: 'object', description: '组件接受行内样式', }, { name: 'accordion', propType: 'bool', description: '手风琴模式,一次只能打开一个', defaultValue: false, }, { name: 'rtl', propType: 'bool', }, ], configure: { component: { isContainer: true, }, props: [ { name: '!mode', title: '模式', setValue: (target, value) => { const parentTarget = target.parent; switch (value) { case 'single': parentTarget.setPropValue('selectMode', 'single'); break; case 'multiple': parentTarget.setPropValue('selectMode', 'multiple'); break; case 'arrowLeft': parentTarget.setPropValue('isSelectIconRight', false); break; case 'arrowRight': parentTarget.setPropValue('isSelectIconRight', true); break; default: break; } }, setter: { componentName: 'SelectSetter', props: { options: [ { title: '单选框', value: 'single', }, { title: '复选框', value: 'multiple', }, { title: '箭头在左', value: 'arrowLeft', }, { title: '箭头在右', value: 'arrowRight', }, ], }, }, defaultValue: 'single', }, { name: 'mode', setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '内联', value: 'inline', }, { label: '弹出', value: 'popup', }, ], }, }, title: '子菜单模式', defaultValue: 'inline', }, { name: 'style.width', title: '宽度', setter: 'NumberSetter', }, { name: 'plainData', display: 'block', title: '内容', tip: { title: '数据格式', url: '', }, setValue: (target, value) => { const { children, selectedKeys } = getDataFromPlainText(value); if (children) { target.node.children.importSchema(children); } if (selectedKeys) { target.parent.setPropValue('selectedKeys', selectedKeys); } }, setter: { componentName: 'MagicEditorSetter', props: { toolbar: ['normal', 'active', 'disable'], disableIcon: true, }, }, }, ], }, icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/menu/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Menu', title: '菜单', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Menu', main: '', destructuring: true, subName: '', }, props: [ { name: 'onItemClick', propType: 'func', description: '点击菜单项触发的回调函数\n@param {String} key 点击的菜单项的 key 值\n@param {Object} item 点击的菜单项对象\n@param {Object} event 点击的事件对象', }, { name: 'defaultOpenAll', propType: 'bool', description: "初始展开所有的子菜单,只在 mode 设置为 'inline' 以及 openMode 设置为 'multiple' 下生效,优先级高于 defaultOpenKeys", defaultValue: false, }, { name: 'onOpen', propType: 'func', description: '打开或关闭子菜单触发的回调函数\n@param {String} key 打开的所有子菜单的 key 值\n@param {Object} extra 额外参数\n@param {String} extra.key 当前操作子菜单的 key 值\n@param {Boolean} extra.open 是否是打开', }, { name: 'mode', propType: { type: 'oneOf', value: ['inline', 'popup'], }, description: '子菜单打开的模式', defaultValue: 'inline', }, { name: 'triggerType', propType: { type: 'oneOf', value: ['click', 'hover'], }, description: '子菜单打开的触发行为', defaultValue: 'click', }, { name: 'openMode', propType: { type: 'oneOf', value: ['single', 'multiple'], }, description: '展开内连子菜单的模式,同时可以展开一个子菜单还是多个子菜单,该属性仅在 mode 为 inline 时生效', defaultValue: 'multiple', }, { name: 'inlineIndent', propType: 'number', description: '内连子菜单缩进距离', defaultValue: 20, }, { name: 'inlineArrowDirection', propType: { type: 'oneOf', value: ['down', 'right'], }, defaultValue: 'down', }, { name: 'popupAutoWidth', propType: 'bool', description: '是否自动让弹层的宽度和菜单项保持一致,如果弹层的宽度比菜单项小则和菜单项保持一致,如果宽度大于菜单项则不做处理', defaultValue: false, }, { name: 'popupAlign', propType: { type: 'oneOf', value: ['follow', 'outside'], }, description: '弹层的对齐方式', defaultValue: 'follow', }, { name: 'popupClassName', propType: 'string', description: '弹出子菜单自定义 className', }, { name: 'onSelect', propType: 'func', description: '选中或取消选中菜单项触发的回调函数\n@param {Array} selectedKeys 选中的所有菜单项的值\n@param {Object} item 选中或取消选中的菜单项\n@param {Object} extra 额外参数\n@param {Boolean} extra.select 是否是选中\n@param {Array} extra.key 菜单项的 key\n@param {Object} extra.label 菜单项的文本\n@param {Array} extra.keyPath 菜单项 key 的路径', }, { name: 'selectMode', propType: { type: 'oneOf', value: ['single', 'multiple'], }, description: '选中模式,单选还是多选,默认无值,不可选', }, { name: 'shallowSelect', propType: 'bool', description: '是否只能选择第一层菜单项(不能选择子菜单中的菜单项)', defaultValue: false, }, { name: 'hasSelectedIcon', propType: 'bool', description: '是否显示选中图标,如果设置为 false 需配合配置平台设置选中时的背景色以示区分', defaultValue: true, }, { name: 'labelToggleChecked', propType: 'bool', defaultValue: true, }, { name: 'isSelectIconRight', propType: 'bool', description: '是否将选中图标居右,仅当 hasSelectedIcon 为true 时生效。\n注意:SubMenu 上的选中图标一直居左,不受此API控制', defaultValue: false, }, { name: 'direction', propType: { type: 'oneOf', value: ['ver', 'hoz'], }, description: '菜单第一层展示方向', defaultValue: 'ver', }, { name: 'hozAlign', propType: { type: 'oneOf', value: ['left', 'right'], }, description: "横向菜单条 item 和 footer 的对齐方向,在 direction 设置为 'hoz' 并且 header 存在时生效", defaultValue: 'left', }, { name: 'hozInLine', propType: 'bool', description: "横向菜单模式下,是否维持在一行,即超出一行折叠成 SubMenu 显示, 仅在 direction='hoz' mode='popup' 时生效", defaultValue: false, }, { name: 'header', propType: 'node', description: '自定义菜单头部', }, { name: 'footer', propType: 'node', description: '自定义菜单尾部', }, { name: 'autoFocus', propType: 'bool', description: '是否自动获得焦点', defaultValue: false, }, { name: 'focusedKey', propType: 'string', description: '当前获得焦点的子菜单或菜单项 key 值', }, { name: 'focusable', propType: 'bool', defaultValue: true, }, { name: 'onItemFocus', propType: 'func', }, { name: 'onBlur', propType: 'func', }, { name: 'embeddable', propType: 'bool', description: "是否开启嵌入式模式,一般用于Layout的布局中,开启后没有默认背景、外层border、box-shadow,可以配合`` 自定义高度", defaultValue: false, }, { name: 'onItemKeyDown', propType: 'func', }, { name: 'expandAnimation', propType: 'bool', defaultValue: true, }, { name: 'itemClassName', propType: 'string', }, { name: 'style', propType: 'object', }, { name: 'openKeys', propType: { type: 'oneOfType', value: [ 'string', { type: 'arrayOf', value: 'string', }, ], }, description: '当前打开的子菜单的 key 值', }, { name: 'defaultOpenKeys', propType: { type: 'oneOfType', value: [ 'string', { type: 'arrayOf', value: 'string', }, ], }, description: '初始打开的子菜单的 key 值', defaultValue: [], }, { name: 'selectedKeys', propType: { type: 'oneOfType', value: [ 'string', { type: 'arrayOf', value: 'string', }, ], }, description: '当前选中菜单项的 key 值', }, { name: 'defaultSelectedKeys', propType: { type: 'oneOfType', value: [ 'string', { type: 'arrayOf', value: 'string', }, ], }, description: '初始选中菜单项的 key 值', defaultValue: [], }, ], configure: { component: { isContainer: true, }, }, icon: '', category: '信息输入', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/menu/snippets.design.ts ================================================ import { getDataFromPlainText } from './adaptor'; const plainData = '#Group1\noption1\n*option2\n\tsub option3\n\t-sub option4\n\tsub option5\n---\n#Group2\noption1\n*option2'; const { children, selectedKeys } = getDataFromPlainText(plainData); const menuProps = { plainData, }; if (selectedKeys && selectedKeys.length) { menuProps.selectedKeys = selectedKeys; } export default [ { title: '菜单', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_dialog.png', schema: { componentName: 'Menu', props: { ...menuProps, }, children, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/menu-button/adaptor.ts ================================================ import parseData from '../utils/parse-data'; export const createDataSource = ( list, keys = { selected: [], expanded: {} }, level = 0, prefix = '', ) => { const array = []; let group = []; let grouping = false; let index = 0; list.forEach((item) => { switch (item.type) { // eslint-disable-next-line no-case-declarations case 'node': const key = `${prefix || level}-${index++}`; if (item.children && item.children.length > 0) { item.children = createDataSource(item.children, keys, level + 1, key); } if (grouping) { group.push({ ...item, key, }); } else { array.push({ ...item, key, }); } if (item.state === 'active') { if (item.children && item.children.length > 0) { keys.expanded.push(key); } else { keys.selected.push(key); } } return; case 'comment': if (group.length > 0) { array.push({ type: 'group', value: grouping, children: group, key: `${prefix || level}-${index++}`, }); group = []; } grouping = item.value; return; case 'divider': if (group.length > 0) { array.push({ type: 'group', value: grouping, children: group, key: `${prefix || level}-${index++}`, }); group = []; } grouping = false; array.push({ type: 'divider', key: `${prefix || level}-${index++}`, }); default: } }); if (group.length > 0) { array.push({ type: 'group', value: grouping, children: group, key: `${prefix || level}-${index++}`, }); group = []; } return array; }; const createMenuItem = (item) => { if (item.children.length > 0) { // return ( // type === ContentType.text).map(({ value }) => value).join('') : ''}> // {createContents(item.children)} // // ); return { componentName: 'SubMenu', props: { key: item.key, disabled: item.state === 'disabled', label: item.value ? item.value .filter(({ type }) => type === 'text') .map(({ value }) => value) .join('') : '', }, children: createContents(item.children), }; } // return type === 'icon' ? : value)} />; return { componentName: 'Menu.Item', props: { key: item.key, checked: item.state === 'active', disabled: item.state === 'disabled', }, children: item.value.map(({ type, value }, index) => type === 'icon' ? { componentName: 'Icon', props: { disabled: true, key: `icon_${index}`, type: value, size: 'small', style: { marginRight: '4px' }, }, } : { componentName: 'Typography.Text', props: { children: value, style: { color: 'inherit', }, }, }, ), }; }; export const createContents = (array = []) => { return array.map((item) => { if (item.type === 'group' && item.children.length > 0) { // return {item.children.map(it => createMenuItem(it))}; return { componentName: 'Menu.Group', props: { key: item.key, label: item.value, }, children: item.children.map((it) => createMenuItem(it)), }; } if (item.type === 'divider') { // return ; return { componentName: 'Menu.Divider', props: { key: item.key, }, }; } return createMenuItem(item); }); }; function getButtonLabel(buttonItem) { if (buttonItem.type !== 'node') return {}; // return buttonItem.value.find(item => item.type === 'text').value; // FIXME: 渲染时 JSSlot 有问题,暂时不要 icon return { label: { type: 'JSSlot', value: buttonItem.value.map(({ type, value }) => { if (type === 'icon') return { componentName: 'Icon', props: { disabled: true, type: value, size: 'small', style: { marginRight: '4px' }, }, }; return { componentName: 'Typography.Text', props: { children: value, style: { color: 'inherit', }, }, }; }), }, disabled: buttonItem?.state === 'disabled', }; } export function getDataFromPlainText(value) { const keys = { selected: [], expanded: [] }; const list = parseData(value, { parseContent: true }); const buttonItem = list[0] ? list[0] : { value: [] }; const { label, disabled } = getButtonLabel(buttonItem); const dataSource = createDataSource(list[0] ? list[0].children : [], keys); const children = createContents(dataSource); return { label, disabled, children, selectedKeys: keys.selected }; } // const _propsValue = ({ shape, level, size, data, ...others}) =>{ // const list = parseData(data, { parseContent: true }); // const buttonItem = list[0] ? list[0] : { value: []}; // const keys = { selected: [], expanded: [] }; // if (buttonItem.type !== 'node') return null; // const label = buttonItem.value.map(({ type, value}) => { // if (type === 'icon') return ; // return value; // }); // return { // ...others, // size, // disabled: buttonItem.state === 'disabled', // visible: buttonItem.state === 'active', // type: shape === 'ghost' ? 'normal' : level, // popupProps: { needAdjust: false, container: node => node }, // ghost: shape === 'ghost' ? level : false, // selectMode: "multiple", // menuProps: { openKeys: keys.expanded, style: { textAlign: 'left' } }, // selectedKeys: keys.selected, // label: label // }; // }; // export default { // name: 'SplitButton', // shape: ['normal', 'ghost'], // editor: (shape = 'normal') => ({ // props: [{ // name: 'level', // type: Types.enum, // options: shape === 'ghost' ? ['light', 'dark'] : ['normal', 'primary', 'secondary'], // default: shape === 'ghost' ? 'light' : 'normal', // }, { // name: 'size', // type: Types.enum, // options: ['large', 'medium', 'small'], // default: 'medium' // }], // data: { // icon: true, // active: true, // disable: true, // default: 'Edit Document\n\tUndo\n\t*Redo\n\tCut\n\tCopy\n\tPaste' // } // }), // propsValue: _propsValue, // adaptor: (args) => { // const list = parseData(args.data, { parseContent: true }); // const keys = { selected: [], expanded: [] }; // const dataSouce = createDataSource(list[0] ? list[0].children : [], keys); // const props = _propsValue(args); // return ( // // {createContents(dataSouce)} // // ); // }, // demoOptions: (demo) => { // const { node = { props: {} } } = demo; // const { level, data } = node.props; // if (data.indexOf('*') === 0) { // demo = { // ...demo, // height: 250 // }; // } // if (level === 'dark') { // demo = { // ...demo, // background: '#333' // }; // } else if(level === 'light') { // demo = { // ...demo, // background: 'rgb(235, 236, 240)', // }; // } // return demo; // } // }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/menu-button/meta.design.ts ================================================ import { getDataFromPlainText } from './adaptor'; export default { group: '原子组件', componentName: 'MenuButton', title: '分隔按钮', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'MenuButton', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'style', propType: 'object', }, { name: 'label', propType: { type: 'instanceOf', value: 'node', }, description: '主按钮的文案', }, { name: 'type', title: '按钮类型', propType: { type: 'oneOf', value: ['normal', 'primary', 'secondary'], }, description: '按钮的类型', defaultValue: 'normal', }, { name: 'size', title: '按钮尺寸', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '按钮组的尺寸', defaultValue: 'medium', }, { name: 'component', title: '标签类型', propType: { type: 'oneOf', value: ['button', 'a'], }, defaultValue: 'button', description: '设置标签类型', }, { name: 'ghost', title: '幽灵按钮', propType: { type: 'oneOf', value: ['light', 'dark', false, true], }, description: '是否为幽灵按钮', }, { name: 'defaultSelectedKeys', propType: { type: 'instanceOf', value: 'array', }, description: '默认激活的菜单项(用法同 Menu 非受控)', defaultValue: [], }, { name: 'selectedKeys', propType: { type: 'instanceOf', value: 'array', }, description: '激活的菜单项(用法同 Menu 受控)', }, { name: 'selectMode', title: '单选多选', propType: { type: 'oneOf', value: ['single', 'multiple'], }, defaultValue: 'single', description: '菜单的选择模式', }, { name: 'onSelect', propType: 'func', description: '选择菜单项时的回调,参考 Menu', }, { name: 'onItemClick', propType: 'func', description: '点击菜单项时的回调,参考 Menu', }, { name: 'triggerProps', propType: 'object', description: '触发按钮的属性(支持 Button 的所有属性透传)', }, { name: 'onVisibleChange', propType: 'func', description: '弹层显示状态变化时的回调函数\n@param {Boolean} visible 弹层显示状态\n@param {String} type 触发弹层显示或隐藏的来源 menuSelect 表示由menu触发; fromTrigger 表示由trigger的点击触发; docClick 表示由document的点击触发', }, { name: 'popupTriggerType', title: '弹层触发', propType: { type: 'oneOf', value: ['click', 'hover'], }, description: '弹层的触发方式', defaultValue: 'click', }, { name: 'popupAlign', title: '弹层对齐', propType: 'string', description: '弹层对齐方式, 详情见Overlay align', }, { name: 'popupStyle', propType: 'object', description: '弹层自定义样式', }, { name: 'popupClassName', propType: 'string', description: '弹层自定义样式类', }, { name: 'popupProps', propType: 'object', description: '透传给弹层的属性', }, { name: 'autoWidth', title: '自动宽度', propType: 'bool', description: '弹层菜单的宽度是否与按钮组一致', defaultValue: true, }, { name: 'visible', propType: 'bool', description: '弹层是否显示', }, { name: 'defaultVisible', title: '默认显示', defaultValue: true, propType: 'bool', description: '弹层默认是否显示', }, { name: 'followTrigger', title: '跟随滚动', propType: 'bool', description: '是否跟随滚动', }, { name: 'menuProps', propType: 'object', description: '透传给 Menu 的属性', }, { name: 'leftButtonProps', propType: 'object', description: '透传给 左侧按钮 的属性', }, { name: 'className', propType: 'string', }, ], configure: { component: { isContainer: true, isMinimalRenderUnit: true, }, props: [ { name: '!type', title: { type: 'i18n', zh_CN: '类型', en_US: 'type', }, getValue: (target) => { const parentTarget = target.parent; const isTextButton = parentTarget.getPropValue('text'); const isWarningButton = parentTarget.getPropValue('warning'); const ghostConfig = parentTarget.getPropValue('ghost'); if (isTextButton) { return 'text'; } else if (typeof ghostConfig !== 'undefined' && ghostConfig !== false) { return 'ghost'; } else { return 'normal'; } }, setValue: (target, value) => { const parentTarget = target.parent; parentTarget.setPropValue('text', false); parentTarget.setPropValue('ghost', false); switch (value) { case 'normal': break; case 'text': parentTarget.setPropValue('text', true); break; case 'ghost': parentTarget.setPropValue('ghost', 'light'); break; default: break; } }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '普通按钮', value: 'normal', }, { title: '文本按钮', value: 'text', }, { title: '幽灵按钮', value: 'ghost', }, ], }, }, defaultValue: 'normal', }, { name: 'ghost', title: { label: { type: 'i18n', zh_CN: '形式', en_US: 'Button Type', }, tip: { type: 'i18n', zh_CN: '属性: type | 说明: 按钮类型', en_US: 'prop: type | description: button type', }, }, defaultValue: 'light', condition: (target) => target?.parent?.getPropValue('!type') === 'ghost', setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: 'Light', value: 'light', }, { label: 'Dark', value: 'dark', }, ], }, }, }, { name: 'type', title: { label: { type: 'i18n', zh_CN: '形式', en_US: 'Button Type', }, tip: { type: 'i18n', zh_CN: '属性: type | 说明: 按钮类型', en_US: 'prop: type | description: button type', }, }, condition: (target) => target?.parent?.getPropValue('!type') !== 'ghost', setter: { componentName: 'RadioGroupSetter', props: { options: [ { value: 'normal', label: '普通', }, { value: 'primary', label: '主要', }, { value: 'secondary', label: '次要', }, ], }, }, defaultValue: 'normal', }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Button Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 按钮尺寸', en_US: 'prop: size | description: button size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '小', value: 'small', }, { label: '中', value: 'medium', }, { label: '大', value: 'large', }, ], }, }, defaultValue: 'medium', }, { name: 'plainData', display: 'block', title: '选项', tip: { title: '数据格式', url: '', }, setValue: (target, value) => { const { label, disabled, children, selectedKeys } = getDataFromPlainText(value); if (label) { target.parent.setPropValue('label', label); } if (typeof disabled !== 'undefined') { target.parent.setPropValue('disabled', disabled); } if (children) { target.node.children.importSchema(children); } if (selectedKeys) { target.parent.setPropValue('selectedKeys', selectedKeys); } }, setter: { componentName: 'MagicEditorSetter', props: { toolbar: ['normal', 'disable', 'group'], }, }, }, ], }, icon: '', category: '常用', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/menu-button/meta.ts ================================================ import { getDataFromPlainText } from './adaptor'; export default { group: '原子组件', componentName: 'MenuButton', title: '分隔按钮', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'MenuButton', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'style', propType: 'object', }, { name: 'label', propType: { type: 'instanceOf', value: 'node', }, description: '主按钮的文案', }, { name: 'type', title: '按钮类型', propType: { type: 'oneOf', value: ['normal', 'primary', 'secondary'], }, description: '按钮的类型', defaultValue: 'normal', }, { name: 'size', title: '按钮尺寸', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '按钮组的尺寸', defaultValue: 'medium', }, { name: 'component', title: '标签类型', propType: { type: 'oneOf', value: ['button', 'a'], }, defaultValue: 'button', description: '设置标签类型', }, { name: 'ghost', title: '幽灵按钮', propType: { type: 'oneOf', value: ['light', 'dark', false, true], }, description: '是否为幽灵按钮', }, { name: 'defaultSelectedKeys', propType: { type: 'instanceOf', value: 'array', }, description: '默认激活的菜单项(用法同 Menu 非受控)', defaultValue: [], }, { name: 'selectedKeys', propType: { type: 'instanceOf', value: 'array', }, description: '激活的菜单项(用法同 Menu 受控)', }, { name: 'selectMode', title: '单选多选', propType: { type: 'oneOf', value: ['single', 'multiple'], }, defaultValue: 'single', description: '菜单的选择模式', }, { name: 'onSelect', propType: 'func', description: '选择菜单项时的回调,参考 Menu', }, { name: 'onItemClick', propType: 'func', description: '点击菜单项时的回调,参考 Menu', }, { name: 'triggerProps', propType: 'object', description: '触发按钮的属性(支持 Button 的所有属性透传)', }, { name: 'onVisibleChange', propType: 'func', description: '弹层显示状态变化时的回调函数\n@param {Boolean} visible 弹层显示状态\n@param {String} type 触发弹层显示或隐藏的来源 menuSelect 表示由menu触发; fromTrigger 表示由trigger的点击触发; docClick 表示由document的点击触发', }, { name: 'popupTriggerType', title: '弹层触发', propType: { type: 'oneOf', value: ['click', 'hover'], }, description: '弹层的触发方式', defaultValue: 'click', }, { name: 'popupAlign', title: '弹层对齐', propType: 'string', description: '弹层对齐方式, 详情见Overlay align', }, { name: 'popupStyle', propType: 'object', description: '弹层自定义样式', }, { name: 'popupClassName', propType: 'string', description: '弹层自定义样式类', }, { name: 'popupProps', propType: 'object', description: '透传给弹层的属性', }, { name: 'autoWidth', title: '自动宽度', propType: 'bool', description: '弹层菜单的宽度是否与按钮组一致', defaultValue: true, }, { name: 'visible', propType: 'bool', description: '弹层是否显示', }, { name: 'defaultVisible', title: '默认显示', defaultValue: true, propType: 'bool', description: '弹层默认是否显示', }, { name: 'followTrigger', title: '跟随滚动', propType: 'bool', description: '是否跟随滚动', }, { name: 'menuProps', propType: 'object', description: '透传给 Menu 的属性', }, { name: 'leftButtonProps', propType: 'object', description: '透传给 左侧按钮 的属性', }, { name: 'className', propType: 'string', }, ], configure: { component: { isContainer: true, isMinimalRenderUnit: true, }, props: [ { name: '!type', title: { type: 'i18n', zh_CN: '类型', en_US: 'type', }, getValue: (target) => { const parentTarget = target.parent; const isTextButton = parentTarget.getPropValue('text'); const isWarningButton = parentTarget.getPropValue('warning'); const ghostConfig = parentTarget.getPropValue('ghost'); if (isTextButton) { return 'text'; } else if (typeof ghostConfig !== 'undefined' && ghostConfig !== false) { return 'ghost'; } else { return 'normal'; } }, setValue: (target, value) => { const parentTarget = target.parent; parentTarget.setPropValue('text', false); parentTarget.setPropValue('ghost', false); switch (value) { case 'normal': break; case 'text': parentTarget.setPropValue('text', true); break; case 'ghost': parentTarget.setPropValue('ghost', 'light'); break; default: break; } }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '普通按钮', value: 'normal', }, { title: '文本按钮', value: 'text', }, { title: '幽灵按钮', value: 'ghost', }, ], }, }, defaultValue: 'normal', }, { name: 'ghost', title: { label: { type: 'i18n', zh_CN: '形式', en_US: 'Button Type', }, tip: { type: 'i18n', zh_CN: '属性: type | 说明: 按钮类型', en_US: 'prop: type | description: button type', }, }, defaultValue: 'light', condition: (target) => target?.parent?.getPropValue('!type') === 'ghost', setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: 'Light', value: 'light', }, { label: 'Dark', value: 'dark', }, ], }, }, }, { name: 'type', title: { label: { type: 'i18n', zh_CN: '形式', en_US: 'Button Type', }, tip: { type: 'i18n', zh_CN: '属性: type | 说明: 按钮类型', en_US: 'prop: type | description: button type', }, }, condition: (target) => target?.parent?.getPropValue('!type') !== 'ghost', setter: { componentName: 'RadioGroupSetter', props: { options: [ { value: 'normal', label: '普通', }, { value: 'primary', label: '主要', }, { value: 'secondary', label: '次要', }, ], }, }, defaultValue: 'normal', }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Button Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 按钮尺寸', en_US: 'prop: size | description: button size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '小', value: 'small', }, { label: '中', value: 'medium', }, { label: '大', value: 'large', }, ], }, }, defaultValue: 'medium', }, { name: 'plainData', display: 'block', title: '选项', tip: { title: '数据格式', url: '', }, setValue: (target, value) => { const { label, disabled, children, selectedKeys } = getDataFromPlainText(value); if (label) { target.parent.setPropValue('label', label); } if (typeof disabled !== 'undefined') { target.parent.setPropValue('disabled', disabled); } if (children) { target.node.children.importSchema(children); } if (selectedKeys) { target.parent.setPropValue('selectedKeys', selectedKeys); } }, setter: { componentName: 'MagicEditorSetter', props: { toolbar: ['normal', 'disable', 'group'], }, }, }, ], }, icon: '', category: '常用', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/menu-divider/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Menu.Divider', title: '菜单分隔线', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Menu', main: '', destructuring: true, subName: 'Divider', }, props: [ { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: false, nestingRule: { parentWhitelist: ['Menu', 'SubMenu', 'Menu.Group', 'MenuButton'], }, }, advanced: { callbacks: { onHoverHook: () => false, onMouseDownHook: () => false, onClickHook: () => false, onMove: () => false, }, }, }, icon: '', category: '信息输入', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/menu-group/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Menu.Group', title: '菜单组', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Menu', main: '', destructuring: true, subName: 'Group', }, props: [ { name: 'label', propType: { type: 'instanceOf', value: 'node', }, description: '标签内容', }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: true, nestingRule: { parentWhitelist: ['Menu', 'SubMenu', 'Menu.Group', 'MenuButton'], }, }, advanced: { callbacks: { onHoverHook: () => false, onMouseDownHook: () => false, onClickHook: () => false, onMove: () => false, }, }, }, icon: '', category: '信息输入', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/menu-item/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Menu.Item', title: '菜单项', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Menu', main: '', destructuring: true, subName: 'Item', }, props: [ { name: 'key', propType: 'string', description: '菜单项标识符', }, { name: 'disabled', propType: 'bool', description: '是否禁用', defaultValue: false, }, { name: 'helper', propType: 'node', description: '帮助文本', }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: true, nestingRule: { parentWhitelist: ['Menu', 'SubMenu', 'Menu.Group', 'MenuButton'], }, }, advanced: { callbacks: { onHoverHook: () => false, onMouseDownHook: () => false, onClickHook: () => false, onMove: () => false, }, }, }, icon: '', category: '信息输入', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/menu-popup-item/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Menu.PopupItem', title: '自定义弹出内容', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Menu', main: '', destructuring: true, subName: 'PopupItem', }, props: [ { name: 'key', propType: 'string', description: '菜单项标识符', }, { name: 'label', propType: 'node', description: '标签内容', }, { name: 'children', propType: 'node', description: '自定义弹层内容', }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: true, nestingRule: { parentWhitelist: ['Menu', 'SubMenu', 'Menu.Group', 'MenuButton'], }, }, advanced: { callbacks: { onHoverHook: () => false, onMouseDownHook: () => false, onClickHook: () => false, onMove: () => false, }, }, }, icon: '', category: '信息输入', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/month-picker/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'MonthPicker', title: 'MonthPicker', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'DatePicker', main: '', destructuring: true, subName: 'MonthPicker', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'rtl', propType: 'bool', defaultValue: false, }, { name: 'label', propType: { type: 'instanceOf', value: 'node', }, description: '输入框内置标签', }, { name: 'state', propType: { type: 'oneOf', value: ['success', 'loading', 'error'], }, description: '输入框状态', }, { name: 'placeholder', propType: 'string', description: '输入提示', }, { name: 'defaultVisibleYear', propType: 'func', description: '默认展现的年\n@return {MomentObject} 返回包含指定年份的 moment 对象实例', }, { name: 'value', propType: { type: 'instanceOf', value: 'custom', }, description: '日期值(受控)moment 对象', }, { name: 'defaultValue', propType: { type: 'instanceOf', value: 'custom', }, description: '初始日期值,moment 对象', }, { name: 'format', propType: 'string', description: '日期值的格式(用于限定用户输入和展示)', defaultValue: 'YYYY-MM', }, { name: 'disabledDate', propType: 'func', description: '禁用日期函数\n@param {MomentObject} 日期值\n@param {String} view 当前视图类型,year: 年, month: 月, date: 日\n@return {Boolean} 是否禁用', }, { name: 'footerRender', propType: 'func', description: '自定义面板页脚\n@return {Node} 自定义的面板页脚组件', }, { name: 'onChange', propType: 'func', description: '日期值改变时的回调\n@param {MomentObject|String} value 日期值', }, { name: 'size', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '输入框尺寸', defaultValue: 'medium', }, { name: 'disabled', propType: 'bool', description: '是否禁用', }, { name: 'hasClear', propType: 'bool', description: '是否显示清空按钮', defaultValue: true, }, { name: 'visible', propType: 'bool', description: '弹层显示状态', }, { name: 'defaultVisible', propType: 'bool', description: '弹层默认是否显示', }, { name: 'onVisibleChange', propType: 'func', description: '弹层展示状态变化时的回调\n@param {Boolean} visible 弹层是否显示\n@param {String} type 触发弹层显示和隐藏的来源 calendarSelect 表示由日期表盘的选择触发; fromTrigger 表示由trigger的点击触发; docClick 表示由document的点击触发', }, { name: 'popupTriggerType', propType: { type: 'oneOf', value: ['click', 'hover'], }, description: '弹层触发方式', defaultValue: 'click', }, { name: 'popupAlign', propType: 'string', description: '弹层对齐方式, 具体含义见 OverLay文档', defaultValue: 'tl tl', }, { name: 'popupContainer', propType: 'any', description: '弹层容器\n@param {Element} target 目标元素\n@return {Element} 弹层的容器元素', }, { name: 'popupStyle', propType: 'object', description: '弹层自定义样式', }, { name: 'popupClassName', propType: 'string', description: '弹层自定义样式类', }, { name: 'popupProps', propType: 'object', description: '弹层其他属性', }, { name: 'followTrigger', propType: 'bool', description: '是否跟随滚动', }, { name: 'inputProps', propType: 'object', description: '输入框其他属性', }, { name: 'monthCellRender', propType: 'func', description: '自定义月份渲染函数\n@param {Object} calendarDate 对应 Calendar 返回的自定义日期对象\n@returns {ReactNode}', }, { name: 'yearCellRender', propType: 'func', }, { name: 'dateInputAriaLabel', propType: 'string', description: '日期输入框的 aria-label 属性', }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', }, { name: 'renderPreview', propType: 'func', description: '预览态模式下渲染的内容\n@param {MomentObject} value 月份', }, { name: 'locale', propType: 'object', }, { name: 'className', propType: 'string', }, { name: 'name', propType: 'string', }, { name: 'popupComponent', propType: { type: 'instanceOf', value: 'elementType', }, }, { name: 'popupContent', propType: { type: 'instanceOf', value: 'node', }, }, { name: 'style', propType: 'object', }, ], category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/nav/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Nav', title: '导航', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Nav', main: '', destructuring: true, subName: '', }, props: [ { name: 'style', propType: 'object', }, { name: 'children', propType: 'node', description: '导航项和子导航', }, { name: 'type', propType: { type: 'oneOf', value: ['normal', 'primary', 'secondary', 'line'], }, description: '导航类型', defaultValue: 'normal', }, { name: 'direction', propType: { type: 'oneOf', value: ['hoz', 'ver'], }, description: '导航布局', defaultValue: 'ver', }, { name: 'hozAlign', propType: { type: 'oneOf', value: ['left', 'right'], }, description: '对齐方向', defaultValue: 'left', }, { name: 'activeDirection', propType: { type: 'oneOf', value: [null, 'top', 'bottom', 'left', 'right'], }, description: '选中条方向', }, { name: 'mode', propType: { type: 'oneOf', value: ['inline', 'popup'], }, description: '子导航打开的模式', defaultValue: 'inline', }, { name: 'triggerType', propType: { type: 'oneOf', value: ['click', 'hover'], }, description: '子导航打开的触发方式', defaultValue: 'click', }, { name: 'inlineIndent', propType: 'number', description: '内联子导航缩进距离', defaultValue: 20, }, { name: 'defaultOpenAll', propType: 'bool', description: '初始展开所有的子导航', defaultValue: false, }, { name: 'openMode', propType: { type: 'oneOf', value: ['single', 'multiple'], }, description: '内联子导航的展开模式', defaultValue: 'multiple', }, { name: 'selectedKeys', propType: { type: 'oneOfType', value: [ 'string', { type: 'instanceOf', value: 'array', }, ], }, description: '当前选中导航key值', }, { name: 'defaultSelectedKeys', propType: { type: 'oneOfType', value: [ 'string', { type: 'instanceOf', value: 'array', }, ], }, description: '初始选中导航项的key值', }, { name: 'onSelect', propType: 'func', description: '选中或取消选中导航项触发的回调函数\n@param {Array} selectedKeys 选中的所有导航项的 key\n@param {Object} item 选中或取消选中的导航项\n@param {Object} extra 额外参数\n@param {Boolean} extra.select 是否是选中\n@param {Array} extra.key 导航项的 key\n@param {Object} extra.label 导航项的文本\n@param {Array} extra.keyPath 导航项 key 的路径', }, { name: 'popupAlign', propType: { type: 'oneOf', value: ['follow', 'outside'], }, description: '弹出子导航的对齐方式(水平导航只支持 follow )\n@eumdesc Item 顶端对齐, Nav 顶端对齐', defaultValue: 'follow', }, { name: 'popupClassName', propType: 'string', description: '弹出子导航的自定义类名', }, { name: 'iconOnly', propType: 'bool', description: '是否只显示图标', }, { name: 'hasArrow', propType: 'bool', description: '是否显示右侧的箭头', defaultValue: true, }, { name: 'hasTooltip', propType: 'bool', description: '是否有ToolTips', defaultValue: false, }, { name: 'header', propType: { type: 'instanceOf', value: 'node', }, description: '自定义导航头部', }, { name: 'footer', propType: { type: 'instanceOf', value: 'node', }, description: '自定义导航尾部', }, { name: 'embeddable', propType: 'bool', description: '开启嵌入式模式', defaultValue: false, }, ], configure: { component: { isContainer: true, }, }, icon: '', category: '引导', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/nav-item/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Nav.Item', title: '导航项', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Nav', main: '', destructuring: true, subName: 'Item', }, props: [ { name: 'icon', propType: { type: 'icon', }, description: '自定义图标', }, { name: 'children', propType: { type: 'oneOfType', value: ['string', 'node'], }, description: '导航内容', }, { name: 'style', propType: 'object', }, ], icon: '', category: '引导', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/next-table/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'NextTable', title: '表格', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: 'latest', exportName: 'NextTable', main: 'lib/index.js', destructuring: true, subName: '', }, props: [ { name: 'columns', title: '数据列', propType: { type: 'arrayOf', value: { type: 'shape', value: [ { name: 'title', description: '列标题', propType: 'string', defaultValue: 'Title', }, { name: 'dataKey', description: '列索引', propType: 'string', defaultValue: 'Key', }, { name: 'dataType', description: '数据类型', propType: { type: 'oneOf', value: ['text', 'timestamp', 'cascadeTimestamp', 'employee', 'money', 'moneyRange'], }, defaultValue: 'Key', }, { name: 'editType', description: '编辑类型', propType: { type: 'oneOf', value: ['select', 'text', 'radio', 'date', 'employee'], }, defaultValue: 'Key', }, ], }, }, }, { name: 'data', title: '数据源', propType: { type: 'oneOfType', value: ['Json', 'JSExpression'], }, }, { name: 'actionTitle', title: '操作列标题', propType: 'string', }, { name: 'actionColumn', title: '操作列', propType: { type: 'arrayOf', value: { type: 'shape', value: [ { name: 'title', description: '列标题', propType: 'string', defaultValue: 'Title', }, { name: 'callback', description: 'callback', propType: 'func', defaultValue: { type: 'JSFunction', value: '(rowData, action, table) => {\n return table.editRow(rowData).then((row) => {\n console.log(row);\n })}', }, }, ], }, }, }, { name: 'customBarItem', isRequired: true, title: '自定义工具栏渲染', propType: 'any', }, ], configure: { props: [ { name: 'customBarItem', isRequired: true, title: '自定义工具栏渲染', setter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'render', title: '整体自定义渲染', setter: { componentName: 'FunctionSetter', props: { supportParams: true, }, }, }, { name: 'rightRender', title: '底部自定义渲染', setter: { componentName: 'SlotSetter', initialValue: { type: 'JSSlot', params: ['value', 'index', 'record'], value: [], }, }, }, { name: 'bottomRender', title: '右侧自定义渲染', setter: { componentName: 'SlotSetter', initialValue: { type: 'JSSlot', params: ['value', 'index', 'record'], value: [], }, }, }, ], }, }, }, }, { name: 'StyleAndTheme', title: '风格和样式', type: 'group', extraProps: { display: 'entry', }, items: [ { name: 'theme', title: '主题', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: 'zebra', value: 'zebra', }, { title: 'split', value: 'split', }, { title: 'border', value: 'border', }, ], }, }, }, { name: 'hasHeader', title: '是否显示表头', setter: 'BoolSetter', supportVariable: true, }, { name: 'fixedHeader', title: '是否固定表头', setter: 'BoolSetter', supportVariable: true, }, { name: 'stickyHeader', title: '表头是否是sticky', setter: 'BoolSetter', supportVariable: true, }, { name: 'setEmptyContent', title: '开启自定义空提示', setter: 'BoolSetter', supportVariable: true, }, { description: '最大高度', name: 'maxBodyHeight', setter: 'StringSetter', supportVariable: true, }, ], }, { name: 'Selector', title: '行选择器', type: 'group', extraProps: { display: 'entry', }, items: [ { name: 'rowSelector', title: '选择器模式', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: 'checkboxSelector', value: 'checkboxSelector', }, { title: 'radioSelector', value: 'radioSelector', }, ], }, }, }, { name: 'showRowSelector', title: '是否启用选择模式', setter: 'BoolSetter', supportVariable: true, }, ], }, { name: 'Pagination', title: '分页设置', type: 'group', extraProps: { display: 'entry', }, items: [ { name: 'isPagination', title: '是否显示分页', setter: 'BoolSetter', supportVariable: true, initialValue: true, }, { name: 'pagination', title: '分页设置', setter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'paginationPosition', title: '翻页器显示位置', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: 'left', value: 'left', }, { title: 'right', value: 'right', }, ], }, }, }, { name: 'size', title: '分页组件大小', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: 'small', value: 'small', }, { title: 'medium', value: 'medium', }, { title: 'large', value: 'large', }, ], }, }, }, { name: 'type', title: '分页组件类型', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: 'normal', value: 'normal', }, { title: 'simple', value: 'simple', }, { title: 'mini', value: 'mini', }, ], }, }, }, { name: 'shape', title: '前进后退按钮样式', setter: { componentName: 'SelectSetter', props: { options: [ { title: 'normal', value: 'normal', }, { title: 'arrow-only', value: 'arrow-only', }, { title: 'arrow-prev-only', value: 'arrow-prev-only', }, { title: 'no-border', value: 'no-border', }, ], }, }, }, { name: 'pageSizeSelector', title: '每页显示选择器类型', setter: 'BoolSetter', supportVariable: true, }, { name: 'pageSizeList', title: '每页显示选择器可选值', setter: 'StringSetter', supportVariable: true, }, { name: 'pageSizePosition', title: '每页显示选择器在组件中的位置', setter: { componentName: 'SelectSetter', props: { options: [ { title: 'start', value: 'start', }, { title: 'end', value: 'end', }, ], }, }, }, { name: 'hideOnlyOnePage', title: 'hideOnlyOnePage', setter: 'BoolSetter', supportVariable: true, }, { name: 'showJump', title: 'showJump', setter: 'BoolSetter', supportVariable: true, }, { name: 'pageShowCount', title: '页码显示的数量', setter: 'NumberSetter', supportVariable: true, }, ], }, }, initialValue: { type: 'normal', shape: 'arrow-only', pageSize: 10, pageSizeSelector: false, pageSizeList: '5,10,20', pageSizePosition: 'end', paginationPosition: 'right', hideOnlyOnePage: false, showJump: true, }, }, }, ], }, { name: 'ExpandAndTree', title: '可折叠/树形表格', type: 'group', extraProps: { display: 'entry', }, items: [ { name: 'hasExpandedRowCtrl', title: '启用折叠', setter: 'BoolSetter', supportVariable: true, }, { name: 'isTree', title: '启用树形', setter: 'BoolSetter', supportVariable: true, }, ], }, { name: 'TopAction', title: '顶部操作选项', type: 'group', extraProps: { display: 'entry', }, items: [ { name: 'showMiniPager', title: '顶部迷你分页器', setter: { componentName: 'BoolSetter', }, }, { name: 'showActionBar', title: '显示操作条', setter: { componentName: 'BoolSetter', }, }, { name: 'showLinkBar', title: '显示外链条', setter: { componentName: 'BoolSetter', }, }, { name: 'showSearch', title: '显示搜索', setter: { componentName: 'BoolSetter', }, }, { name: 'searchBarPlaceholder', title: '搜索 placeholder', setter: 'StringSetter', supportVariable: true, }, { name: 'showCustomColumn', title: '显示筛选器', setter: { componentName: 'BoolSetter', }, }, ], }, { name: 'actionBar', title: '操作条', setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'title', description: '标题', setter: 'StringSetter', supportVariable: true, initialValue: 'Title', }, { name: 'callback', description: 'callback', setter: { componentName: 'FunctionSetter', }, }, ], }, }, initialValue: { title: 'Title', }, }, }, }, }, { name: 'linkBar', title: '外链操作条', setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'title', description: '标题', setter: 'StringSetter', supportVariable: true, initialValue: 'Title', }, { name: 'callback', description: 'callback', setter: { componentName: 'FunctionSetter', }, }, ], }, }, initialValue: { title: 'Title', }, }, }, }, }, { name: 'columns', title: '数据列', setter: { componentName: 'MixedSetter', props: { setters: [ 'ExpressionSetter', { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'title', description: '列标题', setter: 'StringSetter', supportVariable: true, }, { name: 'dataKey', description: '列索引', setter: 'StringSetter', supportVariable: true, }, { description: '宽度', name: 'width', setter: 'StringSetter', supportVariable: true, }, { name: 'dataType', description: '数据类型', setter: { componentName: 'SelectSetter', props: { options: [ { title: 'text', value: 'text', }, { title: 'timestamp', value: 'timestamp', }, { title: 'cascadeTimestamp', value: 'cascadeTimestamp', }, { title: 'employee', value: 'employee', }, { title: 'money', value: 'money', }, { title: 'moneyRange', value: 'moneyRange', }, ], }, }, }, { name: 'editType', description: '编辑类型', setter: { componentName: 'SelectSetter', props: { options: [ { title: 'select', value: 'select', }, { title: 'text', value: 'text', }, { title: 'radio', value: 'radio', }, { title: 'date', value: 'date', }, { title: 'employee', value: 'employee', }, ], }, }, }, { name: 'lock', description: '锁定位置', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '左', value: 'left', }, { title: '右', value: 'right', }, { title: '无', value: '', }, ], }, initialValue: '', }, }, { description: '自定义渲染', name: 'render', setter: { componentName: 'SlotSetter', title: '单元格自定义', initialValue: { type: 'JSSlot', params: [''], value: [ { componentName: 'Box', }, ], }, }, }, ], }, }, initialValue: { title: 'Title', dataKey: 'Key', dataType: 'text', editType: 'text', width: 200, lock: '', }, }, }, }, ], }, }, }, { name: 'data', title: '数据源', setter: { componentName: 'MixedSetter', props: { setters: ['JsonSetter', 'ExpressionSetter'], }, }, }, { name: 'action', title: '操作列选项', type: 'group', extraProps: { display: 'entry', }, items: [ { name: 'actionTitle', title: '操作列标题', setter: 'StringSetter', supportVariable: true, }, { name: 'actionWidth', title: '操作列宽度', setter: 'NumberSetter', supportVariable: true, }, { name: 'actionType', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: 'link', value: 'link', }, { title: 'button', value: 'button', }, ], }, }, }, { name: 'actionFixed', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: 'right', value: 'right', }, { title: 'none', value: 'none', }, ], }, }, }, { name: 'actionHidden', setter: 'BoolSetter', supportVariable: true, initialValue: false, }, ], }, { name: 'actionColumn', title: '操作列', setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'title', description: '列标题', setter: 'StringSetter', supportVariable: true, initialValue: 'Title', }, { name: 'callback', description: 'callback', setter: { componentName: 'FunctionSetter', }, }, ], }, }, initialValue: { title: 'Title', callback: { type: 'JSFunction', value: '(rowData, action, table) => {\n return table.editRow(rowData).then((row) => {\n console.log(row);\n })}', }, }, }, }, }, }, ], supports: { style: true, events: [ 'onFetchData', 'onSelect', 'onRowClick', 'onRowMouseEnter', 'onRowMouseLeave', 'onResizeChange', 'onColumnsChange', 'onRowOpen', 'onShowSearch', ], }, }, icon: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_table.png', category: '信息输入', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/next-table/snippets.ts ================================================ module.exports = [ { title: 'NextTable', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_table.png', schema: { componentName: 'NextTable', title: '表格', props: { setEmptyContent: true, emptyContent: { type: 'JSSlot', title: 'EmptyContent', value: [ { componentName: 'Typography.Text', props: { children: 'No Data', }, }, ], }, showMiniPager: true, showActionBar: true, actionBar: [ { title: '新增', type: 'primary', }, { title: '编辑', }, ], columns: [ { dataKey: 'name', width: 200, align: 'center', title: '姓名', editType: 'text', }, { dataKey: 'age', width: 200, align: 'center', title: '年龄', }, { dataKey: 'role', width: 200, align: 'center', title: '职责', }, ], data: [ { name: '王小', id: '1', age: 15000, role: '开发', }, { name: '王中', id: '2', age: 25000, role: '产品', }, { name: '王大', id: '3', age: 35000, role: '设计', }, ], actionTitle: '操作', actionWidth: 180, actionType: 'link', actionFixed: 'none', actionHidden: false, maxWebShownActionCount: 2, actionColumn: [ { title: '编辑', callback: { type: 'JSFunction', value: '(rowData, action, table) => {\n return table.editRow(rowData).then((row) => {\n console.log(row);\n });\n }', }, }, { title: '保存', callback: { type: 'JSFunction', value: '(rowData, action, table) => { \nreturn table.saveRow(rowData).then((row) => { \nconsole.log(row); \n}); \n}', }, }, ], }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/next-text/meta.ts ================================================ module.exports = { componentName: 'NextText', title: '文本', category: '基础元素', group: '精选组件', npm: { package: '@alilc/lowcode-materials', version: 'latest', exportName: 'NextText', main: 'lib/index.js', destructuring: true, subName: '', }, props: [ { name: 'style', propType: 'object', }, { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'classname', propType: 'bool', defaultValue: true, }, { name: 'type', title: '字体大小', extraProps: { defaultValue: 'body2', }, defaultValue: 'body2', initialValue: 'body2', setter: { componentName: 'SelectSetter', initialValue: 'body2', props: { defaultValue: 'body2', options: [ { title: '默认', value: 'inherit', }, { title: 'h1', value: 'h1', }, { title: 'h2', value: 'h2', }, { title: 'h3', value: 'h3', }, { title: 'h4', value: 'h4', }, { title: 'h5', value: 'h5', }, { title: 'h6', value: 'h6', }, { title: 'body1', value: 'body1', }, { title: 'body2', value: 'body2', }, { title: 'caption', value: 'caption', }, { title: 'overline', value: 'overline', }, ], }, }, }, { name: 'children', propType: 'string', }, { name: 'mark', title: '标记', propType: 'bool', description: '添加标记样式', defaultValue: false, }, { name: 'code', title: '代码', propType: 'bool', description: '添加代码样式', defaultValue: false, }, { name: 'delete', title: '删除线', propType: 'bool', description: '添加删除线样式', defaultValue: false, }, { name: 'underline', title: '下划线', propType: 'bool', description: '添加下划线样式', defaultValue: false, }, { name: 'strong', propType: 'bool', description: '是否加粗', defaultValue: false, }, { name: 'onClick', propType: 'func', description: '鼠标点击', }, { name: 'style', propType: 'object', }, ], configure: { props: { isExtends: true, override: [ { name: 'prefix', condition: () => false, }, { name: 'classname', condition: () => false, }, { name: 'children', supportVariable: true, title: { label: { type: 'i18n', zh_CN: '文本内容', en_US: 'Text', }, tip: { type: 'i18n', zh_CN: '属性:children | 说明:文本内容', en_US: 'prop: children | description: text of the content', }, }, setter: 'TextAreaSetter', supportVariable: true, }, ], }, }, snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/next-text/snippets.ts ================================================ module.exports = [ { title: '标题', screenshot: 'https://img.alicdn.com/imgextra/i4/O1CN01E2PcPW1bKJV5QUVMg_!!6000000003446-55-tps-50-50.svg', schema: { componentName: 'NextText', props: { type: 'h5', children: '标题标题', }, }, }, { title: '正文', screenshot: 'https://img.alicdn.com/imgextra/i3/O1CN01n5wpxc1bi862KuXFz_!!6000000003498-55-tps-50-50.svg', schema: { componentName: 'NextText', props: { type: 'inherit', children: '基于 Ali-Lowcode-Engine 快速打造高生产力的低代码研发平台, 基于自然布局体系快速搭建页面', }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/note-wrapper/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Wrapper', title: '备注容器', category: 'Others', npm: { package: '@alilc/lowcode-materials', version: 'latest', exportName: 'NoteWrapper', main: '', destructuring: true, subName: '', }, props: [ { name: 'style', propType: 'object', }, { name: 'note', propType: 'string', defaultValue: '这是一个备注', }, ], configure: { component: { isContainer: true, isModal: false, }, props: [ { name: 'style', setter: 'StyleSetter', supportVariable: true, }, { name: 'note', propType: 'string', setter: 'StringSetter', supportVariable: true, }, ], }, icon: '', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/number-picker/meta.design.ts ================================================ import snippets from './snippets'; export default { group: '原子组件', componentName: 'NumberPicker', title: '数字输入框', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: 'latest', exportName: 'NumberPicker', main: '', destructuring: true, subName: '', }, props: [ { name: 'size', propType: { type: 'oneOf', value: ['large', 'medium'], }, description: '大小', defaultValue: 'medium', }, { name: 'type', propType: { type: 'oneOf', value: ['normal', 'inline'], }, description: '设置类型', defaultValue: 'normal', }, { name: 'value', propType: 'number', description: '当前值', }, { name: 'defaultValue', propType: 'number', description: '默认值', }, { name: 'disabled', propType: 'bool', description: '是否禁用', }, { name: 'step', propType: 'number', description: '步长', defaultValue: 1, }, { name: 'precision', propType: 'number', description: '保留小数点后位数', defaultValue: 0, }, { name: 'editable', propType: 'bool', description: '用户是否可以输入', defaultValue: true, }, { name: 'autoFocus', propType: 'bool', description: '自动焦点', }, { name: 'max', propType: 'number', description: '最大值', defaultValue: null, }, { name: 'min', propType: 'number', description: '最小值', defaultValue: null, }, { name: 'format', propType: 'func', description: '格式化当前值', }, { name: 'upBtnProps', propType: 'object', description: '增加按钮的props', }, { name: 'downBtnProps', propType: 'object', description: '减少按钮的props', }, { name: 'label', propType: 'string', description: '内联 label', }, { name: 'innerAfter', propType: { type: 'oneOfType', value: ['string', 'icon'], }, description: 'inner after', }, { name: 'rtl', propType: 'bool', }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', }, { name: 'renderPreview', propType: 'func', description: '预览态模式下渲染的内容\n@param {number} value 评分值', }, { name: 'onChange', propType: 'func', description: '数值被改变的事件\n@param {Number} value 数据\n@param {Event} e DOM事件对象', }, { name: 'onKeyDown', propType: 'func', description: '键盘按下', }, { name: 'onFocus', propType: 'func', description: '焦点获得', }, { name: 'onBlur', propType: 'func', description: '焦点失去', }, { name: 'onCorrect', propType: 'func', description: '数值订正后的回调\n@param {Object} obj {currentValue,oldValue:String}', }, { name: 'onDisabled', propType: 'func', }, { name: 'className', propType: 'string', description: '自定义class', }, { name: 'style', propType: 'object', description: '自定义内联样式', }, ], configure: { props: [ { name: 'type', title: '类型', defaultValue: 'normal', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '普通', value: 'normal' }, { title: '内联', value: 'inline' }, ], }, }, }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Button Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 按钮尺寸', en_US: 'prop: size | description: button size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '小', value: 'small', }, { label: '中', value: 'medium', }, { label: '大', value: 'large', }, ], }, }, defaultValue: 'medium', }, { name: 'style.width', title: '宽度', setter: 'NumberSetter', }, { name: 'defaultValue', title: '当前值', setter: (target) => { const precision = target?.parent?.getPropValue?.('precision') || 0; console.log('precision: ', precision); return { componentName: 'NumberSetter', props: { step: target?.parent?.getPropValue?.('step') || 0, precision, }, }; }, }, { name: 'innerAfter', title: '单位', setter: 'StringSetter', }, { name: 'step', title: '步长', defaultValue: 1, setter: 'NumberSetter', }, { name: 'precision', title: '小数位数', defaultValue: 0, setter: 'NumberSetter', }, { name: 'editable', title: '可以输入', defaultValue: true, setter: 'BoolSetter', }, { name: 'disabled', setter: 'BoolSetter', description: '是否禁用', }, ], supports: { events: ['onChange', 'onKeyDown', 'onFocus', 'onBlur', 'onCorrect'], }, }, icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/number-picker/meta.ts ================================================ import snippets from './snippets'; export default { group: '原子组件', componentName: 'NumberPicker', title: '数字输入框', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'NumberPicker', main: '', destructuring: true, subName: '', }, props: [ { name: 'size', propType: { type: 'oneOf', value: ['large', 'medium'], }, description: '大小', defaultValue: 'medium', }, { name: 'type', propType: { type: 'oneOf', value: ['normal', 'inline'], }, description: '设置类型', defaultValue: 'normal', }, { name: 'value', propType: 'number', description: '当前值', }, { name: 'defaultValue', propType: 'number', description: '默认值', }, { name: 'disabled', propType: 'bool', description: '是否禁用', }, { name: 'step', propType: 'number', description: '步长', defaultValue: 1, }, { name: 'precision', propType: 'number', description: '保留小数点后位数', defaultValue: 0, }, { name: 'editable', propType: 'bool', description: '用户是否可以输入', defaultValue: true, }, { name: 'autoFocus', propType: 'bool', description: '自动焦点', }, { name: 'max', propType: 'number', description: '最大值', defaultValue: null, }, { name: 'min', propType: 'number', description: '最小值', defaultValue: null, }, { name: 'format', propType: 'func', description: '格式化当前值', }, { name: 'upBtnProps', propType: 'object', description: '增加按钮的props', }, { name: 'downBtnProps', propType: 'object', description: '减少按钮的props', }, { name: 'label', propType: 'string', description: '内联 label', }, { name: 'innerAfter', propType: { type: 'oneOfType', value: ['string', 'icon'], }, description: 'inner after', }, { name: 'rtl', propType: 'bool', }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', }, { name: 'renderPreview', propType: 'func', description: '预览态模式下渲染的内容\n@param {number} value 评分值', }, { name: 'onChange', propType: 'func', description: '数值被改变的事件\n@param {Number} value 数据\n@param {Event} e DOM事件对象', }, { name: 'onKeyDown', propType: 'func', description: '键盘按下', }, { name: 'onFocus', propType: 'func', description: '焦点获得', }, { name: 'onBlur', propType: 'func', description: '焦点失去', }, { name: 'onCorrect', propType: 'func', description: '数值订正后的回调\n@param {Object} obj {currentValue,oldValue:String}', }, { name: 'onDisabled', propType: 'func', }, { name: 'className', propType: 'string', description: '自定义class', }, { name: 'style', propType: 'object', description: '自定义内联样式', }, ], configure: { props: [ { name: 'value', title: '当前值', setter: ['NumberSetter', 'ExpressionSetter'], }, { name: 'defaultValue', title: '默认值', setter: ['NumberSetter', 'ExpressionSetter'], }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 尺寸\n@enumdesc 小, 中, 大', en_US: 'prop: size | description: size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['small', 'medium', 'large'], }, }, defaultValue: 'medium', }, { name: 'type', title: '类型', defaultValue: 'normal', setter: { componentName: 'MixedSetter', props: { setters: [ { componentName: 'RadioGroupSetter', props: { options: [ { title: '普通', value: 'normal' }, { title: '内联', value: 'inline' }, ], }, }, 'ExpressionSetter', ], }, }, }, { name: 'innerAfter', title: '单位', setter: ['StringSetter', 'ExpressionSetter'], }, { name: 'step', title: '步长', defaultValue: 1, setter: ['NumberSetter', 'ExpressionSetter'], }, { name: 'precision', title: '小数位数', defaultValue: 0, setter: ['NumberSetter', 'ExpressionSetter'], }, { name: 'max', title: '最大值', setter: ['NumberSetter', 'ExpressionSetter'], }, { name: 'min', title: '最小值', setter: ['NumberSetter', 'ExpressionSetter'], }, { name: 'editable', title: '可以输入', defaultValue: true, setter: ['BoolSetter', 'ExpressionSetter'], }, { name: 'format', title: '格式化', display: 'block', setter: { componentName: 'FunctionSetter', // props: { // defaultActionName="format", // defaultCode=`function format(value) { // return value; // }`, // } }, }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', supportVariable: true, }, ], }, { name: 'style', setter: { componentName: 'StyleSetter', }, }, ], supports: { events: ['onChange', 'onKeyDown', 'onFocus', 'onBlur', 'onCorrect'], }, }, icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/number-picker/snippets.ts ================================================ export default [ { title: '数字输入框', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_number-picker.png', schema: { componentName: 'NumberPicker', props: { prefix: 'next-', type: 'normal', size: 'medium', step: 1, editable: true, }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/number-picker/view.tsx ================================================ import * as React from 'react'; import { NumberPicker } from '@alifd/next'; import { ValueWrapper } from 'lowcode/utils/component-wrapper'; export default ValueWrapper(NumberPicker, 'NumberPicker'); ================================================ FILE: packages/fusion-lowcode-materials/lowcode/page/meta.ts ================================================ export default [ { group: '原子组件', componentName: 'Page', title: '页面', props: [ { name: 'style', propType: 'object', defaultValue: { padding: 12, }, }, ], configure: { events: { supportedLifecycles: [ { description: '初始化时', name: 'constructor', }, { description: '装载后', name: 'componentDidMount', }, { description: '更新时', name: 'componentDidMount', }, { description: '卸载时', name: 'componentWillUnmount', }, ], }, supports: { style: true, }, component: { isContainer: true, disableBehaviors: '*', }, }, category: '基础', }, { componentName: 'Leaf', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Typography', main: '', destructuring: true, subName: 'Text', }, configure: { component: { disableBehaviors: '*', }, advanced: { callbacks: { onHoverHook: () => false, onMouseDownHook: () => false, onClickHook: () => false, }, }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/pagination/meta.design.ts ================================================ export default { group: '原子组件', componentName: 'Pagination', title: '翻页器', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Pagination', main: '', destructuring: true, subName: '', }, props: [ { name: 'rtl', propType: 'bool', defaultValue: false, }, { name: 'className', propType: 'string', }, { name: 'type', title: { label: '组件类型', tip: '分页组件类型', }, propType: { type: 'oneOf', value: ['normal', 'simple', 'mini'], }, description: '分页组件类型', defaultValue: 'normal', }, { name: 'shape', title: { label: '按钮样式', tip: '前进后退按钮样式', }, propType: { type: 'oneOf', value: ['normal', 'arrow-only', 'arrow-prev-only', 'no-border'], }, description: '前进后退按钮样式', defaultValue: 'normal', }, { name: 'size', title: { label: '尺寸', tip: '分页组件大小', }, propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '分页组件大小', defaultValue: 'medium', }, { name: 'current', propType: 'number', description: '(受控)当前页码', }, { name: 'defaultCurrent', title: { label: '按钮样式', tip: '前进后退按钮样式', }, title: { label: '初始页码', tip: '(非受控)初始页码', }, propType: 'number', description: '(非受控)初始页码', defaultValue: 1, }, { name: 'onChange', propType: 'func', description: '页码发生改变时的回调函数\n@param {Number} current 改变后的页码数\n@param {Object} e 点击事件对象', }, { name: 'total', propType: 'number', description: '总记录数', defaultValue: 100, }, { name: 'totalRender', propType: 'func', title: { label: '总数渲染', tip: '总数的渲染函数\n@param {Number} total 总数\n@param {Array} range 当前数据在总数中的区间', }, }, { name: 'pageShowCount', propType: 'number', title: { label: '显示页数', tip: '页码显示的数量,更多的使用...代替', }, defaultValue: 5, }, { name: 'pageSize', title: { label: '单页记录', tip: '一页中的记录数', }, propType: 'number', description: '一页中的记录数', defaultValue: 10, }, { name: 'pageSizeSelector', title: { label: '选择器类型', tip: '每页显示选择器类型', }, propType: { type: 'oneOf', value: [false, 'filter', 'dropdown'], }, description: '每页显示选择器类型', defaultValue: false, }, { name: 'pageNumberRender', propType: 'func', title: { label: '自定义页码', tip: '自定义页码渲染函数,函数作用于页码button以及当前页/总页数的数字渲染\n@param {Number} index 分页的页码,从1开始\n@return {ReactNode} 返回渲染结果', }, }, { name: 'pageSizePosition', title: { label: '选择器位置', tip: '每页显示选择器在组件中的位置', }, propType: { type: 'oneOf', value: ['start', 'end'], }, description: '每页显示选择器在组件中的位置', defaultValue: 'start', }, { name: 'onPageSizeChange', propType: 'func', description: '每页显示记录数量改变时的回调函数\n@param {Number} pageSize 改变后的每页显示记录数', }, { name: 'hideOnlyOnePage', propType: 'bool', title: { label: '单页隐藏', tip: '当分页数为1时,是否隐藏分页器', }, defaultValue: false, }, { name: 'showJump', propType: 'bool', title: { label: '显示跳转', tip: 'type 设置为 normal 时,在页码数超过5页后,会显示跳转输入框与按钮,当设置 showJump 为 false 时,不再显示该跳转区域', }, defaultValue: true, }, { name: 'link', title: { label: '跳转链接', tip: '设置页码按钮的跳转链接,它的值为一个包含 {page} 的模版字符串', }, propType: 'string', description: '设置页码按钮的跳转链接,它的值为一个包含 {page} 的模版字符串', }, { name: 'style', propType: 'object', }, ], configure: { props: [ { name: 'type', title: { label: '类型', tip: '分页组件类型', }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '普通', value: 'normal', }, { label: '简单', value: 'simple', }, { label: '迷你', value: 'mini', }, ], }, }, description: '分页组件类型', defaultValue: 'normal', }, { name: 'size', title: { label: '尺寸', tip: '分页组件大小', }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '小', value: 'small', }, { label: '中', value: 'medium', }, { label: '大', value: 'large', }, ], }, }, description: '分页组件大小', defaultValue: 'medium', }, { name: 'pageSizeSelector', title: { label: '扩展内容', tip: '每页显示选择器类型', }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '无', value: false, }, { label: '平铺', value: 'filter', }, { label: '下拉选择', value: 'dropdown', }, ], }, }, description: '每页显示选择器类型', defaultValue: false, }, { name: 'shape', title: { label: '样式', tip: '前进后退按钮样式', }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '文本&图标', value: 'normal', }, { label: '仅图标', value: 'arrow-only', }, { label: '无边框', value: 'no-border', }, ], }, }, description: '前进后退按钮样式', defaultValue: 'normal', }, ], }, icon: '', category: '导航', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/pagination/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Pagination', title: '翻页器', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Pagination', main: '', destructuring: true, subName: '', }, props: [ { name: 'rtl', propType: 'bool', defaultValue: false, }, { name: 'className', propType: 'string', }, { name: 'type', title: { label: '组件类型', tip: '分页组件类型', }, propType: { type: 'oneOf', value: ['normal', 'simple', 'mini'], }, description: '分页组件类型', defaultValue: 'normal', }, { name: 'shape', title: { label: '按钮样式', tip: '前进后退按钮样式', }, propType: { type: 'oneOf', value: ['normal', 'arrow-only', 'arrow-prev-only', 'no-border'], }, description: '前进后退按钮样式', defaultValue: 'normal', }, { name: 'size', title: { label: '尺寸', tip: '分页组件大小', }, propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '分页组件大小', defaultValue: 'medium', }, { name: 'current', propType: 'number', description: '(受控)当前页码', }, { name: 'defaultCurrent', title: { label: '按钮样式', tip: '前进后退按钮样式', }, title: { label: '初始页码', tip: '(非受控)初始页码', }, propType: 'number', description: '(非受控)初始页码', defaultValue: 1, }, { name: 'onChange', propType: 'func', description: '页码发生改变时的回调函数\n@param {Number} current 改变后的页码数\n@param {Object} e 点击事件对象', }, { name: 'total', propType: 'number', description: '总记录数', defaultValue: 100, }, { name: 'totalRender', propType: 'func', title: { label: '总数渲染', tip: '总数的渲染函数\n@param {Number} total 总数\n@param {Array} range 当前数据在总数中的区间', }, }, { name: 'pageShowCount', propType: 'number', title: { label: '显示页数', tip: '页码显示的数量,更多的使用...代替', }, defaultValue: 5, }, { name: 'pageSize', title: { label: '单页记录', tip: '一页中的记录数', }, propType: 'number', description: '一页中的记录数', defaultValue: 10, }, { name: 'pageSizeSelector', title: { label: '选择器类型', tip: '每页显示选择器类型', }, propType: { type: 'oneOf', value: [false, 'filter', 'dropdown'], }, description: '每页显示选择器类型', defaultValue: false, }, { name: 'pageNumberRender', propType: 'func', title: { label: '自定义页码', tip: '自定义页码渲染函数,函数作用于页码button以及当前页/总页数的数字渲染\n@param {Number} index 分页的页码,从1开始\n@return {ReactNode} 返回渲染结果', }, }, { name: 'pageSizePosition', title: { label: '选择器位置', tip: '每页显示选择器在组件中的位置', }, propType: { type: 'oneOf', value: ['start', 'end'], }, description: '每页显示选择器在组件中的位置', defaultValue: 'start', }, { name: 'onPageSizeChange', propType: 'func', description: '每页显示记录数量改变时的回调函数\n@param {Number} pageSize 改变后的每页显示记录数', }, { name: 'hideOnlyOnePage', propType: 'bool', title: { label: '单页隐藏', tip: '当分页数为1时,是否隐藏分页器', }, defaultValue: false, }, { name: 'showJump', propType: 'bool', title: { label: '显示跳转', tip: 'type 设置为 normal 时,在页码数超过5页后,会显示跳转输入框与按钮,当设置 showJump 为 false 时,不再显示该跳转区域', }, defaultValue: true, }, { name: 'link', title: { label: '跳转链接', tip: '设置页码按钮的跳转链接,它的值为一个包含 {page} 的模版字符串', }, propType: 'string', description: '设置页码按钮的跳转链接,它的值为一个包含 {page} 的模版字符串', }, { name: 'style', propType: 'object', }, ], configure: { props: { isExtends: true, override: [ { name: 'rtl', condition: () => false, }, { name: 'current', condition: () => false, title: { label: '当前页面', tip: '(受控)当前页码', }, setter: { componentName: 'MixedSetter', props: { setters: ['NumberSetter', 'ExpressionSetter'], }, }, }, { name: 'total', title: { label: '总记录数', tip: '总记录数', }, setter: { componentName: 'MixedSetter', props: { setters: ['NumberSetter', 'ExpressionSetter'], }, }, }, ], }, }, icon: '', category: '引导', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/pagination/snippets.ts ================================================ module.exports = [ { title: '翻页器', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_pagination.png', schema: { componentName: 'Pagination', props: { prefix: 'next-', type: 'normal', shape: 'normal', size: 'medium', defaultCurrent: 1, total: 100, pageShowCount: 5, pageSize: 10, pageSizePosition: 'start', showJump: true, }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/paragraph/meta.design.ts ================================================ import snippets from './snippets'; export default { group: '原子组件', componentName: 'Paragraph', title: '段落', docUrl: '', screenshot: 'https://img.alicdn.com/imgextra/i3/O1CN01n5wpxc1bi862KuXFz_!!6000000003498-55-tps-50-50.svg', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Paragraph', main: '', destructuring: true, subName: '', }, props: [ { name: 'component', propType: { type: 'instanceOf', value: 'elementType', }, description: '设置标签类型', defaultValue: 'article', }, { name: 'style', propType: 'object', }, { name: 'children', title: '内容', propType: 'string', }, ], configure: { props: [ { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Button Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 按钮尺寸', en_US: 'prop: size | description: button size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '小', value: 'small', }, { label: '中', value: 'medium', }, ], }, }, defaultValue: 'medium', }, { name: 'style.width', title: '宽度', setter: 'NumberSetter', }, { name: 'children', title: '内容', setter: 'TextAreaSetter', }, ], }, icon: 'https://img.alicdn.com/imgextra/i3/O1CN01n5wpxc1bi862KuXFz_!!6000000003498-55-tps-50-50.svg', category: '通用', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/paragraph/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Paragraph', title: 'Paragraph', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Typography', main: '', destructuring: true, subName: 'Paragraph', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'component', propType: { type: 'instanceOf', value: 'elementType', }, description: '设置标签类型', defaultValue: 'p', }, { name: 'type', defaultValue: 'long', }, { name: 'size', defaultValue: 'medium', }, { name: 'style', propType: 'object', }, ], category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/paragraph/snippets.ts ================================================ export default [ { title: '段落', screenshot: 'https://img.alicdn.com/imgextra/i3/O1CN01n5wpxc1bi862KuXFz_!!6000000003498-55-tps-50-50.svg', schema: { componentName: 'Paragraph', props: { size: 'medium', style: { wordBreak: 'break-word', }, children: `Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.`, }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/popup-item/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'PopupItem', title: 'PopupItem', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Nav', main: '', destructuring: true, subName: 'PopupItem', }, props: [ { name: 'className', propType: 'string', description: '自定义类名', }, { name: 'icon', propType: { type: 'oneOfType', value: [ 'string', { type: 'instanceOf', value: 'node', }, ], }, description: '自定义图标,可以使用 Icon 的 type, 也可以使用组件 ``', }, { name: 'label', propType: { type: 'instanceOf', value: 'node', }, description: '标签内容', }, { name: 'children', propType: { type: 'instanceOf', value: 'node', }, description: '弹出内容', }, { name: 'style', propType: 'object', }, ], category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/progress/meta.design.ts ================================================ export default { group: '原子组件', componentName: 'Progress', title: '进度指示器', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Progress', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'shape', propType: { type: 'oneOf', value: ['circle', 'line'], }, description: '形态', defaultValue: 'line', }, { name: 'size', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '尺寸', defaultValue: 'medium', }, { name: 'percent', title: '百分比', propType: 'number', description: '所占百分比', defaultValue: 0, }, { name: 'state', title: '进度状态', propType: { type: 'oneOf', value: ['normal', 'success', 'error'], }, description: '进度状态, 显示优先级: color > progressive > state', defaultValue: 'normal', }, { name: 'progressive', title: { label: '色阶变化', tip: '是否为色彩阶段变化模式, 显示优先级: color > progressive > state', }, propType: 'bool', description: '是否为色彩阶段变化模式, 显示优先级: color > progressive > state', defaultValue: false, }, { name: 'hasBorder', title: '边框', propType: 'bool', description: '是否添加 Border(只适用于 Line Progress)', defaultValue: false, }, { name: 'textRender', title: { label: '文本渲染', tip: '文本渲染函数\n@param {Number} percent 当前的进度信息\n@param {Object} option 额外的参数\n@property {Boolean} option.rtl 是否在rtl 模式下渲染\n@return {ReactNode} 返回文本节点', }, propType: 'func', description: '文本渲染函数\n@param {Number} percent 当前的进度信息\n@param {Object} option 额外的参数\n@property {Boolean} option.rtl 是否在rtl 模式下渲染\n@return {ReactNode} 返回文本节点', }, { name: 'color', propType: 'string', description: '进度条颜色, 显示优先级: color > progressive > state', }, { name: 'backgroundColor', propType: 'string', description: '背景色', }, { name: 'rtl', propType: 'bool', }, { name: 'style', propType: 'object', }, ], configure: { props: [ { name: 'shape', title: '形状', setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '圆形', value: 'circle', }, { label: '线', value: 'line', }, ], }, }, description: '形态', defaultValue: 'line', }, { name: 'progressive', title: { label: '类型', tip: '是否为色彩阶段变化模式, 显示优先级: color > progressive > state', }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '基础型', value: false, }, { label: '阶段型', value: true, }, ], }, }, description: '是否为色彩阶段变化模式, 显示优先级: color > progressive > state', defaultValue: false, }, { name: 'state', title: '状态', setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '普通', value: 'normal', }, { label: '成功', value: 'success', }, { label: '失败', value: 'error', }, ], }, }, description: '进度状态, 显示优先级: color > progressive > state', defaultValue: 'normal', }, { name: 'size', title: '尺寸', setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '小', value: 'small', }, { label: '中', value: 'medium', }, { label: '大', value: 'large', }, ], }, }, description: '尺寸', defaultValue: 'medium', }, { name: '!showData', title: { label: '显示数据', tip: '是否显示百分比数据', }, setter: 'BoolSetter', setValue: (target, value) => { if (value === false) { target.parent.setPropValue('textRender', () => {}); } else { target.parent.setPropValue('textRender', (percent) => `${Math.floor(percent)}%`); } }, defaultValue: true, }, { name: 'hasBorder', condition: (target) => { return target?.parent?.getPropValue('shape') === 'line'; }, title: '边框', setter: 'BoolSetter', description: '是否添加 Border(只适用于 Line Progress)', defaultValue: false, }, { name: 'style.width', condition: (target) => { return target?.parent?.getPropValue('shape') === 'line'; }, title: '宽度', setter: 'NumberSetter', }, { name: 'percent', title: '百分比', setter: 'NumberSetter', }, ], }, icon: '', category: '信息展示', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/progress/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Progress', title: '进度指示器', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Progress', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'shape', propType: { type: 'oneOf', value: ['circle', 'line'], }, description: '形态', defaultValue: 'line', }, { name: 'size', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '尺寸', defaultValue: 'medium', }, { name: 'percent', title: '百分比', propType: 'number', description: '所占百分比', defaultValue: 0, }, { name: 'state', title: '进度状态', propType: { type: 'oneOf', value: ['normal', 'success', 'error'], }, description: '进度状态, 显示优先级: color > progressive > state', defaultValue: 'normal', }, { name: 'progressive', title: { label: '色阶变化', tip: '是否为色彩阶段变化模式, 显示优先级: color > progressive > state', }, propType: 'bool', description: '是否为色彩阶段变化模式, 显示优先级: color > progressive > state', defaultValue: false, }, { name: 'hasBorder', title: '边框', propType: 'bool', description: '是否添加 Border(只适用于 Line Progress)', defaultValue: false, }, { name: 'textRender', title: { label: '文本渲染', tip: '文本渲染函数\n@param {Number} percent 当前的进度信息\n@param {Object} option 额外的参数\n@property {Boolean} option.rtl 是否在rtl 模式下渲染\n@return {ReactNode} 返回文本节点', }, propType: 'func', description: '文本渲染函数\n@param {Number} percent 当前的进度信息\n@param {Object} option 额外的参数\n@property {Boolean} option.rtl 是否在rtl 模式下渲染\n@return {ReactNode} 返回文本节点', }, { name: 'color', propType: 'string', description: '进度条颜色, 显示优先级: color > progressive > state', }, { name: 'backgroundColor', propType: 'string', description: '背景色', }, { name: 'rtl', propType: 'bool', }, { name: 'style', propType: 'object', }, ], configure: { props: { isExtends: true, override: [ { name: 'rtl', condition: () => false, }, { name: 'prefix', condition: () => false, }, { name: 'percent', title: '百分比', supportVariable: true, setter: 'NumberSetter', }, { name: 'color', title: { label: '进度条颜色', tip: 'color|进度条颜色, 显示优先级: color > progressive > state', }, setter: { componentName: 'ColorSetter', }, }, { name: 'backgroundColor', title: { label: '背景色', tip: 'backgroundColor|背景色', }, setter: { componentName: 'ColorSetter', }, }, ], }, }, icon: '', category: '信息反馈', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/progress/snippets.ts ================================================ module.exports = [ { title: '进度指示器', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_progress.png', schema: { componentName: 'Progress', props: { prefix: 'next-', shape: 'line', size: 'medium', state: 'normal', percent: 30, }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/radio/meta.design.ts ================================================ import snippets from './snippets.design'; export default { group: '原子组件', componentName: 'Radio', title: '单选框', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Radio', main: '', destructuring: true, subName: '', }, props: [ { name: 'className', propType: 'string', description: '自定义类名', }, { name: 'style', propType: 'object', description: '自定义内敛样式', }, { name: 'id', propType: 'string', description: 'input元素id', }, { name: 'name', propType: 'string', description: 'name', }, { name: 'checked', propType: 'bool', description: '是否选中', }, { name: 'defaultChecked', propType: 'bool', description: '是否默认选中', }, { name: 'label', propType: 'string', description: '通过属性配置label', }, { name: 'disabled', propType: 'bool', description: '是否被禁用', }, { name: 'value', propType: { type: 'oneOfType', value: ['string', 'number', 'bool'], }, description: 'value', }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', defaultValue: false, }, { name: 'renderPreview', propType: 'func', description: '预览态模式下渲染的内容', }, { name: 'onChange', propType: 'func', description: '状态变化时触发的事件\n@param {Boolean} checked 是否选中\n@param {Event} e Dom 事件对象', }, { name: 'onMouseEnter', propType: 'func', description: '鼠标进入enter事件\n@param {Event} e Dom 事件对象', }, { name: 'onMouseLeave', propType: 'func', description: '鼠标离开事件\n@param {Event} e Dom 事件对象', }, ], icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/radio/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Radio', title: '单选框', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Radio', main: '', destructuring: true, subName: '', }, props: [ { name: 'className', propType: 'string', description: '自定义类名', }, { name: 'style', propType: 'object', description: '自定义内敛样式', }, { name: 'id', propType: 'string', description: 'input元素id', }, { name: 'name', propType: 'string', description: 'name', }, { name: 'checked', propType: 'bool', description: '是否选中', }, { name: 'defaultChecked', propType: 'bool', description: '是否默认选中', }, { name: 'label', propType: 'string', description: '通过属性配置label', }, { name: 'disabled', propType: 'bool', description: '是否被禁用', }, { name: 'value', propType: { type: 'oneOfType', value: ['string', 'number', 'bool'], }, description: 'value', }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', defaultValue: false, }, { name: 'renderPreview', propType: 'func', description: '预览态模式下渲染的内容', }, { name: 'onChange', propType: 'func', description: '状态变化时触发的事件\n@param {Boolean} checked 是否选中\n@param {Event} e Dom 事件对象', }, { name: 'onMouseEnter', propType: 'func', description: '鼠标进入enter事件\n@param {Event} e Dom 事件对象', }, { name: 'onMouseLeave', propType: 'func', description: '鼠标离开事件\n@param {Event} e Dom 事件对象', }, ], icon: '', category: '信息输入', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/radio/snippets.design.ts ================================================ export default [ { title: '单选按钮组', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_radio.png', schema: { componentName: 'Radio.Group', props: { dataSource: [ { label: '选项一', value: '1', }, { label: '选项二', value: '2', }, { label: '选项三', value: '3', }, ], }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/radio/snippets.ts ================================================ module.exports = [ { title: '单选按钮', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_radio.png', schema: { componentName: 'Radio', props: { label: '选项一', value: '1', }, }, }, { title: '单选按钮组', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_radio.png', schema: { componentName: 'Radio.Group', props: { dataSource: [ { label: '选项一', value: '1', }, { label: '选项二', value: '2', }, { label: '选项三', value: '3', }, ], }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/radio-group/meta.design.ts ================================================ export default { group: '原子组件', componentName: 'Radio.Group', title: '单选框组', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Radio', main: '', destructuring: true, subName: 'Group', }, props: [ { name: 'className', propType: 'string', description: '自定义类名', }, { name: 'style', propType: 'object', description: '自定义内敛样式', }, { name: 'name', propType: 'string', description: 'name', }, { name: 'size', propType: { type: 'oneOf', value: ['large', 'medium', 'small'], }, description: '尺寸', defaultValue: 'medium', }, { name: 'shape', propType: { type: 'oneOf', value: ['normal', 'button'], }, description: '展示形态', }, { name: 'value', propType: { type: 'oneOfType', value: ['string', 'number', 'bool'], }, description: '选中项的值', }, { name: 'defaultValue', propType: { type: 'oneOfType', value: ['string', 'number', 'bool'], }, description: '默认值', }, { name: 'component', propType: 'string', description: '设置标签类型', defaultValue: 'div', }, { name: 'disabled', propType: 'bool', description: '是否被禁用', }, { name: 'dataSource', propType: 'object', description: '可选项列表', }, { name: 'itemDirection', propType: { type: 'oneOf', value: ['hoz', 'ver'], }, description: '子项目的排列方式', defaultValue: 'hoz', }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', defaultValue: false, }, { name: 'renderPreview', propType: 'func', description: '预览态模式下渲染的内容\n@param {number} value 评分值', }, { name: 'onChange', propType: 'func', description: '选中值改变时的事件\n@param {String/Number} value 选中项的值\n@param {Event} e Dom 事件对象', }, ], configure: { props: [ { name: 'shape', title: '类型', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '单选', value: 'normal' }, { title: '单选按钮', value: 'button' }, ], }, }, defaultValue: 'normal', }, { name: 'itemDirection', title: '排列方式', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '水平排列', value: 'hoz' }, { title: '垂直排列', value: 'ver' }, ], }, }, defaultValue: 'hoz', }, { name: 'dataSource', display: 'block', title: '选项', setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'label', title: 'label', setter: 'StringSetter', important: true, }, { name: 'value', title: 'value', setter: 'StringSetter', }, ], }, }, initialValue: { label: '选项一', value: '1', }, }, }, }, }, { name: 'disabled', title: '是否禁用', setter: 'BoolSetter', }, ], supports: { style: true, events: ['onChange'], }, }, icon: '', category: '信息输入', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/radio-group/meta.ts ================================================ export default { group: '原子组件', componentName: 'Radio.Group', title: '单选框组', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Radio', main: '', destructuring: true, subName: 'Group', }, props: [ { name: 'className', propType: 'string', description: '自定义类名', }, { name: 'style', propType: 'object', description: '自定义内敛样式', }, { name: 'name', propType: 'string', description: 'name', }, { name: 'size', propType: { type: 'oneOf', value: ['large', 'medium', 'small'], }, description: '尺寸', defaultValue: 'medium', }, { name: 'shape', propType: { type: 'oneOf', value: ['normal', 'button'], }, description: '展示形态', }, { name: 'value', propType: { type: 'oneOfType', value: ['string', 'number', 'bool'], }, description: '选中项的值', }, { name: 'defaultValue', propType: { type: 'oneOfType', value: ['string', 'number', 'bool'], }, description: '默认值', }, { name: 'component', propType: 'string', description: '设置标签类型', defaultValue: 'div', }, { name: 'disabled', propType: 'bool', description: '是否被禁用', }, { name: 'dataSource', propType: 'object', description: '可选项列表', }, { name: 'itemDirection', propType: { type: 'oneOf', value: ['hoz', 'ver'], }, description: '子项目的排列方式', defaultValue: 'hoz', }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', defaultValue: false, }, { name: 'renderPreview', propType: 'func', description: '预览态模式下渲染的内容\n@param {number} value 评分值', }, { name: 'onChange', propType: 'func', description: '选中值改变时的事件\n@param {String/Number} value 选中项的值\n@param {Event} e Dom 事件对象', }, ], configure: { props: [ { name: 'shape', title: '展示形状', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '默认', value: 'normal' }, { title: '按钮', value: 'button' }, ], }, }, defaultValue: 'normal', }, { name: 'disabled', title: '是否禁用', setter: { componentName: 'MixedSetter', props: { setters: ['BoolSetter', 'ExpressionSetter'], }, }, }, { name: 'itemDirection', title: '排列方式', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '水平排列', value: 'hoz' }, { title: '垂直排列', value: 'ver' }, ], }, }, defaultValue: 'hoz', }, { name: 'isPreview', title: '预览态', setter: { componentName: 'BoolSetter', }, }, { name: 'defaultValue', title: '默认值', defaultValue: '', setter: { componentName: 'MixedSetter', props: { setters: ['StringSetter', 'ExpressionSetter'], }, }, }, { name: 'dataSource', display: 'block', title: '选项', setter: { componentName: 'MixedSetter', props: { setters: [ { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'label', title: 'label', setter: 'StringSetter', supportVariable: true, }, { name: 'value', title: 'value', setter: 'StringSetter', supportVariable: true, }, ], }, }, initialValue: { label: '选项一', value: '1', }, }, }, }, 'ExpressionSetter', ], }, }, }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', supportVariable: true, }, ], }, ], supports: { style: true, events: ['onChange'], }, }, icon: '', category: '信息输入', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/radio-item/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'RadioItem', title: '单选菜单项', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Menu', main: '', destructuring: true, subName: 'RadioItem', }, props: [ { name: 'checked', propType: 'bool', description: '是否选中', defaultValue: false, }, { name: 'disabled', propType: 'bool', description: '是否禁用', defaultValue: false, }, { name: 'onChange', propType: 'func', description: '选中或取消选中触发的回调函数\n@param {Boolean} checked 是否选中\n@param {Object} event 选中事件对象', }, { name: 'helper', propType: 'node', description: '帮助文本', }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: true, nestingRule: { parentWhitelist: ['Menu', 'SubMenu', 'Menu.Group', 'MenuButton'], }, }, }, icon: '', category: '信息输入', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/range/meta.design.ts ================================================ import snippets from './snippets'; export default { group: '原子组件', componentName: 'Range', title: '区段选择器', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Range', main: '', destructuring: true, subName: '', }, props: [ { name: 'className', propType: 'string', description: '自定义类名', }, { name: 'style', propType: 'object', description: '自定义内敛样式', }, { name: 'id', propType: 'string', }, { name: 'name', propType: 'string', description: 'name', }, { name: 'value', propType: 'number', description: '分值', }, { name: 'slider', title: { label: '滑块个数', tip: '滑块个数: 单个, 两个', }, propType: { type: 'oneOf', value: ['single', 'double'], }, description: '滑块个数\n@enumdesc 单个, 两个', defaultValue: 'single', }, { name: 'min', title: { label: '最小值', }, propType: 'number', description: '最小值', defaultValue: 0, }, { name: 'max', title: { label: '最大值', }, propType: 'number', description: '最大值', defaultValue: 100, }, { name: 'step', title: { label: '步长', tip: '步长,取值必须大于 0,并且可被 (max - min) 整除。', }, propType: 'number', description: '步长,取值必须大于 0,并且可被 (max - min) 整除。', defaultValue: 1, }, { name: 'marksPosition', title: { label: 'Marks 位置', tip: "marksPosition|marks显示在上方('above')or下方('below')", }, propType: { type: 'oneOf', value: ['above', 'below'], }, description: "marks显示在上方('above')or下方('below')", defaultValue: 'above', }, { name: 'disabled', propType: 'bool', description: '值为 `true` 时,滑块为禁用状态', defaultValue: false, }, { name: 'onChange', propType: 'func', description: '当 Range 的值发生改变后,会触发 onChange 事件,并把改变后的值作为参数传入, 如果设置了value, 要配合此函数做受控使用\n@param {String/number} value', }, { name: 'onProcess', propType: 'func', description: '滑块拖动的时候触发的事件,不建议在这里setState, 一般情况下不需要用, 滑动时有特殊需求时使用\n@param {String/number} value', }, { name: 'hasTip', title: { label: '是否显示 tip', tip: 'hasTip', }, propType: 'bool', description: '是否显示 tip', defaultValue: true, }, { name: 'reverse', title: { label: '选中态反转', tip: 'reverse', }, propType: 'bool', description: '选中态反转', defaultValue: false, }, { name: 'pure', propType: 'bool', description: '是否pure render', defaultValue: false, }, { name: 'fixedWidth', propType: 'bool', description: '是否为拖动线段类型,默认slider为double, defaultValue必传且指定区间', defaultValue: false, }, { name: 'tooltipVisible', propType: 'bool', description: 'tooltip是否默认展示', defaultValue: false, }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', defaultValue: false, }, ], configure: { props: [ { name: 'slider', title: { label: '滑块个数', tip: '滑块个数: 单个, 两个', }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '单个', value: 'single', }, { label: '两个', value: 'double', }, ], }, }, description: '滑块个数\n@enumdesc 单个, 两个', defaultValue: 'single', }, { name: 'marks', title: '显示刻度', setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '否', value: false, }, { label: '是', value: 5, }, ], }, }, defaultValue: false, }, { name: 'marksPosition', title: { label: '刻度位置', tip: "marksPosition|marks显示在上方('above')or下方('below')", }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '上', value: 'above', }, { label: '下', value: 'below', }, ], }, }, description: "marks显示在上方('above')or下方('below')", defaultValue: 'above', }, { name: 'style.width', title: '宽度', setter: 'NumberSetter', }, { name: 'value', title: '当前值', setter: 'NumberSetter', }, { name: 'min', title: { label: '最小值', }, setter: 'NumberSetter', description: '最小值', defaultValue: 0, }, { name: 'max', title: { label: '最大值', }, setter: 'NumberSetter', description: '最大值', defaultValue: 100, }, { name: 'disabled', title: '是否禁用', setter: 'BoolSetter', defaultValue: false, }, ], supports: { style: true, events: ['onChange'], }, }, icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/range/meta.ts ================================================ import snippets from './snippets'; export default { group: '原子组件', componentName: 'Range', title: '区段选择器', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Range', main: '', destructuring: true, subName: '', }, props: [ { name: 'className', propType: 'string', description: '自定义类名', }, { name: 'style', propType: 'object', description: '自定义内敛样式', }, { name: 'id', propType: 'string', }, { name: 'name', propType: 'string', description: 'name', }, { name: 'value', propType: 'number', description: '分值', }, { name: 'slider', title: { label: '滑块个数', tip: '滑块个数: 单个, 两个', }, propType: { type: 'oneOf', value: ['single', 'double'], }, description: '滑块个数\n@enumdesc 单个, 两个', defaultValue: 'single', }, { name: 'min', title: { label: '最小值', }, propType: 'number', description: '最小值', defaultValue: 0, }, { name: 'max', title: { label: '最大值', }, propType: 'number', description: '最大值', defaultValue: 100, }, { name: 'step', title: { label: '步长', tip: '步长,取值必须大于 0,并且可被 (max - min) 整除。', }, propType: 'number', description: '步长,取值必须大于 0,并且可被 (max - min) 整除。', defaultValue: 1, }, { name: 'marksPosition', title: { label: 'Marks 位置', tip: "marksPosition|marks显示在上方('above')or下方('below')", }, propType: { type: 'oneOf', value: ['above', 'below'], }, description: "marks显示在上方('above')or下方('below')", defaultValue: 'above', }, { name: 'disabled', propType: 'bool', description: '值为 `true` 时,滑块为禁用状态', defaultValue: false, }, { name: 'onChange', propType: 'func', description: '当 Range 的值发生改变后,会触发 onChange 事件,并把改变后的值作为参数传入, 如果设置了value, 要配合此函数做受控使用\n@param {String/number} value', }, { name: 'onProcess', propType: 'func', description: '滑块拖动的时候触发的事件,不建议在这里setState, 一般情况下不需要用, 滑动时有特殊需求时使用\n@param {String/number} value', }, { name: 'hasTip', title: { label: '是否显示 tip', tip: 'hasTip', }, propType: 'bool', description: '是否显示 tip', defaultValue: true, }, { name: 'reverse', title: { label: '选中态反转', tip: 'reverse', }, propType: 'bool', description: '选中态反转', defaultValue: false, }, { name: 'pure', propType: 'bool', description: '是否pure render', defaultValue: false, }, { name: 'fixedWidth', propType: 'bool', description: '是否为拖动线段类型,默认slider为double, defaultValue必传且指定区间', defaultValue: false, }, { name: 'tooltipVisible', propType: 'bool', description: 'tooltip是否默认展示', defaultValue: false, }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', defaultValue: false, }, ], configure: { props: [ { name: 'value', title: '当前值', setter: ['NumberSetter', 'ExpressionSetter'], }, { name: 'defaultValue', title: '默认值', setter: ['NumberSetter', 'ExpressionSetter'], }, { name: 'min', title: { label: '最小值', }, setter: 'NumberSetter', supportVariable: true, description: '最小值', defaultValue: 0, }, { name: 'max', title: { label: '最大值', }, setter: 'NumberSetter', supportVariable: true, description: '最大值', defaultValue: 100, }, { name: 'step', title: { label: '步长', tip: '步长,取值必须大于 0,并且可被 (max - min) 整除。', }, setter: 'NumberSetter', supportVariable: true, description: '步长,取值必须大于 0,并且可被 (max - min) 整除。', defaultValue: 1, }, { name: 'slider', title: { label: '滑块个数', tip: '滑块个数: 单个, 两个', }, setter: { componentName: 'RadioGroupSetter', props: { options: ['single', 'double'] }, }, description: '滑块个数\n@enumdesc 单个, 两个', defaultValue: 'single', }, { name: 'marksPosition', title: { label: 'Marks 位置', tip: "marksPosition|marks显示在上方('above')or下方('below')", }, setter: { componentName: 'RadioGroupSetter', props: { options: ['above', 'below'] }, }, description: "marks显示在上方('above')or下方('below')", defaultValue: 'above', }, { name: 'disabled', title: '是否禁用', setter: 'BoolSetter', supportVariable: true, description: '值为 `true` 时,滑块为禁用状态', defaultValue: false, }, { name: 'hasTip', title: { label: '显示 Tip', tip: 'hasTip', }, setter: 'BoolSetter', supportVariable: true, description: '是否显示 tip', defaultValue: true, }, { name: 'fixedWidth', title: '固定宽度', setter: 'BoolSetter', supportVariable: true, description: '是否为拖动线段类型,默认slider为double, defaultValue必传且指定区间', defaultValue: false, }, { name: 'tooltipVisible', display: 'block', setter: 'BoolSetter', supportVariable: true, title: 'tooltip是否默认展示', defaultValue: false, }, { name: 'reverse', display: 'block', title: { label: '选中态反转', tip: 'reverse', }, setter: 'BoolSetter', supportVariable: true, description: '选中态反转', defaultValue: false, }, { name: 'isPreview', display: 'block', setter: 'BoolSetter', supportVariable: true, title: '是否为预览态', defaultValue: false, }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', supportVariable: true, }, ], }, ], supports: { style: true, events: ['onChange'], }, }, icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/range/snippets.ts ================================================ export default [ { title: '区段选择器', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_range.png', schema: { componentName: 'Range', props: { prefix: 'next-', slider: 'single', max: 100, step: 1, marksPosition: 'above', hasTip: true, }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/range-calendar/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'RangeCalendar', title: 'RangeCalendar', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Calendar', main: '', destructuring: true, subName: 'RangeCalendar', }, props: [ { name: 'prefix', propType: 'string', description: '样式前缀', defaultValue: 'next-', }, { name: 'rtl', propType: 'bool', defaultValue: false, }, { name: 'defaultStartValue', propType: { type: 'instanceOf', value: 'custom', }, description: '默认的开始日期', }, { name: 'defaultEndValue', propType: { type: 'instanceOf', value: 'custom', }, description: '默认的结束日期', }, { name: 'startValue', propType: { type: 'instanceOf', value: 'custom', }, description: '开始日期(moment 对象)', }, { name: 'endValue', propType: { type: 'instanceOf', value: 'custom', }, description: '结束日期(moment 对象)', }, { name: 'disableChangeMode', propType: 'bool', defaultValue: false, }, { name: 'format', propType: 'string', defaultValue: 'YYYY-MM-DD', }, { name: 'showOtherMonth', propType: 'bool', description: '是否显示非本月的日期', defaultValue: false, }, { name: 'defaultVisibleMonth', propType: 'func', description: '模板展示的月份(起始月份)', }, { name: 'onVisibleMonthChange', propType: 'func', description: '展现的月份变化时的回调\n@param {Object} value 显示的月份 (moment 对象)\n@param {String} reason 触发月份改变原因', }, { name: 'disabledDate', propType: 'func', description: '不可选择的日期\n@param {Object} calendarDate 对应 Calendar 返回的自定义日期对象\n@param {String} view 当前视图类型,year: 年, month: 月, date: 日\n@returns {Boolean}', }, { name: 'onSelect', propType: 'func', description: '选择日期单元格时的回调\n@param {Object} value 对应的日期值 (moment 对象)', }, { name: 'dateCellRender', propType: 'func', description: '自定义日期单元格渲染', }, { name: 'monthCellRender', propType: 'func', description: '自定义月份渲染函数\n@param {Object} calendarDate 对应 Calendar 返回的自定义日期对象\n@returns {ReactNode}', }, { name: 'yearCellRender', propType: 'func', }, { name: 'locale', propType: 'object', }, { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, ], configure: { props: { isExtends: true, override: [ { name: 'startValue', setter: 'DateSetter', supportVariable: true, }, { name: 'defaultStartValue', setter: 'DateSetter', supportVariable: true, }, { name: 'defaultEndValue', setter: 'DateSetter', supportVariable: true, }, { name: 'endValue', setter: 'DateSetter', supportVariable: true, }, ], }, }, category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/range-picker/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'RangePicker', title: '日期区段选择', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'DatePicker', main: '', destructuring: true, subName: 'RangePicker', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'rtl', propType: 'bool', defaultValue: false, }, { name: 'type', propType: { type: 'oneOf', value: ['date', 'month', 'year'], }, description: '日期范围类型', defaultValue: 'date', }, { name: 'defaultVisibleMonth', propType: 'func', description: '默认展示的起始月份\n@return {MomentObject} 返回包含指定月份的 moment 对象实例', }, { name: 'onVisibleMonthChange', propType: 'func', }, { name: 'value', propType: 'array', description: '日期范围值数组 [moment, moment]', }, { name: 'defaultValue', propType: 'array', description: '初始的日期范围值数组 [moment, moment]', }, { name: 'format', propType: 'string', description: '日期格式', defaultValue: 'YYYY-MM-DD', }, { name: 'showTime', propType: 'bool', description: '是否使用时间控件,支持传入 TimePicker 的属性', defaultValue: false, }, { name: 'resetTime', propType: 'bool', description: '每次选择是否重置时间(仅在 showTime 开启时有效)', defaultValue: false, }, { name: 'disabledDate', propType: 'func', description: '禁用日期函数\n@param {MomentObject} 日期值\n@param {String} view 当前视图类型,year: 年, month: 月, date: 日\n@return {Boolean} 是否禁用', }, { name: 'footerRender', propType: 'func', description: '自定义面板页脚\n@return {Node} 自定义的面板页脚组件', }, { name: 'onChange', propType: 'func', description: '日期范围值改变时的回调 [ MomentObject|String, MomentObject|String ]\n@param {Array} value 日期值', }, { name: 'onOk', propType: 'func', description: '点击确认按钮时的回调 返回开始时间和结束时间`[ MomentObject|String, MomentObject|String ]`\n@return {Array} 日期范围', }, { name: 'label', propType: 'string', description: '输入框内置标签', }, { name: 'state', propType: { type: 'oneOf', value: ['error', 'loading', 'success'], }, description: '输入框状态', }, { name: 'size', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '输入框尺寸', defaultValue: 'medium', }, { name: 'disabled', propType: 'bool', description: '是否禁用', }, { name: 'hasClear', propType: 'bool', description: '是否显示清空按钮', defaultValue: true, }, { name: 'visible', propType: 'bool', description: '弹层显示状态', }, { name: 'defaultVisible', propType: 'bool', description: '弹层默认是否显示', defaultValue: false, }, { name: 'onVisibleChange', propType: 'func', description: '弹层展示状态变化时的回调\n@param {Boolean} visible 弹层是否显示\n@param {String} type 触发弹层显示和隐藏的来源 okBtnClick 表示由确认按钮触发; fromTrigger 表示由trigger的点击触发; docClick 表示由document的点击触发', }, { name: 'popupTriggerType', propType: { type: 'oneOf', value: ['click', 'hover'], }, description: '弹层触发方式', defaultValue: 'click', }, { name: 'popupAlign', propType: 'string', description: '弹层对齐方式, 具体含义见 OverLay文档', defaultValue: 'tl tl', }, { name: 'popupContainer', propType: 'node', description: '弹层容器\n@param {Element} target 目标元素\n@return {Element} 弹层的容器元素', }, { name: 'popupClassName', propType: 'string', description: '弹层自定义样式类', }, { name: 'followTrigger', propType: 'bool', description: '是否跟随滚动', }, { name: 'startDateInputAriaLabel', propType: 'string', description: '开始日期输入框的 aria-label 属性', }, { name: 'startTimeInputAriaLabel', propType: 'string', description: '开始时间输入框的 aria-label 属性', }, { name: 'endDateInputAriaLabel', propType: 'string', description: '结束日期输入框的 aria-label 属性', }, { name: 'endTimeInputAriaLabel', propType: 'string', description: '结束时间输入框的 aria-label 属性', }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', }, { name: 'locale', propType: 'object', }, { name: 'className', propType: 'string', }, { name: 'name', propType: 'string', }, { name: 'popupComponent', propType: 'string', }, { name: 'popupContent', propType: 'node', }, { name: 'style', propType: 'object', }, ], configure: { supports: { style: true, events: ['onVisibleMonthChange', 'onChange', 'onOk', 'onVisibleChange'], }, props: [ { name: 'defaultValue', title: { label: '默认值', tip: '初始的日期范围值数组 [moment, moment]', }, setter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 0, title: '开始时间', setter: 'DateSetter', supportVariable: true, }, { name: 1, title: '结束时间', setter: 'DateSetter', supportVariable: true, }, ], }, }, }, }, { name: 'type', title: '日期类型', setter: { setter: 'RadioGroupSetter', supportVariable: true, props: { options: ['date', 'month', 'year'] }, }, description: '日期范围类型', defaultValue: 'date', }, { name: 'label', title: '内置标签', setter: 'StringSetter', supportVariable: true, description: '输入框内置标签', }, { name: 'state', title: '输入状态', setter: { setter: 'RadioGroupSetter', supportVariable: true, props: { options: ['error', 'loading', 'success'] }, }, description: '输入框状态', }, { name: 'size', title: '尺寸', setter: { setter: 'RadioGroupSetter', supportVariable: true, props: { options: ['small', 'medium', 'large'] }, }, description: '输入框尺寸', defaultValue: 'medium', }, { name: 'disabled', setter: 'BoolSetter', supportVariable: true, title: '是否禁用', }, { name: 'hasClear', setter: 'BoolSetter', supportVariable: true, title: '清空按钮', defaultValue: true, }, { name: 'defaultVisible', setter: 'BoolSetter', supportVariable: true, title: '显示弹层', defaultValue: false, }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', supportVariable: true, }, ], }, ], }, category: '信息输入', icon: '', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/rating/meta.design.ts ================================================ import snippets from './snippets'; export default { group: '原子组件', componentName: 'Rating', title: '评分', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Rating', main: '', destructuring: true, subName: '', }, props: [ { name: 'id', propType: 'string', }, { name: 'name', propType: 'string', description: 'name', }, { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, { name: 'defaultValue', propType: 'number', description: '默认值', defaultValue: 0, }, { name: 'value', propType: 'number', description: '值', }, { name: 'size', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '尺寸', defaultValue: 'medium', }, { name: 'count', propType: 'number', description: '评分的总数', defaultValue: 5, }, { name: 'showGrade', propType: 'bool', description: '是否显示 grade', defaultValue: false, }, { name: 'allowHalf', propType: 'bool', description: '是否允许半星评分', defaultValue: false, }, { name: 'disabled', propType: 'bool', description: '是否禁用', defaultValue: false, }, { name: 'rtl', propType: 'bool', }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', defaultValue: false, }, { name: 'renderPreview', propType: 'func', description: '预览态模式下渲染的内容', }, { name: 'readOnly', propType: 'bool', description: '是否为只读态,效果上同 disabeld', defaultValue: false, }, { name: 'onChange', propType: 'func', description: '用户点击评分时触发的回调\n@param {String} value 评分值', }, { name: 'onHoverChange', propType: 'func', description: '用户hover评分时触发的回调\n@param {String} value 评分值', }, ], configure: { props: [ { name: 'size', title: { label: { type: 'i18n', zh_CN: '按钮尺寸', en_US: 'Button Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 按钮尺寸', en_US: 'prop: size | description: button size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '小', value: 'small', }, { label: '中', value: 'medium', }, { label: '大', value: 'large', }, ], }, }, defaultValue: 'medium', }, { name: 'value', title: '当前值', setter: 'NumberSetter', }, { name: 'count', title: '评分总数', setter: 'NumberSetter', }, { name: 'showGrade', title: '显示分数', setter: 'BoolSetter', }, ], supports: { events: ['onChange', 'onHoverChange'], }, }, icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/rating/meta.ts ================================================ import snippets from './snippets'; export default { group: '原子组件', componentName: 'Rating', title: '评分', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Rating', main: '', destructuring: true, subName: '', }, props: [ { name: 'id', propType: 'string', }, { name: 'name', propType: 'string', description: 'name', }, { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, { name: 'defaultValue', propType: 'number', description: '默认值', defaultValue: 0, }, { name: 'value', propType: 'number', description: '值', }, { name: 'size', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '尺寸', defaultValue: 'medium', }, { name: 'count', propType: 'number', description: '评分的总数', defaultValue: 5, }, { name: 'showGrade', propType: 'bool', description: '是否显示 grade', defaultValue: false, }, { name: 'allowHalf', propType: 'bool', description: '是否允许半星评分', defaultValue: false, }, { name: 'disabled', propType: 'bool', description: '是否禁用', defaultValue: false, }, { name: 'rtl', propType: 'bool', }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', defaultValue: false, }, { name: 'renderPreview', propType: 'func', description: '预览态模式下渲染的内容', }, { name: 'readOnly', propType: 'bool', description: '是否为只读态,效果上同 disabeld', defaultValue: false, }, { name: 'onChange', propType: 'func', description: '用户点击评分时触发的回调\n@param {String} value 评分值', }, { name: 'onHoverChange', propType: 'func', description: '用户hover评分时触发的回调\n@param {String} value 评分值', }, ], configure: { props: [ { name: 'value', title: '当前值', setter: ['NumberSetter', 'ExpressionSetter'], }, { name: 'defaultValue', title: '默认值', setter: ['NumberSetter', 'ExpressionSetter'], }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 尺寸\n@enumdesc 小, 中, 大', en_US: 'prop: size | description: size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['small', 'medium', 'large'], }, }, defaultValue: 'medium', }, { name: 'count', title: '评分总数', setter: ['NumberSetter', 'ExpressionSetter'], }, { name: 'allowHalf', title: '半星评分', setter: ['BoolSetter', 'ExpressionSetter'], }, { name: 'showGrade', title: '显示分数', setter: ['BoolSetter', 'ExpressionSetter'], }, { name: 'readAs', title: '评分文案生成方法', display: 'block', setter: { componentName: 'FunctionSetter', // props: { // defaultActionName="readAs", // defaultCode=`function readAs(val) { // return val + 'source'; // }`, // } }, }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', supportVariable: true, }, ], }, { name: 'style', setter: { componentName: 'StyleSetter', }, }, ], supports: { events: ['onChange', 'onHoverChange'], }, }, icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/rating/snippets.ts ================================================ module.exports = [ { title: '评分', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_rating.png', schema: { componentName: 'Rating', props: { prefix: 'next-', count: 5, size: 'medium', }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/responsive-grid/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'ResponsiveGrid', title: '布局容器', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'ResponsiveGrid', main: '', destructuring: true, subName: '', }, props: [ { name: 'className', propType: 'any', }, { name: 'device', propType: { type: 'oneOf', value: ['phone', 'tablet', 'desktop'], }, description: '设备,用来做自适应,默认为PC', defaultValue: 'desktop', }, { name: 'columns', propType: 'number', description: '分为几列', defaultValue: 12, }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: true, }, props: [ { name: 'layout', title: '布局', defaultValue: '6:6', // setter: { // componentName: 'NewArraySetter', // props: { // itemSetter: { // componentName: 'NumberSetter', // } // } // }, setter: { componentName: 'StringSetter', }, extraProps: { setValue(target, value) { // 解析x:y:z的数据形式,排除不符合规范的传入 let arrValue = value.split(':'); arrValue = arrValue.filter((item) => { return item && item.trim(); // 去除空数组项 }); const flag = arrValue.find((item) => { return isNaN(Number(item)); }); if (flag) { return; } const { node } = target; node.children.mergeChildren( (child, index) => { child.setPropValue('colSpan', arrValue[index]); return index >= arrValue.length; }, (children) => { let l = children.length; const items = []; while (l++ < arrValue.length) { items.push({ componentName: 'ResponsiveGrid.Cell', props: { colSpan: arrValue[l - 1] || 1, }, }); } return items; }, null, ); }, }, }, { name: 'gap', title: '列间距', defaultValue: 0, setter: { componentName: 'MixedSetter', props: { setters: [ { componentName: 'NumberSetter', props: { defaultValue: 8, }, }, { componentName: 'JsonSetter', props: { defaultValue: [8, 4], }, }, 'ExpressionSetter', ], }, }, }, { name: 'dense', title: '紧密模式', defaultValue: false, setter: { componentName: 'MixedSetter', props: { setters: ['BoolSetter', 'ExpressionSetter'], }, }, }, { name: 'style', setter: { componentName: 'StyleSetter', }, }, ], }, icon: '', category: '布局容器类', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/responsive-grid-cell/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'ResponsiveGrid.Cell', title: '布局容器 Cell', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'ResponsiveGrid', main: '', destructuring: true, subName: 'Cell', }, props: [ { name: 'colSpan', propType: 'number', description: '横向,占据几列', }, { name: 'rowSpan', propType: 'number', description: '纵向,占据几行', }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: true, }, advanced: { // 这个函数返回false会报错... getResizingHandlers: (node) => { const currentNodeIndex = node.index; const parent = node.parent; if (!parent) return []; let layout = parent.getPropValue('layout'); if (!layout) return []; layout = layout.split(':').map((item) => parseInt(item, 10)); // 最后一个节点不允许拖拽 if (currentNodeIndex >= layout.length - 1) { return []; } return ['e']; }, callbacks: { onResizeStart: (e, currentNode) => { const { trigger } = e; let nodeIndex = currentNode.index; let startLayout = currentNode.parent.getPropValue('layout'); startLayout = startLayout.split(':').map((item) => parseInt(item, 10)); let eachWidth = currentNode.getRect().width / startLayout[nodeIndex]; // 暴露到currentNode节点上供onResize回调使用 currentNode.nodeIndex = nodeIndex; currentNode.startLayout = startLayout; currentNode.eachWidth = eachWidth; }, onResize: (e, currentNode) => { const { trigger, deltaX, deltaY } = e; const { nodeIndex, startLayout, eachWidth } = currentNode; let moveColumn = Math.round(deltaX / eachWidth); const layout = [...startLayout]; // 浅拷贝 if (moveColumn > 0) { moveColumn = Math.min(moveColumn, layout[nodeIndex + 1] - 1); } else { moveColumn = -Math.min(-moveColumn, layout[nodeIndex] - 1); } layout[nodeIndex] += moveColumn; layout[nodeIndex + 1] -= moveColumn; // 获取下一个节点实例 let nextNode = currentNode.parent.children.filter((c, index) => { return index === nodeIndex + 1; }); // 为当前节点设置colSpan属性 currentNode.setPropValue('colSpan', layout[nodeIndex]); // 为nextChild节点设置colSpan属性 if (nextNode && nextNode[0]) { nextNode[0].setPropValue('colSpan', layout[nodeIndex + 1]); } // 为父容器设置layout属性 currentNode.parent.setPropValue('layout', layout.join(':')); }, }, }, }, icon: '', category: '布局容器类', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/rich-text/meta.ts ================================================ module.exports = { componentName: 'RichText', title: '需求占位', npm: { package: '@alilc/lowcode-materials', version: 'latest', exportName: 'RichText', main: '', destructuring: true, subName: '', }, props: [ { name: 'style', propType: 'object', }, ], configure: { props: { override: [ { name: 'style', propType: 'object', }, { name: 'maxHeight', title: '最大高度', propType: 'number', setter: 'NumberSetter', description: '最大高度', }, { name: 'content', title: '需求内容', display: 'inline', supportVariable: true, setter: { componentName: 'EditSetter', props: { title: '编辑内容', }, }, }, ], }, }, advanced: { getResizingHandlers: () => { return ['e']; }, callbacks: { onResizeStart: (e, currentNode) => { const parent = currentNode.parent; if (parent) { const parentNode = parent.getDOMNode(); if (parentNode) { currentNode.parentRect = parentNode.getBoundingClientRect(); } } currentNode.beforeSpan = currentNode.getPropValue('colSpan') || 12; currentNode.startRect = currentNode.getRect(); }, onResize: (e, currentNode) => { const { deltaX } = e; const startWidth = currentNode.startRect ? currentNode.startRect.width : currentNode.beforeSpan * (currentNode.parentRect.width / 12); let width = startWidth + deltaX; if (!currentNode.startRect) { currentNode.startRect = { width, }; } width = Math.max(0, width); // 不能小于0 width = Math.min(width, currentNode.parentRect.width); // 不能大于父容器宽度 currentNode.getDOMNode().style['width'] = `${Math.round(width)}px`; }, onResizeEnd: (e, currentNode) => { currentNode.setPropValue('style.width', currentNode.getDOMNode().style['width']); }, }, }, icon: 'https://img.alicdn.com/imgextra/i3/O1CN01G7Lc8e1pZL7p4cdKc_!!6000000005374-2-tps-112-112.png', category: '基础元素', group: '精选组件', snippets: require('./snippets'), hidden: true, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/rich-text/snippets.ts ================================================ module.exports = [ { title: '需求占位', screenshot: 'https://img.alicdn.com/tfs/TB160cKkP39YK4jSZPcXXXrUFXa-112-64.png', schema: { title: '需求占位', componentName: 'RichText', props: { title: '需求占位描述', content: { subject: '需求标题', hideTitle: false, description: '

- 你可以在这里描述需求
- 或者粘贴需求截图

', }, }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/search/meta.design.ts ================================================ import snippets from './snippets.design'; export default { group: '原子组件', componentName: 'Search', title: '搜索', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Search', main: '', destructuring: true, subName: '', }, configure: { supports: { style: true, events: ['onChange', 'onSearch', 'onFilterChange'], }, props: [ { name: 'shape', title: { label: '模式', tip: 'shape|形状', }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '普通', value: 'normal', }, { label: '简单', value: 'simple', }, ], }, }, description: '形状', defaultValue: 'normal', }, { name: 'type', title: { label: '类型', tip: 'type|类型 shape=normal: primary/secondary; shape=simple: normal/dark;', }, setter: { componentName: 'SelectSetter', props: { options: [ { label: '普通', value: 'normal', }, { label: '主要', value: 'primary', }, { label: '次要', value: 'secondary', }, { label: '反底', value: 'dark', }, ], }, }, defaultValue: 'normal', }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '按钮尺寸', en_US: 'Button Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 按钮尺寸', en_US: 'prop: size | description: button size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '中', value: 'medium', }, { label: '大', value: 'large', }, ], }, }, defaultValue: 'medium', }, { name: 'disabled', title: '状态', setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '普通', value: false, }, { label: '禁用', value: true, }, ], }, }, defaultValue: false, }, { name: 'filter', title: '是否有菜单', defaultValue: false, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '否', value: false, }, { label: '是', value: [ { label: 'Products', value: 'Products', }, { label: 'Products1', value: 'Products1', }, { label: 'Products2', value: 'Products2', }, { label: 'Products3', value: 'Products3', }, { label: 'Products4', value: 'Products4', }, { label: 'Products5', value: 'Products5', }, { label: 'Products6', value: 'Products6', }, { label: 'Products7', value: 'Products7', }, { label: 'Products8', value: 'Products8', }, { label: 'Products9', value: 'Products9', }, { label: 'Products10', value: 'Products10', }, { label: 'Suppliers', value: 'Suppliers', }, ], }, ], }, }, }, { name: 'style.width', title: '宽度', setter: 'NumberSetter', }, { name: 'placeholder', title: '提示文字', setter: 'StringSetter', defaultValue: '请输入关键词', }, { name: 'searchText', title: '按钮文案', setter: 'StringSetter', description: 'button 的内容', }, ], }, icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/search/meta.ts ================================================ import snippets from './snippets'; export default { group: '原子组件', componentName: 'Search', title: '搜索', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Search', main: '', destructuring: true, subName: '', }, configure: { supports: { style: true, events: ['onChange', 'onSearch', 'onFilterChange'], }, props: [ { name: 'placeholder', title: '提示文字', setter: 'StringSetter', supportVariable: true, description: '默认提示', }, { name: 'defaultValue', title: '默认值', setter: 'StringSetter', supportVariable: true, description: '搜索框默认值', }, { name: 'searchText', title: '按钮文案', setter: 'StringSetter', supportVariable: true, description: 'button 的内容', }, { name: 'size', title: { label: '尺寸', tip: "size|'大', '小'", }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: 'large', value: 'large', }, { title: 'medium', value: 'medium', }, ], }, }, description: "大小\n@enumdesc '大', '小'", defaultValue: 'medium', }, { name: 'shape', title: { label: '形状', tip: 'shape|形状', }, setter: { componentName: 'RadioGroupSetter', props: { options: ['normal', 'simple'], }, }, description: '形状', defaultValue: 'normal', }, { name: 'type', title: { label: '类型', tip: 'type|类型 shape=normal: primary/secondary; shape=simple: normal/dark;', }, setter: { componentName: 'RadioGroupSetter', props: { options: ['primary', 'secondary', 'normal', 'dark'], }, }, description: '类型 shape=normal: primary/secondary; shape=simple: normal/dark;', defaultValue: 'normal', }, { name: 'hasClear', title: '清除按钮', setter: 'BoolSetter', supportVariable: true, description: '是否显示清除按钮', defaultValue: false, }, { name: 'hasIcon', title: '搜索图标', setter: 'BoolSetter', supportVariable: true, description: '是否显示搜索按钮', defaultValue: true, }, { name: 'disabled', title: '是否禁用', setter: 'BoolSetter', supportVariable: true, description: '是否禁用', defaultValue: false, }, { name: 'dataSource', display: 'block', title: { label: '搜索框下拉联想列表', tip: 'dataSource | 搜索框下拉联想列表', }, setter: { componentName: 'MixedSetter', props: { setters: ['JsonSetter', 'ExpressionSetter'], }, }, }, { name: 'filter', display: 'block', title: { label: '选择器数据', tip: 'filter|选择器数据', }, setter: { componentName: 'JsonSetter', }, }, { name: 'defaultFilterValue', display: 'block', title: '选择器默认值', setter: 'StringSetter', supportVariable: true, description: '选择器默认值', }, ], }, icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/search/snippets.design.ts ================================================ export default [ { title: '搜索', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_search.png', schema: { componentName: 'Search', props: { dataSource: [ { label: 'Recent', value: 'Recent', }, { label: 'dress', value: 'dress', }, { label: 'sunglasses', value: 'sunglasses', }, { label: 't-shirt', value: 't-shirt', }, ], followTrigger: true, searchText: '搜索', prefix: 'next-', shape: 'normal', type: 'normal', size: 'medium', hasIcon: true, }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/search/snippets.ts ================================================ export default [ { title: '搜索', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_search.png', schema: { componentName: 'Search', props: { dataSource: [ { label: 'Recent', value: 'Recent', }, { label: 'dress', value: 'dress', }, { label: 'sunglasses', value: 'sunglasses', }, { label: 't-shirt', value: 't-shirt', }, ], followTrigger: true, searchText: '搜索', prefix: 'next-', shape: 'normal', type: 'normal', size: 'medium', hasIcon: true, }, }, }, { title: '带分类', screenshot: 'https://img.alicdn.com/tfs/TB1rRaLu5_1gK0jSZFqXXcpaXXa-112-64.png', schema: { componentName: 'Search', props: { followTrigger: true, defaultFilterValue: 'Products', filter: [ { label: 'Products', value: 'Products', }, { label: 'Products1', value: 'Products1', }, ], dataSource: [ { label: 'Recent', value: 'Recent', }, { label: 'dress', value: 'dress', }, { label: 'sunglasses', value: 'sunglasses', }, { label: 't-shirt', value: 't-shirt', }, ], searchText: '搜索', prefix: 'next-', shape: 'normal', type: 'normal', size: 'medium', hasIcon: true, }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/select/meta.design.ts ================================================ import snippets from './snippets.design'; import parseData from '../utils/parse-data'; export default { group: '原子组件', componentName: 'Select', title: '选择器', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Select', main: '', destructuring: true, subName: '', }, configure: { component: { rootSelector: 'span.next-select', }, props: [ { name: 'mode', title: { label: '模式', tip: '属性: mode', }, setter: { componentName: 'RadioGroupSetter', props: { defaultValue: 'single', options: [ { value: 'single', title: '单选' }, { value: 'multiple', title: '多选' }, ], }, }, }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Button Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 按钮尺寸', en_US: 'prop: size | description: button size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '小', value: 'small', }, { label: '中', value: 'medium', }, { label: '大', value: 'large', }, ], }, }, defaultValue: 'medium', }, { name: 'visible', title: { label: '状态', tip: '属性: visible', }, setter: { componentName: 'RadioGroupSetter', props: { defaultValue: 'single', options: [ { value: false, title: '普通' }, { value: true, title: '展开' }, ], }, }, }, { name: 'hasBorder', title: { label: { type: 'i18n', zh_CN: '显示边框', en_US: 'ShowBorder', }, tip: { type: 'i18n', zh_CN: '属性: hasBorder | 说明: 是否有边框', en_US: 'prop: hasBorder | description: HasBorder', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '无', value: false, }, { label: '有', value: true, }, ], }, }, }, { name: 'style.width', title: '宽度', setter: 'NumberSetter', setValue: (target) => { const visible = target.parent.getPropValue('visible'); if (!visible) return; target.parent.setPropValue('visible', false); setTimeout(() => { target.parent.setPropValue('visible', true); }, 300); }, }, { name: 'label', title: { label: '内联文案', tip: 'label|输入框内置标签', }, setter: 'StringSetter', }, { name: 'placeholder', title: { label: '占位提示', tip: '属性: placeholder', }, defaultValue: '请选择', // 不生效 setter: 'StringSetter', }, { name: 'showSearch', title: { label: '可搜索', tip: '属性: showSearch', }, setter: 'BoolSetter', defaultValue: false, }, { name: 'disabled', title: '是否禁用', setter: 'BoolSetter', defaultValue: false, }, { name: 'plainData', display: 'block', title: '选项', tip: { title: '数据', url: '', }, setValue: (target, value) => { const list = parseData(value).filter(({ type }) => 'node' === type); const dataSource = []; const _value = []; list.forEach((item, index) => { dataSource.push({ label: item.value, value: index, disabled: item.state === 'disabled', }); if (item.state === 'active') { _value.push(index); } }); target.parent.setPropValue('dataSource', dataSource); target.parent.setPropValue('value', _value); }, setter: { componentName: 'MagicEditorSetter', props: { toolbar: ['normal', 'active', 'disable'], disableIcon: true, }, }, }, ], supports: { style: true, events: [ { name: 'onChange', propType: 'func', description: '值发生变化', }, { name: 'onVisibleChange', propType: 'func', description: '弹层显示隐藏变化', }, { name: 'onRemove', propType: 'func', description: 'Tag 被删除', }, { name: 'onSearch', propType: 'func', description: '搜索', }, ], }, }, icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/select/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Select', title: '选择器', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Select', main: '', destructuring: true, subName: '', }, props: [ { name: 'placeholder', title: { label: '占位提示', tip: '属性: placeholder', }, defaultValue: '请选择', // 不生效 propType: 'string', }, { name: 'defaultValue', title: { label: '默认值', tip: '属性: defaultValue', }, propType: 'string', }, { name: 'mode', propType: { type: 'oneOf', value: ['single', 'multiple', 'tag'], }, description: '选择器模式', }, { name: 'hasClear', title: { label: '清除按钮', tip: '属性: hasClear', }, propType: 'bool', defaultValue: false, }, { name: 'showSearch', title: { label: '可搜索', tip: '属性: showSearch', }, propType: 'bool', defaultValue: false, }, { name: 'dataSource', }, { type: 'group', title: '其他配置', display: 'block', items: [ { name: 'notFoundContent', title: { label: '空文案', tip: 'notFoundContent|弹层内容为空的文案', }, setter: 'StringSetter', supportVariable: true, description: '弹层内容为空的文案', }, { name: 'hasBorder', title: { label: '边框', tip: '是否有边框', }, propType: 'bool', setter: 'BoolSetter', supportVariable: true, description: '是否有边框', }, { name: 'autoWidth', title: '下拉等宽', propType: 'bool', setter: 'BoolSetter', supportVariable: true, }, { name: 'hasArrow', title: '下拉箭头', propType: 'bool', setter: 'BoolSetter', supportVariable: true, description: '是否有下拉箭头', defaultValue: true, }, ], }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', supportVariable: true, }, ], }, ], configure: { props: { isExtends: true, override: [ { name: 'dataSource', display: 'block', title: '选项', tip: { title: '数据格式', url: '', }, setter: { componentName: 'MixedSetter', props: { setters: [ { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'label', title: 'label', setter: 'StringSetter', supportVariable: true, }, { name: 'value', title: 'value', setter: 'StringSetter', supportVariable: true, }, ], }, }, initialValue: { title: 'Title', }, }, }, }, 'ExpressionSetter', ], }, }, }, { name: 'mode', title: { label: '模式', tip: '属性: mode', }, setter: { componentName: 'RadioGroupSetter', props: { defaultValue: 'single', options: [ { value: 'single', title: '单选' }, { value: 'multiple', title: '多选' }, { value: 'tag', title: '标签' }, ], }, }, }, ], }, supports: { style: true, events: [ { name: 'onChange', propType: 'func', description: '值发生变化', }, { name: 'onVisibleChange', propType: 'func', description: '弹层显示隐藏变化', }, { name: 'onRemove', propType: 'func', description: 'Tag 被删除', }, { name: 'onSearch', propType: 'func', description: '搜索', }, ], }, }, icon: '', category: '信息输入', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/select/snippets.design.ts ================================================ import parseData from '../utils/parse-data'; const plainData = 'Option 1\n*Option 2\nOption 3\nOption 4\nOption 5'; const list = parseData(plainData).filter(({ type }) => 'node' === type); const dataSource = []; const value = []; list.forEach((item, index) => { dataSource.push({ label: item.value, value: index, disabled: item.state === 'disabled', }); if (item.state === 'active') { value.push(index); } }); export default [ { title: '选择器', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_select.png', schema: { componentName: 'Select', props: { mode: 'single', hasArrow: true, cacheValue: true, visible: true, plainData, dataSource, value, }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/select/snippets.ts ================================================ module.exports = [ { title: '选择器', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_select.png', schema: { componentName: 'Select', props: { mode: 'single', hasArrow: true, cacheValue: true, dataSource: [ { value: '1', label: '选项1', }, { value: '2', label: '选项2', }, { value: '3', label: '选项3', }, ], }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/select-option/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Select.Option', title: 'Select.Option', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Select', main: '', destructuring: true, subName: 'Option', }, props: [ { name: 'value', propType: 'string', description: '选项值', defaultValue: 'test', }, { name: 'disabled', propType: 'bool', description: '是否禁用', defaultValue: false, }, ], configure: { component: { isContainer: true, }, }, icon: '', category: '信息输入', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/slider/meta.design.ts ================================================ import snippets from './snippets'; export default { group: '原子组件', componentName: 'Slider', title: '图片轮播', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Slider', main: '', destructuring: true, subName: '', }, configure: { component: { isContainer: true, }, props: [ { name: 'slideDirection', title: { label: '轮播方向', tip: 'slideDirection', }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '水平', value: 'hoz', }, { label: '垂直', value: 'ver', }, ], }, }, description: '轮播方向', defaultValue: 'hoz', }, { name: 'speed', title: { label: '轮播速度', tip: 'speed', }, setter: 'NumberSetter', description: '轮播速度', defaultValue: 600, }, { name: 'arrows', title: { label: '箭头', tip: 'arrows|是否显示箭头', }, setter: 'BoolSetter', description: '是否显示箭头', defaultValue: true, }, { name: 'arrowSize', title: { label: '箭头大小', tip: "arrowSize|导航箭头大小 可选值: 'medium', 'large'", }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '中', value: 'medium', }, { label: '大', value: 'large', }, ], }, }, description: "导航箭头大小 可选值: 'medium', 'large'", defaultValue: 'medium', }, { name: 'arrowPosition', title: { label: '箭头位置', tip: "arrowPosition|导航箭头位置 可选值: 'inner', 'outer'", }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '内', value: 'inner', }, { label: '外', value: 'outter', }, ], }, }, description: "导航箭头位置 可选值: 'inner', 'outer'", defaultValue: 'inner', }, { name: 'dots', title: { label: '导航锚点', tip: 'dots|是否显示导航锚点', }, setter: 'BoolSetter', description: '是否显示导航锚点', defaultValue: true, }, { name: 'dotsDirection', title: { label: '导航锚点位置', tip: 'dotsDirection', }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '水平', value: 'hoz', }, { label: '垂直', value: 'ver', }, ], }, }, description: '导航锚点位置', defaultValue: 'hoz', }, { name: 'style.width', title: '宽度', setter: 'NumberSetter', }, { name: 'style.height', title: '高度', setter: 'NumberSetter', }, { name: 'slidesToShow', title: { label: '图片数量', tip: 'slidesToShow|同时展示的图片数量', }, setter: 'NumberSetter', description: '同时展示的图片数量', defaultValue: 1, }, ], }, icon: '', category: '信息展示', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/slider/meta.ts ================================================ import snippets from './snippets'; export default { group: '原子组件', componentName: 'Slider', title: '图片轮播', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Slider', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'rtl', propType: 'bool', defaultValue: false, }, { name: 'className', propType: 'any', description: '自定义传入的样式', }, { name: 'slidesToShow', title: { label: '图片数量', tip: 'slidesToShow|同时展示的图片数量', }, propType: 'number', description: '同时展示的图片数量', defaultValue: 1, }, { name: 'slidesToScroll', title: { label: '同时滑动的图片数量', tip: 'slidesToScroll', }, propType: 'number', description: '同时滑动的图片数量', defaultValue: 1, }, { name: 'speed', title: { label: '轮播速度', tip: 'speed', }, propType: 'number', description: '轮播速度', defaultValue: 600, }, { name: 'activeIndex', title: { label: '指定轮播图', tip: 'activeIndex|跳转到指定的轮播图(受控)', }, propType: 'number', description: '跳转到指定的轮播图(受控)', }, { name: 'adaptiveHeight', title: { label: '自适应高度', tip: 'adaptiveHeight', }, propType: 'bool', description: '是否使用自适应高度', defaultValue: false, }, { name: 'animation', title: { label: '动效类型', tip: 'animation', }, propType: { type: 'oneOfType', value: ['string', 'bool'], }, description: "动效类型,默认是'slide'", defaultValue: 'slide', }, { name: 'arrows', title: { label: '箭头', tip: 'arrows|是否显示箭头', }, propType: 'bool', description: '是否显示箭头', defaultValue: true, }, { name: 'arrowSize', title: { label: '箭头大小', tip: "arrowSize|导航箭头大小 可选值: 'medium', 'large'", }, propType: { type: 'oneOf', value: ['medium', 'large'], }, description: "导航箭头大小 可选值: 'medium', 'large'", defaultValue: 'medium', }, { name: 'arrowPosition', title: { label: '箭头位置', tip: "arrowPosition|导航箭头位置 可选值: 'inner', 'outer'", }, propType: { type: 'oneOf', value: ['inner', 'outer'], }, description: "导航箭头位置 可选值: 'inner', 'outer'", defaultValue: 'inner', }, { name: 'arrowDirection', title: { label: '箭头方向', tip: "arrowDirection|导航箭头的方向 可选值: 'hoz', 'ver'", }, propType: { type: 'oneOf', value: ['hoz', 'ver'], }, description: "导航箭头的方向 可选值: 'hoz', 'ver'", defaultValue: 'hoz', }, { name: 'autoplay', title: { label: '自动播放', tip: 'autoplay', }, propType: 'bool', description: '是否自动播放', defaultValue: false, }, { name: 'autoplaySpeed', title: { label: '自动播放的速度', tip: 'autoplaySpeed, 默认 3000 毫秒', }, propType: 'number', description: '自动播放的速度', defaultValue: 3000, }, { name: 'nextArrow', propType: 'node', description: '向后箭头', defaultValue: null, }, { name: 'prevArrow', propType: 'node', description: '向前箭头', defaultValue: null, }, { name: 'centerMode', title: { label: '居中模式', tip: 'centerMode', }, propType: 'bool', description: '是否启用居中模式', defaultValue: false, }, { name: 'dots', title: { label: '导航锚点', tip: 'dots|是否显示导航锚点', }, propType: 'bool', description: '是否显示导航锚点', defaultValue: true, }, { name: 'dotsDirection', title: { label: '导航锚点位置', tip: 'dotsDirection', }, propType: { type: 'oneOf', value: ['hoz', 'ver'], }, description: '导航锚点位置', defaultValue: 'hoz', }, { name: 'draggable', title: { label: '可拖拽', tip: 'draggable', }, propType: 'bool', description: '是否可拖拽', defaultValue: true, }, { name: 'infinite', title: { label: '无穷循环', tip: 'infinite', }, propType: 'bool', description: '是否使用无穷循环模式', defaultValue: true, }, { name: 'defaultActiveIndex', title: { label: '初始轮播图', tip: 'defaultActiveIndex|初始被激活的轮播图', }, propType: 'number', description: '初始被激活的轮播图', defaultValue: 0, }, { name: 'lazyLoad', title: { label: '懒加载', tip: 'lazyLoad|是否启用懒加载', }, propType: 'bool', description: '是否启用懒加载', defaultValue: false, }, { name: 'slideDirection', title: { label: '轮播方向', tip: 'slideDirection', }, propType: { type: 'oneOf', value: ['hoz', 'ver'], }, description: '轮播方向', defaultValue: 'hoz', }, { name: 'triggerType', title: { label: '触发方式', tip: 'triggerType|锚点导航触发方式', }, propType: { type: 'oneOf', value: ['click', 'hover'], }, description: '锚点导航触发方式', defaultValue: 'click', }, { name: 'onChange', propType: 'func', description: '轮播切换的回调函数\n@param {Number} index 幻灯片的索引', }, { name: 'onBeforeChange', propType: 'func', }, { name: 'style', propType: 'object', description: '自定义传入的class', defaultValue: null, }, { name: 'focusOnSelect', title: { label: '自动居中', tip: 'focusOnSelect|多图轮播时,点击选中后自动居中', }, propType: 'bool', description: '多图轮播时,点击选中后自动居中', defaultValue: false, }, ], configure: { component: { isContainer: true, }, props: { isExtends: true, override: [ { name: 'rtl', condition: () => false, }, { name: 'prefix', condition: () => false, }, ], }, }, icon: '', category: '信息展示', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/slider/snippets.ts ================================================ export default [ { title: '图片轮播', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_slider.png', schema: { componentName: 'Slider', props: { prefix: 'next-', animation: 'slide', arrows: true, arrowSize: 'medium', arrowPosition: 'inner', arrowDirection: 'hoz', autoplaySpeed: 3000, dots: true, dotsDirection: 'hoz', draggable: true, infinite: true, slide: 'div', slideDirection: 'hoz', slidesToShow: 1, slidesToScroll: 1, speed: 600, triggerType: 'click', centerPadding: '50px', cssEase: 'ease', edgeFriction: 0.35, swipe: true, touchMove: true, touchThreshold: 5, useCSS: true, waitForAnimate: true, }, children: [ { componentName: 'Image', props: { src: 'https://img.alicdn.com/tps/TB1bewbNVXXXXc5XXXXXXXXXXXX-1000-300.png', }, }, { componentName: 'Image', props: { src: 'https://img.alicdn.com/tps/TB1xuUcNVXXXXcRXXXXXXXXXXXX-1000-300.jpg', }, }, { componentName: 'Image', props: { src: 'https://img.alicdn.com/tps/TB1ikP.NVXXXXaYXpXXXXXXXXXX-1000-300.jpg', }, }, { componentName: 'Image', props: { src: 'https://img.alicdn.com/tps/TB1s1_JNVXXXXbhaXXXXXXXXXXX-1000-300.jpg', }, }, ], }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/slot/meta.ts ================================================ module.exports = { componentName: 'Slot', npm: { package: '@alilc/lowcode-materials', version: 'latest', exportName: 'Slot', main: '', destructuring: true, subName: '', }, configure: { props: [ { name: '___title', title: { type: 'i18n', 'en-US': 'Slot Title', 'zh-CN': '插槽标题', }, setter: 'StringSetter', defaultValue: '插槽容器', }, { name: '___params', title: { type: 'i18n', 'en-US': 'Slot Params', 'zh-CN': '插槽入参', }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'StringSetter', props: { placeholder: { type: 'i18n', 'zh-CN': '参数名称', 'en-US': 'Argument Name', }, }, }, }, }, }, ], component: { isContainer: true, disableBehaviors: '*', }, // events/className/style/general/directives supports: false, advanced: { callbacks: { onHoverHook: () => false, onMouseDownHook: () => false, onClickHook: () => false, }, }, }, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/slot/view.tsx ================================================ import { Component } from 'react'; class Slot extends Component { static displayName = 'Slot'; static componentMetadata = { componentName: 'Slot', configure: { props: [ { name: '___title', title: { type: 'i18n', 'en-US': 'Slot Title', 'zh-CN': '插槽标题', }, setter: 'StringSetter', defaultValue: '插槽容器', }, { name: '___params', title: { type: 'i18n', 'en-US': 'Slot Params', 'zh-CN': '插槽入参', }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'StringSetter', props: { placeholder: { type: 'i18n', 'zh-CN': '参数名称', 'en-US': 'Argument Name', }, }, }, }, }, }, ], component: { isContainer: true, }, // events/className/style/general/directives supports: false, }, }; render() { const { children } = this.props; return <>{children}; } } export default Slot; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/split-button/adaptor.ts ================================================ import parseData from '../utils/parse-data'; export const createDataSource = ( list, keys = { selected: [], expanded: {} }, level = 0, prefix = '', ) => { const array = []; let group = []; let grouping = false; let index = 0; list.forEach((item) => { switch (item.type) { // eslint-disable-next-line no-case-declarations case 'node': const key = `${prefix || level}-${index++}`; if (item.children && item.children.length > 0) { item.children = createDataSource(item.children, keys, level + 1, key); } if (grouping) { group.push({ ...item, key, }); } else { array.push({ ...item, key, }); } if (item.state === 'active') { if (item.children && item.children.length > 0) { keys.expanded.push(key); } else { keys.selected.push(key); } } return; case 'comment': if (group.length > 0) { array.push({ type: 'group', value: grouping, children: group, key: `${prefix || level}-${index++}`, }); group = []; } grouping = item.value; return; case 'divider': if (group.length > 0) { array.push({ type: 'group', value: grouping, children: group, key: `${prefix || level}-${index++}`, }); group = []; } grouping = false; array.push({ type: 'divider', key: `${prefix || level}-${index++}`, }); default: } }); if (group.length > 0) { array.push({ type: 'group', value: grouping, children: group, key: `${prefix || level}-${index++}`, }); group = []; } return array; }; const createMenuItem = (item) => { if (item.children.length > 0) { // return ( // type === ContentType.text).map(({ value }) => value).join('') : ''}> // {createContents(item.children)} // // ); return { componentName: 'SubMenu', props: { key: item.key, disabled: item.state === 'disabled', label: item.value ? item.value .filter(({ type }) => type === 'text') .map(({ value }) => value) .join('') : '', }, children: createContents(item.children), }; } // return type === 'icon' ? : value)} />; return { componentName: 'Menu.Item', props: { key: item.key, checked: item.state === 'active', disabled: item.state === 'disabled', }, children: item.value.map(({ type, value }, index) => type === 'icon' ? { componentName: 'Icon', props: { disabled: true, key: `icon_${index}`, type: value, size: 'small', style: { marginRight: '4px' }, }, } : { componentName: 'Typography.Text', props: { children: value, style: { color: 'inherit', }, }, }, ), }; }; export const createContents = (array = []) => { return array.map((item) => { if (item.type === 'group' && item.children.length > 0) { // return {item.children.map(it => createMenuItem(it))}; return { componentName: 'Menu.Group', props: { key: item.key, label: item.value, }, children: item.children.map((it) => createMenuItem(it)), }; } if (item.type === 'divider') { // return ; return { componentName: 'Menu.Divider', props: { key: item.key, }, }; } return createMenuItem(item); }); }; function getButtonLabel(buttonItem) { if (buttonItem.type !== 'node') return {}; // return buttonItem.value.find(item => item.type === 'text').value; // FIXME: 渲染时 JSSlot 有问题,暂时不要 icon return { label: { type: 'JSSlot', value: buttonItem.value.map(({ type, value }) => { if (type === 'icon') return { componentName: 'Icon', props: { disabled: true, type: value, size: 'small', style: { marginRight: '4px' }, }, }; return { componentName: 'Typography.Text', props: { children: value, style: { color: 'inherit', }, }, }; }), }, disabled: buttonItem?.state === 'disabled', }; } export function getDataFromPlainText(value) { const keys = { selected: [], expanded: [] }; const list = parseData(value, { parseContent: true }); const buttonItem = list[0] ? list[0] : { value: [] }; const { label, disabled } = getButtonLabel(buttonItem); const dataSource = createDataSource(list[0] ? list[0].children : [], keys); const children = createContents(dataSource); return { label, disabled, children, selectedKeys: keys.selected }; } // const _propsValue = ({ shape, level, size, data, ...others}) =>{ // const list = parseData(data, { parseContent: true }); // const buttonItem = list[0] ? list[0] : { value: []}; // const keys = { selected: [], expanded: [] }; // if (buttonItem.type !== 'node') return null; // const label = buttonItem.value.map(({ type, value}) => { // if (type === 'icon') return ; // return value; // }); // return { // ...others, // size, // disabled: buttonItem.state === 'disabled', // visible: buttonItem.state === 'active', // type: shape === 'ghost' ? 'normal' : level, // popupProps: { needAdjust: false, container: node => node }, // ghost: shape === 'ghost' ? level : false, // selectMode: "multiple", // menuProps: { openKeys: keys.expanded, style: { textAlign: 'left' } }, // selectedKeys: keys.selected, // label: label // }; // }; // export default { // name: 'SplitButton', // shape: ['normal', 'ghost'], // editor: (shape = 'normal') => ({ // props: [{ // name: 'level', // type: Types.enum, // options: shape === 'ghost' ? ['light', 'dark'] : ['normal', 'primary', 'secondary'], // default: shape === 'ghost' ? 'light' : 'normal', // }, { // name: 'size', // type: Types.enum, // options: ['large', 'medium', 'small'], // default: 'medium' // }], // data: { // icon: true, // active: true, // disable: true, // default: 'Edit Document\n\tUndo\n\t*Redo\n\tCut\n\tCopy\n\tPaste' // } // }), // propsValue: _propsValue, // adaptor: (args) => { // const list = parseData(args.data, { parseContent: true }); // const keys = { selected: [], expanded: [] }; // const dataSouce = createDataSource(list[0] ? list[0].children : [], keys); // const props = _propsValue(args); // return ( // // {createContents(dataSouce)} // // ); // }, // demoOptions: (demo) => { // const { node = { props: {} } } = demo; // const { level, data } = node.props; // if (data.indexOf('*') === 0) { // demo = { // ...demo, // height: 250 // }; // } // if (level === 'dark') { // demo = { // ...demo, // background: '#333' // }; // } else if(level === 'light') { // demo = { // ...demo, // background: 'rgb(235, 236, 240)', // }; // } // return demo; // } // }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/split-button/meta.design.ts ================================================ import { getDataFromPlainText } from './adaptor'; export default { group: '原子组件', componentName: 'SplitButton', title: '分隔按钮', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'SplitButton', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'style', propType: 'object', }, { name: 'label', propType: { type: 'instanceOf', value: 'node', }, description: '主按钮的文案', }, { name: 'type', title: '按钮类型', propType: { type: 'oneOf', value: ['normal', 'primary', 'secondary'], }, description: '按钮的类型', defaultValue: 'normal', }, { name: 'size', title: '按钮尺寸', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '按钮组的尺寸', defaultValue: 'medium', }, { name: 'component', title: '标签类型', propType: { type: 'oneOf', value: ['button', 'a'], }, defaultValue: 'button', description: '设置标签类型', }, { name: 'ghost', title: '幽灵按钮', propType: { type: 'oneOf', value: ['light', 'dark', false, true], }, description: '是否为幽灵按钮', }, { name: 'defaultSelectedKeys', propType: { type: 'instanceOf', value: 'array', }, description: '默认激活的菜单项(用法同 Menu 非受控)', defaultValue: [], }, { name: 'selectedKeys', propType: { type: 'instanceOf', value: 'array', }, description: '激活的菜单项(用法同 Menu 受控)', }, { name: 'selectMode', title: '单选多选', propType: { type: 'oneOf', value: ['single', 'multiple'], }, defaultValue: 'single', description: '菜单的选择模式', }, { name: 'onSelect', propType: 'func', description: '选择菜单项时的回调,参考 Menu', }, { name: 'onItemClick', propType: 'func', description: '点击菜单项时的回调,参考 Menu', }, { name: 'triggerProps', propType: 'object', description: '触发按钮的属性(支持 Button 的所有属性透传)', }, { name: 'onVisibleChange', propType: 'func', description: '弹层显示状态变化时的回调函数\n@param {Boolean} visible 弹层显示状态\n@param {String} type 触发弹层显示或隐藏的来源 menuSelect 表示由menu触发; fromTrigger 表示由trigger的点击触发; docClick 表示由document的点击触发', }, { name: 'popupTriggerType', title: '弹层触发', propType: { type: 'oneOf', value: ['click', 'hover'], }, description: '弹层的触发方式', defaultValue: 'click', }, { name: 'popupAlign', title: '弹层对齐', propType: 'string', description: '弹层对齐方式, 详情见Overlay align', }, { name: 'popupStyle', propType: 'object', description: '弹层自定义样式', }, { name: 'popupClassName', propType: 'string', description: '弹层自定义样式类', }, { name: 'popupProps', propType: 'object', description: '透传给弹层的属性', }, { name: 'autoWidth', title: '自动宽度', propType: 'bool', description: '弹层菜单的宽度是否与按钮组一致', defaultValue: true, }, { name: 'visible', propType: 'bool', description: '弹层是否显示', }, { name: 'defaultVisible', title: '默认显示', defaultValue: true, propType: 'bool', description: '弹层默认是否显示', }, { name: 'followTrigger', title: '跟随滚动', propType: 'bool', description: '是否跟随滚动', }, { name: 'menuProps', propType: 'object', description: '透传给 Menu 的属性', }, { name: 'leftButtonProps', propType: 'object', description: '透传给 左侧按钮 的属性', }, { name: 'className', propType: 'string', }, ], configure: { component: { isContainer: true, isMinimalRenderUnit: true, }, props: [ { name: '!type', title: { type: 'i18n', zh_CN: '类型', en_US: 'type', }, getValue: (target) => { const parentTarget = target.parent; const ghostConfig = parentTarget.getPropValue('ghost'); if (ghostConfig) { return 'ghost'; } else { return 'normal'; } }, setValue: (target, value) => { const parentTarget = target.parent; parentTarget.setPropValue('ghost', false); switch (value) { case 'normal': break; case 'ghost': parentTarget.setPropValue('ghost', 'light'); break; default: break; } }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '普通按钮', value: 'normal', }, { title: '幽灵按钮', value: 'ghost', }, ], }, }, defaultValue: 'normal', }, { name: 'ghost', title: { label: { type: 'i18n', zh_CN: '形式', en_US: 'Button Type', }, tip: { type: 'i18n', zh_CN: '属性: type | 说明: 按钮类型', en_US: 'prop: type | description: button type', }, }, defaultValue: 'light', condition: (target) => target?.parent?.getPropValue('!type') === 'ghost', setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: 'Light', value: 'light', }, { label: 'Dark', value: 'dark', }, ], }, }, }, { name: 'type', title: { label: { type: 'i18n', zh_CN: '形式', en_US: 'Button Type', }, tip: { type: 'i18n', zh_CN: '属性: type | 说明: 按钮类型', en_US: 'prop: type | description: button type', }, }, condition: (target) => target?.parent?.getPropValue('!type') !== 'ghost', setter: { componentName: 'RadioGroupSetter', props: { options: [ { value: 'normal', label: '普通', }, { value: 'primary', label: '主要', }, { value: 'secondary', label: '次要', }, ], }, }, defaultValue: 'normal', }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Button Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 按钮尺寸', en_US: 'prop: size | description: button size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '小', value: 'small', }, { label: '中', value: 'medium', }, { label: '大', value: 'large', }, ], }, }, defaultValue: 'medium', }, { name: 'plainData', display: 'block', title: '选项', tip: { title: '数据格式', url: '', }, setValue: (target, value) => { const { label, disabled, children, selectedKeys } = getDataFromPlainText(value); if (label) { target.parent.setPropValue('label', label); } if (typeof disabled !== 'undefined') { target.parent.setPropValue('disabled', disabled); } if (children) { target.node.children.importSchema(children); } if (selectedKeys) { target.parent.setPropValue('selectedKeys', selectedKeys); } }, setter: { componentName: 'MagicEditorSetter', props: { toolbar: ['normal', 'disable', 'group'], }, }, }, ], }, icon: '', category: '常用', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/split-button/meta.ts ================================================ import { getDataFromPlainText } from './adaptor'; export default { group: '原子组件', componentName: 'SplitButton', title: '分隔按钮', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'SplitButton', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'style', propType: 'object', }, { name: 'label', propType: { type: 'instanceOf', value: 'node', }, description: '主按钮的文案', }, { name: 'type', title: '按钮类型', propType: { type: 'oneOf', value: ['normal', 'primary', 'secondary'], }, description: '按钮的类型', defaultValue: 'normal', }, { name: 'size', title: '按钮尺寸', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '按钮组的尺寸', defaultValue: 'medium', }, { name: 'component', title: '标签类型', propType: { type: 'oneOf', value: ['button', 'a'], }, defaultValue: 'button', description: '设置标签类型', }, { name: 'ghost', title: '幽灵按钮', propType: { type: 'oneOf', value: ['light', 'dark', false, true], }, description: '是否为幽灵按钮', }, { name: 'defaultSelectedKeys', propType: { type: 'instanceOf', value: 'array', }, description: '默认激活的菜单项(用法同 Menu 非受控)', defaultValue: [], }, { name: 'selectedKeys', propType: { type: 'instanceOf', value: 'array', }, description: '激活的菜单项(用法同 Menu 受控)', }, { name: 'selectMode', title: '单选多选', propType: { type: 'oneOf', value: ['single', 'multiple'], }, defaultValue: 'single', description: '菜单的选择模式', }, { name: 'onSelect', propType: 'func', description: '选择菜单项时的回调,参考 Menu', }, { name: 'onItemClick', propType: 'func', description: '点击菜单项时的回调,参考 Menu', }, { name: 'triggerProps', propType: 'object', description: '触发按钮的属性(支持 Button 的所有属性透传)', }, { name: 'onVisibleChange', propType: 'func', description: '弹层显示状态变化时的回调函数\n@param {Boolean} visible 弹层显示状态\n@param {String} type 触发弹层显示或隐藏的来源 menuSelect 表示由menu触发; fromTrigger 表示由trigger的点击触发; docClick 表示由document的点击触发', }, { name: 'popupTriggerType', title: '弹层触发', propType: { type: 'oneOf', value: ['click', 'hover'], }, description: '弹层的触发方式', defaultValue: 'click', }, { name: 'popupAlign', title: '弹层对齐', propType: 'string', description: '弹层对齐方式, 详情见Overlay align', }, { name: 'popupStyle', propType: 'object', description: '弹层自定义样式', }, { name: 'popupClassName', propType: 'string', description: '弹层自定义样式类', }, { name: 'popupProps', propType: 'object', description: '透传给弹层的属性', }, { name: 'autoWidth', title: '自动宽度', propType: 'bool', description: '弹层菜单的宽度是否与按钮组一致', defaultValue: true, }, { name: 'visible', propType: 'bool', description: '弹层是否显示', }, { name: 'defaultVisible', title: '默认显示', defaultValue: true, propType: 'bool', description: '弹层默认是否显示', }, { name: 'followTrigger', title: '跟随滚动', propType: 'bool', description: '是否跟随滚动', }, { name: 'menuProps', propType: 'object', description: '透传给 Menu 的属性', }, { name: 'leftButtonProps', propType: 'object', description: '透传给 左侧按钮 的属性', }, { name: 'className', propType: 'string', }, ], configure: { component: { isContainer: true, isMinimalRenderUnit: true, }, props: [ { name: '!type', title: { type: 'i18n', zh_CN: '类型', en_US: 'type', }, getValue: (target) => { const parentTarget = target.parent; const ghostConfig = parentTarget.getPropValue('ghost'); if (ghostConfig) { return 'ghost'; } else { return 'normal'; } }, setValue: (target, value) => { const parentTarget = target.parent; parentTarget.setPropValue('ghost', false); switch (value) { case 'normal': break; case 'ghost': parentTarget.setPropValue('ghost', 'light'); break; default: break; } }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '普通按钮', value: 'normal', }, { title: '幽灵按钮', value: 'ghost', }, ], }, }, defaultValue: 'normal', }, { name: 'ghost', title: { label: { type: 'i18n', zh_CN: '形式', en_US: 'Button Type', }, tip: { type: 'i18n', zh_CN: '属性: type | 说明: 按钮类型', en_US: 'prop: type | description: button type', }, }, defaultValue: 'light', condition: (target) => target?.parent?.getPropValue('!type') === 'ghost', setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: 'Light', value: 'light', }, { label: 'Dark', value: 'dark', }, ], }, }, }, { name: 'type', title: { label: { type: 'i18n', zh_CN: '形式', en_US: 'Button Type', }, tip: { type: 'i18n', zh_CN: '属性: type | 说明: 按钮类型', en_US: 'prop: type | description: button type', }, }, condition: (target) => target?.parent?.getPropValue('!type') !== 'ghost', setter: { componentName: 'RadioGroupSetter', props: { options: [ { value: 'normal', label: '普通', }, { value: 'primary', label: '主要', }, { value: 'secondary', label: '次要', }, ], }, }, defaultValue: 'normal', }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Button Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 按钮尺寸', en_US: 'prop: size | description: button size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '小', value: 'small', }, { label: '中', value: 'medium', }, { label: '大', value: 'large', }, ], }, }, defaultValue: 'medium', }, { name: 'plainData', display: 'block', title: '选项', tip: { title: '数据格式', url: '', }, setValue: (target, value) => { const { label, disabled, children, selectedKeys } = getDataFromPlainText(value); if (label) { target.parent.setPropValue('label', label); } if (typeof disabled !== 'undefined') { target.parent.setPropValue('disabled', disabled); } if (children) { target.node.children.importSchema(children); } if (selectedKeys) { target.parent.setPropValue('selectedKeys', selectedKeys); } }, setter: { componentName: 'MagicEditorSetter', props: { toolbar: ['normal', 'disable', 'group'], }, }, }, ], }, icon: '', category: '常用', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/step/adaptor.ts ================================================ import parseData from '../utils/parse-data'; export const createDataSource = (data: any, props) => { const list = parseData(data, { parseContent: true }); const dataSource = []; list.forEach((item, index) => { const { value = '' } = item.value.find(({ type }) => type === 'icon') || {}; dataSource.push({ key: index, icon: value, title: item.value .filter(({ type }) => type === 'text') .map(({ value }) => value) .join(''), content: item.children && item.children.length > 0 ? item.children[0].value .filter(({ type }) => type === 'text') .map(({ value }) => value) .join('') : '', disabled: item.state === 'disabled', }); if (item.state === 'active') { props.current = index; } }); return dataSource; }; function createContents(dataSource) { //dataSouce.map(item => ) return dataSource.map((item) => { return { componentName: 'Step.Item', props: item, }; }); } export function getDataFromPlainText(value) { const props = { current: 0 }; const dataSource = createDataSource(value, props); const children = createContents(dataSource); return { children, ...props }; } // const _propsValue = ({ shape, level, location }) => { // return { // shape: shape, // direction: level, // labelPlacement: location === 'right' ? 'hoz' : 'ver', // }; // }; // export default { // name: 'Step', // shape: ['circle', 'arrow', 'dot'], // editor: (shape) => { // if (shape === 'arrow') { // return { // props: [{ // name: 'state', // type: Types.enum, // options: ['normal', 'disabled'], // default: 'normal' // }, { // name: 'width', // type: Types.number, // default: 500 // }], // data: { // active: true, // disabled: true, // default: 'Step 1\nStep 2\n*Step 3\nStep 4' // } // }; // } // return { // props: [{ // name: 'level', // label: 'Orientation', // type: Types.enum, // options: [{ value: 'hoz', label: 'Horizontal' }, { value: 'ver', label: 'Vertical' }] // }, // ...( // shape === 'circle' ? [{ // name: 'state', // type: Types.enum, // options: ['normal', 'percent', 'disabled'], // default: 'normal' // }, { // name: 'location', // type: Types.enum, // options: ['down', 'right'], // default: 'down' // }] : [{ // name: 'state', // label: 'Status', // type: Types.enum, // options: ['normal', 'disabled'], // default: 'normal' // }] // ), { // name: 'width', // type: Types.number, // default: 600 // }, { // name: 'height', // type: Types.number, // default: 300 // }], // data: { // active: true, // disabled: true, // default: 'Step 1\n\tOpen the door Put the elephant into the fridge\n*Step 2\n\tOpen the door Put the elephant into the fridge\nStep 3\n\tOpen the door Put the elephant into the fridge\nStep 4\n\tOpen the door Put the elephant into the fridge' // } // }; // }, // propsValue:_propsValue, // adaptor: ({ shape, level, state, location, width, height, data, style, ...others }) => { // const list = parseData(data, { parseContent: true }).filter(({ type }) => type === NodeType.node); // const dataSouce = []; // let current = 0; // list.forEach((item, index) => { // const { value = '' } = item.value.find(({ type }) => type === ContentType.icon) || {}; // dataSouce.push({ // key: index, // icon: value, // title: item.value.filter(({ type }) => type === ContentType.text).map(({ value }) => value).join(''), // content: item.children && item.children.length > 0 ? item.children[0].value.filter(({ type }) => type === ContentType.text).map(({ value }) => value).join('') : '', // disabled: state === 'disabled' || item.state === 'disabled', // }); // if (item.state === 'active') { // current = index; // } // }); // if (state === 'percent' && dataSouce[current]) { // dataSouce[current].percent = 60; // } // return ( //
// // { // dataSouce.map(item => ) // } // //
// ); // }, // demoOptions: (demo) => { // if (demo.node.props.level === 'hoz') { // demo.node.props = { // ...demo.node.props, // width: 600, // height: 120 // }; // } else if (demo.node.props.level === 'ver') { // demo.node.props = { // ...demo.node.props, // width: 200, // height: 300 // }; // } // return demo; // } // }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/step/meta.design.ts ================================================ import snippets from './snippets.design'; import { getDataFromPlainText } from './adaptor'; export default { group: '原子组件', componentName: 'Step', title: '步骤条', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Step', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'rtl', propType: 'bool', }, { name: 'current', propType: 'number', description: '当前步骤', defaultValue: 0, }, { name: 'direction', propType: { type: 'oneOf', value: ['hoz', 'ver'], }, description: '展示方向', defaultValue: 'hoz', }, { name: 'labelPlacement', propType: { type: 'oneOf', value: ['hoz', 'ver'], }, description: '横向布局时( direction 为 hoz )的内容排列', defaultValue: 'ver', }, { name: 'shape', propType: { type: 'oneOf', value: ['circle', 'arrow', 'dot'], }, description: '类型', defaultValue: 'circle', }, { name: 'readOnly', propType: 'bool', description: '是否只读模式', }, { name: 'animation', propType: 'bool', description: '是否开启动效', defaultValue: true, }, { name: 'className', propType: 'string', description: '自定义样式名', }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: true, isMinimalRenderUnit: true, }, props: [ { name: 'shape', setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '圆圈', value: 'circle', }, { label: '箭头', value: 'arrow', }, { label: '点', value: 'dot', }, ], }, }, title: '类型', defaultValue: 'circle', setValue: (target, value) => { if (value === 'dot') { target?.parent?.setPropValue?.('labelPlacement', 'ver'); } }, }, { name: 'direction', setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '水平', value: 'hoz', }, { label: '垂直', value: 'ver', }, ], }, }, title: '方向', defaultValue: 'hoz', condition: (target) => target?.parent?.getPropValue?.('shape') !== 'arrow', }, { name: 'labelPlacement', setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '右侧', value: 'hoz', }, { label: '底侧', value: 'ver', }, ], }, }, title: '内容位置', defaultValue: 'ver', condition: (target) => target?.parent?.getPropValue?.('shape') === 'circle', }, { name: 'style.width', title: '宽度', condition: (target) => target?.parent?.getPropValue?.('direction') !== 'ver', setter: 'NumberSetter', }, // { // name: 'style.height', // title: '高度', // setter: 'NumberSetter' // }, { name: 'plainData', display: 'block', title: '内容', setValue: (target, value) => { const { children, current } = getDataFromPlainText(value); if (children) { const map = {}; children.forEach((item) => { const { props } = item; map[props.key] = props; }); // target.parent.setPropValue('children', children); const _children = target.node.export().children; target.node.children.mergeChildren( (child) => { const primaryKey = String(child.getPropValue('key')); return Object.hasOwnProperty.call(map, primaryKey); }, () => { const items = []; for (const key in map) { const originChild = _children.find((child) => { const found = child.props.key === key; return found; }) || { children: [] }; if (Object.hasOwnProperty.call(map, key)) { items.push({ componentName: 'Step.Item', props: map[key], children: originChild.children, }); } } return items; }, (child1, child2) => { const a = children.findIndex( (item) => String(item.props.key) === String(child1.getPropValue('key')), ); const b = children.findIndex( (item) => String(item.props.key) === String(child2.getPropValue('key')), ); return a - b; }, ); } if (typeof current !== 'undefined') { target.parent.setPropValue('current', current); } }, setter: { componentName: 'MagicEditorSetter', props: { toolbar: ['normal', 'active', 'disable'], }, }, }, ], }, icon: '', category: '导航', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/step/meta.ts ================================================ import snippets from './snippets'; export default { group: '原子组件', componentName: 'Step', title: '步骤条', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Step', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'rtl', propType: 'bool', }, { name: 'current', propType: 'number', description: '当前步骤', defaultValue: 0, }, { name: 'direction', propType: { type: 'oneOf', value: ['hoz', 'ver'], }, description: '展示方向', defaultValue: 'hoz', }, { name: 'labelPlacement', propType: { type: 'oneOf', value: ['hoz', 'ver'], }, description: '横向布局时( direction 为 hoz )的内容排列', defaultValue: 'ver', }, { name: 'shape', propType: { type: 'oneOf', value: ['circle', 'arrow', 'dot'], }, description: '类型', defaultValue: 'circle', }, { name: 'readOnly', propType: 'bool', description: '是否只读模式', }, { name: 'animation', propType: 'bool', description: '是否开启动效', defaultValue: true, }, { name: 'className', propType: 'string', description: '自定义样式名', }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: true, }, props: [ { name: 'items', title: '步骤项', setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'icon', title: '图标', setter: 'IconSetter', supportVariable: true, description: '图标', }, { name: 'title', title: '标题', setter: 'StringSetter', supportVariable: true, description: '标题', }, { name: 'status', setter: { componentName: 'RadioGroupSetter', props: { options: ['wait', 'process', 'finish'] }, }, description: '步骤的状态,如不传,会根据外层的 Step 的 current 属性生成,可选值为 `wait`, `process`, `finish`', }, { name: 'content', title: { label: '内容', tip: 'content|内容填充, shape为 arrow 时无效', }, setter: 'TextAreaSetter', supportVariable: true, description: '内容填充, shape为 arrow 时无效', }, { name: 'percent', title: '百分比', setter: 'NumberSetter', supportVariable: true, description: '百分比', }, { name: 'disabled', title: '是否禁用', setter: 'BoolSetter', supportVariable: true, description: '是否禁用', }, ], }, }, initialValue: () => { return { primaryKey: String(Math.floor(Math.random() * 10000)), title: 'StepItem', }; }, }, }, }, extraProps: { getValue(target, fieldValue) { // const node = target.node; // const children = node.children; const map = target.node.children.map((child) => { const primaryKey = child.getPropValue('primaryKey') ? String(child.getPropValue('primaryKey')) : child.id; return { primaryKey, icon: child.getPropValue('icon'), title: child.getPropValue('title'), status: child.getPropValue('status'), content: child.getPropValue('content'), percent: child.getPropValue('percent'), disabled: child.getPropValue('disabled'), }; }); return map; }, setValue(target, value) { const { node } = target; const map = {}; if (!Array.isArray(value)) { value = []; } value.forEach((item) => { const tabitem = Object.assign({}, item); map[item.primaryKey] = tabitem; }); node.children.mergeChildren( (child) => { const primaryKey = String(child.getPropValue('primaryKey')); if (Object.hasOwnProperty.call(map, primaryKey)) { child.setPropValue('icon', map[primaryKey].icon); child.setPropValue('title', map[primaryKey].title); child.setPropValue('content', map[primaryKey].content); child.setPropValue('status', map[primaryKey].status); child.setPropValue('percent', map[primaryKey].percent); child.setPropValue('disabled', map[primaryKey].disabled); delete map[primaryKey]; return false; } return true; }, () => { const items = []; for (const primaryKey in map) { if (Object.hasOwnProperty.call(map, primaryKey)) { items.push({ componentName: 'Step.Item', props: map[primaryKey], }); } } return items; }, (child1, child2) => { const a = value.findIndex( (item) => String(item.primaryKey) === String(child1.getPropValue('primaryKey')), ); const b = value.findIndex( (item) => String(item.primaryKey) === String(child2.getPropValue('primaryKey')), ); return a - b; }, ); }, }, }, { name: 'current', setter: (target) => { const items = target.parent.getPropValue('items') || []; return { componentName: 'MixedSetter', props: { setters: [ { componentName: 'NumberSetter', props: { min: 0, max: items.length - 1, defaultValue: 0, }, }, 'ExpressionSetter', ], }, }; }, title: '当前步骤', defaultValue: 0, }, { name: 'direction', setter: { componentName: 'RadioGroupSetter', props: { options: ['hoz', 'ver'], }, }, title: '展示方向', defaultValue: 'hoz', }, { name: 'labelPlacement', setter: { componentName: 'RadioGroupSetter', props: { options: ['hoz', 'ver'], }, }, title: '内容排列', defaultValue: 'ver', }, { name: 'shape', setter: { componentName: 'RadioGroupSetter', props: { options: ['circle', 'arrow', 'dot'], }, }, title: '类型', defaultValue: 'circle', }, { name: 'readOnly', setter: 'BoolSetter', supportVariable: true, title: '是否只读', }, { name: 'animation', setter: 'BoolSetter', supportVariable: true, title: '开启动效', defaultValue: true, }, ], }, icon: '', category: '引导', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/step/snippets.design.ts ================================================ import { getDataFromPlainText } from './adaptor'; const plainData = 'Step 1\n\tOpen the door Put the elephant into the fridge\n*Step 2\n\tOpen the door Put the elephant into the fridge\nStep 3\n\tOpen the door Put the elephant into the fridge\nStep 4\n\tOpen the door Put the elephant into the fridge'; const { current, children } = getDataFromPlainText(plainData); export default [ { title: '步骤', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_step.png', schema: { componentName: 'Step', props: { prefix: 'next-', direction: 'hoz', labelPlacement: 'ver', shape: 'circle', animation: true, current, plainData, }, children, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/step/snippets.ts ================================================ import { getDataFromPlainText } from './adaptor'; const plainData = 'Step 1\n\tOpen the door Put the elephant into the fridge\n*Step 2\n\tOpen the door Put the elephant into the fridge\nStep 3\n\tOpen the door Put the elephant into the fridge\nStep 4\n\tOpen the door Put the elephant into the fridge'; const { children } = getDataFromPlainText(plainData); export default [ { title: '步骤', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_step.png', schema: { componentName: 'Step', props: { prefix: 'next-', direction: 'hoz', labelPlacement: 'ver', shape: 'circle', animation: true, }, children, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/step-item/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Step.Item', title: '步骤项', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Step', main: '', destructuring: true, subName: 'Item', }, props: [ { name: 'icon', propType: 'string', description: '图标', }, { name: 'title', propType: { type: 'instanceOf', value: 'node', }, description: '标题', }, { name: 'content', title: { label: '内容', tip: 'content|内容填充, shape为 arrow 时无效', }, propType: { type: 'instanceOf', value: 'node', }, description: '内容填充, shape为 arrow 时无效', }, { name: 'status', title: { label: '状态', tip: 'status|步骤的状态,如不传,会根据外层的 Step 的 current 属性生成,可选值为 `wait`, `process`, `finish`', }, propType: { type: 'oneOf', value: ['wait', 'process', 'finish'], }, description: '步骤的状态,如不传,会根据外层的 Step 的 current 属性生成,可选值为 `wait`, `process`, `finish`', }, { name: 'percent', propType: 'number', description: '百分比', }, { name: 'disabled', propType: 'bool', description: '是否禁用', }, { name: 'onClick', propType: 'func', description: '点击步骤时的回调\n@param {Number} index 节点索引', }, { name: 'className', propType: 'string', description: '自定义样式', }, { name: 'style', propType: 'object', }, ], configure: { props: { isExtends: true, override: [ { name: 'title', title: '标题', setter: 'StringSetter', }, { name: 'icon', title: { label: '图标', tip: 'icon|图标', }, setter: { componentName: 'IconSetter', }, }, { name: 'content', title: { label: '内容', tip: 'content|内容', }, setter: { componentName: 'TextAreaSetter', }, }, { name: 'status', title: { label: '状态', tip: 'status|状态', }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '等待', value: 'wait', }, { title: '进行中', value: 'process', }, { title: '结束', value: 'finish', }, { title: '默认', value: '', }, ], }, }, }, ], }, advanced: { callbacks: { onHoverHook: () => false, onMouseDownHook: () => false, onClickHook: () => false, onMove: () => false, }, }, }, category: 'null', icon: '', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/sub-menu/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'SubMenu', title: '子菜单', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Menu', main: '', destructuring: true, subName: 'SubMenu', }, props: [ { name: 'key', propType: 'string', description: '子菜单标识符', }, { name: 'label', propType: 'node', description: '标签内容', }, { name: 'selectable', propType: 'bool', description: '是否可选,该属性仅在设置 Menu 组件 selectMode 属性后生效', defaultValue: false, }, { name: 'mode', propType: { type: 'oneOf', value: ['inline', 'popup'], }, description: '子菜单打开方式,如果设置会覆盖 Menu 上的同名属性\n@default Menu 的 mode 属性值', }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: true, nestingRule: { parentWhitelist: ['Menu', 'SubMenu', 'Menu.Group', 'MenuButton'], }, }, advanced: { callbacks: { onHoverHook: () => false, onMouseDownHook: () => false, onClickHook: () => false, onMove: () => false, }, }, }, icon: '', category: '信息输入', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/sub-nav/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'SubNav', title: 'SubNav', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Nav', main: '', destructuring: true, subName: 'SubNav', }, props: [ { name: 'className', propType: 'string', description: '自定义类名', }, { name: 'icon', propType: { type: 'oneOfType', value: [ 'string', { type: 'instanceOf', value: 'node', }, ], }, description: '自定义图标,可以使用 Icon 的 type,也可以使用组件 ``', }, { name: 'label', propType: { type: 'instanceOf', value: 'node', }, description: '标签内容', }, { name: 'selectable', propType: 'bool', description: '是否可选', defaultValue: false, }, { name: 'children', propType: { type: 'instanceOf', value: 'node', }, description: '导航项和子导航', }, { name: 'style', propType: 'object', }, ], category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/switch/meta.design.ts ================================================ import snippets from './snippets'; export default { group: '原子组件', componentName: 'Switch', title: '开关', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Switch', main: '', destructuring: true, subName: '', }, props: [ { name: 'id', propType: 'string', }, { name: 'name', propType: 'string', description: 'name', }, { name: 'className', propType: 'string', description: '自定义类名', }, { name: 'style', propType: 'object', description: '自定义内敛样式', }, { name: 'checked', propType: 'bool', description: '当前状态', }, { name: 'disabled', propType: 'bool', description: '是否禁用', defaultValue: false, }, { name: 'size', propType: { type: 'oneOf', value: ['medium', 'small'], }, description: '尺寸', defaultValue: 'medium', }, { name: 'checkedChildren', propType: 'string', description: '打开时的内容', }, { name: 'unCheckedChildren', propType: 'string', description: '关闭时的内容', }, { name: 'onChange', propType: 'func', description: '开关状态改变是触发此事件\n@param {Boolean} checked 是否为打开状态\n@param {Event} e DOM事件对象', }, { name: 'onClick', propType: 'func', description: '鼠标点击事件\n@param {Event} e DOM事件对象', }, { name: 'onKeyDown', propType: 'func', description: '键盘按键事件\n@param {Event} e DOM事件对象', }, ], configure: { props: [ { name: 'checked', title: { label: { type: 'i18n', zh_CN: '当前状态', en_US: 'Checked', }, tip: { type: 'i18n', zh_CN: '属性: checked | 说明: 当前状态', en_US: 'prop: checked | description: current status', }, }, setter: 'BoolSetter', }, { name: 'disabled', title: { label: { type: 'i18n', zh_CN: '是否禁用', en_US: 'Disabled', }, tip: { type: 'i18n', zh_CN: '属性: disabled | 说明: 是否被禁用', en_US: 'prop: disabled | description: disabled', }, }, setter: 'BoolSetter', description: '是否禁用', defaultValue: false, }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 尺寸', en_US: 'prop: size | description: size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '小', value: 'small', }, { label: '中', value: 'medium', }, ], }, }, defaultValue: 'medium', }, { name: 'checkedChildren', title: { label: { type: 'i18n', zh_CN: '开启内容', en_US: 'Checked Content', }, tip: { type: 'i18n', zh_CN: '属性: checkedChildren | 说明: 打开时的内容', en_US: 'prop: checkedChildren | description: checked content', }, }, setter: { componentName: 'StringSetter', props: { placeholder: '请输入', }, }, description: '打开时的内容', }, { name: 'unCheckedChildren', title: { label: { type: 'i18n', zh_CN: '关闭内容', en_US: 'UnChecked Content', }, tip: { type: 'i18n', zh_CN: '属性: unCheckedChildren | 说明: 关闭时的内容', en_US: 'prop: unCheckedChildren | description: unchecked content', }, }, setter: { componentName: 'StringSetter', props: { placeholder: '请输入', }, }, }, ], supports: { style: true, events: ['onChange', 'onClick', 'onKeyDown'], }, }, icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/switch/meta.ts ================================================ import snippets from './snippets'; export default { group: '原子组件', componentName: 'Switch', title: '开关', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Switch', main: '', destructuring: true, subName: '', }, props: [ { name: 'id', propType: 'string', }, { name: 'name', propType: 'string', description: 'name', }, { name: 'className', propType: 'string', description: '自定义类名', }, { name: 'style', propType: 'object', description: '自定义内敛样式', }, { name: 'checked', propType: 'bool', description: '当前状态', }, { name: 'disabled', propType: 'bool', description: '是否禁用', defaultValue: false, }, { name: 'size', propType: { type: 'oneOf', value: ['medium', 'small'], }, description: '尺寸', defaultValue: 'medium', }, { name: 'checkedChildren', propType: 'string', description: '打开时的内容', }, { name: 'unCheckedChildren', propType: 'string', description: '关闭时的内容', }, { name: 'onChange', propType: 'func', description: '开关状态改变是触发此事件\n@param {Boolean} checked 是否为打开状态\n@param {Event} e DOM事件对象', }, { name: 'onClick', propType: 'func', description: '鼠标点击事件\n@param {Event} e DOM事件对象', }, { name: 'onKeyDown', propType: 'func', description: '键盘按键事件\n@param {Event} e DOM事件对象', }, ], configure: { props: [ { name: 'checked', title: { label: { type: 'i18n', zh_CN: '当前状态', en_US: 'Checked', }, tip: { type: 'i18n', zh_CN: '属性: checked | 说明: 当前状态', en_US: 'prop: checked | description: current status', }, }, setter: 'BoolSetter', supportVariable: true, }, { name: 'disabled', title: { label: { type: 'i18n', zh_CN: '是否禁用', en_US: 'Disabled', }, tip: { type: 'i18n', zh_CN: '属性: disabled | 说明: 是否被禁用', en_US: 'prop: disabled | description: disabled', }, }, setter: 'BoolSetter', supportVariable: true, description: '是否禁用', defaultValue: false, }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 尺寸', en_US: 'prop: size | description: size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['medium', 'small'], }, }, defaultValue: 'medium', }, { name: 'checkedChildren', title: { label: { type: 'i18n', zh_CN: '开启内容', en_US: 'Checked Content', }, tip: { type: 'i18n', zh_CN: '属性: checkedChildren | 说明: 打开时的内容', en_US: 'prop: checkedChildren | description: checked content', }, }, setter: 'StringSetter', supportVariable: true, description: '打开时的内容', }, { name: 'unCheckedChildren', title: { label: { type: 'i18n', zh_CN: '关闭内容', en_US: 'UnChecked Content', }, tip: { type: 'i18n', zh_CN: '属性: unCheckedChildren | 说明: 关闭时的内容', en_US: 'prop: unCheckedChildren | description: unchecked content', }, }, setter: 'StringSetter', supportVariable: true, }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', supportVariable: true, }, ], }, ], supports: { style: true, events: ['onChange', 'onClick', 'onKeyDown'], }, }, icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/switch/snippets.ts ================================================ export default [ { title: '开关组件', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_switch.png', schema: { componentName: 'Switch', props: { prefix: 'next-', size: 'medium', }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/tab/adaptor.ts ================================================ import parseData from '../utils/parse-data'; export const createDataSource = (data: any, props) => { const list = parseData(data, { parseContent: true }); const dataSource = []; list.forEach((item, index) => { const { value = '' } = item.value.find(({ type }) => type === 'icon') || {}; dataSource.push({ icon: value, key: `tab_item_${index}`, title: { type: 'JSSlot', value: item.value.map(({ type, value }) => { if (type === 'icon') return { componentName: 'Icon', props: { disabled: true, type: value, size: 'small', style: { marginRight: '4px' }, }, }; return { componentName: 'Typography.Text', props: { children: value, style: { color: 'inherit', }, }, }; }), }, disabled: item.state === 'disabled', }); if (item.state === 'active') { props.current = `tab_item_${index}`; } }); return dataSource; }; function createContents(dataSource) { //dataSouce.map(item => ) return dataSource.map((item) => { return { componentName: 'Tab.Item', props: item, }; }); } export function getDataFromPlainText(value) { const props = { current: `tab_item_0` }; const dataSource = createDataSource(value, props); const children = createContents(dataSource); return { children, ...props }; } // export default { // name: 'Tab', // shape: ['pure', 'wrapped', 'text', 'capsule'], // editor: (shape = 'pure') => { // const props = [{ // name: 'size', // type: Types.enum, // options: ['medium', 'small'], // default: 'medium' // }, { // name: 'closable', // type: Types.bool, // default: false // }]; // if (['pure', 'wrapped', 'text'].indexOf(shape) !== -1) { // props.push({ // name: 'overflow', // label: 'Overflow Indicator', // type: Types.enum, // options: ['slide', 'dropdown'], // default: 'slide' // }); // props.push({ // name: 'width', // type: Types.number, // default: 480 // }); // } // if (shape === 'wrapped') { // props.splice(props.length - 2, 0, { // name: 'position', // type: Types.enum, // options: ['top', 'left', 'right'], // default: 'top' // }); // } // return { // props, // data: { // active: true, // disable: true, // default: 'Tab 1\n*Tab 2\nTab 3' // } // }; // }, // adaptor: ({ shape, size, closable, overflow, width, position, style = {}, data, ...others }) => { // const list = parseData(data, { parseContent: true }); // const activeKey = list.findIndex((item) => item.state === 'active'); // return ( // // { // list.map((item, index) => type === 'icon' ? : value)} closeable={closable} disabled={item.state === 'disabled'} />) // } // // ); // } // }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/tab/meta.design.ts ================================================ import snippets from './snippets'; import { getDataFromPlainText } from './adaptor'; export default { group: '原子组件', componentName: 'Tab', title: '选项卡', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Tab', main: '', destructuring: true, subName: '', }, props: [ { name: 'rtl', propType: 'bool', }, { name: 'device', propType: { type: 'oneOf', value: ['tablet', 'desktop', 'phone'], }, }, { name: 'shape', propType: { type: 'oneOf', value: ['pure', 'wrapped', 'text', 'capsule'], }, description: '外观形态', defaultValue: 'pure', }, { name: 'animation', propType: 'bool', description: '是否开启动效', defaultValue: true, }, { name: 'excessMode', propType: { type: 'oneOf', value: ['slide', 'dropdown'], }, description: '选项卡过多时的滑动模式', defaultValue: 'slide', }, { name: 'tabPosition', propType: { type: 'oneOf', value: ['top', 'bottom', 'left', 'right'], }, description: '导航选项卡的位置,只适用于包裹型(wrapped)选项卡', defaultValue: 'top', }, { name: 'size', propType: { type: 'oneOf', value: ['small', 'medium'], }, description: '尺寸', defaultValue: 'medium', }, { name: 'triggerType', propType: { type: 'oneOf', value: ['hover', 'click'], }, description: '激活选项卡的触发方式', defaultValue: 'click', }, { name: 'lazyLoad', propType: 'bool', description: '是否延迟加载 TabPane 的内容, 默认开启, 即不提前渲染', defaultValue: true, }, { name: 'unmountInactiveTabs', propType: 'bool', description: '是否自动卸载未处于激活状态的选项卡', defaultValue: false, }, { name: 'navClassName', propType: 'string', description: '导航条的自定义样式类', }, { name: 'contentClassName', propType: 'string', description: '内容区容器的自定义样式类', }, { name: 'extra', propType: { type: 'instanceOf', value: 'node', }, description: '导航栏附加内容', }, { name: 'onClick', propType: 'func', description: '点击单个选项卡时触发的回调', }, { name: 'onChange', propType: 'func', description: '选项卡发生切换时的事件回调\n@param {String|Number} key 改变后的 key', }, { name: 'onClose', propType: 'func', description: '选项卡被关闭时的事件回调\n@param {String|Number} key 关闭的选项卡的 key', }, { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: true, isMinimalRenderUnit: true, }, props: [ { name: 'shape', title: '类型', defaultValue: 'pure', setter: { componentName: 'SelectSetter', props: { options: [ { title: '普通型', value: 'pure' }, { title: '包裹型', value: 'wrapped' }, { title: '文本型', value: 'text' }, { title: '胶囊型', value: 'capsule' }, ], }, }, }, { name: 'size', title: '尺寸', defaultValue: 'medium', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '小', value: 'small' }, { title: '中', value: 'medium' }, ], }, }, }, { name: 'closeable', title: '关闭入口', setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '无', value: false, }, { label: '有', value: true, }, ], }, }, }, { name: 'excessMode', title: '超出模式', defaultValue: 'slide', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '左右滑动', value: 'slide' }, { title: '下拉', value: 'dropdown' }, ], }, }, }, { name: 'style.width', title: '宽度', setter: 'NumberSetter', }, { name: 'plainData', display: 'block', title: '内容', setValue: (target, value) => { const { children, current } = getDataFromPlainText(value); if (children) { const map = {}; children.forEach((item) => { const { props } = item; map[props.key] = props; }); // target.parent.setPropValue('children', children); const _children = target.node.export().children; target.node.children.mergeChildren( (child) => { const primaryKey = String(child.getPropValue('key')); return Object.hasOwnProperty.call(map, primaryKey); }, () => { const items = []; for (const key in map) { const originChild = _children.find((child) => { const found = child.props.key === key; return found; }) || { children: [] }; if (Object.hasOwnProperty.call(map, key)) { items.push({ componentName: 'Tab.Item', props: map[key], children: originChild.children, }); } } return items; }, (child1, child2) => { const a = children.findIndex( (item) => String(item.props.key) === String(child1.getPropValue('key')), ); const b = children.findIndex( (item) => String(item.props.key) === String(child2.getPropValue('key')), ); return a - b; }, ); } const currentShape = target.parent.getPropValue('shape'); target.parent.setPropValue('shape', ''); target.parent.setPropValue('shape', currentShape); if (typeof current !== 'undefined') { // target.parent.setPropValue('activeKey', current); } }, setter: { componentName: 'MagicEditorSetter', props: { toolbar: ['normal', 'disable'], }, }, }, ], supports: { events: ['onClick', 'onChange', 'onClose'], }, advanced: { initialChildren: [ { componentName: 'Tab.Item', props: { primaryKey: 'item1' }, }, { componentName: 'Tab.Item', props: { primaryKey: 'item2' }, }, ], }, }, icon: '', category: '导航', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/tab/meta.ts ================================================ import snippets from './snippets'; import { IPublicModelSettingField } from '@alilc/lowcode-types'; export default { group: '原子组件', componentName: 'Tab', title: '选项卡', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Tab', main: '', destructuring: true, subName: '', }, props: [ { name: 'rtl', propType: 'bool', }, { name: 'device', propType: { type: 'oneOf', value: ['tablet', 'desktop', 'phone'], }, }, { name: 'shape', propType: { type: 'oneOf', value: ['pure', 'wrapped', 'text', 'capsule'], }, description: '外观形态', defaultValue: 'pure', }, { name: 'animation', propType: 'bool', description: '是否开启动效', defaultValue: true, }, { name: 'excessMode', propType: { type: 'oneOf', value: ['slide', 'dropdown'], }, description: '选项卡过多时的滑动模式', defaultValue: 'slide', }, { name: 'tabPosition', propType: { type: 'oneOf', value: ['top', 'bottom', 'left', 'right'], }, description: '导航选项卡的位置,只适用于包裹型(wrapped)选项卡', defaultValue: 'top', }, { name: 'size', propType: { type: 'oneOf', value: ['small', 'medium'], }, description: '尺寸', defaultValue: 'medium', }, { name: 'triggerType', propType: { type: 'oneOf', value: ['hover', 'click'], }, description: '激活选项卡的触发方式', defaultValue: 'click', }, { name: 'lazyLoad', propType: 'bool', description: '是否延迟加载 TabPane 的内容, 默认开启, 即不提前渲染', defaultValue: true, }, { name: 'unmountInactiveTabs', propType: 'bool', description: '是否自动卸载未处于激活状态的选项卡', defaultValue: false, }, { name: 'navClassName', propType: 'string', description: '导航条的自定义样式类', }, { name: 'contentClassName', propType: 'string', description: '内容区容器的自定义样式类', }, { name: 'extra', propType: { type: 'instanceOf', value: 'node', }, description: '导航栏附加内容', }, { name: 'onClick', propType: 'func', description: '点击单个选项卡时触发的回调', }, { name: 'onChange', propType: 'func', description: '选项卡发生切换时的事件回调\n@param {String|Number} key 改变后的 key', }, { name: 'onClose', propType: 'func', description: '选项卡被关闭时的事件回调\n@param {String|Number} key 关闭的选项卡的 key', }, { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: true, }, props: [ { name: 'items', title: '标签项', setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'title', title: '名称', initialValue: '标签项', setter: 'StringSetter', important: true, supportVariable: true, }, { name: 'primaryKey', title: '项目编号', condition: () => false, initialValue: (val: string) => { if (val) return val; return String(Math.floor(Math.random() * 10000)); }, setter: 'StringSetter', supportVariable: true, }, { name: 'closeable', title: '可关闭', initialValue: false, important: true, setter: 'BoolSetter', supportVariable: true, }, { name: 'disabled', title: '是否禁用', initialValue: false, important: true, setter: 'BoolSetter', supportVariable: true, }, ], }, }, initialValue: () => { return { primaryKey: String(Math.floor(Math.random() * 10000)), title: '标签项', closeable: false, disabled: false, }; }, }, }, }, extraProps: { getValue(target: IPublicModelSettingField, value: any) { const map = target.node?.children?.map((child) => { const primaryKey = child.getPropValue('primaryKey') ? String(child.getPropValue('primaryKey')) : child.id; return { primaryKey, title: child.getPropValue('title'), closeable: child.getPropValue('closeable'), disabled: child.getPropValue('disabled'), }; }) || []; return map; }, setValue(target: IPublicModelSettingField, value: any) { const { node } = target; const map: Record = {}; if (!Array.isArray(value)) { value = []; } value.forEach((item: any) => { const tabitem = Object.assign({}, item); map[item.primaryKey] = tabitem; }); node?.children?.mergeChildren( (child) => { const primaryKey = String(child.getPropValue('primaryKey')); if (Object.hasOwnProperty.call(map, primaryKey)) { child.setPropValue('title', map[primaryKey].title); child.setPropValue('closeable', map[primaryKey].closeable); child.setPropValue('disabled', map[primaryKey].disabled); delete map[primaryKey]; return false; } return true; }, () => { const items = []; for (const primaryKey in map) { if (Object.hasOwnProperty.call(map, primaryKey)) { items.push({ componentName: 'Tab.Item', props: map[primaryKey], }); } } return items; }, (child1, child2) => { const a = value.findIndex( (item: any) => String(item.primaryKey) === String(child1.getPropValue('primaryKey')), ); const b = value.findIndex( (item: any) => String(item.primaryKey) === String(child2.getPropValue('primaryKey')), ); return a - b; }, ); }, }, }, { name: 'shape', title: '形态', defaultValue: 'pure', setter: { componentName: 'SelectSetter', props: { options: [ { title: '普通型', value: 'pure' }, { title: '包裹型', value: 'wrapped' }, { title: '文本型', value: 'text' }, { title: '胶囊型', value: 'capsule' }, ], }, }, }, { name: 'size', title: '尺寸', defaultValue: 'medium', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '小', value: 'small' }, { title: '中', value: 'medium' }, ], }, }, }, { name: 'excessMode', title: { label: '模式', tip: '选项卡过多时的查看模式', }, condition: () => false, defaultValue: 'slide', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '滑动', value: 'slide' }, { title: '下拉', value: 'dropdown' }, ], }, }, }, { name: 'advance', title: '高级', type: 'group', extraProps: { display: 'accordion', }, items: [ { name: 'unmountInactiveTabs', title: '切换销毁', defaultValue: false, setter: { componentName: 'BoolSetter', }, }, { name: 'needBadge', title: '开启徽标', defaultValue: false, setter: { componentName: 'BoolSetter', }, }, { name: 'renderBadge', title: '徽标渲染', display: 'block', setter: { componentName: 'FunctionSetter', // props: { // defaultActionName="renderBadge", // defaultCode=`function renderBadge(tabItem) { // //支持返回jsx,返回false或者null时不显示内容,返回字符串"dot"显示红点 // return 'dot'; // }`, // } }, condition(target: IPublicModelSettingField) { return target.parent.getPropValue('needBadge') || false; }, }, { name: 'tabRender', title: '自定义渲染选项卡', display: 'block', setter: { componentName: 'FunctionSetter', // props: { // defaultActionName="renderBadge", // defaultCode=`function renderTabItem(key, props) { // return props.title; // }`, // } }, }, { name: 'extraRender', title: '渲染导航栏附加内容', display: 'block', setter: { componentName: 'FunctionSetter', // props: { // defaultActionName="renderBadge", // defaultCode=`function renderTabExtra() { // return 'Extra'; // }`, // } }, }, ], }, { name: 'style', setter: { componentName: 'StyleSetter', }, }, ], supports: { events: ['onClick', 'onChange', 'onClose'], }, advanced: { initialChildren: [ { componentName: 'Tab.Item', props: { primaryKey: 'item1' }, }, { componentName: 'Tab.Item', props: { primaryKey: 'item2' }, }, ], }, }, icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/tab/snippets.design.ts ================================================ import { getDataFromPlainText } from './adaptor'; const plainData = 'Tab 1\nTab 2\nTab 3'; const { children } = getDataFromPlainText(plainData); export default [ { title: '普通型', screenshot: 'https://img.alicdn.com/tfs/TB1D0p2u.z1gK0jSZLeXXb9kVXa-112-64.png', schema: { componentName: 'Tab', props: { shape: 'pure', size: 'medium', excessMode: 'slide', plainData, }, children, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/tab/snippets.ts ================================================ export default [ { title: '普通型', screenshot: 'https://img.alicdn.com/tfs/TB1D0p2u.z1gK0jSZLeXXb9kVXa-112-64.png', schema: { componentName: 'Tab', props: { shape: 'pure', size: 'medium', excessMode: 'slide', }, children: [ { componentName: 'Tab.Item', props: { title: 'Tab1', }, }, { componentName: 'Tab.Item', props: { title: 'Tab2', }, }, { componentName: 'Tab.Item', props: { title: 'Tab3', }, }, ], }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/tab-item/meta.design.ts ================================================ module.exports = { group: '原子组件', componentName: 'Tab.Item', title: '选项卡Item', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Tab', main: '', destructuring: true, subName: 'Item', }, props: [ { name: 'isAutoContainer', initialValue: true, defaultValue: true, setter: 'BoolSetter', supportVariable: true, condition: () => false, }, { name: 'title', propType: 'string', description: '选项卡标题', }, { name: 'closeable', propType: 'bool', description: '单个选项卡是否可关闭', defaultValue: false, }, { name: 'disabled', propType: 'bool', description: '选项卡是否被禁用', }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: true, isMinimalRenderUnit: true, disableBehaviors: '*', nestingRule: { parentWhitelist: ['Tab'], }, }, advanced: { callbacks: { onHoverHook: () => false, onMouseDownHook: () => false, onClickHook: () => false, onMove: () => false, }, }, }, icon: '', category: 'null', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/tab-item/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Tab.Item', title: '选项卡Item', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Tab', main: '', destructuring: true, subName: 'Item', }, props: [ { name: 'isAutoContainer', initialValue: true, defaultValue: true, setter: 'BoolSetter', supportVariable: true, condition: () => false, }, { name: 'title', propType: 'string', description: '选项卡标题', }, { name: 'closeable', propType: 'bool', description: '单个选项卡是否可关闭', defaultValue: false, }, { name: 'disabled', propType: 'bool', description: '选项卡是否被禁用', }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: true, isMinimalRenderUnit: true, nestingRule: { parentWhitelist: ['Tab'], }, }, advanced: { callbacks: { onHoverHook: () => false, onMouseDownHook: () => false, onClickHook: () => false, onMove: () => false, }, }, }, icon: '', category: 'null', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/tab-tab-pane/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Tab.TabPane', title: 'Tab.TabPane', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Tab', main: '', destructuring: true, subName: 'TabPane', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'title', propType: { type: 'instanceOf', value: 'node', }, description: '选项卡标题', }, { name: 'closeable', propType: 'bool', description: '单个选项卡是否可关闭', defaultValue: false, }, { name: 'disabled', propType: 'bool', description: '选项卡是否被禁用', }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: true, }, }, category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/table/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Table', title: 'Table', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Table', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', }, { name: 'children', propType: 'string', }, { name: 'pure', propType: 'bool', }, { name: 'rtl', propType: 'bool', }, { name: 'tableLayout', propType: { type: 'oneOf', value: ['fixed', 'auto'], }, }, { name: 'tableWidth', propType: 'number', }, { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, { name: 'size', propType: { type: 'oneOf', value: ['small', 'medium'], }, }, { name: 'dataSource', propType: { type: 'arrayOf', value: 'object', }, }, { name: 'entireDataSource', propType: 'array', }, { name: 'onRowClick', propType: 'func', }, { name: 'onRowMouseEnter', propType: 'func', }, { name: 'rowProps', propType: 'func', }, { name: 'cellProps', propType: 'func', }, { name: 'hasBorder', propType: 'bool', }, { name: 'hasHeader', propType: 'bool', }, { name: 'isZebra', propType: 'bool', }, { name: 'loading', propType: 'bool', }, { name: 'filterParams', propType: 'object', }, { name: 'sort', propType: 'object', }, { name: 'sortIcons', propType: 'object', }, { name: 'locale', propType: 'object', }, { name: 'components', propType: 'object', }, { name: 'columns', propType: { type: 'arrayOf', value: { type: 'shape', value: [ { name: 'title', description: '列标题', propType: 'string', }, { name: 'dataIndex', description: '列名称', propType: 'string', }, ], }, }, }, { name: 'emptyContent', propType: 'node', }, { name: 'primaryKey', propType: 'string', }, { name: 'lockType', propType: { type: 'oneOf', value: ['left', 'right'], }, }, { name: 'style', propType: 'object', }, { name: 'wrapperContent', propType: 'any', }, { name: 'refs', propType: 'object', }, { name: 'expandedRowRender', propType: 'func', }, { name: 'expandedRowIndent', propType: 'array', }, { name: 'hasExpandedRowCtrl', propType: 'bool', }, { name: 'getExpandedColProps', propType: 'func', }, { name: 'openRowKeys', propType: 'array', }, { name: 'onRowOpen', propType: 'func', }, { name: 'onExpandedRowClick', propType: 'func', }, { name: 'fixedHeader', propType: 'bool', }, { name: 'rowSelection', propType: 'object', }, { name: 'stickyHeader', propType: 'bool', }, { name: 'offsetTop', propType: 'number', }, { name: 'affixProps', propType: 'object', }, { name: 'indent', propType: 'number', }, { name: 'isTree', propType: 'bool', }, { name: 'useVirtual', propType: 'bool', }, { name: 'onBodyScroll', propType: 'func', }, { name: 'expandedIndexSimulate', propType: 'bool', }, { name: 'crossline', propType: 'bool', }, { name: 'lengths', propType: 'object', }, ], configure: { props: { isExtends: true, override: [ { name: 'dataSource', setter: 'JsonSetter', supportVariable: true, }, { name: 'children', setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'componentName', title: '子组件', defaultValue: 'Table.Column', setter: { componentName: 'StringSetter', }, }, { name: 'props', title: 'props', setter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'title', setter: { componentName: 'StringSetter', }, }, { name: 'dataIndex', setter: { componentName: 'StringSetter', }, }, ], }, }, }, }, ], }, }, }, }, }, extraProps: { defaultValue: '', onChange: { type: 'JSFunction', value: '(val, field, editor) => {\n debugger;\n console.log(\'val\', val);//field.node.children.importSchema(val && {"componentName": "Table.Column", "props": {"type": val, "style": {"marginRight": 5}}}, true); //field.top.setPropValue(\'children\', [{"componentName": "Icon", "props": {"type": val}}, (field.top.getPropValue(\'children\') || []).slice(-1)]);\n}', }, }, }, ], }, }, category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/table-column/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Table.Column', title: 'Table.Column', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Table', main: '', destructuring: true, subName: 'Column', }, props: [ { name: 'title', propType: 'string', }, { name: 'dataIndex', propType: 'string', }, { name: 'cell', propType: 'func', }, ], configure: { props: { isExtends: true, override: [ { name: 'cell', setter: { componentName: 'SlotSetter', initialValue: { type: 'JSSlot', value: [], }, props: { supportParams: true, }, }, extraProps: { display: 'block', }, }, ], }, }, category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/tag/meta.design.ts ================================================ export default { group: '原子组件', componentName: 'Tag', title: '标签', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Tag', main: '', destructuring: true, }, props: [ { name: 'type', title: { label: { type: 'i18n', zh_CN: '标签类型', en_US: 'Tag Type', }, tip: { type: 'i18n', zh_CN: '属性: type | 说明: 标签的类型', en_US: 'prop: type | description: tag type', }, }, propType: { type: 'oneOf', value: ['normal', 'primary'], }, description: '标签的类型', }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '标签尺寸', en_US: 'Tag Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 标签的尺寸(large 尺寸为兼容表单场景 large = medium)', en_US: 'prop: size | description: tag size', }, }, propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '标签的尺寸(large 尺寸为兼容表单场景 large = medium)', }, { name: 'color', propType: 'string', description: '标签颜色, 目前支持:blue、 green、 orange、red、 turquoise、 yellow 和 hex 颜色值 (`color keywords`作为 Tag 组件的保留字,请勿直接使用 ), `1.19.0` 以上版本生效', }, { name: 'animation', title: { label: { type: 'i18n', zh_CN: '开启动效', en_US: 'Animation', }, tip: { type: 'i18n', zh_CN: '属性: animation | 说明: 是否开启动效', en_US: 'prop: animation | description: enable animation', }, }, propType: 'bool', description: '是否开启动效', }, { name: 'afterAppear', propType: 'func', description: '标签出现动画结束后执行的回调', }, { name: 'onClick', propType: 'func', description: '点击回调', }, { name: 'children', title: { label: { type: 'i18n', zh_CN: '标签文本', en_US: 'Content', }, tip: { type: 'i18n', zh_CN: '属性: children | 说明: 标签文本内容', en_US: 'prop: children | description: tag content', }, }, propType: 'string', description: '内容', }, { name: 'style', propType: 'object', }, ], configure: { props: [ { name: '!children', title: { label: { type: 'i18n', zh_CN: '内容', en_US: 'Content', }, tip: { type: 'i18n', zh_CN: '属性: children | 说明: 按钮文本', en_US: 'prop: children | description: button content', }, }, setter: 'StringSetter', getValue: (target) => { const { node } = target; const children = node.propsData.children || []; return children.filter((item) => typeof item === 'string').join(''); }, setValue: (target, value) => { const { node } = target; let children = node.propsData.children || []; const hasTextChild = children.find((item) => typeof item === 'string'); if (hasTextChild) { children = children.map((item) => { if (typeof item === 'string') { item = value; } return item; }); } else { children.push(value); } node.setPropValue('children', children); }, }, { name: '!icon', title: { label: { type: 'i18n', zh_CN: '图标', en_US: 'Icon', }, tip: { type: 'i18n', zh_CN: '属性: icon | 说明: 图标类型', en_US: 'prop: icon | description: icon type', }, }, setter: 'IconSetter', supportVariable: false, getValue: (target) => { const { node } = target; const children = node.propsData.children || []; const iconObject = children.find((item) => typeof item === 'object'); return iconObject && iconObject.props.type; }, setValue: (target, value) => { const { node } = target; let children = node.propsData.children || []; const hasIconChild = children.find((item) => typeof item === 'object'); if (hasIconChild) { children = children.map((item) => { if (typeof item === 'object') { item = { ...item, props: { ...item.props, type: value, }, }; } return item; }); } else { children.unshift({ componentName: 'Icon', props: { type: value, style: { marginRight: 4, }, }, }); } node.setPropValue('children', children); }, }, { name: 'type', title: { label: { type: 'i18n', zh_CN: '标签类型', en_US: 'Tag Type', }, tip: { type: 'i18n', zh_CN: '属性: type | 说明: 标签的类型', en_US: 'prop: type | description: tag type', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '主要', value: 'primary', }, { label: '普通', value: 'normal', }, ], }, }, }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '标签尺寸', en_US: 'Tag Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 标签的尺寸(large 尺寸为兼容表单场景 large = medium)', en_US: 'prop: size | description: tag size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '小', value: 'small' }, { title: '中', value: 'medium' }, { title: '大', value: 'large' }, ], }, }, }, { name: 'disabled', title: '状态', setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '普通', value: false, }, { label: '禁用', value: true, }, ], }, }, defaultValue: false, }, ], }, icon: '', category: '信息展示', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/tag/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Tag', title: '标签', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Tag', main: '', destructuring: true, }, props: [ { name: 'type', title: { label: { type: 'i18n', zh_CN: '标签类型', en_US: 'Tag Type', }, tip: { type: 'i18n', zh_CN: '属性: type | 说明: 标签的类型', en_US: 'prop: type | description: tag type', }, }, propType: { type: 'oneOf', value: ['normal', 'primary'], }, description: '标签的类型', }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '标签尺寸', en_US: 'Tag Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 标签的尺寸(large 尺寸为兼容表单场景 large = medium)', en_US: 'prop: size | description: tag size', }, }, propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '标签的尺寸(large 尺寸为兼容表单场景 large = medium)', }, { name: 'color', propType: 'string', description: '标签颜色, 目前支持:blue、 green、 orange、red、 turquoise、 yellow 和 hex 颜色值 (`color keywords`作为 Tag 组件的保留字,请勿直接使用 ), `1.19.0` 以上版本生效', }, { name: 'animation', title: { label: { type: 'i18n', zh_CN: '开启动效', en_US: 'Animation', }, tip: { type: 'i18n', zh_CN: '属性: animation | 说明: 是否开启动效', en_US: 'prop: animation | description: enable animation', }, }, propType: 'bool', description: '是否开启动效', }, { name: 'afterAppear', propType: 'func', description: '标签出现动画结束后执行的回调', }, { name: 'onClick', propType: 'func', description: '点击回调', }, { name: 'children', title: { label: { type: 'i18n', zh_CN: '标签文本', en_US: 'Content', }, tip: { type: 'i18n', zh_CN: '属性: children | 说明: 标签文本内容', en_US: 'prop: children | description: tag content', }, }, propType: 'string', description: '内容', }, { name: 'style', propType: 'object', }, ], configure: { props: { isExtends: true, override: [ { name: 'color', title: { label: { type: 'i18n', zh_CN: '标签颜色', en_US: 'Tag Color', }, tip: { type: 'i18n', zh_CN: '属性: color | 说明: 是否开启动效', en_US: 'prop: color | description: 目前支持:blue、 green、 orange、red、 turquoise、 yellow 和 hex 颜色值 (`color keywords`作为 Tag 组件的保留字,请勿直接使用 ), `1.19.0` 以上版本生效', }, }, setter: { componentName: 'ColorSetter', }, }, ], }, }, icon: '', category: '信息展示', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/tag/snippets.ts ================================================ module.exports = [ { title: '标签', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_tag.png', schema: { componentName: 'Tag', props: { prefix: 'next-', type: 'normal', size: 'medium', animation: false, children: ['Tag'], }, }, }, { title: '可关闭标签', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_tag.png', schema: { componentName: 'Tag.Closeable', props: { prefix: 'next-', closeArea: 'tail', size: 'medium', children: ['Tag'], }, }, }, { title: '可选中标签', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_tag.png', schema: { componentName: 'Tag.Selectable', props: { prefix: 'next-', children: ['Tag'], }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/tag-closeable/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Tag.Closeable', title: '可关闭标签', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Tag', main: '', destructuring: true, subName: 'Closeable', }, props: [ { name: 'closeArea', title: { label: { type: 'i18n', zh_CN: '关闭区域', en_US: 'Close Area', }, tip: { type: 'i18n', zh_CN: '属性: closeArea | 说明: closeable 标签的 onClose 响应区域, tag: 标签体, tail(默认): 关闭按钮', en_US: 'prop: closeArea | description: close area', }, }, propType: { type: 'oneOf', value: ['tag', 'tail'], }, description: 'closeable 标签的 onClose 响应区域, tag: 标签体, tail(默认): 关闭按钮', }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '标签尺寸', en_US: 'Tag Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 标签的尺寸(large 尺寸为兼容表单场景 large = medium)', en_US: 'prop: size | description: tag size', }, }, propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '标签的尺寸(large 尺寸为兼容表单场景 large = medium)', }, { name: 'onClose', propType: 'func', description: '点击关闭按钮时的回调,返回值 true 则关闭, false 阻止关闭', }, { name: 'onClick', propType: 'func', description: '点击回调', }, { name: 'afterClose', propType: 'func', description: '标签关闭后执行的回调', }, { name: 'children', title: { label: { type: 'i18n', zh_CN: '标签文本', en_US: 'Content', }, tip: { type: 'i18n', zh_CN: '属性: children | 说明: 标签文本内容', en_US: 'prop: children | description: tag content', }, }, propType: 'string', description: '内容', }, { name: 'style', propType: 'object', }, ], configure: {}, icon: '', category: '信息输入', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/tag-selectable/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Tag.Selectable', title: '可选中标签', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Tag', main: '', destructuring: true, subName: 'Selectable', }, props: [ { name: 'checked', title: { label: { type: 'i18n', zh_CN: '是否选中', en_US: 'Checked', }, tip: { type: 'i18n', zh_CN: '属性: checked | 说明: 标签是否被选中,受控用法', en_US: 'prop: checked | description: tag checked', }, }, propType: 'bool', description: '标签是否被选中,受控用法', }, { name: 'defaultChecked', title: { label: { type: 'i18n', zh_CN: '默认选中', en_US: 'Default Checked', }, tip: { type: 'i18n', zh_CN: '属性: defaultChecked | 说明: 标签是否默认被选中,非受控用法', en_US: 'prop: defaultChecked | description: tag default checked', }, }, propType: 'bool', description: '标签是否默认被选中,非受控用法', }, { name: 'disabled', title: { label: { type: 'i18n', zh_CN: '是否禁用', en_US: 'Disabled', }, tip: { type: 'i18n', zh_CN: '属性: disabled | 说明: 标签是否被禁用', en_US: 'prop: disabled | description: tag disabled', }, }, propType: 'bool', description: '标签是否被禁用', }, { name: 'onChange', propType: 'func', description: '选中状态变化时触发的事件 Function(checked: Boolean, e: Event) => void', }, { name: 'children', title: { label: { type: 'i18n', zh_CN: '标签文本', en_US: 'Content', }, tip: { type: 'i18n', zh_CN: '属性: children | 说明: 标签文本内容', en_US: 'prop: children | description: tag content', }, }, propType: 'string', description: '内容', }, { name: 'style', propType: 'object', }, ], configure: {}, icon: '', category: '信息输入', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/time-picker/meta.design.ts ================================================ import snippets from './snippets'; export default { group: '原子组件', componentName: 'TimePicker', title: '时间选择框', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'TimePicker', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'rtl', propType: 'bool', defaultValue: false, }, { name: 'name', title: { label: '名称', tip: 'name|表单相关', }, propType: 'string', description: 'name|表单相关', }, { name: 'label', title: { label: '标签', tip: 'label|输入框内置标签', }, propType: 'string', description: 'label|输入框内置标签', }, { name: 'state', title: { label: '状态', tip: 'state|输入框状态', }, propType: { type: 'oneOf', value: ['success', 'loading', 'error'], }, description: 'state|输入框状态', }, { name: 'placeholder', title: { label: '占位提示', tip: 'placeholder|输入提示', }, propType: 'string', description: '输入提示', }, { name: 'value', title: { label: 'value', tip: 'value|日期值(受控)', }, propType: { type: 'instanceOf', value: 'custom', }, description: '日期值(受控)moment 对象', }, { name: 'defaultValue', title: { label: '默认值', tip: 'defaultValue|初始日期值,moment 对象', }, propType: 'date', description: 'defaultValue|初始日期值,moment 对象', }, { name: 'format', title: { label: '格式', tip: 'format|日期值的格式(用于限定用户输入和展示)', }, propType: 'string', description: 'format|日期值的格式(用于限定用户输入和展示)', defaultValue: 'YYYY-MM-DD', }, { name: 'onChange', propType: 'func', description: '日期值改变时的回调\n@param {MomentObject|String} value 日期值', }, { name: 'onOk', propType: 'func', description: '点击确认按钮时的回调\n@return {MomentObject|String} 日期值', }, { name: 'size', title: { label: '尺寸', tip: 'size|输入框尺寸', }, propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: 'size|输入框尺寸', defaultValue: 'medium', }, { name: 'disabled', title: { label: '是否禁用', tip: 'disabled|是否禁用', }, propType: 'bool', description: '是否禁用', }, { name: 'hasClear', title: { label: '清除按钮', tip: 'hasClear|是否显示清空按钮', }, propType: 'bool', description: 'hasClear|是否显示清空按钮', defaultValue: true, }, { name: 'followTrigger', propType: 'bool', description: '跟随滚动', }, { name: 'defaultVisible', title: { label: '弹层显示', tip: 'defaultVisible|弹层默认是否显示', }, propType: 'bool', description: 'defaultVisible|弹层默认是否显示', defaultValue: false, }, { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, { name: 'form', propType: 'object', }, ], configure: { props: [ { name: 'format', title: '时间格式', defaultValue: 'HH:mm:ss', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: 'HH:mm:ss', value: 'HH:mm:ss' }, { title: 'HH:mm', value: 'HH:mm' }, { title: 'mm:ss', value: 'mm:ss' }, ], }, }, }, { name: 'visible', title: { label: '状态', tip: '属性: visible', }, defaultValue: false, setter: { componentName: 'RadioGroupSetter', props: { options: [ { value: false, label: '普通' }, { value: true, label: '展开' }, ], }, }, }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Button Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 按钮尺寸', en_US: 'prop: size | description: button size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '小', value: 'small', }, { label: '中', value: 'medium', }, { label: '大', value: 'large', }, ], }, }, defaultValue: 'medium', }, { name: 'style.width', title: '宽度', setter: 'NumberSetter', }, { name: 'label', title: { label: '内联文案', tip: 'label|输入框内置标签', }, setter: { componentName: 'StringSetter', props: { placeholder: '请输入', }, }, }, { name: 'placeholder', title: { label: '占位提示', tip: 'placeholder|输入提示', }, defaultValue: '请选择时间', setter: 'StringSetter', }, { name: 'defaultValue', title: '默认值', setter: 'TimePicker', }, ], }, icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/time-picker/meta.ts ================================================ import snippets from './snippets'; export default { group: '原子组件', componentName: 'TimePicker', title: '时间选择框', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'TimePicker', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'rtl', propType: 'bool', defaultValue: false, }, { name: 'name', title: { label: '名称', tip: 'name|表单相关', }, propType: 'string', description: 'name|表单相关', }, { name: 'label', propType: 'string', description: '按钮的文案', }, { name: 'state', propType: { type: 'oneOf', value: ['error', 'success'], }, description: '输入框状态', }, { name: 'placeholder', propType: 'string', description: '输入框提示', }, { name: 'value', propType: { type: 'instanceOf', value: 'custom', }, description: '时间值(moment 对象或时间字符串,受控状态使用)', }, { name: 'defaultValue', propType: { type: 'instanceOf', value: 'custom', }, description: '时间初值(moment 对象或时间字符串,非受控状态使用)', }, { name: 'size', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '时间选择框的尺寸', defaultValue: 'medium', }, { name: 'hasClear', propType: 'bool', description: '是否允许清空时间', defaultValue: true, }, { name: 'format', propType: 'string', description: '时间的格式\nhttps://momentjs.com/docs/#/parsing/string-format/', defaultValue: 'HH:mm:ss', }, { name: 'hourStep', propType: 'number', description: '小时选项步长', }, { name: 'minuteStep', propType: 'number', description: '分钟选项步长', }, { name: 'secondStep', propType: 'number', description: '秒钟选项步长', }, { name: 'visible', propType: 'bool', description: '弹层是否显示(受控)', }, { name: 'defaultVisible', propType: 'bool', description: '弹层默认是否显示(非受控)', }, { name: 'followTrigger', propType: 'bool', description: '是否跟随滚动', }, { name: 'disabled', propType: 'bool', description: '是否禁用', defaultValue: false, }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', }, { name: 'onChange', propType: 'func', description: '时间值改变时的回调\n@param {Object|String} value 时间对象或时间字符串', }, { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, { name: 'popupContainer', propType: 'any', description: '弹层容器\n@param {Element} target 目标元素\n@return {Element} 弹层的容器元素', }, ], configure: { props: [ { name: 'defaultValue', title: '默认值', setter: ['TimePicker', 'ExpressionSetter'], }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 尺寸\n@enumdesc 小, 中, 大', en_US: 'prop: size | description: size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['small', 'medium', 'large'], }, }, defaultValue: 'medium', }, { name: 'format', title: '时间格式', defaultValue: 'HH:mm:ss', setter: { componentName: 'MixedSetter', props: { setters: [ { componentName: 'RadioGroupSetter', props: { options: [ { title: 'HH:mm:ss', value: 'HH:mm:ss' }, { title: 'HH:mm', value: 'HH:mm' }, { title: 'mm:ss', value: 'mm:ss' }, ], }, }, 'ExpressionSetter', ], }, }, }, { name: 'hourStep', title: '小时步长', defaultValue: 1, setter: ['NumberSetter', 'ExpressionSetter'], }, { name: 'minuteStep', title: '分钟步长', defaultValue: 1, setter: ['NumberSetter', 'ExpressionSetter'], }, { name: 'secondStep', title: '秒钟步长', defaultValue: 1, setter: ['NumberSetter', 'ExpressionSetter'], }, { name: 'hasClear', title: '清除按钮', defaultValue: true, setter: ['BoolSetter', 'ExpressionSetter'], }, { name: 'disabledHours', title: '禁用小时函数', display: 'block', setter: { componentName: 'FunctionSetter', // props: { // defaultActionName="disabledHours", // defaultCode=`function disabledHours(index) { // return true; // }`, // } }, }, { name: 'disabledMinutes', title: '禁用分钟函数', display: 'block', setter: { componentName: 'FunctionSetter', // props: { // defaultActionName="disabledMinutes", // defaultCode=`function disabledMinutes(index) { // return true; // }`, // } }, }, { name: 'disabledSeconds', title: '禁用秒钟函数', display: 'block', setter: { componentName: 'FunctionSetter', // props: { // defaultActionName="disabledSeconds", // defaultCode=`function disabledSeconds(index) { // return true; // }`, // } }, }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', supportVariable: true, }, ], }, { name: 'style', setter: { componentName: 'StyleSetter', }, }, ], supports: { events: ['onChange', 'onVisibleChange'], }, }, icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/time-picker/snippets.ts ================================================ export default [ { title: '时间选择框', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_time-picker.png', schema: { componentName: 'TimePicker', props: { prefix: 'next-', size: 'medium', hasClear: true, format: 'HH:mm:ss', popupAlign: 'tl tl', popupTriggerType: 'click', }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/timeline/meta.design.ts ================================================ const updateChildren = (target, value) => { const { node } = target; const map = {}; if (!Array.isArray(value)) { value = []; } value.forEach((item) => { const tabitem = Object.assign({}, item); map[item.primaryKey] = tabitem; }); node.children.mergeChildren( (child) => { const primaryKey = String(child.getPropValue('primaryKey')); if (Object.hasOwnProperty.call(map, primaryKey)) { child.setPropValue('icon', map[primaryKey].icon); child.setPropValue('title', map[primaryKey].title); child.setPropValue('content', map[primaryKey].content); child.setPropValue('state', map[primaryKey].state); child.setPropValue('time', map[primaryKey].time); child.setPropValue('timeLeft', map[primaryKey].timeLeft); child.setPropValue('animation', map[primaryKey].animation); delete map[primaryKey]; return false; } return true; }, () => { const items = []; for (const primaryKey in map) { if (Object.hasOwnProperty.call(map, primaryKey)) { items.push({ componentName: 'Timeline.Item', props: map[primaryKey], }); } } return items; }, (child1, child2) => { const a = value.findIndex( (item) => String(item.primaryKey) === String(child1.getPropValue('primaryKey')), ); const b = value.findIndex( (item) => String(item.primaryKey) === String(child2.getPropValue('primaryKey')), ); return a - b; }, ); }; module.exports = { group: '原子组件', componentName: 'Timeline', title: '时间轴', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Timeline', main: '', destructuring: true, subName: '', }, props: [ { name: 'fold', propType: { type: 'arrayOf', value: { type: 'exact', value: [ { name: 'foldArea', propType: { type: 'arrayOf', value: 'number', }, }, { name: 'foldShow', propType: 'bool', }, ], }, }, description: '自定义折叠选项 示例`[{foldArea: [startIndex, endIndex], foldShow: boolean}]`', defaultValue: [], }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: true, nestingRule: { childWhitelist: ['Timeline.Item'], }, }, props: [ { name: '!timeAlign', title: '时间位置', defaultValue: 'bottom', setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '左侧', value: 'left', }, { label: '底部', value: 'bottom', }, ], }, }, setValue: (target, value) => { console.log('setvalue'); const items = target?.parent?.getPropValue?.('!items'); if (items && items.length) { let _items; if (value === 'left') { _items = items.map((item) => ({ ...item, time: undefined, timeLeft: item.time, })); } else { _items = items.map((item) => ({ ...item, timeLeft: undefined, time: item.timeLeft, })); } target?.parent?.setPropValue?.('!items', _items); updateChildren(target, _items); } }, }, { name: '!items', title: '时间轴数据', setter: (target) => { return { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'title', setter: 'StringSetter', important: true, title: '标题', }, { name: 'icon', title: '图标', setter: 'IconSetter', description: '图标', }, { name: 'state', setter: { componentName: 'RadioGroupSetter', props: { options: ['done', 'process', 'error', 'success'], }, }, title: '节点状态', defaultValue: 'done', }, { name: 'time', setter: { componentName: 'DateSetter', props: { format: 'YYYY-MM-DD', }, }, title: '底部时间', condition: () => { const timeAlign = target?.parent?.getPropValue?.('!timeAlign') || 'left'; return timeAlign === 'bottom'; }, }, { name: 'timeLeft', setter: { componentName: 'DateSetter', props: { format: 'YYYY-MM-DD', }, }, title: '左侧时间', condition: () => { const timeAlign = target?.parent?.getPropValue?.('!timeAlign') || 'left'; return timeAlign === 'left'; }, }, { name: 'content', setter: 'TextAreaSetter', title: '右侧内容', }, { name: 'animation', setter: 'BoolSetter', title: '启用动画', defaultValue: true, }, ], }, }, initialValue: () => { return { primaryKey: String(Math.floor(Math.random() * 10000)), title: 'TimelineItem', }; }, }, }, }; }, extraProps: { getValue: (target, fieldValue) => { // const node = target.node; // const children = node.getChildren(); const map = target.node.children.map((child) => { const primaryKey = child.getPropValue('primaryKey') ? String(child.getPropValue('primaryKey')) : child.id; return { primaryKey, icon: child.getPropValue('icon'), title: child.getPropValue('title'), state: child.getPropValue('state'), time: child.getPropValue('time'), timeLeft: child.getPropValue('timeLeft'), content: child.getPropValue('content'), animation: child.getPropValue('animation'), }; }); return map; }, setValue: updateChildren, }, }, ], }, icon: '', category: '信息展示', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/timeline/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Timeline', title: '时间轴', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Timeline', main: '', destructuring: true, subName: '', }, props: [ { name: 'fold', propType: { type: 'arrayOf', value: { type: 'exact', value: [ { name: 'foldArea', propType: { type: 'arrayOf', value: 'number', }, }, { name: 'foldShow', propType: 'bool', }, ], }, }, description: '自定义折叠选项 示例`[{foldArea: [startIndex, endIndex], foldShow: boolean}]`', defaultValue: [], }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: true, nestingRule: { childWhitelist: ['Timeline.Item'], }, }, props: [ { name: 'items', title: '时间轴数据', setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'title', setter: 'StringSetter', supportVariable: true, isRequired: true, title: '标题', }, { name: 'icon', title: '图标', isRequired: true, setter: 'IconSetter', supportVariable: true, description: '图标', }, { name: 'state', setter: { componentName: 'RadioGroupSetter', props: { options: ['done', 'process', 'error', 'success'], }, }, title: '节点状态', defaultValue: 'done', }, { name: 'time', setter: 'DateSetter', supportVariable: true, title: '右侧时间', }, { name: 'timeLeft', setter: 'DateSetter', supportVariable: true, title: '左侧时间', }, { name: 'content', setter: 'TextAreaSetter', supportVariable: true, title: '右侧内容', }, { name: 'animation', setter: 'BoolSetter', supportVariable: true, title: '启用动画', defaultValue: true, }, ], }, }, initialValue: () => { return { primaryKey: String(Math.floor(Math.random() * 10000)), title: 'TimelineItem', }; }, }, }, }, extraProps: { getValue(target, fieldValue) { // const node = target.node; // const children = node.children; const map = target.node.children.map((child) => { const primaryKey = child.getPropValue('primaryKey') ? String(child.getPropValue('primaryKey')) : child.id; return { primaryKey, icon: child.getPropValue('icon'), title: child.getPropValue('title'), state: child.getPropValue('state'), time: child.getPropValue('time'), timeLeft: child.getPropValue('timeLeft'), content: child.getPropValue('content'), animation: child.getPropValue('animation'), }; }); return map; }, setValue(target, value) { const { node } = target; const map = {}; if (!Array.isArray(value)) { value = []; } value.forEach((item) => { const tabitem = Object.assign({}, item); map[item.primaryKey] = tabitem; }); node.children.mergeChildren( (child) => { const primaryKey = String(child.getPropValue('primaryKey')); if (Object.hasOwnProperty.call(map, primaryKey)) { child.setPropValue('icon', map[primaryKey].icon); child.setPropValue('title', map[primaryKey].title); child.setPropValue('content', map[primaryKey].content); child.setPropValue('state', map[primaryKey].state); child.setPropValue('time', map[primaryKey].time); child.setPropValue('timeLeft', map[primaryKey].timeLeft); child.setPropValue('animation', map[primaryKey].animation); delete map[primaryKey]; return false; } return true; }, () => { const items = []; for (const primaryKey in map) { if (Object.hasOwnProperty.call(map, primaryKey)) { items.push({ componentName: 'Timeline.Item', props: map[primaryKey], }); } } return items; }, (child1, child2) => { const a = value.findIndex( (item) => String(item.primaryKey) === String(child1.getPropValue('primaryKey')), ); const b = value.findIndex( (item) => String(item.primaryKey) === String(child2.getPropValue('primaryKey')), ); return a - b; }, ); }, }, }, ], }, icon: '', category: '信息展示', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/timeline/snippets.ts ================================================ module.exports = [ { title: '时间轴', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_timeline.png', schema: { componentName: 'Timeline', props: { prefix: 'next-', fold: [], animation: true, }, children: [ { componentName: 'Timeline.Item', props: { state: 'process', title: 'Buy', time: '2022-02-01', }, }, { componentName: 'Timeline.Item', props: { title: 'Ship', time: '2022-02-01', }, }, { componentName: 'Timeline.Item', props: { title: 'Order', time: '2022-02-01', }, }, ], }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/timeline-item/meta.design.ts ================================================ export default { group: '原子组件', componentName: 'Timeline.Item', title: '时间轴项', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Timeline', main: '', destructuring: true, subName: 'Item', }, props: [ { name: 'state', propType: { type: 'oneOf', value: ['done', 'process', 'error', 'success'], }, description: '节点状态', defaultValue: 'done', }, { name: 'icon', propType: 'string', description: '图标', }, { name: 'dot', propType: 'node', description: '自定义时间轴节点', }, { name: 'time', propType: 'string', description: '格式化后的时间', }, { name: 'title', propType: { type: 'oneOfType', value: ['string', 'node'], }, description: '标题', }, { name: 'timeLeft', propType: 'string', description: '左侧时间', }, { name: 'content', propType: { type: 'oneOfType', value: ['string', 'node'], }, description: '右侧内容', }, { name: 'animation', propType: 'bool', description: '动画', defaultValue: true, }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: false, nestingRule: { parentWhitelist: ['Timeline'], }, }, props: [ { name: 'title', setter: 'StringSetter', supportVariable: true, title: '标题', }, { name: 'icon', title: '图标', setter: 'IconSetter', supportVariable: true, description: '图标', }, { name: 'state', setter: { componentName: 'RadioGroupSetter', props: { options: ['done', 'process', 'error', 'success'], }, }, title: '节点状态', defaultValue: 'done', }, { name: 'time', setter: 'DateSetter', supportVariable: true, title: '右侧时间', }, { name: 'timeLeft', setter: 'DateSetter', supportVariable: true, title: '左侧时间', }, { name: 'content', setter: 'TextAreaSetter', supportVariable: true, title: '右侧内容', }, { name: 'animation', setter: 'BoolSetter', supportVariable: true, title: '启用动画', defaultValue: true, }, ], advanced: { callbacks: { onHoverHook: () => false, onMouseDownHook: () => false, onClickHook: () => false, onMove: () => false, }, }, }, icon: '', category: 'null', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/timeline-item/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Timeline.Item', title: '时间轴项', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Timeline', main: '', destructuring: true, subName: 'Item', }, props: [ { name: 'state', propType: { type: 'oneOf', value: ['done', 'process', 'error', 'success'], }, description: '节点状态', defaultValue: 'done', }, { name: 'icon', propType: 'string', description: '图标', }, { name: 'dot', propType: 'node', description: '自定义时间轴节点', }, { name: 'time', propType: 'string', description: '格式化后的时间', }, { name: 'title', propType: { type: 'oneOfType', value: ['string', 'node'], }, description: '标题', }, { name: 'timeLeft', propType: 'string', description: '左侧时间', }, { name: 'content', propType: { type: 'oneOfType', value: ['string', 'node'], }, description: '右侧内容', }, { name: 'animation', propType: 'bool', description: '动画', defaultValue: true, }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: false, nestingRule: { parentWhitelist: ['Timeline'], }, }, props: [ { name: 'title', setter: 'StringSetter', supportVariable: true, title: '标题', }, { name: 'icon', title: '图标', setter: 'IconSetter', supportVariable: true, description: '图标', }, { name: 'state', setter: { componentName: 'RadioGroupSetter', props: { options: ['done', 'process', 'error', 'success'], }, }, title: '节点状态', defaultValue: 'done', }, { name: 'time', setter: 'DateSetter', supportVariable: true, title: '右侧时间', }, { name: 'timeLeft', setter: 'DateSetter', supportVariable: true, title: '左侧时间', }, { name: 'content', setter: 'TextAreaSetter', supportVariable: true, title: '右侧内容', }, { name: 'animation', setter: 'BoolSetter', supportVariable: true, title: '启用动画', defaultValue: true, }, ], }, icon: '', category: 'null', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/toast/meta.design.ts ================================================ export default { group: '原子组件', componentName: 'Message', title: '提示', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Message', main: '', destructuring: true, subName: '', }, props: [ { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, { name: 'title', title: { label: { type: 'i18n', zh_CN: '标题', en_US: 'Title', }, tip: { type: 'i18n', zh_CN: '属性: title | 说明: 标题', en_US: 'prop: title | description: Title', }, }, propType: 'string', description: '标题', defaultValue: '标题', }, { name: 'type', title: { label: { type: 'i18n', zh_CN: '类型', en_US: 'Type', }, tip: { type: 'i18n', zh_CN: '属性: type | 说明: 反馈类型', en_US: 'prop: type | description: message type', }, }, propType: { type: 'oneOf', value: ['success', 'warning', 'error', 'notice', 'help', 'loading'], }, description: '反馈类型', defaultValue: 'success', }, { name: 'shape', title: { label: { type: 'i18n', zh_CN: '形状', en_US: 'Shape', }, tip: { type: 'i18n', zh_CN: '属性: shape | 说明: 外观', en_US: 'prop: shape | description: message shape', }, }, propType: { type: 'oneOf', value: [ { label: 'Inline', value: 'inline', }, { label: 'Addon', value: 'addon', }, { label: 'Toast', value: 'toast', }, ], }, description: '外观', defaultValue: 'inline', }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 尺寸', en_US: 'prop: size | description: message size', }, }, propType: { type: 'oneOf', value: ['medium', 'large'], }, description: '尺寸', defaultValue: 'medium', }, { name: 'children', title: { label: { type: 'i18n', zh_CN: '文本', en_US: 'Content', }, tip: { type: 'i18n', zh_CN: '属性: children | 说明: 文本内容', en_US: 'prop: children | description: message content', }, }, propType: { type: 'oneOfType', value: ['string', 'node'], }, description: '内容', }, { name: 'visible', title: { label: { type: 'i18n', zh_CN: '是否显示', en_US: 'Visible', }, tip: { type: 'i18n', zh_CN: '属性: visible | 说明: 当前是否显示', en_US: 'prop: visible | description: visible', }, }, propType: 'bool', description: '当前是否显示', }, { name: 'iconType', propType: 'string', description: '显示的图标类型,会覆盖内部设置的IconType', }, { name: 'closeable', title: { label: { type: 'i18n', zh_CN: '显示 Close', en_US: 'Show Close', }, tip: { type: 'i18n', zh_CN: '属性: closeable | 说明: 显示关闭按钮', en_US: 'prop: closeable | description: show close button', }, }, propType: 'bool', description: '显示关闭按钮', defaultValue: false, }, { name: 'onClose', propType: 'func', description: '关闭按钮的回调', }, { name: 'afterClose', propType: 'func', description: '关闭之后调用的函数', }, { name: 'animation', title: { label: { type: 'i18n', zh_CN: '开启动效', en_US: 'Animation', }, tip: { type: 'i18n', zh_CN: '属性: animation | 说明: 是否开启动效', en_US: 'prop: animation | description: enable animation', }, }, propType: 'bool', description: '收起动画', defaultValue: true, }, ], configure: { props: [ { name: 'shape', title: { label: { type: 'i18n', zh_CN: '形状', en_US: 'Shape', }, tip: { type: 'i18n', zh_CN: '属性: shape | 说明: 外观', en_US: 'prop: shape | description: message shape', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['inline', 'addon', 'toast'] }, }, description: '外观', defaultValue: 'inline', }, { name: 'type', title: { label: { type: 'i18n', zh_CN: '类型', en_US: 'Type', }, tip: { type: 'i18n', zh_CN: '属性: type | 说明: 反馈类型', en_US: 'prop: type | description: message type', }, }, setter: { componentName: 'SelectSetter', props: { options: [ { label: '成功', value: 'success', }, { label: '警告', value: 'warning', }, { label: '失败', value: 'error', }, { label: '提示', value: 'notice', }, { label: '帮助', value: 'help', }, { label: '加载', value: 'loading', }, ], }, }, description: '反馈类型', defaultValue: 'success', }, { name: 'title', title: { label: { type: 'i18n', zh_CN: '标题', en_US: 'Title', }, tip: { type: 'i18n', zh_CN: '属性: title | 说明: 标题', en_US: 'prop: title | description: Title', }, }, setter: 'StringSetter', description: '标题', defaultValue: '标题', }, { name: 'iconType', title: { label: { type: 'i18n', zh_CN: '图标', en_US: 'Icon', }, tip: { type: 'i18n', zh_CN: '属性: iconType | 说明: 显示的图标类型', en_US: 'prop: iconType | description: icon type', }, }, setter: { componentName: 'IconSetter', }, }, { name: 'children', title: { label: { type: 'i18n', zh_CN: '文本', en_US: 'Content', }, tip: { type: 'i18n', zh_CN: '属性: children | 说明: 文本内容', en_US: 'prop: children | description: message content', }, }, setter: 'TextAreaSetter', description: '内容', }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 尺寸', en_US: 'prop: size | description: message size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '中', value: 'medium', }, { label: '大', value: 'large', }, ], }, }, description: '尺寸', defaultValue: 'medium', }, { name: 'style.width', title: '宽度', setter: 'NumberSetter', }, { name: 'visible', title: { label: { type: 'i18n', zh_CN: '是否显示', en_US: 'Visible', }, tip: { type: 'i18n', zh_CN: '属性: visible | 说明: 当前是否显示', en_US: 'prop: visible | description: visible', }, }, setter: 'BoolSetter', description: '当前是否显示', }, { name: 'closeable', title: { label: { type: 'i18n', zh_CN: '关闭按钮', en_US: 'Show Close', }, tip: { type: 'i18n', zh_CN: '属性: closeable | 说明: 显示关闭按钮', en_US: 'prop: closeable | description: show close button', }, }, setter: 'BoolSetter', description: '显示关闭按钮', defaultValue: false, }, { name: 'animation', title: { label: { type: 'i18n', zh_CN: '开启动效', en_US: 'Animation', }, tip: { type: 'i18n', zh_CN: '属性: animation | 说明: 是否开启动效', en_US: 'prop: animation | description: enable animation', }, }, setter: 'BoolSetter', description: '收起动画', defaultValue: true, }, ], }, icon: '', category: '信息反馈', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/toast/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Message', title: '面包片', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Message', main: '', destructuring: true, subName: '', }, props: [ { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, { name: 'title', title: { label: { type: 'i18n', zh_CN: '标题', en_US: 'Title', }, tip: { type: 'i18n', zh_CN: '属性: title | 说明: 标题', en_US: 'prop: title | description: Title', }, }, propType: 'string', description: '标题', defaultValue: '标题', }, { name: 'type', title: { label: { type: 'i18n', zh_CN: '类型', en_US: 'Type', }, tip: { type: 'i18n', zh_CN: '属性: type | 说明: 反馈类型', en_US: 'prop: type | description: message type', }, }, propType: { type: 'oneOf', value: ['success', 'warning', 'error', 'notice', 'help', 'loading'], }, description: '反馈类型', defaultValue: 'success', }, { name: 'shape', title: { label: { type: 'i18n', zh_CN: '形状', en_US: 'Shape', }, tip: { type: 'i18n', zh_CN: '属性: shape | 说明: 外观', en_US: 'prop: shape | description: message shape', }, }, propType: { type: 'oneOf', value: ['inline', 'addon', 'toast'], }, description: '外观', defaultValue: 'inline', }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 尺寸', en_US: 'prop: size | description: message size', }, }, propType: { type: 'oneOf', value: ['medium', 'large'], }, description: '尺寸', defaultValue: 'medium', }, { name: 'children', title: { label: { type: 'i18n', zh_CN: '文本', en_US: 'Content', }, tip: { type: 'i18n', zh_CN: '属性: children | 说明: 文本内容', en_US: 'prop: children | description: message content', }, }, propType: { type: 'oneOfType', value: ['string', 'node'], }, description: '内容', }, { name: 'visible', title: { label: { type: 'i18n', zh_CN: '是否显示', en_US: 'Visible', }, tip: { type: 'i18n', zh_CN: '属性: visible | 说明: 当前是否显示', en_US: 'prop: visible | description: visible', }, }, propType: 'bool', description: '当前是否显示', }, { name: 'iconType', propType: 'string', description: '显示的图标类型,会覆盖内部设置的IconType', }, { name: 'closeable', title: { label: { type: 'i18n', zh_CN: '显示 Close', en_US: 'Show Close', }, tip: { type: 'i18n', zh_CN: '属性: closeable | 说明: 显示关闭按钮', en_US: 'prop: closeable | description: show close button', }, }, propType: 'bool', description: '显示关闭按钮', defaultValue: false, }, { name: 'onClose', propType: 'func', description: '关闭按钮的回调', }, { name: 'afterClose', propType: 'func', description: '关闭之后调用的函数', }, { name: 'animation', title: { label: { type: 'i18n', zh_CN: '开启动效', en_US: 'Animation', }, tip: { type: 'i18n', zh_CN: '属性: animation | 说明: 是否开启动效', en_US: 'prop: animation | description: enable animation', }, }, propType: 'bool', description: '收起动画', defaultValue: true, }, ], configure: { props: { isExtends: true, override: [ { name: 'iconType', title: { label: { type: 'i18n', zh_CN: '图标', en_US: 'Icon', }, tip: { type: 'i18n', zh_CN: '属性: iconType | 说明: 显示的图标类型', en_US: 'prop: iconType | description: icon type', }, }, setter: { componentName: 'IconSetter', }, }, ], }, }, icon: '', category: '信息反馈', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/toast/snippets.ts ================================================ module.exports = [ { title: '面包片', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_message.png', schema: { componentName: 'Message', props: { title: 'Toast', type: 'success', shape: 'toast', size: 'medium', visible: true, animation: true, children: 'This item already has the label "travel", you can add a new label.', }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/tooltip/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Tooltip', title: 'Tooltip', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Balloon', main: '', destructuring: true, subName: 'Tooltip', }, props: [ { name: 'prefix', propType: 'string', description: '样式类名的品牌前缀', defaultValue: 'next-', }, { name: 'className', propType: 'string', description: '自定义类名', }, { name: 'style', propType: 'object', description: '自定义内联样式', }, { name: 'children', propType: 'node', description: 'tooltip的内容', }, { name: 'align', propType: { type: 'oneOf', value: ['t', 'r', 'b', 'l', 'tl', 'tr', 'bl', 'br', 'lt', 'lb', 'rt', 'rb'], }, description: '弹出层位置\n@enumdesc 上, 右, 下, 左, 上左, 上右, 下左, 下右, 左上, 左下, 右上, 右下 及其 两两组合', defaultValue: 'b', }, { name: 'trigger', propType: 'node', description: '触发元素', }, { name: 'triggerType', propType: { type: 'oneOf', value: ['hover', 'click'], }, description: "触发行为\n鼠标悬浮, 鼠标点击('hover', 'click')或者它们组成的数组,如 ['hover', 'click'], 强烈不建议使用'focus',若有复杂交互,推荐使用triggerType为click的Balloon组件", defaultValue: 'hover', }, { name: 'popupStyle', propType: 'object', description: '弹层组件style,透传给Popup', }, { name: 'popupClassName', propType: 'string', description: '弹层组件className,透传给Popup', }, { name: 'popupProps', propType: 'object', description: '弹层组件属性,透传给Popup', }, { name: 'pure', propType: 'bool', description: '是否pure render', }, { name: 'popupContainer', propType: 'string', description: '指定浮层渲染的父节点, 可以为节点id的字符串,也可以返回节点的函数。', }, { name: 'followTrigger', propType: 'bool', description: '是否跟随滚动', }, { name: 'id', propType: 'string', description: '弹层id, 传入值才会支持无障碍', }, { name: 'delay', propType: 'number', description: '如果需要让 Tooltip 内容可被点击,可以设置这个参数,例如 100', defaultValue: 0, }, ], category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/transfer/meta.design.ts ================================================ import snippets from './snippets.design'; import parseData from '../utils/parse-data'; export default { group: '原子组件', componentName: 'Transfer', title: '穿梭框', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Transfer', main: '', destructuring: true, subName: '', }, props: [ { name: 'id', propType: 'string', description: '请设置 id 以保证transfer的可访问性', }, { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, { name: 'rtl', propType: 'bool', }, { name: 'mode', propType: { type: 'oneOf', value: ['normal', 'simple'], }, description: '移动选项模式', defaultValue: 'normal', }, { name: 'dataSource', propType: 'array', description: '数据源', }, { name: 'value', propType: 'array', description: '当前值', }, { name: 'defaultValue', propType: 'array', description: '默认值', }, { name: 'disabled', propType: 'bool', description: '是否禁用', defaultValue: false, }, { name: 'leftDisabled', propType: 'bool', description: '是否禁用左侧面板', defaultValue: false, }, { name: 'rightDisabled', propType: 'bool', description: '是否禁用右侧面板', defaultValue: false, }, { name: 'itemRender', propType: 'func', description: '列表项渲染函数', }, { name: 'showSearch', propType: 'bool', description: '是否显示搜索框', defaultValue: false, }, { name: 'filter', propType: 'func', description: '自定义搜索函数', }, { name: 'searchPlaceholder', propType: 'string', description: '搜索框占位符', }, { name: 'notFoundContent', propType: { type: 'instanceOf', value: 'node', }, description: '列表为空显示内容', defaultValue: 'Not Found', }, { name: 'titles', propType: 'array', description: '左右面板标题', }, { name: 'operations', propType: 'array', description: '向右向左移动按钮显示内容', }, { name: 'defaultLeftChecked', propType: 'array', description: '左面板默认选中值', }, { name: 'defaultRightChecked', propType: 'array', description: '右面板默认选中值', }, { name: 'listClassName', propType: 'string', description: '左右面板列表自定义样式类名', }, { name: 'listStyle', propType: 'object', description: '左右面板列表自定义样式对象', }, { name: 'sortable', propType: 'bool', description: '是否允许拖拽排序', defaultValue: false, }, { name: 'children', propType: 'func', description: '接收 children 自定义渲染列表', }, { name: 'onChange', propType: 'func', description: '值发生改变的时候触发的回调函数', }, { name: 'onSearch', propType: 'func', description: '搜索框输入时触发的回调函数', }, { name: 'onSort', propType: 'func', description: '拖拽排序时触发的回调函数', }, ], configure: { props: [ { name: 'mode', title: '类型', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '普通', value: 'normal' }, { title: '简单', value: 'simple' }, ], }, }, defaultValue: 'normal', }, { name: 'titles.0', title: '左侧标题', setter: 'StringSetter', defaultValue: 'TitleLeft', }, { name: 'titles.1', title: '右侧标题', setter: 'StringSetter', defaultValue: 'TitleRight', }, { name: 'showSearch', title: '搜索框', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '无', value: false }, { title: '有', value: true }, ], }, }, defaultValue: false, }, { name: 'showCheckAll', title: '显示全选', setter: 'BoolSetter', defaultValue: true, }, { name: 'searchPlaceholder', title: '占位符', setter: 'StringSetter', condition(target) { return target.getProps().getPropValue('showSearch') || false; }, }, { name: 'sortable', title: '拖拽排序', setter: 'BoolSetter', defaultValue: false, }, { name: 'plainData', display: 'block', title: '内容', setter: { componentName: 'MagicEditorSetter', props: { toolbar: ['normal', 'active', 'disable'], disableIcon: true, }, }, setValue: (target, value) => { const list = parseData(value).filter(({ type }) => type === 'node'); const keys = []; const dataSource = list.map((item, i) => { if (item.state === 'active') { keys.push(`${i}`); } return { label: `${item.value}`, value: `${i}`, disabled: item.state === 'disabled', }; }); target.parent.setPropValue('dataSource', dataSource); target.parent.setPropValue('defaultLeftChecked', keys); }, }, ], supports: { events: ['onChange', 'onSearch', 'onSort'], }, }, icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/transfer/meta.ts ================================================ import snippets from './snippets'; export default { group: '原子组件', componentName: 'Transfer', title: '穿梭框', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Transfer', main: '', destructuring: true, subName: '', }, props: [ { name: 'id', propType: 'string', description: '请设置 id 以保证transfer的可访问性', }, { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, { name: 'rtl', propType: 'bool', }, { name: 'mode', propType: { type: 'oneOf', value: ['normal', 'simple'], }, description: '移动选项模式', defaultValue: 'normal', }, { name: 'dataSource', propType: 'array', description: '数据源', }, { name: 'value', propType: 'array', description: '当前值', }, { name: 'defaultValue', propType: 'array', description: '默认值', }, { name: 'disabled', propType: 'bool', description: '是否禁用', defaultValue: false, }, { name: 'leftDisabled', propType: 'bool', description: '是否禁用左侧面板', defaultValue: false, }, { name: 'rightDisabled', propType: 'bool', description: '是否禁用右侧面板', defaultValue: false, }, { name: 'itemRender', propType: 'func', description: '列表项渲染函数', }, { name: 'showSearch', propType: 'bool', description: '是否显示搜索框', defaultValue: false, }, { name: 'filter', propType: 'func', description: '自定义搜索函数', }, { name: 'searchPlaceholder', propType: 'string', description: '搜索框占位符', }, { name: 'notFoundContent', propType: { type: 'instanceOf', value: 'node', }, description: '列表为空显示内容', defaultValue: 'Not Found', }, { name: 'titles', propType: 'array', description: '左右面板标题', }, { name: 'operations', propType: 'array', description: '向右向左移动按钮显示内容', }, { name: 'defaultLeftChecked', propType: 'array', description: '左面板默认选中值', }, { name: 'defaultRightChecked', propType: 'array', description: '右面板默认选中值', }, { name: 'listClassName', propType: 'string', description: '左右面板列表自定义样式类名', }, { name: 'listStyle', propType: 'object', description: '左右面板列表自定义样式对象', }, { name: 'sortable', propType: 'bool', description: '是否允许拖拽排序', defaultValue: false, }, { name: 'children', propType: 'func', description: '接收 children 自定义渲染列表', }, { name: 'onChange', propType: 'func', description: '值发生改变的时候触发的回调函数', }, { name: 'onSearch', propType: 'func', description: '搜索框输入时触发的回调函数', }, { name: 'onSort', propType: 'func', description: '拖拽排序时触发的回调函数', }, ], configure: { props: [ { name: 'value', title: '当前值', setter: ['NumberSetter', 'ExpressionSetter'], }, { name: 'defaultValue', title: '默认值', setter: ['NumberSetter', 'ExpressionSetter'], }, { name: 'mode', title: '模式', setter: { componentName: 'MixedSetter', props: { setters: [ { componentName: 'RadioGroupSetter', props: { options: [ { title: 'normal', value: 'normal' }, { title: 'simple', value: 'simple' }, ], }, }, 'ExpressionSetter', ], }, }, defaultValue: 'simple', }, { name: 'showCheckAll', title: '显示全选', setter: { componentName: 'MixedSetter', props: { setters: ['BoolSetter', 'ExpressionSetter'], }, }, defaultValue: true, }, { name: 'showSearch', title: '搜索框', setter: { componentName: 'MixedSetter', props: { setters: ['BoolSetter', 'ExpressionSetter'], }, }, defaultValue: false, }, { name: 'searchPlaceholder', title: '搜索框占位符', display: 'block', setter: { componentName: 'MixedSetter', props: { setters: ['StringSetter', 'ExpressionSetter'], }, }, condition(target) { return target.parent.getPropValue('showSearch') || false; }, }, { name: 'filter', title: '自定义搜索函数', display: 'block', setter: { componentName: 'FunctionSetter', // props: { // defaultActionName="filter", // defaultCode=`function filter(searchedValue, data) { // return true; // }`, // } }, condition(target) { return target.parent.getPropValue('showSearch') || false; }, }, { name: 'sortable', title: '拖拽排序', setter: { componentName: 'MixedSetter', props: { setters: ['BoolSetter', 'ExpressionSetter'], }, }, defaultValue: false, }, { name: 'dataSource', title: '数据源', display: 'block', setter: { componentName: 'MixedSetter', props: { setters: [ { componentName: 'JsonSetter', }, 'ExpressionSetter', ], }, }, defaultValue: [ { label: 'item0', value: '0', disabled: false }, { label: 'item1', value: '1', disabled: false }, { label: 'item2', value: '2', disabled: true }, ], }, { name: 'defaultLeftChecked', title: '左侧面板默认选中值', display: 'block', setter: { componentName: 'MixedSetter', props: { setters: [ { componentName: 'JsonSetter', }, 'ExpressionSetter', ], }, }, defaultValue: ['1'], }, { name: 'defaultRightChecked', title: '右侧面板默认选中值', display: 'block', setter: { componentName: 'MixedSetter', props: { setters: [ { componentName: 'JsonSetter', }, 'ExpressionSetter', ], }, }, defaultValue: ['1'], }, { name: 'titles', title: '面板标题', display: 'block', setter: { componentName: 'MixedSetter', props: { setters: [ { componentName: 'JsonSetter', }, 'ExpressionSetter', ], }, }, defaultValue: ['TitleLeft', 'TitleRight'], }, { name: 'notFountContent', title: '无数据时显示内容', display: 'block', setter: { componentName: 'MixedSetter', props: { setters: [ { componentName: 'StringSetter', }, 'ExpressionSetter', ], }, }, defaultValue: ['无数据'], }, { name: 'itemRender', title: '列表项渲染函数', display: 'block', setter: { componentName: 'FunctionSetter', // props: { // defaultActionName="itemRender", // defaultCode=`function itemRender(data) { // return data.label; // }`, // } }, }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', supportVariable: true, }, ], }, { name: 'style', setter: { componentName: 'StyleSetter', }, }, ], supports: { events: ['onChange', 'onSearch', 'onSort'], }, }, icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/transfer/snippets.design.ts ================================================ import parseData from '../utils/parse-data'; const plainData = 'Content1\nContent2\n*Content3\n*Content4\n*Content5\nContent6\nContent7\nContent8\nContent9\nContent10'; const list = parseData(plainData).filter(({ type }) => type === 'node'); const keys = []; const dataSource = list.map((item, i) => { if (item.state === 'active') { keys.push(`${i}`); } return { label: `${item.value}`, value: `${i}`, disabled: item.state === 'disabled', }; }); export default [ { title: '穿梭框', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_transfer.png', schema: { componentName: 'Transfer', props: { prefix: 'next-', mode: 'normal', titles: ['TitleLeft', 'TitleRight'], dataSource, plainData, defaultLeftChecked: keys, notFoundContent: 'Not Found', }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/transfer/snippets.ts ================================================ export default [ { title: '穿梭框', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_transfer.png', schema: { componentName: 'Transfer', props: { prefix: 'next-', mode: 'normal', titles: ['TitleLeft', 'TitleRight'], notFoundContent: 'Not Found', }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/tree/adaptor.ts ================================================ export const createDataSource = ( list, keys = { selected: [], expanded: [] }, level = 0, prefix = '', ) => { const array = []; let index = 0; list.forEach((item) => { const key = `${prefix || level}-${index++}`; if (item.children && item.children.length > 0) { item.children = createDataSource(item.children, keys, level + 1, key); } if (typeof Array.isArray(item.value) && item.value.length) { let _label, _icon; item.value.forEach((i) => { if (i.type === 'icon') { _icon = i.value; } else { _label = i.value; } }); array.push({ label: _label, icon: _icon, disabled: item.state === 'disabled', key, children: item.children, }); } else { array.push({ label: item.value, disabled: item.state === 'disabled', key, children: item.children, }); } if (item.state === 'active') { if (item.children && item.children.length > 0) { keys.expanded.push(key); } else { keys.selected.push(key); } } return; }); return array; }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/tree/meta.design.ts ================================================ import snippets from './snippets.design'; import parseData from '../utils/parse-data'; import { createDataSource } from './adaptor'; export default { group: '原子组件', componentName: 'Tree', title: '树形控件', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Tree', main: '', destructuring: true, subName: '', }, props: [ { name: 'className', propType: 'string', }, { name: 'dataSource', propType: { type: 'object', }, description: '数据源,该属性优先级高于 children', }, { name: 'showLine', propType: 'bool', description: '是否显示树的线', defaultValue: false, }, { name: 'selectable', propType: 'bool', description: '是否支持选中节点', defaultValue: true, }, { name: 'onSelect', propType: 'func', description: '选中或取消选中节点时触发的回调函数\n@param {Array} selectedKeys 选中节点key的数组\n@param {Object} extra 额外参数\n@param {Array} extra.selectedNodes 选中节点的数组\n@param {Object} extra.node 当前操作的节点\n@param {Boolean} extra.selected 当前操作是否是选中', }, { name: 'multiple', propType: 'bool', description: '是否支持多选', defaultValue: false, }, { name: 'checkable', propType: 'bool', description: '是否支持勾选节点的复选框', defaultValue: false, }, { name: 'checkStrictly', propType: 'bool', description: '勾选节点复选框是否完全受控(父子节点选中状态不再关联)', defaultValue: false, }, { name: 'checkedStrategy', propType: { type: 'oneOf', value: ['all', 'parent', 'child'], }, description: '定义选中时回填的方式\n@enumdesc 返回所有选中的节点, 父子节点都选中时只返回父节点, 父子节点都选中时只返回子节点', defaultValue: 'all', }, { name: 'onCheck', propType: 'func', description: '勾选或取消勾选复选框时触发的回调函数\n@param {Array} checkedKeys 勾选复选框节点key的数组\n@param {Object} extra 额外参数\n@param {Array} extra.checkedNodes 勾选复选框节点的数组\n@param {Array} extra.checkedNodesPositions 包含有勾选复选框节点和其位置的对象的数组\n@param {Array} extra.indeterminateKeys 半选复选框节点 key 的数组\n@param {Object} extra.node 当前操作的节点\n@param {Boolean} extra.checked 当前操作是否是勾选', }, { name: 'defaultExpandAll', propType: 'bool', description: '是否默认展开所有节点', defaultValue: false, }, { name: 'autoExpandParent', propType: 'bool', description: '是否自动展开父节点,建议受控时设置为false', defaultValue: true, }, { name: 'onExpand', propType: 'func', description: '展开或收起节点时触发的回调函数\n@param {Array} expandedKeys 展开的节点key的数组\n@param {Object} extra 额外参数\n@param {Object} extra.node 当前操作的节点\n@param {Boolean} extra.expanded 当前操作是否是展开', }, { name: 'editable', propType: 'bool', description: '是否支持编辑节点内容', defaultValue: false, }, { name: 'onEditFinish', propType: 'func', description: '编辑节点内容完成时触发的回调函数\n@param {String} key 编辑节点的 key\n@param {String} label 编辑节点完成时节点的文本\n@param {Object} node 当前编辑的节点', }, { name: 'draggable', propType: 'bool', description: '是否支持拖拽节点', defaultValue: false, }, { name: 'onDragStart', propType: 'func', description: '开始拖拽节点时触发的回调函数\n@param {Object} info 拖拽信息\n@param {Object} info.event 事件对象\n@param {Object} info.node 拖拽的节点', }, { name: 'onDragEnter', propType: 'func', description: '拖拽节点进入目标节点时触发的回调函数\n@param {Object} info 拖拽信息\n@param {Object} info.event 事件对象\n@param {Object} info.node 目标节点\n@param {Array} info.expandedKeys 当前展开的节点key的数组', }, { name: 'onDragOver', propType: 'func', description: '拖拽节点在目标节点上移动的时候触发的回调函数\n@param {Object} info 拖拽信息\n@param {Object} info.event 事件对象\n@param {Object} info.node 目标节点', }, { name: 'onDragLeave', propType: 'func', description: '拖拽节点离开目标节点时触发的回调函数\n@param {Object} info 拖拽信息\n@param {Object} info.event 事件对象\n@param {Object} info.node 目标节点', }, { name: 'onDragEnd', propType: 'func', description: '拖拽节点拖拽结束时触发的回调函数\n@param {Object} info 拖拽信息\n@param {Object} info.event 事件对象\n@param {Object} info.node 目标节点', }, { name: 'onDrop', propType: 'func', description: '拖拽节点放入目标节点内或前后触发的回调函数\n@param {Object} info 拖拽信息\n@param {Object} info.event 事件对象\n@param {Object} info.node 目标节点\n@param {Object} info.dragNode 拖拽的节点\n@param {Array} info.dragNodesKeys 拖拽的节点和其子节点 key 的数组\n@param {Number} info.dropPosition 放置位置,-1代表当前节点前,0代表当前节点里,1代表当前节点后', }, { name: 'canDrop', propType: 'func', description: '节点是否可被作为拖拽的目标节点', }, { name: 'loadData', propType: 'func', description: '异步加载数据的函数', }, { name: 'filterTreeNode', propType: 'func', description: '按需筛选高亮节点', }, { name: 'onRightClick', propType: 'func', description: '右键点击节点时触发的回调函数', }, { name: 'isLabelBlock', propType: 'bool', description: '设置节点是否占满剩余空间,一般用于统一在各节点右侧添加元素(借助 flex 实现,暂时只支持 ie10+)', defaultValue: false, }, { name: 'isNodeBlock', propType: 'bool', description: '设置节点是否占满一行', defaultValue: false, }, { name: 'animation', propType: 'bool', description: '是否开启展开收起动画', defaultValue: true, }, { name: 'focusedKey', propType: 'string', description: '当前获得焦点的子菜单或菜单项 key 值', }, { name: 'renderChildNodes', propType: 'func', description: '渲染子节点', }, { name: 'useVirtual', propType: 'bool', description: '是否开启虚拟滚动', }, { name: 'onItemFocus', propType: 'func', }, { name: 'onBlur', propType: 'func', }, { name: 'onItemKeyDown', propType: 'func', }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: true, }, props: [ { name: 'showLine', title: '类型', defaultValue: false, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '普通', value: false, }, { label: '线性树', value: true, }, ], }, }, }, { name: 'isNodeBlock', title: '选择模式', defaultValue: false, condition: (target) => !target?.parent?.getPropValue('showLine'), setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '节点', value: true, }, { label: '标签', value: false, }, ], }, }, }, { name: 'multiple', title: '支持多选', setter: { componentName: 'BoolSetter', }, description: '是否支持多选', defaultValue: false, }, { name: 'checkable', title: '复选框', setter: { componentName: 'BoolSetter', }, description: '是否支持勾选节点的复选框', defaultValue: false, }, { name: 'editable', title: '支持编辑', setter: { componentName: 'BoolSetter', }, defaultValue: false, }, { name: 'draggable', title: '支持拖拽', setter: { componentName: 'BoolSetter', }, defaultValue: false, }, { name: 'selectable', title: '支持选中', setter: { componentName: 'BoolSetter', }, defaultValue: false, }, { name: 'plainData', display: 'block', title: '选项', tip: { title: '数据格式', url: '', }, setValue: (target, value) => { let keys = { selected: [], expanded: [] }; const parsedValue = createDataSource(parseData(value, { parseContent: true }), keys); target.parent.setPropValue('dataSource', parsedValue); if (keys && keys.selected) { target.parent.setPropValue('selectedKeys', keys.selected); } }, setter: { componentName: 'MagicEditorSetter', props: { toolbar: ['normal', 'active', 'disable'], }, }, }, // { // name: "defaultExpandedKeys", // display: "block", // title: "默认展开的节点", // setter: "JsonSetter", // supportVariable: true // }, // { // name: "defaultSelectedKeys", // display: "block", // title: "默认选中的节点", // setter: "JsonSetter", // supportVariable: true // } ], supports: { style: true, events: ['onSelect', 'onCheck', 'onExpand'], }, }, icon: '', category: '信息展示', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/tree/meta.ts ================================================ import snippets from './snippets'; export default { group: '原子组件', componentName: 'Tree', title: '树形控件', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Tree', main: '', destructuring: true, subName: '', }, props: [ { name: 'className', propType: 'string', }, { name: 'dataSource', propType: { type: 'object', }, description: '数据源,该属性优先级高于 children', }, { name: 'showLine', propType: 'bool', description: '是否显示树的线', defaultValue: false, }, { name: 'selectable', propType: 'bool', description: '是否支持选中节点', defaultValue: true, }, { name: 'onSelect', propType: 'func', description: '选中或取消选中节点时触发的回调函数\n@param {Array} selectedKeys 选中节点key的数组\n@param {Object} extra 额外参数\n@param {Array} extra.selectedNodes 选中节点的数组\n@param {Object} extra.node 当前操作的节点\n@param {Boolean} extra.selected 当前操作是否是选中', }, { name: 'multiple', propType: 'bool', description: '是否支持多选', defaultValue: false, }, { name: 'checkable', propType: 'bool', description: '是否支持勾选节点的复选框', defaultValue: false, }, { name: 'checkStrictly', propType: 'bool', description: '勾选节点复选框是否完全受控(父子节点选中状态不再关联)', defaultValue: false, }, { name: 'checkedStrategy', propType: { type: 'oneOf', value: ['all', 'parent', 'child'], }, description: '定义选中时回填的方式\n@enumdesc 返回所有选中的节点, 父子节点都选中时只返回父节点, 父子节点都选中时只返回子节点', defaultValue: 'all', }, { name: 'onCheck', propType: 'func', description: '勾选或取消勾选复选框时触发的回调函数\n@param {Array} checkedKeys 勾选复选框节点key的数组\n@param {Object} extra 额外参数\n@param {Array} extra.checkedNodes 勾选复选框节点的数组\n@param {Array} extra.checkedNodesPositions 包含有勾选复选框节点和其位置的对象的数组\n@param {Array} extra.indeterminateKeys 半选复选框节点 key 的数组\n@param {Object} extra.node 当前操作的节点\n@param {Boolean} extra.checked 当前操作是否是勾选', }, { name: 'defaultExpandAll', propType: 'bool', description: '是否默认展开所有节点', defaultValue: false, }, { name: 'autoExpandParent', propType: 'bool', description: '是否自动展开父节点,建议受控时设置为false', defaultValue: true, }, { name: 'onExpand', propType: 'func', description: '展开或收起节点时触发的回调函数\n@param {Array} expandedKeys 展开的节点key的数组\n@param {Object} extra 额外参数\n@param {Object} extra.node 当前操作的节点\n@param {Boolean} extra.expanded 当前操作是否是展开', }, { name: 'editable', propType: 'bool', description: '是否支持编辑节点内容', defaultValue: false, }, { name: 'onEditFinish', propType: 'func', description: '编辑节点内容完成时触发的回调函数\n@param {String} key 编辑节点的 key\n@param {String} label 编辑节点完成时节点的文本\n@param {Object} node 当前编辑的节点', }, { name: 'draggable', propType: 'bool', description: '是否支持拖拽节点', defaultValue: false, }, { name: 'onDragStart', propType: 'func', description: '开始拖拽节点时触发的回调函数\n@param {Object} info 拖拽信息\n@param {Object} info.event 事件对象\n@param {Object} info.node 拖拽的节点', }, { name: 'onDragEnter', propType: 'func', description: '拖拽节点进入目标节点时触发的回调函数\n@param {Object} info 拖拽信息\n@param {Object} info.event 事件对象\n@param {Object} info.node 目标节点\n@param {Array} info.expandedKeys 当前展开的节点key的数组', }, { name: 'onDragOver', propType: 'func', description: '拖拽节点在目标节点上移动的时候触发的回调函数\n@param {Object} info 拖拽信息\n@param {Object} info.event 事件对象\n@param {Object} info.node 目标节点', }, { name: 'onDragLeave', propType: 'func', description: '拖拽节点离开目标节点时触发的回调函数\n@param {Object} info 拖拽信息\n@param {Object} info.event 事件对象\n@param {Object} info.node 目标节点', }, { name: 'onDragEnd', propType: 'func', description: '拖拽节点拖拽结束时触发的回调函数\n@param {Object} info 拖拽信息\n@param {Object} info.event 事件对象\n@param {Object} info.node 目标节点', }, { name: 'onDrop', propType: 'func', description: '拖拽节点放入目标节点内或前后触发的回调函数\n@param {Object} info 拖拽信息\n@param {Object} info.event 事件对象\n@param {Object} info.node 目标节点\n@param {Object} info.dragNode 拖拽的节点\n@param {Array} info.dragNodesKeys 拖拽的节点和其子节点 key 的数组\n@param {Number} info.dropPosition 放置位置,-1代表当前节点前,0代表当前节点里,1代表当前节点后', }, { name: 'canDrop', propType: 'func', description: '节点是否可被作为拖拽的目标节点', }, { name: 'loadData', propType: 'func', description: '异步加载数据的函数', }, { name: 'filterTreeNode', propType: 'func', description: '按需筛选高亮节点', }, { name: 'onRightClick', propType: 'func', description: '右键点击节点时触发的回调函数', }, { name: 'isLabelBlock', propType: 'bool', description: '设置节点是否占满剩余空间,一般用于统一在各节点右侧添加元素(借助 flex 实现,暂时只支持 ie10+)', defaultValue: false, }, { name: 'isNodeBlock', propType: 'bool', description: '设置节点是否占满一行', defaultValue: false, }, { name: 'animation', propType: 'bool', description: '是否开启展开收起动画', defaultValue: true, }, { name: 'focusedKey', propType: 'string', description: '当前获得焦点的子菜单或菜单项 key 值', }, { name: 'renderChildNodes', propType: 'func', description: '渲染子节点', }, { name: 'useVirtual', propType: 'bool', description: '是否开启虚拟滚动', }, { name: 'onItemFocus', propType: 'func', }, { name: 'onBlur', propType: 'func', }, { name: 'onItemKeyDown', propType: 'func', }, { name: 'style', propType: 'object', }, ], configure: { component: { isContainer: true, }, props: [ { name: 'dataSource', title: '节点数据', setter: 'JsonSetter', supportVariable: true, }, { name: 'showLine', title: '显示线', setter: { componentName: 'BoolSetter', }, }, { name: 'multiple', title: '支持多选', setter: { componentName: 'BoolSetter', }, description: '是否支持多选', defaultValue: false, }, { name: 'checkable', title: '复选框', setter: { componentName: 'BoolSetter', }, description: '是否支持勾选节点的复选框', defaultValue: false, }, { name: 'editable', title: '支持编辑', setter: { componentName: 'BoolSetter', }, defaultValue: false, }, { name: 'draggable', title: '支持拖拽', setter: { componentName: 'BoolSetter', }, defaultValue: false, }, { name: 'selectable', title: '支持选中', setter: { componentName: 'BoolSetter', }, defaultValue: false, }, { name: 'defaultExpandedKeys', display: 'block', title: '默认展开的节点', setter: 'JsonSetter', supportVariable: true, }, { name: 'defaultSelectedKeys', display: 'block', title: '默认选中的节点', setter: 'JsonSetter', supportVariable: true, }, ], supports: { style: true, events: ['onSelect', 'onCheck', 'onExpand'], }, }, icon: '', category: '信息展示', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/tree/snippets.design.ts ================================================ import parseData from '../utils/parse-data'; import { createDataSource } from './adaptor'; const plainData = 'children\n\t123\n\t*[ashbin]333\n\t-222'; const keys = { selected: [], expanded: [] }; const dataSource = createDataSource(parseData(plainData, { parseContent: true }), keys); export default [ { title: '树形控件', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_tree.png', schema: { componentName: 'Tree', props: { prefix: 'next-', selectable: true, selectedKeys: keys.selected, defaultExpandAll: true, checkedStrategy: 'all', autoExpandParent: true, animation: true, focusable: true, plainData, dataSource, }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/tree/snippets.ts ================================================ import parseData from '../utils/parse-data'; import { createDataSource } from './adaptor'; const plainData = 'children\n\t123\n\t*[ashbin]333\n\t-222'; const keys = { selected: [], expanded: [] }; const dataSource = createDataSource(parseData(plainData, { parseContent: true }), keys); export default [ { title: '树形控件', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_tree.png', schema: { componentName: 'Tree', props: { prefix: 'next-', selectable: true, defaultExpandAll: true, checkedStrategy: 'all', autoExpandParent: true, animation: true, focusable: true, plainData, dataSource, }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/tree-node/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'TreeNode', title: '树形控件节点', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Tree', main: '', destructuring: true, subName: 'Node', }, props: [ { name: 'className', propType: 'string', }, { name: 'children', propType: { type: 'instanceOf', value: 'node', }, description: '树节点', }, { name: 'label', propType: { type: 'oneOfType', value: ['string', 'node'], }, description: '节点文本内容', defaultValue: '---', }, { name: 'selectable', propType: 'bool', description: '单独设置是否支持选中,覆盖 Tree 的 selectable', }, { name: 'checkable', propType: 'bool', description: '单独设置是否出现复选框,覆盖 Tree 的 checkable', }, { name: 'editable', propType: 'bool', description: '单独设置是否支持编辑,覆盖 Tree 的 editable', }, { name: 'draggable', propType: 'bool', description: '单独设置是否支持拖拽,覆盖 Tree 的 draggable', }, { name: 'disabled', propType: 'bool', description: '是否禁止节点响应', defaultValue: false, }, { name: 'checkboxDisabled', propType: 'bool', description: '是否禁止勾选节点复选框', defaultValue: false, }, { name: 'isLeaf', propType: 'bool', description: '是否是叶子节点', defaultValue: false, }, ], icon: '', category: '信息输入', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/tree-select/adaptor.ts ================================================ export const createDataSource = ( list, keys = { selected: [], expanded: [] }, level = 0, prefix = '', ) => { const array = []; let index = 0; list.forEach((item) => { const key = `${prefix || level}-${index++}`; if (item.children && item.children.length > 0) { item.children = createDataSource(item.children, keys, level + 1, key); } array.push({ label: item.value, value: key, disabled: item.state === 'disabled', key, children: item.children, }); if (item.state === 'active') { if (item.children && item.children.length > 0) { keys.expanded.push(key); } else { keys.selected.push(key); } } return; }); return array; }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/tree-select/meta.design.ts ================================================ import snippets from './snippets.design'; import parseData from '../utils/parse-data'; import { createDataSource } from './adaptor'; export default { group: '原子组件', componentName: 'TreeSelect', title: '树型选择控件', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'TreeSelect', main: '', destructuring: true, subName: '', }, configure: { component: { rootSelector: 'span.next-select', }, props: [ { name: 'visible', title: { label: '状态', tip: '属性: visible', }, defaultValue: true, setter: { componentName: 'RadioGroupSetter', props: { defaultValue: 'single', options: [ { value: false, title: '普通' }, { value: true, title: '展开' }, ], }, }, }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Button Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 按钮尺寸', en_US: 'prop: size | description: button size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '小', value: 'small', }, { label: '中', value: 'medium', }, { label: '大', value: 'large', }, ], }, }, defaultValue: 'medium', }, { name: 'hasBorder', title: { label: { type: 'i18n', zh_CN: '显示边框', en_US: 'ShowBorder', }, tip: { type: 'i18n', zh_CN: '属性: hasBorder | 说明: 是否有边框', en_US: 'prop: hasBorder | description: HasBorder', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '无', value: false, }, { label: '有', value: true, }, ], }, }, }, { name: 'style.width', title: '宽度', setter: 'NumberSetter', setValue: (target) => { const visible = target.parent.getPropValue('visible'); if (!visible) return; target.parent.setPropValue('visible', false); setTimeout(() => { target.parent.setPropValue('visible', true); }, 300); }, }, { name: 'label', title: { label: '内联文案', tip: 'label|输入框内置标签', }, setter: 'StringSetter', }, { name: 'placeholder', title: { label: '占位提示', tip: '属性: placeholder', }, defaultValue: '请选择', // 不生效 setter: 'StringSetter', }, { name: 'showSearch', title: { label: '可搜索', tip: '属性: showSearch', }, setter: 'BoolSetter', defaultValue: false, }, { name: 'treeCheckable', title: { label: '复选框', tip: '属性: treeCheckable', }, setter: 'BoolSetter', defaultValue: false, }, { name: 'plainData', display: 'block', title: '选项', tip: { title: '数据格式', url: '', }, setValue: (target, value) => { const list = parseData(value).filter(({ type }) => 'node' === type); const keys = { selected: [], expanded: [] }; const dataSource = createDataSource(list, keys); target.parent.setPropValue('dataSource', dataSource); target.parent.setPropValue('value', keys.selected); }, setter: { componentName: 'MagicEditorSetter', props: { toolbar: ['normal', 'active', 'disable'], }, }, }, ], supports: { style: true, events: [ { name: 'onChange', propType: 'func', description: '值发生变化', }, { name: 'onVisibleChange', propType: 'func', description: '弹层显示隐藏变化', }, { name: 'onRemove', propType: 'func', description: 'Tag 被删除', }, { name: 'onSearch', propType: 'func', description: '搜索', }, ], }, }, icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/tree-select/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'TreeSelect', title: '树型选择控件', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'TreeSelect', main: '', destructuring: true, subName: '', }, props: [ { name: 'className', propType: 'string', }, { name: 'dataSource', propType: { type: 'Json', }, description: '数据源', }, { name: 'size', title: '尺寸', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '选择框大小', defaultValue: 'medium', }, { name: 'placeholder', title: '占位提示', propType: 'string', description: '选择框占位符', }, { name: 'label', title: '内联文案', propType: { type: 'instanceOf', value: 'node', }, description: '自定义内联label', }, { name: 'notFoundContent', title: '空提示', propType: { type: 'instanceOf', value: 'node', }, description: '无数据时显示内容', defaultValue: 'Not Found', }, { name: 'disabled', propType: 'bool', description: '是否禁用', defaultValue: false, }, { name: 'hasArrow', title: '下拉箭头', propType: 'bool', description: '是否有下拉箭头', defaultValue: true, }, { name: 'hasBorder', title: '边框', propType: 'bool', description: '是否有边框', defaultValue: true, }, { name: 'hasClear', title: '清空按钮', propType: 'bool', description: '是否有清空按钮', defaultValue: false, }, { name: 'readOnly', propType: 'bool', description: '是否只读', }, { name: 'autoWidth', propType: 'bool', description: '下拉框是否与选择器对齐', defaultValue: true, }, { name: 'onChange', propType: 'func', description: '选中值改变时触发的回调函数\n@param {String|Array} value 选中的值,单选时返回单个值,多选时返回数组\n@param {Object|Array} data 选中的数据,包括 value, label, pos, key属性,单选时返回单个值,多选时返回数组,父子节点选中关联时,同时选中,只返回父节点', }, { name: 'showSearch', propType: 'bool', description: '搜索框', defaultValue: false, }, { name: 'onSearch', propType: 'func', description: '在搜索框中输入时触发的回调函数\n@param {String} keyword 输入的关键字', }, { name: 'onSearchClear', propType: 'func', }, { name: 'multiple', propType: 'bool', description: '支持多选', defaultValue: false, }, { name: 'treeCheckable', propType: 'bool', description: '下拉框中的树是否支持勾选节点的复选框', defaultValue: false, }, { name: 'treeCheckStrictly', propType: 'bool', description: '下拉框中的树勾选节点复选框是否完全受控(父子节点选中状态不再关联)', defaultValue: false, }, { name: 'treeCheckedStrategy', propType: { type: 'oneOf', value: ['all', 'parent', 'child'], }, description: '定义选中时回填的方式\n@enumdesc 返回所有选中的节点, 父子节点都选中时只返回父节点, 父子节点都选中时只返回子节点', defaultValue: 'parent', }, { name: 'treeDefaultExpandAll', propType: 'bool', description: '下拉框中的树是否默认展开所有节点', defaultValue: false, }, { name: 'treeLoadData', propType: 'func', description: '下拉框中的树异步加载数据的函数,使用请参考[Tree的异步加载数据Demo](https://fusion.design/component/tree)\n@param {ReactElement} node 被点击展开的节点', }, { name: 'treeProps', propType: { type: 'Json', }, description: '透传到 Tree 的属性对象', }, { name: 'defaultVisible', title: '初始显示', propType: 'bool', description: '初始下拉框是否显示', defaultValue: false, }, { name: 'visible', propType: 'bool', description: '当前下拉框是否显示', }, { name: 'onVisibleChange', propType: 'func', description: '下拉框显示或关闭时触发事件的回调函数\n@param {Boolean} visible 是否显示\n@param {String} type 触发显示关闭的操作类型', }, { name: 'popupStyle', propType: { type: 'object', }, description: '下拉框自定义样式对象', }, { name: 'popupClassName', propType: 'string', description: '下拉框样式自定义类名', }, { name: 'popupContainer', propType: 'any', description: '下拉框挂载的容器节点', }, { name: 'popupProps', propType: { type: 'object', }, description: '透传到 Popup 的属性对象', }, { name: 'followTrigger', propType: 'bool', description: '是否跟随滚动', }, { name: 'isPreview', propType: 'bool', description: '预览态', }, { name: 'renderPreview', propType: 'func', description: '预览态模式下渲染的内容\n@param {Array} value 选择值 { label: , value:}', }, { name: 'useVirtual', propType: 'bool', description: '是否开启虚拟滚动', }, { name: 'style', propType: 'object', }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', supportVariable: true, }, ], }, ], configure: { props: { isExtends: true, override: [ { name: 'visible', condition: () => false, }, { name: 'autoWidth', condition: () => false, }, { name: 'useVirtual', condition: () => false, }, { name: 'renderPreview', condition: () => false, }, { name: 'followTrigger', condition: () => false, }, { name: 'popupStyle', condition: () => false, }, { name: 'popupClassName', condition: () => false, }, { name: 'popupContainer', condition: () => false, }, { name: 'popupProps', condition: () => false, }, { name: 'treeCheckable', condition: () => false, }, { name: 'treeCheckStrictly', condition: () => false, }, { name: 'treeCheckedStrategy', condition: () => false, }, { name: 'treeDefaultExpandAll', condition: () => false, }, { name: 'treeLoadData', condition: () => false, }, { name: 'treeProps', condition: () => false, }, { name: 'label', title: '内联文案', setter: { componentName: 'StringSetter', }, }, { name: 'dataSource', title: { label: '节点数据', tip: '数据源', }, setter: 'JsonSetter', supportVariable: true, }, ], }, }, icon: '', category: '信息输入', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/tree-select/snippets.design.ts ================================================ import parseData from '../utils/parse-data'; import { createDataSource } from './adaptor'; const plainData = '*Trunk\n\t-Branch\n\t\t*Branch\n\t\t\tLeaf\n\t\tLeaf\n\t*Branch\n\t\tLeaf\n\t\tLeaf'; const list = parseData(plainData).filter(({ type }) => 'node' === type); const keys = { selected: [], expanded: [] }; const dataSource = createDataSource(list, keys); export default [ { title: '树型选择控件', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_select.png', schema: { componentName: 'TreeSelect', props: { mode: 'single', hasArrow: true, cacheValue: true, visible: true, plainData, dataSource, value: keys.selected, }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/tree-select/snippets.ts ================================================ module.exports = [ { title: '树型选择控件', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_tree-select.png', schema: { componentName: 'TreeSelect', props: { prefix: 'next-', size: 'medium', hasArrow: true, hasBorder: true, autoWidth: true, notFoundContent: 'Not Found', treeCheckedStrategy: 'parent', }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/typography/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Typography', title: 'Text', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Typography', main: '', destructuring: true, subName: '', }, props: [ { name: 'component', propType: { type: 'instanceOf', value: 'elementType', }, description: '设置标签类型', defaultValue: 'article', }, { name: 'style', propType: 'object', }, { name: 'children', title: '内容', propType: 'string', }, ], configure: { component: { isContainer: true, }, }, icon: '', category: '常用', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/typography-text/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Typography.Text', title: 'Text', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Typography', main: '', destructuring: true, subName: 'Text', }, props: [ { name: 'children', propType: 'string', }, { name: 'delete', propType: 'bool', description: '添加删除线样式', defaultValue: false, }, { name: 'mark', propType: 'bool', description: '添加标记样式', defaultValue: false, }, { name: 'underline', propType: 'bool', description: '添加下划线样式', defaultValue: false, }, { name: 'strong', propType: 'bool', description: '是否加粗', defaultValue: false, }, { name: 'code', propType: 'bool', description: '添加代码样式', defaultValue: false, }, { name: 'component', propType: { type: 'oneOf', value: ['span', 'h1', 'h2', 'h3', 'h4'], }, description: '设置标签类型', defaultValue: 'span', }, { name: 'onClick', propType: 'func', description: '鼠标点击', }, { name: 'style', propType: 'object', }, ], configure: { props: [ { name: 'children', setter: 'TextAreaSetter', supportVariable: true, }, ], advanced: { callbacks: { onHoverHook: () => false, onMouseDownHook: () => false, onClickHook: () => false, onMove: () => false, }, }, }, category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/upload/meta.design.ts ================================================ import snippets from './snippets'; export default { group: '原子组件', componentName: 'Upload', title: '上传', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Upload', main: '', destructuring: true, subName: '', }, props: [ { name: 'action', propType: 'string', description: '上传的地址', }, { name: 'value', propType: { type: 'Json', }, description: '文件列表', }, { name: 'defaultValue', propType: 'object', description: '默认文件列表', }, { name: 'shape', propType: { type: 'oneOf', value: ['card'], }, description: '上传按钮形状', }, { name: 'listType', propType: { type: 'oneOf', value: ['text', 'image', 'card'], }, description: '上传列表的样式', }, { name: 'name', propType: 'string', description: '文件名字段', }, { name: 'data', propType: { type: 'oneOfType', value: ['object', 'func'], }, description: '上传额外传参', }, { name: 'formatter', propType: 'func', title: { label: '数据格式化函数', tip: '数据格式化函数,配合自定义 action 使用,参数为服务器的响应数据,详见 [formatter](#formater)\n@param {Object} response 返回\n@param {File} file 文件对象', }, }, { name: 'limit', propType: 'number', description: '最大文件上传个数', defaultValue: null, }, { name: 'timeout', propType: 'number', description: '设置上传超时,单位ms', }, { name: 'dragable', propType: 'bool', description: '可选参数,是否支持拖拽上传,`ie10+` 支持。', }, { name: 'useDataURL', propType: 'bool', description: '可选参数,是否本地预览', }, { name: 'disabled', propType: 'bool', description: '可选参数,是否禁用上传功能', }, { name: 'onSelect', propType: 'func', description: '选择文件回调', }, { name: 'onProgress', propType: 'func', description: '上传中', }, { name: 'onChange', propType: 'func', description: '上传文件改变时的状态\n@param {Object} info 文件事件对象', }, { name: 'onSuccess', propType: 'func', description: '可选参数,上传成功回调函数,参数为请求下响应信息以及文件\n@param {Object} file 文件\n@param {Array} value 值', }, { name: 'afterSelect', propType: 'func', description: '可选参数, 用于校验文件,afterSelect仅在 autoUpload=false 的时候生效,autoUpload=true时,可以使用beforeUpload完全可以替代该功能.\n@param {Object} file\n@returns {Boolean} 返回false会阻止上传,其他则表示正常', }, { name: 'onRemove', propType: 'func', description: '移除文件回调函数\n@param {Object} file 文件\n@returns {Boolean|Promise} 返回 false、Promise.resolve(false)、 Promise.reject() 将阻止文件删除', }, { name: 'onError', propType: 'func', description: '可选参数,上传失败回调函数,参数为上传失败的信息、响应信息以及文件\n@param {Object} file 出错的文件\n@param {Array} value 当前值', }, { name: 'beforeUpload', propType: 'func', title: { label: '开始上传时回调', tip: '可选参数, 详见 [beforeUpload](#beforeUpload)\n@param {Object} file 所有文件\n@param {Object} options 参数\n@returns {Boolean|Object|Promise} 返回值作用见demo', }, }, { name: 'onDrop', propType: 'func', description: '放文件', }, { name: 'className', propType: 'string', description: '自定义class', }, { name: 'style', propType: 'object', description: '自定义内联样式', }, { name: 'autoUpload', propType: 'bool', description: '自动上传', defaultValue: true, }, { name: 'request', propType: 'func', description: '自定义上传方法\n@param {Object} option\n@return {Object} object with abort method', }, { name: 'progressProps', propType: 'object', description: '透传给Progress props', }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', }, { name: 'renderPreview', propType: 'func', description: '预览态模式下渲染的内容\n@param {number} value 评分值', }, ], configure: { props: [ { name: 'shape', title: '类型', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '默认', value: '', }, { title: '卡片', value: 'card', }, ], }, }, description: '上传按钮形状', }, { name: 'listType', title: '列表样式', setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '文本', value: 'text', }, { label: '图片', value: 'image', }, { label: '卡片', value: 'card', }, ], }, }, defaultValue: 'text', description: '上传列表的样式', }, { name: 'limit', title: '数量限制', setter: 'NumberSetter', }, { name: 'disabled', title: '是否禁用', setter: 'BoolSetter', }, ], }, icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/upload/meta.ts ================================================ import snippets from './snippets'; export default { group: '原子组件', componentName: 'Upload', title: '上传', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Upload', main: '', destructuring: true, subName: '', }, props: [ { name: 'action', propType: 'string', description: '上传的地址', }, { name: 'value', propType: { type: 'Json', }, description: '文件列表', }, { name: 'defaultValue', propType: 'object', description: '默认文件列表', }, { name: 'shape', propType: { type: 'oneOf', value: ['card'], }, description: '上传按钮形状', }, { name: 'listType', propType: { type: 'oneOf', value: ['text', 'image', 'card'], }, description: '上传列表的样式', }, { name: 'name', propType: 'string', description: '文件名字段', }, { name: 'data', propType: { type: 'oneOfType', value: ['object', 'func'], }, description: '上传额外传参', }, { name: 'formatter', propType: 'func', title: { label: '数据格式化函数', tip: '数据格式化函数,配合自定义 action 使用,参数为服务器的响应数据,详见 [formatter](#formater)\n@param {Object} response 返回\n@param {File} file 文件对象', }, }, { name: 'limit', propType: 'number', description: '最大文件上传个数', defaultValue: null, }, { name: 'timeout', propType: 'number', description: '设置上传超时,单位ms', }, { name: 'dragable', propType: 'bool', description: '可选参数,是否支持拖拽上传,`ie10+` 支持。', }, { name: 'useDataURL', propType: 'bool', description: '可选参数,是否本地预览', }, { name: 'disabled', propType: 'bool', description: '可选参数,是否禁用上传功能', }, { name: 'onSelect', propType: 'func', description: '选择文件回调', }, { name: 'onProgress', propType: 'func', description: '上传中', }, { name: 'onChange', propType: 'func', description: '上传文件改变时的状态\n@param {Object} info 文件事件对象', }, { name: 'onSuccess', propType: 'func', description: '可选参数,上传成功回调函数,参数为请求下响应信息以及文件\n@param {Object} file 文件\n@param {Array} value 值', }, { name: 'afterSelect', propType: 'func', description: '可选参数, 用于校验文件,afterSelect仅在 autoUpload=false 的时候生效,autoUpload=true时,可以使用beforeUpload完全可以替代该功能.\n@param {Object} file\n@returns {Boolean} 返回false会阻止上传,其他则表示正常', }, { name: 'onRemove', propType: 'func', description: '移除文件回调函数\n@param {Object} file 文件\n@returns {Boolean|Promise} 返回 false、Promise.resolve(false)、 Promise.reject() 将阻止文件删除', }, { name: 'onError', propType: 'func', description: '可选参数,上传失败回调函数,参数为上传失败的信息、响应信息以及文件\n@param {Object} file 出错的文件\n@param {Array} value 当前值', }, { name: 'beforeUpload', propType: 'func', title: { label: '开始上传时回调', tip: '可选参数, 详见 [beforeUpload](#beforeUpload)\n@param {Object} file 所有文件\n@param {Object} options 参数\n@returns {Boolean|Object|Promise} 返回值作用见demo', }, }, { name: 'onDrop', propType: 'func', description: '放文件', }, { name: 'className', propType: 'string', description: '自定义class', }, { name: 'style', propType: 'object', description: '自定义内联样式', }, { name: 'autoUpload', propType: 'bool', description: '自动上传', defaultValue: true, }, { name: 'request', propType: 'func', description: '自定义上传方法\n@param {Object} option\n@return {Object} object with abort method', }, { name: 'progressProps', propType: 'object', description: '透传给Progress props', }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', }, { name: 'renderPreview', propType: 'func', description: '预览态模式下渲染的内容\n@param {number} value 评分值', }, ], configure: { props: [ { name: 'title', title: '标题', setter: 'StringSetter', supportVariable: true, }, { name: 'title', title: '标题位置', setter: 'StringSetter', supportVariable: true, }, { name: 'defaultValue', title: '默认值', setter: { componentName: 'JsonSetter', }, }, { name: 'shape', title: '按钮形状', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '默认', value: '', }, { title: '卡片', value: 'card', }, ], }, }, description: '上传按钮形状', }, { name: 'listType', title: '列表样式', setter: { componentName: 'RadioGroupSetter', props: { options: ['text', 'image', 'card'], }, }, defaultValue: 'text', description: '上传列表的样式', }, { name: 'limit', title: '数量限制', setter: 'NumberSetter', supportVariable: true, }, { name: 'disabled', title: '是否禁用', setter: 'BoolSetter', supportVariable: true, }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', supportVariable: true, }, ], }, ], }, icon: '', category: '信息输入', snippets, }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/upload/snippets.ts ================================================ export default [ { title: '上传组件', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_upload.png', schema: { componentName: 'Upload', props: { prefix: 'next-', closable: true, autoUpload: true, shape: 'card', defaultValue: [], }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/upload-dragger/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Upload.Dragger', title: 'Upload.Dragger', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Upload', main: '', destructuring: true, subName: 'DragUpload', }, props: [ { name: 'prefix', propType: 'string', description: '样式前缀', defaultValue: 'next-', }, { name: 'locale', propType: 'object', }, { name: 'shape', propType: 'string', }, { name: 'onDragOver', propType: 'func', }, { name: 'onDragLeave', propType: 'func', }, { name: 'onDrop', propType: 'func', }, { name: 'limit', propType: 'number', }, { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, { name: 'defaultValue', propType: { type: 'instanceOf', value: 'array', }, }, { name: 'children', propType: { type: 'instanceOf', value: 'node', }, }, { name: 'listType', propType: 'string', }, { name: 'timeout', propType: 'number', }, ], category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/upload-list/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Upload.List', title: 'Upload.List', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Upload', main: '', destructuring: true, subName: 'List', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'locale', propType: 'object', description: '多语言', }, { name: 'listType', propType: { type: 'oneOf', value: ['text', 'image', 'card'], }, description: '文件列表,数据格式请参考 文件对象', defaultValue: 'text', }, { name: 'value', propType: { type: 'instanceOf', value: 'array', }, description: '文件列表', defaultValue: [], }, { name: 'closable', propType: 'bool', defaultValue: false, }, { name: 'onRemove', propType: 'func', description: '删除文件回调(支持Promise)', }, { name: 'onCancel', propType: 'func', description: '取消上传回调(支持Promise)', }, { name: 'onImageError', propType: 'func', description: '头像加载出错回调', }, { name: 'onPreview', propType: 'func', description: 'listType=card时点击图片回调', }, { name: 'extraRender', propType: 'func', description: '自定义额外渲染', }, { name: 'progressProps', propType: 'object', description: '透传给Progress props', }, { name: 'children', propType: 'node', }, { name: 'uploader', propType: 'any', }, { name: 'useDataURL', propType: 'bool', description: '可选参数,是否本地预览', }, { name: 'rtl', propType: 'bool', }, { name: 'isPreview', propType: 'bool', }, { name: 'style', propType: 'object', }, ], category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/upload-selecter/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Upload.Selecter', title: 'Upload.Selecter', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'Upload', main: '', destructuring: true, subName: 'Selecter', }, props: [ { name: 'id', propType: 'string', }, { name: 'style', propType: 'object', }, { name: 'className', propType: 'string', }, { name: 'disabled', propType: 'bool', description: '是否禁用上传功能', }, { name: 'multiple', propType: 'bool', description: '是否支持多选文件,`ie10+` 支持。开启后按住 ctrl 可选择多个文件', defaultValue: false, }, { name: 'dragable', propType: 'bool', description: '是否支持拖拽上传,`ie10+` 支持。', }, { name: 'accept', propType: 'string', description: '接受上传的文件类型 (image/png, image/jpg, .doc, .ppt) 详见 [input accept attribute](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/Input#attr-accept)', }, { name: 'onSelect', propType: 'func', description: '文件选择回调', }, { name: 'onDragOver', propType: 'func', description: '拖拽经过回调', }, { name: 'onDragLeave', propType: 'func', description: '拖拽离开回调', }, { name: 'onDrop', propType: 'func', description: '拖拽完成回调', }, { name: 'children', propType: { type: 'instanceOf', value: 'node', }, }, { name: 'name', propType: 'string', defaultValue: 'file', }, ], category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/utils/component-wrapper.ts ================================================ import * as React from 'react'; const { createElement } = React; export const ValueWrapper = (NextFormComponent: React.ElementType, displayName: string) => { const WrappedComponent = (props: any) => { const { __designMode, value, defaultValue, ...otherProps } = props; const finalValue = __designMode === 'design' ? defaultValue : value; if (typeof finalValue !== 'undefined') { otherProps.value = finalValue; } return createElement(NextFormComponent, { ...otherProps }); }; WrappedComponent.displayName = displayName; return WrappedComponent; }; export const DynamicPropWrapper = ( prop: string, NextFormComponent: React.ElementType, displayName: string, ) => { const WrappedComponent = (props: any) => { const dynamicProp = prop; const defaultDynamicProp = `default${prop.slice(0, 1).toUpperCase()}${prop.slice(1)}`; const { __designMode, ...otherProps } = props; const dynamicPropValueValue = props[dynamicProp]; const defaultDynamicPropValue = props[defaultDynamicProp]; const finalValue = __designMode === 'design' ? defaultDynamicPropValue : dynamicPropValueValue; if (typeof finalValue !== 'undefined') { otherProps[dynamicProp] = finalValue; } return createElement(NextFormComponent, { ...otherProps }); }; WrappedComponent.displayName = displayName; return WrappedComponent; }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/utils/icons.ts ================================================ export const Icons = { message: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_message.png', avatar: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_avatar.png', badge: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_badge.png', balloon: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_balloon.png', breadcrumb: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_breadcrumb.png', button: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_button.png', 'split-button': 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_split-button.png', card: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_card.png', 'cascader-select': 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_cascader-select.png', cascader: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_cascader.png', menu: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_menu.png', 'date-picker': 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_date-picker.png', dialog: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_dialog.png', divider: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_divider.png', input: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_input.png', loading: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_loading.png', table: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_table.png', 'number-picker': 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_number-picker.png', pagination: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_pagination.png', progress: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_progress.png', radio: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_radio.png', range: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_range.png', rating: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_rating.png', search: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_search.png', select: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_select.png', slider: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_slider.png', step: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_step.png', switch: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_switch.png', tag: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_tag.png', 'time-picker': 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_time-picker.png', timeline: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_timeline.png', transfer: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_transfer.png', tree: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_tree.png', 'tree-select': 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_tree-select.png', upload: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_upload.png', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/utils/index.ts ================================================ ================================================ FILE: packages/fusion-lowcode-materials/lowcode/utils/parse-data.ts ================================================ export const STATE_MARK: any = { '-': 'disabled', // tslint:disable-next-line:object-literal-sort-keys '*': 'active', '~': 'hover', '': 'normal', }; export enum NodeType { divider = 'divider', node = 'node', comment = 'comment', } export enum ContentType { text = 'text', icon = 'icon', } export interface IContent { type: ContentType; value: string; } export interface INode { type: NodeType; state: string; value: string | IContent[]; children: INode[]; } export interface IParseOption { parseContent: boolean; } const getChildren = (template: string = ''): IContent[] => { if (!template) { return []; } return template .replace(/(\[.*?\])/g, '\n$1\n') .split('\n') .filter((v) => !!v) .map((d) => { switch (true) { case /^\[(.*)\]$/.test(d): return { type: 'icon', value: RegExp.$1, } as IContent; default: return { type: 'text', value: d, } as IContent; } }); }; export const parseData = ( text: string, options: IParseOption = { parseContent: false }, ): INode[] => { if (!text) { return []; } const root: INode = { type: NodeType.node, state: 'normal', value: '', children: [], }; const stack: INode[] = [root]; text .split('\n') .filter((line) => line.trim()) .forEach((line) => { const re: any = /^(\t*)([#\-~*]?)(.*)$/.exec(line); const indent = (re[1] || '').length; const prefix = re[2] || ''; const item: INode = { type: NodeType.node, state: 'normal', value: re[3] || '', children: [], }; if (prefix === '-' && /^-{2,}$/.test(item.value as string)) { item.type = NodeType.divider; } else if (prefix === '#') { item.type = NodeType.comment; } else { item.state = STATE_MARK[prefix]; } if (item.type === 'node' && options.parseContent) { item.value = getChildren(item.value as string); } while (indent <= stack.length - 2) { stack.pop(); } stack[stack.length - 1].children.push(item); stack.push(item); }); return root.children; }; export default parseData; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/video/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'Video', title: '视频', npm: { package: '@alilc/lowcode-materials', version: 'latest', exportName: 'Video', main: '', destructuring: true, subName: '', }, props: [ { name: 'src', title: { label: { type: 'i18n', zh_CN: '视频链接', en_US: 'Video Address', }, tip: { type: 'i18n', zh_CN: '属性: src | 说明: 视频链接', en_US: 'prop: src | description: Video address', }, }, propType: 'string', defaultValue: 'https://fusion.alicdn.com/fusion-site-2.0/fusion.mp4', }, { name: 'autoPlay', title: { label: { type: 'i18n', zh_CN: '自动播放', en_US: 'autoPlay', }, }, propType: 'bool', setter: { componentName: 'BoolSetter', }, }, { name: 'loop', title: { label: { type: 'i18n', zh_CN: '循环播放', en_US: 'loop', }, }, propType: 'bool', }, { name: 'muted', title: { label: { type: 'i18n', zh_CN: '静音', en_US: 'muted', }, }, propType: 'bool', }, { name: 'controls', title: { label: { type: 'i18n', zh_CN: '控制条', en_US: 'controls', }, }, propType: 'bool', }, { name: 'poster', title: { label: { type: 'i18n', zh_CN: '默认图URL', en_US: 'poster', }, }, propType: 'string', }, { name: 'style', propType: 'object', }, ], configure: { props: { isExtends: true, override: [ { name: 'autoPlay', title: '自动播放', setter: { componentName: 'BoolSetter', }, extraProps: { setValue: (target, value) => { if (value) { target.node.setPropValue('muted', true); } }, }, }, { name: 'muted', title: '静音', setter: { componentName: 'BoolSetter', }, condition: (target) => { return !target.parent.getPropValue('autoPlay'); }, }, ], }, }, icon: 'https://img.alicdn.com/imgextra/i4/O1CN01Rc4H6E1KHhpdjKn0n_!!6000000001139-55-tps-56-56.svg', category: '信息展示', snippets: require('./snippets'), }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/video/snippets.ts ================================================ module.exports = [ { title: '视频', screenshot: 'https://img.alicdn.com/imgextra/i4/O1CN01Rc4H6E1KHhpdjKn0n_!!6000000001139-55-tps-56-56.svg', schema: { title: '视频', componentName: 'Video', props: { src: 'https://fusion.alicdn.com/images/page-1.mp4', controls: true, style: { width: '600px', }, }, }, }, ]; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/week-picker/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'WeekPicker', title: 'WeekPicker', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'DatePicker', main: '', destructuring: true, subName: 'WeekPicker', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'rtl', propType: 'bool', defaultValue: false, }, { name: 'label', propType: { type: 'instanceOf', value: 'node', }, description: '输入框内置标签', }, { name: 'state', propType: { type: 'oneOf', value: ['success', 'loading', 'error'], }, description: '输入框状态', }, { name: 'placeholder', propType: 'string', description: '输入提示', }, { name: 'defaultVisibleMonth', propType: 'func', description: '默认展现的月\n@return {MomentObject} 返回包含指定月份的 moment 对象实例', }, { name: 'onVisibleMonthChange', propType: 'func', }, { name: 'value', propType: { type: 'instanceOf', value: 'custom', }, description: '日期值(受控)moment 对象', }, { name: 'defaultValue', propType: { type: 'instanceOf', value: 'custom', }, description: '初始日期值,moment 对象', }, { name: 'format', propType: 'string', description: '日期值的格式(用于限定用户输入和展示)', defaultValue: 'YYYY-wo', }, { name: 'disabledDate', propType: 'func', description: '禁用日期函数\n@param {MomentObject} 日期值\n@param {String} view 当前视图类型,year: 年, month: 月, date: 日\n@return {Boolean} 是否禁用', }, { name: 'footerRender', propType: 'func', description: '自定义面板页脚\n@return {Node} 自定义的面板页脚组件', }, { name: 'onChange', propType: 'func', description: '日期值改变时的回调\n@param {MomentObject|String} value 日期值', }, { name: 'size', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '输入框尺寸', defaultValue: 'medium', }, { name: 'disabled', propType: 'bool', description: '是否禁用', }, { name: 'hasClear', propType: 'bool', description: '是否显示清空按钮', defaultValue: true, }, { name: 'visible', propType: 'bool', description: '弹层显示状态', }, { name: 'defaultVisible', propType: 'bool', description: '弹层默认是否显示', defaultValue: false, }, { name: 'onVisibleChange', propType: 'func', description: '弹层展示状态变化时的回调\n@param {Boolean} visible 弹层是否显示\n@param {String} type 触发弹层显示和隐藏的来源 calendarSelect 表示由日期表盘的选择触发; okBtnClick 表示由确认按钮触发; fromTrigger 表示由trigger的点击触发; docClick 表示由document的点击触发', }, { name: 'popupTriggerType', propType: { type: 'oneOf', value: ['click', 'hover'], }, description: '弹层触发方式', defaultValue: 'click', }, { name: 'popupAlign', propType: 'string', description: '弹层对齐方式,具体含义见 OverLay文档', defaultValue: 'tl tl', }, { name: 'popupContainer', propType: 'any', description: '弹层容器\n@param {Element} target 目标元素\n@return {Element} 弹层的容器元素', }, { name: 'popupStyle', propType: 'object', description: '弹层自定义样式', }, { name: 'popupClassName', propType: 'string', description: '弹层自定义样式类', }, { name: 'popupProps', propType: 'object', description: '弹层其他属性', }, { name: 'followTrigger', propType: 'bool', description: '是否跟随滚动', }, { name: 'inputProps', propType: 'object', description: '输入框其他属性', }, { name: 'dateCellRender', propType: 'func', description: '自定义日期渲染函数\n@param {Object} value 日期值(moment对象)\n@returns {ReactNode}', }, { name: 'monthCellRender', propType: 'func', description: '自定义月份渲染函数\n@param {Object} calendarDate 对应 Calendar 返回的自定义日期对象\n@returns {ReactNode}', }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', }, { name: 'renderPreview', propType: 'func', description: '预览态模式下渲染的内容\n@param {MomentObject} value 年份', }, { name: 'yearCellRender', propType: 'func', }, { name: 'locale', propType: 'object', }, { name: 'className', propType: 'string', }, { name: 'name', propType: 'string', }, { name: 'popupComponent', propType: { type: 'instanceOf', value: 'elementType', }, }, { name: 'popupContent', propType: { type: 'instanceOf', value: 'node', }, }, { name: 'style', propType: 'object', }, ], category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/lowcode/year-picker/meta.ts ================================================ module.exports = { group: '原子组件', componentName: 'YearPicker', title: 'YearPicker', docUrl: '', screenshot: '', npm: { package: '@alilc/lowcode-materials', version: '{{version}}', exportName: 'DatePicker', main: '', destructuring: true, subName: 'YearPicker', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'rtl', propType: 'bool', defaultValue: false, }, { name: 'label', propType: { type: 'instanceOf', value: 'node', }, description: '输入框内置标签', }, { name: 'state', propType: { type: 'oneOf', value: ['success', 'loading', 'error'], }, description: '输入框状态', }, { name: 'placeholder', propType: 'string', description: '输入提示', }, { name: 'value', propType: { type: 'instanceOf', value: 'custom', }, description: '日期值(受控)moment 对象', }, { name: 'defaultValue', propType: { type: 'instanceOf', value: 'custom', }, description: '初始日期值,moment 对象', }, { name: 'format', propType: 'string', description: '日期值的格式(用于限定用户输入和展示)', defaultValue: 'YYYY', }, { name: 'disabledDate', propType: 'func', description: '禁用日期函数\n@param {MomentObject} 日期值\n@param {String} view 当前视图类型,year: 年, month: 月, date: 日\n@return {Boolean} 是否禁用', }, { name: 'footerRender', propType: 'func', description: '自定义面板页脚\n@return {Node} 自定义的面板页脚组件', }, { name: 'onChange', propType: 'func', description: '日期值改变时的回调\n@param {MomentObject|String} value 日期值', }, { name: 'size', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '输入框尺寸', defaultValue: 'medium', }, { name: 'disabled', propType: 'bool', description: '是否禁用', }, { name: 'hasClear', propType: 'bool', description: '是否显示清空按钮', defaultValue: true, }, { name: 'visible', propType: 'bool', description: '弹层显示状态', }, { name: 'defaultVisible', propType: 'bool', description: '弹层默认是否显示', }, { name: 'onVisibleChange', propType: 'func', description: '弹层展示状态变化时的回调\n@param {Boolean} visible 弹层是否显示\n@param {String} reason 触发弹层显示和隐藏的来源 calendarSelect 表示由日期表盘的选择触发; fromTrigger 表示由trigger的点击触发; docClick 表示由document的点击触发', }, { name: 'popupTriggerType', propType: { type: 'oneOf', value: ['click', 'hover'], }, description: '弹层触发方式', defaultValue: 'click', }, { name: 'popupAlign', propType: 'string', description: '弹层对齐方式, 具体含义见 OverLay文档', defaultValue: 'tl tl', }, { name: 'popupContainer', propType: 'any', description: '弹层容器\n@param {Element} target 目标元素\n@return {Element} 弹层的容器元素', }, { name: 'popupStyle', propType: 'object', description: '弹层自定义样式', }, { name: 'popupClassName', propType: 'string', description: '弹层自定义样式类', }, { name: 'popupProps', propType: 'object', description: '弹层其他属性', }, { name: 'followTrigger', propType: 'bool', description: '是否跟随滚动', }, { name: 'inputProps', propType: 'object', description: '输入框其他属性', }, { name: 'yearCellRender', propType: 'func', }, { name: 'dateInputAriaLabel', propType: 'string', description: '日期输入框的 aria-label 属性', }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', }, { name: 'renderPreview', propType: 'func', description: '预览态模式下渲染的内容\n@param {MomentObject} value 年份', }, { name: 'locale', propType: 'object', }, { name: 'className', propType: 'string', }, { name: 'name', propType: 'string', }, { name: 'popupComponent', propType: { type: 'instanceOf', value: 'elementType', }, }, { name: 'popupContent', propType: { type: 'instanceOf', value: 'node', }, }, { name: 'style', propType: 'object', }, ], category: '基础', }; ================================================ FILE: packages/fusion-lowcode-materials/package.json ================================================ { "name": "@alilc/lowcode-materials", "version": "1.2.1", "description": "Fusion Next for LowCode", "main": "lib/index.js", "module": "es/index.js", "lowcodeEditMain": "build/lowcode/view.js", "stylePath": "style.js", "scripts": { "start": "build-scripts start", "build": "build-scripts build", "lowcode:dev": "build-scripts start --config ./build.lowcode.js", "lowcode:build": "build-scripts build --config ./build.lowcode.js", "prepublishOnly": "npm run build && npm run lowcode:build", "beta": "npm publish --tag beta", "pub": "npm publish" }, "files": [ "es/", "lib/", "dist/", "build/", "lowcode/", "lowcode_lib/", "lowcode_es/" ], "resolutions": { "webpack": "4.x" }, "dependencies": { "@alifd/next": "^1.24.14", "@types/react": "^16.14.0", "big.js": "^6.2.1", "lodash": "^4.17.21", "moment": "^2.29.4", "@babel/runtime": "^7.0.0" }, "devDependencies": { "@alib/build-scripts": "^0.1.23", "@alifd/build-plugin-lowcode": "^0.4.1", "@alifd/theme-2": "^0.4.4", "@types/big.js": "^6.1.6", "@types/lodash": "^4.14.191", "build-plugin-component": "^1.3.3", "build-plugin-fusion": "^0.1.3", "build-plugin-moment-locales": "^0.1.0", "moment": "^2.20.1", "react": "^16.14.0", "react-dom": "^16.14.0", "typescript": "^3.9.3" }, "authors": [ { "name": "金禅" }, { "name": "荣彬" }, { "name": "屹凡" }, { "name": "启剑" }, { "name": "春希" }, { "name": "度城" }, { "name": "梧忌" } ], "componentConfig": { "materialSchema": "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.2.1/build/lowcode/assets-prod.json" }, "license": "MIT", "homepage": "https://unpkg.com/@alilc/lowcode-materials@1.2.1/build/index.html", "exports": { ".": { "import": "./es/index.js", "require": "./lib/index.js" }, "./prototype": { "require": "./lowcode_lib/meta.js", "import": "./lowcode_es/meta.js" }, "./prototypeView": { "require": "./lowcode_lib/view.js", "import": "./lowcode_es/view.js" }, "./*": "./*" }, "lcMeta": { "type": "component" }, "repository": "https://github.com/alibaba/lowcode-materials.git" } ================================================ FILE: packages/fusion-lowcode-materials/plugins/compatible.build.js ================================================ const fs = require('fs'); const path = require('path'); module.exports = ({ onHook }) => { onHook('after.build.compile', (stats) => { fs.writeFileSync( path.resolve('dist/utils.js'), fs.readFileSync(path.resolve('scripts/utils.js')), ); fs.writeFileSync( path.resolve('dist/assets.json'), fs.readFileSync(path.resolve('build/lowcode/assets-prod.json')), ); }); }; ================================================ FILE: packages/fusion-lowcode-materials/scripts/utils.js ================================================ module.exports = { replacer(key, value) { if (typeof value === 'function') { return { type: 'JSFunction', value: String(value), }; } return value; }, isAsyncFunction: (fn) => { return fn[Symbol.toStringTag] === 'AsyncFunction'; }, reviewer(key, value) { if (!value) { return value; } if (key === 'icon') { if (typeof value === 'object') { return { type: 'smile', size: 'small', }; } } if (typeof value === 'object') { if (value.type === 'JSFunction') { let _value = value.value && value.value.trim(); let template = ` return function lowcode() { const self = this; try { return (${_value}).apply(self, arguments); } catch(e) { console.log('call function which parsed by lowcode for key ${key} failed: ', e); return e.message; } };`; try { return Function(template)(); } catch (e) { if (e && e.message.includes("Unexpected token '{'")) { console.log('method need add funtion prefix'); _value = 'function ' + _value; template = ` return function lowcode() { const self = this; try { return (${_value}).apply(self, arguments); } catch(e) { console.log('call function which parsed by lowcode for key ${key} failed: ', e); return e.message; } };`; return Function(template)(); } console.error('parse lowcode function error: ', e); console.error(value); return value; } } } return value; }, toJson(object, replacer) { return JSON.stringify(object, replacer || this.replacer, 2); }, parseJson(json) { const input = typeof json === 'string' ? json : JSON.stringify(json); return JSON.parse(input, this.reviewer); }, calculateDependencies(schema, componentsMap) { function findComps(schema, componentsMap, dependencies) { dependencies = dependencies || {}; if (dependencies[schema.componentName]) { dependencies[schema.componentName].count++; } else { dependencies[schema.componentName] = { count: 1, }; if (componentsMap && componentsMap[schema.componentName]) { dependencies[schema.componentName].npm = componentsMap[schema.componentName].package; dependencies[schema.componentName].version = componentsMap[schema.componentName].version; } } if (schema.children && Array.isArray(schema.children)) { schema.children.forEach((child) => { dependencies = Object.assign(dependencies, findComps(child, componentsMap, dependencies)); }); } return dependencies; } const comps = findComps(schema, componentsMap); const deps = {}; Object.keys(comps).forEach((key) => { const comp = comps[key]; if (!comp.npm) comp.npm = 'BuiltIn'; if (deps[`${comp.npm}${comp.version ? '@' + comp.version : ''}`]) { deps[`${comp.npm}${comp.version ? '@' + comp.version : ''}`][key] = comp.count; } else { deps[`${comp.npm}${comp.version ? '@' + comp.version : ''}`] = { [key]: comp.count, }; } }); return deps; }, }; ================================================ FILE: packages/fusion-lowcode-materials/src/components/balloon/index.tsx ================================================ import { Balloon } from '@alifd/next'; const { Tooltip } = Balloon; export default (props = {}) => { const { __designMode, defaultVisible, visible, mode, children, ...otherProps } = props || {}; console.log('props: ', props); const RealComponent = mode === 'Tooltip' ? Tooltip : Balloon; let finalValue = __designMode === 'design' ? defaultVisible : visible; const finalProps = { ...otherProps }; if (typeof finalValue !== 'undefined') { finalProps.visible = finalValue; } if (typeof defaultVisible !== 'undefined') { finalProps.defaultVisible = defaultVisible; } return {children}; }; ================================================ FILE: packages/fusion-lowcode-materials/src/components/calendar/index.tsx ================================================ import { Calendar } from '@alifd/next'; export default (props = {}) => { const { __designMode, defaultValue, value, ...otherProps } = props || {}; let finalValue = __designMode === 'design' ? defaultValue : value; const finalProps = { ...otherProps }; if (finalValue) { finalProps.value = typeof finalValue === 'string' ? moment(finalValue) : finalValue; } if (defaultValue) { finalProps.defaultValue = typeof defaultValue === 'string' ? moment(defaultValue) : defaultValue; } return ; }; ================================================ FILE: packages/fusion-lowcode-materials/src/components/div/index.tsx ================================================ import React, { CSSProperties, forwardRef } from 'react'; const Div = forwardRef((props, ref) => { return (
{props.children}
) }) Div.displayName = 'Div'; export default Div; ================================================ FILE: packages/fusion-lowcode-materials/src/components/image/index.tsx ================================================ import * as React from 'react'; interface ImageProps { alt?: string; title?: string; src?: string; style?: object; } /** * 文字 字体、大小、行高 * @param props */ const Image: React.ForwardRefRenderFunction = (props, ref) => { return ; }; const RefImage = React.forwardRef(Image); RefImage.defaultProps = { src: 'https://img.alicdn.com/tps/TB16TQvOXXXXXbiaFXXXXXXXXXX-120-120.svg', }; export default RefImage; ================================================ FILE: packages/fusion-lowcode-materials/src/components/link/index.tsx ================================================ import * as React from 'react'; interface LinkProps { target?: string; children?: string; href?: string; style?: object; __designMode?: string; } /** * 文字 字体、大小、行高 * @param props */ const Link: React.ForwardRefRenderFunction = (props, ref) => { const { children, __designMode, ...others } = props; const otherProps: any = {}; if (__designMode === 'design') { otherProps.onClick = (e: Event) => { e.preventDefault(); }; } return ( {children} ); }; const RefLink = React.forwardRef(Link); RefLink.defaultProps = { href: 'https://fusion.design', children: '这是一个超链接', target: '_blank', }; export default RefLink; ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/component/field/baseTableField.tsx ================================================ import React, { ReactNode } from "react"; import classnames from 'classnames'; import { Field } from "@alifd/next"; import { Rule } from "@alifd/next/types/field"; export interface IBaseTableFieldProps { name: string; value?: any; onChange: (value: any) => void; nextTablePrefix: string; rules?: Rule; } class BaseTableField

extends React.Component { field: Field; constructor(props: IBaseTableFieldProps & P) { super(props); this.field = new Field(this, { onChange: (name, value) => { this.dataChangeHandler(value); }, }); } componentWillMount() { const { name } = this.props; this.field.setValue(name, this.convertValueToSet(this.props.value)); } componentWillReceiveProps(nextProps: IBaseTableFieldProps) { const { name } = this.props; this.field.setValue(name, this.convertValueToSet(nextProps.value)); } validate() { return new Promise((resolve) => { const { name } = this.props; this.field.validate([name], (errors) => { resolve(errors); }); }); } convertValueToSet(value: any) { return value; } dataChangeHandler(value: any) { const { onChange } = this.props; onChange && onChange(value); } renderField(): ReactNode { return null; } render() { const { nextTablePrefix, name } = this.props; const field = this.field; const errMsg = field.getError(name); const fieldState = field.getState(name); return (

{this.renderField()}
{errMsg ?
{errMsg}
: null}
); } } export default BaseTableField; ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/component/field/customField.tsx ================================================ import { InitResult, Rule } from "@alifd/next/types/field"; import { ReactNode } from "react"; import BaseTableField from "./baseTableField"; export interface ICustomFieldProps { rowData: any; renderField: (props: InitResult, value: any, rowData: any) => ReactNode; } export default class CustomField extends BaseTableField { renderField() { const field = this.field; const { nextTablePrefix, value, onChange, rules, name, renderField, rowData, ...rest } = this.props; const props = field.init(name, { rules }, rest); delete props.value; // 外部默认为非受控模式 return renderField(props, value, rowData); } } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/component/field/dateField.tsx ================================================ import React from "react"; import Moment, { MomentInput } from "moment"; import { DatePicker } from "@alifd/next"; import BaseTableField from "./baseTableField"; export default class DateField extends BaseTableField { convertValueToSet(value: MomentInput) { return value ? Moment(value) : value; } dataChangeHandler(value: any) { const { onChange } = this.props; onChange && onChange(value ? value.toDate().getTime() : value); } renderField() { const field = this.field; const { nextTablePrefix, value, onChange, rules, name, ...rest } = this.props; return (); } } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/component/field/dateRangeField.tsx ================================================ import React from "react"; import Moment, { MomentInput } from "moment"; import { DatePicker } from "@alifd/next"; import BaseTableField from "./baseTableField"; const { RangePicker } = DatePicker; export default class DateRangeField extends BaseTableField { convertValueToSet(value: { start?: MomentInput; end?: MomentInput }) { const { start, end } = value; return [ start ? Moment(start) : null, end ? Moment(end) : null, ]; } dataChangeHandler(value: any) { const { onChange } = this.props; if (onChange) { const { 0: start, 1: end } = value; onChange && onChange({ start: start ? start.toDate().getTime() : undefined, end: end ? end.toDate().getTime() : undefined, }); } } renderField() { const field = this.field; const { nextTablePrefix, value, onChange, rules, name, ...rest } = this.props; return (); } } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/component/field/inputField.tsx ================================================ import React from "react"; import { Input } from "@alifd/next"; import BaseTableField from "./baseTableField"; export default class InputField extends BaseTableField { renderField() { const field = this.field; const { nextTablePrefix, value, onChange, rules, name, ...rest } = this.props; return ( ); } } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/component/field/radioField.tsx ================================================ import React, { ReactNode } from "react"; import { Radio } from "@alifd/next"; import BaseTableField from "./baseTableField"; import { GroupProps } from "@alifd/next/types/radio"; const RadioGroup = Radio.Group; interface IRadioFieldProps { renderChildren?(): GroupProps['children']; } export default class RadioField extends BaseTableField { renderField() { const field = this.field; const { nextTablePrefix, value, onChange, rules, name, renderChildren, ...rest } = this.props; if (renderChildren) { return ( {renderChildren()} ); } return null; } } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/component/field/selectField.tsx ================================================ import React from "react"; import { Select } from "@alifd/next"; import BaseTableField from "./baseTableField"; import { SelectProps } from "@alifd/next/types/select"; interface ISelectFieldProps { renderChildren?(): SelectProps['children']; } export default class SelectField extends BaseTableField { renderField() { const field = this.field; const { nextTablePrefix, value, onChange, rules, name, renderChildren, ...rest } = this.props; return (); } } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/component/webCustomColumnDrawer.tsx ================================================ import React from "react"; import { Drawer, Button, Icon, Message, Checkbox, Switch } from '@alifd/next'; import cloneDeep from 'lodash/cloneDeep'; import isEqual from 'lodash/isEqual'; import { Table } from '@alifd/next'; function getSelectedRowKeys(columns: IWebCustomColumnDrawerProps['columns'] = []) { const selectedRowKeys: string[] = []; columns && columns.forEach((item) => { const { hidden, dataKey } = item; if (!hidden && dataKey) { selectedRowKeys.push(dataKey); } }); return selectedRowKeys; } export interface IWebCustomColumnDrawerProps { columns?: any[]; onOk?: (columns: IWebCustomColumnDrawerProps['columns']) => void; onClose?: () => void; locale?: { [propKey: string]: string; } nextTablePrefix?: string; visible: boolean; } interface IWebCustomColumnDrawerState { defaultColumns: IWebCustomColumnDrawerProps['columns']; currentColumns: IWebCustomColumnDrawerProps['columns']; } export default class WebCustomColumnDrawer extends React.Component { static defaultProps = { columns: [], }; constructor(props: IWebCustomColumnDrawerProps) { super(props); const { columns } = this.props; this.state = { defaultColumns: cloneDeep(columns), currentColumns: cloneDeep(columns), }; } componentWillReceiveProps(nextProps: IWebCustomColumnDrawerProps) { const { defaultColumns } = this.state; const { columns: nextColumns } = nextProps; if (!isEqual(defaultColumns, nextColumns)) { this.setState({ defaultColumns: cloneDeep(nextColumns), currentColumns: cloneDeep(nextColumns), }); } } isHidden(dataKey: string) { const { currentColumns = [] } = this.state; const column = currentColumns.find((item) => { return item.dataKey === dataKey; }); return column ? (!!column.hidden) : false; } isLocked(dataKey: string) { const { currentColumns = [] } = this.state; const column = currentColumns.find((item) => { return item.dataKey === dataKey; }); let lock = column && column.lock; if (lock === "none") { lock = undefined; } return !!lock; } isAllColumnsShown() { const { currentColumns = [] } = this.state; return !currentColumns.some((item) => { return item.hidden; }); } handleCheck(checked: boolean, dataKey: string) { const { currentColumns = [] } = this.state; const column = currentColumns.find((item) => { return item.dataKey === dataKey; }); if (column) { column.hidden = !checked; column.lock = false; this.forceUpdate(); } } handleLock(checked: boolean, dataKey: string) { const { currentColumns = [] } = this.state; const column = currentColumns.find((item) => { return item.dataKey === dataKey; }); if (column) { column.lock = checked ? 'left' : undefined; this.forceUpdate(); } } restoreDefault() { const { defaultColumns } = this.state; this.setState({ currentColumns: cloneDeep(defaultColumns), }); } handleOk() { const { currentColumns = [] } = this.state; const { onOk, locale = {} } = this.props; let shownCount = 0; let fixedCount = 0; currentColumns.forEach((colums) => { const { lock, hidden } = colums; if (!hidden) { shownCount++; } if (lock && lock != "none") { fixedCount++; } }); if (currentColumns.length >= 2 && shownCount < 2) { Message.error(locale.tipLeastColumns); return; } onOk && onOk(currentColumns); } handleCheckAll(checked: boolean) { const { currentColumns = [] } = this.state; currentColumns.forEach((item) => { return item.hidden = !checked; }); this.forceUpdate(); } renderColumnShown(value: any, record: any, hasCheckbox: boolean) { const { nextTablePrefix } = this.props; const { dataKey } = record; return
{hasCheckbox ? { this.handleCheck(checked, dataKey); }} checked={!this.isHidden(dataKey)} /> : null} {value}
; } renderColumnFixed(value: any, rowIndex: string, record: any) { const { dataKey } = record; return this.isHidden(dataKey) ? null : { this.handleLock(checked, dataKey); }} />; } render() { const { nextTablePrefix, onClose, visible, locale = {} } = this.props; const { currentColumns = [] } = this.state; return (
{locale.customColumn}
{ return !item.isGroup })} hasBorder={false} primaryKey="dataKey" rowSelection={{ selectedRowKeys: getSelectedRowKeys(currentColumns), onSelectAll: (selected) => { this.handleCheckAll(selected); }, onSelect: (selected, records) => { const { dataKey } = records; this.handleCheck(selected, dataKey); }, }}> { return this.renderColumnShown(value, record, false); }} title={locale.showColumn} dataIndex="title" width="60%" />
); } } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/component/webLinkBar.tsx ================================================ import React from 'react'; import isFunction from "lodash/isFunction"; import type { IAction } from './webToolbar'; export interface IWebLinkBarProps { nextTablePrefix?: string; onActionClick?: (item: IAction, index: number) => void; linkBar?: IAction[]; } export default class WebLinkBar extends React.Component { renderActionButton(item: IAction, index: number) { const { nextTablePrefix, onActionClick } = this.props; let content; const itemProps = { onClick: () => { onActionClick && onActionClick(item, index); }, }; if (item.render && isFunction(item.render)) { content = (
{item.render(item.title)}
); } else { content = ( {item.title} ); } return (
{content} {index === 0 ? null :
}
); } render() { const { nextTablePrefix, linkBar = [] } = this.props; return (
{linkBar.slice(0).reverse().map((link, index) => { return link ? this.renderActionButton(link, index) : null; })}
); } } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/component/webNextTableActionCell.tsx ================================================ import React, { ReactNode } from "react"; import classnames from 'classnames'; import { Button, MenuButton } from '@alifd/next'; import actionTitleRender from "../utils/render/actionTitleRender"; import runColumnActionCallback from "../utils/runColumnActionCallback"; import filterActionColumn from "../utils/filterActionColumn"; import dispatchResizeEvent from "../utils/dispatchResizeEvent"; const { Item } = MenuButton; export interface IActionColumnItem { title: string; callback?: (rowData: any, action: IActionColumnItem, index?: number) => void; device?: string[]; mode?: string; render?: (title: IActionColumnItem['title'], rowData: any) => ReactNode; } export interface IWebNextTableActionCellProps { actionColumn?: IActionColumnItem[]; actionType?: string; maxWebShownActionCount?: number; nextTablePrefix?: string; rowData?: any; device?: string; index?: number; locale?: { [prop: string]: string; } } export default class WebNextTableActionCell extends React.Component { refreshCellUI() { this.forceUpdate(() => { dispatchResizeEvent(); }); } componentDidMount() { setTimeout(() => { dispatchResizeEvent() }, 400) } render() { const { actionColumn, actionType, maxWebShownActionCount = 3, nextTablePrefix, rowData, device, index, locale = {} } = this.props; const currentActionColumn = filterActionColumn(actionColumn, rowData, device); const showMoreAction = currentActionColumn.length > maxWebShownActionCount; const actionColumnToRender = currentActionColumn.slice(0, (showMoreAction ? maxWebShownActionCount - 1 : undefined)); const remainActions = currentActionColumn.slice(maxWebShownActionCount - 1); const isLink = actionType === 'link'; const menu = remainActions.map((action) => { const render = actionTitleRender(action, rowData) return render ? {render} : null; }).filter(i => i !== null); return (
{ actionColumnToRender.map((action) => { const render = actionTitleRender(action, rowData) return ( render ? : null ); }) } {showMoreAction && menu.length ? { const title = item.props.title; const action = remainActions.find((item) => { return item.title = title; }); runColumnActionCallback({ index, rowData, action: action!, }).finally(() => { this.refreshCellUI(); }); }} label={locale.more} >{menu} : null}
); } } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/component/webNextTableCell.tsx ================================================ import React from "react"; import isFunction from "lodash/isFunction"; import commonTableCellRender from "../utils/render/commonTableCellRender"; import { safeAccess, safeWrite } from "../utils/chainAccess"; import InputField from "./field/inputField"; import SelectField from "./field/selectField"; import RadioField from "./field/radioField"; import DateField from "./field/dateField"; import CustomField from "./field/customField"; import DateRangeField from "./field/dateRangeField"; import BaseTableField from "./field/baseTableField"; const fieldsMap = { select: SelectField, text: InputField, radio: RadioField, date: DateField, dateRange: DateRangeField, custom: CustomField, }; function canEditCell(canEdit: boolean, rowData: IWebNextTableCellProps['rowData']) { if (typeof canEdit === "undefined" || canEdit === null) { return true; } if (isFunction(canEdit)) { return canEdit(rowData); } return !!canEdit; } export interface IWebNextTableCellProps { rowData: any; column: { editType?: keyof typeof fieldsMap; dataKey: string; [prop: string]: any; }; isRenderEditMode?: boolean; rowIndex: number; nextTablePrefix?: string; onCellDataChange?(options: { dataKey: IWebNextTableCellProps['column']['dataKey']; value: any, rowData: IWebNextTableCellProps['rowData']; rowIndex: IWebNextTableCellProps['rowIndex']; }): void; } interface IWebNextTableCellState { editable: boolean; currentValue: any; } export default class WebNextTableCell extends React.Component { fieldComponentRef: React.RefObject; constructor(props: IWebNextTableCellProps) { super(props); this.state = { editable: false, currentValue: this.getRowValue(), }; this.fieldComponentRef = React.createRef(); } setEditable(v: boolean) { const { rowData } = this.props; rowData.__mode__ = v ? "EDIT" : "VIEW"; this.setState({ editable: !!v }); } getRowValue() { const { rowData, column } = this.props; const { dataKey } = column; return safeAccess(rowData, dataKey); } saveCell() { const { currentValue } = this.state; const { rowData, column } = this.props; const { dataKey } = column; safeWrite(rowData, dataKey, currentValue); this.setEditable(false); } resetCell() { this.setState({ currentValue: this.getRowValue(), }); this.setEditable(false); } validateCell() { const current = this.fieldComponentRef.current; const validate = current && current.validate; return validate && validate.call(current); } _fillFields(rowData: IWebNextTableCellProps['rowData'], dataKey: IWebNextTableCellProps['column']['dataKey']) { rowData.__fields__ = rowData.__fields__ || {}; rowData.__fields__[dataKey] = this; } renderCellEditInner() { const { currentValue } = this.state; const { nextTablePrefix, column, rowData, rowIndex, onCellDataChange } = this.props; const { editType, dataKey } = column; const FieldComponent = fieldsMap[editType!]; let { editProps } = column; if (isFunction(editProps)) { editProps = editProps(rowData); } return ( { // 兼容乐高 onChange 的返回格式 { value: value, ...rest } let realValue = value; if (value && (typeof value === 'object') && Object.hasOwnProperty.call(value, 'value')) { realValue = value.value; } this.setState({ currentValue: realValue }); onCellDataChange && onCellDataChange({ dataKey, value: realValue, rowData, rowIndex, }); }} rowData={rowData} {...editProps} />); } render() { const { editable } = this.state; const { column, rowData, isRenderEditMode, rowIndex } = this.props; const { editType, canEdit, dataKey } = column; this._fillFields(rowData, dataKey); if (isRenderEditMode && editable && editType && editType in fieldsMap && canEditCell(canEdit, rowData)) { return (
{ e.stopPropagation(); }}> {this.renderCellEditInner()}
); } return commonTableCellRender(safeAccess(rowData, dataKey), rowIndex, rowData, column); } } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/component/webPagination.tsx ================================================ import React from "react"; import classnames from 'classnames'; import isString from "lodash/isString"; import { Pagination } from '@alifd/next'; import { paginationProps, fetchKey } from "../utils/tableProps"; import { PaginationProps } from "@alifd/next/types/pagination"; export interface IWebPaginationProps extends Pick { nextTablePrefix?: string; currentPage?: PaginationProps['current']; totalCount?: PaginationProps['total']; locale?: { [prop: string]: string; } hideOnlyOnePage?: boolean; noPadding?: boolean; paginationPosition?: string; } export default class WebPagination extends React.Component { render() { const { nextTablePrefix, currentPage, pageSize, totalCount, locale, onChange, onPageSizeChange, hideOnlyOnePage, noPadding } = this.props; const myProps = fetchKey(this.props, paginationProps as Array); const { pageSizeList, paginationPosition = 'right', ...rest } = myProps; if (hideOnlyOnePage && pageSize !== undefined && totalCount !== undefined && pageSize > totalCount) { return null } return (
{ return ( {locale && locale.totalCount ? locale.totalCount : '总计'}:{' '}{total}{' '}); }} {... { ...rest, pageSizeList: (pageSizeList && isString(pageSizeList)) ? (() => { const pageSizeArray = pageSizeList.split(','); if (pageSizeArray.length > 1) { return pageSizeArray.map(i => parseInt(i, 10)); } })() : pageSizeList, current: currentPage, pageSize, total: totalCount, onChange, onPageSizeChange, } } />
); } } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/component/webRowOrder.tsx ================================================ import React, { ReactNode } from 'react'; import { Select, Icon } from '@alifd/next'; import { SelectProps } from '@alifd/next/types/select'; const Option = Select.Option; export interface IWebRowOrderProps { items: { value: string; text: ReactNode; }[]; nextTablePrefix: any; defaultValue: any; onChange: SelectProps['onChange']; } export default class WebRowOrder extends React.Component { render() { const { items, nextTablePrefix, defaultValue, onChange } = this.props; return (
); } } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/component/webToolbar.tsx ================================================ import React, { MouseEventHandler, ReactNode } from "react"; import classnames from "classnames"; import { Button, Search, Pagination, Icon } from '@alifd/next'; import WebRowOrder, { IWebRowOrderProps } from "./webRowOrder"; import WebLinkBar from "./webLinkBar"; import { SearchProps } from "@alifd/next/types/search"; import { PaginationProps } from "@alifd/next/types/pagination"; import { ButtonProps } from "@alifd/next/types/button"; export interface IAction { render?: (title: IAction['title']) => ReactNode; isDisabled?: () => boolean; title?: ReactNode; type: ButtonProps['type']; disabled: boolean; callback?: (action: IAction) => void; } export interface IWebToolbarProps { nextTablePrefix?: string; onSearch?: SearchProps['onSearch']; onActionClick?: (action: IAction, index: number) => void; locale?: { [prop: string]: string }; showActionBar?: boolean; actionBar?: IAction[]; showLinkBar?: boolean; linkBar?: any; showSearch?: boolean; searchBarPlaceholder?: string; showCustomColumn?: boolean; onClickCustomColumn?: MouseEventHandler; rowOrder?: IWebRowOrderProps; customBarItem?: { render?: () => ReactNode; rightRender?: () => ReactNode; bottomRender?: () => ReactNode; } showMiniPager?: boolean; paginationProps?: Pick & { currentPage?: PaginationProps['current']; totalCount?: PaginationProps['total']; }; noPadding?: boolean; } export default class WebToolbar extends React.Component { render() { const { nextTablePrefix, onSearch, onActionClick, locale = {}, showActionBar, actionBar, showLinkBar, linkBar, showSearch, searchBarPlaceholder, showCustomColumn, onClickCustomColumn, rowOrder, customBarItem, showMiniPager, paginationProps, noPadding } = this.props; const { currentPage, pageSize, totalCount, onChange, onPageSizeChange } = paginationProps || {}; const renderCustomBarItem = !!(customBarItem && customBarItem.render); const renderCustomBarItemRight = !!(customBarItem && customBarItem.rightRender); const renderCustomBarItemBottom = !!(customBarItem && customBarItem.bottomRender); const renderActionBar = !!(showActionBar && actionBar && actionBar.length); const renderLeft = renderActionBar || renderCustomBarItem; const renderLinkBar = !!(showLinkBar && linkBar && linkBar.length); const renderRight = renderLinkBar || rowOrder || showCustomColumn || showMiniPager || showSearch || renderCustomBarItemRight; const renderToolbar = renderLeft || renderRight; if (!renderToolbar) { return null; } return (
{renderLeft ?
{renderActionBar ? actionBar.map((action, index) => { const { isDisabled, title, type, disabled, callback, ...rest } = action const buttonType = type ? type : index === 0 ? 'secondary' : 'normal'; const disable = disabled !== undefined ? disabled : isDisabled ? !!(isDisabled()) : false; return ( ); }) : null} {renderCustomBarItem ?
{customBarItem.render!()}
: null}
: null} {renderRight ?
{renderLinkBar ? : null} {rowOrder ? : null} {showCustomColumn ?
{locale.customColumn}
: null} {showMiniPager ?
: null} { showSearch ? : null } { renderCustomBarItemRight ?
{customBarItem.rightRender!()}
: null }
: null }
{renderCustomBarItemBottom ?
{customBarItem.bottomRender!()}
: null}
); } } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/index.scss ================================================ /* write style here */ @import "scss/variables"; $table-css-prefix: '#{$deep-css-prefix}table-' !default; $red: #fb575f; $blue: #33a4ff; $orange: #ff8c33; $green: #82cb78; $grey: #c2c2c2; $black: #2c2f33; $yellow: #F9BD0F; .#{$table-css-prefix}full-wrap, .#{$table-css-prefix}detail-view-drawer { .#{$table-css-prefix}detail-list { background-color: #ffffff; width: calc(100% - 18px); .#{$table-css-prefix}detail-field-wrap { line-height: 24px; font-size: 14px; display: flex; .#{$table-css-prefix}detail-label { color: $color-text1-3; white-space: nowrap; } .#{$table-css-prefix}detail-value { color: $color-text1-4; .#{$css-prefix}btn { font-size: 14px; } > span { word-break: break-word; font-size: 14px; } } } .#{$table-css-prefix}detail-field-highlight { font-size: 16px; padding-left: 0; font-weight: bold; padding-bottom: 8px; } } .#{$css-prefix}table-sort { outline: none; line-height: 16px; .#{$css-prefix}icon { &.#{$css-prefix}icon-ascending, &.#{$css-prefix}icon-descending { left: 0; } } } .#{$css-prefix}table-filter { width: 16px; } .#{$css-prefix}table th { background-color: $color-fill1-1; .#{$css-prefix}table-cell-wrapper { ul.#{$css-prefix}menu { text-align: left; } } } .#{$css-prefix}table-cell{ .#{$css-prefix}btn-text.deep-table-link-button { color:$color-link-2 } .deep-table-badge { display: inline-block; padding: 2px 5px; border-radius: 2px; &.deep-table-badge-background-red { color: white; background-color: $red; } &.deep-table-badge-color-red { color: $red } &.deep-table-badge-background-yellow { color: white; background-color: $yellow; } &.deep-table-badge-color-yellow { color: $yellow } &.deep-table-badge-background-black { color: white; background-color: $black; } &.deep-table-badge-color-black { color: $black } &.deep-table-badge-background-grey { color: white; background-color: $grey; } &.deep-table-badge-color-grey { color: $grey } &.deep-table-badge-background-green { color: white; background-color: $green; } &.deep-table-badge-color-green { color: $green } &.deep-table-badge-background-blue { color: white; background-color: $blue; } &.deep-table-badge-color-blue { color: $blue } &.deep-table-badge-background-orange { color: white; background-color: $orange; } &.deep-table-badge-color-orange { color: $orange } } } .#{$css-prefix}table-cell.#{$css-prefix}table-expanded { .#{$css-prefix}icon-add:before, .#{$css-prefix}icon-minus:before { color: $color-fill1-6; font-size: 16px; width: 16px; } .#{$css-prefix}icon-add:before { content: "\e724"; } .#{$css-prefix}icon-minus:before { content: "\e725"; } } .#{$table-css-prefix}input { width: 100%; } .#{$table-css-prefix}field-msg { line-height: 24px; text-align: left; color: $color-error-3; } .#{$table-css-prefix}employee { width: 100%; .#{$css-prefix}select-trigger, .#{$css-prefix}select .#{$css-prefix}select-inner { min-width: 50px; } } } .#{$table-css-prefix}full-wrap { .#{$table-css-prefix}web-toolbar { overflow: hidden; padding: 16px 0; &.#{$table-css-prefix}no-padding { padding-top: 0; } .#{$table-css-prefix}left-wrap { float: left; } .#{$table-css-prefix}right-wrap { float: right; } .#{$table-css-prefix}button { margin-right: 8px; } .#{$table-css-prefix}search { width: 280px; margin-left: 20px; vertical-align: top; .#{$css-prefix}search-icon { outline: none; } } .#{$table-css-prefix}custom-column, .#{$table-css-prefix}link-a, .#{$table-css-prefix}link-div { color: $color-link-1; font-size: 12px; cursor: pointer; i { color: $color-text1-2; margin-right: 3px; } .#{$table-css-prefix}text { padding-left: 3px; } } .#{$table-css-prefix}link-a { text-decoration: none; } .#{$table-css-prefix}custom-column { margin-left: 24px; line-height: 32px; display: inline-block; vertical-align: top; } .#{$table-css-prefix}link-wrap { margin-left: 24px; display: inline-block; white-space: nowrap; line-height: 32px; vertical-align: top; .#{$table-css-prefix}link-item { float: right; } .#{$table-css-prefix}link-sp { width: 1px; height: 12px; margin: 10px 12px; display: inline-block; vertical-align: top; background-color: $color-line1-2; } } .#{$table-css-prefix}row-order { display: inline-block; vertical-align: top; margin-left: 24px; .#{$table-css-prefix}row-order-v { color: $color-link-1; i { color: $color-text1-2; margin-right: 3px; } } .#{$css-prefix}input-control { display: none; } .#{$css-prefix}input.#{$css-prefix}medium .#{$css-prefix}input-text-field { padding-left: 3px; padding-right: 0; color: $color-link-1; } .#{$css-prefix}select-inner { min-width: 50px; } .#{$css-prefix}select-trigger { min-width: 50px; } .#{$css-prefix}input.#{$css-prefix}medium .#{$css-prefix}icon:before { width: 16px; font-size: 16px; } } .#{$table-css-prefix}custom { display: inline-block; height: 32px; line-height: 32px; vertical-align: top; margin: 0 5px; } .#{$table-css-prefix}custom-right { display: inline-block; height: 32px; line-height: 32px; vertical-align: top; margin: 0 5px 0 10px; } .#{$table-css-prefix}pagination { display: inline-block; vertical-align: top; margin: 2px 0 0 20px; } } .#{$table-css-prefix}mobile-body { .#{$css-prefix}radio-group { width: 100%; } } .#{$table-css-prefix}mobile-toolbar { overflow: hidden; border-bottom: 1px solid $color-line1-2; .#{$table-css-prefix}right-wrap { line-height: 44px; display: flex; &-selector { width: 54px; text-align: center; } &-content { width: 100%; text-align: right; } } .#{$table-css-prefix}search-wrap { padding: 8px 0; .#{$table-css-prefix}search-inner { overflow: hidden; padding-left: 16px; } .#{$table-css-prefix}search-cancel-wrap { float: right; line-height: 28px; padding: 0 16px; } } .#{$table-css-prefix}search-cancel { font-size: 14px; color: $color-fill1-7; } .#{$table-css-prefix}i-wrap, .#{$table-css-prefix}row-order { margin-right: 16px; display: inline-block; vertical-align: top; color: $color-link-1; font-size: 0; position: relative; &:active { &:after { position: absolute; top: 6px; left: -6px; display: inline-block; content: ''; width: 32px; height: 32px; background: $color-fill1-1; z-index: -1; border-radius: 16px; } } } .#{$table-css-prefix}search { position: relative; overflow: hidden; .#{$css-prefix}icon-search { vertical-align: top; } .input { line-height: 28px; width: 100%; padding: 0; border: none; font-size: 12px; outline: none; background-color: transparent; } .i-wrap { position: absolute; right: 5px; top: 4px; padding: 0 10px; color: $color-fill1-6; } .input-wrap { border-radius: 20px; padding: 0 0 0 18px; background: #F1F3F5; } } } .#{$table-css-prefix}mobile-table { .#{$css-prefix}table.#{$css-prefix}table-small td .#{$css-prefix}table-cell-wrapper { padding: 8px; } .#{$css-prefix}table.#{$css-prefix}table-small .#{$css-prefix}table-prerow .#{$css-prefix}table-cell-wrapper { padding-right: 8px; } .#{$css-prefix}table.#{$css-prefix}table-small { td.first, th.#{$css-prefix}table-selection { .#{$css-prefix}table-cell-wrapper { padding-left: 16px; } } } .#{$css-prefix}table.#{$css-prefix}table-small th.#{$css-prefix}table-selection .#{$css-prefix}table-cell-wrapper { padding-left: 16px; } .#{$css-prefix}table-expanded-row { background-color: $color-fill1-1; } .#{$css-prefix}table.#{$css-prefix}table-small td.#{$table-css-prefix}column-action .#{$css-prefix}table-cell-wrapper { padding: 0; } .#{$table-css-prefix}column-action-i { padding: 8px; color: $color-fill1-6; } .#{$css-prefix}btn, .#{$css-prefix}table-expanded-ctrl { cursor: default; } .#{$css-prefix}table-row.hovered { background-color: #ffffff; } .#{$table-css-prefix}expand-wrap { padding-left: 8px; } } .#{$table-css-prefix}card-table { .#{$table-css-prefix}item-wrap { width: 100%; padding: 16px; border-bottom: 1px solid $color-line1-2; position: relative; font-size: 14px; display: flex; align-items: center; justify-items: center; .#{$table-css-prefix}item-wrap-selector { margin-right: 12px; } .#{$table-css-prefix}item-wrap-content { width: 100%; display: flex; justify-items: center; align-items: center; &.is-right { flex-direction: row-reverse; } .#{$table-css-prefix}item-wrap-content-column { width: 100%; } .#{$table-css-prefix}row-operate { position: absolute; right: 16px; top: 10px; line-height: 30px; color: $color-fill1-6; } .#{$table-css-prefix}row-button-wrap { margin-top: 16px; text-align: right; } } } .#{$table-css-prefix}expand-wrap { text-align: center; margin-top: 16px; } .#{$table-css-prefix}more-wrap { text-align: left; } .#{$table-css-prefix}expand-wrap, .#{$table-css-prefix}more-wrap { line-height: 22px; color: $color-fill1-6; font-size: 14px; .#{$table-css-prefix}text { padding-right: 4px; } .#{$css-prefix}icon { line-height: 20px; } } .#{$table-css-prefix}expand-content-wrap { background-color: $color-fill1-1; border-radius: 4px; margin-top: 16px; } .#{$css-prefix}btn { cursor: default; } } .#{$table-css-prefix}date-picker { &.#{$css-prefix}date-picker, .#{$css-prefix}month-picker, .#{$css-prefix}year-picker { width: 100%; } } .#{$table-css-prefix}web-pagination-wrap { .#{$table-css-prefix}web-pagination-left { float: left; } .#{$table-css-prefix}web-pagination-right { float: right; .#{$css-prefix}select { width: unset !important; } } } .#{$table-css-prefix}web-table { .#{$css-prefix}table-expanded-row { background-color: $color-fill1-1; } .#{$table-css-prefix}action-cell { .#{$table-css-prefix}action-link { &.#{$css-prefix}btn-text, &.#{$css-prefix}menu-btn.#{$css-prefix}btn-text.#{$css-prefix}btn-primary .#{$css-prefix}menu-btn-arrow { color: $color-link-1; } } .#{$table-css-prefix}action-button { margin-right: 8px; &:last-child { margin-right: 0; } &.#{$table-css-prefix}action-more { .#{$css-prefix}menu-btn-arrow { vertical-align: middle; } } } .#{$table-css-prefix}action-link { padding: 0 12px; position: relative; vertical-align: baseline; &:first-child { padding-left: 0; &:before { width: 0; } } &:last-child { padding-right: 0; } &.#{$table-css-prefix}action-more{ &:before { top: 4px } } &:before { position: absolute; content: ''; width: 1px; height: 10px; background: $color-line1-4; vertical-align: middle; top: 5px; left: 1px; } } .#{$table-css-prefix}action-more { .#{$css-prefix}menu-btn-arrow { vertical-align: top; } } } .#{$css-prefix}table-sort { cursor: pointer; } } .#{$table-css-prefix}web-pagination-wrap { padding: 16px 10px; &.#{$table-css-prefix}no-padding { padding-bottom: 0; } } } .#{$table-css-prefix}mobile-drawer { .#{$css-prefix}drawer-body { padding: 0; } &.#{$css-prefix}drawer { background-color: $color-fill1-2; } &.#{$css-prefix}drawer-right { max-width: none; width: 100%; height: 100%; } .#{$css-prefix}switch, .#{$css-prefix}checkbox-wrapper input[type="checkbox"] { cursor: default; } } .#{$table-css-prefix}detail-view-drawer { .#{$css-prefix}drawer-body { position: absolute; left: 0; width: 100%; top: 0; height: 100%; } .#{$table-css-prefix}title { line-height: 48px; text-align: center; background: #fff; font-size: 16px; position: absolute; left: 0; width: 100%; top: 0; border-bottom: 1px solid $color-line1-2; color: $color-text1-4; .#{$table-css-prefix}close { position: absolute; right: 16px; top: 12px; line-height: 20px; } } .#{$table-css-prefix}detail-list-wrap { background-color: #ffffff; padding: 16px; } .#{$table-css-prefix}expand-content-wrap { margin-top: 16px; background-color: #ffffff; } .#{$table-css-prefix}center { position: absolute; left: 0; width: 100%; top: 49px; bottom: 0; overflow: auto; } .#{$table-css-prefix}center-action { bottom: 51px; } .#{$table-css-prefix}bottom { position: absolute; bottom: 0; left: 0; width: 100%; z-index: 1002; background-color: #ffffff; .#{$table-css-prefix}action-wrap { display: flex; flex-direction: row; border-top: 1px solid $color-fill1-2; } .#{$table-css-prefix}action-item { flex: 1; padding: 12px 0; } .#{$table-css-prefix}action-inner { line-height: 24px; color: $color-fill1-7; border-left: 1px solid $color-line1-2; text-align: center; padding: 0 5px; font-size: 16px; } .#{$table-css-prefix}action-disable { color: $color-fill1-5; } .#{$table-css-prefix}action-item.first .#{$table-css-prefix}action-inner { border-left: none; } } } .#{$table-css-prefix}operation-drawer { .#{$table-css-prefix}item { line-height: 47px; font-size: 17px; text-align: center; background-color: #fff; border-bottom: 1px solid $color-line1-2; } .#{$table-css-prefix}item-disable { color: $color-fill1-5; } .#{$table-css-prefix}close { line-height: 47px; font-size: 17px; text-align: center; background-color: #fff; margin-top: 10px; } .#{$table-css-prefix}action-list { max-height: 384px; overflow-x: hidden; overflow-y: auto; } } .#{$table-css-prefix}web-custom-column-drawer { .#{$css-prefix}drawer-body { position: absolute; left: 0; width: 100%; top: 0; height: 100%; padding: 0; } .#{$table-css-prefix}title { line-height: 48px; text-align: left; background: #fff; font-size: 16px; position: absolute; left: 0; width: 100%; top: 0; color: $color-text1-4; border-bottom: 1px solid $color-line1-2; .#{$table-css-prefix}title-txt { padding: 0 16px; font-weight: bold; } .#{$table-css-prefix}close { line-height: 20px; position: absolute; right: 16px; top: 12px; cursor: pointer; } } .#{$table-css-prefix}center { position: absolute; left: 0; width: 100%; top: 49px; bottom: 53px; overflow: auto; } .#{$table-css-prefix}cell-wrap { line-height: 32px; } .#{$table-css-prefix}cell, .#{$table-css-prefix}select-all-content { font-size: 12px; color: $color-text1-4; vertical-align: top; } .#{$css-prefix}table { td, th { .#{$css-prefix}table-cell-wrapper { padding-left: 0; padding-right: 0; } &.#{$css-prefix}table-selection { .#{$css-prefix}table-cell-wrapper { padding: 12px 16px; } } } } .#{$table-css-prefix}cell-checkbox, .#{$table-css-prefix}select-all-checkbox { vertical-align: top; position: relative; top: -2px; } .#{$table-css-prefix}bottom { position: absolute; bottom: 0; width: 100%; border-top: 1px solid $color-line1-2; padding: 10px 16px; text-align: right; left: 0; background: #fff; border-radius: 0 0 4px 4px; } .#{$table-css-prefix}select-all { float: left; margin-left: 20px; } .#{$table-css-prefix}button { margin-right: 6px; } } .#{$table-css-prefix}mobile-custom-column-drawer { .#{$css-prefix}drawer-body { position: absolute; left: 0; width: 100%; top: 0; height: 100%; } .#{$table-css-prefix}title { line-height: 48px; text-align: center; background: #fff; font-size: 16px; position: absolute; left: 0; width: 100%; top: 0; color: $color-text1-4; .#{$table-css-prefix}close { line-height: 20px; position: absolute; right: 16px; top: 12px; } } .#{$table-css-prefix}cell-wrap { line-height: 32px; } .#{$table-css-prefix}cell, .#{$table-css-prefix}select-all-content { margin-left: 12px; font-size: 16px; color: $color-text1-4; vertical-align: top; } .#{$table-css-prefix}cell-checkbox, .#{$table-css-prefix}select-all-checkbox { vertical-align: top; position: relative; top: -2px; } .#{$table-css-prefix}messge { line-height: 30px; } .#{$table-css-prefix}center { position: absolute; left: 0; width: 100%; top: 49px; bottom: 48px; overflow: auto; } .#{$table-css-prefix}bottom { position: absolute; bottom: 0; line-height: 48px; background: #ffffff; left: 0; width: 100%; } .#{$table-css-prefix}select-all { float: left; margin-left: 20px; } .#{$table-css-prefix}button { float: right; margin-right: 16px; } .#{$css-prefix}checkbox-wrapper .#{$css-prefix}checkbox-inner { border-radius: 50%; } } .#{$table-css-prefix}full-wrap { .#{$css-prefix}table-header { overflow: hidden; &::-webkit-scrollbar { display: none; } } } .#{$table-css-prefix}column-title { .#{$table-css-prefix}column-tooltip { color: $color-notice-3; line-height: 14px; margin-left: 4px; } } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/index.tsx ================================================ import classnames from 'classnames'; import React from 'react'; import { Table, Loading, ConfigProvider } from '@alifd/next' import WebTable, { IWebTableProps } from './table/webTable'; import { fetchKey, tableProps } from "./utils/tableProps"; import buildNextTableMethod from "./utils/buildNextTableMethod"; import delegateFunctions from "./utils/delegateFunctions"; import getColumnsFromChildren from './utils/getColumnsFromChildern' import zhCN from './locale/zh-cn' import { LoadingProps } from '@alifd/next/types/loading'; import { IEditableMethods } from './mixin/editableMethods'; import { ICommonMethods } from './mixin/commonMethods'; import './index.scss'; const { GroupHeader, GroupFooter, Column, ColumnGroup } = Table export interface ITableProps extends IWebTableProps {} interface NextTable extends React.Component, Omit, Pick {} class NextTable extends React.Component { static Column = Column static ColumnGroup = ColumnGroup static GroupHeader = GroupHeader static GroupFooter = GroupFooter static defaultProps = { columns: [], clsPrefix: 'deep-', locale: zhCN, tablePrefix: 'table-', primaryKey: 'id', maxWebShownActionCount: 3, expandedIndexSimulate: false, loadingComponent: (props: LoadingProps) => { return } {...props} />; }, }; tableRef: React.RefObject; constructor(props: ITableProps) { super(props); this.tableRef = React.createRef(); buildNextTableMethod(this); } renderTable() { const { clsPrefix, tablePrefix } = this.props; const myProps = fetchKey(this.props, tableProps); const { children } = myProps; if (children) { myProps.columns = getColumnsFromChildren(children) } myProps.nextTablePrefix = `${clsPrefix}${tablePrefix}`; myProps.actionColumn = delegateFunctions(myProps.actionColumn, 'callback', this, 2); myProps.actionBar = delegateFunctions(myProps.actionBar, 'callback', this); myProps.linkBar = delegateFunctions(myProps.linkBar, 'callback', this); return ; } render() { const { clsPrefix, tablePrefix, className } = this.props; const nextTablePrefix = `${clsPrefix}${tablePrefix}`; return (
{this.renderTable()}
); } } export { NextTable, }; export default ConfigProvider.config(NextTable); ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/interface/index.ts ================================================ ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/locale/en-us.ts ================================================ export default { tipLeastNeededColumns: '2 shown columns is needed at least', tipLeastColumns: '2 shown columns at least', customColumn: 'Custom Columns', showColumn: 'Show Column', stickColumn: 'Stick Column', showAll: 'Show All', noData: 'No data', restoreDefault: 'Reset', notice: 'Notice', ok: 'OK', detail: 'Detail', cancel: 'Cancel', submit: 'Submit', totalCount: 'Total', collapse: 'Collapse', expand: 'Expand', more: 'More', } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/locale/zh-cn.ts ================================================ export default { tipLeastNeededColumns: '最少需要展示2列', tipLeastColumns: '最少展示2列', customColumn: '自定义列', showColumn: '展示此列', stickColumn: '固定此列', showAll: '全部展示', noData: '没有数据', restoreDefault: '恢复默认', notice: '提示', ok: '确定', detail: '详情', cancel: '取消', submit: '提交', totalCount: '总计', collapse: '收起', expand: '展开', more: '更多', } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/mixin/columnMethods.tsx ================================================ import React, { ReactNode } from "react"; import assign from "lodash/assign"; import deepcopy from 'lodash/cloneDeep'; import WebCustomColumnDrawer from "../component/webCustomColumnDrawer"; import filterColumn from "../utils/filterColumn"; import type WebTable from "../table/webTable"; import { IWebTableProps } from "../table/webTable"; export interface IColumnMethods { init(this: WebTable): void; showCustomColumnDrawer(this: WebTable): void; hideCustomColumnDrawer(this: WebTable): void; setOriginalColumns(this: WebTable, columns: IWebTableProps['columns']): void; changeCurrentColumns(this: WebTable, columns: IWebTableProps['columns']): void; renderCustomColumnDrawer(this: WebTable): ReactNode; } const methods: IColumnMethods = { init() { const { columns = [] } = this.props; const mergeState = { isCustomColumnDrawerShown: false, originalColumns: deepcopy(columns), currentColumns: filterColumn(columns), }; this.state = this.state || {}; assign(this.state, mergeState); }, showCustomColumnDrawer() { this.setState({ isCustomColumnDrawerShown: true, }); }, hideCustomColumnDrawer() { this.setState({ isCustomColumnDrawerShown: false, }); }, setOriginalColumns(columns) { this.setState({ originalColumns: deepcopy(columns), }); }, changeCurrentColumns(columns) { this.setState({ currentColumns: filterColumn(columns), }); }, renderCustomColumnDrawer() { const { isCustomColumnDrawerShown, originalColumns } = this.state; const { nextTablePrefix, locale, onColumnsChange = () => { } } = this.props; return ( { this.changeCurrentColumns(columns); onColumnsChange(columns) this.hideCustomColumnDrawer(); }} /> ); }, }; export default methods; ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/mixin/commonMethods.ts ================================================ import assign from "lodash/assign"; import deepcopy from "lodash/cloneDeep"; import { isValidElement, ReactNode } from "react"; import WebTable from "../table/webTable"; import convertData from "../utils/convertData"; import getDataSource from "../utils/getDataSource"; export interface ICommonMethods { init(this: WebTable): void; loadData(this: WebTable, from: string): void; getDataSource(this: WebTable): any; getDataItem(this: WebTable, value: any): any; onSort(this: WebTable, dataIndex: string, order: string): void; onSearch(this: WebTable, searchKey: string): void; renderEmptyContent(this: WebTable): ReactNode | null; onPageSizeChange(this: WebTable, pageSize: number): void; onPageNumChange(this: WebTable, current: number): void; getPaginationProps(this: WebTable): any; } const methods: ICommonMethods = { init() { const { pagination = {} } = this.props; const { pageSize } = pagination; const result = convertData(getDataSource(this.props)); const mergeState = { searchKey: '', orderColumn: '', orderType: '', dataSource: result.dataSource || [], totalCount: result.totalCount || 0, pageSize, currentPage: result.currentPage || 1, }; this.state = this.state || {}; assign(this.state, mergeState); }, loadData(this, from) { const { onFetchData, onLoadData } = this.props; const { currentPage, pageSize, searchKey, orderColumn, orderType } = this.state; if (onLoadData) { onLoadData(currentPage, pageSize, searchKey, orderColumn, orderType, from); } else { onFetchData && onFetchData({ currentPage, pageSize, searchKey, orderColumn, orderType, from }); } }, getDataSource(this) { const { dataSource } = this.state; const list = deepcopy(dataSource); list.forEach((item: any) => { delete item.__mode__; delete item.__fields__; delete item.__expand__; }); return list; }, getDataItem(value) { const { primaryKey } = this.props; const { dataSource } = this.state; return dataSource.find((item: any) => { return item[primaryKey!] === value; }); }, onSort(dataIndex, order) { this.setState({ orderColumn: dataIndex, orderType: order, }, () => { this.loadData('order'); }); }, onSearch(searchKey) { this.setState({ searchKey }, () => { this.loadData('search'); }); }, renderEmptyContent() { const { setEmptyContent, emptyContent } = this.props; if (!setEmptyContent) { return null; } return typeof emptyContent === 'function' ? emptyContent() : isValidElement(emptyContent) ? emptyContent : null; }, onPageSizeChange(pageSize) { this.setState({ pageSize }, () => { this.loadData('pagination'); }); }, onPageNumChange(current) { this.setState({ currentPage: current, }, () => { this.loadData('pagination'); }); }, getPaginationProps() { const { nextTablePrefix, pagination, locale, noPadding } = this.props; const { currentPage, pageSize, totalCount } = this.state; return { nextTablePrefix, currentPage, totalCount, ...pagination, noPadding, pageSize, locale, onChange: this.onPageNumChange.bind(this), onPageSizeChange: this.onPageSizeChange.bind(this), }; }, }; export default methods; ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/mixin/editableMethods.ts ================================================ import assign from "lodash/assign"; import isObject from "lodash/isObject"; import isEmpty from "lodash/isEmpty"; import dispatchResizeEvent from "../utils/dispatchResizeEvent"; import getCleanRowData from "../utils/getCleanRowData"; import type WebTable from "../table/webTable"; function getDataItemByValue(rowData: any, instance: WebTable) { const { primaryKey } = instance.props; const primaryValue = isObject(rowData) ? (rowData as any)[primaryKey!] : rowData; return instance.getDataItem(primaryValue); } function getAndCloneDataItem(rowData: any, instance: WebTable) { return getCleanRowData(getDataItemByValue(rowData, instance)); } function callTableCell(rowData: any, instance: WebTable, callback: (field: any) => any) { const item = getDataItemByValue(rowData, instance) || {}; const { __fields__ } = item; if (__fields__) { const promiseList: Promise[] = []; Object.keys(__fields__).forEach((name) => { const field = __fields__[name]; if (field && callback) { promiseList.push(Promise.resolve(callback(field))); } }); return Promise.all(promiseList); } return Promise.resolve(); } // editRow(rowData): 使指定的行切换到编辑模式。 // saveRow(rowData): 保存行至数据 // resetRow(rowData): 重置行到数据(若保存过,则为保存过后的数据)。 export interface IEditableMethodsProps { onEditRow?(rowItem: any): void; onResetRow?(rowItem: any): void; onSaveRow?(rowItem: any): void; } export interface IEditableMethods { init(this: WebTable): void; validateRow(this: WebTable, rowData: any): any; editRow(this: WebTable, rowData: any): any; saveRow(this: WebTable, rowData: any): any; resetRow(this: WebTable, rowData: any): any; } const methods: IEditableMethods = { init() { const mergeState = {}; this.state = this.state || {}; assign(this.state, mergeState); }, validateRow(rowData) { return callTableCell(rowData, this, (field) => { return field.validateCell(); }).then((dataList) => { const result: any = {}; dataList && dataList.forEach((field) => { field && Object.keys(field).forEach((name) => { result[name] = field[name]; }); }); return isEmpty(result) ? undefined : result; }); }, editRow(rowData) { const { onEditRow } = this.props; const promise = callTableCell(rowData, this, (field) => { return field.setEditable(true); }).then(() => { const rowItem = getAndCloneDataItem(rowData, this); rowItem && onEditRow && onEditRow(rowItem); return rowItem; }); promise.finally(() => { dispatchResizeEvent(); }); return promise; }, saveRow(rowData) { const { onSaveRow } = this.props; const promise = this.validateRow(rowData).then((error: Error) => { if (error) { return Promise.reject(error); } else { return callTableCell(rowData, this, (field) => { return field.saveCell(); }); } }).then(() => { const rowItem = getAndCloneDataItem(rowData, this); rowItem && onSaveRow && onSaveRow(rowItem); return rowItem; }); promise.finally(() => { dispatchResizeEvent(); }); return promise; }, resetRow(rowData) { const { onResetRow } = this.props; const promise = callTableCell(rowData, this, (field) => { return field.resetCell(); }).then(() => { const rowItem = getAndCloneDataItem(rowData, this); rowItem && onResetRow && onResetRow(rowItem); return rowItem; }); promise.finally(() => { dispatchResizeEvent(); }); return promise; }, }; export default methods; ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/mixin/loadMethods.ts ================================================ import isPlainObject from "lodash/isPlainObject"; export default function loadMethods(target: {[propKey: string]: any}, source: {[propKey: string]: any}) { if (!source || !isPlainObject(source)) { return; } const { init, ...srcMethods } = source; // eslint-disable-next-line guard-for-in,no-restricted-syntax for (const methodName in srcMethods) { target[methodName] = source[methodName]; } if (typeof init === 'function') { init.call(target); } } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/scss/variables.scss ================================================ /* write style here */ @import '~@alifd/next/variables.scss'; // 必须设置,请严格遵循该包含default的写法。 $css-prefix: 'next-' !default; $deep-css-prefix: 'deep-' !default; // 使用到的主题扩展变量,内置默认值 $color-fill1-5: #BBC3CC !default; $color-fill1-6: #A5AFBC !default; $color-fill1-7: #79889B !default; $color-fill1-8: #4C6079 !default; $color-fill1-9: #1F3858 !default; // default for theme-97 $color-brand1-2: #FFF0E5 !default; $color-brand1-3: #FFF7F0 !default; // default for theme-254 //$color-brand1-2: #E5F1FD !default; //$color-brand1-3: #F0F7FF !default; ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/table/webTable.tsx ================================================ import React, { ReactNode } from 'react'; import { Table } from '@alifd/next'; import isEqual from 'lodash/isEqual'; import { ColumnProps, TableProps } from '@alifd/next/types/table'; import convertData from '../utils/convertData'; import loadMethods from "../mixin/loadMethods"; import commonMethods, { ICommonMethods } from "../mixin/commonMethods"; import columnMethods, { IColumnMethods } from "../mixin/columnMethods"; import WebToolbar, { IWebToolbarProps } from "../component/webToolbar"; import WebPagination from "../component/webPagination"; import hasRowAction from "../utils/hasRowAction"; import runToolbarActionCallback from "../utils/runToolbarActionCallback"; import buildTableProps from "../utils/buildTableProps"; import editableMethods, { IEditableMethods, IEditableMethodsProps } from "../mixin/editableMethods"; import WebNextTableActionCell, { IWebNextTableActionCellProps } from "../component/webNextTableActionCell"; import WebNextTableCell, { IWebNextTableCellProps } from "../component/webNextTableCell"; import getDataSource from "../utils/getDataSource"; import titleMessageRender from "../utils/render/titleMessageRender"; import { LoadingProps } from '@alifd/next/types/loading'; export interface IWebTableProps extends IWebToolbarProps, IEditableMethodsProps, Omit, Omit { data?: any; columns?: any[]; nextTablePrefix?: string; isPagination?: boolean; actionTitle?: string; actionFixed?: string; actionWidth?: number | string; pagination?: any; primaryKey?: string; onFetchData?: (options: Pick & { from: string; }) => void; onLoadData?: (...options: any[]) => void; onColumnsChange?: (columns: IWebTableProps['columns']) => void; setEmptyContent?: boolean; emptyContent?: (() => ReactNode) | ReactNode; noPadding?: boolean; dataSource?: any; device?: string; actionHidden?: boolean; theme?: string; width?: string | number; height?: string | number; showRowSelector?: boolean; onSelect?: NonNullable['onSelect']; onSelectAll?: NonNullable['onSelectAll']; isRowSelectorDisabled?: (rowData: any, index: number) => boolean; rowSelector?: string; onCellDataChange?: IWebNextTableCellProps['onCellDataChange']; clsPrefix?: string; tablePrefix?: string; className?: string; loadingComponent?: (props: LoadingProps) => ReactNode; } interface IWebTableState { originalColumns?: any[]; currentColumns?: any[] currentPage: number; pageSize: number; searchKey: string; orderColumn: string; orderType: string; dataSource: any; totalCount: number; isCustomColumnDrawerShown: boolean; } interface WebTable extends React.Component, Omit, Omit, Omit {} class WebTable extends React.Component { static displayName = 'WebTable'; constructor(props: IWebTableProps) { super(props); loadMethods(this, commonMethods); loadMethods(this, columnMethods); loadMethods(this, editableMethods); } componentWillReceiveProps(nextProps: IWebTableProps) { const { data } = this.props; const nextData = getDataSource(nextProps); if (!isEqual(nextData, data)) { this.setState(convertData(nextData)); } const {originalColumns} = this.state; const {columns : nextColumns} = nextProps; if (!isEqual(originalColumns, nextColumns)) { this.setOriginalColumns(nextColumns); this.changeCurrentColumns(nextColumns); } } renderColumn(column: any) { const { nextTablePrefix, onCellDataChange } = this.props; const { lock, dataKey, width, title, titleRender, message, sortable, align, resizable, filters, filterMode } = column; const props: ColumnProps = { dataIndex: dataKey, cell: (value, rowIndex, rowData) => { return (); }, title: titleMessageRender(title, message, nextTablePrefix), width, sortable, align, resizable, filters, filterMode, }; if (lock && lock !== 'none') { props.lock = lock; } if (titleRender) { props.title = titleRender(column.title); } return ; } renderColumns(columns: IWebTableState['currentColumns']) { return columns ? columns.map((column) => { if (!column.isGroup) { return this.renderColumn(column) } return ( column.children && column.children.length ? { this.renderColumns(column.children) } : null ) }) : null; } renderActionColumns() { const { actionTitle, actionFixed, actionWidth, actionColumn, actionType, maxWebShownActionCount, nextTablePrefix, device, primaryKey, locale } = this.props; if (!hasRowAction(this.props)) { return null; } const actionColumnProps: ColumnProps = { title: actionTitle, lock: actionFixed !== 'none' ? actionFixed : false, width: actionWidth, cell: (value, index, rowData) => { return ; }, }; return ; } render() { const { nextTablePrefix, isPagination, locale } = this.props; const { dataSource, currentColumns } = this.state; const paginationProps = this.getPaginationProps(); return (
{ runToolbarActionCallback({ action: item }); }} onSearch={this.onSearch.bind(this)} onClickCustomColumn={this.showCustomColumnDrawer.bind(this)} paginationProps={paginationProps} /> {this.renderColumns(currentColumns)} {this.renderActionColumns()}
{isPagination ? : null} {this.renderCustomColumnDrawer()}
); } } export default WebTable; ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/buildNextTableMethod.ts ================================================ import type { NextTable } from ".."; import { IEditableMethods } from "../mixin/editableMethods"; const methodList: (keyof Omit | 'getDataSource')[] = [ 'editRow', 'saveRow', 'resetRow', 'validateRow', 'getDataSource', ]; export default function buildNextTableMethod(instance: NextTable) { methodList.forEach((name) => { instance[name] = function () { const { tableRef } = instance; const { current } = tableRef; if (current) { const method = current[name]; if (method) { return method.apply(current, arguments as any); } } }; }); } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/buildTableProps.ts ================================================ import { IWebTableProps } from "../table/webTable"; import { TableProps } from '@alifd/next/types/table'; export default function buildTableProps(props: IWebTableProps) { const { loading, dataSource, onSort, emptyContent, onFilter, cellProps, rowProps, primaryKey, theme, hasHeader, fixedHeader, maxBodyHeight, stickyHeader, isTree, indent, onRowClick, onRowMouseEnter, onRowMouseLeave, onResizeChange, width, height, loadingComponent, hasExpandedRowCtrl, expandedRowRender, onRowOpen, expandedRowIndent, useVirtual,offsetTop, sort, sortIcons, showRowSelector, onSelect, onSelectAll, isRowSelectorDisabled, rowSelector, size, expandedIndexSimulate, rowSelection, } = props; let tableProps: TableProps = { size, primaryKey: primaryKey || 'id', dataSource: dataSource || [], hasBorder: theme === 'border', hasHeader, isZebra: theme === 'zebra', loading, emptyContent, cellProps, rowProps, onFilter, fixedHeader, maxBodyHeight, stickyHeader, offsetTop, isTree, indent, useVirtual, onRowClick, onRowMouseEnter, onRowMouseLeave, onResizeChange, sort, sortIcons, onSort, loadingComponent, hasExpandedRowCtrl, expandedRowRender, onRowOpen, expandedRowIndent, style: { width, height }, expandedIndexSimulate, }; if ('openRowKeys' in props) { tableProps.openRowKeys = props.openRowKeys } if (showRowSelector) { let selection: TableProps['rowSelection']; if (rowSelection) { selection = rowSelection; } else { selection = {}; if (onSelect) { selection.onSelect = onSelect; } if (onSelectAll) { selection.onSelectAll = onSelectAll; } selection.mode = rowSelector === 'checkboxSelector' ? 'multiple' : 'single'; if (isRowSelectorDisabled) { const isRowSelectorDisabledFunc = isRowSelectorDisabled; selection.getProps = (rowData, index) => ({ disabled: isRowSelectorDisabledFunc(rowData, index), }); } } tableProps.rowSelection = selection; } return tableProps; } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/chainAccess.ts ================================================ export function safeAccess(obj: { [prop: string]: any }, str: string) { return str.split('.').reduce((o, k) => (o ? o[k] : undefined), obj); }; export function safeWrite(obj: { [prop: string]: any }, str: string, value: any) { const segs = str.split('.'); const key = segs.pop(); const leaf = segs.reduce((o, k) => { if (!o[k]) { o[k] = {}; } return o[k]; }, obj); if (typeof key === 'string') { leaf[key] = value; } }; ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/convertData.ts ================================================ import deepcopy from 'lodash/cloneDeep'; import isPlainObject from "lodash/isPlainObject"; export default function convertData(data: Array | { data?: Array; currentPage?: string; totalCount?: string; }) { let dataSource: Array | undefined = []; let currentPage = 1; let totalCount = 0; if (Array.isArray(data)) { dataSource = data; } else if (isPlainObject(data)) { dataSource = data.data; currentPage = typeof data.currentPage !== "undefined" ? parseInt(data.currentPage, 10) : 1; totalCount = typeof data.totalCount !== "undefined" ? parseInt(data.totalCount, 10) : 0; } return {dataSource : dataSource ? deepcopy(dataSource) : [], currentPage, totalCount}; } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/delegateFunctions.ts ================================================ import deepcopy from "lodash/cloneDeep"; import isFunction from "lodash/isFunction"; export default function delegateFunctions(list: any[] | undefined, key: string, context: any, newArgPosition?: number) { if (list && list.length) { const result = deepcopy(list); result.forEach((item) => { const func = item && item[key]; if (func && isFunction(func)) { item[key] = function () { const ARGS = Array.prototype.slice.call(arguments); if (newArgPosition === undefined) { ARGS.push(context); } else { ARGS.splice(newArgPosition, 0, context); } return func.apply(context, ARGS); }; } }); return result; } } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/dispatchResizeEvent.ts ================================================ let lastDelayId: number; export default function dispatchResizeEvent() { clearTimeout(lastDelayId); lastDelayId = window.setTimeout(function () { if (window.dispatchEvent) { window.dispatchEvent(new Event('resize')); } }, 10); } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/filterActionColumn.ts ================================================ import type { IWebTableProps } from "../table/webTable"; import filterActionColumnByDevice from "./filterActionColumnByDevice"; export default function filterActionColumn(actionColumn: IWebTableProps['actionColumn'], rowData: any, device: IWebTableProps['device']) { const filterByEditable = actionColumn.filter((action) => { if (action.render && typeof action.render === 'function' && !action.render(action.title, rowData)) { return false } if (rowData.__mode__ === "EDIT") { return action.mode === "EDIT"; } else { return action.mode !== "EDIT"; } }); return filterActionColumnByDevice(filterByEditable, device); } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/filterActionColumnByDevice.ts ================================================ import type { IWebTableProps } from "../table/webTable"; export default function filterActionColumnByDevice(actionColumn: IWebTableProps['actionColumn'] = [], device: IWebTableProps['device']) { return actionColumn.filter((action) => { let actionDevice = action.device; if (device && actionDevice) { if (!Array.isArray(actionDevice)) { actionDevice = [actionDevice]; } return actionDevice.includes(device); } else { return true; } }); } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/filterColumn.ts ================================================ import type { IWebCustomColumnDrawerProps } from "../component/webCustomColumnDrawer"; export default function filterColumn(columns: IWebCustomColumnDrawerProps['columns'] = []) { return columns.filter((item) => { return item.hidden !== true; }); } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/formatter.ts ================================================ import Big from 'big.js'; const Formatter = { date: (str: string | false | null, pattern?: string) => { // new Date(null,false) 会返回最初日期。 if (str === null || str === false || str === undefined || str === '') { console.warn('Formatter: invalid date'); return ''; } const date = new Date(str); if (Object.prototype.toString.call(date) === '[object Date]') { if (isNaN(date.getTime())) { // invalid console.warn('Formatter: invalid date'); return ''; } let actualPattern = pattern || 'YYYY-MM-DD'; const o = { 'M+': date.getMonth() + 1, // 月份 'D+': date.getDate(), // 日 'd+': date.getDate(), // 日 'H+': date.getHours(), // 小时 'h+': date.getHours(), // 小时 'm+': date.getMinutes(), // 分 's+': date.getSeconds(), // 秒 'Q+': Math.floor((date.getMonth() + 3) / 3), // 季度 'q+': Math.floor((date.getMonth() + 3) / 3), // 季度 S: date.getMilliseconds(), // 毫秒 }; if (/(y+)/i.test(actualPattern)) { actualPattern = actualPattern.replace( /(y+)/i, (substr, $1) => { return (`${date.getFullYear()}`).slice(4 - $1.length) } ); } (Object.keys(o) as Array).forEach((k) => { if (new RegExp(`(${k})`).test(actualPattern)) { actualPattern = actualPattern.replace(new RegExp(`(${k})`), (substr, $1) => { if ($1.length === 1) return `${o[k]}`; return `00${o[k]}`.slice(`${o[k]}`.length) }) } }); return actualPattern; } return ''; }, money: (str: string, delimiter = ' ', fixedNum?: number | string) => { const actualStr = fixedNum ? new Big(str).toFixed(parseInt(fixedNum.toString(), 10)).toString() : str; if (actualStr.indexOf('.') !== -1) { return actualStr.replace(/(\d)(?=(?:\d{3})+(\.))/g, (match, $1) => $1 + delimiter) .replace(/(\d{3})(?![$|\.|\(|\s])/g, (match, $1) => $1); } return actualStr.replace(/(\d)(?=(?:\d{3})+$)/g, (match, $1) => $1 + delimiter); }, }; export default Formatter; ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/getCleanRowData.ts ================================================ import isPlainObject from "lodash/isPlainObject"; import forOwn from "lodash/forOwn"; import isArray from "lodash/isArray"; function deepCopyExcept(data: any, callback: (value: any, key: string | number) => boolean) { let dest: any, i, shouldExcept, newValue; if (isPlainObject(data)) { dest = {}; forOwn(data, (value, key) => { newValue = deepCopyExcept(value, callback); shouldExcept = callback(newValue, key); if (!shouldExcept) { dest[key] = newValue; } }); } else if (isArray(data)) { dest = []; for (i = 0; i < data.length; i++) { newValue = deepCopyExcept(data[i], callback); shouldExcept = callback(newValue, i); if (!shouldExcept) { dest.push(newValue); } } } else { return data; } return dest; }; export default function getCleanRowData(rowData: any) { if (rowData) { const blackList = ['__mode__', '__fields__', '__expand__']; return deepCopyExcept(rowData, (value, key) => { return blackList.indexOf(key) !== -1 }) } } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/getColumnsFromChildern.tsx ================================================ import React, { ReactNode, ReactElement } from 'react' export default (children: ReactNode) => { const getColumns = (children: ReactNode) => { let columns: any = [] const getCols = (children: ReactNode) => { React.Children.map(children, item => { const { props } = item as ReactElement; if (props.children && props.children.length) { columns.push({ isGroup: true, title: props.align ?
{props.title || ''}
: props.title || '', children: getColumns(props.children) }) } else { columns.push({...props}) } }); } getCols(children) return columns; } return getColumns(children) } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/getDataSource.ts ================================================ import type { IWebTableProps } from "../table/webTable"; export default function getDataSource(props: IWebTableProps) { if (props) { return props.dataSource || props.data; } } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/hasRowAction.ts ================================================ import { IWebTableProps } from "../table/webTable"; import filterActionColumnByDevice from "./filterActionColumnByDevice"; export default function hasRowAction(props: IWebTableProps, withoutEdit?: boolean) { const { actionHidden, actionColumn, device } = props; if (actionHidden) { return false; } if (actionColumn && actionColumn.length) { let actionColumnFilter = filterActionColumnByDevice(actionColumn, device); if (withoutEdit) { actionColumnFilter = actionColumnFilter.filter((action) => { return action.mode !== "EDIT"; }); } return !!(actionColumnFilter && actionColumnFilter.length); } else { return false; } } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/render/actionTitleRender.tsx ================================================ import type { IActionColumnItem } from "../../component/webNextTableActionCell"; export default function actionTitleRender(action: IActionColumnItem, rowData: any) { const { title, render } = action; if (render) { try { return render(title, rowData); } catch (e) { if (e instanceof Error) { console.warn(e.stack); } return title; } } else { return title; } } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/render/cascadeTimestampRender.tsx ================================================ import errorRender from './errorRender'; import defaultRender from './defaultRender'; import Formatter from '../formatter'; export default function cascadeTimestampRender(cellData: any, item: { timeFormatter?: string }) { if (!cellData) { return ''; } const { timeFormatter } = item; if (Object.prototype.toString.call(cellData) === '[object Object]') { if (!cellData.hasOwnProperty('start') && !cellData.hasOwnProperty('end')) { return errorRender(); } const start = Formatter.date(cellData.start, timeFormatter); const end = Formatter.date(cellData.end, timeFormatter); return defaultRender(`${start} ~ ${end}`); } return errorRender(); }; ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/render/commonTableCellRender.tsx ================================================ import defaultRender from "./defaultRender"; import timestampRender from "./timestampRender"; import cascadeTimestampRender from "./cascadeTimestampRender"; import moneyRender from "./moneyRender"; import moneyRangeRender from "./moneyRangeRender"; import linkRender from './linkRender' import fileRender from './fileRender' import enumRender from './enumRender' import imageRender from './imageRender' export default function commonTableCellRender(value: any, index: number, rowData: any, column: any) { const { dataType } = column; if (dataType === 'text') { return defaultRender(value); } if (dataType === 'link') { return linkRender(value, column, rowData) } if (dataType === 'file') { return fileRender(value) } if (dataType === 'image') { return imageRender(value, column, rowData) } if (dataType === 'enum') { return enumRender(value, column) } if (dataType === 'timestamp') { return timestampRender(value, column); } if (dataType === 'cascadeTimestamp') { return cascadeTimestampRender(value, column); } if (dataType === 'money') { return moneyRender(value); } if (dataType === 'moneyRange') { return moneyRangeRender(value); } const { render } = column; if (render) { try { return render(value, index, rowData); } catch (e) { if (e instanceof Error) { console.warn(e.stack); } return defaultRender(value); } } else { return defaultRender(value); } } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/render/defaultRender.tsx ================================================ import React from 'react'; import isObject from "lodash/isObject"; export default function defaultRender(value: any, className = '') { if (value === undefined || value === null) { return ''; } if (isObject(value)) { value = JSON.stringify(value); } return ( {value} ); }; ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/render/enumRender.tsx ================================================ import React, { ReactNode } from 'react'; export default function enumRender(cellData: any, column: { enumData?: { value: any; text?: ReactNode; color?: string }[]; enumBadgeType?: string; }) { if (!cellData && cellData !== 0) { return ''; } const { enumData, enumBadgeType } = column; if (!enumData || !Array.isArray(enumData) || enumData.length === 0) { return cellData; } const found = enumData.find((item) => { return item.value === cellData; }); let color = 'black'; let theme = 'background'; if (!found) { return cellData; } if (found.color) { color = found.color; if (enumBadgeType) { theme = enumBadgeType; } let className = `deep-table-badge deep-table-badge-${theme}-${color}`; return {found.text} } return found.text; }; ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/render/errorRender.tsx ================================================ import defaultRender from './defaultRender'; export default function errorRender() { return defaultRender('数据格式不合法', 'error-cell'); } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/render/fileRender.tsx ================================================ import React from 'react'; export default function fileRender(value: {name?: string; url?: string}[]) { if (!value) { return ''; } if (!value.length || !value.splice) { return
数据格式不合规,请返回数组形式!
} return value.map(file => { return ( {file.name} ) }) }; ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/render/imageRender.tsx ================================================ import React, { MouseEvent } from 'react'; interface IImageRenderColumn { imageProps?: React.CSSProperties & { onClick?(e: MouseEvent, column: IImageRenderColumn, rowData: any): void }; imageWrapProps?: React.CSSProperties; } export default function ImageRender(value: string, column: IImageRenderColumn, rowData: any) { if (!value || typeof value !== 'string') { return
数据格式不合规,请返回字符串形式!
} const imageProps = column.imageProps || { width: 80, height: 80, borderRadius: 4 } const imageWrapProps = column.imageWrapProps || { display: 'inline-block', padding: 4, background: '#eee', borderRadius: 4, height: 88, width: 88 } const { onClick, width } = imageProps const renderImageProps = { src: value, width: width, style: { ...imageProps }, onClick: (e: MouseEvent) => { if (onClick && typeof onClick === 'function') { onClick(e, column, rowData) e.stopPropagation() } } }; return ( ) }; ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/render/linkRender.tsx ================================================ import React from 'react'; import { Button } from '@alifd/next' import { ButtonProps } from '@alifd/next/types/button'; export default function linkRender(value?: { title?: string; href?: string } | string, column?: any, rowData?: any, onClick?: () => void) { if (value === undefined || value === null) { return ''; } let renderProps: ButtonProps = { text: true, type: 'primary', className: `deep-table-link-button`, title: typeof value == 'object' ? value.title : value, style: { ...(rowData.style || {}) }, onClick: () => { onClick && typeof onClick === 'function' && onClick(); if (typeof value === 'object' && value.href) { location.href = value.href; } else if (typeof value == 'string') { location.href = value; } } } return ( ); }; ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/render/moneyRangeRender.tsx ================================================ import errorRender from './errorRender'; import defaultRender from './defaultRender'; import Formatter from '../formatter'; export default function moneyRangeRender(cellData: { lower?: string; upper?: string; currency?: string; }) { if (!cellData) { return ''; } if (Object.prototype.toString.call(cellData) === '[object Object]') { if (!cellData.hasOwnProperty('lower') || !cellData.hasOwnProperty('upper')) { return errorRender(); } let lower; let upper; try { lower = Formatter.money(cellData.lower || '0', ',', 2); upper = Formatter.money(cellData.upper || '0', ',', 2); } catch (e) { return errorRender(); } return defaultRender(`${lower} ${cellData.currency || ''} ~ ${upper} ${cellData.currency || ''}`); } return errorRender(); }; ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/render/moneyRender.tsx ================================================ import errorRender from './errorRender'; import defaultRender from './defaultRender'; import Formatter from '../formatter'; export default function moneyRender(cellData: { amount: string; currency: string; } | string) { if (cellData === undefined || cellData === null) { return ''; } let money; if (typeof cellData === 'object') { if (!cellData.hasOwnProperty('amount') || !cellData.hasOwnProperty('currency')) { return errorRender(); } try { money = Formatter.money(cellData.amount || '0', ',', 2); } catch (e) { return errorRender(); } return defaultRender(`${money} ${cellData.currency}`); } try { money = Formatter.money(cellData || '0', ',', 2); } catch (e) { return errorRender(); } return defaultRender(money); }; ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/render/timestampRender.tsx ================================================ import errorRender from './errorRender'; import defaultRender from './defaultRender'; import Formatter from '../formatter'; export default function timestampRender(cellData: string, item: { timeFormatter?: string }) { if (!cellData) { return ''; } if (isNaN(Number(cellData))) { return errorRender(); } const { timeFormatter } = item; const result = Formatter.date(cellData, timeFormatter); return defaultRender(result); } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/render/titleMessageRender.tsx ================================================ import { Balloon, Icon } from '@alifd/next'; import React, { ReactNode } from 'react'; export default function titleMessageRender(title: ReactNode, message: ReactNode, prefix?: string) { if (!message) { return title; } else { return {title} } align="t" > {message} } } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/runColumnActionCallback.ts ================================================ import { IActionColumnItem } from "../component/webNextTableActionCell"; import getCleanRowData from "./getCleanRowData"; export default function runColumnActionCallback(param: { action: IActionColumnItem; rowData: any; index?: number }) { const { action, rowData, index } = param; const { callback = () => { } } = action; try { if (rowData && callback) { return Promise.resolve(callback(getCleanRowData(rowData), action, index)); } } catch (e) { if (e instanceof Error) { console.warn(e.stack); } } return Promise.reject(); }; ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/runToolbarActionCallback.ts ================================================ import { IAction } from "../component/webToolbar"; export default function runToolbarActionCallback(param: { action: IAction }) { const { action } = param; const { callback } = action; try { return callback && callback(action); } catch (e) { if (e instanceof Error) { console.warn(e.stack); } } }; ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-table/utils/tableProps.ts ================================================ import type { IWebTableProps } from "../table/webTable"; export function fetchKey(source: T, keyList: Array): Partial { const result: Partial = {}; keyList.forEach((k) => { const v = source[k]; if (typeof v !== "undefined") { result[k] = v; } }); return result; } export const tableProps: Array = [ 'clsPrefix', 'loading', 'device', 'locale', 'data', 'children', 'size', 'hasBorder', 'isZebra', 'noPadding', 'useVirtual', 'dataSource', 'onLoadData', 'onFetchData', 'columns', 'openRowKeys', 'onFilter', 'actionBar', 'isPagination', 'pagination', 'actionColumn', 'showMiniPager', 'sort', 'sortIcons', 'onColumnsChange', 'primaryKey', 'theme', 'hasHeader', 'fixedHeader', 'maxBodyHeight', 'stickyHeader', 'isTree', 'indent', 'onRowClick', 'onRowMouseEnter', 'onRowMouseLeave', 'onResizeChange', 'width', 'height', 'loadingComponent', 'hasExpandedRowCtrl', 'expandedRowRender', 'onRowOpen', 'expandedRowIndent', 'showRowSelector', 'onSelect', 'onSelectAll', 'isRowSelectorDisabled', 'rowSelector', 'actionHidden', 'actionColumn', 'actionTitle', 'actionType', 'actionFixed', 'actionWidth', 'maxWebShownActionCount', 'rowSelection', 'cellProps', 'rowProps', 'offsetTop', 'showActionBar', 'actionBar', 'showSearch', 'showCustomColumn', 'searchBarPlaceholder', 'showLinkBar', 'linkBar', "rowOrder", "customBarItem", 'onCellDataChange', 'expandedIndexSimulate', 'onEditRow', 'onSaveRow', 'onResetRow', 'setEmptyContent', 'emptyContent' ]; export const paginationProps = [ 'size', 'type', 'shape', 'pageShowCount', 'pageSize', 'pageSizeSelector', 'pageSizeList', 'pageNumberRender', 'pageSizePosition', 'useFloatLayout', 'hideOnlyOnePage', 'showJump', 'link', 'popupProps', 'paginationPosition', ]; ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-text/index.scss ================================================ $css-prefix: '.next-'; :root { --s-base: 4px; --s-compact: calc(var(--s-base) * 50); --s-comfortable: calc(var(--s-base) * 80); --s-luxury: calc(var(--s-base) * 160); --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-5: 20px; --s-6: 24px; --s-7: 28px; --s-8: 32px; --s-9: 36px; --s-10: 40px; /* font */ --font-family: Roboto, 'Helvetica Neue', Helvetica, Tahoma, Arial, 'PingFang SC', 'Microsoft YaHei'; --p-h1-font-size: 56px; --p-h1-icon-size: 56px; --p-h1-font-weight: 900; --p-h1-line-height: 64px; --p-h1-margin-top: var(--s-9); --p-h1-margin-bottom: var(--s-1); --p-h2-font-size: 48px; --p-h2-icon-size: 48px; --p-h2-font-weight: 800; --p-h2-line-height: 52px; --p-h2-margin-top: var(--s-8); --p-h2-margin-bottom: var(--s-1); --p-h3-font-size: 36px; --p-h3-icon-size: 36px; --p-h3-font-weight: 700; --p-h3-line-height: 44px; --p-h3-margin-top: var(--s-7); --p-h3-margin-bottom: var(--s-1); --p-h4-font-size: 24px; --p-h4-icon-size: 24px; --p-h4-font-weight: 600; --p-h4-line-height: 32px; --p-h4-margin-top: var(--s-5); --p-h4-margin-bottom: var(--s-2); --p-h5-font-size: 20px; --p-h5-icon-size: 20px; --p-h5-font-weight: 500; --p-h5-line-height: 28px; --p-h5-margin-top: var(--s-4); // 上下不一定相等 --p-h5-margin-bottom: var(--s-1); /* large */ --p-h6-font-size: 16px; --p-h6-icon-size: 16px; --p-h6-font-weight: 400; --p-h6-line-height: 24px; --p-h6-margin-top: var(--s-4); --p-h6-margin-bottom: var(--s-1); --p-body1-font-size: 16px; --p-body1-icon-size: 16px; --p-body1-font-weight: 400; --p-body1-line-height: 24px; --p-body1-margin-top: var(--s-3); --p-body1-margin-bottom: var(--s-1); --p-body1-indent-size: var(--s-2); /* medium */ --p-body2-font-size: 14px; --p-body2-icon-size: 14px; --p-body2-font-weight: 400; --p-body2-line-height: 22px; --p-body2-margin-top: var(--s-2); --p-body2-margin-bottom: var(--s-1); --p-body2-indent-size: var(--s-2); /* small */ --p-caption-font-size: 12px; --p-caption-icon-size: 12px; --p-caption-font-weight: 300; --p-caption-line-height: 20px; --p-caption-margin-top: var(--s-3); --p-caption-margin-bottom: var(--s-1); --p-caption-indent-size: var(--s-1); --p-overline-font-size: 10px; --p-overline-icon-size: 10px; --p-overline-font-weight: 200; --p-overline-line-height: 18px; --p-overline-margin-top: var(--s-1); --p-overline-margin-bottom: var(--s-1); } body { --p-h1-margin-top: var(--s-1); --p-h2-margin-top: var(--s-1); --p-h3-margin-top: var(--s-1); --p-h4-margin-top: var(--s-1); --p-h5-margin-top: var(--s-1); --p-h6-margin-top: var(--s-1); --p-body1-margin-top: var(--s-1); --p-body2-margin-top: var(--s-1); --p-caption-margin-top: var(--s-1); } #{$css-prefix}text { color: #1f2633; text-align: justify; // & + & { // margin-left: 0; // } &-title { font-weight: bold; margin-bottom: 0.5em; } & + &-title { margin-top: 1.2em; } &-paragraph { color: #1f2633; margin-bottom: 1em; font-size: 14px; line-height: 1.5; } mark { padding: 0; background: #fffbc7; color: #1f2633; } strong { font-weight: bold; } code { background-color: #f4f6f9; color: #1f2633; border: 1px solid #e4e8ee; margin: 0 0.2em; padding: 0.2em 0.4em 0.1em; font-size: 85%; border-radius: 4px; } ul, ol { margin: 0 0 1em 0; padding: 0; } li { list-style-type: circle; margin: 0 0 0 20px; padding: 0 0 0 4px; } a { text-decoration: none; &:link { color: rgba(3, 193, 253, 1); } &:visited { color: rgba(0, 123, 176, 1); } &:hover { color: rgba(0, 157, 214, 1); } &:active { text-decoration: underline; color: rgba(0, 157, 214, 1); } } } h1#{$css-prefix}text-title { font-size: 24px; } h2#{$css-prefix}text-title { font-size: 20px; } h3#{$css-prefix}text-title { font-size: 16px; } h4#{$css-prefix}text-title { font-size: 16px; } h5#{$css-prefix}text-title { font-size: 14px; } h6#{$css-prefix}text-title { font-size: 14px; } #{$css-prefix}text { &-inherit { font-family: inherit; font-size: inherit; font-weight: inherit; line-height: inherit; } &-overline { font-family: var(--p-overline-font-family); font-size: var(--p-overline-font-size); font-weight: var(--p-overline-font-weight); line-height: var(--p-overline-line-height); } &-caption { font-family: var(--p-caption-font-family); font-size: var(--p-caption-font-size); font-weight: var(--p-caption-font-weight); line-height: var(--p-caption-line-height); } &-body2 { font-family: var(--p-body2-font-family); font-size: var(--p-body2-font-size); font-weight: var(--p-body2-font-weight); line-height: var(--p-body2-line-height); } &-body1 { font-family: var(--p-body1-font-family); font-size: var(--p-body1-font-size); font-weight: var(--p-body1-font-weight); line-height: var(--p-body1-line-height); } &-h6 { font-family: var(--p-h6-font-family); font-size: var(--p-h6-font-size); font-weight: var(--p-h6-font-weight); line-height: var(--p-h6-line-height); } &-h5 { font-family: var(--p-h5-font-family); font-size: var(--p-h5-font-size); font-weight: var(--p-h5-font-weight); line-height: var(--p-h5-line-height); } &-h4 { font-family: var(--p-h4-font-family); font-size: var(--p-h4-font-size); font-weight: var(--p-h4-font-weight); line-height: var(--p-h4-line-height); } &-h3 { font-family: var(--p-h3-font-family); font-size: var(--p-h3-font-size); font-weight: var(--p-h3-font-weight); line-height: var(--p-h3-line-height); } &-h2 { font-family: var(--p-h2-font-family); font-size: var(--p-h2-font-size); font-weight: var(--p-h2-font-weight); line-height: var(--p-h2-line-height); } &-h1 { font-family: var(--p-h1-font-family); font-size: var(--p-h1-font-size); font-weight: var(--p-h1-font-weight); line-height: var(--p-h1-line-height); } } ================================================ FILE: packages/fusion-lowcode-materials/src/components/next-text/index.tsx ================================================ import * as React from 'react'; import classNames from 'classnames'; export const createTitle = (Tag) => { /** * Typography.Title * @description 分为 H1, H2, H3, H4, H5, H6 不同的组件,表示不同层级,继承 Typography.Text API * @order 1 */ class Title extends React.Component { static defaultProps = { prefix: 'next-', }; render() { const { prefix, className, ...others } = this.props; return ( ); } } Title.displayName = Tag.toUpperCase(); return Title; }; /** * 判断是否是生产环境 * @type {Boolean} */ export const isProduction = () => { const PRODUCTION_ENV = 'production'; let result = false; try { if (process.env.NODE_ENV === PRODUCTION_ENV) { result = true; } } catch (err) { // } return result; }; // 兼容老逻辑 export const textTypeMap = { 'body-1': 'body2', 'body-2': 'body1', subhead: 'h6', title: 'h5', headline: 'h4', 'display-1': 'h3', 'display-2': 'h2', 'display-3': 'h1', }; interface TextProps { prefix?: string; className?: string; // type?: 'overline' | 'caption' | 'body-1' | 'body-2' | 'subhead' | 'title' | 'headline' | 'display-1' | 'display-2' | 'display-3'; // title === h5 // des === description type?: | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'title' | 'h6' | 'body1' | 'body2' | 'caption' | 'overline' | 'inherit'; children?: React.ReactNode; /** * 添加删除线样式 */ delete?: boolean; /** * 添加标记样式 */ mark?: boolean; /** * 添加下划线样式 */ underline?: boolean; /** * 是否加粗 */ strong?: boolean; /** * 添加代码样式 */ code?: boolean; /** * 设置标签类型 */ component?: React.ElementType; } /** * 文字 字体、大小、行高 * @param props */ const Text: React.FC = (props, ref) => { const { prefix, className, type, component = 'span', strong, underline, delete: deleteProp, code, mark, ...others } = props; let { children } = props; const newType = textTypeMap[type] || type; const cls = classNames(className, { [`${prefix}text`]: true, [`${prefix}text-${newType}`]: newType, }); if (typeof children === 'string' && children.indexOf('\n') !== -1) { const childrenList = children.split('\n'); const newChildren: any = []; childrenList.forEach((child) => { newChildren.push(child); newChildren.push(
); }); newChildren.pop(); children = newChildren; } const Tag = component; if (strong) { children = {children}; } if (underline) { children = {children}; } if (deleteProp) { children = {children}; } if (code) { children = {children}; } if (mark) { children = {children}; } return ( {children} ); }; const RefText = React.forwardRef(Text); RefText.defaultProps = { prefix: 'next-', }; const Paragraph: React.FC = (props) => { const { prefix, className, component, ...others } = props; const cls = classNames(`${prefix}text-paragraph`, className); if (!isProduction()) { console.warn('Warning: Text.Paragraph is deprecated, use P instead'); } return ; }; // 为了保证兼容性,@alifd/next基础组件中 Typography 组件有的所有子组件、功能,Text也有,但是均不建议使用 RefText.H1 = createTitle('h1'); RefText.H2 = createTitle('h2'); RefText.H3 = createTitle('h3'); RefText.H4 = createTitle('h4'); RefText.H5 = createTitle('h5'); RefText.H6 = createTitle('h6'); RefText.Paragraph = Paragraph; export default RefText; ================================================ FILE: packages/fusion-lowcode-materials/src/components/note-wrapper/index.scss ================================================ /* write style here */ .done-note-wrapper.render-wrapper-root { // display: none !important; display: block !important; position: absolute !important; z-index: 1 !important; top: 0 !important; left: 0 !important; width: 100% !important; height: 100% !important; line-height: 0 !important; color: #000 !important; border: 1px dashed rgba(9, 195, 182, 0.5) !important; border-radius: 0 !important; pointer-events: none !important; text-align: left !important; margin: 0; padding: 0; .render-wrapper-note { display: inline-block; width: 18px; height: 18px; margin: -1px 0 0 -1px; line-height: 18px; text-align: center; font-size: 12px; color: #fff; background: #09c3b6; border-radius: 0 0 60% 0; opacity: 0.5; pointer-events: auto; cursor: pointer; &:hover { opacity: 1; box-shadow: 1px 1px 4px rgba(68, 215, 182, 0.5); } } &.hover { border-color: #09c3b6 !important; .render-wrapper-note { opacity: 1; background: #09c3b6; } } } .render-wrapper-target:hover > .render-wrapper-root, .render-wrapper-root.hover { display: block !important; } // 全局禁用批注 .preview-shell-note-0 { .render-wrapper-root { display: none !important; } .render-wrapper-target:hover > .render-wrapper-root, .render-wrapper-root.hover { display: none !important; } } // 全局开启批注 .preview-shell-note-1 { } // 全局批注全部显示 .preview-shell-note-2 { .render-wrapper-root { display: block !important; } } ================================================ FILE: packages/fusion-lowcode-materials/src/components/note-wrapper/index.tsx ================================================ import React, { useEffect } from 'react'; import ReactDom from 'react-dom'; import { Balloon } from '@alifd/next'; const targetClass = 'render-wrapper-target'; const rootClass = 'render-wrapper-root done-note-wrapper'; // 获取DOM真实style的方法 const getStyle = (obj, attr) => { if (obj.currentStyle) { // 兼容IE return obj.currentStyle[attr]; } else { return window.getComputedStyle(obj, null)[attr]; } }; interface NoteProps { note?: string; id?: string; } const NoteWrapper: React.ForwardRefRenderFunction = (props, ref) => { const el = document.createElement('div'); let innerRef = null; el.className = rootClass; el.id = props.id; el.ref = ref; const _renderLayer = function() { const { note } = props; const defaultTrigger =
N
; const node = ( {note} ); ReactDom.render(node, el); }; useEffect(() => { _renderLayer(); if (innerRef) { const refDom = ReactDom.findDOMNode(innerRef); if (refDom.className.indexOf(targetClass) === -1) { if (getStyle(refDom, 'position') === 'static') { refDom.style.position = 'relative'; // 当target目标组件的position为static时, 则使用relative, 方便内层元素定位 } refDom.className += ` ${targetClass}`; refDom.appendChild(el); } } }); const { children } = props; const _children = React.Children.map(children, (child) => { let c = child; if (typeof child === 'string') c = {child}; return React.cloneElement(c, { ref: (ref) => (innerRef = ref) }); }); return _children || <>; }; const RefNoteWrapper = React.forwardRef(NoteWrapper); RefNoteWrapper.displayName = 'Wrapper'; export default RefNoteWrapper; ================================================ FILE: packages/fusion-lowcode-materials/src/components/rich-text/index.tsx ================================================ import * as React from 'react'; // 新结构 interface IContent { aone?: { // 可能未绑定 url: string; priorityId: string; project: { id: string; name: string }; creator: { empId: string; name: string }; assigner: { empId: string; name: string }; }; subject: string; description: string; hideTitle?: boolean; id?: string; } interface IRichTextProps { content?: IContent | string; className?: string; maxHeight?: string; } /** * 文字 字体、大小、行高 * @param props */ const RichText: React.ForwardRefRenderFunction = (props, ref) => { const { content = { subject: '', description: '' }, maxHeight = 'auto', ...others }: IRichTextProps = props; const oldType = typeof content === 'string'; const desc = oldType ? content : content?.description || ''; const title = (!oldType && content?.subject) || ''; const hideTitle = oldType || content?.hideTitle; return (
{!hideTitle && (
{title}
)}
); }; const RefRichText = React.forwardRef(RichText); RefRichText.defaultProps = { content: { subject: '需求标题', hideTitle: false, description: '
- 你可以在这里描述需求
- 或者粘贴需求截图
', }, className: '', }; export default RefRichText; ================================================ FILE: packages/fusion-lowcode-materials/src/components/video/index.tsx ================================================ import * as React from 'react'; export interface Props { src?: string; autoPlay?: boolean; //自动播放必须设置 muted=true loop?: boolean; muted?: boolean; controls?: boolean; poster?: string; style?: object; } /** * 视频 */ const Video: React.ForwardRefRenderFunction = (props, ref) => { return ; }; const RefVideo = React.forwardRef(Video); RefVideo.defaultProps = { src: 'https://fusion.alicdn.com/fusion-site-2.0/fusion.mp4', }; export default RefVideo; ================================================ FILE: packages/fusion-lowcode-materials/src/index.scss ================================================ @import './components/note-wrapper/index.scss'; @import './components/next-text/index.scss'; ================================================ FILE: packages/fusion-lowcode-materials/src/index.tsx ================================================ import Link from './components/link'; import Image from './components/image'; import Video from './components/video'; import Balloon from './components/balloon'; import Calendar from './components/calendar'; import RichText from './components/rich-text'; import NextText from './components/next-text'; import NoteWrapper from './components/note-wrapper'; import NextTable from './components/next-table'; import Div from './components/div'; export { Affix, Animate, Badge, Breadcrumb, Button, Calendar2, Card, Cascader, CascaderSelect, Checkbox, Collapse, ConfigProvider, DatePicker, Dialog, Drawer, Dropdown, Form, Grid, Icon, Input, Loading, Menu, MenuButton, Message, Nav, Notification, NumberPicker, Overlay, Pagination, Paragraph, Progress, Radio, Range, Rating, Search, Select, Slider, SplitButton, Step, Switch, Tab, Table, Tag, TimePicker, TimePicker2, Timeline, Transfer, Tree, TreeSelect, Upload, VirtualList, Typography, Field, Divider, Avatar, ResponsiveGrid, Box, List, DatePicker2, } from '@alifd/next'; export { Link, Image, Video, RichText, NextText, NoteWrapper, Calendar, Balloon, NextTable, Div }; ================================================ FILE: packages/fusion-lowcode-materials/src/utils.js ================================================ module.exports = { replacer(key, value) { if (typeof value === 'function') { return { type: 'JSFunction', value: String(value), }; } return value; }, isAsyncFunction: (fn) => { return fn[Symbol.toStringTag] === 'AsyncFunction'; }, reviewer(key, value) { if (!value) { return value; } if (key === 'icon') { if (typeof value === 'object') { return { type: 'smile', size: 'small', }; } } if (typeof value === 'object') { if (value.type === 'JSFunction') { let _value = value.value && value.value.trim(); let template = ` return function lowcode() { const self = this; try { return (${_value}).apply(self, arguments); } catch(e) { console.log('call function which parsed by lowcode for key ${key} failed: ', e); return e.message; } };`; try { return Function(template)(); } catch (e) { if (e && e.message.includes("Unexpected token '{'")) { console.log('method need add funtion prefix'); _value = 'function ' + _value; template = ` return function lowcode() { const self = this; try { return (${_value}).apply(self, arguments); } catch(e) { console.log('call function which parsed by lowcode for key ${key} failed: ', e); return e.message; } };`; return Function(template)(); } console.error('parse lowcode function error: ', e); console.error(value); return value; } } } return value; }, toJson(object, replacer) { return JSON.stringify(object, replacer || this.replacer, 2); }, parseJson(json) { const input = typeof json === 'string' ? json : JSON.stringify(json); return JSON.parse(input, this.reviewer); }, calculateDependencies(schema, componentsMap) { function findComps(schema, componentsMap, dependencies) { dependencies = dependencies || {}; if (dependencies[schema.componentName]) { dependencies[schema.componentName].count++; } else { dependencies[schema.componentName] = { count: 1, }; if (componentsMap && componentsMap[schema.componentName]) { dependencies[schema.componentName].npm = componentsMap[schema.componentName].package; dependencies[schema.componentName].version = componentsMap[schema.componentName].version; } } if (schema.children && Array.isArray(schema.children)) { schema.children.forEach((child) => { dependencies = Object.assign(dependencies, findComps(child, componentsMap, dependencies)); }); } return dependencies; } const comps = findComps(schema, componentsMap); const deps = {}; Object.keys(comps).forEach((key) => { const comp = comps[key]; if (!comp.npm) comp.npm = 'BuiltIn'; if (deps[`${comp.npm}${comp.version ? '@' + comp.version : ''}`]) { deps[`${comp.npm}${comp.version ? '@' + comp.version : ''}`][key] = comp.count; } else { deps[`${comp.npm}${comp.version ? '@' + comp.version : ''}`] = { [key]: comp.count, }; } }); return deps; }, }; ================================================ FILE: packages/fusion-ui/.editorconfig ================================================ root = true [*] indent_style = space indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true quote_type = single [*.md] trim_trailing_whitespace = false ================================================ FILE: packages/fusion-ui/.eslintignore ================================================ node_modules/ build/ dist/ lib/ es/ docs/ plugins/ build* **/*.min.js **/*-min.js **/*.bundle.js ================================================ FILE: packages/fusion-ui/.eslintrc.js ================================================ module.exports = { extends: [ 'eslint-config-ali/typescript/react', 'prettier', 'prettier/@typescript-eslint', 'prettier/react', ], rules: { '@typescript-eslint/ban-ts-comment': 'off', }, }; ================================================ FILE: packages/fusion-ui/.gitignore ================================================ lowcode_es/ lowcode_lib/ # See https://help.github.com/ignore-files/ for more about ignoring files. # dependencies node_modules/ # production build/ dist/ tmp/ lib/ es/ # misc .idea/ .happypack .DS_Store *.swp *.dia~ .tmp npm-debug.log* yarn-debug.log* yarn-error.log* yarn.lock storybook-static/ docs/src/.umi/ ================================================ FILE: packages/fusion-ui/.markdownlint.json ================================================ { "extends": "markdownlint-config-ali" } ================================================ FILE: packages/fusion-ui/.markdownlintignore ================================================ node_modules/ build/ dist/ ================================================ FILE: packages/fusion-ui/.prettierrc.js ================================================ module.exports = { printWidth: 100, tabWidth: 2, semi: true, singleQuote: true, trailingComma: 'all', arrowParens: 'always', }; ================================================ FILE: packages/fusion-ui/.stylelintignore ================================================ node_modules/ build/ dist/ es/ lib/ docs/ **/*.min.css **/*-min.css **/*.bundle.css ================================================ FILE: packages/fusion-ui/.stylelintrc.js ================================================ module.exports = { extends: 'stylelint-config-ali', }; ================================================ FILE: packages/fusion-ui/README.md ================================================ # README ## 开发常用命令 - `cnpm start` 运行所有组件的开发调试环境 - `cnpm start page-header` 运行单个组件的开发调试环境 - `cnpm run lowcode:dev` 启动低代码开发调试环境 - `cnpm run lowcode:build` 构建低代码产物 - `cnpm run build` 打包生成 lib/ es/ dist/ build/文件 - `cnpm run materials` 生成物料中心需要的入库 JSON 文件 - `cnpm run lint` 进行代码检查 ================================================ FILE: packages/fusion-ui/build.json ================================================ { "library": "AlifdFusionUi", "libraryTarget": "umd", "sourceMap": false, "alias": { "@": "./src", "@components": "./src/components" }, "plugins": [ [ "build-plugin-component", { "themePackage": "@alifd/theme-2" } ], [ "build-plugin-fusion", { "uniteBaseComponent": "@alifd/next", "cssVariable": true, "importOptions": { "libraryDirectory": "lib" } } ] ] } ================================================ FILE: packages/fusion-ui/build.lowcode.js ================================================ const { library } = require('./build.json'); const { version, name } = require('./package.json'); module.exports = { sourceMap: false, alias: { '@': './src', '@alifd/fusion-ui': './src', }, plugins: [ [ '@alifd/build-plugin-lowcode', { noParse: true, renderUrls: [ `https://alifd.alicdn.com/npm/${name}@${version}/dist/${library}.js`, `https://alifd.alicdn.com/npm/${name}@${version}/dist/${library}.css`, ], baseUrl: { prod: `https://alifd.alicdn.com/npm/${name}@${version}`, daily: `https://alifd.alicdn.com/npm/${name}@${version}`, }, engineScope: '@alilc', }, ], [ 'build-plugin-fusion', { uniteBaseComponent: '@alifd/next', cssVariable: true, importOptions: { libraryDirectory: 'lib', }, }, ], ], }; ================================================ FILE: packages/fusion-ui/commitlint.config.js ================================================ module.exports = { extends: ['ali'], }; ================================================ FILE: packages/fusion-ui/docs/.dumi/theme/builtins/API.tsx ================================================ import React, { useContext } from 'react'; import type { IApiComponentProps } from 'dumi/theme'; import { context, useApiData } from 'dumi/theme'; import './index.scss'; const LOCALE_TEXTS = { 'zh-CN': { name: '参数', description: '说明', type: '类型', default: '默认值', required: '(必选)', }, 'en-US': { name: 'Name', description: 'Description', type: 'Type', default: 'Default', required: '(required)', }, }; export default ({ identifier, export: expt }: IApiComponentProps) => { const data = useApiData(identifier); const { locale = '' } = useContext(context); const texts = /^zh|cn$/i.test(locale) ? LOCALE_TEXTS['zh-CN'] : LOCALE_TEXTS['en-US']; const defaultComponentName = identifier ?.replace(/-([a-z])/g, function (all, i) { return i.toUpperCase(); }) ?.replace(/^\S/, (s) => s.toUpperCase()); return ( <> {data && ( <>

{expt === 'default' ? defaultComponentName : expt}

{data[expt]?.map((row) => ( ))}
{texts.name} {texts.description} {texts.type} {texts.default}
{row.identifier} {row.description || '--'} {row.type} {row.default || (row.required && texts.required) || '--'}
)} ); }; ================================================ FILE: packages/fusion-ui/docs/.dumi/theme/builtins/index.scss ================================================ .apiContainer { border: none !important; .apiTitle{ text-transform: capitalize; } thead tr { th { background: #fff; border: none; font-weight: 700; text-align: left; word-wrap: break-word; letter-spacing: 0.2px; padding: 4px 0 10px; border-bottom: 2px solid #333; font-size: 14px; &:first-child { padding-left: 8px; } } } tbody tr { td { border: none; border-bottom: 1px solid #ccc; text-align: left; margin: 0; padding: 18px 18px 18px 0; color: #666; word-wrap: break-word; line-height: 24px; letter-spacing: 0.2px; font-size: 14px; code { color: #666; word-wrap: break-word; line-height: 24px; letter-spacing: 0.2px; font-size: 13px; } &:last-child { min-width: 72px; } &:first-child{ color: #595959; font-weight: 600; white-space: nowrap; padding-left: 8px; font-size: 14px; } } } } .__dumi-default-layout-footer-meta { border: none; } ================================================ FILE: packages/fusion-ui/docs/.dumi/theme/layout.tsx ================================================ import React from 'react'; import Layout from 'dumi-theme-default/es/layout'; import '@/index.scss'; import '@alifd/theme-2/dist/next.min.css'; export default ({ children, ...props }) => { return {children}; }; ================================================ FILE: packages/fusion-ui/docs/.fatherrc.ts ================================================ export default { esm: 'rollup', sassInRollupMode: {}, sass: { // 默认值 Dart Sass,如果要改用 Node Sass,可安装 node-sass 依赖,然后使用该配置项 implementation: require('node-sass'), // 传递给 Dart Sass 或 Node Sass 的配置项,可以是一个 Function sassOptions: { }, }, } ================================================ FILE: packages/fusion-ui/docs/.umirc.ts ================================================ import { defineConfig } from 'dumi'; import fs from 'fs'; import { join } from 'path'; const { version } = JSON.parse(fs.readFileSync(join(__dirname, '../package.json'), 'utf8')); const productStyles = '.__dumi-default-menu{display:none} .__dumi-default-layout{padding-left:58px!important}'; const productPath = `/@alifd/fusion-ui@${version}/build/docs/`; export default defineConfig({ // other config entry chainWebpack(memo) { memo.module .rule('js') .include.add(join(__dirname, '../')) .end() .exclude.add(/node_modules/); // 删除 dumi 内置插件 memo.plugins.delete('friendly-error'); memo.plugins.delete('copy'); // 配置文件import alias memo.resolve.alias.set('@', join(__dirname, '../src')); memo.resolve.alias.set('@components', join(__dirname, '../src/components')); memo.resolve.alias.set('@alifd/fusion-ui', join(__dirname, '../src')); }, logo: 'https://fusion.alicdn.com/images/jdSvK6gaqaWB.png', exportStatic: process.env.NODE_ENV === 'production' ? { htmlSuffix: true } : {}, base: process.env.NODE_ENV === 'production' ? productPath : '/', publicPath: process.env.NODE_ENV === 'production' ? productPath : '/', styles: process.env.NODE_ENV === 'production' ? [productStyles] : [], nodeModulesTransform: { type: 'none', exclude: [], }, // md文件中使用@需配置alias alias: { '@': join(__dirname, '../src'), '@components': join(__dirname, '../src/components'), '@alifd/fusion-ui': join(__dirname, '../src'), }, apiParser: { propFilter: (prop) => { if (prop.declarations !== undefined && prop.declarations.length > 0) { const hasPropAdditionalDescription = prop.declarations.find((declaration) => { if (declaration.fileName.includes('node_modules')) { return ( declaration.fileName.includes('alifd/next') || declaration.fileName.includes('bizcharts') ); } return true; }); return Boolean(hasPropAdditionalDescription); } return true; }, }, mfsu: {}, locales: [ ['zh-CN', '中文'], ['en-US', 'English'], ], outputPath: '../build/docs', }); ================================================ FILE: packages/fusion-ui/docs/src/BarChart/index.md ================================================ ## 何时使用 BarChart 的基础用法。 ## 示例 ```tsx import React from 'react'; import { BarChart } from '@alifd/fusion-ui'; const props = { data: [ { year: '1991', value: 72345678 }, { year: '1992', value: 4321132 }, { year: '1993', value: 33121112.5 }, { year: '1994', value: 45227221 }, { year: '1995', value: 4321221.9 }, { year: '1996', value: 6322121 }, { year: '1997', value: 78312213 }, { year: '1998', value: 4192312 }, { year: '1999', value: 6212332 }, { year: '2000', value: 3192312 }, ], xField: 'value', yField: 'year', color: '#0079f2', label: { visible: true, position: 'middle', }, }; export default () => { return (
basic demo
); }; ``` ## API ================================================ FILE: packages/fusion-ui/docs/src/ColumnChart/index.md ================================================ ## 何时使用 ColumnChart 的基础用法。 ## 示例 ```tsx import React from 'react'; import { ColumnChart } from '@alifd/fusion-ui'; const props = { data: [ { year: '1991', value: 72345678 }, { year: '1992', value: 4321132 }, { year: '1993', value: 33121112.5 }, { year: '1994', value: 45227221 }, { year: '1995', value: 4321221.9 }, { year: '1996', value: 6322121 }, { year: '1997', value: 78312213 }, { year: '1998', value: 4192312 }, { year: '1999', value: 6212332 }, { year: '2000', value: 3192312 }, ], xField: 'year', yField: 'value', color: '#0079f2', label: { visible: true, position: 'middle', }, }; export default () => { return (
basic demo
); }; ``` ## API ================================================ FILE: packages/fusion-ui/docs/src/DonutChart/index.md ================================================ ## 何时使用 DonutChart 的基础用法。 ## 示例 ### 基本用法 ```tsx import React from 'react'; import { DonutChart } from '@alifd/fusion-ui'; const props = { legend: { position: 'top-left', }, data: [ { year: '1991', value: 72345678 }, { year: '1992', value: 4321132 }, { year: '1993', value: 33121112.5 }, { year: '1994', value: 45227221 }, { year: '1995', value: 4321221.9 }, { year: '1996', value: 6322121 }, { year: '1997', value: 78312213 }, { year: '1998', value: 2192312 }, { year: '1999', value: 6212332 }, { year: '2000', value: 1192312 }, ], angleField: 'value', colorField: 'year', label: { visible: true, type: 'spider', }, color: ['#3BCBD1', '#47A4FE', '#EDBA42', '#F4704E', '#ED6899', '#7F62C3', '#6E7BC9'], }; export default () => { return (
); }; ``` ### 显示百分比 ```tsx import React from 'react'; import { DonutChart } from '@alifd/fusion-ui'; const props = { legend: { position: 'top-left', }, data: [ { year: '1991', value: 72345678 }, { year: '1992', value: 4321132 }, { year: '1993', value: 33121112.5 }, { year: '1994', value: 45227221 }, { year: '1995', value: 4321221.9 }, { year: '1996', value: 6322121 }, { year: '1997', value: 78312213 }, { year: '1998', value: 2192312 }, { year: '1999', value: 6212332 }, { year: '2000', value: 1192312 }, ], angleField: 'value', colorField: 'year', color: ['#3BCBD1', '#47A4FE', '#EDBA42', '#F4704E', '#ED6899', '#7F62C3', '#6E7BC9'], }; export default () => { return (
); }; ``` ## API ================================================ FILE: packages/fusion-ui/docs/src/EditTable/index.md ================================================ ## 何时使用 EditTable 的基础用法,演示自己控制数据的用法。code 试一下能不能用 ## 示例 ## API ================================================ FILE: packages/fusion-ui/docs/src/EditTable/index.tsx ================================================ import React from 'react'; import { EditTable } from '@alifd/fusion-ui'; const props = { dataSource: [ { id: 'id-2f5DdE2b-0', date: '2013-06-12', percent: 1.862, documentAmount: 2022, currency: 'CNY', company: '支付宝科技有限公司', childTableProps: { dataSource: [], columns: [ { title: '公司', dataIndex: 'company', width: 160, formatType: 'link', searchable: true, }, { title: '单据金额', dataIndex: 'documentAmount', formatType: 'money', }, { title: '币种', dataIndex: 'currency', formatType: 'currency', filters: [ { label: 'CNY', value: 'CNY', }, { label: 'USD', value: 'USD', }, { label: 'JPY', value: 'JPY', }, { label: 'HKD', value: 'HKD', }, ], filterMode: 'multiple', explanation: '提示信息', width: 110, }, { title: '完成进度', dataIndex: 'percent', formatType: 'progress', }, { title: '到账日期', dataIndex: 'date', formatType: 'date', }, ], }, }, { id: 'id-2f5DdE2b-1', date: '2013-06-12', percent: 1.862, documentAmount: 2022, currency: 'CNY', company: '支付宝科技有限公司', childTableProps: { dataSource: [], columns: [ { title: '公司', dataIndex: 'company', width: 160, formatType: 'link', searchable: true, }, { title: '单据金额', dataIndex: 'documentAmount', formatType: 'money', }, { title: '币种', dataIndex: 'currency', formatType: 'currency', filters: [ { label: 'CNY', value: 'CNY', }, { label: 'USD', value: 'USD', }, { label: 'JPY', value: 'JPY', }, { label: 'HKD', value: 'HKD', }, ], filterMode: 'multiple', explanation: '提示信息', width: 110, }, { title: '完成进度', dataIndex: 'percent', formatType: 'progress', }, { title: '到账日期', dataIndex: 'date', formatType: 'date', }, ], }, }, { id: 'id-2f5DdE2b-2', date: '2013-06-12', percent: 1.862, documentAmount: 2022, currency: 'CNY', company: '支付宝科技有限公司', childTableProps: { dataSource: [], columns: [ { title: '公司', dataIndex: 'company', width: 160, formatType: 'link', searchable: true, }, { title: '单据金额', dataIndex: 'documentAmount', formatType: 'money', }, { title: '币种', dataIndex: 'currency', formatType: 'currency', filters: [ { label: 'CNY', value: 'CNY', }, { label: 'USD', value: 'USD', }, { label: 'JPY', value: 'JPY', }, { label: 'HKD', value: 'HKD', }, ], filterMode: 'multiple', explanation: '提示信息', width: 110, }, { title: '完成进度', dataIndex: 'percent', formatType: 'progress', }, { title: '到账日期', dataIndex: 'date', formatType: 'date', }, ], }, }, ], actionColumnButtons: { dataSource: [ { children: '查看', type: 'primary', }, { children: '编辑', type: 'primary', disabled: true, }, { children: '删除', type: 'primary', }, ], text: true, visibleButtonCount: 3, }, actionBarButtons: { dataSource: [ { type: 'primary', children: '操作一', }, { type: 'normal', children: '操作二', }, ], visibleButtonCount: 3, }, paginationProps: { pageSize: 20, current: 1, }, settingButtons: true, columns: [ { title: '公司', dataIndex: 'company', width: 160, formatType: 'link', searchable: true, }, { title: '单据金额', dataIndex: 'documentAmount', formatType: 'money', }, { title: '币种', dataIndex: 'currency', formatType: 'currency', filters: [ { label: 'CNY', value: 'CNY', }, { label: 'USD', value: 'USD', }, { label: 'JPY', value: 'JPY', }, { label: 'HKD', value: 'HKD', }, ], filterMode: 'multiple', explanation: '提示信息', width: 110, }, { title: '完成进度', dataIndex: 'percent', formatType: 'progress', }, { title: '到账日期', dataIndex: 'date', formatType: 'date', }, ], }; export default () => { return (
); }; ================================================ FILE: packages/fusion-ui/docs/src/ExpandTable/index.md ================================================ ## 何时使用 ExpandTable 的基础用法,演示自己控制数据的用法。code 试一下能不能用 ## 示例 ## API ================================================ FILE: packages/fusion-ui/docs/src/ExpandTable/index.tsx ================================================ import React from 'react'; import { ExpandTable } from '@alifd/fusion-ui'; const props = { dataSource: [ { id: 'id-2f5DdE2b-0', date: '2013-06-12', percent: 1.862, documentAmount: 2022, currency: 'CNY', company: '支付宝科技有限公司', childTableProps: { dataSource: [], columns: [ { title: '公司', dataIndex: 'company', width: 160, formatType: 'link', searchable: true, }, { title: '单据金额', dataIndex: 'documentAmount', formatType: 'money', }, { title: '币种', dataIndex: 'currency', formatType: 'currency', filters: [ { label: 'CNY', value: 'CNY', }, { label: 'USD', value: 'USD', }, { label: 'JPY', value: 'JPY', }, { label: 'HKD', value: 'HKD', }, ], filterMode: 'multiple', explanation: '提示信息', width: 110, }, { title: '完成进度', dataIndex: 'percent', formatType: 'progress', }, { title: '到账日期', dataIndex: 'date', formatType: 'date', }, ], }, }, { id: 'id-2f5DdE2b-1', date: '2013-06-12', percent: 1.862, documentAmount: 2022, currency: 'CNY', company: '支付宝科技有限公司', childTableProps: { dataSource: [], columns: [ { title: '公司', dataIndex: 'company', width: 160, formatType: 'link', searchable: true, }, { title: '单据金额', dataIndex: 'documentAmount', formatType: 'money', }, { title: '币种', dataIndex: 'currency', formatType: 'currency', filters: [ { label: 'CNY', value: 'CNY', }, { label: 'USD', value: 'USD', }, { label: 'JPY', value: 'JPY', }, { label: 'HKD', value: 'HKD', }, ], filterMode: 'multiple', explanation: '提示信息', width: 110, }, { title: '完成进度', dataIndex: 'percent', formatType: 'progress', }, { title: '到账日期', dataIndex: 'date', formatType: 'date', }, ], }, }, { id: 'id-2f5DdE2b-2', date: '2013-06-12', percent: 1.862, documentAmount: 2022, currency: 'CNY', company: '支付宝科技有限公司', childTableProps: { dataSource: [], columns: [ { title: '公司', dataIndex: 'company', width: 160, formatType: 'link', searchable: true, }, { title: '单据金额', dataIndex: 'documentAmount', formatType: 'money', }, { title: '币种', dataIndex: 'currency', formatType: 'currency', filters: [ { label: 'CNY', value: 'CNY', }, { label: 'USD', value: 'USD', }, { label: 'JPY', value: 'JPY', }, { label: 'HKD', value: 'HKD', }, ], filterMode: 'multiple', explanation: '提示信息', width: 110, }, { title: '完成进度', dataIndex: 'percent', formatType: 'progress', }, { title: '到账日期', dataIndex: 'date', formatType: 'date', }, ], }, }, ], actionColumnButtons: { dataSource: [ { children: '查看', type: 'primary', }, { children: '编辑', type: 'primary', disabled: true, }, { children: '删除', type: 'primary', }, ], text: true, visibleButtonCount: 3, }, actionBarButtons: { dataSource: [ { type: 'primary', children: '操作一', }, { type: 'normal', children: '操作二', }, ], visibleButtonCount: 3, }, paginationProps: { pageSize: 20, current: 1, }, settingButtons: true, columns: [ { title: '公司', dataIndex: 'company', width: 160, formatType: 'link', searchable: true, }, { title: '单据金额', dataIndex: 'documentAmount', formatType: 'money', }, { title: '币种', dataIndex: 'currency', formatType: 'currency', filters: [ { label: 'CNY', value: 'CNY', }, { label: 'USD', value: 'USD', }, { label: 'JPY', value: 'JPY', }, { label: 'HKD', value: 'HKD', }, ], filterMode: 'multiple', explanation: '提示信息', width: 110, }, { title: '完成进度', dataIndex: 'percent', formatType: 'progress', }, { title: '到账日期', dataIndex: 'date', formatType: 'date', }, ], }; export default () => { return (
); }; ================================================ FILE: packages/fusion-ui/docs/src/Filter/index.md ================================================ ## 何时使用 Filter 的基础用法,演示自己控制数据的用法。code 试一下能不能用 ## 示例 ## API ================================================ FILE: packages/fusion-ui/docs/src/Filter/index.tsx ================================================ import React from 'react'; import { Input } from '@alifd/next'; import { Filter, ProForm } from '@alifd/fusion-ui'; const ProFormItem = ProForm.Item; export default () => { return ( ); }; ================================================ FILE: packages/fusion-ui/docs/src/GroupTable/index.md ================================================ ## 何时使用 GroupTable 的基础用法,演示自己控制数据的用法。code 试一下能不能用 ## 示例 ## API ================================================ FILE: packages/fusion-ui/docs/src/GroupTable/index.tsx ================================================ import React from 'react'; import { GroupTable } from '@alifd/fusion-ui'; const dataSource = [ { header: '头部文字', footer: '尾部文字', children: [ { company: '支付宝科技有限公司', documentAmount: 2022, currency: 'CNY', percent: 1.862, date: '2013-06-12', id: 'id-2f5DdE2b-0', }, { company: '支付宝科技有限公司', documentAmount: 2022, currency: 'CNY', percent: 1.862, date: '2013-06-12', id: 'id-2f5DdE2b-0', }, ], }, { header: '头部文字2', footer: '尾部文字2', children: [ { company: '支付宝科技有限公司', documentAmount: 2022, currency: 'CNY', percent: 1.862, date: '2013-06-12', id: 'id-2f5DdE2b-0', }, { company: '支付宝科技有限公司', documentAmount: 2022, currency: 'CNY', percent: 1.862, date: '2013-06-12', id: 'id-2f5DdE2b-0', }, { company: '支付宝科技有限公司', documentAmount: 2022, currency: 'CNY', percent: 1.862, date: '2013-06-12', id: 'id-2f5DdE2b-0', }, { company: '支付宝科技有限公司', documentAmount: 2022, currency: 'CNY', percent: 1.862, date: '2013-06-12', id: 'id-2f5DdE2b-0', }, ], }, ]; const props = { dataSource, actionColumnButtons: { dataSource: [ { children: '查看', type: 'primary', }, { children: '编辑', type: 'primary', disabled: true, }, { children: '删除', type: 'primary', }, ], text: true, visibleButtonCount: 3, }, actionBarButtons: { dataSource: [ { type: 'primary', children: '操作一', }, { type: 'normal', children: '操作二', }, ], visibleButtonCount: 3, }, paginationProps: { pageSize: 20, current: 1, }, settingButtons: true, columns: [ { title: '公司', dataIndex: 'company', width: 160, formatType: 'link', searchable: true, }, { title: '单据金额', dataIndex: 'documentAmount', formatType: 'money', }, { title: '币种', dataIndex: 'currency', formatType: 'currency', filters: [ { label: 'CNY', value: 'CNY', }, { label: 'USD', value: 'USD', }, { label: 'JPY', value: 'JPY', }, { label: 'HKD', value: 'HKD', }, ], filterMode: 'multiple', explanation: '提示信息', width: 110, }, { title: '完成进度', dataIndex: 'percent', formatType: 'progress', }, { title: '到账日期', dataIndex: 'date', formatType: 'date', }, ], }; export default () => { return (
); }; ================================================ FILE: packages/fusion-ui/docs/src/LineChart/basic.tsx ================================================ import React from 'react'; import { LineChart } from '@alifd/fusion-ui'; const props = { data: [ { year: '1991', value: 72345678 }, { year: '1992', value: 4321132 }, { year: '1993', value: 33121112.5 }, { year: '1994', value: 45227221 }, { year: '1995', value: 4321221.9 }, { year: '1996', value: 6322121 }, { year: '1997', value: 78312213 }, { year: '1998', value: 4192312 }, { year: '1999', value: 6212332 }, { year: '2000', value: 3192312 }, ], xField: 'year', yField: 'value', color: '#0079f2', label: { visible: true, }, }; export default () => { return (
); }; ================================================ FILE: packages/fusion-ui/docs/src/LineChart/index.md ================================================ ## 何时使用 LineChart 的基础用法。 ## 示例 ### 基础用法 ### 缩略轴 ## API ================================================ FILE: packages/fusion-ui/docs/src/LineChart/slider.tsx ================================================ import React from 'react'; import { LineChart } from '@alifd/fusion-ui'; const props = { data: [ { year: '1991', value: 72345678 }, { year: '1992', value: 4321132 }, { year: '1993', value: 33121112.5 }, { year: '1994', value: 45227221 }, { year: '1995', value: 4321221.9 }, { year: '1996', value: 6322121 }, { year: '1997', value: 78312213 }, { year: '1998', value: 4192312 }, { year: '1999', value: 6212332 }, { year: '2000', value: 3192312 }, ], xField: 'year', yField: 'value', color: '#0079f2', label: { visible: true, }, interactions: [ { type: 'slider', cfg: { start: 0, end: 1, }, }, ], }; export default () => { return (
); }; ================================================ FILE: packages/fusion-ui/docs/src/PageHeader/basic.tsx ================================================ import React from 'react'; import { PageHeader } from '@alifd/fusion-ui'; export default () => { return ( ); }; ================================================ FILE: packages/fusion-ui/docs/src/PageHeader/breadcrumb.tsx ================================================ import React from 'react'; import { PageHeader } from '@alifd/fusion-ui'; import { Breadcrumb } from '@alifd/next'; export default () => { return ( 1 2 3 } subTitle="This is a subtitle" /> ); }; ================================================ FILE: packages/fusion-ui/docs/src/PageHeader/index.md ================================================ ## 何时使用 PageHeader 的基础用法,演示自己控制数据的用法。code 试一下能不能用 ## 示例 ### 基础用法 ### 面包屑用法 ## API ================================================ FILE: packages/fusion-ui/docs/src/PieChart/basic.tsx ================================================ import React from 'react'; import { PieChart } from '@alifd/fusion-ui'; const props = { legend: { position: 'top-left', }, data: [ { year: '1991', value: 72345678 }, { year: '1992', value: 4321132 }, { year: '1993', value: 33121112.5 }, { year: '1994', value: 45227221 }, { year: '1995', value: 4321221.9 }, { year: '1996', value: 6322121 }, { year: '1997', value: 78312213 }, { year: '1998', value: 2192312 }, { year: '1999', value: 6212332 }, { year: '2000', value: 1192312 }, ], angleField: 'value', colorField: 'year', label: { visible: true, type: 'spider', }, color: ['#3BCBD1', '#47A4FE', '#EDBA42', '#F4704E', '#ED6899', '#7F62C3', '#6E7BC9'], }; export default () => { return (
); }; ================================================ FILE: packages/fusion-ui/docs/src/PieChart/index.md ================================================ ## 何时使用 PieChart 的基础用法。 ## 示例 ### 基础用法 ### 标签显示百分比 ## API ================================================ FILE: packages/fusion-ui/docs/src/PieChart/percent.tsx ================================================ import React from 'react'; import { PieChart } from '@alifd/fusion-ui'; const props = { legend: { position: 'top-left', }, data: [ { year: '1991', value: 72345678 }, { year: '1992', value: 4321132 }, { year: '1993', value: 33121112.5 }, { year: '1994', value: 45227221 }, { year: '1995', value: 4321221.9 }, { year: '1996', value: 6322121 }, { year: '1997', value: 78312213 }, { year: '1998', value: 2192312 }, { year: '1999', value: 6212332 }, { year: '2000', value: 1192312 }, ], angleField: 'value', colorField: 'year', color: ['#3BCBD1', '#47A4FE', '#EDBA42', '#F4704E', '#ED6899', '#7F62C3', '#6E7BC9'], }; export default () => { return (
); }; ================================================ FILE: packages/fusion-ui/docs/src/ProDialog/basic.tsx ================================================ import React from 'react'; import { ProDialog } from '@alifd/fusion-ui'; import { Button } from '@alifd/next'; export default () => { const dialogRef = React.useRef(); return (
{ console.log('ok'); }} onCancel={() => { console.log('cancel'); }} onClose={() => { console.log('close'); }} > Start your business here by searching a popular product
); }; ================================================ FILE: packages/fusion-ui/docs/src/ProDialog/index.md ================================================ ## 何时使用 ProDialog 的基础用法,演示自己控制数据的用法。code 试一下能不能用 ## 示例 ### 基本用法 ### 长文本 ## API ================================================ FILE: packages/fusion-ui/docs/src/ProDialog/large-content.tsx ================================================ import React from 'react'; import { ProDialog } from '@alifd/fusion-ui'; import { Button, Typography } from '@alifd/next'; const { H4 } = Typography; export default () => { const dialogRef = React.useRef(); const largeContent = new Array(60) .fill() .map((_, index) => (

Start your business here by searching a popular product

)); return (
{ console.log('ok'); }} onCancel={() => { console.log('cancel'); }} onClose={() => { console.log('close'); }} > {largeContent}
); }; ================================================ FILE: packages/fusion-ui/docs/src/ProDrawer/basic.tsx ================================================ import React, { useRef } from 'react'; import { ProDrawer } from '@alifd/fusion-ui'; import { Button } from '@alifd/next'; export default () => { const drawerRef = useRef(); const handleChangeVis = () => { drawerRef?.current?.show(); }; return (
{ console.log('ok'); }} onCancel={() => { console.log('cancel'); }} onClose={() => { console.log('close'); }} > Start your business here by searching a popular product
); }; ================================================ FILE: packages/fusion-ui/docs/src/ProDrawer/index.md ================================================ ## 何时使用 ProDrawer 的基础用法,演示自己控制数据的用法。code 试一下能不能用 ## 示例 ### 基本用法 ## API ================================================ FILE: packages/fusion-ui/docs/src/ProForm/basic.tsx ================================================ import React from 'react'; import { Input, Field } from '@alifd/next'; import { ProForm, FormInput } from '@alifd/fusion-ui'; const ProFormItem = ProForm.Item; export default () => { const field = Field.useField([]); const [values, setValues] = React.useState(); return (
{ const _values = field.getValues(); setValues(_values); }, }, ]} emptyContent="添加表单项" operationConfig={{ align: 'center' }} labelAlign="top" columns={3} labelCol={{ fixedSpan: 4 }} > 表单数据: {JSON.stringify(values || {}, null, 2)}
); }; ================================================ FILE: packages/fusion-ui/docs/src/ProForm/index.md ================================================ ## 何时使用 ProForm 的基础用法,演示自己控制数据的用法。code 试一下能不能用 ## 示例 ### 基本用法 ### 操作按钮用法 ## API ================================================ FILE: packages/fusion-ui/docs/src/ProForm/operations.tsx ================================================ import React from 'react'; import { Input, Button } from '@alifd/next'; import { ProForm } from '@alifd/fusion-ui'; export default () => { return (
自定义按钮, { action: 'submit', type: 'primary', content: '提交' }, ]} emptyContent="添加表单项" operationConfig={{ align: 'center' }} labelAlign="top" placeholderStyle={{ border: 0, color: '#0088FF', background: '#d8d8d836', height: '38px', gridArea: 'span 4 / span 4', }} columns={3} placeholder="请在右侧面板添加表单项+" labelCol={{ fixedSpan: 4 }} >
); }; ================================================ FILE: packages/fusion-ui/docs/src/ProTable/basic.tsx ================================================ import * as React from 'react'; import { ProTable, useProTable } from '@alifd/fusion-ui'; import { fetchPaginationList } from './service'; import { Dialog } from '@alifd/next'; const columns = [ { title: '公司', dataIndex: 'company', width: 160, }, { title: '完成进度', dataIndex: 'percent', formatType: 'percent', }, ]; const actionColumnButtons = { dataSource: [ { children: '查看' }, { children: '编辑', disabled: (payload) => payload.rowRecord.percent > 0.5, }, { children: '删除', onClick: (e, payload) => { Dialog.confirm({ title: `是否删除${payload.rowRecord.company}`, }); }, }, ], }; export default () => { const { tableProps } = useProTable(fetchPaginationList); return ; }; ================================================ FILE: packages/fusion-ui/docs/src/ProTable/index.md ================================================ ## 何时使用 ProTable 的基础用法,演示自己控制数据的用法。code试一下能不能用 ## 示例 ### 基本用法 ## API ================================================ FILE: packages/fusion-ui/docs/src/ProTable/service.ts ================================================ import qs from 'qs'; export const fetchPaginationList = async ({ current, pageSize }) => { const size = +pageSize || 10; return fetch( `https://oneapi.alibaba-inc.com/mock/whalebase/pro-table/pagination-list?${qs.stringify({ current, pageSize, })}`, ) .then((res) => res.json()) .then(({ content }) => ({ ...content, dataSource: content.dataSource .slice(0, size) .map((vo, index) => ({ ...vo, id: `id-${current * size + index}` })), })); }; ================================================ FILE: packages/fusion-ui/docs/src/StepForm/basic.tsx ================================================ import React from 'react'; import { Input } from '@alifd/next'; import { StepForm, ProForm } from '@alifd/fusion-ui'; const ProFormItem = ProForm.Item; const props = { current: 0, operations: [ { content: '上一步', action: 'previous', type: 'secondary', }, { content: '下一步', action: 'next', type: 'primary', }, ], }; export default () => { return (
); }; ================================================ FILE: packages/fusion-ui/docs/src/StepForm/index.md ================================================ ## 何时使用 StepForm 的基础用法,演示自己控制数据的用法。code 试一下能不能用 ## 示例 ### 基本用法 ## API ================================================ FILE: packages/fusion-ui/docs/src/TabContainer/basic.tsx ================================================ import React from 'react'; import { TabContainer } from '@alifd/fusion-ui'; const props = { shape: 'pure', size: 'medium', excessMode: 'slide', }; export default () => { return (
内容1 内容2 内容3
); }; ================================================ FILE: packages/fusion-ui/docs/src/TabContainer/index.md ================================================ ## 何时使用 TabContainer 的基础用法,演示自己控制数据的用法。code试一下能不能用 ## 示例 ### 基本用法 ## API ================================================ FILE: packages/fusion-ui/docs/src/anchorForm/index.md ================================================ ## 何时使用 适合表单场景。 ## 示例 ```tsx import React from 'react'; import { AnchorForm, ChildForm, FormInput, TabContainer } from '@alifd/fusion-ui'; const anchorFormProps = { showAnchor: true, enableRandomHtmlId: true, anchorProps: { direction: 'hoz', hasAffix: true, }, operationConfig: { align: 'center', }, operations: [ { content: '提交', action: 'submit', type: 'secondary', }, { content: '重置', action: 'reset', type: 'secondary', }, ], }; const childFormProps = [1, 2, 3, 4, 5, 6, 7, 8].map((item) => ({ columns: 2, mode: 'independent', anchorItemProps: { label: `Tab-${item}`, }, cardSectionProps: { noBullet: true, tagGroup: [ { label: '操作', color: 'orange', }, { label: '操作', color: 'green', }, { label: '操作', color: 'blue', }, ], }, })); const formInputProps = { formItemProps: { label: '表单项', size: 'medium', device: 'desktop', fullWidth: true, }, placeholder: '请输入', }; export default () => { return (
basic demo
); }; ``` ## API ================================================ FILE: packages/fusion-ui/docs/src/areaChart/index.md ================================================ ## 何时使用 区域图表。 ## 示例 ```tsx import React from 'react'; import { AreaChart } from '@alifd/fusion-ui'; const props = { data: [ { year: '1991', value: 72345678 }, { year: '1992', value: 4321132 }, { year: '1993', value: 33121112.5 }, { year: '1994', value: 45227221 }, { year: '1995', value: 4321221.9 }, { year: '1996', value: 6322121 }, { year: '1997', value: 78312213 }, { year: '1998', value: 4192312 }, { year: '1999', value: 6212332 }, { year: '2000', value: 3192312 }, ], xField: 'year', yField: 'value', color: '#0079f2', label: { visible: true, }, }; export default () => { return ; }; ``` ## API ================================================ FILE: packages/fusion-ui/docs/src/childForm/index.md ================================================ ## 何时使用 适合表单场景。 ## 示例 ```tsx import React from 'react'; import { Input } from '@alifd/next'; import { ChildForm, ProForm } from '@alifd/fusion-ui'; const ProFormItem = ProForm.Item; export default () => { return ( ); }; ``` ## API ================================================ FILE: packages/fusion-ui/f2elint.config.js ================================================ module.exports = { enableStylelint: true, enableMarkdownlint: true, enablePrettier: true, }; ================================================ FILE: packages/fusion-ui/jest.config.js ================================================ module.exports = { setupFilesAfterEnv: ['/test/setupTests.js'], }; ================================================ FILE: packages/fusion-ui/lowcode/anchor/meta.ts ================================================ import { hideProp } from '../utils'; const meta = { components: [ { componentName: 'Anchor', group: '精选组件', title: '电梯容器', category: '布局容器类', docUrl: '', screenshot: 'https://img.alicdn.com/imgextra/i3/O1CN01aDpmze26zlTZVDhtR_!!6000000007733-2-tps-112-112.png', devMode: 'proCode', npm: { package: '@alifd/fusion-ui', version: '1.0.24-5', exportName: 'Anchor', main: 'lib/index.js', destructuring: true, subName: '', }, configure: { props: [ { title: { label: { type: 'i18n', 'en-US': 'dataSource', 'zh-CN': '锚点列表数据源' }, tip: 'dataSource | 锚点列表数据源', }, name: 'dataSource', description: '锚点列表数据源', setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { title: { label: { type: 'i18n', 'en-US': 'htmlId', 'zh-CN': 'htmlId' } }, name: 'htmlId', setter: { componentName: 'StringSetter', isRequired: true, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'label', 'zh-CN': 'label' } }, name: 'label', setter: { componentName: 'StringSetter', isRequired: true, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'children', 'zh-CN': 'children' }, }, name: 'children', setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: {}, isRequired: false, initialValue: {}, }, }, initialValue: [], }, }, ], }, }, }, }, isRequired: true, initialValue: [], }, }, { title: { label: { type: 'i18n', 'en-US': 'container', 'zh-CN': '容器,默认是 win' }, tip: 'container | 容器,默认是 window', }, condition: hideProp, name: 'container', setter: { componentName: 'FunctionSetter', isRequired: false }, }, { title: { label: { type: 'i18n', 'en-US': 'direction', 'zh-CN': '锚点方向' }, tip: 'direction | 锚点方向', }, name: 'direction', defaultValue: 'ver', setter: { componentName: 'RadioGroupSetter', props: { dataSource: [ { label: 'ver', value: 'ver' }, { label: 'hoz', value: 'hoz' }, ], options: [ { label: 'ver', value: 'ver' }, { label: 'hoz', value: 'hoz' }, ], }, initialValue: 'ver', }, }, { title: { label: { type: 'i18n', 'en-US': 'hasAffix', 'zh-CN': '固定在顶部' }, tip: 'hasAffix | direction="hoz" 生效', }, condition: (target) => { return target.getProps().getPropValue('direction') === 'hoz'; }, name: 'hasAffix', setter: { componentName: 'BoolSetter', isRequired: false, initialValue: false }, }, { title: { label: { type: 'i18n', 'en-US': 'affixProps', 'zh-CN': '固钉配置' }, tip: 'affixProps | hasAffix={true} 后使用', }, condition: (target) => { const hasAffix = target.getProps().getPropValue('hasAffix'); return typeof hasAffix === 'boolean' && hasAffix; }, name: 'affixProps', setter: { componentName: 'ObjectSetter', props: { config: { items: [ { title: { label: { type: 'i18n', 'en-US': 'container', 'zh-CN': 'container' }, }, name: 'container', setter: { componentName: 'FunctionSetter', isRequired: false }, }, { title: { label: { type: 'i18n', 'en-US': 'offsetTop', 'zh-CN': 'offsetTop' }, }, name: 'offsetTop', setter: { componentName: 'NumberSetter', isRequired: false, initialValue: 0 }, }, { title: { label: { type: 'i18n', 'en-US': 'offsetBottom', 'zh-CN': 'offsetBottom' }, }, name: 'offsetBottom', setter: { componentName: 'NumberSetter', isRequired: false, initialValue: 0 }, }, { title: { label: { type: 'i18n', 'en-US': 'onAffix', 'zh-CN': 'onAffix' } }, name: 'onAffix', setter: { componentName: 'FunctionSetter' }, }, { title: { label: { type: 'i18n', 'en-US': 'useAbsolute', 'zh-CN': 'useAbsolute' }, }, name: 'useAbsolute', setter: { componentName: 'BoolSetter', isRequired: false, initialValue: false, }, }, ], }, }, }, }, ], supports: { className: true, style: true }, component: {}, }, }, ], }; export default meta; ================================================ FILE: packages/fusion-ui/lowcode/anchor-form/meta.ts ================================================ import { IComponentDescription } from '../types'; import { hideProp, mockId } from '../utils'; import { operationProps } from '../common'; const AnchorFormMeta: IComponentDescription = { componentName: 'AnchorForm', title: '电梯表单', category: '表单类', group: '精选组件', docUrl: '', screenshot: 'https://img.alicdn.com/imgextra/i1/O1CN01jnfLpK1rFJ4nPj9Pt_!!6000000005601-55-tps-56-56.svg', devMode: 'proCode', npm: { package: '@alifd/fusion-ui', version: '0.1.6-beta.22', exportName: 'AnchorForm', main: 'lib/index.js', destructuring: true, subName: '', }, configure: { supports: { className: true, style: true, events: ['onChange'] }, component: { isContainer: true, isMinimalRenderUnit: true, nestingRule: { childWhitelist: ['ChildForm'], }, }, props: [ { name: 'anchorConfig', title: '电梯设置', type: 'group', display: 'accordion', items: [ { name: 'showAnchor', title: '电梯显示', defaultValue: true, setter: 'BoolSetter', }, { title: { label: { type: 'i18n', 'en-US': 'direction', 'zh-CN': '锚点方向' }, tip: 'direction | 锚点方向', }, name: 'anchorProps.direction', condition: (target) => { const showAnchor = target.getProps().getPropValue('showAnchor'); return typeof showAnchor === 'undefined' || showAnchor; }, defaultValue: 'ver', setter: { componentName: 'RadioGroupSetter', props: { dataSource: [ { label: '垂直', value: 'ver' }, { label: '水平', value: 'hoz' }, ], options: [ { label: '垂直', value: 'ver' }, { label: '水平', value: 'hoz' }, ], }, initialValue: 'ver', }, }, { title: { label: { type: 'i18n', 'en-US': 'hasAffix', 'zh-CN': '固定在顶部' }, tip: 'hasAffix | direction="hoz" 生效', }, condition: (target) => { const showAnchor = target.getProps().getPropValue('showAnchor'); return ( showAnchor && target.getProps().getPropValue('anchorProps.direction') === 'hoz' ); }, name: 'anchorProps.hasAffix', setter: { componentName: 'BoolSetter', isRequired: false, initialValue: false }, }, ], }, { title: { label: { type: 'i18n', 'en-US': 'container', 'zh-CN': '容器,默认是 win' }, tip: 'container | 容器,默认是 window', }, condition: hideProp, name: 'container', setter: { componentName: 'FunctionSetter', isRequired: false }, }, { title: { label: { type: 'i18n', 'en-US': 'affixProps', 'zh-CN': '固钉配置' }, tip: 'affixProps | hasAffix={true} 后使用', }, condition: (target) => { const hasAffix = target.getProps().getPropValue('hasAffix'); return typeof hasAffix === 'boolean' && hasAffix; }, name: 'affixProps', setter: { componentName: 'ObjectSetter', props: { config: { items: [ { title: { label: { type: 'i18n', 'en-US': 'container', 'zh-CN': 'container' } }, name: 'container', setter: { componentName: 'FunctionSetter', isRequired: false }, }, { title: { label: { type: 'i18n', 'en-US': 'offsetTop', 'zh-CN': 'offsetTop' } }, name: 'offsetTop', setter: { componentName: 'NumberSetter', isRequired: false, initialValue: 0 }, }, { title: { label: { type: 'i18n', 'en-US': 'offsetBottom', 'zh-CN': 'offsetBottom' }, }, name: 'offsetBottom', setter: { componentName: 'NumberSetter', isRequired: false, initialValue: 0 }, }, { title: { label: { type: 'i18n', 'en-US': 'onAffix', 'zh-CN': 'onAffix' } }, name: 'onAffix', setter: { componentName: 'FunctionSetter' }, }, { title: { label: { type: 'i18n', 'en-US': 'useAbsolute', 'zh-CN': 'useAbsolute' }, }, name: 'useAbsolute', setter: { componentName: 'BoolSetter', isRequired: false, initialValue: false }, }, ], }, }, }, }, ...operationProps, { title: { label: { type: 'i18n', 'en-US': 'onChange', 'zh-CN': '点击不同锚点时的自定' }, tip: 'onChange | 点击不同锚点时的自定义触发函数', }, condition: hideProp, name: 'onChange', setter: { componentName: 'FunctionSetter' }, }, { title: { label: { type: 'i18n', 'en-US': 'offsetY', 'zh-CN': '垂直跳转偏移量' }, tip: 'offsetY | 垂直跳转偏移量', }, condition: hideProp, name: 'offsetY', defaultValue: 0, setter: { componentName: 'NumberSetter', isRequired: false, initialValue: 0 }, }, { title: { label: { type: 'i18n', 'en-US': 'scrollTop', 'zh-CN': '自定义滚动到页首的方' }, tip: 'scrollTop | 自定义滚动到页首的方法', }, condition: hideProp, name: 'scrollTop', setter: { componentName: 'FunctionSetter', isRequired: false }, }, ], }, }; const snippets: Snippet[] = [ { title: '电梯表单', screenshot: 'https://img.alicdn.com/imgextra/i1/O1CN01jnfLpK1rFJ4nPj9Pt_!!6000000005601-55-tps-56-56.svg', schema: { componentName: 'AnchorForm', props: { showAnchor: true, anchorProps: { direction: 'hoz', }, }, children: [ { componentName: 'ChildForm', props: { columns: 2, mode: 'independent', anchorItemProps: { htmlId: mockId(), label: 'Tab1', }, cardSectionProps: { noBullet: true, }, operationConfig: {}, labelCol: { fixedSpan: 4, }, labelAlign: 'top', }, children: [...new Array(4).keys()].map(() => ({ componentName: 'FormInput', props: { formItemProps: { primaryKey: mockId(), label: '表单项', size: 'medium', device: 'desktop', fullWidth: true, }, placeholder: '请输入', }, })), }, { componentName: 'ChildForm', props: { mode: 'independent', anchorItemProps: { htmlId: mockId(), label: 'Tab2', }, cardSectionProps: { noBullet: true, }, columns: 2, operationConfig: {}, labelCol: { fixedSpan: 4, }, labelAlign: 'top', }, children: [...new Array(4).keys()].map(() => ({ componentName: 'FormInput', props: { formItemProps: { primaryKey: mockId(), label: '表单项', size: 'medium', device: 'desktop', fullWidth: true, }, placeholder: '请输入', }, })), }, { componentName: 'ChildForm', props: { mode: 'independent', anchorItemProps: { htmlId: mockId(), label: 'Tab3', }, cardSectionProps: { noBullet: true, }, columns: 2, operationConfig: {}, labelCol: { fixedSpan: 4, }, labelAlign: 'top', }, children: [...new Array(4).keys()].map(() => ({ componentName: 'FormInput', props: { formItemProps: { primaryKey: mockId(), label: '表单项', size: 'medium', device: 'desktop', fullWidth: true, }, placeholder: '请输入', }, })), }, { componentName: 'ChildForm', props: { mode: 'independent', anchorItemProps: { htmlId: mockId(), label: 'Tab4', }, cardSectionProps: { noBullet: true, }, columns: 2, operationConfig: {}, labelCol: { fixedSpan: 4, }, labelAlign: 'top', }, children: [...new Array(4).keys()].map(() => ({ componentName: 'FormInput', props: { formItemProps: { primaryKey: mockId(), label: '表单项', size: 'medium', device: 'desktop', fullWidth: true, }, placeholder: '请输入', }, })), }, ], }, }, ]; export default { ...AnchorFormMeta, snippets, }; ================================================ FILE: packages/fusion-ui/lowcode/area-chart/meta.ts ================================================ import { IPublicTypeComponentMetadata, IPublicTypeSnippet } from '@alilc/lowcode-types'; import { actionConfigure } from '../common/chart-action'; import { plotConfigure } from '../common/chart-plot'; const AreaChartMeta: IPublicTypeComponentMetadata = { componentName: 'AreaChart', title: '面积图', category: '图表', group: '精选组件', docUrl: '', screenshot: '', devMode: 'proCode', npm: { package: '@alifd/fusion-ui', version: '0.1.3-beta.3', exportName: 'AreaChart', main: 'lib/index.js', destructuring: true, subName: '', }, configure: { props: [ // 数据 { name: 'data', type: 'group', display: 'accordion', title: { label: '数据', }, items: [ { name: 'data', title: '图表数据', setter: 'JsonSetter', }, { name: 'xField', title: { label: 'x轴字段名', tip: 'x 方向映射对应的数据字段名', }, setter: 'StringSetter', }, { name: 'yField', title: { label: 'y轴字段名', tip: 'y 方向映射所对应的数据字段名', }, setter: 'StringSetter', }, ], }, // 图形属性 { name: '', type: 'group', display: 'accordion', title: { label: '图形属性', }, items: [ { name: 'color', title: '颜色', setter: 'ColorSetter', }, { name: 'line.size', title: '粗细', setter: 'NumberSetter', }, { name: 'smooth', title: '平滑', setter: 'BoolSetter', }, { name: 'point.visible', title: '显示点', setter: 'BoolSetter', }, { name: 'label.visible', title: '显示标签', setter: 'BoolSetter', }, ], }, ...plotConfigure, ...actionConfigure, ], }, }; const snippets: IPublicTypeSnippet[] = [ { title: '面积图', screenshot: 'https://img.alicdn.com/imgextra/i2/O1CN012P76ko1dqUbwwmuF8_!!6000000003787-55-tps-56-56.svg', schema: { componentName: 'AreaChart', props: { data: [ { year: '1991', value: 72345678 }, { year: '1992', value: 4321132 }, { year: '1993', value: 33121112.5 }, { year: '1994', value: 45227221 }, { year: '1995', value: 4321221.9 }, { year: '1996', value: 6322121 }, { year: '1997', value: 78312213 }, { year: '1998', value: 4192312 }, { year: '1999', value: 6212332 }, { year: '2000', value: 3192312 }, ], xField: 'year', yField: 'value', color: '#0079f2', label: { visible: true, }, }, }, }, ]; export default { ...AreaChartMeta, snippets, }; ================================================ FILE: packages/fusion-ui/lowcode/bar-chart/meta.ts ================================================ import { IPublicTypeComponentMetadata, IPublicTypeSnippet } from '@alilc/lowcode-types'; import { actionConfigure } from '../common/chart-action'; import { plotConfigure } from '../common/chart-plot'; const BarChartMeta: IPublicTypeComponentMetadata = { componentName: 'BarChart', title: '条形图', category: '图表', group: '精选组件', docUrl: '', screenshot: '', devMode: 'proCode', npm: { package: '@alifd/fusion-ui', version: '0.1.3-beta.3', exportName: 'BarChart', main: 'lib/index.js', destructuring: true, subName: '', }, configure: { props: [ // 数据 { name: 'data', type: 'group', display: 'accordion', title: { label: '数据', }, items: [ { name: 'data', title: '图表数据', setter: 'JsonSetter', }, { name: 'xField', title: { label: 'x轴字段名', tip: 'x 方向映射对应的数据字段名', }, setter: 'StringSetter', }, { name: 'yField', title: { label: 'y轴字段名', tip: 'y 方向映射所对应的数据字段名', }, setter: 'StringSetter', }, ], }, // 图形属性 { name: '', type: 'group', display: 'accordion', title: { label: '图形属性', }, items: [ { name: 'color', title: '颜色', setter: 'ColorSetter', }, { name: 'barSize', title: '粗细', setter: 'NumberSetter', }, { name: 'label', type: 'group', display: 'accordion', title: { label: '标签', }, items: [ { name: 'label.visible', title: '显示', setter: 'BoolSetter', }, { name: 'label.position', title: '位置', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '左', value: 'left' }, { title: '中', value: 'middle' }, { title: '右', value: 'right' }, ], }, }, condition: (target) => { return !!target.getProps().getPropValue('label.visible'); }, }, ], }, ], }, ...plotConfigure, ...actionConfigure, ], }, }; const snippets: IPublicTypeSnippet[] = [ { title: '条形图', screenshot: 'https://img.alicdn.com/imgextra/i3/O1CN01cOF2841sYpZkxzCsv_!!6000000005779-55-tps-56-56.svg', schema: { componentName: 'BarChart', props: { data: [ { year: '1991', value: 72345678 }, { year: '1992', value: 4321132 }, { year: '1993', value: 33121112.5 }, { year: '1994', value: 45227221 }, { year: '1995', value: 4321221.9 }, { year: '1996', value: 6322121 }, { year: '1997', value: 78312213 }, { year: '1998', value: 4192312 }, { year: '1999', value: 6212332 }, { year: '2000', value: 3192312 }, ], xField: 'value', yField: 'year', color: '#0079f2', label: { visible: true, position: 'middle', }, }, }, }, ]; export default { ...BarChartMeta, snippets }; ================================================ FILE: packages/fusion-ui/lowcode/cascader-select/meta.js ================================================ import { wrapFormItemProps } from '../utils/form-utils'; export default { componentName: 'FormCascaderSelect', isFormItemComponent: true, title: '级联选择器', docUrl: '', screenshot: '', npm: { package: '@alifd/fusion-ui', version: '{{version}}', exportName: 'FormCascaderSelect', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'label', title: { label: 'label', tip: '自定义内联 label', }, propType: 'string', description: '自定义内联 label', }, { name: 'className', propType: 'string', }, { name: 'size', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '大小', defaultValue: 'medium', }, { name: 'placeholder', propType: 'string', description: '占位符', }, { name: 'dataSource', propType: { type: 'arrayOf', value: 'object', }, }, { name: 'disabled', propType: 'bool', description: '是否禁用', defaultValue: false, }, { name: 'hasArrow', propType: 'bool', description: '下拉箭头', defaultValue: true, }, { name: 'hasBorder', propType: 'bool', description: '边框', defaultValue: true, }, { name: 'hasClear', propType: 'bool', description: '清除按钮', defaultValue: false, }, { name: 'notFoundContent', title: { label: '无数据时显示内容', tip: 'notFoundContent', }, propType: { type: 'oneOfType', value: ['node', 'string'], }, description: '无数据时显示内容', defaultValue: 'Not Found', }, { name: 'loadData', propType: 'func', description: '异步加载数据函数\n@param {Object} data 当前点击异步加载的数据', }, { name: 'header', propType: 'node', description: '自定义下拉框头部', }, { name: 'footer', propType: 'node', description: '自定义下拉框底部', }, { name: 'defaultVisible', title: { label: '初始下拉框是否显示', tip: 'defaultVisible', }, propType: 'bool', description: '初始下拉框是否显示', defaultValue: false, }, { name: 'visible', title: { label: '当前下拉框是否显示', tip: 'visible', }, propType: 'bool', description: '当前下拉框是否显示', }, { name: 'readOnly', propType: 'bool', description: '是否只读', }, { name: 'onChange', propType: 'func', description: '选中值改变时触发的回调函数\n@param {String|Array} value 选中的值,单选时返回单个值,多选时返回数组\n@param {Object|Array} data 选中的数据,包括 value 和 label,单选时返回单个值,多选时返回数组,父子节点选中关联时,同时选中,只返回父节点\n@param {Object} extra 额外参数\n@param {Array} extra.selectedPath 单选时选中的数据的路径\n@param {Boolean} extra.checked 多选时当前的操作是选中还是取消选中\n@param {Object} extra.currentData 多选时当前操作的数据\n@param {Array} extra.checkedData 多选时所有被选中的数据\n@param {Array} extra.indeterminateData 多选时半选的数据', }, { name: 'expandTriggerType', propType: { type: 'oneOf', value: ['click', 'hover'], }, description: '展开触发方式', defaultValue: 'click', }, { name: 'onExpand', propType: 'func', }, { name: 'useVirtual', propType: 'bool', description: '虚拟滚动', defaultValue: false, }, { name: 'multiple', propType: 'bool', description: '是否多选', defaultValue: false, }, { name: 'changeOnSelect', title: { label: '选中即改变', tip: 'changeOnSelect|是否选中即发生改变, 该属性仅在单选模式下有效', }, propType: 'bool', description: '是否选中即发生改变, 该属性仅在单选模式下有效', defaultValue: false, }, { name: 'canOnlyCheckLeaf', title: { label: 'canOnlyCheckLeaf', tip: '是否只能勾选叶子项的checkbox,该属性仅在多选模式下有效', }, propType: 'bool', description: '是否只能勾选叶子项的checkbox,该属性仅在多选模式下有效', defaultValue: false, }, { name: 'checkStrictly', title: { label: 'checkStrictly', tip: '父子节点是否选中不关联', }, propType: 'bool', description: '父子节点是否选中不关联', defaultValue: false, }, { name: 'listStyle', propType: 'object', description: '每列列表样式对象', }, { name: 'resultAutoWidth', title: { label: 'resultAutoWidth', tip: '搜索结果列表是否和选择框等宽', }, propType: 'bool', description: '搜索结果列表是否和选择框等宽', defaultValue: true, }, { name: 'showSearch', propType: 'bool', description: '搜索框', defaultValue: false, }, { name: 'filter', propType: 'func', description: '自定义搜索函数\n@param {String} searchValue 搜索的关键字\n@param {Array} path 节点路径\n@return {Boolean} 是否匹配\n@default 根据路径所有节点的文本值模糊匹配', }, { name: 'onVisibleChange', propType: 'func', description: '下拉框显示或关闭时触发事件的回调函数\n@param {Boolean} visible 是否显示\n@param {String} type 触发显示关闭的操作类型, fromTrigger 表示由trigger的点击触发; docClick 表示由document的点击触发', }, { name: 'popupStyle', propType: 'object', description: '下拉框自定义样式对象', }, { name: 'popupProps', propType: 'object', description: '透传到 Popup 的属性对象', }, { name: 'followTrigger', title: { label: '是否跟随滚动', tip: 'followTrigger', }, propType: 'bool', description: '是否跟随滚动', }, { name: 'isPreview', title: { label: '是否为预览态', tip: 'isPreview', }, propType: 'bool', description: '是否为预览态', }, { name: 'style', propType: 'object', }, { name: 'popupContainer', propType: 'any', description: '弹层容器\n@param {Element} target 目标元素\n@return {Element} 弹层的容器元素', }, ], configure: { supports: { style: true, events: ['onChange', 'onExpand', 'onVisibleChange'], }, props: wrapFormItemProps([ { name: 'label', title: { label: '内联文案', tip: '自定义内联 label', }, setter: 'StringSetter', }, { name: 'size', title: '尺寸', setter: { componentName: 'RadioGroupSetter', props: { options: ['small', 'medium', 'large'] }, }, defaultValue: 'medium', }, { name: 'placeholder', title: '占位提示', setter: 'StringSetter', }, { name: 'dataSource', title: '级联数据', setter: 'JsonSetter', }, { name: 'disabled', setter: 'BoolSetter', title: '是否禁用', defaultValue: false, }, { name: 'hasArrow', setter: 'BoolSetter', title: '下拉箭头', defaultValue: true, }, { name: 'hasBorder', setter: 'BoolSetter', title: '边框', defaultValue: true, }, { name: 'hasClear', setter: 'BoolSetter', title: '清除按钮', defaultValue: false, }, { name: 'readOnly', setter: 'BoolSetter', title: '是否只读', }, { name: 'multiple', setter: 'BoolSetter', title: '是否多选', defaultValue: false, }, { name: 'showSearch', setter: 'BoolSetter', title: '搜索框', defaultValue: false, }, { name: 'followTrigger', title: { label: '跟随滚动', tip: 'followTrigger', }, setter: 'BoolSetter', description: '是否跟随滚动', }, { name: 'isPreview', title: { label: '预览态', tip: 'isPreview', }, setter: 'BoolSetter', description: '是否为预览态', }, { name: 'expandTriggerType', display: 'block', setter: { componentName: 'RadioGroupSetter', props: { options: ['click', 'hover'] }, }, title: '展开触发方式', defaultValue: 'click', }, { name: 'notFoundContent', display: 'block', title: { label: '无数据时显示内容', tip: 'notFoundContent', }, setter: { componentName: 'MixedSetter', props: { setters: ['StringSetter', 'SlotSetter'], }, }, defaultValue: 'Not Found', }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', }, ], }, ]), }, icon: '', category: '内容', }; ================================================ FILE: packages/fusion-ui/lowcode/cascader-select/snippets.js ================================================ module.exports = [ { title: '收起模式', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_cascader-select.png', schema: { componentName: 'CascaderSelect', props: { prefix: 'next-', size: 'medium', hasArrow: true, hasBorder: true, expandTriggerType: 'click', resultAutoWidth: true, notFoundContent: 'Not Found', dataSource: [ { value: '2974', label: '西安', children: [ { value: '2975', label: '西安市', }, { value: '2976', label: '高陵县', }, { value: '2977', label: '蓝田县', }, ], }, ], }, }, }, { title: '展开模式', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_cascader.png', schema: { componentName: 'Cascader', props: { prefix: 'next-', expandTriggerType: 'click', dataSource: [ { value: '2974', label: '西安', children: [ { value: '2975', label: '西安市', }, { value: '2976', label: '高陵县', }, { value: '2977', label: '蓝田县', }, ], }, ], }, }, }, ]; ================================================ FILE: packages/fusion-ui/lowcode/checkbox-group/meta.js ================================================ import { wrapFormItemProps } from '../utils/form-utils'; export default { componentName: 'FormCheckboxGroup', isFormItemComponent: true, title: '复选按钮组', docUrl: '', screenshot: '', npm: { package: '@alifd/fusion-ui', version: '{{version}}', exportName: 'FormCheckboxGroup', main: '', destructuring: true, subName: '', }, configure: { props: wrapFormItemProps([ { name: 'disabled', title: '是否禁用', setter: { componentName: 'MixedSetter', props: { setters: ['BoolSetter', 'ExpressionSetter'], }, }, }, { name: 'itemDirection', title: '排列方式', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '水平排列', value: 'hoz' }, { title: '垂直排列', value: 'ver' }, ], }, }, defaultValue: 'hoz', }, { name: 'isPreview', title: '预览态', setter: { componentName: 'BoolSetter', }, }, { name: 'defaultValue', title: '默认值', defaultValue: '[]', setter: { componentName: 'MixedSetter', props: { setters: ['JsonSetter', 'ExpressionSetter'], }, }, }, { name: 'dataSource', display: 'block', title: '选项', setter: { componentName: 'MixedSetter', props: { setters: [ { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'label', title: 'label', setter: 'StringSetter', }, { name: 'value', title: 'value', setter: 'StringSetter', }, ], }, }, initialValue: { label: '选项一', value: '1', }, }, }, }, 'ExpressionSetter', ], }, }, }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', }, ], }, // { // name: "renderPreview", // title: "预览态模式下渲染的内容", // display: "block", // setter: { // componentName: "FunctionSetter" // }, // condition(target) { // return target.getProps().getPropValue("isPreview") || false; // } // } ]), supports: { style: true, events: ['onChange'], }, advanced: { initials: [ { name: 'dataSource', initial: () => { return [ { label: '选项一', value: '1', }, { label: '选项二', value: '2', }, { label: '选项三', value: '3', }, ]; }, }, ], }, }, icon: '', category: '内容', }; ================================================ FILE: packages/fusion-ui/lowcode/child-form/meta.ts ================================================ import { ComponentMetadata, Snippet } from '@ali/lowcode-types'; import { default as formBaseProps } from '../pro-form/common/form-base-props'; const ChildFormMeta: ComponentMetadata = { componentName: 'ChildForm', title: '子表单', docUrl: '', screenshot: '', category: '表单类', group: '精选组件', devMode: 'proCode', hidden: true, npm: { package: '@alifd/fusion-ui', version: '0.1.6-beta.24', exportName: 'ChildForm', main: 'lib/index.js', destructuring: true, subName: '', }, configure: { props: formBaseProps, supports: { className: true, style: true, }, component: { isContainer: true, isMinimalRenderUnit: true, nestingRule: { childWhitelist: new RegExp('form.*', 'i'), }, }, }, }; const snippets: Snippet[] = [ { title: '子表单', screenshot: 'https://img.alicdn.com/imgextra/i1/O1CN01MJT0lc1pXVaHIcoBy_!!6000000005370-55-tps-56-56.svg', schema: { componentName: 'ChildForm', props: { primaryKey: String(Math.floor(Math.random() * 10000)), placeholder: '请在右侧面板添加表单项+', placeholderStyle: { height: '38px', color: '#0088FF', background: '#d8d8d836', border: 0, gridArea: 'span 4 / span 4', }, columns: 3, labelCol: { fixedSpan: 4, }, labelAlign: 'top', emptyContent: '添加表单项', }, children: [...new Array(3).keys()].map((item) => ({ componentName: 'FormInput', props: { formItemProps: { primaryKey: String(Math.floor(Math.random() * 10000) + item), label: '表单项', size: 'medium', device: 'desktop', fullWidth: true, }, placeholder: '请输入', }, })), }, }, ]; export default { ...ChildFormMeta, snippets, }; ================================================ FILE: packages/fusion-ui/lowcode/column-chart/meta.ts ================================================ import { IPublicTypeComponentMetadata, IPublicTypeSnippet } from '@alilc/lowcode-types'; import { actionConfigure } from '../common/chart-action'; import { plotConfigure } from '../common/chart-plot'; const ColumnChartMeta: IPublicTypeComponentMetadata = { componentName: 'ColumnChart', title: '柱状图', category: '图表', group: '精选组件', docUrl: '', screenshot: '', devMode: 'proCode', npm: { package: '@alifd/fusion-ui', version: '0.1.3-beta.3', exportName: 'ColumnChart', main: 'lib/index.js', destructuring: true, subName: '', }, configure: { props: [ // 数据 { name: 'data', type: 'group', display: 'accordion', title: { label: '数据', }, items: [ { name: 'data', title: '图表数据', setter: 'JsonSetter', }, { name: 'xField', title: { label: 'x轴字段名', tip: 'x 方向映射对应的数据字段名', }, setter: 'StringSetter', }, { name: 'yField', title: { label: 'y轴字段名', tip: 'y 方向映射所对应的数据字段名', }, setter: 'StringSetter', }, ], }, // 图形属性 { name: '', type: 'group', display: 'accordion', title: { label: '图形属性', }, items: [ { name: 'color', title: '颜色', setter: 'ColorSetter', }, { name: 'columnSize', title: '粗细', setter: 'NumberSetter', }, { name: 'label', type: 'group', display: 'accordion', title: { label: '标签', }, items: [ { name: 'label.visible', title: '显示', setter: 'BoolSetter', }, { name: 'label.position', title: '位置', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '上', value: 'top' }, { title: '中', value: 'middle' }, { title: '下', value: 'bottom' }, ], }, }, condition: (target) => { return !!target.getProps().getPropValue('label.visible'); }, }, ], }, ], }, ...plotConfigure, ...actionConfigure, ], }, }; const snippets: IPublicTypeSnippet[] = [ { title: '柱状图', screenshot: 'https://img.alicdn.com/imgextra/i1/O1CN01mz7siK1JIn9XZmCF6_!!6000000001006-55-tps-56-56.svg', schema: { componentName: 'ColumnChart', props: { data: [ { year: '1991', value: 72345678 }, { year: '1992', value: 4321132 }, { year: '1993', value: 33121112.5 }, { year: '1994', value: 45227221 }, { year: '1995', value: 4321221.9 }, { year: '1996', value: 6322121 }, { year: '1997', value: 78312213 }, { year: '1998', value: 4192312 }, { year: '1999', value: 6212332 }, { year: '2000', value: 3192312 }, ], xField: 'year', yField: 'value', color: '#0079f2', label: { visible: true, position: 'middle', }, // data: [ // { // name: 'London', // 月份: 'Jan.', // 月均降雨量: 18.9, // }, // { // name: 'London', // 月份: 'Feb.', // 月均降雨量: 28.8, // }, // { // name: 'London', // 月份: 'Mar.', // 月均降雨量: 39.3, // }, // { // name: 'London', // 月份: 'Apr.', // 月均降雨量: 81.4, // }, // { // name: 'London', // 月份: 'May', // 月均降雨量: 47, // }, // { // name: 'London', // 月份: 'Jun.', // 月均降雨量: 20.3, // }, // { // name: 'London', // 月份: 'Jul.', // 月均降雨量: 24, // }, // { // name: 'London', // 月份: 'Aug.', // 月均降雨量: 35.6, // }, // { // name: 'Berlin', // 月份: 'Jan.', // 月均降雨量: 12.4, // }, // { // name: 'Berlin', // 月份: 'Feb.', // 月均降雨量: 23.2, // }, // { // name: 'Berlin', // 月份: 'Mar.', // 月均降雨量: 34.5, // }, // { // name: 'Berlin', // 月份: 'Apr.', // 月均降雨量: 99.7, // }, // { // name: 'Berlin', // 月份: 'May', // 月均降雨量: 52.6, // }, // { // name: 'Berlin', // 月份: 'Jun.', // 月均降雨量: 35.5, // }, // { // name: 'Berlin', // 月份: 'Jul.', // 月均降雨量: 37.4, // }, // { // name: 'Berlin', // 月份: 'Aug.', // 月均降雨量: 42.4, // }, // ], // xField: '月份', // yField: '月均降雨量', // seriesField: 'name', // legend: { // position: 'top-left', // } }, }, }, ]; export default { ...ColumnChartMeta, snippets, }; ================================================ FILE: packages/fusion-ui/lowcode/common/actions.ts ================================================ export const commonActions = [ { name: 'actionType', title: '操作类型', display: 'inline', editable: true, initialValue: 'link', setter: { componentName: 'SelectSetter', props: { options: [ { value: 'formDialog', title: '打开表单弹窗', }, { value: 'link', title: '链接', }, ], }, }, }, { name: 'text', title: '标题', editable: true, initialValue: '详情', display: 'inline', setter: { componentName: 'TextSetter', }, }, { name: 'key', title: '标识', display: 'none', initialValue: (currentValue, defaultValue) => { return currentValue || defaultValue || `data-${Math.random().toString(36).substr(-6)}`; }, setter: { componentName: 'TextSetter', }, }, { name: '_redirect_url', title: '跳转页面', display: 'inline', accessor() { const _redirect = this.parent.getParam('_redirect').getValue() || {}; return _redirect.url; }, mutator(value) { this.parent.getParam('_redirect').setValue({ externalLink: true, openType: 'current', url: value, }); }, setter() { const pages = this.node.getProp('_pages_').getValue(); const data = pages.map((item) => { return { title: item.title.zh_CN, value: `/${item.navUuid}`, }; }); return { componentName: 'SelectSetter', props: { options: data, }, }; }, hidden() { return this.parent.getParam('actionType').getValue() !== 'link'; }, }, { name: '_redirect', title: '跳转页面', display: 'none', hidden: true, }, { title: '关联弹窗', name: '_bindFormDialog', display: 'inline', hidden() { const actionType = this.parent.getParam('actionType').toData(); return actionType !== 'formDialog'; }, setter() { // 兼容Vision低版本 const nodeDocument = this.node.document || this.node.page; const { nodeList } = nodeDocument.getRootNodeVisitor('NodeCache'); const options = nodeList .filter((x) => x.componentName.includes('Dialog')) .map((x) => ({ title: x.propsData && x.propsData.title ? `${x.propsData.title}(${x.id})` : `${x.id}(${x.componentName})`, value: x.id, })); return { componentName: 'SelectSetter', props: { options, hasClear: true, }, }; }, }, ]; ================================================ FILE: packages/fusion-ui/lowcode/common/button-groups.ts ================================================ import { IProps } from '../types/index'; import { hideProp } from '../utils'; export const buttonConfigureProps: IProps[] = [ { name: 'children', title: '名称', display: 'inline', initialValue: '操作', isRequired: true, setter: 'StringSetter', }, { name: 'type', title: '按钮样式', display: 'inline', isRequired: true, initialValue: 'primary', setter: { componentName: 'SelectSetter', props: { options: [ { title: '普通按钮', value: 'normal', }, { title: '主按钮', value: 'primary', }, { title: '次按钮', value: 'secondary', }, ], }, }, }, { name: 'key', title: '标识', condition: hideProp, initialValue: (currentValue, defaultValue) => currentValue || defaultValue || `data-${Math.random().toString(36).substr(-6)}`, setter: { componentName: 'StringSetter', }, }, { name: 'disabled', title: '是否禁用', display: 'inline', initialValue: false, setter: 'BoolSetter', }, { name: 'hidden', title: '是否隐藏', display: 'inline', initialValue: false, setter: 'BoolSetter', }, { name: 'actionType', title: '操作类型(TODO)', condition: hideProp, display: 'inline', initialValue: 'batch', setter: { componentName: 'SelectSetter', props: { options: [ // { // title: '批量', // value: 'batch', // }, { title: '表单弹窗', value: 'formDialog', }, { title: '链接', value: 'link', }, { title: '导入', value: 'import', }, // { // title: '同步', // value: 'sync', // }, { title: '导出', value: 'export', }, // { // title: '解析导出', // value: 'analysisExport', // }, ], }, }, }, { name: 'onClick', title: '点击事件', setter: 'FunctionSetter', }, ]; export const buttonGroupConfigureProp: IProps = { type: 'field', name: 'buttonGroup', title: '按钮组', extraProps: { display: 'accordion', }, setter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'text', title: { label: '文字模式', tip: '是否设定按钮为文字模式', }, setter: 'BoolSetter', }, { name: 'visibleButtonCount', title: { label: '可见数量', tip: '超过会收起到”更多“菜单中', }, extraProps: { defaultValue: 3, }, setter: { componentName: 'NumberSetter', props: { max: 6, min: 1, }, }, }, { name: 'dataSource', title: '按钮组', extraProps: { display: 'plain', }, setter: { componentName: 'ArraySetter', props: { hideDescription: true, itemSetter: { componentName: 'ObjectSetter', props: { config: { items: buttonConfigureProps, }, }, initialValue: () => ({ children: '操作', type: 'normal', }), }, }, }, }, ], }, }, }, }; ================================================ FILE: packages/fusion-ui/lowcode/common/chart-action.ts ================================================ import { IPublicTypeConfigure } from '@alilc/lowcode-types'; export const actionConfigure: NonNullable = [ { type: 'field', name: 'cardProps.actionButtons', title: '操作配置', extraProps: { display: 'accordion', }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'children', title: '名称', display: 'inline', initialValue: '操作', important: true, setter: 'StringSetter', }, { name: 'onClick', title: '点击事件', display: 'inline', important: true, setter: 'FunctionSetter', }, ], }, }, initialValue: () => { return { children: '操作', }; }, }, }, }, }, { name: 'cardProps.text', title: { label: '文字模式', tip: '是否设定按钮为文字模式', }, setter: 'BoolSetter', }, { name: 'cardProps.visibleButtonCount', title: { label: '可见数量', tip: '超过会收起到”更多“菜单中', }, extraProps: { defaultValue: 3, }, setter: { componentName: 'NumberSetter', props: { max: 6, min: 1, }, }, }, ]; ================================================ FILE: packages/fusion-ui/lowcode/common/chart-plot.ts ================================================ import { IPublicTypeConfigure } from '@alilc/lowcode-types'; export const plotConfigure: NonNullable = [ { name: 'autoFit', title: '自适应宽高', display: 'block', defaultValue: true, setter: 'BoolSetter', }, { name: 'height', title: '高度', display: "block", defaultValue: 300, setter: { componentName: 'NumberSetter', }, } ]; ================================================ FILE: packages/fusion-ui/lowcode/common/index.ts ================================================ export * from './actions'; export * from './chart-action'; export * from './operations'; ================================================ FILE: packages/fusion-ui/lowcode/common/operations.ts ================================================ import { IProps } from '../types'; import { hideProp } from '../utils'; import { IPublicModelSettingField } from '@alilc/lowcode-types'; export const operationConfig: IProps = { name: 'operationConfig', display: 'accordion', title: '底部操作', setter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'visibleButtonCount', title: { label: '可见数量', tip: '超过会收起到”更多“菜单中', }, extraProps: { defaultValue: 3, }, setter: { componentName: 'NumberSetter', props: { max: 6, min: 1, }, }, }, { name: 'fixed', title: '吸底', setter: 'BoolSetter', }, { name: 'showSaveTime', title: '显示时间', setter: { componentName: 'BoolSetter', }, }, { name: 'align', title: '布局', defaultValue: 'center', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '居左', value: 'left', }, { title: '居中', value: 'center', }, { title: '居右', value: 'right', }, ], }, }, }, ], }, }, }, }; export const operations: IProps = { name: 'operations', display: 'block', title: '操作项', getValue: (target, value) => { return value || []; }, setter: { componentName: 'MixedSetter', props: { setters: [ { componentName: 'SlotSetter', defaultValue: { type: 'JSSlot', value: [], }, }, { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'id', condition: hideProp, setter: (target: IPublicModelSettingField) => { if (!target.getValue()) { target.setValue(`${target.id}`); } return 'StringSetter'; }, }, { name: 'content', display: 'inline', title: '文本', setter: 'StringSetter', important: true, }, { name: 'action', display: 'inline', title: '操作', important: true, setValue: (target: IPublicModelSettingField, value: any) => { const actionNameMap: any = { submit: '提交', reset: '重置', custom: '自定义', }; const actionName = actionNameMap[value] || '自定义'; target.parent.setPropValue('content', actionName); }, setter: { componentName: 'SelectSetter', props: { options: [ { title: '提交', value: 'submit', }, { title: '重置', value: 'reset', }, { title: '自定义', value: 'custom', }, ], }, }, }, { name: 'type', display: 'inline', title: '样式', important: true, setter: { componentName: 'SelectSetter', props: { options: [ { title: '主要', value: 'primary', }, { title: '次要', value: 'secondary', }, { title: '普通', value: 'normal', }, ], }, }, }, { name: 'behavior', title: '交互设置', display: 'block', condition: (target: IPublicModelSettingField) => { const action = target.parent.getPropValue('action'); return !action || action === 'custom'; }, setter: { componentName: 'BehaviorSetter', props: (target: IPublicModelSettingField) => ({ actions: ['onClick'], enableTooltipAction: true, enableMessageAction: true, extendedOptions: { tooltip: { id: target.parent.getPropValue('id'), defaultTriggerType: 'click', }, message: { types: ['notice', 'success', 'loading', 'warning', 'error'], defaultType: 'notice', library: 'Next', component: 'Message', }, }, }), }, }, { name: 'onClick', display: 'inline', title: '点击事件', condition: hideProp, setter: 'FunctionSetter', extraProps: { supportVariable: true, }, }, { name: 'htmlType', condition: hideProp, }, { name: '!autoSubmit', display: 'inline', virtual: true, title: '自动提交', setter: { componentName: 'BoolSetter', }, extraProps: { setValue: (target: IPublicModelSettingField, value: any) => { target.parent.setPropValue('htmlType', value ? 'submit' : ''); }, getValue: (target: IPublicModelSettingField, value: any) => { return value === 'submit'; }, }, condition: (target: IPublicModelSettingField) => { return target.parent.getPropValue('action') !== 'submit'; }, }, ], }, }, initialValue: () => { return { content: '提交', action: 'submit', type: 'normal', }; }, }, }, }, ], }, }, }; export const operationProps = [operationConfig, operations]; ================================================ FILE: packages/fusion-ui/lowcode/date-picker/meta.ts ================================================ import { hideProp } from '../utils'; import { wrapFormItemProps } from '../utils/form-utils'; import { IComponentDescription } from '../types'; const meta: IComponentDescription = { componentName: 'FormDatePicker', isFormItemComponent: true, title: '日期选择框', docUrl: '', screenshot: '', npm: { package: '@alifd/fusion-ui', version: '{{version}}', exportName: 'FormDatePicker', main: '', destructuring: true, subName: '', }, configure: { supports: { events: ['onChange', 'onOk'], }, props: wrapFormItemProps([ { name: 'label', title: { label: '标签', tip: 'label|表单项内置标签', }, setter: 'StringSetter', }, { name: 'state', title: { label: '状态', tip: 'state|表单项状态', }, setter: { componentName: 'RadioGroupSetter', props: { options: ['success', 'loading', 'error'], }, }, }, { name: 'placeholder', title: { label: '占位提示', tip: 'placeholder|输入提示', }, setter: 'StringSetter', }, { name: 'value', title: { label: 'value', tip: 'value|日期值(受控)', }, setter: 'DateSetter', condition: hideProp, }, { name: 'format', title: { label: '格式', tip: 'format|日期值的格式(用于限定用户输入和展示)', }, setter: 'StringSetter', defaultValue: 'YYYY-MM-DD', }, { name: 'size', title: { label: '尺寸', tip: 'size|表单项尺寸', }, setter: { componentName: 'RadioGroupSetter', props: { options: ['small', 'medium', 'large'], }, }, defaultValue: 'medium', }, { name: 'disabled', title: { label: '是否禁用', tip: 'disabled|是否禁用', }, setter: 'BoolSetter', }, { name: 'hasClear', title: { label: '清除按钮', tip: 'hasClear|是否显示清空按钮', }, setter: 'BoolSetter', defaultValue: true, }, { name: 'followTrigger', setter: 'BoolSetter', title: '跟随滚动', }, { name: 'defaultValue', title: { label: '默认值', tip: 'defaultValue|初始日期值,moment 对象', }, setter: 'DateSetter', }, { name: 'form', type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', }, ], }, ]), }, icon: '', category: '内容', }; export default meta; ================================================ FILE: packages/fusion-ui/lowcode/date-picker/snippets.js ================================================ module.exports = [ { title: '日期选择框', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_date-picker.png', schema: { componentName: 'DatePicker', props: { prefix: 'next-', format: 'YYYY-MM-DD', size: 'medium', hasClear: false, popupTriggerType: 'click', popupAlign: 'tl tl', followTrigger: true, }, }, }, { title: '日期区间', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_date-picker.png', schema: { componentName: 'RangePicker', props: { prefix: 'next-', format: 'YYYY-MM-DD', size: 'medium', type: 'date', hasClear: false, popupTriggerType: 'click', popupAlign: 'tl tl', followTrigger: true, }, }, }, ]; ================================================ FILE: packages/fusion-ui/lowcode/donut-chart/meta.ts ================================================ import { IPublicTypeComponentMetadata, IPublicTypeSnippet } from '@alilc/lowcode-types'; import { actionConfigure } from '../common/chart-action'; import { plotConfigure } from '../common/chart-plot'; const DonutChartMeta: IPublicTypeComponentMetadata = { componentName: 'DonutChart', title: '环形图', category: '图表', group: '精选组件', docUrl: '', screenshot: '', devMode: 'proCode', npm: { package: '@alifd/fusion-ui', version: '0.1.3-beta.3', exportName: 'DonutChart', main: 'lib/index.js', destructuring: true, subName: '', }, configure: { props: [ // 图例 { name: 'legend', type: 'group', display: 'accordion', title: { label: '图例', }, items: [ { name: 'legend.position', title: '位置', setter: { componentName: 'SelectSetter', props: { options: [ { title: '左', value: 'left' }, { title: '左上', value: 'left-top' }, { title: '左下', value: 'left-bottom' }, { title: '右', value: 'right' }, { title: '右上', value: 'right-top' }, { title: '右下', value: 'right-bottom' }, { title: '上', value: 'top' }, { title: '上左', value: 'top-left' }, { title: '上右', value: 'top-right' }, { title: '下', value: 'bottom' }, { title: '下左', value: 'bottom-left' }, { title: '下右', value: 'bottom-right' }, ], }, }, }, ], }, // 数据 { name: 'data', type: 'group', display: 'accordion', title: { label: '数据', }, items: [ { name: 'data', title: '图表数据', setter: 'JsonSetter', }, { name: 'angleField', title: { label: '值字段名', tip: '扇形切片大小(弧度)所对应的数据字段名', }, setter: 'StringSetter', }, { name: 'colorField', title: { label: '分类字段名', tip: '扇形颜色映射对应的数据字段名', }, setter: 'StringSetter', }, ], }, // 图形属性 { name: '', type: 'group', display: 'accordion', title: { label: '图形属性', }, items: [ { name: 'color', title: '颜色', setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ColorSetter', initialValue: '#0079f2', }, }, }, }, { name: 'label', type: 'group', display: 'accordion', title: { label: '标签', }, items: [ { name: 'label.visible', title: '显示', setter: 'BoolSetter', }, { name: 'label.type', title: '位置', setter: { componentName: 'SelectSetter', props: { options: [ { title: '内部', value: 'inner' }, { title: '外部', value: 'outer' }, { title: '外部圆形排布', value: 'outer-center' }, { title: '蜘蛛布局', value: 'spider' }, ], }, }, }, ], }, ], }, ...plotConfigure, ...actionConfigure, ], }, }; const snippets: IPublicTypeSnippet[] = [ { title: '环形图', screenshot: 'https://img.alicdn.com/imgextra/i3/O1CN01pLbt7T1Mh0woqKEN1_!!6000000001465-55-tps-56-56.svg', schema: { componentName: 'DonutChart', props: { legend: { position: 'top-left', }, data: [ { year: '1991', value: 72345678 }, { year: '1992', value: 4321132 }, { year: '1993', value: 33121112.5 }, { year: '1994', value: 45227221 }, { year: '1995', value: 4321221.9 }, { year: '1996', value: 6322121 }, { year: '1997', value: 78312213 }, { year: '1998', value: 2192312 }, { year: '1999', value: 6212332 }, { year: '2000', value: 1192312 }, ], angleField: 'value', colorField: 'year', label: { visible: true, type: 'spider', }, color: ['#3BCBD1', '#47A4FE', '#EDBA42', '#F4704E', '#ED6899', '#7F62C3', '#6E7BC9'], }, }, }, ]; export default { ...DonutChartMeta, snippets, }; ================================================ FILE: packages/fusion-ui/lowcode/edit-table/meta.ts ================================================ import { IComponentDescription } from '../types/index'; import { ProTableProps } from '../pro-table/pro-table-meta'; function editTablePropsFilter(prop: any) { const ignorePropNames: string[] = ['dataSource']; return !ignorePropNames.includes(prop?.name); } const EditTableProps = ProTableProps.filter(editTablePropsFilter).map((item) => { if (item.name === 'advanced') { return { type: 'group', title: '高级', name: 'other', extraProps: { display: 'accordion', defaultCollapsed: true, }, items: [ { name: 'addPosition', title: '新增行位置', defaultValue: 'end', setter: { componentName: 'RadioGroupSetter', props: { options: [ { label: '上', value: 'start', }, { label: '下', value: 'end', }, ], }, }, }, { type: 'field', name: '!选择模式', title: '选择模式', display: 'inline', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '无', value: 'none', tip: 'none', }, { title: '多选', value: 'multiple', tip: 'multiple', }, { title: '单选', value: 'single', tip: 'single', }, ], }, }, defaultValue: 'none', getValue: (target) => { const rowSelection = target.parent.getPropValue('rowSelection'); if (!rowSelection) { return 'none'; } return rowSelection.mode === 'single' ? 'single' : 'multiple'; }, setValue: (field, value) => { const { node } = field; if (['single', 'multiple'].includes(value)) { node.setPropValue('rowSelection', { ...node.getPropValue('rowSelection'), mode: value, }); } else { node.setPropValue('rowSelection', undefined); } }, }, { type: 'field', name: 'indexColumn', title: '开启序号列', extraProps: { display: 'inline', defaultValue: false, }, setter: { componentName: 'BoolSetter', }, }, { type: 'field', name: 'settingButtons', title: '开启设置按钮', extraProps: { display: 'inline', defaultValue: false, }, setter: { componentName: 'BoolSetter', }, }, { type: 'field', name: 'primaryKey', title: { label: '数据主键', tip: '数据主键用于区分数据中不同的行,对行选择和行编辑功能非常重要,不同的行主键值不可重复,一般采用数据库中自增 ID 字段', }, extraProps: { display: 'inline', defaultValue: 'id', condition: () => false, }, }, { name: 'cellDefault', title: { label: '单元格缺省填充', tip: '当单元格值为空时,显示内容', }, setter: 'StringSetter', }, ], }; } return { ...item }; }); export const editTableMeta: IComponentDescription = { componentName: 'EditTable', title: '可编辑表格', docUrl: '', icon: 'https://img.alicdn.com/imgextra/i4/O1CN01dtjMvv1heoyqst9u5_!!6000000004303-55-tps-56-56.svg', devMode: 'procode', group: '精选组件', category: '表格类', tags: ['业务组件'], npm: { package: '@alifd/fusion-ui', version: '1.0.24-21', exportName: 'EditTable', main: 'lib/index.js', destructuring: true, subName: '', }, configure: { props: EditTableProps, component: { isContainer: false, nestingRule: {}, }, supports: { events: ['onSave', 'onRemove'], }, }, snippets: [ { title: '可编辑表格', screenshot: 'https://img.alicdn.com/imgextra/i4/O1CN01dtjMvv1heoyqst9u5_!!6000000004303-55-tps-56-56.svg', schema: { componentName: 'EditTable', props: { dataSource: [ { id: 'id-2f5DdE2b-0', date: '2013-06-12', percent: 1.862, documentAmount: 2022, currency: 'CNY', company: '支付宝科技有限公司', }, { id: 'id-2f5DdE2b-1', date: '2013-06-12', percent: 1.862, documentAmount: 2022, currency: 'CNY', company: '支付宝科技有限公司', }, { id: 'id-2f5DdE2b-2', date: '2013-06-12', percent: 1.862, documentAmount: 2022, currency: 'CNY', company: '支付宝科技有限公司', }, { id: 'id-2f5DdE2b-3', date: '2013-06-12', percent: 1.862, documentAmount: 2022, currency: 'CNY', company: '支付宝科技有限公司', }, { id: 'id-2f5DdE2b-4', date: '2013-06-12', percent: 1.862, documentAmount: 2022, currency: 'CNY', company: '支付宝科技有限公司', }, ], actionColumnButtons: { text: true, visibleButtonCount: 3, }, actionBarButtons: { dataSource: [ { type: 'primary', children: '操作一', }, { type: 'normal', children: '操作二', }, ], visibleButtonCount: 3, }, paginationProps: { pageSize: 20, current: 1, }, settingButtons: true, columns: [ { title: '公司', dataIndex: 'company', width: 160, formatType: 'link', searchable: true, }, { title: '单据金额', dataIndex: 'documentAmount', formatType: 'money', }, { title: '币种', dataIndex: 'currency', formatType: 'currency', filters: [ { label: 'CNY', value: 'CNY', }, { label: 'USD', value: 'USD', }, { label: 'JPY', value: 'JPY', }, { label: 'HKD', value: 'HKD', }, ], filterMode: 'multiple', explanation: '提示信息', width: 110, }, { title: '完成进度', dataIndex: 'percent', formatType: 'progress', }, { title: '到账日期', dataIndex: 'date', formatType: 'date', }, ], }, }, }, ], }; export default editTableMeta; ================================================ FILE: packages/fusion-ui/lowcode/expand-table/meta.ts ================================================ import { ComponentMetadata, Snippet } from '@ali/lowcode-types'; import { proTableMeta } from '../pro-table/pro-table-meta'; import { mockProTableRow, mockId } from '../pro-table/utils'; import { isJSExpression } from '../utils'; const childProps = proTableMeta.configure.props.map((item) => { if (item.name === 'dataSource') { return { type: 'field', name: 'dataSource', title: '表格数据源', display: 'accordion', setter: (target) => { const dataSource = target.getProps().getPropValue('dataSource'); if (isJSExpression(dataSource)) { return { componentName: 'ExpressionSetter', }; } const current = dataSource[target.path[1]]; const columns = current?.childTableProps?.columns; if (!columns || isJSExpression(columns)) { return { componentName: 'ExpressionSetter', }; } const mockRow = mockProTableRow(columns); const primaryKey = target.getProps().getPropValue('primaryKey') || 'id'; return { componentName: 'MixedSetter', props: { setters: [ { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: columns.map((column, index) => { return { title: { label: { type: 'i18n', 'en-US': column.dataIndex, 'zh-CN': column.title, }, }, name: column.dataIndex, setter: { isRequired: index < 2, componentName: 'StringSetter', }, defaultValue: mockRow[column.dataIndex], }; }), }, }, initialValue: () => { return { ...mockRow, [primaryKey]: mockId(), }; }, }, }, }, 'ExpressionSetter', ], }, }; }, }; } return item; }); const props = proTableMeta.configure.props.map((item) => { if (item.name === 'dataSource') { return { type: 'field', name: 'dataSource', title: '表格数据源', display: 'accordion', setter: (target) => { const columns = target.getProps().getPropValue('columns'); if (!columns || isJSExpression(columns)) { return { componentName: 'ExpressionSetter', }; } const mockRow = mockProTableRow(columns); const primaryKey = target.getProps().getPropValue('primaryKey') || 'id'; return { componentName: 'MixedSetter', props: { setters: [ { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ ...columns.map((column, index) => { return { title: { label: { type: 'i18n', 'en-US': column.dataIndex, 'zh-CN': column.title, }, }, name: column.dataIndex, setter: { isRequired: index < 2, componentName: 'StringSetter', }, defaultValue: mockRow[column.dataIndex], }; }), { title: { label: { type: 'i18n', 'en-US': 'ChildTable', 'zh-CN': '子表格配置' }, }, display: 'accordion', name: 'childTableProps', setter: { componentName: 'ObjectSetter', props: { config: { items: childProps, }, }, }, }, ], }, }, initialValue: () => { return { ...mockRow, [primaryKey]: mockId(), }; }, }, }, }, 'ExpressionSetter', ], }, }; }, }; } return item; }); const ExpandTableMeta: ComponentMetadata = { componentName: 'ExpandTable', title: '母子表格', docUrl: '', screenshot: 'https://img.alicdn.com/imgextra/i4/O1CN01N3gxxr1cjKnzi9iBU_!!6000000003636-55-tps-56-56.svg', devMode: 'proCode', group: '精选组件', category: '表格类', tags: ['业务组件'], npm: { package: '@alifd/fusion-ui', version: '0.1.6-beta.8', exportName: 'ExpandTable', main: 'lib/index.js', destructuring: true, subName: '', }, configure: { props, supports: { className: true, style: true, events: [ { name: 'onBodyScroll', description: '在内容区域滚动的时候触发的函数', }, ], }, component: {}, }, }; const snippets: Snippet[] = [ { title: '母子表格', screenshot: 'https://img.alicdn.com/imgextra/i4/O1CN01N3gxxr1cjKnzi9iBU_!!6000000003636-55-tps-56-56.svg', schema: { componentName: 'ExpandTable', props: { dataSource: [ { id: 'id-2f5DdE2b-0', date: '2013-06-12', percent: 1.862, documentAmount: 2022, currency: 'CNY', company: '支付宝科技有限公司', childTableProps: { dataSource: [], columns: [ { title: '公司', dataIndex: 'company', width: 160, formatType: 'link', searchable: true, }, { title: '单据金额', dataIndex: 'documentAmount', formatType: 'money', }, { title: '币种', dataIndex: 'currency', formatType: 'currency', filters: [ { label: 'CNY', value: 'CNY', }, { label: 'USD', value: 'USD', }, { label: 'JPY', value: 'JPY', }, { label: 'HKD', value: 'HKD', }, ], filterMode: 'multiple', explanation: '提示信息', width: 110, }, { title: '完成进度', dataIndex: 'percent', formatType: 'progress', }, { title: '到账日期', dataIndex: 'date', formatType: 'date', }, ], }, }, { id: 'id-2f5DdE2b-1', date: '2013-06-12', percent: 1.862, documentAmount: 2022, currency: 'CNY', company: '支付宝科技有限公司', childTableProps: { dataSource: [], columns: [ { title: '公司', dataIndex: 'company', width: 160, formatType: 'link', searchable: true, }, { title: '单据金额', dataIndex: 'documentAmount', formatType: 'money', }, { title: '币种', dataIndex: 'currency', formatType: 'currency', filters: [ { label: 'CNY', value: 'CNY', }, { label: 'USD', value: 'USD', }, { label: 'JPY', value: 'JPY', }, { label: 'HKD', value: 'HKD', }, ], filterMode: 'multiple', explanation: '提示信息', width: 110, }, { title: '完成进度', dataIndex: 'percent', formatType: 'progress', }, { title: '到账日期', dataIndex: 'date', formatType: 'date', }, ], }, }, { id: 'id-2f5DdE2b-2', date: '2013-06-12', percent: 1.862, documentAmount: 2022, currency: 'CNY', company: '支付宝科技有限公司', childTableProps: { dataSource: [], columns: [ { title: '公司', dataIndex: 'company', width: 160, formatType: 'link', searchable: true, }, { title: '单据金额', dataIndex: 'documentAmount', formatType: 'money', }, { title: '币种', dataIndex: 'currency', formatType: 'currency', filters: [ { label: 'CNY', value: 'CNY', }, { label: 'USD', value: 'USD', }, { label: 'JPY', value: 'JPY', }, { label: 'HKD', value: 'HKD', }, ], filterMode: 'multiple', explanation: '提示信息', width: 110, }, { title: '完成进度', dataIndex: 'percent', formatType: 'progress', }, { title: '到账日期', dataIndex: 'date', formatType: 'date', }, ], }, }, ], actionColumnButtons: { dataSource: [ { children: '查看', type: 'primary', }, { children: '编辑', type: 'primary', disabled: true, }, { children: '删除', type: 'primary', }, ], text: true, visibleButtonCount: 3, }, actionBarButtons: { dataSource: [ { type: 'primary', children: '操作一', }, { type: 'normal', children: '操作二', }, ], visibleButtonCount: 3, }, paginationProps: { pageSize: 20, current: 1, }, settingButtons: true, columns: [ { title: '公司', dataIndex: 'company', width: 160, formatType: 'link', searchable: true, }, { title: '单据金额', dataIndex: 'documentAmount', formatType: 'money', }, { title: '币种', dataIndex: 'currency', formatType: 'currency', filters: [ { label: 'CNY', value: 'CNY', }, { label: 'USD', value: 'USD', }, { label: 'JPY', value: 'JPY', }, { label: 'HKD', value: 'HKD', }, ], filterMode: 'multiple', explanation: '提示信息', width: 110, }, { title: '完成进度', dataIndex: 'percent', formatType: 'progress', }, { title: '到账日期', dataIndex: 'date', formatType: 'date', }, ], }, }, }, ]; export default { ...ExpandTableMeta, snippets, }; ================================================ FILE: packages/fusion-ui/lowcode/filter/meta.ts ================================================ import { ComponentMetadata, Snippet } from '@ali/lowcode-types'; import { formItemsProps } from '../pro-form/common/form-base-props'; import { showWithLabelAlign } from '../utils'; import { operations } from '../common'; const operationConfig = { name: 'operationConfig', display: 'accordion', title: '底部操作', setter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'visibleButtonCount', title: { label: '可见数量', tip: '超过会收起到”更多“菜单中', }, extraProps: { defaultValue: 3, }, setter: { componentName: 'NumberSetter', props: { max: 6, min: 1, }, }, }, ], }, }, }, }; const FilterMeta: ComponentMetadata = { componentName: 'Filter', title: '查询筛选', group: '精选组件', category: '表格类', tags: ['业务组件'], docUrl: '', icon: 'https://img.alicdn.com/imgextra/i1/O1CN01O4Oshp1RA6Z0sFZ6h_!!6000000002070-55-tps-56-56.svg', devMode: 'proCode', npm: { package: '@alifd/fusion-ui', version: '0.1.6-beta.8', exportName: 'Filter', main: 'lib/index.js', destructuring: true, subName: '', }, configure: { props: [ { name: 'globalConfig', title: '全局配置', type: 'group', display: 'accordion', items: [ { name: 'enableFilterConfiguration', title: '开启筛选项', setter: 'BoolSetter', }, { name: 'status', title: '状态', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '只读态', value: 'readonly', }, { title: '编辑态', value: 'editable', }, ], }, }, getValue: (target) => { const isPreview = target.getProps().getPropValue('isPreview'); return isPreview ? 'readonly' : 'editable'; }, setValue: (target, value) => { target.getProps().setPropValue('isPreview', value === 'readonly'); }, defaultValue: 'editable', }, { name: 'isPreview', condition: () => false, title: { label: { type: 'i18n', zh_CN: '预览态', en_US: 'Preview Mode', }, tip: { type: 'i18n', zh_CN: '属性: isPreview | 说明: 是否开启预览态', en_US: 'prop: isPreview | description: preview mode', }, }, setter: 'BoolSetter', }, { name: 'cols', title: '布局', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '一列', value: 1, }, { title: '二列', value: 2, }, { title: '三列', value: 3, }, { title: '四列', value: 4, }, ], }, }, defaultValue: 4, }, { name: 'labelAlign', title: { label: { type: 'i18n', zh_CN: '标签位置', en_US: 'Label Align', }, tip: { type: 'i18n', zh_CN: '属性: labelAlign | 说明: 标签的位置\n@enum desc 上, 左, 内', en_US: 'prop: labelAlign | description: label align', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '上', value: 'top', }, { title: '左', value: 'left', }, { title: '内', value: 'inset', }, ], }, }, setValue: (target, value) => { if (value === 'inset') { target.getProps().setPropValue('labelCol', null); target.getProps().setPropValue('wrapperCol', null); } else if (value === 'left') { target.getProps().setPropValue('labelCol', { fixedSpan: 4 }); target.getProps().setPropValue('wrapperCol', null); } return target.getProps().setPropValue('labelAlign', value); }, defaultValue: 'top', }, { name: 'labelCol.fixedSpan', title: '标题宽度', condition: showWithLabelAlign, setter: { componentName: 'NumberSetter', props: { min: 0, max: 24, }, }, }, { name: 'labelCol.offset', title: '标题偏移', condition: showWithLabelAlign, setter: { componentName: 'NumberSetter', props: { min: 0, max: 24, }, }, }, { name: 'wrapperCol.span', title: '内容宽度', condition: showWithLabelAlign, setter: { componentName: 'NumberSetter', props: { min: 0, max: 24, }, }, }, { name: 'wrapperCol.offset', title: '内容偏移', condition: showWithLabelAlign, setter: { componentName: 'NumberSetter', props: { min: 0, max: 24, }, }, }, { name: 'labelTextAlign', condition: showWithLabelAlign, title: { label: { type: 'i18n', zh_CN: '标签对齐', en_US: 'Text Align', }, tip: { type: 'i18n', zh_CN: '属性: labelTextAlign | 说明: 标签的左右对齐方式\n@enumdesc 左, 右', en_US: 'prop: labelTextAlign | description: label text align', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['left', 'right'], }, }, defaultValue: 'right', }, ], }, formItemsProps, operationConfig, operations, ], supports: { style: true, className: true, events: ['onExpand', 'onSearch', 'onReset'], }, component: { isMinimalRenderUnit: true, }, }, }; const snippets: Snippet[] = [ { title: '查询筛选', screenshot: 'https://img.alicdn.com/imgextra/i1/O1CN01O4Oshp1RA6Z0sFZ6h_!!6000000002070-55-tps-56-56.svg', schema: { componentName: 'Filter', id: 'node_ockt5mo4jj1', props: { labelAlign: 'top', }, children: [...new Array(4).keys()].map((item) => ({ componentName: 'FormInput', props: { formItemProps: { primaryKey: String(Math.floor(Math.random() * 10000) + item), label: '表单项', size: 'medium', device: 'desktop', fullWidth: true, }, placeholder: '请输入', }, })), }, }, ]; export default { ...FilterMeta, snippets, }; ================================================ FILE: packages/fusion-ui/lowcode/filter-item/meta.ts ================================================ import { ComponentMetadata } from '@ali/lowcode-types'; const FilterItemMeta: ComponentMetadata = { componentName: 'FilterItem', title: 'FilterItem', docUrl: '', screenshot: '', devMode: 'proCode', npm: { package: '@alifd/fusion-ui', version: '0.1.6-beta.8', exportName: 'FilterItem', main: 'lib/index.js', destructuring: true, subName: '', }, configure: { props: [ { title: { label: { type: 'i18n', 'en-US': 'prefix', 'zh-CN': '样式前缀', }, tip: 'prefix | 样式前缀', }, name: 'prefix', description: '样式前缀', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'label', 'zh-CN': 'label 标签的文', }, tip: 'label | label 标签的文本', }, name: 'label', description: 'label 标签的文本', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'labelCol', 'zh-CN': 'label 标签布局', }, tip: 'labelCol | label 标签布局,通 `` 组件,设置 span offset 值,如 {span: 8, offset: 16},该项仅在垂直表单有效', }, name: 'labelCol', description: 'label 标签布局,通 `` 组件,设置 span offset 值,如 {span: 8, offset: 16},该项仅在垂直表单有效', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'wrapperCol', 'zh-CN': '需要为输入控件设置布', }, tip: 'wrapperCol | 需要为输入控件设置布局样式时,使用该属性,用法同 labelCol', }, name: 'wrapperCol', description: '需要为输入控件设置布局样式时,使用该属性,用法同 labelCol', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'help', 'zh-CN': '自定义提示信息,如不', }, tip: 'help | 自定义提示信息,如不设置,则会根据校验规则自动生成.', }, name: 'help', description: '自定义提示信息,如不设置,则会根据校验规则自动生成.', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'extra', 'zh-CN': '额外的提示信息,和 ', }, tip: 'extra | 额外的提示信息,和 help 类似,当需要错误信息和提示文案同时出现时,可以使用这个。 位于错误信息后面', }, name: 'extra', description: '额外的提示信息,和 help 类似,当需要错误信息和提示文案同时出现时,可以使用这个。 位于错误信息后面', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'validateState', 'zh-CN': '校验状态,如不设置,', }, tip: 'validateState | 校验状态,如不设置,则会根据校验规则自动生成', }, name: 'validateState', description: '校验状态,如不设置,则会根据校验规则自动生成', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'hasFeedback', 'zh-CN': '配合 validat', }, tip: 'hasFeedback | 配合 validateState 属性使用,是否展示 success/loading 的校验状态图标, 目前只有Input支持', }, name: 'hasFeedback', description: '配合 validateState 属性使用,是否展示 success/loading 的校验状态图标, 目前只有Input支持', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'children', 'zh-CN': 'node 或者 fu', }, tip: 'children | node 或者 function(values)', }, name: 'children', description: 'node 或者 function(values)', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'size', 'zh-CN': '单个 Item 的 ', }, tip: 'size | 单个 Item 的 size 自定义,优先级高于 Form 的 size, 并且当组件与 Item 一起使用时,组件自身设置 size 属性无效。', }, name: 'size', description: '单个 Item 的 size 自定义,优先级高于 Form 的 size, 并且当组件与 Item 一起使用时,组件自身设置 size 属性无效。', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'labelAlign', 'zh-CN': '标签的位置', }, tip: 'labelAlign | 标签的位置', }, name: 'labelAlign', description: '标签的位置', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'labelTextAlign', 'zh-CN': '标签的左右对齐方式', }, tip: 'labelTextAlign | 标签的左右对齐方式', }, name: 'labelTextAlign', defaultValue: 'right', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'required', 'zh-CN': '[表单校验] 不能为', }, tip: 'required | [表单校验] 不能为空', }, name: 'required', description: '[表单校验] 不能为空', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'asterisk', 'zh-CN': 'required 的', }, tip: 'asterisk | required 的星号是否显示', }, name: 'asterisk', description: 'required 的星号是否显示', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'requiredMessage', 'zh-CN': 'required 自', }, tip: 'requiredMessage | required 自定义错误信息', }, name: 'requiredMessage', description: 'required 自定义错误信息', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'requiredTrigger', 'zh-CN': 'required 自', }, tip: 'requiredTrigger | required 自定义触发方式', }, name: 'requiredTrigger', description: 'required 自定义触发方式', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'min', 'zh-CN': '[表单校验] 最小值', }, tip: 'min | [表单校验] 最小值', }, name: 'min', description: '[表单校验] 最小值', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'max', 'zh-CN': '[表单校验] 最大值', }, tip: 'max | [表单校验] 最大值', }, name: 'max', description: '[表单校验] 最大值', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'minmaxMessage', 'zh-CN': 'min/max 自定', }, tip: 'minmaxMessage | min/max 自定义错误信息', }, name: 'minmaxMessage', description: 'min/max 自定义错误信息', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'minmaxTrigger', 'zh-CN': 'min/max 自定', }, tip: 'minmaxTrigger | min/max 自定义触发方式', }, name: 'minmaxTrigger', description: 'min/max 自定义触发方式', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'minLength', 'zh-CN': '[表单校验] 字符串', }, tip: 'minLength | [表单校验] 字符串最小长度 / 数组最小个数', }, name: 'minLength', description: '[表单校验] 字符串最小长度 / 数组最小个数', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'maxLength', 'zh-CN': '[表单校验] 字符串', }, tip: 'maxLength | [表单校验] 字符串最大长度 / 数组最大个数', }, name: 'maxLength', description: '[表单校验] 字符串最大长度 / 数组最大个数', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'minmaxLengthMessage', 'zh-CN': 'minLength/', }, tip: 'minmaxLengthMessage | minLength/maxLength 自定义错误信息', }, name: 'minmaxLengthMessage', description: 'minLength/maxLength 自定义错误信息', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'minmaxLengthTrigger', 'zh-CN': 'minLength/', }, tip: 'minmaxLengthTrigger | minLength/maxLength 自定义触发方式', }, name: 'minmaxLengthTrigger', description: 'minLength/maxLength 自定义触发方式', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'length', 'zh-CN': '[表单校验] 字符串', }, tip: 'length | [表单校验] 字符串精确长度 / 数组精确个数', }, name: 'length', description: '[表单校验] 字符串精确长度 / 数组精确个数', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'lengthMessage', 'zh-CN': 'length 自定义', }, tip: 'lengthMessage | length 自定义错误信息', }, name: 'lengthMessage', description: 'length 自定义错误信息', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'lengthTrigger', 'zh-CN': 'length 自定义', }, tip: 'lengthTrigger | length 自定义触发方式', }, name: 'lengthTrigger', description: 'length 自定义触发方式', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'pattern', 'zh-CN': '正则校验', }, tip: 'pattern | 正则校验', }, name: 'pattern', description: '正则校验', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'patternMessage', 'zh-CN': 'pattern 自定', }, tip: 'patternMessage | pattern 自定义错误信息', }, name: 'patternMessage', description: 'pattern 自定义错误信息', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'patternTrigger', 'zh-CN': 'pattern 自定', }, tip: 'patternTrigger | pattern 自定义触发方式', }, name: 'patternTrigger', description: 'pattern 自定义触发方式', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'format', 'zh-CN': '[表单校验] 四种常', }, tip: 'format | [表单校验] 四种常用的 pattern', }, name: 'format', description: '[表单校验] 四种常用的 pattern', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'formatMessage', 'zh-CN': 'format 自定义', }, tip: 'formatMessage | format 自定义错误信息', }, name: 'formatMessage', description: 'format 自定义错误信息', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'formatTrigger', 'zh-CN': 'format 自定义', }, tip: 'formatTrigger | format 自定义触发方式', }, name: 'formatTrigger', description: 'format 自定义触发方式', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'validator', 'zh-CN': '[表单校验] 自定义', }, tip: 'validator | [表单校验] 自定义校验函数', }, name: 'validator', description: '[表单校验] 自定义校验函数', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'validatorTrigger', 'zh-CN': 'validator ', }, tip: 'validatorTrigger | validator 自定义触发方式', }, name: 'validatorTrigger', description: 'validator 自定义触发方式', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'autoValidate', 'zh-CN': '是否修改数据时自动触', }, tip: 'autoValidate | 是否修改数据时自动触发校验', }, name: 'autoValidate', description: '是否修改数据时自动触发校验', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'labelWidth', 'zh-CN': '在响应式布局下,且l', }, tip: 'labelWidth | 在响应式布局下,且label在左边时,label的宽度是多少', }, name: 'labelWidth', description: '在响应式布局下,且label在左边时,label的宽度是多少', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'colSpan', 'zh-CN': '在响应式布局模式下,', }, tip: 'colSpan | 在响应式布局模式下,表单项占多少列', }, name: 'colSpan', description: '在响应式布局模式下,表单项占多少列', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'isPreview', 'zh-CN': '是否开启预览态', }, tip: 'isPreview | 是否开启预览态', }, name: 'isPreview', description: '是否开启预览态', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'renderPreview', 'zh-CN': '预览态模式下渲染的内', }, tip: 'renderPreview | 预览态模式下渲染的内容', }, name: 'renderPreview', description: '预览态模式下渲染的内容', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'useLabelForErrorMessage', 'zh-CN': '是否使用 label', }, tip: 'useLabelForErrorMessage | 是否使用 label 替换校验信息的 name 字段', }, name: 'useLabelForErrorMessage', description: '是否使用 label 替换校验信息的 name 字段', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'colon', 'zh-CN': '表示是否显示 lab', }, tip: 'colon | 表示是否显示 label 后面的冒号', }, name: 'colon', description: '表示是否显示 label 后面的冒号', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'valueName', 'zh-CN': '子元素的 value', }, tip: 'valueName | 子元素的 value 名称', }, name: 'valueName', description: '子元素的 value 名称', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'fullWidth', 'zh-CN': '单个 Item 中表', }, tip: 'fullWidth | 单个 Item 中表单类组件宽度是否是 100%', }, name: 'fullWidth', description: '单个 Item 中表单类组件宽度是否是 100%', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'locale', 'zh-CN': '国际化文案对象,属性', }, tip: 'locale | 国际化文案对象,属性为组件的 displayName', }, name: 'locale', description: '国际化文案对象,属性为组件的 displayName', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'pure', 'zh-CN': '是否开启 Pure ', }, tip: 'pure | 是否开启 Pure Render 模式,会提高性能,但是也会带来副作用', }, name: 'pure', description: '是否开启 Pure Render 模式,会提高性能,但是也会带来副作用', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'warning', 'zh-CN': '是否在开发模式下显示', }, tip: 'warning | 是否在开发模式下显示组件属性被废弃的 warning 提示', }, name: 'warning', description: '是否在开发模式下显示组件属性被废弃的 warning 提示', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'rtl', 'zh-CN': '是否开启 rtl 模', }, tip: 'rtl | 是否开启 rtl 模式', }, name: 'rtl', description: '是否开启 rtl 模式', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, ], supports: { style: true, className: true, }, component: {}, }, }; export default { ...FilterItemMeta, }; ================================================ FILE: packages/fusion-ui/lowcode/group-table/meta.ts ================================================ import { mockProTableRow } from '../pro-table/utils'; import { IComponentDescription } from '../types/index'; import { actionColumnButtonField, actionColumnField } from '../pro-table/actionColumnFields'; import { isJSExpression } from '../utils'; import { columnsField } from '../pro-table/columns-field'; import { buttonGroupConfigureProp } from '../common/button-groups'; const dataSource = [ { header: '头部文字', footer: '尾部文字', children: [ { company: '支付宝科技有限公司', documentAmount: 2022, currency: 'CNY', percent: 1.862, date: '2013-06-12', id: 'id-2f5DdE2b-0', }, { company: '支付宝科技有限公司', documentAmount: 2022, currency: 'CNY', percent: 1.862, date: '2013-06-12', id: 'id-2f5DdE2b-0', }, ], }, { header: '头部文字2', footer: '尾部文字2', children: [ { company: '支付宝科技有限公司', documentAmount: 2022, currency: 'CNY', percent: 1.862, date: '2013-06-12', id: 'id-2f5DdE2b-0', }, { company: '支付宝科技有限公司', documentAmount: 2022, currency: 'CNY', percent: 1.862, date: '2013-06-12', id: 'id-2f5DdE2b-0', }, { company: '支付宝科技有限公司', documentAmount: 2022, currency: 'CNY', percent: 1.862, date: '2013-06-12', id: 'id-2f5DdE2b-0', }, { company: '支付宝科技有限公司', documentAmount: 2022, currency: 'CNY', percent: 1.862, date: '2013-06-12', id: 'id-2f5DdE2b-0', }, ], }, ]; const positiveIntegerSetter = { componentName: 'NumberSetter', props: { max: 200, min: 1, }, }; const groupTableMeta: IComponentDescription = { componentName: 'GroupTable', title: '分组表格', docUrl: '', icon: 'https://img.alicdn.com/imgextra/i4/O1CN01idASGC1tGLCY6bAUC_!!6000000005874-55-tps-56-56.svg', devMode: 'proCode', group: '精选组件', category: '表格类', tags: ['业务组件'], npm: { package: '@alifd/fusion-ui', version: '1.0.24-21', exportName: 'GroupTable', main: 'lib/index.js', destructuring: true, subName: '', }, configure: { props: [ columnsField, { type: 'field', name: 'id', title: '节点 ID', condition: () => false, extraProps: {}, setter: 'NodeSetter', }, actionColumnButtonField, { ...buttonGroupConfigureProp, name: 'actionBarButtons', title: '操作栏按钮', }, actionColumnField, { name: 'dataSource', title: '分组内容', setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { title: { label: { type: 'i18n', 'en-US': 'header', 'zh-CN': '头部文字' } }, name: 'header', setter: { componentName: 'StringSetter', isRequired: true, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'label', 'zh-CN': '尾部文字' } }, name: 'footer', setter: { componentName: 'StringSetter', isRequired: true, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'label', 'zh-CN': '数据源' } }, name: 'children', setter: (target) => { const columns = target.getProps().getPropValue('columns'); if (!columns || isJSExpression(columns)) { return { componentName: 'ExpressionSetter', }; } const mockRow = mockProTableRow(columns); return { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: columns.map((column, index) => { return { title: { label: { type: 'i18n', 'en-US': column.dataIndex, 'zh-CN': column.title, }, }, name: column.dataIndex, setter: { isRequired: index < 2, componentName: 'StringSetter', }, defaultValue: mockRow[column.dataIndex], }; }), }, }, initialValue: mockRow, }, }, }; }, }, ], extraSetter: { componentName: 'MixedSetter', isRequired: false, props: {} }, }, }, initialValue: { header: '标题', footer: '尾部', children: [], }, }, }, isRequired: true, initialValue: [], }, }, { type: 'field', name: 'paginationProps', title: '分页器', extraProps: { display: 'accordion', defaultCollapsed: true, }, setter: { componentName: 'ObjectSetter', display: 'inline', props: { config: { items: [ { type: 'field', name: 'hidden', title: '关闭分页', extraProps: { display: 'inline', defaultValue: false, }, setter: 'BoolSetter', }, { name: 'total', title: '总行数', setter: { componentName: 'NumberSetter', props: { min: 0, }, }, hidden() { console.log( 'visiblevisiblevisiblevisible', this.parent.getParam('hidden').getValue(), ); return !this.parent.getParam('hidden').getValue(); }, }, { name: 'current', title: '当前页', setter: positiveIntegerSetter, }, { name: 'pageSize', title: '每页行数', setter: [ { componentName: 'SelectSetter', initialValue: 10, props: { options: [ { title: '5', value: 5, }, { title: '10', value: 10, }, { title: '20', value: 20, }, { title: '50', value: 50, }, ], }, }, positiveIntegerSetter, ], }, ], }, }, }, }, { type: 'field', name: 'rowSelection', condition: () => false, }, ], component: { isContainer: false, nestingRule: {}, }, supports: {}, }, snippets: [ { title: '分组表格', screenshot: 'https://img.alicdn.com/imgextra/i4/O1CN01idASGC1tGLCY6bAUC_!!6000000005874-55-tps-56-56.svg', schema: { componentName: 'GroupTable', props: { dataSource, actionColumnButtons: { dataSource: [ { children: '查看', type: 'primary', }, { children: '编辑', type: 'primary', disabled: true, }, { children: '删除', type: 'primary', }, ], text: true, visibleButtonCount: 3, }, actionBarButtons: { dataSource: [ { type: 'primary', children: '操作一', }, { type: 'normal', children: '操作二', }, ], visibleButtonCount: 3, }, paginationProps: { pageSize: 20, current: 1, }, settingButtons: true, columns: [ { title: '公司', dataIndex: 'company', width: 160, formatType: 'link', searchable: true, }, { title: '单据金额', dataIndex: 'documentAmount', formatType: 'money', }, { title: '币种', dataIndex: 'currency', formatType: 'currency', filters: [ { label: 'CNY', value: 'CNY', }, { label: 'USD', value: 'USD', }, { label: 'JPY', value: 'JPY', }, { label: 'HKD', value: 'HKD', }, ], filterMode: 'multiple', explanation: '提示信息', width: 110, }, { title: '完成进度', dataIndex: 'percent', formatType: 'progress', }, { title: '到账日期', dataIndex: 'date', formatType: 'date', }, ], }, }, }, ], }; export default groupTableMeta; ================================================ FILE: packages/fusion-ui/lowcode/input/meta.ts ================================================ import { IProps } from '../types'; import { wrapFormItemProps } from '../utils/form-utils'; const props: IProps[] = wrapFormItemProps([ { name: 'label', setter: 'StringSetter', title: { label: { type: 'i18n', zh_CN: '标签文本', en_US: 'Label', }, tip: { type: 'i18n', zh_CN: '属性: label | 说明: 标签文本内容', en_US: 'prop: label | description: label content', }, }, }, { name: 'defaultValue', title: { label: '默认值', tip: 'defaultValue|初始值', }, setter: 'StringSetter', }, { name: 'placeholder', defaultValue: '请输入', title: { label: { type: 'i18n', zh_CN: '输入提示', en_US: 'Placeholder', }, tip: { type: 'i18n', zh_CN: '属性: placeholder | 说明: 输入提示', en_US: 'prop: placeholder | description: placeholder', }, }, setter: 'StringSetter', }, { name: 'state', title: { label: { type: 'i18n', zh_CN: '状态', en_US: 'State', }, tip: { type: 'i18n', zh_CN: '属性: state | 说明: 状态\n@enumdesc 错误, 校验中, 成功, 警告', en_US: 'prop: state | description: input state', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { value: 'error', title: 'error', }, { value: 'loading', title: 'loading', }, { value: 'success', title: 'success', }, { value: 'warning', title: 'warning', }, { value: '', title: '默认', }, ], }, }, }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 尺寸\n@enumdesc 小, 中, 大', en_US: 'prop: size | description: size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['small', 'medium', 'large'], }, }, defaultValue: 'medium', }, { name: 'maxLength', title: { label: { type: 'i18n', zh_CN: '最大长度', en_US: 'MaxLength', }, tip: { type: 'i18n', zh_CN: '属性: maxLength | 说明: 最大长度', en_US: 'prop: maxLength | description: max length', }, }, setter: 'NumberSetter', description: '最大长度', }, { name: 'hasClear', title: { label: { type: 'i18n', zh_CN: '显示清除', en_US: 'Show Clear', }, tip: { type: 'i18n', zh_CN: '属性: hasClear | 说明: 是否出现清除按钮', en_US: 'prop: hasClear | description: show clear icon', }, }, setter: 'BoolSetter', description: '是否出现清除按钮', }, { name: 'disabled', title: { label: { type: 'i18n', zh_CN: '是否禁用', en_US: 'Disabled', }, tip: { type: 'i18n', zh_CN: '属性: disabled | 说明: 是否被禁用', en_US: 'prop: disabled | description: disabled', }, }, setter: 'BoolSetter', description: '是否禁用', }, { name: 'showLimitHint', title: { label: { type: 'i18n', zh_CN: '展示限制', en_US: 'ShowLimit', }, tip: { type: 'i18n', zh_CN: '属性: showLimitHint | 说明: 是否展现最大长度样式', en_US: 'prop: showLimitHint | description: showLimitHint', }, }, setter: 'BoolSetter', description: '是否展现最大长度样式', }, { name: 'cutString', title: { label: { type: 'i18n', zh_CN: '是否截断', en_US: 'Cut Off', }, tip: { type: 'i18n', zh_CN: '属性: cutString | 说明: 是否截断超出字符串', en_US: 'prop: cutString | description: whether cut off string', }, }, setter: 'BoolSetter', description: '是否截断超出字符串', }, { name: 'readOnly', title: { label: { type: 'i18n', zh_CN: '是否只读', en_US: 'ReadOnly', }, tip: { type: 'i18n', zh_CN: '属性: readOnly | 说明: 是否只读', en_US: 'prop: readOnly | description: ReadOnly', }, }, setter: 'BoolSetter', description: '是否只读', }, { name: 'trim', title: { label: { type: 'i18n', zh_CN: '是否 Trim', en_US: 'Trim', }, tip: { type: 'i18n', zh_CN: '属性: trim | 说明: onChange返回会自动去除头尾空字符', en_US: 'prop: trim | description: whether trim when onChange called', }, }, setter: 'BoolSetter', }, { name: 'hasBorder', title: { label: { type: 'i18n', zh_CN: '显示边框', en_US: 'ShowBorder', }, tip: { type: 'i18n', zh_CN: '属性: hasBorder | 说明: 是否有边框', en_US: 'prop: hasBorder | description: HasBorder', }, }, setter: 'BoolSetter', }, { name: 'autoFocus', title: { label: { type: 'i18n', zh_CN: '自动聚焦', en_US: 'Auto Focus', }, tip: { type: 'i18n', zh_CN: '属性: autoFocus | 说明: 自动聚焦', en_US: 'prop: autoFocus | description: autoFocus', }, }, setter: 'BoolSetter', description: '自动聚焦', }, { name: 'hint', title: { label: { type: 'i18n', zh_CN: 'Icon 水印', en_US: 'IconHint', }, tip: { type: 'i18n', zh_CN: '属性: hint | 说明: Icon 水印', en_US: 'prop: hint | description: Icon hint', }, }, setter: { componentName: 'IconSetter', }, }, { name: 'innerBefore', display: 'block', title: { label: { type: 'i18n', zh_CN: '文字前附加内容', en_US: 'Inner Before', }, tip: { type: 'i18n', zh_CN: '属性: innerBefore | 说明: 文字前附加内容', en_US: 'prop: innerBefore | description: innerBefore', }, }, setter: 'StringSetter', }, { name: 'innerAfter', display: 'block', title: { label: { type: 'i18n', zh_CN: '文字后附加内容', en_US: 'Inner After', }, tip: { type: 'i18n', zh_CN: '属性: innerAfter | 说明: 文字后附加内容', en_US: 'prop: innerAfter | description: innerAfter', }, }, setter: 'StringSetter', }, { name: 'addonBefore', display: 'block', title: { label: { type: 'i18n', zh_CN: '输入框前附加内容', en_US: 'Addon Before', }, tip: { type: 'i18n', zh_CN: '属性: addonBefore | 说明: 输入框前附加内容', en_US: 'prop: addonBefore | description: addonBefore', }, }, setter: 'StringSetter', }, { name: 'addonAfter', display: 'block', title: { label: { type: 'i18n', zh_CN: '输入框后附加内容', en_US: 'Addon After', }, tip: { type: 'i18n', zh_CN: '属性: addonAfter | 说明: 输入框后附加内容', en_US: 'prop: addonAfter | description: addonAfter', }, }, setter: 'StringSetter', }, { name: 'addonTextBefore', display: 'block', title: { label: { type: 'i18n', zh_CN: '输入框前附加文字', en_US: 'Text Before', }, tip: { type: 'i18n', zh_CN: '属性: addonTextBefore | 说明: 输入框前附加文字', en_US: 'prop: addonTextBefore | description: addonTextBefore', }, }, setter: 'StringSetter', }, { name: 'addonTextAfter', display: 'block', title: { label: { type: 'i18n', zh_CN: '输入框后附加文字', en_US: 'Text After', }, tip: { type: 'i18n', zh_CN: '属性: addonTextAfter | 说明: 输入框后附加文字', en_US: 'prop: addonTextAfter | description: addonTextAfter', }, }, setter: 'StringSetter', }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', }, ], }, ]); const meta = { componentName: 'FormInput', isFormItemComponent: true, title: '输入框', docUrl: '', screenshot: '', npm: { package: '@alifd/fusion-ui', version: '{{version}}', exportName: 'FormInput', main: '', destructuring: true, subName: '', }, configure: { props, supports: { style: true, events: ['onPressEnter', 'onClear', 'onChange', 'onKeyDown', 'onFocus', 'onBlur'], }, }, icon: '', category: '内容', }; export default meta; ================================================ FILE: packages/fusion-ui/lowcode/line-chart/meta.ts ================================================ import { IPublicTypeComponentMetadata, IPublicTypeSnippet } from '@alilc/lowcode-types'; import { actionConfigure } from '../common/chart-action'; import { plotConfigure } from '../common/chart-plot'; const LineChartMeta: IPublicTypeComponentMetadata = { componentName: 'LineChart', title: '折线图', category: '图表', group: '精选组件', docUrl: '', screenshot: '', devMode: 'proCode', npm: { package: '@alifd/fusion-ui', version: '0.1.3-beta.3', exportName: 'LineChart', main: 'lib/index.js', destructuring: true, subName: '', }, configure: { props: [ // 数据 { name: 'data', type: 'group', display: 'accordion', title: { label: '数据', }, items: [ { name: 'data', title: '图表数据', setter: 'JsonSetter', }, { name: 'xField', title: { label: 'x轴字段名', tip: 'x 方向映射对应的数据字段名', }, setter: 'StringSetter', }, { name: 'yField', title: { label: 'y轴字段名', tip: 'y 方向映射所对应的数据字段名', }, setter: 'StringSetter', }, ], }, // 图形属性 { name: '', type: 'group', display: 'accordion', title: { label: '图形属性', }, items: [ { name: 'color', title: '颜色', setter: 'ColorSetter', }, { name: 'lineSize', title: '粗细', setter: 'NumberSetter', }, { name: 'smooth', title: '平滑', setter: 'BoolSetter', }, { name: 'point.visible', title: '显示点', setter: 'BoolSetter', }, { name: 'label.visible', title: '显示标签', setter: 'BoolSetter', }, ], }, ...plotConfigure, ...actionConfigure, ], }, }; const snippets: IPublicTypeSnippet[] = [ { title: '折线图', screenshot: 'https://img.alicdn.com/imgextra/i2/O1CN01ChN5mm1txOQnh6kTh_!!6000000005968-55-tps-56-56.svg', schema: { componentName: 'LineChart', props: { data: [ { year: '1991', value: 72345678 }, { year: '1992', value: 4321132 }, { year: '1993', value: 33121112.5 }, { year: '1994', value: 45227221 }, { year: '1995', value: 4321221.9 }, { year: '1996', value: 6322121 }, { year: '1997', value: 78312213 }, { year: '1998', value: 4192312 }, { year: '1999', value: 6212332 }, { year: '2000', value: 3192312 }, ], xField: 'year', yField: 'value', color: '#0079f2', label: { visible: true, }, }, }, }, ]; export default { ...LineChartMeta, snippets }; ================================================ FILE: packages/fusion-ui/lowcode/month-picker/meta.js ================================================ export default { componentName: 'MonthPicker', title: 'MonthPicker', docUrl: '', screenshot: '', npm: { package: '@alifd/next', version: '{{version}}', exportName: 'DatePicker', main: '', destructuring: true, subName: 'MonthPicker', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'rtl', propType: 'bool', defaultValue: false, }, { name: 'label', propType: { type: 'instanceOf', value: 'node', }, description: '表单项内置标签', }, { name: 'state', propType: { type: 'oneOf', value: ['success', 'loading', 'error'], }, description: '表单项状态', }, { name: 'placeholder', propType: 'string', description: '输入提示', }, { name: 'defaultVisibleYear', propType: 'func', description: '默认展现的年\n@return {MomentObject} 返回包含指定年份的 moment 对象实例', }, { name: 'value', propType: { type: 'instanceOf', value: 'custom', }, description: '日期值(受控)moment 对象', }, { name: 'defaultValue', propType: { type: 'instanceOf', value: 'custom', }, description: '初始日期值,moment 对象', }, { name: 'format', propType: 'string', description: '日期值的格式(用于限定用户输入和展示)', defaultValue: 'YYYY-MM', }, { name: 'disabledDate', propType: 'func', description: '禁用日期函数\n@param {MomentObject} 日期值\n@param {String} view 当前视图类型,year: 年, month: 月, date: 日\n@return {Boolean} 是否禁用', }, { name: 'footerRender', propType: 'func', description: '自定义面板页脚\n@return {Node} 自定义的面板页脚组件', }, { name: 'onChange', propType: 'func', description: '日期值改变时的回调\n@param {MomentObject|String} value 日期值', }, { name: 'size', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '表单项尺寸', defaultValue: 'medium', }, { name: 'disabled', propType: 'bool', description: '是否禁用', }, { name: 'hasClear', propType: 'bool', description: '是否显示清空按钮', defaultValue: true, }, { name: 'visible', propType: 'bool', description: '弹层显示状态', }, { name: 'defaultVisible', propType: 'bool', description: '弹层默认是否显示', }, { name: 'onVisibleChange', propType: 'func', description: '弹层展示状态变化时的回调\n@param {Boolean} visible 弹层是否显示\n@param {String} type 触发弹层显示和隐藏的来源 calendarSelect 表示由日期表盘的选择触发; fromTrigger 表示由trigger的点击触发; docClick 表示由document的点击触发', }, { name: 'popupTriggerType', propType: { type: 'oneOf', value: ['click', 'hover'], }, description: '弹层触发方式', defaultValue: 'click', }, { name: 'popupAlign', propType: 'string', description: '弹层对齐方式, 具体含义见 OverLay文档', defaultValue: 'tl tl', }, { name: 'popupContainer', propType: 'any', description: '弹层容器\n@param {Element} target 目标元素\n@return {Element} 弹层的容器元素', }, { name: 'popupStyle', propType: 'object', description: '弹层自定义样式', }, { name: 'popupClassName', propType: 'string', description: '弹层自定义样式类', }, { name: 'popupProps', propType: 'object', description: '弹层其他属性', }, { name: 'followTrigger', propType: 'bool', description: '是否跟随滚动', }, { name: 'inputProps', propType: 'object', description: '表单项其他属性', }, { name: 'monthCellRender', propType: 'func', description: '自定义月份渲染函数\n@param {Object} calendarDate 对应 Calendar 返回的自定义日期对象\n@returns {ReactNode}', }, { name: 'yearCellRender', propType: 'func', }, { name: 'dateInputAriaLabel', propType: 'string', description: '日期表单项的 aria-label 属性', }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', }, { name: 'renderPreview', propType: 'func', description: '预览态模式下渲染的内容\n@param {MomentObject} value 月份', }, { name: 'locale', propType: 'object', }, { name: 'className', propType: 'string', }, { name: 'name', propType: 'string', }, { name: 'popupComponent', propType: { type: 'instanceOf', value: 'elementType', }, }, { name: 'popupContent', propType: { type: 'instanceOf', value: 'node', }, }, { name: 'style', propType: 'object', }, ], configure: { props: [], }, category: '基础', }; ================================================ FILE: packages/fusion-ui/lowcode/number-picker/meta.ts ================================================ import { wrapFormItemProps } from '../utils/form-utils'; export default { componentName: 'FormNumberPicker', isFormItemComponent: true, title: '数字表单项', docUrl: '', screenshot: '', npm: { package: '@alifd/fusion-ui', version: '{{version}}', exportName: 'FormNumberPicker', main: '', destructuring: true, subName: '', }, props: [ { name: 'size', propType: { type: 'oneOf', value: ['large', 'medium'], }, description: '大小', defaultValue: 'medium', }, { name: 'type', propType: { type: 'oneOf', value: ['normal', 'inline'], }, description: '设置类型', defaultValue: 'normal', }, { name: 'value', propType: 'number', description: '当前值', }, { name: 'defaultValue', propType: 'number', description: '默认值', }, { name: 'disabled', propType: 'bool', description: '是否禁用', }, { name: 'step', propType: 'number', description: '步长', defaultValue: 1, }, { name: 'precision', propType: 'number', description: '保留小数点后位数', defaultValue: 0, }, { name: 'editable', propType: 'bool', description: '用户是否可以输入', defaultValue: true, }, { name: 'autoFocus', propType: 'bool', description: '自动焦点', }, { name: 'max', propType: 'number', description: '最大值', defaultValue: null, }, { name: 'min', propType: 'number', description: '最小值', defaultValue: null, }, { name: 'format', propType: 'func', description: '格式化当前值', }, { name: 'upBtnProps', propType: 'object', description: '增加按钮的props', }, { name: 'downBtnProps', propType: 'object', description: '减少按钮的props', }, { name: 'label', propType: 'string', description: '内联 label', }, { name: 'innerAfter', propType: { type: 'oneOfType', value: ['string', 'icon'], }, description: 'inner after', }, { name: 'rtl', propType: 'bool', }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', }, { name: 'renderPreview', propType: 'func', description: '预览态模式下渲染的内容\n@param {number} value 评分值', }, { name: 'onChange', propType: 'func', description: '数值被改变的事件\n@param {Number} value 数据\n@param {Event} e DOM事件对象', }, { name: 'onKeyDown', propType: 'func', description: '键盘按下', }, { name: 'onFocus', propType: 'func', description: '焦点获得', }, { name: 'onBlur', propType: 'func', description: '焦点失去', }, { name: 'onCorrect', propType: 'func', description: '数值订正后的回调\n@param {Object} obj {currentValue,oldValue:String}', }, { name: 'onDisabled', propType: 'func', }, { name: 'className', propType: 'string', description: '自定义class', }, { name: 'style', propType: 'object', description: '自定义内联样式', }, ], configure: { props: wrapFormItemProps([ { name: 'alwaysShowTrigger', title: '展示操作', setter: 'BoolSetter', defaultValue: true, }, { name: 'value', title: '当前值', setter: ['NumberSetter', 'ExpressionSetter'], }, { name: 'defaultValue', title: '默认值', setter: ['NumberSetter', 'ExpressionSetter'], }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 尺寸\n@enumdesc 小, 中, 大', en_US: 'prop: size | description: size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['small', 'medium', 'large'], }, }, defaultValue: 'medium', }, { name: 'type', title: '类型', defaultValue: 'normal', setter: { componentName: 'MixedSetter', props: { setters: [ { componentName: 'RadioGroupSetter', props: { options: [ { title: '普通', value: 'normal' }, { title: '内联', value: 'inline' }, ], }, }, 'ExpressionSetter', ], }, }, }, { name: 'innerAfter', title: '单位', setter: ['StringSetter', 'ExpressionSetter'], }, { name: 'step', title: '步长', defaultValue: 1, setter: ['NumberSetter', 'ExpressionSetter'], }, { name: 'precision', title: '小数位数', defaultValue: 0, setter: ['NumberSetter', 'ExpressionSetter'], }, { name: 'max', title: '最大值', setter: ['NumberSetter', 'ExpressionSetter'], }, { name: 'min', title: '最小值', setter: ['NumberSetter', 'ExpressionSetter'], }, { name: 'editable', title: '可以输入', defaultValue: true, setter: ['BoolSetter', 'ExpressionSetter'], }, { name: 'format', title: '格式化', display: 'block', setter: { componentName: 'FunctionSetter', // props: { // defaultActionName="format", // defaultCode=`function format(value) { // return value; // }`, // } }, }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', }, ], }, { name: 'style', setter: { componentName: 'StyleSetter', }, }, ]), supports: { events: ['onChange', 'onKeyDown', 'onFocus', 'onBlur', 'onCorrect'], }, }, icon: '', category: '内容', }; ================================================ FILE: packages/fusion-ui/lowcode/page-header/common/props.ts ================================================ import { FieldConfig } from '@ali/lowcode-types'; const props: FieldConfig[] = [ { name: 'title', title: '标题', setter: 'StringSetter', }, { name: 'subTitle', title: '子标题', setter: 'StringSetter', }, { name: 'backIcon', title: '返回图标', setter: { componentName: 'IconSetter', }, }, { name: 'showAvatar', title: '头像', setValue: (target, value) => { return target.getProps().setPropValue('avatar', value || null); }, setter: { componentName: 'BoolSetter', }, }, { name: 'showBreadcrumb', title: '面包屑', setValue: (target, value) => { return target.getProps().setPropValue('breadcrumb', value ? ['首页', '列表'] : null); }, defaultValue: true, setter: { componentName: 'BoolSetter', }, }, { name: 'showActions', title: '操作区', defaultValue: false, setter: { componentName: 'BoolSetter', }, }, { name: 'avatar', type: 'group', display: 'accordion', condition: (target) => { const _avatar = target.getProps().getPropValue('showAvatar'); return !!_avatar; }, title: { label: '头像', }, items: [ { name: 'avatar.icon', title: { label: { type: 'i18n', zh_CN: '图标', en_US: 'Icon', }, tip: { type: 'i18n', zh_CN: '属性: icon | 说明: 图标类型', en_US: 'prop: icon | description: icon type', }, }, setter: { componentName: 'IconSetter', }, }, { name: 'avatar.children', title: { label: { type: 'i18n', zh_CN: '文本内容', en_US: 'Content', }, tip: { type: 'i18n', zh_CN: '属性: children | 说明: 文本内容', en_US: 'prop: children | description: avatar content', }, }, setter: 'StringSetter', }, { name: 'avatar.size', title: { label: { type: 'i18n', zh_CN: '头像尺寸', en_US: 'Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 头像的大小', en_US: 'prop: size | description: avatar size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['small', 'medium', 'large'], }, }, defaultValue: 'medium', }, { name: 'avatar.shape', title: { label: { type: 'i18n', zh_CN: '头像形状', en_US: 'Shape', }, tip: { type: 'i18n', zh_CN: '属性: shape | 说明: 头像的形状', en_US: 'prop: shape | description: avatar shape', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['circle', 'square'], }, }, defaultValue: 'circle', }, { name: 'avatar.src', title: { label: { type: 'i18n', zh_CN: '头像地址', en_US: 'Src', }, tip: { type: 'i18n', zh_CN: '属性: src | 说明: 图片类头像的资源地址', en_US: 'prop: src | description: resource address', }, }, setter: 'StringSetter', }, ], }, { name: 'breadcrumb', title: '面包屑', condition: (target) => { const _breadcrumbTarget = target.getProps().get('showBreadcrumb'); const _breadcrumbValue = _breadcrumbTarget.getValue(); const _breadcrumbDefaultValue = _breadcrumbTarget.getDefaultValue(); if (_breadcrumbValue === undefined && _breadcrumbDefaultValue) { return _breadcrumbDefaultValue; } else { return !!_breadcrumbValue; } }, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'StringSetter', initialValue: '首页', }, }, }, }, ]; export default props; ================================================ FILE: packages/fusion-ui/lowcode/page-header/meta.design.js ================================================ const props = require('./common/props'); module.exports = { componentName: 'PageHeader', title: '设计态 PageHeader', docUrl: '', screenshot: '', devMode: 'proCode', npm: { package: '@alifd/fusion-ui', version: '1.0.0', exportName: 'PageHeader', main: 'lib/index.js', destructuring: true, subName: '', }, props: [ { name: 'backIcon', propType: 'node', }, { name: 'prefixCls', propType: 'string', }, { name: 'title', propType: 'node', }, { name: 'subTitle', propType: 'node', }, { name: 'style', propType: 'object', }, { name: 'breadcrumb', propType: { type: 'oneOfType', value: ['object'], }, }, { name: 'breadcrumbRender', propType: { type: 'func', params: [ { name: 'props', propType: { type: 'shape', value: [ { name: 'backIcon', propType: 'node', }, { name: 'prefixCls', propType: 'string', }, { name: 'title', propType: 'node', }, { name: 'subTitle', propType: 'node', }, { name: 'style', propType: 'object', }, { name: 'breadcrumb', propType: { type: 'oneOfType', value: ['object'], }, }, { name: 'breadcrumbRender', propType: 'object', }, { name: 'tags', propType: { type: 'oneOfType', value: [ 'object', { type: 'arrayOf', value: 'object', }, ], }, }, { name: 'footer', propType: 'node', }, { name: 'extra', propType: 'node', }, { name: 'avatar', propType: 'object', }, { name: 'onBack', propType: { type: 'func', params: [ { name: 'e', propType: 'object', }, ], raw: '(e?: MouseEvent) => void', }, }, { name: 'className', propType: 'string', }, { name: 'ghost', propType: 'bool', }, ], }, }, { name: 'defaultDom', propType: 'node', }, ], raw: '(props: PageHeaderProps, defaultDom: ReactNode) => ReactNode', }, }, { name: 'tags', propType: { type: 'oneOfType', value: [ 'object', { type: 'arrayOf', value: 'object', }, ], }, }, { name: 'footer', propType: 'node', }, { name: 'extra', propType: 'node', }, { name: 'avatar', propType: 'object', }, { name: 'onBack', propType: { type: 'func', params: [ { name: 'e', propType: 'object', }, ], raw: '(e?: MouseEvent) => void', }, }, { name: 'className', propType: 'string', }, { name: 'ghost', propType: 'bool', }, ], configure: { component: { isContainer: true, }, props, }, snippets: [ { title: 'PageHeader', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_message.png', schema: { title: 'PageHeader', componentName: 'PageHeader', props: { placeholderStyle: { height: '38px', color: '#0088FF', background: '#d8d8d836', border: 0, }, placeholder: '', title: 'This is a designer title', subTitle: '', breadcrumb: ['首页', '列表'], }, }, }, ], }; ================================================ FILE: packages/fusion-ui/lowcode/page-header/meta.ts ================================================ import { ComponentMetadata, Snippet } from '@ali/lowcode-types'; import { operations } from '../common'; import props from './common/props'; const PageHeaderMeta: ComponentMetadata = { componentName: 'PageHeader', category: '布局容器类', group: '精选组件', title: '页头', docUrl: '', icon: 'https://img.alicdn.com/imgextra/i2/O1CN01q3ZRHx24rrQ9ysyU8_!!6000000007445-55-tps-56-56.svg', devMode: 'procode', npm: { package: '@alifd/fusion-ui', version: '1.0.0', exportName: 'PageHeader', main: 'lib/index.js', destructuring: true, subName: '', }, props: [ { name: 'backIcon', propType: 'node', }, { name: 'prefixCls', propType: 'string', }, { name: 'title', propType: 'node', }, { name: 'subTitle', propType: 'node', }, { name: 'style', propType: 'object', }, { name: 'breadcrumb', propType: { type: 'oneOfType', value: ['object'], }, }, { name: 'breadcrumbRender', propType: { type: 'func', params: [ { name: 'props', propType: { type: 'shape', value: [ { name: 'backIcon', propType: 'node', }, { name: 'prefixCls', propType: 'string', }, { name: 'title', propType: 'node', }, { name: 'subTitle', propType: 'node', }, { name: 'style', propType: 'object', }, { name: 'breadcrumb', propType: { type: 'oneOfType', value: ['object'], }, }, { name: 'breadcrumbRender', propType: 'object', }, { name: 'tags', propType: { type: 'oneOfType', value: [ 'object', { type: 'arrayOf', value: 'object', }, ], }, }, { name: 'footer', propType: 'node', }, { name: 'extra', propType: 'node', }, { name: 'avatar', propType: 'object', }, { name: 'onBack', propType: { type: 'func', params: [ { name: 'e', propType: 'object', }, ], raw: '(e?: MouseEvent) => void', }, }, { name: 'className', propType: 'string', }, { name: 'ghost', propType: 'bool', }, ], }, }, { name: 'defaultDom', propType: 'node', }, ], raw: '(props: PageHeaderProps, defaultDom: ReactNode) => ReactNode', }, }, { name: 'tags', propType: { type: 'oneOfType', value: [ 'object', { type: 'arrayOf', value: 'object', }, ], }, }, { name: 'footer', propType: 'node', }, { name: 'extra', propType: 'node', }, { name: 'avatar', propType: 'object', }, { name: 'onBack', propType: { type: 'func', params: [ { name: 'e', propType: 'object', }, ], raw: '(e?: MouseEvent) => void', }, }, { name: 'className', propType: 'string', }, { name: 'ghost', propType: 'bool', }, ], configure: { component: { isContainer: false, }, props: [ ...props, Object.assign({}, operations, { condition: (target) => { const showAction = target.getProps().getPropValue('showActions'); return !!showAction; }, }), ], }, }; const snippets: Snippet[] = [ { title: '页头', screenshot: 'https://img.alicdn.com/imgextra/i2/O1CN01q3ZRHx24rrQ9ysyU8_!!6000000007445-55-tps-56-56.svg', schema: { componentName: 'PageHeader', title: '页头', props: { title: 'This is a designer title', subTitle: '', breadcrumb: ['首页', '列表'], operations: [ { content: '自定义', action: 'custom', type: 'secondary', }, { content: '自定义', action: 'custom', type: 'secondary', }, ], }, }, }, ]; export default { ...PageHeaderMeta, snippets, }; ================================================ FILE: packages/fusion-ui/lowcode/pie-chart/meta.ts ================================================ import { IPublicTypeComponentMetadata, IPublicTypeConfigure } from '@alilc/lowcode-types'; import { actionConfigure } from '../common/chart-action'; import { plotConfigure } from '../common/chart-plot'; const pieChartMeta: IPublicTypeComponentMetadata = { componentName: 'PieChart', title: '饼图', category: '图表', group: '精选组件', docUrl: '', screenshot: '', devMode: 'proCode', npm: { package: '@alifd/fusion-ui', version: '0.1.3-beta.3', exportName: 'PieChart', main: 'lib/index.js', destructuring: true, subName: '', }, configure: { props: [ // 图例 { name: 'legend', type: 'group', display: 'accordion', title: { label: '图例', }, items: [ { name: 'legend.position', title: '位置', setter: { componentName: 'SelectSetter', props: { options: [ { title: '左', value: 'left' }, { title: '左上', value: 'left-top' }, { title: '左下', value: 'left-bottom' }, { title: '右', value: 'right' }, { title: '右上', value: 'right-top' }, { title: '右下', value: 'right-bottom' }, { title: '上', value: 'top' }, { title: '上左', value: 'top-left' }, { title: '上右', value: 'top-right' }, { title: '下', value: 'bottom' }, { title: '下左', value: 'bottom-left' }, { title: '下右', value: 'bottom-right' }, ], }, }, }, ], }, // 数据 { name: 'data', type: 'group', display: 'accordion', title: { label: '数据', }, items: [ { name: 'data', title: '图表数据', setter: 'JsonSetter', }, { name: 'angleField', title: { label: '值字段名', tip: '扇形切片大小(弧度)所对应的数据字段名', }, setter: 'StringSetter', }, { name: 'colorField', title: { label: '分类字段名', tip: '扇形颜色映射对应的数据字段名', }, setter: 'StringSetter', }, ], }, // 图形属性 { name: '', type: 'group', display: 'accordion', title: { label: '图形属性', }, items: [ { name: 'color', title: '颜色', setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ColorSetter', initialValue: '#0079f2', }, }, }, }, { name: 'label', type: 'group', display: 'accordion', title: { label: '标签', }, items: [ { name: 'label.visible', title: '显示', setter: 'BoolSetter', }, { name: 'label.type', title: '位置', setter: { componentName: 'SelectSetter', props: { options: [ { title: '内部', value: 'inner' }, { title: '外部', value: 'outer' }, { title: '外部圆形排布', value: 'outer-center' }, { title: '蜘蛛布局', value: 'spider' }, ], }, }, }, ], }, ...plotConfigure, ...actionConfigure, ], }, ], }, }; const snippets = [ { title: '饼图', name: 'PieChart', screenshot: 'https://img.alicdn.com/imgextra/i4/O1CN018rBRGK24fx7hzkITN_!!6000000007419-55-tps-56-56.svg', schema: { componentName: 'PieChart', title: '饼图', props: { legend: { position: 'top-left', }, data: [ { year: '1991', value: 72345678 }, { year: '1992', value: 4321132 }, { year: '1993', value: 33121112.5 }, { year: '1994', value: 45227221 }, { year: '1995', value: 4321221.9 }, { year: '1996', value: 6322121 }, { year: '1997', value: 78312213 }, { year: '1998', value: 2192312 }, { year: '1999', value: 6212332 }, { year: '2000', value: 1192312 }, ], angleField: 'value', colorField: 'year', label: { visible: true, type: 'spider', }, color: ['#3BCBD1', '#47A4FE', '#EDBA42', '#F4704E', '#ED6899', '#7F62C3', '#6E7BC9'], }, }, }, ]; export default { ...pieChartMeta, snippets }; ================================================ FILE: packages/fusion-ui/lowcode/pro-dialog/meta.ts ================================================ import { ComponentMetadata, Snippet } from '@ali/lowcode-types'; import { hideProp } from '../utils'; import { operationProps } from '../common'; const ProDialogMeta: ComponentMetadata = { componentName: 'ProDialog', title: '对话框', group: '精选组件', docUrl: '', screenshot: 'https://img.alicdn.com/imgextra/i1/O1CN01n5JLZG1aBmYZlckSx_!!6000000003292-55-tps-56-56.svg', devMode: 'proCode', npm: { package: '@alifd/fusion-ui', version: '0.1.6-beta.23', exportName: 'ProDialog', main: 'lib/index.js', destructuring: true, subName: '', }, configure: { component: { isContainer: true, isModal: true, rootSelector: 'div.next-dialog', nestingRule: { parentWhitelist: ['Page'], }, }, props: [ { name: 'ref', condition: hideProp, setter: (target) => { if (!target?.getValue()) { target?.setValue(`pro-dialog-${target?.id}`); } return 'StringSetter'; }, }, { name: 'dialogType', title: '弹窗类型', defaultValue: 'normal', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '提示弹窗', value: 'notice', }, { title: '普通弹窗', value: 'normal', }, ], }, }, }, { name: 'status', title: '提示状态', condition: (target) => { return target.getProps().getPropValue('dialogType') === 'notice'; }, defaultValue: 'success', setter: { componentName: 'SelectSetter', props: { options: [ { title: '提醒', value: 'notice', }, { title: '警告', value: 'warning', }, { title: '确认', value: 'help', }, { title: '成功', value: 'success', }, { title: '失败', value: 'error', }, { title: '加载中', value: 'loading', }, ], }, }, }, { name: 'title', title: '标题', setter: () => { const hasTitleSetter = AliLowCodeEngine.setters.getSetter('TitleSetter'); return hasTitleSetter ? { componentName: 'TitleSetter', props: { defaultChecked: true, }, } : 'StringSetter'; }, defaultValue: 'Title', }, { name: 'size', title: '弹窗尺寸', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '大', value: 'large', }, { title: '中', value: 'medium', }, { title: '小', value: 'small', }, ], }, }, }, { name: 'visible', title: '默认显示', setter: 'BoolSetter', defaultValue: false, }, { name: 'hasTips', title: '提示信息', setter: 'BoolSetter', defaultValue: false, }, { name: 'iconType', title: '提示图标', setter: { componentName: 'IconSetter', }, condition: (target) => { const showExplanation = target.getProps().getPropValue('hasTips'); return !!showExplanation; }, }, { name: 'explanation', title: '解释文案', setter: { componentName: 'StringSetter', }, condition: (target) => { const showExplanation = target.getProps().getPropValue('hasTips'); return !!showExplanation; }, }, { name: 'hasMask', title: '显示遮罩', setter: 'BoolSetter', defaultValue: true, }, { name: 'closeMode', title: '关闭方式', setter: { componentName: 'SelectSetter', props: { mode: 'tag', options: [ { title: '点击按钮', value: 'close', }, { title: '点击遮罩', value: 'mask', }, { title: 'ESC', value: 'esc', }, ], }, }, defaultValue: ['close'], }, { name: 'autoFocus', title: '自动聚焦', setter: 'BoolSetter', defaultValue: false, }, ...operationProps, { name: 'buttons', title: '底部按钮配置', type: 'group', condition: hideProp, extraProps: { display: 'block', }, items: [ { name: 'footer', title: '是否显示', setter: 'BoolSetter', initialValue: true, }, { name: 'footerAlign', title: '对齐方式', initialValue: 'right', condition: (target) => { return target.getProps().getPropValue('footer'); }, setter: { componentName: 'RadioGroupSetter', initialValue: 'right', props: { options: [ { title: 'left', value: 'left', }, { title: 'center', value: 'center', }, { title: 'right', value: 'right', }, ], }, }, }, { name: 'footerActions', title: '排列方式', initialValue: ['ok', 'cancel'], condition: (target) => { return target.getProps().getPropValue('footer'); }, setter: { componentName: 'SelectSetter', initialValue: ['ok', 'cancel'], props: { options: [ { title: 'ok, cancel', value: ['ok', 'cancel'], }, { title: 'cancel, ok', value: ['cancel', 'ok'], }, { title: 'cancel', value: ['cancel'], }, { title: 'ok', value: ['ok'], }, ], }, }, }, ], }, ], supports: { events: ['onOk', 'onCancel', 'onClose'], style: true, }, advanced: { callbacks: { // 与 next-page 的 onNodeAdd 一模一样 onNodeAdd: (dragment, currentNode) => { // 拖入的组件为 P、Block、Slot(把NextPage拖入到面板里时,NextPage的Slot也会触发onNodeAdd事件) 时,不进行包裹 // 拖入的组件 isModal为true时(例如drawer dialog 这类有单独组件树结构的),不进行包裹 if ( !dragment || ['NextP', 'NextBlock', 'Slot'].includes(dragment.componentName) || (dragment.componentMeta.isModal && dragment.componentMeta.isModal()) ) { console.log( `[${dragment.componentName}] doesn \\'n need to wrap with NextBlock > NextBlockCell`, ); return; } const NextPProps = { wrap: false, type: 'body2', verAlign: 'middle', textSpacing: true, align: 'left', }; if ( [ 'Form', 'ResponsiveGrid', 'Box', 'Card', 'List', 'Message', 'Slider', 'NextTable', ].includes(dragment.componentName) || dragment.getPropValue('isFillContainer') ) { NextPProps.full = true; } const layoutPSchema = { componentName: 'NextP', title: '段落', props: NextPProps, children: [dragment.exportSchema()], }; // 为目标元素包裹一层 Block const layoutBlockNode = (len) => currentNode.document.createNode({ componentName: 'NextBlock', title: '区块', props: { childTotalColumns: len || 12, }, children: [ { componentName: 'NextBlockCell', title: '子区块', props: { isAutoContainer: true, colSpan: 12, rowSpan: 1, }, children: [layoutPSchema], }, ], }); const { dropLocation } = dragment.document.canvas; if (!dropLocation) { // 没有 dropLocation 一般是 slot, slot 元素不用特殊处理 不做任何包裹 return; } const dropTarget = dropLocation.target; const dropTargetName = dropLocation.target.componentName || ''; // 找到要拖入进去的节点 ID const targetId = (dropLocation && dropLocation.target.id) || ''; // 找到要拖入进去的节点 const slotTarget = currentNode.slots.length > 0 && currentNode.slots.find((item) => item.id === targetId); const layoutPNode = currentNode.document.createNode(layoutPSchema); // 是否为 aside slot const isAsideSlot = slotTarget && ['aside'].indexOf(slotTarget._slotFor.key) > -1; // 是否为需要被 P 包裹的 Slot const isNeedPSlot = slotTarget && ['header', 'footer', 'nav'].indexOf(slotTarget._slotFor.key) > -1; const wrapWithBlock = (curDragMent, node, curDropTargetName, blockLen) => { setTimeout(() => { console.log( `[${curDragMent.componentName}] to [${curDropTargetName}] need to wrap with NextBlock > NextBlockCell > NextP [from NextPage2]`, ); const newNode = node.document.createNode(layoutBlockNode(blockLen).exportSchema()); node.insertBefore(newNode, curDragMent, false); curDragMent.remove(false); newNode.children.get(0).children.get(0).children.get(0).select(); }, 1); }; const wrapWithP = (curDragMent, node, curDropTargetName) => { setTimeout(() => { // const dragmentTarget = dropTarget; // 要拖入的地方如果是 NextP 那就 不再自动包裹 P了 if (dropTargetName === 'NextP') { console.log( `[${curDragMent.componentName}] to [${curDropTargetName}] does't need to wrap with NextP. [from NextPage3]`, ); return; } console.log( `[${curDragMent.componentName}] to [${dropTargetName}] need to wrap with NextP [from NextPage3]`, ); const newNode = node.document.createNode(Object.assign(layoutPNode.exportSchema())); node.insertBefore(newNode, curDragMent, false); curDragMent.remove(false); newNode.children.get(0).select(); }, 1); }; // 需要包裹 Block BlockCell P 的情况: // 1. 组件拖入到 NextPage,的直接子元素下(不包括slot), 此时Block宽度为12 if (['NextPage'].includes(dropTargetName) && currentNode.children.has(dragment)) { wrapWithBlock(dragment, currentNode, dropTargetName, 12); // 需要包裹 Block BlockCell P 的情况: // 2. 组件拖入到 NextPage 的 aside slot, 的直接子元素下 (不包括slot下的进一步内容),此时Block宽度为1 } else if (isAsideSlot && slotTarget && slotTarget.children.has(dragment)) { wrapWithBlock(dragment, slotTarget, dropTargetName, 1); // 需要包裹 P 的情况: // 1. 如果是处于,开启了自然布局模式的容器组件中 (或者Tab里) // 这里的Tab主要是给纪元epoch使用的,因为他们用到了 @ali/vc-deep 的TabLayout组件,没办法在这个组件上再增加属性 isAutoContainer } else if (dropTarget.getPropValue('isAutoContainer') || dropTargetName === 'Tab.Item') { wrapWithP(dragment, dropTarget, dropTargetName); // 需要包裹 P 的情况: // 2. 如果是处于,Page 的 nav header footer 中 } else if (isNeedPSlot && slotTarget) { wrapWithP(dragment, slotTarget, dropTargetName); } // 其他维持原状,不进行其他设置 }, }, }, }, icon: 'https://img.alicdn.com/imgextra/i1/O1CN01n5JLZG1aBmYZlckSx_!!6000000003292-55-tps-56-56.svg', category: '布局容器类', }; const snippets: Snippet[] = [ { title: '高级对话框', screenshot: 'https://img.alicdn.com/imgextra/i1/O1CN01n5JLZG1aBmYZlckSx_!!6000000003292-55-tps-56-56.svg', schema: { componentName: 'ProDialog', props: { status: 'success', size: 'medium', prefix: 'next-', footerAlign: 'right', title: 'Title', closeMode: ['esc', 'close'], hasMask: true, align: 'cc cc', minMargin: 40, isAutoContainer: true, visible: true, iconType: 'prompt', explanation: '提示文案', operationConfig: { align: 'right', }, operations: [ { action: 'ok', type: 'primary', content: '确认', }, { action: 'cancel', type: 'normal', content: '取消', }, ], }, }, }, ]; export default { ...ProDialogMeta, snippets, }; ================================================ FILE: packages/fusion-ui/lowcode/pro-drawer/meta.ts ================================================ import { hideProp } from '../utils'; import { operationProps } from '../common'; const wrapWithBlock = (dragment, node, dropTargetName, blockLen, layoutBlockNode) => { setTimeout(() => { console.log( `[${dragment.componentName}] to [${dropTargetName}] need to wrap with NextBlock > NextBlockCell > NextP [from NextPage2]`, ); const newNode = node.document.createNode(layoutBlockNode(blockLen).exportSchema()); node.insertBefore(newNode, dragment, false); dragment.remove(false); newNode.children.get(0).children.get(0).children.get(0).select(); }, 1); }; const wrapWithP = (dragment, node, dropTargetName, layoutPNode) => { setTimeout(() => { // const dragmentTarget = dropTarget; // 要拖入的地方如果是 NextP 那就 不再自动包裹 P了 if (dropTargetName === 'NextP') { console.log( `[${dragment.componentName}] to [${dropTargetName}] does't need to wrap with NextP. [from NextPage3]`, ); return; } console.log( `[${dragment.componentName}] to [${dropTargetName}] need to wrap with NextP [from NextPage3]`, ); const newNode = node.document.createNode(Object.assign(layoutPNode.exportSchema())); node.insertBefore(newNode, dragment, false); dragment.remove(false); newNode.children.get(0).select(); }, 1); }; const meta = { componentName: 'Drawer', title: '抽屉', group: '精选组件', docUrl: '', screenshot: '', npm: { package: '@alifd/fusion-ui', version: '0.1.6-beta.23', exportName: 'ProDrawer', main: 'lib/index.js', destructuring: true, subName: '', }, configure: { component: { isContainer: true, isModal: true, rootSelector: '.next-drawer', nestingRule: { parentWhitelist: (testNode) => { return testNode.componentName === 'Page'; }, }, }, props: [ { name: 'ref', condition: hideProp, setter: (target) => { if (!target?.getValue()) { target?.setValue(`pro-drawer-${target?.id}`); } return 'StringSetter'; }, }, { name: 'title', title: { label: { type: 'i18n', zh_CN: '标题', en_US: 'Title', }, tip: { type: 'i18n', zh_CN: '属性: title | 说明: 标题', en_US: 'prop: title | description: title', }, }, setter: { componentName: 'StringSetter', }, description: '标题', }, { name: 'titleTip.enable', title: '标题提示', condition: (target) => { console.log('title: ', target.getProps().getPropValue('title')); return !!target.getProps().getPropValue('title'); }, setter: { componentName: 'BoolSetter', }, }, { name: 'titleTip.content', condition: (target) => { return target.getProps().getPropValue('titleTip.enable') === true; }, title: '提示内容', setter: { componentName: 'StringSetter', }, }, { name: 'titleTip.icon', condition: (target) => { return target.getProps().getPropValue('titleTip.enable') === true; }, title: '提示图标', setter: { componentName: 'IconSetter', }, }, { name: 'width', condition: hideProp, title: { label: { type: 'i18n', zh_CN: '宽度', en_US: 'width', }, tip: { type: 'i18n', zh_CN: '属性: width | 说明: 宽度', en_US: 'prop: width | description: 仅在 placement是 left right 的时候生效', }, }, setter: { componentName: 'NumberSetter', }, description: '宽度,仅在 placement是 left right 的时候生效', }, { name: 'height', condition: hideProp, title: { label: { type: 'i18n', zh_CN: '高度', en_US: 'height', }, tip: { type: 'i18n', zh_CN: '属性: height | 说明: 高度', en_US: 'prop: height | description: 仅在 placement是 top bottom 的时候生效', }, }, setter: { componentName: 'NumberSetter', }, description: '高度,仅在 placement是 top bottom 的时候生效', }, { name: 'placement', title: { label: { type: 'i18n', zh_CN: '弹出位置', en_US: 'height', }, tip: { type: 'i18n', zh_CN: '属性: placement | 说明: 位于页面的位置', en_US: 'prop: placement | description: drawer placement', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '上', value: 'top', }, { title: '右', value: 'right', }, { title: '下', value: 'bottom', }, { title: '左', value: 'left', }, ], }, }, description: '位于页面的位置', defaultValue: 'right', }, { name: 'size', title: '尺寸', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '大', value: 'large', }, { title: '中', value: 'medium', }, { title: '小', value: 'small', }, ], }, }, }, { name: 'visible', title: { label: { type: 'i18n', zh_CN: '默认显示', en_US: 'visible', }, tip: { type: 'i18n', zh_CN: '属性: visible | 说明: 默认显示', en_US: 'prop: visible | description: drawer visible', }, }, setter: 'BoolSetter', }, { name: 'hasMask', title: { label: { type: 'i18n', zh_CN: '显示遮罩', en_US: 'hasMask', }, tip: { type: 'i18n', zh_CN: '属性: hasMask | 说明: 是否显示遮罩', en_US: 'prop: hasMask | description: drawer hasMask', }, }, setter: { componentName: 'BoolSetter', }, description: '是否显示遮罩', defaultValue: true, }, { name: 'closeMode', title: '关闭方式', setter: { componentName: 'SelectSetter', props: { mode: 'multiple', options: [ { title: '点击按钮', value: 'close', }, { title: '点击遮罩', value: 'mask', }, { title: 'ESC', value: 'esc', }, ], }, }, defaultValue: ['close'], }, ...operationProps, ], }, advanced: { callbacks: { // 与 next-page 的 onNodeAdd 一模一样 onNodeAdd: (dragment, currentNode) => { // 拖入的组件为 P、Block、Slot(把NextPage拖入到面板里时,NextPage的Slot也会触发onNodeAdd事件) 时,不进行包裹 // 拖入的组件 isModal为true时(例如drawer dialog 这类有单独组件树结构的),不进行包裹 if ( !dragment || ['NextP', 'NextBlock', 'Slot'].includes(dragment.componentName) || (dragment.componentMeta.isModal && dragment.componentMeta.isModal()) ) { console.log( `[${dragment.componentName}] does not need to wrap with NextBlock > NextBlockCell`, ); return; } const NextPProps = { wrap: false, type: 'body2', verAlign: 'middle', textSpacing: true, align: 'left', }; if ( [ 'Form', 'ResponsiveGrid', 'Box', 'Card', 'List', 'Message', 'Slider', 'NextTable', ].includes(dragment.componentName) || dragment.getPropValue('isFillContainer') ) { NextPProps.full = true; } const layoutPSchema = { componentName: 'NextP', title: '段落', props: NextPProps, children: [dragment.exportSchema()], }; // 为目标元素包裹一层 Block const layoutBlockNode = (len) => currentNode.document.createNode({ componentName: 'NextBlock', title: '区块', props: { childTotalColumns: len || 12, }, children: [ { componentName: 'NextBlockCell', title: '子区块', props: { isAutoContainer: true, colSpan: 12, rowSpan: 1, }, children: [layoutPSchema], }, ], }); const { dropLocation } = dragment.document.canvas; if (!dropLocation) { // 没有 dropLocation 一般是 slot, slot 元素不用特殊处理 不做任何包裹 return; } const dropTarget = dropLocation.target; const dropTargetName = dropLocation.target.componentName || ''; // 找到要拖入进去的节点 ID const targetId = (dropLocation && dropLocation.target.id) || ''; // 找到要拖入进去的节点 const slotTarget = currentNode.slots.length > 0 && currentNode.slots.find((item) => item.id === targetId); const layoutPNode = currentNode.document.createNode(layoutPSchema); // 是否为 aside slot const isAsideSlot = slotTarget && ['aside'].indexOf(slotTarget._slotFor.key) > -1; // 是否为需要被 P 包裹的 Slot const isNeedPSlot = slotTarget && ['header', 'footer', 'nav'].indexOf(slotTarget._slotFor.key) > -1; // 需要包裹 Block BlockCell P 的情况: // 1. 组件拖入到 NextPage,的直接子元素下(不包括slot), 此时Block宽度为12 if (['NextPage'].includes(dropTargetName) && currentNode.children.has(dragment)) { wrapWithBlock(dragment, currentNode, dropTargetName, 12, layoutBlockNode); // 需要包裹 Block BlockCell P 的情况: // 2. 组件拖入到 NextPage 的 aside slot, 的直接子元素下 (不包括slot下的进一步内容),此时Block宽度为1 } else if (isAsideSlot && slotTarget && slotTarget.children.has(dragment)) { wrapWithBlock(dragment, slotTarget, dropTargetName, 1, layoutBlockNode); // 需要包裹 P 的情况: // 1. 如果是处于,开启了自然布局模式的容器组件中 (或者Tab里) // 这里的Tab主要是给纪元epoch使用的,因为他们用到了 @ali/vc-deep 的TabLayout组件,没办法在这个组件上再增加属性 isAutoContainer } else if (dropTarget.getPropValue('isAutoContainer') || dropTargetName === 'Tab.Item') { wrapWithP(dragment, dropTarget, dropTargetName, layoutPNode); // 需要包裹 P 的情况: // 2. 如果是处于,Page 的 nav header footer 中 } else if (isNeedPSlot && slotTarget) { wrapWithP(dragment, slotTarget, dropTargetName, layoutPNode); } // 其他维持原状,不进行其他设置 }, }, }, icon: '', category: '布局容器类', }; const snippets = [ { title: '高级抽屉', screenshot: 'https://img.alicdn.com/imgextra/i3/O1CN01PIbHBa1dxMY8m44cf_!!6000000003802-55-tps-56-56.svg', schema: { componentName: 'Drawer', props: { prefix: 'next-', title: '高级抽屉', triggerType: 'click', closeable: true, placement: 'right', hasMask: true, isAutoContainer: true, visible: true, size: 'medium', operationConfig: { align: 'right', fixed: true, }, operations: [ { action: 'ok', type: 'primary', content: '确认', }, { action: 'cancel', type: 'normal', content: '取消', }, ], }, }, }, ]; export default { ...meta, snippets }; ================================================ FILE: packages/fusion-ui/lowcode/pro-form/common/form-base-props.ts ================================================ import { isEqual, throttle } from 'lodash'; import { IPublicModelSettingField } from '@alilc/lowcode-types'; import { material } from '@alilc/lowcode-engine' import { IProps } from '../../types'; import { formItemShortcutProps as baseFormItemProps } from './form-item-props'; import { hideProp, showWithLabelAlign } from '../../utils'; function getInitialPropsForFormItem(componentName, currentComponentProps) { const component = material?.getAssets()?.components.filter((item) => item.componentName === componentName)[0]; const defaultProps = {}; const initials = component?.advanced?.initials; if (initials && Array.isArray(initials) && initials.length) { initials.forEach((initial) => { if (initial && initial.name && initial.initial) { defaultProps[initial.name] = typeof initial.initial === 'function' ? initial.initial() : initial.initial; } }); } const props = { ...currentComponentProps }; Object.keys(defaultProps).forEach((item) => { const propValue = currentComponentProps[item]; if (!propValue && defaultProps[item]) { props[item] = defaultProps[item]; } }); return props; } const itemSetValue = throttle((target: IPublicModelSettingField, value) => { const { node } = target; const mergedValueMap = {}; const mergedValues: any = []; const map = {}; if (!Array.isArray(value)) { value = []; } value.forEach((item) => { if (item.primaryKey === undefined) return; if (!mergedValueMap[item.primaryKey]) { mergedValueMap[item.primaryKey] = item; mergedValues.push(item); } const FormItem = Object.assign({}, item); if (!FormItem.componentName) { // 新增表单项时初始化 FormItem.componentName = 'FormInput'; } map[item.primaryKey] = FormItem; }); const children = node?.children?.filter((child) => { if (!mergedValueMap[child.propsData?.['primaryKey']]) { mergedValueMap[child.propsData?.['primaryKey']] = child.propsData; mergedValues.push(child.propsData); } return true; }); const preValue = children.map((child) => { return child.propsData; }); if (isEqual(preValue, value)) { return; } node?.children?.mergeChildren( (child) => { const primaryKey = child.getPropValue('formItemProps')?.primaryKey || child.getPropValue('primaryKey'); if (Object.hasOwnProperty.call(map, primaryKey)) { const { componentName, componentProps, ...otherProps } = map[primaryKey]; const newComponentProps = getInitialPropsForFormItem(componentName, componentProps); let newProps; if (child.componentName === 'ProFormItem') { const formItemProps = { ...(child.propsData || {}), ...otherProps }; delete formItemProps.componentProps; delete formItemProps.componentName; newProps = { formItemProps, ...newComponentProps, }; delete newProps.componentName; } else { newProps = { ...(child.propsData || {}), ...newComponentProps, formItemProps: otherProps, }; } node.replaceChild(child, { componentName, props: newProps, }); delete map[primaryKey]; return false; } return true; }, () => { const items: any[] = []; for (const primaryKey in map) { if (Object.hasOwnProperty.call(map, primaryKey)) { const { componentName, componentProps, ...otherProps } = map[primaryKey]; const newProps = { formItemProps: otherProps, ...componentProps, }; items.push({ componentName, props: newProps, }); } } return items; }, (child1, child2) => { const a = mergedValues.findIndex( (item) => String(item.primaryKey) === String( child1.getPropValue('formItemProps')?.primaryKey || child1.getPropValue('primaryKey'), ), ); const b = mergedValues.findIndex( (item) => String(item.primaryKey) === String( child2.getPropValue('formItemProps')?.primaryKey || child2.getPropValue('primaryKey'), ), ); return a - b; }, ); }); export const formItemsProps = { name: '!items', title: '表单项', display: 'accordion', virtual: true, setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'componentName', title: '表单项组件', display: 'inline', defaultValue: 'FormInput', important: true, setter: () => { return { componentName: 'SelectSetter', props: { options: AliLowCodeEngine.material .getAssets() .components.filter((item) => item.isFormItemComponent) .map((item) => { return { title: item.title || item.componentName, value: item.componentName, }; }), }, }; }, }, ...baseFormItemProps, ], }, }, initialValue: () => { const mockProps = {}; baseFormItemProps.forEach((item) => { if (item.defaultValue) { if (typeof item.defaultValue === 'function') { mockProps[item.name] = item.defaultValue(); } else { mockProps[item.name] = item.defaultValue; } } }); return { componentName: 'FormInput', ...mockProps, }; }, }, }, }, getValue: (target: IPublicModelSettingField) => { const hotValue = target.node?.children?.map((child) => { const { propsData } = child; // 兼容 FroFromItem -> Input 的数据结构 if (child.componentName === 'ProFormItem') { const { componentProps, ...formItemProps } = propsData || {}; return { ...formItemProps, componentProps, }; } else { const { formItemProps, ...componentProps } = propsData || {}; return { ...formItemProps, componentName: child.componentName, componentProps, }; } }); return hotValue; }, setValue: itemSetValue, }; const props: IProps[] = [ { name: 'ref', condition: hideProp, setter: (target) => { if (!target?.getValue()) { target?.setValue(`pro-form-${target?.id}`); } return 'StringSetter'; }, }, { name: 'globalConfig', title: '全局配置', type: 'group', display: 'accordion', items: [ { name: 'inline', condition: hideProp, title: { label: { type: 'i18n', zh_CN: '内联表单', en_US: 'Inline', }, tip: { type: 'i18n', zh_CN: '属性: inline | 说明: 内联表单', en_US: 'prop: inline | description: inline form', }, }, setter: { componentName: 'MixedSetter', props: { setters: ['BoolSetter', 'ExpressionSetter'], }, }, setValue: (target, value) => { if (value === true) { target.getProps().setPropValue('labelCol', null); target.getProps().setPropValue('wrapperCol', null); } else { target.getProps().setPropValue('labelCol', { fixedSpan: 4 }); target.getProps().setPropValue('wrapperCol', null); } return target.getProps().setPropValue('inline', value); }, }, { name: 'fullWidth', condition: hideProp, title: { label: { type: 'i18n', zh_CN: '宽度占满', en_US: 'FullWidth', }, tip: { type: 'i18n', zh_CN: '属性: fullWidth | 说明: 单个 Item 中表单类组件宽度是否是100%', en_US: 'prop: fullWidth | description: full width', }, }, setter: 'BoolSetter', }, { name: 'status', virtual: true, title: '状态', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '只读态', value: 'readonly', }, { title: '编辑态', value: 'editable', }, ], }, }, getValue: (target) => { const isPreview = target.getProps().getPropValue('isPreview'); return isPreview ? 'readonly' : 'editable'; }, setValue: (target, value) => { target.getProps().setPropValue('isPreview', value === 'readonly'); }, defaultValue: 'editable', }, { name: 'isPreview', condition: () => false, title: { label: { type: 'i18n', zh_CN: '预览态', en_US: 'Preview Mode', }, tip: { type: 'i18n', zh_CN: '属性: isPreview | 说明: 是否开启预览态', en_US: 'prop: isPreview | description: preview mode', }, }, setter: 'BoolSetter', description: '是否开启预览态', }, { name: 'columns', title: '布局', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '一列', value: 1, }, { title: '二列', value: 2, }, { title: '三列', value: 3, }, { title: '四列', value: 4, }, ], }, }, }, { name: 'labelAlign', title: { label: { type: 'i18n', zh_CN: '标签位置', en_US: 'Label Align', }, tip: { type: 'i18n', zh_CN: '属性: labelAlign | 说明: 标签的位置\n@enumdesc 上, 左, 内', en_US: 'prop: labelAlign | description: label align', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '上', value: 'top', }, { title: '左', value: 'left', }, { title: '内', value: 'inset', }, ], }, }, extraProps: { setValue: (target, value) => { if (value === 'inset') { target.getProps().setPropValue('labelCol.fixedSpan', 0); target.getProps().setPropValue('wrapperCol', null); } else if (value === 'left') { target.getProps().setPropValue('labelCol.fixedSpan', 4); target.getProps().setPropValue('wrapperCol', null); } return target.getProps().setPropValue('labelAlign', value); }, }, defaultValue: 'top', }, { name: 'labelCol.fixedSpan', title: '标题宽度', condition: showWithLabelAlign, setter: { componentName: 'NumberSetter', props: { min: 0, max: 24, }, }, }, { name: 'labelCol.offset', title: '标题偏移', condition: showWithLabelAlign, setter: { componentName: 'NumberSetter', props: { min: 0, max: 24, }, }, }, { name: 'wrapperCol.span', title: '内容宽度', condition: showWithLabelAlign, setter: { componentName: 'NumberSetter', props: { min: 0, max: 24, }, }, }, { name: 'wrapperCol.offset', title: '内容偏移', condition: showWithLabelAlign, setter: { componentName: 'NumberSetter', props: { min: 0, max: 24, }, }, }, { name: 'labelTextAlign', condition: showWithLabelAlign, title: { label: { type: 'i18n', zh_CN: '标签对齐', en_US: 'Text Align', }, tip: { type: 'i18n', zh_CN: '属性: labelTextAlign | 说明: 标签的左右对齐方式\n@enumdesc 左, 右', en_US: 'prop: labelTextAlign | description: label text align', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['left', 'right'], }, }, defaultValue: 'right', }, ], }, { name: 'field', condition: hideProp, title: { label: { type: 'i18n', zh_CN: 'Field 实例', en_US: 'Field', }, tip: { type: 'i18n', zh_CN: '属性: field | 说明: 传入 Field 实例', en_US: 'prop: field | description: field instance', }, docUrl: 'https://fusion.alibaba-inc.com/pc/component/basic/form#%E5%A4%8D%E6%9D%82%E5%8A%9F%E8%83%BD(Field)', }, setter: { componentName: 'ExpressionSetter', }, }, { name: 'value', condition: hideProp, title: { label: { type: 'i18n', zh_CN: '表单值', en_US: 'value', }, tip: { type: 'i18n', zh_CN: '属性: value | 说明: 表单值', en_US: 'prop: value | description: value instance', }, }, setter: { componentName: 'MixedSetter', props: { setters: ['JsonSetter', 'ExpressionSetter'], }, }, }, { name: 'size', condition: hideProp, title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 单个 Item 的 size 自定义,优先级高于 Form 的 size, 并且当组件与 Item 一起使用时,组件自身设置 size 属性无效。\n@enumdesc 大, 中, 小', en_US: 'prop: size | description: size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['large', 'medium', 'small'], }, }, defaultValue: 'medium', }, { name: 'device', condition: hideProp, title: { label: { type: 'i18n', zh_CN: '设备', en_US: 'Device', }, tip: { type: 'i18n', zh_CN: '属性: device | 说明: 预设屏幕宽度', en_US: 'prop: device | description: device', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['phone', 'tablet', 'desktop'], }, }, defaultValue: 'desktop', }, formItemsProps, ]; export default props; ================================================ FILE: packages/fusion-ui/lowcode/pro-form/common/form-item-props.ts ================================================ import React from 'react'; import { IProps } from '../../types'; import { showWithLabelAlign, showWithLabelAlignShortcut, hideProp, getParentValue, mockId, } from '../../utils'; const primaryKeyConfig = { name: 'primaryKey', title: '编号', display: 'none', condition: hideProp, defaultValue: (val: any) => { if (val) return val; return mockId(); }, setter: 'StringSetter', }; const columnSpanConfig = { name: 'columnSpan', title: '表单项宽度', defaultValue: 1, setter: (target) => { const parentColumns = target.parent.getPropValue('columns'); const options = [ { title: '一列', value: 1, }, { title: '二列', value: 2, }, { title: '三列', value: 3, }, { title: '四列', value: 4, }, ].slice(0, parentColumns); return { componentName: 'RadioGroupSetter', props: { options, }, }; }, }; const labelConfig = { name: 'label', title: '标题', display: 'inline', defaultValue: '表单项', setter: 'StringSetter', important: true, supportVariable: true, }; const idConfig = { name: 'id', condition: hideProp, title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', }; const nameConfig = { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识,用于表单校验', en_US: 'prop: name | description: form item name', }, }, setter: 'StringSetter', }; const helpConfig = { name: 'help', title: { label: { type: 'i18n', zh_CN: '错误提示', en_US: 'Help Info', }, tip: { type: 'i18n', zh_CN: '属性: help | 说明: 自定义提示信息, 如不设置,则会根据校验规则自动生成.', en_US: 'prop: help | description: help infomation', }, }, setter: 'StringSetter', }; const extraConfig = { name: 'extra', title: { label: { type: 'i18n', zh_CN: '帮助提示', en_US: 'Extra Info', }, tip: { type: 'i18n', zh_CN: '属性: extra | 说明: 额外的提示信息, 和 help 类似,当需要错误信息和提示文案同时出现时,可以使用这个。 位于错误信息后面', en_US: 'prop: extra | description: extra infomation', }, }, setter: 'StringSetter', }; const validateStateConfig = { name: 'validateState', title: { label: '校验状态', tip: '如不设置,则会根据校验规则自动生成\n@enumdesc 失败, 成功, 校验中, 警告', }, setter: { componentName: 'RadioGroupSetter', props: { options: ['error', 'success', 'loading', 'warning'], }, }, }; const sizeConfig = { name: 'size', title: { label: '尺寸', tip: '单个 Item 的 size 自定义,优先级高于 Form 的 size, 并且当组件与 Item 一起使用时,组件自身设置 size 属性无效。', }, setter: { componentName: 'RadioGroupSetter', props: { options: ['small', 'medium', 'large'], }, }, defaultValue: 'medium', }; const labelAlignConfig = { name: 'labelAlign', title: { label: '标签位置', tip: '上, 左, 内', }, condition: hideProp, getValue: getParentValue, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '上', value: 'top', }, { title: '左', value: 'left', }, { title: '内', value: 'inset', }, { title: '默认', value: '', }, ], }, }, }; const labelColFixedSpanConfig = { name: 'labelCol.fixedSpan', title: '标题宽度', condition: showWithLabelAlign, getValue: getParentValue, setter: { componentName: 'NumberSetter', props: { min: 0, max: 24, }, }, }; const labelColOffsetConfig = { name: 'labelCol.offset', title: '标题偏移', condition: showWithLabelAlign, getValue: getParentValue, setter: { componentName: 'NumberSetter', props: { min: 0, max: 24, }, }, }; const wrapperColSpanConfig = { name: 'wrapperCol.span', title: '内容宽度', condition: showWithLabelAlign, getValue: getParentValue, setter: { componentName: 'NumberSetter', props: { min: 0, max: 24, }, }, }; const wrapperColOffsetConfig = { name: 'wrapperCol.offset', title: '内容偏移', condition: showWithLabelAlign, getValue: getParentValue, setter: { componentName: 'NumberSetter', props: { min: 0, max: 24, }, }, }; const labelTipEnableConfig = { name: 'labelTip.enable', title: '标题提示', condition: showWithLabelAlign, setter: { componentName: 'BoolSetter', }, }; const labelTipContentConfig = { name: 'labelTip.content', title: '提示内容', condition: showWithLabelAlign, setter: { componentName: 'StringSetter', }, }; const labelTipIconConfig = { name: 'labelTip.icon', title: '提示图标', condition: showWithLabelAlign, setter: { componentName: 'IconSetter', }, }; const labelTextAlignConfig = { name: 'labelTextAlign', condition: showWithLabelAlign, title: { label: '标签对齐', tip: '左, 右', }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '左', value: 'left', }, { title: '右', value: 'right', }, { title: '默认', value: '', }, ], }, }, defaultValue: 'right', }; const deviceConfig = { name: 'device', title: { label: '设备', }, setter: { componentName: 'RadioGroupSetter', props: { options: ['phone', 'tablet', 'desktop'], }, }, defaultValue: 'desktop', }; const requiredConfig = { name: 'required', defaultValue: false, title: { label: '是否必填', tip: 'required | 是否必填', }, setter: { componentName: 'BoolSetter', }, extraProps: { setValue: (target, value) => { if (value === true) { const name = target.parent.getPropValue('name'); if (!name) { target.parent.setPropValue('name', mockId()); } } target.parent.setValue(target.parent.getValue()); }, }, }; const fullWidthConfig = { name: 'fullWidth', defaultValue: true, title: { label: '宽度占满', tip: '单个 Item 中表单类组件宽度是否是100%', }, setter: { componentName: 'BoolSetter', }, }; const isPreviewConfig = { name: 'isPreview', title: { label: '预览态', tip: '是否开启预览态', }, setter: 'BoolSetter', }; const autoValidateConfig = { name: 'autoValidate', title: { label: '自动校验', tip: '是否修改数据时自动触发校验', }, setter: 'BoolSetter', }; const validationConfig = { type: 'group', name: 'validation', display: 'accordion', defaultCollapsed: true, title: '校验', items: [ { type: 'group', name: 'notNullValidation', display: 'popup', title: '非空校验', items: [ { name: 'required', title: { label: '不能为空', tip: '[表单校验] 不能为空', }, setter: 'BoolSetter', }, { name: 'requiredMessage', title: { label: '错误信息', tip: '[表单校验]为空时自定义错误信息', }, setter: 'StringSetter', }, ], }, { type: 'group', name: 'maxValidation', display: 'popup', title: '最大/最小值校验', items: [ { name: 'min', title: { label: '最小值', tip: '[表单校验] 最小值', }, setter: 'NumberSetter', }, { name: 'max', title: { label: '最大值', tip: '[表单校验] 最大值', }, setter: 'NumberSetter', }, { name: 'minmaxMessage', title: { label: '错误信息', tip: '[表单校验] min/max 自定义错误信息', }, setter: 'StringSetter', }, ], }, { type: 'group', name: 'maxLenValidation', display: 'popup', title: '最大/最小长度校验', items: [ { name: 'minLength', title: { label: '最小长度', tip: '[表单校验] 字符串最小长度 / 数组最小个数', }, setter: 'NumberSetter', }, { name: 'maxLength', title: { label: '最大长度', tip: '[表单校验] 字符串最大长度 / 数组最大个数', }, setter: 'NumberSetter', }, { name: 'minmaxLengthMessage', title: { label: '错误信息', tip: '[表单校验] minLength/maxLength 自定义错误信息', }, setter: 'StringSetter', }, ], }, { type: 'group', name: 'lengthValidation', display: 'popup', title: '长度校验', items: [ { name: 'length', title: { label: '长度', tip: '[表单校验] 字符串精确长度 / 数组精确个数', }, setter: 'NumberSetter', }, { name: 'lengthMessage', title: { label: '错误信息', tip: '[表单校验] minLength/maxLength 自定义错误信息', }, setter: 'StringSetter', }, ], }, { type: 'group', name: 'regValidation', display: 'popup', title: '正则校验', items: [ { name: 'pattern', title: { label: '正则', tip: '[表单校验] 正则校验', }, setter: 'StringSetter', }, { name: 'patternMessage', title: { label: '错误信息', tip: '[表单校验] pattern 自定义错误信息', }, setter: 'StringSetter', }, ], }, { type: 'group', name: 'formatValidation', display: 'popup', title: '格式化校验', items: [ { name: 'format', title: { label: 'format', tip: '[表单校验] 四种常用的 pattern', }, setter: { componentName: 'RadioGroupSetter', props: { options: ['number', 'email', 'url', 'tel'], }, }, }, { name: 'formatMessage', title: { label: '错误信息', tip: '[表单校验] format 自定义错误信息', }, setter: 'StringSetter', }, ], }, { name: 'validator', display: 'popup', title: { label: '自定义校验函数', }, setter: 'FunctionSetter', }, ], }; const childFormConfig = { name: 'childForm', title: '开启子表单', setter: { componentName: 'SlotSetter', initialValue: { type: 'JSSlot', visible: false, value: [ { componentName: 'ChildForm', props: { primaryKey: String(Math.floor(Math.random() * 10000)), placeholder: '请在右侧面板添加表单项+', placeholderStyle: { height: '38px', color: '#0088FF', background: '#d8d8d836', border: 0, gridArea: 'span 4 / span 4', }, columns: 3, labelCol: { fixedSpan: 4, }, labelAlign: 'top', emptyContent: '添加表单项', }, children: [...new Array(3).keys()].map((item) => ({ componentName: 'FormInput', props: { formItemProps: { primaryKey: String(Math.floor(Math.random() * 10000) + item), label: '表单项', size: 'medium', device: 'desktop', fullWidth: true, }, placeholder: '请输入', }, })), }, ], }, }, }; export const formItemProps = [ primaryKeyConfig, idConfig, nameConfig, columnSpanConfig, labelConfig, childFormConfig, helpConfig, extraConfig, validateStateConfig, sizeConfig, labelAlignConfig, labelColFixedSpanConfig, labelColOffsetConfig, wrapperColSpanConfig, wrapperColOffsetConfig, labelTipEnableConfig, labelTipIconConfig, labelTipContentConfig, labelTextAlignConfig, deviceConfig, requiredConfig, fullWidthConfig, isPreviewConfig, autoValidateConfig, validationConfig, ]; export const formItemShortcutProps = [ primaryKeyConfig, nameConfig, labelConfig, sizeConfig, columnSpanConfig, childFormConfig, { name: 'labelTip.enable', title: '标题提示', condition: showWithLabelAlignShortcut, setter: { componentName: 'BoolSetter', }, }, { name: 'labelTip.icon', title: '提示图标', condition: showWithLabelAlignShortcut, setter: { componentName: 'IconSetter', }, }, { name: 'labelTip.content', title: '提示内容', condition: showWithLabelAlignShortcut, setter: { componentName: 'StringSetter', }, }, requiredConfig, fullWidthConfig, isPreviewConfig, autoValidateConfig, { name: '!entry', title: '组件详细配置', display: 'block', setter: (target) => { return React.createElement( Next.Button, { onClick: () => { const { node } = target; node.children.get(target.parent.key).select(); }, }, '点击配置', ); }, }, ]; const props: IProps[] = [ { name: 'formItemProps', title: '表单项配置', extraProps: { display: 'accordion', defaultCollapsed: true, }, setter: { componentName: 'ObjectSetter', props: { config: { items: formItemProps, }, }, }, }, ]; export default props; ================================================ FILE: packages/fusion-ui/lowcode/pro-form/common/props.ts ================================================ import { IProps } from '../../types'; import { operationProps } from '../../common'; import FormItemProps from './form-item-props'; import FormBaseProps from './form-base-props'; export { FormItemProps, FormBaseProps }; const props: IProps[] = [...FormBaseProps, ...operationProps]; export default props; ================================================ FILE: packages/fusion-ui/lowcode/pro-form/components/index.ts ================================================ import { default as PasswordMeta } from './password'; import { default as TextAreaMeta } from './text-area'; export default [PasswordMeta, TextAreaMeta]; ================================================ FILE: packages/fusion-ui/lowcode/pro-form/components/password.ts ================================================ import { IProps } from '../../types'; import { wrapFormItemProps } from '../../utils/form-utils'; const props: IProps[] = wrapFormItemProps([ { name: 'rows', title: { label: { type: 'i18n', zh_CN: '行数', en_US: 'Rows', }, tip: { type: 'i18n', zh_CN: '属性: rows | 说明: 多行文本框高度
(不要直接用height设置多行文本框的高度, ie9 10会有兼容性问题)', en_US: 'prop: rows | description: row numbers', }, }, setter: 'NumberSetter', supportVariable: true, defaultValue: 4, }, { name: 'maxLength', title: { label: { type: 'i18n', zh_CN: '最大长度', en_US: 'MaxLength', }, tip: { type: 'i18n', zh_CN: '属性: maxLength | 说明: 最大长度', en_US: 'prop: maxLength | description: max length', }, }, setter: 'NumberSetter', supportVariable: true, description: '最大长度', }, { name: 'placeholder', title: { label: { type: 'i18n', zh_CN: '输入提示', en_US: 'Placeholder', }, tip: { type: 'i18n', zh_CN: '属性: placeholder | 说明: 输入提示', en_US: 'prop: placeholder | description: placeholder', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'state', title: { label: { type: 'i18n', zh_CN: '状态', en_US: 'State', }, tip: { type: 'i18n', zh_CN: '属性: state | 说明: 状态\n@enumdesc 错误', en_US: 'prop: state | description: input state', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['error', 'warning'], }, }, }, { name: 'autoHeight', title: { label: { type: 'i18n', zh_CN: '自动高度', en_US: 'Auto Height', }, tip: { type: 'i18n', zh_CN: '属性: autoHeight | 说明: 自动高度 true / {minRows: 2, maxRows: 4}', en_US: 'prop: autoHeight | description: auto height', }, }, setter: 'BoolSetter', supportVariable: true, defaultValue: false, }, { name: 'isPreview', title: { label: { type: 'i18n', zh_CN: '预览态', en_US: 'Preview', }, tip: { type: 'i18n', zh_CN: '属性: isPreview | 说明: 是否为预览态', en_US: 'prop: isPreview | description: preview', }, }, setter: 'BoolSetter', supportVariable: true, defaultValue: false, }, { name: 'disabled', title: { label: { type: 'i18n', zh_CN: '是否禁用', en_US: 'Disabled', }, tip: { type: 'i18n', zh_CN: '属性: disabled | 说明: 是否被禁用', en_US: 'prop: disabled | description: disabled', }, }, setter: 'BoolSetter', supportVariable: true, description: '是否禁用', }, { name: 'hasLimitHint', title: { label: { type: 'i18n', zh_CN: '展示限制', en_US: 'ShowLimit', }, tip: { type: 'i18n', zh_CN: '属性: hasLimitHint | 说明: 是否展现最大长度样式', en_US: 'prop: hasLimitHint | description: hasLimitHint', }, }, setter: 'BoolSetter', supportVariable: true, description: '是否展现最大长度样式', }, { name: 'cutString', title: { label: { type: 'i18n', zh_CN: '是否截断', en_US: 'Cut Off', }, tip: { type: 'i18n', zh_CN: '属性: cutString | 说明: 是否截断超出字符串', en_US: 'prop: cutString | description: whether cut off string', }, }, setter: 'BoolSetter', supportVariable: true, description: '是否截断超出字符串', }, { name: 'readOnly', title: { label: { type: 'i18n', zh_CN: '是否只读', en_US: 'ReadOnly', }, tip: { type: 'i18n', zh_CN: '属性: readOnly | 说明: 是否只读', en_US: 'prop: readOnly | description: ReadOnly', }, }, setter: 'BoolSetter', supportVariable: true, description: '是否只读', }, { name: 'trim', title: { label: { type: 'i18n', zh_CN: '是否 Trim', en_US: 'Trim', }, tip: { type: 'i18n', zh_CN: '属性: trim | 说明: onChange返回会自动去除头尾空字符', en_US: 'prop: trim | description: whether trim when onChange called', }, }, setter: 'BoolSetter', supportVariable: true, }, { name: 'hasBorder', title: { label: { type: 'i18n', zh_CN: '显示边框', en_US: 'ShowBorder', }, tip: { type: 'i18n', zh_CN: '属性: hasBorder | 说明: 是否有边框', en_US: 'prop: hasBorder | description: HasBorder', }, }, setter: 'BoolSetter', supportVariable: true, }, { name: 'autoFocus', title: { label: { type: 'i18n', zh_CN: '自动聚焦', en_US: 'Auto Focus', }, tip: { type: 'i18n', zh_CN: '属性: autoFocus | 说明: 自动聚焦', en_US: 'prop: autoFocus | description: autoFocus', }, }, setter: 'BoolSetter', supportVariable: true, description: '自动聚焦', }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', supportVariable: true, }, ], }, ]); const meta = { componentName: 'FormPassword', isFormItemComponent: true, title: '密码框', docUrl: '', screenshot: '', npm: { package: '@alifd/fusion-ui', version: '{{version}}', exportName: 'FormPassword', main: '', destructuring: true, subName: '', }, configure: { props, supports: { style: true, events: ['onPressEnter', 'onClear', 'onChange', 'onKeyDown', 'onFocus', 'onBlur'], }, }, icon: '', category: '内容', }; export default meta; ================================================ FILE: packages/fusion-ui/lowcode/pro-form/components/text-area.ts ================================================ import { IProps } from '../../types'; import { wrapFormItemProps } from '../../utils/form-utils'; const props: IProps[] = wrapFormItemProps([ { name: 'rows', title: { label: { type: 'i18n', zh_CN: '行数', en_US: 'Rows', }, tip: { type: 'i18n', zh_CN: '属性: rows | 说明: 多行文本框高度
(不要直接用height设置多行文本框的高度, ie9 10会有兼容性问题)', en_US: 'prop: rows | description: row numbers', }, }, setter: 'NumberSetter', supportVariable: true, defaultValue: 4, }, { name: 'maxLength', title: { label: { type: 'i18n', zh_CN: '最大长度', en_US: 'MaxLength', }, tip: { type: 'i18n', zh_CN: '属性: maxLength | 说明: 最大长度', en_US: 'prop: maxLength | description: max length', }, }, setter: 'NumberSetter', supportVariable: true, description: '最大长度', }, { name: 'placeholder', title: { label: { type: 'i18n', zh_CN: '输入提示', en_US: 'Placeholder', }, tip: { type: 'i18n', zh_CN: '属性: placeholder | 说明: 输入提示', en_US: 'prop: placeholder | description: placeholder', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'state', title: { label: { type: 'i18n', zh_CN: '状态', en_US: 'State', }, tip: { type: 'i18n', zh_CN: '属性: state | 说明: 状态\n@enumdesc 错误', en_US: 'prop: state | description: input state', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['error', 'warning'], }, }, }, { name: 'autoHeight', title: { label: { type: 'i18n', zh_CN: '自动高度', en_US: 'Auto Height', }, tip: { type: 'i18n', zh_CN: '属性: autoHeight | 说明: 自动高度 true / {minRows: 2, maxRows: 4}', en_US: 'prop: autoHeight | description: auto height', }, }, setter: 'BoolSetter', supportVariable: true, defaultValue: false, }, { name: 'isPreview', title: { label: { type: 'i18n', zh_CN: '预览态', en_US: 'Preview', }, tip: { type: 'i18n', zh_CN: '属性: isPreview | 说明: 是否为预览态', en_US: 'prop: isPreview | description: preview', }, }, setter: 'BoolSetter', supportVariable: true, defaultValue: false, }, { name: 'disabled', title: { label: { type: 'i18n', zh_CN: '是否禁用', en_US: 'Disabled', }, tip: { type: 'i18n', zh_CN: '属性: disabled | 说明: 是否被禁用', en_US: 'prop: disabled | description: disabled', }, }, setter: 'BoolSetter', supportVariable: true, description: '是否禁用', }, { name: 'hasLimitHint', title: { label: { type: 'i18n', zh_CN: '展示限制', en_US: 'ShowLimit', }, tip: { type: 'i18n', zh_CN: '属性: hasLimitHint | 说明: 是否展现最大长度样式', en_US: 'prop: hasLimitHint | description: hasLimitHint', }, }, setter: 'BoolSetter', supportVariable: true, description: '是否展现最大长度样式', }, { name: 'cutString', title: { label: { type: 'i18n', zh_CN: '是否截断', en_US: 'Cut Off', }, tip: { type: 'i18n', zh_CN: '属性: cutString | 说明: 是否截断超出字符串', en_US: 'prop: cutString | description: whether cut off string', }, }, setter: 'BoolSetter', supportVariable: true, description: '是否截断超出字符串', }, { name: 'readOnly', title: { label: { type: 'i18n', zh_CN: '是否只读', en_US: 'ReadOnly', }, tip: { type: 'i18n', zh_CN: '属性: readOnly | 说明: 是否只读', en_US: 'prop: readOnly | description: ReadOnly', }, }, setter: 'BoolSetter', supportVariable: true, description: '是否只读', }, { name: 'trim', title: { label: { type: 'i18n', zh_CN: '是否 Trim', en_US: 'Trim', }, tip: { type: 'i18n', zh_CN: '属性: trim | 说明: onChange返回会自动去除头尾空字符', en_US: 'prop: trim | description: whether trim when onChange called', }, }, setter: 'BoolSetter', supportVariable: true, }, { name: 'hasBorder', title: { label: { type: 'i18n', zh_CN: '显示边框', en_US: 'ShowBorder', }, tip: { type: 'i18n', zh_CN: '属性: hasBorder | 说明: 是否有边框', en_US: 'prop: hasBorder | description: HasBorder', }, }, setter: 'BoolSetter', supportVariable: true, }, { name: 'autoFocus', title: { label: { type: 'i18n', zh_CN: '自动聚焦', en_US: 'Auto Focus', }, tip: { type: 'i18n', zh_CN: '属性: autoFocus | 说明: 自动聚焦', en_US: 'prop: autoFocus | description: autoFocus', }, }, setter: 'BoolSetter', supportVariable: true, description: '自动聚焦', }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', supportVariable: true, }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', supportVariable: true, }, ], }, ]); const meta = { componentName: 'FormTextArea', isFormItemComponent: true, title: '多行文本框', docUrl: '', screenshot: '', npm: { package: '@alifd/fusion-ui', version: '{{version}}', exportName: 'FormTextArea', main: '', destructuring: true, subName: '', }, configure: { props, supports: { style: true, events: ['onPressEnter', 'onClear', 'onChange', 'onKeyDown', 'onFocus', 'onBlur'], }, }, icon: '', category: '内容', }; export default meta; ================================================ FILE: packages/fusion-ui/lowcode/pro-form/meta.ts ================================================ import { IComponentDescription, ISnippet } from '../types'; import { default as props, FormItemProps } from './common/props'; import { default as ComponentsMeta } from './components'; const snippets: ISnippet[] = [ { title: '高级表单', screenshot: 'https://img.alicdn.com/imgextra/i2/O1CN016gn5DQ1FeXUNKdK22_!!6000000000512-55-tps-50-36.svg', schema: { componentName: 'ProForm', title: '高级表单', props: { placeholder: '请在右侧面板添加表单项+', placeholderStyle: { height: '38px', color: '#0088FF', background: '#d8d8d836', border: 0, gridArea: 'span 4 / span 4', }, columns: 4, labelCol: { fixedSpan: 4, }, labelAlign: 'top', emptyContent: '添加表单项', }, children: [...new Array(8).keys()].map((item) => ({ componentName: 'FormInput', props: { formItemProps: { primaryKey: String(Math.floor(Math.random() * 10000) + item), label: '表单项', size: 'medium', device: 'desktop', fullWidth: true, }, placeholder: '请输入', }, })), }, }, ]; const ProFormMeta: IComponentDescription[] = [ { componentName: 'ProForm', category: '表单类', title: '高级表单', group: '精选组件', docUrl: '', screenshot: '', devMode: 'proCode', npm: { package: '@alifd/fusion-ui', version: '0.1.4', exportName: 'ProForm', main: 'lib/index.js', destructuring: true, subName: '', }, configure: { component: { isContainer: true, isMinimalRenderUnit: true, nestingRule: { childWhitelist: new RegExp('form.*', 'i'), }, }, supports: { style: true, events: ['saveField', 'onSubmit', 'onChange'], }, props, }, snippets, }, { componentName: 'ProFormItem', title: '表单项', docUrl: '', screenshot: 'https://img.alicdn.com/imgextra/i2/O1CN016gn5DQ1FeXUNKdK22_!!6000000000512-55-tps-50-36.svg', icon: 'https://img.alicdn.com/imgextra/i2/O1CN016gn5DQ1FeXUNKdK22_!!6000000000512-55-tps-50-36.svg', devMode: 'proCode', npm: { package: '@alifd/fusion-ui', version: '0.1.4', exportName: 'ProForm', main: 'lib/index.js', destructuring: true, subName: 'Item', }, configure: { component: { disableBehaviors: ['copy'], nestingRule: { parentWhitelist: ['ProForm'], }, }, props: FormItemProps, supports: { style: true, events: ['onPressEnter', 'onClear', 'onChange', 'onKeyDown', 'onFocus', 'onBlur'], }, advanced: { initialChildren: [ { componentName: 'FormInput', props: { hasBorder: true, size: 'medium', autoComplete: 'off', }, }, ], callbacks: { onNodeRemove: (removedNode, currentNode) => { if (!removedNode || !currentNode) { return; } const { children } = currentNode; // 若无 children,则说明当前 P 组件内已为空,需要删除 FormItem 组件本身 if (children && children.isEmptyNode) { currentNode.remove(); } }, }, }, }, }, ]; export default [...ProFormMeta, ...ComponentsMeta]; ================================================ FILE: packages/fusion-ui/lowcode/pro-table/actionColumnFields.ts ================================================ import { IProps } from '../types/index'; import { buttonGroupConfigureProp } from '../common/button-groups'; export const actionColumnField: IProps = { name: 'actionColumnProps', title: '操作列', extraProps: { display: 'accordion', defaultCollapsed: true, }, setter: { componentName: 'ObjectSetter', props: { display: 'drawer', config: { items: [ { name: 'title', title: '标题', extraProps: { display: 'inline', defaultValue: '操作', }, setter: { componentName: 'StringSetter', }, }, { type: 'field', name: 'width', title: '宽度', extraProps: { display: 'inline', defaultValue: 120, }, setter: { componentName: 'NumberSetter', props: { units: 'px', }, }, }, { name: 'lock', title: '锁列', display: 'inline', initialValue: 'none', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '左侧', value: 'left', tip: 'left', }, { title: '不锁', value: 'none', tip: 'none', }, { title: '右侧', value: 'right', tip: 'right', }, ], compact: false, }, }, }, ], }, }, }, }; export const actionColumnButtonField: IProps = { ...buttonGroupConfigureProp, name: 'actionColumnButtons', title: '操作列按钮', }; ================================================ FILE: packages/fusion-ui/lowcode/pro-table/columns-field.ts ================================================ import { uuid, mockProTableRow, mockId } from './utils'; import { IProps } from '../types/index'; import { hideProp, deepEqual, isJSExpression } from '../utils'; import debounce from 'lodash/debounce'; export const columnsField: IProps = { type: 'field', name: 'columns', title: '数据列', extraProps: { display: 'accordion', }, setValue: debounce((field, columns) => { const _columns = isJSExpression(columns) ? columns.mock : columns; if (!_columns || !Array.isArray(_columns) || !_columns.length) { return; } const { node } = field; const dataSource = node.getPropValue('dataSource') || []; const _dataSource = isJSExpression(dataSource) ? dataSource.mock : dataSource; if (!_dataSource || !Array.isArray(_dataSource) || !_dataSource.length) { return; } const primaryKey = node.getPropValue('primaryKey') || 'id'; const mockRow = mockProTableRow(columns); const newData = dataSource.map((item) => ({ [primaryKey]: mockId(), ...mockRow, ...item, })); if (!deepEqual(newData, dataSource)) { node.setPropValue('dataSource', newData); } }), setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'title', title: '标题', display: 'inline', initialValue: '姓名', isRequired: true, setter: 'StringSetter', }, { name: 'formatType', title: '数据类型', display: 'inline', initialValue: 'text', isRequired: true, setter: { componentName: 'SelectSetter', props: { options: [ { value: 'text', title: '文本' }, { value: 'number', title: '数字' }, { value: 'money', title: '金额' }, { value: 'date', title: '日期' }, { value: 'phone', title: '手机号' }, // { value: 'currency', title: '币种' }, // { value: 'ou', title: 'OU编码' }, { value: 'percent', title: '百分比' }, { value: 'progress', title: '进度条' }, { value: 'link', title: '链接' }, { value: 'dialog', title: '弹窗' }, { value: 'tag', title: '标签' }, // { value: 'textTag', title: '文字标签' }, // { value: 'files', title: '附件' }, // { value: 'bankCard', title: '银行卡号' }, // { value: 'employee', title: '员工' }, ], }, }, }, { name: 'dataIndex', title: '数据字段', display: 'inline', initialValue: (currentValue, defaultValue) => currentValue || defaultValue || `data-${uuid()}`, setter: 'StringSetter', }, { name: 'align', title: '对齐方式', display: 'inline', initialValue: 'left', setter: { componentName: 'RadioGroupSetter', props: { options: [ { value: 'left', title: '居左', }, { value: 'center', title: '居中', }, { value: 'right', title: '居右', }, ], }, }, }, { name: 'lock', title: '锁列', display: 'inline', initialValue: 'none', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '左侧', value: 'left', tip: 'left', }, { title: '不锁', value: 'none', tip: 'none', }, { title: '右侧', value: 'right', tip: 'right', }, ], compact: false, }, }, }, // 格式化参数 { name: 'formatOptions', title: '格式化参数', setter: 'ArraySetter', condition: hideProp, }, { name: '_format_options_date', title: '时间格式', display: 'inline', defaultValue: 'YYYY-MM-DD HH:mm:ss', condition: (target) => { return target.parent.getPropValue('formatType') === 'date'; }, getValue: (target) => { const formatOptions = target.getProps().getPropValue('formatOptions') || []; return formatOptions[0]; }, setValue: (target, value) => { target.parent.setPropValue('formatOptions', [value]); }, setter: { componentName: 'SelectSetter', props: { options: [ { value: 'YYYY-MM-DD HH:mm:ss', title: '年-月-日 时:分:秒' }, { value: 'YYYY-MM-DD HH:mm', title: '年-月-日 时:分' }, { value: 'YYYY-MM-DD', title: '年-月-日' }, { value: 'YYYY-MM', title: '年-月' }, { value: 'YYYY', title: '年' }, ], }, }, }, // 高级设置 { name: 'explanation', title: '表头说明', display: 'inline', initialValue: '', setter: 'StringSetter', }, { name: 'width', title: '宽度', display: 'inline', setter: { componentName: 'NumberSetter', props: { units: [ { type: 'px', list: true, }, { type: '%', list: true, }, ], }, }, }, // { // name: 'hidden', // title: '是否隐藏', // display: 'inline', // initialValue: false, // setter: 'BoolSetter', // }, // { // name: 'maxChars', // title: '字数限定', // display: 'inline', // setter: 'NumberSetter', // hidden() { // return this.parent.getParam('formatType').toData() !== 'text'; // }, // }, { name: 'sortable', title: '列排序', display: 'inline', initialValue: false, setter: 'BoolSetter', }, { name: 'searchable', title: '列搜索', display: 'inline', initialValue: false, setter: 'BoolSetter', }, { name: 'onCellClick', condition: hideProp, }, { name: 'behavior', title: '交互设置', display: 'block', condition: (target) => { const formatType = target.parent.getPropValue('formatType'); return formatType && ['dialog', 'link'].includes(formatType); }, setter: { componentName: 'BehaviorSetter', props: (target) => { return { actions: ['onCellClick'], type: target.parent.getPropValue('formatType'), }; }, }, }, ], }, }, initialValue: () => { return { title: '列标题', formatType: 'text', dataIndex: 'dataIndex', }; }, }, }, }, }; ================================================ FILE: packages/fusion-ui/lowcode/pro-table/global-style.ts ================================================ export const globalStyleField = { type: 'group', title: '全局样式', name: 'globalStyle', extraProps: { display: 'accordion', defaultCollapsed: true, }, items: [ { name: 'hasBorder', title: '列分隔线', display: 'inline', defaultValue: false, setter: 'BoolSetter', }, { name: 'isZebra', title: '斑马线', display: 'inline', defaultValue: false, setter: 'BoolSetter', }, { name: 'fixedHeader', title: '固定表头', display: 'inline', defaultValue: false, setter: 'BoolSetter', }, { name: 'size', title: '密度', display: 'inline', defaultValue: 'medium', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '紧凑', value: 'small', tip: 'small', }, { title: '正常', value: 'medium', tip: 'medium', }, ], }, }, }, ], }; ================================================ FILE: packages/fusion-ui/lowcode/pro-table/meta.ts ================================================ import { IAssets } from '../types/index'; import { proTableMeta } from './pro-table-meta'; const meta: IAssets = { components: [ proTableMeta, { componentName: 'ProTableSlot', title: '表格槽位', docUrl: '', screenshot: '', devMode: 'proCode', npm: { package: '@alifd/fusion-ui', version: '1.0.24-21', exportName: 'ProTableSlot', main: 'lib/index.js', destructuring: true, subName: '', }, props: [ { name: 'position', propType: { type: 'oneOf', isRequired: true, value: [ 'actionBarLeft', 'actionBarRight', 'actionBarBefore', 'actionBarAfter', 'table', ], }, description: '位置', }, ], }, ], }; export default meta; ================================================ FILE: packages/fusion-ui/lowcode/pro-table/pro-table-meta.ts ================================================ import { mockProTableRow, mockId, getDataSourceItemSetter } from './utils'; import { IComponentDescription } from '../types/index'; import { actionColumnButtonField, actionColumnField } from './actionColumnFields'; import { isJSExpression } from '../utils'; import { columnsField } from './columns-field'; import { buttonGroupConfigureProp } from '../common/button-groups'; import { globalStyleField } from './global-style'; const positiveIntegerSetter = { componentName: 'NumberSetter', props: { max: 200, min: 1, }, }; export const ProTableProps = [ columnsField, { type: 'field', name: 'id', title: '节点 ID', condition: () => false, extraProps: {}, setter: 'NodeSetter', }, actionColumnField, actionColumnButtonField, { ...buttonGroupConfigureProp, name: 'actionBarButtons', title: '操作栏按钮', }, { type: 'field', name: 'dataSource', title: '表格数据源', display: 'accordion', setter: (target) => { const columns = target.getProps().getPropValue('columns'); if (!columns || isJSExpression(columns)) { return { componentName: 'ExpressionSetter', }; } const mockRow = mockProTableRow(columns); const primaryKey = target.getProps().getPropValue('primaryKey') || 'id'; const items = columns.map((column, index) => { return { title: { label: { type: 'i18n', 'en-US': column.dataIndex, 'zh-CN': column.title, }, }, name: column.dataIndex, important: index < 2, setter: getDataSourceItemSetter(column.formatType), defaultValue: mockRow[column.dataIndex], }; }); return { componentName: 'MixedSetter', props: { setters: [ { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items, }, }, initialValue: () => { return { ...mockRow, [primaryKey]: mockId(), }; }, }, }, }, 'ExpressionSetter', ], }, }; }, }, { type: 'field', name: 'paginationProps', title: '分页器', extraProps: { display: 'accordion', defaultCollapsed: true, }, setter: { componentName: 'ObjectSetter', display: 'inline', props: { config: { items: [ { type: 'field', name: 'hidden', title: '关闭分页', extraProps: { display: 'inline', defaultValue: false, }, setter: 'BoolSetter', }, { name: 'total', title: '总行数', setter: { componentName: 'NumberSetter', props: { min: 0, }, }, hidden() { console.log( 'visiblevisiblevisiblevisible', this.parent.getParam('hidden').getValue(), ); return !this.parent.getParam('hidden').getValue(); }, }, { name: 'current', title: '当前页', setter: positiveIntegerSetter, }, { name: 'pageSize', title: '每页行数', setter: [ { componentName: 'SelectSetter', initialValue: 10, props: { options: [ { title: '5', value: 5, }, { title: '10', value: 10, }, { title: '20', value: 20, }, { title: '50', value: 50, }, ], }, }, positiveIntegerSetter, ], }, ], }, }, }, }, { type: 'field', name: 'rowSelection', condition: () => false, }, { type: 'group', title: '高级', name: 'advanced', extraProps: { display: 'accordion', defaultCollapsed: true, }, items: [ { type: 'field', name: '!选择模式', title: '选择模式', display: 'inline', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '无', value: 'none', tip: 'none', }, { title: '多选', value: 'multiple', tip: 'multiple', }, { title: '单选', value: 'single', tip: 'single', }, ], }, }, defaultValue: 'none', getValue: (target) => { const rowSelection = target.parent.getPropValue('rowSelection'); if (!rowSelection) { return 'none'; } return rowSelection.mode === 'single' ? 'single' : 'multiple'; }, setValue: (field, value) => { const { node } = field; if (['single', 'multiple'].includes(value)) { node.setPropValue('rowSelection', { ...node.getPropValue('rowSelection'), mode: value, }); } else { node.setPropValue('rowSelection', undefined); } }, }, { type: 'field', name: 'indexColumn', title: '开启序号列', extraProps: { display: 'inline', defaultValue: false, }, setter: { componentName: 'BoolSetter', }, }, { type: 'field', name: 'settingButtons', title: '开启设置按钮', extraProps: { display: 'inline', defaultValue: false, }, setter: { componentName: 'BoolSetter', }, }, { type: 'field', name: 'primaryKey', title: { label: '数据主键', tip: '数据主键用于区分数据中不同的行,对行选择和行编辑功能非常重要,不同的行主键值不可重复,一般采用数据库中自增 ID 字段', }, extraProps: { display: 'inline', defaultValue: 'id', condition: () => false, }, }, { name: 'cellDefault', title: { label: '单元格缺省填充', tip: '当单元格值为空时,显示内容', }, setter: 'StringSetter', }, ], }, globalStyleField, ]; export const proTableMeta: IComponentDescription = { componentName: 'ProTable', title: '高级表格', docUrl: '', icon: 'https://img.alicdn.com/imgextra/i4/O1CN01z4HeA61OwhjktJNDW_!!6000000001770-55-tps-56-56.svg', devMode: 'proCode', group: '精选组件', category: '表格类', tags: ['业务组件'], npm: { package: '@alifd/fusion-ui', version: '1.0.24-21', exportName: 'ProTable', main: 'lib/index.js', destructuring: true, subName: '', }, configure: { props: ProTableProps, component: { isContainer: false, isMinimalRenderUnit: true, nestingRule: {}, }, supports: {}, }, props: [], snippets: [ { title: '高级表格', screenshot: 'https://img.alicdn.com/imgextra/i1/O1CN01R1OdLV1GgCXW0rjop_!!6000000000651-2-tps-112-112.png', schema: { componentName: 'ProTable', props: { dataSource: [ { id: 'id-2f5DdE2b-0', date: '2013-06-12', percent: 1.862, documentAmount: 2022, currency: 'CNY', company: '支付宝科技有限公司', }, { id: 'id-2f5DdE2b-1', date: '2013-06-12', percent: 1.862, documentAmount: 2022, currency: 'CNY', company: '支付宝科技有限公司', }, ], actionColumnButtons: { dataSource: [ { children: '查看', type: 'primary', }, { children: '编辑', type: 'primary', disabled: true, }, { children: '删除', type: 'primary', }, ], text: true, visibleButtonCount: 3, }, actionBarButtons: { dataSource: [ { type: 'primary', children: '操作一', }, { type: 'normal', children: '操作二', }, ], visibleButtonCount: 3, }, paginationProps: { pageSize: 20, current: 1, }, settingButtons: true, columns: [ { title: '公司', dataIndex: 'company', width: 160, formatType: 'link', searchable: true, }, { title: '单据金额', dataIndex: 'documentAmount', formatType: 'money', }, { title: '币种', dataIndex: 'currency', formatType: 'currency', filters: [ { label: 'CNY', value: 'CNY', }, { label: 'USD', value: 'USD', }, { label: 'JPY', value: 'JPY', }, { label: 'HKD', value: 'HKD', }, ], filterMode: 'multiple', explanation: '提示信息', width: 110, }, { title: '完成进度', dataIndex: 'percent', formatType: 'progress', }, { title: '到账日期', dataIndex: 'date', formatType: 'date', }, ], }, }, }, { title: '树状表格', screenshot: 'https://img.alicdn.com/imgextra/i1/O1CN01m4IZ481VKPwFFbDhP_!!6000000002634-2-tps-112-112.png', schema: { componentName: 'ProTable', props: { isTree: true, dataSource: [ { id: 'id-2f5DdE2b-0', date: '2013-06-12', percent: 1.862, documentAmount: 2022, currency: 'CNY', company: '支付宝科技有限公司', children: [ { id: '2f5DdE2b-5Aee-c43c-e1db-0-0', date: '2013-06-12', percent: 1.862, documentAmount: 2022, currency: 'CNY', company: '支付宝科技有限公司', }, { id: '2f5DdE2b-5Aee-c43c-e1db-0-1', date: '2013-06-12', percent: 1.862, documentAmount: 2022, currency: 'CNY', company: '支付宝科技有限公司', }, ], }, { id: 'id-2f5DdE2b-1', date: '2013-06-12', percent: 1.862, documentAmount: 2022, currency: 'CNY', company: '支付宝科技有限公司', children: [ { id: '2f5DdE2b-5Aee-c43c-e1db-1-0', date: '2013-06-12', percent: 1.862, documentAmount: 2022, currency: 'CNY', company: '支付宝科技有限公司', }, { id: '2f5DdE2b-5Aee-c43c-e1db-1-1', date: '2013-06-12', percent: 1.862, documentAmount: 2022, currency: 'CNY', company: '支付宝科技有限公司', }, ], }, ], columns: [ { title: '公司', dataIndex: 'company', width: 160, formatType: 'link', searchable: true, }, { title: '单据金额', dataIndex: 'documentAmount', formatType: 'money', }, { title: '币种', dataIndex: 'currency', formatType: 'currency', filters: [ { label: 'CNY', value: 'CNY', }, { label: 'USD', value: 'USD', }, { label: 'JPY', value: 'JPY', }, { label: 'HKD', value: 'HKD', }, ], filterMode: 'multiple', explanation: '提示信息', width: 110, }, { title: '完成进度', dataIndex: 'percent', formatType: 'progress', }, { title: '到账日期', dataIndex: 'date', formatType: 'date', }, ], }, }, }, ], }; ================================================ FILE: packages/fusion-ui/lowcode/pro-table/utils.ts ================================================ import is from '@sindresorhus/is'; export const uuid = () => Math.random().toString(36).substr(-6); export const PRO_TABLE_COLUMN_MOCK_VALUES = { text: '这是一个文本', number: 1234561.231, money: 123213.1232, date: '2021-08-18 20:52:33', phone: '+86 13888888888', currency: 'CNY', ou: '34', percent: 0.64, progress: 0.64, link: '这是链接', tag: '成功', textTag: '进行中', files: [], bankCard: '6226123412341234', employee: { img: 'https://work.alibaba-inc.com/photo/256512.40x40.jpg', staff_id: '256512', nickname: '乔勇', realname: '石强', }, }; export const mockProTableCell = (formatType) => PRO_TABLE_COLUMN_MOCK_VALUES[formatType]; export const mockId = () => `id-${uuid()}`; export const columnMockValueKey = (formatType) => `_mock_value_${formatType}`; export const mockProTableRow = (columns: any[]) => { return columns ?.filter?.((vo) => vo.formatType && vo.dataIndex) ?.reduce?.((p, column) => { const { formatType, dataIndex } = column; const mockValue = column[columnMockValueKey(formatType)]; p[dataIndex] = is.nullOrUndefined(mockValue) ? mockProTableCell(formatType) : mockValue; return p; }, {}); }; export const getDataSourceItemSetter = (formatType) => { // console.log('formatType: ', formatType); let setter; switch (formatType) { case 'text': case 'phone': case 'link': case 'dialog': setter = 'StringSetter'; break; case 'number': case 'money': case 'percent': case 'currency': case 'progress': setter = 'NumberSetter'; break; case 'date': setter = 'DateSetter'; break; default: setter = 'StringSetter'; } return setter; }; ================================================ FILE: packages/fusion-ui/lowcode/pro-table-slot/meta.ts ================================================ import { ComponentMetadata } from '@ali/lowcode-types'; const ProTableSlotMeta: ComponentMetadata = { componentName: 'ProTableSlot', title: 'ProTableSlot', docUrl: '', screenshot: '', devMode: 'proCode', npm: { package: '@alifd/fusion-ui', version: '0.1.6-beta.8', exportName: 'ProTableSlot', main: 'lib/index.js', destructuring: true, subName: '', }, configure: { props: [ { title: { label: { type: 'i18n', 'en-US': 'position', 'zh-CN': '插入槽位', }, tip: 'position | 插入槽位', }, name: 'position', description: '插入槽位', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, ], supports: { style: true, }, component: {}, }, }; export default { ...ProTableSlotMeta, }; ================================================ FILE: packages/fusion-ui/lowcode/radio-group/meta.js ================================================ import { wrapFormItemProps } from '../utils/form-utils'; export default { componentName: 'FormRadioGroup', isFormItemComponent: true, title: '单选框组', docUrl: '', screenshot: '', npm: { package: '@alifd/fusion-ui', version: '{{version}}', exportName: 'FormRadioGroup', main: '', destructuring: true, subName: '', }, props: [ { name: 'className', propType: 'string', description: '自定义类名', }, { name: 'style', propType: 'object', description: '自定义内敛样式', }, { name: 'name', propType: 'string', description: 'name', }, { name: 'size', propType: { type: 'oneOf', value: ['large', 'medium', 'small'], }, description: '尺寸', defaultValue: 'medium', }, { name: 'shape', propType: { type: 'oneOf', value: ['normal', 'button'], }, description: '展示形态', }, { name: 'value', propType: { type: 'oneOfType', value: ['string', 'number', 'bool'], }, description: '选中项的值', }, { name: 'defaultValue', propType: { type: 'oneOfType', value: ['string', 'number', 'bool'], }, description: '默认值', }, { name: 'component', propType: 'string', description: '设置标签类型', defaultValue: 'div', }, { name: 'disabled', propType: 'bool', description: '是否被禁用', }, { name: 'dataSource', propType: 'object', description: '可选项列表', }, { name: 'itemDirection', propType: { type: 'oneOf', value: ['hoz', 'ver'], }, description: '子项目的排列方式', defaultValue: 'hoz', }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', defaultValue: false, }, { name: 'renderPreview', propType: 'func', description: '预览态模式下渲染的内容\n@param {number} value 评分值', }, { name: 'onChange', propType: 'func', description: '选中值改变时的事件\n@param {String/Number} value 选中项的值\n@param {Event} e Dom 事件对象', }, ], configure: { props: wrapFormItemProps([ { name: 'shape', title: '展示形状', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '默认', value: 'normal' }, { title: '按钮', value: 'button' }, ], }, }, defaultValue: 'normal', }, { name: 'disabled', title: '是否禁用', setter: { componentName: 'MixedSetter', props: { setters: ['BoolSetter', 'ExpressionSetter'], }, }, }, { name: 'itemDirection', title: '排列方式', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '水平排列', value: 'hoz' }, { title: '垂直排列', value: 'ver' }, ], }, }, defaultValue: 'hoz', }, { name: 'isPreview', title: '预览态', setter: { componentName: 'BoolSetter', }, }, { name: 'defaultValue', title: '默认值', defaultValue: '', setter: { componentName: 'MixedSetter', props: { setters: ['StringSetter', 'ExpressionSetter'], }, }, }, { name: 'dataSource', display: 'block', title: '选项', setter: { componentName: 'MixedSetter', props: { setters: [ { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'label', title: 'label', setter: 'StringSetter', }, { name: 'value', title: 'value', setter: 'StringSetter', }, ], }, }, initialValue: { label: '选项一', value: '1', }, }, }, }, 'ExpressionSetter', ], }, }, }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', }, ], }, ]), supports: { style: true, events: ['onChange'], }, advanced: { initials: [ { name: 'dataSource', initial: () => { return [ { label: '选项一', value: '1', }, { label: '选项二', value: '2', }, { label: '选项三', value: '3', }, ]; }, }, ], }, }, icon: '', category: '内容', }; ================================================ FILE: packages/fusion-ui/lowcode/range-picker/meta.js ================================================ import { wrapFormItemProps } from '../utils/form-utils'; export default { componentName: 'FormRangePicker', isFormItemComponent: true, title: '日期区段选择', docUrl: '', screenshot: '', npm: { package: '@alifd/fusion-ui', version: '{{version}}', exportName: 'FormRangePicker', main: '', destructuring: true, subName: '', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'rtl', propType: 'bool', defaultValue: false, }, { name: 'type', propType: { type: 'oneOf', value: ['date', 'month', 'year'], }, description: '日期范围类型', defaultValue: 'date', }, { name: 'defaultVisibleMonth', propType: 'func', description: '默认展示的起始月份\n@return {MomentObject} 返回包含指定月份的 moment 对象实例', }, { name: 'onVisibleMonthChange', propType: 'func', }, { name: 'value', propType: 'array', description: '日期范围值数组 [moment, moment]', }, { name: 'defaultValue', propType: 'array', description: '初始的日期范围值数组 [moment, moment]', }, { name: 'format', propType: 'string', description: '日期格式', defaultValue: 'YYYY-MM-DD', }, { name: 'showTime', propType: 'bool', description: '是否使用时间控件,支持传入 TimePicker 的属性', defaultValue: false, }, { name: 'resetTime', propType: 'bool', description: '每次选择是否重置时间(仅在 showTime 开启时有效)', defaultValue: false, }, { name: 'disabledDate', propType: 'func', description: '禁用日期函数\n@param {MomentObject} 日期值\n@param {String} view 当前视图类型,year: 年, month: 月, date: 日\n@return {Boolean} 是否禁用', }, { name: 'footerRender', propType: 'func', description: '自定义面板页脚\n@return {Node} 自定义的面板页脚组件', }, { name: 'onChange', propType: 'func', description: '日期范围值改变时的回调 [ MomentObject|String, MomentObject|String ]\n@param {Array} value 日期值', }, { name: 'onOk', propType: 'func', description: '点击确认按钮时的回调 返回开始时间和结束时间`[ MomentObject|String, MomentObject|String ]`\n@return {Array} 日期范围', }, { name: 'label', propType: 'string', description: '表单项内置标签', }, { name: 'state', propType: { type: 'oneOf', value: ['error', 'loading', 'success'], }, description: '表单项状态', }, { name: 'size', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '表单项尺寸', defaultValue: 'medium', }, { name: 'disabled', propType: 'bool', description: '是否禁用', }, { name: 'hasClear', propType: 'bool', description: '是否显示清空按钮', defaultValue: true, }, { name: 'visible', propType: 'bool', description: '弹层显示状态', }, { name: 'defaultVisible', propType: 'bool', description: '弹层默认是否显示', defaultValue: false, }, { name: 'onVisibleChange', propType: 'func', description: '弹层展示状态变化时的回调\n@param {Boolean} visible 弹层是否显示\n@param {String} type 触发弹层显示和隐藏的来源 okBtnClick 表示由确认按钮触发; fromTrigger 表示由trigger的点击触发; docClick 表示由document的点击触发', }, { name: 'popupTriggerType', propType: { type: 'oneOf', value: ['click', 'hover'], }, description: '弹层触发方式', defaultValue: 'click', }, { name: 'popupAlign', propType: 'string', description: '弹层对齐方式, 具体含义见 OverLay文档', defaultValue: 'tl tl', }, { name: 'popupContainer', propType: 'node', description: '弹层容器\n@param {Element} target 目标元素\n@return {Element} 弹层的容器元素', }, { name: 'popupClassName', propType: 'string', description: '弹层自定义样式类', }, { name: 'followTrigger', propType: 'bool', description: '是否跟随滚动', }, { name: 'startDateInputAriaLabel', propType: 'string', description: '开始日期表单项的 aria-label 属性', }, { name: 'startTimeInputAriaLabel', propType: 'string', description: '开始时间表单项的 aria-label 属性', }, { name: 'endDateInputAriaLabel', propType: 'string', description: '结束日期表单项的 aria-label 属性', }, { name: 'endTimeInputAriaLabel', propType: 'string', description: '结束时间表单项的 aria-label 属性', }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', }, { name: 'locale', propType: 'object', }, { name: 'className', propType: 'string', }, { name: 'name', propType: 'string', }, { name: 'popupComponent', propType: 'string', }, { name: 'popupContent', propType: 'node', }, { name: 'style', propType: 'object', }, ], configure: { supports: { style: true, events: ['onVisibleMonthChange', 'onChange', 'onOk', 'onVisibleChange'], }, props: wrapFormItemProps([ { name: 'defaultValue', title: { label: '默认值', tip: '初始的日期范围值数组 [moment, moment]', }, setter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 0, title: '开始时间', setter: 'DateSetter', }, { name: 1, title: '结束时间', setter: 'DateSetter', }, ], }, }, }, }, { name: 'type', title: '日期类型', setter: { setter: 'RadioGroupSetter', props: { options: ['date', 'month', 'year'] }, }, description: '日期范围类型', defaultValue: 'date', }, { name: 'label', title: '内置标签', setter: 'StringSetter', description: '表单项内置标签', }, { name: 'state', title: '输入状态', setter: { setter: 'RadioGroupSetter', props: { options: ['error', 'loading', 'success'] }, }, description: '表单项状态', }, { name: 'size', title: '尺寸', setter: { setter: 'RadioGroupSetter', props: { options: ['small', 'medium', 'large'] }, }, description: '表单项尺寸', defaultValue: 'medium', }, { name: 'disabled', setter: 'BoolSetter', title: '是否禁用', }, { name: 'hasClear', setter: 'BoolSetter', title: '清空按钮', defaultValue: true, }, { name: 'defaultVisible', setter: 'BoolSetter', title: '显示弹层', defaultValue: false, }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', }, ], }, ]), }, category: '内容', icon: '', }; ================================================ FILE: packages/fusion-ui/lowcode/rating/meta.js ================================================ import { wrapFormItemProps } from '../utils/form-utils'; export default { componentName: 'FormRating', isFormItemComponent: true, title: '评分', docUrl: '', screenshot: '', npm: { package: '@alifd/fusion-ui', version: '{{version}}', exportName: 'FormRating', main: '', destructuring: true, subName: '', }, props: [ { name: 'id', propType: 'string', }, { name: 'name', propType: 'string', description: 'name', }, { name: 'className', propType: 'string', }, { name: 'style', propType: 'object', }, { name: 'defaultValue', propType: 'number', description: '默认值', defaultValue: 0, }, { name: 'value', propType: 'number', description: '值', }, { name: 'size', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '尺寸', defaultValue: 'medium', }, { name: 'count', propType: 'number', description: '评分的总数', defaultValue: 5, }, { name: 'showGrade', propType: 'bool', description: '是否显示 grade', defaultValue: false, }, { name: 'allowHalf', propType: 'bool', description: '是否允许半星评分', defaultValue: false, }, { name: 'disabled', propType: 'bool', description: '是否禁用', defaultValue: false, }, { name: 'rtl', propType: 'bool', }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', defaultValue: false, }, { name: 'renderPreview', propType: 'func', description: '预览态模式下渲染的内容', }, { name: 'readOnly', propType: 'bool', description: '是否为只读态,效果上同 disabeld', defaultValue: false, }, { name: 'onChange', propType: 'func', description: '用户点击评分时触发的回调\n@param {String} value 评分值', }, { name: 'onHoverChange', propType: 'func', description: '用户hover评分时触发的回调\n@param {String} value 评分值', }, ], configure: { props: wrapFormItemProps([ { name: 'value', title: '当前值', setter: ['NumberSetter', 'ExpressionSetter'], }, { name: 'defaultValue', title: '默认值', setter: ['NumberSetter', 'ExpressionSetter'], }, { name: 'size', title: { label: { type: 'i18n', zh_CN: '尺寸', en_US: 'Size', }, tip: { type: 'i18n', zh_CN: '属性: size | 说明: 尺寸\n@enumdesc 小, 中, 大', en_US: 'prop: size | description: size', }, }, setter: { componentName: 'RadioGroupSetter', props: { options: ['small', 'medium', 'large'], }, }, defaultValue: 'medium', }, { name: 'count', title: '评分总数', setter: ['NumberSetter', 'ExpressionSetter'], }, { name: 'allowHalf', title: '半星评分', setter: ['BoolSetter', 'ExpressionSetter'], }, { name: 'showGrade', title: '显示分数', setter: ['BoolSetter', 'ExpressionSetter'], }, { name: 'readAs', title: '评分文案生成方法', display: 'block', setter: { componentName: 'FunctionSetter', // props: { // defaultActionName="readAs", // defaultCode=`function readAs(val) { // return val + 'source'; // }`, // } }, }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', }, ], }, ]), supports: { style: true, events: ['onChange', 'onHoverChange'], }, }, icon: '', category: '内容', }; ================================================ FILE: packages/fusion-ui/lowcode/rating/snippets.js ================================================ module.exports = [ { title: '评分', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_rating.png', schema: { componentName: 'Rating', props: { prefix: 'next-', count: 5, size: 'medium', }, }, }, ]; ================================================ FILE: packages/fusion-ui/lowcode/select/meta.js ================================================ import { wrapFormItemProps } from '../utils/form-utils'; export default { componentName: 'FormSelect', isFormItemComponent: true, title: '选择器', docUrl: '', screenshot: '', npm: { package: '@alifd/fusion-ui', version: '{{version}}', exportName: 'FormSelect', main: '', destructuring: true, subName: '', }, configure: { props: wrapFormItemProps([ { name: 'placeholder', title: { label: '占位提示', tip: '属性: placeholder', }, defaultValue: '请选择', // 不生效 setter: 'StringSetter', }, { name: 'hasClear', title: { label: '清除按钮', tip: '属性: hasClear', }, setter: 'BoolSetter', defaultValue: false, }, { name: 'showSearch', title: { label: '可搜索', tip: '属性: showSearch', }, setter: 'BoolSetter', defaultValue: false, }, { name: 'dataSource', display: 'block', title: '选项', tip: { title: '数据格式', url: '', }, setter: { componentName: 'MixedSetter', props: { setters: [ { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'label', title: 'label', setter: 'StringSetter', }, { name: 'value', title: 'value', setter: 'StringSetter', }, ], }, }, initialValue: { title: 'Title', }, }, }, }, 'ExpressionSetter', ], }, }, }, { name: 'mode', title: { label: '模式', tip: '属性: mode', }, setter: { componentName: 'RadioGroupSetter', props: { defaultValue: 'single', options: [ { value: 'single', title: '单选' }, { value: 'multiple', title: '多选' }, { value: 'tag', title: '标签' }, ], }, }, }, { type: 'group', title: '其他配置', display: 'block', items: [ { name: 'notFoundContent', title: { label: '空文案', tip: 'notFoundContent|弹层内容为空的文案', }, setter: 'StringSetter', }, { name: 'hasBorder', title: { label: '边框', tip: '是否有边框', }, setter: 'BoolSetter', }, { name: 'autoWidth', title: '下拉等宽', setter: 'BoolSetter', }, { name: 'hasArrow', title: '下拉箭头', setter: 'BoolSetter', defaultValue: true, }, ], }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', }, ], }, ]), supports: { style: true, events: [ { name: 'onChange', propType: 'func', description: '值发生变化', }, { name: 'onVisibleChange', propType: 'func', description: '弹层显示隐藏变化', }, { name: 'onRemove', propType: 'func', description: 'Tag 被删除', }, { name: 'onSearch', propType: 'func', description: '搜索', }, ], }, }, icon: '', category: '内容', }; ================================================ FILE: packages/fusion-ui/lowcode/select/snippets.js ================================================ module.exports = [ { title: '选择器', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_select.png', schema: { componentName: 'Select', props: { mode: 'single', hasArrow: true, cacheValue: true, dataSource: [ { value: '1', label: '选项1', }, { value: '2', label: '选项2', }, { value: '3', label: '选项3', }, ], }, }, }, ]; ================================================ FILE: packages/fusion-ui/lowcode/step-form/meta.ts ================================================ import { operationConfig } from '../common'; import { IComponentDescription, ISnippet } from '../types'; import { hideProp } from '../utils'; import stepProps, { operations } from './step-props'; const snippets: ISnippet[] = [ { title: '步骤表单', screenshot: 'https://img.alicdn.com/imgextra/i4/O1CN01HFWZfM24k4gYve7im_!!6000000007428-55-tps-56-56.svg', schema: { componentName: 'StepForm', props: { current: 0, operations: [ { content: '上一步', action: 'previous', type: 'secondary', }, { content: '下一步', action: 'next', type: 'primary', }, ], }, children: [ { componentName: 'ProForm', props: { stepItemProps: { title: 'StepItem', }, }, children: [...new Array(3).keys()].map((item) => ({ componentName: 'FormInput', props: { formItemProps: { primaryKey: String(Math.floor(Math.random() * 10000) + item), label: '表单项', size: 'medium', device: 'desktop', fullWidth: true, }, placeholder: '请输入', }, })), }, { componentName: 'ProForm', props: { stepItemProps: { title: 'StepItem', }, }, children: [ { componentName: 'ProFormItem', props: { primaryKey: String(Math.floor(Math.random() * 10000)), label: '表单项', size: 'medium', device: 'desktop', }, }, { componentName: 'ProFormItem', props: { primaryKey: String(Math.floor(Math.random() * 10000)), label: '表单项', size: 'medium', device: 'desktop', }, }, { componentName: 'ProFormItem', props: { primaryKey: String(Math.floor(Math.random() * 10000)), label: '表单项', size: 'medium', device: 'desktop', }, }, ], }, ], }, }, ]; const ProFormMeta: IComponentDescription[] = [ { componentName: 'StepForm', category: '表单类', title: '步骤表单', group: '精选组件', docUrl: '', screenshot: '', devMode: 'procode', npm: { package: '@alifd/fusion-ui', version: '0.1.4', exportName: 'StepForm', main: 'lib/index.js', destructuring: true, subName: '', }, configure: { component: { isContainer: false, }, supports: { style: true, events: ['saveField', 'onSubmit', 'onChange'], }, props: [...stepProps, operationConfig, operations], }, snippets, }, { componentName: 'Step.Item', title: '步骤项', docUrl: '', screenshot: '', npm: { package: '@alifd/next', version: '{{version}}', exportName: 'Step', main: '', destructuring: true, subName: 'Item', }, props: [ { name: 'icon', propType: 'string', description: '图标', }, { name: 'title', propType: { type: 'instanceOf', value: 'node', }, defaultValue: '步骤项', description: '标题', }, { name: 'content', title: { label: '内容', tip: 'content|内容填充, shape为 arrow 时无效', }, propType: { type: 'instanceOf', value: 'node', }, description: '内容填充, shape为 arrow 时无效', }, { name: 'status', title: { label: '状态', tip: 'status|步骤的状态,如不传,会根据外层的 Step 的 current 属性生成,可选值为 `wait`, `process`, `finish`', }, propType: { type: 'oneOf', value: ['wait', 'process', 'finish'], }, description: '步骤的状态,如不传,会根据外层的 Step 的 current 属性生成,可选值为 `wait`, `process`, `finish`', }, { name: 'percent', propType: 'number', description: '百分比', }, { name: 'disabled', propType: 'bool', description: '是否禁用', }, { name: 'onClick', propType: 'func', description: '点击步骤时的回调\n@param {Number} index 节点索引', }, { name: 'className', propType: 'string', description: '自定义样式', }, { name: 'style', propType: 'object', }, ], configure: { props: { isExtends: true, override: [ { name: 'icon', title: { label: '图标', tip: 'icon|图标', }, setter: { componentName: 'IconSetter', }, }, { name: 'title', setter: { componentName: 'StringSetter', }, defaultValue: '步骤项', title: '标题', }, { name: 'content', condition: hideProp, title: { label: '内容', tip: 'content|内容', }, setter: { componentName: 'TextAreaSetter', }, }, { name: 'status', title: { label: '状态', tip: 'status|状态', }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '等待', value: 'wait', }, { title: '进行中', value: 'process', }, { title: '结束', value: 'finish', }, { title: '默认', value: '', }, ], }, }, }, ], }, }, category: 'null', icon: '', }, ]; export default ProFormMeta; ================================================ FILE: packages/fusion-ui/lowcode/step-form/step-props.ts ================================================ import { hideProp } from '../utils'; export default [ { name: '!items', title: '步骤项', setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'icon', title: '图标', important: true, setter: 'IconSetter', }, { name: 'title', title: '标题', important: true, setter: 'StringSetter', }, { name: 'status', title: { label: '状态', tip: '步骤的状态,如不传,会根据外层的 Step 的 current 属性生成,可选值为 `wait`, `process`, `finish`', }, setter: { componentName: 'RadioGroupSetter', props: { options: ['wait', 'process', 'finish'] }, }, }, { name: 'content', title: { label: '内容', tip: 'content|内容填充, shape为 arrow 时无效', }, condition: hideProp, setter: 'TextAreaSetter', description: '内容填充, shape为 arrow 时无效', }, { name: 'percent', title: '百分比', setter: 'NumberSetter', description: '百分比', }, { name: 'disabled', title: '是否禁用', setter: 'BoolSetter', description: '是否禁用', }, ], }, }, initialValue: () => { return { primaryKey: String(Math.floor(Math.random() * 10000)), title: 'StepItem', }; }, }, }, }, getValue(target) { // const node = target.node; // const children = node.children; const map = target.node.children.map((child) => { const stepItemProps = child.getPropValue('stepItemProps') || {}; const primaryKey = stepItemProps.primaryKey ? stepItemProps.primaryKey : child.id; return { ...stepItemProps, primaryKey, }; }); return map; }, setValue(target, value) { const { node } = target; const map = {}; if (!Array.isArray(value)) { value = []; } value.forEach((item) => { const tabitem = Object.assign({}, item); map[item.primaryKey] = tabitem; }); node.children.mergeChildren( (child) => { const primaryKey = String(child.getPropValue('primaryKey')); if (Object.hasOwnProperty.call(map, primaryKey)) { child.setPropValue('stepItemProps', map[primaryKey]); delete map[primaryKey]; return false; } return true; }, () => { const items = []; for (const primaryKey in map) { if (Object.hasOwnProperty.call(map, primaryKey)) { items.push({ componentName: 'ProForm', props: { columns: 1, primaryKey, stepItemProps: map[primaryKey], }, children: [...new Array(3).keys()].map((item) => ({ componentName: 'FormInput', props: { formItemProps: { primaryKey: String(Math.floor(Math.random() * 10000) + item), label: '表单项', size: 'medium', device: 'desktop', fullWidth: true, }, placeholder: '请输入', }, })), }); } } return items; }, (child1, child2) => { const a = value.findIndex( (item) => String(item.primaryKey) === String(child1.getPropValue('primaryKey')), ); const b = value.findIndex( (item) => String(item.primaryKey) === String(child2.getPropValue('primaryKey')), ); return a - b; }, ); }, }, { name: 'current', setter: (target) => { return { componentName: 'MixedSetter', props: { setters: [ { componentName: 'SelectSetter', props: () => { const items = target.getProps().getPropValue('!items') || []; return { options: items.map((item, index: number) => { return { title: `第 ${index + 1} 步: ${item.title}`, value: `${index}`, }; }), }; }, }, 'ExpressionSetter', ], }, }; }, setValue: (target, value) => { target.parent.setPropValue('current', +value); }, title: '当前步骤', defaultValue: 0, }, { name: 'shape', title: '类型', setter: (target) => { const options = target.getProps().getPropValue('direction') === 'ver' ? ['circle', 'dot'] : ['circle', 'arrow', 'dot']; return { componentName: 'RadioGroupSetter', props: { options, }, }; }, defaultValue: 'circle', }, { name: 'direction', condition: (target) => { return target.getProps().getPropValue('shape') !== 'arrow'; }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { value: 'hoz', title: '横向' }, { value: 'ver', title: '纵向' }, ], }, }, title: '展示方向', defaultValue: 'hoz', }, { name: 'showAll', condition: (target) => { return target.getProps().getPropValue('direction') === 'ver'; }, title: '展示所有表单', setter: { componentName: 'BoolSetter', }, }, { name: 'labelPlacement', condition: hideProp, setter: { componentName: 'RadioGroupSetter', props: { options: ['hoz', 'ver'], }, }, title: '内容排列', defaultValue: 'ver', }, { name: 'readOnly', setter: 'BoolSetter', title: '是否只读', }, { name: 'animation', setter: 'BoolSetter', title: '开启动效', defaultValue: true, }, ]; export const operations = { name: 'operations', display: 'block', title: '操作项', getValue: (target, value) => { return value || []; }, setter: { componentName: 'MixedSetter', props: { setters: [ { componentName: 'SlotSetter', defaultValue: { type: 'JSSlot', value: [], }, }, { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'content', display: 'inline', title: '文本', setter: 'StringSetter', important: true, extraProps: { supportVariable: true, }, }, { name: 'action', display: 'inline', title: '操作', important: true, setValue: (target, value) => { const actionNameMap = { submit: '提交', reset: '重置', custom: '自定义', }; const actionName = actionNameMap[value] || '自定义'; target.parent.setPropValue('content', actionName); }, setter: { componentName: 'SelectSetter', props: { options: [ { title: '提交', value: 'submit', action: 'submit', }, { title: '重置', value: 'reset', action: 'reset', }, { title: '上一步', value: 'previous', action: 'previous', }, { title: '下一步', value: 'next', action: 'next', }, { title: '自定义', value: 'custom', }, ], }, }, }, { name: 'type', display: 'inline', title: '样式', important: true, setter: { componentName: 'SelectSetter', props: { options: [ { title: '主要', value: 'primary', }, { title: '次要', value: 'secondary', }, { title: '普通', value: 'normal', }, ], }, }, }, { name: 'behavior', title: '交互设置', display: 'block', condition: (target) => { const action = target.parent.getPropValue('action'); return !action || action === 'custom'; }, setter: { componentName: 'BehaviorSetter', props: { actions: ['onClick'], }, }, }, { name: 'onClick', display: 'inline', title: '点击事件', condition: hideProp, setter: 'FunctionSetter', extraProps: { supportVariable: true, }, }, { name: 'htmlType', condition: hideProp, }, { name: '!autoSubmit', display: 'inline', virtual: true, title: '自动提交', setter: { componentName: 'BoolSetter', }, extraProps: { setValue: (target, value) => { target.parent.setPropValue('htmlType', value ? 'submit' : ''); }, getValue: (target, value) => { return value === 'submit'; }, }, condition: (target) => { return target.parent.getPropValue('action') !== 'submit'; }, }, ], }, }, initialValue: () => { return { content: '提交', action: 'submit', type: 'secondary', }; }, }, }, }, ], }, }, }; ================================================ FILE: packages/fusion-ui/lowcode/story-placeholder/meta.ts ================================================ import { IPublicModelNode } from '@alilc/lowcode-types'; import { IComponentDescription, ISnippet } from '../types'; const snippets: ISnippet[] = [ { title: '需求占位', screenshot: 'https://img.alicdn.com/tfs/TB160cKkP39YK4jSZPcXXXrUFXa-112-64.png', schema: { title: '需求占位', componentName: 'StoryPlaceholder', props: { title: '需求占位描述', content: { subject: '需求标题', hideTitle: false, description: '

- 你可以在这里描述需求
- 或者粘贴需求截图

', }, }, }, }, ]; interface INode extends IPublicModelNode { startRect: any; beforeSpan: number; parentRect: any; } const meta: IComponentDescription = { componentName: 'StoryPlaceholder', title: '需求占位', npm: { package: '@alifd/fusion-ui', version: 'latest', exportName: 'StoryPlaceholder', main: '', destructuring: true, subName: '', }, configure: { supports: { style: true, }, props: [ { name: 'maxHeight', title: '最大高度', propType: 'number', setter: 'NumberSetter', description: '最大高度', }, { name: 'content', title: '需求关联', display: 'inline', supportVariable: true, setter: { componentName: 'EditSetter', props: { title: '编辑内容', }, }, }, ], }, advanced: { getResizingHandlers: () => { return ['e']; }, callbacks: { onResizeStart: (e, currentNode: INode) => { const parent = currentNode.parent; if (parent) { const parentNode = parent.getDOMNode(); if (parentNode) { currentNode.parentRect = parentNode.getBoundingClientRect(); } } currentNode.beforeSpan = currentNode.getPropValue('colSpan') || 12; currentNode.startRect = currentNode.getRect(); }, onResize: (e, currentNode: INode) => { const { deltaX } = e; const startWidth = currentNode.startRect ? currentNode.startRect.width : currentNode.beforeSpan * (currentNode.parentRect.width / 12); let width = startWidth + deltaX; if (!currentNode.startRect) { currentNode.startRect = { width, }; } width = Math.max(0, width); // 不能小于0 width = Math.min(width, currentNode.parentRect.width); // 不能大于父容器宽度 currentNode.getDOMNode().style.width = `${Math.round(width)}px`; }, onResizeEnd: (e, currentNode) => { currentNode.setPropValue('style.width', currentNode.getDOMNode().style.width); }, }, }, icon: 'https://img.alicdn.com/imgextra/i3/O1CN01G7Lc8e1pZL7p4cdKc_!!6000000005374-2-tps-112-112.png', category: '基础元素', group: '精选组件', hidden: true, }; export default { ...meta, snippets, }; ================================================ FILE: packages/fusion-ui/lowcode/tab-container/meta.ts ================================================ import { ComponentMetadata, Snippet } from '@ali/lowcode-types'; import props from './props'; const snippets: Snippet[] = [ { title: '选项卡', screenshot: 'https://img.alicdn.com/imgextra/i4/O1CN01mh9LPG268B90t8DaA_!!6000000007616-55-tps-56-56.svg', schema: { componentName: 'TabContainer', props: { shape: 'pure', size: 'medium', excessMode: 'slide', }, children: [ { componentName: 'TabContainer.Item', props: { title: '标签项1', primaryKey: 'tab-item-1', }, }, { componentName: 'TabContainer.Item', props: { title: '标签项2', primaryKey: 'tab-item-2', }, }, ], }, }, ]; const tabItemMeta = { componentName: 'TabContainer.Item', title: '选项卡', docUrl: '', screenshot: '', devMode: 'proCode', npm: { package: '@alifd/fusion-ui', version: '{{version}}', exportName: 'TabContainer', main: 'lib/index.js', destructuring: true, subName: 'Item', }, configure: { props: [ { title: { label: { type: 'i18n', 'en-US': 'title', 'zh-CN': '选项卡标题', }, tip: 'title | 选项卡标题', }, name: 'title', description: '选项卡标题', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'closeable', 'zh-CN': '单个选项卡是否可关闭', }, tip: 'closeable | 单个选项卡是否可关闭', }, name: 'closeable', description: '单个选项卡是否可关闭', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'disabled', 'zh-CN': '选项卡是否被禁用', }, tip: 'disabled | 选项卡是否被禁用', }, name: 'disabled', description: '选项卡是否被禁用', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'prefix', 'zh-CN': '样式类名的品牌前缀', }, tip: 'prefix | 样式类名的品牌前缀', }, name: 'prefix', description: '样式类名的品牌前缀', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'locale', 'zh-CN': '国际化文案对象,属性', }, tip: 'locale | 国际化文案对象,属性为组件的 displayName', }, name: 'locale', description: '国际化文案对象,属性为组件的 displayName', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'pure', 'zh-CN': '是否开启 Pure ', }, tip: 'pure | 是否开启 Pure Render 模式,会提高性能,但是也会带来副作用', }, name: 'pure', description: '是否开启 Pure Render 模式,会提高性能,但是也会带来副作用', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'warning', 'zh-CN': '是否在开发模式下显示', }, tip: 'warning | 是否在开发模式下显示组件属性被废弃的 warning 提示', }, name: 'warning', description: '是否在开发模式下显示组件属性被废弃的 warning 提示', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, { title: { label: { type: 'i18n', 'en-US': 'rtl', 'zh-CN': '是否开启 rtl 模', }, tip: 'rtl | 是否开启 rtl 模式', }, name: 'rtl', description: '是否开启 rtl 模式', setter: { componentName: 'StringSetter', isRequired: false, initialValue: '', }, }, ], supports: { events: [ { name: 'onClick', }, { name: 'onChange', }, ], style: true, }, component: { isContainer: true, disableBehaviors: '*', }, advanced: { hideSelectTools: true, callbacks: { onMouseDownHook: () => false, onClickHook: () => false, }, }, }, }; const TabContainerMeta: ComponentMetadata[] = [ { componentName: 'TabContainer', title: '选项卡', category: '布局容器类', group: '精选组件', docUrl: '', screenshot: 'https://img.alicdn.com/imgextra/i4/O1CN01mh9LPG268B90t8DaA_!!6000000007616-55-tps-56-56.svg', devMode: 'proCode', npm: { package: '@alifd/fusion-ui', version: '{{version}}', exportName: 'TabContainer', main: 'lib/index.js', destructuring: true, subName: '', }, configure: { component: { isContainer: true, nestingRule: { childWhitelist: ['TabContainer.Item'], }, }, props, supports: { style: true, }, }, snippets, }, tabItemMeta, // compatible with the exsting json schema which has componentName: Tab.Item { ...tabItemMeta, componentName: 'Tab.Item', } ]; export default TabContainerMeta; ================================================ FILE: packages/fusion-ui/lowcode/tab-container/props.ts ================================================ export default [ { name: 'items', title: '标签项', setter: { componentName: 'ArraySetter', props: { itemSetter: { componentName: 'ObjectSetter', props: { config: { items: [ { name: 'title', title: '名称', defaultValue: '标签项', important: true, setter: 'StringSetter', }, { name: 'primaryKey', title: '项目编号', condition: () => false, setter: 'StringSetter', }, { name: 'closeable', title: '可关闭', initialValue: false, setter: 'BoolSetter', }, { name: 'disabled', title: '是否禁用', initialValue: false, setter: 'BoolSetter', }, ], }, }, initialValue: () => { return { primaryKey: String(Math.floor(Math.random() * 10000)), title: '标签项', closeable: false, disabled: false, }; }, }, }, }, extraProps: { getValue(target) { const map = target.node.children.map((child) => { const primaryKey = child.getPropValue('primaryKey') ? String(child.getPropValue('primaryKey')) : child.id; return { primaryKey, title: child.getPropValue('title') || '标签项', closeable: child.getPropValue('closeable'), disabled: child.getPropValue('disabled'), }; }); return map; }, setValue(target, value) { const { node } = target; const map = {}; if (!Array.isArray(value)) { value = []; } value.forEach((item) => { const tabitem = Object.assign({}, item); map[item.primaryKey] = tabitem; }); node.children.mergeChildren( (child) => { const primaryKey = String(child.getPropValue('primaryKey')); if (Object.hasOwnProperty.call(map, primaryKey)) { child.setPropValue('title', map[primaryKey].title); child.setPropValue('closeable', map[primaryKey].closeable); child.setPropValue('disabled', map[primaryKey].disabled); delete map[primaryKey]; return false; } return true; }, () => { const items = []; for (const primaryKey in map) { if (Object.hasOwnProperty.call(map, primaryKey)) { items.push({ componentName: 'TabContainer.Item', props: map[primaryKey], }); } } return items; }, (child1, child2) => { const a = value.findIndex( (item) => String(item.primaryKey) === String(child1.getPropValue('primaryKey')), ); const b = value.findIndex( (item) => String(item.primaryKey) === String(child2.getPropValue('primaryKey')), ); return a - b; }, ); }, }, }, { name: 'shape', title: '形态', defaultValue: 'pure', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '普通型', value: 'pure' }, { title: '包裹型', value: 'wrapped' }, { title: '文本型', value: 'text' }, { title: '胶囊型', value: 'capsule' }, ], }, }, }, { name: 'size', title: '尺寸', defaultValue: 'medium', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '小', value: 'small' }, { title: '中', value: 'medium' }, ], }, }, }, { name: 'excessMode', title: '选项卡过多时的滑动模式', defaultValue: 'slide', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '滑动', value: 'slide' }, { title: '下拉', value: 'dropdown' }, ], }, }, }, { name: 'tabPosition', title: { label: '导航选项卡的位置', tip: '只适用于包裹型(wrapped)选项卡', }, condition: (target) => { const shape = target.getProps().getPropValue('shape'); return shape === 'wrapped'; }, defaultValue: 'top', setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '顶部', value: 'top', }, { title: '底部', value: 'bottom', }, { title: '左边', value: 'left', }, { title: '右边', value: 'right', }, ], }, }, }, ]; ================================================ FILE: packages/fusion-ui/lowcode/tree-select/meta.js ================================================ import { wrapFormItemProps } from '../utils/form-utils'; export default { componentName: 'FormTreeSelect', isFormItemComponent: true, title: '树型选择控件', docUrl: '', screenshot: '', npm: { package: '@alifd/fusion-ui', version: '{{version}}', exportName: 'FormTreeSelect', main: '', destructuring: true, subName: '', }, configure: { props: wrapFormItemProps([ { name: 'placeholder', title: { label: '占位提示', tip: '属性: placeholder', }, defaultValue: '请选择', // 不生效 setter: 'StringSetter', }, { name: 'hasClear', title: { label: '清除按钮', tip: '属性: hasClear', }, setter: 'BoolSetter', defaultValue: false, }, { name: 'showSearch', title: { label: '可搜索', tip: '属性: showSearch', }, setter: 'BoolSetter', defaultValue: false, }, { name: 'label', title: '内联文案', setter: { componentName: 'StringSetter', }, }, { name: 'dataSource', title: { label: '节点数据', tip: '数据源', }, setter: 'JsonSetter', }, ]), }, icon: '', category: '内容', }; ================================================ FILE: packages/fusion-ui/lowcode/tree-select/snippets.js ================================================ module.exports = [ { title: '树型选择控件', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_tree-select.png', schema: { componentName: 'TreeSelect', props: { prefix: 'next-', size: 'medium', hasArrow: true, hasBorder: true, autoWidth: true, notFoundContent: 'Not Found', treeCheckedStrategy: 'parent', }, }, }, { title: '树形控件', screenshot: 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_tree.png', schema: { componentName: 'Tree', props: { prefix: 'next-', selectable: true, checkedStrategy: 'all', autoExpandParent: true, animation: true, focusable: true, }, }, }, ]; ================================================ FILE: packages/fusion-ui/lowcode/types/index.ts ================================================ import { IPublicTypeComponentMetadata, IPublicTypeSnippet, IPublicTypeFieldConfig, IPublicModelSettingField } from '@alilc/lowcode-types'; export interface ISnippet extends IPublicTypeSnippet { label?: string; title?: string; } export interface IComponentDescription extends IPublicTypeComponentMetadata { snippets?: ISnippet[]; } export interface IProps extends IPublicTypeFieldConfig { showInListSetter?: boolean; initialValue?: Function | any; editable?: boolean; items?: IProps[] | IPublicTypeFieldConfig[]; } export interface SetterProps { forceInline?: boolean; key?: string; prop?: IPublicModelSettingField; selected?: any; field?: IPublicModelSettingField; value: any; onChange: Function; onInitial?: Function; removeProp?: Function; } export interface IAssets { components?: IComponentDescription[]; } ================================================ FILE: packages/fusion-ui/lowcode/upload/meta.js ================================================ import { wrapFormItemProps } from '../utils/form-utils'; export default { componentName: 'FormUpload', isFormItemComponent: true, title: '上传', docUrl: '', screenshot: '', npm: { package: '@alifd/fusion-ui', version: '{{version}}', exportName: 'FormUpload', main: '', destructuring: true, subName: '', }, props: [ { name: 'action', propType: 'string', description: '上传的地址', }, { name: 'value', propType: { type: 'Json', }, description: '文件列表', }, { name: 'defaultValue', propType: 'object', description: '默认文件列表', }, { name: 'shape', propType: { type: 'oneOf', value: ['card'], }, description: '上传按钮形状', }, { name: 'listType', propType: { type: 'oneOf', value: ['text', 'image', 'card'], }, description: '上传列表的样式', }, { name: 'name', propType: 'string', description: '文件名字段', }, { name: 'data', propType: { type: 'oneOfType', value: ['object', 'func'], }, description: '上传额外传参', }, { name: 'formatter', propType: 'func', title: { label: '数据格式化函数', tip: '数据格式化函数,配合自定义 action 使用,参数为服务器的响应数据,详见 [formatter](#formater)\n@param {Object} response 返回\n@param {File} file 文件对象', }, }, { name: 'limit', propType: 'number', description: '最大文件上传个数', defaultValue: null, }, { name: 'timeout', propType: 'number', description: '设置上传超时,单位ms', }, { name: 'dragable', propType: 'bool', description: '可选参数,是否支持拖拽上传,`ie10+` 支持。', }, { name: 'useDataURL', propType: 'bool', description: '可选参数,是否本地预览', }, { name: 'disabled', propType: 'bool', description: '可选参数,是否禁用上传功能', }, { name: 'onSelect', propType: 'func', description: '选择文件回调', }, { name: 'onProgress', propType: 'func', description: '上传中', }, { name: 'onChange', propType: 'func', description: '上传文件改变时的状态\n@param {Object} info 文件事件对象', }, { name: 'onSuccess', propType: 'func', description: '可选参数,上传成功回调函数,参数为请求下响应信息以及文件\n@param {Object} file 文件\n@param {Array} value 值', }, { name: 'afterSelect', propType: 'func', description: '可选参数, 用于校验文件,afterSelect仅在 autoUpload=false 的时候生效,autoUpload=true时,可以使用beforeUpload完全可以替代该功能.\n@param {Object} file\n@returns {Boolean} 返回false会阻止上传,其他则表示正常', }, { name: 'onRemove', propType: 'func', description: '移除文件回调函数\n@param {Object} file 文件\n@returns {Boolean|Promise} 返回 false、Promise.resolve(false)、 Promise.reject() 将阻止文件删除', }, { name: 'onError', propType: 'func', description: '可选参数,上传失败回调函数,参数为上传失败的信息、响应信息以及文件\n@param {Object} file 出错的文件\n@param {Array} value 当前值', }, { name: 'beforeUpload', propType: 'func', title: { label: '开始上传时回调', tip: '可选参数, 详见 [beforeUpload](#beforeUpload)\n@param {Object} file 所有文件\n@param {Object} options 参数\n@returns {Boolean|Object|Promise} 返回值作用见demo', }, }, { name: 'onDrop', propType: 'func', description: '放文件', }, { name: 'className', propType: 'string', description: '自定义class', }, { name: 'style', propType: 'object', description: '自定义内联样式', }, { name: 'autoUpload', propType: 'bool', description: '自动上传', defaultValue: true, }, { name: 'request', propType: 'func', description: '自定义上传方法\n@param {Object} option\n@return {Object} object with abort method', }, { name: 'progressProps', propType: 'object', description: '透传给Progress props', }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', }, { name: 'renderPreview', propType: 'func', description: '预览态模式下渲染的内容\n@param {number} value 评分值', }, ], configure: { props: wrapFormItemProps([ { name: 'defaultValue', title: '默认值', setter: { componentName: 'JsonSetter', }, }, { name: 'shape', title: '按钮形状', defaultValue: '', setValue: (target, value) => { const { node } = target; if (value === 'card') { node.removeChild(node.children.get(0)); } else { node.children?.importSchema({ componentName: 'Button', props: { children: '上传文件', type: 'primary', }, }); } }, setter: { componentName: 'RadioGroupSetter', props: { options: [ { title: '默认', value: '', }, { title: '卡片', value: 'card', }, ], }, }, description: '上传按钮形状', }, { name: 'listType', title: '列表样式', setter: { componentName: 'RadioGroupSetter', props: { options: ['text', 'image', 'card'], }, }, defaultValue: 'text', description: '上传列表的样式', }, { name: 'limit', title: '数量限制', setter: 'NumberSetter', }, { name: 'disabled', title: '是否禁用', setter: 'BoolSetter', }, { type: 'group', title: '高级', display: 'block', items: [ { name: 'id', title: { label: { type: 'i18n', zh_CN: '唯一标识', en_US: 'ID', }, tip: { type: 'i18n', zh_CN: '属性: id | 说明: 唯一标识', en_US: 'prop: id | description: switch id', }, }, setter: 'StringSetter', }, { name: 'name', title: { label: { type: 'i18n', zh_CN: '表单标识', en_US: 'Name', }, tip: { type: 'i18n', zh_CN: '属性: name | 说明: 表单标识', en_US: 'prop: name | description: switch name', }, }, setter: 'StringSetter', }, ], }, ]), }, advanced: { initialChildren: [ { componentName: 'Button', props: { children: '上传文件', type: 'primary', }, }, ], initials: [ { name: 'shape', initial: () => '', }, ], }, icon: '', category: '内容', }; ================================================ FILE: packages/fusion-ui/lowcode/utils/form-utils.ts ================================================ import { IProps } from '../types'; import { default as formItemProps } from '../pro-form/common/form-item-props'; export const wrapFormItemProps = (props: IProps[]) => { return [ ...formItemProps, { name: 'componentProps', title: '组件配置', extraProps: { display: 'accordion', defaultCollapsed: true, }, type: 'group', items: props.filter((item) => item.title !== '高级'), }, ]; }; ================================================ FILE: packages/fusion-ui/lowcode/utils/index.ts ================================================ export const hideProp = () => false; export function isJSExpression(data: any) { return data && data.type === 'JSExpression'; } export const deepEqual = function (x, y) { if (x === y) { return true; } else if (typeof x === 'object' && x != null && typeof y === 'object' && y !== null) { if (Object.keys(x).length !== Object.keys(y).length) return false; for (const prop in x) { if (y.hasOwnProperty(prop)) { if (!deepEqual(x[prop], y[prop])) return false; } else return false; } return true; } else return false; }; export const showWithLabelAlign = (target) => { const parentLabelAlign = target && target.parent.node.parent.getPropValue('labelAlign'); const labelAlign = parentLabelAlign || (target && target.parent.getPropValue('labelAlign')); if (labelAlign === 'top') { const enableLabelTip = target.parent.getPropValue('labelTip.enable'); if (enableLabelTip) { return target.name.startsWith('labelTip'); } return target.name === 'labelTip.enable'; } if (labelAlign === 'inset') { return target.name.startsWith('wrapper'); } if (labelAlign === 'left') { return !target.name.startsWith('labelTip'); } return true; }; export const showWithLabelAlignShortcut = (target) => { const { labelAlign: parentLabelAlign } = target && target.parent.node.propsData; const labelAlign = parentLabelAlign || (target && target.parent.getPropValue('labelAlign')); if (labelAlign === 'top') { const enableLabelTip = target.parent.getPropValue('labelTip.enable'); if (enableLabelTip) { return target.name.startsWith('labelTip'); } return target.name === 'labelTip.enable'; } if (labelAlign === 'inset') { return target.name.startsWith('wrapper'); } if (labelAlign === 'left') { return !target.name.startsWith('labelTip'); } return true; }; export const showWithFormItemType = (target, type) => { const formItemType = target && target.getProps().getPropValue('type'); return formItemType === type; }; export const propsFormWrapper = (props, formItemType) => { return props.map((item) => { item.condition = (target) => { return showWithFormItemType(target, formItemType); }; item.name = `componentPorps.${item.name}`; return item; }); }; export const getParentValue = (target) => { return target.getProps().node.parent.getPropValue(target.name); }; export const uuid = () => Math.random().toString(36).substr(-6); export const mockId = () => `id-${uuid()}`; ================================================ FILE: packages/fusion-ui/lowcode/utils/keybindingService.ts ================================================ interface cbFunc { (node: any, e: KeyboardEvent): void; } export interface IKeyBinding { command: string; keybinding: string | string[]; components: string | string[]; cb: cbFunc; desc?: string; } /* example export const KeybindingMap: IKeyBinding[] = [ { command: 'updateColSpan', keybinding: 's', components: ['NextBlockCell'], cb: (node) => { updateColSpan({ parent: node.parent, child: node, type: 'split', }); }, }, ]; */ class KeybindingService { hotkey: any; designer: any; keybindingMap: IKeyBinding[]; constructor() { const engine = (window.parent as any).AliLowCodeEngine; this.hotkey = engine.hotkey; this.designer = engine.designer; this.keybindingMap = []; } bind(kb: IKeyBinding) { if (kb.command && this.keybindingMap.find((k) => k.command === kb.command)) { console.warn('KeybindingService Error[duplicated command]', kb.command); return; } this.keybindingMap.push(kb); this.hotkey.bind(kb.keybinding, (e: KeyboardEvent) => { const node = this.getSelectedNode(); if (!node) { console.warn(`No node select on keydown: ${kb.keybinding}`); return; } if (!this.isValidNode(node, kb)) { console.warn(`Not valid node for keydown target: ${kb.keybinding}`); return; } kb.cb.apply(null, [node, e]); }); } // unbind, hotkey 暂时不支持 execCommand(command: string, node: any, ...rest: any[]) { const targetKb = this.keybindingMap.find((kb) => kb.command === command); if (!targetKb) { console.warn(`No command founded from keybindingMap: ${command}`); return; } if (!node || !this.isValidNode(node, targetKb)) { console.warn(`Not valid node target for command: ${command} ${node}`); return; } targetKb.cb.apply(null, [node, ...rest]); } private getSelectedNode() { const selectedNodeId = this.designer.currentDocument.selection.selected[0]; return selectedNodeId ? this.designer.currentDocument.nodesMap.get(selectedNodeId) : null; } private isValidNode(node: any, kb: IKeyBinding) { return kb.components.includes(node.componentName); } } export const keybindingService = new KeybindingService(); ================================================ FILE: packages/fusion-ui/lowcode/week-picker/meta.js ================================================ export default { componentName: 'WeekPicker', title: 'WeekPicker', docUrl: '', screenshot: '', npm: { package: '@alifd/next', version: '{{version}}', exportName: 'DatePicker', main: '', destructuring: true, subName: 'WeekPicker', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'rtl', propType: 'bool', defaultValue: false, }, { name: 'label', propType: { type: 'instanceOf', value: 'node', }, description: '表单项内置标签', }, { name: 'state', propType: { type: 'oneOf', value: ['success', 'loading', 'error'], }, description: '表单项状态', }, { name: 'placeholder', propType: 'string', description: '输入提示', }, { name: 'defaultVisibleMonth', propType: 'func', description: '默认展现的月\n@return {MomentObject} 返回包含指定月份的 moment 对象实例', }, { name: 'onVisibleMonthChange', propType: 'func', }, { name: 'value', propType: { type: 'instanceOf', value: 'custom', }, description: '日期值(受控)moment 对象', }, { name: 'defaultValue', propType: { type: 'instanceOf', value: 'custom', }, description: '初始日期值,moment 对象', }, { name: 'format', propType: 'string', description: '日期值的格式(用于限定用户输入和展示)', defaultValue: 'YYYY-wo', }, { name: 'disabledDate', propType: 'func', description: '禁用日期函数\n@param {MomentObject} 日期值\n@param {String} view 当前视图类型,year: 年, month: 月, date: 日\n@return {Boolean} 是否禁用', }, { name: 'footerRender', propType: 'func', description: '自定义面板页脚\n@return {Node} 自定义的面板页脚组件', }, { name: 'onChange', propType: 'func', description: '日期值改变时的回调\n@param {MomentObject|String} value 日期值', }, { name: 'size', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '表单项尺寸', defaultValue: 'medium', }, { name: 'disabled', propType: 'bool', description: '是否禁用', }, { name: 'hasClear', propType: 'bool', description: '是否显示清空按钮', defaultValue: true, }, { name: 'visible', propType: 'bool', description: '弹层显示状态', }, { name: 'defaultVisible', propType: 'bool', description: '弹层默认是否显示', defaultValue: false, }, { name: 'onVisibleChange', propType: 'func', description: '弹层展示状态变化时的回调\n@param {Boolean} visible 弹层是否显示\n@param {String} type 触发弹层显示和隐藏的来源 calendarSelect 表示由日期表盘的选择触发; okBtnClick 表示由确认按钮触发; fromTrigger 表示由trigger的点击触发; docClick 表示由document的点击触发', }, { name: 'popupTriggerType', propType: { type: 'oneOf', value: ['click', 'hover'], }, description: '弹层触发方式', defaultValue: 'click', }, { name: 'popupAlign', propType: 'string', description: '弹层对齐方式,具体含义见 OverLay文档', defaultValue: 'tl tl', }, { name: 'popupContainer', propType: 'any', description: '弹层容器\n@param {Element} target 目标元素\n@return {Element} 弹层的容器元素', }, { name: 'popupStyle', propType: 'object', description: '弹层自定义样式', }, { name: 'popupClassName', propType: 'string', description: '弹层自定义样式类', }, { name: 'popupProps', propType: 'object', description: '弹层其他属性', }, { name: 'followTrigger', propType: 'bool', description: '是否跟随滚动', }, { name: 'inputProps', propType: 'object', description: '表单项其他属性', }, { name: 'dateCellRender', propType: 'func', description: '自定义日期渲染函数\n@param {Object} value 日期值(moment对象)\n@returns {ReactNode}', }, { name: 'monthCellRender', propType: 'func', description: '自定义月份渲染函数\n@param {Object} calendarDate 对应 Calendar 返回的自定义日期对象\n@returns {ReactNode}', }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', }, { name: 'renderPreview', propType: 'func', description: '预览态模式下渲染的内容\n@param {MomentObject} value 年份', }, { name: 'yearCellRender', propType: 'func', }, { name: 'locale', propType: 'object', }, { name: 'className', propType: 'string', }, { name: 'name', propType: 'string', }, { name: 'popupComponent', propType: { type: 'instanceOf', value: 'elementType', }, }, { name: 'popupContent', propType: { type: 'instanceOf', value: 'node', }, }, { name: 'style', propType: 'object', }, ], category: '基础', }; ================================================ FILE: packages/fusion-ui/lowcode/year-picker/meta.js ================================================ export default { componentName: 'YearPicker', title: 'YearPicker', docUrl: '', screenshot: '', npm: { package: '@alifd/next', version: '{{version}}', exportName: 'DatePicker', main: '', destructuring: true, subName: 'YearPicker', }, props: [ { name: 'prefix', propType: 'string', defaultValue: 'next-', }, { name: 'rtl', propType: 'bool', defaultValue: false, }, { name: 'label', propType: { type: 'instanceOf', value: 'node', }, description: '表单项内置标签', }, { name: 'state', propType: { type: 'oneOf', value: ['success', 'loading', 'error'], }, description: '表单项状态', }, { name: 'placeholder', propType: 'string', description: '输入提示', }, { name: 'value', propType: { type: 'instanceOf', value: 'custom', }, description: '日期值(受控)moment 对象', }, { name: 'defaultValue', propType: { type: 'instanceOf', value: 'custom', }, description: '初始日期值,moment 对象', }, { name: 'format', propType: 'string', description: '日期值的格式(用于限定用户输入和展示)', defaultValue: 'YYYY', }, { name: 'disabledDate', propType: 'func', description: '禁用日期函数\n@param {MomentObject} 日期值\n@param {String} view 当前视图类型,year: 年, month: 月, date: 日\n@return {Boolean} 是否禁用', }, { name: 'footerRender', propType: 'func', description: '自定义面板页脚\n@return {Node} 自定义的面板页脚组件', }, { name: 'onChange', propType: 'func', description: '日期值改变时的回调\n@param {MomentObject|String} value 日期值', }, { name: 'size', propType: { type: 'oneOf', value: ['small', 'medium', 'large'], }, description: '表单项尺寸', defaultValue: 'medium', }, { name: 'disabled', propType: 'bool', description: '是否禁用', }, { name: 'hasClear', propType: 'bool', description: '是否显示清空按钮', defaultValue: true, }, { name: 'visible', propType: 'bool', description: '弹层显示状态', }, { name: 'defaultVisible', propType: 'bool', description: '弹层默认是否显示', }, { name: 'onVisibleChange', propType: 'func', description: '弹层展示状态变化时的回调\n@param {Boolean} visible 弹层是否显示\n@param {String} reason 触发弹层显示和隐藏的来源 calendarSelect 表示由日期表盘的选择触发; fromTrigger 表示由trigger的点击触发; docClick 表示由document的点击触发', }, { name: 'popupTriggerType', propType: { type: 'oneOf', value: ['click', 'hover'], }, description: '弹层触发方式', defaultValue: 'click', }, { name: 'popupAlign', propType: 'string', description: '弹层对齐方式, 具体含义见 OverLay文档', defaultValue: 'tl tl', }, { name: 'popupContainer', propType: 'any', description: '弹层容器\n@param {Element} target 目标元素\n@return {Element} 弹层的容器元素', }, { name: 'popupStyle', propType: 'object', description: '弹层自定义样式', }, { name: 'popupClassName', propType: 'string', description: '弹层自定义样式类', }, { name: 'popupProps', propType: 'object', description: '弹层其他属性', }, { name: 'followTrigger', propType: 'bool', description: '是否跟随滚动', }, { name: 'inputProps', propType: 'object', description: '表单项其他属性', }, { name: 'yearCellRender', propType: 'func', }, { name: 'dateInputAriaLabel', propType: 'string', description: '日期表单项的 aria-label 属性', }, { name: 'isPreview', propType: 'bool', description: '是否为预览态', }, { name: 'renderPreview', propType: 'func', description: '预览态模式下渲染的内容\n@param {MomentObject} value 年份', }, { name: 'locale', propType: 'object', }, { name: 'className', propType: 'string', }, { name: 'name', propType: 'string', }, { name: 'popupComponent', propType: { type: 'instanceOf', value: 'elementType', }, }, { name: 'popupContent', propType: { type: 'instanceOf', value: 'node', }, }, { name: 'style', propType: 'object', }, ], category: '基础', }; ================================================ FILE: packages/fusion-ui/package.json ================================================ { "name": "@alifd/fusion-ui", "version": "2.1.0", "description": "A component library based on Fusion Next", "files": [ "es/", "lib/", "build/", "dist/", "lowcode/", "lowcode_lib/", "lowcode_es/" ], "main": "lib/index.js", "module": "es/index.js", "lowcodeEditMain": "build/lowcode/view.js", "stylePath": "style.js", "scripts": { "start": "npm run dumi", "build": "build-scripts build", "lowcode:dev": "build-scripts start --config ./build.lowcode.js", "lowcode:build": "build-scripts build --config ./build.lowcode.js", "test": "build-scripts test", "lint": "f2elint scan", "lint:fix": "f2elint fix", "dumi": "cross-env APP_ROOT=docs dumi dev", "dumi:build": "cross-env APP_ROOT=docs dumi build", "prepublishOnly": "npm run build && npm run lowcode:build && npm run dumi:build" }, "keywords": [ "react", "component" ], "dependencies": { "@alifd/layout": "^2.0.7", "@alifd/next": "^1.25.18", "@antv/data-set": "^0.11.8", "@sindresorhus/is": "^4.0.1", "ahooks": "^2.10.11", "bizcharts": "^4.1.16", "classnames": "^2.3.1", "framer-motion": "^4.1.17", "lodash": "^4.17.21", "moment": "^2.29.4", "numeral": "^2.0.6", "numvert": "^0.2.2", "prop-types": "^15.5.8", "qs": "^6.10.1", "rc-resize-observer": "^1.0.0", "react-beautiful-dnd": "^13.1.0", "react-sortablejs": "6.1.1", "sortablejs": "^1.14.0", "@babel/runtime": "^7.0.0" }, "devDependencies": { "@alifd/theme-2": "^0.4.4", "node-sass": "^8.0.0", "@umijs/plugin-sass": "^1.1.1", "@alilc/lowcode-engine": "^1.0.0", "@alib/build-scripts": "^0.1.3", "@alifd/build-plugin-lowcode": "^0.4.0", "@types/lodash": "^4.14.177", "@types/react": "^16.14.15", "@types/react-dom": "^16.9.4", "build-plugin-component": "^1.12.0", "build-plugin-fusion": "^0.1.0", "build-plugin-load-assets": "^0.1.3", "build-plugin-moment-locales": "^0.1.0", "cross-env": "^7.0.3", "dumi": "^1.1.49", "enzyme": "^3.10.0", "enzyme-adapter-react-16": "^1.14.0", "eslint": "^6.0.1", "f2elint": "^1.2.0", "fs-extra": "^10.0.0", "marked": "^2.1.3", "prop-types": "^15.7.2", "remark-codesandbox": "^0.10.0", "reqwest": "^2.0.5", "to-string-loader": "^1.1.6" }, "peerDependencies": { "@alifd/next": "1.x", "react": "^16.9.0", "react-dom": "^16.9.0" }, "resolutions": { "webpack": "4.x" }, "license": "MIT", "homepage": "https://unpkg.com/@alifd/fusion-ui@2.1.0/build/index.html", "componentConfig": { "name": "FusionUI", "category": "精品物料库", "isComponentLibrary": true, "materialSchema": "https://alifd.alicdn.com/npm/@alifd/fusion-ui@2.1.0/build/lowcode/assets-prod.json" }, "husky": { "hooks": { "pre-commit": "f2elint commit-file-scan", "commit-msg": "f2elint commit-msg-scan" } }, "materialConfig": { "fusion-site": { "id": 1, "name": "PC 官网", "url": "https://fusion.design/api/v1/sites/1/materials" } }, "repository": "https://github.com/alibaba/lowcode-materials.git", "exports": { "./prototype": { "require": "./lowcode_lib/meta.js", "import": "./lowcode_es/meta.js" }, "./prototypeView": { "require": "./lowcode_lib/view.js", "import": "./lowcode_es/view.js" }, "./*": "./*", ".": { "import": "./es/index.js", "require": "./lib/index.js" } }, "lcMeta": { "type": "component" } } ================================================ FILE: packages/fusion-ui/src/common/operations/index.scss ================================================ #{$biz-css-prefix}common-operations { &.operation-container { display: flex; align-items: center; padding-top: 15px; & > * { margin-left: 10px; } & > *:first-child { margin-left: 0; } &-operation-item + &-operation-item { margin-left: 10px; } &.operation-align-left { justify-content: flex-start; } &.operation-align-center { justify-content: center; } &.operation-align-right { justify-content: flex-end; } &.operation-fixed { width: calc(100vw - var(--sidebar-width, 0px)); position: fixed; padding: 15px; z-index: 999; box-shadow: 0 -4px 10px 0 rgba(74, 91, 109, 0.1); background-color: #fff; bottom: 0; left: var(--sidebar-width, 0); } &.operation-absolute { width: 100%; padding: 15px; position: absolute; background-color: #fff; bottom: 0; left: 0; } } } ================================================ FILE: packages/fusion-ui/src/common/operations/index.tsx ================================================ import * as React from 'react'; import moment from 'moment'; import classnames from 'classnames'; import { Icon, Form } from '@alifd/next'; import { bizCssPrefix } from '@/variables'; import { Button } from '@/components/button'; import { ButtonGroup, ButtonGroupProps } from '@/components/button-group'; const cssPrefix = `${bizCssPrefix}-common-operations`; export interface OperationProps { operations?: any; operationConfig?: any; lastSaveTime?: any; renderDefaultBtns?: any; cssPrefix?: any; } const Operations: React.FC = (props) => { const { cssPrefix: propCssPrefix, operations, operationConfig = {}, lastSaveTime, renderDefaultBtns, } = props; const operationRef = React.useRef(); const operationCssPrefix = 'operation-container'; let classNames = classnames( propCssPrefix || cssPrefix, operationCssPrefix, operationConfig.align ? `operation-align-${operationConfig.align}` : 'operation-align-center', ); if (operationConfig.fixed) { classNames = classnames(classNames, 'operation-fixed'); } const saveTime = operationConfig.showSaveTime ? ( ) : null; const buttonGroupProps: ButtonGroupProps = {}; if (operationConfig.moreMenuButtonProps) { buttonGroupProps.moreMenuButtonProps = operationConfig.moreMenuButtonProps; } if (operationConfig.visibleButtonCount) { buttonGroupProps.visibleButtonCount = operationConfig.visibleButtonCount; } const defaultBtns = renderDefaultBtns && typeof renderDefaultBtns === 'function' ? renderDefaultBtns() : []; if ((!defaultBtns || !defaultBtns.length) && !operations) { return null; } if (!operations) { return (
{defaultBtns} {saveTime}
); } const operationsView = ( operations.type?.displayName === 'Slot' ? operations.props?.children || [] : operations ).map((operation: any, index: number) => { if (React.isValidElement(operation)) { return operation; } const { content, action, onActionClick, ...otherOperationProps } = operation; let BtnComp; if (action === 'submit') { BtnComp = Form.Submit; otherOperationProps.validate = true; otherOperationProps.htmlType = 'submit'; } else if (action === 'reset') { BtnComp = Form.Reset; } else { BtnComp = Button; } if (onActionClick) { otherOperationProps.onClick = onActionClick; } return ( {operation.content} ); }); if ((!defaultBtns || !defaultBtns.length) && (!operationsView || !operationsView.length)) { return null; } const isLowcodePlaceHolder = operationsView.some((item) => item?.type === 'div'); return (
{defaultBtns} {isLowcodePlaceHolder ? null : operationsView} {isLowcodePlaceHolder ? operationsView : null} {saveTime}
); }; export default Operations; ================================================ FILE: packages/fusion-ui/src/components/anchor/components/HozAnchor/index.scss ================================================ #{$biz-css-prefix}anchor-hoz-affix { z-index: 99; } #{$biz-css-prefix}anchor-hoz { padding: var(--s-4 $s-5, $s-4 $s-5); margin-bottom: var(--s-5, $s-5); background: var(--color-white, $color-white); border-radius: var(--corner-2, $corner-2); } ================================================ FILE: packages/fusion-ui/src/components/anchor/components/HozAnchor/index.tsx ================================================ import * as React from 'react'; import cx from 'classnames'; import { Affix } from '@alifd/next'; import { Segment } from '@/components/segment'; import { AnchorProps } from '../../index'; import { startListen, removeListen, jumpToNode } from '../../util'; export class HozAnchor extends React.Component> { state = { currentValue: '', container: null, }; affixRef = React.createRef(); componentDidMount() { const { dataSource, container, offsetY } = this.props; const _container = container(); startListen(dataSource, () => _container, this.updateCurrentValue, { offsetY, }); this.setState({ container: _container, }); } componentWillUnmount() { const { dataSource } = this.props; const { container } = this.state; removeListen(dataSource, () => container); } updateCurrentValue = (newValue) => { if (newValue === this.state.currentValue) { return; } this.setState({ currentValue: newValue, }); }; onChange = (newValue) => { const { onChange } = this.props; const status = onChange && onChange(newValue); if (status !== false) { this.setState({ currentValue: newValue, }); jumpToNode(newValue); } }; render() { const { dataSource, className, style, hasAffix, affixProps, containerRef, offsetY } = this.props; const { container } = this.state; const { currentValue } = this.state; const classes = cx({ 'fusion-ui-anchor-hoz': true, [className]: !!className, }); const segmentDataSource = dataSource.map((item) => ({ label: item.label, value: item.htmlId, })); const anchorEl = (
); if (hasAffix) { const self = this.affixRef?.current?.getInstance?.(); // FIXME: 为了解决一个页面多个 affix 会导致除最后一个 affix 外其余 affix 失效的问题,需要手动重新设置监听事件, // 但调用了 affix 的内部方法,如果 affix 新版本的这个内部方法有变动,则需要加上兼容逻辑 const func = self?._setEventHandlerForContainer; if (typeof func === 'function') { func.call(self, () => container); } removeListen(dataSource, () => container) startListen(dataSource, () => container, this.updateCurrentValue, { offsetY, }); return ( container} {...affixProps}> {anchorEl} ); } return anchorEl; } } ================================================ FILE: packages/fusion-ui/src/components/anchor/components/VerAnchor/AnchorList/AnchorLink.tsx ================================================ import React from 'react'; import classNames from 'classnames'; import { Ellipsis } from '@/components/ellipsis/index'; export interface AnchorLinkProps { isFocus: boolean; label: string; htmlId: string; level: number; onSelect: (htmlId: string) => void; } export class AnchorLink extends React.Component { static displayName = 'AnchorLink'; static defaultProps = { onSelect: () => {}, }; render() { const { label, htmlId, isFocus, level, onSelect } = this.props; const cls = classNames({ 'fusion-ui-anchor-item': true, [`fusion-ui-anchor-item-level-${level}`]: true, 'fusion-ui-anchor-item-active': !!isFocus, }); return (
onSelect(htmlId)}> {label}
); } } ================================================ FILE: packages/fusion-ui/src/components/anchor/components/VerAnchor/AnchorList/index.scss ================================================ #{$biz-css-prefix}anchor-ver-menu { padding: var(--s-4, $s-4); background: var(--color-white, $color-white); box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.1); width: 160px; &-header { position: absolute; display: none; top: var(--s-4, $s-4); left: 14px; width: var(--s-1, $s-1); height: var(--s-3, $s-3); border-radius: 2px; background: var(--color-brand1-6, $color-brand1-6); transition: top 0.3s ease; } &-footer { border-left: 1px solid $color-line1-2; #{$biz-css-prefix}anchor-item { font-weight: var(--font-weight-medium, $font-weight-medium); font-size: var(--font-size-body-1, $font-size-body-1); color: var(--color-text1-4, $color-text1-4); &:hover { cursor: pointer; } &:not(:last-child) { margin-bottom: var(--s-4, $s-4); } &-active, &:hover { color: var(--color-brand1-6, $color-brand1-6); } &-level-1 { padding-left: var(--s-3, $s-3); } &-level-2 { padding-left: var(--s-5, $s-5); } } } } ================================================ FILE: packages/fusion-ui/src/components/anchor/components/VerAnchor/AnchorList/index.tsx ================================================ import React from 'react'; import { AnchorLink, AnchorLinkProps } from './AnchorLink'; import { LinkItemData } from '../../../index'; interface AnchorListProps { value: string; dataSource: LinkItemData[]; onSelect: (htmlId) => void; } interface AnchorTocState { menuList: AnchorLinkProps[]; } /** * 将原本的嵌套 dataSource 转换为扁平 * 并直接将 focus 状态等计算好附加上 * @param menuList 目标扁平列表,直接做修改 * @param props 组件属性 * @param level 锚点嵌套等级 */ const renderMenu = (menuList, props, level: number) => { const { onSelect, dataSource, value } = props; dataSource.forEach((item) => { const isFocus = value === item.htmlId; menuList.push({ level, label: item.label, htmlId: item.htmlId, isFocus, onSelect, }); if (Array.isArray(item.children)) { renderMenu(menuList, { ...props, dataSource: item.children }, level + 1); } }); }; export class AnchorList extends React.Component { static displayName = 'AnchorList'; static defaultProps = { dataSource: [], }; static getDerivedStateFromProps = (nextProps) => { const menuList = []; renderMenu(menuList, nextProps, 1); return { menuList, }; }; constructor(props) { super(props); const initialMenuList = []; renderMenu(initialMenuList, props, 1); this.state = { menuList: initialMenuList, }; } render() { const { menuList } = this.state; const firstFocusIdx = menuList.findIndex((item) => item.isFocus); return (
{menuList.map((item) => ( ))}
); } } ================================================ FILE: packages/fusion-ui/src/components/anchor/components/VerAnchor/index.scss ================================================ $fusion-ui-anchor-ver-prefix: '.fusion-ui-anchor-ver'; $anchor-menu-spacing: var(--s-2, $s-2); #{$fusion-ui-anchor-ver-prefix} { position: fixed; z-index: 100; top: 120px; right: 40px; &-expand { #{$fusion-ui-anchor-ver-prefix}-header { padding-left: var(--anchor-menu-spacing, $anchor-menu-spacing); width: 42px + $anchor-menu-spacing; } #{$fusion-ui-anchor-ver-prefix}-footer { margin-left: var(--anchor-menu-spacing, $anchor-menu-spacing); } #{$fusion-ui-anchor-ver-prefix}-body { opacity: 1; } #{$fusion-ui-anchor-ver-prefix}-mask { height: 42px; width: 20px; position: fixed; z-index: 101; top: 120px; right: 80px; background-color: var(--color-white, $color-white); } } &-button { height: 42px; width: 42px; color: var(--color-line1-4, $color-line1-4); background-color: var(--color-white, $color-white); border-radius: var(--corner-2, $corner-2); box-shadow: 0 0 $s-3 0 rgba(0, 0, 0, 0.1); z-index: 10; display: flex; align-items: center; justify-content: center; &:hover { cursor: pointer; } } &-header { transition: padding 0.3s ease-in-out; } &-body { position: absolute; top: 0; right: 42px + $anchor-menu-spacing; opacity: 0; transition: opacity 0.3s ease-in-out; } &-footer { margin-top: var(--s-2, $s-2); } } ================================================ FILE: packages/fusion-ui/src/components/anchor/components/VerAnchor/index.tsx ================================================ import * as React from 'react'; import cx from 'classnames'; import { CustomIcon } from '@/components/toggle-icon'; import { AnchorProps } from '../../index'; import { startListen, removeListen, jumpToNode } from '../../util'; import { AnchorList } from './AnchorList'; export class VerAnchor extends React.Component> { static displayName = 'Anchor'; static defaultProps = { defaultVisible: true, }; state = { currentValue: '', visible: this.props.defaultVisible, container: null, }; prefix = 'fusion-ui-anchor-ver'; componentDidMount() { const { dataSource, container, offsetY } = this.props; const _container = container(); startListen(dataSource, () => _container, this.updateCurrentValue, { offsetY, }); this.setState({ container: _container, }); } componentWillUnmount() { const { dataSource } = this.props; const { container } = this.state; removeListen(dataSource, () => container); } changeMenuStatus = () => { const { visible } = this.state; this.setState({ visible: !visible, }); }; updateCurrentValue = (newValue) => { this.setState({ currentValue: newValue, }); }; handleScrollTop = () => { document.documentElement.scrollTop = 0; document.body.scrollTop = 0; }; onChange = (newValue) => { const { onChange } = this.props; const status = onChange && onChange(newValue); if (status !== false) { this.setState({ currentValue: newValue, }); jumpToNode(newValue); } }; render() { const { className, style, dataSource, scrollTop } = this.props; const { currentValue, visible } = this.state; const classes = cx({ [this.prefix]: true, [`${this.prefix}-expand`]: visible, [className]: !!className, }); return (
); } } ================================================ FILE: packages/fusion-ui/src/components/anchor/index.scss ================================================ @import './theme-dark.scss'; @import './components/HozAnchor/index.scss'; @import './components/VerAnchor/index.scss'; @import './components/VerAnchor/AnchorList/index.scss'; ================================================ FILE: packages/fusion-ui/src/components/anchor/index.tsx ================================================ import * as React from 'react'; import { VerAnchor } from './components/VerAnchor'; import { HozAnchor } from './components/HozAnchor'; import { AffixProps as NextAffixProps } from '@alifd/next/types/affix'; export interface LinkItemData { // 跳转的 htmlId htmlId: string; // 链接文案 label: string; /** * 嵌套层级 * 仅在 direction="ver" 生效,且最大层级不超过二级 */ children?: LinkItemData[]; } export interface AnchorProps extends Omit, 'onChange'> { /** * 自定义样式名 */ className?: string; /** * 自定义样式 */ style?: React.CSSProperties; /** * 锚点方向 * 水平方向 dataSource 不支持属性 */ direction?: 'ver' | 'hoz'; /** * 锚点列表数据源 */ dataSource: LinkItemData[]; /** * 设置是否为财鲸页面的锚点 * 设置后会修改 container 为 () => document.querySelector('#fusion-ui-page > div.fusion-ui-page-content-wrapper'); */ isWhalePageAnchor?: boolean; /** * 容器,默认是 window */ container?: () => React.ReactElement> | Element; /** * direction="hoz" 生效 * 开启可在滚动超出屏幕后固定在屏幕 */ hasAffix?: boolean; /** * hasAffix={true} 后使用 * 用于覆盖 Affix 的属性值 */ affixProps?: NextAffixProps; /** * 点击不同锚点时的自定义触发函数 * 默认跳转到对应 htmlId 节点 * 可返回布尔值,如返回 false,则阻止默认跳转操作 */ onChange?: (htmlId: string) => boolean; /** * 垂直跳转偏移量 */ offsetY?: number; /** * [方向垂直可用] * 用于设定悬浮锚点的菜单是否默认展开 * @default true */ defaultVisible?: boolean; /** * 自定义滚动到页首的方法 */ scrollTop?: () => void; containerRef?: any; } function getScrollElement(element: HTMLElement) { if (!element) return element; if (elementCanScroll(element)) { return element; } return getScrollElement(element.parentElement); } function elementCanScroll(element: any) { if (!element || !(element instanceof HTMLElement)) { console.log('invalid element'); return false; } if (element.scrollTop > 0) { return true; } else { element.scrollTop++; const top = element.scrollTop; top && (element.scrollTop = 0); return top > 0; } } export class Anchor extends React.Component { static displayName = 'Anchor'; static defaultProps = { direction: 'ver', isWhalePageAnchor: false, offsetY: 0, scrollTop: () => { const container = getScrollElement(document.querySelector('[class^="fusion-ui-anchor"]')) || document.documentElement; if (container) { container.scrollIntoView({ behavior: 'smooth' }); } }, }; ref = React.createRef(); render() { const { direction, isWhalePageAnchor, ...otherProps } = this.props; otherProps.container = otherProps.container ? otherProps.container : () => { let container = getScrollElement(this.ref?.current || document.querySelector('[class^="fusion-ui-anchor"]')); if (!container || container === document.documentElement) { container = window; } return container; }; if (direction === 'hoz') { return ; } return ; } } ================================================ FILE: packages/fusion-ui/src/components/anchor/theme-dark.scss ================================================ body.dark { #{$biz-css-prefix}anchor { &-hoz, &-ver-button, &-ver-menu, &-ver-mask { background-color: var(--color-fill1-1, $color-fill1-1); } &-ver-button { color: inherit; &:hover { color: var(--color-brand1-6, $color-brand1-6); a { color: var(--color-brand1-6, $color-brand1-6); } } } } } ================================================ FILE: packages/fusion-ui/src/components/anchor/util.ts ================================================ import { events } from '@/utils/util'; import debounce from 'lodash/debounce'; let timeout: number; /** * 用于监听当前页面到达哪一个锚点 * @param dataSource 数据源 * @param container 函数,返回监听容器 * @param cb 锚点改变时触发 * @param external 放置额外参数,例如 offsetY */ export const startListen = (dataSource, container, cb, external: { offsetY: number }, doNotUpdate=false) => { if (!doNotUpdate) { updateNodePosition(dataSource, container, cb, external); } timeout = window.setTimeout(() => { setEventHandlerForContainer(dataSource, container, cb, external); }); }; export const setEventHandlerForContainer = (dataSource, container, cb, external) => { const affixContainer = container(); if (affixContainer) { events.on( affixContainer, 'scroll', updateNodePosition.bind(null, dataSource, container, cb, external), false, ); events.on( affixContainer, 'resize', updateNodePosition.bind(null, dataSource, container, cb, external), false, ); } }; /** * 解除 startListen 带来的监听功能 */ export const removeListen = (dataSource, container) => { if (timeout) { clearTimeout(timeout); timeout = null; } removeEventHandlerForContainer(dataSource, container); }; const removeEventHandlerForContainer = (dataSource, container) => { const affixContainer = container(); if (affixContainer) { events.off(affixContainer, 'scroll', updateNodePosition.bind(null, dataSource, container)); events.off(affixContainer, 'resize', updateNodePosition.bind(null, dataSource, container)); } }; /** * 获取节点已经滚动的距离 */ export function getScroll(node, isVertical) { if (typeof window === 'undefined') { return 0; } const windowProp = isVertical ? 'pageYOffset' : 'pageXOffset'; const elementProp = isVertical ? 'scrollTop' : 'scrollLeft'; return node === window ? node[windowProp] : node[elementProp]; } /** * 滚动时触发,判断所有在页面中的节点中的”第一个“,并通过 cb 返回此 htmlId */ export const updateNodePosition = debounce((dataSource, container, cb?, external?) => { const { offsetY } = external || {}; const affixContainer = container(); if (affixContainer) { const containerScrollTop = getScroll(affixContainer, true); // 容器在垂直位置上的滚动 offset let findEl; const predicateItem = (item) => { const el = item?.htmlId && document.getElementById(item.htmlId); if (el) { if (el.offsetTop >= containerScrollTop + offsetY) { findEl = item.htmlId; return true; } } return false; }; dataSource.some((item) => { const status = predicateItem(item); if (!status && Array.isArray(item.children)) { item.children.some((subItem) => { const subStatus = predicateItem(subItem); return subStatus; }); } return !!findEl; }); if (findEl) { cb && cb(findEl); } } }, 100); /** * 用于在特定容器内跳转到对应的锚点位置 * 增加 offsetY,用于跳转的偏移,防止部分元素 fixed 遮挡锚点 */ export const jumpToNode = (htmlId) => { const el = htmlId && document.getElementById(htmlId); el.scrollIntoView({ behavior: 'smooth' }); }; ================================================ FILE: packages/fusion-ui/src/components/area-chart/index.tsx ================================================ import React from 'react'; import { AreaChart as BizAreaChart } from 'bizcharts'; type Iprops = React.ComponentProps; function AreaChart(props:Iprops) { return ( ); } export default AreaChart; ================================================ FILE: packages/fusion-ui/src/components/bar-chart/index.tsx ================================================ import React from 'react'; import { BarChart as BizBarChart } from 'bizcharts'; type Iprops = React.ComponentProps; function BarChart(props:Iprops) { return ( ); } export default BarChart; ================================================ FILE: packages/fusion-ui/src/components/button/Button.tsx ================================================ import * as React from 'react'; import { Button as NextButton, Badge as NextBadge, Balloon } from '@alifd/next'; import { BadgeProps } from '@alifd/next/types/badge'; import { ButtonProps as NextButtonProps } from '@alifd/next/types/button'; export interface ButtonProps extends NextButtonProps { /** * 徽标相关属性 */ badgeProps?: BadgeProps; tooltipProps?: TooltipProps; } export interface TooltipProps { showTooltip: boolean; tooltipMessage: string; triggerType: 'click' | 'hover'; } export interface ButtonState { showTooltip: boolean; tooltipMessage: string; triggerType: 'click' | 'hover'; } export class Button extends React.Component { static displayName = 'Button'; static getDerivedStateFromProps = ( nextProps: ButtonProps, prevState: ButtonState = { showTooltip: false, tooltipMessage: '', triggerType: 'click', }, ) => { const { tooltipProps = {} } = nextProps; return { ...prevState, ...tooltipProps, }; }; constructor(props: ButtonProps) { super(props); const { tooltipProps = {} } = props; this.state = { showTooltip: false, tooltipMessage: '', triggerType: 'click', ...tooltipProps, }; } /** * @deprecated * @param message * @param triggerType */ toggleTip = (message: string, triggerType: 'click' | 'hover') => { const { triggerType: stateTriggerType } = this.state; this.setState({ showTooltip: true, tooltipMessage: message, triggerType: triggerType || stateTriggerType || 'click', }); }; enableTooltip = (triggerType: 'click' | 'hover' = 'click', message: string) => { const { triggerType: stateTriggerType } = this.state; this.setState({ showTooltip: true, tooltipMessage: message, triggerType: triggerType || stateTriggerType || 'click', }); }; render() { const { showTooltip, tooltipMessage, triggerType } = this.state; const { badgeProps, id, ...otherProps } = this.props; const buttonComp = ; let finalComp = buttonComp; if (badgeProps) { finalComp = {buttonComp}; } if (showTooltip) { finalComp = ( {tooltipMessage} ); } return
{finalComp}
; } } ================================================ FILE: packages/fusion-ui/src/components/button/index.tsx ================================================ export * from './Button'; ================================================ FILE: packages/fusion-ui/src/components/button-group/ButtonGroup.tsx ================================================ import * as React from 'react'; import omit from 'lodash/omit'; import cx from 'classnames'; import { Button, ButtonProps } from '@/components/button'; import { MenuButton, MenuButtonProps } from '@/components/menu-button'; import { Space, SpaceProps } from '@/components/container'; import checkComName from '@/utils/checkComName'; export interface ButtonGroupProps extends SpaceProps { /** * 自定义样式 */ style?: React.CSSProperties; /** * 自定义样式名 */ className?: string; /** * 是否设定按钮为文字模式 */ text?: boolean; /** * 可见按钮数量,超过会收起到”更多“菜单中 */ visibleButtonCount?: number | false; /** * 数据源驱动,如传入 children,则以 children 优先 */ dataSource?: ButtonProps[]; /** * "更多" 按钮的额外配置 */ moreMenuButtonProps?: Partial; /** * 国际化文案 */ i18nBundle?: any; } export class ButtonGroup extends React.Component { static defaultProps = { visibleButtonCount: 3, moreMenuButtonProps: {}, }; static displayName = 'ButtonGroup'; /** * 将 dataSource 和 children 处理成真正的 dataSource */ getDataSource = () => { const { dataSource, children, text } = this.props; let externalProps: Partial = {}; if (text) { externalProps = { type: 'primary', text: true, }; } const realDataSource: object[] = []; if (children) { React.Children.forEach(children, (child) => { if (checkComName(child, Button)) { realDataSource.push({ ...externalProps, ...child.props, }); } else if ( // 表单操作按钮逻辑兼容 checkComName(child, null, [ 'SubmitButton', 'ResetButton', 'Submit', 'Reset', 'Form.Submit', 'Form.Reset', 'Config(Button)', ]) ) { realDataSource.push(child); } }); } else if (Array.isArray(dataSource)) { dataSource.forEach((dataSourceItem) => { realDataSource.push({ ...externalProps, ...dataSourceItem, }); }); } return realDataSource; }; /** * 获取可展示的 dataSource & 折叠的 dataSource */ getVisibleDataSourceAndCollapseDataSource = (dataSource) => { const { visibleButtonCount } = this.props; if (visibleButtonCount === false) { return { visible: dataSource, collapse: [], }; } const visibleDataSource = []; const collapseDataSource = []; dataSource.forEach((dataSourceItem, idx) => { if (idx >= visibleButtonCount) { collapseDataSource.push(dataSourceItem); } else { visibleDataSource.push(dataSourceItem); } }); return { visible: visibleDataSource, collapse: collapseDataSource, }; }; /** * 渲染可展示的 dataSource */ renderVisible(dataSource) { const buttonList = []; dataSource.forEach((dataSourceItem, idx) => { if (React.isValidElement(dataSourceItem)) { buttonList.push(dataSourceItem); } else { buttonList.push( )}
); }; const _children = renderChildren(); const content = ( {formatFormItems(_children, { columns: propsCols, ...others, })} ); return
{content}
; }; Filter.defaultProps = { buttons: {}, defaultExpand: false, expand: undefined, cols: 4, visibleRowCount: 1, rowGap: 12, enableFilterConfiguration: false, onExpand: () => {}, formProps: {}, responsive: false, hideDefaultButtons: false, hideExpandButton: false, enableForm: false, }; export { Filter }; ================================================ FILE: packages/fusion-ui/src/components/filter/theme-dark.scss ================================================ .dark { .fusion-ui-filter-configurator { background-color: var(--color-fill1-1, $color-fill1-1); .fusion-ui-filter-configurator-item.dragging { background-color: var(--color-fill1-4 !important, $color-fill1-4 !important); } .fusion-ui-icon-close { color: var(--color-text1-2, $color-text1-2); } &-title { border-bottom-color: var(--color-line1-4, $color-line1-4); } } } ================================================ FILE: packages/fusion-ui/src/components/line-chart/index.tsx ================================================ import React from 'react'; import { LineChart as BizLineChart } from 'bizcharts'; type Iprops = React.ComponentProps; function LineChart(props: Iprops) { return ( ); } export default LineChart; ================================================ FILE: packages/fusion-ui/src/components/menu/Menu.tsx ================================================ import * as React from 'react'; import omit from 'lodash/omit'; import cx from 'classnames'; import { Menu as NextMenu, Loading as NextLoading, Icon } from '@alifd/next'; import { MenuProps as NextMenuProps } from '@alifd/next/types/menu'; import { SelectableItem as MenuItem } from './MenuItem'; const { PopupItem: MenuPopupItem, CheckboxItem: MenuCheckboxItem, RadioItem: MenuRadioItem, SubMenu, Group, Divider, } = NextMenu; export interface MenuItemProps { /** * 菜单值 */ key?: string; /** * 类型 * @default item */ type?: 'item' | 'popupItem' | 'checkboxItem' | 'radioItem' | 'divider' | 'group' | 'subMenu'; /** * 展示标签 */ label?: string; /** * 是否处于禁用状态 */ disabled?: boolean; /** * 自定义 label 展示 */ children?: React.ReactNode; /** * 帮助文本 */ helper?: React.ReactNode; } export interface MenuProps extends Omit { /** * 是否处于加载状态 */ loading?: boolean; /** * 是否出错 */ error?: boolean | string; /** * 数据源 */ dataSource?: MenuItemProps[]; /** * 国际化文案 */ i18nBundle?: Record; } export class Menu extends React.Component { static displayName = 'Menu'; renderChildren(dataSource) { const menuItemList: React.ReactElement[] = []; Array.isArray(dataSource) && dataSource.forEach((dataItem) => { if (!dataItem.type || dataItem.type?.toLowerCase() === 'item') { menuItemList.push(); } if (dataItem.type?.toLowerCase() === 'popupitem') { menuItemList.push(); } if (dataItem.type?.toLowerCase() === 'checkboxitem') { const children = dataItem.children || dataItem.label; menuItemList.push( {children} , ); } if (dataItem.type?.toLowerCase() === 'radioitem') { const children = dataItem.children || dataItem.label; menuItemList.push( {children} , ); } if (dataItem.type?.toLowerCase() === 'divider') { menuItemList.push(); } if (dataItem.type?.toLowerCase() === 'group') { menuItemList.push( {this.renderChildren(dataItem.children)} , ); } if (dataItem.type?.toLowerCase() === 'submenu') { menuItemList.push( {this.renderChildren(dataItem.children)} , ); } }); return menuItemList; } renderLoadingContent() { return ; } renderErrorContent() { const { error, i18nBundle } = this.props; const errorText = typeof error === 'boolean' ? i18nBundle.error : error; return (
{errorText}
); } render() { const { className, dataSource, loading, error, i18nBundle, ...otherProps } = this.props; const classes = cx({ 'fusion-ui-menu': true, [className]: !!className, }); let children; if (loading) { children = this.renderLoadingContent(); } else if (error) { children = this.renderErrorContent(); } else { children = this.renderChildren(dataSource); } const menuProps = { className: classes, ...otherProps, }; return {children} ; } } ================================================ FILE: packages/fusion-ui/src/components/menu/MenuItem.tsx ================================================ import React from 'react'; import PropTypes from 'prop-types'; import cx from 'classnames'; import { Checkbox, Icon } from '@alifd/next'; import { func, obj, KEYCODE } from '@/utils/util'; import Item from '@alifd/next/lib/menu/view/item'; import { CheckboxProps } from '@alifd/next/types/checkbox'; import { MenuItemText } from './MenuItemText'; const { bindCtx } = func; const { pickOthers } = obj; export interface SelectableItemProps { /** * 用于显示标签文字 */ label?: string; /** * 自定义样式名 */ className?: string; /** * 是否禁用 */ disabled?: boolean; /** * 帮助文本 */ helper?: React.ReactNode; /** * 是否缩进 */ needIndent?: boolean; /** * 是否处于加载状态 */ loading?: boolean; /** * 是否有展开功能 */ hasExpand?: boolean; /** * 受控值,显示是否展开 */ expanded?: boolean; /** * 当 hasExpand={true} 时,展开触发 */ onExpand?: () => void; /** * 用于覆盖 checkbox 的属性 */ checkboxProps?: Partial; /** * 自定义渲染标签文字,传入则 label 失效 */ children?: React.ReactNode; _key?: string; root?: any; } export class SelectableItem extends React.Component { static menuChildType = 'item'; static propTypes = { _key: PropTypes.string, root: PropTypes.object, selected: PropTypes.bool, onSelect: PropTypes.func, inlineIndent: PropTypes.number, /** * 是否禁用 */ disabled: PropTypes.bool, /** * 帮助文本 */ helper: PropTypes.node, /** * 菜单项标签内容 */ children: PropTypes.node, className: PropTypes.string, onKeyDown: PropTypes.func, onClick: PropTypes.func, needIndent: PropTypes.bool, }; static defaultProps = { disabled: false, needIndent: true, }; constructor(props) { super(props); bindCtx(this, ['handleKeyDown', 'handleClick']); } getSelected() { const { _key, root, selected } = this.props; const { selectMode } = root.props; const { selectedKeys } = root.state; return selected || (!!selectMode && selectedKeys.indexOf(_key) > -1); } handleSelect(e) { const { _key, root, onSelect } = this.props; if (onSelect) { onSelect(!this.getSelected(), this, e); } else { root.handleSelect(_key, !this.getSelected(), this); } } handleKeyDown(e) { if (e.keyCode === KEYCODE.SPACE && !this.props.disabled) { this.handleSelect(e); } this.props.onKeyDown && this.props.onKeyDown(e); } handleClick(e) { this.handleSelect(e); this.props.onClick && this.props.onClick(e); } render() { const { _key, root, className, disabled, helper, label, children, needIndent, loading, // 展开状态 hasExpand, onExpand, expanded, checkboxProps, } = this.props; const { prefix, selectMode } = root.props; const others = pickOthers(Object.keys(SelectableItem.propTypes), this.props); const selected = this.getSelected(); const newProps = { _key, root, disabled, type: 'item', className: cx({ 'fusion-ui-menu-item': true, [`${prefix}selected`]: selected, [className]: !!className, }), onKeyDown: this.handleKeyDown, onClick: !disabled ? this.handleClick : this.props.onClick, needIndent, ...others, }; const textProps = {}; if ('selectMode' in root.props) { textProps['aria-selected'] = selected; } let innerText = ( {label} ); if (children) { innerText = (
{children}
); } const checkProps = { disabled, checked: selected, ...checkboxProps, }; let innerRightIcon; if (loading) { innerRightIcon = ; } // 对于可展开模式,选中状态及选中函数进行特殊处理 if (hasExpand) { checkProps.onChange = this.handleClick; newProps.onClick = !disabled && onExpand; newProps.className = cx({ 'fusion-ui-menu-item': true, [`${prefix}selected`]: expanded, [className]: !!className, }); if (!innerRightIcon) { innerRightIcon = ( ); } } return (
{selectMode === 'multiple' && } {innerText}
{helper ?
{helper}
: null} {innerRightIcon}
); } } ================================================ FILE: packages/fusion-ui/src/components/menu/MenuItemText.tsx ================================================ import * as React from 'react'; import { Balloon } from '@alifd/next'; export type MenuItemTextProps = React.HTMLAttributes; export class MenuItemText extends React.Component { ref = React.createRef(); state = { isOverflow: false, }; componentDidMount() { if (this.ref.current && this.ref.current.scrollWidth > this.ref.current.offsetWidth) { this.setState({ isOverflow: true, }); } } render() { const { isOverflow } = this.state; const { children, ...otherProps } = this.props; const trigger = (
{children}
); if (isOverflow) { return ( {children} ); } return trigger; } } ================================================ FILE: packages/fusion-ui/src/components/menu/i18n.ts ================================================ export default { 'zh-CN': { error: '出错了', }, 'en-US': { error: 'Error', }, }; ================================================ FILE: packages/fusion-ui/src/components/menu/index.scss ================================================ @import './theme-dark.scss'; $fusion-ui-prefix: '.fusion-ui-menu'; /* 这里写你漂亮的样式 */ #{$fusion-ui-prefix} { &.fusion-ui-ver { padding: var(--s-2 $s-1, $s-2 $s-1); } #{$fusion-ui-prefix}-content { position: relative; padding: 0 !important; margin: 0 !important; list-style: none; } #{$fusion-ui-prefix}-item.fusion-ui-menu-item { border-radius: var(--s-1, $s-1); // 反选 hover 背景色覆盖 &.fusion-ui-selected { background-color: var(--color-brand1-1, $color-brand1-1); &:focus { background-color: var(--color-brand1-1, $color-brand1-1); } } .next-menu-item-inner { display: flex; align-items: center; justify-content: space-between; font-size: var(--menu-font-size, 12px); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; word-wrap: normal; line-height: var(--menu-line-height, 32px); #{$fusion-ui-prefix}-item-header { flex: 1 1 0; display: flex; align-items: center; // 多选状态下设置为 flex,为放置左侧 icon .next-checkbox { margin-right: 8px; } // 文本超出显示为省略号 .next-menu-item-text { overflow: hidden; text-overflow: ellipsis; } } #{$fusion-ui-prefix}-item-footer { #{$fusion-ui-prefix}-icon-right { color: var(--color-line1-4, $color-line1-4); } } } } &-loading { height: 160px; width: 100%; } &-error { height: 160px; width: 100%; display: flex; justify-content: center; align-items: center; &-content { text-align: center; &-text { font-size: var(--font-size-body-1, $font-size-body-1); line-height: 1.5; color: var(--color-text1-3, $color-text1-3); margin-bottom: 8px; } } } } ================================================ FILE: packages/fusion-ui/src/components/menu/index.tsx ================================================ import { withGlobal } from '@/provider'; import { Menu as PureMenu } from './Menu'; export const Menu = withGlobal(PureMenu, { i18nBundleName: 'Menu', }); export { MenuProps, MenuItemProps } from './Menu'; ================================================ FILE: packages/fusion-ui/src/components/menu/theme-dark.scss ================================================ body.dark { /* 这里写暗色覆盖主题 */ .fusion-ui-menu { .fusion-ui-menu-item.fusion-ui-menu-item { &.fusion-ui-selected { background-color: var(--color-brand1-6, $color-brand1-6); &:not(.fusion-ui-disabled) { &:hover, &.fusion-ui-focused { background-color: var(--color-brand1-6, $color-brand1-6); } } } } .fusion-ui-error-content { color: var(--color-text1-3); } } } ================================================ FILE: packages/fusion-ui/src/components/menu-button/index.scss ================================================ @import '~@alifd/next/lib/core/style/_global.scss'; @import '~@alifd/next/lib/core/style/_motion.scss'; @import 'scss/variable'; #{$menu-btn-prefix} { display: inline-block; box-shadow: none; &-spacing-tb { margin: var(--popup-spacing-tb 0, $popup-spacing-tb 0); } &-popup { box-shadow: 0 $s-1 $s-4 0 rgba(0, 0, 0, 0.1); border-radius: var(--corner-1, $corner-1); .fusion-ui-menu.fusion-ui-ver { border: none; max-height: 272px; overflow: auto; &::-webkit-scrollbar { width: var(--s-2, $s-2); } &::-webkit-scrollbar-thumb { border: 2px solid transparent; background-clip: padding-box; border-radius: 9999px; background-color: var(--color-fill1-1, $color-fill1-1); } &::-webkit-scrollbar-track { background: transparent; } } } .fusion-ui-icon { transition: transform $motion-duration-immediately $motion-linear; } .fusion-ui-menu-btn-arrow::before { content: var(--menu-btn-fold-icon-content, $menu-btn-fold-icon-content); } &.fusion-ui-expand .fusion-ui-btn-icon.fusion-ui-menu-btn-arrow { transform: rotate(180deg); } // --------- this is for config platform &-symbol-unfold::before { content: var(--menu-btn-unfold-icon-content, $menu-btn-unfold-icon-content); } // --------- this is for config platform &.fusion-ui-btn-normal { .fusion-ui-menu-btn-arrow { color: var(--menu-btn-pure-text-normal-icon-color, $menu-btn-pure-text-normal-icon-color); } &:hover .fusion-ui-menu-btn-arrow { color: var(--btn-pure-normal-color-hover, $btn-pure-normal-color-hover); } } &.fusion-ui-btn-secondary { .fusion-ui-menu-btn-arrow { color: var( --menu-btn-pure-text-secondary-icon-color, $menu-btn-pure-text-secondary-icon-color ); } &:hover .fusion-ui-menu-btn-arrow { color: var(--btn-pure-secondary-color-hover, $btn-pure-secondary-color-hover); } &.fusion-ui-btn-text:hover .fusion-ui-menu-btn-arrow { color: var(--btn-text-secondary-color-hover, $btn-text-secondary-color-hover); } } &.fusion-ui-btn-primary { .fusion-ui-menu-btn-arrow { color: var(--menu-btn-pure-text-primary-icon-color, $menu-btn-pure-text-primary-icon-color); } &:hover .fusion-ui-menu-btn-arrow { color: var(--btn-pure-primary-color-hover, $btn-pure-primary-color-hover); } } &.fusion-ui-btn-text.fusion-ui-btn-normal { .fusion-ui-menu-btn-arrow { color: var(--menu-btn-text-text-normal-icon-color, $menu-btn-text-text-normal-icon-color); } &:hover .fusion-ui-menu-btn-arrow { color: var(--btn-text-normal-color-hover, $btn-text-normal-color-hover); } } &.fusion-ui-btn-text.fusion-ui-btn-primary { .fusion-ui-menu-btn-arrow { color: var(--menu-btn-text-text-primary-icon-color, $menu-btn-text-text-primary-icon-color); } &:hover .fusion-ui-menu-btn-arrow { color: var(--btn-text-primary-color-hover, $btn-text-primary-color-hover); } } &.fusion-ui-btn-ghost.fusion-ui-btn-light { .fusion-ui-menu-btn-arrow { color: var(--menu-btn-ghost-light-icon-color, $menu-btn-ghost-light-icon-color); } &:hover .fusion-ui-menu-btn-arrow { color: var(--btn-ghost-light-color-hover, $btn-ghost-light-color-hover); } } &.fusion-ui-btn-ghost.fusion-ui-btn-dark { .fusion-ui-menu-btn-arrow { color: var(--menu-btn-ghost-dark-icon-color, $menu-btn-ghost-dark-icon-color); } &:hover .fusion-ui-menu-btn-arrow { color: var(--btn-ghost-dark-color-hover, $btn-ghost-dark-color-hover); } } &.disabled .fusion-ui-menu-btn-arrow, &[disabled] .fusion-ui-menu-btn-arrow { color: var(--menu-btn-disabled-icon-color, $menu-btn-disabled-icon-color); } &.fusion-ui-btn-text.disabled .fusion-ui-menu-btn-arrow, &.fusion-ui-btn-text[disabled] .fusion-ui-menu-btn-arrow { color: var(--menu-btn-disabled-icon-color, $menu-btn-disabled-icon-color); } &[disabled].fusion-ui-btn-ghost.fusion-ui-btn-dark .fusion-ui-menu-btn-arrow { color: var(--menu-btn-ghost-dark-disabled-icon-color, $menu-btn-ghost-dark-disabled-icon-color); } &[disabled].fusion-ui-btn-ghost.fusion-ui-btn-light .fusion-ui-menu-btn-arrow { color: var( --menu-btn-ghost-light-disabled-icon-color, $menu-btn-ghost-light-disabled-icon-color ); } } ================================================ FILE: packages/fusion-ui/src/components/menu-button/index.tsx ================================================ import React from 'react'; import classnames from 'classnames'; import { Menu, MenuProps } from '@/components/menu'; import { Overlay, Icon, Button } from '@alifd/next'; import { func } from '@/utils/util'; import { MenuButtonProps as NextMenuButtonProps } from '@alifd/next/types/menu-button'; const { Popup } = Overlay; export interface MenuButtonProps extends NextMenuButtonProps { /** * 下拉菜单数据源 */ dataSource?: MenuProps['dataSource']; } export interface MenuButtonState { visible?: boolean; selectedKeys?: string[]; } /** * MenuButton */ export class MenuButton extends React.Component { static displayName = 'MenuButton'; static defaultProps = { prefix: 'fusion-ui-', autoWidth: true, popupTriggerType: 'click', onVisibleChange: func.noop, onItemClick: func.noop, onSelect: func.noop, defaultSelectedKeys: [], menuProps: {}, dataSource: [], }; static getDerivedStateFromProps(props) { const st: Partial = {}; if ('visible' in props) { st.visible = props.visible; } if ('selectedKeys' in props) { st.selectedKeys = props.selectedKeys; } return st; } constructor(props) { super(props); this.state = { selectedKeys: props.defaultSelectedKeys, visible: props.defaultVisible, }; } clickMenuItem = (key, ...others) => { const { selectMode } = this.props; this.props.onItemClick(key, ...others); if (selectMode === 'multiple') { return; } this.onPopupVisibleChange(false, 'menuSelect'); }; selectMenu = (keys, ...others) => { if (!('selectedKeys' in this.props)) { this.setState({ selectedKeys: keys, }); } this.props.onSelect(keys, ...others); }; onPopupOpen = () => { const button = this.node; if (this.props.autoWidth && button && this.menu && this.menu.style) { this.menu.style.width = `${button.offsetWidth}px`; } }; onPopupVisibleChange = (visible, type) => { if (!('visible' in this.props)) { this.setState({ visible, }); } this.props.onVisibleChange(visible, type); }; _menuRefHandler = (ref) => { this.menu = ref; const refFn = this.props.menuProps.ref; if (typeof refFn === 'function') { refFn(ref); } }; render() { const { prefix, style, className, label, popupTriggerType, popupContainer, popupStyle, popupClassName, popupProps, followTrigger, selectMode, menuProps, dataSource, children, // 未用到的 props onSelect, defaultSelectedKeys, onVisibleChange, autoWidth, onItemClick, ...others } = this.props; const { visible, selectedKeys } = this.state; const classNames = classnames( { [`${prefix}menu-btn`]: true, [`${prefix}expand`]: visible, opened: visible, }, className, ); const popupClassNames = classnames({ [popupClassName]: !!popupClassName, [`${prefix}menu-btn-popup`]: true, }); const trigger = ( ); return ( { this.node = node; }} style={popupStyle} className={popupClassNames} {...popupProps} >
); } } ================================================ FILE: packages/fusion-ui/src/components/menu-button/scss/variable.scss ================================================ //// /// @module menu-button: 菜单按钮 /// @tag MenuButton /// @category component /// @family general /// @varPrefix $menu-btn- /// @classPrefix {prefix}-menu-btn //// // menu-button variables // -------------------------------------------------- // prefix $menu-btn-prefix: '.fusion-ui-menu-btn'; /// icon /// @namespace statement/disabled $menu-btn-disabled-icon-color: var(--color-text1-1, $color-text1-1) !default; /// ghost icon $menu-btn-ghost-light-disabled-icon-color: var( --btn-ghost-light-color-disabled, $btn-ghost-light-color-disabled ) !default; /// ghost icon $menu-btn-ghost-dark-disabled-icon-color: var( --btn-ghost-dark-color-disabled, $btn-ghost-dark-color-disabled ) !default; /// icon /// @namespace statement/normal $menu-btn-pure-text-normal-icon-color: var(--color-text1-2, $color-text1-2) !default; /// icon /// @namespace statement/normal $menu-btn-pure-text-primary-icon-color: var(--color-white, $color-white) !default; /// icon /// @namespace statement/normal $menu-btn-pure-text-secondary-icon-color: var(--color-brand1-6, $color-brand1-6) !default; /// icon /// @namespace statement/normal $menu-btn-text-text-normal-icon-color: var(--color-text1-4, $color-text1-4) !default; /// icon /// @namespace statement/primary $menu-btn-text-text-primary-icon-color: var(--color-link-1, $color-link-1) !default; /// icon /// @namespace statement/light $menu-btn-ghost-light-icon-color: var(--color-text1-4, $color-text1-4) !default; /// icon /// @namespace statement/dark $menu-btn-ghost-dark-icon-color: var(--color-white, $color-white) !default; /// fold icon /// @namespace statement/normal /// @type icon $menu-btn-fold-icon-content: var(--icon-content-arrow-down, $icon-content-arrow-down) !default; /// unfold icon /// @namespace statement/normal /// @type icon $menu-btn-unfold-icon-content: var(--icon-reset, $icon-reset) !default; ================================================ FILE: packages/fusion-ui/src/components/page-header/index.scss ================================================ #{$biz-css-prefix}page-header { position: relative; padding: 0; .next-breadcrumb .next-breadcrumb-text { font-size: 14px; } &-ghost { } &.has-breadcrumb { padding-top: 0; } &.has-footer { padding-bottom: 0; } &-back { margin-right: 16px; font-size: 16px; line-height: 1; &-button { border: none !important; cursor: pointer; } } .fusion-ui-divider-vertical { height: 14px; vertical-align: middle; } .fusion-ui-breadcrumb + &-heading { box-sizing: border-box; margin: 0; padding: 0; color: #000000d9; font-variant: tabular-nums; line-height: 1.5715; list-style: none; font-feature-settings: 'tnum'; color: #00000073; font-size: 14px; } @mixin text-overflow-ellipsis() { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } &-heading { display: flex; justify-content: space-between; margin-top: 8px; &-left { display: flex; align-items: center; overflow: hidden; } &-title { margin-right: 12px; margin-bottom: 0; color: #000000d9; font-weight: 600; font-size: 20px; line-height: 32px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } &-avatar { margin-right: 12px; } &-sub-title { margin-right: 12px; color: #00000073; font-size: 14px; line-height: 1.5715; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } &-extra { white-space: nowrap; > * { white-space: unset; } > *:first-child { margin-left: 0; } } } &-content { padding-top: 16px; } &-actions { float: right; } &-footer { .fusion-ui-tabs { > .fusion-ui-tabs-nav { margin: 0; &::before { border: none; } } .fusion-ui-tabs-tab { } } } &-compact &-heading { flex-wrap: wrap; } } ================================================ FILE: packages/fusion-ui/src/components/page-header/index.tsx ================================================ import * as React from 'react'; import classNames from 'classnames'; import ResizeObserver from 'rc-resize-observer'; import { Icon, Breadcrumb, Avatar, Button } from '@alifd/next'; import { bizCssPrefix } from '../../variables'; import Operations from '@/common/operations'; const TransButton = Button; export interface PageHeaderProps { backIcon?: string | React.ReactNode; prefixCls?: string; title?: React.ReactNode; subTitle?: React.ReactNode; style?: React.CSSProperties; showBreadcrumb?: boolean; breadcrumb?: any[] | React.ReactElement; breadcrumbRender?: (props: PageHeaderProps, defaultDom: React.ReactNode) => React.ReactNode; tags?: React.ReactElement | React.ReactElement[]; footer?: React.ReactNode; extra?: React.ReactNode; showAvatar?: boolean; showActions?: boolean; avatar?: object; onBack?: (e?: React.MouseEvent) => void; className?: string; ghost?: boolean; direction?: string; pageHeader?: any; operations?: any[]; operationConfig?: Record; } const renderBack = ( prefixCls: string, backIcon?: string | React.ReactNode, onBack?: (e?: React.MouseEvent) => void, ) => { if (!backIcon) { return null; } return (
) => { onBack?.(e); }} className={`${prefixCls}-back-button`} >
); }; const renderBreadcrumb = (breadcrumb: any[]) => { if (!breadcrumb) return null; if (!Array.isArray(breadcrumb)) { return breadcrumb; } if (!breadcrumb.length) { return null; } return ( {breadcrumb.map((item) => { return {item}; })} ); }; const getBackIcon = (props: PageHeaderProps, direction = '') => { if (props.backIcon !== undefined) { return props.backIcon; } else if (direction) { return direction === 'rtl' ? 'arrow-right' : 'arrow-left'; } else { return null; } }; const renderOperations = ( prefixCls: string, operations: any[], operationConfig = { align: 'right' }, ) => { const operationsProps = { operations, operationConfig }; let content; if (!operations || !operations.length) { content = null; } else { content = ; } return
{content}
; }; const renderTitle = ( prefixCls: string, props: PageHeaderProps, direction = '', operations: any[], operationConfig: { align: 'right' }, ) => { const { title, showAvatar, avatar, showActions, subTitle, tags, extra, onBack } = props; const headingPrefixCls = `${prefixCls}-heading`; const hasHeading = title || subTitle || tags || extra; // If there is nothing, return a null if (!hasHeading) { return null; } const backIcon = getBackIcon(props, direction); const backIconDom = renderBack(prefixCls, backIcon, onBack); const hasTitle = backIconDom || avatar || hasHeading; return (
{hasTitle && (
{backIconDom} {showAvatar && avatar && } {title && ( {title} )} {subTitle && ( {subTitle} )} {tags && {tags}}
)} {extra && {extra}} {showActions && operations && renderOperations(prefixCls, operations, operationConfig)}
); }; const renderFooter = (prefixCls: string, footer: React.ReactNode) => { if (footer) { return
{footer}
; } return null; }; const renderChildren = (prefixCls: string, children: React.ReactNode) => (
{children}
); const PageHeader: React.FC = (props: PageHeaderProps) => { const [compact, updateCompact] = React.useState(false); const onResize = ({ width }: { width: number }) => { updateCompact(width < 768); }; const { prefixCls = `${bizCssPrefix}-page-header`, style, footer, children, breadcrumb, breadcrumbRender, showBreadcrumb, className: customizeClassName, direction, pageHeader, operations, operationConfig, } = props; let ghost: undefined | boolean = true; // Use `ghost` from `props` or from `ConfigProvider` instead. if ('ghost' in props) { ghost = props.ghost; } else if (pageHeader && 'ghost' in pageHeader) { ghost = pageHeader.ghost; } const getDefaultBreadcrumbDom = () => { if (breadcrumb as any[]) { return renderBreadcrumb(breadcrumb as any[]); } return null; }; const defaultBreadcrumbDom = getDefaultBreadcrumbDom(); const isBreadcrumbComponent = breadcrumb && 'props' in breadcrumb; // support breadcrumbRender function const breadcrumbRenderDomFromProps = breadcrumbRender?.(props, defaultBreadcrumbDom) || defaultBreadcrumbDom; const breadcrumbDom = isBreadcrumbComponent ? breadcrumb : breadcrumbRenderDomFromProps; const className = classNames(prefixCls, customizeClassName, { 'has-breadcrumb': !!breadcrumbDom && breadcrumbDom, 'has-footer': !!footer, [`${prefixCls}-ghost`]: ghost, [`${prefixCls}-rtl`]: direction === 'rtl', [`${prefixCls}-compact`]: compact, }); return (
{showBreadcrumb && breadcrumbDom} {renderTitle(prefixCls, props, direction, operations, operationConfig)} {children && renderChildren(prefixCls, children)} {renderFooter(prefixCls, footer)}
); }; PageHeader.defaultProps = { showBreadcrumb: true, showAvatar: false, showOperation: true, showActions: false, }; export { PageHeader }; ================================================ FILE: packages/fusion-ui/src/components/pie-chart/index.tsx ================================================ import React from 'react'; import { PieChart as MyPie } from 'bizcharts'; import numeral from 'numeral'; import DataSet from '@antv/data-set'; const { DataView } = DataSet; const dv = new DataView(); type IProps = React.ComponentProps; function PieChart(props: IProps) { const { data, ...others } = props || {}; dv.source(data); // 求百分比 dv.transform({ type: 'percent', field: props?.angleField, // 统计字段 dimension: props?.colorField, // 该字段的占比 as: 'percent', // 结果存储在该字段 }); return ( { const percent = typeof angleField?.percent === 'number' ? numeral(angleField?.percent).format('0.00%') : angleField?.percent; return `${angleField?.[props?.colorField]} ${percent}`; }, }} interactions={[ { type: 'element-selected' }, ]} {...others as IProps} /> ); } export default PieChart; ================================================ FILE: packages/fusion-ui/src/components/pro-card/components/button-group/index.tsx ================================================ import * as React from 'react'; import { Button } from '@alifd/next'; export interface ButtonDataSource { label?: string; onClick?: (e: React.MouseEvent) => unknown; } export interface CardButtonGroupProps { dataSource?: ButtonDataSource[]; text?: boolean; } export const CardButtonGroup: React.FC = ({ dataSource, text }) => { return ( <> {dataSource.map(({ label, onClick, ...rest }) => { return ( ); })} ); }; CardButtonGroup.defaultProps = { dataSource: [], }; export default CardButtonGroup; ================================================ FILE: packages/fusion-ui/src/components/pro-card/components/card/index.scss ================================================ @import '../../../../variables.scss'; $fusion-ui-card-padding: var(--s-5, $s-5); $fusion-ui-card-padding-s: var(--s-3, $s-3); .fusion-ui-card { position: relative; box-sizing: border-box; width: 100%; background-color: var(--color-white, $color-white); // border-radius: 0; display: flex; flex-direction: column; &-body { flex: 1 1 auto; &__panel { padding: var(--fusion-ui-card-padding, $fusion-ui-card-padding); padding-bottom: 0; } &__nopadding { padding: 0; } // .fusion-ui-card-header + & { // .fusion-ui-card-body__panel { // padding-top: 0; // } // } } &--dialog { padding: 0; border-radius: 0; box-shadow: none; } } .fusion-ui-card-footer-actions { padding-bottom: var(--fusion-ui-card-padding, $fusion-ui-card-padding); } .fusion-ui-pro-card-operation-container { padding: var( --fusion-ui-card-padding $fusion-ui-card-padding 0, $fusion-ui-card-padding $fusion-ui-card-padding 0 ); } .fusion-ui-pro-card-operation-fixed { position: fixed; width: 100%; box-shadow: 0 -4px 10px 0 rgba(74, 91, 109, 0.1); background-color: #fff; bottom: 0; left: 0; padding-bottom: var(--fusion-ui-card-padding, $fusion-ui-card-padding); } ================================================ FILE: packages/fusion-ui/src/components/pro-card/components/card/index.tsx ================================================ import * as React from 'react'; import { Loading } from '@alifd/next'; import classnames from 'classnames'; import { CardHeader, CardTagProps } from '../card-header'; import { CardButtonGroupProps } from '../button-group'; import { useFiledState } from '@/utils/hooks/useFiledState'; import { TooltipProps } from '@alifd/next/lib/balloon'; import Operations from '@/common/operations'; export interface IOperationConfig { fixed?: boolean; // 是否固定 showSaveTime?: boolean; align?: 'center' | 'flex-start' | 'flex-end'; } export interface IOperationItem { label?: string; type?: 'primary' | 'secondary' | 'normal'; onClick?: () => void; } export interface CardProps extends Omit, 'title'> { /** * 卡片标题 */ title?: React.ReactNode; description?: React.ReactNode; visibleButtonCount?: number; /** * 帮助信息,仅在 title 展示时生效 */ explanation?: string; bodyPadding?: boolean; /** * 帮助信息气泡配置 */ explanationTooltipProps?: TooltipProps; /** * 卡片顶部操作区域自定义渲染 */ actionBar?: React.ReactNode; actionButtons?: CardButtonGroupProps; tagGroup?: CardTagProps[]; /** * 段落分割线; 如果为 true 时,默认最后一个段落没有分割线。 * @default false */ segmentLine?: boolean; /** * 是否 loading */ loading?: boolean; /** * 受控控制 Card 展开收起状态 */ isCollapse?: boolean; /** * 是否开启 Card 显示展开收起 */ hasCollapse?: boolean; /** * 默认收起 */ defaultCollapse?: boolean; /** * 展开收起状态切换后的回调函数 */ setCollapse?: (collapseState: boolean) => void; /** * 是否为弹窗卡片 */ isDialogCard?: boolean; hasDivider?: boolean; operations?: IOperationItem[]; operationConfig?: IOperationConfig; lastSaveTime?: number; text?: boolean; } export const Card: React.FC = (props) => { const { title, description, visibleButtonCount, className, actionBar, actionButtons, loading, tagGroup, style, hasCollapse, isDialogCard, explanation, explanationTooltipProps, children, segmentLine, defaultCollapse, setCollapse, isCollapse, hasDivider, operations, operationConfig, lastSaveTime, bodyPadding, text, ...otherProps } = props; const [collapsed, onCollapse] = useFiledState( { value: isCollapse, defaultValue: defaultCollapse, onChange: setCollapse, }, 'isCollapse' in props, ); const cardBody = children; const layout = 'flow'; const content = ( <> {(title || hasCollapse || actionBar || actionButtons || tagGroup) && ( onCollapse(!collapsed)} explanation={explanation} explanationTooltipProps={explanationTooltipProps} hasDivider={hasDivider} /> )}
{!collapsed && (
{cardBody}
)}
{!collapsed && (
)} ); return (
{loading ? ( {content} ) : ( content )}
); }; Card.defaultProps = { segmentLine: false, loading: false, isDialogCard: false, hasCollapse: false, defaultCollapse: false, }; Card.displayName = 'Card'; ================================================ FILE: packages/fusion-ui/src/components/pro-card/components/card-collapse/index.scss ================================================ .fusion-ui-card-collapse { transition: height 0.3s; overflow: hidden; } ================================================ FILE: packages/fusion-ui/src/components/pro-card/components/card-collapse/index.tsx ================================================ import * as React from 'react'; import { useLayoutEffect } from 'react'; export const CardCollapse: React.FC<{ collapsed: boolean; }> = ({ collapsed, children }) => { const ref = React.useRef(); const contentRef = React.useRef(); useLayoutEffect(() => { if (!ref.current) { return () => {}; } // 折叠 if (collapsed) { // 解决折叠第一次也会进行动画问题 if (ref.current.style.height === 'auto') { ref.current.style.height = `${contentRef.current.offsetHeight}px`; } const index = setTimeout(() => { ref.current.style.height = '0px'; }, 0); return () => clearTimeout(index); } // 当前已经展开,不进行动画 if (ref.current.style.height === 'auto') { return () => {}; } // 展开 ref.current.style.height = `${contentRef.current.offsetHeight}px`; const index = setTimeout(() => { ref.current.style.height = 'auto'; }, 400); return () => clearTimeout(index); }, [collapsed]); return (
{children}
); }; CardCollapse.displayName = 'CardCollapse'; ================================================ FILE: packages/fusion-ui/src/components/pro-card/components/card-header/index.scss ================================================ @import '../../../../variables.scss'; $fusion-ui-card-header-padding: var(--s-4 $s-5, $s-4 $s-5); .fusion-ui-card-header-padding { padding-bottom: var(--s-4, $s-4); } .fusion-ui-card-header { &__content { box-sizing: border-box; position: relative; display: flex; justify-content: space-between; align-items: center; overflow: hidden; padding: var(--fusion-ui-card-header-padding, $fusion-ui-card-header-padding); padding-bottom: 0; // border-left: var(--s-1 transparent solid, $size-base transparent solid); border-radius: var(--corner-2, $corner-2); } &--collapsed { cursor: pointer; border-color: var(--color-brand1-1, $color-brand1-1); &:hover { background-color: var(--color-fill1-2, $color-fill1-2); } .fusion-ui-card-header__action-bar { display: none; } } &__hd { display: flex; box-sizing: border-box; align-items: center; gap: var(--s-2, $s-2); } &__ft { flex: 1; display: flex; gap: var(--s-2, $s-2); justify-content: flex-end; align-items: center; } &__desc { padding: 0 $fusion-ui-card-header-padding $s-4 $fusion-ui-card-header-padding; } &__title { display: flex; box-sizing: border-box; align-items: center; font-size: var(--font-size-subhead, $font-size-subhead); font-weight: var(--font-weight-semi-bold, $font-weight-semi-bold); color: var(--color-text1-4, $color-text1-4); } &__tooltip { color: var(--color-text1-1, $color-text1-1); } &__action-bar { display: flex; gap: var(--s-2, $s-2); justify-content: flex-end; } &__collapse-btn { user-select: none; & > .fusion-ui-icon { transition: transform 0.1s ease-in-out; color: var(--color-line1-4 !important, $color-line1-4 !important); } &--collapsed { & > .fusion-ui-icon { color: var(--color-brand1-6 !important, $color-brand1-6 !important); transform-origin: center; transform: rotate(-180deg) !important; } } &:hover { & > .fusion-ui-icon { color: var(--color-brand1-6 !important, $color-brand1-6 !important); } } } } .fusion-ui-card-header__divider { height: 1px; border-bottom: 1px solid $color-line1-1; margin-top: var(--s-4, $s-4); } ================================================ FILE: packages/fusion-ui/src/components/pro-card/components/card-header/index.tsx ================================================ import * as React from 'react'; import { Button, Balloon, Tag } from '@alifd/next'; import { CustomIcon } from '@/components/toggle-icon'; import { ButtonGroup } from '@/components/button-group'; import { CardButtonGroupProps } from '../button-group'; import classnames from 'classnames'; import { TooltipProps } from '@alifd/next/lib/balloon'; const Tooltip = Balloon; function formatActionButtons(actionButtons) { if (actionButtons && Array.isArray(actionButtons)) { return actionButtons.map((item) => { if (item.label && !item.children) { item.children = item.label; } return item; }); } return []; } export interface CardTagProps { label?: string; color?: string; } export interface CardHeaderProps { /** * 卡片标题 */ title?: React.ReactNode; description?: React.ReactNode; /** * 卡片顶部操作区域自定义渲染 */ actionBar?: React.ReactNode; actionButtons?: CardButtonGroupProps; text?: boolean; visibleButtonCount?: number; tagGroup?: CardTagProps[]; /** * 受控控制 Card 展开收起状态 */ isCollapse?: boolean; /** * 是否开启 Card 显示展开收起 */ hasCollapse?: boolean; collapsed?: boolean; onCollapse?: () => void; /** * 帮助信息,仅在 title 展示时生效 */ explanation?: string; /** * 帮助信息气泡配置 */ explanationTooltipProps?: TooltipProps; hasDivider?: boolean; } export const CardHeader: React.FC = ({ title, description, hasCollapse, actionBar, collapsed, onCollapse, explanation, explanationTooltipProps, hasDivider, tagGroup, actionButtons, text, visibleButtonCount, }) => { return (
{title &&
{title}
} {title && explanation && (
} {...explanationTooltipProps} > {explanation}
)} {tagGroup.map((item) => { let label: any = item; let color: any = 'blue'; if (typeof item === 'object') { label = item.label; if (item.color) { color = item.color; } } return ( {label} ); })}
{actionBar &&
{actionBar}
} {hasCollapse && ( )}
{description ?
{description}
: null} {hasDivider && !collapsed &&
}
); }; CardHeader.defaultProps = { onCollapse: () => {}, hasDivider: true, tagGroup: [], }; CardHeader.displayName = 'CardHeader'; ================================================ FILE: packages/fusion-ui/src/components/pro-card/components/card-section/index.scss ================================================ $fusion-ui-card-padding: var(--s-1 * 5, $size-base * 5); $fusion-ui-card-header-padding: var(--fusion-ui-card-padding, $fusion-ui-card-padding); $fusion-ui-card-section-padding: var(--fusion-ui-card-padding, $fusion-ui-card-padding); .fusion-ui-card-section { // padding-bottom: var(--fusion-ui-card-section-padding, $fusion-ui-card-section-padding); box-sizing: border-box; border: 0 solid $color-line1-1; align-self: stretch; } .fusion-ui-card-section-header__divider { height: 1px; border-bottom: 1px solid $color-line1-1; } .fusion-ui-card-section-header + .fusion-ui-card-section-header__divider { margin-top: var(--s-4, $s-4); } .fusion-ui-card-section-footer__divider { height: 1px; border-bottom: 1px solid $color-line1-1; margin-top: var(--s-5, $s-5); } .fusion-ui-section-divider-indent { margin-left: var(--s-5, $s-5); margin-right: var(--s-5, $s-5); } .fusion-ui-card-section-header { box-sizing: border-box; position: relative; display: flex; justify-content: space-between; align-items: center; overflow: hidden; padding: 5px 0; padding-bottom: 0; &__hd { display: flex; box-sizing: border-box; align-items: center; gap: var(--s-1 * 2, $size-base * 2); } &__ft { flex: 1; display: flex; gap: var(--s-1 * 2, $size-base * 2); justify-content: flex-end; align-items: center; } &__title { display: flex; box-sizing: border-box; align-items: center; font-size: var(--font-size-body-2, $font-size-body-2); font-weight: var(--font-weight-semi-bold, $font-weight-semi-bold); color: var(--color-text1-3, $color-text1-3); &::before { content: ''; display: inline-block; height: 13px; width: 3px; opacity: 0.8; background: #034dfa; border-radius: 2px; margin-right: 8px; } &.fusion-ui-card-section-header-noBullet::before { display: none; } } &__tooltip { color: var(--color-text1-1, $color-text1-1); } &__action-bar { display: flex; gap: var(--s-1 * 2, $size-base * 2); justify-content: flex-end; } } .fusion-ui-card-section-body { padding: var(--fusion-ui-card-section-padding 0, $fusion-ui-card-section-padding 0); } .fusion-ui-card-body__panel--flow > .fusion-ui-card-section, .fusion-ui-card-body__panel--flow > .fusion-ui-row-col-container > .fusion-ui-row > .fusion-ui-col > .fusion-ui-card-section { // margin: 0 ($fusion-ui-card-padding * -1); &--segment-line { &:first-child { border-top: none; } } &:first-child { padding-top: 0; } &:last-child { padding-bottom: 0; } } .fusion-ui-card-body__panel--grid > .fusion-ui-grid { margin: 0 ($fusion-ui-card-padding * -1 - 1px) ($fusion-ui-card-padding * -1) ($fusion-ui-card-padding * -1); & > .fusion-ui-card-section { &--segment-line { border-right-width: 1px; } .fusion-ui-card-section-header__title::before { display: none; } } } ================================================ FILE: packages/fusion-ui/src/components/pro-card/components/card-section/index.tsx ================================================ import * as React from 'react'; import { Loading, Balloon, Tag } from '@alifd/next'; import classnames from 'classnames'; import { CardTagProps } from '../card-header'; import { TooltipProps } from '@alifd/next/lib/balloon'; import { CustomIcon } from '@/components/toggle-icon'; const { Tooltip } = Balloon; export interface CardSectionProps extends Omit, 'title'> { /** * 段落标题 */ title?: React.ReactNode; /** * 帮助信息,仅在 title 展示时生效 */ explanation?: string; /** * 帮助信息气泡配置 */ explanationTooltipProps?: TooltipProps; /** * 子卡片顶部操作区域自定义渲染 */ actionBar?: React.ReactNode; /** * 是否启用分割线 * @default false */ segmentLine?: boolean; /** * 是否 loading * @default false */ loading?: boolean; className?: string; style?: React.CSSProperties; tagGroup?: CardTagProps[]; headerDivider?: boolean; footerDivider?: boolean; hasDividerIndent?: boolean; noBullet?: boolean; } /** * 子卡片 */ export const CardSection: React.FC = ({ children, title, className, loading, segmentLine, actionBar, explanation, explanationTooltipProps, tagGroup, id, headerDivider, footerDivider, hasDividerIndent, noBullet, style, }) => { // 获取 loading 状态 const loadingStatus = loading; const content = ( <> {(title || actionBar) && (
{title && (
{title}
{explanation && ( } {...explanationTooltipProps} > {explanation} )}
{tagGroup.map((item) => { let label: any = item; let color: any = 'blue'; if (typeof item === 'object') { label = item.label; if (item.color) { color = item.color; } } return ( {label} ); })}
)}
{actionBar && (
{actionBar}
)}
)} {headerDivider && (
)}
{children}
{footerDivider && (
)} ); // 一般情况 return (
{loadingStatus ? ( {content} ) : ( content )}
); }; CardSection.displayName = 'CardSection'; CardSection.defaultProps = { title: null, segmentLine: false, loading: false, tagGroup: [], noBullet: false, headerDivider: true, }; ================================================ FILE: packages/fusion-ui/src/components/pro-card/index.scss ================================================ @import './theme-dark.scss'; @import './components/card/index.scss'; @import './components/card-collapse/index.scss'; @import './components/card-header/index.scss'; @import './components/card-section/index.scss'; ================================================ FILE: packages/fusion-ui/src/components/pro-card/index.tsx ================================================ import { Card as ProCard, CardProps } from './components/card'; import { CardSection, CardSectionProps } from './components/card-section'; ProCard.CardSection = CardSection; export { CardProps, CardSectionProps }; export default ProCard; ================================================ FILE: packages/fusion-ui/src/components/pro-card/theme-dark.scss ================================================ body.dark { .fusion-ui-card { background-color: var(--color-fill1-1, $color-fill1-1); &-header { &__title { color: var(--color-text1-4, $color-text1-4); } } &-body { color: var(--color-text1-3, $color-text1-3); } &-header { &--collapsed { border-color: var(--color-brand1-6, $color-brand1-6); &:hover { background-color: var(--color-fill1-1, $color-fill1-1); } } } .fusion-ui-card-grid > .fusion-ui-card-section { background-color: var(--color-fill1-1, $color-fill1-1); } .fusion-ui-card-section-header__title::before { background: var(--color-brand1-6, $color-brand1-6); } } } ================================================ FILE: packages/fusion-ui/src/components/pro-dialog/dialog.tsx ================================================ import * as React from 'react'; import cx from 'classnames'; import { Dialog as NextDialog, Message, Balloon, Icon } from '@alifd/next'; import { DialogProps as NextDialogProps } from '@alifd/next/types/dialog'; import Operations, { OperationProps } from '@/common/operations'; import { isEditorEnv } from '@/utils'; const { Tooltip } = Balloon; const noop = () => {}; const isValidFunction = (func: any) => typeof func === 'function'; const ACTION_MAP: Record = { ok: noop, cancel: noop, }; function getAction(action: string | number) { return ACTION_MAP[action] || noop; } export interface DialogProps extends NextDialogProps { /** * 弹窗大小 */ size?: 'small' | 'medium' | 'large' | 'autoLarge'; operations?: object[]; operationConfig?: object; status?: string; dialogType?: string; explanation?: string; iconType?: string; hasTips?: boolean; } export interface DialogOperationsProps extends OperationProps { onOk?: any; onCancel?: any; } export interface DialogState { visible?: boolean; } const DialogOperations = (props: DialogOperationsProps) => { const { operations, operationConfig, onOk = noop, onCancel = noop, renderDefaultBtns } = props; if (!operations || !operations.length) { return null; } const baseOperations = operations.map((operation: any) => { let onClick = getAction(operation.action).bind(this); if (operation.action) { if (operation.action === 'ok' && onOk && typeof onOk === 'function') { onClick = onOk; } else if (operation.action === 'cancel' && onCancel && typeof onCancel === 'function') { onClick = onCancel; } } return { onClick, ...operation, }; }); const operationProps = { operations: baseOperations, operationConfig, renderDefaultBtns, }; return ; }; function Dialog(props: DialogProps) { const { size, className, onOk, onCancel, children, operations, footer, operationConfig, status, messageProps, dialogType, explanationTooltipProps, hasTips, explanation, iconType, rtl, title, width, ...otherProps } = props; let footerElement = footer; if (operations && operations.length) { const operationsProps = { operations, operationConfig, onOk, onCancel, renderDefaultBtns: () => footer || [], }; footerElement = ; } if (typeof width !== 'undefined') { otherProps.width = width; } // class 处理 const classes = cx({ 'fusion-ui-dialog': true, [`fusion-ui-dialog-${size}`]: typeof width === 'undefined', [className]: !!className, }); // 如果指定了 width ,则 size 不生效; const titleElement = dialogType === 'notice' && status ? ( ) : (
{title} {hasTips ? (
} {...explanationTooltipProps}> {explanation}
) : ( '' )}
); return ( {children} ); } export class InnerProDialog extends React.Component { static displayName: 'ProDialog'; static propTypes: DialogProps; constructor(props: DialogProps) { super(props); const { visible } = props; this.state = { visible: visible || false, }; } onOk = (event: Object) => { const { onOk } = this.props; if (isValidFunction(onOk)) { onOk(event); } if (!('visible' in this.props)) { this.setState({ visible: false }); } }; onCancel = (event: Object) => { const { onCancel } = this.props; if (isValidFunction(onCancel)) { onCancel(event); } this.setState({ visible: false }); }; onClose = (trigger: String, event: Object) => { const { onClose } = this.props; if (isValidFunction(onClose)) { onClose(trigger, event); } this.setState({ visible: false }); }; show = () => { this.setState({ visible: true, }); }; open = () => { this.setState({ visible: true, }); }; hide = () => { this.setState({ visible: false, }); }; close = () => { this.setState({ visible: false, }); }; render() { const { children, ...otherProps } = this.props; const { visible } = this.state; const realVisible = isEditorEnv(this.props) ? true : visible; const dialogProps = { ...otherProps, visible: realVisible, onOk: this.onOk, onCancel: this.onCancel, onClose: this.onClose, }; return {children}; } } export const ProDialog = Object.assign(InnerProDialog, NextDialog); ================================================ FILE: packages/fusion-ui/src/components/pro-dialog/index.scss ================================================ .fusion-ui-dialog { top: 50%; left: 50%; translate: -50% -50%; &-small { width: calc(var(--s-1, 4) * 100) !important; } &-medium { width: calc(var(--s-1, 4) * 175) !important; } &-large { width: calc(var(--s-1, 4) * 250) !important; } &-autoLarge { width: 90vw !important; min-width: 900px; } &__tooltip { color: var(--color-text1-1, $color-text1-1); display: inline-block; margin-left: 8px; } } ================================================ FILE: packages/fusion-ui/src/components/pro-dialog/index.tsx ================================================ export * from './dialog'; ================================================ FILE: packages/fusion-ui/src/components/pro-drawer/drawer.tsx ================================================ import * as React from 'react'; import { Drawer as NextDrawer, Balloon, Icon } from '@alifd/next'; import { DrawerProps as NextDrawerProps } from '@alifd/next/types/Drawer'; import { isEditorEnv } from '@/utils'; import { bizCssPrefix } from '@/variables'; import { Space } from '@/components/container'; import Operations, { OperationProps } from '@/common/operations'; const cssPrefix = `${bizCssPrefix}-pro-drawer`; const noop = () => {}; const isValidFunction = (func: any) => typeof func === 'function'; const ACTION_MAP: Record = { ok: noop, cancel: noop, }; function getAction(action: string | number) { return ACTION_MAP[action] || noop; } export interface DrawerProps extends NextDrawerProps { /** * 弹窗大小 */ size?: 'small' | 'medium' | 'large' | 'autoLarge'; operations?: object[]; operationConfig?: object; onOk?: any; onCancel?: any; footer?: any; titleTip?: any; } export interface DrawerOperationsProps extends OperationProps { onOk?: any; onCancel?: any; } const DrawerOperations = (props: DrawerOperationsProps) => { const { operations, operationConfig, onOk = noop, onCancel = noop, renderDefaultBtns } = props; if (!operations || !operations.length) { return null; } const baseOperations = operations.map((operation: any) => { let onClick = getAction(operation.action).bind(this); if (operation.action) { if (operation.action === 'ok' && onOk && typeof onOk === 'function') { onClick = onOk; } else if (operation.action === 'cancel' && onCancel && typeof onCancel === 'function') { onClick = onCancel; } } return { onClick, ...operation, }; }); const operationProps = { operations: baseOperations, operationConfig, renderDefaultBtns, }; return ; }; const sizeMap: Record> = { small: { hoz: '20vw', ver: '20vh', }, medium: { hoz: '40vw', ver: '40vh', }, large: { hoz: '60vw', ver: '60vh', }, }; function Drawer(props: DrawerProps) { const { size, children, operations, placement, onOk, onCancel, footer, operationConfig = {}, title, titleTip, className, width, height, ...otherProps } = props; let footerElement = footer; if (operations && operations.length) { const operationsProps = { operations, operationConfig, onOk, onCancel, renderDefaultBtns: () => footer || [], }; footerElement = ; } let _width = width; let _height = height; let align; if (size) { // ver if (['top', 'bottom'].includes(placement)) { align = 'ver'; if (!_height) { _height = sizeMap[size].ver; } } else if (['left', 'right'].includes(placement)) { align = 'hoz'; if (!_width) { _width = sizeMap[size].hoz; } } } const _titleTip = titleTip && titleTip.enable ? Object.assign( { content: title, icon: 'help', }, titleTip, ) : null; const titleElement = title ? ( {title} {_titleTip ? ( } alignEdge closable={false} >

{_titleTip.content || title}

) : null}
) : null; return (
{children}
{footerElement}
); } export class InnerProDrawer extends React.Component { static displayName: 'ProDrawer'; static propTypes: DrawerProps; constructor(props: DrawerProps) { super(props); const { visible } = props; this.state = { visible: visible || false, }; } onOk = (event: Object) => { const { onOk } = this.props; if (isValidFunction(onOk)) { onOk(event); } if (!('visible' in this.props)) { this.setState({ visible: false }); } }; onCancel = (event: Object) => { const { onCancel } = this.props; if (isValidFunction(onCancel)) { onCancel(event); } this.setState({ visible: false }); }; onClose = (trigger: String, event: Object) => { const { onClose } = this.props; if (isValidFunction(onClose)) { onClose(trigger, event); } this.setState({ visible: false }); }; show = () => { this.setState({ visible: true, }); }; open = () => { this.setState({ visible: true, }); }; hide = () => { this.setState({ visible: false, }); }; close = () => { this.setState({ visible: false, }); }; render() { const { children, ...otherProps } = this.props; const { visible } = this.state; const realVisible = isEditorEnv(this.props) ? true : visible; const DrawerProps = { ...otherProps, visible: realVisible, onOk: this.onOk, onCancel: this.onCancel, onClose: this.onClose, }; return {children}; } } export const ProDrawer = Object.assign(InnerProDrawer, NextDrawer); ================================================ FILE: packages/fusion-ui/src/components/pro-drawer/index.scss ================================================ #{$biz-css-prefix}pro-drawer { &-small { width: calc(var(--s-1, 4) * 100); } &-medium { width: calc(var(--s-1, 4) * 175); } &-large { width: calc(var(--s-1, 4) * 250); } &-autoLarge { width: 90vw; min-width: 900px; } &-title { font-size: var(--s-4, $s-4); letter-spacing: 0; line-height: var(--s-5, $s-5); } &.operation-container { display: flex; padding: 15px; align-items: center; & > * { margin-left: 10px; } & > *:first-child { margin-left: 0; } &-operation-item + &-operation-item { margin-left: 10px; } &.operation-align-left { justify-content: flex-start; } &.operation-align-center { justify-content: center; } &.operation-align-right { justify-content: flex-end; } &.operation-fixed { width: 100%; position: absolute; background-color: #fff; bottom: 0; left: 0; } } } ================================================ FILE: packages/fusion-ui/src/components/pro-drawer/index.tsx ================================================ export * from './drawer'; ================================================ FILE: packages/fusion-ui/src/components/pro-form/components/Input.tsx ================================================ import * as React from 'react'; import { Input } from '@alifd/next'; import FormItem from './form-item'; const FormInput = (props: any) => { const { formItemProps = {}, ...componentProps } = props; return ( ); }; FormInput.displayName = 'FormInput'; export default FormInput; ================================================ FILE: packages/fusion-ui/src/components/pro-form/components/form-item/index.scss ================================================ #{$biz-css-prefix}form-item-bubble { position: relative; padding-top: 8px; &::before { content: ''; width: 0; height: 0; border-bottom: 7px solid #f4f5f8; border-bottom: 7px solid var(--color-fill1-2, #f4f5f8); border-right: 7px solid transparent; border-left: 7px solid transparent; position: absolute; top: 1px; left: 20px; } } ================================================ FILE: packages/fusion-ui/src/components/pro-form/components/form-item/index.tsx ================================================ import * as React from 'react'; import * as Next from '@alifd/next'; import { ItemProps } from '@alifd/next/types/form'; const { Balloon, Icon, Form } = Next; const { Item } = Form; export enum FormItemTypes { Input = 'Input', NumberPicker = 'NumberPicker', DatePicker = 'DatePicker', } export interface ProFormItemProps extends ItemProps { labelTip?: Record; componentProps?: Record; __designMode?: string; childForm?: any; } const ProFormItem: React.ForwardRefRenderFunction = ( props: ProFormItemProps, ref, ) => { const { labelTip, label, __designMode, children, labelAlign, labelCol, childForm, ...otherProps } = props; const _labelTip = labelTip && labelTip.enable ? Object.assign( { content: label, icon: 'help', }, labelTip, ) : null; return ( {label} {_labelTip ? ( } alignEdge closable={false} >

{_labelTip.content || label}

) : null} } {...otherProps} ref={ref} > {React.Children.map(children, (child) => { if (!child) return null; const _props = Object.assign({}, child.props || {}); const { defaultValue, value, ...otherComponentProps } = _props; const finalValue = (__designMode || otherComponentProps.__designMode) === 'design' ? defaultValue : value; if (finalValue) { otherComponentProps.value = finalValue; } otherComponentProps.renderPreview = (curValue) => { if (otherProps.isPreview && !curValue) { return '—'; } if (!curValue) { return curValue; } switch (typeof curValue) { case 'boolean': return curValue; case 'object': if (Array.isArray(curValue)) { return curValue.length ? curValue.map((item, index) => ( {item?.label || '—'} )) : null; } return curValue.label ? ( {curValue.label} ) : null; default: return curValue; } }; if (otherProps.name) { _props.name = otherProps.name; } if (child) { return React.cloneElement(child, Object.assign(_props, otherComponentProps)); } return child; })} {childForm ?
{childForm}
: null}
); }; const RefProFormItem = React.forwardRef(ProFormItem); RefProFormItem.displayName = 'ProFormItem'; RefProFormItem.defaultProps = {}; RefProFormItem.propTypes = {}; export default RefProFormItem; ================================================ FILE: packages/fusion-ui/src/components/pro-form/components/next-wrapper.tsx ================================================ import * as React from 'react'; import { CascaderSelect, Checkbox, DatePicker, Input, NumberPicker, Radio, Rating, Select, TreeSelect, Upload, } from '@alifd/next'; import FormItem from './form-item'; const RadioGroup = Radio.Group; const CheckboxGroup = Checkbox.Group; const { RangePicker } = DatePicker; const { TextArea, Password } = Input; const FormCascaderSelect = wrapper(CascaderSelect, 'FormCascaderSelect'); const FormCheckboxGroup = wrapper(CheckboxGroup, 'FormCheckboxGroup'); const FormDatePicker = wrapper(DatePicker, 'FormDatePicker'); const FormInput = wrapper(Input, 'FormInput'); const FormNumberPicker = wrapper(NumberPicker, 'FormNumberPicker'); const FormRadioGroup = wrapper(RadioGroup, 'FormRadioGroup'); const FormRangePicker = wrapper(RangePicker, 'FormRangePicker'); const FormRating = wrapper(Rating, 'FormRating'); const FormSelect = wrapper(Select, 'FormSelect'); const FormTreeSelect = wrapper(TreeSelect, 'FormTreeSelect'); const FormUpload = wrapper(Upload, 'FormUpload'); const FormTextArea = wrapper(TextArea, 'FormTextArea'); const FormPassword = wrapper(Password, 'FormPassword'); function wrapper(NextFormComponent: any, displayName: string) { const WrappedComponent = (props: any) => { const { formItemProps = {}, ...componentProps } = props; return ( ); }; WrappedComponent.displayName = displayName; return WrappedComponent; } export { FormCascaderSelect, FormCheckboxGroup, FormDatePicker, FormInput, FormNumberPicker, FormRadioGroup, FormRangePicker, FormRating, FormSelect, FormTreeSelect, FormUpload, FormTextArea, FormPassword, }; ================================================ FILE: packages/fusion-ui/src/components/pro-form/index.scss ================================================ @import './layouts/anchor-form/index.scss'; @import './layouts/child-form/index.scss'; @import './layouts/pro-form/index.scss'; @import './layouts/step-form/index.scss'; @import './components/form-item/index.scss'; ================================================ FILE: packages/fusion-ui/src/components/pro-form/index.tsx ================================================ import ProForm from './layouts/pro-form'; import StepForm from './layouts/step-form'; import AnchorForm from './layouts/anchor-form'; import ChildForm from './layouts/child-form'; export * from './components/form-item'; export * from './components/next-wrapper'; export { StepForm, ProForm, AnchorForm, ChildForm }; ================================================ FILE: packages/fusion-ui/src/components/pro-form/layouts/anchor-form/container.tsx ================================================ import React from 'react'; function AnchorContainer() { return
Container
; } export default AnchorContainer; ================================================ FILE: packages/fusion-ui/src/components/pro-form/layouts/anchor-form/index.scss ================================================ #{$biz-css-prefix}anchor-form { &.forms { margin-bottom: var(--s-5, $s-5); background-color: var(--color-white, $color-white); } } ================================================ FILE: packages/fusion-ui/src/components/pro-form/layouts/anchor-form/index.tsx ================================================ import * as React from 'react'; import { useRef, useImperativeHandle, forwardRef } from 'react'; import { Form, Card } from '@alifd/next'; import { Space } from '@/components/container'; import { Anchor, AnchorProps, LinkItemData } from '@/components/anchor'; import Operations from '@/common/operations'; import { getId } from '@/utils'; export interface AnchorFormProps { children?: React.ReactElement; /** * 可以这样写属性描述 * @description 是否展示锚点 * @description.zh-CN 还支持不同的 locale 后缀来实现多语言描述,使用 description 兜底 * @default false */ showAnchor?: boolean; formMapRef?: any; operations?: any; operationConfig?: any; lastSaveTime?: any; anchorProps?: AnchorProps; enableRandomHtmlId?: boolean; } export type AnchorFormItemProps = LinkItemData; function renderAnchor(props: AnchorFormProps, formArray: Map) { const dataSource: AnchorFormItemProps[] = Array.from(formArray.keys()).map((item) => { const anchorItemProps = formArray.get(item); const { label = '', htmlId = getId(), ...otherProps } = anchorItemProps || {}; return { ...otherProps, label, htmlId, }; }); return <>{dataSource && }; } function renderForm( props: AnchorFormProps, formArrayRef: React.MutableRefObject, formArray: Map, ) { const { children } = props; return ( <> {React.Children.map(children, (child, index) => { const anchorItemProps = formArray.get(`${index}`); const { mode = 'independent', cardProps = {}, ...otherProps } = child.props; const { label = '', htmlId = getId() } = anchorItemProps; return ( {React.cloneElement(child, { ref: (node) => { // Keep your own reference formArrayRef.current[index] = node; // Call the original ref, if any const { ref } = child; if (typeof ref === 'function') { ref(node); } }, ...otherProps, mode, })} ); })} ); } function AnchorForm(props: AnchorFormProps, ref: any) { const { children, formMapRef: propsFormMapRef, operations, operationConfig, lastSaveTime, anchorProps = {}, showAnchor = false, enableRandomHtmlId, ...otherProps } = props; const formArrayRef = useRef>>([]); useImperativeHandle(propsFormMapRef, () => formArrayRef.current); if (!children) { return ( 内容为空 ); } const formArray = new Map(); React.Children.map(children, (child, index) => { const { anchorItemProps } = child.props; const name = `${index}`; const data = { ...anchorItemProps }; if (enableRandomHtmlId) { data.htmlId = getId(); } formArray.set(name, data); }); const operationsProps = { operations, operationConfig, lastSaveTime, }; const formContent = renderForm(props, formArrayRef, formArray); return (
{showAnchor ? renderAnchor(anchorProps, formArray) : null}
{formContent}
); } export default forwardRef(AnchorForm); ================================================ FILE: packages/fusion-ui/src/components/pro-form/layouts/child-form/index.scss ================================================ #{$biz-css-prefix}subForm-child-form { &.one-column { max-width: 600px; margin: 0 auto; } background: #f5f5f5; border-radius: 6px; background-color: #f5f5f5; padding: var(--s-4 $s-4 0 $s-4, $s-4 $s-4 0 $s-4); margin-bottom: var(--s-4, $s-4); &.empty-content { display: flex; justify-content: center; align-content: center; } } #{$biz-css-prefix}independent-child-form { &.one-column { max-width: 600px; margin: 0 auto; } .next-number-picker { .next-input-control { padding-right: 0 !important; } } .next-form-item-label label[required]:before { margin-right: 0; content: ''; } .next-form-item-label label[required]:after { margin-left: 4px; content: '*'; color: #ff3000; } &.empty-content { display: flex; justify-content: center; align-content: center; } } ================================================ FILE: packages/fusion-ui/src/components/pro-form/layouts/child-form/index.tsx ================================================ import * as React from 'react'; import { formatFormItems, ProFormProps } from '../pro-form'; import { ResponsiveGrid } from '@alifd/next'; import { bizCssPrefix } from '@/variables'; export interface ChildFormProps extends ProFormProps { mode?: string; } const ChildForm = (props: ChildFormProps, ref) => { const { children, columns, mode, spacing = 16, emptyContent, ...otherProps } = props; const cssPrefix = `${bizCssPrefix}-${mode || 'subForm'}`; return (
{children ? ( {formatFormItems( children, { columns, ...otherProps, }, true, )} ) : (
{emptyContent}
)}
); }; const RefChildForm = React.forwardRef(ChildForm); RefChildForm.displayName = 'ChildForm'; export default RefChildForm; ================================================ FILE: packages/fusion-ui/src/components/pro-form/layouts/pro-form/index.scss ================================================ #{$biz-css-prefix}pro-form { &.one-column { max-width: 600px; margin: 0 auto; } .next-number-picker { .next-input-control { padding-right: 0 !important; } } .next-form-item-label label[required]:before { margin-right: 0; content: ''; } .next-form-item-label label[required]:after { margin-left: 4px; content: '*'; color: #ff3000; } &.empty-content { display: flex; justify-content: center; align-content: center; } } .next-form-item-control > .next-input, .next-form-item-control > .next-input-group, .next-form-item-fullwidth .next-form-item-control > .next-date-picker, .next-form-item-fullwidth .next-form-item-control > .next-date-picker > .next-date-picker-trigger > .next-input, .next-form-item-fullwidth .next-form-item-control > .next-input, .next-form-item-fullwidth .next-form-item-control > .next-input-group, .next-form-item-fullwidth .next-form-item-control > .next-month-picker, .next-form-item-fullwidth .next-form-item-control > .next-range-picker, .next-form-item-fullwidth .next-form-item-control > .next-select, .next-form-item-fullwidth .next-form-item-control > .next-time-picker, .next-form-item-fullwidth .next-form-item-control > .next-year-picker, .next-form-item-fullwidth .next-form-item-control > .next-number-picker { width: 100%; } ================================================ FILE: packages/fusion-ui/src/components/pro-form/layouts/pro-form/index.tsx ================================================ import moment from 'moment'; import * as React from 'react'; import classnames from 'classnames'; import { FormProps } from '@alifd/next/lib/form'; import { ResponsiveGrid, Form } from '@alifd/next'; import { ObjUtils } from '@/utils'; import { bizCssPrefix } from '@/variables'; import Operations from '@/common/operations'; import ProFormItem from '@/components/pro-form/components/form-item'; moment.locale('zh-cn'); const cssPrefix = `${bizCssPrefix}-pro-form`; function getVisibleChildren(children: any[]) { return children.filter((child: any) => { return !child?.props?.invisible; }); } export interface ProFormProps extends FormProps { columns: number; children: React.ReactChild; emptyContent: React.ReactNode | string; spacing: number; operations?: React.ReactNode | object[]; operationConfig?: object; lastSaveTime?: number; device?: string; } export const calculateLastRows: Function = (children: any[], gridColumns: number) => { const rows: any[] = []; const childrenLength = children.length; for (let i = 0; i < childrenLength; ) { const subRows = []; let index = i; let sum = 0; let childColumnSpan = children[index].props.columnSpan || children[index].props.formItemProps?.columnSpan || 1; if (childColumnSpan >= gridColumns) { subRows.push(children[index].key); } else { while (index < childrenLength) { childColumnSpan = children[index].props.columnSpan || children[index].props.formItemProps?.columnSpan || 1; sum += childColumnSpan; if (sum > gridColumns) { index--; break; } subRows.push(children[index++].key); } } i = ++index; rows.push(subRows); } return rows; }; export const formatFormItems: Function = ( children: React.ReactChild, props: ProFormProps, isChildForm: boolean, ) => { const { columns: gridColumns, size, device, labelAlign, labelTextAlign, labelCol, wrapperCol, colon, isPreview, } = props; let _children; if (!children) { return null; } else if (Array.isArray(children)) { _children = children.filter( (child: React.ReactElement) => child && ['function', 'object', 'string'].indexOf(typeof child.type) > -1, ); } else { _children = [children]; } _children = getVisibleChildren(_children); const rows: any = calculateLastRows(_children, gridColumns); return React.Children.map(_children, (child: React.ReactElement) => { if (ObjUtils.isReactFragment(child)) { return formatFormItems(child.props.children, props); } if (child && ['function', 'object'].indexOf(typeof child.type) > -1) { const _labelAlign = device === 'phone' ? 'top' : labelAlign; const childrenProps: any = { labelCol: child.props.labelCol ? child.props.labelCol : labelCol, wrapperCol: child.props.wrapperCol ? child.props.wrapperCol : wrapperCol, labelAlign: child.props.labelAlign ? child.props.labelAlign : _labelAlign, labelTextAlign: child.props.labelTextAlign ? child.props.labelTextAlign : labelTextAlign, colon: 'colon' in child.props ? child.props.colon : colon, size: child.props.size ? child.props.size : size, isPreview: child.props.isPreview ? child.props.isPreview : isPreview, }; const { formItemProps = {}, ...componentProps } = child.props || {}; let { columnSpan = 1 } = formItemProps; if (!isChildForm && rows[rows.length - 1]?.includes(child.key)) { childrenProps.style = { marginBottom: '0px' }; } if ( ['ProFormItem', 'ChildForm'].includes(child.type.displayName) || child.type?.displayName?.startsWith('Form') ) { if (child.type.displayName === 'ChildForm') { columnSpan = gridColumns; } return ( {React.cloneElement(child, { formItemProps: { ...ObjUtils.pickDefined(childrenProps), ...formItemProps, }, })} ); } return ( {React.cloneElement(child, componentProps)} ); } return child; }); }; const ProForm: React.ForwardRefRenderFunction = (props: ProFormProps, ref) => { const { children, columns, spacing = [0, 16, 16, 0], operations, operationConfig, emptyContent, lastSaveTime, ...otherProps } = props; const { isPreview } = otherProps || {}; const operationProps = { operations, operationConfig, lastSaveTime }; return ( <>
{children ? ( {formatFormItems(children, { columns, ...otherProps, })} ) : (
{emptyContent}
)} {isPreview ? null : } ); }; const RefProForm: React.ForwardRefExoticComponent & { Item?: typeof ProFormItem; } = React.forwardRef(ProForm); RefProForm.displayName = 'ProForm'; RefProForm.defaultProps = {}; RefProForm.propTypes = {}; RefProForm.Item = ProFormItem; export default RefProForm; ================================================ FILE: packages/fusion-ui/src/components/pro-form/layouts/step-form/index.scss ================================================ #{$biz-css-prefix}step-form { &.steps { margin-bottom: var(--s-5, $s-5); } &.forms { margin-left: 0; } } ================================================ FILE: packages/fusion-ui/src/components/pro-form/layouts/step-form/index.tsx ================================================ import * as React from 'react'; import { useRef, useImperativeHandle, useEffect, useState, forwardRef } from 'react'; import { Step, Box } from '@alifd/next'; import { StepProps, ItemProps } from '@alifd/next/lib/step'; import Operations from '@/common/operations'; export interface StepFormProps extends StepProps { children?: React.ReactElement; onPrevious?: Function; onNext?: Function; formRef?: React.MutableRefObject; formMapRef?: React.MutableRefObject; operations?: any[]; operationConfig?: Record; lastSaveTime?: Number; } export interface StepFormItemProps extends ItemProps { stepItemProps?: React.ReactNode; } const ACTION_MAP = { previous: (step, setStep) => { setStep(Math.max(0, --step)); }, next: (step, setStep, stepLength) => { setStep(Math.min(stepLength - 1, ++step)); }, }; const noop = () => {}; function getAction(action: string | number) { return ACTION_MAP[action] || noop; } function renderStep( props: StepFormProps, formArray: Map, step: number, formArrayRef, ) { const { direction = 'hoz', children, showAll, ...others } = props; if (direction === 'hoz') { return (
{formArray && ( {Array.from(formArray.keys()).map((item) => { const { stepItemProps } = formArray.get(item); return ; })} )}
); } return (
{React.Children.map(children, (child: React.ReactElement, index) => { const { stepItemProps } = formArray.get(`${index}`); const content = (
{React.cloneElement(child, { ref: (node) => { // Keep your own reference formArrayRef.current[index] = node; // Call the original ref, if any const { ref } = child; if (typeof ref === 'function') { ref(node); } }, })}
); return ; })}
); } function renderForm( props: StepFormProps, step: number, formArrayRef: React.MutableRefObject>>, ) { const { children } = props; return ( <> {React.Children.map(children, (child: React.ReactElement, index) => { return (
{React.cloneElement(child, { ref: (node) => { // Keep your own reference formArrayRef.current[index] = node; // Call the original ref, if any const { ref } = child; if (typeof ref === 'function') { ref(node); } }, })}
); })} ); } const renderOperations = ({ operations, operationConfig = {}, lastSaveTime, onPrevious, onNext, step, setStep, stepLength, }) => { if (!operations || !operations.length) { return null; } const baseOperations = operations.map((operation: any) => { let onClick = getAction(operation.action).bind(this, step, setStep, stepLength); if (operation.action) { if (operation.action === 'next') { operation.disabled = step === stepLength - 1; if (onNext && typeof onNext === 'function') { onClick = onNext; } } else if (operation.action === 'previous') { operation.disabled = step === 0; if (onPrevious && typeof onPrevious === 'function') { onClick = onPrevious; } } } return { onClick, ...operation, }; }); const operationsProps = { operations: baseOperations, operationConfig, lastSaveTime, }; return ; }; function StepForm(props: StepFormProps, ref) { const { children, onPrevious, onNext, formRef, formMapRef: propsFormMapRef, operations, operationConfig, lastSaveTime, direction = 'hoz', } = props; const [step, setStep] = useState(props.current); const formArrayRef = useRef>>([]); useImperativeHandle(propsFormMapRef, () => formArrayRef.current); const currentFormRef = formArrayRef.current[step || 0]?.current; useImperativeHandle(formRef, () => currentFormRef); const formArray = new Map(); React.Children.map(children, (child, index) => { const itemProps = child.props as StepFormItemProps; const name = `${index}`; formArray.set(name, itemProps); }); useEffect(() => { setStep(props.current); }, [props.current]); if (!children) { return ( 内容为空 ); } return (
<>{renderStep(props, formArray, step, formArrayRef)} <>{direction === 'hoz' ? renderForm(props, step, formArrayRef) : null} {renderOperations({ operations, operationConfig, lastSaveTime, onPrevious, onNext, step, setStep, stepLength: formArray.size, })}
); } export default forwardRef(StepForm); ================================================ FILE: packages/fusion-ui/src/components/pro-table/components/edit-table/index.scss ================================================ .fusion-ui-pro-table { .row-add { height: 37px; background: #f6f8fb; border: 1px dashed #c8d6fa; background-color: #f6f8fb; } .next-table-cell-wrapper .next-select, .next-table-cell-wrapper .next-input { width: 100% !important; min-width: 100% !important; } } ================================================ FILE: packages/fusion-ui/src/components/pro-table/components/edit-table/index.tsx ================================================ import * as React from 'react'; import { Button } from '@alifd/next'; import { ProTable, ProTableProps } from '../../index'; import { Space } from '@/components/container'; export interface EditTableProps extends ProTableProps { addPosition?: 'end' | 'start'; onSave?: (rowIndex: number, record: Record, dataSource: any[]) => void; onRemove?: (rowIndex: number, record: Record, dataSource: any[]) => void; onCancel?: (rowIndex: number, record: Record, dataSource: any[]) => void; } export const EditTable = function (props: EditTableProps) { const { primaryKey = 'id', dataSource: propDataSource, actionColumnButtons: propActionColumnButtons = { dataSource: [] }, onSave, onRemove, onCancel, addPosition = 'end', ...otherProps } = props; const [dataSource, setDataSource] = React.useState(propDataSource); const dataSourceRef = React.useRef(dataSource); const [actionColumnButtons, setActionColumnButtons] = React.useState(propActionColumnButtons); function actionColumnButtonsHidden(showInEdit) { return ({ rowRecord }) => { return showInEdit ? !!rowRecord.editMode : !rowRecord.editMode; }; } const defaultActionColumnButtons = [ { children: '编辑', type: 'primary', onClick(e, payload) { const { rowKey, rowRecord } = payload; const _data = dataSourceRef.current.map((item) => { if (item[primaryKey] === rowKey) { return Object.assign(item, rowRecord, { editMode: true }); } return item; }); setDataSource(_data); }, hidden: actionColumnButtonsHidden(true), }, { children: '保存', type: 'primary', onClick(e, payload) { const { rowIndex, rowKey, rowRecord } = payload; const _data = dataSourceRef.current.map((item) => { if (item[primaryKey] === rowKey) { return Object.assign(item, rowRecord, { editMode: false }); } return item; }); onSave && onSave(rowIndex, rowRecord, _data); setDataSource(_data); }, hidden: actionColumnButtonsHidden(false), }, { children: '取消', type: 'primary', onClick(e, payload) { const { rowIndex, rowKey, rowRecord } = payload; const _data = dataSourceRef.current.map((item) => { if (item[primaryKey] === rowKey) { const keys = Object.keys(item); const originKeys = keys.filter((key) => key.startsWith('origin-')); originKeys.forEach((originKey) => { item[originKey.replace('origin-', '')] = item[originKey]; }); return Object.assign(item, { editMode: false }); } return item; }); onCancel && onCancel(rowIndex, rowRecord, _data); setDataSource(_data); }, hidden: actionColumnButtonsHidden(false), }, { children: '删除', type: 'primary', onClick(e, payload) { const { rowKey, rowIndex, rowRecord } = payload; dataSourceRef.current = dataSourceRef.current.filter((item) => item[primaryKey] !== rowKey); setDataSource(dataSourceRef.current); onRemove && onRemove(rowIndex, rowRecord, dataSourceRef.current); }, }, ]; React.useEffect(() => { const { dataSource: actionColumnDataSource = [] } = propActionColumnButtons; const _actionColumnButtons = { ...actionColumnButtons, dataSource: defaultActionColumnButtons.concat(actionColumnDataSource), }; setActionColumnButtons(_actionColumnButtons); }, [propActionColumnButtons, dataSource]); const tableAfter = ( ); return ( <> ); }; ================================================ FILE: packages/fusion-ui/src/components/pro-table/components/group-table/index.tsx ================================================ import * as React from 'react'; import { ProTableProps } from '../../types'; import { ProTable } from '../pro-table'; export const GroupTable: React.FC = (props) => { const { groupHeader: propGroupHeader, groupFooter: propGroupFooter, ...otherProps } = props; const groupHeader = propGroupHeader || { cell: (record) => record?.header, }; const groupFooter = propGroupFooter || { cell: (record) => record?.footer, }; return ; }; GroupTable.defaultProps = { settingButtons: false, defaultColumnsSetting: {}, columnKey: 'key', primaryKey: 'id', stickyLock: true, resizable: true, emptyContent:
, hasBorder: false, size: 'medium', isZebra: false, cellDefault: '', cellTooltipMode: 'none', }; ================================================ FILE: packages/fusion-ui/src/components/pro-table/components/pro-table/index.scss ================================================ .fusion-ui-pro-table { .fusion-ui-pagination { padding: var(--s-4 0 0, $s-4 0 0); display: flex; justify-content: flex-end; } &.fullscreen { padding: var(--s-5 $s-5 0, $s-5 $s-5 0); background: var(--color-white, $color-white); overflow-y: auto; .fusion-ui-pagination { box-sizing: border-box; position: sticky; bottom: 0; background-color: var(--color-white, $color-white); border-radius: var(--corner-2, $corner-2); z-index: 9; } } &-expanded-child { padding: var(--s-5 $s-5 $s-2 $s-5, $s-5 $s-5 $s-2 $s-5); background-color: var(--color-fill1-2, $color-fill1-2); } } .fusion-ui-pro-table-body { display: flex; flex-direction: column; gap: var(--s-4, $s-4); .fusion-ui-pro-table-action-bar { margin: 0; } } .fusion-ui-pro-table-content { position: relative; .next-loading.next-open.next-loading-inline.next-table-loading-content{ position: absolute; width: 100%; height: 100%; top: 0; } } ================================================ FILE: packages/fusion-ui/src/components/pro-table/components/pro-table/index.tsx ================================================ import * as React from 'react'; import { Space } from '@/components/container'; import { Box, Pagination } from '@alifd/next'; import { ProTableProps, ProTableSettingButtonType } from '../../types'; import { ProTableCompactButton } from '../pro-table-compact-button'; import { ProTableZebraButton } from '../pro-table-zebra-button'; import { ProTableFullscreenButton } from '../pro-table-fullscreen-button'; import { ProTableSettingButton } from '../pro-table-setting-button'; import { useProTableSlots } from '../pro-table-slot'; import { ProTableContext, useProTableValue, } from '@/components/pro-table/contexts/pro-table-context'; import { ProTableColumnsSettingContext, useColumnsSettingValue, } from '@/components/pro-table/contexts/pro-table-columns-setting-context'; import { ProTableColumnsFilterContext, useColumnsFilterValue, } from '@/components/pro-table/contexts/pro-table-columns-filters-context'; import { ProTableBase } from '../pro-table-base/index'; // import { Result } from '@/result'; import { ProTableSettingContext, useProTableSettingValue, } from '@/components/pro-table/contexts/pro-table-setting-context'; import is from '@sindresorhus/is'; import { ToggleIconGroup } from '@/components/toggle-icon'; import { ProTableColumnsContext, useProTableColumnsValue, } from '@/components/pro-table/contexts/pro-table-columns-context'; import cns from 'classnames'; // import { Pagination } from '../../../pagination/index'; import { ProTableActionBarButtonGroup } from '../pro-table-action-bar-buttons'; import { useProTableRowSelectionValue, ProTableRowSelectionContext, } from '../../contexts/pro-table-row-selection-context'; export const ProTable: React.FC = (props: ProTableProps) => { const slots = useProTableSlots(props); const columnsFiltersCtxValue = useColumnsFilterValue(props); const columnsSettingCtxValue = useColumnsSettingValue(props); const proTableSettingCtxValue = useProTableSettingValue(props); const { paginationProps, settingButtons } = props; const proTableContainer = React.useRef(); const tableBeforeContainer = React.useRef(); const proTableCtxValue = useProTableValue({ pageSize: paginationProps?.pageSize, total: paginationProps?.total, tableBeforeContainer, proTableContainer, }); const proTableColumnsCtxValue = useProTableColumnsValue(props); const proTableRowSelectionCtxValue = useProTableRowSelectionValue(props); const buttons = React.useMemo(() => { if (settingButtons === false) { return []; } if (is.array(settingButtons)) { return settingButtons; } return ['compact', 'zebra', 'fullscreen', 'setting']; }, [settingButtons]); const loading = React.useMemo( () => !columnsFiltersCtxValue.filterPanelVisible && props.loading, [columnsFiltersCtxValue.filterPanelVisible, props.loading], ); const hasActionBarButtons = props.actionBarButtons?.dataSource?.length > 0; return (
{slots.actionBarBefore} {(buttons.length > 0 || hasActionBarButtons || slots.actionBarLeft || slots.actionBarRight) && (
{hasActionBarButtons && ( )} {slots.actionBarLeft} {slots.actionBarRight} {buttons.length > 0 && ( {buttons.includes('compact') && } {buttons.includes('zebra') && } {buttons.includes('fullscreen') && ( )} {buttons.includes('setting') && } )}
)} {slots.actionBarAfter}
{slots.table} {slots.tableAfter}
{paginationProps && !paginationProps.hidden && ( )}
); }; ProTable.defaultProps = { settingButtons: false, defaultColumnsSetting: {}, columnKey: 'key', primaryKey: 'id', stickyLock: true, resizable: true, emptyContent: ( 暂无内容 ), hasBorder: false, size: 'medium', isZebra: false, cellDefault: '', cellTooltipMode: 'none', }; ================================================ FILE: packages/fusion-ui/src/components/pro-table/components/pro-table-action-bar-buttons.tsx ================================================ import React, { useContext, useMemo } from 'react'; import { ProTableButtonGroup } from './pro-table-button-group/index'; import { ProTableActionBarButtons } from '../types'; import { ProTableRowSelectionContext } from '../contexts/pro-table-row-selection-context'; export const ProTableActionBarButtonGroup: React.FC = (props) => { const rowSelection = useContext(ProTableRowSelectionContext); const payload = useMemo( () => ({ rowSelection, }), [rowSelection], ); return ; }; ================================================ FILE: packages/fusion-ui/src/components/pro-table/components/pro-table-base/columns/useActionColumn.tsx ================================================ import { ColumnProps } from '@alifd/next/types/table'; import * as React from 'react'; import is from '@sindresorhus/is'; import { ProTableBaseProps, ProTableRowRecord, ProTableProps, ProTableActionColumnButtons, ProTableRowPayload, } from '../../../types'; import { useI18nBundle } from '@/provider'; import { emptyFn } from '@/utils/constants'; import { usePersistFn } from 'ahooks'; import get from 'lodash/get'; import { ProTableButtonGroup, ProTableButtonGroupProps } from '../../pro-table-button-group/index'; type ActionColumnProps = Pick< ProTableBaseProps, | 'actionColumn' | 'actionButtonGroupProps' | 'actionColumnButtons' | 'actionColumnProps' | 'actionColumnPredication' | 'onActionColumnClick' | 'primaryKey' >; const calcButtonWidth = (str: React.ReactNode) => { if (is.string(str)) { return str.length * 12 + 12; } return 50; }; /** * 操作列 */ export const useActionColumn = ({ actionColumn, actionColumnProps, actionColumnPredication, actionButtonGroupProps, actionColumnButtons, onActionColumnClick, primaryKey, }: ActionColumnProps): ColumnProps => { const i18nBundle = useI18nBundle('ProTable'); const handleActionColumnClick = usePersistFn(onActionColumnClick || emptyFn); const buttonGroupProps = { dataSource: actionColumn, ...(actionColumnButtons || actionButtonGroupProps), }; if (!is.array(buttonGroupProps.dataSource) || buttonGroupProps.dataSource.length === 0) { return undefined; } const width = actionColumnProps?.width || buttonGroupProps.dataSource .slice(0, 3) .map((vo) => calcButtonWidth(vo.children)) .reduce((p, vo) => p + vo, buttonGroupProps.dataSource.length > 3 ? 65 : 30); return { width, lock: 'right', title: i18nBundle.operation, cell: (value, rowIndex, rowRecord) => ( ), ...actionColumnProps, }; }; interface ActionColumnButtonGroupProps { rowIndex: number; rowRecord: ProTableRowRecord; actionColumnPredication?: ProTableProps['actionColumnPredication']; onActionColumnClick?: ProTableProps['onActionColumnClick']; primaryKey: ProTableProps['primaryKey']; buttonGroupProps: ProTableActionColumnButtons; } const ActionColumnButtonGroup: React.FC = ({ rowIndex, rowRecord, actionColumnPredication, onActionColumnClick, primaryKey, buttonGroupProps, }) => { const payload = React.useMemo( () => ({ rowKey: rowRecord[primaryKey], rowIndex, rowRecord, }), [rowIndex, primaryKey, rowRecord], ); const { dataSource, ...otherProps } = buttonGroupProps; const realDataSource = React.useMemo(() => { const buttons = is.function_(actionColumnPredication) ? actionColumnPredication({ actionColumn: dataSource, index: payload.rowIndex, record: payload.rowRecord, }) : dataSource; return is.array(buttons) ? buttons.map((vo) => ({ onClick: () => { onActionColumnClick({ currentActionKey: vo.key, selectedRowKey: payload.rowKey, record: payload.rowRecord, }); }, ...vo, hidden: is.string(vo.hidden) ? () => !!get(payload.rowRecord, vo.hidden as string) : vo.hidden, disabled: is.string(vo.disabled) ? () => !!get(payload.rowRecord, vo.disabled as string) : vo.disabled, })) : []; }, [actionColumnPredication, dataSource, onActionColumnClick, payload]); return ; }; ActionColumnButtonGroup.defaultProps = { onActionColumnClick: emptyFn, }; ================================================ FILE: packages/fusion-ui/src/components/pro-table/components/pro-table-base/columns/useIndexColumn.tsx ================================================ import { useI18nBundle } from '@/provider'; import { ColumnProps } from '@alifd/next/types/table'; import * as React from 'react'; import { ProTableBaseProps } from '../../../types'; type IndexColumnProps = Pick; /** * 序号列 */ export const useIndexColumn = ({ indexColumn, indexColumnProps, }: IndexColumnProps): ColumnProps => { const i18nBundle = useI18nBundle('ProTable'); if (!indexColumn) { return undefined; } return { width: 70, lock: 'left', title: i18nBundle.indexColumnTitle, cell: (value: any, index: number) => (
{index + 1}
), align: 'center', ...indexColumnProps, }; }; ================================================ FILE: packages/fusion-ui/src/components/pro-table/components/pro-table-base/columns/useRowSelection.tsx ================================================ import * as React from 'react'; import { Checkbox } from '@alifd/next'; import { CustomIcon } from '@/components/toggle-icon'; import { MenuButton } from '@/components/menu-button'; import { ProTableBaseProps, ProTableRowKey, ProTableRowRecord, ProTableRowSelectionType, } from '../../../types'; import numvert from 'numvert'; import is from '@sindresorhus/is'; import { emptyFn } from '@/utils/constants'; import { ProTableContext } from '../../../contexts/pro-table-context'; import ReactDOM from 'react-dom'; import { ProTableRowSelectionContext } from '../../../contexts/pro-table-row-selection-context'; export const isSelectedAllPages = (selectedRowKeys: ProTableRowKey[], reverseSelection: boolean) => reverseSelection && selectedRowKeys.length === 0; export const hasSelectedRows = (selectedRowKeys: ProTableRowKey[], reverseSelection: boolean) => reverseSelection || selectedRowKeys.length > 0; /** * 行选择逻辑 * - 支持选择当前页所有行 * - 支持跨页选择 * - 支持选择所有页 */ export const useRowSelection = ( originRowSelection: ProTableBaseProps['rowSelection'], dataSource: any[] = [], ) => { const hasRowSelection = !!originRowSelection; const rowSelection = hasRowSelection ? originRowSelection : {}; const { tableBeforeContainer } = React.useContext(ProTableContext); const instance = React.useContext(ProTableRowSelectionContext); const tooltip = useProTableSelectionTooltip( rowSelection.crossPageSelection === false ? instance.currentPageSelectedRowKeys.length : instance.selectedRowKeys.length, instance.reverseSelection, ); if (!hasRowSelection) { return undefined; } if (rowSelection.ref) { rowSelection.ref.current = instance; } const { selectAllPages, selectCurrentPage, currentPageSelectedRowKeys, reverseSelection, selectRows, selectedRowKeys, getRowKeyByRecord, currentPageRowKeys, } = instance; const { onSelect = emptyFn, onSelectAll = emptyFn, selections = ['SELECTION_ALL', 'SELECTION_NONE'], titleProps, } = rowSelection; const isMultiple = rowSelection.mode !== 'single'; const hasMenu = isMultiple && is.array(selections) && selections.length > 0; return { mode: rowSelection.mode, getProps: rowSelection.getProps, selectedRowKeys: currentPageSelectedRowKeys, onSelect: (selected: boolean, record: ProTableRowRecord, records: ProTableRowRecord[]) => { selectRows(selected, [getRowKeyByRecord(record)]); onSelect(selected, record, records); }, columnProps: () => ({ align: 'left', width: hasMenu ? 70 : 50, }), titleProps: () => ({ style: { display: 'none', }, }), titleAddons: !isMultiple ? undefined : () => { const selectionTexts: Record = { SELECTION_ALL: '全选所有', SELECTION_NONE: '清空所有', }; const globalChecked = currentPageSelectedRowKeys.length > 0; const globalCheckedIndeterminate = globalChecked && (reverseSelection ? selectedRowKeys.length > 0 : currentPageSelectedRowKeys.length < currentPageRowKeys.length); const checkboxProps = titleProps ? titleProps() : {}; return ( <> {!rowSelection.hideTooltip && tableBeforeContainer.current && tooltip && ReactDOM.createPortal(
{tooltip}
, tableBeforeContainer.current, )}
{ onSelectAll(selected, dataSource); selectCurrentPage(selected); }} {...checkboxProps} /> {hasMenu && ( } text onItemClick={(key: ProTableRowSelectionType) => { if (key === 'SELECTION_ALL') { selectAllPages(true); } else if (key === 'SELECTION_NONE') { selectAllPages(false); } }} popupTriggerType="hover" autoWidth={false} menuProps={{ isSelectIconRight: false, }} dataSource={selections.map((vo) => ({ key: vo, label: selectionTexts[vo] }))} /> )}
); }, // ...rowSelection, }; }; const renders = { selected: (amount: number) => ( <> 已选中 {numvert(amount).format('0,0')} 条 ), selectedWithPageCount: (amount: number, pageCount: number) => ( <> 已选中{pageCount}页, 共 {numvert(amount).format('0,0')} 条 ), allPageUnselected: (amount: number) => ( <> 已选中所有页,反选 {numvert(amount).format('0,0')} 条 ), allPageSelectedAll: () => <>已选中所有项, }; const useProTableSelectionTooltip = (selecteAmount: number, reverseSelection: boolean) => { const { total, pageSize } = React.useContext(ProTableContext); return React.useMemo(() => { if (reverseSelection) { if (is.number(total)) { if (total === 0) { return undefined; } const pageCount = is.number(pageSize) && is.number(total) && pageSize !== 0 ? Math.ceil(total / pageSize) : undefined; return is.number(pageCount) ? renders.selectedWithPageCount(total - selecteAmount, pageCount) : renders.selected(total - selecteAmount); } if (selecteAmount > 0) { return renders.allPageUnselected(selecteAmount); } return renders.allPageSelectedAll(); } if (selecteAmount > 0) { return renders.selected(selecteAmount); } return undefined; }, [reverseSelection, selecteAmount, total, pageSize]); }; ================================================ FILE: packages/fusion-ui/src/components/pro-table/components/pro-table-base/index.scss ================================================ .fusion-ui-pro-table-base { position: relative; .next-table-empty { min-height: 224px; } .next-table-cell-wrapper:hover { .next-table-resize-handler { border-color: var(--color-line1-4, $color-line1-4); } } .next-table-header-resizable .next-table-resize-handler { width: var(--s-2, $s-2); border-right: 2px solid transparent; } // 标题样式修改 .next-table-header .next-table-cell .next-table-cell-wrapper { word-break: break-word; } // 内容样式修改 .next-table-body .next-table-cell .next-table-cell-wrapper { word-break: break-word; } .only-bottom-border td { border: 0; } .only-bottom-border .next-table-group .next-table-body table { border-top: 0; border-left: 0; border-bottom: 0; } // 统计列相关样式修改 .fusion-ui-pro-table-total-row { background: var(--color-fill1-1, $color-fill1-1); font-family: Roboto-Medium; font-size: var(--font-size-body-2, $font-size-body-2); line-height: 16px; font-weight: var(--font-weight-medium, $font-weight-medium); } .cell-money { white-space: nowrap; overflow: visible; } .cell-nowrap { white-space: nowrap; } .fusion-ui-table-sort { .fusion-ui-pro-table-sort-icon { left: 0; &.fusion-ui-icon-triangle-down { top: 6px; } &.fusion-ui-icon-triangle-up { top: -2px; } } } } // 在 selectedRowKeys.length > 0 时展示 "已选择 x 项" 的容器 .fusion-ui-pro-table-selection { position: absolute; z-index: 50; will-change: transform; background-color: var(--color-white, $color-white); border-radius: var(--s-1, $s-1); padding: var(--s-1 $s-2, $s-1 $s-2); text-align: center; top: -16px; left: var(--s-2, $s-2); perspective: 800px; box-shadow: var(--shadow-2, $shadow-2); white-space: nowrap; font-weight: normal; font-size: var(--font-size-body-1, $font-size-body-1); &-placeholder { position: absolute; width: 10px; height: 10px; background-color: red; left: -8px; top: 0; } &-number { color: var(--color-brand1-6, $color-brand1-6); font-weight: var(--font-weight-medium, $font-weight-medium); margin: 0 $s-1; } } .fusion-ui-tablex-serial-number { color: var(--color-white, $color-white); text-align: center; font-size: var(--font-size-body-1, $font-size-body-1); display: inline-flex; justify-content: center; align-items: center; height: var(--s-5, $s-5); width: var(--s-5, $s-5); border-radius: var(--corner-2, $corner-2); background-color: var(--color-line1-4, $color-line1-4); } .fusion-ui-pro-table-selection-checkbox { display: inline-flex; flex-direction: row; align-items: center; gap: var(--s-1, $s-1); .fusion-ui-menu-btn { color: var(--color-text1-2, $color-text1-2); } .fusion-ui-menu-btn-arrow { display: none !important; } } ================================================ FILE: packages/fusion-ui/src/components/pro-table/components/pro-table-base/index.tsx ================================================ import * as React from 'react'; import cns from 'classnames'; import { Table } from '@alifd/next'; import { TableProps } from '@alifd/next/types/table'; import { getColumnKey, pickTableProps } from './utils'; import { useMemo } from 'react'; import { useActionColumn } from './columns/useActionColumn'; import { useIndexColumn } from './columns/useIndexColumn'; import { ProTableBaseProps } from '../../types'; import { renderColumns, useColumnsWithSetting } from '../pro-table-column'; import { useRowSelection } from './columns/useRowSelection'; import { ProTableColumnsSettingContext } from '../../contexts/pro-table-columns-setting-context'; import { ProTableSettingContext } from '@/components/pro-table/contexts/pro-table-setting-context'; import { registerColumnFormatters } from '../pro-table-column/pro-table-column-formatter'; import { defaultColumnFormatters } from '../pro-table-column/defaultColumnFormatters'; import { emptyFn } from '@/utils/constants'; import { ProTableCell } from '../pro-table-cell/pro-table-cell'; import { ProTableTreeCell } from '../pro-table-cell/pro-table-tree-cell'; // import { ProTableCell } from '../pro-table-cell'; registerColumnFormatters(defaultColumnFormatters); const totalCell = () => 'Total'; const valueCell = (val) => val; export const ProTableBase: React.FC = (props) => { const { tableSetting } = React.useContext(ProTableSettingContext); const { columnKey, resizable, dataSource: originalDataSource, rowSelection, expandedRowRender, groupHeader, groupFooter, totalDataSource, } = props; const actionColumnProps = useActionColumn(props); const indexColumnProps = useIndexColumn(props); const { updateColumnSetting, columnsSetting } = React.useContext(ProTableColumnsSettingContext); const { flatColumns, columnsWithSetting } = useColumnsWithSetting({ columnKey, columnsSetting, columns: props.columns, cellDefault: props.cellDefault, cellTooltipMode: props.cellTooltipMode, }); // table 属性 const externalProps: Partial = { expandedIndexSimulate: expandedRowRender ? true : undefined, }; if (resizable) { externalProps.hasBorder = false; externalProps.onResizeChange = (dataIndex, width) => { const columnItem = flatColumns.find((vo) => vo.dataIndex === dataIndex); if (!columnItem) { console.warn(`未找到dataIndex=${dataIndex}的columnItem`); return; } updateColumnSetting( getColumnKey(columnItem, columnKey), (oldSetting) => { const oldWidth = +oldSetting.width || +columnItem.width || 200; return { width: Math.max(10, oldWidth + width), }; }, 'resize', ); }; } const dataSource = useMemo( () => (totalDataSource ? [...(originalDataSource || []), totalDataSource] : originalDataSource), [totalDataSource, originalDataSource], ); if (totalDataSource) { // 数据列第一列的下标,去掉表左侧功能列 const dataColumnsStartIndex = [expandedRowRender, rowSelection, indexColumnProps].filter( (vo) => vo, ).length; // 数据列最后一列的下标,去掉表右侧功能列 const dataColumnsEndIndex = dataColumnsStartIndex + flatColumns.length - 1; // 统计行下标 const totalRowIndex = dataSource.length - 1; externalProps.rowProps = (record, rowIndex) => { if (rowIndex === totalRowIndex) { return { className: 'fusion-ui-pro-table-total-row', }; } return {}; }; externalProps.cellProps = (rowIndex, colIndex) => { if (rowIndex === totalRowIndex) { // 统计行的数据第一列显示 Total 文案 if (colIndex === 0) { return { cell: totalCell, onCellClick: undefined, formatValue: undefined, }; } // 不在数据列范围内的隐藏 if (colIndex < dataColumnsStartIndex || colIndex > dataColumnsEndIndex) { return { cell: emptyFn, onCellClick: undefined, formatValue: undefined, }; } return { cell: valueCell, onCellClick: undefined, formatValue: undefined, }; } return {}; }; } const NextTable = props.stickyLock ? Table.StickyLock : Table; const nextTableProps = pickTableProps({ ...externalProps, ...props, ...tableSetting, rowSelection: useRowSelection(rowSelection, originalDataSource), dataSource, columns: undefined, // 剔除columns className: cns('fusion-ui-pro-table-base', props.className), }); const columns = renderColumns(columnsWithSetting, { resizable, }); return ( {groupHeader && (React.isValidElement(groupHeader) ? ( groupHeader ) : ( ))} {groupFooter && (React.isValidElement(groupFooter) ? ( groupFooter ) : ( ))} {indexColumnProps && } {columns} {actionColumnProps && } {props.children} ); }; ProTableBase.displayName = 'ProTableBase'; ================================================ FILE: packages/fusion-ui/src/components/pro-table/components/pro-table-base/utils.tsx ================================================ import pick from 'lodash/pick'; import { TableProps } from '@alifd/next/types/table'; import { ProTableColumnProps, ProTableBaseProps } from '../../types'; export function getColumnKey(column: ProTableColumnProps, columnKey?: string) { if (columnKey) { if (column[columnKey]) { return column[columnKey]; } } if (column.key) { return column.key; } if (column.dataIndex) { return column.dataIndex; } console.warn( `[TableX] 自定义列需要每个 column 必须有 ${columnKey} | key | dataIndex 属性`, column, ); } const nextTablePropsKeys: Array = [ // next table 所有属性 'affixProps', 'cellProps', 'className', 'columns', 'crossline', 'dataSource', 'emptyContent', 'expandedIndexSimulate', 'expandedRowIndent', 'expandedRowRender', 'filterParams', 'fixedHeader', // 'getCellProps', // fusion 废弃 'getExpandedColProps', // 'getRowProps', // fusion 废弃 'hasBorder', 'hasExpandedRowCtrl', 'hasHeader', 'indent', 'isTree', 'isZebra', 'loading', 'loadingComponent', 'locale', 'maxBodyHeight', 'offsetTop', 'onBodyScroll', 'onExpandedRowClick', 'onFilter', 'onResizeChange', 'onRowClick', 'onRowMouseEnter', 'onRowMouseLeave', 'onRowOpen', 'onSort', 'openRowKeys', 'prefix', 'primaryKey', 'pure', 'rowExpandable', 'rowHeight', 'rowProps', 'rowSelection', 'rtl', 'scrollToRow', 'size', 'sort', 'sortIcons', 'stickyHeader', 'style', 'tableLayout', 'tableWidth', 'useVirtual', 'warning', ]; export const pickTableProps = (whaleTableProps: ProTableBaseProps) => { return pick( whaleTableProps, nextTablePropsKeys.filter((vo) => whaleTableProps[vo] !== undefined), ); }; ================================================ FILE: packages/fusion-ui/src/components/pro-table/components/pro-table-button-group/index.tsx ================================================ import * as React from 'react'; import { Button, ButtonProps } from '@/components/button'; import { MenuButton, MenuButtonProps } from '@/components/menu-button'; import { Space, SpaceProps } from '@/components/container'; import { PayloadButtonProps, usePayloadButtons } from './payload-button'; import { useI18nBundle } from '@/provider/contexts/locale-context/index'; import { omit } from 'lodash'; export interface ProTableButtonGroupProps extends SpaceProps { /** * 是否设定按钮为文字模式 */ text?: boolean; /** * 可见按钮数量,超过会收起到”更多“菜单中 */ maxCount?: number; /** * 按钮 */ payload?: Payload; /** * 数据源驱动 */ dataSource?: Array>; /** * "更多" 按钮的额外配置 */ moreMenuButtonProps?: Partial; } export const ProTableButtonGroup: React.FC = ({ text, maxCount, payload, dataSource, moreMenuButtonProps, ...otherProps }) => { const i18nBundle = useI18nBundle('ButtonGroup'); const realDataSource = usePayloadButtons(dataSource, payload); const splitIndex = getVisibleSplitIndex(realDataSource, maxCount); const visibleButtons = realDataSource.slice(0, splitIndex); const menuButtons = realDataSource.slice(splitIndex).map((vo) => omit(vo, ['type', 'text'])); return ( {text ? visibleButtons.map((dataSourceItem, idx) => ( {!isImmediate && ( )}
)}
); }; ProTableColumnTitleFilterPanel.defaultProps = { onClose: () => {}, isImmediate: true, }; interface FilterMenuProps extends Omit { dataSource?: AsyncDataSource; } const FilterMenu: React.FC = ({ dataSource, ...otherProps }) => { const [keywords, setKeywords] = React.useState(); const { data, loading, error } = useDataSource({ dataSource }); const menuDataSource = useMemo( () => (is.array(data) ? dataSourceToMenuDataSource(data) : []), [data], ); const filterDataSource = React.useMemo(() => { if (!keywords) { return menuDataSource; } return menuDataSource.filter( (vo) => is.string(vo.label) && vo.label.toLowerCase().indexOf(keywords) > -1, ); }, [menuDataSource, keywords]); const i18nBundle = useI18nBundle('ProTable'); return ( setKeywords(val.trim().toLowerCase())} placeholder={i18nBundle.columnTitleFilterPanelMenuSearchPlaceholder} /> } style={{ maxHeight: 'auto', }} loading={loading} error={error?.message} {...otherProps} dataSource={filterDataSource} /> ); }; const SearchInput: React.FC = (props) => ( } hasClear style={{ width: '100%', }} {...props} /> ); ================================================ FILE: packages/fusion-ui/src/components/pro-table/components/pro-table-column-title/pro-table-column-title-filter.tsx ================================================ import * as React from 'react'; import { Dropdown } from '@alifd/next'; import { CustomIcon } from '@/components/toggle-icon'; import cns from 'classnames'; import { ProTableColumnTitleFilterPanel, ProTableColumnFilterPanelProps, } from './pro-table-column-title-filter-panel'; import { ProTableContext } from '@/components/pro-table/contexts/pro-table-context'; export interface ProTableColumnTitleFilterProps extends Omit { iconType?: string; } /** * ProTable 列标题 */ export const ProTableColumnTitleFilter: React.FC = ({ rtl, iconType, columnFilters, dataIndex, ...others }) => { const [visible, setVisible] = React.useState(false); const hasValue = React.useMemo(() => { return !!( columnFilters.getColumnKeywords(dataIndex) || columnFilters.getColumnSort(dataIndex) || columnFilters.getColumnSelectedKeys(dataIndex)?.length > 0 ); }, [columnFilters, dataIndex]); const { tableBeforeContainer } = React.useContext(ProTableContext); const triggerRef = React.useRef(); const trigger = ( ); return ( { columnFilters.setFilterPanelVisible(val); setVisible(val); }} offset={[0, 8]} trigger={trigger} triggerType="click" rtl={rtl} container={tableBeforeContainer.current} > setVisible(false)} {...others} /> ); }; ProTableColumnTitleFilter.displayName = 'ProTableColumnTitleFilter'; ================================================ FILE: packages/fusion-ui/src/components/pro-table/components/pro-table-column-title/pro-table-column-title-sortter.tsx ================================================ import * as React from 'react'; import { CustomIcon } from '@/components/toggle-icon'; import { SortValue } from '../../types'; import cns from 'classnames'; export interface ProTableColumnTitleSortterProps { value?: SortValue; className?: string; sortDirections?: SortValue[]; onChange: (val: SortValue) => void; } export const ProTableColumnTitleSortter: React.FC = ({ sortDirections = ['desc', 'asc', 'default'], value, onChange, }) => { const val = value || 'default'; return (
{ const index = sortDirections.indexOf(val); onChange(sortDirections[(index + 1) % sortDirections.length]); }} >
); }; ProTableColumnTitleSortter.displayName = 'ProTableColumnTitleSortter'; ProTableColumnTitleSortter.defaultProps = { sortDirections: ['desc', 'asc', 'default'], value: 'default', }; ================================================ FILE: packages/fusion-ui/src/components/pro-table/components/pro-table-column-title/utils.ts ================================================ // export const filterTree = () => {} ================================================ FILE: packages/fusion-ui/src/components/pro-table/components/pro-table-compact-button.tsx ================================================ import * as React from 'react'; import { FC, useContext } from 'react'; import { useI18nBundle } from '@/provider'; import { ProTableSettingContext } from '../contexts/pro-table-setting-context'; import { ToggleIcon } from '@/components/toggle-icon'; /** * 表格密度调整按钮 */ export const ProTableCompactButton: FC = () => { const i18nBundle = useI18nBundle('ProTable'); const { tableSetting, setTableSetting } = useContext(ProTableSettingContext); const onSizeChange = () => { setTableSetting((oldState) => ({ ...oldState, size: oldState.size === 'small' ? 'medium' : 'small', })); }; return ( ); }; ProTableCompactButton.displayName = 'ProTableCompactButton'; ================================================ FILE: packages/fusion-ui/src/components/pro-table/components/pro-table-fullscreen-button.tsx ================================================ import * as React from 'react'; import { useFullscreen } from 'ahooks'; import is from '@sindresorhus/is'; import { useI18nBundle } from '@/provider'; import { ToggleIcon } from '@/components/toggle-icon'; import { ProTableContext } from '../contexts/pro-table-context'; interface ProTableFullscreenButtonProps { /** * 全屏状态变化回调 */ onFullscreenStateChange?: (fullscreenState: boolean) => void; } /** * 表格全屏设置按钮 */ export const ProTableFullscreenButton: React.FC = ({ onFullscreenStateChange, }) => { const i18nBundle = useI18nBundle('ProTable'); const { proTableContainer } = React.useContext(ProTableContext); const [isFullscreen, { toggleFull }] = useFullscreen(proTableContainer, { onFull: () => { const ele = proTableContainer.current; if (ele) { ele.classList.add('fullscreen'); } if (is.function_(onFullscreenStateChange)) { onFullscreenStateChange(true); } }, onExitFull: () => { const ele = proTableContainer.current; if (ele) { ele.classList.remove('fullscreen'); } if (is.function_(onFullscreenStateChange)) { onFullscreenStateChange(false); } }, }); return ( ); }; ProTableFullscreenButton.displayName = 'ProTableFullscreenButton'; ================================================ FILE: packages/fusion-ui/src/components/pro-table/components/pro-table-setting-button/index.scss ================================================ @import '../../../../variables.scss'; .fusion-ui-pro-table-setting-panel { background: var(--color-white, $color-white); padding: 0 $s-2; border-radius: var(--corner-1, $corner-1); box-shadow: var(--shadow-2-down, $shadow-2-down); max-height: 400px; overflow-y: auto; width: 240px; box-sizing: border-box; } .fusion-ui-pro-table-setting-block { display: flex; flex-direction: column; &:first-child { margin-top: var(--s-4, $s-4); } &:last-child { margin-bottom: var(--s-4, $s-4); } &__title { font-size: var(--font-size-body-1, $font-size-body-1); color: var(--color-text1-1, $color-text1-1); margin-left: var(--s-2, $s-2); padding: var(--s-2 0, $s-2 0); position: sticky; background-color: var(--color-white, $color-white); top: 0; bottom: 0; z-index: 1; } } .fusion-ui-pro-table-setting-item { display: flex; flex-direction: column; .fusion-ui-checkbox-label { margin-left: var(--s-2, $s-2); } &__bd { display: flex; flex-direction: row; align-items: center; justify-content: space-between; box-sizing: border-box; padding: var(--s-2, $s-2); font-size: var(--font-size-body-1, $font-size-body-1); border-radius: var(--corner-2, $corner-2); &:hover { background-color: var(--color-fill1-1, $color-fill1-1); } } &__icons { display: flex; gap: var(--s-3, $s-3); flex-direction: row; align-items: center; } &__drag, &__icon { color: var(--color-text1-2, $color-text1-2); cursor: pointer; &:hover { color: var(--color-brand1-6, $color-brand1-6); } } &__icon { display: none; } &__drag { cursor: move; } &:hover { .fusion-ui-pro-table-setting-item__icon { display: block; } } .fusion-ui-pro-table-setting-item { padding-left: var(--s-4, $s-4); } } // .sort-item { // margin-bottom: 11px; // .fusion-ui-checkbox-wrapper.sort-checkbox { // white-space: nowrap; // max-width: calc(100% - 16px - 20px); // .fusion-ui-checkbox-label { // white-space: nowrap; // text-overflow: ellipsis; // overflow: hidden; // } // } // .column-drag-handle { // display: block; // cursor: move; // color: var(--color-text1-2, $color-text1-2); // } // } ================================================ FILE: packages/fusion-ui/src/components/pro-table/components/pro-table-setting-button/index.tsx ================================================ import * as React from 'react'; import { useRef } from 'react'; import { OverlayProps } from '@alifd/next/types/overlay/index'; import { ProTableSettingOverlay } from './pro-table-setting-overlay'; import { useI18nBundle } from '@/provider'; import { ToggleIcon } from '@/components/toggle-icon'; import { ProTableColumnsSettingContext } from '@/components/pro-table/contexts/pro-table-columns-setting-context'; export interface ProTableSettingButtonProps { /** * 排序窗口属性,属性参考 Fusion Overlay */ sortOverlayProps?: Partial; } const settingKeys = new Set(['sortRank', 'hidden', 'lock']); export const ProTableSettingButton: React.FC = ({ sortOverlayProps, }) => { const [visible, setVisible] = React.useState(false); const { columnsSetting } = React.useContext(ProTableColumnsSettingContext); const buttonRef = useRef(); const i18nBundle = useI18nBundle('ProTable'); const hasSetting = React.useMemo( () => Object.values(columnsSetting).some( (vo) => vo && Object.keys(vo).some((k) => settingKeys.has(k)), ), [columnsSetting], ); return (
setVisible(!visible)} active={visible || hasSetting} ref={buttonRef} /> {visible && ( type === 'docClick' && setVisible(false)} target={buttonRef.current} safeNode={buttonRef.current} offset={[8, 8]} {...sortOverlayProps} /> )}
); }; ProTableSettingButton.displayName = 'ProTableSettingButton'; ================================================ FILE: packages/fusion-ui/src/components/pro-table/components/pro-table-setting-button/pro-table-setting-overlay.tsx ================================================ import * as React from 'react'; import cx from 'classnames'; import { Overlay } from '@alifd/next'; import { OverlayProps } from '@alifd/next/types/overlay/index'; import { ProTableSettingSortableList } from './pro-table-setting-sortable-list'; import { ProTableSettingItem, ProTableSettingMenuItem } from './types'; import { ProTableColumnsSettingContext } from '@/components/pro-table/contexts/pro-table-columns-setting-context'; import { ProTableColumnProps } from '@/components/pro-table/types'; import { getColumnKey } from '../pro-table-base/utils'; import { ProTableContext } from '@/components/pro-table/contexts/pro-table-context'; import is from '@sindresorhus/is'; import { ProTableColumnsContext } from '@/components/pro-table/contexts/pro-table-columns-context'; export type ProTableSettingOverlayActionType = 'init' | 'input' | 'resize'; export type ProTableSettingOverlayValue = Record; export const ProTableSettingOverlay: React.FC = (props) => { const { columnsSetting, updateColumnSetting, updateColumnsSetting } = React.useContext( ProTableColumnsSettingContext, ); const { tableBeforeContainer } = React.useContext(ProTableContext); const { columns, columnKey } = React.useContext(ProTableColumnsContext); const onToggleShow = React.useCallback( (item: ProTableSettingMenuItem, checked: boolean) => { updateColumnSetting(item.id, () => ({ hidden: !checked }), 'input'); }, [updateColumnSetting], ); const onLock = React.useCallback( (id: string, lock: boolean | 'left' | 'right') => { updateColumnSetting(id, () => ({ lock }), 'input'); }, [updateColumnSetting], ); const onSortEnd = React.useCallback( (oldIndex: number, newIndex: number, ids: string[]) => { ids.splice(newIndex, 0, ...ids.splice(oldIndex, 1)); // 当前项移至新位置 // 按新顺序更新sortRank updateColumnsSetting( ids.reduce( (p, key, sortRank) => ({ ...p, [key]: { sortRank, }, }), {}, ), 'input', ); }, [updateColumnsSetting], ); const dataSource = React.useMemo(() => { const formatItems = (items: ProTableColumnProps[]): ProTableSettingMenuItem[] => items .map((vo, index) => { const id = getColumnKey(vo, columnKey); return { id, title: vo.title || vo.group, defaultSortRank: index, defaultLock: vo.lock, children: vo.group && is.array(vo.children) && vo.children.length > 0 ? formatItems(vo.children) : undefined, }; }) .filter((vo) => vo.id); return formatItems(columns || []); }, [columnKey, columns]); const dataSourceGroup = React.useMemo(() => { const leftLock = []; const rightLock = []; const noLock = []; dataSource.forEach((vo) => { const settingLock = columnsSetting[vo.id]?.lock; const lock = is.undefined(settingLock) ? vo.defaultLock : settingLock; if (lock === 'left' || lock === true) { leftLock.push(vo); } else if (lock === 'right') { rightLock.push(vo); } else { noLock.push(vo); } }); return [ { title: '固定在左侧', key: 'left', lock: 'left', dataSource: leftLock, }, { title: '不固定', key: 'no', lock: false, dataSource: noLock, }, { title: '固定在右侧', key: 'right', lock: 'right', dataSource: rightLock, }, ].filter((vo) => vo.dataSource.length > 0); }, [dataSource, columnsSetting]); return (
{dataSourceGroup.map((vo) => (
{vo.title}
))}
); }; ProTableSettingOverlay.displayName = 'ProTableSettingOverlay'; ================================================ FILE: packages/fusion-ui/src/components/pro-table/components/pro-table-setting-button/pro-table-setting-sortable-list.tsx ================================================ import * as React from 'react'; import { ReactSortable } from 'react-sortablejs'; import { Checkbox, Balloon } from '@alifd/next'; import { CustomIcon } from '@/components/toggle-icon'; import is from '@sindresorhus/is'; import { ProTableSettingItem, ProTableSettingMenuItem } from './types'; import { useI18nBundle } from '@/provider'; const { Tooltip } = Balloon; export interface ProTableSettingSortableListProps { dataSource: ProTableSettingMenuItem[]; onToggleShow: (item: ProTableSettingMenuItem, checked: boolean) => void; onSortEnd?: (oldIndex: number, newIndex: number, keys: string[]) => void; onLock?: (id: string, lock: boolean | string) => void; lock?: boolean | string; parentHidden?: boolean; setting: Record; } const getSortRank = ( item: ProTableSettingMenuItem, columnsSetting: Record, ) => { const settingSortRank = columnsSetting[item.id]?.sortRank; return is.undefined(settingSortRank) ? item.defaultSortRank : settingSortRank; }; export const ProTableSettingSortableList: React.FC = ({ dataSource, onToggleShow, onSortEnd, onLock, lock, setting, parentHidden, }) => { const i18nBundle = useI18nBundle('ProTable'); const items = React.useMemo( () => dataSource.sort((aItem, bItem) => getSortRank(aItem, setting) - getSortRank(bItem, setting)), [dataSource, setting], ); return ( is.function_(onSortEnd) && onSortEnd( e.oldIndex, e.newIndex, items.map((vo) => vo.id), ) } swap list={items} setList={() => {}} > {items.map((item) => (
onToggleShow(item, checked)} > {item.title}
{onLock && ( <> {lock !== 'left' && ( onLock(item.id, 'left')} /> } > {i18nBundle.settingButtonLockLeft} )} {lock && ( onLock(item.id, false)} /> } > {i18nBundle.settingButtonLockCancel} )} {lock !== 'right' && ( onLock(item.id, 'right')} /> } > {i18nBundle.settingButtonLockRight} )} )}
{is.array(item.children) && item.children.length > 0 && ( )}
))}
); }; ================================================ FILE: packages/fusion-ui/src/components/pro-table/components/pro-table-setting-button/types.ts ================================================ export interface ProTableSettingItem { /** * 排序排名,顺序从小到大 */ sortRank?: number; /** * 是否隐藏 * @default false */ hidden?: boolean; /** * 拖拽宽度 */ width?: number | string; /** * 锁列 */ lock?: boolean | string; } export type ProTableSettingActionType = 'init' | 'input' | 'resize'; export interface ProTableSettingMenuItem { children?: ProTableSettingMenuItem[]; title?: React.ReactNode; defaultSortRank?: number; defaultLock?: boolean | string; id: string; } ================================================ FILE: packages/fusion-ui/src/components/pro-table/components/pro-table-slot.tsx ================================================ import * as React from 'react'; import { ReactNode, PropsWithChildren, FC, isValidElement, ReactElement } from 'react'; /** 运行的槽位 */ export type ProTableSlotPosition = | 'actionBarLeft' | 'actionBarRight' | 'actionBarBefore' | 'actionBarAfter' | 'table' | 'tableAfter'; /** 默认的槽位 */ const defaultPosition: ProTableSlotPosition = 'table'; export interface ProTableSlotProps { /** * 插入槽位 * - actionBarLeft 操作条左侧 * - actionBarRight 操作条右侧 * - actionBarBefore 操作条前 * - actionBarAfter 操作条后 * - table 表格内 */ position: ProTableSlotPosition; } export const ProTableSlot: FC = ({ children }) => <>{children}; ProTableSlot.displayName = 'ProTableSlot'; const isProTableSlot = (element: unknown): element is ReactElement => isValidElement(element) && (element.type as typeof ProTableSlot)?.displayName === ProTableSlot.displayName; export interface ProTableSlotsOptions { /** 操作条左侧槽位 */ actionBarLeft?: ReactNode; /** 操作条右侧槽位 */ actionBarRight?: ReactNode; /** 操作条前槽位 */ actionBarBefore?: ReactNode; /** 操作条后槽位 */ actionBarAfter?: ReactNode; /** 表格内槽位 */ table?: ReactNode; tableAfter?: ReactNode; } export const useProTableSlots = ({ children, ...defaultSlots }: PropsWithChildren) => { const slots: Partial> = {}; const pushSlot = (position: ProTableSlotPosition, node: ReactNode) => { if (!node) { return; } if (position in slots) { slots[position].push(node); } else { slots[position] = [node]; } }; Object.keys(defaultSlots).forEach((position: ProTableSlotPosition) => pushSlot(position, defaultSlots[position]), ); React.Children.forEach(children, (vo) => { if (!isProTableSlot(vo)) { pushSlot(defaultPosition, vo); return; } pushSlot(vo.props.position, vo); }); return slots; }; ================================================ FILE: packages/fusion-ui/src/components/pro-table/components/pro-table-zebra-button.tsx ================================================ import * as React from 'react'; import { useContext, useCallback } from 'react'; import { useI18nBundle } from '@/provider'; import { ProTableSettingContext } from '../contexts/pro-table-setting-context'; import { ToggleIcon } from '@/components/toggle-icon'; /** * 表格设置斑马线按钮 */ export const ProTableZebraButton: React.FC = () => { const { tableSetting, setTableSetting } = useContext(ProTableSettingContext); const i18nBundle = useI18nBundle('ProTable'); const handleClick = useCallback( () => setTableSetting((oldState) => ({ ...oldState, isZebra: !oldState.isZebra, })), [setTableSetting], ); return ( ); }; ProTableZebraButton.displayName = 'ProTableZebraButton'; ================================================ FILE: packages/fusion-ui/src/components/pro-table/contexts/pro-table-columns-context.tsx ================================================ import { createContext, useMemo } from 'react'; import { ProTableBaseProps } from '../types'; export const useProTableColumnsValue = ({ columns = [], columnKey = 'key', }: Pick) => { return useMemo( () => ({ columns, columnKey, }), [columnKey, columns], ); }; export type ProTableColumnsValue = ReturnType; export const ProTableColumnsContext = createContext({ columns: [], columnKey: 'key', }); ================================================ FILE: packages/fusion-ui/src/components/pro-table/contexts/pro-table-columns-filters-context.tsx ================================================ import { emptyFn } from '@/utils/constants'; import { useFiledState } from '@/utils/hooks/useFiledState'; import is from '@sindresorhus/is'; import { useState, useMemo, useCallback, createContext } from 'react'; import { SortValue, ProTableBaseProps } from '../types'; type UseColumnsFilterOptions = Pick< ProTableBaseProps, 'searchParams' | 'sort' | 'filterParams' | 'sortMode' | 'onSort' | 'onSearch' | 'onFilter' >; export const useColumnsFilterValue = (options: UseColumnsFilterOptions) => { const [sort, setSort] = useFiledState( { value: options.sort, onChange: (sortMap: Record, dataIndex: string) => { if (is.function_(options.onSort)) { options.onSort(dataIndex, sortMap[dataIndex], sortMap); } }, }, !!options.sort, ); const [filterParams, setFilterParams] = useFiledState( { value: options.filterParams, onChange: options.onFilter, }, !!options.filterParams, ); const [searchParams, setSearchParams] = useFiledState( { value: options.searchParams, onChange: options.onSearch, }, !!options.filterParams, ); /** 获取列的排序值 */ const getColumnSort = useCallback((dataIndex: string) => sort?.[dataIndex], [sort]); /** 设置列的排序值 */ const setColumnSort = useCallback( (dataIndex: string, val: SortValue) => setSort((oldVal) => { const newVal = !val || val === 'default' ? undefined : val; if (options.sortMode === 'single') { return { [dataIndex]: newVal, }; } return { ...oldVal, [dataIndex]: newVal, }; }, dataIndex), [setSort, options.sortMode], ); /** 获取列的筛选值 */ const getColumnSelectedKeys = useCallback( (dataIndex: string) => filterParams?.[dataIndex]?.selectedKeys, [filterParams], ); /** 设置列的筛选值 */ const setColumnSelectedKeys = useCallback( (dataIndex: string, selectedKeys: string[], visible: boolean) => setFilterParams((oldVal) => ({ ...oldVal, [dataIndex]: selectedKeys?.length > 0 ? { visible, selectedKeys, } : undefined, })), [setFilterParams], ); /** 获取列的关键字值 */ const getColumnKeywords = useCallback( (dataIndex: string) => searchParams?.[dataIndex]?.keywords, [searchParams], ); /** 设置列的关键字值 */ const setColumnKeywords = useCallback( (dataIndex: string, keywords: string, visible: boolean) => setSearchParams((oldVal) => ({ ...oldVal, [dataIndex]: keywords ? { visible, keywords, } : undefined, })), [setSearchParams], ); /** 是否有过滤面板显示 */ const [filterPanelVisible, setFilterPanelVisible] = useState(false); return useMemo( () => ({ filterPanelVisible, setFilterPanelVisible, sort, setSort, filterParams, setFilterParams, searchParams, setSearchParams, getColumnSort, getColumnSelectedKeys, getColumnKeywords, setColumnSort, setColumnSelectedKeys, setColumnKeywords, }), [ filterPanelVisible, filterParams, getColumnKeywords, getColumnSelectedKeys, getColumnSort, searchParams, setColumnKeywords, setColumnSelectedKeys, setColumnSort, setFilterParams, setSearchParams, setSort, sort, ], ); }; export type ProTableColumnsFilterValue = ReturnType; export const ProTableColumnsFilterContext = createContext({ filterPanelVisible: false, setFilterPanelVisible: emptyFn, filterParams: {}, getColumnKeywords: () => '', getColumnSelectedKeys: () => [], getColumnSort: () => 'default', searchParams: {}, setFilterParams: emptyFn, setSearchParams: emptyFn, setSort: emptyFn, sort: {}, setColumnSort: emptyFn, setColumnSelectedKeys: emptyFn, setColumnKeywords: emptyFn, }); ================================================ FILE: packages/fusion-ui/src/components/pro-table/contexts/pro-table-columns-setting-context.tsx ================================================ import { emptyFn } from '@/utils/constants'; import { useFiledState } from '@/utils/hooks/useFiledState'; import is from '@sindresorhus/is'; import { useMemo, useCallback, createContext } from 'react'; import { ProTableProps } from '../types'; import { ProTableSettingActionType, ProTableSettingItem, } from '../components/pro-table-setting-button/types'; export const useColumnsSettingValue = ( options: Pick< ProTableProps, 'columnsSetting' | 'onColumnsSettingChange' | 'defaultColumnsSetting' | 'columns' >, ) => { const [columnsSetting, setColumnsSetting] = useFiledState( { value: options.columnsSetting, defaultValue: options.defaultColumnsSetting || {}, onChange: options.onColumnsSettingChange, }, !!options.columnsSetting, ); const updateColumnsSetting = useCallback( ( newSetting: | Record> | (( oldVal: Record, ) => Record>), actionType: ProTableSettingActionType, ) => { setColumnsSetting((oldVal) => { const val = is.function_(newSetting) ? newSetting(oldVal || {}) : newSetting; return Object.keys(val).reduce( (p, key) => ({ ...p, [key]: { ...p[key], ...val[key], }, }), oldVal, ); }, actionType); }, [setColumnsSetting], ); const updateColumnSetting = useCallback( ( key: string, newSetting: | Partial | ((oldVal: ProTableSettingItem) => Partial), actionType: ProTableSettingActionType, ) => { updateColumnsSetting( (oldVal) => ({ [key]: is.function_(newSetting) ? newSetting(oldVal[key] || {}) : newSetting, }), actionType, ); }, [updateColumnsSetting], ); const getColumnSetting = useCallback( (key: string): ProTableSettingItem => columnsSetting[key] || {}, [columnsSetting], ); return useMemo( () => ({ columnsSetting, setColumnsSetting, updateColumnsSetting, getColumnSetting, updateColumnSetting, }), [ columnsSetting, getColumnSetting, setColumnsSetting, updateColumnSetting, updateColumnsSetting, ], ); }; export type ProTableColumnsSettingValue = ReturnType; export const ProTableColumnsSettingContext = createContext({ columnsSetting: {}, setColumnsSetting: emptyFn, updateColumnSetting: emptyFn, updateColumnsSetting: emptyFn, getColumnSetting: () => ({}), }); ================================================ FILE: packages/fusion-ui/src/components/pro-table/contexts/pro-table-context.tsx ================================================ import { createContext, MutableRefObject, useMemo } from 'react'; export const useProTableValue = (options: { tableBeforeContainer: MutableRefObject; proTableContainer: MutableRefObject; pageSize?: number; total?: number; }) => { const { proTableContainer, tableBeforeContainer, pageSize, total } = options; return useMemo( () => ({ proTableContainer, tableBeforeContainer, pageSize, total, }), [proTableContainer, tableBeforeContainer, pageSize, total], ); }; export type ProTableValue = ReturnType; export const ProTableContext = createContext({ proTableContainer: { current: document.body }, tableBeforeContainer: { current: document.body }, pageSize: undefined, total: undefined, }); ================================================ FILE: packages/fusion-ui/src/components/pro-table/contexts/pro-table-pagination-context.tsx ================================================ import { createContext, useMemo } from 'react'; import { ProTableProps, ProTablePaginationInstance } from '../types'; import { useFiledState } from '../../utils/hooks/useFiledState'; import { emptyFn } from '../../utils/constants'; export const useProTablePaginationValue = ({ paginationProps = {}, }: Pick) => { const [pageSize, setPageSize] = useFiledState( { value: paginationProps.pageSize, defaultValue: 10, onChange: paginationProps.onPageSizeChange, }, !!paginationProps.pageSize, ); const [current, setCurrent] = useFiledState( { value: paginationProps.current, defaultValue: paginationProps.defaultCurrent, onChange: (newVal) => paginationProps.onChange(newVal, {}), }, !!paginationProps.pageSize, ); const total = paginationProps.total || 0; return useMemo( () => ({ total, current, setCurrent, pageSize, setPageSize, }), [total, current, setCurrent, pageSize, setPageSize], ); }; export type ProTablePaginationValue = ReturnType; export const ProTablePaginationContext = createContext({ total: 0, current: 0, setCurrent: emptyFn, pageSize: 10, setPageSize: emptyFn, }); ================================================ FILE: packages/fusion-ui/src/components/pro-table/contexts/pro-table-row-selection-context.tsx ================================================ import { createContext, useMemo, useCallback } from 'react'; import { ProTableBaseProps, ProTableRowKey, ProTableRowRecord, ProTableRowSelectionInstance, } from '../types'; import is from '@sindresorhus/is'; import { emptyArray, emptyFn } from '@/utils/constants'; import { useFiledState } from '@/utils/hooks/useFiledState'; import { useUpdateEffect } from 'ahooks'; export const isSelectedAllPages = (selectedRowKeys: ProTableRowKey[], reverseSelection: boolean) => reverseSelection && selectedRowKeys.length === 0; const arrayOmit = (arr: string[] = [], omitArr: string[] = []) => { if (omitArr.length === 0) { return arr; } const keySet = new Set(omitArr); return arrayUnique(arr.filter((vo) => !keySet.has(vo))); // 剔除keys }; const arrayUnique = (arr: string[] = []) => Array.from(new Set(arr)); const arrayMerge = (arr1: string[] = [], arr2: string[] = []) => { return arrayUnique([...arr1, ...arr2]); }; const arrayPick = (arr: string[] = [], pickArr: string[] = []) => { if (arr.length === 0) { return arr; } if (!pickArr || pickArr.length === 0) { return []; } const keySet = new Set(pickArr); return arrayUnique(arr.filter((vo) => keySet.has(vo))); // 剔除keys }; const flatDataSource = (dataSource: ProTableRowRecord[]) => { let ret = []; dataSource.forEach((vo) => { if (!vo) return; ret.push(vo); if (is.array(vo.children)) { ret = ret.concat(vo.children); } }); return ret.length === dataSource.length ? dataSource : ret; }; export const useProTableRowSelectionValue = ({ rowSelection = {}, dataSource = [], primaryKey = 'id', }: Pick< ProTableBaseProps, 'rowSelection' | 'dataSource' | 'primaryKey' >): ProTableRowSelectionInstance => { const mode = rowSelection.mode || 'multiple'; /** 是否是反向选择状态 */ const [reverseSelection, setReverseSelection] = useFiledState( { value: rowSelection.reverseSelection, defaultValue: rowSelection.defaultReverseSelection || false, }, 'reverseSelection' in rowSelection, ); const getRowKeyByRecord = useCallback( (record: ProTableRowRecord) => record && record[primaryKey], [primaryKey], ); /** * 反/已选keys列表 * - reverseSelection为false时为已选的keys * - reverseSelection为true时为反选的keys */ const [selectedRowKeys, setSelectRowKeys] = useFiledState( { value: rowSelection.selectedRowKeys, defaultValue: rowSelection.defaultSelectedRowKeys || [], onChange: (keys, isReverseSelection) => { setReverseSelection(isReverseSelection); if (is.function_(rowSelection.onChange)) { const keysSet = new Set(keys); const selectedRecords = isReverseSelection ? dataSource.filter((vo) => !keysSet.has(getRowKeyByRecord(vo))) : dataSource.filter((vo) => keysSet.has(getRowKeyByRecord(vo))); rowSelection.onChange(keys, isReverseSelection, selectedRecords); } }, }, !!rowSelection.selectedRowKeys, ); // mode修改时,清空所选项 useUpdateEffect(() => { setSelectRowKeys([], false); }, [mode, setSelectRowKeys]); /** 当前页keys */ const flattedDataSource = useMemo(() => flatDataSource(dataSource), [dataSource]); const { getProps } = rowSelection; /** 当前页disabledKeys */ const currentPageDisableKeys = useMemo(() => { if (!is.function_(getProps)) { return emptyArray; } return flattedDataSource .filter((vo, index) => getProps(vo, index).disabled) .map(getRowKeyByRecord); }, [flattedDataSource, getProps, getRowKeyByRecord]); /** 增加/取消选择 */ const selectRows = useCallback( (selected: boolean, keys: ProTableRowKey[]) => { if (mode === 'single') { if (keys.length === 0) { return; } setSelectRowKeys((oldKeys) => { if (selected) { if (keys.length > 1) { console.warn('当前是单选模式, 不支持全选所有页'); } return [keys[keys.length - 1]]; } // 取消选择: 已选模式剔除选择的keys return arrayOmit(oldKeys, keys); }, false); return; } setSelectRowKeys((oldKeys) => { if (selected) { // 增加选择: 反选模式下剔除keys; 已选模式增加选择的keys return reverseSelection ? arrayOmit(oldKeys, keys) : arrayMerge(oldKeys, keys); } // 取消选择: 反选模式下增加keys; 已选模式剔除选择的keys return reverseSelection ? arrayMerge(oldKeys, keys) : arrayOmit(oldKeys, keys); }, reverseSelection); }, [reverseSelection, setSelectRowKeys, mode], ); /** 当前页keys */ const currentPageRowKeys = arrayOmit( useMemo(() => flattedDataSource.map(getRowKeyByRecord), [flattedDataSource, getRowKeyByRecord]), currentPageDisableKeys, ); // arrayOmit(currentPageRowKeys, currentPageDisableKeys); /** 本页已选行 */ const currentPageSelectedRowKeys = useMemo( () => reverseSelection ? arrayOmit(currentPageRowKeys, selectedRowKeys) : arrayPick(currentPageRowKeys, selectedRowKeys), [currentPageRowKeys, reverseSelection, selectedRowKeys], ); const selectAllPages = useCallback( (selected: boolean) => { if (selected && mode === 'single') { console.warn('当前是单选模式, 不支持全选所有页'); return; } return setSelectRowKeys([], selected); }, [setSelectRowKeys, mode], ); const selectCurrentPage = useCallback( (selected: boolean) => { if (selected && mode === 'single') { console.warn('当前是单选模式, 不支持全选当前页'); return; } return selectRows(selected, currentPageRowKeys); }, [currentPageRowKeys, selectRows, mode], ); const isSelectedRowKey = useCallback( (rowKey: ProTableRowKey) => reverseSelection ? !selectedRowKeys.includes(rowKey) : selectedRowKeys.includes(rowKey), [reverseSelection, selectedRowKeys], ); const hasSelectedRows = useCallback( () => reverseSelection || selectedRowKeys.length > 0, [reverseSelection, selectedRowKeys], ); return { selectAllPages, selectCurrentPage, selectRows, hasSelectedRows, isSelectedRowKey, currentPageSelectedRowKeys, currentPageRowKeys, reverseSelection, selectedRowKeys, getRowKeyByRecord, }; }; export const ProTableRowSelectionContext = createContext({ selectAllPages: emptyFn, selectCurrentPage: emptyFn, selectRows: emptyFn, currentPageSelectedRowKeys: emptyArray, currentPageRowKeys: emptyArray, reverseSelection: false, selectedRowKeys: emptyArray, isSelectedRowKey: () => false, getRowKeyByRecord: () => '', hasSelectedRows: () => false, }); ================================================ FILE: packages/fusion-ui/src/components/pro-table/contexts/pro-table-setting-context.tsx ================================================ import { emptyFn } from '@/utils/constants'; import { useFiledState } from '@/utils/hooks/useFiledState'; import { useMemo, createContext, useEffect } from 'react'; import { ProTableBaseProps } from '../types'; type UseProTableSettingOptions = Pick; export const useProTableSettingValue = (options: UseProTableSettingOptions) => { const [tableSetting, setTableSetting] = useFiledState({ defaultValue: { isZebra: options.isZebra, size: options.size, }, }); useEffect( () => setTableSetting({ ...options, }), Object.values(options), ); return useMemo( () => ({ tableSetting, setTableSetting, }), [tableSetting, setTableSetting], ); }; export type ProTableSettingValue = ReturnType; export const ProTableSettingContext = createContext({ tableSetting: { isZebra: false, size: 'medium', }, setTableSetting: emptyFn, }); ================================================ FILE: packages/fusion-ui/src/components/pro-table/hooks.ts ================================================ import * as React from 'react'; import { useDebounceFn, useFusionTable } from 'ahooks'; import { ProTableProps, SortValue } from './types'; import mapValues from 'lodash/mapValues'; import { BasePaginatedOptions, Result } from 'ahooks/lib/useFusionTable'; import { FilterProps } from '@/components/filter'; import { Field } from '@alifd/next'; interface TableParams { sorters: Record; searchers: Record; filters: Record; } type FilterParams = Record; export interface UseProTableResult extends Omit, 'tableProps'> { tableProps: { dataSource: Item[]; loading: boolean; onSort: ProTableProps['onSort']; onFilter: ProTableProps['onFilter']; onSearch: ProTableProps['onSearch']; paginationProps: ProTableProps['paginationProps']; }; filterProps: FilterProps; } export interface UseProTableServiceParams { /** * 当前页 */ current: number; /** * 每页条数 */ pageSize: number; /** * 表格筛选/排序/搜索参数 */ tableParams: TableParams; /** * 筛选表单参数 */ filterParams: FilterParams; } export type UseProTableService = (params: UseProTableServiceParams) => Promise<{ total: number; dataSource: Item[]; [key: string]: any; }>; export interface UseProTableOptions extends Omit, 'paginated'> { field?: Field; } /** * ProTable hooks * @param service 请求service * @param options 参数 */ export const useProTable = ( service: UseProTableService, options: UseProTableOptions = {}, ): UseProTableResult => { const [tableParams, setTableParams] = React.useState({ sorters: {}, searchers: {}, filters: {}, }); const selfField = Field.useField(); const field = options.field || selfField; const { run: setTableParamsDebounce } = useDebounceFn(setTableParams, { wait: 300 }); const fusionTable = useFusionTable( async (p, filterParams) => { const res = await service({ ...p, tableParams, filterParams }); return { ...res, list: res.dataSource, }; }, { defaultPageSize: 10, ...options, field, }, ); const { run: refresh } = useDebounceFn(fusionTable.refresh, { wait: 100 }); const tableEvents = React.useMemo<{ onSort: ProTableProps['onSort']; onFilter: ProTableProps['onFilter']; onSearch: ProTableProps['onSearch']; }>(() => { return { onFilter: (newVal) => { setTableParams((oldVal) => ({ ...oldVal, filters: mapValues(newVal, (vo) => vo && vo.selectedKeys), })); refresh(); }, onSearch: (newVal) => setTableParamsDebounce((oldVal) => { refresh(); return { ...oldVal, searchers: mapValues(newVal, (vo) => vo && vo.keywords), }; }), onSort: (index, order, sorters) => { setTableParams((oldVal) => ({ ...oldVal, sorters, })); refresh(); }, }; }, [setTableParamsDebounce, refresh]); const { type, changeType, submit, reset } = fusionTable.search || {}; return { ...fusionTable, tableProps: { ...fusionTable.tableProps, ...tableEvents, paginationProps: fusionTable.paginationProps, }, filterProps: { enableForm: true, onSearch: submit, onReset: reset, expand: type === 'advance', formProps: { field, }, onExpand: (expand) => { if ((type === 'advance') !== expand) { changeType(); } }, }, }; }; ================================================ FILE: packages/fusion-ui/src/components/pro-table/i18n.ts ================================================ export default { 'zh-CN': { columnTitleFilterPanelOk: '确认', columnTitleFilterPanelReset: '重置', columnTitleFilterPanelSearchPlaceholder: '搜索', columnTitleFilterPanelMenuSearchPlaceholder: '搜索', columnTitleFilterPanelAsc: '升序', columnTitleFilterPanelDesc: '倒序', selectionTooltipChosen: '已选择', selectionTooltipChosenEnd: '项', operation: '操作', indexColumnTitle: '序号', fullscreenButtonOpenTooltip: '全屏', fullscreenButtonCloseTooltip: '取消全屏', compactButtonCompactTooltip: '紧凑模式', compactButtonNormalTooltip: '正常模式', zebraButtonOpenTooltip: '斑马线', zebraButtonCloseTooltip: '隐藏斑马线', settingButtonTooltip: '列展示', settingButtonLockLeft: '固定在表格左侧', settingButtonLockRight: '固定在表格右侧', settingButtonLockCancel: '取消固定', // 分页 pagiationTotal: '共', pagiationItem: '项', pagiationItems: '项', }, 'en-US': { columnTitleFilterPanelOk: 'Ok', selectionTooltipChosen: '', selectionTooltipChosenEnd: 'items selected', operation: 'Action', indexColumnTitle: 'Index', fullscreenButtonOpenTooltip: 'Fullscreen', compactButtonBalloonText: 'Density Adjustment', zebraButtonOpenTooltip: 'Zebra', // 分页 pagiationTotal: 'Total', pagiationItem: 'item', pagiationItems: 'items', }, }; ================================================ FILE: packages/fusion-ui/src/components/pro-table/index.scss ================================================ @import './theme-dark.scss'; @import './components/edit-table/index.scss'; @import './components/pro-table/index.scss'; @import './components/pro-table-base/index.scss'; @import './components/pro-table-column-title/index.scss'; @import './components/pro-table-setting-button/index.scss'; .fusion-ui-pro-table-action-bar { display: flex; margin-bottom: var(--s-5, $s-5); align-items: center; justify-content: space-between; } .cell-label { &-success { color: var(--color-success-3, $color-success-3); } &-error { color: var(--color-error-3, $color-error-3); } &-warning { color: var(--color-warning-3, $color-warning-3); } &-notice { color: var(--color-notice-3, $color-notice-3); } &-help { color: var(--color-help-3, $color-help-3); } } ================================================ FILE: packages/fusion-ui/src/components/pro-table/index.tsx ================================================ export { EditTable } from './components/edit-table'; export { ProTable } from './components/pro-table'; export { GroupTable } from './components/group-table'; export { ProTableProps, ProTableColumnProps } from './types'; export { ProTableSlot, ProTableSlotProps, ProTableSlotPosition } from './components/pro-table-slot'; export * from './hooks'; ================================================ FILE: packages/fusion-ui/src/components/pro-table/theme-dark.scss ================================================ .dark { .fusion-ui-pro-table.fullscreen { background-color: var(--color-fill1-4, $color-fill1-4); .fusion-ui-pagination { background-color: var(--color-fill1-4, $color-fill1-4); } } .fusion-ui-pro-table-column-title-filter-panel { background-color: var(--color-fill1-4, $color-fill1-4); &__ft { border-top-color: var(--color-line1-2, $color-line1-2); } } .fusion-ui-pro-table-setting-panel { background-color: var(--color-fill1-4, $color-fill1-4); } .fusion-ui-pro-table-setting-block { &__title { background-color: var(--color-fill1-4, $color-fill1-4); } } .fusion-ui-table.zebra tr:nth-child(2n + 1) td { background-color: var(--color-fill1-2, $color-fill1-2); } .fusion-ui-pro-table-selection { background-color: var(--color-fill1-4, $color-fill1-4); } } ================================================ FILE: packages/fusion-ui/src/components/pro-table/types/index.ts ================================================ import * as React from 'react'; import { ColumnProps, GroupFooterProps, GroupHeaderProps, TableProps, } from '@alifd/next/types/table'; import { ButtonGroupProps } from '@/components/button-group'; // import { PaginationProps } from '@/pagination'; import { ProTableSlotsOptions } from '../components/pro-table-slot'; import { ProTableSettingActionType, ProTableSettingItem, } from '../components/pro-table-setting-button/types'; import { CheckboxProps } from '@alifd/next/types/checkbox'; import { RadioProps } from '@alifd/next/types/radio'; import { AsyncDataSource, ColorType } from '@/types'; import { ProTableButtonGroupProps } from '../components/pro-table-button-group/index'; import { PayloadButtonProps } from '../components/pro-table-button-group/payload-button'; /** * 全局和列都支持的配置 * 设置优先级: 列配置 > 列类型提供值 > 表格 */ export interface ProTableCellCommonProps { /** * 单元格没值时缺省值 * 设置优先级: 列配置 > 列类型提供值 > 表格 * @default '' */ cellDefault?: React.ReactNode; /** * 单元格tooltip显示逻辑 * 设置优先级: 列配置 > 列类型提供值 > 表格 * - ellipsis 在显示省略号时显示tooltip * - none 不显示tooltip * @default 'none' */ cellTooltipMode?: 'ellipsis' | 'none'; } export interface ProTableRowInstance { /** 当前行主键值 */ rowKey?: ProTableRowKey; /** 当前行下标 */ rowIndex: number; /** 当前行数据 */ rowRecord: ProTableRowRecord; } export interface ProTablePaginationInstance { /** 表格总行数 */ total: number; /** 当前页数 */ current: number; /** 当前每页行数 */ pageSize: number; /** 设置当前页数 */ setCurrent: (page: number) => void; /** 设置每页行数 */ setPageSize: (pageSize: number) => void; } export interface ProTableInstance { rowSelection: ProTableRowSelectionInstance; // pagination: ProTablePaginationInstance; } export interface ProTableColumnProps extends ProTableCellCommonProps, Omit { /** * 列的唯一表示,当不存在是默认取dataIndex的值 */ key?: string; /** * 当设定 group, 表明此为父子表头的父表头, 值会作为父表头标题存在 */ group?: React.ReactNode; // totalCell?: ColumnProps['cell']; /** * 传入ProTable预置类型 或是 通过columnFormatter的扩展类型 * https://yuque.antfin-inc.com/docs/share/34a98885-3630-4a3f-921e-f29366b586b7 */ formatType?: | 'id' | 'number' | 'money' | 'currency' | 'date' | 'phone' | 'ou' | 'bankCard' | 'percent' | 'progress' | 'link' | 'tag' | 'textTag' | 'files' | 'employee' | string; /** 格式化参数 */ formatOptions?: string[]; /** * 值转换,如果是字典转换走dataSource */ formatValue?: (value: unknown, rowIndex: number, record: unknown) => unknown; /** * 回调、对象映射得到单元格的颜色 */ formatColor?: ColorType | ((value: unknown) => ColorType) | Record; /** * 单元格点击事件 */ onCellClick?: (value: unknown, rowIndex: number, record: unknown) => void; /** * 列dataSource,当前仅text/currency/textTag/tag类型的formatter支持 */ dataSource?: AsyncDataSource; /** * 帮助信息 */ explanation?: string; /** * 设定 group 后, children作为子表头的值存在 */ children?: ProTableColumnProps[]; /** * 是否支持关键字搜索 * @default false */ searchable?: boolean; /** * 生成标题过滤的菜单, 格式为`[{label:'xxx', value:'xxx'}]` */ filters?: AsyncDataSource; /** * 关键字和筛选是否是即时生效 * @default true */ isImmediate?: boolean; cell?: | React.ReactNode | ((value: unknown, rowIndex: number, record: unknown, context: any) => React.ReactNode); } export interface SearchParam { keywords: string; visible: boolean; } export interface FilterParam { selectedKeys: string[]; visible: boolean; } export type SortValue = 'desc' | 'asc' | 'default'; export interface ProTableColumnFilterValue { keywords?: string; sort?: SortValue; selectedKeys?: string[]; } export type ProTableColumnsFilterValue = Record; export type ProTableRowRecord = Record; export type ProTableRowKey = string; export interface ProTableRowSelectionInstance { /** 选中/反选的key */ readonly selectedRowKeys: ProTableRowKey[]; /** 是否是反选模式 */ readonly reverseSelection: boolean; /** 当前页选中所有的key */ readonly currentPageSelectedRowKeys: ProTableRowKey[]; /** 当前页所有的key */ readonly currentPageRowKeys: ProTableRowKey[]; /** 当前是否有选中的 */ readonly hasSelectedRows: () => boolean; /** 选择/取消选择所有页所有项 */ readonly selectAllPages: (selected: boolean) => void; /** 选择/取消选择当前页所有项 */ readonly selectCurrentPage: (selected: boolean) => void; /** 选择/取消选择多项 */ readonly selectRows: (selected: boolean, rowKeys: ProTableRowKey[]) => void; /** 判断当前行是否是选中状态 */ readonly isSelectedRowKey: (rowKey: ProTableRowKey) => boolean; /** 获取行数据key */ readonly getRowKeyByRecord: (rowRecord: ProTableRowRecord) => ProTableRowKey; } export type ProTableRowSelectionType = 'SELECTION_ALL' | 'SELECTION_NONE'; export type ProTableRowPayload = ProTableRowInstance; export type ProTablePayload = ProTableInstance; interface ActionColumnButton extends Omit, 'disabled' | 'hidden'> { key?: string; /** * 是否禁用 * @default false */ disabled?: boolean | ((payload: ProTableRowPayload) => boolean) | string; /** * 是否隐藏 * @default false */ hidden?: boolean | ((payload: ProTableRowPayload) => boolean) | string; } export interface ProTableActionColumnButtons extends Omit, 'dataSource'> { dataSource: ActionColumnButton[]; } export type ProTableActionBarButtons = ProTableButtonGroupProps; export interface ProTableBaseProps extends ProTableCellCommonProps, Omit { /** * 指定列唯一的标识,一般不需要设置 * @default key */ columnKey?: 'dataIndex' | 'key'; /** * 表格列设置 */ columns?: ProTableColumnProps[]; /** * 可以调整大小 */ resizable?: boolean; /** * 排序模式是单列还是多列 * @default 'multiple' */ sortMode?: 'single' | 'multiple'; /** * 排序值 */ sort?: Record; /** * 点击列排序触发的事件 */ onSort?: (dataIndex: string, order: SortValue, sort: Record) => void; searchParams?: Record; /** * 点击列搜索触发的事件 */ onSearch?: (searchParams: Record) => void; filterParams?: Record; /** * 点击列排序触发的事件 */ onFilter?: (filterParams: Record) => void; columnFilters?: ProTableColumnsFilterValue; onColumnsFilterChange?: ( newValue: ProTableColumnsFilterValue, oldValue: ProTableColumnsFilterValue, changedColumnFilterValue?: ProTableColumnFilterValue, changedColumnDataIndex?: string, ) => void; groupHeader?: React.ReactNode | GroupHeaderProps; groupFooter?: React.ReactNode | GroupFooterProps; /** * 是否设置 Table 为 Table.stickyLock */ stickyLock?: boolean; /** * 序号列 */ indexColumn?: boolean; /** * 序号列props */ indexColumnProps?: Partial; /** * 操作列配置覆盖 */ actionColumnProps?: Partial; /** * 操作列按钮组 */ actionColumnButtons?: ProTableActionColumnButtons; /** * 操作列按钮配置列表 * @deprecated 使用 actionColumnButtons */ actionColumn?: ActionColumnButton[]; /** * 操作列按钮组的props * @deprecated 使用 actionColumnButtons */ actionButtonGroupProps?: ButtonGroupProps; /** * 自定义列操作 * @deprecated 使用 actionColumnButtons */ actionColumnPredication?: (payload: { actionColumn?: any[]; index: number; record: any; }) => ActionColumnButton[]; /** * 操作列点击触发事件 * @deprecated 使用 actionColumnButtons */ onActionColumnClick?: (payload: { currentActionKey: string; selectedRowKey: string; record: any; }) => void; /** * 总计数据源, 传入后显示总计行, 统计行需要 */ totalDataSource?: Record; /** * 是否启用选择模式 * https://yuque.antfin-inc.com/docs/share/34ec077c-14d5-4408-bfd4-d2827bfd87ec */ rowSelection?: { /** * 选择实例 * https://yuque.antfin-inc.com/docs/share/34ec077c-14d5-4408-bfd4-d2827bfd87ec */ ref?: React.MutableRefObject; // columnProps?: () => any; // titleAddons?: () => any; /** * 获取selection的默认属性 * @param record 当前操作行数据 * @param index 当前行下标 */ getProps?: (record: ProTableRowRecord, index: number) => CheckboxProps | RadioProps; /** * 选择改变的时候触发的事件, * @param selectedRowKeys 选中/反选的keys * @param reverseSelection 是否反选模式 * @param records 只会包含当前dataSource的数据,很可能会小于selectedRowKeys的长度。 */ onChange?: ( selectedRowKeys: ProTableRowKey[], reverseSelection: boolean, records: ProTableRowRecord[], ) => void; /** * 用户手动选择/取消选择某行的回调 * @param selected 选择/取消选择 * @param record 当前操作行数据 * @param records 只会包含当前dataSource的数据 */ onSelect?: (selected: boolean, record: ProTableRowRecord, records: ProTableRowRecord[]) => void; /** * 用户手动选择/取消选择本页所有行的回调 * @param selected 选择/取消选择 * @param records 只会包含当前dataSource的数据。 */ onSelectAll?: (selected: boolean, records: ProTableRowRecord[]) => void; /** * 用户手动选择/取消选择本页所有行的回调 * @param selected 选择/取消选择 * @param records 只会包含当前dataSource的数据。 */ onSelectAllPages?: (selected: boolean, records: ProTableRowRecord[]) => void; /** * 选择selection的模式, 可选值为single, multiple * @default 'multiple' */ mode?: 'single' | 'multiple'; /** * 菜单配置项 * - SELECTION_ALL 开启全选所有页 * - SELECTION_NONE 开启取消选择所有项 * @default ['SELECTION_ALL', 'SELECTION_NONE'] */ selections?: Array<'SELECTION_ALL' | 'SELECTION_NONE'>; /** * 选中的值 */ selectedRowKeys?: ProTableRowKey[]; /** * 默认选中的值 */ defaultSelectedRowKeys?: ProTableRowKey[]; /** * 是否是反向选择 * @default false */ reverseSelection?: boolean; /** * 默认反向选择 * @default false */ defaultReverseSelection?: boolean; /** * 是否可以跨页选择,全选所有页强制开启跨页 * @default true */ crossPageSelection?: boolean; /** * 是否隐藏 tooltip * @default false */ hideTooltip?: boolean; /** * 列头标题CheckBox样式覆盖 */ titleProps?: () => CheckboxProps; }; // /** // * 单元格内容过长配置 // * @default 'ellipsis' // */ // cellOverflow?: 'ellipsis' | 'warp' | 'visible'; } type ProTableColumnsSetting = Record; export type ProTableSettingButtonType = 'compact' | 'zebra' | 'fullscreen' | 'setting'; export interface ProTableProps extends ProTableSlotsOptions, Omit { /** * 表格操作栏按钮 */ actionBarButtons?: ProTableActionBarButtons; /** * 表格设置按钮 * @default false */ settingButtons?: ProTableSettingButtonType[] | boolean; /** * 分页设置 */ // paginationProps?: PaginationProps; /** * 列设置 */ columnsSetting?: ProTableColumnsSetting; /** 默认列设置 */ defaultColumnsSetting?: ProTableColumnsSetting; /** * 设置改变时的回调 */ onColumnsSettingChange?: ( newSetting: ProTableColumnsSetting, actionType: ProTableSettingActionType, ) => void; /** * 全屏状态变化回调 */ onFullscreenStateChange?: (fullscreenState: boolean) => void; /** * 是否是子母表的子表 * @default false */ isExpandedChild?: boolean; paginationProps?: Record; } ================================================ FILE: packages/fusion-ui/src/components/pro-table/types/instance.ts ================================================ ================================================ FILE: packages/fusion-ui/src/components/segment/index.scss ================================================ @import './theme-dark.scss'; .fusion-ui-segment { position: relative; border-radius: var(--corner-2, $corner-2); background-color: var(--color-fill1-2, $color-fill1-2); display: inline-flex; padding: 2px; &-primary { .fusion-ui-segment-item { &:hover { color: var(--color-brand1-6, $color-brand1-6); } &.item-selected { color: var(--color-brand1-6, $color-brand1-6); } } } &-secondary { background-color: var(--color-brand1-1, $color-brand1-1); .fusion-ui-segment-item { color: var(--color-brand1-6, $color-brand1-6); &:hover { color: var(--color-brand1-9, $color-brand1-9); } &.item-selected { color: var(--color-white, $color-white); } } .fusion-ui-segment-handler { background-color: var(--color-brand1-6, $color-brand1-6); } } &-small { height: var(--s-6, $s-6); .fusion-ui-segment-item { padding: 0 var(--s-2, $s-2); line-height: var(--s-5, $s-5); height: var(--s-5, $s-5); } } &-medium { height: var(--s-7, $s-7); .fusion-ui-segment-item { padding: 0 var(--s-3, $s-3); line-height: var(--s-6, $s-6); height: var(--s-6, $s-6); } } &-large { height: var(--s-8, $s-8); padding: var(--s-1, $size-base); .fusion-ui-segment-item { padding: 0 var(--s-4, $s-4); line-height: var(--s-6, $s-6); height: var(--s-6, $s-6); } } &-item { height: 100%; display: flex; justify-content: center; align-items: center; z-index: 9; cursor: pointer; transition: color 0.3s; color: var(--color-text1-3, $color-text1-3); &:hover { color: var(--color-text1-4, $color-text1-4); } &.item-selected { color: var(--color-text1-4, $color-text1-4); // font-weight: 500; } } &-handler { position: absolute; border-radius: var(--corner-2, $corner-2); background-color: var(--color-white, $color-white); z-index: 1; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } &-full { width: 100%; .fusion-ui-box { width: 100%; .fusion-ui-segment-item { flex: 1; } } } } ================================================ FILE: packages/fusion-ui/src/components/segment/index.tsx ================================================ import React, { useEffect, useRef, useState, useMemo } from 'react'; import { motion } from 'framer-motion'; import { Space } from '../container'; import set from 'lodash/set'; import cn from 'classnames'; export interface SegmentDataSourceItem { label: React.ReactNode; value: any; } export interface SegmentProps { /** * 自定义样式 */ style?: React.CSSProperties; /** * 自定义样式名 */ className?: string; /** * 按钮数据源 */ dataSource: SegmentDataSourceItem[]; /** * 选中值的回调 */ onChange?: (value: any, data: SegmentDataSourceItem) => void; /** * 受控的值 */ value?: any; /** * 默认的值 */ defaultValue?: any; /** * @default "medium" * 按钮组大小 */ size?: 'small' | 'medium' | 'large'; /** * 是否占满容器的宽度,如果为 true,下面的元素将均分展示 */ fullWidth?: boolean; /** * @default "normal" * 按钮类型 */ type?: 'normal' | 'primary' | 'secondary'; } const Segment: React.FC = ({ className, style, dataSource, onChange, value: propsValue, defaultValue, fullWidth, size, type, }) => { const [selectedDom, setSelectedDom] = useState(null); const [value, setValue] = useState(defaultValue); const itemRef = useRef({}); const beforeWidth = useRef(null); const { width, height } = useMemo( () => selectedDom?.getBoundingClientRect() || {}, [selectedDom], ); const handlerOffsetLeft = useMemo( () => selectedDom?.offsetLeft - (size === 'large' ? 4 : 2), [selectedDom], ); // 首次进入的时候不需要动画 const noDuring = !beforeWidth.current && width; beforeWidth.current = width; // 受控模式处理 useEffect(() => { if (propsValue !== undefined) { setValue(propsValue); } }, [propsValue]); // 更新选中 dom useEffect(() => { setSelectedDom(itemRef.current[value]); }, [value]); // 点击选中某个值 const handleItemClick = (val: any, data: SegmentDataSourceItem) => { if (propsValue === undefined) { setValue(val); } onChange(val, data); }; const cssPrefix = 'fusion-ui-segment'; return (
{dataSource.map((item, index) => (
handleItemClick(item.value, item)} key={index} ref={(ref) => { set(itemRef.current, item.value, ref); }} > {item.label}
))}
); }; Segment.defaultProps = { onChange: () => {}, size: 'medium', type: 'normal', }; Segment.displayName = 'Segment'; export { Segment }; ================================================ FILE: packages/fusion-ui/src/components/segment/theme-dark.scss ================================================ body.dark { /* 这里写暗色覆盖主题 */ .fusion-ui-segment { transition: 0.3s background-color; background-color: var(--color-fill1-1, $color-fill1-1); &-handler { transition: 0.3s background-color; background-color: var(--color-line1-2, $color-line1-2); } } } ================================================ FILE: packages/fusion-ui/src/components/story-placeholder/index.tsx ================================================ import * as React from 'react'; // 新结构 interface IContent { aone?: { // 可能未绑定 url: string; priorityId: string; project: { id: string; name: string }; creator: { empId: string; name: string }; assigner: { empId: string; name: string }; }; subject: string; description: string; hideTitle?: boolean; id?: string; } interface IStoryPlaceholderProps { content?: IContent | string; className?: string; maxHeight?: string; } /** * 文字 字体、大小、行高 * @param props */ const StoryPlaceholder: React.ForwardRefRenderFunction = ( props, ref, ) => { const { content = { subject: '', description: '' }, maxHeight = 'auto', ...others }: IStoryPlaceholderProps = props; const oldType = typeof content === 'string'; const desc = oldType ? content : content?.description || ''; const title = (!oldType && content?.subject) || ''; const hideTitle = oldType || content?.hideTitle; return (
{!hideTitle && (
{title}
)}
); }; const RefStoryPlaceholder = React.forwardRef(StoryPlaceholder); RefStoryPlaceholder.defaultProps = { content: { subject: '需求标题', hideTitle: false, description: '
- 你可以在这里描述需求
- 或者粘贴需求截图
', }, className: '', }; export default RefStoryPlaceholder; ================================================ FILE: packages/fusion-ui/src/components/tab-container/index.scss ================================================ .fusion-ui-tab { display: block; background-color: #fff; &.next-medium { .next-tabs-content { padding: 16px; } } &.next-small { .next-tabs-content { padding: 12px; } } } ================================================ FILE: packages/fusion-ui/src/components/tab-container/index.tsx ================================================ import * as React from 'react'; import cx from 'classnames'; import { Tab } from '@alifd/next'; export interface ITabContainerProps extends React.ComponentProps { className?: string; } export const TabContainer = (props: ITabContainerProps) => { const { className, ...restProps } = props; return ; }; TabContainer.Item = Tab.Item; ================================================ FILE: packages/fusion-ui/src/components/toggle-icon/index.scss ================================================ @import './theme-dark.scss'; .fusion-ui-toggle-icon-group { display: flex; gap: var(--s-1, $s-1); background-color: var(--color-fill1-2, $color-fill1-2); border-radius: var(--s-1, $s-1); padding: 2px $s-2; } .fusion-ui-toggle-icon { display: flex; flex-direction: row; align-items: center; justify-content: center; cursor: pointer; width: var(--s-7, $s-7); height: var(--s-7, $s-7); border-radius: var(--corner-2, $corner-2); background-color: var(--color-fill1-2, $color-fill1-2); &:hover { background-color: #e6e8eb; color: var(--color-brand1-6, $color-brand1-6); } &--active { color: var(--color-brand1-6, $color-brand1-6); } } ================================================ FILE: packages/fusion-ui/src/components/toggle-icon/index.tsx ================================================ import { Icon, Balloon } from '@alifd/next'; import * as React from 'react'; import cns from 'classnames'; import { IconProps } from '@alifd/next/types/icon'; const RemoteIcon = Icon.createFromIconfontCN({ scriptUrl: '//at.alicdn.com/t/font_2535522_4oyyibdwj5v.js', }); export const CustomIcon = (props) => { const { type, ...otherProps } = props; return ; }; const { Tooltip } = Balloon; /** * icon组 */ export const ToggleIconGroup: React.FC> = ({ className, ...props }) =>
; export interface ToggleIconProps extends React.HtmlHTMLAttributes { title?: string; active?: boolean; type: IconProps['type']; size?: IconProps['size']; } export const ToggleIcon = React.forwardRef( ({ title, active, type, size, className, ...props }, ref) => { const trigger = ( ); if (!title) return trigger; return {title}; }, ); ToggleIcon.defaultProps = { size: 'small', }; ================================================ FILE: packages/fusion-ui/src/components/toggle-icon/theme-dark.scss ================================================ .dark { .fusion-ui-toggle-icon { &:hover { background-color: var(--color-fill1-4, $color-fill1-4); } } } ================================================ FILE: packages/fusion-ui/src/index.scss ================================================ @import './variables.scss'; @import './common/operations/index.scss'; @import './components/anchor/index.scss'; @import './components/ellipsis/index.scss'; @import './components/expand-table/index.scss'; @import './components/filter/index.scss'; @import './components/menu/index.scss'; @import './components/menu-button/index.scss'; @import './components/pro-dialog/index.scss'; @import './components/pro-drawer/index.scss'; @import './components/page-header/index.scss'; @import './components/pro-table/index.scss'; @import './components/pro-form/index.scss'; @import './components/segment/index.scss'; @import './components/tab-container/index.scss'; @import './components/toggle-icon/index.scss'; #{$biz-css-prefix}page .lc-container-placeholder { min-height: 48px; background: #f1f1f1; border: 1px solid #e0e0e0; } ================================================ FILE: packages/fusion-ui/src/index.tsx ================================================ import { version } from '../package'; // export { default as ProCard } from './components/pro-card'; // export type { CardProps, CardSectionProps } from './components/pro-card'; export { default as PieChart } from './components/pie-chart'; export { default as ColumnChart } from './components/column-chart'; export { default as BarChart } from './components/bar-chart'; export { default as LineChart } from './components/line-chart'; export { default as AreaChart } from './components/area-chart'; export { default as DonutChart } from './components/donut-chart'; export * from './components/page-header'; export * from './components/pro-form'; export * from './components/pro-table'; export * from './components/expand-table'; export * from './components/filter'; export * from './components/anchor'; export * from './components/pro-dialog'; export * from './components/tab-container'; export * from './components/pro-drawer'; export * from './components/button'; export * from './components/button-group'; export { default as StoryPlaceholder } from './components/story-placeholder'; export * from './variables'; const bizCssPrefix = 'fusion-ui'; const displayName = 'FusionUI'; export { bizCssPrefix, displayName, version }; ================================================ FILE: packages/fusion-ui/src/provider/contexts/locale-context/index.ts ================================================ import React, { useContext, useMemo, createContext, useState, useCallback } from 'react'; import { locales as defaultI18nBundles } from '@/utils/locales'; import { getCookieLanguage, toISOLanguage } from './util'; export type LanguageType = 'zh-CN' | 'en-US'; const DEFAULT_LANGUAGE: LanguageType = 'zh-CN'; type I18nBundlesType = typeof defaultI18nBundles; /** * 所有定义文案的组件名字 */ export type I18nBundlesNames = keyof I18nBundlesType; /** 某一组的文案集合类型 */ export type ComponentI18nBundleType = I18nBundlesType[Name]['zh-CN']; /** * 用户定义的多语言文案 */ export type CustomI18nBundles = { [Name in I18nBundlesNames]?: Partial>; }; /** * 传入组件名字获取文案集合 * * @example * ``` ts * const i18nBundle = getI18nBundle('card', 'zh-CN', { collapse: '收起abc' }); * i18nBundle.collapse // '收起abc' * i18nBundle.open // '打开' * ``` * @param componentName 组件名称,如tablex * @param lang 需要的语言,默认是中文 * @param customI18nBundle 自定义文案 * @returns 当前组件的文案集合 */ const getI18nBundleBase = ( componentName: Name, lang: 'zh-CN' | 'en-US' = 'zh-CN', customI18nBundle?: Partial>, ): ComponentI18nBundleType => { const componentBundles = defaultI18nBundles[componentName]; if (!componentBundles) { return {} as any; } if (lang === 'en-US') { return { ...componentBundles['zh-CN'], ...componentBundles['en-US'], ...customI18nBundle, }; } if (customI18nBundle) { return { ...componentBundles['zh-CN'], ...customI18nBundle, }; } return componentBundles['zh-CN']; }; export interface LocaleContextValue { language: LanguageType; setLanguage: React.Dispatch>; i18nBundles?: CustomI18nBundles; getI18nBundle: ( componentName: Name, ) => ComponentI18nBundleType; } export const LocaleContext = createContext({ language: DEFAULT_LANGUAGE, setLanguage: () => {}, getI18nBundle: (componentName) => getI18nBundleBase(componentName, DEFAULT_LANGUAGE), i18nBundles: {}, }); export const useLanguage = () => useContext(LocaleContext).language; export const useLocaleContextValue = ( defaultLanguage: LanguageType = DEFAULT_LANGUAGE, i18nBundles?: CustomI18nBundles, ): LocaleContextValue => { const [language, setLanguage] = useState( defaultLanguage ? toISOLanguage(defaultLanguage) : getCookieLanguage(), ); const getI18nBundleCtx = useCallback( (componentName: Name): ComponentI18nBundleType => getI18nBundleBase(componentName, language, i18nBundles?.[componentName]), [i18nBundles, language], ); return { language, setLanguage, i18nBundles, getI18nBundle: getI18nBundleCtx, }; }; /** * Hooks: 传入组件名字获取文案集合 * * @example * ``` ts * const i18nBundle = useI18nBundle('card'); * i18nBundle.collapse // '收起' * ``` * @param componentName 组件名称,如tablex * @returns 当前组件的文案集合 */ export const useI18nBundle = (componentName: Name) => { const { getI18nBundle } = useContext(LocaleContext); return useMemo>( () => getI18nBundle(componentName), [componentName, getI18nBundle], ); }; ================================================ FILE: packages/fusion-ui/src/provider/contexts/locale-context/util.ts ================================================ import Cookies from 'js-cookie'; export const toSSOLanguage = (language: 'zh-CN' | 'en-US'): 'zh-CN' | 'en' => { return language.toLowerCase().includes('en') ? 'en' : 'zh-CN'; }; export const toISOLanguage = (language: string): 'zh-CN' | 'en-US' => { return language.toLowerCase().includes('en') ? 'en-US' : 'zh-CN'; }; export const getCookieLanguageKey = () => { // 首先从全局作用域中获取 _i18nCookieName_ 变量值作为 cookie 名称,便于可能由于历史原因而暂无法统一 cookie 名称的场景 // 如果没全局设定,那么使用实参 // 如果无实参,那么使用默认值 SSO_LANG_V2 let _cookieName; if (typeof window !== 'undefined') { _cookieName = (window as any)._i18nCookieName_; } if (!_cookieName) { _cookieName = 'SSO_LANG_V2'; } return _cookieName; }; /** * 获取页面所用的多语言 locale * * 首先从 cookie 中获取,cookie 名称优先通过 window._i18nCookieName_ 来获取,如果为空且无显式传参时,默认是 SSO_LANG_V2 * 没有,从 navigator 中获取; * 没有,最后使用默认值 zh-CN */ export function getCookieLanguage() { let language = Cookies.get(getCookieLanguageKey()); if (!language && typeof navigator === 'object') { language = navigator.language; } return toISOLanguage(language || 'zh-CN'); } ================================================ FILE: packages/fusion-ui/src/provider/contexts/theme-context/index.ts ================================================ import { createContext, useContext, useEffect, useState, useRef } from 'react'; export type ThemeType = 'light' | 'dark'; export interface ThemeContextValue { theme: ThemeType; setTheme: React.Dispatch>; } export const ThemeContext = createContext({ theme: 'light', setTheme: () => {}, }); export const useThemeContextValue = (defaultTheme: ThemeType = 'light'): ThemeContextValue => { const [theme, setTheme] = useState(defaultTheme); const stylePoolsRef = useRef([]); // 加载样式 const loadStyle = (styleString) => { const oStyle = document.createElement('style'); oStyle.innerHTML = styleString; document.head.appendChild(oStyle); stylePoolsRef.current.push(oStyle); return oStyle; }; // 主题样式清理 const cleanup = () => { while (stylePoolsRef.current.length) { stylePoolsRef.current.pop().remove(); } }; useEffect(() => { return cleanup; }); // 主题切换 useEffect(() => { const DARK_THEME_VERSION = '0.4.2'; const THEME_CDN_PREFIX = 'https://unpkg.alibaba-inc.com/@alifd/next'; if (theme === 'dark') { document.body.classList.add('dark'); fetch(`${THEME_CDN_PREFIX}@${DARK_THEME_VERSION}/variables.css`) .then((res) => res.text()) .then((tokens) => { loadStyle(tokens); loadStyle(` :root { color-scheme: dark; }`); }); } else { document.body.classList.remove('dark'); cleanup(); } }, [theme]); return { theme, setTheme, }; }; export const useTheme = () => useContext(ThemeContext).theme; ================================================ FILE: packages/fusion-ui/src/provider/index.tsx ================================================ export * from './provider'; export * from './contexts/locale-context'; export * from './contexts/theme-context'; ================================================ FILE: packages/fusion-ui/src/provider/provider.tsx ================================================ import { I18nBundlesNames, LocaleContext, LocaleContextValue, useI18nBundle, CustomI18nBundles, LanguageType, useLocaleContextValue, useLanguage, } from '@/provider/contexts/locale-context'; import { ThemeContext, ThemeContextValue, ThemeType, useThemeContextValue, } from '@/provider/contexts/theme-context'; import hoistNonReactStatics from 'hoist-non-react-statics'; import * as React from 'react'; import PropTypes from 'prop-types'; import { ConfigProvider } from '@alifd/next'; import enUS from '@alifd/next/lib/locale/en-us'; import zhCN from '@alifd/next/lib/locale/zh-cn'; export type GlobalConfig = LocaleContextValue & ThemeContextValue; export const GlobalConfigProvider: React.FC<{ theme?: ThemeType; language?: LanguageType; i18nBundles?: CustomI18nBundles; }> = ({ theme: propsTheme, language, i18nBundles, children }) => { const themeContextValue = useThemeContextValue(propsTheme); const localeContextValue = useLocaleContextValue(language, i18nBundles); React.useEffect(() => { themeContextValue.setTheme(propsTheme); }, [propsTheme]); return ( {children} ); }; GlobalConfigProvider.propTypes = { theme: PropTypes.oneOf(['dark', 'light']), language: PropTypes.oneOf(['zh-CN', 'en-US']), }; interface GlobalConfigOptions { /** * 使用的 i18nBundle 名称 */ i18nBundleName?: I18nBundlesNames; } interface GlobalHocOption extends GlobalConfigOptions { /** * 转换函数 */ transform?: (props: any) => any; } export const useGlobal = (options?: GlobalConfigOptions) => { const localeContextValue = React.useContext(LocaleContext); const i18nBundle = useI18nBundle(options?.i18nBundleName); return React.useMemo( () => ({ ...localeContextValue, i18nBundle, }), [localeContextValue, i18nBundle], ); }; export function withGlobal( ReactComp: React.ComponentType>, options?: GlobalHocOption, ) { const { transform, ...others } = options; const Comp = React.forwardRef((props, ref) => { const globalConfig = useGlobal(others); const newProps = transform ? transform(props) : props; const componentProps = { language: globalConfig.language, i18nBundle: globalConfig.i18nBundle, ...newProps, ref, }; return ; }); hoistNonReactStatics(Comp, ReactComp); // 由于 displayName 在 React 属性中,不会被 hoistNonReactStatics 复制,需要单独处理 Comp.displayName = ReactComp.displayName; return Comp; } export function withBizGlobal( ReactComp: React.ComponentType>, options?: { i18nBundles: any; }, ) { const { i18nBundles = {} } = options; const Comp = React.forwardRef((props, ref) => { const language = useLanguage(); let i18nBundle = {}; if (language === 'en-US') { i18nBundle = { ...i18nBundles['zh-CN'], ...i18nBundles['en-US'], }; } else { i18nBundle = i18nBundles['zh-CN']; } const componentProps = { language, i18nBundle, ...props, ref, }; return ; }); hoistNonReactStatics(Comp, ReactComp); // 由于 displayName 在 React 属性中,不会被 hoistNonReactStatics 复制,需要单独处理 Comp.displayName = ReactComp.displayName; return Comp; } ================================================ FILE: packages/fusion-ui/src/types/dataSource.ts ================================================ export type DefaultLabel = string | number | boolean; export type DefaultValue = string | number | boolean; type DefaultKey = string | number; export interface DataSourceNode