Skip to content

Commit 2e78fad

Browse files
Initial commit
0 parents  commit 2e78fad

File tree

13 files changed

+429
-0
lines changed

13 files changed

+429
-0
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# angular-dropdown-menu-component
2+
3+
[Edit on StackBlitz ⚡️](https://stackblitz.com/edit/angular-dropdown-menu-component)

angular.json

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
{
2+
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3+
"version": 1,
4+
"newProjectRoot": "projects",
5+
"projects": {
6+
"demo": {
7+
"root": "",
8+
"sourceRoot": "src",
9+
"projectType": "application",
10+
"prefix": "app",
11+
"schematics": {},
12+
"architect": {
13+
"build": {
14+
"builder": "@angular-devkit/build-angular:browser",
15+
"options": {
16+
"outputPath": "dist/demo",
17+
"index": "src/index.html",
18+
"main": "src/main.ts",
19+
"polyfills": "src/polyfills.ts",
20+
"tsConfig": "src/tsconfig.app.json",
21+
"assets": ["src/favicon.ico", "src/assets"],
22+
"styles": ["src/styles.scss"],
23+
"scripts": []
24+
},
25+
"configurations": {
26+
"production": {
27+
"fileReplacements": [
28+
{
29+
"replace": "src/environments/environment.ts",
30+
"with": "src/environments/environment.prod.ts"
31+
}
32+
],
33+
"optimization": true,
34+
"outputHashing": "all",
35+
"sourceMap": false,
36+
"extractCss": true,
37+
"namedChunks": false,
38+
"aot": true,
39+
"extractLicenses": true,
40+
"vendorChunk": false,
41+
"buildOptimizer": true
42+
}
43+
}
44+
},
45+
"serve": {
46+
"builder": "@angular-devkit/build-angular:dev-server",
47+
"options": {
48+
"browserTarget": "demo:build"
49+
},
50+
"configurations": {
51+
"production": {
52+
"browserTarget": "demo:build:production"
53+
}
54+
}
55+
},
56+
"extract-i18n": {
57+
"builder": "@angular-devkit/build-angular:extract-i18n",
58+
"options": {
59+
"browserTarget": "demo:build"
60+
}
61+
},
62+
"test": {
63+
"builder": "@angular-devkit/build-angular:karma",
64+
"options": {
65+
"main": "src/test.ts",
66+
"polyfills": "src/polyfills.ts",
67+
"tsConfig": "src/tsconfig.spec.json",
68+
"karmaConfig": "src/karma.conf.js",
69+
"styles": ["styles.css"],
70+
"scripts": [],
71+
"assets": ["src/favicon.ico", "src/assets"]
72+
}
73+
},
74+
"lint": {
75+
"builder": "@angular-devkit/build-angular:tslint",
76+
"options": {
77+
"tsConfig": ["src/tsconfig.app.json", "src/tsconfig.spec.json"],
78+
"exclude": ["**/node_modules/**"]
79+
}
80+
}
81+
}
82+
}
83+
},
84+
"defaultProject": "demo"
85+
}

package.json

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{
2+
"name": "angular",
3+
"version": "0.0.0",
4+
"private": true,
5+
"dependencies": {
6+
"@angular/animations": "^15.1.0",
7+
"@angular/common": "^15.1.0",
8+
"@angular/compiler": "^15.1.0",
9+
"@angular/core": "^15.1.0",
10+
"@angular/forms": "^15.1.0",
11+
"@angular/platform-browser": "^15.1.0",
12+
"@angular/platform-browser-dynamic": "^15.1.0",
13+
"@angular/router": "^15.1.0",
14+
"rxjs": "^7.8.0",
15+
"tslib": "^2.4.1",
16+
"zone.js": "^0.12.0"
17+
},
18+
"scripts": {
19+
"ng": "ng",
20+
"start": "ng serve",
21+
"build": "ng build",
22+
"test": "ng test",
23+
"lint": "ng lint",
24+
"e2e": "ng e2e"
25+
},
26+
"devDependencies": {
27+
"@angular-devkit/build-angular": "~0.1100.4",
28+
"@angular/cli": "~11.0.4",
29+
"@angular/compiler-cli": "~11.0.4",
30+
"@types/jasmine": "~3.6.0",
31+
"@types/node": "^12.11.1",
32+
"codelyzer": "^6.0.0",
33+
"jasmine-core": "~3.6.0",
34+
"jasmine-spec-reporter": "~5.0.0",
35+
"karma": "~5.1.0",
36+
"karma-chrome-launcher": "~3.1.0",
37+
"karma-coverage": "~2.0.3",
38+
"karma-jasmine": "~4.0.0",
39+
"karma-jasmine-html-reporter": "^1.5.0",
40+
"protractor": "~7.0.0",
41+
"ts-node": "~8.3.0",
42+
"tslint": "~6.1.0",
43+
"typescript": "~4.0.2"
44+
}
45+
}

src/app/app.component.html

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<header>
2+
<div class="fat-arrow">
3+
<span>( ) =</span>
4+
<span class="caret">&#62;</span>
5+
</div>
6+
<a href="https://frontenddevelopment.tech/" target="_blank"
7+
>frontenddevelopment.tech</a
8+
>
9+
</header>
10+
11+
<div id="dropdown-component">
12+
<div class="selected" (click)="toggleMenu()">
13+
<span>{{ selectedValue }}</span>
14+
<span [ngClass]="{ 'arrow-down': menuOpen }">&#x27A4;</span>
15+
</div>
16+
<div class="menu-wrapper">
17+
<ul #listElem>
18+
<li *ngFor="let item of listElems" (click)="clickHandler(item)">
19+
<a href="#" clickDirective>{{ item }}</a>
20+
</li>
21+
</ul>
22+
</div>
23+
</div>

src/app/app.component.scss

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#dropdown-component {
2+
margin: 20px auto 0 auto;
3+
font: normal 14px sans-serif;
4+
width: 200px;
5+
position: relative;
6+
.selected {
7+
z-index: 10;
8+
cursor: pointer;
9+
margin: 0 auto;
10+
border: 1px solid black;
11+
padding: 5px;
12+
border-radius: 4px;
13+
span:first-child {
14+
margin-right: 10px;
15+
}
16+
span:last-child {
17+
float: right;
18+
transition: transform 0.2s;
19+
}
20+
}
21+
.arrow-down {
22+
transform: rotate(90deg);
23+
}
24+
.menu-wrapper {
25+
overflow: hidden;
26+
margin-top: 3px;
27+
position: absolute;
28+
width: 100%;
29+
ul {
30+
list-style-type: none;
31+
width: calc(100% - 4px);
32+
padding: 0;
33+
border: 1px solid #000;
34+
border-bottom-left-radius: 4px;
35+
border-bottom-right-radius: 4px;
36+
overflow: hidden;
37+
transition: transform 0.2s;
38+
transform: translateY(-145px);
39+
left: 0;
40+
right: 0;
41+
margin: 0 auto;
42+
li {
43+
overflow: hidden;
44+
a {
45+
text-decoration: none;
46+
background-color: lightgray;
47+
width: 100%;
48+
display: block;
49+
color: black;
50+
padding: 5px 0 5px 15px;
51+
box-sizing: border-box;
52+
transition: background-color 0.2s;
53+
&:hover {
54+
background-color: darkgray;
55+
}
56+
}
57+
}
58+
}
59+
}
60+
61+
.show-menu {
62+
transform: none !important;
63+
}
64+
}

