mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
Compare commits
120 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e3f09ce845 | |||
| cfbb1faa6f | |||
| e2bb954a7a | |||
| 5795c980b5 | |||
| e99c4e230f | |||
| d36890c854 | |||
| 5adb47ff35 | |||
| 7e0ff8cbb6 | |||
| bf85f04baf | |||
| fffefd12e5 | |||
| 9ae21ee118 | |||
| 95446fb15c | |||
| ba6d8d44b1 | |||
| 3b0c51e045 | |||
| 80c21bf6b0 | |||
| c0d1e34d53 | |||
| 6973a9919b | |||
| 415ad8df13 | |||
| 9aa3e9f0fc | |||
| 67333a98b9 | |||
| 24600ff77d | |||
| 74cb759c2a | |||
| a4e396dbcf | |||
| 1e064074ac | |||
| 621c32d22a | |||
| 305d41c0b0 | |||
| 36a3a6af7f | |||
| 52da337ca5 | |||
| ceafef1a6a | |||
| bc7be8f1ab | |||
| cd1b76478f | |||
| 57d46d4293 | |||
| 13857519e4 | |||
| 35c3d80f1d | |||
| 900bc87d20 | |||
| 86a6be753d | |||
| 22f734f102 | |||
| 63f6273346 | |||
| 98defb6e68 | |||
| 345eccad8e | |||
| 49c108e33c | |||
| adcba1b9b2 | |||
| b282a94c31 | |||
| d79e62292c | |||
| 8505865587 | |||
| d05f157209 | |||
| 9bab583c58 | |||
| ea3ec5361e | |||
| afce2987d1 | |||
| 4e78e2196a | |||
| 5766c2d52f | |||
| 7e6595b59b | |||
| 58ee0133e4 | |||
| b8d6e15447 | |||
| 7a68915d18 | |||
| 1e4c39ada8 | |||
| b12e798685 | |||
| b0613b7329 | |||
| 9738878fbf | |||
| 81c496d0a4 | |||
| 9675260a56 | |||
| 8216de27ed | |||
| 7a45153266 | |||
| c3ed990f47 | |||
| 07e071cec0 | |||
| 3c1d9860d0 | |||
| ba16665073 | |||
| d11cb25f4d | |||
| b01153cf84 | |||
| 698efeed63 | |||
| eda6c6d5c9 | |||
| 506b6a2ab6 | |||
| 3989a0a240 | |||
| 6345f89825 | |||
| 4d05f533a8 | |||
| 192de59ddc | |||
| 7c1453614b | |||
| 11cc4c9dcf | |||
| 737bc7a3e5 | |||
| b1d589712c | |||
| 58f8ba0a8c | |||
| 6ac05c05e9 | |||
| 7c38a4a037 | |||
| 0b1f1930b9 | |||
| 4877f687b5 | |||
| 5c547675b1 | |||
| 1fbbb1e34d | |||
| 4cc15fe78e | |||
| 07a3d7a16b | |||
| 21994ee985 | |||
| f25a1b9597 | |||
| fa3f310745 | |||
| e66b89a4e4 | |||
| 95d8f58393 | |||
| 2fc618471a | |||
| 08252b2c5e | |||
| 5f9053405a | |||
| f1d2afa496 | |||
| 6d5e6cf1cf | |||
| 746792b838 | |||
| da3dc29477 | |||
| caafac2248 | |||
| ff93a6723e | |||
| 46d43267e3 | |||
| 4c5f18dfda | |||
| 5fcf2f9a5f | |||
| 4d1b3177d8 | |||
| f261c1c66b | |||
| 552009ec07 | |||
| 9d396f837c | |||
| daa9b7e608 | |||
| 47fe75e19d | |||
| 44298dfb65 | |||
| 0463578944 | |||
| 584fd4513c | |||
| 5b0147512f | |||
| 7a6d1e2bf2 | |||
| cabe8bec40 | |||
| e11e6cf8c4 | |||
| f44a8e2cf6 |
+2
-13
@@ -479,6 +479,7 @@ groups:
|
||||
users:
|
||||
- alxhub
|
||||
- IgorMinar
|
||||
- petebacondarwin
|
||||
|
||||
|
||||
# =========================================================
|
||||
@@ -1166,19 +1167,7 @@ groups:
|
||||
'.vscode/**',
|
||||
'.yarn/**',
|
||||
'dev-infra/**',
|
||||
'docs/BAZEL.md',
|
||||
'docs/CARETAKER.md',
|
||||
'docs/CODING_STANDARDS.md',
|
||||
'docs/COMMITTER.md',
|
||||
'docs/DEBUG.md',
|
||||
'docs/DEBUG_COMPONENTS_REPO_IVY.md',
|
||||
'docs/DEVELOPER.md',
|
||||
'docs/FIXUP_COMMITS.md',
|
||||
'docs/GITHUB_PROCESS.md',
|
||||
'docs/PR_REVIEW.md',
|
||||
'docs/SAVED_REPLIES.md',
|
||||
'docs/TOOLS.md',
|
||||
'docs/TRIAGE_AND_LABELS.md',
|
||||
'docs/*.md',
|
||||
'docs/images/**',
|
||||
'goldens/*',
|
||||
'modules/*',
|
||||
|
||||
+63
-2
@@ -1,14 +1,75 @@
|
||||
<a name="11.2.0"></a>
|
||||
# 11.2.0 (2021-02-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **animations:** properly track listeners for a removed element ([#40712](https://github.com/angular/angular/issues/40712)) ([74cb759](https://github.com/angular/angular/commit/74cb759))
|
||||
* **common:** date is not correctly formatted when year is between 0 and 99 ([#40448](https://github.com/angular/angular/issues/40448)) ([bf85f04](https://github.com/angular/angular/commit/bf85f04)), closes [#40377](https://github.com/angular/angular/issues/40377)
|
||||
* **compiler:** include parenthesis in expression source spans ([#40740](https://github.com/angular/angular/issues/40740)) ([e99c4e2](https://github.com/angular/angular/commit/e99c4e2)), closes [#40721](https://github.com/angular/angular/issues/40721)
|
||||
* **compiler:** throw error for duplicate template references ([#40538](https://github.com/angular/angular/issues/40538)) ([7e0ff8c](https://github.com/angular/angular/commit/7e0ff8c)), closes [#40536](https://github.com/angular/angular/issues/40536)
|
||||
* **compiler-cli:** don't crash when we can't resolve a resource ([#40660](https://github.com/angular/angular/issues/40660)) ([95446fb](https://github.com/angular/angular/commit/95446fb)), closes [angular/vscode-ng-language-service#1079](https://github.com/angular/vscode-ng-language-service/issues/1079)
|
||||
* **core:** properly move embedded views of dynamic component's projectable nodes ([#37167](https://github.com/angular/angular/issues/37167)) ([9ae21ee](https://github.com/angular/angular/commit/9ae21ee)), closes [#37120](https://github.com/angular/angular/issues/37120)
|
||||
* **localize:** improve invalid syntax in extraction error message ([#40724](https://github.com/angular/angular/issues/40724)) ([24600ff](https://github.com/angular/angular/commit/24600ff))
|
||||
* **localize:** support downleveled inlined helper localize calls ([#40754](https://github.com/angular/angular/issues/40754)) ([415ad8d](https://github.com/angular/angular/commit/415ad8d)), closes [#40702](https://github.com/angular/angular/issues/40702)
|
||||
* **router:** stop emitting to event observable on destroy ([#40638](https://github.com/angular/angular/issues/40638)) ([737bc7a](https://github.com/angular/angular/commit/737bc7a)), closes [#40502](https://github.com/angular/angular/issues/40502)
|
||||
|
||||
|
||||
|
||||
<a name="11.2.0-rc.0"></a>
|
||||
# 11.2.0-rc.0 (2021-02-03)
|
||||
|
||||
|
||||
|
||||
<a name="11.2.0-next.1"></a>
|
||||
# 11.2.0-next.1 (2021-02-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **common:** parse `YYYY-MM` strings as UTC dates ([#40620](https://github.com/angular/angular/issues/40620)) ([4c5f18d](https://github.com/angular/angular/commit/4c5f18d)), closes [#33944](https://github.com/angular/angular/issues/33944)
|
||||
* **common:** parse `YYYY` strings as UTC dates ([#40629](https://github.com/angular/angular/issues/40629)) ([46d4326](https://github.com/angular/angular/commit/46d4326)), closes [#33944](https://github.com/angular/angular/issues/33944) [#40620](https://github.com/angular/angular/issues/40620)
|
||||
* **compiler:** Don't set expression text to synthetic `$implicit` when empty ([#40583](https://github.com/angular/angular/issues/40583)) ([9d396f8](https://github.com/angular/angular/commit/9d396f8))
|
||||
* **compiler:** exclude trailing whitespace from element source spans ([#40513](https://github.com/angular/angular/issues/40513)) ([7a6d1e2](https://github.com/angular/angular/commit/7a6d1e2)), closes [#39148](https://github.com/angular/angular/issues/39148)
|
||||
* **compiler-cli:** preserve user line endings in diagnostic template parse ([#40597](https://github.com/angular/angular/issues/40597)) ([caafac2](https://github.com/angular/angular/commit/caafac2))
|
||||
* **core:** ensure the type `T` of `EventEmitter<T>` can be inferred ([#40644](https://github.com/angular/angular/issues/40644)) ([5c54767](https://github.com/angular/angular/commit/5c54767)), closes [#40637](https://github.com/angular/angular/issues/40637)
|
||||
* **core:** remove duplicated EMPTY_ARRAY constant ([#40587](https://github.com/angular/angular/issues/40587)) ([cabe8be](https://github.com/angular/angular/commit/cabe8be))
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **language-service:** update NgCompiler via resource-only path when able ([#40585](https://github.com/angular/angular/issues/40585)) ([07a3d7a](https://github.com/angular/angular/commit/07a3d7a))
|
||||
|
||||
|
||||
|
||||
<a name="11.2.0-next.0"></a>
|
||||
# 11.2.0-next.0 (2021-01-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **core:** make DefaultIterableDiffer keep the order of duplicates ([#23941](https://github.com/angular/angular/issues/23941)) ([a826926](https://github.com/angular/angular/commit/a826926)), closes [#23815](https://github.com/angular/angular/issues/23815)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **common:** implement `appendAll()` method on `HttpParams` ([#20930](https://github.com/angular/angular/issues/20930)) ([575a2d1](https://github.com/angular/angular/commit/575a2d1)), closes [#20798](https://github.com/angular/angular/issues/20798)
|
||||
* **language-service:** Add diagnostics to suggest turning on strict mode ([#40423](https://github.com/angular/angular/issues/40423)) ([ecae75f](https://github.com/angular/angular/commit/ecae75f))
|
||||
* **language-service:** Implement `getRenameInfo` ([#40439](https://github.com/angular/angular/issues/40439)) ([4e8198d](https://github.com/angular/angular/commit/4e8198d))
|
||||
* **language-service:** initial implementation for `findRenameLocations` ([#40140](https://github.com/angular/angular/issues/40140)) ([9a5ac47](https://github.com/angular/angular/commit/9a5ac47))
|
||||
* **language-service:** view template typecheck block ([#39974](https://github.com/angular/angular/issues/39974)) ([d482f5c](https://github.com/angular/angular/commit/d482f5c))
|
||||
|
||||
|
||||
|
||||
<a name="11.1.1"></a>
|
||||
## 11.1.1 (2021-01-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **compiler:** support multiple `:host-context()` selectors ([#40494](https://github.com/angular/angular/issues/40494)) ([72c0ba6](https://github.com/angular/angular/commit/72c0ba6)), closes [#19199](https://github.com/angular/angular/issues/19199)
|
||||
* **compiler-cli:** handle pseudo cycles in inline source-maps ([#40435](https://github.com/angular/angular/issues/40435)) ([566206b](https://github.com/angular/angular/commit/566206b)), closes [#40408](https://github.com/angular/angular/issues/40408)
|
||||
* **compiler-cli:** use `Map` rather than `object` for map of partial linkers ([#40563](https://github.com/angular/angular/issues/40563)) ([33e0f2b](https://github.com/angular/angular/commit/33e0f2b))
|
||||
* **core:** fix possible XSS attack in development through SSR ([#40525](https://github.com/angular/angular/issues/40525)) ([97ec6e4](https://github.com/angular/angular/commit/97ec6e4))
|
||||
* **core:** fix possible XSS attack in development through SSR ([#40525](https://github.com/angular/angular/issues/40525)) ([3bf6a99](https://github.com/angular/angular/commit/3bf6a99))
|
||||
* **core:** improve injector debug information in `ngDevMode` ([#40476](https://github.com/angular/angular/issues/40476)) ([4bb38c9](https://github.com/angular/angular/commit/4bb38c9))
|
||||
* **forms:** allow `patchValue()` method of `FormGroup` and `FormArray` classes to skip `null` values ([#40534](https://github.com/angular/angular/issues/40534)) ([2fab148](https://github.com/angular/angular/commit/2fab148)), closes [#36672](https://github.com/angular/angular/issues/36672) [#21021](https://github.com/angular/angular/issues/21021)
|
||||
* **forms:** properly cleanup in cases when FormControlName has no CVA ([#40526](https://github.com/angular/angular/issues/40526)) ([72fc6aa](https://github.com/angular/angular/commit/72fc6aa)), closes [#39235](https://github.com/angular/angular/issues/39235) [#40521](https://github.com/angular/angular/issues/40521)
|
||||
|
||||
@@ -8,8 +8,8 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
# Fetch rules_nodejs so we can install our npm dependencies
|
||||
http_archive(
|
||||
name = "build_bazel_rules_nodejs",
|
||||
sha256 = "9d93d4e1340c43dbf6b2fd66b683d89630a6310bf8be3bf40ec96685dcacc26c",
|
||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/2.3.3/rules_nodejs-2.3.3.tar.gz"],
|
||||
sha256 = "dd4dc46066e2ce034cba0c81aa3e862b27e8e8d95871f567359f7a534cccb666",
|
||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/3.1.0/rules_nodejs-3.1.0.tar.gz"],
|
||||
)
|
||||
|
||||
# Check the rules_nodejs version and download npm dependencies
|
||||
@@ -31,6 +31,9 @@ yarn_install(
|
||||
name = "npm",
|
||||
manual_build_file_contents = npm_package_archives(),
|
||||
package_json = "//:package.json",
|
||||
# TODO(josephperrott): Correct usage of transitive dependencies to reenable strict_visibility
|
||||
# See: https://github.com/bazelbuild/rules_nodejs/wiki#strict_visibility-on-yarn_install-and-npm_install-now-defaults-true-2199
|
||||
strict_visibility = False,
|
||||
yarn_lock = "//:yarn.lock",
|
||||
)
|
||||
|
||||
@@ -44,11 +47,6 @@ load("@npm//@bazel/protractor:package.bzl", "npm_bazel_protractor_dependencies")
|
||||
|
||||
npm_bazel_protractor_dependencies()
|
||||
|
||||
# Load karma dependencies
|
||||
load("@npm//@bazel/karma:package.bzl", "npm_bazel_karma_dependencies")
|
||||
|
||||
npm_bazel_karma_dependencies()
|
||||
|
||||
# Setup the rules_webtesting toolchain
|
||||
load("@io_bazel_rules_webtesting//web:repositories.bzl", "web_test_repositories")
|
||||
|
||||
@@ -59,7 +57,7 @@ load("//dev-infra/browsers:browser_repositories.bzl", "browser_repositories")
|
||||
browser_repositories()
|
||||
|
||||
# Setup the rules_sass toolchain
|
||||
load("@io_bazel_rules_sass//sass:sass_repositories.bzl", "sass_repositories")
|
||||
load("@io_bazel_rules_sass//:defs.bzl", "sass_repositories")
|
||||
|
||||
sass_repositories()
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
@name Pipe Not Found
|
||||
@category runtime
|
||||
@videoUrl https://www.youtube.com/embed/maI2u6Sxk9M
|
||||
@shortDescription Pipe not found!
|
||||
|
||||
@description
|
||||
Angular can't find a pipe with this name.
|
||||
The pipe referenced in the template has not been named or declared properly.
|
||||
A [pipe](guide/pipes) must be either declared or imported in the `NgModule` where it is used, and the name used in a template must match the name defined in the pipe decorator.
|
||||
|
||||
@debugging
|
||||
Use the pipe name to trace the templates or modules where this pipe is declared and used.
|
||||
|
||||
To resolve this error, ensure that:
|
||||
- A local custom pipe is uniquely named in the pipe's decorator, and declared in the `NgModule`, or
|
||||
- A pipe from another `NgModule` is added to the imports of the `NgModule` where it is used.
|
||||
|
||||
If you recently added an import or declaration, you may need to restart your server to see these changes.
|
||||
@@ -0,0 +1,13 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-not-great',
|
||||
})
|
||||
// #docregion not-great
|
||||
export class NotGreatComponent {
|
||||
|
||||
buggyFunction() {
|
||||
// things could be better here...
|
||||
}
|
||||
}
|
||||
// #enddocregion not-great
|
||||
@@ -19,7 +19,7 @@ export class HeroesComponent implements OnInit {
|
||||
heroes = HEROES;
|
||||
// #enddocregion component
|
||||
// #docregion on-select
|
||||
selectedHero: Hero;
|
||||
selectedHero?: Hero;
|
||||
// #enddocregion on-select
|
||||
|
||||
constructor() { }
|
||||
@@ -35,4 +35,3 @@ export class HeroesComponent implements OnInit {
|
||||
// #docregion component
|
||||
}
|
||||
// #enddocregion component
|
||||
|
||||
|
||||
@@ -26,10 +26,10 @@ export class HeroService {
|
||||
// #docregion getHeroes, getHeroes-1
|
||||
getHeroes(): Observable<Hero[]> {
|
||||
// #enddocregion getHeroes-1
|
||||
// TODO: send the message _after_ fetching the heroes
|
||||
const heroes = of(HEROES);
|
||||
this.messageService.add('HeroService: fetched heroes');
|
||||
// #docregion getHeroes-1
|
||||
return of(HEROES);
|
||||
return heroes;
|
||||
}
|
||||
// #enddocregion getHeroes, getHeroes-1
|
||||
}
|
||||
|
||||
@@ -15,8 +15,6 @@ The following are metadata errors you may encounter, with explanations and sugge
|
||||
[Tagged template expressions are not supported](#tagged-template-expressions-not-supported)<br>
|
||||
[Symbol reference expected](#symbol-reference-expected)<br>
|
||||
|
||||
<hr>
|
||||
|
||||
{@a expression-form-not-supported}
|
||||
## Expression form not supported
|
||||
|
||||
@@ -47,8 +45,6 @@ Avoid this error by sticking to the compiler's [restricted expression syntax](gu
|
||||
when writing Angular metadata
|
||||
and be wary of new or unusual TypeScript features.
|
||||
|
||||
<hr>
|
||||
|
||||
{@a reference-to-a-local-symbol}
|
||||
## Reference to a local (non-exported) symbol
|
||||
|
||||
@@ -128,8 +124,6 @@ The compiler needs the value of the `template` property _right now_ to generate
|
||||
The variable reference alone is insufficient.
|
||||
Prefixing the declaration with `export` merely produces a new error, "[`Only initialized variables and constants can be referenced`](#only-initialized-variables)".
|
||||
|
||||
<hr>
|
||||
|
||||
{@a only-initialized-variables}
|
||||
## Only initialized variables and constants
|
||||
|
||||
@@ -187,8 +181,6 @@ export let someTemplate = '<h1>Greetings from Angular</h1>';
|
||||
export class MyComponent {}
|
||||
```
|
||||
|
||||
<hr>
|
||||
|
||||
{@a reference-to-a-non-exported-class}
|
||||
## Reference to a non-exported class
|
||||
|
||||
@@ -228,7 +220,6 @@ export abstract class MyStrategy { }
|
||||
]
|
||||
...
|
||||
```
|
||||
<hr>
|
||||
|
||||
{@a reference-to-a-non-exported-function}
|
||||
## Reference to a non-exported function
|
||||
@@ -266,7 +257,6 @@ export function myStrategy() { ... }
|
||||
]
|
||||
...
|
||||
```
|
||||
<hr>
|
||||
|
||||
{@a function-calls-not-supported}
|
||||
## Function calls are not supported
|
||||
@@ -322,8 +312,6 @@ export function someValueFactory() {
|
||||
...
|
||||
```
|
||||
|
||||
<hr>
|
||||
|
||||
{@a destructured-variable-not-supported}
|
||||
## Destructured variable or constant not supported
|
||||
|
||||
@@ -364,8 +352,6 @@ import { configuration } from './configuration';
|
||||
...
|
||||
```
|
||||
|
||||
<hr>
|
||||
|
||||
{@a could-not-resolve-type}
|
||||
## Could not resolve type
|
||||
|
||||
@@ -437,7 +423,6 @@ export class MyComponent {
|
||||
constructor (@Inject(DOCUMENT) private doc: Document) { ... }
|
||||
}
|
||||
```
|
||||
<hr>
|
||||
|
||||
{@a name-expected}
|
||||
## Name expected
|
||||
@@ -462,8 +447,6 @@ Change the name of the property to something non-numeric.
|
||||
provider: [{ provide: Foo, useValue: { '0': 'test' } }]
|
||||
```
|
||||
|
||||
<hr>
|
||||
|
||||
{@a unsupported-enum-member-name}
|
||||
## Unsupported enum member name
|
||||
|
||||
@@ -494,8 +477,6 @@ enum Colors {
|
||||
|
||||
Avoid referring to enums with complicated initializers or computed properties.
|
||||
|
||||
<hr>
|
||||
|
||||
{@a tagged-template-expressions-not-supported}
|
||||
## Tagged template expressions are not supported
|
||||
|
||||
@@ -520,8 +501,6 @@ is a _tag function_ native to JavaScript ES2015.
|
||||
|
||||
The AOT compiler does not support tagged template expressions; avoid them in metadata expressions.
|
||||
|
||||
<hr>
|
||||
|
||||
{@a symbol-reference-expected}
|
||||
## Symbol reference expected
|
||||
|
||||
|
||||
@@ -114,13 +114,12 @@ The router interprets a link URL according to your app's view navigation rules a
|
||||
|
||||
To define navigation rules, you associate *navigation paths* with your components. A path uses a URL-like syntax that integrates your program data, in much the same way that template syntax integrates your views with your program data. You can then apply program logic to choose which views to show or to hide, in response to user input and your own access rules.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
<div class="alert is-helpful">
|
||||
|
||||
For a more detailed discussion, see [Routing and navigation](guide/router).
|
||||
For a more detailed discussion, see [Routing and navigation](guide/router).
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
## What's next
|
||||
|
||||
|
||||
@@ -74,10 +74,8 @@ For more information on how to bind to the `colSpan` property, see the [`colspan
|
||||
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a class-binding}
|
||||
|
||||
## Binding to the `class` attribute
|
||||
|
||||
You can use class binding to add and remove CSS class names from an element's `class` attribute.
|
||||
@@ -159,10 +157,8 @@ The following table summarizes class binding syntax.
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a style-binding}
|
||||
|
||||
## Binding to the style attribute
|
||||
|
||||
You can use style binding to set styles dynamically.
|
||||
@@ -260,10 +256,7 @@ However, using the above style binding syntax without `NgStyle` is preferred bec
|
||||
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a styling-precedence}
|
||||
|
||||
## Styling Precedence
|
||||
|
||||
A single HTML element can have its CSS class list and style values bound to multiple sources (for example, host bindings from multiple directives).
|
||||
@@ -326,8 +319,6 @@ In that case, if `dirWithHostBinding` sets its binding to `undefined`, the `widt
|
||||
However, if `dirWithHostBinding` sets its binding to `null`, the `width` property will be removed entirely.
|
||||
|
||||
|
||||
<hr/>
|
||||
|
||||
## Injecting attribute values
|
||||
|
||||
There are cases where you need to differentiate the behavior of a [Component](api/core/Component) or [Directive](api/core/Directive) based on a static value set on the host element as an HTML attribute. For example, you might have a directive that needs to know the `type` of a `<button>` or `<input>` element.
|
||||
|
||||
@@ -311,10 +311,7 @@ Here's how the harness should work when you're done coding.
|
||||
<img src="generated/images/guide/attribute-directives/highlight-directive-final-anim.gif" alt="Final Highlight">
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
{@a ngNonBindable}
|
||||
|
||||
## `ngNonBindable`
|
||||
|
||||
With the built-in template primitive `ngNonBindable`, Angular won't
|
||||
|
||||
@@ -98,7 +98,7 @@ export class AppComponent {
|
||||
|
||||
## Configure target-specific file replacements
|
||||
|
||||
The main CLI configuration file, `angular.json`, contains a `fileReplacements` section in the configuration for each build target, which allows you to replace any file with a target-specific version of that file.
|
||||
The main CLI configuration file, `angular.json`, contains a `fileReplacements` section in the configuration for each build target, which allows you to replace any file in the TypeScript program with a target-specific version of that file.
|
||||
This is useful for including target-specific code or variables in a build that targets a specific environment, such as production or staging.
|
||||
|
||||
By default no files are replaced.
|
||||
|
||||
@@ -10,10 +10,7 @@ See the <live-example></live-example> for a working example containing the code
|
||||
|
||||
For more detail, including how to build your own custom directives, see [Attribute Directives](guide/attribute-directives) and [Structural Directives](guide/structural-directives).
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a attribute-directives}
|
||||
|
||||
## Built-in attribute directives
|
||||
|
||||
Attribute directives listen to and modify the behavior of
|
||||
@@ -28,10 +25,7 @@ The most common attribute directives are as follows:
|
||||
* [`NgStyle`](guide/built-in-directives#ngStyle)—adds and removes a set of HTML styles.
|
||||
* [`NgModel`](guide/built-in-directives#ngModel)—adds two-way data binding to an HTML form element.
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a ngClass}
|
||||
|
||||
## `NgClass`
|
||||
|
||||
Add or remove several CSS classes simultaneously with `ngClass`.
|
||||
@@ -62,10 +56,7 @@ both initially and when the dependent properties change.
|
||||
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a ngStyle}
|
||||
|
||||
## `NgStyle`
|
||||
|
||||
Use `NgStyle` to set many inline styles simultaneously and dynamically, based on the state of the component.
|
||||
@@ -95,10 +86,7 @@ Remember to call `setCurrentStyles()`, both initially and when the dependent pro
|
||||
</div>
|
||||
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a ngModel}
|
||||
|
||||
## `[(ngModel)]`: Two-way binding
|
||||
|
||||
The `NgModel` directive allows you to display a data property and
|
||||
@@ -167,10 +155,7 @@ Here are all variations in action, including the uppercase version:
|
||||
<img src='generated/images/guide/built-in-directives/ng-model-anim.gif' alt="NgModel variations">
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a structural-directives}
|
||||
|
||||
## Built-in _structural_ directives
|
||||
|
||||
Structural directives are responsible for HTML layout.
|
||||
@@ -198,10 +183,7 @@ to group elements when there is no suitable host element for the directive.
|
||||
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a ngIf}
|
||||
|
||||
## NgIf
|
||||
|
||||
You can add or remove an element from the DOM by applying an `NgIf` directive to
|
||||
@@ -265,8 +247,6 @@ The `nullCustomer` will not be displayed as long as it is `null`.
|
||||
|
||||
<code-example path="built-in-directives/src/app/app.component.html" region="NgIf-2b" header="src/app/app.component.html"></code-example>
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a ngFor}
|
||||
## `NgFor`
|
||||
|
||||
@@ -383,8 +363,6 @@ they do not have special access to any private APIs that other directives can't
|
||||
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a ngSwitch}
|
||||
## The `NgSwitch` directives
|
||||
|
||||
|
||||
@@ -90,11 +90,8 @@ The revised second version does depend on `Logger` service.
|
||||
|
||||
</code-tabs>
|
||||
|
||||
|
||||
In this example, the `getHeroes()` method uses the `Logger` service by logging a message when fetching heroes.
|
||||
|
||||
<hr />
|
||||
|
||||
## What's next
|
||||
|
||||
* [Dependency providers](guide/dependency-injection-providers)
|
||||
|
||||
@@ -156,10 +156,7 @@ Check out [angular-cli-ghpages](https://github.com/angular-buch/angular-cli-ghpa
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
{@a server-configuration}
|
||||
|
||||
## Server configuration
|
||||
|
||||
This section covers changes you may have to make to the server or to files deployed on the server.
|
||||
@@ -299,10 +296,7 @@ The server must be configured to accept the application's requests.
|
||||
Read about how to enable CORS for specific servers at
|
||||
<a href="https://enable-cors.org/server.html" title="Enabling CORS server">enable-cors.org</a>.
|
||||
|
||||
<hr>
|
||||
|
||||
{@a optimize}
|
||||
|
||||
## Production optimizations
|
||||
|
||||
The `--prod` _meta-flag_ engages the following build optimization features.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -52,8 +52,6 @@ When your custom element is placed on a page, the browser creates an instance of
|
||||
<img src="generated/images/guide/elements/customElement1.png" alt="Custom element in browser" class="left">
|
||||
</div>
|
||||
|
||||
<hr class="clear">
|
||||
|
||||
## Transforming components to custom elements
|
||||
|
||||
Angular provides the `createCustomElement()` function for converting an Angular component,
|
||||
@@ -192,7 +190,7 @@ class MyDialog {
|
||||
}
|
||||
```
|
||||
|
||||
The most straight forward way to get accurate typings is to cast the return value of the relevant DOM methods to the correct type. For that, you can use the `NgElement` and `WithProperties` types (both exported from `@angular/elements`):
|
||||
The most straightforward way to get accurate typings is to cast the return value of the relevant DOM methods to the correct type. For that, you can use the `NgElement` and `WithProperties` types (both exported from `@angular/elements`):
|
||||
|
||||
```ts
|
||||
const aDialog = document.createElement('my-dialog') as NgElement & WithProperties<{content: string}>;
|
||||
|
||||
@@ -107,8 +107,6 @@ the tree shaker will throw it away. So, it's best to add only the components tha
|
||||
as trim as possible.
|
||||
|
||||
|
||||
<hr />
|
||||
|
||||
## More on Angular modules
|
||||
|
||||
You may also be interested in the following:
|
||||
|
||||
@@ -59,8 +59,6 @@ In the following example, Angular checks to see if `myClick` is an event on the
|
||||
|
||||
If the target event name, `myClick` fails to match an element event or an output property of `ClickDirective`, Angular reports an "unknown directive" error.
|
||||
|
||||
<hr />
|
||||
|
||||
## What's next
|
||||
|
||||
For more information on how event binding works, see [How event binding works](guide/event-binding-concepts).
|
||||
|
||||
@@ -106,8 +106,6 @@ Now, in addition to the title that renders by default, the `CustomerDashboardCom
|
||||
<img src="generated/images/guide/feature-modules/feature-module.png" alt="feature module component">
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
## More on NgModules
|
||||
|
||||
You may also be interested in the following:
|
||||
|
||||
@@ -115,8 +115,6 @@ Angular returns an error telling you to use `CommonModule` instead.
|
||||
<img src="generated/images/guide/frequent-ngmodules/browser-module-error.gif" width=750 alt="BrowserModule error">
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
|
||||
## More on NgModules
|
||||
|
||||
|
||||
@@ -1183,8 +1183,6 @@ its injector produces an instance of `Car` resolved by injector (C) with an `Eng
|
||||
</div>
|
||||
|
||||
|
||||
<hr />
|
||||
|
||||
## More on dependency injection
|
||||
|
||||
For more information on Angular dependency injection, see the [DI Providers](guide/dependency-injection-providers) and [DI in Action](guide/dependency-injection-in-action) guides.
|
||||
|
||||
@@ -762,7 +762,7 @@ The HTML `base` tag with the `href` attribute specifies the base URI, or URL, fo
|
||||
"locales": {
|
||||
"fr": {
|
||||
"translation": "src/locale/messages.fr.xlf",
|
||||
"baseHref": ""
|
||||
"baseHref": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -806,11 +806,11 @@ server {
|
||||
server_name localhost;
|
||||
root /www/data;
|
||||
|
||||
# Fallback to default language if no preference defined by browser
|
||||
# Fallback to default language if no preference defined by browser
|
||||
if ($accept_language ~ "^$") {
|
||||
set $accept_language "fr";
|
||||
}
|
||||
|
||||
|
||||
# Redirect "/" to Angular app in browser's preferred language
|
||||
rewrite ^/$ /$accept_language permanent;
|
||||
|
||||
@@ -834,17 +834,17 @@ The following is an example of an Apache configuration.
|
||||
RewriteEngine on
|
||||
RewriteBase /
|
||||
RewriteRule ^../index\.html$ - [L]
|
||||
|
||||
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule (..) $1/index.html [L]
|
||||
|
||||
|
||||
RewriteCond %{HTTP:Accept-Language} ^de [NC]
|
||||
RewriteRule ^$ /de/ [R]
|
||||
|
||||
|
||||
RewriteCond %{HTTP:Accept-Language} ^en [NC]
|
||||
RewriteRule ^$ /en/ [R]
|
||||
|
||||
|
||||
RewriteCond %{HTTP:Accept-Language} !^en [NC]
|
||||
RewriteCond %{HTTP:Accept-Language} !^de [NC]
|
||||
RewriteRule ^$ /fr/ [R]
|
||||
@@ -979,3 +979,5 @@ Both elements now use the same translation (`Bonjour`) because they were defined
|
||||
<!-- ... -->
|
||||
<p>Bonjour</p>
|
||||
```
|
||||
|
||||
@reviewed 2020-04-10
|
||||
@@ -54,13 +54,13 @@ You can then click "Go to definition" or press F12 to go directly to the definit
|
||||
## Angular Language Service in your editor
|
||||
|
||||
Angular Language Service is currently available as an extension for [Visual Studio Code](https://code.visualstudio.com/),
|
||||
[WebStorm](https://www.jetbrains.com/webstorm), and [Sublime Text](https://www.sublimetext.com/).
|
||||
[WebStorm](https://www.jetbrains.com/webstorm), [Sublime Text](https://www.sublimetext.com/) and [Eclipse IDE](https://www.eclipse.org/eclipseide/).
|
||||
|
||||
### Visual Studio Code
|
||||
|
||||
In [Visual Studio Code](https://code.visualstudio.com/), install the extension from the [Extensions: Marketplace](https://marketplace.visualstudio.com/items?itemName=Angular.ng-template). You can open the marketplace from the editor using the Extensions icon on the left menu pane, or use VS Quick Open (⌘+P on Mac, CTRL+P on Windows) and type "? ext".
|
||||
In [Visual Studio Code](https://code.visualstudio.com/), install the extension from the [Extensions: Marketplace](https://marketplace.visualstudio.com/items?itemName=Angular.ng-template). You can open the marketplace from the editor using the Extensions icon on the left menu pane, or use VS Quick Open (⌘+P on Mac, CTRL+P on Windows) and type "? ext". In the marketplace, search for Angular Language Service extension, and click the **Install** button.
|
||||
|
||||
In the marketplace, search for Angular Language Service extension, and click the **Install** button.
|
||||
The Visual Studio Code integration with the Angular language service is maintained and distributed by the Angular team.
|
||||
|
||||
### WebStorm
|
||||
|
||||
@@ -103,7 +103,9 @@ npm install --save-dev @angular/language-service
|
||||
|
||||
This allows the Angular Language Service to provide diagnostics and completions in `.ts` files.
|
||||
|
||||
### Eclipse IDE
|
||||
|
||||
Either directly install the "Eclipse IDE for Web and JavaScript developers" package which comes with the Angular Language Server included, or from other Eclipse IDE packages, use Help > Eclipse Marketplace to find and install [Eclipse Wild Web Developer](https://marketplace.eclipse.org/content/wild-web-developer-html-css-javascript-typescript-nodejs-angular-json-yaml-kubernetes-xml).
|
||||
|
||||
|
||||
## How the Language Service works
|
||||
@@ -123,8 +125,6 @@ The HTML AST can only tell the compiler that there is some text with the charact
|
||||
That's when the template parser produces an expression AST, which resides within the template AST.
|
||||
The Angular Language Services then looks at `data.---` within its context, asks the TypeScript Language Service what the members of `data` are, and returns the list of possibilities.
|
||||
|
||||
<hr>
|
||||
|
||||
## More information
|
||||
|
||||
* For more in-depth information on the implementation, see the
|
||||
|
||||
@@ -17,7 +17,7 @@ For the final sample app with two lazy-loaded modules that this page describes,
|
||||
This section introduces the basic procedure for configuring a lazy-loaded route.
|
||||
For a step-by-step example, see the [step-by-step setup](#step-by-step) section on this page.
|
||||
|
||||
To lazy load Angular modules, use `loadchildren` (instead of `component`) in your `AppRoutingModule` `routes` configuration as follows.
|
||||
To lazy load Angular modules, use `loadChildren` (instead of `component`) in your `AppRoutingModule` `routes` configuration as follows.
|
||||
|
||||
<code-example header="AppRoutingModule (excerpt)">
|
||||
|
||||
@@ -323,8 +323,6 @@ ngOnInit() {
|
||||
For more information with a working example, see the [routing tutorial section on preloading](guide/router-tutorial-toh#preloading-background-loading-of-feature-areas).
|
||||
|
||||
|
||||
<hr>
|
||||
|
||||
## More on NgModules and routing
|
||||
|
||||
You may also be interested in the following:
|
||||
|
||||
@@ -220,8 +220,6 @@ The following table summarizes the `@NgModule` metadata properties.
|
||||
</table>
|
||||
|
||||
|
||||
<hr />
|
||||
|
||||
## More on NgModules
|
||||
|
||||
You may also be interested in the following:
|
||||
|
||||
@@ -12,17 +12,14 @@ Add [declarable](guide/bootstrapping#the-declarations-array) classes—compo
|
||||
Declare these classes in _exactly one_ module of the application.
|
||||
Declare them in a module if they belong to that particular module.
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a q-declarable}
|
||||
|
||||
## What is a _declarable_?
|
||||
|
||||
Declarables are the class types—components, directives, and pipes—that
|
||||
you can add to a module's `declarations` list.
|
||||
They're the only classes that you can add to `declarations`.
|
||||
|
||||
<hr/>
|
||||
|
||||
## What classes should I _not_ add to `declarations`?
|
||||
|
||||
@@ -39,8 +36,6 @@ For example, don't declare `FORMS_DIRECTIVES` from `@angular/forms` because the
|
||||
* Non-Angular classes and objects, such as
|
||||
strings, numbers, functions, entity models, configurations, business logic, and helper classes.
|
||||
|
||||
<hr/>
|
||||
|
||||
|
||||
## Why list the same component in multiple `NgModule` properties?
|
||||
|
||||
@@ -56,7 +51,6 @@ Membership in one list doesn't imply membership in another list.
|
||||
* A component could be exported for inclusion in an external component's template
|
||||
as well as dynamically loaded in a pop-up dialog.
|
||||
|
||||
<hr/>
|
||||
|
||||
## What does "Can't bind to 'x' since it isn't a known property of 'y'" mean?
|
||||
|
||||
@@ -70,7 +64,6 @@ The "x" class isn't visible to other modules until you add it to the `exports` l
|
||||
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
## What should I import?
|
||||
|
||||
@@ -89,10 +82,8 @@ components, directives, and pipes.
|
||||
|
||||
Import [BrowserModule](guide/ngmodule-faq#q-browser-vs-common-module) only in the root `AppModule`.
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a q-browser-vs-common-module}
|
||||
|
||||
## Should I import `BrowserModule` or `CommonModule`?
|
||||
|
||||
The root application module, `AppModule`, of almost every browser application
|
||||
@@ -110,10 +101,8 @@ They need the common directives. They don't need to re-install the app-wide prov
|
||||
|
||||
Importing `CommonModule` also frees feature modules for use on _any_ target platform, not just browsers.
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a q-reimport}
|
||||
|
||||
## What if I import the same module twice?
|
||||
|
||||
That's not a problem. When three modules all import Module 'A',
|
||||
@@ -126,10 +115,8 @@ When Angular gets to the 'B' and 'A' in 'D', they're already cached and ready to
|
||||
|
||||
Angular doesn't like NgModules with circular references, so don't let Module 'A' import Module 'B', which imports Module 'A'.
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a q-reexport}
|
||||
|
||||
## What should I export?
|
||||
|
||||
Export [declarable](guide/bootstrapping#the-declarations-array) classes that components in _other_ NgModules
|
||||
@@ -143,7 +130,6 @@ it's declared in this NgModule or in an imported NgModule.
|
||||
You _can_ re-export entire imported NgModules, which effectively re-export all of their exported classes.
|
||||
An NgModule can even export a module that it doesn't import.
|
||||
|
||||
<hr/>
|
||||
|
||||
## What should I *not* export?
|
||||
|
||||
@@ -159,9 +145,6 @@ While there's no harm in exporting them, there's also no benefit.
|
||||
For example, there's no point in re-exporting `HttpClientModule` because it doesn't export anything.
|
||||
Its only purpose is to add http service providers to the application as a whole.
|
||||
|
||||
<hr/>
|
||||
|
||||
|
||||
|
||||
## Can I re-export classes and modules?
|
||||
|
||||
@@ -185,9 +168,6 @@ For example, there's no point in re-exporting `HttpClientModule` because it does
|
||||
Its only purpose is to add http service providers to the application as a whole.
|
||||
|
||||
|
||||
<hr/>
|
||||
|
||||
|
||||
## What is the `forRoot()` method?
|
||||
|
||||
The `forRoot()` static method is a convention that makes it easy for developers to configure services and providers that are intended to be singletons. A good example of `forRoot()` is the `RouterModule.forRoot()` method.
|
||||
@@ -211,9 +191,6 @@ configure services in root and feature modules respectively.
|
||||
Follow this convention when you write similar modules with configurable service providers.
|
||||
|
||||
|
||||
<hr/>
|
||||
|
||||
|
||||
## Why is a service provided in a feature module visible everywhere?
|
||||
|
||||
Providers listed in the `@NgModule.providers` of a bootstrapped module have application scope.
|
||||
@@ -238,10 +215,8 @@ not just the classes declared in the `HeroModule`.
|
||||
|
||||
To limit access to a service, consider lazy loading the NgModule that provides that service. See [How do I restrict service scope to a module?](guide/ngmodule-faq#service-scope) for more information.
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a q-lazy-loaded-module-provider-visibility}
|
||||
|
||||
## Why is a service provided in a lazy-loaded module visible only to that module?
|
||||
|
||||
Unlike providers of the modules loaded at launch,
|
||||
@@ -257,8 +232,6 @@ These providers are insulated from changes to application providers with the sam
|
||||
When the router creates a component within the lazy-loaded context,
|
||||
Angular prefers service instances created from these providers to the service instances of the application root injector.
|
||||
|
||||
<hr/>
|
||||
|
||||
|
||||
## What if two modules provide the same service?
|
||||
|
||||
@@ -277,10 +250,8 @@ that also provides a service for token 'X', then NgModule A's service definition
|
||||
The service provided by the root `AppModule` takes precedence over services provided by imported NgModules.
|
||||
The `AppModule` always wins.
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a service-scope}
|
||||
|
||||
## How do I restrict service scope to a module?
|
||||
|
||||
When a module is loaded at application launch,
|
||||
@@ -329,11 +300,8 @@ Define child routes and let the router load module components into that outlet.
|
||||
|
||||
Though you can limit access to a service by providing it in a lazy loaded module or providing it in a component, providing services in a component can lead to multiple instances of those services. Thus, the lazy loading is preferable.
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a q-root-component-or-module}
|
||||
|
||||
|
||||
## Should I add application-wide providers to the root `AppModule` or the root `AppComponent`?
|
||||
|
||||
Define application-wide providers by specifying `providedIn: 'root'` on its `@Injectable()` decorator (in the case of services) or at `InjectionToken` construction (in the case where tokens are provided). Providers that are created this way automatically are made available to the entire application and don't need to be listed in any module.
|
||||
@@ -366,10 +334,8 @@ But in routed applications, routing operates at the root level
|
||||
where `AppComponent` services don't exist.
|
||||
This means that lazy-loaded modules can't reach them.
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a q-component-or-module}
|
||||
|
||||
## Should I add other providers to a module or a component?
|
||||
|
||||
Providers should be configured using `@Injectable` syntax. If possible, they should be provided in the application root (`providedIn: 'root'`). Services that are configured this way are lazily loaded if they are only used from a lazily loaded context.
|
||||
@@ -389,11 +355,8 @@ The changes that editor makes in its service don't touch the instances elsewhere
|
||||
[Always register _application-wide_ services with the root `AppModule`](guide/ngmodule-faq#q-root-component-or-module),
|
||||
not the root `AppComponent`.
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a q-why-bad}
|
||||
|
||||
|
||||
## Why is it bad if a shared module provides a service to a lazy-loaded module?
|
||||
|
||||
### The eagerly loaded scenario
|
||||
@@ -426,10 +389,8 @@ Then toggle between the "Contact" and "Heroes" links a few times.
|
||||
The username goes bonkers as the Angular creates a new `UserService` instance each time.
|
||||
I'd like to see the error so I can include it.-->
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a q-why-child-injector}
|
||||
|
||||
## Why does lazy loading create a child injector?
|
||||
|
||||
Angular adds `@NgModule.providers` to the application root injector, unless the NgModule is lazy-loaded.
|
||||
@@ -453,10 +414,8 @@ Angular must add the lazy-loaded module's providers to an injector somewhere.
|
||||
It can't add them to the app root injector because that injector is closed to new providers.
|
||||
So Angular creates a new child injector for the lazy-loaded module context.
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a q-is-it-loaded}
|
||||
|
||||
## How can I tell if an NgModule or service was previously loaded?
|
||||
|
||||
Some NgModules and their services should be loaded only once by the root `AppModule`.
|
||||
@@ -472,10 +431,8 @@ Here is a custom constructor for an NgModule called `GreetingModule`.
|
||||
|
||||
<code-example path="ngmodules/src/app/greeting/greeting.module.ts" region="ctor" header="src/app/greeting/greeting.module.ts (Constructor)"></code-example>
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a q-entry-component-defined}
|
||||
|
||||
## What is an `entry component`?
|
||||
|
||||
An entry component is any component that Angular loads _imperatively_ by type.
|
||||
@@ -498,7 +455,6 @@ loads the component dynamically into a `RouterOutlet`.
|
||||
|
||||
For more information, see [Entry Components](guide/entry-components).
|
||||
|
||||
<hr/>
|
||||
|
||||
## What's the difference between a _bootstrap_ component and an _entry component_?
|
||||
|
||||
@@ -514,7 +470,6 @@ although doing so is harmless.
|
||||
|
||||
For more information, see [Entry Components](guide/entry-components).
|
||||
|
||||
<hr/>
|
||||
|
||||
## When do I add components to _entryComponents_?
|
||||
|
||||
@@ -535,8 +490,6 @@ in the templates of other components.
|
||||
|
||||
For more information, see [Entry Components](guide/entry-components).
|
||||
|
||||
<hr/>
|
||||
|
||||
|
||||
## Why does Angular need _entryComponents_?
|
||||
|
||||
@@ -559,7 +512,6 @@ and every component reachable from an entry component.
|
||||
If a component isn't an _entry component_ or wasn't found in a template,
|
||||
the compiler omits it.
|
||||
|
||||
<hr/>
|
||||
|
||||
## What kinds of modules should I have and how should I use them?
|
||||
|
||||
@@ -593,7 +545,6 @@ For more information, see [Feature Modules](guide/feature-modules) and
|
||||
[Module Types](guide/module-types)
|
||||
|
||||
|
||||
|
||||
## What's the difference between NgModules and JavaScript Modules?
|
||||
|
||||
In an Angular app, NgModules and JavaScript modules work together.
|
||||
@@ -610,10 +561,8 @@ You _export_ this NgModule's classes so they can be imported and used by compone
|
||||
|
||||
For more information, see [JavaScript Modules vs. NgModules](guide/ngmodule-vs-jsmodule).
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a q-template-reference}
|
||||
|
||||
## How does Angular find components, directives, and pipes in a template?<br>What is a <i><b>template reference</b></i>?
|
||||
|
||||
The [Angular compiler](guide/ngmodule-faq#q-angular-compiler) looks inside component templates
|
||||
@@ -626,10 +575,8 @@ The compiler finds a pipe if the pipe's *name* appears within the pipe syntax of
|
||||
Angular only matches selectors and pipe names for classes that are declared by this module
|
||||
or exported by a module that this module imports.
|
||||
|
||||
<hr/>
|
||||
|
||||
{@a q-angular-compiler}
|
||||
|
||||
## What is the Angular compiler?
|
||||
|
||||
The Angular compiler converts the application code you write into highly performant JavaScript code.
|
||||
|
||||
@@ -57,8 +57,6 @@ The [Angular CLI](cli) generates the following basic `AppModule` when creating a
|
||||
|
||||
At the top are the import statements. The next section is where you configure the `@NgModule` by stating what components and directives belong to it (`declarations`) as well as which other modules it uses (`imports`). For more information on the structure of an `@NgModule`, be sure to read [Bootstrapping](guide/bootstrapping).
|
||||
|
||||
<hr />
|
||||
|
||||
## More on NgModules
|
||||
|
||||
You may also be interested in the following:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Using observables to pass values
|
||||
|
||||
Observables provide support for passing messages between parts of your application.
|
||||
They are used frequently in Angular and are the recommended technique for event handling, asynchronous programming, and handling multiple values.
|
||||
They are used frequently in Angular and are a technique for event handling, asynchronous programming, and handling multiple values.
|
||||
|
||||
The observer pattern is a software design pattern in which an object, called the *subject*, maintains a list of its dependents, called *observers*, and notifies them automatically of state changes.
|
||||
This pattern is similar (but not identical) to the [publish/subscribe](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern) design pattern.
|
||||
@@ -11,7 +11,7 @@ The subscribed consumer then receives notifications until the function completes
|
||||
|
||||
An observable can deliver multiple values of any type—literals, messages, or events, depending on the context. The API for receiving values is the same whether the values are delivered synchronously or asynchronously. Because setup and teardown logic are both handled by the observable, your application code only needs to worry about subscribing to consume values, and when done, unsubscribing. Whether the stream was keystrokes, an HTTP response, or an interval timer, the interface for listening to values and stopping listening is the same.
|
||||
|
||||
Because of these advantages, observables are used extensively within Angular, and are recommended for app development as well.
|
||||
Because of these advantages, observables are used extensively within Angular, and for app development as well.
|
||||
|
||||
## Basic usage and terms
|
||||
|
||||
|
||||
@@ -18,8 +18,6 @@ To get the most out of property binding, you should be familiar with the followi
|
||||
* [Basics of templates](guide/glossary#template)
|
||||
* [Binding syntax](guide/binding-syntax)
|
||||
|
||||
<hr />
|
||||
|
||||
## Understanding the flow of data
|
||||
|
||||
Property binding moves a value in one direction, from a component's property into a target element property.
|
||||
@@ -196,8 +194,6 @@ The following binding pairs do the same thing.
|
||||
You can use either form when rendering data values as strings, though interpolation is preferable for readability.
|
||||
However, when setting an element property to a non-string data value, you must use property binding.
|
||||
|
||||
<hr />
|
||||
|
||||
## What's next
|
||||
|
||||
* [Property binding best practices](guide/property-binding-best-practices)
|
||||
|
||||
@@ -97,9 +97,6 @@ Child modules and component injectors are independent of each other, and create
|
||||
For more information, see [Hierarchical injectors](guide/hierarchical-dependency-injection).
|
||||
|
||||
|
||||
|
||||
<hr>
|
||||
|
||||
## More on NgModules
|
||||
|
||||
You may also be interested in:
|
||||
|
||||
@@ -19,10 +19,7 @@ Before creating a route, you should be familiar with the following:
|
||||
For an introduction to Angular with a ready-made app, see [Getting Started](start).
|
||||
For a more in-depth experience of building an Angular app, see the [Tour of Heroes](tutorial) tutorial. Both guide you through using component classes and templates.
|
||||
|
||||
<hr />
|
||||
|
||||
{@a basics}
|
||||
|
||||
## Generate an app with routing enabled
|
||||
|
||||
The following command uses the Angular CLI to generate a basic Angular app with an app routing module, called `AppRoutingModule`, which is an NgModule where you can configure your routes.
|
||||
@@ -374,7 +371,7 @@ The following route guards are available in Angular:
|
||||
* [`Resolve`](api/router/Resolve)
|
||||
* [`CanLoad`](api/router/CanLoad)
|
||||
|
||||
To use route guards, consider using component-less routes as this facilitates guarding child routes.
|
||||
To use route guards, consider using [component-less routes](api/router/Route#componentless-routes) as this facilitates guarding child routes.
|
||||
|
||||
Create a service for your guard:
|
||||
|
||||
|
||||
@@ -7,8 +7,6 @@ Importing `ServiceWorkerModule` into your `AppModule` doesn't just register the
|
||||
A basic understanding of the following:
|
||||
* [Getting Started with Service Workers](guide/service-worker-getting-started).
|
||||
|
||||
<hr />
|
||||
|
||||
|
||||
## `SwUpdate` service
|
||||
|
||||
|
||||
@@ -7,8 +7,6 @@ This page is a reference for deploying and supporting production apps that use t
|
||||
A basic understanding of the following:
|
||||
* [Service Worker Communication](guide/service-worker-communications).
|
||||
|
||||
<hr />
|
||||
|
||||
## Service worker and caching of app resources
|
||||
|
||||
Conceptually, you can imagine the Angular service worker as a forward cache or a CDN edge that is installed in the end user's web browser. The service worker's job is to satisfy requests made by the Angular app for resources or data from a local cache, without needing to wait for the network. Like any cache, it has rules for how content is expired and updated.
|
||||
@@ -346,16 +344,16 @@ the past on your site.
|
||||
|
||||
### Changing your app's location
|
||||
|
||||
It is important to note that service workers don't work behind redirect. You
|
||||
It is important to note that service workers don't work behind redirect. You
|
||||
may have already encountered the error `The script resource is behind a redirect, which is disallowed`.
|
||||
|
||||
This can be a problem if you have to change your app's location. If you setup
|
||||
a redirect from the old location (for example `example.com`) to the new
|
||||
location (for example `www.example.com`) the worker will stop working.
|
||||
Also, the redirect won't even trigger for users who are loading the site
|
||||
This can be a problem if you have to change your app's location. If you setup
|
||||
a redirect from the old location (for example `example.com`) to the new
|
||||
location (for example `www.example.com`) the worker will stop working.
|
||||
Also, the redirect won't even trigger for users who are loading the site
|
||||
entirely from Service Worker. The old worker (registered at `example.com`)
|
||||
tries to update and sends requests to the old location `example.com` which
|
||||
get redirected to the new location `www.example.com` and create the error
|
||||
tries to update and sends requests to the old location `example.com` which
|
||||
get redirected to the new location `www.example.com` and create the error
|
||||
`The script resource is behind a redirect, which is disallowed`.
|
||||
|
||||
To remedy this, you may need to kill the old worker using one of the above
|
||||
|
||||
@@ -115,7 +115,7 @@ Pay attention to two key points:
|
||||
### Making changes to your application
|
||||
|
||||
Now that you've seen how service workers cache your application, the
|
||||
next step is understanding how updates work.
|
||||
next step is understanding how updates work. Let's make a change to the application, and watch the service worker install the update:
|
||||
|
||||
1. If you're testing in an incognito window, open a second blank tab. This will keep the incognito and the cache state alive during your test.
|
||||
|
||||
@@ -123,13 +123,11 @@ next step is understanding how updates work.
|
||||
|
||||
3. Shut down `http-server`.
|
||||
|
||||
4. Next, make a change to the application, and watch the service worker install the update.
|
||||
4. Open `src/app/app.component.html` for editing.
|
||||
|
||||
5. Open `src/app/app.component.html` for editing.
|
||||
5. Change the text `Welcome to {{title}}!` to `Bienvenue à {{title}}!`.
|
||||
|
||||
6. Change the text `Welcome to {{title}}!` to `Bienvenue à {{title}}!`.
|
||||
|
||||
7. Build and run the server again:
|
||||
6. Build and run the server again:
|
||||
|
||||
```sh
|
||||
ng build --prod
|
||||
@@ -158,8 +156,6 @@ If you look at the `http-server` logs, you can see the service worker requesting
|
||||
|
||||
The service worker installed the updated version of your app *in the background*, and the next time the page is loaded or reloaded, the service worker switches to the latest version.
|
||||
|
||||
<hr />
|
||||
|
||||
## More on Angular service workers
|
||||
|
||||
You may also be interested in the following:
|
||||
|
||||
@@ -53,8 +53,6 @@ The most common way to get a hold of shared services is through Angular
|
||||
To read about sharing services, see [Providers](guide/providers).
|
||||
|
||||
|
||||
<hr />
|
||||
|
||||
## More on NgModules
|
||||
|
||||
You may also be interested in the following:
|
||||
|
||||
@@ -171,8 +171,6 @@ Here are the two files in their entirety for reference:
|
||||
</code-pane>
|
||||
</code-tabs>
|
||||
|
||||
<hr />
|
||||
|
||||
## More on NgModules
|
||||
|
||||
You may also be interested in:
|
||||
|
||||
@@ -53,7 +53,6 @@ For more information, see the [Security](guide/security) page.
|
||||
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
## More on template syntax
|
||||
|
||||
|
||||
@@ -24,5 +24,3 @@ Debug specs in the browser in the same way that you debug an application.
|
||||
<div class="lightbox">
|
||||
<img src='generated/images/guide/testing/karma-1st-spec-debug.png' alt="Karma debugging">
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
@@ -74,5 +74,3 @@ A few techniques are noteworthy:
|
||||
and its `defaultColor`.
|
||||
|
||||
- `DebugElement.properties` affords access to the artificial custom property that is set by the directive.
|
||||
|
||||
<hr>
|
||||
|
||||
@@ -124,10 +124,7 @@ There is no harm in calling `detectChanges()` more often than is strictly necess
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
{@a dispatch-event}
|
||||
|
||||
#### Change an input value with _dispatchEvent()_
|
||||
|
||||
To simulate user input, you can find the input element and set its `value` property.
|
||||
@@ -143,8 +140,6 @@ The following example demonstrates the proper sequence.
|
||||
|
||||
<code-example path="testing/src/app/hero/hero-detail.component.spec.ts" region="title-case-pipe" header="app/hero/hero-detail.component.spec.ts (pipe test)"></code-example>
|
||||
|
||||
<hr>
|
||||
|
||||
## Component with external files
|
||||
|
||||
The `BannerComponent` above is defined with an _inline template_ and _inline css_, specified in the `@Component.template` and `@Component.styles` properties respectively.
|
||||
@@ -291,10 +286,7 @@ The remaining tests confirm the logic of the component when the service returns
|
||||
The second test validates the effect of changing the user name.
|
||||
The third test checks that the component displays the proper message when there is no logged-in user.
|
||||
|
||||
<hr>
|
||||
|
||||
{@a component-with-async-service}
|
||||
|
||||
## Component with async service
|
||||
|
||||
In this sample, the `AboutComponent` template hosts a `TwainComponent`.
|
||||
@@ -670,8 +662,6 @@ can give you that information and make assertions about the state of the view.
|
||||
path="testing/src/app/twain/twain.component.spec.ts"
|
||||
region="spy-done-test"></code-example>
|
||||
|
||||
<hr>
|
||||
|
||||
{@a marble-testing}
|
||||
## Component marble tests
|
||||
|
||||
@@ -776,10 +766,7 @@ RxJS marble testing is a rich subject, beyond the scope of this guide.
|
||||
Learn about it on the web, starting with the
|
||||
[official documentation](https://rxjs.dev/guide/testing/marble-testing).
|
||||
|
||||
<hr>
|
||||
|
||||
{@a component-with-input-output}
|
||||
|
||||
## Component with inputs and outputs
|
||||
|
||||
A component with inputs and outputs typically appears inside the view template of a host component.
|
||||
@@ -970,10 +957,7 @@ Here's the previous test, rewritten using the click helper.
|
||||
header="app/dashboard/dashboard-hero.component.spec.ts (test with click helper)">
|
||||
</code-example>
|
||||
|
||||
<hr>
|
||||
|
||||
{@a component-inside-test-host}
|
||||
|
||||
## Component inside a test host
|
||||
|
||||
The previous tests played the role of the host `DashboardComponent` themselves.
|
||||
@@ -1032,10 +1016,7 @@ The tests themselves are almost identical to the stand-alone version:
|
||||
Only the selected event test differs. It confirms that the selected `DashboardHeroComponent` hero
|
||||
really does find its way up through the event binding to the host component.
|
||||
|
||||
<hr>
|
||||
|
||||
{@a routing-component}
|
||||
|
||||
## Routing component
|
||||
|
||||
A _routing component_ is a component that tells the `Router` to navigate to another component.
|
||||
@@ -1186,8 +1167,6 @@ New heroes have `id=0` and a blank `name`. This test confirms that the component
|
||||
region="route-no-id"
|
||||
header="app/hero/hero-detail.component.spec.ts (no id)"></code-example>
|
||||
|
||||
<hr>
|
||||
|
||||
## Nested component tests
|
||||
|
||||
Component templates often have nested components, whose templates
|
||||
@@ -1309,8 +1288,6 @@ The Angular compiler creates the `BannerComponentStub` for the `<app-banner>` el
|
||||
and applies the `RouterLinkStubDirective` to the anchors with the `routerLink` attribute,
|
||||
but it ignores the `<app-welcome>` and `<router-outlet>` tags.
|
||||
|
||||
<hr>
|
||||
|
||||
{@a routerlink}
|
||||
## Components with _RouterLink_
|
||||
|
||||
@@ -1417,10 +1394,7 @@ tests with the `RouterTestingModule`.
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
{@a page-object}
|
||||
|
||||
## Use a _page_ object
|
||||
|
||||
The `HeroDetailComponent` is a simple view with a title, two hero fields, and two buttons.
|
||||
@@ -1474,8 +1448,6 @@ Here are a few more `HeroDetailComponent` tests to reinforce the point.
|
||||
region="selected-tests"
|
||||
header="app/hero/hero-detail.component.spec.ts (selected tests)"></code-example>
|
||||
|
||||
<hr>
|
||||
|
||||
{@a compile-components}
|
||||
## Calling _compileComponents()_
|
||||
|
||||
@@ -1619,10 +1591,7 @@ even though it is never required when running `ng test`.
|
||||
|
||||
The tests in this guide only call `compileComponents` when necessary.
|
||||
|
||||
<hr>
|
||||
|
||||
{@a import-module}
|
||||
|
||||
## Setup with module imports
|
||||
|
||||
Earlier component tests configured the testing module with a few `declarations` like this:
|
||||
@@ -1705,10 +1674,7 @@ the module is small, as feature modules tend to be.
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
{@a component-override}
|
||||
|
||||
## Override component providers
|
||||
|
||||
The `HeroDetailComponent` provides its own `HeroDetailService`.
|
||||
@@ -1817,5 +1783,3 @@ The `TestBed` offers similar `overrideDirective`, `overrideModule`, and `overrid
|
||||
for digging into and replacing parts of these other classes.
|
||||
|
||||
Explore the options and combinations on your own.
|
||||
|
||||
<hr>
|
||||
|
||||
@@ -144,10 +144,7 @@ Here's a summary of the stand-alone functions, in order of likely utility:
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<hr>
|
||||
|
||||
{@a testbed-class-summary}
|
||||
|
||||
## _TestBed_ class summary
|
||||
|
||||
The `TestBed` class is one of the principal Angular testing utilities.
|
||||
@@ -789,6 +786,3 @@ The Angular `By` class has three static methods for common predicates:
|
||||
- `By.directive(directive)` - return elements that Angular matched to an instance of the directive class.
|
||||
|
||||
<code-example path="testing/src/app/hero/hero-list.component.spec.ts" region="by" header="app/hero/hero-list.component.spec.ts"></code-example>
|
||||
|
||||
<hr>
|
||||
|
||||
|
||||
@@ -275,8 +275,6 @@ Now you can run the following commands to use the `--no-sandbox` flag:
|
||||
</div>
|
||||
|
||||
|
||||
<hr />
|
||||
|
||||
## More info on testing
|
||||
|
||||
After you've set up your app for testing, you may find the following testing guides useful.
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
@@ -281,6 +281,14 @@
|
||||
"bio": "Raul works as a CEO and Front-end Architect at Byte Default for companies around the world helping them to build high-performance web apps. In his spare time he's usually working on Videogular, involved in local meetups, speaking at conferences and contributing to open source projects.",
|
||||
"groups": ["GDE"]
|
||||
},
|
||||
"eliraneliassy": {
|
||||
"name": "Eliran Eliassy",
|
||||
"picture": "eliraneliassy.jpg",
|
||||
"twitter": "eliraneliassy",
|
||||
"website": "https://eliassy.dev",
|
||||
"bio": "Eliran is an Experienced FE developer, located in Tel Aviv, Israel. He is a developer, trainer, and consultant with a focus on Angular and the eco-system around it. He gives talks and workshops on Angular, RXJS, NGRX, and related technologies. As an active part of the community, he is constantly involved in growing it and interacting with the members. Eliran is one of the Organisers of AngularUP Annual Conference in Tel Aviv and also an organizer and leading the Angular meetup & community in Israel. He often speaks at conferences and meetups and also writes for AngualrInDepth.com.",
|
||||
"groups": ["GDE"]
|
||||
},
|
||||
"eusoj": {
|
||||
"name": "Josue Gutierrez",
|
||||
"picture": "josue.jpg",
|
||||
@@ -928,3 +936,4 @@
|
||||
"groups": ["GDE"]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"name": "Angular Global Summit",
|
||||
"location": "Online",
|
||||
"linkUrl": "https://angular.geekle.us/",
|
||||
"date": {
|
||||
"start": "2021-04-13",
|
||||
"end": "2021-04-14"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ng-china",
|
||||
"location": "Online",
|
||||
|
||||
@@ -469,6 +469,11 @@
|
||||
"desc": "NGX Skeleton Loader is a lightweight and A11Y friendly solution for blazing fast loading skeletons that automatically adapt to your Angular apps.",
|
||||
"title": "NGX Skeleton Loader",
|
||||
"url": "https://www.npmjs.com/package/ngx-skeleton-loader"
|
||||
},
|
||||
"taiga-ui": {
|
||||
"desc": "Taiga UI is fully-treeshakable Angular UI Kit consisting of multiple base libraries and several add-ons. We have 130+ components, 100+ directives, dozens of tokens, utils and tools. They are easily customizable and well engineered.",
|
||||
"title": "Taiga UI",
|
||||
"url": "https://taiga-ui.dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -542,6 +547,11 @@
|
||||
"desc": "Practical journey with Angular framework, ES6, TypeScript, webpack and Angular CLI.",
|
||||
"title": "Developing with Angular",
|
||||
"url": "https://leanpub.com/developing-with-angular"
|
||||
},
|
||||
"reactive-state-for-angular-with-ngrx": {
|
||||
"desc": "Learn how to build a Reactive Application with Ngrx and Angular",
|
||||
"title": "Reactive State for Angular with NgRx",
|
||||
"url": "https://bpbonline.com/products/reactive-state-for-angular-with-ngrx"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -15,11 +15,8 @@ To get the most out of this tutorial you should already have a basic understandi
|
||||
* [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript "JavaScript")
|
||||
* [TypeScript](https://www.typescriptlang.org/ "The TypeScript language")
|
||||
|
||||
<hr />
|
||||
|
||||
|
||||
{@a components}
|
||||
|
||||
## Take a tour of the example application
|
||||
|
||||
You build Angular applications with components.
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
{"type": 301, "source": "/getting-started", "destination": "/start"},
|
||||
{"type": 301, "source": "/getting-started/:rest*", "destination": "/start/:rest*"},
|
||||
{"type": 301, "source": "/guide/displaying-data", "destination": "/start#template-syntax"},
|
||||
{"type": 301, "source": "/guide/updating-to-version-10", "destination": "/guide/updating-to-version-11"},
|
||||
|
||||
// Renaming of Getting Started topics
|
||||
{"type": 301, "source": "/start/data", "destination": "/start/start-data"},
|
||||
|
||||
@@ -123,6 +123,9 @@
|
||||
"!/guide/service-worker-configref",
|
||||
"!/guide/service-worker-configref.html",
|
||||
"!/guide/service-worker-configref/",
|
||||
"!/guide/updating-to-version-10",
|
||||
"!/guide/updating-to-version-10.html",
|
||||
"!/guide/updating-to-version-10/",
|
||||
"!/guide/webpack",
|
||||
"!/guide/webpack.html",
|
||||
"!/guide/webpack/",
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@
|
||||
"build-local-with-viewengine": "yarn ~~build",
|
||||
"prebuild-local-with-viewengine-ci": "node scripts/switch-to-viewengine && yarn setup-local-ci",
|
||||
"build-local-with-viewengine-ci": "yarn ~~build --progress=false",
|
||||
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js c366e223b",
|
||||
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js ab638724c",
|
||||
"lint": "yarn check-env && yarn docs-lint && ng lint && yarn example-lint && yarn tools-lint",
|
||||
"test": "yarn check-env && ng test",
|
||||
"pree2e": "yarn check-env && yarn update-webdriver",
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<article class="api-list-container l-content-small docs-content">
|
||||
<article class="api-list-container">
|
||||
<div *ngFor="let section of filteredSections | async" >
|
||||
<h2 *ngIf="section.items"><a [href]="section.path" [class.deprecated-api-item]="section.deprecated">{{section.title}}</a></h2>
|
||||
<ul class="api-list" *ngIf="section.items && section.items.length">
|
||||
|
||||
+2
-2
@@ -25,8 +25,8 @@
|
||||
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="assets/images/favicons/favicon-144x144.png">
|
||||
|
||||
<!-- NOTE: These need to be kept in sync with `ngsw-config.json`. -->
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500&display=swap">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Droid+Sans+Mono&display=swap">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@300;400;500&display=swap">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons&display=block">
|
||||
<!-- -->
|
||||
|
||||
|
||||
@@ -6,20 +6,21 @@ body {
|
||||
font-family: $main-font;
|
||||
margin: 0;
|
||||
color: $darkgray;
|
||||
@include font-size(14);
|
||||
@include font-size(16);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
color: $deepgray;
|
||||
margin-bottom: 0;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
h1 {
|
||||
@include font-size(24);
|
||||
font-weight: 500;
|
||||
@include font-size(40);
|
||||
display: inline-block;
|
||||
margin: 8px 0px;
|
||||
margin: 1.6rem 0;
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
margin-top: 0;
|
||||
@@ -27,38 +28,48 @@ h1 {
|
||||
}
|
||||
|
||||
h2 {
|
||||
@include font-size(22);
|
||||
font-weight: 500;
|
||||
margin: 32px 0px 24px;
|
||||
border-top: 1px solid $lightgray;
|
||||
clear: both;
|
||||
@include font-size(32);
|
||||
margin-top: 4rem;
|
||||
padding-top: 4rem;
|
||||
|
||||
.page-about &,
|
||||
.page-api &,
|
||||
.page-contribute &,
|
||||
.page-events &,
|
||||
.page-features &,
|
||||
.page-home &,
|
||||
.page-presskit &,
|
||||
.page-resources & {
|
||||
border-top: 0;
|
||||
margin-top: 2rem;
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
@include font-size(20);
|
||||
font-weight: 400;
|
||||
margin: 24px 0px 12px;
|
||||
@include font-size(24);
|
||||
margin-top: 3rem;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
h4 {
|
||||
@include font-size(18);
|
||||
font-weight: 400;
|
||||
margin: 8px 0px;
|
||||
@include font-size(20);
|
||||
margin-top: 3rem;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
h5 {
|
||||
@include font-size(16);
|
||||
font-weight: 500;
|
||||
margin: 8px 0px;
|
||||
@include font-size(18);
|
||||
margin-top: 2rem;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
h6 {
|
||||
@include font-size(16);
|
||||
font-weight: 500;
|
||||
color: $mediumgray;
|
||||
margin: 8px 0px;
|
||||
margin-top: 2rem;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
@@ -87,18 +98,18 @@ ol,
|
||||
li,
|
||||
input,
|
||||
a {
|
||||
@include font-size(14);
|
||||
@include line-height(24);
|
||||
@include letter-spacing(0.3);
|
||||
@include font-size(16);
|
||||
@include line-height(32);
|
||||
font-weight: 400;
|
||||
color: $darkgray;
|
||||
|
||||
& > em {
|
||||
@include letter-spacing(0.3);
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 14px 0 0;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
p + ul {
|
||||
@@ -122,6 +133,7 @@ ol ol {
|
||||
|
||||
li {
|
||||
padding-bottom: 8px;
|
||||
@include line-height(24);
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
@@ -160,7 +172,6 @@ table tbody th {
|
||||
td {
|
||||
font-weight: 400;
|
||||
padding: 8px 30px;
|
||||
@include letter-spacing(0.3);
|
||||
|
||||
> p,
|
||||
ul {
|
||||
@@ -188,8 +199,9 @@ code {
|
||||
|
||||
.sidenav-content a {
|
||||
color: $blue;
|
||||
|
||||
&:hover {
|
||||
color: $mediumgray;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,7 +216,6 @@ code {
|
||||
.folder-guide,
|
||||
.folder-start,
|
||||
.folder-tutorial {
|
||||
|
||||
aio-doc-viewer{
|
||||
a {
|
||||
&[href^="http:"]::after,
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
.sidenav-content {
|
||||
min-height: 100vh;
|
||||
padding: 80px 3rem 2rem;
|
||||
max-width: 50em;
|
||||
margin: 0 auto;
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
min-height: 450px;
|
||||
@@ -16,9 +18,15 @@
|
||||
padding: 80px 1rem 1rem;
|
||||
}
|
||||
|
||||
aio-shell.page-docs & {
|
||||
// padding: 6rem 3rem 3rem 3rem; // THIS CAUSES THE TOP NAV TOOLBAR TO JUMP BETWEEN DOCS AND OTHER PAGES
|
||||
margin: auto;
|
||||
.page-about &,
|
||||
.page-contribute &,
|
||||
.page-events &,
|
||||
.page-features &,
|
||||
.page-guide-cheatsheet &,
|
||||
.page-home &,
|
||||
.page-presskit &,
|
||||
.page-resources & {
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
button {
|
||||
@@ -31,11 +39,3 @@ aio-menu {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
#guide-change-log h2::before {
|
||||
content: "";
|
||||
display: block;
|
||||
height: 1px;
|
||||
margin: 24px 0px;
|
||||
background: $lightgray;
|
||||
}
|
||||
|
||||
@@ -13,104 +13,99 @@ footer {
|
||||
|
||||
& > * {
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
|
||||
.footer-block {
|
||||
margin: 0 24px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $white;
|
||||
text-decoration: none;
|
||||
z-index: 20;
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
max-width: 50em;
|
||||
}
|
||||
|
||||
&:visited {
|
||||
.footer-block {
|
||||
margin: 0 24px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $white;
|
||||
text-decoration: none;
|
||||
z-index: 20;
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
&:visited {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
// `outline-offset` is not applied on Chrome on Windows, if `outline-style` is `auto.
|
||||
outline: 1px solid rgba($white, 0.8);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
// `outline-offset` is not applied on Chrome on Windows, if `outline-style` is `auto.
|
||||
outline: 1px solid rgba($white, 0.8);
|
||||
outline-offset: 2px;
|
||||
h3 {
|
||||
@include font-size(16);
|
||||
text-transform: uppercase;
|
||||
font-weight: 400;
|
||||
margin: 8px 0 12px;
|
||||
color: $white;
|
||||
|
||||
@media (max-width: 600px) {
|
||||
@include font-size(14);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a.action {
|
||||
cursor: pointer;
|
||||
}
|
||||
p {
|
||||
text-align: center;
|
||||
margin: 10px auto 5px;
|
||||
|
||||
h3 {
|
||||
@include font-size(16);
|
||||
text-transform: uppercase;
|
||||
font-weight: 400;
|
||||
margin: 8px 0 12px;
|
||||
color: $white;
|
||||
}
|
||||
|
||||
p {
|
||||
text-align: center;
|
||||
margin: 10px 0px 5px;
|
||||
|
||||
@media (max-width: 480px) {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
div.grid-fluid {
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
text-align: left;
|
||||
margin: 0 0 40px;
|
||||
|
||||
ul {
|
||||
list-style-position: inside;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
|
||||
li {
|
||||
list-style-type: none;
|
||||
padding: 4px 0;
|
||||
@media (max-width: 480px) {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
flex-direction: column;
|
||||
div.grid-fluid {
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
text-align: left;
|
||||
margin: 0 auto 40px;
|
||||
|
||||
.footer-block {
|
||||
margin: 8px 24px;
|
||||
ul {
|
||||
list-style-position: inside;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
|
||||
li {
|
||||
list-style-type: none;
|
||||
padding: 4px 0;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
flex-direction: column;
|
||||
|
||||
.footer-block {
|
||||
margin: 8px 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
h3 {
|
||||
@include font-size(14);
|
||||
}
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: url("/assets/images/logos/angular/angular_whiteTransparent_withMargin.png")
|
||||
top 0 left 0 repeat,
|
||||
url("/assets/images/logos/angular/angular_whiteTransparent_withMargin.png")
|
||||
top 80px left 160px repeat;
|
||||
opacity: 0.05;
|
||||
background-size: 320px auto;
|
||||
}
|
||||
}
|
||||
|
||||
footer::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: url("/assets/images/logos/angular/angular_whiteTransparent_withMargin.png")
|
||||
top 0 left 0 repeat,
|
||||
url("/assets/images/logos/angular/angular_whiteTransparent_withMargin.png")
|
||||
top 80px left 160px repeat;
|
||||
opacity: 0.05;
|
||||
background-size: 320px auto;
|
||||
}
|
||||
|
||||
@@ -1,34 +1,18 @@
|
||||
html, body {
|
||||
height: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body,
|
||||
.content {
|
||||
background-color: $white;
|
||||
background-color: $white;
|
||||
}
|
||||
|
||||
.github-links + .content h1 {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.clearfix {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.clear {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.l-clearfix:after, .clearfix:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.is-visible {
|
||||
display: block!important;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.l-flex-wrap {
|
||||
@@ -37,20 +21,16 @@ body,
|
||||
}
|
||||
|
||||
.flex-center {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.center {
|
||||
text-align: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.visually-hidden {
|
||||
position: absolute !important;
|
||||
top: -9999px !important;
|
||||
left: -9999px !important;
|
||||
}
|
||||
|
||||
.text-uppercase {
|
||||
text-transform: uppercase;
|
||||
position: absolute !important;
|
||||
top: -9999px !important;
|
||||
left: -9999px !important;
|
||||
}
|
||||
|
||||
@@ -262,13 +262,13 @@ section#intro {
|
||||
|
||||
aio-shell {
|
||||
&.page-resources, &.page-events, &.page-features, &.page-presskit, &.page-contribute {
|
||||
main {
|
||||
padding: 0rem 0rem 3rem;
|
||||
.sidenav-content {
|
||||
padding: 0 0 3rem;
|
||||
}
|
||||
}
|
||||
|
||||
&.page-home {
|
||||
main {
|
||||
.sidenav-content {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,41 +3,8 @@
|
||||
transition: none;
|
||||
}
|
||||
|
||||
aio-nav-menu {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
max-width: 260px;
|
||||
@include font-size(13);
|
||||
|
||||
ul, a {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
aio-nav-item div a {
|
||||
padding-left: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
mat-sidenav.mat-sidenav.sidenav {
|
||||
position: fixed;
|
||||
top: 64px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
padding: 0;
|
||||
min-width: 260px;
|
||||
background-color: $white;
|
||||
box-shadow: 6px 0 6px rgba(0,0,0,0.10);
|
||||
|
||||
&.collapsed {
|
||||
top: 56px;
|
||||
}
|
||||
}
|
||||
|
||||
mat-sidenav-container.sidenav-container {
|
||||
background-color: $white;
|
||||
min-height: 100%;
|
||||
height: auto !important;
|
||||
max-width: 100%;
|
||||
@@ -47,192 +14,179 @@ mat-sidenav-container.sidenav-container {
|
||||
&.has-floating-toc {
|
||||
max-width: 82%;
|
||||
}
|
||||
}
|
||||
|
||||
mat-sidenav-container.sidenav-container.mat-drawer-container.mat-sidenav-container,
|
||||
mat-sidenav-container .sidenav-content {
|
||||
background-color: $white;
|
||||
}
|
||||
|
||||
mat-sidenav-container div.mat-sidenav-content {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.vertical-menu-item {
|
||||
box-sizing: border-box;
|
||||
color: $darkgray;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
overflow-wrap: break-word;
|
||||
padding: 8px;
|
||||
text-decoration: none;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
word-wrap: break-word;
|
||||
|
||||
&:hover {
|
||||
background-color: $lightgray;
|
||||
color: $blue;
|
||||
text-shadow: 0 0 5px #ffffff;
|
||||
.sidenav-content {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: $focus-outline-onlight auto 2px;
|
||||
}
|
||||
mat-sidenav.sidenav {
|
||||
position: fixed;
|
||||
top: 64px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
min-width: 260px;
|
||||
background-color: $superlightgray;
|
||||
border-right: 1px solid $lightgray;
|
||||
|
||||
&.selected {
|
||||
color: $blue;
|
||||
}
|
||||
&.collapsed {
|
||||
top: 56px;
|
||||
}
|
||||
|
||||
&.level-2 {
|
||||
padding-top: 4px;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
// Angular Version Selector
|
||||
.doc-version {
|
||||
padding: 8px;
|
||||
border-top: 1px solid $lightgray;
|
||||
|
||||
span {
|
||||
padding-right: 32px;
|
||||
}
|
||||
select {
|
||||
outline: none;
|
||||
width: 100%;
|
||||
background: rgba($lightgray, 0.5);
|
||||
height: 32px;
|
||||
border: 1px solid $lightgray;
|
||||
color: $darkgray;
|
||||
|
||||
//icons _within_ nav
|
||||
.mat-icon {
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
button.vertical-menu-item {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.heading {
|
||||
color: $darkgray;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.heading-children {
|
||||
&.expanded {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
padding-left: 0;
|
||||
max-height: 4000px; // Arbitrary max-height. Can increase if needed. Must have measurement to transition height.
|
||||
transition: visibility 500ms, opacity 500ms, max-height 500ms;
|
||||
transition-timing-function: ease-in-out;
|
||||
}
|
||||
|
||||
&.collapsed {
|
||||
overflow: hidden; // Needed to prevent unnecessary sidenav scrollbar.
|
||||
visibility: hidden;
|
||||
padding-left: 0;
|
||||
opacity: 0;
|
||||
max-height: 1px; // Must have measurement to transition height.
|
||||
transition: visibility 275ms, opacity 275ms, max-height 280ms;
|
||||
transition-timing-function: ease-out;
|
||||
}
|
||||
}
|
||||
|
||||
.no-animations {
|
||||
.heading-children.expanded,
|
||||
.heading-children.collapsed {
|
||||
transition: none! important;
|
||||
}
|
||||
}
|
||||
|
||||
.level-1 {
|
||||
font-family: $main-font;
|
||||
@include font-size(14);
|
||||
font-weight: 400;
|
||||
padding-left: 20px;
|
||||
margin: 0;
|
||||
transition: background-color 0.2s;
|
||||
text-transform: uppercase;
|
||||
|
||||
&.expanded .mat-icon,
|
||||
.level-2.expanded .mat-icon {
|
||||
@include rotate(90deg);
|
||||
}
|
||||
|
||||
&:not(.expanded) .mat-icon,
|
||||
.level-2:not(.expanded) .mat-icon {
|
||||
@include rotate(0deg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.level-2 {
|
||||
color: $mediumgray;
|
||||
font-family: $main-font;
|
||||
@include font-size(14);
|
||||
font-weight: 400;
|
||||
margin: 0;
|
||||
padding-left: 32px;
|
||||
text-transform: none;
|
||||
|
||||
&.expanded .mat-icon,
|
||||
.level-3.expanded .mat-icon {
|
||||
@include rotate(90deg);
|
||||
}
|
||||
|
||||
&:not(.expanded) .mat-icon,
|
||||
.level-3:not(.expanded) .mat-icon {
|
||||
@include rotate(0deg);
|
||||
}
|
||||
}
|
||||
|
||||
.level-3 {
|
||||
color: $mediumgray;
|
||||
font-family: $main-font;
|
||||
@include font-size(14);
|
||||
margin: 0;
|
||||
padding-left: 40px;
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
.level-4 {
|
||||
color: $mediumgray;
|
||||
font-family: $main-font;
|
||||
@include font-size(14);
|
||||
margin: 0;
|
||||
padding-left: 48px;
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
aio-nav-menu.top-menu {
|
||||
padding: 24px 0 0;
|
||||
|
||||
aio-nav-item:last-child div {
|
||||
border-bottom: 1px solid rgba($mediumgray, 0.5);
|
||||
}
|
||||
|
||||
aio-nav-item:first-child div {
|
||||
border-top: 1px solid rgba($mediumgray, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
// Angular Version Selector
|
||||
mat-sidenav .doc-version {
|
||||
padding: 8px;
|
||||
border-top: 1px solid $lightgray;
|
||||
|
||||
select {
|
||||
outline: none;
|
||||
width: 100%;
|
||||
background: rgba($lightgray, 0.5);
|
||||
height: 32px;
|
||||
border: 1px solid $lightgray;
|
||||
color: $darkgray;
|
||||
|
||||
option {
|
||||
font-family: $main-font;
|
||||
@include font-size(14);
|
||||
option {
|
||||
font-family: $main-font;
|
||||
@include font-size(14);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aio-nav-menu {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
max-width: 268px;
|
||||
|
||||
&:first-of-type {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
ul, a {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
aio-nav-item {
|
||||
.vertical-menu-item {
|
||||
box-sizing: border-box;
|
||||
color: $darkgray;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
overflow-wrap: break-word;
|
||||
padding: 8px;
|
||||
text-decoration: none;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
word-wrap: break-word;
|
||||
|
||||
&:hover {
|
||||
background-color: $lightgray;
|
||||
color: $blue;
|
||||
text-shadow: 0 0 5px $white;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: $focus-outline-onlight auto 2px;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
color: $darkblue;
|
||||
}
|
||||
|
||||
span {
|
||||
padding-right: 32px;
|
||||
}
|
||||
|
||||
//icons _within_ nav
|
||||
.mat-icon {
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
button.vertical-menu-item {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.heading-children {
|
||||
&.expanded {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
padding-left: 0;
|
||||
max-height: 4000px; // Arbitrary max-height. Can increase if needed. Must have measurement to transition height.
|
||||
transition: visibility 500ms, opacity 500ms, max-height 500ms;
|
||||
transition-timing-function: ease-in-out;
|
||||
}
|
||||
|
||||
&.collapsed {
|
||||
overflow: hidden; // Needed to prevent unnecessary sidenav scrollbar.
|
||||
visibility: hidden;
|
||||
padding-left: 0;
|
||||
opacity: 0;
|
||||
max-height: 1px; // Must have measurement to transition height.
|
||||
transition: visibility 275ms, opacity 275ms, max-height 280ms;
|
||||
transition-timing-function: ease-out;
|
||||
}
|
||||
|
||||
.no-animations &.expanded,
|
||||
.no-animations &.collapsed {
|
||||
transition: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.level-1 {
|
||||
font-family: $main-font;
|
||||
@include font-size(16);
|
||||
@include line-height(28);
|
||||
font-weight: 400;
|
||||
padding-left: 20px;
|
||||
margin: 0;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
.level-2 {
|
||||
font-family: $main-font;
|
||||
@include font-size(14);
|
||||
@include line-height(24);
|
||||
font-weight: 400;
|
||||
margin: 0;
|
||||
padding-left: 36px;
|
||||
}
|
||||
|
||||
.level-3 {
|
||||
font-family: $main-font;
|
||||
@include font-size(14);
|
||||
@include line-height(24);
|
||||
margin: 0;
|
||||
padding-left: 44px;
|
||||
}
|
||||
|
||||
.level-4 {
|
||||
font-family: $main-font;
|
||||
@include font-size(14);
|
||||
@include line-height(24);
|
||||
margin: 0;
|
||||
padding-left: 52px;
|
||||
}
|
||||
|
||||
.level-1, .level-2, .level-3 {
|
||||
&.collapsed > .mat-icon {
|
||||
@include rotate(0deg);
|
||||
}
|
||||
|
||||
&.expanded > .mat-icon {
|
||||
@include rotate(90deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ $hamburgerShownMargin: 0 8px 0 0;
|
||||
$hamburgerHiddenMargin: 0 16px 0 -64px;
|
||||
|
||||
// DOCS PAGE / STANDARD: TOPNAV TOOLBAR FIXED
|
||||
mat-toolbar.mat-toolbar {
|
||||
mat-toolbar.app-toolbar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
@@ -13,6 +13,47 @@ mat-toolbar.mat-toolbar {
|
||||
z-index: 10;
|
||||
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.3);
|
||||
|
||||
// HOME PAGE OVERRIDE: TOPNAV TOOLBAR
|
||||
aio-shell.page-home & {
|
||||
background-color: $blue;
|
||||
|
||||
@media (min-width: 481px) {
|
||||
&:not(.transitioning) {
|
||||
background-color: transparent;
|
||||
transition: background-color 0.2s linear;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARKETING PAGES OVERRIDE: TOPNAV TOOLBAR AND HAMBURGER
|
||||
aio-shell.page-home &,
|
||||
aio-shell.page-features &,
|
||||
aio-shell.page-events &,
|
||||
aio-shell.page-resources & {
|
||||
box-shadow: none;
|
||||
|
||||
// FIXED TOPNAV TOOLBAR FOR SMALL MOBILE
|
||||
@media (min-width: 481px) {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
// DOCS PAGES OVERRIDE: HAMBURGER
|
||||
aio-shell.folder-api &,
|
||||
aio-shell.folder-cli &,
|
||||
aio-shell.folder-docs &,
|
||||
aio-shell.folder-guide &,
|
||||
aio-shell.folder-errors &,
|
||||
aio-shell.folder-start &,
|
||||
aio-shell.folder-tutorial & {
|
||||
@media (min-width: $showTopMenuWidth) {
|
||||
.hamburger {
|
||||
// Hamburger shown on non-marketing pages even on large screens.
|
||||
margin: $hamburgerShownMargin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mat-toolbar-row {
|
||||
padding: 0 16px 0 0;
|
||||
}
|
||||
@@ -20,228 +61,185 @@ mat-toolbar.mat-toolbar {
|
||||
mat-icon {
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
|
||||
// HOME PAGE OVERRIDE: TOPNAV TOOLBAR
|
||||
aio-shell.page-home mat-toolbar.mat-toolbar {
|
||||
background-color: $blue;
|
||||
// HAMBURGER BUTTON
|
||||
.hamburger {
|
||||
height: 100%;
|
||||
margin: $hamburgerShownMargin;
|
||||
padding: 0;
|
||||
|
||||
@media (min-width: 481px) {
|
||||
&:not(.transitioning) {
|
||||
background-color: transparent;
|
||||
transition: background-color 0.2s linear;
|
||||
@media (min-width: $showTopMenuWidth) {
|
||||
// Hamburger hidden by default on large screens.
|
||||
// (Will be shown per doc.)
|
||||
margin: $hamburgerHiddenMargin;
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
min-width: 15%;
|
||||
}
|
||||
|
||||
&:not(.starting) {
|
||||
transition-duration: 0.4s;
|
||||
transition-property: color, margin;
|
||||
transition-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $offwhite;
|
||||
}
|
||||
|
||||
& .mat-icon {
|
||||
color: $white;
|
||||
position: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARKETING PAGES OVERRIDE: TOPNAV TOOLBAR AND HAMBURGER
|
||||
aio-shell.page-home mat-toolbar.mat-toolbar,
|
||||
aio-shell.page-features mat-toolbar.mat-toolbar,
|
||||
aio-shell.page-events mat-toolbar.mat-toolbar,
|
||||
aio-shell.page-resources mat-toolbar.mat-toolbar {
|
||||
box-shadow: none;
|
||||
// HOME NAV-LINK
|
||||
.nav-link.home {
|
||||
cursor: pointer;
|
||||
margin: 0 16px 0 0;
|
||||
padding: 8px 0;
|
||||
|
||||
// FIXED TOPNAV TOOLBAR FOR SMALL MOBILE
|
||||
@media (min-width: 481px) {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
// DOCS PAGES OVERRIDE: HAMBURGER
|
||||
aio-shell.folder-api mat-toolbar.mat-toolbar,
|
||||
aio-shell.folder-cli mat-toolbar.mat-toolbar,
|
||||
aio-shell.folder-docs mat-toolbar.mat-toolbar,
|
||||
aio-shell.folder-guide mat-toolbar.mat-toolbar,
|
||||
aio-shell.folder-errors mat-toolbar.mat-toolbar,
|
||||
aio-shell.folder-start mat-toolbar.mat-toolbar,
|
||||
aio-shell.folder-tutorial mat-toolbar.mat-toolbar {
|
||||
@media (min-width: $showTopMenuWidth) {
|
||||
.hamburger.mat-button {
|
||||
// Hamburger shown on non-marketing pages even on large screens.
|
||||
margin: $hamburgerShownMargin;
|
||||
&:focus {
|
||||
// `outline-offset` is not applied on Chrome on Windows, if `outline-style` is `auto.
|
||||
outline: 1px solid $focus-outline-ondark;
|
||||
outline-offset: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HAMBURGER BUTTON
|
||||
.hamburger.mat-button {
|
||||
height: 100%;
|
||||
margin: $hamburgerShownMargin;
|
||||
padding: 0;
|
||||
@media screen and (max-width: $hideTopMenuWidth) {
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
@media (min-width: $showTopMenuWidth) {
|
||||
// Hamburger hidden by default on large screens.
|
||||
// (Will be shown per doc.)
|
||||
margin: $hamburgerHiddenMargin;
|
||||
}
|
||||
@media screen and (max-width: 480px) {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
min-width: 15%;
|
||||
}
|
||||
img {
|
||||
position: relative;
|
||||
margin-top: -21px;
|
||||
top: 12px;
|
||||
height: 40px;
|
||||
|
||||
&:not(.starting) {
|
||||
transition-duration: 0.4s;
|
||||
transition-property: color, margin;
|
||||
transition-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $offwhite;
|
||||
}
|
||||
|
||||
& .mat-icon {
|
||||
color: $white;
|
||||
position: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
// HOME NAV-LINK
|
||||
.nav-link.home {
|
||||
cursor: pointer;
|
||||
margin: 0 16px 0 0;
|
||||
padding: 8px 0;
|
||||
|
||||
&:focus {
|
||||
// `outline-offset` is not applied on Chrome on Windows, if `outline-style` is `auto.
|
||||
outline: 1px solid $focus-outline-ondark;
|
||||
outline-offset: 4px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: $hideTopMenuWidth) {
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
img {
|
||||
position: relative;
|
||||
margin-top: -21px;
|
||||
top: 12px;
|
||||
height: 40px;
|
||||
|
||||
@media (max-width: $hideTopMenuWidth) {
|
||||
&:hover {
|
||||
transform: scale(1.1);
|
||||
@media (max-width: $hideTopMenuWidth) {
|
||||
&:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TOP MENU
|
||||
aio-top-menu {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
width: 80%;
|
||||
|
||||
ul {
|
||||
// TOP MENU
|
||||
aio-top-menu {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
list-style-position: inside;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
width: 80%;
|
||||
|
||||
li {
|
||||
padding-bottom: 2px;
|
||||
list-style-type: none;
|
||||
cursor: pointer;
|
||||
ul {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
list-style-position: inside;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
|
||||
li {
|
||||
padding-bottom: 2px;
|
||||
list-style-type: none;
|
||||
cursor: pointer;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
a.nav-link {
|
||||
margin: 0 4px;
|
||||
padding: 0px;
|
||||
cursor: pointer;
|
||||
|
||||
.nav-link-inner {
|
||||
border-radius: 4px;
|
||||
padding: 8px 16px;
|
||||
|
||||
&:hover {
|
||||
background: rgba($white, 0.15);
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
|
||||
.nav-link-inner {
|
||||
background: rgba($white, 0.15);
|
||||
border-radius: 1px;
|
||||
box-shadow: 0 0 1px 2px $focus-outline-ondark;
|
||||
}
|
||||
}
|
||||
|
||||
&:active {
|
||||
.nav-link-inner {
|
||||
background: rgba($white, 0.15);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.selected {
|
||||
a.nav-link {
|
||||
.nav-link-inner {
|
||||
background: rgba($white, 0.15);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SEARCH BOX
|
||||
aio-search-box.search-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
min-width: 150px;
|
||||
height: 100%;
|
||||
margin-right: 16px;
|
||||
|
||||
input {
|
||||
color: $darkgray;
|
||||
border: none;
|
||||
border-radius: 100px;
|
||||
background-color: $white;
|
||||
padding: 5px 16px;
|
||||
margin-left: 8px;
|
||||
width: 180px;
|
||||
max-width: 240px;
|
||||
height: 50%;
|
||||
-webkit-appearance: none;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
a.nav-link {
|
||||
margin: 0 4px;
|
||||
padding: 0px;
|
||||
cursor: pointer;
|
||||
@include placeholder {
|
||||
@include font-size(14);
|
||||
color: $mediumgray;
|
||||
}
|
||||
|
||||
.nav-link-inner {
|
||||
border-radius: 4px;
|
||||
padding: 8px 16px;
|
||||
|
||||
&:hover {
|
||||
background: rgba($white, 0.15);
|
||||
}
|
||||
}
|
||||
@include bp(big) {
|
||||
transition: width 0.4s ease-in-out;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
|
||||
.nav-link-inner {
|
||||
background: rgba($white, 0.15);
|
||||
border-radius: 1px;
|
||||
box-shadow: 0 0 1px 2px $focus-outline-ondark;
|
||||
}
|
||||
}
|
||||
|
||||
&:active {
|
||||
.nav-link-inner {
|
||||
background: rgba($white, 0.15);
|
||||
}
|
||||
width: 80%;
|
||||
}
|
||||
}
|
||||
|
||||
&.selected {
|
||||
a.nav-link {
|
||||
.nav-link-inner {
|
||||
background: rgba($white, 0.15);
|
||||
}
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
width: 150px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SEARCH BOX
|
||||
aio-search-box.search-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
min-width: 150px;
|
||||
height: 100%;
|
||||
margin-right: 16px;
|
||||
|
||||
input {
|
||||
color: $darkgray;
|
||||
border: none;
|
||||
border-radius: 100px;
|
||||
background-color: $white;
|
||||
padding: 5px 16px;
|
||||
margin-left: 8px;
|
||||
width: 180px;
|
||||
max-width: 240px;
|
||||
height: 50%;
|
||||
-webkit-appearance: none;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
@include placeholder {
|
||||
@include font-size(14);
|
||||
color: $mediumgray;
|
||||
}
|
||||
|
||||
@include bp(big) {
|
||||
transition: width 0.4s ease-in-out;
|
||||
|
||||
&:focus {
|
||||
width: 80%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
width: 150px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// EXTERNAL LINK ICONS
|
||||
.app-toolbar {
|
||||
// EXTERNAL LINK ICONS
|
||||
.toolbar-external-icons-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
@@ -1,329 +1,153 @@
|
||||
/* API EDIT ICON */
|
||||
#api {
|
||||
.api-filter .material-icons {
|
||||
right: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
/* API LIST STYLES */
|
||||
|
||||
aio-api-list {
|
||||
div.form-search i.material-icons {
|
||||
width: 20px;
|
||||
pointer-events: none;
|
||||
}
|
||||
.api-filter {
|
||||
display: flex;
|
||||
margin: 0 auto;
|
||||
|
||||
.form-search input {
|
||||
width: 182px;
|
||||
@media (max-width: 600px) {
|
||||
flex-direction: column;
|
||||
margin: 16px auto;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
width: 100%;
|
||||
/* API FILTER MENU */
|
||||
aio-select {
|
||||
width: 200px;
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.form-select-menu,
|
||||
.form-search {
|
||||
margin: 8px;
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
aio-select:first-child {
|
||||
.form-select-menu {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.form-search {
|
||||
position: relative;
|
||||
float: left;
|
||||
|
||||
input {
|
||||
box-shadow: 0 2px 2px rgba($black, 0.24), 0 0 2px rgba($black, 0.12);
|
||||
box-sizing: border-box;
|
||||
border: 1px solid $white;
|
||||
border-radius: 4px;
|
||||
color: $darkgray;
|
||||
@include font-size(14);
|
||||
@include line-height(32);
|
||||
outline: none;
|
||||
padding: 4px 16px 4px 32px;
|
||||
transition: all .2s;
|
||||
width: 182px;
|
||||
|
||||
@include placeholder {
|
||||
@include font-size(14);
|
||||
color: $mediumgray;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border: 1px solid $blue-400;
|
||||
box-shadow: 0 2px 2px rgba($blue-400, 0.24), 0 0 2px rgba($blue-400, 0.12);
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.material-icons {
|
||||
color: $blue-grey-600;
|
||||
@include font-size(20);
|
||||
left: 8px;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
width: 20px;
|
||||
z-index: $layer-1;
|
||||
}
|
||||
}
|
||||
|
||||
/* API SEARCH ICON */
|
||||
.material-icons {
|
||||
right: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
/* LAYOUT */
|
||||
|
||||
.api-list-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0 auto;
|
||||
padding-left: 0;
|
||||
max-width: 1100px;
|
||||
padding: 16px 16px 16px 0;
|
||||
position: relative;
|
||||
|
||||
@media handheld and (max-width: $phone-breakpoint),
|
||||
screen and (max-device-width: $phone-breakpoint),
|
||||
screen and (max-width: $tablet-breakpoint) {
|
||||
padding: 24px 0 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-top: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.api-filter {
|
||||
display: flex;
|
||||
margin: 0 auto;
|
||||
|
||||
@media (max-width: 600px) {
|
||||
flex-direction: column;
|
||||
margin: 16px auto;
|
||||
}
|
||||
|
||||
.form-select-menu,
|
||||
.form-search {
|
||||
margin: 8px;
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
aio-select:first-child .form-select-menu {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* LAYOUT */
|
||||
|
||||
.docs-content {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.l-content-small {
|
||||
padding: 16px;
|
||||
max-width: 1100px;
|
||||
margin: 0;
|
||||
|
||||
@media handheld and (max-width: $phone-breakpoint),
|
||||
screen and (max-device-width: $phone-breakpoint),
|
||||
screen and (max-width: $tablet-breakpoint) {
|
||||
padding: 24px 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* SEARCH BAR */
|
||||
|
||||
.form-search {
|
||||
position: relative;
|
||||
|
||||
input {
|
||||
box-shadow: 0 2px 2px rgba($black, 0.24), 0 0 2px rgba($black, 0.12);
|
||||
box-sizing: border-box;
|
||||
border: 1px solid $white;
|
||||
border-radius: 4px;
|
||||
color: $darkgray;
|
||||
@include font-size(14);
|
||||
@include line-height(32);
|
||||
outline: none;
|
||||
padding: 4px 16px 4px 32px;
|
||||
transition: all .2s;
|
||||
|
||||
@include placeholder {
|
||||
@include font-size(14);
|
||||
color: $mediumgray;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border: 1px solid $blue-400;
|
||||
box-shadow: 0 2px 2px rgba($blue-400, 0.24), 0 0 2px rgba($blue-400, 0.12);
|
||||
}
|
||||
}
|
||||
|
||||
.material-icons {
|
||||
color: $blue-grey-600;
|
||||
@include font-size(20);
|
||||
left: 8px;
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
z-index: $layer-1;
|
||||
}
|
||||
}
|
||||
|
||||
/* API SYMBOLS */
|
||||
|
||||
/* SYMBOL CLASS */
|
||||
|
||||
.symbol {
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 1px 2px rgba($black, .24);
|
||||
color: $white;
|
||||
display: inline-block;
|
||||
@include font-size(10);
|
||||
font-weight: 600;
|
||||
@include line-height(16);
|
||||
text-align: center;
|
||||
width: 16px;
|
||||
|
||||
// SYMBOL TYPES
|
||||
// Symbol mapping variables in *constants*
|
||||
@each $name, $symbol in $api-symbols {
|
||||
&.#{$name} {
|
||||
background: map-get($symbol, background);
|
||||
|
||||
&:before {
|
||||
content: map-get($symbol, content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* API HOMEE PAGE */
|
||||
|
||||
/* API FILTER MENU */
|
||||
|
||||
.api-filter {
|
||||
aio-select {
|
||||
width: 200px;
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.symbol {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.form-search {
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
|
||||
/* API CLASS LIST */
|
||||
|
||||
.docs-content .api-list {
|
||||
list-style: none;
|
||||
margin: 0 0 32px -8px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
margin: 0 0 0 -8px;
|
||||
}
|
||||
|
||||
li {
|
||||
@include font-size(14);
|
||||
margin: 8px 0;
|
||||
@include line-height(14);
|
||||
padding: 0;
|
||||
float: left;
|
||||
width: 33%;
|
||||
overflow: hidden;
|
||||
min-width: 220px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
.symbol {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $blue-grey-600;
|
||||
display: inline-block;
|
||||
@include line-height(16);
|
||||
padding: 0 16px 0;
|
||||
text-decoration: none;
|
||||
transition: all .3s;
|
||||
/* API CLASS LIST */
|
||||
.api-list {
|
||||
list-style: none;
|
||||
margin: 0 0 32px -8px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
&:hover {
|
||||
background: $blue-grey-50;
|
||||
color: $blue-500;
|
||||
@media screen and (max-width: 600px) {
|
||||
margin: 0 0 0 -8px;
|
||||
}
|
||||
|
||||
&.deprecated-api-item {
|
||||
text-decoration: line-through;
|
||||
li {
|
||||
@include font-size(14);
|
||||
margin: 8px 0;
|
||||
@include line-height(14);
|
||||
padding: 0;
|
||||
float: left;
|
||||
width: 33%;
|
||||
overflow: hidden;
|
||||
min-width: 220px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
a {
|
||||
color: $blue-grey-600;
|
||||
display: inline-block;
|
||||
@include line-height(16);
|
||||
padding: 0 16px 0;
|
||||
text-decoration: none;
|
||||
transition: all .3s;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
&:hover {
|
||||
background: $blue-grey-50;
|
||||
color: $blue-500;
|
||||
}
|
||||
|
||||
&.deprecated-api-item {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.docs-content .h2-api-docs,
|
||||
.docs-content .h2-api-docs:first-of-type {
|
||||
@include font-size(18);
|
||||
@include line-height(24);
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.code-links {
|
||||
a {
|
||||
code, .api-doc-code {
|
||||
color: #1E88E5 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.openParens {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.endParens {
|
||||
margin-bottom: 20px !important;
|
||||
}
|
||||
|
||||
p {
|
||||
&.selector {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&.location-badge {
|
||||
margin: 0 0 16px 16px !important;
|
||||
}
|
||||
|
||||
.api-doc-code {
|
||||
border-bottom: 0;
|
||||
|
||||
:hover {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.row-margin {
|
||||
margin-bottom: 36px;
|
||||
h2 {
|
||||
@include line-height(28);
|
||||
}
|
||||
}
|
||||
|
||||
.code-margin {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.no-bg {
|
||||
background: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.no-bg-with-indent {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 16px;
|
||||
margin-top: 6px;
|
||||
margin-bottom: 0;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.code-background {
|
||||
padding: 0 5px 0;
|
||||
|
||||
span.pln {
|
||||
color: #1E88E5 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.code-anchor {
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
font-size: inherit;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.api-doc-code {
|
||||
@include font-size(14);
|
||||
color: #1a2326;
|
||||
|
||||
// the last .pln (white space) creates additional spacing between sections of the api doc. Remove it.
|
||||
&.no-pln {
|
||||
.pln:last-child {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
.docs-content {
|
||||
// Overrides display flex from angular material.
|
||||
// This was added because Safari doesn't play nice with layout="column".
|
||||
// Look of API doc in Chrome and Firefox remains the same, and is fixed for Safari.
|
||||
.layout-xs-column {
|
||||
display: block !important;
|
||||
}
|
||||
}
|
||||
|
||||
.api-doc-code {
|
||||
@include font-size(12);
|
||||
}
|
||||
|
||||
p.location-badge {
|
||||
position: relative;
|
||||
@include font-size(11);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,6 +276,7 @@
|
||||
}
|
||||
|
||||
h1 {
|
||||
@include font-size(24);
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/* API SYMBOLS */
|
||||
|
||||
/* SYMBOL CLASS */
|
||||
|
||||
.symbol {
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 1px 2px rgba($black, .24);
|
||||
color: $white;
|
||||
display: inline-block;
|
||||
@include font-size(10);
|
||||
font-weight: 600;
|
||||
@include line-height(16);
|
||||
margin-right: 8px;
|
||||
text-align: center;
|
||||
width: 16px;
|
||||
|
||||
// SYMBOL TYPES
|
||||
// Symbol mapping variables in *constants*
|
||||
@each $name, $symbol in $api-symbols {
|
||||
&.#{$name} {
|
||||
background: map-get($symbol, background);
|
||||
|
||||
&:before {
|
||||
content: map-get($symbol, content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -98,6 +98,23 @@ a.filter-button {
|
||||
}
|
||||
}
|
||||
|
||||
.group-buttons {
|
||||
margin: 32px auto;
|
||||
|
||||
a.selected {
|
||||
background-color: $blue;
|
||||
color: $white;
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.filter-button.button {
|
||||
font-size: 1.2rem;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[mat-button], [mat-raised-button], [mat-button], [mat-raised-button] {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
@@ -1,83 +1,61 @@
|
||||
.card-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
margin: 16px 0;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
margin: 16px 0;
|
||||
|
||||
.docs-card {
|
||||
@include card(194px, 30%);
|
||||
max-width: 340px;
|
||||
min-width: 262px;
|
||||
margin: 24px 8px;
|
||||
padding-bottom: 48px;
|
||||
position: relative;
|
||||
.docs-card {
|
||||
@include card(194px, 35%);
|
||||
max-width: 340px;
|
||||
min-width: 300px;
|
||||
margin: 24px 16px;
|
||||
padding-bottom: 48px;
|
||||
position: relative;
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
width: 100%;
|
||||
margin: 8px auto;
|
||||
max-width: none;
|
||||
}
|
||||
@media screen and (max-width: 600px) {
|
||||
width: 100%;
|
||||
margin: 8px auto;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
section {
|
||||
color: $blue;
|
||||
@include font-size(20);
|
||||
@include line-height(24);
|
||||
margin: 0;
|
||||
padding: 32px 0 24px;
|
||||
text-transform: none;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
section {
|
||||
color: $blue;
|
||||
}
|
||||
p {
|
||||
color: $darkgray;
|
||||
@include font-size(13);
|
||||
@include line-height(24);
|
||||
padding: 0 16px;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
p {
|
||||
color: $darkgray;
|
||||
padding: 0 16px;
|
||||
}
|
||||
.card-footer {
|
||||
color: $darkblue;
|
||||
background-color: rgba($blue, 0.1);
|
||||
bottom: 0;
|
||||
border-top: 0.5px solid $lightgray;
|
||||
box-sizing: border-box;
|
||||
@include line-height(48);
|
||||
left: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
text-align: right;
|
||||
|
||||
.card-footer {
|
||||
@include line-height(32);
|
||||
padding: 8px 16px;
|
||||
background-color: rgba($blue, 0.1);
|
||||
color: $blue;
|
||||
}
|
||||
}
|
||||
|
||||
section {
|
||||
color: $deepgray;
|
||||
@include font-size(20);
|
||||
@include line-height(24);
|
||||
margin: 0;
|
||||
padding: 32px 0 24px;
|
||||
text-transform: none;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
p {
|
||||
color: $darkgray;
|
||||
@include font-size(13);
|
||||
@include line-height(24);
|
||||
padding: 0 16px;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
bottom: 0;
|
||||
border-top: 0.5px solid $lightgray;
|
||||
box-sizing: border-box;
|
||||
@include line-height(48);
|
||||
left: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
text-align: right;
|
||||
a {
|
||||
color: $mediumgray;
|
||||
|
||||
a {
|
||||
color: $mediumgray;
|
||||
@include font-size(13);
|
||||
}
|
||||
}
|
||||
|
||||
.card-footer.center {
|
||||
text-align: center;
|
||||
@include font-size(13);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-section {
|
||||
@@ -107,5 +85,4 @@
|
||||
button {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+110
-102
@@ -1,15 +1,23 @@
|
||||
code-example,
|
||||
code-tabs {
|
||||
clear: both;
|
||||
display: block;
|
||||
clear: both;
|
||||
display: block;
|
||||
|
||||
ol {
|
||||
list-style: decimal;
|
||||
}
|
||||
code {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
ol {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
.mat-card {
|
||||
padding: 0;
|
||||
border-radius: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
code-example {
|
||||
|
||||
&:not(.no-box) {
|
||||
background-color: rgba($backgroundgray, 0.2);
|
||||
border: 0.5px solid $lightgray;
|
||||
@@ -19,9 +27,10 @@ code-example {
|
||||
}
|
||||
|
||||
&.no-box {
|
||||
pre {
|
||||
pre.prettyprint {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: transparent;
|
||||
}
|
||||
@@ -30,34 +39,44 @@ code-example {
|
||||
code {
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
||||
code-example, code-tabs {
|
||||
.mat-card {
|
||||
padding: 0;
|
||||
border-radius: 5px;
|
||||
// TERMINAL / SHELL TEXT STYLES
|
||||
&.code-shell, &[language=sh], &[language=bash] {
|
||||
background-color: $darkgray;
|
||||
}
|
||||
code {
|
||||
overflow: auto;
|
||||
|
||||
header {
|
||||
background-color: $accentblue;
|
||||
border-radius: 5px 5px 0 0;
|
||||
color: $offwhite;
|
||||
@include font-size(16);
|
||||
padding: 8px 16px;
|
||||
}
|
||||
}
|
||||
|
||||
code-tabs {
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
// TERMINAL / SHELL TEXT STYLES
|
||||
.code-tab-group {
|
||||
.mat-tab-label {
|
||||
&:hover {
|
||||
background: rgba(black, 0.04);
|
||||
}
|
||||
}
|
||||
|
||||
code-example.code-shell, code-example[language=sh], code-example[language=bash] {
|
||||
background-color: $darkgray;
|
||||
}
|
||||
.mat-tab-body {
|
||||
overflow-y: hidden;
|
||||
|
||||
code-example header {
|
||||
background-color: $accentblue;
|
||||
border-radius: 5px 5px 0 0;
|
||||
color: $offwhite;
|
||||
@include font-size(16);
|
||||
padding: 8px 16px;
|
||||
.mat-tab-body-content {
|
||||
height: auto;
|
||||
transform: none;
|
||||
|
||||
.fadeIn {
|
||||
animation: opacity 2s ease-in;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
code-example.avoid header,
|
||||
@@ -73,102 +92,89 @@ code-tabs.avoidFile mat-tab-body {
|
||||
border: 0.5px solid $anti-pattern;
|
||||
}
|
||||
|
||||
code-tabs div .mat-tab-body-content {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
code-tabs .mat-tab-body-wrapper mat-tab-body .mat-tab-body {
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
code-tabs mat-tab-body-content .fadeIn {
|
||||
animation: opacity 2s ease-in;
|
||||
}
|
||||
|
||||
aio-code pre {
|
||||
aio-code {
|
||||
pre.prettyprint {
|
||||
position: relative;
|
||||
display: flex;
|
||||
min-height: 32px;
|
||||
margin: 16px 24px;
|
||||
white-space: pre-wrap;
|
||||
align-items: center;
|
||||
|
||||
code span {
|
||||
@include line-height(24);
|
||||
code {
|
||||
span {
|
||||
@include line-height(24);
|
||||
}
|
||||
|
||||
ol.linenums {
|
||||
margin: 0;
|
||||
font-family: $main-font;
|
||||
color: #B3B6B7;
|
||||
|
||||
li {
|
||||
margin: 0;
|
||||
font-family: $code-font;
|
||||
font-size: 90%;
|
||||
@include line-height(24);
|
||||
}
|
||||
}
|
||||
|
||||
.code-missing {
|
||||
color: $darkred;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.copy-button {
|
||||
position: absolute;
|
||||
top: -7px;
|
||||
right: -19px;
|
||||
padding: 0;
|
||||
overflow: visible; // This is required for the button to be displayed correctly in IE11.
|
||||
|
||||
.code-missing {
|
||||
color: $darkred;
|
||||
}
|
||||
color: $blue-grey-200;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: $mediumgray;
|
||||
}
|
||||
}
|
||||
|
||||
.copy-button {
|
||||
position: absolute;
|
||||
top: -7px;
|
||||
right: -19px;
|
||||
padding: 0;
|
||||
overflow: visible; // This is required for the button to be displayed correctly in IE11.
|
||||
&.lang-sh, &.lang-bash {
|
||||
.copy-button {
|
||||
color: $mediumgray;
|
||||
|
||||
color: $blue-grey-200;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
color: $mediumgray;
|
||||
&:hover {
|
||||
color: $lightgray;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.lang-sh .copy-button, .lang-bash .copy-button {
|
||||
color: $mediumgray;
|
||||
&:hover {
|
||||
color: $lightgray;
|
||||
.sidenav-content {
|
||||
code {
|
||||
a {
|
||||
color: inherit;
|
||||
font-size: inherit;
|
||||
font-weight: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.code-tab-group .mat-tab-label {
|
||||
&:hover {
|
||||
background: rgba(black, 0.04);
|
||||
.code-anchor {
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
font-size: inherit;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.code-tab-group .mat-tab-body-content {
|
||||
height: auto;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
|
||||
[role="tabpanel"] {
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.sidenav-content code a {
|
||||
color: inherit;
|
||||
font-size: inherit;
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
/* PRETTY PRINTING STYLES for prettify.js. */
|
||||
|
||||
.prettyprint {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Specify class=linenums on a pre to get line numbering */
|
||||
ol.linenums {
|
||||
margin: 0;
|
||||
font-family: $main-font;
|
||||
color: #B3B6B7;
|
||||
|
||||
li {
|
||||
margin: 0;
|
||||
font-family: $code-font;
|
||||
font-size: 90%;
|
||||
@include line-height(24);
|
||||
}
|
||||
}
|
||||
|
||||
/* The following class|color styles are derived from https://github.com/google/code-prettify/blob/master/src/prettify.css*/
|
||||
|
||||
/* SPAN elements with the classes below are added by prettyprint. */
|
||||
@@ -204,8 +210,10 @@ ol.linenums {
|
||||
|
||||
/* SHELL / TERMINAL CODE BLOCKS */
|
||||
|
||||
code-example.code-shell, code-example[language=sh], code-example[language=bash] {
|
||||
.pnk, .blk, .pln, .otl, .kwd, .typ, .tag, .str, .atv, .atn, .com, .lit, .pun, .dec {
|
||||
color: $codegreen;
|
||||
code-example {
|
||||
&.code-shell, &[language=sh], &[language=bash] {
|
||||
.pnk, .blk, .pln, .otl, .kwd, .typ, .tag, .str, .atv, .atn, .com, .lit, .pun, .dec {
|
||||
color: $codegreen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
aio-contributor-list {
|
||||
@media handheld and (max-width: 480px), screen and (max-width: 480px), screen and (max-width: 900px) {
|
||||
.grid-fluid {
|
||||
width: auto;
|
||||
}
|
||||
.contributor-group {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@media handheld and (max-width: 480px), screen and (max-width: 480px), screen and (max-width: 900px) {
|
||||
@media handheld and (max-width: 480px), screen and (max-width: 900px) {
|
||||
.grid-fluid {
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
@@ -16,32 +17,6 @@ aio-contributor-list {
|
||||
}
|
||||
}
|
||||
|
||||
.group-buttons {
|
||||
margin: 32px auto;
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.filter-button.button {
|
||||
font-size: 1.2rem;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
&.selected {
|
||||
background-color: $blue;
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.contributor-group {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
aio-contributor {
|
||||
background: $white;
|
||||
margin: 8px;
|
||||
@@ -108,7 +83,7 @@ aio-contributor {
|
||||
}
|
||||
}
|
||||
|
||||
div.contributor-card {
|
||||
.contributor-card {
|
||||
width: 250px;
|
||||
height: 270px;
|
||||
display: flex;
|
||||
@@ -156,11 +131,11 @@ aio-contributor {
|
||||
@include line-height(14);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&.flipped {
|
||||
transform:rotateY(180deg);
|
||||
|
||||
.card-front {
|
||||
display: none;
|
||||
}
|
||||
@@ -181,17 +156,6 @@ aio-contributor {
|
||||
transition: all .2s ease-in-out;
|
||||
}
|
||||
|
||||
section {
|
||||
@include font-size(14);
|
||||
font-weight: 500;
|
||||
padding: 8px;
|
||||
margin: 0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
p {
|
||||
cursor: pointer;
|
||||
@include font-size(14);
|
||||
|
||||
@@ -2,44 +2,44 @@
|
||||
* General styling to make detail/summary tags look a bit more material
|
||||
* To get the best out of it you should structure your usage like this:
|
||||
*
|
||||
* ```
|
||||
* ```html
|
||||
* <details>
|
||||
* <summary>Some title</summary>
|
||||
* <div class="details-content">
|
||||
* Some content
|
||||
* </div>
|
||||
* </details>
|
||||
*
|
||||
* </details>
|
||||
* ```
|
||||
*/
|
||||
|
||||
summary {
|
||||
cursor: pointer;
|
||||
@include font-size(16);
|
||||
position: relative;
|
||||
padding: 16px 24px;
|
||||
color: $black;
|
||||
height: 16px;
|
||||
display: block; // Remove the built in details marker in FF
|
||||
|
||||
&::-webkit-details-marker {
|
||||
display: none; // Remove the built in details marker in webkit
|
||||
}
|
||||
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
details {
|
||||
box-shadow: 0 1px 4px 0 rgba($black, 0.37);
|
||||
|
||||
> summary {
|
||||
cursor: pointer;
|
||||
@include font-size(16);
|
||||
position: relative;
|
||||
padding: 16px 24px;
|
||||
color: $black;
|
||||
height: 16px;
|
||||
display: block; // Remove the built in details marker in FF
|
||||
overflow: hidden;
|
||||
|
||||
&::-webkit-details-marker {
|
||||
display: none; // Remove the built in details marker in webkit
|
||||
}
|
||||
|
||||
// Rotate the icon
|
||||
i.material-icons.expand {
|
||||
@include rotate(0deg);
|
||||
|
||||
@at-root #{selector-replace(&, 'details', 'details[open]')} {
|
||||
@include rotate(180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.detail-contents {
|
||||
padding: 16px 24px;
|
||||
}
|
||||
|
||||
// Rotate the icon
|
||||
summary i.material-icons.expand {
|
||||
@include rotate(0deg);
|
||||
}
|
||||
&[open] > summary i.material-icons.expand {
|
||||
@include rotate(180deg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
.edit-page-cta {
|
||||
font-weight: 400;
|
||||
@include font-size(14);
|
||||
color: $blue;
|
||||
text-align: right;
|
||||
margin-right: 32px;
|
||||
display: block;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
}
|
||||
@@ -21,8 +21,6 @@
|
||||
white-space: nowrap;
|
||||
|
||||
.symbol {
|
||||
margin-right: 8px;
|
||||
|
||||
&.runtime {
|
||||
background: $green-500;
|
||||
}
|
||||
@@ -34,11 +32,11 @@
|
||||
|
||||
.symbol.runtime:before {
|
||||
content: "R";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.symbol.compiler:before {
|
||||
content: "C";
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: $blue-grey-600;
|
||||
@@ -70,4 +68,4 @@
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
.reviewed {
|
||||
color: lighten($darkgray, 10);
|
||||
@include font-size(13);
|
||||
font-style: italic;
|
||||
text-align: right;
|
||||
}
|
||||
@@ -7,8 +7,8 @@
|
||||
text-decoration: none;
|
||||
user-select: none;
|
||||
visibility: hidden;
|
||||
display: inline-block;
|
||||
vertical-align: text-top;
|
||||
display: inline-flex;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
&:hover .header-link {
|
||||
|
||||
@@ -1,67 +1,55 @@
|
||||
label.raised, .api-header label {
|
||||
border-radius: 4px;
|
||||
padding: 4px 16px;
|
||||
display: inline;
|
||||
@include font-size(14);
|
||||
color: $white;
|
||||
margin-right: 8px;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
display: block;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
&.page-label {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: $mist;
|
||||
color: $mediumgray;
|
||||
margin-bottom: 8px;
|
||||
width: 140px;
|
||||
|
||||
.material-icons {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
&.property-type-label {
|
||||
@include font-size(12);
|
||||
background-color: $darkgray;
|
||||
color: $white;
|
||||
text-transform: none;
|
||||
}
|
||||
}
|
||||
|
||||
.api-header label {
|
||||
border-radius: 4px;
|
||||
padding: 2px 10px;
|
||||
display: inline;
|
||||
@include font-size(12);
|
||||
color: $white;
|
||||
margin-right: 8px;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
|
||||
// The API badges should be a little smaller
|
||||
padding: 2px 10px;
|
||||
@media screen and (max-width: 600px) {
|
||||
display: block;
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
&.api-status-label {
|
||||
background-color: $mediumgray;
|
||||
|
||||
&.deprecated, &.security, &.impure-pipe {
|
||||
background-color: $brightred;
|
||||
}
|
||||
}
|
||||
|
||||
&.api-type-label {
|
||||
background-color: $accentblue;
|
||||
|
||||
@each $name, $symbol in $api-symbols {
|
||||
&.#{$name} {
|
||||
background: map-get($symbol, background);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.page-label {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: $mist;
|
||||
color: $mediumgray;
|
||||
margin-bottom: 8px;
|
||||
width: 140px;
|
||||
|
||||
.material-icons {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
&.property-type-label {
|
||||
@include font-size(12);
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
&.api-status-label {
|
||||
background-color: $mediumgray;
|
||||
|
||||
&.deprecated, &.security, &.impure-pipe {
|
||||
background-color: $brightred;
|
||||
}
|
||||
}
|
||||
|
||||
&.api-type-label {
|
||||
background-color: $accentblue;
|
||||
|
||||
@each $name, $symbol in $api-symbols {
|
||||
&.#{$name} {
|
||||
background: map-get($symbol, background);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
background-color: $darkgray;
|
||||
color: $white;
|
||||
text-transform: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
@import 'alert';
|
||||
@import 'api-list';
|
||||
@import 'api-pages';
|
||||
@import 'api-symbols';
|
||||
@import 'buttons';
|
||||
@import 'callout';
|
||||
@import 'card';
|
||||
@@ -14,10 +15,10 @@
|
||||
@import 'contributor';
|
||||
@import 'deploy-theme';
|
||||
@import 'details';
|
||||
@import 'edit-page-cta';
|
||||
@import 'errors';
|
||||
@import 'features';
|
||||
@import 'filetree';
|
||||
@import 'guides';
|
||||
@import 'heading-anchors';
|
||||
@import 'hr';
|
||||
@import 'images';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
$notificationHeight: 56px;
|
||||
|
||||
// we need to override some of the toolbar styling
|
||||
.mat-toolbar mat-toolbar-row.notification-container {
|
||||
.app-toolbar mat-toolbar-row.notification-container {
|
||||
padding: 0;
|
||||
height: auto;
|
||||
overflow: hidden;
|
||||
@@ -69,15 +69,17 @@ aio-notification {
|
||||
// Here are all the hacks to make the content and sidebars the right height
|
||||
// when the notification is visible
|
||||
.aio-notification-show {
|
||||
.sidenav-content {
|
||||
padding-top: 80px + $notificationHeight;
|
||||
}
|
||||
mat-sidenav-container.sidenav-container {
|
||||
.sidenav-content {
|
||||
padding-top: 80px + $notificationHeight;
|
||||
}
|
||||
|
||||
mat-sidenav.mat-sidenav.sidenav {
|
||||
top: 64px + $notificationHeight;
|
||||
mat-sidenav.sidenav {
|
||||
top: 64px + $notificationHeight;
|
||||
|
||||
@media (max-width: 600px) {
|
||||
top: 56px + $notificationHeight;
|
||||
@media (max-width: 600px) {
|
||||
top: 56px + $notificationHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +92,7 @@ aio-notification {
|
||||
}
|
||||
|
||||
&.page-home, &.page-resources, &.page-events, &.page-features, &.page-presskit, &.page-contribute {
|
||||
main {
|
||||
.sidenav-content {
|
||||
padding-top: $notificationHeight;
|
||||
}
|
||||
}
|
||||
@@ -104,7 +106,8 @@ aio-notification {
|
||||
.sidenav-content {
|
||||
transition: padding-top 250ms ease;
|
||||
}
|
||||
mat-sidenav.mat-sidenav.sidenav, .toc-container {
|
||||
|
||||
mat-sidenav.sidenav, .toc-container {
|
||||
transition: top 250ms ease;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,6 @@
|
||||
}
|
||||
|
||||
.presskit-image-container {
|
||||
|
||||
@media(max-width: 599px) {
|
||||
text-align: center;
|
||||
}
|
||||
@@ -72,13 +71,13 @@
|
||||
margin-bottom: 8px * 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.presskit-row:first-child {
|
||||
margin-top: 0;
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
|
||||
@media(max-width: 599px) {
|
||||
margin-top: 48px;
|
||||
@media(max-width: 599px) {
|
||||
margin-top: 48px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,106 +1,7 @@
|
||||
.showcase {
|
||||
width: 80%;
|
||||
@media (max-width: 600px) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.c-resource-nav {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.resources-container {
|
||||
position: relative;
|
||||
|
||||
.group-buttons {
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.button {
|
||||
font-size: 1.2rem;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.grid-fixed:after, .grid-fixed:before {
|
||||
content: '.';
|
||||
clear: both;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
@include font-size(0);
|
||||
@include line-height(0);
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
@media handheld and (max-width: 480px), screen and (max-width: 480px), screen and (max-width: 900px) {
|
||||
.grid-fixed {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media handheld and (max-width: 480px), screen and (max-width: 480px), screen and (max-width: 900px) {
|
||||
.grid-fixed .c3, .grid-fixed .c8 {
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
float: none;
|
||||
display: block;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media handheld and (max-width: 480px), screen and (max-width: 480px), screen and (max-width: 480px) {
|
||||
.grid-fixed .c3, .grid-fixed .c8 {
|
||||
margin-left: 0px;
|
||||
margin-right: 0px;
|
||||
float: none;
|
||||
display: block;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media handheld and (max-width: 900px), screen and (max-width: 900px) {
|
||||
/* line 6, ../scss/_responsive.scss */
|
||||
.grid-fixed {
|
||||
margin: 0 auto;
|
||||
*zoom: 1;
|
||||
}
|
||||
.grid-fixed:after, .grid-fixed:before {
|
||||
content: '.';
|
||||
clear: both;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
@include font-size(0);
|
||||
@include line-height(0);
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media handheld and (max-width: 480px), screen and (max-width: 480px) {
|
||||
/* line 6, ../scss/_responsive.scss */
|
||||
.grid-fixed {
|
||||
margin: 0 auto;
|
||||
*zoom: 1;
|
||||
}
|
||||
.grid-fixed:after, .grid-fixed:before {
|
||||
content: '.';
|
||||
clear: both;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
@include font-size(0);
|
||||
@include line-height(0);
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
aio-resource-list {
|
||||
.resources-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.shadow-1 {
|
||||
transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
@@ -108,8 +9,13 @@ aio-resource-list {
|
||||
}
|
||||
|
||||
.showcase {
|
||||
margin-bottom: 8px * 6;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 8px * 6;
|
||||
width: 80%;
|
||||
|
||||
@media (max-width: 600px) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.c-resource {
|
||||
@@ -123,51 +29,6 @@ aio-resource-list {
|
||||
}
|
||||
}
|
||||
|
||||
.c-resource-nav {
|
||||
position: fixed;
|
||||
top: 142px;
|
||||
right: 32px;
|
||||
width: 8px * 20;
|
||||
z-index: 1;
|
||||
background-color: #fff;
|
||||
border-radius: 2px;
|
||||
|
||||
a {
|
||||
color: #373E41;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.category {
|
||||
padding: 10px 0;
|
||||
|
||||
.category-link {
|
||||
display: block;
|
||||
margin: 2px 0;
|
||||
padding: 3px 14px;
|
||||
font-size: 18px !important;
|
||||
font-size: 1.8rem !important;
|
||||
|
||||
&:hover {
|
||||
background: #edf0f2;
|
||||
color: #2B85E7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.subcategory {
|
||||
.subcategory-link {
|
||||
display: block;
|
||||
margin: 2px 0;
|
||||
padding: 4px 14px;
|
||||
|
||||
&:hover {
|
||||
background: #edf0f2;
|
||||
color: #2B85E7;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.h-anchor-offset {
|
||||
display: block;
|
||||
position: relative;
|
||||
@@ -184,18 +45,6 @@ aio-resource-list {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.c-resource-header {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.c-contribute {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.c-resource-header h2 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.subcategory-title {
|
||||
padding: 16px 23px;
|
||||
margin: 0;
|
||||
@@ -203,14 +52,6 @@ aio-resource-list {
|
||||
color: #373E41;
|
||||
}
|
||||
|
||||
.h-capitalize {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.h-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.resource-row-link {
|
||||
color: #1a2326;
|
||||
border: transparent solid 1px;
|
||||
@@ -219,20 +60,14 @@ aio-resource-list {
|
||||
position: relative;
|
||||
text-decoration: none;
|
||||
transition: all .3s;
|
||||
}
|
||||
|
||||
.resource-row-link:hover {
|
||||
color: #1a2326;
|
||||
text-decoration: none;
|
||||
border-color: #2B85E7;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 8px 8px rgba(1, 67, 163, .24), 0 0 8px rgba(1, 67, 163, .12), 0 6px 18px rgba(43, 133, 231, .12);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.c-resource-nav {
|
||||
display: none;
|
||||
&:hover {
|
||||
color: #1a2326;
|
||||
text-decoration: none;
|
||||
border-color: #2B85E7;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 8px 8px rgba(1, 67, 163, .24), 0 0 8px rgba(1, 67, 163, .12), 0 6px 18px rgba(43, 133, 231, .12);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,10 +51,6 @@ aio-search-results {
|
||||
&:hover {
|
||||
color: $white;
|
||||
}
|
||||
|
||||
.symbol {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
&.priority-pages {
|
||||
|
||||
@@ -1,89 +1,91 @@
|
||||
/* SELECT MENU */
|
||||
|
||||
.form-select-menu {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.form-select-button {
|
||||
background: $white;
|
||||
box-shadow: 0 2px 2px rgba($black, 0.24), 0 0 2px rgba($black, 0.12);
|
||||
box-sizing: border-box;
|
||||
border: 1px solid $white;
|
||||
border-radius: 4px;
|
||||
color: $blue-grey-600;
|
||||
@include font-size(14);
|
||||
font-weight: 400;
|
||||
@include line-height(32);
|
||||
outline: none;
|
||||
padding: 4px 16px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
|
||||
strong {
|
||||
font-weight: 600;
|
||||
margin-right: 8px;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border: 1px solid $blue-400;
|
||||
box-shadow: 0 2px 2px rgba($blue-400, 0.24), 0 0 2px rgba($blue-400, 0.12);
|
||||
}
|
||||
|
||||
&[disabled] {
|
||||
color: lightgrey;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
.form-select-dropdown {
|
||||
background: $white;
|
||||
box-shadow: 0 16px 16px rgba($black, 0.24), 0 0 16px rgba($black, 0.12);
|
||||
border-radius: 4px;
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
z-index: $layer-2;
|
||||
|
||||
li {
|
||||
cursor: pointer;
|
||||
@include font-size(14);
|
||||
@include line-height(32);
|
||||
margin: 0;
|
||||
padding: 4px 16px 4px 40px;
|
||||
aio-select {
|
||||
.form-select-menu {
|
||||
position: relative;
|
||||
transition: all .2s;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-radius: 4px 4px 0 0;
|
||||
.form-select-button {
|
||||
background: $white;
|
||||
box-shadow: 0 2px 2px rgba($black, 0.24), 0 0 2px rgba($black, 0.12);
|
||||
box-sizing: border-box;
|
||||
border: 1px solid $white;
|
||||
border-radius: 4px;
|
||||
color: $blue-grey-600;
|
||||
@include font-size(14);
|
||||
font-weight: 400;
|
||||
@include line-height(32);
|
||||
outline: none;
|
||||
padding: 4px 16px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
|
||||
strong {
|
||||
font-weight: 600;
|
||||
margin-right: 8px;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-radius: 0 0 4px 4px;
|
||||
&:focus {
|
||||
border: 1px solid $blue-400;
|
||||
box-shadow: 0 2px 2px rgba($blue-400, 0.24), 0 0 2px rgba($blue-400, 0.12);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $blue-grey-50;
|
||||
color: $blue-500;
|
||||
&[disabled] {
|
||||
color: lightgrey;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background-color: $blue-grey-100;
|
||||
}
|
||||
.form-select-dropdown {
|
||||
background: $white;
|
||||
box-shadow: 0 16px 16px rgba($black, 0.24), 0 0 16px rgba($black, 0.12);
|
||||
border-radius: 4px;
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
z-index: $layer-2;
|
||||
|
||||
.symbol {
|
||||
left: 16px;
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
z-index: $layer-5;
|
||||
li {
|
||||
cursor: pointer;
|
||||
@include font-size(14);
|
||||
@include line-height(32);
|
||||
margin: 0;
|
||||
padding: 4px 16px 4px 40px;
|
||||
position: relative;
|
||||
transition: all .2s;
|
||||
border: 1px solid transparent;
|
||||
|
||||
&:first-child {
|
||||
border-radius: 4px 4px 0 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-radius: 0 0 4px 4px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $blue-grey-50;
|
||||
color: $blue-500;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background-color: $blue-grey-100;
|
||||
}
|
||||
|
||||
.symbol {
|
||||
left: 16px;
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
z-index: $layer-5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+169
-165
@@ -8,201 +8,205 @@
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.toc-inner {
|
||||
@include font-size(13);
|
||||
overflow-y: visible;
|
||||
padding: 4px 0 0 10px;
|
||||
aio-toc {
|
||||
.toc-inner {
|
||||
@include font-size(13);
|
||||
overflow-y: visible;
|
||||
padding: 4px 0 0 10px;
|
||||
|
||||
.toc-heading,
|
||||
.toc-list .h1 {
|
||||
@include font-size(16);
|
||||
}
|
||||
|
||||
.toc-heading {
|
||||
font-weight: 500;
|
||||
margin: 0 0 16px 8px;
|
||||
padding: 0;
|
||||
|
||||
&.secondary {
|
||||
position: relative;
|
||||
top: -8px;
|
||||
|
||||
&:hover {
|
||||
color: $accentblue;
|
||||
}
|
||||
.toc-heading,
|
||||
.toc-list .h1 {
|
||||
@include font-size(16);
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
&.toc-heading,
|
||||
&.toc-more-items {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
background: 0;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
.toc-heading {
|
||||
font-weight: 500;
|
||||
margin: 0 0 16px 8px;
|
||||
padding: 0;
|
||||
text-align: start;
|
||||
|
||||
&.embedded:focus {
|
||||
outline: none;
|
||||
background: $lightgray;
|
||||
}
|
||||
}
|
||||
|
||||
&.toc-heading {
|
||||
mat-icon.rotating-icon {
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
&.secondary {
|
||||
position: relative;
|
||||
left: -4px;
|
||||
top: 5px;
|
||||
}
|
||||
top: -8px;
|
||||
|
||||
&:hover:not(.embedded) {
|
||||
color: $accentblue;
|
||||
&:hover {
|
||||
color: $accentblue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.toc-more-items {
|
||||
color: $mediumgray;
|
||||
top: 10px;
|
||||
position: relative;
|
||||
button {
|
||||
&.toc-heading,
|
||||
&.toc-more-items {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
background: 0;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
padding: 0;
|
||||
text-align: start;
|
||||
|
||||
&:hover {
|
||||
color: $accentblue;
|
||||
&.embedded:focus {
|
||||
outline: none;
|
||||
background: $lightgray;
|
||||
}
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: 'expand_less';
|
||||
}
|
||||
&.toc-heading {
|
||||
mat-icon.rotating-icon {
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
position: relative;
|
||||
left: -4px;
|
||||
top: 5px;
|
||||
}
|
||||
|
||||
&.collapsed::after {
|
||||
content: 'more_horiz';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mat-icon {
|
||||
&.collapsed {
|
||||
@include rotate(0deg);
|
||||
}
|
||||
|
||||
&:not(.collapsed) {
|
||||
@include rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
ul.toc-list {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0 8px 0 0;
|
||||
|
||||
@media (max-width: 800px) {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
li {
|
||||
box-sizing: border-box;
|
||||
padding: 7px 0 7px 12px;
|
||||
position: relative;
|
||||
transition: all 0.3s ease-in-out;
|
||||
|
||||
&.h1:after {
|
||||
content: '';
|
||||
display: block;
|
||||
height: 1px;
|
||||
width: 40%;
|
||||
margin: 7px 0 4px 0;
|
||||
background: $lightgray;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
&.h3 {
|
||||
padding-left: 24px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: lighten($darkgray, 10);
|
||||
overflow: visible;
|
||||
@include font-size(12);
|
||||
@include line-height(16);
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
* {
|
||||
&:hover:not(.embedded) {
|
||||
color: $accentblue;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
* {
|
||||
color: $blue;
|
||||
font-weight: 500;
|
||||
&.toc-more-items {
|
||||
color: $mediumgray;
|
||||
top: 10px;
|
||||
position: relative;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
border-radius: 50%;
|
||||
left: -3px;
|
||||
top: 12px;
|
||||
background: $blue;
|
||||
position: absolute;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
}
|
||||
&:hover {
|
||||
color: $accentblue;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: 'expand_less';
|
||||
}
|
||||
|
||||
&.collapsed::after {
|
||||
content: 'more_horiz';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.embedded) li {
|
||||
&:before {
|
||||
border-left: 1px solid $lightgray;
|
||||
bottom: 0;
|
||||
content: '';
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
.mat-icon {
|
||||
&.collapsed {
|
||||
@include rotate(0deg);
|
||||
}
|
||||
|
||||
&:first-child:before {
|
||||
top: 15px;
|
||||
&:not(.collapsed) {
|
||||
@include rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
ul.toc-list {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0 8px 0 0;
|
||||
|
||||
@media (max-width: 800px) {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
&:last-child:before {
|
||||
bottom: calc(100% - 15px);
|
||||
li {
|
||||
box-sizing: border-box;
|
||||
padding: 7px 0 7px 12px;
|
||||
position: relative;
|
||||
transition: all 0.3s ease-in-out;
|
||||
|
||||
&.h1:after {
|
||||
content: '';
|
||||
display: block;
|
||||
height: 1px;
|
||||
width: 40%;
|
||||
margin: 7px 0 4px 0;
|
||||
background: $lightgray;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
&.h3 {
|
||||
padding-left: 24px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: lighten($darkgray, 10);
|
||||
overflow: visible;
|
||||
@include font-size(14);
|
||||
@include line-height(28);
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
* {
|
||||
color: $accentblue;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
* {
|
||||
color: $blue;
|
||||
font-weight: 500;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
border-radius: 50%;
|
||||
left: -3px;
|
||||
top: 14px;
|
||||
background: $blue;
|
||||
position: absolute;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.active):hover a:before {
|
||||
content: '';
|
||||
border-radius: 50%;
|
||||
left: -3px;
|
||||
top: 12px;
|
||||
background: $lightgray;
|
||||
position: absolute;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
&:not(.embedded) li {
|
||||
&:before {
|
||||
border-left: 1px solid $lightgray;
|
||||
bottom: 0;
|
||||
content: '';
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
&:first-child:before {
|
||||
top: 15px;
|
||||
}
|
||||
|
||||
&:last-child:before {
|
||||
bottom: calc(100% - 15px);
|
||||
}
|
||||
|
||||
&:not(.active):hover a:before {
|
||||
content: '';
|
||||
border-radius: 50%;
|
||||
left: -3px;
|
||||
top: 14px;
|
||||
background: $lightgray;
|
||||
position: absolute;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Alternative TOC View for Smaller Screens
|
||||
&.embedded {
|
||||
@media (min-width: 801px) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.toc-inner {
|
||||
padding: 12px 0 0 0;
|
||||
|
||||
.toc-heading {
|
||||
margin: 0 0 8px;
|
||||
}
|
||||
|
||||
&.collapsed {
|
||||
.secondary {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Alternative TOC View for Smaller Screens
|
||||
aio-toc.embedded {
|
||||
@media (min-width: 801px) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.toc-inner {
|
||||
padding: 12px 0 0 0;
|
||||
|
||||
.toc-heading {
|
||||
margin: 0 0 8px;
|
||||
}
|
||||
}
|
||||
|
||||
> div.collapsed li.secondary {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// TYPOGRAPHY
|
||||
$main-font: "Roboto","Helvetica Neue Light","Helvetica Neue",Helvetica,Arial,"Lucida Grande",sans-serif;
|
||||
$code-font: "Droid Sans Mono", monospace;
|
||||
$code-font: "Roboto Mono", monospace;
|
||||
|
||||
// Z-LAYER
|
||||
$layer-1: 1;
|
||||
@@ -11,12 +11,14 @@ $layer-5: 5;
|
||||
|
||||
// COLOR PALETTE
|
||||
$blue: #1976D2;
|
||||
$darkblue: #1669bb;
|
||||
$accentblue: #1E88E5;
|
||||
$brightred: #DD0031;
|
||||
$darkred: #C3002F;
|
||||
$white: #FFFFFF;
|
||||
$offwhite: #FAFAFA;
|
||||
$backgroundgray: #F1F1F1;
|
||||
$superlightgray: #F2F2F2;
|
||||
$lightgray: #DBDBDB;
|
||||
$lightboxgray: #EBEBEB;
|
||||
$mist: #ECEFF1;
|
||||
|
||||
@@ -185,6 +185,7 @@
|
||||
/guide/service-worker-getstart /guide/service-worker-getting-started
|
||||
/guide/service-worker-comm /guide/service-worker-communications
|
||||
/guide/service-worker-configref /guide/service-worker-config
|
||||
/guide/updating-to-version-10 /guide/updating-to-version-11
|
||||
/guide/webpack https://v5.angular.io/guide/webpack
|
||||
/news https://blog.angular.io/
|
||||
/news.html https://blog.angular.io/
|
||||
|
||||
@@ -18,6 +18,7 @@ module.exports = function processPackages(collectPackageContentDocsProcessor) {
|
||||
// Partition the exports into groups by type
|
||||
if (doc.exports) {
|
||||
const publicExports = doc.exports.filter(doc => !doc.privateExport);
|
||||
doc.hasPublicExports = publicExports.length > 0;
|
||||
doc.ngmodules = publicExports.filter(doc => doc.docType === 'ngmodule').sort(byId);
|
||||
doc.classes = publicExports.filter(doc => doc.docType === 'class').sort(byId);
|
||||
doc.decorators = publicExports.filter(doc => doc.docType === 'decorator').sort(byId);
|
||||
@@ -26,7 +27,7 @@ module.exports = function processPackages(collectPackageContentDocsProcessor) {
|
||||
doc.directives = publicExports.filter(doc => doc.docType === 'directive').sort(byId);
|
||||
doc.pipes = publicExports.filter(doc => doc.docType === 'pipe').sort(byId);
|
||||
doc.types = publicExports.filter(doc => doc.docType === 'type-alias' || doc.docType === 'const').sort(byId);
|
||||
if (publicExports.every(doc => !!doc.deprecated)) {
|
||||
if (doc.hasPublicExports && publicExports.every(doc => !!doc.deprecated)) {
|
||||
doc.deprecated = 'all exports of this entry point are deprecated.';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,6 +163,47 @@ describe('processPackages processor', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should compute whether the entry point has public exports', () => {
|
||||
const docs = [
|
||||
{
|
||||
fileInfo: { filePath: 'some/package-1/index' },
|
||||
docType: 'module',
|
||||
id: 'package-1',
|
||||
exports: [
|
||||
{ docType: 'class', id: 'class-1' },
|
||||
]
|
||||
},
|
||||
{
|
||||
fileInfo: { filePath: 'some/package-1/sub-1index' },
|
||||
docType: 'module',
|
||||
id: 'package-1/sub-1',
|
||||
exports: [],
|
||||
},
|
||||
{
|
||||
fileInfo: { filePath: 'some/package-2/index' },
|
||||
docType: 'module',
|
||||
id: 'package-2',
|
||||
exports: [],
|
||||
},
|
||||
{
|
||||
fileInfo: { filePath: 'some/package-1/sub-1index' },
|
||||
docType: 'module',
|
||||
id: 'package-1/sub-1',
|
||||
exports: [
|
||||
{ docType: 'const', id: 'const-2' },
|
||||
{ docType: 'enum', id: 'enum-3' },
|
||||
],
|
||||
},
|
||||
];
|
||||
const processor = processorFactory({ packageContentFiles: {} });
|
||||
processor.$process(docs);
|
||||
|
||||
expect(docs[0].hasPublicExports).toBeTrue();
|
||||
expect(docs[1].hasPublicExports).toBeFalse();
|
||||
expect(docs[2].hasPublicExports).toBeFalse();
|
||||
expect(docs[3].hasPublicExports).toBeTrue();
|
||||
});
|
||||
|
||||
it('should compute the deprecated status of each entry point', () => {
|
||||
const docs = [
|
||||
{
|
||||
@@ -199,6 +240,12 @@ describe('processPackages processor', () => {
|
||||
{ docType: 'class', id: 'class-6' },
|
||||
]
|
||||
},
|
||||
{
|
||||
fileInfo: { filePath: 'some/package-4/index' },
|
||||
docType: 'module',
|
||||
id: 'package-4',
|
||||
exports: []
|
||||
},
|
||||
];
|
||||
const processor = processorFactory({ packageContentFiles: {} });
|
||||
processor.$process(docs);
|
||||
@@ -207,6 +254,7 @@ describe('processPackages processor', () => {
|
||||
expect(docs[1].deprecated).toBeTruthy();
|
||||
expect(docs[2].deprecated).toBeUndefined();
|
||||
expect(docs[3].deprecated).toBeUndefined();
|
||||
expect(docs[4].deprecated).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should compute the deprecated status of packages', () => {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @reviewed <date-string>
|
||||
*
|
||||
* Use this tag-def to indicate the date when this document was last reviewed.
|
||||
* The date-string will be passed to the `Date()` constructor.
|
||||
*/
|
||||
module.exports = function(createDocMessage) {
|
||||
return {
|
||||
name: 'reviewed',
|
||||
transforms(doc, tag, value) {
|
||||
if (!/^\d{4}-\d{1,2}-\d{1,2}/.test(value.trim())) {
|
||||
throw new Error(createDocMessage(
|
||||
`Tag Error: @${tag.tagName} tag is missing the required date in the form "yyyy-mm-dd" but got "${value}"\n`,
|
||||
doc));
|
||||
}
|
||||
return {
|
||||
date: new Date(value),
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -43,6 +43,9 @@
|
||||
{% endif %}
|
||||
|
||||
<h2>{% if doc.isPrimaryPackage %}Primary entry{% else %}Entry{% endif %} point exports</h2>
|
||||
{% if not doc.hasPublicExports %}
|
||||
<p><i>No public exports.</i></p>
|
||||
{% endif %}
|
||||
{% include "includes/deprecation.html" %}
|
||||
{$ listItems(doc.ngmodules, 'NgModules') $}
|
||||
{$ listItems(doc.classes, 'Classes') $}
|
||||
|
||||
@@ -3,12 +3,13 @@
|
||||
{% set relativePath = doc.fileInfo.relativePath %}
|
||||
{% if doc.title %}{$ ('# ' + doc.title.trim()) | marked $}{% endif %}
|
||||
{% if '/' in relativePath or 'docs.md' in relativePath %}
|
||||
<div class="github-links">
|
||||
{$ github.githubEditLink(doc, versionInfo) $}
|
||||
</div>
|
||||
<div class="github-links">
|
||||
{$ github.githubEditLink(doc, versionInfo) $}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% block content %}
|
||||
<div class="content">
|
||||
{$ doc.description | marked $}
|
||||
{$ doc.description | marked $}
|
||||
{% if doc.reviewed %}<div class="reviewed">Last reviewed on {$ doc.reviewed.date.toDateString() $}</div>{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -1,6 +1,7 @@
|
||||
load("//dev-infra/benchmark/ng_rollup_bundle:ng_rollup_bundle.bzl", "ng_rollup_bundle")
|
||||
load("//tools:defaults.bzl", "ng_module")
|
||||
load("@npm//@bazel/typescript:index.bzl", "ts_devserver", "ts_library")
|
||||
load("@npm//@bazel/typescript:index.bzl", "ts_library")
|
||||
load("@npm//@bazel/concatjs:index.bzl", "concatjs_devserver")
|
||||
load(":benchmark_test.bzl", "benchmark_test")
|
||||
|
||||
def copy_default_file(origin, destination):
|
||||
@@ -113,7 +114,7 @@ def component_benchmark(
|
||||
tsconfig = "//dev-infra/benchmark/component_benchmark:tsconfig-e2e.json",
|
||||
)
|
||||
|
||||
# Bundle the application (needed by ts_devserver).
|
||||
# Bundle the application (needed by concatjs_devserver).
|
||||
ng_rollup_bundle(
|
||||
name = app_main,
|
||||
entry_point = entry_point,
|
||||
@@ -130,7 +131,7 @@ def component_benchmark(
|
||||
)
|
||||
|
||||
# The server for our application.
|
||||
ts_devserver(
|
||||
concatjs_devserver(
|
||||
name = server,
|
||||
bootstrap = ["//packages/zone.js/bundles:zone.umd.js"],
|
||||
port = 4200,
|
||||
|
||||
@@ -28,8 +28,8 @@ function log_verbose(...m) {
|
||||
const useBuildOptimizer = TMPL_build_optimizer;
|
||||
const bannerFile = TMPL_banner_file;
|
||||
const ivyEnabled = 'TMPL_angular_ivy_enabled' === 'True';
|
||||
// `bazel_stamp_file` is a substitution that is applied by `@bazel/rollup`.
|
||||
const stampDataFile = bazel_stamp_file;
|
||||
// `bazel_version_file` is a substitution that is applied by `@bazel/rollup`.
|
||||
const stampDataFile = bazel_version_file;
|
||||
|
||||
log_verbose(`running with
|
||||
cwd: ${process.cwd()}
|
||||
|
||||
@@ -28,7 +28,7 @@ export class Buildifier extends Formatter {
|
||||
commandFlags: `${BAZEL_WARNING_FLAG} --lint=warn --mode=check --format=json`,
|
||||
callback:
|
||||
(_: string, code: number, stdout: string) => {
|
||||
return code !== 0 || !JSON.parse(stdout)['success'];
|
||||
return code !== 0 || !(JSON.parse(stdout) as {success: string}).success;
|
||||
},
|
||||
},
|
||||
format: {
|
||||
|
||||
+4
-2
@@ -2391,7 +2391,7 @@ class Buildifier extends Formatter {
|
||||
check: {
|
||||
commandFlags: `${BAZEL_WARNING_FLAG} --lint=warn --mode=check --format=json`,
|
||||
callback: (_, code, stdout) => {
|
||||
return code !== 0 || !JSON.parse(stdout)['success'];
|
||||
return code !== 0 || !JSON.parse(stdout).success;
|
||||
},
|
||||
},
|
||||
format: {
|
||||
@@ -5885,11 +5885,13 @@ class ReleaseAction {
|
||||
return false;
|
||||
}
|
||||
// Create a cherry-pick pull request that should be merged by the caretaker.
|
||||
const { url } = yield this.pushChangesToForkAndCreatePullRequest(nextBranch, `changelog-cherry-pick-${newVersion}`, commitMessage, `Cherry-picks the changelog from the "${stagingBranch}" branch to the next ` +
|
||||
const { url, id } = yield this.pushChangesToForkAndCreatePullRequest(nextBranch, `changelog-cherry-pick-${newVersion}`, commitMessage, `Cherry-picks the changelog from the "${stagingBranch}" branch to the next ` +
|
||||
`branch (${nextBranch}).`);
|
||||
info(green(` ✓ Pull request for cherry-picking the changelog into "${nextBranch}" ` +
|
||||
'has been created.'));
|
||||
info(yellow(` Please ask team members to review: ${url}.`));
|
||||
// Wait for the Pull Request to be merged.
|
||||
yield this.waitForPullRequestToBeMerged(id);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ describe('ng-dev release build', () => {
|
||||
expect(writeSpy).toHaveBeenCalledTimes(1);
|
||||
|
||||
const jsonText = writeSpy.calls.mostRecent().args[0] as string;
|
||||
const parsed = JSON.parse(jsonText);
|
||||
const parsed = JSON.parse(jsonText) as releaseConfig.BuiltPackage[];
|
||||
|
||||
expect(parsed).toEqual([
|
||||
{name: '@angular/pkg1', outputPath: 'dist/pkg1'},
|
||||
|
||||
@@ -82,7 +82,8 @@ export abstract class ReleaseAction {
|
||||
/** Updates the version in the project top-level `package.json` file. */
|
||||
protected async updateProjectVersion(newVersion: semver.SemVer) {
|
||||
const pkgJsonPath = join(this.projectDir, packageJsonPath);
|
||||
const pkgJson = JSON.parse(await fs.readFile(pkgJsonPath, 'utf8'));
|
||||
const pkgJson =
|
||||
JSON.parse(await fs.readFile(pkgJsonPath, 'utf8')) as {version: string, [key: string]: any};
|
||||
pkgJson.version = newVersion.format();
|
||||
// Write the `package.json` file. Note that we add a trailing new line
|
||||
// to avoid unnecessary diff. IDEs usually add a trailing new line.
|
||||
@@ -450,7 +451,7 @@ export abstract class ReleaseAction {
|
||||
}
|
||||
|
||||
// Create a cherry-pick pull request that should be merged by the caretaker.
|
||||
const {url} = await this.pushChangesToForkAndCreatePullRequest(
|
||||
const {url, id} = await this.pushChangesToForkAndCreatePullRequest(
|
||||
nextBranch, `changelog-cherry-pick-${newVersion}`, commitMessage,
|
||||
`Cherry-picks the changelog from the "${stagingBranch}" branch to the next ` +
|
||||
`branch (${nextBranch}).`);
|
||||
@@ -459,6 +460,10 @@ export abstract class ReleaseAction {
|
||||
` ✓ Pull request for cherry-picking the changelog into "${nextBranch}" ` +
|
||||
'has been created.'));
|
||||
info(yellow(` Please ask team members to review: ${url}.`));
|
||||
|
||||
// Wait for the Pull Request to be merged.
|
||||
await this.waitForPullRequestToBeMerged(id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -554,7 +559,8 @@ export abstract class ReleaseAction {
|
||||
private async _verifyPackageVersions(version: semver.SemVer, packages: BuiltPackage[]) {
|
||||
for (const pkg of packages) {
|
||||
const {version: packageJsonVersion} =
|
||||
JSON.parse(await fs.readFile(join(pkg.outputPath, 'package.json'), 'utf8'));
|
||||
JSON.parse(await fs.readFile(join(pkg.outputPath, 'package.json'), 'utf8')) as
|
||||
{version: string, [key: string]: any};
|
||||
if (version.compare(packageJsonVersion) !== 0) {
|
||||
error(red('The built package version does not match the version being released.'));
|
||||
error(` Release Version: ${version.version}`);
|
||||
|
||||
@@ -64,7 +64,7 @@ export async function invokeReleaseBuildCommand(): Promise<BuiltPackage[]> {
|
||||
info(green(' ✓ Built release output for all packages.'));
|
||||
// The `ng-dev release build` command prints a JSON array to stdout
|
||||
// that represents the built release packages and their output paths.
|
||||
return JSON.parse(stdout.trim());
|
||||
return JSON.parse(stdout.trim()) as BuiltPackage[];
|
||||
} catch (e) {
|
||||
spinner.stop();
|
||||
error(e);
|
||||
|
||||
@@ -93,7 +93,8 @@ describe('common release action logic', () => {
|
||||
// it is properly appended. Also expect a pull request to be created in the fork.
|
||||
repo.expectChangelogFetch(branchName, fakeReleaseNotes)
|
||||
.expectFindForkRequest(fork)
|
||||
.expectPullRequestToBeCreated('master', fork, forkBranchName, 200);
|
||||
.expectPullRequestToBeCreated('master', fork, forkBranchName, 200)
|
||||
.expectPullRequestWait(200);
|
||||
|
||||
// Simulate that the fork branch name is available.
|
||||
fork.expectBranchRequest(forkBranchName, null);
|
||||
@@ -119,7 +120,8 @@ describe('common release action logic', () => {
|
||||
// it is properly appended. Also expect a pull request to be created in the fork.
|
||||
repo.expectChangelogFetch(branchName, customReleaseNotes)
|
||||
.expectFindForkRequest(fork)
|
||||
.expectPullRequestToBeCreated('master', fork, forkBranchName, 200);
|
||||
.expectPullRequestToBeCreated('master', fork, forkBranchName, 200)
|
||||
.expectPullRequestWait(200);
|
||||
|
||||
// Simulate that the fork branch name is available.
|
||||
fork.expectBranchRequest(forkBranchName, null);
|
||||
@@ -138,7 +140,8 @@ describe('common release action logic', () => {
|
||||
// it is properly appended. Also expect a pull request to be created in the fork.
|
||||
repo.expectChangelogFetch(branchName, `non analyzable changelog`)
|
||||
.expectFindForkRequest(fork)
|
||||
.expectPullRequestToBeCreated('master', fork, forkBranchName, 200);
|
||||
.expectPullRequestToBeCreated('master', fork, forkBranchName, 200)
|
||||
.expectPullRequestWait(200);
|
||||
|
||||
// Simulate that the fork branch name is available.
|
||||
fork.expectBranchRequest(forkBranchName, null);
|
||||
@@ -166,7 +169,8 @@ describe('common release action logic', () => {
|
||||
// it is properly appended. Also expect a pull request to be created in the fork.
|
||||
repo.expectChangelogFetch(branchName, fakeReleaseNotes)
|
||||
.expectFindForkRequest(fork)
|
||||
.expectPullRequestToBeCreated('master', fork, forkBranchName, 200);
|
||||
.expectPullRequestToBeCreated('master', fork, forkBranchName, 200)
|
||||
.expectPullRequestWait(200);
|
||||
|
||||
// Simulate that the fork branch name is available.
|
||||
fork.expectBranchRequest(forkBranchName, null);
|
||||
|
||||
@@ -49,7 +49,7 @@ describe('cut next pre-release action', () => {
|
||||
await expectStagingAndPublishWithoutCherryPick(action, 'master', '10.2.0-next.0', 'next');
|
||||
|
||||
const pkgJsonContents = readFileSync(join(action.testTmpDir, packageJsonPath), 'utf8');
|
||||
const pkgJson = JSON.parse(pkgJsonContents);
|
||||
const pkgJson = JSON.parse(pkgJsonContents) as {version: string, [key: string]: any};
|
||||
expect(pkgJson.version).toBe('10.2.0-next.0', 'Expected version to not have changed.');
|
||||
});
|
||||
|
||||
|
||||
@@ -194,7 +194,8 @@ export async function expectStagingAndPublishWithCherryPick(
|
||||
.expectTagToBeCreated(expectedTagName, 'STAGING_COMMIT_SHA')
|
||||
.expectReleaseToBeCreated(`v${expectedVersion}`, expectedTagName)
|
||||
.expectChangelogFetch(expectedBranch, getChangelogForVersion(expectedVersion))
|
||||
.expectPullRequestToBeCreated('master', fork, expectedCherryPickForkBranch, 300);
|
||||
.expectPullRequestToBeCreated('master', fork, expectedCherryPickForkBranch, 300)
|
||||
.expectPullRequestWait(300);
|
||||
|
||||
// In the fork, we make the staging and cherry-pick branches appear as
|
||||
// non-existent, so that the PRs can be created properly without collisions.
|
||||
|
||||
@@ -35,7 +35,8 @@ export async function getVersionOfBranch(
|
||||
repo: GithubRepoWithApi, branchName: string): Promise<semver.SemVer> {
|
||||
const {data} = await repo.api.repos.getContents(
|
||||
{owner: repo.owner, repo: repo.name, path: '/package.json', ref: branchName});
|
||||
const {version} = JSON.parse(Buffer.from(data.content, 'base64').toString());
|
||||
const {version} = JSON.parse(Buffer.from(data.content, 'base64').toString()) as
|
||||
{version: string, [key: string]: any};
|
||||
const parsedVersion = semver.parse(version);
|
||||
if (parsedVersion === null) {
|
||||
throw Error(`Invalid version detected in following branch: ${branchName}.`);
|
||||
|
||||
@@ -93,7 +93,7 @@ export function main(
|
||||
info(yellow(` Please rerun with "--warnings" to inspect unresolved imports.`));
|
||||
}
|
||||
|
||||
const expected: Golden = JSON.parse(readFileSync(goldenFile, 'utf8'));
|
||||
const expected = JSON.parse(readFileSync(goldenFile, 'utf8')) as Golden;
|
||||
const {fixedCircularDeps, newCircularDeps} = compareGoldens(actual, expected);
|
||||
const isMatching = fixedCircularDeps.length === 0 && newCircularDeps.length === 0;
|
||||
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
# Angular Branching and Versioning: A Practical Guide
|
||||
|
||||
This guide explains how the Angular team manages branches and how those branches relate to
|
||||
merging PRs and publishing releases. Before reading, you should understand
|
||||
[Semantic Versioning](https://semver.org/#semantic-versioning-200).
|
||||
|
||||
## Distribution tags on npm
|
||||
|
||||
Angular's branching relates directly to versions published on npm. We will reference these [npm
|
||||
distribution tags](https://docs.npmjs.com/cli/v6/commands/npm-dist-tag#purpose) throughout:
|
||||
|
||||
| Tag | Description |
|
||||
|--------|-----------------------------------------------------------------------------------|
|
||||
| latest | The most recent stable version. |
|
||||
| next | The most recent pre-release version of Angular for testing. May not always exist. |
|
||||
| v*-lts | The most recent LTS release for the specified version, such as `v9-lts`. |
|
||||
|
||||
## Branch naming
|
||||
|
||||
Angular's main branch is `master`. This branch always represents the absolute latest changes. The
|
||||
code on master always represents a pre-release version, often published with the `next` tag on npm.
|
||||
|
||||
For each minor and major version increment, a new branch is created. These branches use a naming
|
||||
scheme matching `\d+\.\d+\.x` and receive subsequent patch changes for that version range. For
|
||||
example, the `10.2.x` branch represents the latest patch changes for subsequent releases starting
|
||||
with `10.2.`. The version tagged on npm as `latest` will always correspond to such a branch,
|
||||
referred to as the **active patch branch**.
|
||||
|
||||
## Major releases lifecycle
|
||||
|
||||
Angular releases a major version roughly every six months. Following a major release, we move
|
||||
through a consistent lifecycle to the next major release, and repeat. At a high level, this
|
||||
process proceeds as follows:
|
||||
|
||||
* A major release occurs. The `master` branch now represents the next minor version.
|
||||
* Six weeks later, a minor release occurs. The `master` branch now represents the next minor
|
||||
version.
|
||||
* Six weeks later, a second minor release occurs. The `master` branch now represents the next major
|
||||
version.
|
||||
* Three months later, a major release occurs and the process repeats.
|
||||
|
||||
### Example
|
||||
* Angular publishes `11.0.0`. At this point in time, the `master` branch represents `11.1.0`.
|
||||
* Six weeks later, we publish `11.1.0` and `master` represents `11.2.0`.
|
||||
* Six weeks later, we publish `11.2.0` and `master` represents `12.0.0`.
|
||||
* Three months later, this cycle repeats with the publication of `12.0.0`.
|
||||
|
||||
### Feature freeze and release candidates
|
||||
|
||||
Before publishing minor and major versions as `latest` on npm, they go through a feature freeze and
|
||||
a release candidate (RC) phase.
|
||||
|
||||
**Feature freeze** means that `master` is forked into a branch for a specific version, with no
|
||||
additional features permitted before releasing as `latest` to npm. This branch becomes the **active
|
||||
RC branch**. Upon branching, the `master` branch increments to the next minor or major pre-release
|
||||
version. One week after feature freeze, the first RC is published with the `next` tag on npm from
|
||||
the active RC branch. Patch bug fixes continue to merge into `master`, the active RC branch, and
|
||||
the active patch branch during this entire period.
|
||||
|
||||
One to three weeks after publishing the first RC, the active RC branch is published as `latest` on
|
||||
npm and the branch becomes the active patch branch. At this point there is no active RC branch until
|
||||
the next minor or major release.
|
||||
|
||||
## Targeting pull requests
|
||||
|
||||
Every pull request has a **base branch**:
|
||||
|
||||

|
||||
|
||||
This base branch represents the latest branch that will receive the change. Most pull requests
|
||||
should specify `master`. However, some changes will explicitly use an earlier branch, such as
|
||||
`11.1.x`, in order to patch an older version. Specific GitHub labels, described below, control the
|
||||
additional branches into which a pull request will be cherry-picked.
|
||||
|
||||
### Labelling pull requests
|
||||
|
||||
There are five labels that target PRs to versions:
|
||||
|
||||
| Label | Description |
|
||||
|---------------|-----------------------------------------------------------------------------|
|
||||
| target: major | A change that includes a backwards-incompatible behavior or API change. |
|
||||
| target: minor | A change that introduces a new, backwards-compatible functionality. |
|
||||
| target: patch | A backwards-compatible bug fix. |
|
||||
| target: rc | A change that should be explicitly included in an active release candidate. |
|
||||
| target: lts | A critical security or browser compatibility fix for LTS releases. |
|
||||
|
||||
Every PR must have exactly one `target: *` label. Angular's dev tooling will merge the pull request
|
||||
into its base branch and then cherry-pick the commits to the appropriate branches based on the
|
||||
specified target label.
|
||||
|
||||
The vast majority of pull requests will target `major`, `minor`, or `patch` based on the contents of
|
||||
the code change. In rare cases, a pull request will specify `target: rc` or `target: lts` to
|
||||
explicitly target a special branch.
|
||||
|
||||
Breaking changes, marked with `target: major`, can only be merged when `master` represents the next
|
||||
major version.
|
||||
|
||||
### Pull request examples
|
||||
|
||||
| I want to... | Target branch | Target label | Your change will land in... |
|
||||
|-------------------------------------------------------------|-------------------------|--------------|------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Make a non-breaking bug fix | `master` | `patch` | `master`, the active patch branch, and the active RC branch if there is one |
|
||||
| Introduce a new feature | `master` | `minor` | `master` (any time) |
|
||||
| Make a breaking change | `master` | `major` | `master` (only when `master` represents the next major version) |
|
||||
| Make a critical security fix | `master` | `lts` | `master`, the active patch branch, the active RC branch if there is one, and all branches for versions within the LTS window |
|
||||
| Bump the version of an RC | the active RC branch | `rc` | The active RC branch |
|
||||
| Fix an RC bug for a major release feature | `master` | `rc` | `master` and the active RC branch |
|
||||
| Backport a bug fix to the `latest` npm version during an RC | the active patch branch | `patch` | the active patch branch only |
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user