@propbinder/mobile-design 0.2.47 → 0.2.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. package/ng-package.json +24 -0
  2. package/package.json +3 -39
  3. package/src/animations/page-transitions.ts +165 -0
  4. package/src/assets/fonts/brockmann-mediumitalic-webfont.woff2 +0 -0
  5. package/src/assets/fonts/brockmann-regularitalic-webfont.woff2 +0 -0
  6. package/src/assets/fonts/brockmann-semibolditalic-webfont.woff2 +0 -0
  7. package/src/components/action-list-item/ds-mobile-action-list-item.ts +102 -0
  8. package/src/components/action-list-item/index.ts +2 -0
  9. package/src/components/app-icon/ds-app-icon.ts +133 -0
  10. package/src/components/app-icon/index.ts +2 -0
  11. package/src/components/attachment-preview/ds-mobile-attachment-preview.css +139 -0
  12. package/src/components/attachment-preview/ds-mobile-attachment-preview.ts +164 -0
  13. package/src/components/attachment-preview/index.ts +1 -0
  14. package/src/components/avatar-with-badge/ds-avatar-with-badge.ts +142 -0
  15. package/src/components/avatar-with-badge/index.ts +2 -0
  16. package/src/components/booking-modal/ds-mobile-booking-confirmation-wrapper.ts +71 -0
  17. package/src/components/booking-modal/ds-mobile-booking-modal.service.ts +121 -0
  18. package/src/components/booking-modal/ds-mobile-booking-modal.ts +598 -0
  19. package/src/components/booking-modal/ds-mobile-booking-summary.ts +161 -0
  20. package/src/components/booking-modal/index.ts +4 -0
  21. package/src/components/bottom-sheet/ds-mobile-actions-bottom-sheet.ts +266 -0
  22. package/src/components/bottom-sheet/ds-mobile-bottom-sheet-header.ts +146 -0
  23. package/src/components/bottom-sheet/ds-mobile-bottom-sheet-wrapper.ts +156 -0
  24. package/src/components/bottom-sheet/ds-mobile-bottom-sheet.css +101 -0
  25. package/src/components/bottom-sheet/ds-mobile-bottom-sheet.service.ts +169 -0
  26. package/src/components/bottom-sheet/ds-mobile-confirmation-sheet.ts +211 -0
  27. package/src/components/bottom-sheet/ds-mobile-post-create-bottom-sheet.ts +578 -0
  28. package/src/components/bottom-sheet/ds-mobile-profile-actions-sheet.ts +614 -0
  29. package/src/components/bottom-sheet/index.ts +8 -0
  30. package/src/components/bottom-sheet/modal-shadow-fix.ts +42 -0
  31. package/src/components/card-inline/ds-mobile-card-inline.ts +301 -0
  32. package/src/components/card-inline/index.ts +2 -0
  33. package/src/components/card-inline-banner/ds-mobile-card-inline-banner.ts +118 -0
  34. package/src/components/card-inline-banner/index.ts +1 -0
  35. package/src/components/card-inline-contact/ds-mobile-card-inline-contact.ts +120 -0
  36. package/src/components/card-inline-contact/index.ts +1 -0
  37. package/src/components/card-inline-file/ds-mobile-card-inline-file.ts +141 -0
  38. package/src/components/card-inline-file/index.ts +1 -0
  39. package/src/components/chat-modal/ds-mobile-chat-modal.css +159 -0
  40. package/src/components/chat-modal/ds-mobile-chat-modal.service.ts +105 -0
  41. package/src/components/chat-modal/ds-mobile-chat-modal.ts +918 -0
  42. package/src/components/chat-modal/index.ts +8 -0
  43. package/src/components/comment/ds-mobile-comment.ts +568 -0
  44. package/src/components/comment/index.ts +2 -0
  45. package/src/components/contact-list-item/ds-mobile-contact-list-item.ts +182 -0
  46. package/src/components/contact-list-item/index.ts +2 -0
  47. package/src/components/content/ds-mobile-content.ts +139 -0
  48. package/src/components/content/index.ts +2 -0
  49. package/src/components/dropdown/ds-mobile-dropdown.css +199 -0
  50. package/src/components/dropdown/ds-mobile-dropdown.ts +340 -0
  51. package/src/components/dropdown/index.ts +2 -0
  52. package/src/components/ds-mobile-tabs.css +407 -0
  53. package/src/components/ds-mobile-tabs.ts +216 -0
  54. package/src/components/empty-state/ds-mobile-empty-state.ts +120 -0
  55. package/src/components/empty-state/index.ts +2 -0
  56. package/src/components/fab/ds-mobile-fab.ts +315 -0
  57. package/src/components/fab/index.ts +1 -0
  58. package/src/components/facility-creation-modal/ds-mobile-facility-creation-confirmation-wrapper.ts +121 -0
  59. package/src/components/facility-creation-modal/ds-mobile-facility-creation-modal.css +189 -0
  60. package/src/components/facility-creation-modal/ds-mobile-facility-creation-modal.service.ts +135 -0
  61. package/src/components/facility-creation-modal/ds-mobile-facility-creation-modal.ts +656 -0
  62. package/src/components/facility-creation-modal/index.ts +9 -0
  63. package/src/components/facility-creation-modal/sheets/ds-mobile-access-sheet.ts +105 -0
  64. package/src/components/facility-creation-modal/sheets/ds-mobile-price-sheet.ts +188 -0
  65. package/src/components/facility-creation-modal/sheets/ds-mobile-when-can-book-sheet.ts +460 -0
  66. package/src/components/facility-creation-modal/sheets/ds-mobile-who-can-book-sheet.ts +134 -0
  67. package/src/components/facility-detail-modal/ds-mobile-facility-detail-modal.service.ts +69 -0
  68. package/src/components/facility-detail-modal/ds-mobile-facility-detail-modal.ts +379 -0
  69. package/src/components/facility-detail-modal/index.ts +2 -0
  70. package/src/components/file-attachment/ds-mobile-file-attachment.ts +164 -0
  71. package/src/components/file-attachment/index.ts +2 -0
  72. package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.css +214 -0
  73. package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.service.ts +84 -0
  74. package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.ts +424 -0
  75. package/src/components/handbook-detail-modal/index.ts +3 -0
  76. package/src/components/handbook-folder/ds-mobile-handbook-folder-mini.ts +175 -0
  77. package/src/components/handbook-folder/ds-mobile-handbook-folder.ts +533 -0
  78. package/src/components/handbook-folder/index.ts +4 -0
  79. package/src/components/header-content/ds-mobile-header-content.ts +222 -0
  80. package/src/components/header-content/index.ts +2 -0
  81. package/src/components/illustration/ds-mobile-illustration.ts +124 -0
  82. package/src/components/illustration/index.ts +2 -0
  83. package/src/components/index.ts +124 -0
  84. package/src/components/inline-photo/ds-mobile-inline-photo.ts +361 -0
  85. package/src/components/inline-photo/index.ts +1 -0
  86. package/src/components/inline-tabs/ds-mobile-inline-tabs.ts +132 -0
  87. package/src/components/inline-tabs/index.ts +2 -0
  88. package/src/components/interactive-list-item-booking/ds-mobile-interactive-list-item-booking.ts +350 -0
  89. package/src/components/interactive-list-item-booking/index.ts +1 -0
  90. package/src/components/interactive-list-item-inquiry/ds-mobile-interactive-list-item-inquiry.ts +321 -0
  91. package/src/components/interactive-list-item-inquiry/index.ts +2 -0
  92. package/src/components/interactive-list-item-message/ds-mobile-interactive-list-item-message.ts +237 -0
  93. package/src/components/interactive-list-item-message/index.ts +2 -0
  94. package/src/components/interactive-list-item-post/ds-mobile-interactive-list-item-post.ts +549 -0
  95. package/src/components/interactive-list-item-post/ds-mobile-post-pdf-attachment.ts +124 -0
  96. package/src/components/interactive-list-item-post/index.ts +13 -0
  97. package/src/components/lightbox/ds-mobile-lightbox-footer.ts +315 -0
  98. package/src/components/lightbox/ds-mobile-lightbox-header.ts +202 -0
  99. package/src/components/lightbox/ds-mobile-lightbox-image.ts +484 -0
  100. package/src/components/lightbox/ds-mobile-lightbox-pdf.css +377 -0
  101. package/src/components/lightbox/ds-mobile-lightbox-pdf.ts +374 -0
  102. package/src/components/lightbox/ds-mobile-lightbox.css +587 -0
  103. package/src/components/lightbox/ds-mobile-lightbox.service.ts +296 -0
  104. package/src/components/lightbox/ds-mobile-lightbox.ts +529 -0
  105. package/src/components/lightbox/index.ts +22 -0
  106. package/src/components/list-item/ds-mobile-list-item.ts +603 -0
  107. package/src/components/list-item/index.ts +2 -0
  108. package/src/components/list-item-static/ds-mobile-list-item-static.ts +133 -0
  109. package/src/components/list-item-static/index.ts +2 -0
  110. package/src/components/loader-overlay/ds-mobile-loader-overlay.css +49 -0
  111. package/src/components/loader-overlay/ds-mobile-loader-overlay.ts +77 -0
  112. package/src/components/loader-overlay/index.ts +1 -0
  113. package/src/components/logo/ds-logo.ts +95 -0
  114. package/src/components/logo/index.ts +2 -0
  115. package/src/components/message-bubble/ds-mobile-message-bubble.ts +633 -0
  116. package/src/components/message-bubble/index.ts +7 -0
  117. package/src/components/message-composer/ds-mobile-message-composer.ts +1146 -0
  118. package/src/components/message-composer/index.ts +7 -0
  119. package/src/components/modal/ds-mobile-modal.css +163 -0
  120. package/src/components/modal/ds-mobile-modal.service.ts +329 -0
  121. package/src/components/modal/index.ts +8 -0
  122. package/src/components/modal-base/ds-mobile-modal-base.css +378 -0
  123. package/src/components/modal-base/ds-mobile-modal-base.ts +261 -0
  124. package/src/components/modal-base/index.ts +2 -0
  125. package/src/components/new-inquiry-modal/ds-mobile-new-inquiry-modal.css +112 -0
  126. package/src/components/new-inquiry-modal/ds-mobile-new-inquiry-modal.service.ts +93 -0
  127. package/src/components/new-inquiry-modal/ds-mobile-new-inquiry-modal.ts +442 -0
  128. package/src/components/new-inquiry-modal/index.ts +4 -0
  129. package/src/components/offline-banner/ds-mobile-offline-banner.ts +135 -0
  130. package/src/components/offline-banner/index.ts +1 -0
  131. package/src/components/page-details/ds-mobile-page-details.css +83 -0
  132. package/src/components/page-details/ds-mobile-page-details.ts +282 -0
  133. package/src/components/page-details/index.ts +2 -0
  134. package/src/components/page-main/ds-mobile-page-main.css +68 -0
  135. package/src/components/page-main/ds-mobile-page-main.ts +421 -0
  136. package/src/components/page-main/index.ts +2 -0
  137. package/src/components/post-composer/ds-mobile-post-composer.ts +140 -0
  138. package/src/components/post-composer/index.ts +2 -0
  139. package/src/components/post-detail-modal/ds-mobile-post-detail-modal.css +390 -0
  140. package/src/components/post-detail-modal/ds-mobile-post-detail-modal.service.ts +108 -0
  141. package/src/components/post-detail-modal/ds-mobile-post-detail-modal.ts +722 -0
  142. package/src/components/post-detail-modal/index.ts +9 -0
  143. package/src/components/property-banner/ds-mobile-property-banner.ts +95 -0
  144. package/src/components/property-banner/index.ts +2 -0
  145. package/src/components/section/ds-mobile-section.ts +263 -0
  146. package/src/components/section/index.ts +2 -0
  147. package/src/components/shared/directives/index.ts +2 -0
  148. package/src/components/shared/directives/long-press.directive.ts +212 -0
  149. package/src/components/shared/index.ts +3 -0
  150. package/src/components/shared/mobile-modal-base.ts +457 -0
  151. package/src/components/shared/mobile-page-base.ts +204 -0
  152. package/src/components/swiper/ds-mobile-swiper-with-nav.ts +160 -0
  153. package/src/components/swiper/ds-mobile-swiper.ts +327 -0
  154. package/src/components/swiper/index.ts +3 -0
  155. package/src/components/system-message-banner/ds-mobile-system-message-banner.ts +129 -0
  156. package/src/components/system-message-banner/index.ts +2 -0
  157. package/src/components/tab-bar/ds-mobile-tab-bar.css +533 -0
  158. package/src/components/tab-bar/ds-mobile-tab-bar.ts +735 -0
  159. package/src/components/tab-bar/index.ts +2 -0
  160. package/src/components/tabs/ds-mobile-tabs.css +25 -0
  161. package/src/components/tabs/ds-mobile-tabs.ts +89 -0
  162. package/src/components/tabs/index.ts +2 -0
  163. package/src/components/text-input/ds-text-input.ts +287 -0
  164. package/src/components/text-input/index.ts +2 -0
  165. package/src/examples/booking.page.ts +434 -0
  166. package/src/examples/community.page.ts +776 -0
  167. package/src/examples/handbook.page.ts +324 -0
  168. package/src/examples/home.page.ts +347 -0
  169. package/src/examples/index.ts +12 -0
  170. package/src/examples/inquiries.example.ts +273 -0
  171. package/src/examples/inquiry-detail.example.css +189 -0
  172. package/src/examples/inquiry-detail.example.ts +415 -0
  173. package/src/examples/mobile-tabs-example.component.ts +208 -0
  174. package/src/examples/post-create.page.ts +311 -0
  175. package/src/examples/post-detail.page.ts +296 -0
  176. package/src/examples/sign-in.page.ts +291 -0
  177. package/src/examples/whitelabel-demo-modal.component.ts +1094 -0
  178. package/src/examples/whitelabel-demo-modal.service.ts +77 -0
  179. package/src/models/index.ts +7 -0
  180. package/src/models/post.model.ts +41 -0
  181. package/src/pages/community.page.ts +769 -0
  182. package/src/pages/handbook.page.ts +388 -0
  183. package/src/pages/home.page.ts +303 -0
  184. package/src/pages/index.ts +11 -0
  185. package/src/pages/inquiries.example.ts +273 -0
  186. package/src/pages/inquiry-detail.example.css +189 -0
  187. package/src/pages/inquiry-detail.example.ts +415 -0
  188. package/src/pages/mobile-tabs-example.component.ts +179 -0
  189. package/src/pages/post-create.page.ts +311 -0
  190. package/src/pages/post-detail.page.ts +296 -0
  191. package/src/pages/sign-in.page.ts +291 -0
  192. package/src/pages/whitelabel-demo-modal.component.ts +1094 -0
  193. package/src/pages/whitelabel-demo-modal.service.ts +77 -0
  194. package/src/public-api.ts +6 -0
  195. package/src/services/base-modal.service.ts +101 -0
  196. package/src/services/index.ts +11 -0
  197. package/src/services/posts.service.ts +542 -0
  198. package/src/services/tracking-permission.service.ts +88 -0
  199. package/src/services/user.service.ts +60 -0
  200. package/src/services/whitelabel.service.ts +675 -0
  201. package/{styles → src/styles}/ionic.css +25 -0
  202. package/tsconfig.lib.json +17 -0
  203. package/tsconfig.lib.prod.json +9 -0
  204. package/tsconfig.spec.json +13 -0
  205. package/fesm2022/propbinder-mobile-design.mjs +0 -26136
  206. package/fesm2022/propbinder-mobile-design.mjs.map +0 -1
  207. package/index.d.ts +0 -8154
  208. /package/{assets → src/assets}/fonts/Brockmann-Bold.otf +0 -0
  209. /package/{assets → src/assets}/fonts/Brockmann-BoldItalic.otf +0 -0
  210. /package/{assets → src/assets}/fonts/Brockmann-Medium.otf +0 -0
  211. /package/{assets → src/assets}/fonts/Brockmann-MediumItalic.otf +0 -0
  212. /package/{assets → src/assets}/fonts/Brockmann-Regular.otf +0 -0
  213. /package/{assets → src/assets}/fonts/Brockmann-RegularItalic.otf +0 -0
  214. /package/{assets → src/assets}/fonts/Brockmann-SemiBold.otf +0 -0
  215. /package/{assets → src/assets}/fonts/Brockmann-SemiBoldItalic.otf +0 -0
  216. /package/{assets → src/assets}/fonts/Brockmann_desktop_license.pdf +0 -0
  217. /package/{assets → src/assets}/fonts/brockmann-medium-webfont.woff2 +0 -0
  218. /package/{assets → src/assets}/fonts/brockmann-regular-webfont.woff2 +0 -0
  219. /package/{assets → src/assets}/fonts/brockmann-semibold-webfont.woff2 +0 -0
  220. /package/{styles → src/components/shared}/mobile-common.css +0 -0
  221. /package/{styles → src/components/shared}/mobile-page-base.css +0 -0
