@iankibetsh/shframework 5.7.7 → 5.7.8

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.
@@ -260,38 +260,6 @@
260
260
  }
261
261
  }
262
262
 
263
- .colored-toast.swal2-icon-success {
264
- background-color: #a5dc86 !important;
265
- }
266
-
267
- .colored-toast.swal2-icon-error {
268
- background-color: #f27474 !important;
269
- }
270
-
271
- .colored-toast.swal2-icon-warning {
272
- background-color: #f8bb86 !important;
273
- }
274
-
275
- .colored-toast.swal2-icon-info {
276
- background-color: #3fc3ee !important;
277
- }
278
-
279
- .colored-toast.swal2-icon-question {
280
- background-color: #87adbd !important;
281
- }
282
-
283
- .colored-toast .swal2-title {
284
- color: white;
285
- }
286
-
287
- .colored-toast .swal2-close {
288
- color: white;
289
- }
290
-
291
- .colored-toast .swal2-html-container {
292
- color: white;
293
- }
294
-
295
263
  .sh-phone{
296
264
  display: flex;
297
265
  width: 100%;
@@ -324,6 +292,38 @@
324
292
  opacity: 0.5;
325
293
  }
326
294
 
295
+ .colored-toast.swal2-icon-success {
296
+ background-color: #a5dc86 !important;
297
+ }
298
+
299
+ .colored-toast.swal2-icon-error {
300
+ background-color: #f27474 !important;
301
+ }
302
+
303
+ .colored-toast.swal2-icon-warning {
304
+ background-color: #f8bb86 !important;
305
+ }
306
+
307
+ .colored-toast.swal2-icon-info {
308
+ background-color: #3fc3ee !important;
309
+ }
310
+
311
+ .colored-toast.swal2-icon-question {
312
+ background-color: #87adbd !important;
313
+ }
314
+
315
+ .colored-toast .swal2-title {
316
+ color: white;
317
+ }
318
+
319
+ .colored-toast .swal2-close {
320
+ color: white;
321
+ }
322
+
323
+ .colored-toast .swal2-html-container {
324
+ color: white;
325
+ }
326
+
327
327
  .permissions-main {
328
328
  background: #edeff2;
329
329
  }
package/dist/library.js CHANGED
@@ -2141,7 +2141,16 @@ const setSelectedCountry = () => {
2141
2141
  };
2142
2142
 
2143
2143
  vue.watch(() => props.modelValue, (newVal) => {
2144
- if (!input.value) {
2144
+ if (!newVal) {
2145
+ input.value = '';
2146
+ return;
2147
+ }
2148
+
2149
+ const country = countriesList.value.find(c => newVal.startsWith(c.dialCode));
2150
+ if (country) {
2151
+ selectedCountry.value = country;
2152
+ input.value = newVal.replace(country.dialCode, '').replace(/:/g, '');
2153
+ } else {
2145
2154
  input.value = newVal.replace('+254', '').replace('+1', '');
2146
2155
  }
2147
2156
  });
@@ -3110,29 +3119,21 @@ var script$x = {
3110
3119
 
3111
3120
  const props = __props;
3112
3121
  const emit = __emit;
3113
- const inputModel = vue.ref(null);
3114
3122
 
3115
- const modelValueUpdated = (e) => {
3116
- emit('clearValidationErrors');
3117
- emit('update:modelValue',inputModel.value);
3118
- };
3119
- vue.onMounted(()=>{
3120
- props.modelValue && (inputModel.value = props.modelValue);
3121
- });
3122
- vue.watch(()=>props.modelValue, (newValue)=>{
3123
- if(newValue) {
3124
- inputModel.value = newValue;
3123
+ // Use computed for proper two-way binding
3124
+ const inputModel = vue.computed({
3125
+ get: () => props.modelValue,
3126
+ set: (value) => {
3127
+ emit('clearValidationErrors');
3128
+ emit('update:modelValue', value);
3125
3129
  }
3126
3130
  });
3127
3131
 
3128
3132
  return (_ctx, _cache) => {
3129
3133
  return vue.withDirectives((vue.openBlock(), vue.createElementBlock("input", {
3130
3134
  type: "email",
3131
- "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event)),
3132
- onChange: modelValueUpdated,
3133
- onKeydown: modelValueUpdated,
3134
- onUpdated: modelValueUpdated
3135
- }, null, 544 /* NEED_HYDRATION, NEED_PATCH */)), [
3135
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event))
3136
+ }, null, 512 /* NEED_PATCH */)), [
3136
3137
  [vue.vModelText, inputModel.value]
3137
3138
  ])
3138
3139
  }
@@ -3153,18 +3154,13 @@ var script$w = {
3153
3154
 
3154
3155
  const props = __props;
3155
3156
  const emit = __emit;
3156
- const inputModel = vue.ref(null);
3157
3157
 
3158
- const modelValueUpdated = (e) => {
3159
- emit('clearValidationErrors');
3160
- emit('update:modelValue',inputModel.value);
3161
- };
3162
- vue.onMounted(()=>{
3163
- props.modelValue && (inputModel.value = props.modelValue);
3164
- });
3165
- vue.watch(()=>props.modelValue, (newValue)=>{
3166
- if(newValue) {
3167
- inputModel.value = newValue;
3158
+ // Use computed for proper two-way binding
3159
+ const inputModel = vue.computed({
3160
+ get: () => props.modelValue,
3161
+ set: (value) => {
3162
+ emit('clearValidationErrors');
3163
+ emit('update:modelValue', value);
3168
3164
  }
3169
3165
  });
3170
3166
 
@@ -3173,11 +3169,8 @@ return (_ctx, _cache) => {
3173
3169
  min: __props.min,
3174
3170
  max: __props.max,
3175
3171
  type: "number",
3176
- "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event)),
3177
- onChange: modelValueUpdated,
3178
- onKeydown: modelValueUpdated,
3179
- onUpdated: modelValueUpdated
3180
- }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_1$n)), [
3172
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event))
3173
+ }, null, 8 /* PROPS */, _hoisted_1$n)), [
3181
3174
  [vue.vModelText, inputModel.value]
3182
3175
  ])
