nuxt-ui-tools 1.2.0 → 1.4.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 (238) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +18 -2
  3. package/dist/runtime/dashboard/components/block/dashboard-block-state.d.vue.ts +2 -0
  4. package/dist/runtime/dashboard/components/block/dashboard-block-state.vue +4 -1
  5. package/dist/runtime/dashboard/components/block/dashboard-block-state.vue.d.ts +2 -0
  6. package/dist/runtime/dashboard/components/block/dashboard-chips.d.vue.ts +20 -0
  7. package/dist/runtime/dashboard/components/block/dashboard-chips.vue +42 -0
  8. package/dist/runtime/dashboard/components/block/dashboard-chips.vue.d.ts +20 -0
  9. package/dist/runtime/dashboard/components/block/dashboard-series-picker.d.vue.ts +8 -0
  10. package/dist/runtime/dashboard/components/block/dashboard-series-picker.vue +29 -0
  11. package/dist/runtime/dashboard/components/block/dashboard-series-picker.vue.d.ts +8 -0
  12. package/dist/runtime/dashboard/components/block/dashboard-skeleton.d.vue.ts +1 -1
  13. package/dist/runtime/dashboard/components/block/dashboard-skeleton.vue.d.ts +1 -1
  14. package/dist/runtime/dashboard/components/block/dashboard-view-scope.d.vue.ts +21 -0
  15. package/dist/runtime/dashboard/components/block/dashboard-view-scope.vue +12 -0
  16. package/dist/runtime/dashboard/components/block/dashboard-view-scope.vue.d.ts +21 -0
  17. package/dist/runtime/dashboard/components/dashboard-alerts.vue +3 -3
  18. package/dist/runtime/dashboard/components/dashboard-bar-chart.d.vue.ts +14 -3
  19. package/dist/runtime/dashboard/components/dashboard-bar-chart.vue +30 -9
  20. package/dist/runtime/dashboard/components/dashboard-bar-chart.vue.d.ts +14 -3
  21. package/dist/runtime/dashboard/components/dashboard-bars.vue +4 -4
  22. package/dist/runtime/dashboard/components/dashboard-card.vue +28 -6
  23. package/dist/runtime/dashboard/components/dashboard-combo-chart.d.vue.ts +6 -1
  24. package/dist/runtime/dashboard/components/dashboard-combo-chart.vue +13 -3
  25. package/dist/runtime/dashboard/components/dashboard-combo-chart.vue.d.ts +6 -1
  26. package/dist/runtime/dashboard/components/dashboard-donut-chart.vue +5 -5
  27. package/dist/runtime/dashboard/components/dashboard-feed.vue +1 -1
  28. package/dist/runtime/dashboard/components/dashboard-filter.d.vue.ts +67 -0
  29. package/dist/runtime/dashboard/components/dashboard-filter.vue +134 -0
  30. package/dist/runtime/dashboard/components/dashboard-filter.vue.d.ts +67 -0
  31. package/dist/runtime/dashboard/components/dashboard-filters.d.vue.ts +49 -0
  32. package/dist/runtime/dashboard/components/dashboard-filters.vue +96 -0
  33. package/dist/runtime/dashboard/components/dashboard-filters.vue.d.ts +49 -0
  34. package/dist/runtime/dashboard/components/dashboard-funnel.vue +5 -5
  35. package/dist/runtime/dashboard/components/dashboard-gauge.vue +3 -3
  36. package/dist/runtime/dashboard/components/dashboard-grid.d.vue.ts +10 -3
  37. package/dist/runtime/dashboard/components/dashboard-grid.vue +24 -9
  38. package/dist/runtime/dashboard/components/dashboard-grid.vue.d.ts +10 -3
  39. package/dist/runtime/dashboard/components/dashboard-line-chart.d.vue.ts +14 -3
  40. package/dist/runtime/dashboard/components/dashboard-line-chart.vue +30 -9
  41. package/dist/runtime/dashboard/components/dashboard-line-chart.vue.d.ts +14 -3
  42. package/dist/runtime/dashboard/components/dashboard-list.d.vue.ts +3 -0
  43. package/dist/runtime/dashboard/components/dashboard-list.vue +18 -6
  44. package/dist/runtime/dashboard/components/dashboard-list.vue.d.ts +3 -0
  45. package/dist/runtime/dashboard/components/dashboard-page.d.vue.ts +53 -0
  46. package/dist/runtime/dashboard/components/dashboard-page.vue +156 -0
  47. package/dist/runtime/dashboard/components/dashboard-page.vue.d.ts +53 -0
  48. package/dist/runtime/dashboard/components/dashboard-paired-bars.vue +4 -4
  49. package/dist/runtime/dashboard/components/dashboard-refresh.d.vue.ts +1 -1
  50. package/dist/runtime/dashboard/components/dashboard-refresh.vue +1 -0
  51. package/dist/runtime/dashboard/components/dashboard-refresh.vue.d.ts +1 -1
  52. package/dist/runtime/dashboard/components/dashboard-stack-bar.vue +4 -4
  53. package/dist/runtime/dashboard/components/dashboard-stat.d.vue.ts +14 -2
  54. package/dist/runtime/dashboard/components/dashboard-stat.vue +28 -10
  55. package/dist/runtime/dashboard/components/dashboard-stat.vue.d.ts +14 -2
  56. package/dist/runtime/dashboard/components/dashboard-stats.vue +3 -3
  57. package/dist/runtime/dashboard/components/dashboard-table.d.vue.ts +1 -1
  58. package/dist/runtime/dashboard/components/dashboard-table.vue +3 -3
  59. package/dist/runtime/dashboard/components/dashboard-table.vue.d.ts +1 -1
  60. package/dist/runtime/dashboard/components/dashboard-tabs.d.vue.ts +1 -1
  61. package/dist/runtime/dashboard/components/dashboard-tabs.vue.d.ts +1 -1
  62. package/dist/runtime/dashboard/components/dashboard-total.d.vue.ts +7 -2
  63. package/dist/runtime/dashboard/components/dashboard-total.vue +10 -2
  64. package/dist/runtime/dashboard/components/dashboard-total.vue.d.ts +7 -2
  65. package/dist/runtime/dashboard/components/dashboard-view-tabs.d.vue.ts +33 -0
  66. package/dist/runtime/dashboard/components/dashboard-view-tabs.vue +66 -0
  67. package/dist/runtime/dashboard/components/dashboard-view-tabs.vue.d.ts +33 -0
  68. package/dist/runtime/dashboard/components/dashboard-widget.vue +1 -1
  69. package/dist/runtime/dashboard/components/filter/dashboard-filter-menu.d.vue.ts +44 -0
  70. package/dist/runtime/dashboard/components/filter/dashboard-filter-menu.vue +220 -0
  71. package/dist/runtime/dashboard/components/filter/dashboard-filter-menu.vue.d.ts +44 -0
  72. package/dist/runtime/dashboard/composables/use-dashboard-api.d.ts +6 -1
  73. package/dist/runtime/dashboard/composables/use-dashboard-api.js +29 -6
  74. package/dist/runtime/dashboard/composables/use-dashboard-block.d.ts +5 -4
  75. package/dist/runtime/dashboard/composables/use-dashboard-block.js +32 -15
  76. package/dist/runtime/dashboard/composables/use-dashboard-chart.d.ts +8 -1
  77. package/dist/runtime/dashboard/composables/use-dashboard-chart.js +16 -4
  78. package/dist/runtime/dashboard/composables/use-dashboard-context.d.ts +50 -0
  79. package/dist/runtime/dashboard/composables/use-dashboard-context.js +56 -0
  80. package/dist/runtime/dashboard/composables/use-dashboard-derived.js +6 -1
  81. package/dist/runtime/dashboard/composables/use-dashboard-filter-control.d.ts +16 -0
  82. package/dist/runtime/dashboard/composables/use-dashboard-filter-control.js +161 -0
  83. package/dist/runtime/dashboard/composables/use-dashboard-filter-scope.d.ts +37 -0
  84. package/dist/runtime/dashboard/composables/use-dashboard-filter-scope.js +107 -0
  85. package/dist/runtime/dashboard/composables/use-dashboard-format.d.ts +46 -6
  86. package/dist/runtime/dashboard/composables/use-dashboard-format.js +51 -8
  87. package/dist/runtime/dashboard/composables/use-dashboard-options.d.ts +11 -4
  88. package/dist/runtime/dashboard/composables/use-dashboard-options.js +33 -47
  89. package/dist/runtime/dashboard/composables/use-dashboard-remote-options.d.ts +8 -5
  90. package/dist/runtime/dashboard/composables/use-dashboard-remote-options.js +59 -70
  91. package/dist/runtime/dashboard/composables/use-dashboard-resource.d.ts +15 -4
  92. package/dist/runtime/dashboard/composables/use-dashboard-resource.js +52 -17
  93. package/dist/runtime/dashboard/composables/use-dashboard-scope.d.ts +10 -7
  94. package/dist/runtime/dashboard/composables/use-dashboard-scope.js +26 -16
  95. package/dist/runtime/dashboard/composables/use-dashboard-series-picker.d.ts +20 -0
  96. package/dist/runtime/dashboard/composables/use-dashboard-series-picker.js +30 -0
  97. package/dist/runtime/dashboard/composables/use-dashboard-time.d.ts +2 -0
  98. package/dist/runtime/dashboard/composables/use-dashboard-time.js +4 -1
  99. package/dist/runtime/dashboard/composables/use-dashboard-ui.d.ts +12 -2
  100. package/dist/runtime/dashboard/composables/use-dashboard-ui.js +3 -0
  101. package/dist/runtime/dashboard/composables/use-dashboard-views.d.ts +15 -3
  102. package/dist/runtime/dashboard/composables/use-dashboard-views.js +33 -10
  103. package/dist/runtime/dashboard/composables/use-dashboard.d.ts +18 -12
  104. package/dist/runtime/dashboard/composables/use-dashboard.js +98 -9
  105. package/dist/runtime/dashboard/index.d.ts +3 -1
  106. package/dist/runtime/dashboard/index.js +3 -1
  107. package/dist/runtime/dashboard/schema/index.d.ts +62 -30
  108. package/dist/runtime/dashboard/schema/index.js +3 -0
  109. package/dist/runtime/dashboard/types/blocks.d.ts +30 -4
  110. package/dist/runtime/dashboard/types/charts.d.ts +2 -2
  111. package/dist/runtime/dashboard/types/controls.d.ts +123 -0
  112. package/dist/runtime/dashboard/types/filters.d.ts +236 -0
  113. package/dist/runtime/dashboard/types/index.d.ts +3 -2
  114. package/dist/runtime/dashboard/types/page.d.ts +17 -0
  115. package/dist/runtime/dashboard/types/page.js +0 -0
  116. package/dist/runtime/dashboard/types/resource.d.ts +66 -28
  117. package/dist/runtime/dashboard/types/runtime.d.ts +39 -8
  118. package/dist/runtime/dashboard/types/schema.d.ts +94 -54
  119. package/dist/runtime/dashboard/types/ui.d.ts +78 -0
  120. package/dist/runtime/dashboard/utils/builders/dashboard-filters.d.ts +142 -0
  121. package/dist/runtime/dashboard/utils/builders/dashboard-filters.js +135 -0
  122. package/dist/runtime/dashboard/utils/charts.d.ts +4 -15
  123. package/dist/runtime/dashboard/utils/charts.js +26 -28
  124. package/dist/runtime/dashboard/utils/{params/codecs.d.ts → codecs.d.ts} +2 -2
  125. package/dist/runtime/dashboard/utils/{params/codecs.js → codecs.js} +1 -1
  126. package/dist/runtime/dashboard/utils/environment.d.ts +36 -0
  127. package/dist/runtime/dashboard/utils/environment.js +30 -0
  128. package/dist/runtime/dashboard/utils/filters.d.ts +44 -0
  129. package/dist/runtime/dashboard/utils/filters.js +62 -0
  130. package/dist/runtime/dashboard/utils/format.d.ts +25 -0
  131. package/dist/runtime/dashboard/utils/format.js +66 -0
  132. package/dist/runtime/dashboard/utils/grid.d.ts +17 -0
  133. package/dist/runtime/dashboard/utils/grid.js +14 -0
  134. package/dist/runtime/dashboard/utils/options.d.ts +3 -1
  135. package/dist/runtime/dashboard/utils/options.js +6 -0
  136. package/dist/runtime/dashboard/utils/remote.d.ts +7 -0
  137. package/dist/runtime/dashboard/utils/remote.js +14 -0
  138. package/dist/runtime/dashboard/utils/resource.d.ts +16 -7
  139. package/dist/runtime/dashboard/utils/resource.js +15 -9
  140. package/dist/runtime/dashboard/utils/schema.d.ts +8 -3
  141. package/dist/runtime/dashboard/utils/schema.js +9 -4
  142. package/dist/runtime/dashboard/utils/state.d.ts +11 -6
  143. package/dist/runtime/dashboard/utils/state.js +10 -5
  144. package/dist/runtime/dashboard/utils/time.d.ts +2 -0
  145. package/dist/runtime/dashboard/utils/time.js +11 -1
  146. package/dist/runtime/dashboard/utils/ui.d.ts +1 -1
  147. package/dist/runtime/dashboard/utils/ui.js +1 -1
  148. package/dist/runtime/form/components/actions/form-actions.vue +13 -127
  149. package/dist/runtime/form/components/page/form-page-actions.d.vue.ts +3 -0
  150. package/dist/runtime/form/components/page/form-page-actions.vue +40 -0
  151. package/dist/runtime/form/components/page/form-page-actions.vue.d.ts +3 -0
  152. package/dist/runtime/form/components/page/form-page-header.d.vue.ts +24 -0
  153. package/dist/runtime/form/components/page/form-page-header.vue +99 -0
  154. package/dist/runtime/form/components/page/form-page-header.vue.d.ts +24 -0
  155. package/dist/runtime/form/components/page/form-page-navigation.d.vue.ts +34 -0
  156. package/dist/runtime/form/components/page/form-page-navigation.vue +229 -0
  157. package/dist/runtime/form/components/page/form-page-navigation.vue.d.ts +34 -0
  158. package/dist/runtime/form/components/page/form-page-section.d.vue.ts +19 -0
  159. package/dist/runtime/form/components/page/form-page-section.vue +114 -0
  160. package/dist/runtime/form/components/page/form-page-section.vue.d.ts +19 -0
  161. package/dist/runtime/form/components/page/form-page-sections.d.vue.ts +21 -0
  162. package/dist/runtime/form/components/page/form-page-sections.vue +75 -0
  163. package/dist/runtime/form/components/page/form-page-sections.vue.d.ts +21 -0
  164. package/dist/runtime/form/components/page/form-page.d.vue.ts +80 -0
  165. package/dist/runtime/form/components/page/form-page.vue +91 -0
  166. package/dist/runtime/form/components/page/form-page.vue.d.ts +80 -0
  167. package/dist/runtime/form/components/renderer/form-field-shell.vue +7 -11
  168. package/dist/runtime/form/components/root/form.vue +26 -195
  169. package/dist/runtime/form/composables/use-form-action-buttons.d.ts +32 -0
  170. package/dist/runtime/form/composables/use-form-action-buttons.js +89 -0
  171. package/dist/runtime/form/composables/use-form-actions.d.ts +8 -5
  172. package/dist/runtime/form/composables/use-form-actions.js +1 -1
  173. package/dist/runtime/form/composables/use-form-page-scroll.d.ts +22 -0
  174. package/dist/runtime/form/composables/use-form-page-scroll.js +178 -0
  175. package/dist/runtime/form/composables/use-form-page.d.ts +114 -0
  176. package/dist/runtime/form/composables/use-form-page.js +83 -0
  177. package/dist/runtime/form/composables/use-form-root.d.ts +34 -0
  178. package/dist/runtime/form/composables/use-form-root.js +171 -0
  179. package/dist/runtime/form/composables/use-form-runtime.js +13 -4
  180. package/dist/runtime/form/composables/use-form.js +2 -22
  181. package/dist/runtime/form/fields/card-selection.d.ts +1 -0
  182. package/dist/runtime/form/fields/card-selection.js +1 -0
  183. package/dist/runtime/form/fields/checkbox-card/component.vue +28 -17
  184. package/dist/runtime/form/fields/checkbox-card/types.d.ts +2 -5
  185. package/dist/runtime/form/fields/checkbox-group/component.vue +5 -0
  186. package/dist/runtime/form/fields/choice-card/choice-card-label.d.vue.ts +17 -0
  187. package/dist/runtime/form/fields/choice-card/choice-card-label.vue +50 -0
  188. package/dist/runtime/form/fields/choice-card/choice-card-label.vue.d.ts +17 -0
  189. package/dist/runtime/form/fields/choice-card/types.d.ts +31 -0
  190. package/dist/runtime/form/fields/choice-card/types.js +0 -0
  191. package/dist/runtime/form/fields/choice-card/use-choice-card.d.ts +22 -0
  192. package/dist/runtime/form/fields/choice-card/use-choice-card.js +52 -0
  193. package/dist/runtime/form/fields/radio/component.vue +10 -0
  194. package/dist/runtime/form/fields/radio-card/component.vue +17 -16
  195. package/dist/runtime/form/fields/radio-card/types.d.ts +2 -4
  196. package/dist/runtime/form/index.d.ts +1 -1
  197. package/dist/runtime/form/index.js +7 -1
  198. package/dist/runtime/form/schema/index.d.ts +1 -1
  199. package/dist/runtime/form/schema/index.js +1 -0
  200. package/dist/runtime/form/schema/page.d.ts +50 -0
  201. package/dist/runtime/form/schema/page.js +25 -0
  202. package/dist/runtime/form/types/index.d.ts +1 -0
  203. package/dist/runtime/form/types/options.d.ts +1 -11
  204. package/dist/runtime/form/types/page.d.ts +172 -0
  205. package/dist/runtime/form/types/page.js +0 -0
  206. package/dist/runtime/form/types/ui.d.ts +60 -0
  207. package/dist/runtime/form/utils/controls.d.ts +15 -0
  208. package/dist/runtime/form/utils/controls.js +38 -0
  209. package/dist/runtime/form/utils/focus.js +1 -1
  210. package/dist/runtime/form/utils/layout.js +3 -1
  211. package/dist/runtime/form/utils/page.d.ts +20 -0
  212. package/dist/runtime/form/utils/page.js +107 -0
  213. package/dist/runtime/form/utils/state.d.ts +2 -0
  214. package/dist/runtime/form/utils/state.js +1 -1
  215. package/dist/runtime/form/utils/ui.js +1 -0
  216. package/dist/runtime/i18n/locales/en.js +47 -0
  217. package/dist/runtime/i18n/locales/fr.js +47 -0
  218. package/dist/runtime/i18n/types.d.ts +70 -0
  219. package/dist/runtime/shared/styles/tokens.css +1 -1
  220. package/dist/runtime/shared/types/query.d.ts +8 -0
  221. package/dist/runtime/table/types/index.d.ts +1 -0
  222. package/dist/runtime/table/types/remote-options.d.ts +64 -0
  223. package/dist/runtime/table/types/remote-options.js +0 -0
  224. package/dist/runtime/table/types/source.d.ts +10 -1
  225. package/dist/runtime/table/utils/builders/table-source.d.ts +2 -6
  226. package/dist/runtime/table/utils/index.d.ts +1 -0
  227. package/dist/runtime/table/utils/index.js +1 -0
  228. package/dist/runtime/table/utils/remote-table-options.d.ts +26 -0
  229. package/dist/runtime/table/utils/remote-table-options.js +88 -0
  230. package/package.json +4 -1
  231. package/dist/runtime/dashboard/composables/use-dashboard-param-scope.d.ts +0 -30
  232. package/dist/runtime/dashboard/composables/use-dashboard-param-scope.js +0 -71
  233. package/dist/runtime/dashboard/types/options.d.ts +0 -46
  234. package/dist/runtime/dashboard/types/params.d.ts +0 -115
  235. package/dist/runtime/dashboard/utils/builders/dashboard-params.d.ts +0 -85
  236. package/dist/runtime/dashboard/utils/builders/dashboard-params.js +0 -87
  237. /package/dist/runtime/dashboard/types/{options.js → controls.js} +0 -0
  238. /package/dist/runtime/dashboard/types/{params.js → filters.js} +0 -0
