Skip to content

Commit bf90034

Browse files
authoredDec 4, 2022
feat(theme:default): add LayoutDefaultService service (#1561)
1 parent 41fbae0 commit bf90034

19 files changed

+279
-73
lines changed
 

‎packages/theme/layout-default/index.en-US.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export class LayoutBasicComponent {
8888
}
8989
```
9090

91-
In addition, in layout operations, you can subscribe to layout changes through `SettingsService.notify` (for example: sidebar show and hide, etc.). Note that all layout-related changes will pass through this interface, so you need to do `filter` operation.
91+
The layout can be dynamically managed at runtime through the `LayoutDefaultService` service. In addition, in layout operations, you can subscribe to layout changes through `SettingsService.notify` (for example: sidebar show and hide, etc.). Note that all layout-related changes will pass through this interface, so you need to do `filter` operation.
9292

9393
## API
9494

@@ -98,6 +98,7 @@ In addition, in layout operations, you can subscribe to layout changes through `
9898
|----------|-------------|------|---------|
9999
| `[options]` | Options of the layout | `LayoutDefaultOptions` | `-` |
100100
| `[asideUser]` | Side user of the layout | `TemplateRef<void>` | `-` |
101+
| `[asideBottom]` | Bottom information of the layout | `TemplateRef<void>` | `-` |
101102
| `[nav]` | Nav | `TemplateRef<void>` | `-` |
102103
| `[content]` | Content | `TemplateRef<void>` | `-` |
103104
| `[customError]` | Custom exception routing error message, can't show when is `null` | `string, null` | `Could not load ${evt.url} route` |
@@ -112,6 +113,9 @@ In addition, in layout operations, you can subscribe to layout changes through `
112113
| `[logoFixWidth]` | Specify a fixed logo width | `number` | - |
113114
| `[logoLink]` | Specify the logo routing address | `string` | `/` |
114115
| `[hideAside]` | Hide the sidebar without showing the collapsed icon button | `boolean` | `false` |
116+
| `[hideHeader]` | Hide top bar | `boolean` | `false` |
117+
| `[showHeaderCollapse]` | Whether to display the menu collapse button on the top bar | `boolean` | `true` |
118+
| `[showSiderCollapse]` | Whether to show the menu collapse button at the bottom of the sidebar | `boolean` | `false` |
115119

116120
### layout-default-nav
117121

@@ -239,8 +243,4 @@ The menu will be re-rendered via calling `MenuService.setItem(key, newValue)`, p
239243

240244
**How to control menu expand**
241245

242-
Use `SettingsService.setLayout` to operate on `collapsed`, for example:
243-
244-
```ts
245-
SettingsService.setLayout('collapsed', status);
246-
````
246+
Use `LayoutDefaultService.toggleCollapsed()` for manual control at runtime.

‎packages/theme/layout-default/index.zh-CN.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export class LayoutBasicComponent {
8888
}
8989
```
9090

91-
除此之外,在布局的操作都可以通过 `SettingsService.notify` 来订阅布局的变化(例如:侧边栏的展开与收缩等),注意所有布局相关的变化都会通过这个接口,所以需要做好 `filter` 操作。
91+
通过 `LayoutDefaultService` 服务可以在运行时动态管理布局。除此之外,在布局的操作都可以通过 `SettingsService.notify` 来订阅布局的变化(例如:侧边栏的展开与收缩等),注意所有布局相关的变化都会通过这个接口,所以需要做好 `filter` 操作。
9292

9393
## API
9494

@@ -98,6 +98,7 @@ export class LayoutBasicComponent {
9898
|----|----|----|-----|
9999
| `[options]` | 选项 | `LayoutDefaultOptions` | `-` |
100100
| `[asideUser]` | 侧边用户信息 | `TemplateRef<void>` | `-` |
101+
| `[asideBottom]` | 侧边底部信息 | `TemplateRef<void>` | `-` |
101102
| `[nav]` | 导航信息 | `TemplateRef<void>` | `-` |
102103
| `[content]` | 内容信息 | `TemplateRef<void>` | `-` |
103104
| `[customError]` | 自定义异常路由错误消息,当 `null` 时表示不显示错误消息 | `string, null` | `Could not load ${evt.url} route` |
@@ -112,6 +113,9 @@ export class LayoutBasicComponent {
112113
| `[logoFixWidth]` | 指定固定 Logo 宽度 | `number` | - |
113114
| `[logoLink]` | 指定 Logo 路由地址 | `string` | `/` |
114115
| `[hideAside]` | 隐藏侧边栏,同时不显收缩图标按钮 | `boolean` | `false` |
116+
| `[hideHeader]` | 隐藏顶栏 | `boolean` | `false` |
117+
| `[showHeaderCollapse]` | 是否在顶栏显示菜单折叠按钮 | `boolean` | `true` |
118+
| `[showSiderCollapse]` | 是否在侧边栏底部显示菜单折叠按钮 | `boolean` | `false` |
115119

116120
### layout-default-nav
117121

@@ -239,8 +243,4 @@ export class LayoutBasicComponent {
239243

240244
**如何控制菜单展开**
241245

242-
利用 `SettingsService.setLayout``collapsed` 进行操作,例如:
243-
244-
```ts
245-
SettingsService.setLayout('collapsed', status);
246-
```
246+
利用 `LayoutDefaultService.toggleCollapsed()` 来运行时手动控制。

‎packages/theme/layout-default/layout-header.component.ts

+16-15
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { App, SettingsService } from '@delon/theme';
1414
import type { NzSafeAny } from 'ng-zorro-antd/core/types';
1515

1616
import { LayoutDefaultHeaderItemComponent } from './layout-header-item.component';
17+
import { LayoutDefaultService } from './layout.service';
1718
import { LayoutDefaultHeaderItemDirection, LayoutDefaultHeaderItemHidden, LayoutDefaultOptions } from './types';
1819

1920
interface LayoutDefaultHeaderItem {
@@ -30,19 +31,19 @@ interface LayoutDefaultHeaderItem {
3031
<ng-container *ngTemplateOutlet="i.host"></ng-container>
3132
</li>
3233
</ng-template>
33-
<div class="alain-default__header-logo" [style.width.px]="options.logoFixWidth">
34-
<ng-container *ngIf="!options.logo; else options.logo!">
35-
<a [routerLink]="options.logoLink" class="alain-default__header-logo-link">
36-
<img class="alain-default__header-logo-expanded" [attr.src]="options.logoExpanded" [attr.alt]="app.name" />
37-
<img class="alain-default__header-logo-collapsed" [attr.src]="options.logoCollapsed" [attr.alt]="app.name" />
34+
<div class="alain-default__header-logo" [style.width.px]="opt.logoFixWidth">
35+
<ng-container *ngIf="!opt.logo; else opt.logo!">
36+
<a [routerLink]="opt.logoLink" class="alain-default__header-logo-link">
37+
<img class="alain-default__header-logo-expanded" [attr.src]="opt.logoExpanded" [attr.alt]="app.name" />
38+
<img class="alain-default__header-logo-collapsed" [attr.src]="opt.logoCollapsed" [attr.alt]="app.name" />
3839
</a>
3940
</ng-container>
4041
</div>
4142
<div class="alain-default__nav-wrap">
4243
<ul class="alain-default__nav">
43-
<li *ngIf="!options.hideAside">
44+
<li *ngIf="!opt.hideAside && opt.showHeaderCollapse">
4445
<div class="alain-default__nav-item alain-default__nav-item--collapse" (click)="toggleCollapsed()">
45-
<i nz-icon [nzType]="collapsedIcon"></i>
46+
<span nz-icon [nzType]="collapsedIcon"></span>
4647
</div>
4748
</li>
4849
<ng-template [ngTemplateOutlet]="render" [ngTemplateOutletContext]="{ $implicit: left }"></ng-template>
@@ -64,12 +65,15 @@ export class LayoutDefaultHeaderComponent implements AfterViewInit, OnDestroy {
6465
private destroy$ = new Subject<void>();
6566

6667
@Input() items!: QueryList<LayoutDefaultHeaderItemComponent>;
67-
@Input() options!: LayoutDefaultOptions;
6868

6969
left: LayoutDefaultHeaderItem[] = [];
7070
middle: LayoutDefaultHeaderItem[] = [];
7171
right: LayoutDefaultHeaderItem[] = [];
7272

73+
get opt(): LayoutDefaultOptions {
74+
return this.srv.options;
75+
}
76+
7377
get app(): App {
7478
return this.settings.app;
7579
}
@@ -79,14 +83,10 @@ export class LayoutDefaultHeaderComponent implements AfterViewInit, OnDestroy {
7983
}
8084

8185
get collapsedIcon(): string {
82-
let type = this.collapsed ? 'unfold' : 'fold';
83-
if (this.settings.layout.direction === 'rtl') {
84-
type = this.collapsed ? 'fold' : 'unfold';
85-
}
86-
return `menu-${type}`;
86+
return this.srv.collapsedIcon;
8787
}
8888

89-
constructor(private settings: SettingsService, private cdr: ChangeDetectorRef) {}
89+
constructor(private srv: LayoutDefaultService, private settings: SettingsService, private cdr: ChangeDetectorRef) {}
9090

9191
private refresh(): void {
9292
const arr = this.items.toArray();
@@ -98,11 +98,12 @@ export class LayoutDefaultHeaderComponent implements AfterViewInit, OnDestroy {
9898

9999
ngAfterViewInit(): void {
100100
this.items.changes.pipe(takeUntil(this.destroy$)).subscribe(() => this.refresh());
101+
this.srv.options$.pipe(takeUntil(this.destroy$)).subscribe(() => this.cdr.detectChanges());
101102
this.refresh();
102103
}
103104

104105
toggleCollapsed(): void {
105-
this.settings.setLayout('collapsed', !this.settings.layout.collapsed);
106+
this.srv.toggleCollapsed();
106107
}
107108

108109
ngOnDestroy(): void {

‎packages/theme/layout-default/layout-nav.component.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ const FLOATINGCLS = 'sidebar-nav__floating';
3737
templateUrl: './layout-nav.component.html',
3838
host: {
3939
'(click)': '_click()',
40-
'(document:click)': 'closeSubMenu()'
40+
'(document:click)': 'closeSubMenu()',
41+
'[class.d-block]': `true`
4142
},
4243
preserveWhitespaces: false,
4344
changeDetection: ChangeDetectionStrategy.OnPush,

‎packages/theme/layout-default/layout.component.spec.ts

+6-7
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { SettingsService } from '../src/services/settings/settings.service';
1212
import { AlainThemeModule } from '../src/theme.module';
1313
import { LayoutDefaultComponent } from './layout.component';
1414
import { LayoutDefaultModule } from './layout.module';
15+
import { LayoutDefaultService } from './layout.service';
1516
import { LayoutDefaultOptions } from './types';
1617

1718
describe('theme: layout-default', () => {
@@ -50,16 +51,14 @@ describe('theme: layout-default', () => {
5051
});
5152

5253
it('should be toggle collapsed', () => {
53-
const srv = TestBed.inject(SettingsService);
54-
let collapsed = false;
55-
spyOnProperty(srv, 'layout').and.returnValue({ collapsed });
54+
const srv = TestBed.inject(LayoutDefaultService);
55+
srv.toggleCollapsed(true);
5656
fixture.detectChanges();
5757
const el = page.getEl('.alain-default__nav-item--collapse');
58-
expect(el.querySelector('.anticon-menu-fold') != null).toBe(true);
59-
collapsed = true;
60-
el.click();
61-
fixture.detectChanges();
6258
expect(el.querySelector('.anticon-menu-unfold') != null).toBe(true);
59+
srv.toggleCollapsed(false);
60+
fixture.detectChanges();
61+
expect(el.querySelector('.anticon-menu-fold') != null).toBe(true);
6362
});
6463

6564
it('#colorWeak', () => {

‎packages/theme/layout-default/layout.component.ts

+45-24
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
Inject,
77
Input,
88
OnDestroy,
9-
OnInit,
109
QueryList,
1110
Renderer2,
1211
TemplateRef
@@ -28,19 +27,29 @@ import type { NzSafeAny } from 'ng-zorro-antd/core/types';
2827
import { NzMessageService } from 'ng-zorro-antd/message';
2928

3029
import { LayoutDefaultHeaderItemComponent } from './layout-header-item.component';
30+
import { LayoutDefaultService } from './layout.service';
3131
import { LayoutDefaultOptions } from './types';
3232

3333
@Component({
3434
selector: 'layout-default',
3535
exportAs: 'layoutDefault',
3636
template: `
3737
<div class="alain-default__progress-bar" *ngIf="isFetching"></div>
38-
<layout-default-header [options]="options" [items]="headerItems"></layout-default-header>
39-
<div *ngIf="!options.hideAside" class="alain-default__aside">
40-
<div class="alain-default__aside-inner">
41-
<ng-container *ngTemplateOutlet="asideUser"></ng-container>
42-
<ng-container *ngTemplateOutlet="nav"></ng-container>
43-
<layout-default-nav *ngIf="!nav" class="d-block py-lg"></layout-default-nav>
38+
<layout-default-header *ngIf="!opt.hideHeader" [items]="headerItems"></layout-default-header>
39+
<div *ngIf="!opt.hideAside" class="alain-default__aside">
40+
<div class="alain-default__aside-wrap">
41+
<div class="alain-default__aside-inner">
42+
<ng-container *ngTemplateOutlet="asideUser"></ng-container>
43+
<ng-container *ngTemplateOutlet="nav"></ng-container>
44+
<layout-default-nav *ngIf="!nav"></layout-default-nav>
45+
</div>
46+
<div *ngIf="opt.showSiderCollapse" class="alain-default__aside-link">
47+
<ng-container *ngIf="asideBottom === null; else asideBottom">
48+
<div class="alain-default__aside-link-collapsed" (click)="toggleCollapsed()">
49+
<span nz-icon [nzType]="collapsedIcon"></span>
50+
</div>
51+
</ng-container>
52+
</div>
4453
</div>
4554
</div>
4655
<section class="alain-default__content">
@@ -49,28 +58,52 @@ import { LayoutDefaultOptions } from './types';
4958
</section>
5059
`
5160
})
52-
export class LayoutDefaultComponent implements OnInit, OnDestroy {
61+
export class LayoutDefaultComponent implements OnDestroy {
5362
@ContentChildren(LayoutDefaultHeaderItemComponent, { descendants: false })
5463
headerItems!: QueryList<LayoutDefaultHeaderItemComponent>;
5564

56-
@Input() options!: LayoutDefaultOptions;
65+
get opt(): LayoutDefaultOptions {
66+
return this.srv.options;
67+
}
68+
69+
@Input()
70+
set options(value: LayoutDefaultOptions | null | undefined) {
71+
this.srv.setOptions(value);
72+
}
5773
@Input() asideUser: TemplateRef<void> | null = null;
74+
@Input() asideBottom: TemplateRef<NzSafeAny> | null = null;
5875
@Input() nav: TemplateRef<void> | null = null;
5976
@Input() content: TemplateRef<void> | null = null;
6077
@Input() customError?: string | null;
6178

6279
private destroy$ = new Subject<void>();
6380
isFetching = false;
6481

82+
get collapsed(): boolean {
83+
return this.settings.layout.collapsed;
84+
}
85+
86+
get collapsedIcon(): string {
87+
return this.srv.collapsedIcon;
88+
}
89+
90+
toggleCollapsed(): void {
91+
this.srv.toggleCollapsed();
92+
}
93+
6594
constructor(
6695
router: Router,
6796
private msgSrv: NzMessageService,
6897
private settings: SettingsService,
6998
private el: ElementRef,
7099
private renderer: Renderer2,
71-
@Inject(DOCUMENT) private doc: NzSafeAny
100+
@Inject(DOCUMENT) private doc: NzSafeAny,
101+
private srv: LayoutDefaultService
72102
) {
73103
router.events.pipe(takeUntil(this.destroy$)).subscribe(ev => this.processEv(ev));
104+
const { destroy$ } = this;
105+
this.srv.options$.pipe(takeUntil(destroy$)).subscribe(() => this.setClass());
106+
this.settings.notify.pipe(takeUntil(destroy$)).subscribe(() => this.setClass());
74107
}
75108

76109
processEv(ev: Event): void {
@@ -102,25 +135,13 @@ export class LayoutDefaultComponent implements OnInit, OnDestroy {
102135
['alain-default']: true,
103136
[`alain-default__fixed`]: layout.fixed,
104137
[`alain-default__collapsed`]: layout.collapsed,
105-
[`alain-default__hide-aside`]: this.options!.hideAside
138+
[`alain-default__hide-aside`]: this.opt.hideAside,
139+
[`alain-default__hide-header`]: this.opt.hideHeader
106140
});
107141

108142
doc.body.classList[layout.colorWeak ? 'add' : 'remove']('color-weak');
109143
}
110144

111-
ngOnInit(): void {
112-
this.options = {
113-
logoExpanded: `./assets/logo-full.svg`,
114-
logoCollapsed: `./assets/logo.svg`,
115-
logoLink: `/`,
116-
hideAside: false,
117-
...this.options
118-
};
119-
const { settings, destroy$ } = this;
120-
settings.notify.pipe(takeUntil(destroy$)).subscribe(() => this.setClass());
121-
this.setClass();
122-
}
123-
124145
ngOnDestroy(): void {
125146
this.destroy$.next();
126147
this.destroy$.complete();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { TestBed } from '@angular/core/testing';
2+
3+
import { AlainThemeModule, Layout, SettingsService } from '@delon/theme';
4+
5+
import { LayoutDefaultService } from './layout.service';
6+
7+
describe('theme: #LayoutDefaultService', () => {
8+
let srv: LayoutDefaultService;
9+
10+
beforeEach(() => {
11+
TestBed.configureTestingModule({
12+
imports: [AlainThemeModule]
13+
});
14+
srv = TestBed.inject(LayoutDefaultService);
15+
});
16+
17+
it('should be working', () => {
18+
srv.setOptions({ hideAside: true });
19+
expect(srv.options.hideAside).toBe(true);
20+
});
21+
22+
it('#toggleCollapsed', () => {
23+
const settings = TestBed.inject(SettingsService);
24+
(settings.layout as Layout).direction = 'ltr';
25+
srv.toggleCollapsed(true);
26+
expect(srv.collapsedIcon).toBe('menu-unfold');
27+
srv.toggleCollapsed(false);
28+
expect(srv.collapsedIcon).toBe('menu-fold');
29+
srv.toggleCollapsed();
30+
expect(srv.collapsedIcon).toBe('menu-unfold');
31+
srv.toggleCollapsed();
32+
expect(srv.collapsedIcon).toBe('menu-fold');
33+
// when is direction
34+
(settings.layout as Layout).direction = 'rtl';
35+
srv.toggleCollapsed(true);
36+
expect(srv.collapsedIcon).toBe('menu-fold');
37+
srv.toggleCollapsed(false);
38+
expect(srv.collapsedIcon).toBe('menu-unfold');
39+
});
40+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { Injectable } from '@angular/core';
2+
import { BehaviorSubject, Observable } from 'rxjs';
3+
4+
import { SettingsService } from '@delon/theme';
5+
6+
import { LayoutDefaultOptions } from './types';
7+
8+
const DEFAULT: LayoutDefaultOptions = {
9+
logoExpanded: `./assets/logo-full.svg`,
10+
logoCollapsed: `./assets/logo.svg`,
11+
logoLink: `/`,
12+
showHeaderCollapse: true,
13+
showSiderCollapse: false,
14+
hideAside: false,
15+
hideHeader: false
16+
};
17+
18+
@Injectable({ providedIn: 'root' })
19+
export class LayoutDefaultService {
20+
private _options$ = new BehaviorSubject<LayoutDefaultOptions>(DEFAULT);
21+
private _options: LayoutDefaultOptions = DEFAULT;
22+
23+
get options(): LayoutDefaultOptions {
24+
return this._options;
25+
}
26+
27+
get options$(): Observable<LayoutDefaultOptions> {
28+
return this._options$.asObservable();
29+
}
30+
31+
get collapsedIcon(): string {
32+
const collapsed = this.settings.layout.collapsed;
33+
let type = collapsed ? 'unfold' : 'fold';
34+
if (this.settings.layout.direction === 'rtl') {
35+
type = collapsed ? 'fold' : 'unfold';
36+
}
37+
return `menu-${type}`;
38+
}
39+
40+
constructor(private settings: SettingsService) {}
41+
42+
private notify(): void {
43+
this._options$.next(this._options);
44+
}
45+
46+
/**
47+
* Set layout configuration
48+
*
49+
* 设置布局配置
50+
*/
51+
setOptions(options?: LayoutDefaultOptions | null): void {
52+
this._options = {
53+
...DEFAULT,
54+
...options
55+
};
56+
this.notify();
57+
}
58+
59+
/**
60+
* Toggle the collapsed state of the sidebar menu bar
61+
*
62+
* 切换侧边栏菜单栏折叠状态
63+
*/
64+
toggleCollapsed(status?: boolean): void {
65+
this.settings.setLayout('collapsed', status != null ? status : !this.settings.layout.collapsed);
66+
this.notify();
67+
}
68+
}

‎packages/theme/layout-default/public_api.ts

+1
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ export * from './layout-header-item.component';
55
export * from './layout-header-item-trigger.directive';
66
export * from './layout-nav.component';
77
export * from './types';
8+
export * from './layout.service';

‎packages/theme/layout-default/style/_aside.less

+18-1
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,14 @@
2020
content: '';
2121
}
2222

23-
&-inner {
23+
&-wrap {
24+
display: flex;
25+
flex-direction: column;
2426
height: 100%;
27+
}
28+
29+
&-inner {
30+
flex: 1 1 0%;
2531
overflow-x: hidden;
2632
overflow-y: scroll;
2733
-webkit-overflow-scrolling: touch;
@@ -43,6 +49,17 @@
4349
background-color: @alain-default-aside-scrollbar-thumb-color;
4450
}
4551
}
52+
53+
&-link {
54+
border-top: 1px solid @alain-default-content-heading-border;
55+
56+
&-collapsed {
57+
padding: 8px 0;
58+
font-size: 16px;
59+
text-align: center;
60+
cursor: pointer;
61+
}
62+
}
4663
}
4764

4865
// Desktop

‎packages/theme/layout-default/style/_fixed.less

+4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@
99
&__aside {
1010
position: fixed;
1111
}
12+
}
13+
}
1214

15+
@{alain-default-prefix}__fixed:not(@{alain-default-prefix}__hide-header) {
16+
@{alain-default-prefix} {
1317
&__content {
1418
margin-top: @alain-default-header-hg;
1519
}

‎packages/theme/layout-default/style/_layout.less

+6
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ body {
7575
transform: none !important;
7676
}
7777
}
78+
79+
&__hide-header {
80+
@{alain-default-prefix}__aside {
81+
margin-top: 0;
82+
}
83+
}
7884
}
7985

8086
// Desktop

‎packages/theme/layout-default/style/fix/_reuse-tab.less

+6
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@
2727
}
2828
}
2929

30+
@{alain-default-prefix}__hide-header {
31+
@{reuse-tab-prefix} {
32+
top: 0;
33+
}
34+
}
35+
3036
@media (min-width: @mobile-min) {
3137
@{alain-default-prefix}__fixed {
3238
@{reuse-tab-prefix} {

‎packages/theme/layout-default/style/fix/_sidebar-nav.less

+1-1
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@
234234
&-link {
235235
display: flex;
236236
justify-content: center;
237-
padding: (@layout-gutter * 3) 0;
237+
padding: @alain-default-aside-collapsed-padding;
238238

239239
@{sidebar-nav-prefix}__item-icon {
240240
margin-right: 0;

‎packages/theme/layout-default/style/theme-default.less

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
@alain-default-aside-collapsed-wd: @layout-gutter * 8;
3737
@alain-default-aside-collapsed-nav-fs: 24px;
3838
@alain-default-aside-collapsed-nav-img-wh: 24px;
39+
@alain-default-aside-collapsed-padding: (@layout-gutter * 2) 0;
3940

4041
@alain-default-content-heading-bg: #fafbfc;
4142
@alain-default-content-heading-border: #efe3e5;

‎packages/theme/layout-default/types.ts

+21
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,25 @@ export interface LayoutDefaultOptions {
4242
* 隐藏侧边栏,同时不显收缩图标按钮,默认:`false`
4343
*/
4444
hideAside?: boolean;
45+
46+
/**
47+
* Hide top bar, default: `false`
48+
*
49+
* 隐藏顶栏,默认:`false`
50+
*/
51+
hideHeader?: boolean;
52+
53+
/**
54+
* Whether to display the menu collapse button on the top bar, default: `true`
55+
*
56+
* 是否在顶栏显示菜单折叠按钮,默认:`true`
57+
*/
58+
showHeaderCollapse?: boolean;
59+
60+
/**
61+
* Whether to show the menu collapse button at the bottom of the sidebar, default: `false`
62+
*
63+
* 是否在侧边栏底部显示菜单折叠按钮,默认:`false`
64+
*/
65+
showSiderCollapse?: boolean;
4566
}

‎src/dev/dev.module.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const routes: Routes = [
2020
path: '',
2121
component: DevLayoutComponent,
2222
children: [
23-
{ path: '', component: DevHomeComponent },
23+
{ path: 'home', component: DevHomeComponent },
2424
{ path: 'l1', component: DevPageComponent },
2525
{ path: 'l2', component: DevPageComponent },
2626
{ path: 'l3', component: DevPageComponent },

‎src/dev/home/home.component.ts

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,27 @@
11
import { Component } from '@angular/core';
22

3+
import { LayoutDefaultService } from '@delon/theme/layout-default';
4+
35
@Component({
46
selector: 'dev-home',
57
template: `
68
<page-header [autoBreadcrumb]="false"></page-header>
79
home
10+
<div class="mb-md"> options: {{ srv.options | json }} </div>
11+
<div class="mb-md">
12+
<button nz-button (click)="srv.toggleCollapsed()">切换折叠</button>
13+
<button nz-button (click)="srv.setOptions({ hideHeader: true })">隐藏顶部</button>
14+
<button nz-button (click)="srv.setOptions({ hideAside: true })">隐藏侧边栏</button>
15+
<button nz-button (click)="srv.setOptions({ hideHeader: true, hideAside: true })">隐藏顶部与侧边栏</button>
16+
<button nz-button (click)="srv.setOptions({ showHeaderCollapse: true })">显示顶部折叠开关</button>
17+
<button nz-button (click)="srv.setOptions({ showSiderCollapse: true })">显示侧边栏底部折叠开关</button>
18+
<button nz-button (click)="srv.setOptions({ showHeaderCollapse: true, showSiderCollapse: true })"
19+
>显示顶部与侧边栏底部折叠开关</button
20+
>
21+
<button nz-button (click)="srv.setOptions({})">恢复默认</button>
22+
</div>
823
`
924
})
10-
export class DevHomeComponent {}
25+
export class DevHomeComponent {
26+
constructor(public srv: LayoutDefaultService) {}
27+
}

‎src/dev/layout.component.ts

+13-10
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,11 @@ const ICONS = [
9494
export class DevLayoutComponent implements OnInit {
9595
options: LayoutDefaultOptions = {
9696
logoExpanded: `./assets/logo-full.svg`,
97-
logoCollapsed: `./assets/logo.svg`
97+
logoCollapsed: `./assets/logo.svg`,
98+
hideHeader: false,
99+
showHeaderCollapse: false,
100+
showSiderCollapse: true
101+
// hideAside: true
98102
};
99103

100104
lang: LangType = 'zh-CN';
@@ -110,18 +114,17 @@ export class DevLayoutComponent implements OnInit {
110114
children: [
111115
{
112116
text: 'Dashboard-DISABLED',
113-
link: '/dev',
117+
link: '/dev/home',
114118
icon: 'anticon anticon-dashboard',
115119
i18n: 'app.header.menu.home',
116-
badge: 5,
117-
disabled: true
120+
badge: 5
118121
},
119-
{ text: '测试view1-id', link: '/dev/view/1' },
120-
{ text: '测试view2-id', link: '/dev/view/2' },
121-
{ text: 'lazy测试1', link: '/dev/lazy/p1' },
122-
{ text: 'lazy测试2', link: '/dev/lazy/p2' },
123-
{ text: 'lazy测试view1-id', link: '/dev/lazy/1/view' },
124-
{ text: 'lazy测试view2-id', link: '/dev/lazy/2/view' },
122+
{ text: '测试view1-id', link: '/dev/view/1', icon: 'anticon anticon-appstore' },
123+
{ text: '测试view2-id', link: '/dev/view/2', icon: 'anticon anticon-appstore' },
124+
{ text: 'lazy测试1', link: '/dev/lazy/p1', icon: 'anticon anticon-appstore' },
125+
{ text: 'lazy测试2', link: '/dev/lazy/p2', icon: 'anticon anticon-appstore' },
126+
{ text: 'lazy测试view1-id', link: '/dev/lazy/1/view', icon: 'anticon anticon-appstore' },
127+
{ text: 'lazy测试view2-id', link: '/dev/lazy/2/view', icon: 'anticon anticon-appstore' },
125128
{
126129
text: 'Level1',
127130
link: '#',

0 commit comments

Comments
 (0)
Please sign in to comment.