diff --git a/.gitignore b/.gitignore index 37b6881acdb2..855c73dc0ecf 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ /libpeerconnection.log npm-debug.log testem.log +/.chrome diff --git a/.travis.yml b/.travis.yml index a86024956813..aba30cd4acff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: node_js sudo: false node_js: - - '5.6.0' + - '6.9.1' addons: apt: diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c8e48793964..7003cd93a2b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,117 @@ + +# [2.0.0-alpha.10 mithril-hoverboard](https://github.com/angular/material2/compare/2.0.0-alpha.9...2.0.0-alpha.10) (2016-11-10) + +## Breaking Changes +* `MdSnackbarConfig` no longer takes a `ViewContainerRef` as a contructor argument because the + `ViewContainerRef` is now optional. +* Tabs no longer use an `md-tab-content` directive. Instead, the non-label content of the tab is + used as its content. Labels can also be specified via attribute, so the tabs can now be given as: + ```html + + + This is the overview tab + + + This is the details tab + + + ``` + + You can still use `md-tab-label` to provide a label template. + + +### Features + +* **tab-nav-bar:** new component! Provides a tab-bar for use with a router-outlet ([#1589](https://github.com/angular/material2/issues/1589)) ([572b36e](https://github.com/angular/material2/commit/572b36e)) +* **a11y:** manager for list keyboard events ([#1599](https://github.com/angular/material2/issues/1599)) ([95b2a34](https://github.com/angular/material2/commit/95b2a34)) +* **checkbox:** add color attribute. ([#1463](https://github.com/angular/material2/issues/1463)) ([333b11e](https://github.com/angular/material2/commit/333b11e)) +* **checkbox:** add ripple ([#1611](https://github.com/angular/material2/issues/1611)) ([ef4c3c9](https://github.com/angular/material2/commit/ef4c3c9)) +* **dialog:** add disableClose option ([#1678](https://github.com/angular/material2/issues/1678)) ([93f8e04](https://github.com/angular/material2/commit/93f8e04)), closes [#1419](https://github.com/angular/material2/issues/1419) +* **dialog:** allow for an object literal to be passed on init ([#1679](https://github.com/angular/material2/issues/1679)) ([f525db1](https://github.com/angular/material2/commit/f525db1)) +* **dialog:** don't require a ViewContainerRef ([#1704](https://github.com/angular/material2/issues/1704)) ([f59030e](https://github.com/angular/material2/commit/f59030e)) +* **menu:** add animations ([#1685](https://github.com/angular/material2/issues/1685)) ([7fcf511](https://github.com/angular/material2/commit/7fcf511)) +* **menu:** allow menu-trigger to take a menu interface. ([#1564](https://github.com/angular/material2/issues/1564)) ([96d196a](https://github.com/angular/material2/commit/96d196a)), closes [#1560](https://github.com/angular/material2/issues/1560) +* **menu:** support icons ([#1702](https://github.com/angular/material2/issues/1702)) ([982cdaa](https://github.com/angular/material2/commit/982cdaa)) +* **overlay:** add custom classes for backdrop ([#1532](https://github.com/angular/material2/issues/1532)) ([0b54668](https://github.com/angular/material2/commit/0b54668)) +* **overlay:** set overlay size ([#1583](https://github.com/angular/material2/issues/1583)) ([ffbc295](https://github.com/angular/material2/commit/ffbc295)) +* **overlay:** support all overlay config properties ([#1591](https://github.com/angular/material2/issues/1591)) ([6f322cf](https://github.com/angular/material2/commit/6f322cf)) +* **overlay:** support custom offsets ([#1660](https://github.com/angular/material2/issues/1660)) ([1738d24](https://github.com/angular/material2/commit/1738d24)) +* **overlay:** support rtl in overlays ([#1593](https://github.com/angular/material2/issues/1593)) ([b56f520](https://github.com/angular/material2/commit/b56f520)) +* **radio:** add ripple ([#1553](https://github.com/angular/material2/issues/1553)) ([d83b3e0](https://github.com/angular/material2/commit/d83b3e0)) +* **slider:** fire change event ([#1618](https://github.com/angular/material2/issues/1618)) ([780a654](https://github.com/angular/material2/commit/780a654)) +* **slider:** implement ControlValueAccessor setDisabledState ([#1603](https://github.com/angular/material2/issues/1603)) ([437ec8e](https://github.com/angular/material2/commit/437ec8e)) +* **snack bar:** add enter and exit animations. ([#1320](https://github.com/angular/material2/issues/1320)) ([6df29dc](https://github.com/angular/material2/commit/6df29dc)) +* **snackbar:** don't require a ViewContainerRef ([#1783](https://github.com/angular/material2/issues/1783)) ([9115538](https://github.com/angular/material2/commit/9115538)) +* **tabs:** simplify api ([#1645](https://github.com/angular/material2/issues/1645)) ([ea6c817](https://github.com/angular/material2/commit/ea6c817)) +* **textarea:** initial md-textarea. Does not yet support auto-size. ([#1562](https://github.com/angular/material2/issues/1562)) ([aff22e5](https://github.com/angular/material2/commit/aff22e5)) +* **tooltip:** add tooltip animations ([#1644](https://github.com/angular/material2/issues/1644)) ([52582f4](https://github.com/angular/material2/commit/52582f4)) + + +### Bug Fixes + +* **aot:** export dialog/snackbar containers through index ([#1378](https://github.com/angular/material2/issues/1378)) ([bb61928](https://github.com/angular/material2/commit/bb61928)) +* **aot:** fix aot error w/ live announcer ([#1355](https://github.com/angular/material2/issues/1355)) ([276d07d](https://github.com/angular/material2/commit/276d07d)) +* **button:** Changed button corner radius from 3px to 2px ([#1441](https://github.com/angular/material2/issues/1441)) ([ec48b34](https://github.com/angular/material2/commit/ec48b34)) +* **button:** set vertical alignment for md-button and md-raised-button ([#1565](https://github.com/angular/material2/issues/1565)) ([f10ac7c](https://github.com/angular/material2/commit/f10ac7c)) +* **button-toggle:** add exportAs ([#1528](https://github.com/angular/material2/issues/1528)) ([d2c288d](https://github.com/angular/material2/commit/d2c288d)) +* **button-toggle:** disable user-select in button-toggle ([#1720](https://github.com/angular/material2/issues/1720)) ([83f6efc](https://github.com/angular/material2/commit/83f6efc)) +* **checkbox:** disable for all non-false values ([#1631](https://github.com/angular/material2/issues/1631)) ([80491a9](https://github.com/angular/material2/commit/80491a9)) +* **checkbox:** prevent checkbox being squished ([#1713](https://github.com/angular/material2/issues/1713)) ([6601949](https://github.com/angular/material2/commit/6601949)) +* **checkbox:** vertically align for when there's no text ([#1721](https://github.com/angular/material2/issues/1721)) ([7fd0fcd](https://github.com/angular/material2/commit/7fd0fcd)) +* **gestures:** don't clobber native drag events ([#1458](https://github.com/angular/material2/issues/1458)) ([b09465c](https://github.com/angular/material2/commit/b09465c)) ([#1744](https://github.com/angular/material2/issues/1744)) ([4af3cd3](https://github.com/angular/material2/commit/4af3cd3)), closes [#1025](https://github.com/angular/material2/issues/1025) +* **input:** correctly position md-hint in IE11 when position start ([#1674](https://github.com/angular/material2/issues/1674)) ([ecefb89](https://github.com/angular/material2/commit/ecefb89)) +* **input:** remove invalid aria-target attribute ([#1513](https://github.com/angular/material2/issues/1513)) ([601c036](https://github.com/angular/material2/commit/601c036)), closes [#929](https://github.com/angular/material2/issues/929) +* **input:** set line-height to normal ([#1734](https://github.com/angular/material2/issues/1734)) ([f1f660e](https://github.com/angular/material2/commit/f1f660e)) +* **list:** ensure multi-line lists expand to fill space ([#1466](https://github.com/angular/material2/issues/1466)) ([e7b872a](https://github.com/angular/material2/commit/e7b872a)) +* **list:** prevent default black border from applying ([#1548](https://github.com/angular/material2/issues/1548)) ([4086b32](https://github.com/angular/material2/commit/4086b32)), closes [#1336](https://github.com/angular/material2/issues/1336) +* **list:** set flex-shrink for avatar ([#1464](https://github.com/angular/material2/issues/1464)) ([5a528aa](https://github.com/angular/material2/commit/5a528aa)), closes [#1403](https://github.com/angular/material2/issues/1403) +* **menu:** improve a11y for screenreaders ([#1715](https://github.com/angular/material2/issues/1715)) ([267e323](https://github.com/angular/material2/commit/267e323)) +* **menu:** make menu open idempotent ([#1478](https://github.com/angular/material2/issues/1478)) ([a5b3296](https://github.com/angular/material2/commit/a5b3296)) +* **menu:** properly handle spacebar events ([#1533](https://github.com/angular/material2/issues/1533)) ([cfe3e98](https://github.com/angular/material2/commit/cfe3e98)), closes [#1175](https://github.com/angular/material2/issues/1175) +* **menu:** update menu to use overlay rtl ([#1687](https://github.com/angular/material2/issues/1687)) ([2b913de](https://github.com/angular/material2/commit/2b913de)) +* **menu:** update to use overlay backdrop ([#1534](https://github.com/angular/material2/issues/1534)) ([add0d23](https://github.com/angular/material2/commit/add0d23)) +* **overlay:** ensure container covers entire screen ([#1634](https://github.com/angular/material2/issues/1634)) ([af39236](https://github.com/angular/material2/commit/af39236)) +* **overlay:** fix connected position calculation while scrolled ([#1732](https://github.com/angular/material2/issues/1732)) ([2de461e](https://github.com/angular/material2/commit/2de461e)) +* **overlay:** not taking up entire viewport if body is scrollable ([#1661](https://github.com/angular/material2/issues/1661)) ([16cbbab](https://github.com/angular/material2/commit/16cbbab)), closes [#1633](https://github.com/angular/material2/issues/1633) +* **overlay:** raise z-index for overlay-container ([#1614](https://github.com/angular/material2/issues/1614)) ([8f50c35](https://github.com/angular/material2/commit/8f50c35)) +* **portal:** cleanup PortalHost on directive destroy ([#1703](https://github.com/angular/material2/issues/1703)) ([7e08468](https://github.com/angular/material2/commit/7e08468)) +* **progress-bar:** bar being thrown off by parent's text-align ([#1717](https://github.com/angular/material2/issues/1717)) ([309d54c](https://github.com/angular/material2/commit/309d54c)), closes [#1165](https://github.com/angular/material2/issues/1165) +* **progress-circle:** allow value to be set to 0 ([#1536](https://github.com/angular/material2/issues/1536)) ([25c7fd5](https://github.com/angular/material2/commit/25c7fd5)) +* **progress-spinner:** animation expanding parent element ([#1742](https://github.com/angular/material2/issues/1742)) ([4203d09](https://github.com/angular/material2/commit/4203d09)), closes [#1259](https://github.com/angular/material2/issues/1259) +* **radio:** only call change callback with user input ([#1521](https://github.com/angular/material2/issues/1521)) ([920c875](https://github.com/angular/material2/commit/920c875)) +* **radio:** only emit change event on user interaction ([#1680](https://github.com/angular/material2/issues/1680)) ([0d552f5](https://github.com/angular/material2/commit/0d552f5)) +* **radio:** only fire group change if there is a group ([#1622](https://github.com/angular/material2/issues/1622)) ([065469a](https://github.com/angular/material2/commit/065469a)) +* **radio:** Uncheck radio group if uncheck radio button programmatically ([#1561](https://github.com/angular/material2/issues/1561)) ([c108607](https://github.com/angular/material2/commit/c108607)), closes [#609](https://github.com/angular/material2/issues/609) +* **ripple:** disable pointer events on ripple ([#1623](https://github.com/angular/material2/issues/1623)) ([f91ea21](https://github.com/angular/material2/commit/f91ea21)) ([#1684](https://github.com/angular/material2/issues/1684)) ([7336b90](https://github.com/angular/material2/commit/7336b90)) +* **ripple:** prevent color flicker on radio/checkbox ([#1705](https://github.com/angular/material2/issues/1705)) ([8ce65ca](https://github.com/angular/material2/commit/8ce65ca)) +* **sidenav:** resolve the promise when sidenav is initialized opened. ([#1666](https://github.com/angular/material2/issues/1666)) ([a0d85d8](https://github.com/angular/material2/commit/a0d85d8)), closes [#1382](https://github.com/angular/material2/issues/1382) +* **slide-toggle:** disabled theme not working and dragging works if disabled ([#1268](https://github.com/angular/material2/issues/1268)) ([8908366](https://github.com/angular/material2/commit/8908366)) +* **slide-toggle:** emit change event after drag end ([#1405](https://github.com/angular/material2/issues/1405)) ([0b5b6f2](https://github.com/angular/material2/commit/0b5b6f2)) +* **slide-toggle:** remove view encapsulation ([#1446](https://github.com/angular/material2/issues/1446)) ([cbecbce](https://github.com/angular/material2/commit/cbecbce)), closes [#1343](https://github.com/angular/material2/issues/1343) +* **slide-toggle:** thumb spacing at end for rtl ([#1659](https://github.com/angular/material2/issues/1659)) ([ad3100e](https://github.com/angular/material2/commit/ad3100e)) +* **slide-toggle:** update colors to match spec ([#1612](https://github.com/angular/material2/issues/1612)) ([596d994](https://github.com/angular/material2/commit/596d994)) +* **slider:** clamp thumb between min and max ([#1617](https://github.com/angular/material2/issues/1617)) ([783dbb3](https://github.com/angular/material2/commit/783dbb3)), closes [#1557](https://github.com/angular/material2/issues/1557) +* **slider:** correctly detect when sidenav align changes. ([#1758](https://github.com/angular/material2/issues/1758)) ([5ffdea6](https://github.com/angular/material2/commit/5ffdea6)) +* **slider:** update thumb pos & ticks when min/max change ([#1598](https://github.com/angular/material2/issues/1598)) ([ff84842](https://github.com/angular/material2/commit/ff84842)) +* **slider:** update thumb position when value changes. Closes [#1386](https://github.com/angular/material2/issues/1386) ([#1610](https://github.com/angular/material2/issues/1610)) ([8e7f80d](https://github.com/angular/material2/commit/8e7f80d)) +* **slider:** use percent values for the track ([#1663](https://github.com/angular/material2/issues/1663)) ([8815846](https://github.com/angular/material2/commit/8815846)), closes [#1389](https://github.com/angular/material2/issues/1389) [#1304](https://github.com/angular/material2/issues/1304) [#1234](https://github.com/angular/material2/issues/1234) +* **snackbar:** add explicit box-sizing ([#1413](https://github.com/angular/material2/issues/1413)) ([580da74](https://github.com/angular/material2/commit/580da74)), closes [#1412](https://github.com/angular/material2/issues/1412) +* **snackbar:** always clear ref when dismissing ([#1773](https://github.com/angular/material2/issues/1773)) ([3c5b632](https://github.com/angular/material2/commit/3c5b632)) +* **snackbar:** remove even if still animating open ([#1797](https://github.com/angular/material2/issues/1797)) ([523a48e](https://github.com/angular/material2/commit/523a48e)) +* **snackbar:** snackbars sometimes don't get removed ([#1795](https://github.com/angular/material2/issues/1795)) ([fcd29c8](https://github.com/angular/material2/commit/fcd29c8)) +* **tabs:** make [@Output](https://github.com/Output) not private ([#1636](https://github.com/angular/material2/issues/1636)) ([04e2201](https://github.com/angular/material2/commit/04e2201)) +* **tabs:** set correct min-width on mobile devices ([#1351](https://github.com/angular/material2/issues/1351)) ([e270e50](https://github.com/angular/material2/commit/e270e50)), closes [#1350](https://github.com/angular/material2/issues/1350) +* **tooltip:** remove tooltip component after its parent destroyed ([#1470](https://github.com/angular/material2/issues/1470)) ([92ac392](https://github.com/angular/material2/commit/92ac392)), closes [#1111](https://github.com/angular/material2/issues/1111) +* correct EventEmitter generic type across lib ([#1620](https://github.com/angular/material2/issues/1620)) ([0174fa9](https://github.com/angular/material2/commit/0174fa9)) +* disable ripples when parent component is disabled ([#1778](https://github.com/angular/material2/issues/1778)) ([6b9e11c](https://github.com/angular/material2/commit/6b9e11c)) + + +### Performance Improvements + +* **progress-circle:** improved rendering performance ([#1635](https://github.com/angular/material2/issues/1635)) ([0883fb2](https://github.com/angular/material2/commit/0883fb2)) + + + # [2.0.0-alpha.9 cobalt-kraken](https://github.com/angular/material2/compare/2.0.0-alpha.8...2.0.0-alpha.9) (2016-09-26) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9bc26372a89f..d3bf583f350d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -150,8 +150,7 @@ To ensure consistency throughout the source code, keep these rules in mind as yo * All features or bug fixes **must be tested** by one or more specs (unit-tests). * All public API methods **must be documented**. (Details TBD). * We follow [Google's JavaScript Style Guide][js-style-guide], but wrap all code at - **100 characters**. An automated formatter is available, see - [DEVELOPER.md](DEVELOPER.md#clang-format). + **100 characters**. ## Commit Message Guidelines @@ -234,7 +233,7 @@ changes to be accepted, the CLA must be signed. It's a quick process, we promise [coc]: https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md [commit-message-format]: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/preview [corporate-cla]: http://code.google.com/legal/corporate-cla-v1.0.html -[dev-doc]: https://github.com/angular/material2/blob/master/DEVELOPER.md +[dev-doc]: https://github.com/angular/material2/blob/master/DEV_ENVIRONMENT.md [github]: https://github.com/angular/material2 [gitter]: https://gitter.im/angular/material2 [individual-cla]: http://code.google.com/legal/individual-cla-v1.0.html diff --git a/GETTING_STARTED.md b/GETTING_STARTED.md index f8af7ef9e3b7..2f547f906138 100644 --- a/GETTING_STARTED.md +++ b/GETTING_STARTED.md @@ -33,9 +33,11 @@ import { MaterialModule } from '@angular/material'; export class PizzaPartyAppModule { } ``` -### Including core and theme styles: -See the [theming guide](docs/theming.md) for more information. +## Include the core and theme styles: +This is **required** to apply all of the core and theme styles to your application. You can either +use a pre-built theme, or define your own custom theme. +:trident: See the [theming guide](docs/theming.md) for instructions. ### Additional setup for `md-slide-toggle` and `md-slider`: The slide-toggle and slider components have a dependency on [HammerJS](http://hammerjs.github.io/). @@ -44,16 +46,31 @@ Add HammerJS to your application via [npm](https://www.npmjs.com/package/hammerj (such as the [Google CDN](https://developers.google.com/speed/libraries/#hammerjs)), or served directly from your app. +## Configuring SystemJS +If your project is using SystemJS for module loading, you will need to add `@angular/material` +to the SystemJS configuration: + +```js +System.config({ + // existing configuration options + map: { + ..., + '@angular/material': 'npm:@angular/material/material.umd.js' + } +}); +``` + ### [Optional] Using Material Design icons with `md-icon`: -- If you want to use Material Design icons, load the Material Design font in your `index.html`. -`md-icon` supports any font icons or svg icons, so this is only one potential option. +- If you want to use Material Design icons in addition to Angular Material components, +load the Material Design font in your `index.html`. +`md-icon` supports any font icons or svg icons, so this is only one option for an icon source. **src/index.html** ```html ``` -### Sample Angular Material 2 projects +## Sample Angular Material 2 projects - [Material 2 Sample App](https://github.com/jelbourn/material2-app) - [Angular Connect 2016 Demo](https://github.com/kara/leashed-in) diff --git a/README.md b/README.md index 56bfc77810a0..bbdaea8d65e1 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Material Design for Angular 2 -[![NPM Version](https://badge.fury.io/js/%40angular2-material%2Fcore.svg)](https://www.npmjs.com/package/%2540angular2-material%2Fcore) +[![npm version](https://badge.fury.io/js/%40angular%2Fmaterial.svg)](https://www.npmjs.com/package/%40angular%2Fmaterial) [![Build Status](https://travis-ci.org/angular/material2.svg?branch=master)](https://travis-ci.org/angular/material2) [![Gitter](https://badges.gitter.im/angular/material2.svg)](https://gitter.im/angular/material2?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) @@ -28,13 +28,15 @@ and which pieces are blocked) and make a comment. Also see our [`Good for community contribution`](https://github.com/angular/material2/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+for+community+contribution%22) label. -High level items planned for September 2016: -* Work on Angular core towards 2.0.0 final -* Preparing for conferences (Angular Connect and ng-europe) -* Final features for dialog -* Initial version of snackbar. -* Additional behaviors for menu, start design for select. -* Finalize high-level design details for data-table. +High level items planned for November 2016: +* Initial version of md-select +* Continued bug bashing +* Initial versions of autocomplete and chips +* AoT compile e2e app +* Continue work on https://material.angular.io site +* Major refactoring for md-input +* Tabs animations +* Expanding e2e test coverage #### Feature status: @@ -60,17 +62,17 @@ High level items planned for September 2016: | menu | Initial version, needs enhancements | [README][17] | [#119][0119] | | tooltip | Initial version, needs enhancements | [README][18] | - | | ripples | Available, but needs to be applied | [README][19] | [#108][0108] | -| dialog | Started, not yet ready for release | - | [#114][0114] | -| snackbar / toast | Proof-of-concept | - | [#115][0115] | +| dialog | Started, not yet ready for release | [README][22] | [#114][0114] | +| snackbar / toast | Initial version, needs enhancements | [README][21] | [#115][0115] | | select | Design started | - | [#118][0118] | -| textarea | Not started | - | [#546][0546] | -| autocomplete | Not started | - | [#117][0117] | -| chips | Not started | - | [#120][0120] | -| theming | In master, not released, some bugs | [Guide][20] | [#123][0123] | +| textarea | Started | - | [#546][0546] | +| autocomplete | Design started | - | [#117][0117] | +| chips | Design started | - | [#120][0120] | +| theming | Initial version, needs enhancements | [Guide][20] | - | | prod build | Not started | - | - | | docs site | UX design and tooling in progress | - | - | | typography | Not started | - | [#205][0205] | -| layout | Not started | - | - | +| layout | Design in-progress, prototyped | - | - | | fab speed-dial | Not started | - | [#860][0860] | | fab toolbar | Not started | - | - | | bottom-sheet | Not started | - | - | @@ -100,6 +102,8 @@ High level items planned for September 2016: [18]: https://github.com/angular/material2/blob/master/src/lib/tooltip/README.md [19]: https://github.com/angular/material2/blob/master/src/lib/core/ripple/README.md [20]: https://github.com/angular/material2/blob/master/docs/theming.md +[21]: https://github.com/angular/material2/blob/master/src/lib/snack-bar/README.md +[22]: https://github.com/angular/material2/blob/master/src/lib/dialog/README.md [0107]: https://github.com/angular/material2/issues/107 [0119]: https://github.com/angular/material2/issues/119 diff --git a/build/autoprefixer-options.js b/build/autoprefixer-options.js deleted file mode 100644 index 7747b94f43e3..000000000000 --- a/build/autoprefixer-options.js +++ /dev/null @@ -1,9 +0,0 @@ -// Options for autoprefixer. See https://github.com/postcss/autoprefixer#options -module.exports = { - // To see the full list of supported browers, you can direcly use `browserslist` - browsers: [ - 'last 2 versions', - 'not ie <= 10', - 'not ie_mob <= 10', - ] -}; diff --git a/config/environment.dev.ts b/config/environment.dev.ts deleted file mode 100644 index ffe8aed76642..000000000000 --- a/config/environment.dev.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const environment = { - production: false -}; diff --git a/config/environment.js b/config/environment.js deleted file mode 100644 index 4fa28880da9f..000000000000 --- a/config/environment.js +++ /dev/null @@ -1,10 +0,0 @@ -/* jshint node: true */ - -module.exports = function(environment) { - return { - environment: environment, - baseURL: '/', - locationType: 'auto' - }; -}; - diff --git a/config/environment.prod.ts b/config/environment.prod.ts deleted file mode 100644 index 3612073bc31c..000000000000 --- a/config/environment.prod.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const environment = { - production: true -}; diff --git a/docs/theming-your-components.md b/docs/theming-your-components.md new file mode 100644 index 000000000000..6481e5e222fe --- /dev/null +++ b/docs/theming-your-components.md @@ -0,0 +1,69 @@ +#Theming your custom components +In order to style your own components with Angular Material's tooling, the component's styles must be defined with Sass. + +## Using `@mixin` to automatically apply a theme + +### Why using `@mixin` +The advantage of using a `@mixin` function is that when you change your theme, every file that uses it will be updated automatically. +Calling it with a different theme argument allow multiple themes within the app or component. + +### How to use `@mixin` +We can better theming our custom components adding a `@mixin` function to its theme file and then calling this function to apply a theme. + +All you need is to create a `@mixin` function in the custom-component-theme.scss + +```sass +// Import all the tools needed to customize the theme and extract parts of it +@import '~@angular/material/core/theming/all-theme'; + +// Define a mixin that accepts a theme and outputs the color styles for the component. +@mixin candy-carousel-theme($theme) { + // Extract whichever individual palettes you need from the theme. + $primary: map-get($theme, primary); + $accent: map-get($theme, accent); + + // Use md-color to extract individual colors from a palette as necessary. + .candy-carousel { + background-color: md-color($primary); + border-color: md-color($accent, A400); + } +} +``` +Now you just have have to call the `@mixin` function to apply the theme: + +```sass +// Import a pre-built theme +@import '~@angular/material/core/theming/prebuilt/deep-purple-amber'; +// Import your custom input theme file so you can call the custom-input-theme function +@import 'app/candy-carousel/candy-carousel-theme.scss'; + +// Using the $theme variable from the pre-built theme you can call the theming function +@include candy-carousel-theme($theme); +``` + +For more details about the theming functions, see the comments in the +[source](https://github.com/angular/material2/blob/master/src/lib/core/theming/_theming.scss). + +### Best practices using `@mixin` +When using `@mixin`, the theme file should only contain the definitions that are affected by the passed-in theme. + +All styles that are not affected by the theme should be placed in a `candy-carousel.scss` file. This file should contain everything that is not affected by the theme like sizes, transitions... + +Styles that are affected by the theme should be placed in a separated theming file as `_candy-carousel-theme.scss` and the file should have a `_` before the name. This file should contain the `@mixin` function responsible for applying the theme to the component. + + +## Using colors from a pallete +You can consume the theming functions from the `@angular/material/core/theming/theming` and Material pallete vars from `@angular/material/core/theming/palette`. You can use the `md-color` function to extract a specific color from a palette. For example: + +```scss +// Import theming functions +@import '~@angular/material/core/theming/theming'; +// Import your custom theme +@import 'src/unicorn-app-theme.scss'; + +// Use md-color to extract individual colors from a palette as necessary. +.candy-carousel { + background-color: md-color($candy-app-primary); + border-color: md-color($candy-app-accent, A400); +} +``` diff --git a/docs/theming.md b/docs/theming.md index 16a242516f52..cef94c7b891e 100644 --- a/docs/theming.md +++ b/docs/theming.md @@ -3,9 +3,9 @@ ### What is a theme? A **theme** is the set of colors that will be applied to the Angular Material components. The -library's approach to theming is based on the guidance from the [Material Design spec][1]. +library's approach to theming is based on the guidance from the [Material Design spec][1]. -In Angular Material, a theme is created by composing multiple palettes. In particular, +In Angular Material, a theme is created by composing multiple palettes. In particular, a theme consists of: * A primary palette: colors most widely used across all screens and components. * An accent palette: colors used for the floating action button and interactive elements. @@ -21,9 +21,9 @@ app doesn't have to spend cycles generating theme styles on startup. ### Using a pre-built theme Angular Material comes prepackaged with several pre-built theme css files. These theme files also include all of the styles for core (styles common to all components), so you only have to include a -single css file for Angular Material in your app. +single css file for Angular Material in your app. -You can include a theme file directly into your application from +You can include a theme file directly into your application from `@angular/material/core/theming/prebuilt` If you're using Angular CLI, this is as simple as including one line @@ -35,8 +35,8 @@ in your `style.css` file: Alternatively, you can just reference the file directly. This would look something like ```html -``` -The actual path will depend on your server setup. +``` +The actual path will depend on your server setup. You can also concatenate the file with the rest of your application's css. @@ -56,25 +56,25 @@ the corresponding styles. A typical theme file will look something like this: // Define the palettes for your theme using the Material Design palettes available in palette.scss // (imported above). For each palette, you can optionally specify a default, lighter, and darker // hue. -$primary: md-palette($md-indigo); -$accent: md-palette($md-pink, A200, A100, A400); +$candy-app-primary: md-palette($md-indigo); +$candy-app-accent: md-palette($md-pink, A200, A100, A400); // The warn palette is optional (defaults to red). -$warn: md-palette($md-red); +$candy-app-warn: md-palette($md-red); // Create the theme object (a Sass map containing all of the palettes). -$theme: md-light-theme($primary, $accent, $warn); +$candy-app-theme: md-light-theme($candy-app-primary, $candy-app-accent, $candy-app-warn); // Include theme styles for core and each component used in your app. // Alternatively, you can import and @include the theme mixins for each component // that you are using. -@include angular-material-theme($theme); +@include angular-material-theme($candy-app-theme); ``` You only need this single Sass file; you do not need to use Sass to style the rest of your app. -If you are using the Angular CLI, support for compiling Sass to css is built-in; you only have to -add a new entry to the `"styles"` list in `angular-cli.json` pointing to the theme +If you are using the Angular CLI, support for compiling Sass to css is built-in; you only have to +add a new entry to the `"styles"` list in `angular-cli.json` pointing to the theme file (e.g., `unicorn-app-theme.scss`). If you're not using the Angular CLI, you can use any existing Sass tooling to build the file (such @@ -87,8 +87,8 @@ and then include the output file in your application. The theme file can be concatenated and minified with the rest of the application's css. #### Multiple themes -You can extend the example above to define a second (or third or fourth) theme that is gated by -some selector. For example, we could append the following to the example above to define a +You can extend the example above to define a second (or third or fourth) theme that is gated by +some selector. For example, we could append the following to the example above to define a secondary dark theme: ```scss .unicorn-dark-theme { @@ -97,26 +97,16 @@ secondary dark theme: $dark-warn: md-palette($md-deep-orange); $dark-theme: md-dark-theme($dark-primary, $dark-accent, $dark-warn); - -@include angular-material-theme($dark-theme); + + @include angular-material-theme($dark-theme); } ``` With this, any element inside of a parent with the `unicorn-dark-theme` class will use this dark theme. -### Styling your own components -In order to style your own components with our tooling, the component's styles must be defined -with Sass. - -You can consume the theming functions and variables from the `@angular/material/core/theming`. -You can use the `md-color` function to extract a specific color from a palette. For example: -```scss -.unicorn-carousel { - background-color: md-color($primary); - color: md-color($primary, default-contrast); -} -``` +### Theming your own components +For more details about theming your own components, see [theming-your-components.md](https://github.com/angular/material2/blob/master/docs/theming-your-components.md) ### Future work * Once CSS variables (custom properties) are available in all the browsers we support, diff --git a/e2e/components/checkbox/checkbox.e2e.ts b/e2e/components/checkbox/checkbox.e2e.ts new file mode 100644 index 000000000000..d4b0008c95bf --- /dev/null +++ b/e2e/components/checkbox/checkbox.e2e.ts @@ -0,0 +1,18 @@ +describe('checkbox', function () { + describe('check behavior', function () { + beforeEach(function() { + browser.get('/checkbox'); + }); + it('should be checked when clicked, and be unchecked when clicked again', function () { + element(by.id('test-checkbox')).click(); + element(by.css('input[id=input-test-checkbox]')).getAttribute('checked').then((value: string) => { + expect(value).toBeTruthy('Expect checkbox "checked" property to be true'); + }); + + element(by.id('test-checkbox')).click(); + element(by.css('input[id=input-test-checkbox]')).getAttribute('checked').then((value: string) => { + expect(value).toBeFalsy('Expect checkbox "checked" property to be false'); + }); + }); + }); +}); diff --git a/e2e/components/dialog/dialog.e2e.ts b/e2e/components/dialog/dialog.e2e.ts new file mode 100644 index 000000000000..105f8e91abe6 --- /dev/null +++ b/e2e/components/dialog/dialog.e2e.ts @@ -0,0 +1,105 @@ +describe('dialog', () => { + beforeEach(() => browser.get('/dialog')); + + it('should open a dialog', () => { + element(by.id('default')).click(); + waitForDialog().then(isPresent => expect(isPresent).toBe(true)); + }); + + it('should close by clicking on the backdrop', () => { + element(by.id('default')).click(); + + waitForDialog().then(() => { + clickOnBackrop(); + waitForDialog().then(isPresent => expect(isPresent).toBe(false)); + }); + }); + + it('should close by pressing escape', () => { + element(by.id('default')).click(); + + waitForDialog().then(() => { + pressEscape(); + waitForDialog().then(isPresent => expect(isPresent).toBe(false)); + }); + }); + + it('should close by clicking on the "close" button', () => { + element(by.id('default')).click(); + + waitForDialog().then(() => { + element(by.id('close')).click(); + waitForDialog().then(isPresent => expect(isPresent).toBe(false)); + }); + }); + + it('should focus the first focusable element', () => { + element(by.id('default')).click(); + + waitForDialog().then(() => { + expectFocusOn(element(by.css('md-dialog-container input'))); + }); + }); + + it('should restore focus to the element that opened the dialog', () => { + let openButton = element(by.id('default')); + + openButton.click(); + + waitForDialog().then(() => { + clickOnBackrop(); + expectFocusOn(openButton); + }); + }); + + it('should prevent tabbing out of the dialog', () => { + element(by.id('default')).click(); + + waitForDialog().then(() => { + let tab = protractor.Key.TAB; + + browser.actions().sendKeys(tab, tab, tab).perform(); + expectFocusOn(element(by.id('close'))); + }); + }); + + it('should be able to prevent closing by clicking on the backdrop', () => { + element(by.id('disabled')).click(); + + waitForDialog().then(() => { + clickOnBackrop(); + waitForDialog().then(isPresent => expect(isPresent).toBe(true)); + }); + }); + + it('should be able to prevent closing by pressing escape', () => { + element(by.id('disabled')).click(); + + waitForDialog().then(() => { + pressEscape(); + waitForDialog().then(isPresent => expect(isPresent).toBe(true)); + }); + }); + + function waitForDialog() { + return browser.isElementPresent(by.css('md-dialog-container')); + } + + function clickOnBackrop() { + browser.actions() + // We need to move the cursor to the top left so + // the dialog doesn't receive the click accidentally. + .mouseMove(element(by.css('.md-overlay-backdrop')).getWebElement(), { x: 0, y: 0 }) + .click() + .perform(); + } + + function pressEscape() { + browser.actions().sendKeys(protractor.Key.ESCAPE).perform(); + } + + // TODO(crisbeto): should be moved to a common util. copied from the menu e2e setup. + function expectFocusOn(el: any): void { + expect(browser.driver.switchTo().activeElement().getInnerHtml()).toBe(el.getInnerHtml()); + } +}); diff --git a/e2e/components/grid-list/grid-list.e2e.ts b/e2e/components/grid-list/grid-list.e2e.ts new file mode 100644 index 000000000000..b3c19563df20 --- /dev/null +++ b/e2e/components/grid-list/grid-list.e2e.ts @@ -0,0 +1,12 @@ +describe('grid-list', () => { + beforeEach(() => browser.get('/grid-list')); + + it('should render a grid list container', () => { + expect(element(by.css('md-grid-list')).isPresent()).toBe(true); + }); + + it('should render list items inside the grid list container', () => { + let container = element(by.css('md-grid-list')); + expect(container.isElementPresent(by.css('md-grid-tile'))).toBe(true); + }); +}); diff --git a/e2e/components/icon/icon.e2e.ts b/e2e/components/icon/icon.e2e.ts index 4d5648ac5d8d..9894a2fd9a3b 100644 --- a/e2e/components/icon/icon.e2e.ts +++ b/e2e/components/icon/icon.e2e.ts @@ -15,7 +15,8 @@ describe('icon', () => { it('should have the correct class when used', () => { testIcon.getAttribute('class').then((attr: string) => { - expect(attr).toEqual('md-24 material-icons'); + expect(attr).toContain('md-24'); + expect(attr).toContain('material-icons'); }); }); diff --git a/e2e/components/list/list.e2e.ts b/e2e/components/list/list.e2e.ts new file mode 100644 index 000000000000..708ff9943ef0 --- /dev/null +++ b/e2e/components/list/list.e2e.ts @@ -0,0 +1,12 @@ +describe('list', () => { + beforeEach(() => browser.get('/list')); + + it('should render a list container', () => { + expect(element(by.css('md-list')).isPresent()).toBe(true); + }); + + it('should render list items inside the list container', () => { + let container = element(by.css('md-list')); + expect(container.isElementPresent(by.css('md-list-item'))).toBe(true); + }); +}); diff --git a/e2e/components/menu/menu-page.ts b/e2e/components/menu/menu-page.ts index 7e25d774004c..3938ad7e8a0a 100644 --- a/e2e/components/menu/menu-page.ts +++ b/e2e/components/menu/menu-page.ts @@ -6,7 +6,7 @@ export class MenuPage { browser.get('/menu'); } - menu() { return element(by.css('.md-menu')); } + menu() { return element(by.css('.md-menu-panel')); } start() { return element(by.id('start')); } @@ -14,7 +14,7 @@ export class MenuPage { triggerTwo() { return element(by.id('trigger-two')); } - body() { return element(by.tagName('body')); } + backdrop() { return element(by.css('.md-overlay-backdrop')); } items(index: number) { return element.all(by.css('[md-menu-item]')).get(index); @@ -28,11 +28,11 @@ export class MenuPage { combinedTrigger() { return element(by.id('combined-t')); } - beforeMenu() { return element(by.css('.md-menu.before')); } + beforeMenu() { return element(by.css('.md-menu-panel.before')); } - aboveMenu() { return element(by.css('.md-menu.above')); } + aboveMenu() { return element(by.css('.md-menu-panel.above')); } - combinedMenu() { return element(by.css('.md-menu.combined')); } + combinedMenu() { return element(by.css('.md-menu-panel.combined')); } // TODO(kara): move to common testing utility pressKey(key: any): void { @@ -46,7 +46,7 @@ export class MenuPage { } expectMenuPresent(expected: boolean) { - return browser.isElementPresent(by.css('.md-menu')).then((isPresent) => { + return browser.isElementPresent(by.css('.md-menu-panel')).then(isPresent => { expect(isPresent).toBe(expected); }); } diff --git a/e2e/components/menu/menu.e2e.ts b/e2e/components/menu/menu.e2e.ts index b247bc113ef8..564db6175bad 100644 --- a/e2e/components/menu/menu.e2e.ts +++ b/e2e/components/menu/menu.e2e.ts @@ -15,12 +15,6 @@ describe('menu', () => { expect(page.menu().getText()).toEqual("One\nTwo\nThree\nFour"); }); - it('should close menu when area outside menu is clicked', () => { - page.trigger().click(); - page.body().click(); - page.expectMenuPresent(false); - }); - it('should close menu when menu item is clicked', () => { page.trigger().click(); page.items(0).click(); @@ -48,21 +42,23 @@ describe('menu', () => { expect(page.menu().getText()).toEqual("One\nTwo\nThree\nFour"); page.expectMenuAlignedWith(page.menu(), 'trigger-two'); - page.body().click(); + page.backdrop().click(); page.expectMenuPresent(false); + // TODO(kara): temporary, remove when #1607 is fixed + browser.sleep(250); page.trigger().click(); expect(page.menu().getText()).toEqual("One\nTwo\nThree\nFour"); page.expectMenuAlignedWith(page.menu(), 'trigger'); - page.body().click(); + page.backdrop().click(); page.expectMenuPresent(false); }); it('should mirror classes on host to menu template in overlay', () => { page.trigger().click(); page.menu().getAttribute('class').then((classes) => { - expect(classes).toEqual('md-menu custom'); + expect(classes).toContain('md-menu-panel custom'); }); }); @@ -73,11 +69,16 @@ describe('menu', () => { page.pressKey(protractor.Key.TAB); }); - it('should auto-focus the first item when opened with keyboard', () => { + it('should auto-focus the first item when opened with ENTER', () => { page.pressKey(protractor.Key.ENTER); page.expectFocusOn(page.items(0)); }); + it('should auto-focus the first item when opened with SPACE', () => { + page.pressKey(protractor.Key.SPACE); + page.expectFocusOn(page.items(0)); + }); + it('should not focus the first item when opened with mouse', () => { page.trigger().click(); page.expectFocusOn(page.trigger()); @@ -111,9 +112,10 @@ describe('menu', () => { page.pressKey(protractor.Key.TAB); page.expectMenuPresent(false); - page.start().click(); page.pressKey(protractor.Key.TAB); page.pressKey(protractor.Key.ENTER); + page.expectMenuPresent(true); + page.pressKey(protractor.Key.chord(protractor.Key.SHIFT, protractor.Key.TAB)); page.expectMenuPresent(false); }); diff --git a/e2e/components/radio/radio.e2e.ts b/e2e/components/radio/radio.e2e.ts new file mode 100644 index 000000000000..7fccd196a68a --- /dev/null +++ b/e2e/components/radio/radio.e2e.ts @@ -0,0 +1,51 @@ +describe('radio', function () { + + describe('disabling behavior', function () { + beforeEach(function() { + browser.get('/radio'); + }); + + it('should be checked when clicked', function () { + element(by.id('water')).click(); + element(by.id('water')).getAttribute('class').then((value: string) => { + expect(value).toContain('md-radio-checked'); + }); + element(by.css('input[id=water-input]')).getAttribute('checked').then((value: string) => { + expect(value).toBeTruthy(); + }); + element(by.css('input[id=leaf-input]')).getAttribute('checked').then((value: string) => { + expect(value).toBeFalsy(); + }); + + element(by.id('leaf')).click(); + element(by.id('leaf')).getAttribute('class').then((value: string) => { + expect(value).toContain('md-radio-checked'); + }); + element(by.css('input[id=leaf-input]')).getAttribute('checked').then((value: string) => { + expect(value).toBeTruthy(); + }); + element(by.css('input[id=water-input]')).getAttribute('checked').then((value: string) => { + expect(value).toBeFalsy(); + }); + }); + + it('should be disabled when disable the radio group', function () { + element(by.id('toggle-disable')).click(); + element(by.id('water')).click(); + element(by.id('water')).getAttribute('class').then((value: string) => { + expect(value).toContain('md-radio-disabled'); + }); + element(by.css('input[id=water-input]')).getAttribute('disabled').then((value: string) => { + expect(value).toBeTruthy(); + }); + + element(by.id('leaf')).click(); + element(by.id('leaf')).getAttribute('class').then((value: string) => { + expect(value).toContain('md-radio-disabled'); + }); + element(by.css('input[id=leaf-input]')).getAttribute('disabled').then((value: string) => { + expect(value).toBeTruthy(); + }); + }); + }); +}); diff --git a/e2e/components/tabs/tabs.e2e.ts b/e2e/components/tabs/tabs.e2e.ts index daf4171824a7..61f8a9b9f95e 100644 --- a/e2e/components/tabs/tabs.e2e.ts +++ b/e2e/components/tabs/tabs.e2e.ts @@ -11,17 +11,17 @@ describe('tabs', () => { browser.get('/tabs'); tabGroup = element(by.css('md-tab-group')); tabLabels = element.all(by.css('.md-tab-label')); - tabBodies = element.all(by.css('.md-tab-body')); + tabBodies = element.all(by.css('md-tab-body')); }); it('should change tabs when the label is clicked', () => { tabLabels.get(1).click(); - expect(getActiveStates(tabLabels)).toEqual([false, true, false]); - expect(getActiveStates(tabBodies)).toEqual([false, true, false]); + expect(getLabelActiveStates(tabLabels)).toEqual([false, true, false]); + expect(getBodyActiveStates(tabBodies)).toEqual([false, true, false]); tabLabels.get(0).click(); - expect(getActiveStates(tabLabels)).toEqual([true, false, false]); - expect(getActiveStates(tabBodies)).toEqual([true, false, false]); + expect(getLabelActiveStates(tabLabels)).toEqual([true, false, false]); + expect(getBodyActiveStates(tabBodies)).toEqual([true, false, false]); }); it('should change focus with keyboard interaction', () => { @@ -49,18 +49,13 @@ describe('tabs', () => { }); }); -/** - * A helper function to perform the sendKey action - * @param key - */ +/** A helper function to perform the sendKey action. */ function pressKey(key: string) { browser.actions().sendKeys(key).perform(); } /** - * Returns an array of true/false that represents the focus states of the provided elements - * @param elements - * @returns {webdriver.promise.Promise[]>|webdriver.promise.Promise} + * Returns an array of true/false that represents the focus states of the provided elements. */ function getFocusStates(elements: ElementArrayFinder) { return elements.map(element => { @@ -72,21 +67,19 @@ function getFocusStates(elements: ElementArrayFinder) { }); } -/** - * Returns an array of true/false that represents the active states for the provided elements - * @param elements - * @returns {webdriver.promise.Promise[]>|webdriver.promise.Promise} - */ -function getActiveStates(elements: ElementArrayFinder) { - return getClassStates(elements, 'md-tab-active'); +/** Returns an array of true/false that represents the active states for the provided elements. */ +function getLabelActiveStates(elements: ElementArrayFinder) { + return getClassStates(elements, 'md-tab-label-active'); +} + +/** Returns an array of true/false that represents the active states for the provided elements */ +function getBodyActiveStates(elements: ElementArrayFinder) { + return getClassStates(elements, 'md-tab-body-active'); } /** * Returns an array of true/false values that represents whether the provided className is on - * each element - * @param elements - * @param className - * @returns {webdriver.promise.Promise[]>|webdriver.promise.Promise} + * each element. */ function getClassStates(elements: ElementArrayFinder, className: string) { return elements.map(element => { diff --git a/firebase.json b/firebase.json index 48d40be158b7..c9467c51676e 100644 --- a/firebase.json +++ b/firebase.json @@ -1,23 +1,30 @@ { - "firebase": "material2-test", - "public": "dist", - "ignore": [ - "firebase.json", - "**/.*", - "**/node_modules/**", - "tmp", - "deploy", - "typings" - ], - "headers": [{ - "source": "*", - "headers": [{ - "key": "Cache-Control", - "value": "no-cache" - }] - }], - "rewrites": [{ - "source": "/**/!(*.@(js|ts|html|css|json|svg|png|jpg|jpeg))", - "destination": "/index.html" - }] + "hosting": { + "public": "dist", + "rewrites": [ + { + "source": "/**/!(*.@(js|ts|html|css|json|svg|png|jpg|jpeg))", + "destination": "/index.html" + } + ], + "headers": [ + { + "source": "*", + "headers": [ + { + "key": "Cache-Control", + "value": "no-cache" + } + ] + } + ], + "ignore": [ + "firebase.json", + "**/.*", + "**/node_modules/**", + "tmp", + "deploy", + "typings" + ] + } } diff --git a/package.json b/package.json index a5770adefb17..97fd10eff170 100644 --- a/package.json +++ b/package.json @@ -17,10 +17,10 @@ "deploy": "firebase deploy", "webdriver-manager": "webdriver-manager" }, - "version": "2.0.0-alpha.9", + "version": "2.0.0-alpha.10", "license": "MIT", "engines": { - "node": ">= 4.2.1 < 5" + "node": ">= 5.4.1 < 7" }, "dependencies": { "@angular/common": "^2.0.0", @@ -38,7 +38,7 @@ "zone.js": "^0.6.23" }, "devDependencies": { - "@angular/compiler-cli": "0.6.0", + "@angular/compiler-cli": "^2.0.0", "@angular/platform-server": "^2.0.0", "@types/glob": "^5.0.29", "@types/gulp": "^3.8.29", @@ -48,14 +48,17 @@ "@types/minimist": "^1.1.28", "@types/node": "^6.0.34", "@types/run-sequence": "0.0.27", - "browserstacktunnel-wrapper": "^1.4.2", + "@types/rx": "^2.5.33", + "browserstacktunnel-wrapper": "^2.0.0", "conventional-changelog": "^1.1.0", "express": "^4.14.0", "firebase-tools": "^2.2.1", "fs-extra": "^0.26.5", "glob": "^6.0.4", "gulp": "^3.9.1", + "gulp-autoprefixer": "^3.1.1", "gulp-clean": "^0.3.2", + "gulp-cli": "^1.2.2", "gulp-sass": "^2.3.2", "gulp-server-livereload": "^1.8.2", "gulp-shell": "^0.5.2", @@ -79,7 +82,7 @@ "run-sequence": "^1.2.2", "sass": "^0.5.0", "strip-ansi": "^3.0.0", - "stylelint": "^6.9.0", + "stylelint": "^7.5.0", "symlink-or-copy": "^1.0.1", "ts-node": "^0.7.3", "tslint": "^3.13.0", diff --git a/scripts/browserstack/start_tunnel.js b/scripts/browserstack/start_tunnel.js index cae1738541d5..54c5087e8c79 100644 --- a/scripts/browserstack/start_tunnel.js +++ b/scripts/browserstack/start_tunnel.js @@ -34,7 +34,12 @@ var tunnel = new BrowserStackTunnel({ }); console.log('Starting tunnel on ports', PORTS.join(', ')); -tunnel.start(function(error) { + +// Emit a `newer_available` event to force an update of the Browserstack binaries (necessary due to Travis caching) +// This also starts a new tunnel after the latest binaries are available. +tunnel.emit('newer_available'); + +tunnel.once('started', function(error) { if (error) { console.error('Can not establish the tunnel', error); } else { @@ -44,7 +49,7 @@ tunnel.start(function(error) { }); if (READY_FILE) { - fs.writeFile(READY_FILE, ''); + fs.writeFile(READY_FILE, process.pid); } } }); diff --git a/scripts/browserstack/teardown_tunnel.sh b/scripts/browserstack/teardown_tunnel.sh index 86fd334284e3..ba09b621e803 100755 --- a/scripts/browserstack/teardown_tunnel.sh +++ b/scripts/browserstack/teardown_tunnel.sh @@ -4,5 +4,17 @@ set -e -o pipefail echo "Shutting down Browserstack tunnel" -echo "TODO: implement me" -exit 1 \ No newline at end of file + +PID=$(cat $BROWSER_PROVIDER_READY_FILE); + +# Resolving the PID from the readyfile. +kill $PID + + +while [[ -n `ps -ef | grep $PID | grep -v "grep"` ]]; do + printf "." + sleep .5 +done + +echo "" +echo "Browserstack tunnel has been shut down" \ No newline at end of file diff --git a/scripts/browserstack/waitfor_tunnel.sh b/scripts/browserstack/waitfor_tunnel.sh index a603a317b066..cb2e7d15324c 100755 --- a/scripts/browserstack/waitfor_tunnel.sh +++ b/scripts/browserstack/waitfor_tunnel.sh @@ -2,18 +2,18 @@ # Wait for Connect to be ready before exiting -# Time out if we wait for more than 2 minutes, so that we can print logs. +# Time out if we wait for more than 2 minutes, so the process won't run forever. let "counter=0" while [ ! -f $BROWSER_PROVIDER_READY_FILE ]; do let "counter++" + if [ $counter -gt 240 ]; then - echo "Timed out after 2 minutes waiting for browser provider ready file" - # We must manually print logs here because travis will not run - # after_script commands if the failure occurs before the script - # phase. - ./scripts/ci/print-logs.sh + echo + echo "Timed out after 2 minutes waiting for tunnel ready file" exit 5 fi + + printf "." sleep .5 done diff --git a/scripts/ci/sources/tunnel.sh b/scripts/ci/sources/tunnel.sh index 1074fe1163f8..62d29160ba86 100644 --- a/scripts/ci/sources/tunnel.sh +++ b/scripts/ci/sources/tunnel.sh @@ -34,7 +34,7 @@ teardown_tunnel() { ./scripts/sauce/sauce_connect_teardown.sh ;; browserstack*) - # ./scripts/browserstack/teardown_tunnel.sh + ./scripts/browserstack/teardown_tunnel.sh ;; *) ;; diff --git a/scripts/e2e.sh b/scripts/e2e.sh deleted file mode 100755 index f9acbb3e4129..000000000000 --- a/scripts/e2e.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash - -export MODE=e2e -export LOGS_DIR=/tmp/angular-material2-build/logs -export SAUCE_USERNAME=angular-ci -export SAUCE_ACCESS_KEY=9b988f434ff8-fbca-8aa4-4ae3-35442987 -export TRAVIS_JOB_NUMBER=12345 -export BROWSER_PROVIDER_READY_FILE=/tmp/angular-material2-build/readyfile - - -mkdir -p $LOGS_DIR -rm -f $BROWSER_PROVIDER_READY_FILE - -# Force cleanup (shouldn't be necessary) -killall angular-cli -./scripts/sauce/sauce_connect_teardown.sh -# Run the script -./scripts/ci/build-and-test.sh -# Actual cleanup -./scripts/sauce/sauce_connect_teardown.sh -killall angular-cli diff --git a/scripts/release/changelog.js b/scripts/release/changelog.js index d33b6e660826..037076e7d24d 100755 --- a/scripts/release/changelog.js +++ b/scripts/release/changelog.js @@ -7,7 +7,7 @@ */ const fs = require('fs'); -const addStream = require('add-stream'); +const merge2 = require('merge2'); const changelog = require('conventional-changelog'); const spawnSync = require('child_process').spawnSync; const npmVersion = require('../../package.json').version; @@ -17,7 +17,7 @@ const npmVersion = require('../../package.json').version; * By default, it will only create the changelog from the latest tag to head and prepends it to the changelog. */ const isForce = process.argv.indexOf('--force') !== -1; -const inStream = fs.createReadStream('CHANGELOG.md'); +const previousChangelog = fs.createReadStream('CHANGELOG.md'); const gitTags = getAvailableTags(); // Whether the npm version is later than the most recent tag. @@ -27,33 +27,40 @@ const currentTag = isNpmLatest ? npmVersion : gitTags[0]; // When the npm version is the latest use the most recent tag. Otherwise use the previous tag. const previousTag = isNpmLatest ? gitTags[0] : gitTags[1]; -inStream.on('error', function(err) { - console.error('An error occurred, while reading the previous changelog file.\n' + - 'If there is no previous changelog, then you should create an empty file or use the `--force` flag.\n' + err); +if (!isForce) { + previousChangelog.on('error', function(err) { + console.error('An error occurred, while reading the previous changelog file.\n' + + 'If there is changelog file, you should create an empty file or use the `--force` flag.\n' + err); - process.exit(1); -}); + process.exit(1); + }); +} -var config = { +const config = { preset: 'angular', releaseCount: isForce ? 0 : 1 }; -var context = { +const context = { currentTag: currentTag, previousTag: previousTag }; -var stream = changelog(config, context) - .on('error', function(err) { - console.error('An error occurred while generating the changelog: ' + err); - }) - .pipe(!isForce && addStream(inStream) || getOutputStream()); +let stream = changelog(config, context).on('error', function(err) { + console.error('An error occurred while generating the changelog: ' + err); +}); + +if (!isForce) { + // Append the previous changelog to the new generated one. + stream = merge2(stream, previousChangelog); +} else { + stream.pipe(getOutputStream()) +} // When we are pre-pending the new changelog, then we need to wait for the input stream to be ending, // otherwise we can't write into the same destination. if (!isForce) { - inStream.on('end', function() { + previousChangelog.on('end', function() { stream.pipe(getOutputStream()); }); } diff --git a/scripts/sauce/sauce_connect_block.sh b/scripts/sauce/sauce_connect_block.sh index 7aa105032eda..4a519d288111 100755 --- a/scripts/sauce/sauce_connect_block.sh +++ b/scripts/sauce/sauce_connect_block.sh @@ -2,9 +2,24 @@ # Wait for Connect to be ready before exiting echo "Connecting to Sauce Labs" + + +# Wait for Saucelabs Connect to be ready before exiting +# Time out if we wait for more than 2 minutes, so the process won't run forever. +let "counter=0" + while [ ! -f $BROWSER_PROVIDER_READY_FILE ]; do + let "counter++" + + if [ $counter -gt 240 ]; then + echo + echo "Timed out after 2 minutes waiting for tunnel ready file" + exit 5 + fi + printf "." sleep .5 done + echo echo "Connected" diff --git a/scripts/sauce/sauce_connect_setup.sh b/scripts/sauce/sauce_connect_setup.sh index be110f567c53..3eb7e2202191 100755 --- a/scripts/sauce/sauce_connect_setup.sh +++ b/scripts/sauce/sauce_connect_setup.sh @@ -23,10 +23,10 @@ CONNECT_STDERR="$LOGS_DIR/sauce-connect.stderr" if [ `uname -s` = "Darwin" ]; then # If the user is running Mac, download the OSX version # https://en.wikipedia.org/wiki/Darwin_(operating_system) - CONNECT_URL="https://saucelabs.com/downloads/sc-4.3.11-osx.zip" + CONNECT_URL="https://saucelabs.com/downloads/sc-4.4.1-osx.zip" else # Otherwise, default to Linux for Travis-CI - CONNECT_URL="https://saucelabs.com/downloads/sc-4.3.11-linux.tar.gz" + CONNECT_URL="https://saucelabs.com/downloads/sc-4.4.1-linux.tar.gz" fi mkdir -p $CONNECT_DIR cd $CONNECT_DIR diff --git a/src/demo-app/button/button-demo.html b/src/demo-app/button/button-demo.html index e8d9b17ae78e..5fb68da3df3c 100644 --- a/src/demo-app/button/button-demo.html +++ b/src/demo-app/button/button-demo.html @@ -89,4 +89,16 @@ SEARCH +
+ + + + +
+
+ + + + +
diff --git a/src/demo-app/checkbox/checkbox-demo.html b/src/demo-app/checkbox/checkbox-demo.html index 9fd9c922cd8e..713f8b008d4c 100644 --- a/src/demo-app/checkbox/checkbox-demo.html +++ b/src/demo-app/checkbox/checkbox-demo.html @@ -2,6 +2,7 @@

