mirror of
https://github.com/Raghu-Ch/angular-accessibility.git
synced 2026-02-10 04:43:02 -05:00
feat(app): initial commit!
This commit is contained in:
17
.browserslistrc
Normal file
17
.browserslistrc
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
|
||||||
|
# For additional information regarding the format and rule options, please see:
|
||||||
|
# https://github.com/browserslist/browserslist#queries
|
||||||
|
|
||||||
|
# For the full list of supported browsers by the Angular framework, please see:
|
||||||
|
# https://angular.io/guide/browser-support
|
||||||
|
|
||||||
|
# You can see what browsers were selected by your queries by running:
|
||||||
|
# npx browserslist
|
||||||
|
|
||||||
|
last 1 Chrome version
|
||||||
|
last 1 Firefox version
|
||||||
|
last 2 Edge major versions
|
||||||
|
last 2 Safari major versions
|
||||||
|
last 2 iOS major versions
|
||||||
|
Firefox ESR
|
||||||
|
not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line.
|
||||||
16
.editorconfig
Normal file
16
.editorconfig
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# Editor configuration, see https://editorconfig.org
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.ts]
|
||||||
|
quote_type = single
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
max_line_length = off
|
||||||
|
trim_trailing_whitespace = false
|
||||||
78
.eslintrc.json
Normal file
78
.eslintrc.json
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
{
|
||||||
|
"root": true,
|
||||||
|
"ignorePatterns": [
|
||||||
|
"projects/**/*"
|
||||||
|
],
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"*.ts"
|
||||||
|
],
|
||||||
|
"parserOptions": {
|
||||||
|
"project": [
|
||||||
|
"tsconfig.json",
|
||||||
|
"e2e/tsconfig.json"
|
||||||
|
],
|
||||||
|
"createDefaultProgram": true
|
||||||
|
},
|
||||||
|
"extends": [
|
||||||
|
"plugin:@angular-eslint/ng-cli-compat",
|
||||||
|
"plugin:@angular-eslint/ng-cli-compat--formatting-add-on",
|
||||||
|
"plugin:@angular-eslint/template/process-inline-templates"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"@angular-eslint/component-selector": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"type": "element",
|
||||||
|
"prefix": "app",
|
||||||
|
"style": "kebab-case"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"@angular-eslint/directive-selector": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"type": "attribute",
|
||||||
|
"prefix": "app",
|
||||||
|
"style": "camelCase"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"@typescript-eslint/explicit-member-accessibility": [
|
||||||
|
"off",
|
||||||
|
{
|
||||||
|
"accessibility": "explicit"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"@typescript-eslint/no-unused-vars": "error",
|
||||||
|
"arrow-parens": [
|
||||||
|
"off",
|
||||||
|
"always"
|
||||||
|
],
|
||||||
|
"id-blacklist": "error",
|
||||||
|
"import/order": "off",
|
||||||
|
"no-bitwise": "off",
|
||||||
|
"space-before-function-paren": "off"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"*.html"
|
||||||
|
],
|
||||||
|
"extends": [
|
||||||
|
"plugin:@angular-eslint/template/recommended"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"@angular-eslint/template/accessibility-alt-text": 2,
|
||||||
|
"@angular-eslint/template/accessibility-elements-content": 2,
|
||||||
|
"@angular-eslint/template/accessibility-label-for": 2,
|
||||||
|
"@angular-eslint/template/no-positive-tabindex": 2,
|
||||||
|
"@angular-eslint/template/accessibility-table-scope": 2,
|
||||||
|
"@angular-eslint/template/accessibility-valid-aria": 2,
|
||||||
|
"@angular-eslint/template/click-events-have-key-events": 2,
|
||||||
|
"@angular-eslint/template/mouse-events-have-key-events": 2,
|
||||||
|
"@angular-eslint/template/no-autofocus": 2,
|
||||||
|
"@angular-eslint/template/no-distracting-elements": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
47
.gitignore
vendored
Normal file
47
.gitignore
vendored
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# compiled output
|
||||||
|
/dist
|
||||||
|
/tmp
|
||||||
|
/out-tsc
|
||||||
|
# Only exists if Bazel was run
|
||||||
|
/bazel-out
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
|
||||||
|
# profiling files
|
||||||
|
chrome-profiler-events*.json
|
||||||
|
speed-measure-plugin*.json
|
||||||
|
|
||||||
|
# IDEs and editors
|
||||||
|
/.idea
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
.c9/
|
||||||
|
*.launch
|
||||||
|
.settings/
|
||||||
|
*.sublime-workspace
|
||||||
|
|
||||||
|
# IDE - VSCode
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.history/*
|
||||||
|
|
||||||
|
# misc
|
||||||
|
/.sass-cache
|
||||||
|
/connect.lock
|
||||||
|
/coverage
|
||||||
|
/libpeerconnection.log
|
||||||
|
npm-debug.log
|
||||||
|
yarn-error.log
|
||||||
|
testem.log
|
||||||
|
/typings
|
||||||
|
*.package-lock.json
|
||||||
|
|
||||||
|
# System Files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
29
CONTRIBUTING.md
Normal file
29
CONTRIBUTING.md
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# How to Contribute
|
||||||
|
|
||||||
|
We'd love to accept your patches and contributions to this project. There are
|
||||||
|
just a few small guidelines you need to follow.
|
||||||
|
|
||||||
|
## Contributor License Agreement
|
||||||
|
|
||||||
|
Contributions to this project must be accompanied by a Contributor License
|
||||||
|
Agreement (CLA). You (or your employer) retain the copyright to your
|
||||||
|
contribution; this simply gives us permission to use and redistribute your
|
||||||
|
contributions as part of the project. Head over to
|
||||||
|
<https://cla.developers.google.com/> to see your current agreements on file or
|
||||||
|
to sign a new one.
|
||||||
|
|
||||||
|
You generally only need to submit a CLA once, so if you've already submitted one
|
||||||
|
(even if it was for a different project), you probably don't need to do it
|
||||||
|
again.
|
||||||
|
|
||||||
|
## Code Reviews
|
||||||
|
|
||||||
|
All submissions, including submissions by project members, require review. We
|
||||||
|
use GitHub pull requests for this purpose. Consult
|
||||||
|
[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
|
||||||
|
information on using pull requests.
|
||||||
|
|
||||||
|
## Community Guidelines
|
||||||
|
|
||||||
|
This project follows
|
||||||
|
[Google's Open Source Community Guidelines](https://opensource.google/conduct/).
|
||||||
201
LICENSE
Normal file
201
LICENSE
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
17
README.md
Normal file
17
README.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# A11y in Angular demo : A Dumpling Shop
|
||||||
|
|
||||||
|
Demo for the [Build more accessible Angular apps](codelabs.developers.google.com/angular-a11y) codelab.
|
||||||
|
|
||||||
|
|
||||||
|
## Get set up
|
||||||
|
|
||||||
|
Run `npm install` to install the dependencies required to run the server.
|
||||||
|
|
||||||
|
Run `ng serve --hmr` to run the server.
|
||||||
|
|
||||||
|
Open a browser tab to [http://localhost:4200](). The app will automatically reload if you change any of the source files.
|
||||||
|
|
||||||
|
|
||||||
|
## Disclaimer
|
||||||
|
|
||||||
|
This is a demo from [@twerske](https://twitter.com/twerske) and the Angular team, and not an officially supported Google product.
|
||||||
130
angular.json
Normal file
130
angular.json
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
{
|
||||||
|
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||||
|
"cli": {
|
||||||
|
"analytics": false
|
||||||
|
},
|
||||||
|
"version": 1,
|
||||||
|
"newProjectRoot": "projects",
|
||||||
|
"projects": {
|
||||||
|
"angular-a11y": {
|
||||||
|
"projectType": "application",
|
||||||
|
"schematics": {
|
||||||
|
"@schematics/angular:component": {
|
||||||
|
"style": "scss"
|
||||||
|
},
|
||||||
|
"@schematics/angular:application": {
|
||||||
|
"strict": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "",
|
||||||
|
"sourceRoot": "src",
|
||||||
|
"prefix": "app",
|
||||||
|
"architect": {
|
||||||
|
"build": {
|
||||||
|
"builder": "@angular-devkit/build-angular:browser",
|
||||||
|
"options": {
|
||||||
|
"outputPath": "dist/angular-a11y",
|
||||||
|
"index": "src/index.html",
|
||||||
|
"main": "src/main.ts",
|
||||||
|
"polyfills": "src/polyfills.ts",
|
||||||
|
"tsConfig": "tsconfig.app.json",
|
||||||
|
"aot": true,
|
||||||
|
"assets": [
|
||||||
|
"src/favicon.ico",
|
||||||
|
"src/assets"
|
||||||
|
],
|
||||||
|
"styles": [
|
||||||
|
"src/styles.scss"
|
||||||
|
],
|
||||||
|
"scripts": []
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"fileReplacements": [
|
||||||
|
{
|
||||||
|
"replace": "src/environments/environment.ts",
|
||||||
|
"with": "src/environments/environment.prod.ts"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"optimization": true,
|
||||||
|
"outputHashing": "all",
|
||||||
|
"sourceMap": false,
|
||||||
|
"namedChunks": false,
|
||||||
|
"extractLicenses": true,
|
||||||
|
"vendorChunk": false,
|
||||||
|
"buildOptimizer": true,
|
||||||
|
"budgets": [
|
||||||
|
{
|
||||||
|
"type": "initial",
|
||||||
|
"maximumWarning": "500kb",
|
||||||
|
"maximumError": "1mb"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "anyComponentStyle",
|
||||||
|
"maximumWarning": "2kb",
|
||||||
|
"maximumError": "4kb"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"serve": {
|
||||||
|
"builder": "@angular-devkit/build-angular:dev-server",
|
||||||
|
"options": {
|
||||||
|
"browserTarget": "angular-a11y:build"
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"browserTarget": "angular-a11y:build:production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extract-i18n": {
|
||||||
|
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||||
|
"options": {
|
||||||
|
"browserTarget": "angular-a11y:build"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"builder": "@angular-devkit/build-angular:karma",
|
||||||
|
"options": {
|
||||||
|
"main": "src/test.ts",
|
||||||
|
"polyfills": "src/polyfills.ts",
|
||||||
|
"tsConfig": "tsconfig.spec.json",
|
||||||
|
"karmaConfig": "karma.conf.js",
|
||||||
|
"assets": [
|
||||||
|
"src/favicon.ico",
|
||||||
|
"src/assets"
|
||||||
|
],
|
||||||
|
"styles": [
|
||||||
|
"src/styles.scss"
|
||||||
|
],
|
||||||
|
"scripts": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"builder": "@angular-eslint/builder:lint",
|
||||||
|
"options": {
|
||||||
|
"lintFilePatterns": [
|
||||||
|
"src/**/*.ts",
|
||||||
|
"src/**/*.html"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"e2e": {
|
||||||
|
"builder": "@angular-devkit/build-angular:protractor",
|
||||||
|
"options": {
|
||||||
|
"protractorConfig": "e2e/protractor.conf.js",
|
||||||
|
"devServerTarget": "angular-a11y:serve"
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"devServerTarget": "angular-a11y:serve:production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"defaultProject": "angular-a11y"
|
||||||
|
}
|
||||||
59
karma.conf.js
Normal file
59
karma.conf.js
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
// Karma configuration file, see link for more information
|
||||||
|
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||||
|
|
||||||
|
module.exports = function (config) {
|
||||||
|
config.set({
|
||||||
|
basePath: '',
|
||||||
|
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||||
|
plugins: [
|
||||||
|
require('karma-jasmine'),
|
||||||
|
require('karma-chrome-launcher'),
|
||||||
|
require('karma-jasmine-html-reporter'),
|
||||||
|
require('karma-coverage'),
|
||||||
|
require('@angular-devkit/build-angular/plugins/karma')
|
||||||
|
],
|
||||||
|
client: {
|
||||||
|
jasmine: {
|
||||||
|
// you can add configuration options for Jasmine here
|
||||||
|
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
|
||||||
|
// for example, you can disable the random execution with `random: false`
|
||||||
|
// or set a specific seed with `seed: 4321`
|
||||||
|
},
|
||||||
|
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||||
|
},
|
||||||
|
jasmineHtmlReporter: {
|
||||||
|
suppressAll: true // removes the duplicated traces
|
||||||
|
},
|
||||||
|
coverageReporter: {
|
||||||
|
dir: require('path').join(__dirname, './coverage/angular-a11y'),
|
||||||
|
subdir: '.',
|
||||||
|
reporters: [
|
||||||
|
{ type: 'html' },
|
||||||
|
{ type: 'text-summary' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
reporters: ['progress', 'kjhtml'],
|
||||||
|
port: 9876,
|
||||||
|
colors: true,
|
||||||
|
logLevel: config.LOG_INFO,
|
||||||
|
autoWatch: true,
|
||||||
|
browsers: ['Chrome'],
|
||||||
|
singleRun: false,
|
||||||
|
restartOnFileChange: true
|
||||||
|
});
|
||||||
|
};
|
||||||
14852
package-lock.json
generated
Normal file
14852
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
58
package.json
Normal file
58
package.json
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
{
|
||||||
|
"name": "angular-a11y",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"scripts": {
|
||||||
|
"ng": "ng",
|
||||||
|
"start": "ng serve",
|
||||||
|
"build": "ng build",
|
||||||
|
"test": "ng test",
|
||||||
|
"lint": "eslint -c .eslintrc.js --ext .ts ./src/",
|
||||||
|
"e2e": "ng e2e"
|
||||||
|
},
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@angular/animations": "~12.0.0-next.9",
|
||||||
|
"@angular/cdk": "^12.0.0-next.7",
|
||||||
|
"@angular/common": "^12.0.0-next.9",
|
||||||
|
"@angular/compiler": "^12.0.0-next.9",
|
||||||
|
"@angular/core": "^12.0.0-next.9",
|
||||||
|
"@angular/forms": "^12.0.0-next.9",
|
||||||
|
"@angular/google-maps": "^11.2.6",
|
||||||
|
"@angular/material": "^12.0.0-next.7",
|
||||||
|
"@angular/platform-browser": "^12.0.0-next.9",
|
||||||
|
"@angular/platform-browser-dynamic": "^12.0.0-next.9",
|
||||||
|
"@angular/router": "~12.0.0-next.9",
|
||||||
|
"rxjs": "~6.6.0",
|
||||||
|
"tslib": "^2.0.0",
|
||||||
|
"zone.js": "~0.11.3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@angular-devkit/build-angular": "~12.0.0-next.9",
|
||||||
|
"@angular/cli": "~12.0.0-next.9",
|
||||||
|
"@angular/compiler-cli": "~12.0.0-next.9",
|
||||||
|
"@types/jasmine": "~3.6.0",
|
||||||
|
"@types/node": "^12.11.1",
|
||||||
|
"@typescript-eslint/eslint-plugin": "4.16.1",
|
||||||
|
"@typescript-eslint/parser": "4.16.1",
|
||||||
|
"eslint": "^7.6.0",
|
||||||
|
"jasmine-core": "~3.6.0",
|
||||||
|
"jasmine-spec-reporter": "~5.0.0",
|
||||||
|
"karma": "~6.3.2",
|
||||||
|
"karma-chrome-launcher": "~3.1.0",
|
||||||
|
"karma-coverage": "~2.0.3",
|
||||||
|
"karma-jasmine": "~4.0.0",
|
||||||
|
"karma-jasmine-html-reporter": "^1.5.0",
|
||||||
|
"protractor": "~7.0.0",
|
||||||
|
"ts-node": "~8.3.0",
|
||||||
|
"tslint": "~6.1.0",
|
||||||
|
"typescript": "~4.2.3",
|
||||||
|
"eslint-plugin-import": "2.22.1",
|
||||||
|
"eslint-plugin-jsdoc": "30.7.6",
|
||||||
|
"eslint-plugin-prefer-arrow": "1.2.2",
|
||||||
|
"@angular-eslint/builder": "2.0.2",
|
||||||
|
"@angular-eslint/eslint-plugin": "2.0.2",
|
||||||
|
"@angular-eslint/eslint-plugin-template": "2.0.2",
|
||||||
|
"@angular-eslint/schematics": "2.0.2",
|
||||||
|
"@angular-eslint/template-parser": "2.0.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/app/about/about.component.html
Normal file
27
src/app/about/about.component.html
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<!--
|
||||||
|
Copyright 2021 Google LLC
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<div class="about">
|
||||||
|
<!-- TODO: #6. Use Semantic HTML -->
|
||||||
|
<h3>Who are we?</h3>
|
||||||
|
<h2>Have you ever thought, “wow, I love dumplings”?</h2>
|
||||||
|
<h5 class="right">Who hasn't.</h5>
|
||||||
|
<h6 class="center">We took it one step further and created Dumpling Dumpling,</h6>
|
||||||
|
<h5 class="center">double the dumpling, double the fun.</h5>
|
||||||
|
<div class="spacer"></div>
|
||||||
|
<h5>How are we different?</h5>
|
||||||
|
<h4>Handmade in San Francisco, California, we craft fully customizable dumplings. Glitter? Rainbows? Vegan? We do it all.</h4>
|
||||||
|
<h3 class="right">This shop is concept only.</h3>
|
||||||
|
</div>
|
||||||
42
src/app/about/about.component.scss
Normal file
42
src/app/about/about.component.scss
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
:host {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.about {
|
||||||
|
width: 50%;
|
||||||
|
padding: 5%;
|
||||||
|
|
||||||
|
.center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spacer {
|
||||||
|
height: 10%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:host-context(.dark-theme) {
|
||||||
|
.about {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
23
src/app/about/about.component.ts
Normal file
23
src/app/about/about.component.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-about',
|
||||||
|
templateUrl: './about.component.html',
|
||||||
|
styleUrls: ['./about.component.scss']
|
||||||
|
})
|
||||||
|
export class AboutComponent { }
|
||||||
35
src/app/app-routing.module.ts
Normal file
35
src/app/app-routing.module.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
import { AboutComponent } from './about/about.component';
|
||||||
|
import { LocationComponent } from './location/location.component';
|
||||||
|
import { ShopComponent } from './shop/shop.component';
|
||||||
|
|
||||||
|
// TODO: #4. Define unique page titles
|
||||||
|
const routes: Routes = [
|
||||||
|
{ path: 'shop', component: ShopComponent },
|
||||||
|
{ path: 'about', component: AboutComponent },
|
||||||
|
{ path: 'locate', component: LocationComponent },
|
||||||
|
{ path: '', redirectTo: '/shop', pathMatch: 'full' },
|
||||||
|
{ path: '**', component: ShopComponent },
|
||||||
|
];
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [RouterModule.forRoot(routes)],
|
||||||
|
exports: [RouterModule]
|
||||||
|
})
|
||||||
|
export class AppRoutingModule { }
|
||||||
17
src/app/app.component.html
Normal file
17
src/app/app.component.html
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<!--
|
||||||
|
Copyright 2021 Google LLC
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<app-navigation></app-navigation>
|
||||||
|
<router-outlet></router-outlet>
|
||||||
15
src/app/app.component.scss
Normal file
15
src/app/app.component.scss
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
34
src/app/app.component.ts
Normal file
34
src/app/app.component.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
// TODO: #4. Define unique page titles - add imports
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-root',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.scss']
|
||||||
|
})
|
||||||
|
export class AppComponent implements OnInit {
|
||||||
|
title = 'a11y in Angular';
|
||||||
|
isDark: boolean | undefined;
|
||||||
|
bodyStyles: CSSStyleDeclaration | undefined;
|
||||||
|
|
||||||
|
// TODO: #4. Define unique page titles - add the TitleService and Router.
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
|
ngOnInit(): void {}
|
||||||
|
}
|
||||||
71
src/app/app.module.ts
Normal file
71
src/app/app.module.ts
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { BrowserModule, Title } from '@angular/platform-browser';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
|
||||||
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
|
import { AppComponent } from './app.component';
|
||||||
|
|
||||||
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
|
import { MatCardModule } from '@angular/material/card';
|
||||||
|
import { MatDialogModule } from '@angular/material/dialog';
|
||||||
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
|
import { MatListModule } from '@angular/material/list';
|
||||||
|
import { MatSliderModule } from '@angular/material/slider';
|
||||||
|
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||||
|
import { GoogleMapsModule } from '@angular/google-maps';
|
||||||
|
|
||||||
|
import { AboutComponent } from './about/about.component';
|
||||||
|
import { ColorPickerComponent } from './shop/color-picker/color-picker.component';
|
||||||
|
import { ColorPickerDialogComponent } from './shop/color-picker/color-picker-dialog/color-picker-dialog.component';
|
||||||
|
import { DumplingComponent } from './shop/dumpling/dumpling.component';
|
||||||
|
import { LocationComponent } from './location/location.component';
|
||||||
|
import { NavigationComponent } from './navigation/navigation.component';
|
||||||
|
import { ShopComponent } from './shop/shop.component';
|
||||||
|
|
||||||
|
// TODO: #9. Add the power of @angular/cdk/a11y
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [
|
||||||
|
AppComponent,
|
||||||
|
NavigationComponent,
|
||||||
|
ShopComponent,
|
||||||
|
AboutComponent,
|
||||||
|
LocationComponent,
|
||||||
|
DumplingComponent,
|
||||||
|
ColorPickerComponent,
|
||||||
|
ColorPickerDialogComponent,
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
BrowserModule,
|
||||||
|
AppRoutingModule,
|
||||||
|
FormsModule,
|
||||||
|
BrowserAnimationsModule,
|
||||||
|
MatButtonModule,
|
||||||
|
MatCardModule,
|
||||||
|
MatDialogModule,
|
||||||
|
MatIconModule,
|
||||||
|
MatListModule,
|
||||||
|
MatSliderModule,
|
||||||
|
MatToolbarModule,
|
||||||
|
GoogleMapsModule,
|
||||||
|
],
|
||||||
|
providers: [Title],
|
||||||
|
bootstrap: [AppComponent]
|
||||||
|
})
|
||||||
|
export class AppModule { }
|
||||||
36
src/app/location/location.component.html
Normal file
36
src/app/location/location.component.html
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<!--
|
||||||
|
Copyright 2021 Google LLC
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<div class="location-map">
|
||||||
|
<google-map
|
||||||
|
role="application"
|
||||||
|
height="50%"
|
||||||
|
width="100%"
|
||||||
|
[options]="options">
|
||||||
|
<map-marker [position]="markerPosition"
|
||||||
|
[options]="markerOptions"></map-marker>
|
||||||
|
</google-map>
|
||||||
|
<div class="details">
|
||||||
|
<h2>Find Us</h2>
|
||||||
|
<address class="address">
|
||||||
|
<div>123 Dolores Street</div>
|
||||||
|
<div>San Francisco, CA 94114</div>
|
||||||
|
</address>
|
||||||
|
<div class="hours">
|
||||||
|
<h3>Pickup Hours</h3>
|
||||||
|
<p>Monday to Friday, 10am to 6pm</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
46
src/app/location/location.component.scss
Normal file
46
src/app/location/location.component.scss
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
.location-map {
|
||||||
|
height: 100%;
|
||||||
|
text-align: -webkit-center;
|
||||||
|
padding: 5%;
|
||||||
|
|
||||||
|
.map-container {
|
||||||
|
border: #f0f8ff 2px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.details {
|
||||||
|
margin: 5%;
|
||||||
|
|
||||||
|
.typography {
|
||||||
|
margin: .1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hours {
|
||||||
|
margin-top: 1rem;
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:host-context(.dark-theme) {
|
||||||
|
.details {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
62
src/app/location/location.component.ts
Normal file
62
src/app/location/location.component.ts
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-location',
|
||||||
|
templateUrl: './location.component.html',
|
||||||
|
styleUrls: ['./location.component.scss']
|
||||||
|
})
|
||||||
|
export class LocationComponent {
|
||||||
|
center: google.maps.LatLngLiteral = {
|
||||||
|
lat: 37.759767,
|
||||||
|
lng: -122.427121,
|
||||||
|
};
|
||||||
|
|
||||||
|
options: google.maps.MapOptions = {
|
||||||
|
center: this.center,
|
||||||
|
zoom: 20,
|
||||||
|
mapTypeId: 'hybrid',
|
||||||
|
zoomControl: false,
|
||||||
|
scrollwheel: false,
|
||||||
|
disableDoubleClickZoom: true,
|
||||||
|
maxZoom: 15,
|
||||||
|
minZoom: 8,
|
||||||
|
styles: [
|
||||||
|
{
|
||||||
|
featureType: 'all',
|
||||||
|
stylers: [
|
||||||
|
{ color: '#C0C0C0' }
|
||||||
|
]
|
||||||
|
}, {
|
||||||
|
featureType: 'road.arterial',
|
||||||
|
elementType: 'geometry',
|
||||||
|
stylers: [
|
||||||
|
{ color: '#CCFFFF' }
|
||||||
|
]
|
||||||
|
}, {
|
||||||
|
featureType: 'landscape',
|
||||||
|
elementType: 'labels',
|
||||||
|
stylers: [
|
||||||
|
{ visibility: 'off' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
markerPosition: google.maps.LatLngLiteral = this.center;
|
||||||
|
markerOptions: google.maps.MarkerOptions = {draggable: false};
|
||||||
|
}
|
||||||
39
src/app/navigation/navigation.component.html
Normal file
39
src/app/navigation/navigation.component.html
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<!--
|
||||||
|
Copyright 2021 Google LLC
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<mat-toolbar color="primary">
|
||||||
|
<mat-toolbar-row class="title-header">
|
||||||
|
<a mat-icon-button class="home-icon" aria-label="Home"
|
||||||
|
routerLink="/" routerLinkActive="active" color="primary">
|
||||||
|
<mat-icon>home</mat-icon>
|
||||||
|
</a>
|
||||||
|
<h1 class="display-1">Dumpling Shop</h1>
|
||||||
|
<button mat-icon-button
|
||||||
|
(click)="toggleTheme()"
|
||||||
|
matTooltip="Toggle theme"
|
||||||
|
attr.aria-label="Switch to {{ isDark ? 'light' : 'dark' }} theme"
|
||||||
|
color="primary">
|
||||||
|
<mat-icon>brightness_medium</mat-icon>
|
||||||
|
</button>
|
||||||
|
</mat-toolbar-row>
|
||||||
|
|
||||||
|
<mat-toolbar-row class="navigation-links">
|
||||||
|
<nav>
|
||||||
|
<a mat-button routerLink="/shop" routerLinkActive="active">Our Shop</a>
|
||||||
|
<a mat-button routerLink="/about" routerLinkActive="active">Our Story</a>
|
||||||
|
<a mat-button routerLink="/locate" routerLinkActive="active">Find Us</a>
|
||||||
|
</nav>
|
||||||
|
</mat-toolbar-row>
|
||||||
|
</mat-toolbar>
|
||||||
26
src/app/navigation/navigation.component.scss
Normal file
26
src/app/navigation/navigation.component.scss
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
.title-header {
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
align-self: flex-end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.navigation-links {
|
||||||
|
place-content: center center;
|
||||||
|
}
|
||||||
43
src/app/navigation/navigation.component.ts
Normal file
43
src/app/navigation/navigation.component.ts
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { OverlayContainer } from '@angular/cdk/overlay';
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-navigation',
|
||||||
|
templateUrl: './navigation.component.html',
|
||||||
|
styleUrls: ['./navigation.component.scss']
|
||||||
|
})
|
||||||
|
export class NavigationComponent implements OnInit {
|
||||||
|
isDark: boolean | undefined;
|
||||||
|
|
||||||
|
constructor(private overlayContainer: OverlayContainer) {}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.isDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||||
|
this.setTheme();
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleTheme(): void {
|
||||||
|
this.isDark = !this.isDark;
|
||||||
|
this.setTheme();
|
||||||
|
}
|
||||||
|
|
||||||
|
setTheme(): void {
|
||||||
|
document.documentElement.classList.toggle('dark-theme', this.isDark);
|
||||||
|
this.overlayContainer.getContainerElement().classList.toggle('dark-theme', this.isDark);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<!--
|
||||||
|
Copyright 2021 Google LLC
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<div mat-dialog-content>
|
||||||
|
<!-- TODO: #10. Control focus with FocusTrap -->
|
||||||
|
<mat-selection-list #colors aria-label="Dumpling wrapper color" multiple="false">
|
||||||
|
<mat-list-option *ngFor="let paint of defaultColors" [value]="paint" color="primary">
|
||||||
|
<div class="color-option">
|
||||||
|
<div class="circle" [ngStyle]="{'background': paint}"></div>
|
||||||
|
<p>{{ paint }}</p>
|
||||||
|
</div>
|
||||||
|
</mat-list-option>
|
||||||
|
</mat-selection-list>
|
||||||
|
</div>
|
||||||
|
<div mat-dialog-actions>
|
||||||
|
<button mat-button (click)="closeDialog()">
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
<button mat-button (click)="changeColor(colors.selectedOptions.selected[0]?.value)">
|
||||||
|
Apply color
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
.color-option {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
text-transform: uppercase;
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.circle {
|
||||||
|
height: 40px;
|
||||||
|
width: 40px;
|
||||||
|
margin: 10px;
|
||||||
|
margin-left: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 100%;
|
||||||
|
border: 1px solid #dadada;
|
||||||
|
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.14);
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
|
||||||
|
import { MatDialogRef } from '@angular/material/dialog';
|
||||||
|
|
||||||
|
export interface ColorDialogData {
|
||||||
|
color: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-color-picker-dialog',
|
||||||
|
templateUrl: './color-picker-dialog.component.html',
|
||||||
|
styleUrls: ['./color-picker-dialog.component.scss']
|
||||||
|
})
|
||||||
|
export class ColorPickerDialogComponent implements OnInit {
|
||||||
|
@Output() recolor = new EventEmitter();
|
||||||
|
color = '#fff';
|
||||||
|
|
||||||
|
public defaultColors: string[] = [
|
||||||
|
'white',
|
||||||
|
'tomato',
|
||||||
|
'hotpink',
|
||||||
|
'coral',
|
||||||
|
'gold',
|
||||||
|
'greenyellow',
|
||||||
|
'lightgreen',
|
||||||
|
'turquoise',
|
||||||
|
'skyblue',
|
||||||
|
'royalblue',
|
||||||
|
'plum',
|
||||||
|
];
|
||||||
|
|
||||||
|
// TODO: #11. Announce changes with LiveAnnouncer
|
||||||
|
constructor(public dialogRef: MatDialogRef<ColorPickerDialogComponent>) { }
|
||||||
|
|
||||||
|
ngOnInit(): void { }
|
||||||
|
|
||||||
|
public changeColor(color: string): void {
|
||||||
|
if (color) {
|
||||||
|
this.recolor.emit(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: #11. Announce changes with LiveAnnouncer
|
||||||
|
this.dialogRef.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public closeDialog(): void {
|
||||||
|
this.dialogRef.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
29
src/app/shop/color-picker/color-picker.component.html
Normal file
29
src/app/shop/color-picker/color-picker.component.html
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<!--
|
||||||
|
Copyright 2021 Google LLC
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<button mat-button
|
||||||
|
(click)="openDialog()"
|
||||||
|
aria-label="Change dumpling wrapper color"
|
||||||
|
class="wrapper-color">
|
||||||
|
<div class="color-info">
|
||||||
|
<div class="text">
|
||||||
|
<p class="style">
|
||||||
|
Wrapper color:
|
||||||
|
<span class="style-value">{{ color }}</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="circle" [ngStyle]="{'background': color}"></div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
61
src/app/shop/color-picker/color-picker.component.scss
Normal file
61
src/app/shop/color-picker/color-picker.component.scss
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
:host {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper-color {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
.color-info {
|
||||||
|
display: flex;
|
||||||
|
width: 120%;
|
||||||
|
align-items: center;
|
||||||
|
padding: 10px 0;
|
||||||
|
|
||||||
|
.text {
|
||||||
|
width: calc(100% - 40px);
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
p.style {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.style-value {
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 14px;
|
||||||
|
letter-spacing: 1.5px;
|
||||||
|
line-height: normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.circle {
|
||||||
|
height: 40px;
|
||||||
|
width: 40px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 100%;
|
||||||
|
border: 1px solid #dadada;
|
||||||
|
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.14);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
41
src/app/shop/color-picker/color-picker.component.ts
Normal file
41
src/app/shop/color-picker/color-picker.component.ts
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||||
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
|
import { ColorPickerDialogComponent } from './color-picker-dialog/color-picker-dialog.component';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-color-picker',
|
||||||
|
templateUrl: './color-picker.component.html',
|
||||||
|
styleUrls: ['./color-picker.component.scss']
|
||||||
|
})
|
||||||
|
export class ColorPickerComponent {
|
||||||
|
@Input() color = 'gold';
|
||||||
|
@Output() recolor = new EventEmitter();
|
||||||
|
|
||||||
|
constructor(public dialog: MatDialog) {}
|
||||||
|
|
||||||
|
openDialog(): void {
|
||||||
|
const dialogRef = this.dialog.open(ColorPickerDialogComponent, {
|
||||||
|
data: {color: this.color},
|
||||||
|
});
|
||||||
|
|
||||||
|
dialogRef.componentInstance.recolor.subscribe((color) => {
|
||||||
|
this.color = color;
|
||||||
|
this.recolor.emit(this.color);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
29
src/app/shop/dumpling/dumpling.component.html
Normal file
29
src/app/shop/dumpling/dumpling.component.html
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<!--
|
||||||
|
Copyright 2021 Google LLC
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<div class="container">
|
||||||
|
<div class="dumpling-body" [style.background]="color">
|
||||||
|
<div class="fold" [style.background]="color"></div>
|
||||||
|
<div class="fold2" [style.background]="color"></div>
|
||||||
|
<div class="fold3" [style.background]="color"></div>
|
||||||
|
<div class="fold4" [style.background]="color"></div>
|
||||||
|
<div class="fold5" [style.background]="color"></div>
|
||||||
|
<div class="fold6" [style.background]="color"></div>
|
||||||
|
<div class="fold7" [style.background]="color"></div>
|
||||||
|
<div class="fold8" [style.background]="color"></div>
|
||||||
|
<div class="fold9" [style.background]="color"></div>
|
||||||
|
<div class="shadow"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
122
src/app/shop/dumpling/dumpling.component.scss
Normal file
122
src/app/shop/dumpling/dumpling.component.scss
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Adapted from https://codepen.io/osermay/pen/wrKQOd
|
||||||
|
$dumpling-light: #efd7b8;
|
||||||
|
$dumpling-dark: darken(#efd7b8, 15%);
|
||||||
|
$dumpling-size: 100px;
|
||||||
|
$dumpling-inner: 70px;
|
||||||
|
$fold-size: 20px;
|
||||||
|
|
||||||
|
@mixin center ($margin: auto, $left: 0, $right: 0) {
|
||||||
|
margin: $margin;
|
||||||
|
left: $left;
|
||||||
|
right: $right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
position: relative;
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
margin: auto;
|
||||||
|
margin-bottom: -200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dumpling-body {
|
||||||
|
@include center;
|
||||||
|
background-color: $dumpling-light;
|
||||||
|
width: $dumpling-size;
|
||||||
|
height: $dumpling-size/2;
|
||||||
|
border-top-left-radius: $dumpling-size;
|
||||||
|
border-top-right-radius: $dumpling-size;
|
||||||
|
border: #ffe9e9 solid 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shadow {
|
||||||
|
@include center;
|
||||||
|
opacity: 10%;
|
||||||
|
background-color: #ffebcd;
|
||||||
|
width: $dumpling-size * .9;
|
||||||
|
height: $dumpling-inner - $fold-size;
|
||||||
|
border-top-left-radius: $dumpling-size;
|
||||||
|
border-top-right-radius: $dumpling-size;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fold-class {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 60%;
|
||||||
|
border: #ffe9e9 solid 2px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: $dumpling-light;
|
||||||
|
width: $fold-size;
|
||||||
|
height: $fold-size;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fold {
|
||||||
|
@extend .fold-class;
|
||||||
|
right: 68%;
|
||||||
|
top: 15.5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fold2 {
|
||||||
|
@extend .fold-class;
|
||||||
|
right: 66%;
|
||||||
|
top: 7%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fold3 {
|
||||||
|
@extend .fold-class
|
||||||
|
}
|
||||||
|
|
||||||
|
.fold4 {
|
||||||
|
@include center;
|
||||||
|
@extend .fold-class;
|
||||||
|
right: 15%;
|
||||||
|
top: -4%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fold5 {
|
||||||
|
@include center;
|
||||||
|
@extend .fold-class;
|
||||||
|
top: -5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fold6 {
|
||||||
|
@extend .fold5;
|
||||||
|
top: -4%;
|
||||||
|
left: 15%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fold7 {
|
||||||
|
@extend .fold;
|
||||||
|
left: 60%;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fold8 {
|
||||||
|
@extend .fold;
|
||||||
|
left: 66%;
|
||||||
|
top: 7%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fold9 {
|
||||||
|
@extend .fold;
|
||||||
|
left: 68%;
|
||||||
|
top: 15.5%;
|
||||||
|
}
|
||||||
40
src/app/shop/dumpling/dumpling.component.spec.ts
Normal file
40
src/app/shop/dumpling/dumpling.component.spec.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { DumplingComponent } from './dumpling.component';
|
||||||
|
|
||||||
|
describe('DumplingComponent', () => {
|
||||||
|
let component: DumplingComponent;
|
||||||
|
let fixture: ComponentFixture<DumplingComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ DumplingComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(DumplingComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
25
src/app/shop/dumpling/dumpling.component.ts
Normal file
25
src/app/shop/dumpling/dumpling.component.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { Component, Input } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-dumpling',
|
||||||
|
templateUrl: './dumpling.component.html',
|
||||||
|
styleUrls: ['./dumpling.component.scss']
|
||||||
|
})
|
||||||
|
export class DumplingComponent {
|
||||||
|
@Input() color = '#efd7b8';
|
||||||
|
}
|
||||||
101
src/app/shop/shop.component.html
Normal file
101
src/app/shop/shop.component.html
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
<!--
|
||||||
|
Copyright 2021 Google LLC
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<div class="shop">
|
||||||
|
<div class="dumpling-container">
|
||||||
|
<app-dumpling *ngFor="let item of counter(quantity)" [color]="color"></app-dumpling>
|
||||||
|
</div>
|
||||||
|
<div class="dumpling-customizations">
|
||||||
|
<mat-card class="fillings selection-card">
|
||||||
|
<mat-card-title>Fillings</mat-card-title>
|
||||||
|
<mat-card-content>
|
||||||
|
<!-- TODO: #7. Create selectable controls with Angular Material -->
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox" name="vegan" id="vegan"
|
||||||
|
[(ngModel)]="fillings.bokchoy"
|
||||||
|
[(ngModel)]="fillings.tofu">
|
||||||
|
<label for="tall">Vegan</label>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox"
|
||||||
|
id="bokchoy"
|
||||||
|
[(ngModel)]="fillings.bokchoy"
|
||||||
|
name="bokchoy">
|
||||||
|
<label for="bokchoy">Bok Choy</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox"
|
||||||
|
id="tofu"
|
||||||
|
[(ngModel)]="fillings.tofu"
|
||||||
|
name="tofu">
|
||||||
|
<label for="tofu">Tofu & Shitake</label>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox"
|
||||||
|
[(ngModel)]="fillings.chicken"
|
||||||
|
[(ngModel)]="fillings.impossible"
|
||||||
|
name="meat" id="meat">
|
||||||
|
<label for="meat">Meat</label>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox"
|
||||||
|
id="chicken"
|
||||||
|
[(ngModel)]="fillings.chicken"
|
||||||
|
name="chicken">
|
||||||
|
<label for="chicken">Chicken</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<input type="checkbox"
|
||||||
|
id="impossible"
|
||||||
|
[(ngModel)]="fillings.impossible"
|
||||||
|
name="impossible">
|
||||||
|
<label for="impossible">Impossible Meat</label>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
|
<mat-card class="quantity selection-card">
|
||||||
|
<mat-card-title>Quantity</mat-card-title>
|
||||||
|
<mat-card-content>
|
||||||
|
<!-- TODO: #8. Provide control labels with ARIA -->
|
||||||
|
<mat-slider
|
||||||
|
color="primary"
|
||||||
|
class="quantity-slider"
|
||||||
|
[max]="13"
|
||||||
|
[min]="1"
|
||||||
|
[step]="1"
|
||||||
|
[thumbLabel]="true"
|
||||||
|
[tickInterval]="1"
|
||||||
|
[(ngModel)]="quantity">
|
||||||
|
</mat-slider>
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
|
<mat-card class="color selection-card">
|
||||||
|
<mat-card-title>Color</mat-card-title>
|
||||||
|
<mat-card-content>
|
||||||
|
<app-color-picker [color]="color" (recolor)="changeColor($event)"></app-color-picker>
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
|
</div>
|
||||||
|
<!-- TODO: #6. Use Semantic HTML (& Angular Material!) -->
|
||||||
|
<div (click)="fauxPurchase()" class="purchase-button">
|
||||||
|
<h3>Purchase</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
114
src/app/shop/shop.component.scss
Normal file
114
src/app/shop/shop.component.scss
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
@use '~@angular/material' as mat;
|
||||||
|
|
||||||
|
// TODO: #12. Enable HighContrast mode
|
||||||
|
|
||||||
|
:host {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shop {
|
||||||
|
width: 75%;
|
||||||
|
padding: 5%;
|
||||||
|
padding-top: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.dumpling-container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
height: 45vh;
|
||||||
|
overflow: hidden;
|
||||||
|
place-content: space-evenly center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dumpling-customizations {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
.selection-card {
|
||||||
|
margin: 0 10px 10px 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: mat.get-color-from-palette(mat.$pink-palette, 100);
|
||||||
|
|
||||||
|
.mat-card-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantity-slider {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fillings {
|
||||||
|
flex-grow: 1;
|
||||||
|
|
||||||
|
// TODO: #7. Create selectable controls with Angular Material
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
margin: 5px 20px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantity {
|
||||||
|
flex-grow: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.color {
|
||||||
|
flex-grow: 2;
|
||||||
|
margin: 0 0 10px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.purchase-button {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px 0;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: mat.get-color-from-palette(mat.$pink-palette, A100);
|
||||||
|
|
||||||
|
// TODO: #12. Enable HighContrast mode
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 12px;
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin: 16px 0 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:host-context(.dark-theme) {
|
||||||
|
.dumpling-customizations .selection-card {
|
||||||
|
background-color: mat.get-color-from-palette(mat.$indigo-palette, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
.purchase-button {
|
||||||
|
background-color: mat.get-color-from-palette(mat.$light-green-palette, A100);
|
||||||
|
|
||||||
|
// TODO: #12. Enable HighContrast mode
|
||||||
|
}
|
||||||
|
}
|
||||||
62
src/app/shop/shop.component.ts
Normal file
62
src/app/shop/shop.component.ts
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-shop',
|
||||||
|
templateUrl: './shop.component.html',
|
||||||
|
styleUrls: ['./shop.component.scss']
|
||||||
|
})
|
||||||
|
export class ShopComponent implements OnInit {
|
||||||
|
quantity = 11;
|
||||||
|
color = 'gold';
|
||||||
|
|
||||||
|
// TODO: #7. Create selectable controls with Angular Material
|
||||||
|
fillings = {
|
||||||
|
bokchoy: true,
|
||||||
|
tofu: true,
|
||||||
|
chicken: false,
|
||||||
|
impossible: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: #11. Announce changes with LiveAnnouncer
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit(): void { }
|
||||||
|
|
||||||
|
counter(i: number): Array<number> {
|
||||||
|
return new Array(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
public changeColor(color: string): void {
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
fauxPurchase(): void {
|
||||||
|
let flavor = '';
|
||||||
|
|
||||||
|
// TODO: #7. Create selectable controls with Angular Material
|
||||||
|
if (this.fillings.bokchoy) { flavor += 'Bok Choy '; }
|
||||||
|
if (this.fillings.tofu) { flavor += 'Tofu & Mushroom '; }
|
||||||
|
if (this.fillings.chicken) { flavor += 'Chicken & Ginger '; }
|
||||||
|
if (this.fillings.impossible) { flavor += 'Impossible Meat '; }
|
||||||
|
|
||||||
|
const fakePurchase = `Purchase ${this.quantity}${flavor} dumplings in the color ${this.color}!`;
|
||||||
|
console.log(fakePurchase);
|
||||||
|
|
||||||
|
// TODO: #11. Announce changes with LiveAnnouncer
|
||||||
|
}
|
||||||
|
}
|
||||||
0
src/assets/.gitkeep
Normal file
0
src/assets/.gitkeep
Normal file
18
src/environments/environment.prod.ts
Normal file
18
src/environments/environment.prod.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
export const environment = {
|
||||||
|
production: true
|
||||||
|
};
|
||||||
31
src/environments/environment.ts
Normal file
31
src/environments/environment.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
// This file can be replaced during build by using the `fileReplacements` array.
|
||||||
|
// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
|
||||||
|
// The list of file replacements can be found in `angular.json`.
|
||||||
|
|
||||||
|
export const environment = {
|
||||||
|
production: false
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For easier debugging in development mode, you can import the following file
|
||||||
|
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
|
||||||
|
*
|
||||||
|
* This import should be commented out in production mode because it will have a negative impact
|
||||||
|
* on performance if an error is thrown.
|
||||||
|
*/
|
||||||
|
// import 'zone.js/dist/zone-error'; // Included with Angular CLI.
|
||||||
BIN
src/favicon.ico
Normal file
BIN
src/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
17
src/index.html
Normal file
17
src/index.html
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>a11y in Angular</title>
|
||||||
|
<base href="/">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com">
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
|
||||||
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||||
|
<script src="https://maps.googleapis.com/maps/api/js?libraries=visualization"></script>
|
||||||
|
</head>
|
||||||
|
<body class="mat-typography">
|
||||||
|
<app-root role="main"></app-root>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
27
src/main.ts
Normal file
27
src/main.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { enableProdMode } from '@angular/core';
|
||||||
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||||
|
|
||||||
|
import { AppModule } from './app/app.module';
|
||||||
|
import { environment } from './environments/environment';
|
||||||
|
|
||||||
|
if (environment.production) {
|
||||||
|
enableProdMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
platformBrowserDynamic().bootstrapModule(AppModule)
|
||||||
|
.catch(err => console.error(err));
|
||||||
80
src/polyfills.ts
Normal file
80
src/polyfills.ts
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* This file includes polyfills needed by Angular and is loaded before the app.
|
||||||
|
* You can add your own extra polyfills to this file.
|
||||||
|
*
|
||||||
|
* This file is divided into 2 sections:
|
||||||
|
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
|
||||||
|
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main
|
||||||
|
* file.
|
||||||
|
*
|
||||||
|
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
|
||||||
|
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
|
||||||
|
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
|
||||||
|
*
|
||||||
|
* Learn more in https://angular.io/guide/browser-support
|
||||||
|
*/
|
||||||
|
|
||||||
|
/***************************************************************************************************
|
||||||
|
* BROWSER POLYFILLS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IE11 requires the following for NgClass support on SVG elements
|
||||||
|
*/
|
||||||
|
// import 'classlist.js'; // Run `npm install --save classlist.js`.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web Animations `@angular/platform-browser/animations`
|
||||||
|
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
|
||||||
|
* Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
|
||||||
|
*/
|
||||||
|
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default, zone.js will patch all possible macroTask and DomEvents
|
||||||
|
* user can disable parts of macroTask/DomEvents patch by setting following flags
|
||||||
|
* because those flags need to be set before `zone.js` being loaded, and webpack
|
||||||
|
* will put import in the top of bundle, so user need to create a separate file
|
||||||
|
* in this directory (for example: zone-flags.ts), and put the following flags
|
||||||
|
* into that file, and then add the following code before importing zone.js.
|
||||||
|
* import './zone-flags';
|
||||||
|
*
|
||||||
|
* The flags allowed in zone-flags.ts are listed here.
|
||||||
|
*
|
||||||
|
* The following flags will work for all browsers.
|
||||||
|
*
|
||||||
|
* (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
|
||||||
|
* (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
|
||||||
|
* (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
|
||||||
|
*
|
||||||
|
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
|
||||||
|
* with the following flag, it will bypass `zone.js` patch for IE/Edge
|
||||||
|
*
|
||||||
|
* (window as any).__Zone_enable_cross_context_check = true;
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/***************************************************************************************************
|
||||||
|
* Zone JS is required by default for Angular itself.
|
||||||
|
*/
|
||||||
|
import 'zone.js/dist/zone'; // Included with Angular CLI.
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************************************
|
||||||
|
* APPLICATION IMPORTS
|
||||||
|
*/
|
||||||
86
src/styles.scss
Normal file
86
src/styles.scss
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
@use '~@angular/material' as mat;
|
||||||
|
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Vollkorn:ital,wght@1,700&Lato:wght@400;700;900&display=swap');
|
||||||
|
$vollkorn-font-family: 'Vollkorn', serif;
|
||||||
|
$lato-font-family: 'Lato', sans-serif;
|
||||||
|
|
||||||
|
// TODO: #5. Ensure adequate color contrast
|
||||||
|
$light-primary: mat.define-palette(mat.$pink-palette, $default: A100, $lighter: 100, $text: 500);
|
||||||
|
$light-accent: mat.define-palette(mat.$red-palette, $default: A400, $lighter: 100);
|
||||||
|
|
||||||
|
$dark-primary: mat.define-palette(mat.$light-green-palette, $default: A100, $lighter: 50, $text: 900);
|
||||||
|
$dark-accent: mat.define-palette(mat.$indigo-palette, $default: 600, $lighter: 500);
|
||||||
|
|
||||||
|
$custom-typography: mat.define-typography-config(
|
||||||
|
$font-family: $lato-font-family,
|
||||||
|
$display-4: mat.define-typography-level(112px, 112px, 700, $letter-spacing: -0.05em, $font-family: $vollkorn-font-family),
|
||||||
|
$display-3: mat.define-typography-level(56px, 56px, 700, $letter-spacing: -0.02em, $font-family: $vollkorn-font-family),
|
||||||
|
$display-2: mat.define-typography-level(45px, 48px, 700, $letter-spacing: -0.005em, $font-family: $vollkorn-font-family),
|
||||||
|
$display-1: mat.define-typography-level(34px, 40px, 700, $font-family: $vollkorn-font-family),
|
||||||
|
$headline: mat.define-typography-level(18px, 32px, 700, $font-family: $vollkorn-font-family),
|
||||||
|
$title: mat.define-typography-level(50px, 32px, 700, $font-family: $vollkorn-font-family),
|
||||||
|
$subheading-2: mat.define-typography-level(18px, 28px, 700, $letter-spacing: .2em, $font-family: $lato-font-family),
|
||||||
|
$subheading-1: mat.define-typography-level(18px, 24px, 700, $font-family: $lato-font-family),
|
||||||
|
$body-2: mat.define-typography-level(18px, 24px, 700, $font-family: $lato-font-family),
|
||||||
|
$body-1: mat.define-typography-level(16px, 20px, 700, $font-family: $lato-font-family),
|
||||||
|
$caption: mat.define-typography-level(16px, 20px, 700, $font-family: $lato-font-family),
|
||||||
|
$button: mat.define-typography-level(18px, 28px, 700, $font-family: $lato-font-family),
|
||||||
|
$input: mat.define-typography-level(inherit, 1.125, 700, $font-family: $lato-font-family)
|
||||||
|
);
|
||||||
|
|
||||||
|
$light-theme: mat.define-light-theme((
|
||||||
|
color: (
|
||||||
|
primary: $light-primary,
|
||||||
|
accent: $light-accent,
|
||||||
|
),
|
||||||
|
typography: $custom-typography
|
||||||
|
));
|
||||||
|
|
||||||
|
$dark-theme: mat.define-dark-theme((
|
||||||
|
color: (
|
||||||
|
primary: $dark-primary,
|
||||||
|
accent: $dark-accent
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
|
@include mat.core();
|
||||||
|
@include mat.core-theme($light-theme);
|
||||||
|
@include mat.all-component-themes($light-theme);
|
||||||
|
@include mat.all-component-typographies($light-theme);
|
||||||
|
|
||||||
|
.dark-theme {
|
||||||
|
@include mat.core-color($dark-theme);
|
||||||
|
@include mat.all-component-themes($dark-theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Global styles */
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
background-color: mat.get-color-from-palette($light-accent, default);
|
||||||
|
color: mat.get-contrast-color-from-palette($light-accent, default);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark-theme body {
|
||||||
|
background-color: mat.get-color-from-palette($dark-accent, default);
|
||||||
|
color: mat.get-contrast-color-from-palette($dark-accent, default);
|
||||||
|
}
|
||||||
40
src/test.ts
Normal file
40
src/test.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||||
|
|
||||||
|
import 'zone.js/dist/zone-testing';
|
||||||
|
import { getTestBed } from '@angular/core/testing';
|
||||||
|
import {
|
||||||
|
BrowserDynamicTestingModule,
|
||||||
|
platformBrowserDynamicTesting
|
||||||
|
} from '@angular/platform-browser-dynamic/testing';
|
||||||
|
|
||||||
|
declare const require: {
|
||||||
|
context(path: string, deep?: boolean, filter?: RegExp): {
|
||||||
|
keys(): string[];
|
||||||
|
<T>(id: string): T;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// First, initialize the Angular testing environment.
|
||||||
|
getTestBed().initTestEnvironment(
|
||||||
|
BrowserDynamicTestingModule,
|
||||||
|
platformBrowserDynamicTesting()
|
||||||
|
);
|
||||||
|
// Then we find all the tests.
|
||||||
|
const context = require.context('./', true, /\.spec\.ts$/);
|
||||||
|
// And load the modules.
|
||||||
|
context.keys().map(context);
|
||||||
15
tsconfig.app.json
Normal file
15
tsconfig.app.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "./out-tsc/app",
|
||||||
|
"types": []
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src/main.ts",
|
||||||
|
"src/polyfills.ts"
|
||||||
|
],
|
||||||
|
"include": [
|
||||||
|
"src/**/*.d.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
30
tsconfig.json
Normal file
30
tsconfig.json
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||||
|
{
|
||||||
|
"compileOnSave": false,
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": "./",
|
||||||
|
"outDir": "./dist/out-tsc",
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"strict": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"declaration": false,
|
||||||
|
"downlevelIteration": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"importHelpers": true,
|
||||||
|
"target": "es2015",
|
||||||
|
"module": "es2020",
|
||||||
|
"lib": [
|
||||||
|
"es2018",
|
||||||
|
"dom"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"angularCompilerOptions": {
|
||||||
|
"enableI18nLegacyMessageIdFormat": false,
|
||||||
|
"strictInjectionParameters": true,
|
||||||
|
"strictInputAccessModifiers": true,
|
||||||
|
"strictTemplates": true
|
||||||
|
}
|
||||||
|
}
|
||||||
18
tsconfig.spec.json
Normal file
18
tsconfig.spec.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "./out-tsc/spec",
|
||||||
|
"types": [
|
||||||
|
"jasmine"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src/test.ts",
|
||||||
|
"src/polyfills.ts"
|
||||||
|
],
|
||||||
|
"include": [
|
||||||
|
"src/**/*.spec.ts",
|
||||||
|
"src/**/*.d.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user