@vue-ui-kit/ant 1.8.0 → 1.8.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.
package/dist/index.d.ts CHANGED
@@ -1,12 +1,16 @@
1
1
  import { App } from 'vue';
2
+ import { setUIKitConfig, getUIKitConfig, resetUIKitConfig, UIKitConfig } from './packages/utils/config';
3
+ declare function setup(config?: Partial<UIKitConfig>): void;
2
4
  declare const _default: {
3
5
  install(app: App): void;
4
- addFormatter: (formatter: Record<string, (a: import('./declarations/antProxy').CellFuncArg, ...args: any[]) => any>) => void;
6
+ addFormatter: (formatter: Record<string, (a: import('./Declarations/antProxy').CellFuncArg, ...args: any[]) => any>) => void;
5
7
  addRender: (name: string, { renderItemContent, renderDefault, }: {
6
8
  renderItemContent?: (options: import('./declarations/antProxy').RenderOptions, params: import('./declarations/antProxy').RenderFormParams, defaultHandler: Recordable) => any;
7
9
  renderDefault?: (options: import('./declarations/antProxy').RenderOptions, params: import('./declarations/antProxy').RenderTableParams, defaultHandler: Recordable) => any;
8
10
  }) => void;
11
+ setup: typeof setup;
9
12
  };
10
13
  export default _default;
11
14
  export * from './declarations/antProxy';
12
15
  export * from './packages/utils/core';
