@@ -20,113 +20,94 @@ This is a convenience component that wraps an input component, allowing
2020dynamically created inputs.
2121-->
2222
23- <script >
24- import { h , mergeProps } from ' vue'
23+ <template >
24+ <component
25+ :is =" inputProps.is"
26+ v-bind =" inputProps"
27+ v-model =" model"
28+ :gqlType =" gqlType"
29+ :types =" types"
30+ v-mask =" inputProps.mask"
31+ >
32+ <template
33+ v-if =" help "
34+ v-slot :append-inner
35+ >
36+ <v-tooltip >
37+ <template v-slot :activator =" { props } " >
38+ <v-icon
39+ v-bind =" props"
40+ style =" cursor : default "
41+ :icon =" mdiHelpCircleOutline"
42+ />
43+ </template >
44+ <Markdown :markdown =" help" />
45+ </v-tooltip >
46+ </template >
47+ <!-- pass the "append" slot onto the child component -->
48+ <template v-slot :append =" slotProps " >
49+ <slot
50+ name =" append"
51+ v-bind =" slotProps"
52+ />
53+ </template >
54+ </component >
55+ </template >
56+
57+ <script setup>
58+ import { mergeProps , useAttrs } from ' vue'
2559import { mask } from ' vue-the-mask'
2660import Markdown from ' @/components/Markdown.vue'
27- import { formElement } from ' @/components/graphqlFormGenerator/mixins'
61+ import { formElementProps , useFormElement } from ' @/components/graphqlFormGenerator/mixins'
2862import VuetifyConfig , { getComponentProps } from ' @/components/graphqlFormGenerator/components/vuetify'
2963import { mdiHelpCircleOutline } from ' @mdi/js'
3064import { VIcon } from ' vuetify/components/VIcon'
3165import { VTooltip } from ' vuetify/components/VTooltip'
32- import { upperFirst } from ' lodash'
33-
34- /**
35- * Render help icon with tooltip containing help text.
36- *
37- * @param {string} helpText - (supports markdown)
38- */
39- export const renderHelpIcon = (helpText ) => h (
40- VTooltip,
41- { location: ' bottom' },
42- {
43- activator : ({ props }) => h (
44- VIcon,
45- {
46- ... props,
47- style: {
48- cursor: ' default'
49- }
50- },
51- () => mdiHelpCircleOutline
52- ),
53- default : () => h (Markdown, { markdown: helpText })
54- }
55- )
56-
57- export default {
58- name: ' g-form-input' ,
5966
67+ defineOptions ({
6068 // Prevent fallthrough attrs overriding the supplied props for the input
6169 // https://github.com/vuejs/core/issues/6504
6270 inheritAttrs: false ,
71+ })
6372
64- mixins: [formElement],
65-
66- components: {
67- Markdown
68- },
69-
70- directives: {
71- mask : (el , binding ) => {
72- // only use the mask if one is provided, this allows us to use the
73- // mask directive on elements which it doesn't support
74- if (binding .value ) {
75- mask (el, binding)
76- }
77- }
78- },
79-
80- props: {
81- // dictionary of props for overriding default values
82- propOverrides: {
83- type: Object ,
84- default : () => { Object () }
85- }
86- },
87-
88- beforeCreate () {
89- // Set the props to pass to the form input. Note, this includes the "is"
90- // prop which tells Vue which component class to use.
91- // TODO: move to rule based system to allow changing
92- // of parent components based on child types?
93-
94- // get the default props for this graphQL type
95- const componentProps = getComponentProps (this .gqlType , VuetifyConfig .namedTypes , VuetifyConfig .kinds )
96-
97- // merge this in with default and override props
98- const propGroups = [
99- componentProps,
100- this .propOverrides || {}
101- ]
102- // rules is a list so needs special treatment
103- const rules = propGroups .flatMap (({ rules }) => rules ?? [])
104-
105- this .inputProps = mergeProps (this .$attrs , ... propGroups, { rules })
106- },
107-
108- render () {
109- // Some components implement custom v-model
110- // (https://v2.vuejs.org/v2/guide/components-custom-events.html#Customizing-Component-v-model)
111- const vModel = this .inputProps .is .options ? .model || { prop: ' modelValue' , event : ' update:modelValue' }
112- return h (
113- this .inputProps .is ,
114- {
115- ... this .inputProps ,
116- [vModel .prop ]: this .model ,
117- [` on${ upperFirst (vModel .event )} ` ]: (value ) => {
118- this .model = value
119- },
120- gqlType: this .gqlType ,
121- types: this .types
122- },
123- {
124- ' append-inner' : this .help ? () => renderHelpIcon (this .help ) : null ,
125- // pass the "append" slot onto the child component
126- append : (slotProps ) => this .$slots .append ? .(slotProps)
127- }
128- )
129- }
73+ const attrs = useAttrs ()
13074
75+ const vMask = (el , binding ) => {
76+ // only use the mask if one is provided, this allows us to use the
77+ // mask directive on elements which it doesn't support
78+ if (binding .value ) {
79+ mask (el, binding)
80+ }
13181}
82+
83+ const props = defineProps ({
84+ ... formElementProps,
85+ // dictionary of props for overriding default values
86+ propOverrides: {
87+ type: Object ,
88+ default : () => ({})
89+ }
90+ })
91+
92+ const model = defineModel ()
93+
94+ // Set the props to pass to the form input. Note, this includes the "is"
95+ // prop which tells Vue which component class to use.
96+ // TODO: move to rule based system to allow changing
97+ // of parent components based on child types?
98+
99+ // get the default props for this graphQL type
100+ const componentProps = getComponentProps (props .gqlType , VuetifyConfig .namedTypes , VuetifyConfig .kinds )
101+
102+ // merge this in with default and override props
103+ const propGroups = [
104+ componentProps,
105+ props .propOverrides || {}
106+ ]
107+ // rules is a list so needs special treatment
108+ const rules = propGroups .flatMap (({ rules }) => rules ?? [])
109+
110+ const inputProps = mergeProps (attrs, ... propGroups, { rules })
111+
112+ const { help } = useFormElement (props)
132113< / script>
0 commit comments