@propbinder/mobile-design 0.0.2 → 0.0.21

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 (123) hide show
  1. package/fesm2022/propbinder-mobile-design.mjs +12596 -0
  2. package/fesm2022/propbinder-mobile-design.mjs.map +1 -0
  3. package/index.d.ts +3214 -0
  4. package/package.json +39 -12
  5. package/ng-package.json +0 -7
  6. package/src/animations/page-transitions.ts +0 -86
  7. package/src/assets/fonts/Brockmann-Bold.otf +0 -0
  8. package/src/assets/fonts/Brockmann-BoldItalic.otf +0 -0
  9. package/src/assets/fonts/Brockmann-Medium.otf +0 -0
  10. package/src/assets/fonts/Brockmann-MediumItalic.otf +0 -0
  11. package/src/assets/fonts/Brockmann-Regular.otf +0 -0
  12. package/src/assets/fonts/Brockmann-RegularItalic.otf +0 -0
  13. package/src/assets/fonts/Brockmann-SemiBold.otf +0 -0
  14. package/src/assets/fonts/Brockmann-SemiBoldItalic.otf +0 -0
  15. package/src/assets/fonts/Brockmann_desktop_license.pdf +0 -0
  16. package/src/assets/fonts/brockmann-medium-webfont.woff2 +0 -0
  17. package/src/assets/fonts/brockmann-regular-webfont.woff2 +0 -0
  18. package/src/assets/fonts/brockmann-semibold-webfont.woff2 +0 -0
  19. package/src/components/action-list-item/ds-mobile-action-list-item.ts +0 -83
  20. package/src/components/action-list-item/index.ts +0 -2
  21. package/src/components/app-layout/ds-mobile-app-layout.css +0 -343
  22. package/src/components/app-layout/ds-mobile-app-layout.ts +0 -271
  23. package/src/components/app-layout/index.ts +0 -2
  24. package/src/components/avatar-with-badge/ds-avatar-with-badge.ts +0 -130
  25. package/src/components/avatar-with-badge/index.ts +0 -2
  26. package/src/components/bottom-sheet/ds-mobile-actions-bottom-sheet.ts +0 -273
  27. package/src/components/bottom-sheet/ds-mobile-bottom-sheet.css +0 -110
  28. package/src/components/bottom-sheet/ds-mobile-bottom-sheet.service.ts +0 -167
  29. package/src/components/bottom-sheet/ds-mobile-post-create-bottom-sheet.ts +0 -656
  30. package/src/components/bottom-sheet/index.ts +0 -3
  31. package/src/components/comment/ds-mobile-comment.ts +0 -516
  32. package/src/components/comment/index.ts +0 -2
  33. package/src/components/contact-list-item/ds-mobile-contact-list-item.ts +0 -182
  34. package/src/components/contact-list-item/index.ts +0 -2
  35. package/src/components/content/ds-mobile-content.ts +0 -158
  36. package/src/components/content/index.ts +0 -2
  37. package/src/components/ds-mobile-tabs.css +0 -372
  38. package/src/components/ds-mobile-tabs.ts +0 -217
  39. package/src/components/file-attachment/ds-mobile-file-attachment.ts +0 -164
  40. package/src/components/file-attachment/index.ts +0 -2
  41. package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.service.ts +0 -98
  42. package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.ts +0 -514
  43. package/src/components/handbook-detail-modal/index.ts +0 -3
  44. package/src/components/handbook-folder/ds-mobile-handbook-folder-mini.ts +0 -130
  45. package/src/components/handbook-folder/ds-mobile-handbook-folder.ts +0 -444
  46. package/src/components/handbook-folder/index.ts +0 -4
  47. package/src/components/header-content/ds-mobile-header-content.ts +0 -211
  48. package/src/components/header-content/index.ts +0 -2
  49. package/src/components/index.ts +0 -45
  50. package/src/components/inline-photo/ds-mobile-inline-photo.ts +0 -269
  51. package/src/components/inline-photo/index.ts +0 -1
  52. package/src/components/interactive-list-item-inquiry/ds-mobile-interactive-list-item-inquiry.css +0 -60
  53. package/src/components/interactive-list-item-inquiry/ds-mobile-interactive-list-item-inquiry.ts +0 -280
  54. package/src/components/interactive-list-item-inquiry/index.ts +0 -2
  55. package/src/components/interactive-list-item-message/ds-mobile-interactive-list-item-message.ts +0 -197
  56. package/src/components/interactive-list-item-message/index.ts +0 -2
  57. package/src/components/interactive-list-item-post/ds-mobile-interactive-list-item-post.css +0 -70
  58. package/src/components/interactive-list-item-post/ds-mobile-interactive-list-item-post.ts +0 -594
  59. package/src/components/interactive-list-item-post/ds-mobile-post-pdf-attachment.ts +0 -124
  60. package/src/components/interactive-list-item-post/index.ts +0 -13
  61. package/src/components/lightbox/ds-mobile-lightbox-footer.ts +0 -331
  62. package/src/components/lightbox/ds-mobile-lightbox-header.ts +0 -173
  63. package/src/components/lightbox/ds-mobile-lightbox-image.ts +0 -464
  64. package/src/components/lightbox/ds-mobile-lightbox-pdf.css +0 -375
  65. package/src/components/lightbox/ds-mobile-lightbox-pdf.ts +0 -374
  66. package/src/components/lightbox/ds-mobile-lightbox.css +0 -587
  67. package/src/components/lightbox/ds-mobile-lightbox.service.ts +0 -293
  68. package/src/components/lightbox/ds-mobile-lightbox.ts +0 -529
  69. package/src/components/lightbox/index.ts +0 -22
  70. package/src/components/list-item/ds-mobile-list-item.ts +0 -499
  71. package/src/components/list-item/index.ts +0 -2
  72. package/src/components/list-item-static/ds-mobile-list-item-static.ts +0 -133
  73. package/src/components/list-item-static/index.ts +0 -2
  74. package/src/components/logo/ds-logo.ts +0 -85
  75. package/src/components/logo/index.ts +0 -2
  76. package/src/components/modal/ds-mobile-modal.css +0 -163
  77. package/src/components/modal/ds-mobile-modal.service.ts +0 -329
  78. package/src/components/modal/index.ts +0 -8
  79. package/src/components/page-details/ds-mobile-page-details.css +0 -285
  80. package/src/components/page-details/ds-mobile-page-details.ts +0 -128
  81. package/src/components/page-details/index.ts +0 -2
  82. package/src/components/page-main/ds-mobile-page-main.css +0 -346
  83. package/src/components/page-main/ds-mobile-page-main.ts +0 -331
  84. package/src/components/page-main/index.ts +0 -2
  85. package/src/components/post-card/ds-mobile-post-card.ts +0 -685
  86. package/src/components/post-card/ds-mobile-post-pdf-attachment.ts +0 -124
  87. package/src/components/post-card/index.ts +0 -11
  88. package/src/components/post-composer/ds-mobile-post-composer.ts +0 -140
  89. package/src/components/post-composer/index.ts +0 -2
  90. package/src/components/post-detail-modal/ds-mobile-post-detail-modal.service.ts +0 -104
  91. package/src/components/post-detail-modal/ds-mobile-post-detail-modal.ts +0 -1273
  92. package/src/components/post-detail-modal/index.ts +0 -9
  93. package/src/components/shared/directives/index.ts +0 -2
  94. package/src/components/shared/directives/long-press.directive.ts +0 -208
  95. package/src/components/shared/index.ts +0 -3
  96. package/src/components/shared/mobile-common.css +0 -94
  97. package/src/components/shared/mobile-page-base.css +0 -315
  98. package/src/components/shared/mobile-page-base.ts +0 -70
  99. package/src/components/swiper/ds-mobile-swiper.ts +0 -123
  100. package/src/components/swiper/index.ts +0 -2
  101. package/src/components/tab-bar/ds-mobile-tab-bar.ts +0 -132
  102. package/src/components/tab-bar/index.ts +0 -2
  103. package/src/components/tabs/ds-mobile-tabs.css +0 -405
  104. package/src/components/tabs/ds-mobile-tabs.ts +0 -204
  105. package/src/components/tabs/index.ts +0 -2
  106. package/src/pages/community.page.ts +0 -768
  107. package/src/pages/handbook.page.ts +0 -298
  108. package/src/pages/home.page.ts +0 -192
  109. package/src/pages/index.ts +0 -9
  110. package/src/pages/inquiries.example.ts +0 -212
  111. package/src/pages/inquiry-detail.example.css +0 -434
  112. package/src/pages/inquiry-detail.example.ts +0 -416
  113. package/src/pages/mobile-tabs-example.component.ts +0 -146
  114. package/src/pages/post-create.page.ts +0 -311
  115. package/src/pages/post-detail.page.ts +0 -295
  116. package/src/pages/whitelabel-demo.page.ts +0 -548
  117. package/src/public-api.ts +0 -5
  118. package/src/services/user.service.ts +0 -35
  119. package/src/services/whitelabel.service.ts +0 -171
  120. package/src/styles/ionic.css +0 -673
  121. package/tsconfig.lib.json +0 -17
  122. package/tsconfig.lib.prod.json +0 -9
  123. package/tsconfig.spec.json +0 -13
