easybill-ui 1.2.26 → 1.3.1

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.
@@ -0,0 +1,95 @@
1
+ <template>
2
+ <CurdFormGroup v-for="(item, index) in props.schema.items" v-show="!schemaItemHidden(item)" :key="index" :item="item" :title="item.groupName" :icon="item.icon" :label-position="item.labelPosition">
3
+ <template v-if="item.headerRight" #headerRight>
4
+ <component :is="item.headerRight" :schema="props.schema" :schemaItem="item" :form-model="form" />
5
+ </template>
6
+ <template v-if="item.headerTitle" #title>
7
+ <component :is="item.headerTitle" :schema="props.schema" :schemaItem="item" :form-model="form" />
8
+ </template>
9
+ <template v-if="item.headerBottom" #headerBottom>
10
+ <component :is="item.headerBottom" :schema="props.schema" :schemaItem="item" :form-model="form" />
11
+ </template>
12
+ <div class="curdform-group-content" data-instance-form-wrap>
13
+ <CurdForm
14
+ :ref="(el: Element | ComponentPublicInstance | null) => (formRef[(item.step || '') + item.groupName + index] = el as InstanceType<typeof CurdForm>)"
15
+ v-model="form"
16
+ :form-schema="item.schema"
17
+ :extend-context="extendContext"
18
+ :validateOnRuleChange="false"
19
+ :scroll-to-error="true"
20
+ @change="onChange"
21
+ />
22
+ </div>
23
+ </CurdFormGroup>
24
+ </template>
25
+
26
+ <script lang="ts" setup>
27
+ import { CurdForm } from "easybill-ui"
28
+ import type { ComponentPublicInstance, PropType } from "vue"
29
+ import { watch } from "vue"
30
+ import type { CurdGroupFormSchema } from "../types"
31
+ import CurdFormGroup from "./components/CurdFormGroup.vue"
32
+ import { useFormHook } from "./hooks/useFormHook"
33
+ const props = defineProps({
34
+ modelValue: {
35
+ type: Object as PropType<Record<string, unknown>>,
36
+ default: () => ({}),
37
+ },
38
+ schema: {
39
+ type: Object as PropType<CurdGroupFormSchema>,
40
+ default: () => ({}),
41
+ },
42
+ })
43
+
44
+ const emits = defineEmits(["update:modelValue", "change", "loadOptions"])
45
+ const { form, formRef, schema: formSchema, validate, schemaItemHidden } = useFormHook()
46
+ const init = () => {
47
+ form.value = props.modelValue || {}
48
+ formSchema.value = props.schema
49
+ }
50
+ init()
51
+ watch(
52
+ () => props.schema,
53
+ () => {
54
+ formSchema.value = props.schema
55
+ },
56
+ )
57
+
58
+ watch(
59
+ () => props.modelValue,
60
+ () => {
61
+ if (form.value != props.modelValue) {
62
+ form.value = props.modelValue
63
+ // emits("update:modelValue", form.value)
64
+ }
65
+ },
66
+ )
67
+
68
+ const loadOptions = (prop: string, config?: unknown) => {
69
+ if (!props.schema) return
70
+ let has = false
71
+ for (const index in props.schema.items) {
72
+ const group = props.schema.items[index]
73
+ const formItem = group.schema.formItem
74
+ for (const i in formItem) {
75
+ const item = formItem[i]
76
+ if (item.prop == prop) {
77
+ has = true
78
+ formRef.value[(group.step || "") + group.groupName + index]?.loadOptions(prop, config)
79
+ }
80
+ }
81
+ }
82
+ if (!has) {
83
+ emits("loadOptions", prop)
84
+ }
85
+ }
86
+ const extendContext = {
87
+ loadOptions,
88
+ }
89
+
90
+ const onChange = (v: unknown, l: unknown) => {
91
+ emits("change", v, l)
92
+ }
93
+
94
+ defineExpose({ loadOptions, validate })
95
+ </script>
@@ -0,0 +1,39 @@
1
+ <template>
2
+ <div class="curdform-group" :style="props.item.style" :class="props.item.class">
3
+ <div v-if="props.title || $slots.title" class="curdform-group-head">
4
+ <div class="left">
5
+ <span v-if="props.icon" class="icon"><i v-if="typeof props.icon == 'string'" :class="props.icon"></i><component v-else :is="props.icon"></component></span>
6
+ <div v-if="!$slots.title" class="title">{{ props.title }}</div>
7
+ <slot name="title"></slot>
8
+ </div>
9
+ <div class="right">
10
+ <slot name="headerRight"></slot>
11
+ </div>
12
+ </div>
13
+ <div v-if="props.item.desc" class="curdform-group-desc">{{ props.item.desc }}</div>
14
+ <slot name="headerBottom"></slot>
15
+ <div v-if="$slots.default" class="curdform-group-body">
16
+ <slot></slot>
17
+ </div>
18
+ </div>
19
+ </template>
20
+
21
+ <script lang="ts" setup>
22
+ import type { PropType } from "vue"
23
+ import type { CurdGroupFormSchemaItem } from "../../types"
24
+
25
+ const props = defineProps({
26
+ title: {
27
+ type: String,
28
+ default: "",
29
+ },
30
+ icon: {
31
+ type: String,
32
+ default: "",
33
+ },
34
+ item: {
35
+ type: Object as PropType<CurdGroupFormSchemaItem>,
36
+ default: () => ({}),
37
+ },
38
+ })
39
+ </script>
@@ -0,0 +1,55 @@
1
+ import { CurdForm } from "easybill-ui"
2
+ import { ref, type Ref } from "vue"
3
+ import type { Schema, SchemaItem } from "../../types"
4
+
5
+ export const useFormHook = (): {
6
+ form: Ref<Record<string, unknown>>
7
+ formRef: Ref<Record<string, InstanceType<typeof CurdForm>>>
8
+ submit: () => void
9
+ schema: Ref<Schema | undefined>
10
+ validate: (callback: (valid: boolean) => void) => void
11
+ loading: Ref<boolean>
12
+ schemaItemHidden: (item: SchemaItem) => boolean
13
+ } => {
14
+ const formRef = ref<Record<string, InstanceType<typeof CurdForm>>>({})
15
+ const form = ref<Record<string, unknown>>({})
16
+ const schema = ref<Schema>()
17
+ const loading = ref(false)
18
+ const schemaItemHidden = (item: SchemaItem) => {
19
+ if (item?.hidden && item?.hidden instanceof Function) {
20
+ return item.hidden(form.value, item)
21
+ }
22
+ return !!item?.hidden
23
+ }
24
+ const validate = (callback: (valid: boolean) => void) => {
25
+ const validMap: boolean[] = []
26
+ for (const i in formRef.value) {
27
+ const curSchema = schema.value?.items.find((a, index) => (a.step || "") + a.groupName + index == i)
28
+ // 如果当前item隐藏了,则直接跳过校验
29
+ if (curSchema && schemaItemHidden(curSchema)) {
30
+ validMap.push(true)
31
+ continue
32
+ }
33
+ const cur = formRef.value[i]
34
+ cur.validate((valid: boolean) => {
35
+ validMap.push(valid)
36
+ if (validMap.length >= Object.keys(formRef.value).length && callback) callback(validMap.every((a) => a))
37
+ })
38
+ }
39
+ }
40
+ const submit = () => {
41
+ validate((valid) => {
42
+ if (!valid) return
43
+ })
44
+ }
45
+
46
+ return {
47
+ form,
48
+ formRef,
49
+ submit,
50
+ schema,
51
+ validate,
52
+ loading,
53
+ schemaItemHidden,
54
+ }
55
+ }
@@ -0,0 +1,22 @@
1
+ import type { Fields, FormSchema } from "easybill-ui"
2
+ import type { Component, VNode } from "vue"
3
+ export interface CurdGroupFormSchema {
4
+ items: CurdGroupFormSchemaItem[]
5
+ }
6
+
7
+ export interface CurdGroupFormSchemaItem {
8
+ groupName: string
9
+ schema: FormSchema
10
+ icon?: string
11
+ prop?: string // 唯一标识 不可修改
12
+ desc?: string
13
+ step?: string
14
+ stepIndex?: number
15
+ class?: string
16
+ style?: string
17
+ labelPosition?: string | "left" | "right" | "top"
18
+ hidden?: boolean | ((form: Fields, schemaItem: CurdGroupFormSchemaItem) => boolean)
19
+ headerRight?: Component | ((props: { schema: CurdGroupFormSchema; schemaItem: CurdGroupFormSchemaItem; formModel: Fields }) => VNode | VNode[])
20
+ headerBottom?: Component | ((props: { schema: CurdGroupFormSchema; schemaItem: CurdGroupFormSchemaItem; formModel: Fields }) => VNode | VNode[])
21
+ headerTitle?: Component | ((props: { schema: CurdGroupFormSchema; schemaItem: CurdGroupFormSchemaItem; formModel: Fields }) => VNode | VNode[])
22
+ }
@@ -1,30 +1,43 @@
1
1
  <template>
