@propbinder/mobile-design 0.2.50 → 0.2.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. package/fesm2022/propbinder-mobile-design.mjs +26206 -0
  2. package/fesm2022/propbinder-mobile-design.mjs.map +1 -0
  3. package/index.d.ts +8193 -0
  4. package/package.json +39 -3
  5. package/ng-package.json +0 -24
  6. package/src/animations/page-transitions.ts +0 -165
  7. package/src/components/action-list-item/ds-mobile-action-list-item.ts +0 -102
  8. package/src/components/action-list-item/index.ts +0 -2
  9. package/src/components/app-icon/ds-app-icon.ts +0 -133
  10. package/src/components/app-icon/index.ts +0 -2
  11. package/src/components/attachment-preview/ds-mobile-attachment-preview.css +0 -139
  12. package/src/components/attachment-preview/ds-mobile-attachment-preview.ts +0 -164
  13. package/src/components/attachment-preview/index.ts +0 -1
  14. package/src/components/avatar-with-badge/ds-avatar-with-badge.ts +0 -142
  15. package/src/components/avatar-with-badge/index.ts +0 -2
  16. package/src/components/booking-modal/ds-mobile-booking-confirmation-wrapper.ts +0 -71
  17. package/src/components/booking-modal/ds-mobile-booking-modal.service.ts +0 -121
  18. package/src/components/booking-modal/ds-mobile-booking-modal.ts +0 -598
  19. package/src/components/booking-modal/ds-mobile-booking-summary.ts +0 -161
  20. package/src/components/booking-modal/index.ts +0 -4
  21. package/src/components/bottom-sheet/ds-mobile-actions-bottom-sheet.ts +0 -266
  22. package/src/components/bottom-sheet/ds-mobile-bottom-sheet-header.ts +0 -146
  23. package/src/components/bottom-sheet/ds-mobile-bottom-sheet-wrapper.ts +0 -156
  24. package/src/components/bottom-sheet/ds-mobile-bottom-sheet.css +0 -101
  25. package/src/components/bottom-sheet/ds-mobile-bottom-sheet.service.ts +0 -169
  26. package/src/components/bottom-sheet/ds-mobile-confirmation-sheet.ts +0 -211
  27. package/src/components/bottom-sheet/ds-mobile-post-create-bottom-sheet.ts +0 -578
  28. package/src/components/bottom-sheet/ds-mobile-profile-actions-sheet.ts +0 -614
  29. package/src/components/bottom-sheet/index.ts +0 -8
  30. package/src/components/bottom-sheet/modal-shadow-fix.ts +0 -42
  31. package/src/components/card-inline/ds-mobile-card-inline.ts +0 -301
  32. package/src/components/card-inline/index.ts +0 -2
  33. package/src/components/card-inline-banner/ds-mobile-card-inline-banner.ts +0 -118
  34. package/src/components/card-inline-banner/index.ts +0 -1
  35. package/src/components/card-inline-contact/ds-mobile-card-inline-contact.ts +0 -120
  36. package/src/components/card-inline-contact/index.ts +0 -1
  37. package/src/components/card-inline-file/ds-mobile-card-inline-file.ts +0 -141
  38. package/src/components/card-inline-file/index.ts +0 -1
  39. package/src/components/chat-modal/ds-mobile-chat-modal.css +0 -159
  40. package/src/components/chat-modal/ds-mobile-chat-modal.service.ts +0 -105
  41. package/src/components/chat-modal/ds-mobile-chat-modal.ts +0 -918
  42. package/src/components/chat-modal/index.ts +0 -8
  43. package/src/components/comment/ds-mobile-comment.ts +0 -568
  44. package/src/components/comment/index.ts +0 -2
  45. package/src/components/contact-list-item/ds-mobile-contact-list-item.ts +0 -182
  46. package/src/components/contact-list-item/index.ts +0 -2
  47. package/src/components/content/ds-mobile-content.ts +0 -139
  48. package/src/components/content/index.ts +0 -2
  49. package/src/components/dropdown/ds-mobile-dropdown.css +0 -199
  50. package/src/components/dropdown/ds-mobile-dropdown.ts +0 -340
  51. package/src/components/dropdown/index.ts +0 -2
  52. package/src/components/ds-mobile-tabs.css +0 -407
  53. package/src/components/ds-mobile-tabs.ts +0 -216
  54. package/src/components/empty-state/ds-mobile-empty-state.ts +0 -120
  55. package/src/components/empty-state/index.ts +0 -2
  56. package/src/components/fab/ds-mobile-fab.ts +0 -315
  57. package/src/components/fab/index.ts +0 -1
  58. package/src/components/facility-creation-modal/ds-mobile-facility-creation-confirmation-wrapper.ts +0 -121
  59. package/src/components/facility-creation-modal/ds-mobile-facility-creation-modal.css +0 -189
  60. package/src/components/facility-creation-modal/ds-mobile-facility-creation-modal.service.ts +0 -135
  61. package/src/components/facility-creation-modal/ds-mobile-facility-creation-modal.ts +0 -656
  62. package/src/components/facility-creation-modal/index.ts +0 -9
  63. package/src/components/facility-creation-modal/sheets/ds-mobile-access-sheet.ts +0 -105
  64. package/src/components/facility-creation-modal/sheets/ds-mobile-price-sheet.ts +0 -188
  65. package/src/components/facility-creation-modal/sheets/ds-mobile-when-can-book-sheet.ts +0 -460
  66. package/src/components/facility-creation-modal/sheets/ds-mobile-who-can-book-sheet.ts +0 -134
  67. package/src/components/facility-detail-modal/ds-mobile-facility-detail-modal.service.ts +0 -69
  68. package/src/components/facility-detail-modal/ds-mobile-facility-detail-modal.ts +0 -379
  69. package/src/components/facility-detail-modal/index.ts +0 -2
  70. package/src/components/file-attachment/ds-mobile-file-attachment.ts +0 -164
  71. package/src/components/file-attachment/index.ts +0 -2
  72. package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.css +0 -214
  73. package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.service.ts +0 -84
  74. package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.ts +0 -424
  75. package/src/components/handbook-detail-modal/index.ts +0 -3
  76. package/src/components/handbook-folder/ds-mobile-handbook-folder-mini.ts +0 -175
  77. package/src/components/handbook-folder/ds-mobile-handbook-folder.ts +0 -533
  78. package/src/components/handbook-folder/index.ts +0 -4
  79. package/src/components/header-content/ds-mobile-header-content.ts +0 -222
  80. package/src/components/header-content/index.ts +0 -2
  81. package/src/components/illustration/ds-mobile-illustration.ts +0 -124
  82. package/src/components/illustration/index.ts +0 -2
  83. package/src/components/index.ts +0 -124
  84. package/src/components/inline-photo/ds-mobile-inline-photo.ts +0 -361
  85. package/src/components/inline-photo/index.ts +0 -1
  86. package/src/components/inline-tabs/ds-mobile-inline-tabs.ts +0 -132
  87. package/src/components/inline-tabs/index.ts +0 -2
  88. package/src/components/interactive-list-item-booking/ds-mobile-interactive-list-item-booking.ts +0 -350
  89. package/src/components/interactive-list-item-booking/index.ts +0 -1
  90. package/src/components/interactive-list-item-inquiry/ds-mobile-interactive-list-item-inquiry.ts +0 -321
  91. package/src/components/interactive-list-item-inquiry/index.ts +0 -2
  92. package/src/components/interactive-list-item-message/ds-mobile-interactive-list-item-message.ts +0 -237
  93. package/src/components/interactive-list-item-message/index.ts +0 -2
  94. package/src/components/interactive-list-item-post/ds-mobile-interactive-list-item-post.ts +0 -549
  95. package/src/components/interactive-list-item-post/ds-mobile-post-pdf-attachment.ts +0 -124
  96. package/src/components/interactive-list-item-post/index.ts +0 -13
  97. package/src/components/lightbox/ds-mobile-lightbox-footer.ts +0 -315
  98. package/src/components/lightbox/ds-mobile-lightbox-header.ts +0 -202
  99. package/src/components/lightbox/ds-mobile-lightbox-image.ts +0 -484
  100. package/src/components/lightbox/ds-mobile-lightbox-pdf.css +0 -377
  101. package/src/components/lightbox/ds-mobile-lightbox-pdf.ts +0 -374
  102. package/src/components/lightbox/ds-mobile-lightbox.css +0 -587
  103. package/src/components/lightbox/ds-mobile-lightbox.service.ts +0 -296
  104. package/src/components/lightbox/ds-mobile-lightbox.ts +0 -529
  105. package/src/components/lightbox/index.ts +0 -22
  106. package/src/components/list-item/ds-mobile-list-item.ts +0 -603
  107. package/src/components/list-item/index.ts +0 -2
  108. package/src/components/list-item-static/ds-mobile-list-item-static.ts +0 -133
  109. package/src/components/list-item-static/index.ts +0 -2
  110. package/src/components/loader-overlay/ds-mobile-loader-overlay.css +0 -49
  111. package/src/components/loader-overlay/ds-mobile-loader-overlay.ts +0 -77
  112. package/src/components/loader-overlay/index.ts +0 -1
  113. package/src/components/logo/ds-logo.ts +0 -95
  114. package/src/components/logo/index.ts +0 -2
  115. package/src/components/message-bubble/ds-mobile-message-bubble.ts +0 -633
  116. package/src/components/message-bubble/index.ts +0 -7
  117. package/src/components/message-composer/ds-mobile-message-composer.ts +0 -1146
  118. package/src/components/message-composer/index.ts +0 -7
  119. package/src/components/modal/ds-mobile-modal.css +0 -163
  120. package/src/components/modal/ds-mobile-modal.service.ts +0 -329
  121. package/src/components/modal/index.ts +0 -8
  122. package/src/components/modal-base/ds-mobile-modal-base.css +0 -378
  123. package/src/components/modal-base/ds-mobile-modal-base.ts +0 -261
  124. package/src/components/modal-base/index.ts +0 -2
  125. package/src/components/new-inquiry-modal/ds-mobile-new-inquiry-modal.css +0 -112
  126. package/src/components/new-inquiry-modal/ds-mobile-new-inquiry-modal.service.ts +0 -93
  127. package/src/components/new-inquiry-modal/ds-mobile-new-inquiry-modal.ts +0 -442
  128. package/src/components/new-inquiry-modal/index.ts +0 -4
  129. package/src/components/offline-banner/ds-mobile-offline-banner.ts +0 -135
  130. package/src/components/offline-banner/index.ts +0 -1
  131. package/src/components/page-details/ds-mobile-page-details.css +0 -83
  132. package/src/components/page-details/ds-mobile-page-details.ts +0 -282
  133. package/src/components/page-details/index.ts +0 -2
  134. package/src/components/page-main/ds-mobile-page-main.css +0 -68
  135. package/src/components/page-main/ds-mobile-page-main.ts +0 -421
  136. package/src/components/page-main/index.ts +0 -2
  137. package/src/components/post-composer/ds-mobile-post-composer.ts +0 -140
  138. package/src/components/post-composer/index.ts +0 -2
  139. package/src/components/post-detail-modal/ds-mobile-post-detail-modal.css +0 -390
  140. package/src/components/post-detail-modal/ds-mobile-post-detail-modal.service.ts +0 -108
  141. package/src/components/post-detail-modal/ds-mobile-post-detail-modal.ts +0 -722
  142. package/src/components/post-detail-modal/index.ts +0 -9
  143. package/src/components/property-banner/ds-mobile-property-banner.ts +0 -95
  144. package/src/components/property-banner/index.ts +0 -2
  145. package/src/components/section/ds-mobile-section.ts +0 -263
  146. package/src/components/section/index.ts +0 -2
  147. package/src/components/shared/directives/index.ts +0 -2
  148. package/src/components/shared/directives/long-press.directive.ts +0 -212
  149. package/src/components/shared/index.ts +0 -3
  150. package/src/components/shared/mobile-modal-base.ts +0 -457
  151. package/src/components/shared/mobile-page-base.ts +0 -204
  152. package/src/components/swiper/ds-mobile-swiper-with-nav.ts +0 -160
  153. package/src/components/swiper/ds-mobile-swiper.ts +0 -327
  154. package/src/components/swiper/index.ts +0 -3
  155. package/src/components/system-message-banner/ds-mobile-system-message-banner.ts +0 -129
  156. package/src/components/system-message-banner/index.ts +0 -2
  157. package/src/components/tab-bar/ds-mobile-tab-bar.css +0 -533
  158. package/src/components/tab-bar/ds-mobile-tab-bar.ts +0 -735
  159. package/src/components/tab-bar/index.ts +0 -2
  160. package/src/components/tabs/ds-mobile-tabs.css +0 -25
  161. package/src/components/tabs/ds-mobile-tabs.ts +0 -89
  162. package/src/components/tabs/index.ts +0 -2
  163. package/src/components/text-input/ds-text-input.ts +0 -287
  164. package/src/components/text-input/index.ts +0 -2
  165. package/src/examples/booking.page.ts +0 -434
  166. package/src/examples/community.page.ts +0 -776
  167. package/src/examples/handbook.page.ts +0 -324
  168. package/src/examples/home.page.ts +0 -347
  169. package/src/examples/index.ts +0 -12
  170. package/src/examples/inquiries.example.ts +0 -273
  171. package/src/examples/inquiry-detail.example.css +0 -189
  172. package/src/examples/inquiry-detail.example.ts +0 -415
  173. package/src/examples/mobile-tabs-example.component.ts +0 -208
  174. package/src/examples/post-create.page.ts +0 -311
  175. package/src/examples/post-detail.page.ts +0 -296
  176. package/src/examples/sign-in.page.ts +0 -291
  177. package/src/examples/whitelabel-demo-modal.component.ts +0 -1094
  178. package/src/examples/whitelabel-demo-modal.service.ts +0 -77
  179. package/src/models/index.ts +0 -7
  180. package/src/models/post.model.ts +0 -41
  181. package/src/pages/community.page.ts +0 -769
  182. package/src/pages/handbook.page.ts +0 -388
  183. package/src/pages/home.page.ts +0 -303
  184. package/src/pages/index.ts +0 -11
  185. package/src/pages/inquiries.example.ts +0 -273
  186. package/src/pages/inquiry-detail.example.css +0 -189
  187. package/src/pages/inquiry-detail.example.ts +0 -415
  188. package/src/pages/mobile-tabs-example.component.ts +0 -179
  189. package/src/pages/post-create.page.ts +0 -311
  190. package/src/pages/post-detail.page.ts +0 -296
  191. package/src/pages/sign-in.page.ts +0 -291
  192. package/src/pages/whitelabel-demo-modal.component.ts +0 -1094
  193. package/src/pages/whitelabel-demo-modal.service.ts +0 -77
  194. package/src/public-api.ts +0 -6
  195. package/src/services/base-modal.service.ts +0 -101
  196. package/src/services/index.ts +0 -11
  197. package/src/services/posts.service.ts +0 -542
  198. package/src/services/tracking-permission.service.ts +0 -88
  199. package/src/services/user.service.ts +0 -60
  200. package/src/services/whitelabel.service.ts +0 -675
  201. package/tsconfig.lib.json +0 -17
  202. package/tsconfig.lib.prod.json +0 -9
  203. package/tsconfig.spec.json +0 -13
  204. /package/{src/assets → assets}/fonts/Brockmann-Bold.otf +0 -0
  205. /package/{src/assets → assets}/fonts/Brockmann-BoldItalic.otf +0 -0
  206. /package/{src/assets → assets}/fonts/Brockmann-Medium.otf +0 -0
  207. /package/{src/assets → assets}/fonts/Brockmann-MediumItalic.otf +0 -0
  208. /package/{src/assets → assets}/fonts/Brockmann-Regular.otf +0 -0
  209. /package/{src/assets → assets}/fonts/Brockmann-RegularItalic.otf +0 -0
  210. /package/{src/assets → assets}/fonts/Brockmann-SemiBold.otf +0 -0
  211. /package/{src/assets → assets}/fonts/Brockmann-SemiBoldItalic.otf +0 -0
  212. /package/{src/assets → assets}/fonts/Brockmann_desktop_license.pdf +0 -0
  213. /package/{src/assets → assets}/fonts/brockmann-medium-webfont.woff2 +0 -0
  214. /package/{src/assets → assets}/fonts/brockmann-mediumitalic-webfont.woff2 +0 -0
  215. /package/{src/assets → assets}/fonts/brockmann-regular-webfont.woff2 +0 -0
  216. /package/{src/assets → assets}/fonts/brockmann-regularitalic-webfont.woff2 +0 -0
  217. /package/{src/assets → assets}/fonts/brockmann-semibold-webfont.woff2 +0 -0
  218. /package/{src/assets → assets}/fonts/brockmann-semibolditalic-webfont.woff2 +0 -0
  219. /package/{src/styles → styles}/ionic.css +0 -0
  220. /package/{src/components/shared → styles}/mobile-common.css +0 -0
  221. /package/{src/components/shared → styles}/mobile-page-base.css +0 -0
