@propbinder/mobile-design 0.2.50 → 0.2.52

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/fesm2022/propbinder-mobile-design.mjs +26206 -0
  2. package/fesm2022/propbinder-mobile-design.mjs.map +1 -0
  3. package/index.d.ts +8193 -0
  4. package/package.json +39 -3
  5. package/ng-package.json +0 -24
  6. package/src/animations/page-transitions.ts +0 -165
  7. package/src/components/action-list-item/ds-mobile-action-list-item.ts +0 -102
  8. package/src/components/action-list-item/index.ts +0 -2
  9. package/src/components/app-icon/ds-app-icon.ts +0 -133
  10. package/src/components/app-icon/index.ts +0 -2
  11. package/src/components/attachment-preview/ds-mobile-attachment-preview.css +0 -139
  12. package/src/components/attachment-preview/ds-mobile-attachment-preview.ts +0 -164
  13. package/src/components/attachment-preview/index.ts +0 -1
  14. package/src/components/avatar-with-badge/ds-avatar-with-badge.ts +0 -142
  15. package/src/components/avatar-with-badge/index.ts +0 -2
  16. package/src/components/booking-modal/ds-mobile-booking-confirmation-wrapper.ts +0 -71
  17. package/src/components/booking-modal/ds-mobile-booking-modal.service.ts +0 -121
  18. package/src/components/booking-modal/ds-mobile-booking-modal.ts +0 -598
  19. package/src/components/booking-modal/ds-mobile-booking-summary.ts +0 -161
  20. package/src/components/booking-modal/index.ts +0 -4
  21. package/src/components/bottom-sheet/ds-mobile-actions-bottom-sheet.ts +0 -266
  22. package/src/components/bottom-sheet/ds-mobile-bottom-sheet-header.ts +0 -146
  23. package/src/components/bottom-sheet/ds-mobile-bottom-sheet-wrapper.ts +0 -156
  24. package/src/components/bottom-sheet/ds-mobile-bottom-sheet.css +0 -101
  25. package/src/components/bottom-sheet/ds-mobile-bottom-sheet.service.ts +0 -169
  26. package/src/components/bottom-sheet/ds-mobile-confirmation-sheet.ts +0 -211
  27. package/src/components/bottom-sheet/ds-mobile-post-create-bottom-sheet.ts +0 -578
  28. package/src/components/bottom-sheet/ds-mobile-profile-actions-sheet.ts +0 -614
  29. package/src/components/bottom-sheet/index.ts +0 -8
  30. package/src/components/bottom-sheet/modal-shadow-fix.ts +0 -42
  31. package/src/components/card-inline/ds-mobile-card-inline.ts +0 -301
  32. package/src/components/card-inline/index.ts +0 -2
  33. package/src/components/card-inline-banner/ds-mobile-card-inline-banner.ts +0 -118
  34. package/src/components/card-inline-banner/index.ts +0 -1
  35. package/src/components/card-inline-contact/ds-mobile-card-inline-contact.ts +0 -120
  36. package/src/components/card-inline-contact/index.ts +0 -1
  37. package/src/components/card-inline-file/ds-mobile-card-inline-file.ts +0 -141
  38. package/src/components/card-inline-file/index.ts +0 -1
  39. package/src/components/chat-modal/ds-mobile-chat-modal.css +0 -159
  40. package/src/components/chat-modal/ds-mobile-chat-modal.service.ts +0 -105
  41. package/src/components/chat-modal/ds-mobile-chat-modal.ts +0 -918
  42. package/src/components/chat-modal/index.ts +0 -8
  43. package/src/components/comment/ds-mobile-comment.ts +0 -568
  44. package/src/components/comment/index.ts +0 -2
  45. package/src/components/contact-list-item/ds-mobile-contact-list-item.ts +0 -182
  46. package/src/components/contact-list-item/index.ts +0 -2
  47. package/src/components/content/ds-mobile-content.ts +0 -139
  48. package/src/components/content/index.ts +0 -2
  49. package/src/components/dropdown/ds-mobile-dropdown.css +0 -199
  50. package/src/components/dropdown/ds-mobile-dropdown.ts +0 -340
  51. package/src/components/dropdown/index.ts +0 -2
  52. package/src/components/ds-mobile-tabs.css +0 -407
  53. package/src/components/ds-mobile-tabs.ts +0 -216
  54. package/src/components/empty-state/ds-mobile-empty-state.ts +0 -120
  55. package/src/components/empty-state/index.ts +0 -2
  56. package/src/components/fab/ds-mobile-fab.ts +0 -315
  57. package/src/components/fab/index.ts +0 -1
  58. package/src/components/facility-creation-modal/ds-mobile-facility-creation-confirmation-wrapper.ts +0 -121
  59. package/src/components/facility-creation-modal/ds-mobile-facility-creation-modal.css +0 -189
  60. package/src/components/facility-creation-modal/ds-mobile-facility-creation-modal.service.ts +0 -135
  61. package/src/components/facility-creation-modal/ds-mobile-facility-creation-modal.ts +0 -656
  62. package/src/components/facility-creation-modal/index.ts +0 -9
  63. package/src/components/facility-creation-modal/sheets/ds-mobile-access-sheet.ts +0 -105
  64. package/src/components/facility-creation-modal/sheets/ds-mobile-price-sheet.ts +0 -188
  65. package/src/components/facility-creation-modal/sheets/ds-mobile-when-can-book-sheet.ts +0 -460
  66. package/src/components/facility-creation-modal/sheets/ds-mobile-who-can-book-sheet.ts +0 -134
  67. package/src/components/facility-detail-modal/ds-mobile-facility-detail-modal.service.ts +0 -69
  68. package/src/components/facility-detail-modal/ds-mobile-facility-detail-modal.ts +0 -379
  69. package/src/components/facility-detail-modal/index.ts +0 -2
  70. package/src/components/file-attachment/ds-mobile-file-attachment.ts +0 -164
  71. package/src/components/file-attachment/index.ts +0 -2
  72. package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.css +0 -214
  73. package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.service.ts +0 -84
  74. package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.ts +0 -424
  75. package/src/components/handbook-detail-modal/index.ts +0 -3
  76. package/src/components/handbook-folder/ds-mobile-handbook-folder-mini.ts +0 -175
  77. package/src/components/handbook-folder/ds-mobile-handbook-folder.ts +0 -533
  78. package/src/components/handbook-folder/index.ts +0 -4
  79. package/src/components/header-content/ds-mobile-header-content.ts +0 -222
  80. package/src/components/header-content/index.ts +0 -2
  81. package/src/components/illustration/ds-mobile-illustration.ts +0 -124
  82. package/src/components/illustration/index.ts +0 -2
  83. package/src/components/index.ts +0 -124
  84. package/src/components/inline-photo/ds-mobile-inline-photo.ts +0 -361
  85. package/src/components/inline-photo/index.ts +0 -1
  86. package/src/components/inline-tabs/ds-mobile-inline-tabs.ts +0 -132
  87. package/src/components/inline-tabs/index.ts +0 -2
  88. package/src/components/interactive-list-item-booking/ds-mobile-interactive-list-item-booking.ts +0 -350
  89. package/src/components/interactive-list-item-booking/index.ts +0 -1
  90. package/src/components/interactive-list-item-inquiry/ds-mobile-interactive-list-item-inquiry.ts +0 -321
  91. package/src/components/interactive-list-item-inquiry/index.ts +0 -2
  92. package/src/components/interactive-list-item-message/ds-mobile-interactive-list-item-message.ts +0 -237
  93. package/src/components/interactive-list-item-message/index.ts +0 -2
  94. package/src/components/interactive-list-item-post/ds-mobile-interactive-list-item-post.ts +0 -549
  95. package/src/components/interactive-list-item-post/ds-mobile-post-pdf-attachment.ts +0 -124
  96. package/src/components/interactive-list-item-post/index.ts +0 -13
  97. package/src/components/lightbox/ds-mobile-lightbox-footer.ts +0 -315
  98. package/src/components/lightbox/ds-mobile-lightbox-header.ts +0 -202
  99. package/src/components/lightbox/ds-mobile-lightbox-image.ts +0 -484
  100. package/src/components/lightbox/ds-mobile-lightbox-pdf.css +0 -377
  101. package/src/components/lightbox/ds-mobile-lightbox-pdf.ts +0 -374
  102. package/src/components/lightbox/ds-mobile-lightbox.css +0 -587
  103. package/src/components/lightbox/ds-mobile-lightbox.service.ts +0 -296
  104. package/src/components/lightbox/ds-mobile-lightbox.ts +0 -529
  105. package/src/components/lightbox/index.ts +0 -22
  106. package/src/components/list-item/ds-mobile-list-item.ts +0 -603
  107. package/src/components/list-item/index.ts +0 -2
  108. package/src/components/list-item-static/ds-mobile-list-item-static.ts +0 -133
  109. package/src/components/list-item-static/index.ts +0 -2
  110. package/src/components/loader-overlay/ds-mobile-loader-overlay.css +0 -49
  111. package/src/components/loader-overlay/ds-mobile-loader-overlay.ts +0 -77
  112. package/src/components/loader-overlay/index.ts +0 -1
  113. package/src/components/logo/ds-logo.ts +0 -95
  114. package/src/components/logo/index.ts +0 -2
  115. package/src/components/message-bubble/ds-mobile-message-bubble.ts +0 -633
  116. package/src/components/message-bubble/index.ts +0 -7
  117. package/src/components/message-composer/ds-mobile-message-composer.ts +0 -1146
  118. package/src/components/message-composer/index.ts +0 -7
  119. package/src/components/modal/ds-mobile-modal.css +0 -163
  120. package/src/components/modal/ds-mobile-modal.service.ts +0 -329
  121. package/src/components/modal/index.ts +0 -8
  122. package/src/components/modal-base/ds-mobile-modal-base.css +0 -378
  123. package/src/components/modal-base/ds-mobile-modal-base.ts +0 -261
  124. package/src/components/modal-base/index.ts +0 -2
  125. package/src/components/new-inquiry-modal/ds-mobile-new-inquiry-modal.css +0 -112
  126. package/src/components/new-inquiry-modal/ds-mobile-new-inquiry-modal.service.ts +0 -93
  127. package/src/components/new-inquiry-modal/ds-mobile-new-inquiry-modal.ts +0 -442
  128. package/src/components/new-inquiry-modal/index.ts +0 -4
  129. package/src/components/offline-banner/ds-mobile-offline-banner.ts +0 -135
  130. package/src/components/offline-banner/index.ts +0 -1
  131. package/src/components/page-details/ds-mobile-page-details.css +0 -83
  132. package/src/components/page-details/ds-mobile-page-details.ts +0 -282
  133. package/src/components/page-details/index.ts +0 -2
  134. package/src/components/page-main/ds-mobile-page-main.css +0 -68
  135. package/src/components/page-main/ds-mobile-page-main.ts +0 -421
  136. package/src/components/page-main/index.ts +0 -2
  137. package/src/components/post-composer/ds-mobile-post-composer.ts +0 -140
  138. package/src/components/post-composer/index.ts +0 -2
  139. package/src/components/post-detail-modal/ds-mobile-post-detail-modal.css +0 -390
  140. package/src/components/post-detail-modal/ds-mobile-post-detail-modal.service.ts +0 -108
  141. package/src/components/post-detail-modal/ds-mobile-post-detail-modal.ts +0 -722
  142. package/src/components/post-detail-modal/index.ts +0 -9
  143. package/src/components/property-banner/ds-mobile-property-banner.ts +0 -95
  144. package/src/components/property-banner/index.ts +0 -2
  145. package/src/components/section/ds-mobile-section.ts +0 -263
  146. package/src/components/section/index.ts +0 -2
  147. package/src/components/shared/directives/index.ts +0 -2
  148. package/src/components/shared/directives/long-press.directive.ts +0 -212
  149. package/src/components/shared/index.ts +0 -3
  150. package/src/components/shared/mobile-modal-base.ts +0 -457
  151. package/src/components/shared/mobile-page-base.ts +0 -204
  152. package/src/components/swiper/ds-mobile-swiper-with-nav.ts +0 -160
  153. package/src/components/swiper/ds-mobile-swiper.ts +0 -327
  154. package/src/components/swiper/index.ts +0 -3
  155. package/src/components/system-message-banner/ds-mobile-system-message-banner.ts +0 -129
  156. package/src/components/system-message-banner/index.ts +0 -2
  157. package/src/components/tab-bar/ds-mobile-tab-bar.css +0 -533
  158. package/src/components/tab-bar/ds-mobile-tab-bar.ts +0 -735
  159. package/src/components/tab-bar/index.ts +0 -2
  160. package/src/components/tabs/ds-mobile-tabs.css +0 -25
  161. package/src/components/tabs/ds-mobile-tabs.ts +0 -89
  162. package/src/components/tabs/index.ts +0 -2
  163. package/src/components/text-input/ds-text-input.ts +0 -287
  164. package/src/components/text-input/index.ts +0 -2
  165. package/src/examples/booking.page.ts +0 -434
  166. package/src/examples/community.page.ts +0 -776
  167. package/src/examples/handbook.page.ts +0 -324
  168. package/src/examples/home.page.ts +0 -347
  169. package/src/examples/index.ts +0 -12
  170. package/src/examples/inquiries.example.ts +0 -273
  171. package/src/examples/inquiry-detail.example.css +0 -189
  172. package/src/examples/inquiry-detail.example.ts +0 -415
  173. package/src/examples/mobile-tabs-example.component.ts +0 -208
  174. package/src/examples/post-create.page.ts +0 -311
  175. package/src/examples/post-detail.page.ts +0 -296
  176. package/src/examples/sign-in.page.ts +0 -291
  177. package/src/examples/whitelabel-demo-modal.component.ts +0 -1094
  178. package/src/examples/whitelabel-demo-modal.service.ts +0 -77
  179. package/src/models/index.ts +0 -7
  180. package/src/models/post.model.ts +0 -41
  181. package/src/pages/community.page.ts +0 -769
  182. package/src/pages/handbook.page.ts +0 -388
  183. package/src/pages/home.page.ts +0 -303
  184. package/src/pages/index.ts +0 -11
  185. package/src/pages/inquiries.example.ts +0 -273
  186. package/src/pages/inquiry-detail.example.css +0 -189
  187. package/src/pages/inquiry-detail.example.ts +0 -415
  188. package/src/pages/mobile-tabs-example.component.ts +0 -179
  189. package/src/pages/post-create.page.ts +0 -311
  190. package/src/pages/post-detail.page.ts +0 -296
  191. package/src/pages/sign-in.page.ts +0 -291
  192. package/src/pages/whitelabel-demo-modal.component.ts +0 -1094
  193. package/src/pages/whitelabel-demo-modal.service.ts +0 -77
  194. package/src/public-api.ts +0 -6
  195. package/src/services/base-modal.service.ts +0 -101
  196. package/src/services/index.ts +0 -11
  197. package/src/services/posts.service.ts +0 -542
  198. package/src/services/tracking-permission.service.ts +0 -88
  199. package/src/services/user.service.ts +0 -60
  200. package/src/services/whitelabel.service.ts +0 -675
  201. package/tsconfig.lib.json +0 -17
  202. package/tsconfig.lib.prod.json +0 -9
  203. package/tsconfig.spec.json +0 -13
  204. /package/{src/assets → assets}/fonts/Brockmann-Bold.otf +0 -0
  205. /package/{src/assets → assets}/fonts/Brockmann-BoldItalic.otf +0 -0
  206. /package/{src/assets → assets}/fonts/Brockmann-Medium.otf +0 -0
  207. /package/{src/assets → assets}/fonts/Brockmann-MediumItalic.otf +0 -0
  208. /package/{src/assets → assets}/fonts/Brockmann-Regular.otf +0 -0
  209. /package/{src/assets → assets}/fonts/Brockmann-RegularItalic.otf +0 -0
  210. /package/{src/assets → assets}/fonts/Brockmann-SemiBold.otf +0 -0
  211. /package/{src/assets → assets}/fonts/Brockmann-SemiBoldItalic.otf +0 -0
  212. /package/{src/assets → assets}/fonts/Brockmann_desktop_license.pdf +0 -0
  213. /package/{src/assets → assets}/fonts/brockmann-medium-webfont.woff2 +0 -0
  214. /package/{src/assets → assets}/fonts/brockmann-mediumitalic-webfont.woff2 +0 -0
  215. /package/{src/assets → assets}/fonts/brockmann-regular-webfont.woff2 +0 -0
  216. /package/{src/assets → assets}/fonts/brockmann-regularitalic-webfont.woff2 +0 -0
  217. /package/{src/assets → assets}/fonts/brockmann-semibold-webfont.woff2 +0 -0
  218. /package/{src/assets → assets}/fonts/brockmann-semibolditalic-webfont.woff2 +0 -0
  219. /package/{src/styles → styles}/ionic.css +0 -0
  220. /package/{src/components/shared → styles}/mobile-common.css +0 -0
  221. /package/{src/components/shared → styles}/mobile-page-base.css +0 -0