2
2
  <component :is="componentName" v-bind="containerProps">
3
- <el-steps v-if="stepSchemaList.length > 1" :active="step" align-center style="margin-bottom: 20px; position: sticky; top: 0; z-index: 2000; background: var(--el-bg-color)" v-bind="stepProps">
4
- <el-step v-for="(item, i) in stepSchemaList" :key="i" :title="item.name" :description="item.description" />
3
+ <el-steps v-if="isGroupMode && hasMultipleSteps && !stepComponent" :active="activeStep" align-center style="margin-bottom: 20px; position: sticky; top: 0; z-index: 2000; background: var(--el-bg-color)" v-bind="stepProps">
4
+ <el-step v-for="(stepItem, i) in stepList" :key="i" :title="stepItem.name" />
5
5
  </el-steps>
6
+ <component v-if="stepComponent" :is="stepComponent" :step="activeStep" :steps="stepList" />
6
7
  <div v-loading="confirmLoading" class="form-dialog-content">
7
- <template v-for="(item, i) in stepSchemaList" :key="i">
8
- <curd-form v-show="step == i" ref="curdFormRef" v-model="form" :fields="fields" :form-schema="item.formSchema" :extend-context="extendContexts" />
8
+ <!-- 单表单模式 -->
9
+ <curd-form v-if="isFormMode" ref="curdFormRef" v-model="form" :fields="fields" :form-schema="formSchema" :extend-context="extendContexts" />
10
+ <!-- 分组表单模式 -->
11
+ <template v-else-if="isGroupMode">
12
+ <div v-for="(stepItem, i) in stepList" :key="i" class="form-dialog-step" v-show="activeStep === i">
13
+ <curd-group-form :ref="(el: any) => el && (groupFormRef[i] = el)" v-model="form" :schema="stepItem.schema" :fields="fields" :extend-context="extendContexts" />
14
+ </div>
9
15
  </template>