@@ -0,0 +1,350 @@
1
+ import { Component, input, output } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { DsIconComponent } from '@propbinder/design-system';
4
+ import { DsShapeIndicatorComponent } from '@propbinder/design-system';
5
+ import { DsMobileListItemComponent } from '../list-item';
6
+
7
+ /**
8
+ * DsMobileInteractiveListItemBookingComponent
9
+ *
10
+ * Specialized interactive list item for displaying facility bookings.
11
+ * Built on top of ds-mobile-list-item base component.
12
+ * Displays facility thumbnail, title, description, booking dates/times, and availability status.
13
+ *
14
+ * @example
15
+ * ```html
16
+ * <!-- Active booking variant -->
17
+ * <ds-mobile-interactive-list-item-booking
18
+ * [thumbnail]="'assets/facility.jpg'"
19
+ * [facilityTitle]="'Gæsteparkering'"
20
+ * [bookingDate]="'14. februar, 2026'"
21
+ * [bookingTime]="'9:00 - 17:00'"
22
+ * [clickable]="false">
23
+ * </ds-mobile-interactive-list-item-booking>
24
+ *
25
+ * <!-- Available facility variant -->
26
+ * <ds-mobile-interactive-list-item-booking
27
+ * [thumbnail]="'assets/facility.jpg'"
28
+ * [facilityTitle]="'Boremaskinen'"
29
+ * [description]="'Book a guest parking spot to give your visitors...'"
30
+ * [availabilityStatus]="'available-today'"
31
+ * [statusLabel]="'Ledig i dag'"
32
+ * [clickable]="true"
33
+ * [enableLongPress]="false"
34
+ * (bookingClick)="openBooking()">
35
+ * </ds-mobile-interactive-list-item-booking>
36
+ * ```
37
+ */
38
+ @Component({
39
+ selector: 'ds-mobile-interactive-list-item-booking',
40
+ standalone: true,
41
+ imports: [CommonModule, DsIconComponent, DsShapeIndicatorComponent, DsMobileListItemComponent],
42
+ styles: [`
43
+ :host {
44
+ display: block;
45
+ }
46
+
47
+ /* Hide divider on last child */
48
+ :host:last-child {
49
+ --divider-display: none;
50
+ --item-padding-bottom: 0;
51
+ }
52
+
53
+ .booking-thumbnail {
54
+ flex-shrink: 0;
55
+ width: 64px;
56
+ height: 64px;
57
+ border-radius: 12px;
58
+ overflow: hidden;
59
+ background: var(--color-surface-secondary, #f5f5f5);
60
+ display: flex;
61
+ align-items: center;
62
+ justify-content: center;
63
+ }
64
+
65
+ .booking-thumbnail img {
66
+ width: 100%;
67
+ height: 100%;
68
+ object-fit: cover;
69
+ }
70
+
71
+ .booking-thumbnail-placeholder {
72
+ width: 100%;
73
+ height: 100%;
74
+ display: flex;
75
+ align-items: center;
76
+ justify-content: center;
77
+ color: var(--text-color-default-tertiary, #737373);
78
+ }
79
+
80
+ .booking-content {
81
+ display: flex;
82
+ flex-direction: column;
83
+ gap: 4px;
84
+ flex: 1;
85
+ min-width: 0;
86
+ }
87
+
88
+ .booking-title {
89
+ font-family: 'Brockmann', sans-serif;
90
+ font-size: var(--font-size-sm, 14px);
91
+ font-weight: 600;
92
+ line-height: 20px;
93
+ letter-spacing: -0.3px;
94
+ color: var(--text-color-default-primary, #202227);
95
+ margin: 0;
96
+ white-space: nowrap;
97
+ overflow: hidden;
98
+ text-overflow: ellipsis;
99
+ }
100
+
101
+ .booking-description {
102
+ font-family: 'Brockmann', sans-serif;
103
+ font-size: var(--font-size-sm, 14px);
104
+ font-weight: 400;
105
+ line-height: 20px;
106
+ letter-spacing: -0.3px;
107
+ color: var(--text-color-default-secondary, #545B66);
108
+ margin: 0;
109
+ display: -webkit-box;
110
+ -webkit-line-clamp: 2;
111
+ -webkit-box-orient: vertical;
112
+ overflow: hidden;
113
+ }
114
+
115
+ .booking-meta {
116
+ font-family: 'Brockmann', sans-serif;
117
+ font-size: var(--font-size-xs, 12px);
118
+ font-weight: 400;
119
+ line-height: 1.2;
120
+ letter-spacing: -0.26px;
121
+ color: var(--text-color-default-secondary, #545B66);
122
+ display: flex;
123
+ align-items: center;
124
+ gap: 8px;
125
+ margin-top: 4px;
126
+ }
127
+
128
+ .booking-status {
129
+ display: flex;
130
+ align-items: center;
131
+ gap: 6px;
132
+ font-family: 'Brockmann', sans-serif;
133
+ font-size: var(--font-size-xs);
134
+ font-weight: 500;
135
+ line-height: 1.2;
136
+ letter-spacing: -0.26px;
137
+ color: var(--text-color-default-secondary, #545B66);
138
+ }
139
+
140
+ .booking-status.available-today {
141
+ color: var(--color-accent, #5d5fef);
142
+ }
143
+
144
+ .booking-status.available-from {
145
+ color: var(--color-warning, #f59e0b);
146
+ }
147
+
148
+ .booking-status.unavailable {
149
+ color: var(--text-color-default-tertiary, #737373);
150
+ }
151
+
152
+ .booking-datetime {
153
+ display: flex;
154
+ align-items: center;
155
+ gap: 4px;
156
+ font-family: 'Brockmann', sans-serif;
157
+ font-size: var(--font-size-xs);
158
+ font-weight: 400;
159
+ line-height: 1.2;
160
+ letter-spacing: -0.26px;
161
+ color: var(--text-color-default-secondary, #545B66);
162
+ }
163
+
164
+ .booking-trailing {
165
+ display: flex;
166
+ align-items: center;
167
+ color: var(--color-text-tertiary, #a3a3a3);
168
+ }
169
+ `],
170
+ template: `
171
+ <ds-mobile-list-item
172
+ [leadingSize]="'64px'"
173
+ [align]="align()"
174
+ [variant]="variant()"
175
+ [interactive]="clickable()"
176
+ [enableLongPress]="enableLongPress()"
177
+ [moreActions]="moreActions()"
178
+ (itemClick)="handleBookingClick()"
179
+ (longPress)="handleLongPress()"
180
+ (moreButtonClick)="handleMoreButtonClick($event)">
181
+
182
+ <div content-leading>
183
+ <div class="booking-thumbnail">
184
+ @if (thumbnail()) {
185
+ <img [src]="thumbnail()" [alt]="facilityTitle()" />
186
+ } @else {
187
+ <div class="booking-thumbnail-placeholder">
188
+ <ds-icon name="remixImageLine" size="24px" color="--text-color-default-tertiary" />
189
+ </div>
190
+ }
191
+ </div>
192
+ </div>
193
+
194
+ <div content-main>
195
+ <div class="booking-content">
196
+ <h3 class="booking-title">{{ facilityTitle() }}</h3>
197
+
198
+ @if (description()) {
199
+ <p class="booking-description">{{ description() }}</p>
200
+ }
201
+
202
+ <div class="booking-meta">
203
+ @if (availabilityStatus()) {
204
+ <div class="booking-status"
205
+ [class.available-today]="availabilityStatus() === 'available-today'"
206
+ [class.available-from]="availabilityStatus() === 'available-from'"
207
+ [class.unavailable]="availabilityStatus() === 'unavailable'">
208
+ <ds-shape-indicator
209
+ shape="circle"
210
+ [variant]="getStatusVariant()">
211
+ </ds-shape-indicator>
212
+ <span>{{ statusLabel() }}</span>
213
+ </div>
214
+ }
215
+
216
+ @if (bookingDate()) {
217
+ <div class="booking-datetime">
218
+ <ds-icon name="remixCalendarLine" size="14px" color="--color-text-secondary" />
219
+ <span>{{ bookingDate() }}</span>
220
+ </div>
221
+ }
222
+
223
+ @if (bookingTime()) {
224
+ <div class="booking-datetime">
225
+ <ds-icon name="remixTimeLine" size="14px" color="--color-text-secondary" />
226
+ <span>{{ bookingTime() }}</span>
227
+ </div>
228
+ }
229
+ </div>
230
+ </div>
231
+ </div>
232
+
233
+ @if (showChevron()) {
234
+ <div content-trailing>
235
+ <div class="booking-trailing">
236
+ <ds-icon name="remixArrowRightSLine" size="20px" />
237
+ </div>
238
+ </div>
239
+ }
240
+ </ds-mobile-list-item>
241
+ `
242
+ })
243
+ export class DsMobileInteractiveListItemBookingComponent {
244
+ /**
245
+ * Facility thumbnail image URL
246
+ */
247
+ thumbnail = input<string>('');
248
+
249
+ /**
250
+ * Facility title
251
+ */
252
+ facilityTitle = input.required<string>();
253
+
254
+ /**
255
+ * Facility description/preview text (only for available facilities)
256
+ */
257
+ description = input<string>('');
258
+
259
+ /**
260
+ * Booking date (only for active bookings, e.g., "14. februar, 2026")
261
+ */
262
+ bookingDate = input<string>('');
263
+
264
+ /**
265
+ * Booking time range (only for active bookings, e.g., "9:00 - 17:00")
266
+ */
267
+ bookingTime = input<string>('');
268
+
269
+ /**
270
+ * Availability status (only for available facilities)
271
+ */
272
+ availabilityStatus = input<'available-today' | 'available-from' | 'unavailable' | undefined>(undefined);
273
+
274
+ /**
275
+ * Status label text (e.g., "Ledig i dag", "Ledig fra 28. februar, 2026")
276
+ */
277
+ statusLabel = input<string>('');
278
+
279
+ /**
280
+ * Display variant
281
+ * - undefined (default) - Standard display
282
+ * - 'compact' - Compact display
283
+ */
284
+ variant = input<'compact' | undefined>(undefined);
285
+
286
+ /**
287
+ * Vertical alignment of content
288
+ * - 'top' - Align to top (default)
289
+ * - 'center' - Align to center
290
+ * - 'bottom' - Align to bottom
291
+ */
292
+ align = input<'top' | 'center' | 'bottom'>('top');
293
+
294
+ /**
295
+ * Whether the booking item is clickable
296
+ */
297
+ clickable = input<boolean>(true);
298
+
299
+ /**
300
+ * Whether to show chevron icon
301
+ */
302
+ showChevron = input<boolean>(true);
303
+
304
+ /**
305
+ * Enable long-press interaction when clickable is true
306
+ * Set to false to disable long-press but keep click
307
+ * Also controls visibility of desktop "more" button
308
+ * @default true
309
+ */
310
+ enableLongPress = input<boolean>(true);
311
+
312
+ /**
313
+ * Unified toggle for contextual actions (more button + long press).
314
+ * When set, takes precedence over `enableLongPress`.
315
+ */
316
+ moreActions = input<boolean | undefined>(undefined);
317
+
318
+ /**
319
+ * Emits when the booking item is clicked (if clickable)
320
+ */
321
+ bookingClick = output<void>();
322
+
323
+ /**
324
+ * Emits when the booking item is long-pressed
325
+ */
326
+ longPress = output<void>();
327
+
328
+ /**
329
+ * Get status indicator variant based on availability status
330
+ */
331
+ getStatusVariant(): 'brand' | 'warning' | 'grey' {
332
+ const status = this.availabilityStatus();
333
+ if (status === 'available-today') return 'brand';
334
+ if (status === 'available-from') return 'warning';
335
+ return 'grey';
336
+ }
337
+
338
+ handleBookingClick(): void {
339
+ this.bookingClick.emit();
340
+ }
341
+
342
+ handleLongPress(): void {
343
+ this.longPress.emit();
344
+ }
345
+
346
+ handleMoreButtonClick(event: Event): void {
347
+ // Desktop more button click - trigger the same action as long press
348
+ this.longPress.emit();
349
+ }
350
+ }
@@ -0,0 +1 @@
1
+ export * from './ds-mobile-interactive-list-item-booking';
@@ -0,0 +1,321 @@
1
+ import { Component, input, output } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { DsIconComponent } from '@propbinder/design-system';
4
+ import { DsShapeIndicatorComponent } from '@propbinder/design-system';
5
+ import { DsAvatarComponent } from '@propbinder/design-system';
6
+ import { DsMobileListItemComponent } from '../list-item';
7
+
8
+ /**
9
+ * DsMobileInteractiveListItemInquiryComponent
10
+ *
11
+ * Specialized interactive list item for displaying inquiries/tickets.
12
+ * Built on top of ds-mobile-interactive-list-item base component.
13
+ * Displays inquiry title, description, status, and timestamp.
14
+ *
15
+ * @example
16
+ * ```html
17
+ * <ds-mobile-interactive-list-item-inquiry
18
+ * [title]="'Tumble dryer is not working'"
19
+ * [description]="'For the past three days, I have been experiencing...'"
20
+ * [status]="'open'"
21
+ * [timestamp]="'12 days ago'"
22
+ * [iconName]="'remixCalendarLine'"
23
+ * [clickable]="true"
24
+ * [enableLongPress]="true"
25
+ * (inquiryClick)="openInquiry()">
26
+ * </ds-mobile-interactive-list-item-inquiry>
27
+ * ```
28
+ */
29
+ @Component({
30
+ selector: 'ds-mobile-interactive-list-item-inquiry',
31
+ standalone: true,
32
+ imports: [CommonModule, DsIconComponent, DsShapeIndicatorComponent, DsAvatarComponent, DsMobileListItemComponent],
33
+ styles: [`
34
+ :host {
35
+ display: block;
36
+ }
37
+
38
+ /* Hide divider on last child */
39
+ :host:last-child {
40
+ --divider-display: none;
41
+ --item-padding-bottom: 0;
42
+ }
43
+
44
+ .inquiry-avatar {
45
+ flex-shrink: 0;
46
+ }
47
+
48
+ /* Default/Open inquiries: brand-primary surface with brand-primary content */
49
+ .inquiry-avatar:not(.closed)::ng-deep .avatar--icon {
50
+ background-color: var(--color-accent, #5d5fef) !important;
51
+ }
52
+
53
+ .inquiry-avatar:not(.closed)::ng-deep .avatar--icon ds-icon,
54
+ .inquiry-avatar:not(.closed)::ng-deep .avatar--icon ds-icon::ng-deep svg {
55
+ color: var(--color-on-accent, #ffffff) !important;
56
+ fill: var(--color-on-accent, #ffffff) !important;
57
+ }
58
+
59
+ /* Closed inquiries: content tertiary surface with white icon */
60
+ .inquiry-avatar.closed::ng-deep .avatar--icon {
61
+ background-color: var(--text-color-default-tertiary, #737373) !important;
62
+ }
63
+
64
+ .inquiry-avatar.closed::ng-deep .avatar--icon ds-icon,
65
+ .inquiry-avatar.closed::ng-deep .avatar--icon ds-icon::ng-deep svg {
66
+ color: #ffffff !important;
67
+ fill: #ffffff !important;
68
+ }
69
+
70
+ .inquiry-content {
71
+ display: flex;
72
+ flex-direction: column;
73
+ gap: 4px;
74
+ flex: 1;
75
+ min-width: 0;
76
+ }
77
+
78
+ .inquiry-title {
79
+ font-family: 'Brockmann', sans-serif;
80
+ font-size: var(--font-size-sm, 14px);
81
+ font-weight: 600;
82
+ line-height: 20px;
83
+ letter-spacing: -0.3px;
84
+ color: var(--text-color-default-primary, #202227);
85
+ margin: 0;
86
+ white-space: nowrap;
87
+ overflow: hidden;
88
+ text-overflow: ellipsis;
89
+ }
90
+
91
+ .inquiry-description {
92
+ font-family: 'Brockmann', sans-serif;
93
+ font-size: var(--font-size-sm, 14px);
94
+ font-weight: 400;
95
+ line-height: 20px;
96
+ letter-spacing: -0.3px;
97
+ color: var(--text-color-default-secondary, #545B66);
98
+ margin: 0;
99
+ display: -webkit-box;
100
+ -webkit-line-clamp: 2;
101
+ -webkit-box-orient: vertical;
102
+ overflow: hidden;
103
+ }
104
+
105
+ .inquiry-meta {
106
+ font-family: 'Brockmann', sans-serif;
107
+ font-size: var(--font-size-xs, 12px);
108
+ font-weight: 400;
109
+ line-height: 1.2;
110
+ letter-spacing: -0.26px;
111
+ color: var(--text-color-default-secondary, #545B66);
112
+ display: flex;
113
+ align-items: center;
114
+ gap: 8px;
115
+ margin-top: 4px;
116
+ }
117
+
118
+ .inquiry-status {
119
+ display: flex;
120
+ align-items: center;
121
+ gap: 6px;
122
+ font-family: 'Brockmann', sans-serif;
123
+ font-size: var(--font-size-xs);
124
+ font-weight: 500;
125
+ line-height: 1.2;
126
+ letter-spacing: -0.26px;
127
+ color: var(--text-color-default-secondary, #545B66);
128
+ }
129
+
130
+ .inquiry-status.open {
131
+ color: var(--text-color-default-tertiary, #737373);
132
+ }
133
+
134
+ .inquiry-status.closed {
135
+ color: var(--text-color-default-tertiary, #737373);
136
+ }
137
+
138
+ .inquiry-timestamp {
139
+ display: flex;
140
+ align-items: center;
141
+ gap: 4px;
142
+ font-family: 'Brockmann', sans-serif;
143
+ font-size: var(--font-size-xs);
144
+ font-weight: 400;
145
+ line-height: 1.2;
146
+ letter-spacing: -0.26px;
147
+ color: var(--text-color-default-secondary, #545B66);
148
+ }
149
+
150
+ .inquiry-trailing {
151
+ display: flex;
152
+ align-items: center;
153
+ color: var(--color-text-tertiary, #a3a3a3);
154
+ }
155
+ `],
156
+ template: `
157
+ <ds-mobile-list-item
158
+ [leadingSize]="'32px'"
159
+ [align]="align()"
160
+ [variant]="variant()"
161
+ [interactive]="clickable()"
162
+ [enableLongPress]="enableLongPress()"
163
+ [moreActions]="moreActions()"
164
+ (itemClick)="handleInquiryClick()"
165
+ (longPress)="handleLongPress()"
166
+ (moreButtonClick)="handleMoreButtonClick($event)">
167
+
168
+ <div content-leading>
169
+ <div class="inquiry-avatar" [class.closed]="status() === 'closed'">
170
+ <ds-avatar
171
+ type="icon"
172
+ [iconName]="iconName()"
173
+ size="md"
174
+ />
175
+ </div>
176
+ </div>
177
+
178
+ <div content-main>
179
+ <div class="inquiry-content">
180
+ <h3 class="inquiry-title">{{ title() }}</h3>
181
+
182
+ @if (description()) {
183
+ <p class="inquiry-description">{{ description() }}</p>
184
+ }
185
+
186
+ <div class="inquiry-meta">
187
+ <div class="inquiry-status" [class.open]="status() === 'open'" [class.closed]="status() === 'closed'">
188
+ <ds-shape-indicator
189
+ shape="circle"
190
+ [variant]="status() === 'open' ? 'brand' : 'grey'">
191
+ </ds-shape-indicator>
192
+ <span>{{ computedStatusLabel() }}</span>
193
+ </div>
194
+
195
+ <div class="inquiry-timestamp">
196
+ <ds-icon name="remixTimeLine" size="14px" color="--color-text-secondary" />
197
+ <span>{{ timestamp() }}</span>
198
+ </div>
199
+ </div>
200
+ </div>
201
+ </div>
202
+
203
+ @if (showChevron()) {
204
+ <div content-trailing>
205
+ <div class="inquiry-trailing">
206
+ <ds-icon name="remixArrowRightSLine" size="20px" />
207
+ </div>
208
+ </div>
209
+ }
210
+ </ds-mobile-list-item>
211
+ `
212
+ })
213
+ export class DsMobileInteractiveListItemInquiryComponent {
214
+ /**
215
+ * Inquiry title
216
+ */
217
+ title = input.required<string>();
218
+
219
+ /**
220
+ * Inquiry description/preview text
221
+ */
222
+ description = input<string>('');
223
+
224
+ /**
225
+ * Inquiry status
226
+ */
227
+ status = input<'open' | 'closed'>('open');
228
+
229
+ /**
230
+ * Status label (defaults to capitalized status)
231
+ */
232
+ statusLabel = input<string>('');
233
+
234
+ /**
235
+ * Timestamp text (e.g., "12 days ago", "2 months ago")
236
+ */
237
+ timestamp = input.required<string>();
238
+
239
+ /**
240
+ * Icon name for the leading icon
241
+ */
242
+ iconName = input<string>('remixTodoLine');
243
+
244
+ /**
245
+ * Icon color
246
+ */
247
+ iconColor = input<string>('secondary');
248
+
249
+ /**
250
+ * Display variant
251
+ * - undefined (default) - Standard display
252
+ * - 'compact' - Compact display
253
+ */
254
+ variant = input<'compact' | undefined>(undefined);
255
+
256
+ /**
257
+ * Vertical alignment of content
258
+ * - 'top' - Align to top (default)
259
+ * - 'center' - Align to center
260
+ * - 'bottom' - Align to bottom
261
+ */
262
+ align = input<'top' | 'center' | 'bottom'>('top');
263
+
264
+ /**
265
+ * Whether the inquiry item is clickable
266
+ */
267
+ clickable = input<boolean>(true);
268
+
269
+ /**
270
+ * Whether to show chevron icon
271
+ */
272
+ showChevron = input<boolean>(true);
273
+
274
+ /**
275
+ * Enable long-press interaction when clickable is true
276
+ * Set to false to disable long-press but keep click
277
+ * Also controls visibility of desktop "more" button
278
+ * @default true
279
+ */
280
+ enableLongPress = input<boolean>(true);
281
+
282
+ /**
283
+ * Unified toggle for contextual actions (more button + long press).
284
+ * When set, takes precedence over `enableLongPress`.
285
+ */
286
+ moreActions = input<boolean | undefined>(undefined);
287
+
288
+ /**
289
+ * Emits when the inquiry item is clicked (if clickable)
290
+ */
291
+ inquiryClick = output<void>();
292
+
293
+ /**
294
+ * Emits when the inquiry item is long-pressed
295
+ */
296
+ longPress = output<void>();
297
+
298
+ /**
299
+ * Get computed status label
300
+ */
301
+ computedStatusLabel(): string {
302
+ if (this.statusLabel()) {
303
+ return this.statusLabel();
304
+ }
305
+ return this.status() === 'open' ? 'Åben' : 'Lukket';
306
+ }
307
+
308
+ handleInquiryClick(): void {
309
+ this.inquiryClick.emit();
310
+ }
311
+
312
+ handleLongPress(): void {
313
+ this.longPress.emit();
314
+ }
315
+
316
+ handleMoreButtonClick(event: Event): void {
317
+ // Desktop more button click - trigger the same action as long press
318
+ this.longPress.emit();
319
+ }
320
+ }
321
+
@@ -0,0 +1,2 @@
1
+ export { DsMobileInteractiveListItemInquiryComponent } from './ds-mobile-interactive-list-item-inquiry';
2
+