@propbinder/mobile-design 0.0.1

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