10
16
  </div>
11
17
  <template #footer>
12
- <span v-if="handleOk" class="dialog-footer">
18
+ <component v-if="footerComponent" :is="footerComponent" />
19
+ <span v-else-if="handleOk" class="dialog-footer">
13
20
  <el-button v-if="cancelBtnTextLabel" :disabled="confirmLoading" type="default" @click="onCancel()">{{ cancelBtnTextLabel }}</el-button>
14
- <el-button v-if="stepSchemaList.length > 1 && step > 0" :disabled="confirmLoading" type="primary" plain @click="prev">{{ t("el.formDialog.preStep") }}</el-button>
15
- <el-button v-if="stepSchemaList.length > 1 && step < stepSchemaList.length - 1" :disabled="confirmLoading" type="primary" plain @click="next">{{ t("el.formDialog.nextStep") }}</el-button>
16
- <el-button v-if="step >= stepSchemaList.length - 1" :disabled="confirmLoading" type="primary" :loading="confirmLoading" @click="onOk">{{ confirmBtnTextLabel }}</el-button>
21
+ <el-button v-if="isGroupMode && hasMultipleSteps && canPrev" :disabled="confirmLoading" type="primary" plain @click="prev()">{{ t("el.formDialog.preStep") }}</el-button>
22
+ <el-button v-if="isGroupMode && hasMultipleSteps && canNext" :disabled="confirmLoading" type="primary" plain @click="next()">{{ t("el.formDialog.nextStep") }}</el-button>
23
+ <el-button v-if="!isGroupMode || isLastStep" :disabled="confirmLoading" type="primary" :loading="confirmLoading" @click="onOk">{{ confirmBtnTextLabel }}</el-button>
17
24
  </span>
