@synopackageland/ui 0.20.20 → 0.21.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.21.1 (2026-11-07)
6
+
7
+ Native phone shell fixes. No App change is required; pages without a FAB, a DSM window and desktop are unchanged.
8
+
9
+ - **Toasts clear the FAB.** On a touch phone a toast sat over the FAB (at 390x844, the toast at y 730–780 and the FAB at 715–771). While a page shows a FAB (page actions or a `PageFab`), the toast now sits 8px above it; while the FAB is hidden on scroll or by the keyboard, the toast goes back to its own place. While the speed dial is open the toast fades out, so it never covers a pill, and it comes back when the dial closes. It moves with the bars in `--ui-motion-bars`, at once with reduced motion
10
+ - **IconButtons in the speed dial are labelled pills.** An `IconButton` among the page actions (such as "More actions", which opens a menu) became a 48px circle in the dial with its name spilling out of it. Every dial pill is now its icon and its text: an action with no text of its own shows its `aria-label`, or else its `title` (copied to `data-ui-fab-label`), and the pill sizes to it, a name too long for the screen ending in an ellipsis. A menu trigger stays in the dial and keeps it open until its menu closes
11
+ - `check:phone-layout` adds a list page with a More actions menu in the dial and a toast with one FAB and with the dial, at 390x844, 360x800 and 390x664 with touch, in a DSM window and on desktop, in English and Traditional Chinese: each pill holds its whole label, the toast sits above a shown FAB, steps aside while the dial is open and is back down while the FAB is hidden, keeps the bottom right off a phone, and moves at once with reduced motion
12
+
13
+ ## 0.21.0 (2026-11-07)
14
+
15
+ Native phone shell. A *touch phone* is an `AppLayout` 640px or narrower under a coarse pointer (`data-ui-phone`). A narrow DSM window driven by a mouse, tablets and desktop are unchanged. No App change is required; every new behaviour has an opt-out (docs/mobile-native.md, "Native phone shell").
16
+
17
+ - **Page actions become a FAB.** On a touch phone the page's actions (PageHeader `#actions`, a pushed page's `#header-actions`, AppToolbar `#actions`) render in a floating action button at the bottom right instead of the bar. One action: the 56px FAB is that action and runs it. Two or more: the FAB opens a speed dial of labelled pills over a scrim, with focus trapped in it; Escape, Back, the scrim or the FAB close it and focus returns to the FAB; a pick runs the action and closes it; reduced motion shows it at once. A page whose primary action is in a footer bar (a `SettingsPage` footer, a sticky `FormActions`) keeps its actions in the bar. Page content gets `--ui-fab-room` of bottom padding
18
+ - **Opt-out / override:** `phone-actions="fab" | "bar" | "inline"` on `AppLayout` (all pages) and on `PageHeader`, `AppToolbar` and `PushTransition` (one page). `bar` is the 0.20.20 behaviour
19
+ - **New `PageFab`:** `<PageFab><Button variant="primary">…</Button></PageFab>` in the page's actions picks the FAB explicitly; the page's other actions go to the bar. Elsewhere it renders in place
20
+ - **Hide on scroll, on by default.** Scrolling a page down (16px) slides the bar, the tab bar, the FAB and a clean settings footer out; any scroll up (4px), the top of the page and a scroll that stops at its end bring them back. They never hide while the speed dial, the drawer, a sheet or a dialog is open or a text field has focus. They move in `--ui-motion-bars` (200ms, 0 with reduced motion). The root carries `data-ui-bars-hidden="all|bottom"`
21
+ - **Opt-out:** `<AppLayout :hide-on-scroll="false">` (the App) or `<PageContent :hide-on-scroll="false">` (one page). Both keep the settings footer as well
22
+ - **Settings footer hides only when clean.** A `SettingsPage` footer slides away with the bars only while its form is clean, never while it is dirty, invalid or saving. New props `dirty`, `invalid` and `saving`; left out, it reads them from the page: clean while the footer's primary button is disabled, invalid while a field has `aria-invalid="true"`, saving while a footer button is loading. The footer does not collapse at rest
23
+ - **Footer hints on their own line.** On a touch phone, a hint or status beside the buttons of any footer bar (`data-ui-footer-bar`: SettingsPage, Dialog, Sheet, BottomSheet, Card, Panel, Wizard, AppActionBar, and a FormActions in one) takes a full-width line above them instead of a narrow column of one or two words per line. Wrap bare text in an element
24
+ - **One compact bar.** A root page with no menu button leads the bar with the App icon (`brand-icon`), title start-aligned; no brand row. On a touch phone at most two trailing icons show in the bar; more page actions stay in the page's row, and `headerActions` go to "…" once page actions are in the bar. `AppTabBar` labels are 12px
25
+ - **SectionTabs: the underline strip on a touch phone.** `phone="auto"` with four or fewer sections (not `fill`) is now the scrolling underline strip under the bar instead of a full-width SegmentControl. `phone="segment"` keeps the SegmentControl; a mouse-driven narrow window keeps it too
26
+ - **Host insets.** `--ui-safe-top/-right/-bottom/-left` read `--ui-host-inset-*` first, then `env(safe-area-inset-*)`. A host shell that draws its own chrome around the App sets them so the bars and the FAB clear it. The Package Land mobile shell draws none and needs no setting
27
+ - New UI string "Page actions" (the speed dial's name), in all nine locales
28
+ - `check:phone-layout` covers a list page with one action (FAB), three (speed dial), `phone-actions="bar"`, hide-on-scroll off, and settings pages with a clean footer, a dirty footer and a footer hint, at 390x844, 360x800 and 390x664 with touch, in a DSM window and on desktop, in English and Traditional Chinese. It also checks the FAB's size, place and colour, hiding and showing on scroll, the dial's focus trap, Escape and scrim, and reduced motion. `check:mobile` gains the FAB, the open speed dial, hidden bars and a footer hint
29
+
5
30
  ## 0.20.20 (2026-11-07)
6
31
 
7
32
  Phone layout (AppLayout 640px or narrower). No App change is required; `PageHeader` `back` is new and optional.
package/dist/cli.js CHANGED
File without changes
@@ -1,3 +1,4 @@
1
+ import { PhoneActionsPlacement } from './pageTitle';
1
2
  import { DropdownMenuEntry } from '../../primitives/dropdown-menu/DropdownMenu.vue';
2
3
  import { AppAsideState, AppNavigation, WideLayout } from '../../../lib/adaptiveLayout';
3
4
  type __VLS_Props = {
@@ -37,6 +38,23 @@ type __VLS_Props = {
37
38
  * label); the rest open from "…". A pick emits `headerAction` with the key.
38
39
  */
39
40
  headerActions?: DropdownMenuEntry[];
41
+ /**
42
+ * Where a page's own actions (PageHeader `#actions`, a pushed page's
43
+ * `#header-actions`, an AppToolbar's `#actions` above the page) go on a
44
+ * phone: `fab` (default) a floating action button, which runs a single
45
+ * action or opens a speed dial of them; `bar` icons in the phone bar;
46
+ * `inline` the page's own header row. A page's `phone-actions` overrides
47
+ * it. A page with a sticky footer (a SettingsPage footer, a sticky
48
+ * FormActions) keeps them in the bar, and a narrow window used with a
49
+ * mouse treats `fab` as `bar`.
50
+ */
51
+ phoneActions?: PhoneActionsPlacement;
52
+ /**
53
+ * On a phone, scrolling the page down slides the phone bar, the tab bar
54
+ * and the FAB out of view, and any scroll up brings them back. `false`
55
+ * keeps them; a page opts out alone with PageContent `hide-on-scroll="false"`.
56
+ */
57
+ hideOnScroll?: boolean;
40
58
  };
41
59
  type __VLS_Slots = {
42
60
  sidebar?: () => unknown;
@@ -86,6 +104,7 @@ declare const __VLS_base: import('vue').DefineComponent<__VLS_PublicProps, {}, {
86
104
  }>, {
87
105
  title: string;
88
106
  height: "auto" | "fill";
107
+ phoneActions: PhoneActionsPlacement;
89
108
  minHeight: string;
90
109
  back: boolean;
91
110
  sidebarWidth: string;
@@ -96,6 +115,7 @@ declare const __VLS_base: import('vue').DefineComponent<__VLS_PublicProps, {}, {
96
115
  brandIcon: string;
97
116
  navigation: AppNavigation;
98
117
  headerActions: DropdownMenuEntry[];
118
+ hideOnScroll: boolean;
99
119
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
100
120
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
101
121
  declare const _default: typeof __VLS_export;
@@ -0,0 +1,18 @@
1
+ type __VLS_Props = {
2
+ /** Slid out of view (the page scrolled down, or the keyboard is open). */
3
+ hidden?: boolean;
4
+ };
5
+ type __VLS_ModelProps = {
6
+ 'open'?: boolean;
7
+ };
8
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
9
+ declare const __VLS_export: import('vue').DefineComponent<__VLS_PublicProps, {
10
+ actions: import('vue').Ref<HTMLElement | null, HTMLElement | null>;
11
+ count: import('vue').Ref<number, number>;
12
+ }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
13
+ "update:open": (value: boolean) => any;
14
+ }, string, import('vue').PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
15
+ "onUpdate:open"?: ((value: boolean) => any) | undefined;
16
+ }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
17
+ declare const _default: typeof __VLS_export;
18
+ export default _default;
@@ -0,0 +1,37 @@
1
+ import { InjectionKey, Ref, WatchSource } from 'vue';
2
+ /** Scrolling down this far in one go hides the bars (a small threshold against jitter). */
3
+ export declare const HIDE_AFTER_PX = 16;
4
+ /** Scrolling up this far brings them back: any real scroll up, not a sub-pixel wobble. */
5
+ export declare const SHOW_AFTER_PX = 4;
6
+ /**
7
+ * Which bars a scroll hides: `all` (the phone bar, the tab bar and the FAB)
8
+ * when the page scrolls in an area under the bar, `bottom` (the tab bar and
9
+ * the FAB) when the document scrolls, which already carries the bar away.
10
+ */
11
+ export type BarsHidden = false | 'all' | 'bottom';
12
+ export interface HideOnScrollOptions {
13
+ /** The layout's content column: scrolls in it (or of the document) count. */
14
+ column: Readonly<Ref<HTMLElement | null>>;
15
+ /** The phone bar, to tell whether the scroller carries it. */
16
+ bar: () => HTMLElement | null;
17
+ /** On only for a phone with the feature on (no page opted out). */
18
+ enabled: () => boolean;
19
+ /** Never hide while this holds (the speed dial or the navigation drawer is open). */
20
+ blocked: () => boolean;
21
+ /** The room the bars take: a page that scrolls less than this keeps them, or hiding them would end its scroll. */
22
+ room: () => number;
23
+ /** How long hiding or showing moves the layout; scrolls in that time are its own, not the user's. */
24
+ settleMs: () => number;
25
+ /** Each change shows the bars again (a new page). */
26
+ reset: WatchSource[];
27
+ }
28
+ /**
29
+ * Hide-on-scroll for the phone shell: scrolling the page down slides the bars
30
+ * out, any scroll up brings them back at once, and so do the top of the page
31
+ * and a scroll that ends at its bottom. It never hides while a sheet, dialog,
32
+ * the speed dial or the drawer is open, or while a text field has focus, and
33
+ * focus moving into the bars shows them.
34
+ */
35
+ export declare function useHideOnScroll(options: HideOnScrollOptions): Ref<BarsHidden>;
36
+ /** A page's opt-out from hide-on-scroll (PageContent `hide-on-scroll="false"`): counts while it is mounted. */
37
+ export declare const APP_KEEP_BARS_KEY: InjectionKey<() => () => void>;
@@ -1,4 +1,12 @@
1
1
  import { ComputedRef, InjectionKey, Ref } from 'vue';
2
+ /**
3
+ * Where a page's own actions go on a phone (an App 640px or narrower with a
4
+ * coarse pointer): `fab`, a floating action button at the bottom right (one
5
+ * action runs at once, two or more open a speed dial); `bar`, icons in the
6
+ * phone bar after the title; `inline`, the page's own header row. A narrow
7
+ * window used with a mouse treats `fab` as `bar`.
8
+ */
9
+ export type PhoneActionsPlacement = 'fab' | 'bar' | 'inline';
2
10
  interface PageTitleEntry {
3
11
  title: () => string;
4
12
  /**
@@ -29,6 +37,18 @@ export interface AppPageTitleHost {
29
37
  actions: Readonly<Ref<HTMLElement | null>>;
30
38
  /** Counts what renders into `actions`, so the bar knows the title is not alone. Returns the release. */
31
39
  useActions: () => () => void;
40
+ /** The phone's floating action button, where page actions go with the `fab` placement; null where there is none. */
41
+ fab?: Readonly<Ref<HTMLElement | null>>;
42
+ /** The placement a page's actions take, given the page's own choice (its `phone-actions`). */
43
+ placement?: (requested: PhoneActionsPlacement | undefined) => PhoneActionsPlacement;
44
+ /**
45
+ * A footer bar that sticks at the bottom of the page (a SettingsPage
46
+ * footer, a sticky FormActions) claims the bottom: the page's primary
47
+ * action is there, so the page's actions take the bar, not a FAB.
48
+ */
49
+ useFooterBar?: () => () => void;
50
+ /** A PageFab holds the FAB: the page's other actions with the `fab` placement take the bar instead. */
51
+ useExplicitFab?: () => () => void;
32
52
  }
33
53
  export declare const APP_PAGE_TITLE_KEY: InjectionKey<AppPageTitleHost>;
34
54
  /**
@@ -40,6 +60,10 @@ export declare function createPageTitleHost(main: Readonly<Ref<HTMLElement | nul
40
60
  phone?: () => boolean;
41
61
  actions?: Readonly<Ref<HTMLElement | null>>;
42
62
  actionUsers?: Ref<number>;
63
+ fab?: Readonly<Ref<HTMLElement | null>>;
64
+ placement?: (requested: PhoneActionsPlacement | undefined) => PhoneActionsPlacement;
65
+ footerBars?: Ref<number>;
66
+ explicitFabs?: Ref<number>;
43
67
  }): AppPageTitleHost;
44
68
  /**
45
69
  * Hands a PageHeader's title to the layout's bar. Returns whether the bar shows
@@ -53,11 +77,20 @@ export declare function usePageTitle(element: Readonly<Ref<HTMLElement | null>>,
53
77
  when?: () => boolean;
54
78
  }): ComputedRef<boolean>;
55
79
  /**
56
- * Whether a component's actions render in the phone bar, and counts them while
57
- * they do. `wanted` says whether the component would put them there (its title
58
- * is in the bar, or it is the bar above the page).
80
+ * Where a component's actions render on a phone: the phone bar or the FAB
81
+ * (`target`), or null for its own row. Counts them while they are in the bar.
82
+ * `wanted` says whether the component would move them out of its row (its
83
+ * title is in the bar, or it is the bar above the page); `placement` is the
84
+ * component's own `phone-actions`, which overrides the layout's.
59
85
  */
60
- export declare function usePageActionsInBar(wanted: () => boolean): {
86
+ export declare function usePageActionsInBar(wanted: () => boolean, placement?: () => PhoneActionsPlacement | undefined): {
61
87
  target: ComputedRef<HTMLElement | null>;
88
+ placement: ComputedRef<PhoneActionsPlacement>;
62
89
  };
90
+ /**
91
+ * Claims the bottom of the layout's page for a footer bar while `active`
92
+ * holds and `element` is in the layout's content column (a footer in a dialog
93
+ * or sheet does not count).
94
+ */
95
+ export declare function useFooterBarClaim(element: Readonly<Ref<HTMLElement | null>>, active: () => boolean): void;
63
96
  export {};
@@ -1,5 +1,8 @@
1
+ import { PhoneActionsPlacement } from '../app-layout/pageTitle';
1
2
  type __VLS_Props = {
2
3
  height?: string;
4
+ /** Where `#actions` go on a phone when this is the bar above the page: `fab`, `bar` or `inline` (this row). Defaults to AppLayout's `phone-actions`. */
5
+ phoneActions?: PhoneActionsPlacement;
3
6
  };
4
7
  type __VLS_Slots = {
5
8
  default?: () => unknown;
@@ -8,6 +11,7 @@ type __VLS_Slots = {
8
11
  };
9
12
  declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
10
13
  height: string;
14
+ phoneActions: PhoneActionsPlacement;
11
15
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
12
16
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
13
17
  declare const _default: typeof __VLS_export;
@@ -53,11 +53,11 @@ 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
+ fab: boolean;
56
57
  icon: Component;
57
58
  shortcut: string;
58
59
  expandable: boolean;
59
60
  unread: boolean;
60
- fab: boolean;
61
61
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
62
62
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
63
63
  declare const _default: typeof __VLS_export;
@@ -12,6 +12,11 @@ type __VLS_Props = {
12
12
  * holding one) takes the height left and scrolls itself.
13
13
  */
14
14
  height?: 'auto' | 'fill';
15
+ /**
16
+ * `false` keeps a phone's bars in place while this page shows, when
17
+ * AppLayout hides them on scroll (its `hide-on-scroll`, on by default).
18
+ */
19
+ hideOnScroll?: boolean;
15
20
  };
16
21
  declare var __VLS_1: {};
17
22
  type __VLS_Slots = {} & {
@@ -21,6 +26,7 @@ declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {},
21
26
  height: "auto" | "fill";
22
27
  width: "fill" | "readable" | (string & {});
23
28
  surface: "auto" | "flat" | "card" | "none";
29
+ hideOnScroll: boolean;
24
30
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
25
31
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
26
32
  declare const _default: typeof __VLS_export;
@@ -0,0 +1,12 @@
1
+ type __VLS_Slots = {
2
+ default?: () => unknown;
3
+ };
4
+ declare const __VLS_base: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
5
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
6
+ declare const _default: typeof __VLS_export;
7
+ export default _default;
8
+ type __VLS_WithSlots<T, S> = T & {
9
+ new (): {
10
+ $slots: S;
11
+ };
12
+ };
@@ -1,9 +1,12 @@
1
+ import { PhoneActionsPlacement } from '../app-layout/pageTitle';
1
2
  type __VLS_Props = {
2
3
  title: string;
3
4
  description?: string;
4
5
  sticky?: boolean;
5
6
  /** A sub-page's header: Back before the title, emitting `back`. On a phone, the bar's Back. */
6
7
  back?: boolean;
8
+ /** Where `#actions` go on a phone: `fab`, `bar` or `inline` (this header's row). Defaults to AppLayout's `phone-actions`. */
9
+ phoneActions?: PhoneActionsPlacement;
7
10
  };
8
11
  declare var __VLS_19: {}, __VLS_27: {}, __VLS_29: {};
9
12
  type __VLS_Slots = {} & {
@@ -19,6 +22,7 @@ declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {},
19
22
  onBack?: (() => any) | undefined;
20
23
  }>, {
21
24
  sticky: boolean;
25
+ phoneActions: PhoneActionsPlacement;
22
26
  back: boolean;
23
27
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
24
28
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -8,9 +8,10 @@ export type SectionTab = {
8
8
  /**
9
9
  * How the sections show on a phone (an App 640px wide or less):
10
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.
11
+ * full-width SegmentControl, `strip` the scrolling underline strip. `auto`: a
12
+ * list for five or more sections or a `fill` settings page, else the strip on
13
+ * a touch phone (a SegmentControl before 0.21.0; ask for `segment` to keep
14
+ * it) and a SegmentControl in a narrow window used with a mouse.
14
15
  */
15
16
  export type SectionTabsPhoneLayout = 'auto' | 'list' | 'segment' | 'strip';
16
17
  type __VLS_Props = {
@@ -1,10 +1,25 @@
1
+ type __VLS_Props = {
2
+ /**
3
+ * The form has changes not yet applied. With `false` the footer may slide
4
+ * away with the phone's bars on a scroll down; with `true` it stays. Left
5
+ * out, the footer reads it: the form is clean while the footer's primary
6
+ * button (every button, when none is primary) is disabled.
7
+ */
8
+ dirty?: boolean;
9
+ /** A field has an error: the footer stays. A field with `aria-invalid="true"` counts too. */
10
+ invalid?: boolean;
11
+ /** Apply is running: the footer stays. A footer button in its loading state counts too. */
12
+ saving?: boolean;
13
+ };
1
14
  declare var __VLS_1: {}, __VLS_9: {};
2
15
  type __VLS_Slots = {} & {
3
16
  default?: (props: typeof __VLS_1) => any;
4
17
  } & {
5
18
  footer?: (props: typeof __VLS_9) => any;
6
19
  };
7
- declare const __VLS_base: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
20
+ declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
21
+ dirty: boolean;
22
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
8
23
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
9
24
  declare const _default: typeof __VLS_export;
10
25
  export default _default;
@@ -1,3 +1,4 @@
1
+ import { PhoneActionsPlacement } from '../../app/app-layout/pageTitle';
1
2
  type __VLS_Props = {
2
3
  /** Whether the page is pushed. */
3
4
  show: boolean;
@@ -11,6 +12,8 @@ type __VLS_Props = {
11
12
  keepMounted?: boolean;
12
13
  /** The page's element. */
13
14
  as?: string;
15
+ /** Where `#header-actions` go on a phone while the layout's bar shows this page: `fab`, `bar` or `inline` (a row atop the page). Defaults to AppLayout's `phone-actions`. */
16
+ phoneActions?: PhoneActionsPlacement;
14
17
  };
15
18
  type __VLS_Slots = {
16
19
  default?: () => unknown;
@@ -27,6 +30,7 @@ declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {},
27
30
  enabled: boolean;
28
31
  under: HTMLElement | null;
29
32
  keepMounted: boolean;
33
+ phoneActions: PhoneActionsPlacement;
30
34
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
31
35
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
32
36
  declare const _default: typeof __VLS_export;
package/dist/grid.js CHANGED
@@ -3942,6 +3942,7 @@ const Xe = (e, t) => e.x >= t.x && e.x < t.x + t.width && e.y >= t.y && e.y < t.
3942
3942
  "Free now {now}, free after {after}": "Free now {now}, free after {after}",
3943
3943
  Sections: "Sections",
3944
3944
  "Back to the previous page": "Back",
3945
+ "Page actions": "Page actions",
3945
3946
  Slider: "Slider",
3946
3947
  "Increase value": "Increase value",
3947
3948
  "Decrease value": "Decrease value",
@@ -4203,6 +4204,7 @@ const Xe = (e, t) => e.x >= t.x && e.x < t.x + t.width && e.y >= t.y && e.y < t.
4203
4204
  "Free now {now}, free after {after}": "目前可用 {now},清理後可用 {after}",
4204
4205
  Sections: "區段",
4205
4206
  "Back to the previous page": "返回",
4207
+ "Page actions": "頁面動作",
4206
4208
  Slider: "滑桿",
4207
4209
  "Increase value": "增加數值",
4208
4210
  "Decrease value": "減少數值",
@@ -4463,6 +4465,7 @@ const Xe = (e, t) => e.x >= t.x && e.x < t.x + t.width && e.y >= t.y && e.y < t.
4463
4465
  "Free now {now}, free after {after}": "当前可用 {now},清理后可用 {after}",
4464
4466
  Sections: "区段",
4465
4467
  "Back to the previous page": "返回",
4468
+ "Page actions": "页面操作",
4466
4469
  Slider: "滑块",
4467
4470
  "Increase value": "增加数值",
4468
4471
  "Decrease value": "减少数值",
@@ -4723,6 +4726,7 @@ const Xe = (e, t) => e.x >= t.x && e.x < t.x + t.width && e.y >= t.y && e.y < t.
4723
4726
  "Free now {now}, free after {after}": "現在の空き {now}、解放後の空き {after}",
4724
4727
  Sections: "セクション",
4725
4728
  "Back to the previous page": "戻る",
4729
+ "Page actions": "ページの操作",
4726
4730
  Slider: "スライダー",
4727
4731
  "Increase value": "値を増やす",
4728
4732
  "Decrease value": "値を減らす",
@@ -4983,6 +4987,7 @@ const Xe = (e, t) => e.x >= t.x && e.x < t.x + t.width && e.y >= t.y && e.y < t.
4983
4987
  "Free now {now}, free after {after}": "현재 여유 공간 {now}, 정리 후 여유 공간 {after}",
4984
4988
  Sections: "섹션",
4985
4989
  "Back to the previous page": "뒤로",
4990
+ "Page actions": "페이지 작업",
4986
4991
  Slider: "슬라이더",
4987
4992
  "Increase value": "값 증가",
4988
4993
  "Decrease value": "값 감소",
@@ -5243,6 +5248,7 @@ const Xe = (e, t) => e.x >= t.x && e.x < t.x + t.width && e.y >= t.y && e.y < t.
5243
5248
  "Free now {now}, free after {after}": "Jetzt frei {now}, danach frei {after}",
5244
5249
  Sections: "Abschnitte",
5245
5250
  "Back to the previous page": "Zurück",
5251
+ "Page actions": "Seitenaktionen",
5246
5252
  Slider: "Schieberegler",
5247
5253
  "Increase value": "Wert erhöhen",
5248
5254
  "Decrease value": "Wert verringern",
@@ -5503,6 +5509,7 @@ const Xe = (e, t) => e.x >= t.x && e.x < t.x + t.width && e.y >= t.y && e.y < t.
5503
5509
  "Free now {now}, free after {after}": "Libre maintenant {now}, libre ensuite {after}",
5504
5510
  Sections: "Sections",
5505
5511
  "Back to the previous page": "Retour",
5512
+ "Page actions": "Actions de la page",
5506
5513
  Slider: "Curseur",
5507
5514
  "Increase value": "Augmenter la valeur",
5508
5515
  "Decrease value": "Diminuer la valeur",
@@ -5763,6 +5770,7 @@ const Xe = (e, t) => e.x >= t.x && e.x < t.x + t.width && e.y >= t.y && e.y < t.
5763
5770
  "Free now {now}, free after {after}": "Libre ahora {now}, libre después {after}",
5764
5771
  Sections: "Secciones",
5765
5772
  "Back to the previous page": "Atrás",
5773
+ "Page actions": "Acciones de la página",
5766
5774
  Slider: "Control deslizante",
5767
5775
  "Increase value": "Aumentar valor",
5768
5776
  "Decrease value": "Disminuir valor",
@@ -6023,6 +6031,7 @@ const Xe = (e, t) => e.x >= t.x && e.x < t.x + t.width && e.y >= t.y && e.y < t.
6023
6031
  "Free now {now}, free after {after}": "Libero ora {now}, libero dopo {after}",
6024
6032
  Sections: "Sezioni",
6025
6033
  "Back to the previous page": "Indietro",
6034
+ "Page actions": "Azioni della pagina",
6026
6035
  Slider: "Cursore",
6027
6036
  "Increase value": "Aumenta valore",
6028
6037
  "Decrease value": "Diminuisci valore",
@@ -106,6 +106,7 @@ export declare const englishUiText: {
106
106
  readonly "Free now {now}, free after {after}": "Free now {now}, free after {after}";
107
107
  readonly Sections: "Sections";
108
108
  readonly "Back to the previous page": "Back";
109
+ readonly "Page actions": "Page actions";
109
110
  readonly Slider: "Slider";
110
111
  readonly "Increase value": "Increase value";
111
112
  readonly "Decrease value": "Decrease value";
package/dist/index.d.ts CHANGED
@@ -260,6 +260,8 @@ export type { AppSidebarGroup, AppSidebarItem } from './components/app/app-sideb
260
260
  export { default as AppToolbar } from './components/app/app-toolbar/AppToolbar.vue';
261
261
  export { default as AppActionBar } from './components/app/app-action-bar/AppActionBar.vue';
262
262
  export { default as PageHeader } from './components/app/page-header/PageHeader.vue';
263
+ export { default as PageFab } from './components/app/page-fab/PageFab.vue';
264
+ export type { PhoneActionsPlacement } from './components/app/app-layout/pageTitle';
263
265
  export { default as PageToolbar } from './components/app/page-toolbar/PageToolbar.vue';
264
266
  export { default as SplitPane } from './components/containers/split-pane/SplitPane.vue';
265
267
  export { default as ListDetail } from './components/containers/list-detail/ListDetail.vue';