@synopackageland/ui 0.20.4 → 0.20.5

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 (71) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/LICENSES/THIRD_PARTY.md +2 -32
  3. package/dist/cli.js +0 -0
  4. package/dist/components/app/app-layout/AppLayout.vue.d.ts +21 -1
  5. package/dist/components/app/app-layout/pageTitle.d.ts +24 -0
  6. package/dist/components/app/app-tab-bar/AppTabBar.vue.d.ts +1 -1
  7. package/dist/components/app/aside-panel/AsidePanel.vue.d.ts +1 -1
  8. package/dist/components/app/section-tabs/SectionTabs.vue.d.ts +22 -4
  9. package/dist/components/composite/about-dialog/AboutDialog.vue.d.ts +1 -1
  10. package/dist/components/composite/adaptive-panel/AdaptivePanel.vue.d.ts +1 -1
  11. package/dist/components/composite/data-grid/DataGrid.vue.d.ts +19 -1
  12. package/dist/components/composite/data-grid/labels.d.ts +15 -0
  13. package/dist/components/composite/data-grid/listLayout.d.ts +26 -0
  14. package/dist/components/composite/data-table/DataTable.vue.d.ts +33 -7
  15. package/dist/components/composite/file-picker/FilePicker.vue.d.ts +2 -2
  16. package/dist/components/composite/form/FormGroup.vue.d.ts +1 -1
  17. package/dist/components/composite/form/context.d.ts +13 -0
  18. package/dist/components/composite/form-actions/FormActions.vue.d.ts +6 -2
  19. package/dist/components/composite/record-panel/RecordPanel.vue.d.ts +20 -6
  20. package/dist/components/composite/settings-section/SettingsSection.vue.d.ts +1 -1
  21. package/dist/components/composite/tag-editor/TagEditor.vue.d.ts +2 -2
  22. package/dist/components/composite/tree-view/TreeView.vue.d.ts +4 -4
  23. package/dist/components/composite/wizard/WizardDialog.vue.d.ts +2 -2
  24. package/dist/components/containers/list-detail/ListDetail.vue.d.ts +5 -3
  25. package/dist/components/feedback/validation-popup/ValidationPopup.vue.d.ts +1 -1
  26. package/dist/components/primitives/color-picker/ColorPicker.vue.d.ts +4 -4
  27. package/dist/components/primitives/combobox/Combobox.vue.d.ts +4 -4
  28. package/dist/components/primitives/context-menu/ContextMenu.vue.d.ts +2 -2
  29. package/dist/components/primitives/dialog/Dialog.vue.d.ts +17 -9
  30. package/dist/components/primitives/dropdown-menu/DropdownMenu.vue.d.ts +3 -3
  31. package/dist/components/primitives/dropdown-menu/DropdownMenuSheet.vue.d.ts +28 -0
  32. package/dist/components/primitives/input/Input.vue.d.ts +8 -1
  33. package/dist/components/primitives/input/Textarea.vue.d.ts +1 -1
  34. package/dist/components/primitives/input-steppers/InputSteppers.vue.d.ts +1 -1
  35. package/dist/components/primitives/motion/PushTransition.vue.d.ts +38 -0
  36. package/dist/components/primitives/multiple-select/MultipleSelect.vue.d.ts +4 -4
  37. package/dist/components/primitives/pagination/Pagination.vue.d.ts +22 -9
  38. package/dist/components/primitives/pagination/PaginationSheet.vue.d.ts +27 -0
  39. package/dist/components/primitives/pagination/labels.d.ts +6 -0
  40. package/dist/components/primitives/popover/Popover.vue.d.ts +1 -1
  41. package/dist/components/primitives/select/internal/ComboboxField.vue.d.ts +5 -5
  42. package/dist/components/primitives/select/internal/SelectSheet.vue.d.ts +42 -0
  43. package/dist/components/primitives/sheet/BottomSheet.vue.d.ts +69 -0
  44. package/dist/components/primitives/sheet/Sheet.vue.d.ts +13 -5
  45. package/dist/components/primitives/sheet/phone.d.ts +7 -0
  46. package/dist/components/primitives/superbox-select/SuperboxSelect.vue.d.ts +4 -4
  47. package/dist/components/rich-text-editor/RichTextEditor.vue.d.ts +1 -1
  48. package/dist/composables/formControl.d.ts +18 -0
  49. package/dist/composables/phoneSurface.d.ts +35 -0
  50. package/dist/feedback/StatusSlot.vue.d.ts +1 -1
  51. package/dist/grid/host/GridHost.vue.d.ts +1 -1
  52. package/dist/grid.js +358 -259
  53. package/dist/i18n/text.d.ts +11 -0
  54. package/dist/index.d.ts +7 -2
  55. package/dist/index.js +23021 -18391
  56. package/dist/json-preview/preview.js +16926 -12450
  57. package/dist/reka-runtime.json +15 -12
  58. package/dist/rich-text.js +1 -1
  59. package/dist/theme.css +1 -1
  60. package/dist/themes/dsm7-embedded-reset.css +1 -1
  61. package/dist/themes/dsm7-embedded-theme.css +1 -1
  62. package/dist/themes/dsm7-embedded.css +1 -1
  63. package/dist/themes/dsm7.css +1 -1
  64. package/docs/adaptive-layout.md +11 -9
  65. package/docs/app-local-modal.md +1 -1
  66. package/docs/layout-rules.md +14 -0
  67. package/docs/list-detail.md +9 -3
  68. package/docs/mobile-native.md +299 -11
  69. package/docs/release-checks.md +5 -0
  70. package/docs/theme-hooks.md +2 -2
  71. package/package.json +64 -57
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.20.5 (2026-11-05)
4
+
5
+ - In a DSM window on a touch device, a small Button, IconButton, checkbox, radio, switch or tappable Tag keeps its 44px tap box around itself. The host reset made these controls static, so the tap box covered the nearest positioned ancestor (a whole board or panel) and took every tap in it. `check:mobile` now fails when a tap box reaches past twice its control or 64px
6
+ - Mobile overflow checks now block the full release gate. Tables and nowrap examples scroll within their parent; wizard actions wrap, topology and Select labels fit, and Slider bubbles stay inside their track. Sheets, heading links, preset options and settings switches use the touch hit area; the rich text toolbar moves 44px tools into More earlier
7
+ - Phone tabs have 44px tap targets and selected-tab scrolling; short segmented controls fill the available width
8
+ - On a phone, RecordPanel and AsidePanel open as the BottomSheet: the record sheet is 92% with an optional Previous / Next footer and comments as a pushed page, and the assistant rests at half or 92%. Their own swipe code is gone
9
+ - Phone shell: `AppLayout`'s phone bar is one 48px row with a menu or Back button (`back`, emits `back`), the page title (new `title` prop, else the page's `PageHeader` title, else the brand) and one action plus "…" (`headerActions`, emits `headerAction`); the navigation drawer is Reka's Drawer from the left (85%, up to 320px), swipes left to close, moves 240/180ms and closes on Back. `AppTabBar` shows at most five slots, the rest under More, and pads by `--ui-safe-bottom`
10
+ - Phone forms: Input and SearchField set keyboard hints by type (new `integer` and `decimal` types), Form gives fields Next / Done in order, and FormActions sticks above the keyboard with full-width buttons by default on a phone
11
+ - New `BottomSheet` on Reka's Drawer (reka-ui 2.11.0): grabber, swipe to close, keyboard-aware heights, Back to close and `confirm-close`. `Dialog` on a phone and `Sheet side="bottom"` use it
12
+ - Phone push navigation: `ListDetail` at 640px or narrower pushes the detail over the list (Back, browser Back and an edge swipe pop it); `SectionTabs` on a phone shows five or more sections or a `fill` settings page as a grouped list that pushes each section, and four or fewer as a full-width SegmentControl; new `PushTransition`
13
+ - On a phone, Select and the combobox selects, DatePicker, ColorPicker and menus with more than five actions or a submenu open as bottom sheets (48px rows, a pinned search, Done or Cancel); new `usePhoneSurface` decides popover or sheet
14
+ - On a phone, `Pagination` is `‹ Page 1 of N ›` with 44px buttons and a sheet for the page and page size. `DataGrid` and `DataTable` show a list (title, subtitle, trailing status; new column `list` role); DataGrid selects by long press with a bottom selection bar and moves sorting and columns into a sheet. DataTable's `auto` view is the list instead of cards
15
+
3
16
  ## 0.20.4 (2026-11-05)