src/app/app.component.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Component, ElementRef, HostListener, ViewChild } from '@angular/core';
2+
3+
@Component({
4+
selector: 'my-app',
5+
templateUrl: './app.component.html',
6+
styleUrls: ['./app.component.scss'],
7+
})
8+
export class AppComponent {
9+
menuOpen: boolean = false;
10+
@ViewChild('listElem') listElem: ElementRef;
11+
listElems: string[] = ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5'];
12+
selectedValue: string = 'Select an item';
13+
14+
toggleMenu() {
15+
this.menuOpen = !this.menuOpen;
16+
this.listElem.nativeElement.classList.toggle('show-menu');
17+
}
18+
19+
clickHandler(item: string) {
20+
this.selectedValue = item;
21+
this.toggleMenu();
22+
}
23+
24+
@HostListener('click') hostClick() {
25+
console.log('interacted with menu...');
26+
}
27+
}

src/app/app.module.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { NgModule } from '@angular/core';
2+
import { BrowserModule } from '@angular/platform-browser';
3+
import { FormsModule } from '@angular/forms';
4+
import { AppComponent } from './app.component';
5+
import { ClickDirective } from './directive';
6+
7+
@NgModule({
8+
imports: [BrowserModule, FormsModule],
9+
declarations: [AppComponent, ClickDirective],
10+
bootstrap: [AppComponent],
11+
})
12+
export class AppModule {}

src/app/directive.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { Directive, ElementRef, Renderer2 } from '@angular/core';
2+
3+
@Directive({
4+
selector: '[clickDirective]',
5+
})
6+
export class ClickDirective {
7+
constructor(private renderer: Renderer2, private elemRef: ElementRef) {}
8+
9+
ngAfterViewInit() {
10+
this.renderer.listen(this.elemRef.nativeElement, 'click', (evt) => {
11+
console.log('Global click evt:', evt.target);
12+
});
13+
}
14+
}

src/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<my-app>loading</my-app>

src/main.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import './polyfills';
2+
3+
import { enableProdMode } from '@angular/core';
4+
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
5+
6+
import { AppModule } from './app/app.module';
7+
8+
platformBrowserDynamic().bootstrapModule(AppModule).then(ref => {
9+
// Ensure Angular destroys itself on hot reloads.
10+
if (window['ngRef']) {
11+
window['ngRef'].destroy();
12+
}
13+
window['ngRef'] = ref;
14+
15+
// Otherwise, log the boot error
16+
}).catch(err => console.error(err));

0 commit comments

Comments
 (0)