@propbinder/mobile-design 0.0.2 → 0.0.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/fesm2022/propbinder-mobile-design.mjs +12604 -0
  2. package/fesm2022/propbinder-mobile-design.mjs.map +1 -0
  3. package/index.d.ts +3214 -0
  4. package/package.json +39 -12
  5. package/ng-package.json +0 -7
  6. package/src/animations/page-transitions.ts +0 -86
  7. package/src/assets/fonts/Brockmann-Bold.otf +0 -0
  8. package/src/assets/fonts/Brockmann-BoldItalic.otf +0 -0
  9. package/src/assets/fonts/Brockmann-Medium.otf +0 -0
  10. package/src/assets/fonts/Brockmann-MediumItalic.otf +0 -0
  11. package/src/assets/fonts/Brockmann-Regular.otf +0 -0
  12. package/src/assets/fonts/Brockmann-RegularItalic.otf +0 -0
  13. package/src/assets/fonts/Brockmann-SemiBold.otf +0 -0
  14. package/src/assets/fonts/Brockmann-SemiBoldItalic.otf +0 -0
  15. package/src/assets/fonts/Brockmann_desktop_license.pdf +0 -0
  16. package/src/assets/fonts/brockmann-medium-webfont.woff2 +0 -0
  17. package/src/assets/fonts/brockmann-regular-webfont.woff2 +0 -0
  18. package/src/assets/fonts/brockmann-semibold-webfont.woff2 +0 -0
  19. package/src/components/action-list-item/ds-mobile-action-list-item.ts +0 -83
  20. package/src/components/action-list-item/index.ts +0 -2
  21. package/src/components/app-layout/ds-mobile-app-layout.css +0 -343
  22. package/src/components/app-layout/ds-mobile-app-layout.ts +0 -271
  23. package/src/components/app-layout/index.ts +0 -2
  24. package/src/components/avatar-with-badge/ds-avatar-with-badge.ts +0 -130
  25. package/src/components/avatar-with-badge/index.ts +0 -2
  26. package/src/components/bottom-sheet/ds-mobile-actions-bottom-sheet.ts +0 -273
  27. package/src/components/bottom-sheet/ds-mobile-bottom-sheet.css +0 -110
  28. package/src/components/bottom-sheet/ds-mobile-bottom-sheet.service.ts +0 -167
  29. package/src/components/bottom-sheet/ds-mobile-post-create-bottom-sheet.ts +0 -656
  30. package/src/components/bottom-sheet/index.ts +0 -3
  31. package/src/components/comment/ds-mobile-comment.ts +0 -516
  32. package/src/components/comment/index.ts +0 -2
  33. package/src/components/contact-list-item/ds-mobile-contact-list-item.ts +0 -182
  34. package/src/components/contact-list-item/index.ts +0 -2
  35. package/src/components/content/ds-mobile-content.ts +0 -158
  36. package/src/components/content/index.ts +0 -2
  37. package/src/components/ds-mobile-tabs.css +0 -372
  38. package/src/components/ds-mobile-tabs.ts +0 -217
  39. package/src/components/file-attachment/ds-mobile-file-attachment.ts +0 -164
  40. package/src/components/file-attachment/index.ts +0 -2
  41. package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.service.ts +0 -98
  42. package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.ts +0 -514
  43. package/src/components/handbook-detail-modal/index.ts +0 -3
  44. package/src/components/handbook-folder/ds-mobile-handbook-folder-mini.ts +0 -130
  45. package/src/components/handbook-folder/ds-mobile-handbook-folder.ts +0 -444
  46. package/src/components/handbook-folder/index.ts +0 -4
  47. package/src/components/header-content/ds-mobile-header-content.ts +0 -211
  48. package/src/components/header-content/index.ts +0 -2
  49. package/src/components/index.ts +0 -45
  50. package/src/components/inline-photo/ds-mobile-inline-photo.ts +0 -269
  51. package/src/components/inline-photo/index.ts +0 -1
  52. package/src/components/interactive-list-item-inquiry/ds-mobile-interactive-list-item-inquiry.css +0 -60
  53. package/src/components/interactive-list-item-inquiry/ds-mobile-interactive-list-item-inquiry.ts +0 -280
  54. package/src/components/interactive-list-item-inquiry/index.ts +0 -2
  55. package/src/components/interactive-list-item-message/ds-mobile-interactive-list-item-message.ts +0 -197
  56. package/src/components/interactive-list-item-message/index.ts +0 -2
  57. package/src/components/interactive-list-item-post/ds-mobile-interactive-list-item-post.css +0 -70
  58. package/src/components/interactive-list-item-post/ds-mobile-interactive-list-item-post.ts +0 -594
  59. package/src/components/interactive-list-item-post/ds-mobile-post-pdf-attachment.ts +0 -124
  60. package/src/components/interactive-list-item-post/index.ts +0 -13
  61. package/src/components/lightbox/ds-mobile-lightbox-footer.ts +0 -331
  62. package/src/components/lightbox/ds-mobile-lightbox-header.ts +0 -173
  63. package/src/components/lightbox/ds-mobile-lightbox-image.ts +0 -464
  64. package/src/components/lightbox/ds-mobile-lightbox-pdf.css +0 -375
  65. package/src/components/lightbox/ds-mobile-lightbox-pdf.ts +0 -374
  66. package/src/components/lightbox/ds-mobile-lightbox.css +0 -587
  67. package/src/components/lightbox/ds-mobile-lightbox.service.ts +0 -293
  68. package/src/components/lightbox/ds-mobile-lightbox.ts +0 -529
  69. package/src/components/lightbox/index.ts +0 -22
  70. package/src/components/list-item/ds-mobile-list-item.ts +0 -499
  71. package/src/components/list-item/index.ts +0 -2
  72. package/src/components/list-item-static/ds-mobile-list-item-static.ts +0 -133
  73. package/src/components/list-item-static/index.ts +0 -2
  74. package/src/components/logo/ds-logo.ts +0 -85
  75. package/src/components/logo/index.ts +0 -2
  76. package/src/components/modal/ds-mobile-modal.css +0 -163
  77. package/src/components/modal/ds-mobile-modal.service.ts +0 -329
  78. package/src/components/modal/index.ts +0 -8
  79. package/src/components/page-details/ds-mobile-page-details.css +0 -285
  80. package/src/components/page-details/ds-mobile-page-details.ts +0 -128
  81. package/src/components/page-details/index.ts +0 -2
  82. package/src/components/page-main/ds-mobile-page-main.css +0 -346
  83. package/src/components/page-main/ds-mobile-page-main.ts +0 -331
  84. package/src/components/page-main/index.ts +0 -2
  85. package/src/components/post-card/ds-mobile-post-card.ts +0 -685
  86. package/src/components/post-card/ds-mobile-post-pdf-attachment.ts +0 -124
  87. package/src/components/post-card/index.ts +0 -11
  88. package/src/components/post-composer/ds-mobile-post-composer.ts +0 -140
  89. package/src/components/post-composer/index.ts +0 -2
  90. package/src/components/post-detail-modal/ds-mobile-post-detail-modal.service.ts +0 -104
  91. package/src/components/post-detail-modal/ds-mobile-post-detail-modal.ts +0 -1273
  92. package/src/components/post-detail-modal/index.ts +0 -9
  93. package/src/components/shared/directives/index.ts +0 -2
  94. package/src/components/shared/directives/long-press.directive.ts +0 -208
  95. package/src/components/shared/index.ts +0 -3
  96. package/src/components/shared/mobile-common.css +0 -94
  97. package/src/components/shared/mobile-page-base.css +0 -315
  98. package/src/components/shared/mobile-page-base.ts +0 -70
  99. package/src/components/swiper/ds-mobile-swiper.ts +0 -123
  100. package/src/components/swiper/index.ts +0 -2
  101. package/src/components/tab-bar/ds-mobile-tab-bar.ts +0 -132
  102. package/src/components/tab-bar/index.ts +0 -2
  103. package/src/components/tabs/ds-mobile-tabs.css +0 -405
  104. package/src/components/tabs/ds-mobile-tabs.ts +0 -204
  105. package/src/components/tabs/index.ts +0 -2
  106. package/src/pages/community.page.ts +0 -768
  107. package/src/pages/handbook.page.ts +0 -298
  108. package/src/pages/home.page.ts +0 -192
  109. package/src/pages/index.ts +0 -9
  110. package/src/pages/inquiries.example.ts +0 -212
  111. package/src/pages/inquiry-detail.example.css +0 -434
  112. package/src/pages/inquiry-detail.example.ts +0 -416
  113. package/src/pages/mobile-tabs-example.component.ts +0 -146
  114. package/src/pages/post-create.page.ts +0 -311
  115. package/src/pages/post-detail.page.ts +0 -295
  116. package/src/pages/whitelabel-demo.page.ts +0 -548
  117. package/src/public-api.ts +0 -5
  118. package/src/services/user.service.ts +0 -35
  119. package/src/services/whitelabel.service.ts +0 -171
  120. package/src/styles/ionic.css +0 -673
  121. package/tsconfig.lib.json +0 -17
  122. package/tsconfig.lib.prod.json +0 -9
  123. package/tsconfig.spec.json +0 -13
