@hug/ngx-layout 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,11 @@
1
+ ## 1.1.0 (2024-06-26)
2
+
3
+
4
+ ### 🚀 Features
5
+
6
+ - **layout:** first commit ([70a9056](https://github.com/DSI-HUG/ngx-components/commit/70a9056))
7
+
8
+
9
+ ### ❤️ Thank You
10
+
11
+ - Badisi
package/README.md ADDED
@@ -0,0 +1,6 @@
1
+ @hug/layout
2
+ =======
3
+
4
+ The sources for this package are in the main [DSI-HUG/ngx-components](https://github.com/dsi-hug/ngx-components) repo. Please file issues and pull requests against that repo.
5
+
6
+ License: GPL-3.0-only
package/karma.conf.js ADDED
@@ -0,0 +1,45 @@
1
+ // Karma configuration file, see link for more information
2
+ // https://karma-runner.github.io/1.0/config/configuration-file.html
3
+
4
+ module.exports = config => {
5
+ config.set({
6
+ basePath: '',
7
+ frameworks: ['jasmine', '@angular-devkit/build-angular'],
8
+ plugins: [
9
+ require('karma-jasmine'),
10
+ require('karma-chrome-launcher'),
11
+ require('karma-jasmine-html-reporter'),
12
+ require('karma-coverage'),
13
+ require('@angular-devkit/build-angular/plugins/karma')
14
+ ],
15
+ client: {
16
+ jasmine: {
17
+ // you can add configuration options for Jasmine here
18
+ // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
19
+ // for example, you can disable the random execution with `random: false`
20
+ // or set a specific seed with `seed: 4321`
21
+ },
22
+ clearContext: false // leave Jasmine Spec Runner output visible in browser
23
+ },
24
+ jasmineHtmlReporter: {
25
+ suppressAll: true // removes the duplicated traces
26
+ },
27
+ coverageReporter: {
28
+ dir: require('path').join(__dirname, '../../coverage/layout'),
29
+ subdir: '.',
30
+ reporters: [
31
+ { type: 'html' },
32
+ { type: 'text-summary' }
33
+ ]
34
+ },
35
+ reporters: ['progress', 'kjhtml'],
36
+ port: 9876,
37
+ colors: true,
38
+ logLevel: config.LOG_INFO,
39
+ autoWatch: true,
40
+ browsers: ['Chrome'],
41
+ singleRun: false,
42
+ failOnEmptyTestSuite: false,
43
+ restartOnFileChange: true
44
+ });
45
+ };
@@ -0,0 +1,15 @@
1
+ {
2
+ "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3
+ "dest": "../../dist/layout",
4
+ "assets": [
5
+ "CHANGELOG.md",
6
+ {
7
+ "input": "src/",
8
+ "glob": "_layout-theme.scss",
9
+ "output": "."
10
+ }
11
+ ],
12
+ "lib": {
13
+ "entryFile": "src/index.ts"
14
+ }
15
+ }
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@hug/ngx-layout",
3
+ "version": "1.1.0",
4
+ "description": "HUG Angular - layout component",
5
+ "homepage": "https://github.com/dsi-hug/ngx-components",
6
+ "license": "GPL-3.0-only",
7
+ "author": "HUG - Hôpitaux Universitaires Genève",
8
+ "contributors": [
9
+ "badisi (https://github.com/badisi)",
10
+ "vapkse (https://github.com/vapkse)"
11
+ ],
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/dsi-hug/ngx-components.git"
15
+ },
16
+ "keywords": [
17
+ "angular",
18
+ "material",
19
+ "material design",
20
+ "components"
21
+ ],
22
+ "sideEffects": false,
23
+ "scripts": {
24
+ "lint": "eslint . --fix",
25
+ "test": "ng test layout",
26
+ "test:ci": "ng test layout --watch=false --browsers=ChromeHeadless",
27
+ "build:ng": "ng build layout -c=production",
28
+ "build": "nx build:ng @hug/ngx-layout --verbose",
29
+ "release": "nx release -p=@hug/ngx-layout --yes --verbose",
30
+ "release:dry-run": "nx release -p=@hug/ngx-layout --verbose --dry-run"
31
+ },
32
+ "peerDependencies": {
33
+ "@angular/common": ">= 14",
34
+ "@angular/core": ">= 14",
35
+ "@angular/cdk": ">= 14",
36
+ "@angular/material": ">= 14",
37
+ "@hug/ngx-core": "1.1.5",
38
+ "@hug/ngx-sidenav": "1.1.0"
39
+ },
40
+ "dependencies": {
41
+ "tslib": "^2.6.3"
42
+ },
43
+ "publishConfig": {
44
+ "access": "public"
45
+ }
46
+ }
@@ -0,0 +1,136 @@
1
+ @use '@angular/material'as mat;
2
+
3
+ @mixin layout-theme($theme) {
4
+ $primary: map-get($theme, primary);
5
+ $accent: map-get($theme, accent);
6
+ $background: map-get($theme, background);
7
+ $foreground: map-get($theme, foreground);
8
+
9
+ layout>.mat-toolbar.mat-primary {
10
+ background-color: mat.get-color-from-palette($primary, darker);
11
+ color: mat.get-color-from-palette($primary, darker-contrast);
12
+
13
+ .mat-icon-button:not([disabled]) .mat-icon {
14
+ color: mat.get-color-from-palette($primary, darker-contrast);
15
+ }
16
+
17
+ &:not(:first-of-type) {
18
+ background-color: mat.get-color-from-palette($primary);
19
+ color: mat.get-color-from-palette($primary, default-contrast);
20
+
21
+ .mat-icon-button:not([disabled]) .mat-icon {
22
+ color: mat.get-color-from-palette($primary, default-contrast);
23
+ }
24
+ }
25
+ }
26
+
27
+ layout {
28
+ mat-drawer {
29
+ &.right {
30
+ [filters-title] {
31
+ color: mat.get-color-from-palette($foreground, secondary-text);
32
+ background-color: mat.get-color-from-palette($background, disabled-button-toggle);
33
+ }
34
+
35
+ [filters-subtitle] {
36
+ color: mat.get-color-from-palette($foreground, secondary-text);
37
+ background-color: mat.get-color-from-palette($background, hover);
38
+ }
39
+
40
+ [filters-icon] {
41
+ color: mat.get-color-from-palette($foreground, text);
42
+
43
+ &:hover {
44
+ color: mat.get-color-from-palette($foreground, secondary-text);
45
+ }
46
+ }
47
+
48
+ [filters-chip-list] {
49
+ .mat-standard-chip {
50
+ background-color: mat.get-color-from-palette($accent);
51
+ color: mat.get-color-from-palette($background, background);
52
+ }
53
+
54
+ .mat-standard-chip {
55
+ &:not([disabled]) {
56
+ &:hover {
57
+ background-color: mat.get-color-from-palette($accent, 700);
58
+ color: mat.get-color-from-palette($accent, 600);
59
+
60
+ &:before {
61
+ color: mat.get-color-from-palette($background, background);
62
+ }
63
+ }
64
+ }
65
+ }
66
+ }
67
+
68
+ [filters-toggle-group] {
69
+ .mat-button-toggle {
70
+ color: mat.get-color-from-palette($foreground, secondary-text);
71
+
72
+ &.mat-button-toggle-checked {
73
+ background-color: mat.get-color-from-palette($accent);
74
+ color: mat.get-color-from-palette($background, background);
75
+ }
76
+
77
+ &:not(:has(button[disabled])) {
78
+ &:hover {
79
+ background-color: mat.get-color-from-palette($accent, 200);
80
+ color: mat.get-color-from-palette($background, background);
81
+ }
82
+ }
83
+ }
84
+ }
85
+ }
86
+ }
87
+
88
+ mat-button-toggle-group {
89
+ &:not([filters-toggle-group]):not([color="accent"]):not([color="primary"]) {
90
+ mat-button-toggle {
91
+ button {
92
+ .mat-button-toggle-label-content {
93
+ color: mat.get-color-from-palette($foreground, secondary-text);
94
+ }
95
+ }
96
+ }
97
+ }
98
+ }
99
+
100
+ mat-toolbar {
101
+ &.actions {
102
+ .info-boxes-container {
103
+ .info-box {
104
+ &.accent {
105
+ background-color: mat.get-color-from-palette($accent);
106
+ color: mat.get-color-from-palette($accent, default-contrast);
107
+ }
108
+
109
+ &.primary {
110
+ background-color: mat.get-color-from-palette($primary, 800);
111
+ color: mat.get-color-from-palette($primary, default-contrast);
112
+ }
113
+ }
114
+ }
115
+ }
116
+ }
117
+
118
+ // Custom scrollbar
119
+ ::-webkit-scrollbar-track {
120
+ background-color: mat.get-color-from-palette($background, background);
121
+ }
122
+
123
+ ::-webkit-scrollbar-thumb {
124
+ background-color: mat.get-color-from-palette($foreground, hint-text);
125
+ border: 2px solid mat.get-color-from-palette($background, background);
126
+ }
127
+
128
+ ::-webkit-scrollbar-thumb:hover {
129
+ background-color: mat.get-color-from-palette($foreground, secondary-text);
130
+ }
131
+
132
+ .editor-toolbar-wrapper {
133
+ background-color: mat.get-color-from-palette($background, background);
134
+ }
135
+ }
136
+ }
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './layout.component';
@@ -0,0 +1,60 @@
1
+ <ng-container *ngTemplateOutlet="filter"></ng-container>
2
+
3
+ <ng-template #content>
4
+ <div class="main-content">
5
+ <span class="primary-action-container" [class.bottom]="(mediaService.isHandset$ | async)" *ngIf="layoutPrimaryAction && !((layoutActions || layoutInfoBoxes) && ((mediaService.isHandset$ | async) === false))">
6
+ <ng-template [ngTemplateOutlet]="layoutPrimaryAction"></ng-template>
7
+ </span>
8
+ <ng-content></ng-content>
9
+ </div>
10
+ <ng-container *ngIf="(mediaService.isHandset$ | async) && actionsToolbar">
11
+ <ng-container *ngTemplateOutlet="actionsToolbar"></ng-container>
12
+ </ng-container>
13
+ </ng-template>
14
+
15
+ <ng-template #actionsToolbar>
16
+ <mat-toolbar id="actions-toolbar" class="actions" [color]="toolbarColor" [class.bottom]="(mediaService.isHandset$ | async)">
17
+ <span class="primary-action-container" *ngIf="layoutPrimaryAction && (layoutActions || layoutInfoBoxes) && ((mediaService.isHandset$ | async) === false)">
18
+ <ng-template [ngTemplateOutlet]="layoutPrimaryAction"></ng-template>
19
+ </span>
20
+ <ng-container *ngIf="layoutActions">
21
+ <ng-template [ngTemplateOutlet]="layoutActions"></ng-template>
22
+ </ng-container>
23
+ <div class="info-boxes-container" *ngIf="layoutInfoBoxes && (mediaService.isHandset$ | async) === false">
24
+ <ng-template [ngTemplateOutlet]="layoutInfoBoxes"></ng-template>
25
+ </div>
26
+ </mat-toolbar>
27
+ </ng-template>
28
+
29
+ <ng-template #filter>
30
+ <mat-toolbar id="toolbar" [color]="toolbarColor" *ngIf="layoutToolbar || layoutRight">
31
+ <button type="button" id="sidenav-button" mat-icon-button *ngIf="withSidenav && (mediaService.isHandset$ | async) && ((sidenavService.openChanged$ | async) === false)" (click)="sidenavService.toggle()">
32
+ <mat-icon>menu</mat-icon>
33
+ </button>
34
+ <button type="button" id="back-button" mat-icon-button *ngIf="withBackButton" (click)="this.backButtonClicked.emit($event)" [matTooltip]="backButtonLabel">
35
+ <mat-icon>arrow_back</mat-icon>
36
+ </button>
37
+ <div id="toolbar-content-container">
38
+ <ng-container *ngIf="layoutToolbar">
39
+ <ng-template [ngTemplateOutlet]="layoutToolbar"></ng-template>
40
+ </ng-container>
41
+ </div>
42
+ <button type="button" id="filter-button" mat-icon-button (click)="sideFilter.toggle()" *ngIf="sideFilter && (keepFilterButtonDisplayed || (mediaService.isHandset$ | async)) && layoutRight" matTooltip="Afficher/Masquer les filtres">
43
+ <mat-icon>tune</mat-icon>
44
+ </button>
45
+ <button type="button" id="close-button" mat-icon-button *ngIf="withCloseButton" (click)="this.closeButtonClicked.emit($event)" [matTooltip]="closeButtonLabel">
46
+ <mat-icon>close</mat-icon>
47
+ </button>
48
+ </mat-toolbar>
49
+ <ng-container *ngIf="(layoutActions || layoutInfoBoxes) && ((mediaService.isHandset$ | async) === false)">
50
+ <ng-container *ngTemplateOutlet="actionsToolbar"></ng-container>
51
+ </ng-container>
52
+ <mat-drawer-container *ngIf="layoutRight; else content" autosize="true">
53
+ <mat-drawer-content>
54
+ <ng-container *ngTemplateOutlet="content"></ng-container>
55
+ </mat-drawer-content>
56
+ <mat-drawer id="side-filter" #sideFilter (closed)="sideFilterClosed.emit()" (openedChange)="sideFilterOpened.emit()" class="right" position="end" [attr.role]="(mediaService.isHandset$ | async) ? 'dialog' : 'navigation'" [mode]="(mediaService.isHandset$ | async) ? 'over' : 'side'" [opened]="(mediaService.isHandset$ | async) === false">
57
+ <ng-template [ngTemplateOutlet]="layoutRight"></ng-template>
58
+ </mat-drawer>
59
+ </mat-drawer-container>
60
+ </ng-template>
@@ -0,0 +1,251 @@
1
+ layout {
2
+ display: flex;
3
+ flex-direction: column;
4
+ position: absolute;
5
+ top: 0;
6
+ bottom: 0;
7
+ left: 0;
8
+ right: 0;
9
+
10
+ &.no-left.no-right .main-content {
11
+ padding: 0;
12
+ }
13
+
14
+ mat-sidenav-container {
15
+ position: absolute;
16
+ top: 0;
17
+ bottom: 0;
18
+ left: 0;
19
+ right: 0;
20
+ }
21
+
22
+ mat-sidenav-content,
23
+ mat-drawer-content {
24
+ display: flex !important;
25
+ flex-direction: column;
26
+ }
27
+
28
+ mat-sidenav {
29
+ width: 200px;
30
+ }
31
+
32
+ mat-drawer {
33
+ width: 220px;
34
+
35
+ &.right {
36
+ padding: 0.3rem;
37
+
38
+ [filters-title] {
39
+ font-size: 1.2rem;
40
+ display: flex;
41
+ align-items: center;
42
+ justify-content: space-between;
43
+ flex: 1 1 auto;
44
+ font-weight: bold;
45
+ padding: 0.6rem;
46
+ margin-bottom: 0.3rem;
47
+ }
48
+
49
+ [filters-subtitle] {
50
+ font-size: 1rem;
51
+ display: flex;
52
+ align-items: center;
53
+ justify-content: space-between;
54
+ flex: 1 1 auto;
55
+ font-weight: 600;
56
+ padding: 0.4rem 0.6rem;
57
+ margin-bottom: 0.3rem;
58
+ margin-top: 0.3rem;
59
+ }
60
+
61
+ [icons-container] {
62
+ display: flex;
63
+ align-items: center;
64
+ }
65
+
66
+ [filters-icon] {
67
+ cursor: pointer;
68
+ transition: color 0.3s ease-in-out;
69
+ }
70
+
71
+ [filters-chip-list] {
72
+ .mat-chip-list-wrapper {
73
+ margin: 0;
74
+ max-height: 20vh;
75
+ overflow-y: auto;
76
+ }
77
+
78
+ .mat-standard-chip {
79
+ position: relative;
80
+ }
81
+
82
+ .mat-standard-chip {
83
+ padding: 0.5rem;
84
+ margin: 0.1rem;
85
+ font-size: 0.75rem;
86
+ transition: 0.3s ease-in-out;
87
+
88
+ &:not([disabled]) {
89
+ cursor: pointer;
90
+
91
+ &:hover {
92
+ &:before {
93
+ content: 'close';
94
+ display: flex;
95
+ align-items: center;
96
+ justify-content: center;
97
+
98
+ position: absolute;
99
+ left: 0;
100
+ right: 0;
101
+ top: 0;
102
+ bottom: 0;
103
+
104
+ font-weight: bold;
105
+ font-size: 1.2rem;
106
+
107
+ cursor: pointer;
108
+
109
+ transition: 0.3s ease-in-out;
110
+ }
111
+ }
112
+ }
113
+ }
114
+ }
115
+
116
+ [filters-toggle-group] {
117
+ display: flex;
118
+
119
+ .mat-button-toggle {
120
+ transition: 0.3s ease-in-out;
121
+
122
+ mat-icon {
123
+ margin-right: 1rem;
124
+ }
125
+
126
+ .mat-button-toggle-label-content {
127
+ text-align: start;
128
+ }
129
+
130
+ .mat-button-toggle-focus-overlay {
131
+ height: 100%;
132
+ }
133
+ }
134
+ }
135
+
136
+ mat-form-field {
137
+ width: 100%;
138
+ }
139
+
140
+ .mat-form-field-infix {
141
+ width: inherit;
142
+ }
143
+
144
+ &.mat-drawer-side {
145
+ box-shadow: -3px 0 5px -1px rgba(0, 0, 0, 0.2);
146
+ z-index: 10;
147
+ }
148
+ }
149
+ }
150
+
151
+ mat-drawer-container {
152
+ flex: 1;
153
+ }
154
+
155
+ .mat-toolbar {
156
+ &:not(.actions) {
157
+ display: flex;
158
+ box-shadow: 0 3px 5px -1px rgba(0, 0, 0, 0.2),
159
+ 0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12);
160
+ z-index: 10;
161
+
162
+ #toolbar-content-container {
163
+ display: flex;
164
+ flex-grow: 1;
165
+ overflow: hidden;
166
+ }
167
+
168
+ [toolbar-title] {
169
+ overflow: hidden;
170
+ text-overflow: ellipsis;
171
+ }
172
+
173
+ &>div {
174
+ display: flex;
175
+ align-items: center;
176
+ }
177
+ }
178
+
179
+ &#actions-toolbar {
180
+ flex: 0 0 auto;
181
+ height: 40px;
182
+ font-size: inherit;
183
+ padding-right: 0;
184
+
185
+ .info-boxes-container {
186
+ display: flex;
187
+ flex: 1 1 auto;
188
+ justify-content: flex-end;
189
+
190
+ .info-box {
191
+ display: flex;
192
+ flex-grow: 0;
193
+ line-height: 40px;
194
+ padding-left: 2rem;
195
+ padding-right: 2rem;
196
+ box-shadow: -3px 0 5px -1px rgba(0, 0, 0, 0.2);
197
+ }
198
+ }
199
+
200
+ &.bottom {
201
+ &#actions-toolbar {
202
+ display: flex;
203
+ width: 100%;
204
+ justify-content: space-around;
205
+ }
206
+ }
207
+
208
+ .primary-action-container {
209
+ z-index: 20;
210
+ }
211
+ }
212
+ }
213
+
214
+ .main-content {
215
+ position: relative;
216
+ display: flex;
217
+ flex: 1 1 auto;
218
+ overflow: hidden;
219
+
220
+ .primary-action-container {
221
+ position: absolute;
222
+ z-index: 20;
223
+ opacity: 0.8;
224
+ transition: 0.3s ease-in-out;
225
+
226
+ &:hover {
227
+ opacity: 1;
228
+ }
229
+
230
+ &.bottom {
231
+ right: 1rem;
232
+ bottom: 1rem;
233
+ }
234
+
235
+ &:not(.bottom) {
236
+ top: 1rem;
237
+ left: 1rem;
238
+ }
239
+ }
240
+ }
241
+
242
+ ::-webkit-scrollbar {
243
+ width: 12px;
244
+ height: 12px;
245
+ }
246
+
247
+ ::-webkit-scrollbar-thumb {
248
+ transition: 0.3s ease-in-out;
249
+ border-radius: 6px;
250
+ }
251
+ }
@@ -0,0 +1,155 @@
1
+ import { BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion';
2
+ import { CommonModule } from '@angular/common';
3
+ import { ChangeDetectionStrategy, Component, ContentChild, EventEmitter, HostBinding, Input, Output, TemplateRef, ViewChild, ViewEncapsulation } from '@angular/core';
4
+ import { MatButtonModule } from '@angular/material/button';
5
+ import { MatIconModule } from '@angular/material/icon';
6
+ import { MatDrawer, MatSidenavModule } from '@angular/material/sidenav';
7
+ import { MatToolbarModule } from '@angular/material/toolbar';
8
+ import { MatTooltipModule } from '@angular/material/tooltip';
9
+ import { MediaService } from '@hug/ngx-core';
10
+ import { SidenavService } from '@hug/ngx-sidenav';
11
+
12
+ @Component({
13
+ selector: 'layout',
14
+ templateUrl: './layout.component.html',
15
+ styleUrls: ['./layout.component.scss'],
16
+ encapsulation: ViewEncapsulation.None,
17
+ changeDetection: ChangeDetectionStrategy.OnPush,
18
+ standalone: true,
19
+ imports: [
20
+ CommonModule,
21
+ MatButtonModule,
22
+ MatIconModule,
23
+ MatSidenavModule,
24
+ MatToolbarModule,
25
+ MatTooltipModule
26
+ ]
27
+ })
28
+ export class LayoutComponent {
29
+ @Input() public toolbarColor = 'primary';
30
+ @Input() public editorToolbarId = 'editor-toolbar';
31
+
32
+ @Input() public closeButtonLabel = 'Fermer';
33
+ @Input() public backButtonLabel = 'Retour';
34
+
35
+ @Input() public layoutToolbarExternal?: TemplateRef<unknown>;
36
+ @Input() public layoutPrimaryActionExternal?: TemplateRef<unknown>;
37
+ @Input() public layoutActionsExternal?: TemplateRef<unknown>;
38
+ @Input() public layoutInfoBoxesExternal?: TemplateRef<unknown>;
39
+ @Input() public layoutRightExternal?: TemplateRef<unknown>;
40
+
41
+ @Output() public readonly closeButtonClicked = new EventEmitter<MouseEvent>();
42
+ @Output() public readonly backButtonClicked = new EventEmitter<MouseEvent>();
43
+ @Output() public readonly sideFilterClosed = new EventEmitter<void>();
44
+ @Output() public readonly sideFilterOpened = new EventEmitter<void>();
45
+
46
+ @ContentChild('layoutToolbar') protected layoutToolbarContent?: TemplateRef<unknown>;
47
+ @ContentChild('layoutPrimaryAction') protected layoutPrimaryActionContent?: TemplateRef<unknown>;
48
+ @ContentChild('layoutActions') protected layoutActionsContent?: TemplateRef<unknown>;
49
+ @ContentChild('layoutInfoBoxes') protected layoutInfoBoxesContent?: TemplateRef<unknown>;
50
+ @ContentChild('layoutRight') protected layoutRightContent?: TemplateRef<unknown>;
51
+
52
+ @HostBinding('class.no-right') protected noRight = false;
53
+
54
+ @ViewChild('sideFilter') protected sideFilter?: MatDrawer;
55
+
56
+ private _withEditorToolbar = true;
57
+
58
+ public get layoutToolbar(): TemplateRef<unknown> | undefined {
59
+ return this.layoutToolbarExternal ?? this.layoutToolbarContent;
60
+ }
61
+
62
+ public get layoutPrimaryAction(): TemplateRef<unknown> | undefined {
63
+ return this.layoutPrimaryActionExternal ?? this.layoutPrimaryActionContent;
64
+ }
65
+
66
+ public get layoutActions(): TemplateRef<unknown> | undefined {
67
+ return this.layoutActionsExternal ?? this.layoutActionsContent;
68
+ }
69
+
70
+ public get layoutInfoBoxes(): TemplateRef<unknown> | undefined {
71
+ return this.layoutInfoBoxesExternal ?? this.layoutInfoBoxesContent;
72
+ }
73
+
74
+ public get layoutRight(): TemplateRef<unknown> | undefined {
75
+ const value = this.layoutRightExternal ?? this.layoutRightContent;
76
+ this.noRight = !value;
77
+ return value;
78
+ }
79
+
80
+ @Input()
81
+ public set withEditorToolbar(value: BooleanInput) {
82
+ this._withEditorToolbar = coerceBooleanProperty(value);
83
+ }
84
+
85
+ public get withEditorToolbar(): BooleanInput {
86
+ return this._withEditorToolbar;
87
+ }
88
+
89
+ private _withSidenav = false;
90
+
91
+ @Input()
92
+ public set withSidenav(value: BooleanInput) {
93
+ this._withSidenav = coerceBooleanProperty(value);
94
+ }
95
+
96
+ public get withSidenav(): BooleanInput {
97
+ return this._withSidenav;
98
+ }
99
+
100
+ private _keepFilterButtonDisplayed = true;
101
+ @Input()
102
+ public set keepFilterButtonDisplayed(value: BooleanInput) {
103
+ this._keepFilterButtonDisplayed = coerceBooleanProperty(value);
104
+ }
105
+
106
+ public get keepFilterButtonDisplayed(): BooleanInput {
107
+ return this._keepFilterButtonDisplayed;
108
+ }
109
+
110
+ private _withCloseButton = false;
111
+ @Input()
112
+ public set withCloseButton(value: BooleanInput) {
113
+ this._withCloseButton = coerceBooleanProperty(value);
114
+ }
115
+
116
+ public get withCloseButton(): BooleanInput {
117
+ return this._withCloseButton;
118
+ }
119
+
120
+ private _withBackButton = false;
121
+
122
+ @Input()
123
+ public set withBackButton(value: BooleanInput) {
124
+ this._withBackButton = coerceBooleanProperty(value);
125
+ }
126
+
127
+ public get withBackButton(): BooleanInput {
128
+ return this._withBackButton;
129
+ }
130
+
131
+ private _displayEditorToolbar = true;
132
+
133
+ @Input()
134
+ public set displayEditorToolbar(value: BooleanInput) {
135
+ this._displayEditorToolbar = coerceBooleanProperty(value);
136
+ }
137
+
138
+ public get displayEditorToolbar(): BooleanInput {
139
+ return this._displayEditorToolbar;
140
+ }
141
+
142
+ public constructor(
143
+ protected mediaService: MediaService,
144
+ protected sidenavService: SidenavService
145
+ ) {
146
+ }
147
+
148
+ public closeSideFilter(): void {
149
+ void this.sideFilter?.close();
150
+ }
151
+
152
+ public openSideFilter(): void {
153
+ void this.sideFilter?.open();
154
+ }
155
+ }
package/src/test.ts ADDED
@@ -0,0 +1,28 @@
1
+ // This file is required by karma.conf.js and loads recursively all the .spec and framework files
2
+
3
+ import 'zone.js';
4
+ import 'zone.js/testing';
5
+
6
+ import { getTestBed } from '@angular/core/testing';
7
+ import {
8
+ BrowserDynamicTestingModule,
9
+ platformBrowserDynamicTesting
10
+ } from '@angular/platform-browser-dynamic/testing';
11
+
12
+ declare const require: {
13
+ context: (path: string, deep?: boolean, filter?: RegExp) => {
14
+ <T>(id: string): T;
15
+ keys: () => string[];
16
+ };
17
+ };
18
+
19
+ // First, initialize the Angular testing environment.
20
+ getTestBed().initTestEnvironment(
21
+ BrowserDynamicTestingModule,
22
+ platformBrowserDynamicTesting()
23
+ );
24
+
25
+ // Then we find all the tests.
26
+ const context = require.context('./', true, /\.spec\.ts$/);
27
+ // And load the modules.
28
+ context.keys().forEach(context);
@@ -0,0 +1,15 @@
1
+ /* To learn more about this file see: https://angular.io/config/tsconfig. */
2
+ {
3
+ "extends": "../../tsconfig.base.json",
4
+ "compilerOptions": {
5
+ "outDir": "../../out-tsc/lib",
6
+ "declaration": true,
7
+ "declarationMap": true,
8
+ "inlineSources": true,
9
+ "types": []
10
+ },
11
+ "exclude": [
12
+ "src/test.ts",
13
+ "**/*.spec.ts"
14
+ ]
15
+ }
@@ -0,0 +1,10 @@
1
+ /* To learn more about this file see: https://angular.io/config/tsconfig. */
2
+ {
3
+ "extends": "./tsconfig.lib.json",
4
+ "compilerOptions": {
5
+ "declarationMap": false
6
+ },
7
+ "angularCompilerOptions": {
8
+ "compilationMode": "partial"
9
+ }
10
+ }
@@ -0,0 +1,17 @@
1
+ /* To learn more about this file see: https://angular.io/config/tsconfig. */
2
+ {
3
+ "extends": "../../tsconfig.json",
4
+ "compilerOptions": {
5
+ "outDir": "../../out-tsc/spec",
6
+ "types": [
7
+ "jasmine"
8
+ ]
9
+ },
10
+ "files": [
11
+ "src/test.ts"
12
+ ],
13
+ "include": [
14
+ "**/*.spec.ts",
15
+ "**/*.d.ts"
16
+ ]
17
+ }