@xleddyl/443-components-vue 0.8.1 → 0.8.3

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 (164) hide show
  1. package/README.md +52 -4
  2. package/dist/chart/BarChart.vue +33 -22
  3. package/dist/chart/BarChart.vue.d.ts +4 -0
  4. package/dist/chart/chart.css +2 -2
  5. package/dist/chart/useChartColors.mjs +8 -8
  6. package/dist/components/core/Button.vue.d.ts +1 -1
  7. package/dist/components/core/FormField.vue +5 -0
  8. package/dist/components/core/FormField.vue.d.ts +4 -0
  9. package/dist/components/core/Input.vue +59 -5
  10. package/dist/components/core/Input.vue.d.ts +9 -5
  11. package/dist/components/core/Textarea.vue +28 -3
  12. package/dist/components/core/Textarea.vue.d.ts +7 -5
  13. package/dist/components/core/types.d.ts +1 -1
  14. package/dist/components/data/Badge.vue.d.ts +1 -1
  15. package/dist/components/data/DescriptionList.vue.d.ts +1 -1
  16. package/dist/components/data/FilterPills.vue +43 -4
  17. package/dist/components/data/FilterPills.vue.d.ts +4 -1
  18. package/dist/components/data/Pagination.vue +63 -2
  19. package/dist/components/data/Pagination.vue.d.ts +12 -0
  20. package/dist/components/data/Tag.vue.d.ts +1 -1
  21. package/dist/components/data/Tree.vue.d.ts +1 -1
  22. package/dist/components/data/types.d.ts +1 -0
  23. package/dist/components/feedback/Meter.vue.d.ts +1 -1
  24. package/dist/components/feedback/Progress.vue.d.ts +1 -1
  25. package/dist/components/feedback/ProgressRing.vue.d.ts +1 -1
  26. package/dist/components/forms/Calendar.vue +31 -7
  27. package/dist/components/forms/Calendar.vue.d.ts +13 -2
  28. package/dist/components/forms/CheckboxGroup.vue +7 -1
  29. package/dist/components/forms/CheckboxGroup.vue.d.ts +1 -0
  30. package/dist/components/forms/ColorInput.vue.d.ts +5 -5
  31. package/dist/components/forms/Combobox.vue +4 -3
  32. package/dist/components/forms/Combobox.vue.d.ts +1 -0
  33. package/dist/components/forms/DateInput.vue.d.ts +10 -6
  34. package/dist/components/forms/DatePicker.vue.d.ts +1 -1
  35. package/dist/components/forms/FileInput.vue.d.ts +1 -1
  36. package/dist/components/forms/NumberInput.vue.d.ts +5 -5
  37. package/dist/components/forms/PasswordInput.vue.d.ts +9 -5
  38. package/dist/components/forms/PinInput.vue.d.ts +5 -5
  39. package/dist/components/forms/Select.vue +21 -2
  40. package/dist/components/forms/Select.vue.d.ts +4 -4
  41. package/dist/components/forms/Slider.vue.d.ts +5 -5
  42. package/dist/components/forms/Switch.vue.d.ts +1 -1
  43. package/dist/components/forms/TimeInput.vue.d.ts +9 -5
  44. package/dist/components/layout/AppShell.vue +4 -2
  45. package/dist/components/layout/AppShell.vue.d.ts +2 -0
  46. package/dist/components/layout/Card.vue.d.ts +1 -1
  47. package/dist/components/layout/CopyButton.vue.d.ts +1 -1
  48. package/dist/components/layout/PageHeader.vue +15 -3
  49. package/dist/components/layout/PageHeader.vue.d.ts +5 -0
  50. package/dist/components/layout/Separator.vue +17 -4
  51. package/dist/components/layout/Separator.vue.d.ts +7 -1
  52. package/dist/components/layout/Tabs.vue +10 -0
  53. package/dist/components/layout/types.d.ts +3 -0
  54. package/dist/components/overlays/ConfirmDialog.vue.d.ts +8 -4
  55. package/dist/components/overlays/ConfirmHost.vue.d.ts +8 -4
  56. package/dist/components/overlays/ContextMenu.vue.d.ts +4 -2
  57. package/dist/components/overlays/DropdownMenu.vue +5 -1
  58. package/dist/components/overlays/DropdownMenu.vue.d.ts +8 -2
  59. package/dist/components/overlays/Modal.vue +9 -2
  60. package/dist/components/overlays/Modal.vue.d.ts +4 -0
  61. package/dist/components/overlays/types.d.ts +2 -2
  62. package/dist/components/templates/DashboardLayout.vue +2 -0
  63. package/dist/components/templates/DashboardLayout.vue.d.ts +2 -0
  64. package/dist/components/templates/SettingsModal.vue.d.ts +8 -4
  65. package/dist/components/templates/types.d.ts +1 -0
  66. package/dist/composables/useForm.d.ts +24 -2
  67. package/dist/composables/useForm.mjs +51 -8
  68. package/dist/composables/useOverlay.d.ts +1 -1
  69. package/dist/editor/RichTextEditor.vue +108 -10
  70. package/dist/editor/RichTextEditor.vue.d.ts +5 -2
  71. package/dist/editor/rich-text-editor.css +31 -4
  72. package/dist/editor/types.d.ts +2 -1
  73. package/dist/grid/DataGrid.vue +106 -24
  74. package/dist/grid/DataGrid.vue.d.ts +14 -2
  75. package/dist/grid/cells/DateCell.vue +18 -3
  76. package/dist/grid/cells/ImageCell.vue +6 -1
  77. package/dist/grid/data-grid.css +17 -3
  78. package/dist/grid/index.d.ts +2 -1
  79. package/dist/grid/index.mjs +6 -1
  80. package/dist/grid/modules.d.ts +2 -0
  81. package/dist/grid/modules.mjs +32 -0
  82. package/dist/grid/theme.mjs +5 -5
  83. package/dist/grid/types.d.ts +4 -0
  84. package/dist/icons/builtin.d.ts +3 -0
  85. package/dist/icons/builtin.mjs +3 -0
  86. package/dist/index.d.ts +1 -1
  87. package/dist/index.mjs +1 -0
  88. package/dist/internal/core/intl.d.ts +2 -0
  89. package/dist/internal/core/intl.mjs +17 -0
  90. package/dist/internal/forms/counter.d.ts +18 -0
  91. package/dist/internal/forms/counter.mjs +31 -0
  92. package/dist/internal/keys.d.ts +2 -1
  93. package/dist/internal/keys.mjs +1 -0
  94. package/dist/internal/overlays/MenuList.vue +4 -2
  95. package/dist/internal/overlays/MenuList.vue.d.ts +2 -0
  96. package/dist/internal/overlays/OverlayView.vue.d.ts +8 -4
  97. package/dist/locale/de.mjs +21 -3
  98. package/dist/locale/en.mjs +21 -3
  99. package/dist/locale/it.mjs +21 -3
  100. package/dist/locale/types.d.ts +18 -0
  101. package/dist/nuxt/runtime/layouts/dashboard.vue +1 -0
  102. package/dist/styles/base.css +2 -1
  103. package/dist/styles/core/button.css +42 -16
  104. package/dist/styles/core/form-field.css +7 -1
  105. package/dist/styles/core/input.css +31 -2
  106. package/dist/styles/core/kbd.css +1 -1
  107. package/dist/styles/core/textarea.css +10 -0
  108. package/dist/styles/data/avatar.css +1 -1
  109. package/dist/styles/data/badge.css +39 -23
  110. package/dist/styles/data/description-list.css +2 -2
  111. package/dist/styles/data/filter-pills.css +24 -3
  112. package/dist/styles/data/pagination.css +26 -3
  113. package/dist/styles/data/selection-bar.css +1 -1
  114. package/dist/styles/data/stat.css +4 -4
  115. package/dist/styles/data/table.css +4 -4
  116. package/dist/styles/data/tag.css +1 -1
  117. package/dist/styles/data/timeline.css +1 -1
  118. package/dist/styles/data/tree.css +2 -2
  119. package/dist/styles/feedback/empty-state.css +1 -1
  120. package/dist/styles/feedback/loading-host.css +1 -1
  121. package/dist/styles/feedback/loading-overlay.css +1 -1
  122. package/dist/styles/feedback/meter.css +1 -1
  123. package/dist/styles/feedback/progress.css +2 -2
  124. package/dist/styles/forced-colors.css +6 -1
  125. package/dist/styles/forms/calendar.css +30 -3
  126. package/dist/styles/forms/checkbox.css +1 -1
  127. package/dist/styles/forms/choice.css +7 -1
  128. package/dist/styles/forms/combobox.css +2 -2
  129. package/dist/styles/forms/file-input.css +1 -1
  130. package/dist/styles/forms/password-input.css +1 -1
  131. package/dist/styles/forms/pin-input.css +1 -1
  132. package/dist/styles/forms/radio.css +1 -1
  133. package/dist/styles/forms/segmented.css +2 -2
  134. package/dist/styles/forms/select.css +2 -2
  135. package/dist/styles/forms/slider.css +1 -1
  136. package/dist/styles/forms/switch.css +4 -4
  137. package/dist/styles/layout/accordion.css +2 -2
  138. package/dist/styles/layout/app-shell.css +18 -6
  139. package/dist/styles/layout/breadcrumbs.css +3 -3
  140. package/dist/styles/layout/card.css +1 -1
  141. package/dist/styles/layout/nav-link.css +1 -1
  142. package/dist/styles/layout/page-header.css +21 -1
  143. package/dist/styles/layout/separator.css +21 -1
  144. package/dist/styles/layout/sidebar.css +1 -1
  145. package/dist/styles/layout/tabs.css +30 -1
  146. package/dist/styles/layout/theme-switch.css +1 -1
  147. package/dist/styles/overlays/command.css +3 -3
  148. package/dist/styles/overlays/drawer.css +4 -3
  149. package/dist/styles/overlays/floating.css +2 -2
  150. package/dist/styles/overlays/menu.css +5 -1
  151. package/dist/styles/overlays/modal.css +12 -9
  152. package/dist/styles/overlays/toast.css +3 -3
  153. package/dist/styles/overlays/tooltip.css +26 -8
  154. package/dist/styles/shared.css +2 -2
  155. package/dist/styles/templates/account-menu.css +1 -1
  156. package/dist/styles/templates/auth-layout.css +4 -4
  157. package/dist/styles/templates/brand.css +2 -2
  158. package/dist/styles/templates/dashboard-page.css +1 -1
  159. package/dist/styles/templates/empty-page.css +3 -3
  160. package/dist/styles/templates/error-page.css +1 -1
  161. package/dist/styles/templates/save-bar.css +1 -1
  162. package/dist/styles/templates/settings-modal.css +6 -6
  163. package/dist/styles/utilities.css +3 -3
  164. package/package.json +1 -1