16
+ export { setup, setUIKitConfig, getUIKitConfig, resetUIKitConfig, type UIKitConfig };
@@ -3,12 +3,10 @@ declare const _default: <T extends Recordable = Recordable<any>>(__VLS_props: No
3
3
  props: __VLS_Prettify<Pick<Partial<{}> & Omit<{
4
4
  readonly onTrigger?: ((cusFields?: string | string[] | undefined) => any) | undefined;
5
5
  readonly onReset?: (() => any) | undefined;
6
- readonly onDelayTrigger?: ((cusFields?: string | string[] | undefined, time?: number | undefined) => any) | undefined;
7
6
  } & import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps & Readonly<{}> & Readonly<{
8
7
  onTrigger?: ((cusFields?: string | string[] | undefined) => any) | undefined;
9
8
  onReset?: (() => any) | undefined;
10
- onDelayTrigger?: ((cusFields?: string | string[] | undefined, time?: number | undefined) => any) | undefined;
11
- }>, never>, "onReset" | "onTrigger" | "onDelayTrigger"> & {
9
+ }>, never>, "onReset" | "onTrigger"> & {
12
10
  item: PFormItemProps<T>;
13
11
  formData: T;
14
12
  }> & import('vue').PublicProps;
@@ -16,7 +14,6 @@ declare const _default: <T extends Recordable = Recordable<any>>(__VLS_props: No
16
14
  attrs: any;
17
15
  slots: ReturnType<() => {}>;
18
16
  emit: {
19
- (e: "delayTrigger", cusFields?: string | string[], time?: number): void;
20
17
  (e: "trigger", cusFields?: string | string[]): void;
21
18
  (e: "reset"): void;
22
19
  } & {};
@@ -3,12 +3,12 @@ import { TableProps } from 'ant-design-vue';
3
3
  import { ColumnProps } from '../../declarations/antProxy';
4
4
  declare const _default: <D = Recordable<any>>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_Prettify<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
5
5
  props: __VLS_Prettify<Pick<Partial<{
6
- modelValue: D[];
7
6
  tableConfig: TableProps<any>;
7
+ modelValue: D[];
8
8
  editColumns: ColumnProps<Recordable<any>>[];
9
9
  }> & Omit<{
10
- readonly modelValue: D[];
11
10
  readonly tableConfig: TableProps<any>;
11
+ readonly modelValue: D[];
12
12
  readonly editColumns: ColumnProps<Recordable<any>>[];
13
13
  readonly onTrigger?: ((...args: any[]) => any) | undefined;
14
14
  readonly "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
@@ -28,7 +28,7 @@ declare const _default: <D = Recordable<any>>(__VLS_props: NonNullable<Awaited<t
28
28
  }>> & Readonly<{
29
29
  onTrigger?: ((...args: any[]) => any) | undefined;
30
30
  "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
31
- }>, "modelValue" | "tableConfig" | "editColumns">, "onTrigger" | "onUpdate:modelValue" | ("modelValue" | "tableConfig" | "editColumns")> & {}> & import('vue').PublicProps;
31
+ }>, "tableConfig" | "modelValue" | "editColumns">, "onTrigger" | "onUpdate:modelValue" | ("tableConfig" | "modelValue" | "editColumns")> & {}> & import('vue').PublicProps;
32
32
  expose(exposed: import('vue').ShallowUnwrapRef<{}>): void;
33
33
  attrs: any;
34
34
  slots: ReturnType<() => {}>;
@@ -0,0 +1,17 @@
1
+ import { PFormProps, PGridProps } from '../../declarations/antProxy';
2
+ export interface UIKitConfig {
3
+ form?: {
4
+ labelCol?: any;
5
+ wrapperCol?: any;
6
+ };
7
+ grid?: {
8
+ align?: 'left' | 'right' | 'center';
9
+ lazyReset?: boolean;
10
+ fitHeight?: number;
11
+ };
12
+ }
13
+ export declare function setUIKitConfig(config: Partial<UIKitConfig>): void;
14
+ export declare function getUIKitConfig(): UIKitConfig;
15
+ export declare function getFormDefaults(): Partial<PFormProps>;
16
+ export declare function getGridDefaults(): Partial<PGridProps>;
17
+ export declare function resetUIKitConfig(): void;
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- @charset "UTF-8";:root{--p-theme-bg: #fff}.p-pane{background-color:var(--p-theme-bg);padding:16px;border-radius:4px}.w-full{width:100%}.cursor-pointer{cursor:pointer}.py-4x{padding-top:4px;padding-bottom:4px}.px-2x{padding-left:2px;padding-right:2px}.pl-4x{padding-left:1em}.pl-8{padding-left:2em}.h-0{height:0}.h-full{height:100%}.flex{display:flex}.flex-col{flex-direction:column}.flex-1{flex:1}.items-center{align-items:center}.justify-between{justify-content:space-between}.gap-4px{gap:4px}.gap-8px{gap:8px}.pt-8px{padding-top:8px}.px-16px{padding-left:16px;padding-right:16px}.mt-4px{margin-top:4px}.text-right{text-align:right}.overflow-y-auto{overflow-y:auto}.p-theme-bg{background-color:var(--p-theme-bg)}.p-wrapper .p-form-wrapper{z-index:4}.p-wrapper .p-toolbar-wrapper{box-shadow:0 8px #fff;border-radius:.5em .5em 0 0;margin-bottom:-.5em}.p-wrapper .ant-form .ant-form-item{margin-bottom:0}.p-wrapper .ant-form .ant-form-item.p-required .ant-form-item-label>label:before{display:inline-block;margin-inline-end:4px;color:#ff4d4f;font-size:14px;font-family:SimSun,sans-serif;line-height:1;content:"*"}.p-wrapper .ant-form .ant-form-item .ant-form-item-label{display:flex;align-items:start;justify-content:flex-end}.p-wrapper .ant-form .ant-form-item .ant-form-item-label>label{white-space:break-spaces;align-items:flex-start;height:fit-content;padding-top:.36em}.p-wrapper .ant-form .ant-form-item .ant-form-item-label>label:after{padding-left:4px;margin-inline-start:unset}.p-wrapper .ant-form.ant-form-vertical .ant-form-item .ant-form-item-label{justify-content:flex-start;font-weight:600}.p-wrapper .ant-table-sticky-scroll{visibility:hidden}.p-wrapper .ant-table-header.ant-table-sticky-holder:before{content:"";width:100%;position:absolute;height:22px;display:block;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);top:-16px}.p-wrapper .ant-table-wrapper .ant-table-pagination.ant-pagination{margin:unset;padding:16px 0}.p-wrapper .p-inner-scroll>.ant-table-wrapper{height:100%}.p-wrapper .p-inner-scroll>.ant-table-wrapper>.ant-spin-nested-loading{height:100%}.p-wrapper .p-inner-scroll>.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container{height:100%;display:flex;flex-direction:column}.p-wrapper .p-inner-scroll>.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container>.ant-table{border-radius:unset}.p-wrapper .ant-pagination-options .ant-select{width:100px}.p-error-group-tab{position:relative;overflow:visible;color:#f5222d!important}.p-error-group-tab:after{content:"🏷️";position:absolute;top:-1em;right:0;width:1em;height:1em;font-size:.8em;animation:heartbeat 2s infinite}.p-content-align-right.ant-form-item .ant-form-item-control-input-content{display:flex;justify-content:flex-end;align-items:center;text-align:right}.p-content-align-center.ant-form-item .ant-form-item-control-input-content{display:flex;justify-content:center;align-items:center;text-align:center}@keyframes heartbeat{0%{transform:scale(1)}6%{transform:scale(1.22)}12%{transform:scale(1)}18%{transform:scale(1.18)}24%{transform:scale(1)}48%{transform:scale(1)}54%{transform:scale(1.22)}60%{transform:scale(1)}66%{transform:scale(1.18)}72%{transform:scale(1)}to{transform:scale(1)}}
1
+ @charset "UTF-8";:root{--p-theme-bg: #fff}.p-pane{background-color:var(--p-theme-bg);padding:16px;border-radius:4px}.w-full{width:100%}.cursor-pointer{cursor:pointer}.py-4x{padding-top:4px;padding-bottom:4px}.px-2x{padding-left:2px;padding-right:2px}.pl-4x{padding-left:1em}.pl-8{padding-left:2em}.h-0{height:0}.h-full{height:100%}.flex{display:flex}.flex-col{flex-direction:column}.flex-1{flex:1}.items-center{align-items:center}.justify-between{justify-content:space-between}.gap-4px{gap:4px}.gap-8px{gap:8px}.pt-8px{padding-top:8px}.px-16px{padding-left:16px;padding-right:16px}.mt-4px{margin-top:4px}.text-right{text-align:right}.overflow-y-auto{overflow-y:auto}.p-theme-bg{background-color:var(--p-theme-bg)}.p-wrapper .p-form-wrapper{z-index:4}.p-wrapper .p-error-hang-out .ant-input-affix-wrapper-status-error:not(.ant-input-affix-wrapper-disabled):not(.ant-input-affix-wrapper-borderless).ant-input-affix-wrapper{border-color:#d9d9d9!important}.p-wrapper .p-error-hang-out .ant-input-affix-wrapper-status-error:not(.ant-input-affix-wrapper-disabled):not(.ant-input-affix-wrapper-borderless).ant-input-affix-wrapper:focus{border-color:#4096ff!important}.p-wrapper .p-error-hang-out .ant-form-item-explain-error{opacity:0!important;transform:translateY(-10px)!important;max-height:0!important;overflow:hidden!important;transition:none!important}.p-wrapper .ant-form-item-explain-error{opacity:0;transform:translateY(-10px);max-height:0;overflow:hidden;transition:opacity .3s ease-out .3s,transform .3s ease-out .3s,max-height .3s ease-out .3s}.p-wrapper .ant-form-item-has-error .ant-form-item-explain-error{opacity:1;transform:translateY(0);max-height:100px}.p-wrapper .p-toolbar-wrapper{box-shadow:0 8px #fff;border-radius:.5em .5em 0 0;margin-bottom:-.5em}.p-wrapper .ant-form .ant-form-item{margin-bottom:0}.p-wrapper .ant-form .ant-form-item.p-required .ant-form-item-label>label:before{display:inline-block;margin-inline-end:4px;color:#ff4d4f;font-size:14px;font-family:SimSun,sans-serif;line-height:1;content:"*"}.p-wrapper .ant-form .ant-form-item .ant-form-item-label{display:flex;align-items:start;justify-content:flex-end}.p-wrapper .ant-form .ant-form-item .ant-form-item-label>label{white-space:break-spaces;align-items:flex-start;height:fit-content;padding-top:.36em}.p-wrapper .ant-form .ant-form-item .ant-form-item-label>label:after{padding-left:4px;margin-inline-start:unset}.p-wrapper .ant-form.ant-form-vertical .ant-form-item .ant-form-item-label{justify-content:flex-start;font-weight:600}.p-wrapper .ant-table-sticky-scroll{visibility:hidden}.p-wrapper .ant-table-header.ant-table-sticky-holder:before{content:"";width:100%;position:absolute;height:22px;display:block;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);top:-16px}.p-wrapper .ant-table-wrapper .ant-table-pagination.ant-pagination{margin:unset;padding:16px 0}.p-wrapper .p-inner-scroll>.ant-table-wrapper{height:100%}.p-wrapper .p-inner-scroll>.ant-table-wrapper>.ant-spin-nested-loading{height:100%}.p-wrapper .p-inner-scroll>.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container{height:100%;display:flex;flex-direction:column}.p-wrapper .p-inner-scroll>.ant-table-wrapper>.ant-spin-nested-loading>.ant-spin-container>.ant-table{border-radius:unset}.p-wrapper .ant-pagination-options .ant-select{width:100px}.p-error-group-tab{position:relative;overflow:visible;color:#f5222d!important}.p-error-group-tab:after{content:"🏷️";position:absolute;top:-1em;right:0;width:1em;height:1em;font-size:.8em;animation:heartbeat 2s infinite}.p-error-hang-out .ant-input-affix-wrapper-status-error:not(.ant-input-affix-wrapper-disabled):not(.ant-input-affix-wrapper-borderless).ant-input-affix-wrapper{border-color:#d9d9d9!important}.p-error-hang-out .ant-input-affix-wrapper-status-error:not(.ant-input-affix-wrapper-disabled):not(.ant-input-affix-wrapper-borderless).ant-input-affix-wrapper:focus{border-color:#4096ff!important}.p-error-hang-out .ant-form-item-explain-error{display:none}.no-error-border{border-color:#d9d9d9!important}.no-error-border:focus{border-color:#4096ff!important}.p-content-align-right.ant-form-item .ant-form-item-control-input-content{display:flex;justify-content:flex-end;align-items:center;text-align:right}.p-content-align-center.ant-form-item .ant-form-item-control-input-content{display:flex;justify-content:center;align-items:center;text-align:center}@keyframes heartbeat{0%{transform:scale(1)}6%{transform:scale(1.22)}12%{transform:scale(1)}18%{transform:scale(1.18)}24%{transform:scale(1)}48%{transform:scale(1)}54%{transform:scale(1.22)}60%{transform:scale(1)}66%{transform:scale(1.18)}72%{transform:scale(1)}to{transform:scale(1)}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue-ui-kit/ant",
3
- "version": "1.8.0",
3
+ "version": "1.8.2",
4
4
  "description": "Vue3 UI Kit based on Ant Design",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
@@ -203,6 +203,8 @@ export type PGridProps<D = Recordable, F = Recordable> = {
203
203
  proxyConfig?: ProxyConfig<D, F>;
204
204
  tableConfig?: TableProps<D>;
205
205
  scrollMode?: 'outer' | 'inner';
206
+ // 重置后不自动提交
207
+ lazyReset?: boolean;
206
208
  /**
207
209
  * 适应展示区到页面顶部的高度,通常和容器最上的y值有关(正比)
208
210
  */
package/src/index.ts CHANGED
@@ -6,8 +6,16 @@ import PGroupBlock from '@/components/PGroupBlock.vue';
6
6
  import PromisePicker from '@/components/PromisePicker.vue';
7
7
  import { addFormatter } from '@/utils/AFormatters';
8
8
  import { addRender } from '@/store/renderStore';
9
+ import { setUIKitConfig, getUIKitConfig, resetUIKitConfig, UIKitConfig } from '@/utils/config';
9
10
  import * as utils from '@/utils/core';
10
11
 
12
+ // 创建setup方法
13
+ function setup(config?: Partial<UIKitConfig>) {
14
+ if (config) {
15
+ setUIKitConfig(config);
16
+ }
17
+ }
18
+
11
19
  export default {
12
20
  install(app: App) {
13
21
  app.component('PForm', PForm);
@@ -19,7 +27,15 @@ export default {
19
27
  },
20
28
  addFormatter,
21
29
  addRender,
30
+ setup,
22
31
  };
23
32
 
24
33
  export * from '#/antProxy';
25
34
  export * from '@/utils/core';
35
+ export {
36
+ setup,
37
+ setUIKitConfig,
38
+ getUIKitConfig,
39
+ resetUIKitConfig,
40
+ type UIKitConfig
41
+ };
@@ -5,6 +5,7 @@
5
5
  import { v4 as uuid_v4 } from 'uuid';
6
6
  import { isGoodValue } from '@/utils/is';
7
7
  import { eachTree } from '@/utils/treeHelper';
8
+ import { getFormDefaults } from '@/utils/config';
8
9
  import PFormCol from '@/components/PFormCol.vue';
9
10
  import {
10
11
  Form as AForm,
@@ -13,6 +14,15 @@
13
14
 
14
15
  const props = defineProps<PFormProps<F> & { data: F }>();
15
16
  const emit = defineEmits(['apply', 'reset']);
17
+
18
+ // 应用默认值
19
+ const formDefaults = getFormDefaults();
20
+ const propsWithDefaults = computed(() => ({
21
+ ...props,
22
+ labelCol: props.labelCol ?? formDefaults.labelCol ?? { span: 6 },
23
+ wrapperCol: props.wrapperCol ?? formDefaults.wrapperCol ?? { span: 16 },
24
+ }));
25
+
16
26
  const { items, data: formData } = toRefs(props);
17
27
 
18
28
  function handleSubmit() {
@@ -52,9 +62,9 @@
52
62
  };
53
63
  // omit({labelCol:defaultLabelCol,...props},['items','data','model'])
54
64
  const fc = computed(() => ({
55
- ...omit(props, ['items', 'data', 'model', 'labelCol', 'wrapperCol']),
56
- labelCol: props.labelCol ?? { span: 6 },
57
- wrapperCol: props.wrapperCol ?? { span: 16 },
65
+ ...omit(propsWithDefaults.value, ['items', 'data', 'model', 'labelCol', 'wrapperCol']),
66
+ labelCol: propsWithDefaults.value.labelCol,
67
+ wrapperCol: propsWithDefaults.value.wrapperCol,
58
68
  }));
59
69
  const validateField = (fields?: string | string[]) => {
60
70
  if (fields) {
@@ -64,12 +74,7 @@
64
74
  const handleTrigger = (cusFields?: string | string[]) => {
65
75
  validateField(cusFields);
66
76
  };
67
- const handleDelayTrigger = (cusFields?: string | string[], time?: number) => {
68
- const delayTime = time ?? 222;
69
- setTimeout(() => {
70
- validateField(cusFields);
71
- }, delayTime);
72
- };
77
+
73
78
  defineExpose({
74
79
  reset: resetForm,
75
80
  $form: computed(() => formEl.value),
@@ -87,7 +92,6 @@
87
92
  :key="`_col_${idx}`"
88
93
  :form-data="formData"
89
94
  :item="item"
90
- @delay-trigger="handleDelayTrigger"
91
95
  @reset="resetFormData"
92
96
  @trigger="handleTrigger"
93
97
  />
@@ -13,13 +13,18 @@ const props = defineProps<{
13
13
  formData: T
14
14
  }>()
15
15
  const emit = defineEmits<{
16
- (e: 'delayTrigger', cusFields?: string | string[], time?: number): void
17
16
  (e: 'trigger', cusFields?: string | string[]): void
18
17
  (e: 'reset'): void
19
18
  }>()
19
+ const hangOut = ref(false)
20
20
  const renderFormKey = ref(uuid_v4())
21
21
  const handleDelayTrigger = (cusFields?: string | string[], time?: number) => {
22
- emit('delayTrigger', cusFields, time)
22
+ const delayTime = time ?? 222
23
+ hangOut.value = true
24
+ setTimeout(() => {
25
+ hangOut.value = false
26
+ emit('trigger', cusFields)
27
+ }, delayTime)
23
28
  }
24
29
  const handleTrigger = (cusFields?: string | string[]) => {
25
30
  emit('trigger', cusFields)
@@ -45,7 +50,10 @@ watch(() => props.item, (cur, old) => {
45
50
  >
46
51
  <a-form-item
47
52
  :key="`_item_${renderFormKey}`"
48
- :class="`p-content-align-${item.align ?? 'left'} ${item.forceRequired ? 'p-required' : ''}`"
53
+ :class="[
54
+ `p-content-align-${item.align ?? 'left'} ${item.forceRequired ? 'p-required' : ''}`,
55
+ { 'p-error-hang-out': hangOut },
56
+ ]"
49
57
  colon
50
58
  :label="item.title"
51
59
  :name="item.field"
@@ -14,29 +14,38 @@
14
14
  import { debounce, get, isArray, isBoolean, isFunction, isObject, isString, merge, omit, toNumber } from 'xe-utils';
15
15
  import { eachTree } from '@/utils/treeHelper';
16
16
  import { message as $message } from 'ant-design-vue';
17
- import RenderAntItem from '@/components/RenderAntItem';
18
17
  import RenderTitleSlots from '@/components/RenderTitleSlots';
19
18
  import RenderDefaultSlots from '@/components/RenderDefaultSlots';
20
19
  import { v4 as uuid_v4 } from 'uuid';
21
- import { isGoodValue, valued } from '@/utils/is';
22
- import RenderItemSlots from '@/components/RenderItemSlots';
23
- import { cleanCol, defaultItemResponsive, defaultLabelCol } from '@/utils/core';
20
+ import { isGoodValue } from '@/utils/is';
21
+ import PFormCol from '@/components/PFormCol.vue';
22
+ import { cleanCol, defaultLabelCol } from '@/utils/core';
23
+ import { getGridDefaults } from '@/utils/config';
24
24
  import Icon from '@/renders/Icon';
25
25
  import { $confirm } from '@/hooks/useMessage';
26
26
  import {
27
27
  Table as ATable,
28
28
  Button as AButton,
29
29
  Form as AForm,
30
- FormItem as AFormItem,
31
30
  Row as ARow,
32
- Col as ACol,
33
31
  Spin as ASpin,
34
- Tooltip as ATooltip,
35
32
  } from 'ant-design-vue';
36
33
  import { TablePaginationConfig } from 'ant-design-vue/es/table/interface';
37
- import { InfoCircleOutlined, DownOutlined } from '@ant-design/icons-vue';
34
+ import { DownOutlined } from '@ant-design/icons-vue';
38
35
 
39
36
  const props = defineProps<PGridProps<D, F>>();
37
+
38
+ // 应用默认值
39
+ const gridDefaults = getGridDefaults();
40
+ const propsWithDefaults = computed(() => ({
41
+ ...props,
42
+ rowKey: props.rowKey ?? 'id',
43
+ scrollMode: props.scrollMode ?? 'inner',
44
+ align: props.align ?? gridDefaults.align ?? 'left',
45
+ lazyReset: props.lazyReset ?? gridDefaults.lazyReset ?? false,
46
+ fitHeight: props.fitHeight ?? gridDefaults.fitHeight ?? 170,
47
+ }));
48
+
40
49
  const {
41
50
  formConfig,
42
51
  pageConfig,
@@ -63,7 +72,6 @@
63
72
  loading.toolbar = value;
64
73
  }
65
74
  };
66
- const submitOnReset = true;
67
75
  const boxEl = ref<HTMLDivElement>();
68
76
  const pFormWrapper = ref<HTMLDivElement>();
69
77
  const renderHeight = ref(500);
@@ -118,9 +126,7 @@
118
126
  const tableEl = ref();
119
127
  const renderFormKey = ref(uuid_v4());
120
128
  const renderTableKey = ref(uuid_v4());
121
- const refreshForm = () => {
122
- renderFormKey.value = uuid_v4();
123
- };
129
+
124
130
  const codeLoadings = reactive<Record<string, boolean>>(
125
131
  [
126
132
  ...(props.toolbarConfig?.buttons?.map((m) => m.code) ?? []).filter((f) => f),
@@ -139,7 +145,6 @@
139
145
  const refreshTable = () => {
140
146
  renderTableKey.value = uuid_v4();
141
147
  };
142
- const debounceRefreshForm = debounce(refreshForm, 100);
143
148
  const debounceRefreshTable = debounce(refreshTable, 100);
144
149
  const slotDefaultColumns = computed(() => {
145
150
  const cols: ColumnProps<D>[] = [];
@@ -237,7 +242,6 @@
237
242
  queryFormData.value = obj;
238
243
  }
239
244
  emit('resetQuery');
240
- refreshForm();
241
245
  }
242
246
 
243
247
  pagination.page = 1;
@@ -397,13 +401,6 @@
397
401
  resetPage();
398
402
  };
399
403
 
400
- watch(
401
- () => formConfig.value,
402
- () => {
403
- debounceRefreshForm();
404
- },
405
- { deep: true },
406
- );
407
404
  watch(
408
405
  () => [columns.value, proxyConfig.value, toolbarConfig.value],
409
406
  () => {
@@ -423,7 +420,7 @@
423
420
  const showCountHeight = selectConfig.value?.showCount ? 22 : 0
424
421
  renderHeight.value =
425
422
  props.renderY ??
426
- toNumber(ph.replace('px', '')) -(props.fitHeight ?? 170) -(!!props.toolbarConfig ? 30 : 0) -formHeight- showCountHeight;
423
+ toNumber(ph.replace('px', '')) -propsWithDefaults.value.fitHeight -(props.toolbarConfig ? 30 : 0) -formHeight- showCountHeight;
427
424
  enoughSpacing.value = toNumber(ph.replace('px', '')) > 600;
428
425
  };
429
426
  defineExpose({
@@ -468,7 +465,7 @@
468
465
  const passFields = ['align']
469
466
  const passDefaultColumnProps = (columns: ColumnProps<D>[]) => columns.map(c => ({
470
467
  ...passFields.reduce((prev, cur) => ({
471
- [cur]: props[cur],
468
+ [cur]: propsWithDefaults.value[cur],
472
469
  }), {} as ColumnProps<D>),
473
470
  ...c,
474
471
  }))
@@ -495,64 +492,13 @@
495
492
  @submit="handleFormSubmit"
496
493
  >
497
494
  <a-row :gutter="[6, 12]">
498
- <a-col
495
+ <p-form-col
499
496
  v-for="(item, idx) in formConfig!.items"
500
- :key="'_col_' + idx"
501
- v-bind="item.col ?? (item.span ? { span: item.span } : defaultItemResponsive)"
502
- >
503
- <a-form-item
504
- :key="'_item_' + idx"
505
- :class="`p-content-align-${item.align ?? 'left'} ${item.forceRequired ? 'p-required' : ''}`"
506
- :label="item.title"
507
- :name="item.field"
508
- v-bind="
509
- omit(item, [
510
- 'field',
511
- 'title',
512
- 'span',
513
- 'col',
514
- 'itemRender',
515
- 'forceRequired',
516
- 'tooltip',
517
- ])
518
- "
519
- >
520
- <render-item-slots
521
- v-if="item.slots?.default"
522
- :key="'_sl_' + (item.field ?? '_') + '_' + idx"
523
- :form-data="queryFormData"
524
- :item="item"
525
- :pass-trigger="() => {}"
526
- :pass-delay-trigger="() => {}"
527
- />
528
- <render-ant-item
529
- v-else-if="item.itemRender?.name"
530
- :key="'_re_' + (item.field ?? '_') + '_' + idx"
531
- :default-handler="{
532
- reset: () => {
533
- resetQueryFormData(!submitOnReset);
534
- },
535
- }"
536
- :item-render="item.itemRender"
537
- :render-form-params="{ data: queryFormData, field: item.field }"
538
- />
539
- <span v-else></span>
540
- <template #tooltip v-if="item.tooltipConfig">
541
- <a-tooltip
542
- v-if="isFunction(item.tooltipConfig.title)"
543
- v-bind="omit(item.tooltipConfig, ['title'])"
544
- >
545
- <InfoCircleOutlined class="cursor-pointer py-4x px-2x" />
546
- <template #title>
547
- <div v-html="item.tooltipConfig.title()"></div>
548
- </template>
549
- </a-tooltip>
550
- <a-tooltip v-else v-bind="item.tooltipConfig">
551
- <InfoCircleOutlined class="cursor-pointer py-4x px-2x" />
552
- </a-tooltip>
553
- </template>
554
- </a-form-item>
555
- </a-col>
497
+ :key="`_col_${idx}`"
498
+ :form-data="queryFormData"
499
+ :item="item as PFormItemProps<Partial<F>>"
500
+ @reset="resetQueryFormData(propsWithDefaults.lazyReset)"
501
+ />
556
502
  </a-row>
557
503
  </a-form>
558
504
  </a-spin>
@@ -99,7 +99,37 @@
99
99
  .p-form-wrapper {
100
100
  z-index: 4;
101
101
  }
102
-
102
+ .p-error-hang-out {
103
+ .ant-input-affix-wrapper-status-error:not(
104
+ .ant-input-affix-wrapper-disabled
105
+ ):not(.ant-input-affix-wrapper-borderless).ant-input-affix-wrapper {
106
+ border-color: #d9d9d9 !important;
107
+
108
+ &:focus {
109
+ border-color: #4096ff !important;
110
+ }
111
+ }
112
+ .ant-form-item-explain-error {
113
+ opacity: 0 !important;
114
+ transform: translateY(-10px) !important;
115
+ max-height: 0 !important;
116
+ overflow: hidden !important;
117
+ transition: none !important;
118
+ }
119
+ }
120
+ .ant-form-item-explain-error {
121
+ opacity: 0;
122
+ transform: translateY(-10px);
123
+ max-height: 0;
124
+ overflow: hidden;
125
+ transition: opacity 0.3s ease-out 0.3s, transform 0.3s ease-out 0.3s,
126
+ max-height 0.3s ease-out 0.3s;
127
+ }
128
+ .ant-form-item-has-error .ant-form-item-explain-error {
129
+ opacity: 1;
130
+ transform: translateY(0);
131
+ max-height: 100px;
132
+ }
103
133
  .p-toolbar-wrapper {
104
134
  box-shadow: 0 8px #fff;
105
135
  border-radius: 0.5em 0.5em 0 0;
@@ -219,6 +249,27 @@
219
249
  animation: heartbeat 2s infinite;
220
250
  }
221
251
  }
252
+ .p-error-hang-out {
253
+ .ant-input-affix-wrapper-status-error:not(
254
+ .ant-input-affix-wrapper-disabled
255
+ ):not(.ant-input-affix-wrapper-borderless).ant-input-affix-wrapper {
256
+ border-color: #d9d9d9 !important;
257
+
258
+ &:focus {
259
+ border-color: #4096ff !important;
260
+ }
261
+ }
262
+ .ant-form-item-explain-error {
263
+ display: none;
264
+ }
265
+ }
266
+ .no-error-border {
267
+ border-color: #d9d9d9 !important;
268
+
269
+ &:focus {
270
+ border-color: #4096ff !important;
271
+ }
272
+ }
222
273
  //endregion
223
274
 
224
275
  @each $align in right center {
@@ -0,0 +1,72 @@
1
+ import { PFormProps, PGridProps } from '#/antProxy';
2
+ import { clone } from 'xe-utils';
3
+
4
+ // 全局配置接口
5
+ export interface UIKitConfig {
6
+ form?: {
7
+ labelCol?: any;
8
+ wrapperCol?: any;
9
+ };
10
+ grid?: {
11
+ align?: 'left' | 'right' | 'center';
12
+ lazyReset?: boolean;
13
+ fitHeight?: number;
14
+ };
15
+ }
16
+
17
+ // 默认配置
18
+ const defaultConfig: UIKitConfig = {
19
+ form: {
20
+ labelCol: { span: 6 },
21
+ wrapperCol: { span: 16 },
22
+ },
23
+ grid: {
24
+ align: 'left',
25
+ lazyReset: false,
26
+ fitHeight: 170,
27
+ },
28
+ };
29
+
30
+ // 当前配置(可被修改)
31
+ let currentConfig: UIKitConfig = clone(defaultConfig);
32
+
33
+ // 设置配置
34
+ export function setUIKitConfig(config: Partial<UIKitConfig>): void {
35
+ currentConfig = {
36
+ form: {
37
+ ...currentConfig.form,
38
+ ...config.form,
39
+ },
40
+ grid: {
41
+ ...currentConfig.grid,
42
+ ...config.grid,
43
+ },
44
+ };
45
+ }
46
+
47
+ // 获取配置
48
+ export function getUIKitConfig(): UIKitConfig {
49
+ return currentConfig;
50
+ }
51
+
52
+ // 获取表单默认配置
53
+ export function getFormDefaults(): Partial<PFormProps> {
54
+ return {
55
+ labelCol: currentConfig.form?.labelCol,
56
+ wrapperCol: currentConfig.form?.wrapperCol,
57
+ };
58
+ }
59
+
60
+ // 获取Grid默认配置
61
+ export function getGridDefaults(): Partial<PGridProps> {
62
+ return {
63
+ align: currentConfig.grid?.align,
64
+ lazyReset: currentConfig.grid?.lazyReset,
65
+ fitHeight: currentConfig.grid?.fitHeight,
66
+ };
67
+ }
68
+
69
+ // 重置为默认配置
70
+ export function resetUIKitConfig(): void {
71
+ currentConfig = JSON.parse(JSON.stringify(defaultConfig));
72
+ }