@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.
- package/fesm2022/propbinder-mobile-design.mjs +26206 -0
- package/fesm2022/propbinder-mobile-design.mjs.map +1 -0
- package/index.d.ts +8193 -0
- package/package.json +39 -3
- package/ng-package.json +0 -24
- package/src/animations/page-transitions.ts +0 -165
- package/src/components/action-list-item/ds-mobile-action-list-item.ts +0 -102
- package/src/components/action-list-item/index.ts +0 -2
- package/src/components/app-icon/ds-app-icon.ts +0 -133
- package/src/components/app-icon/index.ts +0 -2
- package/src/components/attachment-preview/ds-mobile-attachment-preview.css +0 -139
- package/src/components/attachment-preview/ds-mobile-attachment-preview.ts +0 -164
- package/src/components/attachment-preview/index.ts +0 -1
- package/src/components/avatar-with-badge/ds-avatar-with-badge.ts +0 -142
- package/src/components/avatar-with-badge/index.ts +0 -2
- package/src/components/booking-modal/ds-mobile-booking-confirmation-wrapper.ts +0 -71
- package/src/components/booking-modal/ds-mobile-booking-modal.service.ts +0 -121
- package/src/components/booking-modal/ds-mobile-booking-modal.ts +0 -598
- package/src/components/booking-modal/ds-mobile-booking-summary.ts +0 -161
- package/src/components/booking-modal/index.ts +0 -4
- package/src/components/bottom-sheet/ds-mobile-actions-bottom-sheet.ts +0 -266
- package/src/components/bottom-sheet/ds-mobile-bottom-sheet-header.ts +0 -146
- package/src/components/bottom-sheet/ds-mobile-bottom-sheet-wrapper.ts +0 -156
- package/src/components/bottom-sheet/ds-mobile-bottom-sheet.css +0 -101
- package/src/components/bottom-sheet/ds-mobile-bottom-sheet.service.ts +0 -169
- package/src/components/bottom-sheet/ds-mobile-confirmation-sheet.ts +0 -211
- package/src/components/bottom-sheet/ds-mobile-post-create-bottom-sheet.ts +0 -578
- package/src/components/bottom-sheet/ds-mobile-profile-actions-sheet.ts +0 -614
- package/src/components/bottom-sheet/index.ts +0 -8
- package/src/components/bottom-sheet/modal-shadow-fix.ts +0 -42
- package/src/components/card-inline/ds-mobile-card-inline.ts +0 -301
- package/src/components/card-inline/index.ts +0 -2
- package/src/components/card-inline-banner/ds-mobile-card-inline-banner.ts +0 -118
- package/src/components/card-inline-banner/index.ts +0 -1
- package/src/components/card-inline-contact/ds-mobile-card-inline-contact.ts +0 -120
- package/src/components/card-inline-contact/index.ts +0 -1
- package/src/components/card-inline-file/ds-mobile-card-inline-file.ts +0 -141
- package/src/components/card-inline-file/index.ts +0 -1
- package/src/components/chat-modal/ds-mobile-chat-modal.css +0 -159
- package/src/components/chat-modal/ds-mobile-chat-modal.service.ts +0 -105
- package/src/components/chat-modal/ds-mobile-chat-modal.ts +0 -918
- package/src/components/chat-modal/index.ts +0 -8
- package/src/components/comment/ds-mobile-comment.ts +0 -568
- package/src/components/comment/index.ts +0 -2
- package/src/components/contact-list-item/ds-mobile-contact-list-item.ts +0 -182
- package/src/components/contact-list-item/index.ts +0 -2
- package/src/components/content/ds-mobile-content.ts +0 -139
- package/src/components/content/index.ts +0 -2
- package/src/components/dropdown/ds-mobile-dropdown.css +0 -199
- package/src/components/dropdown/ds-mobile-dropdown.ts +0 -340
- package/src/components/dropdown/index.ts +0 -2
- package/src/components/ds-mobile-tabs.css +0 -407
- package/src/components/ds-mobile-tabs.ts +0 -216
- package/src/components/empty-state/ds-mobile-empty-state.ts +0 -120
- package/src/components/empty-state/index.ts +0 -2
- package/src/components/fab/ds-mobile-fab.ts +0 -315
- package/src/components/fab/index.ts +0 -1
- package/src/components/facility-creation-modal/ds-mobile-facility-creation-confirmation-wrapper.ts +0 -121
- package/src/components/facility-creation-modal/ds-mobile-facility-creation-modal.css +0 -189
- package/src/components/facility-creation-modal/ds-mobile-facility-creation-modal.service.ts +0 -135
- package/src/components/facility-creation-modal/ds-mobile-facility-creation-modal.ts +0 -656
- package/src/components/facility-creation-modal/index.ts +0 -9
- package/src/components/facility-creation-modal/sheets/ds-mobile-access-sheet.ts +0 -105
- package/src/components/facility-creation-modal/sheets/ds-mobile-price-sheet.ts +0 -188
- package/src/components/facility-creation-modal/sheets/ds-mobile-when-can-book-sheet.ts +0 -460
- package/src/components/facility-creation-modal/sheets/ds-mobile-who-can-book-sheet.ts +0 -134
- package/src/components/facility-detail-modal/ds-mobile-facility-detail-modal.service.ts +0 -69
- package/src/components/facility-detail-modal/ds-mobile-facility-detail-modal.ts +0 -379
- package/src/components/facility-detail-modal/index.ts +0 -2
- package/src/components/file-attachment/ds-mobile-file-attachment.ts +0 -164
- package/src/components/file-attachment/index.ts +0 -2
- package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.css +0 -214
- package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.service.ts +0 -84
- package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.ts +0 -424
- package/src/components/handbook-detail-modal/index.ts +0 -3
- package/src/components/handbook-folder/ds-mobile-handbook-folder-mini.ts +0 -175
- package/src/components/handbook-folder/ds-mobile-handbook-folder.ts +0 -533
- package/src/components/handbook-folder/index.ts +0 -4
- package/src/components/header-content/ds-mobile-header-content.ts +0 -222
- package/src/components/header-content/index.ts +0 -2
- package/src/components/illustration/ds-mobile-illustration.ts +0 -124
- package/src/components/illustration/index.ts +0 -2
- package/src/components/index.ts +0 -124
- package/src/components/inline-photo/ds-mobile-inline-photo.ts +0 -361
- package/src/components/inline-photo/index.ts +0 -1
- package/src/components/inline-tabs/ds-mobile-inline-tabs.ts +0 -132
- package/src/components/inline-tabs/index.ts +0 -2
- package/src/components/interactive-list-item-booking/ds-mobile-interactive-list-item-booking.ts +0 -350
- package/src/components/interactive-list-item-booking/index.ts +0 -1
- package/src/components/interactive-list-item-inquiry/ds-mobile-interactive-list-item-inquiry.ts +0 -321
- package/src/components/interactive-list-item-inquiry/index.ts +0 -2
- package/src/components/interactive-list-item-message/ds-mobile-interactive-list-item-message.ts +0 -237
- package/src/components/interactive-list-item-message/index.ts +0 -2
- package/src/components/interactive-list-item-post/ds-mobile-interactive-list-item-post.ts +0 -549
- package/src/components/interactive-list-item-post/ds-mobile-post-pdf-attachment.ts +0 -124
- package/src/components/interactive-list-item-post/index.ts +0 -13
- package/src/components/lightbox/ds-mobile-lightbox-footer.ts +0 -315
- package/src/components/lightbox/ds-mobile-lightbox-header.ts +0 -202
- package/src/components/lightbox/ds-mobile-lightbox-image.ts +0 -484
- package/src/components/lightbox/ds-mobile-lightbox-pdf.css +0 -377
- package/src/components/lightbox/ds-mobile-lightbox-pdf.ts +0 -374
- package/src/components/lightbox/ds-mobile-lightbox.css +0 -587
- package/src/components/lightbox/ds-mobile-lightbox.service.ts +0 -296
- package/src/components/lightbox/ds-mobile-lightbox.ts +0 -529
- package/src/components/lightbox/index.ts +0 -22
- package/src/components/list-item/ds-mobile-list-item.ts +0 -603
- package/src/components/list-item/index.ts +0 -2
- package/src/components/list-item-static/ds-mobile-list-item-static.ts +0 -133
- package/src/components/list-item-static/index.ts +0 -2
- package/src/components/loader-overlay/ds-mobile-loader-overlay.css +0 -49
- package/src/components/loader-overlay/ds-mobile-loader-overlay.ts +0 -77
- package/src/components/loader-overlay/index.ts +0 -1
- package/src/components/logo/ds-logo.ts +0 -95
- package/src/components/logo/index.ts +0 -2
- package/src/components/message-bubble/ds-mobile-message-bubble.ts +0 -633
- package/src/components/message-bubble/index.ts +0 -7
- package/src/components/message-composer/ds-mobile-message-composer.ts +0 -1146
- package/src/components/message-composer/index.ts +0 -7
- package/src/components/modal/ds-mobile-modal.css +0 -163
- package/src/components/modal/ds-mobile-modal.service.ts +0 -329
- package/src/components/modal/index.ts +0 -8
- package/src/components/modal-base/ds-mobile-modal-base.css +0 -378
- package/src/components/modal-base/ds-mobile-modal-base.ts +0 -261
- package/src/components/modal-base/index.ts +0 -2
- package/src/components/new-inquiry-modal/ds-mobile-new-inquiry-modal.css +0 -112
- package/src/components/new-inquiry-modal/ds-mobile-new-inquiry-modal.service.ts +0 -93
- package/src/components/new-inquiry-modal/ds-mobile-new-inquiry-modal.ts +0 -442
- package/src/components/new-inquiry-modal/index.ts +0 -4
- package/src/components/offline-banner/ds-mobile-offline-banner.ts +0 -135
- package/src/components/offline-banner/index.ts +0 -1
- package/src/components/page-details/ds-mobile-page-details.css +0 -83
- package/src/components/page-details/ds-mobile-page-details.ts +0 -282
- package/src/components/page-details/index.ts +0 -2
- package/src/components/page-main/ds-mobile-page-main.css +0 -68
- package/src/components/page-main/ds-mobile-page-main.ts +0 -421
- package/src/components/page-main/index.ts +0 -2
- package/src/components/post-composer/ds-mobile-post-composer.ts +0 -140
- package/src/components/post-composer/index.ts +0 -2
- package/src/components/post-detail-modal/ds-mobile-post-detail-modal.css +0 -390
- package/src/components/post-detail-modal/ds-mobile-post-detail-modal.service.ts +0 -108
- package/src/components/post-detail-modal/ds-mobile-post-detail-modal.ts +0 -722
- package/src/components/post-detail-modal/index.ts +0 -9
- package/src/components/property-banner/ds-mobile-property-banner.ts +0 -95
- package/src/components/property-banner/index.ts +0 -2
- package/src/components/section/ds-mobile-section.ts +0 -263
- package/src/components/section/index.ts +0 -2
- package/src/components/shared/directives/index.ts +0 -2
- package/src/components/shared/directives/long-press.directive.ts +0 -212
- package/src/components/shared/index.ts +0 -3
- package/src/components/shared/mobile-modal-base.ts +0 -457
- package/src/components/shared/mobile-page-base.ts +0 -204
- package/src/components/swiper/ds-mobile-swiper-with-nav.ts +0 -160
- package/src/components/swiper/ds-mobile-swiper.ts +0 -327
- package/src/components/swiper/index.ts +0 -3
- package/src/components/system-message-banner/ds-mobile-system-message-banner.ts +0 -129
- package/src/components/system-message-banner/index.ts +0 -2
- package/src/components/tab-bar/ds-mobile-tab-bar.css +0 -533
- package/src/components/tab-bar/ds-mobile-tab-bar.ts +0 -735
- package/src/components/tab-bar/index.ts +0 -2
- package/src/components/tabs/ds-mobile-tabs.css +0 -25
- package/src/components/tabs/ds-mobile-tabs.ts +0 -89
- package/src/components/tabs/index.ts +0 -2
- package/src/components/text-input/ds-text-input.ts +0 -287
- package/src/components/text-input/index.ts +0 -2
- package/src/examples/booking.page.ts +0 -434
- package/src/examples/community.page.ts +0 -776
- package/src/examples/handbook.page.ts +0 -324
- package/src/examples/home.page.ts +0 -347
- package/src/examples/index.ts +0 -12
- package/src/examples/inquiries.example.ts +0 -273
- package/src/examples/inquiry-detail.example.css +0 -189
- package/src/examples/inquiry-detail.example.ts +0 -415
- package/src/examples/mobile-tabs-example.component.ts +0 -208
- package/src/examples/post-create.page.ts +0 -311
- package/src/examples/post-detail.page.ts +0 -296
- package/src/examples/sign-in.page.ts +0 -291
- package/src/examples/whitelabel-demo-modal.component.ts +0 -1094
- package/src/examples/whitelabel-demo-modal.service.ts +0 -77
- package/src/models/index.ts +0 -7
- package/src/models/post.model.ts +0 -41
- package/src/pages/community.page.ts +0 -769
- package/src/pages/handbook.page.ts +0 -388
- package/src/pages/home.page.ts +0 -303
- package/src/pages/index.ts +0 -11
- package/src/pages/inquiries.example.ts +0 -273
- package/src/pages/inquiry-detail.example.css +0 -189
- package/src/pages/inquiry-detail.example.ts +0 -415
- package/src/pages/mobile-tabs-example.component.ts +0 -179
- package/src/pages/post-create.page.ts +0 -311
- package/src/pages/post-detail.page.ts +0 -296
- package/src/pages/sign-in.page.ts +0 -291
- package/src/pages/whitelabel-demo-modal.component.ts +0 -1094
- package/src/pages/whitelabel-demo-modal.service.ts +0 -77
- package/src/public-api.ts +0 -6
- package/src/services/base-modal.service.ts +0 -101
- package/src/services/index.ts +0 -11
- package/src/services/posts.service.ts +0 -542
- package/src/services/tracking-permission.service.ts +0 -88
- package/src/services/user.service.ts +0 -60
- package/src/services/whitelabel.service.ts +0 -675
- package/tsconfig.lib.json +0 -17
- package/tsconfig.lib.prod.json +0 -9
- package/tsconfig.spec.json +0 -13
- /package/{src/assets → assets}/fonts/Brockmann-Bold.otf +0 -0
- /package/{src/assets → assets}/fonts/Brockmann-BoldItalic.otf +0 -0
- /package/{src/assets → assets}/fonts/Brockmann-Medium.otf +0 -0
- /package/{src/assets → assets}/fonts/Brockmann-MediumItalic.otf +0 -0
- /package/{src/assets → assets}/fonts/Brockmann-Regular.otf +0 -0
- /package/{src/assets → assets}/fonts/Brockmann-RegularItalic.otf +0 -0
- /package/{src/assets → assets}/fonts/Brockmann-SemiBold.otf +0 -0
- /package/{src/assets → assets}/fonts/Brockmann-SemiBoldItalic.otf +0 -0
- /package/{src/assets → assets}/fonts/Brockmann_desktop_license.pdf +0 -0
- /package/{src/assets → assets}/fonts/brockmann-medium-webfont.woff2 +0 -0
- /package/{src/assets → assets}/fonts/brockmann-mediumitalic-webfont.woff2 +0 -0
- /package/{src/assets → assets}/fonts/brockmann-regular-webfont.woff2 +0 -0
- /package/{src/assets → assets}/fonts/brockmann-regularitalic-webfont.woff2 +0 -0
- /package/{src/assets → assets}/fonts/brockmann-semibold-webfont.woff2 +0 -0
- /package/{src/assets → assets}/fonts/brockmann-semibolditalic-webfont.woff2 +0 -0
- /package/{src/styles → styles}/ionic.css +0 -0
- /package/{src/components/shared → styles}/mobile-common.css +0 -0
- /package/{src/components/shared → styles}/mobile-page-base.css +0 -0
|
@@ -1,340 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Component,
|
|
3
|
-
input,
|
|
4
|
-
output,
|
|
5
|
-
signal,
|
|
6
|
-
computed,
|
|
7
|
-
ContentChild,
|
|
8
|
-
TemplateRef,
|
|
9
|
-
ElementRef,
|
|
10
|
-
inject,
|
|
11
|
-
CUSTOM_ELEMENTS_SCHEMA,
|
|
12
|
-
effect
|
|
13
|
-
} from '@angular/core';
|
|
14
|
-
import { CommonModule } from '@angular/common';
|
|
15
|
-
import { DsIconComponent } from '@propbinder/design-system';
|
|
16
|
-
import { IonPopover } from '@ionic/angular/standalone';
|
|
17
|
-
|
|
18
|
-
export interface DsMobileDropdownItem {
|
|
19
|
-
id: string;
|
|
20
|
-
/** Optional leading icon */
|
|
21
|
-
leadingIcon?: string;
|
|
22
|
-
/** Optional trailing icon */
|
|
23
|
-
trailingIcon?: string;
|
|
24
|
-
/** Main label text */
|
|
25
|
-
label?: string;
|
|
26
|
-
/** Whether the item is disabled */
|
|
27
|
-
disabled?: boolean;
|
|
28
|
-
/** Optional action callback */
|
|
29
|
-
action?: () => void;
|
|
30
|
-
/** Custom data for template rendering */
|
|
31
|
-
data?: any;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export type DropdownPosition = 'above' | 'below';
|
|
35
|
-
export type DropdownAlign = 'start' | 'end';
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* DsMobileDropdownComponent
|
|
39
|
-
*
|
|
40
|
-
* A mobile-optimized dropdown component for action menus, mention lists, and selection lists.
|
|
41
|
-
* Uses Ionic Popover for robust mobile positioning and backdrop management.
|
|
42
|
-
*
|
|
43
|
-
* Features:
|
|
44
|
-
* - Vertical list layout with leading/main/trailing slots
|
|
45
|
-
* - Custom template support via content projection
|
|
46
|
-
* - Mobile-friendly touch interactions (mousedown events)
|
|
47
|
-
* - Ionic-powered backdrop overlay for dismissal
|
|
48
|
-
* - Configurable positioning (above/below) and alignment (start/end)
|
|
49
|
-
* - Max height with scroll support
|
|
50
|
-
* - Smooth enter/exit animations
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* Basic dropdown with default items:
|
|
54
|
-
* ```html
|
|
55
|
-
* <button (click)="toggleMenu()">Open Menu</button>
|
|
56
|
-
* <ds-mobile-dropdown
|
|
57
|
-
* [items]="menuItems"
|
|
58
|
-
* [isOpen]="isMenuOpen()"
|
|
59
|
-
* position="below"
|
|
60
|
-
* align="start"
|
|
61
|
-
* (itemSelected)="handleSelection($event)"
|
|
62
|
-
* (closed)="closeMenu()">
|
|
63
|
-
* </ds-mobile-dropdown>
|
|
64
|
-
* ```
|
|
65
|
-
*
|
|
66
|
-
* @example
|
|
67
|
-
* Custom template for mention menu with avatars:
|
|
68
|
-
* ```html
|
|
69
|
-
* <textarea (input)="handleInput($event)"></textarea>
|
|
70
|
-
* <ds-mobile-dropdown
|
|
71
|
-
* [items]="users"
|
|
72
|
-
* [isOpen]="showMentions()"
|
|
73
|
-
* position="above"
|
|
74
|
-
* [maxHeight]="200"
|
|
75
|
-
* (itemSelected)="selectUser($event)"
|
|
76
|
-
* (closed)="closeMentions()">
|
|
77
|
-
* <ng-template #itemTemplate let-item>
|
|
78
|
-
* <ds-avatar
|
|
79
|
-
* [initials]="item.data.initials"
|
|
80
|
-
* size="sm" />
|
|
81
|
-
* <div class="user-info">
|
|
82
|
-
* <span>{{ item.data.name }}</span>
|
|
83
|
-
* <span>{{ item.data.role }}</span>
|
|
84
|
-
* </div>
|
|
85
|
-
* </ng-template>
|
|
86
|
-
* </ds-mobile-dropdown>
|
|
87
|
-
* ```
|
|
88
|
-
*/
|
|
89
|
-
@Component({
|
|
90
|
-
selector: 'ds-mobile-dropdown',
|
|
91
|
-
standalone: true,
|
|
92
|
-
imports: [CommonModule, DsIconComponent, IonPopover],
|
|
93
|
-
styleUrls: ['./ds-mobile-dropdown.css'],
|
|
94
|
-
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
95
|
-
template: `
|
|
96
|
-
<ion-popover
|
|
97
|
-
[isOpen]="isOpen()"
|
|
98
|
-
[trigger]="trigger()"
|
|
99
|
-
[side]="position() === 'above' ? 'top' : 'bottom'"
|
|
100
|
-
[alignment]="'start'"
|
|
101
|
-
[showBackdrop]="true"
|
|
102
|
-
[dismissOnSelect]="false"
|
|
103
|
-
[backdropDismiss]="true"
|
|
104
|
-
[keepContentsMounted]="false"
|
|
105
|
-
[keyboardClose]="false"
|
|
106
|
-
(didDismiss)="closed.emit()"
|
|
107
|
-
[style.--offset-y]="offsetY()"
|
|
108
|
-
[style.--offset-x]="offsetX()"
|
|
109
|
-
[style.--max-width]="maxWidth()"
|
|
110
|
-
[style.--background]="'transparent'"
|
|
111
|
-
[style.--box-shadow]="'none'"
|
|
112
|
-
[style.--backdrop-opacity]="'0'">
|
|
113
|
-
|
|
114
|
-
<ng-template>
|
|
115
|
-
@if (customContent) {
|
|
116
|
-
<!-- Fully custom popover content (e.g. picker, form) -->
|
|
117
|
-
<ng-container *ngTemplateOutlet="customContent" />
|
|
118
|
-
} @else {
|
|
119
|
-
<!-- Standard item list -->
|
|
120
|
-
<div
|
|
121
|
-
[class]="dropdownClasses()"
|
|
122
|
-
[style.max-height.px]="maxHeight()"
|
|
123
|
-
(mousedown)="$event.stopPropagation()"
|
|
124
|
-
(click)="$event.stopPropagation()"
|
|
125
|
-
role="menu"
|
|
126
|
-
[attr.aria-label]="ariaLabel()">
|
|
127
|
-
|
|
128
|
-
@if (customItemTemplate) {
|
|
129
|
-
<!-- Custom template for each item -->
|
|
130
|
-
@for (item of items(); track item.id) {
|
|
131
|
-
<div
|
|
132
|
-
[class]="getItemClass(item)"
|
|
133
|
-
[attr.data-disabled]="item.disabled ? '' : null"
|
|
134
|
-
[attr.aria-disabled]="item.disabled"
|
|
135
|
-
(mousedown)="handleItemClick(item, $event)"
|
|
136
|
-
role="menuitem">
|
|
137
|
-
<ng-container
|
|
138
|
-
*ngTemplateOutlet="customItemTemplate; context: { $implicit: item }" />
|
|
139
|
-
</div>
|
|
140
|
-
}
|
|
141
|
-
} @else {
|
|
142
|
-
<!-- Default three-slot template: leading - main - trailing -->
|
|
143
|
-
@for (item of items(); track item.id) {
|
|
144
|
-
<div
|
|
145
|
-
[class]="getItemClass(item)"
|
|
146
|
-
[attr.data-disabled]="item.disabled ? '' : null"
|
|
147
|
-
[attr.aria-disabled]="item.disabled"
|
|
148
|
-
(mousedown)="handleItemClick(item, $event)"
|
|
149
|
-
role="menuitem">
|
|
150
|
-
|
|
151
|
-
<!-- Leading slot -->
|
|
152
|
-
@if (item.leadingIcon) {
|
|
153
|
-
<div class="ds-mobile-dropdown__slot ds-mobile-dropdown__slot--leading">
|
|
154
|
-
<ds-icon [name]="item.leadingIcon" size="16px" />
|
|
155
|
-
</div>
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
<!-- Main slot -->
|
|
159
|
-
@if (item.label) {
|
|
160
|
-
<div class="ds-mobile-dropdown__slot ds-mobile-dropdown__slot--main">
|
|
161
|
-
<span class="ds-mobile-dropdown__label">{{ item.label }}</span>
|
|
162
|
-
</div>
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
<!-- Trailing slot -->
|
|
166
|
-
@if (item.trailingIcon) {
|
|
167
|
-
<div class="ds-mobile-dropdown__slot ds-mobile-dropdown__slot--trailing">
|
|
168
|
-
<ds-icon [name]="item.trailingIcon" size="20px" />
|
|
169
|
-
</div>
|
|
170
|
-
}
|
|
171
|
-
</div>
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
@if (items().length === 0 && emptyMessage()) {
|
|
176
|
-
<div class="ds-mobile-dropdown__empty">{{ emptyMessage() }}</div>
|
|
177
|
-
}
|
|
178
|
-
</div>
|
|
179
|
-
}
|
|
180
|
-
</ng-template>
|
|
181
|
-
</ion-popover>
|
|
182
|
-
`
|
|
183
|
-
})
|
|
184
|
-
export class DsMobileDropdownComponent {
|
|
185
|
-
private elementRef = inject(ElementRef);
|
|
186
|
-
|
|
187
|
-
constructor() {
|
|
188
|
-
// Effect to refocus the keepFocusOn element when popover opens
|
|
189
|
-
effect(() => {
|
|
190
|
-
const isOpen = this.isOpen();
|
|
191
|
-
const focusElement = this.keepFocusOn();
|
|
192
|
-
|
|
193
|
-
if (isOpen && focusElement?.nativeElement) {
|
|
194
|
-
// Wait for popover to mount, then refocus
|
|
195
|
-
setTimeout(() => {
|
|
196
|
-
focusElement.nativeElement.focus();
|
|
197
|
-
}, 100);
|
|
198
|
-
}
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Content projection for custom item template (per-item renderer)
|
|
204
|
-
*/
|
|
205
|
-
@ContentChild('itemTemplate') customItemTemplate?: TemplateRef<any>;
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Content projection for fully custom popover content.
|
|
209
|
-
* When provided, the item list is bypassed entirely and this template
|
|
210
|
-
* is rendered directly inside the popover — use for pickers, forms, etc.
|
|
211
|
-
*/
|
|
212
|
-
@ContentChild('customContent') customContent?: TemplateRef<any>;
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Optional trigger element ID for Ionic Popover positioning
|
|
216
|
-
*/
|
|
217
|
-
trigger = input<string>();
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Optional element to keep focused (prevent keyboard from dismissing)
|
|
221
|
-
* Pass ElementRef to maintain focus when popover opens
|
|
222
|
-
*/
|
|
223
|
-
keepFocusOn = input<ElementRef<any>>();
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Array of dropdown items to display.
|
|
227
|
-
* Not required when using the #customContent slot.
|
|
228
|
-
*/
|
|
229
|
-
items = input<DsMobileDropdownItem[]>([]);
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Whether the dropdown is open
|
|
233
|
-
*/
|
|
234
|
-
isOpen = input<boolean>(false);
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Position relative to parent container
|
|
238
|
-
* - 'above': Appears above the anchor
|
|
239
|
-
* - 'below': Appears below the anchor
|
|
240
|
-
*/
|
|
241
|
-
position = input<DropdownPosition>('above');
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* Horizontal alignment
|
|
245
|
-
* - 'start': Left-aligned (default)
|
|
246
|
-
* - 'end': Right-aligned
|
|
247
|
-
*/
|
|
248
|
-
align = input<DropdownAlign>('start');
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* Maximum height in pixels before scrolling
|
|
252
|
-
*/
|
|
253
|
-
maxHeight = input<number>(200);
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* Message to show when items array is empty
|
|
257
|
-
*/
|
|
258
|
-
emptyMessage = input<string>('No items available');
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* ARIA label for the dropdown menu
|
|
262
|
-
*/
|
|
263
|
-
ariaLabel = input<string>('Dropdown menu');
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* Maximum width of the popover.
|
|
267
|
-
* Defaults to '192px' (standard dropdown width).
|
|
268
|
-
* Override when using #customContent that requires more space (e.g. '280px' for a picker).
|
|
269
|
-
*/
|
|
270
|
-
maxWidth = input<string>('192px');
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* Emits when an item is selected
|
|
274
|
-
*/
|
|
275
|
-
itemSelected = output<DsMobileDropdownItem>();
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* Emits when the dropdown should be closed (backdrop click)
|
|
279
|
-
*/
|
|
280
|
-
closed = output<void>();
|
|
281
|
-
|
|
282
|
-
/**
|
|
283
|
-
* Computed dropdown CSS classes
|
|
284
|
-
*/
|
|
285
|
-
dropdownClasses = computed(() => {
|
|
286
|
-
const classes = [
|
|
287
|
-
'ds-mobile-dropdown',
|
|
288
|
-
`ds-mobile-dropdown--${this.position()}`,
|
|
289
|
-
`ds-mobile-dropdown--align-${this.align()}`
|
|
290
|
-
];
|
|
291
|
-
|
|
292
|
-
return classes.join(' ');
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* Computed offset Y for Ionic Popover
|
|
297
|
-
* Uses CSS variable for precise control
|
|
298
|
-
*/
|
|
299
|
-
offsetY = computed(() => {
|
|
300
|
-
// 4px offset - works well on both web and iOS
|
|
301
|
-
return this.position() === 'above' ? '-4px' : '4px';
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
/**
|
|
305
|
-
* Computed offset X for Ionic Popover
|
|
306
|
-
* Negative value to shift left by trigger position + add 20px left margin
|
|
307
|
-
*/
|
|
308
|
-
offsetX = computed(() => {
|
|
309
|
-
// This will be calculated to position it 20px from the left edge
|
|
310
|
-
// The exact value depends on where the trigger is positioned
|
|
311
|
-
return '0px'; // Ionic will handle this based on alignment="start"
|
|
312
|
-
});
|
|
313
|
-
|
|
314
|
-
/**
|
|
315
|
-
* Get CSS classes for a dropdown item
|
|
316
|
-
*/
|
|
317
|
-
getItemClass(item: DsMobileDropdownItem): string {
|
|
318
|
-
const classes = ['ds-mobile-dropdown__item'];
|
|
319
|
-
if (item.disabled) classes.push('ds-mobile-dropdown__item--disabled');
|
|
320
|
-
return classes.join(' ');
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* Handle item click with mousedown to prevent keyboard loss
|
|
325
|
-
*/
|
|
326
|
-
handleItemClick(item: DsMobileDropdownItem, event: MouseEvent): void {
|
|
327
|
-
if (item.disabled) return;
|
|
328
|
-
|
|
329
|
-
event.preventDefault();
|
|
330
|
-
event.stopPropagation();
|
|
331
|
-
|
|
332
|
-
// Execute item action if provided
|
|
333
|
-
if (item.action) {
|
|
334
|
-
item.action();
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
// Emit selection event
|
|
338
|
-
this.itemSelected.emit(item);
|
|
339
|
-
}
|
|
340
|
-
}
|