@@ -0,0 +1,66 @@
1
+ const formatsByLocale = /* @__PURE__ */ new Map();
2
+ const numberFormats = /* @__PURE__ */ new Map();
3
+ const monthFormats = /* @__PURE__ */ new Map();
4
+ export function normalizeDashboardSpaces(text) {
5
+ return text.replaceAll("\u202F", "\xA0");
6
+ }
7
+ export function resolveDashboardNumberFormat(locale, options) {
8
+ const resolvedOptions = withCurrencyShorthand(options);
9
+ const key = `${locale}|${JSON.stringify(resolvedOptions)}`;
10
+ let format = numberFormats.get(key);
11
+ if (!format) {
12
+ format = new Intl.NumberFormat(locale, resolvedOptions);
13
+ numberFormats.set(key, format);
14
+ }
15
+ const resolved = format;
16
+ return (value) => normalizeDashboardSpaces(resolved.format(value));
17
+ }
18
+ function withCurrencyShorthand(options) {
19
+ if (options.currency === void 0 || options.style !== void 0) return options;
20
+ const digits = options.minimumFractionDigits === void 0 && options.maximumFractionDigits === void 0 ? { maximumFractionDigits: 0 } : {};
21
+ return { ...digits, ...options, style: "currency" };
22
+ }
23
+ export function resolveDashboardFormats(locale) {
24
+ const cached = formatsByLocale.get(locale);
25
+ if (cached) return cached;
26
+ const plain = resolveDashboardNumberFormat(locale, { maximumFractionDigits: 1 });
27
+ const compact = resolveDashboardNumberFormat(locale, {
28
+ maximumFractionDigits: 1,
29
+ notation: "compact"
30
+ });
31
+ const percent = resolveDashboardNumberFormat(locale, {
32
+ maximumFractionDigits: 1,
33
+ style: "percent"
34
+ });
35
+ const delta = resolveDashboardNumberFormat(locale, {
36
+ maximumFractionDigits: 1,
37
+ signDisplay: "exceptZero",
38
+ style: "percent"
39
+ });
40
+ const formats = {
41
+ compact,
42
+ decimal: plain,
43
+ delta: (value) => delta(value / 100),
44
+ integer: resolveDashboardNumberFormat(locale, { maximumFractionDigits: 0 }),
45
+ number: (value) => Math.abs(value) >= 1e4 ? compact(value) : plain(value),
46
+ percent: (value) => percent(value / 100),
47
+ ratio: percent,
48
+ signed: resolveDashboardNumberFormat(locale, {
49
+ maximumFractionDigits: 1,
50
+ signDisplay: "exceptZero"
51
+ })
52
+ };
53
+ formatsByLocale.set(locale, formats);
54
+ return formats;
55
+ }
56
+ export function formatDashboardMonth(locale, value, width = "short") {
57
+ const key = `${locale}|${width}`;
58
+ let format = monthFormats.get(key);
59
+ if (!format) {
60
+ format = new Intl.DateTimeFormat(locale, { month: width });
61
+ monthFormats.set(key, format);
62
+ }
63
+ const date = typeof value === "number" ? new Date(2e3, value - 1, 1) : value;
64
+ const text = format.format(date);
65
+ return text.charAt(0).toLocaleUpperCase(locale) + text.slice(1);
66
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Flex item style of one grid cell. Dashboard grids are wrapping flex rows: a cell's basis is the
3
+ * width its `size` spans over the grid's columns (the same widths a CSS grid would give), so rows
4
+ * break where the column count says. When `fill` is on, a row that is not full (a block hidden
5
+ * because its source is disabled, or a short last row) shares the free width between its cells in
6
+ * proportion to their span, so no gap is left.
7
+ *
8
+ * `span` is the resolved column span, `null` for a full-row cell.
9
+ */
10
+ export declare function resolveDashboardCellStyle(params: {
11
+ span: number | null;
12
+ columns: number;
13
+ gap: string;
14
+ fill: boolean;
15
+ }): string;
16
+ /** Parses a resolved responsive token (`"8"`) into a positive integer, `null` when unset. */
17
+ export declare function parseDashboardSpan(value: number | string | null | undefined): number | null;
@@ -0,0 +1,14 @@
1
+ import { isNumber } from "../../shared/utils/predicate.js";
2
+ export function resolveDashboardCellStyle(params) {
3
+ const columns = Math.max(1, Math.round(params.columns));
4
+ const span = params.span === null || !Number.isFinite(params.span) ? columns : Math.min(columns, Math.max(1, Math.round(params.span)));
5
+ if (span >= columns) return "flex: 1 1 100%; min-width: 0";
6
+ const { gap } = params;
7
+ const basis = `calc((100% - ${columns - 1} * ${gap}) / ${columns} * ${span} + ${span - 1} * ${gap} - 0.02px)`;
8
+ return `flex: ${params.fill ? span : 0} 1 ${basis}; min-width: 0`;
9
+ }
10
+ export function parseDashboardSpan(value) {
11
+ if (value === null || value === void 0 || value === "") return null;
12
+ const parsed = isNumber(value) ? value : Number.parseInt(value, 10);
13
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
14
+ }
@@ -1,5 +1,7 @@
1
1
  import type { DashboardOption } from '../types/index.js';
2
- /** Normalizes a single or multiple param value to its string keys, in value order. */
2
+ /** Normalizes a single or multiple filter value to its string keys, in value order. */
3
3
  export declare function resolveDashboardOptionValues(value: unknown): string[];
4
4
  /** Unique options by value, keeping the first occurrence. */
5
5
  export declare function mergeDashboardOptions(...lists: readonly (readonly DashboardOption[])[]): DashboardOption[];
6
+ /** The label contains the search term, ignoring case and diacritics. */
7
+ export declare function matchesDashboardSearch(label: string, term: string): boolean;
@@ -16,3 +16,9 @@ export function mergeDashboardOptions(...lists) {
16
16
  }
17
17
  return merged;
18
18
  }
