@mythpe/quasar-ui-qui 0.0.25 → 0.0.26-dev

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 (71) hide show
  1. package/index.d.ts +17 -0
  2. package/package.json +14 -8
  3. package/src/boot/register.ts +14 -0
  4. package/src/components/form/MAvatarViewer.vue +324 -0
  5. package/src/components/form/MAxios.vue +141 -0
  6. package/src/components/form/MBtn.vue +271 -93
  7. package/src/components/form/MCheckbox.vue +126 -0
  8. package/src/components/form/MColor.vue +122 -0
  9. package/src/components/form/MDate.vue +47 -0
  10. package/src/components/form/MEditor.vue +285 -0
  11. package/src/components/form/MEmail.vue +40 -0
  12. package/src/components/form/MField.vue +145 -0
  13. package/src/components/form/MFile.vue +212 -0
  14. package/src/components/form/MForm.vue +86 -0
  15. package/src/components/form/MHidden.vue +86 -0
  16. package/src/components/form/MHiddenInput.vue +55 -0
  17. package/src/components/form/MInput.vue +178 -0
  18. package/src/components/form/MInputFieldControl.vue +27 -0
  19. package/src/components/form/MInputLabel.vue +35 -0
  20. package/src/components/form/MMobile.vue +40 -0
  21. package/src/components/form/MPassword.vue +73 -0
  22. package/src/components/form/MPicker.vue +313 -0
  23. package/src/components/form/MRadio.vue +178 -0
  24. package/src/components/form/MSelect.vue +349 -0
  25. package/src/components/form/MTime.vue +45 -0
  26. package/src/components/form/index.ts +55 -0
  27. package/src/components/grid/MBlock.vue +39 -18
  28. package/src/components/grid/MCol.vue +11 -15
  29. package/src/components/grid/MColumn.vue +8 -0
  30. package/src/components/grid/MContainer.vue +22 -13
  31. package/src/components/grid/MHelpRow.vue +9 -12
  32. package/src/components/grid/MRow.vue +31 -10
  33. package/src/components/grid/index.ts +16 -0
  34. package/src/components/index.ts +12 -0
  35. package/src/components/transition/MFadeTransition.vue +27 -0
  36. package/src/components/transition/MFadeXTransition.vue +26 -0
  37. package/src/components/transition/MTransition.vue +41 -0
  38. package/src/components/transition/index.ts +13 -0
  39. package/src/components/typography/MTypingString.vue +8 -0
  40. package/src/components/typography/index.ts +11 -0
  41. package/src/composable/index.ts +12 -0
  42. package/src/composable/useBindInput.ts +209 -0
  43. package/src/composable/useError.ts +11 -0
  44. package/src/composable/useMyth.ts +302 -0
  45. package/src/composable/useValue.ts +12 -0
  46. package/src/index.common.js +19 -1
  47. package/src/index.esm.js +18 -3
  48. package/src/index.js +19 -0
  49. package/src/index.sass +8 -26
  50. package/src/index.ts +18 -4
  51. package/src/index.umd.js +17 -2
  52. package/src/style/m-container.sass +13 -0
  53. package/src/style/main.sass +42 -0
  54. package/src/types/api-helpers.d.ts +123 -0
  55. package/src/types/components.d.ts +769 -27
  56. package/src/types/dt.d.ts +144 -0
  57. package/src/types/index.d.ts +155 -1
  58. package/src/types/lodash.d.ts +26 -0
  59. package/src/types/quasar-helpers.d.ts +7 -0
  60. package/src/types/theme.d.ts +12 -0
  61. package/src/utils/Helpers.ts +293 -0
  62. package/src/utils/Str.ts +211 -0
  63. package/src/utils/index.ts +13 -0
  64. package/src/utils/myth.ts +95 -0
  65. package/src/utils/vee-rules.ts +32 -0
  66. package/src/utils/vue-plugin.ts +129 -0
  67. package/tsconfig.json +9 -13
  68. package/src/myth.ts +0 -30
  69. package/src/types/myth.ts +0 -42
  70. package/src/vue-plugin.ts +0 -41
  71. package/types.d.ts +0 -1