4
17
 
5
18
  - Keep anchored menus, pickers and tips within the shared floating boundary, safe area and keyboard inset
@@ -211,7 +211,7 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
211
211
  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
212
212
  ```
213
213
 
214
- ## @floating-ui/vue@1.1.11
214
+ ## @floating-ui/vue@2.0.1
215
215
 
216
216
  Declared license: MIT
217
217
 
@@ -3393,7 +3393,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
3393
3393
  THE SOFTWARE.
3394
3394
  ```
3395
3395
 
3396
- ## reka-ui@2.10.5
3396
+ ## reka-ui@2.11.0
3397
3397
 
3398
3398
  Declared license: MIT
3399
3399
 
@@ -3603,36 +3603,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
3603
3603
  THE SOFTWARE.
3604
3604
  ```
3605
3605
 
3606
- ## vue-demi@0.14.10
3607
-
3608
- Declared license: MIT
3609
-
3610
- ### LICENSE
3611
-
3612
- ```text
3613
- MIT License
3614
-
3615
- Copyright (c) 2020-present, Anthony Fu
3616
-
3617
- Permission is hereby granted, free of charge, to any person obtaining a copy
3618
- of this software and associated documentation files (the "Software"), to deal
3619
- in the Software without restriction, including without limitation the rights
3620
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
3621
- copies of the Software, and to permit persons to whom the Software is
3622
- furnished to do so, subject to the following conditions:
3623
-
3624
- The above copyright notice and this permission notice shall be included in all
3625
- copies or substantial portions of the Software.
3626
-
3627
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3628
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3629
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
3630
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3631
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3632
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3633
- SOFTWARE.
3634
- ```
3635
-
3636
3606
  ## w3c-keyname@2.2.8
3637
3607
 
3638
3608
  Declared license: MIT
package/dist/cli.js CHANGED
File without changes
@@ -1,3 +1,4 @@
1
+ import { DropdownMenuEntry } from '../../primitives/dropdown-menu/DropdownMenu.vue';
1
2
  import { AppAsideState, AppNavigation, WideLayout } from '../../../lib/adaptiveLayout';
2
3
  type __VLS_Props = {
3
4
  sidebarWidth?: string;
@@ -8,7 +9,7 @@ type __VLS_Props = {
8
9
  wideLayout?: WideLayout;
9
10
  /** Remembers the web sidebar's width and collapse under `${key}:app-sidebar`; use an app-unique key. */
10
11
  sidebarStorageKey?: string;
11
- /** Heads the web sidebar and the phone bar; defaults to the page title. A DSM window shows it in its title bar instead. */
12
+ /** Heads the web sidebar and the phone drawer (and the phone bar when no page title is known); defaults to the document title. A DSM window shows it in its title bar instead. */
12
13
  brandName?: string;
13
14
  /** Logo URL beside the brand name; defaults to the page icon. */
14
15
  brandIcon?: string;
@@ -24,6 +25,18 @@ type __VLS_Props = {
24
25
  * drawer. Defaults to the left sidebar.
25
26
  */
26
27
  navigation?: AppNavigation;
28
+ /**
29
+ * The phone bar's title. Without it the bar shows the title of the page's
30
+ * `PageHeader`, and without one of those the brand.
31
+ */
32
+ title?: string;
33
+ /** The phone bar leads with a Back button (emits `back`) instead of the menu button, for a pushed page. */
34
+ back?: boolean;
35
+ /**
36
+ * The phone bar's actions: the first is one button (its icon, or else its
37
+ * label); the rest open from "…". A pick emits `headerAction` with the key.
38
+ */
39
+ headerActions?: DropdownMenuEntry[];
27
40
  };
28
41
  type __VLS_Slots = {
29
42
  sidebar?: () => unknown;
@@ -59,16 +72,22 @@ type __VLS_ModelProps = {
59
72
  };
60
73
  type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
61
74
  declare const __VLS_base: import('vue').DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
75
+ back: () => any;
62
76
  brand: (event: MouseEvent) => any;
77
+ headerAction: (key: string) => any;
63
78
  "update:aside": (value: AppAsideState) => any;
64
79
  "update:asideWidth": (value: number) => any;
65
80
  }, string, import('vue').PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
81
+ onBack?: (() => any) | undefined;
66
82
  onBrand?: ((event: MouseEvent) => any) | undefined;
83
+ onHeaderAction?: ((key: string) => any) | undefined;
67
84
  "onUpdate:aside"?: ((value: AppAsideState) => any) | undefined;
68
85
  "onUpdate:asideWidth"?: ((value: number) => any) | undefined;
69
86
  }>, {
87
+ title: string;
70
88
  height: "auto" | "fill";
71
89
  minHeight: string;
90
+ back: boolean;
72
91
  sidebarWidth: string;
73
92
  responsive: boolean;
74
93
  wideLayout: WideLayout;
@@ -76,6 +95,7 @@ declare const __VLS_base: import('vue').DefineComponent<__VLS_PublicProps, {}, {
76
95
  brandName: string;
77
96
  brandIcon: string;
78
97
  navigation: AppNavigation;
98
+ headerActions: DropdownMenuEntry[];
79
99
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
80
100
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
81
101
  declare const _default: typeof __VLS_export;
@@ -0,0 +1,24 @@
1
+ import { ComputedRef, InjectionKey, Ref } from 'vue';
2
+ interface PageTitleEntry {
3
+ title: () => string;
4
+ }
5
+ /**
6
+ * The phone bar's page title. A PageHeader in the layout's content registers
7
+ * its title; the last one mounted is the page's, and the bar shows it unless
8
+ * AppLayout's own `title` prop is set.
9
+ */
10
+ export interface AppPageTitleHost {
11
+ /** The content column: a PageHeader outside it (in a dialog or sheet) keeps its own title. */
12
+ main: Readonly<Ref<HTMLElement | null>>;
13
+ entries: Ref<readonly PageTitleEntry[]>;
14
+ /** Whether the bar shows this entry's title (a phone, and no `title` prop). */
15
+ shows: (entry: PageTitleEntry) => boolean;
16
+ }
17
+ export declare const APP_PAGE_TITLE_KEY: InjectionKey<AppPageTitleHost>;
18
+ export declare function createPageTitleHost(main: Readonly<Ref<HTMLElement | null>>, active: () => boolean): AppPageTitleHost;
19
+ /**
20
+ * Hands a PageHeader's title to the phone bar. Returns whether the bar shows
21
+ * it, so the header can keep its own heading for screen readers only.
22
+ */
23
+ export declare function usePageTitle(element: Readonly<Ref<HTMLElement | null>>, title: () => string): ComputedRef<boolean>;
24
+ export {};
@@ -28,9 +28,9 @@ declare const __VLS_export: import('vue').DefineComponent<__VLS_Props, {}, {}, {
28
28
  "onUpdate:modelValue"?: ((key: string) => any) | undefined;
29
29
  onMore?: (() => any) | undefined;
30
30
  }>, {
31
+ hidden: boolean;
31
32
  modelValue: string;
32
33
  ariaLabel: string;
33
- hidden: boolean;
34
34
  more: boolean;
35
35
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
36
36
  declare const _default: typeof __VLS_export;
@@ -53,8 +53,8 @@ declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {
53
53
  mode: import('vue').ComputedRef<Mode>;
54
54
  }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
55
55
  initialFocus: "field" | "panel" | "none";
56
- shortcut: string;
57
56
  icon: Component;
57
+ shortcut: string;
58
58
  expandable: boolean;
59
59
  unread: boolean;
60
60
  fab: boolean;
@@ -2,7 +2,17 @@ export type SectionTab = {
2
2
  value: string;
3
3
  label: string;
4
4
  disabled?: boolean;
5
+ /** On a phone's section list, sections with the same group sit in one block under this heading. */
6
+ group?: string;
5
7
  };
8
+ /**
9
+ * How the sections show on a phone (an App 640px wide or less):
10
+ * `list` a grouped list that pushes each section as a page, `segment` a
11
+ * full-width SegmentControl, `strip` the scrolling strip (inside a pushed page
12
+ * or a sheet). `auto`: a list for five or more sections or a `fill` settings
13
+ * page, else a SegmentControl.
14
+ */
15
+ export type SectionTabsPhoneLayout = 'auto' | 'list' | 'segment' | 'strip';
6
16
  type __VLS_Props = {
7
17
  ariaLabel?: string;
8
18
  modelValue: string;
@@ -15,19 +25,27 @@ type __VLS_Props = {
15
25
  fill?: boolean;
16
26
  /** Mount all supplied item panels and hide inactive ones, preserving local drafts. */
17
27
  keepMounted?: boolean;
28
+ /** How the sections show on a phone; see SectionTabsPhoneLayout. */
29
+ phone?: SectionTabsPhoneLayout;
30
+ /** On a phone's section list, whether the selected section is pushed (`v-model:pushed`). */
31
+ pushed?: boolean;
18
32
  };
19
- declare var __VLS_14: {}, __VLS_17: `panel-${string}`, __VLS_18: {}, __VLS_21: `panel-${string}`, __VLS_22: {};
33
+ declare var __VLS_8: {}, __VLS_35: {}, __VLS_44: `panel-${string}`, __VLS_45: {}, __VLS_48: `panel-${string}`, __VLS_49: {};
20
34
  type __VLS_Slots = {} & {
21
- [K in NonNullable<typeof __VLS_17>]?: (props: typeof __VLS_18) => any;
35
+ [K in NonNullable<typeof __VLS_44>]?: (props: typeof __VLS_45) => any;
22
36
  } & {
23
- [K in NonNullable<typeof __VLS_21>]?: (props: typeof __VLS_22) => any;
37
+ [K in NonNullable<typeof __VLS_48>]?: (props: typeof __VLS_49) => any;
24
38
  } & {
25
- actions?: (props: typeof __VLS_14) => any;
39
+ actions?: (props: typeof __VLS_8) => any;
40
+ } & {
41
+ actions?: (props: typeof __VLS_35) => any;
26
42
  };
27
43
  declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
28
44
  "update:modelValue": (value: string) => any;
45
+ "update:pushed": (value: boolean) => any;
29
46
  }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
30
47
  "onUpdate:modelValue"?: ((value: string) => any) | undefined;
48
+ "onUpdate:pushed"?: ((value: boolean) => any) | undefined;
31
49
  }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
32
50
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
33
51
  declare const _default: typeof __VLS_export;
@@ -60,10 +60,10 @@ declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {
60
60
  "onCheck-result"?: ((info: AboutVersionInfo | null) => any) | undefined;
61
61
  "onCheck-error"?: ((error: unknown) => any) | undefined;
62
62
  }>, {
63
+ open: boolean;
63
64
  width: string;
64
65
  version: string;
65
66
  defaultOpen: boolean;
66
- open: boolean;
67
67
  tagline: string;
68
68
  iconSrc: string;
69
69
  beta: boolean;
@@ -41,10 +41,10 @@ declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {},
41
41
  }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
42
42
  "onUpdate:open"?: ((value: boolean) => any) | undefined;
43
43
  }>, {
44
+ open: boolean;
44
45
  width: string;
45
46
  side: "top" | "right" | "bottom" | "left";
46
47
  align: "start" | "center" | "end";
47
- open: boolean;
48
48
  motion: OverlayMotion;
49
49
  sheetSide: "bottom" | "right";
50
50
  sheetSize: string;
@@ -1,5 +1,6 @@
1
1
  import { DataGridLabels } from './labels';
2
2
  import { TableColumnAlign, TableColumnType } from './columnType';
3
+ import { TableColumnListRole } from './listLayout';
3
4
  export type DataGridSort = {
4
5
  key: string;
5
6
  direction: 'asc' | 'desc';
@@ -47,6 +48,8 @@ export type DataGridColumn = {
47
48
  /** Cell slots of an editable column get `editing`, `startEdit`, `stopEdit` and `update`. */
48
49
  editable?: boolean;
49
50
  compare?: (a: unknown, b: unknown, rowA: Record<string, unknown>, rowB: Record<string, unknown>) => number;
51
+ /** Its place in the phone list (see TableColumnListRole); unset, the first column is the title and the next two the subtitle. */
52
+ list?: TableColumnListRole;
50
53
  };
51
54
  export type DataGridColumnWidths = Record<string, number>;
52
55
  export type DataGridGroup = {
@@ -117,6 +120,12 @@ export type DataGridGroupSlotProps = {
117
120
  expanded: boolean;
118
121
  toggle: () => void;
119
122
  };
123
+ export type DataGridSelectionSlotProps = {
124
+ keys: string[];
125
+ rows: Record<string, unknown>[];
126
+ /** Clears the selection, which ends the phone list's select mode. */
127
+ clear: () => void;
128
+ };
120
129
  export type DataGridExpandSlotProps = {
121
130
  row: Record<string, unknown>;
122
131
  index: number;
@@ -205,6 +214,12 @@ type __VLS_Props = {
205
214
  defaultExpandedKeys?: string[];
206
215
  /** Row reordering with drag and drop plus keyboard support. */
207
216
  draggable?: boolean | DataGridDraggable;
217
+ /**
218
+ * `auto` shows a list in an app 640px or narrower (a phone): a row per
219
+ * item with a title, a subtitle and a trailing status, long press to
220
+ * select, and sorting and columns in a sheet. `list` always, `table` never.
221
+ */
222
+ mobileView?: 'auto' | 'list' | 'table';
208
223
  };
209
224
  declare function resetColumns(): void;
210
225
  type __VLS_Slots = {
@@ -216,6 +231,8 @@ type __VLS_Slots = {
216
231
  pageCount: number;
217
232
  }) => unknown;
218
233
  expand?: (props: DataGridExpandSlotProps) => unknown;
234
+ /** Actions in the phone list's selection bar. */
235
+ 'selection-actions'?: (props: DataGridSelectionSlotProps) => unknown;
219
236
  [name: `header-${string}`]: (props: {
220
237
  column: DataGridColumn;
221
238
  }) => unknown;
@@ -303,15 +320,16 @@ declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {
303
320
  fill: boolean;
304
321
  footer: boolean;
305
322
  loading: boolean;
323
+ draggable: boolean | DataGridDraggable;
306
324
  group: DataGridGroup | null;
307
325
  loadingText: string;
308
- draggable: boolean | DataGridDraggable;
309
326
  page: number;
310
327
  pageSize: number;
311
328
  selectable: boolean;
312
329
  columnOrder: string[];
313
330
  hiddenColumns: string[];
314
331
  rowKey: string;
332
+ mobileView: "auto" | "list" | "table";
315
333
  resizable: boolean;
316
334
  defaultSort: DataGridSort | null;
317
335
  selectedKeys: string[];
@@ -28,6 +28,15 @@ export type DataGridLabels = {
28
28
  pageSize?: string;
29
29
  /** Beside a column the chooser lists that the width leaves out. */
30
30
  hiddenByWidth?: string;
31
+ /** The phone list's selection bar. */
32
+ selected?: (count: number) => string;
33
+ /** Ends the phone list's select mode and clears the selection. */
34
+ cancelSelection?: string;
35
+ /** The phone list's sort and columns sheet, and its button. */
36
+ viewOptions?: string;
37
+ sortBy?: string;
38
+ ascending?: string;
39
+ descending?: string;
31
40
  };
32
41
  /** `DataGridLabels` after the defaults were merged in: every label is present. */
33
42
  export type ResolvedDataGridLabels = DataGridLabels & {
@@ -40,6 +49,12 @@ export type ResolvedDataGridLabels = DataGridLabels & {
40
49
  noMatch: string;
41
50
  pageSize: string;
42
51
  hiddenByWidth: string;
52
+ selected: (count: number) => string;
53
+ cancelSelection: string;
54
+ viewOptions: string;
55
+ sortBy: string;
56
+ ascending: string;
57
+ descending: string;
43
58
  };
44
59
  export declare const defaultDataGridLabels: ResolvedDataGridLabels;
45
60
  /** Locale-aware chrome; the exported English defaults remain available to callers. */
@@ -0,0 +1,26 @@
1
+ import { TableColumnType } from './columnType';
2
+ /**
3
+ * A column's place in the phone list (DataGrid and DataTable at 640px or
4
+ * narrower): `title` is the row's first line, `subtitle` joins the second
5
+ * line (two at most), `trailing` sits at the row's end (a status badge, the
6
+ * actions), `none` leaves the column out of the list.
7
+ */
8
+ export type TableColumnListRole = 'title' | 'subtitle' | 'trailing' | 'none';
9
+ type ListColumn = {
10
+ key: string;
11
+ type?: TableColumnType;
12
+ list?: TableColumnListRole;
13
+ };
14
+ export type ListLayout<T extends ListColumn> = {
15
+ title: T | undefined;
16
+ subtitle: T[];
17
+ trailing: T[];
18
+ };
19
+ export declare const MAX_LIST_SUBTITLE_COLUMNS = 2;
20
+ /**
21
+ * Places the shown columns in the list. Without `list` roles the first column
22
+ * is the title, the next two make the subtitle and an `actions` column trails.
23
+ * A column marked `subtitle` replaces the unmarked ones on the second line.
24
+ */
25
+ export declare function listLayout<T extends ListColumn>(columns: readonly T[]): ListLayout<T>;
26
+ export {};
@@ -1,4 +1,5 @@
1
1
  import { TableColumnAlign, TableColumnType } from '../data-grid/columnType';
2
+ import { TableColumnListRole } from '../data-grid/listLayout';
2
3
  export type DataTableColumn = {
3
4
  key: string;
4
5
  label: string;
@@ -11,6 +12,8 @@ export type DataTableColumn = {
11
12
  minWidth?: string | number;
12
13
  /** Overrides the table's `resizable` for this column. */
13
14
  resizable?: boolean;
15
+ /** Its place in the phone list (see TableColumnListRole); unset, the first column is the title and the next two the subtitle. */
16
+ list?: TableColumnListRole;
14
17
  };
15
18
  type __VLS_Props = {
16
19
  columns: DataTableColumn[];
@@ -18,8 +21,13 @@ type __VLS_Props = {
18
21
  rowKey?: string;
19
22
  emptyText?: string;
20
23
  compact?: boolean;
21
- /** Simple tables become fully labeled cards in mobile mode unless set to table. `container` picks cards from the measured width (see `containerBreakpoint`) whatever the app presentation. */
22
- mobileView?: 'auto' | 'cards' | 'table' | 'container';
24
+ /**
25
+ * `auto` shows a list in mobile mode (an app 640px or narrower): a row per
26
+ * item with a title, a subtitle and a trailing column. `list` and `cards`
27
+ * (fully labeled cards) always, `table` never. `container` picks cards from
28
+ * the measured width (see `containerBreakpoint`) whatever the app presentation.
29
+ */
30
+ mobileView?: 'auto' | 'list' | 'cards' | 'table' | 'container';
23
31
  /** Width in px under which `mobileView="container"` shows cards. */
24
32
  containerBreakpoint?: number;
25
33
  /**
@@ -39,11 +47,23 @@ declare var __VLS_2: `cell-${string}`, __VLS_3: {
39
47
  row: Record<string, unknown>;
40
48
  value: unknown;
41
49
  column: DataTableColumn;
42
- }, __VLS_12: `cell-${string}`, __VLS_13: {
50
+ }, __VLS_6: `cell-${string}`, __VLS_7: {
51
+ row: Record<string, unknown>;
52
+ value: unknown;
53
+ column: DataTableColumn;
54
+ }, __VLS_10: `cell-${string}`, __VLS_11: {
55
+ row: Record<string, unknown>;
56
+ value: unknown;
57
+ column: DataTableColumn;
58
+ }, __VLS_14: `cell-${string}`, __VLS_15: {
59
+ row: Record<string, unknown>;
60
+ value: unknown;
61
+ column: DataTableColumn;
62
+ }, __VLS_24: `cell-${string}`, __VLS_25: {
43
63
  row: Record<string, unknown>;
44
64
  value: unknown;
45
65
  column: DataTableColumn;
46
- }, __VLS_16: `cell-${string}`, __VLS_17: {
66
+ }, __VLS_28: `cell-${string}`, __VLS_29: {
47
67
  row: Record<string, unknown>;
48
68
  value: unknown;
49
69
  column: DataTableColumn;
@@ -51,9 +71,15 @@ declare var __VLS_2: `cell-${string}`, __VLS_3: {
51
71
  type __VLS_Slots = {} & {
52
72
  [K in NonNullable<typeof __VLS_2>]?: (props: typeof __VLS_3) => any;
53
73
  } & {
54
- [K in NonNullable<typeof __VLS_12>]?: (props: typeof __VLS_13) => any;
74
+ [K in NonNullable<typeof __VLS_6>]?: (props: typeof __VLS_7) => any;
75
+ } & {
76
+ [K in NonNullable<typeof __VLS_10>]?: (props: typeof __VLS_11) => any;
77
+ } & {
78
+ [K in NonNullable<typeof __VLS_14>]?: (props: typeof __VLS_15) => any;
79
+ } & {
80
+ [K in NonNullable<typeof __VLS_24>]?: (props: typeof __VLS_25) => any;
55
81
  } & {
56
- [K in NonNullable<typeof __VLS_16>]?: (props: typeof __VLS_17) => any;
82
+ [K in NonNullable<typeof __VLS_28>]?: (props: typeof __VLS_29) => any;
57
83
  };
58
84
  declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
59
85
  "update:columnWidths": (value: Record<string, number>) => any;
@@ -64,7 +90,7 @@ declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {},
64
90
  compact: boolean;
65
91
  columnWidths: Record<string, number>;
66
92
  rowKey: string;
67
- mobileView: "auto" | "cards" | "table" | "container";
93
+ mobileView: "auto" | "list" | "cards" | "table" | "container";
68
94
  containerBreakpoint: number;
69
95
  resizable: boolean;
70
96
  stateKey: string;
@@ -38,13 +38,13 @@ declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {},
38
38
  }>, {
39
39
  variant: "dropzone" | "compact";
40
40
  disabled: boolean;
41
- modelValue: File[];
42
41
  paste: boolean;
42
+ modelValue: File[];
43
43
  multiple: boolean;
44
+ showList: boolean;
44
45
  maxFiles: number;
45
46
  maxSize: number;
46
47
  directory: boolean;
47
- showList: boolean;
48
48
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
49
49
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
50
50
  declare const _default: typeof __VLS_export;
@@ -1,5 +1,5 @@
1
1
  type __VLS_Props = {
2
- /** Indent levels (multiples of 28px) or any CSS length. */
2
+ /** Indent levels (28px, or 12px on a touch phone) or any CSS length. */
3
3
  indent?: number | string;
4
4
  /** Disables every control in the group, usually `!parentOn`. */
5
5
  disabled?: boolean;
@@ -18,6 +18,19 @@ export type FormContext = {
18
18
  validateMessageDisplayMode: ValidateMessageDisplayMode;
19
19
  registerField: (field: FormFieldHandle) => void;
20
20
  unregisterField: (field: FormFieldHandle) => void;
21
+ /** Text entry fields, kept in document order for their keyboard's Enter key. */
22
+ registerTextControl?: (control: FormTextControl) => void;
23
+ unregisterTextControl?: (control: FormTextControl) => void;
24
+ /** `done` for the form's last active text field, `next` for the others. */
25
+ enterKeyHint?: (control: FormTextControl) => 'next' | 'done' | undefined;
26
+ /** The active text field after this one, if any. */
27
+ nextTextControl?: (control: FormTextControl) => HTMLElement | undefined;
28
+ };
29
+ /** One text entry field of a Form (an Input), for the Next / Done keyboard key. */
30
+ export type FormTextControl = {
31
+ element: () => HTMLElement | null;
32
+ /** False while the field is disabled or read-only: it is skipped. */
33
+ active: () => boolean;
21
34
  };
22
35
  /** One registered FormItem, as used by `Form.validate()` / `resetFields()` / `commit()`. */
23
36
  export type FormFieldHandle = {
@@ -4,7 +4,11 @@ type __VLS_Props = {
4
4
  labelWidth?: string;
5
5
  /** Indents the actions past the shared label column (`--ui-label-column`). */
6
6
  inset?: boolean;
7
- /** Keeps the actions in view at the bottom of a long scrolling form, over a divider. */
7
+ /**
8
+ * Keeps the actions in view at the bottom of a long scrolling form, over a
9
+ * divider, and above the on-screen keyboard. On by default on a phone, off
10
+ * elsewhere; `false` turns it off on a phone too.
11
+ */
8
12
  sticky?: boolean;
9
13
  };
10
14
  declare var __VLS_1: {};
@@ -12,9 +16,9 @@ type __VLS_Slots = {} & {
12
16
  default?: (props: typeof __VLS_1) => any;
13
17
  };
14
18
  declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
15
- align: "start" | "end";
16
19
  sticky: boolean;
17
20
  inset: boolean;
21
+ align: "start" | "end";
18
22
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
19
23
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
20
24
  declare const _default: typeof __VLS_export;
@@ -1,4 +1,5 @@
1
- export type RecordPanelCloseReason = 'escape' | 'button' | 'swipe';
1
+ /** `swipe` is any other way the phone sheet was let go: a drag, or Back. */
2
+ export type RecordPanelCloseReason = 'escape' | 'button' | 'outside' | 'swipe';
2
3
  type __VLS_Props = {
3
4
  /** Controlled open state (`v-model:open`). */
4
5
  open?: boolean;
@@ -12,16 +13,21 @@ type __VLS_Props = {
12
13
  minWidth?: number;
13
14
  /** The view kept visible beside the panel, however wide it is dragged. */
14
15
  minMainWidth?: number;
15
- /** Shows the `secondary` slot (comments) as a column on the far side; the panel grows by `secondaryWidth`. */
16
+ /** Shows the `secondary` slot (comments) as a column on the far side; the panel grows by `secondaryWidth`. On the phone sheet it is a page pushed over the body, and its Back emits `update:secondaryOpen`. */
16
17
  secondaryOpen?: boolean;
17
18
  secondaryWidth?: number;
19
+ /** The pushed comments page's title on the phone sheet, already translated. */
20
+ secondaryLabel?: string;
18
21
  /** The element the panel docks to and is clipped by; it must be positioned. The parent element otherwise. */
19
22
  container?: HTMLElement | null;
20
- /** At this host width and narrower the panel is a full-screen sheet. */
23
+ /** At this host width and narrower the panel is a bottom sheet. */
21
24
  compactBelow?: number;
25
+ /** The phone sheet's footer: Previous and Next record, disabled where false. Without both, no footer. */
26
+ hasPrevious?: boolean;
27
+ hasNext?: boolean;
22
28
  /** Where focus goes on close when the element that had it at open is gone (a re-rendered card). */
23
29
  returnFocus?: () => HTMLElement | null | undefined;
24
- /** `field`: the first editable field (not on touch); `panel`: the panel itself; `none`: focus stays. */
30
+ /** `field`: the first editable field (not on touch or the phone sheet); `panel`: the panel itself; `none`: focus stays. */
25
31
  initialFocus?: 'field' | 'panel' | 'none';
26
32
  /** No body padding; the caller lays the body out. */
27
33
  flush?: boolean;
@@ -45,18 +51,25 @@ declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {
45
51
  compact: import('vue').ComputedRef<boolean>;
46
52
  width: import('vue').ComputedRef<number>;
47
53
  }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
54
+ next: () => any;
48
55
  close: (reason: RecordPanelCloseReason) => any;
49
56
  "update:open": (value: boolean) => any;
50
57
  "update:width": (value: number) => any;
58
+ "update:secondaryOpen": (value: boolean) => any;
51
59
  resizeEnd: (value: number) => any;
60
+ previous: () => any;
52
61
  }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
62
+ onNext?: (() => any) | undefined;
53
63
  onClose?: ((reason: RecordPanelCloseReason) => any) | undefined;
54
64
  "onUpdate:open"?: ((value: boolean) => any) | undefined;
55
65
  "onUpdate:width"?: ((value: number) => any) | undefined;
66
+ "onUpdate:secondaryOpen"?: ((value: boolean) => any) | undefined;
56
67
  onResizeEnd?: ((value: number) => any) | undefined;
68
+ onPrevious?: (() => any) | undefined;
57
69
  }>, {
58
- width: number;
59
70
  open: boolean;
71
+ width: number;
72
+ initialFocus: "field" | "panel" | "none";
60
73
  minWidth: number;
61
74
  compactBelow: number;
62
75
  container: HTMLElement | null;
@@ -64,8 +77,9 @@ declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {
64
77
  minMainWidth: number;
65
78
  secondaryOpen: boolean;
66
79
  secondaryWidth: number;
80
+ hasPrevious: boolean;
81
+ hasNext: boolean;
67
82
  returnFocus: () => HTMLElement | null | undefined;
68
- initialFocus: "field" | "panel" | "none";
69
83
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
70
84
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
71
85
  declare const _default: typeof __VLS_export;
@@ -31,8 +31,8 @@ declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {},
31
31
  }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
32
32
  "onUpdate:open"?: ((value: boolean) => any) | undefined;
33
33
  }>, {
34
- defaultOpen: boolean;
35
34
  open: boolean;
35
+ defaultOpen: boolean;
36
36
  collapsible: boolean;
37
37
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
38
38
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -13,14 +13,14 @@ type __VLS_Props = {
13
13
  };
14
14
  declare const __VLS_export: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
15
15
  error: (error: unknown) => any;
16
- "update:modelValue": (value: string[]) => any;
17
16
  close: () => any;
18
17
  open: () => any;
18
+ "update:modelValue": (value: string[]) => any;
19
19
  }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
20
20
  onError?: ((error: unknown) => any) | undefined;
21
- "onUpdate:modelValue"?: ((value: string[]) => any) | undefined;
22
21
  onClose?: (() => any) | undefined;
23
22
  onOpen?: (() => any) | undefined;
23
+ "onUpdate:modelValue"?: ((value: string[]) => any) | undefined;
24
24
  }>, {
25
25
  disabled: boolean;
26
26
  modelValue: string[];