19
+ function normalizeDashboardSearch(value) {
20
+ return value.normalize("NFD").replaceAll(/[̀-ͯ]/gu, "").toLowerCase().trim();
21
+ }
22
+ export function matchesDashboardSearch(label, term) {
23
+ return normalizeDashboardSearch(label).includes(normalizeDashboardSearch(term));
24
+ }
@@ -0,0 +1,7 @@
1
+ import type { QueryFunctionContext, QueryKey } from '@tanstack/vue-query';
2
+ import type { DashboardRemoteResult } from '../types/index.js';
3
+ /**
4
+ * Settles what a remote option source returned: awaits a promise, or runs a query definition's
5
+ * `queryFn` under the definition's own key (the page is already cached by the caller's query).
6
+ */
7
+ export declare function runDashboardRemoteResult<TResult>(result: DashboardRemoteResult<TResult>, context: QueryFunctionContext<QueryKey, never>): Promise<TResult>;
@@ -0,0 +1,14 @@
1
+ export async function runDashboardRemoteResult(result, context) {
2
+ if (!("queryKey" in result)) return result;
3
+ if (!result.queryFn) {
4
+ throw new Error(
5
+ "[dashboard] Remote option sources returning a query definition need a queryFn."
6
+ );
7
+ }
8
+ return result.queryFn({
9
+ ...context,
10
+ direction: "forward",
11
+ pageParam: null,
12
+ queryKey: result.queryKey
13
+ });
14
+ }
@@ -1,16 +1,25 @@
1
1
  import type { ShallowRef } from 'vue';
