├── .changeset ├── README.md └── config.json ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitattributes ├── .github └── workflows │ ├── deploy-docs.yml │ └── npm-publish.yml ├── .gitignore ├── .husky ├── commit-msg └── pre-commit ├── .npmrc ├── .pnpmfile.cjs ├── .prettierignore ├── .standard.jsonc ├── .vscode └── settings.json ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── package.json ├── packages ├── adapter │ ├── .gitignore │ ├── CHANGELOG.md │ ├── README.md │ ├── __tests__ │ │ └── date-format.js │ ├── babel.config.js │ ├── bin │ │ └── wakeadmin-adapter-switch.mjs │ ├── package.json │ ├── scripts │ │ ├── postinstall.mjs │ │ ├── switch-cli.mjs │ │ └── utils.mjs │ ├── src │ │ ├── shared │ │ │ ├── date-format.js │ │ │ ├── index.js │ │ │ └── utils.js │ │ ├── v2 │ │ │ ├── README.md │ │ │ ├── components │ │ │ │ ├── Alert.js │ │ │ │ ├── Button.js │ │ │ │ ├── Cascader.js │ │ │ │ ├── Checkbox.js │ │ │ │ ├── Col.js │ │ │ │ ├── DatePicker.js │ │ │ │ ├── Dialog.js │ │ │ │ ├── Drawer.js │ │ │ │ ├── Dropdown.js │ │ │ │ ├── Empty.js │ │ │ │ ├── Form.js │ │ │ │ ├── Input.js │ │ │ │ ├── InputNumber.js │ │ │ │ ├── Message.js │ │ │ │ ├── MessageBox.js │ │ │ │ ├── Pagination.js │ │ │ │ ├── Popover.js │ │ │ │ ├── Progress.js │ │ │ │ ├── Radio.js │ │ │ │ ├── Rate.js │ │ │ │ ├── Row.js │ │ │ │ ├── Select.js │ │ │ │ ├── Slider.js │ │ │ │ ├── Steps.js │ │ │ │ ├── Switch.tsx │ │ │ │ ├── Table.js │ │ │ │ ├── TableColumn.js │ │ │ │ ├── Tabs.js │ │ │ │ ├── TimePicker.js │ │ │ │ ├── TimeSelect.js │ │ │ │ ├── Tooltip.js │ │ │ │ ├── Tree.js │ │ │ │ ├── TreeSelect.jsx │ │ │ │ ├── Upload.js │ │ │ │ ├── directives.js │ │ │ │ └── index.js │ │ │ ├── index.js │ │ │ └── utils │ │ │ │ ├── expose.ts │ │ │ │ ├── form-event.js │ │ │ │ ├── index.js │ │ │ │ └── regexp.js │ │ └── v3 │ │ │ ├── README.md │ │ │ ├── components │ │ │ ├── Alert.js │ │ │ ├── Button.js │ │ │ ├── Cascader.js │ │ │ ├── Checkbox.js │ │ │ ├── Col.js │ │ │ ├── DatePicker.js │ │ │ ├── Dialog.js │ │ │ ├── Drawer.js │ │ │ ├── Dropdown.js │ │ │ ├── Empty.js │ │ │ ├── Form.js │ │ │ ├── Input.js │ │ │ ├── InputNumber.js │ │ │ ├── Message.js │ │ │ ├── MessageBox.js │ │ │ ├── Pagination.js │ │ │ ├── Popover.js │ │ │ ├── Progress.js │ │ │ ├── Radio.js │ │ │ ├── Rate.js │ │ │ ├── Row.js │ │ │ ├── Select.js │ │ │ ├── Slider.js │ │ │ ├── Steps.js │ │ │ ├── Switch.js │ │ │ ├── Table.js │ │ │ ├── TableColumn.js │ │ │ ├── Tabs.js │ │ │ ├── TimePicker.js │ │ │ ├── TimeSelect.js │ │ │ ├── Tooltip.js │ │ │ ├── Tree.js │ │ │ ├── TreeSelect.js │ │ │ ├── Upload.js │ │ │ ├── directives.js │ │ │ └── index.js │ │ │ ├── index.js │ │ │ └── utils │ │ │ ├── form-event.js │ │ │ └── index.js │ ├── style │ │ ├── index.scss │ │ ├── share │ │ │ ├── _css-variable.scss │ │ │ └── index.scss │ │ ├── v2 │ │ │ ├── _switch.scss │ │ │ ├── _tree-select.scss │ │ │ └── index.scss │ │ └── v3 │ │ │ └── index.scss │ ├── tsconfig.common.json │ ├── tsconfig.json │ └── types │ │ ├── alert.d.ts │ │ ├── async-validator.d.ts │ │ ├── button.d.ts │ │ ├── cascader-panel.d.ts │ │ ├── cascader.d.ts │ │ ├── checkbox.d.ts │ │ ├── col.d.ts │ │ ├── common.d.ts │ │ ├── date-picker.d.ts │ │ ├── dialog.d.ts │ │ ├── drawer.d.ts │ │ ├── dropdown.d.ts │ │ ├── empty.d.ts │ │ ├── form.d.ts │ │ ├── index.d.ts │ │ ├── input-number.d.ts │ │ ├── input.d.ts │ │ ├── message-box.d.ts │ │ ├── message.d.ts │ │ ├── pagination.d.ts │ │ ├── popover.d.ts │ │ ├── progress.d.ts │ │ ├── radio.d.ts │ │ ├── rate.d.ts │ │ ├── row.d.ts │ │ ├── select.d.ts │ │ ├── shared.d.ts │ │ ├── slider.d.ts │ │ ├── steps.d.ts │ │ ├── switch.d.ts │ │ ├── table.d.ts │ │ ├── tabs.d.ts │ │ ├── time-picker.d.ts │ │ ├── time-select.d.ts │ │ ├── tooltip.d.ts │ │ ├── tree-select.d.ts │ │ ├── tree.d.ts │ │ ├── upload.d.ts │ │ └── utils.d.ts ├── components │ ├── CHANGELOG.md │ ├── README.md │ ├── bbt-lang │ │ └── bbt.csv │ ├── bbt.config.js │ ├── env.d.ts │ ├── locale │ │ ├── en.tr │ │ ├── th.tr │ │ ├── zh-Hant.tr │ │ └── zh.tr │ ├── package.json │ ├── src │ │ ├── atomic │ │ │ ├── define.ts │ │ │ ├── host.test.ts │ │ │ ├── host.ts │ │ │ ├── index.ts │ │ │ ├── registry.ts │ │ │ └── types.ts │ │ ├── builtin-atomic │ │ │ ├── README.md │ │ │ ├── avatar │ │ │ │ └── index.tsx │ │ │ ├── captcha │ │ │ │ └── index.tsx │ │ │ ├── cascader │ │ │ │ ├── cascader-lazy.tsx │ │ │ │ ├── cascader.tsx │ │ │ │ └── index.tsx │ │ │ ├── checkbox │ │ │ │ └── index.tsx │ │ │ ├── checkboxs │ │ │ │ └── index.tsx │ │ │ ├── currency │ │ │ │ └── index.tsx │ │ │ ├── date-range │ │ │ │ └── index.tsx │ │ │ ├── date-time-range │ │ │ │ └── index.tsx │ │ │ ├── date-time │ │ │ │ └── index.tsx │ │ │ ├── date │ │ │ │ └── index.tsx │ │ │ ├── file │ │ │ │ └── index.tsx │ │ │ ├── files │ │ │ │ ├── index.tsx │ │ │ │ ├── useTrigger.ts │ │ │ │ └── useUpload.ts │ │ │ ├── float │ │ │ │ └── index.tsx │ │ │ ├── image │ │ │ │ └── index.tsx │ │ │ ├── images │ │ │ │ └── index.tsx │ │ │ ├── index.ts │ │ │ ├── integer │ │ │ │ └── index.tsx │ │ │ ├── number │ │ │ │ └── index.tsx │ │ │ ├── progress │ │ │ │ └── index.tsx │ │ │ ├── radio │ │ │ │ └── index.tsx │ │ │ ├── rate │ │ │ │ └── index.tsx │ │ │ ├── select │ │ │ │ ├── index.ts │ │ │ │ ├── loader.ts │ │ │ │ ├── multi-select.tsx │ │ │ │ ├── select.tsx │ │ │ │ └── shared.tsx │ │ │ ├── slider-range │ │ │ │ └── index.tsx │ │ │ ├── slider │ │ │ │ └── index.tsx │ │ │ ├── switch │ │ │ │ └── index.tsx │ │ │ ├── text │ │ │ │ ├── email.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── password.tsx │ │ │ │ ├── phone.tsx │ │ │ │ ├── search.tsx │ │ │ │ ├── text.tsx │ │ │ │ ├── textarea.tsx │ │ │ │ ├── url.tsx │ │ │ │ └── utils.ts │ │ │ ├── time-range │ │ │ │ └── index.tsx │ │ │ ├── time-select │ │ │ │ └── index.tsx │ │ │ ├── time │ │ │ │ └── index.tsx │ │ │ └── tree-select │ │ │ │ └── index.tsx │ │ ├── collections │ │ │ ├── selection.test.ts │ │ │ └── selection.ts │ │ ├── enum │ │ │ ├── index.ts │ │ │ └── mouse.ts │ │ ├── fat-actions │ │ │ └── index.tsx │ │ ├── fat-atomic │ │ │ └── index.tsx │ │ ├── fat-configurable │ │ │ ├── configure.tsx │ │ │ ├── default.tsx │ │ │ ├── index.tsx │ │ │ └── types.ts │ │ ├── fat-drag-drop │ │ │ ├── design.md │ │ │ ├── dragRef.ts │ │ │ ├── dropListRef.ts │ │ │ ├── error.ts │ │ │ ├── event.ts │ │ │ ├── fat-drag-handler.tsx │ │ │ ├── fat-drag-item.tsx │ │ │ ├── fat-drop-list-group.tsx │ │ │ ├── fat-drop-list.tsx │ │ │ ├── index.ts │ │ │ ├── positionTrack.ts │ │ │ ├── strategy │ │ │ │ └── defaultStrategy.ts │ │ │ ├── style.ts │ │ │ ├── token.ts │ │ │ └── type.ts │ │ ├── fat-form-layout │ │ │ ├── README.md │ │ │ ├── define-fat-form-drawer.tsx │ │ │ ├── define-fat-form-modal.tsx │ │ │ ├── define-fat-form-page.tsx │ │ │ ├── fat-form-drawer.tsx │ │ │ ├── fat-form-modal.tsx │ │ │ ├── fat-form-page.tsx │ │ │ ├── fat-form-query.tsx │ │ │ ├── fat-form-steps │ │ │ │ ├── default-layout.tsx │ │ │ │ ├── define-fat-form-steps.tsx │ │ │ │ ├── fat-form-step.tsx │ │ │ │ ├── fat-form-steps-context.tsx │ │ │ │ ├── fat-form-steps.tsx │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── fat-form-tabs │ │ │ │ ├── default-layout.tsx │ │ │ │ ├── define-fat-form-tabs.tsx │ │ │ │ ├── fat-form-tab-pane.tsx │ │ │ │ ├── fat-form-tabs-context.tsx │ │ │ │ ├── fat-form-tabs.tsx │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ └── index.ts │ │ ├── fat-form │ │ │ ├── constants.ts │ │ │ ├── define-fat-form.tsx │ │ │ ├── fat-form-collection.tsx │ │ │ ├── fat-form-consumer.tsx │ │ │ ├── fat-form-group.tsx │ │ │ ├── fat-form-item.tsx │ │ │ ├── fat-form-section.tsx │ │ │ ├── fat-form-table.tsx │ │ │ ├── fat-form.tsx │ │ │ ├── hooks.ts │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ └── utils.ts │ │ ├── fat-i18n-content │ │ │ ├── README.md │ │ │ ├── builtin.tsx │ │ │ ├── constants.tsx │ │ │ ├── factory.tsx │ │ │ ├── index.tsx │ │ │ ├── provider.tsx │ │ │ ├── types.ts │ │ │ ├── utils.test.ts │ │ │ └── utils.ts │ │ ├── fat-icon │ │ │ └── index.tsx │ │ ├── fat-image-verification │ │ │ ├── README.md │ │ │ └── index.tsx │ │ ├── fat-import │ │ │ ├── README.md │ │ │ └── index.tsx │ │ ├── fat-layout │ │ │ ├── README.md │ │ │ ├── fat-card.tsx │ │ │ ├── fat-container.tsx │ │ │ ├── fat-content.tsx │ │ │ ├── fat-float-footer.tsx │ │ │ ├── index.ts │ │ │ └── utils.ts │ │ ├── fat-logic-tree │ │ │ ├── fat-logic-tree.tsx │ │ │ └── index.ts │ │ ├── fat-space │ │ │ ├── index.tsx │ │ │ └── types.ts │ │ ├── fat-switch │ │ │ └── index.tsx │ │ ├── fat-table-layout │ │ │ ├── define-fat-table-drawer.tsx │ │ │ ├── define-fat-table-modal.tsx │ │ │ ├── define-fat-table-select-modal.tsx │ │ │ ├── define-fat-table-select.tsx │ │ │ ├── fat-table-drawer.tsx │ │ │ ├── fat-table-modal.tsx │ │ │ ├── fat-table-select-modal.tsx │ │ │ ├── fat-table-select.tsx │ │ │ └── index.ts │ │ ├── fat-table │ │ │ ├── README.md │ │ │ ├── batch-actions.tsx │ │ │ ├── column-setting.tsx │ │ │ ├── column.tsx │ │ │ ├── constants.ts │ │ │ ├── define-table.tsx │ │ │ ├── fat-table.tsx │ │ │ ├── hooks.ts │ │ │ ├── index.ts │ │ │ ├── layouts │ │ │ │ ├── README.md │ │ │ │ ├── default.tsx │ │ │ │ └── index.ts │ │ │ ├── query.tsx │ │ │ ├── types-inner.ts │ │ │ ├── types.ts │ │ │ └── utils.ts │ │ ├── fat-text │ │ │ ├── fat-link.tsx │ │ │ ├── fat-text.tsx │ │ │ └── index.tsx │ │ ├── fat-tree-select │ │ │ └── index.tsx │ │ ├── fat-vnode │ │ │ └── index.tsx │ │ ├── hooks │ │ │ ├── index.ts │ │ │ ├── useAtomicRegistry.ts │ │ │ ├── useDevtoolsExpose.ts │ │ │ ├── useDisposer.ts │ │ │ ├── useI18n.ts │ │ │ ├── useLazyFalsy.ts │ │ │ ├── useLazyOptions.test.ts │ │ │ ├── useLazyOptions.ts │ │ │ ├── usePromise.ts │ │ │ ├── useRoute.ts │ │ │ ├── useUid.ts │ │ │ └── useUploadAccept.ts │ │ ├── i18n │ │ │ ├── index.ts │ │ │ ├── instance.test.ts │ │ │ └── instance.ts │ │ ├── index.ts │ │ ├── locale │ │ │ └── languages.ts │ │ ├── mapper │ │ │ ├── index.ts │ │ │ ├── numberToString.test.ts │ │ │ ├── numberToString.ts │ │ │ ├── toCommaSplitArray.test.ts │ │ │ ├── toCommaSplitArray.ts │ │ │ ├── toJSONString.test.ts │ │ │ └── toJSONString.ts │ │ ├── plugin.ts │ │ ├── test-dts │ │ │ ├── MyGenericComponent.tsx │ │ │ ├── define-form.test.d.tsx │ │ │ ├── define-table.test-d.tsx │ │ │ ├── fat-atomic.test-d.tsx │ │ │ ├── index.d.ts │ │ │ ├── jsx.test-d.tsx │ │ │ ├── utils-types.test-d.tsx │ │ │ └── vue-template │ │ │ │ ├── fat-form-steps.vue │ │ │ │ ├── fat-form.vue │ │ │ │ ├── fat-table.vue │ │ │ │ └── generic.vue │ │ └── utils │ │ │ ├── array.test.ts │ │ │ ├── array.ts │ │ │ ├── atom.ts │ │ │ ├── className.test.ts │ │ │ ├── className.ts │ │ │ ├── color.ts │ │ │ ├── date.test.ts │ │ │ ├── date.ts │ │ │ ├── document.ts │ │ │ ├── element.ts │ │ │ ├── event.ts │ │ │ ├── expose.ts │ │ │ ├── hmr.ts │ │ │ ├── index.ts │ │ │ ├── isDev.ts │ │ │ ├── loose-message.ts │ │ │ ├── merge-props.test.ts │ │ │ ├── merge-props.ts │ │ │ ├── misc.ts │ │ │ ├── number.ts │ │ │ ├── object.test.ts │ │ │ ├── object.ts │ │ │ ├── path.ts │ │ │ ├── placeholder.ts │ │ │ ├── portal.tsx │ │ │ ├── promise.ts │ │ │ ├── ref.ts │ │ │ ├── render.ts │ │ │ ├── string.test.ts │ │ │ ├── string.ts │ │ │ ├── style.test.ts │ │ │ ├── style.ts │ │ │ └── types.ts │ ├── style │ │ ├── README.md │ │ ├── _config.scss │ │ ├── _css-variables.scss │ │ ├── _fat-actions.scss │ │ ├── _fat-card.scss │ │ ├── _fat-container.scss │ │ ├── _fat-content.scss │ │ ├── _fat-drag-drop.scss │ │ ├── _fat-float-footer.scss │ │ ├── _fat-form-drawer.scss │ │ ├── _fat-form-query.scss │ │ ├── _fat-form-steps.scss │ │ ├── _fat-form.scss │ │ ├── _fat-i18n-content.scss │ │ ├── _fat-icon.scss │ │ ├── _fat-image-verification.scss │ │ ├── _fat-import.scss │ │ ├── _fat-logic-tree.scss │ │ ├── _fat-space.scss │ │ ├── _fat-table-default-layout.scss │ │ ├── _fat-table-drawer.scss │ │ ├── _fat-table-modal.scss │ │ ├── _fat-table-select.scss │ │ ├── _fat-table.scss │ │ ├── _fat-text.scss │ │ ├── _fat-utils.scss │ │ ├── _share.scss │ │ ├── _variables.scss │ │ ├── atomics │ │ │ ├── _avatar.scss │ │ │ ├── _captcha.scss │ │ │ ├── _cascader.scss │ │ │ ├── _checkbox.scss │ │ │ ├── _date.scss │ │ │ ├── _files.scss │ │ │ ├── _image.scss │ │ │ ├── _index.scss │ │ │ ├── _progress.scss │ │ │ ├── _radio.scss │ │ │ ├── _select.scss │ │ │ ├── _slider.scss │ │ │ └── _textarea.scss │ │ └── index.scss │ ├── tsconfig.build.common.json │ ├── tsconfig.build.json │ └── tsconfig.json ├── doc │ ├── CHANGELOG.md │ ├── docs │ │ ├── .vitepress │ │ │ ├── config.js │ │ │ └── theme │ │ │ │ ├── custom.css │ │ │ │ └── index.js │ │ ├── atomics │ │ │ ├── AllAtomics.vue │ │ │ ├── AsyncOptions.tsx │ │ │ ├── AsyncOptionsWithSwrv.tsx │ │ │ ├── all-atomics.demo.md │ │ │ ├── custom.md │ │ │ ├── faq.md │ │ │ ├── images │ │ │ │ ├── atomic-date.png │ │ │ │ ├── atomic-display.png │ │ │ │ ├── atomic-files.png │ │ │ │ ├── atomic-interaction.png │ │ │ │ ├── atomic-number.png │ │ │ │ ├── atomic-select.png │ │ │ │ ├── atomic-text.png │ │ │ │ └── atomic.png │ │ │ └── index.md │ │ ├── base │ │ │ ├── Atomics.vue │ │ │ ├── change-log.md │ │ │ ├── concepts.md │ │ │ ├── images │ │ │ │ ├── arch.png │ │ │ │ ├── content.png │ │ │ │ └── yida.png │ │ │ ├── install.md │ │ │ └── typescript.md │ │ ├── fat-configurable │ │ │ ├── images │ │ │ │ └── fat-configurable.png │ │ │ └── index.md │ │ ├── fat-drag-drop │ │ │ ├── advanced.md │ │ │ ├── demo │ │ │ │ ├── drag.vue │ │ │ │ ├── dragDelay.vue │ │ │ │ ├── dragDisabled.vue │ │ │ │ ├── dragHandler.vue │ │ │ │ ├── dragLimit.vue │ │ │ │ ├── dropList.vue │ │ │ │ ├── dropListConnectTo.vue │ │ │ │ ├── dropListGroup.vue │ │ │ │ ├── dropListGroupEnterPredicate.vue │ │ │ │ ├── dropListHorizontal.vue │ │ │ │ ├── dropListPlaceholder.vue │ │ │ │ ├── dropListPreview.vue │ │ │ │ └── images │ │ │ │ │ ├── 1.jpg │ │ │ │ │ ├── 2.jpg │ │ │ │ │ ├── 3.jpg │ │ │ │ │ ├── 4.jpg │ │ │ │ │ ├── 5.jpg │ │ │ │ │ └── 6.jpg │ │ │ ├── images │ │ │ │ ├── fat-drag-item-events.png │ │ │ │ ├── fat-drag-item-props.png │ │ │ │ ├── fat-drop-list-events.png │ │ │ │ └── fat-drop-list-props.png │ │ │ └── index.md │ │ ├── fat-form-layout │ │ │ ├── Drawer.vue │ │ │ ├── DrawerWithSteps.vue │ │ │ ├── Modal.vue │ │ │ ├── ModalWithTabs.vue │ │ │ ├── Page.tsx │ │ │ ├── PageComplex.tsx │ │ │ ├── Query.vue │ │ │ ├── QueryNonAlign.vue │ │ │ ├── Steps-Complex-Vertical.tsx │ │ │ ├── Steps-Complex.tsx │ │ │ ├── Steps-Loose.tsx │ │ │ ├── Steps.tsx │ │ │ ├── Steps.vue │ │ │ ├── Table.tsx │ │ │ ├── TableCustomCreate.tsx │ │ │ ├── TableSortable.module.scss │ │ │ ├── TableSortable.tsx │ │ │ ├── TableSortableDrag.tsx │ │ │ ├── TableSortableSimple.tsx │ │ │ ├── Tabs.tsx │ │ │ ├── Tabs.vue │ │ │ ├── drawer.md │ │ │ ├── images │ │ │ │ ├── fat-form-drawer.png │ │ │ │ ├── fat-form-modal.png │ │ │ │ ├── fat-form-page.png │ │ │ │ ├── fat-form-query.png │ │ │ │ ├── fat-form-step.png │ │ │ │ ├── fat-form-steps.png │ │ │ │ ├── fat-form-tab-pane.png │ │ │ │ ├── fat-form-table.png │ │ │ │ └── fat-form-tabs.png │ │ │ ├── modal.md │ │ │ ├── page-complex.demo.md │ │ │ ├── page.demo.md │ │ │ ├── page.md │ │ │ ├── query.md │ │ │ ├── steps-complex-vertical.demo.md │ │ │ ├── steps-complex.demo.md │ │ │ ├── steps-define.demo.md │ │ │ ├── steps-loose.demo.md │ │ │ ├── steps.demo.md │ │ │ ├── steps.md │ │ │ ├── table-custom-create.demo.md │ │ │ ├── table-sortable-drag.demo.md │ │ │ ├── table-sortable-simple.demo.md │ │ │ ├── table-sortable.demo.md │ │ │ ├── table.demo.md │ │ │ ├── table.md │ │ │ ├── tabs.demo.md │ │ │ └── tabs.md │ │ ├── fat-form │ │ │ ├── Center.vue │ │ │ ├── ChangePassword.vue │ │ │ ├── Consumer.vue │ │ │ ├── Convert.vue │ │ │ ├── CustomItemByConsumer.vue │ │ │ ├── CustomSubmitter.vue │ │ │ ├── CustomSubmitterReuse.vue │ │ │ ├── CustomSubmitterReuseJSX.tsx │ │ │ ├── DefineCompare.tsx │ │ │ ├── DefineDemo.tsx │ │ │ ├── DefineHelloWorld.tsx │ │ │ ├── Dynamic.vue │ │ │ ├── FatFormItemInitialValue.vue │ │ │ ├── FatFormItemProp.vue │ │ │ ├── Grid.vue │ │ │ ├── HozGroup.vue │ │ │ ├── InitialValue.vue │ │ │ ├── InitialValueSync.vue │ │ │ ├── Layout.vue │ │ │ ├── Message.vue │ │ │ ├── MixGroup.vue │ │ │ ├── Mode.vue │ │ │ ├── Request.vue │ │ │ ├── Section.vue │ │ │ ├── Transform.vue │ │ │ ├── UniGrid.vue │ │ │ ├── ValueMapSimple.tsx │ │ │ ├── VerGroup.vue │ │ │ ├── Width.vue │ │ │ ├── consumer.md │ │ │ ├── define.md │ │ │ ├── group.md │ │ │ ├── images │ │ │ │ ├── fat-form-api.png │ │ │ │ ├── fat-form-events.png │ │ │ │ ├── fat-form-group.png │ │ │ │ ├── fat-form-item.png │ │ │ │ ├── fat-form-methods.png │ │ │ │ ├── fat-form-section.png │ │ │ │ ├── fat-form.png │ │ │ │ ├── request.png │ │ │ │ ├── sub-form.png │ │ │ │ ├── submit.png │ │ │ │ └── width.png │ │ │ ├── index.md │ │ │ ├── item.md │ │ │ └── section.md │ │ ├── fat-layout │ │ │ ├── CardExtra.vue │ │ │ ├── CardGrid.vue │ │ │ ├── CardGridEscaped.vue │ │ │ ├── CardHeaderless.vue │ │ │ ├── ContainerSimple.vue │ │ │ ├── ContainerTab.vue │ │ │ ├── ContainerWithQuery.vue │ │ │ ├── ContainerWithQueryLegacy.vue │ │ │ ├── FloatFooter.vue │ │ │ ├── card.md │ │ │ ├── container.md │ │ │ ├── float-footer.demo.md │ │ │ ├── float-footer.md │ │ │ └── images │ │ │ │ ├── fat-card.png │ │ │ │ └── fat-container.png │ │ ├── fat-table-layout │ │ │ ├── Drawer.vue │ │ │ ├── Modal.vue │ │ │ ├── QuickTableSelect.tsx │ │ │ ├── TableSelectActions.tsx │ │ │ ├── TableSelectAllActions.tsx │ │ │ ├── TableSelectModal.vue │ │ │ ├── TableSelectModalCustomColumn.vue │ │ │ ├── TableSelectModel.vue │ │ │ ├── TableSelectMultiModal.vue │ │ │ ├── drawer.md │ │ │ ├── images │ │ │ │ ├── fat-table-drawer.png │ │ │ │ ├── fat-table-modal.png │ │ │ │ ├── fat-table-select-event.png │ │ │ │ ├── fat-table-select-methods.png │ │ │ │ └── fat-table-select-props.png │ │ │ ├── modal.md │ │ │ ├── quick-table-select.demo.md │ │ │ ├── table-select-actions.demo.md │ │ │ ├── table-select-all-actions.demo.md │ │ │ ├── table-select-modal.md │ │ │ ├── table-select-model.demo.md │ │ │ └── table-select.md │ │ ├── fat-table │ │ │ ├── Actions.tsx │ │ │ ├── ActionsForm.tsx │ │ │ ├── Atomics.tsx │ │ │ ├── BatchActions.tsx │ │ │ ├── CellLineControl.tsx │ │ │ ├── CustomCell.tsx │ │ │ ├── CustomTable.tsx │ │ │ ├── MergeFields.tsx │ │ │ ├── Quick.tsx │ │ │ ├── Setting.tsx │ │ │ ├── Slots.tsx │ │ │ ├── Switch.tsx │ │ │ ├── actions.demo.md │ │ │ ├── atomics.demo.md │ │ │ ├── batch-actions.demo.md │ │ │ ├── cell-line-control.demo.md │ │ │ ├── custom-cell.demo.md │ │ │ ├── custom-table.demo.md │ │ │ ├── define.md │ │ │ ├── faq.md │ │ │ ├── images │ │ │ │ ├── fat-table-api.png │ │ │ │ ├── fat-table-column.png │ │ │ │ ├── fat-table-events.png │ │ │ │ ├── fat-table-methods.png │ │ │ │ ├── fat-table-slots.png │ │ │ │ ├── query.png │ │ │ │ └── slots.png │ │ │ ├── index.md │ │ │ ├── merge-fields.demo.md │ │ │ ├── quick.demo.md │ │ │ ├── setting.demo.md │ │ │ ├── slots.demo.md │ │ │ └── switch.demo.md │ │ ├── index.md │ │ ├── other │ │ │ ├── DefineFatI18nContent.tsx │ │ │ ├── FatImportDemo.vue │ │ │ ├── Icon.vue │ │ │ ├── LogicTreeCustom.vue │ │ │ ├── LogicTreeDeep.vue │ │ │ ├── LogicTreeOperation.module.scss │ │ │ ├── LogicTreeOperation.tsx │ │ │ ├── LogicTreeWithFatForm.tsx │ │ │ ├── LogicTreeWithSortable.tsx │ │ │ ├── SpaceHoz.vue │ │ │ ├── SpaceVer.vue │ │ │ ├── VNodeRender.vue │ │ │ ├── fat-i18n-content.md │ │ │ ├── fat-import.demo.md │ │ │ ├── fat-import.md │ │ │ ├── i18n.md │ │ │ ├── icon.md │ │ │ ├── image-verification.md │ │ │ ├── images │ │ │ │ ├── fat-logic-tree.png │ │ │ │ ├── fat-space.png │ │ │ │ └── fat-text.png │ │ │ ├── logic-tree-custom.demo.md │ │ │ ├── logic-tree-deep.demo.md │ │ │ ├── logic-tree-operation.demo.md │ │ │ ├── logic-tree-with-fat-form.demo.md │ │ │ ├── logic-tree-with-sortable.demo.md │ │ │ ├── logic-tree.md │ │ │ ├── space.md │ │ │ ├── switch.md │ │ │ ├── text.md │ │ │ ├── tree-select.md │ │ │ └── vnode.md │ │ ├── public │ │ │ ├── group.png │ │ │ └── logo.png │ │ └── vite.config.ts │ ├── drawio │ │ ├── components.drawio │ │ ├── fat-form.drawio │ │ └── fat-table.drawio │ ├── env.d.ts │ ├── package.json │ ├── tsconfig.json │ └── xmind │ │ ├── atomics-date.xmind │ │ ├── atomics-display.xmind │ │ ├── atomics-files.xmind │ │ ├── atomics-interaction.xmind │ │ ├── atomics-number.xmind │ │ ├── atomics-select.xmind │ │ ├── atomics-text.xmind │ │ ├── atomics.xmind │ │ ├── components.xmind │ │ ├── fat-card.xmind │ │ ├── fat-configurable.xmind │ │ ├── fat-container.xmind │ │ ├── fat-drag-item-events.xmind │ │ ├── fat-drag-item-props.xmind │ │ ├── fat-drop-list-events.xmind │ │ ├── fat-drop-list-props.xmind │ │ ├── fat-form-api.xmind │ │ ├── fat-form-drawer.xmind │ │ ├── fat-form-events.xmind │ │ ├── fat-form-group.xmind │ │ ├── fat-form-item.xmind │ │ ├── fat-form-methods.xmind │ │ ├── fat-form-modal.xmind │ │ ├── fat-form-page.xmind │ │ ├── fat-form-query.xmind │ │ ├── fat-form-section.xmind │ │ ├── fat-form-step.xmind │ │ ├── fat-form-steps.xmind │ │ ├── fat-form-tab-pane.xmind │ │ ├── fat-form-table.xmind │ │ ├── fat-form-tabs.xmind │ │ ├── fat-form.xmind │ │ ├── fat-logic-tree.xmind │ │ ├── fat-space.xmind │ │ ├── fat-table-api.xmind │ │ ├── fat-table-column.xmind │ │ ├── fat-table-drawer.xmind │ │ ├── fat-table-events.xmind │ │ ├── fat-table-methods.xmind │ │ ├── fat-table-modal.xmind │ │ ├── fat-table-select-api.xmind │ │ ├── fat-table-select-events.xmind │ │ ├── fat-table-select-methods.xmind │ │ ├── fat-table-slots.xmind │ │ └── fat-text.xmind ├── playground-vite │ ├── .gitignore │ ├── .vscode │ │ └── extensions.json │ ├── CHANGELOG.md │ ├── README.md │ ├── index.html │ ├── package.json │ ├── public │ │ └── vite.svg │ ├── src │ │ ├── App.vue │ │ ├── assets │ │ │ └── vue.svg │ │ ├── components │ │ │ └── HelloWorld.vue │ │ ├── main.ts │ │ ├── style.css │ │ └── vite-env.d.ts │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── playground-volar │ ├── CHANGELOG.md │ ├── package.json │ ├── src │ │ └── generic.vue │ └── tsconfig.json ├── playground-vue2 │ ├── .dockerignore │ ├── .editorconfig │ ├── .eslintignore │ ├── .eslintrc.json │ ├── .gitattributes │ ├── .gitignore │ ├── .npmrc │ ├── .prettierignore │ ├── .standard.jsonc │ ├── CHANGELOG.md │ ├── Dockerfile │ ├── README.md │ ├── babel.config.js │ ├── env.d.ts │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ └── index.html │ ├── scripts │ │ ├── build.sh │ │ ├── check.sh │ │ ├── docker-build.js │ │ ├── docker-publish.js │ │ ├── rancher-update.js │ │ └── shared.js │ ├── src │ │ ├── App.vue │ │ ├── assets │ │ │ └── logo.png │ │ ├── components │ │ │ ├── ChildrenView.tsx │ │ │ └── HelloWorld.vue │ │ ├── i18n.ts │ │ ├── locales │ │ │ ├── en.tr │ │ │ ├── index.ts │ │ │ ├── th.tr │ │ │ ├── zh-Hant.tr │ │ │ └── zh.tr │ │ ├── main.ts │ │ ├── router │ │ │ └── index.ts │ │ └── views │ │ │ ├── AboutView.vue │ │ │ ├── ComponentTest.vue │ │ │ ├── FormLayoutView.vue │ │ │ ├── FormTabs.vue │ │ │ ├── FormView │ │ │ ├── Atomics.vue │ │ │ ├── DrawerDefine.tsx │ │ │ ├── Dynamic.tsx │ │ │ ├── FatAtomic.vue │ │ │ ├── FormDefine.tsx │ │ │ ├── FormItemWidth.tsx │ │ │ ├── FormLayout.vue │ │ │ ├── InitialValue.vue │ │ │ ├── Layout.vue │ │ │ ├── ModalDefine.tsx │ │ │ ├── Nested.vue │ │ │ ├── Transform.vue │ │ │ └── index.vue │ │ │ ├── HomeView.vue │ │ │ ├── LayoutView.vue │ │ │ ├── Steps-Complex-Vertical.vue │ │ │ ├── Steps-Complex.vue │ │ │ ├── Steps-Vertical.vue │ │ │ ├── Steps.vue │ │ │ ├── StepsDefine.tsx │ │ │ ├── TreeSelect.vue │ │ │ ├── child.vue │ │ │ ├── components │ │ │ ├── ByDeclareComponent.tsx │ │ │ ├── ByDefineComponent.tsx │ │ │ ├── BySPA.vue │ │ │ ├── ReferByJSX.tsx │ │ │ └── ReferBySPA.vue │ │ │ ├── drag.vue │ │ │ ├── imgs │ │ │ ├── 1.jpg │ │ │ ├── 2.jpg │ │ │ ├── 3.jpg │ │ │ ├── 4.jpg │ │ │ ├── 5.jpg │ │ │ └── 6.jpg │ │ │ └── tableSelect.vue │ ├── tsconfig.json │ └── vue.config.js ├── playground-vue3 │ ├── .dockerignore │ ├── .editorconfig │ ├── .gitattributes │ ├── .gitignore │ ├── .prettierignore │ ├── CHANGELOG.md │ ├── Dockerfile │ ├── README.md │ ├── babel.config.js │ ├── env.d.ts │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ └── index.html │ ├── scripts │ │ ├── build.sh │ │ ├── check.sh │ │ ├── docker-build.js │ │ ├── docker-publish.js │ │ ├── rancher-update.js │ │ └── shared.js │ ├── src │ │ ├── App.vue │ │ ├── assets │ │ │ └── logo.png │ │ ├── components │ │ │ ├── ChildrenView.tsx │ │ │ └── HelloWorld.vue │ │ ├── main.ts │ │ ├── router │ │ │ └── index.ts │ │ └── views │ │ │ ├── AboutView.vue │ │ │ ├── ComponentTest.vue │ │ │ ├── FormLayoutView.vue │ │ │ ├── FormView │ │ │ ├── Atomics.vue │ │ │ ├── InitialValue.vue │ │ │ ├── Layout.vue │ │ │ └── index.vue │ │ │ ├── HomeView.vue │ │ │ ├── child.vue │ │ │ ├── components │ │ │ ├── ByDeclareComponent.tsx │ │ │ ├── ByDefineComponent.tsx │ │ │ ├── BySPA.vue │ │ │ ├── ReferByJSX.tsx │ │ │ └── ReferBySPA.vue │ │ │ ├── drag.vue │ │ │ ├── fatTableModal.tsx │ │ │ ├── imgs │ │ │ ├── 1.jpg │ │ │ ├── 2.jpg │ │ │ ├── 3.jpg │ │ │ ├── 4.jpg │ │ │ ├── 5.jpg │ │ │ └── 6.jpg │ │ │ └── tableSelect.vue │ ├── tsconfig.json │ └── vue.config.js └── unplugin │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ ├── scripts │ └── postbuild.ts │ ├── src │ ├── esbuild.ts │ ├── index.ts │ ├── nuxt.ts │ ├── rollup.ts │ ├── types.ts │ ├── vite.ts │ └── webpack.ts │ ├── tsconfig.json │ └── tsup.config.ts ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── scripts ├── check.sh ├── generate-languages.js ├── publish-public.sh ├── publish.sh └── replace-export.js └── tsconfig.json /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@2.1.1/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "restricted", 8 | "baseBranch": "master", 9 | "updateInternalDependencies": "patch", 10 | "ignore": [] 11 | } 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | # 注意和 prettier-config-wk 保持一致 3 | root = true 4 | 5 | [*] 6 | indent_style = space 7 | indent_size = 2 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | quote_type = single 12 | end_of_line = lf 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | build 3 | coverage 4 | node_modules 5 | *.min.js 6 | vendors/ 7 | **/templates/ 8 | .eslintrc.js 9 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | *.png binary 3 | *.jpeg binary 4 | *.jpg binary 5 | *.doc binary 6 | *.docx binary 7 | *.xmind binary 8 | -------------------------------------------------------------------------------- /.github/workflows/npm-publish.yml: -------------------------------------------------------------------------------- 1 | name: publish 2 | 3 | on: 4 | workflow_dispatch: 5 | release: 6 | types: [created] 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v3 13 | # 安装 pnpm 14 | - uses: pnpm/action-setup@v2 15 | with: 16 | version: 8 17 | # 安装 Node 18 | - uses: actions/setup-node@v3 19 | with: 20 | node-version: 16 21 | - run: pnpm i -f 22 | - run: pnpm build 23 | - run: npm config set //registry.npmjs.org/:_authToken $NODE_AUTH_TOKEN 24 | env: 25 | NODE_AUTH_TOKEN: ${{secrets.npm_token}} 26 | - run: pnpm publish -r --no-git-checks --access public --registry=https://registry.npmjs.org/ 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | dist-ssr 5 | dist-node 6 | *.local 7 | .idea 8 | yarn-error.log 9 | *.Identifier 10 | env.local.json 11 | env.*.local.json 12 | .umi/** 13 | wk-docs-out 14 | wk-docs 15 | .tsBuildInfo* 16 | *.log 17 | .pnpm-store/ 18 | **/.vitepress/cache/ 19 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npm run local-check -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npmmirror.com/ 2 | 3 | shamefully-hoist=true 4 | enable-pre-post-scripts=true 5 | strict-peer-dependencies=false 6 | prefer-workspace-packages=true 7 | -------------------------------------------------------------------------------- /.pnpmfile.cjs: -------------------------------------------------------------------------------- 1 | function readPackage(pkg, context) { 2 | if (pkg.peerDependencies) { 3 | // 不处理 vue 相关 peerDependencies 手动修复 4 | const keys = Object.keys(pkg.peerDependencies); 5 | for (const key of keys) { 6 | if (key.startsWith('vue') || key.startsWith('@vue')) { 7 | delete pkg.peerDependencies[key]; 8 | } 9 | } 10 | } 11 | 12 | return pkg; 13 | } 14 | 15 | module.exports = { 16 | hooks: { 17 | readPackage, 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | dist 2 | coverage 3 | node_modules 4 | *.min.js 5 | vendors/ 6 | templates/ 7 | **/test-dts/**/*.vue 8 | *.yaml 9 | **/playground-volar/**/*.vue 10 | -------------------------------------------------------------------------------- /packages/adapter/.gitignore: -------------------------------------------------------------------------------- 1 | lib 2 | -------------------------------------------------------------------------------- /packages/adapter/README.md: -------------------------------------------------------------------------------- 1 | # 组件适配器 2 | 3 | [element-plus 与 element-ui 的区别](https://github.com/element-plus/element-plus/discussions/5658) 4 | -------------------------------------------------------------------------------- /packages/adapter/__tests__/date-format.js: -------------------------------------------------------------------------------- 1 | import { normalizeDateFormat } from '../src/shared/date-format'; 2 | 3 | test('normalizeDateFormat', () => { 4 | expect(normalizeDateFormat('YYYY-MM-DD HH:mm:ss')).toBe('yyyy-MM-dd HH:mm:SS'); 5 | expect(normalizeDateFormat('w x')).toBe('W timestamp'); 6 | }); 7 | -------------------------------------------------------------------------------- /packages/adapter/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [['@babel/preset-env', { targets: { node: 'current' } }]], 3 | }; 4 | -------------------------------------------------------------------------------- /packages/adapter/bin/wakeadmin-adapter-switch.mjs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import '../scripts/switch-cli.mjs'; 4 | -------------------------------------------------------------------------------- /packages/adapter/scripts/postinstall.mjs: -------------------------------------------------------------------------------- 1 | import { switchVersion, loadModule } from './utils.mjs'; 2 | 3 | const Vue = loadModule('vue'); 4 | 5 | if (!Vue || typeof Vue.version !== 'string') { 6 | console.warn('[wakeadmin adapter] Vue is not found. Please run "npm install vue" to install.'); 7 | } else if (Vue.version.startsWith('2.')) { 8 | switchVersion(2); 9 | } else if (Vue.version.startsWith('3.')) { 10 | switchVersion(3); 11 | } else { 12 | console.warn(`[wakeadmin adapter] Vue version v${Vue.version} is not suppported.`); 13 | } 14 | -------------------------------------------------------------------------------- /packages/adapter/scripts/switch-cli.mjs: -------------------------------------------------------------------------------- 1 | import { switchVersion } from './utils.mjs'; 2 | 3 | const version = process.argv[2]; 4 | 5 | if (version === '2') { 6 | switchVersion(2); 7 | console.log(`[vue-adapter] Switched for Vue 2`); 8 | } else { 9 | switchVersion(3); 10 | console.log(`[vue-adapter] Switched for Vue 3`); 11 | } 12 | -------------------------------------------------------------------------------- /packages/adapter/src/shared/date-format.js: -------------------------------------------------------------------------------- 1 | /** 2 | * element-ui 使用自定义的时间格式,而 element-plus 使用的是 dayjs 3 | */ 4 | 5 | /** 6 | * format 使用 dayjs 标准 7 | * @param {string} format 8 | */ 9 | export function normalizeDateFormat(format) { 10 | return format 11 | .replace(/(Y{2,4})/g, 'yyyy') 12 | .replace(/D/g, 'd') 13 | .replace(/w/g, 'W') 14 | .replace(/x/g, 'timestamp'); 15 | } 16 | -------------------------------------------------------------------------------- /packages/adapter/src/shared/index.js: -------------------------------------------------------------------------------- 1 | export * from './utils'; 2 | export * from './date-format'; 3 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/README.md: -------------------------------------------------------------------------------- 1 | # vue 2 & element-ui 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/Alert.js: -------------------------------------------------------------------------------- 1 | export { Alert } from 'element-ui'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/Button.js: -------------------------------------------------------------------------------- 1 | export { Button } from 'element-ui'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/Cascader.js: -------------------------------------------------------------------------------- 1 | export { Cascader, CascaderPanel } from 'element-ui'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/Checkbox.js: -------------------------------------------------------------------------------- 1 | export { Checkbox, CheckboxButton, CheckboxGroup } from 'element-ui'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/Col.js: -------------------------------------------------------------------------------- 1 | export { Col } from 'element-ui'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/Dialog.js: -------------------------------------------------------------------------------- 1 | import { Dialog as ElDialog } from 'element-ui'; 2 | import { h } from '@wakeadmin/h'; 3 | 4 | export const Dialog = { 5 | name: 'DialogAdapter', 6 | functional: true, 7 | render(_, context) { 8 | return h( 9 | ElDialog, 10 | Object.assign({}, context.data, { 11 | props: Object.assign({}, context.props, { 12 | visible: context.props.modelValue, 13 | }), 14 | on: Object.assign({}, context.listeners, { 15 | 'update:visible': context.listeners['update:modelValue'], 16 | }), 17 | attrs: undefined, 18 | }), 19 | context.slots() 20 | ); 21 | }, 22 | }; 23 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/Drawer.js: -------------------------------------------------------------------------------- 1 | import { Drawer as ElDrawer } from 'element-ui'; 2 | import { h } from '@wakeadmin/h'; 3 | 4 | export const Drawer = { 5 | name: 'DrawerAdapter', 6 | functional: true, 7 | render(_, context) { 8 | return h( 9 | ElDrawer, 10 | Object.assign({}, context.data, { 11 | props: Object.assign({}, context.props, { 12 | visible: context.props.modelValue, 13 | }), 14 | on: Object.assign({}, context.listeners, { 15 | 'update:visible': context.listeners['update:modelValue'], 16 | }), 17 | attrs: undefined, 18 | }), 19 | context.slots() 20 | ); 21 | }, 22 | }; 23 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/Dropdown.js: -------------------------------------------------------------------------------- 1 | export { Dropdown, DropdownMenu, DropdownItem } from 'element-ui'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/Empty.js: -------------------------------------------------------------------------------- 1 | export { Empty } from 'element-ui'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/Form.js: -------------------------------------------------------------------------------- 1 | export { Form, FormItem } from 'element-ui'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/Input.js: -------------------------------------------------------------------------------- 1 | export { Input } from 'element-ui'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/InputNumber.js: -------------------------------------------------------------------------------- 1 | export { InputNumber } from 'element-ui'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/Message.js: -------------------------------------------------------------------------------- 1 | export { Message } from 'element-ui'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/MessageBox.js: -------------------------------------------------------------------------------- 1 | export { MessageBox } from 'element-ui'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/Pagination.js: -------------------------------------------------------------------------------- 1 | export { Pagination } from 'element-ui'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/Popover.js: -------------------------------------------------------------------------------- 1 | import { h } from '@wakeadmin/h'; 2 | import { Popover as OPopover } from 'element-ui'; 3 | 4 | export const Popover = { 5 | name: 'PopoverAdapter', 6 | functional: true, 7 | render(_, context) { 8 | return h( 9 | OPopover, 10 | Object.assign({}, context.data, { 11 | props: Object.assign({}, context.props, { 12 | value: context.props.value ?? context.props.visible, 13 | }), 14 | on: Object.assign({}, context.listeners, { 15 | input: context.listeners.input ?? context.listeners['update:visible'], 16 | }), 17 | attrs: undefined, 18 | }), 19 | context.slots() 20 | ); 21 | }, 22 | }; 23 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/Progress.js: -------------------------------------------------------------------------------- 1 | export { Progress } from 'element-ui'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/Radio.js: -------------------------------------------------------------------------------- 1 | export { Radio, RadioButton, RadioGroup } from 'element-ui'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/Rate.js: -------------------------------------------------------------------------------- 1 | export { Rate } from 'element-ui'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/Row.js: -------------------------------------------------------------------------------- 1 | import { Row as ORow } from 'element-ui'; 2 | import { h } from '@wakeadmin/h'; 3 | 4 | export const Row = { 5 | functional: true, 6 | render(_, context) { 7 | return h( 8 | ORow, 9 | // 和 plus 保持一致, 默认为 flex 10 | Object.assign({}, context.data, { props: Object.assign({ type: 'flex' }, context.props), attrs: undefined }), 11 | context.slots() 12 | ); 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/Select.js: -------------------------------------------------------------------------------- 1 | export { Select, Option, OptionGroup } from 'element-ui'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/Slider.js: -------------------------------------------------------------------------------- 1 | export { Slider } from 'element-ui'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/Steps.js: -------------------------------------------------------------------------------- 1 | export { Steps, Step } from 'element-ui'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/Table.js: -------------------------------------------------------------------------------- 1 | export { Table } from 'element-ui'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/TableColumn.js: -------------------------------------------------------------------------------- 1 | export { TableColumn } from 'element-ui'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/Tabs.js: -------------------------------------------------------------------------------- 1 | export { Tabs, TabPane } from 'element-ui'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/TimeSelect.js: -------------------------------------------------------------------------------- 1 | import { TimeSelect as ElTimeSelect } from 'element-ui'; 2 | import { h } from '@wakeadmin/h'; 3 | 4 | // WARNING: 不支持 format 5 | export const TimeSelect = { 6 | functional: true, 7 | render(_, context) { 8 | const { start, end, step, minTime, maxTime, ...other } = context.props; 9 | 10 | // vue3 pickerOptions 提取到了全局 11 | other.pickerOptions = { 12 | ...other.pickerOptions, 13 | start, 14 | end, 15 | step, 16 | minTime, 17 | maxTime, 18 | }; 19 | 20 | return h(ElTimeSelect, Object.assign({}, context.data, { props: other, attrs: undefined }), context.slots()); 21 | }, 22 | }; 23 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/Tooltip.js: -------------------------------------------------------------------------------- 1 | export { Tooltip } from 'element-ui'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/Tree.js: -------------------------------------------------------------------------------- 1 | export { Tree } from 'element-ui'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/components/directives.js: -------------------------------------------------------------------------------- 1 | export const vLoading = 'loading'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/index.js: -------------------------------------------------------------------------------- 1 | export * from './components'; 2 | export * from './utils'; 3 | export * from '../shared'; 4 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/utils/expose.ts: -------------------------------------------------------------------------------- 1 | import { Ref } from '@wakeadmin/demi'; 2 | 3 | /** 4 | * 转发子组件 expose 的值 5 | * @param expose 6 | */ 7 | export function forwardExpose(exposed: Record, fields: string[] | readonly string[], ref: Ref) { 8 | for (const field of fields) { 9 | if (field in exposed) { 10 | continue; 11 | } 12 | 13 | Object.defineProperty(exposed, field, { 14 | configurable: true, 15 | enumerable: true, 16 | get() { 17 | return ref.value?.[field]; 18 | }, 19 | set(value) { 20 | if (ref.value != null) { 21 | ref.value[field] = value; 22 | } 23 | }, 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/utils/index.js: -------------------------------------------------------------------------------- 1 | export * from './form-event'; 2 | export * from './regexp'; 3 | export * from './expose'; 4 | -------------------------------------------------------------------------------- /packages/adapter/src/v2/utils/regexp.js: -------------------------------------------------------------------------------- 1 | export const escapeRegexpString = (value = '') => String(value).replace(/[|\\{}()[\]^$+*?.]/g, '\\$&'); 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/README.md: -------------------------------------------------------------------------------- 1 | # vue 3 & element-plus 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Alert.js: -------------------------------------------------------------------------------- 1 | export { ElAlert as Alert } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Button.js: -------------------------------------------------------------------------------- 1 | import { ElButton } from 'element-plus'; 2 | import { h } from '@wakeadmin/demi'; 3 | 4 | export const Button = (props, context) => { 5 | const overrideProps = {}; 6 | 7 | // element-plus type=text 已废弃,使用 link 代替 8 | // 不要使用 text! link 更接近旧版的 type=text 样式 9 | if (props.type === 'text') { 10 | overrideProps.type = 'primary'; 11 | overrideProps.link = true; 12 | } 13 | 14 | return h(ElButton, { ...props, ...overrideProps }, context.slots); 15 | }; 16 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Cascader.js: -------------------------------------------------------------------------------- 1 | export { ElCascader as Cascader, ElCascaderPanel as CascaderPanel } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Checkbox.js: -------------------------------------------------------------------------------- 1 | export { 2 | ElCheckbox as Checkbox, 3 | ElCheckboxGroup as CheckboxGroup, 4 | ElCheckboxButton as CheckboxButton, 5 | } from 'element-plus'; 6 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Col.js: -------------------------------------------------------------------------------- 1 | export { ElCol as Col } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/DatePicker.js: -------------------------------------------------------------------------------- 1 | export { ElDatePicker as DatePicker } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Dialog.js: -------------------------------------------------------------------------------- 1 | export { ElDialog as Dialog } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Drawer.js: -------------------------------------------------------------------------------- 1 | export { ElDrawer as Drawer } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Dropdown.js: -------------------------------------------------------------------------------- 1 | export { ElDropdown as Dropdown, ElDropdownMenu as DropdownMenu, ElDropdownItem as DropdownItem } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Empty.js: -------------------------------------------------------------------------------- 1 | export { ElEmpty as Empty } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Form.js: -------------------------------------------------------------------------------- 1 | export { ElForm as Form, ElFormItem as FormItem } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Input.js: -------------------------------------------------------------------------------- 1 | export { ElInput as Input } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/InputNumber.js: -------------------------------------------------------------------------------- 1 | export { ElInputNumber as InputNumber } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Message.js: -------------------------------------------------------------------------------- 1 | export { ElMessage as Message } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/MessageBox.js: -------------------------------------------------------------------------------- 1 | export { ElMessageBox as MessageBox } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Pagination.js: -------------------------------------------------------------------------------- 1 | export { ElPagination as Pagination } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Popover.js: -------------------------------------------------------------------------------- 1 | export { ElPopover as Popover } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Progress.js: -------------------------------------------------------------------------------- 1 | export { ElProgress as Progress } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Radio.js: -------------------------------------------------------------------------------- 1 | export { ElRadio as Radio, ElRadioButton as RadioButton, ElRadioGroup as RadioGroup } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Rate.js: -------------------------------------------------------------------------------- 1 | export { ElRate as Rate } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Row.js: -------------------------------------------------------------------------------- 1 | export { ElRow as Row } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Select.js: -------------------------------------------------------------------------------- 1 | export { ElSelect as Select, ElOption as Option, ElOptionGroup as OptionGroup } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Slider.js: -------------------------------------------------------------------------------- 1 | export { ElSlider as Slider } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Steps.js: -------------------------------------------------------------------------------- 1 | export { ElSteps as Steps, ElStep as Step } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Switch.js: -------------------------------------------------------------------------------- 1 | export { ElSwitch as Switch } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Table.js: -------------------------------------------------------------------------------- 1 | export { ElTable as Table } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/TableColumn.js: -------------------------------------------------------------------------------- 1 | export { ElTableColumn as TableColumn } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Tabs.js: -------------------------------------------------------------------------------- 1 | export { ElTabs as Tabs, ElTabPane as TabPane } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/TimePicker.js: -------------------------------------------------------------------------------- 1 | export { ElTimePicker as TimePicker } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/TimeSelect.js: -------------------------------------------------------------------------------- 1 | export { ElTimeSelect as TimeSelect } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Tooltip.js: -------------------------------------------------------------------------------- 1 | export { ElTooltip as Tooltip } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Tree.js: -------------------------------------------------------------------------------- 1 | export { ElTree as Tree } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/TreeSelect.js: -------------------------------------------------------------------------------- 1 | export { ElTreeSelect as TreeSelect } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/Upload.js: -------------------------------------------------------------------------------- 1 | // onPreview 事件测试 2 | export { ElUpload as Upload } from 'element-plus'; 3 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/components/directives.js: -------------------------------------------------------------------------------- 1 | export { vLoading } from 'element-plus'; 2 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/index.js: -------------------------------------------------------------------------------- 1 | export * from './components'; 2 | export * from './utils'; 3 | export * from '../shared'; 4 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/utils/form-event.js: -------------------------------------------------------------------------------- 1 | import { formItemContextKey } from 'element-plus'; 2 | import { inject } from '@wakeadmin/demi'; 3 | 4 | /** 5 | * 触发 form-item 验证。用于自定义表单组件 6 | * @returns 7 | */ 8 | export function useFormItemValidate() { 9 | const formItem = inject(formItemContextKey, null); 10 | 11 | /** 12 | * @param {'change' | 'blur'} event 13 | */ 14 | return function validate(event) { 15 | formItem?.validate?.(event).catch(() => { 16 | // ignored 17 | }); 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /packages/adapter/src/v3/utils/index.js: -------------------------------------------------------------------------------- 1 | export * from './form-event'; 2 | -------------------------------------------------------------------------------- /packages/adapter/style/index.scss: -------------------------------------------------------------------------------- 1 | @forward '../lib/index'; 2 | -------------------------------------------------------------------------------- /packages/adapter/style/share/_css-variable.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * 获取 css 变量 3 | */ 4 | @function getCSSVar($name, $fallback: '') { 5 | @if $fallback == '' { 6 | @return var(--#{$name}); 7 | } @else { 8 | @return var(--#{$name}, #{$fallback}); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/adapter/style/share/index.scss: -------------------------------------------------------------------------------- 1 | @forward './css-variable'; 2 | -------------------------------------------------------------------------------- /packages/adapter/style/v2/_tree-select.scss: -------------------------------------------------------------------------------- 1 | .ad-tree-select { 2 | &__tree { 3 | .el-select-dropdown__item { 4 | height: 20px; 5 | line-height: 20px; 6 | padding-left: 0; 7 | flex: 1; 8 | background: transparent !important; 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/adapter/style/v2/index.scss: -------------------------------------------------------------------------------- 1 | @forward './switch'; 2 | @forward './tree-select'; 3 | -------------------------------------------------------------------------------- /packages/adapter/style/v3/index.scss: -------------------------------------------------------------------------------- 1 | // nothing here... 2 | -------------------------------------------------------------------------------- /packages/adapter/tsconfig.common.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./dist/common", 5 | "module": "CommonJS" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/adapter/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./dist" /* Redirect output structure to the directory. */, 5 | "allowJs": true, 6 | "jsx": "react-jsx", 7 | "jsxImportSource": "@wakeadmin/h", 8 | "declaration": false, 9 | "declarationMap": false, 10 | "rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, 11 | "noEmit": false, 12 | "target": "ES2016" 13 | }, 14 | "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.tsx", "src/**/*.ts"] 15 | } 16 | -------------------------------------------------------------------------------- /packages/adapter/types/alert.d.ts: -------------------------------------------------------------------------------- 1 | export interface AlertProps { 2 | /** Title */ 3 | title?: string; 4 | 5 | /** Component type */ 6 | type?: 'success' | 'warning' | 'info' | 'error'; 7 | 8 | /** Descriptive text. Can also be passed with the default slot */ 9 | description?: string; 10 | 11 | /** If closable or not */ 12 | closable?: boolean; 13 | 14 | /** whether to center the text */ 15 | center?: boolean; 16 | 17 | /** Customized close button text */ 18 | closeText?: string; 19 | 20 | /** If a type icon is displayed */ 21 | showIcon?: boolean; 22 | 23 | /** Choose effect */ 24 | effect?: 'dark' | 'light'; 25 | 26 | onClose?: () => void; 27 | } 28 | 29 | export const Alert: (props: AlertProps) => any; 30 | -------------------------------------------------------------------------------- /packages/adapter/types/button.d.ts: -------------------------------------------------------------------------------- 1 | export interface ButtonProps { 2 | size?: string; 3 | disabled?: boolean; 4 | type?: 'default' | 'primary' | 'success' | 'warning' | 'info' | 'danger' | 'text'; 5 | icon?: any; 6 | nativeType?: 'button' | 'submit' | 'reset'; 7 | loading?: boolean; 8 | loadingIcon?: any; 9 | plain?: boolean; 10 | text?: boolean; 11 | link?: boolean; 12 | bg?: boolean; 13 | autofocus?: boolean; 14 | round?: boolean; 15 | circle?: boolean; 16 | color?: string; 17 | dark?: boolean; 18 | autoInsertSpace?: boolean; 19 | onClick?: ((evt: MouseEvent) => any) | undefined; 20 | } 21 | export const Button: (props: ButtonProps) => any; 22 | -------------------------------------------------------------------------------- /packages/adapter/types/common.d.ts: -------------------------------------------------------------------------------- 1 | import { CSSProperties } from '@wakeadmin/demi'; 2 | 3 | export type ClassValue = string | { [key: string]: any } | ClassValue[]; 4 | export type StyleValue = string | CSSProperties | StyleValue[]; 5 | 6 | export type LooseClassValue = string | undefined | { [key: string]: any } | LooseClassValue[]; 7 | export type LooseStyleValue = string | undefined | CSSProperties | LooseStyleValue[]; 8 | 9 | export interface CommonProps { 10 | class?: ClassValue; 11 | style?: StyleValue; 12 | } 13 | 14 | /** 15 | * 组件key 的类型 16 | */ 17 | export type KeyType = string | number | symbol; 18 | -------------------------------------------------------------------------------- /packages/adapter/types/empty.d.ts: -------------------------------------------------------------------------------- 1 | export interface EmptyProps { 2 | image?: string; 3 | 4 | /* image size (width) */ 5 | imageSize?: number; 6 | 7 | /* description */ 8 | description?: string; 9 | } 10 | export const Empty = (props: EmptyProps) => any; 11 | -------------------------------------------------------------------------------- /packages/adapter/types/row.d.ts: -------------------------------------------------------------------------------- 1 | /** Horizontal alignment of flex layout */ 2 | export type HorizontalAlignment = 'start' | 'end' | 'center' | 'space-around' | 'space-between'; 3 | 4 | /** vertical alignment of flex layout */ 5 | export type VertialAlignment = 'top' | 'middle' | 'bottom'; 6 | 7 | export interface RowProps { 8 | /** Grid spacing */ 9 | gutter?: number; 10 | 11 | /** Horizontal alignment of flex layout */ 12 | justify?: HorizontalAlignment; 13 | 14 | /** Vertical alignment of flex layout */ 15 | align?: VertialAlignment; 16 | 17 | /** Custom element tag */ 18 | tag?: string; 19 | } 20 | 21 | export const Row: (props: RowProps) => any; 22 | -------------------------------------------------------------------------------- /packages/adapter/types/shared.d.ts: -------------------------------------------------------------------------------- 1 | import { Ref } from '@wakeadmin/demi'; 2 | 3 | export type Size = 'small' | 'default' | 'large'; 4 | 5 | export function size(s?: Size): string; 6 | 7 | /** 8 | * @deprecated use useVModel 9 | * @param value 10 | * @param onChange 11 | */ 12 | export function model(value: T, onChange: (value: T) => void): any; 13 | 14 | export function useVModel(props: { value?: T; onChange?: (value: T) => void }): Ref; 15 | 16 | export const vLoading: any; 17 | 18 | export type VNodeChildAtom = JSX.Element | string | number | boolean | null | undefined | void; 19 | 20 | export type VNodeArrayChildren = (VNodeArrayChildren | VNodeChildAtom)[]; 21 | 22 | export type VNodeChild = VNodeChildAtom | VNodeArrayChildren; 23 | -------------------------------------------------------------------------------- /packages/adapter/types/tree-select.d.ts: -------------------------------------------------------------------------------- 1 | import { TreeProps, TreeMethods, TreeData } from './tree'; 2 | import { SelectProps, SelectMethods } from './select'; 3 | 4 | export interface TreeSelectData extends TreeData { 5 | value: any; 6 | children?: TreeSelectData[]; 7 | } 8 | 9 | export interface TreeSelectProps extends TreeProps, SelectProps {} 10 | 11 | export interface TreeSelectMethods extends TreeMethods, SelectMethods {} 12 | 13 | export const TreeSelect: ( 14 | props: TreeSelectProps 15 | ) => any; 16 | -------------------------------------------------------------------------------- /packages/adapter/types/utils.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 触发 form-item 验证。用于自定义表单组件 3 | * @returns 4 | */ 5 | export function useFormItemValidate(): (event: 'change' | 'blur') => void; 6 | -------------------------------------------------------------------------------- /packages/components/README.md: -------------------------------------------------------------------------------- 1 | # 组件库实现 2 | -------------------------------------------------------------------------------- /packages/components/bbt.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | langs: ['zh', 'zh-Hant', 'en', 'th'], 3 | resourcePath: './', 4 | src: './', 5 | exclude: ['dist'], 6 | __version: '1.1.4', 7 | }; 8 | -------------------------------------------------------------------------------- /packages/components/env.d.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/components/env.d.ts -------------------------------------------------------------------------------- /packages/components/src/atomic/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types'; 2 | export * from './registry'; 3 | export * from './define'; 4 | -------------------------------------------------------------------------------- /packages/components/src/builtin-atomic/README.md: -------------------------------------------------------------------------------- 1 | # 内置原件 2 | -------------------------------------------------------------------------------- /packages/components/src/builtin-atomic/cascader/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './cascader-lazy'; 2 | export * from './cascader'; 3 | -------------------------------------------------------------------------------- /packages/components/src/builtin-atomic/files/useTrigger.ts: -------------------------------------------------------------------------------- 1 | import { ref } from '@wakeadmin/demi'; 2 | 3 | export function useTrigger() { 4 | const r = ref(0); 5 | return { 6 | track: () => r.value, 7 | trigger: () => r.value++, 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /packages/components/src/builtin-atomic/select/index.ts: -------------------------------------------------------------------------------- 1 | export * from './multi-select'; 2 | export * from './select'; 3 | export * from './shared'; 4 | -------------------------------------------------------------------------------- /packages/components/src/builtin-atomic/select/loader.ts: -------------------------------------------------------------------------------- 1 | import { computed } from '@wakeadmin/demi'; 2 | 3 | import { useLazyOptions } from '../../hooks'; 4 | import { memoizeTask } from '../../atomic/host'; 5 | 6 | import { ASelectOption } from './shared'; 7 | import { NoopArray } from '@wakeadmin/utils'; 8 | 9 | export function useOptions(props: { options?: ASelectOption[] | (() => Promise) }) { 10 | const options = 11 | typeof props.options === 'function' ? memoizeTask(props.options) : computed(() => props.options ?? NoopArray); 12 | 13 | const { loading, value } = useLazyOptions(options, []); 14 | 15 | return { loading, options: value }; 16 | } 17 | -------------------------------------------------------------------------------- /packages/components/src/builtin-atomic/select/shared.tsx: -------------------------------------------------------------------------------- 1 | import { OptionProps } from '@wakeadmin/element-adapter'; 2 | 3 | import { Color } from '../../utils'; 4 | 5 | export { normalizeColor } from '../../utils'; 6 | 7 | export interface ASelectOption extends OptionProps { 8 | /** 9 | * 颜色 10 | */ 11 | color?: Color; 12 | } 13 | -------------------------------------------------------------------------------- /packages/components/src/builtin-atomic/text/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './text'; 2 | export * from './password'; 3 | export * from './search'; 4 | export * from './url'; 5 | export * from './textarea'; 6 | export * from './email'; 7 | export * from './phone'; 8 | -------------------------------------------------------------------------------- /packages/components/src/builtin-atomic/text/utils.ts: -------------------------------------------------------------------------------- 1 | export function isEmpty(value: any) { 2 | return value == null || value === ''; 3 | } 4 | -------------------------------------------------------------------------------- /packages/components/src/enum/index.ts: -------------------------------------------------------------------------------- 1 | export * from './mouse'; -------------------------------------------------------------------------------- /packages/components/src/enum/mouse.ts: -------------------------------------------------------------------------------- 1 | export const enum MouseEventButton { 2 | /** 3 | * 主按键,通常指鼠标左键或默认值 4 | * 5 | * 如 document.getElementById('a').click() 这样触发就会是默认值 6 | * */ 7 | 'Main' = 0, 8 | /** 9 | * 鼠辅助按键,通常指鼠标滚轮中键 10 | * */ 11 | 'Aid' = 1, 12 | /** 13 | * 次按键,通常指鼠标右键 14 | * */ 15 | 'Sub' = 2, 16 | /** 17 | * 第四个按钮,通常指浏览器后退按钮 18 | * */ 19 | 'Back' = 3, 20 | /** 21 | * 第五个按钮,通常指浏览器的前进按钮 22 | * */ 23 | 'Go' = 4, 24 | } 25 | -------------------------------------------------------------------------------- /packages/components/src/fat-configurable/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * 全局配置组件库的行为 3 | */ 4 | export * from './types'; 5 | export * from './configure'; 6 | -------------------------------------------------------------------------------- /packages/components/src/fat-drag-drop/design.md: -------------------------------------------------------------------------------- 1 | ## 实现 2 | 3 | 基本上参考 `@angular/cdk` 的`drag-drop`的流程 4 | 5 | - `fat-drag-handler` 6 | 7 | ~~针对拖拽响应元素 这里采用指令的方式进行处理~~ 8 | 9 | ~~如果使用组件的模式 会额外进行一层对应的包装 完全没有任何意义~~ 10 | 11 | 垃圾 Vue 12 | 13 | 指令模式无法获取其拖拽上下文 14 | 15 | 通过组件进行封装 16 | 17 | - `fat-drag-placeholder` 以及 `fat-drag-preview` 18 | 19 | 这两个采用`slot`模式是为了方便固定其上下文以及行为统一 20 | 21 | 一开始设计上是直接通过组件内部状态进行控制, ~~但是考虑到指令的实现模式~~,最终决定统一实现模式。在内部会通过`Portal`进行`slot`或者是`render`的实例挂载; 22 | -------------------------------------------------------------------------------- /packages/components/src/fat-drag-drop/error.ts: -------------------------------------------------------------------------------- 1 | export class FatDragDropError extends Error { 2 | constructor(message: string) { 3 | super(`[fat-drag error]: ${message}`); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /packages/components/src/fat-drag-drop/index.ts: -------------------------------------------------------------------------------- 1 | export * from './type'; 2 | export * from './fat-drag-item'; 3 | export * from './fat-drag-handler'; 4 | export * from './fat-drop-list'; 5 | export * from './fat-drop-list-group'; 6 | export * from './token'; 7 | -------------------------------------------------------------------------------- /packages/components/src/fat-drag-drop/token.ts: -------------------------------------------------------------------------------- 1 | import { InjectionKey } from '@wakeadmin/demi'; 2 | import { DropListRef } from './dropListRef'; 3 | import { DragRef } from './dragRef'; 4 | import { DragRefEvents } from './type'; 5 | 6 | export const FatDropContainerToken: InjectionKey<{ 7 | instance: DropListRef; 8 | emits(eventName: K, ...args: Parameters): void; 9 | renderPlaceholder?: (...args: any) => any; 10 | renderPreview?: (...args: any) => any; 11 | }> = Symbol('FatDropContainer'); 12 | 13 | export const FatDragRefToken: InjectionKey = Symbol('FatDragRef'); 14 | 15 | export const FatDropListGroupToken: InjectionKey> = Symbol('FatDropListGroup'); 16 | -------------------------------------------------------------------------------- /packages/components/src/fat-form-layout/README.md: -------------------------------------------------------------------------------- 1 | # 常见的表单应用场景 2 | -------------------------------------------------------------------------------- /packages/components/src/fat-form-layout/fat-form-steps/index.ts: -------------------------------------------------------------------------------- 1 | export * from './fat-form-steps'; 2 | export * from './fat-form-step'; 3 | export * from './types'; 4 | export * from './define-fat-form-steps'; 5 | -------------------------------------------------------------------------------- /packages/components/src/fat-form-layout/fat-form-tabs/default-layout.tsx: -------------------------------------------------------------------------------- 1 | import { FatFloatFooter } from '../../fat-layout'; 2 | import { FatFormTabsLayout } from './types'; 3 | 4 | export const DEFAULT_LAYOUT: FatFormTabsLayout = renderers => { 5 | return ( 6 |
7 | {renderers.renderTabs()} 8 | {!!renderers.renderSubmitter && {renderers.renderSubmitter()}} 9 |
10 | ); 11 | }; 12 | -------------------------------------------------------------------------------- /packages/components/src/fat-form-layout/fat-form-tabs/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types'; 2 | export * from './fat-form-tabs'; 3 | export * from './fat-form-tab-pane'; 4 | export * from './define-fat-form-tabs'; 5 | -------------------------------------------------------------------------------- /packages/components/src/fat-form-layout/index.ts: -------------------------------------------------------------------------------- 1 | export * from './fat-form-drawer'; 2 | export * from './fat-form-modal'; 3 | export * from './fat-form-page'; 4 | export * from './fat-form-query'; 5 | export * from './fat-form-steps'; 6 | export * from './fat-form-tabs'; 7 | 8 | export * from './define-fat-form-drawer'; 9 | export * from './define-fat-form-modal'; 10 | export * from './define-fat-form-page'; 11 | -------------------------------------------------------------------------------- /packages/components/src/fat-form/fat-form-collection.tsx: -------------------------------------------------------------------------------- 1 | import { declareComponent, declareProps } from '@wakeadmin/h'; 2 | import { provideFatFormCollection } from './hooks'; 3 | import { FatFormCollection } from './types'; 4 | 5 | export const FatFormCollectionProvider = declareComponent({ 6 | name: 'FatFormItemCollection', 7 | props: declareProps<{ value: FatFormCollection }>({ 8 | value: null, 9 | }), 10 | setup(props, { slots }) { 11 | provideFatFormCollection(props.value); 12 | 13 | return () => { 14 | return slots.default?.(); 15 | }; 16 | }, 17 | }); 18 | -------------------------------------------------------------------------------- /packages/components/src/fat-form/fat-form-consumer.tsx: -------------------------------------------------------------------------------- 1 | import { declareComponent, declareSlots, declareProps } from '@wakeadmin/h'; 2 | import { ToHSlotDefinition } from '../utils'; 3 | import { useFatFormContext } from './hooks'; 4 | import { FatFormConsumerProps } from './types'; 5 | 6 | /** 7 | * 获取表单实例,用于实现表单联动场景 8 | */ 9 | export const FatFormConsumer = declareComponent({ 10 | name: 'FatFormConsumer', 11 | props: declareProps(['renderDefault']), 12 | slots: declareSlots>>(), 13 | setup(props, { slots }) { 14 | const form = useFatFormContext()!; 15 | 16 | return () => { 17 | return slots.default ? slots.default(form) : props.renderDefault?.(form); 18 | }; 19 | }, 20 | }); 21 | -------------------------------------------------------------------------------- /packages/components/src/fat-form/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types'; 2 | 3 | export * from './fat-form'; 4 | export * from './fat-form-item'; 5 | export * from './fat-form-consumer'; 6 | export * from './fat-form-group'; 7 | export * from './fat-form-collection'; 8 | export * from './fat-form-section'; 9 | export * from './fat-form-table'; 10 | 11 | export * from './define-fat-form'; 12 | 13 | export { useFatFormRef, useFatFormInheritableProps, useFatFormContext, provideFatFormCollection } from './hooks'; 14 | export { runInModifyContext } from './utils'; 15 | -------------------------------------------------------------------------------- /packages/components/src/fat-i18n-content/README.md: -------------------------------------------------------------------------------- 1 | # 内容多语言包装器 2 | -------------------------------------------------------------------------------- /packages/components/src/fat-i18n-content/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './provider'; 2 | export * from './factory'; 3 | export * from './types'; 4 | export * from './builtin'; 5 | -------------------------------------------------------------------------------- /packages/components/src/fat-image-verification/README.md: -------------------------------------------------------------------------------- 1 | # 图像验证码 2 | -------------------------------------------------------------------------------- /packages/components/src/fat-import/README.md: -------------------------------------------------------------------------------- 1 | # 批量导入 2 | -------------------------------------------------------------------------------- /packages/components/src/fat-layout/README.md: -------------------------------------------------------------------------------- 1 | # 页面布局 2 | -------------------------------------------------------------------------------- /packages/components/src/fat-layout/fat-content.tsx: -------------------------------------------------------------------------------- 1 | import { declareComponent } from '@wakeadmin/h'; 2 | 3 | /** 4 | * 页面内容 5 | * 建议使用 FatCard 代替 6 | */ 7 | export const FatContent = declareComponent({ 8 | name: 'FatContent', 9 | setup(_, { slots, attrs }) { 10 | return () => { 11 | return ( 12 |
13 | {slots.default?.()} 14 |
15 | ); 16 | }; 17 | }, 18 | }); 19 | -------------------------------------------------------------------------------- /packages/components/src/fat-layout/index.ts: -------------------------------------------------------------------------------- 1 | export * from './fat-container'; 2 | export * from './fat-float-footer'; 3 | export * from './fat-content'; 4 | export * from './fat-card'; 5 | -------------------------------------------------------------------------------- /packages/components/src/fat-layout/utils.ts: -------------------------------------------------------------------------------- 1 | import { isVue2 } from '@wakeadmin/demi'; 2 | 3 | export const isWakeadminBayEnabled = () => { 4 | return '__MAPP_SERVICES__' in window; 5 | }; 6 | 7 | /** 8 | * 传入 HTML 自定义元素 slot 属性 9 | * @param name 10 | * @returns 11 | */ 12 | export const ceSlot = (name: string) => { 13 | return isVue2 ? { attrs: { slot: name } } : { slot: name }; 14 | }; 15 | -------------------------------------------------------------------------------- /packages/components/src/fat-logic-tree/index.ts: -------------------------------------------------------------------------------- 1 | export * from './fat-logic-tree'; 2 | -------------------------------------------------------------------------------- /packages/components/src/fat-space/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 按照惟客云 spacing 变量定义 3 | */ 4 | export type FatSpaceSize = 'xs' | 'sm' | 'base' | 'md' | 'lg' | 'xl' | Number; 5 | 6 | export interface FatSpaceProps { 7 | /** 8 | * 对齐方式, 默认 center 9 | */ 10 | align?: 'start' | 'end' | 'center' | 'baseline'; 11 | 12 | /** 13 | * 内联模式, 默认 true 14 | */ 15 | inline?: boolean; 16 | 17 | /** 18 | * 间距方向, 默认 horizontal 19 | */ 20 | direction?: 'vertical' | 'horizontal'; 21 | 22 | /** 23 | * 间距大小, 默认 small 24 | * 如果传入的是一个元组,则分别用于控制水平、垂直的间距 25 | */ 26 | size?: FatSpaceSize | [FatSpaceSize, FatSpaceSize]; 27 | 28 | /** 29 | * 是否自动换行,仅在 horizontal 时有效, 默认 false 30 | */ 31 | wrap?: boolean; 32 | } 33 | -------------------------------------------------------------------------------- /packages/components/src/fat-switch/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * 移植 3 | */ 4 | export { Switch as FatSwitch, SwitchProps as FatSwitchProps } from '@wakeadmin/element-adapter'; 5 | -------------------------------------------------------------------------------- /packages/components/src/fat-table-layout/index.ts: -------------------------------------------------------------------------------- 1 | export * from './define-fat-table-modal'; 2 | export * from './define-fat-table-drawer'; 3 | export * from './define-fat-table-select'; 4 | export * from './define-fat-table-select-modal'; 5 | export * from './fat-table-modal'; 6 | export * from './fat-table-drawer'; 7 | export * from './fat-table-select'; 8 | export * from './fat-table-select-modal'; 9 | -------------------------------------------------------------------------------- /packages/components/src/fat-table/hooks.ts: -------------------------------------------------------------------------------- 1 | import { ref } from '@wakeadmin/demi'; 2 | import { FatTableMethods } from './types'; 3 | 4 | /** 5 | * fat-table 实例引用 6 | * @returns 7 | */ 8 | export function useFatTableRef() { 9 | return ref>(); 10 | } 11 | -------------------------------------------------------------------------------- /packages/components/src/fat-table/index.ts: -------------------------------------------------------------------------------- 1 | export { BUILTIN_LAYOUTS as FAT_TABLE_DEFAULT_LAYOUTS } from './layouts'; 2 | export * from './types'; 3 | export * from './fat-table'; 4 | export * from './define-table'; 5 | export * from './hooks'; 6 | -------------------------------------------------------------------------------- /packages/components/src/fat-table/layouts/README.md: -------------------------------------------------------------------------------- 1 | # 内置布局 2 | -------------------------------------------------------------------------------- /packages/components/src/fat-table/layouts/index.ts: -------------------------------------------------------------------------------- 1 | import DefaultLayout from './default'; 2 | 3 | /** 4 | * 内置布局 5 | */ 6 | export const BUILTIN_LAYOUTS = { 7 | default: DefaultLayout, 8 | }; 9 | -------------------------------------------------------------------------------- /packages/components/src/fat-table/types-inner.ts: -------------------------------------------------------------------------------- 1 | export interface FatTableSettingPayload { 2 | [key: string]: { 3 | visible: boolean; 4 | }; 5 | } 6 | -------------------------------------------------------------------------------- /packages/components/src/fat-text/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './fat-text'; 2 | export * from './fat-link'; 3 | -------------------------------------------------------------------------------- /packages/components/src/fat-vnode/index.tsx: -------------------------------------------------------------------------------- 1 | import { declareComponent, declareProps } from '@wakeadmin/h'; 2 | 3 | export const FatVNode = declareComponent({ 4 | name: 'FatVNode', 5 | props: declareProps<{ vnode: any }>({ 6 | vnode: null, 7 | }), 8 | setup(props) { 9 | return () => { 10 | return props.vnode; 11 | }; 12 | }, 13 | }); 14 | -------------------------------------------------------------------------------- /packages/components/src/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useAtomicRegistry'; 2 | export * from './useDevtoolsExpose'; 3 | export * from './useDisposer'; 4 | export * from './useI18n'; 5 | export * from './useLazyFalsy'; 6 | export * from './useLazyOptions'; 7 | export * from './useRoute'; 8 | export * from './useUid'; 9 | export * from './usePromise'; 10 | -------------------------------------------------------------------------------- /packages/components/src/hooks/useAtomicRegistry.ts: -------------------------------------------------------------------------------- 1 | import { globalRegistry, Registry, createRegistry } from '../atomic'; 2 | import { provide, InjectionKey, inject } from '@wakeadmin/demi'; 3 | 4 | const AtomicRegistryInjectKey: InjectionKey = Symbol('atomic-registry'); 5 | 6 | /** 7 | * 提供注册器 8 | * @param registry 9 | */ 10 | export function provideAtomicRegistry() { 11 | const parent = inject(AtomicRegistryInjectKey, globalRegistry); 12 | 13 | provide(AtomicRegistryInjectKey, createRegistry(parent)); 14 | } 15 | 16 | /** 17 | * 获取注册器 18 | * @returns 19 | */ 20 | export function useAtomicRegistry() { 21 | return inject(AtomicRegistryInjectKey, globalRegistry); 22 | } 23 | -------------------------------------------------------------------------------- /packages/components/src/hooks/useDisposer.ts: -------------------------------------------------------------------------------- 1 | import { onBeforeUnmount } from '@wakeadmin/demi'; 2 | import { Disposer } from '@wakeadmin/utils'; 3 | 4 | export function useDisposer() { 5 | const disposer = new Disposer(); 6 | 7 | onBeforeUnmount(disposer.release); 8 | 9 | return disposer; 10 | } 11 | -------------------------------------------------------------------------------- /packages/components/src/hooks/useI18n.ts: -------------------------------------------------------------------------------- 1 | import { useFatConfigurable } from '../fat-configurable'; 2 | import { defaultI18nInstance } from '../i18n'; 3 | 4 | export function useI18n() { 5 | const configurable = useFatConfigurable(); 6 | return configurable?.i18n ?? defaultI18nInstance; 7 | } 8 | 9 | export function useT() { 10 | const i18n = useI18n(); 11 | return i18n.t; 12 | } 13 | -------------------------------------------------------------------------------- /packages/components/src/hooks/useUid.ts: -------------------------------------------------------------------------------- 1 | let uid = 0 2 | 3 | export function useUid() { 4 | return uid++ 5 | } -------------------------------------------------------------------------------- /packages/components/src/hooks/useUploadAccept.ts: -------------------------------------------------------------------------------- 1 | import { MaybeRef } from '@wakeadmin/h'; 2 | import { computed, unref } from '@wakeadmin/demi'; 3 | import { isDev } from '../utils'; 4 | 5 | export function useUploadAccept(name: string, accept: MaybeRef) { 6 | return computed(() => { 7 | const value = unref(accept); 8 | 9 | if (Array.isArray(value)) { 10 | if (isDev) { 11 | // 检查是否为扩展名 12 | if (value.some(i => !i.startsWith('.'))) { 13 | throw new Error(`[wakeadmin/components] ${name} 需要传入扩展名数组,例如 [".png"]`); 14 | } 15 | } 16 | return value.join(','); 17 | } 18 | 19 | return value; 20 | }); 21 | } 22 | -------------------------------------------------------------------------------- /packages/components/src/i18n/index.ts: -------------------------------------------------------------------------------- 1 | export * from './instance'; 2 | -------------------------------------------------------------------------------- /packages/components/src/i18n/instance.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, test } from 'vitest'; 2 | import { createT } from './instance'; 3 | 4 | describe('i18n', () => { 5 | test('t', () => { 6 | const t = createT({ 7 | a: '令白鸟哀叹的天空之蓝', 8 | b: '无法浸染的大海之青, {c}', 9 | }); 10 | expect(t('a')).toBe('令白鸟哀叹的天空之蓝'); 11 | expect(t('a1')).toBe(''); 12 | expect(t('b', { c: '相互映照' })).toBe('无法浸染的大海之青, 相互映照'); 13 | expect(t('b')).toBe('无法浸染的大海之青, {c}'); 14 | expect(t('b', {})).toBe('无法浸染的大海之青, '); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/components/src/mapper/index.ts: -------------------------------------------------------------------------------- 1 | export * from './toJSONString'; 2 | export * from './numberToString'; 3 | export * from './toCommaSplitArray'; 4 | -------------------------------------------------------------------------------- /packages/components/src/mapper/numberToString.ts: -------------------------------------------------------------------------------- 1 | import { FatFormItemMapper } from '../fat-form'; 2 | 3 | export const numberToString: FatFormItemMapper = { 4 | in(value: unknown) { 5 | if (typeof value === 'number') { 6 | return value; 7 | } 8 | 9 | if (typeof value === 'string' && value !== '') { 10 | return Number(value); 11 | } 12 | 13 | if (value != null && process.env.NODE_ENV !== 'production') { 14 | console.warn(`expected to get string number, but got`, value); 15 | } 16 | }, 17 | out(value: unknown) { 18 | if (value != null) { 19 | return String(value); 20 | } 21 | }, 22 | }; 23 | -------------------------------------------------------------------------------- /packages/components/src/test-dts/MyGenericComponent.tsx: -------------------------------------------------------------------------------- 1 | import { OurComponentInstance } from '../utils'; 2 | 3 | import { noop } from '.'; 4 | 5 | interface Events { 6 | onChange?: (value: T) => void; 7 | } 8 | 9 | interface Slots { 10 | renderLabel?: (value: { foo: number; value: T }) => any; 11 | } 12 | 13 | interface Props extends Events, Slots { 14 | value?: T; 15 | } 16 | 17 | interface Expose { 18 | getValue(): T; 19 | } 20 | 21 | export const MyGenericComponent: new (props: Props) => OurComponentInstance< 22 | typeof props, 23 | Slots, 24 | Events, 25 | Expose 26 | > = noop; 27 | -------------------------------------------------------------------------------- /packages/components/src/test-dts/define-form.test.d.tsx: -------------------------------------------------------------------------------- 1 | import { expectType, test } from '.'; 2 | import { defineFatForm } from '../fat-form'; 3 | 4 | test('defineFatForm', () => { 5 | interface T { 6 | foo: number; 7 | } 8 | defineFatForm(({ item }) => { 9 | return () => ({ 10 | children: [ 11 | // @ts-expect-error prop 是必须的, 12 | item({}), 13 | item({ 14 | valueProps: { 15 | // @ts-expect-error 默认推断为 text 类型 16 | type: 'unknown', 17 | renderPreview: value => { 18 | expectType(value); 19 | return ''; 20 | }, 21 | }, 22 | }), 23 | ], 24 | }); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /packages/components/src/test-dts/fat-atomic.test-d.tsx: -------------------------------------------------------------------------------- 1 | import { test, expectType } from '.'; 2 | import { FatAtomic } from '../fat-atomic'; 3 | 4 | test('FatAtomicProps', () => { 5 | expectType(e)} 8 | onBlur={() => console.log('blur')} 9 | />; 10 | expectType(e)} 13 | placeholder="ok" 14 | min={1} 15 | />; 16 | }); 17 | -------------------------------------------------------------------------------- /packages/components/src/test-dts/index.d.ts: -------------------------------------------------------------------------------- 1 | export function describe(_name: string, _fn: () => void): void; 2 | export function test(_name: string, _fn: () => any): void; 3 | 4 | export function expectType(value: T): void; 5 | export function expectError(value: T): void; 6 | export function expectAssignable(value: T2): void; 7 | 8 | export type MayBeUndefined = T | undefined; 9 | 10 | export const noop: any; 11 | -------------------------------------------------------------------------------- /packages/components/src/test-dts/vue-template/fat-form-steps.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 12 | -------------------------------------------------------------------------------- /packages/components/src/test-dts/vue-template/fat-table.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 28 | -------------------------------------------------------------------------------- /packages/components/src/test-dts/vue-template/generic.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 25 | -------------------------------------------------------------------------------- /packages/components/src/utils/className.test.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from 'vitest'; 2 | import { normalizeClassName } from './className'; 3 | 4 | test('normalizeClassName', () => { 5 | expect(normalizeClassName()).toBe(''); 6 | expect(normalizeClassName('hello')).toBe('hello'); 7 | expect(normalizeClassName('hello', 'world')).toBe('hello world'); 8 | expect(normalizeClassName('hello', 'world', {})).toBe('hello world'); 9 | expect(normalizeClassName('hello', 'world', { foo: true, bar: false, baz: [] })).toBe('hello world foo baz'); 10 | expect( 11 | normalizeClassName('hello', 'world', { foo: true, bar: false, baz: [] }, ['one', 'two', { three: true }, ['four']]) 12 | ).toBe('hello world foo baz one two three four'); 13 | }); 14 | -------------------------------------------------------------------------------- /packages/components/src/utils/color.ts: -------------------------------------------------------------------------------- 1 | export type Color = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | String; 2 | 3 | const BUILTIN_COLORS = ['primary', 'secondary', 'success', 'danger', 'warning', 'info']; 4 | 5 | export function normalizeColor(color?: Color): string | undefined { 6 | if (!color) { 7 | return undefined; 8 | } 9 | 10 | if (BUILTIN_COLORS.includes(color as string)) { 11 | return `var(--fat-color-${color})`; 12 | } 13 | 14 | return color as string; 15 | } 16 | -------------------------------------------------------------------------------- /packages/components/src/utils/date.test.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from 'vitest'; 2 | 3 | import { normalizeToDayjsFormat } from './date'; 4 | 5 | test('normalizeToDayjsFormat', () => { 6 | expect(normalizeToDayjsFormat('yyyy-MM-dd')).toBe('YYYY-MM-DD'); 7 | expect(normalizeToDayjsFormat('yyyy-MM-dd HH:mm:SS')).toBe('YYYY-MM-DD HH:mm:ss'); 8 | expect(normalizeToDayjsFormat('WW')).toBe('ww'); 9 | expect(normalizeToDayjsFormat('timestamp')).toBe('x'); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/components/src/utils/document.ts: -------------------------------------------------------------------------------- 1 | export function getDocument(): Document { 2 | if (typeof document === 'undefined') { 3 | return null as any; 4 | } 5 | return document; 6 | } 7 | -------------------------------------------------------------------------------- /packages/components/src/utils/expose.ts: -------------------------------------------------------------------------------- 1 | import { Ref } from '@wakeadmin/demi'; 2 | 3 | /** 4 | * 转发子组件 expose 的值 5 | * @param expose 6 | */ 7 | export function forwardExpose(exposed: Record, fields: string[] | readonly string[], ref: Ref) { 8 | for (const field of fields) { 9 | if (field in exposed) { 10 | continue; 11 | } 12 | 13 | Object.defineProperty(exposed, field, { 14 | configurable: true, 15 | enumerable: true, 16 | get() { 17 | return ref.value?.[field]; 18 | }, 19 | set(value) { 20 | if (ref.value != null) { 21 | ref.value[field] = value; 22 | } 23 | }, 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/components/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './array'; 2 | export * from './atom'; 3 | export * from './className'; 4 | export * from './color'; 5 | export * from './date'; 6 | export * from './document'; 7 | export * from './element'; 8 | export * from './expose'; 9 | export * from './loose-message'; 10 | export * from './merge-props'; 11 | export * from './misc'; 12 | export * from './number'; 13 | export * from './object'; 14 | export * from './portal'; 15 | export * from './promise'; 16 | export * from './ref'; 17 | export * from './render'; 18 | export * from './string'; 19 | export * from './style'; 20 | export * from './types'; 21 | export * from './path'; 22 | export * from './isDev'; 23 | -------------------------------------------------------------------------------- /packages/components/src/utils/isDev.ts: -------------------------------------------------------------------------------- 1 | export const isDev = process.env.NODE_ENV !== 'production'; 2 | -------------------------------------------------------------------------------- /packages/components/src/utils/number.ts: -------------------------------------------------------------------------------- 1 | export function clamp(value: number, min: number, max: number): number { 2 | return Math.max(min, Math.min(max, value)); 3 | } 4 | -------------------------------------------------------------------------------- /packages/components/src/utils/path.ts: -------------------------------------------------------------------------------- 1 | import memoize from 'lodash/memoize'; 2 | import toPath from 'lodash/toPath'; 3 | 4 | /** 5 | * Returns an array of path segments. 6 | * If the path is a string, the array will be frozen in development mode. 7 | */ 8 | export const getPaths = memoize((path: string): readonly string[] => { 9 | if (process.env.NODE_ENV !== 'production') { 10 | return Object.freeze(toPath(path)); 11 | } 12 | 13 | return toPath(path); 14 | }); 15 | 16 | /** 17 | * 获取父路径 18 | */ 19 | export const getParentPath = memoize((path: string) => { 20 | return getPaths(path).slice(0, -1).join('.'); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/components/src/utils/promise.ts: -------------------------------------------------------------------------------- 1 | export function settledThrowIfNeed(results?: PromiseSettledResult[]) { 2 | if (results == null || results.length === 0) { 3 | return; 4 | } 5 | 6 | for (const result of results) { 7 | if (result.status === 'rejected') { 8 | throw result.reason; 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/components/src/utils/string.test.ts: -------------------------------------------------------------------------------- 1 | import { expect, test } from 'vitest'; 2 | import { filterStringByRegexp } from './string'; 3 | 4 | test('filterStringByRegexp', () => { 5 | expect(filterStringByRegexp('hello', /.*/)).toBe('hello'); 6 | expect(filterStringByRegexp(' hello hello', /[a-z]+/)).toBe('hello'); 7 | expect(filterStringByRegexp(' hello hello', /[a-z]+/g)).toBe('hello'); 8 | 9 | // trim 10 | expect(filterStringByRegexp(' hello hello ', /\S(.*\S)?/)).toBe('hello hello'); 11 | 12 | // chinese 13 | expect(filterStringByRegexp(' 你好 666', /[\u4e00-\u9fa5]+/)).toBe('你好'); 14 | 15 | // javascript identifier 16 | expect(filterStringByRegexp(' 0$123', /[_$a-zA-Z]{1}[a-zA-Z0-9_$]*/)).toBe('$123'); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/components/style/README.md: -------------------------------------------------------------------------------- 1 | # 在这里统一定义所有组件的样式 2 | -------------------------------------------------------------------------------- /packages/components/style/_config.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * element-plus 命名空间。如果你在 element-plus 中自定义了命名空间,这个变量也需要被配置; 3 | */ 4 | $el-ns: 'el' !default; 5 | -------------------------------------------------------------------------------- /packages/components/style/_css-variables.scss: -------------------------------------------------------------------------------- 1 | // 暴露表单到 css variables 2 | @use 'sass:meta'; 3 | @use 'variables' as v; 4 | 5 | :root { 6 | @each $name, $value in meta.module-variables(v) { 7 | --#{$name}: #{$value}; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/components/style/_fat-content.scss: -------------------------------------------------------------------------------- 1 | @use 'variables' as *; 2 | 3 | .fat-content { 4 | border: 1px solid $fat-color-border-light; 5 | background-color: $fat-color-white; 6 | border-radius: $fat-border-radius-base; 7 | 8 | &:not(:only-of-type) { 9 | margin-top: 16px; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/components/style/_fat-drag-drop.scss: -------------------------------------------------------------------------------- 1 | @mixin dragging-shadow { 2 | box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12); 3 | } 4 | 5 | @mixin dragging-animate { 6 | transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); 7 | } 8 | 9 | .fat-drag-placeholder { 10 | opacity: 0; 11 | } 12 | .fat-drag-preview, 13 | .fat-drag-dragging { 14 | @include dragging-shadow(); 15 | } 16 | 17 | .fat-drop-list { 18 | &__dragging .fat-drag-item { 19 | @include dragging-animate(); 20 | } 21 | } 22 | 23 | .fat-drag-animating { 24 | @include dragging-animate(); 25 | } 26 | -------------------------------------------------------------------------------- /packages/components/style/_fat-float-footer.scss: -------------------------------------------------------------------------------- 1 | @use 'share' as *; 2 | @use 'variables' as *; 3 | 4 | .fat-float-footer { 5 | $height: getVar(float-footer-height, 60px); 6 | $bg: getVar(float-footer-background, $fat-color-white); 7 | 8 | position: fixed; 9 | bottom: 0; 10 | left: 0; 11 | right: 0; 12 | height: $height; 13 | line-height: $height; 14 | box-shadow: 0 -4px 8px 0 rgb(0 0 0 / 7%); 15 | background: $bg; 16 | z-index: 10; 17 | 18 | display: flex; 19 | align-items: center; 20 | justify-content: center; 21 | 22 | &__placeholder { 23 | width: 100%; 24 | height: $height; 25 | } 26 | 27 | &__watcher { 28 | position: absolute; 29 | left: 0; 30 | right: 0; 31 | bottom: 0; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/components/style/_fat-form-drawer.scss: -------------------------------------------------------------------------------- 1 | .fat-form-drawer { 2 | &__body { 3 | padding: 24px; 4 | padding-bottom: 80px; 5 | } 6 | 7 | &__footer { 8 | position: absolute; 9 | bottom: 0; 10 | right: 0; 11 | left: 0; 12 | background: white; 13 | padding: 8px; 14 | display: flex; 15 | align-items: center; 16 | justify-content: center; 17 | border-top: 1px solid #f2f6fc; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/components/style/_fat-form-query.scss: -------------------------------------------------------------------------------- 1 | @use 'config' as *; 2 | 3 | .fat-form-query { 4 | position: relative; 5 | 6 | &__submitter { 7 | &--align > .#{$el-ns}-form-item__label-wrap, 8 | &--align > .#{$el-ns}-form-item__label { 9 | visibility: hidden; 10 | } 11 | } 12 | } 13 | 14 | .vue3 .fat-form-query { 15 | .#{$el-ns}-input__clear, 16 | .clear-icon { 17 | position: absolute; 18 | margin-right: 8px; 19 | background-color: white; 20 | border-radius: 8px; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/components/style/_fat-icon.scss: -------------------------------------------------------------------------------- 1 | @keyframes fat-rotating { 2 | 0% { 3 | transform: rotateZ(0deg); 4 | } 5 | 100% { 6 | transform: rotateZ(360deg); 7 | } 8 | } 9 | 10 | .fat-icon { 11 | --color: inherit; 12 | 13 | height: 1em; 14 | width: 1em; 15 | line-height: 1em; 16 | display: inline-flex; 17 | justify-content: center; 18 | align-items: center; 19 | position: relative; 20 | fill: currentColor; 21 | color: var(--color); 22 | font-size: inherit; 23 | 24 | &--loading { 25 | animation: fat-rotating 2s linear infinite; 26 | } 27 | 28 | &--right { 29 | margin-left: 5px; 30 | } 31 | 32 | &--left { 33 | margin-right: 5px; 34 | } 35 | 36 | svg { 37 | height: 1em; 38 | width: 1em; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/components/style/_fat-space.scss: -------------------------------------------------------------------------------- 1 | .fat-space { 2 | display: flex; 3 | } 4 | 5 | .fat-space--inline { 6 | display: inline-flex; 7 | } 8 | 9 | .fat-space--vertical { 10 | flex-direction: column; 11 | } 12 | 13 | .fat-space--wrap { 14 | flex-wrap: wrap; 15 | } 16 | 17 | .fat-space--align-start { 18 | align-items: start; 19 | } 20 | 21 | .fat-space--align-end { 22 | align-items: end; 23 | } 24 | 25 | .fat-space--align-center { 26 | align-items: center; 27 | } 28 | 29 | .fat-space--align-baseline { 30 | align-items: baseline; 31 | } 32 | -------------------------------------------------------------------------------- /packages/components/style/_fat-table-default-layout.scss: -------------------------------------------------------------------------------- 1 | .fat-table--default { 2 | .fat-table__toolbar, 3 | .fat-table__bottom-toolbar, 4 | .fat-table__body, 5 | .fat-table__pagination { 6 | margin-bottom: 10px; 7 | } 8 | 9 | .fat-table__pagination { 10 | display: flex; 11 | align-items: center; 12 | justify-content: flex-end; 13 | } 14 | 15 | .fat-table__toolbar { 16 | display: flex; 17 | align-items: center; 18 | justify-content: space-between; 19 | 20 | &-main { 21 | flex: 1; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/components/style/_fat-table-drawer.scss: -------------------------------------------------------------------------------- 1 | @use 'config' as *; 2 | 3 | .fat-table-drawer { 4 | .#{$el-ns}-drawer__body { 5 | padding: 0; 6 | } 7 | 8 | &__body { 9 | padding-bottom: 80px; 10 | } 11 | 12 | &__footer { 13 | position: absolute; 14 | bottom: 0; 15 | right: 0; 16 | left: 0; 17 | background: white; 18 | padding: 8px; 19 | display: flex; 20 | align-items: center; 21 | justify-content: center; 22 | border-top: 1px solid #f2f6fc; 23 | z-index: 100; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/components/style/_fat-table-modal.scss: -------------------------------------------------------------------------------- 1 | @use 'config' as *; 2 | 3 | .fat-table-modal { 4 | // 去除 modal 的边距 5 | .#{$el-ns}-dialog__body { 6 | padding: 0; 7 | } 8 | 9 | .#{$el-ns}-dialog__footer:empty { 10 | display: none; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/components/style/_fat-table-select.scss: -------------------------------------------------------------------------------- 1 | @use 'share' as *; 2 | @use 'variables' as *; 3 | @use 'config' as *; 4 | 5 | .fat-table-select { 6 | .fat-table__footer { 7 | display: flex; 8 | align-items: center; 9 | justify-content: space-between; 10 | } 11 | .fat-table__pagination { 12 | margin-left: auto; 13 | } 14 | 15 | &__counter { 16 | color: getVar(color-font-regular, $fat-color-font-regular); 17 | font-size: getVar(font-size, $fat-font-size); 18 | &-value { 19 | padding: 0 calc(getVar(spacing-xs, $fat-spacing-xs) / 2); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/components/style/_fat-text.scss: -------------------------------------------------------------------------------- 1 | @use 'variables' as *; 2 | 3 | .fat-text { 4 | position: relative; 5 | word-break: break-all; 6 | 7 | &--ellipsis.fat-text--copyable { 8 | padding-right: 28px; 9 | } 10 | 11 | &__copy { 12 | display: inline-block; 13 | height: auto; 14 | line-height: inherit; 15 | font-size: 1.1em; 16 | cursor: pointer; 17 | color: $fat-color-info; 18 | margin-left: 5px; 19 | 20 | &:active { 21 | opacity: 0.7; 22 | } 23 | 24 | svg { 25 | vertical-align: middle; 26 | } 27 | } 28 | 29 | &--ellipsis &__copy { 30 | position: absolute; 31 | 32 | right: 0; 33 | bottom: 0; 34 | } 35 | } 36 | 37 | .fat-link { 38 | cursor: pointer; 39 | } 40 | -------------------------------------------------------------------------------- /packages/components/style/_share.scss: -------------------------------------------------------------------------------- 1 | @use 'sass:string'; 2 | @use 'sass:meta'; 3 | 4 | @function isCSSVar($name) { 5 | @if meta.type-of($name) == 'string' and string.index($name, '--') == 1 { 6 | @return true; 7 | } 8 | 9 | @return false; 10 | } 11 | 12 | @function getVar($name, $default) { 13 | $var: --fat-#{$name}; 14 | $value: $default; 15 | 16 | @if isCSSVar($value) { 17 | $value: var($value); 18 | } 19 | 20 | @return var($var, $value); 21 | } 22 | -------------------------------------------------------------------------------- /packages/components/style/atomics/_captcha.scss: -------------------------------------------------------------------------------- 1 | .fat-a-captcha { 2 | display: flex; 3 | align-items: center; 4 | flex: 1; 5 | width: 100%; 6 | 7 | &__input { 8 | flex: 1; 9 | } 10 | 11 | &__button { 12 | margin-left: 8px; 13 | font-variant: tabular-nums; 14 | min-width: 80px; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/components/style/atomics/_cascader.scss: -------------------------------------------------------------------------------- 1 | @use '../config' as *; 2 | 3 | .a-cascader, 4 | .a-cascader-lazy { 5 | // 修复宽度自动撑开 6 | .#{$el-ns}-cascader { 7 | width: 100%; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/components/style/atomics/_checkbox.scss: -------------------------------------------------------------------------------- 1 | .fat-a-checkboxs { 2 | // 垂直布局 3 | &--vertical { 4 | display: flex; 5 | flex-direction: column; 6 | align-items: flex-start; 7 | 8 | .el-checkbox { 9 | height: auto; 10 | 11 | &:not(:last-child) { 12 | // 这是足以放下错误信息最小大小 13 | margin-bottom: 16px; 14 | } 15 | } 16 | 17 | // element-ui 适配:对齐 18 | @at-root .vue2 & { 19 | .el-checkbox__label { 20 | vertical-align: middle; 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/components/style/atomics/_date.scss: -------------------------------------------------------------------------------- 1 | @use '../config' as *; 2 | 3 | .a-date, 4 | .a-time, 5 | .a-date-time { 6 | .#{$el-ns}-date-editor { 7 | width: 100%; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/components/style/atomics/_files.scss: -------------------------------------------------------------------------------- 1 | @use '../variables' as *; 2 | 3 | .fat-a-files { 4 | &__p-item { 5 | & > * { 6 | vertical-align: middle; 7 | } 8 | } 9 | 10 | &__p-icon { 11 | margin-right: 5px; 12 | color: gray; 13 | } 14 | 15 | &__dragger { 16 | height: 100%; 17 | display: flex; 18 | flex-direction: column; 19 | align-items: center; 20 | justify-content: center; 21 | } 22 | 23 | &__dragger-icon { 24 | color: gray; 25 | font-size: 40px; 26 | } 27 | 28 | &__dragger-text { 29 | color: gray; 30 | margin-top: 15px; 31 | 32 | & > em { 33 | color: $fat-color-info; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /packages/components/style/atomics/_index.scss: -------------------------------------------------------------------------------- 1 | @use 'avatar'; 2 | @use 'captcha'; 3 | @use 'cascader'; 4 | @use 'date'; 5 | @use 'files'; 6 | @use 'image'; 7 | @use 'progress'; 8 | @use 'select'; 9 | @use 'slider'; 10 | @use 'textarea'; 11 | @use 'checkbox'; 12 | @use 'radio'; 13 | -------------------------------------------------------------------------------- /packages/components/style/atomics/_progress.scss: -------------------------------------------------------------------------------- 1 | @use '../config' as *; 2 | 3 | // 修复 progress 默认宽度问题 4 | .a-progress { 5 | .#{$el-ns}-progress.#{$el-ns}-progress--line { 6 | width: 100%; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/components/style/atomics/_radio.scss: -------------------------------------------------------------------------------- 1 | .fat-a-radio { 2 | // 垂直布局 3 | &--vertical { 4 | display: flex; 5 | flex-direction: column; 6 | align-items: flex-start; 7 | 8 | .el-radio { 9 | height: auto; 10 | 11 | &:not(:last-child) { 12 | // 这是足以放下错误信息最小大小 13 | margin-bottom: 16px; 14 | } 15 | } 16 | 17 | // element-ui 适配 18 | @at-root .vue2 & { 19 | .el-radio { 20 | display: flex; 21 | align-items: center; 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/components/style/atomics/_select.scss: -------------------------------------------------------------------------------- 1 | @use '../config' as *; 2 | 3 | .fat-a-select--color { 4 | color: var(--fat-a-select-color); 5 | 6 | &.fat-a-select--color-dot { 7 | color: inherit; 8 | 9 | &::before { 10 | $size: 8px; 11 | content: ''; 12 | 13 | display: inline-block; 14 | width: $size; 15 | height: $size; 16 | border-radius: $size; 17 | background-color: var(--fat-a-select-color); 18 | margin-right: 5px; 19 | } 20 | } 21 | } 22 | 23 | .a-select, 24 | .a-tree-select, 25 | .a-multi-select { 26 | .#{$el-ns}-select { 27 | width: 100%; 28 | 29 | // 加载状态修复 30 | .#{$el-ns}-loading-mask { 31 | opacity: 0.3; 32 | 33 | .circular { 34 | width: 20px; 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/components/style/atomics/_slider.scss: -------------------------------------------------------------------------------- 1 | @use '../config' as *; 2 | 3 | .a-slider, 4 | .a-slider-range { 5 | .#{$el-ns}-slider { 6 | width: 100%; 7 | &.is-vertical { 8 | height: 200px; 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/components/style/atomics/_textarea.scss: -------------------------------------------------------------------------------- 1 | .fat-a-textarea-preview { 2 | margin: 0; 3 | white-space: pre-wrap; 4 | line-height: 2; 5 | } 6 | -------------------------------------------------------------------------------- /packages/components/style/index.scss: -------------------------------------------------------------------------------- 1 | @forward 'variables'; 2 | 3 | @use 'share'; 4 | @use 'css-variables'; 5 | @use 'atomics/index'; 6 | @use 'fat-actions'; 7 | @use 'fat-card'; 8 | @use 'fat-content'; 9 | @use 'fat-float-footer'; 10 | @use 'fat-form-drawer'; 11 | @use 'fat-form'; 12 | @use 'fat-container'; 13 | @use 'fat-icon'; 14 | @use 'fat-space'; 15 | @use 'fat-table-default-layout'; 16 | @use 'fat-table'; 17 | @use 'fat-table-drawer'; 18 | @use 'fat-table-modal'; 19 | @use 'fat-table-select'; 20 | @use 'fat-text'; 21 | @use 'fat-utils'; 22 | @use 'fat-form-steps'; 23 | @use 'fat-form-query'; 24 | @use 'fat-drag-drop'; 25 | @use 'fat-logic-tree'; 26 | @use 'fat-image-verification'; 27 | @use 'fat-import'; 28 | @use 'fat-i18n-content'; 29 | 30 | @import '@wakeadmin/element-adapter/style/index.scss'; 31 | -------------------------------------------------------------------------------- /packages/components/tsconfig.build.common.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.build.json", 3 | "compilerOptions": { 4 | "outDir": "./dist/common", 5 | "module": "CommonJS", 6 | "declaration": false, 7 | "declarationMap": false 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/components/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./dist", 5 | "noEmit": false, 6 | "noEmitOnError": false, 7 | "jsx": "react-jsx", 8 | "target": "ES2017" 9 | }, 10 | "exclude": ["dist", "**/__tests__/*", "**/*.test.*", "**/test-dts/*", "**/*.test-d.ts", "**/*.vue", "**/*.d.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/components/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./dist" /* Redirect output structure to the directory. */, 5 | "rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 6 | }, 7 | "vueCompilerOptions": { 8 | "jsxTemplates": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/doc/docs/.vitepress/theme/custom.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 0 !important; 3 | overflow: auto !important; 4 | } 5 | 6 | :root { 7 | --vp-layout-max-width: 1700px; 8 | } 9 | 10 | .VPDoc.has-aside .content-container { 11 | max-width: unset !important; 12 | } 13 | 14 | .wk-demo { 15 | background-color: #f5f7fa; 16 | padding: 20px; 17 | border-radius: 5px; 18 | 19 | color: #111; 20 | } 21 | 22 | .full-height { 23 | min-height: 100vh; 24 | } 25 | 26 | .demo-frame { 27 | border: none; 28 | width: 100%; 29 | height: 50vh; 30 | border-radius: 5px; 31 | } 32 | 33 | .codesandbox-icon { 34 | fill: transparent !important; 35 | } 36 | -------------------------------------------------------------------------------- /packages/doc/docs/atomics/all-atomics.demo.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: false 3 | --- 4 | 5 | 9 | 10 | 11 |
12 | 13 |
14 |
15 | -------------------------------------------------------------------------------- /packages/doc/docs/atomics/images/atomic-date.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/atomics/images/atomic-date.png -------------------------------------------------------------------------------- /packages/doc/docs/atomics/images/atomic-display.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/atomics/images/atomic-display.png -------------------------------------------------------------------------------- /packages/doc/docs/atomics/images/atomic-files.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/atomics/images/atomic-files.png -------------------------------------------------------------------------------- /packages/doc/docs/atomics/images/atomic-interaction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/atomics/images/atomic-interaction.png -------------------------------------------------------------------------------- /packages/doc/docs/atomics/images/atomic-number.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/atomics/images/atomic-number.png -------------------------------------------------------------------------------- /packages/doc/docs/atomics/images/atomic-select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/atomics/images/atomic-select.png -------------------------------------------------------------------------------- /packages/doc/docs/atomics/images/atomic-text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/atomics/images/atomic-text.png -------------------------------------------------------------------------------- /packages/doc/docs/atomics/images/atomic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/atomics/images/atomic.png -------------------------------------------------------------------------------- /packages/doc/docs/base/concepts.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | # 基本概念 7 | 8 | ## 何为 'fat' 9 | 10 | Fat 是肥胖的意思。`@wakeadmin/components` 的定位是一个高级组件库,而不是 element-ui 这类基础组件库。它的目标是覆盖管理后台的 80% 的开发场景,因此,它有以下特征: 11 | 12 | - 组件的粒度更加大。大到一个页面,小到一个页面区域。 13 | - 遵循“约定大于配置”。 我们期望开发一个页面,只需要少量的配置代码,按照 UI/产品 规范,将大部分交互、数据处理的细节固定下来,做到开箱即用。 14 | 15 |
16 |
17 |
18 | 19 | ## 何为'原件(Atomic)' 20 | 21 | ![宜搭](./images/yida.png) 22 | 23 | 原件类似于低代码平台的’组件‘,在 `@wakeadmin/components` 中,`原件` 是组成`表格` 和`表单`的基本单位。 24 | 25 | 原件有两种形态: 26 | 27 | - `编辑形态(editable)`: 用于表单、表格查询等场景 28 | - `预览形态(preview)`: 用于详情页,表格等场景 29 | 30 |
31 |
32 | 33 | 代码示例: 34 | 35 | 36 | 37 | 38 | 39 | ::: details 查看代码 40 | 41 | <<< @/base/Atomics.vue 42 | 43 | ::: 44 | -------------------------------------------------------------------------------- /packages/doc/docs/base/images/arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/base/images/arch.png -------------------------------------------------------------------------------- /packages/doc/docs/base/images/content.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/base/images/content.png -------------------------------------------------------------------------------- /packages/doc/docs/base/images/yida.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/base/images/yida.png -------------------------------------------------------------------------------- /packages/doc/docs/fat-configurable/images/fat-configurable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/fat-configurable/images/fat-configurable.png -------------------------------------------------------------------------------- /packages/doc/docs/fat-drag-drop/advanced.md: -------------------------------------------------------------------------------- 1 | # 高级 2 | 3 | ## 自定义排序策略 4 | 5 | todo 6 | -------------------------------------------------------------------------------- /packages/doc/docs/fat-drag-drop/demo/drag.vue: -------------------------------------------------------------------------------- 1 | 8 | 11 | 20 | -------------------------------------------------------------------------------- /packages/doc/docs/fat-drag-drop/demo/dragDelay.vue: -------------------------------------------------------------------------------- 1 | 8 | 11 | 20 | -------------------------------------------------------------------------------- /packages/doc/docs/fat-drag-drop/demo/dragHandler.vue: -------------------------------------------------------------------------------- 1 | 9 | 12 | 23 | -------------------------------------------------------------------------------- /packages/doc/docs/fat-drag-drop/demo/images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/fat-drag-drop/demo/images/1.jpg -------------------------------------------------------------------------------- /packages/doc/docs/fat-drag-drop/demo/images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/fat-drag-drop/demo/images/2.jpg -------------------------------------------------------------------------------- /packages/doc/docs/fat-drag-drop/demo/images/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/fat-drag-drop/demo/images/3.jpg -------------------------------------------------------------------------------- /packages/doc/docs/fat-drag-drop/demo/images/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/fat-drag-drop/demo/images/4.jpg -------------------------------------------------------------------------------- /packages/doc/docs/fat-drag-drop/demo/images/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/fat-drag-drop/demo/images/5.jpg -------------------------------------------------------------------------------- /packages/doc/docs/fat-drag-drop/demo/images/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/fat-drag-drop/demo/images/6.jpg -------------------------------------------------------------------------------- /packages/doc/docs/fat-drag-drop/images/fat-drag-item-events.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/fat-drag-drop/images/fat-drag-item-events.png -------------------------------------------------------------------------------- /packages/doc/docs/fat-drag-drop/images/fat-drag-item-props.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/fat-drag-drop/images/fat-drag-item-props.png -------------------------------------------------------------------------------- /packages/doc/docs/fat-drag-drop/images/fat-drop-list-events.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/fat-drag-drop/images/fat-drop-list-events.png -------------------------------------------------------------------------------- /packages/doc/docs/fat-drag-drop/images/fat-drop-list-props.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/fat-drag-drop/images/fat-drop-list-props.png -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/PageComplex.tsx: -------------------------------------------------------------------------------- 1 | import { defineFatFormPage } from '@wakeadmin/components'; 2 | 3 | export default defineFatFormPage(({ item, section }) => { 4 | return () => ({ 5 | title: '新增 XX', 6 | children: [ 7 | section({ 8 | title: '个人信息', 9 | children: [ 10 | item({ label: '名称', prop: 'name', width: 'medium', rules: { required: true } }), 11 | item({ label: '昵称', prop: 'nickName', width: 'medium', rules: { required: true } }), 12 | item({ label: '地址', prop: 'address', valueType: 'textarea', width: 'huge' }), 13 | ], 14 | }), 15 | section({ 16 | title: '详细信息', 17 | children: [item({ label: '详细描述', prop: 'detail', width: 'huge', valueType: 'textarea' })], 18 | }), 19 | ], 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/Query.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 21 | -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/QueryNonAlign.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 21 | -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/TableSortable.module.scss: -------------------------------------------------------------------------------- 1 | .dragHandle { 2 | display: flex; 3 | align-items: center; 4 | gap: 3px; 5 | } 6 | -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/images/fat-form-drawer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/fat-form-layout/images/fat-form-drawer.png -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/images/fat-form-modal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/fat-form-layout/images/fat-form-modal.png -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/images/fat-form-page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/fat-form-layout/images/fat-form-page.png -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/images/fat-form-query.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/fat-form-layout/images/fat-form-query.png -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/images/fat-form-step.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/fat-form-layout/images/fat-form-step.png -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/images/fat-form-steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/fat-form-layout/images/fat-form-steps.png -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/images/fat-form-tab-pane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/fat-form-layout/images/fat-form-tab-pane.png -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/images/fat-form-table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/fat-form-layout/images/fat-form-table.png -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/images/fat-form-tabs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wakeadmin/components/68d34add311b44c76fcbccf31dd30dc3acbdec13/packages/doc/docs/fat-form-layout/images/fat-form-tabs.png -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/page-complex.demo.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: false 3 | --- 4 | 5 | 9 | 10 | 11 |
12 | 13 |
14 |
15 | -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/page.demo.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: false 3 | --- 4 | 5 | 9 | 10 | 11 |
12 | 13 |
14 |
15 | -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/steps-complex-vertical.demo.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: false 3 | --- 4 | 5 | 9 | 10 | 11 |
12 | 13 |
14 |
15 | -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/steps-complex.demo.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: false 3 | --- 4 | 5 | 9 | 10 | 11 |
12 | 13 |
14 |
15 | -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/steps-define.demo.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: false 3 | --- 4 | 5 | 9 | 10 | 11 |
12 | 13 |
14 |
15 | -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/steps-loose.demo.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: false 3 | --- 4 | 5 | 9 | 10 | 11 |
12 | 13 |
14 |
15 | -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/steps.demo.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: false 3 | --- 4 | 5 | 9 | 10 | 11 |
12 | 13 |
14 |
15 | -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/table-custom-create.demo.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: false 3 | --- 4 | 5 | 9 | 10 | 11 |
12 | 13 |
14 |
15 | -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/table-sortable-drag.demo.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: false 3 | --- 4 | 5 | 9 | 10 | 11 |
12 | 13 |
14 |
15 | -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/table-sortable-simple.demo.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: false 3 | --- 4 | 5 | 9 | 10 | 11 |
12 | 13 |
14 |
15 | -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/table-sortable.demo.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: false 3 | --- 4 | 5 | 9 | 10 | 11 |
12 | 13 |
14 |
15 | -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/table.demo.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: false 3 | --- 4 | 5 | 9 | 10 | 11 |
12 | 13 |
14 |
15 | -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/tabs.demo.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: false 3 | --- 4 | 5 | 9 | 10 | 11 |
12 | 13 |
14 |
15 | -------------------------------------------------------------------------------- /packages/doc/docs/fat-form-layout/tabs.md: -------------------------------------------------------------------------------- 1 | # FatFormTabs 标签页表单 2 | 3 | `FatFormTabs` 是 FatForm 针对复杂标签页表单场景设计的一个组件 4 | 5 | ## 示例 6 | 7 | 使用组件模式创建: 8 | 9 |