free-fe-core-modules 0.0.4 → 0.0.6

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 (35) hide show
  1. package/components/Basic/BreadCrumbs.vue +18 -9
  2. package/components/Basic/LeveledMenus.vue +13 -5
  3. package/components/Basic/SummaryHead.vue +5 -2
  4. package/components/Dialog/BasicDialog.vue +14 -3
  5. package/components/FloatingWindow/index.vue +9 -1
  6. package/components/SlidingCarousel/index.vue +5 -2
  7. package/components/SlidingNews/index.vue +33 -24
  8. package/composible/useFormValidator.js +56 -0
  9. package/free-field/Fields/AgreementCheck.js +6 -2
  10. package/free-field/Fields/Category.js +2 -1
  11. package/free-field/Fields/Check.js +1 -0
  12. package/free-field/Fields/Date.js +13 -5
  13. package/free-field/Fields/DateRange.js +14 -8
  14. package/free-field/Fields/DynamicList.js +36 -33
  15. package/free-field/Fields/FixedList.vue +9 -5
  16. package/free-field/Fields/Labels.vue +7 -1
  17. package/free-field/Fields/MixedTable.vue +9 -3
  18. package/free-field/Fields/Number.js +12 -6
  19. package/free-field/Fields/Password.js +12 -6
  20. package/free-field/Fields/Search.vue +8 -2
  21. package/free-field/Fields/Select.vue +4 -1
  22. package/free-field/Fields/SelectionChain.vue +8 -2
  23. package/free-field/Fields/String.js +11 -5
  24. package/free-field/Fields/Text.js +12 -6
  25. package/free-field/Fields/Time.vue +8 -2
  26. package/free-field/Fields/TimeRange.vue +13 -5
  27. package/free-field/Fields/Year.js +12 -6
  28. package/free-field/Fields/YearRange.vue +9 -6
  29. package/free-field/composible/fieldWrapper.js +59 -51
  30. package/free-field/composible/freeFieldLabel.js +10 -3
  31. package/index.js +123 -78
  32. package/package.json +1 -1
  33. package/view/dict/index.vue +85 -1
  34. package/view/menu/index.vue +15 -11
  35. package/view/mourning/mourning.vue +17 -12
@@ -9,12 +9,13 @@
9
9
  />
10
10
  <q-space></q-space>
11
11
  <q-btn v-if="meta.length > 0 && canBack"
12
- flat icon="keyboard_arrow_left" @click="back">{{backText}}</q-btn>
12
+ flat icon="keyboard_arrow_left" @click="back">{{$t(backText)}}</q-btn>
13
13
  </q-breadcrumbs>
14
14
  </template>
15
15
 
16
16
  <script>
17
17
  import { defineComponent } from 'vue';
18
+ import { useRouter, useRoute } from 'vue-router'
18
19
  import { mapWritableState } from 'pinia';
19
20
  import useAppStore from '@/stores/app';
20
21
 
