@propbinder/mobile-design 0.2.50 → 0.2.52
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 +26206 -0
- package/fesm2022/propbinder-mobile-design.mjs.map +1 -0
- package/index.d.ts +8193 -0
- package/package.json +39 -3
- package/ng-package.json +0 -24
- package/src/animations/page-transitions.ts +0 -165
- package/src/components/action-list-item/ds-mobile-action-list-item.ts +0 -102
- package/src/components/action-list-item/index.ts +0 -2
- package/src/components/app-icon/ds-app-icon.ts +0 -133
- package/src/components/app-icon/index.ts +0 -2
- package/src/components/attachment-preview/ds-mobile-attachment-preview.css +0 -139
- package/src/components/attachment-preview/ds-mobile-attachment-preview.ts +0 -164
- package/src/components/attachment-preview/index.ts +0 -1
- package/src/components/avatar-with-badge/ds-avatar-with-badge.ts +0 -142
- package/src/components/avatar-with-badge/index.ts +0 -2
- package/src/components/booking-modal/ds-mobile-booking-confirmation-wrapper.ts +0 -71
- package/src/components/booking-modal/ds-mobile-booking-modal.service.ts +0 -121
- package/src/components/booking-modal/ds-mobile-booking-modal.ts +0 -598
- package/src/components/booking-modal/ds-mobile-booking-summary.ts +0 -161
- package/src/components/booking-modal/index.ts +0 -4
- package/src/components/bottom-sheet/ds-mobile-actions-bottom-sheet.ts +0 -266
- package/src/components/bottom-sheet/ds-mobile-bottom-sheet-header.ts +0 -146
- package/src/components/bottom-sheet/ds-mobile-bottom-sheet-wrapper.ts +0 -156
- package/src/components/bottom-sheet/ds-mobile-bottom-sheet.css +0 -101
- package/src/components/bottom-sheet/ds-mobile-bottom-sheet.service.ts +0 -169
- package/src/components/bottom-sheet/ds-mobile-confirmation-sheet.ts +0 -211
- package/src/components/bottom-sheet/ds-mobile-post-create-bottom-sheet.ts +0 -578
- package/src/components/bottom-sheet/ds-mobile-profile-actions-sheet.ts +0 -614
- package/src/components/bottom-sheet/index.ts +0 -8
- package/src/components/bottom-sheet/modal-shadow-fix.ts +0 -42
- package/src/components/card-inline/ds-mobile-card-inline.ts +0 -301
- package/src/components/card-inline/index.ts +0 -2
- package/src/components/card-inline-banner/ds-mobile-card-inline-banner.ts +0 -118
- package/src/components/card-inline-banner/index.ts +0 -1
- package/src/components/card-inline-contact/ds-mobile-card-inline-contact.ts +0 -120
- package/src/components/card-inline-contact/index.ts +0 -1
- package/src/components/card-inline-file/ds-mobile-card-inline-file.ts +0 -141
- package/src/components/card-inline-file/index.ts +0 -1
- package/src/components/chat-modal/ds-mobile-chat-modal.css +0 -159
- package/src/components/chat-modal/ds-mobile-chat-modal.service.ts +0 -105
- package/src/components/chat-modal/ds-mobile-chat-modal.ts +0 -918
- package/src/components/chat-modal/index.ts +0 -8
- package/src/components/comment/ds-mobile-comment.ts +0 -568
- package/src/components/comment/index.ts +0 -2
- package/src/components/contact-list-item/ds-mobile-contact-list-item.ts +0 -182
- package/src/components/contact-list-item/index.ts +0 -2
- package/src/components/content/ds-mobile-content.ts +0 -139
- package/src/components/content/index.ts +0 -2
- package/src/components/dropdown/ds-mobile-dropdown.css +0 -199
- package/src/components/dropdown/ds-mobile-dropdown.ts +0 -340
- package/src/components/dropdown/index.ts +0 -2
- package/src/components/ds-mobile-tabs.css +0 -407
- package/src/components/ds-mobile-tabs.ts +0 -216
- package/src/components/empty-state/ds-mobile-empty-state.ts +0 -120
- package/src/components/empty-state/index.ts +0 -2
- package/src/components/fab/ds-mobile-fab.ts +0 -315
- package/src/components/fab/index.ts +0 -1
- package/src/components/facility-creation-modal/ds-mobile-facility-creation-confirmation-wrapper.ts +0 -121
- package/src/components/facility-creation-modal/ds-mobile-facility-creation-modal.css +0 -189
- package/src/components/facility-creation-modal/ds-mobile-facility-creation-modal.service.ts +0 -135
- package/src/components/facility-creation-modal/ds-mobile-facility-creation-modal.ts +0 -656
- package/src/components/facility-creation-modal/index.ts +0 -9
- package/src/components/facility-creation-modal/sheets/ds-mobile-access-sheet.ts +0 -105
- package/src/components/facility-creation-modal/sheets/ds-mobile-price-sheet.ts +0 -188
- package/src/components/facility-creation-modal/sheets/ds-mobile-when-can-book-sheet.ts +0 -460
- package/src/components/facility-creation-modal/sheets/ds-mobile-who-can-book-sheet.ts +0 -134
- package/src/components/facility-detail-modal/ds-mobile-facility-detail-modal.service.ts +0 -69
- package/src/components/facility-detail-modal/ds-mobile-facility-detail-modal.ts +0 -379
- package/src/components/facility-detail-modal/index.ts +0 -2
- package/src/components/file-attachment/ds-mobile-file-attachment.ts +0 -164
- package/src/components/file-attachment/index.ts +0 -2
- package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.css +0 -214
- package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.service.ts +0 -84
- package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.ts +0 -424
- package/src/components/handbook-detail-modal/index.ts +0 -3
- package/src/components/handbook-folder/ds-mobile-handbook-folder-mini.ts +0 -175
- package/src/components/handbook-folder/ds-mobile-handbook-folder.ts +0 -533
- package/src/components/handbook-folder/index.ts +0 -4
- package/src/components/header-content/ds-mobile-header-content.ts +0 -222
- package/src/components/header-content/index.ts +0 -2
- package/src/components/illustration/ds-mobile-illustration.ts +0 -124
- package/src/components/illustration/index.ts +0 -2
- package/src/components/index.ts +0 -124
- package/src/components/inline-photo/ds-mobile-inline-photo.ts +0 -361
- package/src/components/inline-photo/index.ts +0 -1
- package/src/components/inline-tabs/ds-mobile-inline-tabs.ts +0 -132
- package/src/components/inline-tabs/index.ts +0 -2
- package/src/components/interactive-list-item-booking/ds-mobile-interactive-list-item-booking.ts +0 -350
- package/src/components/interactive-list-item-booking/index.ts +0 -1
- package/src/components/interactive-list-item-inquiry/ds-mobile-interactive-list-item-inquiry.ts +0 -321
- package/src/components/interactive-list-item-inquiry/index.ts +0 -2
- package/src/components/interactive-list-item-message/ds-mobile-interactive-list-item-message.ts +0 -237
- package/src/components/interactive-list-item-message/index.ts +0 -2
- package/src/components/interactive-list-item-post/ds-mobile-interactive-list-item-post.ts +0 -549
- package/src/components/interactive-list-item-post/ds-mobile-post-pdf-attachment.ts +0 -124
- package/src/components/interactive-list-item-post/index.ts +0 -13
- package/src/components/lightbox/ds-mobile-lightbox-footer.ts +0 -315
- package/src/components/lightbox/ds-mobile-lightbox-header.ts +0 -202
- package/src/components/lightbox/ds-mobile-lightbox-image.ts +0 -484
- package/src/components/lightbox/ds-mobile-lightbox-pdf.css +0 -377
- package/src/components/lightbox/ds-mobile-lightbox-pdf.ts +0 -374
- package/src/components/lightbox/ds-mobile-lightbox.css +0 -587
- package/src/components/lightbox/ds-mobile-lightbox.service.ts +0 -296
- package/src/components/lightbox/ds-mobile-lightbox.ts +0 -529
- package/src/components/lightbox/index.ts +0 -22
- package/src/components/list-item/ds-mobile-list-item.ts +0 -603
- package/src/components/list-item/index.ts +0 -2
- package/src/components/list-item-static/ds-mobile-list-item-static.ts +0 -133
- package/src/components/list-item-static/index.ts +0 -2
- package/src/components/loader-overlay/ds-mobile-loader-overlay.css +0 -49
- package/src/components/loader-overlay/ds-mobile-loader-overlay.ts +0 -77
- package/src/components/loader-overlay/index.ts +0 -1
- package/src/components/logo/ds-logo.ts +0 -95
- package/src/components/logo/index.ts +0 -2
- package/src/components/message-bubble/ds-mobile-message-bubble.ts +0 -633
- package/src/components/message-bubble/index.ts +0 -7
- package/src/components/message-composer/ds-mobile-message-composer.ts +0 -1146
- package/src/components/message-composer/index.ts +0 -7
- package/src/components/modal/ds-mobile-modal.css +0 -163
- package/src/components/modal/ds-mobile-modal.service.ts +0 -329
- package/src/components/modal/index.ts +0 -8
- package/src/components/modal-base/ds-mobile-modal-base.css +0 -378
- package/src/components/modal-base/ds-mobile-modal-base.ts +0 -261
- package/src/components/modal-base/index.ts +0 -2
- package/src/components/new-inquiry-modal/ds-mobile-new-inquiry-modal.css +0 -112
- package/src/components/new-inquiry-modal/ds-mobile-new-inquiry-modal.service.ts +0 -93
- package/src/components/new-inquiry-modal/ds-mobile-new-inquiry-modal.ts +0 -442
- package/src/components/new-inquiry-modal/index.ts +0 -4
- package/src/components/offline-banner/ds-mobile-offline-banner.ts +0 -135
- package/src/components/offline-banner/index.ts +0 -1
- package/src/components/page-details/ds-mobile-page-details.css +0 -83
- package/src/components/page-details/ds-mobile-page-details.ts +0 -282
- package/src/components/page-details/index.ts +0 -2
- package/src/components/page-main/ds-mobile-page-main.css +0 -68
- package/src/components/page-main/ds-mobile-page-main.ts +0 -421
- package/src/components/page-main/index.ts +0 -2
- package/src/components/post-composer/ds-mobile-post-composer.ts +0 -140
- package/src/components/post-composer/index.ts +0 -2
- package/src/components/post-detail-modal/ds-mobile-post-detail-modal.css +0 -390
- package/src/components/post-detail-modal/ds-mobile-post-detail-modal.service.ts +0 -108
- package/src/components/post-detail-modal/ds-mobile-post-detail-modal.ts +0 -722
- package/src/components/post-detail-modal/index.ts +0 -9
- package/src/components/property-banner/ds-mobile-property-banner.ts +0 -95
- package/src/components/property-banner/index.ts +0 -2
- package/src/components/section/ds-mobile-section.ts +0 -263
- package/src/components/section/index.ts +0 -2
- package/src/components/shared/directives/index.ts +0 -2
- package/src/components/shared/directives/long-press.directive.ts +0 -212
- package/src/components/shared/index.ts +0 -3
- package/src/components/shared/mobile-modal-base.ts +0 -457
- package/src/components/shared/mobile-page-base.ts +0 -204
- package/src/components/swiper/ds-mobile-swiper-with-nav.ts +0 -160
- package/src/components/swiper/ds-mobile-swiper.ts +0 -327
- package/src/components/swiper/index.ts +0 -3
- package/src/components/system-message-banner/ds-mobile-system-message-banner.ts +0 -129
- package/src/components/system-message-banner/index.ts +0 -2
- package/src/components/tab-bar/ds-mobile-tab-bar.css +0 -533
- package/src/components/tab-bar/ds-mobile-tab-bar.ts +0 -735
- package/src/components/tab-bar/index.ts +0 -2
- package/src/components/tabs/ds-mobile-tabs.css +0 -25
- package/src/components/tabs/ds-mobile-tabs.ts +0 -89
- package/src/components/tabs/index.ts +0 -2
- package/src/components/text-input/ds-text-input.ts +0 -287
- package/src/components/text-input/index.ts +0 -2
- package/src/examples/booking.page.ts +0 -434
- package/src/examples/community.page.ts +0 -776
- package/src/examples/handbook.page.ts +0 -324
- package/src/examples/home.page.ts +0 -347
- package/src/examples/index.ts +0 -12
- package/src/examples/inquiries.example.ts +0 -273
- package/src/examples/inquiry-detail.example.css +0 -189
- package/src/examples/inquiry-detail.example.ts +0 -415
- package/src/examples/mobile-tabs-example.component.ts +0 -208
- package/src/examples/post-create.page.ts +0 -311
- package/src/examples/post-detail.page.ts +0 -296
- package/src/examples/sign-in.page.ts +0 -291
- package/src/examples/whitelabel-demo-modal.component.ts +0 -1094
- package/src/examples/whitelabel-demo-modal.service.ts +0 -77
- package/src/models/index.ts +0 -7
- package/src/models/post.model.ts +0 -41
- package/src/pages/community.page.ts +0 -769
- package/src/pages/handbook.page.ts +0 -388
- package/src/pages/home.page.ts +0 -303
- package/src/pages/index.ts +0 -11
- package/src/pages/inquiries.example.ts +0 -273
- package/src/pages/inquiry-detail.example.css +0 -189
- package/src/pages/inquiry-detail.example.ts +0 -415
- package/src/pages/mobile-tabs-example.component.ts +0 -179
- package/src/pages/post-create.page.ts +0 -311
- package/src/pages/post-detail.page.ts +0 -296
- package/src/pages/sign-in.page.ts +0 -291
- package/src/pages/whitelabel-demo-modal.component.ts +0 -1094
- package/src/pages/whitelabel-demo-modal.service.ts +0 -77
- package/src/public-api.ts +0 -6
- package/src/services/base-modal.service.ts +0 -101
- package/src/services/index.ts +0 -11
- package/src/services/posts.service.ts +0 -542
- package/src/services/tracking-permission.service.ts +0 -88
- package/src/services/user.service.ts +0 -60
- package/src/services/whitelabel.service.ts +0 -675
- package/tsconfig.lib.json +0 -17
- package/tsconfig.lib.prod.json +0 -9
- package/tsconfig.spec.json +0 -13
- /package/{src/assets → assets}/fonts/Brockmann-Bold.otf +0 -0
- /package/{src/assets → assets}/fonts/Brockmann-BoldItalic.otf +0 -0
- /package/{src/assets → assets}/fonts/Brockmann-Medium.otf +0 -0
- /package/{src/assets → assets}/fonts/Brockmann-MediumItalic.otf +0 -0
- /package/{src/assets → assets}/fonts/Brockmann-Regular.otf +0 -0
- /package/{src/assets → assets}/fonts/Brockmann-RegularItalic.otf +0 -0
- /package/{src/assets → assets}/fonts/Brockmann-SemiBold.otf +0 -0
- /package/{src/assets → assets}/fonts/Brockmann-SemiBoldItalic.otf +0 -0
- /package/{src/assets → assets}/fonts/Brockmann_desktop_license.pdf +0 -0
- /package/{src/assets → assets}/fonts/brockmann-medium-webfont.woff2 +0 -0
- /package/{src/assets → assets}/fonts/brockmann-mediumitalic-webfont.woff2 +0 -0
- /package/{src/assets → assets}/fonts/brockmann-regular-webfont.woff2 +0 -0
- /package/{src/assets → assets}/fonts/brockmann-regularitalic-webfont.woff2 +0 -0
- /package/{src/assets → assets}/fonts/brockmann-semibold-webfont.woff2 +0 -0
- /package/{src/assets → assets}/fonts/brockmann-semibolditalic-webfont.woff2 +0 -0
- /package/{src/styles → styles}/ionic.css +0 -0
- /package/{src/components/shared → styles}/mobile-common.css +0 -0
- /package/{src/components/shared → styles}/mobile-page-base.css +0 -0
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { Component, input } from '@angular/core';
|
|
2
|
-
import { CommonModule } from '@angular/common';
|
|
3
|
-
import { DsIconComponent } from '@propbinder/design-system';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* DsMobileOfflineBannerComponent
|
|
7
|
-
*
|
|
8
|
-
* A compact banner component to indicate offline status.
|
|
9
|
-
* Designed to be used in the [offline-indicator] slot of page components.
|
|
10
|
-
*
|
|
11
|
-
* Features:
|
|
12
|
-
* - Amber/yellow warning styling
|
|
13
|
-
* - WiFi off icon
|
|
14
|
-
* - Customizable message
|
|
15
|
-
* - Compact, non-intrusive design
|
|
16
|
-
* - Smooth slide-in animation
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* ```html
|
|
20
|
-
* <ds-mobile-page-main title="Community">
|
|
21
|
-
* <ds-mobile-offline-banner
|
|
22
|
-
* offline-indicator
|
|
23
|
-
* *ngIf="pageComponent.isOffline()">
|
|
24
|
-
* </ds-mobile-offline-banner>
|
|
25
|
-
*
|
|
26
|
-
* <!-- Page content -->
|
|
27
|
-
* </ds-mobile-page-main>
|
|
28
|
-
* ```
|
|
29
|
-
*/
|
|
30
|
-
@Component({
|
|
31
|
-
selector: 'ds-mobile-offline-banner',
|
|
32
|
-
standalone: true,
|
|
33
|
-
imports: [CommonModule, DsIconComponent],
|
|
34
|
-
styles: [`
|
|
35
|
-
:host {
|
|
36
|
-
display: block;
|
|
37
|
-
animation: slideDown 0.3s ease-out;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
@keyframes slideDown {
|
|
41
|
-
from {
|
|
42
|
-
opacity: 0;
|
|
43
|
-
transform: translateY(-10px);
|
|
44
|
-
}
|
|
45
|
-
to {
|
|
46
|
-
opacity: 1;
|
|
47
|
-
transform: translateY(0);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
.offline-banner {
|
|
52
|
-
background: var(--color-warning-surface, #FEF3C7);
|
|
53
|
-
border-bottom: 1px solid var(--color-warning-border, #F59E0B);
|
|
54
|
-
padding: 12px 20px;
|
|
55
|
-
display: flex;
|
|
56
|
-
align-items: center;
|
|
57
|
-
gap: 12px;
|
|
58
|
-
position: relative;
|
|
59
|
-
z-index: 10;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
.offline-banner__icon {
|
|
63
|
-
flex-shrink: 0;
|
|
64
|
-
display: flex;
|
|
65
|
-
align-items: center;
|
|
66
|
-
justify-content: center;
|
|
67
|
-
color: var(--color-warning-content, #92400E);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
.offline-banner__content {
|
|
71
|
-
flex: 1;
|
|
72
|
-
display: flex;
|
|
73
|
-
flex-direction: column;
|
|
74
|
-
gap: 2px;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
.offline-banner__title {
|
|
78
|
-
font-family: 'Brockmann', sans-serif;
|
|
79
|
-
font-size: var(--font-size-sm, 14px);
|
|
80
|
-
font-weight: 600;
|
|
81
|
-
line-height: 1.3;
|
|
82
|
-
color: var(--color-warning-content, #92400E);
|
|
83
|
-
margin: 0;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
.offline-banner__message {
|
|
87
|
-
font-family: 'Brockmann', sans-serif;
|
|
88
|
-
font-size: var(--font-size-xs, 12px);
|
|
89
|
-
font-weight: 400;
|
|
90
|
-
line-height: 1.4;
|
|
91
|
-
color: var(--color-warning-content-secondary, #B45309);
|
|
92
|
-
margin: 0;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/* Desktop - center with max-width */
|
|
96
|
-
@media (min-width: 768px) {
|
|
97
|
-
.offline-banner {
|
|
98
|
-
padding: 12px 40px;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
`],
|
|
102
|
-
template: `
|
|
103
|
-
<div class="offline-banner">
|
|
104
|
-
<div class="offline-banner__icon">
|
|
105
|
-
<ds-icon
|
|
106
|
-
[name]="icon()"
|
|
107
|
-
size="20px"
|
|
108
|
-
color="var(--color-warning-content, #92400E)">
|
|
109
|
-
</ds-icon>
|
|
110
|
-
</div>
|
|
111
|
-
<div class="offline-banner__content">
|
|
112
|
-
<p class="offline-banner__title">{{ title() }}</p>
|
|
113
|
-
@if (message()) {
|
|
114
|
-
<p class="offline-banner__message">{{ message() }}</p>
|
|
115
|
-
}
|
|
116
|
-
</div>
|
|
117
|
-
</div>
|
|
118
|
-
`
|
|
119
|
-
})
|
|
120
|
-
export class DsMobileOfflineBannerComponent {
|
|
121
|
-
/**
|
|
122
|
-
* Icon to display (default: WiFi off icon)
|
|
123
|
-
*/
|
|
124
|
-
icon = input<string>('remixWifiOffLine');
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Title text for the banner
|
|
128
|
-
*/
|
|
129
|
-
title = input<string>('No internet connection');
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Optional secondary message
|
|
133
|
-
*/
|
|
134
|
-
message = input<string>('Some features may be unavailable');
|
|
135
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './ds-mobile-offline-banner';
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
/* ============================================
|
|
2
|
-
DS MOBILE PAGE DETAILS
|
|
3
|
-
Reusable mobile page component for detail/drill-down pages
|
|
4
|
-
============================================ */
|
|
5
|
-
|
|
6
|
-
/* ============================================
|
|
7
|
-
PULL-TO-REFRESH SPINNER STYLING
|
|
8
|
-
============================================ */
|
|
9
|
-
|
|
10
|
-
/* Style the pull-to-refresh spinner with brand secondary content color */
|
|
11
|
-
ion-refresher {
|
|
12
|
-
--color: var(--color-header-content);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
ion-refresher-content {
|
|
16
|
-
--color: var(--color-header-content);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/* Target the actual spinner element */
|
|
20
|
-
ion-refresher-content::part(spinner) {
|
|
21
|
-
color: var(--color-header-content);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/* ============================================
|
|
25
|
-
HEADER DETAILS - Back Button + Title
|
|
26
|
-
============================================ */
|
|
27
|
-
|
|
28
|
-
.header-details {
|
|
29
|
-
gap: 12px;
|
|
30
|
-
padding: 0 20px;
|
|
31
|
-
height: 72px;
|
|
32
|
-
min-height: 72px;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
:host .header-details .back-button {
|
|
36
|
-
width: 36px;
|
|
37
|
-
height: 36px;
|
|
38
|
-
border-radius: 50%;
|
|
39
|
-
background: var(--color-header-accent) !important;
|
|
40
|
-
flex-shrink: 0;
|
|
41
|
-
border: none;
|
|
42
|
-
padding: 0;
|
|
43
|
-
display: flex;
|
|
44
|
-
align-items: center;
|
|
45
|
-
justify-content: center;
|
|
46
|
-
cursor: pointer;
|
|
47
|
-
color: var(--color-header-content);
|
|
48
|
-
transition: background var(--transition-duration-fast) var(--ease-smooth);
|
|
49
|
-
z-index: 10;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
:host .header-details .back-button:hover {
|
|
53
|
-
background: var(--color-header-accent-hover) !important;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
:host .header-details .back-button:active {
|
|
57
|
-
background: var(--color-header-accent-active) !important;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
.header-details .header-title {
|
|
61
|
-
left: 64px;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
@media (min-width: 768px) {
|
|
65
|
-
/* Keep header visible on desktop for detail pages */
|
|
66
|
-
ion-header {
|
|
67
|
-
display: block !important;
|
|
68
|
-
height: 88px;
|
|
69
|
-
min-height: 88px;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
ion-header ion-toolbar {
|
|
73
|
-
--min-height: 88px;
|
|
74
|
-
height: 88px;
|
|
75
|
-
min-height: 88px;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
.header-details {
|
|
79
|
-
padding: 16px 24px;
|
|
80
|
-
height: 88px;
|
|
81
|
-
min-height: 88px;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
@@ -1,282 +0,0 @@
|
|
|
1
|
-
import { Component, input, output, ElementRef, ViewChild, AfterViewInit, computed, inject } from '@angular/core';
|
|
2
|
-
import { CommonModule } from '@angular/common';
|
|
3
|
-
import { NavController, Platform } from '@ionic/angular/standalone';
|
|
4
|
-
import {
|
|
5
|
-
IonHeader,
|
|
6
|
-
IonToolbar,
|
|
7
|
-
IonTitle,
|
|
8
|
-
IonContent,
|
|
9
|
-
IonRefresher,
|
|
10
|
-
IonRefresherContent
|
|
11
|
-
} from '@ionic/angular/standalone';
|
|
12
|
-
import { Haptics, ImpactStyle } from '@capacitor/haptics';
|
|
13
|
-
import { DsIconComponent } from '@propbinder/design-system';
|
|
14
|
-
import { MobilePageBase } from '../shared/mobile-page-base';
|
|
15
|
-
import { DsMobileLoaderOverlayComponent } from '../loader-overlay';
|
|
16
|
-
import { DsMobileInlineTabsComponent, type InlineTabItem } from '../inline-tabs';
|
|
17
|
-
import { customBackTransition } from '../../animations/page-transitions';
|
|
18
|
-
import { WhitelabelService } from '../../services/whitelabel.service';
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* DsMobilePageDetailsComponent
|
|
22
|
-
*
|
|
23
|
-
* A complete mobile page layout for detail/drill-down pages with:
|
|
24
|
-
* - Fixed header with back button + title (fades in on scroll)
|
|
25
|
-
* - Purple expandable header section (scrolls with content)
|
|
26
|
-
* - Optional inline tabs in expandable header
|
|
27
|
-
* - White rounded content wrapper
|
|
28
|
-
* - Pull-to-refresh support (native platforms only)
|
|
29
|
-
* - Auto scroll title fade-in and header fade-out
|
|
30
|
-
*
|
|
31
|
-
* @example
|
|
32
|
-
* ```html
|
|
33
|
-
* <!-- Simple detail page -->
|
|
34
|
-
* <ds-mobile-page-details
|
|
35
|
-
* title="Property Details"
|
|
36
|
-
* (back)="goBack()">
|
|
37
|
-
* <div class="page-content">
|
|
38
|
-
* <!-- Your content -->
|
|
39
|
-
* </div>
|
|
40
|
-
* </ds-mobile-page-details>
|
|
41
|
-
*
|
|
42
|
-
* <!-- With tabs -->
|
|
43
|
-
* <ds-mobile-page-details
|
|
44
|
-
* title="Inquiry Details"
|
|
45
|
-
* [tabs]="tabItems"
|
|
46
|
-
* [activeTab]="activeTab()"
|
|
47
|
-
* (tabChange)="setActiveTab($event)"
|
|
48
|
-
* (back)="goBack()">
|
|
49
|
-
* <div class="page-content">
|
|
50
|
-
* <!-- Your content -->
|
|
51
|
-
* </div>
|
|
52
|
-
* </ds-mobile-page-details>
|
|
53
|
-
* ```
|
|
54
|
-
*/
|
|
55
|
-
@Component({
|
|
56
|
-
selector: 'ds-mobile-page-details',
|
|
57
|
-
standalone: true,
|
|
58
|
-
imports: [
|
|
59
|
-
CommonModule,
|
|
60
|
-
IonHeader,
|
|
61
|
-
IonToolbar,
|
|
62
|
-
IonTitle,
|
|
63
|
-
IonContent,
|
|
64
|
-
IonRefresher,
|
|
65
|
-
IonRefresherContent,
|
|
66
|
-
DsIconComponent,
|
|
67
|
-
DsMobileLoaderOverlayComponent,
|
|
68
|
-
DsMobileInlineTabsComponent
|
|
69
|
-
],
|
|
70
|
-
host: {
|
|
71
|
-
'[style.--content-wrapper-padding]': 'contentPadding()'
|
|
72
|
-
},
|
|
73
|
-
styleUrls: [
|
|
74
|
-
'../shared/mobile-page-base.css',
|
|
75
|
-
'./ds-mobile-page-details.css'
|
|
76
|
-
],
|
|
77
|
-
template: `
|
|
78
|
-
<!-- Fixed header at top -->
|
|
79
|
-
<ion-header>
|
|
80
|
-
<ion-toolbar>
|
|
81
|
-
<div class="header-details">
|
|
82
|
-
<!-- Back Button -->
|
|
83
|
-
<button class="back-button" (click)="handleBack()" [attr.aria-label]="'Go back'">
|
|
84
|
-
<ds-icon name="remixArrowLeftSLine" size="24px" [color]="whitelabelService.headerContent()" />
|
|
85
|
-
</button>
|
|
86
|
-
|
|
87
|
-
<!-- Title - fades in on scroll -->
|
|
88
|
-
<ion-title class="header-title">{{ title() }}</ion-title>
|
|
89
|
-
</div>
|
|
90
|
-
</ion-toolbar>
|
|
91
|
-
</ion-header>
|
|
92
|
-
|
|
93
|
-
<!-- Content with expandable header -->
|
|
94
|
-
<ion-content [scrollEvents]="true" [forceOverscroll]="true" (ionScroll)="handleScroll($event)">
|
|
95
|
-
<!-- Pull to refresh (only on native iOS/Android) -->
|
|
96
|
-
@if (showRefresh() && isNativePlatform()) {
|
|
97
|
-
<ion-refresher
|
|
98
|
-
slot="fixed"
|
|
99
|
-
(ionRefresh)="handleRefresh($event)"
|
|
100
|
-
[pullFactor]="0.4"
|
|
101
|
-
[pullMin]="80"
|
|
102
|
-
[pullMax]="240"
|
|
103
|
-
closeDuration="600ms">
|
|
104
|
-
<ion-refresher-content
|
|
105
|
-
pullingIcon="remixArrowDownS"
|
|
106
|
-
refreshingSpinner="crescent">
|
|
107
|
-
</ion-refresher-content>
|
|
108
|
-
</ion-refresher>
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
<!-- Expandable header section (purple background) -->
|
|
112
|
-
<div class="header-expandable">
|
|
113
|
-
<div class="header-expandable-inner">
|
|
114
|
-
<div class="header-expandable__text">
|
|
115
|
-
<h1 class="header-expandable__title">{{ title() }}</h1>
|
|
116
|
-
</div>
|
|
117
|
-
|
|
118
|
-
<!-- Tabs in header (optional) -->
|
|
119
|
-
@if (tabs() && tabs()!.length > 0) {
|
|
120
|
-
<ds-mobile-inline-tabs
|
|
121
|
-
[tabs]="tabs()!"
|
|
122
|
-
[activeTab]="activeTab()"
|
|
123
|
-
(tabChange)="handleTabChange($event)">
|
|
124
|
-
</ds-mobile-inline-tabs>
|
|
125
|
-
}
|
|
126
|
-
</div>
|
|
127
|
-
</div>
|
|
128
|
-
|
|
129
|
-
<!-- Content wrapper -->
|
|
130
|
-
<div class="content-wrapper">
|
|
131
|
-
@if (contentLoading()) {
|
|
132
|
-
<ds-mobile-loader-overlay />
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
<!-- Offline indicator slot (appears at top of content) -->
|
|
136
|
-
<ng-content select="[offline-indicator]"></ng-content>
|
|
137
|
-
|
|
138
|
-
<div class="content-inner">
|
|
139
|
-
<ng-content></ng-content>
|
|
140
|
-
</div>
|
|
141
|
-
</div>
|
|
142
|
-
</ion-content>
|
|
143
|
-
`
|
|
144
|
-
})
|
|
145
|
-
export class DsMobilePageDetailsComponent extends MobilePageBase implements AfterViewInit {
|
|
146
|
-
@ViewChild(IonContent) ionContent?: IonContent;
|
|
147
|
-
|
|
148
|
-
// Platform detection
|
|
149
|
-
private platform = inject(Platform);
|
|
150
|
-
|
|
151
|
-
// Whitelabel service
|
|
152
|
-
whitelabelService = inject(WhitelabelService);
|
|
153
|
-
|
|
154
|
-
// Computed property to check if running on native platform
|
|
155
|
-
isNativePlatform = computed(() =>
|
|
156
|
-
this.platform.is('ios') ||
|
|
157
|
-
this.platform.is('android') ||
|
|
158
|
-
this.platform.is('capacitor')
|
|
159
|
-
);
|
|
160
|
-
|
|
161
|
-
// Inputs
|
|
162
|
-
title = input.required<string>();
|
|
163
|
-
backRoute = input<string>(''); // Optional default back route
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Content wrapper padding
|
|
167
|
-
* - '0' (default) - No padding, use ds-mobile-section for content organization
|
|
168
|
-
* - '20px' - Legacy padding for content without sections
|
|
169
|
-
* - Any custom CSS padding value
|
|
170
|
-
*
|
|
171
|
-
* Note: Bottom padding for safe area and tab bar is always preserved
|
|
172
|
-
*/
|
|
173
|
-
contentPadding = input<string>('0');
|
|
174
|
-
|
|
175
|
-
// Inputs - Tabs (optional)
|
|
176
|
-
tabs = input<InlineTabItem[] | undefined>(undefined);
|
|
177
|
-
activeTab = input<string>('');
|
|
178
|
-
|
|
179
|
-
// Inputs - Features
|
|
180
|
-
showRefresh = input<boolean>(true);
|
|
181
|
-
scrollThreshold = input<number>(160); // Pixels to scroll before title appears
|
|
182
|
-
headerFadeDistance = input<number>(200); // Distance over which header fades out
|
|
183
|
-
|
|
184
|
-
// Outputs
|
|
185
|
-
back = output<void>();
|
|
186
|
-
tabChange = output<string>();
|
|
187
|
-
refresh = output<any>();
|
|
188
|
-
scroll = output<any>();
|
|
189
|
-
|
|
190
|
-
constructor(
|
|
191
|
-
private navCtrl: NavController,
|
|
192
|
-
private elementRef: ElementRef
|
|
193
|
-
) {
|
|
194
|
-
super();
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
ngAfterViewInit(): void {
|
|
198
|
-
// Initialize network monitoring
|
|
199
|
-
this.initNetworkMonitoring(this.isNativePlatform());
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Handle back navigation
|
|
204
|
-
*
|
|
205
|
-
* By default, navigates using the provided backRoute or browser back.
|
|
206
|
-
* Parent components can listen to the (back) event to override this behavior.
|
|
207
|
-
*/
|
|
208
|
-
handleBack(): void {
|
|
209
|
-
// Emit event for parent to optionally handle
|
|
210
|
-
this.back.emit();
|
|
211
|
-
|
|
212
|
-
// Default behavior: navigate using backRoute or browser back
|
|
213
|
-
if (this.backRoute()) {
|
|
214
|
-
this.navCtrl.navigateBack(this.backRoute());
|
|
215
|
-
} else {
|
|
216
|
-
this.navCtrl.back({ animation: customBackTransition });
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Handle tab change
|
|
222
|
-
*/
|
|
223
|
-
handleTabChange(tabId: string): void {
|
|
224
|
-
this.tabChange.emit(tabId);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Handle scroll events
|
|
229
|
-
* - Shows title in fixed header when scrolled past threshold
|
|
230
|
-
* - Fades out expandable header content based on scroll position
|
|
231
|
-
* - Emits scroll event for custom handling
|
|
232
|
-
*/
|
|
233
|
-
handleScroll(event: any): void {
|
|
234
|
-
const scrollTop = event.detail.scrollTop;
|
|
235
|
-
const threshold = this.scrollThreshold();
|
|
236
|
-
const fadeDistance = this.headerFadeDistance();
|
|
237
|
-
const header = this.elementRef.nativeElement.querySelector('ion-header:not([collapse])');
|
|
238
|
-
const headerExpandable = this.elementRef.nativeElement.querySelector('.header-expandable');
|
|
239
|
-
|
|
240
|
-
// Show title in fixed header when scrolled past threshold
|
|
241
|
-
if (scrollTop > threshold) {
|
|
242
|
-
header?.classList.add('header-scrolled');
|
|
243
|
-
} else {
|
|
244
|
-
header?.classList.remove('header-scrolled');
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
// Fade out header-expandable content based on scroll
|
|
248
|
-
if (headerExpandable) {
|
|
249
|
-
const fadeProgress = Math.min(scrollTop / fadeDistance, 1);
|
|
250
|
-
|
|
251
|
-
// Calculate opacity (1 to 0)
|
|
252
|
-
const opacity = 1 - fadeProgress;
|
|
253
|
-
|
|
254
|
-
// Calculate transform (0px to -20px upward)
|
|
255
|
-
const translateY = fadeProgress * -20;
|
|
256
|
-
|
|
257
|
-
// Apply styles
|
|
258
|
-
headerExpandable.style.opacity = opacity.toString();
|
|
259
|
-
headerExpandable.style.transform = `translateY(${translateY}px)`;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
this.scroll.emit(event);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* Handle pull-to-refresh
|
|
267
|
-
* Emits refresh event - parent should call event.target.complete()
|
|
268
|
-
*/
|
|
269
|
-
async handleRefresh(event: any): Promise<void> {
|
|
270
|
-
// Haptic feedback for pull-to-refresh
|
|
271
|
-
try {
|
|
272
|
-
await Haptics.impact({ style: ImpactStyle.Medium });
|
|
273
|
-
} catch {
|
|
274
|
-
// Fallback to Web Vibration API if Capacitor Haptics is not available
|
|
275
|
-
if ('vibrate' in navigator) {
|
|
276
|
-
navigator.vibrate(50);
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
this.refresh.emit(event);
|
|
281
|
-
}
|
|
282
|
-
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/* ============================================
|
|
2
|
-
DS MOBILE PAGE MAIN
|
|
3
|
-
Reusable mobile page component for main/tab pages
|
|
4
|
-
============================================ */
|
|
5
|
-
|
|
6
|
-
/* ============================================
|
|
7
|
-
HEADER MAIN - Logo + Title + Avatar
|
|
8
|
-
============================================ */
|
|
9
|
-
|
|
10
|
-
.header-main {
|
|
11
|
-
padding: 0 20px;
|
|
12
|
-
height: 72px;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
.header-main__title {
|
|
16
|
-
transform: translateX(-50%) translateY(-100%);
|
|
17
|
-
opacity: 0;
|
|
18
|
-
transition: transform 0.6s ease, opacity 0.6s ease;
|
|
19
|
-
padding: 0;
|
|
20
|
-
--color: var(--color-header-content);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/* Show title when scrolled */
|
|
24
|
-
.header-scrolled .header-main__title {
|
|
25
|
-
opacity: 1;
|
|
26
|
-
transform: translateX(-50%) translateY(0);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.header-main__actions {
|
|
30
|
-
display: flex;
|
|
31
|
-
align-items: center;
|
|
32
|
-
gap: 8px;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
.header-main__actions ds-avatar {
|
|
36
|
-
cursor: pointer;
|
|
37
|
-
-webkit-tap-highlight-color: transparent;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
@media (min-width: 768px) {
|
|
41
|
-
.header-main {
|
|
42
|
-
padding: 16px 24px;
|
|
43
|
-
height: 88px;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/* Hide title on desktop - not needed */
|
|
47
|
-
.header-main__title {
|
|
48
|
-
display: none;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/* ============================================
|
|
53
|
-
PULL-TO-REFRESH SPINNER STYLING
|
|
54
|
-
============================================ */
|
|
55
|
-
|
|
56
|
-
/* Style the pull-to-refresh spinner with brand secondary content color */
|
|
57
|
-
ion-refresher {
|
|
58
|
-
--color: var(--color-header-content);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
ion-refresher-content {
|
|
62
|
-
--color: var(--color-header-content);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/* Target the actual spinner element */
|
|
66
|
-
ion-refresher-content::part(spinner) {
|
|
67
|
-
color: var(--color-header-content);
|
|
68
|
-
}
|