@propbinder/mobile-design 0.2.5 → 0.2.6

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.
@@ -6998,6 +6998,534 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
6998
6998
  type: Output
6999
6999
  }] } });
7000
7000
 
7001
+ /**
7002
+ * DsMobileCardInlineComponent
7003
+ *
7004
+ * A versatile, always-interactive inline card component for standalone or small-group usage.
7005
+ * Designed for tappable card-like elements such as file attachments, contact cards, etc.
7006
+ * Not intended for long scrolling lists - use ds-mobile-list-item for that purpose.
7007
+ *
7008
+ * Features:
7009
+ * - Always interactive/tappable (unless disabled)
7010
+ * - Two layout variants: default (column) and compact (row)
7011
+ * - Flexible content projection with leading/main/trailing slots
7012
+ * - Consistent styling with rounded corners and neutral background
7013
+ * - Built-in hover and active states
7014
+ * - Accessibility features (role, tabindex, aria attributes)
7015
+ *
7016
+ * @example
7017
+ * ```html
7018
+ * <!-- Default variant (column layout) -->
7019
+ * <ds-mobile-card-inline
7020
+ * [variant]="'default'"
7021
+ * (cardClick)="handleClick()">
7022
+ *
7023
+ * <div content-leading>
7024
+ * <ds-avatar initials="JD" />
7025
+ * </div>
7026
+ *
7027
+ * <div content-main>
7028
+ * <div class="title">Document Title</div>
7029
+ * <div class="subtitle">PDF · 1.2 MB</div>
7030
+ * </div>
7031
+ *
7032
+ * <ds-icon content-trailing name="remixArrowRightSLine" />
7033
+ * </ds-mobile-card-inline>
7034
+ *
7035
+ * <!-- Compact variant (row layout) -->
7036
+ * <ds-mobile-card-inline
7037
+ * [variant]="'compact'"
7038
+ * (cardClick)="handleClick()">
7039
+ *
7040
+ * <ds-avatar content-leading size="sm" />
7041
+ *
7042
+ * <div content-main>
7043
+ * <span class="name">File.pdf</span>
7044
+ * <span class="size">245 KB</span>
7045
+ * </div>
7046
+ *
7047
+ * <ds-icon content-trailing name="remixArrowRightSLine" />
7048
+ * </ds-mobile-card-inline>
7049
+ *
7050
+ * <!-- Disabled state -->
7051
+ * <ds-mobile-card-inline [disabled]="true">
7052
+ * <div content-main>Disabled card</div>
7053
+ * </ds-mobile-card-inline>
7054
+ * ```
7055
+ */
7056
+ class DsMobileCardInlineComponent {
7057
+ /**
7058
+ * Display variant
7059
+ * - 'default' - Column layout with standard padding (gap: 12px, padding: 10px 12px)
7060
+ * - 'compact' - Row layout with reduced padding (gap: 8px, padding: 10px)
7061
+ */
7062
+ variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : []));
7063
+ /**
7064
+ * Whether the card is disabled
7065
+ * Disables all interactions and reduces opacity
7066
+ */
7067
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
7068
+ /**
7069
+ * Emits when the card is clicked (if not disabled)
7070
+ */
7071
+ cardClick = output();
7072
+ /**
7073
+ * Handle click events
7074
+ */
7075
+ handleClick(event) {
7076
+ if (this.disabled()) {
7077
+ return;
7078
+ }
7079
+ // Don't emit click if it came from an interactive child element
7080
+ const target = event.target;
7081
+ const closestInteractive = target.closest('button, a, input, select, textarea, [role="button"]');
7082
+ // Check if the interactive element is a child, not the host itself
7083
+ if (closestInteractive && closestInteractive !== event.currentTarget) {
7084
+ return;
7085
+ }
7086
+ this.cardClick.emit();
7087
+ }
7088
+ /**
7089
+ * Handle keyboard events (Enter/Space)
7090
+ */
7091
+ handleKeyDown(event) {
7092
+ if (this.disabled()) {
7093
+ return;
7094
+ }
7095
+ event.preventDefault();
7096
+ this.cardClick.emit();
7097
+ }
7098
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsMobileCardInlineComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7099
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.15", type: DsMobileCardInlineComponent, isStandalone: true, selector: "ds-mobile-card-inline", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cardClick: "cardClick" }, host: { listeners: { "click": "handleClick($event)", "keydown.enter": "handleKeyDown($event)", "keydown.space": "handleKeyDown($event)" }, properties: { "class.disabled": "disabled()", "class.variant-compact": "variant() === \"compact\"", "class.variant-default": "variant() === \"default\"", "attr.role": "\"button\"", "attr.tabindex": "disabled() ? null : \"0\"", "attr.aria-disabled": "disabled() ? \"true\" : null" } }, ngImport: i0, template: `
7100
+ <div class="card-inline-inner">
7101
+ <div class="content-leading">
7102
+ <ng-content select="[content-leading]" />
7103
+ </div>
7104
+
7105
+ <div class="content-main">
7106
+ <ng-content select="[content-main]" />
7107
+ <ng-content />
7108
+ </div>
7109
+
7110
+ <div class="content-trailing">
7111
+ <ng-content select="[content-trailing]" />
7112
+ </div>
7113
+ </div>
7114
+ `, isInline: true, styles: [":host{display:flex;align-items:center;background:var(--color-background-neutral-secondary, #f5f5f5);border-radius:16px;cursor:pointer;transition:all .2s ease;box-sizing:border-box}:host(.variant-default){gap:12px;padding:10px 12px}:host(.variant-compact){gap:8px;padding:10px}@media (hover: hover) and (pointer: fine){:host(:hover):not(.disabled){background:var(--color-background-neutral-secondary-hover, #ebebeb)}}:host(:active):not(.disabled){transform:scale(.98);background:var(--color-background-neutral-secondary-hover, #ebebeb)}:host(:focus-visible):not(.disabled){outline:2px solid var(--color-brand-primary, #5d5fef);outline-offset:2px}:host(.disabled){opacity:.5;pointer-events:none;cursor:not-allowed}.card-inline-inner{display:flex;align-items:center;gap:inherit;width:100%;min-width:0}.content-leading{flex-shrink:0;display:flex;align-items:center;justify-content:center}.content-main{flex:1;min-width:0;display:flex;align-items:center}:host(.variant-compact) .content-main{flex-direction:row;gap:8px}:host(.variant-default) .content-main{flex-direction:column;align-items:flex-start;gap:2px}.content-trailing{flex-shrink:0;display:flex;align-items:center}::ng-deep .item-avatar{flex-shrink:0}::ng-deep .item-content{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:center;gap:2px}:host(.variant-compact) ::ng-deep .item-content{flex-direction:row;align-items:center;justify-content:flex-start;gap:8px}::ng-deep .item-name{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:600;line-height:20px;letter-spacing:-.3px;color:var(--color-text-primary, #1a1a1a);margin:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:left}::ng-deep .item-meta{font-family:Brockmann,sans-serif;font-size:var(--font-size-xs);font-weight:400;line-height:1.2;letter-spacing:-.26px;color:var(--color-text-tertiary, #737373);margin:0;display:flex;align-items:center;justify-content:flex-start;gap:4px;white-space:nowrap;flex-shrink:0}::ng-deep .item-trailing{display:flex;align-items:center;color:var(--color-text-tertiary, #a3a3a3);flex-shrink:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
7115
+ }
7116
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsMobileCardInlineComponent, decorators: [{
7117
+ type: Component,
7118
+ args: [{ selector: 'ds-mobile-card-inline', standalone: true, imports: [CommonModule], host: {
7119
+ '[class.disabled]': 'disabled()',
7120
+ '[class.variant-compact]': 'variant() === "compact"',
7121
+ '[class.variant-default]': 'variant() === "default"',
7122
+ '[attr.role]': '"button"',
7123
+ '[attr.tabindex]': 'disabled() ? null : "0"',
7124
+ '[attr.aria-disabled]': 'disabled() ? "true" : null',
7125
+ '(click)': 'handleClick($event)',
7126
+ '(keydown.enter)': 'handleKeyDown($event)',
7127
+ '(keydown.space)': 'handleKeyDown($event)'
7128
+ }, template: `
7129
+ <div class="card-inline-inner">
7130
+ <div class="content-leading">
7131
+ <ng-content select="[content-leading]" />
7132
+ </div>
7133
+
7134
+ <div class="content-main">
7135
+ <ng-content select="[content-main]" />
7136
+ <ng-content />
7137
+ </div>
7138
+
7139
+ <div class="content-trailing">
7140
+ <ng-content select="[content-trailing]" />
7141
+ </div>
7142
+ </div>
7143
+ `, styles: [":host{display:flex;align-items:center;background:var(--color-background-neutral-secondary, #f5f5f5);border-radius:16px;cursor:pointer;transition:all .2s ease;box-sizing:border-box}:host(.variant-default){gap:12px;padding:10px 12px}:host(.variant-compact){gap:8px;padding:10px}@media (hover: hover) and (pointer: fine){:host(:hover):not(.disabled){background:var(--color-background-neutral-secondary-hover, #ebebeb)}}:host(:active):not(.disabled){transform:scale(.98);background:var(--color-background-neutral-secondary-hover, #ebebeb)}:host(:focus-visible):not(.disabled){outline:2px solid var(--color-brand-primary, #5d5fef);outline-offset:2px}:host(.disabled){opacity:.5;pointer-events:none;cursor:not-allowed}.card-inline-inner{display:flex;align-items:center;gap:inherit;width:100%;min-width:0}.content-leading{flex-shrink:0;display:flex;align-items:center;justify-content:center}.content-main{flex:1;min-width:0;display:flex;align-items:center}:host(.variant-compact) .content-main{flex-direction:row;gap:8px}:host(.variant-default) .content-main{flex-direction:column;align-items:flex-start;gap:2px}.content-trailing{flex-shrink:0;display:flex;align-items:center}::ng-deep .item-avatar{flex-shrink:0}::ng-deep .item-content{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:center;gap:2px}:host(.variant-compact) ::ng-deep .item-content{flex-direction:row;align-items:center;justify-content:flex-start;gap:8px}::ng-deep .item-name{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:600;line-height:20px;letter-spacing:-.3px;color:var(--color-text-primary, #1a1a1a);margin:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:left}::ng-deep .item-meta{font-family:Brockmann,sans-serif;font-size:var(--font-size-xs);font-weight:400;line-height:1.2;letter-spacing:-.26px;color:var(--color-text-tertiary, #737373);margin:0;display:flex;align-items:center;justify-content:flex-start;gap:4px;white-space:nowrap;flex-shrink:0}::ng-deep .item-trailing{display:flex;align-items:center;color:var(--color-text-tertiary, #a3a3a3);flex-shrink:0}\n"] }]
7144
+ }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], cardClick: [{ type: i0.Output, args: ["cardClick"] }] } });
7145
+
7146
+ /**
7147
+ * DsMobileCardInlineBannerComponent
7148
+ *
7149
+ * Specialized interactive component for displaying notification banners.
7150
+ * Used to show unread message notifications above inquiry details.
7151
+ *
7152
+ * Features:
7153
+ * - Neutral background matching file/contact cards
7154
+ * - Avatar icon with message symbol
7155
+ * - Title and timestamp
7156
+ * - Unread count badge
7157
+ * - Chevron for navigation indication
7158
+ *
7159
+ * @example
7160
+ * ```html
7161
+ * <ds-mobile-card-inline-banner
7162
+ * [title]="'New messages'"
7163
+ * [timestamp]="'2 min ago'"
7164
+ * [unreadCount]="3"
7165
+ * (bannerClick)="navigateToMessages()">
7166
+ * </ds-mobile-card-inline-banner>
7167
+ * ```
7168
+ */
7169
+ class DsMobileCardInlineBannerComponent {
7170
+ /**
7171
+ * Banner title (e.g., "New messages", "Unread messages")
7172
+ */
7173
+ title = input.required(...(ngDevMode ? [{ debugName: "title" }] : []));
7174
+ /**
7175
+ * Timestamp text (e.g., "2 min ago", "Just now")
7176
+ */
7177
+ timestamp = input('', ...(ngDevMode ? [{ debugName: "timestamp" }] : []));
7178
+ /**
7179
+ * Number of unread items (optional, shows badge if > 0)
7180
+ */
7181
+ unreadCount = input(0, ...(ngDevMode ? [{ debugName: "unreadCount" }] : []));
7182
+ /**
7183
+ * Layout variant
7184
+ * - 'default' - Standard padding and column layout
7185
+ * - 'compact' - Reduced padding and row layout
7186
+ */
7187
+ layout = input('default', ...(ngDevMode ? [{ debugName: "layout" }] : []));
7188
+ /**
7189
+ * Emits when the banner is clicked
7190
+ */
7191
+ bannerClick = output();
7192
+ handleBannerClick() {
7193
+ this.bannerClick.emit();
7194
+ }
7195
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsMobileCardInlineBannerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7196
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DsMobileCardInlineBannerComponent, isStandalone: true, selector: "ds-mobile-card-inline-banner", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, timestamp: { classPropertyName: "timestamp", publicName: "timestamp", isSignal: true, isRequired: false, transformFunction: null }, unreadCount: { classPropertyName: "unreadCount", publicName: "unreadCount", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { bannerClick: "bannerClick" }, ngImport: i0, template: `
7197
+ <ds-mobile-card-inline
7198
+ [variant]="layout()"
7199
+ (cardClick)="handleBannerClick()">
7200
+
7201
+ <div content-leading class="item-avatar">
7202
+ <ds-avatar
7203
+ type="icon"
7204
+ [iconName]="'remixNotificationLine'"
7205
+ [size]="layout() === 'compact' ? 'sm' : 'md'"
7206
+ />
7207
+ </div>
7208
+
7209
+ <div content-main class="item-content">
7210
+ <div class="item-name">{{ title() }}</div>
7211
+
7212
+ @if (timestamp()) {
7213
+ <div class="item-meta">
7214
+ <span>{{ timestamp() }}</span>
7215
+ </div>
7216
+ }
7217
+ </div>
7218
+
7219
+ <div content-trailing class="item-trailing">
7220
+ @if (unreadCount() && unreadCount()! > 0) {
7221
+ <span class="unread-badge">{{ unreadCount() }}</span>
7222
+ }
7223
+ <ds-icon name="remixArrowRightSLine" size="20px" />
7224
+ </div>
7225
+ </ds-mobile-card-inline>
7226
+ `, isInline: true, styles: [".unread-badge{min-width:24px;height:16px;padding:0 6px;border-radius:10px;background:var(--color-background-neutral-tertiary, #e5e5e5);color:var(--color-text-primary, #1a1a1a);font-family:Brockmann,sans-serif;font-size:var(--font-size-xs);font-weight:600;display:flex;align-items:center;justify-content:center;line-height:1;margin-right:8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsAvatarComponent, selector: "ds-avatar", inputs: ["type", "size", "initials", "src", "alt", "iconName", "iconColor"] }, { kind: "component", type: DsMobileCardInlineComponent, selector: "ds-mobile-card-inline", inputs: ["variant", "disabled"], outputs: ["cardClick"] }] });
7227
+ }
7228
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsMobileCardInlineBannerComponent, decorators: [{
7229
+ type: Component,
7230
+ args: [{ selector: 'ds-mobile-card-inline-banner', standalone: true, imports: [CommonModule, DsIconComponent, DsAvatarComponent, DsMobileCardInlineComponent], template: `
7231
+ <ds-mobile-card-inline
7232
+ [variant]="layout()"
7233
+ (cardClick)="handleBannerClick()">
7234
+
7235
+ <div content-leading class="item-avatar">
7236
+ <ds-avatar
7237
+ type="icon"
7238
+ [iconName]="'remixNotificationLine'"
7239
+ [size]="layout() === 'compact' ? 'sm' : 'md'"
7240
+ />
7241
+ </div>
7242
+
7243
+ <div content-main class="item-content">
7244
+ <div class="item-name">{{ title() }}</div>
7245
+
7246
+ @if (timestamp()) {
7247
+ <div class="item-meta">
7248
+ <span>{{ timestamp() }}</span>
7249
+ </div>
7250
+ }
7251
+ </div>
7252
+
7253
+ <div content-trailing class="item-trailing">
7254
+ @if (unreadCount() && unreadCount()! > 0) {
7255
+ <span class="unread-badge">{{ unreadCount() }}</span>
7256
+ }
7257
+ <ds-icon name="remixArrowRightSLine" size="20px" />
7258
+ </div>
7259
+ </ds-mobile-card-inline>
7260
+ `, styles: [".unread-badge{min-width:24px;height:16px;padding:0 6px;border-radius:10px;background:var(--color-background-neutral-tertiary, #e5e5e5);color:var(--color-text-primary, #1a1a1a);font-family:Brockmann,sans-serif;font-size:var(--font-size-xs);font-weight:600;display:flex;align-items:center;justify-content:center;line-height:1;margin-right:8px}\n"] }]
7261
+ }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], timestamp: [{ type: i0.Input, args: [{ isSignal: true, alias: "timestamp", required: false }] }], unreadCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "unreadCount", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: false }] }], bannerClick: [{ type: i0.Output, args: ["bannerClick"] }] } });
7262
+
7263
+ /**
7264
+ * DsMobileCardInlineContactComponent
7265
+ *
7266
+ * Specialized interactive component for displaying contacts.
7267
+ * Displays contact name with avatar initials and metadata (person name + phone number).
7268
+ * Similar styling to file attachments with rounded corners and hover states.
7269
+ *
7270
+ * @example
7271
+ * ```html
7272
+ * <ds-mobile-card-inline-contact
7273
+ * [name]="'Mortensen & Søn ApS'"
7274
+ * [initials]="'M'"
7275
+ * [contactPerson]="'John Mortensen'"
7276
+ * [phoneNumber]="'+45 12 34 56 78'"
7277
+ * [clickable]="true"
7278
+ * (contactClick)="openContact()">
7279
+ * </ds-mobile-card-inline-contact>
7280
+ * ```
7281
+ */
7282
+ class DsMobileCardInlineContactComponent {
7283
+ /**
7284
+ * Contact/company name
7285
+ */
7286
+ name = input.required(...(ngDevMode ? [{ debugName: "name" }] : []));
7287
+ /**
7288
+ * Avatar initials (usually 1-2 letters)
7289
+ */
7290
+ initials = input.required(...(ngDevMode ? [{ debugName: "initials" }] : []));
7291
+ /**
7292
+ * Contact person name (optional)
7293
+ */
7294
+ contactPerson = input('', ...(ngDevMode ? [{ debugName: "contactPerson" }] : []));
7295
+ /**
7296
+ * Phone number (optional)
7297
+ */
7298
+ phoneNumber = input('', ...(ngDevMode ? [{ debugName: "phoneNumber" }] : []));
7299
+ /**
7300
+ * Layout variant
7301
+ * - 'default' - Standard padding and column layout
7302
+ * - 'compact' - Reduced padding and row layout
7303
+ */
7304
+ layout = input('default', ...(ngDevMode ? [{ debugName: "layout" }] : []));
7305
+ /**
7306
+ * Whether the contact item is clickable
7307
+ */
7308
+ clickable = input(true, ...(ngDevMode ? [{ debugName: "clickable" }] : []));
7309
+ /**
7310
+ * Whether to show chevron icon
7311
+ */
7312
+ showChevron = input(true, ...(ngDevMode ? [{ debugName: "showChevron" }] : []));
7313
+ /**
7314
+ * Emits when the contact item is clicked (if clickable)
7315
+ */
7316
+ contactClick = output();
7317
+ handleContactClick() {
7318
+ this.contactClick.emit();
7319
+ }
7320
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsMobileCardInlineContactComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7321
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DsMobileCardInlineContactComponent, isStandalone: true, selector: "ds-mobile-card-inline-contact", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, initials: { classPropertyName: "initials", publicName: "initials", isSignal: true, isRequired: true, transformFunction: null }, contactPerson: { classPropertyName: "contactPerson", publicName: "contactPerson", isSignal: true, isRequired: false, transformFunction: null }, phoneNumber: { classPropertyName: "phoneNumber", publicName: "phoneNumber", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null }, clickable: { classPropertyName: "clickable", publicName: "clickable", isSignal: true, isRequired: false, transformFunction: null }, showChevron: { classPropertyName: "showChevron", publicName: "showChevron", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { contactClick: "contactClick" }, ngImport: i0, template: `
7322
+ <ds-mobile-card-inline
7323
+ [variant]="layout()"
7324
+ [disabled]="!clickable()"
7325
+ (cardClick)="handleContactClick()">
7326
+
7327
+ <div content-leading class="item-avatar">
7328
+ <ds-avatar
7329
+ [initials]="initials()"
7330
+ type="initials"
7331
+ [size]="layout() === 'compact' ? 'sm' : 'md'"
7332
+ />
7333
+ </div>
7334
+
7335
+ <div content-main class="item-content">
7336
+ <div class="item-name">{{ name() }}</div>
7337
+
7338
+ @if (contactPerson() || phoneNumber()) {
7339
+ <div class="item-meta">
7340
+ @if (contactPerson()) {
7341
+ <span>{{ contactPerson() }}</span>
7342
+ }
7343
+ @if (contactPerson() && phoneNumber()) {
7344
+ <span>·</span>
7345
+ }
7346
+ @if (phoneNumber()) {
7347
+ <span>{{ phoneNumber() }}</span>
7348
+ }
7349
+ </div>
7350
+ }
7351
+ </div>
7352
+
7353
+ @if (showChevron()) {
7354
+ <div content-trailing class="item-trailing">
7355
+ <ds-icon name="remixArrowRightSLine" size="20px" />
7356
+ </div>
7357
+ }
7358
+ </ds-mobile-card-inline>
7359
+ `, isInline: true, styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsAvatarComponent, selector: "ds-avatar", inputs: ["type", "size", "initials", "src", "alt", "iconName", "iconColor"] }, { kind: "component", type: DsMobileCardInlineComponent, selector: "ds-mobile-card-inline", inputs: ["variant", "disabled"], outputs: ["cardClick"] }] });
7360
+ }
7361
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsMobileCardInlineContactComponent, decorators: [{
7362
+ type: Component,
7363
+ args: [{ selector: 'ds-mobile-card-inline-contact', standalone: true, imports: [CommonModule, DsIconComponent, DsAvatarComponent, DsMobileCardInlineComponent], template: `
7364
+ <ds-mobile-card-inline
7365
+ [variant]="layout()"
7366
+ [disabled]="!clickable()"
7367
+ (cardClick)="handleContactClick()">
7368
+
7369
+ <div content-leading class="item-avatar">
7370
+ <ds-avatar
7371
+ [initials]="initials()"
7372
+ type="initials"
7373
+ [size]="layout() === 'compact' ? 'sm' : 'md'"
7374
+ />
7375
+ </div>
7376
+
7377
+ <div content-main class="item-content">
7378
+ <div class="item-name">{{ name() }}</div>
7379
+
7380
+ @if (contactPerson() || phoneNumber()) {
7381
+ <div class="item-meta">
7382
+ @if (contactPerson()) {
7383
+ <span>{{ contactPerson() }}</span>
7384
+ }
7385
+ @if (contactPerson() && phoneNumber()) {
7386
+ <span>·</span>
7387
+ }
7388
+ @if (phoneNumber()) {
7389
+ <span>{{ phoneNumber() }}</span>
7390
+ }
7391
+ </div>
7392
+ }
7393
+ </div>
7394
+
7395
+ @if (showChevron()) {
7396
+ <div content-trailing class="item-trailing">
7397
+ <ds-icon name="remixArrowRightSLine" size="20px" />
7398
+ </div>
7399
+ }
7400
+ </ds-mobile-card-inline>
7401
+ ` }]
7402
+ }], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }], initials: [{ type: i0.Input, args: [{ isSignal: true, alias: "initials", required: true }] }], contactPerson: [{ type: i0.Input, args: [{ isSignal: true, alias: "contactPerson", required: false }] }], phoneNumber: [{ type: i0.Input, args: [{ isSignal: true, alias: "phoneNumber", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: false }] }], clickable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clickable", required: false }] }], showChevron: [{ type: i0.Input, args: [{ isSignal: true, alias: "showChevron", required: false }] }], contactClick: [{ type: i0.Output, args: ["contactClick"] }] } });
7403
+
7404
+ /**
7405
+ * DsMobileCardInlineFileComponent
7406
+ *
7407
+ * File attachment display for various document types.
7408
+ * Shows file info card with icon, filename, and file size.
7409
+ * Supports PDF and generic document formats.
7410
+ * Emits click event to open file in viewer.
7411
+ *
7412
+ * @example
7413
+ * ```html
7414
+ * <ds-mobile-card-inline-file
7415
+ * [fileName]="'Document.pdf'"
7416
+ * [fileSize]="'1.2 MB'"
7417
+ * [variant]="'pdf'"
7418
+ * [layout]="'compact'"
7419
+ * (fileClick)="openFile()">
7420
+ * </ds-mobile-card-inline-file>
7421
+ * ```
7422
+ */
7423
+ class DsMobileCardInlineFileComponent {
7424
+ /**
7425
+ * File name
7426
+ */
7427
+ fileName = input('Document', ...(ngDevMode ? [{ debugName: "fileName" }] : []));
7428
+ /**
7429
+ * File size display (e.g., "1.2 MB")
7430
+ */
7431
+ fileSize = input('', ...(ngDevMode ? [{ debugName: "fileSize" }] : []));
7432
+ /**
7433
+ * File type variant
7434
+ * - 'pdf' - PDF document (red icon)
7435
+ * - 'doc' - Generic document (blue icon)
7436
+ */
7437
+ variant = input('doc', ...(ngDevMode ? [{ debugName: "variant" }] : []));
7438
+ /**
7439
+ * Layout variant
7440
+ * - 'default' - Standard padding and column layout
7441
+ * - 'compact' - Reduced padding and row layout
7442
+ */
7443
+ layout = input('default', ...(ngDevMode ? [{ debugName: "layout" }] : []));
7444
+ /**
7445
+ * Emits when the file attachment is clicked
7446
+ */
7447
+ fileClick = output();
7448
+ /**
7449
+ * Get the appropriate icon name based on variant
7450
+ */
7451
+ getIconName() {
7452
+ return this.variant() === 'pdf' ? 'remixFileTextLine' : 'remixAttachmentLine';
7453
+ }
7454
+ /**
7455
+ * Get the file type label based on variant
7456
+ */
7457
+ getFileTypeLabel() {
7458
+ return this.variant() === 'pdf' ? 'PDF' : 'DOC';
7459
+ }
7460
+ handleClick() {
7461
+ this.fileClick.emit();
7462
+ }
7463
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsMobileCardInlineFileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7464
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DsMobileCardInlineFileComponent, isStandalone: true, selector: "ds-mobile-card-inline-file", inputs: { fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: false, transformFunction: null }, fileSize: { classPropertyName: "fileSize", publicName: "fileSize", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fileClick: "fileClick" }, ngImport: i0, template: `
7465
+ <ds-mobile-card-inline
7466
+ [variant]="layout()"
7467
+ (cardClick)="handleClick()">
7468
+
7469
+ <div content-leading class="item-avatar" [class.pdf]="variant() === 'pdf'" [class.doc]="variant() === 'doc'">
7470
+ <ds-avatar
7471
+ type="icon"
7472
+ [iconName]="getIconName()"
7473
+ [size]="layout() === 'compact' ? 'sm' : 'md'"
7474
+ />
7475
+ </div>
7476
+
7477
+ <div content-main class="item-content">
7478
+ <div class="item-name">{{ fileName() }}</div>
7479
+ @if (fileSize()) {
7480
+ <div class="item-meta">{{ getFileTypeLabel() }} · {{ fileSize() }}</div>
7481
+ } @else {
7482
+ <div class="item-meta">{{ getFileTypeLabel() }}</div>
7483
+ }
7484
+ </div>
7485
+
7486
+ <ds-icon
7487
+ content-trailing
7488
+ name="remixArrowRightSLine"
7489
+ size="20px"
7490
+ class="item-trailing"
7491
+ />
7492
+ </ds-mobile-card-inline>
7493
+ `, isInline: true, styles: [".item-avatar.pdf ::ng-deep .avatar--icon{background-color:#ff5757!important}.item-avatar.doc ::ng-deep .avatar--icon{background-color:var(--color-blue-base, #3B82F6)!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsAvatarComponent, selector: "ds-avatar", inputs: ["type", "size", "initials", "src", "alt", "iconName", "iconColor"] }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsMobileCardInlineComponent, selector: "ds-mobile-card-inline", inputs: ["variant", "disabled"], outputs: ["cardClick"] }] });
7494
+ }
7495
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsMobileCardInlineFileComponent, decorators: [{
7496
+ type: Component,
7497
+ args: [{ selector: 'ds-mobile-card-inline-file', standalone: true, imports: [CommonModule, DsAvatarComponent, DsIconComponent, DsMobileCardInlineComponent], template: `
7498
+ <ds-mobile-card-inline
7499
+ [variant]="layout()"
7500
+ (cardClick)="handleClick()">
7501
+
7502
+ <div content-leading class="item-avatar" [class.pdf]="variant() === 'pdf'" [class.doc]="variant() === 'doc'">
7503
+ <ds-avatar
7504
+ type="icon"
7505
+ [iconName]="getIconName()"
7506
+ [size]="layout() === 'compact' ? 'sm' : 'md'"
7507
+ />
7508
+ </div>
7509
+
7510
+ <div content-main class="item-content">
7511
+ <div class="item-name">{{ fileName() }}</div>
7512
+ @if (fileSize()) {
7513
+ <div class="item-meta">{{ getFileTypeLabel() }} · {{ fileSize() }}</div>
7514
+ } @else {
7515
+ <div class="item-meta">{{ getFileTypeLabel() }}</div>
7516
+ }
7517
+ </div>
7518
+
7519
+ <ds-icon
7520
+ content-trailing
7521
+ name="remixArrowRightSLine"
7522
+ size="20px"
7523
+ class="item-trailing"
7524
+ />
7525
+ </ds-mobile-card-inline>
7526
+ `, styles: [".item-avatar.pdf ::ng-deep .avatar--icon{background-color:#ff5757!important}.item-avatar.doc ::ng-deep .avatar--icon{background-color:var(--color-blue-base, #3B82F6)!important}\n"] }]
7527
+ }], propDecorators: { fileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileName", required: false }] }], fileSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileSize", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: false }] }], fileClick: [{ type: i0.Output, args: ["fileClick"] }] } });
7528
+
7001
7529
  /**
7002
7530
  * DsMobileLightboxHeaderComponent
7003
7531
  *
@@ -10083,481 +10611,211 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
10083
10611
  type: Input
10084
10612
  }], currentUserName: [{
10085
10613
  type: Input
10086
- }], currentUserInitialsInput: [{
10087
- type: Input
10088
- }], loading: [{
10089
- type: Input
10090
- }], error: [{
10091
- type: Input
10092
- }], onSubmitComment: [{
10093
- type: Input
10094
- }], onToggleCommentLike: [{
10095
- type: Input
10096
- }], onEditComment: [{
10097
- type: Input
10098
- }], onDeleteComment: [{
10099
- type: Input
10100
- }], commentInput: [{
10101
- type: ViewChild,
10102
- args: ['commentInput']
10103
- }] } });
10104
-
10105
- /**
10106
- * BaseModalService
10107
- *
10108
- * Abstract base class for all modal services in the application.
10109
- * Enforces consistent modal configuration and presentation across all modals.
10110
- *
10111
- * **Features:**
10112
- * - Standardized modal presentation (stacked effect with gap at top)
10113
- * - Consistent backdrop and dismissal behavior
10114
- * - Automatic safe area handling
10115
- * - Native iOS-style animations
10116
- *
10117
- * **Why use this:**
10118
- * - Ensures all modals have the same look and feel
10119
- * - Prevents inconsistencies in modal configuration
10120
- * - Single source of truth for modal settings
10121
- * - Makes it impossible to forget critical configuration
10122
- *
10123
- * @example
10124
- * ```typescript
10125
- * @Injectable({ providedIn: 'root' })
10126
- * export class MyModalService extends BaseModalService {
10127
- * async open(data: MyData) {
10128
- * const modal = await this.createModal(
10129
- * MyModalComponent,
10130
- * { data }
10131
- * );
10132
- * await modal.present();
10133
- * }
10134
- * }
10135
- * ```
10136
- */
10137
- class BaseModalService {
10138
- modalController;
10139
- constructor(modalController) {
10140
- this.modalController = modalController;
10141
- }
10142
- /**
10143
- * Create a modal with standardized configuration
10144
- *
10145
- * This method enforces consistent modal behavior across the app:
10146
- * - Uses 'ds-modal-base' CSS class for consistent styling
10147
- * - iOS mode for native feel
10148
- * - presentingElement for stacked modal effect
10149
- * - Standard backdrop and dismissal settings
10150
- *
10151
- * @param component The component to display in the modal
10152
- * @param componentProps Props to pass to the component
10153
- * @param customOptions Optional overrides for specific modal needs
10154
- * @returns Promise resolving to the created modal
10155
- *
10156
- * @example
10157
- * ```typescript
10158
- * const modal = await this.createModal(
10159
- * PostDetailComponent,
10160
- * { postId: '123', loading: false }
10161
- * );
10162
- * await modal.present();
10163
- * ```
10164
- */
10165
- async createModal(component, componentProps, customOptions) {
10166
- return await this.modalController.create({
10167
- component,
10168
- componentProps,
10169
- // Standard configuration for all modals
10170
- cssClass: 'ds-modal-base',
10171
- mode: 'ios',
10172
- presentingElement: document.querySelector('ion-router-outlet') || undefined,
10173
- backdropDismiss: true,
10174
- showBackdrop: true,
10175
- animated: true,
10176
- // Allow service-specific overrides if needed
10177
- ...customOptions,
10178
- });
10179
- }
10180
- /**
10181
- * Close the currently open modal
10182
- *
10183
- * @param data Optional data to pass back when dismissing
10184
- * @returns Promise that resolves when the modal is dismissed
10185
- */
10186
- async close(data) {
10187
- return this.modalController.dismiss(data);
10188
- }
10189
- /**
10190
- * Get the top-most modal if one exists
10191
- *
10192
- * @returns Promise that resolves to the modal element or undefined
10193
- */
10194
- async getTop() {
10195
- return this.modalController.getTop();
10196
- }
10197
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: BaseModalService, deps: [{ token: i1.ModalController }], target: i0.ɵɵFactoryTarget.Injectable });
10198
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: BaseModalService });
10199
- }
10200
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: BaseModalService, decorators: [{
10201
- type: Injectable
10202
- }], ctorParameters: () => [{ type: i1.ModalController }] });
10203
-
10204
- /**
10205
- * DsMobilePostDetailModalService
10206
- *
10207
- * Service for displaying post details in a full-screen modal.
10208
- * Built on Ionic's modal system with native gestures and animations.
10209
- * Follows the same pattern as DsMobileLightboxService for consistent behavior.
10210
- *
10211
- * Features:
10212
- * - Full post content display
10213
- * - Comments section
10214
- * - Like/comment actions
10215
- * - Image lightbox integration
10216
- * - Native modal animations
10217
- * - Safe area support
10218
- *
10219
- * @example
10220
- * ```typescript
10221
- * constructor(private postModal: DsMobilePostDetailModalService) {}
10222
- *
10223
- * async openPost() {
10224
- * await this.postModal.open({
10225
- * postId: '123',
10226
- * authorName: 'John Doe',
10227
- * authorRole: 'Tenant',
10228
- * timestamp: '2h ago',
10229
- * avatarInitials: 'JD',
10230
- * content: 'Just moved into my new apartment!',
10231
- * isLiked: false,
10232
- * likeCount: 42,
10233
- * commentCount: 12,
10234
- * comments: [
10235
- * {
10236
- * authorName: 'Jane Smith',
10237
- * authorRole: 'Tenant',
10238
- * timestamp: '1h ago',
10239
- * avatarInitials: 'JS',
10240
- * content: 'Welcome to the community!'
10241
- * }
10242
- * ]
10243
- * });
10244
- * }
10245
- * ```
10246
- */
10247
- class DsMobilePostDetailModalService extends BaseModalService {
10248
- constructor(modalController) {
10249
- super(modalController);
10250
- }
10251
- /**
10252
- * Open the post detail modal
10253
- *
10254
- * @param postData Post data to display
10255
- * @param options Optional loading and error states
10256
- * @returns Promise that resolves when the modal is presented
10257
- */
10258
- async open(postData, options) {
10259
- console.log('[PostDetailModal] Opening with data:', postData);
10260
- console.log('[PostDetailModal] options.onSubmitComment =', options?.onSubmitComment);
10261
- const modal = await this.createModal(DsMobilePostDetailModalComponent, {
10262
- postData: postData,
10263
- loading: options?.loading ?? false,
10264
- error: options?.error,
10265
- onSubmitComment: options?.onSubmitComment,
10266
- onToggleCommentLike: options?.onToggleCommentLike,
10267
- currentUserName: options?.currentUserName ?? '',
10268
- currentUserInitialsInput: options?.currentUserInitials ?? '',
10269
- }, {
10270
- keyboardClose: true, // Keep keyboard close behavior for this modal
10271
- });
10272
- console.log('[PostDetailModal] Modal created, presenting...');
10273
- await modal.present();
10274
- console.log('[PostDetailModal] Modal presented');
10275
- }
10276
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsMobilePostDetailModalService, deps: [{ token: i1.ModalController }], target: i0.ɵɵFactoryTarget.Injectable });
10277
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsMobilePostDetailModalService, providedIn: 'root' });
10278
- }
10279
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsMobilePostDetailModalService, decorators: [{
10280
- type: Injectable,
10281
- args: [{
10282
- providedIn: 'root',
10283
- }]
10284
- }], ctorParameters: () => [{ type: i1.ModalController }] });
10285
-
10286
- /**
10287
- * Mobile Post Detail Modal Module
10288
- *
10289
- * Service and component for displaying posts in a modal
10290
- */
10291
-
10292
- /**
10293
- * DsMobileCardInlineComponent
10294
- *
10295
- * A versatile, always-interactive inline card component for standalone or small-group usage.
10296
- * Designed for tappable card-like elements such as file attachments, contact cards, etc.
10297
- * Not intended for long scrolling lists - use ds-mobile-list-item for that purpose.
10298
- *
10299
- * Features:
10300
- * - Always interactive/tappable (unless disabled)
10301
- * - Two layout variants: default (column) and compact (row)
10302
- * - Flexible content projection with leading/main/trailing slots
10303
- * - Consistent styling with rounded corners and neutral background
10304
- * - Built-in hover and active states
10305
- * - Accessibility features (role, tabindex, aria attributes)
10306
- *
10307
- * @example
10308
- * ```html
10309
- * <!-- Default variant (column layout) -->
10310
- * <ds-mobile-card-inline
10311
- * [variant]="'default'"
10312
- * (cardClick)="handleClick()">
10313
- *
10314
- * <div content-leading>
10315
- * <ds-avatar initials="JD" />
10316
- * </div>
10317
- *
10318
- * <div content-main>
10319
- * <div class="title">Document Title</div>
10320
- * <div class="subtitle">PDF · 1.2 MB</div>
10321
- * </div>
10322
- *
10323
- * <ds-icon content-trailing name="remixArrowRightSLine" />
10324
- * </ds-mobile-card-inline>
10325
- *
10326
- * <!-- Compact variant (row layout) -->
10327
- * <ds-mobile-card-inline
10328
- * [variant]="'compact'"
10329
- * (cardClick)="handleClick()">
10614
+ }], currentUserInitialsInput: [{
10615
+ type: Input
10616
+ }], loading: [{
10617
+ type: Input
10618
+ }], error: [{
10619
+ type: Input
10620
+ }], onSubmitComment: [{
10621
+ type: Input
10622
+ }], onToggleCommentLike: [{
10623
+ type: Input
10624
+ }], onEditComment: [{
10625
+ type: Input
10626
+ }], onDeleteComment: [{
10627
+ type: Input
10628
+ }], commentInput: [{
10629
+ type: ViewChild,
10630
+ args: ['commentInput']
10631
+ }] } });
10632
+
10633
+ /**
10634
+ * BaseModalService
10330
10635
  *
10331
- * <ds-avatar content-leading size="sm" />
10636
+ * Abstract base class for all modal services in the application.
10637
+ * Enforces consistent modal configuration and presentation across all modals.
10332
10638
  *
10333
- * <div content-main>
10334
- * <span class="name">File.pdf</span>
10335
- * <span class="size">245 KB</span>
10336
- * </div>
10639
+ * **Features:**
10640
+ * - Standardized modal presentation (stacked effect with gap at top)
10641
+ * - Consistent backdrop and dismissal behavior
10642
+ * - Automatic safe area handling
10643
+ * - Native iOS-style animations
10337
10644
  *
10338
- * <ds-icon content-trailing name="remixArrowRightSLine" />
10339
- * </ds-mobile-card-inline>
10645
+ * **Why use this:**
10646
+ * - Ensures all modals have the same look and feel
10647
+ * - Prevents inconsistencies in modal configuration
10648
+ * - Single source of truth for modal settings
10649
+ * - Makes it impossible to forget critical configuration
10340
10650
  *
10341
- * <!-- Disabled state -->
10342
- * <ds-mobile-card-inline [disabled]="true">
10343
- * <div content-main>Disabled card</div>
10344
- * </ds-mobile-card-inline>
10651
+ * @example
10652
+ * ```typescript
10653
+ * @Injectable({ providedIn: 'root' })
10654
+ * export class MyModalService extends BaseModalService {
10655
+ * async open(data: MyData) {
10656
+ * const modal = await this.createModal(
10657
+ * MyModalComponent,
10658
+ * { data }
10659
+ * );
10660
+ * await modal.present();
10661
+ * }
10662
+ * }
10345
10663
  * ```
10346
10664
  */
