nuxt-ui-tools 1.18.0 → 1.20.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 (64) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/form/components/page/form-page-header.d.vue.ts +3 -1
  3. package/dist/runtime/form/components/page/form-page-header.vue +44 -34
  4. package/dist/runtime/form/components/page/form-page-header.vue.d.ts +3 -1
  5. package/dist/runtime/form/components/page/form-page-section.vue +14 -0
  6. package/dist/runtime/form/components/page/form-page.vue +2 -1
  7. package/dist/runtime/form/components/utils/form-option-choice-label.d.vue.ts +16 -0
  8. package/dist/runtime/form/components/utils/form-option-choice-label.vue +37 -0
  9. package/dist/runtime/form/components/utils/form-option-choice-label.vue.d.ts +16 -0
  10. package/dist/runtime/form/components/utils/form-option-display-value.d.vue.ts +14 -0
  11. package/dist/runtime/form/components/utils/form-option-display-value.vue +20 -0
  12. package/dist/runtime/form/components/utils/form-option-display-value.vue.d.ts +14 -0
  13. package/dist/runtime/form/components/utils/form-option-item-label.d.vue.ts +9 -2
  14. package/dist/runtime/form/components/utils/form-option-item-label.vue +20 -13
  15. package/dist/runtime/form/components/utils/form-option-item-label.vue.d.ts +9 -2
  16. package/dist/runtime/form/components/utils/form-option-leading.d.vue.ts +23 -0
  17. package/dist/runtime/form/components/utils/form-option-leading.vue +41 -0
  18. package/dist/runtime/form/components/utils/form-option-leading.vue.d.ts +23 -0
  19. package/dist/runtime/form/components/utils/form-option-render.d.ts +11 -0
  20. package/dist/runtime/form/components/utils/form-option-render.js +5 -0
  21. package/dist/runtime/form/components/utils/form-option-suffix.d.vue.ts +8 -0
  22. package/dist/runtime/form/components/utils/form-option-suffix.vue +15 -0
  23. package/dist/runtime/form/components/utils/form-option-suffix.vue.d.ts +8 -0
  24. package/dist/runtime/form/components/utils/form-option-value-overlay.d.vue.ts +30 -0
  25. package/dist/runtime/form/components/utils/form-option-value-overlay.vue +44 -0
  26. package/dist/runtime/form/components/utils/form-option-value-overlay.vue.d.ts +30 -0
  27. package/dist/runtime/form/composables/use-choice-group-items.d.ts +27 -0
  28. package/dist/runtime/form/composables/use-choice-group-items.js +24 -0
  29. package/dist/runtime/form/composables/use-field-control.d.ts +5 -5
  30. package/dist/runtime/form/composables/use-form-layout.js +4 -3
  31. package/dist/runtime/form/composables/use-option-menu.d.ts +20 -0
  32. package/dist/runtime/form/composables/use-option-menu.js +41 -0
  33. package/dist/runtime/form/fields/auto-complete/component.vue +92 -51
  34. package/dist/runtime/form/fields/auto-complete/config.d.ts +1 -0
  35. package/dist/runtime/form/fields/auto-complete/config.js +1 -1
  36. package/dist/runtime/form/fields/auto-complete/types.d.ts +2 -2
  37. package/dist/runtime/form/fields/checkbox-card/component.vue +3 -3
  38. package/dist/runtime/form/fields/checkbox-card/types.d.ts +3 -3
  39. package/dist/runtime/form/fields/checkbox-group/component.vue +18 -4
  40. package/dist/runtime/form/fields/checkbox-group/types.d.ts +2 -2
  41. package/dist/runtime/form/fields/choice-card/types.d.ts +3 -22
  42. package/dist/runtime/form/fields/choice-card/utils.d.ts +0 -17
  43. package/dist/runtime/form/fields/choice-card/utils.js +0 -11
  44. package/dist/runtime/form/fields/index.d.ts +2 -0
  45. package/dist/runtime/form/fields/radio/component.vue +19 -2
  46. package/dist/runtime/form/fields/radio/types.d.ts +2 -2
  47. package/dist/runtime/form/fields/radio-card/component.vue +3 -3
  48. package/dist/runtime/form/fields/radio-card/types.d.ts +3 -3
  49. package/dist/runtime/form/fields/select/component.vue +56 -58
  50. package/dist/runtime/form/fields/select/config.d.ts +1 -0
  51. package/dist/runtime/form/fields/select/config.js +1 -1
  52. package/dist/runtime/form/fields/select/types.d.ts +2 -2
  53. package/dist/runtime/form/types/layout.d.ts +6 -0
  54. package/dist/runtime/form/types/options.d.ts +137 -0
  55. package/dist/runtime/form/types/page.d.ts +7 -0
  56. package/dist/runtime/form/types/ui.d.ts +7 -0
  57. package/dist/runtime/form/utils/options.d.ts +37 -13
  58. package/dist/runtime/form/utils/options.js +71 -0
  59. package/dist/runtime/form/utils/page-surface.d.ts +5 -0
  60. package/dist/runtime/form/utils/page-surface.js +1 -0
  61. package/dist/runtime/form/utils/page.js +1 -0
  62. package/dist/runtime/table/types/remote-options.d.ts +4 -1
  63. package/dist/runtime/table/utils/remote-table-options.js +1 -1
  64. package/package.json +1 -1