@@ -2,7 +2,8 @@
2
2
  <img
3
3
  v-if="src"
4
4
  class="k-data-grid-image"
5
- :class="{ 'is-rounded': params.rounded }"
5
+ :class="{ 'is-rounded': params.rounded, 'is-contain': params.fit === 'contain' }"
6
+ :style="sizeStyle"
6
7
  :src="src"
7
8
  :alt="alt"
8
9
  loading="lazy"
@@ -12,6 +13,7 @@
12
13
  v-else
13
14
  class="k-data-grid-image is-empty"
14
15
  :class="{ 'is-rounded': params.rounded }"
16
+ :style="sizeStyle"
15
17
  aria-hidden="true"
16
18
  >
17
19
  <Icon name="photo" />
@@ -28,5 +30,8 @@ const src = computed(() => {
28
30
  const raw = props.params.value;
29
31
  return typeof raw === "string" && raw ? raw : "";
30
32
  });
33
+ const sizeStyle = computed(
34
+ () => props.params.size ? { "--k-grid-image-size": props.params.size } : void 0
35
+ );
31
36
  const alt = computed(() => props.params.alt?.(props.params.data) ?? "");
32
37
  </script>
@@ -33,6 +33,16 @@
33
33
  min-height: 8rem;
34
34
  }
