@propbinder/mobile-design 0.0.1
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/README.md +63 -0
- package/fesm2022/propbinder-mobile-design.mjs +8294 -0
- package/fesm2022/propbinder-mobile-design.mjs.map +1 -0
- package/index.d.ts +2860 -0
- package/package.json +39 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"propbinder-mobile-design.mjs","sources":["../../../projects/mobile-design-lib/src/ui/shared/mobile-page-base.ts","../../../projects/mobile-design-lib/src/ui/shared/directives/long-press.directive.ts","../../../projects/mobile-design-lib/src/ui/list-item/ds-mobile-list-item.ts","../../../projects/mobile-design-lib/src/ui/action-list-item/ds-mobile-action-list-item.ts","../../../projects/mobile-design-lib/src/ui/bottom-sheet/ds-mobile-actions-bottom-sheet.ts","../../../projects/mobile-design-lib/src/ui/bottom-sheet/ds-mobile-bottom-sheet.service.ts","../../../projects/mobile-design-lib/src/ui/bottom-sheet/ds-mobile-post-create-bottom-sheet.ts","../../../projects/mobile-design-lib/src/ui/page-main/ds-mobile-page-main.ts","../../../projects/mobile-design-lib/src/ui/page-details/ds-mobile-page-details.ts","../../../projects/mobile-design-lib/src/ui/content/ds-mobile-content.ts","../../../projects/mobile-design-lib/src/ui/header-content/ds-mobile-header-content.ts","../../../projects/mobile-design-lib/src/ui/post-card/ds-mobile-post-card.ts","../../../projects/mobile-design-lib/src/ui/comment/ds-mobile-comment.ts","../../../projects/mobile-design-lib/src/ui/post-composer/ds-mobile-post-composer.ts","../../../projects/mobile-design-lib/src/ui/interactive-list-item-post/ds-mobile-interactive-list-item-post.ts","../../../projects/mobile-design-lib/src/ui/interactive-list-item-post/ds-mobile-post-pdf-attachment.ts","../../../projects/mobile-design-lib/src/ui/interactive-list-item-post/index.ts","../../../projects/mobile-design-lib/src/ui/interactive-list-item-inquiry/ds-mobile-interactive-list-item-inquiry.ts","../../../projects/mobile-design-lib/src/ui/interactive-list-item-message/ds-mobile-interactive-list-item-message.ts","../../../projects/mobile-design-lib/src/ui/contact-list-item/ds-mobile-contact-list-item.ts","../../../projects/mobile-design-lib/src/ui/app-layout/ds-mobile-app-layout.ts","../../../projects/mobile-design-lib/src/ui/tabs/ds-mobile-tabs.ts","../../../projects/mobile-design-lib/src/ui/lightbox/ds-mobile-lightbox-header.ts","../../../projects/mobile-design-lib/src/ui/lightbox/ds-mobile-lightbox-footer.ts","../../../projects/mobile-design-lib/src/ui/lightbox/ds-mobile-lightbox-image.ts","../../../projects/mobile-design-lib/src/ui/lightbox/ds-mobile-lightbox-pdf.ts","../../../projects/mobile-design-lib/src/ui/lightbox/ds-mobile-lightbox.service.ts","../../../projects/mobile-design-lib/src/ui/lightbox/index.ts","../../../projects/mobile-design-lib/src/ui/inline-photo/ds-mobile-inline-photo.ts","../../../projects/mobile-design-lib/src/ui/modal/ds-mobile-modal.service.ts","../../../projects/mobile-design-lib/src/ui/modal/index.ts","../../../projects/mobile-design-lib/src/ui/post-detail-modal/ds-mobile-post-detail-modal.ts","../../../projects/mobile-design-lib/src/ui/post-detail-modal/ds-mobile-post-detail-modal.service.ts","../../../projects/mobile-design-lib/src/ui/post-detail-modal/index.ts","../../../projects/mobile-design-lib/src/ui/handbook-folder/ds-mobile-handbook-folder-mini.ts","../../../projects/mobile-design-lib/src/ui/file-attachment/ds-mobile-file-attachment.ts","../../../projects/mobile-design-lib/src/ui/swiper/ds-mobile-swiper.ts","../../../projects/mobile-design-lib/src/ui/handbook-detail-modal/ds-mobile-handbook-detail-modal.ts","../../../projects/mobile-design-lib/src/ui/handbook-detail-modal/ds-mobile-handbook-detail-modal.service.ts","../../../projects/mobile-design-lib/src/ui/handbook-folder/ds-mobile-handbook-folder.ts","../../../projects/mobile-design-lib/src/ui/index.ts","../../../projects/mobile-design-lib/src/public-api.ts","../../../projects/mobile-design-lib/src/propbinder-mobile-design.ts"],"sourcesContent":["import { input, computed, Directive } from '@angular/core';\r\n\r\n/**\r\n * Content width preset values\r\n * - 'narrow' - 640px max width (reading content)\r\n * - 'standard' - 1024px max width (default)\r\n * - 'wide' - 1440px max width (dashboards)\r\n * - 'full' - 100% width (no max)\r\n */\r\nexport type ContentWidth = 'narrow' | 'standard' | 'wide' | 'full';\r\n\r\n/**\r\n * MobilePageBase\r\n * \r\n * Shared base class for mobile page components (ds-mobile-page-main, ds-mobile-page-details).\r\n * Provides consistent content width control across all page types.\r\n * \r\n * **Padding Strategy:**\r\n * - All pages use 20px horizontal padding globally\r\n * - For tappable lists, use negative margins (e.g., margin: 0 -8px) to create full-width sections\r\n * - This approach simplifies padding management and provides consistency\r\n * \r\n * @internal This is a base class and should not be used directly.\r\n */\r\n@Directive()\r\nexport abstract class MobilePageBase {\r\n /**\r\n * Maximum content width (desktop only)\r\n * \r\n * **Options:**\r\n * - `'narrow'` (640px) - For reading content, forms\r\n * - `'standard'` (1024px) - Default for most pages\r\n * - `'wide'` (1440px) - For dashboards, tables\r\n * - `'full'` - No max-width constraint\r\n * \r\n * **Note:** Only applies on desktop (>= 768px). Mobile is always full width.\r\n * \r\n * @default 'standard'\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Narrow reading layout -->\r\n * <ds-mobile-page-main title=\"Article\" contentWidth=\"narrow\">\r\n * \r\n * <!-- Wide dashboard -->\r\n * <ds-mobile-page-main title=\"Dashboard\" contentWidth=\"wide\">\r\n * ```\r\n */\r\n contentWidth = input<ContentWidth>('standard');\r\n\r\n /**\r\n * Resolved max-width value (computed)\r\n * Maps preset values to pixel values\r\n * \r\n * @internal\r\n */\r\n protected maxWidthValue = computed(() => {\r\n const w = this.contentWidth();\r\n \r\n const widthMap: Record<ContentWidth, string> = {\r\n 'narrow': '640px',\r\n 'standard': '1024px',\r\n 'wide': '1440px',\r\n 'full': '100%'\r\n };\r\n \r\n return widthMap[w];\r\n });\r\n}\r\n\r\n","import { \r\n Directive, \r\n Output, \r\n EventEmitter, \r\n HostListener, \r\n Input,\r\n OnDestroy \r\n} from '@angular/core';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\n\r\n/**\r\n * DsMobileLongPressDirective\r\n * \r\n * A reusable directive for handling long press interactions on mobile devices.\r\n * Provides haptic feedback and prevents long press when touching interactive elements.\r\n * \r\n * Features:\r\n * - Configurable duration and movement threshold\r\n * - Automatic haptic feedback (with fallback to navigator.vibrate)\r\n * - Excludes interactive elements (buttons, links, inputs)\r\n * - Handles touchmove cancellation\r\n * - Context menu support (right-click on desktop)\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Basic usage -->\r\n * <div dsMobileLongPress (longPress)=\"handleLongPress()\">\r\n * Long press me\r\n * </div>\r\n * \r\n * <!-- Custom duration and threshold -->\r\n * <div \r\n * dsMobileLongPress \r\n * [longPressDuration]=\"800\"\r\n * [moveThreshold]=\"15\"\r\n * [excludeSelectors]=\"'button, a, .no-longpress'\"\r\n * (longPress)=\"showContextMenu()\">\r\n * Custom long press\r\n * </div>\r\n * ```\r\n */\r\n@Directive({\r\n selector: '[dsMobileLongPress]',\r\n standalone: true\r\n})\r\nexport class DsMobileLongPressDirective implements OnDestroy {\r\n /**\r\n * Duration in milliseconds to trigger long press\r\n * @default 500\r\n */\r\n @Input() longPressDuration = 500;\r\n\r\n /**\r\n * Maximum movement in pixels before canceling long press\r\n * @default 10\r\n */\r\n @Input() moveThreshold = 10;\r\n\r\n /**\r\n * CSS selectors to exclude from long press detection\r\n * @default 'button, a, input, select, textarea, [role=\"button\"]'\r\n */\r\n @Input() excludeSelectors = 'button, a, input, select, textarea, [role=\"button\"]';\r\n\r\n /**\r\n * Haptic feedback style (Light, Medium, Heavy)\r\n * @default ImpactStyle.Medium\r\n */\r\n @Input() hapticStyle: ImpactStyle = ImpactStyle.Medium;\r\n\r\n /**\r\n * Enable/disable haptic feedback\r\n * @default true\r\n */\r\n @Input() enableHaptics = true;\r\n\r\n /**\r\n * Emits when long press is triggered\r\n */\r\n @Output() longPress = new EventEmitter<void>();\r\n\r\n /**\r\n * Emits when long press starts (timer begins)\r\n */\r\n @Output() longPressStart = new EventEmitter<void>();\r\n\r\n /**\r\n * Emits when long press is cancelled\r\n */\r\n @Output() longPressCancel = new EventEmitter<void>();\r\n\r\n private longPressTimer: any = null;\r\n private longPressTriggered = false;\r\n private touchStartX = 0;\r\n private touchStartY = 0;\r\n\r\n /**\r\n * Handle touch start for long press detection\r\n */\r\n @HostListener('touchstart', ['$event'])\r\n handleTouchStart(event: TouchEvent): void {\r\n // Don't start long press if touching interactive elements\r\n const target = event.target as HTMLElement;\r\n if (target.closest(this.excludeSelectors)) {\r\n return;\r\n }\r\n\r\n this.longPressTriggered = false;\r\n this.touchStartX = event.touches[0].clientX;\r\n this.touchStartY = event.touches[0].clientY;\r\n\r\n // Emit start event\r\n this.longPressStart.emit();\r\n\r\n // Start long press timer\r\n this.longPressTimer = setTimeout(async () => {\r\n this.longPressTriggered = true;\r\n this.longPress.emit();\r\n\r\n // Haptic feedback for long press\r\n if (this.enableHaptics) {\r\n await this.triggerHaptics();\r\n }\r\n }, this.longPressDuration);\r\n }\r\n\r\n /**\r\n * Handle touch end to clear long press timer\r\n */\r\n @HostListener('touchend', ['$event'])\r\n handleTouchEnd(event: TouchEvent): void {\r\n if (this.longPressTimer) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n \r\n if (!this.longPressTriggered) {\r\n this.longPressCancel.emit();\r\n }\r\n }\r\n\r\n // Prevent normal click if long press was triggered\r\n if (this.longPressTriggered) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.longPressTriggered = false;\r\n }\r\n }\r\n\r\n /**\r\n * Handle touch move to cancel long press if moved too much\r\n */\r\n @HostListener('touchmove', ['$event'])\r\n handleTouchMove(event: TouchEvent): void {\r\n if (!this.longPressTimer) return;\r\n\r\n const touch = event.touches[0];\r\n const deltaX = Math.abs(touch.clientX - this.touchStartX);\r\n const deltaY = Math.abs(touch.clientY - this.touchStartY);\r\n\r\n // Cancel long press if moved too far\r\n if (deltaX > this.moveThreshold || deltaY > this.moveThreshold) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n this.longPressTriggered = false;\r\n this.longPressCancel.emit();\r\n }\r\n }\r\n\r\n /**\r\n * Handle context menu (right-click on desktop) to trigger long press action\r\n */\r\n @HostListener('contextmenu', ['$event'])\r\n handleContextMenu(event: Event): void {\r\n event.preventDefault();\r\n this.longPress.emit();\r\n }\r\n\r\n /**\r\n * Trigger haptic feedback\r\n */\r\n private async triggerHaptics(): Promise<void> {\r\n try {\r\n await Haptics.impact({ style: this.hapticStyle });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n // Map haptic styles to vibration durations\r\n const vibrationMap = {\r\n [ImpactStyle.Light]: 30,\r\n [ImpactStyle.Medium]: 50,\r\n [ImpactStyle.Heavy]: 80\r\n };\r\n navigator.vibrate(vibrationMap[this.hapticStyle] || 50);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Cleanup on destroy\r\n */\r\n ngOnDestroy(): void {\r\n if (this.longPressTimer) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n }\r\n }\r\n}\r\n\r\n","import { Component, input, output, computed, signal, PLATFORM_ID, inject } from '@angular/core';\r\nimport { CommonModule, isPlatformBrowser } from '@angular/common';\r\nimport { DsMobileLongPressDirective } from '../shared/directives/long-press.directive';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobileListItemComponent\r\n * \r\n * A versatile, reusable list item component for mobile applications.\r\n * Supports both interactive and non-interactive modes with flexible content projection.\r\n * \r\n * Features:\r\n * - Interactive mode with click and long-press support\r\n * - Pseudo-element background extends 8px beyond bounds (no negative margins needed)\r\n * - Flexible content slots (leading, main, trailing)\r\n * - Optional structured inputs for common use cases (title, subtitle)\r\n * - Accessibility features (focus states, ARIA attributes)\r\n * - Disabled and loading states\r\n * \r\n * This component serves as the foundation for specialized list item types like posts,\r\n * notifications, messages, contacts, and other list content.\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Simple structured usage -->\r\n * <ds-mobile-list-item\r\n * title=\"Document Title\"\r\n * subtitle=\"Supporting text\"\r\n * [interactive]=\"true\"\r\n * (itemClick)=\"handleClick()\">\r\n * \r\n * <ds-icon content-leading name=\"document\" />\r\n * </ds-mobile-list-item>\r\n * \r\n * <!-- Flexible custom usage -->\r\n * <ds-mobile-list-item\r\n * [interactive]=\"true\"\r\n * (itemClick)=\"handleClick()\"\r\n * (longPress)=\"showContextMenu()\">\r\n * \r\n * <div content-leading>\r\n * <ds-avatar initials=\"JD\" />\r\n * </div>\r\n * \r\n * <div content-main>\r\n * <h3>Custom Content</h3>\r\n * <p>Full control over layout and styling</p>\r\n * </div>\r\n * \r\n * <button content-trailing (click)=\"handleAction($event)\">\r\n * Action\r\n * </button>\r\n * </ds-mobile-list-item>\r\n * \r\n * <!-- Non-interactive read-only -->\r\n * <ds-mobile-list-item\r\n * title=\"Read-only Item\"\r\n * subtitle=\"No interaction\">\r\n * <ds-icon content-leading name=\"info\" />\r\n * </ds-mobile-list-item>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-list-item',\r\n standalone: true,\r\n imports: [CommonModule, DsIconButtonComponent],\r\n hostDirectives: [\r\n {\r\n directive: DsMobileLongPressDirective,\r\n outputs: ['longPress']\r\n }\r\n ],\r\n host: {\r\n '[class.interactive]': 'interactive() && !disabled()',\r\n '[class.disabled]': 'disabled()',\r\n '[class.loading]': 'loading()',\r\n '[class.no-divider]': '!showDivider()',\r\n '[class.variant-feed]': 'variant() === \"feed\"',\r\n '[class.variant-detail]': 'variant() === \"detail\"',\r\n '[class.variant-compact]': 'variant() === \"compact\"',\r\n '[attr.role]': 'interactive() ? \"button\" : null',\r\n '[attr.tabindex]': 'interactive() && !disabled() ? \"0\" : null',\r\n '[attr.aria-disabled]': 'disabled() ? \"true\" : null',\r\n '[style.--leading-size]': 'leadingSize()',\r\n '[style.--interactive-offset]': 'interactiveOffset()',\r\n '[style.--divider-spacing]': 'dividerSpacing()',\r\n '(click)': 'handleClick($event)',\r\n '(keydown.enter)': 'handleKeyDown($event)',\r\n '(keydown.space)': 'handleKeyDown($event)',\r\n '(longPress)': 'handleLongPress()'\r\n },\r\n styles: [`\r\n :host {\r\n display: block;\r\n position: relative;\r\n padding: var(--item-padding-top, 12px) 0 var(--item-padding-bottom, 12px) 0;\r\n box-sizing: border-box;\r\n /* CSS variables defined at host level for use by children and pseudo-elements */\r\n --leading-size: 32px;\r\n --content-gap: 12px;\r\n --interactive-offset: 8px;\r\n }\r\n \r\n /* Divider line on host */\r\n :host::after {\r\n content: '';\r\n position: absolute;\r\n bottom: 0;\r\n left: calc(var(--leading-size) + var(--content-gap));\r\n right: 0;\r\n height: 1px;\r\n background: var(--border-color-default, #e5e5e5);\r\n z-index: 1;\r\n display: var(--divider-display, block);\r\n }\r\n \r\n .list-item-inner {\r\n display: flex;\r\n flex-direction: row;\r\n align-items: flex-start;\r\n gap: var(--content-gap);\r\n position: relative;\r\n }\r\n \r\n /* Pseudo-element for interactive background */\r\n :host(.interactive) .list-item-inner::before {\r\n content: '';\r\n position: absolute;\r\n top: calc(-1 * var(--interactive-offset));\r\n left: calc(-1 * var(--interactive-offset));\r\n right: calc(-1 * var(--interactive-offset));\r\n bottom: calc(-1 * var(--interactive-offset));\r\n background: var(--color-background-primary, #ffffff);\r\n border-radius: 16px;\r\n z-index: -1;\r\n pointer-events: none;\r\n }\r\n \r\n /* Interactive states */\r\n :host(.interactive) {\r\n cursor: pointer;\r\n }\r\n \r\n /* Hover state (desktop only) */\r\n @media (hover: hover) and (pointer: fine) {\r\n :host(.interactive):hover .list-item-inner::before {\r\n background: var(--color-background-neutral-primary-hover, #f5f5f5);\r\n }\r\n }\r\n \r\n /* Active state */\r\n :host(.interactive):active .list-item-inner::before {\r\n background: var(--color-background-neutral-primary-hover, #f5f5f5);\r\n }\r\n \r\n /* Focus visible for keyboard navigation */\r\n :host(.interactive):focus-visible {\r\n outline: none;\r\n }\r\n \r\n :host(.interactive):focus-visible .list-item-inner::before {\r\n outline: 2px solid var(--color-brand-primary, #5d5fef);\r\n outline-offset: 2px;\r\n }\r\n \r\n /* Disabled state */\r\n :host(.disabled) {\r\n opacity: 0.5;\r\n pointer-events: none;\r\n }\r\n \r\n /* Loading state */\r\n :host(.loading) {\r\n pointer-events: none;\r\n }\r\n \r\n /* Variants */\r\n :host(.variant-detail) .list-item-inner {\r\n padding: 0;\r\n }\r\n \r\n :host(.variant-compact) .list-item-inner {\r\n gap: 8px;\r\n }\r\n \r\n /* Content slots */\r\n .content-leading {\r\n flex-shrink: 0;\r\n width: var(--leading-size);\r\n height: var(--leading-size);\r\n display: flex;\r\n align-items: flex-start;\r\n justify-content: center;\r\n position: relative;\r\n z-index: 1;\r\n }\r\n \r\n .content-main {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n position: relative;\r\n z-index: 1;\r\n }\r\n \r\n .content-trailing {\r\n flex-shrink: 0;\r\n display: flex;\r\n align-items: flex-start;\r\n position: relative;\r\n z-index: 1;\r\n }\r\n \r\n /* Structured content styles */\r\n .structured-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm, 14px);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-primary, #202227);\r\n margin: 0;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n .structured-subtitle {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm, 14px);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n margin: 0;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n /* Desktop more actions button - using ds-icon-button */\r\n .desktop-more-button::ng-deep button {\r\n border-radius: 50% !important;\r\n }\r\n `],\r\n template: `\r\n <div class=\"list-item-inner\">\r\n <div class=\"content-leading\">\r\n <ng-content select=\"[content-leading]\" />\r\n </div>\r\n \r\n <div class=\"content-main\">\r\n @if (title()) {\r\n <h3 class=\"structured-title\">{{ title() }}</h3>\r\n }\r\n @if (subtitle()) {\r\n <p class=\"structured-subtitle\">{{ subtitle() }}</p>\r\n }\r\n \r\n <ng-content select=\"[content-main]\" />\r\n <ng-content />\r\n </div>\r\n \r\n <div class=\"content-trailing\">\r\n @if (interactive() && enableLongPress() && showDesktopMoreButton() && isDesktop()) {\r\n <ds-icon-button\r\n class=\"desktop-more-button\"\r\n icon=\"remixMoreFill\"\r\n variant=\"secondary\"\r\n size=\"sm\"\r\n (clicked)=\"handleMoreButtonClick($event)\"\r\n aria-label=\"More options\">\r\n </ds-icon-button>\r\n }\r\n <ng-content select=\"[content-trailing]\" />\r\n </div>\r\n </div>\r\n `\r\n})\r\nexport class DsMobileListItemComponent {\r\n private platformId = inject(PLATFORM_ID);\r\n \r\n /**\r\n * Detect if viewport is desktop size\r\n * Use viewport width for breakpoint detection (show button on tablet and above)\r\n */\r\n isDesktop = signal<boolean>(false);\r\n \r\n constructor() {\r\n if (isPlatformBrowser(this.platformId)) {\r\n // Show button on tablet breakpoint and above (768px+)\r\n const isDesktopViewport = window.innerWidth >= 768;\r\n \r\n console.log('[ListItem] Desktop detection:', {\r\n innerWidth: window.innerWidth,\r\n isDesktopViewport\r\n });\r\n \r\n this.isDesktop.set(isDesktopViewport);\r\n \r\n // Listen for window resize to update detection\r\n window.addEventListener('resize', () => {\r\n const newIsDesktop = window.innerWidth >= 768;\r\n if (newIsDesktop !== this.isDesktop()) {\r\n console.log('[ListItem] Viewport changed, updating desktop detection:', newIsDesktop);\r\n this.isDesktop.set(newIsDesktop);\r\n }\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * CSS size value for the leading content area (e.g., '32px', '40px', '48px')\r\n * Defaults to '32px' for standard list item avatars/icons\r\n */\r\n leadingSize = input<string>('32px');\r\n \r\n /**\r\n * Display variant\r\n * - 'feed' - Standard feed display (default)\r\n * - 'detail' - Full detail view\r\n * - 'compact' - Compact display for nested/related items\r\n */\r\n variant = input<'feed' | 'detail' | 'compact'>('feed');\r\n \r\n /**\r\n * Whether the list item is interactive (clickable and long-pressable)\r\n * When true, adds interactive background, cursor pointer, and touch handlers\r\n */\r\n interactive = input<boolean>(false);\r\n \r\n /**\r\n * Whether the list item is disabled\r\n * Disables all interactions and reduces opacity\r\n */\r\n disabled = input<boolean>(false);\r\n \r\n /**\r\n * Whether the list item is in a loading state\r\n * Disables interactions but maintains full opacity\r\n */\r\n loading = input<boolean>(false);\r\n \r\n /**\r\n * Enable long-press interaction when interactive is true\r\n * Set to false to disable long-press but keep click\r\n */\r\n enableLongPress = input<boolean>(true);\r\n \r\n /**\r\n * Show \"more actions\" button on desktop for items with long-press enabled\r\n * Only visible on desktop (hover: hover) and when enableLongPress is true\r\n * Clicking this button triggers the same handler as long-press on mobile\r\n * @default true\r\n */\r\n showDesktopMoreButton = input<boolean>(true);\r\n \r\n /**\r\n * Offset distance for the interactive background pseudo-element\r\n * Extends the background beyond the content bounds\r\n * @default '8px'\r\n */\r\n interactiveOffset = input<string>('8px');\r\n \r\n /**\r\n * Optional structured title text\r\n * Provides a simple way to add title without custom markup\r\n */\r\n title = input<string>();\r\n \r\n /**\r\n * Optional structured subtitle text\r\n * Provides a simple way to add subtitle without custom markup\r\n */\r\n subtitle = input<string>();\r\n \r\n /**\r\n * Whether to show the divider line below the list item\r\n * Automatically hidden on last-child and detail variant\r\n * @default true\r\n */\r\n showDivider = input<boolean>(true);\r\n \r\n /**\r\n * Spacing around the divider (top and bottom padding)\r\n * @default '4px'\r\n */\r\n dividerSpacing = input<string>('4px');\r\n \r\n /**\r\n * Emits when the list item is clicked (if interactive and not disabled)\r\n */\r\n itemClick = output<void>();\r\n \r\n /**\r\n * Emits when the desktop more actions button is clicked\r\n * This is separate from longPress to give more control to parent components\r\n * Typically, you can use (longPress) for both mobile and desktop actions\r\n */\r\n moreButtonClick = output<Event>();\r\n \r\n /**\r\n * Track if long press was triggered to prevent click\r\n */\r\n private longPressTriggered = false;\r\n \r\n /**\r\n * Check if leading content slot has content\r\n * Always true to maintain consistent layout\r\n */\r\n hasLeadingContent = computed(() => true);\r\n \r\n /**\r\n * Check if trailing content slot has content\r\n * Always true to maintain consistent layout\r\n */\r\n hasTrailingContent = computed(() => true);\r\n \r\n /**\r\n * Handle click events\r\n */\r\n handleClick(event: Event): void {\r\n console.log('[ListItem] Click event fired', {\r\n interactive: this.interactive(),\r\n disabled: this.disabled(),\r\n loading: this.loading(),\r\n longPressTriggered: this.longPressTriggered,\r\n target: event.target\r\n });\r\n \r\n if (!this.interactive() || this.disabled() || this.loading()) {\r\n console.log('[ListItem] Click ignored - not interactive or disabled/loading');\r\n return;\r\n }\r\n \r\n // Don't emit click if it came from an interactive child element\r\n // (but not the host element itself)\r\n const target = event.target as HTMLElement;\r\n const closestInteractive = target.closest('button, a, input, select, textarea, [role=\"button\"]');\r\n \r\n // Check if the interactive element is a child, not the host itself\r\n if (closestInteractive && closestInteractive !== event.currentTarget) {\r\n console.log('[ListItem] Click ignored - came from interactive child:', closestInteractive);\r\n return;\r\n }\r\n \r\n if (!this.longPressTriggered) {\r\n console.log('[ListItem] Emitting itemClick');\r\n this.itemClick.emit();\r\n } else {\r\n console.log('[ListItem] Click ignored - long press was triggered');\r\n }\r\n \r\n this.longPressTriggered = false;\r\n }\r\n \r\n /**\r\n * Handle keyboard events (Enter/Space)\r\n */\r\n handleKeyDown(event: KeyboardEvent): void {\r\n if (!this.interactive() || this.disabled() || this.loading()) {\r\n return;\r\n }\r\n \r\n event.preventDefault();\r\n this.itemClick.emit();\r\n }\r\n \r\n /**\r\n * Handle long press events from the directive\r\n * Set the flag to prevent the subsequent click event\r\n */\r\n handleLongPress(): void {\r\n this.longPressTriggered = true;\r\n // Reset the flag after a short delay to allow for the next interaction\r\n setTimeout(() => {\r\n this.longPressTriggered = false;\r\n }, 100);\r\n }\r\n \r\n /**\r\n * Handle desktop more button click\r\n * Stops propagation to prevent triggering itemClick\r\n * Emits moreButtonClick for parent components to handle\r\n */\r\n handleMoreButtonClick(event: Event): void {\r\n console.log('[ListItem] Desktop more button clicked');\r\n \r\n // Stop propagation to prevent triggering itemClick\r\n event.stopPropagation();\r\n event.preventDefault();\r\n \r\n // Emit the more button click event\r\n this.moreButtonClick.emit(event);\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { DsMobileListItemComponent } from '../list-item/ds-mobile-list-item';\r\n\r\n/**\r\n * DsMobileActionListItemComponent\r\n * \r\n * Specialized list item for action sheets and menus.\r\n * Wraps ds-mobile-list-item with action-specific styling:\r\n * - Vertically centered content\r\n * - Interactive by default\r\n * - No dividers (controlled per-item)\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-action-list-item\r\n * title=\"Edit\"\r\n * [showDivider]=\"true\"\r\n * (itemClick)=\"handleEdit()\">\r\n * <ds-icon content-leading name=\"remixEditLine\" size=\"20px\" />\r\n * </ds-mobile-action-list-item>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-action-list-item',\r\n standalone: true,\r\n imports: [DsMobileListItemComponent],\r\n template: `\r\n <ds-mobile-list-item\r\n [title]=\"title()\"\r\n [interactive]=\"true\"\r\n [enableLongPress]=\"false\"\r\n [showDivider]=\"showDivider()\"\r\n [disabled]=\"disabled()\"\r\n (itemClick)=\"itemClick.emit()\">\r\n \r\n <div content-leading>\r\n <ng-content select=\"[action-icon]\" />\r\n </div>\r\n </ds-mobile-list-item>\r\n `,\r\n styles: [`\r\n /* Center all content vertically for action items */\r\n :host ::ng-deep ds-mobile-list-item .list-item-inner {\r\n align-items: center;\r\n }\r\n \r\n /* Center icon within leading slot */\r\n :host ::ng-deep ds-mobile-list-item .content-leading {\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n /* Remove gap from content-main for single-line actions */\r\n :host ::ng-deep ds-mobile-list-item .content-main {\r\n gap: 0;\r\n justify-content: center;\r\n }\r\n `]\r\n})\r\nexport class DsMobileActionListItemComponent {\r\n /**\r\n * Action title text\r\n */\r\n title = input.required<string>();\r\n \r\n /**\r\n * Whether to show divider below item\r\n * @default false\r\n */\r\n showDivider = input<boolean>(false);\r\n \r\n /**\r\n * Whether the action is disabled\r\n * @default false\r\n */\r\n disabled = input<boolean>(false);\r\n \r\n /**\r\n * Emits when the action item is clicked\r\n */\r\n itemClick = output<void>();\r\n}\r\n\r\n","import { Component, Input, computed, signal } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsMobileActionListItemComponent } from '../action-list-item/ds-mobile-action-list-item';\r\n\r\nexport interface ActionResult {\r\n action: string;\r\n}\r\n\r\nexport interface ActionItem {\r\n action: string;\r\n title: string;\r\n icon: string;\r\n destructive?: boolean;\r\n}\r\n\r\nexport interface ActionGroup {\r\n actions: ActionItem[];\r\n}\r\n\r\n/**\r\n * DsMobileActionsBottomSheetComponent\r\n * \r\n * Generic bottom sheet for displaying action lists.\r\n * Supports custom action groups or preset content actions (posts/comments).\r\n * Action groups are automatically separated by full-width dividers.\r\n * \r\n * @example Custom actions with auto-height (recommended to avoid cropping)\r\n * ```typescript\r\n * const sheet = await this.modalController.create({\r\n * component: DsMobileActionsBottomSheetComponent,\r\n * componentProps: {\r\n * customActionGroups: [\r\n * {\r\n * actions: [\r\n * { action: 'profile', title: 'Min profil', icon: 'remixUser3Line' },\r\n * { action: 'settings', title: 'Indstillinger', icon: 'remixSettings3Line' }\r\n * ]\r\n * },\r\n * {\r\n * actions: [\r\n * { action: 'logout', title: 'Log ud', icon: 'remixLogoutBoxLine', destructive: true }\r\n * ]\r\n * }\r\n * ]\r\n * },\r\n * breakpoints: [0, 1],\r\n * initialBreakpoint: 1,\r\n * handle: true,\r\n * cssClass: 'auto-height'\r\n * });\r\n * \r\n * const result = await sheet.onWillDismiss();\r\n * if (result.data?.action) {\r\n * // Handle the action\r\n * }\r\n * ```\r\n * \r\n * @example Preset content actions\r\n * ```typescript\r\n * const sheet = await this.modalController.create({\r\n * component: DsMobileActionsBottomSheetComponent,\r\n * componentProps: {\r\n * isOwnContent: false\r\n * },\r\n * breakpoints: [0, 1],\r\n * initialBreakpoint: 1,\r\n * handle: true,\r\n * cssClass: 'auto-height'\r\n * });\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-actions-bottom-sheet',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent, DsMobileActionListItemComponent],\r\n template: `\r\n <div class=\"actions-sheet\">\r\n <!-- Actions List -->\r\n <div class=\"actions-list\">\r\n @for (group of actionGroups(); track $index; let isLast = $last) {\r\n <!-- Action Group -->\r\n <div class=\"action-group\">\r\n @for (actionItem of group.actions; track actionItem.action; let isLastInGroup = $last) {\r\n <ds-mobile-action-list-item\r\n [title]=\"actionItem.title\"\r\n [showDivider]=\"!isLastInGroup\"\r\n [class.destructive]=\"actionItem.destructive\"\r\n (itemClick)=\"selectAction(actionItem.action)\">\r\n <ds-icon \r\n action-icon \r\n [name]=\"actionItem.icon\" \r\n size=\"20px\" \r\n [class.destructive-icon]=\"actionItem.destructive\" />\r\n </ds-mobile-action-list-item>\r\n }\r\n </div>\r\n \r\n <!-- Full-width divider between groups -->\r\n @if (!isLast) {\r\n <div class=\"action-group-divider\"></div>\r\n }\r\n }\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n display: block;\r\n }\r\n \r\n .actions-sheet {\r\n display: flex;\r\n flex-direction: column;\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n padding-bottom: env(safe-area-inset-bottom, 0px);\r\n }\r\n \r\n /* Actions List */\r\n .actions-list {\r\n display: flex;\r\n flex-direction: column;\r\n padding-top: 16px; /* Only top padding for the container */\r\n }\r\n \r\n /* Action Group - padding on groups instead of list */\r\n .action-group {\r\n display: flex;\r\n flex-direction: column;\r\n padding: 0 16px; /* Horizontal padding on each group */\r\n }\r\n \r\n /* Override default background color to transparent so hover state is visible */\r\n /* Need ::ng-deep because ds-mobile-list-item uses :host styles internally */\r\n ::ng-deep ds-mobile-action-list-item ds-mobile-list-item {\r\n --color-background-primary: transparent;\r\n --color-background-neutral-primary-hover: var(--color-background-neutral-secondary, #f5f5f5);\r\n }\r\n \r\n /* Ensure the interactive background is visible */\r\n ::ng-deep ds-mobile-action-list-item ds-mobile-list-item .list-item-inner::before {\r\n z-index: 0 !important;\r\n }\r\n \r\n /* Ensure content is above the background */\r\n ::ng-deep ds-mobile-action-list-item ds-mobile-list-item .content-leading,\r\n ::ng-deep ds-mobile-action-list-item ds-mobile-list-item .content-main,\r\n ::ng-deep ds-mobile-action-list-item ds-mobile-list-item .content-trailing {\r\n position: relative;\r\n z-index: 1;\r\n }\r\n \r\n /* Hide divider on last list item using CSS variable */\r\n ds-mobile-action-list-item:last-of-type {\r\n --divider-display: none;\r\n }\r\n \r\n /* Destructive action styling */\r\n ds-mobile-action-list-item.destructive {\r\n --text-color-default-primary: var(--color-error-base, #ef4444);\r\n }\r\n \r\n .destructive-icon {\r\n color: var(--color-error-base, #ef4444);\r\n }\r\n \r\n /* Full-width divider between action groups */\r\n .action-group-divider {\r\n height: 1px;\r\n background: var(--color-border-subtle, #e5e5e5);\r\n margin: 8px 0;\r\n }\r\n `]\r\n})\r\nexport class DsMobileActionsBottomSheetComponent {\r\n /**\r\n * Custom action groups to display (overrides isOwnContent)\r\n */\r\n @Input() customActionGroups?: ActionGroup[];\r\n \r\n /**\r\n * Whether this content belongs to the current user (for preset content actions)\r\n */\r\n @Input() isOwnContent: boolean = false;\r\n \r\n /**\r\n * Computed action groups - uses custom groups if provided, otherwise falls back to preset content actions\r\n */\r\n actionGroups = computed<ActionGroup[]>(() => {\r\n // Use custom action groups if provided\r\n if (this.customActionGroups) {\r\n return this.customActionGroups;\r\n }\r\n \r\n // Otherwise fall back to preset content actions\r\n if (this.isOwnContent) {\r\n // Own content: Group 1 (Edit, Delete) + Group 2 (Like, Reply)\r\n return [\r\n {\r\n actions: [\r\n {\r\n action: 'edit',\r\n title: 'Rediger',\r\n icon: 'remixEditLine',\r\n destructive: false\r\n },\r\n {\r\n action: 'delete',\r\n title: 'Slet',\r\n icon: 'remixDeleteBinLine',\r\n destructive: true\r\n }\r\n ]\r\n },\r\n {\r\n actions: [\r\n {\r\n action: 'like',\r\n title: 'Synes om',\r\n icon: 'remixHeart3Line',\r\n destructive: false\r\n },\r\n {\r\n action: 'reply',\r\n title: 'Svar',\r\n icon: 'remixReplyLine',\r\n destructive: false\r\n }\r\n ]\r\n }\r\n ];\r\n } else {\r\n // Other users' content: Group 1 (Like, Reply)\r\n return [\r\n {\r\n actions: [\r\n {\r\n action: 'like',\r\n title: 'Synes om',\r\n icon: 'remixHeart3Line',\r\n destructive: false\r\n },\r\n {\r\n action: 'reply',\r\n title: 'Svar',\r\n icon: 'remixReplyLine',\r\n destructive: false\r\n }\r\n ]\r\n }\r\n ];\r\n }\r\n });\r\n \r\n constructor(private modalController: ModalController) {}\r\n \r\n /**\r\n * Handle action selection and dismiss with result\r\n */\r\n selectAction(action: string): void {\r\n this.modalController.dismiss(\r\n { action } as ActionResult,\r\n 'select'\r\n );\r\n }\r\n}\r\n\r\n// Legacy exports for backwards compatibility\r\nexport { DsMobileActionsBottomSheetComponent as DsMobilePostActionsBottomSheetComponent };\r\nexport { DsMobileActionsBottomSheetComponent as DsMobileCommentActionsBottomSheetComponent };\r\nexport type { ActionResult as PostActionResult };\r\nexport type { ActionResult as CommentActionResult };\r\n","import { Injectable } from '@angular/core';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { ComponentRef } from '@angular/core';\r\n\r\n/**\r\n * Configuration options for the bottom sheet modal\r\n */\r\nexport interface BottomSheetOptions {\r\n /** The component to display in the bottom sheet */\r\n component: any;\r\n /** Component props to pass to the modal content */\r\n componentProps?: { [key: string]: any };\r\n /** Breakpoints for the bottom sheet (0-1 values representing percentage of screen) */\r\n breakpoints?: number[];\r\n /** Initial breakpoint to open the sheet at */\r\n initialBreakpoint?: number;\r\n /** Show/hide the drag handle */\r\n handle?: boolean;\r\n /** Custom CSS class for styling */\r\n cssClass?: string | string[];\r\n /** Whether backdrop dismisses the modal */\r\n backdropDismiss?: boolean;\r\n /** Backdrop opacity (0-1) */\r\n backdropOpacity?: number;\r\n /** Enable backdrop blur effect */\r\n backdropBlur?: boolean;\r\n /** Keyboard close behavior */\r\n keyboardClose?: boolean;\r\n /** Auto-height mode: sheet sizes to content instead of using fixed breakpoints */\r\n autoHeight?: boolean;\r\n}\r\n\r\n/**\r\n * DsMobileBottomSheetService\r\n * \r\n * Service for creating and managing Ionic 6 bottom sheet modals.\r\n * Based on the Ionic blog article: https://ionic.io/blog/5-examples-of-the-new-ionic-6-bottom-sheet-modal\r\n * \r\n * Features:\r\n * - Multiple breakpoints for snap-to positions\r\n * - Customizable initial height\r\n * - Optional drag handle\r\n * - Backdrop blur effect\r\n * - Custom styling support\r\n * \r\n * @example\r\n * ```typescript\r\n * constructor(private bottomSheet: DsMobileBottomSheetService) {}\r\n * \r\n * async openSheet() {\r\n * const sheet = await this.bottomSheet.create({\r\n * component: PostCreateComponent,\r\n * breakpoints: [0, 0.5, 0.9],\r\n * initialBreakpoint: 0.5,\r\n * handle: true\r\n * });\r\n * \r\n * const result = await sheet.onWillDismiss();\r\n * console.log('Sheet dismissed with:', result.data);\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class DsMobileBottomSheetService {\r\n constructor(private modalController: ModalController) {}\r\n\r\n /**\r\n * Create and present a bottom sheet modal\r\n * \r\n * @param options Configuration options for the bottom sheet\r\n * @returns Promise that resolves to the modal instance\r\n */\r\n async create(options: BottomSheetOptions): Promise<HTMLIonModalElement> {\r\n const {\r\n component,\r\n componentProps = {},\r\n breakpoints = [0, 0.5, 0.9],\r\n initialBreakpoint = 0.5,\r\n handle = true,\r\n cssClass = '',\r\n backdropDismiss = true,\r\n backdropOpacity,\r\n backdropBlur = false,\r\n keyboardClose = true,\r\n autoHeight = false\r\n } = options;\r\n\r\n // Build CSS classes array\r\n const cssClasses = ['ds-bottom-sheet'];\r\n if (backdropBlur) {\r\n cssClasses.push('ds-bottom-sheet--blur');\r\n }\r\n if (autoHeight) {\r\n cssClasses.push('auto-height');\r\n }\r\n if (typeof cssClass === 'string' && cssClass) {\r\n cssClasses.push(cssClass);\r\n } else if (Array.isArray(cssClass)) {\r\n cssClasses.push(...cssClass);\r\n }\r\n\r\n const modal = await this.modalController.create({\r\n component,\r\n componentProps,\r\n breakpoints: autoHeight ? undefined : breakpoints,\r\n initialBreakpoint: autoHeight ? undefined : initialBreakpoint,\r\n handle: autoHeight ? false : handle,\r\n cssClass: cssClasses,\r\n backdropDismiss,\r\n keyboardClose,\r\n showBackdrop: true,\r\n canDismiss: backdropDismiss,\r\n // Remove animation delay for instant appearance\r\n animated: true,\r\n enterAnimation: undefined, // Use default but we'll customize via CSS\r\n leaveAnimation: undefined,\r\n ...(backdropOpacity !== undefined && { \r\n cssClass: [...cssClasses, 'ds-bottom-sheet--custom-backdrop']\r\n })\r\n });\r\n\r\n // Apply custom backdrop opacity if specified\r\n if (backdropOpacity !== undefined) {\r\n modal.style.setProperty('--backdrop-opacity', backdropOpacity.toString());\r\n }\r\n\r\n // Add ESC key listener to dismiss the modal\r\n const escKeyHandler = (event: KeyboardEvent) => {\r\n if (event.key === 'Escape') {\r\n modal.dismiss(undefined, 'escape');\r\n }\r\n };\r\n \r\n // Add listener when modal is presented\r\n modal.addEventListener('ionModalDidPresent', () => {\r\n document.addEventListener('keydown', escKeyHandler);\r\n });\r\n \r\n // Remove listener when modal is dismissed\r\n modal.addEventListener('ionModalDidDismiss', () => {\r\n document.removeEventListener('keydown', escKeyHandler);\r\n });\r\n\r\n await modal.present();\r\n \r\n // Don't wait - return immediately so component can try to focus\r\n // while still in user gesture context\r\n return modal;\r\n }\r\n\r\n /**\r\n * Dismiss all open modals\r\n */\r\n async dismiss(data?: any, role?: string): Promise<boolean> {\r\n return this.modalController.dismiss(data, role);\r\n }\r\n\r\n /**\r\n * Get the top-most modal overlay\r\n */\r\n async getTop(): Promise<HTMLIonModalElement | undefined> {\r\n return this.modalController.getTop();\r\n }\r\n}\r\n\r\n","import { Component, signal, ViewChild, ElementRef, AfterViewInit, OnInit } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { ModalController, IonHeader, IonToolbar, IonTitle, IonContent, IonButtons } from '@ionic/angular/standalone';\r\nimport { Keyboard } from '@capacitor/keyboard';\r\nimport { Camera, CameraResultType, CameraSource } from '@capacitor/camera';\r\nimport { StatusBar } from '@capacitor/status-bar';\r\nimport { DsButtonComponent } from '@propbinder/design-system';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobilePostCreateBottomSheetComponent\r\n * \r\n * Bottom sheet modal for creating new posts in the community feed.\r\n * This is the modal content that gets displayed in the bottom sheet.\r\n * Features Threads-inspired interface with rich text editing capabilities.\r\n * \r\n * Auto-focuses the textarea and brings up the keyboard when opened.\r\n * \r\n * Usage: Use with DsMobileBottomSheetService to present as a bottom sheet\r\n */\r\n@Component({\r\n selector: 'ds-mobile-post-create-bottom-sheet',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n IonHeader,\r\n IonToolbar,\r\n IonTitle,\r\n IonContent,\r\n IonButtons,\r\n DsButtonComponent,\r\n DsIconButtonComponent\r\n ],\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n height: 100%;\r\n }\r\n\r\n /* ============================================\r\n HEADER\r\n ============================================ */\r\n \r\n ion-header {\r\n box-shadow: none;\r\n }\r\n\r\n ion-toolbar {\r\n --background: var(--color-background-neutral-primary, #ffffff);\r\n --border-width: 0 0 1px 0;\r\n --border-color: var(--border-color-default);\r\n --padding-top: 12px;\r\n --padding-bottom: 8px;\r\n --min-height: 56px;\r\n }\r\n\r\n ion-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n line-height: 22px;\r\n letter-spacing: -0.4px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n\r\n ion-button {\r\n --color: var(--color-text-secondary, #737373);\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 400;\r\n }\r\n\r\n /* Make Post button pill-shaped */\r\n ion-buttons[slot=\"end\"] ds-button {\r\n --border-radius: 100px;\r\n }\r\n \r\n ion-buttons[slot=\"end\"] ds-button::ng-deep button {\r\n border-radius: 100px;\r\n }\r\n \r\n /* Make Cancel button pill-shaped */\r\n ion-buttons[slot=\"start\"] ds-button {\r\n --border-radius: 100px;\r\n }\r\n \r\n ion-buttons[slot=\"start\"] ds-button::ng-deep button {\r\n border-radius: 100px;\r\n }\r\n\r\n /* ============================================\r\n CONTENT AREA\r\n ============================================ */\r\n \r\n ion-content {\r\n --background: var(--color-background-neutral-primary, #ffffff);\r\n --padding-top: 0;\r\n --padding-bottom: 0;\r\n }\r\n\r\n .post-create-container {\r\n padding: 24px 16px 16px;\r\n max-width: 640px;\r\n margin: 0 auto;\r\n }\r\n \r\n .post-composer {\r\n display: flex;\r\n gap: 12px;\r\n align-items: flex-start;\r\n }\r\n \r\n .post-composer__main {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n }\r\n \r\n .post-composer__header {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n height: 32px;\r\n }\r\n \r\n .post-composer__username {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n .post-composer__textarea {\r\n width: 100%;\r\n min-height: 60px;\r\n max-height: 400px;\r\n border: none;\r\n outline: none;\r\n resize: none;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 400;\r\n line-height: 22px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n background: transparent;\r\n padding: 0;\r\n cursor: text;\r\n overflow-y: auto;\r\n /* Auto-resize as user types */\r\n field-sizing: content;\r\n }\r\n \r\n .post-composer__textarea::placeholder {\r\n color: var(--color-text-tertiary, #999999);\r\n }\r\n \r\n /* Visual focus indicator - helps users see the textarea is ready */\r\n .post-composer__textarea:focus {\r\n outline: none;\r\n }\r\n \r\n /* Subtle animation to draw attention when empty */\r\n @keyframes gentlePulse {\r\n 0%, 100% { opacity: 1; }\r\n 50% { opacity: 0.6; }\r\n }\r\n \r\n .post-composer__textarea:not(:focus):empty + .focus-hint {\r\n animation: gentlePulse 2s ease-in-out 1;\r\n }\r\n \r\n .post-composer__actions {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n padding-top: 12px;\r\n }\r\n \r\n .post-composer__actions ds-icon-button::ng-deep button {\r\n width: 44px;\r\n height: 44px;\r\n border-radius: 50%;\r\n }\r\n \r\n /* ============================================\r\n IMAGE PREVIEW\r\n ============================================ */\r\n \r\n .image-previews {\r\n display: flex;\r\n flex-wrap: wrap;\r\n gap: 8px;\r\n margin-top: 12px;\r\n }\r\n \r\n .image-preview {\r\n position: relative;\r\n width: 96px;\r\n height: 96px;\r\n border-radius: 12px;\r\n overflow: visible;\r\n }\r\n \r\n .preview-image {\r\n width: 100%;\r\n height: 100%;\r\n display: block;\r\n border-radius: 12px;\r\n border: 1px solid var(--border-color-default);\r\n object-fit: cover;\r\n }\r\n \r\n .remove-image-btn {\r\n position: absolute;\r\n top: -8px;\r\n right: -8px;\r\n width: 24px;\r\n height: 24px;\r\n border-radius: 50%;\r\n background: rgba(0, 0, 0, 0.6);\r\n backdrop-filter: blur(8px);\r\n border: 2px solid white;\r\n color: white;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n padding: 0;\r\n }\r\n \r\n .remove-image-btn:hover {\r\n background: rgba(0, 0, 0, 0.8);\r\n transform: scale(1.05);\r\n }\r\n \r\n .remove-image-btn:active {\r\n transform: scale(0.95);\r\n }\r\n \r\n /* ============================================\r\n MOBILE OPTIMIZATIONS\r\n ============================================ */\r\n \r\n @media (max-width: 768px) {\r\n .post-create-container {\r\n padding: 12px 16px 24px;\r\n }\r\n\r\n .post-composer__textarea {\r\n min-height: 60px;\r\n max-height: 300px;\r\n /* Make tap target larger on mobile */\r\n padding: 8px;\r\n margin: -8px;\r\n }\r\n }\r\n `],\r\n template: `\r\n <!-- Header with cancel and post buttons -->\r\n <ion-header>\r\n <ion-toolbar>\r\n <ion-buttons slot=\"start\">\r\n <ds-button\r\n variant=\"secondary\"\r\n size=\"sm\"\r\n (clicked)=\"handleCancel()\">\r\n Annuller\r\n </ds-button>\r\n </ion-buttons>\r\n <ion-title>{{ modalTitle() }}</ion-title>\r\n <ion-buttons slot=\"end\">\r\n <ds-button\r\n variant=\"primary\"\r\n size=\"sm\"\r\n [disabled]=\"!canPost()\"\r\n (clicked)=\"handlePost()\">\r\n {{ submitButtonLabel() }}\r\n </ds-button>\r\n </ion-buttons>\r\n </ion-toolbar>\r\n </ion-header>\r\n\r\n <!-- Content -->\r\n <ion-content>\r\n <div class=\"post-create-container\">\r\n <div class=\"post-composer\">\r\n <div class=\"post-composer__main\">\r\n <textarea\r\n #textareaInput\r\n class=\"post-composer__textarea\"\r\n [(ngModel)]=\"postContent\"\r\n [placeholder]=\"placeholder()\"\r\n [readonly]=\"isReadonly\"\r\n (input)=\"handleInput()\"\r\n (focus)=\"handleFocus()\"\r\n inputmode=\"text\"\r\n enterkeyhint=\"done\"\r\n rows=\"1\">\r\n </textarea>\r\n \r\n <!-- Image Previews -->\r\n @if (selectedImages().length > 0) {\r\n <div class=\"image-previews\">\r\n @for (image of selectedImages(); track image; let i = $index) {\r\n <div class=\"image-preview\">\r\n <img [src]=\"image\" alt=\"Selected image\" class=\"preview-image\" />\r\n <button \r\n class=\"remove-image-btn\" \r\n (click)=\"handleRemoveImage(i)\"\r\n type=\"button\"\r\n aria-label=\"Fjern billede\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n <path d=\"M12 4L4 12M4 4L12 12\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n }\r\n \r\n <div class=\"post-composer__actions\">\r\n <ds-icon-button\r\n icon=\"remixImageLine\"\r\n variant=\"secondary\"\r\n size=\"md\"\r\n (clicked)=\"handleAddImage()\"\r\n aria-label=\"Tilføj billede\">\r\n </ds-icon-button>\r\n <ds-icon-button\r\n icon=\"remixAttachmentLine\"\r\n variant=\"secondary\"\r\n size=\"md\"\r\n (clicked)=\"handleAddAttachment()\"\r\n aria-label=\"Tilføj vedhæftning\">\r\n </ds-icon-button>\r\n \r\n <!-- Hidden file input for file selection -->\r\n <input\r\n #fileInput\r\n type=\"file\"\r\n accept=\"*/*\"\r\n multiple\r\n (change)=\"handleFileSelect($event)\"\r\n style=\"display: none;\"\r\n aria-hidden=\"true\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ion-content>\r\n `\r\n})\r\nexport class DsMobilePostCreateBottomSheetComponent implements AfterViewInit, OnInit {\r\n @ViewChild('textareaInput') textareaInput?: ElementRef<HTMLTextAreaElement>;\r\n @ViewChild('fileInput') fileInput?: ElementRef<HTMLInputElement>;\r\n \r\n // Optional input to control auto-focus behavior\r\n autoFocus = true;\r\n \r\n // Control readonly state for keyboard trick\r\n isReadonly = true;\r\n \r\n // Edit mode properties - can be set via componentProps\r\n isEditMode = false;\r\n postId?: string;\r\n initialContent = '';\r\n \r\n postContent = '';\r\n selectedImages = signal<string[]>([]);\r\n username = signal('Lars Mikkelsen');\r\n placeholder = signal(\"Hvad er nyt?\");\r\n modalTitle = signal('Nyt opslag');\r\n submitButtonLabel = signal('Slå op');\r\n \r\n constructor(\r\n private modalController: ModalController,\r\n private elementRef: ElementRef\r\n ) {}\r\n \r\n /**\r\n * Ensure toolbar doesn't have unnecessary padding\r\n * Modal is already positioned below status bar, so no extra safe area needed\r\n */\r\n private applySafeAreaToToolbar(): void {\r\n try {\r\n const hostElement = this.elementRef?.nativeElement;\r\n if (hostElement) {\r\n const header = hostElement.querySelector('ion-header');\r\n if (header) {\r\n const toolbar = header.querySelector('ion-toolbar');\r\n if (toolbar) {\r\n const toolbarElement = toolbar as HTMLElement;\r\n // Ensure toolbar uses standard padding (no safe area since modal is already offset)\r\n toolbarElement.style.setProperty('--padding-top', '12px', 'important');\r\n toolbarElement.style.setProperty('--min-height', '56px', 'important');\r\n }\r\n }\r\n }\r\n } catch (e) {\r\n console.log('[SafeArea] Failed to apply to toolbar:', e);\r\n }\r\n }\r\n \r\n ngOnInit(): void {\r\n // Initialize edit mode if provided\r\n if (this.isEditMode && this.initialContent) {\r\n this.postContent = this.initialContent;\r\n this.modalTitle.set('Rediger opslag');\r\n this.submitButtonLabel.set('Gem');\r\n }\r\n }\r\n \r\n ngAfterViewInit(): void {\r\n // Apply safe area padding immediately to prevent corruption\r\n this.applySafeAreaToToolbar();\r\n \r\n // Auto-resize textarea if there's initial content (edit mode)\r\n if (this.postContent && this.textareaInput) {\r\n setTimeout(() => {\r\n this.resizeTextarea();\r\n }, 0);\r\n }\r\n \r\n // Try to focus IMMEDIATELY - no delay\r\n // This maximizes our chance of being in user gesture context\r\n if (this.autoFocus && this.textareaInput) {\r\n const textarea = this.textareaInput.nativeElement;\r\n \r\n // Remove readonly immediately\r\n this.isReadonly = false;\r\n \r\n // Try focusing with minimal delay\r\n setTimeout(() => {\r\n textarea.focus();\r\n textarea.click();\r\n \r\n // Explicitly show keyboard\r\n Keyboard.show().catch(e => console.log('Keyboard.show() not available'));\r\n \r\n // iOS sometimes needs a second attempt\r\n setTimeout(() => {\r\n textarea.focus();\r\n Keyboard.show().catch(e => console.log('Keyboard.show() not available'));\r\n }, 100);\r\n }, 10);\r\n }\r\n }\r\n \r\n /**\r\n * Ionic lifecycle hook - called when modal enters view\r\n * At 95% height, this acts more like a page than a modal\r\n * which might allow keyboard to open\r\n */\r\n ionViewDidEnter(): void {\r\n // Resize textarea in case initial attempt didn't work\r\n if (this.postContent && this.textareaInput) {\r\n this.resizeTextarea();\r\n }\r\n \r\n // Final focus attempt when view fully enters\r\n if (this.autoFocus && this.textareaInput) {\r\n this.isReadonly = false;\r\n const textarea = this.textareaInput.nativeElement;\r\n \r\n // Try to focus as if this was a page navigation\r\n textarea.focus();\r\n textarea.click();\r\n \r\n // Explicitly show keyboard\r\n Keyboard.show().catch(e => console.log('Keyboard.show() not available'));\r\n \r\n // Set cursor position\r\n const length = textarea.value.length;\r\n textarea.setSelectionRange(length, length);\r\n }\r\n }\r\n \r\n handleFocus(): void {\r\n // When user focuses (or we focus programmatically), remove readonly\r\n this.isReadonly = false;\r\n // Explicitly show keyboard\r\n Keyboard.show().catch(e => console.log('Keyboard.show() not available'));\r\n }\r\n \r\n handleInput(): void {\r\n this.resizeTextarea();\r\n }\r\n \r\n /**\r\n * Auto-resize textarea based on content\r\n */\r\n private resizeTextarea(): void {\r\n if (this.textareaInput) {\r\n const textarea = this.textareaInput.nativeElement;\r\n // Reset height to auto to get the correct scrollHeight\r\n textarea.style.height = 'auto';\r\n // Set height based on content, respecting min/max from CSS\r\n textarea.style.height = Math.min(textarea.scrollHeight, 400) + 'px';\r\n }\r\n }\r\n \r\n canPost(): boolean {\r\n return this.postContent.trim().length > 0 || this.selectedImages().length > 0;\r\n }\r\n \r\n async handleCancel(): Promise<void> {\r\n if (this.postContent.trim().length > 0 || this.selectedImages().length > 0) {\r\n // Show confirmation\r\n const confirmed = confirm('Kassér dette opslag?');\r\n if (confirmed) {\r\n await this.modalController.dismiss(null, 'cancel');\r\n }\r\n } else {\r\n await this.modalController.dismiss(null, 'cancel');\r\n }\r\n }\r\n \r\n async handlePost(): Promise<void> {\r\n if (!this.canPost()) return;\r\n \r\n if (this.isEditMode) {\r\n console.log('Updating post:', this.postId, this.postContent);\r\n } else {\r\n console.log('Creating post:', this.postContent, 'with images:', this.selectedImages().length);\r\n }\r\n \r\n // Pass the post content, images, and edit info back to the parent\r\n await this.modalController.dismiss(\r\n { \r\n content: this.postContent,\r\n images: this.selectedImages(),\r\n timestamp: new Date(),\r\n isEdit: this.isEditMode,\r\n postId: this.postId\r\n },\r\n 'post'\r\n );\r\n }\r\n \r\n async handleAddImage(): Promise<void> {\r\n console.log('Add image button clicked');\r\n \r\n // Re-apply safe area padding before opening camera (preventive)\r\n // This ensures the value is locked in before iOS corrupts it\r\n this.applySafeAreaToToolbar();\r\n \r\n try {\r\n console.log('Requesting photo from library...');\r\n \r\n const image = await Camera.getPhoto({\r\n quality: 90,\r\n allowEditing: false,\r\n resultType: CameraResultType.Uri,\r\n source: CameraSource.Photos, // Only show photo library, not camera\r\n });\r\n\r\n console.log('Photo selected successfully:', image);\r\n \r\n // Add the image path to the array\r\n if (image.webPath) {\r\n this.selectedImages.update(images => [...images, image.webPath!]);\r\n console.log('Image added to preview:', image.webPath);\r\n }\r\n \r\n // Re-apply safe area padding immediately after returning\r\n // Since we're using fixed values, this won't cause flickering\r\n requestAnimationFrame(() => {\r\n this.applySafeAreaToToolbar();\r\n });\r\n \r\n // Restore StatusBar configuration (background task)\r\n this.restoreStatusBar();\r\n \r\n } catch (error) {\r\n console.error('Photo selection error:', error);\r\n // Only show alert for non-cancellation errors\r\n if (error && typeof error === 'object' && 'message' in error) {\r\n const errorMessage = (error as any).message;\r\n if (!errorMessage.includes('cancel')) {\r\n alert(`Error selecting photo: ${JSON.stringify(error)}`);\r\n }\r\n }\r\n }\r\n }\r\n \r\n /**\r\n * Restore StatusBar configuration (background task)\r\n * Safe area padding is now handled preventively via applySafeAreaToToolbar()\r\n */\r\n private restoreStatusBar(): void {\r\n setTimeout(async () => {\r\n try {\r\n await StatusBar.setBackgroundColor({ color: '#221a4c' });\r\n await StatusBar.setOverlaysWebView({ overlay: false });\r\n } catch (e) {\r\n // StatusBar API not available, ignore\r\n }\r\n }, 0);\r\n }\r\n \r\n handleRemoveImage(index: number): void {\r\n console.log('Removing image at index:', index);\r\n this.selectedImages.update(images => images.filter((_, i) => i !== index));\r\n }\r\n \r\n handleAddAttachment(): void {\r\n console.log('Add attachment button clicked');\r\n // Trigger the hidden file input\r\n if (this.fileInput) {\r\n this.fileInput.nativeElement.click();\r\n }\r\n }\r\n \r\n handleFileSelect(event: Event): void {\r\n const input = event.target as HTMLInputElement;\r\n const files = input.files;\r\n \r\n if (!files || files.length === 0) {\r\n console.log('No files selected');\r\n return;\r\n }\r\n \r\n console.log('Files selected:', files.length);\r\n \r\n // Process each selected file\r\n Array.from(files).forEach(file => {\r\n console.log('File:', file.name, file.type, file.size);\r\n \r\n // Create a data URL for preview (for images and other files)\r\n const reader = new FileReader();\r\n reader.onload = (e) => {\r\n const result = e.target?.result as string;\r\n if (result) {\r\n // Add to selectedImages array for preview\r\n this.selectedImages.update(images => [...images, result]);\r\n console.log('File added to preview:', file.name);\r\n }\r\n };\r\n reader.readAsDataURL(file);\r\n });\r\n \r\n // Reset the input so the same file can be selected again\r\n input.value = '';\r\n }\r\n}\r\n\r\n","import { Component, input, output, HostListener, ElementRef, ViewChild, AfterViewInit, computed, inject } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { Router } from '@angular/router';\r\nimport { \r\n IonHeader, \r\n IonToolbar, \r\n IonTitle,\r\n IonContent, \r\n IonRefresher, \r\n IonRefresherContent,\r\n Platform,\r\n ModalController\r\n} from '@ionic/angular/standalone';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { MobilePageBase } from '../shared/mobile-page-base';\r\nimport { DsMobileActionsBottomSheetComponent, ActionResult } from '../bottom-sheet';\r\n\r\n/**\r\n * DsMobilePageMainComponent\r\n * \r\n * A complete mobile page layout for main/tab pages with:\r\n * - Fixed header with logomark + title + avatar\r\n * - Purple expandable header section (scrolls with content)\r\n * - White rounded content wrapper\r\n * - Pull-to-refresh support\r\n * - Auto scroll title fade-in\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Simple page -->\r\n * <ds-mobile-page-main\r\n * title=\"Inquiries\"\r\n * [avatarInitials]=\"'JD'\">\r\n * <div class=\"page-content\">\r\n * <!-- Your content -->\r\n * </div>\r\n * </ds-mobile-page-main>\r\n * \r\n * <!-- Page with custom header content -->\r\n * <ds-mobile-page-main\r\n * title=\"Home\"\r\n * headerTitle=\"Welcome, Lars\"\r\n * headerSubtitle=\"Your rental property at a glance.\"\r\n * [avatarInitials]=\"'L'\">\r\n * \r\n * <div header-content class=\"property-tiles\">\r\n * <!-- Custom header content like tiles -->\r\n * </div>\r\n * \r\n * <div class=\"page-content\">\r\n * <!-- Main page content -->\r\n * </div>\r\n * </ds-mobile-page-main>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-page-main',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonHeader,\r\n IonToolbar,\r\n IonTitle,\r\n IonContent,\r\n IonRefresher,\r\n IonRefresherContent,\r\n DsAvatarComponent\r\n ],\r\n styleUrls: ['./ds-mobile-page-main.css'],\r\n template: `\r\n <!-- Fixed header at top -->\r\n <ion-header>\r\n <ion-toolbar>\r\n <div class=\"header-home\">\r\n <!-- Propbinder Logomark -->\r\n <svg class=\"logomark\" width=\"36\" height=\"32\" viewBox=\"0 0 36 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M33.9862 5.51709H23.1724V8.82743H26.0413C26.2841 8.82743 26.4827 9.02606 26.4827 9.26881V12.7998C26.4827 13.0426 26.2841 13.2412 26.0413 13.2412H23.1724V14.3447H26.0413C26.2841 14.3447 26.4827 14.5433 26.4827 14.7861V18.3171C26.4827 18.5598 26.2841 18.7585 26.0413 18.7585H23.1724V19.8619H26.0413C26.2841 19.8619 26.4827 20.0605 26.4827 20.3033V23.8343C26.4827 24.0771 26.2841 24.2757 26.0413 24.2757H23.1724V26.2619C23.1724 26.7496 23.0267 27.2043 22.7773 27.5861H27.5862L32 31.9999V27.5861H33.9862C34.7167 27.5861 35.3103 26.9924 35.3103 26.2619V6.84123C35.3103 6.11075 34.7167 5.51709 33.9862 5.51709ZM32 23.8343C32 24.0771 31.8013 24.2757 31.5586 24.2757H28.0276C27.7848 24.2757 27.5862 24.0771 27.5862 23.8343V20.3033C27.5862 20.0605 27.7848 19.8619 28.0276 19.8619H31.5586C31.8013 19.8619 32 20.0605 32 20.3033V23.8343ZM32 18.3171C32 18.5598 31.8013 18.7585 31.5586 18.7585H28.0276C27.7848 18.7585 27.5862 18.5598 27.5862 18.3171V14.7861C27.5862 14.5433 27.7848 14.3447 28.0276 14.3447H31.5586C31.8013 14.3447 32 14.5433 32 14.7861V18.3171ZM32 12.7998C32 13.0426 31.8013 13.2412 31.5586 13.2412H28.0276C27.7848 13.2412 27.5862 13.0426 27.5862 12.7998V9.26881C27.5862 9.02606 27.7848 8.82743 28.0276 8.82743H31.5586C31.8013 8.82743 32 9.02606 32 9.26881V12.7998Z\" fill=\"white\"/>\r\n <path d=\"M20.7448 0H1.32414C0.593655 0 0 0.593655 0 1.32414V26.2621C0 26.9926 0.593655 27.5862 1.32414 27.5862H3.31034V32L7.72414 27.5862H20.7448C21.4753 27.5862 22.069 26.9926 22.069 26.2621V1.32414C22.069 0.593655 21.4753 0 20.7448 0ZM7.72414 23.8345C7.72414 24.0772 7.52552 24.2759 7.28276 24.2759H3.75172C3.50897 24.2759 3.31034 24.0772 3.31034 23.8345V20.3034C3.31034 20.0607 3.50897 19.8621 3.75172 19.8621H7.28276C7.52552 19.8621 7.72414 20.0607 7.72414 20.3034V23.8345ZM7.72414 18.3172C7.72414 18.56 7.52552 18.7586 7.28276 18.7586H3.75172C3.50897 18.7586 3.31034 18.56 3.31034 18.3172V14.7862C3.31034 14.5434 3.50897 14.3448 3.75172 14.3448H7.28276C7.52552 14.3448 7.72414 14.5434 7.72414 14.7862V18.3172ZM7.72414 12.8C7.72414 13.0428 7.52552 13.2414 7.28276 13.2414H3.75172C3.50897 13.2414 3.31034 13.0428 3.31034 12.8V9.26897C3.31034 9.02621 3.50897 8.82759 3.75172 8.82759H7.28276C7.52552 8.82759 7.72414 9.02621 7.72414 9.26897V12.8ZM7.72414 7.28276C7.72414 7.52552 7.52552 7.72414 7.28276 7.72414H3.75172C3.50897 7.72414 3.31034 7.52552 3.31034 7.28276V3.75172C3.31034 3.50897 3.50897 3.31034 3.75172 3.31034H7.28276C7.52552 3.31034 7.72414 3.50897 7.72414 3.75172V7.28276ZM13.2414 23.8345C13.2414 24.0772 13.0428 24.2759 12.8 24.2759H9.26897C9.02621 24.2759 8.82759 24.0772 8.82759 23.8345V20.3034C8.82759 20.0607 9.02621 19.8621 9.26897 19.8621H12.8C13.0428 19.8621 13.2414 20.0607 13.2414 20.3034V23.8345ZM13.2414 18.3172C13.2414 18.56 13.0428 18.7586 12.8 18.7586H9.26897C9.02621 18.7586 8.82759 18.56 8.82759 18.3172V14.7862C8.82759 14.5434 9.02621 14.3448 9.26897 14.3448H12.8C13.0428 14.3448 13.2414 14.5434 13.2414 14.7862V18.3172ZM13.2414 12.8C13.2414 13.0428 13.0428 13.2414 12.8 13.2414H9.26897C9.02621 13.2414 8.82759 13.0428 8.82759 12.8V9.26897C8.82759 9.02621 9.02621 8.82759 9.26897 8.82759H12.8C13.0428 8.82759 13.2414 9.02621 13.2414 9.26897V12.8ZM13.2414 6.84138V7.28276C13.2414 7.52552 13.0428 7.72414 12.8 7.72414H9.26897C9.02621 7.72414 8.82759 7.52552 8.82759 7.28276V3.75172C8.82759 3.50897 9.02621 3.31034 9.26897 3.31034H12.8C13.0428 3.31034 13.2414 3.50897 13.2414 3.75172V6.84138ZM18.7586 23.8345C18.7586 24.0772 18.56 24.2759 18.3172 24.2759H14.7862C14.5434 24.2759 14.3448 24.0772 14.3448 23.8345V20.3034C14.3448 20.0607 14.5434 19.8621 14.7862 19.8621H18.3172C18.56 19.8621 18.7586 20.0607 18.7586 20.3034V23.8345ZM18.7586 18.3172C18.7586 18.56 18.56 18.7586 18.3172 18.7586H14.7862C14.5434 18.7586 14.3448 18.56 14.3448 18.3172V14.7862C14.3448 14.5434 14.5434 14.3448 14.7862 14.3448H18.3172C18.56 14.3448 18.7586 14.5434 18.7586 14.7862V18.3172ZM18.7586 12.8C18.7586 13.0428 18.56 13.2414 18.3172 13.2414H14.7862C14.5434 13.2414 14.3448 13.0428 14.3448 12.8V9.26897C14.3448 9.02621 14.5434 8.82759 14.7862 8.82759H18.3172C18.56 8.82759 18.7586 9.02621 18.7586 9.26897V12.8ZM18.7586 5.51724V7.28276C18.7586 7.52552 18.56 7.72414 18.3172 7.72414H14.7862C14.5434 7.72414 14.3448 7.52552 14.3448 7.28276V3.75172C14.3448 3.50897 14.5434 3.31034 14.7862 3.31034H18.3172C18.56 3.31034 18.7586 3.50897 18.7586 3.75172V5.51724Z\" fill=\"white\"/>\r\n </svg>\r\n \r\n <!-- Title - fades in on scroll -->\r\n <ion-title class=\"header-home__title\">{{ title() }}</ion-title>\r\n \r\n <!-- Avatar -->\r\n <div class=\"header-home__actions\">\r\n <ds-avatar\r\n [size]=\"'md'\"\r\n [type]=\"avatarType()\"\r\n [initials]=\"avatarInitials()\"\r\n [src]=\"avatarSrc()\"\r\n [iconName]=\"avatarIconName()\"\r\n (click)=\"handleAvatarClick()\"\r\n style=\"cursor: pointer;\"\r\n />\r\n </div>\r\n </div>\r\n </ion-toolbar>\r\n </ion-header>\r\n\r\n <!-- Content with expandable header -->\r\n <ion-content [scrollEvents]=\"true\" (ionScroll)=\"handleScroll($event)\">\r\n <!-- Condensed header for Ionic scroll effects -->\r\n @if (showCondensedHeader()) {\r\n <ion-header collapse=\"condense\">\r\n <ion-toolbar>\r\n <ion-title size=\"large\">{{ title() }}</ion-title>\r\n </ion-toolbar>\r\n </ion-header>\r\n }\r\n\r\n <!-- Pull to refresh (only on native iOS/Android) -->\r\n @if (showRefresh() && isNativePlatform()) {\r\n <ion-refresher \r\n slot=\"fixed\" \r\n (ionRefresh)=\"handleRefresh($event)\"\r\n [pullFactor]=\"0.4\" \r\n [pullMin]=\"80\" \r\n [pullMax]=\"240\"\r\n closeDuration=\"600ms\">\r\n <ion-refresher-content\r\n pullingIcon=\"chevron-down-circle-outline\"\r\n refreshingSpinner=\"lines\">\r\n </ion-refresher-content>\r\n </ion-refresher>\r\n }\r\n\r\n <!-- Expandable header section (purple background) -->\r\n <div class=\"header-expandable\">\r\n <div class=\"header-expandable-inner\">\r\n <div class=\"header-expandable__text\">\r\n <h1 class=\"header-expandable__title\">{{ headerTitle() || title() }}</h1>\r\n @if (headerSubtitle()) {\r\n <p class=\"header-expandable__subtitle\">{{ headerSubtitle() }}</p>\r\n }\r\n </div>\r\n \r\n <!-- Slot for custom header content (e.g., property tiles) -->\r\n <ng-content select=\"[header-content]\"></ng-content>\r\n </div>\r\n </div>\r\n\r\n <!-- Content wrapper -->\r\n <div class=\"content-wrapper\">\r\n <div class=\"content-inner\">\r\n <!-- Main page content -->\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n </ion-content>\r\n `\r\n})\r\nexport class DsMobilePageMainComponent extends MobilePageBase implements AfterViewInit {\r\n @ViewChild(IonContent) ionContent?: IonContent;\r\n \r\n // Platform detection\r\n private platform = inject(Platform);\r\n private modalController = inject(ModalController);\r\n private router = inject(Router);\r\n \r\n // Computed property to check if running on native platform\r\n isNativePlatform = computed(() => \r\n this.platform.is('ios') || \r\n this.platform.is('android') || \r\n this.platform.is('capacitor')\r\n );\r\n \r\n // Inputs - Title\r\n title = input.required<string>(); // For fixed header title\r\n headerTitle = input<string>(''); // Optional different title for expandable header\r\n headerSubtitle = input<string>('');\r\n \r\n // Inputs - Avatar\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n avatarInitials = input<string>('U');\r\n avatarSrc = input<string>('');\r\n avatarIconName = input<string>('remixUser3Line');\r\n \r\n // Inputs - Features\r\n showRefresh = input<boolean>(true);\r\n showCondensedHeader = input<boolean>(true);\r\n scrollThreshold = input<number>(160); // Pixels to scroll before title appears\r\n headerFadeDistance = input<number>(150); // Distance over which header fades out\r\n \r\n // Outputs\r\n avatarClick = output<void>();\r\n refresh = output<any>();\r\n scroll = output<any>();\r\n \r\n constructor(private elementRef: ElementRef) {\r\n super();\r\n }\r\n \r\n ngAfterViewInit(): void {\r\n // Initial setup if needed\r\n }\r\n \r\n /**\r\n * Handle avatar click - opens profile actions bottom sheet\r\n */\r\n async handleAvatarClick(): Promise<void> {\r\n console.log('Avatar clicked - opening profile bottom sheet');\r\n \r\n // Emit the event for any parent listeners\r\n this.avatarClick.emit();\r\n \r\n const sheet = await this.modalController.create({\r\n component: DsMobileActionsBottomSheetComponent,\r\n componentProps: {\r\n customActionGroups: [\r\n {\r\n actions: [\r\n {\r\n action: 'profile',\r\n title: 'Min profil',\r\n icon: 'remixUser3Line',\r\n destructive: false\r\n },\r\n {\r\n action: 'settings',\r\n title: 'Indstillinger',\r\n icon: 'remixSettings3Line',\r\n destructive: false\r\n },\r\n {\r\n action: 'whitelabel-demo',\r\n title: 'Whitelabel Demo',\r\n icon: 'remixPaletteLine',\r\n destructive: false\r\n }\r\n ]\r\n },\r\n {\r\n actions: [\r\n {\r\n action: 'logout',\r\n title: 'Log ud',\r\n icon: 'remixLogoutBoxLine',\r\n destructive: true\r\n }\r\n ]\r\n }\r\n ]\r\n },\r\n // Auto-height: no breakpoints, no handle\r\n cssClass: 'ds-bottom-sheet auto-height'\r\n });\r\n \r\n await sheet.present();\r\n \r\n const result = await sheet.onWillDismiss<ActionResult>();\r\n if (result.data?.action) {\r\n console.log('Profile action selected:', result.data.action);\r\n \r\n switch (result.data.action) {\r\n case 'logout':\r\n console.log('Logging out...');\r\n // TODO: Implement logout logic\r\n break;\r\n case 'profile':\r\n console.log('Opening profile...');\r\n // TODO: Navigate to profile page\r\n break;\r\n case 'settings':\r\n console.log('Opening settings...');\r\n // TODO: Navigate to settings page\r\n break;\r\n case 'whitelabel-demo':\r\n console.log('Opening whitelabel demo...');\r\n this.router.navigate(['/whitelabel-demo']);\r\n break;\r\n }\r\n }\r\n }\r\n \r\n /**\r\n * Handle scroll events\r\n * - Shows title in fixed header when scrolled past threshold\r\n * - Fades out expandable header content based on scroll position\r\n * - Emits scroll event for custom handling\r\n */\r\n handleScroll(event: any): void {\r\n const scrollTop = event.detail.scrollTop;\r\n const header = this.elementRef.nativeElement.querySelector('ion-header:not([collapse])');\r\n const headerExpandable = this.elementRef.nativeElement.querySelector('.header-expandable');\r\n \r\n // Show title in fixed header when scrolled past threshold\r\n if (scrollTop > this.scrollThreshold()) {\r\n header?.classList.add('header-scrolled');\r\n } else {\r\n header?.classList.remove('header-scrolled');\r\n }\r\n \r\n // Fade out header-expandable content based on scroll\r\n if (headerExpandable) {\r\n const fadeDistance = this.headerFadeDistance();\r\n const fadeProgress = Math.min(scrollTop / fadeDistance, 1);\r\n \r\n // Calculate opacity (1 to 0)\r\n const opacity = 1 - fadeProgress;\r\n \r\n // Calculate transform (0px to -20px upward)\r\n const translateY = fadeProgress * -20;\r\n \r\n // Apply styles\r\n headerExpandable.style.opacity = opacity.toString();\r\n headerExpandable.style.transform = `translateY(${translateY}px)`;\r\n }\r\n \r\n this.scroll.emit(event);\r\n }\r\n \r\n /**\r\n * Handle pull-to-refresh\r\n * Emits refresh event - parent should call event.target.complete()\r\n */\r\n async handleRefresh(event: any): Promise<void> {\r\n // Haptic feedback for pull-to-refresh\r\n try {\r\n await Haptics.impact({ style: ImpactStyle.Medium });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n navigator.vibrate(50);\r\n }\r\n }\r\n \r\n this.refresh.emit(event);\r\n }\r\n}\r\n\r\n","import { Component, input, output, ElementRef } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { NavController } from '@ionic/angular/standalone';\r\nimport { IonHeader, IonToolbar, IonContent } from '@ionic/angular/standalone';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { MobilePageBase } from '../shared/mobile-page-base';\r\n\r\n/**\r\n * DsMobilePageDetailsComponent\r\n * \r\n * A mobile page layout for detail/drill-down pages with:\r\n * - Back button header (mobile + desktop variants)\r\n * - White background content area\r\n * - Responsive padding\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Simple detail page -->\r\n * <ds-mobile-page-details\r\n * title=\"Property Details\"\r\n * (back)=\"goBack()\">\r\n * <div class=\"page-content\">\r\n * <!-- Your content -->\r\n * </div>\r\n * </ds-mobile-page-details>\r\n * \r\n * <!-- With default back route -->\r\n * <ds-mobile-page-details\r\n * title=\"Invoice Details\"\r\n * backRoute=\"/invoices\">\r\n * <div class=\"page-content\">\r\n * <!-- Your content -->\r\n * </div>\r\n * </ds-mobile-page-details>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-page-details',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonHeader,\r\n IonToolbar,\r\n IonContent,\r\n DsIconComponent\r\n ],\r\n styleUrls: ['./ds-mobile-page-details.css'],\r\n template: `\r\n <!-- Mobile header - hidden on desktop -->\r\n <ion-header>\r\n <ion-toolbar>\r\n <div class=\"header-back\">\r\n <button class=\"back-button\" (click)=\"handleBack()\" [attr.aria-label]=\"'Go back'\">\r\n <ds-icon name=\"remixArrowLeftLine\" size=\"24px\" />\r\n </button>\r\n <h1 class=\"header-title\">{{ title() }}</h1>\r\n </div>\r\n </ion-toolbar>\r\n </ion-header>\r\n\r\n <ion-content>\r\n <!-- Desktop header above content -->\r\n <div class=\"desktop-header\">\r\n <button class=\"back-button\" (click)=\"handleBack()\" [attr.aria-label]=\"'Go back'\">\r\n <ds-icon name=\"remixArrowLeftLine\" size=\"24px\" />\r\n </button>\r\n <h1>{{ title() }}</h1>\r\n </div>\r\n\r\n <!-- Content area -->\r\n <div class=\"detail-content\">\r\n <ng-content></ng-content>\r\n </div>\r\n </ion-content>\r\n `\r\n})\r\nexport class DsMobilePageDetailsComponent extends MobilePageBase {\r\n // Inputs\r\n title = input.required<string>();\r\n backRoute = input<string>(''); // Optional default back route\r\n \r\n // Outputs\r\n back = output<void>();\r\n \r\n constructor(\r\n private navCtrl: NavController,\r\n private elementRef: ElementRef\r\n ) {\r\n super();\r\n }\r\n \r\n /**\r\n * Handle back navigation\r\n * \r\n * By default, navigates using the provided backRoute or browser back.\r\n * Parent components can listen to the (back) event to override this behavior.\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Default behavior: uses backRoute or browser back -->\r\n * <ds-mobile-page-details \r\n * title=\"Details\" \r\n * backRoute=\"/home\">\r\n * </ds-mobile-page-details>\r\n * \r\n * <!-- Custom behavior: parent handles navigation -->\r\n * <ds-mobile-page-details \r\n * title=\"Details\"\r\n * (back)=\"customBackHandler()\">\r\n * </ds-mobile-page-details>\r\n * ```\r\n */\r\n handleBack(): void {\r\n // Add class to trigger reverse animation\r\n this.elementRef.nativeElement.classList.add('navigating-back');\r\n \r\n // Emit event for parent to optionally handle\r\n this.back.emit();\r\n \r\n // Default behavior: navigate using backRoute or browser back\r\n if (this.backRoute()) {\r\n this.navCtrl.navigateBack(this.backRoute());\r\n } else {\r\n this.navCtrl.back();\r\n }\r\n }\r\n}\r\n\r\n","import { Component, input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n/**\r\n * DsMobileContentComponent\r\n * \r\n * Main content container for mobile pages with flexible layout options.\r\n * Provides consistent spacing and layout patterns.\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Default: stacked layout -->\r\n * <ds-mobile-content>\r\n * <ds-mobile-content-section>...</ds-mobile-content-section>\r\n * <ds-mobile-content-section>...</ds-mobile-content-section>\r\n * </ds-mobile-content>\r\n * \r\n * <!-- Grid layout -->\r\n * <ds-mobile-content layout=\"grid-2\">\r\n * <ds-mobile-content-section>...</ds-mobile-content-section>\r\n * <ds-mobile-content-section>...</ds-mobile-content-section>\r\n * </ds-mobile-content>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-content',\r\n standalone: true,\r\n imports: [CommonModule],\r\n host: {\r\n '[class.layout-stacked]': 'layout() === \"stacked\"',\r\n '[class.layout-grid-2]': 'layout() === \"grid-2\"',\r\n '[class.layout-grid-3]': 'layout() === \"grid-3\"'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 32px;\r\n max-width: 640px;\r\n margin: 0 auto;\r\n }\r\n \r\n /* Grid layouts */\r\n :host.layout-grid-2 {\r\n display: grid;\r\n grid-template-columns: repeat(2, 1fr);\r\n gap: 16px;\r\n }\r\n \r\n :host.layout-grid-3 {\r\n display: grid;\r\n grid-template-columns: repeat(3, 1fr);\r\n gap: 16px;\r\n }\r\n \r\n @media (max-width: 768px) {\r\n :host.layout-grid-2,\r\n :host.layout-grid-3 {\r\n grid-template-columns: 1fr;\r\n }\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class DsMobileContentComponent {\r\n /**\r\n * Layout mode for content sections\r\n * - 'stacked' - Vertical stack with 32px gap (default)\r\n * - 'grid-2' - 2 column grid\r\n * - 'grid-3' - 3 column grid (stacks on mobile)\r\n */\r\n layout = input<'stacked' | 'grid-2' | 'grid-3'>('stacked');\r\n}\r\n\r\n/**\r\n * DsMobileContentSectionComponent\r\n * \r\n * Section within mobile content with optional header.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-content-section>\r\n * <section-header width=\"half\"></section-header>\r\n * <content-row>\r\n * <div class=\"grey-box\"></div>\r\n * </content-row>\r\n * </ds-mobile-content-section>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-content-section',\r\n standalone: true,\r\n imports: [CommonModule],\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 16px;\r\n }\r\n `],\r\n template: `\r\n <ng-content select=\"section-header\" />\r\n <ng-content />\r\n `\r\n})\r\nexport class DsMobileContentSectionComponent {}\r\n\r\n/**\r\n * SectionHeaderComponent\r\n * \r\n * Semantic placeholder header for content sections.\r\n * Used for prototyping/placeholders.\r\n */\r\n@Component({\r\n selector: 'section-header',\r\n standalone: true,\r\n host: {\r\n '[class.w-half]': 'width() === \"half\"',\r\n '[class.w-third]': 'width() === \"third\"',\r\n '[class.w-full]': 'width() === \"full\"'\r\n },\r\n styles: [`\r\n :host {\r\n height: 20px;\r\n border-radius: 8px;\r\n background: var(--color-background-neutral-tertiary);\r\n display: block;\r\n }\r\n \r\n :host.w-half { width: 50%; }\r\n :host.w-third { width: 33%; }\r\n :host.w-full { width: 100%; }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class SectionHeaderComponent {\r\n /** Width of the header placeholder */\r\n width = input<'half' | 'third' | 'full'>('half');\r\n}\r\n\r\n/**\r\n * ContentRowComponent\r\n * \r\n * Horizontal row container for content items.\r\n */\r\n@Component({\r\n selector: 'content-row',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n gap: 12px;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class ContentRowComponent {}\r\n\r\n","import { Component, input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n/**\r\n * DsMobileHeaderContentComponent\r\n * \r\n * Container for header content tiles - displays tiles in a responsive grid.\r\n * Used within the expandable header section of mobile pages to show\r\n * summary information like property details, statistics, etc.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-header-content header-content>\r\n * <ds-mobile-header-content-tile>\r\n * <tile-icon>\r\n * <ds-icon name=\"remixHome4Line\" />\r\n * </tile-icon>\r\n * <tile-content>\r\n * <tile-label>Area</tile-label>\r\n * <tile-value>120 m²</tile-value>\r\n * </tile-content>\r\n * </ds-mobile-header-content-tile>\r\n * </ds-mobile-header-content>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-header-content',\r\n standalone: true,\r\n imports: [CommonModule],\r\n styles: [`\r\n :host {\r\n display: grid;\r\n grid-template-columns: repeat(2, 1fr);\r\n gap: 12px;\r\n }\r\n \r\n @media (min-width: 768px) {\r\n :host {\r\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\r\n }\r\n }\r\n `],\r\n template: `<ng-content select=\"ds-mobile-header-content-tile\" />`\r\n})\r\nexport class DsMobileHeaderContentComponent {}\r\n\r\n/**\r\n * DsMobileHeaderContentTileComponent\r\n * \r\n * Individual tile for displaying summary information in the header.\r\n * Styled with purple background to match the mobile header theme.\r\n * \r\n * Must contain:\r\n * - `<tile-icon>` - Icon container (optional)\r\n * - `<tile-content>` - Label and value container\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-header-content-tile>\r\n * <tile-icon>\r\n * <ds-icon name=\"remixHome4Line\" size=\"20px\" color=\"#DFE4FF\" />\r\n * </tile-icon>\r\n * <tile-content>\r\n * <tile-label>Rooms</tile-label>\r\n * <tile-value>3 rooms</tile-value>\r\n * </tile-content>\r\n * </ds-mobile-header-content-tile>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-header-content-tile',\r\n standalone: true,\r\n imports: [CommonModule],\r\n styles: [`\r\n :host {\r\n background: rgba(255, 255, 255, 0.05);\r\n border: 1px solid rgba(255, 255, 255, 0.1);\r\n border-radius: 12px;\r\n padding: 12px;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 16px;\r\n }\r\n `],\r\n template: `\r\n <ng-content select=\"tile-icon\" />\r\n <ng-content select=\"tile-content\" />\r\n `\r\n})\r\nexport class DsMobileHeaderContentTileComponent {}\r\n\r\n/**\r\n * TileIconComponent\r\n * \r\n * Semantic slot for tile icon with dark purple background.\r\n * Use within `ds-mobile-header-content-tile`.\r\n */\r\n@Component({\r\n selector: 'tile-icon',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n background: var(--color-brand-secondary);\r\n border-radius: 8px;\r\n width: 32px;\r\n height: 32px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class TileIconComponent {}\r\n\r\n/**\r\n * TileContentComponent\r\n * \r\n * Semantic slot for tile content containing label and value.\r\n * Use within `ds-mobile-header-content-tile`.\r\n * \r\n * Contains:\r\n * - `<tile-label>` - Small label text\r\n * - `<tile-value>` - Large value text\r\n */\r\n@Component({\r\n selector: 'tile-content',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 0;\r\n }\r\n \r\n ::ng-deep tile-label {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.56px;\r\n color: rgba(255, 255, 255, 0.8);\r\n display: block;\r\n }\r\n \r\n ::ng-deep tile-value {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-lg);\r\n font-weight: 600;\r\n line-height: 26px;\r\n letter-spacing: -0.72px;\r\n color: #ffffff;\r\n display: block;\r\n }\r\n `],\r\n template: `\r\n <ng-content select=\"tile-label\" />\r\n <ng-content select=\"tile-value\" />\r\n `\r\n})\r\nexport class TileContentComponent {}\r\n\r\n/**\r\n * TileLabelComponent\r\n * \r\n * Label text for tile content.\r\n * Use within `tile-content` inside `ds-mobile-header-content-tile`.\r\n */\r\n@Component({\r\n selector: 'tile-label',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.56px;\r\n color: rgba(255, 255, 255, 0.8);\r\n display: block;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class TileLabelComponent {}\r\n\r\n/**\r\n * TileValueComponent\r\n * \r\n * Value text for tile content.\r\n * Use within `tile-content` inside `ds-mobile-header-content-tile`.\r\n */\r\n@Component({\r\n selector: 'tile-value',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-lg);\r\n font-weight: 600;\r\n line-height: 26px;\r\n letter-spacing: -0.72px;\r\n color: #ffffff;\r\n display: block;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class TileValueComponent {}\r\n\r\n","import { Component, input, output, signal, model } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\n\r\n/**\r\n * DsMobilePostCardComponent\r\n * \r\n * Individual post card for community feed and post details.\r\n * Displays user posts with avatar, content, media, and action buttons.\r\n * Follows Threads-inspired design with clean layout and interactions.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-post-card\r\n * [authorName]=\"'John Doe'\"\r\n * [authorRole]=\"'Tenant'\"\r\n * [timestamp]=\"'2h ago'\"\r\n * [avatarInitials]=\"'JD'\"\r\n * [clickable]=\"true\"\r\n * (postClick)=\"openPost()\">\r\n * \r\n * <post-content>\r\n * <post-text>This is a sample post...</post-text>\r\n * </post-content>\r\n * \r\n * <post-actions>\r\n * <action-like [active]=\"true\" count=\"42\" />\r\n * <action-comment count=\"12\" />\r\n * <action-share />\r\n * </post-actions>\r\n * </ds-mobile-post-card>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-post-card',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent],\r\n styleUrls: ['../shared/mobile-common.css'],\r\n host: {\r\n '[class.clickable]': 'clickable()',\r\n '[class.variant-feed]': 'variant() === \"feed\"',\r\n '[class.variant-detail]': 'variant() === \"detail\"',\r\n '[class.variant-compact]': 'variant() === \"compact\"',\r\n '(click)': 'handlePostClick($event)',\r\n '(touchstart)': 'handleTouchStart($event)',\r\n '(touchend)': 'handleTouchEnd($event)',\r\n '(touchmove)': 'handleTouchMove($event)',\r\n '(contextmenu)': 'handleContextMenu($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n background: var(--color-background-primary, #ffffff);\r\n padding: 8px;\r\n gap: 8px;\r\n transition: all 0.2s ease;\r\n position: relative;\r\n border-radius: 16px;\r\n margin-bottom: 8px;\r\n margin-left: -8px;\r\n margin-right: -8px;\r\n }\r\n \r\n :host::after {\r\n content: '';\r\n position: absolute;\r\n bottom: -4px;\r\n left: 52px;\r\n right: 8px;\r\n height: 1px;\r\n background: var(--border-color-default);\r\n }\r\n \r\n :host:last-child {\r\n margin-bottom: 0;\r\n }\r\n \r\n :host:last-child::after {\r\n display: none;\r\n }\r\n \r\n :host.clickable {\r\n cursor: pointer;\r\n }\r\n \r\n :host.clickable:active {\r\n background: var(--color-background-neutral-primary-hover, #f5f5f5);\r\n }\r\n \r\n :host.variant-detail {\r\n padding: 0;\r\n margin-bottom: 8px;\r\n }\r\n \r\n :host.variant-detail::after {\r\n display: none;\r\n }\r\n \r\n :host.variant-compact {\r\n padding: 8px;\r\n gap: 8px;\r\n margin-bottom: 8px;\r\n }\r\n \r\n .post-header {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n }\r\n \r\n /* Author styles imported from mobile-common.css */\r\n \r\n .menu-slot {\r\n margin-left: auto;\r\n }\r\n \r\n .avatar-wrapper {\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n .avatar-badge {\r\n position: absolute;\r\n bottom: -6px;\r\n right: -6px;\r\n width: 20px;\r\n height: 20px;\r\n border-radius: 8px;\r\n background: var(--color-brand-secondary, #5d5fef);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n border: 2px solid var(--color-background-primary, #ffffff);\r\n }\r\n \r\n .avatar-badge svg {\r\n width: 10px;\r\n position: relative;\r\n top: 1px;\r\n fill: white;\r\n }\r\n `],\r\n template: `\r\n <div class=\"post-header\">\r\n <div class=\"avatar-wrapper\">\r\n <ds-avatar \r\n [initials]=\"avatarInitials()\"\r\n [type]=\"avatarType()\"\r\n [src]=\"avatarSrc()\"\r\n [iconName]=\"avatarIconName()\"\r\n size=\"md\" />\r\n \r\n @if (showBadge()) {\r\n <div class=\"avatar-badge\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 36 32\" fill=\"none\">\r\n <path d=\"M33.9862 5.51709H23.1724V8.82743H26.0413C26.2841 8.82743 26.4827 9.02606 26.4827 9.26881V12.7998C26.4827 13.0426 26.2841 13.2412 26.0413 13.2412H23.1724V14.3447H26.0413C26.2841 14.3447 26.4827 14.5433 26.4827 14.7861V18.3171C26.4827 18.5598 26.2841 18.7585 26.0413 18.7585H23.1724V19.8619H26.0413C26.2841 19.8619 26.4827 20.0605 26.4827 20.3033V23.8343C26.4827 24.0771 26.2841 24.2757 26.0413 24.2757H23.1724V26.2619C23.1724 26.7496 23.0267 27.2043 22.7773 27.5861H27.5862L32 31.9999V27.5861H33.9862C34.7167 27.5861 35.3103 26.9924 35.3103 26.2619V6.84123C35.3103 6.11075 34.7167 5.51709 33.9862 5.51709ZM32 23.8343C32 24.0771 31.8013 24.2757 31.5586 24.2757H28.0276C27.7848 24.2757 27.5862 24.0771 27.5862 23.8343V20.3033C27.5862 20.0605 27.7848 19.8619 28.0276 19.8619H31.5586C31.8013 19.8619 32 20.0605 32 20.3033V23.8343ZM32 18.3171C32 18.5598 31.8013 18.7585 31.5586 18.7585H28.0276C27.7848 18.7585 27.5862 18.5598 27.5862 18.3171V14.7861C27.5862 14.5433 27.7848 14.3447 28.0276 14.3447H31.5586C31.8013 14.3447 32 14.5433 32 14.7861V18.3171ZM32 12.7998C32 13.0426 31.8013 13.2412 31.5586 13.2412H28.0276C27.7848 13.2412 27.5862 13.0426 27.5862 12.7998V9.26881C27.5862 9.02606 27.7848 8.82743 28.0276 8.82743H31.5586C31.8013 8.82743 32 9.02606 32 9.26881V12.7998Z\" fill=\"white\"/>\r\n <path d=\"M20.7448 0H1.32414C0.593655 0 0 0.593655 0 1.32414V26.2621C0 26.9926 0.593655 27.5862 1.32414 27.5862H3.31034V32L7.72414 27.5862H20.7448C21.4753 27.5862 22.069 26.9926 22.069 26.2621V1.32414C22.069 0.593655 21.4753 0 20.7448 0ZM7.72414 23.8345C7.72414 24.0772 7.52552 24.2759 7.28276 24.2759H3.75172C3.50897 24.2759 3.31034 24.0772 3.31034 23.8345V20.3034C3.31034 20.0607 3.50897 19.8621 3.75172 19.8621H7.28276C7.52552 19.8621 7.72414 20.0607 7.72414 20.3034V23.8345ZM7.72414 18.3172C7.72414 18.56 7.52552 18.7586 7.28276 18.7586H3.75172C3.50897 18.7586 3.31034 18.56 3.31034 18.3172V14.7862C3.31034 14.5434 3.50897 14.3448 3.75172 14.3448H7.28276C7.52552 14.3448 7.72414 14.5434 7.72414 14.7862V18.3172ZM7.72414 12.8C7.72414 13.0428 7.52552 13.2414 7.28276 13.2414H3.75172C3.50897 13.2414 3.31034 13.0428 3.31034 12.8V9.26897C3.31034 9.02621 3.50897 8.82759 3.75172 8.82759H7.28276C7.52552 8.82759 7.72414 9.02621 7.72414 9.26897V12.8ZM7.72414 7.28276C7.72414 7.52552 7.52552 7.72414 7.28276 7.72414H3.75172C3.50897 7.72414 3.31034 7.52552 3.31034 7.28276V3.75172C3.31034 3.50897 3.50897 3.31034 3.75172 3.31034H7.28276C7.52552 3.31034 7.72414 3.50897 7.72414 3.75172V7.28276ZM13.2414 23.8345C13.2414 24.0772 13.0428 24.2759 12.8 24.2759H9.26897C9.02621 24.2759 8.82759 24.0772 8.82759 23.8345V20.3034C8.82759 20.0607 9.02621 19.8621 9.26897 19.8621H12.8C13.0428 19.8621 13.2414 20.0607 13.2414 20.3034V23.8345ZM13.2414 18.3172C13.2414 18.56 13.0428 18.7586 12.8 18.7586H9.26897C9.02621 18.7586 8.82759 18.56 8.82759 18.3172V14.7862C8.82759 14.5434 9.02621 14.3448 9.26897 14.3448H12.8C13.0428 14.3448 13.2414 14.5434 13.2414 14.7862V18.3172ZM13.2414 12.8C13.2414 13.0428 13.0428 13.2414 12.8 13.2414H9.26897C9.02621 13.2414 8.82759 13.0428 8.82759 12.8V9.26897C8.82759 9.02621 9.02621 8.82759 9.26897 8.82759H12.8C13.0428 8.82759 13.2414 9.02621 13.2414 9.26897V12.8ZM13.2414 6.84138V7.28276C13.2414 7.52552 13.0428 7.72414 12.8 7.72414H9.26897C9.02621 7.72414 8.82759 7.52552 8.82759 7.28276V3.75172C8.82759 3.50897 9.02621 3.31034 9.26897 3.31034H12.8C13.0428 3.31034 13.2414 3.50897 13.2414 3.75172V6.84138ZM18.7586 23.8345C18.7586 24.0772 18.56 24.2759 18.3172 24.2759H14.7862C14.5434 24.2759 14.3448 24.0772 14.3448 23.8345V20.3034C14.3448 20.0607 14.5434 19.8621 14.7862 19.8621H18.3172C18.56 19.8621 18.7586 20.0607 18.7586 20.3034V23.8345ZM18.7586 18.3172C18.7586 18.56 18.56 18.7586 18.3172 18.7586H14.7862C14.5434 18.7586 14.3448 18.56 14.3448 18.3172V14.7862C14.3448 14.5434 14.5434 14.3448 14.7862 14.3448H18.3172C18.56 14.3448 18.7586 14.5434 18.7586 14.7862V18.3172ZM18.7586 12.8C18.7586 13.0428 18.56 13.2414 18.3172 13.2414H14.7862C14.5434 13.2414 14.3448 13.0428 14.3448 12.8V9.26897C14.3448 9.02621 14.5434 8.82759 14.7862 8.82759H18.3172C18.56 8.82759 18.7586 9.02621 18.7586 9.26897V12.8ZM18.7586 5.51724V7.28276C18.7586 7.52552 18.56 7.72414 18.3172 7.72414H14.7862C14.5434 7.72414 14.3448 7.52552 14.3448 7.28276V3.75172C14.3448 3.50897 14.5434 3.31034 14.7862 3.31034H18.3172C18.56 3.31034 18.7586 3.50897 18.7586 3.75172V5.51724Z\" fill=\"white\"/>\r\n </svg>\r\n </div>\r\n }\r\n </div>\r\n \r\n <div class=\"author-details\">\r\n <div class=\"author-name\">{{ authorName() }}</div>\r\n <div class=\"author-meta\">{{ authorRole() }} · {{ timestamp() }}</div>\r\n </div>\r\n \r\n <div class=\"menu-slot\">\r\n <ng-content select=\"post-menu\" />\r\n </div>\r\n </div>\r\n \r\n <ng-content select=\"post-content\" />\r\n <ng-content select=\"post-actions\" />\r\n `\r\n})\r\nexport class DsMobilePostCardComponent {\r\n /**\r\n * Author's display name\r\n */\r\n authorName = input.required<string>();\r\n \r\n /**\r\n * Author's role (e.g., \"Tenant\", \"Property Manager\")\r\n */\r\n authorRole = input.required<string>();\r\n \r\n /**\r\n * Timestamp text (e.g., \"2h ago\", \"1d ago\")\r\n */\r\n timestamp = input.required<string>();\r\n \r\n /**\r\n * Avatar initials (for initials type)\r\n */\r\n avatarInitials = input<string>('');\r\n \r\n /**\r\n * Avatar type\r\n */\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n \r\n /**\r\n * Avatar photo source (for photo type)\r\n */\r\n avatarSrc = input<string>('');\r\n \r\n /**\r\n * Icon name (for icon type avatars)\r\n */\r\n avatarIconName = input<string>('remixUser3Fill');\r\n \r\n /**\r\n * Show badge on avatar (e.g., for property managers)\r\n */\r\n showBadge = input<boolean>(false);\r\n \r\n /**\r\n * Display variant\r\n * - 'feed' - Standard feed display (default)\r\n * - 'detail' - Full detail view\r\n * - 'compact' - Compact display for nested/related posts\r\n */\r\n variant = input<'feed' | 'detail' | 'compact'>('feed');\r\n \r\n /**\r\n * Whether the post card is clickable\r\n */\r\n clickable = input<boolean>(false);\r\n \r\n /**\r\n * Emits when the post card is clicked (if clickable)\r\n */\r\n postClick = output<void>();\r\n \r\n /**\r\n * Emits when the comment button is clicked\r\n */\r\n commentClick = output<void>();\r\n \r\n /**\r\n * Emits when the post card is long-pressed\r\n */\r\n longPress = output<void>();\r\n \r\n /**\r\n * Long press tracking\r\n */\r\n private longPressTimer: any = null;\r\n private longPressTriggered = false;\r\n private touchStartX = 0;\r\n private touchStartY = 0;\r\n private readonly LONG_PRESS_DURATION = 500; // ms\r\n private readonly MOVE_THRESHOLD = 10; // px\r\n \r\n handlePostClick(event: Event): void {\r\n if (this.clickable()) {\r\n this.postClick.emit();\r\n }\r\n }\r\n \r\n handleCommentClick(): void {\r\n this.commentClick.emit();\r\n }\r\n \r\n /**\r\n * Handle touch start for long press detection\r\n */\r\n handleTouchStart(event: TouchEvent): void {\r\n // Don't start long press if touching action buttons or interactive elements\r\n const target = event.target as HTMLElement;\r\n if (target.closest('post-actions, action-like, action-comment, action-share, button, a, img')) {\r\n return;\r\n }\r\n \r\n this.longPressTriggered = false;\r\n this.touchStartX = event.touches[0].clientX;\r\n this.touchStartY = event.touches[0].clientY;\r\n \r\n // Start long press timer\r\n this.longPressTimer = setTimeout(async () => {\r\n this.longPressTriggered = true;\r\n this.longPress.emit();\r\n \r\n // Haptic feedback for long press\r\n try {\r\n await Haptics.impact({ style: ImpactStyle.Medium });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n navigator.vibrate(50);\r\n }\r\n }\r\n }, this.LONG_PRESS_DURATION);\r\n }\r\n \r\n /**\r\n * Handle touch end to clear long press timer\r\n */\r\n handleTouchEnd(event: TouchEvent): void {\r\n if (this.longPressTimer) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n }\r\n \r\n // Prevent normal click if long press was triggered\r\n if (this.longPressTriggered) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.longPressTriggered = false;\r\n }\r\n }\r\n \r\n /**\r\n * Handle touch move to cancel long press if moved too much\r\n */\r\n handleTouchMove(event: TouchEvent): void {\r\n if (!this.longPressTimer) return;\r\n \r\n const touch = event.touches[0];\r\n const deltaX = Math.abs(touch.clientX - this.touchStartX);\r\n const deltaY = Math.abs(touch.clientY - this.touchStartY);\r\n \r\n // Cancel long press if moved too far\r\n if (deltaX > this.MOVE_THRESHOLD || deltaY > this.MOVE_THRESHOLD) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n this.longPressTriggered = false;\r\n }\r\n }\r\n \r\n /**\r\n * Handle context menu (right-click on desktop) to trigger long press action\r\n */\r\n handleContextMenu(event: Event): void {\r\n event.preventDefault();\r\n this.longPress.emit();\r\n }\r\n}\r\n\r\n/**\r\n * PostContentComponent\r\n * \r\n * Main content section of the post.\r\n * \r\n * Contains:\r\n * - `<post-text>` - Text content\r\n * - `<post-media>` - Optional images/videos\r\n * - `<post-attachments>` - Optional file attachments\r\n */\r\n@Component({\r\n selector: 'post-content',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n }\r\n \r\n :host:not(.no-indent) {\r\n padding-left: 44px;\r\n }\r\n `],\r\n template: `\r\n <ng-content select=\"post-text\" />\r\n <ng-content select=\"post-media\" />\r\n <ng-content select=\"ds-mobile-inline-photo\" />\r\n <ng-content select=\"post-attachments\" />\r\n `\r\n})\r\nexport class PostContentComponent {}\r\n\r\n/**\r\n * PostTextComponent\r\n * \r\n * Text content of the post.\r\n */\r\n@Component({\r\n selector: 'post-text',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 22px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n display: block;\r\n white-space: pre-wrap;\r\n word-wrap: break-word;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostTextComponent {}\r\n\r\n/**\r\n * PostMediaComponent\r\n * \r\n * Media container for images/videos.\r\n */\r\n@Component({\r\n selector: 'post-media',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: block;\r\n border-radius: 8px;\r\n overflow: hidden;\r\n }\r\n \r\n ::ng-deep img {\r\n width: 100%;\r\n height: auto;\r\n display: block;\r\n }\r\n \r\n ::ng-deep video {\r\n width: 100%;\r\n height: auto;\r\n display: block;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostMediaComponent {}\r\n\r\n/**\r\n * PostAttachmentsComponent\r\n * \r\n * Container for file attachments, links, etc.\r\n */\r\n@Component({\r\n selector: 'post-attachments',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostAttachmentsComponent {}\r\n\r\n/**\r\n * PostActionsComponent\r\n * \r\n * Action buttons container (like, comment, share).\r\n * \r\n * Contains:\r\n * - `<action-like>` - Like button with count\r\n * - `<action-comment>` - Comment button with count\r\n * - `<action-share>` - Share button\r\n */\r\n@Component({\r\n selector: 'post-actions',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 16px;\r\n padding-top: 4px;\r\n }\r\n \r\n :host:not(.no-indent) {\r\n padding-left: 44px;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostActionsComponent {}\r\n\r\n/**\r\n * ActionLikeComponent\r\n * \r\n * Like action button with count display and animated heart icon.\r\n */\r\n@Component({\r\n selector: 'action-like',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent],\r\n host: {\r\n '[class.active]': 'active()',\r\n '(click)': 'handleClick($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 2px;\r\n color: var(--color-text-secondary, #737373);\r\n cursor: pointer;\r\n transition: color 0.2s ease;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n }\r\n \r\n :host.active {\r\n color: #f91880;\r\n }\r\n \r\n .icon-wrapper {\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n .icon-pulse {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n opacity: 0;\r\n pointer-events: none;\r\n }\r\n \r\n .icon-pulse.animating {\r\n animation: pulse 0.4s cubic-bezier(0.4, 0, 0.2, 1);\r\n }\r\n \r\n @keyframes pulse {\r\n 0% {\r\n transform: translate(-50%, -50%) scale(1);\r\n opacity: 0.8;\r\n }\r\n 100% {\r\n transform: translate(-50%, -50%) scale(2.5);\r\n opacity: 0;\r\n }\r\n }\r\n \r\n .count {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 500;\r\n line-height: 20px;\r\n letter-spacing: -0.28px;\r\n }\r\n `],\r\n template: `\r\n <div class=\"icon-wrapper\">\r\n <ds-icon \r\n #pulseIcon\r\n class=\"icon-pulse\"\r\n [class.animating]=\"isPulsing()\"\r\n [name]=\"active() ? 'remixHeart3Fill' : 'remixHeart3Line'\" \r\n size=\"20px\" />\r\n <ds-icon \r\n [name]=\"active() ? 'remixHeart3Fill' : 'remixHeart3Line'\" \r\n size=\"20px\" />\r\n </div>\r\n @if (count() > 0) {\r\n <span class=\"count\">{{ count() }}</span>\r\n }\r\n `\r\n})\r\nexport class ActionLikeComponent {\r\n /**\r\n * Whether the like is active (user has liked)\r\n * Using model() for two-way binding\r\n */\r\n active = model<boolean>(false);\r\n \r\n /**\r\n * Number of likes\r\n * Using model() for two-way binding\r\n */\r\n count = model<number>(0);\r\n \r\n /**\r\n * Emits when the like button is clicked\r\n */\r\n likeClick = output<{ active: boolean; count: number }>();\r\n \r\n /**\r\n * Signal to control pulse animation\r\n */\r\n isPulsing = signal(false);\r\n \r\n async handleClick(event: Event): Promise<void> {\r\n event.stopPropagation();\r\n \r\n // Toggle active state\r\n const newActive = !this.active();\r\n this.active.set(newActive);\r\n \r\n // Update count\r\n const newCount = newActive ? this.count() + 1 : this.count() - 1;\r\n this.count.set(Math.max(0, newCount));\r\n \r\n // Trigger pulse animation only when liking\r\n if (newActive) {\r\n this.isPulsing.set(true);\r\n setTimeout(() => this.isPulsing.set(false), 400);\r\n }\r\n \r\n // Haptic feedback for like/unlike\r\n try {\r\n await Haptics.impact({ style: ImpactStyle.Light });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n navigator.vibrate(50);\r\n }\r\n }\r\n \r\n // Emit the event with the new state\r\n this.likeClick.emit({ active: newActive, count: newCount });\r\n }\r\n}\r\n\r\n/**\r\n * ActionCommentComponent\r\n * \r\n * Comment action button with count display.\r\n */\r\n@Component({\r\n selector: 'action-comment',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent],\r\n host: {\r\n '(click)': 'handleClick($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 2px;\r\n color: var(--color-text-secondary, #737373);\r\n cursor: pointer;\r\n transition: color 0.2s ease;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n }\r\n \r\n :host:active {\r\n transform: scale(0.95);\r\n }\r\n \r\n :host:hover {\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n .count {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 500;\r\n line-height: 20px;\r\n letter-spacing: -0.28px;\r\n }\r\n `],\r\n template: `\r\n <ds-icon name=\"remixChat3Line\" size=\"20px\" />\r\n @if (count() > 0) {\r\n <span class=\"count\">{{ count() }}</span>\r\n }\r\n `\r\n})\r\nexport class ActionCommentComponent {\r\n /**\r\n * Number of comments\r\n */\r\n count = input<number>(0);\r\n \r\n /**\r\n * Emits when the comment button is clicked\r\n */\r\n commentClick = output<void>();\r\n \r\n handleClick(event: Event): void {\r\n event.stopPropagation();\r\n this.commentClick.emit();\r\n }\r\n}\r\n","import { Component, input, output, model, signal, computed } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\n\r\n/**\r\n * DsMobileCommentComponent\r\n * \r\n * Individual comment component for post discussions.\r\n * Displays user comments with avatar, content, and like action.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-comment\r\n * [authorName]=\"'John Doe'\"\r\n * [authorRole]=\"'Tenant'\"\r\n * [timestamp]=\"'1h ago'\"\r\n * [avatarInitials]=\"'JD'\"\r\n * [content]=\"'Great post!'\">\r\n * </ds-mobile-comment>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-comment',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent, DsIconComponent, DsIconButtonComponent],\r\n styleUrls: ['../shared/mobile-common.css'],\r\n host: {\r\n '[class.clickable]': 'clickable()',\r\n '(click)': 'handleCommentClick($event)',\r\n '(touchstart)': 'handleTouchStart($event)',\r\n '(touchend)': 'handleTouchEnd($event)',\r\n '(touchmove)': 'handleTouchMove($event)',\r\n '(contextmenu)': 'handleContextMenu($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n gap: 12px;\r\n padding: 8px;\r\n position: relative;\r\n border-radius: 16px;\r\n transition: all 0.2s ease;\r\n background: var(--color-background-primary, #ffffff);\r\n margin-bottom: 8px;\r\n margin-left: -8px;\r\n margin-right: -8px;\r\n }\r\n \r\n :host:last-child {\r\n margin-bottom: 0;\r\n }\r\n \r\n :host::after {\r\n content: '';\r\n position: absolute;\r\n bottom: -4px;\r\n /* Align with comment content: padding (8px) + avatar (32px) + gap (12px) */\r\n left: 44px;\r\n /* Align with comment content right edge: padding (8px) from right */\r\n right: 8px;\r\n height: 1px;\r\n background: var(--border-color-default);\r\n }\r\n \r\n :host:last-child::after {\r\n display: none;\r\n }\r\n \r\n :host.clickable {\r\n cursor: pointer;\r\n }\r\n \r\n :host.clickable:active {\r\n background: var(--color-background-neutral-primary-hover, #f5f5f5);\r\n }\r\n \r\n .avatar-wrapper {\r\n position: relative;\r\n display: flex;\r\n align-items: flex-start;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n }\r\n \r\n .comment-content {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 4px;\r\n }\r\n \r\n .comment-header {\r\n display: flex;\r\n align-items: baseline;\r\n gap: 6px;\r\n flex-wrap: wrap;\r\n }\r\n \r\n /* Wrapper for like and more actions */\r\n .header-actions {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n margin-left: auto;\r\n }\r\n \r\n /* Desktop more actions button - using ds-icon-button */\r\n .desktop-more-button {\r\n display: none; /* Hidden by default (mobile) */\r\n }\r\n \r\n /* Make button circular */\r\n .desktop-more-button::ng-deep button {\r\n border-radius: 50% !important;\r\n }\r\n \r\n /* Show only on desktop with hover capability */\r\n @media (hover: hover) and (pointer: fine) {\r\n .desktop-more-button {\r\n display: block;\r\n }\r\n }\r\n \r\n /* Author styles imported from mobile-common.css */\r\n \r\n .action-like {\r\n display: flex;\r\n align-items: center;\r\n gap: 2px;\r\n color: var(--color-text-secondary, #737373);\r\n cursor: pointer;\r\n transition: color 0.2s ease;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 500;\r\n line-height: 18px;\r\n }\r\n \r\n .like-count {\r\n opacity: 1;\r\n }\r\n \r\n .like-count.hidden {\r\n opacity: 0;\r\n }\r\n \r\n .action-like.active {\r\n color: #f91880;\r\n }\r\n \r\n .icon-wrapper {\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n .icon-pulse {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n opacity: 0;\r\n pointer-events: none;\r\n }\r\n \r\n .icon-pulse.animating {\r\n animation: pulse 0.4s cubic-bezier(0.4, 0, 0.2, 1);\r\n }\r\n \r\n @keyframes pulse {\r\n 0% {\r\n transform: translate(-50%, -50%) scale(1);\r\n opacity: 0.8;\r\n }\r\n 100% {\r\n transform: translate(-50%, -50%) scale(2.5);\r\n opacity: 0;\r\n }\r\n }\r\n \r\n .comment-text {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 22px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n white-space: pre-wrap;\r\n word-wrap: break-word;\r\n }\r\n \r\n .comment-text ::ng-deep .mention {\r\n color: var(--color-brand-base, #6B5FF5) !important;\r\n font-weight: 600;\r\n }\r\n \r\n .comment-actions {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n margin-top: 4px;\r\n }\r\n \r\n .action-reply {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 500;\r\n line-height: 18px;\r\n color: var(--color-text-secondary, #737373);\r\n cursor: pointer;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n transition: color 0.2s ease;\r\n }\r\n \r\n .action-reply:hover {\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n .action-edit {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 500;\r\n line-height: 18px;\r\n color: var(--color-text-secondary, #737373);\r\n cursor: pointer;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n transition: color 0.2s ease;\r\n }\r\n \r\n .action-edit:hover {\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n `],\r\n template: `\r\n <div class=\"avatar-wrapper\">\r\n <ds-avatar \r\n [initials]=\"avatarInitials()\"\r\n [type]=\"avatarType()\"\r\n size=\"sm\" />\r\n </div>\r\n \r\n <div class=\"comment-content\">\r\n <div class=\"comment-header\">\r\n <span class=\"author-name\">{{ authorName() }}</span>\r\n <span class=\"author-meta\">{{ authorRole() }} · {{ timestamp() }}</span>\r\n \r\n <!-- Wrapper for like and more actions -->\r\n <div class=\"header-actions\">\r\n <div \r\n class=\"action-like\"\r\n [class.active]=\"isLiked()\"\r\n (click)=\"toggleLike()\">\r\n <span class=\"like-count\" [class.hidden]=\"likeCount() === 0\">{{ likeCount() }}</span>\r\n <div class=\"icon-wrapper\">\r\n <ds-icon \r\n class=\"icon-pulse\"\r\n [class.animating]=\"isPulsing()\"\r\n [name]=\"isLiked() ? 'remixHeart3Fill' : 'remixHeart3Line'\" \r\n size=\"16px\" />\r\n <ds-icon \r\n [name]=\"isLiked() ? 'remixHeart3Fill' : 'remixHeart3Line'\" \r\n size=\"16px\" />\r\n </div>\r\n </div>\r\n \r\n <!-- Desktop more button -->\r\n <ds-icon-button\r\n class=\"desktop-more-button\"\r\n icon=\"remixMoreFill\"\r\n variant=\"secondary\"\r\n size=\"sm\"\r\n (clicked)=\"handleMoreButtonClick($event)\"\r\n aria-label=\"More options\">\r\n </ds-icon-button>\r\n </div>\r\n </div>\r\n \r\n <div class=\"comment-text\" [innerHTML]=\"formattedContent()\"></div>\r\n \r\n <div class=\"comment-actions\">\r\n <div class=\"action-reply\" (click)=\"handleReply()\">\r\n Reply\r\n </div>\r\n @if (isOwnComment()) {\r\n <div class=\"action-edit\" (click)=\"handleEdit()\">\r\n Edit\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n `\r\n})\r\nexport class DsMobileCommentComponent {\r\n /**\r\n * Author's display name\r\n */\r\n authorName = input.required<string>();\r\n \r\n /**\r\n * Author's role (e.g., \"Tenant\", \"Property Manager\")\r\n */\r\n authorRole = input.required<string>();\r\n \r\n /**\r\n * Timestamp text (e.g., \"1h ago\", \"2d ago\")\r\n */\r\n timestamp = input.required<string>();\r\n \r\n /**\r\n * Comment content text\r\n */\r\n content = input.required<string>();\r\n \r\n /**\r\n * Avatar initials\r\n */\r\n avatarInitials = input<string>('');\r\n \r\n /**\r\n * Avatar type\r\n */\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n \r\n /**\r\n * Whether the comment is clickable\r\n */\r\n clickable = input<boolean>(false);\r\n \r\n /**\r\n * Whether this comment belongs to the current user\r\n */\r\n isOwnComment = input<boolean>(false);\r\n \r\n /**\r\n * Whether the comment is liked by current user\r\n */\r\n isLiked = model<boolean>(false);\r\n \r\n /**\r\n * Number of likes\r\n */\r\n likeCount = model<number>(0);\r\n \r\n /**\r\n * Signal to control pulse animation\r\n */\r\n isPulsing = signal(false);\r\n \r\n /**\r\n * Computed property to format content with @mentions\r\n */\r\n formattedContent = computed(() => {\r\n const text = this.content();\r\n // Replace @mentions with styled spans\r\n // Matches @FirstName or @FirstName LastName (max 2 words)\r\n return text.replace(/@([A-Za-z]+(?:\\s+[A-Za-z]+)?)\\b/g, '<span class=\"mention\">@$1</span>');\r\n });\r\n \r\n /**\r\n * Emits when the comment card is clicked (if clickable)\r\n */\r\n commentClick = output<void>();\r\n \r\n /**\r\n * Emits when reply is clicked\r\n */\r\n replyClick = output<void>();\r\n \r\n /**\r\n * Emits when edit is clicked\r\n */\r\n editClick = output<void>();\r\n \r\n /**\r\n * Emits when the comment is long-pressed\r\n */\r\n longPress = output<void>();\r\n \r\n /**\r\n * Long press tracking\r\n */\r\n private longPressTimer: any = null;\r\n private longPressTriggered = false;\r\n private touchStartX = 0;\r\n private touchStartY = 0;\r\n private readonly LONG_PRESS_DURATION = 500; // ms\r\n private readonly MOVE_THRESHOLD = 10; // px\r\n \r\n handleCommentClick(event: Event): void {\r\n // Only emit if clickable and not clicking on action buttons\r\n if (this.clickable() && !(event.target as HTMLElement).closest('.comment-actions')) {\r\n this.commentClick.emit();\r\n }\r\n }\r\n \r\n async toggleLike(): Promise<void> {\r\n const newLiked = !this.isLiked();\r\n this.isLiked.set(newLiked);\r\n \r\n const newCount = newLiked ? this.likeCount() + 1 : this.likeCount() - 1;\r\n this.likeCount.set(Math.max(0, newCount));\r\n \r\n // Trigger pulse animation only when liking\r\n if (newLiked) {\r\n this.isPulsing.set(true);\r\n setTimeout(() => this.isPulsing.set(false), 400);\r\n }\r\n \r\n // Haptic feedback for like/unlike\r\n try {\r\n await Haptics.impact({ style: ImpactStyle.Light });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n navigator.vibrate(50);\r\n }\r\n }\r\n }\r\n \r\n handleReply(): void {\r\n this.replyClick.emit();\r\n }\r\n \r\n handleEdit(): void {\r\n this.editClick.emit();\r\n }\r\n \r\n /**\r\n * Handle touch start for long press detection\r\n */\r\n handleTouchStart(event: TouchEvent): void {\r\n this.longPressTriggered = false;\r\n this.touchStartX = event.touches[0].clientX;\r\n this.touchStartY = event.touches[0].clientY;\r\n \r\n // Start long press timer\r\n this.longPressTimer = setTimeout(async () => {\r\n this.longPressTriggered = true;\r\n this.longPress.emit();\r\n \r\n // Haptic feedback for long press\r\n try {\r\n await Haptics.impact({ style: ImpactStyle.Medium });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n navigator.vibrate(50);\r\n }\r\n }\r\n }, this.LONG_PRESS_DURATION);\r\n }\r\n \r\n /**\r\n * Handle touch end to clear long press timer\r\n */\r\n handleTouchEnd(event: TouchEvent): void {\r\n if (this.longPressTimer) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n }\r\n \r\n // Prevent normal click if long press was triggered\r\n if (this.longPressTriggered) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.longPressTriggered = false;\r\n }\r\n }\r\n \r\n /**\r\n * Handle touch move to cancel long press if moved too much\r\n */\r\n handleTouchMove(event: TouchEvent): void {\r\n if (!this.longPressTimer) return;\r\n \r\n const touch = event.touches[0];\r\n const deltaX = Math.abs(touch.clientX - this.touchStartX);\r\n const deltaY = Math.abs(touch.clientY - this.touchStartY);\r\n \r\n // Cancel long press if moved too far\r\n if (deltaX > this.MOVE_THRESHOLD || deltaY > this.MOVE_THRESHOLD) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n this.longPressTriggered = false;\r\n }\r\n }\r\n \r\n /**\r\n * Handle context menu (right-click on desktop) to trigger long press action\r\n */\r\n handleContextMenu(event: Event): void {\r\n event.preventDefault();\r\n this.longPress.emit();\r\n }\r\n \r\n /**\r\n * Handle desktop more button click\r\n * Stops propagation and triggers long press action\r\n */\r\n handleMoreButtonClick(event: Event): void {\r\n console.log('[Comment] Desktop more button clicked');\r\n event.stopPropagation();\r\n event.preventDefault();\r\n this.longPress.emit();\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobilePostComposerComponent\r\n * \r\n * A \"fake\" input composer for creating new posts in the community feed.\r\n * Features a user avatar, placeholder input, and post button.\r\n * Clicking opens the full post creation modal/page.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-post-composer\r\n * [avatarInitials]=\"'LM'\"\r\n * [avatarType]=\"'photo'\"\r\n * [avatarSrc]=\"'...'\"\r\n * (composerClick)=\"openPostCreator()\">\r\n * </ds-mobile-post-composer>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-post-composer',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent],\r\n host: {\r\n '(click)': 'handleClick()'\r\n },\r\n styles: [`\r\n :host {\r\n display: block;\r\n max-width: 640px;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n }\r\n \r\n .composer-container {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n }\r\n \r\n .composer-input-wrapper {\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .composer-input {\r\n width: 100%;\r\n background: rgba(255, 255, 255, 0.1);\r\n border: none;\r\n border-radius: 24px;\r\n padding: 10px 16px;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: rgba(255, 255, 255, 0.5);\r\n outline: none;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n pointer-events: none;\r\n user-select: none;\r\n }\r\n \r\n .composer-input::placeholder {\r\n color: rgba(255, 255, 255, 0.5);\r\n opacity: 1;\r\n }\r\n \r\n /* Hover effects for desktop */\r\n @media (hover: hover) {\r\n :host:hover .composer-input {\r\n opacity: 0.8;\r\n }\r\n }\r\n `],\r\n template: `\r\n <div class=\"composer-container\">\r\n <ds-avatar \r\n [initials]=\"avatarInitials()\"\r\n [type]=\"avatarType()\"\r\n [src]=\"avatarSrc()\"\r\n [iconName]=\"avatarIconName()\"\r\n size=\"md\" />\r\n \r\n <div class=\"composer-input-wrapper\">\r\n <input \r\n type=\"text\" \r\n class=\"composer-input\" \r\n [placeholder]=\"placeholder()\"\r\n readonly\r\n tabindex=\"-1\"\r\n />\r\n </div>\r\n </div>\r\n `\r\n})\r\nexport class DsMobilePostComposerComponent {\r\n /**\r\n * Avatar initials (for initials type)\r\n */\r\n avatarInitials = input<string>('');\r\n \r\n /**\r\n * Avatar type\r\n */\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n \r\n /**\r\n * Avatar photo source (for photo type)\r\n */\r\n avatarSrc = input<string>('');\r\n \r\n /**\r\n * Icon name (for icon type avatars)\r\n */\r\n avatarIconName = input<string>('remixUser3Fill');\r\n \r\n /**\r\n * Placeholder text for the input\r\n */\r\n placeholder = input<string>(\"Hvad er nyt?\");\r\n \r\n /**\r\n * Text for the post button\r\n */\r\n buttonText = input<string>('Slå op');\r\n \r\n /**\r\n * Emits when the composer is clicked\r\n */\r\n composerClick = output<void>();\r\n \r\n handleClick(): void {\r\n this.composerClick.emit();\r\n }\r\n}\r\n\r\n","import { Component, input, output, signal, model } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\nimport { DsMobileListItemComponent } from '../list-item';\r\n\r\n/**\r\n * DsMobileInteractiveListItemPostComponent\r\n * \r\n * Specialized interactive list item for displaying social media posts.\r\n * Built on top of ds-mobile-interactive-list-item base component.\r\n * Displays user posts with avatar, content, media, and action buttons.\r\n * Follows Threads-inspired design with clean layout and interactions.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-interactive-list-item-post\r\n * [authorName]=\"'John Doe'\"\r\n * [authorRole]=\"'Tenant'\"\r\n * [timestamp]=\"'2h ago'\"\r\n * [avatarInitials]=\"'JD'\"\r\n * [clickable]=\"true\"\r\n * (postClick)=\"openPost()\">\r\n * \r\n * <post-content>\r\n * <post-text>This is a sample post...</post-text>\r\n * </post-content>\r\n * \r\n * <post-actions>\r\n * <action-like [active]=\"true\" count=\"42\" />\r\n * <action-comment count=\"12\" />\r\n * </post-actions>\r\n * </ds-mobile-interactive-list-item-post>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-interactive-list-item-post',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent, DsMobileListItemComponent],\r\n styleUrls: ['../shared/mobile-common.css'],\r\n styles: [`\r\n :host {\r\n display: block;\r\n }\r\n \r\n /* Hide divider on last child */\r\n :host:last-child {\r\n --divider-display: none;\r\n --item-padding-bottom: 0;\r\n }\r\n \r\n .post-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n height: 32px;\r\n margin-bottom: 8px;\r\n }\r\n \r\n .author-details {\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: center;\r\n gap: 2px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .author-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-primary, #202227);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n .author-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--text-color-default-tertiary, #626B78);\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n }\r\n \r\n .avatar-wrapper {\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n .avatar-badge {\r\n position: absolute;\r\n bottom: -6px;\r\n right: -6px;\r\n width: 20px;\r\n height: 20px;\r\n border-radius: 8px;\r\n background: var(--color-brand-secondary, #5d5fef);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n border: 2px solid var(--color-background-primary, #ffffff);\r\n }\r\n \r\n .avatar-badge svg {\r\n width: 10px;\r\n position: relative;\r\n top: 1px;\r\n fill: white;\r\n }\r\n \r\n .menu-slot {\r\n flex-shrink: 0;\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-list-item\r\n [leadingSize]=\"'32px'\"\r\n [variant]=\"variant()\"\r\n [interactive]=\"clickable()\"\r\n (itemClick)=\"handlePostClick()\"\r\n (longPress)=\"handleLongPress()\"\r\n (moreButtonClick)=\"handleMoreButtonClick($event)\">\r\n \r\n <div content-leading>\r\n <div class=\"avatar-wrapper\">\r\n <ds-avatar \r\n [initials]=\"avatarInitials()\"\r\n [type]=\"avatarType()\"\r\n [src]=\"avatarSrc()\"\r\n [iconName]=\"avatarIconName()\"\r\n size=\"md\" />\r\n \r\n @if (showBadge()) {\r\n <div class=\"avatar-badge\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 36 32\" fill=\"none\">\r\n <path d=\"M33.9862 5.51709H23.1724V8.82743H26.0413C26.2841 8.82743 26.4827 9.02606 26.4827 9.26881V12.7998C26.4827 13.0426 26.2841 13.2412 26.0413 13.2412H23.1724V14.3447H26.0413C26.2841 14.3447 26.4827 14.5433 26.4827 14.7861V18.3171C26.4827 18.5598 26.2841 18.7585 26.0413 18.7585H23.1724V19.8619H26.0413C26.2841 19.8619 26.4827 20.0605 26.4827 20.3033V23.8343C26.4827 24.0771 26.2841 24.2757 26.0413 24.2757H23.1724V26.2619C23.1724 26.7496 23.0267 27.2043 22.7773 27.5861H27.5862L32 31.9999V27.5861H33.9862C34.7167 27.5861 35.3103 26.9924 35.3103 26.2619V6.84123C35.3103 6.11075 34.7167 5.51709 33.9862 5.51709ZM32 23.8343C32 24.0771 31.8013 24.2757 31.5586 24.2757H28.0276C27.7848 24.2757 27.5862 24.0771 27.5862 23.8343V20.3033C27.5862 20.0605 27.7848 19.8619 28.0276 19.8619H31.5586C31.8013 19.8619 32 20.0605 32 20.3033V23.8343ZM32 18.3171C32 18.5598 31.8013 18.7585 31.5586 18.7585H28.0276C27.7848 18.7585 27.5862 18.5598 27.5862 18.3171V14.7861C27.5862 14.5433 27.7848 14.3447 28.0276 14.3447H31.5586C31.8013 14.3447 32 14.5433 32 14.7861V18.3171ZM32 12.7998C32 13.0426 31.8013 13.2412 31.5586 13.2412H28.0276C27.7848 13.2412 27.5862 13.0426 27.5862 12.7998V9.26881C27.5862 9.02606 27.7848 8.82743 28.0276 8.82743H31.5586C31.8013 8.82743 32 9.02606 32 9.26881V12.7998Z\" fill=\"white\"/>\r\n <path d=\"M20.7448 0H1.32414C0.593655 0 0 0.593655 0 1.32414V26.2621C0 26.9926 0.593655 27.5862 1.32414 27.5862H3.31034V32L7.72414 27.5862H20.7448C21.4753 27.5862 22.069 26.9926 22.069 26.2621V1.32414C22.069 0.593655 21.4753 0 20.7448 0ZM7.72414 23.8345C7.72414 24.0772 7.52552 24.2759 7.28276 24.2759H3.75172C3.50897 24.2759 3.31034 24.0772 3.31034 23.8345V20.3034C3.31034 20.0607 3.50897 19.8621 3.75172 19.8621H7.28276C7.52552 19.8621 7.72414 20.0607 7.72414 20.3034V23.8345ZM7.72414 18.3172C7.72414 18.56 7.52552 18.7586 7.28276 18.7586H3.75172C3.50897 18.7586 3.31034 18.56 3.31034 18.3172V14.7862C3.31034 14.5434 3.50897 14.3448 3.75172 14.3448H7.28276C7.52552 14.3448 7.72414 14.5434 7.72414 14.7862V18.3172ZM7.72414 12.8C7.72414 13.0428 7.52552 13.2414 7.28276 13.2414H3.75172C3.50897 13.2414 3.31034 13.0428 3.31034 12.8V9.26897C3.31034 9.02621 3.50897 8.82759 3.75172 8.82759H7.28276C7.52552 8.82759 7.72414 9.02621 7.72414 9.26897V12.8ZM7.72414 7.28276C7.72414 7.52552 7.52552 7.72414 7.28276 7.72414H3.75172C3.50897 7.72414 3.31034 7.52552 3.31034 7.28276V3.75172C3.31034 3.50897 3.50897 3.31034 3.75172 3.31034H7.28276C7.52552 3.31034 7.72414 3.50897 7.72414 3.75172V7.28276ZM13.2414 23.8345C13.2414 24.0772 13.0428 24.2759 12.8 24.2759H9.26897C9.02621 24.2759 8.82759 24.0772 8.82759 23.8345V20.3034C8.82759 20.0607 9.02621 19.8621 9.26897 19.8621H12.8C13.0428 19.8621 13.2414 20.0607 13.2414 20.3034V23.8345ZM13.2414 18.3172C13.2414 18.56 13.0428 18.7586 12.8 18.7586H9.26897C9.02621 18.7586 8.82759 18.56 8.82759 18.3172V14.7862C8.82759 14.5434 9.02621 14.3448 9.26897 14.3448H12.8C13.0428 14.3448 13.2414 14.5434 13.2414 14.7862V18.3172ZM13.2414 12.8C13.2414 13.0428 13.0428 13.2414 12.8 13.2414H9.26897C9.02621 13.2414 8.82759 13.0428 8.82759 12.8V9.26897C8.82759 9.02621 9.02621 8.82759 9.26897 8.82759H12.8C13.0428 8.82759 13.2414 9.02621 13.2414 9.26897V12.8ZM13.2414 6.84138V7.28276C13.2414 7.52552 13.0428 7.72414 12.8 7.72414H9.26897C9.02621 7.72414 8.82759 7.52552 8.82759 7.28276V3.75172C8.82759 3.50897 9.02621 3.31034 9.26897 3.31034H12.8C13.0428 3.31034 13.2414 3.50897 13.2414 3.75172V6.84138ZM18.7586 23.8345C18.7586 24.0772 18.56 24.2759 18.3172 24.2759H14.7862C14.5434 24.2759 14.3448 24.0772 14.3448 23.8345V20.3034C14.3448 20.0607 14.5434 19.8621 14.7862 19.8621H18.3172C18.56 19.8621 18.7586 20.0607 18.7586 20.3034V23.8345ZM18.7586 18.3172C18.7586 18.56 18.56 18.7586 18.3172 18.7586H14.7862C14.5434 18.7586 14.3448 18.56 14.3448 18.3172V14.7862C14.3448 14.5434 14.5434 14.3448 14.7862 14.3448H18.3172C18.56 14.3448 18.7586 14.5434 18.7586 14.7862V18.3172ZM18.7586 12.8C18.7586 13.0428 18.56 13.2414 18.3172 13.2414H14.7862C14.5434 13.2414 14.3448 13.0428 14.3448 12.8V9.26897C14.3448 9.02621 14.5434 8.82759 14.7862 8.82759H18.3172C18.56 8.82759 18.7586 9.02621 18.7586 9.26897V12.8ZM18.7586 5.51724V7.28276C18.7586 7.52552 18.56 7.72414 18.3172 7.72414H14.7862C14.5434 7.72414 14.3448 7.52552 14.3448 7.28276V3.75172C14.3448 3.50897 14.5434 3.31034 14.7862 3.31034H18.3172C18.56 3.31034 18.7586 3.50897 18.7586 3.75172V5.51724Z\" fill=\"white\"/>\r\n </svg>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n \r\n <div content-main>\r\n <div class=\"post-header\">\r\n <div class=\"author-details\">\r\n <div class=\"author-name\">{{ authorName() }}</div>\r\n <div class=\"author-meta\">{{ authorRole() }} · {{ timestamp() }}</div>\r\n </div>\r\n \r\n <div class=\"menu-slot\">\r\n <ng-content select=\"post-menu\" />\r\n </div>\r\n </div>\r\n \r\n <ng-content select=\"post-content\" />\r\n <ng-content select=\"post-actions\" />\r\n </div>\r\n </ds-mobile-list-item>\r\n `\r\n})\r\nexport class DsMobileInteractiveListItemPostComponent {\r\n /**\r\n * Author's display name\r\n */\r\n authorName = input.required<string>();\r\n \r\n /**\r\n * Author's role (e.g., \"Tenant\", \"Property Manager\")\r\n */\r\n authorRole = input.required<string>();\r\n \r\n /**\r\n * Timestamp text (e.g., \"2h ago\", \"1d ago\")\r\n */\r\n timestamp = input.required<string>();\r\n \r\n /**\r\n * Avatar initials (for initials type)\r\n */\r\n avatarInitials = input<string>('');\r\n \r\n /**\r\n * Avatar type\r\n */\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n \r\n /**\r\n * Avatar photo source (for photo type)\r\n */\r\n avatarSrc = input<string>('');\r\n \r\n /**\r\n * Icon name (for icon type avatars)\r\n */\r\n avatarIconName = input<string>('remixUser3Fill');\r\n \r\n /**\r\n * Show badge on avatar (e.g., for property managers)\r\n */\r\n showBadge = input<boolean>(false);\r\n \r\n /**\r\n * Display variant\r\n * - 'feed' - Standard feed display (default)\r\n * - 'detail' - Full detail view\r\n * - 'compact' - Compact display for nested/related posts\r\n */\r\n variant = input<'feed' | 'detail' | 'compact'>('feed');\r\n \r\n /**\r\n * Whether the post card is clickable\r\n */\r\n clickable = input<boolean>(false);\r\n \r\n /**\r\n * Emits when the post card is clicked (if clickable)\r\n */\r\n postClick = output<void>();\r\n \r\n /**\r\n * Emits when the comment button is clicked\r\n */\r\n commentClick = output<void>();\r\n \r\n /**\r\n * Emits when the post card is long-pressed\r\n */\r\n longPress = output<void>();\r\n \r\n handlePostClick(): void {\r\n console.log('[InteractiveListItemPost] handlePostClick called, emitting postClick');\r\n this.postClick.emit();\r\n }\r\n \r\n handleCommentClick(): void {\r\n this.commentClick.emit();\r\n }\r\n \r\n handleLongPress(): void {\r\n this.longPress.emit();\r\n }\r\n \r\n handleMoreButtonClick(event: Event): void {\r\n // Desktop more button click - trigger the same action as long press\r\n this.longPress.emit();\r\n }\r\n}\r\n\r\n/**\r\n * PostContentComponent\r\n * \r\n * Main content section of the post.\r\n * \r\n * Contains:\r\n * - `<post-text>` - Text content\r\n * - `<post-media>` - Optional images/videos\r\n * - `<post-attachments>` - Optional file attachments\r\n */\r\n@Component({\r\n selector: 'post-content',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n margin-bottom: 8px;\r\n }\r\n `],\r\n template: `\r\n <ng-content select=\"post-text\" />\r\n <ng-content select=\"post-media\" />\r\n <ng-content select=\"ds-mobile-inline-photo\" />\r\n <ng-content select=\"post-attachments\" />\r\n `\r\n})\r\nexport class PostContentComponent {}\r\n\r\n/**\r\n * PostTextComponent\r\n * \r\n * Text content of the post.\r\n */\r\n@Component({\r\n selector: 'post-text',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 22px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n display: block;\r\n white-space: pre-wrap;\r\n word-wrap: break-word;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostTextComponent {}\r\n\r\n/**\r\n * PostMediaComponent\r\n * \r\n * Media container for images/videos.\r\n */\r\n@Component({\r\n selector: 'post-media',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: block;\r\n border-radius: 8px;\r\n overflow: hidden;\r\n }\r\n \r\n ::ng-deep img {\r\n width: 100%;\r\n height: auto;\r\n display: block;\r\n }\r\n \r\n ::ng-deep video {\r\n width: 100%;\r\n height: auto;\r\n display: block;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostMediaComponent {}\r\n\r\n/**\r\n * PostAttachmentsComponent\r\n * \r\n * Container for file attachments, links, etc.\r\n */\r\n@Component({\r\n selector: 'post-attachments',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostAttachmentsComponent {}\r\n\r\n/**\r\n * PostActionsComponent\r\n * \r\n * Action buttons container (like, comment, share).\r\n * \r\n * Contains:\r\n * - `<action-like>` - Like button with count\r\n * - `<action-comment>` - Comment button with count\r\n * - `<action-share>` - Share button\r\n */\r\n@Component({\r\n selector: 'post-actions',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 16px;\r\n padding-top: 4px;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostActionsComponent {}\r\n\r\n/**\r\n * ActionLikeComponent\r\n * \r\n * Like action button with count display and animated heart icon.\r\n */\r\n@Component({\r\n selector: 'action-like',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent],\r\n host: {\r\n '[class.active]': 'active()',\r\n '(click)': 'handleClick($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 2px;\r\n color: var(--color-text-secondary, #737373);\r\n cursor: pointer;\r\n transition: color 0.2s ease;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n }\r\n \r\n :host.active {\r\n color: #f91880;\r\n }\r\n \r\n .icon-wrapper {\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n .icon-pulse {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n opacity: 0;\r\n pointer-events: none;\r\n }\r\n \r\n .icon-pulse.animating {\r\n animation: pulse 0.4s cubic-bezier(0.4, 0, 0.2, 1);\r\n }\r\n \r\n @keyframes pulse {\r\n 0% {\r\n transform: translate(-50%, -50%) scale(1);\r\n opacity: 0.8;\r\n }\r\n 100% {\r\n transform: translate(-50%, -50%) scale(2.5);\r\n opacity: 0;\r\n }\r\n }\r\n \r\n .count {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 500;\r\n line-height: 20px;\r\n letter-spacing: -0.28px;\r\n }\r\n `],\r\n template: `\r\n <div class=\"icon-wrapper\">\r\n <ds-icon \r\n #pulseIcon\r\n class=\"icon-pulse\"\r\n [class.animating]=\"isPulsing()\"\r\n [name]=\"active() ? 'remixHeart3Fill' : 'remixHeart3Line'\" \r\n size=\"20px\" />\r\n <ds-icon \r\n [name]=\"active() ? 'remixHeart3Fill' : 'remixHeart3Line'\" \r\n size=\"20px\" />\r\n </div>\r\n @if (count() > 0) {\r\n <span class=\"count\">{{ count() }}</span>\r\n }\r\n `\r\n})\r\nexport class ActionLikeComponent {\r\n /**\r\n * Whether the like is active (user has liked)\r\n * Using model() for two-way binding\r\n */\r\n active = model<boolean>(false);\r\n \r\n /**\r\n * Number of likes\r\n * Using model() for two-way binding\r\n */\r\n count = model<number>(0);\r\n \r\n /**\r\n * Emits when the like button is clicked\r\n */\r\n likeClick = output<{ active: boolean; count: number }>();\r\n \r\n /**\r\n * Signal to control pulse animation\r\n */\r\n isPulsing = signal(false);\r\n \r\n async handleClick(event: Event): Promise<void> {\r\n event.stopPropagation();\r\n \r\n // Toggle active state\r\n const newActive = !this.active();\r\n this.active.set(newActive);\r\n \r\n // Update count\r\n const newCount = newActive ? this.count() + 1 : this.count() - 1;\r\n this.count.set(Math.max(0, newCount));\r\n \r\n // Trigger pulse animation only when liking\r\n if (newActive) {\r\n this.isPulsing.set(true);\r\n setTimeout(() => this.isPulsing.set(false), 400);\r\n }\r\n \r\n // Haptic feedback for like/unlike\r\n try {\r\n await Haptics.impact({ style: ImpactStyle.Light });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n navigator.vibrate(50);\r\n }\r\n }\r\n \r\n // Emit the event with the new state\r\n this.likeClick.emit({ active: newActive, count: newCount });\r\n }\r\n}\r\n\r\n/**\r\n * ActionCommentComponent\r\n * \r\n * Comment action button with count display.\r\n */\r\n@Component({\r\n selector: 'action-comment',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent],\r\n host: {\r\n '(click)': 'handleClick($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 2px;\r\n color: var(--color-text-secondary, #737373);\r\n cursor: pointer;\r\n transition: color 0.2s ease;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n }\r\n \r\n :host:active {\r\n transform: scale(0.95);\r\n }\r\n \r\n :host:hover {\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n .count {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 500;\r\n line-height: 20px;\r\n letter-spacing: -0.28px;\r\n }\r\n `],\r\n template: `\r\n <ds-icon name=\"remixChat3Line\" size=\"20px\" />\r\n @if (count() > 0) {\r\n <span class=\"count\">{{ count() }}</span>\r\n }\r\n `\r\n})\r\nexport class ActionCommentComponent {\r\n /**\r\n * Number of comments\r\n */\r\n count = input<number>(0);\r\n \r\n /**\r\n * Emits when the comment button is clicked\r\n */\r\n commentClick = output<void>();\r\n \r\n handleClick(event: Event): void {\r\n event.stopPropagation();\r\n this.commentClick.emit();\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * PostPdfAttachmentComponent\r\n * \r\n * PDF file attachment display for posts.\r\n * Shows PDF info card with icon, filename, and file size.\r\n * Emits click event to open PDF in viewer.\r\n */\r\n@Component({\r\n selector: 'post-pdf-attachment',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent, DsIconComponent],\r\n host: {\r\n '(click)': 'handleClick($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n padding: 10px 12px;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-radius: 16px;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n }\r\n \r\n :host:hover {\r\n background: var(--color-background-neutral-secondary-hover, #ebebeb);\r\n }\r\n \r\n :host:active {\r\n transform: scale(0.98);\r\n }\r\n \r\n .pdf-avatar {\r\n flex-shrink: 0;\r\n }\r\n \r\n .pdf-avatar::ng-deep .avatar--icon {\r\n background-color: #ff5757 !important;\r\n }\r\n \r\n .pdf-info {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 2px;\r\n }\r\n \r\n .pdf-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n .pdf-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--color-text-tertiary, #737373);\r\n }\r\n \r\n .open-icon {\r\n color: var(--color-text-tertiary, #a3a3a3);\r\n flex-shrink: 0;\r\n }\r\n `],\r\n template: `\r\n <div class=\"pdf-avatar\">\r\n <ds-avatar\r\n type=\"icon\"\r\n iconName=\"remixFileTextLine\"\r\n size=\"md\"\r\n />\r\n </div>\r\n \r\n <div class=\"pdf-info\">\r\n <div class=\"pdf-name\">{{ fileName() }}</div>\r\n <div class=\"pdf-meta\">PDF · {{ fileSize() }}</div>\r\n </div>\r\n \r\n <ds-icon \r\n name=\"remixArrowRightSLine\" \r\n size=\"24px\"\r\n class=\"open-icon\"\r\n />\r\n `\r\n})\r\nexport class PostPdfAttachmentComponent {\r\n /**\r\n * PDF file name\r\n */\r\n fileName = input<string>('Document.pdf');\r\n \r\n /**\r\n * File size display (e.g., \"1.2 MB\")\r\n */\r\n fileSize = input<string>('');\r\n \r\n /**\r\n * Emits when the PDF attachment is clicked\r\n */\r\n pdfClick = output<void>();\r\n \r\n handleClick(event: Event): void {\r\n event.stopPropagation();\r\n this.pdfClick.emit();\r\n }\r\n}\r\n\r\n","// Export the main component and shared post components without the indent\r\nexport {\r\n DsMobileInteractiveListItemPostComponent,\r\n PostContentComponent,\r\n PostTextComponent,\r\n PostMediaComponent,\r\n PostAttachmentsComponent,\r\n PostActionsComponent,\r\n ActionLikeComponent,\r\n ActionCommentComponent\r\n} from './ds-mobile-interactive-list-item-post';\r\nexport { PostPdfAttachmentComponent } from './ds-mobile-post-pdf-attachment';\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsShapeIndicatorComponent } from '@propbinder/design-system';\r\nimport { DsMobileListItemComponent } from '../list-item';\r\n\r\n/**\r\n * DsMobileInteractiveListItemInquiryComponent\r\n * \r\n * Specialized interactive list item for displaying inquiries/tickets.\r\n * Built on top of ds-mobile-interactive-list-item base component.\r\n * Displays inquiry title, description, status, and timestamp.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-interactive-list-item-inquiry\r\n * [title]=\"'Tumble dryer is not working'\"\r\n * [description]=\"'For the past three days, I have been experiencing...'\"\r\n * [status]=\"'open'\"\r\n * [timestamp]=\"'12 days ago'\"\r\n * [iconName]=\"'remixCalendarLine'\"\r\n * [clickable]=\"true\"\r\n * (inquiryClick)=\"openInquiry()\">\r\n * </ds-mobile-interactive-list-item-inquiry>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-interactive-list-item-inquiry',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent, DsShapeIndicatorComponent, DsMobileListItemComponent],\r\n styleUrls: ['./ds-mobile-interactive-list-item-inquiry.css'],\r\n styles: [`\r\n :host {\r\n display: block;\r\n }\r\n \r\n /* Hide divider on last child */\r\n :host:last-child {\r\n --divider-display: none;\r\n --item-padding-bottom: 0;\r\n }\r\n \r\n .inquiry-icon {\r\n width: 32px;\r\n height: 32px;\r\n border-radius: 8px;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n }\r\n \r\n .inquiry-content {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 4px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .inquiry-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-primary, #202227);\r\n margin: 0;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n .inquiry-description {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n margin: 0;\r\n display: -webkit-box;\r\n -webkit-line-clamp: 2;\r\n -webkit-box-orient: vertical;\r\n overflow: hidden;\r\n }\r\n \r\n .inquiry-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n margin-top: 4px;\r\n }\r\n \r\n .inquiry-status {\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 500;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n }\r\n \r\n .inquiry-status.open {\r\n color: var(--color-brand-primary, #5d5fef);\r\n }\r\n \r\n .inquiry-status.closed {\r\n color: var(--text-color-default-tertiary, #737373);\r\n }\r\n \r\n .inquiry-timestamp {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n }\r\n \r\n .inquiry-trailing {\r\n display: flex;\r\n align-items: center;\r\n color: var(--color-text-tertiary, #a3a3a3);\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-list-item\r\n [leadingSize]=\"'32px'\"\r\n [variant]=\"variant()\"\r\n [interactive]=\"clickable()\"\r\n (itemClick)=\"handleInquiryClick()\"\r\n (longPress)=\"handleLongPress()\"\r\n (moreButtonClick)=\"handleMoreButtonClick($event)\">\r\n \r\n <div content-leading>\r\n <div class=\"inquiry-icon\">\r\n <ds-icon \r\n [name]=\"iconName()\"\r\n size=\"20px\"\r\n [color]=\"iconColor()\" />\r\n </div>\r\n </div>\r\n \r\n <div content-main>\r\n <div class=\"inquiry-content\">\r\n <h3 class=\"inquiry-title\">{{ title() }}</h3>\r\n \r\n @if (description()) {\r\n <p class=\"inquiry-description\">{{ description() }}</p>\r\n }\r\n \r\n <div class=\"inquiry-meta\">\r\n <div class=\"inquiry-status\" [class.open]=\"status() === 'open'\" [class.closed]=\"status() === 'closed'\">\r\n <ds-shape-indicator \r\n shape=\"circle\" \r\n [variant]=\"status() === 'open' ? 'brand' : 'grey'\">\r\n </ds-shape-indicator>\r\n <span>{{ computedStatusLabel() }}</span>\r\n </div>\r\n \r\n <div class=\"inquiry-timestamp\">\r\n <ds-icon name=\"remixTimeLine\" size=\"14px\" color=\"--color-text-secondary\" />\r\n <span>{{ timestamp() }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n @if (showChevron()) {\r\n <div content-trailing>\r\n <div class=\"inquiry-trailing\">\r\n <ds-icon name=\"remixArrowRightSLine\" size=\"20px\" />\r\n </div>\r\n </div>\r\n }\r\n </ds-mobile-list-item>\r\n `\r\n})\r\nexport class DsMobileInteractiveListItemInquiryComponent {\r\n /**\r\n * Inquiry title\r\n */\r\n title = input.required<string>();\r\n \r\n /**\r\n * Inquiry description/preview text\r\n */\r\n description = input<string>('');\r\n \r\n /**\r\n * Inquiry status\r\n */\r\n status = input<'open' | 'closed'>('open');\r\n \r\n /**\r\n * Status label (defaults to capitalized status)\r\n */\r\n statusLabel = input<string>('');\r\n \r\n /**\r\n * Timestamp text (e.g., \"12 days ago\", \"2 months ago\")\r\n */\r\n timestamp = input.required<string>();\r\n \r\n /**\r\n * Icon name for the leading icon\r\n */\r\n iconName = input<string>('remixTodoLine');\r\n \r\n /**\r\n * Icon color\r\n */\r\n iconColor = input<string>('secondary');\r\n \r\n /**\r\n * Display variant\r\n * - 'feed' - Standard feed display (default)\r\n * - 'detail' - Full detail view\r\n * - 'compact' - Compact display\r\n */\r\n variant = input<'feed' | 'detail' | 'compact'>('feed');\r\n \r\n /**\r\n * Whether the inquiry item is clickable\r\n */\r\n clickable = input<boolean>(true);\r\n \r\n /**\r\n * Whether to show chevron icon\r\n */\r\n showChevron = input<boolean>(true);\r\n \r\n /**\r\n * Emits when the inquiry item is clicked (if clickable)\r\n */\r\n inquiryClick = output<void>();\r\n \r\n /**\r\n * Emits when the inquiry item is long-pressed\r\n */\r\n longPress = output<void>();\r\n \r\n /**\r\n * Get computed status label\r\n */\r\n computedStatusLabel(): string {\r\n if (this.statusLabel()) {\r\n return this.statusLabel();\r\n }\r\n return this.status() === 'open' ? 'Åben' : 'Lukket';\r\n }\r\n \r\n handleInquiryClick(): void {\r\n this.inquiryClick.emit();\r\n }\r\n \r\n handleLongPress(): void {\r\n this.longPress.emit();\r\n }\r\n \r\n handleMoreButtonClick(event: Event): void {\r\n // Desktop more button click - trigger the same action as long press\r\n this.longPress.emit();\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsMobileListItemComponent } from '../list-item';\r\n\r\n/**\r\n * DsMobileInteractiveListItemMessageComponent\r\n * \r\n * Specialized interactive list item for displaying message threads.\r\n * Built on top of ds-mobile-interactive-list-item base component.\r\n * Displays message preview with sender info - simplified version without actions.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-interactive-list-item-message\r\n * [senderName]=\"'John Doe'\"\r\n * [senderRole]=\"'Tenant'\"\r\n * [timestamp]=\"'2h ago'\"\r\n * [message]=\"'Hey, when is the maintenance scheduled?'\"\r\n * [avatarInitials]=\"'JD'\"\r\n * [unread]=\"true\"\r\n * [clickable]=\"true\"\r\n * (messageClick)=\"openThread()\">\r\n * </ds-mobile-interactive-list-item-message>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-interactive-list-item-message',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent, DsMobileListItemComponent],\r\n styles: [`\r\n :host {\r\n display: block;\r\n }\r\n \r\n /* Hide divider on last child */\r\n :host:last-child {\r\n --divider-display: none;\r\n --item-padding-bottom: 0;\r\n }\r\n \r\n .message-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n }\r\n \r\n .sender-details {\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .sender-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-primary, #202227);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n flex-shrink: 0;\r\n }\r\n \r\n .sender-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--text-color-default-tertiary, #737373);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n flex-shrink: 1;\r\n }\r\n \r\n .unread-indicator {\r\n width: 8px;\r\n height: 8px;\r\n border-radius: 50%;\r\n background: var(--color-brand-primary, #5d5fef);\r\n flex-shrink: 0;\r\n }\r\n \r\n .message-preview {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n margin: 0;\r\n display: -webkit-box;\r\n -webkit-line-clamp: 2;\r\n -webkit-box-orient: vertical;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-list-item\r\n [leadingSize]=\"'32px'\"\r\n [variant]=\"'feed'\"\r\n [interactive]=\"clickable()\"\r\n (itemClick)=\"handleMessageClick()\"\r\n (longPress)=\"handleLongPress()\">\r\n \r\n <div content-leading>\r\n <ds-avatar \r\n [initials]=\"avatarInitials()\"\r\n [type]=\"avatarType()\"\r\n [src]=\"avatarSrc()\"\r\n size=\"md\" />\r\n </div>\r\n \r\n <div content-main>\r\n <div class=\"message-header\">\r\n <div class=\"sender-details\">\r\n <span class=\"sender-name\">{{ senderName() }}</span>\r\n <span class=\"sender-meta\">{{ senderRole() }}</span>\r\n </div>\r\n \r\n @if (unread()) {\r\n <div class=\"unread-indicator\"></div>\r\n }\r\n </div>\r\n \r\n <p class=\"message-preview\">{{ message() }}</p>\r\n </div>\r\n </ds-mobile-list-item>\r\n `\r\n})\r\nexport class DsMobileInteractiveListItemMessageComponent {\r\n /**\r\n * Sender's display name\r\n */\r\n senderName = input.required<string>();\r\n \r\n /**\r\n * Sender's role (e.g., \"Tenant\", \"Property Manager\")\r\n */\r\n senderRole = input.required<string>();\r\n \r\n /**\r\n * Message preview text\r\n */\r\n message = input.required<string>();\r\n \r\n /**\r\n * Avatar initials (for initials type)\r\n */\r\n avatarInitials = input<string>('');\r\n \r\n /**\r\n * Avatar type\r\n */\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n \r\n /**\r\n * Avatar photo source (for photo type)\r\n */\r\n avatarSrc = input<string>('');\r\n \r\n /**\r\n * Whether the message is unread\r\n */\r\n unread = input<boolean>(false);\r\n \r\n /**\r\n * Whether the message item is clickable\r\n */\r\n clickable = input<boolean>(true);\r\n \r\n /**\r\n * Emits when the message item is clicked\r\n */\r\n messageClick = output<void>();\r\n \r\n /**\r\n * Emits when the message item is long-pressed\r\n */\r\n longPress = output<void>();\r\n \r\n handleMessageClick(): void {\r\n this.messageClick.emit();\r\n }\r\n \r\n handleLongPress(): void {\r\n this.longPress.emit();\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobileContactListItemComponent\r\n * \r\n * Specialized interactive component for displaying contacts.\r\n * Displays contact name with avatar initials and metadata (person name + phone number).\r\n * Similar styling to file attachments with rounded corners and hover states.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-contact-list-item\r\n * [name]=\"'Mortensen & Søn ApS'\"\r\n * [initials]=\"'M'\"\r\n * [contactPerson]=\"'John Mortensen'\"\r\n * [phoneNumber]=\"'+45 12 34 56 78'\"\r\n * [clickable]=\"true\"\r\n * (contactClick)=\"openContact()\">\r\n * </ds-mobile-contact-list-item>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-contact-list-item',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent, DsAvatarComponent],\r\n host: {\r\n '[class.clickable]': 'clickable()',\r\n '(click)': 'handleContactClick()'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n padding: 10px 12px;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-radius: 16px;\r\n transition: all 0.2s ease;\r\n }\r\n \r\n :host.clickable {\r\n cursor: pointer;\r\n }\r\n \r\n :host.clickable:hover {\r\n background: var(--color-background-neutral-secondary-hover, #ebebeb);\r\n }\r\n \r\n :host.clickable:active {\r\n transform: scale(0.98);\r\n }\r\n \r\n .contact-avatar {\r\n flex-shrink: 0;\r\n }\r\n\r\n .contact-content {\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: center;\r\n gap: 2px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .contact-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n margin: 0;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n .contact-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--color-text-tertiary, #737373);\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n margin: 0;\r\n }\r\n \r\n .meta-separator {\r\n color: var(--color-text-tertiary, #a0a0a0);\r\n }\r\n \r\n .contact-trailing {\r\n display: flex;\r\n align-items: center;\r\n color: var(--color-text-tertiary, #a3a3a3);\r\n flex-shrink: 0;\r\n }\r\n `],\r\n template: `\r\n <div class=\"contact-avatar\">\r\n <ds-avatar\r\n [initials]=\"initials()\"\r\n type=\"initials\"\r\n size=\"md\"\r\n />\r\n </div>\r\n \r\n <div class=\"contact-content\">\r\n <div class=\"contact-name\">{{ name() }}</div>\r\n \r\n @if (contactPerson() || phoneNumber()) {\r\n <div class=\"contact-meta\">\r\n @if (contactPerson()) {\r\n <span>{{ contactPerson() }}</span>\r\n }\r\n @if (contactPerson() && phoneNumber()) {\r\n <span class=\"meta-separator\">·</span>\r\n }\r\n @if (phoneNumber()) {\r\n <span>{{ phoneNumber() }}</span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n \r\n @if (showChevron()) {\r\n <div class=\"contact-trailing\">\r\n <ds-icon name=\"remixArrowRightSLine\" size=\"20px\" />\r\n </div>\r\n }\r\n `\r\n})\r\nexport class DsMobileContactListItemComponent {\r\n /**\r\n * Contact/company name\r\n */\r\n name = input.required<string>();\r\n \r\n /**\r\n * Avatar initials (usually 1-2 letters)\r\n */\r\n initials = input.required<string>();\r\n \r\n /**\r\n * Contact person name (optional)\r\n */\r\n contactPerson = input<string>('');\r\n \r\n /**\r\n * Phone number (optional)\r\n */\r\n phoneNumber = input<string>('');\r\n \r\n /**\r\n * Whether the contact item is clickable\r\n */\r\n clickable = input<boolean>(true);\r\n \r\n /**\r\n * Whether to show chevron icon\r\n */\r\n showChevron = input<boolean>(true);\r\n \r\n /**\r\n * Emits when the contact item is clicked (if clickable)\r\n */\r\n contactClick = output<void>();\r\n \r\n handleContactClick(): void {\r\n if (this.clickable()) {\r\n this.contactClick.emit();\r\n }\r\n }\r\n}\r\n\r\n","import { Component, ElementRef, signal, ViewChild, AfterViewInit, input, output, effect, Injector, computed, inject } from '@angular/core';\r\nimport { Router } from '@angular/router';\r\nimport { CommonModule } from '@angular/common';\r\nimport { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';\r\nimport { \r\n IonTabs, \r\n IonTabBar, \r\n IonTabButton, \r\n IonLabel,\r\n IonHeader, \r\n IonToolbar, \r\n IonContent, \r\n IonRefresher, \r\n IonRefresherContent,\r\n Platform\r\n} from '@ionic/angular/standalone';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\n\r\nexport interface TabConfig {\r\n id: string;\r\n label: string;\r\n route: string;\r\n icon: string;\r\n iconActive: string;\r\n}\r\n\r\nexport type HeaderVariant = 'home' | 'simple' | 'back' | 'none';\r\n\r\n/**\r\n * DsMobileAppLayoutComponent\r\n * \r\n * A complete mobile application shell component based on actual mobile page patterns.\r\n * Provides tab navigation, flexible headers, and mobile-optimized layout.\r\n * \r\n * Features:\r\n * - Tab bar navigation with active state\r\n * - Multiple header variants (home with logomark, simple title, back button)\r\n * - Pull-to-refresh support\r\n * - Purple brand background with content wrapper\r\n * - iOS safe area support\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-app-layout\r\n * [showTabBar]=\"true\"\r\n * [tabs]=\"tabsConfig\"\r\n * [headerVariant]=\"'home'\"\r\n * [avatarInitials]=\"'JD'\"\r\n * />\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-app-layout',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonTabs,\r\n IonTabBar,\r\n IonTabButton,\r\n IonLabel,\r\n IonHeader,\r\n IonToolbar,\r\n IonContent,\r\n IonRefresher,\r\n IonRefresherContent,\r\n DsIconComponent,\r\n DsAvatarComponent\r\n ],\r\n styleUrls: ['./ds-mobile-app-layout.css'],\r\n template: `\r\n @if (showTabBar()) {\r\n <!-- Layout with tab bar - NO ion-content, pages provide their own -->\r\n <ion-tabs>\r\n <!-- Tab Bar - dynamic slot based on viewport -->\r\n <ion-tab-bar [attr.slot]=\"isDesktop() ? 'top' : 'bottom'\">\r\n @for (tab of tabs(); track tab.id) {\r\n <ion-tab-button \r\n [tab]=\"tab.id\" \r\n (click)=\"navigateToTab(tab.route)\">\r\n <ds-icon \r\n [name]=\"isTabActive(tab.id) ? tab.iconActive : tab.icon\" \r\n size=\"24px\" \r\n />\r\n <ion-label>{{ tab.label }}</ion-label>\r\n </ion-tab-button>\r\n }\r\n </ion-tab-bar>\r\n </ion-tabs>\r\n } @else {\r\n <!-- Standalone layout (no tabs) -->\r\n @if (headerVariant() !== 'none') {\r\n <ion-header>\r\n <ion-toolbar>\r\n @switch (headerVariant()) {\r\n @case ('home') {\r\n <div class=\"header-home\">\r\n <svg class=\"logomark\" width=\"36\" height=\"32\" viewBox=\"0 0 36 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M33.9862 5.51709H23.1724V8.82743H26.0413C26.2841 8.82743 26.4827 9.02606 26.4827 9.26881V12.7998C26.4827 13.0426 26.2841 13.2412 26.0413 13.2412H23.1724V14.3447H26.0413C26.2841 14.3447 26.4827 14.5433 26.4827 14.7861V18.3171C26.4827 18.5598 26.2841 18.7585 26.0413 18.7585H23.1724V19.8619H26.0413C26.2841 19.8619 26.4827 20.0605 26.4827 20.3033V23.8343C26.4827 24.0771 26.2841 24.2757 26.0413 24.2757H23.1724V26.2619C23.1724 26.7496 23.0267 27.2043 22.7773 27.5861H27.5862L32 31.9999V27.5861H33.9862C34.7167 27.5861 35.3103 26.9924 35.3103 26.2619V6.84123C35.3103 6.11075 34.7167 5.51709 33.9862 5.51709ZM32 23.8343C32 24.0771 31.8013 24.2757 31.5586 24.2757H28.0276C27.7848 24.2757 27.5862 24.0771 27.5862 23.8343V20.3033C27.5862 20.0605 27.7848 19.8619 28.0276 19.8619H31.5586C31.8013 19.8619 32 20.0605 32 20.3033V23.8343ZM32 18.3171C32 18.5598 31.8013 18.7585 31.5586 18.7585H28.0276C27.7848 18.7585 27.5862 18.5598 27.5862 18.3171V14.7861C27.5862 14.5433 27.7848 14.3447 28.0276 14.3447H31.5586C31.8013 14.3447 32 14.5433 32 14.7861V18.3171ZM32 12.7998C32 13.0426 31.8013 13.2412 31.5586 13.2412H28.0276C27.7848 13.2412 27.5862 13.0426 27.5862 12.7998V9.26881C27.5862 9.02606 27.7848 8.82743 28.0276 8.82743H31.5586C31.8013 8.82743 32 9.02606 32 9.26881V12.7998Z\" fill=\"white\"/>\r\n <path d=\"M20.7448 0H1.32414C0.593655 0 0 0.593655 0 1.32414V26.2621C0 26.9926 0.593655 27.5862 1.32414 27.5862H3.31034V32L7.72414 27.5862H20.7448C21.4753 27.5862 22.069 26.9926 22.069 26.2621V1.32414C22.069 0.593655 21.4753 0 20.7448 0ZM7.72414 23.8345C7.72414 24.0772 7.52552 24.2759 7.28276 24.2759H3.75172C3.50897 24.2759 3.31034 24.0772 3.31034 23.8345V20.3034C3.31034 20.0607 3.50897 19.8621 3.75172 19.8621H7.28276C7.52552 19.8621 7.72414 20.0607 7.72414 20.3034V23.8345ZM7.72414 18.3172C7.72414 18.56 7.52552 18.7586 7.28276 18.7586H3.75172C3.50897 18.7586 3.31034 18.56 3.31034 18.3172V14.7862C3.31034 14.5434 3.50897 14.3448 3.75172 14.3448H7.28276C7.52552 14.3448 7.72414 14.5434 7.72414 14.7862V18.3172ZM7.72414 12.8C7.72414 13.0428 7.52552 13.2414 7.28276 13.2414H3.75172C3.50897 13.2414 3.31034 13.0428 3.31034 12.8V9.26897C3.31034 9.02621 3.50897 8.82759 3.75172 8.82759H7.28276C7.52552 8.82759 7.72414 9.02621 7.72414 9.26897V12.8ZM7.72414 7.28276C7.72414 7.52552 7.52552 7.72414 7.28276 7.72414H3.75172C3.50897 7.72414 3.31034 7.52552 3.31034 7.28276V3.75172C3.31034 3.50897 3.50897 3.31034 3.75172 3.31034H7.28276C7.52552 3.31034 7.72414 3.50897 7.72414 3.75172V7.28276ZM13.2414 23.8345C13.2414 24.0772 13.0428 24.2759 12.8 24.2759H9.26897C9.02621 24.2759 8.82759 24.0772 8.82759 23.8345V20.3034C8.82759 20.0607 9.02621 19.8621 9.26897 19.8621H12.8C13.0428 19.8621 13.2414 20.0607 13.2414 20.3034V23.8345ZM13.2414 18.3172C13.2414 18.56 13.0428 18.7586 12.8 18.7586H9.26897C9.02621 18.7586 8.82759 18.56 8.82759 18.3172V14.7862C8.82759 14.5434 9.02621 14.3448 9.26897 14.3448H12.8C13.0428 14.3448 13.2414 14.5434 13.2414 14.7862V18.3172ZM13.2414 12.8C13.2414 13.0428 13.0428 13.2414 12.8 13.2414H9.26897C9.02621 13.2414 8.82759 13.0428 8.82759 12.8V9.26897C8.82759 9.02621 9.02621 8.82759 9.26897 8.82759H12.8C13.0428 8.82759 13.2414 9.02621 13.2414 9.26897V12.8ZM13.2414 6.84138V7.28276C13.2414 7.52552 13.0428 7.72414 12.8 7.72414H9.26897C9.02621 7.72414 8.82759 7.52552 8.82759 7.28276V3.75172C8.82759 3.50897 9.02621 3.31034 9.26897 3.31034H12.8C13.0428 3.31034 13.2414 3.50897 13.2414 3.75172V6.84138ZM18.7586 23.8345C18.7586 24.0772 18.56 24.2759 18.3172 24.2759H14.7862C14.5434 24.2759 14.3448 24.0772 14.3448 23.8345V20.3034C14.3448 20.0607 14.5434 19.8621 14.7862 19.8621H18.3172C18.56 19.8621 18.7586 20.0607 18.7586 20.3034V23.8345ZM18.7586 18.3172C18.7586 18.56 18.56 18.7586 18.3172 18.7586H14.7862C14.5434 18.7586 14.3448 18.56 14.3448 18.3172V14.7862C14.3448 14.5434 14.5434 14.3448 14.7862 14.3448H18.3172C18.56 14.3448 18.7586 14.5434 18.7586 14.7862V18.3172ZM18.7586 12.8C18.7586 13.0428 18.56 13.2414 18.3172 13.2414H14.7862C14.5434 13.2414 14.3448 13.0428 14.3448 12.8V9.26897C14.3448 9.02621 14.5434 8.82759 14.7862 8.82759H18.3172C18.56 8.82759 18.7586 9.02621 18.7586 9.26897V12.8ZM18.7586 5.51724V7.28276C18.7586 7.52552 18.56 7.72414 18.3172 7.72414H14.7862C14.5434 7.72414 14.3448 7.52552 14.3448 7.28276V3.75172C14.3448 3.50897 14.5434 3.31034 14.7862 3.31034H18.3172C18.56 3.31034 18.7586 3.50897 18.7586 3.75172V5.51724Z\" fill=\"white\"/>\r\n </svg>\r\n <div class=\"header-home__actions\">\r\n <ds-avatar\r\n [size]=\"'md'\"\r\n [type]=\"avatarType()\"\r\n [initials]=\"avatarInitials()\"\r\n [src]=\"avatarSrc()\"\r\n [iconName]=\"avatarIconName()\"\r\n (click)=\"handleAvatarClick()\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n @case ('back') {\r\n <div class=\"header-back\">\r\n @if (showBackButton()) {\r\n <button class=\"back-button\" (click)=\"handleBackClick()\">\r\n <ds-icon name=\"remixArrowLeftSLine\" size=\"24px\" />\r\n </button>\r\n }\r\n <h1 class=\"header-title\">{{ pageTitle() }}</h1>\r\n </div>\r\n }\r\n @case ('simple') {\r\n <div class=\"header-simple\">\r\n <h1 class=\"header-title\">{{ pageTitle() }}</h1>\r\n </div>\r\n }\r\n }\r\n </ion-toolbar>\r\n </ion-header>\r\n }\r\n\r\n <ion-content [scrollEvents]=\"true\" (ionScroll)=\"handleScroll($event)\">\r\n @if (showPullToRefresh() && isNativePlatform()) {\r\n <ion-refresher\r\n slot=\"fixed\"\r\n (ionRefresh)=\"handleRefresh($event)\"\r\n [pullFactor]=\"0.4\"\r\n [pullMin]=\"80\"\r\n [pullMax]=\"240\"\r\n closeDuration=\"600ms\">\r\n <ion-refresher-content\r\n pullingIcon=\"chevron-down-circle-outline\"\r\n refreshingSpinner=\"lines\">\r\n </ion-refresher-content>\r\n </ion-refresher>\r\n }\r\n\r\n <ng-content></ng-content>\r\n </ion-content>\r\n }\r\n `\r\n})\r\nexport class DsMobileAppLayoutComponent implements AfterViewInit {\r\n @ViewChild(IonContent, { static: false }) ionContent!: IonContent;\r\n\r\n // Platform detection\r\n private platform = inject(Platform);\r\n \r\n // Computed property to check if running on native platform\r\n isNativePlatform = computed(() => \r\n this.platform.is('ios') || \r\n this.platform.is('android') || \r\n this.platform.is('capacitor')\r\n );\r\n\r\n // Inputs\r\n headerVariant = input<HeaderVariant>('simple');\r\n pageTitle = input<string>('');\r\n showBackButton = input<boolean>(false);\r\n showPullToRefresh = input<boolean>(false);\r\n showTabBar = input<boolean>(false);\r\n tabs = input<TabConfig[]>([]);\r\n \r\n // Avatar inputs (for home header)\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n avatarInitials = input<string>('U');\r\n avatarSrc = input<string>('');\r\n avatarIconName = input<string>('remixUser3Line');\r\n\r\n // Outputs\r\n backClick = output<void>();\r\n refresh = output<any>();\r\n avatarClick = output<void>();\r\n scroll = output<any>();\r\n\r\n // Internal state\r\n private scrollY = signal(0);\r\n activeTab = signal<string>('home');\r\n isDesktop = signal<boolean>(false);\r\n\r\n constructor(\r\n private router: Router,\r\n private elementRef: ElementRef,\r\n private breakpointObserver: BreakpointObserver\r\n ) {\r\n // Track active tab based on current route\r\n this.router.events.subscribe(() => {\r\n const url = this.router.url;\r\n const tab = this.tabs().find(t => url.includes(t.route));\r\n if (tab) {\r\n this.activeTab.set(tab.id);\r\n }\r\n });\r\n \r\n // Track breakpoint for tab bar positioning\r\n this.breakpointObserver.observe(['(min-width: 768px)'])\r\n .subscribe(result => {\r\n this.isDesktop.set(result.matches);\r\n });\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n if (this.ionContent) {\r\n this.ionContent.scrollEvents = true;\r\n this.ensureScrollable();\r\n }\r\n }\r\n\r\n handleScroll(event: any): void {\r\n const scrollTop = event.detail.scrollTop || 0;\r\n this.scrollY.set(scrollTop);\r\n this.scroll.emit(event);\r\n }\r\n\r\n async handleRefresh(event: any): Promise<void> {\r\n // Haptic feedback for pull-to-refresh\r\n try {\r\n await Haptics.impact({ style: ImpactStyle.Medium });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n navigator.vibrate(50);\r\n }\r\n }\r\n \r\n this.refresh.emit(event);\r\n // Note: Parent component should handle event.target.complete()\r\n // If no handler is provided, you can add a default timeout in the parent\r\n }\r\n\r\n handleBackClick(): void {\r\n this.backClick.emit();\r\n }\r\n\r\n handleAvatarClick(): void {\r\n this.avatarClick.emit();\r\n }\r\n\r\n navigateToTab(route: string): void {\r\n this.router.navigateByUrl(route, { replaceUrl: true });\r\n }\r\n\r\n private ensureScrollable(): void {\r\n if (this.ionContent) {\r\n this.ionContent.getScrollElement().then((scrollEl: HTMLElement) => {\r\n if (scrollEl) {\r\n scrollEl.style.overscrollBehaviorY = 'none';\r\n (scrollEl.style as any).webkitOverflowScrolling = 'touch';\r\n }\r\n });\r\n }\r\n }\r\n\r\n isTabActive(tabId: string): boolean {\r\n return this.activeTab() === tabId;\r\n }\r\n}\r\n\r\n","import { Component, Input, Output, EventEmitter, signal, OnInit, AfterViewInit, ElementRef } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { \r\n IonTabs, \r\n IonTab,\r\n IonTabBar, \r\n IonTabButton, \r\n IonLabel\r\n} from '@ionic/angular/standalone';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\n\r\nexport interface TabConfig {\r\n id: string;\r\n label: string;\r\n route: string;\r\n icon: string;\r\n iconActive: string;\r\n}\r\n\r\n/**\r\n * DsMobileTabsComponent\r\n * \r\n * Responsive tab navigation that adapts from mobile to desktop:\r\n * - Mobile (< 768px): Bottom tab bar with icons + labels\r\n * - Desktop (≥ 768px): Top navigation bar with logo, tabs, and avatar\r\n * \r\n * Wraps ion-tabs to maintain native routing functionality while\r\n * providing a responsive navigation experience with branding.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-tabs\r\n * [tabs]=\"tabsConfig\"\r\n * [avatarInitials]=\"'JD'\"\r\n * (avatarClick)=\"handleAvatarClick()\"\r\n * />\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-tabs',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonTabs,\r\n IonTab,\r\n IonTabBar,\r\n IonTabButton,\r\n IonLabel,\r\n DsIconComponent,\r\n DsAvatarComponent\r\n ],\r\n styleUrls: ['./ds-mobile-tabs.css'],\r\n template: `\r\n <ion-tabs>\r\n <ng-container *ngIf=\"tabs && tabs.length > 0\">\r\n <ion-tab *ngFor=\"let tab of tabs; trackBy: trackByTabId\" [tab]=\"tab.id\"></ion-tab>\r\n </ng-container>\r\n \r\n <ion-tab-bar \r\n [attr.slot]=\"isDesktop() ? 'top' : 'bottom'\" \r\n class=\"ds-tab-bar\"\r\n [class.ds-tab-bar--desktop]=\"isDesktop()\">\r\n \r\n <!-- Logo (desktop only, positioned via CSS) -->\r\n <div class=\"ds-tab-bar__logo\">\r\n <svg class=\"logomark\" width=\"32\" height=\"28\" viewBox=\"0 0 36 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M33.9862 5.51709H23.1724V8.82743H26.0413C26.2841 8.82743 26.4827 9.02606 26.4827 9.26881V12.7998C26.4827 13.0426 26.2841 13.2412 26.0413 13.2412H23.1724V14.3447H26.0413C26.2841 14.3447 26.4827 14.5433 26.4827 14.7861V18.3171C26.4827 18.5598 26.2841 18.7585 26.0413 18.7585H23.1724V19.8619H26.0413C26.2841 19.8619 26.4827 20.0605 26.4827 20.3033V23.8343C26.4827 24.0771 26.2841 24.2757 26.0413 24.2757H23.1724V26.2619C23.1724 26.7496 23.0267 27.2043 22.7773 27.5861H27.5862L32 31.9999V27.5861H33.9862C34.7167 27.5861 35.3103 26.9924 35.3103 26.2619V6.84123C35.3103 6.11075 34.7167 5.51709 33.9862 5.51709ZM32 23.8343C32 24.0771 31.8013 24.2757 31.5586 24.2757H28.0276C27.7848 24.2757 27.5862 24.0771 27.5862 23.8343V20.3033C27.5862 20.0605 27.7848 19.8619 28.0276 19.8619H31.5586C31.8013 19.8619 32 20.0605 32 20.3033V23.8343ZM32 18.3171C32 18.5598 31.8013 18.7585 31.5586 18.7585H28.0276C27.7848 18.7585 27.5862 18.5598 27.5862 18.3171V14.7861C27.5862 14.5433 27.7848 14.3447 28.0276 14.3447H31.5586C31.8013 14.3447 32 14.5433 32 14.7861V18.3171ZM32 12.7998C32 13.0426 31.8013 13.2412 31.5586 13.2412H28.0276C27.7848 13.2412 27.5862 13.0426 27.5862 12.7998V9.26881C27.5862 9.02606 27.7848 8.82743 28.0276 8.82743H31.5586C31.8013 8.82743 32 9.02606 32 9.26881V12.7998Z\" fill=\"white\"/>\r\n <path d=\"M20.7448 0H1.32414C0.593655 0 0 0.593655 0 1.32414V26.2621C0 26.9926 0.593655 27.5862 1.32414 27.5862H3.31034V32L7.72414 27.5862H20.7448C21.4753 27.5862 22.069 26.9926 22.069 26.2621V1.32414C22.069 0.593655 21.4753 0 20.7448 0ZM7.72414 23.8345C7.72414 24.0772 7.52552 24.2759 7.28276 24.2759H3.75172C3.50897 24.2759 3.31034 24.0772 3.31034 23.8345V20.3034C3.31034 20.0607 3.50897 19.8621 3.75172 19.8621H7.28276C7.52552 19.8621 7.72414 20.0607 7.72414 20.3034V23.8345ZM7.72414 18.3172C7.72414 18.56 7.52552 18.7586 7.28276 18.7586H3.75172C3.50897 18.7586 3.31034 18.56 3.31034 18.3172V14.7862C3.31034 14.5434 3.50897 14.3448 3.75172 14.3448H7.28276C7.52552 14.3448 7.72414 14.5434 7.72414 14.7862V18.3172ZM7.72414 12.8C7.72414 13.0428 7.52552 13.2414 7.28276 13.2414H3.75172C3.50897 13.2414 3.31034 13.0428 3.31034 12.8V9.26897C3.31034 9.02621 3.50897 8.82759 3.75172 8.82759H7.28276C7.52552 8.82759 7.72414 9.02621 7.72414 9.26897V12.8ZM7.72414 7.28276C7.72414 7.52552 7.52552 7.72414 7.28276 7.72414H3.75172C3.50897 7.72414 3.31034 7.52552 3.31034 7.28276V3.75172C3.31034 3.50897 3.50897 3.31034 3.75172 3.31034H7.28276C7.52552 3.31034 7.72414 3.50897 7.72414 3.75172V7.28276ZM13.2414 23.8345C13.2414 24.0772 13.0428 24.2759 12.8 24.2759H9.26897C9.02621 24.2759 8.82759 24.0772 8.82759 23.8345V20.3034C8.82759 20.0607 9.02621 19.8621 9.26897 19.8621H12.8C13.0428 19.8621 13.2414 20.0607 13.2414 20.3034V23.8345ZM13.2414 18.3172C13.2414 18.56 13.0428 18.7586 12.8 18.7586H9.26897C9.02621 18.7586 8.82759 18.56 8.82759 18.3172V14.7862C8.82759 14.5434 9.02621 14.3448 9.26897 14.3448H12.8C13.0428 14.3448 13.2414 14.5434 13.2414 14.7862V18.3172ZM13.2414 12.8C13.2414 13.0428 13.0428 13.2414 12.8 13.2414H9.26897C9.02621 13.2414 8.82759 13.0428 8.82759 12.8V9.26897C8.82759 9.02621 9.02621 8.82759 9.26897 8.82759H12.8C13.0428 8.82759 13.2414 9.02621 13.2414 9.26897V12.8ZM13.2414 6.84138V7.28276C13.2414 7.52552 13.0428 7.72414 12.8 7.72414H9.26897C9.02621 7.72414 8.82759 7.52552 8.82759 7.28276V3.75172C8.82759 3.50897 9.02621 3.31034 9.26897 3.31034H12.8C13.0428 3.31034 13.2414 3.50897 13.2414 3.75172V6.84138ZM18.7586 23.8345C18.7586 24.0772 18.56 24.2759 18.3172 24.2759H14.7862C14.5434 24.2759 14.3448 24.0772 14.3448 23.8345V20.3034C14.3448 20.0607 14.5434 19.8621 14.7862 19.8621H18.3172C18.56 19.8621 18.7586 20.0607 18.7586 20.3034V23.8345ZM18.7586 18.3172C18.7586 18.56 18.56 18.7586 18.3172 18.7586H14.7862C14.5434 18.7586 14.3448 18.56 14.3448 18.3172V14.7862C14.3448 14.5434 14.5434 14.3448 14.7862 14.3448H18.3172C18.56 14.3448 18.7586 14.5434 18.7586 14.7862V18.3172ZM18.7586 12.8C18.7586 13.0428 18.56 13.2414 18.3172 13.2414H14.7862C14.5434 13.2414 14.3448 13.0428 14.3448 12.8V9.26897C14.3448 9.02621 14.5434 8.82759 14.7862 8.82759H18.3172C18.56 8.82759 18.7586 9.02621 18.7586 9.26897V12.8ZM18.7586 5.51724V7.28276C18.7586 7.52552 18.56 7.72414 18.3172 7.72414H14.7862C14.5434 7.72414 14.3448 7.52552 14.3448 7.28276V3.75172C14.3448 3.50897 14.5434 3.31034 14.7862 3.31034H18.3172C18.56 3.31034 18.7586 3.50897 18.7586 3.75172V5.51724Z\" fill=\"white\"/>\r\n </svg>\r\n </div>\r\n \r\n <!-- Tab buttons container -->\r\n <div class=\"ds-tab-bar__tabs\" *ngIf=\"tabs\">\r\n <ion-tab-button \r\n *ngFor=\"let tab of tabs; trackBy: trackByTabId\"\r\n [tab]=\"tab.id\"\r\n [attr.data-icon]=\"tab.icon\"\r\n [attr.data-icon-active]=\"tab.iconActive\"\r\n [attr.aria-label]=\"tab.label\"\r\n class=\"ds-tab-button ion-activatable\"\r\n [class.tab-selected]=\"isTabActive(tab.id)\">\r\n <div class=\"tab-icon-ripple\"></div>\r\n <div class=\"tab-icon-wrapper\">\r\n <ds-icon \r\n [name]=\"tab.icon\"\r\n [size]=\"isDesktop() ? '20px' : '24px'\"\r\n class=\"tab-icon-inactive\"\r\n />\r\n <ds-icon \r\n [name]=\"tab.iconActive\"\r\n [size]=\"isDesktop() ? '20px' : '24px'\"\r\n class=\"tab-icon-active\"\r\n />\r\n </div>\r\n <ion-label [attr.aria-hidden]=\"true\">{{ tab.label }}</ion-label>\r\n </ion-tab-button>\r\n </div>\r\n \r\n <!-- Avatar (desktop only, positioned via CSS) -->\r\n <div class=\"ds-tab-bar__actions\">\r\n <ds-avatar\r\n [size]=\"'md'\"\r\n [type]=\"avatarType\"\r\n [initials]=\"avatarInitials\"\r\n [src]=\"avatarSrc\"\r\n [iconName]=\"avatarIconName\"\r\n (click)=\"handleAvatarClick()\"\r\n />\r\n </div>\r\n </ion-tab-bar>\r\n </ion-tabs>\r\n `\r\n})\r\nexport class DsMobileTabsComponent implements OnInit, AfterViewInit {\r\n // Inputs\r\n @Input() tabs: TabConfig[] = [];\r\n \r\n // Avatar inputs\r\n @Input() avatarType: 'initials' | 'photo' | 'icon' = 'initials';\r\n @Input() avatarInitials: string = 'U';\r\n @Input() avatarSrc: string = '';\r\n @Input() avatarIconName: string = 'remixUser3Line';\r\n \r\n // Outputs\r\n @Output() avatarClick = new EventEmitter<void>();\r\n \r\n // Internal state\r\n activeTab = signal<string>('');\r\n isDesktop = signal<boolean>(false);\r\n \r\n private mutationObserver?: MutationObserver;\r\n \r\n constructor(private elementRef: ElementRef) {}\r\n \r\n ngOnInit(): void {\r\n console.log('DsMobileTabsComponent initialized');\r\n }\r\n \r\n ngAfterViewInit(): void {\r\n // Initial removal\r\n this.removeTitleAttributes();\r\n \r\n // Set up mutation observer to continuously remove title attributes\r\n this.setupTitleRemovalObserver();\r\n }\r\n \r\n ngOnDestroy(): void {\r\n if (this.mutationObserver) {\r\n this.mutationObserver.disconnect();\r\n }\r\n }\r\n \r\n private setupTitleRemovalObserver(): void {\r\n const config = { \r\n attributes: true, \r\n attributeFilter: ['title'],\r\n subtree: true,\r\n childList: true\r\n };\r\n \r\n this.mutationObserver = new MutationObserver((mutations) => {\r\n mutations.forEach((mutation) => {\r\n if (mutation.type === 'attributes' && mutation.attributeName === 'title') {\r\n const target = mutation.target as HTMLElement;\r\n if (target.tagName === 'ION-TAB-BUTTON' && target.hasAttribute('title')) {\r\n target.removeAttribute('title');\r\n }\r\n }\r\n });\r\n // Also do a sweep after any changes\r\n this.removeTitleAttributes();\r\n });\r\n \r\n this.mutationObserver.observe(this.elementRef.nativeElement, config);\r\n }\r\n \r\n private removeTitleAttributes(): void {\r\n const tabButtons = this.elementRef.nativeElement.querySelectorAll('ion-tab-button');\r\n tabButtons.forEach((button: HTMLElement) => {\r\n if (button.hasAttribute('title')) {\r\n button.removeAttribute('title');\r\n }\r\n // Also remove from the native button inside shadow DOM\r\n const nativeButton = button.shadowRoot?.querySelector('button');\r\n if (nativeButton?.hasAttribute('title')) {\r\n nativeButton.removeAttribute('title');\r\n }\r\n });\r\n }\r\n \r\n trackByTabId(index: number, tab: TabConfig): string {\r\n return tab.id;\r\n }\r\n \r\n isTabActive(tabId: string): boolean {\r\n return this.activeTab() === tabId;\r\n }\r\n \r\n handleAvatarClick(): void {\r\n this.avatarClick.emit();\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport type { LightboxAuthor } from './ds-mobile-lightbox.service';\r\n\r\n/**\r\n * DsMobileLightboxHeaderComponent\r\n * \r\n * Shared header component for all lightbox types (image, PDF, etc.)\r\n * Displays author information and close button with consistent styling.\r\n */\r\n@Component({\r\n selector: 'ds-mobile-lightbox-header',\r\n standalone: true,\r\n imports: [CommonModule, DsIconButtonComponent, DsAvatarComponent],\r\n styleUrls: ['../shared/mobile-common.css'],\r\n template: `\r\n @if (author()) {\r\n <div class=\"lightbox-header lightbox-context\">\r\n <div class=\"header-content\">\r\n <!-- Post author info -->\r\n <div class=\"post-author-info\">\r\n <ds-avatar\r\n [initials]=\"author()!.avatarInitials ?? ''\"\r\n [type]=\"author()!.avatarType ?? 'initials'\"\r\n [src]=\"author()!.avatarSrc ?? ''\"\r\n size=\"md\"\r\n />\r\n <div class=\"author-details\">\r\n <div class=\"author-name\">{{ author()!.name }}</div>\r\n <div class=\"author-meta\">\r\n @if (author()!.role) {\r\n <span>{{ author()!.role }}</span>\r\n }\r\n @if (author()!.role && author()!.timestamp) {\r\n <span class=\"separator\">·</span>\r\n }\r\n @if (author()!.timestamp) {\r\n <span>{{ author()!.timestamp }}</span>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Close button -->\r\n <ds-icon-button\r\n icon=\"remixCloseLine\"\r\n variant=\"ghost\"\r\n size=\"md\"\r\n (click)=\"closeClick.emit()\"\r\n class=\"close-button\"\r\n [ariaLabel]=\"'Close'\">\r\n </ds-icon-button>\r\n </div>\r\n </div>\r\n }\r\n `,\r\n styles: [`\r\n .lightbox-header {\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n right: 0;\r\n z-index: 1000;\r\n padding: 0 16px;\r\n background: linear-gradient(to bottom, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.4) 80%, transparent 100%);\r\n pointer-events: none;\r\n }\r\n\r\n .header-content {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 12px;\r\n pointer-events: auto;\r\n }\r\n\r\n .post-author-info {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n\r\n .author-details {\r\n display: flex;\r\n flex-direction: column;\r\n min-width: 0;\r\n flex: 1;\r\n }\r\n\r\n .author-name {\r\n color: white;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n }\r\n\r\n .author-meta {\r\n color: rgba(255, 255, 255, 0.7);\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n }\r\n\r\n .author-meta .separator {\r\n color: rgba(255, 255, 255, 0.5);\r\n }\r\n\r\n .close-button {\r\n pointer-events: auto;\r\n flex-shrink: 0;\r\n border-radius: 50%;\r\n }\r\n\r\n .close-button::ng-deep button {\r\n color: white !important;\r\n background: rgba(255, 255, 255, 0.1) !important;\r\n border-radius: 50%;\r\n transition: background 0.2s ease;\r\n border: none;\r\n width: 36px !important;\r\n height: 36px !important;\r\n min-width: 36px !important;\r\n min-height: 36px !important;\r\n padding: 0 !important;\r\n display: flex !important;\r\n align-items: center !important;\r\n justify-content: center !important;\r\n }\r\n\r\n .close-button::ng-deep button:hover {\r\n background: rgba(255, 255, 255, 0.15) !important;\r\n }\r\n\r\n .close-button::ng-deep button:active {\r\n background: rgba(255, 255, 255, 0.15) !important;\r\n }\r\n\r\n .close-button::ng-deep svg {\r\n color: white !important;\r\n fill: white !important;\r\n }\r\n\r\n /* Safe area support for notched devices */\r\n @supports (padding-top: env(safe-area-inset-top)) {\r\n .lightbox-header {\r\n padding-top: calc(16px + env(safe-area-inset-top));\r\n }\r\n }\r\n `]\r\n})\r\nexport class DsMobileLightboxHeaderComponent {\r\n /**\r\n * Author information to display\r\n */\r\n author = input<LightboxAuthor>();\r\n\r\n /**\r\n * Emitted when close button is clicked\r\n */\r\n closeClick = output<void>();\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobileLightboxFooterComponent\r\n * \r\n * Shared footer component for all lightbox types (image, PDF, etc.)\r\n * Displays navigation controls (for multiple images) and action buttons.\r\n */\r\n@Component({\r\n selector: 'ds-mobile-lightbox-footer',\r\n standalone: true,\r\n imports: [CommonModule, DsIconButtonComponent],\r\n template: `\r\n <div class=\"lightbox-footer\">\r\n <!-- Navigation controls (only shown for multiple images) -->\r\n @if (showNavigation() && totalImages() > 1) {\r\n <div class=\"footer-navigation\">\r\n <button \r\n class=\"nav-button prev\"\r\n (click)=\"prevClick.emit()\"\r\n [disabled]=\"currentIndex() === 0\"\r\n aria-label=\"Previous image\">\r\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path d=\"M15 18L9 12L15 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg>\r\n </button>\r\n \r\n <div class=\"counter\">\r\n {{ currentIndex() + 1 }} / {{ totalImages() }}\r\n </div>\r\n \r\n <button \r\n class=\"nav-button next\"\r\n (click)=\"nextClick.emit()\"\r\n [disabled]=\"currentIndex() === totalImages() - 1\"\r\n aria-label=\"Next image\">\r\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path d=\"M9 18L15 12L9 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n }\r\n \r\n <!-- Action buttons -->\r\n <div class=\"footer-actions\">\r\n <div class=\"action-buttons-left\">\r\n <!-- Like button -->\r\n <ds-icon-button\r\n [icon]=\"isLiked() ? 'remixHeart3Fill' : 'remixHeart3Line'\"\r\n variant=\"ghost\"\r\n size=\"md\"\r\n (click)=\"likeClick.emit()\"\r\n [attr.data-liked]=\"isLiked()\"\r\n class=\"action-button-like\"\r\n [ariaLabel]=\"'Like'\">\r\n </ds-icon-button>\r\n \r\n <!-- Comment button -->\r\n <ds-icon-button\r\n icon=\"remixChat3Line\"\r\n variant=\"ghost\"\r\n size=\"md\"\r\n (click)=\"commentClick.emit()\"\r\n class=\"action-button-comment\"\r\n [ariaLabel]=\"'Comment'\">\r\n </ds-icon-button>\r\n </div>\r\n \r\n <ds-icon-button\r\n icon=\"remixShare2Line\"\r\n variant=\"ghost\"\r\n size=\"md\"\r\n (click)=\"shareClick.emit()\"\r\n class=\"action-button-share\"\r\n [ariaLabel]=\"'Share'\">\r\n </ds-icon-button>\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n .lightbox-footer {\r\n position: fixed;\r\n bottom: 0;\r\n left: 0;\r\n right: 0;\r\n z-index: 100;\r\n padding: 16px 20px 20px 20px;\r\n background: linear-gradient(to top, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.6) 50%, rgba(0, 0, 0, 0.4) 75%, transparent 100%);\r\n pointer-events: none;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n }\r\n\r\n /* Navigation controls */\r\n .footer-navigation {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 24px;\r\n pointer-events: auto;\r\n }\r\n\r\n .nav-button {\r\n background: rgba(255, 255, 255, 0.1);\r\n border: 1px solid rgba(255, 255, 255, 0.2);\r\n border-radius: 50%;\r\n color: white;\r\n width: 40px;\r\n height: 40px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n backdrop-filter: blur(10px);\r\n -webkit-backdrop-filter: blur(10px);\r\n padding: 0;\r\n }\r\n\r\n .nav-button:hover:not(:disabled) {\r\n background: rgba(255, 255, 255, 0.2);\r\n transform: scale(1.05);\r\n }\r\n\r\n .nav-button:active:not(:disabled) {\r\n transform: scale(0.95);\r\n }\r\n\r\n .nav-button:disabled {\r\n opacity: 0.3;\r\n cursor: not-allowed;\r\n }\r\n\r\n .nav-button svg {\r\n width: 24px;\r\n height: 24px;\r\n flex-shrink: 0;\r\n }\r\n\r\n .counter {\r\n background: rgba(255, 255, 255, 0.1);\r\n border: 1px solid rgba(255, 255, 255, 0.2);\r\n backdrop-filter: blur(10px);\r\n -webkit-backdrop-filter: blur(10px);\r\n border-radius: 100px;\r\n padding: 8px 16px;\r\n color: white;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 500;\r\n line-height: 1;\r\n letter-spacing: -0.3px;\r\n pointer-events: auto;\r\n user-select: none;\r\n }\r\n\r\n .footer-actions {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 16px;\r\n pointer-events: auto;\r\n }\r\n\r\n .action-buttons-left {\r\n display: flex;\r\n align-items: center;\r\n gap: 16px;\r\n }\r\n\r\n /* Style the action buttons to match the ghost/transparent look */\r\n .action-button-like::ng-deep button,\r\n .action-button-comment::ng-deep button,\r\n .action-button-share::ng-deep button {\r\n background: rgba(255, 255, 255, 0.1) !important;\r\n border: 1px solid rgba(255, 255, 255, 0.2) !important;\r\n color: white !important;\r\n backdrop-filter: blur(10px);\r\n -webkit-backdrop-filter: blur(10px);\r\n transition: all 0.2s ease;\r\n }\r\n\r\n .action-button-like::ng-deep button:hover,\r\n .action-button-comment::ng-deep button:hover,\r\n .action-button-share::ng-deep button:hover {\r\n background: rgba(255, 255, 255, 0.2) !important;\r\n transform: scale(1.02);\r\n }\r\n\r\n .action-button-like::ng-deep button:active,\r\n .action-button-comment::ng-deep button:active,\r\n .action-button-share::ng-deep button:active {\r\n transform: scale(0.98);\r\n }\r\n\r\n /* Icon and label colors */\r\n .action-button-like::ng-deep button svg,\r\n .action-button-comment::ng-deep button svg,\r\n .action-button-share::ng-deep button svg,\r\n .action-button-like::ng-deep button .btn__icon,\r\n .action-button-comment::ng-deep button .btn__icon,\r\n .action-button-share::ng-deep button .btn__icon,\r\n .action-button-like::ng-deep button .btn__content,\r\n .action-button-comment::ng-deep button .btn__content {\r\n color: white !important;\r\n fill: white !important;\r\n }\r\n\r\n /* Make sure icons are visible */\r\n .action-button-like::ng-deep button .btn__icon svg,\r\n .action-button-comment::ng-deep button .btn__icon svg,\r\n .action-button-share::ng-deep button .btn__icon svg {\r\n color: white !important;\r\n fill: white !important;\r\n display: block !important;\r\n opacity: 1 !important;\r\n visibility: visible !important;\r\n width: 20px !important;\r\n height: 20px !important;\r\n }\r\n\r\n /* Ensure icon wrapper is visible */\r\n .action-button-like::ng-deep button .btn__icon,\r\n .action-button-comment::ng-deep button .btn__icon,\r\n .action-button-share::ng-deep button .btn__icon {\r\n display: flex !important;\r\n align-items: center !important;\r\n justify-content: center !important;\r\n flex-shrink: 0 !important;\r\n }\r\n\r\n /* Like button active state (pink heart) */\r\n .action-button-like[data-liked=\"true\"]::ng-deep button svg {\r\n fill: #f91880 !important;\r\n color: #f91880 !important;\r\n }\r\n\r\n .action-button-like[data-liked=\"true\"]::ng-deep button {\r\n border-color: rgba(249, 24, 128, 0.3) !important;\r\n }\r\n\r\n /* All action buttons should have same circular styling */\r\n .action-button-like,\r\n .action-button-comment,\r\n .action-button-share {\r\n flex-shrink: 0;\r\n border-radius: 50%;\r\n }\r\n\r\n .action-button-like::ng-deep button,\r\n .action-button-comment::ng-deep button,\r\n .action-button-share::ng-deep button {\r\n border-radius: 50% !important;\r\n width: 44px !important;\r\n height: 44px !important;\r\n min-width: 44px !important;\r\n min-height: 44px !important;\r\n padding: 0 !important;\r\n display: flex !important;\r\n align-items: center !important;\r\n justify-content: center !important;\r\n }\r\n\r\n /* Safe area support for footer */\r\n @supports (padding-bottom: env(safe-area-inset-bottom)) {\r\n .lightbox-footer {\r\n padding-bottom: calc(20px + env(safe-area-inset-bottom));\r\n }\r\n }\r\n `]\r\n})\r\nexport class DsMobileLightboxFooterComponent {\r\n /**\r\n * Whether to show navigation controls\r\n */\r\n showNavigation = input<boolean>(false);\r\n\r\n /**\r\n * Current image index (0-based)\r\n */\r\n currentIndex = input<number>(0);\r\n\r\n /**\r\n * Total number of images\r\n */\r\n totalImages = input<number>(1);\r\n\r\n /**\r\n * Whether the content is liked\r\n */\r\n isLiked = input<boolean>(false);\r\n\r\n /**\r\n * Number of likes\r\n */\r\n likeCount = input<number>(0);\r\n\r\n /**\r\n * Number of comments\r\n */\r\n commentCount = input<number>(0);\r\n\r\n /**\r\n * Emitted when previous button is clicked\r\n */\r\n prevClick = output<void>();\r\n\r\n /**\r\n * Emitted when next button is clicked\r\n */\r\n nextClick = output<void>();\r\n\r\n /**\r\n * Emitted when like button is clicked\r\n */\r\n likeClick = output<void>();\r\n\r\n /**\r\n * Emitted when comment button is clicked\r\n */\r\n commentClick = output<void>();\r\n\r\n /**\r\n * Emitted when share button is clicked\r\n */\r\n shareClick = output<void>();\r\n}\r\n\r\n","import {\r\n Component,\r\n signal,\r\n computed,\r\n ViewChild,\r\n ElementRef,\r\n AfterViewInit,\r\n OnDestroy,\r\n OnInit,\r\n CUSTOM_ELEMENTS_SCHEMA,\r\n HostListener\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport {\r\n IonSpinner,\r\n GestureController,\r\n Gesture\r\n} from '@ionic/angular/standalone';\r\nimport { Share } from '@capacitor/share';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsMobileLightboxHeaderComponent } from './ds-mobile-lightbox-header';\r\nimport { DsMobileLightboxFooterComponent } from './ds-mobile-lightbox-footer';\r\nimport type { LightboxImage, LightboxAuthor } from './ds-mobile-lightbox.service';\r\nimport Swiper from 'swiper';\r\nimport type { SwiperOptions } from 'swiper/types';\r\n\r\n/**\r\n * DsMobileLightboxImageComponent\r\n * \r\n * Full-screen image lightbox component with Swiper.js navigation and pinch-zoom.\r\n * \r\n * This component is typically not used directly - use DsMobileLightboxService instead.\r\n * \r\n * Features:\r\n * - Swiper.js for smooth image navigation\r\n * - Pinch to zoom in/out\r\n * - Double-tap to toggle zoom\r\n * - Swipe down to close (when not zoomed)\r\n * - Image counter and navigation controls\r\n * \r\n * @example\r\n * ```typescript\r\n * // Don't instantiate directly - use the service:\r\n * constructor(private lightbox: DsMobileLightboxService) {}\r\n * \r\n * openImage() {\r\n * this.lightbox.openImages({\r\n * images: [{ type: 'image', src: 'image.jpg', title: 'My Image' }]\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-lightbox-image',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonSpinner,\r\n DsIconButtonComponent,\r\n DsAvatarComponent,\r\n DsMobileLightboxHeaderComponent,\r\n DsMobileLightboxFooterComponent\r\n ],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n template: `\r\n <div class=\"lightbox-overlay\" \r\n [class.zoomed]=\"isZoomed()\">\r\n \r\n <div class=\"lightbox-wrapper\">\r\n <!-- Header with author info and close button -->\r\n <ds-mobile-lightbox-header \r\n [author]=\"author\"\r\n (closeClick)=\"close()\"\r\n />\r\n\r\n <!-- Swiper container -->\r\n <div class=\"swiper-container\" #swiperContainer>\r\n <div class=\"swiper-wrapper\">\r\n @for (image of images; track image.src; let i = $index) {\r\n <div class=\"swiper-slide\">\r\n <div class=\"image-zoom-container\" [attr.data-index]=\"i\">\r\n <img \r\n [src]=\"image.src\"\r\n [alt]=\"image.alt || 'Lightbox image'\"\r\n class=\"lightbox-image\"\r\n (load)=\"onImageLoad(i)\"\r\n (error)=\"onImageError(i)\">\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n \r\n <!-- Loading indicator -->\r\n @if (isLoading()) {\r\n <div class=\"loading-spinner\">\r\n <ion-spinner name=\"crescent\"></ion-spinner>\r\n </div>\r\n }\r\n\r\n <!-- Footer with navigation and actions -->\r\n <ds-mobile-lightbox-footer\r\n [showNavigation]=\"showControls && images.length > 1\"\r\n [currentIndex]=\"currentIndex()\"\r\n [totalImages]=\"images.length\"\r\n [isLiked]=\"isLiked()\"\r\n [likeCount]=\"likeCount()\"\r\n [commentCount]=\"commentCount()\"\r\n (prevClick)=\"previousImage()\"\r\n (nextClick)=\"nextImage()\"\r\n (likeClick)=\"onLikeToggle()\"\r\n (commentClick)=\"onReply()\"\r\n (shareClick)=\"onShare()\"\r\n />\r\n </div>\r\n </div>\r\n `,\r\n styleUrl: './ds-mobile-lightbox.css'\r\n})\r\nexport class DsMobileLightboxImageComponent implements OnInit, AfterViewInit, OnDestroy {\r\n // Inputs (passed from service as regular properties, not signals)\r\n images!: LightboxImage[];\r\n author?: LightboxAuthor;\r\n initialIndex: number = 0;\r\n enableZoom: boolean = true;\r\n showControls: boolean = true;\r\n enableSwipe: boolean = true;\r\n showInfo: boolean = true;\r\n animation: 'fade' | 'zoom' | 'slide' = 'fade';\r\n onCloseRequested?: () => void;\r\n\r\n // View children\r\n @ViewChild('swiperContainer', { read: ElementRef }) swiperContainer!: ElementRef<HTMLDivElement>;\r\n\r\n // State\r\n currentIndex = signal(0);\r\n scale = signal(1);\r\n isZoomed = signal(false);\r\n isLoading = signal(true);\r\n hasError = signal(false);\r\n \r\n // Action states\r\n isLiked = signal(false);\r\n likeCount = signal(0);\r\n commentCount = signal(0);\r\n\r\n // Computed\r\n currentImage = computed(() => this.images[this.currentIndex()]);\r\n\r\n // Swiper instance\r\n private swiper?: Swiper;\r\n private zoomData: Map<number, { scale: number; x: number; y: number }> = new Map();\r\n\r\n constructor(\r\n private gestureCtrl: GestureController\r\n ) {}\r\n\r\n ngOnInit(): void {\r\n // Set initial index from the passed property\r\n if (this.initialIndex !== undefined) {\r\n this.currentIndex.set(this.initialIndex);\r\n }\r\n \r\n // Initialize action states from current image\r\n const currentImg = this.images[this.currentIndex()];\r\n if (currentImg) {\r\n this.isLiked.set(currentImg.isLiked ?? false);\r\n this.likeCount.set(currentImg.likeCount ?? 0);\r\n this.commentCount.set(currentImg.commentCount ?? 0);\r\n }\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n setTimeout(() => {\r\n this.initializeSwiper();\r\n this.initializeZoomGestures();\r\n }, 100);\r\n }\r\n\r\n ngOnDestroy(): void {\r\n // Clean up Swiper\r\n if (this.swiper) {\r\n this.swiper.destroy();\r\n this.swiper = undefined;\r\n }\r\n }\r\n /**\r\n * Initialize Swiper for image navigation\r\n */\r\n private initializeSwiper(): void {\r\n if (!this.swiperContainer) {\r\n console.error('[Lightbox] Swiper container not found');\r\n return;\r\n }\r\n\r\n const swiperOptions: SwiperOptions = {\r\n initialSlide: this.initialIndex,\r\n speed: 300,\r\n resistance: true,\r\n resistanceRatio: 0.85,\r\n slidesPerView: 1,\r\n spaceBetween: 0,\r\n touchRatio: 1,\r\n longSwipesRatio: 0.5,\r\n threshold: 10,\r\n on: {\r\n slideChange: (swiper) => {\r\n this.currentIndex.set(swiper.activeIndex);\r\n this.updateActionStates();\r\n \r\n // Check if the image is already loaded\r\n const currentSlide = swiper.slides[swiper.activeIndex];\r\n const img = currentSlide?.querySelector('img');\r\n if (img && img.complete && img.naturalHeight !== 0) {\r\n // Image is already loaded\r\n this.isLoading.set(false);\r\n }\r\n },\r\n slideChangeTransitionStart: () => {\r\n // Don't show loading spinner if image is already loaded\r\n const currentSlide = this.swiper?.slides[this.swiper.activeIndex];\r\n const img = currentSlide?.querySelector('img');\r\n if (!img || !img.complete || img.naturalHeight === 0) {\r\n this.isLoading.set(true);\r\n }\r\n }\r\n }\r\n };\r\n\r\n this.swiper = new Swiper(this.swiperContainer.nativeElement, swiperOptions);\r\n \r\n // Check if the initial image is already loaded\r\n setTimeout(() => {\r\n const currentSlide = this.swiper?.slides[this.currentIndex()];\r\n const img = currentSlide?.querySelector('img');\r\n if (img && img.complete && img.naturalHeight !== 0) {\r\n this.isLoading.set(false);\r\n }\r\n }, 0);\r\n }\r\n\r\n /**\r\n * Initialize pinch-zoom gestures for all slides\r\n */\r\n private initializeZoomGestures(): void {\r\n if (!this.enableZoom) return;\r\n\r\n const slides = this.swiperContainer.nativeElement.querySelectorAll('.image-zoom-container');\r\n \r\n slides.forEach((slide, index) => {\r\n this.initializeZoomForSlide(slide as HTMLElement, index);\r\n });\r\n }\r\n\r\n /**\r\n * Initialize zoom gestures for a specific slide\r\n */\r\n private initializeZoomForSlide(container: HTMLElement, index: number): void {\r\n let initialDistance = 0;\r\n let initialScale = 1;\r\n let currentScale = 1;\r\n let lastTap = 0;\r\n\r\n // Double-tap to zoom\r\n container.addEventListener('click', (event: MouseEvent) => {\r\n const now = Date.now();\r\n const timeSinceLastTap = now - lastTap;\r\n\r\n if (timeSinceLastTap < 300 && timeSinceLastTap > 0) {\r\n event.preventDefault();\r\n this.toggleZoom(container, index);\r\n }\r\n\r\n lastTap = now;\r\n });\r\n\r\n // Pinch to zoom\r\n const getTouchDistance = (touches: TouchList) => {\r\n const dx = touches[0].clientX - touches[1].clientX;\r\n const dy = touches[0].clientY - touches[1].clientY;\r\n return Math.sqrt(dx * dx + dy * dy);\r\n };\r\n\r\n container.addEventListener('touchstart', (event: TouchEvent) => {\r\n if (event.touches.length === 2) {\r\n event.preventDefault();\r\n initialDistance = getTouchDistance(event.touches);\r\n const zoomData = this.zoomData.get(index) || { scale: 1, x: 0, y: 0 };\r\n initialScale = zoomData.scale;\r\n \r\n // Disable Swiper when zooming\r\n if (this.swiper) {\r\n this.swiper.allowTouchMove = false;\r\n }\r\n }\r\n }, { passive: false });\r\n\r\n container.addEventListener('touchmove', (event: TouchEvent) => {\r\n if (event.touches.length === 2) {\r\n event.preventDefault();\r\n \r\n const currentDistance = getTouchDistance(event.touches);\r\n const pinchScale = currentDistance / initialDistance;\r\n \r\n currentScale = Math.max(1, Math.min(initialScale * pinchScale, 4));\r\n \r\n const img = container.querySelector('img');\r\n if (img) {\r\n img.style.transform = `scale(${currentScale})`;\r\n }\r\n \r\n if (currentScale > 1) {\r\n this.isZoomed.set(true);\r\n } else {\r\n this.isZoomed.set(false);\r\n }\r\n }\r\n }, { passive: false });\r\n\r\n container.addEventListener('touchend', (event: TouchEvent) => {\r\n if (event.touches.length < 2) {\r\n // Save zoom state\r\n this.zoomData.set(index, { scale: currentScale, x: 0, y: 0 });\r\n \r\n // Re-enable Swiper if not zoomed\r\n if (this.swiper && currentScale <= 1) {\r\n this.swiper.allowTouchMove = true;\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Toggle zoom on double-tap\r\n */\r\n private toggleZoom(container: HTMLElement, index: number): void {\r\n const zoomData = this.zoomData.get(index) || { scale: 1, x: 0, y: 0 };\r\n const img = container.querySelector('img');\r\n \r\n if (!img) return;\r\n\r\n if (zoomData.scale > 1) {\r\n // Zoom out\r\n img.style.transform = 'scale(1)';\r\n this.zoomData.set(index, { scale: 1, x: 0, y: 0 });\r\n this.isZoomed.set(false);\r\n if (this.swiper) {\r\n this.swiper.allowTouchMove = true;\r\n }\r\n } else {\r\n // Zoom in\r\n img.style.transform = 'scale(2)';\r\n this.zoomData.set(index, { scale: 2, x: 0, y: 0 });\r\n this.isZoomed.set(true);\r\n if (this.swiper) {\r\n this.swiper.allowTouchMove = false;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Update action states (like, comments) when slide changes\r\n */\r\n private updateActionStates(): void {\r\n const currentImg = this.images[this.currentIndex()];\r\n if (currentImg) {\r\n this.isLiked.set(currentImg.isLiked ?? false);\r\n this.likeCount.set(currentImg.likeCount ?? 0);\r\n this.commentCount.set(currentImg.commentCount ?? 0);\r\n }\r\n }\r\n\r\n /**\r\n * Close the lightbox\r\n */\r\n close(): void {\r\n if (this.onCloseRequested) {\r\n this.onCloseRequested();\r\n }\r\n }\r\n\r\n /**\r\n * Handle share button click\r\n */\r\n async onShare(): Promise<void> {\r\n console.log('[Lightbox] Share button clicked');\r\n const currentImg = this.currentImage();\r\n \r\n try {\r\n await Share.share({\r\n title: currentImg.title || 'Shared Image',\r\n url: currentImg.src,\r\n dialogTitle: 'Share Image',\r\n });\r\n } catch (error) {\r\n console.error('[Lightbox] Share failed:', error);\r\n }\r\n }\r\n\r\n /**\r\n * Handle like button toggle\r\n */\r\n onLikeToggle(): void {\r\n console.log('[Lightbox] Like button toggled');\r\n this.isLiked.update(liked => !liked);\r\n \r\n if (this.isLiked()) {\r\n this.likeCount.update(count => count + 1);\r\n } else {\r\n this.likeCount.update(count => Math.max(0, count - 1));\r\n }\r\n }\r\n\r\n /**\r\n * Handle reply/comment button click\r\n */\r\n onReply(): void {\r\n console.log('[Lightbox] Reply button clicked');\r\n if (this.onCloseRequested) {\r\n this.onCloseRequested();\r\n }\r\n }\r\n\r\n /**\r\n * Navigate to the next image\r\n */\r\n nextImage(): void {\r\n if (this.swiper && this.currentIndex() < this.images.length - 1) {\r\n this.swiper.slideNext();\r\n }\r\n }\r\n\r\n /**\r\n * Navigate to the previous image\r\n */\r\n previousImage(): void {\r\n if (this.swiper && this.currentIndex() > 0) {\r\n this.swiper.slidePrev();\r\n }\r\n }\r\n\r\n /**\r\n * Handle image load success\r\n */\r\n onImageLoad(index: number): void {\r\n if (index === this.currentIndex()) {\r\n this.isLoading.set(false);\r\n }\r\n }\r\n\r\n /**\r\n * Handle image load error\r\n */\r\n onImageError(index: number): void {\r\n if (index === this.currentIndex()) {\r\n console.error(`[Lightbox] Image ${index} failed to load`);\r\n this.isLoading.set(false);\r\n this.hasError.set(true);\r\n }\r\n }\r\n}\r\n\r\n","import {\r\n Component,\r\n OnInit,\r\n CUSTOM_ELEMENTS_SCHEMA\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport {\r\n IonContent,\r\n IonSpinner\r\n} from '@ionic/angular/standalone';\r\nimport { Filesystem, Directory } from '@capacitor/filesystem';\r\nimport { Browser } from '@capacitor/browser';\r\nimport { Share } from '@capacitor/share';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsButtonComponent } from '@propbinder/design-system';\r\nimport { DsMobileLightboxHeaderComponent } from './ds-mobile-lightbox-header';\r\nimport { DsMobileLightboxFooterComponent } from './ds-mobile-lightbox-footer';\r\nimport type { LightboxPdf, LightboxAuthor } from './ds-mobile-lightbox.service';\r\n\r\n/**\r\n * DsMobileLightboxPdfComponent\r\n * \r\n * PDF viewer component that displays PDF info and allows users to open PDFs in the native device viewer.\r\n * Shows a lightbox with PDF details first, then user can choose to open in native viewer.\r\n * \r\n * This component is typically not used directly - use DsMobileLightboxService instead.\r\n * \r\n * Features:\r\n * - PDF info preview (title, size, icon)\r\n * - User-initiated native PDF viewing (iOS/Android)\r\n * - Download and cache support\r\n * - Share functionality\r\n * - Loading states\r\n * \r\n * @example\r\n * ```typescript\r\n * // Don't instantiate directly - use the service:\r\n * constructor(private lightbox: DsMobileLightboxService) {}\r\n * \r\n * openPdf() {\r\n * this.lightbox.openPdf({\r\n * pdf: { type: 'pdf', src: 'document.pdf', title: 'My Document' }\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-lightbox-pdf',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonContent,\r\n IonSpinner,\r\n DsAvatarComponent,\r\n DsButtonComponent,\r\n DsMobileLightboxHeaderComponent,\r\n DsMobileLightboxFooterComponent\r\n ],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n template: `\r\n <ion-content \r\n [fullscreen]=\"true\"\r\n class=\"lightbox-content pdf-viewer\">\r\n \r\n <div class=\"lightbox-wrapper\">\r\n <!-- Header with author info and close button -->\r\n <ds-mobile-lightbox-header \r\n [author]=\"author\"\r\n (closeClick)=\"close()\"\r\n />\r\n\r\n <!-- PDF Info & Actions -->\r\n <div class=\"pdf-container\">\r\n @if (isLoading) {\r\n <div class=\"loading-state\">\r\n <ion-spinner name=\"crescent\"></ion-spinner>\r\n <p>Loading PDF...</p>\r\n </div>\r\n } @else if (hasError) {\r\n <div class=\"error-state\">\r\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path d=\"M12 8V12M12 16H12.01M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg>\r\n <h3>Failed to Load PDF</h3>\r\n <p>{{ errorMessage }}</p>\r\n <button class=\"retry-button\" (click)=\"openPdfInNativeViewer()\">\r\n Try Again\r\n </button>\r\n </div>\r\n } @else {\r\n <div class=\"pdf-content\">\r\n <!-- PDF Icon -->\r\n <ds-avatar\r\n type=\"icon\"\r\n iconName=\"remixFileTextLine\"\r\n size=\"xl\"\r\n />\r\n \r\n <!-- PDF Title (same as attachment fileName) -->\r\n <h2 class=\"pdf-title\">{{ getDisplayTitle() }}</h2>\r\n \r\n <!-- PDF Metadata (same format as attachment: PDF · fileSize) -->\r\n <div class=\"pdf-meta\">\r\n PDF · {{ pdf.fileSize ? formatFileSize(pdf.fileSize) : '' }}\r\n </div>\r\n \r\n <!-- Open Button -->\r\n <ds-button\r\n variant=\"secondary\"\r\n size=\"lg\"\r\n (clicked)=\"openPdfInNativeViewer()\"\r\n class=\"open-pdf-button\">\r\n Open Preview\r\n </ds-button>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Bottom actions -->\r\n <ds-mobile-lightbox-footer\r\n [isLiked]=\"false\"\r\n [likeCount]=\"0\"\r\n [commentCount]=\"0\"\r\n (likeClick)=\"onLikeToggle()\"\r\n (commentClick)=\"onReply()\"\r\n (shareClick)=\"onShare()\"\r\n />\r\n </div>\r\n </ion-content>\r\n `,\r\n styleUrl: './ds-mobile-lightbox-pdf.css'\r\n})\r\nexport class DsMobileLightboxPdfComponent implements OnInit {\r\n // Inputs (passed from service as regular properties)\r\n pdf!: LightboxPdf;\r\n author?: LightboxAuthor;\r\n onCloseRequested?: () => void;\r\n\r\n // State\r\n isLoading = false;\r\n hasError = false;\r\n errorMessage = '';\r\n cachedFilePath?: string;\r\n\r\n constructor() {}\r\n\r\n ngOnInit(): void {\r\n console.log('[PDF Lightbox] Initializing with PDF:', this.pdf);\r\n \r\n // Don't automatically open - let user click the \"Open\" button\r\n // this.openPdfInNativeViewer();\r\n }\r\n\r\n /**\r\n * Open the PDF in the native device viewer\r\n */\r\n async openPdfInNativeViewer(): Promise<void> {\r\n if (!this.pdf?.src) {\r\n console.error('[PDF Lightbox] No PDF source provided');\r\n this.hasError = true;\r\n this.errorMessage = 'No PDF file provided';\r\n return;\r\n }\r\n\r\n this.isLoading = true;\r\n this.hasError = false;\r\n this.errorMessage = '';\r\n\r\n try {\r\n console.log('[PDF Lightbox] Opening PDF:', this.pdf.src);\r\n \r\n // Check if it's already a full URL\r\n let pdfUrl: string;\r\n \r\n if (this.pdf.src.startsWith('http://') || this.pdf.src.startsWith('https://')) {\r\n // Already a full URL\r\n pdfUrl = this.pdf.src;\r\n } else {\r\n // Relative path - construct full URL\r\n // Use current origin (which includes the dev server URL in Capacitor)\r\n // Remove leading slash if present to avoid double slashes\r\n const cleanPath = this.pdf.src.startsWith('/') ? this.pdf.src.slice(1) : this.pdf.src;\r\n pdfUrl = `${window.location.origin}/${cleanPath}`;\r\n }\r\n \r\n console.log('[PDF Lightbox] Opening PDF at URL:', pdfUrl);\r\n \r\n // Use Browser to open the PDF\r\n await Browser.open({ \r\n url: pdfUrl,\r\n presentationStyle: 'fullscreen'\r\n });\r\n \r\n this.isLoading = false;\r\n \r\n // Close the modal after opening browser\r\n setTimeout(() => {\r\n this.close();\r\n }, 500);\r\n } catch (error: any) {\r\n console.error('[PDF Lightbox] Error opening PDF:', error);\r\n this.isLoading = false;\r\n this.hasError = true;\r\n this.errorMessage = error?.message || 'Failed to open PDF';\r\n }\r\n }\r\n\r\n /**\r\n * Download a remote PDF and open it\r\n */\r\n private async downloadAndOpenPdf(): Promise<void> {\r\n try {\r\n console.log('[PDF Lightbox] Downloading PDF from:', this.pdf.src);\r\n \r\n // Fetch the PDF\r\n const response = await fetch(this.pdf.src);\r\n if (!response.ok) {\r\n throw new Error(`Failed to download PDF: ${response.statusText}`);\r\n }\r\n \r\n const blob = await response.blob();\r\n const base64Data = await this.blobToBase64(blob);\r\n \r\n // Generate a filename\r\n const fileName = this.pdf.title \r\n ? `${this.pdf.title.replace(/[^a-z0-9]/gi, '_')}.pdf`\r\n : 'document.pdf';\r\n \r\n // Save to cache directory\r\n const result = await Filesystem.writeFile({\r\n path: fileName,\r\n data: base64Data,\r\n directory: Directory.Cache\r\n });\r\n \r\n console.log('[PDF Lightbox] PDF saved to cache:', result.uri);\r\n this.cachedFilePath = result.uri;\r\n \r\n // Open using Browser\r\n await Browser.open({ \r\n url: result.uri,\r\n presentationStyle: 'fullscreen'\r\n });\r\n \r\n console.log('[PDF Lightbox] PDF opened successfully');\r\n } catch (error) {\r\n console.error('[PDF Lightbox] Error downloading/opening PDF:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Open a local PDF file\r\n */\r\n private async openLocalPdf(): Promise<void> {\r\n try {\r\n // Remove leading slash if present to avoid double slashes\r\n const cleanPath = this.pdf.src.startsWith('/') ? this.pdf.src.slice(1) : this.pdf.src;\r\n const fullUrl = window.location.origin + '/' + cleanPath;\r\n \r\n await Browser.open({ \r\n url: fullUrl,\r\n presentationStyle: 'fullscreen'\r\n });\r\n \r\n console.log('[PDF Lightbox] Local PDF opened successfully');\r\n } catch (error) {\r\n console.error('[PDF Lightbox] Error opening local PDF:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Convert Blob to base64 string\r\n */\r\n private blobToBase64(blob: Blob): Promise<string> {\r\n return new Promise((resolve, reject) => {\r\n const reader = new FileReader();\r\n reader.onloadend = () => {\r\n const base64String = reader.result as string;\r\n // Remove the data URL prefix\r\n const base64Data = base64String.split(',')[1];\r\n resolve(base64Data);\r\n };\r\n reader.onerror = reject;\r\n reader.readAsDataURL(blob);\r\n });\r\n }\r\n\r\n /**\r\n * Get display title with file extension\r\n * If title is provided, ensure it has .pdf extension\r\n * Otherwise, extract filename from src\r\n */\r\n getDisplayTitle(): string {\r\n if (this.pdf.title) {\r\n // If title doesn't end with .pdf, add it\r\n return this.pdf.title.endsWith('.pdf') ? this.pdf.title : `${this.pdf.title}.pdf`;\r\n }\r\n \r\n // Extract filename from src\r\n if (this.pdf.src) {\r\n const filename = this.pdf.src.split('/').pop() || 'PDF Document.pdf';\r\n return filename;\r\n }\r\n \r\n return 'PDF Document.pdf';\r\n }\r\n\r\n /**\r\n * Format file size for display\r\n */\r\n formatFileSize(bytes: number): string {\r\n if (bytes === 0) return '0 Bytes';\r\n \r\n const k = 1024;\r\n const sizes = ['Bytes', 'KB', 'MB', 'GB'];\r\n const i = Math.floor(Math.log(bytes) / Math.log(k));\r\n \r\n return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + ' ' + sizes[i];\r\n }\r\n\r\n /**\r\n * Share the PDF\r\n */\r\n async onShare(): Promise<void> {\r\n console.log('[PDF Lightbox] Share button clicked');\r\n \r\n if (!this.pdf?.src) return;\r\n \r\n try {\r\n await Share.share({\r\n title: this.pdf.title || 'PDF Document',\r\n text: this.pdf.description || '',\r\n url: this.pdf.src,\r\n dialogTitle: 'Share PDF'\r\n });\r\n \r\n console.log('[PDF Lightbox] PDF shared successfully');\r\n } catch (error) {\r\n console.error('[PDF Lightbox] Error sharing PDF:', error);\r\n }\r\n }\r\n\r\n /**\r\n * Close the PDF viewer\r\n */\r\n close(): void {\r\n if (this.onCloseRequested) {\r\n this.onCloseRequested();\r\n }\r\n }\r\n\r\n /**\r\n * Handle like toggle\r\n */\r\n onLikeToggle(): void {\r\n console.log('[PDF Lightbox] Like toggled');\r\n // TODO: Implement like logic for PDFs if needed\r\n }\r\n\r\n /**\r\n * Handle reply/comment\r\n * Close the lightbox and signal to open post detail with comment focus\r\n */\r\n onReply(): void {\r\n console.log('[PDF Lightbox] Reply button clicked');\r\n if (this.onCloseRequested) {\r\n this.onCloseRequested();\r\n // The calling code should handle opening the post detail modal\r\n }\r\n }\r\n}\r\n\r\n","import { Injectable, ApplicationRef, ComponentRef, createComponent, EnvironmentInjector, Injector } from '@angular/core';\r\nimport { DsMobileLightboxImageComponent } from './ds-mobile-lightbox-image';\r\nimport { DsMobileLightboxPdfComponent } from './ds-mobile-lightbox-pdf';\r\n\r\n/**\r\n * Media file types supported by the lightbox\r\n */\r\nexport type LightboxMediaType = 'image' | 'pdf';\r\n\r\n/**\r\n * Base media file interface\r\n */\r\nexport interface LightboxMediaFile {\r\n /** File source URL */\r\n src: string;\r\n /** Media type - determines which viewer to use */\r\n type: LightboxMediaType;\r\n /** File title */\r\n title?: string;\r\n /** File description */\r\n description?: string;\r\n}\r\n\r\n/**\r\n * Image data for lightbox display\r\n */\r\nexport interface LightboxImage extends LightboxMediaFile {\r\n type: 'image';\r\n /** Alt text for accessibility */\r\n alt?: string;\r\n /** Thumbnail URL for faster loading (optional) */\r\n thumbnail?: string;\r\n /** Whether the image is liked */\r\n isLiked?: boolean;\r\n /** Number of likes */\r\n likeCount?: number;\r\n /** Number of comments */\r\n commentCount?: number;\r\n}\r\n\r\n/**\r\n * PDF document data for lightbox display\r\n */\r\nexport interface LightboxPdf extends LightboxMediaFile {\r\n type: 'pdf';\r\n /** File size in bytes (optional, for display) */\r\n fileSize?: number;\r\n /** Number of pages (optional, for display) */\r\n pageCount?: number;\r\n}\r\n\r\n/**\r\n * Author metadata for the lightbox\r\n */\r\nexport interface LightboxAuthor {\r\n /** Author name */\r\n name: string;\r\n /** Author role/subtitle */\r\n role?: string;\r\n /** Author avatar URL */\r\n avatarSrc?: string;\r\n /** Author avatar initials (if no photo) */\r\n avatarInitials?: string;\r\n /** Avatar type */\r\n avatarType?: 'photo' | 'initials';\r\n /** Timestamp */\r\n timestamp?: string;\r\n}\r\n\r\n/**\r\n * Configuration options for image lightbox\r\n */\r\nexport interface LightboxImageOptions {\r\n /** Array of images to display */\r\n images: LightboxImage[];\r\n /** Author information to display in header */\r\n author?: LightboxAuthor;\r\n /** Initial image index to show (0-based) */\r\n initialIndex?: number;\r\n /** Enable pinch-to-zoom and double-tap zoom */\r\n enableZoom?: boolean;\r\n /** Show navigation controls (arrows, counter) */\r\n showControls?: boolean;\r\n /** Enable swipe gestures to navigate between images */\r\n enableSwipe?: boolean;\r\n /** Show image info (title, description) */\r\n showInfo?: boolean;\r\n /** Animation type for opening */\r\n animation?: 'fade' | 'zoom' | 'slide';\r\n}\r\n\r\n/**\r\n * Configuration options for PDF lightbox\r\n */\r\nexport interface LightboxPdfOptions {\r\n /** PDF document to display */\r\n pdf: LightboxPdf;\r\n /** Author information to display */\r\n author?: LightboxAuthor;\r\n}\r\n\r\n/**\r\n * Generic lightbox options (for backward compatibility)\r\n */\r\nexport type LightboxOptions = LightboxImageOptions;\r\n\r\n/**\r\n * DsMobileLightboxService\r\n * \r\n * Service for displaying media files (images and PDFs) in full-screen viewers.\r\n * - Images: Full-screen modal with gestures (pinch-zoom, swipe navigation)\r\n * - PDFs: Native device PDF viewer (iOS/Android)\r\n * \r\n * Features:\r\n * - Full-screen image viewing with gestures\r\n * - Native PDF viewing\r\n * - Swipe navigation between images\r\n * - Pinch-to-zoom and double-tap zoom for images\r\n * - Mobile-optimized touch gestures\r\n * - Share functionality\r\n * \r\n * @example\r\n * ```typescript\r\n * constructor(private lightbox: DsMobileLightboxService) {}\r\n * \r\n * // Open images\r\n * async openImages() {\r\n * const modal = await this.lightbox.openImages({\r\n * images: [\r\n * {\r\n * type: 'image',\r\n * src: 'https://example.com/image1.jpg',\r\n * title: 'Beautiful Sunset'\r\n * }\r\n * ]\r\n * });\r\n * \r\n * // Listen for when lightbox is dismissed\r\n * const { data } = await modal.onDidDismiss();\r\n * if (data?.action === 'comment') {\r\n * // Open post detail modal with comment focus\r\n * this.openPostDetail({ focusComment: true });\r\n * }\r\n * }\r\n * \r\n * // Open PDF\r\n * async openPdf() {\r\n * await this.lightbox.openPdf({\r\n * pdf: {\r\n * type: 'pdf',\r\n * src: 'https://example.com/document.pdf',\r\n * title: 'Document'\r\n * }\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class DsMobileLightboxService {\r\n private currentLightbox: ComponentRef<any> | null = null;\r\n\r\n constructor(\r\n private appRef: ApplicationRef,\r\n private injector: EnvironmentInjector\r\n ) {}\r\n\r\n /**\r\n * Open the lightbox with images (backward compatible method)\r\n * \r\n * @param options Configuration options for the image lightbox\r\n * @returns Promise that resolves to a dismiss function\r\n */\r\n async open(options: LightboxOptions): Promise<() => void> {\r\n return this.openImages(options);\r\n }\r\n\r\n /**\r\n * Open the image lightbox with one or more images\r\n * \r\n * @param options Configuration options for the image lightbox\r\n * @returns Promise that resolves to a dismiss function\r\n */\r\n async openImages(options: LightboxImageOptions): Promise<() => void> {\r\n console.log('[Lightbox] Opening images with options:', options);\r\n \r\n // Close any existing lightbox\r\n if (this.currentLightbox) {\r\n this.close();\r\n }\r\n\r\n // Create the component\r\n const componentRef = createComponent(DsMobileLightboxImageComponent, {\r\n environmentInjector: this.injector\r\n });\r\n\r\n // Set component props\r\n componentRef.instance.images = options.images;\r\n componentRef.instance.author = options.author;\r\n componentRef.instance.initialIndex = options.initialIndex ?? 0;\r\n componentRef.instance.enableZoom = options.enableZoom !== false;\r\n componentRef.instance.showControls = options.showControls !== false;\r\n componentRef.instance.enableSwipe = options.enableSwipe !== false;\r\n componentRef.instance.showInfo = options.showInfo !== false;\r\n componentRef.instance.animation = options.animation ?? 'fade';\r\n \r\n // Set up close callback\r\n componentRef.instance.onCloseRequested = () => {\r\n this.close();\r\n };\r\n\r\n // Attach to application\r\n this.appRef.attachView(componentRef.hostView);\r\n \r\n // Append to body\r\n const domElem = (componentRef.hostView as any).rootNodes[0] as HTMLElement;\r\n document.body.appendChild(domElem);\r\n \r\n // Store reference\r\n this.currentLightbox = componentRef;\r\n\r\n console.log('[Lightbox] Image lightbox rendered');\r\n \r\n // Return dismiss function\r\n return () => this.close();\r\n }\r\n\r\n /**\r\n * Open the PDF lightbox (opens native PDF viewer)\r\n * \r\n * @param options Configuration options for the PDF lightbox\r\n * @returns Promise that resolves to a dismiss function\r\n */\r\n async openPdf(options: LightboxPdfOptions): Promise<() => void> {\r\n console.log('[Lightbox] Opening PDF with options:', options);\r\n \r\n // Close any existing lightbox\r\n if (this.currentLightbox) {\r\n this.close();\r\n }\r\n\r\n // Create the component\r\n const componentRef = createComponent(DsMobileLightboxPdfComponent, {\r\n environmentInjector: this.injector\r\n });\r\n\r\n // Set component props\r\n componentRef.instance.pdf = options.pdf;\r\n componentRef.instance.author = options.author;\r\n \r\n // Set up close callback\r\n componentRef.instance.onCloseRequested = () => {\r\n this.close();\r\n };\r\n\r\n // Attach to application\r\n this.appRef.attachView(componentRef.hostView);\r\n \r\n // Append to body\r\n const domElem = (componentRef.hostView as any).rootNodes[0] as HTMLElement;\r\n document.body.appendChild(domElem);\r\n \r\n // Store reference\r\n this.currentLightbox = componentRef;\r\n\r\n console.log('[Lightbox] PDF lightbox rendered');\r\n \r\n // Return dismiss function\r\n return () => this.close();\r\n }\r\n\r\n /**\r\n * Close the currently open lightbox\r\n */\r\n close(): void {\r\n if (this.currentLightbox) {\r\n const domElem = (this.currentLightbox.hostView as any).rootNodes[0] as HTMLElement;\r\n domElem.remove();\r\n this.appRef.detachView(this.currentLightbox.hostView);\r\n this.currentLightbox.destroy();\r\n this.currentLightbox = null;\r\n }\r\n }\r\n\r\n /**\r\n * Check if a lightbox is currently open\r\n */\r\n isOpen(): boolean {\r\n return this.currentLightbox !== null;\r\n }\r\n}\r\n\r\n","// Components\r\nexport { DsMobileLightboxImageComponent } from './ds-mobile-lightbox-image';\r\nexport { DsMobileLightboxPdfComponent } from './ds-mobile-lightbox-pdf';\r\nexport { DsMobileLightboxHeaderComponent } from './ds-mobile-lightbox-header';\r\nexport { DsMobileLightboxFooterComponent } from './ds-mobile-lightbox-footer';\r\n\r\n// Service and Types\r\nexport { \r\n DsMobileLightboxService,\r\n type LightboxImage,\r\n type LightboxPdf,\r\n type LightboxMediaFile,\r\n type LightboxMediaType,\r\n type LightboxAuthor,\r\n type LightboxOptions,\r\n type LightboxImageOptions,\r\n type LightboxPdfOptions\r\n} from './ds-mobile-lightbox.service';\r\n\r\n// Legacy export for backward compatibility\r\nexport { DsMobileLightboxImageComponent as DsMobileLightboxComponent } from './ds-mobile-lightbox-image';\r\n\r\n","import { Component, Input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsMobileLightboxService, LightboxImage } from '../lightbox/ds-mobile-lightbox.service';\r\n\r\n/**\r\n * DsMobileInlinePhotoComponent\r\n * \r\n * Displays one or multiple photos in a grid layout optimized for social feeds.\r\n * Supports up to 5 visible images with automatic grid layouts.\r\n * \r\n * Features:\r\n * - Automatic grid layouts for 1-5 images\r\n * - Shows \"+N more\" overlay if more than 5 images\r\n * - Opens lightbox with all images (including hidden ones) when clicked\r\n * - Optimized layouts: 1 full, 2 split, 3 masonry, 4 grid, 5 grid\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-inline-photo\r\n * [images]=\"['img1.jpg', 'img2.jpg', 'img3.jpg']\"\r\n * [author]=\"authorInfo\"\r\n * />\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-inline-photo',\r\n standalone: true,\r\n imports: [CommonModule],\r\n template: `\r\n <div \r\n class=\"photo-grid\" \r\n [attr.data-count]=\"visibleImages.length\"\r\n [class.has-more]=\"hiddenCount > 0\">\r\n @for (image of visibleImages; track image; let i = $index) {\r\n <div \r\n class=\"photo-item\"\r\n [class.last]=\"i === visibleImages.length - 1\"\r\n (click)=\"openLightbox(i, $event)\">\r\n <img \r\n [src]=\"image\" \r\n [alt]=\"'Photo ' + (i + 1)\"\r\n loading=\"lazy\">\r\n \r\n <!-- Show \"+N more\" overlay on last image if there are hidden images -->\r\n @if (i === visibleImages.length - 1 && hiddenCount > 0) {\r\n <div class=\"more-overlay\">\r\n <span class=\"more-text\">+{{ hiddenCount }}</span>\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n display: block;\r\n }\r\n\r\n .photo-grid {\r\n display: grid;\r\n gap: 4px;\r\n border-radius: 8px;\r\n overflow: hidden;\r\n background: var(--ds-color-neutral-100);\r\n width: 100%;\r\n }\r\n\r\n .photo-item {\r\n position: relative;\r\n overflow: hidden;\r\n cursor: pointer;\r\n background: var(--ds-color-neutral-200);\r\n aspect-ratio: 1;\r\n }\r\n\r\n .photo-item img {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n display: block;\r\n transition: transform 0.2s ease;\r\n }\r\n\r\n .photo-item:active img {\r\n transform: scale(0.98);\r\n }\r\n\r\n .more-overlay {\r\n position: absolute;\r\n inset: 0;\r\n background: rgba(0, 0, 0, 0.6);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n pointer-events: none;\r\n }\r\n\r\n .more-text {\r\n color: white;\r\n font-size: 32px;\r\n font-weight: 600;\r\n font-family: var(--ds-font-family-medium);\r\n }\r\n\r\n /* 1 image: full width, 4:3 ratio */\r\n .photo-grid[data-count=\"1\"] {\r\n grid-template-columns: 1fr;\r\n }\r\n \r\n .photo-grid[data-count=\"1\"] .photo-item {\r\n aspect-ratio: 4/3;\r\n }\r\n\r\n /* 2 images: side by side */\r\n .photo-grid[data-count=\"2\"] {\r\n grid-template-columns: 1fr 1fr;\r\n }\r\n\r\n /* 3 images: 1 large left, 2 stacked right */\r\n .photo-grid[data-count=\"3\"] {\r\n grid-template-columns: 2fr 1fr;\r\n grid-auto-rows: 1fr;\r\n }\r\n \r\n .photo-grid[data-count=\"3\"] .photo-item:first-child {\r\n grid-row: 1 / 3;\r\n aspect-ratio: auto;\r\n }\r\n \r\n /* Right side images remain 1:1 squares */\r\n .photo-grid[data-count=\"3\"] .photo-item:nth-child(2),\r\n .photo-grid[data-count=\"3\"] .photo-item:nth-child(3) {\r\n aspect-ratio: 1;\r\n }\r\n\r\n /* 4 images: 2x2 grid */\r\n .photo-grid[data-count=\"4\"] {\r\n grid-template-columns: 1fr 1fr;\r\n grid-template-rows: 1fr 1fr;\r\n }\r\n\r\n /* 5 images: 2 on top, 3 on bottom */\r\n .photo-grid[data-count=\"5\"] {\r\n grid-template-columns: repeat(6, 1fr);\r\n grid-template-rows: auto auto;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item {\r\n aspect-ratio: 1;\r\n width: 100%;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(1) {\r\n grid-column: 1 / 4;\r\n grid-row: 1;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(2) {\r\n grid-column: 4 / 7;\r\n grid-row: 1;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(3) {\r\n grid-column: 1 / 3;\r\n grid-row: 2;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(4) {\r\n grid-column: 3 / 5;\r\n grid-row: 2;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(5) {\r\n grid-column: 5 / 7;\r\n grid-row: 2;\r\n }\r\n\r\n /* Round bottom corners for 5-image layout */\r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(3) {\r\n border-bottom-left-radius: 8px;\r\n overflow: hidden;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(5) {\r\n border-bottom-right-radius: 8px;\r\n overflow: hidden;\r\n }\r\n `]\r\n})\r\nexport class DsMobileInlinePhotoComponent {\r\n /**\r\n * Array of image URLs to display\r\n */\r\n @Input() images: string[] = [];\r\n\r\n /**\r\n * Author information (passed to lightbox)\r\n */\r\n @Input() author?: {\r\n name: string;\r\n role?: string;\r\n avatarSrc?: string;\r\n avatarInitials?: string;\r\n avatarType?: 'photo' | 'initials';\r\n timestamp?: string;\r\n };\r\n\r\n /**\r\n * Maximum number of images to show inline (default: 5)\r\n * Remaining images shown in lightbox only\r\n */\r\n @Input() maxVisible: number = 5;\r\n\r\n /**\r\n * Event emitted when lightbox is opened\r\n */\r\n photoClick = output<{ index: number; totalImages: number }>();\r\n\r\n constructor(private lightboxService: DsMobileLightboxService) {}\r\n\r\n /**\r\n * Get the first N images to display inline\r\n */\r\n get visibleImages(): string[] {\r\n return this.images.slice(0, this.maxVisible);\r\n }\r\n\r\n /**\r\n * Calculate how many images are hidden\r\n */\r\n get hiddenCount(): number {\r\n return Math.max(0, this.images.length - this.maxVisible);\r\n }\r\n\r\n /**\r\n * Open lightbox with all images, starting at the clicked index\r\n */\r\n openLightbox(index: number, event?: Event): void {\r\n // Stop event propagation to prevent triggering parent click handlers\r\n if (event) {\r\n event.stopPropagation();\r\n event.preventDefault();\r\n }\r\n\r\n // Emit event\r\n this.photoClick.emit({\r\n index,\r\n totalImages: this.images.length\r\n });\r\n\r\n // Convert image URLs to LightboxImage format\r\n const lightboxImages: LightboxImage[] = this.images.map((src, i) => ({\r\n type: 'image',\r\n src,\r\n alt: `Photo ${i + 1}`\r\n }));\r\n\r\n // Open lightbox with all images (not just visible ones)\r\n this.lightboxService.openImages({\r\n images: lightboxImages,\r\n initialIndex: index,\r\n author: this.author,\r\n enableZoom: true,\r\n showControls: true,\r\n enableSwipe: true\r\n });\r\n }\r\n}\r\n\r\n","import { Injectable, Type } from '@angular/core';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\n\r\n/**\r\n * Configuration options for modal presentation\r\n */\r\nexport interface ModalOptions<T = any> {\r\n /** The component to display in the modal */\r\n component: Type<T>;\r\n /** Props to pass to the component */\r\n componentProps?: Record<string, any>;\r\n /** CSS class(es) to apply to the modal */\r\n cssClass?: string | string[];\r\n /** Modal presentation style */\r\n presentationStyle?: 'fullscreen' | 'card' | 'sheet';\r\n /** Enable backdrop dismiss (tap outside to close) */\r\n backdropDismiss?: boolean;\r\n /** Show backdrop */\r\n showBackdrop?: boolean;\r\n /** Enable keyboard close (ESC key) */\r\n keyboardClose?: boolean;\r\n /** Enable swipe to close */\r\n swipeToClose?: boolean;\r\n /** Initial breakpoint (0-1) for sheet presentation */\r\n initialBreakpoint?: number;\r\n /** Available breakpoints for sheet presentation */\r\n breakpoints?: number[];\r\n /** Animation type */\r\n animated?: boolean;\r\n /** Mode (ios or md) */\r\n mode?: 'ios' | 'md';\r\n /** Whether to handle navigation back button */\r\n handleNavigationBack?: boolean;\r\n}\r\n\r\n/**\r\n * DsMobileModalService\r\n * \r\n * Generic service for displaying any component as a modal.\r\n * Built on Ionic's modal system with customizable presentation styles.\r\n * \r\n * Features:\r\n * - Open any component as a modal\r\n * - Fullscreen, card, or sheet presentation styles\r\n * - Customizable backdrop and dismissal behavior\r\n * - Native gestures and animations\r\n * - Type-safe component props\r\n * \r\n * @example\r\n * ```typescript\r\n * import { MobilePostDetailPageComponent } from './post-detail.page';\r\n * \r\n * constructor(private modal: DsMobileModalService) {}\r\n * \r\n * async openPostModal() {\r\n * await this.modal.open({\r\n * component: MobilePostDetailPageComponent,\r\n * componentProps: {\r\n * postId: '123',\r\n * authorName: 'John Doe'\r\n * },\r\n * presentationStyle: 'card',\r\n * backdropDismiss: true\r\n * });\r\n * }\r\n * ```\r\n * \r\n * @example Sheet presentation with breakpoints\r\n * ```typescript\r\n * async openSheet() {\r\n * await this.modal.open({\r\n * component: CommentsComponent,\r\n * presentationStyle: 'sheet',\r\n * initialBreakpoint: 0.5,\r\n * breakpoints: [0, 0.5, 0.75, 1],\r\n * swipeToClose: true\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class DsMobileModalService {\r\n constructor(private modalController: ModalController) {}\r\n\r\n /**\r\n * Open a component as a modal\r\n * \r\n * @param options Configuration options for the modal\r\n * @returns Promise that resolves when the modal is presented\r\n * \r\n * @example\r\n * ```typescript\r\n * await this.modal.open({\r\n * component: MyComponent,\r\n * componentProps: { data: 'value' },\r\n * presentationStyle: 'fullscreen'\r\n * });\r\n * ```\r\n */\r\n async open<T = any>(options: ModalOptions<T>): Promise<HTMLIonModalElement> {\r\n console.log('[Modal] Opening modal with options:', options);\r\n \r\n const {\r\n component,\r\n componentProps,\r\n cssClass,\r\n presentationStyle = 'card',\r\n backdropDismiss = true,\r\n showBackdrop = true,\r\n keyboardClose = true,\r\n swipeToClose,\r\n initialBreakpoint,\r\n breakpoints,\r\n animated = true,\r\n mode = 'ios',\r\n handleNavigationBack = true\r\n } = options;\r\n\r\n // Build modal configuration\r\n const modalConfig: any = {\r\n component,\r\n componentProps: componentProps || {},\r\n cssClass: this.buildCssClasses(cssClass, presentationStyle),\r\n mode,\r\n backdropDismiss,\r\n showBackdrop,\r\n animated,\r\n keyboardClose,\r\n presentingElement: document.querySelector('ion-router-outlet') || undefined,\r\n handle: presentationStyle === 'sheet', // Show handle for sheet presentation\r\n };\r\n\r\n // Add swipe to close for sheet presentation\r\n if (swipeToClose !== undefined) {\r\n modalConfig.canDismiss = swipeToClose;\r\n }\r\n\r\n // Add breakpoints for sheet presentation\r\n if (presentationStyle === 'sheet' && breakpoints) {\r\n modalConfig.breakpoints = breakpoints;\r\n if (initialBreakpoint !== undefined) {\r\n modalConfig.initialBreakpoint = initialBreakpoint;\r\n }\r\n }\r\n\r\n // Handle navigation back button\r\n if (handleNavigationBack) {\r\n modalConfig.canDismiss = async () => {\r\n // You can add custom logic here if needed\r\n return true;\r\n };\r\n }\r\n\r\n const modal = await this.modalController.create(modalConfig);\r\n\r\n console.log('[Modal] Modal created, presenting...');\r\n await modal.present();\r\n console.log('[Modal] Modal presented');\r\n\r\n return modal;\r\n }\r\n\r\n /**\r\n * Open a component as a fullscreen modal\r\n * \r\n * @param component Component to display\r\n * @param componentProps Props to pass to the component\r\n * @returns Promise that resolves when the modal is presented\r\n * \r\n * @example\r\n * ```typescript\r\n * await this.modal.openFullscreen(PostDetailPage, { postId: '123' });\r\n * ```\r\n */\r\n async openFullscreen<T = any>(\r\n component: Type<T>,\r\n componentProps?: Record<string, any>\r\n ): Promise<HTMLIonModalElement> {\r\n return this.open({\r\n component,\r\n componentProps,\r\n presentationStyle: 'fullscreen',\r\n backdropDismiss: false,\r\n showBackdrop: false\r\n });\r\n }\r\n\r\n /**\r\n * Open a component as a card modal\r\n * \r\n * @param component Component to display\r\n * @param componentProps Props to pass to the component\r\n * @returns Promise that resolves when the modal is presented\r\n * \r\n * @example\r\n * ```typescript\r\n * await this.modal.openCard(DetailComponent, { itemId: '456' });\r\n * ```\r\n */\r\n async openCard<T = any>(\r\n component: Type<T>,\r\n componentProps?: Record<string, any>\r\n ): Promise<HTMLIonModalElement> {\r\n return this.open({\r\n component,\r\n componentProps,\r\n presentationStyle: 'card',\r\n backdropDismiss: true,\r\n showBackdrop: true\r\n });\r\n }\r\n\r\n /**\r\n * Open a component as a bottom sheet\r\n * \r\n * @param component Component to display\r\n * @param componentProps Props to pass to the component\r\n * @param options Additional sheet options (breakpoints, etc.)\r\n * @returns Promise that resolves when the modal is presented\r\n * \r\n * @example\r\n * ```typescript\r\n * await this.modal.openSheet(\r\n * CommentsComponent,\r\n * { postId: '789' },\r\n * { initialBreakpoint: 0.5, breakpoints: [0, 0.5, 1] }\r\n * );\r\n * ```\r\n */\r\n async openSheet<T = any>(\r\n component: Type<T>,\r\n componentProps?: Record<string, any>,\r\n options?: {\r\n initialBreakpoint?: number;\r\n breakpoints?: number[];\r\n swipeToClose?: boolean;\r\n }\r\n ): Promise<HTMLIonModalElement> {\r\n return this.open({\r\n component,\r\n componentProps,\r\n presentationStyle: 'sheet',\r\n backdropDismiss: true,\r\n showBackdrop: true,\r\n swipeToClose: options?.swipeToClose ?? true,\r\n initialBreakpoint: options?.initialBreakpoint ?? 0.5,\r\n breakpoints: options?.breakpoints ?? [0, 0.5, 0.75, 1]\r\n });\r\n }\r\n\r\n /**\r\n * Close the currently open modal\r\n * \r\n * @param data Optional data to pass back when dismissing\r\n * @param role Optional role (e.g., 'cancel', 'confirm')\r\n * @returns Promise that resolves when the modal is dismissed\r\n * \r\n * @example\r\n * ```typescript\r\n * await this.modal.dismiss({ saved: true }, 'confirm');\r\n * ```\r\n */\r\n async dismiss(data?: any, role?: string): Promise<boolean> {\r\n return this.modalController.dismiss(data, role);\r\n }\r\n\r\n /**\r\n * Get the top-most modal if one exists\r\n * \r\n * @returns Promise that resolves to the modal element or undefined\r\n * \r\n * @example\r\n * ```typescript\r\n * const topModal = await this.modal.getTop();\r\n * if (topModal) {\r\n * await topModal.dismiss();\r\n * }\r\n * ```\r\n */\r\n async getTop(): Promise<HTMLIonModalElement | undefined> {\r\n return this.modalController.getTop();\r\n }\r\n\r\n /**\r\n * Get all currently open modals\r\n * \r\n * @returns Promise that resolves to an array of modal elements\r\n */\r\n async getAll(): Promise<HTMLIonModalElement[]> {\r\n const modals: HTMLIonModalElement[] = [];\r\n let modal = await this.modalController.getTop();\r\n \r\n while (modal) {\r\n modals.push(modal);\r\n // Get the next modal in the stack\r\n await modal.dismiss();\r\n modal = await this.modalController.getTop();\r\n }\r\n \r\n return modals;\r\n }\r\n\r\n /**\r\n * Build CSS classes for the modal\r\n */\r\n private buildCssClasses(\r\n customClass?: string | string[],\r\n presentationStyle?: string\r\n ): string[] {\r\n const classes: string[] = ['ds-mobile-modal'];\r\n \r\n if (presentationStyle) {\r\n classes.push(`ds-modal-${presentationStyle}`);\r\n }\r\n \r\n if (customClass) {\r\n if (Array.isArray(customClass)) {\r\n classes.push(...customClass);\r\n } else {\r\n classes.push(customClass);\r\n }\r\n }\r\n \r\n return classes;\r\n }\r\n}\r\n\r\n","/**\r\n * Mobile Modal Module\r\n * \r\n * Generic service for opening any component as a modal\r\n */\r\n\r\nexport * from './ds-mobile-modal.service';\r\n\r\n","import {\r\n Component,\r\n signal,\r\n computed,\r\n CUSTOM_ELEMENTS_SCHEMA,\r\n Input,\r\n ViewChild,\r\n ElementRef,\r\n AfterViewInit,\r\n OnDestroy\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport {\r\n IonContent,\r\n ModalController\r\n} from '@ionic/angular/standalone';\r\nimport { Keyboard } from '@capacitor/keyboard';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport {\r\n DsMobilePostCardComponent,\r\n PostContentComponent,\r\n PostTextComponent,\r\n PostMediaComponent,\r\n PostActionsComponent,\r\n ActionLikeComponent,\r\n ActionCommentComponent\r\n} from '../post-card/ds-mobile-post-card';\r\nimport { DsMobileCommentComponent } from '../comment/ds-mobile-comment';\r\nimport { DsMobileLightboxService, LightboxAuthor } from '../lightbox';\r\nimport { \r\n DsMobileBottomSheetService, \r\n DsMobileCommentActionsBottomSheetComponent,\r\n CommentActionResult \r\n} from '../bottom-sheet';\r\n\r\n/**\r\n * Post data interface for the modal\r\n */\r\nexport interface PostDetailData {\r\n postId: string;\r\n authorName: string;\r\n authorRole: string;\r\n timestamp: string;\r\n avatarInitials?: string;\r\n avatarType?: 'photo' | 'initials';\r\n avatarSrc?: string;\r\n content: string;\r\n imageSrc?: string;\r\n imageAlt?: string;\r\n isLiked?: boolean;\r\n likeCount?: number;\r\n commentCount?: number;\r\n comments?: CommentData[];\r\n focusComment?: boolean; // Auto-focus comment input when modal opens\r\n}\r\n\r\nexport interface CommentData {\r\n authorName: string;\r\n authorRole: string;\r\n timestamp: string;\r\n avatarInitials: string;\r\n content: string;\r\n isLiked?: boolean;\r\n likeCount?: number;\r\n isOwnComment?: boolean;\r\n}\r\n\r\n/**\r\n * DsMobilePostDetailModalComponent\r\n * \r\n * Modal wrapper for displaying post details with comments.\r\n * Follows the same pattern as the lightbox modal for consistent behavior.\r\n * \r\n * Features:\r\n * - Full post content display\r\n * - Comments section\r\n * - Image lightbox integration\r\n * - Native modal controls (close, swipe down)\r\n * - Safe area support\r\n * \r\n * This component is typically not used directly - use DsMobilePostDetailModalService instead.\r\n * \r\n * @example\r\n * ```typescript\r\n * // Don't instantiate directly - use the service:\r\n * constructor(private postModal: DsMobilePostDetailModalService) {}\r\n * \r\n * openPost() {\r\n * this.postModal.open({\r\n * postId: '123',\r\n * authorName: 'John Doe',\r\n * content: 'Post content...'\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-post-detail-modal',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n IonContent,\r\n DsIconButtonComponent,\r\n DsIconComponent,\r\n DsAvatarComponent,\r\n PostTextComponent,\r\n PostMediaComponent,\r\n ActionLikeComponent,\r\n ActionCommentComponent,\r\n DsMobileCommentComponent\r\n ],\r\n styleUrls: ['../shared/mobile-common.css'],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n template: `\r\n <ion-content [fullscreen]=\"true\" [scrollY]=\"true\" class=\"post-modal-content\">\r\n <div class=\"post-modal-wrapper\">\r\n <!-- Header with post author info -->\r\n <div class=\"post-modal-header\">\r\n <div class=\"header-content\">\r\n <!-- Post author info -->\r\n <div class=\"post-author-info\">\r\n <ds-avatar\r\n [initials]=\"post().avatarInitials || ''\"\r\n [type]=\"post().avatarType || 'initials'\"\r\n [src]=\"post().avatarSrc || ''\"\r\n size=\"md\"\r\n />\r\n <div class=\"author-details\">\r\n <div class=\"author-name\">{{ post().authorName }}</div>\r\n <div class=\"author-meta\">\r\n <span>{{ post().authorRole }}</span>\r\n <span class=\"separator\">·</span>\r\n <span>{{ post().timestamp }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Close button -->\r\n <ds-icon-button\r\n icon=\"remixCloseLine\"\r\n variant=\"secondary\"\r\n size=\"lg\"\r\n (click)=\"close()\"\r\n class=\"close-button\"\r\n aria-label=\"Luk opslag\">\r\n </ds-icon-button>\r\n </div>\r\n </div>\r\n\r\n <!-- Post content -->\r\n <div class=\"post-detail-container\">\r\n <!-- Post Section -->\r\n <div class=\"post-section\">\r\n <div class=\"post-content-only\">\r\n <post-text>{{ post().content }}</post-text>\r\n @if (post().imageSrc) {\r\n <post-media>\r\n <img \r\n [src]=\"post().imageSrc\"\r\n [alt]=\"post().imageAlt || 'Post image'\"\r\n class=\"clickable-image\"\r\n (click)=\"openImageLightbox()\"\r\n />\r\n </post-media>\r\n }\r\n </div>\r\n \r\n <!-- Post actions -->\r\n <div class=\"post-actions\">\r\n <action-like \r\n [active]=\"post().isLiked || false\" \r\n [count]=\"post().likeCount || 0\" />\r\n <action-comment \r\n [count]=\"post().commentCount || 0\"\r\n (commentClick)=\"focusCommentInput()\" />\r\n </div>\r\n </div>\r\n \r\n <!-- Comments Section -->\r\n <div class=\"comments-section\">\r\n @if (post().comments && post().comments!.length > 0) {\r\n <h2 class=\"comments-header\">{{ post().comments!.length }} {{ post().comments!.length === 1 ? 'reply' : 'replies' }}</h2>\r\n \r\n <div class=\"comments-list\">\r\n @for (comment of post().comments!; track comment.authorName + comment.timestamp) {\r\n <ds-mobile-comment\r\n [authorName]=\"comment.authorName\"\r\n [authorRole]=\"comment.authorRole\"\r\n [timestamp]=\"comment.timestamp\"\r\n [avatarInitials]=\"comment.avatarInitials\"\r\n [content]=\"comment.content\"\r\n [isLiked]=\"comment.isLiked || false\"\r\n [likeCount]=\"comment.likeCount || 0\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"comment.isOwnComment || false\"\r\n (replyClick)=\"handleReply(comment.authorName, comment.content)\"\r\n (editClick)=\"handleEditComment(comment.authorName, comment.content, comment.timestamp)\"\r\n (longPress)=\"handleCommentLongPress(comment.authorName, comment.content, comment.isOwnComment || false)\" />\r\n }\r\n </div>\r\n } @else {\r\n <!-- Empty State -->\r\n <div class=\"comments-empty-state\">\r\n <img \r\n src=\"/Assets/Empty state-chat.png\" \r\n alt=\"Ingen kommentarer endnu\" \r\n class=\"empty-state-image\"\r\n />\r\n <h3 class=\"empty-state-title\">Ingen svar endnu</h3>\r\n <p class=\"empty-state-description\">Vær den første til at svare på dette opslag</p>\r\n </div>\r\n }\r\n \r\n <!-- Bottom spacer for fixed composer -->\r\n <div class=\"composer-spacer\"></div>\r\n </div>\r\n </div>\r\n </div>\r\n </ion-content>\r\n \r\n <!-- Fixed comment composer -->\r\n <div class=\"comment-composer-fixed\">\r\n <div class=\"comment-composer\">\r\n <!-- Edit indicator -->\r\n @if (editingComment()) {\r\n <div class=\"edit-indicator\">\r\n <div class=\"edit-indicator-content\">\r\n <ds-icon name=\"remixEditLine\" size=\"16px\" />\r\n <span class=\"edit-text\">Redigerer kommentar</span>\r\n </div>\r\n <button class=\"cancel-edit\" (click)=\"cancelEdit()\">\r\n <ds-icon name=\"remixCloseLine\" size=\"16px\" />\r\n </button>\r\n </div>\r\n } @else if (replyingTo()) {\r\n <!-- Reply indicator -->\r\n <div class=\"reply-indicator\">\r\n <div class=\"reply-indicator-content\">\r\n <ds-icon name=\"remixReplyLine\" size=\"16px\" />\r\n <span class=\"reply-to-text\">\r\n Svarer til <span class=\"reply-author\">{{ replyingTo()!.authorName }}</span>\r\n </span>\r\n </div>\r\n <button class=\"cancel-reply\" (click)=\"cancelReply()\">\r\n <ds-icon name=\"remixCloseLine\" size=\"16px\" />\r\n </button>\r\n </div>\r\n }\r\n \r\n <div class=\"composer-content\">\r\n <ds-avatar\r\n [initials]=\"currentUserInitials()\"\r\n [type]=\"'initials'\"\r\n size=\"md\"\r\n />\r\n <div class=\"composer-input-wrapper\">\r\n <!-- Mention menu -->\r\n @if (showMentionMenu() && filteredUsers().length > 0 && !editingComment()) {\r\n <div class=\"mention-menu\">\r\n @for (user of filteredUsers(); track user.name) {\r\n <button \r\n class=\"mention-menu-item\" \r\n (click)=\"selectMention(user.name)\">\r\n <ds-avatar \r\n [initials]=\"user.initials\"\r\n [type]=\"'initials'\"\r\n size=\"sm\" />\r\n <div class=\"mention-user-info\">\r\n <span class=\"mention-user-name\">{{ user.name }}</span>\r\n <span class=\"mention-user-role\">{{ user.role }}</span>\r\n </div>\r\n </button>\r\n }\r\n </div>\r\n }\r\n \r\n <textarea\r\n #commentInput\r\n class=\"composer-input\"\r\n [placeholder]=\"editingComment() ? 'Rediger din kommentar...' : (replyingTo() ? 'Tilføj et svar...' : 'Tilføj et svar...')\"\r\n [(ngModel)]=\"commentText\"\r\n (input)=\"handleInput($event)\"\r\n (focus)=\"showKeyboard()\"\r\n (click)=\"showKeyboard()\"\r\n rows=\"1\"\r\n ></textarea>\r\n </div>\r\n @if (commentText().trim().length > 0) {\r\n <ds-icon-button\r\n icon=\"remixCheckLine\"\r\n variant=\"primary\"\r\n size=\"sm\"\r\n (clicked)=\"submitComment()\"\r\n aria-label=\"Send kommentar\"\r\n class=\"send-button-fixed\">\r\n </ds-icon-button>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n display: block;\r\n position: relative;\r\n height: 100%;\r\n width: 100%;\r\n }\r\n\r\n .post-modal-content {\r\n --background: var(--color-background-neutral-primary, #ffffff);\r\n }\r\n\r\n .post-modal-wrapper {\r\n display: flex;\r\n flex-direction: column;\r\n min-height: 100%;\r\n min-height: 100dvh; /* Use dynamic viewport height for proper iOS safe area handling */\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n }\r\n\r\n .post-modal-header {\r\n position: sticky;\r\n top: 0;\r\n z-index: 10;\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n border-bottom: 1px solid var(--border-color-default);\r\n padding: 0 16px;\r\n }\r\n\r\n .header-content {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 12px;\r\n min-height: 72px;\r\n /* No padding needed - StatusBar.setOverlaysWebView(false) handles all spacing */\r\n }\r\n\r\n .post-author-info {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n\r\n .author-details {\r\n display: flex;\r\n flex-direction: column;\r\n min-width: 0;\r\n flex: 1;\r\n }\r\n\r\n /* Author name and meta styles imported from mobile-common.css */\r\n\r\n .author-meta .separator {\r\n color: var(--color-text-tertiary, #a0a0a0);\r\n }\r\n\r\n .close-button {\r\n flex-shrink: 0;\r\n border-radius: 50%;\r\n }\r\n \r\n .close-button::ng-deep button {\r\n border-radius: 50% !important;\r\n width: 36px !important;\r\n height: 36px !important;\r\n min-width: 36px !important;\r\n min-height: 36px !important;\r\n padding: 0 !important;\r\n display: flex !important;\r\n align-items: center !important;\r\n justify-content: center !important;\r\n }\r\n\r\n .post-detail-container {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 16px;\r\n width: 100%;\r\n max-width: 640px;\r\n margin: 0 auto;\r\n padding: 16px 0 20px 0;\r\n flex: 1;\r\n }\r\n \r\n .post-section {\r\n width: 100%;\r\n border-bottom: 1px solid var(--border-color-default);\r\n padding: 0 0 16px 0;\r\n }\r\n\r\n .post-content-only {\r\n font-size: var(--font-size-sm);\r\n line-height: 24px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n margin-bottom: 16px;\r\n padding: 0 20px;\r\n }\r\n \r\n .post-content-only post-media {\r\n margin-top: 16px;\r\n }\r\n\r\n .post-actions {\r\n display: flex;\r\n align-items: center;\r\n gap: 16px;\r\n padding: 0 20px;\r\n }\r\n \r\n .clickable-image {\r\n cursor: pointer;\r\n transition: transform 0.2s ease, opacity 0.2s ease;\r\n border-radius: 8px;\r\n display: block;\r\n width: 100%;\r\n aspect-ratio: 16/9;\r\n object-fit: cover;\r\n }\r\n \r\n .clickable-image:active {\r\n transform: scale(0.98);\r\n opacity: 0.9;\r\n }\r\n \r\n .comments-section {\r\n display: flex;\r\n flex-direction: column;\r\n margin-left: 0;\r\n margin-right: 0;\r\n padding: 0 20px;\r\n padding-bottom: 0;\r\n }\r\n \r\n .comments-header {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n line-height: 24px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n margin: 0 0 16px 0;\r\n padding-left: 0;\r\n padding-right: 0;\r\n }\r\n \r\n .comments-list {\r\n display: flex;\r\n flex-direction: column;\r\n }\r\n \r\n /* Empty State */\r\n .comments-empty-state {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 60px 20px;\r\n text-align: center;\r\n }\r\n \r\n .empty-state-image {\r\n width: 96px;\r\n height: 96px;\r\n margin-bottom: 24px;\r\n }\r\n \r\n .empty-state-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n line-height: 1.3;\r\n color: var(--color-text-primary, #1a1a1a);\r\n margin: 0 0 8px 0;\r\n }\r\n \r\n .empty-state-description {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 1.4;\r\n color: var(--color-text-secondary, #737373);\r\n margin: 0;\r\n }\r\n \r\n .composer-spacer {\r\n /* Match full composer height:\r\n - Border: 1px\r\n - Top padding: 12px\r\n - Composer content: ~56px (avatar + input wrapper)\r\n - Bottom padding: 12px + safe area\r\n Total: ~81px + safe area */\r\n height: calc(81px + env(safe-area-inset-bottom, 0px));\r\n }\r\n \r\n .bottom-spacer {\r\n height: 0px;\r\n }\r\n\r\n /* Fixed Comment Composer Container */\r\n .comment-composer-fixed {\r\n position: fixed;\r\n bottom: 48px; /* Compensate for modal's margin-top: 48px */\r\n left: 0;\r\n right: 0;\r\n z-index: 1000;\r\n pointer-events: none;\r\n /* Slide up with keyboard on native apps */\r\n transform: translateY(calc(-1 * var(--keyboard-height, 0px)));\r\n transition: transform 0.3s ease-out;\r\n /* Ensure it's within the modal viewport */\r\n max-width: 100vw;\r\n }\r\n\r\n /* Comment Composer */\r\n .comment-composer {\r\n pointer-events: auto;\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n border-top: 1px solid var(--border-color-default);\r\n padding: 12px 16px;\r\n /* Use dynamic viewport height safe area - matches tabs fix */\r\n /* For web browsers: 12px default; for native iOS: env(safe-area-inset-bottom) */\r\n padding-bottom: max(12px, env(safe-area-inset-bottom, 0px));\r\n width: 100%;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n /* White box shadow to cover content gap between keyboard and composer */\r\n box-shadow: 100px 150px 0 150px var(--color-background-neutral-primary, #ffffff);\r\n }\r\n \r\n /* Edit indicator */\r\n .edit-indicator {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 8px 12px;\r\n background: var(--color-background-brand-subtle, #f0edfe);\r\n border-radius: 8px;\r\n animation: slideDown 0.2s ease-out;\r\n }\r\n \r\n .edit-indicator-content {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n color: var(--color-brand-base, #6B5FF5);\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .edit-text {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 500;\r\n line-height: 18px;\r\n color: var(--color-brand-base, #6B5FF5);\r\n }\r\n \r\n .cancel-edit {\r\n background: none;\r\n border: none;\r\n padding: 4px;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n color: var(--color-brand-base, #6B5FF5);\r\n border-radius: 4px;\r\n transition: background 0.2s ease;\r\n flex-shrink: 0;\r\n }\r\n \r\n .cancel-edit:active {\r\n background: var(--color-brand-subtle, #e0dbfe);\r\n }\r\n \r\n /* Reply indicator */\r\n .reply-indicator {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 8px 12px;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-radius: 8px;\r\n animation: slideDown 0.2s ease-out;\r\n }\r\n \r\n .reply-indicator-content {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n color: var(--color-text-secondary, #737373);\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .reply-to-text {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n line-height: 18px;\r\n color: var(--color-text-secondary, #737373);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n .reply-author {\r\n color: var(--color-brand-base, #6B5FF5);\r\n font-weight: 600;\r\n }\r\n \r\n .cancel-reply {\r\n background: none;\r\n border: none;\r\n padding: 4px;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n color: var(--color-text-secondary, #737373);\r\n border-radius: 4px;\r\n transition: background 0.2s ease;\r\n flex-shrink: 0;\r\n }\r\n \r\n .cancel-reply:active {\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n }\r\n \r\n @keyframes slideDown {\r\n from {\r\n opacity: 0;\r\n transform: translateY(-10px);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n }\r\n \r\n .composer-content {\r\n display: flex;\r\n align-items: flex-start;\r\n gap: 12px;\r\n width: 100%;\r\n position: relative;\r\n }\r\n \r\n .composer-content ds-avatar {\r\n position: relative;\r\n top: 6px;\r\n }\r\n \r\n .composer-input-wrapper {\r\n flex: 1;\r\n display: flex;\r\n align-items: flex-start;\r\n gap: 8px;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-radius: 24px;\r\n padding: 12px 16px;\r\n padding-right: 48px; /* Extra padding for fixed send button */\r\n min-height: 44px;\r\n position: relative;\r\n }\r\n \r\n /* Mention menu */\r\n .mention-menu {\r\n position: absolute;\r\n bottom: 100%;\r\n left: 0;\r\n right: 0;\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n border-radius: 12px;\r\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\r\n margin-bottom: 8px;\r\n max-height: 200px;\r\n overflow-y: auto;\r\n z-index: 10;\r\n animation: slideUp 0.2s ease-out;\r\n }\r\n \r\n @keyframes slideUp {\r\n from {\r\n opacity: 0;\r\n transform: translateY(10px);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n }\r\n \r\n .mention-menu-item {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n padding: 12px;\r\n border: none;\r\n background: none;\r\n width: 100%;\r\n text-align: left;\r\n cursor: pointer;\r\n transition: background 0.2s ease;\r\n border-bottom: 1px solid var(--border-color-default);\r\n }\r\n \r\n .mention-menu-item:last-child {\r\n border-bottom: none;\r\n }\r\n \r\n .mention-menu-item:active {\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n }\r\n \r\n .mention-user-info {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .mention-user-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n line-height: 20px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n .mention-user-role {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n line-height: 18px;\r\n color: var(--color-text-secondary, #737373);\r\n }\r\n \r\n .composer-input {\r\n flex: 1;\r\n border: none;\r\n background: transparent;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n line-height: 20px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n outline: none;\r\n resize: none;\r\n min-height: 20px;\r\n max-height: 120px;\r\n overflow-y: auto;\r\n padding: 0;\r\n margin: 0;\r\n }\r\n \r\n .composer-input::placeholder {\r\n color: var(--color-text-tertiary, #a0a0a0);\r\n font-size: var(--font-size-sm);\r\n }\r\n \r\n /* Style the send button (ds-icon-button) - positioned in top right corner */\r\n .send-button-fixed {\r\n position: absolute;\r\n top: 6px;\r\n right: 6px;\r\n z-index: 10;\r\n flex-shrink: 0;\r\n animation: slideInFromRight 0.2s ease-out;\r\n }\r\n \r\n .send-button-fixed::ng-deep button {\r\n width: 32px !important;\r\n height: 32px !important;\r\n min-width: 32px !important;\r\n min-height: 32px !important;\r\n padding: 0 !important;\r\n border-radius: 50% !important;\r\n }\r\n \r\n /* Keep old style for reference but won't be used */\r\n .composer-input-wrapper ds-icon-button {\r\n flex-shrink: 0;\r\n animation: slideInFromRight 0.2s ease-out;\r\n }\r\n \r\n .composer-input-wrapper ds-icon-button::ng-deep button {\r\n width: 32px !important;\r\n height: 32px !important;\r\n min-width: 32px !important;\r\n min-height: 32px !important;\r\n padding: 0 !important;\r\n border-radius: 50% !important;\r\n }\r\n \r\n /* Slide in animation from right */\r\n @keyframes slideInFromRight {\r\n from {\r\n opacity: 0;\r\n transform: translateX(20px) scale(0.8);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateX(0) scale(1);\r\n }\r\n }\r\n\r\n /* Safe area support */\r\n @supports (padding: env(safe-area-inset-bottom)) {\r\n .post-detail-container {\r\n padding-bottom: calc(20px + env(safe-area-inset-bottom));\r\n }\r\n }\r\n `]\r\n})\r\nexport class DsMobilePostDetailModalComponent implements AfterViewInit, OnDestroy {\r\n // Post data passed from service\r\n @Input() postData!: PostDetailData;\r\n \r\n // ViewChild for comment input\r\n @ViewChild('commentInput') commentInput?: ElementRef<HTMLTextAreaElement>;\r\n\r\n // Signal for reactive post data\r\n post = signal<PostDetailData>({\r\n postId: '',\r\n authorName: '',\r\n authorRole: '',\r\n timestamp: '',\r\n content: '',\r\n comments: []\r\n });\r\n\r\n // Comment composer state\r\n commentText = signal('');\r\n currentUserInitials = signal('LM');\r\n replyingTo = signal<{ authorName: string; content: string } | null>(null);\r\n editingComment = signal<{ authorName: string; originalContent: string; timestamp: string } | null>(null);\r\n \r\n // Mention menu state\r\n showMentionMenu = signal(false);\r\n mentionQuery = signal('');\r\n \r\n // Get available users to mention (post author + commenters)\r\n availableUsers = computed(() => {\r\n const post = this.post();\r\n const users: Array<{ name: string; initials: string; role: string }> = [];\r\n \r\n // Add post author\r\n users.push({\r\n name: post.authorName,\r\n initials: post.avatarInitials || post.authorName.split(' ').map(n => n[0]).join(''),\r\n role: post.authorRole\r\n });\r\n \r\n // Add unique commenters\r\n const commenterNames = new Set<string>();\r\n post.comments?.forEach(comment => {\r\n if (!commenterNames.has(comment.authorName)) {\r\n commenterNames.add(comment.authorName);\r\n users.push({\r\n name: comment.authorName,\r\n initials: comment.avatarInitials,\r\n role: comment.authorRole\r\n });\r\n }\r\n });\r\n \r\n return users;\r\n });\r\n \r\n // Filtered users based on mention query\r\n filteredUsers = computed(() => {\r\n const query = this.mentionQuery().toLowerCase();\r\n if (!query) return this.availableUsers();\r\n return this.availableUsers().filter(user => \r\n user.name.toLowerCase().includes(query)\r\n );\r\n });\r\n\r\n constructor(\r\n private modalController: ModalController,\r\n private lightbox: DsMobileLightboxService,\r\n private bottomSheet: DsMobileBottomSheetService\r\n ) {}\r\n\r\n ngOnInit(): void {\r\n // Initialize post data from input\r\n if (this.postData) {\r\n this.post.set(this.postData);\r\n }\r\n \r\n // Set up keyboard listeners to update CSS variable for composer positioning\r\n this.setupKeyboardListeners();\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n // Auto-focus comment input if requested\r\n if (this.postData?.focusComment) {\r\n // Small delay to ensure modal animation is complete\r\n setTimeout(() => {\r\n this.commentInput?.nativeElement.focus();\r\n // Show keyboard on mobile\r\n this.showKeyboard();\r\n }, 300);\r\n }\r\n }\r\n \r\n ngOnDestroy(): void {\r\n // Clean up keyboard listeners when modal is destroyed\r\n this.cleanupKeyboardListeners();\r\n }\r\n \r\n /**\r\n * Set up keyboard event listeners to adjust composer position\r\n * The CSS uses --keyboard-height variable to translate the composer up\r\n */\r\n private setupKeyboardListeners(): void {\r\n Keyboard.addListener('keyboardWillShow', (info) => {\r\n document.documentElement.style.setProperty('--keyboard-height', `${info.keyboardHeight}px`);\r\n }).catch(e => console.log('Keyboard listeners not available:', e));\r\n \r\n Keyboard.addListener('keyboardWillHide', () => {\r\n document.documentElement.style.setProperty('--keyboard-height', '0px');\r\n }).catch(e => console.log('Keyboard listeners not available:', e));\r\n }\r\n \r\n /**\r\n * Clean up keyboard event listeners\r\n */\r\n private cleanupKeyboardListeners(): void {\r\n Keyboard.removeAllListeners().catch(e => console.log('Keyboard cleanup not available:', e));\r\n }\r\n\r\n /**\r\n * Show the keyboard when user interacts with input\r\n */\r\n showKeyboard(): void {\r\n Keyboard.show().catch(e => console.log('Keyboard.show() not available'));\r\n }\r\n \r\n /**\r\n * Focus the comment input when comment icon is tapped\r\n */\r\n focusCommentInput(): void {\r\n // Focus the input\r\n this.commentInput?.nativeElement.focus();\r\n // Show keyboard on mobile\r\n this.showKeyboard();\r\n }\r\n \r\n /**\r\n * Handle input changes and detect @ mentions\r\n */\r\n handleInput(event: Event): void {\r\n const textarea = event.target as HTMLTextAreaElement;\r\n const text = textarea.value;\r\n const cursorPosition = textarea.selectionStart || 0;\r\n \r\n // Auto-resize textarea\r\n textarea.style.height = 'auto';\r\n textarea.style.height = textarea.scrollHeight + 'px';\r\n \r\n // Find the last @ before cursor\r\n const textBeforeCursor = text.substring(0, cursorPosition);\r\n const lastAtIndex = textBeforeCursor.lastIndexOf('@');\r\n \r\n if (lastAtIndex !== -1) {\r\n // Check if there's a space after @\r\n const textAfterAt = textBeforeCursor.substring(lastAtIndex + 1);\r\n const hasSpace = textAfterAt.includes(' ');\r\n \r\n if (!hasSpace) {\r\n // Show mention menu\r\n this.showMentionMenu.set(true);\r\n this.mentionQuery.set(textAfterAt);\r\n } else {\r\n this.showMentionMenu.set(false);\r\n }\r\n } else {\r\n this.showMentionMenu.set(false);\r\n }\r\n }\r\n \r\n /**\r\n * Select a user from mention menu - show as reply indicator instead of inline mention\r\n */\r\n selectMention(userName: string): void {\r\n // Set as reply (similar to clicking Reply on a comment)\r\n this.replyingTo.set({ authorName: userName, content: '' });\r\n \r\n // Clear the @ from the input\r\n const currentText = this.commentText();\r\n const textWithoutMention = currentText.substring(0, currentText.lastIndexOf('@'));\r\n this.commentText.set(textWithoutMention);\r\n \r\n // Hide mention menu\r\n this.showMentionMenu.set(false);\r\n \r\n // Focus back on input\r\n setTimeout(() => {\r\n this.commentInput?.nativeElement.focus();\r\n }, 0);\r\n }\r\n \r\n /**\r\n * Handle reply to a comment\r\n */\r\n handleReply(authorName: string, content: string): void {\r\n this.replyingTo.set({ authorName, content });\r\n // Focus the input and show keyboard\r\n setTimeout(() => {\r\n this.commentInput?.nativeElement.focus();\r\n this.showKeyboard();\r\n }, 100);\r\n }\r\n \r\n /**\r\n * Cancel reply\r\n */\r\n cancelReply(): void {\r\n this.replyingTo.set(null);\r\n }\r\n \r\n /**\r\n * Cancel edit\r\n */\r\n cancelEdit(): void {\r\n this.editingComment.set(null);\r\n this.commentText.set('');\r\n }\r\n \r\n /**\r\n * Handle edit comment\r\n */\r\n handleEditComment(authorName: string, originalContent: string, timestamp: string): void {\r\n // Clear reply state if active\r\n this.replyingTo.set(null);\r\n \r\n // Remove @mention from the content if it exists\r\n let contentToEdit = originalContent;\r\n const mentionMatch = originalContent.match(/^@([A-Za-z]+(?:\\s+[A-Za-z]+)?)\\s+/);\r\n if (mentionMatch) {\r\n contentToEdit = originalContent.substring(mentionMatch[0].length);\r\n }\r\n \r\n // Set edit state\r\n this.editingComment.set({ authorName, originalContent, timestamp });\r\n \r\n // Populate the input with existing content\r\n this.commentText.set(contentToEdit);\r\n \r\n // Focus the input, show keyboard, and auto-resize\r\n setTimeout(() => {\r\n if (this.commentInput?.nativeElement) {\r\n const textarea = this.commentInput.nativeElement;\r\n textarea.focus();\r\n \r\n // Auto-resize textarea to fit content\r\n textarea.style.height = 'auto';\r\n textarea.style.height = textarea.scrollHeight + 'px';\r\n \r\n this.showKeyboard();\r\n }\r\n }, 100);\r\n }\r\n\r\n /**\r\n * Close the modal\r\n */\r\n close(): void {\r\n this.modalController.dismiss();\r\n }\r\n\r\n /**\r\n * Submit a comment\r\n */\r\n submitComment(): void {\r\n const text = this.commentText().trim();\r\n if (!text) return;\r\n\r\n const currentPost = this.post();\r\n \r\n // Check if we're editing an existing comment\r\n if (this.editingComment()) {\r\n console.log('[PostDetailModal] Updating comment:', text);\r\n \r\n const editing = this.editingComment()!;\r\n \r\n // Update the existing comment\r\n const updatedComments = currentPost.comments?.map(comment => {\r\n if (comment.authorName === editing.authorName && \r\n comment.content === editing.originalContent &&\r\n comment.timestamp === editing.timestamp) {\r\n return {\r\n ...comment,\r\n content: text,\r\n timestamp: 'Just now (edited)'\r\n };\r\n }\r\n return comment;\r\n });\r\n \r\n this.post.set({\r\n ...currentPost,\r\n comments: updatedComments\r\n });\r\n \r\n // Clear edit state\r\n this.editingComment.set(null);\r\n } else {\r\n // Create new comment\r\n console.log('[PostDetailModal] Submitting comment:', text);\r\n \r\n const newComment: CommentData = {\r\n authorName: 'Lars Mikkelsen',\r\n authorRole: 'You',\r\n timestamp: 'Just now',\r\n avatarInitials: this.currentUserInitials(),\r\n content: this.replyingTo() \r\n ? `@${this.replyingTo()!.authorName} ${text}`\r\n : text,\r\n isLiked: false,\r\n likeCount: 0,\r\n isOwnComment: true\r\n };\r\n\r\n // Add comment to the list\r\n const updatedComments = [...(currentPost.comments || []), newComment];\r\n \r\n this.post.set({\r\n ...currentPost,\r\n comments: updatedComments,\r\n commentCount: updatedComments.length\r\n });\r\n \r\n // Clear reply state\r\n this.replyingTo.set(null);\r\n }\r\n\r\n // Clear the input\r\n this.commentText.set('');\r\n this.showMentionMenu.set(false);\r\n \r\n // Reset textarea height to initial state\r\n if (this.commentInput?.nativeElement) {\r\n this.commentInput.nativeElement.style.height = 'auto';\r\n }\r\n \r\n // Blur the input to hide the keyboard\r\n this.commentInput?.nativeElement.blur();\r\n \r\n // Hide keyboard explicitly\r\n Keyboard.hide().catch(e => console.log('Keyboard.hide() not available'));\r\n\r\n // In a real app, you would also send this to your backend\r\n // this.commentService.addComment(currentPost.postId, text);\r\n }\r\n\r\n /**\r\n * Open image in lightbox\r\n */\r\n openImageLightbox(): void {\r\n const postData = this.post();\r\n \r\n if (!postData.imageSrc) return;\r\n\r\n const authorMeta: LightboxAuthor = {\r\n name: postData.authorName,\r\n role: postData.authorRole,\r\n avatarInitials: postData.avatarInitials || '',\r\n avatarType: postData.avatarType || 'initials',\r\n avatarSrc: postData.avatarSrc || '',\r\n timestamp: postData.timestamp\r\n };\r\n\r\n this.lightbox.open({\r\n images: [\r\n {\r\n type: 'image',\r\n src: postData.imageSrc,\r\n alt: postData.imageAlt || 'Post image',\r\n title: postData.imageAlt || '',\r\n description: postData.content,\r\n isLiked: postData.isLiked || false,\r\n likeCount: postData.likeCount || 0,\r\n commentCount: postData.commentCount || 0\r\n }\r\n ],\r\n author: authorMeta,\r\n enableZoom: true,\r\n showControls: false,\r\n showInfo: true\r\n });\r\n }\r\n \r\n /**\r\n * Handle long press on a comment to show action sheet\r\n */\r\n async handleCommentLongPress(authorName: string, content: string, isOwnComment: boolean): Promise<void> {\r\n const sheet = await this.bottomSheet.create({\r\n component: DsMobileCommentActionsBottomSheetComponent,\r\n componentProps: {\r\n isOwnContent: isOwnComment\r\n },\r\n breakpoints: [0, 1],\r\n initialBreakpoint: 1,\r\n handle: true,\r\n backdropDismiss: true,\r\n cssClass: 'auto-height'\r\n });\r\n \r\n const result = await sheet.onWillDismiss();\r\n \r\n if (result.role === 'select' && result.data) {\r\n const action = (result.data as CommentActionResult).action;\r\n const currentPost = this.post();\r\n \r\n switch (action) {\r\n case 'like':\r\n console.log('Like comment by', authorName);\r\n // Find and toggle like on the comment\r\n const updatedComments = currentPost.comments?.map(comment => {\r\n if (comment.authorName === authorName && comment.content === content) {\r\n const isLiked = !comment.isLiked;\r\n return {\r\n ...comment,\r\n isLiked,\r\n likeCount: isLiked ? (comment.likeCount || 0) + 1 : Math.max(0, (comment.likeCount || 0) - 1)\r\n };\r\n }\r\n return comment;\r\n });\r\n this.post.set({ ...currentPost, comments: updatedComments });\r\n break;\r\n case 'reply':\r\n console.log('Reply to comment by', authorName);\r\n this.handleReply(authorName, content);\r\n break;\r\n case 'edit':\r\n console.log('Edit comment by', authorName);\r\n // Find the full comment data to get timestamp\r\n const commentToEdit = currentPost.comments?.find(\r\n comment => comment.authorName === authorName && comment.content === content\r\n );\r\n if (commentToEdit) {\r\n this.handleEditComment(authorName, content, commentToEdit.timestamp);\r\n }\r\n break;\r\n case 'delete':\r\n console.log('Delete comment by', authorName);\r\n // Show confirmation before deleting\r\n if (confirm('Are you sure you want to delete this comment?')) {\r\n const updatedCommentsAfterDelete = currentPost.comments?.filter(\r\n comment => !(comment.authorName === authorName && comment.content === content)\r\n );\r\n this.post.set({ \r\n ...currentPost, \r\n comments: updatedCommentsAfterDelete,\r\n commentCount: updatedCommentsAfterDelete?.length || 0\r\n });\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { DsMobilePostDetailModalComponent, PostDetailData } from './ds-mobile-post-detail-modal';\r\n\r\n/**\r\n * DsMobilePostDetailModalService\r\n * \r\n * Service for displaying post details in a full-screen modal.\r\n * Built on Ionic's modal system with native gestures and animations.\r\n * Follows the same pattern as DsMobileLightboxService for consistent behavior.\r\n * \r\n * Features:\r\n * - Full post content display\r\n * - Comments section\r\n * - Like/comment actions\r\n * - Image lightbox integration\r\n * - Native modal animations\r\n * - Safe area support\r\n * \r\n * @example\r\n * ```typescript\r\n * constructor(private postModal: DsMobilePostDetailModalService) {}\r\n * \r\n * async openPost() {\r\n * await this.postModal.open({\r\n * postId: '123',\r\n * authorName: 'John Doe',\r\n * authorRole: 'Tenant',\r\n * timestamp: '2h ago',\r\n * avatarInitials: 'JD',\r\n * content: 'Just moved into my new apartment!',\r\n * isLiked: false,\r\n * likeCount: 42,\r\n * commentCount: 12,\r\n * comments: [\r\n * {\r\n * authorName: 'Jane Smith',\r\n * authorRole: 'Tenant',\r\n * timestamp: '1h ago',\r\n * avatarInitials: 'JS',\r\n * content: 'Welcome to the community!'\r\n * }\r\n * ]\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class DsMobilePostDetailModalService {\r\n constructor(private modalController: ModalController) {}\r\n\r\n /**\r\n * Open the post detail modal\r\n * \r\n * @param postData Post data to display\r\n * @returns Promise that resolves when the modal is presented\r\n */\r\n async open(postData: PostDetailData): Promise<void> {\r\n console.log('[PostDetailModal] Opening with data:', postData);\r\n \r\n const modal = await this.modalController.create({\r\n component: DsMobilePostDetailModalComponent,\r\n componentProps: {\r\n postData: postData\r\n },\r\n cssClass: 'ds-post-detail-modal',\r\n mode: 'ios',\r\n presentingElement: document.querySelector('ion-router-outlet') || undefined,\r\n backdropDismiss: true,\r\n showBackdrop: true,\r\n animated: true,\r\n keyboardClose: true,\r\n // Control the presenting element animation\r\n enterAnimation: undefined, // Use default\r\n leaveAnimation: undefined // Use default\r\n });\r\n\r\n console.log('[PostDetailModal] Modal created, presenting...');\r\n await modal.present();\r\n console.log('[PostDetailModal] Modal presented');\r\n }\r\n\r\n /**\r\n * Close the currently open post detail modal\r\n * \r\n * @param data Optional data to pass back when dismissing\r\n * @returns Promise that resolves when the modal is dismissed\r\n */\r\n async close(data?: any): Promise<boolean> {\r\n return this.modalController.dismiss(data);\r\n }\r\n\r\n /**\r\n * Get the top-most modal if one exists\r\n * \r\n * @returns Promise that resolves to the modal element or undefined\r\n */\r\n async getTop(): Promise<HTMLIonModalElement | undefined> {\r\n return this.modalController.getTop();\r\n }\r\n}\r\n\r\n","/**\r\n * Mobile Post Detail Modal Module\r\n * \r\n * Service and component for displaying posts in a modal\r\n */\r\n\r\nexport * from './ds-mobile-post-detail-modal';\r\nexport * from './ds-mobile-post-detail-modal.service';\r\n\r\n","import { Component, Input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobileHandbookFolderMiniComponent\r\n * \r\n * A minimized folder icon component for use in headers and small spaces.\r\n * Simplified version without animations or page sheets - just folder and icon.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-handbook-folder-mini\r\n * [variant]=\"'pink'\"\r\n * [iconName]=\"'remixLightbulbLine'\">\r\n * </ds-mobile-handbook-folder-mini>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-handbook-folder-mini',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent],\r\n styles: [`\r\n :host {\r\n display: inline-block;\r\n width: 32px;\r\n height: 32px;\r\n flex-shrink: 0;\r\n }\r\n \r\n .mini-folder-container {\r\n position: relative;\r\n width: 100%;\r\n height: 100%;\r\n display: flex;\r\n flex-direction: column;\r\n }\r\n \r\n .mini-folder-tab {\r\n width: 50%;\r\n height: auto;\r\n display: block;\r\n }\r\n \r\n .mini-folder-back {\r\n height: 28px;\r\n border-radius: 0px 4px 4px 4px;\r\n position: relative;\r\n margin-top: -1px;\r\n }\r\n \r\n .mini-folder-front {\r\n position: absolute;\r\n bottom: 0;\r\n left: 0;\r\n right: 0;\r\n height: 24px;\r\n border-radius: 4px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n z-index: 2;\r\n box-shadow: inset 0 8px 8px rgba(255, 255, 255, 0.2), \r\n inset 0 0.5px 0.5px rgba(255, 255, 255, 0.3);\r\n }\r\n `],\r\n template: `\r\n <div class=\"mini-folder-container\">\r\n <!-- Folder Tab SVG -->\r\n <svg \r\n class=\"mini-folder-tab\" \r\n width=\"101\" \r\n height=\"24\" \r\n viewBox=\"0 0 101 24\" \r\n fill=\"none\" \r\n xmlns=\"http://www.w3.org/2000/svg\">\r\n <path \r\n d=\"M100.037 23.9999L100.5 24L0 24.0001V10.7646C0 4.80853 4.91797 -0.0234985 11 -0.0196688L66.4213 -0.0322266C69.3519 -0.0115886 72.197 1.20548 74.2473 3.29947L90.6765 20.0951C93.1218 22.5925 96.5417 23.9999 100.037 23.9999Z\" \r\n [attr.fill]=\"getColorVar('strong')\"/>\r\n </svg>\r\n \r\n <!-- Folder Back -->\r\n <div class=\"mini-folder-back\" [style.background-color]=\"getColorVar('strong')\">\r\n <!-- Folder Front -->\r\n <div \r\n class=\"mini-folder-front\" \r\n [style.background-color]=\"getColorVar('base')\">\r\n <ds-icon \r\n [name]=\"iconName\" \r\n [size]=\"'14px'\"\r\n [style.color]=\"'white'\" />\r\n </div>\r\n </div>\r\n </div>\r\n `\r\n})\r\nexport class DsMobileHandbookFolderMiniComponent {\r\n /**\r\n * Color variant for the folder\r\n * Available variants: success, warning, destructive, blue, light-purple, pink, salmon-orange, orange, lime-green, grey\r\n */\r\n @Input() variant: string = 'light-purple';\r\n \r\n /**\r\n * Icon name from the design system icon library\r\n */\r\n @Input() iconName: string = 'remixFolder3Line';\r\n \r\n /**\r\n * Get the CSS variable name for the color variant\r\n */\r\n getColorVar(suffix: 'base' | 'strong'): string {\r\n const variantMap: Record<string, string> = {\r\n 'success': 'success',\r\n 'warning': 'warning',\r\n 'destructive': 'destructive',\r\n 'blue': 'blue',\r\n 'light-purple': 'light-purple',\r\n 'pink': 'pink',\r\n 'salmon-orange': 'salmon-orange',\r\n 'orange': 'orange',\r\n 'lime-green': 'lime-green',\r\n 'grey': 'grey'\r\n };\r\n \r\n const colorName = variantMap[this.variant] || 'light-purple';\r\n return `var(--color-${colorName}-${suffix})`;\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobileFileAttachmentComponent\r\n * \r\n * File attachment display for various document types.\r\n * Shows file info card with icon, filename, and file size.\r\n * Supports PDF and generic document formats.\r\n * Emits click event to open file in viewer.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-file-attachment\r\n * [fileName]=\"'Document.pdf'\"\r\n * [fileSize]=\"'1.2 MB'\"\r\n * [variant]=\"'pdf'\"\r\n * (fileClick)=\"openFile()\">\r\n * </ds-mobile-file-attachment>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-file-attachment',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent, DsIconComponent],\r\n host: {\r\n '(click)': 'handleClick($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n padding: 10px 12px;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-radius: 16px;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n }\r\n \r\n :host:hover {\r\n background: var(--color-background-neutral-secondary-hover, #ebebeb);\r\n }\r\n \r\n :host:active {\r\n transform: scale(0.98);\r\n }\r\n \r\n .file-avatar {\r\n flex-shrink: 0;\r\n }\r\n \r\n .file-avatar.pdf::ng-deep .avatar--icon {\r\n background-color: #ff5757 !important;\r\n }\r\n \r\n .file-avatar.doc::ng-deep .avatar--icon {\r\n background-color: var(--color-blue-base, #3B82F6) !important;\r\n }\r\n \r\n .file-info {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 2px;\r\n }\r\n \r\n .file-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n .file-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--color-text-tertiary, #737373);\r\n }\r\n \r\n .open-icon {\r\n color: var(--color-text-tertiary, #a3a3a3);\r\n flex-shrink: 0;\r\n }\r\n `],\r\n template: `\r\n <div class=\"file-avatar\" [class.pdf]=\"variant() === 'pdf'\" [class.doc]=\"variant() === 'doc'\">\r\n <ds-avatar\r\n type=\"icon\"\r\n [iconName]=\"getIconName()\"\r\n size=\"md\"\r\n />\r\n </div>\r\n \r\n <div class=\"file-info\">\r\n <div class=\"file-name\">{{ fileName() }}</div>\r\n @if (fileSize()) {\r\n <div class=\"file-meta\">{{ getFileTypeLabel() }} · {{ fileSize() }}</div>\r\n } @else {\r\n <div class=\"file-meta\">{{ getFileTypeLabel() }}</div>\r\n }\r\n </div>\r\n \r\n <ds-icon \r\n name=\"remixArrowRightSLine\" \r\n size=\"20px\"\r\n class=\"open-icon\"\r\n />\r\n `\r\n})\r\nexport class DsMobileFileAttachmentComponent {\r\n /**\r\n * File name\r\n */\r\n fileName = input<string>('Document');\r\n \r\n /**\r\n * File size display (e.g., \"1.2 MB\")\r\n */\r\n fileSize = input<string>('');\r\n \r\n /**\r\n * File type variant\r\n * - 'pdf' - PDF document (red icon)\r\n * - 'doc' - Generic document (blue icon)\r\n */\r\n variant = input<'pdf' | 'doc'>('doc');\r\n \r\n /**\r\n * Emits when the file attachment is clicked\r\n */\r\n fileClick = output<void>();\r\n \r\n /**\r\n * Get the appropriate icon name based on variant\r\n */\r\n getIconName(): string {\r\n return this.variant() === 'pdf' ? 'remixFileTextLine' : 'remixAttachmentLine';\r\n }\r\n \r\n /**\r\n * Get the file type label based on variant\r\n */\r\n getFileTypeLabel(): string {\r\n return this.variant() === 'pdf' ? 'PDF' : 'DOC';\r\n }\r\n \r\n handleClick(event: Event): void {\r\n event.stopPropagation();\r\n this.fileClick.emit();\r\n }\r\n}\r\n\r\n","import {\r\n Component,\r\n input,\r\n AfterViewInit,\r\n OnDestroy,\r\n ElementRef,\r\n ViewChild,\r\n CUSTOM_ELEMENTS_SCHEMA\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport Swiper from 'swiper';\r\n\r\n/**\r\n * DsMobileSwiperComponent\r\n * \r\n * A reusable swiper/carousel component with configurable child width and spacing.\r\n * \r\n * Features:\r\n * - First slide is left-aligned\r\n * - Middle slides are centered when active\r\n * - Last slide is right-aligned\r\n * - Configurable slide width and gap\r\n * - Content projection via ng-content\r\n * \r\n * Usage:\r\n * ```html\r\n * <ds-mobile-swiper [slideWidth]=\"'75vw'\" [gap]=\"16\">\r\n * <div class=\"swiper-slide\">Slide 1</div>\r\n * <div class=\"swiper-slide\">Slide 2</div>\r\n * <div class=\"swiper-slide\">Slide 3</div>\r\n * </ds-mobile-swiper>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-swiper',\r\n standalone: true,\r\n imports: [CommonModule],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n template: `\r\n <div class=\"swiper-container\" #swiperContainer>\r\n <div class=\"swiper-wrapper\">\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n display: block;\r\n width: 100%;\r\n }\r\n\r\n .swiper-container {\r\n width: 100%;\r\n position: relative;\r\n overflow: hidden;\r\n border-radius: 12px;\r\n }\r\n\r\n .swiper-wrapper {\r\n display: flex;\r\n transition-property: transform;\r\n box-sizing: content-box;\r\n }\r\n\r\n :host ::ng-deep .swiper-slide {\r\n flex-shrink: 0;\r\n height: 100%;\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n `]\r\n})\r\nexport class DsMobileSwiperComponent implements AfterViewInit, OnDestroy {\r\n /**\r\n * Width of each slide (e.g., '75vw', '300px', '80%')\r\n */\r\n slideWidth = input<string>('75vw');\r\n\r\n /**\r\n * Gap between slides in pixels\r\n */\r\n gap = input<number>(16);\r\n\r\n @ViewChild('swiperContainer', { static: false }) swiperContainer!: ElementRef;\r\n\r\n private swiperInstance: Swiper | null = null;\r\n\r\n ngAfterViewInit(): void {\r\n setTimeout(() => {\r\n this.initializeSwiper();\r\n }, 100);\r\n }\r\n\r\n private initializeSwiper(): void {\r\n if (!this.swiperContainer) return;\r\n\r\n // Apply slide width to all slides\r\n const slides = this.swiperContainer.nativeElement.querySelectorAll('.swiper-slide');\r\n slides.forEach((slide: HTMLElement) => {\r\n slide.style.width = this.slideWidth();\r\n });\r\n\r\n this.swiperInstance = new Swiper(this.swiperContainer.nativeElement, {\r\n slidesPerView: 'auto',\r\n spaceBetween: this.gap(),\r\n centeredSlides: true,\r\n centeredSlidesBounds: true,\r\n speed: 300,\r\n resistance: true,\r\n resistanceRatio: 0.85,\r\n });\r\n }\r\n\r\n ngOnDestroy(): void {\r\n if (this.swiperInstance) {\r\n this.swiperInstance.destroy();\r\n this.swiperInstance = null;\r\n }\r\n }\r\n}\r\n\r\n","import {\r\n Component,\r\n signal,\r\n Input,\r\n CUSTOM_ELEMENTS_SCHEMA\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport {\r\n IonContent,\r\n ModalController\r\n} from '@ionic/angular/standalone';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { DsMobileHandbookFolderMiniComponent } from '../handbook-folder/ds-mobile-handbook-folder-mini';\r\nimport { DsMobileFileAttachmentComponent } from '../file-attachment';\r\nimport { DsMobileContactListItemComponent } from '../contact-list-item';\r\nimport { DsMobileSwiperComponent } from '../swiper';\r\n\r\n/**\r\n * Handbook detail data interface\r\n */\r\nexport interface HandbookDetailData {\r\n title: string;\r\n variant: string;\r\n iconName: string;\r\n itemCount: number;\r\n items?: HandbookItem[];\r\n}\r\n\r\nexport interface HandbookItem {\r\n title: string;\r\n description?: string;\r\n images?: string[];\r\n attachments?: AttachmentItem[];\r\n contacts?: ContactItem[];\r\n}\r\n\r\nexport interface AttachmentItem {\r\n name: string;\r\n type?: string;\r\n}\r\n\r\nexport interface ContactItem {\r\n name: string;\r\n initials: string;\r\n contactPerson?: string;\r\n phoneNumber?: string;\r\n}\r\n\r\n/**\r\n * DsMobileHandbookDetailModalComponent\r\n * \r\n * Modal wrapper for displaying handbook folder details.\r\n * \r\n * Features:\r\n * - Folder content display\r\n * - Items list with descriptions\r\n * - Images and attachments\r\n * - Contact information\r\n * - Native modal controls (close, swipe down)\r\n * - Safe area support\r\n * \r\n * This component is typically not used directly - use DsMobileHandbookDetailModalService instead.\r\n */\r\n@Component({\r\n selector: 'ds-mobile-handbook-detail-modal',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonContent,\r\n DsIconButtonComponent,\r\n DsMobileHandbookFolderMiniComponent,\r\n DsMobileFileAttachmentComponent,\r\n DsMobileContactListItemComponent,\r\n DsMobileSwiperComponent\r\n ],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n template: `\r\n <ion-content [fullscreen]=\"true\" [scrollY]=\"true\" class=\"handbook-modal-content\">\r\n <div class=\"handbook-modal-wrapper\">\r\n <!-- Header -->\r\n <div class=\"handbook-modal-header\">\r\n <div class=\"header-content\">\r\n <!-- Handbook folder info -->\r\n <div class=\"handbook-folder-info\">\r\n <ds-mobile-handbook-folder-mini\r\n [variant]=\"handbook().variant\"\r\n [iconName]=\"handbook().iconName\">\r\n </ds-mobile-handbook-folder-mini>\r\n <div class=\"folder-details\">\r\n <div class=\"folder-name\">{{ handbook().title }}</div>\r\n <div class=\"folder-meta\">\r\n <span>{{ handbook().itemCount }} emner</span>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Close button -->\r\n <ds-icon-button\r\n icon=\"remixCloseLine\"\r\n variant=\"secondary\"\r\n size=\"lg\"\r\n (click)=\"close()\"\r\n class=\"close-button\"\r\n aria-label=\"Luk\">\r\n </ds-icon-button>\r\n </div>\r\n </div>\r\n\r\n <!-- Content -->\r\n <div class=\"handbook-detail-container\">\r\n @if (handbook().items && handbook().items!.length > 0) {\r\n @for (item of getDisplayItems(); track item.title + $index; let isLast = $last) {\r\n <div class=\"handbook-item\" [class.last-item]=\"isLast\">\r\n <div class=\"item-text-group\">\r\n <h2 class=\"item-title\">{{ item.title }}</h2>\r\n \r\n @if (item.description) {\r\n <p class=\"item-description\">{{ item.description }}</p>\r\n }\r\n </div>\r\n \r\n <!-- Images -->\r\n @if (item.images && item.images.length > 0) {\r\n <ds-mobile-swiper [slideWidth]=\"item.images.length === 1 ? '100%' : '60vw'\" [gap]=\"16\">\r\n @for (image of item.images; track image) {\r\n <div class=\"swiper-slide\">\r\n <img \r\n [src]=\"image\" \r\n [alt]=\"item.title\"\r\n class=\"item-image\"\r\n />\r\n </div>\r\n }\r\n </ds-mobile-swiper>\r\n }\r\n \r\n <!-- Contacts -->\r\n @if (item.contacts && item.contacts.length > 0) {\r\n <div class=\"contacts-list\">\r\n @for (contact of item.contacts; track contact.name) {\r\n <ds-mobile-contact-list-item\r\n [name]=\"contact.name\"\r\n [initials]=\"contact.initials\"\r\n [contactPerson]=\"contact.contactPerson || ''\"\r\n [phoneNumber]=\"contact.phoneNumber || ''\"\r\n [clickable]=\"true\"\r\n (contactClick)=\"handleContactClick(contact)\">\r\n </ds-mobile-contact-list-item>\r\n }\r\n </div>\r\n }\r\n \r\n <!-- Attachments -->\r\n @if (item.attachments && item.attachments.length > 0) {\r\n <div class=\"attachments-list\">\r\n @for (attachment of item.attachments; track attachment.name) {\r\n <ds-mobile-file-attachment\r\n [fileName]=\"attachment.name\"\r\n [variant]=\"attachment.type === 'pdf' ? 'pdf' : 'doc'\"\r\n (fileClick)=\"handleAttachmentClick(attachment)\">\r\n </ds-mobile-file-attachment>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n } @else {\r\n <!-- Empty State -->\r\n <div class=\"handbook-empty-state\">\r\n <img \r\n src=\"/Assets/Empty state-chat.png\" \r\n alt=\"No items yet\" \r\n class=\"empty-state-image\"\r\n />\r\n <h3 class=\"empty-state-title\">No items yet</h3>\r\n <p class=\"empty-state-description\">This folder is empty</p>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </ion-content>\r\n `,\r\n styles: [`\r\n .handbook-modal-content {\r\n --background: var(--color-background-neutral-primary, #ffffff);\r\n }\r\n\r\n .handbook-modal-wrapper {\r\n display: flex;\r\n flex-direction: column;\r\n min-height: 100%;\r\n min-height: 100dvh;\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n }\r\n\r\n .handbook-modal-header {\r\n position: sticky;\r\n top: 0;\r\n z-index: 10;\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n border-bottom: 1px solid var(--border-color-default);\r\n padding: 0 16px;\r\n }\r\n\r\n .header-content {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 12px;\r\n min-height: 72px;\r\n }\r\n\r\n .handbook-folder-info {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n\r\n .folder-details {\r\n display: flex;\r\n flex-direction: column;\r\n min-width: 0;\r\n flex: 1;\r\n }\r\n\r\n .folder-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n\r\n .folder-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--color-text-tertiary, #737373);\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n }\r\n\r\n .close-button {\r\n flex-shrink: 0;\r\n border-radius: 50%;\r\n }\r\n \r\n .close-button::ng-deep button {\r\n border-radius: 50% !important;\r\n width: 36px !important;\r\n height: 36px !important;\r\n min-width: 36px !important;\r\n min-height: 36px !important;\r\n padding: 0 !important;\r\n display: flex !important;\r\n align-items: center !important;\r\n justify-content: center !important;\r\n }\r\n\r\n .handbook-detail-container {\r\n display: flex;\r\n flex-direction: column;\r\n width: 100%;\r\n max-width: 640px;\r\n margin: 0 auto;\r\n flex: 1;\r\n }\r\n \r\n .handbook-item {\r\n width: 100%;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 24px;\r\n padding: 24px 20px 24px 20px;\r\n border-bottom: 1px solid var(--border-color-default);\r\n }\r\n \r\n .handbook-item.last-item {\r\n border-bottom: none;\r\n }\r\n\r\n .item-text-group {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n }\r\n\r\n .item-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: 16px;\r\n font-weight: 600;\r\n line-height: 24px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n margin: 0;\r\n }\r\n\r\n .item-description {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n line-height: 20px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n margin: 0;\r\n }\r\n\r\n .item-image {\r\n width: 100%;\r\n height: 280px;\r\n object-fit: cover;\r\n border-radius: 12px;\r\n display: block;\r\n }\r\n\r\n .contacts-list {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 0;\r\n }\r\n \r\n .contacts-list ds-mobile-contact-list-item:not(:last-child) {\r\n position: relative;\r\n padding-bottom: 8px;\r\n }\r\n \r\n .contacts-list ds-mobile-contact-list-item:not(:first-child) {\r\n padding-top: 8px;\r\n }\r\n \r\n .contacts-list ds-mobile-contact-list-item:not(:last-child)::after {\r\n content: '';\r\n position: absolute;\r\n bottom: 0;\r\n left: 44px;\r\n right: 0;\r\n height: 1px;\r\n background: var(--border-color-default);\r\n }\r\n \r\n \r\n .attachments-list {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 4px;\r\n }\r\n \r\n\r\n /* Empty State */\r\n .handbook-empty-state {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 60px 20px;\r\n text-align: center;\r\n }\r\n \r\n .empty-state-image {\r\n width: 96px;\r\n height: 96px;\r\n }\r\n \r\n .empty-state-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n line-height: 1.3;\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n .empty-state-description {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 1.4;\r\n color: var(--color-text-secondary, #737373);\r\n }\r\n\r\n /* Safe area support */\r\n @supports (padding: env(safe-area-inset-bottom)) {\r\n .handbook-detail-container {\r\n padding-bottom: calc(20px + env(safe-area-inset-bottom));\r\n }\r\n }\r\n `]\r\n})\r\nexport class DsMobileHandbookDetailModalComponent {\r\n // Handbook data passed from service\r\n @Input() handbookData!: HandbookDetailData;\r\n \r\n // Signal for reactive handbook data\r\n handbook = signal<HandbookDetailData>({\r\n title: '',\r\n variant: 'light-purple',\r\n iconName: 'remixFolder3Line',\r\n itemCount: 0,\r\n items: []\r\n });\r\n\r\n constructor(\r\n private modalController: ModalController\r\n ) {}\r\n\r\n ngOnInit(): void {\r\n // Initialize handbook data from input\r\n if (this.handbookData) {\r\n this.handbook.set(this.handbookData);\r\n }\r\n }\r\n\r\n /**\r\n * Split handbook items to enforce content structure rules:\r\n * - Never mix photos and documents (attachments) in the same section\r\n * - Never mix contact persons and attachments together in the same section\r\n * \r\n * This method splits items that violate these rules into multiple display items.\r\n * Each resulting item will have only compatible content types.\r\n */\r\n splitItemsByContentRules(item: HandbookItem): HandbookItem[] {\r\n const displayItems: HandbookItem[] = [];\r\n \r\n const hasImages = item.images && item.images.length > 0;\r\n const hasContacts = item.contacts && item.contacts.length > 0;\r\n const hasAttachments = item.attachments && item.attachments.length > 0;\r\n \r\n // Case 1: Only one type of content - keep as is\r\n const contentTypeCount = [hasImages, hasContacts, hasAttachments].filter(Boolean).length;\r\n if (contentTypeCount <= 1) {\r\n return [item];\r\n }\r\n \r\n // Case 2: Has images + contacts (allowed together) but no attachments\r\n if (hasImages && hasContacts && !hasAttachments) {\r\n return [item];\r\n }\r\n \r\n // Case 3: Violates rules - need to split\r\n \r\n // First item: Text + Images (if present)\r\n if (hasImages) {\r\n displayItems.push({\r\n title: item.title,\r\n description: item.description,\r\n images: item.images\r\n });\r\n }\r\n \r\n // Second item: Text + Contacts (if present and no images shown yet)\r\n if (hasContacts) {\r\n displayItems.push({\r\n title: item.title,\r\n description: hasImages ? undefined : item.description, // Only show description if not shown before\r\n contacts: item.contacts\r\n });\r\n }\r\n \r\n // Third item: Text + Attachments (if present)\r\n if (hasAttachments) {\r\n displayItems.push({\r\n title: item.title,\r\n description: (!hasImages && !hasContacts) ? item.description : undefined, // Only show description if not shown before\r\n attachments: item.attachments\r\n });\r\n }\r\n \r\n return displayItems;\r\n }\r\n \r\n /**\r\n * Get all display items with enforced content structure rules applied\r\n */\r\n getDisplayItems(): HandbookItem[] {\r\n const items = this.handbook().items || [];\r\n const displayItems: HandbookItem[] = [];\r\n \r\n for (const item of items) {\r\n const splitItems = this.splitItemsByContentRules(item);\r\n displayItems.push(...splitItems);\r\n }\r\n \r\n return displayItems;\r\n }\r\n\r\n /**\r\n * Close the modal\r\n */\r\n close(): void {\r\n this.modalController.dismiss();\r\n }\r\n \r\n /**\r\n * Handle contact click\r\n */\r\n handleContactClick(contact: ContactItem): void {\r\n console.log('Contact clicked:', contact);\r\n // Implement contact action (e.g., show contact details, call, etc.)\r\n }\r\n \r\n /**\r\n * Handle attachment click\r\n */\r\n handleAttachmentClick(attachment: AttachmentItem): void {\r\n console.log('Attachment clicked:', attachment);\r\n // Implement attachment action (e.g., open file viewer, download, etc.)\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { DsMobileHandbookDetailModalComponent, HandbookDetailData } from './ds-mobile-handbook-detail-modal';\r\n\r\n/**\r\n * DsMobileHandbookDetailModalService\r\n * \r\n * Service for displaying handbook folder details in a full-screen modal.\r\n * Built on Ionic's modal system with native gestures and animations.\r\n * \r\n * Features:\r\n * - Full handbook content display\r\n * - Items list with descriptions\r\n * - Images and attachments\r\n * - Contact information\r\n * - Native modal animations\r\n * - Safe area support\r\n * \r\n * @example\r\n * ```typescript\r\n * constructor(private handbookModal: DsMobileHandbookDetailModalService) {}\r\n * \r\n * async openHandbook() {\r\n * await this.handbookModal.open({\r\n * title: 'Utilities',\r\n * variant: 'pink',\r\n * iconName: 'remixLightbulbLine',\r\n * itemCount: 8,\r\n * items: [\r\n * {\r\n * title: 'Hjertestarter',\r\n * description: 'Installed on the 4th floor...',\r\n * images: ['/path/to/image.jpg'],\r\n * contacts: [\r\n * { name: 'Mortensen & Søn ApS', initials: 'M' }\r\n * ]\r\n * }\r\n * ]\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class DsMobileHandbookDetailModalService {\r\n constructor(private modalController: ModalController) {}\r\n\r\n /**\r\n * Open the handbook detail modal\r\n * \r\n * @param handbookData Handbook data to display\r\n * @returns Promise that resolves when the modal is presented\r\n */\r\n async open(handbookData: HandbookDetailData): Promise<void> {\r\n console.log('[HandbookDetailModal] Opening with data:', handbookData);\r\n \r\n const modal = await this.modalController.create({\r\n component: DsMobileHandbookDetailModalComponent,\r\n componentProps: {\r\n handbookData: handbookData\r\n },\r\n cssClass: 'ds-handbook-detail-modal',\r\n mode: 'ios',\r\n presentingElement: document.querySelector('ion-router-outlet') || undefined,\r\n backdropDismiss: true,\r\n showBackdrop: true,\r\n animated: true,\r\n keyboardClose: true,\r\n enterAnimation: undefined,\r\n leaveAnimation: undefined\r\n });\r\n\r\n console.log('[HandbookDetailModal] Modal created, presenting...');\r\n await modal.present();\r\n console.log('[HandbookDetailModal] Modal presented');\r\n }\r\n\r\n /**\r\n * Close the currently open handbook detail modal\r\n * \r\n * @param data Optional data to pass back when dismissing\r\n * @returns Promise that resolves when the modal is dismissed\r\n */\r\n async close(data?: any): Promise<boolean> {\r\n return this.modalController.dismiss(data);\r\n }\r\n\r\n /**\r\n * Get the top-most modal if one exists\r\n * \r\n * @returns Promise that resolves to the modal element or undefined\r\n */\r\n async getTop(): Promise<HTMLIonModalElement | undefined> {\r\n return this.modalController.getTop();\r\n }\r\n}\r\n\r\n","import { Component, Input, signal, HostListener } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsMobileHandbookDetailModalService, HandbookDetailData, HandbookItem } from '../handbook-detail-modal';\r\n\r\n/**\r\n * DsMobileHandbookFolderComponent\r\n * \r\n * A visually rich folder component for displaying handbook categories or sections.\r\n * Features a two-layer folder design with customizable colors, icon, item count, and label.\r\n * \r\n * Design Details:\r\n * - Folder back: 72px height with a decorative notch\r\n * - Folder front: 64px height overlaying the back\r\n * - Item count displayed in bottom-left corner\r\n * - Icon displayed in bottom-right corner\r\n * - Label text centered below the folder\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-handbook-folder\r\n * [colorBase]=\"'#d244cf'\"\r\n * [colorWeak]=\"'#f9e6f9'\"\r\n * [iconName]=\"'remixLightbulbLine'\"\r\n * [itemCount]=\"8\"\r\n * [label]=\"'Utilities'\">\r\n * </ds-mobile-handbook-folder>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-handbook-folder',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent],\r\n styles: [`\r\n :host {\r\n display: inline-flex;\r\n flex-direction: column;\r\n align-items: center;\r\n gap: 16px;\r\n cursor: pointer;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n padding: 16px;\r\n border-radius: 16px;\r\n background: var(--color-background-neutral-secondary, #f0f0f0);\r\n transition: background 0.2s ease;\r\n }\r\n \r\n :host:active {\r\n background: var(--color-background-neutral-secondary-hover, #ebebeb);\r\n }\r\n \r\n @media (hover: hover) {\r\n :host:hover {\r\n background: var(--color-background-neutral-secondary-hover, #ebebeb);\r\n }\r\n }\r\n \r\n .folder-container {\r\n position: relative;\r\n width: 100%;\r\n display: flex;\r\n flex-direction: column;\r\n perspective: 800px;\r\n -webkit-perspective: 800px;\r\n max-width: 160px;\r\n /* Safari optimization: Ensure proper 3D rendering context */\r\n transform-style: preserve-3d;\r\n -webkit-transform-style: preserve-3d;\r\n }\r\n \r\n .folder-container.open .page-sheet {\r\n -webkit-transform: translateY(-8px);\r\n transform: translateY(-8px);\r\n transition-delay: 0.2s;\r\n }\r\n \r\n .folder-container.open .page-sheet:nth-child(1) {\r\n -webkit-transform: scale(1) translateY(-8px) rotateX(-45deg) translateZ(0.1px);\r\n transform: scale(1) translateY(-8px) rotateX(-45deg) translateZ(0.1px);\r\n }\r\n \r\n .folder-container.open .page-sheet:nth-child(2) {\r\n -webkit-transform: scale(0.98) translateY(-12px) rotateX(-36deg) translateZ(0.1px);\r\n transform: scale(0.98) translateY(-12px) rotateX(-36deg) translateZ(0.1px);\r\n }\r\n \r\n .folder-container.open .page-sheet:nth-child(3) {\r\n -webkit-transform: scale(0.96) translateY(-16px) rotateX(-27deg) translateZ(0.1px);\r\n transform: scale(0.96) translateY(-16px) rotateX(-27deg) translateZ(0.1px);\r\n }\r\n \r\n .folder-container.open .page-sheet:nth-child(4) {\r\n -webkit-transform: scale(0.94) translateY(-20px) rotateX(-18deg) translateZ(0.1px);\r\n transform: scale(0.94) translateY(-20px) rotateX(-18deg) translateZ(0.1px);\r\n }\r\n \r\n .folder-container.open .page-sheet:nth-child(5) {\r\n -webkit-transform: scale(0.92) translateY(-24px) rotateX(-9deg) translateZ(0.1px);\r\n transform: scale(0.92) translateY(-24px) rotateX(-9deg) translateZ(0.1px);\r\n }\r\n \r\n .folder-container.open .page-sheet:nth-child(6) {\r\n -webkit-transform: scale(0.90) translateY(-28px) rotateX(0deg) translateZ(0.1px);\r\n transform: scale(0.90) translateY(-28px) rotateX(0.1px);\r\n }\r\n \r\n .folder-container.open .folder-front {\r\n -webkit-transform: translate3d(0, 0, 0) rotateX(-45deg);\r\n transform: translate3d(0, 0, 0) rotateX(-45deg);\r\n }\r\n \r\n .folder-tab {\r\n width: 50%;\r\n height: auto;\r\n display: block;\r\n }\r\n \r\n .folder-back {\r\n height: 128px;\r\n border-radius: 0px 12px 12px 12px;\r\n position: relative;\r\n margin-top: -1px;\r\n transform-style: preserve-3d;\r\n -webkit-transform-style: preserve-3d;\r\n backface-visibility: hidden;\r\n -webkit-backface-visibility: hidden;\r\n /* Safari optimization: Force GPU acceleration */\r\n -webkit-transform: translateZ(0);\r\n transform: translateZ(0);\r\n }\r\n \r\n .page-sheet {\r\n position: absolute;\r\n width: 80%;\r\n height: 120px;\r\n background: #ffffff;\r\n border-radius: 8px;\r\n box-shadow: 0 -1px 5px rgba(0, 0, 0, 0.1);\r\n border: 1px solid var(--border-color-default);\r\n transition: transform 0.3s ease-out;\r\n -webkit-transition: -webkit-transform 0.3s ease-out;\r\n left: 10%;\r\n /* Safari optimization: Force hardware acceleration and proper 3D rendering */\r\n -webkit-transform: translateZ(0);\r\n transform: translateZ(0);\r\n transform-style: preserve-3d;\r\n -webkit-transform-style: preserve-3d;\r\n backface-visibility: hidden;\r\n -webkit-backface-visibility: hidden;\r\n /* Safari optimization: Prevent subpixel rendering issues */\r\n -webkit-font-smoothing: antialiased;\r\n /* Safari optimization: Ensure proper layer creation */\r\n will-change: transform;\r\n }\r\n \r\n .page-sheet:nth-child(1) {\r\n bottom: 2px;\r\n z-index: 6;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n -webkit-transform: scale(1) translateZ(0.1px);\r\n transform: scale(1) translateZ(0.1px);\r\n }\r\n \r\n .page-sheet:nth-child(2) {\r\n bottom: 8px;\r\n z-index: 5;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n -webkit-transform: scale(0.98) translateZ(0.1px);\r\n transform: scale(0.98) translateZ(0.1px);\r\n }\r\n \r\n .page-sheet:nth-child(3) {\r\n bottom: 14px;\r\n z-index: 4;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n -webkit-transform: scale(0.96) translateZ(0.1px);\r\n transform: scale(0.96) translateZ(0.1px);\r\n }\r\n \r\n .page-sheet:nth-child(4) {\r\n bottom: 20px;\r\n z-index: 3;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n -webkit-transform: scale(0.94) translateZ(0.1px);\r\n transform: scale(0.94) translateZ(0.1px);\r\n }\r\n \r\n .page-sheet:nth-child(5) {\r\n bottom: 26px;\r\n z-index: 2;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n -webkit-transform: scale(0.92) translateZ(0.1px);\r\n transform: scale(0.92) translateZ(0.1px);\r\n }\r\n \r\n .page-sheet:nth-child(6) {\r\n bottom: 32px;\r\n z-index: 1;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n -webkit-transform: scale(0.90) translateZ(0.1px);\r\n transform: scale(0.90) translateZ(0.1px);\r\n }\r\n \r\n .folder-front {\r\n position: absolute;\r\n bottom: 0;\r\n left: 0;\r\n right: 0;\r\n height: 116px;\r\n border-radius: 12px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 8px;\r\n z-index: 2;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n transform-style: preserve-3d;\r\n -webkit-transform-style: preserve-3d;\r\n transition: transform 0.4s ease-in-out, -webkit-transform 0.4s ease-in-out;\r\n -webkit-transition: -webkit-transform 0.4s ease-in-out;\r\n will-change: transform;\r\n backface-visibility: hidden;\r\n -webkit-backface-visibility: hidden;\r\n -webkit-font-smoothing: antialiased;\r\n /* Safari optimization: Use more specific transform to avoid render glitches */\r\n -webkit-transform: rotateX(-20deg) translateZ(0.1px);\r\n transform: rotateX(-20deg) translateZ(0.1px);\r\n /* Safari optimization: Force layer creation for smoother animations */\r\n -webkit-transform: translate3d(0, 0, 0) rotateX(-20deg);\r\n transform: translate3d(0, 0, 0) rotateX(-20deg);\r\n box-shadow: inset 0 64px 48px rgba(255, 255, 255, 0.2), \r\n inset 0 2px 4px rgba(255, 255, 255, 0.3),\r\n inset 0 1px 1px rgba(255, 255, 255, 0.3);\r\n }\r\n \r\n .item-count {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n }\r\n \r\n .item-count-label {\r\n letter-spacing: 0.5px;\r\n }\r\n \r\n .folder-icon {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n .folder-label-container {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n gap: 4px;\r\n }\r\n \r\n .folder-label {\r\n text-align: center;\r\n }\r\n `],\r\n template: `\r\n <div class=\"folder-container\" \r\n [class.open]=\"isOpen()\">\r\n <!-- Folder Tab SVG -->\r\n <svg \r\n class=\"folder-tab\" \r\n width=\"101\" \r\n height=\"24\" \r\n viewBox=\"0 0 101 24\" \r\n fill=\"none\" \r\n xmlns=\"http://www.w3.org/2000/svg\">\r\n <path \r\n d=\"M100.037 23.9999L100.5 24L0 24.0001V10.7646C0 4.80853 4.91797 -0.0234985 11 -0.0196688L66.4213 -0.0322266C69.3519 -0.0115886 72.197 1.20548 74.2473 3.29947L90.6765 20.0951C93.1218 22.5925 96.5417 23.9999 100.037 23.9999Z\" \r\n [attr.fill]=\"getColorVar('strong')\"/>\r\n </svg>\r\n \r\n <!-- Folder Back -->\r\n <div class=\"folder-back\" [style.background-color]=\"getColorVar('strong')\">\r\n <!-- Page Sheets -->\r\n @for (sheet of getPageSheets(); track $index) {\r\n <div class=\"page-sheet\"></div>\r\n }\r\n \r\n <!-- Folder Front -->\r\n <div \r\n class=\"folder-front\" \r\n [style.--border-color]=\"getColorVar('strong')\"\r\n [style.background-color]=\"getColorVar('base')\">\r\n <!-- Icon (Centered) -->\r\n <div class=\"folder-icon\">\r\n <ds-icon \r\n [name]=\"iconName\" \r\n [size]=\"'32px'\"\r\n [style.color]=\"'white'\" />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Label and Item Count -->\r\n <div class=\"folder-label-container\">\r\n <div class=\"folder-label ui-sm-semiBold\">{{ label }}</div>\r\n <div class=\"item-count ui-sm-regular\" [style.color]=\"'var(--color-text-secondary, #6b7280)'\">\r\n <span>{{ itemCount }}</span>\r\n <span class=\"item-count-label\">emner</span>\r\n </div>\r\n </div>\r\n `\r\n})\r\nexport class DsMobileHandbookFolderComponent {\r\n /**\r\n * Color variant for the folder\r\n * Available variants: success, warning, destructive, blue, light-purple, pink, salmon-orange, orange, lime-green, grey\r\n * Example: 'pink', 'success', 'blue'\r\n */\r\n @Input() variant: string = 'light-purple';\r\n \r\n /**\r\n * Icon name from the design system icon library\r\n * Example: 'remixLightbulbLine', 'remixFolder3Line'\r\n */\r\n @Input() iconName: string = 'remixFolder3Line';\r\n \r\n /**\r\n * Number of items in the folder\r\n */\r\n @Input() itemCount: number = 0;\r\n \r\n /**\r\n * Label text displayed below the folder\r\n */\r\n @Input() label: string = 'Folder';\r\n \r\n /**\r\n * Optional items data for the handbook folder\r\n */\r\n @Input() items?: HandbookItem[];\r\n \r\n /**\r\n * Track open/closed state for animation\r\n */\r\n isOpen = signal(false);\r\n \r\n /**\r\n * Get the CSS variable name for the color variant\r\n */\r\n getColorVar(suffix: 'base' | 'strong'): string {\r\n const variantMap: Record<string, string> = {\r\n 'success': 'success',\r\n 'warning': 'warning',\r\n 'destructive': 'destructive',\r\n 'blue': 'blue',\r\n 'light-purple': 'light-purple',\r\n 'pink': 'pink',\r\n 'salmon-orange': 'salmon-orange',\r\n 'orange': 'orange',\r\n 'lime-green': 'lime-green',\r\n 'grey': 'grey'\r\n };\r\n \r\n const colorName = variantMap[this.variant] || 'light-purple';\r\n return `var(--color-${colorName}-${suffix})`;\r\n }\r\n \r\n /**\r\n * Open folder animation\r\n */\r\n @HostListener('mouseenter')\r\n open(): void {\r\n this.isOpen.set(true);\r\n }\r\n \r\n /**\r\n * Close folder animation\r\n */\r\n @HostListener('mouseleave')\r\n close(): void {\r\n this.isOpen.set(false);\r\n }\r\n \r\n /**\r\n * Handle touch start - open animation\r\n */\r\n @HostListener('touchstart', ['$event'])\r\n onTouchStart(event: TouchEvent): void {\r\n this.isOpen.set(true);\r\n }\r\n \r\n /**\r\n * Handle touch end - close animation\r\n */\r\n @HostListener('touchend')\r\n onTouchEnd(): void {\r\n this.isOpen.set(false);\r\n }\r\n \r\n /**\r\n * Handle touch cancel - close animation\r\n */\r\n @HostListener('touchcancel')\r\n onTouchCancel(): void {\r\n this.isOpen.set(false);\r\n }\r\n \r\n /**\r\n * Handle click - open modal\r\n */\r\n @HostListener('click')\r\n async onClick(): Promise<void> {\r\n const handbookData: HandbookDetailData = {\r\n title: this.label,\r\n variant: this.variant,\r\n iconName: this.iconName,\r\n itemCount: this.itemCount,\r\n items: this.items\r\n };\r\n\r\n await this.handbookModal.open(handbookData);\r\n }\r\n \r\n /**\r\n * Calculate the number of page sheets to display\r\n * Max 6 sheets regardless of item count\r\n */\r\n getPageSheets(): number[] {\r\n const count = Math.min(this.itemCount, 6);\r\n return Array(count).fill(0);\r\n }\r\n\r\n constructor(\r\n private handbookModal: DsMobileHandbookDetailModalService\r\n ) {}\r\n}\r\n\r\n","// Mobile Page Components\r\nexport * from './page-main';\r\nexport * from './page-details';\r\n\r\n// Mobile Content Components\r\nexport * from './content';\r\nexport * from './header-content';\r\n\r\n// Mobile Community Components\r\nexport * from './post-card';\r\nexport * from './comment';\r\nexport * from './post-composer';\r\n\r\n// Mobile List Components\r\nexport * from './list-item';\r\nexport { DsMobileInteractiveListItemPostComponent, PostPdfAttachmentComponent } from './interactive-list-item-post';\r\nexport { DsMobileInteractiveListItemInquiryComponent } from './interactive-list-item-inquiry';\r\nexport { DsMobileInteractiveListItemMessageComponent } from './interactive-list-item-message';\r\nexport { DsMobileContactListItemComponent } from './contact-list-item';\r\n\r\n// Mobile Layout Components\r\nexport { DsMobileAppLayoutComponent, type HeaderVariant } from './app-layout';\r\nexport { DsMobileTabsComponent, type TabConfig } from './tabs';\r\n\r\n// Mobile Bottom Sheet Components\r\nexport * from './bottom-sheet';\r\n\r\n// Mobile Lightbox Components\r\nexport * from './lightbox';\r\n\r\n// Mobile Inline Photo Component\r\nexport * from './inline-photo';\r\n\r\n// Mobile Modal Service\r\nexport * from './modal';\r\n\r\n// Mobile Post Detail Modal\r\nexport * from './post-detail-modal';\r\n\r\n// Mobile Handbook Components\r\nexport * from './handbook-folder';\r\n\r\n\r\n// Shared directives\r\nexport * from './shared';","/* Auto-generated. Do not edit. */\nexport * from './ui/index';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.DsMobileLongPressDirective","PostContentComponent","PostTextComponent","PostMediaComponent","PostAttachmentsComponent","PostActionsComponent","ActionLikeComponent","ActionCommentComponent","i1","i2","i1.DsMobileLightboxService","DsMobileCommentActionsBottomSheetComponent","i2.DsMobileLightboxService","i3.DsMobileBottomSheetService","i4","i1.DsMobileHandbookDetailModalService"],"mappings":"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"}
|