From 498aa2baca8fcaec92cfea7f11e5f7126556a789 Mon Sep 17 00:00:00 2001 From: "Andrew C. Dvorak" Date: Thu, 24 May 2018 16:41:42 -0700 Subject: [PATCH 001/175] chore(infrastructure): Use component-specific test page dimensions (#2810) Fixes #2805 ### How to test ```bash export CBT_USERNAME='...' export CBT_AUTHKEY='...' export MDC_GCLOUD_SERVICE_ACCOUNT_KEY_FILE_PATH='...' npm run screenshot:test ``` ### What it does - Sets button-specific widths/heights with new `test-main--button` and `test-cell--button` classes - Sets FAB-specific widths/heights with new `test-main--fab` and `test-cell--fab` classes - Moves `mdc-button/mixins/custom.scss` to `mdc-button/custom.scss` - Changes `` to `
` - Removes and inlines some Sass variables ### Example output [Diff report](https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/05/24/19_19_57_797/3ac00277f/report.html) (**NOTE:** the first diff on the report is flaky - it is NOT included in this PR's `golden.json`) --- test/screenshot/fixture.scss | 12 +- test/screenshot/golden.json | 24 ++-- .../mdc-button/classes/baseline.html | 115 +++++++++--------- test/screenshot/mdc-button/classes/dense.html | 115 +++++++++--------- .../mdc-button/{mixins => }/custom.scss | 4 +- test/screenshot/mdc-button/fixture.scss | 24 ++++ .../mixins/container-fill-color.html | 17 +-- .../mdc-button/mixins/corner-radius.html | 37 +++--- .../mdc-button/mixins/filled-accessible.html | 29 ++--- .../mixins/horizontal-padding-baseline.html | 85 ++++++------- .../mixins/horizontal-padding-dense.html | 85 ++++++------- .../mdc-button/mixins/icon-color.html | 37 +++--- .../mdc-button/mixins/ink-color.html | 53 ++++---- .../mdc-button/mixins/stroke-color.html | 17 +-- .../mdc-button/mixins/stroke-width.html | 55 +++++---- test/screenshot/mdc-fab/classes/baseline.html | 39 +++--- test/screenshot/mdc-fab/classes/mini.html | 39 +++--- test/screenshot/mdc-fab/fixture.scss | 24 ++++ 18 files changed, 432 insertions(+), 379 deletions(-) rename test/screenshot/mdc-button/{mixins => }/custom.scss (93%) create mode 100644 test/screenshot/mdc-button/fixture.scss create mode 100644 test/screenshot/mdc-fab/fixture.scss diff --git a/test/screenshot/fixture.scss b/test/screenshot/fixture.scss index 8391ecc702c..200523b7b08 100644 --- a/test/screenshot/fixture.scss +++ b/test/screenshot/fixture.scss @@ -19,11 +19,6 @@ $test-trim-color: #abc123; // Value must match `TRIM_COLOR_CSS_VALUE` in `image-cropper.js` $test-grid-color: #dddddd; -$test-fixture-width: 348px; -$test-button-cell-padding: 10px; -$test-button-cell-width: 171px; -$test-button-cell-height: 71px; -$test-button-columns: 2; .test-body { display: flex; @@ -34,7 +29,6 @@ $test-button-columns: 2; .test-main { box-sizing: border-box; - width: $test-fixture-width; border: 1px solid $test-trim-color; } @@ -46,12 +40,10 @@ $test-button-columns: 2; .test-cell { box-sizing: border-box; - width: $test-button-cell-width; - height: $test-button-cell-height; margin: 1px; // Ensure that shadows from adjacent components don't overlap - padding: $test-button-cell-padding; + padding: 10px; // Ruler grid pattern // https://stackoverflow.com/a/32861765/467582 @@ -59,5 +51,5 @@ $test-button-columns: 2; linear-gradient(to right, #{$test-grid-color} 1px, transparent 1.01px), // fraction for IE 11 linear-gradient(to bottom, #{$test-grid-color} 1px, transparent 1.01px); // fraction for IE 11 - background-size: #{$test-button-cell-padding} #{$test-button-cell-padding}; + background-size: 10px 10px; } diff --git a/test/screenshot/golden.json b/test/screenshot/golden.json index 032017e6d6a..e60e908cf29 100644 --- a/test/screenshot/golden.json +++ b/test/screenshot/golden.json @@ -110,23 +110,23 @@ } }, "mdc-fab/classes/baseline.html": { - "publicUrl": "https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/05/22/16_23_58_618/af3d7271f/mdc-fab/classes/baseline.html", + "publicUrl": "https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/05/24/19_19_57_797/3ac00277f/mdc-fab/classes/baseline.html", "screenshots": { - "desktop_windows_chrome@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/05/22/16_23_58_618/af3d7271f/mdc-fab/classes/baseline.html.win10e15_chrome66x64.png", - "desktop_windows_edge@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/05/22/16_23_58_618/af3d7271f/mdc-fab/classes/baseline.html.win10e17_edge17.png", - "desktop_windows_firefox@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/05/22/16_23_58_618/af3d7271f/mdc-fab/classes/baseline.html.win10e14_ff59x64.png", - "desktop_windows_ie@11": "https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/05/22/16_23_58_618/af3d7271f/mdc-fab/classes/baseline.html.win10e14_ie11.png", - "mobile_android_chrome@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/05/22/16_23_58_618/af3d7271f/mdc-fab/classes/baseline.html.galaxys7and70_mblchrome64.png" + "desktop_windows_chrome@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/05/24/19_19_57_797/3ac00277f/mdc-fab/classes/baseline.html.win10_chrome66x64.png", + "desktop_windows_edge@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/05/24/19_19_57_797/3ac00277f/mdc-fab/classes/baseline.html.win10_edge17.png", + "desktop_windows_firefox@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/05/24/19_19_57_797/3ac00277f/mdc-fab/classes/baseline.html.win10_ff59x64.png", + "desktop_windows_ie@11": "https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/05/24/19_19_57_797/3ac00277f/mdc-fab/classes/baseline.html.win10_ie11.png", + "mobile_android_chrome@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/05/24/19_19_57_797/3ac00277f/mdc-fab/classes/baseline.html.galaxys7and70_mblchrome64.png" } }, "mdc-fab/classes/mini.html": { - "publicUrl": "https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/05/22/16_23_58_618/af3d7271f/mdc-fab/classes/mini.html", + "publicUrl": "https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/05/24/19_19_57_797/3ac00277f/mdc-fab/classes/mini.html", "screenshots": { - "desktop_windows_chrome@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/05/22/16_23_58_618/af3d7271f/mdc-fab/classes/mini.html.win10e15_chrome66x64.png", - "desktop_windows_edge@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/05/22/16_23_58_618/af3d7271f/mdc-fab/classes/mini.html.win10e17_edge17.png", - "desktop_windows_firefox@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/05/22/16_23_58_618/af3d7271f/mdc-fab/classes/mini.html.win10e14_ff59x64.png", - "desktop_windows_ie@11": "https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/05/22/16_23_58_618/af3d7271f/mdc-fab/classes/mini.html.win10e14_ie11.png", - "mobile_android_chrome@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/05/22/16_23_58_618/af3d7271f/mdc-fab/classes/mini.html.galaxys7and70_mblchrome64.png" + "desktop_windows_chrome@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/05/24/19_19_57_797/3ac00277f/mdc-fab/classes/mini.html.win10_chrome66x64.png", + "desktop_windows_edge@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/05/24/19_19_57_797/3ac00277f/mdc-fab/classes/mini.html.win10_edge17.png", + "desktop_windows_firefox@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/05/24/19_19_57_797/3ac00277f/mdc-fab/classes/mini.html.win10_ff59x64.png", + "desktop_windows_ie@11": "https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/05/24/19_19_57_797/3ac00277f/mdc-fab/classes/mini.html.win10_ie11.png", + "mobile_android_chrome@latest": "https://storage.googleapis.com/mdc-web-screenshot-tests/advorak/2018/05/24/19_19_57_797/3ac00277f/mdc-fab/classes/mini.html.galaxys7and70_mblchrome64.png" } } } diff --git a/test/screenshot/mdc-button/classes/baseline.html b/test/screenshot/mdc-button/classes/baseline.html index 2352a7964e3..f72a5508309 100644 --- a/test/screenshot/mdc-button/classes/baseline.html +++ b/test/screenshot/mdc-button/classes/baseline.html @@ -21,24 +21,25 @@ + -
+
- +
- - +
+
Link - - +
+
- - +
+
- - +
+
- - +
+
- - +
+
- - +
+
Link - - +
+
- - +
+
- - +
+
- - +
+
- - +
+
- - +
+
Link - - +
+
- - +
+
- - +
+
- - +
+
- - +
+
- - +
+
Link - - +
+
- - +
+
- - +
+
- - +
+
- - +
+
- - +
+
- - +
+
- - +
+
- +
diff --git a/test/screenshot/mdc-button/classes/dense.html b/test/screenshot/mdc-button/classes/dense.html index ec8a94783cf..7bbae881d2e 100644 --- a/test/screenshot/mdc-button/classes/dense.html +++ b/test/screenshot/mdc-button/classes/dense.html @@ -21,24 +21,25 @@ + -
+
- +
- - +
+
Link - - +
+
- - +
+
- - +
+
- - +
+
- - +
+
- - +
+
Link - - +
+
- - +
+
- - +
+
- - +
+
- - +
+
- - +
+
Link - - +
+
- - +
+
- - +
+
- - +
+
- - +
+
- - +
+
Link - - +
+
- - +
+
- - +
+
- - +
+
- - +
+
- - +
+
- - +
+
- - +
+
- +
diff --git a/test/screenshot/mdc-button/mixins/custom.scss b/test/screenshot/mdc-button/custom.scss similarity index 93% rename from test/screenshot/mdc-button/mixins/custom.scss rename to test/screenshot/mdc-button/custom.scss index 177d7e15678..344fdb1bb2e 100644 --- a/test/screenshot/mdc-button/mixins/custom.scss +++ b/test/screenshot/mdc-button/custom.scss @@ -14,8 +14,8 @@ // limitations under the License. // -@import "../../../../packages/mdc-button/mixins"; -@import "../../../../packages/mdc-theme/color-palette"; +@import "../../../packages/mdc-button/mixins"; +@import "../../../packages/mdc-theme/color-palette"; $custom-button-color: $material-color-red-300; $custom-button-custom-corner-radius: 8px; diff --git a/test/screenshot/mdc-button/fixture.scss b/test/screenshot/mdc-button/fixture.scss new file mode 100644 index 00000000000..47fb0d9a316 --- /dev/null +++ b/test/screenshot/mdc-button/fixture.scss @@ -0,0 +1,24 @@ +// +// Copyright 2018 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +.test-main--button { + width: 348px; // fits 2 columns of buttons within a Galaxy S7 viewport +} + +.test-cell--button { + width: 171px; + height: 71px; +} diff --git a/test/screenshot/mdc-button/mixins/container-fill-color.html b/test/screenshot/mdc-button/mixins/container-fill-color.html index 4a755356308..3a910a5d926 100644 --- a/test/screenshot/mdc-button/mixins/container-fill-color.html +++ b/test/screenshot/mdc-button/mixins/container-fill-color.html @@ -21,21 +21,22 @@ - + + -
+
- +
- - +
+
Link - - +
+
- +
diff --git a/test/screenshot/mdc-button/mixins/corner-radius.html b/test/screenshot/mdc-button/mixins/corner-radius.html index 88475bdd55e..4cba8df7e11 100644 --- a/test/screenshot/mdc-button/mixins/corner-radius.html +++ b/test/screenshot/mdc-button/mixins/corner-radius.html @@ -21,36 +21,37 @@ - + + -
+
- +
- - +
+
- - +
+
- - +
+
- - +
+
- - +
+
- - +
+
- - +
+
- +
diff --git a/test/screenshot/mdc-button/mixins/filled-accessible.html b/test/screenshot/mdc-button/mixins/filled-accessible.html index d5c549b25f7..670468c3147 100644 --- a/test/screenshot/mdc-button/mixins/filled-accessible.html +++ b/test/screenshot/mdc-button/mixins/filled-accessible.html @@ -21,25 +21,26 @@ - + + -
+
- +
- - +
+
Link - - +
+
- - +
+
- - +
+
- - +
+
- +
diff --git a/test/screenshot/mdc-button/mixins/horizontal-padding-baseline.html b/test/screenshot/mdc-button/mixins/horizontal-padding-baseline.html index 0f25e342a94..19308c95bbd 100644 --- a/test/screenshot/mdc-button/mixins/horizontal-padding-baseline.html +++ b/test/screenshot/mdc-button/mixins/horizontal-padding-baseline.html @@ -21,72 +21,73 @@ - + + -
+
- +
- - +
+
Link - - +
+
- - +
+
- - +
+
- - +
+
Link - - +
+
- - +
+
- - +
+
- - +
+
Link - - +
+
- - +
+
- - +
+
- - +
+
Link - - +
+
- - +
+
- - +
+
- - +
+
- - +
+
- - +
+
- +
diff --git a/test/screenshot/mdc-button/mixins/horizontal-padding-dense.html b/test/screenshot/mdc-button/mixins/horizontal-padding-dense.html index 15a565da9ee..24b077e30f4 100644 --- a/test/screenshot/mdc-button/mixins/horizontal-padding-dense.html +++ b/test/screenshot/mdc-button/mixins/horizontal-padding-dense.html @@ -21,72 +21,73 @@ - + + -
+
- +
- - +
+
Link - - +
+
- - +
+
- - +
+
- - +
+
Link - - +
+
- - +
+
- - +
+
- - +
+
Link - - +
+
- - +
+
- - +
+
- - +
+
Link - - +
+
- - +
+
- - +
+
- - +
+
- - +
+
- - +
+
- +
diff --git a/test/screenshot/mdc-button/mixins/icon-color.html b/test/screenshot/mdc-button/mixins/icon-color.html index b67ca8a76a2..5fba3e67325 100644 --- a/test/screenshot/mdc-button/mixins/icon-color.html +++ b/test/screenshot/mdc-button/mixins/icon-color.html @@ -21,19 +21,20 @@ - + + -
+
- +
- - +
+
- - +
+
- - +
+
- - +
+
- - +
+
- - +
+
- - +
+
- +
diff --git a/test/screenshot/mdc-button/mixins/ink-color.html b/test/screenshot/mdc-button/mixins/ink-color.html index 2c36a05549a..fda7ffd561c 100644 --- a/test/screenshot/mdc-button/mixins/ink-color.html +++ b/test/screenshot/mdc-button/mixins/ink-color.html @@ -21,25 +21,26 @@ - + + -
+
- +
- - +
+
Link - - +
+
- - +
+
- - +
+
- - +
+
- - +
+
- - +
+
Link - - +
+
- - +
+
- - +
+
- - +
+
- +
diff --git a/test/screenshot/mdc-button/mixins/stroke-color.html b/test/screenshot/mdc-button/mixins/stroke-color.html index f59ad70fb0d..22f8d15edce 100644 --- a/test/screenshot/mdc-button/mixins/stroke-color.html +++ b/test/screenshot/mdc-button/mixins/stroke-color.html @@ -21,21 +21,22 @@ - + + -
+
- +
- - +
+
Link - - +
+
- +
diff --git a/test/screenshot/mdc-button/mixins/stroke-width.html b/test/screenshot/mdc-button/mixins/stroke-width.html index 9fcca8c4468..99e3a21cd78 100644 --- a/test/screenshot/mdc-button/mixins/stroke-width.html +++ b/test/screenshot/mdc-button/mixins/stroke-width.html @@ -12,7 +12,7 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and - limitations under the License + limitations under the License. --> @@ -21,25 +21,26 @@ - + + -
+
- +
- - +
+
Link - - +
+
- - +
+
- - +
+
- - +
+
- - +
+
- - +
+
Link - - +
+
- - +
+
- - +
+
- - +
+
- +
diff --git a/test/screenshot/mdc-fab/classes/baseline.html b/test/screenshot/mdc-fab/classes/baseline.html index 39c3e44517d..b24cd65b9e9 100644 --- a/test/screenshot/mdc-fab/classes/baseline.html +++ b/test/screenshot/mdc-fab/classes/baseline.html @@ -1,19 +1,19 @@ + Copyright 2018 Google Inc. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License +--> @@ -21,26 +21,27 @@ + -
+
- +
- - +
+
- +
diff --git a/test/screenshot/mdc-fab/classes/mini.html b/test/screenshot/mdc-fab/classes/mini.html index 92dea5a49e9..5ca22b2fa91 100644 --- a/test/screenshot/mdc-fab/classes/mini.html +++ b/test/screenshot/mdc-fab/classes/mini.html @@ -1,19 +1,19 @@ + Copyright 2018 Google Inc. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License +--> @@ -21,26 +21,27 @@ + -
+
- +
- - +
+
- +
diff --git a/test/screenshot/mdc-fab/fixture.scss b/test/screenshot/mdc-fab/fixture.scss new file mode 100644 index 00000000000..84cb1349b81 --- /dev/null +++ b/test/screenshot/mdc-fab/fixture.scss @@ -0,0 +1,24 @@ +// +// Copyright 2018 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +.test-main--fab { + width: 334px; // fits 4 columns of FABs within a Galaxy S7 viewport +} + +.test-cell--fab { + width: 81px; + height: 81px; +} From e793a564878b85085ae2a3cdcddaf366e06b5ed6 Mon Sep 17 00:00:00 2001 From: yezhi Date: Fri, 25 May 2018 22:30:09 +0800 Subject: [PATCH 002/175] fix(dialog): Fix Typography version (#2821) --- packages/mdc-dialog/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mdc-dialog/package.json b/packages/mdc-dialog/package.json index d20c119de69..eb081fe3cf4 100644 --- a/packages/mdc-dialog/package.json +++ b/packages/mdc-dialog/package.json @@ -21,7 +21,7 @@ "@material/ripple": "^0.35.0", "@material/rtl": "^0.35.0", "@material/theme": "^0.35.0", - "@material/typography": "^0.1.1", + "@material/typography": "^0.35.0", "focus-trap": "^2.3.0" }, "publishConfig": { From 16a68904d4584323c505fbe98191dedd715d2dd9 Mon Sep 17 00:00:00 2001 From: Abhinay Omkar Date: Fri, 25 May 2018 11:46:53 -0400 Subject: [PATCH 003/175] fix(ripple): Fix missing dependency (#2795) --- packages/mdc-ripple/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/mdc-ripple/package.json b/packages/mdc-ripple/package.json index e083d4f5920..8a89c758fa7 100644 --- a/packages/mdc-ripple/package.json +++ b/packages/mdc-ripple/package.json @@ -15,6 +15,7 @@ }, "dependencies": { "@material/base": "^0.35.0", - "@material/theme": "^0.35.0" + "@material/theme": "^0.35.0", + "@material/animation": "^0.34.0" } } From 39a481597f87e872caf92ef31249279bce665c07 Mon Sep 17 00:00:00 2001 From: Will Ernest <34519388+williamernest@users.noreply.github.com> Date: Fri, 25 May 2018 09:40:44 -0700 Subject: [PATCH 004/175] feat(icon-button): Add new package (#2748) --- demos/card.html | 62 ++- demos/card.scss | 2 +- demos/icon-button.html | 256 ++++++++++++ demos/{icon-toggle.scss => icon-button.scss} | 26 +- demos/icon-toggle.html | 174 --------- demos/index.html | 6 +- demos/theme/_theme-shared.scss | 8 +- demos/theme/index.html | 66 ++-- docs/authoring-components.md | 2 +- docs/migrating-from-mdl.md | 2 +- package.json | 2 + packages/material-components-web/README.md | 20 +- packages/material-components-web/index.js | 3 + .../material-components-web.scss | 1 + packages/material-components-web/package.json | 1 + packages/mdc-card/README.md | 24 +- packages/mdc-card/mdc-card.scss | 2 +- packages/mdc-icon-button/README.md | 170 ++++++++ packages/mdc-icon-button/_mixins.scss | 64 +++ packages/mdc-icon-button/_variables.scss | 17 + packages/mdc-icon-button/adapter.js | 93 +++++ packages/mdc-icon-button/constants.js | 36 ++ packages/mdc-icon-button/foundation.js | 158 ++++++++ packages/mdc-icon-button/index.js | 100 +++++ packages/mdc-icon-button/mdc-icon-button.scss | 32 ++ packages/mdc-icon-button/package.json | 25 ++ scripts/webpack/css-bundle-factory.js | 1 + scripts/webpack/js-bundle-factory.js | 1 + test/unit/mdc-icon-button/foundation.test.js | 217 +++++++++++ .../mdc-icon-button-toggle.test.js} | 71 +--- test/unit/mdc-icon-toggle/foundation.test.js | 363 ------------------ 31 files changed, 1299 insertions(+), 706 deletions(-) create mode 100644 demos/icon-button.html rename demos/{icon-toggle.scss => icon-button.scss} (79%) delete mode 100644 demos/icon-toggle.html create mode 100644 packages/mdc-icon-button/README.md create mode 100644 packages/mdc-icon-button/_mixins.scss create mode 100644 packages/mdc-icon-button/_variables.scss create mode 100644 packages/mdc-icon-button/adapter.js create mode 100644 packages/mdc-icon-button/constants.js create mode 100644 packages/mdc-icon-button/foundation.js create mode 100644 packages/mdc-icon-button/index.js create mode 100644 packages/mdc-icon-button/mdc-icon-button.scss create mode 100644 packages/mdc-icon-button/package.json create mode 100644 test/unit/mdc-icon-button/foundation.test.js rename test/unit/{mdc-icon-toggle/mdc-icon-toggle.test.js => mdc-icon-button/mdc-icon-button-toggle.test.js} (71%) delete mode 100644 test/unit/mdc-icon-toggle/foundation.test.js diff --git a/demos/card.html b/demos/card.html index fe0447d4ca0..958eee401a9 100644 --- a/demos/card.html +++ b/demos/card.html @@ -58,26 +58,20 @@

by Kurt Wagner

- - favorite_border - - favorite_border + +
@@ -152,31 +146,25 @@

Asia's clean ener
- - favorite_border - - favorite_border + +
@@ -245,15 +233,15 @@

Asia's clean ener mdc.ripple.MDCRipple.attachTo(surface); }); - [].forEach.call(document.querySelectorAll('.mdc-icon-toggle'), function(iconToggle) { - mdc.iconToggle.MDCIconToggle.attachTo(iconToggle); + [].forEach.call(document.querySelectorAll('.mdc-icon-button[data-toggle-on-content]'), function(iconButtonToggle) { + mdc.iconButton.MDCIconButtonToggle.attachTo(iconButtonToggle); }); - document.addEventListener('MDCIconToggle:change', function(evt) { + document.addEventListener('MDCIconButtonToggle:change', function(evt) { evt.target.setAttribute('title', evt.target.getAttribute('aria-label')); }); - [].forEach.call(document.querySelectorAll('.mdc-ripple-surface'), function(surface) { + [].forEach.call(document.querySelectorAll('.mdc-ripple-surface, [data-mdc-ripple-is-unbounded]'), function(surface) { mdc.ripple.MDCRipple.attachTo(surface); }); diff --git a/demos/card.scss b/demos/card.scss index c21f49ae171..faa5b9508f9 100644 --- a/demos/card.scss +++ b/demos/card.scss @@ -19,7 +19,7 @@ @import "../packages/mdc-card/mdc-card"; @import "../packages/mdc-checkbox/mdc-checkbox"; @import "../packages/mdc-form-field/mdc-form-field"; -@import "../packages/mdc-icon-toggle/mdc-icon-toggle"; +@import "../packages/mdc-icon-button/mdc-icon-button"; @import "../packages/mdc-list/mdc-list"; @import "../packages/mdc-ripple/mdc-ripple"; diff --git a/demos/icon-button.html b/demos/icon-button.html new file mode 100644 index 00000000000..02a71729055 --- /dev/null +++ b/demos/icon-button.html @@ -0,0 +1,256 @@ + + + + + + Icon Button - Material Components Demo + + + + + + + + + + +
+
+
+ + Icon Buttons +
+
+
+
+
+
+
+ +
+
+ +
+
+
+

Buttons

+
+
+
+

Material Icons

+
+ + + directions_transit +
+
+ +
+

SVG Icon

+
+ +
+
+ +
+

Disabled Buttons

+
+ + +
+
+ +
+

Larger Buttons

+
+ + +
+
+
+
+
+ +
+
+
+

Button Toggles

+
+
+
+

Using Material Icons

+
+ +
+

Favorited? no

+
+ +
+

Using Font Awesome

+
+ +
+
+ +
+

Disabled Icons

+
+ +
+
+
+ +
+

Additional Color Combinations

+
+
+
+ +
+
Light icon on background
+
+
+
+ +
+
Dark icon on background
+
+
+
+ +
+
Custom color
+
+
+
+
+
+
+ + + + + + diff --git a/demos/icon-toggle.scss b/demos/icon-button.scss similarity index 79% rename from demos/icon-toggle.scss rename to demos/icon-button.scss index 3e2a49252ec..afdc53bed7c 100644 --- a/demos/icon-toggle.scss +++ b/demos/icon-button.scss @@ -15,7 +15,7 @@ // @import "./common"; -@import "../packages/mdc-icon-toggle/mdc-icon-toggle"; +@import "../packages/mdc-icon-button/mdc-icon-button"; @import "../packages/mdc-ripple/mixins"; .demo-wrapper { @@ -30,9 +30,13 @@ } .toggle-example { - min-width: 240px; - padding: 24px; + min-width: 260px; margin: 24px; + padding: 24px; +} + +.toggle-examples-container { + display: flex; } #demo-color-combos { @@ -55,8 +59,8 @@ #light-on-bg { background-color: #3e82f7; } -#light-on-bg .mdc-icon-toggle { - @include mdc-icon-toggle-ink-color(white); +#light-on-bg .mdc-icon-button { + @include mdc-icon-button-ink-color(white); @include mdc-states-base-color(white); @include mdc-states-hover-opacity(.1); @include mdc-states-focus-opacity(.3); @@ -66,15 +70,19 @@ #dark-on-bg { background-color: #00bcd6; } -#dark-on-bg .mdc-icon-toggle { - @include mdc-icon-toggle-ink-color(black); +#dark-on-bg .mdc-icon-button { + @include mdc-icon-button-ink-color(black); @include mdc-states(black); } -#custom-color-combo .mdc-icon-toggle { - @include mdc-icon-toggle-ink-color(#de442c); +#custom-color-combo .mdc-icon-button { + @include mdc-icon-button-ink-color(#de442c); @include mdc-states-base-color(#de442c); @include mdc-states-hover-opacity(.09); @include mdc-states-focus-opacity(.26); @include mdc-states-press-opacity(.35); } + +.demo-icon-button-large { + @include mdc-icon-button-size(36px); +} diff --git a/demos/icon-toggle.html b/demos/icon-toggle.html deleted file mode 100644 index 04776478341..00000000000 --- a/demos/icon-toggle.html +++ /dev/null @@ -1,174 +0,0 @@ - - - - - - Icon Toggle - Material Components Demo - - - - - - - - - - -
-
-
- - Icon Toggle -
-
-
-
-
-
-
- - - favorite_border - -
-
- -
-
-

Using Material Icons

-
- - - favorite_border - -
-

Favorited? no

-
- -
-

Using Font Awesome

-
- - - -
-
- -
-

Disabled Icons

-
- - favorite_border - -
-
- -
-

Additional Color Combinations

-
-
-
- - favorite_border - -
-
Light icon on background
-
-
-
- - favorite_border - -
-
Dark icon on background
-
-
-
- - favorite_border - -
-
Custom color
-
-
-
-
-
- - - - - diff --git a/demos/index.html b/demos/index.html index 894acbb6e0b..1ab46be89d9 100644 --- a/demos/index.html +++ b/demos/index.html @@ -103,11 +103,11 @@ - + - Icon toggle - Toggling icon states + Icon button + Icon buttons and toggles diff --git a/demos/theme/_theme-shared.scss b/demos/theme/_theme-shared.scss index 10464e881e0..9fa6051f08b 100644 --- a/demos/theme/_theme-shared.scss +++ b/demos/theme/_theme-shared.scss @@ -23,7 +23,7 @@ @import "../../packages/mdc-elevation/mdc-elevation"; @import "../../packages/mdc-fab/mdc-fab"; @import "../../packages/mdc-form-field/mdc-form-field"; -@import "../../packages/mdc-icon-toggle/mdc-icon-toggle"; +@import "../../packages/mdc-icon-button/mdc-icon-button"; @import "../../packages/mdc-linear-progress/mdc-linear-progress"; @import "../../packages/mdc-list/mdc-list"; @import "../../packages/mdc-menu/mdc-menu"; @@ -294,6 +294,8 @@ figure { // .demo-drawer-toggle { + @include mdc-states(on-primary); + vertical-align: middle; cursor: pointer; } @@ -327,8 +329,8 @@ figure { // Icon Toggle demo // -.mdc-icon-toggle { - // .material-icons and .mdc-icon-toggle each set different `display` values. Whichever CSS file is imported last +.mdc-icon-button { + // .material-icons and .mdc-icon-button each set different `display` values. Whichever CSS file is imported last // will win, so prevent them from fighting by specifying the value we want here. display: inline-flex; } diff --git a/demos/theme/index.html b/demos/theme/index.html index 8abbd4b3d39..e149a28d384 100644 --- a/demos/theme/index.html +++ b/demos/theme/index.html @@ -35,12 +35,12 @@
- + Color Theming
@@ -509,30 +503,26 @@

Enabled

- - favorite_border - + data-toggle-on-content="favorite" + data-toggle-on-label="Remove from favorites" + data-toggle-off-content="favorite_border" + data-toggle-off-label="Add to favorites">favorite_border

Disabled

- - favorite_border - + disabled + data-toggle-on-content="favorite" + data-toggle-on-label="Remove from favorites" + data-toggle-off-content="favorite_border" + data-toggle-off-label="Add to favorites">favorite_border
@@ -894,12 +884,20 @@

mdc.ripple.MDCRipple.attachTo(fab); }); + /* + * Icon Button + */ + + [].forEach.call(document.querySelectorAll('[data-mdc-ripple-is-unbounded]'), function(iconButtonEl) { + mdc.ripple.MDCRipple.attachTo(iconButtonEl); + }); + /* * Icon Toggle */ - [].forEach.call(document.querySelectorAll('.mdc-icon-toggle'), function(iconToggleEl) { - mdc.iconToggle.MDCIconToggle.attachTo(iconToggleEl); + [].forEach.call(document.querySelectorAll('.mdc-icon-button[data-toggle-on-content]'), function(iconButtonToggleEl) { + mdc.iconButton.MDCIconButtonToggle.attachTo(iconButtonToggleEl); }); /* diff --git a/docs/authoring-components.md b/docs/authoring-components.md index 71827db7ad2..dbec73e61da 100644 --- a/docs/authoring-components.md +++ b/docs/authoring-components.md @@ -753,7 +753,7 @@ Concretely: - Ensure that the correct **commit subject** for the package is added to the `config.validate-commit-msg.scope.allowed` array within the top-level `package.json` at the root of the repo. The commit subject is the _name the component, without the `mdc-`/`@material/`_. - E.g., for `mdc-icon-toggle`, the correct subject is `icon-toggle`. + E.g., for `mdc-icon-button`, the correct subject is `icon-button`. - Ensure that the package name is added to the `closureWhitelist` array within the top-level `package.json`. diff --git a/docs/migrating-from-mdl.md b/docs/migrating-from-mdl.md index ebceaf2156a..0a8cbb66729 100644 --- a/docs/migrating-from-mdl.md +++ b/docs/migrating-from-mdl.md @@ -305,7 +305,7 @@ The following table summarizes the current situation (TBI = to be investigated): | `mdl-dialog` | [`@material/dialog`](../packages/mdc-dialog/README.md) | Sufficiently different from MDL. MDL uses the `dialog` element which has limited cross-browser support. `mdc-dialog` relies on elements with more cross-browser support. | | `mdl-footer` | None | Not currently planned for MDC Web. | | `mdl-grid` | [`@material/layout-grid`](../packages/mdc-layout-grid/README.md) | Very similar. No offsets in MDC Web. | -| `mdl-icon-toggle` | [`@material/icon-toggle`](../packages/mdc-icon-toggle/README.md) | Very different DOM. | +| `mdl-icon-toggle` | [`@material/icon-button`](../packages/mdc-icon-button/README.md) | Very different DOM. | | `mdl-layout` | Split into [`@material/drawer`](../packages/mdc-drawer/README.md), [`@material/top-app-bar`](../packages/mdc-top-app-bar/README.md), [`@material/layout-grid`](../packages/mdc-layout-grid/README.md), and [`@material/tabs`](../packages/mdc-tabs/README.md) | Different DOM and variants. | | `mdl-list` | [`@material/list`](../packages/mdc-list/README.md) | Very different DOM. | | `mdl-menu` | [`@material/menu`](../packages/mdc-menu/README.md) | Very different DOM. | diff --git a/package.json b/package.json index 337e1ef43dd..3fe6aa3da01 100644 --- a/package.json +++ b/package.json @@ -155,6 +155,7 @@ "floating-label", "form-field", "grid-list", + "icon-button", "icon-toggle", "image-list", "layout-grid", @@ -197,6 +198,7 @@ "mdc-chips", "mdc-floating-label", "mdc-form-field", + "mdc-icon-button", "mdc-icon-toggle", "mdc-line-ripple", "mdc-menu", diff --git a/packages/material-components-web/README.md b/packages/material-components-web/README.md index cc234943c26..0c50a71777c 100644 --- a/packages/material-components-web/README.md +++ b/packages/material-components-web/README.md @@ -36,17 +36,17 @@ The `material-components-web` package automatically registers all MDC Web compon [mdc-auto-init](../mdc-auto-init), making it dead simple to create and initialize components with zero configuration or manual work. -For example, say you want to use an [icon toggle](../mdc-icon-toggle). Simply render the necessary -DOM, and attach the `data-mdc-auto-init="MDCIconToggle"` attribute. +For example, say you want to use an [icon button toogle](../mdc-icon-button). Simply render the necessary +DOM, and attach the `data-mdc-auto-init="MDCICconButtonToggle"` attribute. ```html - - favorite_border - +
- share - more_vert + +
@@ -121,18 +121,16 @@ above, or with icon buttons, as below: ```html
- - favorite_border - - share - more_vert + data-toggle-on-content="favorite" + data-toggle-on-label="Remove from favorites" + data-toggle-off-content="favorite_border" + data-toggle-off-label="Add to favorites">favorite_border + +
``` @@ -160,8 +158,8 @@ elements:
- share - more_vert + +
``` diff --git a/packages/mdc-card/mdc-card.scss b/packages/mdc-card/mdc-card.scss index c8a75837809..51e0108c900 100644 --- a/packages/mdc-card/mdc-card.scss +++ b/packages/mdc-card/mdc-card.scss @@ -187,7 +187,7 @@ // Icon toggles are taller than buttons, so we need to adjust their margins to prevent the action row from expanding. margin: -6px 0; - // Same padding as mdc-icon-toggle. + // Same padding as mdc-icon-button. padding: 12px; } diff --git a/packages/mdc-icon-button/README.md b/packages/mdc-icon-button/README.md new file mode 100644 index 00000000000..974b0daea80 --- /dev/null +++ b/packages/mdc-icon-button/README.md @@ -0,0 +1,170 @@ + + +# Icon Buttons + + + +Icon buttons allow users to take actions, and make choices, with a single tap. + +## Design & API Documentation + + + +## Installation + +``` +npm install @material/icon-button +``` + +## Usage + +### HTML Structure + +```html + +``` + +> Note: The MDC Icon Button can be used with ` +``` + +```js +var toggleButton = new mdc.iconButton.MDCIconButtonToggle(document.getElementById('add-to-favorites')); +``` + +#### Icon Button Toggle States + +Note the use of `data-toggle-*` properties in the above examples. When an MDCIconButtonToggle +instance is toggled, it looks at these data attributes to determine how to update the element. This is what +allows MDCIconButtonToggle to be so flexible. The `data-toggle-on-*` properties will be used when the is +MDCIconButtonToggle is toggled on, and vice versa for `data-toggle-off-*`. + +Attribute | Description +--- | --- +`data-toggle--label` | The value to apply to the element's "aria-label" attribute. +`data-toggle--content` | The text content to set on the element. Note that if an inner icon is used, the text content will be set on that element instead. +`data-toggle--class` | A CSS class to apply to the icon element. The same rules regarding inner icon elements described for `content` apply here as well. + +### Icons + +The icon button can be used with a standard icon library or an `svg`. The icon button toggle should only be used with +an standard icon library. We recommend you use [Material Icons](https://material.io/tools/icons) from Google Fonts. + +### Disabled + +To disable an icon, add the `disabled` attribute directly to the ` +``` + +## Style Customization + +### CSS Classes + +CSS Class | Description +--- | --- +`mdc-icon-button` | Mandatory. + +### Sass Mixins + +To customize an icon button's color and properties, you can use the following mixins. + +Mixin | Description +--- | --- +`mdc-icon-button-size($width, $height, $padding)` | Sets the width, height, font-size and padding for the icon and ripple. `$height` is optional and defaults to `$width`. `$padding` is optional and defaults to `max($width, $height)/2`. `font-size` is set to `max($width, $height)`. +`mdc-icon-button-ink-color($color)` | Sets the font color and the ripple color to the provided color value. + + +## `MDCIconButtonToggle` Properties and Methods + +Property | Value Type | Description +--- | --- | --- +`on` | Boolean | Sets the toggle state to the provided `isOn` value. + +### Events + +Event Name | Event Data Structure | Description +--- | --- | --- +`MDCIconButtonToggle` | `{"detail": {"isOn": boolean}}` | Emits when the icon is toggled. + +## Usage within Web Frameworks + +If you are using a JavaScript framework, such as React or Angular, you can create an Icon Button Toggle for your framework. Depending on your needs, you can use the _Simple Approach: Wrapping MDC Web Vanilla Components_, or the _Advanced Approach: Using Foundations and Adapters_. Please follow the instructions [here](../../docs/integrating-into-frameworks.md). + +### `MDCIconButtonToggleAdapter` + +Method Signature | Description +--- | --- +`addClass(className: string) => void` | Adds a class to the root element, or the inner icon element. +`removeClass(className: string) => void` | Removes a class from the root element, or the inner icon element. +`registerInteractionHandler(type: string, handler: EventListener) => void` | Registers an event handler for an interaction event, such as `click` or `keydown`. +`deregisterInteractionHandler(type: string, handler: EventListener) => void` | Removes an event handler for an interaction event, such as `click` or `keydown`. +`setText(text: string) => void` | Sets the text content of the root element, or the inner icon element. +`getTabIndex() => number` | Returns the tab index of the root element. +`setTabIndex(tabIndex: number) => void` | Sets the tab index of the root element. +`getAttr(name: string) => string` | Returns the value of the attribute `name` on the root element. Can also return `null`, similar to `getAttribute()`. +`setAttr(name: string, value: string) => void` | Sets the attribute `name` to `value` on the root element. +`removeAttr(name: string) => void` | Removes the attribute `name` on the root element. +`notifyChange(evtData: {isOn: boolean}) => void` | Broadcasts a change notification, passing along the `evtData` to the environment's event handling system. In our vanilla implementation, Custom Events are used for this. + +### Foundation: `MDCIconButtonToggleFoundation` + +The foundation does not contain any public properties or methods aside from those inherited from MDCFoundation. diff --git a/packages/mdc-icon-button/_mixins.scss b/packages/mdc-icon-button/_mixins.scss new file mode 100644 index 00000000000..f572e470af0 --- /dev/null +++ b/packages/mdc-icon-button/_mixins.scss @@ -0,0 +1,64 @@ +// +// Copyright 2018 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@import "@material/ripple/common"; +@import "@material/ripple/mixins"; +@import "@material/theme/mixins"; +@import "./variables"; + +@mixin mdc-icon-button-size($width, $height: $width, $padding: max($width, $height)/2) { + width: $width + $padding * 2; + height: $height + $padding * 2; + padding: $padding; + font-size: max($width, $height); + + // stylelint-disable-next-line selector-max-type + svg, + img { + width: $width; + height: $height; + } +} + +@mixin mdc-icon-button-ink-color($color) { + @include mdc-theme-prop(color, $color); + @include mdc-states($color); +} + +@mixin mdc-icon-button-base_() { + @include mdc-ripple-surface; + @include mdc-ripple-radius-unbounded; + @include mdc-icon-button-size($mdc-icon-button-size); + + display: inline-block; + position: relative; + box-sizing: border-box; + border: none; + outline: none; + background-color: transparent; + fill: currentColor; + color: inherit; + text-decoration: none; + cursor: pointer; + user-select: none; + + &:disabled { + @include mdc-theme-prop(color, text-disabled-on-light); + + cursor: default; + pointer-events: none; + } +} diff --git a/packages/mdc-icon-button/_variables.scss b/packages/mdc-icon-button/_variables.scss new file mode 100644 index 00000000000..a9c23cc7420 --- /dev/null +++ b/packages/mdc-icon-button/_variables.scss @@ -0,0 +1,17 @@ +// +// Copyright 2018 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +$mdc-icon-button-size: 24px; diff --git a/packages/mdc-icon-button/adapter.js b/packages/mdc-icon-button/adapter.js new file mode 100644 index 00000000000..7b9f0afab69 --- /dev/null +++ b/packages/mdc-icon-button/adapter.js @@ -0,0 +1,93 @@ +/** + * @license + * Copyright 2018 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* eslint no-unused-vars: [2, {"args": "none"}] */ + +/** + * Adapter for MDC Icon Button Toggle. Provides an interface for managing + * - classes + * - dom + * - inner text + * - event handlers + * - event dispatch + * + * Additionally, provides type information for the adapter to the Closure + * compiler. + * + * Implement this adapter for your framework of choice to delegate updates to + * the component in your framework of choice. See architecture documentation + * for more details. + * https://github.com/material-components/material-components-web/blob/master/docs/code/architecture.md + * + * @record + */ + +class MDCIconButtonToggleAdapter { + /** @param {string} className */ + addClass(className) {} + + /** @param {string} className */ + removeClass(className) {} + + /** + * @param {string} type + * @param {!EventListener} handler + */ + registerInteractionHandler(type, handler) {} + + /** + * @param {string} type + * @param {!EventListener} handler + */ + deregisterInteractionHandler(type, handler) {} + + /** @param {string} text */ + setText(text) {} + + /** @return {number} */ + getTabIndex() {} + + /** @param {number} tabIndex */ + setTabIndex(tabIndex) {} + + /** + * @param {string} name + * @return {string} + */ + getAttr(name) {} + + /** + * @param {string} name + * @param {string} value + */ + setAttr(name, value) {} + + /** @param {string} name */ + removeAttr(name) {} + + /** @param {!IconButtonToggleEvent} evtData */ + notifyChange(evtData) {} +} + +/** + * @typedef {{ + * isOn: boolean, + * }} + */ +let IconButtonToggleEvent; + +export {MDCIconButtonToggleAdapter, IconButtonToggleEvent}; diff --git a/packages/mdc-icon-button/constants.js b/packages/mdc-icon-button/constants.js new file mode 100644 index 00000000000..e1557446722 --- /dev/null +++ b/packages/mdc-icon-button/constants.js @@ -0,0 +1,36 @@ +/** + * @license + * Copyright 2018 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** @enum {string} */ +const cssClasses = { + ROOT: 'mdc-icon-button', +}; + +/** @enum {string} */ +const strings = { + DATA_TOGGLE_ON_LABEL: 'data-toggle-on-label', + DATA_TOGGLE_ON_CONTENT: 'data-toggle-on-content', + DATA_TOGGLE_ON_CLASS: 'data-toggle-on-class', + DATA_TOGGLE_OFF_LABEL: 'data-toggle-off-label', + DATA_TOGGLE_OFF_CONTENT: 'data-toggle-off-content', + DATA_TOGGLE_OFF_CLASS: 'data-toggle-off-class', + ARIA_PRESSED: 'aria-pressed', + ARIA_LABEL: 'aria-label', + CHANGE_EVENT: 'MDCIconButtonToggle:change', +}; + +export {cssClasses, strings}; diff --git a/packages/mdc-icon-button/foundation.js b/packages/mdc-icon-button/foundation.js new file mode 100644 index 00000000000..39a801038a3 --- /dev/null +++ b/packages/mdc-icon-button/foundation.js @@ -0,0 +1,158 @@ +/** + * @license + * Copyright 2018 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import MDCFoundation from '@material/base/foundation'; +/* eslint-disable no-unused-vars */ +import {MDCIconButtonToggleAdapter, IconButtonToggleEvent} from './adapter'; +import {cssClasses, strings} from './constants'; + +/** + * @extends {MDCFoundation} + */ +class MDCIconButtonToggleFoundation extends MDCFoundation { + static get cssClasses() { + return cssClasses; + } + + static get strings() { + return strings; + } + + static get defaultAdapter() { + return { + addClass: (/* className: string */) => {}, + removeClass: (/* className: string */) => {}, + registerInteractionHandler: (/* type: string, handler: EventListener */) => {}, + deregisterInteractionHandler: (/* type: string, handler: EventListener */) => {}, + setText: (/* text: string */) => {}, + getTabIndex: () => /* number */ 0, + setTabIndex: (/* tabIndex: number */) => {}, + getAttr: (/* name: string */) => /* string */ '', + setAttr: (/* name: string, value: string */) => {}, + removeAttr: (/* name: string */) => {}, + notifyChange: (/* evtData: IconButtonToggleEvent */) => {}, + }; + } + + constructor(adapter) { + super(Object.assign(MDCIconButtonToggleFoundation.defaultAdapter, adapter)); + + /** @private {boolean} */ + this.on_ = false; + + /** @private {boolean} */ + this.disabled_ = false; + + /** @private {number} */ + this.savedTabIndex_ = -1; + + /** @private {?IconButtonToggleState} */ + this.toggleOnData_ = null; + + /** @private {?IconButtonToggleState} */ + this.toggleOffData_ = null; + + this.clickHandler_ = /** @private {!EventListener} */ ( + () => this.toggleFromEvt_()); + } + + init() { + this.refreshToggleData(); + this.savedTabIndex_ = this.adapter_.getTabIndex(); + this.adapter_.registerInteractionHandler('click', this.clickHandler_); + } + + destroy() { + this.adapter_.deregisterInteractionHandler('click', this.clickHandler_); + } + + refreshToggleData() { + this.toggleOnData_ = { + label: this.adapter_.getAttr(strings.DATA_TOGGLE_ON_LABEL), + content: this.adapter_.getAttr(strings.DATA_TOGGLE_ON_CONTENT), + cssClass: this.adapter_.getAttr(strings.DATA_TOGGLE_ON_CLASS), + }; + this.toggleOffData_ = { + label: this.adapter_.getAttr(strings.DATA_TOGGLE_OFF_LABEL), + content: this.adapter_.getAttr(strings.DATA_TOGGLE_OFF_CONTENT), + cssClass: this.adapter_.getAttr(strings.DATA_TOGGLE_OFF_CLASS), + }; + } + + /** @private */ + toggleFromEvt_() { + this.toggle(); + const {on_: isOn} = this; + this.adapter_.notifyChange(/** @type {!IconButtonToggleEvent} */ ({isOn})); + } + + /** @return {boolean} */ + isOn() { + return this.on_; + } + + /** @param {boolean=} isOn */ + toggle(isOn = !this.on_) { + this.on_ = isOn; + + const {ARIA_LABEL, ARIA_PRESSED} = MDCIconButtonToggleFoundation.strings; + + this.adapter_.setAttr(ARIA_PRESSED, this.on_.toString()); + + const {cssClass: classToRemove} = + this.on_ ? this.toggleOffData_ : this.toggleOnData_; + + if (classToRemove) { + this.adapter_.removeClass(classToRemove); + } + + const {content, label, cssClass} = this.on_ ? this.toggleOnData_ : this.toggleOffData_; + + if (cssClass) { + this.adapter_.addClass(cssClass); + } + if (content) { + this.adapter_.setText(content); + } + if (label) { + this.adapter_.setAttr(ARIA_LABEL, label); + } + } +} + +/** @record */ +class IconButtonToggleState {} + +/** + * The aria-label value of the icon toggle, or undefined if there is no aria-label. + * @export {string|undefined} + */ +IconButtonToggleState.prototype.label; + +/** + * The text for the icon toggle, or undefined if there is no text. + * @export {string|undefined} + */ +IconButtonToggleState.prototype.content; + +/** + * The CSS class to add to the icon toggle, or undefined if there is no CSS class. + * @export {string|undefined} + */ +IconButtonToggleState.prototype.cssClass; + +export default MDCIconButtonToggleFoundation; diff --git a/packages/mdc-icon-button/index.js b/packages/mdc-icon-button/index.js new file mode 100644 index 00000000000..f98616ce8fa --- /dev/null +++ b/packages/mdc-icon-button/index.js @@ -0,0 +1,100 @@ +/** + * @license + * Copyright 2018 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import MDCComponent from '@material/base/component'; +import MDCIconButtonToggleFoundation from './foundation'; +import {MDCRipple} from '@material/ripple/index'; + +/** + * @extends {MDCComponent} + */ +class MDCIconButtonToggle extends MDCComponent { + static attachTo(root) { + return new MDCIconButtonToggle(root); + } + + constructor(...args) { + super(...args); + + /** @private {!MDCRipple} */ + this.ripple_ = this.initRipple_(); + } + + /** @return {!Element} */ + get iconEl_() { + const {'iconInnerSelector': sel} = this.root_.dataset; + return sel ? + /** @type {!Element} */ (this.root_.querySelector(sel)) : this.root_; + } + + /** + * @return {!MDCRipple} + * @private + */ + initRipple_() { + const ripple = new MDCRipple(this.root_); + ripple.unbounded = true; + return ripple; + } + + destroy() { + this.ripple_.destroy(); + super.destroy(); + } + + /** @return {!MDCIconButtonToggleFoundation} */ + getDefaultFoundation() { + return new MDCIconButtonToggleFoundation({ + addClass: (className) => this.iconEl_.classList.add(className), + removeClass: (className) => this.iconEl_.classList.remove(className), + registerInteractionHandler: (type, handler) => this.root_.addEventListener(type, handler), + deregisterInteractionHandler: (type, handler) => this.root_.removeEventListener(type, handler), + setText: (text) => this.iconEl_.textContent = text, + getTabIndex: () => /* number */ this.root_.tabIndex, + setTabIndex: (tabIndex) => this.root_.tabIndex = tabIndex, + getAttr: (name, value) => this.root_.getAttribute(name, value), + setAttr: (name, value) => this.root_.setAttribute(name, value), + removeAttr: (name) => this.root_.removeAttribute(name), + notifyChange: (evtData) => this.emit(MDCIconButtonToggleFoundation.strings.CHANGE_EVENT, evtData), + }); + } + + initialSyncWithDOM() { + this.on = this.root_.getAttribute(MDCIconButtonToggleFoundation.strings.ARIA_PRESSED) === 'true'; + } + + /** @return {!MDCRipple} */ + get ripple() { + return this.ripple_; + } + + /** @return {boolean} */ + get on() { + return this.foundation_.isOn(); + } + + /** @param {boolean} isOn */ + set on(isOn) { + this.foundation_.toggle(isOn); + } + + refreshToggleData() { + this.foundation_.refreshToggleData(); + } +} + +export {MDCIconButtonToggle, MDCIconButtonToggleFoundation}; diff --git a/packages/mdc-icon-button/mdc-icon-button.scss b/packages/mdc-icon-button/mdc-icon-button.scss new file mode 100644 index 00000000000..8fa5874381f --- /dev/null +++ b/packages/mdc-icon-button/mdc-icon-button.scss @@ -0,0 +1,32 @@ +// +// Copyright 2018 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// postcss-bem-linter: define icon-button + +@import "./mixins"; + +.mdc-icon-button { + @include mdc-icon-button-base_; + @include mdc-states; +} + +.mdc-icon-button--disabled { + @include mdc-theme-prop(color, text-disabled-on-light); + + pointer-events: none; +} + +// postcss-bem-linter: end diff --git a/packages/mdc-icon-button/package.json b/packages/mdc-icon-button/package.json new file mode 100644 index 00000000000..dbbcf6be24f --- /dev/null +++ b/packages/mdc-icon-button/package.json @@ -0,0 +1,25 @@ +{ + "name": "@material/icon-button", + "description": "The Material Components for the web icon button component", + "version": "0.0.0", + "license": "Apache 2.0", + "keywords": [ + "material components", + "material design", + "button", + "icon button", + "icon toggle" + ], + "repository": { + "type": "git", + "url": "https://github.com/material-components/material-components-web.git" + }, + "dependencies": { + "@material/base": "^0.35.0", + "@material/ripple": "^0.35.0", + "@material/theme": "^0.35.0" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/scripts/webpack/css-bundle-factory.js b/scripts/webpack/css-bundle-factory.js index 65dcb5bfc63..8283d5c8485 100644 --- a/scripts/webpack/css-bundle-factory.js +++ b/scripts/webpack/css-bundle-factory.js @@ -146,6 +146,7 @@ class CssBundleFactory { 'mdc.floating-label': getAbsolutePath('/packages/mdc-floating-label/mdc-floating-label.scss'), 'mdc.form-field': getAbsolutePath('/packages/mdc-form-field/mdc-form-field.scss'), 'mdc.grid-list': getAbsolutePath('/packages/mdc-grid-list/mdc-grid-list.scss'), + 'mdc.icon-button': getAbsolutePath('/packages/mdc-icon-button/mdc-icon-button.scss'), 'mdc.icon-toggle': getAbsolutePath('/packages/mdc-icon-toggle/mdc-icon-toggle.scss'), 'mdc.image-list': getAbsolutePath('/packages/mdc-image-list/mdc-image-list.scss'), 'mdc.layout-grid': getAbsolutePath('/packages/mdc-layout-grid/mdc-layout-grid.scss'), diff --git a/scripts/webpack/js-bundle-factory.js b/scripts/webpack/js-bundle-factory.js index c7047096a75..eb0a20f3270 100644 --- a/scripts/webpack/js-bundle-factory.js +++ b/scripts/webpack/js-bundle-factory.js @@ -134,6 +134,7 @@ class JsBundleFactory { floatingLabel: getAbsolutePath('/packages/mdc-floating-label/index.js'), formField: getAbsolutePath('/packages/mdc-form-field/index.js'), gridList: getAbsolutePath('/packages/mdc-grid-list/index.js'), + iconButton: getAbsolutePath('/packages/mdc-icon-button/index.js'), iconToggle: getAbsolutePath('/packages/mdc-icon-toggle/index.js'), lineRipple: getAbsolutePath('/packages/mdc-line-ripple/index.js'), linearProgress: getAbsolutePath('/packages/mdc-linear-progress/index.js'), diff --git a/test/unit/mdc-icon-button/foundation.test.js b/test/unit/mdc-icon-button/foundation.test.js new file mode 100644 index 00000000000..a1a863f4285 --- /dev/null +++ b/test/unit/mdc-icon-button/foundation.test.js @@ -0,0 +1,217 @@ +/** + * Copyright 2018 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {assert} from 'chai'; +import td from 'testdouble'; + +import {setupFoundationTest} from '../helpers/setup'; +import {verifyDefaultAdapter, captureHandlers as baseCaptureHandlers} from '../helpers/foundation'; +import MDCIconButtonToggleFoundation from '../../../packages/mdc-icon-button/foundation'; + +const {strings} = MDCIconButtonToggleFoundation; + +suite('MDCIconButtonToggleFoundation'); + +test('exports strings', () => { + assert.isOk('strings' in MDCIconButtonToggleFoundation); +}); + +test('exports cssClasses', () => { + assert.isOk('cssClasses' in MDCIconButtonToggleFoundation); +}); + +test('defaultAdapter returns a complete adapter implementation', () => { + verifyDefaultAdapter(MDCIconButtonToggleFoundation, [ + 'addClass', 'removeClass', 'registerInteractionHandler', 'deregisterInteractionHandler', + 'setText', 'getTabIndex', 'setTabIndex', 'getAttr', 'setAttr', 'removeAttr', 'notifyChange', + ]); +}); + +const setupTest = () => setupFoundationTest(MDCIconButtonToggleFoundation); + +test('#constructor sets on to false', () => { + const {foundation} = setupTest(); + assert.isNotOk(foundation.isOn()); +}); + +test('#toggle flips on', () => { + const {foundation} = setupTest(); + foundation.init(); + + foundation.toggle(); + assert.isOk(foundation.isOn()); + foundation.toggle(); + assert.isNotOk(foundation.isOn()); +}); + +test('#toggle accepts boolean argument denoting toggle state', () => { + const {foundation} = setupTest(); + foundation.init(); + + foundation.toggle(false); + assert.isNotOk(foundation.isOn()); + foundation.toggle(true); + assert.isOk(foundation.isOn()); +}); + +test('#toggle sets "aria-pressed" to true when toggled on', () => { + const {foundation, mockAdapter} = setupTest(); + foundation.init(); + + foundation.toggle(true); + td.verify(mockAdapter.setAttr(strings.ARIA_PRESSED, 'true')); +}); + +test('#toggle removes cssClass in "data-toggle-off-class" if specified when toggled on', () => { + const {foundation, mockAdapter} = setupTest(); + const cssClass = 'toggle-off-css-class'; + td.when(mockAdapter.getAttr(strings.DATA_TOGGLE_OFF_CLASS)).thenReturn(cssClass); + foundation.init(); + + foundation.toggle(true); + td.verify(mockAdapter.removeClass(cssClass)); +}); + +test('#toggle adds cssClass in "data-toggle-on-class" if specified when toggled on', () => { + const {foundation, mockAdapter} = setupTest(); + const cssClass = 'toggle-on-css-class'; + td.when(mockAdapter.getAttr(strings.DATA_TOGGLE_ON_CLASS)).thenReturn(cssClass); + foundation.init(); + + foundation.toggle(true); + td.verify(mockAdapter.addClass(cssClass)); +}); + +test('#toggle sets text to content in "data-toggle-on-content" if specified when toggled on', () => { + const {foundation, mockAdapter} = setupTest(); + const content = 'toggle on content'; + td.when(mockAdapter.getAttr(strings.DATA_TOGGLE_ON_CONTENT)).thenReturn(content); + foundation.init(); + + foundation.toggle(true); + td.verify(mockAdapter.setText(content)); +}); + +test('#toggle sets aria-label to label in "data-toggle-on" if specified when toggled on', () => { + const {foundation, mockAdapter} = setupTest(); + const label = 'toggle on label'; + td.when(mockAdapter.getAttr(strings.DATA_TOGGLE_ON_LABEL)).thenReturn(label); + foundation.init(); + + foundation.toggle(true); + td.verify(mockAdapter.setAttr(strings.ARIA_LABEL, label)); +}); + +test('#toggle sets "aria-pressed" to false when toggled off', () => { + const {foundation, mockAdapter} = setupTest(); + foundation.init(); + + foundation.toggle(false); + td.verify(mockAdapter.setAttr(strings.ARIA_PRESSED, 'false')); +}); + +test('#toggle removes cssClass in "data-toggle-on-class" if specified when toggled off', () => { + const {foundation, mockAdapter} = setupTest(); + const cssClass = 'toggle-on-css-class'; + td.when(mockAdapter.getAttr(strings.DATA_TOGGLE_ON_CLASS)).thenReturn(cssClass); + foundation.init(); + + foundation.toggle(false); + td.verify(mockAdapter.removeClass(cssClass)); +}); + +test('#toggle adds cssClass in "data-toggle-off-class" if specified when toggled off', () => { + const {foundation, mockAdapter} = setupTest(); + const cssClass = 'toggle-off-css-class'; + td.when(mockAdapter.getAttr(strings.DATA_TOGGLE_OFF_CLASS)).thenReturn(cssClass); + foundation.init(); + + foundation.toggle(false); + td.verify(mockAdapter.addClass(cssClass)); +}); + +test('#toggle sets text to content in "data-toggle-off-content" if specified when toggled off', () => { + const {foundation, mockAdapter} = setupTest(); + const content = 'toggle off content'; + td.when(mockAdapter.getAttr(strings.DATA_TOGGLE_OFF_CONTENT)).thenReturn(content); + foundation.init(); + + foundation.toggle(false); + td.verify(mockAdapter.setText(content)); +}); + +test('#toggle sets aria-label to label in "data-toggle-off-label" if specified when toggled off', () => { + const {foundation, mockAdapter} = setupTest(); + const label = 'toggle off label'; + td.when(mockAdapter.getAttr(strings.DATA_TOGGLE_OFF_LABEL)).thenReturn(label); + foundation.init(); + + foundation.toggle(false); + td.verify(mockAdapter.setAttr(strings.ARIA_LABEL, label)); +}); + +test('#refreshToggleData syncs the foundation state with data-toggle-on, data-toggle-off', () => { + const {foundation, mockAdapter} = setupTest(); + td.when(mockAdapter.getAttr(strings.DATA_TOGGLE_ON_CLASS)).thenReturn('first-class-on'); + td.when(mockAdapter.getAttr(strings.DATA_TOGGLE_OFF_CLASS)).thenReturn('first-class-off'); + foundation.init(); + + foundation.toggle(true); + td.verify(mockAdapter.addClass('first-class-on')); + td.verify(mockAdapter.removeClass('first-class-off')); + + td.when(mockAdapter.getAttr(strings.DATA_TOGGLE_ON_CLASS)).thenReturn('second-class-on'); + td.when(mockAdapter.getAttr(strings.DATA_TOGGLE_OFF_CLASS)).thenReturn('second-class-off'); + foundation.refreshToggleData(); + + foundation.toggle(true); + td.verify(mockAdapter.addClass('second-class-on')); + td.verify(mockAdapter.removeClass('second-class-off')); +}); + +test('#destroy deregisters all interaction handlers', () => { + const {foundation, mockAdapter} = setupTest(); + const {isA} = td.matchers; + foundation.destroy(); + td.verify(mockAdapter.deregisterInteractionHandler('click', isA(Function))); +}); + +const captureHandlers = (adapter) => baseCaptureHandlers(adapter, 'registerInteractionHandler'); + +test('updates toggle state on click', () => { + const {foundation, mockAdapter} = setupTest(); + const handlers = captureHandlers(mockAdapter); + foundation.init(); + + handlers.click(); + assert.isOk(foundation.isOn()); + td.verify(mockAdapter.setAttr(strings.ARIA_PRESSED, 'true')); + + handlers.click(); + assert.isNotOk(foundation.isOn()); + td.verify(mockAdapter.setAttr(strings.ARIA_PRESSED, 'false')); +}); + +test('broadcasts change notification on click', () => { + const {foundation, mockAdapter} = setupTest(); + const handlers = captureHandlers(mockAdapter); + foundation.init(); + + handlers.click(); + td.verify(mockAdapter.notifyChange({isOn: true})); + handlers.click(); + td.verify(mockAdapter.notifyChange({isOn: false})); +}); diff --git a/test/unit/mdc-icon-toggle/mdc-icon-toggle.test.js b/test/unit/mdc-icon-button/mdc-icon-button-toggle.test.js similarity index 71% rename from test/unit/mdc-icon-toggle/mdc-icon-toggle.test.js rename to test/unit/mdc-icon-button/mdc-icon-button-toggle.test.js index 688138ca6ad..07926e664ef 100644 --- a/test/unit/mdc-icon-toggle/mdc-icon-toggle.test.js +++ b/test/unit/mdc-icon-button/mdc-icon-button-toggle.test.js @@ -1,5 +1,5 @@ /** - * Copyright 2016 Google Inc. All Rights Reserved. + * Copyright 2018 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,12 +21,12 @@ import {assert} from 'chai'; import {supportsCssVariables} from '../../../packages/mdc-ripple/util'; import {createMockRaf} from '../helpers/raf'; -import {MDCIconToggle, MDCIconToggleFoundation} from '../../../packages/mdc-icon-toggle'; +import {MDCIconButtonToggle, MDCIconButtonToggleFoundation} from '../../../packages/mdc-icon-button'; import {MDCRipple} from '../../../packages/mdc-ripple'; import {cssClasses} from '../../../packages/mdc-ripple/constants'; function setupTest({tabIndex = undefined, useInnerIconElement = false} = {}) { - const root = document.createElement(useInnerIconElement ? 'span' : 'i'); + const root = document.createElement('button'); if (useInnerIconElement) { const icon = document.createElement('i'); icon.id = 'icon'; @@ -36,14 +36,14 @@ function setupTest({tabIndex = undefined, useInnerIconElement = false} = {}) { if (tabIndex !== undefined) { root.tabIndex = tabIndex; } - const component = new MDCIconToggle(root); + const component = new MDCIconButtonToggle(root); return {root, component}; } -suite('MDCIconToggle'); +suite('MDCIconButtonToggle'); -test('attachTo initializes and returns a MDCIconToggle instance', () => { - assert.isOk(MDCIconToggle.attachTo(document.createElement('i')) instanceof MDCIconToggle); +test('attachTo initializes and returns a MDCIconButtonToggle instance', () => { + assert.isOk(MDCIconButtonToggle.attachTo(document.createElement('i')) instanceof MDCIconButtonToggle); }); if (supportsCssVariables(window)) { @@ -77,63 +77,22 @@ test('set/get on', () => { assert.equal(root.getAttribute('aria-pressed'), 'false'); }); -test('set/get disabled to true', () => { - const {root, component} = setupTest({tabIndex: 0}); - - component.disabled = true; - assert.isOk(component.disabled); - assert.equal(root.getAttribute('aria-disabled'), 'true'); - assert.isOk(root.classList.contains(MDCIconToggleFoundation.cssClasses.DISABLED)); - assert.equal(root.tabIndex, -1); -}); - -test('set/get disabled to false', () => { - const {root, component} = setupTest({tabIndex: 0}); - - component.disabled = false; - assert.isNotOk(component.disabled); - assert.isNotOk(root.hasAttribute('aria-disabled')); - assert.isNotOk(root.classList.contains(MDCIconToggleFoundation.cssClasses.DISABLED)); - assert.equal(root.tabIndex, 0, 'element\'s tabIndex should be the same value it already had'); -}); - -test('set/get disabled to true, then false', () => { - const {root, component} = setupTest({tabIndex: 0}); - - component.disabled = true; - assert.isOk(component.disabled); - assert.equal(root.getAttribute('aria-disabled'), 'true'); - assert.isOk(root.classList.contains(MDCIconToggleFoundation.cssClasses.DISABLED)); - assert.equal(root.tabIndex, -1); - - component.disabled = false; - assert.isNotOk(component.disabled); - assert.isNotOk(root.hasAttribute('aria-disabled')); - assert.isNotOk(root.classList.contains(MDCIconToggleFoundation.cssClasses.DISABLED)); - assert.equal(root.tabIndex, 0, 'element\'s tabIndex should be the same value it originally had'); -}); test('#refreshToggleData proxies to foundation.refreshToggleData()', () => { - const MockIconToggleFoundation = td.constructor(MDCIconToggleFoundation); + const MockIconToggleFoundation = td.constructor(MDCIconButtonToggleFoundation); const root = document.createElement('i'); const foundation = new MockIconToggleFoundation(); - const component = new MDCIconToggle(root, foundation); + const component = new MDCIconButtonToggle(root, foundation); component.refreshToggleData(); td.verify(foundation.refreshToggleData()); }); test('intially set to on if root has aria-pressed=true', () => { - const root = bel``; - const component = new MDCIconToggle(root); + const root = bel``; + const component = new MDCIconButtonToggle(root); assert.isOk(component.on); }); -test('intially set to disabled if root has aria-disabled=true', () => { - const root = bel``; - const component = new MDCIconToggle(root); - assert.isOk(component.disabled); -}); - test('get ripple returns a MDCRipple instance', () => { const {component} = setupTest(); assert.isOk(component.ripple instanceof MDCRipple); @@ -222,17 +181,17 @@ test('#adapter.setAttr sets an attribute on the root element', () => { assert.equal(root.getAttribute('aria-label'), 'hello'); }); -test('#adapter.rmAttr removes an attribute from the root element', () => { +test('#adapter.removeAttr removes an attribute from the root element', () => { const {root, component} = setupTest(); root.setAttribute('aria-label', 'hello'); - component.getDefaultFoundation().adapter_.rmAttr('aria-label'); + component.getDefaultFoundation().adapter_.removeAttr('aria-label'); assert.isNotOk(root.hasAttribute('aria-label')); }); -test(`#adapter.notifyChange broadcasts a ${MDCIconToggleFoundation.strings.CHANGE_EVENT} custom event`, () => { +test(`#adapter.notifyChange broadcasts a ${MDCIconButtonToggleFoundation.strings.CHANGE_EVENT} custom event`, () => { const {root, component} = setupTest(); const handler = td.func('custom event handler'); - root.addEventListener(MDCIconToggleFoundation.strings.CHANGE_EVENT, handler); + root.addEventListener(MDCIconButtonToggleFoundation.strings.CHANGE_EVENT, handler); component.getDefaultFoundation().adapter_.notifyChange({}); td.verify(handler(td.matchers.anything())); }); diff --git a/test/unit/mdc-icon-toggle/foundation.test.js b/test/unit/mdc-icon-toggle/foundation.test.js deleted file mode 100644 index f363bc153cc..00000000000 --- a/test/unit/mdc-icon-toggle/foundation.test.js +++ /dev/null @@ -1,363 +0,0 @@ -/** - * Copyright 2016 Google Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import {assert} from 'chai'; -import td from 'testdouble'; - -import {setupFoundationTest} from '../helpers/setup'; -import {verifyDefaultAdapter, captureHandlers as baseCaptureHandlers} from '../helpers/foundation'; -import MDCIconToggleFoundation from '../../../packages/mdc-icon-toggle/foundation'; - -const {strings, cssClasses} = MDCIconToggleFoundation; - -suite('MDCIconToggleFoundation'); - -test('exports strings', () => { - assert.isOk('strings' in MDCIconToggleFoundation); -}); - -test('exports cssClasses', () => { - assert.isOk('cssClasses' in MDCIconToggleFoundation); -}); - -test('defaultAdapter returns a complete adapter implementation', () => { - verifyDefaultAdapter(MDCIconToggleFoundation, [ - 'addClass', 'removeClass', 'registerInteractionHandler', 'deregisterInteractionHandler', - 'setText', 'getTabIndex', 'setTabIndex', 'getAttr', 'setAttr', 'rmAttr', 'notifyChange', - ]); -}); - -const setupTest = () => setupFoundationTest(MDCIconToggleFoundation); - -test('#constructor sets on to false', () => { - const {foundation} = setupTest(); - assert.isNotOk(foundation.isOn()); -}); - -test('#toggle flips on', () => { - const {foundation} = setupTest(); - foundation.init(); - - foundation.toggle(); - assert.isOk(foundation.isOn()); - foundation.toggle(); - assert.isNotOk(foundation.isOn()); -}); - -test('#toggle accepts boolean argument denoting toggle state', () => { - const {foundation} = setupTest(); - foundation.init(); - - foundation.toggle(false); - assert.isNotOk(foundation.isOn()); - foundation.toggle(true); - assert.isOk(foundation.isOn()); -}); - -test('#toggle sets "aria-pressed" to true when toggled on', () => { - const {foundation, mockAdapter} = setupTest(); - foundation.init(); - - foundation.toggle(true); - td.verify(mockAdapter.setAttr(strings.ARIA_PRESSED, 'true')); -}); - -test('#toggle removes cssClass in "data-toggle-off" if specified when toggled on', () => { - const {foundation, mockAdapter} = setupTest(); - const cssClass = 'toggle-off-css-class'; - td.when(mockAdapter.getAttr(strings.DATA_TOGGLE_OFF)).thenReturn(JSON.stringify({cssClass})); - foundation.init(); - - foundation.toggle(true); - td.verify(mockAdapter.removeClass(cssClass)); -}); - -test('#toggle adds cssClass in "data-toggle-on" if specified when toggled on', () => { - const {foundation, mockAdapter} = setupTest(); - const cssClass = 'toggle-on-css-class'; - td.when(mockAdapter.getAttr(strings.DATA_TOGGLE_ON)).thenReturn(JSON.stringify({cssClass})); - foundation.init(); - - foundation.toggle(true); - td.verify(mockAdapter.addClass(cssClass)); -}); - -test('#toggle sets text to content in "data-toggle-on" if specified when toggled on', () => { - const {foundation, mockAdapter} = setupTest(); - const content = 'toggle on content'; - td.when(mockAdapter.getAttr(strings.DATA_TOGGLE_ON)).thenReturn(JSON.stringify({content})); - foundation.init(); - - foundation.toggle(true); - td.verify(mockAdapter.setText(content)); -}); - -test('#toggle sets aria-label to label in "data-toggle-on" if specified when toggled on', () => { - const {foundation, mockAdapter} = setupTest(); - const label = 'toggle on label'; - td.when(mockAdapter.getAttr(strings.DATA_TOGGLE_ON)).thenReturn(JSON.stringify({label})); - foundation.init(); - - foundation.toggle(true); - td.verify(mockAdapter.setAttr(strings.ARIA_LABEL, label)); -}); - -test('#toggle sets "aria-pressed" to false when toggled off', () => { - const {foundation, mockAdapter} = setupTest(); - foundation.init(); - - foundation.toggle(false); - td.verify(mockAdapter.setAttr(strings.ARIA_PRESSED, 'false')); -}); - -test('#toggle removes cssClass in "data-toggle-on" if specified when toggled off', () => { - const {foundation, mockAdapter} = setupTest(); - const cssClass = 'toggle-on-css-class'; - td.when(mockAdapter.getAttr(strings.DATA_TOGGLE_ON)).thenReturn(JSON.stringify({cssClass})); - foundation.init(); - - foundation.toggle(false); - td.verify(mockAdapter.removeClass(cssClass)); -}); - -test('#toggle adds cssClass in "data-toggle-off" if specified when toggled off', () => { - const {foundation, mockAdapter} = setupTest(); - const cssClass = 'toggle-off-css-class'; - td.when(mockAdapter.getAttr(strings.DATA_TOGGLE_OFF)).thenReturn(JSON.stringify({cssClass})); - foundation.init(); - - foundation.toggle(false); - td.verify(mockAdapter.addClass(cssClass)); -}); - -test('#toggle sets text to content in "data-toggle-off" if specified when toggled off', () => { - const {foundation, mockAdapter} = setupTest(); - const content = 'toggle off content'; - td.when(mockAdapter.getAttr(strings.DATA_TOGGLE_OFF)).thenReturn(JSON.stringify({content})); - foundation.init(); - - foundation.toggle(false); - td.verify(mockAdapter.setText(content)); -}); - -test('#toggle sets aria-label to label in "data-toggle-off" if specified when toggled off', () => { - const {foundation, mockAdapter} = setupTest(); - const label = 'toggle off label'; - td.when(mockAdapter.getAttr(strings.DATA_TOGGLE_OFF)).thenReturn(JSON.stringify({label})); - foundation.init(); - - foundation.toggle(false); - td.verify(mockAdapter.setAttr(strings.ARIA_LABEL, label)); -}); - -test('#setDisabled updates the disabled state', () => { - const {foundation} = setupTest(); - foundation.setDisabled(true); - assert.isOk(foundation.isDisabled()); - foundation.setDisabled(false); - assert.isNotOk(foundation.isDisabled()); -}); - -test('#setDisabled sets the tabindex to -1 when disabled', () => { - const {foundation, mockAdapter} = setupTest(); - foundation.setDisabled(true); - td.verify(mockAdapter.setTabIndex(-1)); -}); - -test('#setDisabled sets "aria-disabled" to true when disabled', () => { - const {foundation, mockAdapter} = setupTest(); - foundation.setDisabled(true); - td.verify(mockAdapter.setAttr(strings.ARIA_DISABLED, 'true')); -}); - -test('#setDisabled adds "mdc-icon-toggle--disabled" class when disabled', () => { - const {foundation, mockAdapter} = setupTest(); - foundation.setDisabled(true); - td.verify(mockAdapter.addClass(cssClasses.DISABLED)); -}); - -test('#setDisabled restores the previously set tab index when enabled', () => { - const {foundation, mockAdapter} = setupTest(); - const tabIndex = 5; - td.when(mockAdapter.getTabIndex()).thenReturn(tabIndex); - foundation.setDisabled(true); - - foundation.setDisabled(false); - td.verify(mockAdapter.setTabIndex(tabIndex)); -}); - -test('#setDisabled removes "aria-disabled" when enabled', () => { - const {foundation, mockAdapter} = setupTest(); - foundation.setDisabled(false); - td.verify(mockAdapter.rmAttr(strings.ARIA_DISABLED)); -}); - -test('#setDisabled removes "mdc-icon-toggle--disabled" class when enabled', () => { - const {foundation, mockAdapter} = setupTest(); - foundation.setDisabled(false); - td.verify(mockAdapter.removeClass(cssClasses.DISABLED)); -}); - -test('#refreshToggleData syncs the foundation state with data-toggle-on, data-toggle-off', () => { - const {foundation, mockAdapter} = setupTest(); - td.when(mockAdapter.getAttr(strings.DATA_TOGGLE_ON)).thenReturn(JSON.stringify({ - cssClass: 'first-class-on', - })); - td.when(mockAdapter.getAttr(strings.DATA_TOGGLE_OFF)).thenReturn(JSON.stringify({ - cssClass: 'first-class-off', - })); - foundation.init(); - - foundation.toggle(true); - td.verify(mockAdapter.addClass('first-class-on')); - td.verify(mockAdapter.removeClass('first-class-off')); - - td.when(mockAdapter.getAttr(strings.DATA_TOGGLE_ON)).thenReturn(JSON.stringify({ - cssClass: 'second-class-on', - })); - td.when(mockAdapter.getAttr(strings.DATA_TOGGLE_OFF)).thenReturn(JSON.stringify({ - cssClass: 'second-class-off', - })); - foundation.refreshToggleData(); - - foundation.toggle(true); - td.verify(mockAdapter.addClass('second-class-on')); - td.verify(mockAdapter.removeClass('second-class-off')); -}); - -test('#destroy deregisters all interaction handlers', () => { - const {foundation, mockAdapter} = setupTest(); - const {isA} = td.matchers; - foundation.destroy(); - td.verify(mockAdapter.deregisterInteractionHandler('click', isA(Function))); - td.verify(mockAdapter.deregisterInteractionHandler('keydown', isA(Function))); - td.verify(mockAdapter.deregisterInteractionHandler('keyup', isA(Function))); -}); - -const captureHandlers = (adapter) => baseCaptureHandlers(adapter, 'registerInteractionHandler'); - -test('updates toggle state on click', () => { - const {foundation, mockAdapter} = setupTest(); - const handlers = captureHandlers(mockAdapter); - foundation.init(); - - handlers.click(); - assert.isOk(foundation.isOn()); - td.verify(mockAdapter.setAttr(strings.ARIA_PRESSED, 'true')); - - handlers.click(); - assert.isNotOk(foundation.isOn()); - td.verify(mockAdapter.setAttr(strings.ARIA_PRESSED, 'false')); -}); - -test('broadcasts change notification on click', () => { - const {foundation, mockAdapter} = setupTest(); - const handlers = captureHandlers(mockAdapter); - foundation.init(); - - handlers.click(); - td.verify(mockAdapter.notifyChange({isOn: true})); - handlers.click(); - td.verify(mockAdapter.notifyChange({isOn: false})); -}); - -test('prevents default action on spacebar keydown', () => { - const {foundation, mockAdapter} = setupTest(); - const handlers = captureHandlers(mockAdapter); - const evt = {preventDefault: td.func('evt.preventDefault'), key: 'Space'}; - foundation.init(); - - handlers.keydown(evt); - td.verify(evt.preventDefault()); -}); - -test('prevents default action on spacebar keydown using keyCode', () => { - const {foundation, mockAdapter} = setupTest(); - const handlers = captureHandlers(mockAdapter); - const evt = {preventDefault: td.func('evt.preventDefault'), keyCode: 32}; - foundation.init(); - - handlers.keydown(evt); - td.verify(evt.preventDefault()); -}); - -test('flips isKeyboardActivated() to true on spacebar keydown', () => { - const {foundation, mockAdapter} = setupTest(); - const handlers = captureHandlers(mockAdapter); - const evt = {preventDefault: td.func('evt.preventDefault'), key: 'Space'}; - foundation.init(); - - handlers.keydown(evt); - assert.isOk(foundation.isKeyboardActivated()); -}); - -test('flips isKeyboardActivated() to true on spacebar keydown using keyCode', () => { - const {foundation, mockAdapter} = setupTest(); - const handlers = captureHandlers(mockAdapter); - const evt = {preventDefault: td.func('evt.preventDefault'), keyCode: 32}; - foundation.init(); - - handlers.keydown(evt); - assert.isOk(foundation.isKeyboardActivated()); -}); - -test('triggers toggle on spacebar keyup', () => { - const {foundation, mockAdapter} = setupTest(); - const handlers = captureHandlers(mockAdapter); - foundation.init(); - - handlers.keyup({key: 'Space'}); - assert.isOk(foundation.isOn()); - td.verify(mockAdapter.setAttr(strings.ARIA_PRESSED, 'true')); - td.verify(mockAdapter.notifyChange({isOn: true})); -}); - -test('triggers toggle on spacebar keyup using keyCode', () => { - const {foundation, mockAdapter} = setupTest(); - const handlers = captureHandlers(mockAdapter); - foundation.init(); - - handlers.keyup({keyCode: 32}); - assert.isOk(foundation.isOn()); - td.verify(mockAdapter.setAttr(strings.ARIA_PRESSED, 'true')); - td.verify(mockAdapter.notifyChange({isOn: true})); -}); - -test('flips isKeyboardActivated() back to false on spacebar keydown', () => { - const {foundation, mockAdapter} = setupTest(); - const handlers = captureHandlers(mockAdapter); - const evt = {preventDefault: td.func('evt.preventDefault'), key: 'Space'}; - foundation.init(); - - handlers.keydown(evt); - assert.isOk(foundation.isKeyboardActivated(), 'isKeyboardActivated sanity check'); - - handlers.keyup(evt); - assert.isNotOk(foundation.isKeyboardActivated()); -}); - -test('flips isKeyboardActivated() back to false on spacebar keydown using keyCode', () => { - const {foundation, mockAdapter} = setupTest(); - const handlers = captureHandlers(mockAdapter); - const evt = {preventDefault: td.func('evt.preventDefault'), keyCode: 32}; - foundation.init(); - - handlers.keydown(evt); - assert.isOk(foundation.isKeyboardActivated(), 'isKeyboardActivated sanity check'); - - handlers.keyup(evt); - assert.isNotOk(foundation.isKeyboardActivated()); -}); From 119645e2c39d32fc7816505c2cebd57cd1ba845e Mon Sep 17 00:00:00 2001 From: Will Ernest Date: Fri, 25 May 2018 10:53:08 -0700 Subject: [PATCH 005/175] docs(icon-toggle): Add deprecation notice to README (#2766) BREAKING CHANGE: The icon-toggle package has been deprecated. The functionality was moved to the icon-button package. Please refer to the icon-button readme for changes and how to update. --- packages/mdc-icon-toggle/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/mdc-icon-toggle/README.md b/packages/mdc-icon-toggle/README.md index 8ed0303609f..8395ed483ae 100644 --- a/packages/mdc-icon-toggle/README.md +++ b/packages/mdc-icon-toggle/README.md @@ -6,6 +6,13 @@ iconId: button path: /catalog/buttons/icon-toggle-buttons/ --> +## Important - Deprecation Notice + +The existing `MDCIconToggle` component and styles will be removed in a future release. Some of its functionality +will be available in the [MDC Icon Button](../mdc-icon-button) package instead. Bugs and feature requests +will no longer be accepted for the `mdc-icon-toggle` package. It is recommended that you migrate to the +`mdc-icon-button` package to continue to receive new features and updates. + # Icon Toggle Buttons +## Important - Default Style Deprecation Notice + +The existing default text field style will be changed in an upcoming release. The Material spec indicates that +the default style will be the filled variant (currently referred to as the box variant). This will become the +default style. Continuing to add the `mdc-text-field--box` class to the text field will +result in no change. + # Text Field +## Important - Default Style Deprecation Notice + +The existing default select style will be changed in an upcoming release. The Material spec indicates that +the default style will be the filled variant (currently referred to as the box variant). This will become the +default style. Continuing to add the `mdc-select--box` class to the select will result in no change. + # Select Menus + + + + Baseline Icon Button - MDC Web Screenshot Test + + + + + + + +
+
+
+ +
+
+
+ +
+
+ +
+ +
+ +
+
+ +
+
+ +
+
+
+ + diff --git a/test/screenshot/mdc-icon-button/custom.scss b/test/screenshot/mdc-icon-button/custom.scss new file mode 100644 index 00000000000..0d20454c37d --- /dev/null +++ b/test/screenshot/mdc-icon-button/custom.scss @@ -0,0 +1,29 @@ +// +// Copyright 2018 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +@import "../../../packages/mdc-icon-button/mixins"; +@import "../../../packages/mdc-theme/color-palette"; + +$custom-icon-button-icon-ink-color: $material-color-red-500; +$custom-icon-button-size: 36px; + +.custom-icon-button--ink-color { + @include mdc-icon-button-ink-color($custom-icon-button-icon-ink-color); +} + +.custom-icon-button--icon-size { + @include mdc-icon-button-size($custom-icon-button-size); +} diff --git a/test/screenshot/mdc-icon-button/fixture.scss b/test/screenshot/mdc-icon-button/fixture.scss new file mode 100644 index 00000000000..21093e1bac3 --- /dev/null +++ b/test/screenshot/mdc-icon-button/fixture.scss @@ -0,0 +1,24 @@ +// +// Copyright 2018 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +.test-main--icon-button { + width: 348px; // fits 4 columns of icon buttons within a Galaxy S7 viewport +} + +.test-cell--icon-button { + width: 91px; + height: 91px; +} diff --git a/test/screenshot/mdc-icon-button/mixins/icon-size.html b/test/screenshot/mdc-icon-button/mixins/icon-size.html new file mode 100644 index 00000000000..6a755077086 --- /dev/null +++ b/test/screenshot/mdc-icon-button/mixins/icon-size.html @@ -0,0 +1,77 @@ + + + + + + icon-size Icon Button - MDC Web Screenshot Test + + + + + + + + +
+
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+
+ +
+
+
+ + diff --git a/test/screenshot/mdc-icon-button/mixins/ink-color.html b/test/screenshot/mdc-icon-button/mixins/ink-color.html new file mode 100644 index 00000000000..018e448a22b --- /dev/null +++ b/test/screenshot/mdc-icon-button/mixins/ink-color.html @@ -0,0 +1,77 @@ + + + + + + ink-color Icon Button - MDC Web Screenshot Test + + + + + + + + +
+
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+
+ +
+
+
+ + From 7d406fa06a91ef9d357247ed54483dfd3215f530 Mon Sep 17 00:00:00 2001 From: Esteban Gonzalez Date: Wed, 30 May 2018 16:26:50 -0700 Subject: [PATCH 026/175] fix(chips): Fix choice-chips leading icon being hidden (#2796) Add a boolean to not remove the leading icon when selected chip does not contain a checkmark. Change the color of the leading icon when selected. Change the tests to ensure it is checking the right chips. Add test for selected chip with leading icon and no checkmark, to not remove the leading icon. Fixes #2728 --- packages/mdc-chips/_mixins.scss | 1 + packages/mdc-chips/chip/mdc-chip.scss | 52 ++++++++++--------- .../mdc-chips/mdc-chip.foundation.test.js | 9 ++-- 3 files changed, 33 insertions(+), 29 deletions(-) diff --git a/packages/mdc-chips/_mixins.scss b/packages/mdc-chips/_mixins.scss index b6fcbfddfc8..69257ecf641 100644 --- a/packages/mdc-chips/_mixins.scss +++ b/packages/mdc-chips/_mixins.scss @@ -60,6 +60,7 @@ &.mdc-chip--selected { @include mdc-theme-prop(color, $color); + @include mdc-chip-leading-icon-color($color); &:hover { @include mdc-theme-prop(color, $color); diff --git a/packages/mdc-chips/chip/mdc-chip.scss b/packages/mdc-chips/chip/mdc-chip.scss index 0979ae68ebc..afee7a2dd3a 100644 --- a/packages/mdc-chips/chip/mdc-chip.scss +++ b/packages/mdc-chips/chip/mdc-chip.scss @@ -115,41 +115,43 @@ // Add leading checkmark to filter chips with a leading icon -.mdc-chip__icon--leading { - transition: opacity $mdc-chip-opacity-animation-duration linear; - transition-delay: $mdc-chip-leading-icon-delay; - opacity: 1; - - + .mdc-chip__checkmark { +.mdc-chip-set--filter { + .mdc-chip__icon--leading { transition: opacity $mdc-chip-opacity-animation-duration linear; + transition-delay: $mdc-chip-leading-icon-delay; + opacity: 1; - // Delay the checkmark transition. - transition-delay: $mdc-chip-checkmark-with-leading-icon-delay; - opacity: 0; + + .mdc-chip__checkmark { + transition: opacity $mdc-chip-opacity-animation-duration linear; + + // Delay the checkmark transition. + transition-delay: $mdc-chip-checkmark-with-leading-icon-delay; + opacity: 0; - .mdc-chip__checkmark-svg { - transition: width 0ms; + .mdc-chip__checkmark-svg { + transition: width 0ms; + } } } -} -.mdc-chip--selected .mdc-chip__icon--leading { - opacity: 0; + .mdc-chip--selected .mdc-chip__icon--leading { + opacity: 0; - + .mdc-chip__checkmark { - // This ensures that the checkmark has zero width while the leading icon is still animating. - width: 0; - opacity: 1; + + .mdc-chip__checkmark { + // This ensures that the checkmark has zero width while the leading icon is still animating. + width: 0; + opacity: 1; + } } -} -.mdc-chip__icon--leading-hidden.mdc-chip__icon--leading { - width: 0; + .mdc-chip__icon--leading-hidden.mdc-chip__icon--leading { + width: 0; - // This ensures that the leading icon doesn't fade in while the checkmark is fading out. - opacity: 0; + // This ensures that the leading icon doesn't fade in while the checkmark is fading out. + opacity: 0; - + .mdc-chip__checkmark { - width: $mdc-chip-leading-icon-size; + + .mdc-chip__checkmark { + width: $mdc-chip-leading-icon-size; + } } } diff --git a/test/unit/mdc-chips/mdc-chip.foundation.test.js b/test/unit/mdc-chips/mdc-chip.foundation.test.js index 7f4640270ce..3c6feaddef5 100644 --- a/test/unit/mdc-chips/mdc-chip.foundation.test.js +++ b/test/unit/mdc-chips/mdc-chip.foundation.test.js @@ -36,10 +36,11 @@ test('exports cssClasses', () => { test('defaultAdapter returns a complete adapter implementation', () => { verifyDefaultAdapter(MDCChipFoundation, [ - 'addClass', 'removeClass', 'hasClass', 'addClassToLeadingIcon', 'removeClassFromLeadingIcon', - 'eventTargetHasClass', 'registerEventHandler', 'deregisterEventHandler', - 'registerTrailingIconInteractionHandler', 'deregisterTrailingIconInteractionHandler', - 'notifyInteraction', 'notifyTrailingIconInteraction', 'notifyRemoval', + 'addClass', 'removeClass', 'hasClass', 'addClassToLeadingIcon', + 'removeClassFromLeadingIcon', 'eventTargetHasClass', 'registerEventHandler', + 'deregisterEventHandler', 'registerTrailingIconInteractionHandler', + 'deregisterTrailingIconInteractionHandler', 'notifyInteraction', + 'notifyTrailingIconInteraction', 'notifyRemoval', 'getComputedStyleValue', 'setStyleProperty', ]); }); From a02397ab919cbe28061163104e20a611c0e48d0b Mon Sep 17 00:00:00 2001 From: Fredrik Broman Date: Thu, 31 May 2018 14:43:33 +0200 Subject: [PATCH 027/175] docs(layout-grid): Correct wrong reference to Sass variable name (#2846) --- packages/mdc-layout-grid/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mdc-layout-grid/README.md b/packages/mdc-layout-grid/README.md index f82077133fe..b023452907b 100644 --- a/packages/mdc-layout-grid/README.md +++ b/packages/mdc-layout-grid/README.md @@ -172,7 +172,7 @@ Generates CSS for a fixed column width container on certain device type. The mix Variables | Description --- | --- `mdc-layout-grid-breakpoints` | A SASS Map specifies the breakpoints width -`mdc-layout-grid-default-margin` | A SASS Map specifies the number of columns +`mdc-layout-grid-columns` | A SASS Map specifies the number of columns `mdc-layout-grid-default-margin` | A SASS Map specifies the space between the edge of the grid and the edge of the first cell `mdc-layout-grid-default-gutter` | A SASS Map specifies the space between edges of adjacent cells `mdc-layout-grid-column-width` | A SASS Map specifies the column width of grid columns From eadec3cbfe2282265d61a378911ef684d14b61f9 Mon Sep 17 00:00:00 2001 From: Patty RoDee Date: Thu, 31 May 2018 10:50:56 -0700 Subject: [PATCH 028/175] fix(checkbox): Fix visibility in Windows high-contrast mode (#2672) --- packages/mdc-checkbox/_mixins.scss | 6 ++++-- packages/mdc-radio/_mixins.scss | 2 +- packages/mdc-radio/mdc-radio.scss | 12 +++++++----- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/mdc-checkbox/_mixins.scss b/packages/mdc-checkbox/_mixins.scss index 5b07f4fcd41..aba23a2fc1c 100644 --- a/packages/mdc-checkbox/_mixins.scss +++ b/packages/mdc-checkbox/_mixins.scss @@ -76,7 +76,7 @@ } .mdc-checkbox__mixedmark { - @include mdc-theme-prop(background-color, $color); + @include mdc-theme-prop(border-color, $color); } } @@ -365,9 +365,11 @@ @mixin mdc-checkbox__mixedmark_ { width: 100%; - height: floor($mdc-checkbox-mark-stroke-size); + height: 0; transform: scaleX(0) rotate(0deg); transition: mdc-checkbox-transition-exit(opacity), mdc-checkbox-transition-exit(transform); + border-width: floor($mdc-checkbox-mark-stroke-size) / 2; + border-style: solid; opacity: 0; } diff --git a/packages/mdc-radio/_mixins.scss b/packages/mdc-radio/_mixins.scss index 18df1067aab..3144dc2ba27 100644 --- a/packages/mdc-radio/_mixins.scss +++ b/packages/mdc-radio/_mixins.scss @@ -34,7 +34,7 @@ @mixin mdc-radio-ink-color($color) { // stylelint-disable-next-line selector-max-specificity .mdc-radio__native-control:enabled + .mdc-radio__background .mdc-radio__inner-circle { - @include mdc-theme-prop(background-color, $color); + @include mdc-theme-prop(border-color, $color); } } diff --git a/packages/mdc-radio/mdc-radio.scss b/packages/mdc-radio/mdc-radio.scss index 3a70277863a..c6bda221699 100644 --- a/packages/mdc-radio/mdc-radio.scss +++ b/packages/mdc-radio/mdc-radio.scss @@ -41,7 +41,7 @@ cursor: pointer; /* @alternate */ - will-change: opacity, transform, border-color, background-color, color; + will-change: opacity, transform, border-color, color; // Container for radio circles and ripple. &__background { @@ -88,7 +88,9 @@ width: 100%; height: 100%; transform: scale(0, 0); - transition: mdc-radio-exit(transform), mdc-radio-exit(background-color); + transition: mdc-radio-exit(transform), mdc-radio-exit(border-color); + border-width: 10px; + border-style: solid; border-radius: 50%; } @@ -124,7 +126,7 @@ } .mdc-radio__inner-circle { - transition: mdc-radio-enter(transform), mdc-radio-enter(background-color); + transition: mdc-radio-enter(transform), mdc-radio-enter(border-color); } } } @@ -138,7 +140,7 @@ + .mdc-radio__background { .mdc-radio__inner-circle { transform: scale(.5); - transition: mdc-radio-enter(transform), mdc-radio-enter(background-color); + transition: mdc-radio-enter(transform), mdc-radio-enter(border-color); } } } @@ -153,7 +155,7 @@ } .mdc-radio__inner-circle { - background-color: $mdc-radio-circle-color; + border-color: $mdc-radio-circle-color; } } } From 9b2c6a1632d398c7402836edeebdb4cdf2a4d5ed Mon Sep 17 00:00:00 2001 From: aprigogin <17075403+aprigogin@users.noreply.github.com> Date: Thu, 31 May 2018 13:40:58 -0700 Subject: [PATCH 029/175] fix(checkbox): make checkmark in high contrast mode on IE visible. (#2848) --- packages/mdc-checkbox/_variables.scss | 1 + packages/mdc-checkbox/mdc-checkbox.scss | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/packages/mdc-checkbox/_variables.scss b/packages/mdc-checkbox/_variables.scss index 5ba49ff11e1..f112d5e3169 100644 --- a/packages/mdc-checkbox/_variables.scss +++ b/packages/mdc-checkbox/_variables.scss @@ -17,6 +17,7 @@ @import "@material/theme/variables"; $mdc-checkbox-mark-color: mdc-theme-prop-value(on-primary); +$mdc-checkbox-mark-color-high-contrast-black-on-white: black !default; $mdc-checkbox-border-color: rgba(mdc-theme-prop-value(on-surface), .54); $mdc-checkbox-disabled-color: rgba(mdc-theme-prop-value(on-surface), .26); $mdc-checkbox-baseline-theme-color: secondary; diff --git a/packages/mdc-checkbox/mdc-checkbox.scss b/packages/mdc-checkbox/mdc-checkbox.scss index 8d3b88b0722..f927333f81e 100644 --- a/packages/mdc-checkbox/mdc-checkbox.scss +++ b/packages/mdc-checkbox/mdc-checkbox.scss @@ -35,6 +35,18 @@ @include mdc-checkbox-disabled-container-color_; } +@media screen and (-ms-high-contrast: active) { + .mdc-checkbox__mixedmark { + margin: 0 1px; // Extra horizontal space around mixedmark symbol. + } +} + +@media screen and (-ms-high-contrast: black-on-white) { + @at-root { + @include mdc-checkbox-ink-color($mdc-checkbox-mark-color-high-contrast-black-on-white); + } +} + // Needed to disable hover effects on CSS-only (non-JS) checkboxes .mdc-checkbox--disabled { @include mdc-checkbox--disabled_; From ef159c84bb3d1e0cb0a387bdf2c8357fce1f461b Mon Sep 17 00:00:00 2001 From: aprigogin <17075403+aprigogin@users.noreply.github.com> Date: Fri, 1 Jun 2018 14:24:31 -0700 Subject: [PATCH 030/175] fix(switch): Refactor switch styles to show up in HC windows mode. (#2853) --- packages/mdc-switch/_mixins.scss | 14 +++++++++++++- packages/mdc-switch/mdc-switch.scss | 14 +++++++++++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/packages/mdc-switch/_mixins.scss b/packages/mdc-switch/_mixins.scss index ba79e4c8161..93ac3eedea9 100644 --- a/packages/mdc-switch/_mixins.scss +++ b/packages/mdc-switch/_mixins.scss @@ -24,6 +24,7 @@ @mixin mdc-switch-track-color($color) { .mdc-switch__native-control:enabled:checked ~ .mdc-switch__background::before { @include mdc-theme-prop(background-color, $color); + @include mdc-theme-prop(border-color, $color); } } @@ -31,6 +32,7 @@ // stylelint-disable-next-line selector-max-specificity .mdc-switch__native-control:enabled:checked ~ .mdc-switch__background .mdc-switch__knob { @include mdc-theme-prop(background-color, $color); + @include mdc-theme-prop(border-color, $color); } } @@ -48,6 +50,7 @@ @mixin mdc-switch-unchecked-track-color_($color) { .mdc-switch__native-control:enabled:not(:checked) ~ .mdc-switch__background::before { @include mdc-theme-prop(background-color, $color); + @include mdc-theme-prop(border-color, $color); } } @@ -55,6 +58,7 @@ // stylelint-disable-next-line selector-max-specificity .mdc-switch__native-control:enabled:not(:checked) ~ .mdc-switch__background .mdc-switch__knob { @include mdc-theme-prop(background-color, $color); + @include mdc-theme-prop(border-color, $color); } } @@ -65,10 +69,18 @@ } } -@mixin mdc-switch-tap-target_ { +@mixin mdc-switch-native-control_ { position: absolute; top: -14px; left: -14px; width: $mdc-switch-focus-ring-diameter; height: $mdc-switch-focus-ring-diameter; } + +@mixin mdc-switch-tap-target_ { + position: absolute; + top: -24px; + left: -24px; + width: $mdc-switch-focus-ring-diameter; + height: $mdc-switch-focus-ring-diameter; +} diff --git a/packages/mdc-switch/mdc-switch.scss b/packages/mdc-switch/mdc-switch.scss index 8c62b8e30cb..9e85409f282 100644 --- a/packages/mdc-switch/mdc-switch.scss +++ b/packages/mdc-switch/mdc-switch.scss @@ -26,10 +26,11 @@ position: relative; &__native-control { - @include mdc-switch-tap-target_; + @include mdc-switch-native-control_; display: inline-block; margin-top: $mdc-switch-knob-vertical-offset_; + margin-left: 0; transition: mdc-switch-transition(transform); opacity: 0; cursor: pointer; @@ -73,7 +74,9 @@ left: 0; transition: mdc-switch-transition(opacity), - mdc-switch-transition(background-color); + mdc-switch-transition(background-color), + mdc-switch-transition(border-color); + border: 1px solid; border-radius: 7px; opacity: .38; content: ""; @@ -87,12 +90,15 @@ display: block; position: absolute; top: $mdc-switch-knob-vertical-offset_; + box-sizing: border-box; width: $mdc-switch-knob-diameter; height: $mdc-switch-knob-diameter; transform: translateX(0); transition: mdc-switch-transition(transform), - mdc-switch-transition(background-color); + mdc-switch-transition(background-color), + mdc-switch-transition(border-color); + border: $mdc-switch-knob-diameter / 2 solid; border-radius: 50%; z-index: 1; @@ -149,6 +155,8 @@ } .mdc-switch__knob { + border-width: 1px; // In high contrast mode, only show outline of the knob. + border-color: $mdc-switch-disabled-knob-color; background-color: $mdc-switch-disabled-knob-color; } } From 91ea09f14a80679913fa8961fa716d30754485d8 Mon Sep 17 00:00:00 2001 From: "Kenneth G. Franqueiro" Date: Mon, 4 Jun 2018 11:40:01 -0400 Subject: [PATCH 031/175] chore: Publish --- lerna.json | 2 +- packages/material-components-web/package.json | 52 +++++++++---------- packages/mdc-button/package.json | 6 +-- packages/mdc-card/package.json | 6 +-- packages/mdc-checkbox/package.json | 8 +-- packages/mdc-chips/package.json | 6 +-- packages/mdc-dialog/package.json | 6 +-- packages/mdc-drawer/package.json | 4 +- packages/mdc-fab/package.json | 4 +- packages/mdc-floating-label/package.json | 4 +- packages/mdc-form-field/package.json | 6 +-- packages/mdc-grid-list/package.json | 4 +- packages/mdc-icon-button/package.json | 4 +- packages/mdc-icon-toggle/package.json | 4 +- packages/mdc-list/package.json | 6 +-- packages/mdc-radio/package.json | 6 +-- packages/mdc-ripple/package.json | 2 +- packages/mdc-rtl/package.json | 2 +- packages/mdc-select/package.json | 8 +-- packages/mdc-selection-control/package.json | 4 +- packages/mdc-slider/package.json | 4 +- packages/mdc-snackbar/package.json | 4 +- packages/mdc-switch/package.json | 4 +- packages/mdc-tab/package.json | 4 +- packages/mdc-tabs/package.json | 6 +-- packages/mdc-textfield/package.json | 8 +-- packages/mdc-toolbar/package.json | 6 +-- packages/mdc-top-app-bar/package.json | 6 +-- 28 files changed, 93 insertions(+), 93 deletions(-) diff --git a/lerna.json b/lerna.json index ea0350234b5..859c2816870 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "2.0.0-beta.36", - "version": "0.36.0-0", + "version": "0.36.0", "commands": { "publish": { "ignore": [ diff --git a/packages/material-components-web/package.json b/packages/material-components-web/package.json index 04cacbb9b44..b0bf0eac0e8 100644 --- a/packages/material-components-web/package.json +++ b/packages/material-components-web/package.json @@ -1,7 +1,7 @@ { "name": "material-components-web", "description": "Modular and customizable Material Design UI components for the web", - "version": "0.36.0-0", + "version": "0.36.0", "license": "Apache-2.0", "keywords": [ "material components", @@ -16,40 +16,40 @@ "@material/animation": "^0.34.0", "@material/auto-init": "^0.35.0", "@material/base": "^0.35.0", - "@material/button": "^0.36.0-0", - "@material/card": "^0.36.0-0", - "@material/checkbox": "^0.36.0-0", - "@material/chips": "^0.36.0-0", - "@material/dialog": "^0.36.0-0", - "@material/drawer": "^0.35.0", + "@material/button": "^0.36.0", + "@material/card": "^0.36.0", + "@material/checkbox": "^0.36.0", + "@material/chips": "^0.36.0", + "@material/dialog": "^0.36.0", + "@material/drawer": "^0.36.0", "@material/elevation": "^0.35.0", - "@material/fab": "^0.36.0-0", - "@material/floating-label": "^0.35.2", - "@material/form-field": "^0.36.0-0", - "@material/grid-list": "^0.35.0", - "@material/icon-button": "^0.36.0-0", - "@material/icon-toggle": "^0.36.0-0", + "@material/fab": "^0.36.0", + "@material/floating-label": "^0.36.0", + "@material/form-field": "^0.36.0", + "@material/grid-list": "^0.36.0", + "@material/icon-button": "^0.36.0", + "@material/icon-toggle": "^0.36.0", "@material/image-list": "^0.35.0", "@material/layout-grid": "^0.34.0", "@material/line-ripple": "^0.35.0", "@material/linear-progress": "^0.35.0", - "@material/list": "^0.36.0-0", + "@material/list": "^0.36.0", "@material/menu": "^0.35.0", "@material/notched-outline": "^0.35.0", - "@material/radio": "^0.36.0-0", - "@material/ripple": "^0.36.0-0", - "@material/rtl": "^0.35.0", - "@material/select": "^0.36.0-0", - "@material/selection-control": "^0.36.0-0", + "@material/radio": "^0.36.0", + "@material/ripple": "^0.36.0", + "@material/rtl": "^0.36.0", + "@material/select": "^0.36.0", + "@material/selection-control": "^0.36.0", "@material/shape": "^0.35.0", - "@material/slider": "^0.35.0", - "@material/snackbar": "^0.35.0", - "@material/switch": "^0.35.2", - "@material/tabs": "^0.36.0-0", - "@material/textfield": "^0.36.0-0", + "@material/slider": "^0.36.0", + "@material/snackbar": "^0.36.0", + "@material/switch": "^0.36.0", + "@material/tabs": "^0.36.0", + "@material/textfield": "^0.36.0", "@material/theme": "^0.35.0", - "@material/toolbar": "^0.36.0-0", - "@material/top-app-bar": "^0.36.0-0", + "@material/toolbar": "^0.36.0", + "@material/top-app-bar": "^0.36.0", "@material/typography": "^0.35.0" } } diff --git a/packages/mdc-button/package.json b/packages/mdc-button/package.json index 24bfab6bebb..34fd27c317a 100644 --- a/packages/mdc-button/package.json +++ b/packages/mdc-button/package.json @@ -1,7 +1,7 @@ { "name": "@material/button", "description": "The Material Components for the web button component", - "version": "0.36.0-0", + "version": "0.36.0", "license": "Apache 2.0", "keywords": [ "material components", @@ -14,8 +14,8 @@ }, "dependencies": { "@material/elevation": "^0.35.0", - "@material/ripple": "^0.36.0-0", - "@material/rtl": "^0.35.0", + "@material/ripple": "^0.36.0", + "@material/rtl": "^0.36.0", "@material/theme": "^0.35.0", "@material/typography": "^0.35.0" } diff --git a/packages/mdc-card/package.json b/packages/mdc-card/package.json index 79144ba57d2..7cbd3f3e38d 100644 --- a/packages/mdc-card/package.json +++ b/packages/mdc-card/package.json @@ -1,6 +1,6 @@ { "name": "@material/card", - "version": "0.36.0-0", + "version": "0.36.0", "description": "The Material Components for the web card component", "license": "Apache-2.0", "keywords": [ @@ -14,8 +14,8 @@ }, "dependencies": { "@material/elevation": "^0.35.0", - "@material/ripple": "^0.36.0-0", - "@material/rtl": "^0.35.0", + "@material/ripple": "^0.36.0", + "@material/rtl": "^0.36.0", "@material/theme": "^0.35.0" } } diff --git a/packages/mdc-checkbox/package.json b/packages/mdc-checkbox/package.json index 2df1511a190..19aacb99e86 100644 --- a/packages/mdc-checkbox/package.json +++ b/packages/mdc-checkbox/package.json @@ -1,7 +1,7 @@ { "name": "@material/checkbox", "description": "The Material Components for the web checkbox component", - "version": "0.36.0-0", + "version": "0.36.0", "license": "Apache-2.0", "keywords": [ "material components", @@ -16,9 +16,9 @@ "dependencies": { "@material/animation": "^0.34.0", "@material/base": "^0.35.0", - "@material/ripple": "^0.36.0-0", - "@material/rtl": "^0.35.0", - "@material/selection-control": "^0.36.0-0", + "@material/ripple": "^0.36.0", + "@material/rtl": "^0.36.0", + "@material/selection-control": "^0.36.0", "@material/theme": "^0.35.0" } } diff --git a/packages/mdc-chips/package.json b/packages/mdc-chips/package.json index 41bcd495256..13a317ce8c0 100644 --- a/packages/mdc-chips/package.json +++ b/packages/mdc-chips/package.json @@ -1,7 +1,7 @@ { "name": "@material/chips", "description": "The Material Components for the Web chips component", - "version": "0.36.0-0", + "version": "0.36.0", "license": "Apache 2.0", "keywords": [ "material components", @@ -18,8 +18,8 @@ "dependencies": { "@material/animation": "^0.34.0", "@material/base": "^0.35.0", - "@material/checkbox": "^0.36.0-0", - "@material/ripple": "^0.36.0-0", + "@material/checkbox": "^0.36.0", + "@material/ripple": "^0.36.0", "@material/typography": "^0.35.0" } } diff --git a/packages/mdc-dialog/package.json b/packages/mdc-dialog/package.json index e0a92fdfc0d..05296008097 100644 --- a/packages/mdc-dialog/package.json +++ b/packages/mdc-dialog/package.json @@ -1,6 +1,6 @@ { "name": "@material/dialog", - "version": "0.36.0-0", + "version": "0.36.0", "description": "The Material Components Web dialog component", "license": "Apache-2.0", "keywords": [ @@ -18,8 +18,8 @@ "@material/animation": "^0.34.0", "@material/base": "^0.35.0", "@material/elevation": "^0.35.0", - "@material/ripple": "^0.36.0-0", - "@material/rtl": "^0.35.0", + "@material/ripple": "^0.36.0", + "@material/rtl": "^0.36.0", "@material/theme": "^0.35.0", "@material/typography": "^0.35.0", "focus-trap": "^2.3.0" diff --git a/packages/mdc-drawer/package.json b/packages/mdc-drawer/package.json index 8f36b17d347..5a34d6be093 100644 --- a/packages/mdc-drawer/package.json +++ b/packages/mdc-drawer/package.json @@ -1,6 +1,6 @@ { "name": "@material/drawer", - "version": "0.35.0", + "version": "0.36.0", "description": "The Material Components Web drawer component", "license": "Apache-2.0", "keywords": [ @@ -18,7 +18,7 @@ "@material/animation": "^0.34.0", "@material/base": "^0.35.0", "@material/elevation": "^0.35.0", - "@material/rtl": "^0.35.0", + "@material/rtl": "^0.36.0", "@material/theme": "^0.35.0", "@material/typography": "^0.35.0" } diff --git a/packages/mdc-fab/package.json b/packages/mdc-fab/package.json index 2c8993a660b..f38cc47c65e 100644 --- a/packages/mdc-fab/package.json +++ b/packages/mdc-fab/package.json @@ -1,7 +1,7 @@ { "name": "@material/fab", "description": "The Material Components for the web floating action button component", - "version": "0.36.0-0", + "version": "0.36.0", "license": "Apache-2.0", "keywords": [ "material components", @@ -16,7 +16,7 @@ "dependencies": { "@material/animation": "^0.34.0", "@material/elevation": "^0.35.0", - "@material/ripple": "^0.36.0-0", + "@material/ripple": "^0.36.0", "@material/theme": "^0.35.0" } } diff --git a/packages/mdc-floating-label/package.json b/packages/mdc-floating-label/package.json index b7d758d0d34..ccec73e1f94 100644 --- a/packages/mdc-floating-label/package.json +++ b/packages/mdc-floating-label/package.json @@ -1,7 +1,7 @@ { "name": "@material/floating-label", "description": "The Material Components for the web floating-label component", - "version": "0.35.2", + "version": "0.36.0", "license": "Apache-2.0", "keywords": [ "material components", @@ -19,7 +19,7 @@ }, "dependencies": { "@material/base": "^0.35.0", - "@material/rtl": "^0.35.0", + "@material/rtl": "^0.36.0", "@material/theme": "^0.35.0", "@material/typography": "^0.35.0" } diff --git a/packages/mdc-form-field/package.json b/packages/mdc-form-field/package.json index 48bd57159ec..3f8fa44dfad 100644 --- a/packages/mdc-form-field/package.json +++ b/packages/mdc-form-field/package.json @@ -1,7 +1,7 @@ { "name": "@material/form-field", "description": "Material Components for the web wrapper for laying out form fields and labels next to one another", - "version": "0.36.0-0", + "version": "0.36.0", "license": "Apache-2.0", "keywords": [ "material components", @@ -15,8 +15,8 @@ }, "dependencies": { "@material/base": "^0.35.0", - "@material/rtl": "^0.35.0", - "@material/selection-control": "^0.36.0-0", + "@material/rtl": "^0.36.0", + "@material/selection-control": "^0.36.0", "@material/theme": "^0.35.0", "@material/typography": "^0.35.0" } diff --git a/packages/mdc-grid-list/package.json b/packages/mdc-grid-list/package.json index 3d31d7a782f..c009205c7c4 100644 --- a/packages/mdc-grid-list/package.json +++ b/packages/mdc-grid-list/package.json @@ -1,6 +1,6 @@ { "name": "@material/grid-list", - "version": "0.35.0", + "version": "0.36.0", "description": "The Material Components for the web grid list component", "license": "Apache-2.0", "repository": { @@ -14,7 +14,7 @@ ], "dependencies": { "@material/base": "^0.35.0", - "@material/rtl": "^0.35.0", + "@material/rtl": "^0.36.0", "@material/theme": "^0.35.0", "@material/typography": "^0.35.0" }, diff --git a/packages/mdc-icon-button/package.json b/packages/mdc-icon-button/package.json index d715589aa2c..500bcf997f7 100644 --- a/packages/mdc-icon-button/package.json +++ b/packages/mdc-icon-button/package.json @@ -1,7 +1,7 @@ { "name": "@material/icon-button", "description": "The Material Components for the web icon button component", - "version": "0.36.0-0", + "version": "0.36.0", "license": "Apache 2.0", "keywords": [ "material components", @@ -16,7 +16,7 @@ }, "dependencies": { "@material/base": "^0.35.0", - "@material/ripple": "^0.36.0-0", + "@material/ripple": "^0.36.0", "@material/theme": "^0.35.0" }, "publishConfig": { diff --git a/packages/mdc-icon-toggle/package.json b/packages/mdc-icon-toggle/package.json index 1daead2f087..7573851379e 100644 --- a/packages/mdc-icon-toggle/package.json +++ b/packages/mdc-icon-toggle/package.json @@ -1,7 +1,7 @@ { "name": "@material/icon-toggle", "description": "The Material Components for the web icon toggle component", - "version": "0.36.0-0", + "version": "0.36.0", "license": "Apache-2.0", "keywords": [ "material components", @@ -16,7 +16,7 @@ "dependencies": { "@material/animation": "^0.34.0", "@material/base": "^0.35.0", - "@material/ripple": "^0.36.0-0", + "@material/ripple": "^0.36.0", "@material/theme": "^0.35.0" } } diff --git a/packages/mdc-list/package.json b/packages/mdc-list/package.json index ff78f450062..7decf75385e 100644 --- a/packages/mdc-list/package.json +++ b/packages/mdc-list/package.json @@ -1,7 +1,7 @@ { "name": "@material/list", "description": "The Material Components for the web list component", - "version": "0.36.0-0", + "version": "0.36.0", "license": "Apache-2.0", "keywords": [ "material components", @@ -13,8 +13,8 @@ "url": "https://github.com/material-components/material-components-web.git" }, "dependencies": { - "@material/ripple": "^0.36.0-0", - "@material/rtl": "^0.35.0", + "@material/ripple": "^0.36.0", + "@material/rtl": "^0.36.0", "@material/theme": "^0.35.0", "@material/typography": "^0.35.0" } diff --git a/packages/mdc-radio/package.json b/packages/mdc-radio/package.json index 73a4ca9644c..90a0c07e702 100644 --- a/packages/mdc-radio/package.json +++ b/packages/mdc-radio/package.json @@ -1,7 +1,7 @@ { "name": "@material/radio", "description": "The Material Components for the web radio component", - "version": "0.36.0-0", + "version": "0.36.0", "license": "Apache-2.0", "keywords": [ "material components", @@ -16,8 +16,8 @@ "dependencies": { "@material/animation": "^0.34.0", "@material/base": "^0.35.0", - "@material/ripple": "^0.36.0-0", - "@material/selection-control": "^0.36.0-0", + "@material/ripple": "^0.36.0", + "@material/selection-control": "^0.36.0", "@material/theme": "^0.35.0" } } diff --git a/packages/mdc-ripple/package.json b/packages/mdc-ripple/package.json index 6b793cea684..7551eb9df93 100644 --- a/packages/mdc-ripple/package.json +++ b/packages/mdc-ripple/package.json @@ -1,7 +1,7 @@ { "name": "@material/ripple", "description": "The Material Components for the web Ink Ripple effect for web element interactions", - "version": "0.36.0-0", + "version": "0.36.0", "license": "Apache-2.0", "keywords": [ "material components", diff --git a/packages/mdc-rtl/package.json b/packages/mdc-rtl/package.json index d60e3310028..e339fd3cea9 100644 --- a/packages/mdc-rtl/package.json +++ b/packages/mdc-rtl/package.json @@ -1,7 +1,7 @@ { "name": "@material/rtl", "description": "Material Components for the web RTL Scss helpers", - "version": "0.35.0", + "version": "0.36.0", "license": "Apache-2.0", "keywords": [ "material components", diff --git a/packages/mdc-select/package.json b/packages/mdc-select/package.json index 8660e473ae0..f8631bff087 100644 --- a/packages/mdc-select/package.json +++ b/packages/mdc-select/package.json @@ -1,7 +1,7 @@ { "name": "@material/select", "description": "The Material Components web select (text field drop-down) component", - "version": "0.36.0-0", + "version": "0.36.0", "license": "Apache-2.0", "keywords": [ "material components", @@ -17,10 +17,10 @@ "dependencies": { "@material/animation": "^0.34.0", "@material/base": "^0.35.0", - "@material/floating-label": "^0.35.2", + "@material/floating-label": "^0.36.0", "@material/line-ripple": "^0.35.0", - "@material/ripple": "^0.36.0-0", - "@material/rtl": "^0.35.0", + "@material/ripple": "^0.36.0", + "@material/rtl": "^0.36.0", "@material/theme": "^0.35.0", "@material/typography": "^0.35.0" } diff --git a/packages/mdc-selection-control/package.json b/packages/mdc-selection-control/package.json index 6469d753a3c..03cd144c778 100644 --- a/packages/mdc-selection-control/package.json +++ b/packages/mdc-selection-control/package.json @@ -1,7 +1,7 @@ { "name": "@material/selection-control", "description": "The set of base classes for Material selection controls", - "version": "0.36.0-0", + "version": "0.36.0", "license": "Apache-2.0", "main": "index.js", "repository": { @@ -9,7 +9,7 @@ "url": "https://github.com/material-components/material-components-web.git" }, "dependencies": { - "@material/ripple": "^0.36.0-0" + "@material/ripple": "^0.36.0" }, "publishConfig": { "access": "public" diff --git a/packages/mdc-slider/package.json b/packages/mdc-slider/package.json index b4fffb2c970..65dc99d6b03 100644 --- a/packages/mdc-slider/package.json +++ b/packages/mdc-slider/package.json @@ -1,6 +1,6 @@ { "name": "@material/slider", - "version": "0.35.0", + "version": "0.36.0", "description": "The Material Components for the web slider component", "main": "index.js", "license": "Apache-2.0", @@ -19,7 +19,7 @@ "dependencies": { "@material/animation": "^0.34.0", "@material/base": "^0.35.0", - "@material/rtl": "^0.35.0", + "@material/rtl": "^0.36.0", "@material/theme": "^0.35.0" } } diff --git a/packages/mdc-snackbar/package.json b/packages/mdc-snackbar/package.json index f0f9f02501d..f6bc565abd7 100644 --- a/packages/mdc-snackbar/package.json +++ b/packages/mdc-snackbar/package.json @@ -1,7 +1,7 @@ { "name": "@material/snackbar", "description": "The Material Components for the web snackbar component", - "version": "0.35.0", + "version": "0.36.0", "license": "Apache-2.0", "keywords": [ "material components", @@ -16,7 +16,7 @@ "dependencies": { "@material/animation": "^0.34.0", "@material/base": "^0.35.0", - "@material/rtl": "^0.35.0", + "@material/rtl": "^0.36.0", "@material/theme": "^0.35.0", "@material/typography": "^0.35.0" } diff --git a/packages/mdc-switch/package.json b/packages/mdc-switch/package.json index d1770b2077a..b9b85932a32 100644 --- a/packages/mdc-switch/package.json +++ b/packages/mdc-switch/package.json @@ -1,7 +1,7 @@ { "name": "@material/switch", "description": "The Material Components for the web switch component", - "version": "0.35.2", + "version": "0.36.0", "license": "Apache-2.0", "keywords": [ "material components", @@ -15,7 +15,7 @@ "dependencies": { "@material/animation": "^0.34.0", "@material/elevation": "^0.35.0", - "@material/rtl": "^0.35.0", + "@material/rtl": "^0.36.0", "@material/theme": "^0.35.0" }, "publishConfig": { diff --git a/packages/mdc-tab/package.json b/packages/mdc-tab/package.json index 89658a5af38..5ec425d7122 100644 --- a/packages/mdc-tab/package.json +++ b/packages/mdc-tab/package.json @@ -1,7 +1,7 @@ { "name": "@material/tab", "description": "The Material Components for the web tab component", - "version": "0.36.0-0", + "version": "0.36.0", "license": "Apache-2.0", "private": true, "keywords": [ @@ -16,7 +16,7 @@ }, "dependencies": { "@material/base": "^0.35.0", - "@material/ripple": "^0.36.0-0", + "@material/ripple": "^0.36.0", "@material/rtl": "^0.30.0", "@material/theme": "^0.30.0", "@material/typography": "^0.35.0" diff --git a/packages/mdc-tabs/package.json b/packages/mdc-tabs/package.json index 64e0b5cb2c7..af45a24fdb8 100644 --- a/packages/mdc-tabs/package.json +++ b/packages/mdc-tabs/package.json @@ -1,6 +1,6 @@ { "name": "@material/tabs", - "version": "0.36.0-0", + "version": "0.36.0", "description": "The Material Components for the web tabs component", "license": "Apache-2.0", "repository": { @@ -18,8 +18,8 @@ "dependencies": { "@material/animation": "^0.34.0", "@material/base": "^0.35.0", - "@material/ripple": "^0.36.0-0", - "@material/rtl": "^0.35.0", + "@material/ripple": "^0.36.0", + "@material/rtl": "^0.36.0", "@material/theme": "^0.35.0", "@material/typography": "^0.35.0" } diff --git a/packages/mdc-textfield/package.json b/packages/mdc-textfield/package.json index b2d1a0df3f8..75b566daefe 100644 --- a/packages/mdc-textfield/package.json +++ b/packages/mdc-textfield/package.json @@ -1,7 +1,7 @@ { "name": "@material/textfield", "description": "The Material Components for the web text field component", - "version": "0.36.0-0", + "version": "0.36.0", "license": "Apache-2.0", "keywords": [ "material components", @@ -17,11 +17,11 @@ "dependencies": { "@material/animation": "^0.34.0", "@material/base": "^0.35.0", - "@material/floating-label": "^0.35.2", + "@material/floating-label": "^0.36.0", "@material/line-ripple": "^0.35.0", "@material/notched-outline": "^0.35.0", - "@material/ripple": "^0.36.0-0", - "@material/rtl": "^0.35.0", + "@material/ripple": "^0.36.0", + "@material/rtl": "^0.36.0", "@material/theme": "^0.35.0", "@material/typography": "^0.35.0" } diff --git a/packages/mdc-toolbar/package.json b/packages/mdc-toolbar/package.json index 14bd1459430..b8bc0b1bf79 100644 --- a/packages/mdc-toolbar/package.json +++ b/packages/mdc-toolbar/package.json @@ -1,6 +1,6 @@ { "name": "@material/toolbar", - "version": "0.36.0-0", + "version": "0.36.0", "description": "The Material Components for the web toolbar component", "license": "Apache-2.0", "repository": { @@ -15,8 +15,8 @@ "dependencies": { "@material/base": "^0.35.0", "@material/elevation": "^0.35.0", - "@material/ripple": "^0.36.0-0", - "@material/rtl": "^0.35.0", + "@material/ripple": "^0.36.0", + "@material/rtl": "^0.36.0", "@material/theme": "^0.35.0", "@material/typography": "^0.35.0" }, diff --git a/packages/mdc-top-app-bar/package.json b/packages/mdc-top-app-bar/package.json index 5ac8daced3a..5ee1e1004ae 100644 --- a/packages/mdc-top-app-bar/package.json +++ b/packages/mdc-top-app-bar/package.json @@ -1,6 +1,6 @@ { "name": "@material/top-app-bar", - "version": "0.36.0-0", + "version": "0.36.0", "description": "The Material Components for the web top app bar component", "license": "Apache-2.0", "repository": { @@ -18,8 +18,8 @@ "@material/animation": "^0.34.0", "@material/base": "^0.35.0", "@material/elevation": "^0.35.0", - "@material/ripple": "^0.36.0-0", - "@material/rtl": "^0.35.0", + "@material/ripple": "^0.36.0", + "@material/rtl": "^0.36.0", "@material/theme": "^0.35.0", "@material/typography": "^0.35.0" }, From 13fd6784866864839d0d287b3703b3beb0888d9c Mon Sep 17 00:00:00 2001 From: "Kenneth G. Franqueiro" Date: Mon, 4 Jun 2018 11:42:35 -0400 Subject: [PATCH 032/175] docs: Update CHANGELOG.md --- CHANGELOG.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a76952e5f13..db61fa84847 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ - -# [0.36.0-0](https://github.com/material-components/material-components-web/compare/v0.35.2...v0.36.0-0) (2018-05-29) + +# [0.36.0](https://github.com/material-components/material-components-web/compare/v0.36.0-0...v0.36.0) (2018-06-04) ### Bug Fixes @@ -14,6 +14,17 @@ * **text-field:** Update floating-label to work properly for number fields ([#2781](https://github.com/material-components/material-components-web/issues/2781)) ([d0bff1f](https://github.com/material-components/material-components-web/commit/d0bff1f)) * **top-app-bar:** Add z-index. Cleanup redundant properties. ([#2828](https://github.com/material-components/material-components-web/issues/2828)) ([3f6bbc1](https://github.com/material-components/material-components-web/commit/3f6bbc1)) * **top-app-bar:** Fix testdouble warning about using both stub & verify. ([#2793](https://github.com/material-components/material-components-web/issues/2793)) ([d79af08](https://github.com/material-components/material-components-web/commit/d79af08)) +* **checkbox:** Fix visibility in Windows high-contrast mode ([#2672](https://github.com/material-components/material-components-web/issues/2672)) ([eadec3c](https://github.com/material-components/material-components-web/commit/eadec3c)) +* **checkbox:** make checkmark in high contrast mode on IE visible. ([#2848](https://github.com/material-components/material-components-web/issues/2848)) ([9b2c6a1](https://github.com/material-components/material-components-web/commit/9b2c6a1)) +* **chips:** Add delay to filter chip checkmark ([#2804](https://github.com/material-components/material-components-web/issues/2804)) ([9e35b1e](https://github.com/material-components/material-components-web/commit/9e35b1e)) +* **chips:** Fix choice-chips leading icon being hidden ([#2796](https://github.com/material-components/material-components-web/issues/2796)) ([7d406fa](https://github.com/material-components/material-components-web/commit/7d406fa)), closes [#2728](https://github.com/material-components/material-components-web/issues/2728) +* **switch:** Refactor switch styles to show up in HC windows mode. ([#2853](https://github.com/material-components/material-components-web/issues/2853)) ([ef159c8](https://github.com/material-components/material-components-web/commit/ef159c8)) +* **text-field:** Changes to text area label positioning to cover text content ([#2816](https://github.com/material-components/material-components-web/issues/2816)) ([d6f4dc1](https://github.com/material-components/material-components-web/commit/d6f4dc1)) + + +### Code Refactoring + +* **chips:** Stop handling DOM manipulation in input chips ([#2791](https://github.com/material-components/material-components-web/issues/2791)) ([5a8ada5](https://github.com/material-components/material-components-web/commit/5a8ada5)) ### Documentation @@ -25,6 +36,7 @@ * **icon-button:** Add new package ([#2748](https://github.com/material-components/material-components-web/issues/2748)) ([39a4815](https://github.com/material-components/material-components-web/commit/39a4815)) * **text-field:** Add methods to set text field icon aria-label and content ([#2771](https://github.com/material-components/material-components-web/issues/2771)) ([02d7dca](https://github.com/material-components/material-components-web/commit/02d7dca)) +* **rtl:** Make mdc-rtl-reflexive sass mixin public ([#2823](https://github.com/material-components/material-components-web/issues/2823)) ([ca018a7](https://github.com/material-components/material-components-web/commit/ca018a7)) ### BREAKING CHANGES @@ -32,6 +44,7 @@ * **text-field:** Adds setContent adapter API to text field icon * **icon-toggle:** The icon-toggle package has been deprecated. The functionality was moved to the icon-button package. Please refer to the icon-button readme for changes and how to update. * **text-field:** registerValidationAttributeChangeHandler adapter API now expects the handler to accept an array of strings, not mutation objects +* **chips:** MDCChipSet/MDCChip no longer manipulates DOM directly. Removed MDCChipSetAdapter.appendChip, MDCChipSetFoundation.addChip, and MDCChip.remove. Modified signature of MDCChipSet.addChip From 5f4454a399b4518d7782922dcbe9e5671dd6347e Mon Sep 17 00:00:00 2001 From: "Kenneth G. Franqueiro" Date: Mon, 4 Jun 2018 13:50:04 -0400 Subject: [PATCH 033/175] chore(elevation): Update to use latest theme version (#2870) --- packages/mdc-elevation/_mixins.scss | 8 +------- packages/mdc-elevation/package.json | 2 +- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/packages/mdc-elevation/_mixins.scss b/packages/mdc-elevation/_mixins.scss index 40f1564c4de..0ec38b476c0 100644 --- a/packages/mdc-elevation/_mixins.scss +++ b/packages/mdc-elevation/_mixins.scss @@ -30,13 +30,7 @@ @error "$z-value must be between 0 and 24, but received '#{$z-value}'"; } - @if map-has-key($mdc-theme-property-values, $color) { - $color: map-get($mdc-theme-property-values, $color); - } - - @if type-of($color) != color { - @error "$color must be a valid color, but '#{$color}' is of type #{type-of($color)}"; - } + $color: mdc-theme-prop-value($color); $umbra-z-value: map-get($mdc-elevation-umbra-map, $z-value); $penumbra-z-value: map-get($mdc-elevation-penumbra-map, $z-value); diff --git a/packages/mdc-elevation/package.json b/packages/mdc-elevation/package.json index b9647c33dd9..36a9f7afc2e 100644 --- a/packages/mdc-elevation/package.json +++ b/packages/mdc-elevation/package.json @@ -14,6 +14,6 @@ }, "dependencies": { "@material/animation": "^0.34.0", - "@material/theme": "^0.4.0" + "@material/theme": "^0.35.0" } } From eb00fd33376b94fff3e7adbf0985ae93f8283018 Mon Sep 17 00:00:00 2001 From: Bonnie Zhou Date: Mon, 4 Jun 2018 11:24:17 -0700 Subject: [PATCH 034/175] feat(chips): Expose method to begin chip exit animation (#2845) --- demos/chips.html | 11 +++++++++++ packages/mdc-chips/README.md | 1 + packages/mdc-chips/chip/index.js | 9 ++++++++- test/unit/mdc-chips/mdc-chip.test.js | 6 ++++++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/demos/chips.html b/demos/chips.html index d2d70ccbc11..4c06dad05cf 100644 --- a/demos/chips.html +++ b/demos/chips.html @@ -63,6 +63,9 @@

Input Chips

+
face @@ -239,6 +242,7 @@

Custom theme

var chipSets = document.querySelectorAll('.mdc-chip-set:not(#input-chip-set)'); var input = document.getElementById('input-chip-set-input'); var inputButton = document.getElementById('input-chip-set-button'); + var deleteButton = document.getElementById('input-chip-set-delete-button'); [].forEach.call(chipSets, function(chipSet) { mdc.chips.MDCChipSet.attachTo(chipSet); @@ -281,8 +285,15 @@

Custom theme

root && inputChipSetEl.removeChild(root); } + function deleteLastChip() { + const lastChipIndex = inputChipSetComponent.chips.length - 1; + const lastChip = inputChipSetComponent.chips[lastChipIndex]; + lastChip.beginExit(); + }; + inputButton.addEventListener('click', addInputChip); input.addEventListener('keydown', addInputChip); + deleteButton.addEventListener('click', deleteLastChip); inputChipSetEl.addEventListener('MDCChip:removal', removeChip); }); diff --git a/packages/mdc-chips/README.md b/packages/mdc-chips/README.md index 97c24410391..0d5c941f311 100644 --- a/packages/mdc-chips/README.md +++ b/packages/mdc-chips/README.md @@ -213,6 +213,7 @@ Method Signature | Description --- | --- `get foundation() => MDCChipFoundation` | Returns the foundation `isSelected() => boolean` | Proxies to the foundation's `isSelected` method +`beginExit() => void` | Begins the exit animation which leads to removal of the chip Property | Value Type | Description --- | --- | --- diff --git a/packages/mdc-chips/chip/index.js b/packages/mdc-chips/chip/index.js index 3f3654ddb34..43223c27ee0 100644 --- a/packages/mdc-chips/chip/index.js +++ b/packages/mdc-chips/chip/index.js @@ -20,7 +20,7 @@ import {MDCRipple, MDCRippleFoundation} from '@material/ripple/index'; import MDCChipAdapter from './adapter'; import MDCChipFoundation from './foundation'; -import {strings} from './constants'; +import {strings, cssClasses} from './constants'; /** * @extends {MDCComponent} @@ -82,6 +82,13 @@ class MDCChip extends MDCComponent { return this.foundation_.isSelected(); } + /** + * Begins the exit animation which leads to removal of the chip. + */ + beginExit() { + this.root_.classList.add(cssClasses.CHIP_EXIT); + } + /** * @return {!MDCChipFoundation} */ diff --git a/test/unit/mdc-chips/mdc-chip.test.js b/test/unit/mdc-chips/mdc-chip.test.js index 83db905bbaa..08143fbf517 100644 --- a/test/unit/mdc-chips/mdc-chip.test.js +++ b/test/unit/mdc-chips/mdc-chip.test.js @@ -202,3 +202,9 @@ test('#isSelected proxies to foundation', () => { component.isSelected(); td.verify(mockFoundation.isSelected()); }); + +test(`#beginExit adds ${MDCChipFoundation.cssClasses.CHIP_EXIT} class`, () => { + const {component, root} = setupMockFoundationTest(); + component.beginExit(); + assert.isTrue(root.classList.contains(MDCChipFoundation.cssClasses.CHIP_EXIT)); +}); From cfa9f808a7b73569a463a68fb3ceb24d11c120a9 Mon Sep 17 00:00:00 2001 From: "Kenneth G. Franqueiro" Date: Mon, 4 Jun 2018 17:37:42 -0400 Subject: [PATCH 035/175] docs: Add docs for releases/branches; rename releases.md more clearly (#2847) --- .../{release.md => release-process.md} | 0 docs/open_source/releases-and-branches.md | 78 +++++++++++++++++++ 2 files changed, 78 insertions(+) rename docs/open_source/{release.md => release-process.md} (100%) create mode 100644 docs/open_source/releases-and-branches.md diff --git a/docs/open_source/release.md b/docs/open_source/release-process.md similarity index 100% rename from docs/open_source/release.md rename to docs/open_source/release-process.md diff --git a/docs/open_source/releases-and-branches.md b/docs/open_source/releases-and-branches.md new file mode 100644 index 00000000000..ac6e8855697 --- /dev/null +++ b/docs/open_source/releases-and-branches.md @@ -0,0 +1,78 @@ +# Releases and Branches + +This document describes the branching and release strategy we use for MDC Web, and how it affects dependent repositories +we maintain, namely the [MDC Web Catalog](https://github.com/material-components/material-components-web-catalog) and +[MDC React](https://github.com/material-components/material-components-web-react). + +For an explanation of the steps needed to cut a release of MDC Web, see [Release Process](./release-process.md). + +## MDC Web Release Schedule and Versioning + +MDC Web follows a 2-week release cycle. We expect to have one release per month containing breaking changes, to coincide +with the [Material Design Roadmap](https://github.com/material-components/material-components/blob/develop/ROADMAP.md). +Any other interim releases will be patch releases including any non-breaking / non-feature changes that can be +cherry-picked from master in a straightforward manner. + +This is a change from our earlier process, where we simply tagged a release with whatever has been merged to master +within the two-week cycle, and would rev the version number accordingly based on whether there were breaking changes. + +## Release Types + +### Breaking-change Releases + +These are currently our minor releases, e.g. 0.35.0, 0.36.0, etc. These follow the currently-outlined +[Release Process](./release-process.md) and are performed against `master`. + +### Pre-releases + +MDC Web Catalog and MDC React both depend on MDC Web via npm dependencies. In order to be able to integrate +breaking changes for the upcoming release ahead of time - preferably while the necessary changes are fresh in someone's +mind - we will cut pre-releases of MDC Web when breaking changes are merged which warrant updates in the other +repositories. These will be cut on an as-needed basis, with no set schedule. + +The Catalog and React repositories will each have a `next` branch, which will be updated to point to the pre-release. +Pull requests should be filed against this branch for changes needed for the upcoming MDC Web release. + +Later, when the new version of MDC Web is released, the `next` branch will again be updated to point to the new release, +and we will open a PR to squash & merge its contents onto `master`. Once this is done, the `next` branch will be +hard-reset against `master` and force-pushed to accommodate the subsequent release. + +The process for pre-releases should be largely similar to the process for regular releases, with minor changes +(such as the addition of a very important `lerna` option to avoid updating the `latest` tag on npm). + +Pre-releases will also involve updates to the CHANGELOG. We should consolidate these when tagging the final +release to make it easier to read, since the pre-releases will be irrelevant at that point. + +### Bugfix Releases + +Bugfix releases for MDC Web will be released based on the last tagged release, with any commits not involving +breaking changes or features cherry-picked in. The process would look as follows (using 0.36.x as an example): + +1. `git checkout v0.36.0` (or e.g. `v0.36.1` if this is the second bugfix release since the last breaking-change release) +2. `git cherry-pick -x ` +3. Follow the [release process](./release-process.md), choosing "patch" when lerna prompts for version +4. Cherry-pick the publish and CHANGELOG commits onto `master` to ensure that bugfix releases are included in the overall history + +A branch can be created in/after step 1 if desired, but should be temporary - the bugfix release can be referenced via +its git tag once the release process is done. + +We're working on automating the task of finding non-breaking/non-feature commits, cherry-picking them, and test-running +the build and unit tests, but it will still require manually checking for commits dependent on features or breaking +changes that were pruned. + +We may refine this process (and move some documentation to the Release Process page) based on our experiences after our +next bugfix release. + +> Note: In the rare occasion that no breaking changes have been committed since the last breaking-change release, +> a bugfix release can simply be released directly against `master` as documented for breaking-change releases above. + +## Feature Branches + +The `master` branch remains the default target of development, for both bug fixes and breaking changes. + +If we foresee a new component requiring a large amount of work across multiple PRs and release cycles, we +should keep the work in a collective feature branch first, in an attempt to avoid API churn across releases. +(The new work on MDC Tab and associated packages is one example.) + +This allows work on the feature to be performed across multiple separate PRs, which will each be merged into the feature +branch, before finally merging the feature branch into `master` after all aspects of the feature are complete. From 0fac7fe8fb29202a8dfcecd41ea61baf8d1327be Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" Date: Tue, 5 Jun 2018 08:58:30 -0700 Subject: [PATCH 036/175] =?UTF-8?q?chore(package):=20Update=20standard-cha?= =?UTF-8?q?ngelog=20to=20the=20latest=20version=20=F0=9F=9A=80=20(#2860)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 164 +++++++++++++++++++++++++++++++++++++++------- package.json | 2 +- 2 files changed, 141 insertions(+), 25 deletions(-) diff --git a/package-lock.json b/package-lock.json index 558b5f5e47d..15636c9e1d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14901,15 +14901,15 @@ } }, "standard-changelog": { - "version": "1.0.19", - "resolved": "https://registry.npmjs.org/standard-changelog/-/standard-changelog-1.0.19.tgz", - "integrity": "sha512-KlVr5m01m0yrCiNDcr+JShS+HRGhBjWxAxj2uSuXsLbo8XqSBJZLeCH+vUpG2lJIXcI7F2PtcdQjooUQvNVDaA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/standard-changelog/-/standard-changelog-2.0.0.tgz", + "integrity": "sha512-9eRK0FvtWCKDsINNA/S6vfA9CYdtUw47UDcJQC7k1/NUd5s26dt8Akmb8I6Ie7pxflsyIMtQnOIaB0ZX+mHJRg==", "dev": true, "requires": { "add-stream": "^1.0.0", "chalk": "^1.1.3", "conventional-changelog-angular": "^1.6.6", - "conventional-changelog-core": "^2.0.11", + "conventional-changelog-core": "^3.0.0", "figures": "^1.5.0", "fs-access": "^1.0.0", "lodash": "^4.2.1", @@ -14936,6 +14936,76 @@ "quick-lru": "^1.0.0" } }, + "conventional-changelog-core": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-3.0.0.tgz", + "integrity": "sha512-D2hApWWsdh4tkNgDjn1KtRapxUJ70Sd+V84btTVJJJ96S3cVRES8Ty3ih0TRkOZmDkw/uS0mxrHSskQ/P/Gvsg==", + "dev": true, + "requires": { + "conventional-changelog-writer": "^4.0.0", + "conventional-commits-parser": "^3.0.0", + "dateformat": "^3.0.0", + "get-pkg-repo": "^1.0.0", + "git-raw-commits": "^2.0.0", + "git-remote-origin-url": "^2.0.0", + "git-semver-tags": "^2.0.0", + "lodash": "^4.2.1", + "normalize-package-data": "^2.3.5", + "q": "^1.5.1", + "read-pkg": "^1.1.0", + "read-pkg-up": "^1.0.1", + "through2": "^2.0.0" + } + }, + "conventional-changelog-writer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.0.tgz", + "integrity": "sha512-hMZPe0AQ6Bi05epeK/7hz80xxk59nPA5z/b63TOHq2wigM0/akreOc8N4Jam5b9nFgKWX1e9PdPv2ewgW6bcfg==", + "dev": true, + "requires": { + "compare-func": "^1.3.1", + "conventional-commits-filter": "^2.0.0", + "dateformat": "^3.0.0", + "handlebars": "^4.0.2", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.2.1", + "meow": "^4.0.0", + "semver": "^5.5.0", + "split": "^1.0.0", + "through2": "^2.0.0" + } + }, + "conventional-commits-filter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.0.tgz", + "integrity": "sha512-Cfl0j1/NquB/TMVx7Wrmyq7uRM+/rPQbtVVGwzfkhZ6/yH6fcMmP0Q/9044TBZPTNdGzm46vXFXL14wbET0/Mg==", + "dev": true, + "requires": { + "is-subset": "^0.1.1", + "modify-values": "^1.0.0" + } + }, + "conventional-commits-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.0.0.tgz", + "integrity": "sha512-GWh71U26BLWgMykCp+VghZ4s64wVbtseECcKQ/PvcPZR2cUnz+FUc2J9KjxNl7/ZbCxST8R03c9fc+Vi0umS9Q==", + "dev": true, + "requires": { + "JSONStream": "^1.0.4", + "is-text-path": "^1.0.0", + "lodash": "^4.2.1", + "meow": "^4.0.0", + "split2": "^2.0.0", + "through2": "^2.0.0", + "trim-off-newlines": "^1.0.0" + } + }, + "dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true + }, "figures": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", @@ -14955,6 +15025,29 @@ "locate-path": "^2.0.0" } }, + "git-raw-commits": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.0.tgz", + "integrity": "sha512-w4jFEJFgKXMQJ0H0ikBk2S+4KP2VEjhCvLCNqbNRQC8BgGWgLKNCO7a9K9LI+TVT7Gfoloje502sEnctibffgg==", + "dev": true, + "requires": { + "dargs": "^4.0.1", + "lodash.template": "^4.0.2", + "meow": "^4.0.0", + "split2": "^2.0.0", + "through2": "^2.0.0" + } + }, + "git-semver-tags": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-2.0.0.tgz", + "integrity": "sha512-lSgFc3zQTul31nFje2Q8XdNcTOI6B4I3mJRPCgFzHQQLfxfqdWTYzdtCaynkK5Xmb2wQlSJoKolhXJ1VhKROnQ==", + "dev": true, + "requires": { + "meow": "^4.0.0", + "semver": "^5.5.0" + } + }, "indent-string": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", @@ -14994,6 +15087,29 @@ "read-pkg-up": "^3.0.0", "redent": "^2.0.0", "trim-newlines": "^2.0.0" + }, + "dependencies": { + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + } + } } }, "minimist": { @@ -15027,26 +15143,11 @@ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - } + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true }, "redent": { "version": "2.0.0", @@ -15058,6 +15159,21 @@ "strip-indent": "^2.0.0" } }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "requires": { + "through": "2" + } + }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", diff --git a/package.json b/package.json index 3fe6aa3da01..19b26b48b71 100644 --- a/package.json +++ b/package.json @@ -104,7 +104,7 @@ "semver": "^5.3.0", "serve-index": "^1.9.1", "simple-git": "^1.92.0", - "standard-changelog": "^1.0.19", + "standard-changelog": "^2.0.0", "stylelint": "^9.0.0", "stylelint-config-standard": "^18.0.0", "stylelint-order": "^0.8.0", From 1548230677925fc689d388c16e4fb77e117c9a89 Mon Sep 17 00:00:00 2001 From: Will Ernest <34519388+williamernest@users.noreply.github.com> Date: Tue, 5 Jun 2018 09:27:05 -0700 Subject: [PATCH 037/175] fix(menu): Update adapter to check for focus before calling (#2880) --- packages/mdc-menu/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mdc-menu/index.js b/packages/mdc-menu/index.js index f250e646ff8..03a7f89bca5 100644 --- a/packages/mdc-menu/index.js +++ b/packages/mdc-menu/index.js @@ -163,7 +163,7 @@ class MDCMenu extends MDCComponent { this.previousFocus_ = document.activeElement; }, restoreFocus: () => { - if (this.previousFocus_) { + if (this.previousFocus_ && this.previousFocus_.focus) { this.previousFocus_.focus(); } }, From 48631259955b282e43a9e7d3e42e3ab18018eb77 Mon Sep 17 00:00:00 2001 From: Will Ernest <34519388+williamernest@users.noreply.github.com> Date: Tue, 5 Jun 2018 09:50:03 -0700 Subject: [PATCH 038/175] feat(select): Add outlined variant (#2674) --- demos/select.html | 105 ++++++++++++++++++++++++ demos/select.scss | 6 ++ packages/mdc-select/README.md | 22 +++++ packages/mdc-select/_mixins.scss | 66 +++++++++++++++ packages/mdc-select/_variables.scss | 10 +++ packages/mdc-select/constants.js | 13 ++- packages/mdc-select/foundation.js | 34 +++++++- packages/mdc-select/index.js | 78 ++++++++++++++++-- packages/mdc-select/mdc-select.scss | 58 +++++++++++-- packages/mdc-select/package.json | 1 + test/unit/mdc-select/foundation.test.js | 54 ++++++++++-- test/unit/mdc-select/mdc-select.test.js | 46 ++++++++++- 12 files changed, 469 insertions(+), 24 deletions(-) diff --git a/demos/select.html b/demos/select.html index c4d43b30a92..2608f0e5865 100644 --- a/demos/select.html +++ b/demos/select.html @@ -131,6 +131,7 @@

Fully-Featured JS Component

+

Select box

@@ -178,6 +179,67 @@

Select box

+ +
+

Outlined Select

+
+
+ + +
+ + + +
+
+
+
+

Currently selected: (none)

+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+ +
+
+

Pre-selected option via HTML

@@ -307,6 +369,49 @@

MDC Select with optgroups

updateSelectedTextContent(); }); }); + + demoReady(function() { + + var root = document.getElementById('outline-js-select'); + var currentlySelected = document.getElementById('currently-selected-outline'); + var select = new mdc.select.MDCSelect(root); + var demoWrapper = root.parentElement; + var rtlCb = document.getElementById('rtl-outline'); + var alternateColorsCb = document.getElementById('alternate-colors-outline'); + var disabledCb = document.getElementById('disabled-outline'); + var setSelectedButton = document.getElementById('set-selected-index-zero-button-outline'); + var setValueMeatButton = document.getElementById('set-value-meat-button-outline'); + function updateSelectedTextContent() { + var value = select.value; + var index = select.selectedIndex; + currentlySelected.textContent = value ? value + ' at index ' + index : '(none)'; + } + root.addEventListener('change', function() { + updateSelectedTextContent(); + }); + rtlCb.addEventListener('change', function() { + if (rtlCb.checked) { + demoWrapper.setAttribute('dir', 'rtl'); + } else { + demoWrapper.removeAttribute('dir'); + } + select.layout(); + }); + alternateColorsCb.addEventListener('change', function() { + root.classList[alternateColorsCb.checked ? 'add' : 'remove']('demo-select-custom-colors'); + }); + disabledCb.addEventListener('change', function() { + select.disabled = disabledCb.checked; + }); + setSelectedButton.addEventListener('click', function() { + select.selectedIndex = 0; + updateSelectedTextContent(); + }); + setValueMeatButton.addEventListener('click', function() { + select.value = 'meat'; + updateSelectedTextContent(); + }); + }); diff --git a/demos/select.scss b/demos/select.scss index bc00303e9a5..c1ee05f4df2 100644 --- a/demos/select.scss +++ b/demos/select.scss @@ -36,6 +36,12 @@ @include mdc-select-container-fill-color(rgba(blue, .1)); } +.demo-select-custom-colors.mdc-select--outlined { + @include mdc-select-outline-color(rgba(blue, .6)); + @include mdc-select-hover-outline-color(rgba(blue, .87)); + @include mdc-select-focused-outline-color(green); +} + .button-container { margin: 8px 0; } diff --git a/packages/mdc-select/README.md b/packages/mdc-select/README.md index cf211e1c852..d19930ee1d3 100644 --- a/packages/mdc-select/README.md +++ b/packages/mdc-select/README.md @@ -98,6 +98,26 @@ modifier class on the root element. ``` +### Outlined Select + +The Select Outlined variant uses the `mdc-notched-outline` in place of the `mdc-line-ripple` element and adds the +`mdc-select--outlined` modifier class on the root element. + +```html +
+ + +
+ + + +
+
+
+``` + ### Additional Information #### Select with pre-selected option @@ -195,6 +215,7 @@ Mixin | Description `mdc-select-bottom-line-color($color)` | Customizes the color of the default bottom line of the select. `mdc-select-focused-bottom-line-color($color)` | Customizes the color of the bottom line of the select when focused. `mdc-select-hover-bottom-line-color($color)` | Customizes the color of the bottom line when select is hovered. +`mdc-select-outline-corner-radius($color)` | Customizes the color of the notched outline when select is focused. > NOTE: To further customize the floating label, please see the [floating label documentation](./../mdc-floating-label/README.md). @@ -237,6 +258,7 @@ If you are using a JavaScript framework, such as React or Angular, you can creat | Method Signature | Description | | --- | --- | +| `notchOutline(openNotch: boolean) => void` | Opens/closes the notched outline. | | `setValue(value: string) => void` | Sets the value of the component. | | `setDisabled(disabled: boolean) => void` | Adds/removes disabled class, and sets disabled attribute on the component. | | `setSelectedIndex(selectedIndex: number) => void` | Sets the selected index of the component. | diff --git a/packages/mdc-select/_mixins.scss b/packages/mdc-select/_mixins.scss index b789c6f1c37..29798d60335 100644 --- a/packages/mdc-select/_mixins.scss +++ b/packages/mdc-select/_mixins.scss @@ -17,6 +17,7 @@ @import "@material/floating-label/mixins"; @import "@material/theme/mixins"; @import "@material/line-ripple/mixins"; +@import "@material/notched-outline/mixins"; // Public @@ -64,6 +65,24 @@ } } +@mixin mdc-select-outline-color($color) { + &:not(.mdc-select--disabled) { + @include mdc-select-outline-color_($color); + } +} + +@mixin mdc-select-hover-outline-color($color) { + &:not(.mdc-select--disabled) { + @include mdc-select-hover-outline-color_($color); + } +} + +@mixin mdc-select-focused-outline-color($color) { + &:not(.mdc-select--disabled) { + @include mdc-select-focused-outline-color_($color); + } +} + // Private @mixin mdc-select-focused-line-ripple_ { .mdc-select__native-control:focus ~ .mdc-line-ripple { @@ -71,6 +90,13 @@ } } +@mixin mdc-select-focused-outline_ { + .mdc-select__native-control:focus ~ .mdc-notched-outline { + @include mdc-notched-outline-stroke-width(2px); + @content; + } +} + @mixin mdc-select-ink-color_($color) { .mdc-select__native-control { @include mdc-theme-prop(color, $color); @@ -100,3 +126,43 @@ @mixin mdc-select-dd-arrow-svg-bg_($fill-hex-number: 000000, $opacity: .54) { background-image: url("data:image/svg+xml,%3Csvg%20width%3D%2210px%22%20height%3D%225px%22%20viewBox%3D%227%2010%2010%205%22%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%3E%0A%20%20%20%20%3Cpolygon%20id%3D%22Shape%22%20stroke%3D%22none%22%20fill%3D%22%23#{$fill-hex-number}%22%20fill-rule%3D%22evenodd%22%20opacity%3D%22#{$opacity}%22%20points%3D%227%2010%2012%2015%2017%2010%22%3E%3C%2Fpolygon%3E%0A%3C%2Fsvg%3E"); } + +@mixin mdc-select-outline-corner-radius($radius) { + // NOTE: idle and notched state border radius mixins + // are broken into 2 different mixins, otherwise + // we would be overly specific (big no, no). The cause of + // this is because .mdc-notched-outline and .mdc-notched-outline__idle + // are siblings. .mdc-notched-outline__idle needs to be a child of + // .mdc-notched-outline in order to remedy this issue. + .mdc-notched-outline { + @include mdc-notched-outline-corner-radius($radius); + } + + @include mdc-notched-outline-idle-corner-radius($radius); +} + +@mixin mdc-select-outline-color_($color) { + // NOTE: outlined version of select wants the "idle" and + // "notched" outline to have the same color. This covers two cases: + // 1) text field renders with NO value in the "idle" state + // 2) text field renders with a value in the "notched" state + @include mdc-notched-outline-idle-color($color); + @include mdc-notched-outline-color($color); +} + +@mixin mdc-select-hover-outline-color_($color) { + &:not(.mdc-select__native-control:focus) .mdc-select__native-control:hover ~ { + @include mdc-notched-outline-idle-color($color); + + // stylelint-disable-next-line selector-max-specificity + .mdc-notched-outline { + @include mdc-notched-outline-color($color); + } + } +} + +@mixin mdc-select-focused-outline-color_($color) { + @include mdc-select-focused-outline_ { + @include mdc-notched-outline-color($color); + } +} diff --git a/packages/mdc-select/_variables.scss b/packages/mdc-select/_variables.scss index 1101a7ae346..d2bda4f4ea5 100644 --- a/packages/mdc-select/_variables.scss +++ b/packages/mdc-select/_variables.scss @@ -18,6 +18,7 @@ $mdc-select-arrow-padding: 26px; $mdc-select-label-padding: 16px; +$mdc-select-border-radius: 4px; $mdc-select-ink-color: rgba(mdc-theme-prop-value(on-surface), .87); $mdc-select-disabled-ink-color: rgba(mdc-theme-prop-value(on-surface), .37); @@ -32,3 +33,12 @@ $mdc-select-bottom-line-hover-color: rgba(mdc-theme-prop-value(on-surface), .87) $mdc-select-box-fill-color: mix(mdc-theme-prop-value(on-surface), mdc-theme-prop-value(surface), 4%); $mdc-select-box-disabled-fill-color: mix(mdc-theme-prop-value(on-surface), mdc-theme-prop-value(surface), 2%); + +$mdc-select-outlined-idle-border: rgba(mdc-theme-prop-value(on-surface), .24); + +// should be .06 after mdc-select opacity is applied +$mdc-select-outlined-disabled-border: rgba(mdc-theme-prop-value(on-surface), .16); +$mdc-select-outlined-hover-border: rgba(mdc-theme-prop-value(on-surface), .87); + +$mdc-select-outlined-label-position-y: 130%; +$mdc-select-outlined-dense-label-position-y: 110%; diff --git a/packages/mdc-select/constants.js b/packages/mdc-select/constants.js index 8a4fd6e0d9a..36d42b64a17 100644 --- a/packages/mdc-select/constants.js +++ b/packages/mdc-select/constants.js @@ -13,15 +13,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export const cssClasses = { +const cssClasses = { BOX: 'mdc-select--box', DISABLED: 'mdc-select--disabled', ROOT: 'mdc-select', + OUTLINED: 'mdc-select--outlined', }; -export const strings = { +const strings = { CHANGE_EVENT: 'MDCSelect:change', LINE_RIPPLE_SELECTOR: '.mdc-line-ripple', LABEL_SELECTOR: '.mdc-floating-label', NATIVE_CONTROL_SELECTOR: '.mdc-select__native-control', + OUTLINE_SELECTOR: '.mdc-notched-outline', }; + +/** @enum {number} */ +const numbers = { + LABEL_SCALE: 0.75, +}; + +export {cssClasses, strings, numbers}; diff --git a/packages/mdc-select/foundation.js b/packages/mdc-select/foundation.js index 1400e6a50dd..3b8f2a2209a 100644 --- a/packages/mdc-select/foundation.js +++ b/packages/mdc-select/foundation.js @@ -15,13 +15,17 @@ */ import {MDCFoundation} from '@material/base/index'; -import {cssClasses, strings} from './constants'; +import {cssClasses, strings, numbers} from './constants'; export default class MDCSelectFoundation extends MDCFoundation { static get cssClasses() { return cssClasses; } + static get numbers() { + return numbers; + } + static get strings() { return strings; } @@ -30,6 +34,7 @@ export default class MDCSelectFoundation extends MDCFoundation { return { addClass: (/* className: string */) => {}, removeClass: (/* className: string */) => {}, + hasClass: (/* className: string */) => false, floatLabel: (/* value: boolean */) => {}, activateBottomLine: () => {}, deactivateBottomLine: () => {}, @@ -40,6 +45,12 @@ export default class MDCSelectFoundation extends MDCFoundation { setDisabled: (/* disabled: boolean */) => {}, getValue: () => /* string */ '', setValue: (/* value: string */) => {}, + isRtl: () => false, + hasLabel: () => {}, + getLabelWidth: () => {}, + hasOutline: () => {}, + notchOutline: () => {}, + closeOutline: () => {}, }; } @@ -86,10 +97,12 @@ export default class MDCSelectFoundation extends MDCFoundation { floatLabelWithValue_() { const optionHasValue = this.adapter_.getValue().length > 0; this.adapter_.floatLabel(optionHasValue); + this.notchOutline(optionHasValue); } handleFocus_() { this.adapter_.floatLabel(true); + this.notchOutline(true); this.adapter_.activateBottomLine(); } @@ -101,4 +114,23 @@ export default class MDCSelectFoundation extends MDCFoundation { handleSelect_() { this.setSelectedIndex(this.adapter_.getSelectedIndex()); } + + /** + * Opens/closes the notched outline. + * @param {boolean} openNotch + */ + notchOutline(openNotch) { + if (!this.adapter_.hasOutline() || !this.adapter_.hasLabel()) { + return; + } + + if (openNotch) { + const labelScale = numbers.LABEL_SCALE; + const labelWidth = this.adapter_.getLabelWidth() * labelScale; + const isRtl = this.adapter_.isRtl(); + this.adapter_.notchOutline(labelWidth, isRtl); + } else { + this.adapter_.closeOutline(); + } + } } diff --git a/packages/mdc-select/index.js b/packages/mdc-select/index.js index d730b4af03a..92191db0c17 100644 --- a/packages/mdc-select/index.js +++ b/packages/mdc-select/index.js @@ -18,6 +18,7 @@ import {MDCComponent} from '@material/base/index'; import {MDCFloatingLabel} from '@material/floating-label/index'; import {MDCLineRipple} from '@material/line-ripple/index'; import {MDCRipple, MDCRippleFoundation} from '@material/ripple/index'; +import {MDCNotchedOutline} from '@material/notched-outline/index'; import MDCSelectFoundation from './foundation'; import {cssClasses, strings} from './constants'; @@ -53,9 +54,18 @@ export class MDCSelect extends MDCComponent { this.foundation_.setDisabled(disabled); } + /** + * Recomputes the outline SVG path for the outline element. + */ + layout() { + const openNotch = this.nativeControl_.value.length > 0; + this.foundation_.notchOutline(openNotch); + } + initialize( labelFactory = (el) => new MDCFloatingLabel(el), - lineRippleFactory = (el) => new MDCLineRipple(el)) { + lineRippleFactory = (el) => new MDCLineRipple(el), + outlineFactory = (el) => new MDCNotchedOutline(el)) { this.nativeControl_ = this.root_.querySelector(strings.NATIVE_CONTROL_SELECTOR); const labelElement = this.root_.querySelector(strings.LABEL_SELECTOR); if (labelElement) { @@ -65,6 +75,10 @@ export class MDCSelect extends MDCComponent { if (lineRippleElement) { this.lineRipple_ = lineRippleFactory(lineRippleElement); } + const outlineElement = this.root_.querySelector(strings.OUTLINE_SELECTOR); + if (outlineElement) { + this.outline_ = outlineFactory(outlineElement); + } if (this.root_.classList.contains(cssClasses.BOX)) { this.ripple = this.initRipple_(); @@ -81,14 +95,10 @@ export class MDCSelect extends MDCComponent { } getDefaultFoundation() { - return new MDCSelectFoundation({ + return new MDCSelectFoundation((Object.assign({ addClass: (className) => this.root_.classList.add(className), removeClass: (className) => this.root_.classList.remove(className), - floatLabel: (value) => { - if (this.label_) { - this.label_.float(value); - } - }, + hasClass: (className) => this.root_.classList.contains(className), activateBottomLine: () => { if (this.lineRipple_) { this.lineRipple_.activate(); @@ -106,7 +116,11 @@ export class MDCSelect extends MDCComponent { setSelectedIndex: (index) => this.nativeControl_.selectedIndex = index, getValue: () => this.nativeControl_.value, setValue: (value) => this.nativeControl_.value = value, - }); + isRtl: () => window.getComputedStyle(this.root_).getPropertyValue('direction') === 'rtl', + }, + this.getOutlineAdapterMethods_(), + this.getLabelAdapterMethods_())) + ); } initialSyncWithDOM() { @@ -122,6 +136,54 @@ export class MDCSelect extends MDCComponent { if (this.ripple) { this.ripple.destroy(); } + if (this.outline_) { + this.outline_.destroy(); + } super.destroy(); } + + /** + * @return {!{ + * notchOutline: function(number, boolean): undefined, + * hasOutline: function(): boolean, + * }} + */ + getOutlineAdapterMethods_() { + return { + notchOutline: (labelWidth, isRtl) => { + if (this.outline_) { + this.outline_.notch(labelWidth, isRtl); + } + }, + closeOutline: () => { + if (this.outline_) { + this.outline_.closeNotch(); + } + }, + hasOutline: () => !!this.outline_, + }; + } + + /** + * @return {!{ + * floatLabel: function(boolean): undefined, + * hasLabel: function(): boolean, + * getLabelWidth: function(): number, + * }} + */ + getLabelAdapterMethods_() { + return { + floatLabel: (shouldFloat) => { + if (this.label_) { + this.label_.float(shouldFloat); + } + }, + hasLabel: () => !!this.label_, + getLabelWidth: () => { + if (this.label_) { + return this.label_.getWidth(); + } + }, + }; + } } diff --git a/packages/mdc-select/mdc-select.scss b/packages/mdc-select/mdc-select.scss index 12983cc6b18..1a0d5bac325 100644 --- a/packages/mdc-select/mdc-select.scss +++ b/packages/mdc-select/mdc-select.scss @@ -19,6 +19,7 @@ @import "./variables"; @import "@material/animation/variables"; @import "@material/line-ripple/mdc-line-ripple"; +@import "@material/notched-outline/mdc-notched-outline"; @import "@material/floating-label/mdc-floating-label"; @import "@material/typography/mixins"; @import "@material/ripple/common"; @@ -46,7 +47,6 @@ height: 52px; background-repeat: no-repeat; background-position: right 8px bottom 12px; - overflow: hidden; @include mdc-rtl { background-position: left 8px bottom 12px; @@ -106,6 +106,7 @@ height: 56px; border-radius: 4px 4px 0 0; background-position: right 10px center; + overflow: hidden; @include mdc-rtl { background-position: left 10px center; @@ -132,12 +133,44 @@ // stylelint-enable plugin/selector-bem-pattern } -.mdc-select--disabled { - @include mdc-select-dd-arrow-svg-bg_($mdc-select-disabled-arrow-color); +.mdc-select--outlined { + @include mdc-select-outline-color($mdc-select-outlined-idle-border); + @include mdc-select-hover-outline-color($mdc-select-outlined-hover-border); + @include mdc-select-focused-outline-color(primary); + @include mdc-floating-label-float-position($mdc-select-outlined-label-position-y); + @include mdc-floating-label-shake-animation(text-field-outlined); + @include mdc-select-outline-corner-radius($mdc-select-border-radius); - &.mdc-select--box { - @include mdc-select-container-fill-color_($mdc-select-box-disabled-fill-color); + height: 56px; + border: none; + background-position: right 10px center; + + @include mdc-rtl { + background-position: left 10px center; + } + + .mdc-select__native-control { + @include mdc-rtl-reflexive-property(padding, $mdc-select-label-padding, $mdc-select-arrow-padding); + + display: flex; + padding-top: 12px; + padding-bottom: 12px; + border: none; + background-color: transparent; + z-index: 1; + } + + // stylelint-disable-next-line plugin/selector-bem-pattern + .mdc-floating-label { + @include mdc-rtl-reflexive-position(left, 16px); + + position: absolute; + bottom: 20px; } +} + +.mdc-select--disabled { + @include mdc-select-dd-arrow-svg-bg_($mdc-select-disabled-arrow-color); .mdc-floating-label { @include mdc-floating-label-ink-color($mdc-select-disabled-label-color); @@ -147,11 +180,24 @@ .mdc-line-ripple { display: none; } - // stylelint-enable plugin/selector-bem-pattern .mdc-select__native-control { border-bottom-style: dotted; } + // stylelint-enable plugin/selector-bem-pattern + + &.mdc-select--box { + @include mdc-select-container-fill-color_($mdc-select-box-disabled-fill-color); + } + + &.mdc-select--outlined { + // stylelint-disable-next-line plugin/selector-bem-pattern + .mdc-select__native-control { + border-bottom-style: none; + } + + @include mdc-select-outline-color_($mdc-select-outlined-disabled-border); + } opacity: .38; cursor: default; diff --git a/packages/mdc-select/package.json b/packages/mdc-select/package.json index f8631bff087..020572898a0 100644 --- a/packages/mdc-select/package.json +++ b/packages/mdc-select/package.json @@ -19,6 +19,7 @@ "@material/base": "^0.35.0", "@material/floating-label": "^0.36.0", "@material/line-ripple": "^0.35.0", + "@material/notched-outline": "^0.35.0", "@material/ripple": "^0.36.0", "@material/rtl": "^0.36.0", "@material/theme": "^0.35.0", diff --git a/test/unit/mdc-select/foundation.test.js b/test/unit/mdc-select/foundation.test.js index 0c52d674154..06a1189878a 100644 --- a/test/unit/mdc-select/foundation.test.js +++ b/test/unit/mdc-select/foundation.test.js @@ -21,7 +21,7 @@ import {setupFoundationTest} from '../helpers/setup'; import {verifyDefaultAdapter} from '../helpers/foundation'; import MDCSelectFoundation from '../../../packages/mdc-select/foundation'; -import {cssClasses, strings} from '../../../packages/mdc-select/constants'; +import {cssClasses, strings, numbers} from '../../../packages/mdc-select/constants'; suite('MDCSelectFoundation'); @@ -29,16 +29,21 @@ test('exports cssClasses', () => { assert.deepEqual(MDCSelectFoundation.cssClasses, cssClasses); }); +test('exports numbers', () => { + assert.deepEqual(MDCSelectFoundation.numbers, numbers); +}); + test('exports strings', () => { assert.deepEqual(MDCSelectFoundation.strings, strings); }); test('default adapter returns a complete adapter implementation', () => { verifyDefaultAdapter(MDCSelectFoundation, [ - 'addClass', 'removeClass', 'floatLabel', 'activateBottomLine', - 'deactivateBottomLine', 'setDisabled', - 'registerInteractionHandler', 'deregisterInteractionHandler', - 'getValue', 'setValue', 'getSelectedIndex', 'setSelectedIndex', + 'addClass', 'removeClass', 'hasClass', 'floatLabel', 'activateBottomLine', + 'deactivateBottomLine', 'setDisabled', 'registerInteractionHandler', + 'deregisterInteractionHandler', 'getValue', 'setValue', 'getSelectedIndex', + 'setSelectedIndex', 'isRtl', 'hasLabel', 'getLabelWidth', 'hasOutline', + 'notchOutline', 'closeOutline', ]); }); @@ -113,3 +118,42 @@ test('#setValue calls setSelectedIndex, which calls floatLabel true', () => { foundation.setValue('value'); td.verify(mockAdapter.floatLabel(true)); }); + +test('#notchOutline updates the SVG path of the outline element', () => { + const {foundation, mockAdapter} = setupTest(); + td.when(mockAdapter.getLabelWidth()).thenReturn(30); + td.when(mockAdapter.hasLabel()).thenReturn(true); + td.when(mockAdapter.hasOutline()).thenReturn(true); + td.when(mockAdapter.isRtl()).thenReturn(false); + + foundation.notchOutline(true); + td.verify(mockAdapter.notchOutline(30 * numbers.LABEL_SCALE, false)); +}); + +test('#notchOutline does nothing if no outline is present', () => { + const {foundation, mockAdapter} = setupTest(); + td.when(mockAdapter.hasOutline()).thenReturn(false); + td.when(mockAdapter.hasLabel()).thenReturn(true); + + foundation.notchOutline(true); + td.verify(mockAdapter.notchOutline(td.matchers.anything()), {times: 0}); +}); + +test('#notchOutline does nothing if no label is present', () => { + const {foundation, mockAdapter} = setupTest(); + td.when(mockAdapter.hasOutline()).thenReturn(true); + td.when(mockAdapter.hasLabel()).thenReturn(false); + + foundation.notchOutline(true); + td.verify(mockAdapter.notchOutline(td.matchers.anything()), {times: 0}); +}); + +test('#notchOutline calls updates notched outline to return to idle state when ' + + 'openNotch is false', () => { + const {foundation, mockAdapter} = setupTest(); + td.when(mockAdapter.hasLabel()).thenReturn(true); + td.when(mockAdapter.hasOutline()).thenReturn(true); + + foundation.notchOutline(false); + td.verify(mockAdapter.closeOutline()); +}); diff --git a/test/unit/mdc-select/mdc-select.test.js b/test/unit/mdc-select/mdc-select.test.js index e1ae7e54595..69d95c53a36 100644 --- a/test/unit/mdc-select/mdc-select.test.js +++ b/test/unit/mdc-select/mdc-select.test.js @@ -24,6 +24,7 @@ import {supportsCssVariables} from '../../../packages/mdc-ripple/util'; import {MDCRipple, MDCRippleFoundation} from '../../../packages/mdc-ripple'; import {MDCSelect} from '../../../packages/mdc-select'; import {cssClasses} from '../../../packages/mdc-select/constants'; +import {MDCNotchedOutline} from '../../../packages/mdc-notched-outline'; class FakeLabel { constructor() { @@ -38,6 +39,12 @@ class FakeBottomLine { } } +class FakeOutline { + constructor() { + this.destroy = td.func('.destroy'); + } +} + function getFixture() { return bel`
@@ -86,9 +93,10 @@ function setupTest() { const nativeControl = fixture.querySelector('.mdc-select__native-control'); const labelEl = fixture.querySelector('.mdc-floating-label'); const bottomLineEl = fixture.querySelector('.mdc-line-ripple'); - const component = new MDCSelect(fixture, /* foundation */ undefined, () => label, () => bottomLine); + const outline = new FakeOutline(); + const component = new MDCSelect(fixture, /* foundation */ undefined, () => label, () => bottomLine, () => outline); - return {fixture, nativeControl, label, labelEl, bottomLine, bottomLineEl, component}; + return {fixture, nativeControl, label, labelEl, bottomLine, bottomLineEl, component, outline}; } test('#get/setSelectedIndex', () => { @@ -171,6 +179,12 @@ test('adapter#removeClass removes a class from the root element', () => { assert.isFalse(fixture.classList.contains('foo')); }); +test('adapter#hasClass returns true if a class exists on the root element', () => { + const {component, fixture} = setupTest(); + fixture.classList.add('foo'); + assert.isTrue(component.getDefaultFoundation().adapter_.hasClass('foo')); +}); + test('adapter_.floatLabel does not throw error if label does not exist', () => { const fixture = bel`
@@ -212,6 +226,20 @@ test('adapter.activateBottomLine and adapter.deactivateBottomLine ' + () => component.getDefaultFoundation().adapter_.deactivateBottomLine()); }); + +test('#adapter.isRtl returns true when the root element is in an RTL context' + + 'and false otherwise', () => { + const wrapper = bel`
`; + const {fixture, component} = setupTest(); + assert.isFalse(component.getDefaultFoundation().adapter_.isRtl()); + + wrapper.appendChild(fixture); + document.body.appendChild(wrapper); + assert.isTrue(component.getDefaultFoundation().adapter_.isRtl()); + + document.body.removeChild(wrapper); +}); + test(`instantiates ripple when ${cssClasses.BOX} class is present`, function() { if (!supportsCssVariables(window, true)) { this.skip(); // eslint-disable-line no-invalid-this @@ -229,6 +257,13 @@ test(`instantiates ripple when ${cssClasses.BOX} class is present`, function() { raf.restore(); }); +test(`#constructor instantiates an outline on the ${cssClasses.OUTLINE_SELECTOR} element if present`, () => { + const root = getFixture(); + root.appendChild(bel`
`); + const component = new MDCSelect(root); + assert.instanceOf(component.outline_, MDCNotchedOutline); +}); + test(`handles ripple focus properly when ${cssClasses.BOX} class is present`, function() { if (!supportsCssVariables(window, true)) { this.skip(); // eslint-disable-line no-invalid-this @@ -270,6 +305,13 @@ test('#destroy removes the ripple', function() { raf.restore(); }); +test('#destroy cleans up the outline if present', () => { + const {component, outline} = setupTest(); + component.outline_ = outline; + component.destroy(); + td.verify(outline.destroy()); +}); + test(`does not instantiate ripple when ${cssClasses.BOX} class is not present`, () => { const {component} = setupTest(); assert.isUndefined(component.ripple); From 55909135180b01f5eea74e8848d62b97202ecee8 Mon Sep 17 00:00:00 2001 From: Will Ernest <34519388+williamernest@users.noreply.github.com> Date: Tue, 5 Jun 2018 14:29:27 -0700 Subject: [PATCH 039/175] docs(list): Remove checkbox list demo (#2883) --- demos/list.html | 159 ----------------------- packages/mdc-elevation/package-lock.json | 11 ++ 2 files changed, 11 insertions(+), 159 deletions(-) create mode 100644 packages/mdc-elevation/package-lock.json diff --git a/demos/list.html b/demos/list.html index 2e42b214f51..1d58f55ab87 100644 --- a/demos/list.html +++ b/demos/list.html @@ -273,71 +273,6 @@

Graphic Example - Icon with Text

-
-

Leading Checkbox

-
    -
  • - -
    - -
    - - - -
    -
    -
    -
    - -
  • -
  • - -
    - -
    - - - -
    -
    -
    -
    - -
  • -
  • - -
    - -
    - - - -
    -
    -
    -
    - -
  • -
-

Avatar List

    @@ -429,70 +364,6 @@

    Metadata (Dense)

-
-

Trailing Checkbox

-
    -
  • - - -
    - -
    - - - -
    -
    -
    -
    -
  • -
  • - - -
    - -
    - - - -
    -
    -
    -
    -
  • -
  • - - -
    - -
    - - - -
    -
    -
    -
    -
  • -
-

Avatar + Metadata

    @@ -1058,15 +929,6 @@

    Example - Interactive List

    diff --git a/packages/mdc-elevation/package-lock.json b/packages/mdc-elevation/package-lock.json new file mode 100644 index 00000000000..89903b4dece --- /dev/null +++ b/packages/mdc-elevation/package-lock.json @@ -0,0 +1,11 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@material/theme": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@material/theme/-/theme-0.4.0.tgz", + "integrity": "sha1-Cu8aAnm2XBWZBYT7i47KCVxzRkE=" + } + } +} From 0708a2df707df4fe38d383494d34baa7f9ee7e92 Mon Sep 17 00:00:00 2001 From: "Kenneth G. Franqueiro" Date: Wed, 6 Jun 2018 11:15:10 -0400 Subject: [PATCH 040/175] docs: Add triage links for other repos (#2889) --- docs/open_source/triage.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/open_source/triage.md b/docs/open_source/triage.md index c728e280d59..0b24a2dec75 100644 --- a/docs/open_source/triage.md +++ b/docs/open_source/triage.md @@ -1,6 +1,9 @@ # Triage Process -Start with [untriaged issues](https://github.com/material-components/material-components-web/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20-label%3Ain-tracker%20-label%3A%22help%20wanted%22%20no%3Aassignee%20sort%3Acreated-asc%20) +* [MDC Web Untriaged Issues](https://github.com/material-components/material-components-web/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20-label%3Ain-tracker%20-label%3A%22help%20wanted%22%20no%3Aassignee%20sort%3Acreated-asc%20) +* [MDC React Untriaged Issues](https://github.com/material-components/material-components-web-react/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20-label%3Ain-tracker%20-label%3A%22help%20wanted%22%20no%3Aassignee%20sort%3Acreated-asc%20) +* [MDC Catalog Untriaged Issues](https://github.com/material-components/material-components-web-catalog/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20-label%3Ain-tracker%20-label%3A%22help%20wanted%22%20no%3Aassignee%20sort%3Acreated-asc%20) +* [MDC Web Codelabs Untriaged Issues](https://github.com/material-components/material-components-web-codelabs/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20-label%3Ain-tracker%20-label%3A%22help%20wanted%22%20no%3Aassignee%20sort%3Acreated-asc%20) ### Installation Problems From 3de2d408e6f7441816d972b2cf395023887bbfd6 Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" Date: Wed, 6 Jun 2018 09:59:38 -0700 Subject: [PATCH 041/175] =?UTF-8?q?chore(package):=20Update=20recast=20to?= =?UTF-8?q?=20the=20latest=20version=20=F0=9F=9A=80=20(#2862)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 14 +++++++------- package.json | 2 +- .../rewrite-decl-statements-for-closure-test.js | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 15636c9e1d2..2aec946cf90 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13385,21 +13385,21 @@ } }, "recast": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.14.2.tgz", - "integrity": "sha512-zjZWtNLsa8VHoHYUkXP2GAui5gaIs98C5ujo4v9QX+q+GcQ7CvRe/rf8fP6yytEMUpi1eFYbIpX6QqggwPXz9w==", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.15.0.tgz", + "integrity": "sha512-47C2mIxQYvFICrTNuV4+xGgBa1nAoq42ANN5oDTSBIJ50NX7jcki7gAC6HWYptnQgHmqIRTHJq8OKdi3fwgyNQ==", "dev": true, "requires": { - "ast-types": "0.11.1", + "ast-types": "0.11.5", "esprima": "~4.0.0", "private": "~0.1.5", "source-map": "~0.6.1" }, "dependencies": { "ast-types": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.11.1.tgz", - "integrity": "sha512-BAlXqqeEhVEajhgz7rgerupI8sb695KpCaJ/w4Sb9s2LoUci8sSMhXw93Jp8MsOufWGJOY/P2jpUEVw4RlSzNw==", + "version": "0.11.5", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.11.5.tgz", + "integrity": "sha512-oJjo+5e7/vEc2FBK8gUalV0pba4L3VdBIs2EKhOLHLcOd2FgQIVQN9xb0eZ9IjEWyAL7vq6fGJxOvVvdCHNyMw==", "dev": true }, "esprima": { diff --git a/package.json b/package.json index 19b26b48b71..8c94db81210 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,7 @@ "postcss-loader": "^2.0.3", "ps-node": "^0.1.6", "query-ast": "^1.0.1", - "recast": "^0.14.0", + "recast": "^0.15.0", "request-promise-native": "^1.0.5", "resemblejs": "^2.10.1", "resolve": "^1.3.2", diff --git a/scripts/rewrite-decl-statements-for-closure-test.js b/scripts/rewrite-decl-statements-for-closure-test.js index 39b0b9bd898..897b6f16bb1 100644 --- a/scripts/rewrite-decl-statements-for-closure-test.js +++ b/scripts/rewrite-decl-statements-for-closure-test.js @@ -212,7 +212,7 @@ function transform(srcFile, rootDir) { // Specify goog.module after the @license comment and append newline at the end of the file. const pos = outputCode.indexOf(' */') + 3; - outputCode = outputCode.substr(0, pos) + '\ngoog.module(\'' + packageStr + '\');\n' + outputCode.substr(pos) + '\n'; + outputCode = outputCode.substr(0, pos) + '\ngoog.module(\'' + packageStr + '\');\n' + outputCode.substr(pos); fs.writeFileSync(srcFile, outputCode, 'utf8'); logProgress(`[rewrite] ${srcFile}`); } From 7c06e9f527f8b9efe38e55d2ce9eb78d9595b6f7 Mon Sep 17 00:00:00 2001 From: Will Ernest <34519388+williamernest@users.noreply.github.com> Date: Wed, 6 Jun 2018 11:31:43 -0700 Subject: [PATCH 042/175] feat(list): Add arrow key a11y support. (#2871) Add accessibility support for using arrow keys to navigate the list. --- demos/list.html | 154 +++++---- package.json | 1 + packages/material-components-web/index.js | 3 + packages/mdc-list/README.md | 143 +++++--- packages/mdc-list/adapter.js | 59 ++++ packages/mdc-list/constants.js | 31 ++ packages/mdc-list/foundation.js | 202 +++++++++++ packages/mdc-list/index.js | 106 ++++++ packages/mdc-list/package.json | 1 + test/unit/mdc-list/foundation.test.js | 389 ++++++++++++++++++++++ test/unit/mdc-list/mdc-list.test.js | 133 ++++++++ 11 files changed, 1112 insertions(+), 110 deletions(-) create mode 100644 packages/mdc-list/adapter.js create mode 100644 packages/mdc-list/constants.js create mode 100644 packages/mdc-list/foundation.js create mode 100644 packages/mdc-list/index.js create mode 100644 test/unit/mdc-list/foundation.test.js create mode 100644 test/unit/mdc-list/mdc-list.test.js diff --git a/demos/list.html b/demos/list.html index 1d58f55ab87..e4cab90794c 100644 --- a/demos/list.html +++ b/demos/list.html @@ -38,8 +38,8 @@
    -
      -
    • +
        +
      • @@ -118,8 +118,9 @@

        Custom Colors

        Example - Two-Line Lists, Avatars, Metadata, Inset Dividers

        Folders

        -
          -
        • +
            +
          • @@ -164,8 +165,9 @@

            Folders


          Files

          -
            -
          • +
              +
            • @@ -209,8 +211,9 @@

              Text only, non-interactive (no states)

    Text only (dense)

    -
      -
    • Single-line item
    • +
        +
      • Single-line item
      • Single-line item
      • Single-line item
      @@ -218,8 +221,9 @@

      Text only (dense)

      Graphic

      -
        -
      • +
          +
        • Single-line item
        • @@ -235,8 +239,9 @@

          Graphic

      Graphic (dense)

      -
        -
      • +
          +
        • Single-line item
        • @@ -252,8 +257,9 @@

          Graphic (dense)

      Graphic Example - Icon with Text

      -
        -
      • +
          +
        • @@ -275,8 +281,9 @@

          Graphic Example - Icon with Text

      Avatar List

      -
        -
      • +
          +
        • Single-line item
        • @@ -292,8 +299,9 @@

          Avatar List

      Avatar List (dense)

      -
        -
      • +
          +
        • Single-line item
        • @@ -309,8 +317,9 @@

          Avatar List (dense)

      Example - Avatar with Text

      -
        -
      • +
          +
        • Panda @@ -332,8 +341,9 @@

          Example - Avatar with Text

      Metadata

      -
        -
      • +
          +
        • Single-line item $10.00
        • @@ -349,8 +359,9 @@

          Metadata

      Metadata (Dense)

      -
        -
      • +
          +
        • Single-line item $10.00
        • @@ -366,8 +377,9 @@

          Metadata (Dense)

      Avatar + Metadata

      -
        -
      • +
          +
        • Single-line item $10.00 @@ -386,8 +398,9 @@

          Avatar + Metadata

      Avatar + Metadata (Dense)

      -
        -
      • +
          +
        • Single-line item $10.00 @@ -406,8 +419,9 @@

          Avatar + Metadata (Dense)

      Example - Avatar with Text and Icon

      -
        -
      • +
          +
        • Brown Bear @@ -447,8 +461,9 @@

          Example - Avatar with Text and Icon

          Two-Line List

          Text-Only

          -
            -
          • +
              +
            • Two-line item Secondary text @@ -470,8 +485,9 @@

              Text-Only

          Text-Only (Dense)

          -
            -
          • +
              +
            • Two-line item Secondary text @@ -493,8 +509,9 @@

              Text-Only (Dense)

          Graphic

          -
            -
          • +
              +
            • Two-line item @@ -519,8 +536,9 @@

              Graphic

          Graphic (Dense)

          -
            -
          • +
              +
            • Two-line item @@ -545,8 +563,9 @@

              Graphic (Dense)

          Avatar List

          -
            -
          • +
              +
            • Two-line item @@ -571,8 +590,9 @@

              Avatar List

          Avatar List (dense)

          -
            -
          • +
              +
            • Two-line item @@ -597,8 +617,9 @@

              Avatar List (dense)

          Metadata

          -
            -
          • +
              +
            • Two-line item Secondary text @@ -623,8 +644,9 @@

              Metadata

          Metadata (Dense)

          -
            -
          • +
              +
            • Two-line item Secondary text @@ -649,8 +671,9 @@

              Metadata (Dense)

          Example - Two-line Avatar + Text + Icon

          -
            -
          • +
              +
            • @@ -696,8 +719,9 @@

              Example - Two-line Avatar + Text + Icon

          Lists w/ Ellipsis

          -
            -
          • +
              +

Folders - Photos + Photos Jan 9, 2014 Folders - Recipes + Recipes Jan 17, 2014 Folders - Work + Work Jan 28, 2014 Files - Vacation Itinerary + Vacation Itinerary Jan 10, 2014 Files - Kitchen Remodel + Kitchen Remodel Jan 20, 2014 Text-Only aria-orientation="vertical">
  • - Two-line item + Two-line item Secondary text
  • - Two-line item + Two-line item Secondary text
  • - Two-line item + Two-line item Secondary text
  • @@ -620,19 +620,19 @@

    Text-Only (Dense)

    aria-orientation="vertical">
  • - Two-line item + Two-line item Secondary text
  • - Two-line item + Two-line item Secondary text
  • - Two-line item + Two-line item Secondary text
  • @@ -645,21 +645,21 @@

    Graphic

  • - Two-line item + Two-line item Secondary text
  • - Two-line item + Two-line item Secondary text
  • - Two-line item + Two-line item Secondary text
  • @@ -672,21 +672,21 @@

    Graphic (Dense)

  • - Two-line item + Two-line item Secondary text
  • - Two-line item + Two-line item Secondary text
  • - Two-line item + Two-line item Secondary text
  • @@ -699,21 +699,21 @@

    Avatar List

  • - Two-line item + Two-line item Secondary text
  • - Two-line item + Two-line item Secondary text
  • - Two-line item + Two-line item Secondary text
  • @@ -726,21 +726,21 @@

    Avatar List (dense)

  • - Two-line item + Two-line item Secondary text
  • - Two-line item + Two-line item Secondary text
  • - Two-line item + Two-line item Secondary text
  • @@ -752,21 +752,21 @@

    Metadata

    aria-orientation="vertical">
  • - Two-line item + Two-line item Secondary text $10.00
  • - Two-line item + Two-line item Secondary text $20.00
  • - Two-line item + Two-line item Secondary text $30.00 @@ -779,21 +779,21 @@

    Metadata (Dense)

    aria-orientation="vertical">
  • - Two-line item + Two-line item Secondary text $10.00
  • - Two-line item + Two-line item Secondary text $20.00
  • - Two-line item + Two-line item Secondary text $30.00 @@ -809,7 +809,7 @@

    Example - Two-line Avatar + Text + Icon

    - Photos + Photos Jan 9, 2014
    Example - Two-line Avatar + Text + Icon - Recipes + Recipes Jan 17, 2014 Example - Two-line Avatar + Text + Icon - Work + Work Jan 28, 2014 Lists w/ Ellipsis - Photos - - This is some secondary text - + Photos + This is some secondary text - Photos of my best photography using my finely tuned skills and eye - - This is some secondary text - + Photos of my best photography using my finely tuned skills and eye + This is some secondary text - Work Photos - - This is a description of work photos from the years 2018 to present time while I was a barista - + Work Photos + This is a description of work photos from the years 2018 to present time while I was a barista