├── projects ├── .gitkeep └── angular-material-rail-drawer │ ├── src │ ├── lib │ │ ├── default.config.ts │ │ ├── drawer-rail.module.ts │ │ ├── animations.settings.ts │ │ └── drawer-rail.directive.ts │ ├── public-api.ts │ └── test-setup.ts │ ├── ng-package.json │ ├── tsconfig.lib.prod.json │ ├── tsconfig.lib.json │ ├── tsconfig.spec.json │ ├── package.json │ ├── tsconfig.json │ ├── jest.config.ts │ ├── .eslintrc.json │ ├── project.json │ └── README.md ├── .eslintignore ├── .prettierrc ├── examples └── material-rail-drawer │ ├── src │ ├── assets │ │ └── .gitkeep │ ├── app │ │ ├── app.component.scss │ │ ├── app.component.ts │ │ ├── app.module.ts │ │ ├── app.component.spec.ts │ │ └── app.component.html │ ├── favicon.ico │ ├── main.ts │ ├── test-setup.ts │ ├── index.html │ └── styles.scss │ ├── tsconfig.editor.json │ ├── tsconfig.app.json │ ├── tsconfig.spec.json │ ├── jest.config.ts │ ├── tsconfig.json │ ├── .eslintrc.json │ └── project.json ├── .vscode └── settings.json ├── .prettierignore ├── jest.preset.js ├── jest.config.ts ├── .whitesource ├── .editorconfig ├── license ├── tsconfig.base.json ├── .gitignore ├── .eslintrc.json ├── .github └── workflows │ └── npmpublish.yml ├── nx.json ├── package.json └── README.md /projects/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true 3 | } 4 | -------------------------------------------------------------------------------- /examples/material-rail-drawer/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "deno.enable": false, 3 | } -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Add files here to ignore them from prettier formatting 2 | /dist 3 | /coverage 4 | .angular 5 | -------------------------------------------------------------------------------- /examples/material-rail-drawer/src/app/app.component.scss: -------------------------------------------------------------------------------- 1 | .container { 2 | padding: 8px 24px 108px 24px; 3 | } 4 | -------------------------------------------------------------------------------- /jest.preset.js: -------------------------------------------------------------------------------- 1 | const nxPreset = require('@nx/jest/preset').default; 2 | 3 | module.exports = { ...nxPreset }; 4 | -------------------------------------------------------------------------------- /jest.config.ts: -------------------------------------------------------------------------------- 1 | import { getJestProjects } from '@nx/jest'; 2 | 3 | export default { 4 | projects: getJestProjects(), 5 | }; 6 | -------------------------------------------------------------------------------- /examples/material-rail-drawer/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jordan-Hall/angular-material-rail-drawer-plugin/HEAD/examples/material-rail-drawer/src/favicon.ico -------------------------------------------------------------------------------- /.whitesource: -------------------------------------------------------------------------------- 1 | { 2 | "checkRunSettings": { 3 | "vulnerableCheckRunConclusionLevel": "failure" 4 | }, 5 | "issueSettings": { 6 | "minSeverityLevel": "LOW" 7 | } 8 | } -------------------------------------------------------------------------------- /projects/angular-material-rail-drawer/src/lib/default.config.ts: -------------------------------------------------------------------------------- 1 | export const miniConfig = { 2 | defaultDuration: '100ms', 3 | defaultMinWidth: '60px', 4 | defaultMaxWidth: '200px', 5 | }; 6 | -------------------------------------------------------------------------------- /examples/material-rail-drawer/tsconfig.editor.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": [ 4 | "src/**/*.ts" 5 | ], 6 | "compilerOptions": { 7 | "types": [ 8 | "jest", 9 | "node" 10 | ] 11 | } 12 | } -------------------------------------------------------------------------------- /projects/angular-material-rail-drawer/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../dist/angular-material-rail-drawer", 4 | "lib": { 5 | "entryFile": "src/public-api.ts" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /projects/angular-material-rail-drawer/tsconfig.lib.prod.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.lib.json", 3 | "compilerOptions": { 4 | "declarationMap": false 5 | }, 6 | "angularCompilerOptions": { 7 | "compilationMode": "partial" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /examples/material-rail-drawer/src/main.ts: -------------------------------------------------------------------------------- 1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 2 | import { AppModule } from './app/app.module'; 3 | 4 | platformBrowserDynamic() 5 | .bootstrapModule(AppModule) 6 | .catch((err) => console.error(err)); 7 | -------------------------------------------------------------------------------- /projects/angular-material-rail-drawer/src/public-api.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Public API Surface of angular-material-rail-drawer 3 | */ 4 | export * from './lib/default.config'; 5 | export * from './lib/animations.settings'; 6 | export * from './lib/drawer-rail.directive'; 7 | export * from './lib/drawer-rail.module'; 8 | -------------------------------------------------------------------------------- /examples/material-rail-drawer/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | templateUrl: './app.component.html', 6 | styleUrls: ['./app.component.scss'], 7 | }) 8 | export class AppComponent { 9 | title = 'angular-material-rail-drawer-example'; 10 | } 11 | -------------------------------------------------------------------------------- /examples/material-rail-drawer/src/test-setup.ts: -------------------------------------------------------------------------------- 1 | // @ts-expect-error https://thymikee.github.io/jest-preset-angular/docs/getting-started/test-environment 2 | globalThis.ngJest = { 3 | testEnvironmentOptions: { 4 | errorOnUnknownElements: true, 5 | errorOnUnknownProperties: true, 6 | }, 7 | }; 8 | import 'jest-preset-angular/setup-jest'; 9 | -------------------------------------------------------------------------------- /projects/angular-material-rail-drawer/src/test-setup.ts: -------------------------------------------------------------------------------- 1 | // @ts-expect-error https://thymikee.github.io/jest-preset-angular/docs/getting-started/test-environment 2 | globalThis.ngJest = { 3 | testEnvironmentOptions: { 4 | errorOnUnknownElements: true, 5 | errorOnUnknownProperties: true, 6 | }, 7 | }; 8 | import 'jest-preset-angular/setup-jest'; 9 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /examples/material-rail-drawer/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "types": [] 6 | }, 7 | "files": [ 8 | "src/main.ts" 9 | ], 10 | "include": [ 11 | "src/**/*.d.ts" 12 | ], 13 | "exclude": [ 14 | "jest.config.ts", 15 | "src/**/*.test.ts", 16 | "src/**/*.spec.ts" 17 | ] 18 | } -------------------------------------------------------------------------------- /projects/angular-material-rail-drawer/src/lib/drawer-rail.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { MatSidenavModule } from '@angular/material/sidenav'; 3 | import { MatDrawerRailDirective } from './drawer-rail.directive'; 4 | 5 | @NgModule({ 6 | imports: [MatSidenavModule], 7 | declarations: [MatDrawerRailDirective], 8 | exports: [MatDrawerRailDirective], 9 | }) 10 | export class DrawerRailModule {} 11 | -------------------------------------------------------------------------------- /projects/angular-material-rail-drawer/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "declaration": true, 6 | "declarationMap": true, 7 | "inlineSources": true, 8 | "types": [] 9 | }, 10 | "exclude": [ 11 | "src/**/*.spec.ts", 12 | "src/test-setup.ts", 13 | "jest.config.ts", 14 | "src/**/*.test.ts" 15 | ], 16 | "include": ["src/**/*.ts"] 17 | } 18 | -------------------------------------------------------------------------------- /examples/material-rail-drawer/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "target": "es2022", 7 | "types": [ 8 | "jest", 9 | "node" 10 | ] 11 | }, 12 | "files": [ 13 | "src/test-setup.ts" 14 | ], 15 | "include": [ 16 | "jest.config.ts", 17 | "src/**/*.test.ts", 18 | "src/**/*.spec.ts", 19 | "src/**/*.d.ts" 20 | ] 21 | } -------------------------------------------------------------------------------- /projects/angular-material-rail-drawer/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/out-tsc", 5 | "module": "commonjs", 6 | "target": "es2022", 7 | "types": [ 8 | "jest", 9 | "node" 10 | ] 11 | }, 12 | "files": [ 13 | "src/test-setup.ts" 14 | ], 15 | "include": [ 16 | "jest.config.ts", 17 | "src/**/*.test.ts", 18 | "src/**/*.spec.ts", 19 | "src/**/*.d.ts" 20 | ] 21 | } -------------------------------------------------------------------------------- /examples/material-rail-drawer/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |Name
13 |Inbox
20 |Starred
24 |Drafts
28 |44 | Since 2016, the Angular community has been shouting out of a 45 | mini variant for material design, including this article by 52 | Harkirat Singh 59 | which you can view here: 60 | Angular 6 — Mini-Variant Drawer. Unfortunately every version I’ve seen currently uses some form of 67 | *ngIf 68 |
69 | 70 |
87 | Other solutions include using CSS and setting a min with; however, what
88 | all of these solutions are lacking are animation support and straight
89 | forward implantation. In late December a client I was working for,
90 | wanted to use the official
91 | Angular Material design
97 | but also wanted to support a mini variant. At the time, I wrote a
98 | prototype using a customer directive called mat-nav-mini.
99 |
mat-nav-mini Solution
104 | The implementation was easy. You pick either the drawer or the sidenav
105 | drawer and add the custom directive. However, the UI was written
106 | abstract and wasn’t using the official
107 | mat-sidenav-container. However, I still didn’t like this
108 | approach; it felt bulky and still not a “realistic” implementation that
109 | the official team my introduce. At the time, I decided to share the
110 | result on
111 | Github
117 | for people to use as a cleaner implementation to *ngIf.
118 |
121 | Then the other day, I looked back through the thread on GitHub, and 122 | someone called 123 | Angelfraga 129 | asked to create a working example. 130 |
131 | 132 |
158 | 165 | A few more days have passed by, and I decided, I’ll make a working 166 | example. However, for the working example, I wanted to make the right 167 | implementation that meet my strict objectives 168 |
169 | 170 |182 | Material has long last drawn up specs for 183 | “Navigation rail.” 189 | Inside the Specs they a behaviour usage: “Some apps, such as 190 | Material’s Reply, customize and extend the rail to function as both a rail and a 196 | navigation drawer.” 197 |
198 | 199 |
200 | The goal is now to create a drawer implementation for a new mode setting
201 | mode="rail". Any new implementation should be implementing
202 | the existing material drawer component but with
203 | mode="rail".
204 |
207 | The solution meant no extending drawer component, no CSS solution but 208 | somehow adding functionality to “mode” which was an input for both 209 | md-drawer and md-sidenav-drawer 210 |
211 | 212 |
214 | The first step was determining the first issue to overcome. The design
215 | solution requires you to use the mode input with the option of “rail”
216 | this was easy to overcome as every @Input()In angular is a
217 | simple implementation of the custom directive.
218 |
221 | The next problem was the SCSS. Looking at the specs for Navigation rail, 222 | the drawer would be the same spec as the “side” drawer; this meant we 223 | didn’t have to write custom scss file that needed to import. That 224 | allowed me to use the “host” property and assign the same class as 225 | “side”. 226 |
227 |228 | After tackling these two issues, after two hours of work, looking 229 | through angular code file, I managed to come up with a solution. The 230 | solution is a simple directive that needs to include in your module. 231 |
232 | 233 |234 | Result is the page you are looking at. 235 | View Source 238 |
239 |