@omnitend/dashboard-for-laravel 0.16.3 → 0.17.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.
@@ -1 +1,53 @@
1
- export { useToast } from 'bootstrap-vue-next';
1
+ import { isRef } from "vue";
2
+ import { useToast as useBvnToast } from "bootstrap-vue-next";
3
+ import type {
4
+ OrchestratorCreateOptions,
5
+ ToastOrchestratorCreateParam,
6
+ } from "bootstrap-vue-next";
7
+
8
+ // Bootstrap Vue Next maps a toast's `variant` prop straight to Bootstrap's
9
+ // `.text-bg-{variant}` utility class, which sets background/text colour
10
+ // `!important` (all Bootstrap utilities are `!important` by design) — so
11
+ // restyling it can only ever fight that with `!important` too. The variants
12
+ // this theme restyles (see theme.scss) are instead applied as a `toast-{variant}`
13
+ // class, driving Bootstrap's own `--bs-toast-*` variables cleanly. An
14
+ // unrecognised variant (e.g. "primary", "dark", or none) falls through to
15
+ // BVN's default `.text-bg-*` styling unchanged.
16
+ const THEMED_TOAST_VARIANTS = new Set(["success", "danger", "warning", "info"]);
17
+
18
+ function themeToastParam(param: Record<string, unknown>): Record<string, unknown> {
19
+ const variant = param.variant as string | null | undefined;
20
+ if (!variant || !THEMED_TOAST_VARIANTS.has(variant)) return param;
21
+
22
+ const { variant: _variant, toastClass, ...rest } = param;
23
+ return {
24
+ ...rest,
25
+ toastClass: [toastClass, `toast-${variant}`],
26
+ };
27
+ }
28
+
29
+ /**
30
+ * Thin wrapper around Bootstrap Vue Next's `useToast()`. Public API is
31
+ * identical (`create({ title, body, variant })`, `show(...)`) — a themed
32
+ * `variant` is translated internally into a `toast-{variant}` class instead
33
+ * of being passed through to BVN, so it's styled via `--bs-toast-*` variables
34
+ * (see theme.scss) rather than an `!important`-overridden utility class.
35
+ */
36
+ // A ref-wrapped param (rare — most callers pass a plain object) is forwarded
37
+ // untouched: reading through it once here would snapshot every field, losing
38
+ // reactivity for the rest of the toast, not just its variant.
39
+ function maybeThemeParam(obj?: ToastOrchestratorCreateParam): ToastOrchestratorCreateParam | undefined {
40
+ if (!obj || isRef(obj)) return obj;
41
+ return themeToastParam(obj as Record<string, unknown>) as unknown as ToastOrchestratorCreateParam;
42
+ }
43
+
44
+ export function useToast(): ReturnType<typeof useBvnToast> {
45
+ const toast = useBvnToast();
46
+
47
+ return {
48
+ ...toast,
49
+ create: (obj?: ToastOrchestratorCreateParam, options?: OrchestratorCreateOptions) =>
50
+ toast.create(maybeThemeParam(obj), options),
51
+ show: (obj?: ToastOrchestratorCreateParam) => toast.show(maybeThemeParam(obj)),
52
+ };
53
+ }
@@ -61,6 +61,23 @@ export interface FieldOption extends Record<string, unknown> {
61
61
  */
62
62
  export type OptionsLoader = (model: any) => Promise<FieldOption[]>;
63
63
 
64
+ /**
65
+ * Label column width for horizontal layout, mirroring Bootstrap Vue Next's
66
+ * `BFormGroup` `labelCols`/`labelCols*` props: either a single width applied
67
+ * at all breakpoints, or a per-breakpoint object (omitted breakpoints fall
68
+ * back to BFormGroup's own defaults, which is how "collapse to vertical
69
+ * below a breakpoint" comes for free — e.g. `{ md: 3 }` stacks below `md`).
70
+ *
71
+ * Deliberately excludes `boolean` (which BFormGroup's own `labelCols` prop
72
+ * accepts): Vue's type-based `defineProps` auto-defaults an omitted prop to
73
+ * `false` (not `undefined`) whenever its declared type includes `boolean`,
74
+ * which would silently break the `field.labelCols ?? formLabelCols ?? 3`
75
+ * fallback chain used to resolve this value.
76
+ */
77
+ export type LabelCols =
78
+ | number
79
+ | { sm?: number; md?: number; lg?: number; xl?: number };
80
+
64
81
  /**
65
82
  * Field definition shared by every form renderer.
66
83
  *
@@ -172,10 +189,24 @@ export interface FieldDefinition {
172
189
 
173
190
  /**
174
191
  * Render the field full-width with no label wrapper, delegating its
175
- * content to the `#span(<key>)` slot. Useful for custom blocks.
192
+ * content to the `#span(<key>)` slot. Useful for custom blocks. Also
193
+ * doubles as the "fill both columns" escape hatch in horizontal layout —
194
+ * a span field always bypasses the label/content column split.
176
195
  */
177
196
  span?: boolean;
178
197
 
198
+ /**
199
+ * Per-field override of DXForm's `layout` prop ("vertical" | "horizontal").
200
+ * Falls back to the form-level `layout` when omitted.
201
+ */
202
+ layout?: "vertical" | "horizontal";
203
+
204
+ /**
205
+ * Per-field override of DXForm's `labelCols` prop, for horizontal
206
+ * layout. Falls back to the form-level `labelCols` when omitted.
207
+ */
208
+ labelCols?: LabelCols;
209
+
179
210
  /**
180
211
  * Component rendered for `type: "component"` fields. Receives
181
212
  * `modelValue`, `field`, `model` props and emits `update:modelValue`.
@@ -199,6 +230,26 @@ export interface FieldDefinition {
199
230
  minItems?: number;
200
231
  maxItems?: number;
201
232
 
233
+ /**
234
+ * For `repeater` fields: `"cards"` (default) stacks each row as its own
235
+ * card with sub-fields listed vertically — best for rows with several
236
+ * or complex sub-fields. `"table"` renders one row per item with
237
+ * sub-fields as columns — far more compact for simple child-row lists
238
+ * (e.g. 2-3 short sub-fields). Named `repeaterLayout` (not `layout`) to
239
+ * avoid colliding with the unrelated form-level `layout` prop
240
+ * ("vertical" | "horizontal") every field type accepts.
241
+ */
242
+ repeaterLayout?: "cards" | "table";
243
+
244
+ /**
245
+ * For `repeater` fields in `cards` layout: show each row's 1-based
246
+ * position (e.g. "1", "2") next to its Remove button. Off by default —
247
+ * only meaningful once a consumer explicitly wants it (e.g. rows the
248
+ * user thinks of as numbered/ordered); most repeaters don't need it.
249
+ * Not applicable to `table` layout, which has no equivalent column.
250
+ */
251
+ showRowIndex?: boolean;
252
+
202
253
  /**
203
254
  * For `repeater` fields backed by an upsert-children API contract (rows
204
255
  * carrying a persisted `id` are only deleted server-side when submitted