@aoao-y33/ui 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/README.md +811 -0
  2. package/dist/button/components/button/button.vue.d.ts +22 -0
  3. package/dist/button/components/button/button.vue.d.ts.map +1 -0
  4. package/dist/button/components/button/index.d.ts +3 -0
  5. package/dist/button/components/button/index.d.ts.map +1 -0
  6. package/dist/button/components/button/props.d.ts +21 -0
  7. package/dist/button/components/button/props.d.ts.map +1 -0
  8. package/dist/button/components/fields/index.d.ts +2 -0
  9. package/dist/button/components/fields/index.d.ts.map +1 -0
  10. package/dist/button/hoc/index.d.ts +2 -0
  11. package/dist/button/hoc/index.d.ts.map +1 -0
  12. package/dist/button/hoc/useButton.d.ts +19 -0
  13. package/dist/button/hoc/useButton.d.ts.map +1 -0
  14. package/dist/button/index.d.ts +5 -0
  15. package/dist/button/index.d.ts.map +1 -0
  16. package/dist/button/utils/index.d.ts +4 -0
  17. package/dist/button/utils/index.d.ts.map +1 -0
  18. package/dist/common/index.d.ts +2 -0
  19. package/dist/common/index.d.ts.map +1 -0
  20. package/dist/common/utils/iconUtils.d.ts +2 -0
  21. package/dist/common/utils/iconUtils.d.ts.map +1 -0
  22. package/dist/common/utils/index.d.ts +2 -0
  23. package/dist/common/utils/index.d.ts.map +1 -0
  24. package/dist/form/components/fields/index.d.ts +2 -0
  25. package/dist/form/components/fields/index.d.ts.map +1 -0
  26. package/dist/form/components/form/form.vue.d.ts +42 -0
  27. package/dist/form/components/form/form.vue.d.ts.map +1 -0
  28. package/dist/form/components/form/index.d.ts +90 -0
  29. package/dist/form/components/form/index.d.ts.map +1 -0
  30. package/dist/form/components/form/props.d.ts +21 -0
  31. package/dist/form/components/form/props.d.ts.map +1 -0
  32. package/dist/form/components/form-item/form-item.vue.d.ts +19 -0
  33. package/dist/form/components/form-item/form-item.vue.d.ts.map +1 -0
  34. package/dist/form/components/form-item/index.d.ts +31 -0
  35. package/dist/form/components/form-item/index.d.ts.map +1 -0
  36. package/dist/form/components/form-item/props.d.ts +14 -0
  37. package/dist/form/components/form-item/props.d.ts.map +1 -0
  38. package/dist/form/hoc/index.d.ts +4 -0
  39. package/dist/form/hoc/index.d.ts.map +1 -0
  40. package/dist/form/hoc/useForm.d.ts +13 -0
  41. package/dist/form/hoc/useForm.d.ts.map +1 -0
  42. package/dist/form/hoc/useFormExpose.d.ts +24 -0
  43. package/dist/form/hoc/useFormExpose.d.ts.map +1 -0
  44. package/dist/form/hoc/useFormFetch.d.ts +25 -0
  45. package/dist/form/hoc/useFormFetch.d.ts.map +1 -0
  46. package/dist/form/index.d.ts +6 -0
  47. package/dist/form/index.d.ts.map +1 -0
  48. package/dist/form/utils/index.d.ts +9 -0
  49. package/dist/form/utils/index.d.ts.map +1 -0
  50. package/dist/global.d.ts +33 -0
  51. package/dist/global.d.ts.map +1 -0
  52. package/dist/index.css +3 -0
  53. package/dist/index.d.ts +12 -0
  54. package/dist/index.d.ts.map +1 -0
  55. package/dist/index.js +38948 -0
  56. package/dist/layout/components/fields/basic/basic.vue.d.ts +20 -0
  57. package/dist/layout/components/fields/basic/basic.vue.d.ts.map +1 -0
  58. package/dist/layout/components/fields/index.d.ts +2 -0
  59. package/dist/layout/components/fields/index.d.ts.map +1 -0
  60. package/dist/layout/components/fields/side/side.vue.d.ts +20 -0
  61. package/dist/layout/components/fields/side/side.vue.d.ts.map +1 -0
  62. package/dist/layout/components/fields/top/top.vue.d.ts +18 -0
  63. package/dist/layout/components/fields/top/top.vue.d.ts.map +1 -0
  64. package/dist/layout/components/layout/index.d.ts +22 -0
  65. package/dist/layout/components/layout/index.d.ts.map +1 -0
  66. package/dist/layout/components/layout/layout.vue.d.ts +15 -0
  67. package/dist/layout/components/layout/layout.vue.d.ts.map +1 -0
  68. package/dist/layout/components/layout/props.d.ts +4 -0
  69. package/dist/layout/components/layout/props.d.ts.map +1 -0
  70. package/dist/layout/hoc/index.d.ts +2 -0
  71. package/dist/layout/hoc/index.d.ts.map +1 -0
  72. package/dist/layout/hoc/useLayout.d.ts +12 -0
  73. package/dist/layout/hoc/useLayout.d.ts.map +1 -0
  74. package/dist/layout/index.d.ts +5 -0
  75. package/dist/layout/index.d.ts.map +1 -0
  76. package/dist/layout/utils/index.d.ts +4 -0
  77. package/dist/layout/utils/index.d.ts.map +1 -0
  78. package/dist/modal/components/form-modal/form-modal.vue.d.ts +46 -0
  79. package/dist/modal/components/form-modal/form-modal.vue.d.ts.map +1 -0
  80. package/dist/modal/components/form-modal/index.d.ts +101 -0
  81. package/dist/modal/components/form-modal/index.d.ts.map +1 -0
  82. package/dist/modal/components/form-modal/props.d.ts +19 -0
  83. package/dist/modal/components/form-modal/props.d.ts.map +1 -0
  84. package/dist/modal/components/modal/index.d.ts +53 -0
  85. package/dist/modal/components/modal/index.d.ts.map +1 -0
  86. package/dist/modal/components/modal/modal.vue.d.ts +29 -0
  87. package/dist/modal/components/modal/modal.vue.d.ts.map +1 -0
  88. package/dist/modal/components/modal/props.d.ts +24 -0
  89. package/dist/modal/components/modal/props.d.ts.map +1 -0
  90. package/dist/modal/hoc/index.d.ts +4 -0
  91. package/dist/modal/hoc/index.d.ts.map +1 -0
  92. package/dist/modal/hoc/useFormModal.d.ts +13 -0
  93. package/dist/modal/hoc/useFormModal.d.ts.map +1 -0
  94. package/dist/modal/hoc/useModal.d.ts +12 -0
  95. package/dist/modal/hoc/useModal.d.ts.map +1 -0
  96. package/dist/modal/hoc/useModalExpose.d.ts +8 -0
  97. package/dist/modal/hoc/useModalExpose.d.ts.map +1 -0
  98. package/dist/modal/index.d.ts +4 -0
  99. package/dist/modal/index.d.ts.map +1 -0
  100. package/dist/table/components/fields/action-column/action-column.vue.d.ts +6 -0
  101. package/dist/table/components/fields/action-column/action-column.vue.d.ts.map +1 -0
  102. package/dist/table/components/fields/action-column/props.d.ts +8 -0
  103. package/dist/table/components/fields/action-column/props.d.ts.map +1 -0
  104. package/dist/table/components/fields/index.d.ts +2 -0
  105. package/dist/table/components/fields/index.d.ts.map +1 -0
  106. package/dist/table/components/table/index.d.ts +58 -0
  107. package/dist/table/components/table/index.d.ts.map +1 -0
  108. package/dist/table/components/table/props.d.ts +43 -0
  109. package/dist/table/components/table/props.d.ts.map +1 -0
  110. package/dist/table/components/table/table.vue.d.ts +33 -0
  111. package/dist/table/components/table/table.vue.d.ts.map +1 -0
  112. package/dist/table/components/table-column/index.d.ts +6 -0
  113. package/dist/table/components/table-column/index.d.ts.map +1 -0
  114. package/dist/table/components/table-column/props.d.ts +6 -0
  115. package/dist/table/components/table-column/props.d.ts.map +1 -0
  116. package/dist/table/components/table-column/table-column.vue.d.ts +6 -0
  117. package/dist/table/components/table-column/table-column.vue.d.ts.map +1 -0
  118. package/dist/table/components/table-page/index.d.ts +12 -0
  119. package/dist/table/components/table-page/index.d.ts.map +1 -0
  120. package/dist/table/components/table-page/props.d.ts +13 -0
  121. package/dist/table/components/table-page/props.d.ts.map +1 -0
  122. package/dist/table/components/table-page/table-page.vue.d.ts +11 -0
  123. package/dist/table/components/table-page/table-page.vue.d.ts.map +1 -0
  124. package/dist/table/components/table-select/index.d.ts +73 -0
  125. package/dist/table/components/table-select/index.d.ts.map +1 -0
  126. package/dist/table/components/table-select/props.d.ts +21 -0
  127. package/dist/table/components/table-select/props.d.ts.map +1 -0
  128. package/dist/table/components/table-select/table-select.vue.d.ts +36 -0
  129. package/dist/table/components/table-select/table-select.vue.d.ts.map +1 -0
  130. package/dist/table/hoc/index.d.ts +3 -0
  131. package/dist/table/hoc/index.d.ts.map +1 -0
  132. package/dist/table/hoc/useTable.d.ts +33 -0
  133. package/dist/table/hoc/useTable.d.ts.map +1 -0
  134. package/dist/table/hoc/useTableExpose.d.ts +7 -0
  135. package/dist/table/hoc/useTableExpose.d.ts.map +1 -0
  136. package/dist/table/index.d.ts +8 -0
  137. package/dist/table/index.d.ts.map +1 -0
  138. package/dist/table/utils/index.d.ts +4 -0
  139. package/dist/table/utils/index.d.ts.map +1 -0
  140. package/package.json +42 -0
  141. package/src/button/components/button/button.vue +64 -0
  142. package/src/button/components/button/index.ts +2 -0
  143. package/src/button/components/button/props.ts +75 -0
  144. package/src/button/components/fields/index.ts +6 -0
  145. package/src/button/hoc/index.ts +1 -0
  146. package/src/button/hoc/useButton.ts +27 -0
  147. package/src/button/index.ts +4 -0
  148. package/src/button/utils/index.ts +32 -0
  149. package/src/common/index.ts +1 -0
  150. package/src/common/utils/iconUtils.ts +21 -0
  151. package/src/common/utils/index.ts +1 -0
  152. package/src/form/components/fields/index.ts +35 -0
  153. package/src/form/components/form/form.vue +130 -0
  154. package/src/form/components/form/index.ts +6 -0
  155. package/src/form/components/form/props.ts +73 -0
  156. package/src/form/components/form-item/form-item.vue +90 -0
  157. package/src/form/components/form-item/index.ts +6 -0
  158. package/src/form/components/form-item/props.ts +50 -0
  159. package/src/form/hoc/index.ts +3 -0
  160. package/src/form/hoc/useForm.ts +106 -0
  161. package/src/form/hoc/useFormExpose.ts +97 -0
  162. package/src/form/hoc/useFormFetch.ts +103 -0
  163. package/src/form/index.ts +5 -0
  164. package/src/form/utils/index.ts +149 -0
  165. package/src/global.ts +40 -0
  166. package/src/index.ts +37 -0
  167. package/src/layout/components/fields/basic/basic.vue +18 -0
  168. package/src/layout/components/fields/index.ts +10 -0
  169. package/src/layout/components/fields/side/side.vue +26 -0
  170. package/src/layout/components/fields/top/top.vue +13 -0
  171. package/src/layout/components/layout/index.ts +6 -0
  172. package/src/layout/components/layout/layout.vue +19 -0
  173. package/src/layout/components/layout/props.ts +3 -0
  174. package/src/layout/hoc/index.ts +1 -0
  175. package/src/layout/hoc/useLayout.ts +32 -0
  176. package/src/layout/index.ts +4 -0
  177. package/src/layout/utils/index.ts +31 -0
  178. package/src/modal/components/form-modal/form-modal.vue +158 -0
  179. package/src/modal/components/form-modal/index.ts +5 -0
  180. package/src/modal/components/form-modal/props.ts +61 -0
  181. package/src/modal/components/modal/index.ts +6 -0
  182. package/src/modal/components/modal/modal.vue +127 -0
  183. package/src/modal/components/modal/props.ts +78 -0
  184. package/src/modal/hoc/index.ts +3 -0
  185. package/src/modal/hoc/useFormModal.ts +140 -0
  186. package/src/modal/hoc/useModal.ts +151 -0
  187. package/src/modal/hoc/useModalExpose.ts +52 -0
  188. package/src/modal/index.ts +3 -0
  189. package/src/style/index.css +21 -0
  190. package/src/table/components/fields/action-column/action-column.vue +34 -0
  191. package/src/table/components/fields/action-column/props.ts +8 -0
  192. package/src/table/components/fields/index.ts +6 -0
  193. package/src/table/components/table/index.ts +6 -0
  194. package/src/table/components/table/props.ts +148 -0
  195. package/src/table/components/table/table.vue +77 -0
  196. package/src/table/components/table-column/index.ts +6 -0
  197. package/src/table/components/table-column/props.ts +26 -0
  198. package/src/table/components/table-column/table-column.vue +31 -0
  199. package/src/table/components/table-page/index.ts +6 -0
  200. package/src/table/components/table-page/props.ts +48 -0
  201. package/src/table/components/table-page/table-page.vue +51 -0
  202. package/src/table/components/table-select/index.ts +6 -0
  203. package/src/table/components/table-select/props.ts +79 -0
  204. package/src/table/components/table-select/table-select.vue +70 -0
  205. package/src/table/hoc/index.ts +2 -0
  206. package/src/table/hoc/useTable.ts +206 -0
  207. package/src/table/hoc/useTableExpose.ts +46 -0
  208. package/src/table/index.ts +7 -0
  209. package/src/table/utils/index.ts +37 -0
  210. package/tsconfig.json +30 -0
  211. package/vite.config.ts +49 -0