@@ -24,6 +25,14 @@ export default defineComponent({
24
25
  canBack: { type: Boolean, default: true },
25
26
  backText: { type: String, default: '返回' },
26
27
  },
28
+ setup() {
29
+ const router = useRouter();
30
+
31
+ return {
32
+ router,
33
+ route: useRoute(),
34
+ };
35
+ },
27
36
  data() {
28
37
  return {
29
38
  nextFlag: false,
@@ -37,11 +46,11 @@ export default defineComponent({
37
46
  let mt = [];
38
47
  if (this.crumbs && this.crumbs.length) {
39
48
  mt = this.crumbs;
40
- } else if (this.$route.meta && this.$route.meta.length) {
41
- mt = this.$route.meta;
49
+ } else if (this.route.meta && this.route.meta.length) {
50
+ mt = this.route.meta;
42
51
  } else {
43
- for (let i = 0; i < this.$route.matched.length; i += 1) {
44
- const rm = this.$route.matched[i];
52
+ for (let i = 0; i < this.route.matched.length; i += 1) {
53
+ const rm = this.route.matched[i];
45
54
  if (rm.meta && rm.meta.length) mt = rm.meta;
46
55
  }
47
56
  }
@@ -65,14 +74,14 @@ export default defineComponent({
65
74
  return;
66
75
  }
67
76
 
68
- this.$router.push(this.meta[index].route);
77
+ this.router.push(this.meta[index].route);
69
78
  // const backIndex = this.meta.length - 1 - index;
70
79
  // window.history.go(-backIndex);
71
80
  },
72
81
  back() {
73
- const URL = this.$route.fullPath.indexOf('?') === -1
74
- ? this.$route.fullPath
75
- : this.$route.fullPath.split('?')[0];
82
+ const URL = this.route.fullPath.indexOf('?') === -1
83
+ ? this.route.fullPath
84
+ : this.route.fullPath.split('?')[0];
76
85
  if (this.whiteList.indexOf(URL) === -1) {
77
86
  window.history.go(-1);
78
87
  } else {
@@ -6,7 +6,7 @@
6
6
  v-if="!m.Sub || m.Sub.length <= 0"
7
7
  clickable
8
8
  class="simple"
9
- :class="group"
9
+ :class="`${group} level_${level || 0}`"
10
10
  :to="m.Route"
11
11
  expand-icon-class="simple-expand-icon"
12
12
  :ref="`menuItem_${group}_index`"
@@ -17,7 +17,7 @@
17
17
  <q-icon class="leaf-icon" :name="m.Icon"></q-icon>
18
18
  </q-item-section>
19
19
  <q-item-section>
20
- <div class="q-item__label leaf-label">{{$t(m.Label)}}</div>
20
+ <div class="q-item__label leaf-label">{{translate ? $t(m.Label) : m.Label}}</div>
21
21
  </q-item-section>
22
22
  <q-item-section side
23
23
  class="leaf-expand-icon">
@@ -32,10 +32,10 @@
32
32
 
33
33
  <q-expansion-item
34
34
  v-if="m.Sub && m.Sub.length > 0"
35
- :value="m.Sub.filter(s => $route.fullPath.startsWith(s.Route)).length > 0"
35
+ :modelValue="m.Sub.filter(s => $route.fullPath.startsWith(s.Route)).length > 0"
36
36
  exact
37
37
  class="expansion"
38
- :class="group"
38
+ :class="`${group} level_${level || 0}`"
39
39
  :dense-toggle="dense"
40
40
  expand-icon-class="expansion-icon"
41
41
  :expand-icon="expandIcon"
@@ -44,13 +44,14 @@
44
44
  :content-inset-level="inset ? insetLevel || (showIcon ? 0.6 : 0.4) : undefined"
45
45
  expand-separator
46
46
  :icon="(showIcon && m.Icon) ? m.Icon : undefined"
47
- :label="$t(m.Label)"
47
+ :label="translate ? $t(m.Label) : m.Label"
48
48
  :to="m.Route"
49
49
  :ref="`menuItem_${group}_index`"
50
50
  >
51
51
  <leveled-menus
52
52
  :menus="m.Sub"
53
53
  :group="`${group}_${index}`"
54
+ :level="level + 1"
54
55
  :showIcon="showIcon"
55
56
  :insetLevel="insetLevel"
56
57
  :dense="dense"
@@ -71,6 +72,7 @@ import { defineComponent } from 'vue';
71
72
  export default defineComponent({
72
73
  name: 'LeveledMenus',
73
74
  props: {
75
+ level: { type: Number, default: 0 },
74
76
  group: { type: String, default: 'DEFAULT' },
75
77
  menus: { type: Array },
76
78
  showIcon: { type: Boolean, default: true },
@@ -81,7 +83,13 @@ export default defineComponent({
81
83
  leafExpandedIcon: { type: String, default: undefined },
82
84
  expandIcon: { type: String, default: undefined },
83
85
  expandedIcon: { type: String, default: undefined },
86
+ translate: { type: Boolean, default: false },
84
87
  },
85
88
  });
86
89
  </script>
87
90
 
91
+ <style lang="sass">
92
+ .leveled-menu
93
+ .simple-expand-icon
94
+ display: none
95
+ </style>
@@ -76,6 +76,7 @@
76
76
 
77
77
  <script>
78
78
  import { defineComponent } from 'vue';
79
+ import { useRouter } from 'vue-router'
79
80
  import { useObjectData, objectDataProps } from '../../composible/useObjectData';
80
81
 
81
82
  export default defineComponent({
@@ -90,10 +91,12 @@ export default defineComponent({
90
91
  data,
91
92
  refreshData,
92
93
  } = useObjectData(props, ctx);
94
+ const router = useRouter();
93
95
 
94
96
  return {
95
- data,
97
+ data,
96
98
  refreshData,
99
+ router,
97
100
  };
98
101
  },
99
102
  created() {
@@ -150,7 +153,7 @@ export default defineComponent({
150
153
  // if (item.route_query) rParams.query = item.route_query;
151
154
  // if (item.route_params) rParams.params = item.route_params;
152
155
 
153
- this.$router.push(item.route);
156
+ this.router.push(item.route);
154
157
  }
155
158
  });
156
159
  },
@@ -65,7 +65,9 @@
65
65
  :key="index"
66
66
  :Field="field"
67
67
  :values="fieldsData"
68
- :ref="`input_field_validator_${index}`"
68
+ ref="fieldsToValid"
69
+ @cancel="btnCancel"
70
+ @ok="onOKClick"
69
71
  @input="onInputFieldInput(field)"
70
72
  ></free-field>
71
73
  </div>
@@ -75,7 +77,7 @@
75
77
  <q-card-actions
76
78
  align="center"
77
79
  class="action-buttons full-width absolute"
78
- v-if="canOK || canCancel"
80
+ v-if="(canOK || canCancel) && !hideActions"
79
81
  >
80
82
  <q-btn
81
83
  :label="cancelText"
@@ -101,6 +103,7 @@
101
103
 
102
104
  <script>
103
105
  import { defineComponent } from 'vue';
106
+ import { useFormValidator } from '../../composible/useFormValidator';
104
107
  import FreeField from '../../free-field/composible/fieldWrapper';
105
108
  import EIcon from '../Basic/EIcon.vue';
106
109
 
@@ -125,6 +128,7 @@ export default defineComponent({
125
128
  needText: { type: Boolean, default: false },
126
129
  text_label: { type: String, default: '' },
127
130
  max_text_length: { type: Number, default: 100 },
131
+ hideActions: { type: Boolean, default: false },
128
132
  canOK: { type: Boolean, default: true },
129
133
  canCancel: { type: Boolean, default: false },
130
134
  canClose: { type: Boolean, default: false },
@@ -153,6 +157,14 @@ export default defineComponent({
153
157
  FreeField,
154
158
  EIcon,
155
159
  },
160
+ setup(props, { expose }) {
161
+ const { validate } = useFormValidator('fieldsToValid');
162
+ expose({
163
+ validate,
164
+ })
165
+
166
+ return {};
167
+ },
156
168
  data() {
157
169
  return {
158
170
  timeLeft: 0,
@@ -196,7 +208,6 @@ export default defineComponent({
196
208
  // following method is REQUIRED
197
209
  // (don't change its name --> "show")
198
210
  show() {
199
- // debugger
200
211
  this.$refs.dialog.show();
201
212
  this.timeout_counter();
202
213
 
@@ -15,6 +15,7 @@
15
15
 
16
16
  <script>
17
17
  import { defineComponent } from 'vue';
18
+ import { useRouter } from 'vue-router'
18
19
 
19
20
  export default defineComponent({
20
21
  name: 'FloatingWindow',
@@ -24,6 +25,13 @@ export default defineComponent({
24
25
  onlyIn: { type: Array, default: () => [] },
25
26
  top: { type: Number, default: 0 },
26
27
  },
28
+ setup() {
29
+ const router = useRouter();
30
+
31
+ return {
32
+ router,
33
+ };
34
+ },
27
35
  data() {
28
36
  return {
29
37
  x: 150,
@@ -53,7 +61,7 @@ export default defineComponent({
53
61
  if (/^(http|https):\/\/.*/.test(this.url)) {
54
62
  window.open(this.url);
55
63
  } else {
56
- this.$router.push(this.url);
64
+ this.router.push(this.url);
57
65
  }
58
66
  }
59
67
  },
@@ -27,6 +27,7 @@
27
27
 
28
28
  <script>
29
29
  import { defineComponent } from 'vue';
30
+ import { useRouter } from 'vue-router'
30
31
  import { useObjectData, objectDataProps } from '../../composible/useObjectData';
31
32
 
32
33
  export default defineComponent({
@@ -48,9 +49,11 @@ export default defineComponent({
48
49
  refreshData,
49
50
  } = useObjectData(props, ctx);
50
51
 
52
+ const router = useRouter();
51
53
  return {
52
- data,
54
+ data,
53
55
  refreshData,
56
+ router,
54
57
  };
55
58
  },
56
59
  data() {
@@ -77,7 +80,7 @@ export default defineComponent({
77
80
  // window.location.href = l;
78
81
  window.open(carouse.url);
79
82
  } else {
80
- this.$router.push(carouse.url);
83
+ this.router.push(carouse.url);
81
84
  }
82
85
  }
83
86
  },
@@ -2,7 +2,7 @@
2
2
  <div
3
3
  v-if="visible"
4
4
  class="row full-width sliding-news justify-center"
5
- :class="(data && data.length) ? '' : 'empty'"
5
+ :class="(localData.length) ? '' : 'empty'"
6
6
  >
7
7
  <span class="sliding-news-label row items-center">
8
8
  <e-icon
@@ -26,23 +26,19 @@
26
26
  vertical
27
27
  >
28
28
  <q-carousel-slide
29
- v-for="(carouse, index) in data"
29
+ v-for="(carouse, index) in localData"
30
30
  :key="index"
31
31
  :name="index"
32
32
  @click="newsClicked(carouse)"
33
33
  style="cursor: pointer; padding: 0; margin: 0;"
34
34
  >
35
- <div class="row items-center justify-center full-height">
36
- <span class="sliding-news-title">{{carouse.Title}}</span>
35
+ <div class="row no-wrap items-center justify-center full-height">
36
+ <div class="sliding-news-title col ellipsis">{{carouse.title}}</div>
37
37
  <q-space />
38
- <span class="float-right sliding-news-right">
39
- <span
40
- class="sliding-news-date"
41
- :style="`line-height: ${heightString}`"
42
- >
38
+ <div class="sliding-news-right"
39
+ :style="`line-height: ${heightString}`">
43
40
  {{filter('normalDate',(carouse.PublishDate || carouse.LastUpdateDate))}}
44
- </span>
45
- </span>
41
+ </div>
46
42
  </div>
47
43
  </q-carousel-slide>
48
44
  </q-carousel>
@@ -65,6 +61,7 @@
65
61
  </template>
66
62
 
67
63
  <script>
64
+ import { useRouter, useRoute } from 'vue-router'
68
65
  import { defineComponent } from 'vue';
69
66
  import { useObjectData, objectDataProps } from '../../composible/useObjectData';
70
67
 
@@ -72,6 +69,13 @@ export default defineComponent({
72
69
  name: 'SlidingNews',
73
70
  props: {
74
71
  ...objectDataProps,
72
+ fields: {
73
+ type: Object,
74
+ default: () => ({
75
+ title: 'Title',
76
+ date: 'LastUpdateDate'
77
+ }),
78
+ },
75
79
  interval: { type: Number, default: 3000 },
76
80
  height: { type: String, default: '40px' },
77
81
  width: { type: String, default: '100%' },
@@ -88,10 +92,13 @@ export default defineComponent({
88
92
  data,
89
93
  refreshData,
90
94
  } = useObjectData(props, ctx);
95
+ const router = useRouter();
91
96
 
92
97
  return {
93
- data,
98
+ data,
94
99
  refreshData,
100
+ router,
101
+ route: useRoute(),
95
102
  };
96
103
  },
97
104
  data() {
@@ -113,24 +120,26 @@ export default defineComponent({
113
120
  return this.height;
114
121
  },
115
122
  },
116
- // watch: {
117
- // visible() {
118
- // if (!this.visible) {
119
- // clearInterval(this.timer);
120
- // }
121
- // },
122
- // },
123
- // created() {
124
- // this.timer = setInterval(this.carouselNext, this.interval);
125
- // },
123
+ localData() {
124
+ const fks = Object.keys(this.fields || {});
125
+ return (this.data || []).map((dd) => {
126
+ const ret = {};
127
+ for (let i = 0; i < fks.length; i += 1) {
128
+ const fk = fks[i];
129
+ ret[fk] = dd[this.fields[fk]];
130
+ }
131
+
132
+ return { ...dd, ...ret };
133
+ });
134
+ },
126
135
  methods: {
127
136
  newsClicked(news) {
128
137
  let url = '';
129
138
  if (news.url) url += news.url;
130
139
  else if (this.url) url += `${this.url}${news.id || ''}`;
131
140
 
132
- if (url && this.$route.fullPath !== url) {
133
- this.$router.push({ path: url });
141
+ if (url && this.route.fullPath !== url) {
142
+ this.router.push({ path: url });
134
143
  }
135
144
  },
136
145
  // carouselNext() {
@@ -0,0 +1,56 @@
1
+ import { unref, getCurrentInstance, computed } from "vue";
2
+
3
+ export function useFormValidator(...list) {
4
+ const { proxy:vm } = getCurrentInstance();
5
+
6
+ return {
7
+ validate: computed(() => {
8
+ return (...args) => {
9
+ if (vm.shouldHide) return true;
10
+
11
+ // could have customized validate function in component
12
+ if (vm.selfValidate && typeof vm.selfValidate === 'function') {
13
+ return vm.selfValidate();
14
+ }
15
+
16
+ const refsList = [];
17
+ for(let i = 0; i < list.length; i += 1) {
18
+ if (typeof list[i] === 'string') {
19
+ list[i] = vm.$refs[list[i]];
20
+ } else if (typeof list[i] === 'function') {
21
+ list[i] = list[i]();
22
+ }
23
+
24
+ if (Array.isArray(list[i])) {
25
+ refsList.push(...list[i])
26
+ } else {
27
+ refsList.push(list[i])
28
+ }
29
+ }
30
+
31
+ if (refsList.length <= 0) return true;
32
+
33
+ let hasErr = false;
34
+ for (let i = 0; i < refsList.length; i += 1) {
35
+ let refi = unref(refsList[i]);
36
+
37
+
38
+ const validFun = unref(refi.validate || refi.methods?.validate || refi.component?.exposed?.validate|| refi.component?.ctx?.validate);
39
+ const shouldHide = unref(refi.shouldHide || refi.component?.ctx?.shouldHide);
40
+
41
+ if (typeof validFun === 'function' && shouldHide !== true) {
42
+ hasErr = !validFun() || hasErr;
43
+
44
+ if (hasErr) {
45
+ console.error('got error', args)
46
+ break;
47
+ }
48
+ }
49
+ }
50
+
51
+ return !hasErr;
52
+ };
53
+ }),
54
+ }
55
+ };
56
+
@@ -1,6 +1,6 @@
1
1
  import { defineComponent, h, ref, getCurrentInstance } from 'vue';
2
- import { useFreeField, freeFieldProps } from '../composible/useFreeField';
3
2
  import { QCheckbox } from 'quasar';
3
+ import { useFreeField, freeFieldProps } from '../composible/useFreeField';
4
4
 
5
5
  export default defineComponent({
6
6
  name: 'InputFieldAgreementCheck',
@@ -21,7 +21,7 @@ export default defineComponent({
21
21
  ...freeFieldProps,
22
22
  },
23
23
  emits: ['input'],
24
- setup(props, { emit }){
24
+ setup(props, { emit, expose }){
25
25
  if (!props.Field) return {};
26
26
 
27
27
  const { proxy:vm } = getCurrentInstance();
@@ -106,6 +106,10 @@ export default defineComponent({
106
106
  return isValid;
107
107
  };
108
108
 
109
+ defineExpose({
110
+ validate,
111
+ })
112
+
109
113
  const checkboxNode = () => h(QCheckbox, {
110
114
  disable: props.Field?.ReadOnly,
111
115
  label: props.Field?.showLabel ? '' : props.Field?.Label,
@@ -1,4 +1,5 @@
1
1
  import { defineComponent, h } from 'vue';
2
+ import { freeFieldProps } from '../composible/useFreeField';
2
3
 
3
4
  export default defineComponent({
4
5
  name: 'InputFieldCategory',
@@ -9,7 +10,7 @@ export default defineComponent({
9
10
  Description: '',
10
11
  },
11
12
  props: {
12
- Field: { type: Object },
13
+ ...freeFieldProps,
13
14
  },
14
15
  methods: {
15
16
  },
@@ -76,6 +76,7 @@ export default defineComponent({
76
76
  if (!props.Field) return {};
77
77
 
78
78
  const { fieldData, setFieldData } = useFreeField(props);
79
+ fieldData.value = fieldData.value || false;
79
80
 
80
81
  const before = (props.Field.showLabel && !props.Field.dense && props.Field.Label !== void 0) ? () => h(freeFieldLabel, {
81
82
  Field: props.Field,
@@ -1,7 +1,8 @@
1
1
  import { ref, defineComponent, getCurrentInstance, h, computed } from 'vue';
2
- import { useFreeField, freeFieldProps, useFreeFieldMethods } from '../composible/useFreeField';
3
2
  import { QInput, QIcon, QPopupProxy, QDate } from 'quasar';
3
+ import { useFreeField, freeFieldProps, useFreeFieldMethods } from '../composible/useFreeField';
4
4
  import freeFieldLabel from '../composible/freeFieldLabel';
5
+ import { useFormValidator} from '../../composible/useFormValidator';
5
6
 
6
7
  export default defineComponent({
7
8
  name: 'InputFieldDate',
@@ -40,7 +41,7 @@ export default defineComponent({
40
41
  methods: {
41
42
  ...useFreeFieldMethods,
42
43
  },
43
- setup(props, { emit, slots }){
44
+ setup(props, { emit, slots, expose }){
44
45
  if (!props.Field) return {};
45
46
 
46
47
  const { proxy: vm } = getCurrentInstance();
@@ -80,7 +81,7 @@ export default defineComponent({
80
81
 
81
82
  const showPopup = ref(false);
82
83
 
83
- const DateNode = () => h(QInput, {
84
+ const DateNode = computed(() => h(QInput, {
84
85
  hideBottomSpace: true,
85
86
  readonly: props.Field?.ReadOnly,
86
87
 
@@ -121,12 +122,19 @@ export default defineComponent({
121
122
  class: 'cursor-pointer',
122
123
  name: 'event'
123
124
  }),
124
- });
125
+ }));
126
+
127
+ const {
128
+ validate,
129
+ } = useFormValidator(DateNode);
130
+ expose({
131
+ validate,
132
+ })
125
133
 
126
134
  return () => h('div', {
127
135
  class: 'simple-field input-field-date row items-center no-wrap',
128
136
  }, [
129
- props.Field.ReadOnly ? readonlyNode() : DateNode(),
137
+ props.Field.ReadOnly ? readonlyNode() : DateNode.value,
130
138
  slots.warning && slots.warning(),
131
139
  ]);
132
140
  },
@@ -1,7 +1,8 @@
1
1
  import { ref, defineComponent, getCurrentInstance, h, computed, watch, watchEffect } from 'vue';
2
- import { useFreeField, freeFieldProps, useFreeFieldMethods } from '../composible/useFreeField';
3
2
  import { QInput, QIcon, QPopupProxy, QDate } from 'quasar';
3
+ import { useFreeField, freeFieldProps, useFreeFieldMethods } from '../composible/useFreeField';
4
4
  import freeFieldLabel from '../composible/freeFieldLabel';
5
+ import { useFormValidator} from '../../composible/useFormValidator';
5
6
 
6
7
  export default defineComponent({
7
8
  name: 'InputFieldDateRange',
@@ -40,7 +41,7 @@ export default defineComponent({
40
41
  methods: {
41
42
  ...useFreeFieldMethods,
42
43
  },
43
- setup(props, { emit, slots }){
44
+ setup(props, { emit, slots, expose }){
44
45
  if (!props.Field) return {};
45
46
 
46
47
  const { proxy: vm } = getCurrentInstance();
@@ -119,7 +120,7 @@ export default defineComponent({
119
120
  const showMaxPopup = ref(false);
120
121
 
121
122
 
122
- const minDateNode = () => h(QInput, {
123
+ const minDateNode = computed(() => h(QInput, {
123
124
  hideBottomSpace: true,
124
125
  readonly: props.Field?.ReadOnly,
125
126
 
@@ -162,9 +163,9 @@ export default defineComponent({
162
163
  class: 'cursor-pointer',
163
164
  name: 'event'
164
165
  }),
165
- });
166
+ }));
166
167
 
167
- const maxDateNode = () => h(QInput, {
168
+ const maxDateNode = computed(() => h(QInput, {
168
169
  hideBottomSpace: true,
169
170
  readonly: props.Field?.ReadOnly,
170
171
 
@@ -206,7 +207,12 @@ export default defineComponent({
206
207
  class: 'cursor-pointer',
207
208
  name: 'event'
208
209
  }),
209
- });
210
+ }));
211
+
212
+ const { validate } = useFormValidator(minDateNode, maxDateNode);
213
+ expose({
214
+ validate,
215
+ })
210
216
 
211
217
  return () => h('div', {
212
218
  class: 'simple-field input-field-date row items-center no-wrap',
@@ -214,11 +220,11 @@ export default defineComponent({
214
220
  props.Field.ReadOnly ? readonlyNode() : h('div', {
215
221
  class: 'row items-center no-wrap'
216
222
  }, [
217
- minDateNode(),
223
+ minDateNode.value,
218
224
  h('span', {
219
225
  class: 'input-field-range-separator'
220
226
  },props.Field.Separator || '~'),
221
- maxDateNode(),
227
+ maxDateNode.value,
222
228
  ]),
223
229
  slots.warning && slots.warning(),
224
230
  ]);