2
2
  import type { useDashboardResource } from '../composables/use-dashboard-resource.js';
3
3
  import type { DashboardSourceLike, DashboardStage } from '../types/index.js';
4
+ import type { DashboardReadTracker } from './tracker.js';
4
5
  export type DashboardResourceSlot = ShallowRef<ReturnType<typeof useDashboardResource> | null>;
6
+ type DashboardResourceFacade = DashboardSourceLike & {
7
+ kind: 'query';
8
+ stage: DashboardStage;
9
+ active: boolean;
10
+ filters: object;
11
+ controls: object;
12
+ };
5
13
  /**
6
14
  * Public resource object returned by `stage.query(...)`. It exists before its key is known (keys
7
15
  * come from the object the `queries` builder returns), so it reads the resource runtime through a
8
- * slot. Reads before instantiation track the slot, which keeps dependent gates reactive.
16
+ * slot. Reads before instantiation track the slot, which keeps dependent gates reactive, and every
17
+ * `data` read is recorded by the tracker, so `requires` and `derive` know what they depend on.
9
18
  */
10
- export declare function createDashboardResourceFacade(stage: DashboardStage, slot: DashboardResourceSlot, defaultValue: unknown): DashboardSourceLike & {
11
- kind: 'query';
19
+ export declare function createDashboardResourceFacade(params: {
12
20
  stage: DashboardStage;
13
- active: boolean;
14
- params: object;
15
- options: object;
16
- };
21
+ slot: DashboardResourceSlot;
22
+ defaultValue: unknown;
23
+ tracker: DashboardReadTracker;
24
+ }): DashboardResourceFacade;
25
+ export {};
@@ -1,7 +1,8 @@
1
1
  import { markRaw } from "vue";
