gcp-material-ui 0.0.4
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/.agents/skills/charts/SKILL.MD +103 -0
- package/.agents/skills/creating-common-components/SKILL.MD +121 -0
- package/.agents/skills/creating-pages/SKILL.MD +205 -0
- package/.agents/skills/sidebar/SKILL.MD +63 -0
- package/.agents/skills/workflow-graph/SKILL.MD +160 -0
- package/.dockerignore +4 -0
- package/.editorconfig +17 -0
- package/.prettierrc +12 -0
- package/Dockerfile +14 -0
- package/PUBLISH_GUIDE.md +33 -0
- package/README.md +48 -0
- package/angular.json +79 -0
- package/deploy.sh +47 -0
- package/nginx.conf +15 -0
- package/package.json +48 -0
- package/public/favicon.ico +0 -0
- package/public/google-cloud-combined.svg +1 -0
- package/publish.sh +14 -0
- package/src/_variables.scss +183 -0
- package/src/app/app.config.ts +19 -0
- package/src/app/app.html +1 -0
- package/src/app/app.routes.ts +65 -0
- package/src/app/app.scss +0 -0
- package/src/app/app.spec.ts +23 -0
- package/src/app/app.ts +12 -0
- package/src/app/auth/auth.guard.ts +7 -0
- package/src/app/auth/auth.service.ts +50 -0
- package/src/app/components/page/page.html +20 -0
- package/src/app/components/page/page.scss +41 -0
- package/src/app/components/page/page.ts +15 -0
- package/src/app/dashboard/dashboard.html +287 -0
- package/src/app/dashboard/dashboard.scss +196 -0
- package/src/app/dashboard/dashboard.ts +24 -0
- package/src/app/demo-components/buttons/buttons-demo.html +92 -0
- package/src/app/demo-components/buttons/buttons-demo.scss +38 -0
- package/src/app/demo-components/buttons/buttons-demo.ts +23 -0
- package/src/app/demo-components/card/card-demo.html +52 -0
- package/src/app/demo-components/card/card-demo.scss +47 -0
- package/src/app/demo-components/card/card-demo.ts +21 -0
- package/src/app/demo-components/charts/charts-demo.html +88 -0
- package/src/app/demo-components/charts/charts-demo.scss +50 -0
- package/src/app/demo-components/charts/charts-demo.ts +201 -0
- package/src/app/demo-components/chips/chips-demo.html +87 -0
- package/src/app/demo-components/chips/chips-demo.scss +6 -0
- package/src/app/demo-components/chips/chips-demo.ts +57 -0
- package/src/app/demo-components/code-snippet/code-snippet-demo.html +52 -0
- package/src/app/demo-components/code-snippet/code-snippet-demo.scss +20 -0
- package/src/app/demo-components/code-snippet/code-snippet-demo.ts +31 -0
- package/src/app/demo-components/dialog/dialog-demo.html +47 -0
- package/src/app/demo-components/dialog/dialog-demo.ts +90 -0
- package/src/app/demo-components/dialog/dialog-examples.ts +126 -0
- package/src/app/demo-components/expand-button/expand-button-demo.html +28 -0
- package/src/app/demo-components/expand-button/expand-button-demo.scss +45 -0
- package/src/app/demo-components/expand-button/expand-button-demo.ts +28 -0
- package/src/app/demo-components/expansion/expansion-demo.html +105 -0
- package/src/app/demo-components/expansion/expansion-demo.scss +11 -0
- package/src/app/demo-components/expansion/expansion-demo.ts +49 -0
- package/src/app/demo-components/forms/forms-demo.html +114 -0
- package/src/app/demo-components/forms/forms-demo.scss +43 -0
- package/src/app/demo-components/forms/forms-demo.ts +57 -0
- package/src/app/demo-components/message/message-demo.html +47 -0
- package/src/app/demo-components/message/message-demo.ts +33 -0
- package/src/app/demo-components/message/message.html +15 -0
- package/src/app/demo-components/message/message.scss +115 -0
- package/src/app/demo-components/message/message.ts +39 -0
- package/src/app/demo-components/sidebar/sidebar-demo.html +46 -0
- package/src/app/demo-components/sidebar/sidebar-demo.scss +47 -0
- package/src/app/demo-components/sidebar/sidebar-demo.ts +27 -0
- package/src/app/demo-components/sidebar/sidebar.html +15 -0
- package/src/app/demo-components/sidebar/sidebar.scss +25 -0
- package/src/app/demo-components/sidebar/sidebar.ts +87 -0
- package/src/app/demo-components/slide-toggle/slide-toggle-demo.html +110 -0
- package/src/app/demo-components/slide-toggle/slide-toggle-demo.scss +45 -0
- package/src/app/demo-components/slide-toggle/slide-toggle-demo.ts +39 -0
- package/src/app/demo-components/stepper/stepper-demo.html +99 -0
- package/src/app/demo-components/stepper/stepper-demo.ts +84 -0
- package/src/app/demo-components/tables/clean_tables_scss.py +16 -0
- package/src/app/demo-components/tables/tables-demo.html +64 -0
- package/src/app/demo-components/tables/tables-demo.scss +18 -0
- package/src/app/demo-components/tables/tables-demo.ts +89 -0
- package/src/app/demo-components/tabs/tabs-demo.html +168 -0
- package/src/app/demo-components/tabs/tabs-demo.scss +22 -0
- package/src/app/demo-components/tabs/tabs-demo.ts +76 -0
- package/src/app/demo-components/toolbars/toolbars-demo.html +50 -0
- package/src/app/demo-components/toolbars/toolbars-demo.scss +29 -0
- package/src/app/demo-components/toolbars/toolbars-demo.ts +25 -0
- package/src/app/demo-components/tooltip/tooltip-demo.html +80 -0
- package/src/app/demo-components/tooltip/tooltip-demo.scss +30 -0
- package/src/app/demo-components/tooltip/tooltip-demo.ts +27 -0
- package/src/app/demo-components/typography/typography-demo.html +23 -0
- package/src/app/demo-components/typography/typography-demo.scss +49 -0
- package/src/app/demo-components/typography/typography-demo.ts +72 -0
- package/src/app/demo-components/workflow-graph/workflow-graph-demo.html +25 -0
- package/src/app/demo-components/workflow-graph/workflow-graph-demo.scss +48 -0
- package/src/app/demo-components/workflow-graph/workflow-graph-demo.ts +133 -0
- package/src/app/layout/layout.html +12 -0
- package/src/app/layout/layout.scss +21 -0
- package/src/app/layout/layout.ts +19 -0
- package/src/app/layout/side-menu/side-menu.html +32 -0
- package/src/app/layout/side-menu/side-menu.scss +52 -0
- package/src/app/layout/side-menu/side-menu.ts +70 -0
- package/src/app/layout/top-action-bar/top-action-bar.html +41 -0
- package/src/app/layout/top-action-bar/top-action-bar.scss +98 -0
- package/src/app/layout/top-action-bar/top-action-bar.ts +68 -0
- package/src/app/page-templates/complex-form/complex-form.html +103 -0
- package/src/app/page-templates/complex-form/complex-form.scss +110 -0
- package/src/app/page-templates/complex-form/complex-form.ts +66 -0
- package/src/app/page-templates/firewall-add/firewall-add.html +78 -0
- package/src/app/page-templates/firewall-add/firewall-add.scss +1 -0
- package/src/app/page-templates/firewall-add/firewall-add.ts +94 -0
- package/src/app/page-templates/firewall-details/firewall-details.html +115 -0
- package/src/app/page-templates/firewall-details/firewall-details.scss +21 -0
- package/src/app/page-templates/firewall-details/firewall-details.ts +91 -0
- package/src/app/page-templates/firewall-list/firewall-list.html +99 -0
- package/src/app/page-templates/firewall-list/firewall-list.scss +21 -0
- package/src/app/page-templates/firewall-list/firewall-list.ts +85 -0
- package/src/app/page-templates/firewall.service.ts +84 -0
- package/src/app/services/project.service.ts +24 -0
- package/src/index.html +17 -0
- package/src/main.ts +6 -0
- package/src/styles.scss +739 -0
- package/start_server.sh +4 -0
- package/tsconfig.app.json +15 -0
- package/tsconfig.json +33 -0
- package/tsconfig.spec.json +15 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
<app-page title="Chips Showcase">
|
|
2
|
+
<div class="default-container-padding" style="display: flex; flex-direction: column; gap: 24px;">
|
|
3
|
+
|
|
4
|
+
<!-- Basic Chips -->
|
|
5
|
+
<mat-card>
|
|
6
|
+
<mat-card-header>
|
|
7
|
+
<mat-card-title>Basic Chips</mat-card-title>
|
|
8
|
+
<mat-card-subtitle>Simple flat badge elements sets</mat-card-subtitle>
|
|
9
|
+
</mat-card-header>
|
|
10
|
+
<mat-card-content style="padding: 16px;">
|
|
11
|
+
<mat-chip-set aria-label="Static selection">
|
|
12
|
+
<mat-chip>One fish</mat-chip>
|
|
13
|
+
<mat-chip>Two fish</mat-chip>
|
|
14
|
+
<mat-chip>Red fish</mat-chip>
|
|
15
|
+
<mat-chip>Blue fish</mat-chip>
|
|
16
|
+
</mat-chip-set>
|
|
17
|
+
</mat-card-content>
|
|
18
|
+
</mat-card>
|
|
19
|
+
|
|
20
|
+
<!-- Chips with Icons & Avatars -->
|
|
21
|
+
<mat-card>
|
|
22
|
+
<mat-card-header>
|
|
23
|
+
<mat-card-title>Rich Content Chips</mat-card-title>
|
|
24
|
+
<mat-card-subtitle>Using avatars or trailing icons remove triggers</mat-card-subtitle>
|
|
25
|
+
</mat-card-header>
|
|
26
|
+
<mat-card-content style="padding: 16px;">
|
|
27
|
+
<mat-chip-set aria-label="Visual variants">
|
|
28
|
+
<mat-chip>
|
|
29
|
+
<img matChipAvatar src="https://material.angular.io/assets/img/examples/shiba1.jpg" alt="Shiba avatar">
|
|
30
|
+
Avatar Prefix
|
|
31
|
+
</mat-chip>
|
|
32
|
+
|
|
33
|
+
<mat-chip>
|
|
34
|
+
<mat-icon matChipRemove>cancel</mat-icon>
|
|
35
|
+
Deletable item
|
|
36
|
+
</mat-chip>
|
|
37
|
+
</mat-chip-set>
|
|
38
|
+
</mat-card-content>
|
|
39
|
+
</mat-card>
|
|
40
|
+
|
|
41
|
+
<!-- Selectable Box Mode -->
|
|
42
|
+
<mat-card>
|
|
43
|
+
<mat-card-header>
|
|
44
|
+
<mat-card-title>Selectable Listbox Choice</mat-card-title>
|
|
45
|
+
<mat-card-subtitle>Toggling option states arrays sets</mat-card-subtitle>
|
|
46
|
+
</mat-card-header>
|
|
47
|
+
<mat-card-content style="padding: 16px;">
|
|
48
|
+
<mat-chip-listbox aria-label="Color selection" [(ngModel)]="selectedColor">
|
|
49
|
+
@for (color of availableColors; track color) {
|
|
50
|
+
<mat-chip-option [color]="color.toLowerCase() === 'warn' ? 'warn' : color.toLowerCase() === 'primary' ? 'primary' : 'accent'">
|
|
51
|
+
{{color}}
|
|
52
|
+
</mat-chip-option>
|
|
53
|
+
}
|
|
54
|
+
</mat-chip-listbox>
|
|
55
|
+
<p style="margin-top: 12px; font-size: 14px; color: #5f6368;">Selected Color: <strong>{{selectedColor}}</strong></p>
|
|
56
|
+
</mat-card-content>
|
|
57
|
+
</mat-card>
|
|
58
|
+
|
|
59
|
+
<!-- Input Chips -->
|
|
60
|
+
<mat-card>
|
|
61
|
+
<mat-card-header>
|
|
62
|
+
<mat-card-title>Dynamic Add/Remove Inputs</mat-card-title>
|
|
63
|
+
<mat-card-subtitle>Stacking items from an input field list</mat-card-subtitle>
|
|
64
|
+
</mat-card-header>
|
|
65
|
+
<mat-card-content style="padding: 16px;">
|
|
66
|
+
<mat-form-field appearance="outline" style="width: 100%;">
|
|
67
|
+
<mat-label>Favorite Fruits</mat-label>
|
|
68
|
+
<mat-chip-grid #chipGrid aria-label="Fruit selection">
|
|
69
|
+
@for (fruit of fruits; track fruit) {
|
|
70
|
+
<mat-chip-row (removed)="remove(fruit)">
|
|
71
|
+
{{fruit}}
|
|
72
|
+
<button matChipRemove [attr.aria-label]="'remove ' + fruit">
|
|
73
|
+
<mat-icon>cancel</mat-icon>
|
|
74
|
+
</button>
|
|
75
|
+
</mat-chip-row>
|
|
76
|
+
}
|
|
77
|
+
</mat-chip-grid>
|
|
78
|
+
<input placeholder="New fruit..."
|
|
79
|
+
[matChipInputFor]="chipGrid"
|
|
80
|
+
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
|
|
81
|
+
(matChipInputTokenEnd)="add($event)"/>
|
|
82
|
+
</mat-form-field>
|
|
83
|
+
</mat-card-content>
|
|
84
|
+
</mat-card>
|
|
85
|
+
|
|
86
|
+
</div>
|
|
87
|
+
</app-page>
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Component } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { PageComponent } from '../../components/page/page';
|
|
4
|
+
import { MatCardModule } from '@angular/material/card';
|
|
5
|
+
import { MatChipsModule, MatChipInputEvent } from '@angular/material/chips';
|
|
6
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
7
|
+
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
8
|
+
import { MatInputModule } from '@angular/material/input';
|
|
9
|
+
import { COMMA, ENTER } from '@angular/cdk/keycodes';
|
|
10
|
+
import { FormsModule } from '@angular/forms';
|
|
11
|
+
|
|
12
|
+
@Component({
|
|
13
|
+
selector: 'app-chips-demo',
|
|
14
|
+
standalone: true,
|
|
15
|
+
imports: [
|
|
16
|
+
CommonModule,
|
|
17
|
+
PageComponent,
|
|
18
|
+
MatCardModule,
|
|
19
|
+
MatChipsModule,
|
|
20
|
+
MatIconModule,
|
|
21
|
+
MatFormFieldModule,
|
|
22
|
+
MatInputModule,
|
|
23
|
+
FormsModule
|
|
24
|
+
],
|
|
25
|
+
templateUrl: './chips-demo.html',
|
|
26
|
+
styleUrl: './chips-demo.scss'
|
|
27
|
+
})
|
|
28
|
+
export class ChipsDemoComponent {
|
|
29
|
+
readonly separatorKeysCodes = [ENTER, COMMA] as const;
|
|
30
|
+
|
|
31
|
+
// Dynamic list for Input example
|
|
32
|
+
fruits: string[] = ['Lemon', 'Lime', 'Apple'];
|
|
33
|
+
|
|
34
|
+
// Selectable example states
|
|
35
|
+
selectedColor: string = 'Accent';
|
|
36
|
+
availableColors: string[] = ['Primary', 'Accent', 'Warn'];
|
|
37
|
+
|
|
38
|
+
add(event: MatChipInputEvent): void {
|
|
39
|
+
const value = (event.value || '').trim();
|
|
40
|
+
|
|
41
|
+
// Add our fruit
|
|
42
|
+
if (value) {
|
|
43
|
+
this.fruits.push(value);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Clear the input value
|
|
47
|
+
event.chipInput!.clear();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
remove(fruit: string): void {
|
|
51
|
+
const index = this.fruits.indexOf(fruit);
|
|
52
|
+
|
|
53
|
+
if (index >= 0) {
|
|
54
|
+
this.fruits.splice(index, 1);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<app-page title="Code Snippet Showcase">
|
|
2
|
+
<div class="showcase-container default-container-padding">
|
|
3
|
+
|
|
4
|
+
<!-- HTML Snippet -->
|
|
5
|
+
<mat-card class="showcase-card">
|
|
6
|
+
<mat-card-header>
|
|
7
|
+
<mat-card-title>HTML Snippet</mat-card-title>
|
|
8
|
+
<mat-card-subtitle>Standard HTML code block</mat-card-subtitle>
|
|
9
|
+
</mat-card-header>
|
|
10
|
+
<mat-card-content class="showcase-grid">
|
|
11
|
+
<pre class="code-block"><code>{{ htmlSnippet }}</code></pre>
|
|
12
|
+
</mat-card-content>
|
|
13
|
+
</mat-card>
|
|
14
|
+
|
|
15
|
+
<!-- TypeScript Snippet -->
|
|
16
|
+
<mat-card class="showcase-card">
|
|
17
|
+
<mat-card-header>
|
|
18
|
+
<mat-card-title>TypeScript Snippet</mat-card-title>
|
|
19
|
+
<mat-card-subtitle>Standard TS code block</mat-card-subtitle>
|
|
20
|
+
</mat-card-header>
|
|
21
|
+
<mat-card-content class="showcase-grid">
|
|
22
|
+
<pre class="code-block"><code>{{ tsSnippet }}</code></pre>
|
|
23
|
+
</mat-card-content>
|
|
24
|
+
</mat-card>
|
|
25
|
+
|
|
26
|
+
<!-- JSON Snippet -->
|
|
27
|
+
<mat-card class="showcase-card">
|
|
28
|
+
<mat-card-header>
|
|
29
|
+
<mat-card-title>JSON Snippet</mat-card-title>
|
|
30
|
+
<mat-card-subtitle>Standard JSON code block</mat-card-subtitle>
|
|
31
|
+
</mat-card-header>
|
|
32
|
+
<mat-card-content class="showcase-grid">
|
|
33
|
+
<pre class="code-block"><code>{{ jsonSnippet }}</code></pre>
|
|
34
|
+
</mat-card-content>
|
|
35
|
+
</mat-card>
|
|
36
|
+
|
|
37
|
+
<!-- Complex Editor (NgStack) -->
|
|
38
|
+
<mat-card class="showcase-card">
|
|
39
|
+
<mat-card-header>
|
|
40
|
+
<mat-card-title>Complex Editor (Interactive)</mat-card-title>
|
|
41
|
+
<mat-card-subtitle>Using ngstack/code-editor</mat-card-subtitle>
|
|
42
|
+
</mat-card-header>
|
|
43
|
+
<mat-card-content style="padding: 16px;">
|
|
44
|
+
<ngs-code-editor
|
|
45
|
+
[codeModel]="codeModel"
|
|
46
|
+
style="height: 300px; display: block;">
|
|
47
|
+
</ngs-code-editor>
|
|
48
|
+
</mat-card-content>
|
|
49
|
+
</mat-card>
|
|
50
|
+
|
|
51
|
+
</div>
|
|
52
|
+
</app-page>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
.showcase-container {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
gap: 24px;
|
|
5
|
+
max-width: 1000px;
|
|
6
|
+
margin: 0 auto;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.showcase-card {
|
|
10
|
+
margin-bottom: 8px;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.showcase-grid {
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
gap: 16px;
|
|
17
|
+
padding: 16px;
|
|
18
|
+
align-items: flex-start;
|
|
19
|
+
}
|
|
20
|
+
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Component } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { MatCardModule } from '@angular/material/card';
|
|
4
|
+
import { PageComponent } from '../../components/page/page';
|
|
5
|
+
import { CodeEditorModule, CodeModel } from '@ngstack/code-editor';
|
|
6
|
+
|
|
7
|
+
@Component({
|
|
8
|
+
selector: 'app-code-snippet-demo',
|
|
9
|
+
standalone: true,
|
|
10
|
+
imports: [
|
|
11
|
+
CommonModule,
|
|
12
|
+
MatCardModule,
|
|
13
|
+
PageComponent,
|
|
14
|
+
CodeEditorModule
|
|
15
|
+
],
|
|
16
|
+
templateUrl: './code-snippet-demo.html',
|
|
17
|
+
styleUrls: ['./code-snippet-demo.scss']
|
|
18
|
+
})
|
|
19
|
+
export class CodeSnippetDemoComponent {
|
|
20
|
+
htmlSnippet = `<div class="container">\n <h1>Hello World</h1>\n <p>This is a simple HTML snippet.</p>\n</div>`;
|
|
21
|
+
|
|
22
|
+
tsSnippet = `import { Component } from '@angular/core';\n\n@Component({\n selector: 'app-root',\n template: '<h1>Hello</h1>'\n})\nexport class AppComponent { }`;
|
|
23
|
+
|
|
24
|
+
jsonSnippet = `{\n "name": "components",\n "version": "1.0.0",\n "dependencies": {\n "angular": "^15.0.0"\n }\n}`;
|
|
25
|
+
|
|
26
|
+
codeModel: CodeModel = {
|
|
27
|
+
language: 'typescript',
|
|
28
|
+
uri: 'complex-snippet.ts',
|
|
29
|
+
value: `export class UserService {\n constructor() {}\n\n getUser() {\n return 'John Doe';\n }\n}`
|
|
30
|
+
};
|
|
31
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<app-page title="Dialog">
|
|
2
|
+
<div class="demo-container default-container-padding">
|
|
3
|
+
<!-- Simple Dialog Section -->
|
|
4
|
+
<div class="example-section">
|
|
5
|
+
<h3>Simple Dialog</h3>
|
|
6
|
+
<p>A basic dialog that presents information to the user with a dismiss button actions structure neatness.</p>
|
|
7
|
+
|
|
8
|
+
<div class="button-row">
|
|
9
|
+
<button mat-flat-button color="primary" (click)="openSimpleDialog()">
|
|
10
|
+
Launch Simple Dialog
|
|
11
|
+
</button>
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
<!-- Confirmation Dialog Section -->
|
|
16
|
+
<div class="example-section">
|
|
17
|
+
<h3>Confirmation Dialog</h3>
|
|
18
|
+
<p>Requires user action (Confirm or Cancel) and returns a boolean value to the parent component safely triggers.</p>
|
|
19
|
+
|
|
20
|
+
<div class="button-row">
|
|
21
|
+
<button mat-stroked-button color="accent" (click)="openConfirmationDialog()">
|
|
22
|
+
Launch Confirmation Dialog
|
|
23
|
+
</button>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<div class="result-box" *ngIf="confirmationResult">
|
|
27
|
+
<strong>Result:</strong> {{ confirmationResult }}
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
<!-- Form Dialog Section -->
|
|
32
|
+
<div class="example-section">
|
|
33
|
+
<h3>Form Input Dialog</h3>
|
|
34
|
+
<p>Opens a dialog containing an input form to submit dynamic content structures neatly.</p>
|
|
35
|
+
|
|
36
|
+
<div class="button-row">
|
|
37
|
+
<button mat-flat-button color="warn" (click)="openFormDialog()">
|
|
38
|
+
Launch Form Dialog
|
|
39
|
+
</button>
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
<div class="result-box" *ngIf="formResult">
|
|
43
|
+
<strong>Submitted Data:</strong> <pre>{{ formResult | json }}</pre>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
</app-page>
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { Component, ChangeDetectorRef } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
4
|
+
import { MatDialog, MatDialogModule } from '@angular/material/dialog';
|
|
5
|
+
import { MatCardModule } from '@angular/material/card';
|
|
6
|
+
import { PageComponent } from '../../components/page/page';
|
|
7
|
+
import {
|
|
8
|
+
SimpleDialogComponent,
|
|
9
|
+
ConfirmationDialogComponent,
|
|
10
|
+
FormDialogComponent
|
|
11
|
+
} from './dialog-examples';
|
|
12
|
+
|
|
13
|
+
@Component({
|
|
14
|
+
selector: 'app-dialog-demo',
|
|
15
|
+
standalone: true,
|
|
16
|
+
imports: [
|
|
17
|
+
CommonModule,
|
|
18
|
+
MatButtonModule,
|
|
19
|
+
MatDialogModule,
|
|
20
|
+
MatCardModule,
|
|
21
|
+
PageComponent
|
|
22
|
+
],
|
|
23
|
+
templateUrl: './dialog-demo.html',
|
|
24
|
+
styles: [`
|
|
25
|
+
.demo-container {
|
|
26
|
+
display: flex;
|
|
27
|
+
flex-direction: column;
|
|
28
|
+
gap: 24px;
|
|
29
|
+
padding: 16px;
|
|
30
|
+
}
|
|
31
|
+
.example-section {
|
|
32
|
+
border: 1px solid var(--mat-divider-color, #e0e0e0);
|
|
33
|
+
border-radius: 8px;
|
|
34
|
+
padding: 24px;
|
|
35
|
+
}
|
|
36
|
+
.example-section h3 {
|
|
37
|
+
margin-top: 0;
|
|
38
|
+
color: #333;
|
|
39
|
+
}
|
|
40
|
+
.button-row {
|
|
41
|
+
display: flex;
|
|
42
|
+
gap: 12px;
|
|
43
|
+
flex-wrap: wrap;
|
|
44
|
+
margin-top: 16px;
|
|
45
|
+
}
|
|
46
|
+
.result-box {
|
|
47
|
+
margin-top: 16px;
|
|
48
|
+
padding: 12px;
|
|
49
|
+
background-color: #f5f5f5;
|
|
50
|
+
border-radius: 4px;
|
|
51
|
+
font-family: monospace;
|
|
52
|
+
}
|
|
53
|
+
`]
|
|
54
|
+
})
|
|
55
|
+
export class DialogDemoComponent {
|
|
56
|
+
confirmationResult: string | null = null;
|
|
57
|
+
formResult: any | null = null;
|
|
58
|
+
submitData: any | null = null; // Adding this if the user is looking for 'submitData' specifically in template or logic
|
|
59
|
+
|
|
60
|
+
constructor(private dialog: MatDialog, private cdr: ChangeDetectorRef) {}
|
|
61
|
+
|
|
62
|
+
openSimpleDialog(): void {
|
|
63
|
+
this.dialog.open(SimpleDialogComponent, {
|
|
64
|
+
width: '400px'
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
openConfirmationDialog(): void {
|
|
69
|
+
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
|
70
|
+
width: '400px',
|
|
71
|
+
data: { message: 'Do you want to save these changes before leaving?' }
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
dialogRef.afterClosed().subscribe(result => {
|
|
75
|
+
this.confirmationResult = result !== undefined ? `User selected: ${result ? 'Confirm' : 'Cancel'}` : 'Dialog dismissed';
|
|
76
|
+
this.cdr.detectChanges();
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
openFormDialog(): void {
|
|
81
|
+
const dialogRef = this.dialog.open(FormDialogComponent, {
|
|
82
|
+
width: '450px'
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
dialogRef.afterClosed().subscribe(result => {
|
|
86
|
+
this.formResult = result || null;
|
|
87
|
+
this.cdr.detectChanges();
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { Component, Inject } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
4
|
+
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
|
|
5
|
+
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
6
|
+
import { MatInputModule } from '@angular/material/input';
|
|
7
|
+
import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
|
|
8
|
+
|
|
9
|
+
// --- 1. Simple Information Dialog ---
|
|
10
|
+
@Component({
|
|
11
|
+
selector: 'app-simple-dialog',
|
|
12
|
+
standalone: true,
|
|
13
|
+
imports: [CommonModule, MatDialogModule, MatButtonModule],
|
|
14
|
+
template: `
|
|
15
|
+
<h2 mat-dialog-title>Information</h2>
|
|
16
|
+
<mat-dialog-content>
|
|
17
|
+
<p>This is a simple informational dialog content showcasing standard Material dialog layouts structures.</p>
|
|
18
|
+
</mat-dialog-content>
|
|
19
|
+
<mat-dialog-actions align="end">
|
|
20
|
+
<button mat-button mat-dialog-close>Close</button>
|
|
21
|
+
</mat-dialog-actions>
|
|
22
|
+
`
|
|
23
|
+
})
|
|
24
|
+
export class SimpleDialogComponent {}
|
|
25
|
+
|
|
26
|
+
// --- 2. Confirmation Dialog ---
|
|
27
|
+
@Component({
|
|
28
|
+
selector: 'app-confirmation-dialog',
|
|
29
|
+
standalone: true,
|
|
30
|
+
imports: [CommonModule, MatDialogModule, MatButtonModule],
|
|
31
|
+
template: `
|
|
32
|
+
<h2 mat-dialog-title>Confirm Action</h2>
|
|
33
|
+
<mat-dialog-content>
|
|
34
|
+
<p>{{ data.message || 'Are you sure you want to proceed?' }}</p>
|
|
35
|
+
</mat-dialog-content>
|
|
36
|
+
<mat-dialog-actions align="end">
|
|
37
|
+
<button mat-button (click)="onNoClick()">Cancel</button>
|
|
38
|
+
<button mat-flat-button color="primary" [mat-dialog-close]="true">Confirm</button>
|
|
39
|
+
</mat-dialog-actions>
|
|
40
|
+
`
|
|
41
|
+
})
|
|
42
|
+
export class ConfirmationDialogComponent {
|
|
43
|
+
constructor(
|
|
44
|
+
public dialogRef: MatDialogRef<ConfirmationDialogComponent>,
|
|
45
|
+
@Inject(MAT_DIALOG_DATA) public data: { message: string }
|
|
46
|
+
) {}
|
|
47
|
+
|
|
48
|
+
onNoClick(): void {
|
|
49
|
+
this.dialogRef.close(false);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// --- 3. Form Input Dialog ---
|
|
54
|
+
@Component({
|
|
55
|
+
selector: 'app-form-dialog',
|
|
56
|
+
standalone: true,
|
|
57
|
+
imports: [
|
|
58
|
+
CommonModule,
|
|
59
|
+
MatDialogModule,
|
|
60
|
+
MatButtonModule,
|
|
61
|
+
MatFormFieldModule,
|
|
62
|
+
MatInputModule,
|
|
63
|
+
ReactiveFormsModule
|
|
64
|
+
],
|
|
65
|
+
template: `
|
|
66
|
+
<h2 mat-dialog-title>Add New Item</h2>
|
|
67
|
+
<mat-dialog-content class="mat-typography">
|
|
68
|
+
<form [formGroup]="form" class="form-container">
|
|
69
|
+
<mat-form-field appearance="outline" class="full-width">
|
|
70
|
+
<mat-label>Item Name</mat-label>
|
|
71
|
+
<input matInput formControlName="name" placeholder="Enter name">
|
|
72
|
+
<mat-error *ngIf="form.get('name')?.hasError('required')">
|
|
73
|
+
Name is required
|
|
74
|
+
</mat-error>
|
|
75
|
+
</mat-form-field>
|
|
76
|
+
|
|
77
|
+
<mat-form-field appearance="outline" class="full-width">
|
|
78
|
+
<mat-label>Description</mat-label>
|
|
79
|
+
<textarea matInput formControlName="description" placeholder="Enter description" rows="3"></textarea>
|
|
80
|
+
</mat-form-field>
|
|
81
|
+
</form>
|
|
82
|
+
</mat-dialog-content>
|
|
83
|
+
<mat-dialog-actions align="end">
|
|
84
|
+
<button mat-button (click)="onCancel()">Cancel</button>
|
|
85
|
+
<button mat-flat-button color="primary" (click)="onSubmit()" [disabled]="form.invalid">Submit</button>
|
|
86
|
+
</mat-dialog-actions>
|
|
87
|
+
`,
|
|
88
|
+
styles: [`
|
|
89
|
+
.form-container {
|
|
90
|
+
display: flex;
|
|
91
|
+
flex-direction: column;
|
|
92
|
+
gap: 16px;
|
|
93
|
+
margin-top: 8px;
|
|
94
|
+
}
|
|
95
|
+
.full-width {
|
|
96
|
+
width: 100%;
|
|
97
|
+
}
|
|
98
|
+
mat-dialog-content {
|
|
99
|
+
min-width: 320px;
|
|
100
|
+
}
|
|
101
|
+
`]
|
|
102
|
+
})
|
|
103
|
+
export class FormDialogComponent {
|
|
104
|
+
form: FormGroup;
|
|
105
|
+
|
|
106
|
+
constructor(
|
|
107
|
+
private fb: FormBuilder,
|
|
108
|
+
public dialogRef: MatDialogRef<FormDialogComponent>,
|
|
109
|
+
@Inject(MAT_DIALOG_DATA) public data: any
|
|
110
|
+
) {
|
|
111
|
+
this.form = this.fb.group({
|
|
112
|
+
name: ['', Validators.required],
|
|
113
|
+
description: ['']
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
onCancel(): void {
|
|
118
|
+
this.dialogRef.close();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
onSubmit(): void {
|
|
122
|
+
if (this.form.valid) {
|
|
123
|
+
this.dialogRef.close(this.form.value);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<app-page title="Expand Button Showcase">
|
|
2
|
+
<div class="showcase-container default-container-padding">
|
|
3
|
+
<mat-card class="showcase-card">
|
|
4
|
+
<mat-card-header>
|
|
5
|
+
<mat-card-title>Expandable Settings Pattern</mat-card-title>
|
|
6
|
+
<mat-card-subtitle>A lightweight toggle for hidden content</mat-card-subtitle>
|
|
7
|
+
</mat-card-header>
|
|
8
|
+
<mat-card-content style="padding: 16px;">
|
|
9
|
+
<div class="expand-btn-container">
|
|
10
|
+
<button mat-button color="primary" (click)="isExpanded = !isExpanded" class="expand-toggle">
|
|
11
|
+
<mat-icon>{{ isExpanded ? 'expand_less' : 'expand_more' }}</mat-icon>
|
|
12
|
+
<span>{{ isExpanded ? 'Hide' : 'Show' }} advanced settings</span>
|
|
13
|
+
</button>
|
|
14
|
+
|
|
15
|
+
<div class="expand-content" *ngIf="isExpanded">
|
|
16
|
+
<p class="content-description">Here are some advanced settings you can configure. They are hidden by default.</p>
|
|
17
|
+
|
|
18
|
+
<mat-form-field appearance="outline" class="full-width">
|
|
19
|
+
<input matInput placeholder="An input">
|
|
20
|
+
</mat-form-field>
|
|
21
|
+
|
|
22
|
+
<div class="caption-text">This is inside the expand button</div>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</mat-card-content>
|
|
26
|
+
</mat-card>
|
|
27
|
+
</div>
|
|
28
|
+
</app-page>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
.expand-btn-container {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
gap: 16px;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.expand-toggle {
|
|
8
|
+
display: flex;
|
|
9
|
+
align-items: center;
|
|
10
|
+
gap: 8px;
|
|
11
|
+
width: fit-content;
|
|
12
|
+
color: #1a73e8; // Primary blue
|
|
13
|
+
font-weight: 500;
|
|
14
|
+
padding: 0; // Remove default button padding if needed, or keep it for touch target
|
|
15
|
+
|
|
16
|
+
.mat-icon {
|
|
17
|
+
font-size: 20px;
|
|
18
|
+
width: 20px;
|
|
19
|
+
height: 20px;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.expand-content {
|
|
24
|
+
display: flex;
|
|
25
|
+
flex-direction: column;
|
|
26
|
+
gap: 16px;
|
|
27
|
+
padding-left: 16px; // Indent content
|
|
28
|
+
border-left: 2px solid #e8eaed; // Subtle visual guide
|
|
29
|
+
margin-top: 8px;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.content-description {
|
|
33
|
+
font-size: 14px;
|
|
34
|
+
color: #3c4043;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.full-width {
|
|
38
|
+
width: 100%;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.caption-text {
|
|
42
|
+
font-size: 12px;
|
|
43
|
+
color: #70757a;
|
|
44
|
+
margin-top: -8px; // Pull closer to input
|
|
45
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Component } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { MatCardModule } from '@angular/material/card';
|
|
4
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
5
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
6
|
+
import { MatInputModule } from '@angular/material/input';
|
|
7
|
+
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
8
|
+
import { PageComponent } from '../../components/page/page';
|
|
9
|
+
|
|
10
|
+
@Component({
|
|
11
|
+
selector: 'app-expand-button-demo',
|
|
12
|
+
standalone: true,
|
|
13
|
+
imports: [
|
|
14
|
+
CommonModule,
|
|
15
|
+
MatCardModule,
|
|
16
|
+
MatButtonModule,
|
|
17
|
+
MatIconModule,
|
|
18
|
+
MatInputModule,
|
|
19
|
+
MatFormFieldModule,
|
|
20
|
+
PageComponent
|
|
21
|
+
],
|
|
22
|
+
templateUrl: './expand-button-demo.html',
|
|
23
|
+
styleUrls: ['./expand-button-demo.scss']
|
|
24
|
+
})
|
|
25
|
+
export class ExpandButtonDemoComponent {
|
|
26
|
+
isExpanded = false;
|
|
27
|
+
isExpanded2 = false; // For a second variation if needed
|
|
28
|
+
}
|