35
35
 
36
+ .k-data-grid.is-fill {
37
+ flex: 1 1 0%;
38
+ height: 100%;
39
+ min-height: 0;
40
+ }
41
+
42
+ .k-data-grid.is-fill > .k-data-grid-body {
43
+ flex: 1 1 0%;
44
+ }
45
+
36
46
  .k-data-grid-ag {
37
47
  height: 100%;
38
48
  }
@@ -144,7 +154,7 @@
144
154
  align-items: center;
145
155
  padding: 0.125rem 0.5rem;
146
156
  font-size: 0.75rem;
147
- font-weight: 500;
157
+ font-weight: var(--k-font-weight-medium, 500);
148
158
  line-height: 1.2;
149
159
  color: var(--k-badge-tone);
150
160
  background: color-mix(in oklab, var(--k-badge-tone) 12%, transparent);
@@ -174,8 +184,8 @@
174
184
 
175
185
  .k-data-grid-image {
176
186
  display: block;
177
- width: 1.75rem;
178
- height: 1.75rem;
187
+ width: var(--k-grid-image-size, 1.75rem);
188
+ height: var(--k-grid-image-size, 1.75rem);
179
189
  object-fit: cover;
180
190
  background: var(--k-fill);
181
191
  border-radius: var(--k-radius-sm);
@@ -188,6 +198,10 @@
188
198
  --k-icon-size: 1rem;
189
199
  }
190
200
 
201
+ .k-data-grid-image.is-contain {
202
+ object-fit: contain;
203
+ }
204
+
191
205
  .k-data-grid-image.is-rounded {
192
206
  border-radius: var(--k-radius-full);
193
207
  }
@@ -2,9 +2,10 @@ export { default as DataGrid } from './DataGrid.vue';
2
2
  export { default as GridToolbar } from './GridToolbar.vue';
3
3
  export { default as BooleanCell } from './cells/BooleanCell.vue';
4
4
  export { default as DateCell } from './cells/DateCell.vue';
5
+ export { default as EmptyCell } from './cells/EmptyCell.vue';
5
6
  export { default as BadgeCell } from './cells/BadgeCell.vue';
6
7
  export { default as ImageCell } from './cells/ImageCell.vue';
7
8
  export { default as LinkCell } from './cells/LinkCell.vue';
8
- export { registerGridModules } from './modules';
9
+ export { registerGridEditorModules, registerGridFilterModules, registerGridModules, } from './modules';
9
10
  export { createGridTheme } from './theme';
10
11
  export type * from './types';
@@ -2,8 +2,13 @@ export { default as DataGrid } from "./DataGrid.vue";
2
2
  export { default as GridToolbar } from "./GridToolbar.vue";
3
3
  export { default as BooleanCell } from "./cells/BooleanCell.vue";
4
4
  export { default as DateCell } from "./cells/DateCell.vue";
5
+ export { default as EmptyCell } from "./cells/EmptyCell.vue";
5
6
  export { default as BadgeCell } from "./cells/BadgeCell.vue";
6
7
  export { default as ImageCell } from "./cells/ImageCell.vue";
7
8
  export { default as LinkCell } from "./cells/LinkCell.vue";
8
- export { registerGridModules } from "./modules.mjs";
9
+ export {
10
+ registerGridEditorModules,
11
+ registerGridFilterModules,
12
+ registerGridModules
13
+ } from "./modules.mjs";
9
14
  export { createGridTheme } from "./theme.mjs";
@@ -1 +1,3 @@
1
1
  export declare function registerGridModules(): void;
2
+ export declare function registerGridFilterModules(): void;
3
+ export declare function registerGridEditorModules(): void;
@@ -1,21 +1,32 @@
1
1
  import {
2
2
  CellApiModule,
3
+ CheckboxEditorModule,
4
+ CustomEditorModule,
5
+ DateEditorModule,
6
+ LargeTextEditorModule,
7
+ NumberEditorModule,
8
+ SelectEditorModule,
9
+ TextEditorModule,
10
+ UndoRedoEditModule,
3
11
  CellStyleModule,
4
12
  ClientSideRowModelApiModule,
5
13
  ClientSideRowModelModule,
6
14
  ColumnApiModule,
7
15
  ColumnAutoSizeModule,
8
16
  CsvExportModule,
17
+ DateFilterModule,
9
18
  DragAndDropModule,
10
19
  EventApiModule,
11
20
  LocaleModule,
12
21
  ModuleRegistry,
22
+ NumberFilterModule,
13
23
  PaginationModule,
14
24
  QuickFilterModule,
15
25
  RenderApiModule,
16
26
  RowApiModule,
17
27
  RowAutoHeightModule,
18
28
  RowSelectionModule,
29
+ TextFilterModule,
19
30
  TooltipModule
20
31
  } from "ag-grid-community";