10347
- class DsMobileCardInlineComponent {
10348
- /**
10349
- * Display variant
10350
- * - 'default' - Column layout with standard padding (gap: 12px, padding: 10px 12px)
10351
- * - 'compact' - Row layout with reduced padding (gap: 8px, padding: 10px)
10352
- */
10353
- variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : []));
10354
- /**
10355
- * Whether the card is disabled
10356
- * Disables all interactions and reduces opacity
10357
- */
10358
- disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
10665
+ class BaseModalService {
10666
+ modalController;
10667
+ constructor(modalController) {
10668
+ this.modalController = modalController;
10669
+ }
10359
10670
  /**
10360
- * Emits when the card is clicked (if not disabled)
10671
+ * Create a modal with standardized configuration
10672
+ *
10673
+ * This method enforces consistent modal behavior across the app:
10674
+ * - Uses 'ds-modal-base' CSS class for consistent styling
10675
+ * - iOS mode for native feel
10676
+ * - presentingElement for stacked modal effect
10677
+ * - Standard backdrop and dismissal settings
10678
+ *
10679
+ * @param component The component to display in the modal
10680
+ * @param componentProps Props to pass to the component
10681
+ * @param customOptions Optional overrides for specific modal needs
10682
+ * @returns Promise resolving to the created modal
10683
+ *
10684
+ * @example
10685
+ * ```typescript
10686
+ * const modal = await this.createModal(
10687
+ * PostDetailComponent,
10688
+ * { postId: '123', loading: false }
10689
+ * );
10690
+ * await modal.present();
10691
+ * ```
10361
10692
  */
10362
- cardClick = output();
10693
+ async createModal(component, componentProps, customOptions) {
10694
+ return await this.modalController.create({
10695
+ component,
10696
+ componentProps,
10697
+ // Standard configuration for all modals
10698
+ cssClass: 'ds-modal-base',
10699
+ mode: 'ios',
10700
+ presentingElement: document.querySelector('ion-router-outlet') || undefined,
10701
+ backdropDismiss: true,
10702
+ showBackdrop: true,
10703
+ animated: true,
10704
+ // Allow service-specific overrides if needed
10705
+ ...customOptions,
10706
+ });
10707
+ }
10363
10708
  /**
10364
- * Handle click events
10709
+ * Close the currently open modal
10710
+ *
10711
+ * @param data Optional data to pass back when dismissing
10712
+ * @returns Promise that resolves when the modal is dismissed
10365
10713
  */
10366
- handleClick(event) {
10367
- if (this.disabled()) {
10368
- return;
10369
- }
10370
- // Don't emit click if it came from an interactive child element
10371
- const target = event.target;
10372
- const closestInteractive = target.closest('button, a, input, select, textarea, [role="button"]');
10373
- // Check if the interactive element is a child, not the host itself
10374
- if (closestInteractive && closestInteractive !== event.currentTarget) {
10375
- return;
10376
- }
10377
- this.cardClick.emit();
10714
+ async close(data) {
10715
+ return this.modalController.dismiss(data);
10378
10716
  }
10379
10717
  /**
10380
- * Handle keyboard events (Enter/Space)
10718
+ * Get the top-most modal if one exists
10719
+ *
10720
+ * @returns Promise that resolves to the modal element or undefined
10381
10721
  */
10382
- handleKeyDown(event) {
10383
- if (this.disabled()) {
10384
- return;
10385
- }
10386
- event.preventDefault();
10387
- this.cardClick.emit();
10722
+ async getTop() {
10723
+ return this.modalController.getTop();
10388
10724
  }
10389
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsMobileCardInlineComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10390
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.15", type: DsMobileCardInlineComponent, isStandalone: true, selector: "ds-mobile-card-inline", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cardClick: "cardClick" }, host: { listeners: { "click": "handleClick($event)", "keydown.enter": "handleKeyDown($event)", "keydown.space": "handleKeyDown($event)" }, properties: { "class.disabled": "disabled()", "class.variant-compact": "variant() === \"compact\"", "class.variant-default": "variant() === \"default\"", "attr.role": "\"button\"", "attr.tabindex": "disabled() ? null : \"0\"", "attr.aria-disabled": "disabled() ? \"true\" : null" } }, ngImport: i0, template: `
10391
- <div class="card-inline-inner">
10392
- <div class="content-leading">
10393
- <ng-content select="[content-leading]" />
10394
- </div>
10395
-
10396
- <div class="content-main">
10397
- <ng-content select="[content-main]" />
10398
- <ng-content />
10399
- </div>
10400
-
10401
- <div class="content-trailing">
10402
- <ng-content select="[content-trailing]" />
10403
- </div>
10404
- </div>
10405
- `, isInline: true, styles: [":host{display:flex;align-items:center;background:var(--color-background-neutral-secondary, #f5f5f5);border-radius:16px;cursor:pointer;transition:all .2s ease;box-sizing:border-box}:host(.variant-default){gap:12px;padding:10px 12px}:host(.variant-compact){gap:8px;padding:10px}@media (hover: hover) and (pointer: fine){:host(:hover):not(.disabled){background:var(--color-background-neutral-secondary-hover, #ebebeb)}}:host(:active):not(.disabled){transform:scale(.98);background:var(--color-background-neutral-secondary-hover, #ebebeb)}:host(:focus-visible):not(.disabled){outline:2px solid var(--color-brand-primary, #5d5fef);outline-offset:2px}:host(.disabled){opacity:.5;pointer-events:none;cursor:not-allowed}.card-inline-inner{display:flex;align-items:center;gap:inherit;width:100%;min-width:0}.content-leading{flex-shrink:0;display:flex;align-items:center;justify-content:center}.content-main{flex:1;min-width:0;display:flex;align-items:center}:host(.variant-compact) .content-main{flex-direction:row;gap:8px}:host(.variant-default) .content-main{flex-direction:column;align-items:flex-start;gap:2px}.content-trailing{flex-shrink:0;display:flex;align-items:center}::ng-deep .item-avatar{flex-shrink:0}::ng-deep .item-content{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:center;gap:2px}:host(.variant-compact) ::ng-deep .item-content{flex-direction:row;align-items:center;justify-content:flex-start;gap:8px}::ng-deep .item-name{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:600;line-height:20px;letter-spacing:-.3px;color:var(--color-text-primary, #1a1a1a);margin:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:left}::ng-deep .item-meta{font-family:Brockmann,sans-serif;font-size:var(--font-size-xs);font-weight:400;line-height:1.2;letter-spacing:-.26px;color:var(--color-text-tertiary, #737373);margin:0;display:flex;align-items:center;justify-content:flex-start;gap:4px;white-space:nowrap;flex-shrink:0}::ng-deep .item-trailing{display:flex;align-items:center;color:var(--color-text-tertiary, #a3a3a3);flex-shrink:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
10725
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: BaseModalService, deps: [{ token: i1.ModalController }], target: i0.ɵɵFactoryTarget.Injectable });
10726
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: BaseModalService });
10406
10727
  }
