@propbinder/mobile-design 0.1.16 → 0.1.17

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 CHANGED
@@ -1,6 +1,6 @@
1
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';
2
+ import { AfterViewInit, OnInit, ElementRef, OnDestroy, EventEmitter, ApplicationRef, EnvironmentInjector, Type } from '@angular/core';
3
+ import { ModalController, IonContent, NavController, GestureController } from '@ionic/angular/standalone';
4
4
  import { ImpactStyle } from '@capacitor/haptics';
5
5
  import { ControlValueAccessor } from '@angular/forms';
6
6
  import { Router, ActivatedRoute } from '@angular/router';
@@ -62,6 +62,237 @@ declare abstract class MobilePageBase {
62
62
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<MobilePageBase, never, never, { "contentWidth": { "alias": "contentWidth"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
63
63
  }
64
64
 
65
+ interface ActionResult {
66
+ action: string;
67
+ }
68
+ interface ActionItem {
69
+ action: string;
70
+ title: string;
71
+ icon: string;
72
+ destructive?: boolean;
73
+ }
74
+ interface ActionGroup {
75
+ actions: ActionItem[];
76
+ }
77
+ /**
78
+ * DsMobileActionsBottomSheetComponent
79
+ *
80
+ * Generic bottom sheet for displaying action lists.
81
+ * Supports custom action groups or preset content actions (posts/comments).
82
+ * Action groups are automatically separated by full-width dividers.
83
+ *
84
+ * @example Custom actions with auto-height (recommended to avoid cropping)
85
+ * ```typescript
86
+ * const sheet = await this.modalController.create({
87
+ * component: DsMobileActionsBottomSheetComponent,
88
+ * componentProps: {
89
+ * customActionGroups: [
90
+ * {
91
+ * actions: [
92
+ * { action: 'profile', title: 'Min profil', icon: 'remixUser3Line' },
93
+ * { action: 'settings', title: 'Indstillinger', icon: 'remixSettings3Line' }
94
+ * ]
95
+ * },
96
+ * {
97
+ * actions: [
98
+ * { action: 'logout', title: 'Log ud', icon: 'remixLogoutBoxLine', destructive: true }
99
+ * ]
100
+ * }
101
+ * ]
102
+ * },
103
+ * breakpoints: [0, 1],
104
+ * initialBreakpoint: 1,
105
+ * handle: true,
106
+ * cssClass: 'auto-height'
107
+ * });
108
+ *
109
+ * const result = await sheet.onWillDismiss();
110
+ * if (result.data?.action) {
111
+ * // Handle the action
112
+ * }
113
+ * ```
114
+ *
115
+ * @example Preset content actions
116
+ * ```typescript
117
+ * const sheet = await this.modalController.create({
118
+ * component: DsMobileActionsBottomSheetComponent,
119
+ * componentProps: {
120
+ * isOwnContent: false
121
+ * },
122
+ * breakpoints: [0, 1],
123
+ * initialBreakpoint: 1,
124
+ * handle: true,
125
+ * cssClass: 'auto-height'
126
+ * });
127
+ * ```
128
+ */
129
+ declare class DsMobileActionsBottomSheetComponent {
130
+ private modalController;
131
+ /**
132
+ * Custom action groups to display (overrides isOwnContent)
133
+ */
134
+ customActionGroups?: ActionGroup[];
135
+ /**
136
+ * Whether this content belongs to the current user (for preset content actions)
137
+ */
138
+ isOwnContent: boolean;
139
+ /**
140
+ * Computed action groups - uses custom groups if provided, otherwise falls back to preset content actions
141
+ */
142
+ actionGroups: _angular_core.Signal<ActionGroup[]>;
143
+ constructor(modalController: ModalController);
144
+ /**
145
+ * Handle action selection and dismiss with result
146
+ */
147
+ selectAction(action: string): void;
148
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileActionsBottomSheetComponent, never>;
149
+ 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>;
150
+ }
151
+
152
+ /**
153
+ * Configuration options for the bottom sheet modal
154
+ */
155
+ interface BottomSheetOptions {
156
+ /** The component to display in the bottom sheet */
157
+ component: any;
158
+ /** Component props to pass to the modal content */
159
+ componentProps?: {
160
+ [key: string]: any;
161
+ };
162
+ /** Breakpoints for the bottom sheet (0-1 values representing percentage of screen) */
163
+ breakpoints?: number[];
164
+ /** Initial breakpoint to open the sheet at */
165
+ initialBreakpoint?: number;
166
+ /** Show/hide the drag handle */
167
+ handle?: boolean;
168
+ /** Custom CSS class for styling */
169
+ cssClass?: string | string[];
170
+ /** Whether backdrop dismisses the modal */
171
+ backdropDismiss?: boolean;
172
+ /** Backdrop opacity (0-1) */
173
+ backdropOpacity?: number;
174
+ /** Enable backdrop blur effect */
175
+ backdropBlur?: boolean;
176
+ /** Keyboard close behavior */
177
+ keyboardClose?: boolean;
178
+ /** Auto-height mode: sheet sizes to content instead of using fixed breakpoints */
179
+ autoHeight?: boolean;
180
+ }
181
+ /**
182
+ * DsMobileBottomSheetService
183
+ *
184
+ * Service for creating and managing Ionic 6 bottom sheet modals.
185
+ * Based on the Ionic blog article: https://ionic.io/blog/5-examples-of-the-new-ionic-6-bottom-sheet-modal
186
+ *
187
+ * Features:
188
+ * - Multiple breakpoints for snap-to positions
189
+ * - Customizable initial height
190
+ * - Optional drag handle
191
+ * - Backdrop blur effect
192
+ * - Custom styling support
193
+ *
194
+ * @example
195
+ * ```typescript
196
+ * constructor(private bottomSheet: DsMobileBottomSheetService) {}
197
+ *
198
+ * async openSheet() {
199
+ * const sheet = await this.bottomSheet.create({
200
+ * component: PostCreateComponent,
201
+ * breakpoints: [0, 0.5, 0.9],
202
+ * initialBreakpoint: 0.5,
203
+ * handle: true
204
+ * });
205
+ *
206
+ * const result = await sheet.onWillDismiss();
207
+ * console.log('Sheet dismissed with:', result.data);
208
+ * }
209
+ * ```
210
+ */
211
+ declare class DsMobileBottomSheetService {
212
+ private modalController;
213
+ constructor(modalController: ModalController);
214
+ /**
215
+ * Create and present a bottom sheet modal
216
+ *
217
+ * @param options Configuration options for the bottom sheet
218
+ * @returns Promise that resolves to the modal instance
219
+ */
220
+ create(options: BottomSheetOptions): Promise<HTMLIonModalElement>;
221
+ /**
222
+ * Dismiss all open modals
223
+ */
224
+ dismiss(data?: any, role?: string): Promise<boolean>;
225
+ /**
226
+ * Get the top-most modal overlay
227
+ */
228
+ getTop(): Promise<HTMLIonModalElement | undefined>;
229
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileBottomSheetService, never>;
230
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<DsMobileBottomSheetService>;
231
+ }
232
+
233
+ /**
234
+ * DsMobilePostCreateBottomSheetComponent
235
+ *
236
+ * Bottom sheet modal for creating new posts in the community feed.
237
+ * This is the modal content that gets displayed in the bottom sheet.
238
+ * Features Threads-inspired interface with rich text editing capabilities.
239
+ *
240
+ * Auto-focuses the textarea and brings up the keyboard when opened.
241
+ *
242
+ * Usage: Use with DsMobileBottomSheetService to present as a bottom sheet
243
+ */
244
+ declare class DsMobilePostCreateBottomSheetComponent implements AfterViewInit, OnInit {
245
+ private modalController;
246
+ private elementRef;
247
+ textareaInput?: ElementRef<HTMLTextAreaElement>;
248
+ fileInput?: ElementRef<HTMLInputElement>;
249
+ autoFocus: boolean;
250
+ isReadonly: boolean;
251
+ isEditMode: boolean;
252
+ postId?: string;
253
+ initialContent: string;
254
+ postContent: string;
255
+ selectedImages: _angular_core.WritableSignal<string[]>;
256
+ username: _angular_core.WritableSignal<string>;
257
+ placeholder: _angular_core.WritableSignal<string>;
258
+ modalTitle: _angular_core.WritableSignal<string>;
259
+ submitButtonLabel: _angular_core.WritableSignal<string>;
260
+ constructor(modalController: ModalController, elementRef: ElementRef);
261
+ /**
262
+ * Ensure toolbar doesn't have unnecessary padding
263
+ * Modal is already positioned below status bar, so no extra safe area needed
264
+ */
265
+ private applySafeAreaToToolbar;
266
+ ngOnInit(): void;
267
+ ngAfterViewInit(): void;
268
+ /**
269
+ * Ionic lifecycle hook - called when modal enters view
270
+ * At 95% height, this acts more like a page than a modal
271
+ * which might allow keyboard to open
272
+ */
273
+ ionViewDidEnter(): void;
274
+ handleFocus(): void;
275
+ handleInput(): void;
276
+ /**
277
+ * Auto-resize textarea based on content
278
+ */
279
+ private resizeTextarea;
280
+ canPost(): boolean;
281
+ handleCancel(): Promise<void>;
282
+ handlePost(): Promise<void>;
283
+ handleAddImage(): Promise<void>;
284
+ /**
285
+ * Restore StatusBar configuration (background task)
286
+ * Safe area padding is now handled preventively via applySafeAreaToToolbar()
287
+ */
288
+ private restoreStatusBar;
289
+ handleRemoveImage(index: number): void;
290
+ handleAddAttachment(): void;
291
+ handleFileSelect(event: Event): void;
292
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobilePostCreateBottomSheetComponent, never>;
293
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobilePostCreateBottomSheetComponent, "ds-mobile-post-create-bottom-sheet", never, {}, {}, never, never, true, never>;
294
+ }
295
+
65
296
  /**
66
297
  * DsMobilePageMainComponent
67
298
  *
@@ -106,7 +337,7 @@ declare class DsMobilePageMainComponent extends MobilePageBase implements AfterV
106
337
  private platform;
107
338
  private modalController;
108
339
  private router;
109
- private whitelabelDemoModal;
340
+ private userService;
110
341
  isNativePlatform: _angular_core.Signal<boolean>;
111
342
  title: _angular_core.InputSignal<string>;
112
343
  headerTitle: _angular_core.InputSignal<string>;
@@ -119,7 +350,34 @@ declare class DsMobilePageMainComponent extends MobilePageBase implements AfterV
119
350
  showCondensedHeader: _angular_core.InputSignal<boolean>;
120
351
  scrollThreshold: _angular_core.InputSignal<number>;
121
352
  headerFadeDistance: _angular_core.InputSignal<number>;
353
+ /**
354
+ * Profile menu action groups to display when avatar is clicked.
355
+ * If not provided, a default menu will be used (without Whitelabel Demo).
356
+ *
357
+ * @example
358
+ * ```typescript
359
+ * profileMenuItems: ActionGroup[] = [
360
+ * {
361
+ * actions: [
362
+ * { action: 'profile', title: 'Min profil', icon: 'remixUser3Line' },
363
+ * { action: 'settings', title: 'Indstillinger', icon: 'remixSettings3Line' }
364
+ * ]
365
+ * },
366
+ * {
367
+ * actions: [
368
+ * { action: 'logout', title: 'Log ud', icon: 'remixLogoutBoxLine', destructive: true }
369
+ * ]
370
+ * }
371
+ * ];
372
+ * ```
373
+ */
374
+ profileMenuItems: _angular_core.InputSignal<ActionGroup[] | undefined>;
122
375
  avatarClick: _angular_core.OutputEmitterRef<void>;
376
+ /**
377
+ * Emitted when a profile menu action is selected.
378
+ * Parent component should handle the action logic (navigation, logout, etc.).
379
+ */
380
+ profileActionSelected: _angular_core.OutputEmitterRef<ActionResult>;
123
381
  refresh: _angular_core.OutputEmitterRef<any>;
124
382
  scroll: _angular_core.OutputEmitterRef<any>;
125
383
  constructor(elementRef: ElementRef);
@@ -141,7 +399,7 @@ declare class DsMobilePageMainComponent extends MobilePageBase implements AfterV
141
399
  */
142
400
  handleRefresh(event: any): Promise<void>;
143
401
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobilePageMainComponent, never>;
144
- 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>;
402
+ 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; }; "profileMenuItems": { "alias": "profileMenuItems"; "required": false; "isSignal": true; }; }, { "avatarClick": "avatarClick"; "profileActionSelected": "profileActionSelected"; "refresh": "refresh"; "scroll": "scroll"; }, never, ["[header-content]", "*"], true, never>;
145
403
  }
