├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .github ├── CONTRIBUTING.md ├── FUNDING.yml ├── GIT_COMMIT_SPECIFIC.md ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── config.yml ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── check-pr-title.yml │ ├── ci.yml │ ├── commitlint.yml │ ├── package-size.yml │ └── pr-welcome.yml ├── .gitignore ├── .npmrc ├── .prettierrc.js ├── .travis.yml ├── .vscode ├── cspell.json └── settings.json ├── CHANGELOG.md ├── LICENSE ├── README.md ├── examples-vue ├── playground │ ├── .eslintrc │ ├── .npmignore │ ├── LICENSE.md │ ├── README.md │ ├── index.html │ ├── package.json │ ├── src │ │ ├── main.tsx │ │ └── widgets │ │ │ ├── ContentWidget │ │ │ ├── index.tsx │ │ │ └── styles.less │ │ │ └── index.tsx │ ├── tsconfig.build.json │ ├── tsconfig.json │ └── vite.config.ts ├── react │ ├── .eslintrc │ ├── .npmignore │ ├── LICENSE.md │ ├── README.md │ ├── index.html │ ├── package.json │ ├── src │ │ ├── app.tsx │ │ ├── index.ts │ │ └── widgets │ │ │ ├── SchemaEditorWidget.tsx │ │ │ └── index.ts │ ├── tsconfig.build.json │ └── tsconfig.json └── vue │ ├── .eslintrc │ ├── .npmignore │ ├── LICENSE.md │ ├── README.md │ ├── index.html │ ├── package.json │ ├── src │ ├── components │ │ ├── card.tsx │ │ ├── card.vue │ │ ├── field.vue │ │ ├── index.ts │ │ └── style.less │ ├── index.ts │ └── sources │ │ ├── card.ts │ │ ├── field.ts │ │ └── index.ts │ ├── tsconfig.build.json │ └── tsconfig.json ├── examples ├── .eslintrc ├── basic │ ├── .npmignore │ ├── LICENSE.md │ ├── README.md │ ├── index.html │ ├── package.json │ ├── src │ │ ├── content.tsx │ │ ├── main.tsx │ │ └── sandbox.tsx │ ├── tsconfig.build.json │ ├── tsconfig.json │ └── vite.config.ts ├── multi-workspace │ ├── .npmignore │ ├── LICENSE.md │ ├── README.md │ ├── index.html │ ├── package.json │ ├── src │ │ ├── content.tsx │ │ └── main.tsx │ ├── tsconfig.build.json │ ├── tsconfig.json │ └── vite.config.ts ├── sandbox-multi-workspace │ ├── .npmignore │ ├── LICENSE.md │ ├── README.md │ ├── index.html │ ├── package.json │ ├── src │ │ ├── content.tsx │ │ ├── env │ │ │ ├── designable.ts │ │ │ ├── formily.ts │ │ │ └── index.ts │ │ ├── main.tsx │ │ └── sandbox.tsx │ ├── tsconfig.build.json │ ├── tsconfig.json │ ├── vite.config.ts │ └── vite.sandbox.ts └── sandbox │ ├── .npmignore │ ├── LICENSE.md │ ├── README.md │ ├── index.html │ ├── package.json │ ├── src │ ├── content.tsx │ ├── env │ │ ├── designable.ts │ │ ├── formily.ts │ │ └── index.ts │ ├── main.tsx │ └── sandbox.tsx │ ├── tsconfig.build.json │ ├── tsconfig.json │ ├── vite.config.ts │ └── vite.sandbox.ts ├── formily ├── .eslintrc ├── antd │ ├── .npmignore │ ├── LICENSE.md │ ├── README.md │ ├── copy.ts │ ├── index.html │ ├── package.json │ ├── playground │ │ ├── main.tsx │ │ ├── service │ │ │ ├── index.ts │ │ │ └── schema.ts │ │ ├── style.less │ │ ├── tsconfig.json │ │ ├── vite.config.ts │ │ └── widgets │ │ │ ├── ActionsWidget.tsx │ │ │ ├── LogoWidget.tsx │ │ │ ├── MarkupSchemaWidget.tsx │ │ │ ├── PreviewWidget │ │ │ ├── components.tsx │ │ │ └── index.tsx │ │ │ ├── SchemaEditorWidget.tsx │ │ │ └── index.ts │ ├── src │ │ ├── common │ │ │ ├── Container │ │ │ │ ├── index.tsx │ │ │ │ └── styles.less │ │ │ ├── FormItemSwitcher │ │ │ │ └── index.tsx │ │ │ └── LoadTemplate │ │ │ │ └── index.tsx │ │ ├── components │ │ │ ├── ArrayBase │ │ │ │ └── index.ts │ │ │ ├── ArrayCards │ │ │ │ ├── index.ts │ │ │ │ ├── preview.tsx │ │ │ │ └── styles.less │ │ │ ├── ArrayTable │ │ │ │ ├── index.ts │ │ │ │ ├── preview.tsx │ │ │ │ └── styles.less │ │ │ ├── Card │ │ │ │ ├── index.ts │ │ │ │ └── preview.tsx │ │ │ ├── Cascader │ │ │ │ ├── index.ts │ │ │ │ └── preview.tsx │ │ │ ├── Checkbox │ │ │ │ ├── index.ts │ │ │ │ └── preview.tsx │ │ │ ├── DatePicker │ │ │ │ ├── index.ts │ │ │ │ └── preview.tsx │ │ │ ├── Field │ │ │ │ ├── index.ts │ │ │ │ ├── preview.tsx │ │ │ │ └── shared.ts │ │ │ ├── Form │ │ │ │ ├── index.tsx │ │ │ │ ├── preview.tsx │ │ │ │ └── styles.less │ │ │ ├── FormCollapse │ │ │ │ ├── index.ts │ │ │ │ └── preview.tsx │ │ │ ├── FormGrid │ │ │ │ ├── index.ts │ │ │ │ ├── preview.tsx │ │ │ │ └── styles.less │ │ │ ├── FormLayout │ │ │ │ ├── index.ts │ │ │ │ └── preview.ts │ │ │ ├── FormTab │ │ │ │ ├── index.ts │ │ │ │ └── preview.tsx │ │ │ ├── Input │ │ │ │ ├── index.ts │ │ │ │ └── preview.ts │ │ │ ├── NumberPicker │ │ │ │ ├── index.ts │ │ │ │ └── preview.ts │ │ │ ├── Object │ │ │ │ ├── index.ts │ │ │ │ └── preview.tsx │ │ │ ├── Password │ │ │ │ ├── index.ts │ │ │ │ └── preview.tsx │ │ │ ├── Radio │ │ │ │ ├── index.ts │ │ │ │ └── preview.tsx │ │ │ ├── Rate │ │ │ │ ├── index.ts │ │ │ │ └── preview.tsx │ │ │ ├── Select │ │ │ │ ├── index.ts │ │ │ │ └── preview.tsx │ │ │ ├── Slider │ │ │ │ ├── index.ts │ │ │ │ └── preview.tsx │ │ │ ├── Space │ │ │ │ ├── index.ts │ │ │ │ └── preview.tsx │ │ │ ├── Switch │ │ │ │ ├── index.ts │ │ │ │ └── preview.tsx │ │ │ ├── Text │ │ │ │ ├── index.ts │ │ │ │ ├── preview.tsx │ │ │ │ └── styles.less │ │ │ ├── TimePicker │ │ │ │ ├── index.ts │ │ │ │ └── preview.tsx │ │ │ ├── Transfer │ │ │ │ ├── index.ts │ │ │ │ └── preview.tsx │ │ │ ├── TreeSelect │ │ │ │ ├── index.ts │ │ │ │ └── preview.tsx │ │ │ ├── Upload │ │ │ │ ├── index.ts │ │ │ │ └── preview.tsx │ │ │ └── index.ts │ │ ├── hooks │ │ │ ├── index.ts │ │ │ └── useDropTemplate.ts │ │ ├── index.ts │ │ ├── locales │ │ │ ├── ArrayBase.ts │ │ │ ├── ArrayCards.ts │ │ │ ├── ArrayTable.ts │ │ │ ├── Card.ts │ │ │ ├── Cascader.ts │ │ │ ├── Checkbox.ts │ │ │ ├── Component.ts │ │ │ ├── DatePicker.ts │ │ │ ├── Field.ts │ │ │ ├── Form.ts │ │ │ ├── FormCollapse.ts │ │ │ ├── FormGrid.ts │ │ │ ├── FormLayout.ts │ │ │ ├── FormTab.ts │ │ │ ├── Input.ts │ │ │ ├── NumberPicker.ts │ │ │ ├── Object.ts │ │ │ ├── Password.ts │ │ │ ├── Radio.ts │ │ │ ├── Rate.ts │ │ │ ├── Select.ts │ │ │ ├── Slider.ts │ │ │ ├── Space.ts │ │ │ ├── Switch.ts │ │ │ ├── Text.ts │ │ │ ├── TextArea.ts │ │ │ ├── TimePicker.ts │ │ │ ├── Transfer.ts │ │ │ ├── TreeSelect.ts │ │ │ ├── Upload.ts │ │ │ ├── Void.ts │ │ │ ├── all.ts │ │ │ └── index.ts │ │ ├── schemas │ │ │ ├── ArrayCards.ts │ │ │ ├── ArrayTable.ts │ │ │ ├── CSSStyle.ts │ │ │ ├── Card.ts │ │ │ ├── Cascader.ts │ │ │ ├── Checkbox.ts │ │ │ ├── DatePicker.ts │ │ │ ├── Form.ts │ │ │ ├── FormCollapse.ts │ │ │ ├── FormGrid.ts │ │ │ ├── FormItem.ts │ │ │ ├── FormLayout.ts │ │ │ ├── FormTab.ts │ │ │ ├── Input.ts │ │ │ ├── NumberPicker.ts │ │ │ ├── Password.ts │ │ │ ├── Radio.ts │ │ │ ├── Rate.ts │ │ │ ├── Select.ts │ │ │ ├── Slider.ts │ │ │ ├── Space.ts │ │ │ ├── Switch.ts │ │ │ ├── Text.ts │ │ │ ├── TimePicker.ts │ │ │ ├── Transfer.ts │ │ │ ├── TreeSelect.ts │ │ │ ├── Upload.ts │ │ │ ├── all.ts │ │ │ └── index.ts │ │ ├── shared.ts │ │ └── sources.ts │ ├── tsconfig.build.json │ └── tsconfig.json ├── setters │ ├── .npmignore │ ├── LICENSE.md │ ├── README.md │ ├── copy.ts │ ├── package.json │ ├── src │ │ ├── components │ │ │ ├── DataSourceSetter │ │ │ │ ├── DataSettingPanel.tsx │ │ │ │ ├── Header.tsx │ │ │ │ ├── Title.tsx │ │ │ │ ├── TreePanel.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── shared.ts │ │ │ │ ├── styles.less │ │ │ │ └── types.ts │ │ │ ├── ReactionsSetter │ │ │ │ ├── FieldPropertySetter.tsx │ │ │ │ ├── PathSelector.tsx │ │ │ │ ├── declarations.ts │ │ │ │ ├── helpers.ts │ │ │ │ ├── index.tsx │ │ │ │ ├── properties.ts │ │ │ │ ├── styles.less │ │ │ │ └── types.ts │ │ │ ├── ValidatorSetter │ │ │ │ └── index.tsx │ │ │ └── index.ts │ │ ├── index.ts │ │ └── locales │ │ │ ├── en-US.ts │ │ │ ├── index.ts │ │ │ ├── ko-KR.ts │ │ │ └── zh-CN.ts │ ├── tsconfig.build.json │ └── tsconfig.json └── transformer │ ├── .npmignore │ ├── LICENSE.md │ ├── README.md │ ├── package.json │ ├── rollup.config.js │ ├── src │ └── index.ts │ ├── tsconfig.build.json │ └── tsconfig.json ├── jest.config.js ├── lerna.json ├── package.json ├── packages ├── .eslintrc ├── core │ ├── .npmignore │ ├── LICENSE.md │ ├── README.md │ ├── package.json │ ├── rollup.config.js │ ├── src │ │ ├── drivers │ │ │ ├── DragDropDriver.ts │ │ │ ├── KeyboardDriver.ts │ │ │ ├── MouseClickDriver.ts │ │ │ ├── MouseMoveDriver.ts │ │ │ ├── ViewportResizeDriver.ts │ │ │ ├── ViewportScrollDriver.ts │ │ │ └── index.ts │ │ ├── effects │ │ │ ├── index.ts │ │ │ ├── useAutoScrollEffect.ts │ │ │ ├── useContentEditableEffect.ts │ │ │ ├── useCursorEffect.ts │ │ │ ├── useDragDropEffect.ts │ │ │ ├── useFreeSelectionEffect.ts │ │ │ ├── useKeyboardEffect.ts │ │ │ ├── useResizeEffect.ts │ │ │ ├── useSelectionEffect.ts │ │ │ ├── useTranslateEffect.ts │ │ │ ├── useViewportEffect.ts │ │ │ └── useWorkspaceEffect.ts │ │ ├── events │ │ │ ├── cursor │ │ │ │ ├── AbstractCursorEvent.ts │ │ │ │ ├── DragMoveEvent.ts │ │ │ │ ├── DragStartEvent.ts │ │ │ │ ├── DragStopEvent.ts │ │ │ │ ├── MouseClickEvent.ts │ │ │ │ ├── MouseMoveEvent.ts │ │ │ │ └── index.ts │ │ │ ├── history │ │ │ │ ├── AbstractHistoryEvent.ts │ │ │ │ ├── HistoryGotoEvent.ts │ │ │ │ ├── HistoryPushEvent.ts │ │ │ │ ├── HistoryRedoEvent.ts │ │ │ │ ├── HistoryUndoEvent.ts │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ ├── keyboard │ │ │ │ ├── AbstractKeyboardEvent.ts │ │ │ │ ├── KeyDownEvent.ts │ │ │ │ ├── KeyUpEvent.ts │ │ │ │ └── index.ts │ │ │ ├── mutation │ │ │ │ ├── AbstractMutationNodeEvent.ts │ │ │ │ ├── AppendNodeEvent.ts │ │ │ │ ├── CloneNodeEvent.ts │ │ │ │ ├── DragNodeEvent.ts │ │ │ │ ├── DropNodeEvent.ts │ │ │ │ ├── FromNodeEvent.ts │ │ │ │ ├── HoverNodeEvent.ts │ │ │ │ ├── InsertAfterEvent.ts │ │ │ │ ├── InsertBeforeEvent.ts │ │ │ │ ├── InsertChildrenEvent.ts │ │ │ │ ├── PrependNodeEvent.ts │ │ │ │ ├── RemoveNodeEvent.ts │ │ │ │ ├── SelectNodeEvent.ts │ │ │ │ ├── UnSelectNodeEvent.ts │ │ │ │ ├── UpdateChildrenEvent.ts │ │ │ │ ├── UpdateNodePropsEvent.ts │ │ │ │ ├── UserSelectNodeEvent.ts │ │ │ │ ├── WrapNodeEvent.ts │ │ │ │ └── index.ts │ │ │ ├── viewport │ │ │ │ ├── AbstractViewportEvent.ts │ │ │ │ ├── ViewportResizeEvent.ts │ │ │ │ ├── ViewportScrollEvent.ts │ │ │ │ └── index.ts │ │ │ └── workbench │ │ │ │ ├── AbstractWorkspaceEvent.ts │ │ │ │ ├── AddWorkspaceEvent.ts │ │ │ │ ├── RemoveWorkspaceEvent.ts │ │ │ │ ├── SwitchWorkspaceEvent.ts │ │ │ │ └── index.ts │ │ ├── exports.ts │ │ ├── externals.ts │ │ ├── index.ts │ │ ├── internals.ts │ │ ├── models │ │ │ ├── Cursor.ts │ │ │ ├── Engine.ts │ │ │ ├── History.ts │ │ │ ├── Hover.ts │ │ │ ├── Keyboard.ts │ │ │ ├── MoveHelper.ts │ │ │ ├── Operation.ts │ │ │ ├── Screen.ts │ │ │ ├── Selection.ts │ │ │ ├── Shortcut.ts │ │ │ ├── SnapLine.ts │ │ │ ├── SpaceBlock.ts │ │ │ ├── TransformHelper.ts │ │ │ ├── TreeNode.ts │ │ │ ├── Viewport.ts │ │ │ ├── Workbench.ts │ │ │ ├── Workspace.ts │ │ │ └── index.ts │ │ ├── presets.ts │ │ ├── registry.ts │ │ ├── shortcuts │ │ │ ├── CursorSwitch.ts │ │ │ ├── MultiSelection.ts │ │ │ ├── NodeMutation.ts │ │ │ ├── QuickSelection.ts │ │ │ ├── UndoRedo.ts │ │ │ └── index.ts │ │ └── types.ts │ ├── tsconfig.build.json │ └── tsconfig.json ├── react-sandbox │ ├── .npmignore │ ├── LICENSE.md │ ├── README.md │ ├── package.json │ ├── rollup.config.js │ ├── src │ │ ├── components │ │ │ ├── Sandbox.tsx │ │ │ └── index.ts │ │ ├── hooks │ │ │ ├── index.ts │ │ │ ├── useSandbox.ts │ │ │ └── useSandboxScope.ts │ │ ├── index.ts │ │ └── shared │ │ │ └── index.ts │ ├── tsconfig.build.json │ └── tsconfig.json ├── react-settings-form │ ├── .npmignore │ ├── LICENSE.md │ ├── README.md │ ├── copy.ts │ ├── package.json │ ├── rollup.config.js │ ├── src │ │ ├── SchemaField.tsx │ │ ├── SettingsForm.tsx │ │ ├── components │ │ │ ├── BackgroundStyleSetter │ │ │ │ └── index.tsx │ │ │ ├── BorderRadiusStyleSetter │ │ │ │ └── index.tsx │ │ │ ├── BorderStyleSetter │ │ │ │ ├── index.tsx │ │ │ │ └── styles.less │ │ │ ├── BoxShadowStyleSetter │ │ │ │ └── index.tsx │ │ │ ├── BoxStyleSetter │ │ │ │ └── index.tsx │ │ │ ├── CollapseItem │ │ │ │ ├── index.tsx │ │ │ │ └── styles.less │ │ │ ├── ColorInput │ │ │ │ ├── index.tsx │ │ │ │ └── styles.less │ │ │ ├── CornerInput │ │ │ │ ├── index.tsx │ │ │ │ └── styles.less │ │ │ ├── DisplayStyleSetter │ │ │ │ ├── index.tsx │ │ │ │ └── styles.less │ │ │ ├── DrawerSetter │ │ │ │ ├── index.tsx │ │ │ │ └── styles.less │ │ │ ├── FlexStyleSetter │ │ │ │ ├── index.tsx │ │ │ │ └── styles.less │ │ │ ├── FoldItem │ │ │ │ ├── index.tsx │ │ │ │ └── styles.less │ │ │ ├── FontStyleSetter │ │ │ │ └── index.tsx │ │ │ ├── ImageInput │ │ │ │ ├── index.tsx │ │ │ │ └── styles.less │ │ │ ├── InputItems │ │ │ │ ├── index.tsx │ │ │ │ └── styles.less │ │ │ ├── MonacoInput │ │ │ │ ├── config.ts │ │ │ │ ├── format.ts │ │ │ │ ├── index.tsx │ │ │ │ ├── styles.less │ │ │ │ └── themes │ │ │ │ │ ├── chrome.ts │ │ │ │ │ └── monokai.ts │ │ │ ├── PolyInput │ │ │ │ ├── index.tsx │ │ │ │ └── styles.less │ │ │ ├── PositionInput │ │ │ │ ├── index.tsx │ │ │ │ └── styles.less │ │ │ ├── SizeInput │ │ │ │ ├── index.tsx │ │ │ │ └── styles.less │ │ │ ├── ValueInput │ │ │ │ ├── index.tsx │ │ │ │ └── styles.less │ │ │ └── index.ts │ │ ├── effects │ │ │ ├── index.ts │ │ │ ├── useLocales.tsx │ │ │ └── useSnapshot.tsx │ │ ├── index.ts │ │ ├── locales │ │ │ ├── en-US.ts │ │ │ ├── index.ts │ │ │ ├── ko-KR.ts │ │ │ └── zh-CN.ts │ │ ├── registry.ts │ │ ├── shared │ │ │ ├── context.ts │ │ │ └── loadScript.ts │ │ ├── styles.less │ │ └── types.ts │ ├── tsconfig.build.json │ └── tsconfig.json ├── react │ ├── .npmignore │ ├── LICENSE.md │ ├── README.md │ ├── copy.ts │ ├── package.json │ ├── rollup.config.js │ ├── src │ │ ├── containers │ │ │ ├── Designer.tsx │ │ │ ├── Layout.tsx │ │ │ ├── Simulator.tsx │ │ │ ├── Viewport.tsx │ │ │ ├── Workbench.tsx │ │ │ ├── Workspace.tsx │ │ │ ├── index.ts │ │ │ └── styles.less │ │ ├── context.ts │ │ ├── hooks │ │ │ ├── index.ts │ │ │ ├── useComponents.ts │ │ │ ├── useCursor.ts │ │ │ ├── useDesigner.ts │ │ │ ├── useHistory.ts │ │ │ ├── useHover.ts │ │ │ ├── useLayout.ts │ │ │ ├── useMoveHelper.ts │ │ │ ├── useNodeIdProps.ts │ │ │ ├── useOperation.ts │ │ │ ├── useOutline.ts │ │ │ ├── usePosition.ts │ │ │ ├── usePrefix.ts │ │ │ ├── useRegistry.ts │ │ │ ├── useScreen.ts │ │ │ ├── useSelected.ts │ │ │ ├── useSelectedNode.ts │ │ │ ├── useSelection.ts │ │ │ ├── useTheme.ts │ │ │ ├── useTransformHelper.ts │ │ │ ├── useTree.ts │ │ │ ├── useTreeNode.ts │ │ │ ├── useValidNodeOffsetRect.ts │ │ │ ├── useViewport.ts │ │ │ ├── useWorkbench.ts │ │ │ └── useWorkspace.ts │ │ ├── icons │ │ │ ├── actions.tsx │ │ │ ├── add.tsx │ │ │ ├── animations.tsx │ │ │ ├── boolean.tsx │ │ │ ├── clone.tsx │ │ │ ├── close.tsx │ │ │ ├── code.tsx │ │ │ ├── command.tsx │ │ │ ├── component.tsx │ │ │ ├── container.tsx │ │ │ ├── corner.tsx │ │ │ ├── delete.tsx │ │ │ ├── design.tsx │ │ │ ├── display.tsx │ │ │ ├── dragmove.tsx │ │ │ ├── expand.tsx │ │ │ ├── expression.tsx │ │ │ ├── eyes.tsx │ │ │ ├── flex.tsx │ │ │ ├── flip.tsx │ │ │ ├── focus.tsx │ │ │ ├── font.tsx │ │ │ ├── formula.tsx │ │ │ ├── freemove.tsx │ │ │ ├── help.tsx │ │ │ ├── hidden.tsx │ │ │ ├── history.tsx │ │ │ ├── image.tsx │ │ │ ├── index.ts │ │ │ ├── json.tsx │ │ │ ├── logo.tsx │ │ │ ├── menu.tsx │ │ │ ├── mobile.tsx │ │ │ ├── move.tsx │ │ │ ├── number.tsx │ │ │ ├── outline.tsx │ │ │ ├── page.tsx │ │ │ ├── pc.tsx │ │ │ ├── play.tsx │ │ │ ├── position.tsx │ │ │ ├── pushpin.tsx │ │ │ ├── recover.tsx │ │ │ ├── redo.tsx │ │ │ ├── remove.tsx │ │ │ ├── responsive.tsx │ │ │ ├── return.tsx │ │ │ ├── selection.tsx │ │ │ ├── setting.tsx │ │ │ ├── shadow.tsx │ │ │ ├── shift.tsx │ │ │ ├── sources.tsx │ │ │ ├── text.tsx │ │ │ ├── undo.tsx │ │ │ └── upload.tsx │ │ ├── index.ts │ │ ├── locales │ │ │ ├── global.ts │ │ │ ├── icons.ts │ │ │ ├── index.ts │ │ │ ├── operations.ts │ │ │ └── panels.ts │ │ ├── panels │ │ │ ├── CompositePanel.tsx │ │ │ ├── SettingsPanel.tsx │ │ │ ├── StudioPanel.tsx │ │ │ ├── ToolbarPanel.tsx │ │ │ ├── ViewPanel.tsx │ │ │ ├── ViewportPanel.tsx │ │ │ ├── WorkspacePanel.tsx │ │ │ ├── index.ts │ │ │ └── styles.less │ │ ├── simulators │ │ │ ├── MobileSimulator │ │ │ │ ├── body.tsx │ │ │ │ ├── index.tsx │ │ │ │ └── styles.less │ │ │ ├── PCSimulator │ │ │ │ ├── index.tsx │ │ │ │ └── styles.less │ │ │ ├── ResponsiveSimulator │ │ │ │ ├── handle.tsx │ │ │ │ ├── index.tsx │ │ │ │ └── styles.less │ │ │ └── index.tsx │ │ ├── theme.less │ │ ├── types.ts │ │ ├── variables.less │ │ └── widgets │ │ │ ├── AuxToolWidget │ │ │ ├── Copy.tsx │ │ │ ├── Cover.tsx │ │ │ ├── DashedBox.tsx │ │ │ ├── Delete.tsx │ │ │ ├── DragHandler.tsx │ │ │ ├── FreeSelection.tsx │ │ │ ├── Helpers.tsx │ │ │ ├── Insertion.tsx │ │ │ ├── ResizeHandler.tsx │ │ │ ├── Selection.tsx │ │ │ ├── Selector.tsx │ │ │ ├── SnapLine.tsx │ │ │ ├── SpaceBlock.tsx │ │ │ ├── TranslateHandler.tsx │ │ │ ├── index.tsx │ │ │ └── styles.less │ │ │ ├── ComponentTreeWidget │ │ │ ├── index.tsx │ │ │ └── styles.less │ │ │ ├── DesignerToolsWidget │ │ │ ├── index.tsx │ │ │ └── styles.less │ │ │ ├── DroppableWidget │ │ │ ├── index.tsx │ │ │ └── styles.less │ │ │ ├── EmptyWidget │ │ │ ├── index.tsx │ │ │ └── styles.less │ │ │ ├── GhostWidget │ │ │ ├── index.tsx │ │ │ └── styles.less │ │ │ ├── HistoryWidget │ │ │ ├── index.tsx │ │ │ └── styles.less │ │ │ ├── IconWidget │ │ │ ├── index.tsx │ │ │ └── styles.less │ │ │ ├── NodeActionsWidget │ │ │ ├── index.tsx │ │ │ └── styles.less │ │ │ ├── NodePathWidget │ │ │ ├── index.tsx │ │ │ └── styles.less │ │ │ ├── NodeTitleWidget │ │ │ └── index.tsx │ │ │ ├── OutlineWidget │ │ │ ├── Insertion.tsx │ │ │ ├── OutlineNode.tsx │ │ │ ├── context.ts │ │ │ ├── index.tsx │ │ │ └── styles.less │ │ │ ├── ResourceListWidget │ │ │ └── index.tsx │ │ │ ├── ResourceWidget │ │ │ ├── index.tsx │ │ │ └── styles.less │ │ │ ├── TextWidget │ │ │ └── index.tsx │ │ │ ├── ViewToolsWidget │ │ │ └── index.tsx │ │ │ └── index.ts │ ├── tsconfig.build.json │ └── tsconfig.json ├── shared │ ├── .npmignore │ ├── LICENSE.md │ ├── README.md │ ├── package.json │ ├── rollup.config.js │ ├── src │ │ ├── animation.ts │ │ ├── array.ts │ │ ├── clone.ts │ │ ├── compose.ts │ │ ├── coordinate.ts │ │ ├── element.ts │ │ ├── event.ts │ │ ├── globalThisPolyfill.ts │ │ ├── index.ts │ │ ├── instanceof.ts │ │ ├── keycode.ts │ │ ├── lru.ts │ │ ├── observer.ts │ │ ├── request-idle.ts │ │ ├── scroller.ts │ │ ├── subscribable.ts │ │ ├── types.ts │ │ └── uid.ts │ ├── tsconfig.build.json │ └── tsconfig.json └── vue │ ├── .npmignore │ ├── LICENSE.md │ ├── README.md │ ├── copy.ts │ ├── package.json │ ├── rollup.config.js │ ├── src │ ├── context.ts │ ├── hooks │ │ ├── index.ts │ │ ├── useComponents.ts │ │ ├── useDesigner.ts │ │ ├── usePrefix.ts │ │ └── useTreeNode.ts │ ├── index.ts │ ├── types.ts │ └── widgets │ │ ├── ComponentTreeWidget │ │ └── index.tsx │ │ └── index.ts │ ├── tsconfig.build.json │ └── tsconfig.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── scripts ├── build-style │ ├── buildAllStyles.ts │ ├── buildStyle.ts │ ├── copy.ts │ ├── helper.ts │ └── index.ts ├── global.ts ├── jest.base.js ├── release │ ├── git.ts │ └── index.ts ├── rollup.base.js └── validate-commit-msg.js ├── tsconfig.build.json ├── tsconfig.jest.json └── tsconfig.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | indent_style = space 11 | indent_size = 2 12 | 13 | [*.gradle] 14 | indent_size = 4 -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | lib 3 | dist 4 | build 5 | coverage 6 | expected 7 | website 8 | gh-pages 9 | weex 10 | build.ts 11 | docs 12 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | ko_fi: # Replace with a single Ko-fi username 6 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 7 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 8 | liberapay: # Replace with a single Liberapay username 9 | issuehunt: # Replace with a single IssueHunt username 10 | otechie: # Replace with a single Otechie username 11 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '[Bug Report]' 5 | --- 6 | 7 | - [x] I have searched the [issues](https://github.com/pindjs/designable/issues) of this repository and believe that this is not a duplicate. 8 | 9 | ### Reproduction link 10 | 11 | ### Steps to reproduce 12 | 13 | ### What is expected? 14 | 15 | ### What is actually happening? 16 | 17 | ### Package 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | contact_links: 3 | - name: ✨ Question Answer / Idea 4 | url: https://github.com/pindjs/designable/discussions/new 5 | about: All questions can be solved here. At the same time you can provide all your ideas here. 6 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | _Before_ submitting a pull request, please make sure the following is done... 2 | 3 | - [ ] Ensure the pull request title and commit message follow the [Commit Specific](https://github.com/pindjs/designable/blob/main/.github/GIT_COMMIT_SPECIFIC.md) in **English**. 4 | - [ ] Fork the repo and create your branch from `main`. 5 | - [ ] If you've added code that should be tested, add tests! 6 | - [ ] If you've changed APIs, update the documentation. 7 | - [ ] Ensure the test suite passes (`npm test`). 8 | - [ ] Make sure your code lints (`npm run lint`) - we've done our best to make sure these rules match our internal linting guidelines. 9 | -------------------------------------------------------------------------------- /.github/workflows/check-pr-title.yml: -------------------------------------------------------------------------------- 1 | name: Check PR title 2 | on: 3 | pull_request_target: 4 | types: 5 | - opened 6 | - reopened 7 | - edited 8 | - synchronize 9 | 10 | jobs: 11 | lint: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: aslafy-z/conventional-pr-title-action@master 15 | with: 16 | preset: conventional-changelog-angular@^5.0.6 17 | env: 18 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 19 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Node CI 2 | 3 | # on: 4 | # push: 5 | # branches: 6 | # - main 7 | # pull_request: 8 | # branches: 9 | # - main 10 | 11 | # jobs: 12 | # build: 13 | # runs-on: ${{ matrix.os }} 14 | # strategy: 15 | # matrix: 16 | # node_version: [10.x, 11.x] 17 | # os: [ubuntu-latest] 18 | # steps: 19 | # - uses: actions/checkout@v1 20 | # - name: Use Node.js ${{ matrix.node_version }} 21 | # uses: actions/setup-node@v1 22 | # with: 23 | # node-version: ${{ matrix.node_version }} 24 | 25 | # - run: yarn -v 26 | # - run: yarn --ignore-engines 27 | # - run: yarn build 28 | # - run: yarn test:prod 29 | # env: 30 | # CI: true 31 | # HEADLESS: false 32 | # PROGRESS: none 33 | # NODE_ENV: test 34 | # NODE_OPTIONS: --max_old_space_size=4096 35 | 36 | # - name: Upload coverage to Codecov 37 | # uses: codecov/codecov-action@v1 38 | # with: 39 | # token: ${{ secrets.CODECOV_TOKEN }} 40 | -------------------------------------------------------------------------------- /.github/workflows/commitlint.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: Check Commit spec 4 | 5 | # Controls when the action will run. 6 | on: 7 | # Triggers the workflow on push or pull request events but only for the main branch 8 | push: 9 | branches: [main] 10 | pull_request: 11 | branches: [main] 12 | 13 | # Allows you to run this workflow manually from the Actions tab 14 | workflow_dispatch: 15 | 16 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 17 | jobs: 18 | # This workflow contains a single job called "build" 19 | commitlint: 20 | # The type of runner that the job will run on 21 | runs-on: ubuntu-latest 22 | 23 | # Steps represent a sequence of tasks that will be executed as part of the job 24 | steps: 25 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 26 | - uses: actions/checkout@v2 27 | with: 28 | fetch-depth: 0= 29 | - uses: wagoid/commitlint-github-action@v3 30 | -------------------------------------------------------------------------------- /.github/workflows/package-size.yml: -------------------------------------------------------------------------------- 1 | name: Compressed Size 2 | 3 | on: [pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v2 11 | - uses: preactjs/compressed-size-action@v2 12 | with: 13 | repo-token: '${{ secrets.GITHUB_TOKEN }}' 14 | -------------------------------------------------------------------------------- /.github/workflows/pr-welcome.yml: -------------------------------------------------------------------------------- 1 | name: PR Welcome 2 | 3 | on: 4 | pull_request_target: 5 | types: [opened] 6 | 7 | jobs: 8 | welcome: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions-cool/pr-welcome@v1.1.2 12 | with: 13 | pr-emoji: '+1, heart' 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.swp 3 | .DS_Store 4 | .tea 5 | npm-debug.log 6 | lerna-debug.log 7 | npm-debug.log* 8 | package-lock.json 9 | lib/ 10 | esm/ 11 | temp_esm/ 12 | dist/ 13 | build/ 14 | coverage/ 15 | node_modules/ 16 | examples/test 17 | .idea/ 18 | TODO.md 19 | tsconfig.tsbuildinfo 20 | package/ 21 | benchmark 22 | package.zip 23 | .umi 24 | .umi-production 25 | .cjsescache 26 | doc-site 27 | .lerna-changelog -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npmmirror.com/ 2 | auto-install-peers=true 3 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | semi: false, 3 | tabWidth: 2, 4 | singleQuote: true, 5 | } 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | 3 | language: node_js 4 | 5 | before_install: 6 | - npm i -g npm@6 7 | 8 | node_js: 9 | - '8' 10 | - '11' 11 | 12 | before_script: 13 | - rm -rf node_modules 14 | - npm install 15 | - lerna clean --yes 16 | - lerna bootstrap --no-ci 17 | 18 | script: 19 | - npm run lint 20 | - npm run build 21 | -------------------------------------------------------------------------------- /.vscode/cspell.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.1", 3 | "language": "en", 4 | "ignoreWords": [ 5 | "autorun", 6 | "mutators", 7 | "Formily", 8 | "formily", 9 | "untrack", 10 | "untracker", 11 | "untracked", 12 | "Untracking", 13 | "cloneable", 14 | "deletable", 15 | "Unmount", 16 | "octokit", 17 | "repos", 18 | "alibaba", 19 | "Lifecycles", 20 | "antd", 21 | "Antd", 22 | "alifd", 23 | "Mixins", 24 | "builtins", 25 | "cascader", 26 | "Cascader", 27 | "middlewares", 28 | "contenteditable", 29 | "compositionstart", 30 | "compositionupdate", 31 | "compositionend", 32 | "Roundable" 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib", 3 | "vue3snippets.enable-compile-vue-file-on-did-save-code": false 4 | } 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Alibaba 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 | --- 6 | 7 | ## Introduction 8 | 9 | If you are worrying about something builder, Such as form builder/table builder/chart builder/app builder etc. 10 | Designable is your perfect choice. 11 | 12 | ## Screenshot 13 | 14 | 15 | 16 | ## Features 17 | 18 | - 🚀 High performance, Smooth and beautiful drag and drop experience 19 | - 💡 Full scene coverage 20 | - 🎨 Support Low Code and No Code 21 | - 🏅 Strong scalability 22 | 23 | ## Website 24 | 25 | [playground](https://designable.netlify.app) 26 | 27 | ## Contributors 28 | 29 | This project exists thanks to all the people who contribute. 30 | 31 |

