11<script setup lang="ts">
22import { computed , ref , watch } from ' vue' ;
3- import { QInput } from ' quasar' ;
4- import { useFormField , generateFieldId } from ' @quickflo/quickforms-vue' ;
3+ import { QInput , QIcon } from ' quasar' ;
4+ import { useFormField , generateFieldId , useFormContext } from ' @quickflo/quickforms-vue' ;
55import type { FieldProps } from ' @quickflo/quickforms-vue' ;
6+ import type { QuasarFormOptions } from ' ../types' ;
67
78const props = withDefaults (defineProps <FieldProps >(), {
89 disabled: false ,
@@ -15,6 +16,8 @@ const { value, setValue, label, hint, errorMessage, required } = useFormField(
1516 { label: props .label }
1617);
1718
19+ const formContext = useFormContext <QuasarFormOptions >();
20+
1821const fieldId = generateFieldId (props .path );
1922
2023// Local text state for JSON editing
@@ -103,11 +106,30 @@ function handleKeyDown(event: KeyboardEvent) {
103106
104107const displayError = computed (() => parseError .value || errorMessage .value );
105108
106- // Get Quasar-specific props
109+ // Get Quasar-specific props with defaults
107110const quasarProps = computed (() => {
111+ const globalDefaults = formContext ?.componentDefaults ?.global || {};
112+ const jsonEditorDefaults = formContext ?.componentDefaults ?.jsoneditor || {};
108113 const xQuasarProps = (props .schema as any )[' x-quasar-props' ] || {};
109114 const xComponentProps = (props .schema as any )[' x-component-props' ] || {};
110- return { ... xComponentProps , ... xQuasarProps };
115+
116+ // Merge in order: global defaults < jsoneditor defaults < schema-specific props
117+ return { ... globalDefaults , ... jsonEditorDefaults , ... xComponentProps , ... xQuasarProps };
118+ });
119+
120+ // Get QuickForms-specific features (icons, etc.)
121+ const quickformsFeatures = computed (() => {
122+ const globalFeatures = formContext ?.quickformsDefaults ?.global || {};
123+ const jsonEditorFeatures = formContext ?.quickformsDefaults ?.jsoneditor || {};
124+ const xQuickformsQuasar = (props .schema as any )[' x-quickforms-quasar' ] || {};
125+
126+ // Merge in order: global < jsoneditor < schema-specific
127+ return { ... globalFeatures , ... jsonEditorFeatures , ... xQuickformsQuasar };
128+ });
129+
130+ // Whether to show the format hint icon (default: true)
131+ const showFormatHint = computed (() => {
132+ return quickformsFeatures .value .showFormatHint !== false ;
111133});
112134
113135// Get rows from schema or default
@@ -116,44 +138,90 @@ const rows = computed(() => {
116138 return xRows !== undefined ? xRows : 8 ;
117139});
118140
119- // Enhanced hint with format shortcut info
120- const enhancedHint = computed (() => {
121- const formatHint = ' Press Ctrl+Space to format' ;
122- return hint .value ? ` ${hint .value } • ${formatHint } ` : formatHint ;
123- });
124141 </script >
125142
126143<template >
127- <QInput
128- :id =" fieldId"
129- :model-value =" jsonText"
130- :label =" label"
131- :hint =" enhancedHint"
132- :error =" !!displayError"
133- :error-message =" displayError || undefined"
134- :disable =" disabled"
135- :readonly =" readonly"
136- :rules =" [() => !displayError || displayError]"
137- type =" textarea"
138- :rows =" rows"
139- outlined
140- dense
141- class =" quickform-json-field"
142- input-class =" quickform-json-editor"
143- input-style =" font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace; font-size: 0.813rem; line-height: 1.5;"
144- placeholder =" {}"
145- v-bind =" quasarProps"
146- @update:model-value =" handleInput"
147- @keydown =" handleKeyDown"
148- >
149- <template v-if =" required " #label >
150- {{ label }} <span style =" color : red ; margin-left : 0.25rem " >*</span >
151- </template >
152- </QInput >
144+ <div class =" quickform-json-field-wrapper" >
145+ <div v-if =" label" class =" quickform-label-header" >
146+ <span class =" quickform-label-text" >
147+ {{ label }}
148+ <span v-if =" required" style =" color : red ; margin-left : 0.25rem " >*</span >
149+ </span >
150+ <span v-if =" showFormatHint" class =" quickform-info-icon" title =" Press Ctrl+Space to format JSON" >ⓘ</span >
151+ </div >
152+ <QInput
153+ :id =" fieldId"
154+ :model-value =" jsonText"
155+ :hint =" hint"
156+ :error =" !!displayError"
157+ :error-message =" displayError || undefined"
158+ :disable =" disabled"
159+ :readonly =" readonly"
160+ :rules =" [() => !displayError || displayError]"
161+ type =" textarea"
162+ :rows =" rows"
163+ outlined
164+ dense
165+ class =" quickform-json-field"
166+ input-class =" quickform-json-editor"
167+ input-style =" font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace; font-size: 0.813rem; line-height: 1.5;"
168+ placeholder =" {}"
169+ v-bind =" quasarProps"
170+ @update:model-value =" handleInput"
171+ @keydown =" handleKeyDown"
172+ >
173+ <template v-if =" quickformsFeatures .prependIcon " #prepend >
174+ <QIcon
175+ :name =" quickformsFeatures.prependIcon"
176+ :color =" quickformsFeatures.iconColor || 'grey-7'"
177+ :size =" quickformsFeatures.iconSize || 'sm'"
178+ />
179+ </template >
180+ <template v-if =" quickformsFeatures .appendIcon " #append >
181+ <QIcon
182+ :name =" quickformsFeatures.appendIcon"
183+ :color =" quickformsFeatures.iconColor || 'grey-7'"
184+ :size =" quickformsFeatures.iconSize || 'sm'"
185+ />
186+ </template >
187+ </QInput >
188+ </div >
153189</template >
154190
155191<style scoped>
156- .quickform-json-field :deep(.quickform-json-editor ) {
192+ .quickform-json-field-wrapper {
193+ width : 100% ;
194+ }
195+
196+ .quickform-label-header {
197+ display : flex ;
198+ align-items : center ;
199+ gap : 0.375rem ;
200+ margin-bottom : 0.5rem ;
201+ }
202+
203+ .quickform-label-text {
204+ font-size : 0.875rem ;
205+ font-weight : 500 ;
206+ color : rgba (0 , 0 , 0 , 0.87 );
207+ }
208+
209+ .quickform-info-icon {
210+ font-size : 0.875rem ;
211+ color : rgba (0 , 0 , 0 , 0.54 );
212+ cursor : help ;
213+ opacity : 0.7 ;
214+ transition : opacity 0.2s ;
215+ line-height : 1 ;
216+ display : flex ;
217+ align-items : center ;
218+ }
219+
220+ .quickform-info-icon :hover {
221+ opacity : 1 ;
222+ }
223+
224+ .quickform-json-field-wrapper :deep(.quickform-json-editor ) {
157225 font-family : ' Monaco' , ' Menlo' , ' Ubuntu Mono' , ' Consolas' , ' source-code-pro' , monospace ;
158226 font-size : 0.813rem ;
159227 line-height : 1.5 ;
0 commit comments