docs(dev guide): Update 'Component Styles' prose (#1320)

Reowork Ts prose and add Dart prose/code

+ Updates to docs and example code

(Starting point for Dart code was taken from #1171.)
This commit is contained in:
Patrice Chalin 2016-05-10 00:51:23 -07:00 committed by Thibault Sottiaux
parent 6d80a42bea
commit ef66e38e54
25 changed files with 366 additions and 96 deletions

View File

@ -11,6 +11,10 @@
//- preceded by the article "a". (E.g., will be "annotation" for Dart)
- var _decorator = 'decorator';
//- TS arrays vs. Dart lists
- var _array = 'array';
- var _an_array = 'an array';
//- Used to prefix identifiers that are private. In Dart this will be '_'.
- var _priv = '';

View File

@ -0,0 +1,8 @@
class Hero {
bool active = false;
final String name;
final List<String> team;
Hero(this.name, this.team);
}

View File

@ -0,0 +1,21 @@
import 'package:angular2/core.dart';
import 'hero.dart';
import 'hero_app_main_component.dart';
// #docregion
@Component(
selector: 'hero-app',
template: '''
<h1>Tour of Heroes</h1>
<hero-app-main [hero]="hero"></hero-app-main>''',
styles: const ['h1 { font-weight: normal; }'],
directives: const [HeroAppMainComponent])
class HeroAppComponent {
// #enddocregion
Hero hero =
new Hero('Human Torch', ['Mister Fantastic', 'Invisible Woman', 'Thing']);
@HostBinding('class')
String get themeClass => 'theme-light';
// #docregion
}

View File

@ -0,0 +1,22 @@
import 'package:angular2/core.dart';
import 'hero.dart';
import 'hero_details_component.dart';
import 'hero_controls_component.dart';
import 'quest_summary_component.dart';
@Component(
selector: 'hero-app-main',
template: '''
<quest-summary></quest-summary>
<hero-details [hero]="hero" [class.active]="hero.active">
<hero-controls [hero]="hero"></hero-controls>
</hero-details>''',
directives: const [
HeroDetailsComponent,
HeroControlsComponent,
QuestSummaryComponent
])
class HeroAppMainComponent {
@Input() Hero hero;
}

View File

@ -0,0 +1,23 @@
import 'package:angular2/core.dart';
import 'hero.dart';
// #docregion inlinestyles
@Component(
selector: 'hero-controls',
template: '''
<style>
button {
background-color: white;
border: 1px solid #777;
}
</style>
<h3>Controls</h3>
<button (click)="activate()">Activate</button>''')
class HeroControlsComponent {
@Input()
Hero hero;
void activate() {
hero.active = true;
}
}

View File

@ -0,0 +1,6 @@
:host {
padding: 10px;
}
h3 {
background-color: yellow;
}

View File

@ -0,0 +1,32 @@
/* #docregion import */
/* pub build fails on
@ import 'hero_details_box.css';
See https://github.com/angular/angular/issues/8518 */
@import '/packages/component_styles/hero_details_box.css';
/* #enddocregion import */
/* #docregion host */
:host {
display: block;
border: 1px solid black;
}
/* #enddocregion host */
/* #docregion hostfunction */
:host(.active) {
border-width: 3px;
}
/* #enddocregion hostfunction */
/* #docregion hostcontext */
:host-context(.theme-light) h2 {
background-color: #eef;
}
/* #enddocregion hostcontext */
/* #docregion deep */
:host /deep/ h3 {
font-style: italic;
}
/* #enddocregion deep */

View File

@ -0,0 +1,18 @@
import 'package:angular2/core.dart';
import 'hero.dart';
import 'hero_team_component.dart';
// #docregion styleurls
@Component(
selector: 'hero-details',
template: '''
<h2>{{hero.name}}</h2>
<hero-team [hero]=hero></hero-team>
<ng-content></ng-content>''',
styleUrls: const ['hero_details_component.css'],
directives: const [HeroTeamComponent])
class HeroDetailsComponent {
// #enddocregion styleurls
@Input() Hero hero;
// #docregion styleurls
}

View File

@ -0,0 +1,3 @@
li {
list-style-type: square;
}

View File

@ -0,0 +1,17 @@
import 'package:angular2/core.dart';
import 'hero.dart';
// #docregion stylelink
@Component(
selector: 'hero-team',
template: '''
<link rel="stylesheet" href="hero_team_component.css">
<h3>Team</h3>
<ul>
<li *ngFor="let member of hero.team">
{{member}}
</li>
</ul>''')
class HeroTeamComponent {
@Input() Hero hero;
}

View File

@ -0,0 +1,5 @@
:host {
display: block;
background-color: green;
color: white;
}

View File

@ -0,0 +1,18 @@
// #docplaster
import 'package:angular2/core.dart';
// #docregion
@Component(
selector: 'quest-summary',
// #docregion urls
templateUrl: 'quest_summary_component.html',
styleUrls: const ['quest_summary_component.css'])
// #enddocregion urls
class QuestSummaryComponent {}
// #enddocregion
/*
// #docregion encapsulation.native
// warning: few browsers support shadow DOM encapsulation at this time
encapsulation: ViewEncapsulation.Native
// #enddocregion encapsulation.native
*/

View File

@ -0,0 +1 @@
<p>No quests in progress</p>

View File

@ -0,0 +1,15 @@
# #docregion
name: component_styles
description: Component Styles example
version: 0.0.1
environment:
sdk: '>=1.13.0 <2.0.0'
dependencies:
angular2: 2.0.0-beta.17
browser: ^0.10.0
dart_to_js_script_rewriter: ^1.0.1
transformers:
- angular2:
platform_directives: 'package:angular2/common.dart#COMMON_DIRECTIVES'
entry_points: web/main.dart
- dart_to_js_script_rewriter

View File

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<title>Component Styles</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<script defer src="main.dart" type="application/dart"></script>
<script defer src="packages/browser/dart.js"></script>
</head>
<body>
<h1 style="visibility: hidden;">External H1 Title for E2E test</h1>
<hero-app></hero-app>
<button style="visibility: hidden;">External button for E2E test</button>
<ul style="visibility: hidden;">
<li>External list for E2E test</li>
</ul>
</body>
</html>

View File

@ -0,0 +1,6 @@
import 'package:angular2/platform/browser.dart';
import 'package:component_styles/hero_app_component.dart';
main() {
bootstrap(HeroAppComponent);
}

View File

@ -11,8 +11,8 @@ import { HeroAppMainComponent } from './hero-app-main.component';
styles: ['h1 { font-weight: normal; }'],
directives: [HeroAppMainComponent]
})
// #enddocregion
export class HeroAppComponent {
// #enddocregion
hero = new Hero(
'Human Torch',
['Mister Fantastic', 'Invisible Woman', 'Thing']
@ -21,5 +21,6 @@ export class HeroAppComponent {
@HostBinding('class') get themeClass() {
return 'theme-light';
}
// #docregion
}
// #enddocregion

View File

@ -17,7 +17,6 @@ import { Hero } from './hero';
})
// #enddocregion inlinestyles
export class HeroControlsComponent {
@Input() hero: Hero;
activate() {

View File

@ -15,6 +15,6 @@ import { HeroTeamComponent } from './hero-team.component';
})
export class HeroDetailsComponent {
// #enddocregion styleurls
@Input() hero: Hero;
// #docregion styleurls
}