21
32
  let registered = false;
@@ -42,3 +53,24 @@ export function registerGridModules() {
42
53
  TooltipModule
43
54
  ]);
44
55
  }
56
+ let filtersRegistered = false;
57
+ export function registerGridFilterModules() {
58
+ if (filtersRegistered) return;
59
+ filtersRegistered = true;
60
+ ModuleRegistry.registerModules([TextFilterModule, NumberFilterModule, DateFilterModule]);
61
+ }
62
+ let editorsRegistered = false;
63
+ export function registerGridEditorModules() {
64
+ if (editorsRegistered) return;
65
+ editorsRegistered = true;
66
+ ModuleRegistry.registerModules([
67
+ TextEditorModule,
68
+ LargeTextEditorModule,
69
+ NumberEditorModule,
70
+ DateEditorModule,
71
+ CheckboxEditorModule,
72
+ SelectEditorModule,
73
+ CustomEditorModule,
74
+ UndoRedoEditModule
75
+ ]);
76
+ }
@@ -17,21 +17,21 @@ export function createGridTheme(density) {
17
17
  headerBackgroundColor: "var(--k-grid-header-background, var(--k-subtle))",
18
18
  headerTextColor: "var(--k-grid-header-text, var(--k-text-muted))",
19
19
  headerFontFamily: "var(--k-grid-header-font, var(--k-font-sans))",
20
- headerFontSize: 12,
21
- headerFontWeight: 500,
20
+ headerFontSize: "var(--k-grid-header-font-size, 12px)",
21
+ headerFontWeight: "var(--k-grid-header-font-weight, var(--k-font-weight-medium, 500))",
22
22
  headerRowBorder: { color: "var(--k-line)" },
23
23
  headerColumnBorder: false,
24
24
  rowBorder: { color: "var(--k-line)" },
25
25
  columnBorder: false,
26
26
  rowHoverColor: "var(--k-hover)",
27
- selectedRowBackgroundColor: "var(--k-accent-soft)",
27
+ selectedRowBackgroundColor: "var(--k-grid-selected-background, var(--k-accent-soft))",
28
28
  oddRowBackgroundColor: "transparent",
29
29
  fontFamily: "var(--k-font-sans)",
30
- fontSize: 13,
30
+ fontSize: "var(--k-grid-font-size, 13px)",
31
31
  iconSize: 14,
32
32
  spacing: spacingByDensity[density],
33
33
  borderRadius: "var(--k-radius-sm)",
34
- wrapperBorderRadius: "var(--k-radius-lg)",
34
+ wrapperBorderRadius: "var(--k-grid-radius, var(--k-radius-lg))",
35
35
  wrapperBorder: { color: "var(--k-line)" },
36
36
  menuBackgroundColor: "var(--k-elevated)",
37
37
  menuShadow: "var(--k-shadow-overlay)",
@@ -38,15 +38,19 @@ export interface BooleanCellParams {
38
38
  export interface DateCellParams {
39
39
  locale?: string;
40
40
  options?: Intl.DateTimeFormatOptions;
41
+ relative?: boolean | Intl.RelativeTimeFormatOptions;
41
42
  }
42
43
  export interface BadgeCellParams {
43
44
  tones?: Record<string, Tone>;
44
45
  labels?: Record<string, string>;
45
46
  defaultTone?: Tone;
46
47
  }
48
+ export type ImageCellFit = 'cover' | 'contain';
47
49
  export interface ImageCellParams<T = unknown> {
48
50
  alt?: (data: T | undefined) => string;
49
51
  rounded?: boolean;
52
+ fit?: ImageCellFit;
53
+ size?: string;
50
54
  }
51
55
  export interface LinkCellParams<T = unknown> {
52
56
  href?: (value: unknown, data: T | undefined) => string;
@@ -8,6 +8,9 @@ export declare const builtinIcons: {
8
8
  readonly 'chevron-left': readonly ["M15.75 19.5 8.25 12l7.5-7.5"];
9
9
  readonly 'chevron-right': readonly ["m8.25 4.5 7.5 7.5-7.5 7.5"];
10
10
  readonly 'chevron-up-down': readonly ["M8.25 15 12 18.75 15.75 15m-7.5-6L12 5.25 15.75 9"];
11
+ readonly 'chevron-double-left': readonly ["m18.75 4.5-7.5 7.5 7.5 7.5m-6-15L5.25 12l7.5 7.5"];
12
+ readonly 'chevron-double-right': readonly ["m5.25 4.5 7.5 7.5-7.5 7.5m6-15 7.5 7.5-7.5 7.5"];
13
+ readonly underline: readonly ["M17.995 3.744v7.5a6 6 0 1 1-12 0v-7.5m-2.25 16.502h16.5"];
11
14
  readonly 'arrow-path': readonly ["M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99"];
12
15
  readonly 'arrow-right': readonly ["M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3"];
13
16
  readonly 'arrow-left': readonly ["M10.5 19.5 3 12m0 0 7.5-7.5M3 12h18"];
@@ -8,6 +8,9 @@ export const builtinIcons = {
8
8
  "chevron-left": ["M15.75 19.5 8.25 12l7.5-7.5"],
9
9
  "chevron-right": ["m8.25 4.5 7.5 7.5-7.5 7.5"],
10
10
  "chevron-up-down": ["M8.25 15 12 18.75 15.75 15m-7.5-6L12 5.25 15.75 9"],
11
+ "chevron-double-left": ["m18.75 4.5-7.5 7.5 7.5 7.5m-6-15L5.25 12l7.5 7.5"],
12
+ "chevron-double-right": ["m5.25 4.5 7.5 7.5-7.5 7.5m6-15 7.5 7.5-7.5 7.5"],
13
+ underline: ["M17.995 3.744v7.5a6 6 0 1 1-12 0v-7.5m-2.25 16.502h16.5"],
11
14
  "arrow-path": [
12
15
  "M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99"
13
16
  ],
package/dist/index.d.ts CHANGED
@@ -11,5 +11,5 @@ export { builtinLocales, de, defineLocale, en, it } from './locale';
11
11
  export type { DefineLocaleOptions } from './locale';
12
12
  export type * from './locale/types';
13
13
  export type { BuiltinIconName } from './icons/builtin';
14
- export { FIELD_KEY, FORM_KEY, ICON_USAGE_KEY, ICONS_KEY, LINK_KEY, LOCALE_KEY, PRESET_KEY, THEME_KEY, } from './internal/keys';
14
+ export { FIELD_KEY, FORM_CONFIG_KEY, FORM_KEY, ICON_USAGE_KEY, ICONS_KEY, LINK_KEY, LOCALE_KEY, PRESET_KEY, THEME_KEY, } from './internal/keys';
15
15
  export type * from './types/dom';
package/dist/index.mjs CHANGED
@@ -10,6 +10,7 @@ export { builtinIcons } from "./icons/builtin.mjs";
10
10
  export { builtinLocales, de, defineLocale, en, it } from "./locale/index.mjs";
11
11
  export {
12
12
  FIELD_KEY,
13
+ FORM_CONFIG_KEY,
13
14
  FORM_KEY,
14
15
  ICON_USAGE_KEY,
15
16
  ICONS_KEY,
@@ -2,3 +2,5 @@ export declare const numberFormat: (locale?: string, options?: Intl.NumberFormat
2
2
  export declare const dateTimeFormat: (locale?: string, options?: Intl.DateTimeFormatOptions) => Intl.DateTimeFormat;
3
3
  export declare const pluralRules: (locale?: string, options?: Intl.PluralRulesOptions) => Intl.PluralRules;
4
4
  export declare const collator: (locale?: string, options?: Intl.CollatorOptions) => Intl.Collator;
5
+ export declare const relativeTimeFormat: (locale?: string, options?: Intl.RelativeTimeFormatOptions) => Intl.RelativeTimeFormat;
6
+ export declare function formatRelativeTime(date: Date, locale?: string, options?: Intl.RelativeTimeFormatOptions, now?: number): string;
@@ -22,3 +22,20 @@ export const pluralRules = cachedIntl(
22
22
  export const collator = cachedIntl(
23
23
  (locale, options) => new Intl.Collator(locale, options)
24
24
  );
25
+ export const relativeTimeFormat = cachedIntl(
26
+ (locale, options) => new Intl.RelativeTimeFormat(locale, options)
27
+ );
28
+ const relativeUnits = [
29
+ ["year", 31536e3],
30
+ ["month", 2592e3],
31
+ ["week", 604800],
32
+ ["day", 86400],
33
+ ["hour", 3600],
34
+ ["minute", 60],
35
+ ["second", 1]
36
+ ];
37
+ export function formatRelativeTime(date, locale, options = { numeric: "auto" }, now = Date.now()) {
38
+ const seconds = Math.round((date.getTime() - now) / 1e3);
39
+ const [unit, size] = relativeUnits.find(([, length]) => Math.abs(seconds) >= length) ?? relativeUnits.at(-1);
40
+ return relativeTimeFormat(locale, options).format(Math.round(seconds / size), unit);
41
+ }
@@ -0,0 +1,18 @@
1
+ interface CharacterCounterOptions {
2
+ enabled: () => boolean | undefined;
3
+ value: () => unknown;
4
+ attrs: Record<string, unknown>;
5
+ }
6
+ export interface CharacterCounterState {
7
+ id: string;
8
+ visible: boolean;
9
+ length: number;
10
+ max: number;
11
+ atLimit: boolean;
12
+ text: string;
13
+ label: string;
14
+ limitMessage: string;
15
+ width: number;
16
+ }
17
+ export declare function useCharacterCounter(options: CharacterCounterOptions): () => CharacterCounterState;
18
+ export {};
@@ -0,0 +1,31 @@
1
+ import { useId } from "vue";
2
+ import { useLocale } from "../../composables/useLocale.mjs";
3
+ function readLimit(attrs) {
4
+ const raw = attrs.maxlength ?? attrs.maxLength;
5
+ if (raw === void 0 || raw === null || raw === "" || raw === false) return void 0;
6
+ const limit = Number(raw);
7
+ return Number.isFinite(limit) && limit >= 0 ? Math.trunc(limit) : void 0;
8
+ }
9
+ export function useCharacterCounter(options) {
10
+ const { t } = useLocale();
11
+ const id = useId();
12
+ return () => {
13
+ const max = readLimit(options.attrs);
14
+ const visible = Boolean(options.enabled()) && max !== void 0;
15
+ const value = options.value();
16
+ const length = value === null || value === void 0 ? 0 : String(value).length;
17
+ const limit = max ?? 0;
18
+ const atLimit = visible && length >= limit;
19
+ return {
20
+ id,
21
+ visible,
22
+ length,
23
+ max: limit,
24
+ atLimit,
25
+ text: `${length} / ${limit}`,
26
+ label: visible ? t("form.characterCount", { count: length, max: limit }) : "",
27
+ limitMessage: atLimit ? t("form.characterLimitReached") : "",
28
+ width: String(limit).length * 2 + 3
29
+ };
30
+ };
31
+ }
@@ -1,6 +1,6 @@
1
1
  import type { Component, ComputedRef, InjectionKey, Ref } from 'vue';
2
2
  import type { FieldContext, FieldControlRole } from '../composables/useField';
3
- import type { FormContext } from '../composables/useForm';
3
+ import type { FormConfig, FormContext } from '../composables/useForm';
4
4
  import type { IconRegistry } from '../composables/useIcons';
5
5
  import type { ThemePreference } from '../composables/useTheme';
6
6
  import type { KLocale } from '../locale/types';
@@ -14,4 +14,5 @@ export declare const FIELD_KEY: InjectionKey<FieldContext>;
14
14
  export declare const FIELD_ROLE_KEY: InjectionKey<FieldControlRole>;
15
15
  export declare const ROOT_KEY: InjectionKey<true>;
16
16
  export declare const FORM_KEY: InjectionKey<FormContext>;
17
+ export declare const FORM_CONFIG_KEY: InjectionKey<FormConfig>;
17
18
  export declare const LOCALE_KEY: InjectionKey<ComputedRef<KLocale>>;
@@ -7,4 +7,5 @@ export const FIELD_KEY = Symbol("k-field");
7
7
  export const FIELD_ROLE_KEY = Symbol("k-field-role");
8
8
  export const ROOT_KEY = Symbol("k-root");
9
9
  export const FORM_KEY = Symbol("k-form");
10
+ export const FORM_CONFIG_KEY = Symbol("k-form-config");
10
11
  export const LOCALE_KEY = Symbol("k-locale");
@@ -5,7 +5,7 @@
5
5
  :popover="layer.popoverMode.value"
6
6
  :data-side="layer.side.value"
7
7
  class="k-floating k-menu"
8
- :class="{ 'is-submenu': level > 0 }"
8
+ :class="{ 'is-submenu': level > 0, 'is-match-width': matchWidth && level === 0 }"
9
9
  role="menu"
10
10
  :aria-label="label"
11
11
  :aria-labelledby="labelledby"
@@ -133,7 +133,8 @@ const props = defineProps({
133
133
  label: { type: String, required: false },
134
134
  labelledby: { type: String, required: false },
135
135
  id: { type: String, required: false },
136
- manualPositioning: { type: Boolean, required: false }
136
+ manualPositioning: { type: Boolean, required: false },
137
+ matchWidth: { type: Boolean, required: false }
137
138
  });
138
139
  const emit = defineEmits(["openChange", "select"]);
139
140
  const generatedId = useId();
@@ -156,6 +157,7 @@ const layer = useFloatingLayer({
156
157
  placement: () => props.placement,
157
158
  offset: () => props.offset,
158
159
  mode: "auto",
160
+ matchWidth: Boolean(props.matchWidth) && props.level === 0,
159
161
  manualPositioning: () => props.manualPositioning || !(props.anchor() instanceof Element),
160
162
  onOpen: () => {
161
163
  const target = pendingFocus;
@@ -13,6 +13,7 @@ declare const __VLS_export: import("vue").DefineComponent<{
13
13
  labelledby?: string;
14
14
  id?: string | undefined;
15
15
  manualPositioning?: boolean;
16
+ matchWidth?: boolean;
16
17
  key?: PropertyKey | undefined;
17
18
  prefix?: string | undefined | undefined;
18
19
  title?: string | undefined | undefined;
@@ -224,6 +225,7 @@ declare const __VLS_export: import("vue").DefineComponent<{
224
225
  labelledby?: string;
225
226
  id?: string | undefined;
226
227
  manualPositioning?: boolean;
228
+ matchWidth?: boolean;
227
229
  key?: PropertyKey | undefined;
228
230
  prefix?: string | undefined | undefined;
229
231
  title?: string | undefined | undefined;
@@ -4,13 +4,13 @@ declare const __VLS_export: import("vue").DefineComponent<{
4
4
  key?: PropertyKey | undefined;
5
5
  loading?: boolean;
6
6
  prefix?: "k-modal" | "k-drawer" | undefined;
7
+ size?: "sm" | "md" | "lg" | "xl" | "full" | undefined;
7
8
  label?: string;
8
9
  title?: string | undefined;
9
10
  style?: import("vue").StyleValue;
10
11
  results?: (string | number) | undefined;
11
12
  placeholder?: string | undefined;
12
13
  description?: string;
13
- size?: "sm" | "md" | "lg" | "xl" | "full" | undefined;
14
14
  dir?: string | undefined;
15
15
  class?: import("vue").ClassValue;
16
16
  role?: string | undefined;
@@ -114,6 +114,7 @@ declare const __VLS_export: import("vue").DefineComponent<{
114
114
  color?: string | undefined;
115
115
  id?: string | undefined;
116
116
  lang?: string | undefined;
117
+ width?: string;
117
118
  tabindex?: (string | number) | undefined;
118
119
  'aria-activedescendant'?: string | undefined;
119
120
  'aria-atomic'?: (boolean | "true" | "false") | undefined;
@@ -207,15 +208,16 @@ declare const __VLS_export: import("vue").DefineComponent<{
207
208
  onVnodeBeforeUnmount?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
208
209
  onVnodeUnmounted?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
209
210
  flush?: boolean;
211
+ sheet?: boolean;
210
212
  onCancel?: ((payload: Event) => void) | undefined;
211
213
  side?: import("../../index.ts").DrawerSide;
212
- sheet?: boolean;
213
214
  onOpen?: ((() => any) & (() => any)) | undefined;
214
215
  closeLabel?: string;
215
216
  rootClass?: unknown;
216
217
  hideClose?: boolean;
217
218
  beforeClose?: import("../../index.ts").DialogBeforeClose;
218
219
  closedby?: import("../../index.ts").DialogClosedBy;
220
+ minHeight?: string;
219
221
  }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
220
222
  close: () => any;
221
223
  afterLeave: () => any;
@@ -225,13 +227,13 @@ declare const __VLS_export: import("vue").DefineComponent<{
225
227
  key?: PropertyKey | undefined;
226
228
  loading?: boolean;
227
229
  prefix?: "k-modal" | "k-drawer" | undefined;
230
+ size?: "sm" | "md" | "lg" | "xl" | "full" | undefined;
228
231
  label?: string;
229
232
  title?: string | undefined;
230
233
  style?: import("vue").StyleValue;
231
234
  results?: (string | number) | undefined;
232
235
  placeholder?: string | undefined;
233
236
  description?: string;
234
- size?: "sm" | "md" | "lg" | "xl" | "full" | undefined;
235
237
  dir?: string | undefined;
236
238
  class?: import("vue").ClassValue;
237
239
  role?: string | undefined;
@@ -335,6 +337,7 @@ declare const __VLS_export: import("vue").DefineComponent<{
335
337
  color?: string | undefined;
336
338
  id?: string | undefined;
337
339
  lang?: string | undefined;
340
+ width?: string;
338
341
  tabindex?: (string | number) | undefined;
339
342
  'aria-activedescendant'?: string | undefined;
340
343
  'aria-atomic'?: (boolean | "true" | "false") | undefined;
@@ -428,15 +431,16 @@ declare const __VLS_export: import("vue").DefineComponent<{
428
431
  onVnodeBeforeUnmount?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
429
432
  onVnodeUnmounted?: (((vnode: import("vue").VNode) => void) | ((vnode: import("vue").VNode) => void)[]) | undefined;
430
433
  flush?: boolean;
434
+ sheet?: boolean;
431
435
  onCancel?: ((payload: Event) => void) | undefined;
432
436
  side?: import("../../index.ts").DrawerSide;
433
- sheet?: boolean;
434
437
  onOpen?: ((() => any) & (() => any)) | undefined;
435
438
  closeLabel?: string;
436
439
  rootClass?: unknown;
437
440
  hideClose?: boolean;
438
441
  beforeClose?: import("../../index.ts").DialogBeforeClose;
439
442
  closedby?: import("../../index.ts").DialogClosedBy;
443
+ minHeight?: string;
440
444
  }> & Readonly<{
441
445
  onClose?: (() => any) | undefined;
442
446
  onAfterLeave?: (() => any) | undefined;
@@ -40,12 +40,16 @@ export const de = {
40
40
  maxItems: "W\xE4hle h\xF6chstens {count} Eintrag | W\xE4hle h\xF6chstens {count} Eintr\xE4ge",
41
41
  pattern: "Ung\xFCltiges Format",
42
42
  invalid: "Ung\xFCltiger Wert",
43
- requiredHint: "(erforderlich)"
43
+ requiredHint: "(erforderlich)",
44
+ optional: "Optional",
45
+ characterCount: "{count} von {max} Zeichen",
46
+ characterLimitReached: "Zeichenlimit erreicht"
44
47
  },
45
48
  editor: {
46
49
  bold: "Fett",
47
50
  italic: "Kursiv",
48
51
  strike: "Durchgestrichen",
52
+ underline: "Unterstrichen",
49
53
  code: "Code",
50
54
  heading: "\xDCberschrift {level}",
51
55
  bulletList: "Aufz\xE4hlung",
@@ -58,6 +62,13 @@ export const de = {
58
62
  linkUrl: "Link-URL",
59
63
  applyLink: "\xDCbernehmen",
60
64
  removeLink: "Link entfernen",
65
+ linkType: "Linktyp",
66
+ linkTypeUrl: "Webadresse",
67
+ linkTypeEmail: "E-Mail",
68
+ linkTypePhone: "Telefon",
69
+ linkEmail: "E-Mail-Adresse",
70
+ linkPhone: "Telefonnummer",
71
+ linkText: "Linktext",
61
72
  characters: "{count} Zeichen | {count} Zeichen",
62
73
  limit: "{count} von {max} Zeichen",
63
74
  limitReached: "Zeichenlimit erreicht"
@@ -222,7 +233,11 @@ export const de = {
222
233
  rejected: "{count} Datei wurde nicht akzeptiert | {count} Dateien wurden nicht akzeptiert"
223
234
  },
224
235
  filterPills: {
225
- label: "Filter"
236
+ label: "Filter",
237
+ remove: "{label} entfernen"
238
+ },
239
+ tabs: {
240
+ dot: "Erfordert Aufmerksamkeit"
226
241
  },
227
242
  listPage: {
228
243
  toolbar: "Ergebnisse filtern",
@@ -241,7 +256,10 @@ export const de = {
241
256
  previous: "Vorherige Seite",
242
257
  next: "N\xE4chste Seite",
243
258
  pageSize: "Zeilen pro Seite",
244
- of: "von"
259
+ of: "von",
260
+ first: "Erste Seite",
261
+ last: "Letzte Seite",
262
+ jump: "Gehe zu Seite"
245
263
  },
246
264
  passwordInput: {
247
265
  show: "Passwort anzeigen",
@@ -40,12 +40,16 @@ export const en = {
40
40
  maxItems: "Select at most {count} item | Select at most {count} items",
41
41
  pattern: "Invalid format",
42
42
  invalid: "Invalid value",
43
- requiredHint: "(required)"
43
+ requiredHint: "(required)",
44
+ optional: "Optional",
45
+ characterCount: "{count} of {max} characters",
46
+ characterLimitReached: "Character limit reached"
44
47
  },
45
48
  editor: {
46
49
  bold: "Bold",
47
50
  italic: "Italic",
48
51
  strike: "Strikethrough",
52
+ underline: "Underline",
49
53
  code: "Inline code",
50
54
  heading: "Heading {level}",
51
55
  bulletList: "Bullet list",
@@ -58,6 +62,13 @@ export const en = {
58
62
  linkUrl: "Link URL",
59
63
  applyLink: "Apply",
60
64
  removeLink: "Remove link",
65
+ linkType: "Link type",
66
+ linkTypeUrl: "Web address",
67
+ linkTypeEmail: "Email",
68
+ linkTypePhone: "Phone",
69
+ linkEmail: "Email address",
70
+ linkPhone: "Phone number",
71
+ linkText: "Link text",
61
72
  characters: "{count} character | {count} characters",
62
73
  limit: "{count} of {max} characters",
63
74
  limitReached: "Character limit reached"
@@ -222,7 +233,11 @@ export const en = {
222
233
  rejected: "{count} file was not accepted | {count} files were not accepted"
223
234
  },
224
235
  filterPills: {
225
- label: "Filters"
236
+ label: "Filters",
237
+ remove: "Remove {label}"
238
+ },
239
+ tabs: {
240
+ dot: "Needs attention"
226
241
  },
227
242
  listPage: {
228
243
  toolbar: "Filter results",
@@ -241,7 +256,10 @@ export const en = {
241
256
  previous: "Previous page",
242
257
  next: "Next page",
243
258
  pageSize: "Rows per page",
244
- of: "of"
259
+ of: "of",
260
+ first: "First page",
261
+ last: "Last page",
262
+ jump: "Go to page"
245
263
  },
246
264
  passwordInput: {
247
265
  show: "Show password",
@@ -40,12 +40,16 @@ export const it = {
40
40
  maxItems: "Seleziona al massimo {count} elemento | Seleziona al massimo {count} elementi",
41
41
  pattern: "Formato non valido",
42
42
  invalid: "Valore non valido",
43
- requiredHint: "(obbligatorio)"
43
+ requiredHint: "(obbligatorio)",
44
+ optional: "Facoltativo",
45
+ characterCount: "{count} di {max} caratteri",
46
+ characterLimitReached: "Limite di caratteri raggiunto"
44
47
  },
45
48
  editor: {
46
49
  bold: "Grassetto",
47
50
  italic: "Corsivo",
48
51
  strike: "Barrato",
52
+ underline: "Sottolineato",
49
53
  code: "Codice",
50
54
  heading: "Titolo {level}",
51
55
  bulletList: "Elenco puntato",
@@ -58,6 +62,13 @@ export const it = {
58
62
  linkUrl: "URL del link",
59
63
  applyLink: "Applica",
60
64
  removeLink: "Rimuovi link",
65
+ linkType: "Tipo di link",
66
+ linkTypeUrl: "Indirizzo web",
67
+ linkTypeEmail: "Email",
68
+ linkTypePhone: "Telefono",
69
+ linkEmail: "Indirizzo email",
70
+ linkPhone: "Numero di telefono",
71
+ linkText: "Testo del link",
61
72
  characters: "{count} carattere | {count} caratteri",
62
73
  limit: "{count} di {max} caratteri",
63
74
  limitReached: "Limite di caratteri raggiunto"
@@ -222,7 +233,11 @@ export const it = {
222
233
  rejected: "{count} file non accettato | {count} file non accettati"
223
234
  },
224
235
  filterPills: {
225
- label: "Filtri"
236
+ label: "Filtri",
237
+ remove: "Rimuovi {label}"
238
+ },
239
+ tabs: {
240
+ dot: "Richiede attenzione"
226
241
  },
227
242
  listPage: {
228
243
  toolbar: "Filtra i risultati",
@@ -241,7 +256,10 @@ export const it = {
241
256
  previous: "Pagina precedente",
242
257
  next: "Pagina successiva",
243
258
  pageSize: "Righe per pagina",
244
- of: "di"
259
+ of: "di",
260
+ first: "Prima pagina",
261
+ last: "Ultima pagina",
262
+ jump: "Vai alla pagina"
245
263
  },
246
264
  passwordInput: {
247
265
  show: "Mostra password",