18
25
  </template>
19
26
  </component>
20
27
  </template>
21
28
 
22
29
  <script lang="ts">
23
- import { useLocale } from "easybill-ui"
24
- import { computed, defineComponent, type PropType, provide, reactive, ref, type Ref, shallowRef, toRefs, useAttrs } from "vue"
30
+ import { CurdForm, CurdGroupForm, type CurdGroupFormSchema, useLocale } from "easybill-ui"
31
+ import { computed, defineComponent, type PropType, provide, reactive, ref, type Ref, toRefs, useAttrs } from "vue"
25
32
  import { type Fields, type FormSchema } from "../../CurdForm"
33
+ import { useStepList } from "./hooks/useStepList"
34
+ import { useStepNavigation } from "./hooks/useStepNavigation"
26
35
  export default defineComponent({
27
36
  name: "FormDialog",
37
+ components: {
38
+ CurdForm,
39
+ CurdGroupForm,
40
+ },
28
41
  props: {
29
42
  title: {
30
43
  type: String,
@@ -35,14 +48,15 @@ export default defineComponent({
35
48
  type: Function as PropType<() => void>,
36
49
  default: null,
37
50
  },
38
- stepSchema: {
39
- type: Array as PropType<{ name: string; description?: string; formSchema: FormSchema }[]>,
40
- default: () => [],
41
- },
42
51
  formSchema: {
43
52
  // 表单项
44
53
  type: Object as PropType<FormSchema>,
45
- default: () => ({}),
54
+ default: () => null,
55
+ },
56
+ groupSchema: {
57
+ // 分组表单项
58
+ type: Object as PropType<CurdGroupFormSchema>,
59
+ default: () => null,
46
60
  },
47
61
  fields: {
48
62
  // 默认值,一般编辑时传入
@@ -84,45 +98,66 @@ export default defineComponent({
84
98
  type: String as PropType<"dialog" | "drawer">,
85
99
  default: "dialog",
86
100
  },
101
+ stepComponent: {
102
+ type: Object,
103
+ default: null,
104
+ },
105
+ footerComponent: {
106
+ type: Object,
107
+ default: null,
108
+ },
87
109
  },
88
110
  setup(props) {
89
111
  const attrs = useAttrs()
90
112
  const curdFormRef = ref()
91
113
  const form = ref<Fields>({})
92
114
  const state = reactive({
93
- step: 0,
94
115
  visible: true,
95
116
  confirmLoading: false,
96
117
  })
97
118
  const { t } = useLocale()
98
- const stepSchemaList = props.stepSchema?.length ? shallowRef(props.stepSchema) : shallowRef([{ name: "step1", description: "", formSchema: props.formSchema }])
99
- const prev = () => {
100
- if (state.step > 0) {
101
- state.step--
102
- }
103
- }
104
- const next = () => {
105
- if (state.step < stepSchemaList.value.length - 1) {
106
- state.confirmLoading = true
107
- curdFormRef.value[state.step]?.validate((valid: boolean) => {
108
- state.confirmLoading = false
109
- if (valid) state.step++
110
- })
111
- }
112
- }
119
+
120
+ // 模式判断
121
+ const isGroupMode = computed(() => !!props.groupSchema)
122
+ const isFormMode = computed(() => !!props.formSchema && !isGroupMode.value)
123
+
124
+ // 步骤列表
125
+ const { stepList, stepCount, hasMultipleSteps } = useStepList(computed(() => props.groupSchema))
126
+
127
+ // 步骤导航
128
+ const { activeStep, groupFormRef, canPrev, canNext, isLastStep, prev, next, validateCurrentStep } = useStepNavigation(stepCount)
129
+
113
130
  const onOk = () => {
114
131
  state.confirmLoading = true
115
- curdFormRef.value[state.step]
116
- ?.validate()
117
- .then(async () => {
132
+
133
+ const getValidatePromise = (): Promise<boolean> => {
134
+ if (isFormMode.value) {
135
+ return (
136
+ curdFormRef.value
137
+ ?.validate()
138
+ .then(() => true)
139
+ .catch(() => false) ?? Promise.resolve(true)
140
+ )
141
+ }
142
+
143
+ return new Promise<boolean>((resolve) => {
144
+ validateCurrentStep((valid) => resolve(valid))
145
+ })
146
+ }
147
+
148
+ getValidatePromise()
149
+ .then(async (valid) => {
150
+ if (!valid) {
151
+ state.confirmLoading = false
152
+ return
153
+ }
118
154
  const pass = await (props.handleOk && props.handleOk(form.value, state)).finally(() => (state.confirmLoading = false))
119
155
  if (typeof pass == "undefined" || pass) {
120
156
  state.visible = false
121
157
  onCancel()
122
158
  }
123
159
  })
124
- .catch((e: Error) => {
125
- console.error(e)
160
+ .catch(() => {
126
161
  state.confirmLoading = false
127
162
  })
128
163
  }
@@ -141,16 +176,12 @@ export default defineComponent({
141
176
  }, 300)
142
177
  }
143
178
  const loadOptions = (prop: string, config?: unknown) => {
144
- if (!stepSchemaList.value.length) return
145
- for (const i in stepSchemaList.value) {
146
- const group = stepSchemaList.value[i]
147
- const formItem = group.formSchema.formItem
148
- for (const j in formItem) {
149
- const item = formItem[j]
150
- if (item.prop == prop) {
151
- curdFormRef.value[i]?.loadOptions(prop, config)
152
- }
153
- }
179
+ if (isFormMode.value) {
180
+ curdFormRef.value?.loadOptions(prop, config)
181
+ } else if (isGroupMode.value) {
182
+ Object.values(groupFormRef.value).forEach((form) => {
183
+ form?.loadOptions(prop, config)
184
+ })
154
185
  }
155
186
  }
156
187
  const extendContexts = {
@@ -186,11 +217,31 @@ export default defineComponent({
186
217
  const formDialogContext = reactive({
187
218
  form,
188
219
  state,
220
+ stepList,
221
+ activeStep,
189
222
  loadOptions,
190
223
  prev,
191
224
  next,
225
+ goTo: (step: number) => {
226
+ if (step >= 0 && step < stepCount.value) {
227
+ // 验证当前步骤
228
+ validateCurrentStep((valid) => {
229
+ if (valid) {
230
+ activeStep.value = step
231
+ }
232
+ })
233
+ }
234
+ },
192
235
  close: onBeforeClose,
193
236
  handleOk: onOk,
237
+ validateCurrentStep,
238
+ canPrev,
239
+ canNext,
240
+ isLastStep,
241
+ isGroupMode,
242
+ isFormMode,
243
+ confirmBtnTextLabel,
244
+ cancelBtnTextLabel,
194
245
  })
195
246
  provide("formDialogContext", formDialogContext)
196
247
  return {
@@ -199,7 +250,7 @@ export default defineComponent({
199
250
  onCancel,
200
251
  onBeforeClose,
201
252
  curdFormRef,
202
- stepSchemaList,
253
+ stepList,
203
254
  form,
204
255
  prev,
205
256
  next,
@@ -209,6 +260,15 @@ export default defineComponent({
209
260
  cancelBtnTextLabel,
210
261
  componentName,
211
262
  containerProps,
263
+ isGroupMode,
264
+ isFormMode,
265
+ hasMultipleSteps,
266
+ activeStep,
267
+ groupFormRef,
268
+ canPrev,
269
+ canNext,
270
+ isLastStep,
271
+ validateCurrentStep,
212
272
  }
213
273
  },
214
274
  })
@@ -0,0 +1,2 @@
1
+ export { useStepList, type StepItem } from "./useStepList"
2
+ export { useStepNavigation } from "./useStepNavigation"
@@ -0,0 +1,49 @@
1
+ import { computed, type ComputedRef } from "vue"
2
+ import type { CurdGroupFormSchema } from "../../../CurdGroupForm/types"
3
+
4
+ export interface StepItem {
5
+ name: string
6
+ stepIndex?: number
7
+ schema: {
8
+ items: CurdGroupFormSchema["items"]
9
+ }
10
+ }
11
+
12
+ export function useStepList(groupSchema: ComputedRef<CurdGroupFormSchema | null>) {
13
+ const stepList = computed<StepItem[]>(() => {
14
+ if (!groupSchema.value?.items) return []
15
+
16
+ const groups = new Map<string, StepItem>()
17
+
18
+ groupSchema.value.items.forEach((item) => {
19
+ const stepName = item.step || "其他"
20
+
21
+ if (!groups.has(stepName)) {
22
+ groups.set(stepName, {
23
+ name: stepName,
24
+ stepIndex: item.stepIndex,
25
+ schema: { items: [] }
26
+ })
27
+ }
28
+
29
+ groups.get(stepName)!.schema.items.push(item)
30
+ })
31
+
32
+ // 按 stepIndex 排序(undefined 排最后)
33
+ return Array.from(groups.values()).sort((a, b) => {
34
+ const indexA = a.stepIndex ?? Infinity
35
+ const indexB = b.stepIndex ?? Infinity
36
+ return indexA - indexB
37
+ })
38
+ })
39
+
40
+ const stepCount = computed(() => stepList.value.length)
41
+
42
+ const hasMultipleSteps = computed(() => stepList.value.length > 1)
43
+
44
+ return {
45
+ stepList,
46
+ stepCount,
47
+ hasMultipleSteps
48
+ }
49
+ }
@@ -0,0 +1,74 @@
1
+ import { computed, ref, type Ref } from "vue"
2
+ import type { CurdGroupForm } from "../../../CurdGroupForm"
3
+
4
+ interface ValidateFunction {
5
+ validate: (callback: (valid: boolean) => void) => void
6
+ }
7
+
8
+ export function useStepNavigation(stepCount: Ref<number>, onStepChange?: (step: number) => void) {
9
+ const activeStep = ref(0)
10
+ const groupFormRef = ref<Record<number, InstanceType<typeof CurdGroupForm>>>({})
11
+
12
+ const canPrev = computed(() => activeStep.value > 0)
13
+ const canNext = computed(() => activeStep.value < stepCount.value - 1)
14
+ const isLastStep = computed(() => activeStep.value >= stepCount.value - 1)
15
+
16
+ const setStep = (newStep: number) => {
17
+ if (newStep >= 0 && newStep < stepCount.value) {
18
+ activeStep.value = newStep
19
+ onStepChange?.(newStep)
20
+ }
21
+ }
22
+
23
+ const prev = () => {
24
+ if (canPrev.value) {
25
+ setStep(activeStep.value - 1)
26
+ }
27
+ }
28
+
29
+ const next = (onValidateFail?: () => void) => {
30
+ if (!canNext.value) return false
31
+
32
+ const currentForm = groupFormRef.value[activeStep.value] as unknown as ValidateFunction | undefined
33
+ if (currentForm?.validate) {
34
+ currentForm.validate((valid: boolean) => {
35
+ if (valid) {
36
+ setStep(activeStep.value + 1)
37
+ } else if (onValidateFail) {
38
+ onValidateFail()
39
+ }
40
+ })
41
+ } else {
42
+ setStep(activeStep.value + 1)
43
+ }
44
+ return true
45
+ }
46
+
47
+ const validateCurrentStep = (callback: (valid: boolean) => void) => {
48
+ const currentForm = groupFormRef.value[activeStep.value] as unknown as ValidateFunction | undefined
49
+ if (currentForm?.validate) {
50
+ currentForm.validate(callback)
51
+ } else {
52
+ callback(true)
53
+ }
54
+ }
55
+
56
+ const validateCurrentStepAsync = (): Promise<boolean> => {
57
+ return new Promise((resolve) => {
58
+ validateCurrentStep((valid) => resolve(valid))
59
+ })
60
+ }
61
+
62
+ return {
63
+ activeStep,
64
+ groupFormRef,
65
+ canPrev,
66
+ canNext,
67
+ isLastStep,
68
+ setStep,
69
+ prev,
70
+ next,
71
+ validateCurrentStep,
72
+ validateCurrentStepAsync,
73
+ }
74
+ }
@@ -1,12 +1,14 @@
1
+ import type { CurdGroupFormSchema } from "../../CurdGroupForm/types"
1
2
  import type { DialogProps, StepProps } from "element-plus"
2
3
  import type { Fields, FormContext, FormSchema } from "../../CurdForm"
4
+ import type { StepItem } from "./hooks/useStepList"
3
5
 
4
6
  export interface FormDialogOptions extends Partial<DialogProps> {
5
7
  title?: string
6
8
  width?: string | number
7
9
  fields?: Fields
8
- stepSchema?: { name: string; description?: string; formSchema: FormSchema }[]
9
10
  formSchema?: FormSchema
11
+ groupSchema?: CurdGroupFormSchema
10
12
  handleOk?: (modelRef: Fields) => Promise<void>
11
13
  handleClose?: (e: "close" | "cancel") => void
12
14
  setForm?: (form: Fields) => void
@@ -14,4 +16,30 @@ export interface FormDialogOptions extends Partial<DialogProps> {
14
16
  extendContext?: Partial<FormContext>
15
17
  confirmBtnText?: string
16
18
  cancelBtnText?: string
19
+ stepComponent?: object
20
+ footerComponent?: object
21
+ }
22
+
23
+ export interface FormDialogContext {
24
+ form: Fields
25
+ state: {
26
+ visible: boolean
27
+ confirmLoading: boolean
28
+ }
29
+ stepList: StepItem[]
30
+ activeStep: { value: number }
31
+ loadOptions: (prop: string, config?: unknown) => void
32
+ prev: () => void
33
+ next: () => void
34
+ goTo: (step: number) => void
35
+ close: () => void
36
+ handleOk: () => void
37
+ validateCurrentStep: (callback: (valid: boolean) => void) => void
38
+ canPrev: { value: boolean }
39
+ canNext: { value: boolean }
40
+ isLastStep: { value: boolean }
41
+ isGroupMode: { value: boolean }
42
+ isFormMode: { value: boolean }
43
+ confirmBtnTextLabel: { value: string }
44
+ cancelBtnTextLabel: { value: string }
17
45
  }
package/index.ts CHANGED
@@ -2,21 +2,24 @@ import type { Plugin } from "vue"
2
2
  import ConstantStatus from "./components/ConstantStatus"
3
3
  import CurdForm from "./components/CurdForm"
4
4
  import CurdFormItem from "./components/CurdForm/src/CurdFormItem.vue"
5
+ import { CurdGroupForm } from "./components/CurdGroupForm"
5
6
  import CurdTable from "./components/CurdTable"
6
7
  import DetailInfo from "./components/DetailInfo"
7
8
  import FormDialog from "./components/FormDialog"
8
9
  import TableFilter from "./components/TableFilter"
9
10
  import { makeInstaller } from "./utils/vue/make-installer"
10
11
 
11
- const Components = [ConstantStatus, CurdForm, TableFilter, DetailInfo, CurdFormItem, CurdTable, FormDialog] as Plugin[]
12
+ const Components = [ConstantStatus, CurdForm, TableFilter, DetailInfo, CurdFormItem, CurdTable, FormDialog, CurdGroupForm] as Plugin[]
12
13
  export * from "./components/ConstantStatus/src/types"
13
14
  export * from "./components/CurdForm"
15
+ export * from "./components/CurdGroupForm/types"
14
16
  export * from "./components/CurdTable/src/types"
15
17
  export * from "./components/DetailInfo/src/types"
16
18
  export * from "./components/FormDialog/src/types"
17
19
  export * from "./components/TableFilter/types"
18
20
  export * from "./utils/hooks/useGlobalConfig"
19
21
  export * from "./utils/hooks/useLocal"
20
- export { ConstantStatus, CurdForm, CurdFormItem, DetailInfo, TableFilter, CurdTable, FormDialog}
22
+
23
+ export { ConstantStatus, CurdForm, CurdFormItem, CurdGroupForm, CurdTable, DetailInfo, FormDialog, TableFilter }
21
24
 
22
25
  export default makeInstaller([...Components])
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "easybill-ui",
3
- "version": "1.2.26",
3
+ "version": "1.3.1",
4
4
  "description": "A component library for easybill",
5
5
  "author": "tuchongyang <779311998@qq.com>",
6
6
  "private": false,