@@ -1,614 +0,0 @@
1
- import {
2
- Component,
3
- Input,
4
- signal,
5
- computed,
6
- ViewChild,
7
- ElementRef,
8
- afterNextRender,
9
- Injector,
10
- OnInit,
11
- OnChanges,
12
- SimpleChanges,
13
- } from '@angular/core';
14
- import { CommonModule } from '@angular/common';
15
- import { ModalController } from '@ionic/angular/standalone';
16
- import { DsIconComponent, DsIconButtonComponent } from '@propbinder/design-system';
17
- import { DsMobileActionListItemComponent } from '../action-list-item/ds-mobile-action-list-item';
18
- import { ActionResult, ActionItem, ActionGroup } from './ds-mobile-actions-bottom-sheet';
19
- import { DsMobileBottomSheetWrapperComponent } from './ds-mobile-bottom-sheet-wrapper';
20
- import { DsMobileBottomSheetHeaderComponent } from './ds-mobile-bottom-sheet-header';
21
-
22
- export interface Language {
23
- code: string;
24
- nativeName: string;
25
- englishName: string;
26
- flagIcon: string; // Path to flag SVG or icon name
27
- }
28
-
29
- /**
30
- * DsMobileProfileActionsSheetComponent
31
- *
32
- * Bottom sheet for profile actions with navigable language selection.
33
- * Features a smooth slide-in navigation pattern for sub-menus.
34
- *
35
- * @example
36
- * ```typescript
37
- * const sheet = await this.modalController.create({
38
- * component: DsMobileProfileActionsSheetComponent,
39
- * componentProps: {
40
- * actionGroups: [...],
41
- * currentLanguage: 'da',
42
- * availableLanguages: [...]
43
- * },
44
- * breakpoints: [0, 1],
45
- * initialBreakpoint: 1,
46
- * handle: true,
47
- * cssClass: ['ds-bottom-sheet', 'auto-height']
48
- * });
49
- *
50
- * const result = await sheet.onWillDismiss();
51
- * if (result.data?.action) {
52
- * // Handle the action (e.g., 'language:da', 'profile', 'logout')
53
- * }
54
- * ```
55
- */
56
- @Component({
57
- selector: 'ds-mobile-profile-actions-sheet',
58
- standalone: true,
59
- imports: [CommonModule, DsIconComponent, DsMobileActionListItemComponent, DsMobileBottomSheetWrapperComponent, DsMobileBottomSheetHeaderComponent],
60
- template: `
61
- <ds-mobile-bottom-sheet-wrapper>
62
- <div class="profile-sheet-content" #sheetWrapper>
63
- <!-- View Container with CSS Animation -->
64
- <div class="view-container" #viewContainer
65
- [class.show-language]="currentView() === 'language'"
66
- [class.is-animating]="isAnimating()"
67
- [style.height.px]="isAnimating() ? containerHeight() : null">
68
- <!-- Main Actions View -->
69
- <div class="view main-view" [class.active]="currentView() === 'main'">
70
- <div class="actions-list">
71
- @for (group of actionGroups; track $index; let isLast = $last) {
72
- <!-- Action Group -->
73
- <div class="action-group">
74
- @for (actionItem of group.actions; track actionItem.action; let isLastInGroup = $last) {
75
- <ds-mobile-action-list-item
76
- [title]="actionItem.title"
77
- [showDivider]="!isLastInGroup"
78
- [class.destructive]="actionItem.destructive"
79
- (itemClick)="handleActionClick(actionItem)"
80
- >
81
- <ds-icon action-icon [name]="actionItem.icon" size="20px" [class.destructive-icon]="actionItem.destructive" />
82
-
83
- @if (actionItem.showChevron || actionItem.subtitle || actionItem.flagIcon) {
84
- <div content-trailing class="trailing-content">
85
- @if (actionItem.flagIcon) {
86
- <img [src]="actionItem.flagIcon" [alt]="actionItem.title + ' flag'" class="subtitle-flag" />
87
- } @if (actionItem.subtitle) {
88
- <span class="subtitle">{{ actionItem.subtitle }}</span>
89
- } @if (actionItem.showChevron) {
90
- <ds-icon name="remixArrowRightSLine" size="20px" class="chevron-icon" />
91
- }
92
- </div>
93
- }
94
- </ds-mobile-action-list-item>
95
- }
96
- </div>
97
-
98
- <!-- Full-width divider between groups -->
99
- @if (!isLast) {
100
- <div class="action-group-divider"></div>
101
- } }
102
- </div>
103
- </div>
104
-
105
- <!-- Language Selection View -->
106
- <div class="view language-view" [class.active]="currentView() === 'language'">
107
- <!-- Header with back and done buttons -->
108
- <ds-mobile-bottom-sheet-header
109
- title="Sprog"
110
- leftButtonLabel="Tilbage"
111
- rightButtonLabel="Færdig"
112
- [rightButtonDisabled]="!hasLanguageChanged()"
113
- (leftButtonClick)="navigateBack()"
114
- (rightButtonClick)="confirmLanguageSelection()">
115
- </ds-mobile-bottom-sheet-header>
116
-
117
- <!-- Language Options -->
118
- <div class="language-list">
119
- @for (language of availableLanguages; track language.code; let isLast = $last) {
120
- <ds-mobile-action-list-item [title]="language.nativeName" [showDivider]="!isLast" (itemClick)="selectLanguage(language.code)">
121
- <!-- Country Flag -->
122
- <img action-icon [src]="language.flagIcon" [alt]="language.englishName + ' flag'" class="language-flag" />
123
-
124
- <!-- Radio Indicator in trailing slot -->
125
- <div content-trailing class="radio-wrapper">
126
- <div class="radio-indicator" [class.radio-checked]="language.code === selectedLanguage()">
127
- <div class="radio-inner"></div>
128
- </div>
129
- </div>
130
- </ds-mobile-action-list-item>
131
- }
132
- </div>
133
- </div>
134
- </div>
135
- </div>
136
- </ds-mobile-bottom-sheet-wrapper>
137
- `,
138
- styles: [
139
- `
140
- :host {
141
- display: block;
142
- height: auto;
143
- }
144
-
145
- .profile-sheet-content {
146
- overflow: hidden;
147
- width: 100%;
148
- }
149
-
150
- /* View Container - holds both views side by side */
151
- .view-container {
152
- display: grid;
153
- grid-template-columns: 50% 50%;
154
- width: 200%;
155
- transform: translateX(0);
156
- transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), height 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.15s ease-in-out;
157
- overflow: hidden;
158
- /* Height will be set dynamically via inline style */
159
- }
160
-
161
- .view-container.show-language {
162
- transform: translateX(-50%);
163
- }
164
-
165
- /* Individual Views */
166
- .view {
167
- width: 100%;
168
- /* Remove any min-height constraints */
169
- }
170
-
171
- .view-container:not(.is-animating) .view:not(.active) {
172
- height: 0 !important;
173
- overflow: hidden !important;
174
- }
175
-
176
- /* Main View */
177
- .main-view {
178
- padding-top: 16px;
179
- }
180
-
181
- .actions-list {
182
- display: flex;
183
- flex-direction: column;
184
- }
185
-
186
- .action-group {
187
- display: flex;
188
- flex-direction: column;
189
- padding: 0 16px;
190
- }
191
-
192
- /* Language View */
193
- .language-view {
194
- display: flex;
195
- flex-direction: column;
196
- }
197
-
198
- /* Language list styles */
199
- .language-list {
200
- padding: 8px 16px;
201
- }
202
-
203
- .language-flag {
204
- width: 24px;
205
- height: 24px;
206
- object-fit: cover;
207
- }
208
-
209
- /* Radio wrapper to ensure proper positioning */
210
- .radio-wrapper {
211
- display: flex;
212
- align-items: center;
213
- justify-content: center;
214
- }
215
-
216
- /* Radio Button Indicator (Custom styled to match DS radio) */
217
- .radio-indicator {
218
- width: 20px;
219
- height: 20px;
220
- border: 2px solid var(--color-border-default, #d1d5db);
221
- border-radius: 50%;
222
- display: flex;
223
- align-items: center;
224
- justify-content: center;
225
- transition: all 0.2s ease;
226
- flex-shrink: 0;
227
- }
228
-
229
- .radio-indicator.radio-checked {
230
- border-color: var(--color-accent, #7c3aed);
231
- }
232
-
233
- .radio-inner {
234
- width: 10px;
235
- height: 10px;
236
- border-radius: 50%;
237
- background: transparent;
238
- transition: background 0.2s ease;
239
- }
240
-
241
- .radio-checked .radio-inner {
242
- background: var(--color-accent, #7c3aed);
243
- }
244
-
245
- /* Trailing Content (Subtitle + Chevron) */
246
- .trailing-content {
247
- display: flex;
248
- align-items: center;
249
- gap: 8px;
250
- }
251
-
252
- .subtitle-flag {
253
- width: 16px;
254
- height: 16px;
255
- object-fit: cover;
256
- border-radius: 2px;
257
- }
258
-
259
- .subtitle {
260
- font-size: 15px;
261
- color: var(--color-text-subtle, #6b7280);
262
- line-height: 20px;
263
- }
264
-
265
- .chevron-icon {
266
- color: var(--color-text-secondary, #737373);
267
- }
268
-
269
- .check-icon {
270
- color: var(--color-primary-base, #7c3aed);
271
- }
272
-
273
- /* Override default background for action items */
274
- ::ng-deep ds-mobile-action-list-item ds-mobile-list-item {
275
- --color-background-primary: transparent;
276
- --color-background-neutral-primary-hover: var(--color-background-neutral-secondary, #f5f5f5);
277
- }
278
-
279
- ::ng-deep ds-mobile-action-list-item ds-mobile-list-item .list-item-inner::before {
280
- z-index: 0 !important;
281
- }
282
-
283
- ::ng-deep ds-mobile-action-list-item ds-mobile-list-item .content-leading,
284
- ::ng-deep ds-mobile-action-list-item ds-mobile-list-item .content-main,
285
- ::ng-deep ds-mobile-action-list-item ds-mobile-list-item .content-trailing {
286
- position: relative;
287
- z-index: 1;
288
- }
289
-
290
- /* Destructive action styling */
291
- ds-mobile-action-list-item.destructive {
292
- --text-color-default-primary: var(--color-error-base, #ef4444);
293
- }
294
-
295
- .destructive-icon {
296
- color: var(--color-error-base, #ef4444);
297
- }
298
-
299
- /* Full-width divider between action groups */
300
- .action-group-divider {
301
- height: 1px;
302
- background: var(--color-border-subtle, #e5e5e5);
303
- margin: 8px 0;
304
- }
305
- `,
306
- ],
307
- })
308
- export class DsMobileProfileActionsSheetComponent implements OnInit, OnChanges {
309
- /**
310
- * Action groups to display in main view
311
- */
312
- @Input() actionGroups: ActionGroup[] = [];
313
-
314
- /**
315
- * Currently selected language code
316
- */
317
- @Input() currentLanguage: string = 'da';
318
-
319
- /**
320
- * Initial language (for tracking changes)
321
- */
322
- private initialLanguage: string = '';
323
-
324
- /**
325
- * Currently selected language in the view (before confirmation)
326
- */
327
- selectedLanguage = signal<string>('');
328
-
329
- /**
330
- * Check if language has changed
331
- */
332
- hasLanguageChanged = computed(() => {
333
- return this.selectedLanguage() !== this.initialLanguage && this.selectedLanguage() !== '';
334
- });
335
-
336
- /**
337
- * Available languages for selection
338
- */
339
- @Input() availableLanguages: Language[] = [
340
- {
341
- code: 'da',
342
- nativeName: 'Dansk',
343
- englishName: 'Danish',
344
- flagIcon: '/Assets/country-flags/denmark.svg',
345
- },
346
- {
347
- code: 'en',
348
- nativeName: 'English',
349
- englishName: 'English',
350
- flagIcon: '/Assets/country-flags/united kingdom.svg',
351
- },
352
- {
353
- code: 'sv',
354
- nativeName: 'Svenska',
355
- englishName: 'Swedish',
356
- flagIcon: '/Assets/country-flags/sweden.svg',
357
- },
358
- {
359
- code: 'no',
360
- nativeName: 'Norsk',
361
- englishName: 'Norwegian',
362
- flagIcon: '/Assets/country-flags/norway.svg',
363
- },
364
- {
365
- code: 'de',
366
- nativeName: 'Deutsch',
367
- englishName: 'German',
368
- flagIcon: '/Assets/country-flags/germany.svg',
369
- },
370
- ];
371
-
372
- /**
373
- * Current view state
374
- */
375
- currentView = signal<'main' | 'language'>('main');
376
-
377
- /**
378
- * Reference to the view container for height calculations
379
- */
380
- @ViewChild('viewContainer', { read: ElementRef })
381
- viewContainer?: ElementRef<HTMLDivElement>;
382
-
383
- /**
384
- * Reference to the profile actions sheet wrapper
385
- */
386
- @ViewChild('sheetWrapper', { read: ElementRef })
387
- sheetWrapper?: ElementRef<HTMLDivElement>;
388
-
389
- /**
390
- * Current container height (for dynamic transitions)
391
- */
392
- containerHeight = signal<number | null>(null);
393
-
394
- /**
395
- * Is animating between views
396
- */
397
- isAnimating = signal<boolean>(false);
398
-
399
- constructor(private modalController: ModalController, private injector: Injector) {
400
- // Set initial height after render
401
- afterNextRender(
402
- () => {
403
- this.updateHeight();
404
- },
405
- { injector: this.injector }
406
- );
407
- }
408
-
409
- ngOnChanges(changes: SimpleChanges): void {
410
- if (changes['currentLanguage']) {
411
- const val = changes['currentLanguage'].currentValue;
412
- if (val) {
413
- this.selectedLanguage.set(val);
414
- this.initialLanguage = val;
415
- }
416
- }
417
- }
418
-
419
- ngOnInit(): void {
420
- // Try to get language from localStorage as fallback
421
- const storedLangCode = this.getLanguageFromStorage();
422
-
423
- if (storedLangCode) {
424
- this.selectedLanguage.set(storedLangCode);
425
- this.initialLanguage = storedLangCode;
426
- } else if (!this.selectedLanguage()) {
427
- // Fallback to input if storage is empty
428
- this.selectedLanguage.set(this.currentLanguage);
429
- this.initialLanguage = this.currentLanguage;
430
- }
431
- }
432
-
433
- /**
434
- * Try to resolve short language code from localStorage ('selectedLanguage' key)
435
- */
436
- private getLanguageFromStorage(): string | null {
437
- try {
438
- const stored = localStorage.getItem('selectedLanguage'); // e.g. "da-DK", "sv-SE"
439
- if (!stored) return null;
440
-
441
- // Find the code from availableLanguages that matches this locale/string
442
- // We check if any language code is part of the stored string (e.g. 'da' in 'da-DK')
443
- const match = this.availableLanguages.find(lang =>
444
- lang.code === stored || stored.startsWith(lang.code + '-')
445
- );
446
-
447
- return match ? match.code : null;
448
- } catch (e) {
449
- return null;
450
- }
451
- }
452
-
453
- /**
454
- * Handle action item click
455
- */
456
- handleActionClick(actionItem: ActionItem): void {
457
- // If it's the language action, navigate to language view
458
- if (actionItem.action === 'language') {
459
- this.animateViewTransition('language');
460
- return;
461
- }
462
-
463
- // Otherwise, dismiss with the action
464
- this.selectAction(actionItem.action);
465
- }
466
-
467
- /**
468
- * Navigate back to main view
469
- */
470
- navigateBack(): void {
471
- if (this.currentView() === 'language') {
472
- this.animateViewTransition('main');
473
- }
474
- }
475
-
476
- /**
477
- * Confirm language selection and dismiss
478
- */
479
- confirmLanguageSelection(): void {
480
- if (this.hasLanguageChanged()) {
481
- this.modalController.dismiss({ action: `language:${this.selectedLanguage()}` } as ActionResult, 'select');
482
- } else {
483
- // If no change, just go back
484
- this.navigateBack();
485
- }
486
- }
487
-
488
- /**
489
- * Handle language selection (update selection, don't dismiss)
490
- */
491
- selectLanguage(languageCode: string): void {
492
- this.selectedLanguage.set(languageCode);
493
- }
494
-
495
- /**
496
- * Get current language flag icon
497
- */
498
- getCurrentLanguageFlag(): string {
499
- const language = this.availableLanguages.find((lang) => lang.code === this.currentLanguage);
500
- return language?.flagIcon || '';
501
- }
502
-
503
- /**
504
- * Update container height based on active view
505
- */
506
- private updateHeight(): void {
507
- if (!this.viewContainer || !this.sheetWrapper) return;
508
-
509
- const container = this.viewContainer.nativeElement;
510
- const activeView = this.currentView() === 'main' ? container.querySelector('.main-view') : container.querySelector('.language-view');
511
-
512
- if (activeView instanceof HTMLElement) {
513
- const height = activeView.scrollHeight;
514
- this.containerHeight.set(height);
515
- }
516
- }
517
-
518
- /**
519
- * Animate view transition with height change
520
- */
521
- private async animateViewTransition(toView: 'main' | 'language'): Promise<void> {
522
- if (!this.viewContainer || !this.sheetWrapper || this.isAnimating()) return;
523
-
524
- this.isAnimating.set(true);
525
-
526
- const container = this.viewContainer.nativeElement;
527
-
528
- // Step 1: Fade out current view (150ms)
529
- container.style.opacity = '0';
530
-
531
- await this.delay(150);
532
-
533
- // Step 2: Measure target view height
534
- // We need to temporarily position it to measure accurately
535
- const mainView = container.querySelector('.main-view') as HTMLElement;
536
- const langView = container.querySelector('.language-view') as HTMLElement;
537
- const targetView = toView === 'main' ? mainView : langView;
538
-
539
- // Temporarily make both views absolute positioned at same location to measure
540
- const containerStyle = window.getComputedStyle(container);
541
- const currentHeight = container.offsetHeight;
542
-
543
- // Save current state
544
- const savedTransition = container.style.transition;
545
- const savedTransform = container.style.transform;
546
-
547
- // Disable transitions and position target view for measurement
548
- container.style.transition = 'none';
549
- container.style.height = `${currentHeight}px`;
550
-
551
- // Position target view to measure it
552
- if (mainView && langView) {
553
- mainView.style.position = 'absolute';
554
- mainView.style.left = '0';
555
- mainView.style.top = '0';
556
- mainView.style.width = '50%';
557
- mainView.style.visibility = toView === 'main' ? 'visible' : 'hidden';
558
-
559
- langView.style.position = 'absolute';
560
- langView.style.left = '0';
561
- langView.style.top = '0';
562
- langView.style.width = '50%';
563
- langView.style.visibility = toView === 'language' ? 'visible' : 'hidden';
564
- }
565
-
566
- // Force reflow and measure
567
- container.offsetHeight;
568
- const newHeight = targetView ? targetView.scrollHeight : currentHeight;
569
-
570
- // Restore grid layout
571
- if (mainView && langView) {
572
- mainView.style.position = '';
573
- mainView.style.left = '';
574
- mainView.style.top = '';
575
- mainView.style.width = '';
576
- mainView.style.visibility = '';
577
-
578
- langView.style.position = '';
579
- langView.style.left = '';
580
- langView.style.top = '';
581
- langView.style.width = '';
582
- langView.style.visibility = '';
583
- }
584
-
585
- // Wait a frame
586
- await this.delay(10);
587
-
588
- // Step 3: Re-enable transitions, switch view, and set new height
589
- container.style.transition = savedTransition || '';
590
- this.currentView.set(toView);
591
- this.containerHeight.set(newHeight);
592
-
593
- // Step 4: Wait for height animation (300ms) then fade in
594
- await this.delay(250);
595
- container.style.opacity = '1';
596
-
597
- await this.delay(150);
598
- this.isAnimating.set(false);
599
- }
600
-
601
- /**
602
- * Helper to create delay promise
603
- */
604
- private delay(ms: number): Promise<void> {
605
- return new Promise((resolve) => setTimeout(resolve, ms));
606
- }
607
-
608
- /**
609
- * Handle regular action selection
610
- */
611
- selectAction(action: string): void {
612
- this.modalController.dismiss({ action } as ActionResult, 'select');
613
- }
614
- }
@@ -1,8 +0,0 @@
1
- export * from './ds-mobile-actions-bottom-sheet';
2
- export * from './ds-mobile-bottom-sheet.service';
3
- export * from './ds-mobile-bottom-sheet-wrapper';
4
- export * from './ds-mobile-bottom-sheet-header';
5
- export * from './ds-mobile-confirmation-sheet';
6
- export * from './ds-mobile-post-create-bottom-sheet';
7
- export { DsMobileProfileActionsSheetComponent } from './ds-mobile-profile-actions-sheet';
8
- export type { Language } from './ds-mobile-profile-actions-sheet';
@@ -1,42 +0,0 @@
1
- /**
2
- * Disable pointer events for Ionic's internal modal shadow layer.
3
- *
4
- * The .modal-shadow element is rendered inside ion-modal's Shadow DOM and can
5
- * intercept backdrop taps even when visually hidden.
6
- */
7
- export function disableModalShadowPointerEvents(modal: HTMLIonModalElement): void {
8
- const applyFix = () => {
9
- const modalShadow = modal.shadowRoot?.querySelector<HTMLElement>('.modal-shadow');
10
- if (!modalShadow) {
11
- return;
12
- }
13
-
14
- modalShadow.style.setProperty('pointer-events', 'none', 'important');
15
- modalShadow.style.setProperty('box-shadow', 'none', 'important');
16
- };
17
-
18
- applyFix();
19
-
20
- if (!modal.shadowRoot) {
21
- return;
22
- }
23
-
24
- const observer = new MutationObserver(() => {
25
- applyFix();
26
- });
27
-
28
- observer.observe(modal.shadowRoot, {
29
- childList: true,
30
- subtree: true,
31
- attributes: true,
32
- attributeFilter: ['class', 'style'],
33
- });
34
-
35
- modal.addEventListener(
36
- 'ionModalDidDismiss',
37
- () => {
38
- observer.disconnect();
39
- },
40
- { once: true }
41
- );
42
- }