@@ -1,24 +1,175 @@
1
- <script lang="ts" setup>
2
- import type { MBtnProps } from '../../types'
3
- import { useI18n } from 'vue-i18n'
1
+ <!--
2
+ - MyTh Ahmed Faiz Copyright © 2016-2024 All rights reserved.
3
+ - Email: mythpe@gmail.com
4
+ - Mobile: +966590470092
5
+ - Website: https://www.4myth.com
6
+ - Github: https://github.com/mythpe
7
+ -->
8
+
9
+ <script
10
+ lang="ts"
11
+ setup
12
+ >
13
+ import type { MBtnProps as Props } from '../../types'
4
14
  import { computed } from 'vue'
5
- import { extend } from 'quasar'
6
- import { myth } from '../../myth'
15
+ import { myth } from '../../utils'
16
+ import { useBindInput, useMyth } from '../../composable'
17
+ import type { QBtnProps } from 'quasar'
7
18
 
8
- const props = defineProps<MBtnProps>()
9
- const options = computed(() => myth.options.value.btn ?? {})
10
- const { t, te } = useI18n({ useScope: 'global' })
11
- const getLabel = computed(() => {
12
- if (props.label !== undefined) {
13
- if (te(`attributes.${props.label}`)) {
14
- return t(`attributes.${props.label}`)
15
- }
16
- if (te(`${props.label}`)) {
17
- return t(`${props.label}`)
18
- }
19
- }
20
- return props.label
19
+ const props = withDefaults(defineProps<Props>(), {
20
+ /**
21
+ * Size in CSS units, including unit name or standard size name (xs|sm|md|lg|xl)
22
+ */
23
+ size: undefined,
24
+ /**
25
+ * 1) Define the button native type attribute (submit, reset, button) or 2) render component with <a> tag so you can access events even if disable or 3) Use 'href' prop and specify 'type' as a media tag
26
+ * Default value: 'button'
27
+ */
28
+ type: undefined,
29
+ /**
30
+ * Equivalent to Vue Router <router-link> 'to' property; Superseded by 'href' prop if used
31
+ */
32
+ to: undefined,
33
+ /**
34
+ * Equivalent to Vue Router <router-link> 'replace' property; Superseded by 'href' prop if used
35
+ */
36
+ replace: undefined,
37
+ /**
38
+ * Native <a> link href attribute; Has priority over the 'to' and 'replace' props
39
+ */
40
+ href: undefined,
41
+ /**
42
+ * Native <a> link target attribute; Use it only with 'to' or 'href' props
43
+ */
44
+ target: undefined,
45
+ /**
46
+ * The text that will be shown on the button
47
+ */
48
+ label: undefined,
49
+ /**
50
+ * Icon name following Quasar convention; Make sure you have the icon library installed unless you are using 'img:' prefix; If 'none' (Str) is used as value then no icon is rendered (but screen real estate will still be used for it)
51
+ */
52
+ icon: undefined,
53
+ /**
54
+ * Icon name following Quasar convention; Make sure you have the icon library installed unless you are using 'img:' prefix; If 'none' (Str) is used as value then no icon is rendered (but screen real estate will still be used for it)
55
+ */
56
+ iconRight: undefined,
57
+ /**
58
+ * Use 'outline' design
59
+ */
60
+ outline: undefined,
61
+ /**
62
+ * Use 'flat' design
63
+ */
64
+ flat: undefined,
65
+ /**
66
+ * Remove shadow
67
+ */
68
+ unelevated: undefined,
69
+ /**
70
+ * Applies a more prominent border-radius for a squared shape button
71
+ */
72
+ rounded: undefined,
73
+ /**
74
+ * Use 'push' design
75
+ */
76
+ push: undefined,
77
+ /**
78
+ * Removes border-radius so borders are squared
79
+ */
80
+ square: undefined,
81
+ /**
82
+ * Applies a glossy effect
83
+ */
84
+ glossy: undefined,
85
+ /**
86
+ * Makes button size and shape to fit a Floating Action Button
87
+ */
88
+ fab: undefined,
89
+ /**
90
+ * Makes button size and shape to fit a small Floating Action Button
91
+ */
92
+ fabMini: undefined,
93
+ /**
94
+ * Apply custom padding (vertical [horizontal]); Size in CSS units, including unit name or standard size name (none|xs|sm|md|lg|xl); Also removes the min width and height when set
95
+ */
96
+ padding: undefined,
97
+ /**
98
+ * Color name for component from the Quasar Color Palette
99
+ */
100
+ color: 'primary',
101
+ /**
102
+ * Overrides text color (if needed); Color name from the Quasar Color Palette
103
+ */
104
+ textColor: undefined,
105
+ /**
106
+ * Avoid turning label text into caps (which happens by default)
107
+ */
108
+ noCaps: undefined,
109
+ /**
110
+ * Avoid label text wrapping
111
+ */
112
+ noWrap: undefined,
113
+ /**
114
+ * Dense mode; occupies less space
115
+ */
116
+ dense: undefined,
117
+ /**
118
+ * Configure material ripple (disable it by setting it to 'false' or supply a config object)
119
+ * Default value: true
120
+ */
121
+ ripple: undefined,
122
+ /**
123
+ * Tabindex HTML attribute value
124
+ */
125
+ tabindex: undefined,
126
+ /**
127
+ * Label or content alignment
128
+ * Default value: 'center'
129
+ */
130
+ align: undefined,
131
+ /**
132
+ * Stack icon and label vertically instead of on same line (like it is by default)
133
+ */
134
+ stack: undefined,
135
+ /**
136
+ * When used on flexbox parent, button will stretch to parent's height
137
+ */
138
+ stretch: undefined,
139
+ /**
140
+ * Put button into loading state (displays a QSpinner -- can be overridden by using a 'loading' slot)
141
+ * Default value: null
142
+ */
143
+ loading: undefined,
144
+ /**
145
+ * Put component in disabled mode
146
+ */
147
+ disable: undefined,
148
+ /**
149
+ * Makes a circle shaped button
150
+ */
151
+ round: undefined,
152
+ /**
153
+ * Percentage (0.0 < x < 100.0); To be used along 'loading' prop; Display a progress bar on the background
154
+ */
155
+ percentage: undefined,
156
+ /**
157
+ * Progress bar on the background should have dark color; To be used along with 'percentage' and 'loading' props
158
+ */
159
+ darkPercentage: undefined,
160
+ /**
161
+ * Emitted when the component is clicked
162
+ * @param evt JS event object; If you are using route navigation ('to'/'replace' props) and you want to cancel navigation then call evt.preventDefault() synchronously in your event handler
163
+ * @param go Available ONLY if you are using route navigation ('to'/'replace' props); When you need to control the time at which the component should trigger the route navigation then call evt.preventDefault() synchronously and then call this function at your convenience; Useful if you have async work to be done before the actual route navigation or if you want to redirect somewhere else
164
+ */
165
+ onClick: undefined
21
166
  })
167
+ const { __ } = useMyth()
168
+ const btnLoading = computed(() => myth.btnLoading.value)
169
+ const getLabel = computed<string | undefined>(() => props.label ? (__(props.label) ?? undefined) : undefined)
170
+ const getSize = computed<string>(() => myth.btnLoading.value?.size || '20px')
171
+ const getColor = computed<string | undefined>(() => myth.btnLoading.value?.color || undefined)
172
+ const { attrs } = useBindInput<QBtnProps & { name: string }>(() => props, 'btn')
22
173
  defineOptions({
23
174
  name: 'MBtn',
24
175
  inheritAttrs: !1
@@ -26,130 +177,157 @@ defineOptions({
26
177
  </script>
27
178
 
28
179
  <template>
29
- <q-btn v-bind="extend(!0,{...$attrs},options.props,{...$props},{label: getLabel})">
180
+ <q-btn v-bind="{...$props,...attrs,label:loading?`${getLabel} ...`:getLabel}">
30
181
  <template
31
- v-if="!!options.loading && !$slots.loading"
182
+ v-if="!!btnLoading && !$slots.loading"
32
183
  #loading
33
184
  >
34
185
  <q-spinner-audio
35
- v-if="options.loading.type === 'audio'"
36
- :color="options.loading.color"
37
- :size="options.loading.size"
38
- class="on-left"
186
+ v-if="btnLoading.type === 'audio'"
187
+ :class="{'on-left': !!getLabel}"
188
+ :color="getColor"
189
+ :size="getSize"
39
190
  />
40
191
  <q-spinner-ball
41
- v-if="options.loading.type === 'ball'"
42
- :color="options.loading.color"
43
- :size="options.loading.size"
44
- class="on-left"
192
+ v-if="btnLoading.type === 'ball'"
193
+ :class="{'on-left': !!getLabel}"
194
+ :color="getColor"
195
+ :size="getSize"
45
196
  />
46
197
  <q-spinner-bars
47
- v-if="options.loading.type === 'bars'"
48
- :color="options.loading.color"
49
- class="on-left"
198
+ v-if="btnLoading.type === 'bars'"
199
+ :class="{'on-left': !!getLabel}"
200
+ :color="getColor"
201
+ :size="getSize"
50
202
  />
51
203
  <q-spinner-box
52
- v-if="options.loading.type === 'box'"
53
- :color="options.loading.color"
54
- class="on-left"
204
+ v-if="btnLoading.type === 'box'"
205
+ :class="{'on-left': !!getLabel}"
206
+ :color="getColor"
207
+ :size="getSize"
55
208
  />
56
209
  <q-spinner-clock
57
- v-if="options.loading.type === 'clock'"
58
- :color="options.loading.color"
59
- class="on-left"
210
+ v-if="btnLoading.type === 'clock'"
211
+ :class="{'on-left': !!getLabel}"
212
+ :color="getColor"
213
+ :size="getSize"
60
214
  />
61
215
  <q-spinner-comment
62
- v-if="options.loading.type === 'comment'"
63
- :color="options.loading.color"
64
- class="on-left"
216
+ v-if="btnLoading.type === 'comment'"
217
+ :class="{'on-left': !!getLabel}"
218
+ :color="getColor"
219
+ :size="getSize"
65
220
  />
66
221
  <q-spinner-cube
67
- v-if="options.loading.type === 'cube'"
68
- :color="options.loading.color"
69
- class="on-left"
222
+ v-if="btnLoading.type === 'cube'"
223
+ :class="{'on-left': !!getLabel}"
224
+ :color="getColor"
225
+ :size="getSize"
70
226
  />
71
227
  <q-spinner-dots
72
- v-if="options.loading.type === 'dots'"
73
- :color="options.loading.color"
74
- class="on-left"
228
+ v-if="btnLoading.type === 'dots'"
229
+ :class="{'on-left': !!getLabel}"
230
+ :color="getColor"
231
+ :size="getSize"
75
232
  />
76
233
  <q-spinner-facebook
77
- v-if="options.loading.type === 'facebook'"
78
- :color="options.loading.color"
79
- class="on-left"
234
+ v-if="btnLoading.type === 'facebook'"
235
+ :class="{'on-left': !!getLabel}"
236
+ :color="getColor"
237
+ :size="getSize"
80
238
  />
81
239
  <q-spinner-gears
82
- v-if="options.loading.type === 'gears'"
83
- :color="options.loading.color"
84
- class="on-left"
240
+ v-if="btnLoading.type === 'gears'"
241
+ :class="{'on-left': !!getLabel}"
242
+ :color="getColor"
243
+ :size="getSize"
85
244
  />
86
245
  <q-spinner-grid
87
- v-if="options.loading.type === 'grid'"
88
- :color="options.loading.color"
89
- class="on-left"
246
+ v-if="btnLoading.type === 'grid'"
247
+ :class="{'on-left': !!getLabel}"
248
+ :color="getColor"
249
+ :size="getSize"
90
250
  />
91
251
  <q-spinner-hearts
92
- v-if="options.loading.type === 'hearts'"
93
- :color="options.loading.color"
94
- class="on-left"
252
+ v-if="btnLoading.type === 'hearts'"
253
+ :class="{'on-left': !!getLabel}"
254
+ :color="getColor"
255
+ :size="getSize"
95
256
  />
96
257
  <q-spinner-hearts
97
- v-if="options.loading.type === 'hearts'"
98
- :color="options.loading.color"
99
- class="on-left"
258
+ v-if="btnLoading.type === 'hearts'"
259
+ :class="{'on-left': !!getLabel}"
260
+ :color="getColor"
261
+ :size="getSize"
100
262
  />
101
263
  <q-spinner-hourglass
102
- v-if="options.loading.type === 'hourglass'"
103
- :color="options.loading.color"
104
- class="on-left"
264
+ v-if="btnLoading.type === 'hourglass'"
265
+ :class="{'on-left': !!getLabel}"
266
+ :color="getColor"
267
+ :size="getSize"
105
268
  />
106
269
  <q-spinner-infinity
107
- v-if="options.loading.type === 'infinity'"
108
- :color="options.loading.color"
109
- class="on-left"
270
+ v-if="btnLoading.type === 'infinity'"
271
+ :class="{'on-left': !!getLabel}"
272
+ :color="getColor"
273
+ :size="getSize"
110
274
  />
111
275
  <q-spinner-ios
112
- v-if="options.loading.type === 'ios'"
113
- :color="options.loading.color"
114
- class="on-left"
276
+ v-if="btnLoading.type === 'ios'"
277
+ :class="{'on-left': !!getLabel}"
278
+ :color="getColor"
279
+ :size="getSize"
115
280
  />
116
281
  <q-spinner-orbit
117
- v-if="options.loading.type === 'orbit'"
118
- :color="options.loading.color"
119
- class="on-left"
282
+ v-if="btnLoading.type === 'orbit'"
283
+ :class="{'on-left': !!getLabel}"
284
+ :color="getColor"
285
+ :size="getSize"
120
286
  />
121
287
  <q-spinner-oval
122
- v-if="options.loading.type === 'oval'"
123
- :color="options.loading.color"
124
- class="on-left"
288
+ v-if="btnLoading.type === 'oval'"
289
+ :class="{'on-left': !!getLabel}"
290
+ :color="getColor"
291
+ :size="getSize"
125
292
  />
126
293
  <q-spinner-pie
127
- v-if="options.loading.type === 'pie'"
128
- :color="options.loading.color"
129
- class="on-left"
294
+ v-if="btnLoading.type === 'pie'"
295
+ :class="{'on-left': !!getLabel}"
296
+ :color="getColor"
297
+ :size="getSize"
130
298
  />
131
299
  <q-spinner-puff
132
- v-if="options.loading.type === 'puff'"
133
- :color="options.loading.color"
134
- class="on-left"
300
+ v-if="btnLoading.type === 'puff'"
301
+ :class="{'on-left': !!getLabel}"
302
+ :color="getColor"
303
+ :size="getSize"
135
304
  />
136
305
  <q-spinner-radio
137
- v-if="options.loading.type === 'radio'"
138
- :color="options.loading.color"
139
- class="on-left"
306
+ v-if="btnLoading.type === 'radio'"
307
+ :class="{'on-left': !!getLabel}"
308
+ :color="getColor"
309
+ :size="getSize"
140
310
  />
141
311
  <q-spinner-rings
142
- v-if="options.loading.type === 'rings'"
143
- :color="options.loading.color"
144
- class="on-left"
312
+ v-if="btnLoading.type === 'rings'"
313
+ :class="{'on-left': !!getLabel}"
314
+ :color="getColor"
315
+ :size="getSize"
145
316
  />
146
317
  <q-spinner-tail
147
- v-if="options.loading.type === 'tail'"
148
- :color="options.loading.color"
149
- class="on-left"
318
+ v-if="btnLoading.type === 'tail'"
319
+ :class="{'on-left': !!getLabel}"
320
+ :color="getColor"
321
+ :size="getSize"
322
+ />
323
+ <q-spinner
324
+ v-if="btnLoading.type === 'spinner'"
325
+ :class="{'on-left': !!getLabel}"
326
+ :color="getColor"
327
+ :size="getSize"
150
328
  />
151
- <template v-if="options.loading.label === !0">
152
- {{ getLabel }}
329
+ <template v-if="btnLoading.noLabel !== !1 && getLabel">
330
+ <span>{{ getLabel }}</span>
153
331
  </template>
154
332
  </template>
155
333
  <template
@@ -0,0 +1,126 @@
1
+ <!--
2
+ - MyTh Ahmed Faiz Copyright © 2016-2024 All rights reserved.
3
+ - Email: mythpe@gmail.com
4
+ - Mobile: +966590470092
5
+ - Website: https://www.4myth.com
6
+ - Github: https://github.com/mythpe
7
+ -->
8
+
9
+ <script lang="ts" setup>
10
+ import { useField } from 'vee-validate'
11
+ import { computed, reactive, toValue, useTemplateRef } from 'vue'
12
+ import { useBindInput, useMyth } from '../../composable'
13
+ import type { MCheckboxProps as Props } from '../../types'
14
+ import { QCheckbox, QField } from 'quasar'
15
+ import { myth } from '../../utils'
16
+
17
+ const props = defineProps<Props>()
18
+ defineModel<Props['modelValue']>({ required: !1, default: undefined })
19
+ const { __ } = useMyth()
20
+ const helper = useBindInput<any>(() => props, 'checkbox')
21
+ const { getLabel, attrs, inputRules } = helper
22
+ const options = computed(() => myth.props.value)
23
+ const inputScope = useField<Props['modelValue']>(() => props.name, inputRules, {
24
+ syncVModel: !0,
25
+ label: getLabel,
26
+ type: 'checkbox',
27
+ checkedValue: () => props.val,
28
+ ...toValue<any>(props.fieldOptions)
29
+ })
30
+ const { value, errorMessage, handleChange } = inputScope
31
+
32
+ const listeners = {
33
+ 'update:modelValue': (v: Props['modelValue']) => handleChange(v, !!errorMessage.value)
34
+ }
35
+ const input = useTemplateRef<InstanceType<typeof QCheckbox> | null>('input')
36
+ const scopes = reactive(inputScope)
37
+ defineExpose<typeof scopes & { input: typeof input }>({ input, ...scopes })
38
+ defineOptions({
39
+ name: 'MCheckbox',
40
+ inheritAttrs: !1
41
+ })
42
+ </script>
43
+
44
+ <template>
45
+ <MCol
46
+ :auto="auto"
47
+ :class="[$attrs.class,{'m--input__required':inputRules?.required!==undefined,'m--input__error':!!errorMessage,'m--input__view':viewMode}]"
48
+ :col="col"
49
+ :lg="lg"
50
+ :md="md"
51
+ :name="name"
52
+ :sm="sm"
53
+ :xs="xs"
54
+ >
55
+ <slot
56
+ name="top-input"
57
+ v-bind="scopes"
58
+ />
59
+ <slot name="caption">
60
+ <div
61
+ v-if="!!caption"
62
+ class="m--input__caption text-caption"
63
+ >
64
+ {{ __(caption) }}
65
+ </div>
66
+ </slot>
67
+ <MRow v-bind="rowProps">
68
+ <slot
69
+ name="before"
70
+ v-bind="scopes"
71
+ />
72
+ <MCol v-bind="colProps">
73
+ <q-field
74
+ :error="!!errorMessage"
75
+ :error-message="errorMessage"
76
+ :hint="__(hint)"
77
+ v-bind="{
78
+ ...$props,
79
+ ...attrs,
80
+ borderless: !0,
81
+ outlined: !1,
82
+ stackLabel: !0
83
+ }"
84
+ >
85
+ <q-checkbox
86
+ ref="input"
87
+ v-bind="{
88
+ ...$props,
89
+ ...attrs,
90
+ modelValue:value,
91
+ disable:viewMode,
92
+ label: undefined,
93
+ }"
94
+ v-on="listeners"
95
+ >
96
+ <template #default>
97
+ <MRow class="items-center">
98
+ <div
99
+ v-if="!!getLabel"
100
+ class="text-color"
101
+ >
102
+ {{ getLabel }}
103
+ </div>
104
+ <MHelpRow
105
+ v-if="!!help"
106
+ :right="!!getLabel"
107
+ :text="help"
108
+ tooltip
109
+ />
110
+ </MRow>
111
+ </template>
112
+ </q-checkbox>
113
+ </q-field>
114
+ <slot v-bind="scopes" />
115
+ </MCol>
116
+ <slot
117
+ name="after"
118
+ v-bind="scopes"
119
+ />
120
+ </MRow>
121
+ <slot
122
+ name="bottom-input"
123
+ v-bind="scopes"
124
+ />
125
+ </MCol>
126
+ </template>
@@ -0,0 +1,122 @@
1
+ <!--
2
+ - MyTh Ahmed Faiz Copyright © 2016-2024 All rights reserved.
3
+ - Email: mythpe@gmail.com
4
+ - Mobile: +966590470092
5
+ - Website: https://www.4myth.com
6
+ - Github: https://github.com/mythpe
7
+ -->
8
+
9
+ <script
10
+ lang="ts"
11
+ setup
12
+ >
13
+ import type { MInputProps as Props, MInputSlots } from '../../types'
14
+ import { reactive, toValue, useTemplateRef } from 'vue'
15
+ import { useField } from 'vee-validate'
16
+ import { useBindInput } from '../../composable'
17
+ import { QField, QInput } from 'quasar'
18
+
19
+ const props = withDefaults(defineProps<Props>(), {
20
+ name: () => '',
21
+ fillMask: undefined,
22
+ reverseFillMask: undefined,
23
+ unmaskedValue: undefined,
24
+ error: undefined,
25
+ noErrorIcon: undefined,
26
+ reactiveRules: undefined,
27
+ lazyRules: undefined,
28
+ stackLabel: undefined,
29
+ hideHint: undefined,
30
+ dark: undefined,
31
+ loading: undefined,
32
+ clearable: undefined,
33
+ filled: undefined,
34
+ outlined: undefined,
35
+ borderless: undefined,
36
+ standout: undefined,
37
+ labelSlot: undefined,
38
+ bottomSlots: undefined,
39
+ hideBottomSpace: undefined,
40
+ counter: undefined,
41
+ rounded: undefined,
42
+ square: undefined,
43
+ dense: undefined,
44
+ itemAligned: undefined,
45
+ disable: undefined,
46
+ readonly: undefined,
47
+ autofocus: undefined,
48
+ autogrow: undefined,
49
+ viewMode: undefined,
50
+ auto: undefined,
51
+ col: undefined,
52
+ xs: undefined,
53
+ sm: undefined,
54
+ md: undefined,
55
+ lg: undefined,
56
+ xl: undefined,
57
+ required: undefined,
58
+ autocomplete: undefined,
59
+ topLabel: undefined,
60
+ mobile: undefined,
61
+ email: undefined,
62
+ float: undefined
63
+ })
64
+ defineModel<Props['modelValue']>({ required: !1, default: undefined })
65
+ const helper = useBindInput<Props>(() => props, 'input')
66
+ const { getLabel, inputRules, attrs } = helper
67
+ const inputScope = useField<Props['modelValue']>(() => props.name, inputRules, {
68
+ syncVModel: !0,
69
+ label: getLabel,
70
+ ...toValue<any>(props.fieldOptions)
71
+ })
72
+ const { value, errorMessage, handleChange, handleBlur } = inputScope
73
+
74
+ const listeners = {
75
+ blur: (v: any) => handleBlur(v, !0),
76
+ 'update:modelValue': (v: Props['modelValue']) => handleChange(v, !!errorMessage.value)
77
+ }
78
+ const input = useTemplateRef<InstanceType<typeof QInput> | InstanceType<typeof QField>>('input')
79
+ const scopes = reactive(inputScope)
80
+ defineExpose<typeof scopes & { input: typeof input }>({ input, ...scopes })
81
+ defineOptions({
82
+ name: 'MColor',
83
+ inheritAttrs: !1
84
+ })
85
+
86
+ </script>
87
+
88
+ <template>
89
+ <MInput
90
+ ref="input"
91
+ v-bind="{...$props,...attrs,rules:inputRules,modelValue:value}"
92
+ v-on="listeners"
93
+ >
94
+ <template #prepend>
95
+ <div
96
+ :style="`width: 20px; height: 20px; background-color: ${value};`"
97
+ class="m--input__color-preview"
98
+ />
99
+ </template>
100
+ <template #append>
101
+ <q-icon
102
+ class="cursor-pointer"
103
+ name="colorize"
104
+ >
105
+ <q-popup-proxy
106
+ cover
107
+ transition-hide="scale"
108
+ transition-show="scale"
109
+ >
110
+ <q-color v-model="value" />
111
+ </q-popup-proxy>
112
+ </q-icon>
113
+ </template>
114
+ <template
115
+ v-for="(_,slot) in $slots as Readonly<MInputSlots>"
116
+ :key="slot"
117
+ #[slot]
118
+ >
119
+ <slot :name="slot" />
120
+ </template>
121
+ </MInput>
122
+ </template>