@omnitend/dashboard-for-laravel 0.43.0 → 0.44.0

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 (38) hide show
  1. package/dist/components/base/DFormSelect.vue.d.ts +1 -1
  2. package/dist/components/extended/DXChoiceField.vue.d.ts +3 -3
  3. package/dist/components/extended/DXForm.vue.d.ts +66 -1
  4. package/dist/components/extended/DXFormErrorSummary.vue.d.ts +70 -0
  5. package/dist/components/extended/DXFormField.vue.d.ts +3 -0
  6. package/dist/components/extended/DXTable.vue.d.ts +20 -0
  7. package/dist/components/extended/DXTableEditorModal.vue.d.ts +14 -10
  8. package/dist/composables/useAsyncOptions.d.ts +14 -1
  9. package/dist/composables/useForm.d.ts +26 -0
  10. package/dist/dashboard-for-laravel.js +13374 -12823
  11. package/dist/dashboard-for-laravel.js.map +1 -1
  12. package/dist/dashboard-for-laravel.umd.cjs +8 -8
  13. package/dist/dashboard-for-laravel.umd.cjs.map +1 -1
  14. package/dist/index.d.ts +5 -1
  15. package/dist/style.css +1 -1
  16. package/dist/types/index.d.ts +12 -0
  17. package/dist/utils/formErrorTargets.d.ts +86 -0
  18. package/docs/public/api-reference.json +146 -6
  19. package/docs/public/docs-map.md +3 -2
  20. package/docs/public/llms.txt +3 -2
  21. package/package.json +9 -8
  22. package/resources/css/theme.scss +56 -0
  23. package/resources/js/components/base/DFormSelect.vue +5 -2
  24. package/resources/js/components/extended/DXChoiceField.vue +42 -26
  25. package/resources/js/components/extended/DXField.vue +15 -9
  26. package/resources/js/components/extended/DXForm.vue +676 -28
  27. package/resources/js/components/extended/DXFormErrorSummary.vue +232 -0
  28. package/resources/js/components/extended/DXFormField.vue +11 -2
  29. package/resources/js/components/extended/DXRepeater.vue +30 -4
  30. package/resources/js/components/extended/DXTable.vue +36 -4
  31. package/resources/js/components/extended/DXTableEditorModal.vue +29 -1
  32. package/resources/js/composables/useAsyncOptions.ts +30 -5
  33. package/resources/js/composables/useForm.ts +196 -18
  34. package/resources/js/composables/useResourceEditor.ts +140 -107
  35. package/resources/js/index.ts +15 -0
  36. package/resources/js/types/index.ts +13 -0
  37. package/resources/js/utils/formErrorTargets.ts +317 -0
  38. package/scripts/mcp-server.mjs +58 -6
@@ -13,7 +13,10 @@
13
13
  <template>
14
14
  <!-- Full-width span field: delegate entirely to the #span slot, bypassing
15
15
  the label and built-in control (and the shell). -->
16
- <div v-if="field.span" :class="field.class || 'mb-3'">
16
+ <!-- `data-dx-field-key` (the field's data path: `name`, or
17
+ `lines.0.price` inside a repeater) is how DXForm finds a field to
18
+ scroll to and focus after a failed submit (#194). -->
19
+ <div v-if="field.span" :class="field.class || 'mb-3'" :data-dx-field-key="valuePath">
17
20
  <!--
18
21
  @slot Replaces the entire field with custom full-width content when `field.span` is set, bypassing the label and built-in control.
19
22
  @binding {FieldDefinition} field The field definition being rendered.
@@ -34,6 +37,7 @@
34
37
  control that goes inside is chosen by field.type in the default slot. -->
35
38
  <DXFieldShell
36
39
  v-else
40
+ :data-dx-field-key="valuePath"
37
41
  :field="field"
38
42
  :form="form"
39
43
  :error-key="errorKey"
@@ -264,7 +268,7 @@
264
268
  :state="fieldState"
265
269
  :disabled="isDisabled || isReadonly || isPlaintext"
266
270
  :control-props="controlPropsWithGuards"
267
- :options-ready="searchableOptionsReady"
271
+ :options-pending="optionsPending"
268
272
  @update:model-value="setValue"
269
273
  />
270
274
 
@@ -780,12 +784,6 @@ const isPlaintext = computed(() => resolveMaybe(props.field.plaintext) ?? false)
780
784
 
781
785
  const passwordRevealed = ref(false);
782
786
 
783
- // See the template: the searchable select can't render before its options
784
- // resolve, or it shows the raw id instead of the option's label.
785
- const searchableOptionsReady = computed(
786
- () => !props.field.optionsLoader || loadedOptions.value !== null,
787
- );
788
-
789
787
  const isRevealablePassword = computed(
790
788
  () =>
791
789
  props.field.type === "password" &&
@@ -856,7 +854,15 @@ const datalistId = useId();
856
854
 
857
855
  // ————————————————— async options
858
856
 
859
- const { loadedOptions } = useAsyncOptions(() => props.field, effectiveModel);
857
+ const { loadedOptions, firstLoadSettled } = useAsyncOptions(
858
+ () => props.field,
859
+ effectiveModel,
860
+ );
861
+
862
+ // The first load has not settled: nothing to label the value with yet. Once
863
+ // it has (even by failing, which leaves the static options), a reload never
864
+ // makes the field pending again: it keeps what it already shows.
865
+ const optionsPending = computed(() => !firstLoadSettled.value);
860
866
 
861
867
  const resolvedOptions = computed<FieldOption[] | undefined>(
862
868
  () => loadedOptions.value ?? props.field.options,