10407
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsMobileCardInlineComponent, decorators: [{
10408
- type: Component,
10409
- args: [{ selector: 'ds-mobile-card-inline', standalone: true, imports: [CommonModule], host: {
10410
- '[class.disabled]': 'disabled()',
10411
- '[class.variant-compact]': 'variant() === "compact"',
10412
- '[class.variant-default]': 'variant() === "default"',
10413
- '[attr.role]': '"button"',
10414
- '[attr.tabindex]': 'disabled() ? null : "0"',
10415
- '[attr.aria-disabled]': 'disabled() ? "true" : null',
10416
- '(click)': 'handleClick($event)',
10417
- '(keydown.enter)': 'handleKeyDown($event)',
10418
- '(keydown.space)': 'handleKeyDown($event)'
10419
- }, template: `
10420
- <div class="card-inline-inner">
10421
- <div class="content-leading">
10422
- <ng-content select="[content-leading]" />
10423
- </div>
10424
-
10425
- <div class="content-main">
10426
- <ng-content select="[content-main]" />
10427
- <ng-content />
10428
- </div>
10429
-
10430
- <div class="content-trailing">
10431
- <ng-content select="[content-trailing]" />
10432
- </div>
10433
- </div>
10434
- `, styles: [":host{display:flex;align-items:center;background:var(--color-background-neutral-secondary, #f5f5f5);border-radius:16px;cursor:pointer;transition:all .2s ease;box-sizing:border-box}:host(.variant-default){gap:12px;padding:10px 12px}:host(.variant-compact){gap:8px;padding:10px}@media (hover: hover) and (pointer: fine){:host(:hover):not(.disabled){background:var(--color-background-neutral-secondary-hover, #ebebeb)}}:host(:active):not(.disabled){transform:scale(.98);background:var(--color-background-neutral-secondary-hover, #ebebeb)}:host(:focus-visible):not(.disabled){outline:2px solid var(--color-brand-primary, #5d5fef);outline-offset:2px}:host(.disabled){opacity:.5;pointer-events:none;cursor:not-allowed}.card-inline-inner{display:flex;align-items:center;gap:inherit;width:100%;min-width:0}.content-leading{flex-shrink:0;display:flex;align-items:center;justify-content:center}.content-main{flex:1;min-width:0;display:flex;align-items:center}:host(.variant-compact) .content-main{flex-direction:row;gap:8px}:host(.variant-default) .content-main{flex-direction:column;align-items:flex-start;gap:2px}.content-trailing{flex-shrink:0;display:flex;align-items:center}::ng-deep .item-avatar{flex-shrink:0}::ng-deep .item-content{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:center;gap:2px}:host(.variant-compact) ::ng-deep .item-content{flex-direction:row;align-items:center;justify-content:flex-start;gap:8px}::ng-deep .item-name{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:600;line-height:20px;letter-spacing:-.3px;color:var(--color-text-primary, #1a1a1a);margin:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:left}::ng-deep .item-meta{font-family:Brockmann,sans-serif;font-size:var(--font-size-xs);font-weight:400;line-height:1.2;letter-spacing:-.26px;color:var(--color-text-tertiary, #737373);margin:0;display:flex;align-items:center;justify-content:flex-start;gap:4px;white-space:nowrap;flex-shrink:0}::ng-deep .item-trailing{display:flex;align-items:center;color:var(--color-text-tertiary, #a3a3a3);flex-shrink:0}\n"] }]
10435
- }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], cardClick: [{ type: i0.Output, args: ["cardClick"] }] } });
10728
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: BaseModalService, decorators: [{
10729
+ type: Injectable
10730
+ }], ctorParameters: () => [{ type: i1.ModalController }] });
10436
10731
 