View File

@ -1 +1 @@
No quests in progress
<p>No quests in progress</p>

View File

@ -3,7 +3,6 @@
import { Component, ViewEncapsulation } from '@angular/core';
// #docregion
@Component({
moduleId: module.id,
selector: 'quest-summary',
@ -11,6 +10,8 @@ import { Component, ViewEncapsulation } from '@angular/core';
templateUrl: 'quest-summary.component.html',
styleUrls: ['quest-summary.component.css']
// #enddocregion urls
})
export class QuestSummaryComponent { }
// #enddocregion
/*
// #docregion encapsulation.native
@ -18,7 +19,3 @@ import { Component, ViewEncapsulation } from '@angular/core';
encapsulation: ViewEncapsulation.Native
// #enddocregion encapsulation.native
*/
// #docregion
})
export class QuestSummaryComponent { }
// #enddocregion

View File

@ -3,6 +3,8 @@ include ../../../_includes/_util-fns
//- See the _util-fns file included above for a description of the use of these variables.
- var _docsFor = 'dart';
- var _decorator = 'annotation';
- var _array = 'list';
- var _an_array = 'a list';
- var _priv = '_';
mixin liveExampleLink(linkText, exampleUrlPartName)

View File

@ -1 +1,36 @@
!= partial("../../../_includes/_ts-temp")
extends ../../../ts/latest/guide/component-styles.jade
block includes
include ../_util-fns
//- TODO: consider adding material equivalent to TS Appendices 1 & 2 if relevant.
block style-url
:marked
Note that the URLs in `styleUrls` are relative to the component.
block module-bundlers
//- TODO: determine if an equivalent of the TS material is relevant for Dart.
//- Leaving empty for now.
block css-import-url
:marked
In *this* case the URL is relative to the CSS file into which we are importing.
.alert.is-important
:marked
URLs are currently not interpreted in this way, see
[issue 8518](href="https://github.com/angular/angular/issues/8518").
Until this issue is fixed, absolute package-reference style URLs must
be given as is illustrated below.
block module-id
p.
Thankfully, this is the default interpretation of relative URLs in
Angular2 for Dart:
+makeExample('component-styles/ts/app/quest-summary.component.ts', 'urls')(format='.')
:marked
Note that special measures must be taken in Angular2 for TypeScript, if
relative URLs are to have the same interpretation. See
[here](../../../ts/latest/guide/component-styles.html#!#relative-urls)
for details.

View File

@ -2,8 +2,7 @@ include ../../../_includes/_util-fns
//- See the _util-fns file included above for a description of the use of these variables.
- var _docsFor = 'ts';
- var _decorator = 'decorator';
- var _priv = '';
//- Other values match the defaults.
mixin liveExampleLink(linkText, exampleUrlPartName)
a(href='/resources/live-examples/#{exampleUrlPartName}/ts/plnkr.html')= linkText

View File

@ -1,3 +1,4 @@
block includes
include ../_util-fns
:marked
@ -14,13 +15,13 @@ include ../_util-fns
* [Using Component Styles](#using-component-styles)
* [Special selectors](#special-selectors)
* [Loading Styles into Components](#loading-style)
* [Controlling View Encapsulation: Emulated, Native, and None](#controlling-view-encapsulation-native-emulated-and-none)
* [Loading Styles into Components](#loading-styles)
* [Controlling View Encapsulation: Emulated, Native, and None](#view-encapsulation)
* [Appendix 1: Inspecting the generated runtime component styles](#inspect-generated-css)
* [Appendix 2: Loading Styles with Relative URLs](#relative-urls)
**[Run the live code](/resources/live-examples/component-styles/ts/plnkr.html)
shown in this chapter.**
p
| #[+liveExampleLink2('Run the live example', 'component-styles')]&nbsp;
| of the code shown in this chapter.
.l-main-section
:marked
@ -31,7 +32,7 @@ include ../_util-fns
specifying any selectors, rules, and media queries that we need.
One way to do this is to set the `styles` property in the component metadata.
The `styles` property takes an array of strings that contain CSS code.
The `styles` property takes #{_an_array} of strings that contain CSS code.
Usually we give it one string as in this example:
+makeExample('component-styles/ts/app/hero-app.component.ts')(format='.')
@ -40,7 +41,7 @@ include ../_util-fns
Component styles differ from traditional, global styles in a couple of ways.
Firstly, the selectors we put into a component's styles *only apply withing the template
of that component*. The `h1 { }` selector in the example above only applies to the `<h1>` tag
of that component*. The `h1` selector in the example above only applies to the `<h1>` tag
in the template of `HeroAppComponent`. Any `<h1>` elements elsewhere in
the application are unaffected.
@ -65,7 +66,7 @@ a(id="special-selectors")
## Special selectors
Component styles have a few special *selectors* from the world of
<a href="https://www.w3.org/TR/css-scoping-1/" target="_blank">shadow DOM style scoping</a>.
[shadow DOM style scoping](https://www.w3.org/TR/css-scoping-1):
### :host
@ -122,7 +123,7 @@ a(id="special-selectors")
:marked
The `/deep/` and `>>>` selectors should only be used with **emulated** view encapsulation.
This is the default and it is what we use most of the time. See the
[Controlling View Encapsulation](#controlling-view-encapsulation-native-emulated-and-none)
[Controlling View Encapsulation](#view-encapsulation)
section for more details.
a(id='loading-styles')
@ -139,8 +140,8 @@ a(id='loading-styles')
### Styles in Metadata
We can add a `styles` array property to the `@Component` decorator.
Each string in the array (usually just one string) defines the css.
We can add a `styles` #{_array} property to the `@Component` #{_decorator}.
Each string in the #{_array} (usually just one string) defines the CSS.
+makeExample('component-styles/ts/app/hero-app.component.ts')
@ -156,37 +157,42 @@ a(id='loading-styles')
### Style URLs in Metadata
We can load styles from external CSS files by adding a `styleUrls` attribute
into a component's `@Component` or `@View` decorator:
into a component's `@Component` or `@View` #{_decorator}:
+makeExample('component-styles/ts/app/hero-details.component.ts', 'styleurls')
block style-url
.alert.is-important
:marked
The URL is ***relative to the application root*** which is usually the
location of the `index.html` web page that hosts the application.
The style file URL is *not* relative to the component file.
That's why the example URL begins `app/`.
See [Appendix 2](#relative-urls) to specify a URL relative to the component file.
See [Appendix 2](#relative-urls) to specify a URL relative to the
component file.
block module-bundlers
.l-sub-section
:marked
Users of module bundlers like Webpack may also use the `styles` attribute to load
styles from external files at build time. They could write:
Users of module bundlers like Webpack may also use the `styles` attribute
to load styles from external files at build time. They could write:
`styles: [require('my.component.css')]`
We set the `styles` property, **not** `styleUrls` property! The module bundler is loading the CSS strings, not Angular.
Angular only sees the CSS strings *after* the bundler loads them. To Angular it is as if
we wrote the `styles` array by hand.
Refer to the module bundler's documentation for information on loading CSS in this manner.
We set the `styles` property, **not** `styleUrls` property! The module
bundler is loading the CSS strings, not Angular.
Angular only sees the CSS strings *after* the bundler loads them.
To Angular it is as if we wrote the `styles` array by hand.
Refer to the module bundler's documentation for information on
loading CSS in this manner.
:marked
### Template Link Tags
We can also embed `<link>` tags into the component's HTML template.
As with `styleUrls`, the link tag's `href` URL is relative to the HTML host page of the application,
not relative to the component file.
As with `styleUrls`, the link tag's `href` URL is relative to the
application root, not relative to the component file.
+makeExample('component-styles/ts/app/hero-team.component.ts', 'stylelink')
@ -196,10 +202,13 @@ a(id='loading-styles')
We can also import CSS files into our CSS files by using the standard CSS
[`@import` rule](https://developer.mozilla.org/en/docs/Web/CSS/@import).
block css-import-url
:marked
In *this* case the URL is relative to the CSS file into which we are importing.
+makeExample('component-styles/ts/app/hero-details.component.css', 'import', 'app/hero-details.component.css (excerpt)')
a#view-encapsulation
.l-main-section
:marked
## Controlling View Encapsulation: Native, Emulated, and None
@ -227,13 +236,14 @@ a(id='loading-styles')
Set the components encapsulation mode using the `encapsulation` property in the component metadata:
+makeExample('component-styles/ts/app/quest-summary.component.ts', 'encapsulation.native')(format='.')
:marked
`Native` view encapsulation only works on [browsers that have native support
for Shadow DOM](http://caniuse.com/#feat=shadowdom). The support is still limited,
which is why `Emulated` view encapsulation is the default mode and recommended
in most cases.
a(id="inspect-generated-css")
a#inspect-generated-css
.l-main-section
:marked
## Appendix 1: Inspecting The CSS Generated in Emulated View Encapsulation
@ -283,7 +293,7 @@ code-example(format="").
We'll likely live with *emulated* mode until shadow DOM gains traction.
a(id="relative-urls")
a#relative-urls
.l-main-section
:marked
## Appendix 2: Loading Styles with Relative URLs
@ -294,13 +304,18 @@ code-example(format='').
quest-summary.component.ts
quest-summary.component.html
quest-summary.component.css
:marked
We include the template and CSS files by setting the `templateUrl` and `styleUrls` metadata properties respectively.
Because these files are co-located with the component,
it would be nice to refer to them by name without also having to specify a path back to the root of the application.
block module-id
:marked
We'd *prefer* to write this:
+makeExample('component-styles/ts/app/quest-summary.component.ts', 'urls')(format='.')
:marked
We can't do that by default. Angular can't find the files and throws an error:
@ -333,9 +348,11 @@ code-example(format='').
Fortunately, *certain* module loaders make it easy.
SystemJS (starting in v.0.19.19) sets a special `__moduleName` variable to the URL of the component file.
.alert.is-important
:marked
Caution: we currently regard the *__moduleName* feature as experimental.
:marked
Now it's trivial to set the `moduleId` to the `__moduleName` and write module-relative paths for style and template URLs.