package/index.d.ts ADDED
@@ -0,0 +1,3214 @@
1
+ import * as _angular_core from '@angular/core';
2
+ import { AfterViewInit, ElementRef, OnDestroy, EventEmitter, OnInit, ApplicationRef, EnvironmentInjector, Type } from '@angular/core';
3
+ import { IonContent, NavController, ModalController, GestureController } from '@ionic/angular/standalone';
4
+ import { ImpactStyle } from '@capacitor/haptics';
5
+ import { Router, ActivatedRoute } from '@angular/router';
6
+ import { BreakpointObserver } from '@angular/cdk/layout';
7
+ import { Animation } from '@ionic/angular';
8
+
9
+ /**
10
+ * Content width preset values
11
+ * - 'narrow' - 640px max width (reading content)
12
+ * - 'standard' - 1024px max width (default)
13
+ * - 'wide' - 1440px max width (dashboards)
14
+ * - 'full' - 100% width (no max)
15
+ */
16
+ type ContentWidth = 'narrow' | 'standard' | 'wide' | 'full';
17
+ /**
18
+ * MobilePageBase
19
+ *
20
+ * Shared base class for mobile page components (ds-mobile-page-main, ds-mobile-page-details).
21
+ * Provides consistent content width control across all page types.
22
+ *
23
+ * **Padding Strategy:**
24
+ * - All pages use 20px horizontal padding globally
25
+ * - For tappable lists, use negative margins (e.g., margin: 0 -8px) to create full-width sections
26
+ * - This approach simplifies padding management and provides consistency
27
+ *
28
+ * @internal This is a base class and should not be used directly.
29
+ */
30
+ declare abstract class MobilePageBase {
31
+ /**
32
+ * Maximum content width (desktop only)
33
+ *
34
+ * **Options:**
35
+ * - `'narrow'` (640px) - For reading content, forms
36
+ * - `'standard'` (1024px) - Default for most pages
37
+ * - `'wide'` (1440px) - For dashboards, tables
38
+ * - `'full'` - No max-width constraint
39
+ *
40
+ * **Note:** Only applies on desktop (>= 768px). Mobile is always full width.
41
+ *
42
+ * @default 'standard'
43
+ *
44
+ * @example
45
+ * ```html
46
+ * <!-- Narrow reading layout -->
47
+ * <ds-mobile-page-main title="Article" contentWidth="narrow">
48
+ *
49
+ * <!-- Wide dashboard -->
50
+ * <ds-mobile-page-main title="Dashboard" contentWidth="wide">
51
+ * ```
52
+ */
53
+ contentWidth: _angular_core.InputSignal<ContentWidth>;
54
+ /**
55
+ * Resolved max-width value (computed)
56
+ * Maps preset values to pixel values
57
+ *
58
+ * @internal
59
+ */
60
+ protected maxWidthValue: _angular_core.Signal<string>;
61
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MobilePageBase, never>;
62
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<MobilePageBase, never, never, { "contentWidth": { "alias": "contentWidth"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
63
+ }
64
+
65
+ /**
66
+ * DsMobilePageMainComponent
67
+ *
68
+ * A complete mobile page layout for main/tab pages with:
69
+ * - Fixed header with logomark + title + avatar
70
+ * - Purple expandable header section (scrolls with content)
71
+ * - White rounded content wrapper
72
+ * - Pull-to-refresh support
73
+ * - Auto scroll title fade-in
74
+ *
75
+ * @example
76
+ * ```html
77
+ * <!-- Simple page -->
78
+ * <ds-mobile-page-main
79
+ * title="Inquiries"
80
+ * [avatarInitials]="'JD'">
81
+ * <div class="page-content">
82
+ * <!-- Your content -->
83
+ * </div>
84
+ * </ds-mobile-page-main>
85
+ *
86
+ * <!-- Page with custom header content -->
87
+ * <ds-mobile-page-main
88
+ * title="Home"
89
+ * headerTitle="Welcome, Lars"
90
+ * headerSubtitle="Your rental property at a glance."
91
+ * [avatarInitials]="'L'">
92
+ *
93
+ * <div header-content class="property-tiles">
94
+ * <!-- Custom header content like tiles -->
95
+ * </div>
96
+ *
97
+ * <div class="page-content">
98
+ * <!-- Main page content -->
99
+ * </div>
100
+ * </ds-mobile-page-main>
101
+ * ```
102
+ */
103
+ declare class DsMobilePageMainComponent extends MobilePageBase implements AfterViewInit {
104
+ private elementRef;
105
+ ionContent?: IonContent;
106
+ private platform;
107
+ private modalController;
108
+ private router;
109
+ isNativePlatform: _angular_core.Signal<boolean>;
110
+ title: _angular_core.InputSignal<string>;
111
+ headerTitle: _angular_core.InputSignal<string>;
112
+ headerSubtitle: _angular_core.InputSignal<string>;
113
+ avatarType: _angular_core.InputSignal<"initials" | "photo" | "icon">;
114
+ avatarInitials: _angular_core.InputSignal<string>;
115
+ avatarSrc: _angular_core.InputSignal<string>;
116
+ avatarIconName: _angular_core.InputSignal<string>;
117
+ showRefresh: _angular_core.InputSignal<boolean>;
118
+ showCondensedHeader: _angular_core.InputSignal<boolean>;
119
+ scrollThreshold: _angular_core.InputSignal<number>;
120
+ headerFadeDistance: _angular_core.InputSignal<number>;
121
+ avatarClick: _angular_core.OutputEmitterRef<void>;
122
+ refresh: _angular_core.OutputEmitterRef<any>;
123
+ scroll: _angular_core.OutputEmitterRef<any>;
124
+ constructor(elementRef: ElementRef);
125
+ ngAfterViewInit(): void;
126
+ /**
127
+ * Handle avatar click - opens profile actions bottom sheet
128
+ */
129
+ handleAvatarClick(): Promise<void>;
130
+ /**
131
+ * Handle scroll events
132
+ * - Shows title in fixed header when scrolled past threshold
133
+ * - Fades out expandable header content based on scroll position
134
+ * - Emits scroll event for custom handling
135
+ */
136
+ handleScroll(event: any): void;
137
+ /**
138
+ * Handle pull-to-refresh
139
+ * Emits refresh event - parent should call event.target.complete()
140
+ */
141
+ handleRefresh(event: any): Promise<void>;
142
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobilePageMainComponent, never>;
143
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobilePageMainComponent, "ds-mobile-page-main", never, { "title": { "alias": "title"; "required": true; "isSignal": true; }; "headerTitle": { "alias": "headerTitle"; "required": false; "isSignal": true; }; "headerSubtitle": { "alias": "headerSubtitle"; "required": false; "isSignal": true; }; "avatarType": { "alias": "avatarType"; "required": false; "isSignal": true; }; "avatarInitials": { "alias": "avatarInitials"; "required": false; "isSignal": true; }; "avatarSrc": { "alias": "avatarSrc"; "required": false; "isSignal": true; }; "avatarIconName": { "alias": "avatarIconName"; "required": false; "isSignal": true; }; "showRefresh": { "alias": "showRefresh"; "required": false; "isSignal": true; }; "showCondensedHeader": { "alias": "showCondensedHeader"; "required": false; "isSignal": true; }; "scrollThreshold": { "alias": "scrollThreshold"; "required": false; "isSignal": true; }; "headerFadeDistance": { "alias": "headerFadeDistance"; "required": false; "isSignal": true; }; }, { "avatarClick": "avatarClick"; "refresh": "refresh"; "scroll": "scroll"; }, never, ["[header-content]", "*"], true, never>;
144
+ }
145
+
146
+ /**
147
+ * DsMobilePageDetailsComponent
148
+ *
149
+ * A mobile page layout for detail/drill-down pages with:
150
+ * - Back button header (mobile + desktop variants)
151
+ * - White background content area
152
+ * - Responsive padding
153
+ *
154
+ * @example
155
+ * ```html
156
+ * <!-- Simple detail page -->
157
+ * <ds-mobile-page-details
158
+ * title="Property Details"
159
+ * (back)="goBack()">
160
+ * <div class="page-content">
161
+ * <!-- Your content -->
162
+ * </div>
163
+ * </ds-mobile-page-details>
164
+ *
165
+ * <!-- With default back route -->
166
+ * <ds-mobile-page-details
167
+ * title="Invoice Details"
168
+ * backRoute="/invoices">
169
+ * <div class="page-content">
170
+ * <!-- Your content -->
171
+ * </div>
172
+ * </ds-mobile-page-details>
173
+ * ```
174
+ */
175
+ declare class DsMobilePageDetailsComponent extends MobilePageBase {
176
+ private navCtrl;
177
+ private elementRef;
178
+ title: _angular_core.InputSignal<string>;
179
+ backRoute: _angular_core.InputSignal<string>;
180
+ back: _angular_core.OutputEmitterRef<void>;
181
+ constructor(navCtrl: NavController, elementRef: ElementRef);
182
+ /**
183
+ * Handle back navigation
184
+ *
185
+ * By default, navigates using the provided backRoute or browser back.
186
+ * Parent components can listen to the (back) event to override this behavior.
187
+ *
188
+ * @example
189
+ * ```html
190
+ * <!-- Default behavior: uses backRoute or browser back -->
191
+ * <ds-mobile-page-details
192
+ * title="Details"
193
+ * backRoute="/home">
194
+ * </ds-mobile-page-details>
195
+ *
196
+ * <!-- Custom behavior: parent handles navigation -->
197
+ * <ds-mobile-page-details
198
+ * title="Details"
199
+ * (back)="customBackHandler()">
200
+ * </ds-mobile-page-details>
201
+ * ```
202
+ */
203
+ handleBack(): void;
204
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobilePageDetailsComponent, never>;
205
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobilePageDetailsComponent, "ds-mobile-page-details", never, { "title": { "alias": "title"; "required": true; "isSignal": true; }; "backRoute": { "alias": "backRoute"; "required": false; "isSignal": true; }; }, { "back": "back"; }, never, ["*"], true, never>;
206
+ }
207
+
208
+ /**
209
+ * DsMobileContentComponent
210
+ *
211
+ * Main content container for mobile pages with flexible layout options.
212
+ * Provides consistent spacing and layout patterns.
213
+ *
214
+ * @example
215
+ * ```html
216
+ * <!-- Default: stacked layout -->
217
+ * <ds-mobile-content>
218
+ * <ds-mobile-content-section>...</ds-mobile-content-section>
219
+ * <ds-mobile-content-section>...</ds-mobile-content-section>
220
+ * </ds-mobile-content>
221
+ *
222
+ * <!-- Grid layout -->
223
+ * <ds-mobile-content layout="grid-2">
224
+ * <ds-mobile-content-section>...</ds-mobile-content-section>
225
+ * <ds-mobile-content-section>...</ds-mobile-content-section>
226
+ * </ds-mobile-content>
227
+ * ```
228
+ */
229
+ declare class DsMobileContentComponent {
230
+ /**
231
+ * Layout mode for content sections
232
+ * - 'stacked' - Vertical stack with 32px gap (default)
233
+ * - 'grid-2' - 2 column grid
234
+ * - 'grid-3' - 3 column grid (stacks on mobile)
235
+ */
236
+ layout: _angular_core.InputSignal<"stacked" | "grid-2" | "grid-3">;
237
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileContentComponent, never>;
238
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobileContentComponent, "ds-mobile-content", never, { "layout": { "alias": "layout"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
239
+ }
240
+ /**
241
+ * DsMobileContentSectionComponent
242
+ *
243
+ * Section within mobile content with optional header.
244
+ *
245
+ * @example
246
+ * ```html
247
+ * <ds-mobile-content-section>
248
+ * <section-header width="half"></section-header>
249
+ * <content-row>
250
+ * <div class="grey-box"></div>
251
+ * </content-row>
252
+ * </ds-mobile-content-section>
253
+ * ```
254
+ */
255
+ declare class DsMobileContentSectionComponent {
256
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileContentSectionComponent, never>;
257
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobileContentSectionComponent, "ds-mobile-content-section", never, {}, {}, never, ["section-header", "*"], true, never>;
258
+ }
259
+ /**
260
+ * SectionHeaderComponent
261
+ *
262
+ * Semantic placeholder header for content sections.
263
+ * Used for prototyping/placeholders.
264
+ */
265
+ declare class SectionHeaderComponent {
266
+ /** Width of the header placeholder */
267
+ width: _angular_core.InputSignal<"full" | "half" | "third">;
268
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SectionHeaderComponent, never>;
269
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SectionHeaderComponent, "section-header", never, { "width": { "alias": "width"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
270
+ }
271
+ /**
272
+ * ContentRowComponent
273
+ *
274
+ * Horizontal row container for content items.
275
+ */
276
+ declare class ContentRowComponent {
277
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ContentRowComponent, never>;
278
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<ContentRowComponent, "content-row", never, {}, {}, never, ["*"], true, never>;
279
+ }
280
+
281
+ /**
282
+ * DsMobileHeaderContentComponent
283
+ *
284
+ * Container for header content tiles - displays tiles in a responsive grid.
285
+ * Used within the expandable header section of mobile pages to show
286
+ * summary information like property details, statistics, etc.
287
+ *
288
+ * @example
289
+ * ```html
290
+ * <ds-mobile-header-content header-content>
291
+ * <ds-mobile-header-content-tile>
292
+ * <tile-icon>
293
+ * <ds-icon name="remixHome4Line" />
294
+ * </tile-icon>
295
+ * <tile-content>
296
+ * <tile-label>Area</tile-label>
297
+ * <tile-value>120 m²</tile-value>
298
+ * </tile-content>
299
+ * </ds-mobile-header-content-tile>
300
+ * </ds-mobile-header-content>
301
+ * ```
302
+ */
303
+ declare class DsMobileHeaderContentComponent {
304
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileHeaderContentComponent, never>;
305
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobileHeaderContentComponent, "ds-mobile-header-content", never, {}, {}, never, ["ds-mobile-header-content-tile"], true, never>;
306
+ }
307
+ /**
308
+ * DsMobileHeaderContentTileComponent
309
+ *
310
+ * Individual tile for displaying summary information in the header.
311
+ * Styled with purple background to match the mobile header theme.
312
+ *
313
+ * Must contain:
314
+ * - `<tile-icon>` - Icon container (optional)
315
+ * - `<tile-content>` - Label and value container
316
+ *
317
+ * @example
318
+ * ```html
319
+ * <ds-mobile-header-content-tile>
320
+ * <tile-icon>
321
+ * <ds-icon name="remixHome4Line" size="20px" color="#DFE4FF" />
322
+ * </tile-icon>
323
+ * <tile-content>
324
+ * <tile-label>Rooms</tile-label>
325
+ * <tile-value>3 rooms</tile-value>
326
+ * </tile-content>
327
+ * </ds-mobile-header-content-tile>
328
+ * ```
329
+ */
330
+ declare class DsMobileHeaderContentTileComponent {
331
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileHeaderContentTileComponent, never>;
332
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobileHeaderContentTileComponent, "ds-mobile-header-content-tile", never, {}, {}, never, ["tile-icon", "tile-content"], true, never>;
333
+ }
334
+ /**
335
+ * TileIconComponent
336
+ *
337
+ * Semantic slot for tile icon with dark purple background.
338
+ * Use within `ds-mobile-header-content-tile`.
339
+ */
340
+ declare class TileIconComponent {
341
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TileIconComponent, never>;
342
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TileIconComponent, "tile-icon", never, {}, {}, never, ["*"], true, never>;
343
+ }
344
+ /**
345
+ * TileContentComponent
346
+ *
347
+ * Semantic slot for tile content containing label and value.
348
+ * Use within `ds-mobile-header-content-tile`.
349
+ *
350
+ * Contains:
351
+ * - `<tile-label>` - Small label text
352
+ * - `<tile-value>` - Large value text
353
+ */
354
+ declare class TileContentComponent {
355
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TileContentComponent, never>;
356
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TileContentComponent, "tile-content", never, {}, {}, never, ["tile-label", "tile-value"], true, never>;
357
+ }
358
+ /**
359
+ * TileLabelComponent
360
+ *
361
+ * Label text for tile content.
362
+ * Use within `tile-content` inside `ds-mobile-header-content-tile`.
363
+ */
364
+ declare class TileLabelComponent {
365
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TileLabelComponent, never>;
366
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TileLabelComponent, "tile-label", never, {}, {}, never, ["*"], true, never>;
367
+ }
368
+ /**
369
+ * TileValueComponent
370
+ *
371
+ * Value text for tile content.
372
+ * Use within `tile-content` inside `ds-mobile-header-content-tile`.
373
+ */
374
+ declare class TileValueComponent {
375
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TileValueComponent, never>;
376
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TileValueComponent, "tile-value", never, {}, {}, never, ["*"], true, never>;
377
+ }
378
+
379
+ /**
380
+ * DsMobilePostCardComponent
381
+ *
382
+ * Individual post card for community feed and post details.
383
+ * Displays user posts with avatar, content, media, and action buttons.
384
+ * Follows Threads-inspired design with clean layout and interactions.
385
+ *
386
+ * @example
387
+ * ```html
388
+ * <ds-mobile-post-card
389
+ * [authorName]="'John Doe'"
390
+ * [authorRole]="'Tenant'"
391
+ * [timestamp]="'2h ago'"
392
+ * [avatarInitials]="'JD'"
393
+ * [clickable]="true"
394
+ * (postClick)="openPost()">
395
+ *
396
+ * <post-content>
397
+ * <post-text>This is a sample post...</post-text>
398
+ * </post-content>
399
+ *
400
+ * <post-actions>
401
+ * <action-like [active]="true" count="42" />
402
+ * <action-comment count="12" />
403
+ * <action-share />
404
+ * </post-actions>
405
+ * </ds-mobile-post-card>
406
+ * ```
407
+ */
408
+ declare class DsMobilePostCardComponent {
409
+ /**
410
+ * Author's display name
411
+ */
412
+ authorName: _angular_core.InputSignal<string>;
413
+ /**
414
+ * Author's role (e.g., "Tenant", "Property Manager")
415
+ */
416
+ authorRole: _angular_core.InputSignal<string>;
417
+ /**
418
+ * Timestamp text (e.g., "2h ago", "1d ago")
419
+ */
420
+ timestamp: _angular_core.InputSignal<string>;
421
+ /**
422
+ * Avatar initials (for initials type)
423
+ */
424
+ avatarInitials: _angular_core.InputSignal<string>;
425
+ /**
426
+ * Avatar type
427
+ */
428
+ avatarType: _angular_core.InputSignal<"initials" | "photo" | "icon">;
429
+ /**
430
+ * Avatar photo source (for photo type)
431
+ */
432
+ avatarSrc: _angular_core.InputSignal<string>;
433
+ /**
434
+ * Icon name (for icon type avatars)
435
+ */
436
+ avatarIconName: _angular_core.InputSignal<string>;
437
+ /**
438
+ * Show badge on avatar (e.g., for property managers)
439
+ */
440
+ showBadge: _angular_core.InputSignal<boolean>;
441
+ /**
442
+ * Display variant
443
+ * - 'feed' - Standard feed display (default)
444
+ * - 'detail' - Full detail view
445
+ * - 'compact' - Compact display for nested/related posts
446
+ */
447
+ variant: _angular_core.InputSignal<"feed" | "detail" | "compact">;
448
+ /**
449
+ * Whether the post card is clickable
450
+ */
451
+ clickable: _angular_core.InputSignal<boolean>;
452
+ /**
453
+ * Emits when the post card is clicked (if clickable)
454
+ */
455
+ postClick: _angular_core.OutputEmitterRef<void>;
456
+ /**
457
+ * Emits when the comment button is clicked
458
+ */
459
+ commentClick: _angular_core.OutputEmitterRef<void>;
460
+ /**
461
+ * Emits when the post card is long-pressed
462
+ */
463
+ longPress: _angular_core.OutputEmitterRef<void>;
464
+ /**
465
+ * Long press tracking
466
+ */
467
+ private longPressTimer;
468
+ private longPressTriggered;
469
+ private touchStartX;
470
+ private touchStartY;
471
+ private readonly LONG_PRESS_DURATION;
472
+ private readonly MOVE_THRESHOLD;
473
+ handlePostClick(event: Event): void;
474
+ handleCommentClick(): void;
475
+ /**
476
+ * Handle touch start for long press detection
477
+ */
478
+ handleTouchStart(event: TouchEvent): void;
479
+ /**
480
+ * Handle touch end to clear long press timer
481
+ */
482
+ handleTouchEnd(event: TouchEvent): void;
483
+ /**
484
+ * Handle touch move to cancel long press if moved too much
485
+ */
486
+ handleTouchMove(event: TouchEvent): void;
487
+ /**
488
+ * Handle context menu (right-click on desktop) to trigger long press action
489
+ */
490
+ handleContextMenu(event: Event): void;
491
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobilePostCardComponent, never>;
492
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobilePostCardComponent, "ds-mobile-post-card", 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; }; "clickable": { "alias": "clickable"; "required": false; "isSignal": true; }; }, { "postClick": "postClick"; "commentClick": "commentClick"; "longPress": "longPress"; }, never, ["post-menu", "post-content", "post-actions"], true, never>;
493
+ }
494
+ /**
495
+ * PostContentComponent
496
+ *
497
+ * Main content section of the post.
498
+ *
499
+ * Contains:
500
+ * - `<post-text>` - Text content
501
+ * - `<post-media>` - Optional images/videos
502
+ * - `<post-attachments>` - Optional file attachments
503
+ */
504
+ declare class PostContentComponent {
505
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<PostContentComponent, never>;
506
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<PostContentComponent, "post-content", never, {}, {}, never, ["post-text", "post-media", "ds-mobile-inline-photo", "post-attachments"], true, never>;
507
+ }
508
+ /**
509
+ * PostTextComponent
510
+ *
511
+ * Text content of the post.
512
+ */
513
+ declare class PostTextComponent {
514
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<PostTextComponent, never>;
515
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<PostTextComponent, "post-text", never, {}, {}, never, ["*"], true, never>;
516
+ }
517
+ /**
518
+ * PostMediaComponent
519
+ *
520
+ * Media container for images/videos.
521
+ */
522
+ declare class PostMediaComponent {
523
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<PostMediaComponent, never>;
524
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<PostMediaComponent, "post-media", never, {}, {}, never, ["*"], true, never>;
525
+ }
526
+ /**
527
+ * PostAttachmentsComponent
528
+ *
529
+ * Container for file attachments, links, etc.
530
+ */
531
+ declare class PostAttachmentsComponent {
532
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<PostAttachmentsComponent, never>;
533
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<PostAttachmentsComponent, "post-attachments", never, {}, {}, never, ["*"], true, never>;
534
+ }
535
+ /**
536
+ * PostActionsComponent
537
+ *
538
+ * Action buttons container (like, comment, share).
539
+ *
540
+ * Contains:
541
+ * - `<action-like>` - Like button with count
542
+ * - `<action-comment>` - Comment button with count
543
+ * - `<action-share>` - Share button
544
+ */
545
+ declare class PostActionsComponent {
546
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<PostActionsComponent, never>;
547
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<PostActionsComponent, "post-actions", never, {}, {}, never, ["*"], true, never>;
548
+ }
549
+ /**
550
+ * ActionLikeComponent
551
+ *
552
+ * Like action button with count display and animated heart icon.
553
+ */
554
+ declare class ActionLikeComponent {
555
+ /**
556
+ * Whether the like is active (user has liked)
557
+ * Using model() for two-way binding
558
+ */
559
+ active: _angular_core.ModelSignal<boolean>;
560
+ /**
561
+ * Number of likes
562
+ * Using model() for two-way binding
563
+ */
564
+ count: _angular_core.ModelSignal<number>;
565
+ /**
566
+ * Emits when the like button is clicked
567
+ */
568
+ likeClick: _angular_core.OutputEmitterRef<{
569
+ active: boolean;
570
+ count: number;
571
+ }>;
572
+ /**
573
+ * Signal to control pulse animation
574
+ */
575
+ isPulsing: _angular_core.WritableSignal<boolean>;
576
+ handleClick(event: Event): Promise<void>;
577
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ActionLikeComponent, never>;
578
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<ActionLikeComponent, "action-like", never, { "active": { "alias": "active"; "required": false; "isSignal": true; }; "count": { "alias": "count"; "required": false; "isSignal": true; }; }, { "active": "activeChange"; "count": "countChange"; "likeClick": "likeClick"; }, never, never, true, never>;
579
+ }
580
+ /**
581
+ * ActionCommentComponent
582
+ *
583
+ * Comment action button with count display.
584
+ */
585
+ declare class ActionCommentComponent {
586
+ /**
587
+ * Number of comments
588
+ */
589
+ count: _angular_core.InputSignal<number>;
590
+ /**
591
+ * Emits when the comment button is clicked
592
+ */
593
+ commentClick: _angular_core.OutputEmitterRef<void>;
594
+ handleClick(event: Event): void;
595
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ActionCommentComponent, never>;
596
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<ActionCommentComponent, "action-comment", never, { "count": { "alias": "count"; "required": false; "isSignal": true; }; }, { "commentClick": "commentClick"; }, never, never, true, never>;
597
+ }
598
+
599
+ /**
600
+ * DsMobileCommentComponent
601
+ *
602
+ * Individual comment component for post discussions.
603
+ * Displays user comments with avatar, content, and like action.
604
+ *
605
+ * @example
606
+ * ```html
607
+ * <ds-mobile-comment
608
+ * [authorName]="'John Doe'"
609
+ * [authorRole]="'Tenant'"
610
+ * [timestamp]="'1h ago'"
611
+ * [avatarInitials]="'JD'"
612
+ * [content]="'Great post!'">
613
+ * </ds-mobile-comment>
614
+ * ```
615
+ */
616
+ declare class DsMobileCommentComponent {
617
+ /**
618
+ * Author's display name
619
+ */
620
+ authorName: _angular_core.InputSignal<string>;
621
+ /**
622
+ * Author's role (e.g., "Tenant", "Property Manager")
623
+ */
624
+ authorRole: _angular_core.InputSignal<string>;
625
+ /**
626
+ * Timestamp text (e.g., "1h ago", "2d ago")
627
+ */
628
+ timestamp: _angular_core.InputSignal<string>;
629
+ /**
630
+ * Comment content text
631
+ */
632
+ content: _angular_core.InputSignal<string>;
633
+ /**
634
+ * Avatar initials
635
+ */
636
+ avatarInitials: _angular_core.InputSignal<string>;
637
+ /**
638
+ * Avatar type
639
+ */
640
+ avatarType: _angular_core.InputSignal<"initials" | "photo" | "icon">;
641
+ /**
642
+ * Whether the comment is clickable
643
+ */
644
+ clickable: _angular_core.InputSignal<boolean>;
645
+ /**
646
+ * Whether this comment belongs to the current user
647
+ */
648
+ isOwnComment: _angular_core.InputSignal<boolean>;
649
+ /**
650
+ * Whether the comment is liked by current user
651
+ */
652
+ isLiked: _angular_core.ModelSignal<boolean>;
653
+ /**
654
+ * Number of likes
655
+ */
656
+ likeCount: _angular_core.ModelSignal<number>;
657
+ /**
658
+ * Signal to control pulse animation
659
+ */
660
+ isPulsing: _angular_core.WritableSignal<boolean>;
661
+ /**
662
+ * Computed property to format content with @mentions
663
+ */
664
+ formattedContent: _angular_core.Signal<string>;
665
+ /**
666
+ * Emits when the comment card is clicked (if clickable)
667
+ */
668
+ commentClick: _angular_core.OutputEmitterRef<void>;
669
+ /**
670
+ * Emits when reply is clicked
671
+ */
672
+ replyClick: _angular_core.OutputEmitterRef<void>;
673
+ /**
674
+ * Emits when edit is clicked
675
+ */
676
+ editClick: _angular_core.OutputEmitterRef<void>;
677
+ /**
678
+ * Emits when the comment is long-pressed
679
+ */
680
+ longPress: _angular_core.OutputEmitterRef<void>;
681
+ /**
682
+ * Long press tracking
683
+ */
684
+ private longPressTimer;
685
+ private longPressTriggered;
686
+ private touchStartX;
687
+ private touchStartY;
688
+ private readonly LONG_PRESS_DURATION;
689
+ private readonly MOVE_THRESHOLD;
690
+ handleCommentClick(event: Event): void;
691
+ toggleLike(): Promise<void>;
692
+ handleReply(): void;
693
+ handleEdit(): void;
694
+ /**
695
+ * Handle touch start for long press detection
696
+ */
697
+ handleTouchStart(event: TouchEvent): void;
698
+ /**
699
+ * Handle touch end to clear long press timer
700
+ */
701
+ handleTouchEnd(event: TouchEvent): void;
702
+ /**
703
+ * Handle touch move to cancel long press if moved too much
704
+ */
705
+ handleTouchMove(event: TouchEvent): void;
706
+ /**
707
+ * Handle context menu (right-click on desktop) to trigger long press action
708
+ */
709
+ handleContextMenu(event: Event): void;
710
+ /**
711
+ * Handle desktop more button click
712
+ * Stops propagation and triggers long press action
713
+ */
714
+ handleMoreButtonClick(event: Event): void;
715
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileCommentComponent, never>;
716
+ 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; }; }, { "isLiked": "isLikedChange"; "likeCount": "likeCountChange"; "commentClick": "commentClick"; "replyClick": "replyClick"; "editClick": "editClick"; "longPress": "longPress"; }, never, never, true, never>;
717
+ }
718
+
719
+ /**
720
+ * DsMobilePostComposerComponent
721
+ *
722
+ * A "fake" input composer for creating new posts in the community feed.
723
+ * Features a user avatar, placeholder input, and post button.
724
+ * Clicking opens the full post creation modal/page.
725
+ *
726
+ * @example
727
+ * ```html
728
+ * <ds-mobile-post-composer
729
+ * [avatarInitials]="'LM'"
730
+ * [avatarType]="'photo'"
731
+ * [avatarSrc]="'...'"
732
+ * (composerClick)="openPostCreator()">
733
+ * </ds-mobile-post-composer>
734
+ * ```
735
+ */
736
+ declare class DsMobilePostComposerComponent {
737
+ /**
738
+ * Avatar initials (for initials type)
739
+ */
740
+ avatarInitials: _angular_core.InputSignal<string>;
741
+ /**
742
+ * Avatar type
743
+ */
744
+ avatarType: _angular_core.InputSignal<"initials" | "photo" | "icon">;
745
+ /**
746
+ * Avatar photo source (for photo type)
747
+ */
748
+ avatarSrc: _angular_core.InputSignal<string>;
749
+ /**
750
+ * Icon name (for icon type avatars)
751
+ */
752
+ avatarIconName: _angular_core.InputSignal<string>;
753
+ /**
754
+ * Placeholder text for the input
755
+ */
756
+ placeholder: _angular_core.InputSignal<string>;
757
+ /**
758
+ * Text for the post button
759
+ */
760
+ buttonText: _angular_core.InputSignal<string>;
761
+ /**
762
+ * Emits when the composer is clicked
763
+ */
764
+ composerClick: _angular_core.OutputEmitterRef<void>;
765
+ handleClick(): void;
766
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobilePostComposerComponent, never>;
767
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobilePostComposerComponent, "ds-mobile-post-composer", never, { "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; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "buttonText": { "alias": "buttonText"; "required": false; "isSignal": true; }; }, { "composerClick": "composerClick"; }, never, never, true, never>;
768
+ }
769
+
770
+ /**
771
+ * DsMobileLongPressDirective
772
+ *
773
+ * A reusable directive for handling long press interactions on mobile devices.
774
+ * Provides haptic feedback and prevents long press when touching interactive elements.
775
+ *
776
+ * Features:
777
+ * - Configurable duration and movement threshold
778
+ * - Automatic haptic feedback (with fallback to navigator.vibrate)
779
+ * - Excludes interactive elements (buttons, links, inputs)
780
+ * - Handles touchmove cancellation
781
+ * - Context menu support (right-click on desktop)
782
+ *
783
+ * @example
784
+ * ```html
785
+ * <!-- Basic usage -->
786
+ * <div dsMobileLongPress (longPress)="handleLongPress()">
787
+ * Long press me
788
+ * </div>
789
+ *
790
+ * <!-- Custom duration and threshold -->
791
+ * <div
792
+ * dsMobileLongPress
793
+ * [longPressDuration]="800"
794
+ * [moveThreshold]="15"
795
+ * [excludeSelectors]="'button, a, .no-longpress'"
796
+ * (longPress)="showContextMenu()">
797
+ * Custom long press
798
+ * </div>
799
+ * ```
800
+ */
801
+ declare class DsMobileLongPressDirective implements OnDestroy {
802
+ /**
803
+ * Duration in milliseconds to trigger long press
804
+ * @default 500
805
+ */
806
+ longPressDuration: number;
807
+ /**
808
+ * Maximum movement in pixels before canceling long press
809
+ * @default 10
810
+ */
811
+ moveThreshold: number;
812
+ /**
813
+ * CSS selectors to exclude from long press detection
814
+ * @default 'button, a, input, select, textarea, [role="button"]'
815
+ */
816
+ excludeSelectors: string;
817
+ /**
818
+ * Haptic feedback style (Light, Medium, Heavy)
819
+ * @default ImpactStyle.Medium
820
+ */
821
+ hapticStyle: ImpactStyle;
822
+ /**
823
+ * Enable/disable haptic feedback
824
+ * @default true
825
+ */
826
+ enableHaptics: boolean;
827
+ /**
828
+ * Emits when long press is triggered
829
+ */
830
+ longPress: EventEmitter<void>;
831
+ /**
832
+ * Emits when long press starts (timer begins)
833
+ */
834
+ longPressStart: EventEmitter<void>;
835
+ /**
836
+ * Emits when long press is cancelled
837
+ */
838
+ longPressCancel: EventEmitter<void>;
839
+ private longPressTimer;
840
+ private longPressTriggered;
841
+ private touchStartX;
842
+ private touchStartY;
843
+ /**
844
+ * Handle touch start for long press detection
845
+ */
846
+ handleTouchStart(event: TouchEvent): void;
847
+ /**
848
+ * Handle touch end to clear long press timer
849
+ */
850
+ handleTouchEnd(event: TouchEvent): void;
851
+ /**
852
+ * Handle touch move to cancel long press if moved too much
853
+ */
854
+ handleTouchMove(event: TouchEvent): void;
855
+ /**
856
+ * Handle context menu (right-click on desktop) to trigger long press action
857
+ */
858
+ handleContextMenu(event: Event): void;
859
+ /**
860
+ * Trigger haptic feedback
861
+ */
862
+ private triggerHaptics;
863
+ /**
864
+ * Cleanup on destroy
865
+ */
866
+ ngOnDestroy(): void;
867
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileLongPressDirective, never>;
868
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DsMobileLongPressDirective, "[dsMobileLongPress]", never, { "longPressDuration": { "alias": "longPressDuration"; "required": false; }; "moveThreshold": { "alias": "moveThreshold"; "required": false; }; "excludeSelectors": { "alias": "excludeSelectors"; "required": false; }; "hapticStyle": { "alias": "hapticStyle"; "required": false; }; "enableHaptics": { "alias": "enableHaptics"; "required": false; }; }, { "longPress": "longPress"; "longPressStart": "longPressStart"; "longPressCancel": "longPressCancel"; }, never, never, true, never>;
869
+ }
870
+
871
+ /**
872
+ * DsMobileListItemComponent
873
+ *
874
+ * A versatile, reusable list item component for mobile applications.
875
+ * Supports both interactive and non-interactive modes with flexible content projection.
876
+ *
877
+ * Features:
878
+ * - Interactive mode with click and long-press support
879
+ * - Pseudo-element background extends 8px beyond bounds (no negative margins needed)
880
+ * - Flexible content slots (leading, main, trailing)
881
+ * - Optional structured inputs for common use cases (title, subtitle)
882
+ * - Accessibility features (focus states, ARIA attributes)
883
+ * - Disabled and loading states
884
+ *
885
+ * This component serves as the foundation for specialized list item types like posts,
886
+ * notifications, messages, contacts, and other list content.
887
+ *
888
+ * @example
889
+ * ```html
890
+ * <!-- Simple structured usage -->
891
+ * <ds-mobile-list-item
892
+ * title="Document Title"
893
+ * subtitle="Supporting text"
894
+ * [interactive]="true"
895
+ * (itemClick)="handleClick()">
896
+ *
897
+ * <ds-icon content-leading name="document" />
898
+ * </ds-mobile-list-item>
899
+ *
900
+ * <!-- Flexible custom usage -->
901
+ * <ds-mobile-list-item
902
+ * [interactive]="true"
903
+ * (itemClick)="handleClick()"
904
+ * (longPress)="showContextMenu()">
905
+ *
906
+ * <div content-leading>
907
+ * <ds-avatar initials="JD" />
908
+ * </div>
909
+ *
910
+ * <div content-main>
911
+ * <h3>Custom Content</h3>
912
+ * <p>Full control over layout and styling</p>
913
+ * </div>
914
+ *
915
+ * <button content-trailing (click)="handleAction($event)">
916
+ * Action
917
+ * </button>
918
+ * </ds-mobile-list-item>
919
+ *
920
+ * <!-- Non-interactive read-only -->
921
+ * <ds-mobile-list-item
922
+ * title="Read-only Item"
923
+ * subtitle="No interaction">
924
+ * <ds-icon content-leading name="info" />
925
+ * </ds-mobile-list-item>
926
+ * ```
927
+ */
928
+ declare class DsMobileListItemComponent {
929
+ private platformId;
930
+ /**
931
+ * Detect if viewport is desktop size
932
+ * Use viewport width for breakpoint detection (show button on tablet and above)
933
+ */
934
+ isDesktop: _angular_core.WritableSignal<boolean>;
935
+ constructor();
936
+ /**
937
+ * CSS size value for the leading content area (e.g., '32px', '40px', '48px')
938
+ * Defaults to '32px' for standard list item avatars/icons
939
+ */
940
+ leadingSize: _angular_core.InputSignal<string>;
941
+ /**
942
+ * Display variant
943
+ * - 'feed' - Standard feed display (default)
944
+ * - 'detail' - Full detail view
945
+ * - 'compact' - Compact display for nested/related items
946
+ */
947
+ variant: _angular_core.InputSignal<"feed" | "detail" | "compact">;
948
+ /**
949
+ * Whether the list item is interactive (clickable and long-pressable)
950
+ * When true, adds interactive background, cursor pointer, and touch handlers
951
+ */
952
+ interactive: _angular_core.InputSignal<boolean>;
953
+ /**
954
+ * Whether the list item is disabled
955
+ * Disables all interactions and reduces opacity
956
+ */
957
+ disabled: _angular_core.InputSignal<boolean>;
958
+ /**
959
+ * Whether the list item is in a loading state
960
+ * Disables interactions but maintains full opacity
961
+ */
962
+ loading: _angular_core.InputSignal<boolean>;
963
+ /**
964
+ * Enable long-press interaction when interactive is true
965
+ * Set to false to disable long-press but keep click
966
+ */
967
+ enableLongPress: _angular_core.InputSignal<boolean>;
968
+ /**
969
+ * Show "more actions" button on desktop for items with long-press enabled
970
+ * Only visible on desktop (hover: hover) and when enableLongPress is true
971
+ * Clicking this button triggers the same handler as long-press on mobile
972
+ * @default true
973
+ */
974
+ showDesktopMoreButton: _angular_core.InputSignal<boolean>;
975
+ /**
976
+ * Offset distance for the interactive background pseudo-element
977
+ * Extends the background beyond the content bounds
978
+ * @default '8px'
979
+ */
980
+ interactiveOffset: _angular_core.InputSignal<string>;
981
+ /**
982
+ * Optional structured title text
983
+ * Provides a simple way to add title without custom markup
984
+ */
985
+ title: _angular_core.InputSignal<string | undefined>;
986
+ /**
987
+ * Optional structured subtitle text
988
+ * Provides a simple way to add subtitle without custom markup
989
+ */
990
+ subtitle: _angular_core.InputSignal<string | undefined>;
991
+ /**
992
+ * Whether to show the divider line below the list item
993
+ * Automatically hidden on last-child and detail variant
994
+ * @default true
995
+ */
996
+ showDivider: _angular_core.InputSignal<boolean>;
997
+ /**
998
+ * Spacing around the divider (top and bottom padding)
999
+ * @default '4px'
1000
+ */
1001
+ dividerSpacing: _angular_core.InputSignal<string>;
1002
+ /**
1003
+ * Emits when the list item is clicked (if interactive and not disabled)
1004
+ */
1005
+ itemClick: _angular_core.OutputEmitterRef<void>;
1006
+ /**
1007
+ * Emits when the desktop more actions button is clicked
1008
+ * This is separate from longPress to give more control to parent components
1009
+ * Typically, you can use (longPress) for both mobile and desktop actions
1010
+ */
1011
+ moreButtonClick: _angular_core.OutputEmitterRef<Event>;
1012
+ /**
1013
+ * Track if long press was triggered to prevent click
1014
+ */
1015
+ private longPressTriggered;
1016
+ /**
1017
+ * Check if leading content slot has content
1018
+ * Always true to maintain consistent layout
1019
+ */
1020
+ hasLeadingContent: _angular_core.Signal<boolean>;
1021
+ /**
1022
+ * Check if trailing content slot has content
1023
+ * Always true to maintain consistent layout
1024
+ */
1025
+ hasTrailingContent: _angular_core.Signal<boolean>;
1026
+ /**
1027
+ * Handle click events
1028
+ */
1029
+ handleClick(event: Event): void;
1030
+ /**
1031
+ * Handle keyboard events (Enter/Space)
1032
+ */
1033
+ handleKeyDown(event: KeyboardEvent): void;
1034
+ /**
1035
+ * Handle long press events from the directive
1036
+ * Set the flag to prevent the subsequent click event
1037
+ */
1038
+ handleLongPress(): void;
1039
+ /**
1040
+ * Handle desktop more button click
1041
+ * Stops propagation to prevent triggering itemClick
1042
+ * Emits moreButtonClick for parent components to handle
1043
+ */
1044
+ handleMoreButtonClick(event: Event): void;
1045
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileListItemComponent, never>;
1046
+ 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; }; "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"; }; }]>;
1047
+ }
1048
+
1049
+ /**
1050
+ * DsMobileInteractiveListItemPostComponent
1051
+ *
1052
+ * Specialized interactive list item for displaying social media posts.
1053
+ * Built on top of ds-mobile-interactive-list-item base component.
1054
+ * Displays user posts with avatar, content, media, and action buttons.
1055
+ * Follows Threads-inspired design with clean layout and interactions.
1056
+ *
1057
+ * @example
1058
+ * ```html
1059
+ * <ds-mobile-interactive-list-item-post
1060
+ * [authorName]="'John Doe'"
1061
+ * [authorRole]="'Tenant'"
1062
+ * [timestamp]="'2h ago'"
1063
+ * [avatarInitials]="'JD'"
1064
+ * [clickable]="true"
1065
+ * (postClick)="openPost()">
1066
+ *
1067
+ * <post-content>
1068
+ * <post-text>This is a sample post...</post-text>
1069
+ * </post-content>
1070
+ *
1071
+ * <post-actions>
1072
+ * <action-like [active]="true" count="42" />
1073
+ * <action-comment count="12" />
1074
+ * </post-actions>
1075
+ * </ds-mobile-interactive-list-item-post>
1076
+ * ```
1077
+ */
1078
+ declare class DsMobileInteractiveListItemPostComponent {
1079
+ /**
1080
+ * Author's display name
1081
+ */
1082
+ authorName: _angular_core.InputSignal<string>;
1083
+ /**
1084
+ * Author's role (e.g., "Tenant", "Property Manager")
1085
+ */
1086
+ authorRole: _angular_core.InputSignal<string>;
1087
+ /**
1088
+ * Timestamp text (e.g., "2h ago", "1d ago")
1089
+ */
1090
+ timestamp: _angular_core.InputSignal<string>;
1091
+ /**
1092
+ * Avatar initials (for initials type)
1093
+ */
1094
+ avatarInitials: _angular_core.InputSignal<string>;
1095
+ /**
1096
+ * Avatar type
1097
+ */
1098
+ avatarType: _angular_core.InputSignal<"initials" | "photo" | "icon">;
1099
+ /**
1100
+ * Avatar photo source (for photo type)
1101
+ */
1102
+ avatarSrc: _angular_core.InputSignal<string>;
1103
+ /**
1104
+ * Icon name (for icon type avatars)
1105
+ */
1106
+ avatarIconName: _angular_core.InputSignal<string>;
1107
+ /**
1108
+ * Show badge on avatar (e.g., for property managers)
1109
+ */
1110
+ showBadge: _angular_core.InputSignal<boolean>;
1111
+ /**
1112
+ * Display variant
1113
+ * - 'feed' - Standard feed display (default)
1114
+ * - 'detail' - Full detail view
1115
+ * - 'compact' - Compact display for nested/related posts
1116
+ */
1117
+ variant: _angular_core.InputSignal<"feed" | "detail" | "compact">;
1118
+ /**
1119
+ * Whether the post card is clickable
1120
+ */
1121
+ clickable: _angular_core.InputSignal<boolean>;
1122
+ /**
1123
+ * Emits when the post card is clicked (if clickable)
1124
+ */
1125
+ postClick: _angular_core.OutputEmitterRef<void>;
1126
+ /**
1127
+ * Emits when the comment button is clicked
1128
+ */
1129
+ commentClick: _angular_core.OutputEmitterRef<void>;
1130
+ /**
1131
+ * Emits when the post card is long-pressed
1132
+ */
1133
+ longPress: _angular_core.OutputEmitterRef<void>;
1134
+ handlePostClick(): void;
1135
+ handleCommentClick(): void;
1136
+ handleLongPress(): void;
1137
+ handleMoreButtonClick(event: Event): void;
1138
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileInteractiveListItemPostComponent, never>;
1139
+ 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; }; "clickable": { "alias": "clickable"; "required": false; "isSignal": true; }; }, { "postClick": "postClick"; "commentClick": "commentClick"; "longPress": "longPress"; }, never, ["post-menu", "post-content", "post-actions"], true, never>;
1140
+ }
1141
+
1142
+ /**
1143
+ * PostPdfAttachmentComponent
1144
+ *
1145
+ * PDF file attachment display for posts.
1146
+ * Shows PDF info card with icon, filename, and file size.
1147
+ * Emits click event to open PDF in viewer.
1148
+ */
1149
+ declare class PostPdfAttachmentComponent {
1150
+ /**
1151
+ * PDF file name
1152
+ */
1153
+ fileName: _angular_core.InputSignal<string>;
1154
+ /**
1155
+ * File size display (e.g., "1.2 MB")
1156
+ */
1157
+ fileSize: _angular_core.InputSignal<string>;
1158
+ /**
1159
+ * Emits when the PDF attachment is clicked
1160
+ */
1161
+ pdfClick: _angular_core.OutputEmitterRef<void>;
1162
+ handleClick(event: Event): void;
1163
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<PostPdfAttachmentComponent, never>;
1164
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<PostPdfAttachmentComponent, "post-pdf-attachment", never, { "fileName": { "alias": "fileName"; "required": false; "isSignal": true; }; "fileSize": { "alias": "fileSize"; "required": false; "isSignal": true; }; }, { "pdfClick": "pdfClick"; }, never, never, true, never>;
1165
+ }
1166
+
1167
+ /**
1168
+ * DsMobileInteractiveListItemInquiryComponent
1169
+ *
1170
+ * Specialized interactive list item for displaying inquiries/tickets.
1171
+ * Built on top of ds-mobile-interactive-list-item base component.
1172
+ * Displays inquiry title, description, status, and timestamp.
1173
+ *
1174
+ * @example
1175
+ * ```html
1176
+ * <ds-mobile-interactive-list-item-inquiry
1177
+ * [title]="'Tumble dryer is not working'"
1178
+ * [description]="'For the past three days, I have been experiencing...'"
1179
+ * [status]="'open'"
1180
+ * [timestamp]="'12 days ago'"
1181
+ * [iconName]="'remixCalendarLine'"
1182
+ * [clickable]="true"
1183
+ * (inquiryClick)="openInquiry()">
1184
+ * </ds-mobile-interactive-list-item-inquiry>
1185
+ * ```
1186
+ */
1187
+ declare class DsMobileInteractiveListItemInquiryComponent {
1188
+ /**
1189
+ * Inquiry title
1190
+ */
1191
+ title: _angular_core.InputSignal<string>;
1192
+ /**
1193
+ * Inquiry description/preview text
1194
+ */
1195
+ description: _angular_core.InputSignal<string>;
1196
+ /**
1197
+ * Inquiry status
1198
+ */
1199
+ status: _angular_core.InputSignal<"open" | "closed">;
1200
+ /**
1201
+ * Status label (defaults to capitalized status)
1202
+ */
1203
+ statusLabel: _angular_core.InputSignal<string>;
1204
+ /**
1205
+ * Timestamp text (e.g., "12 days ago", "2 months ago")
1206
+ */
1207
+ timestamp: _angular_core.InputSignal<string>;
1208
+ /**
1209
+ * Icon name for the leading icon
1210
+ */
1211
+ iconName: _angular_core.InputSignal<string>;
1212
+ /**
1213
+ * Icon color
1214
+ */
1215
+ iconColor: _angular_core.InputSignal<string>;
1216
+ /**
1217
+ * Display variant
1218
+ * - 'feed' - Standard feed display (default)
1219
+ * - 'detail' - Full detail view
1220
+ * - 'compact' - Compact display
1221
+ */
1222
+ variant: _angular_core.InputSignal<"feed" | "detail" | "compact">;
1223
+ /**
1224
+ * Whether the inquiry item is clickable
1225
+ */
1226
+ clickable: _angular_core.InputSignal<boolean>;
1227
+ /**
1228
+ * Whether to show chevron icon
1229
+ */
1230
+ showChevron: _angular_core.InputSignal<boolean>;
1231
+ /**
1232
+ * Emits when the inquiry item is clicked (if clickable)
1233
+ */
1234
+ inquiryClick: _angular_core.OutputEmitterRef<void>;
1235
+ /**
1236
+ * Emits when the inquiry item is long-pressed
1237
+ */
1238
+ longPress: _angular_core.OutputEmitterRef<void>;
1239
+ /**
1240
+ * Get computed status label
1241
+ */
1242
+ computedStatusLabel(): string;
1243
+ handleInquiryClick(): void;
1244
+ handleLongPress(): void;
1245
+ handleMoreButtonClick(event: Event): void;
1246
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileInteractiveListItemInquiryComponent, never>;
1247
+ 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; }; "clickable": { "alias": "clickable"; "required": false; "isSignal": true; }; "showChevron": { "alias": "showChevron"; "required": false; "isSignal": true; }; }, { "inquiryClick": "inquiryClick"; "longPress": "longPress"; }, never, never, true, never>;
1248
+ }
1249
+
1250
+ /**
1251
+ * DsMobileInteractiveListItemMessageComponent
1252
+ *
1253
+ * Specialized interactive list item for displaying message threads.
1254
+ * Built on top of ds-mobile-interactive-list-item base component.
1255
+ * Displays message preview with sender info - simplified version without actions.
1256
+ *
1257
+ * @example
1258
+ * ```html
1259
+ * <ds-mobile-interactive-list-item-message
1260
+ * [senderName]="'John Doe'"
1261
+ * [senderRole]="'Tenant'"
1262
+ * [timestamp]="'2h ago'"
1263
+ * [message]="'Hey, when is the maintenance scheduled?'"
1264
+ * [avatarInitials]="'JD'"
1265
+ * [unread]="true"
1266
+ * [clickable]="true"
1267
+ * (messageClick)="openThread()">
1268
+ * </ds-mobile-interactive-list-item-message>
1269
+ * ```
1270
+ */
1271
+ declare class DsMobileInteractiveListItemMessageComponent {
1272
+ /**
1273
+ * Sender's display name
1274
+ */
1275
+ senderName: _angular_core.InputSignal<string>;
1276
+ /**
1277
+ * Sender's role (e.g., "Tenant", "Property Manager")
1278
+ */
1279
+ senderRole: _angular_core.InputSignal<string>;
1280
+ /**
1281
+ * Message preview text
1282
+ */
1283
+ message: _angular_core.InputSignal<string>;
1284
+ /**
1285
+ * Avatar initials (for initials type)
1286
+ */
1287
+ avatarInitials: _angular_core.InputSignal<string>;
1288
+ /**
1289
+ * Avatar type
1290
+ */
1291
+ avatarType: _angular_core.InputSignal<"initials" | "photo" | "icon">;
1292
+ /**
1293
+ * Avatar photo source (for photo type)
1294
+ */
1295
+ avatarSrc: _angular_core.InputSignal<string>;
1296
+ /**
1297
+ * Whether the message is unread
1298
+ */
1299
+ unread: _angular_core.InputSignal<boolean>;
1300
+ /**
1301
+ * Whether the message item is clickable
1302
+ */
1303
+ clickable: _angular_core.InputSignal<boolean>;
1304
+ /**
1305
+ * Emits when the message item is clicked
1306
+ */
1307
+ messageClick: _angular_core.OutputEmitterRef<void>;
1308
+ /**
1309
+ * Emits when the message item is long-pressed
1310
+ */
1311
+ longPress: _angular_core.OutputEmitterRef<void>;
1312
+ handleMessageClick(): void;
1313
+ handleLongPress(): void;
1314
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileInteractiveListItemMessageComponent, never>;
1315
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobileInteractiveListItemMessageComponent, "ds-mobile-interactive-list-item-message", never, { "senderName": { "alias": "senderName"; "required": true; "isSignal": true; }; "senderRole": { "alias": "senderRole"; "required": true; "isSignal": true; }; "message": { "alias": "message"; "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; }; "unread": { "alias": "unread"; "required": false; "isSignal": true; }; "clickable": { "alias": "clickable"; "required": false; "isSignal": true; }; }, { "messageClick": "messageClick"; "longPress": "longPress"; }, never, never, true, never>;
1316
+ }
1317
+
1318
+ /**
1319
+ * DsMobileContactListItemComponent
1320
+ *
1321
+ * Specialized interactive component for displaying contacts.
1322
+ * Displays contact name with avatar initials and metadata (person name + phone number).
1323
+ * Similar styling to file attachments with rounded corners and hover states.
1324
+ *
1325
+ * @example
1326
+ * ```html
1327
+ * <ds-mobile-contact-list-item
1328
+ * [name]="'Mortensen & Søn ApS'"
1329
+ * [initials]="'M'"
1330
+ * [contactPerson]="'John Mortensen'"
1331
+ * [phoneNumber]="'+45 12 34 56 78'"
1332
+ * [clickable]="true"
1333
+ * (contactClick)="openContact()">
1334
+ * </ds-mobile-contact-list-item>
1335
+ * ```
1336
+ */
1337
+ declare class DsMobileContactListItemComponent {
1338
+ /**
1339
+ * Contact/company name
1340
+ */
1341
+ name: _angular_core.InputSignal<string>;
1342
+ /**
1343
+ * Avatar initials (usually 1-2 letters)
1344
+ */
1345
+ initials: _angular_core.InputSignal<string>;
1346
+ /**
1347
+ * Contact person name (optional)
1348
+ */
1349
+ contactPerson: _angular_core.InputSignal<string>;
1350
+ /**
1351
+ * Phone number (optional)
1352
+ */
1353
+ phoneNumber: _angular_core.InputSignal<string>;
1354
+ /**
1355
+ * Whether the contact item is clickable
1356
+ */
1357
+ clickable: _angular_core.InputSignal<boolean>;
1358
+ /**
1359
+ * Whether to show chevron icon
1360
+ */
1361
+ showChevron: _angular_core.InputSignal<boolean>;
1362
+ /**
1363
+ * Emits when the contact item is clicked (if clickable)
1364
+ */
1365
+ contactClick: _angular_core.OutputEmitterRef<void>;
1366
+ handleContactClick(): void;
1367
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileContactListItemComponent, never>;
1368
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobileContactListItemComponent, "ds-mobile-contact-list-item", never, { "name": { "alias": "name"; "required": true; "isSignal": true; }; "initials": { "alias": "initials"; "required": true; "isSignal": true; }; "contactPerson": { "alias": "contactPerson"; "required": false; "isSignal": true; }; "phoneNumber": { "alias": "phoneNumber"; "required": false; "isSignal": true; }; "clickable": { "alias": "clickable"; "required": false; "isSignal": true; }; "showChevron": { "alias": "showChevron"; "required": false; "isSignal": true; }; }, { "contactClick": "contactClick"; }, never, never, true, never>;
1369
+ }
1370
+
1371
+ interface TabConfig$2 {
1372
+ id: string;
1373
+ label: string;
1374
+ route: string;
1375
+ icon: string;
1376
+ iconActive: string;
1377
+ }
1378
+ type HeaderVariant = 'home' | 'simple' | 'back' | 'none';
1379
+ /**
1380
+ * DsMobileAppLayoutComponent
1381
+ *
1382
+ * A complete mobile application shell component based on actual mobile page patterns.
1383
+ * Provides tab navigation, flexible headers, and mobile-optimized layout.
1384
+ *
1385
+ * Features:
1386
+ * - Tab bar navigation with active state
1387
+ * - Multiple header variants (home with logomark, simple title, back button)
1388
+ * - Pull-to-refresh support
1389
+ * - Purple brand background with content wrapper
1390
+ * - iOS safe area support
1391
+ *
1392
+ * @example
1393
+ * ```html
1394
+ * <ds-mobile-app-layout
1395
+ * [showTabBar]="true"
1396
+ * [tabs]="tabsConfig"
1397
+ * [headerVariant]="'home'"
1398
+ * [avatarInitials]="'JD'"
1399
+ * />
1400
+ * ```
1401
+ */
1402
+ declare class DsMobileAppLayoutComponent implements AfterViewInit {
1403
+ private router;
1404
+ private elementRef;
1405
+ private breakpointObserver;
1406
+ ionContent: IonContent;
1407
+ private platform;
1408
+ isNativePlatform: _angular_core.Signal<boolean>;
1409
+ headerVariant: _angular_core.InputSignal<HeaderVariant>;
1410
+ pageTitle: _angular_core.InputSignal<string>;
1411
+ showBackButton: _angular_core.InputSignal<boolean>;
1412
+ showPullToRefresh: _angular_core.InputSignal<boolean>;
1413
+ showTabBar: _angular_core.InputSignal<boolean>;
1414
+ tabs: _angular_core.InputSignal<TabConfig$2[]>;
1415
+ avatarType: _angular_core.InputSignal<"initials" | "photo" | "icon">;
1416
+ avatarInitials: _angular_core.InputSignal<string>;
1417
+ avatarSrc: _angular_core.InputSignal<string>;
1418
+ avatarIconName: _angular_core.InputSignal<string>;
1419
+ backClick: _angular_core.OutputEmitterRef<void>;
1420
+ refresh: _angular_core.OutputEmitterRef<any>;
1421
+ avatarClick: _angular_core.OutputEmitterRef<void>;
1422
+ scroll: _angular_core.OutputEmitterRef<any>;
1423
+ private scrollY;
1424
+ activeTab: _angular_core.WritableSignal<string>;
1425
+ isDesktop: _angular_core.WritableSignal<boolean>;
1426
+ constructor(router: Router, elementRef: ElementRef, breakpointObserver: BreakpointObserver);
1427
+ ngAfterViewInit(): void;
1428
+ handleScroll(event: any): void;
1429
+ handleRefresh(event: any): Promise<void>;
1430
+ handleBackClick(): void;
1431
+ handleAvatarClick(): void;
1432
+ navigateToTab(route: string): void;
1433
+ private ensureScrollable;
1434
+ isTabActive(tabId: string): boolean;
1435
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileAppLayoutComponent, never>;
1436
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobileAppLayoutComponent, "ds-mobile-app-layout", never, { "headerVariant": { "alias": "headerVariant"; "required": false; "isSignal": true; }; "pageTitle": { "alias": "pageTitle"; "required": false; "isSignal": true; }; "showBackButton": { "alias": "showBackButton"; "required": false; "isSignal": true; }; "showPullToRefresh": { "alias": "showPullToRefresh"; "required": false; "isSignal": true; }; "showTabBar": { "alias": "showTabBar"; "required": false; "isSignal": true; }; "tabs": { "alias": "tabs"; "required": false; "isSignal": true; }; "avatarType": { "alias": "avatarType"; "required": false; "isSignal": true; }; "avatarInitials": { "alias": "avatarInitials"; "required": false; "isSignal": true; }; "avatarSrc": { "alias": "avatarSrc"; "required": false; "isSignal": true; }; "avatarIconName": { "alias": "avatarIconName"; "required": false; "isSignal": true; }; }, { "backClick": "backClick"; "refresh": "refresh"; "avatarClick": "avatarClick"; "scroll": "scroll"; }, never, ["*"], true, never>;
1437
+ }
1438
+
1439
+ interface TabConfig$1 {
1440
+ id: string;
1441
+ label: string;
1442
+ route: string;
1443
+ icon: string;
1444
+ iconActive: string;
1445
+ }
1446
+ /**
1447
+ * DsMobileTabsComponent
1448
+ *
1449
+ * Responsive tab navigation that adapts from mobile to desktop:
1450
+ * - Mobile (< 768px): Bottom tab bar with icons + labels
1451
+ * - Desktop (≥ 768px): Top navigation bar with logo, tabs, and avatar
1452
+ *
1453
+ * Wraps ion-tabs to maintain native routing functionality while
1454
+ * providing a responsive navigation experience with branding.
1455
+ *
1456
+ * @example
1457
+ * ```html
1458
+ * <ds-mobile-tabs
1459
+ * [tabs]="tabsConfig"
1460
+ * [avatarInitials]="'JD'"
1461
+ * (avatarClick)="handleAvatarClick()"
1462
+ * />
1463
+ * ```
1464
+ */
1465
+ declare class DsMobileTabsComponent implements OnInit, AfterViewInit {
1466
+ private elementRef;
1467
+ tabs: TabConfig$1[];
1468
+ avatarType: 'initials' | 'photo' | 'icon';
1469
+ avatarInitials: string;
1470
+ avatarSrc: string;
1471
+ avatarIconName: string;
1472
+ avatarClick: EventEmitter<void>;
1473
+ activeTab: _angular_core.WritableSignal<string>;
1474
+ isDesktop: _angular_core.WritableSignal<boolean>;
1475
+ private mutationObserver?;
1476
+ constructor(elementRef: ElementRef);
1477
+ ngOnInit(): void;
1478
+ ngAfterViewInit(): void;
1479
+ ngOnDestroy(): void;
1480
+ private setupTitleRemovalObserver;
1481
+ private removeTitleAttributes;
1482
+ trackByTabId(index: number, tab: TabConfig$1): string;
1483
+ isTabActive(tabId: string): boolean;
1484
+ handleAvatarClick(): void;
1485
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileTabsComponent, never>;
1486
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobileTabsComponent, "ds-mobile-tabs", never, { "tabs": { "alias": "tabs"; "required": false; }; "avatarType": { "alias": "avatarType"; "required": false; }; "avatarInitials": { "alias": "avatarInitials"; "required": false; }; "avatarSrc": { "alias": "avatarSrc"; "required": false; }; "avatarIconName": { "alias": "avatarIconName"; "required": false; }; }, { "avatarClick": "avatarClick"; }, never, never, true, never>;
1487
+ }
1488
+
1489
+ interface ActionResult {
1490
+ action: string;
1491
+ }
1492
+ interface ActionItem {
1493
+ action: string;
1494
+ title: string;
1495
+ icon: string;
1496
+ destructive?: boolean;
1497
+ }
1498
+ interface ActionGroup {
1499
+ actions: ActionItem[];
1500
+ }
1501
+ /**
1502
+ * DsMobileActionsBottomSheetComponent
1503
+ *
1504
+ * Generic bottom sheet for displaying action lists.
1505
+ * Supports custom action groups or preset content actions (posts/comments).
1506
+ * Action groups are automatically separated by full-width dividers.
1507
+ *
1508
+ * @example Custom actions with auto-height (recommended to avoid cropping)
1509
+ * ```typescript
1510
+ * const sheet = await this.modalController.create({
1511
+ * component: DsMobileActionsBottomSheetComponent,
1512
+ * componentProps: {
1513
+ * customActionGroups: [
1514
+ * {
1515
+ * actions: [
1516
+ * { action: 'profile', title: 'Min profil', icon: 'remixUser3Line' },
1517
+ * { action: 'settings', title: 'Indstillinger', icon: 'remixSettings3Line' }
1518
+ * ]
1519
+ * },
1520
+ * {
1521
+ * actions: [
1522
+ * { action: 'logout', title: 'Log ud', icon: 'remixLogoutBoxLine', destructive: true }
1523
+ * ]
1524
+ * }
1525
+ * ]
1526
+ * },
1527
+ * breakpoints: [0, 1],
1528
+ * initialBreakpoint: 1,
1529
+ * handle: true,
1530
+ * cssClass: 'auto-height'
1531
+ * });
1532
+ *
1533
+ * const result = await sheet.onWillDismiss();
1534
+ * if (result.data?.action) {
1535
+ * // Handle the action
1536
+ * }
1537
+ * ```
1538
+ *
1539
+ * @example Preset content actions
1540
+ * ```typescript
1541
+ * const sheet = await this.modalController.create({
1542
+ * component: DsMobileActionsBottomSheetComponent,
1543
+ * componentProps: {
1544
+ * isOwnContent: false
1545
+ * },
1546
+ * breakpoints: [0, 1],
1547
+ * initialBreakpoint: 1,
1548
+ * handle: true,
1549
+ * cssClass: 'auto-height'
1550
+ * });
1551
+ * ```
1552
+ */
1553
+ declare class DsMobileActionsBottomSheetComponent {
1554
+ private modalController;
1555
+ /**
1556
+ * Custom action groups to display (overrides isOwnContent)
1557
+ */
1558
+ customActionGroups?: ActionGroup[];
1559
+ /**
1560
+ * Whether this content belongs to the current user (for preset content actions)
1561
+ */
1562
+ isOwnContent: boolean;
1563
+ /**
1564
+ * Computed action groups - uses custom groups if provided, otherwise falls back to preset content actions
1565
+ */
1566
+ actionGroups: _angular_core.Signal<ActionGroup[]>;
1567
+ constructor(modalController: ModalController);
1568
+ /**
1569
+ * Handle action selection and dismiss with result
1570
+ */
1571
+ selectAction(action: string): void;
1572
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileActionsBottomSheetComponent, never>;
1573
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobileActionsBottomSheetComponent, "ds-mobile-actions-bottom-sheet", never, { "customActionGroups": { "alias": "customActionGroups"; "required": false; }; "isOwnContent": { "alias": "isOwnContent"; "required": false; }; }, {}, never, never, true, never>;
1574
+ }
1575
+
1576
+ /**
1577
+ * Configuration options for the bottom sheet modal
1578
+ */
1579
+ interface BottomSheetOptions {
1580
+ /** The component to display in the bottom sheet */
1581
+ component: any;
1582
+ /** Component props to pass to the modal content */
1583
+ componentProps?: {
1584
+ [key: string]: any;
1585
+ };
1586
+ /** Breakpoints for the bottom sheet (0-1 values representing percentage of screen) */
1587
+ breakpoints?: number[];
1588
+ /** Initial breakpoint to open the sheet at */
1589
+ initialBreakpoint?: number;
1590
+ /** Show/hide the drag handle */
1591
+ handle?: boolean;
1592
+ /** Custom CSS class for styling */
1593
+ cssClass?: string | string[];
1594
+ /** Whether backdrop dismisses the modal */
1595
+ backdropDismiss?: boolean;
1596
+ /** Backdrop opacity (0-1) */
1597
+ backdropOpacity?: number;
1598
+ /** Enable backdrop blur effect */
1599
+ backdropBlur?: boolean;
1600
+ /** Keyboard close behavior */
1601
+ keyboardClose?: boolean;
1602
+ /** Auto-height mode: sheet sizes to content instead of using fixed breakpoints */
1603
+ autoHeight?: boolean;
1604
+ }
1605
+ /**
1606
+ * DsMobileBottomSheetService
1607
+ *
1608
+ * Service for creating and managing Ionic 6 bottom sheet modals.
1609
+ * Based on the Ionic blog article: https://ionic.io/blog/5-examples-of-the-new-ionic-6-bottom-sheet-modal
1610
+ *
1611
+ * Features:
1612
+ * - Multiple breakpoints for snap-to positions
1613
+ * - Customizable initial height
1614
+ * - Optional drag handle
1615
+ * - Backdrop blur effect
1616
+ * - Custom styling support
1617
+ *
1618
+ * @example
1619
+ * ```typescript
1620
+ * constructor(private bottomSheet: DsMobileBottomSheetService) {}
1621
+ *
1622
+ * async openSheet() {
1623
+ * const sheet = await this.bottomSheet.create({
1624
+ * component: PostCreateComponent,
1625
+ * breakpoints: [0, 0.5, 0.9],
1626
+ * initialBreakpoint: 0.5,
1627
+ * handle: true
1628
+ * });
1629
+ *
1630
+ * const result = await sheet.onWillDismiss();
1631
+ * console.log('Sheet dismissed with:', result.data);
1632
+ * }
1633
+ * ```
1634
+ */
1635
+ declare class DsMobileBottomSheetService {
1636
+ private modalController;
1637
+ constructor(modalController: ModalController);
1638
+ /**
1639
+ * Create and present a bottom sheet modal
1640
+ *
1641
+ * @param options Configuration options for the bottom sheet
1642
+ * @returns Promise that resolves to the modal instance
1643
+ */
1644
+ create(options: BottomSheetOptions): Promise<HTMLIonModalElement>;
1645
+ /**
1646
+ * Dismiss all open modals
1647
+ */
1648
+ dismiss(data?: any, role?: string): Promise<boolean>;
1649
+ /**
1650
+ * Get the top-most modal overlay
1651
+ */
1652
+ getTop(): Promise<HTMLIonModalElement | undefined>;
1653
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileBottomSheetService, never>;
1654
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<DsMobileBottomSheetService>;
1655
+ }
1656
+
1657
+ /**
1658
+ * DsMobilePostCreateBottomSheetComponent
1659
+ *
1660
+ * Bottom sheet modal for creating new posts in the community feed.
1661
+ * This is the modal content that gets displayed in the bottom sheet.
1662
+ * Features Threads-inspired interface with rich text editing capabilities.
1663
+ *
1664
+ * Auto-focuses the textarea and brings up the keyboard when opened.
1665
+ *
1666
+ * Usage: Use with DsMobileBottomSheetService to present as a bottom sheet
1667
+ */
1668
+ declare class DsMobilePostCreateBottomSheetComponent implements AfterViewInit, OnInit {
1669
+ private modalController;
1670
+ private elementRef;
1671
+ textareaInput?: ElementRef<HTMLTextAreaElement>;
1672
+ fileInput?: ElementRef<HTMLInputElement>;
1673
+ autoFocus: boolean;
1674
+ isReadonly: boolean;
1675
+ isEditMode: boolean;
1676
+ postId?: string;
1677
+ initialContent: string;
1678
+ postContent: string;
1679
+ selectedImages: _angular_core.WritableSignal<string[]>;
1680
+ username: _angular_core.WritableSignal<string>;
1681
+ placeholder: _angular_core.WritableSignal<string>;
1682
+ modalTitle: _angular_core.WritableSignal<string>;
1683
+ submitButtonLabel: _angular_core.WritableSignal<string>;
1684
+ constructor(modalController: ModalController, elementRef: ElementRef);
1685
+ /**
1686
+ * Ensure toolbar doesn't have unnecessary padding
1687
+ * Modal is already positioned below status bar, so no extra safe area needed
1688
+ */
1689
+ private applySafeAreaToToolbar;
1690
+ ngOnInit(): void;
1691
+ ngAfterViewInit(): void;
1692
+ /**
1693
+ * Ionic lifecycle hook - called when modal enters view
1694
+ * At 95% height, this acts more like a page than a modal
1695
+ * which might allow keyboard to open
1696
+ */
1697
+ ionViewDidEnter(): void;
1698
+ handleFocus(): void;
1699
+ handleInput(): void;
1700
+ /**
1701
+ * Auto-resize textarea based on content
1702
+ */
1703
+ private resizeTextarea;
1704
+ canPost(): boolean;
1705
+ handleCancel(): Promise<void>;
1706
+ handlePost(): Promise<void>;
1707
+ handleAddImage(): Promise<void>;
1708
+ /**
1709
+ * Restore StatusBar configuration (background task)
1710
+ * Safe area padding is now handled preventively via applySafeAreaToToolbar()
1711
+ */
1712
+ private restoreStatusBar;
1713
+ handleRemoveImage(index: number): void;
1714
+ handleAddAttachment(): void;
1715
+ handleFileSelect(event: Event): void;
1716
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobilePostCreateBottomSheetComponent, never>;
1717
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobilePostCreateBottomSheetComponent, "ds-mobile-post-create-bottom-sheet", never, {}, {}, never, never, true, never>;
1718
+ }
1719
+
1720
+ /**
1721
+ * Media file types supported by the lightbox
1722
+ */
1723
+ type LightboxMediaType = 'image' | 'pdf';
1724
+ /**
1725
+ * Base media file interface
1726
+ */
1727
+ interface LightboxMediaFile {
1728
+ /** File source URL */
1729
+ src: string;
1730
+ /** Media type - determines which viewer to use */
1731
+ type: LightboxMediaType;
1732
+ /** File title */
1733
+ title?: string;
1734
+ /** File description */
1735
+ description?: string;
1736
+ }
1737
+ /**
1738
+ * Image data for lightbox display
1739
+ */
1740
+ interface LightboxImage extends LightboxMediaFile {
1741
+ type: 'image';
1742
+ /** Alt text for accessibility */
1743
+ alt?: string;
1744
+ /** Thumbnail URL for faster loading (optional) */
1745
+ thumbnail?: string;
1746
+ /** Whether the image is liked */
1747
+ isLiked?: boolean;
1748
+ /** Number of likes */
1749
+ likeCount?: number;
1750
+ /** Number of comments */
1751
+ commentCount?: number;
1752
+ }
1753
+ /**
1754
+ * PDF document data for lightbox display
1755
+ */
1756
+ interface LightboxPdf extends LightboxMediaFile {
1757
+ type: 'pdf';
1758
+ /** File size in bytes (optional, for display) */
1759
+ fileSize?: number;
1760
+ /** Number of pages (optional, for display) */
1761
+ pageCount?: number;
1762
+ }
1763
+ /**
1764
+ * Author metadata for the lightbox
1765
+ */
1766
+ interface LightboxAuthor {
1767
+ /** Author name */
1768
+ name: string;
1769
+ /** Author role/subtitle */
1770
+ role?: string;
1771
+ /** Author avatar URL */
1772
+ avatarSrc?: string;
1773
+ /** Author avatar initials (if no photo) */
1774
+ avatarInitials?: string;
1775
+ /** Avatar type */
1776
+ avatarType?: 'photo' | 'initials';
1777
+ /** Timestamp */
1778
+ timestamp?: string;
1779
+ }
1780
+ /**
1781
+ * Configuration options for image lightbox
1782
+ */
1783
+ interface LightboxImageOptions {
1784
+ /** Array of images to display */
1785
+ images: LightboxImage[];
1786
+ /** Author information to display in header */
1787
+ author?: LightboxAuthor;
1788
+ /** Initial image index to show (0-based) */
1789
+ initialIndex?: number;
1790
+ /** Enable pinch-to-zoom and double-tap zoom */
1791
+ enableZoom?: boolean;
1792
+ /** Show navigation controls (arrows, counter) */
1793
+ showControls?: boolean;
1794
+ /** Enable swipe gestures to navigate between images */
1795
+ enableSwipe?: boolean;
1796
+ /** Show image info (title, description) */
1797
+ showInfo?: boolean;
1798
+ /** Animation type for opening */
1799
+ animation?: 'fade' | 'zoom' | 'slide';
1800
+ }
1801
+ /**
1802
+ * Configuration options for PDF lightbox
1803
+ */
1804
+ interface LightboxPdfOptions {
1805
+ /** PDF document to display */
1806
+ pdf: LightboxPdf;
1807
+ /** Author information to display */
1808
+ author?: LightboxAuthor;
1809
+ }
1810
+ /**
1811
+ * Generic lightbox options (for backward compatibility)
1812
+ */
1813
+ type LightboxOptions = LightboxImageOptions;
1814
+ /**
1815
+ * DsMobileLightboxService
1816
+ *
1817
+ * Service for displaying media files (images and PDFs) in full-screen viewers.
1818
+ * - Images: Full-screen modal with gestures (pinch-zoom, swipe navigation)
1819
+ * - PDFs: Native device PDF viewer (iOS/Android)
1820
+ *
1821
+ * Features:
1822
+ * - Full-screen image viewing with gestures
1823
+ * - Native PDF viewing
1824
+ * - Swipe navigation between images
1825
+ * - Pinch-to-zoom and double-tap zoom for images
1826
+ * - Mobile-optimized touch gestures
1827
+ * - Share functionality
1828
+ *
1829
+ * @example
1830
+ * ```typescript
1831
+ * constructor(private lightbox: DsMobileLightboxService) {}
1832
+ *
1833
+ * // Open images
1834
+ * async openImages() {
1835
+ * const modal = await this.lightbox.openImages({
1836
+ * images: [
1837
+ * {
1838
+ * type: 'image',
1839
+ * src: 'https://example.com/image1.jpg',
1840
+ * title: 'Beautiful Sunset'
1841
+ * }
1842
+ * ]
1843
+ * });
1844
+ *
1845
+ * // Listen for when lightbox is dismissed
1846
+ * const { data } = await modal.onDidDismiss();
1847
+ * if (data?.action === 'comment') {
1848
+ * // Open post detail modal with comment focus
1849
+ * this.openPostDetail({ focusComment: true });
1850
+ * }
1851
+ * }
1852
+ *
1853
+ * // Open PDF
1854
+ * async openPdf() {
1855
+ * await this.lightbox.openPdf({
1856
+ * pdf: {
1857
+ * type: 'pdf',
1858
+ * src: 'https://example.com/document.pdf',
1859
+ * title: 'Document'
1860
+ * }
1861
+ * });
1862
+ * }
1863
+ * ```
1864
+ */
1865
+ declare class DsMobileLightboxService {
1866
+ private appRef;
1867
+ private injector;
1868
+ private currentLightbox;
1869
+ constructor(appRef: ApplicationRef, injector: EnvironmentInjector);
1870
+ /**
1871
+ * Open the lightbox with images (backward compatible method)
1872
+ *
1873
+ * @param options Configuration options for the image lightbox
1874
+ * @returns Promise that resolves to a dismiss function
1875
+ */
1876
+ open(options: LightboxOptions): Promise<() => void>;
1877
+ /**
1878
+ * Open the image lightbox with one or more images
1879
+ *
1880
+ * @param options Configuration options for the image lightbox
1881
+ * @returns Promise that resolves to a dismiss function
1882
+ */
1883
+ openImages(options: LightboxImageOptions): Promise<() => void>;
1884
+ /**
1885
+ * Open the PDF lightbox (opens native PDF viewer)
1886
+ *
1887
+ * @param options Configuration options for the PDF lightbox
1888
+ * @returns Promise that resolves to a dismiss function
1889
+ */
1890
+ openPdf(options: LightboxPdfOptions): Promise<() => void>;
1891
+ /**
1892
+ * Close the currently open lightbox
1893
+ */
1894
+ close(): void;
1895
+ /**
1896
+ * Check if a lightbox is currently open
1897
+ */
1898
+ isOpen(): boolean;
1899
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileLightboxService, never>;
1900
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<DsMobileLightboxService>;
1901
+ }
1902
+
1903
+ /**
1904
+ * DsMobileLightboxImageComponent
1905
+ *
1906
+ * Full-screen image lightbox component with Swiper.js navigation and pinch-zoom.
1907
+ *
1908
+ * This component is typically not used directly - use DsMobileLightboxService instead.
1909
+ *
1910
+ * Features:
1911
+ * - Swiper.js for smooth image navigation
1912
+ * - Pinch to zoom in/out
1913
+ * - Double-tap to toggle zoom
1914
+ * - Swipe down to close (when not zoomed)
1915
+ * - Image counter and navigation controls
1916
+ *
1917
+ * @example
1918
+ * ```typescript
1919
+ * // Don't instantiate directly - use the service:
1920
+ * constructor(private lightbox: DsMobileLightboxService) {}
1921
+ *
1922
+ * openImage() {
1923
+ * this.lightbox.openImages({
1924
+ * images: [{ type: 'image', src: 'image.jpg', title: 'My Image' }]
1925
+ * });
1926
+ * }
1927
+ * ```
1928
+ */
1929
+ declare class DsMobileLightboxImageComponent implements OnInit, AfterViewInit, OnDestroy {
1930
+ private gestureCtrl;
1931
+ images: LightboxImage[];
1932
+ author?: LightboxAuthor;
1933
+ initialIndex: number;
1934
+ enableZoom: boolean;
1935
+ showControls: boolean;
1936
+ enableSwipe: boolean;
1937
+ showInfo: boolean;
1938
+ animation: 'fade' | 'zoom' | 'slide';
1939
+ onCloseRequested?: () => void;
1940
+ swiperContainer: ElementRef<HTMLDivElement>;
1941
+ currentIndex: _angular_core.WritableSignal<number>;
1942
+ scale: _angular_core.WritableSignal<number>;
1943
+ isZoomed: _angular_core.WritableSignal<boolean>;
1944
+ isLoading: _angular_core.WritableSignal<boolean>;
1945
+ hasError: _angular_core.WritableSignal<boolean>;
1946
+ isLiked: _angular_core.WritableSignal<boolean>;
1947
+ likeCount: _angular_core.WritableSignal<number>;
1948
+ commentCount: _angular_core.WritableSignal<number>;
1949
+ currentImage: _angular_core.Signal<LightboxImage>;
1950
+ private swiper?;
1951
+ private zoomData;
1952
+ constructor(gestureCtrl: GestureController);
1953
+ ngOnInit(): void;
1954
+ ngAfterViewInit(): void;
1955
+ ngOnDestroy(): void;
1956
+ /**
1957
+ * Initialize Swiper for image navigation
1958
+ */
1959
+ private initializeSwiper;
1960
+ /**
1961
+ * Initialize pinch-zoom gestures for all slides
1962
+ */
1963
+ private initializeZoomGestures;
1964
+ /**
1965
+ * Initialize zoom gestures for a specific slide
1966
+ */
1967
+ private initializeZoomForSlide;
1968
+ /**
1969
+ * Toggle zoom on double-tap
1970
+ */
1971
+ private toggleZoom;
1972
+ /**
1973
+ * Update action states (like, comments) when slide changes
1974
+ */
1975
+ private updateActionStates;
1976
+ /**
1977
+ * Close the lightbox
1978
+ */
1979
+ close(): void;
1980
+ /**
1981
+ * Handle share button click
1982
+ */
1983
+ onShare(): Promise<void>;
1984
+ /**
1985
+ * Handle like button toggle
1986
+ */
1987
+ onLikeToggle(): void;
1988
+ /**
1989
+ * Handle reply/comment button click
1990
+ */
1991
+ onReply(): void;
1992
+ /**
1993
+ * Navigate to the next image
1994
+ */
1995
+ nextImage(): void;
1996
+ /**
1997
+ * Navigate to the previous image
1998
+ */
1999
+ previousImage(): void;
2000
+ /**
2001
+ * Handle image load success
2002
+ */
2003
+ onImageLoad(index: number): void;
2004
+ /**
2005
+ * Handle image load error
2006
+ */
2007
+ onImageError(index: number): void;
2008
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileLightboxImageComponent, never>;
2009
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobileLightboxImageComponent, "ds-mobile-lightbox-image", never, {}, {}, never, never, true, never>;
2010
+ }
2011
+
2012
+ /**
2013
+ * DsMobileLightboxPdfComponent
2014
+ *
2015
+ * PDF viewer component that displays PDF info and allows users to open PDFs in the native device viewer.
2016
+ * Shows a lightbox with PDF details first, then user can choose to open in native viewer.
2017
+ *
2018
+ * This component is typically not used directly - use DsMobileLightboxService instead.
2019
+ *
2020
+ * Features:
2021
+ * - PDF info preview (title, size, icon)
2022
+ * - User-initiated native PDF viewing (iOS/Android)
2023
+ * - Download and cache support
2024
+ * - Share functionality
2025
+ * - Loading states
2026
+ *
2027
+ * @example
2028
+ * ```typescript
2029
+ * // Don't instantiate directly - use the service:
2030
+ * constructor(private lightbox: DsMobileLightboxService) {}
2031
+ *
2032
+ * openPdf() {
2033
+ * this.lightbox.openPdf({
2034
+ * pdf: { type: 'pdf', src: 'document.pdf', title: 'My Document' }
2035
+ * });
2036
+ * }
2037
+ * ```
2038
+ */
2039
+ declare class DsMobileLightboxPdfComponent implements OnInit {
2040
+ pdf: LightboxPdf;
2041
+ author?: LightboxAuthor;
2042
+ onCloseRequested?: () => void;
2043
+ isLoading: boolean;
2044
+ hasError: boolean;
2045
+ errorMessage: string;
2046
+ cachedFilePath?: string;
2047
+ constructor();
2048
+ ngOnInit(): void;
2049
+ /**
2050
+ * Open the PDF in the native device viewer
2051
+ */
2052
+ openPdfInNativeViewer(): Promise<void>;
2053
+ /**
2054
+ * Download a remote PDF and open it
2055
+ */
2056
+ private downloadAndOpenPdf;
2057
+ /**
2058
+ * Open a local PDF file
2059
+ */
2060
+ private openLocalPdf;
2061
+ /**
2062
+ * Convert Blob to base64 string
2063
+ */
2064
+ private blobToBase64;
2065
+ /**
2066
+ * Get display title with file extension
2067
+ * If title is provided, ensure it has .pdf extension
2068
+ * Otherwise, extract filename from src
2069
+ */
2070
+ getDisplayTitle(): string;
2071
+ /**
2072
+ * Format file size for display
2073
+ */
2074
+ formatFileSize(bytes: number): string;
2075
+ /**
2076
+ * Share the PDF
2077
+ */
2078
+ onShare(): Promise<void>;
2079
+ /**
2080
+ * Close the PDF viewer
2081
+ */
2082
+ close(): void;
2083
+ /**
2084
+ * Handle like toggle
2085
+ */
2086
+ onLikeToggle(): void;
2087
+ /**
2088
+ * Handle reply/comment
2089
+ * Close the lightbox and signal to open post detail with comment focus
2090
+ */
2091
+ onReply(): void;
2092
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileLightboxPdfComponent, never>;
2093
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobileLightboxPdfComponent, "ds-mobile-lightbox-pdf", never, {}, {}, never, never, true, never>;
2094
+ }
2095
+
2096
+ /**
2097
+ * DsMobileLightboxHeaderComponent
2098
+ *
2099
+ * Shared header component for all lightbox types (image, PDF, etc.)
2100
+ * Displays author information and close button with consistent styling.
2101
+ */
2102
+ declare class DsMobileLightboxHeaderComponent {
2103
+ /**
2104
+ * Author information to display
2105
+ */
2106
+ author: _angular_core.InputSignal<LightboxAuthor | undefined>;
2107
+ /**
2108
+ * Emitted when close button is clicked
2109
+ */
2110
+ closeClick: _angular_core.OutputEmitterRef<void>;
2111
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileLightboxHeaderComponent, never>;
2112
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobileLightboxHeaderComponent, "ds-mobile-lightbox-header", never, { "author": { "alias": "author"; "required": false; "isSignal": true; }; }, { "closeClick": "closeClick"; }, never, never, true, never>;
2113
+ }
2114
+
2115
+ /**
2116
+ * DsMobileLightboxFooterComponent
2117
+ *
2118
+ * Shared footer component for all lightbox types (image, PDF, etc.)
2119
+ * Displays navigation controls (for multiple images) and action buttons.
2120
+ */
2121
+ declare class DsMobileLightboxFooterComponent {
2122
+ /**
2123
+ * Whether to show navigation controls
2124
+ */
2125
+ showNavigation: _angular_core.InputSignal<boolean>;
2126
+ /**
2127
+ * Current image index (0-based)
2128
+ */
2129
+ currentIndex: _angular_core.InputSignal<number>;
2130
+ /**
2131
+ * Total number of images
2132
+ */
2133
+ totalImages: _angular_core.InputSignal<number>;
2134
+ /**
2135
+ * Whether the content is liked
2136
+ */
2137
+ isLiked: _angular_core.InputSignal<boolean>;
2138
+ /**
2139
+ * Number of likes
2140
+ */
2141
+ likeCount: _angular_core.InputSignal<number>;
2142
+ /**
2143
+ * Number of comments
2144
+ */
2145
+ commentCount: _angular_core.InputSignal<number>;
2146
+ /**
2147
+ * Emitted when previous button is clicked
2148
+ */
2149
+ prevClick: _angular_core.OutputEmitterRef<void>;
2150
+ /**
2151
+ * Emitted when next button is clicked
2152
+ */
2153
+ nextClick: _angular_core.OutputEmitterRef<void>;
2154
+ /**
2155
+ * Emitted when like button is clicked
2156
+ */
2157
+ likeClick: _angular_core.OutputEmitterRef<void>;
2158
+ /**
2159
+ * Emitted when comment button is clicked
2160
+ */
2161
+ commentClick: _angular_core.OutputEmitterRef<void>;
2162
+ /**
2163
+ * Emitted when share button is clicked
2164
+ */
2165
+ shareClick: _angular_core.OutputEmitterRef<void>;
2166
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileLightboxFooterComponent, never>;
2167
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobileLightboxFooterComponent, "ds-mobile-lightbox-footer", never, { "showNavigation": { "alias": "showNavigation"; "required": false; "isSignal": true; }; "currentIndex": { "alias": "currentIndex"; "required": false; "isSignal": true; }; "totalImages": { "alias": "totalImages"; "required": false; "isSignal": true; }; "isLiked": { "alias": "isLiked"; "required": false; "isSignal": true; }; "likeCount": { "alias": "likeCount"; "required": false; "isSignal": true; }; "commentCount": { "alias": "commentCount"; "required": false; "isSignal": true; }; }, { "prevClick": "prevClick"; "nextClick": "nextClick"; "likeClick": "likeClick"; "commentClick": "commentClick"; "shareClick": "shareClick"; }, never, never, true, never>;
2168
+ }
2169
+
2170
+ /**
2171
+ * DsMobileInlinePhotoComponent
2172
+ *
2173
+ * Displays one or multiple photos in a grid layout optimized for social feeds.
2174
+ * Supports up to 5 visible images with automatic grid layouts.
2175
+ *
2176
+ * Features:
2177
+ * - Automatic grid layouts for 1-5 images
2178
+ * - Shows "+N more" overlay if more than 5 images
2179
+ * - Opens lightbox with all images (including hidden ones) when clicked
2180
+ * - Optimized layouts: 1 full, 2 split, 3 masonry, 4 grid, 5 grid
2181
+ *
2182
+ * @example
2183
+ * ```html
2184
+ * <ds-mobile-inline-photo
2185
+ * [images]="['img1.jpg', 'img2.jpg', 'img3.jpg']"
2186
+ * [author]="authorInfo"
2187
+ * />
2188
+ * ```
2189
+ */
2190
+ declare class DsMobileInlinePhotoComponent {
2191
+ private lightboxService;
2192
+ /**
2193
+ * Array of image URLs to display
2194
+ */
2195
+ images: string[];
2196
+ /**
2197
+ * Author information (passed to lightbox)
2198
+ */
2199
+ author?: {
2200
+ name: string;
2201
+ role?: string;
2202
+ avatarSrc?: string;
2203
+ avatarInitials?: string;
2204
+ avatarType?: 'photo' | 'initials';
2205
+ timestamp?: string;
2206
+ };
2207
+ /**
2208
+ * Maximum number of images to show inline (default: 5)
2209
+ * Remaining images shown in lightbox only
2210
+ */
2211
+ maxVisible: number;
2212
+ /**
2213
+ * Event emitted when lightbox is opened
2214
+ */
2215
+ photoClick: _angular_core.OutputEmitterRef<{
2216
+ index: number;
2217
+ totalImages: number;
2218
+ }>;
2219
+ constructor(lightboxService: DsMobileLightboxService);
2220
+ /**
2221
+ * Get the first N images to display inline
2222
+ */
2223
+ get visibleImages(): string[];
2224
+ /**
2225
+ * Calculate how many images are hidden
2226
+ */
2227
+ get hiddenCount(): number;
2228
+ /**
2229
+ * Open lightbox with all images, starting at the clicked index
2230
+ */
2231
+ openLightbox(index: number, event?: Event): void;
2232
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileInlinePhotoComponent, never>;
2233
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobileInlinePhotoComponent, "ds-mobile-inline-photo", never, { "images": { "alias": "images"; "required": false; }; "author": { "alias": "author"; "required": false; }; "maxVisible": { "alias": "maxVisible"; "required": false; }; }, { "photoClick": "photoClick"; }, never, never, true, never>;
2234
+ }
2235
+
2236
+ /**
2237
+ * Configuration options for modal presentation
2238
+ */
2239
+ interface ModalOptions<T = any> {
2240
+ /** The component to display in the modal */
2241
+ component: Type<T>;
2242
+ /** Props to pass to the component */
2243
+ componentProps?: Record<string, any>;
2244
+ /** CSS class(es) to apply to the modal */
2245
+ cssClass?: string | string[];
2246
+ /** Modal presentation style */
2247
+ presentationStyle?: 'fullscreen' | 'card' | 'sheet';
2248
+ /** Enable backdrop dismiss (tap outside to close) */
2249
+ backdropDismiss?: boolean;
2250
+ /** Show backdrop */
2251
+ showBackdrop?: boolean;
2252
+ /** Enable keyboard close (ESC key) */
2253
+ keyboardClose?: boolean;
2254
+ /** Enable swipe to close */
2255
+ swipeToClose?: boolean;
2256
+ /** Initial breakpoint (0-1) for sheet presentation */
2257
+ initialBreakpoint?: number;
2258
+ /** Available breakpoints for sheet presentation */
2259
+ breakpoints?: number[];
2260
+ /** Animation type */
2261
+ animated?: boolean;
2262
+ /** Mode (ios or md) */
2263
+ mode?: 'ios' | 'md';
2264
+ /** Whether to handle navigation back button */
2265
+ handleNavigationBack?: boolean;
2266
+ }
2267
+ /**
2268
+ * DsMobileModalService
2269
+ *
2270
+ * Generic service for displaying any component as a modal.
2271
+ * Built on Ionic's modal system with customizable presentation styles.
2272
+ *
2273
+ * Features:
2274
+ * - Open any component as a modal
2275
+ * - Fullscreen, card, or sheet presentation styles
2276
+ * - Customizable backdrop and dismissal behavior
2277
+ * - Native gestures and animations
2278
+ * - Type-safe component props
2279
+ *
2280
+ * @example
2281
+ * ```typescript
2282
+ * import { MobilePostDetailPageComponent } from './post-detail.page';
2283
+ *
2284
+ * constructor(private modal: DsMobileModalService) {}
2285
+ *
2286
+ * async openPostModal() {
2287
+ * await this.modal.open({
2288
+ * component: MobilePostDetailPageComponent,
2289
+ * componentProps: {
2290
+ * postId: '123',
2291
+ * authorName: 'John Doe'
2292
+ * },
2293
+ * presentationStyle: 'card',
2294
+ * backdropDismiss: true
2295
+ * });
2296
+ * }
2297
+ * ```
2298
+ *
2299
+ * @example Sheet presentation with breakpoints
2300
+ * ```typescript
2301
+ * async openSheet() {
2302
+ * await this.modal.open({
2303
+ * component: CommentsComponent,
2304
+ * presentationStyle: 'sheet',
2305
+ * initialBreakpoint: 0.5,
2306
+ * breakpoints: [0, 0.5, 0.75, 1],
2307
+ * swipeToClose: true
2308
+ * });
2309
+ * }
2310
+ * ```
2311
+ */
2312
+ declare class DsMobileModalService {
2313
+ private modalController;
2314
+ constructor(modalController: ModalController);
2315
+ /**
2316
+ * Open a component as a modal
2317
+ *
2318
+ * @param options Configuration options for the modal
2319
+ * @returns Promise that resolves when the modal is presented
2320
+ *
2321
+ * @example
2322
+ * ```typescript
2323
+ * await this.modal.open({
2324
+ * component: MyComponent,
2325
+ * componentProps: { data: 'value' },
2326
+ * presentationStyle: 'fullscreen'
2327
+ * });
2328
+ * ```
2329
+ */
2330
+ open<T = any>(options: ModalOptions<T>): Promise<HTMLIonModalElement>;
2331
+ /**
2332
+ * Open a component as a fullscreen modal
2333
+ *
2334
+ * @param component Component to display
2335
+ * @param componentProps Props to pass to the component
2336
+ * @returns Promise that resolves when the modal is presented
2337
+ *
2338
+ * @example
2339
+ * ```typescript
2340
+ * await this.modal.openFullscreen(PostDetailPage, { postId: '123' });
2341
+ * ```
2342
+ */
2343
+ openFullscreen<T = any>(component: Type<T>, componentProps?: Record<string, any>): Promise<HTMLIonModalElement>;
2344
+ /**
2345
+ * Open a component as a card modal
2346
+ *
2347
+ * @param component Component to display
2348
+ * @param componentProps Props to pass to the component
2349
+ * @returns Promise that resolves when the modal is presented
2350
+ *
2351
+ * @example
2352
+ * ```typescript
2353
+ * await this.modal.openCard(DetailComponent, { itemId: '456' });
2354
+ * ```
2355
+ */
2356
+ openCard<T = any>(component: Type<T>, componentProps?: Record<string, any>): Promise<HTMLIonModalElement>;
2357
+ /**
2358
+ * Open a component as a bottom sheet
2359
+ *
2360
+ * @param component Component to display
2361
+ * @param componentProps Props to pass to the component
2362
+ * @param options Additional sheet options (breakpoints, etc.)
2363
+ * @returns Promise that resolves when the modal is presented
2364
+ *
2365
+ * @example
2366
+ * ```typescript
2367
+ * await this.modal.openSheet(
2368
+ * CommentsComponent,
2369
+ * { postId: '789' },
2370
+ * { initialBreakpoint: 0.5, breakpoints: [0, 0.5, 1] }
2371
+ * );
2372
+ * ```
2373
+ */
2374
+ openSheet<T = any>(component: Type<T>, componentProps?: Record<string, any>, options?: {
2375
+ initialBreakpoint?: number;
2376
+ breakpoints?: number[];
2377
+ swipeToClose?: boolean;
2378
+ }): Promise<HTMLIonModalElement>;
2379
+ /**
2380
+ * Close the currently open modal
2381
+ *
2382
+ * @param data Optional data to pass back when dismissing
2383
+ * @param role Optional role (e.g., 'cancel', 'confirm')
2384
+ * @returns Promise that resolves when the modal is dismissed
2385
+ *
2386
+ * @example
2387
+ * ```typescript
2388
+ * await this.modal.dismiss({ saved: true }, 'confirm');
2389
+ * ```
2390
+ */
2391
+ dismiss(data?: any, role?: string): Promise<boolean>;
2392
+ /**
2393
+ * Get the top-most modal if one exists
2394
+ *
2395
+ * @returns Promise that resolves to the modal element or undefined
2396
+ *
2397
+ * @example
2398
+ * ```typescript
2399
+ * const topModal = await this.modal.getTop();
2400
+ * if (topModal) {
2401
+ * await topModal.dismiss();
2402
+ * }
2403
+ * ```
2404
+ */
2405
+ getTop(): Promise<HTMLIonModalElement | undefined>;
2406
+ /**
2407
+ * Get all currently open modals
2408
+ *
2409
+ * @returns Promise that resolves to an array of modal elements
2410
+ */
2411
+ getAll(): Promise<HTMLIonModalElement[]>;
2412
+ /**
2413
+ * Build CSS classes for the modal
2414
+ */
2415
+ private buildCssClasses;
2416
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileModalService, never>;
2417
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<DsMobileModalService>;
2418
+ }
2419
+
2420
+ /**
2421
+ * Post data interface for the modal
2422
+ */
2423
+ interface PostDetailData {
2424
+ postId: string;
2425
+ authorName: string;
2426
+ authorRole: string;
2427
+ timestamp: string;
2428
+ avatarInitials?: string;
2429
+ avatarType?: 'photo' | 'initials';
2430
+ avatarSrc?: string;
2431
+ content: string;
2432
+ imageSrc?: string;
2433
+ imageAlt?: string;
2434
+ isLiked?: boolean;
2435
+ likeCount?: number;
2436
+ commentCount?: number;
2437
+ comments?: CommentData[];
2438
+ focusComment?: boolean;
2439
+ }
2440
+ interface CommentData {
2441
+ authorName: string;
2442
+ authorRole: string;
2443
+ timestamp: string;
2444
+ avatarInitials: string;
2445
+ content: string;
2446
+ isLiked?: boolean;
2447
+ likeCount?: number;
2448
+ isOwnComment?: boolean;
2449
+ }
2450
+ /**
2451
+ * DsMobilePostDetailModalComponent
2452
+ *
2453
+ * Modal wrapper for displaying post details with comments.
2454
+ * Follows the same pattern as the lightbox modal for consistent behavior.
2455
+ *
2456
+ * Features:
2457
+ * - Full post content display
2458
+ * - Comments section
2459
+ * - Image lightbox integration
2460
+ * - Native modal controls (close, swipe down)
2461
+ * - Safe area support
2462
+ *
2463
+ * This component is typically not used directly - use DsMobilePostDetailModalService instead.
2464
+ *
2465
+ * @example
2466
+ * ```typescript
2467
+ * // Don't instantiate directly - use the service:
2468
+ * constructor(private postModal: DsMobilePostDetailModalService) {}
2469
+ *
2470
+ * openPost() {
2471
+ * this.postModal.open({
2472
+ * postId: '123',
2473
+ * authorName: 'John Doe',
2474
+ * content: 'Post content...'
2475
+ * });
2476
+ * }
2477
+ * ```
2478
+ */
2479
+ declare class DsMobilePostDetailModalComponent implements AfterViewInit, OnDestroy {
2480
+ private modalController;
2481
+ private lightbox;
2482
+ private bottomSheet;
2483
+ postData: PostDetailData;
2484
+ commentInput?: ElementRef<HTMLTextAreaElement>;
2485
+ post: _angular_core.WritableSignal<PostDetailData>;
2486
+ commentText: _angular_core.WritableSignal<string>;
2487
+ currentUserInitials: _angular_core.WritableSignal<string>;
2488
+ replyingTo: _angular_core.WritableSignal<{
2489
+ authorName: string;
2490
+ content: string;
2491
+ } | null>;
2492
+ editingComment: _angular_core.WritableSignal<{
2493
+ authorName: string;
2494
+ originalContent: string;
2495
+ timestamp: string;
2496
+ } | null>;
2497
+ showMentionMenu: _angular_core.WritableSignal<boolean>;
2498
+ mentionQuery: _angular_core.WritableSignal<string>;
2499
+ availableUsers: _angular_core.Signal<{
2500
+ name: string;
2501
+ initials: string;
2502
+ role: string;
2503
+ }[]>;
2504
+ filteredUsers: _angular_core.Signal<{
2505
+ name: string;
2506
+ initials: string;
2507
+ role: string;
2508
+ }[]>;
2509
+ constructor(modalController: ModalController, lightbox: DsMobileLightboxService, bottomSheet: DsMobileBottomSheetService);
2510
+ ngOnInit(): void;
2511
+ ngAfterViewInit(): void;
2512
+ ngOnDestroy(): void;
2513
+ /**
2514
+ * Set up keyboard event listeners to adjust composer position
2515
+ * The CSS uses --keyboard-height variable to translate the composer up
2516
+ */
2517
+ private setupKeyboardListeners;
2518
+ /**
2519
+ * Clean up keyboard event listeners
2520
+ */
2521
+ private cleanupKeyboardListeners;
2522
+ /**
2523
+ * Show the keyboard when user interacts with input
2524
+ */
2525
+ showKeyboard(): void;
2526
+ /**
2527
+ * Focus the comment input when comment icon is tapped
2528
+ */
2529
+ focusCommentInput(): void;
2530
+ /**
2531
+ * Handle input changes and detect @ mentions
2532
+ */
2533
+ handleInput(event: Event): void;
2534
+ /**
2535
+ * Select a user from mention menu - show as reply indicator instead of inline mention
2536
+ */
2537
+ selectMention(userName: string): void;
2538
+ /**
2539
+ * Handle reply to a comment
2540
+ */
2541
+ handleReply(authorName: string, content: string): void;
2542
+ /**
2543
+ * Cancel reply
2544
+ */
2545
+ cancelReply(): void;
2546
+ /**
2547
+ * Cancel edit
2548
+ */
2549
+ cancelEdit(): void;
2550
+ /**
2551
+ * Handle edit comment
2552
+ */
2553
+ handleEditComment(authorName: string, originalContent: string, timestamp: string): void;
2554
+ /**
2555
+ * Close the modal
2556
+ */
2557
+ close(): void;
2558
+ /**
2559
+ * Submit a comment
2560
+ */
2561
+ submitComment(): void;
2562
+ /**
2563
+ * Open image in lightbox
2564
+ */
2565
+ openImageLightbox(): void;
2566
+ /**
2567
+ * Handle long press on a comment to show action sheet
2568
+ */
2569
+ handleCommentLongPress(authorName: string, content: string, isOwnComment: boolean): Promise<void>;
2570
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobilePostDetailModalComponent, never>;
2571
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobilePostDetailModalComponent, "ds-mobile-post-detail-modal", never, { "postData": { "alias": "postData"; "required": false; }; }, {}, never, never, true, never>;
2572
+ }
2573
+
2574
+ /**
2575
+ * DsMobilePostDetailModalService
2576
+ *
2577
+ * Service for displaying post details in a full-screen modal.
2578
+ * Built on Ionic's modal system with native gestures and animations.
2579
+ * Follows the same pattern as DsMobileLightboxService for consistent behavior.
2580
+ *
2581
+ * Features:
2582
+ * - Full post content display
2583
+ * - Comments section
2584
+ * - Like/comment actions
2585
+ * - Image lightbox integration
2586
+ * - Native modal animations
2587
+ * - Safe area support
2588
+ *
2589
+ * @example
2590
+ * ```typescript
2591
+ * constructor(private postModal: DsMobilePostDetailModalService) {}
2592
+ *
2593
+ * async openPost() {
2594
+ * await this.postModal.open({
2595
+ * postId: '123',
2596
+ * authorName: 'John Doe',
2597
+ * authorRole: 'Tenant',
2598
+ * timestamp: '2h ago',
2599
+ * avatarInitials: 'JD',
2600
+ * content: 'Just moved into my new apartment!',
2601
+ * isLiked: false,
2602
+ * likeCount: 42,
2603
+ * commentCount: 12,
2604
+ * comments: [
2605
+ * {
2606
+ * authorName: 'Jane Smith',
2607
+ * authorRole: 'Tenant',
2608
+ * timestamp: '1h ago',
2609
+ * avatarInitials: 'JS',
2610
+ * content: 'Welcome to the community!'
2611
+ * }
2612
+ * ]
2613
+ * });
2614
+ * }
2615
+ * ```
2616
+ */
2617
+ declare class DsMobilePostDetailModalService {
2618
+ private modalController;
2619
+ constructor(modalController: ModalController);
2620
+ /**
2621
+ * Open the post detail modal
2622
+ *
2623
+ * @param postData Post data to display
2624
+ * @returns Promise that resolves when the modal is presented
2625
+ */
2626
+ open(postData: PostDetailData): Promise<void>;
2627
+ /**
2628
+ * Close the currently open post detail modal
2629
+ *
2630
+ * @param data Optional data to pass back when dismissing
2631
+ * @returns Promise that resolves when the modal is dismissed
2632
+ */
2633
+ close(data?: any): Promise<boolean>;
2634
+ /**
2635
+ * Get the top-most modal if one exists
2636
+ *
2637
+ * @returns Promise that resolves to the modal element or undefined
2638
+ */
2639
+ getTop(): Promise<HTMLIonModalElement | undefined>;
2640
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobilePostDetailModalService, never>;
2641
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<DsMobilePostDetailModalService>;
2642
+ }
2643
+
2644
+ /**
2645
+ * Handbook detail data interface
2646
+ */
2647
+ interface HandbookDetailData {
2648
+ title: string;
2649
+ variant: string;
2650
+ iconName: string;
2651
+ itemCount: number;
2652
+ items?: HandbookItem[];
2653
+ }
2654
+ interface HandbookItem {
2655
+ title: string;
2656
+ description?: string;
2657
+ images?: string[];
2658
+ attachments?: AttachmentItem[];
2659
+ contacts?: ContactItem[];
2660
+ }
2661
+ interface AttachmentItem {
2662
+ name: string;
2663
+ type?: string;
2664
+ }
2665
+ interface ContactItem {
2666
+ name: string;
2667
+ initials: string;
2668
+ contactPerson?: string;
2669
+ phoneNumber?: string;
2670
+ }
2671
+
2672
+ /**
2673
+ * DsMobileHandbookDetailModalService
2674
+ *
2675
+ * Service for displaying handbook folder details in a full-screen modal.
2676
+ * Built on Ionic's modal system with native gestures and animations.
2677
+ *
2678
+ * Features:
2679
+ * - Full handbook content display
2680
+ * - Items list with descriptions
2681
+ * - Images and attachments
2682
+ * - Contact information
2683
+ * - Native modal animations
2684
+ * - Safe area support
2685
+ *
2686
+ * @example
2687
+ * ```typescript
2688
+ * constructor(private handbookModal: DsMobileHandbookDetailModalService) {}
2689
+ *
2690
+ * async openHandbook() {
2691
+ * await this.handbookModal.open({
2692
+ * title: 'Utilities',
2693
+ * variant: 'pink',
2694
+ * iconName: 'remixLightbulbLine',
2695
+ * itemCount: 8,
2696
+ * items: [
2697
+ * {
2698
+ * title: 'Hjertestarter',
2699
+ * description: 'Installed on the 4th floor...',
2700
+ * images: ['/path/to/image.jpg'],
2701
+ * contacts: [
2702
+ * { name: 'Mortensen & Søn ApS', initials: 'M' }
2703
+ * ]
2704
+ * }
2705
+ * ]
2706
+ * });
2707
+ * }
2708
+ * ```
2709
+ */
2710
+ declare class DsMobileHandbookDetailModalService {
2711
+ private modalController;
2712
+ constructor(modalController: ModalController);
2713
+ /**
2714
+ * Open the handbook detail modal
2715
+ *
2716
+ * @param handbookData Handbook data to display
2717
+ * @returns Promise that resolves when the modal is presented
2718
+ */
2719
+ open(handbookData: HandbookDetailData): Promise<void>;
2720
+ /**
2721
+ * Close the currently open handbook detail modal
2722
+ *
2723
+ * @param data Optional data to pass back when dismissing
2724
+ * @returns Promise that resolves when the modal is dismissed
2725
+ */
2726
+ close(data?: any): Promise<boolean>;
2727
+ /**
2728
+ * Get the top-most modal if one exists
2729
+ *
2730
+ * @returns Promise that resolves to the modal element or undefined
2731
+ */
2732
+ getTop(): Promise<HTMLIonModalElement | undefined>;
2733
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileHandbookDetailModalService, never>;
2734
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<DsMobileHandbookDetailModalService>;
2735
+ }
2736
+
2737
+ /**
2738
+ * DsMobileHandbookFolderComponent
2739
+ *
2740
+ * A visually rich folder component for displaying handbook categories or sections.
2741
+ * Features a two-layer folder design with customizable colors, icon, item count, and label.
2742
+ *
2743
+ * Design Details:
2744
+ * - Folder back: 72px height with a decorative notch
2745
+ * - Folder front: 64px height overlaying the back
2746
+ * - Item count displayed in bottom-left corner
2747
+ * - Icon displayed in bottom-right corner
2748
+ * - Label text centered below the folder
2749
+ *
2750
+ * @example
2751
+ * ```html
2752
+ * <ds-mobile-handbook-folder
2753
+ * [colorBase]="'#d244cf'"
2754
+ * [colorWeak]="'#f9e6f9'"
2755
+ * [iconName]="'remixLightbulbLine'"
2756
+ * [itemCount]="8"
2757
+ * [label]="'Utilities'">
2758
+ * </ds-mobile-handbook-folder>
2759
+ * ```
2760
+ */
2761
+ declare class DsMobileHandbookFolderComponent {
2762
+ private handbookModal;
2763
+ /**
2764
+ * Color variant for the folder
2765
+ * Available variants: success, warning, destructive, blue, light-purple, pink, salmon-orange, orange, lime-green, grey
2766
+ * Example: 'pink', 'success', 'blue'
2767
+ */
2768
+ variant: string;
2769
+ /**
2770
+ * Icon name from the design system icon library
2771
+ * Example: 'remixLightbulbLine', 'remixFolder3Line'
2772
+ */
2773
+ iconName: string;
2774
+ /**
2775
+ * Number of items in the folder
2776
+ */
2777
+ itemCount: number;
2778
+ /**
2779
+ * Label text displayed below the folder
2780
+ */
2781
+ label: string;
2782
+ /**
2783
+ * Optional items data for the handbook folder
2784
+ */
2785
+ items?: HandbookItem[];
2786
+ /**
2787
+ * Track open/closed state for animation
2788
+ */
2789
+ isOpen: _angular_core.WritableSignal<boolean>;
2790
+ /**
2791
+ * Get the CSS variable name for the color variant
2792
+ */
2793
+ getColorVar(suffix: 'base' | 'strong'): string;
2794
+ /**
2795
+ * Open folder animation
2796
+ */
2797
+ open(): void;
2798
+ /**
2799
+ * Close folder animation
2800
+ */
2801
+ close(): void;
2802
+ /**
2803
+ * Handle touch start - open animation
2804
+ */
2805
+ onTouchStart(event: TouchEvent): void;
2806
+ /**
2807
+ * Handle touch end - close animation
2808
+ */
2809
+ onTouchEnd(): void;
2810
+ /**
2811
+ * Handle touch cancel - close animation
2812
+ */
2813
+ onTouchCancel(): void;
2814
+ /**
2815
+ * Handle click - open modal
2816
+ */
2817
+ onClick(): Promise<void>;
2818
+ /**
2819
+ * Calculate the number of page sheets to display
2820
+ * Max 6 sheets regardless of item count
2821
+ */
2822
+ getPageSheets(): number[];
2823
+ constructor(handbookModal: DsMobileHandbookDetailModalService);
2824
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileHandbookFolderComponent, never>;
2825
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobileHandbookFolderComponent, "ds-mobile-handbook-folder", never, { "variant": { "alias": "variant"; "required": false; }; "iconName": { "alias": "iconName"; "required": false; }; "itemCount": { "alias": "itemCount"; "required": false; }; "label": { "alias": "label"; "required": false; }; "items": { "alias": "items"; "required": false; }; }, {}, never, never, true, never>;
2826
+ }
2827
+
2828
+ /**
2829
+ * DsMobileHandbookFolderMiniComponent
2830
+ *
2831
+ * A minimized folder icon component for use in headers and small spaces.
2832
+ * Simplified version without animations or page sheets - just folder and icon.
2833
+ *
2834
+ * @example
2835
+ * ```html
2836
+ * <ds-mobile-handbook-folder-mini
2837
+ * [variant]="'pink'"
2838
+ * [iconName]="'remixLightbulbLine'">
2839
+ * </ds-mobile-handbook-folder-mini>
2840
+ * ```
2841
+ */
2842
+ declare class DsMobileHandbookFolderMiniComponent {
2843
+ /**
2844
+ * Color variant for the folder
2845
+ * Available variants: success, warning, destructive, blue, light-purple, pink, salmon-orange, orange, lime-green, grey
2846
+ */
2847
+ variant: string;
2848
+ /**
2849
+ * Icon name from the design system icon library
2850
+ */
2851
+ iconName: string;
2852
+ /**
2853
+ * Get the CSS variable name for the color variant
2854
+ */
2855
+ getColorVar(suffix: 'base' | 'strong'): string;
2856
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileHandbookFolderMiniComponent, never>;
2857
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobileHandbookFolderMiniComponent, "ds-mobile-handbook-folder-mini", never, { "variant": { "alias": "variant"; "required": false; }; "iconName": { "alias": "iconName"; "required": false; }; }, {}, never, never, true, never>;
2858
+ }
2859
+
2860
+ /**
2861
+ * User service for managing current user data globally
2862
+ */
2863
+ declare class UserService {
2864
+ private _avatarInitials;
2865
+ private _avatarType;
2866
+ private _avatarSrc;
2867
+ readonly avatarInitials: _angular_core.Signal<string>;
2868
+ readonly avatarType: _angular_core.Signal<"initials" | "photo" | "icon">;
2869
+ readonly avatarSrc: _angular_core.Signal<string>;
2870
+ /**
2871
+ * Update avatar configuration
2872
+ */
2873
+ setAvatarInitials(initials: string): void;
2874
+ setAvatarType(type: 'initials' | 'photo' | 'icon'): void;
2875
+ setAvatarSrc(src: string): void;
2876
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UserService, never>;
2877
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<UserService>;
2878
+ }
2879
+
2880
+ declare class MobileCommunityPageComponent {
2881
+ private router;
2882
+ private route;
2883
+ private bottomSheet;
2884
+ private lightbox;
2885
+ private postModal;
2886
+ userService: UserService;
2887
+ userPosts: _angular_core.WritableSignal<any[]>;
2888
+ showStaticPosts: _angular_core.WritableSignal<boolean>;
2889
+ hasAnyPosts: _angular_core.Signal<boolean>;
2890
+ constructor(router: Router, route: ActivatedRoute, bottomSheet: DsMobileBottomSheetService, lightbox: DsMobileLightboxService, postModal: DsMobilePostDetailModalService, userService: UserService);
2891
+ handleRefresh(event: any): void;
2892
+ /**
2893
+ * Open post detail modal
2894
+ * This provides a better UX than route navigation:
2895
+ * - Maintains scroll position
2896
+ * - Native iOS-style modal feel
2897
+ * - Proper close button that works
2898
+ */
2899
+ openPost(postId: string, focusComment?: boolean): Promise<void>;
2900
+ /**
2901
+ * Open user-created post detail modal
2902
+ */
2903
+ openUserPost(index: number, focusComment?: boolean): Promise<void>;
2904
+ openPostCreator(): Promise<void>;
2905
+ /**
2906
+ * Open an image in the lightbox viewer
2907
+ * Prevents the post click event from firing
2908
+ */
2909
+ openImageLightbox(imageSrc: string, title: string, description: string, event: Event): Promise<void>;
2910
+ openHouseRulesPdf(): Promise<void>;
2911
+ /**
2912
+ * Handle long press on a post to show action sheet
2913
+ */
2914
+ handlePostLongPress(postIdOrIndex: string | number, isOwnPost: boolean): Promise<void>;
2915
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MobileCommunityPageComponent, never>;
2916
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<MobileCommunityPageComponent, "app-mobile-community-page", never, {}, {}, never, never, true, never>;
2917
+ }
2918
+
2919
+ declare class MobileHandbookPageComponent {
2920
+ userService: UserService;
2921
+ utilitiesItems: HandbookItem[];
2922
+ sikkerhedsudstyrItems: HandbookItem[];
2923
+ serviceContractsItems: HandbookItem[];
2924
+ equipmentItems: HandbookItem[];
2925
+ constructor(userService: UserService);
2926
+ handleRefresh(event: any): void;
2927
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MobileHandbookPageComponent, never>;
2928
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<MobileHandbookPageComponent, "app-mobile-handbook-page", never, {}, {}, never, never, true, never>;
2929
+ }
2930
+
2931
+ declare class MobileHomePageComponent {
2932
+ private navCtrl;
2933
+ userService: UserService;
2934
+ constructor(navCtrl: NavController, userService: UserService);
2935
+ handleRefresh(event: any): void;
2936
+ navigateToDetail(): void;
2937
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MobileHomePageComponent, never>;
2938
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<MobileHomePageComponent, "app-home-page", never, {}, {}, never, never, true, never>;
2939
+ }
2940
+
2941
+ interface TabItem {
2942
+ id: string;
2943
+ label: string;
2944
+ badge?: number;
2945
+ }
2946
+
2947
+ interface Inquiry {
2948
+ id: string;
2949
+ title: string;
2950
+ description: string;
2951
+ status: 'open' | 'closed';
2952
+ timestamp: string;
2953
+ category: 'maintenance' | 'plumbing' | 'electrical' | 'heating' | 'security' | 'appliance' | 'other';
2954
+ }
2955
+ declare class MobileInquiriesPageComponent {
2956
+ userService: UserService;
2957
+ private navCtrl;
2958
+ constructor(userService: UserService, navCtrl: NavController);
2959
+ filterStatus: _angular_core.WritableSignal<"open" | "closed" | "all">;
2960
+ tabItems: TabItem[];
2961
+ inquiries: _angular_core.WritableSignal<Inquiry[]>;
2962
+ filteredInquiries: _angular_core.Signal<Inquiry[]>;
2963
+ openInquiries: _angular_core.Signal<Inquiry[]>;
2964
+ closedInquiries: _angular_core.Signal<Inquiry[]>;
2965
+ setFilter(status: 'all' | 'open' | 'closed'): void;
2966
+ getInquiryIcon(category: string): string;
2967
+ openInquiryDetail(inquiryId: string): void;
2968
+ showInquiryActions(inquiryId: string): void;
2969
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MobileInquiriesPageComponent, never>;
2970
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<MobileInquiriesPageComponent, "app-mobile-inquiries-page", never, {}, {}, never, never, true, never>;
2971
+ }
2972
+
2973
+ interface ActivityItem {
2974
+ id: string;
2975
+ type: 'assignment' | 'status_change' | 'creation';
2976
+ actor?: string;
2977
+ actorInitials?: string;
2978
+ title: string;
2979
+ description?: string;
2980
+ timestamp: string;
2981
+ date: string;
2982
+ iconName: string;
2983
+ iconBgColor?: string;
2984
+ }
2985
+ interface MessageThread {
2986
+ id: string;
2987
+ senderName: string;
2988
+ senderAvatar: string;
2989
+ senderInitials: string;
2990
+ message: string;
2991
+ role: string;
2992
+ timestamp: string;
2993
+ unread: boolean;
2994
+ }
2995
+ declare class MobileInquiryDetailPageComponent extends MobilePageBase implements AfterViewInit {
2996
+ userService: UserService;
2997
+ private navCtrl;
2998
+ private elementRef;
2999
+ ionContent?: IonContent;
3000
+ private platform;
3001
+ isNativePlatform: _angular_core.Signal<boolean>;
3002
+ inquiryTitle: string;
3003
+ activeTab: _angular_core.WritableSignal<string>;
3004
+ tabItems: TabItem[];
3005
+ activities: ActivityItem[];
3006
+ messageThreads: MessageThread[];
3007
+ unreadMessagesCount: _angular_core.Signal<number>;
3008
+ constructor(userService: UserService, navCtrl: NavController, elementRef: ElementRef);
3009
+ ngAfterViewInit(): void;
3010
+ setActiveTab(tabId: string): void;
3011
+ goBack(): void;
3012
+ handleScroll(event: any): void;
3013
+ handleRefresh(event: any): void;
3014
+ openMessage(messageId: string): void;
3015
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MobileInquiryDetailPageComponent, never>;
3016
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<MobileInquiryDetailPageComponent, "app-mobile-inquiry-detail-page", never, {}, {}, never, never, true, never>;
3017
+ }
3018
+
3019
+ interface TabConfig {
3020
+ id: string;
3021
+ label: string;
3022
+ route: string;
3023
+ icon: string;
3024
+ iconActive: string;
3025
+ }
3026
+
3027
+ declare class MobileTabsExampleComponent implements OnInit {
3028
+ userService: UserService;
3029
+ private modalController;
3030
+ private router;
3031
+ constructor(userService: UserService, modalController: ModalController, router: Router);
3032
+ ngOnInit(): void;
3033
+ tabs: TabConfig[];
3034
+ handleAvatarClick(): Promise<void>;
3035
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MobileTabsExampleComponent, never>;
3036
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<MobileTabsExampleComponent, "app-mobile-tabs-example", never, {}, {}, never, never, true, never>;
3037
+ }
3038
+
3039
+ /**
3040
+ * PostCreatePageComponent
3041
+ *
3042
+ * Full-screen detail page for creating new posts in the community feed.
3043
+ * Features Threads-inspired interface with rich text editing capabilities.
3044
+ */
3045
+ declare class PostCreatePageComponent implements AfterViewInit, OnInit {
3046
+ private router;
3047
+ private route;
3048
+ userService: UserService;
3049
+ textareaInput?: ElementRef<HTMLTextAreaElement>;
3050
+ postContent: string;
3051
+ username: _angular_core.WritableSignal<string>;
3052
+ placeholder: _angular_core.WritableSignal<string>;
3053
+ isEditMode: _angular_core.WritableSignal<boolean>;
3054
+ postId: _angular_core.WritableSignal<string | null>;
3055
+ pageTitle: _angular_core.WritableSignal<string>;
3056
+ submitButtonLabel: _angular_core.WritableSignal<string>;
3057
+ constructor(router: Router, route: ActivatedRoute, userService: UserService);
3058
+ ngOnInit(): void;
3059
+ ngAfterViewInit(): void;
3060
+ handleInput(): void;
3061
+ canPost(): boolean;
3062
+ handleCancel(): void;
3063
+ handlePost(): void;
3064
+ handleAddImage(): void;
3065
+ handleAddEmoji(): void;
3066
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<PostCreatePageComponent, never>;
3067
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<PostCreatePageComponent, "app-post-create-page", never, {}, {}, never, never, true, never>;
3068
+ }
3069
+
3070
+ declare class MobilePostDetailPageComponent {
3071
+ private lightbox;
3072
+ private bottomSheet;
3073
+ repliesCount: number;
3074
+ constructor(lightbox: DsMobileLightboxService, bottomSheet: DsMobileBottomSheetService);
3075
+ /**
3076
+ * Open an image in the lightbox viewer
3077
+ */
3078
+ openImageLightbox(imageSrc: string, title: string, description: string): void;
3079
+ /**
3080
+ * Handle long press on a comment to show action sheet
3081
+ */
3082
+ handleCommentLongPress(authorName: string, content: string, isOwnComment: boolean): Promise<void>;
3083
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MobilePostDetailPageComponent, never>;
3084
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<MobilePostDetailPageComponent, "app-mobile-post-detail-page", never, {}, {}, never, never, true, never>;
3085
+ }
3086
+
3087
+ interface WhitelabelConfig {
3088
+ logoUrl: string;
3089
+ logoMarkUrl: string;
3090
+ logoAlt: string;
3091
+ logoWidth?: number;
3092
+ logoHeight?: number;
3093
+ logoMarkWidth?: number;
3094
+ logoMarkHeight?: number;
3095
+ primaryColor: string;
3096
+ secondaryColor: string;
3097
+ organizationName: string;
3098
+ organizationId: string;
3099
+ }
3100
+ /**
3101
+ * WhitelabelService
3102
+ *
3103
+ * Manages whitelabel configuration including logos and brand colors.
3104
+ * Automatically updates CSS custom properties when colors change.
3105
+ *
3106
+ * @example
3107
+ * Initialize with custom config:
3108
+ * ```typescript
3109
+ * whitelabelService.initialize({
3110
+ * logoUrl: '/assets/logos/acme-logo.svg',
3111
+ * logoMarkUrl: '/assets/logos/acme-mark.svg',
3112
+ * primaryColor: '#2563eb',
3113
+ * secondaryColor: '#3b82f6',
3114
+ * organizationName: 'Acme Corp'
3115
+ * });
3116
+ * ```
3117
+ *
3118
+ * Load from API:
3119
+ * ```typescript
3120
+ * await whitelabelService.loadFromApi('acme-corp');
3121
+ * ```
3122
+ */
3123
+ declare class WhitelabelService {
3124
+ private _config;
3125
+ readonly logoUrl: () => string;
3126
+ readonly logoMarkUrl: () => string;
3127
+ readonly logoAlt: () => string;
3128
+ readonly primaryColor: () => string;
3129
+ readonly secondaryColor: () => string;
3130
+ readonly organizationName: () => string;
3131
+ readonly organizationId: () => string;
3132
+ readonly config: _angular_core.Signal<WhitelabelConfig>;
3133
+ constructor();
3134
+ /**
3135
+ * Initialize whitelabel configuration
3136
+ * Call this early in app initialization (app.config.ts or app.component.ts)
3137
+ */
3138
+ initialize(config: Partial<WhitelabelConfig>): void;
3139
+ /**
3140
+ * Load whitelabel config from API
3141
+ * Typically called on app startup based on subdomain, user tenant, etc.
3142
+ *
3143
+ * @param organizationId - The organization identifier (subdomain, tenant ID, etc.)
3144
+ */
3145
+ loadFromApi(organizationId?: string): Promise<void>;
3146
+ /**
3147
+ * Update config dynamically (e.g., when user switches organizations)
3148
+ */
3149
+ updateConfig(updates: Partial<WhitelabelConfig>): void;
3150
+ /**
3151
+ * Update only the brand colors
3152
+ */
3153
+ updateColors(primaryColor: string, secondaryColor: string): void;
3154
+ /**
3155
+ * Reset to default configuration
3156
+ */
3157
+ resetToDefault(): void;
3158
+ /**
3159
+ * Apply colors to CSS custom properties
3160
+ * This updates the actual CSS variables used throughout the app
3161
+ */
3162
+ private applyColors;
3163
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<WhitelabelService, never>;
3164
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<WhitelabelService>;
3165
+ }
3166
+
3167
+ /**
3168
+ * Whitelabel Demo Page
3169
+ *
3170
+ * Demonstrates the whitelabeling system with live color and logo switching.
3171
+ */
3172
+ declare class WhitelabelDemoPage implements OnInit {
3173
+ whitelabelService: WhitelabelService;
3174
+ customPrimaryColor: string;
3175
+ customSecondaryColor: string;
3176
+ uploadedFullLogoName: string;
3177
+ uploadedLogomarkName: string;
3178
+ ngOnInit(): void;
3179
+ handleFullLogoUpload(event: Event): void;
3180
+ handleLogomarkUpload(event: Event): void;
3181
+ resetFullLogo(): void;
3182
+ resetLogomark(): void;
3183
+ configJson(): string;
3184
+ applyDefaultTheme(): void;
3185
+ applyBlueTheme(): void;
3186
+ applyGreenTheme(): void;
3187
+ applyOrangeTheme(): void;
3188
+ applyCustomColors(): void;
3189
+ private updateCustomColorInputs;
3190
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<WhitelabelDemoPage, never>;
3191
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<WhitelabelDemoPage, "app-whitelabel-demo", never, {}, {}, never, never, true, never>;
3192
+ }
3193
+
3194
+ /**
3195
+ * Custom page transition - iOS-style push/pop
3196
+ *
3197
+ * FORWARD (navigating TO detail):
3198
+ * - Entering page (detail): slides in from RIGHT, z-index 10 (on top)
3199
+ * - Leaving page (list): slides LEFT slightly, z-index 9 (underneath)
3200
+ *
3201
+ * REVERSE (swipe back FROM detail):
3202
+ * - Entering page (list): slides in from LEFT, z-index 9 (underneath)
3203
+ * - Leaving page (detail): slides out to RIGHT, z-index 10 (on top)
3204
+ */
3205
+ declare const customPageTransition: (_: HTMLElement, opts: any) => Animation;
3206
+ /**
3207
+ * Custom back transition - iOS style where page slides out to reveal page underneath
3208
+ * The entering page (inquiries) slides in from the LEFT underneath
3209
+ * The leaving page (detail) slides out to the RIGHT on top
3210
+ */
3211
+ declare const customBackTransition: (_: HTMLElement, opts: any) => Animation;
3212
+
3213
+ export { ActionCommentComponent, ActionLikeComponent, ContentRowComponent, DsMobileActionsBottomSheetComponent, DsMobileAppLayoutComponent, DsMobileBottomSheetService, DsMobileActionsBottomSheetComponent as DsMobileCommentActionsBottomSheetComponent, DsMobileCommentComponent, DsMobileContactListItemComponent, DsMobileContentComponent, DsMobileContentSectionComponent, DsMobileHandbookFolderComponent, DsMobileHandbookFolderMiniComponent, DsMobileHeaderContentComponent, DsMobileHeaderContentTileComponent, DsMobileInlinePhotoComponent, DsMobileInteractiveListItemInquiryComponent, DsMobileInteractiveListItemMessageComponent, DsMobileInteractiveListItemPostComponent, DsMobileLightboxImageComponent as DsMobileLightboxComponent, DsMobileLightboxFooterComponent, DsMobileLightboxHeaderComponent, DsMobileLightboxImageComponent, DsMobileLightboxPdfComponent, DsMobileLightboxService, DsMobileListItemComponent, DsMobileLongPressDirective, DsMobileModalService, DsMobilePageDetailsComponent, DsMobilePageMainComponent, DsMobileActionsBottomSheetComponent as DsMobilePostActionsBottomSheetComponent, DsMobilePostCardComponent, DsMobilePostComposerComponent, DsMobilePostCreateBottomSheetComponent, DsMobilePostDetailModalComponent, DsMobilePostDetailModalService, DsMobileTabsComponent, MobileCommunityPageComponent, MobileHandbookPageComponent, MobileHomePageComponent, MobileInquiriesPageComponent, MobileInquiryDetailPageComponent, MobilePageBase, MobilePostDetailPageComponent, MobileTabsExampleComponent, PostActionsComponent, PostAttachmentsComponent, PostContentComponent, PostCreatePageComponent, PostMediaComponent, PostPdfAttachmentComponent, PostTextComponent, SectionHeaderComponent, TileContentComponent, TileIconComponent, TileLabelComponent, TileValueComponent, UserService, WhitelabelDemoPage, customBackTransition, customPageTransition };
3214
+ export type { ActionGroup, ActionItem, ActionResult, BottomSheetOptions, ActionResult as CommentActionResult, CommentData, ContentWidth, HeaderVariant, LightboxAuthor, LightboxImage, LightboxImageOptions, LightboxMediaFile, LightboxMediaType, LightboxOptions, LightboxPdf, LightboxPdfOptions, ModalOptions, ActionResult as PostActionResult, PostDetailData, TabConfig$1 as TabConfig };