@@ -3,7 +3,32 @@ import { isRecord } from "./path.js";
3
3
  import { isBoolean, isFunction, isNumber, isString, isUndefined } from "./predicate.js";
4
4
  import { resolveFormText } from "./text.js";
5
5
  const DEFAULT_GROUP_KEY = "group";
6
+ const CHIP_COLORS = [
7
+ "primary",
8
+ "secondary",
9
+ "success",
10
+ "info",
11
+ "warning",
12
+ "error",
13
+ "neutral"
14
+ ];
15
+ export function resolveOptionLeading(option) {
16
+ if (option.icon) return "icon";
17
+ if (option.avatar) return "avatar";
18
+ if (option.chip) return "chip";
19
+ return void 0;
20
+ }
21
+ const DESCRIPTION_INDENT = {
22
+ avatar: "ps-8",
23
+ chip: "ps-6",
24
+ icon: "ps-6"
25
+ };
26
+ export function resolveOptionDescriptionIndent(option) {
27
+ const leading = resolveOptionLeading(option);
28
+ return leading ? DESCRIPTION_INDENT[leading] : void 0;
29
+ }
6
30
  export function normalizeOptionItem(option, keys = {}) {
31
+ const item = isFormOptionItem(option) ? option : void 0;
7
32
  if (isRecord(option)) {
8
33
  const rawValue = readOptionProperty(option, keys.value ?? "value");
9
34
  const fallbackValue = isUndefined(rawValue) ? option.key : rawValue;
@@ -14,12 +39,17 @@ export function normalizeOptionItem(option, keys = {}) {
14
39
  const lazy = option.isLeaf === false || option.hasChildren === true;
15
40
  const value = normalizeOptionValue(fallbackValue);
16
41
  const rawIcon = readOptionProperty(option, "icon");
42
+ const rawSuffix = readOptionProperty(option, "suffix");
17
43
  const normalized = {
44
+ avatar: normalizeOptionAvatar(readOptionProperty(option, "avatar")),
45
+ chip: normalizeOptionChip(readOptionProperty(option, "chip")),
18
46
  description: isFormText(rawDescription) ? resolveFormText(rawDescription) : void 0,
19
47
  disabled: option.disabled === true,
20
48
  group: isFormText(rawGroup) ? resolveFormText(rawGroup) : void 0,
21
49
  icon: isString(rawIcon) ? rawIcon : void 0,
50
+ item,
22
51
  label: resolveFormText(readOptionProperty(option, keys.label ?? "label")) ?? String(value),
52
+ suffix: isFormText(rawSuffix) ? resolveFormText(rawSuffix) : void 0,
23
53
  value
24
54
  };
25
55
  if (children) {
@@ -33,10 +63,27 @@ export function normalizeOptionItem(option, keys = {}) {
33
63
  return normalized;
34
64
  }
35
65
  return {
66
+ item,
36
67
  label: String(option),
37
68
  value: normalizeOptionValue(option)
38
69
  };
39
70
  }
71
+ function isFormOptionItem(value) {
72
+ return isOptionValue(value) || isRecord(value);
73
+ }
74
+ function normalizeOptionAvatar(raw) {
75
+ if (!isRecord(raw)) return void 0;
76
+ const { alt, src, text } = raw;
77
+ return {
78
+ alt: isString(alt) ? alt : void 0,
79
+ src: isString(src) ? src : void 0,
80
+ text: isString(text) ? text : void 0
81
+ };
82
+ }
83
+ function normalizeOptionChip(raw) {
84
+ if (!isRecord(raw)) return void 0;
85
+ return { color: CHIP_COLORS.find((color) => color === raw.color) };
86
+ }
40
87
  export function normalizeOptionItems(options, keys = {}) {
41
88
  return (options ?? []).map((option) => normalizeOptionItem(option, keys));
42
89
  }
@@ -51,6 +98,17 @@ export function resolveOptionGroupKey(field) {
51
98
  if (isString(mapped) && mapped) return mapped;
52
99
  return Array.isArray(readOptionSource(field)) ? DEFAULT_GROUP_KEY : void 0;
53
100
  }
101
+ export function groupOptions(items) {
102
+ const groups = /* @__PURE__ */ new Map();
103
+ for (const item of items) {
104
+ const key = item.group?.trim() ?? "";
105
+ const members = groups.get(key);
106
+ if (members) members.push(item);
107
+ else groups.set(key, [item]);
108
+ }
109
+ if (groups.size === 0) return [{ items: [], key: "" }];
110
+ return [...groups].map(([key, members]) => ({ heading: key || void 0, items: members, key }));
111
+ }
54
112
  export const LOAD_MORE_OPTION_VALUE = "__nut:load-more__";
55
113
  export function isLoadMoreOption(item) {
56
114
  return isRecord(item) && item.value === LOAD_MORE_OPTION_VALUE;
@@ -61,6 +119,19 @@ export function appendLoadMoreOption(items, show, label) {
61
119
  }
62
120
  return [...items, { disabled: true, label, value: LOAD_MORE_OPTION_VALUE }];
63
121
  }
122
+ function menuHeading(heading) {
123
+ return { label: heading, type: "label", value: "" };
124
+ }
125
+ export function toMenuItems(options, loadMore) {
126
+ const groups = groupOptions(options);
127
+ if (!groups.some((group) => group.heading)) {
128
+ return [...appendLoadMoreOption(options, loadMore.show, loadMore.label)];
129
+ }
130
+ const nested = groups.map(
131
+ (group) => group.heading ? [menuHeading(group.heading), ...group.items] : group.items
132
+ );
133
+ return loadMore.show ? [...nested, [...appendLoadMoreOption([], true, loadMore.label)]] : nested;
134
+ }
64
135
  export function formOptionKey(value) {
65
136
  const type = isString(value) ? "string" : isNumber(value) ? "number" : isBoolean(value) ? "boolean" : "unknown";
66
137
  return `${type}:${String(value)}`;
@@ -15,6 +15,11 @@ export interface FormPageSurfaceClasses {
15
15
  /** Placeholder shown while the schema context loads. */
16
16
  sectionSkeleton: string;
17
17
  }
18
+ /**
19
+ * The centered column of a page without a navigation. The body and the row of the header share
20
+ * it, so both start and end on the same edges, padding included.
21
+ */
22
+ export declare const FORM_PAGE_COLUMN = "mx-auto w-full max-w-[816px]";
18
23
  export declare const DEFAULT_FORM_PAGE_SURFACE: FormPageSurface;
19
24
  /** The surface a page draws its sections with, `card` unless the config names a known one. */
20
25
  export declare function resolveFormPageSurface(value: FormValue): FormPageSurface;
@@ -1,4 +1,5 @@
1
1
  import { isString } from "./predicate.js";
2
+ export const FORM_PAGE_COLUMN = "mx-auto w-full max-w-[816px]";
2
3
  export const DEFAULT_FORM_PAGE_SURFACE = "card";
3
4
  const FORM_PAGE_SURFACES = {
4
5
  card: {
@@ -69,6 +69,7 @@ export function resolveFormPageSectionState(params) {
69
69
  return {
70
70
  description: resolveFormText(entry.section.description),
71
71
  dirty: dirtyPaths.length > 0,
72
+ icon: entry.section.icon,
72
73
  dirtyPaths,
73
74
  index: params.index,
74
75
  key: entry.section.key,
@@ -39,7 +39,10 @@ export interface RemoteTableOptionsConfig<TRow extends GenericObject, TOption ex
39
39
  * values the loaded pages do not contain. Defaults to `'id'`.
40
40
  */
41
41
  valueKey?: TableKnownFieldPath<TRow> | 'id';
42
- /** Filters applied to every request, e.g. active accounts only. */
42
+ /**
43
+ * Filters applied to every page request, e.g. active accounts only. The lookup of selected
44
+ * values ignores them, so a value the filters now exclude still shows its label.
45
+ */
43
46
  filters?: readonly TableResolvedFilterGroup<TableKnownFieldPath<TRow> | string>[];
44
47
  /** Page type and size. Must match what the endpoint pages by. Defaults to cursor pages of 25. */
45
48
  pagination?: RemoteOptionsPagination;
@@ -8,7 +8,7 @@ export function remoteTableOptions(query, config) {
8
8
  function request(params) {
9
9
  const { page } = params;
10
10
  return {
11
- filters: [...config.filters ?? [], ...params.filters ?? []],
11
+ filters: params.filters ?? [...config.filters ?? []],
12
12
  pagination: pagination.type === "cursor" ? { count: "none", cursor: page.cursor, mode: "cursor", pageSize: page.size } : { count: "exact", mode: "offset", pageIndex: page.index - 1, pageSize: page.size },
13
13
  search: { fields: [...fields], value: params.search },
14
14
  sorting: params.filters ? [] : [...sorting]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuxt-ui-tools",
3
- "version": "1.18.0",
3
+ "version": "1.20.0",
4
4
  "description": "Nuxt module and runtime toolkit for UI-heavy Nuxt applications",
5
5
  "homepage": "https://github.com/ChronicStone/nuxt-ui-tools#readme",
6
6
  "bugs": "https://github.com/ChronicStone/nuxt-ui-tools/issues",