32 | 33 |

34 | -------------------------------------------------------------------------------- /examples-vue/playground/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | build 4 | __tests__ -------------------------------------------------------------------------------- /examples-vue/playground/README.md: -------------------------------------------------------------------------------- 1 | # Vue Playground 2 | 3 | 因为 vue 和 react 的类型干扰,建议使用 pnpm + Monarepo 进行代码管理 4 | -------------------------------------------------------------------------------- /examples-vue/playground/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | PIND 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples-vue/playground/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { createRoot } from 'react-dom/client' 2 | import { createElement } from 'react' 3 | import { App } from '@examples-vue/react' 4 | import { sources } from '@examples-vue/vue' 5 | import { ContentWidget } from './widgets' 6 | const container = document.getElementById('root') as HTMLElement 7 | const root = createRoot(container) 8 | root.render( 9 | createElement(App, { 10 | Content: () => 11 | createElement(ContentWidget, { 12 | components: { 13 | ...sources, 14 | }, 15 | }), 16 | sources: Object.values(sources), 17 | }) 18 | ) 19 | -------------------------------------------------------------------------------- /examples-vue/playground/src/widgets/ContentWidget/styles.less: -------------------------------------------------------------------------------- 1 | .dn-component-tree { 2 | height: 100%; 3 | min-height: 100%; 4 | min-width: 100%; 5 | max-width: 100%; 6 | max-height: 100%; 7 | } 8 | -------------------------------------------------------------------------------- /examples-vue/playground/src/widgets/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './ContentWidget' 2 | -------------------------------------------------------------------------------- /examples-vue/playground/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./lib", 5 | "paths": { 6 | "@pind/designable-*": ["../*"] 7 | }, 8 | "declaration": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples-vue/playground/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "include": ["./src/**/*.ts", "./src/**/*.tsx"], 4 | "exclude": ["./src/__tests__/*", "./esm/*", "./lib/*"] 5 | } 6 | -------------------------------------------------------------------------------- /examples-vue/react/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | build 4 | __tests__ -------------------------------------------------------------------------------- /examples-vue/react/README.md: -------------------------------------------------------------------------------- 1 | # @pind/designable-playground 2 | -------------------------------------------------------------------------------- /examples-vue/react/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | PIND 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples-vue/react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@examples-vue/react", 3 | "version": "2.0.0-beta.6", 4 | "license": "MIT", 5 | "private": true, 6 | "engines": { 7 | "npm": ">=3.0.0" 8 | }, 9 | "scripts": {}, 10 | "devDependencies": { 11 | "@types/react": "^18.0.26", 12 | "@types/react-dom": "^18.0.10", 13 | "@types/react-is": "^17.0.3", 14 | "typescript": "^4.9.5" 15 | }, 16 | "dependencies": { 17 | "@formily/antd-v5": "^1.0.1-rc.1", 18 | "@formily/core": "^2.2.16", 19 | "@formily/react": "^2.2.16", 20 | "@formily/reactive": "^2.2.16", 21 | "@formily/reactive-react": "^2.2.16", 22 | "@pind/designable-core": "workspace:2.0.0-beta.6", 23 | "@pind/designable-react": "workspace:2.0.0-beta.6", 24 | "@pind/designable-react-sandbox": "workspace:2.0.0-beta.6", 25 | "@pind/designable-react-settings-form": "workspace:2.0.0-beta.6", 26 | "@pind/designable-shared": "workspace:2.0.0-beta.6", 27 | "antd": "^5.1.2", 28 | "classnames": "^2.3.2", 29 | "react": "^18.2.0", 30 | "react-dom": "^18.2.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /examples-vue/react/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './app' 2 | -------------------------------------------------------------------------------- /examples-vue/react/src/widgets/SchemaEditorWidget.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { 3 | transformToSchema, 4 | transformToTreeNode, 5 | } from '@pind/designable-formily-transformer' 6 | import { TreeNode, ITreeNode } from '@pind/designable-core' 7 | import { MonacoInput } from '@pind/designable-react-settings-form' 8 | 9 | export interface ISchemaEditorWidgetProps { 10 | tree: TreeNode 11 | onChange?: (tree: ITreeNode) => void 12 | } 13 | 14 | export const SchemaEditorWidget: React.FC = ( 15 | props 16 | ) => { 17 | return ( 18 | { 22 | props.onChange?.(transformToTreeNode(JSON.parse(value))) 23 | }} 24 | language="json" 25 | /> 26 | ) 27 | } 28 | -------------------------------------------------------------------------------- /examples-vue/react/src/widgets/index.ts: -------------------------------------------------------------------------------- 1 | export * from './SchemaEditorWidget' 2 | -------------------------------------------------------------------------------- /examples-vue/react/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./lib", 5 | "paths": { 6 | "@pind/designable-*": ["../*"] 7 | }, 8 | "declaration": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples-vue/react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "include": ["./src/**/*.ts", "./src/**/*.tsx"], 4 | "exclude": ["./src/__tests__/*", "./esm/*", "./lib/*"] 5 | } 6 | -------------------------------------------------------------------------------- /examples-vue/vue/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | build 4 | __tests__ -------------------------------------------------------------------------------- /examples-vue/vue/README.md: -------------------------------------------------------------------------------- 1 | # @pind/designable-playground 2 | -------------------------------------------------------------------------------- /examples-vue/vue/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | PIND 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples-vue/vue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@examples-vue/vue", 3 | "version": "2.0.0-beta.6", 4 | "license": "MIT", 5 | "private": true, 6 | "engines": { 7 | "npm": ">=3.0.0" 8 | }, 9 | "scripts": { 10 | "start": "vite --host" 11 | }, 12 | "devDependencies": { 13 | "eslint": "^8.31.0", 14 | "typescript": "^4.9.5", 15 | "vue": "^3.2.0", 16 | "vue-eslint-parser": "^9.0.0" 17 | }, 18 | "dependencies": { 19 | "@formily/core": "^2.2.16", 20 | "@formily/reactive": "^2.2.16", 21 | "@formily/reactive-vue": "^2.2.16", 22 | "@formily/vue": "^2.2.16", 23 | "@pind/designable-core": "workspace:2.0.0-beta.6", 24 | "@pind/designable-shared": "workspace:2.0.0-beta.6", 25 | "@pind/designable-vue": "workspace:2.0.0-beta.6" 26 | }, 27 | "gitHead": "820790a9ae32c2348bb36b3de7ca5f1051ed392c" 28 | } 29 | -------------------------------------------------------------------------------- /examples-vue/vue/src/components/card.tsx: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue' 2 | import './style.less' 3 | 4 | export const Card = defineComponent({ 5 | name: 'Card', 6 | setup(_, { slots }) { 7 | return () => ( 8 |
9 | card 10 |
{slots.default?.()}
11 |
12 | ) 13 | }, 14 | }) 15 | -------------------------------------------------------------------------------- /examples-vue/vue/src/components/card.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | 23 | -------------------------------------------------------------------------------- /examples-vue/vue/src/components/field.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /examples-vue/vue/src/components/index.ts: -------------------------------------------------------------------------------- 1 | export { default as Field } from './field.vue' 2 | // export { default as Card } from './card.vue' 3 | 4 | export * from './card' 5 | -------------------------------------------------------------------------------- /examples-vue/vue/src/components/style.less: -------------------------------------------------------------------------------- 1 | .card { 2 | width: 200px; 3 | height: 100px; 4 | background: #eee; 5 | border: 1px solid #ddd; 6 | display: flex; 7 | padding: 10; 8 | justify-content: center; 9 | align-items: center; 10 | } 11 | -------------------------------------------------------------------------------- /examples-vue/vue/src/index.ts: -------------------------------------------------------------------------------- 1 | export * as components from './components' 2 | export * as sources from './sources' 3 | -------------------------------------------------------------------------------- /examples-vue/vue/src/sources/index.ts: -------------------------------------------------------------------------------- 1 | export * from './field' 2 | export * from './card' 3 | -------------------------------------------------------------------------------- /examples-vue/vue/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./lib", 5 | "paths": { 6 | "@pind/designable-*": ["../*"] 7 | }, 8 | "declaration": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples-vue/vue/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "moduleResolution": "Node", 7 | "strict": true, 8 | "jsx": "preserve", 9 | "resolveJsonModule": true, 10 | "isolatedModules": true, 11 | "esModuleInterop": true, 12 | "lib": ["ESNext", "DOM"], 13 | "skipLibCheck": true, 14 | "noEmit": true, 15 | "paths": { 16 | "@pind/designable-*": ["../../packages/*/src"], 17 | "@pind/designable-formily-*": ["../../formily/*/src"], 18 | "@examples-vue/*": ["../../examples-vue/*/src"] 19 | } 20 | }, 21 | "include": ["./src/**/*.ts", "./src/**/*.tsx", "./src/**/*.vue"], 22 | "exclude": ["./src/__tests__/*", "./esm/*", "./lib/*"] 23 | } 24 | -------------------------------------------------------------------------------- /examples/basic/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | build 4 | __tests__ -------------------------------------------------------------------------------- /examples/basic/README.md: -------------------------------------------------------------------------------- 1 | # @pind/designable-playground 2 | -------------------------------------------------------------------------------- /examples/basic/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | PIND 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/basic/src/sandbox.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Content } from './content' 3 | import { renderSandboxContent } from '@pind/designable-react-sandbox' 4 | import './theme.less' 5 | 6 | renderSandboxContent(() => { 7 | return 8 | }) 9 | -------------------------------------------------------------------------------- /examples/basic/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./lib", 5 | "paths": { 6 | "@pind/designable-*": ["../*"] 7 | }, 8 | "declaration": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/basic/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "include": ["./src/**/*.ts", "./src/**/*.tsx"], 4 | "exclude": ["./src/__tests__/*", "./esm/*", "./lib/*"] 5 | } 6 | -------------------------------------------------------------------------------- /examples/multi-workspace/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | build 4 | __tests__ -------------------------------------------------------------------------------- /examples/multi-workspace/README.md: -------------------------------------------------------------------------------- 1 | # @pind/designable-playground 2 | -------------------------------------------------------------------------------- /examples/multi-workspace/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | PIND 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/multi-workspace/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./lib", 5 | "paths": { 6 | "@pind/designable-*": ["../*"] 7 | }, 8 | "declaration": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/multi-workspace/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "include": ["./src/**/*.ts", "./src/**/*.tsx"], 4 | "exclude": ["./src/__tests__/*", "./esm/*", "./lib/*"] 5 | } 6 | -------------------------------------------------------------------------------- /examples/sandbox-multi-workspace/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | build 4 | __tests__ -------------------------------------------------------------------------------- /examples/sandbox-multi-workspace/README.md: -------------------------------------------------------------------------------- 1 | # @pind/designable-playground 2 | -------------------------------------------------------------------------------- /examples/sandbox-multi-workspace/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | PIND 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/sandbox-multi-workspace/src/env/designable.ts: -------------------------------------------------------------------------------- 1 | export * as Core from '@pind/designable-core' 2 | -------------------------------------------------------------------------------- /examples/sandbox-multi-workspace/src/env/formily.ts: -------------------------------------------------------------------------------- 1 | export * as Core from '@formily/core' 2 | export * as Reactive from '@formily/reactive' 3 | -------------------------------------------------------------------------------- /examples/sandbox-multi-workspace/src/env/index.ts: -------------------------------------------------------------------------------- 1 | import { globalThisPolyfill } from '@pind/designable-shared' 2 | import * as Formily from './formily' 3 | import * as Designable from './designable' 4 | 5 | globalThisPolyfill['Formily'] = globalThisPolyfill['Formily'] 6 | ? { 7 | ...globalThisPolyfill['Formily'], 8 | ...Formily, 9 | } 10 | : Formily 11 | 12 | globalThisPolyfill['Designable'] = globalThisPolyfill['Designable'] 13 | ? { 14 | ...globalThisPolyfill['Designable'], 15 | ...Designable, 16 | } 17 | : Designable 18 | -------------------------------------------------------------------------------- /examples/sandbox-multi-workspace/src/sandbox.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Content } from './content' 3 | import { renderSandboxContent } from '@pind/designable-react-sandbox' 4 | 5 | renderSandboxContent(() => { 6 | return 7 | }) 8 | -------------------------------------------------------------------------------- /examples/sandbox-multi-workspace/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./lib", 5 | "paths": { 6 | "@pind/designable-*": ["../*"] 7 | }, 8 | "declaration": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/sandbox-multi-workspace/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "include": ["./src/**/*.ts", "./src/**/*.tsx"], 4 | "exclude": ["./src/__tests__/*", "./esm/*", "./lib/*"] 5 | } 6 | -------------------------------------------------------------------------------- /examples/sandbox/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | build 4 | __tests__ -------------------------------------------------------------------------------- /examples/sandbox/README.md: -------------------------------------------------------------------------------- 1 | # @pind/designable-playground 2 | -------------------------------------------------------------------------------- /examples/sandbox/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | PIND 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/sandbox/src/env/designable.ts: -------------------------------------------------------------------------------- 1 | export * as Core from '@pind/designable-core' 2 | -------------------------------------------------------------------------------- /examples/sandbox/src/env/formily.ts: -------------------------------------------------------------------------------- 1 | export * as Core from '@formily/core' 2 | export * as Reactive from '@formily/reactive' 3 | -------------------------------------------------------------------------------- /examples/sandbox/src/env/index.ts: -------------------------------------------------------------------------------- 1 | import { globalThisPolyfill } from '@pind/designable-shared' 2 | import * as Formily from './formily' 3 | import * as Designable from './designable' 4 | 5 | globalThisPolyfill['Formily'] = globalThisPolyfill['Formily'] 6 | ? { 7 | ...globalThisPolyfill['Formily'], 8 | ...Formily, 9 | } 10 | : Formily 11 | 12 | globalThisPolyfill['Designable'] = globalThisPolyfill['Designable'] 13 | ? { 14 | ...globalThisPolyfill['Designable'], 15 | ...Designable, 16 | } 17 | : Designable 18 | -------------------------------------------------------------------------------- /examples/sandbox/src/sandbox.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Content } from './content' 3 | import { renderSandboxContent } from '@pind/designable-react-sandbox' 4 | 5 | renderSandboxContent(() => { 6 | return 7 | }) 8 | -------------------------------------------------------------------------------- /examples/sandbox/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./lib", 5 | "paths": { 6 | "@pind/designable-*": ["../*"] 7 | }, 8 | "declaration": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/sandbox/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "include": ["./src/**/*.ts", "./src/**/*.tsx"], 4 | "exclude": ["./src/__tests__/*", "./esm/*", "./lib/*"] 5 | } 6 | -------------------------------------------------------------------------------- /formily/antd/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | build 4 | docs 5 | doc-site 6 | __tests__ 7 | .eslintrc 8 | jest.config.js 9 | tsconfig.json 10 | .umi 11 | src 12 | vite.config 13 | -------------------------------------------------------------------------------- /formily/antd/README.md: -------------------------------------------------------------------------------- 1 | # @pind/designable-formily-antd 2 | 3 | ### Install 4 | 5 | ```bash 6 | npm install --save @pind/designable-formily-antd 7 | ``` 8 | -------------------------------------------------------------------------------- /formily/antd/copy.ts: -------------------------------------------------------------------------------- 1 | import { runCopy } from '../../scripts/build-style' 2 | 3 | runCopy({ 4 | esStr: 'antd/es/', 5 | libStr: 'antd/lib/', 6 | }) 7 | -------------------------------------------------------------------------------- /formily/antd/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | PIND 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /formily/antd/playground/service/index.ts: -------------------------------------------------------------------------------- 1 | export * from './schema' 2 | -------------------------------------------------------------------------------- /formily/antd/playground/service/schema.ts: -------------------------------------------------------------------------------- 1 | import { Engine } from '@pind/designable-core' 2 | import { 3 | transformToSchema, 4 | transformToTreeNode, 5 | } from '@pind/designable-formily-transformer' 6 | import { message } from 'antd' 7 | 8 | export const saveSchema = (designer: Engine) => { 9 | localStorage.setItem( 10 | 'formily-schema', 11 | JSON.stringify(transformToSchema(designer.getCurrentTree())) 12 | ) 13 | message.success('Save Success') 14 | } 15 | 16 | export const loadInitialSchema = (designer: Engine) => { 17 | try { 18 | designer.setCurrentTree( 19 | transformToTreeNode(JSON.parse(localStorage.getItem('formily-schema'))) 20 | ) 21 | } catch {} 22 | } 23 | -------------------------------------------------------------------------------- /formily/antd/playground/style.less: -------------------------------------------------------------------------------- 1 | .ant-alert-error { 2 | min-height: 100%; 3 | min-width: 100%; 4 | max-width: 100%; 5 | max-height: 100%; 6 | overflow: scroll; 7 | } 8 | -------------------------------------------------------------------------------- /formily/antd/playground/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.json", 3 | "include": ["/**/*.ts", "/**/*.tsx"] 4 | } 5 | -------------------------------------------------------------------------------- /formily/antd/playground/widgets/LogoWidget.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { useTheme } from '@pind/designable-react' 3 | 4 | const logo = { 5 | dark: '//img.alicdn.com/imgextra/i2/O1CN01NTUDi81fHLQvZCPnc_!!6000000003981-55-tps-1141-150.svg', 6 | light: 7 | '//img.alicdn.com/imgextra/i2/O1CN01Kq3OHU1fph6LGqjIz_!!6000000004056-55-tps-1141-150.svg', 8 | } 9 | 10 | export const LogoWidget: React.FC = () => { 11 | const url = logo[useTheme()] 12 | return ( 13 |
14 | 18 |
19 | ) 20 | } 21 | -------------------------------------------------------------------------------- /formily/antd/playground/widgets/PreviewWidget/components.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | export { 3 | Form, 4 | FormItem, 5 | DatePicker, 6 | Checkbox, 7 | Cascader, 8 | Editable, 9 | Input, 10 | NumberPicker, 11 | Switch, 12 | Password, 13 | PreviewText, 14 | Radio, 15 | Reset, 16 | Select, 17 | Space, 18 | Submit, 19 | TimePicker, 20 | Transfer, 21 | TreeSelect, 22 | Upload, 23 | FormGrid, 24 | FormLayout, 25 | FormTab, 26 | FormCollapse, 27 | ArrayTable, 28 | ArrayCards, 29 | } from '@formily/antd-v5' 30 | export { Card, Slider, Rate } from 'antd' 31 | 32 | export const Text: React.FC<{ 33 | value?: string 34 | content?: string 35 | mode?: 'normal' | 'h1' | 'h2' | 'h3' | 'p' 36 | }> = ({ value, mode, content, ...props }) => { 37 | const tagName = mode === 'normal' || !mode ? 'div' : mode 38 | return React.createElement(tagName, props, value || content) 39 | } 40 | -------------------------------------------------------------------------------- /formily/antd/playground/widgets/PreviewWidget/index.tsx: -------------------------------------------------------------------------------- 1 | import { createForm } from '@formily/core' 2 | import { createSchemaField } from '@formily/react' 3 | import { TreeNode } from '@pind/designable-core' 4 | import { transformToSchema } from '@pind/designable-formily-transformer' 5 | import React, { useMemo } from 'react' 6 | import * as components from './components' 7 | import { Form } from './components' 8 | 9 | import { Alert } from 'antd' 10 | 11 | const { ErrorBoundary } = Alert 12 | 13 | const SchemaField = createSchemaField({ 14 | components, 15 | }) 16 | 17 | export interface IPreviewWidgetProps { 18 | tree: TreeNode 19 | } 20 | 21 | export const PreviewWidget: React.FC = (props) => { 22 | const form = useMemo(() => createForm(), []) 23 | const { form: formProps, schema } = transformToSchema(props.tree) 24 | return ( 25 | 26 |
27 | 28 | 29 |
30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /formily/antd/playground/widgets/SchemaEditorWidget.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { 3 | transformToSchema, 4 | transformToTreeNode, 5 | } from '@pind/designable-formily-transformer' 6 | import { TreeNode, ITreeNode } from '@pind/designable-core' 7 | import { MonacoInput } from '@pind/designable-react-settings-form' 8 | 9 | export interface ISchemaEditorWidgetProps { 10 | tree: TreeNode 11 | onChange?: (tree: ITreeNode) => void 12 | } 13 | 14 | export const SchemaEditorWidget: React.FC = ( 15 | props 16 | ) => { 17 | return ( 18 | { 22 | props.onChange?.(transformToTreeNode(JSON.parse(value))) 23 | }} 24 | language="json" 25 | /> 26 | ) 27 | } 28 | -------------------------------------------------------------------------------- /formily/antd/playground/widgets/index.ts: -------------------------------------------------------------------------------- 1 | export * from './LogoWidget' 2 | export * from './ActionsWidget' 3 | export * from './PreviewWidget' 4 | export * from './SchemaEditorWidget' 5 | export * from './MarkupSchemaWidget' 6 | -------------------------------------------------------------------------------- /formily/antd/src/common/Container/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { observer, ReactFC } from '@formily/reactive-react' 3 | import { DroppableWidget } from '@pind/designable-react' 4 | import './styles.less' 5 | 6 | export const Container: ReactFC = observer((props) => { 7 | return {props.children} 8 | }) 9 | 10 | export const withContainer = (Target: React.JSXElementConstructor) => { 11 | return (props: any) => { 12 | return ( 13 | 14 | 15 | 16 | ) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /formily/antd/src/common/Container/styles.less: -------------------------------------------------------------------------------- 1 | .dn-form-container { 2 | margin: 0 !important; 3 | padding: 20px; 4 | border: 1px solid #f5f5f5; 5 | } 6 | -------------------------------------------------------------------------------- /formily/antd/src/common/FormItemSwitcher/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Switch } from 'antd' 3 | 4 | export interface IFormItemSwitcherProps { 5 | value?: string 6 | onChange?: (value?: string) => void 7 | } 8 | 9 | export const FormItemSwitcher: React.FC = (props) => { 10 | return ( 11 | { 14 | props.onChange?.(value ? 'FormItem' : undefined) 15 | }} 16 | /> 17 | ) 18 | } 19 | -------------------------------------------------------------------------------- /formily/antd/src/common/LoadTemplate/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { NodeActionsWidget } from '@pind/designable-react' 3 | 4 | export interface ITemplateAction { 5 | title: React.ReactNode 6 | tooltip?: React.ReactNode 7 | icon?: string | React.ReactNode 8 | onClick: () => void 9 | } 10 | 11 | export interface ILoadTemplateProps { 12 | className?: string 13 | style?: React.CSSProperties 14 | actions?: ITemplateAction[] 15 | } 16 | 17 | export const LoadTemplate: React.FC = (props) => { 18 | return ( 19 | 20 | {props.actions?.map((action, key) => { 21 | return 22 | })} 23 | 24 | ) 25 | } 26 | -------------------------------------------------------------------------------- /formily/antd/src/components/ArrayCards/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | -------------------------------------------------------------------------------- /formily/antd/src/components/ArrayCards/styles.less: -------------------------------------------------------------------------------- 1 | .dn-array-cards { 2 | background-color: #fff; 3 | } 4 | -------------------------------------------------------------------------------- /formily/antd/src/components/ArrayTable/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | -------------------------------------------------------------------------------- /formily/antd/src/components/ArrayTable/styles.less: -------------------------------------------------------------------------------- 1 | .dn-array-table { 2 | background-color: #fff; 3 | } 4 | -------------------------------------------------------------------------------- /formily/antd/src/components/Card/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | -------------------------------------------------------------------------------- /formily/antd/src/components/Cascader/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | -------------------------------------------------------------------------------- /formily/antd/src/components/Cascader/preview.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Cascader as FormilyCascader } from '@formily/antd-v5' 3 | import { createBehavior, createResource } from '@pind/designable-core' 4 | import { DnFC } from '@pind/designable-react' 5 | import { createFieldSchema } from '../Field' 6 | import { AllSchemas } from '../../schemas' 7 | import { AllLocales } from '../../locales' 8 | 9 | export const Cascader: DnFC> = 10 | FormilyCascader 11 | 12 | Cascader.Behavior = createBehavior({ 13 | name: 'Cascader', 14 | extends: ['Field'], 15 | selector: (node) => node.props['x-component'] === 'Cascader', 16 | designerProps: { 17 | propsSchema: createFieldSchema(AllSchemas.Cascader), 18 | }, 19 | designerLocales: AllLocales.Cascader, 20 | }) 21 | 22 | Cascader.Resource = createResource('Inputs', { 23 | icon: 'CascaderSource', 24 | elements: [ 25 | { 26 | componentName: 'Field', 27 | props: { 28 | title: 'Cascader', 29 | 'x-decorator': 'FormItem', 30 | 'x-component': 'Cascader', 31 | }, 32 | }, 33 | ], 34 | }) 35 | -------------------------------------------------------------------------------- /formily/antd/src/components/Checkbox/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | -------------------------------------------------------------------------------- /formily/antd/src/components/DatePicker/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | -------------------------------------------------------------------------------- /formily/antd/src/components/Field/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | export * from './shared' 3 | -------------------------------------------------------------------------------- /formily/antd/src/components/Form/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | -------------------------------------------------------------------------------- /formily/antd/src/components/Form/styles.less: -------------------------------------------------------------------------------- 1 | .dn-designable-form { 2 | .ant-input, 3 | .ant-input-number, 4 | .ant-input-affix-wrapper, 5 | .ant-cascader-picker, 6 | .ant-picker-input, 7 | .ant-picker, 8 | .ant-cascader-picker-label, 9 | .ant-slider, 10 | .ant-checkbox, 11 | .ant-rate, 12 | .ant-switch, 13 | .ant-radio, 14 | .ant-radio-wrapper, 15 | .ant-checkbox-group, 16 | .ant-checkbox-wrapper, 17 | .ant-radio-group, 18 | .ant-upload, 19 | .ant-transfer, 20 | .ant-select, 21 | .ant-select-selector { 22 | pointer-events: none !important; 23 | 24 | input { 25 | pointer-events: none !important; 26 | } 27 | } 28 | 29 | .anticon svg { 30 | pointer-events: none; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /formily/antd/src/components/FormCollapse/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | -------------------------------------------------------------------------------- /formily/antd/src/components/FormGrid/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | -------------------------------------------------------------------------------- /formily/antd/src/components/FormGrid/styles.less: -------------------------------------------------------------------------------- 1 | .dn-grid-column { 2 | margin: 4px; 3 | min-height: 60px; 4 | border: 1px dashed #aaa; 5 | } 6 | -------------------------------------------------------------------------------- /formily/antd/src/components/FormLayout/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | -------------------------------------------------------------------------------- /formily/antd/src/components/FormTab/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | -------------------------------------------------------------------------------- /formily/antd/src/components/Input/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | -------------------------------------------------------------------------------- /formily/antd/src/components/NumberPicker/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | -------------------------------------------------------------------------------- /formily/antd/src/components/Object/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | -------------------------------------------------------------------------------- /formily/antd/src/components/Object/preview.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { createBehavior, createResource } from '@pind/designable-core' 3 | import { DnFC } from '@pind/designable-react' 4 | import { createFieldSchema } from '../Field' 5 | import { Container } from '../../common/Container' 6 | import { AllLocales } from '../../locales' 7 | 8 | export const ObjectContainer: DnFC> = 9 | Container 10 | ObjectContainer.Behavior = createBehavior({ 11 | name: 'Object', 12 | extends: ['Field'], 13 | selector: (node) => node.props.type === 'object', 14 | designerProps: { 15 | droppable: true, 16 | propsSchema: createFieldSchema(), 17 | }, 18 | designerLocales: AllLocales.ObjectLocale, 19 | }) 20 | 21 | ObjectContainer.Resource = createResource('Inputs', { 22 | icon: 'ObjectSource', 23 | elements: [ 24 | { 25 | componentName: 'Field', 26 | props: { 27 | type: 'object', 28 | }, 29 | }, 30 | ], 31 | }) 32 | -------------------------------------------------------------------------------- /formily/antd/src/components/Password/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | -------------------------------------------------------------------------------- /formily/antd/src/components/Password/preview.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Password as FormilyPassword } from '@formily/antd-v5' 3 | import { createBehavior, createResource } from '@pind/designable-core' 4 | import { DnFC } from '@pind/designable-react' 5 | import { createFieldSchema } from '../Field' 6 | import { AllSchemas } from '../../schemas' 7 | import { AllLocales } from '../../locales' 8 | 9 | export const Password: DnFC> = 10 | FormilyPassword 11 | 12 | Password.Behavior = createBehavior({ 13 | name: 'Password', 14 | extends: ['Field'], 15 | selector: (node) => node.props['x-component'] === 'Password', 16 | designerProps: { 17 | propsSchema: createFieldSchema(AllSchemas.Password), 18 | }, 19 | designerLocales: AllLocales.Password, 20 | }) 21 | 22 | Password.Resource = createResource('Inputs', { 23 | icon: 'PasswordSource', 24 | elements: [ 25 | { 26 | componentName: 'Field', 27 | props: { 28 | title: 'Password', 29 | 'x-decorator': 'FormItem', 30 | 'x-component': 'Password', 31 | }, 32 | }, 33 | ], 34 | }) 35 | -------------------------------------------------------------------------------- /formily/antd/src/components/Radio/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | -------------------------------------------------------------------------------- /formily/antd/src/components/Rate/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | -------------------------------------------------------------------------------- /formily/antd/src/components/Rate/preview.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Rate as AntdRate } from 'antd' 3 | import { createBehavior, createResource } from '@pind/designable-core' 4 | import { DnFC } from '@pind/designable-react' 5 | import { createFieldSchema } from '../Field' 6 | import { AllSchemas } from '../../schemas' 7 | import { AllLocales } from '../../locales' 8 | 9 | export const Rate: DnFC> = AntdRate 10 | 11 | Rate.Behavior = createBehavior({ 12 | name: 'Rate', 13 | extends: ['Field'], 14 | selector: (node) => node.props['x-component'] === 'Rate', 15 | designerProps: { 16 | propsSchema: createFieldSchema(AllSchemas.Rate), 17 | }, 18 | designerLocales: AllLocales.Rate, 19 | }) 20 | 21 | Rate.Resource = createResource('Inputs', { 22 | icon: 'RateSource', 23 | elements: [ 24 | { 25 | componentName: 'Field', 26 | props: { 27 | type: 'number', 28 | title: 'Rate', 29 | 'x-decorator': 'FormItem', 30 | 'x-component': 'Rate', 31 | }, 32 | }, 33 | ], 34 | }) 35 | -------------------------------------------------------------------------------- /formily/antd/src/components/Select/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | -------------------------------------------------------------------------------- /formily/antd/src/components/Select/preview.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Select as FormilySelect } from '@formily/antd-v5' 3 | import { createBehavior, createResource } from '@pind/designable-core' 4 | import { DnFC } from '@pind/designable-react' 5 | import { createFieldSchema } from '../Field' 6 | import { AllSchemas } from '../../schemas' 7 | import { AllLocales } from '../../locales' 8 | 9 | export const Select: DnFC> = 10 | FormilySelect 11 | 12 | Select.Behavior = createBehavior({ 13 | name: 'Select', 14 | extends: ['Field'], 15 | selector: (node) => node.props['x-component'] === 'Select', 16 | designerProps: { 17 | propsSchema: createFieldSchema(AllSchemas.Select), 18 | }, 19 | designerLocales: AllLocales.Select, 20 | }) 21 | 22 | Select.Resource = createResource('Inputs', { 23 | icon: 'SelectSource', 24 | elements: [ 25 | { 26 | componentName: 'Field', 27 | props: { 28 | title: 'Select', 29 | 'x-decorator': 'FormItem', 30 | 'x-component': 'Select', 31 | }, 32 | }, 33 | ], 34 | }) 35 | -------------------------------------------------------------------------------- /formily/antd/src/components/Slider/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | -------------------------------------------------------------------------------- /formily/antd/src/components/Slider/preview.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Slider as AntdSlider } from 'antd' 3 | import { createBehavior, createResource } from '@pind/designable-core' 4 | import { DnFC } from '@pind/designable-react' 5 | import { createFieldSchema } from '../Field' 6 | import { AllSchemas } from '../../schemas' 7 | import { AllLocales } from '../../locales' 8 | 9 | export const Slider: DnFC> = AntdSlider 10 | 11 | Slider.Behavior = createBehavior({ 12 | name: 'Slider', 13 | extends: ['Field'], 14 | selector: (node) => node.props['x-component'] === 'Slider', 15 | designerProps: { 16 | propsSchema: createFieldSchema(AllSchemas.Slider), 17 | }, 18 | designerLocales: AllLocales.Slider, 19 | }) 20 | 21 | Slider.Resource = createResource('Inputs', { 22 | icon: 'SliderSource', 23 | elements: [ 24 | { 25 | componentName: 'Field', 26 | props: { 27 | type: 'number', 28 | title: 'Slider', 29 | 'x-decorator': 'FormItem', 30 | 'x-component': 'Slider', 31 | }, 32 | }, 33 | ], 34 | }) 35 | -------------------------------------------------------------------------------- /formily/antd/src/components/Space/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | -------------------------------------------------------------------------------- /formily/antd/src/components/Switch/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | -------------------------------------------------------------------------------- /formily/antd/src/components/Switch/preview.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Switch as AntdSwitch } from 'antd' 3 | import { createBehavior, createResource } from '@pind/designable-core' 4 | import { DnFC } from '@pind/designable-react' 5 | import { createFieldSchema } from '../Field' 6 | import { AllSchemas } from '../../schemas' 7 | import { AllLocales } from '../../locales' 8 | 9 | export const Switch: DnFC> = AntdSwitch 10 | 11 | Switch.Behavior = createBehavior({ 12 | name: 'Switch', 13 | extends: ['Field'], 14 | selector: (node) => node.props['x-component'] === 'Switch', 15 | designerProps: { 16 | propsSchema: createFieldSchema(AllSchemas.Switch), 17 | }, 18 | designerLocales: AllLocales.Switch, 19 | }) 20 | 21 | Switch.Resource = createResource('Inputs', { 22 | icon: 'SwitchSource', 23 | elements: [ 24 | { 25 | componentName: 'Field', 26 | props: { 27 | type: 'boolean', 28 | title: 'Switch', 29 | 'x-decorator': 'FormItem', 30 | 'x-component': 'Switch', 31 | }, 32 | }, 33 | ], 34 | }) 35 | -------------------------------------------------------------------------------- /formily/antd/src/components/Text/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | -------------------------------------------------------------------------------- /formily/antd/src/components/Text/styles.less: -------------------------------------------------------------------------------- 1 | .dn-text { 2 | &:empty::before { 3 | content: 'Please Input'; 4 | display: block; 5 | opacity: 0.6; 6 | } 7 | &:focus { 8 | padding: 4px; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /formily/antd/src/components/TimePicker/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | -------------------------------------------------------------------------------- /formily/antd/src/components/Transfer/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | -------------------------------------------------------------------------------- /formily/antd/src/components/Transfer/preview.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Transfer as FormilyTransfer } from '@formily/antd-v5' 3 | import { createBehavior, createResource } from '@pind/designable-core' 4 | import { DnFC } from '@pind/designable-react' 5 | import { createFieldSchema } from '../Field' 6 | import { AllSchemas } from '../../schemas' 7 | import { AllLocales } from '../../locales' 8 | 9 | export const Transfer: DnFC> = 10 | FormilyTransfer 11 | 12 | Transfer.Behavior = createBehavior({ 13 | name: 'Transfer', 14 | extends: ['Field'], 15 | selector: (node) => node.props['x-component'] === 'Transfer', 16 | designerProps: { 17 | propsSchema: createFieldSchema(AllSchemas.Transfer), 18 | }, 19 | designerLocales: AllLocales.Transfer, 20 | }) 21 | 22 | Transfer.Resource = createResource('Inputs', { 23 | icon: 'TransferSource', 24 | elements: [ 25 | { 26 | componentName: 'Field', 27 | props: { 28 | title: 'Transfer', 29 | 'x-decorator': 'FormItem', 30 | 'x-component': 'Transfer', 31 | }, 32 | }, 33 | ], 34 | }) 35 | -------------------------------------------------------------------------------- /formily/antd/src/components/TreeSelect/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | -------------------------------------------------------------------------------- /formily/antd/src/components/TreeSelect/preview.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { TreeSelect as FormilyTreeSelect } from '@formily/antd-v5' 3 | import { createBehavior, createResource } from '@pind/designable-core' 4 | import { DnFC } from '@pind/designable-react' 5 | import { createFieldSchema } from '../Field' 6 | import { AllSchemas } from '../../schemas' 7 | import { AllLocales } from '../../locales' 8 | 9 | export const TreeSelect: DnFC> = 10 | FormilyTreeSelect 11 | 12 | TreeSelect.Behavior = createBehavior({ 13 | name: 'TreeSelect', 14 | extends: ['Field'], 15 | selector: (node) => node.props['x-component'] === 'TreeSelect', 16 | designerProps: { 17 | propsSchema: createFieldSchema(AllSchemas.TreeSelect), 18 | }, 19 | designerLocales: AllLocales.TreeSelect, 20 | }) 21 | 22 | TreeSelect.Resource = createResource('Inputs', { 23 | icon: 'TreeSelectSource', 24 | elements: [ 25 | { 26 | componentName: 'Field', 27 | props: { 28 | title: 'TreeSelect', 29 | 'x-decorator': 'FormItem', 30 | 'x-component': 'TreeSelect', 31 | }, 32 | }, 33 | ], 34 | }) 35 | -------------------------------------------------------------------------------- /formily/antd/src/components/Upload/index.ts: -------------------------------------------------------------------------------- 1 | export * from './preview' 2 | -------------------------------------------------------------------------------- /formily/antd/src/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Field' 2 | export * from './Form' 3 | export * from './Input' 4 | export * from './Select' 5 | export * from './TreeSelect' 6 | export * from './Cascader' 7 | export * from './Radio' 8 | export * from './Checkbox' 9 | export * from './Slider' 10 | export * from './Rate' 11 | export * from './NumberPicker' 12 | export * from './Transfer' 13 | export * from './Password' 14 | export * from './DatePicker' 15 | export * from './TimePicker' 16 | export * from './Upload' 17 | export * from './Switch' 18 | export * from './Text' 19 | export * from './Card' 20 | export * from './Space' 21 | export * from './Object' 22 | export * from './ArrayCards' 23 | export * from './ArrayTable' 24 | export * from './FormTab' 25 | export * from './FormCollapse' 26 | export * from './FormGrid' 27 | export * from './FormLayout' 28 | -------------------------------------------------------------------------------- /formily/antd/src/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useDropTemplate' 2 | -------------------------------------------------------------------------------- /formily/antd/src/hooks/useDropTemplate.ts: -------------------------------------------------------------------------------- 1 | import { AppendNodeEvent, TreeNode } from '@pind/designable-core' 2 | import { useDesigner } from '@pind/designable-react' 3 | import { matchComponent, matchChildComponent } from '../shared' 4 | 5 | export const useDropTemplate = ( 6 | name: string, 7 | getChildren: (source: TreeNode[]) => TreeNode[] 8 | ) => { 9 | return useDesigner((designer) => { 10 | return designer.subscribeTo(AppendNodeEvent, (event) => { 11 | const { source, target } = event.data 12 | if (Array.isArray(target)) return 13 | if (!Array.isArray(source)) return 14 | if ( 15 | matchComponent( 16 | target, 17 | (key) => 18 | key === name && 19 | source.every((child) => !matchChildComponent(child, name)) 20 | ) && 21 | target.children.length === 0 22 | ) { 23 | target.setChildren(...getChildren(source)) 24 | return false 25 | } 26 | }) 27 | }) 28 | } 29 | -------------------------------------------------------------------------------- /formily/antd/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './components' 2 | export * from './schemas' 3 | export * from './locales' 4 | export * as sources from './sources' 5 | -------------------------------------------------------------------------------- /formily/antd/src/locales/ArrayCards.ts: -------------------------------------------------------------------------------- 1 | import { createLocales } from '@pind/designable-core' 2 | import { Card } from './Card' 3 | 4 | export const ArrayCards = createLocales(Card, { 5 | 'zh-CN': { 6 | title: '自增卡片', 7 | addIndex: '添加索引', 8 | addOperation: '添加操作', 9 | }, 10 | 'en-US': { 11 | title: 'Array Cards', 12 | addIndex: 'Add Index', 13 | addOperation: 'Add Operations', 14 | }, 15 | 'ko-KR': { 16 | title: '배열 카드', 17 | addIndex: '색인 추가', 18 | addOperation: '작업 추가', 19 | }, 20 | }) 21 | -------------------------------------------------------------------------------- /formily/antd/src/locales/Card.ts: -------------------------------------------------------------------------------- 1 | export const Card = { 2 | 'zh-CN': { 3 | title: '卡片', 4 | settings: { 5 | 'x-component-props': { 6 | type: '类型', 7 | title: '标题', 8 | extra: '右侧扩展', 9 | cardTypes: [ 10 | { label: '内置', value: 'inner' }, 11 | { label: '默认', value: '' }, 12 | ], 13 | }, 14 | }, 15 | }, 16 | 'en-US': { 17 | title: 'Card', 18 | settings: { 19 | 'x-component-props': { 20 | type: 'Type', 21 | title: 'Title', 22 | extra: 'Extra', 23 | cardTypes: [ 24 | { label: 'Inner', value: 'inner' }, 25 | { label: 'Default', value: '' }, 26 | ], 27 | }, 28 | }, 29 | }, 30 | 'ko-KR': { 31 | title: '카드', 32 | settings: { 33 | 'x-component-props': { 34 | type: '타입', 35 | title: '제목', 36 | extra: '추가 항목', 37 | cardTypes: [ 38 | { label: '안쪽', value: 'inner' }, 39 | { label: '기본', value: '' }, 40 | ], 41 | }, 42 | }, 43 | }, 44 | } 45 | -------------------------------------------------------------------------------- /formily/antd/src/locales/Checkbox.ts: -------------------------------------------------------------------------------- 1 | export const CheckboxGroup = { 2 | 'zh-CN': { 3 | title: '复选框组', 4 | }, 5 | 'en-US': { 6 | title: 'Checkbox', 7 | }, 8 | 'ko-KR': { 9 | title: '체크박스', 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /formily/antd/src/locales/Object.ts: -------------------------------------------------------------------------------- 1 | export const ObjectLocale = { 2 | 'zh-CN': { 3 | title: '对象容器', 4 | }, 5 | 'en-US': { 6 | title: 'Object', 7 | }, 8 | 'ko-KR': { 9 | title: '오브젝트', 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /formily/antd/src/locales/Password.ts: -------------------------------------------------------------------------------- 1 | import { createLocales } from '@pind/designable-core' 2 | import { Input } from './Input' 3 | 4 | export const Password = createLocales(Input, { 5 | 'zh-CN': { 6 | title: '密码输入', 7 | }, 8 | 'en-US': { 9 | title: 'Password', 10 | }, 11 | 'ko-KR': { 12 | title: '비밀번호', 13 | }, 14 | }) 15 | -------------------------------------------------------------------------------- /formily/antd/src/locales/Radio.ts: -------------------------------------------------------------------------------- 1 | export const RadioGroup = { 2 | 'zh-CN': { 3 | title: '单选框组', 4 | settings: { 5 | 'x-component-props': { 6 | buttonStyle: { title: '按钮风格', dataSource: ['空心', '实心'] }, 7 | optionType: { title: '选项类型', dataSource: ['默认', '按钮'] }, 8 | }, 9 | }, 10 | }, 11 | 'en-US': { 12 | title: 'Radio', 13 | settings: { 14 | 'x-component-props': { 15 | buttonStyle: { title: 'Button style', dataSource: ['Hollow', 'Solid'] }, 16 | optionType: { title: 'Option type', dataSource: ['Default', 'Button'] }, 17 | }, 18 | }, 19 | }, 20 | 'ko-KR': { 21 | title: '라디오', 22 | settings: { 23 | 'x-component-props': { 24 | buttonStyle: { title: '버튼 스타일', dataSource: ['Hollow', 'Solid'] }, 25 | optionType: { title: '옵션 타입', dataSource: ['기본', '버튼'] }, 26 | }, 27 | }, 28 | }, 29 | } 30 | -------------------------------------------------------------------------------- /formily/antd/src/locales/Rate.ts: -------------------------------------------------------------------------------- 1 | export const Rate = { 2 | 'zh-CN': { 3 | title: '评分器', 4 | settings: { 5 | 'x-component-props': { 6 | allowHalf: '允许半选', 7 | tooltips: { title: '提示信息', tooltip: '格式:string[]' }, 8 | count: '总数', 9 | }, 10 | }, 11 | }, 12 | 'en-US': { 13 | title: 'Rate', 14 | settings: { 15 | 'x-component-props': { 16 | allowHalf: 'Allow Half', 17 | tooltips: { title: 'Tooltips', tooltip: 'Format:string[]' }, 18 | count: 'Count', 19 | }, 20 | }, 21 | }, 22 | 'ko-KR': { 23 | title: '비율', 24 | settings: { 25 | 'x-component-props': { 26 | allowHalf: '절반 허용', 27 | tooltips: { title: '툴팁', tooltip: '형식:string[]' }, 28 | count: '개수', 29 | }, 30 | }, 31 | }, 32 | } 33 | -------------------------------------------------------------------------------- /formily/antd/src/locales/Switch.ts: -------------------------------------------------------------------------------- 1 | export const Switch = { 2 | 'zh-CN': { 3 | title: '开关', 4 | }, 5 | 'en-US': { 6 | title: 'Switch', 7 | }, 8 | 'ko-KR': { 9 | title: '스위치', 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /formily/antd/src/locales/Text.ts: -------------------------------------------------------------------------------- 1 | export const Text = { 2 | 'zh-CN': { 3 | title: '文本', 4 | settings: { 5 | 'x-component-props': { 6 | content: '文本内容', 7 | mode: { 8 | title: '文本类型', 9 | dataSource: ['H1', 'H2', 'H3', 'Paragraph', 'Normal'], 10 | }, 11 | }, 12 | }, 13 | }, 14 | 'en-US': { 15 | title: 'Text', 16 | settings: { 17 | 'x-component-props': { 18 | content: 'Text Content', 19 | mode: { 20 | title: 'Text Mode', 21 | dataSource: ['H1', 'H2', 'H3', 'Paragraph', 'Normal'], 22 | }, 23 | }, 24 | }, 25 | }, 26 | 'ko-KR': { 27 | title: '텍스트', 28 | settings: { 29 | 'x-component-props': { 30 | content: '텍스트 내용', 31 | mode: { 32 | title: '텍스트 모드', 33 | dataSource: ['H1', 'H2', 'H3', 'Paragraph', 'Normal'], 34 | }, 35 | }, 36 | }, 37 | }, 38 | } 39 | -------------------------------------------------------------------------------- /formily/antd/src/locales/TextArea.ts: -------------------------------------------------------------------------------- 1 | export const TextArea = { 2 | 'zh-CN': { 3 | title: '多行输入', 4 | settings: { 5 | 'x-component-props': { 6 | maxLength: '最大长度', 7 | autoSize: { 8 | title: '自适应高度', 9 | tooltip: '可设置为 true | false 或对象:{ minRows: 2, maxRows: 6 }', 10 | }, 11 | showCount: '是否展示字数', 12 | }, 13 | }, 14 | }, 15 | 'en-US': { 16 | title: 'TextArea', 17 | settings: { 18 | 'x-component-props': { 19 | maxLength: 'Max Length', 20 | autoSize: 'Auto Size', 21 | showCount: 'Show Count', 22 | }, 23 | }, 24 | }, 25 | 'ko-KR': { 26 | title: '텍스트 상자', 27 | settings: { 28 | 'x-component-props': { 29 | maxLength: '최대 길이', 30 | autoSize: '자동 길이 변환', 31 | showCount: '개수 보기', 32 | }, 33 | }, 34 | }, 35 | } 36 | -------------------------------------------------------------------------------- /formily/antd/src/locales/Void.ts: -------------------------------------------------------------------------------- 1 | export const Void = { 2 | 'zh-CN': { 3 | title: '虚拟容器', 4 | }, 5 | 'en-US': { 6 | title: 'Void', 7 | }, 8 | 'ko-KR': { 9 | title: '비어있음', 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /formily/antd/src/locales/all.ts: -------------------------------------------------------------------------------- 1 | export * from './Component' 2 | export * from './Field' 3 | export * from './Input' 4 | export * from './Select' 5 | export * from './TextArea' 6 | export * from './TreeSelect' 7 | export * from './Cascader' 8 | export * from './Radio' 9 | export * from './Checkbox' 10 | export * from './Slider' 11 | export * from './Rate' 12 | export * from './DatePicker' 13 | export * from './TimePicker' 14 | export * from './NumberPicker' 15 | export * from './Password' 16 | export * from './Transfer' 17 | export * from './Upload' 18 | export * from './Switch' 19 | export * from './Object' 20 | export * from './Form' 21 | export * from './FormLayout' 22 | export * from './Text' 23 | export * from './Card' 24 | export * from './ArrayBase' 25 | export * from './ArrayCards' 26 | export * from './ArrayTable' 27 | export * from './Void' 28 | export * from './Space' 29 | export * from './FormTab' 30 | export * from './FormCollapse' 31 | export * from './FormGrid' 32 | -------------------------------------------------------------------------------- /formily/antd/src/locales/index.ts: -------------------------------------------------------------------------------- 1 | import * as AllLocales from './all' 2 | 3 | export { AllLocales } 4 | -------------------------------------------------------------------------------- /formily/antd/src/schemas/ArrayCards.ts: -------------------------------------------------------------------------------- 1 | import { ArrayTable } from './ArrayTable' 2 | import { Card } from './Card' 3 | 4 | export const ArrayCards = Card 5 | ArrayCards.Addition = ArrayTable.Addition 6 | -------------------------------------------------------------------------------- /formily/antd/src/schemas/Card.ts: -------------------------------------------------------------------------------- 1 | import { GlobalRegistry } from '@pind/designable-core' 2 | import { ISchema } from '@formily/react' 3 | 4 | export const Card: ISchema & { Addition?: ISchema } = { 5 | type: 'object', 6 | properties: { 7 | title: { 8 | type: 'string', 9 | 'x-decorator': 'FormItem', 10 | 'x-component': 'Input', 11 | }, 12 | extra: { 13 | type: 'string', 14 | 'x-decorator': 'FormItem', 15 | 'x-component': 'Input', 16 | }, 17 | type: { 18 | type: 'boolean', 19 | enum: GlobalRegistry.getDesignerMessage('settings.cardTypes'), 20 | 'x-decorator': 'FormItem', 21 | 'x-component': 'Radio.Group', 22 | 'x-component-props': { 23 | defaultValue: '', 24 | optionType: 'button', 25 | }, 26 | }, 27 | bordered: { 28 | type: 'boolean', 29 | 'x-decorator': 'FormItem', 30 | 'x-component': 'Switch', 31 | 'x-component-props': { 32 | defaultChecked: true, 33 | }, 34 | }, 35 | }, 36 | } 37 | -------------------------------------------------------------------------------- /formily/antd/src/schemas/Checkbox.ts: -------------------------------------------------------------------------------- 1 | import { ISchema } from '@formily/react' 2 | 3 | export const Checkbox: ISchema & { Group?: ISchema } = { 4 | type: 'object', 5 | properties: { 6 | autoFocus: { 7 | type: 'boolean', 8 | 'x-decorator': 'FormItem', 9 | 'x-component': 'Switch', 10 | }, 11 | }, 12 | } 13 | -------------------------------------------------------------------------------- /formily/antd/src/schemas/Form.ts: -------------------------------------------------------------------------------- 1 | import { ISchema } from '@formily/react' 2 | import { FormLayout } from './FormLayout' 3 | import { CSSStyle } from './CSSStyle' 4 | 5 | export const Form: ISchema = { 6 | type: 'object', 7 | properties: { 8 | ...(FormLayout.properties as any), 9 | style: CSSStyle, 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /formily/antd/src/schemas/Password.ts: -------------------------------------------------------------------------------- 1 | import { ISchema } from '@formily/react' 2 | import { Input } from './Input' 3 | export const Password: ISchema = { 4 | type: 'object', 5 | properties: { 6 | ...(Input.properties as any), 7 | checkStrength: { 8 | type: 'boolean', 9 | 'x-decorator': 'FormItem', 10 | 'x-component': 'Switch', 11 | }, 12 | }, 13 | } 14 | -------------------------------------------------------------------------------- /formily/antd/src/schemas/Radio.ts: -------------------------------------------------------------------------------- 1 | import { ISchema } from '@formily/react' 2 | 3 | export const Radio: ISchema & { Group?: ISchema } = { 4 | type: 'object', 5 | properties: { 6 | autoFocus: { 7 | type: 'boolean', 8 | 'x-decorator': 'FormItem', 9 | 'x-component': 'Switch', 10 | }, 11 | }, 12 | } 13 | 14 | Radio.Group = { 15 | type: 'object', 16 | properties: { 17 | optionType: { 18 | type: 'string', 19 | enum: ['default', 'button'], 20 | 'x-decorator': 'FormItem', 21 | 'x-component': 'Radio.Group', 22 | 'x-component-props': { 23 | defaultValue: 'default', 24 | optionType: 'button', 25 | }, 26 | }, 27 | buttonStyle: { 28 | type: 'string', 29 | enum: ['outline', 'solid'], 30 | 'x-decorator': 'FormItem', 31 | 'x-component': 'Radio.Group', 32 | 'x-component-props': { 33 | defaultValue: 'outline', 34 | optionType: 'button', 35 | }, 36 | }, 37 | }, 38 | } 39 | -------------------------------------------------------------------------------- /formily/antd/src/schemas/Rate.ts: -------------------------------------------------------------------------------- 1 | import { ISchema } from '@formily/react' 2 | 3 | export const Rate: ISchema = { 4 | type: 'object', 5 | properties: { 6 | allowClear: { 7 | type: 'boolean', 8 | 'x-decorator': 'FormItem', 9 | 'x-component': 'Switch', 10 | 'x-component-props': { 11 | defaultChecked: true, 12 | }, 13 | }, 14 | count: { 15 | type: 'number', 16 | 'x-decorator': 'FormItem', 17 | 'x-component': 'NumberPicker', 18 | 'x-component-props': { 19 | defaultValue: 5, 20 | }, 21 | }, 22 | allowHalf: { 23 | type: 'boolean', 24 | 'x-decorator': 'FormItem', 25 | 'x-component': 'Switch', 26 | }, 27 | tooltips: { 28 | 'x-decorator': 'FormItem', 29 | 'x-component': 'ValueInput', 30 | 'x-component-props': { 31 | include: ['EXPRESSION'], 32 | }, 33 | }, 34 | autoFocus: { 35 | type: 'boolean', 36 | 'x-decorator': 'FormItem', 37 | 'x-component': 'Switch', 38 | }, 39 | }, 40 | } 41 | -------------------------------------------------------------------------------- /formily/antd/src/schemas/Space.ts: -------------------------------------------------------------------------------- 1 | import { ISchema } from '@formily/react' 2 | 3 | export const Space: ISchema = { 4 | type: 'object', 5 | properties: { 6 | align: { 7 | type: 'string', 8 | enum: ['start', 'end', 'center', 'baseline'], 9 | 'x-decorator': 'FormItem', 10 | 'x-component': 'Select', 11 | }, 12 | direction: { 13 | type: 'string', 14 | enum: ['vertical', 'horizontal'], 15 | 'x-decorator': 'FormItem', 16 | 'x-component': 'Radio.Group', 17 | 'x-component-props': { 18 | defaultValue: 'horizontal', 19 | optionType: 'button', 20 | }, 21 | }, 22 | size: { 23 | type: 'number', 24 | 'x-decorator': 'FormItem', 25 | 'x-component': 'NumberPicker', 26 | 'x-component-props': { 27 | defaultValue: 8, 28 | }, 29 | }, 30 | split: { 31 | type: 'string', 32 | 'x-decorator': 'FormItem', 33 | 'x-component': 'Input', 34 | }, 35 | wrap: { 36 | type: 'boolean', 37 | 'x-decorator': 'FormItem', 38 | 'x-component': 'Switch', 39 | }, 40 | }, 41 | } 42 | -------------------------------------------------------------------------------- /formily/antd/src/schemas/Switch.ts: -------------------------------------------------------------------------------- 1 | import { ISchema } from '@formily/react' 2 | 3 | export const Switch: ISchema = { 4 | type: 'object', 5 | properties: { 6 | autoFocus: { 7 | type: 'boolean', 8 | 'x-decorator': 'FormItem', 9 | 'x-component': 'Switch', 10 | }, 11 | size: { 12 | type: 'string', 13 | enum: ['large', 'small', 'default', ''], 14 | 'x-decorator': 'FormItem', 15 | 'x-component': 'Select', 16 | 'x-component-props': { 17 | defaultValue: 'default', 18 | }, 19 | }, 20 | }, 21 | } 22 | -------------------------------------------------------------------------------- /formily/antd/src/schemas/Text.ts: -------------------------------------------------------------------------------- 1 | import { ISchema } from '@formily/react' 2 | 3 | export const Text: ISchema = { 4 | type: 'object', 5 | properties: { 6 | content: { 7 | type: 'string', 8 | 'x-decorator': 'FormItem', 9 | 'x-component': 'Input.TextArea', 10 | }, 11 | mode: { 12 | type: 'string', 13 | 'x-decorator': 'FormItem', 14 | 'x-component': 'Select', 15 | 'x-component-props': { 16 | defaultValue: 'normal', 17 | }, 18 | enum: ['h1', 'h2', 'h3', 'p', 'normal'], 19 | }, 20 | }, 21 | } 22 | -------------------------------------------------------------------------------- /formily/antd/src/schemas/all.ts: -------------------------------------------------------------------------------- 1 | export * from './Input' 2 | export * from './Text' 3 | export * from './FormLayout' 4 | export * from './CSSStyle' 5 | export * from './Form' 6 | export * from './FormItem' 7 | export * from './Select' 8 | export * from './Card' 9 | export * from './Cascader' 10 | export * from './Checkbox' 11 | export * from './Radio' 12 | export * from './DatePicker' 13 | export * from './NumberPicker' 14 | export * from './Password' 15 | export * from './Rate' 16 | export * from './Slider' 17 | export * from './TimePicker' 18 | export * from './TreeSelect' 19 | export * from './Transfer' 20 | export * from './Upload' 21 | export * from './Switch' 22 | export * from './FormGrid' 23 | export * from './Space' 24 | export * from './FormTab' 25 | export * from './FormCollapse' 26 | export * from './ArrayTable' 27 | export * from './ArrayCards' 28 | -------------------------------------------------------------------------------- /formily/antd/src/schemas/index.ts: -------------------------------------------------------------------------------- 1 | import * as AllSchemas from './all' 2 | 3 | export { AllSchemas } 4 | -------------------------------------------------------------------------------- /formily/antd/src/sources.ts: -------------------------------------------------------------------------------- 1 | export { 2 | Form, 3 | Field, 4 | Input, 5 | Select, 6 | TreeSelect, 7 | Cascader, 8 | Radio, 9 | Checkbox, 10 | Slider, 11 | Rate, 12 | NumberPicker, 13 | Transfer, 14 | Password, 15 | DatePicker, 16 | TimePicker, 17 | Upload, 18 | Switch, 19 | Text, 20 | Card, 21 | ArrayCards, 22 | ObjectContainer, 23 | ArrayTable, 24 | Space, 25 | FormTab, 26 | FormCollapse, 27 | FormLayout, 28 | FormGrid, 29 | } from './components' 30 | -------------------------------------------------------------------------------- /formily/antd/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./lib", 5 | "paths": { 6 | "@pind/designable-*": ["../../packages/*"], 7 | "@pind/designable-formily-*": ["../../formily/*"] 8 | }, 9 | "declaration": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /formily/antd/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "include": ["./src/**/*.ts", "./src/**/*.tsx"], 4 | "exclude": ["./src/__tests__/*", "./esm/*", "./lib/*"] 5 | } 6 | -------------------------------------------------------------------------------- /formily/setters/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | build 4 | docs 5 | doc-site 6 | __tests__ 7 | .eslintrc 8 | jest.config.js 9 | tsconfig.json 10 | .umi 11 | src -------------------------------------------------------------------------------- /formily/setters/README.md: -------------------------------------------------------------------------------- 1 | # @pind/designable-formily-setters 2 | 3 | ### Install 4 | 5 | ```bash 6 | npm install --save @pind/designable-formily-setters 7 | ``` 8 | -------------------------------------------------------------------------------- /formily/setters/copy.ts: -------------------------------------------------------------------------------- 1 | import { runCopy } from '../../scripts/build-style' 2 | 3 | runCopy({ 4 | esStr: 'antd/es/', 5 | libStr: 'antd/lib/', 6 | }) 7 | -------------------------------------------------------------------------------- /formily/setters/src/components/DataSourceSetter/Header.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactNode } from 'react' 2 | import { observer } from '@formily/reactive-react' 3 | import { usePrefix } from '@pind/designable-react' 4 | import './styles.less' 5 | 6 | export interface IHeaderProps { 7 | extra: ReactNode | null 8 | title: ReactNode | string 9 | } 10 | 11 | export const Header: React.FC = observer(({ extra, title }) => { 12 | const prefix = usePrefix('data-source-setter') 13 | return ( 14 |
15 |
{title}
16 | {extra} 17 |
18 | ) 19 | }) 20 | -------------------------------------------------------------------------------- /formily/setters/src/components/DataSourceSetter/types.ts: -------------------------------------------------------------------------------- 1 | export interface IDataSourceItem { 2 | label?: '' 3 | value?: any 4 | children?: any[] 5 | } 6 | 7 | export interface INodeItem { 8 | key: string 9 | duplicateKey?: string 10 | map?: { label: string; value: any }[] 11 | children?: INodeItem[] 12 | } 13 | 14 | export interface ITreeDataSource { 15 | dataSource: INodeItem[] 16 | selectedKey: string 17 | } 18 | -------------------------------------------------------------------------------- /formily/setters/src/components/ReactionsSetter/types.ts: -------------------------------------------------------------------------------- 1 | export interface IReaction { 2 | dependencies?: { 3 | [key: string]: string 4 | } 5 | fulfill?: { 6 | state?: { 7 | [key: string]: string 8 | } 9 | schema?: { 10 | [key: string]: string 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /formily/setters/src/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './DataSourceSetter' 2 | export * from './ReactionsSetter' 3 | export * from './ValidatorSetter' 4 | -------------------------------------------------------------------------------- /formily/setters/src/index.ts: -------------------------------------------------------------------------------- 1 | import './locales' 2 | export * from './components' 3 | -------------------------------------------------------------------------------- /formily/setters/src/locales/index.ts: -------------------------------------------------------------------------------- 1 | import { GlobalRegistry } from '@pind/designable-core' 2 | import zhCN from './zh-CN' 3 | import enUS from './en-US' 4 | import koKR from './ko-KR' 5 | 6 | GlobalRegistry.registerDesignerLocales(zhCN, enUS, koKR) 7 | -------------------------------------------------------------------------------- /formily/setters/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./lib", 5 | "paths": { 6 | "@pind/designable-*": ["../../packages/*", "../../formily/*"] 7 | }, 8 | "declaration": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /formily/setters/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "include": ["./src/**/*.ts", "./src/**/*.tsx"], 4 | "exclude": ["./src/__tests__/*", "./esm/*", "./lib/*"] 5 | } 6 | -------------------------------------------------------------------------------- /formily/transformer/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | build 4 | __tests__ -------------------------------------------------------------------------------- /formily/transformer/README.md: -------------------------------------------------------------------------------- 1 | # @pind/designable-formily-transformer 2 | 3 | ### Install 4 | 5 | ```bash 6 | npm install --save @pind/designable-formily-transformer 7 | ``` 8 | -------------------------------------------------------------------------------- /formily/transformer/rollup.config.js: -------------------------------------------------------------------------------- 1 | import baseConfig from '../../scripts/rollup.base.js' 2 | 3 | export default baseConfig('designable.formily', 'Designable.Formily') 4 | -------------------------------------------------------------------------------- /formily/transformer/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./lib", 5 | "paths": { 6 | "@pind/designable-*": ["../../packages/*", "../../formily/*"] 7 | }, 8 | "declaration": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /formily/transformer/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "include": ["./src/**/*.ts", "./src/**/*.tsx"], 4 | "exclude": ["./src/__tests__/*", "./esm/*", "./lib/*"] 5 | } 6 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | const baseConfig = require('./scripts/jest.base') 2 | // jest.config.js 3 | 4 | // Note: If you are using babel version 7 you have to install babel-jest with 5 | // yarn add --dev babel-jest 'babel-core@^7.0.0-bridge' @babel/core 6 | 7 | module.exports = { 8 | ...baseConfig, 9 | } 10 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0-beta.6", 3 | "npmClient": "pnpm", 4 | "useWorkspaces": true, 5 | "npmClientArgs": [ 6 | "--ignore-engines" 7 | ], 8 | "command": { 9 | "version": { 10 | "forcePublish": true, 11 | "exact": true, 12 | "message": "chore(versions): 😊 publish %s" 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/core/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | build 4 | __tests__ -------------------------------------------------------------------------------- /packages/core/README.md: -------------------------------------------------------------------------------- 1 | # @pind/designable-core 2 | -------------------------------------------------------------------------------- /packages/core/rollup.config.js: -------------------------------------------------------------------------------- 1 | import baseConfig from '../../scripts/rollup.base.js' 2 | 3 | export default baseConfig('designable.core', 'Designable.Core') 4 | -------------------------------------------------------------------------------- /packages/core/src/drivers/MouseMoveDriver.ts: -------------------------------------------------------------------------------- 1 | import { EventDriver } from '@pind/designable-shared' 2 | import { Engine } from '../models/Engine' 3 | import { MouseMoveEvent } from '../events' 4 | export class MouseMoveDriver extends EventDriver { 5 | request = 0 6 | 7 | onMouseMove = (e: MouseEvent) => { 8 | this.request = requestAnimationFrame(() => { 9 | cancelAnimationFrame(this.request) 10 | this.dispatch( 11 | new MouseMoveEvent({ 12 | clientX: e.clientX, 13 | clientY: e.clientY, 14 | pageX: e.pageX, 15 | pageY: e.pageY, 16 | target: e.target, 17 | view: e.view, 18 | }) 19 | ) 20 | }) 21 | } 22 | 23 | attach() { 24 | this.addEventListener('mousemove', this.onMouseMove, { 25 | mode: 'onlyOne', 26 | }) 27 | } 28 | 29 | detach() { 30 | this.removeEventListener('mouseover', this.onMouseMove, { 31 | mode: 'onlyOne', 32 | }) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/core/src/drivers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './DragDropDriver' 2 | export * from './MouseClickDriver' 3 | export * from './MouseMoveDriver' 4 | export * from './ViewportResizeDriver' 5 | export * from './ViewportScrollDriver' 6 | export * from './KeyboardDriver' 7 | -------------------------------------------------------------------------------- /packages/core/src/effects/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useCursorEffect' 2 | export * from './useViewportEffect' 3 | export * from './useDragDropEffect' 4 | export * from './useResizeEffect' 5 | export * from './useSelectionEffect' 6 | export * from './useFreeSelectionEffect' 7 | export * from './useKeyboardEffect' 8 | export * from './useAutoScrollEffect' 9 | export * from './useWorkspaceEffect' 10 | export * from './useContentEditableEffect' 11 | export * from './useTranslateEffect' 12 | -------------------------------------------------------------------------------- /packages/core/src/effects/useKeyboardEffect.ts: -------------------------------------------------------------------------------- 1 | import { Engine } from '../models' 2 | import { KeyDownEvent, KeyUpEvent } from '../events' 3 | 4 | export const useKeyboardEffect = (engine: Engine) => { 5 | engine.subscribeTo(KeyDownEvent, (event) => { 6 | const keyboard = engine.keyboard 7 | if (!keyboard) return 8 | const workspace = 9 | engine.workbench.activeWorkspace || engine.workbench.currentWorkspace 10 | if (!workspace) return 11 | keyboard.handleKeyboard(event, workspace.getEventContext()) 12 | }) 13 | 14 | engine.subscribeTo(KeyUpEvent, (event) => { 15 | const keyboard = engine.keyboard 16 | if (!keyboard) return 17 | const workspace = 18 | engine.workbench.activeWorkspace || engine.workbench.currentWorkspace 19 | if (!workspace) return 20 | keyboard.handleKeyboard(event, workspace.getEventContext()) 21 | }) 22 | } 23 | -------------------------------------------------------------------------------- /packages/core/src/effects/useViewportEffect.ts: -------------------------------------------------------------------------------- 1 | import { Engine } from '../models' 2 | import { ViewportResizeEvent, ViewportScrollEvent } from '../events' 3 | 4 | export const useViewportEffect = (engine: Engine) => { 5 | engine.subscribeTo(ViewportResizeEvent, (event) => { 6 | const currentWorkspace = event?.context?.workspace 7 | if (!currentWorkspace) return 8 | const viewport = currentWorkspace.viewport 9 | const outline = currentWorkspace.outline 10 | if (viewport.matchViewport(event.data.target)) { 11 | viewport.digestViewport() 12 | } 13 | if (outline.matchViewport(event.data.target)) { 14 | outline.digestViewport() 15 | } 16 | }) 17 | engine.subscribeTo(ViewportScrollEvent, (event) => { 18 | const currentWorkspace = event?.context?.workspace 19 | if (!currentWorkspace) return 20 | const viewport = currentWorkspace.viewport 21 | const outline = currentWorkspace.outline 22 | if (viewport.matchViewport(event.data.target)) { 23 | viewport.digestViewport() 24 | } 25 | if (outline.matchViewport(event.data.target)) { 26 | outline.digestViewport() 27 | } 28 | }) 29 | } 30 | -------------------------------------------------------------------------------- /packages/core/src/effects/useWorkspaceEffect.ts: -------------------------------------------------------------------------------- 1 | import { Engine } from '../models' 2 | import { ICustomEvent } from '@pind/designable-shared' 3 | import { IEngineContext } from '../types' 4 | import { SelectNodeEvent } from '../events' 5 | 6 | export const useWorkspaceEffect = (engine: Engine) => { 7 | engine.subscribeWith>( 8 | [ 9 | 'append:node', 10 | 'insert:after', 11 | 'insert:before', 12 | 'insert:children', 13 | 'drag:node', 14 | 'drop:node', 15 | 'prepend:node', 16 | 'remove:node', 17 | 'select:node', 18 | 'update:children', 19 | 'wrap:node', 20 | 'update:node:props', 21 | ], 22 | (event) => { 23 | if (event.context?.workbench) { 24 | engine.workbench.setActiveWorkspace(event.context.workspace) 25 | } 26 | } 27 | ) 28 | engine.subscribeTo(SelectNodeEvent, (event) => { 29 | engine.workbench.eachWorkspace((workspace) => { 30 | if (workspace !== event.context.workspace) { 31 | workspace.operation.selection.clear() 32 | } 33 | }) 34 | }) 35 | } 36 | -------------------------------------------------------------------------------- /packages/core/src/events/cursor/DragMoveEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractCursorEvent } from './AbstractCursorEvent' 3 | 4 | export class DragMoveEvent extends AbstractCursorEvent implements ICustomEvent { 5 | type = 'drag:move' 6 | } 7 | -------------------------------------------------------------------------------- /packages/core/src/events/cursor/DragStartEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractCursorEvent } from './AbstractCursorEvent' 3 | 4 | export class DragStartEvent 5 | extends AbstractCursorEvent 6 | implements ICustomEvent 7 | { 8 | type = 'drag:start' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/cursor/DragStopEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractCursorEvent } from './AbstractCursorEvent' 3 | 4 | export class DragStopEvent extends AbstractCursorEvent implements ICustomEvent { 5 | type = 'drag:stop' 6 | } 7 | -------------------------------------------------------------------------------- /packages/core/src/events/cursor/MouseClickEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractCursorEvent } from './AbstractCursorEvent' 3 | 4 | export class MouseClickEvent 5 | extends AbstractCursorEvent 6 | implements ICustomEvent 7 | { 8 | type = 'mouse:click' 9 | } 10 | 11 | export class MouseDoubleClickEvent 12 | extends AbstractCursorEvent 13 | implements ICustomEvent 14 | { 15 | type = 'mouse:dblclick' 16 | } 17 | -------------------------------------------------------------------------------- /packages/core/src/events/cursor/MouseMoveEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractCursorEvent } from './AbstractCursorEvent' 3 | 4 | export class MouseMoveEvent 5 | extends AbstractCursorEvent 6 | implements ICustomEvent 7 | { 8 | type = 'mouse:move' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/cursor/index.ts: -------------------------------------------------------------------------------- 1 | export * from './DragMoveEvent' 2 | export * from './DragStartEvent' 3 | export * from './DragStopEvent' 4 | export * from './MouseClickEvent' 5 | export * from './MouseMoveEvent' 6 | -------------------------------------------------------------------------------- /packages/core/src/events/history/AbstractHistoryEvent.ts: -------------------------------------------------------------------------------- 1 | import { IEngineContext } from '../../types' 2 | 3 | export class AbstractHistoryEvent { 4 | data: any 5 | context: IEngineContext 6 | constructor(data: any) { 7 | this.data = data 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/history/HistoryGotoEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractHistoryEvent } from './AbstractHistoryEvent' 3 | 4 | export class HistoryGotoEvent 5 | extends AbstractHistoryEvent 6 | implements ICustomEvent 7 | { 8 | type = 'history:goto' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/history/HistoryPushEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractHistoryEvent } from './AbstractHistoryEvent' 3 | 4 | export class HistoryPushEvent 5 | extends AbstractHistoryEvent 6 | implements ICustomEvent 7 | { 8 | type = 'history:push' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/history/HistoryRedoEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractHistoryEvent } from './AbstractHistoryEvent' 3 | 4 | export class HistoryUndoEvent 5 | extends AbstractHistoryEvent 6 | implements ICustomEvent 7 | { 8 | type = 'history:undo' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/history/HistoryUndoEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractHistoryEvent } from './AbstractHistoryEvent' 3 | 4 | export class HistoryRedoEvent 5 | extends AbstractHistoryEvent 6 | implements ICustomEvent 7 | { 8 | type = 'history:redo' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/history/index.ts: -------------------------------------------------------------------------------- 1 | export * from './HistoryRedoEvent' 2 | export * from './HistoryUndoEvent' 3 | export * from './HistoryGotoEvent' 4 | export * from './HistoryPushEvent' 5 | -------------------------------------------------------------------------------- /packages/core/src/events/index.ts: -------------------------------------------------------------------------------- 1 | export * from './cursor' 2 | export * from './keyboard' 3 | export * from './mutation' 4 | export * from './viewport' 5 | export * from './workbench' 6 | export * from './history' 7 | -------------------------------------------------------------------------------- /packages/core/src/events/keyboard/KeyDownEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractKeyboardEvent } from './AbstractKeyboardEvent' 3 | 4 | export class KeyDownEvent 5 | extends AbstractKeyboardEvent 6 | implements ICustomEvent 7 | { 8 | type = 'key:down' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/keyboard/KeyUpEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractKeyboardEvent } from './AbstractKeyboardEvent' 3 | 4 | export class KeyUpEvent extends AbstractKeyboardEvent implements ICustomEvent { 5 | type = 'key:up' 6 | } 7 | -------------------------------------------------------------------------------- /packages/core/src/events/keyboard/index.ts: -------------------------------------------------------------------------------- 1 | export * from './KeyDownEvent' 2 | export * from './KeyUpEvent' 3 | -------------------------------------------------------------------------------- /packages/core/src/events/mutation/AbstractMutationNodeEvent.ts: -------------------------------------------------------------------------------- 1 | import { TreeNode } from '../../models' 2 | import { IEngineContext } from '../../types' 3 | 4 | export interface IMutationNodeEventData { 5 | //事件发生的数据源 6 | source: TreeNode | TreeNode[] 7 | //事件发生的目标对象 8 | target: TreeNode | TreeNode[] 9 | // 事件发生的来源对象 10 | originSourceParents?: TreeNode | TreeNode[] 11 | //扩展数据 12 | extra?: any 13 | } 14 | 15 | export class AbstractMutationNodeEvent { 16 | data: IMutationNodeEventData 17 | context: IEngineContext 18 | constructor(data: IMutationNodeEventData) { 19 | this.data = data 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/core/src/events/mutation/AppendNodeEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractMutationNodeEvent } from './AbstractMutationNodeEvent' 3 | 4 | export class AppendNodeEvent 5 | extends AbstractMutationNodeEvent 6 | implements ICustomEvent 7 | { 8 | type = 'append:node' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/mutation/CloneNodeEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractMutationNodeEvent } from './AbstractMutationNodeEvent' 3 | 4 | export class CloneNodeEvent 5 | extends AbstractMutationNodeEvent 6 | implements ICustomEvent 7 | { 8 | type = 'clone:node' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/mutation/DragNodeEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractMutationNodeEvent } from './AbstractMutationNodeEvent' 3 | 4 | export class DragNodeEvent 5 | extends AbstractMutationNodeEvent 6 | implements ICustomEvent 7 | { 8 | type = 'drag:node' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/mutation/DropNodeEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractMutationNodeEvent } from './AbstractMutationNodeEvent' 3 | 4 | export class DropNodeEvent 5 | extends AbstractMutationNodeEvent 6 | implements ICustomEvent 7 | { 8 | type = 'drop:node' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/mutation/FromNodeEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { ITreeNode, TreeNode } from '../../models' 3 | import { IEngineContext } from '../../types' 4 | 5 | export interface IFromNodeEventData { 6 | //事件发生的数据源 7 | source: ITreeNode 8 | //事件发生的目标对象 9 | target: TreeNode 10 | } 11 | 12 | export class FromNodeEvent implements ICustomEvent { 13 | type = 'from:node' 14 | data: IFromNodeEventData 15 | context: IEngineContext 16 | constructor(data: IFromNodeEventData) { 17 | this.data = data 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/core/src/events/mutation/HoverNodeEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractMutationNodeEvent } from './AbstractMutationNodeEvent' 3 | 4 | export class HoverNodeEvent 5 | extends AbstractMutationNodeEvent 6 | implements ICustomEvent 7 | { 8 | type = 'hover:node' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/mutation/InsertAfterEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractMutationNodeEvent } from './AbstractMutationNodeEvent' 3 | 4 | export class InsertAfterEvent 5 | extends AbstractMutationNodeEvent 6 | implements ICustomEvent 7 | { 8 | type = 'insert:after' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/mutation/InsertBeforeEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractMutationNodeEvent } from './AbstractMutationNodeEvent' 3 | 4 | export class InsertBeforeEvent 5 | extends AbstractMutationNodeEvent 6 | implements ICustomEvent 7 | { 8 | type = 'insert:before' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/mutation/InsertChildrenEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractMutationNodeEvent } from './AbstractMutationNodeEvent' 3 | 4 | export class InsertChildrenEvent 5 | extends AbstractMutationNodeEvent 6 | implements ICustomEvent 7 | { 8 | type = 'insert:children' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/mutation/PrependNodeEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractMutationNodeEvent } from './AbstractMutationNodeEvent' 3 | 4 | export class PrependNodeEvent 5 | extends AbstractMutationNodeEvent 6 | implements ICustomEvent 7 | { 8 | type = 'prepend:node' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/mutation/RemoveNodeEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractMutationNodeEvent } from './AbstractMutationNodeEvent' 3 | 4 | export class RemoveNodeEvent 5 | extends AbstractMutationNodeEvent 6 | implements ICustomEvent 7 | { 8 | type = 'remove:node' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/mutation/SelectNodeEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractMutationNodeEvent } from './AbstractMutationNodeEvent' 3 | 4 | export class SelectNodeEvent 5 | extends AbstractMutationNodeEvent 6 | implements ICustomEvent 7 | { 8 | type = 'select:node' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/mutation/UnSelectNodeEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractMutationNodeEvent } from './AbstractMutationNodeEvent' 3 | 4 | export class UnSelectNodeEvent 5 | extends AbstractMutationNodeEvent 6 | implements ICustomEvent 7 | { 8 | type = 'unselect:node' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/mutation/UpdateChildrenEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractMutationNodeEvent } from './AbstractMutationNodeEvent' 3 | 4 | export class UpdateChildrenEvent 5 | extends AbstractMutationNodeEvent 6 | implements ICustomEvent 7 | { 8 | type = 'update:children' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/mutation/UpdateNodePropsEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractMutationNodeEvent } from './AbstractMutationNodeEvent' 3 | 4 | export class UpdateNodePropsEvent 5 | extends AbstractMutationNodeEvent 6 | implements ICustomEvent 7 | { 8 | type = 'update:node:props' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/mutation/UserSelectNodeEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractMutationNodeEvent } from './AbstractMutationNodeEvent' 3 | 4 | export class SelectNodeEvent 5 | extends AbstractMutationNodeEvent 6 | implements ICustomEvent 7 | { 8 | type = 'user:select:node' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/mutation/WrapNodeEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractMutationNodeEvent } from './AbstractMutationNodeEvent' 3 | 4 | export class WrapNodeEvent 5 | extends AbstractMutationNodeEvent 6 | implements ICustomEvent 7 | { 8 | type = 'wrap:node' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/mutation/index.ts: -------------------------------------------------------------------------------- 1 | export * from './DragNodeEvent' 2 | export * from './DropNodeEvent' 3 | export * from './HoverNodeEvent' 4 | export * from './InsertAfterEvent' 5 | export * from './InsertBeforeEvent' 6 | export * from './InsertChildrenEvent' 7 | export * from './PrependNodeEvent' 8 | export * from './RemoveNodeEvent' 9 | export * from './SelectNodeEvent' 10 | export * from './UnSelectNodeEvent' 11 | export * from './UpdateChildrenEvent' 12 | export * from './UpdateNodePropsEvent' 13 | export * from './WrapNodeEvent' 14 | export * from './CloneNodeEvent' 15 | export * from './AppendNodeEvent' 16 | export * from './FromNodeEvent' 17 | -------------------------------------------------------------------------------- /packages/core/src/events/viewport/AbstractViewportEvent.ts: -------------------------------------------------------------------------------- 1 | import { IEngineContext } from '../../types' 2 | import { globalThisPolyfill } from '@pind/designable-shared' 3 | 4 | export interface IViewportEventData { 5 | scrollX: number 6 | scrollY: number 7 | width: number 8 | height: number 9 | view: Window 10 | innerWidth: number 11 | innerHeight: number 12 | target: EventTarget 13 | } 14 | 15 | export class AbstractViewportEvent { 16 | data: IViewportEventData 17 | context: IEngineContext 18 | constructor(data: IViewportEventData) { 19 | this.data = data || { 20 | scrollX: globalThisPolyfill.scrollX, 21 | scrollY: globalThisPolyfill.scrollY, 22 | width: globalThisPolyfill.innerWidth, 23 | height: globalThisPolyfill.innerHeight, 24 | innerWidth: globalThisPolyfill.innerWidth, 25 | innerHeight: globalThisPolyfill.innerHeight, 26 | view: globalThisPolyfill, 27 | target: globalThisPolyfill, 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/core/src/events/viewport/ViewportResizeEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractViewportEvent } from './AbstractViewportEvent' 3 | 4 | export class ViewportResizeEvent 5 | extends AbstractViewportEvent 6 | implements ICustomEvent 7 | { 8 | type = 'viewport:resize' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/viewport/ViewportScrollEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractViewportEvent } from './AbstractViewportEvent' 3 | 4 | export class ViewportScrollEvent 5 | extends AbstractViewportEvent 6 | implements ICustomEvent 7 | { 8 | type = 'viewport:scroll' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/viewport/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ViewportResizeEvent' 2 | export * from './ViewportScrollEvent' 3 | -------------------------------------------------------------------------------- /packages/core/src/events/workbench/AbstractWorkspaceEvent.ts: -------------------------------------------------------------------------------- 1 | import { Workspace } from '../../models' 2 | import { IEngineContext } from '../../types' 3 | 4 | export class AbstractWorkspaceEvent { 5 | data: Workspace 6 | context: IEngineContext 7 | constructor(data: Workspace) { 8 | this.data = data 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/core/src/events/workbench/AddWorkspaceEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractWorkspaceEvent } from './AbstractWorkspaceEvent' 3 | export class AddWorkspaceEvent 4 | extends AbstractWorkspaceEvent 5 | implements ICustomEvent 6 | { 7 | type = 'add:workspace' 8 | } 9 | -------------------------------------------------------------------------------- /packages/core/src/events/workbench/RemoveWorkspaceEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractWorkspaceEvent } from './AbstractWorkspaceEvent' 3 | 4 | export class RemoveWorkspaceEvent 5 | extends AbstractWorkspaceEvent 6 | implements ICustomEvent 7 | { 8 | type = 'remove:workspace' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/workbench/SwitchWorkspaceEvent.ts: -------------------------------------------------------------------------------- 1 | import { ICustomEvent } from '@pind/designable-shared' 2 | import { AbstractWorkspaceEvent } from './AbstractWorkspaceEvent' 3 | 4 | export class SwitchWorkspaceEvent 5 | extends AbstractWorkspaceEvent 6 | implements ICustomEvent 7 | { 8 | type = 'switch:workspace' 9 | } 10 | -------------------------------------------------------------------------------- /packages/core/src/events/workbench/index.ts: -------------------------------------------------------------------------------- 1 | export * from './AddWorkspaceEvent' 2 | export * from './RemoveWorkspaceEvent' 3 | export * from './SwitchWorkspaceEvent' 4 | -------------------------------------------------------------------------------- /packages/core/src/exports.ts: -------------------------------------------------------------------------------- 1 | export * from './externals' 2 | export * from './registry' 3 | export * from './models' 4 | export * from './events' 5 | export * from './types' 6 | -------------------------------------------------------------------------------- /packages/core/src/index.ts: -------------------------------------------------------------------------------- 1 | import * as Core from './exports' 2 | export * from './exports' 3 | import { globalThisPolyfill } from '@pind/designable-shared' 4 | 5 | if (globalThisPolyfill?.['Designable']?.['Core']) { 6 | try { 7 | if (module.exports) { 8 | module.exports = { 9 | __esModule: true, 10 | ...globalThisPolyfill['Designable']['Core'], 11 | } 12 | } 13 | } catch (error) {} 14 | } else { 15 | globalThisPolyfill['Designable'] = globalThisPolyfill['Designable'] || {} 16 | globalThisPolyfill['Designable'].Core = Core 17 | } 18 | -------------------------------------------------------------------------------- /packages/core/src/models/Hover.ts: -------------------------------------------------------------------------------- 1 | import { observable, define, action } from '@formily/reactive' 2 | import { Operation } from './Operation' 3 | import { TreeNode } from './TreeNode' 4 | import { HoverNodeEvent } from '../events' 5 | 6 | export interface IHoverProps { 7 | operation: Operation 8 | } 9 | 10 | export class Hover { 11 | node?: TreeNode 12 | operation?: Operation 13 | constructor(props?: IHoverProps) { 14 | this.operation = props?.operation 15 | this.makeObservable() 16 | } 17 | 18 | setHover(node?: TreeNode) { 19 | this.node = node 20 | this.trigger() 21 | } 22 | 23 | clear() { 24 | this.node = undefined 25 | } 26 | 27 | trigger() { 28 | if (this.operation && this.node) { 29 | return this.operation.dispatch( 30 | new HoverNodeEvent({ 31 | target: this.operation.tree, 32 | source: this.node, 33 | }) 34 | ) 35 | } 36 | } 37 | 38 | makeObservable() { 39 | define(this, { 40 | node: observable.ref, 41 | setHover: action, 42 | clear: action, 43 | }) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/core/src/models/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Engine' 2 | export * from './Screen' 3 | export * from './Cursor' 4 | export * from './Operation' 5 | export * from './Viewport' 6 | export * from './TreeNode' 7 | export * from './Workbench' 8 | export * from './Workspace' 9 | export * from './Selection' 10 | export * from './MoveHelper' 11 | export * from './Keyboard' 12 | export * from './Shortcut' 13 | export * from './History' 14 | -------------------------------------------------------------------------------- /packages/core/src/shortcuts/CursorSwitch.ts: -------------------------------------------------------------------------------- 1 | import { CursorType, KeyCode, Shortcut } from '../models' 2 | 3 | export const CursorSwitchSelection = new Shortcut({ 4 | codes: [KeyCode.Shift, KeyCode.S], 5 | handler(context) { 6 | const engine = context?.engine 7 | if (engine) { 8 | engine.cursor.setType(CursorType.Selection) 9 | } 10 | }, 11 | }) 12 | -------------------------------------------------------------------------------- /packages/core/src/shortcuts/MultiSelection.ts: -------------------------------------------------------------------------------- 1 | import { KeyCode, Shortcut } from '../models' 2 | 3 | export const SelectNodes = new Shortcut({ 4 | codes: [[KeyCode.Meta], [KeyCode.Control]], 5 | }) 6 | 7 | export const SelectSameTypeNodes = new Shortcut({ 8 | codes: [KeyCode.Shift], 9 | }) 10 | 11 | export const PreventCommandX = new Shortcut({ 12 | codes: [ 13 | [KeyCode.Meta, KeyCode.X], 14 | [KeyCode.Control, KeyCode.X], 15 | ], 16 | }) 17 | 18 | export const SelectAllNodes = new Shortcut({ 19 | codes: [ 20 | [KeyCode.Meta, KeyCode.A], 21 | [KeyCode.Control, KeyCode.A], 22 | ], 23 | handler(context) { 24 | const operation = context.workspace?.operation 25 | if (operation) { 26 | const tree = operation.tree 27 | const selection = operation.selection 28 | selection.batchSelect(tree.descendants) 29 | } 30 | }, 31 | }) 32 | -------------------------------------------------------------------------------- /packages/core/src/shortcuts/UndoRedo.ts: -------------------------------------------------------------------------------- 1 | import { KeyCode, Shortcut } from '../models' 2 | 3 | export const UndoMutation = new Shortcut({ 4 | codes: [ 5 | [KeyCode.Meta, KeyCode.Z], 6 | [KeyCode.Control, KeyCode.Z], 7 | ], 8 | handler(context) { 9 | const workspace = context?.workspace 10 | if (workspace) { 11 | workspace.history.undo() 12 | workspace.operation.hover.clear() 13 | } 14 | }, 15 | }) 16 | 17 | export const RedoMutation = new Shortcut({ 18 | codes: [ 19 | [KeyCode.Meta, KeyCode.Shift, KeyCode.Z], 20 | [KeyCode.Control, KeyCode.Shift, KeyCode.Z], 21 | ], 22 | handler(context) { 23 | const workspace = context?.workspace 24 | if (workspace) { 25 | workspace.history.redo() 26 | workspace.operation.hover.clear() 27 | } 28 | }, 29 | }) 30 | -------------------------------------------------------------------------------- /packages/core/src/shortcuts/index.ts: -------------------------------------------------------------------------------- 1 | export * from './MultiSelection' 2 | export * from './NodeMutation' 3 | export * from './UndoRedo' 4 | export * from './CursorSwitch' 5 | export * from './QuickSelection' 6 | -------------------------------------------------------------------------------- /packages/core/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./lib", 5 | "paths": { 6 | "@pind/designable-*": ["../*"] 7 | }, 8 | "declaration": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/core/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "include": ["./src/**/*.ts", "./src/**/*.tsx"], 4 | "exclude": ["./src/__tests__/*", "./esm/*", "./lib/*"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/react-sandbox/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | build 4 | __tests__ -------------------------------------------------------------------------------- /packages/react-sandbox/README.md: -------------------------------------------------------------------------------- 1 | # @pind/designable-react-sandbox 2 | -------------------------------------------------------------------------------- /packages/react-sandbox/rollup.config.js: -------------------------------------------------------------------------------- 1 | import baseConfig from '../../scripts/rollup.base.js' 2 | 3 | export default baseConfig('designable.react-sandbox', 'Designable.ReactSandbox') 4 | -------------------------------------------------------------------------------- /packages/react-sandbox/src/components/Sandbox.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { ISandboxProps, useSandbox } from '../hooks' 3 | 4 | export const Sandbox: React.FC = (props) => { 5 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 6 | const { cssAssets, jsAssets, scope, style, ...iframeProps } = props 7 | return ( 8 |