@@ -0,0 +1,158 @@
1
+ <template>
2
+ <Modal v-bind="{...modalProps,...attrs}" v-model="_open"
3
+ :header-class="'ax-form-modal-header'+' '+headerClass"
4
+ :footer-class="'ax-form-modal-footer'+' '+footerClass"
5
+ :body-class="'ax-form-modal-body'+' '+bodyClass"
6
+ :close-icon
7
+ :class="['ax-form-modal',className]"
8
+ ref="modalRef"
9
+ :show-close="false">
10
+ <template #header v-if="title||showClose">
11
+ <div class="flex justify-between items-center overflow-hidden gap-1">
12
+ <div :title="title" class="flex-1 whitespace-nowrap text-ellipsis overflow-hidden">{{ title }}</div>
13
+ <ElIcon @click="close">
14
+ <Close/>
15
+ </ElIcon>
16
+ </div>
17
+ </template>
18
+ <template #default>
19
+ <AxForm v-loading="_loading" v-bind="{...modalProps,...attrs} as AxFormProps" :is-default="false" ref="formRef">
20
+ <slot></slot>
21
+ </AxForm>
22
+ </template>
23
+ <template #footer v-if="slots.button||isDefault">
24
+ <template v-if="isDefault">
25
+ <ax-button v-bind="_confirmButton" @click="onConfirm"></ax-button>
26
+ <ax-button v-bind="_cancelButton" @click="close"></ax-button>
27
+ </template>
28
+ <slot name="button"></slot>
29
+ </template>
30
+ </Modal>
31
+ </template>
32
+
33
+ <script setup lang="ts">
34
+ import type {AxFormModalProps, AxFormModalEmits} from "./props";
35
+ import {useDefineProps, useFetch} from "@aoao-y33/hooks";
36
+ import {computed, type Ref, ref, useAttrs, useSlots} from "vue";
37
+ import {type DrawerInstance, ElDialog, ElDrawer, ElIcon,vLoading} from "element-plus";
38
+ import {AxButton, type AxButtonProps} from "@/button";
39
+ import {Close} from "@element-plus/icons-vue";
40
+ import {AxForm, type AxFormInstance, type AxFormProps, useFormExpose} from "@/form";
41
+
42
+ const {
43
+ type = 'dialog',
44
+ showClose = true,
45
+ open = false,
46
+ title = '',
47
+ isDefault = true,
48
+ confirmButton = {},
49
+ cancelButton = {},
50
+ className = "md:w-[30%]! w-[100%]!",
51
+ api = null,
52
+ apiConfig = {},
53
+ loading=false,
54
+ ...props
55
+ } = defineProps<AxFormModalProps>();
56
+
57
+ const emits = defineEmits<AxFormModalEmits>();
58
+
59
+ const _confirmButton = useDefineProps<AxButtonProps>(confirmButton, {
60
+ text: '确定',
61
+ icon: 'CircleCheckFilled',
62
+ componentProps: {
63
+ type: 'primary',
64
+ }
65
+ })
66
+
67
+ const _cancelButton = useDefineProps<AxButtonProps>(cancelButton, {
68
+ text: '取消',
69
+ icon: 'CircleCloseFilled',
70
+ componentProps: {
71
+ type: 'default',
72
+ }
73
+ })
74
+
75
+ const slots = useSlots();
76
+
77
+ const attrs = useAttrs();
78
+
79
+ const [,requestApi] = useFetch(api, apiConfig);
80
+
81
+ const modalProps = useDefineProps(props);
82
+
83
+ const _open = computed({
84
+ get() {
85
+ return open;
86
+ },
87
+ set(value) {
88
+ emits('update:open', value);
89
+ }
90
+ })
91
+
92
+ const _loading = computed(()=>{
93
+ return Boolean(loading||requestApi.getConfig().loading);
94
+ })
95
+
96
+
97
+ const modalRef = ref<DrawerInstance>();
98
+
99
+ const formRef = ref<AxFormInstance>() as Ref<AxFormInstance>;
100
+
101
+ const formApi = useFormExpose(formRef);
102
+
103
+ const Modal = computed(() => {
104
+ return type === 'dialog' ? ElDialog : ElDrawer;
105
+ })
106
+
107
+ const close = () => {
108
+ modalRef.value?.handleClose();
109
+ emits("cancel");
110
+ }
111
+
112
+ const onConfirm = () => {
113
+ const data = formApi.getValues();
114
+ formApi.getElForm().validate((res) => {
115
+ if(res){
116
+ if(requestApi.getReady()){
117
+ requestApi.load(data);
118
+ }
119
+ emits("confirm",data);
120
+ }
121
+ })
122
+
123
+ }
124
+
125
+ const getModal = () => {
126
+ return modalRef.value;
127
+ }
128
+
129
+ defineExpose({
130
+ getModal,
131
+ close,
132
+ ...formApi,
133
+ ...requestApi,
134
+ })
135
+ </script>
136
+
137
+ <style lang="scss">
138
+ .ax-form-modal {
139
+ padding: 0 !important;
140
+ }
141
+
142
+ .ax-form-modal-header {
143
+ padding: 8px 12px;
144
+ border-bottom: 1px solid var(--el-border-color);
145
+ }
146
+
147
+ .ax-form-modal-body {
148
+ flex: 1;
149
+ width: 100%;
150
+ height: 100%;
151
+ padding: 8px 12px;
152
+ }
153
+
154
+ .ax-form-modal-footer {
155
+ padding: 8px 12px;
156
+ border-top: 1px solid var(--el-border-color);
157
+ }
158
+ </style>
@@ -0,0 +1,5 @@
1
+ import formModal from './form-modal.vue';
2
+ export * from './props';
3
+ export const AxFormModal = formModal;
4
+ export default AxFormModal;
5
+ export type AxFormModalInstance = InstanceType<typeof formModal>;
@@ -0,0 +1,61 @@
1
+ import type {AxModalProps} from "@/modal";
2
+ import type {AxFormItemOptions, AxFormProps} from "@/form";
3
+ import type {EmitsToEventProps} from "@aoao-y33/utils";
4
+ import type {FieldsConfig} from "@aoao-y33/hooks";
5
+ import type {AxButtonOptions} from "@/button";
6
+ import type {EmitsToProps} from "vue";
7
+ import type {DrawerEmits} from "element-plus";
8
+
9
+ /**
10
+ * AxFormModal 表单弹窗组件属性接口
11
+ * 继承自 AxModalProps(弹窗属性)和 AxFormProps(表单属性),组合了弹窗和表单的双重功能
12
+ * @template T - 表单数据类型,必须是对象类型
13
+ */
14
+ export interface AxFormModalProps<T extends Record<string, any> = any> extends AxModalProps, Omit<AxFormProps<T>, 'size'> {
15
+ // 继承了弹窗的所有属性和表单的大部分属性(排除了 size,避免与弹窗尺寸冲突)
16
+ }
17
+
18
+ /**
19
+ * AxFormModal 表单弹窗组件事件发射接口
20
+ * @template T - 表单数据类型
21
+ */
22
+ export interface AxFormModalEmits<T extends Record<string, any> = any> {
23
+ /**
24
+ * 弹窗显示状态变化事件(用于 v-model:open 双向绑定)
25
+ * @param data - 新的显示状态(true/false)
26
+ */
27
+ 'update:open': [data: boolean]
28
+
29
+ /**
30
+ * 确认按钮点击事件,触发表单验证和提交
31
+ * @param data - 验证通过后的表单数据
32
+ */
33
+ 'confirm': [data: T]
34
+
35
+ /** 取消按钮点击事件或关闭弹窗时触发 */
36
+ 'cancel': []
37
+ }
38
+
39
+ /**
40
+ * AxFormModal 表单弹窗配置选项接口
41
+ * 整合了弹窗属性、表单属性、事件处理和字段配置
42
+ * @template T - 表单数据类型
43
+ */
44
+ export interface AxFormModalOptions<T extends Record<string, any> = any>
45
+ extends Omit<AxFormModalProps<T>, 'open'>, // 排除 open 属性(由内部状态管理)
46
+ EmitsToProps<DrawerEmits>, // 合并 Element Plus Drawer 的事件属性
47
+ EmitsToEventProps<AxFormModalEmits<T>> { // 合并自定义事件处理函数
48
+ /**
49
+ * 按钮配置映射表,用于配置弹窗中的操作按钮(确认、取消等)
50
+ * @see FieldsConfig - 字段配置类型
51
+ * @see AxButtonOptions - 按钮选项类型
52
+ */
53
+ buttonConfig?: FieldsConfig<AxButtonOptions>
54
+
55
+ /**
56
+ * 表单项配置映射表,用于配置弹窗内表单的各个字段
57
+ * @see FieldsConfig - 字段配置类型
58
+ * @see AxFormItemOptions - 表单项选项类型
59
+ */
60
+ fieldConfig?: FieldsConfig<AxFormItemOptions>
61
+ }
@@ -0,0 +1,6 @@
1
+ import modal from './modal.vue';
2
+
3
+ export * from './props';
4
+ export const AxModal = modal;
5
+ export type AxModalInstance = InstanceType<typeof modal>;
6
+ export default AxModal;
@@ -0,0 +1,127 @@
1
+ <template>
2
+ <Modal v-bind="{...modalProps,...attrs}" v-model="_open"
3
+ :header-class="'ax-modal-header'+' '+headerClass"
4
+ :footer-class="'ax-modal-footer'+' '+footerClass"
5
+ :body-class="'ax-modal-body'+' '+bodyClass"
6
+ :close-icon
7
+ :class="['ax-modal',className]"
8
+ ref="modalRef"
9
+ :show-close="false" >
10
+ <template #header v-if="title||showClose">
11
+ <div class="flex justify-between items-center overflow-hidden gap-1">
12
+ <div :title="title" class="flex-1 whitespace-nowrap text-ellipsis overflow-hidden">{{title}}</div>
13
+ <ElIcon @click="close">
14
+ <Close/>
15
+ </ElIcon>
16
+ </div>
17
+ </template>
18
+ <template #default>
19
+ <slot></slot>
20
+ </template>
21
+ <template #footer v-if="slots.button||isDefault">
22
+ <template v-if="isDefault">
23
+ <ax-button v-bind="_confirmButton" @click="onConfirm"></ax-button>
24
+ <ax-button v-bind="_cancelButton" @click="close"></ax-button>
25
+ </template>
26
+ <slot name="button"></slot>
27
+ </template>
28
+ </Modal>
29
+ </template>
30
+
31
+ <script setup lang="ts">
32
+ import type {AxModalProps, AxModalEmits} from "./props";
33
+ import {useDefineProps} from "@aoao-y33/hooks";
34
+ import {computed, ref, useAttrs, useSlots} from "vue";
35
+ import {type DrawerInstance, ElDialog, ElDrawer,ElIcon} from "element-plus";
36
+ import {AxButton, type AxButtonProps} from "@/button";
37
+ import {Close} from "@element-plus/icons-vue";
38
+
39
+ const {
40
+ type = 'dialog',
41
+ showClose = true,
42
+ open = false,
43
+ title = '',
44
+ isDefault = true,
45
+ confirmButton = {},
46
+ cancelButton = {},
47
+ className = "md:w-[30%]! w-[100%]!",
48
+ ...props
49
+ } = defineProps<AxModalProps>();
50
+
51
+ const emits = defineEmits<AxModalEmits>();
52
+
53
+ const _confirmButton = useDefineProps<AxButtonProps>(confirmButton, {
54
+ text: '确定',
55
+ icon: 'CircleCheckFilled',
56
+ componentProps: {
57
+ type: 'primary',
58
+ }
59
+ })
60
+
61
+ const _cancelButton = useDefineProps<AxButtonProps>(cancelButton, {
62
+ text: '取消',
63
+ icon: 'CircleCloseFilled',
64
+ componentProps: {
65
+ type: 'default',
66
+ }
67
+ })
68
+
69
+ const slots = useSlots();
70
+
71
+ const attrs = useAttrs();
72
+
73
+ const modalProps = useDefineProps(props);
74
+
75
+ const _open = computed({
76
+ get() {
77
+ return open;
78
+ },
79
+ set(value) {
80
+ emits('update:open', value);
81
+ }
82
+ })
83
+
84
+ const modalRef = ref<DrawerInstance>();
85
+
86
+ const Modal = computed(() => {
87
+ return type === 'dialog' ? ElDialog : ElDrawer;
88
+ })
89
+
90
+ const close = ()=>{
91
+ modalRef.value?.handleClose();
92
+ emits("cancel");
93
+ }
94
+
95
+ const onConfirm=()=>{
96
+ emits("confirm");
97
+ }
98
+
99
+ const getModal =()=>{
100
+ return modalRef.value;
101
+ }
102
+
103
+ defineExpose({
104
+ getModal,
105
+ close
106
+ })
107
+ </script>
108
+
109
+ <style lang="scss">
110
+ .ax-modal{
111
+ padding: 0 !important;
112
+ }
113
+ .ax-modal-header{
114
+ padding: 8px 12px;
115
+ border-bottom: 1px solid var(--el-border-color);
116
+ }
117
+ .ax-modal-body{
118
+ flex:1;
119
+ width: 100%;
120
+ height: 100%;
121
+ padding: 8px 12px;
122
+ }
123
+ .ax-modal-footer{
124
+ padding: 8px 12px;
125
+ border-top: 1px solid var(--el-border-color);
126
+ }
127
+ </style>
@@ -0,0 +1,78 @@
1
+ import type {DrawerProps,DrawerEmits} from "element-plus";
2
+ import type {AxButtonOptions, AxButtonProps} from "@/button";
3
+ import type {EmitsToEventProps} from "@aoao-y33/utils";
4
+ import type {Component, EmitsToProps} from "vue";
5
+ import type {FieldsConfig} from "@aoao-y33/hooks";
6
+
7
+ /**
8
+ * AxModal 弹窗组件属性接口
9
+ * 继承自 Element Plus DrawerProps,扩展了通用弹窗功能
10
+ * 支持 Drawer(抽屉)和 Dialog(对话框)两种展示模式
11
+ */
12
+ export interface AxModalProps extends DrawerProps{
13
+ /**
14
+ * 弹窗类型,决定使用哪种展示形式
15
+ * - 'drawer': 抽屉式弹窗,从屏幕边缘滑出
16
+ * - 'dialog': 对话框式弹窗,居中显示
17
+ * @default 'drawer'
18
+ */
19
+ type?:'drawer'|'dialog',
20
+
21
+ /** 弹窗标题,显示在弹窗顶部 */
22
+ title?:string
23
+
24
+ /** 弹窗的显示/隐藏状态,用于外部控制 */
25
+ open?:boolean
26
+
27
+ /** 自定义 CSS 类名,用于样式定制 */
28
+ className?:string
29
+
30
+ /** 确认按钮的配置项,用于自定义确认按钮的外观和行为 */
31
+ confirmButton?:AxButtonProps
32
+
33
+ /** 取消按钮的配置项,用于自定义取消按钮的外观和行为 */
34
+ cancelButton?:AxButtonProps
35
+
36
+ /** 是否使用默认配置,启用后将自动应用预设的弹窗样式和按钮 */
37
+ isDefault?:boolean
38
+ }
39
+
40
+ /**
41
+ * AxModal 弹窗组件事件发射接口
42
+ */
43
+ export interface AxModalEmits{
44
+ /**
45
+ * 弹窗显示状态变化事件(用于 v-model:open 双向绑定)
46
+ * @param data - 新的显示状态(true/false)
47
+ */
48
+ 'update:open':[data:boolean],
49
+
50
+ /** 取消按钮点击或关闭弹窗时触发 */
51
+ 'cancel':[]
52
+
53
+ /** 确认按钮点击时触发 */
54
+ 'confirm':[]
55
+ }
56
+
57
+ /**
58
+ * AxModal 弹窗配置选项接口
59
+ * 整合了弹窗属性、事件处理和动态内容配置
60
+ */
61
+ export interface AxModalOptions
62
+ extends Omit<AxModalProps, 'open'>, // 排除 open 属性(由内部状态管理)
63
+ EmitsToEventProps<AxModalEmits>, // 合并自定义事件处理函数
64
+ EmitsToProps<DrawerEmits>{ // 合并 Element Plus Drawer 的事件属性
65
+ /**
66
+ * 动态渲染的组件,用于在弹窗内容区域显示自定义组件
67
+ * @example
68
+ * component: UserFormComponent
69
+ */
70
+ component?:Component,
71
+
72
+ /**
73
+ * 按钮配置映射表,用于配置弹窗中的各种操作按钮
74
+ * @see FieldsConfig - 字段配置类型
75
+ * @see AxButtonOptions - 按钮选项类型
76
+ */
77
+ buttonConfig?:FieldsConfig<AxButtonOptions>
78
+ }
@@ -0,0 +1,3 @@
1
+ export * from './useModal';
2
+ export * from './useFormModal';
3
+ export * from './useModalExpose';
@@ -0,0 +1,140 @@
1
+ import {type AxFormModalOptions, AxFormModal, useModalExpose, type ModalApi} from "@/modal";
2
+ import {type FieldsApi, type StateApi, useComponentPool, useState} from "@aoao-y33/hooks";
3
+ import {omit} from "lodash";
4
+ import {AxButton, type AxButtonOptions} from "@/button";
5
+ import {AxFormItem, type AxFormItemOptions, type FormApi, type FormFetchApi, useFormExpose, useFormFetch} from "@/form";
6
+ import {type Component, defineComponent, h, ref} from "vue";
7
+
8
+ /**
9
+ * UseFormModal Hook 返回的 API 接口
10
+ * 整合了弹窗控制、表单操作和请求管理的完整功能集
11
+ * @template T - 表单数据类型
12
+ */
13
+ export interface UseFormModalApi<T extends Record<string, any>> extends ModalApi, FormApi<T>, FormFetchApi<T> {
14
+ /**
15
+ * 打开弹窗的方法
16
+ * 调用后将显示表单弹窗
17
+ */
18
+ readonly open: () => void;
19
+
20
+ /** 按钮组件池 API,用于管理弹窗中的操作按钮(确认、取消等) */
21
+ readonly buttonsApi: FieldsApi<AxButtonOptions>
22
+
23
+ /**
24
+ * 弹窗属性状态管理器
25
+ * 用于动态更新弹窗配置(不包含 buttonConfig 和 fieldConfig)
26
+ */
27
+ readonly setModal: StateApi<Omit<AxFormModalOptions, 'buttonConfig' | 'fieldConfig'>>
28
+
29
+ /** 表单项组件池 API,用于管理弹窗内表单的各个字段配置 */
30
+ readonly fieldsApi: FieldsApi<AxFormItemOptions>
31
+ }
32
+
33
+ /**
34
+ * 表单弹窗 Hook,用于创建集成了表单功能的弹窗组件
35
+ *
36
+ * 该 Hook 封装了弹窗和表单的组合逻辑,包括:
37
+ * - 弹窗显示/隐藏控制
38
+ * - 表单字段动态配置
39
+ * - 按钮动态配置
40
+ * - 表单验证和提交
41
+ * - 数据双向绑定
42
+ *
43
+ * @param options - 表单弹窗初始配置选项
44
+ * @returns [Modal 组件, FormModal API] 元组
45
+ *
46
+ * @example
47
+ * const [FormModal, modalApi] = useFormModal({
48
+ * title: '编辑用户',
49
+ * api: submitUserData,
50
+ * fieldConfig: {
51
+ * username: { label: '用户名', type: 'input', vtypes: ['required'] },
52
+ * email: { label: '邮箱', type: 'input', vtypes: ['required', 'mail'] }
53
+ * },
54
+ * buttonConfig: {
55
+ * confirm: { text: '保存' },
56
+ * cancel: { text: '取消' }
57
+ * }
58
+ * })
59
+ *
60
+ * // 在模板中使用
61
+ * <FormModal />
62
+ *
63
+ * // 通过 API 控制弹窗
64
+ * modalApi.open() // 打开弹窗
65
+ * modalApi.fieldsApi.addField('phone', { label: '电话', type: 'input' })
66
+ * modalApi.requestApi.submit()
67
+ */
68
+ export function useFormModal<T extends Record<string, any> = any>(options: AxFormModalOptions<T> = {}): [Component, UseFormModalApi<T>] {
69
+ // 创建弹窗属性状态,排除 buttonConfig 和 fieldConfig(它们由独立的组件池管理)
70
+ const [props, setModal] = useState(omit(options, ['buttonConfig', 'fieldConfig']))
71
+
72
+ // 创建按钮组件池,用于管理和渲染弹窗中的操作按钮
73
+ const [Buttons, buttonsApi] = useComponentPool<AxButtonOptions>(AxButton, options.buttonConfig);
74
+
75
+ // 创建表单项组件池,用于管理和渲染弹窗内的表单字段
76
+ const [Fields, fieldsApi] = useComponentPool<AxFormItemOptions>(AxFormItem, options.fieldConfig);
77
+
78
+ // 创建弹窗引用,用于访问弹窗实例的方法
79
+ const modalRef = ref();
80
+
81
+ // 获取弹窗暴露的 API(关闭、销毁等方法)
82
+ const modalApi = useModalExpose(modalRef);
83
+
84
+ // 获取表单暴露的 API(验证、重置、获取数据等方法)
85
+ const formApi = useFormExpose<T>(modalRef);
86
+
87
+ // 获取表单请求 API(提交、数据获取等异步操作)
88
+ const requestApi = useFormFetch<T>(modalRef);
89
+
90
+ // 创建内部可见性状态,用于控制弹窗显示/隐藏
91
+ const [visible, setVisible] = useState(false);
92
+
93
+ /**
94
+ * 打开弹窗方法
95
+ * 设置内部可见性状态为 true
96
+ */
97
+ const open = () => {
98
+ setVisible(true);
99
+ }
100
+
101
+ // 定义表单弹窗渲染组件
102
+ const Modal = defineComponent({
103
+ setup() {
104
+ const slots: Record<string, Component> = {};
105
+
106
+ // 如果存在字段配置,创建默认插槽(表单项列表)
107
+ if (fieldsApi.getList().length) {
108
+ slots.default = () => h(Fields);
109
+ }
110
+
111
+ // 如果存在按钮配置,创建按钮插槽
112
+ if (buttonsApi.getList().length) {
113
+ slots.button = () => h(Buttons);
114
+ }
115
+
116
+ // 渲染 AxFormModal 组件,传入 ref、属性和事件处理
117
+ return () => h(AxFormModal, {
118
+ ref: modalRef,
119
+ ...props.value,
120
+ // 监听弹窗显示状态变化,同步到内部状态
121
+ "onUpdate:open": (val: boolean) => {
122
+ setVisible(val);
123
+ },
124
+ // 绑定内部可见性状态到弹窗
125
+ open: visible.value,
126
+ }, slots);
127
+ }
128
+ })
129
+
130
+ // 返回弹窗组件和完整的 API 集合(合并弹窗、表单、请求 API)
131
+ return [Modal, {
132
+ ...modalApi,
133
+ ...formApi,
134
+ ...requestApi,
135
+ buttonsApi,
136
+ fieldsApi,
137
+ open,
138
+ setModal
139
+ }] as const;
140
+ }