3183
3176
  }
@@ -3195,31 +3188,21 @@ var script$v = {
3195
3188
 
3196
3189
  const props = __props;
3197
3190
  const emit = __emit;
3198
- const inputModel = vue.ref(null);
3199
3191
 
3200
- const modelValueUpdated = (e) => {
3201
- emit('clearValidationErrors');
3202
- emit('update:modelValue',inputModel.value);
3203
- };
3204
- vue.onMounted(()=>{
3205
- props.modelValue && (inputModel.value = props.modelValue);
3206
- });
3207
-
3208
- vue.watch(()=>props.modelValue, (newValue)=>{
3209
- if(newValue) {
3210
- inputModel.value = newValue;
3192
+ // Use computed for proper two-way binding
3193
+ const inputModel = vue.computed({
3194
+ get: () => props.modelValue,
3195
+ set: (value) => {
3196
+ emit('clearValidationErrors');
3197
+ emit('update:modelValue', value);
3211
3198
  }
3212
3199
  });
3213
3200
 
3214
-
3215
3201
  return (_ctx, _cache) => {
3216
3202
  return vue.withDirectives((vue.openBlock(), vue.createElementBlock("input", {
3217
3203
  type: "text",
3218
- "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event)),
3219
- onChange: modelValueUpdated,
3220
- onKeydown: modelValueUpdated,
3221
- onUpdated: modelValueUpdated
3222
- }, null, 544 /* NEED_HYDRATION, NEED_PATCH */)), [
3204
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event))
3205
+ }, null, 512 /* NEED_PATCH */)), [
3223
3206
  [vue.vModelText, inputModel.value]
3224
3207
  ])
3225
3208
  }
@@ -3237,29 +3220,20 @@ var script$u = {
3237
3220
 
3238
3221
  const props = __props;
3239
3222
  const emit = __emit;
3240
- const inputModel = vue.ref(null);
3241
3223
 
3242
- const modelValueUpdated = (e) => {
3243
- emit('clearValidationErrors');
3244
- emit('update:modelValue',inputModel.value);
3245
- };
3246
- vue.onMounted(()=>{
3247
- props.modelValue && (inputModel.value = props.modelValue);
3248
- });
3249
- vue.watch(()=>props.modelValue, (newValue)=>{
3250
- if(newValue) {
3251
- inputModel.value = newValue;
3224
+ // Use computed for proper two-way binding
3225
+ const inputModel = vue.computed({
3226
+ get: () => props.modelValue,
3227
+ set: (value) => {
3228
+ emit('clearValidationErrors');
3229
+ emit('update:modelValue', value);
3252
3230
  }
3253
3231
  });
3254
3232
 
3255
3233
  return (_ctx, _cache) => {
3256
3234
  return vue.withDirectives((vue.openBlock(), vue.createElementBlock("textarea", {
3257
- type: "text",
3258
- "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event)),
3259
- onChange: modelValueUpdated,
3260
- onKeydown: modelValueUpdated,
3261
- onUpdated: modelValueUpdated
3262
- }, null, 544 /* NEED_HYDRATION, NEED_PATCH */)), [
3235
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event))
3236
+ }, null, 512 /* NEED_PATCH */)), [
3263
3237
  [vue.vModelText, inputModel.value]
3264
3238
  ])
3265
3239
  }
