Skip to content

Commit 20f2c56

Browse files
committed
feat: modal grow only mode added
1 parent e3248b3 commit 20f2c56

File tree

4 files changed

+66
-18
lines changed

4 files changed

+66
-18
lines changed

projects/mantic-ui/src/lib/components/modal/modal.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
<div *ngIf="showHeader" [class.ui]="basic" [class.icon]="basic" class="header">
44
<ng-content select="m-modal-header" />
55
<m-modal-header *m-fallback-for="'m-modal-header'">
6-
{{header}}
6+
{{ header }}
77
</m-modal-header>
88
<ng-container *ngIf="basic && showClose === true || !basic && (showClose || showClose === undefined)">
99
<m-icon *ngIf="closeIcon || defaults.closeIcon" [icon]="closeIcon ?? defaults.closeIcon" class="close" (click)="onClose()" />
1010
</ng-container>
1111
</div>
12-
<div [class.image]="imageContent" [class.scrolling]="scrolling" class="content" [class.no-padding]="noPadding" [style.min-height]="minContentHeight" [style.max-height]="maxContentHeight">
12+
<div [class.image]="imageContent" [class.scrolling]="scrolling" class="content" [class.no-padding]="noPadding" [style.min-height]="minContentHeight" [style.min-height.px]="minGrowOnlyContentHeight" [style.max-height]="maxContentHeight" #content>
1313
<ng-content />
1414
<m-dimmer *ngIf="loading" inverted>
1515
<m-loader />

projects/mantic-ui/src/lib/components/modal/modal.component.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { CommonModule } from '@angular/common';
2-
import { Component, EventEmitter, HostBinding, inject, Input, Output } from '@angular/core';
2+
import { Component, effect, ElementRef, EventEmitter, HostBinding, inject, input, Input, Output, viewChild } from '@angular/core';
33
import { ReplaySubject } from 'rxjs';
44
import { takeUntil } from 'rxjs/operators';
55
import { InvertibleComponent } from '../../base/invertible.component';
66
import { BasicDirective } from '../../directives/basic.directive';
77
import { FallbackForDirective } from '../../directives/fallback-for.directive';
8+
import { toBoolean } from '../../helpers/to-boolean';
89
import { BooleanLike } from '../../models/boolean-like';
910
import { ButtonComponent } from '../button/button.component';
1011
import { DimmerComponent } from '../dimmer/dimmer.component';
@@ -45,10 +46,15 @@ export class ModalComponent extends InvertibleComponent {
4546
private isScrolling = true;
4647
private isNoPadding = false;
4748
private isLoading = false;
49+
private readonly resizeObserver = new ResizeObserver(() => this.onResize());
50+
protected minGrowOnlyContentHeight = 0;
4851

4952
private readonly basicDirective = inject(BasicDirective, { self: true });
5053
protected readonly defaults = ModalComponent.defaults;
5154

55+
public readonly growOnly = input<boolean, BooleanLike>(false, { transform: toBoolean });
56+
public readonly contentElementRef = viewChild<ElementRef<HTMLElement>>('content');
57+
5258
protected get basic(): boolean {
5359
return this.basicDirective.basic;
5460
}
@@ -184,6 +190,22 @@ export class ModalComponent extends InvertibleComponent {
184190
super(false);
185191
this.classes.register('visible', 'fullscreen', 'size', 'scrolling', 'imageContent', 'header', 'footer', 'showHeader', 'hideHeader', 'showFooter', 'hideFooter', 'hideDimmer', 'showClose', 'minContentHeight', 'maxContentHeight');
186192
ModalComponent.defaults.invertedChange.pipe(takeUntil(this.destroy)).subscribe(value => this.refreshInverted(value));
193+
194+
effect(() => {
195+
const growOnly = this.growOnly();
196+
const ref = this.contentElementRef();
197+
if (!ref) {
198+
return;
199+
}
200+
if (growOnly) {
201+
this.resizeObserver.observe(ref.nativeElement);
202+
this.onResize();
203+
}
204+
else {
205+
this.minGrowOnlyContentHeight = 0;
206+
this.resizeObserver.unobserve(ref.nativeElement);
207+
}
208+
});
187209
}
188210

189211
protected onClose(): void {
@@ -199,4 +221,8 @@ export class ModalComponent extends InvertibleComponent {
199221
this.onClose();
200222
}
201223
}
224+
225+
private onResize(): void {
226+
this.minGrowOnlyContentHeight = Math.max(this.minGrowOnlyContentHeight ?? 0, this.contentElementRef()?.nativeElement.clientHeight ?? 0);
227+
}
202228
}