10437
10732
  /**
10438
- * DsMobileCardInlineFileComponent
10733
+ * DsMobilePostDetailModalService
10439
10734
  *
10440
- * File attachment display for various document types.
10441
- * Shows file info card with icon, filename, and file size.
10442
- * Supports PDF and generic document formats.
10443
- * Emits click event to open file in viewer.
10735
+ * Service for displaying post details in a full-screen modal.
10736
+ * Built on Ionic's modal system with native gestures and animations.
10737
+ * Follows the same pattern as DsMobileLightboxService for consistent behavior.
10738
+ *
10739
+ * Features:
10740
+ * - Full post content display
10741
+ * - Comments section
10742
+ * - Like/comment actions
10743
+ * - Image lightbox integration
10744
+ * - Native modal animations
10745
+ * - Safe area support
10444
10746
  *
10445
10747
  * @example
10446
- * ```html
10447
- * <ds-mobile-card-inline-file
10448
- * [fileName]="'Document.pdf'"
10449
- * [fileSize]="'1.2 MB'"
10450
- * [variant]="'pdf'"
10451
- * [layout]="'compact'"
10452
- * (fileClick)="openFile()">
10453
- * </ds-mobile-card-inline-file>
10454
- * ```
10455
- */
10456
- class DsMobileCardInlineFileComponent {
10457
- /**
10458
- * File name
10459
- */
10460
- fileName = input('Document', ...(ngDevMode ? [{ debugName: "fileName" }] : []));
10461
- /**
10462
- * File size display (e.g., "1.2 MB")
10463
- */
10464
- fileSize = input('', ...(ngDevMode ? [{ debugName: "fileSize" }] : []));
10465
- /**
10466
- * File type variant
10467
- * - 'pdf' - PDF document (red icon)
10468
- * - 'doc' - Generic document (blue icon)
10469
- */
10470
- variant = input('doc', ...(ngDevMode ? [{ debugName: "variant" }] : []));
10471
- /**
10472
- * Layout variant
10473
- * - 'default' - Standard padding and column layout
10474
- * - 'compact' - Reduced padding and row layout
10475
- */
10476
- layout = input('default', ...(ngDevMode ? [{ debugName: "layout" }] : []));
10477
- /**
10478
- * Emits when the file attachment is clicked
10479
- */
10480
- fileClick = output();
10481
- /**
10482
- * Get the appropriate icon name based on variant
10483
- */
10484
- getIconName() {
10485
- return this.variant() === 'pdf' ? 'remixFileTextLine' : 'remixAttachmentLine';
10748
+ * ```typescript
10749
+ * constructor(private postModal: DsMobilePostDetailModalService) {}
10750
+ *
10751
+ * async openPost() {
10752
+ * await this.postModal.open({
10753
+ * postId: '123',
10754
+ * authorName: 'John Doe',
10755
+ * authorRole: 'Tenant',
10756
+ * timestamp: '2h ago',
10757
+ * avatarInitials: 'JD',
10758
+ * content: 'Just moved into my new apartment!',
10759
+ * isLiked: false,
10760
+ * likeCount: 42,
10761
+ * commentCount: 12,
10762
+ * comments: [
10763
+ * {
10764
+ * authorName: 'Jane Smith',
10765
+ * authorRole: 'Tenant',
10766
+ * timestamp: '1h ago',
10767
+ * avatarInitials: 'JS',
10768
+ * content: 'Welcome to the community!'
10769
+ * }
10770
+ * ]
10771
+ * });
10772
+ * }
10773
+ * ```
10774
+ */
10775
+ class DsMobilePostDetailModalService extends BaseModalService {
10776
+ constructor(modalController) {
10777
+ super(modalController);
10486
10778
  }
10487
10779
  /**
10488
- * Get the file type label based on variant
10780
+ * Open the post detail modal
10781
+ *
10782
+ * @param postData Post data to display
10783
+ * @param options Optional loading and error states
10784
+ * @returns Promise that resolves when the modal is presented
10489
10785
  */
10490
- getFileTypeLabel() {
10491
- return this.variant() === 'pdf' ? 'PDF' : 'DOC';
10492
- }
10493
- handleClick() {
10494
- this.fileClick.emit();
10786
+ async open(postData, options) {
10787
+ console.log('[PostDetailModal] Opening with data:', postData);
10788
+ console.log('[PostDetailModal] options.onSubmitComment =', options?.onSubmitComment);
10789
+ const modal = await this.createModal(DsMobilePostDetailModalComponent, {
10790
+ postData: postData,
10791
+ loading: options?.loading ?? false,
10792
+ error: options?.error,
10793
+ onSubmitComment: options?.onSubmitComment,
10794
+ onToggleCommentLike: options?.onToggleCommentLike,
10795
+ currentUserName: options?.currentUserName ?? '',
10796
+ currentUserInitialsInput: options?.currentUserInitials ?? '',
10797
+ }, {
10798
+ keyboardClose: true, // Keep keyboard close behavior for this modal
10799
+ });
10800
+ console.log('[PostDetailModal] Modal created, presenting...');
10801
+ await modal.present();
10802
+ console.log('[PostDetailModal] Modal presented');
10495
10803
  }
10496
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsMobileCardInlineFileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10497
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DsMobileCardInlineFileComponent, isStandalone: true, selector: "ds-mobile-card-inline-file", inputs: { fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: false, transformFunction: null }, fileSize: { classPropertyName: "fileSize", publicName: "fileSize", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fileClick: "fileClick" }, ngImport: i0, template: `
10498
- <ds-mobile-card-inline
10499
- [variant]="layout()"
10500
- (cardClick)="handleClick()">
10501
-
10502
- <div content-leading class="item-avatar" [class.pdf]="variant() === 'pdf'" [class.doc]="variant() === 'doc'">
10503
- <ds-avatar
10504
- type="icon"
10505
- [iconName]="getIconName()"
10506
- [size]="layout() === 'compact' ? 'sm' : 'md'"
10507
- />
10508
- </div>
10509
-
10510
- <div content-main class="item-content">
10511
- <div class="item-name">{{ fileName() }}</div>
10512
- @if (fileSize()) {
10513
- <div class="item-meta">{{ getFileTypeLabel() }} · {{ fileSize() }}</div>
10514
- } @else {
10515
- <div class="item-meta">{{ getFileTypeLabel() }}</div>
10516
- }
10517
- </div>
10518
-
10519
- <ds-icon
10520
- content-trailing
10521
- name="remixArrowRightSLine"
10522
- size="20px"
10523
- class="item-trailing"
10524
- />
10525
- </ds-mobile-card-inline>
10526
- `, isInline: true, styles: [".item-avatar.pdf ::ng-deep .avatar--icon{background-color:#ff5757!important}.item-avatar.doc ::ng-deep .avatar--icon{background-color:var(--color-blue-base, #3B82F6)!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsAvatarComponent, selector: "ds-avatar", inputs: ["type", "size", "initials", "src", "alt", "iconName", "iconColor"] }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsMobileCardInlineComponent, selector: "ds-mobile-card-inline", inputs: ["variant", "disabled"], outputs: ["cardClick"] }] });
10804
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsMobilePostDetailModalService, deps: [{ token: i1.ModalController }], target: i0.ɵɵFactoryTarget.Injectable });
10805
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsMobilePostDetailModalService, providedIn: 'root' });
10527
10806
  }