@@ -1,516 +0,0 @@
1
- import { Component, input, output, model, signal, computed } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
3
- import { DsAvatarComponent } from '@propbinder/design-system';
4
- import { DsIconComponent } from '@propbinder/design-system';
5
- import { DsIconButtonComponent } from '@propbinder/design-system';
6
- import { Haptics, ImpactStyle } from '@capacitor/haptics';
7
-
8
- /**
9
- * DsMobileCommentComponent
10
- *
11
- * Individual comment component for post discussions.
12
- * Displays user comments with avatar, content, and like action.
13
- *
14
- * @example
15
- * ```html
16
- * <ds-mobile-comment
17
- * [authorName]="'John Doe'"
18
- * [authorRole]="'Tenant'"
19
- * [timestamp]="'1h ago'"
20
- * [avatarInitials]="'JD'"
21
- * [content]="'Great post!'">
22
- * </ds-mobile-comment>
23
- * ```
24
- */
25
- @Component({
26
- selector: 'ds-mobile-comment',
27
- standalone: true,
28
- imports: [CommonModule, DsAvatarComponent, DsIconComponent, DsIconButtonComponent],
29
- styleUrls: ['../shared/mobile-common.css'],
30
- host: {
31
- '[class.clickable]': 'clickable()',
32
- '(click)': 'handleCommentClick($event)',
33
- '(touchstart)': 'handleTouchStart($event)',
34
- '(touchend)': 'handleTouchEnd($event)',
35
- '(touchmove)': 'handleTouchMove($event)',
36
- '(contextmenu)': 'handleContextMenu($event)'
37
- },
38
- styles: [`
39
- :host {
40
- display: flex;
41
- gap: 12px;
42
- padding: 8px;
43
- position: relative;
44
- border-radius: 16px;
45
- transition: all 0.2s ease;
46
- background: var(--color-background-primary, #ffffff);
47
- margin-bottom: 8px;
48
- margin-left: -8px;
49
- margin-right: -8px;
50
- }
51
-
52
- :host:last-child {
53
- margin-bottom: 0;
54
- }
55
-
56
- :host::after {
57
- content: '';
58
- position: absolute;
59
- bottom: -4px;
60
- /* Align with comment content: padding (8px) + avatar (32px) + gap (12px) */
61
- left: 44px;
62
- /* Align with comment content right edge: padding (8px) from right */
63
- right: 8px;
64
- height: 1px;
65
- background: var(--border-color-default);
66
- }
67
-
68
- :host:last-child::after {
69
- display: none;
70
- }
71
-
72
- :host.clickable {
73
- cursor: pointer;
74
- }
75
-
76
- :host.clickable:active {
77
- background: var(--color-background-neutral-primary-hover, #f5f5f5);
78
- }
79
-
80
- .avatar-wrapper {
81
- position: relative;
82
- display: flex;
83
- align-items: flex-start;
84
- justify-content: center;
85
- flex-shrink: 0;
86
- }
87
-
88
- .comment-content {
89
- flex: 1;
90
- min-width: 0;
91
- display: flex;
92
- flex-direction: column;
93
- gap: 4px;
94
- }
95
-
96
- .comment-header {
97
- display: flex;
98
- align-items: baseline;
99
- gap: 6px;
100
- flex-wrap: wrap;
101
- }
102
-
103
- /* Wrapper for like and more actions */
104
- .header-actions {
105
- display: flex;
106
- align-items: center;
107
- gap: 4px;
108
- margin-left: auto;
109
- }
110
-
111
- /* Desktop more actions button - using ds-icon-button */
112
- .desktop-more-button {
113
- display: none; /* Hidden by default (mobile) */
114
- }
115
-
116
- /* Make button circular */
117
- .desktop-more-button::ng-deep button {
118
- border-radius: 50% !important;
119
- }
120
-
121
- /* Show only on desktop with hover capability */
122
- @media (hover: hover) and (pointer: fine) {
123
- .desktop-more-button {
124
- display: block;
125
- }
126
- }
127
-
128
- /* Author styles imported from mobile-common.css */
129
-
130
- .action-like {
131
- display: flex;
132
- align-items: center;
133
- gap: 2px;
134
- color: var(--color-text-secondary, #737373);
135
- cursor: pointer;
136
- transition: color 0.2s ease;
137
- user-select: none;
138
- -webkit-tap-highlight-color: transparent;
139
- font-family: 'Brockmann', sans-serif;
140
- font-size: var(--font-size-xs);
141
- font-weight: 500;
142
- line-height: 18px;
143
- }
144
-
145
- .like-count {
146
- opacity: 1;
147
- }
148
-
149
- .like-count.hidden {
150
- opacity: 0;
151
- }
152
-
153
- .action-like.active {
154
- color: #f91880;
155
- }
156
-
157
- .icon-wrapper {
158
- position: relative;
159
- display: flex;
160
- align-items: center;
161
- justify-content: center;
162
- }
163
-
164
- .icon-pulse {
165
- position: absolute;
166
- top: 50%;
167
- left: 50%;
168
- transform: translate(-50%, -50%);
169
- opacity: 0;
170
- pointer-events: none;
171
- }
172
-
173
- .icon-pulse.animating {
174
- animation: pulse 0.4s cubic-bezier(0.4, 0, 0.2, 1);
175
- }
176
-
177
- @keyframes pulse {
178
- 0% {
179
- transform: translate(-50%, -50%) scale(1);
180
- opacity: 0.8;
181
- }
182
- 100% {
183
- transform: translate(-50%, -50%) scale(2.5);
184
- opacity: 0;
185
- }
186
- }
187
-
188
- .comment-text {
189
- font-family: 'Brockmann', sans-serif;
190
- font-size: var(--font-size-sm);
191
- font-weight: 400;
192
- line-height: 22px;
193
- letter-spacing: -0.3px;
194
- color: var(--color-text-primary, #1a1a1a);
195
- white-space: pre-wrap;
196
- word-wrap: break-word;
197
- }
198
-
199
- .comment-text ::ng-deep .mention {
200
- color: var(--color-brand-base, #6B5FF5) !important;
201
- font-weight: 600;
202
- }
203
-
204
- .comment-actions {
205
- display: flex;
206
- align-items: center;
207
- gap: 12px;
208
- margin-top: 4px;
209
- }
210
-
211
- .action-reply {
212
- font-family: 'Brockmann', sans-serif;
213
- font-size: var(--font-size-sm);
214
- font-weight: 500;
215
- line-height: 18px;
216
- color: var(--color-text-secondary, #737373);
217
- cursor: pointer;
218
- user-select: none;
219
- -webkit-tap-highlight-color: transparent;
220
- transition: color 0.2s ease;
221
- }
222
-
223
- .action-reply:hover {
224
- color: var(--color-text-primary, #1a1a1a);
225
- }
226
-
227
- .action-edit {
228
- font-family: 'Brockmann', sans-serif;
229
- font-size: var(--font-size-sm);
230
- font-weight: 500;
231
- line-height: 18px;
232
- color: var(--color-text-secondary, #737373);
233
- cursor: pointer;
234
- user-select: none;
235
- -webkit-tap-highlight-color: transparent;
236
- transition: color 0.2s ease;
237
- }
238
-
239
- .action-edit:hover {
240
- color: var(--color-text-primary, #1a1a1a);
241
- }
242
- `],
243
- template: `
244
- <div class="avatar-wrapper">
245
- <ds-avatar
246
- [initials]="avatarInitials()"
247
- [type]="avatarType()"
248
- size="sm" />
249
- </div>
250
-
251
- <div class="comment-content">
252
- <div class="comment-header">
253
- <span class="author-name">{{ authorName() }}</span>
254
- <span class="author-meta">{{ authorRole() }} · {{ timestamp() }}</span>
255
-
256
- <!-- Wrapper for like and more actions -->
257
- <div class="header-actions">
258
- <div
259
- class="action-like"
260
- [class.active]="isLiked()"
261
- (click)="toggleLike()">
262
- <span class="like-count" [class.hidden]="likeCount() === 0">{{ likeCount() }}</span>
263
- <div class="icon-wrapper">
264
- <ds-icon
265
- class="icon-pulse"
266
- [class.animating]="isPulsing()"
267
- [name]="isLiked() ? 'remixHeart3Fill' : 'remixHeart3Line'"
268
- size="16px" />
269
- <ds-icon
270
- [name]="isLiked() ? 'remixHeart3Fill' : 'remixHeart3Line'"
271
- size="16px" />
272
- </div>
273
- </div>
274
-
275
- <!-- Desktop more button -->
276
- <ds-icon-button
277
- class="desktop-more-button"
278
- icon="remixMoreFill"
279
- variant="secondary"
280
- size="sm"
281
- (clicked)="handleMoreButtonClick($event)"
282
- aria-label="More options">
283
- </ds-icon-button>
284
- </div>
285
- </div>
286
-
287
- <div class="comment-text" [innerHTML]="formattedContent()"></div>
288
-
289
- <div class="comment-actions">
290
- <div class="action-reply" (click)="handleReply()">
291
- Reply
292
- </div>
293
- @if (isOwnComment()) {
294
- <div class="action-edit" (click)="handleEdit()">
295
- Edit
296
- </div>
297
- }
298
- </div>
299
- </div>
300
- `
301
- })
302
- export class DsMobileCommentComponent {
303
- /**
304
- * Author's display name
305
- */
306
- authorName = input.required<string>();
307
-
308
- /**
309
- * Author's role (e.g., "Tenant", "Property Manager")
310
- */
311
- authorRole = input.required<string>();
312
-
313
- /**
314
- * Timestamp text (e.g., "1h ago", "2d ago")
315
- */
316
- timestamp = input.required<string>();
317
-
318
- /**
319
- * Comment content text
320
- */
321
- content = input.required<string>();
322
-
323
- /**
324
- * Avatar initials
325
- */
326
- avatarInitials = input<string>('');
327
-
328
- /**
329
- * Avatar type
330
- */
331
- avatarType = input<'initials' | 'photo' | 'icon'>('initials');
332
-
333
- /**
334
- * Whether the comment is clickable
335
- */
336
- clickable = input<boolean>(false);
337
-
338
- /**
339
- * Whether this comment belongs to the current user
340
- */
341
- isOwnComment = input<boolean>(false);
342
-
343
- /**
344
- * Whether the comment is liked by current user
345
- */
346
- isLiked = model<boolean>(false);
347
-
348
- /**
349
- * Number of likes
350
- */
351
- likeCount = model<number>(0);
352
-
353
- /**
354
- * Signal to control pulse animation
355
- */
356
- isPulsing = signal(false);
357
-
358
- /**
359
- * Computed property to format content with @mentions
360
- */
361
- formattedContent = computed(() => {
362
- const text = this.content();
363
- // Replace @mentions with styled spans
364
- // Matches @FirstName or @FirstName LastName (max 2 words)
365
- return text.replace(/@([A-Za-z]+(?:\s+[A-Za-z]+)?)\b/g, '<span class="mention">@$1</span>');
366
- });
367
-
368
- /**
369
- * Emits when the comment card is clicked (if clickable)
370
- */
371
- commentClick = output<void>();
372
-
373
- /**
374
- * Emits when reply is clicked
375
- */
376
- replyClick = output<void>();
377
-
378
- /**
379
- * Emits when edit is clicked
380
- */
381
- editClick = output<void>();
382
-
383
- /**
384
- * Emits when the comment is long-pressed
385
- */
386
- longPress = output<void>();
387
-
388
- /**
389
- * Long press tracking
390
- */
391
- private longPressTimer: any = null;
392
- private longPressTriggered = false;
393
- private touchStartX = 0;
394
- private touchStartY = 0;
395
- private readonly LONG_PRESS_DURATION = 500; // ms
396
- private readonly MOVE_THRESHOLD = 10; // px
397
-
398
- handleCommentClick(event: Event): void {
399
- // Only emit if clickable and not clicking on action buttons
400
- if (this.clickable() && !(event.target as HTMLElement).closest('.comment-actions')) {
401
- this.commentClick.emit();
402
- }
403
- }
404
-
405
- async toggleLike(): Promise<void> {
406
- const newLiked = !this.isLiked();
407
- this.isLiked.set(newLiked);
408
-
409
- const newCount = newLiked ? this.likeCount() + 1 : this.likeCount() - 1;
410
- this.likeCount.set(Math.max(0, newCount));
411
-
412
- // Trigger pulse animation only when liking
413
- if (newLiked) {
414
- this.isPulsing.set(true);
415
- setTimeout(() => this.isPulsing.set(false), 400);
416
- }
417
-
418
- // Haptic feedback for like/unlike
419
- try {
420
- await Haptics.impact({ style: ImpactStyle.Light });
421
- } catch {
422
- // Fallback to Web Vibration API if Capacitor Haptics is not available
423
- if ('vibrate' in navigator) {
424
- navigator.vibrate(50);
425
- }
426
- }
427
- }
428
-
429
- handleReply(): void {
430
- this.replyClick.emit();
431
- }
432
-
433
- handleEdit(): void {
434
- this.editClick.emit();
435
- }
436
-
437
- /**
438
- * Handle touch start for long press detection
439
- */
440
- handleTouchStart(event: TouchEvent): void {
441
- this.longPressTriggered = false;
442
- this.touchStartX = event.touches[0].clientX;
443
- this.touchStartY = event.touches[0].clientY;
444
-
445
- // Start long press timer
446
- this.longPressTimer = setTimeout(async () => {
447
- this.longPressTriggered = true;
448
- this.longPress.emit();
449
-
450
- // Haptic feedback for long press
451
- try {
452
- await Haptics.impact({ style: ImpactStyle.Medium });
453
- } catch {
454
- // Fallback to Web Vibration API if Capacitor Haptics is not available
455
- if ('vibrate' in navigator) {
456
- navigator.vibrate(50);
457
- }
458
- }
459
- }, this.LONG_PRESS_DURATION);
460
- }
461
-
462
- /**
463
- * Handle touch end to clear long press timer
464
- */
465
- handleTouchEnd(event: TouchEvent): void {
466
- if (this.longPressTimer) {
467
- clearTimeout(this.longPressTimer);
468
- this.longPressTimer = null;
469
- }
470
-
471
- // Prevent normal click if long press was triggered
472
- if (this.longPressTriggered) {
473
- event.preventDefault();
474
- event.stopPropagation();
475
- this.longPressTriggered = false;
476
- }
477
- }
478
-
479
- /**
480
- * Handle touch move to cancel long press if moved too much
481
- */
482
- handleTouchMove(event: TouchEvent): void {
483
- if (!this.longPressTimer) return;
484
-
485
- const touch = event.touches[0];
486
- const deltaX = Math.abs(touch.clientX - this.touchStartX);
487
- const deltaY = Math.abs(touch.clientY - this.touchStartY);
488
-
489
- // Cancel long press if moved too far
490
- if (deltaX > this.MOVE_THRESHOLD || deltaY > this.MOVE_THRESHOLD) {
491
- clearTimeout(this.longPressTimer);
492
- this.longPressTimer = null;
493
- this.longPressTriggered = false;
494
- }
495
- }
496
-
497
- /**
498
- * Handle context menu (right-click on desktop) to trigger long press action
499
- */
500
- handleContextMenu(event: Event): void {
501
- event.preventDefault();
502
- this.longPress.emit();
503
- }
504
-
505
- /**
506
- * Handle desktop more button click
507
- * Stops propagation and triggers long press action
508
- */
509
- handleMoreButtonClick(event: Event): void {
510
- console.log('[Comment] Desktop more button clicked');
511
- event.stopPropagation();
512
- event.preventDefault();
513
- this.longPress.emit();
514
- }
515
- }
516
-
@@ -1,2 +0,0 @@
1
- export { DsMobileCommentComponent } from './ds-mobile-comment';
2
-
@@ -1,182 +0,0 @@
1
- import { Component, input, output } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
3
- import { DsIconComponent } from '@propbinder/design-system';
4
- import { DsAvatarComponent } from '@propbinder/design-system';
5
-
6
- /**
7
- * DsMobileContactListItemComponent
8
- *
9
- * Specialized interactive component for displaying contacts.
10
- * Displays contact name with avatar initials and metadata (person name + phone number).
11
- * Similar styling to file attachments with rounded corners and hover states.
12
- *
13
- * @example
14
- * ```html
15
- * <ds-mobile-contact-list-item
16
- * [name]="'Mortensen & Søn ApS'"
17
- * [initials]="'M'"
18
- * [contactPerson]="'John Mortensen'"
19
- * [phoneNumber]="'+45 12 34 56 78'"
20
- * [clickable]="true"
21
- * (contactClick)="openContact()">
22
- * </ds-mobile-contact-list-item>
23
- * ```
24
- */
25
- @Component({
26
- selector: 'ds-mobile-contact-list-item',
27
- standalone: true,
28
- imports: [CommonModule, DsIconComponent, DsAvatarComponent],
29
- host: {
30
- '[class.clickable]': 'clickable()',
31
- '(click)': 'handleContactClick()'
32
- },
33
- styles: [`
34
- :host {
35
- display: flex;
36
- align-items: center;
37
- gap: 12px;
38
- padding: 10px 12px;
39
- background: var(--color-background-neutral-secondary, #f5f5f5);
40
- border-radius: 16px;
41
- transition: all 0.2s ease;
42
- }
43
-
44
- :host.clickable {
45
- cursor: pointer;
46
- }
47
-
48
- :host.clickable:hover {
49
- background: var(--color-background-neutral-secondary-hover, #ebebeb);
50
- }
51
-
52
- :host.clickable:active {
53
- transform: scale(0.98);
54
- }
55
-
56
- .contact-avatar {
57
- flex-shrink: 0;
58
- }
59
-
60
- .contact-content {
61
- display: flex;
62
- flex-direction: column;
63
- justify-content: center;
64
- gap: 2px;
65
- flex: 1;
66
- min-width: 0;
67
- }
68
-
69
- .contact-name {
70
- font-family: 'Brockmann', sans-serif;
71
- font-size: var(--font-size-sm);
72
- font-weight: 600;
73
- line-height: 20px;
74
- letter-spacing: -0.3px;
75
- color: var(--color-text-primary, #1a1a1a);
76
- margin: 0;
77
- white-space: nowrap;
78
- overflow: hidden;
79
- text-overflow: ellipsis;
80
- }
81
-
82
- .contact-meta {
83
- font-family: 'Brockmann', sans-serif;
84
- font-size: var(--font-size-xs);
85
- font-weight: 400;
86
- line-height: 1.2;
87
- letter-spacing: -0.26px;
88
- color: var(--color-text-tertiary, #737373);
89
- display: flex;
90
- align-items: center;
91
- gap: 4px;
92
- margin: 0;
93
- }
94
-
95
- .meta-separator {
96
- color: var(--color-text-tertiary, #a0a0a0);
97
- }
98
-
99
- .contact-trailing {
100
- display: flex;
101
- align-items: center;
102
- color: var(--color-text-tertiary, #a3a3a3);
103
- flex-shrink: 0;
104
- }
105
- `],
106
- template: `
107
- <div class="contact-avatar">
108
- <ds-avatar
109
- [initials]="initials()"
110
- type="initials"
111
- size="md"
112
- />
113
- </div>
114
-
115
- <div class="contact-content">
116
- <div class="contact-name">{{ name() }}</div>
117
-
118
- @if (contactPerson() || phoneNumber()) {
119
- <div class="contact-meta">
120
- @if (contactPerson()) {
121
- <span>{{ contactPerson() }}</span>
122
- }
123
- @if (contactPerson() && phoneNumber()) {
124
- <span class="meta-separator">·</span>
125
- }
126
- @if (phoneNumber()) {
127
- <span>{{ phoneNumber() }}</span>
128
- }
129
- </div>
130
- }
131
- </div>
132
-
133
- @if (showChevron()) {
134
- <div class="contact-trailing">
135
- <ds-icon name="remixArrowRightSLine" size="20px" />
136
- </div>
137
- }
138
- `
139
- })
140
- export class DsMobileContactListItemComponent {
141
- /**
142
- * Contact/company name
143
- */
144
- name = input.required<string>();
145
-
146
- /**
147
- * Avatar initials (usually 1-2 letters)
148
- */
149
- initials = input.required<string>();
150
-
151
- /**
152
- * Contact person name (optional)
153
- */
154
- contactPerson = input<string>('');
155
-
156
- /**
157
- * Phone number (optional)
158
- */
159
- phoneNumber = input<string>('');
160
-
161
- /**
162
- * Whether the contact item is clickable
163
- */
164
- clickable = input<boolean>(true);
165
-
166
- /**
167
- * Whether to show chevron icon
168
- */
169
- showChevron = input<boolean>(true);
170
-
171
- /**
172
- * Emits when the contact item is clicked (if clickable)
173
- */
174
- contactClick = output<void>();
175
-
176
- handleContactClick(): void {
177
- if (this.clickable()) {
178
- this.contactClick.emit();
179
- }
180
- }
181
- }
182
-
@@ -1,2 +0,0 @@
1
- export { DsMobileContactListItemComponent } from './ds-mobile-contact-list-item';
2
-