@@ -3280,14 +3254,19 @@ var script$t = {
3280
3254
 
3281
3255
  const props = __props;
3282
3256
  const emit = __emit;
3283
- const inputModel = vue.ref(null);
3257
+
3258
+ // Use computed for proper two-way binding
3259
+ const inputModel = vue.computed({
3260
+ get: () => props.modelValue,
3261
+ set: (value) => {
3262
+ emit('clearValidationErrors');
3263
+ emit('update:modelValue', value);
3264
+ }
3265
+ });
3266
+
3284
3267
  const selectOptions = vue.ref(null);
3285
- const modelValueUpdated = (e) => {
3286
- emit('clearValidationErrors');
3287
- emit('update:modelValue',inputModel.value);
3288
- };
3268
+
3289
3269
  vue.onMounted(()=>{
3290
- props.modelValue && (inputModel.value = props.modelValue);
3291
3270
  const options = props.data ?? props.options;
3292
3271
  if(options){
3293
3272
  selectOptions.value = options.map(item=>{
@@ -3309,18 +3288,10 @@ vue.onMounted(()=>{
3309
3288
  });
3310
3289
  }
3311
3290
  });
3312
- vue.watch(()=>props.modelValue, (newValue)=>{
3313
- if(newValue) {
3314
- inputModel.value = newValue;
3315
- }
3316
- });
3317
3291
 
3318
3292
  return (_ctx, _cache) => {
3319
3293
  return vue.withDirectives((vue.openBlock(), vue.createElementBlock("select", {
3320
- "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event)),
3321
- onChange: modelValueUpdated,
3322
- onKeydown: modelValueUpdated,
3323
- onUpdated: modelValueUpdated
3294
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event))
3324
3295
  }, [
3325
3296
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(selectOptions.value, (option) => {
3326
3297
  return (vue.openBlock(), vue.createElementBlock("option", {
@@ -3328,7 +3299,7 @@ return (_ctx, _cache) => {
3328
3299
  value: option.id
3329
3300
  }, vue.toDisplayString(option.name), 9 /* TEXT, PROPS */, _hoisted_1$m))
3330
3301
  }), 128 /* KEYED_FRAGMENT */))
3331
- ], 544 /* NEED_HYDRATION, NEED_PATCH */)), [
3302
+ ], 512 /* NEED_PATCH */)), [
3332
3303
  [vue.vModelSelect, inputModel.value]
3333
3304
  ])
3334
3305
  }
@@ -3346,25 +3317,21 @@ var script$s = {
3346
3317
 
3347
3318
  const props = __props;
3348
3319
  const emit = __emit;
3349
- const inputModel = vue.ref(null);
3350
3320
 
3351
- const modelValueUpdated = (e) => {
3352
- emit('clearValidationErrors');
3353
- emit('update:modelValue',inputModel.value);
3354
- };
3355
- vue.onMounted(()=>{
3356
- props.modelValue && (inputModel.value = props.modelValue);
3321
+ // Use computed for proper two-way binding
3322
+ const inputModel = vue.computed({
3323
+ get: () => props.modelValue,
3324
+ set: (value) => {
3325
+ emit('clearValidationErrors');
3326
+ emit('update:modelValue', value);
3327
+ }
3357
3328
  });
3358
3329
 
3359
-
3360
3330
  return (_ctx, _cache) => {
3361
3331
  return vue.withDirectives((vue.openBlock(), vue.createElementBlock("input", {
3362
3332
  type: "password",
3363
- "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event)),
3364
- onChange: modelValueUpdated,
3365
- onKeydown: modelValueUpdated,
3366
- onUpdated: modelValueUpdated
3367
- }, null, 544 /* NEED_HYDRATION, NEED_PATCH */)), [
3333
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event))
3334
+ }, null, 512 /* NEED_PATCH */)), [
3368
3335
  [vue.vModelText, inputModel.value]
3369
3336
  ])
3370
3337
  }
@@ -3382,31 +3349,21 @@ var script$r = {
3382
3349
 
3383
3350
  const props = __props;
3384
3351
  const emit = __emit;
3385
- const inputModel = vue.ref(null);
3386
3352
 
3387
- const modelValueUpdated = (e) => {
3388
- emit('clearValidationErrors');
3389
- emit('update:modelValue',inputModel.value);
3390
- };
3391
- vue.onMounted(()=>{
3392
- props.modelValue && (inputModel.value = props.modelValue);
3393
- });
3394
-
3395
- vue.watch(()=>props.modelValue, (newValue)=>{
3396
- if(newValue) {
3397
- inputModel.value = newValue;
3353
+ // Use computed for proper two-way binding
3354
+ const inputModel = vue.computed({
3355
+ get: () => props.modelValue,
3356
+ set: (value) => {
3357
+ emit('clearValidationErrors');
3358
+ emit('update:modelValue', value);
3398
3359
  }
3399
3360
  });
3400
3361
 
3401
-
3402
3362
  return (_ctx, _cache) => {
3403
3363
  return vue.withDirectives((vue.openBlock(), vue.createElementBlock("input", {
3404
3364
  type: "datetime-local",
3405
- "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event)),
3406
- onChange: modelValueUpdated,
3407
- onKeydown: modelValueUpdated,
3408
- onUpdated: modelValueUpdated
3409
- }, null, 544 /* NEED_HYDRATION, NEED_PATCH */)), [
3365
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event))
3366
+ }, null, 512 /* NEED_PATCH */)), [
3410
3367
  [vue.vModelText, inputModel.value]
3411
3368
  ])
3412
3369
  }