10528
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsMobileCardInlineFileComponent, decorators: [{
10529
- type: Component,
10530
- args: [{ selector: 'ds-mobile-card-inline-file', standalone: true, imports: [CommonModule, DsAvatarComponent, DsIconComponent, DsMobileCardInlineComponent], template: `
10531
- <ds-mobile-card-inline
10532
- [variant]="layout()"
10533
- (cardClick)="handleClick()">
10534
-
10535
- <div content-leading class="item-avatar" [class.pdf]="variant() === 'pdf'" [class.doc]="variant() === 'doc'">
10536
- <ds-avatar
10537
- type="icon"
10538
- [iconName]="getIconName()"
10539
- [size]="layout() === 'compact' ? 'sm' : 'md'"
10540
- />
10541
- </div>
10542
-
10543
- <div content-main class="item-content">
10544
- <div class="item-name">{{ fileName() }}</div>
10545
- @if (fileSize()) {
10546
- <div class="item-meta">{{ getFileTypeLabel() }} · {{ fileSize() }}</div>
10547
- } @else {
10548
- <div class="item-meta">{{ getFileTypeLabel() }}</div>
10549
- }
10550
- </div>
10551
-
10552
- <ds-icon
10553
- content-trailing
10554
- name="remixArrowRightSLine"
10555
- size="20px"
10556
- class="item-trailing"
10557
- />
10558
- </ds-mobile-card-inline>
10559
- `, styles: [".item-avatar.pdf ::ng-deep .avatar--icon{background-color:#ff5757!important}.item-avatar.doc ::ng-deep .avatar--icon{background-color:var(--color-blue-base, #3B82F6)!important}\n"] }]
10560
- }], propDecorators: { fileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileName", required: false }] }], fileSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileSize", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: false }] }], fileClick: [{ type: i0.Output, args: ["fileClick"] }] } });
10807
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsMobilePostDetailModalService, decorators: [{
10808
+ type: Injectable,
10809
+ args: [{
10810
+ providedIn: 'root',
10811
+ }]
10812
+ }], ctorParameters: () => [{ type: i1.ModalController }] });
10813
+
10814
+ /**
10815
+ * Mobile Post Detail Modal Module
10816
+ *
10817
+ * Service and component for displaying posts in a modal
10818
+ */
10561
10819
 