@@ -1,378 +0,0 @@
1
- /**
2
- * Mobile Modal Base Styles
3
- *
4
- * Shared styles for all mobile modal components.
5
- * These styles handle the base modal structure, header, loading/error states,
6
- * and fixed bottom components.
7
- *
8
- * Component-specific styles should be defined in each modal's own CSS file.
9
- */
10
-
11
- /* ============================================
12
- HOST AND CONTENT
13
- ============================================ */
14
-
15
- :host {
16
- display: block;
17
- position: relative;
18
- height: 100%;
19
- width: 100%;
20
- }
21
-
22
- :host(.is-auto-height) {
23
- height: auto;
24
- }
25
-
26
- .modal-base-content {
27
- --background: var(--color-background-neutral-primary, #ffffff);
28
- }
29
-
30
- .modal-base-content.is-auto-height {
31
- --height: auto;
32
- height: auto !important;
33
- flex: 0 0 auto;
34
- display: block;
35
- contain: none !important;
36
- }
37
-
38
- /* Ensure the scroll part also allows auto height */
39
- .modal-base-content.is-auto-height::part(scroll) {
40
- position: relative !important;
41
- display: block !important;
42
- height: auto !important;
43
- overflow: visible !important;
44
- }
45
-
46
- /* ============================================
47
- MODAL WRAPPER
48
- ============================================ */
49
-
50
- .modal-wrapper {
51
- display: flex;
52
- flex-direction: column;
53
- width: 100%;
54
- background: var(--color-background-neutral-primary, #ffffff);
55
- }
56
-
57
- .modal-wrapper.is-auto-height {
58
- flex: 0 0 auto;
59
- }
60
-
61
- /* ============================================
62
- MODAL HEADER
63
- ============================================ */
64
-
65
- .modal-header {
66
- position: sticky;
67
- top: 0;
68
- z-index: 10;
69
- background: var(--color-background-neutral-primary, #ffffff);
70
- border-bottom: 1px solid var(--border-color-default);
71
- padding: 16px;
72
- }
73
-
74
- .modal-header.no-leading-content {
75
- padding-left: 20px;
76
- }
77
-
78
- .header-content {
79
- display: flex;
80
- align-items: center;
81
- justify-content: space-between;
82
- gap: 12px;
83
- /* No padding needed - StatusBar.setOverlaysWebView(false) handles all spacing */
84
- }
85
-
86
- /* Header Leading (Avatar, Icon) */
87
- .header-leading {
88
- flex-shrink: 0;
89
- display: flex;
90
- align-items: center;
91
- }
92
-
93
- /* Hide header-leading when empty and adjust spacing */
94
- .header-leading:empty {
95
- display: none;
96
- }
97
-
98
- /* Adjust gap when header-leading is empty */
99
- .modal-header.no-leading-content .header-content,
100
- .header-content:has(.header-leading:empty) {
101
- gap: 16px;
102
- }
103
-
104
- /* Header Main (Title, Meta, Custom Content) */
105
- .header-main {
106
- display: flex;
107
- flex-direction: column;
108
- min-width: 0;
109
- flex: 1;
110
- gap: 2px;
111
- }
112
-
113
- .modal-title {
114
- font-family: 'Brockmann', sans-serif;
115
- font-size: var(--font-size-base);
116
- font-weight: 600;
117
- line-height: 20px;
118
- letter-spacing: -0.3px;
119
- color: var(--color-text-primary, #1a1a1a);
120
- white-space: nowrap;
121
- overflow: hidden;
122
- text-overflow: ellipsis;
123
- }
124
-
125
- .modal-meta {
126
- font-family: 'Brockmann', sans-serif;
127
- font-size: var(--font-size-xs);
128
- font-weight: 400;
129
- line-height: 1.2;
130
- letter-spacing: -0.26px;
131
- color: var(--color-text-tertiary, #737373);
132
- display: flex;
133
- align-items: center;
134
- gap: 6px;
135
- }
136
-
137
- /* Close Button (in header) */
138
- .close-button {
139
- flex-shrink: 0;
140
- border-radius: 50%;
141
- }
142
-
143
- .close-button::ng-deep button {
144
- border-radius: 50% !important;
145
- width: 36px !important;
146
- height: 36px !important;
147
- min-width: 36px !important;
148
- min-height: 36px !important;
149
- padding: 0 !important;
150
- display: flex !important;
151
- align-items: center !important;
152
- justify-content: center !important;
153
- }
154
-
155
- /* Close Button (absolute, when header is hidden) */
156
- .close-button-absolute {
157
- position: absolute;
158
- top: 16px;
159
- right: 16px;
160
- z-index: 100;
161
- flex-shrink: 0;
162
- border-radius: 50%;
163
- }
164
-
165
- .close-button-absolute::ng-deep button {
166
- border-radius: 50% !important;
167
- width: 36px !important;
168
- height: 36px !important;
169
- min-width: 36px !important;
170
- min-height: 36px !important;
171
- padding: 0 !important;
172
- display: flex !important;
173
- align-items: center !important;
174
- justify-content: center !important;
175
- }
176
-
177
- /* ============================================
178
- MODAL CONTENT CONTAINER
179
- ============================================ */
180
-
181
- .modal-content-container {
182
- display: flex;
183
- flex-direction: column;
184
- width: 100%;
185
- max-width: 640px;
186
- margin: 0 auto;
187
- flex: 1;
188
- position: relative;
189
- /* Dynamic bottom padding that matches fixed bottom height */
190
- }
191
-
192
- /* Allow auto-height when used as a bottom sheet */
193
- :host-context(ion-modal.auto-height) .modal-content-container,
194
- .modal-wrapper.is-auto-height .modal-content-container {
195
- flex: 0 0 auto;
196
- }
197
-
198
- /* No top padding when header is hidden - ds-mobile-section provides spacing */
199
- .modal-wrapper.headerless .modal-content-container {
200
- padding-top: 0;
201
- }
202
-
203
- .modal-main-content {
204
- display: flex;
205
- flex-direction: column;
206
- width: 100%;
207
- /* No top padding - ds-mobile-section provides its own */
208
- padding-top: 0;
209
- padding-left: var(--modal-content-padding, 20px);
210
- padding-right: var(--modal-content-padding, 20px);
211
- padding-bottom: var(--modal-content-padding, 20px);
212
- }
213
-
214
- .modal-main-content.content-hidden {
215
- display: none;
216
- }
217
-
218
- /* Hide state containers when not active */
219
- .state-hidden {
220
- display: none;
221
- }
222
-
223
- .custom-loading-slot,
224
- .custom-error-slot {
225
- width: 100%;
226
- }
227
-
228
- /* ============================================
229
- LOADING STATE
230
- ============================================ */
231
-
232
- .modal-loading-state {
233
- display: flex;
234
- flex-direction: column;
235
- align-items: center;
236
- justify-content: center;
237
- padding: 60px 20px;
238
- text-align: center;
239
- }
240
-
241
- .loading-spinner {
242
- width: 48px;
243
- height: 48px;
244
- border: 3px solid var(--color-background-neutral-secondary, #f0f0f0);
245
- border-top-color: var(--color-primary-base, #2563eb);
246
- border-radius: 50%;
247
- animation: spin 1s linear infinite;
248
- }
249
-
250
- @keyframes spin {
251
- to {
252
- transform: rotate(360deg);
253
- }
254
- }
255
-
256
- .loading-text {
257
- font-family: 'Brockmann', sans-serif;
258
- font-size: var(--font-size-sm);
259
- font-weight: 400;
260
- line-height: 1.4;
261
- color: var(--color-text-secondary, #737373);
262
- margin-top: 16px;
263
- }
264
-
265
- /* ============================================
266
- ERROR STATE
267
- ============================================ */
268
-
269
- .modal-error-state {
270
- display: flex;
271
- flex-direction: column;
272
- align-items: center;
273
- justify-content: center;
274
- padding: 60px 20px;
275
- text-align: center;
276
- gap: 16px;
277
- }
278
-
279
- .error-state-title {
280
- font-family: 'Brockmann', sans-serif;
281
- font-size: var(--font-size-base);
282
- font-weight: 600;
283
- line-height: 1.3;
284
- color: var(--color-text-primary, #1a1a1a);
285
- margin: 0;
286
- }
287
-
288
- .error-state-description {
289
- font-family: 'Brockmann', sans-serif;
290
- font-size: var(--font-size-sm);
291
- font-weight: 400;
292
- line-height: 1.4;
293
- color: var(--color-text-secondary, #737373);
294
- margin: 0;
295
- }
296
-
297
- /* ============================================
298
- FIXED BOTTOM COMPONENT / FOOTER
299
- ============================================ */
300
-
301
- /**
302
- * Fixed bottom container for footer actions (e.g., submit buttons, composers)
303
- *
304
- * Features:
305
- * - Automatically slides up with keyboard on iOS/Android (via --keyboard-height)
306
- * - Synchronized with scroll animation using matching cubic-bezier curve
307
- * - Respects safe areas with bottom padding
308
- * - Hidden during loading/error states
309
- * - Opaque background with box-shadow to cover gap between content and keyboard
310
- * - Use [footer] or [fixed-bottom] attribute on content
311
- *
312
- * Usage:
313
- * <ds-mobile-modal-base [hasFixedBottom]="true" [enableKeyboardHandling]="true">
314
- * <div footer>Your footer content</div>
315
- * </ds-mobile-modal-base>
316
- */
317
- .modal-fixed-bottom {
318
- position: fixed;
319
- bottom: 0;
320
- left: 0;
321
- right: 0;
322
- z-index: 1000;
323
- pointer-events: none;
324
- /* Background and box-shadow to cover gap between fixed bottom and keyboard */
325
- background: var(--color-background-neutral-primary, #ffffff);
326
- box-shadow: 0 300px 0 300px var(--color-background-neutral-primary, #ffffff);
327
- /* Slide up with keyboard on native apps */
328
- transform: translateY(calc(-1 * var(--keyboard-height, 0px)));
329
- /* Use cubic-bezier that matches scroll animation (ease-out cubic) for perfect sync */
330
- transition: transform 0.3s cubic-bezier(0.215, 0.61, 0.355, 1);
331
- max-width: 100vw;
332
- /* Same safe-area strategy as tab bar: iOS uses reduced inset with floor */
333
- padding-bottom: max(8px, calc(var(--app-safe-bottom, 0px) - 24px));
334
- }
335
-
336
- /* Android gesture navigation keeps full inset for footer controls */
337
- :host-context(.plt-android) .modal-fixed-bottom {
338
- padding-bottom: max(8px, var(--app-safe-bottom, 0px));
339
- }
340
-
341
- .modal-fixed-bottom.is-auto-height {
342
- position: relative;
343
- bottom: auto;
344
- left: auto;
345
- right: auto;
346
- transform: none !important;
347
- box-shadow: none;
348
- z-index: 1;
349
- background: var(--color-background-neutral-primary, #ffffff);
350
- padding-bottom: var(--keyboard-height, 0px);
351
- transition: padding-bottom 0.3s cubic-bezier(0.215, 0.61, 0.355, 1);
352
- }
353
-
354
- .modal-fixed-bottom > * {
355
- pointer-events: auto;
356
- }
357
-
358
- .modal-fixed-bottom.bottom-hidden {
359
- display: none;
360
- }
361
-
362
- /* ============================================
363
- SAFE AREA SUPPORT
364
- ============================================ */
365
-
366
- /* ============================================
367
- ACCESSIBILITY: REDUCED MOTION
368
- ============================================ */
369
-
370
- @media (prefers-reduced-motion: reduce) {
371
- .modal-fixed-bottom {
372
- transition: none;
373
- }
374
-
375
- .loading-spinner {
376
- animation: none;
377
- }
378
- }
@@ -1,261 +0,0 @@
1
- import { Component, ContentChild, ElementRef, CUSTOM_ELEMENTS_SCHEMA, AfterContentInit, ChangeDetectorRef, input, HostBinding, ViewChild, OnDestroy, OnInit } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
3
- import { IonContent } from '@ionic/angular/standalone';
4
- import { DsIconButtonComponent, DsIconComponent } from '@propbinder/design-system';
5
- import { MobileModalBase } from '../shared/mobile-modal-base';
6
-
7
- /**
8
- * DsMobileModalBaseComponent
9
- *
10
- * Base modal component providing consistent layout and behavior for all modals.
11
- *
12
- * **Features:**
13
- * - Optional header with auto-detection of content
14
- * - Flexible header with slots for leading content (avatar, icon)
15
- * - Title and metadata inputs or custom header slot
16
- * - Default loading and error state templates (with override capability)
17
- * - Fixed bottom component support (e.g., message composer)
18
- * - Automatic keyboard handling
19
- * - Configurable keyboard content behavior (`follow` or `overlay`)
20
- * - Safe area support
21
- *
22
- * **Slot Structure:**
23
- * - `[header-leading]` - Left side of header (avatar, icon)
24
- * - `[header-main]` - Custom header content (replaces title/meta)
25
- * - `[loading-state]` - Custom loading template
26
- * - `[error-state]` - Custom error template
27
- * - `[footer]` or `[fixed-bottom]` - Fixed bottom component (slides with keyboard)
28
- * - Default slot - Main modal content
29
- *
30
- * @example
31
- * ```html
32
- * <!-- Simple title modal -->
33
- * <ds-mobile-modal-base
34
- * headerTitle="Settings"
35
- * closeButtonLabel="Close">
36
- * <div class="content">...</div>
37
- * </ds-mobile-modal-base>
38
- *
39
- * <!-- Avatar header modal -->
40
- * <ds-mobile-modal-base
41
- * headerTitle="John Doe"
42
- * headerMeta="Tenant · 2h ago"
43
- * [hasFixedBottom]="true"
44
- * [enableKeyboardHandling]="true">
45
- *
46
- * <ds-avatar header-leading [initials]="'JD'" size="md" />
47
- *
48
- * <div class="content">...</div>
49
- *
50
- * <div fixed-bottom class="composer">...</div>
51
- * </ds-mobile-modal-base>
52
- *
53
- * <!-- Headerless modal (close button positioned absolutely) -->
54
- * <ds-mobile-modal-base [showHeader]="false">
55
- * <div class="full-width-content">...</div>
56
- * </ds-mobile-modal-base>
57
- *
58
- * <!-- Modal with footer actions (slides with keyboard) -->
59
- * <ds-mobile-modal-base
60
- * headerTitle="Create Inquiry"
61
- * [hasFixedBottom]="true"
62
- * [enableKeyboardHandling]="true"
63
- * [keyboardContentBehavior]="'overlay'">
64
- *
65
- * <div class="content">
66
- * <input type="text" placeholder="Type something..." />
67
- * </div>
68
- *
69
- * <div footer class="action-bar">
70
- * <button>Cancel</button>
71
- * <button>Submit</button>
72
- * </div>
73
- * </ds-mobile-modal-base>
74
- * ```
75
- */
76
- @Component({
77
- selector: 'ds-mobile-modal-base',
78
- standalone: true,
79
- imports: [CommonModule, IonContent, DsIconButtonComponent, DsIconComponent],
80
- schemas: [CUSTOM_ELEMENTS_SCHEMA],
81
- styleUrls: ['./ds-mobile-modal-base.css'],
82
- host: {
83
- '[style.--modal-content-padding]': 'contentPadding()',
84
- '[class.is-auto-height]': 'isAutoHeight()',
85
- },
86
- template: `
87
- <ion-content
88
- [fullscreen]="!isAutoHeight()"
89
- [scrollY]="true"
90
- [class.is-auto-height]="isAutoHeight()"
91
- class="modal-base-content"
92
- [style.--padding-bottom]="contentPadding() || (hasFixedBottom() ? 'var(--fixed-bottom-height)' : '24px')"
93
- >
94
- <div class="modal-wrapper" [class.headerless]="!shouldShowHeader()" [class.is-auto-height]="isAutoHeight()">
95
- <!-- Header (conditional) -->
96
- @if (shouldShowHeader()) {
97
- <div class="modal-header" [class.no-leading-content]="!hasHeaderLeadingContent()">
98
- <div class="header-content">
99
- <!-- Leading slot (avatar, icon) - always rendered, CSS handles empty state -->
100
- <div class="header-leading">
101
- <ng-content select="[header-leading]"></ng-content>
102
- </div>
103
-
104
- <!-- Main (title + meta or custom) -->
105
- <div class="header-main">
106
- @if (headerTitle()) {
107
- <div class="modal-title">{{ headerTitle() }}</div>
108
- }
109
- @if (headerMeta()) {
110
- <div class="modal-meta">{{ headerMeta() }}</div>
111
- }
112
- <ng-content select="[header-main]"></ng-content>
113
- </div>
114
-
115
- <!-- Close button (in header) -->
116
- <ds-icon-button icon="remixCloseLine" variant="secondary" size="lg" (clicked)="close()" class="close-button" [attr.aria-label]="closeButtonLabel()" />
117
- </div>
118
- </div>
119
- }
120
-
121
- <!-- Absolute close button (when header is hidden) -->
122
- @if (!shouldShowHeader()) {
123
- <ds-icon-button icon="remixCloseLine" variant="secondary" size="lg" (clicked)="close()" class="close-button-absolute" [attr.aria-label]="closeButtonLabel()" />
124
- }
125
-
126
- <!-- Content Container -->
127
- <div class="modal-content-container">
128
- <!-- Custom Loading State Slot - always present -->
129
- <div class="custom-loading-slot" [class.state-hidden]="!(loading() && hasCustomLoadingState)">
130
- <ng-content select="[loading-state]"></ng-content>
131
- </div>
132
-
133
- <!-- Default Loading State -->
134
- @if (loading() && !hasCustomLoadingState) {
135
- <div class="modal-loading-state">
136
- <div class="loading-spinner"></div>
137
- <p class="loading-text">Loading...</p>
138
- </div>
139
- }
140
-
141
- <!-- Custom Error State Slot - always present -->
142
- <div class="custom-error-slot" [class.state-hidden]="!(error() && !loading() && hasCustomErrorState)">
143
- <ng-content select="[error-state]"></ng-content>
144
- </div>
145
-
146
- <!-- Default Error State -->
147
- @if (error() && !loading() && !hasCustomErrorState) {
148
- <div class="modal-error-state">
149
- <ds-icon name="remixErrorWarningLine" size="48px" [style.color]="'var(--color-destructive-base)'" />
150
- <h3 class="error-state-title">Error</h3>
151
- <p class="error-state-description">{{ error() }}</p>
152
- </div>
153
- }
154
-
155
- <!-- Main content - always rendered but hidden when loading/error -->
156
- <div class="modal-main-content" [class.content-hidden]="loading() || !!error()">
157
- <ng-content></ng-content>
158
- </div>
159
- </div>
160
- </div>
161
- </ion-content>
162
-
163
- <!-- Fixed Bottom Component / Footer (slides with keyboard) -->
164
- <div class="modal-fixed-bottom" [class.bottom-hidden]="!hasFixedBottom() || loading() || error()" [class.is-auto-height]="isAutoHeight()">
165
- <ng-content select="[fixed-bottom]"></ng-content>
166
- <ng-content select="[footer]"></ng-content>
167
- </div>
168
- `,
169
- })
170
- export class DsMobileModalBaseComponent extends MobileModalBase implements OnInit, AfterContentInit, OnDestroy {
171
- /**
172
- * Reference to ion-content for keyboard handling
173
- */
174
- @ViewChild(IonContent, { read: IonContent }) override ionContent?: IonContent = undefined;
175
-
176
- /**
177
- * Control header visibility
178
- * - true: Always show header
179
- * - false: Never show header (close button becomes absolute)
180
- * - 'auto' (default): Auto-detect based on header content
181
- */
182
- showHeader = input<boolean | 'auto'>('auto');
183
-
184
- /**
185
- * Detect if custom loading state is provided
186
- */
187
- @ContentChild('[loading-state]', { read: ElementRef }) customLoadingState?: ElementRef;
188
-
189
- /**
190
- * Detect if custom error state is provided
191
- */
192
- @ContentChild('[error-state]', { read: ElementRef }) customErrorState?: ElementRef;
193
-
194
- /**
195
- * Detect if header leading content is provided
196
- */
197
- @ContentChild('[header-leading]', { read: ElementRef }) headerLeading?: ElementRef;
198
-
199
- /**
200
- * Detect if header main content is provided
201
- */
202
- @ContentChild('[header-main]', { read: ElementRef }) headerMain?: ElementRef;
203
-
204
- /**
205
- * Flag to track if content has been initialized
206
- */
207
- hasCustomLoadingState = false;
208
- hasCustomErrorState = false;
209
-
210
- constructor(private cdr: ChangeDetectorRef) {
211
- super();
212
- }
213
-
214
- override ngOnInit(): void {
215
- // Call parent to set up keyboard listeners and ResizeObserver
216
- super.ngOnInit();
217
- }
218
-
219
- ngAfterContentInit(): void {
220
- // Check for content after content has been initialized
221
- this.hasCustomLoadingState = !!this.customLoadingState;
222
- this.hasCustomErrorState = !!this.customErrorState;
223
-
224
- // Trigger change detection to update the view
225
- this.cdr.detectChanges();
226
- }
227
-
228
- override ngOnDestroy(): void {
229
- super.ngOnDestroy();
230
- }
231
-
232
- /**
233
- * Determine if header should be shown based on showHeader input and content detection
234
- */
235
- shouldShowHeader(): boolean {
236
- const showHeaderValue = this.showHeader();
237
-
238
- // Explicit override
239
- if (showHeaderValue === true) return true;
240
- if (showHeaderValue === false) return false;
241
-
242
- // Auto-detect: show header if there's any header content
243
- return !!(this.headerTitle() || this.headerMeta() || this.hasContentInSlot(this.headerLeading) || this.hasContentInSlot(this.headerMain));
244
- }
245
-
246
- /**
247
- * Check whether header-leading slot has actual projected content.
248
- */
249
- hasHeaderLeadingContent(): boolean {
250
- return this.hasContentInSlot(this.headerLeading);
251
- }
252
-
253
- /**
254
- * Check if a content child slot has actual content
255
- */
256
- private hasContentInSlot(slot?: ElementRef): boolean {
257
- if (!slot) return false;
258
- const element = slot.nativeElement;
259
- return element && (element.childNodes.length > 0 || element.textContent?.trim().length > 0);
260
- }
261
- }
@@ -1,2 +0,0 @@
1
- export * from './ds-mobile-modal-base';
2
- export * from '../shared/mobile-modal-base';