@@ -3665,6 +3622,8 @@ const submitBtn = vue.ref(false);
3665
3622
  const validationErrors = vue.ref({});
3666
3623
  const formError = vue.ref(null);
3667
3624
  const submitBtnWidth = vue.ref(null);
3625
+ const isDirty = vue.ref(false);
3626
+ const isSynchronizing = vue.ref(false);
3668
3627
 
3669
3628
  // Helper functions
3670
3629
  const closeModal = () => {
@@ -3708,10 +3667,19 @@ const getFormData = () => {
3708
3667
  return data
3709
3668
  };
3710
3669
 
3711
- const fieldChanged = field => {
3670
+ const fieldChanged = (field, value) => {
3671
+ if (isSynchronizing.value) return
3672
+ isDirty.value = true;
3712
3673
  delete validationErrors.value[field];
3674
+
3675
+ // Find the field and update its value if it was passed
3676
+ const fieldObj = formFields.value.find(f => f.field === field);
3677
+ if (fieldObj && value !== undefined) {
3678
+ fieldObj.value = value;
3679
+ }
3680
+
3713
3681
  const data = getFormData();
3714
- const fieldValue = formFields.value.find(f => f.field === field)?.value;
3682
+ const fieldValue = fieldObj?.value;
3715
3683
  setTimeout(() => {
3716
3684
  emit('fieldChanged', field, fieldValue, data);
3717
3685
  }, 300);
@@ -3796,6 +3764,7 @@ const handleSuccessRequest = res => {
3796
3764
  if (!props.retainDataAfterSubmission) {
3797
3765
  formFields.value.forEach(field => field.value = null);
3798
3766
  }
3767
+ isDirty.value = false;
3799
3768
 
3800
3769
  if (!props.retainModal) {
3801
3770
  closeModal();
@@ -3841,19 +3810,34 @@ const handleFailedRequest = reason => {
3841
3810
  emit('formError', reason);
3842
3811
  };
3843
3812
  const setExistingData = (existingData) => {
3813
+ // Don't sync if no data provided
3844
3814
  if (!existingData) return
3845
-
3846
- formFields.value = formFields.value.map(field => {
3847
- if (existingData[field.field] !== undefined) {
3848
- return { ...field, value: existingData[field.field] }
3815
+
3816
+ // Don't sync if user has made changes to the form
3817
+ if (isDirty.value) return
3818
+
3819
+ isSynchronizing.value = true;
3820
+ const keys = Object.keys(existingData);
3821
+
3822
+ keys.forEach(k => {
3823
+ const field = formFields.value.find(f => f.field === k);
3824
+ if (field) {
3825
+ field.value = existingData[k];
3849
3826
  }
3850
- return field
3851
3827
  });
3828
+
3829
+ setTimeout(() => {
3830
+ isSynchronizing.value = false;
3831
+ }, 100);
3852
3832
  };
3853
3833
 
3854
- vue.watch(() => props.currentData, (newData) => {
3855
- setExistingData(newData);
3856
- });
3834
+ vue.watch(() => props.currentData, (newData, oldData) => {
3835
+ // Only sync if form is pristine (not dirty) OR if this is a completely new object reference
3836
+ // This prevents reactive updates to currentData from overwriting user input
3837
+ if (!isDirty.value || !oldData) {
3838
+ setExistingData(newData);
3839
+ }
3840
+ }, { deep: true });
3857
3841
 
3858
3842
  const currentStep = vue.ref(0);
3859
3843
  const formSteps = vue.ref([]);
@@ -3901,7 +3885,11 @@ vue.onMounted(() => {
3901
3885
  type: 'hidden'
3902
3886
  });
3903
3887
 
3888
+ isSynchronizing.value = true;
3904
3889
  setExistingData(props.currentData);
3890
+ setTimeout(() => {
3891
+ isSynchronizing.value = false;
3892
+ }, 200);
3905
3893
 
3906
3894
  // Initialize steps
3907
3895
  if (!props.steps || props.steps.length === 0) {
@@ -4019,11 +4007,10 @@ return (_ctx, _cache) => {
4019
4007
  : vue.createCommentVNode("v-if", true),
4020
4008
  (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(getFieldComponent(field)), vue.mergeProps({ ref_for: true }, getComponentProps(field), {
4021
4009
  isInvalid: typeof validationErrors.value[field.field] !== 'undefined',
4022
- onClick: $event => (fieldChanged(field.field)),
4023
- "onUpdate:modelValue": [$event => (fieldChanged(field.field)), $event => ((field.value) = $event)],
4010
+ "onUpdate:modelValue": [val => fieldChanged(field.field, val), $event => ((field.value) = $event)],
4024
4011
  modelValue: field.value,
4025
4012
  class: getComponentClass(field.field)
4026
- }), null, 16 /* FULL_PROPS */, ["isInvalid", "onClick", "onUpdate:modelValue", "modelValue", "class"])),
4013
+ }), null, 16 /* FULL_PROPS */, ["isInvalid", "onUpdate:modelValue", "modelValue", "class"])),
4027
4014
  (vue.unref(isFloating) && field.label)
4028
4015
  ? (vue.openBlock(), vue.createElementBlock("label", {
4029
4016
  key: 1,
package/dist/library.mjs CHANGED
@@ -2130,7 +2130,16 @@ const setSelectedCountry = () => {
2130
2130
  };
2131
2131
 
2132
2132
  watch(() => props.modelValue, (newVal) => {
2133
- if (!input.value) {
2133
+ if (!newVal) {
2134
+ input.value = '';
2135
+ return;
2136
+ }
2137
+
2138
+ const country = countriesList.value.find(c => newVal.startsWith(c.dialCode));
2139
+ if (country) {
2140
+ selectedCountry.value = country;
2141
+ input.value = newVal.replace(country.dialCode, '').replace(/:/g, '');
2142
+ } else {
2134
2143
  input.value = newVal.replace('+254', '').replace('+1', '');
2135
2144
  }
2136
2145
  });
@@ -3099,29 +3108,21 @@ var script$x = {
3099
3108
 
3100
3109
  const props = __props;
3101
3110
  const emit = __emit;
3102
- const inputModel = ref(null);
3103
3111
 
3104
- const modelValueUpdated = (e) => {
3105
- emit('clearValidationErrors');
3106
- emit('update:modelValue',inputModel.value);
3107
- };
3108
- onMounted(()=>{
3109
- props.modelValue && (inputModel.value = props.modelValue);
3110
- });
3111
- watch(()=>props.modelValue, (newValue)=>{
3112
- if(newValue) {
3113
- inputModel.value = newValue;
3112
+ // Use computed for proper two-way binding
3113
+ const inputModel = computed({
3114
+ get: () => props.modelValue,
3115
+ set: (value) => {
3116
+ emit('clearValidationErrors');
3117
+ emit('update:modelValue', value);
3114
3118
  }
3115
3119
  });
3116
3120
 
3117
3121
  return (_ctx, _cache) => {
3118
3122
  return withDirectives((openBlock(), createElementBlock("input", {
3119
3123
  type: "email",
3120
- "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event)),
3121
- onChange: modelValueUpdated,
3122
- onKeydown: modelValueUpdated,
3123
- onUpdated: modelValueUpdated
3124
- }, null, 544 /* NEED_HYDRATION, NEED_PATCH */)), [
3124
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event))
3125
+ }, null, 512 /* NEED_PATCH */)), [
3125
3126
  [vModelText, inputModel.value]
3126
3127
  ])
3127
3128
  }
@@ -3142,18 +3143,13 @@ var script$w = {
3142
3143
 
3143
3144
  const props = __props;
3144
3145
  const emit = __emit;
3145
- const inputModel = ref(null);
3146
3146
 
3147
- const modelValueUpdated = (e) => {
3148
- emit('clearValidationErrors');
3149
- emit('update:modelValue',inputModel.value);
3150
- };
3151
- onMounted(()=>{
3152
- props.modelValue && (inputModel.value = props.modelValue);
3153
- });
3154
- watch(()=>props.modelValue, (newValue)=>{
3155
- if(newValue) {
3156
- inputModel.value = newValue;
3147
+ // Use computed for proper two-way binding
3148
+ const inputModel = computed({
3149
+ get: () => props.modelValue,
3150
+ set: (value) => {
3151
+ emit('clearValidationErrors');
3152
+ emit('update:modelValue', value);
3157
3153
  }
3158
3154
  });
3159
3155
 
@@ -3162,11 +3158,8 @@ return (_ctx, _cache) => {
3162
3158
  min: __props.min,
3163
3159
  max: __props.max,
3164
3160
  type: "number",
3165
- "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event)),
3166
- onChange: modelValueUpdated,
3167
- onKeydown: modelValueUpdated,
3168
- onUpdated: modelValueUpdated
3169
- }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_1$n)), [
3161
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event))
3162
+ }, null, 8 /* PROPS */, _hoisted_1$n)), [
3170
3163
  [vModelText, inputModel.value]
3171
3164
  ])
3172
3165
  }
@@ -3184,31 +3177,21 @@ var script$v = {
3184
3177
 
3185
3178
  const props = __props;
3186
3179
  const emit = __emit;
3187
- const inputModel = ref(null);
3188
3180
 
3189
- const modelValueUpdated = (e) => {
3190
- emit('clearValidationErrors');
3191
- emit('update:modelValue',inputModel.value);
3192
- };
3193
- onMounted(()=>{
3194
- props.modelValue && (inputModel.value = props.modelValue);
3195
- });
3196
-
3197
- watch(()=>props.modelValue, (newValue)=>{
3198
- if(newValue) {
3199
- inputModel.value = newValue;
3181
+ // Use computed for proper two-way binding
3182
+ const inputModel = computed({
3183
+ get: () => props.modelValue,
3184
+ set: (value) => {
3185
+ emit('clearValidationErrors');
3186
+ emit('update:modelValue', value);
3200
3187
  }
3201
3188
  });
3202
3189
 
3203
-
3204
3190
  return (_ctx, _cache) => {
3205
3191
  return withDirectives((openBlock(), createElementBlock("input", {
3206
3192
  type: "text",
3207
- "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event)),
3208
- onChange: modelValueUpdated,
3209
- onKeydown: modelValueUpdated,
3210
- onUpdated: modelValueUpdated
3211
- }, null, 544 /* NEED_HYDRATION, NEED_PATCH */)), [
3193
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event))
3194
+ }, null, 512 /* NEED_PATCH */)), [
3212
3195
  [vModelText, inputModel.value]
3213
3196
  ])
3214
3197
  }
@@ -3226,29 +3209,20 @@ var script$u = {
3226
3209
 
3227
3210
  const props = __props;
3228
3211
  const emit = __emit;
3229
- const inputModel = ref(null);
3230
3212
 
3231
- const modelValueUpdated = (e) => {
3232
- emit('clearValidationErrors');
3233
- emit('update:modelValue',inputModel.value);
3234
- };
3235
- onMounted(()=>{
3236
- props.modelValue && (inputModel.value = props.modelValue);
3237
- });
3238
- watch(()=>props.modelValue, (newValue)=>{
3239
- if(newValue) {
3240
- inputModel.value = newValue;
3213
+ // Use computed for proper two-way binding
3214
+ const inputModel = computed({
3215
+ get: () => props.modelValue,
3216
+ set: (value) => {
3217
+ emit('clearValidationErrors');
3218
+ emit('update:modelValue', value);
3241
3219
  }
3242
3220
  });
3243
3221
 
3244
3222
  return (_ctx, _cache) => {
3245
3223
  return withDirectives((openBlock(), createElementBlock("textarea", {
3246
- type: "text",
3247
- "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event)),
3248
- onChange: modelValueUpdated,
3249
- onKeydown: modelValueUpdated,
3250
- onUpdated: modelValueUpdated
3251
- }, null, 544 /* NEED_HYDRATION, NEED_PATCH */)), [
3224
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event))
3225
+ }, null, 512 /* NEED_PATCH */)), [
3252
3226
  [vModelText, inputModel.value]
3253
3227
  ])
3254
3228
  }
@@ -3269,14 +3243,19 @@ var script$t = {
3269
3243
 
3270
3244
  const props = __props;
3271
3245
  const emit = __emit;
3272
- const inputModel = ref(null);
3246
+
3247
+ // Use computed for proper two-way binding
3248
+ const inputModel = computed({
3249
+ get: () => props.modelValue,
3250
+ set: (value) => {
3251
+ emit('clearValidationErrors');
3252
+ emit('update:modelValue', value);
3253
+ }
3254
+ });
3255
+
3273
3256
  const selectOptions = ref(null);
3274
- const modelValueUpdated = (e) => {
3275
- emit('clearValidationErrors');
3276
- emit('update:modelValue',inputModel.value);
3277
- };
3257
+
3278
3258
  onMounted(()=>{
3279
- props.modelValue && (inputModel.value = props.modelValue);
3280
3259
  const options = props.data ?? props.options;
3281
3260
  if(options){
3282
3261
  selectOptions.value = options.map(item=>{
@@ -3298,18 +3277,10 @@ onMounted(()=>{
3298
3277
  });
3299
3278
  }
3300
3279
  });
3301
- watch(()=>props.modelValue, (newValue)=>{
3302
- if(newValue) {
3303
- inputModel.value = newValue;
3304
- }
3305
- });
3306
3280
 
3307
3281
  return (_ctx, _cache) => {
3308
3282
  return withDirectives((openBlock(), createElementBlock("select", {
3309
- "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event)),
3310
- onChange: modelValueUpdated,
3311
- onKeydown: modelValueUpdated,
3312
- onUpdated: modelValueUpdated
3283
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event))
3313
3284
  }, [
3314
3285
  (openBlock(true), createElementBlock(Fragment, null, renderList(selectOptions.value, (option) => {
3315
3286
  return (openBlock(), createElementBlock("option", {
@@ -3317,7 +3288,7 @@ return (_ctx, _cache) => {
3317
3288
  value: option.id
3318
3289
  }, toDisplayString(option.name), 9 /* TEXT, PROPS */, _hoisted_1$m))
3319
3290
  }), 128 /* KEYED_FRAGMENT */))
3320
- ], 544 /* NEED_HYDRATION, NEED_PATCH */)), [
3291
+ ], 512 /* NEED_PATCH */)), [
3321
3292
  [vModelSelect, inputModel.value]
3322
3293
  ])
3323
3294
  }
@@ -3335,25 +3306,21 @@ var script$s = {
3335
3306
 
3336
3307
  const props = __props;
3337
3308
  const emit = __emit;
3338
- const inputModel = ref(null);
3339
3309
 
3340
- const modelValueUpdated = (e) => {
3341
- emit('clearValidationErrors');
3342
- emit('update:modelValue',inputModel.value);
3343
- };
3344
- onMounted(()=>{
3345
- props.modelValue && (inputModel.value = props.modelValue);
3310
+ // Use computed for proper two-way binding
3311
+ const inputModel = computed({
3312
+ get: () => props.modelValue,
3313
+ set: (value) => {
3314
+ emit('clearValidationErrors');
3315
+ emit('update:modelValue', value);
3316
+ }
3346
3317
  });
3347
3318
 
3348
-
3349
3319
  return (_ctx, _cache) => {
3350
3320
  return withDirectives((openBlock(), createElementBlock("input", {
3351
3321
  type: "password",
3352
- "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event)),
3353
- onChange: modelValueUpdated,
3354
- onKeydown: modelValueUpdated,
3355
- onUpdated: modelValueUpdated
3356
- }, null, 544 /* NEED_HYDRATION, NEED_PATCH */)), [
3322
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event))
3323
+ }, null, 512 /* NEED_PATCH */)), [
3357
3324
  [vModelText, inputModel.value]
3358
3325
  ])
3359
3326
  }
@@ -3371,31 +3338,21 @@ var script$r = {
3371
3338
 
3372
3339
  const props = __props;
3373
3340
  const emit = __emit;
3374
- const inputModel = ref(null);
3375
3341
 
3376
- const modelValueUpdated = (e) => {
3377
- emit('clearValidationErrors');
3378
- emit('update:modelValue',inputModel.value);
3379
- };
3380
- onMounted(()=>{
3381
- props.modelValue && (inputModel.value = props.modelValue);
3382
- });
3383
-
3384
- watch(()=>props.modelValue, (newValue)=>{
3385
- if(newValue) {
3386
- inputModel.value = newValue;
3342
+ // Use computed for proper two-way binding
3343
+ const inputModel = computed({
3344
+ get: () => props.modelValue,
3345
+ set: (value) => {
3346
+ emit('clearValidationErrors');
3347
+ emit('update:modelValue', value);
3387
3348
  }
3388
3349
  });
3389
3350
 
3390
-
3391
3351
  return (_ctx, _cache) => {
3392
3352
  return withDirectives((openBlock(), createElementBlock("input", {
3393
3353
  type: "datetime-local",
3394
- "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event)),
3395
- onChange: modelValueUpdated,
3396
- onKeydown: modelValueUpdated,
3397
- onUpdated: modelValueUpdated
3398
- }, null, 544 /* NEED_HYDRATION, NEED_PATCH */)), [
3354
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((inputModel).value = $event))
3355
+ }, null, 512 /* NEED_PATCH */)), [
3399
3356
  [vModelText, inputModel.value]
3400
3357
  ])
3401
3358
  }
@@ -3654,6 +3611,8 @@ const submitBtn = ref(false);
3654
3611
  const validationErrors = ref({});
3655
3612
  const formError = ref(null);
3656
3613
  const submitBtnWidth = ref(null);
3614
+ const isDirty = ref(false);
3615
+ const isSynchronizing = ref(false);
3657
3616
 
3658
3617
  // Helper functions
3659
3618
  const closeModal = () => {
@@ -3697,10 +3656,19 @@ const getFormData = () => {
3697
3656
  return data
3698
3657
  };
3699
3658
 
3700
- const fieldChanged = field => {
3659
+ const fieldChanged = (field, value) => {
3660
+ if (isSynchronizing.value) return
3661
+ isDirty.value = true;
3701
3662
  delete validationErrors.value[field];
3663
+
3664
+ // Find the field and update its value if it was passed
3665
+ const fieldObj = formFields.value.find(f => f.field === field);
3666
+ if (fieldObj && value !== undefined) {
3667
+ fieldObj.value = value;
3668
+ }
3669
+
3702
3670
  const data = getFormData();
3703
- const fieldValue = formFields.value.find(f => f.field === field)?.value;
3671
+ const fieldValue = fieldObj?.value;
3704
3672
  setTimeout(() => {
3705
3673
  emit('fieldChanged', field, fieldValue, data);
3706
3674
  }, 300);
@@ -3785,6 +3753,7 @@ const handleSuccessRequest = res => {
3785
3753
  if (!props.retainDataAfterSubmission) {
3786
3754
  formFields.value.forEach(field => field.value = null);
3787
3755
  }
3756
+ isDirty.value = false;
3788
3757
 
3789
3758
  if (!props.retainModal) {
3790
3759
  closeModal();
@@ -3830,19 +3799,34 @@ const handleFailedRequest = reason => {
3830
3799
  emit('formError', reason);
3831
3800
  };
3832
3801
  const setExistingData = (existingData) => {
3802
+ // Don't sync if no data provided
3833
3803
  if (!existingData) return
3834
-
3835
- formFields.value = formFields.value.map(field => {
3836
- if (existingData[field.field] !== undefined) {
3837
- return { ...field, value: existingData[field.field] }
3804
+
3805
+ // Don't sync if user has made changes to the form
3806
+ if (isDirty.value) return
3807
+
3808
+ isSynchronizing.value = true;
3809
+ const keys = Object.keys(existingData);
3810
+
3811
+ keys.forEach(k => {
3812
+ const field = formFields.value.find(f => f.field === k);
3813
+ if (field) {
3814
+ field.value = existingData[k];
3838
3815
  }
3839
- return field
3840
3816
  });
3817
+
3818
+ setTimeout(() => {
3819
+ isSynchronizing.value = false;
3820
+ }, 100);
3841
3821
  };
3842
3822
 
3843
- watch(() => props.currentData, (newData) => {
3844
- setExistingData(newData);
3845
- });
3823
+ watch(() => props.currentData, (newData, oldData) => {
3824
+ // Only sync if form is pristine (not dirty) OR if this is a completely new object reference
3825
+ // This prevents reactive updates to currentData from overwriting user input
3826
+ if (!isDirty.value || !oldData) {
3827
+ setExistingData(newData);
3828
+ }
3829
+ }, { deep: true });
3846
3830
 
3847
3831
  const currentStep = ref(0);
3848
3832
  const formSteps = ref([]);
@@ -3890,7 +3874,11 @@ onMounted(() => {
3890
3874
  type: 'hidden'
3891
3875
  });
3892
3876
 
3877
+ isSynchronizing.value = true;
3893
3878
  setExistingData(props.currentData);
3879
+ setTimeout(() => {
3880
+ isSynchronizing.value = false;
3881
+ }, 200);
3894
3882
 
3895
3883
  // Initialize steps
3896
3884
  if (!props.steps || props.steps.length === 0) {
@@ -4008,11 +3996,10 @@ return (_ctx, _cache) => {
4008
3996
  : createCommentVNode("v-if", true),
4009
3997
  (openBlock(), createBlock(resolveDynamicComponent(getFieldComponent(field)), mergeProps({ ref_for: true }, getComponentProps(field), {
4010
3998
  isInvalid: typeof validationErrors.value[field.field] !== 'undefined',
4011
- onClick: $event => (fieldChanged(field.field)),
4012
- "onUpdate:modelValue": [$event => (fieldChanged(field.field)), $event => ((field.value) = $event)],
3999
+ "onUpdate:modelValue": [val => fieldChanged(field.field, val), $event => ((field.value) = $event)],
4013
4000
  modelValue: field.value,
4014
4001
  class: getComponentClass(field.field)
4015
- }), null, 16 /* FULL_PROPS */, ["isInvalid", "onClick", "onUpdate:modelValue", "modelValue", "class"])),
4002
+ }), null, 16 /* FULL_PROPS */, ["isInvalid", "onUpdate:modelValue", "modelValue", "class"])),
4016
4003
  (unref(isFloating) && field.label)
4017
4004
  ? (openBlock(), createElementBlock("label", {
4018
4005
  key: 1,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iankibetsh/shframework",
3
- "version": "5.7.7",
3
+ "version": "5.7.8",
4
4
  "description": "Vue library for handling laravel backend",
5
5
  "repository": {
6
6
  "type": "git",