10562
10820
  /**
10563
10821
  * DsMobileSystemMessageBannerComponent
@@ -11871,216 +12129,75 @@ class DsMobileHandbookFolderMiniComponent {
11871
12129
  'grey': 'grey'
11872
12130
  };
11873
12131
  const colorName = variantMap[this.variant] || 'light-purple';
11874
- return `var(--color-${colorName}-${suffix})`;
11875
- }
11876
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsMobileHandbookFolderMiniComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
11877
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: DsMobileHandbookFolderMiniComponent, isStandalone: true, selector: "ds-mobile-handbook-folder-mini", inputs: { variant: "variant", iconName: "iconName" }, ngImport: i0, template: `
11878
- <div class="mini-folder-container">
11879
- <!-- Folder Tab SVG -->
11880
- <svg
11881
- class="mini-folder-tab"
11882
- width="101"
11883
- height="24"
11884
- viewBox="0 0 101 24"
11885
- fill="none"
11886
- xmlns="http://www.w3.org/2000/svg">
11887
- <path
11888
- 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"
11889
- [attr.fill]="getColorVar('strong')"/>
11890
- </svg>
11891
-
11892
- <!-- Folder Back -->
11893
- <div class="mini-folder-back" [style.background-color]="getColorVar('strong')">
11894
- <!-- Folder Front -->
11895
- <div
11896
- class="mini-folder-front"
11897
- [style.background-color]="getColorVar('base')">
11898
- <ds-icon
11899
- [name]="iconName"
11900
- [size]="'14px'"
11901
- [style.color]="'white'" />
11902
- </div>
11903
- </div>
11904
- </div>
11905
- `, isInline: true, styles: [":host{display:inline-block;width:32px;height:32px;flex-shrink:0}.mini-folder-container{position:relative;width:100%;height:100%;display:flex;flex-direction:column}.mini-folder-tab{width:50%;height:auto;display:block}.mini-folder-back{height:28px;border-radius:0 4px 4px;position:relative;margin-top:-1px}.mini-folder-front{position:absolute;bottom:0;left:0;right:0;height:24px;border-radius:4px;display:flex;align-items:center;justify-content:center;z-index:2;box-shadow:inset 0 8px 8px #fff3,inset 0 .5px .5px #ffffff4d}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }] });
11906
- }
11907
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsMobileHandbookFolderMiniComponent, decorators: [{
11908
- type: Component,
11909
- args: [{ selector: 'ds-mobile-handbook-folder-mini', standalone: true, imports: [CommonModule, DsIconComponent], template: `
11910
- <div class="mini-folder-container">
11911
- <!-- Folder Tab SVG -->
11912
- <svg
11913
- class="mini-folder-tab"
11914
- width="101"
11915
- height="24"
11916
- viewBox="0 0 101 24"
11917
- fill="none"
11918
- xmlns="http://www.w3.org/2000/svg">
11919
- <path
11920
- 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"
11921
- [attr.fill]="getColorVar('strong')"/>
11922
- </svg>
11923
-
11924
- <!-- Folder Back -->
11925
- <div class="mini-folder-back" [style.background-color]="getColorVar('strong')">
11926
- <!-- Folder Front -->
11927
- <div
11928
- class="mini-folder-front"
11929
- [style.background-color]="getColorVar('base')">
11930
- <ds-icon
11931
- [name]="iconName"
11932
- [size]="'14px'"
11933
- [style.color]="'white'" />
11934
- </div>
11935
- </div>
11936
- </div>
11937
- `, styles: [":host{display:inline-block;width:32px;height:32px;flex-shrink:0}.mini-folder-container{position:relative;width:100%;height:100%;display:flex;flex-direction:column}.mini-folder-tab{width:50%;height:auto;display:block}.mini-folder-back{height:28px;border-radius:0 4px 4px;position:relative;margin-top:-1px}.mini-folder-front{position:absolute;bottom:0;left:0;right:0;height:24px;border-radius:4px;display:flex;align-items:center;justify-content:center;z-index:2;box-shadow:inset 0 8px 8px #fff3,inset 0 .5px .5px #ffffff4d}\n"] }]
11938
- }], propDecorators: { variant: [{
11939
- type: Input
11940
- }], iconName: [{
11941
- type: Input
11942
- }] } });
11943
-
11944
- /**
11945
- * DsMobileCardInlineContactComponent
11946
- *
11947
- * Specialized interactive component for displaying contacts.
11948
- * Displays contact name with avatar initials and metadata (person name + phone number).
11949
- * Similar styling to file attachments with rounded corners and hover states.
11950
- *
11951
- * @example
11952
- * ```html
11953
- * <ds-mobile-card-inline-contact
11954
- * [name]="'Mortensen & Søn ApS'"
11955
- * [initials]="'M'"
11956
- * [contactPerson]="'John Mortensen'"
11957
- * [phoneNumber]="'+45 12 34 56 78'"
11958
- * [clickable]="true"
11959
- * (contactClick)="openContact()">
11960
- * </ds-mobile-card-inline-contact>
11961
- * ```
11962
- */
11963
- class DsMobileCardInlineContactComponent {
11964
- /**
11965
- * Contact/company name
11966
- */
11967
- name = input.required(...(ngDevMode ? [{ debugName: "name" }] : []));
11968
- /**
11969
- * Avatar initials (usually 1-2 letters)
11970
- */
11971
- initials = input.required(...(ngDevMode ? [{ debugName: "initials" }] : []));
11972
- /**
11973
- * Contact person name (optional)
11974
- */
11975
- contactPerson = input('', ...(ngDevMode ? [{ debugName: "contactPerson" }] : []));
11976
- /**
11977
- * Phone number (optional)
11978
- */
11979
- phoneNumber = input('', ...(ngDevMode ? [{ debugName: "phoneNumber" }] : []));
11980
- /**
11981
- * Layout variant
11982
- * - 'default' - Standard padding and column layout
11983
- * - 'compact' - Reduced padding and row layout
11984
- */
11985
- layout = input('default', ...(ngDevMode ? [{ debugName: "layout" }] : []));
11986
- /**
11987
- * Whether the contact item is clickable
11988
- */
11989
- clickable = input(true, ...(ngDevMode ? [{ debugName: "clickable" }] : []));
11990
- /**
11991
- * Whether to show chevron icon
11992
- */
11993
- showChevron = input(true, ...(ngDevMode ? [{ debugName: "showChevron" }] : []));
11994
- /**
11995
- * Emits when the contact item is clicked (if clickable)
11996
- */
11997
- contactClick = output();
11998
- handleContactClick() {
11999
- this.contactClick.emit();
12132
+ return `var(--color-${colorName}-${suffix})`;
12000
12133
  }
12001
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsMobileCardInlineContactComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12002
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DsMobileCardInlineContactComponent, isStandalone: true, selector: "ds-mobile-card-inline-contact", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, initials: { classPropertyName: "initials", publicName: "initials", isSignal: true, isRequired: true, transformFunction: null }, contactPerson: { classPropertyName: "contactPerson", publicName: "contactPerson", isSignal: true, isRequired: false, transformFunction: null }, phoneNumber: { classPropertyName: "phoneNumber", publicName: "phoneNumber", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null }, clickable: { classPropertyName: "clickable", publicName: "clickable", isSignal: true, isRequired: false, transformFunction: null }, showChevron: { classPropertyName: "showChevron", publicName: "showChevron", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { contactClick: "contactClick" }, ngImport: i0, template: `
12003
- <ds-mobile-card-inline
12004
- [variant]="layout()"
12005
- [disabled]="!clickable()"
12006
- (cardClick)="handleContactClick()">
12007
-
12008
- <div content-leading class="item-avatar">
12009
- <ds-avatar
12010
- [initials]="initials()"
12011
- type="initials"
12012
- [size]="layout() === 'compact' ? 'sm' : 'md'"
12013
- />
12014
- </div>
12015
-
12016
- <div content-main class="item-content">
12017
- <div class="item-name">{{ name() }}</div>
12018
-
12019
- @if (contactPerson() || phoneNumber()) {
12020
- <div class="item-meta">
12021
- @if (contactPerson()) {
12022
- <span>{{ contactPerson() }}</span>
12023
- }
12024
- @if (contactPerson() && phoneNumber()) {
12025
- <span>·</span>
12026
- }
12027
- @if (phoneNumber()) {
12028
- <span>{{ phoneNumber() }}</span>
12029
- }
12030
- </div>
12031
- }
12032
- </div>
12134
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsMobileHandbookFolderMiniComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12135
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: DsMobileHandbookFolderMiniComponent, isStandalone: true, selector: "ds-mobile-handbook-folder-mini", inputs: { variant: "variant", iconName: "iconName" }, ngImport: i0, template: `
12136
+ <div class="mini-folder-container">
12137
+ <!-- Folder Tab SVG -->
12138
+ <svg
12139
+ class="mini-folder-tab"
12140
+ width="101"
12141
+ height="24"
12142
+ viewBox="0 0 101 24"
12143
+ fill="none"
12144
+ xmlns="http://www.w3.org/2000/svg">
12145
+ <path
12146
+ 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"
12147
+ [attr.fill]="getColorVar('strong')"/>
12148
+ </svg>
12033
12149
 
12034
- @if (showChevron()) {
12035
- <div content-trailing class="item-trailing">
12036
- <ds-icon name="remixArrowRightSLine" size="20px" />
12150
+ <!-- Folder Back -->
12151
+ <div class="mini-folder-back" [style.background-color]="getColorVar('strong')">
12152
+ <!-- Folder Front -->
12153
+ <div
12154
+ class="mini-folder-front"
12155
+ [style.background-color]="getColorVar('base')">
12156
+ <ds-icon
12157
+ [name]="iconName"
12158
+ [size]="'14px'"
12159
+ [style.color]="'white'" />
12037
12160
  </div>
12038
- }
12039
- </ds-mobile-card-inline>
12040
- `, isInline: true, styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsAvatarComponent, selector: "ds-avatar", inputs: ["type", "size", "initials", "src", "alt", "iconName", "iconColor"] }, { kind: "component", type: DsMobileCardInlineComponent, selector: "ds-mobile-card-inline", inputs: ["variant", "disabled"], outputs: ["cardClick"] }] });
12161
+ </div>
12162
+ </div>
12163
+ `, isInline: true, styles: [":host{display:inline-block;width:32px;height:32px;flex-shrink:0}.mini-folder-container{position:relative;width:100%;height:100%;display:flex;flex-direction:column}.mini-folder-tab{width:50%;height:auto;display:block}.mini-folder-back{height:28px;border-radius:0 4px 4px;position:relative;margin-top:-1px}.mini-folder-front{position:absolute;bottom:0;left:0;right:0;height:24px;border-radius:4px;display:flex;align-items:center;justify-content:center;z-index:2;box-shadow:inset 0 8px 8px #fff3,inset 0 .5px .5px #ffffff4d}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }] });
12041
12164
  }
12042
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsMobileCardInlineContactComponent, decorators: [{
12165
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsMobileHandbookFolderMiniComponent, decorators: [{
12043
12166
  type: Component,
12044
- args: [{ selector: 'ds-mobile-card-inline-contact', standalone: true, imports: [CommonModule, DsIconComponent, DsAvatarComponent, DsMobileCardInlineComponent], template: `
12045
- <ds-mobile-card-inline
12046
- [variant]="layout()"
12047
- [disabled]="!clickable()"
12048
- (cardClick)="handleContactClick()">
12049
-
12050
- <div content-leading class="item-avatar">
12051
- <ds-avatar
12052
- [initials]="initials()"
12053
- type="initials"
12054
- [size]="layout() === 'compact' ? 'sm' : 'md'"
12055
- />
12056
- </div>
12057
-
12058
- <div content-main class="item-content">
12059
- <div class="item-name">{{ name() }}</div>
12060
-
12061
- @if (contactPerson() || phoneNumber()) {
12062
- <div class="item-meta">
12063
- @if (contactPerson()) {
12064
- <span>{{ contactPerson() }}</span>
12065
- }
12066
- @if (contactPerson() && phoneNumber()) {
12067
- <span>·</span>
12068
- }
12069
- @if (phoneNumber()) {
12070
- <span>{{ phoneNumber() }}</span>
12071
- }
12072
- </div>
12073
- }
12074
- </div>
12167
+ args: [{ selector: 'ds-mobile-handbook-folder-mini', standalone: true, imports: [CommonModule, DsIconComponent], template: `
12168
+ <div class="mini-folder-container">
12169
+ <!-- Folder Tab SVG -->
12170
+ <svg
12171
+ class="mini-folder-tab"
12172
+ width="101"
12173
+ height="24"
12174
+ viewBox="0 0 101 24"
12175
+ fill="none"
12176
+ xmlns="http://www.w3.org/2000/svg">
12177
+ <path
12178
+ 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"
12179
+ [attr.fill]="getColorVar('strong')"/>
12180
+ </svg>
12075
12181
 
12076
- @if (showChevron()) {
12077
- <div content-trailing class="item-trailing">
12078
- <ds-icon name="remixArrowRightSLine" size="20px" />
12182
+ <!-- Folder Back -->
12183
+ <div class="mini-folder-back" [style.background-color]="getColorVar('strong')">
12184
+ <!-- Folder Front -->
12185
+ <div
12186
+ class="mini-folder-front"
12187
+ [style.background-color]="getColorVar('base')">
12188
+ <ds-icon
12189
+ [name]="iconName"
12190
+ [size]="'14px'"
12191
+ [style.color]="'white'" />
12079
12192
  </div>
12080
- }
12081
- </ds-mobile-card-inline>
12082
- ` }]
12083
- }], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }], initials: [{ type: i0.Input, args: [{ isSignal: true, alias: "initials", required: true }] }], contactPerson: [{ type: i0.Input, args: [{ isSignal: true, alias: "contactPerson", required: false }] }], phoneNumber: [{ type: i0.Input, args: [{ isSignal: true, alias: "phoneNumber", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: false }] }], clickable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clickable", required: false }] }], showChevron: [{ type: i0.Input, args: [{ isSignal: true, alias: "showChevron", required: false }] }], contactClick: [{ type: i0.Output, args: ["contactClick"] }] } });
12193
+ </div>
12194
+ </div>
12195
+ `, styles: [":host{display:inline-block;width:32px;height:32px;flex-shrink:0}.mini-folder-container{position:relative;width:100%;height:100%;display:flex;flex-direction:column}.mini-folder-tab{width:50%;height:auto;display:block}.mini-folder-back{height:28px;border-radius:0 4px 4px;position:relative;margin-top:-1px}.mini-folder-front{position:absolute;bottom:0;left:0;right:0;height:24px;border-radius:4px;display:flex;align-items:center;justify-content:center;z-index:2;box-shadow:inset 0 8px 8px #fff3,inset 0 .5px .5px #ffffff4d}\n"] }]
12196
+ }], propDecorators: { variant: [{
12197
+ type: Input
12198
+ }], iconName: [{
12199
+ type: Input
12200
+ }] } });
12084
12201
 
12085
12202
  /**
12086
12203
  * DsMobileSwiperComponent
@@ -13145,7 +13262,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
13145
13262
  `, styles: [":host{display:block;position:fixed;z-index:1000;pointer-events:none}.fab-container{position:relative;pointer-events:none;animation:fabEnter .3s cubic-bezier(.4,0,.2,1) forwards}@keyframes fabEnter{0%{opacity:0;transform:scale(.8)}to{opacity:1;transform:scale(1)}}:host(.fab-bottom-right){bottom:88px;right:20px}:host(.fab-bottom-left){bottom:88px;left:20px}:host(.fab-bottom-center){bottom:88px;left:50%;transform:translate(-50%)}:host-context(body.plt-capacitor):not(.plt-desktop).fab-bottom-right,:host-context(body.plt-cordova):not(.plt-desktop).fab-bottom-right{bottom:calc(64px + env(safe-area-inset-bottom))!important}:host-context(body.plt-capacitor):not(.plt-desktop).fab-bottom-left,:host-context(body.plt-cordova):not(.plt-desktop).fab-bottom-left{bottom:calc(64px + env(safe-area-inset-bottom))!important}:host-context(body.plt-capacitor):not(.plt-desktop).fab-bottom-center,:host-context(body.plt-cordova):not(.plt-desktop).fab-bottom-center{bottom:calc(64px + env(safe-area-inset-bottom))!important}@supports (padding-right: env(safe-area-inset-right)){:host(.fab-bottom-right){right:calc(20px + env(safe-area-inset-right))}}@supports (padding-left: env(safe-area-inset-left)){:host(.fab-bottom-left){left:calc(20px + env(safe-area-inset-left))}}@media (min-width: 768px){:host-context(.plt-desktop).fab-bottom-right{bottom:40px;right:40px}:host-context(.plt-desktop).fab-bottom-left{bottom:40px;left:40px}:host-context(.plt-desktop).fab-bottom-center{bottom:40px}@supports (padding-right: env(safe-area-inset-right)){:host-context(.plt-desktop).fab-bottom-right{right:calc(40px + env(safe-area-inset-right))}}@supports (padding-left: env(safe-area-inset-left)){:host-context(.plt-desktop).fab-bottom-left{left:calc(40px + env(safe-area-inset-left))}}}.fab-button{pointer-events:auto;display:block}.fab-button::ng-deep button{width:56px!important;height:56px!important;min-width:56px!important;min-height:56px!important;border-radius:50%!important;padding:0!important;display:flex!important;align-items:center!important;justify-content:center!important;background:var(--color-background-brand)!important;color:var(--color-primary-content)!important;border:none!important;box-shadow:0 3px 5px -1px #0003,0 6px 10px #00000024,0 1px 18px #0000001f;transition:all .2s cubic-bezier(.4,0,.2,1)}.fab-button::ng-deep button:hover:not(:disabled){background:var(--color-brand-base-hover, var(--color-background-brand))!important;box-shadow:0 5px 7px -2px #0003,0 8px 14px #00000024,0 2px 22px #0000001f;transform:scale(1.05)}.fab-button::ng-deep button:active:not(:disabled){box-shadow:0 2px 4px -1px #0003,0 4px 8px #00000024,0 1px 14px #0000001f;transform:scale(.95)}.fab-button::ng-deep button:disabled{opacity:.5;cursor:not-allowed;box-shadow:0 2px 4px -1px #0000001a,0 4px 8px #00000014,0 1px 14px #0000000f}.fab-button::ng-deep button .btn__icon,.fab-button::ng-deep button .btn__icon svg{color:var(--color-primary-content)!important;fill:var(--color-primary-content)!important}.fab-button::ng-deep button .btn__icon{display:flex!important;align-items:center!important;justify-content:center!important;flex-shrink:0!important}.fab-button::ng-deep button .btn__icon svg{width:24px!important;height:24px!important}\n"] }]
13146
13263
  }], propDecorators: { icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], fabClick: [{ type: i0.Output, args: ["fabClick"] }] } });
13147
13264
 
13148
- // Mobile Page Components
13265
+ // Page Components
13149
13266
 
13150
13267
  /**
13151
13268
  * PostsService
@@ -15161,123 +15278,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
15161
15278
  `, styles: [".inquiries-container{display:flex;flex-direction:column}.inquiry-list-wrapper{display:flex;flex-direction:column;margin-top:-8px}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;text-align:center}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;color:var(--color-text-primary);margin:16px 0 8px}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);color:var(--color-text-secondary);margin:0}\n"] }]
15162
15279
  }], ctorParameters: () => [{ type: UserService }, { type: i1.NavController }, { type: DsMobileNewInquiryModalService }] });
15163
15280
 
15164
- /**
15165
- * DsMobileCardInlineBannerComponent
15166
- *
15167
- * Specialized interactive component for displaying notification banners.
15168
- * Used to show unread message notifications above inquiry details.
15169
- *
15170
- * Features:
15171
- * - Neutral background matching file/contact cards
15172
- * - Avatar icon with message symbol
15173
- * - Title and timestamp
15174
- * - Unread count badge
15175
- * - Chevron for navigation indication
15176
- *
15177
- * @example
15178
- * ```html
15179
- * <ds-mobile-card-inline-banner
15180
- * [title]="'New messages'"
15181
- * [timestamp]="'2 min ago'"
15182
- * [unreadCount]="3"
15183
- * (bannerClick)="navigateToMessages()">
15184
- * </ds-mobile-card-inline-banner>
15185
- * ```
15186
- */
15187
- class DsMobileCardInlineBannerComponent {
15188
- /**
15189
- * Banner title (e.g., "New messages", "Unread messages")
15190
- */
15191
- title = input.required(...(ngDevMode ? [{ debugName: "title" }] : []));
15192
- /**
15193
- * Timestamp text (e.g., "2 min ago", "Just now")
15194
- */
15195
- timestamp = input('', ...(ngDevMode ? [{ debugName: "timestamp" }] : []));
15196
- /**
15197
- * Number of unread items (optional, shows badge if > 0)
15198
- */
15199
- unreadCount = input(0, ...(ngDevMode ? [{ debugName: "unreadCount" }] : []));
15200
- /**
15201
- * Layout variant
15202
- * - 'default' - Standard padding and column layout
15203
- * - 'compact' - Reduced padding and row layout
15204
- */
15205
- layout = input('default', ...(ngDevMode ? [{ debugName: "layout" }] : []));
15206
- /**
15207
- * Emits when the banner is clicked
15208
- */
15209
- bannerClick = output();
15210
- handleBannerClick() {
15211
- this.bannerClick.emit();
15212
- }
15213
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsMobileCardInlineBannerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
15214
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DsMobileCardInlineBannerComponent, isStandalone: true, selector: "ds-mobile-card-inline-banner", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, timestamp: { classPropertyName: "timestamp", publicName: "timestamp", isSignal: true, isRequired: false, transformFunction: null }, unreadCount: { classPropertyName: "unreadCount", publicName: "unreadCount", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { bannerClick: "bannerClick" }, ngImport: i0, template: `
15215
- <ds-mobile-card-inline
15216
- [variant]="layout()"
15217
- (cardClick)="handleBannerClick()">
15218
-
15219
- <div content-leading class="item-avatar">
15220
- <ds-avatar
15221
- type="icon"
15222
- [iconName]="'remixNotificationLine'"
15223
- [size]="layout() === 'compact' ? 'sm' : 'md'"
15224
- />
15225
- </div>
15226
-
15227
- <div content-main class="item-content">
15228
- <div class="item-name">{{ title() }}</div>
15229
-
15230
- @if (timestamp()) {
15231
- <div class="item-meta">
15232
- <span>{{ timestamp() }}</span>
15233
- </div>
15234
- }
15235
- </div>
15236
-
15237
- <div content-trailing class="item-trailing">
15238
- @if (unreadCount() && unreadCount()! > 0) {
15239
- <span class="unread-badge">{{ unreadCount() }}</span>
15240
- }
15241
- <ds-icon name="remixArrowRightSLine" size="20px" />
15242
- </div>
15243
- </ds-mobile-card-inline>
15244
- `, isInline: true, styles: [".unread-badge{min-width:24px;height:16px;padding:0 6px;border-radius:10px;background:var(--color-background-neutral-tertiary, #e5e5e5);color:var(--color-text-primary, #1a1a1a);font-family:Brockmann,sans-serif;font-size:var(--font-size-xs);font-weight:600;display:flex;align-items:center;justify-content:center;line-height:1;margin-right:8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsAvatarComponent, selector: "ds-avatar", inputs: ["type", "size", "initials", "src", "alt", "iconName", "iconColor"] }, { kind: "component", type: DsMobileCardInlineComponent, selector: "ds-mobile-card-inline", inputs: ["variant", "disabled"], outputs: ["cardClick"] }] });
15245
- }
15246
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsMobileCardInlineBannerComponent, decorators: [{
15247
- type: Component,
15248
- args: [{ selector: 'ds-mobile-card-inline-banner', standalone: true, imports: [CommonModule, DsIconComponent, DsAvatarComponent, DsMobileCardInlineComponent], template: `
15249
- <ds-mobile-card-inline
15250
- [variant]="layout()"
15251
- (cardClick)="handleBannerClick()">
15252
-
15253
- <div content-leading class="item-avatar">
15254
- <ds-avatar
15255
- type="icon"
15256
- [iconName]="'remixNotificationLine'"
15257
- [size]="layout() === 'compact' ? 'sm' : 'md'"
15258
- />
15259
- </div>
15260
-
15261
- <div content-main class="item-content">
15262
- <div class="item-name">{{ title() }}</div>
15263
-
15264
- @if (timestamp()) {
15265
- <div class="item-meta">
15266
- <span>{{ timestamp() }}</span>
15267
- </div>
15268
- }
15269
- </div>
15270
-
15271
- <div content-trailing class="item-trailing">
15272
- @if (unreadCount() && unreadCount()! > 0) {
15273
- <span class="unread-badge">{{ unreadCount() }}</span>
15274
- }
15275
- <ds-icon name="remixArrowRightSLine" size="20px" />
15276
- </div>
15277
- </ds-mobile-card-inline>
15278
- `, styles: [".unread-badge{min-width:24px;height:16px;padding:0 6px;border-radius:10px;background:var(--color-background-neutral-tertiary, #e5e5e5);color:var(--color-text-primary, #1a1a1a);font-family:Brockmann,sans-serif;font-size:var(--font-size-xs);font-weight:600;display:flex;align-items:center;justify-content:center;line-height:1;margin-right:8px}\n"] }]
15279
- }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], timestamp: [{ type: i0.Input, args: [{ isSignal: true, alias: "timestamp", required: false }] }], unreadCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "unreadCount", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: false }] }], bannerClick: [{ type: i0.Output, args: ["bannerClick"] }] } });
15280
-
15281
15281
  class MobileInquiryDetailPageComponent {
15282
15282
  userService;
15283
15283
  lightbox;
@@ -17134,5 +17134,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
17134
17134
  * Generated bundle index. Do not edit.
17135
17135
  */
17136
17136
 
17137
- export { ActionCommentComponent, ActionLikeComponent, ContentRowComponent, DsAvatarWithBadgeComponent, DsMobileActionsBottomSheetComponent, DsMobileAttachmentPreviewComponent, DsMobileBottomSheetService, DsMobileChatModalComponent, DsMobileChatModalService, DsMobileActionsBottomSheetComponent as DsMobileCommentActionsBottomSheetComponent, DsMobileCommentComponent, DsMobileContactListItemComponent, DsMobileContentComponent, DsMobileContentSectionComponent, DsMobileFabComponent, DsMobileHandbookDetailModalComponent, DsMobileHandbookDetailModalService, DsMobileHandbookFolderComponent, DsMobileHandbookFolderMiniComponent, DsMobileHeaderContentComponent, DsMobileHeaderContentTileComponent, DsMobileInlinePhotoComponent, DsMobileInlineTabsComponent, DsMobileInteractiveListItemInquiryComponent, DsMobileInteractiveListItemMessageComponent, DsMobileInteractiveListItemPostComponent, DsMobileLightboxImageComponent as DsMobileLightboxComponent, DsMobileLightboxFooterComponent, DsMobileLightboxHeaderComponent, DsMobileLightboxImageComponent, DsMobileLightboxPdfComponent, DsMobileLightboxService, DsMobileListItemComponent, DsMobileListItemStaticComponent, DsMobileLongPressDirective, DsMobileMessageBubbleComponent, DsMobileMessageComposerComponent, DsMobileModalBaseComponent, DsMobileModalService, DsMobileNewInquiryModalComponent, DsMobileNewInquiryModalService, DsMobilePageDetailsComponent, DsMobilePageMainComponent, DsMobileActionsBottomSheetComponent as DsMobilePostActionsBottomSheetComponent, DsMobilePostComposerComponent, DsMobilePostCreateBottomSheetComponent, DsMobilePostDetailModalComponent, DsMobilePostDetailModalService, DsMobileTabBarComponent, DsMobileTabsComponent, DsTextInputComponent, MobileCommunityPageComponent, MobileHandbookPageComponent, MobileHomePageComponent, MobileInquiriesPageComponent, MobileInquiryDetailPageComponent, MobileModalBase, MobilePageBase, MobilePostDetailPageComponent, MobileTabsExampleComponent, PostActionsComponent, PostAttachmentsComponent, PostContentComponent, PostCreatePageComponent, PostMediaComponent, PostPdfAttachmentComponent, PostTextComponent, SectionHeaderComponent, SignInPageComponent, TileContentComponent, TileIconComponent, TileLabelComponent, TileValueComponent, UserService, WhitelabelDemoPage, WhitelabelService, customBackTransition, customPageTransition };
17137
+ export { ActionCommentComponent, ActionLikeComponent, ContentRowComponent, DsAvatarWithBadgeComponent, DsMobileActionsBottomSheetComponent, DsMobileAttachmentPreviewComponent, DsMobileBottomSheetService, DsMobileCardInlineBannerComponent, DsMobileCardInlineComponent, DsMobileCardInlineContactComponent, DsMobileCardInlineFileComponent, DsMobileChatModalComponent, DsMobileChatModalService, DsMobileActionsBottomSheetComponent as DsMobileCommentActionsBottomSheetComponent, DsMobileCommentComponent, DsMobileContactListItemComponent, DsMobileContentComponent, DsMobileContentSectionComponent, DsMobileFabComponent, DsMobileHandbookDetailModalComponent, DsMobileHandbookDetailModalService, DsMobileHandbookFolderComponent, DsMobileHandbookFolderMiniComponent, DsMobileHeaderContentComponent, DsMobileHeaderContentTileComponent, DsMobileInlinePhotoComponent, DsMobileInlineTabsComponent, DsMobileInteractiveListItemInquiryComponent, DsMobileInteractiveListItemMessageComponent, DsMobileInteractiveListItemPostComponent, DsMobileLightboxImageComponent as DsMobileLightboxComponent, DsMobileLightboxFooterComponent, DsMobileLightboxHeaderComponent, DsMobileLightboxImageComponent, DsMobileLightboxPdfComponent, DsMobileLightboxService, DsMobileListItemComponent, DsMobileListItemStaticComponent, DsMobileLongPressDirective, DsMobileMessageBubbleComponent, DsMobileMessageComposerComponent, DsMobileModalBaseComponent, DsMobileModalService, DsMobileNewInquiryModalComponent, DsMobileNewInquiryModalService, DsMobilePageDetailsComponent, DsMobilePageMainComponent, DsMobileActionsBottomSheetComponent as DsMobilePostActionsBottomSheetComponent, DsMobilePostComposerComponent, DsMobilePostCreateBottomSheetComponent, DsMobilePostDetailModalComponent, DsMobilePostDetailModalService, DsMobileTabBarComponent, DsMobileTabsComponent, DsTextInputComponent, MobileCommunityPageComponent, MobileHandbookPageComponent, MobileHomePageComponent, MobileInquiriesPageComponent, MobileInquiryDetailPageComponent, MobileModalBase, MobilePageBase, MobilePostDetailPageComponent, MobileTabsExampleComponent, PostActionsComponent, PostAttachmentsComponent, PostContentComponent, PostCreatePageComponent, PostMediaComponent, PostPdfAttachmentComponent, PostTextComponent, SectionHeaderComponent, SignInPageComponent, TileContentComponent, TileIconComponent, TileLabelComponent, TileValueComponent, UserService, WhitelabelDemoPage, WhitelabelService, customBackTransition, customPageTransition };
17138
17138
  //# sourceMappingURL=propbinder-mobile-design.mjs.map