2
2
  const emptyFacade = markRaw({});
3
- export function createDashboardResourceFacade(stage, slot, defaultValue) {
4
- return markRaw({
3
+ export function createDashboardResourceFacade(params) {
4
+ const { slot, stage, tracker } = params;
5
+ const facade = markRaw({
5
6
  activate() {
6
7
  slot.value?.activate();
7
8
  },
@@ -9,20 +10,24 @@ export function createDashboardResourceFacade(stage, slot, defaultValue) {
9
10
  return slot.value?.active.value ?? false;
10
11
  },
11
12
  get data() {
12
- return slot.value ? slot.value.data.value : defaultValue;
13
+ tracker.record(facade);
14
+ return slot.value ? slot.value.data.value : params.defaultValue;
13
15
  },
14
16
  get error() {
15
- return slot.value?.error.value ?? void 0;
17
+ return slot.value?.error.value;
18
+ },
19
+ get controls() {
20
+ return slot.value?.filters.controls ?? emptyFacade;
21
+ },
22
+ get filters() {
23
+ return slot.value?.filters.values ?? emptyFacade;
16
24
  },
17
25
  get id() {
18
26
  return slot.value?.id ?? "";
19
27
  },
20
28
  kind: "query",
21
- get options() {
22
- return slot.value?.widget.options ?? emptyFacade;
23
- },
24
- get params() {
25
- return slot.value?.widget.values ?? emptyFacade;
29
+ get fetching() {
30
+ return slot.value?.fetching.value ?? false;
26
31
  },
27
32
  refresh: () => slot.value?.refresh() ?? Promise.resolve(),
28
33
  get refreshing() {
@@ -36,4 +41,5 @@ export function createDashboardResourceFacade(stage, slot, defaultValue) {
36
41
  return slot.value?.updatedAt.value;
37
42
  }
38
43
  });
44
+ return facade;
39
45
  }
@@ -1,9 +1,14 @@
1
- import type { DashboardSchemaLike } from '../types/index.js';
2
- import type { DashboardRuntimeSchema } from '../types/runtime.js';
1
+ import type { DashboardFilterBuilder, DashboardFilterLike, DashboardSchemaLike } from '../types/index.js';
2
+ import type { DashboardRuntimeFiltersInput, DashboardRuntimeSchema } from '../types/runtime.js';
3
3
  /**
4
4
  * Erases the schema generics once so the runtime can invoke every builder with the contexts it
5
- * creates. Views are resolved here (their builder is an identity function at runtime).
5
+ * creates. Views keep the object they were declared with.
6
6
  */
7
7
  export declare function resolveDashboardRuntimeSchema(schema: DashboardSchemaLike): DashboardRuntimeSchema;
8
+ /** Runs a scope's `filters` callback with the `f` builder. */
9
+ export declare function resolveDashboardFilters(params: {
10
+ input: DashboardRuntimeFiltersInput | undefined;
11
+ builder: DashboardFilterBuilder;
12
+ }): Record<string, DashboardFilterLike>;
8
13
  /** Dev guard mirroring the compile-time key checks, for schemas assembled without inference. */
9
14
  export declare function assertDashboardMemberKey(key: string, taken: ReadonlySet<string>, scope: string): void;
@@ -1,9 +1,11 @@
1
1
  const reservedKeys = /* @__PURE__ */ new Set([
2
2
  "autoRefresh",
3
- "options",
4
- "params",
3
+ "controls",
4
+ "filtered",
5
+ "filters",
5
6
  "refresh",
6
7
  "refreshing",
8
+ "resetFilters",
7
9
  "schema",
8
10
  "state",
9
11
  "updatedAt",
@@ -11,19 +13,22 @@ const reservedKeys = /* @__PURE__ */ new Set([
11
13
  ]);
12
14
  export function resolveDashboardRuntimeSchema(schema) {
13
15
  const input = schema;
14
- const views = Object.entries(input.views?.((view) => view) ?? {});
16
+ const views = Object.entries(input.views ?? {});
15
17
  return {
16
18
  autoRefresh: input.autoRefresh,
17
19
  defaultView: input.defaultView ?? views[0]?.[0],
18
20
  derive: input.derive,
21
+ filters: input.filters,
19
22
  key: input.key,
20
23
  label: input.label,
21
- params: input.params,
22
24
  queries: input.queries,
23
25
  urlPrefix: input.urlPrefix,
24
26
  views
25
27
  };
26
28
  }
29
+ export function resolveDashboardFilters(params) {
30
+ return params.input?.(params.builder) ?? {};
31
+ }
27
32
  export function assertDashboardMemberKey(key, taken, scope) {
28
33
  if (reservedKeys.has(key) || taken.has(key)) {
29
34
  throw new Error(`[dashboard] "${key}" in ${scope} is reserved or already used.`);
@@ -1,28 +1,33 @@
1
- import type { DashboardResourceState } from '../types/index.js';
1
+ import type { DashboardCondition, DashboardResourceState } from '../types/index.js';
2
2
  /**
3
3
  * Combines the states of several sources the way a dependent value experiences them: any error
4
4
  * wins, then any pending source. Idle sources were not requested (gated by `requires`, or a
5
5
  * deferred query nobody activated), so they do not hold the value back unless all are idle.
6
+ * Disabled sources are not part of the dashboard: they are left out, and only when every source is
7
+ * disabled is the combination disabled too.
6
8
  */
7
9
  export declare function combineDashboardStates(states: readonly DashboardResourceState[]): DashboardResourceState;
10
+ /** Whether an `enabled` condition holds. No condition always holds. */
11
+ export declare function resolveDashboardCondition(condition: DashboardCondition | undefined): boolean;
8
12
  /** Oldest defined timestamp of a set of sources: they are all at least this fresh. */
9
13
  export declare function resolveDashboardUpdatedAt(values: readonly (number | undefined)[]): number | undefined;
10
14
  /** Refreshes sources in parallel and reports every failure at once. */
11
15
  export declare function refreshDashboardSources(sources: readonly {
12
16
  refresh: () => Promise<void>;
13
17
  }[]): Promise<void>;
14
- /** URL segment of the current view. A root param cannot use it while the dashboard has views. */
18
+ /** URL segment of the current view. No filter can use it while the dashboard has views. */
15
19
  export declare const DASHBOARD_VIEW_URL_KEY = "view";
16
- /** URL segment of the auto-refresh interval. A root param cannot use it. */
20
+ /** URL segment of the auto-refresh interval. No filter can use it. */
17
21
  export declare const DASHBOARD_REFRESH_URL_KEY = "refresh";
18
22
  /** URL key of the auto-refresh interval: `refresh`, or `<urlPrefix>.refresh`. */
19
23
  export declare function resolveDashboardRefreshKey(urlPrefix: string | undefined): string;
20
24
  /** Joins the non-empty segments of a URL key with dots. */
21
25
  export declare function joinDashboardUrlKey(...segments: readonly (string | undefined)[]): string;
22
26
  /**
23
- * URL key prefix of one scope, named after what it holds: none for the root (`year`), the view
24
- * key for a view (`consumption.currency`). `urlPrefix` namespaces both when set.
27
+ * URL key prefix of a dashboard's filters: none (`year`, `currency`), or `urlPrefix` when two
28
+ * dashboards share a page. Views add no segment: a filter key names the same state in every scope,
29
+ * so `year` declared by two views keeps its value across tabs.
25
30
  */
26
- export declare function resolveDashboardScopePrefix(urlPrefix: string | undefined, viewKey?: string): string;
31
+ export declare function resolveDashboardScopePrefix(urlPrefix: string | undefined): string;
27
32
  /** URL key of the current view: `view`, or `<urlPrefix>.view`. */
28
33
  export declare function resolveDashboardViewKey(urlPrefix: string | undefined): string;
@@ -1,9 +1,14 @@
1
1
  export function combineDashboardStates(states) {
2
- if (states.includes("error")) return "error";
3
- if (states.includes("loading")) return "loading";
4
- if (states.length > 0 && states.every((state) => state === "idle")) return "idle";
2
+ const live = states.filter((state) => state !== "disabled");
3
+ if (live.length === 0) return states.length > 0 ? "disabled" : "ready";
4
+ if (live.includes("error")) return "error";
5
+ if (live.includes("loading")) return "loading";
6
+ if (live.every((state) => state === "idle")) return "idle";
5
7
  return "ready";
6
8
  }
9
+ export function resolveDashboardCondition(condition) {
10
+ return condition === void 0 || condition();
11
+ }
7
12
  export function resolveDashboardUpdatedAt(values) {
8
13
  let oldest;
9
14
  for (const value of values) {
@@ -24,8 +29,8 @@ export function resolveDashboardRefreshKey(urlPrefix) {
24
29
  export function joinDashboardUrlKey(...segments) {
25
30
  return segments.filter(Boolean).join(".");
26
31
  }
27
- export function resolveDashboardScopePrefix(urlPrefix, viewKey) {
28
- return joinDashboardUrlKey(urlPrefix, viewKey);
32
+ export function resolveDashboardScopePrefix(urlPrefix) {
33
+ return joinDashboardUrlKey(urlPrefix);
29
34
  }
30
35
  export function resolveDashboardViewKey(urlPrefix) {
31
36
  return joinDashboardUrlKey(urlPrefix, DASHBOARD_VIEW_URL_KEY);
@@ -13,5 +13,7 @@ export declare function formatDashboardDateTime(time: number, locale: string): s
13
13
  * line.
14
14
  */
15
15
  export declare function formatDashboardDay(time: number, now: number, locale: string): string;
16
+ /** The date of a page header: `Wednesday, September 23, 2026`. Capitalized, since it starts a line. */
17
+ export declare function formatDashboardToday(now: number, locale: string): string;
16
18
  /** Local start of the day of a time, used as a stable group key. */
17
19
  export declare function startOfDashboardDay(time: number): number;
@@ -19,7 +19,13 @@ function resolveTimeFormats(locale) {
19
19
  year: "numeric"
20
20
  }),
21
21
  full: new Intl.DateTimeFormat(locale, { dateStyle: "long", timeStyle: "short" }),
22
- relative: new Intl.RelativeTimeFormat(locale, { numeric: "auto", style: "short" })
22
+ relative: new Intl.RelativeTimeFormat(locale, { numeric: "auto", style: "short" }),
23
+ today: new Intl.DateTimeFormat(locale, {
24
+ day: "numeric",
25
+ month: "long",
26
+ weekday: "long",
27
+ year: "numeric"
28
+ })
23
29
  };
24
30
  formatsByLocale.set(locale, formats);
25
31
  return formats;
@@ -50,6 +56,10 @@ export function formatDashboardDay(time, now, locale) {
50
56
  const text = days < 2 ? formats.relative.format(-days, "day") : (sameYear ? formats.date : formats.dateWithYear).format(time);
51
57
  return text.charAt(0).toLocaleUpperCase(locale) + text.slice(1);
52
58
  }
59
+ export function formatDashboardToday(now, locale) {
60
+ const text = resolveTimeFormats(locale).today.format(now);
61
+ return text.charAt(0).toLocaleUpperCase(locale) + text.slice(1);
62
+ }
53
63
  export function startOfDashboardDay(time) {
54
64
  const day = new Date(time);
55
65
  day.setHours(0, 0, 0, 0);
@@ -20,7 +20,7 @@ export declare const DASHBOARD_TABLE_CLASSES: {
20
20
  * never moves, so its divider stays aligned with the card content; the highlight is a pseudo-element
21
21
  * reaching 8px past both edges, behind the content (`isolate` keeps it inside the row).
22
22
  */
23
- export declare const DASHBOARD_SELECTABLE_ROW = "relative isolate before:pointer-events-none before:absolute before:inset-y-0 before:-inset-x-2 before:-z-10 before:rounded-md before:transition-colors has-[>button:hover]:before:bg-elevated/60 has-[>button:focus-visible]:before:bg-elevated/60";
23
+ export declare const DASHBOARD_SELECTABLE_ROW = "relative isolate before:pointer-events-none before:absolute before:inset-y-0 before:-inset-x-2 before:-z-10 before:rounded-md before:transition-colors has-[>:is(button,a):hover]:before:bg-elevated/60 has-[>:is(button,a):focus-visible]:before:bg-elevated/60";
24
24
  /**
25
25
  * A row shown as selected (`selected` prop): the same tint as the hover, stronger, and an accent
26
26
  * on its start edge, both drawn around the row box.
@@ -15,7 +15,7 @@ export const DASHBOARD_TABLE_CLASSES = {
15
15
  th: "px-2.5 pt-0.5 pb-2 text-xs font-medium whitespace-nowrap text-dimmed first:ps-0 last:pe-0",
16
16
  wrapper: "min-w-0 overflow-auto"
17
17
  };
18
- export const DASHBOARD_SELECTABLE_ROW = "relative isolate before:pointer-events-none before:absolute before:inset-y-0 before:-inset-x-2 before:-z-10 before:rounded-md before:transition-colors has-[>button:hover]:before:bg-elevated/60 has-[>button:focus-visible]:before:bg-elevated/60";
18
+ export const DASHBOARD_SELECTABLE_ROW = "relative isolate before:pointer-events-none before:absolute before:inset-y-0 before:-inset-x-2 before:-z-10 before:rounded-md before:transition-colors has-[>:is(button,a):hover]:before:bg-elevated/60 has-[>:is(button,a):focus-visible]:before:bg-elevated/60";
19
19
  export const DASHBOARD_SELECTED_ROW = "relative isolate before:pointer-events-none before:absolute before:inset-y-0 before:-inset-x-2 before:-z-10 before:rounded-md before:bg-elevated after:pointer-events-none after:absolute after:inset-y-2 after:-start-2 after:w-0.5 after:rounded-full after:bg-primary";
20
20
  export const DASHBOARD_ROW_BUTTON = "absolute inset-y-0 -inset-x-2 cursor-pointer rounded-md outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-inset";
21
21
  export const DASHBOARD_TABLE_ROW_BUTTON = "absolute inset-0 cursor-pointer outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-inset";
@@ -1,11 +1,8 @@
1
1
  <script setup>
2
2
  import UButton from "@nuxt/ui/components/Button.vue";
3
3
  import { computed } from "vue";
4
- import { getResponsiveValue } from "../../../shared/composables/use-responsive-value";
4
+ import { useFormActionButtons } from "../../composables/use-form-action-buttons";
5
5
  import { useFormUi } from "../../composables/use-form-ui";
6
- import { createPublicFormApi } from "../../utils/api";
7
- import { invokeFormFunction, isString } from "../../utils/predicate";
8
- import { resolveFormText } from "../../utils/text";
9
6
  import { mergeFormUiClass } from "../../utils/ui";
10
7
  const props = defineProps({
11
8
  runtime: { type: Object, required: true },
@@ -13,117 +10,24 @@ const props = defineProps({
13
10
  });
14
11
  const formUi = useFormUi();
15
12
  const emit = defineEmits(["cancel"]);
16
- const actionContext = computed(() => ({
17
- actionPending: props.runtime.actionPending.value,
18
- api: createPublicFormApi(props.runtime),
19
- currentStep: props.runtime.currentStepIndex.value,
20
- isFirstStep: props.runtime.isFirstStep.value,
21
- isLastStep: props.runtime.isLastStep.value,
22
- isMultiStep: props.runtime.isStepped.value
23
- }));
24
- const visibleActions = computed(
25
- () => props.actions.filter((action) => action.condition?.(actionContext.value) ?? true)
26
- );
13
+ const buttons = useFormActionButtons({
14
+ actions: () => props.actions,
15
+ onCancel: () => emit("cancel"),
16
+ runtime: props.runtime
17
+ });
27
18
  const actionsLeft = computed(
28
- () => visibleActions.value.filter((action) => resolveActionSlot(action) === "left")
19
+ () => buttons.visible.value.filter((action) => buttons.slot(action) === "left")
29
20
  );
30
21
  const actionsRight = computed(
31
- () => visibleActions.value.filter((action) => resolveActionSlot(action) !== "left")
22
+ () => buttons.visible.value.filter((action) => buttons.slot(action) !== "left")
32
23
  );
33
- async function runAction(action) {
34
- if (isBuiltInAction(action, "submit")) {
35
- return;
36
- }
37
- if (isBuiltInAction(action, "next")) {
38
- await props.runtime.nextStep();
39
- return;
40
- }
41
- if (isBuiltInAction(action, "previous")) {
42
- await props.runtime.previousStep();
43
- return;
44
- }
45
- if (isBuiltInAction(action, "reset")) {
46
- await props.runtime.reset();
47
- return;
48
- }
49
- if (isBuiltInAction(action, "cancel")) {
50
- emit("cancel");
51
- return;
52
- }
53
- if ("action" in action) {
54
- await action.action?.(actionContext.value);
55
- }
56
- }
57
- function resolveActionLabel(action) {
58
- return resolveFormText(action.label);
59
- }
60
- function resolveActionSlot(action) {
61
- const slot = getResponsiveValue(action.slot ?? "right");
62
- return slot === "left" ? "left" : "right";
63
- }
64
- function resolveActionWidth(action) {
65
- const width = getResponsiveValue(action.width ?? "fit");
66
- return width === "fill" ? "fill" : "fit";
67
- }
68
- function resolveActionLink(action) {
69
- if (!("link" in action)) {
70
- return;
71
- }
72
- if (isString(action.link)) {
73
- return action.link;
74
- }
75
- const link = invokeFormFunction(action.link, [actionContext.value]);
76
- return isString(link) ? link : void 0;
77
- }
78
- function isActionDisabled(action) {
79
- const disabled = action.disabled?.(actionContext.value) ?? false;
80
- if (disabled) {
81
- return true;
82
- }
83
- if (!props.runtime.actionPending.value) {
84
- return false;
85
- }
86
- return !isActionLoading(action);
87
- }
88
- function isActionLoading(action) {
89
- if (!isBuiltInActionKey(action.key)) {
90
- return false;
91
- }
92
- const pending = props.runtime.actionPending.value;
93
- if (pending === null) {
94
- return false;
95
- }
96
- return action.key === pending;
97
- }
98
- function resolveActionColor(action) {
99
- if (action.color) {
100
- return action.color;
101
- }
102
- if (action.type === "primary") {
103
- return "primary";
104
- }
105
- }
106
- function resolveActionVariant(action) {
107
- if (action.variant) {
108
- return action.variant;
109
- }
110
- if (action.type === "primary") {
111
- return "solid";
112
- }
113
- }
114
24
  function actionButtonClass(action) {
115
25
  return mergeFormUiClass(
116
- resolveActionWidth(action) === "fill" ? "flex-1 justify-center" : void 0,
26
+ buttons.fills(action) ? "flex-1 justify-center" : void 0,
117
27
  formUi.ui.value.actions?.ui?.button,
118
28
  action.class
119
29
  );
120
30
  }
121
- function isBuiltInAction(action, key) {
122
- return action.key === key;
123
- }
124
- function isBuiltInActionKey(value) {
125
- return value === "reset" || value === "cancel" || value === "submit" || value === "previous" || value === "next";
126
- }
127
31
  </script>
128
32
 
129
33
  <template>
@@ -147,18 +51,9 @@ function isBuiltInActionKey(value) {
147
51
  <UButton
148
52
  v-for="(action, index) in actionsLeft"
149
53
  :key="action.key ?? index"
150
- :type="isBuiltInAction(action, 'submit') ? 'submit' : 'button'"
151
- :to="resolveActionLink(action)"
152
- :label="resolveActionLabel(action)"
153
- :icon="action.icon === false ? void 0 : action.icon"
154
- :trailing-icon="action.trailingIcon === false ? void 0 : action.trailingIcon"
155
- :color="resolveActionColor(action)"
156
- :variant="resolveActionVariant(action)"
157
- :size="action.size ?? formUi.controlSize.value"
54
+ v-bind="buttons.button(action)"
158
55
  :class="actionButtonClass(action)"
159
- :disabled="isActionDisabled(action)"
160
- :loading="isActionLoading(action)"
161
- @click="runAction(action)"
56
+ @click="buttons.run(action)"
162
57
  />
163
58
  </div>
164
59
 
@@ -174,18 +69,9 @@ function isBuiltInActionKey(value) {
174
69
  <UButton
175
70
  v-for="(action, index) in actionsRight"
176
71
  :key="action.key ?? index"
177
- :type="isBuiltInAction(action, 'submit') ? 'submit' : 'button'"
178
- :to="resolveActionLink(action)"
179
- :label="resolveActionLabel(action)"
180
- :icon="action.icon === false ? void 0 : action.icon"
181
- :trailing-icon="action.trailingIcon === false ? void 0 : action.trailingIcon"
182
- :color="resolveActionColor(action)"
183
- :variant="resolveActionVariant(action)"
184
- :size="action.size ?? formUi.controlSize.value"
72
+ v-bind="buttons.button(action)"
185
73
  :class="actionButtonClass(action)"
186
- :disabled="isActionDisabled(action)"
187
- :loading="isActionLoading(action)"
188
- @click="runAction(action)"
74
+ @click="buttons.run(action)"
189
75
  />
190
76
  </div>
191
77
  </div>
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,40 @@
1
+ <script setup>
2
+ import UButton from "@nuxt/ui/components/Button.vue";
3
+ import { computed } from "vue";
4
+ import { useFormActionButtons } from "../../composables/use-form-action-buttons";
5
+ import { useFormActions } from "../../composables/use-form-actions";
6
+ import { useFormPageContext } from "../../composables/use-form-page";
7
+ import { useFormUi } from "../../composables/use-form-ui";
8
+ import { mergeFormUiClass } from "../../utils/ui";
9
+ const page = useFormPageContext();
10
+ const formUi = useFormUi();
11
+ const pageUi = computed(() => formUi.ui.value.page?.ui);
12
+ const actions = useFormActions({ runtime: page.root.runtime, slot: () => "right" });
13
+ const buttons = useFormActionButtons({
14
+ actions: () => actions.value,
15
+ onCancel: page.cancel,
16
+ runtime: page.root.runtime
17
+ });
18
+ function buttonClass(action) {
19
+ return mergeFormUiClass(
20
+ buttons.fills(action) ? "flex-1 justify-center" : void 0,
21
+ formUi.ui.value.actions?.ui?.button,
22
+ action.class
23
+ );
24
+ }
25
+ </script>
26
+
27
+ <template>
28
+ <div
29
+ :class="mergeFormUiClass('flex shrink-0 flex-wrap items-center gap-2', pageUi?.actions)"
30
+ data-form-page-actions
31
+ >
32
+ <UButton
33
+ v-for="(action, index) in buttons.visible.value"
34
+ :key="action.key ?? index"
35
+ v-bind="buttons.button(action)"
36
+ :class="buttonClass(action)"
37
+ @click="buttons.run(action)"
38
+ />
39
+ </div>
40
+ </template>
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;