src/app/examples/modal/modal.component.html

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<m-tab label="Examples">
55
<m-example header="Modal" description="A standard modal" [code]="standardCode">
66
<m-button (click)="showModal = true">Open Modal</m-button>
7-
{{showModal}}
7+
{{ showModal }}
88
<m-modal *ngIf="showModal" imageContent (close)="showModal = false">
99
<m-modal-header>
1010
<m-icon icon="question"></m-icon>
@@ -106,7 +106,7 @@ <h2 m-header dividing>Content</h2>
106106
</m-tab>
107107
<m-tab label="Variations">
108108
<m-example header="Show close button" description="A modal can have a close button">
109-
<m-example-code [code]="showCloseCode"/>
109+
<m-example-code [code]="showCloseCode" />
110110
<ng-container>
111111
<m-modal *ngIf="showWithClose" showClose hideFooter (close)="showWithClose = false">
112112
Some content
@@ -116,7 +116,7 @@ <h2 m-header dividing>Content</h2>
116116
</m-example>
117117

118118
<m-example header="Hide header" description="Show a modal without a header">
119-
<m-example-code [code]="hideHeaderCode"/>
119+
<m-example-code [code]="hideHeaderCode" />
120120
<ng-container>
121121
<m-modal *ngIf="showWithoutHeader" hideHeader (close)="showWithoutHeader = false">
122122
Some content
@@ -126,7 +126,7 @@ <h2 m-header dividing>Content</h2>
126126
</m-example>
127127

128128
<m-example header="Hide footer" description="Show a modal without a footer">
129-
<m-example-code [code]="hideFooterCode"/>
129+
<m-example-code [code]="hideFooterCode" />
130130
<ng-container>
131131
<m-modal *ngIf="showWithoutFooter" header="Header" hideFooter showClose (close)="showWithoutFooter = false">
132132
Some content
@@ -136,7 +136,7 @@ <h2 m-header dividing>Content</h2>
136136
</m-example>
137137

138138
<m-example header="Hide dimmer" description="Show a modal without a dimmer">
139-
<m-example-code [code]="hideDimmerCode"/>
139+
<m-example-code [code]="hideDimmerCode" />
140140
<ng-container>
141141
<m-modal *ngIf="showWithoutDimmer" hideDimmer (close)="showWithoutDimmer = false">
142142
Some content
@@ -164,15 +164,15 @@ <h2 m-header dividing>Content</h2>
164164
</m-example>
165165

166166
<m-example header="Without content padding" description="Removes the padding of the modal content">
167-
<m-example-code [code]="noPaddingCode"/>
167+
<m-example-code [code]="noPaddingCode" />
168168
<m-modal *ngIf="showNoPadding" noPadding (close)="showNoPadding = false">
169169
This modal has no content padding
170170
</m-modal>
171171
<m-button (click)="showNoPadding = true">Open without padding</m-button>
172172
</m-example>
173173

174174
<m-example header="Inverted" description="A modal can be displayed with inverted colors">
175-
<m-example-code [code]="invertedCode"/>
175+
<m-example-code [code]="invertedCode" />
176176
<ng-container>
177177
<m-modal *ngIf="showInverted" header="Inverted" inverted (close)="showInverted = false">
178178
The colors are inverted
@@ -182,7 +182,7 @@ <h2 m-header dividing>Content</h2>
182182
</m-example>
183183