146
404
 
147
405
  /**
@@ -1304,237 +1562,6 @@ declare class DsMobileContactListItemComponent {
1304
1562
  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>;
1305
1563
  }
1306
1564
 
1307
- interface ActionResult {
1308
- action: string;
1309
- }
1310
- interface ActionItem {
1311
- action: string;
1312
- title: string;
1313
- icon: string;
1314
- destructive?: boolean;
1315
- }
1316
- interface ActionGroup {
1317
- actions: ActionItem[];
1318
- }
1319
- /**
1320
- * DsMobileActionsBottomSheetComponent
1321
- *
1322
- * Generic bottom sheet for displaying action lists.
1323
- * Supports custom action groups or preset content actions (posts/comments).
1324
- * Action groups are automatically separated by full-width dividers.
1325
- *
1326
- * @example Custom actions with auto-height (recommended to avoid cropping)
1327
- * ```typescript
1328
- * const sheet = await this.modalController.create({
1329
- * component: DsMobileActionsBottomSheetComponent,
1330
- * componentProps: {
1331
- * customActionGroups: [
1332
- * {
1333
- * actions: [
1334
- * { action: 'profile', title: 'Min profil', icon: 'remixUser3Line' },
1335
- * { action: 'settings', title: 'Indstillinger', icon: 'remixSettings3Line' }
1336
- * ]
1337
- * },
1338
- * {
1339
- * actions: [
1340
- * { action: 'logout', title: 'Log ud', icon: 'remixLogoutBoxLine', destructive: true }
1341
- * ]
1342
- * }
1343
- * ]
1344
- * },
1345
- * breakpoints: [0, 1],
1346
- * initialBreakpoint: 1,
1347
- * handle: true,
1348
- * cssClass: 'auto-height'
1349
- * });
1350
- *
1351
- * const result = await sheet.onWillDismiss();
1352
- * if (result.data?.action) {
1353
- * // Handle the action
1354
- * }
1355
- * ```
1356
- *
1357
- * @example Preset content actions
1358
- * ```typescript
1359
- * const sheet = await this.modalController.create({
1360
- * component: DsMobileActionsBottomSheetComponent,
1361
- * componentProps: {
1362
- * isOwnContent: false
1363
- * },
1364
- * breakpoints: [0, 1],
1365
- * initialBreakpoint: 1,
1366
- * handle: true,
1367
- * cssClass: 'auto-height'
1368
- * });
1369
- * ```
1370
- */
1371
- declare class DsMobileActionsBottomSheetComponent {
1372
- private modalController;
1373
- /**
1374
- * Custom action groups to display (overrides isOwnContent)
1375
- */
1376
- customActionGroups?: ActionGroup[];
1377
- /**
1378
- * Whether this content belongs to the current user (for preset content actions)
1379
- */
1380
- isOwnContent: boolean;
1381
- /**
1382
- * Computed action groups - uses custom groups if provided, otherwise falls back to preset content actions
1383
- */
1384
- actionGroups: _angular_core.Signal<ActionGroup[]>;
1385
- constructor(modalController: ModalController);
1386
- /**
1387
- * Handle action selection and dismiss with result
1388
- */
1389
- selectAction(action: string): void;
1390
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileActionsBottomSheetComponent, never>;
1391
- 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>;
1392
- }
1393
-
1394
- /**
1395
- * Configuration options for the bottom sheet modal
1396
- */
1397
- interface BottomSheetOptions {
1398
- /** The component to display in the bottom sheet */
1399
- component: any;
1400
- /** Component props to pass to the modal content */
1401
- componentProps?: {
1402
- [key: string]: any;
1403
- };
1404
- /** Breakpoints for the bottom sheet (0-1 values representing percentage of screen) */
1405
- breakpoints?: number[];
1406
- /** Initial breakpoint to open the sheet at */
1407
- initialBreakpoint?: number;
1408
- /** Show/hide the drag handle */
1409
- handle?: boolean;
1410
- /** Custom CSS class for styling */
1411
- cssClass?: string | string[];
1412
- /** Whether backdrop dismisses the modal */
1413
- backdropDismiss?: boolean;
1414
- /** Backdrop opacity (0-1) */
1415
- backdropOpacity?: number;
1416
- /** Enable backdrop blur effect */
1417
- backdropBlur?: boolean;
1418
- /** Keyboard close behavior */
1419
- keyboardClose?: boolean;
1420
- /** Auto-height mode: sheet sizes to content instead of using fixed breakpoints */
1421
- autoHeight?: boolean;
1422
- }
1423
- /**
1424
- * DsMobileBottomSheetService
1425
- *
1426
- * Service for creating and managing Ionic 6 bottom sheet modals.
1427
- * Based on the Ionic blog article: https://ionic.io/blog/5-examples-of-the-new-ionic-6-bottom-sheet-modal
1428
- *
1429
- * Features:
1430
- * - Multiple breakpoints for snap-to positions
1431
- * - Customizable initial height
1432
- * - Optional drag handle
1433
- * - Backdrop blur effect
1434
- * - Custom styling support
1435
- *
1436
- * @example
1437
- * ```typescript
1438
- * constructor(private bottomSheet: DsMobileBottomSheetService) {}
1439
- *
1440
- * async openSheet() {
1441
- * const sheet = await this.bottomSheet.create({
1442
- * component: PostCreateComponent,
1443
- * breakpoints: [0, 0.5, 0.9],
1444
- * initialBreakpoint: 0.5,
1445
- * handle: true
1446
- * });
1447
- *
1448
- * const result = await sheet.onWillDismiss();
1449
- * console.log('Sheet dismissed with:', result.data);
1450
- * }
1451
- * ```
1452
- */
1453
- declare class DsMobileBottomSheetService {
1454
- private modalController;
1455
- constructor(modalController: ModalController);
1456
- /**
1457
- * Create and present a bottom sheet modal
1458
- *
1459
- * @param options Configuration options for the bottom sheet
1460
- * @returns Promise that resolves to the modal instance
1461
- */
1462
- create(options: BottomSheetOptions): Promise<HTMLIonModalElement>;
1463
- /**
1464
- * Dismiss all open modals
1465
- */
1466
- dismiss(data?: any, role?: string): Promise<boolean>;
1467
- /**
1468
- * Get the top-most modal overlay
1469
- */
1470
- getTop(): Promise<HTMLIonModalElement | undefined>;
1471
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobileBottomSheetService, never>;
1472
- static ɵprov: _angular_core.ɵɵInjectableDeclaration<DsMobileBottomSheetService>;
1473
- }
1474
-
1475
- /**
1476
- * DsMobilePostCreateBottomSheetComponent
1477
- *
1478
- * Bottom sheet modal for creating new posts in the community feed.
1479
- * This is the modal content that gets displayed in the bottom sheet.
1480
- * Features Threads-inspired interface with rich text editing capabilities.
1481
- *
1482
- * Auto-focuses the textarea and brings up the keyboard when opened.
1483
- *
1484
- * Usage: Use with DsMobileBottomSheetService to present as a bottom sheet
1485
- */
1486
- declare class DsMobilePostCreateBottomSheetComponent implements AfterViewInit, OnInit {
1487
- private modalController;
1488
- private elementRef;
1489
- textareaInput?: ElementRef<HTMLTextAreaElement>;
1490
- fileInput?: ElementRef<HTMLInputElement>;
1491
- autoFocus: boolean;
1492
- isReadonly: boolean;
1493
- isEditMode: boolean;
1494
- postId?: string;
1495
- initialContent: string;
1496
- postContent: string;
1497
- selectedImages: _angular_core.WritableSignal<string[]>;
1498
- username: _angular_core.WritableSignal<string>;
1499
- placeholder: _angular_core.WritableSignal<string>;
1500
- modalTitle: _angular_core.WritableSignal<string>;
1501
- submitButtonLabel: _angular_core.WritableSignal<string>;
1502
- constructor(modalController: ModalController, elementRef: ElementRef);
1503
- /**
1504
- * Ensure toolbar doesn't have unnecessary padding
1505
- * Modal is already positioned below status bar, so no extra safe area needed
1506
- */
1507
- private applySafeAreaToToolbar;
1508
- ngOnInit(): void;
1509
- ngAfterViewInit(): void;
1510
- /**
1511
- * Ionic lifecycle hook - called when modal enters view
1512
- * At 95% height, this acts more like a page than a modal
1513
- * which might allow keyboard to open
1514
- */
1515
- ionViewDidEnter(): void;
1516
- handleFocus(): void;
1517
- handleInput(): void;
1518
- /**
1519
- * Auto-resize textarea based on content
1520
- */
1521
- private resizeTextarea;
1522
- canPost(): boolean;
1523
- handleCancel(): Promise<void>;
1524
- handlePost(): Promise<void>;
1525
- handleAddImage(): Promise<void>;
1526
- /**
1527
- * Restore StatusBar configuration (background task)
1528
- * Safe area padding is now handled preventively via applySafeAreaToToolbar()
1529
- */
1530
- private restoreStatusBar;
1531
- handleRemoveImage(index: number): void;
1532
- handleAddAttachment(): void;
1533
- handleFileSelect(event: Event): void;
1534
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<DsMobilePostCreateBottomSheetComponent, never>;
1535
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<DsMobilePostCreateBottomSheetComponent, "ds-mobile-post-create-bottom-sheet", never, {}, {}, never, never, true, never>;
1536
- }
1537
-
1538
1565
  interface TabConfig {
1539
1566
  id: string;
1540
1567
  label: string;
@@ -1639,6 +1666,7 @@ declare class DsMobileTabBarComponent implements OnInit, AfterViewInit, OnDestro
1639
1666
  private routerSubscription?;
1640
1667
  private router?;
1641
1668
  private modalController;
1669
+ private userService;
1642
1670
  constructor(elementRef: ElementRef);
1643
1671
  ngOnInit(): void;
1644
1672
  ngAfterViewInit(): void;
@@ -3157,7 +3185,7 @@ declare class DsMobileHandbookFolderMiniComponent {
3157
3185
  * ```
3158
3186
  */
3159
3187
  declare class DsTextInputComponent implements ControlValueAccessor {
3160
- type: _angular_core.InputSignal<"text" | "email" | "tel" | "password" | "url" | "search">;
3188
+ type: _angular_core.InputSignal<"search" | "text" | "email" | "tel" | "password" | "url">;
3161
3189
  placeholder: _angular_core.InputSignal<string>;
3162
3190
  disabled: _angular_core.InputSignal<boolean>;
3163
3191
  readonly: _angular_core.InputSignal<boolean>;
@@ -3165,7 +3193,7 @@ declare class DsTextInputComponent implements ControlValueAccessor {
3165
3193
  hasError: _angular_core.InputSignal<boolean>;
3166
3194
  errorMessage: _angular_core.InputSignal<string>;
3167
3195
  autocomplete: _angular_core.InputSignal<string>;
3168
- inputmode: _angular_core.InputSignal<"text" | "email" | "tel" | "url" | "search" | "numeric" | undefined>;
3196
+ inputmode: _angular_core.InputSignal<"search" | "text" | "email" | "tel" | "url" | "numeric" | undefined>;
3169
3197
  autoClearError: _angular_core.InputSignal<boolean>;
3170
3198
  validator: _angular_core.InputSignal<((value: string) => boolean) | null>;
3171
3199
  valueChange: _angular_core.OutputEmitterRef<string>;
@@ -3199,15 +3227,23 @@ declare class UserService {
3199
3227
  private _avatarInitials;
3200
3228
  private _avatarType;
3201
3229
  private _avatarSrc;
3230
+ private _profileMenuItems;
3202
3231
  readonly avatarInitials: _angular_core.Signal<string>;
3203
3232
  readonly avatarType: _angular_core.Signal<"initials" | "photo" | "icon">;
3204
3233
  readonly avatarSrc: _angular_core.Signal<string>;
3234
+ readonly profileMenuItems: _angular_core.Signal<ActionGroup[] | undefined>;
3205
3235
  /**
3206
3236
  * Update avatar configuration
3207
3237
  */
3208
3238
  setAvatarInitials(initials: string): void;
3209
3239
  setAvatarType(type: 'initials' | 'photo' | 'icon'): void;
3210
3240
  setAvatarSrc(src: string): void;
3241
+ /**
3242
+ * Set profile menu items globally.
3243
+ * This will be used by both ds-mobile-tab-bar and ds-mobile-page-main
3244
+ * if they don't receive profileMenuItems as an input.
3245
+ */
3246
+ setProfileMenuItems(items: ActionGroup[]): void;
3211
3247
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UserService, never>;
3212
3248
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<UserService>;
3213
3249
  }
@@ -3363,7 +3399,9 @@ declare class MobileTabsExampleComponent implements OnInit {
3363
3399
  tabs: TabConfig[];
3364
3400
  /**
3365
3401
  * Profile menu items configuration.
3366
- * Define once here, and the tab bar component handles opening/closing the menu.
3402
+ * Define once here - this is set globally in UserService in ngOnInit(),
3403
+ * so it will be used by both ds-mobile-tab-bar and ds-mobile-page-main components
3404
+ * throughout the entire application.
3367
3405
  */
3368
3406
  profileMenuItems: ActionGroup[];
3369
3407
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@propbinder/mobile-design",
3
- "version": "0.1.16",
3
+ "version": "0.1.17",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^20.3.0 || ^21.0.0",
6
6
  "@angular/core": "^20.3.0 || ^21.0.0"