md-checkbox: Basic Example

md-checkbox: Basic Example + +

Alignment:

@@ -41,4 +44,4 @@

md-checkbox: Basic Example

Nested Checklist

- \ No newline at end of file + diff --git a/src/demo-app/checkbox/checkbox-demo.ts b/src/demo-app/checkbox/checkbox-demo.ts index edab7a8fa15c..aed0335dc761 100644 --- a/src/demo-app/checkbox/checkbox-demo.ts +++ b/src/demo-app/checkbox/checkbox-demo.ts @@ -67,6 +67,7 @@ export class CheckboxDemo { isChecked: boolean = false; isDisabled: boolean = false; alignment: string = 'start'; + useAlternativeColor: boolean = false; printResult() { if (this.isIndeterminate) { @@ -74,4 +75,8 @@ export class CheckboxDemo { } return this.isChecked ? 'Yes!' : 'No!'; } + + checkboxColor() { + return this.useAlternativeColor ? 'primary' : 'accent'; + } } diff --git a/src/demo-app/demo-app-module.ts b/src/demo-app/demo-app-module.ts index 9c7b7ac2daba..5f4a02dc5f68 100644 --- a/src/demo-app/demo-app-module.ts +++ b/src/demo-app/demo-app-module.ts @@ -1,7 +1,7 @@ import {NgModule, ApplicationRef} from '@angular/core'; import {BrowserModule} from '@angular/platform-browser'; import {HttpModule} from '@angular/http'; -import {FormsModule} from '@angular/forms'; +import {FormsModule, ReactiveFormsModule} from '@angular/forms'; import {DemoApp, Home} from './demo-app/demo-app'; import {RouterModule} from '@angular/router'; import {MaterialModule} from '@angular/material'; @@ -32,15 +32,15 @@ import {SidenavDemo} from './sidenav/sidenav-demo'; import {SnackBarDemo} from './snack-bar/snack-bar-demo'; import {PortalDemo, ScienceJoke} from './portal/portal-demo'; import {MenuDemo} from './menu/menu-demo'; -import {TabsDemo} from './tabs/tab-group-demo'; - - +import {TabsDemo, SunnyTabContent, RainyTabContent, FoggyTabContent} from './tabs/tabs-demo'; +import {ProjectionDemo, ProjectionTestComponent} from './projection/projection-demo'; @NgModule({ imports: [ BrowserModule, FormsModule, HttpModule, + ReactiveFormsModule, RouterModule.forRoot(DEMO_APP_ROUTES), MaterialModule.forRoot(), ], @@ -67,6 +67,8 @@ import {TabsDemo} from './tabs/tab-group-demo'; PortalDemo, ProgressBarDemo, ProgressCircleDemo, + ProjectionDemo, + ProjectionTestComponent, RadioDemo, RippleDemo, RotiniPanel, @@ -76,9 +78,12 @@ import {TabsDemo} from './tabs/tab-group-demo'; SliderDemo, SlideToggleDemo, SpagettiPanel, - TabsDemo, ToolbarDemo, TooltipDemo, + TabsDemo, + SunnyTabContent, + RainyTabContent, + FoggyTabContent, ], entryComponents: [ DemoApp, diff --git a/src/demo-app/demo-app/demo-app.html b/src/demo-app/demo-app/demo-app.html index 15084fbcdc9f..2e4991ea82e4 100644 --- a/src/demo-app/demo-app/demo-app.html +++ b/src/demo-app/demo-app/demo-app.html @@ -1,34 +1,20 @@ - Button - Button Toggle - Card - Checkbox - Dialog - Gestures - Grid List - Icon - Input - List - Menu - Live Announcer - Overlay - Portal - Progress Bar - Progress Circle - Radio - Ripple - Select - Sidenav - Slider - Slide Toggle - Snack Bar - Tabs - Toolbar - Tooltip + + {{navItem.name}} + +
- Baseline + + + Baseline +
diff --git a/src/demo-app/demo-app/demo-app.ts b/src/demo-app/demo-app/demo-app.ts index 86442e6e90e4..ae2ab491bdf6 100644 --- a/src/demo-app/demo-app/demo-app.ts +++ b/src/demo-app/demo-app/demo-app.ts @@ -18,4 +18,34 @@ export class Home {} styleUrls: ['demo-app.css'], encapsulation: ViewEncapsulation.None, }) -export class DemoApp { } +export class DemoApp { + navItems = [ + {name: 'Button', route: 'button'}, + {name: 'Button Toggle', route: 'button-toggle'}, + {name: 'Card', route: 'card'}, + {name: 'Checkbox', route: 'checkbox'}, + {name: 'Dialog', route: 'dialog'}, + {name: 'Gestures', route: 'gestures'}, + {name: 'Grid List', route: 'grid-list'}, + {name: 'Icon', route: 'icon'}, + {name: 'Input', route: 'input'}, + {name: 'List', route: 'list'}, + {name: 'Menu', route: 'menu'}, + {name: 'Live Announcer', route: 'live-announcer'}, + {name: 'Overlay', route: 'overlay'}, + {name: 'Portal', route: 'portal'}, + {name: 'Projection', route: 'projection'}, + {name: 'Progress Bar', route: 'progress-bar'}, + {name: 'Progress Circle', route: 'progress-circle'}, + {name: 'Radio', route: 'radio'}, + {name: 'Ripple', route: 'ripple'}, + {name: 'Select', route: 'select'}, + {name: 'Sidenav', route: 'sidenav'}, + {name: 'Slider', route: 'slider'}, + {name: 'Slide Toggle', route: 'slide-toggle'}, + {name: 'Snack Bar', route: 'snack-bar'}, + {name: 'Tabs', route: 'tabs'}, + {name: 'Toolbar', route: 'toolbar'}, + {name: 'Tooltip', route: 'tooltip'} + ]; +} diff --git a/src/demo-app/demo-app/routes.ts b/src/demo-app/demo-app/routes.ts index b7c3fa47f3a7..f2e1cf7b68e9 100644 --- a/src/demo-app/demo-app/routes.ts +++ b/src/demo-app/demo-app/routes.ts @@ -3,7 +3,7 @@ import {Home} from './demo-app'; import {ButtonDemo} from '../button/button-demo'; import {BaselineDemo} from '../baseline/baseline-demo'; import {ButtonToggleDemo} from '../button-toggle/button-toggle-demo'; -import {TabsDemo} from '../tabs/tab-group-demo'; +import {TabsDemo} from '../tabs/tabs-demo'; import {GridListDemo} from '../grid-list/grid-list-demo'; import {GesturesDemo} from '../gestures/gestures-demo'; import {LiveAnnouncerDemo} from '../live-announcer/live-announcer-demo'; @@ -27,7 +27,8 @@ import {RippleDemo} from '../ripple/ripple-demo'; import {DialogDemo} from '../dialog/dialog-demo'; import {TooltipDemo} from '../tooltip/tooltip-demo'; import {SnackBarDemo} from '../snack-bar/snack-bar-demo'; - +import {ProjectionDemo} from '../projection/projection-demo'; +import {TABS_DEMO_ROUTES} from '../tabs/routes'; export const DEMO_APP_ROUTES: Routes = [ {path: '', component: Home}, @@ -41,6 +42,7 @@ export const DEMO_APP_ROUTES: Routes = [ {path: 'progress-circle', component: ProgressCircleDemo}, {path: 'progress-bar', component: ProgressBarDemo}, {path: 'portal', component: PortalDemo}, + {path: 'projection', component: ProjectionDemo}, {path: 'overlay', component: OverlayDemo}, {path: 'checkbox', component: CheckboxDemo}, {path: 'input', component: InputDemo}, @@ -51,7 +53,7 @@ export const DEMO_APP_ROUTES: Routes = [ {path: 'live-announcer', component: LiveAnnouncerDemo}, {path: 'gestures', component: GesturesDemo}, {path: 'grid-list', component: GridListDemo}, - {path: 'tabs', component: TabsDemo}, + {path: 'tabs', component: TabsDemo, children: TABS_DEMO_ROUTES}, {path: 'button-toggle', component: ButtonToggleDemo}, {path: 'baseline', component: BaselineDemo}, {path: 'ripple', component: RippleDemo}, diff --git a/src/demo-app/dialog/dialog-demo.ts b/src/demo-app/dialog/dialog-demo.ts index 6fb4e994c7ef..5935059be7c8 100644 --- a/src/demo-app/dialog/dialog-demo.ts +++ b/src/demo-app/dialog/dialog-demo.ts @@ -1,5 +1,5 @@ -import {Component, ViewContainerRef} from '@angular/core'; -import {MdDialog, MdDialogConfig, MdDialogRef} from '@angular/material'; +import {Component} from '@angular/core'; +import {MdDialog, MdDialogRef} from '@angular/material'; @Component({ moduleId: module.id, @@ -11,15 +11,10 @@ export class DialogDemo { dialogRef: MdDialogRef; lastCloseResult: string; - constructor( - public dialog: MdDialog, - public viewContainerRef: ViewContainerRef) { } + constructor(public dialog: MdDialog) { } open() { - let config = new MdDialogConfig(); - config.viewContainerRef = this.viewContainerRef; - - this.dialogRef = this.dialog.open(JazzDialog, config); + this.dialogRef = this.dialog.open(JazzDialog); this.dialogRef.afterClosed().subscribe(result => { this.lastCloseResult = result; @@ -34,8 +29,11 @@ export class DialogDemo { template: `

It's Jazz!

+

{{ jazzMessage }}

` }) export class JazzDialog { + jazzMessage = 'Jazzy jazz jazz'; + constructor(public dialogRef: MdDialogRef) { } } diff --git a/src/demo-app/input/input-demo.html b/src/demo-app/input/input-demo.html index bd79e8ccf017..1bef8bfd2df4 100644 --- a/src/demo-app/input/input-demo.html +++ b/src/demo-app/input/input-demo.html @@ -10,8 +10,8 @@

- - + +

@@ -39,15 +39,23 @@ Divider Colors +

Input

+ +

Textarea

+ + + +
Hints +

Input

{{characterCountHintExample.characterCount}} / 100

+ +

Textarea

+

+ + {{characterCountHintExample.characterCount}} / 100 + +

@@ -157,3 +174,9 @@
+ + + +

textarea autosize

+ +
diff --git a/src/demo-app/input/input-demo.scss b/src/demo-app/input/input-demo.scss index 97a9f93ea2df..b70dd6f1e573 100644 --- a/src/demo-app/input/input-demo.scss +++ b/src/demo-app/input/input-demo.scss @@ -18,3 +18,11 @@ .demo-card { margin: 16px; } + +.demo-textarea { + resize: none; + border: none; + overflow: auto; + padding: 0; + background: lightblue; +} diff --git a/src/demo-app/input/input-demo.ts b/src/demo-app/input/input-demo.ts index 36891a409f01..49dcfe0f56a8 100644 --- a/src/demo-app/input/input-demo.ts +++ b/src/demo-app/input/input-demo.ts @@ -21,6 +21,7 @@ export class InputDemo { { value: 40 }, { value: 50 }, ]; + rows = 8; addABunch(n: number) { for (let x = 0; x < n; x++) { diff --git a/src/demo-app/menu/menu-demo.html b/src/demo-app/menu/menu-demo.html index a28d9fd12f59..423b31d086ec 100644 --- a/src/demo-app/menu/menu-demo.html +++ b/src/demo-app/menu/menu-demo.html @@ -3,7 +3,7 @@

You clicked on: {{ selected }}

- @@ -17,7 +17,7 @@