@propbinder/mobile-design 0.2.46 → 0.2.48
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/fesm2022/propbinder-mobile-design.mjs +608 -311
- package/fesm2022/propbinder-mobile-design.mjs.map +1 -1
- package/index.d.ts +122 -24
- package/package.json +1 -1
- package/styles/ionic.css +26 -7
- package/styles/mobile-page-base.css +4 -6
package/index.d.ts
CHANGED
|
@@ -43,6 +43,13 @@ type NetworkStatus = 'online' | 'offline' | 'unknown';
|
|
|
43
43
|
* @internal This is a base class and should not be used directly.
|
|
44
44
|
*/
|
|
45
45
|
declare abstract class MobilePageBase implements OnDestroy {
|
|
46
|
+
/**
|
|
47
|
+
* Shows a loading overlay above page content area.
|
|
48
|
+
*
|
|
49
|
+
* Non-breaking: defaults to false, so existing pages are unchanged
|
|
50
|
+
* until they explicitly opt in.
|
|
51
|
+
*/
|
|
52
|
+
contentLoading: _angular_core.InputSignal<boolean>;
|
|
46
53
|
/**
|
|
47
54
|
* Maximum content width (desktop only)
|
|
48
55
|
*
|
|
@@ -136,7 +143,7 @@ declare abstract class MobilePageBase implements OnDestroy {
|
|
|
136
143
|
*/
|
|
137
144
|
ngOnDestroy(): void;
|
|
138
145
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<MobilePageBase, never>;
|
|
139
|
-
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<MobilePageBase, never, never, { "contentWidth": { "alias": "contentWidth"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
146
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<MobilePageBase, never, never, { "contentLoading": { "alias": "contentLoading"; "required": false; "isSignal": true; }; "contentWidth": { "alias": "contentWidth"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
140
147
|
}
|
|
141
148
|
|
|
142
149
|
interface ActionResult {
|
|
@@ -731,7 +738,7 @@ declare class DsMobilePageMainComponent extends MobilePageBase implements AfterV
|
|
|
731
738
|
title: _angular_core.InputSignal<string>;
|
|
732
739
|
headerTitle: _angular_core.InputSignal<string>;
|
|
733
740
|
headerSubtitle: _angular_core.InputSignal<string>;
|
|
734
|
-
avatarType: _angular_core.InputSignal<"
|
|
741
|
+
avatarType: _angular_core.InputSignal<"photo" | "initials" | "icon">;
|
|
735
742
|
avatarInitials: _angular_core.InputSignal<string>;
|
|
736
743
|
avatarSrc: _angular_core.InputSignal<string>;
|
|
737
744
|
avatarIconName: _angular_core.InputSignal<string>;
|
|
@@ -1577,11 +1584,19 @@ declare class DsMobileCommentComponent {
|
|
|
1577
1584
|
/**
|
|
1578
1585
|
* Avatar type
|
|
1579
1586
|
*/
|
|
1580
|
-
avatarType: _angular_core.InputSignal<"
|
|
1587
|
+
avatarType: _angular_core.InputSignal<"photo" | "initials" | "icon">;
|
|
1581
1588
|
/**
|
|
1582
1589
|
* Whether the comment is clickable
|
|
1583
1590
|
*/
|
|
1584
1591
|
clickable: _angular_core.InputSignal<boolean>;
|
|
1592
|
+
/**
|
|
1593
|
+
* Unified toggle for contextual actions (more button + long press).
|
|
1594
|
+
* - `true` — more button visible on **all** breakpoints, long press enabled
|
|
1595
|
+
* - `false` — more button hidden, long press suppressed
|
|
1596
|
+
* - `undefined` (default) — falls back to desktop-only button
|
|
1597
|
+
*/
|
|
1598
|
+
moreActions: _angular_core.InputSignal<boolean | undefined>;
|
|
1599
|
+
shouldShowMoreButton: _angular_core.Signal<boolean>;
|
|
1585
1600
|
/**
|
|
1586
1601
|
* Whether this comment belongs to the current user
|
|
1587
1602
|
*/
|
|
@@ -1668,7 +1683,7 @@ declare class DsMobileCommentComponent {
|
|
|
1668
1683
|
*/
|
|
1669
1684
|
handleMoreButtonClick(event: Event): void;
|
|
1670
1685
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileCommentComponent, never>;
|
|
1671
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobileCommentComponent, "ds-mobile-comment", never, { "authorName": { "alias": "authorName"; "required": true; "isSignal": true; }; "authorRole": { "alias": "authorRole"; "required": true; "isSignal": true; }; "timestamp": { "alias": "timestamp"; "required": true; "isSignal": true; }; "content": { "alias": "content"; "required": true; "isSignal": true; }; "avatarInitials": { "alias": "avatarInitials"; "required": false; "isSignal": true; }; "avatarType": { "alias": "avatarType"; "required": false; "isSignal": true; }; "clickable": { "alias": "clickable"; "required": false; "isSignal": true; }; "isOwnComment": { "alias": "isOwnComment"; "required": false; "isSignal": true; }; "isLiked": { "alias": "isLiked"; "required": false; "isSignal": true; }; "likeCount": { "alias": "likeCount"; "required": false; "isSignal": true; }; }, { "likeToggled": "likeToggled"; "commentClick": "commentClick"; "replyClick": "replyClick"; "editClick": "editClick"; "longPress": "longPress"; }, never, never, true, never>;
|
|
1686
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobileCommentComponent, "ds-mobile-comment", never, { "authorName": { "alias": "authorName"; "required": true; "isSignal": true; }; "authorRole": { "alias": "authorRole"; "required": true; "isSignal": true; }; "timestamp": { "alias": "timestamp"; "required": true; "isSignal": true; }; "content": { "alias": "content"; "required": true; "isSignal": true; }; "avatarInitials": { "alias": "avatarInitials"; "required": false; "isSignal": true; }; "avatarType": { "alias": "avatarType"; "required": false; "isSignal": true; }; "clickable": { "alias": "clickable"; "required": false; "isSignal": true; }; "moreActions": { "alias": "moreActions"; "required": false; "isSignal": true; }; "isOwnComment": { "alias": "isOwnComment"; "required": false; "isSignal": true; }; "isLiked": { "alias": "isLiked"; "required": false; "isSignal": true; }; "likeCount": { "alias": "likeCount"; "required": false; "isSignal": true; }; }, { "likeToggled": "likeToggled"; "commentClick": "commentClick"; "replyClick": "replyClick"; "editClick": "editClick"; "longPress": "longPress"; }, never, never, true, never>;
|
|
1672
1687
|
}
|
|
1673
1688
|
|
|
1674
1689
|
/**
|
|
@@ -1696,7 +1711,7 @@ declare class DsMobilePostComposerComponent {
|
|
|
1696
1711
|
/**
|
|
1697
1712
|
* Avatar type
|
|
1698
1713
|
*/
|
|
1699
|
-
avatarType: _angular_core.InputSignal<"
|
|
1714
|
+
avatarType: _angular_core.InputSignal<"photo" | "initials" | "icon">;
|
|
1700
1715
|
/**
|
|
1701
1716
|
* Avatar photo source (for photo type)
|
|
1702
1717
|
*/
|
|
@@ -1988,7 +2003,7 @@ declare class DsMobileMessageComposerComponent implements AfterViewInit, OnDestr
|
|
|
1988
2003
|
/**
|
|
1989
2004
|
* Avatar type
|
|
1990
2005
|
*/
|
|
1991
|
-
avatarType: _angular_core.InputSignal<"
|
|
2006
|
+
avatarType: _angular_core.InputSignal<"photo" | "initials" | "icon">;
|
|
1992
2007
|
/**
|
|
1993
2008
|
* Avatar photo source (for photo type)
|
|
1994
2009
|
*/
|
|
@@ -2309,7 +2324,7 @@ declare class DsMobileMessageBubbleComponent {
|
|
|
2309
2324
|
/**
|
|
2310
2325
|
* Avatar type
|
|
2311
2326
|
*/
|
|
2312
|
-
avatarType: _angular_core.InputSignal<"
|
|
2327
|
+
avatarType: _angular_core.InputSignal<"photo" | "initials" | "icon">;
|
|
2313
2328
|
/**
|
|
2314
2329
|
* Avatar photo source (for photo type)
|
|
2315
2330
|
*/
|
|
@@ -2603,11 +2618,22 @@ declare class DsMobileListItemComponent implements AfterViewInit {
|
|
|
2603
2618
|
enableLongPress: _angular_core.InputSignal<boolean>;
|
|
2604
2619
|
/**
|
|
2605
2620
|
* Show "more actions" button on desktop for items with long-press enabled
|
|
2606
|
-
*
|
|
2607
|
-
* Clicking this button triggers the same handler as long-press on mobile
|
|
2621
|
+
* @deprecated Use `moreActions` instead. Kept for backwards compatibility.
|
|
2608
2622
|
* @default true
|
|
2609
2623
|
*/
|
|
2610
2624
|
showDesktopMoreButton: _angular_core.InputSignal<boolean>;
|
|
2625
|
+
/**
|
|
2626
|
+
* Unified toggle for contextual actions (more button + long press).
|
|
2627
|
+
* - `true` — more button visible on **all** breakpoints, long press enabled
|
|
2628
|
+
* - `false` — more button hidden, long press suppressed
|
|
2629
|
+
* - `undefined` (default) — falls back to legacy `enableLongPress` + `showDesktopMoreButton` + desktop check
|
|
2630
|
+
*/
|
|
2631
|
+
moreActions: _angular_core.InputSignal<boolean | undefined>;
|
|
2632
|
+
/**
|
|
2633
|
+
* Resolved visibility of the more-actions button.
|
|
2634
|
+
* When `moreActions` is set it takes precedence; otherwise legacy inputs + breakpoint apply.
|
|
2635
|
+
*/
|
|
2636
|
+
shouldShowMoreButton: _angular_core.Signal<boolean>;
|
|
2611
2637
|
/**
|
|
2612
2638
|
* Offset distance for the interactive background pseudo-element
|
|
2613
2639
|
* Extends the background beyond the content bounds
|
|
@@ -2679,7 +2705,7 @@ declare class DsMobileListItemComponent implements AfterViewInit {
|
|
|
2679
2705
|
*/
|
|
2680
2706
|
handleMoreButtonClick(event: Event): void;
|
|
2681
2707
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileListItemComponent, never>;
|
|
2682
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobileListItemComponent, "ds-mobile-list-item", never, { "leadingSize": { "alias": "leadingSize"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "interactive": { "alias": "interactive"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "enableLongPress": { "alias": "enableLongPress"; "required": false; "isSignal": true; }; "showDesktopMoreButton": { "alias": "showDesktopMoreButton"; "required": false; "isSignal": true; }; "interactiveOffset": { "alias": "interactiveOffset"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "subtitle": { "alias": "subtitle"; "required": false; "isSignal": true; }; "showDivider": { "alias": "showDivider"; "required": false; "isSignal": true; }; "dividerSpacing": { "alias": "dividerSpacing"; "required": false; "isSignal": true; }; }, { "itemClick": "itemClick"; "moreButtonClick": "moreButtonClick"; }, never, ["[content-leading]", "[content-main]", "*", "[content-trailing]"], true, [{ directive: typeof DsMobileLongPressDirective; inputs: {}; outputs: { "longPress": "longPress"; }; }]>;
|
|
2708
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobileListItemComponent, "ds-mobile-list-item", never, { "leadingSize": { "alias": "leadingSize"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "interactive": { "alias": "interactive"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "enableLongPress": { "alias": "enableLongPress"; "required": false; "isSignal": true; }; "showDesktopMoreButton": { "alias": "showDesktopMoreButton"; "required": false; "isSignal": true; }; "moreActions": { "alias": "moreActions"; "required": false; "isSignal": true; }; "interactiveOffset": { "alias": "interactiveOffset"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "subtitle": { "alias": "subtitle"; "required": false; "isSignal": true; }; "showDivider": { "alias": "showDivider"; "required": false; "isSignal": true; }; "dividerSpacing": { "alias": "dividerSpacing"; "required": false; "isSignal": true; }; }, { "itemClick": "itemClick"; "moreButtonClick": "moreButtonClick"; }, never, ["[content-leading]", "[content-main]", "*", "[content-trailing]"], true, [{ directive: typeof DsMobileLongPressDirective; inputs: {}; outputs: { "longPress": "longPress"; }; }]>;
|
|
2683
2709
|
}
|
|
2684
2710
|
|
|
2685
2711
|
/**
|
|
@@ -2825,7 +2851,7 @@ declare class DsMobileInteractiveListItemPostComponent {
|
|
|
2825
2851
|
/**
|
|
2826
2852
|
* Avatar type
|
|
2827
2853
|
*/
|
|
2828
|
-
avatarType: _angular_core.InputSignal<"
|
|
2854
|
+
avatarType: _angular_core.InputSignal<"photo" | "initials" | "icon">;
|
|
2829
2855
|
/**
|
|
2830
2856
|
* Avatar photo source (for photo type)
|
|
2831
2857
|
*/
|
|
@@ -2862,6 +2888,11 @@ declare class DsMobileInteractiveListItemPostComponent {
|
|
|
2862
2888
|
* @default true
|
|
2863
2889
|
*/
|
|
2864
2890
|
enableLongPress: _angular_core.InputSignal<boolean>;
|
|
2891
|
+
/**
|
|
2892
|
+
* Unified toggle for contextual actions (more button + long press).
|
|
2893
|
+
* When set, takes precedence over `enableLongPress`.
|
|
2894
|
+
*/
|
|
2895
|
+
moreActions: _angular_core.InputSignal<boolean | undefined>;
|
|
2865
2896
|
/**
|
|
2866
2897
|
* Emits when the post card is clicked (if clickable)
|
|
2867
2898
|
*/
|
|
@@ -2879,7 +2910,7 @@ declare class DsMobileInteractiveListItemPostComponent {
|
|
|
2879
2910
|
handleLongPress(): void;
|
|
2880
2911
|
handleMoreButtonClick(event: Event): void;
|
|
2881
2912
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileInteractiveListItemPostComponent, never>;
|
|
2882
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobileInteractiveListItemPostComponent, "ds-mobile-interactive-list-item-post", never, { "authorName": { "alias": "authorName"; "required": true; "isSignal": true; }; "authorRole": { "alias": "authorRole"; "required": true; "isSignal": true; }; "timestamp": { "alias": "timestamp"; "required": true; "isSignal": true; }; "avatarInitials": { "alias": "avatarInitials"; "required": false; "isSignal": true; }; "avatarType": { "alias": "avatarType"; "required": false; "isSignal": true; }; "avatarSrc": { "alias": "avatarSrc"; "required": false; "isSignal": true; }; "avatarIconName": { "alias": "avatarIconName"; "required": false; "isSignal": true; }; "showBadge": { "alias": "showBadge"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "clickable": { "alias": "clickable"; "required": false; "isSignal": true; }; "enableLongPress": { "alias": "enableLongPress"; "required": false; "isSignal": true; }; }, { "postClick": "postClick"; "commentClick": "commentClick"; "longPress": "longPress"; }, never, ["post-menu", "post-content", "post-actions"], true, never>;
|
|
2913
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobileInteractiveListItemPostComponent, "ds-mobile-interactive-list-item-post", never, { "authorName": { "alias": "authorName"; "required": true; "isSignal": true; }; "authorRole": { "alias": "authorRole"; "required": true; "isSignal": true; }; "timestamp": { "alias": "timestamp"; "required": true; "isSignal": true; }; "avatarInitials": { "alias": "avatarInitials"; "required": false; "isSignal": true; }; "avatarType": { "alias": "avatarType"; "required": false; "isSignal": true; }; "avatarSrc": { "alias": "avatarSrc"; "required": false; "isSignal": true; }; "avatarIconName": { "alias": "avatarIconName"; "required": false; "isSignal": true; }; "showBadge": { "alias": "showBadge"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "clickable": { "alias": "clickable"; "required": false; "isSignal": true; }; "enableLongPress": { "alias": "enableLongPress"; "required": false; "isSignal": true; }; "moreActions": { "alias": "moreActions"; "required": false; "isSignal": true; }; }, { "postClick": "postClick"; "commentClick": "commentClick"; "longPress": "longPress"; }, never, ["post-menu", "post-content", "post-actions"], true, never>;
|
|
2883
2914
|
}
|
|
2884
2915
|
/**
|
|
2885
2916
|
* PostContentComponent
|
|
@@ -3089,6 +3120,11 @@ declare class DsMobileInteractiveListItemInquiryComponent {
|
|
|
3089
3120
|
* @default true
|
|
3090
3121
|
*/
|
|
3091
3122
|
enableLongPress: _angular_core.InputSignal<boolean>;
|
|
3123
|
+
/**
|
|
3124
|
+
* Unified toggle for contextual actions (more button + long press).
|
|
3125
|
+
* When set, takes precedence over `enableLongPress`.
|
|
3126
|
+
*/
|
|
3127
|
+
moreActions: _angular_core.InputSignal<boolean | undefined>;
|
|
3092
3128
|
/**
|
|
3093
3129
|
* Emits when the inquiry item is clicked (if clickable)
|
|
3094
3130
|
*/
|
|
@@ -3105,7 +3141,7 @@ declare class DsMobileInteractiveListItemInquiryComponent {
|
|
|
3105
3141
|
handleLongPress(): void;
|
|
3106
3142
|
handleMoreButtonClick(event: Event): void;
|
|
3107
3143
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileInteractiveListItemInquiryComponent, never>;
|
|
3108
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobileInteractiveListItemInquiryComponent, "ds-mobile-interactive-list-item-inquiry", never, { "title": { "alias": "title"; "required": true; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "status": { "alias": "status"; "required": false; "isSignal": true; }; "statusLabel": { "alias": "statusLabel"; "required": false; "isSignal": true; }; "timestamp": { "alias": "timestamp"; "required": true; "isSignal": true; }; "iconName": { "alias": "iconName"; "required": false; "isSignal": true; }; "iconColor": { "alias": "iconColor"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "clickable": { "alias": "clickable"; "required": false; "isSignal": true; }; "showChevron": { "alias": "showChevron"; "required": false; "isSignal": true; }; "enableLongPress": { "alias": "enableLongPress"; "required": false; "isSignal": true; }; }, { "inquiryClick": "inquiryClick"; "longPress": "longPress"; }, never, never, true, never>;
|
|
3144
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobileInteractiveListItemInquiryComponent, "ds-mobile-interactive-list-item-inquiry", never, { "title": { "alias": "title"; "required": true; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "status": { "alias": "status"; "required": false; "isSignal": true; }; "statusLabel": { "alias": "statusLabel"; "required": false; "isSignal": true; }; "timestamp": { "alias": "timestamp"; "required": true; "isSignal": true; }; "iconName": { "alias": "iconName"; "required": false; "isSignal": true; }; "iconColor": { "alias": "iconColor"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "clickable": { "alias": "clickable"; "required": false; "isSignal": true; }; "showChevron": { "alias": "showChevron"; "required": false; "isSignal": true; }; "enableLongPress": { "alias": "enableLongPress"; "required": false; "isSignal": true; }; "moreActions": { "alias": "moreActions"; "required": false; "isSignal": true; }; }, { "inquiryClick": "inquiryClick"; "longPress": "longPress"; }, never, never, true, never>;
|
|
3109
3145
|
}
|
|
3110
3146
|
|
|
3111
3147
|
/**
|
|
@@ -3153,7 +3189,7 @@ declare class DsMobileInteractiveListItemMessageComponent {
|
|
|
3153
3189
|
/**
|
|
3154
3190
|
* Avatar type
|
|
3155
3191
|
*/
|
|
3156
|
-
avatarType: _angular_core.InputSignal<"
|
|
3192
|
+
avatarType: _angular_core.InputSignal<"photo" | "initials" | "icon">;
|
|
3157
3193
|
/**
|
|
3158
3194
|
* Avatar photo source (for photo type)
|
|
3159
3195
|
*/
|
|
@@ -3328,6 +3364,11 @@ declare class DsMobileInteractiveListItemBookingComponent {
|
|
|
3328
3364
|
* @default true
|
|
3329
3365
|
*/
|
|
3330
3366
|
enableLongPress: _angular_core.InputSignal<boolean>;
|
|
3367
|
+
/**
|
|
3368
|
+
* Unified toggle for contextual actions (more button + long press).
|
|
3369
|
+
* When set, takes precedence over `enableLongPress`.
|
|
3370
|
+
*/
|
|
3371
|
+
moreActions: _angular_core.InputSignal<boolean | undefined>;
|
|
3331
3372
|
/**
|
|
3332
3373
|
* Emits when the booking item is clicked (if clickable)
|
|
3333
3374
|
*/
|
|
@@ -3344,7 +3385,7 @@ declare class DsMobileInteractiveListItemBookingComponent {
|
|
|
3344
3385
|
handleLongPress(): void;
|
|
3345
3386
|
handleMoreButtonClick(event: Event): void;
|
|
3346
3387
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileInteractiveListItemBookingComponent, never>;
|
|
3347
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobileInteractiveListItemBookingComponent, "ds-mobile-interactive-list-item-booking", never, { "thumbnail": { "alias": "thumbnail"; "required": false; "isSignal": true; }; "facilityTitle": { "alias": "facilityTitle"; "required": true; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "bookingDate": { "alias": "bookingDate"; "required": false; "isSignal": true; }; "bookingTime": { "alias": "bookingTime"; "required": false; "isSignal": true; }; "availabilityStatus": { "alias": "availabilityStatus"; "required": false; "isSignal": true; }; "statusLabel": { "alias": "statusLabel"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "clickable": { "alias": "clickable"; "required": false; "isSignal": true; }; "showChevron": { "alias": "showChevron"; "required": false; "isSignal": true; }; "enableLongPress": { "alias": "enableLongPress"; "required": false; "isSignal": true; }; }, { "bookingClick": "bookingClick"; "longPress": "longPress"; }, never, never, true, never>;
|
|
3388
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobileInteractiveListItemBookingComponent, "ds-mobile-interactive-list-item-booking", never, { "thumbnail": { "alias": "thumbnail"; "required": false; "isSignal": true; }; "facilityTitle": { "alias": "facilityTitle"; "required": true; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "bookingDate": { "alias": "bookingDate"; "required": false; "isSignal": true; }; "bookingTime": { "alias": "bookingTime"; "required": false; "isSignal": true; }; "availabilityStatus": { "alias": "availabilityStatus"; "required": false; "isSignal": true; }; "statusLabel": { "alias": "statusLabel"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "clickable": { "alias": "clickable"; "required": false; "isSignal": true; }; "showChevron": { "alias": "showChevron"; "required": false; "isSignal": true; }; "enableLongPress": { "alias": "enableLongPress"; "required": false; "isSignal": true; }; "moreActions": { "alias": "moreActions"; "required": false; "isSignal": true; }; }, { "bookingClick": "bookingClick"; "longPress": "longPress"; }, never, never, true, never>;
|
|
3348
3389
|
}
|
|
3349
3390
|
|
|
3350
3391
|
interface TabConfig {
|
|
@@ -4535,6 +4576,13 @@ declare abstract class MobileModalBase implements OnInit, OnDestroy {
|
|
|
4535
4576
|
* @default false
|
|
4536
4577
|
*/
|
|
4537
4578
|
isAutoHeight: _angular_core.InputSignal<boolean>;
|
|
4579
|
+
/**
|
|
4580
|
+
* Controls how modal content behaves when the keyboard opens.
|
|
4581
|
+
* - 'follow': content is pushed to follow keyboard movement
|
|
4582
|
+
* - 'overlay': keyboard/footer overlays lower content (no auto scroll push)
|
|
4583
|
+
* @default 'follow'
|
|
4584
|
+
*/
|
|
4585
|
+
keyboardContentBehavior: _angular_core.InputSignal<"overlay" | "follow">;
|
|
4538
4586
|
/**
|
|
4539
4587
|
* Emitted when modal is closed
|
|
4540
4588
|
*/
|
|
@@ -4581,8 +4629,16 @@ declare abstract class MobileModalBase implements OnInit, OnDestroy {
|
|
|
4581
4629
|
* @protected
|
|
4582
4630
|
*/
|
|
4583
4631
|
protected isThisModal(modalElement: HTMLIonModalElement): boolean;
|
|
4632
|
+
/**
|
|
4633
|
+
* Returns true when keyboard should overlay content without push-scrolling.
|
|
4634
|
+
*/
|
|
4635
|
+
private isOverlayBehavior;
|
|
4636
|
+
/**
|
|
4637
|
+
* Computes scroll bottom inset for current keyboard behavior.
|
|
4638
|
+
*/
|
|
4639
|
+
private getScrollPadding;
|
|
4584
4640
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<MobileModalBase, never>;
|
|
4585
|
-
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<MobileModalBase, never, never, { "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "headerTitle": { "alias": "headerTitle"; "required": false; "isSignal": true; }; "headerMeta": { "alias": "headerMeta"; "required": false; "isSignal": true; }; "closeButtonLabel": { "alias": "closeButtonLabel"; "required": false; "isSignal": true; }; "enableKeyboardHandling": { "alias": "enableKeyboardHandling"; "required": false; "isSignal": true; }; "hasFixedBottom": { "alias": "hasFixedBottom"; "required": false; "isSignal": true; }; "contentPadding": { "alias": "contentPadding"; "required": false; "isSignal": true; }; "isAutoHeight": { "alias": "isAutoHeight"; "required": false; "isSignal": true; }; }, { "closed": "closed"; "keyboardWillShow": "keyboardWillShow"; "keyboardWillHide": "keyboardWillHide"; }, never, never, true, never>;
|
|
4641
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<MobileModalBase, never, never, { "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "headerTitle": { "alias": "headerTitle"; "required": false; "isSignal": true; }; "headerMeta": { "alias": "headerMeta"; "required": false; "isSignal": true; }; "closeButtonLabel": { "alias": "closeButtonLabel"; "required": false; "isSignal": true; }; "enableKeyboardHandling": { "alias": "enableKeyboardHandling"; "required": false; "isSignal": true; }; "hasFixedBottom": { "alias": "hasFixedBottom"; "required": false; "isSignal": true; }; "contentPadding": { "alias": "contentPadding"; "required": false; "isSignal": true; }; "isAutoHeight": { "alias": "isAutoHeight"; "required": false; "isSignal": true; }; "keyboardContentBehavior": { "alias": "keyboardContentBehavior"; "required": false; "isSignal": true; }; }, { "closed": "closed"; "keyboardWillShow": "keyboardWillShow"; "keyboardWillHide": "keyboardWillHide"; }, never, never, true, never>;
|
|
4586
4642
|
}
|
|
4587
4643
|
|
|
4588
4644
|
/**
|
|
@@ -4597,6 +4653,7 @@ declare abstract class MobileModalBase implements OnInit, OnDestroy {
|
|
|
4597
4653
|
* - Default loading and error state templates (with override capability)
|
|
4598
4654
|
* - Fixed bottom component support (e.g., message composer)
|
|
4599
4655
|
* - Automatic keyboard handling
|
|
4656
|
+
* - Configurable keyboard content behavior (`follow` or `overlay`)
|
|
4600
4657
|
* - Safe area support
|
|
4601
4658
|
*
|
|
4602
4659
|
* **Slot Structure:**
|
|
@@ -4639,7 +4696,8 @@ declare abstract class MobileModalBase implements OnInit, OnDestroy {
|
|
|
4639
4696
|
* <ds-mobile-modal-base
|
|
4640
4697
|
* headerTitle="Create Inquiry"
|
|
4641
4698
|
* [hasFixedBottom]="true"
|
|
4642
|
-
* [enableKeyboardHandling]="true"
|
|
4699
|
+
* [enableKeyboardHandling]="true"
|
|
4700
|
+
* [keyboardContentBehavior]="'overlay'">
|
|
4643
4701
|
*
|
|
4644
4702
|
* <div class="content">
|
|
4645
4703
|
* <input type="text" placeholder="Type something..." />
|
|
@@ -4694,6 +4752,10 @@ declare class DsMobileModalBaseComponent extends MobileModalBase implements OnIn
|
|
|
4694
4752
|
* Determine if header should be shown based on showHeader input and content detection
|
|
4695
4753
|
*/
|
|
4696
4754
|
shouldShowHeader(): boolean;
|
|
4755
|
+
/**
|
|
4756
|
+
* Check whether header-leading slot has actual projected content.
|
|
4757
|
+
*/
|
|
4758
|
+
hasHeaderLeadingContent(): boolean;
|
|
4697
4759
|
/**
|
|
4698
4760
|
* Check if a content child slot has actual content
|
|
4699
4761
|
*/
|
|
@@ -4831,6 +4893,10 @@ declare class DsMobilePostDetailModalComponent implements OnInit, AfterViewInit
|
|
|
4831
4893
|
currentUserInitialsInput: string;
|
|
4832
4894
|
loading: boolean;
|
|
4833
4895
|
error: string | undefined;
|
|
4896
|
+
onTogglePostLike?: (payload: {
|
|
4897
|
+
postId: string;
|
|
4898
|
+
active: boolean;
|
|
4899
|
+
}) => void;
|
|
4834
4900
|
onSubmitComment?: (payload: {
|
|
4835
4901
|
postId: string;
|
|
4836
4902
|
text: string;
|
|
@@ -4891,6 +4957,13 @@ declare class DsMobilePostDetailModalComponent implements OnInit, AfterViewInit
|
|
|
4891
4957
|
* Handle edit comment
|
|
4892
4958
|
*/
|
|
4893
4959
|
handleEditComment(comment: CommentData): void;
|
|
4960
|
+
/**
|
|
4961
|
+
* Handle post like/unlike toggle
|
|
4962
|
+
*/
|
|
4963
|
+
handlePostLikeToggle(ev: {
|
|
4964
|
+
active: boolean;
|
|
4965
|
+
count: number;
|
|
4966
|
+
}): void;
|
|
4894
4967
|
/**
|
|
4895
4968
|
* Handle comment like/unlike toggle
|
|
4896
4969
|
* @param comment The comment being liked/unliked
|
|
@@ -4913,7 +4986,7 @@ declare class DsMobilePostDetailModalComponent implements OnInit, AfterViewInit
|
|
|
4913
4986
|
*/
|
|
4914
4987
|
handleCommentLongPress(authorName: string, content: string, isOwnComment: boolean): Promise<void>;
|
|
4915
4988
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobilePostDetailModalComponent, never>;
|
|
4916
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobilePostDetailModalComponent, "ds-mobile-post-detail-modal", never, { "postData": { "alias": "postData"; "required": false; }; "currentUserName": { "alias": "currentUserName"; "required": false; }; "currentUserInitialsInput": { "alias": "currentUserInitialsInput"; "required": false; }; "loading": { "alias": "loading"; "required": false; }; "error": { "alias": "error"; "required": false; }; "onSubmitComment": { "alias": "onSubmitComment"; "required": false; }; "onToggleCommentLike": { "alias": "onToggleCommentLike"; "required": false; }; "onEditComment": { "alias": "onEditComment"; "required": false; }; "onDeleteComment": { "alias": "onDeleteComment"; "required": false; }; }, {}, never, never, true, never>;
|
|
4989
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobilePostDetailModalComponent, "ds-mobile-post-detail-modal", never, { "postData": { "alias": "postData"; "required": false; }; "currentUserName": { "alias": "currentUserName"; "required": false; }; "currentUserInitialsInput": { "alias": "currentUserInitialsInput"; "required": false; }; "loading": { "alias": "loading"; "required": false; }; "error": { "alias": "error"; "required": false; }; "onTogglePostLike": { "alias": "onTogglePostLike"; "required": false; }; "onSubmitComment": { "alias": "onSubmitComment"; "required": false; }; "onToggleCommentLike": { "alias": "onToggleCommentLike"; "required": false; }; "onEditComment": { "alias": "onEditComment"; "required": false; }; "onDeleteComment": { "alias": "onDeleteComment"; "required": false; }; }, {}, never, never, true, never>;
|
|
4917
4990
|
}
|
|
4918
4991
|
|
|
4919
4992
|
/**
|
|
@@ -5047,6 +5120,10 @@ declare class DsMobilePostDetailModalService extends BaseModalService {
|
|
|
5047
5120
|
open(postData: PostDetailData, options?: {
|
|
5048
5121
|
loading?: boolean;
|
|
5049
5122
|
error?: string;
|
|
5123
|
+
onTogglePostLike?: (payload: {
|
|
5124
|
+
postId: string;
|
|
5125
|
+
active: boolean;
|
|
5126
|
+
}) => void;
|
|
5050
5127
|
onSubmitComment?: (payload: {
|
|
5051
5128
|
postId: string;
|
|
5052
5129
|
text: string;
|
|
@@ -5505,7 +5582,7 @@ declare class DsMobileChatModalComponent implements OnInit, AfterViewInit {
|
|
|
5505
5582
|
participant: _angular_core.WritableSignal<ChatParticipant>;
|
|
5506
5583
|
messages: _angular_core.WritableSignal<ChatMessage[]>;
|
|
5507
5584
|
currentUserInitials: _angular_core.WritableSignal<string>;
|
|
5508
|
-
currentUserAvatarType: _angular_core.WritableSignal<"
|
|
5585
|
+
currentUserAvatarType: _angular_core.WritableSignal<"photo" | "initials" | "icon">;
|
|
5509
5586
|
currentUserAvatarSrc: _angular_core.WritableSignal<string>;
|
|
5510
5587
|
autoFocus: _angular_core.WritableSignal<boolean>;
|
|
5511
5588
|
/**
|
|
@@ -5763,6 +5840,7 @@ interface NewInquiryData {
|
|
|
5763
5840
|
declare class DsMobileNewInquiryModalComponent implements OnInit, AfterViewInit {
|
|
5764
5841
|
private modalController;
|
|
5765
5842
|
titleInputRef?: ElementRef<HTMLElement>;
|
|
5843
|
+
descriptionInputRef?: ElementRef<HTMLElement>;
|
|
5766
5844
|
titleInput?: DsTextareaComponent;
|
|
5767
5845
|
fileInput?: ElementRef<HTMLInputElement>;
|
|
5768
5846
|
/**
|
|
@@ -5815,10 +5893,18 @@ declare class DsMobileNewInquiryModalComponent implements OnInit, AfterViewInit
|
|
|
5815
5893
|
* Auto-resize the title textarea based on content
|
|
5816
5894
|
*/
|
|
5817
5895
|
private autoResizeTitleTextarea;
|
|
5896
|
+
/**
|
|
5897
|
+
* Auto-resize the description textarea based on content
|
|
5898
|
+
*/
|
|
5899
|
+
private autoResizeDescriptionTextarea;
|
|
5818
5900
|
/**
|
|
5819
5901
|
* Handle title change with auto-resize
|
|
5820
5902
|
*/
|
|
5821
5903
|
handleTitleChange(value: string): void;
|
|
5904
|
+
/**
|
|
5905
|
+
* Handle description change with auto-resize
|
|
5906
|
+
*/
|
|
5907
|
+
handleDescriptionChange(value: string): void;
|
|
5822
5908
|
/**
|
|
5823
5909
|
* Validate form fields
|
|
5824
5910
|
*/
|
|
@@ -6167,6 +6253,7 @@ declare class DsMobileFacilityCreationModalComponent implements OnInit, AfterVie
|
|
|
6167
6253
|
private modalController;
|
|
6168
6254
|
private bottomSheetService;
|
|
6169
6255
|
titleInputRef?: ElementRef<HTMLElement>;
|
|
6256
|
+
descriptionInputRef?: ElementRef<HTMLElement>;
|
|
6170
6257
|
titleInput?: DsTextareaComponent;
|
|
6171
6258
|
fileInput?: ElementRef<HTMLInputElement>;
|
|
6172
6259
|
/**
|
|
@@ -6235,10 +6322,18 @@ declare class DsMobileFacilityCreationModalComponent implements OnInit, AfterVie
|
|
|
6235
6322
|
* Auto-resize the title textarea based on content
|
|
6236
6323
|
*/
|
|
6237
6324
|
private autoResizeTitleTextarea;
|
|
6325
|
+
/**
|
|
6326
|
+
* Auto-resize the description textarea based on content
|
|
6327
|
+
*/
|
|
6328
|
+
private autoResizeDescriptionTextarea;
|
|
6238
6329
|
/**
|
|
6239
6330
|
* Handle title change with auto-resize
|
|
6240
6331
|
*/
|
|
6241
6332
|
handleTitleChange(value: string): void;
|
|
6333
|
+
/**
|
|
6334
|
+
* Handle description change with auto-resize
|
|
6335
|
+
*/
|
|
6336
|
+
handleDescriptionChange(value: string): void;
|
|
6242
6337
|
/**
|
|
6243
6338
|
* Validate form fields
|
|
6244
6339
|
*/
|
|
@@ -7096,7 +7191,7 @@ declare class DsMobileHandbookFolderMiniComponent {
|
|
|
7096
7191
|
* ```
|
|
7097
7192
|
*/
|
|
7098
7193
|
declare class DsTextInputComponent implements ControlValueAccessor {
|
|
7099
|
-
type: _angular_core.InputSignal<"search" | "text" | "
|
|
7194
|
+
type: _angular_core.InputSignal<"search" | "text" | "email" | "tel" | "url" | "password">;
|
|
7100
7195
|
placeholder: _angular_core.InputSignal<string>;
|
|
7101
7196
|
disabled: _angular_core.InputSignal<boolean>;
|
|
7102
7197
|
readonly: _angular_core.InputSignal<boolean>;
|
|
@@ -7104,7 +7199,7 @@ declare class DsTextInputComponent implements ControlValueAccessor {
|
|
|
7104
7199
|
hasError: _angular_core.InputSignal<boolean>;
|
|
7105
7200
|
errorMessage: _angular_core.InputSignal<string>;
|
|
7106
7201
|
autocomplete: _angular_core.InputSignal<string>;
|
|
7107
|
-
inputmode: _angular_core.InputSignal<"search" | "text" | "
|
|
7202
|
+
inputmode: _angular_core.InputSignal<"search" | "text" | "email" | "tel" | "url" | "numeric" | undefined>;
|
|
7108
7203
|
autoClearError: _angular_core.InputSignal<boolean>;
|
|
7109
7204
|
validator: _angular_core.InputSignal<((value: string) => boolean) | null>;
|
|
7110
7205
|
valueChange: _angular_core.OutputEmitterRef<string>;
|
|
@@ -7469,7 +7564,7 @@ declare class UserService {
|
|
|
7469
7564
|
private _avatarSrc;
|
|
7470
7565
|
private _profileMenuItems;
|
|
7471
7566
|
readonly avatarInitials: _angular_core.Signal<string>;
|
|
7472
|
-
readonly avatarType: _angular_core.Signal<"
|
|
7567
|
+
readonly avatarType: _angular_core.Signal<"photo" | "initials" | "icon">;
|
|
7473
7568
|
readonly avatarSrc: _angular_core.Signal<string>;
|
|
7474
7569
|
readonly profileMenuItems: _angular_core.Signal<ActionGroup[] | undefined>;
|
|
7475
7570
|
private profileActionSelectedSubject;
|
|
@@ -7687,6 +7782,7 @@ declare class MobileHomePageComponent implements OnInit {
|
|
|
7687
7782
|
private postsService;
|
|
7688
7783
|
private postModal;
|
|
7689
7784
|
private trackingPermissionService;
|
|
7785
|
+
private bottomSheet;
|
|
7690
7786
|
pageComponent: DsMobilePageMainComponent;
|
|
7691
7787
|
recentPosts: _angular_core.Signal<_propbinder_mobile_design.Post[]>;
|
|
7692
7788
|
private allInquiries;
|
|
@@ -7697,13 +7793,14 @@ declare class MobileHomePageComponent implements OnInit {
|
|
|
7697
7793
|
status: "open";
|
|
7698
7794
|
timestamp: string;
|
|
7699
7795
|
}[]>;
|
|
7700
|
-
constructor(router: Router, userService: UserService, postsService: PostsService, postModal: DsMobilePostDetailModalService, trackingPermissionService: TrackingPermissionService);
|
|
7796
|
+
constructor(router: Router, userService: UserService, postsService: PostsService, postModal: DsMobilePostDetailModalService, trackingPermissionService: TrackingPermissionService, bottomSheet: DsMobileBottomSheetService);
|
|
7701
7797
|
ngOnInit(): void;
|
|
7702
7798
|
handleRefresh(event: any): void;
|
|
7703
7799
|
openPost(postId: string, focusComment?: boolean): Promise<void>;
|
|
7704
7800
|
openInquiryDetail(inquiryId: string): void;
|
|
7705
7801
|
navigateToCommunity(): void;
|
|
7706
7802
|
navigateToInquiries(): void;
|
|
7803
|
+
handlePostLongPress(postId: string): Promise<void>;
|
|
7707
7804
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<MobileHomePageComponent, never>;
|
|
7708
7805
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<MobileHomePageComponent, "app-home-page", never, {}, {}, never, never, true, never>;
|
|
7709
7806
|
}
|
|
@@ -7834,9 +7931,10 @@ interface FacilityDetail {
|
|
|
7834
7931
|
declare class MobileBookingPageComponent {
|
|
7835
7932
|
private facilityModal;
|
|
7836
7933
|
private facilityCreationModal;
|
|
7934
|
+
userService: UserService;
|
|
7837
7935
|
pageComponent: DsMobilePageMainComponent;
|
|
7838
7936
|
bookingsSwiper?: DsMobileSwiperComponent;
|
|
7839
|
-
constructor(facilityModal: DsMobileFacilityDetailModalService, facilityCreationModal: DsMobileFacilityCreationModalService);
|
|
7937
|
+
constructor(facilityModal: DsMobileFacilityDetailModalService, facilityCreationModal: DsMobileFacilityCreationModalService, userService: UserService);
|
|
7840
7938
|
activeBookings: _angular_core.WritableSignal<FacilityDetail[]>;
|
|
7841
7939
|
availableFacilities: _angular_core.WritableSignal<FacilityDetail[]>;
|
|
7842
7940
|
handleRefresh(event: any): void;
|
package/package.json
CHANGED
package/styles/ionic.css
CHANGED
|
@@ -76,14 +76,28 @@
|
|
|
76
76
|
2. These CSS variables below
|
|
77
77
|
============================================ */
|
|
78
78
|
|
|
79
|
+
/* Normalized safe-area variables consumed by app layout styles.
|
|
80
|
+
Defaults to env() and can be overridden at runtime from SafeArea plugin. */
|
|
81
|
+
--app-safe-top: env(safe-area-inset-top, 0px);
|
|
82
|
+
--app-safe-right: env(safe-area-inset-right, 0px);
|
|
83
|
+
--app-safe-bottom: env(safe-area-inset-bottom, 0px);
|
|
84
|
+
--app-safe-left: env(safe-area-inset-left, 0px);
|
|
85
|
+
|
|
79
86
|
/* Sheet/modal top offset - positions content below status bar area */
|
|
80
87
|
/* Uses max() to ensure at least 32px offset even on devices without notch */
|
|
81
88
|
/* +12px adds breathing room below the status bar */
|
|
82
|
-
--app-sheet-top-offset: calc(max(32px,
|
|
89
|
+
--app-sheet-top-offset: calc(max(32px, var(--app-safe-top, 32px)) + 12px);
|
|
83
90
|
|
|
84
91
|
/* Header top offset - used to fine-tune header position on iOS with overlay: true */
|
|
85
92
|
/* On web (no safe area), this should be 0px. On iOS, it compensates for status bar overlap */
|
|
86
|
-
--app-header-top-offset: max(0px, calc(
|
|
93
|
+
--app-header-top-offset: max(0px, calc(var(--app-safe-top, 0px) - 16px));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/* Android-only top safe-area tuning:
|
|
97
|
+
add 8px extra breathing room above header/sheet content. */
|
|
98
|
+
.plt-android {
|
|
99
|
+
--app-sheet-top-offset: calc(max(32px, var(--app-safe-top, 32px)) + 20px);
|
|
100
|
+
--app-header-top-offset: max(0px, calc(var(--app-safe-top, 0px) - 8px));
|
|
87
101
|
}
|
|
88
102
|
|
|
89
103
|
/* Global Styles for Mobile App */
|
|
@@ -197,14 +211,14 @@ ion-content::part(scroll)::-webkit-scrollbar {
|
|
|
197
211
|
|
|
198
212
|
/* iOS-specific: Enable native scroll overshoot/bounce effect */
|
|
199
213
|
.plt-ios ion-content::part(scroll) {
|
|
200
|
-
overscroll-behavior-y:
|
|
214
|
+
overscroll-behavior-y: auto;
|
|
201
215
|
/* iOS: Set scroll container background to match brand secondary */
|
|
202
216
|
/* This prevents white background from showing when header fades on scroll */
|
|
203
217
|
background: var(--color-header-surface) !important;
|
|
204
218
|
}
|
|
205
219
|
|
|
206
220
|
.plt-ios .ion-page {
|
|
207
|
-
overscroll-behavior-y:
|
|
221
|
+
overscroll-behavior-y: auto;
|
|
208
222
|
/* Set page background to brand secondary to match header on iOS */
|
|
209
223
|
background: var(--color-header-surface) !important;
|
|
210
224
|
}
|
|
@@ -278,7 +292,7 @@ ion-spinner {
|
|
|
278
292
|
ion-modal:not(.ds-bottom-sheet) {
|
|
279
293
|
--background: var(--color-background-neutral-primary);
|
|
280
294
|
--border-radius: 16px;
|
|
281
|
-
--box-shadow:
|
|
295
|
+
--box-shadow: none;
|
|
282
296
|
/* Prevent modal from resizing when keyboard appears */
|
|
283
297
|
height: 100% !important;
|
|
284
298
|
max-height: 100vh !important;
|
|
@@ -297,6 +311,11 @@ ion-modal ion-content {
|
|
|
297
311
|
height: 100% !important;
|
|
298
312
|
}
|
|
299
313
|
|
|
314
|
+
/* Keep neutral cursor over dismissable backdrop areas */
|
|
315
|
+
ion-modal::part(backdrop) {
|
|
316
|
+
cursor: default !important;
|
|
317
|
+
}
|
|
318
|
+
|
|
300
319
|
ion-action-sheet {
|
|
301
320
|
--background: var(--color-background-neutral-primary);
|
|
302
321
|
--color: var(--text-color-default-primary);
|
|
@@ -325,7 +344,7 @@ ion-toast {
|
|
|
325
344
|
/* Base bottom sheet styling */
|
|
326
345
|
.ds-bottom-sheet {
|
|
327
346
|
--border-radius: 16px;
|
|
328
|
-
--box-shadow:
|
|
347
|
+
--box-shadow: none;
|
|
329
348
|
--backdrop-opacity: 0.4;
|
|
330
349
|
transition: --backdrop-opacity 0.3s ease;
|
|
331
350
|
/* Modal at top:0 so backdrop covers full screen including status bar */
|
|
@@ -461,7 +480,7 @@ ion-toast {
|
|
|
461
480
|
.ds-mobile-modal {
|
|
462
481
|
--background: var(--color-background-neutral-primary, #ffffff);
|
|
463
482
|
--border-radius: 16px;
|
|
464
|
-
--box-shadow:
|
|
483
|
+
--box-shadow: none;
|
|
465
484
|
--max-width: 640px;
|
|
466
485
|
--width: 100%;
|
|
467
486
|
}
|
|
@@ -156,6 +156,7 @@
|
|
|
156
156
|
:host ion-content::part(scroll) {
|
|
157
157
|
display: flex;
|
|
158
158
|
flex-direction: column;
|
|
159
|
+
min-height: 100%;
|
|
159
160
|
-webkit-overflow-scrolling: touch;
|
|
160
161
|
/* Note: Do NOT set overscroll-behavior-y here as it prevents ion-refresher from working */
|
|
161
162
|
/* overscroll-behavior on ion-app is sufficient to block native browser pull-to-refresh */
|
|
@@ -207,13 +208,13 @@
|
|
|
207
208
|
width: 100%;
|
|
208
209
|
position: relative;
|
|
209
210
|
z-index: 20;
|
|
210
|
-
/*
|
|
211
|
+
/* Fill remaining viewport height while keeping ion-content as scroller */
|
|
211
212
|
flex: 1;
|
|
212
213
|
display: flex;
|
|
213
214
|
flex-direction: column;
|
|
214
215
|
background: var(--color-background-neutral-primary);
|
|
215
216
|
border-radius: 24px 24px 0 0;
|
|
216
|
-
overflow:
|
|
217
|
+
overflow: visible;
|
|
217
218
|
|
|
218
219
|
/* Visual styling for iOS overshoot - extend background below using box-shadow */
|
|
219
220
|
transform: translateZ(0);
|
|
@@ -226,13 +227,10 @@
|
|
|
226
227
|
padding-left: var(--content-wrapper-padding, 20px);
|
|
227
228
|
padding-right: var(--content-wrapper-padding, 20px);
|
|
228
229
|
/* Bottom padding ALWAYS preserved for safe area and tab bar */
|
|
229
|
-
padding-bottom: calc(var(--mobile-content-spacing) + var(--mobile-tab-bar-height) +
|
|
230
|
+
padding-bottom: calc(var(--mobile-content-spacing) + var(--mobile-tab-bar-height) + var(--app-safe-bottom, 0px));
|
|
230
231
|
}
|
|
231
232
|
|
|
232
233
|
:host .content-inner {
|
|
233
|
-
/* Grow to fill parent flex container */
|
|
234
|
-
flex: 1;
|
|
235
|
-
|
|
236
234
|
/* Mobile-first: max-width 640px, centered */
|
|
237
235
|
max-width: 640px;
|
|
238
236
|
margin: 0 auto;
|