@omnitend/dashboard-for-laravel 0.41.1 → 0.42.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.
- package/README.md +2 -1
- package/dist/assets/MavenPro-Bold-35b16f06.woff2 +0 -0
- package/dist/assets/MavenPro-Medium-febc8674.woff2 +0 -0
- package/dist/assets/MavenPro-Regular-aee3df9e.woff2 +0 -0
- package/dist/assets/MavenPro-SemiBold-c555dbfa.woff2 +0 -0
- package/dist/assets/Poppins-Medium-5800fa57.woff2 +0 -0
- package/dist/assets/Poppins-SemiBold-94a36267.woff2 +0 -0
- package/dist/charts.js +148 -130
- package/dist/charts.js.map +1 -1
- package/dist/charts.umd.cjs +1 -1
- package/dist/charts.umd.cjs.map +1 -1
- package/dist/components/base/DModal.vue.d.ts +26 -2
- package/dist/components/charts/chartTheme.d.ts +14 -2
- package/dist/components/extended/DXField.vue.d.ts +16 -5
- package/dist/components/extended/DXForm.vue.d.ts +25 -9
- package/dist/components/extended/DXLoading.vue.d.ts +9 -0
- package/dist/components/extended/DXModalActions.vue.d.ts +12 -0
- package/dist/components/extended/DXNumberStepper.vue.d.ts +33 -0
- package/dist/components/extended/DXSaveButton.vue.d.ts +38 -0
- package/dist/components/extended/DXSwitch.vue.d.ts +1 -1
- package/dist/components/extended/DXTable.vue.d.ts +8 -2
- package/dist/composables/useForm.d.ts +7 -0
- package/dist/dashboard-for-laravel.js +9547 -9246
- package/dist/dashboard-for-laravel.js.map +1 -1
- package/dist/dashboard-for-laravel.umd.cjs +7 -7
- package/dist/dashboard-for-laravel.umd.cjs.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/style.css +2 -2
- package/dist/types/index.d.ts +20 -3
- package/docs/public/api-reference.json +219 -17
- package/docs/public/docs-map.md +4 -2
- package/docs/public/llms.txt +7 -2
- package/package.json +1 -1
- package/resources/css/theme.scss +524 -103
- package/resources/fonts/maven-pro/MavenPro-Bold.woff2 +0 -0
- package/resources/fonts/maven-pro/MavenPro-Medium.woff2 +0 -0
- package/resources/fonts/maven-pro/MavenPro-Regular.woff2 +0 -0
- package/resources/fonts/maven-pro/MavenPro-SemiBold.woff2 +0 -0
- package/resources/fonts/maven-pro/OFL.txt +93 -0
- package/resources/fonts/poppins/OFL.txt +93 -0
- package/resources/fonts/poppins/Poppins-Medium.woff2 +0 -0
- package/resources/fonts/poppins/Poppins-SemiBold.woff2 +0 -0
- package/resources/js/components/base/DModal.vue +13 -2
- package/resources/js/components/charts/DXBarChart.vue +2 -1
- package/resources/js/components/charts/DXDoughnutChart.vue +2 -1
- package/resources/js/components/charts/DXLineChart.vue +2 -1
- package/resources/js/components/charts/chartTheme.ts +68 -21
- package/resources/js/components/extended/DXDashboard.vue +4 -2
- package/resources/js/components/extended/DXDashboardSidebar.vue +52 -20
- package/resources/js/components/extended/DXField.vue +59 -28
- package/resources/js/components/extended/DXForm.vue +122 -21
- package/resources/js/components/extended/DXLoading.vue +47 -0
- package/resources/js/components/extended/DXModalActions.vue +13 -0
- package/resources/js/components/extended/DXNumberStepper.vue +243 -0
- package/resources/js/components/extended/DXSaveButton.vue +82 -0
- package/resources/js/components/extended/DXSwitch.vue +8 -5
- package/resources/js/components/extended/DXTable.vue +58 -22
- package/resources/js/components/extended/DXTablePagination.vue +1 -1
- package/resources/js/composables/useForm.ts +11 -0
- package/resources/js/composables/useToast.ts +1 -1
- package/resources/js/index.ts +5 -0
- package/resources/js/types/index.ts +21 -3
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
<DFormInput
|
|
101
101
|
v-if="field.filter === 'text'"
|
|
102
102
|
:model-value="effectiveFilters[filterKeyFor(field)] || ''"
|
|
103
|
-
:placeholder="field.filterPlaceholder ||
|
|
103
|
+
:placeholder="field.filterPlaceholder || `${field.label || field.key}…`"
|
|
104
104
|
size="sm"
|
|
105
105
|
@update:model-value="handleFilterChange(filterKeyFor(field), $event as string)"
|
|
106
106
|
/>
|
|
@@ -149,7 +149,7 @@
|
|
|
149
149
|
<DFormInput
|
|
150
150
|
v-else-if="field.filter === 'number'"
|
|
151
151
|
:model-value="effectiveFilters[filterKeyFor(field)] || ''"
|
|
152
|
-
:placeholder="field.filterPlaceholder ||
|
|
152
|
+
:placeholder="field.filterPlaceholder || `${field.label || field.key}…`"
|
|
153
153
|
type="number"
|
|
154
154
|
size="sm"
|
|
155
155
|
@update:model-value="handleFilterChange(filterKeyFor(field), $event as string)"
|
|
@@ -174,7 +174,10 @@
|
|
|
174
174
|
<template v-for="field in fields" :key="`head-${field.key}`" #[`head(${field.key})`]="{ label }">
|
|
175
175
|
<div class="d-flex align-items-center justify-content-between gap-2">
|
|
176
176
|
<div class="flex-grow-1">
|
|
177
|
-
<div class="fw-semibold">
|
|
177
|
+
<div class="fw-semibold">
|
|
178
|
+
<DXFieldLabel v-if="field.info" :label="headerLabel(field, label)" :info="field.info" />
|
|
179
|
+
<template v-else>{{ headerLabel(field, label) }}</template>
|
|
180
|
+
</div>
|
|
178
181
|
<small v-if="field.hint" class="text-muted d-block" style="font-weight: normal;">{{ field.hint }}</small>
|
|
179
182
|
</div>
|
|
180
183
|
|
|
@@ -326,6 +329,7 @@ import DTable from "../base/DTable.vue";
|
|
|
326
329
|
import DFormInput from "../base/DFormInput.vue";
|
|
327
330
|
import DFormSelect from "../base/DFormSelect.vue";
|
|
328
331
|
import DAutocomplete from "../base/DAutocomplete.vue";
|
|
332
|
+
import DXFieldLabel from "./DXFieldLabel.vue";
|
|
329
333
|
import DButton from "../base/DButton.vue";
|
|
330
334
|
import DXTablePagination from "./DXTablePagination.vue";
|
|
331
335
|
import DXTableEditorModal from "./DXTableEditorModal.vue";
|
|
@@ -404,6 +408,8 @@ export interface TableField {
|
|
|
404
408
|
filterAllText?: string;
|
|
405
409
|
sortable?: boolean;
|
|
406
410
|
hint?: string;
|
|
411
|
+
/** Help revealed from a focusable info icon beside the column label. */
|
|
412
|
+
info?: string;
|
|
407
413
|
/**
|
|
408
414
|
* The inline filter control for this column, or `false`/omit for none. See
|
|
409
415
|
* `FilterType`. `'select'` (typeahead) and `'select-native'` (plain
|
|
@@ -571,7 +577,10 @@ export interface Props<TItem = any> {
|
|
|
571
577
|
/** Error message */
|
|
572
578
|
error?: string | null;
|
|
573
579
|
|
|
574
|
-
/**
|
|
580
|
+
/**
|
|
581
|
+
* Pagination data (Inertia mode). Omit it on a plain `items` table and the
|
|
582
|
+
* footer counts the rows given as one page.
|
|
583
|
+
*/
|
|
575
584
|
pagination?: PaginationData;
|
|
576
585
|
|
|
577
586
|
/** Show pagination controls */
|
|
@@ -679,7 +688,8 @@ export interface Props<TItem = any> {
|
|
|
679
688
|
/**
|
|
680
689
|
* Label column width for the edit modal's horizontal layout, forwarded to
|
|
681
690
|
* `DXForm`'s `labelCols` (a single width or a per-breakpoint object). Only
|
|
682
|
-
* meaningful when `editLayout` is "horizontal".
|
|
691
|
+
* meaningful when `editLayout` is "horizontal". Omitted: DXForm's default
|
|
692
|
+
* 45% label column.
|
|
683
693
|
*/
|
|
684
694
|
editLabelCols?: LabelCols;
|
|
685
695
|
|
|
@@ -983,8 +993,11 @@ if (
|
|
|
983
993
|
console.warn('[DXTable] clientSide mode ignores provider, apiUrl and inertiaUrl props. Data is processed locally from items.');
|
|
984
994
|
}
|
|
985
995
|
|
|
986
|
-
//
|
|
987
|
-
|
|
996
|
+
// Effective busy state. Provider mode: `busy` (two-way with BTable's own
|
|
997
|
+
// loading). Items and client-side modes: `busy`, the documented prop, or the
|
|
998
|
+
// deprecated `loading`; these modes used to read only `loading`, so a page
|
|
999
|
+
// passing `:busy` showed the empty text while its rows were still loading.
|
|
1000
|
+
const effectiveBusy = computed(() => isProviderMode.value ? props.busy : props.busy || props.loading);
|
|
988
1001
|
|
|
989
1002
|
/*
|
|
990
1003
|
* `perPage`, `sortBy` and `filters` are dual-purpose: with a `v-model` they are
|
|
@@ -1767,6 +1780,7 @@ watch(clientSideLastPage, (lastPage) => {
|
|
|
1767
1780
|
// Client-side paginated items (final output)
|
|
1768
1781
|
const clientSidePaginatedItems = computed<T[]>(() => {
|
|
1769
1782
|
if (!isClientSideMode.value) return [];
|
|
1783
|
+
if (!props.showPagination) return clientSideSortedItems.value;
|
|
1770
1784
|
|
|
1771
1785
|
const perPage = effectivePerPage.value;
|
|
1772
1786
|
const start = (clientSidePage.value - 1) * perPage;
|
|
@@ -1783,19 +1797,19 @@ const clientSidePagination = computed<PaginationData>(() => {
|
|
|
1783
1797
|
const lastPage = clientSideLastPage.value;
|
|
1784
1798
|
|
|
1785
1799
|
// Same clamped page the slice uses — see `clientSidePage` (#118).
|
|
1786
|
-
const validPage = clientSidePage.value;
|
|
1800
|
+
const validPage = props.showPagination ? clientSidePage.value : 1;
|
|
1787
1801
|
|
|
1788
|
-
const from = total > 0 ? (validPage - 1) * perPage + 1 : 0;
|
|
1789
|
-
const to = Math.min(validPage * perPage, total);
|
|
1802
|
+
const from = total > 0 ? (props.showPagination ? (validPage - 1) * perPage + 1 : 1) : 0;
|
|
1803
|
+
const to = props.showPagination ? Math.min(validPage * perPage, total) : total;
|
|
1790
1804
|
|
|
1791
1805
|
return {
|
|
1792
1806
|
current_page: validPage,
|
|
1793
|
-
per_page: perPage,
|
|
1807
|
+
per_page: props.showPagination ? perPage : Math.max(1, total),
|
|
1794
1808
|
total,
|
|
1795
1809
|
total_unfiltered: totalUnfiltered !== total ? totalUnfiltered : undefined,
|
|
1796
1810
|
from,
|
|
1797
1811
|
to,
|
|
1798
|
-
last_page: lastPage,
|
|
1812
|
+
last_page: props.showPagination ? lastPage : 1,
|
|
1799
1813
|
};
|
|
1800
1814
|
});
|
|
1801
1815
|
|
|
@@ -1822,7 +1836,7 @@ const handleClientSidePageChange = (page: number) => {
|
|
|
1822
1836
|
// Computed: determine if per-page selector should be shown
|
|
1823
1837
|
// Hide it when total items is less than the smallest page size option
|
|
1824
1838
|
const shouldShowPerPageSelector = computed(() => {
|
|
1825
|
-
if (!props.showPerPageSelector) return false;
|
|
1839
|
+
if (!props.showPagination || !props.showPerPageSelector) return false;
|
|
1826
1840
|
|
|
1827
1841
|
const smallestOption = Math.min(...props.perPageOptions);
|
|
1828
1842
|
const total = isClientSideMode.value
|
|
@@ -2016,9 +2030,10 @@ const handleApiPageChange = (page: number) => {
|
|
|
2016
2030
|
* `currentPage` and `perPage`; `busy` is the raw prop (two-way with BTable's
|
|
2017
2031
|
* provider loading via `@update:busy`).
|
|
2018
2032
|
* - client-side: rows are pre-sliced by `clientSidePaginatedItems`, and local
|
|
2019
|
-
* sorting is off (we sort in `clientSideSortedItems`)
|
|
2033
|
+
* sorting is off (we sort in `clientSideSortedItems`); `busy` is
|
|
2034
|
+
* `effectiveBusy`.
|
|
2020
2035
|
* - inertia: server-paginated `items`, local sorting off, `busy` is
|
|
2021
|
-
* `effectiveBusy` (the `loading`
|
|
2036
|
+
* `effectiveBusy` (`busy` or the deprecated `loading` in this mode).
|
|
2022
2037
|
*
|
|
2023
2038
|
* A key absent from the returned object is simply not bound, which is what the
|
|
2024
2039
|
* original blocks did (e.g. non-provider modes never set `provider`/`currentPage`,
|
|
@@ -2034,7 +2049,7 @@ const tableModeBindings = computed<Record<string, unknown>>(() => {
|
|
|
2034
2049
|
};
|
|
2035
2050
|
}
|
|
2036
2051
|
if (isClientSideMode.value) {
|
|
2037
|
-
return { items: clientSidePaginatedItems.value, noLocalSorting: true };
|
|
2052
|
+
return { items: clientSidePaginatedItems.value, noLocalSorting: true, busy: effectiveBusy.value };
|
|
2038
2053
|
}
|
|
2039
2054
|
// inertia
|
|
2040
2055
|
return { items: resolvedItems.value, noLocalSorting: true, busy: effectiveBusy.value };
|
|
@@ -2043,13 +2058,32 @@ const tableModeBindings = computed<Record<string, unknown>>(() => {
|
|
|
2043
2058
|
/*
|
|
2044
2059
|
* The pagination metadata the single footer renders, by mode (#123). Null means
|
|
2045
2060
|
* no footer: only provider mode has that case (a custom provider with no
|
|
2046
|
-
* `pagination` prop). Client-side always
|
|
2047
|
-
*
|
|
2048
|
-
*
|
|
2061
|
+
* `pagination` prop). Client-side and inertia always render a footer.
|
|
2062
|
+
*
|
|
2063
|
+
* Inertia mode is also what a plain `:items` table with no `pagination` lands
|
|
2064
|
+
* in. Its footer read the `withDefaults` placeholder (`total: 0`), so two
|
|
2065
|
+
* rendered rows sat above "0 items.". With no `pagination` passed, the rows
|
|
2066
|
+
* given ARE the whole set: describe them as one page.
|
|
2049
2067
|
*/
|
|
2068
|
+
const unpaginatedItemsPagination = computed<PaginationData>(() => {
|
|
2069
|
+
const itemCount = resolvedItems.value?.length ?? 0;
|
|
2070
|
+
return {
|
|
2071
|
+
current_page: 1,
|
|
2072
|
+
// One page holding every row, so the pager (shown only when
|
|
2073
|
+
// total > per_page) never appears. Floor of 1 keeps the page
|
|
2074
|
+
// maths away from a zero divisor.
|
|
2075
|
+
per_page: Math.max(itemCount, 1),
|
|
2076
|
+
total: itemCount,
|
|
2077
|
+
from: itemCount > 0 ? 1 : 0,
|
|
2078
|
+
to: itemCount,
|
|
2079
|
+
};
|
|
2080
|
+
});
|
|
2081
|
+
|
|
2050
2082
|
const activePagination = computed<PaginationData | null>(() => {
|
|
2051
2083
|
if (isClientSideMode.value) return clientSidePagination.value;
|
|
2052
|
-
if (isInertiaMode.value)
|
|
2084
|
+
if (isInertiaMode.value) {
|
|
2085
|
+
return paginationWasProvided ? props.pagination : unpaginatedItemsPagination.value;
|
|
2086
|
+
}
|
|
2053
2087
|
if (isProviderMode.value) return providerPagination.value;
|
|
2054
2088
|
return null;
|
|
2055
2089
|
});
|
|
@@ -2340,7 +2374,9 @@ const tableSlotSignature = (slots: Record<string, unknown>): string => {
|
|
|
2340
2374
|
// three data modes from one place.
|
|
2341
2375
|
const tablePassthroughProps = computed(() => ({
|
|
2342
2376
|
footClone: props.footClone,
|
|
2343
|
-
|
|
2377
|
+
// No empty text while rows are loading: "No … found" during a load reads as
|
|
2378
|
+
// "there is no data". Provider mode is unchanged by this.
|
|
2379
|
+
showEmpty: props.showEmpty && (isProviderMode.value || effectiveBusy.value === false),
|
|
2344
2380
|
emptyText:
|
|
2345
2381
|
props.emptyText ??
|
|
2346
2382
|
(hasActiveFilters.value
|
|
@@ -2450,7 +2486,7 @@ defineExpose({
|
|
|
2450
2486
|
}
|
|
2451
2487
|
|
|
2452
2488
|
/* Muted header titles (#157): in a data table the CONTENT is what matters —
|
|
2453
|
-
near-black bold headers compete with it. Grey (
|
|
2489
|
+
near-black bold headers compete with it. Grey (weight 500) keeps the
|
|
2454
2490
|
structure without the shout. Consumers re-louden via the token. */
|
|
2455
2491
|
:deep(thead th) {
|
|
2456
2492
|
color: var(--dx-table-header-color, var(--bs-secondary-color));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
@component
|
|
3
|
-
|
|
3
|
+
Pagination + per-page footer shared by `DXTable` and standalone tables. Renders the pager, the
|
|
4
4
|
per-page selector, and the "X to Y out of Z items" info line (with the
|
|
5
5
|
"Filtered from N" note when a column filter is active).
|
|
6
6
|
|
|
@@ -31,6 +31,13 @@ export interface FormState<TData extends Record<string, any>> {
|
|
|
31
31
|
message: string;
|
|
32
32
|
touched: Record<string, boolean>;
|
|
33
33
|
recentlySuccessful: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Whether the most recent submission succeeded. Unlike
|
|
36
|
+
* `recentlySuccessful` (which clears itself after 1.5s) this stays true
|
|
37
|
+
* until the next submission starts, and is false after a failure — the
|
|
38
|
+
* Inertia `wasSuccessful` semantics. DXForm's saved state reads it.
|
|
39
|
+
*/
|
|
40
|
+
wasSuccessful: boolean;
|
|
34
41
|
shouldShowMessage: boolean;
|
|
35
42
|
}
|
|
36
43
|
|
|
@@ -172,6 +179,7 @@ export function useForm<TData extends Record<string, any>>(
|
|
|
172
179
|
message: "",
|
|
173
180
|
touched: {},
|
|
174
181
|
recentlySuccessful: false,
|
|
182
|
+
wasSuccessful: false,
|
|
175
183
|
shouldShowMessage: false,
|
|
176
184
|
});
|
|
177
185
|
|
|
@@ -263,6 +271,7 @@ export function useForm<TData extends Record<string, any>>(
|
|
|
263
271
|
): Promise<TResponse> => {
|
|
264
272
|
inFlightCount += 1;
|
|
265
273
|
state.processing = true;
|
|
274
|
+
state.wasSuccessful = false;
|
|
266
275
|
if (!options.preserveErrors) clearErrors();
|
|
267
276
|
|
|
268
277
|
const payloadRaw = (
|
|
@@ -326,6 +335,7 @@ export function useForm<TData extends Record<string, any>>(
|
|
|
326
335
|
});
|
|
327
336
|
|
|
328
337
|
state.recentlySuccessful = true;
|
|
338
|
+
state.wasSuccessful = true;
|
|
329
339
|
if (successTimer !== null) clearTimeout(successTimer);
|
|
330
340
|
successTimer = setTimeout(() => {
|
|
331
341
|
state.recentlySuccessful = false;
|
|
@@ -338,6 +348,7 @@ export function useForm<TData extends Record<string, any>>(
|
|
|
338
348
|
}
|
|
339
349
|
return data;
|
|
340
350
|
} catch (err) {
|
|
351
|
+
state.wasSuccessful = false;
|
|
341
352
|
const { errors, message } = errorsFromLaravel(err);
|
|
342
353
|
setErrors(errors);
|
|
343
354
|
setMessage(message);
|
|
@@ -13,7 +13,7 @@ import type {
|
|
|
13
13
|
// class, driving Bootstrap's own `--bs-toast-*` variables cleanly. An
|
|
14
14
|
// unrecognised variant (e.g. "primary", "dark", or none) falls through to
|
|
15
15
|
// BVN's default `.text-bg-*` styling unchanged.
|
|
16
|
-
const THEMED_TOAST_VARIANTS = new Set(["success", "danger", "warning", "info"]);
|
|
16
|
+
const THEMED_TOAST_VARIANTS = new Set(["success", "danger", "warning", "info", "pending"]);
|
|
17
17
|
|
|
18
18
|
function themeToastParam(param: Record<string, unknown>): Record<string, unknown> {
|
|
19
19
|
const variant = param.variant as string | null | undefined;
|
package/resources/js/index.ts
CHANGED
|
@@ -9,8 +9,12 @@ export { default as DXDashboard } from "./components/extended/DXDashboard.vue";
|
|
|
9
9
|
export { default as DXForm } from "./components/extended/DXForm.vue";
|
|
10
10
|
export { default as DXField } from "./components/extended/DXField.vue";
|
|
11
11
|
export { default as DXFieldLabel } from "./components/extended/DXFieldLabel.vue";
|
|
12
|
+
export { default as DXModalActions } from "./components/extended/DXModalActions.vue";
|
|
13
|
+
export { default as DXSaveButton } from "./components/extended/DXSaveButton.vue";
|
|
14
|
+
export { default as DXLoading } from "./components/extended/DXLoading.vue";
|
|
12
15
|
export { default as DXSwitch } from "./components/extended/DXSwitch.vue";
|
|
13
16
|
export { default as DXCurrencyInput } from "./components/extended/DXCurrencyInput.vue";
|
|
17
|
+
export { default as DXNumberStepper } from "./components/extended/DXNumberStepper.vue";
|
|
14
18
|
export { default as DXStatCard } from "./components/extended/DXStatCard.vue";
|
|
15
19
|
// Chart components moved to the `@omnitend/dashboard-for-laravel/charts` entry
|
|
16
20
|
// (#142) so chart.js / vue-chartjs stay genuinely optional peers — the main
|
|
@@ -23,6 +27,7 @@ export { default as DXRepeater } from "./components/extended/DXRepeater.vue";
|
|
|
23
27
|
*/
|
|
24
28
|
export { default as DXBasicForm } from "./components/extended/DXBasicForm.vue";
|
|
25
29
|
export { default as DXTable } from "./components/extended/DXTable.vue";
|
|
30
|
+
export { default as DXTablePagination } from "./components/extended/DXTablePagination.vue";
|
|
26
31
|
export { default as DXDashboardSidebar } from "./components/extended/DXDashboardSidebar.vue";
|
|
27
32
|
export { default as DXDashboardNavbar } from "./components/extended/DXDashboardNavbar.vue";
|
|
28
33
|
export { default as DXUserAvatar } from "./components/extended/DXUserAvatar.vue";
|
|
@@ -73,8 +73,9 @@ export type OptionsLoader = (model: any) => Promise<FieldOption[]>;
|
|
|
73
73
|
* Deliberately excludes `boolean` (which BFormGroup's own `labelCols` prop
|
|
74
74
|
* accepts): Vue's type-based `defineProps` auto-defaults an omitted prop to
|
|
75
75
|
* `false` (not `undefined`) whenever its declared type includes `boolean`,
|
|
76
|
-
* which would silently break the `field.labelCols ?? formLabelCols
|
|
77
|
-
*
|
|
76
|
+
* which would silently break the `field.labelCols ?? formLabelCols` fallback
|
|
77
|
+
* chain used to resolve this value (`undefined` at the end of it means the
|
|
78
|
+
* default 45% label column, `--dx-form-label-width`).
|
|
78
79
|
*/
|
|
79
80
|
export type LabelCols =
|
|
80
81
|
| number
|
|
@@ -241,7 +242,8 @@ export interface FieldDefinition {
|
|
|
241
242
|
|
|
242
243
|
/**
|
|
243
244
|
* Per-field override of DXForm's `labelCols` prop, for horizontal
|
|
244
|
-
* layout. Falls back to the form-level `labelCols` when omitted
|
|
245
|
+
* layout. Falls back to the form-level `labelCols` when omitted, and to
|
|
246
|
+
* the default 45% label column (`--dx-form-label-width`) when neither is set.
|
|
245
247
|
*/
|
|
246
248
|
labelCols?: LabelCols;
|
|
247
249
|
|
|
@@ -636,3 +638,19 @@ export interface FormTab {
|
|
|
636
638
|
/** Lazily mount tab content until first activated */
|
|
637
639
|
lazy?: boolean;
|
|
638
640
|
}
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* The theme's extra colour variant, `pending`: waiting, and the next move is
|
|
644
|
+
* not yours ("awaiting payment", "sent to printer, not yet confirmed").
|
|
645
|
+
* theme.scss paints it everywhere a stock variant is painted (badge, soft and
|
|
646
|
+
* outline button, alert, text, subtle utilities, table row, list-group item,
|
|
647
|
+
* toast). Registering it on bootstrap-vue-next's `BaseColorVariant` adds it to
|
|
648
|
+
* every variant union derived from that interface (`ColorVariant`,
|
|
649
|
+
* `ButtonVariant` incl. `outline-pending`, the `-subtle` and `-emphasis`
|
|
650
|
+
* forms), so `<DBadge variant="pending">` type-checks.
|
|
651
|
+
*/
|
|
652
|
+
declare module "bootstrap-vue-next" {
|
|
653
|
+
interface BaseColorVariant {
|
|
654
|
+
pending: unknown;
|
|
655
|
+
}
|
|
656
|
+
}
|