184184
<m-example header="Loading" description="A modal can have a spinner">
185-
<m-example-code [code]="loadingCode"/>
185+
<m-example-code [code]="loadingCode" />
186186
<ng-container>
187187
<m-modal *ngIf="showLoading" header="Loading..." loading (close)="showLoading = false">
188188
Some content
@@ -238,8 +238,20 @@ <h2 m-header dividing>Content</h2>
238238
</ng-container>
239239
<m-button (click)="showChangeIcon = true">Show with changed Item</m-button>
240240
</m-example>
241+
242+
<m-example header="Grow Only" description="The modal can grow based on its content but can not shrink" [code]="growOnlyCode">
243+
<m-button (click)="showGrowOnly = true">Show</m-button>
244+
<m-modal *ngIf="showGrowOnly" growOnly header="I grow only" (close)="showGrowOnly = false">
245+
<m-flex gap="1rem">
246+
<m-button primary (click)="grow()">Grow</m-button>
247+
<m-button primary [disabled]="growOnlyRows <= 0" (click)="shrink()">Shrink</m-button>
248+
</m-flex>
249+
<p>Click button to grow modal!</p>
250+
<p *ngFor="let number of growOnlyRows | mArray">BIGGER {{ number + 1 }}!</p>
251+
</m-modal>
252+
</m-example>
241253
</m-tab>
242-
<m-tab label="Binding">
243-
<!-- TODO -->
244-
</m-tab>
254+
<!-- <m-tab label="Binding">-->
255+
<!-- TODO -->
256+
<!-- </m-tab>-->
245257
</m-tab-group>

src/app/examples/modal/modal.component.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1+
import { CommonModule } from '@angular/common';
12
import { Component } from '@angular/core';
23
import { faRocket } from '@fortawesome/pro-solid-svg-icons';
3-
import { ButtonComponent, DropdownComponent, DropdownItemComponent, HeaderDirective, IconComponent, ModalComponent, ModalDefaultsComponent, ModalFooterComponent, ModalHeaderComponent, ModalSize, TabComponent, TabGroupComponent, ToBodyDirective } from '@mantic-ui/angular';
4-
import { CommonModule } from '@angular/common';
5-
import { HeaderComponent } from '../../components/header/header.component';
4+
import { ArrayPipe, ButtonComponent, DropdownComponent, DropdownItemComponent, FlexComponent, HeaderDirective, IconComponent, ModalComponent, ModalDefaultsComponent, ModalFooterComponent, ModalHeaderComponent, ModalSize, TabComponent, TabGroupComponent, ToBodyDirective } from '@mantic-ui/angular';
65
import { ExampleCodeComponent, ExampleComponent } from '@mantic-ui/angular-doc';
6+
import { HeaderComponent } from '../../components/header/header.component';
77

88
@Component({
99
selector: 'app-modal-example',
10-
imports: [CommonModule, HeaderComponent, TabGroupComponent, TabComponent, IconComponent, HeaderDirective, ExampleComponent, ExampleCodeComponent, ButtonComponent, ModalComponent, ModalHeaderComponent, ModalFooterComponent, ToBodyDirective, DropdownComponent, DropdownItemComponent, ModalDefaultsComponent],
10+
imports: [CommonModule, HeaderComponent, TabGroupComponent, TabComponent, IconComponent, HeaderDirective, ExampleComponent, ExampleCodeComponent, ButtonComponent, ModalComponent, ModalHeaderComponent, ModalFooterComponent, ToBodyDirective, DropdownComponent, DropdownItemComponent, ModalDefaultsComponent, ArrayPipe, FlexComponent],
1111
templateUrl: './modal.component.html',
1212
styleUrls: ['./modal.component.scss']
1313
})
@@ -29,6 +29,8 @@ export class ModalExampleComponent {
2929
public showWithoutFooter = false;
3030
public showWithoutDimmer = false;
3131
public showWithClose = false;
32+
public showGrowOnly = false;
33+
protected growOnlyRows = 0;
3234
protected readonly faRocket = faRocket;
3335

3436
public standardCode = `<m-button (click)="showModal = true">Open</m-button>
@@ -109,5 +111,13 @@ public size: ModalSize = 'mini';`;
109111
protected hideFooterCode = `<m-modal hideFooter />`;
110112
protected hideDimmerCode = `<m-modal hideDimmer />`;
111113
protected showCloseCode = `<m-modal showClose />`;
114+
protected growOnlyCode = `<m-modal growOnly />`;
115+
116+
protected grow(): void {
117+
this.growOnlyRows++;
118+
}
112119

120+
protected shrink(): void {
121+
this.growOnlyRows--;
122+
}
113123
}

0 commit comments

Comments
 (0)