From d9a1b8182f73789ef4b31ed662834d3b8e58a1e7 Mon Sep 17 00:00:00 2001 From: Andrew Seguin Date: Thu, 6 Jan 2022 01:52:20 +0000 Subject: [PATCH 01/17] fix(material-experimental/mdc-slider): keep value indicator within bounds (#24167) --- package.json | 96 +- .../mdc-slider/slider-thumb.html | 2 +- .../mdc-slider/slider.ts | 26 +- yarn.lock | 1234 ++++++++--------- 4 files changed, 691 insertions(+), 667 deletions(-) diff --git a/package.json b/package.json index dab9f845c8b3..b0c6d67d34f2 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "@types/google.maps": "^3.45.6", "@types/youtube": "^0.0.42", "core-js-bundle": "^3.8.2", - "material-components-web": "14.0.0-canary.7d8ea4624.0", + "material-components-web": "14.0.0-canary.c047f7c19.0", "rxjs": "^6.6.7", "rxjs-tslint-rules": "^4.33.1", "tslib": "^2.3.0", @@ -92,53 +92,53 @@ "@bazel/terser": "4.4.5", "@bazel/typescript": "4.4.5", "@firebase/app-types": "^0.6.1", - "@material/animation": "14.0.0-canary.7d8ea4624.0", - "@material/auto-init": "14.0.0-canary.7d8ea4624.0", - "@material/banner": "14.0.0-canary.7d8ea4624.0", - "@material/base": "14.0.0-canary.7d8ea4624.0", - "@material/button": "14.0.0-canary.7d8ea4624.0", - "@material/card": "14.0.0-canary.7d8ea4624.0", - "@material/checkbox": "14.0.0-canary.7d8ea4624.0", - "@material/chips": "14.0.0-canary.7d8ea4624.0", - "@material/circular-progress": "14.0.0-canary.7d8ea4624.0", - "@material/data-table": "14.0.0-canary.7d8ea4624.0", - "@material/density": "14.0.0-canary.7d8ea4624.0", - "@material/dialog": "14.0.0-canary.7d8ea4624.0", - "@material/dom": "14.0.0-canary.7d8ea4624.0", - "@material/drawer": "14.0.0-canary.7d8ea4624.0", - "@material/elevation": "14.0.0-canary.7d8ea4624.0", - "@material/fab": "14.0.0-canary.7d8ea4624.0", - "@material/feature-targeting": "14.0.0-canary.7d8ea4624.0", - "@material/floating-label": "14.0.0-canary.7d8ea4624.0", - "@material/form-field": "14.0.0-canary.7d8ea4624.0", - "@material/icon-button": "14.0.0-canary.7d8ea4624.0", - "@material/image-list": "14.0.0-canary.7d8ea4624.0", - "@material/layout-grid": "14.0.0-canary.7d8ea4624.0", - "@material/line-ripple": "14.0.0-canary.7d8ea4624.0", - "@material/linear-progress": "14.0.0-canary.7d8ea4624.0", - "@material/list": "14.0.0-canary.7d8ea4624.0", - "@material/menu": "14.0.0-canary.7d8ea4624.0", - "@material/menu-surface": "14.0.0-canary.7d8ea4624.0", - "@material/notched-outline": "14.0.0-canary.7d8ea4624.0", - "@material/radio": "14.0.0-canary.7d8ea4624.0", - "@material/ripple": "14.0.0-canary.7d8ea4624.0", - "@material/rtl": "14.0.0-canary.7d8ea4624.0", - "@material/segmented-button": "14.0.0-canary.7d8ea4624.0", - "@material/select": "14.0.0-canary.7d8ea4624.0", - "@material/shape": "14.0.0-canary.7d8ea4624.0", - "@material/slider": "14.0.0-canary.7d8ea4624.0", - "@material/snackbar": "14.0.0-canary.7d8ea4624.0", - "@material/switch": "14.0.0-canary.7d8ea4624.0", - "@material/tab": "14.0.0-canary.7d8ea4624.0", - "@material/tab-bar": "14.0.0-canary.7d8ea4624.0", - "@material/tab-indicator": "14.0.0-canary.7d8ea4624.0", - "@material/tab-scroller": "14.0.0-canary.7d8ea4624.0", - "@material/textfield": "14.0.0-canary.7d8ea4624.0", - "@material/theme": "14.0.0-canary.7d8ea4624.0", - "@material/tooltip": "14.0.0-canary.7d8ea4624.0", - "@material/top-app-bar": "14.0.0-canary.7d8ea4624.0", - "@material/touch-target": "14.0.0-canary.7d8ea4624.0", - "@material/typography": "14.0.0-canary.7d8ea4624.0", + "@material/animation": "14.0.0-canary.c047f7c19.0", + "@material/auto-init": "14.0.0-canary.c047f7c19.0", + "@material/banner": "14.0.0-canary.c047f7c19.0", + "@material/base": "14.0.0-canary.c047f7c19.0", + "@material/button": "14.0.0-canary.c047f7c19.0", + "@material/card": "14.0.0-canary.c047f7c19.0", + "@material/checkbox": "14.0.0-canary.c047f7c19.0", + "@material/chips": "14.0.0-canary.c047f7c19.0", + "@material/circular-progress": "14.0.0-canary.c047f7c19.0", + "@material/data-table": "14.0.0-canary.c047f7c19.0", + "@material/density": "14.0.0-canary.c047f7c19.0", + "@material/dialog": "14.0.0-canary.c047f7c19.0", + "@material/dom": "14.0.0-canary.c047f7c19.0", + "@material/drawer": "14.0.0-canary.c047f7c19.0", + "@material/elevation": "14.0.0-canary.c047f7c19.0", + "@material/fab": "14.0.0-canary.c047f7c19.0", + "@material/feature-targeting": "14.0.0-canary.c047f7c19.0", + "@material/floating-label": "14.0.0-canary.c047f7c19.0", + "@material/form-field": "14.0.0-canary.c047f7c19.0", + "@material/icon-button": "14.0.0-canary.c047f7c19.0", + "@material/image-list": "14.0.0-canary.c047f7c19.0", + "@material/layout-grid": "14.0.0-canary.c047f7c19.0", + "@material/line-ripple": "14.0.0-canary.c047f7c19.0", + "@material/linear-progress": "14.0.0-canary.c047f7c19.0", + "@material/list": "14.0.0-canary.c047f7c19.0", + "@material/menu": "14.0.0-canary.c047f7c19.0", + "@material/menu-surface": "14.0.0-canary.c047f7c19.0", + "@material/notched-outline": "14.0.0-canary.c047f7c19.0", + "@material/radio": "14.0.0-canary.c047f7c19.0", + "@material/ripple": "14.0.0-canary.c047f7c19.0", + "@material/rtl": "14.0.0-canary.c047f7c19.0", + "@material/segmented-button": "14.0.0-canary.c047f7c19.0", + "@material/select": "14.0.0-canary.c047f7c19.0", + "@material/shape": "14.0.0-canary.c047f7c19.0", + "@material/slider": "14.0.0-canary.c047f7c19.0", + "@material/snackbar": "14.0.0-canary.c047f7c19.0", + "@material/switch": "14.0.0-canary.c047f7c19.0", + "@material/tab": "14.0.0-canary.c047f7c19.0", + "@material/tab-bar": "14.0.0-canary.c047f7c19.0", + "@material/tab-indicator": "14.0.0-canary.c047f7c19.0", + "@material/tab-scroller": "14.0.0-canary.c047f7c19.0", + "@material/textfield": "14.0.0-canary.c047f7c19.0", + "@material/theme": "14.0.0-canary.c047f7c19.0", + "@material/tooltip": "14.0.0-canary.c047f7c19.0", + "@material/top-app-bar": "14.0.0-canary.c047f7c19.0", + "@material/touch-target": "14.0.0-canary.c047f7c19.0", + "@material/typography": "14.0.0-canary.c047f7c19.0", "@octokit/rest": "18.3.5", "@rollup/plugin-commonjs": "^21.0.0", "@rollup/plugin-node-resolve": "^13.0.5", diff --git a/src/material-experimental/mdc-slider/slider-thumb.html b/src/material-experimental/mdc-slider/slider-thumb.html index 69045f353dcf..44f82792fe6b 100644 --- a/src/material-experimental/mdc-slider/slider-thumb.html +++ b/src/material-experimental/mdc-slider/slider-thumb.html @@ -1,4 +1,4 @@ -
+
{{valueIndicatorText}}
diff --git a/src/material-experimental/mdc-slider/slider.ts b/src/material-experimental/mdc-slider/slider.ts index 8c3387c5246f..cd387ca9f8e2 100644 --- a/src/material-experimental/mdc-slider/slider.ts +++ b/src/material-experimental/mdc-slider/slider.ts @@ -104,9 +104,13 @@ export class MatSliderVisualThumb implements AfterViewInit, OnDestroy { /** The MatRipple for this slider thumb. */ @ViewChild(MatRipple) private readonly _ripple: MatRipple; - /** The slider thumb knob */ + /** The slider thumb knob. */ @ViewChild('knob') _knob: ElementRef; + /** The slider thumb value indicator container. */ + @ViewChild('valueIndicatorContainer') + _valueIndicatorContainer: ElementRef; + /** The slider input corresponding to this slider thumb. */ private _sliderInput: MatSliderThumb; @@ -261,6 +265,14 @@ export class MatSliderVisualThumb implements AfterViewInit, OnDestroy { _getKnob(): HTMLElement { return this._knob.nativeElement; } + + /** + * Gets the native HTML element of the slider thumb value indicator + * container. + */ + _getValueIndicatorContainer(): HTMLElement { + return this._valueIndicatorContainer.nativeElement; + } } /** @@ -868,6 +880,14 @@ export class MatSlider return this._getThumb(thumbPosition)._getKnob(); } + /** + * Gets the slider value indicator container HTML element of the given thumb + * position. + */ + _getValueIndicatorContainerElement(thumbPosition: Thumb): HTMLElement { + return this._getThumb(thumbPosition)._getValueIndicatorContainer(); + } + /** * Sets the value indicator text of the given thumb position using the given value. * @@ -1066,6 +1086,10 @@ class SliderAdapter implements MDCSliderAdapter { getBoundingClientRect = (): ClientRect => { return this._delegate._elementRef.nativeElement.getBoundingClientRect(); }; + getValueIndicatorContainerWidth = (thumbPosition: Thumb): number => { + return this._delegate._getValueIndicatorContainerElement(thumbPosition).getBoundingClientRect() + .width; + }; isRTL = (): boolean => { return this._delegate._isRTL(); }; diff --git a/yarn.lock b/yarn.lock index 833cfd3931a8..d617ba351be0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1900,681 +1900,681 @@ resolved "https://registry.yarnpkg.com/@jsdevtools/ono/-/ono-7.1.3.tgz#9df03bbd7c696a5c58885c34aa06da41c8543796" integrity sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg== -"@material/animation@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/animation/-/animation-14.0.0-canary.7d8ea4624.0.tgz#80a2fa3a03aa0740186d9886df107bc9e92332f2" - integrity sha512-WzlM2xJFOB9PUY3aAylJZ0KAgDbrSZRVvcNZQBAs2cgh16/T/jRUXLkb/bPfSvgWPB3wu+YTlrOcX1h28Sh1Hg== +"@material/animation@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/animation/-/animation-14.0.0-canary.c047f7c19.0.tgz#0c35f52418d1de1677015ae7d092a29e34632ed0" + integrity sha512-xArlxe2u94qyTm7+QG3A65sn0cERHEfNPtY5ViStXToe7mpBXsyCdsMTPZmXoxR5oH4ROFi3krG94XhbAtOXDg== dependencies: tslib "^2.1.0" -"@material/auto-init@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/auto-init/-/auto-init-14.0.0-canary.7d8ea4624.0.tgz#b664748ae0f360cfce0933526125899092e29a99" - integrity sha512-SoSDBCHgsb4qg1Z6X48kFlpvlaM46H+aa61bsXp25cc8ADehINHgsd3aKQU/UiSNZq/hCeFxyMFykKgeoVLyUw== +"@material/auto-init@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/auto-init/-/auto-init-14.0.0-canary.c047f7c19.0.tgz#91993367a6be8a56a253c98d234dbac53cfa87ab" + integrity sha512-2ImvG16VoDLtzQPw/dHp7k4l/rNwNalfwpmhQJMOw0waxQrBYEyHTM0LK4DROedk0iLsSz56f4BpCTekY1H5fg== dependencies: - "@material/base" "14.0.0-canary.7d8ea4624.0" + "@material/base" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/banner@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/banner/-/banner-14.0.0-canary.7d8ea4624.0.tgz#47225ab582f733fe1b370524e74ac50c566695ee" - integrity sha512-P4R2eyYpTalfOUJMZIAv3y4fJtCWryf8DNH+pu1iy9humDkQuCdeNqoBs+oOGJCGUegFnKB4Coyth306ooXkDg== - dependencies: - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/button" "14.0.0-canary.7d8ea4624.0" - "@material/dom" "14.0.0-canary.7d8ea4624.0" - "@material/elevation" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/ripple" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/shape" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" - "@material/tokens" "14.0.0-canary.7d8ea4624.0" - "@material/typography" "14.0.0-canary.7d8ea4624.0" +"@material/banner@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/banner/-/banner-14.0.0-canary.c047f7c19.0.tgz#53740c984fafa33985d56e3b954e5efef02215b0" + integrity sha512-3J2ayEe57wlBcfVLxHA5zxDWHrvaZaohm/sAU+0hpIv/X44zAyhbYLubpFR9DLVEhP+CcAESGBHgseHHFeEXdQ== + dependencies: + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/button" "14.0.0-canary.c047f7c19.0" + "@material/dom" "14.0.0-canary.c047f7c19.0" + "@material/elevation" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/ripple" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/shape" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" + "@material/tokens" "14.0.0-canary.c047f7c19.0" + "@material/typography" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/base@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/base/-/base-14.0.0-canary.7d8ea4624.0.tgz#abd195e988905a947be8da42f33828f37b4c2030" - integrity sha512-Fp5QPLoioHG4sgcGpShYJ7+29OWApDW70PBMmYnY9NCEyOBUbiuUDhA77QxCdb6kSpEIJklvWAQb+aAesTuQlA== +"@material/base@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/base/-/base-14.0.0-canary.c047f7c19.0.tgz#6ec606a3c59b02fc9265b0eefe7df99ceffe6740" + integrity sha512-9aPd4g+KlYLqJ64cnlkIPdzI/NaRFzK8Zj/QY/HJyizRuFsb7JA9kRSdWUouJFIH3HOouETxliTFd6nl9gJZug== dependencies: tslib "^2.1.0" -"@material/button@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/button/-/button-14.0.0-canary.7d8ea4624.0.tgz#00f91b04f0bcc9bbf6ed37db9bf677d792760fbb" - integrity sha512-WjvHgCCb1dauf2LemN7SGVxKRuKw+HB3zeXFOXZ3uWPIfpw3hWV2duiPqXSaRQo6RJl3EUQB2Ek+99Ii5Yfh6w== - dependencies: - "@material/density" "14.0.0-canary.7d8ea4624.0" - "@material/dom" "14.0.0-canary.7d8ea4624.0" - "@material/elevation" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/focus-ring" "14.0.0-canary.7d8ea4624.0" - "@material/ripple" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/shape" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" - "@material/tokens" "14.0.0-canary.7d8ea4624.0" - "@material/touch-target" "14.0.0-canary.7d8ea4624.0" - "@material/typography" "14.0.0-canary.7d8ea4624.0" +"@material/button@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/button/-/button-14.0.0-canary.c047f7c19.0.tgz#ef3619074c3a37c5ebff75fd09defe427435a378" + integrity sha512-SlOzp1kXxykeuZii8K6csUMufKMERXNjJ6nkCQWRtuU0o0nSzotWjo5vQv63OdzSO2PmqBBbF4H6gBp8Q2y3NA== + dependencies: + "@material/density" "14.0.0-canary.c047f7c19.0" + "@material/dom" "14.0.0-canary.c047f7c19.0" + "@material/elevation" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/focus-ring" "14.0.0-canary.c047f7c19.0" + "@material/ripple" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/shape" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" + "@material/tokens" "14.0.0-canary.c047f7c19.0" + "@material/touch-target" "14.0.0-canary.c047f7c19.0" + "@material/typography" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/card@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/card/-/card-14.0.0-canary.7d8ea4624.0.tgz#766fc9b98a4bef8e9eba21b2b1a28c406f9ba957" - integrity sha512-WatP+Ie2PsX0M0CaOyM4bR0jYwF6NIJAUIfk+dm1Tqy4eoHXk4RXbhbKYFNlN5TXXiIPgu6bfQrFou6B+LHDoA== - dependencies: - "@material/dom" "14.0.0-canary.7d8ea4624.0" - "@material/elevation" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/ripple" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/shape" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" +"@material/card@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/card/-/card-14.0.0-canary.c047f7c19.0.tgz#1966d8483193f60c448efb890f893c13f7cf5826" + integrity sha512-dqFgCO+DZU8sj/7l6ZboNVjosbJU27tBQ0Y0SqQZPDwzTmZDoa0P6YrsMP95EZQJ4Xlr7Q8oN7RVWdV9eSUVqQ== + dependencies: + "@material/dom" "14.0.0-canary.c047f7c19.0" + "@material/elevation" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/ripple" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/shape" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/checkbox@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/checkbox/-/checkbox-14.0.0-canary.7d8ea4624.0.tgz#3feff6bbeba24206ea6b636baaad12a00dc744b2" - integrity sha512-heVHiiqTsEkXOx+7p+2/YRvppv4oLnoChr4CTbJKIJP9ALg/hjl9EAWzfDm74DDNeqszctG1IUGRhl+UaMx2tw== - dependencies: - "@material/animation" "14.0.0-canary.7d8ea4624.0" - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/density" "14.0.0-canary.7d8ea4624.0" - "@material/dom" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/ripple" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" - "@material/touch-target" "14.0.0-canary.7d8ea4624.0" +"@material/checkbox@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/checkbox/-/checkbox-14.0.0-canary.c047f7c19.0.tgz#30b159f833c17d7aef3baa741698befafd79784c" + integrity sha512-juF6U9qTslKzz3GFnveofVpU04GRoZFi2upCuCtckQRTOiDWYmI1F+RRK6Qg7y9ydGOli6y2DwyHySS21DcbWg== + dependencies: + "@material/animation" "14.0.0-canary.c047f7c19.0" + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/density" "14.0.0-canary.c047f7c19.0" + "@material/dom" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/ripple" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" + "@material/touch-target" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/chips@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/chips/-/chips-14.0.0-canary.7d8ea4624.0.tgz#c46f38a3c11c5fbbce54691269c48338f43f847f" - integrity sha512-7FDM/li2xJSp2lpcHzYRF+XY0WJgDUEkmPDicl3Q99blcD1yprc76xk5yTvck8YCXvl8yKp3NHe/Dl72pf5YXg== - dependencies: - "@material/animation" "14.0.0-canary.7d8ea4624.0" - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/checkbox" "14.0.0-canary.7d8ea4624.0" - "@material/density" "14.0.0-canary.7d8ea4624.0" - "@material/dom" "14.0.0-canary.7d8ea4624.0" - "@material/elevation" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/focus-ring" "14.0.0-canary.7d8ea4624.0" - "@material/ripple" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/shape" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" - "@material/tokens" "14.0.0-canary.7d8ea4624.0" - "@material/touch-target" "14.0.0-canary.7d8ea4624.0" - "@material/typography" "14.0.0-canary.7d8ea4624.0" +"@material/chips@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/chips/-/chips-14.0.0-canary.c047f7c19.0.tgz#b5b8cc6140b11c4987d1f3dbe7deb92bc8bdbf3d" + integrity sha512-YG8pKe3ZVHOfHFVC0ctn+CtOaTrJc8klCcmXpgwlhT9YTCNjrWtjkXPZYYzQ0CWwqzv8Cii0ZMeHG4DCaGQChA== + dependencies: + "@material/animation" "14.0.0-canary.c047f7c19.0" + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/checkbox" "14.0.0-canary.c047f7c19.0" + "@material/density" "14.0.0-canary.c047f7c19.0" + "@material/dom" "14.0.0-canary.c047f7c19.0" + "@material/elevation" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/focus-ring" "14.0.0-canary.c047f7c19.0" + "@material/ripple" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/shape" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" + "@material/tokens" "14.0.0-canary.c047f7c19.0" + "@material/touch-target" "14.0.0-canary.c047f7c19.0" + "@material/typography" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/circular-progress@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/circular-progress/-/circular-progress-14.0.0-canary.7d8ea4624.0.tgz#7ab443905d531567cf8b6c6d6a9422cd85494923" - integrity sha512-EgUfbldmsG05SPp0EdbNyvhZHC9WuLBJadU7TBw01w7JRoVp8ZUNQkrwZszR9ylez8sDSmWAHpX0DNyKAwBKXQ== - dependencies: - "@material/animation" "14.0.0-canary.7d8ea4624.0" - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/progress-indicator" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" +"@material/circular-progress@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/circular-progress/-/circular-progress-14.0.0-canary.c047f7c19.0.tgz#2f59b66eed5d3bbf08cbd1647283e146d36ecebd" + integrity sha512-oRnAaViavNBoBua0Z3iLBD3MOoYgpPge3FZB2+z1akxX5O9cktz3ksNv2/QJtqHe4nbh+Vcly8gk6ILFvBxMXg== + dependencies: + "@material/animation" "14.0.0-canary.c047f7c19.0" + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/progress-indicator" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/data-table@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/data-table/-/data-table-14.0.0-canary.7d8ea4624.0.tgz#84a07eb6c33ef036620de4d550bfe9d19270795d" - integrity sha512-2/9ELiCCJEBtW8JY6+oYkHpWeUzSK1YJdyGdzRZ+TtCZNeE7NadcFK8CEOe4OdNkIXeoyum5P/23tXNWx9ZA+Q== - dependencies: - "@material/animation" "14.0.0-canary.7d8ea4624.0" - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/checkbox" "14.0.0-canary.7d8ea4624.0" - "@material/density" "14.0.0-canary.7d8ea4624.0" - "@material/dom" "14.0.0-canary.7d8ea4624.0" - "@material/elevation" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/icon-button" "14.0.0-canary.7d8ea4624.0" - "@material/linear-progress" "14.0.0-canary.7d8ea4624.0" - "@material/list" "14.0.0-canary.7d8ea4624.0" - "@material/menu" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/select" "14.0.0-canary.7d8ea4624.0" - "@material/shape" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" - "@material/touch-target" "14.0.0-canary.7d8ea4624.0" - "@material/typography" "14.0.0-canary.7d8ea4624.0" +"@material/data-table@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/data-table/-/data-table-14.0.0-canary.c047f7c19.0.tgz#ffa54512a0a992ba42202ca85ba531fb806fa1a4" + integrity sha512-ZZsGfTpDQwmIh+/HYUgTIBaLCGA0Be5DIaPS8YoZcKg6xtrX+UvlWZKrTGUWLXk0WviWKenWKnV0cydpNA16Bg== + dependencies: + "@material/animation" "14.0.0-canary.c047f7c19.0" + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/checkbox" "14.0.0-canary.c047f7c19.0" + "@material/density" "14.0.0-canary.c047f7c19.0" + "@material/dom" "14.0.0-canary.c047f7c19.0" + "@material/elevation" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/icon-button" "14.0.0-canary.c047f7c19.0" + "@material/linear-progress" "14.0.0-canary.c047f7c19.0" + "@material/list" "14.0.0-canary.c047f7c19.0" + "@material/menu" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/select" "14.0.0-canary.c047f7c19.0" + "@material/shape" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" + "@material/touch-target" "14.0.0-canary.c047f7c19.0" + "@material/typography" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/density@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/density/-/density-14.0.0-canary.7d8ea4624.0.tgz#41fd6bd1a099355f7a0cc90cf71c23c145de36a2" - integrity sha512-OVFAU4CMj5pRTG/9zdJ//qFIwSx01yyh0pf+zOxVDPRgyGw2Ve2mFiQlEGNEUw7X8IfOQ95hiU+7vflSAgq6vw== +"@material/density@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/density/-/density-14.0.0-canary.c047f7c19.0.tgz#38aa1c803133d54e636fc9c58062af0b533d696a" + integrity sha512-hH9rHn8oLi2/A/PSfDwR2x6HvJEc3NWQahWaM8RVRllRB5QsJHasLqhdyySR0CEpe685fhvaQ4/IyxGs9Eun8g== dependencies: tslib "^2.1.0" -"@material/dialog@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/dialog/-/dialog-14.0.0-canary.7d8ea4624.0.tgz#24be5b16bbc408abd854fcf20d7ae26c83d1d948" - integrity sha512-7xwUEdmmggYJweX3uUJdeH4nEnKpTeQx81cR4LJ3lJX7OV3lARLjXur5meNSdzB/EVsEiWrvuVIE5wLMAiZ6YA== - dependencies: - "@material/animation" "14.0.0-canary.7d8ea4624.0" - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/button" "14.0.0-canary.7d8ea4624.0" - "@material/dom" "14.0.0-canary.7d8ea4624.0" - "@material/elevation" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/icon-button" "14.0.0-canary.7d8ea4624.0" - "@material/ripple" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/shape" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" - "@material/tokens" "14.0.0-canary.7d8ea4624.0" - "@material/touch-target" "14.0.0-canary.7d8ea4624.0" - "@material/typography" "14.0.0-canary.7d8ea4624.0" +"@material/dialog@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/dialog/-/dialog-14.0.0-canary.c047f7c19.0.tgz#e47baea0c51c7667bc318c83106311652d2cb48d" + integrity sha512-8jq5LUoJoJO1sT2+QrelimQWDNLuDUqEtYnYRxlpMtVFSladEpobvwR9I0OdcSf0NRd5sY6pI4h/0syHH9Y3Kw== + dependencies: + "@material/animation" "14.0.0-canary.c047f7c19.0" + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/button" "14.0.0-canary.c047f7c19.0" + "@material/dom" "14.0.0-canary.c047f7c19.0" + "@material/elevation" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/icon-button" "14.0.0-canary.c047f7c19.0" + "@material/ripple" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/shape" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" + "@material/tokens" "14.0.0-canary.c047f7c19.0" + "@material/touch-target" "14.0.0-canary.c047f7c19.0" + "@material/typography" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/dom@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/dom/-/dom-14.0.0-canary.7d8ea4624.0.tgz#51f68a70008bcdffa3bfdc6491f934a7d1f44a9b" - integrity sha512-JLL9HpPNs4lRYmT6sw3tZ8mzvVqRDQxqKxiDX7nwJPQuDcK6vx6dOlD4XrceJ6dnBiKsLwnKi8vtAm+QTNS5fw== +"@material/dom@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/dom/-/dom-14.0.0-canary.c047f7c19.0.tgz#af0e2f93ae2482f5353e00741b3d63e2192b1dc9" + integrity sha512-E+xWPA1et7yJRts+FMWruAUx8f0GVa6gPKcRt2IdbtP/UZuaan5EzA/e86H+zuvY1YG7GUbinr77z8Auon5jBw== dependencies: - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/drawer@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/drawer/-/drawer-14.0.0-canary.7d8ea4624.0.tgz#34959c99239be6a1dc5a1cc096808ca44c8041d4" - integrity sha512-9OdubaAh6cWTDxRh5MQC++97VRhrScxIF364j0zzKMc4A1iIMc12WnevbR83khuDD6/7hgdDoGOfMn3xUPMdVA== - dependencies: - "@material/animation" "14.0.0-canary.7d8ea4624.0" - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/dom" "14.0.0-canary.7d8ea4624.0" - "@material/elevation" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/list" "14.0.0-canary.7d8ea4624.0" - "@material/ripple" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/shape" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" - "@material/typography" "14.0.0-canary.7d8ea4624.0" +"@material/drawer@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/drawer/-/drawer-14.0.0-canary.c047f7c19.0.tgz#7767a58ec5117dde0b0a95fb7855fea61ba2ba10" + integrity sha512-3WQyhqQt+LHZJDzWLfSqGze15Y3LiS5U4Fm9Ouarj5UUwVBXxaCrBI6ArrV/tTWh2MXTEMlDr4b/84eqI0imNw== + dependencies: + "@material/animation" "14.0.0-canary.c047f7c19.0" + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/dom" "14.0.0-canary.c047f7c19.0" + "@material/elevation" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/list" "14.0.0-canary.c047f7c19.0" + "@material/ripple" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/shape" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" + "@material/typography" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/elevation@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/elevation/-/elevation-14.0.0-canary.7d8ea4624.0.tgz#50de6aa51fecf0fc1b2a7461ec4f4a9887540f3c" - integrity sha512-roJyZDizvoxVqvsQuYq5gg13KYRIlj51EhWGYAodINvq9ZXo8QKxBG84rYQz7XN5MRwcAQAussYId2No6YwPjw== +"@material/elevation@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/elevation/-/elevation-14.0.0-canary.c047f7c19.0.tgz#870b090040ae1fe8346aafb227bbdd65fb6fb140" + integrity sha512-HR+fqtIAy28UkHTcfMnb5xPrRksfmmW831RZavCHQqvRVVmFnkHAJ8QgrBcgjYRK9/8aYO8cKYAU4OJj0pvaMA== dependencies: - "@material/animation" "14.0.0-canary.7d8ea4624.0" - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" + "@material/animation" "14.0.0-canary.c047f7c19.0" + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/fab@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/fab/-/fab-14.0.0-canary.7d8ea4624.0.tgz#41737f38ff36fb2e3dc95a1a0f86dea91b98c1a9" - integrity sha512-3JAbLjnm3nZCUocR4J+3kLjBSd6Yq/qsleYnQPQLo46lFRPgw5VGTNU8FU5uT1GK39Q6N+mLqL+oJjqinNHe8A== - dependencies: - "@material/animation" "14.0.0-canary.7d8ea4624.0" - "@material/dom" "14.0.0-canary.7d8ea4624.0" - "@material/elevation" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/focus-ring" "14.0.0-canary.7d8ea4624.0" - "@material/ripple" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/shape" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" - "@material/tokens" "14.0.0-canary.7d8ea4624.0" - "@material/touch-target" "14.0.0-canary.7d8ea4624.0" - "@material/typography" "14.0.0-canary.7d8ea4624.0" +"@material/fab@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/fab/-/fab-14.0.0-canary.c047f7c19.0.tgz#6b9d17385580fc94fd098566fa4ad1f4061da57b" + integrity sha512-SpuRMRKRMFkfiKrIYjuybmWI9BQfa9uLhdr7cPne2D1qHh4XI33KrKcnmphC+M/G2ctrmH9bS+KjkWlp4lpCMw== + dependencies: + "@material/animation" "14.0.0-canary.c047f7c19.0" + "@material/dom" "14.0.0-canary.c047f7c19.0" + "@material/elevation" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/focus-ring" "14.0.0-canary.c047f7c19.0" + "@material/ripple" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/shape" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" + "@material/tokens" "14.0.0-canary.c047f7c19.0" + "@material/touch-target" "14.0.0-canary.c047f7c19.0" + "@material/typography" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/feature-targeting@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/feature-targeting/-/feature-targeting-14.0.0-canary.7d8ea4624.0.tgz#ac50368b7804c069483788cea63a4f85c3486ffe" - integrity sha512-G3y4rUHMExf3nrMSiUvvxce8tUSOSmhoMG+sBYIY6L8GAa+GHbmv7rhjvd7uU33KVKWc2A1PjHL7xk9vZdf87g== +"@material/feature-targeting@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/feature-targeting/-/feature-targeting-14.0.0-canary.c047f7c19.0.tgz#8e6835143a4f419cee00d998f671ab0f4a2cfcc5" + integrity sha512-b69UuDXKtnb6Hx6pRTWEhSSo6U66DLkOBRSRMJDwJ9BROU7kgwbDRgD+ajLHkyr06g2JYXbp5fzRZnbdeIVt6Q== dependencies: tslib "^2.1.0" -"@material/floating-label@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/floating-label/-/floating-label-14.0.0-canary.7d8ea4624.0.tgz#c34f753befb2457ee1b0697c37156a6c2d8c8d75" - integrity sha512-qHcLFCcEbXByht3kFnA1ukWu6kuqFT9dVuCmfxuESJQ9D7+4WIB3ghBkNNLUTEWCrsvEwHmiiBvm9Tj7MHhSIQ== - dependencies: - "@material/animation" "14.0.0-canary.7d8ea4624.0" - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/dom" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" - "@material/typography" "14.0.0-canary.7d8ea4624.0" +"@material/floating-label@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/floating-label/-/floating-label-14.0.0-canary.c047f7c19.0.tgz#ff4e400b88790fbe353f29446d4869ea4d57aec3" + integrity sha512-gw5b9qRf2F6zLD9I2IyAIAdEt3ckFAAoun953T5lvMWaPQN9jjQGfeT224Hhm5Z3Te53yD5xULIZy7RbhJyzDQ== + dependencies: + "@material/animation" "14.0.0-canary.c047f7c19.0" + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/dom" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" + "@material/typography" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/focus-ring@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/focus-ring/-/focus-ring-14.0.0-canary.7d8ea4624.0.tgz#74df41d0a8aa0fd301fa5aa83fc99d990530b813" - integrity sha512-DpW241n9GUUphY3OU+x4bfCvOTx1cWrOLM3Vep77a1S+3EWQSnOlEUCvKcFBJ9tDcQ/Py939FIfAqjo6RcHieg== - dependencies: - "@material/dom" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - -"@material/form-field@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/form-field/-/form-field-14.0.0-canary.7d8ea4624.0.tgz#f8fdf1439ed8d73594bcff5d1fd2892554532956" - integrity sha512-avR6Kz4dDmEFLYv4YnZTLWVzutjUvIcmVQNZU3eF41fdVPJkEh0ESgux/hGUSjkky3eWIACBdwvTpkf6L9cI+w== - dependencies: - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/ripple" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" - "@material/typography" "14.0.0-canary.7d8ea4624.0" +"@material/focus-ring@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/focus-ring/-/focus-ring-14.0.0-canary.c047f7c19.0.tgz#057ddf819a96a86307924c6d9b92a0dc38c3fd09" + integrity sha512-egDOpfTMmxkVqry1WbEcY5pFzyhzTs+F0OpbXnpm1ZZ5/1gbK+4ZXCFas88nwZZEx/iKb6OdFNyOAanKphJX/Q== + dependencies: + "@material/dom" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + +"@material/form-field@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/form-field/-/form-field-14.0.0-canary.c047f7c19.0.tgz#d0a468246efa1f7cbdbf7bd7230ac9f8c26ee887" + integrity sha512-lbBpXpYpQrm1RUjbpBzbVs3VOabJ6WKkI1nz4ViJh9WD3pogU4E8pVVad1ufTwH65rYBrAr53g1ln1qjTKhGSA== + dependencies: + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/ripple" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" + "@material/typography" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/icon-button@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/icon-button/-/icon-button-14.0.0-canary.7d8ea4624.0.tgz#7ca13dd4cfde95a7fd2cbf97197c7248cad4014c" - integrity sha512-/aYjiNc0lN0pX4ASUWjuGJN8KNVYqhKCDhZ+8QHvsyx+XTeXbhDtp3gUXXiCP7NeHqtDZnAYXJq7oY4dW5C0XA== - dependencies: - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/density" "14.0.0-canary.7d8ea4624.0" - "@material/elevation" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/ripple" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" - "@material/touch-target" "14.0.0-canary.7d8ea4624.0" +"@material/icon-button@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/icon-button/-/icon-button-14.0.0-canary.c047f7c19.0.tgz#b623caf55bd23431003a363c0f0aa0f1e65530f7" + integrity sha512-LLq7L1vDPoF5h6RREJms6YD8uOilqRdfic3E25tlCt3VDJWVQg8w1T6GHHyBE8dwGfxNAr/DTa3Hv7SWQis2uw== + dependencies: + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/density" "14.0.0-canary.c047f7c19.0" + "@material/elevation" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/ripple" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" + "@material/touch-target" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/image-list@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/image-list/-/image-list-14.0.0-canary.7d8ea4624.0.tgz#7b2b0580fa2cdf08b8d1822cf08eee734c5101dd" - integrity sha512-yV+2j6NG/leA209N0ASP5jX+EeXbjg4HMvqyXX738fhdVx8ywwKJyg6D8FZdlCm9kUkSOeuxH/bxbLdy+CkX7w== +"@material/image-list@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/image-list/-/image-list-14.0.0-canary.c047f7c19.0.tgz#b7993386677c924e613d18725a107fe89ccfe705" + integrity sha512-MVZnezXHh2sMQP7GepTMMYy6dsxm45M1UfdZyuHcZ2YQyVpcvd20UIfTgOTXKCmVN9bvLdrmcm/i4KMKq0kpRw== dependencies: - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/shape" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" - "@material/typography" "14.0.0-canary.7d8ea4624.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/shape" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" + "@material/typography" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/layout-grid@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/layout-grid/-/layout-grid-14.0.0-canary.7d8ea4624.0.tgz#6804d260cd92b1f087c50441de5b220b4abd4d21" - integrity sha512-oHHIoJdBaikHSClbnMojY4ywex4QsOdPkpOmw0inNxiIj1JvU42v/0bg4R9oO/u8oW4SPJTHt1PkP5wSiEOEkw== +"@material/layout-grid@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/layout-grid/-/layout-grid-14.0.0-canary.c047f7c19.0.tgz#f7575ec0431424217d1ec026f11e5aa9b3c7e8e5" + integrity sha512-BhOcXh1skXejrQD4LCXM6cToK3U4bM1qrvT2FoxoaS1eYLbavws5p6cn3ktN3t20dnVlBvjcN6dGwBO09J2u8g== dependencies: tslib "^2.1.0" -"@material/line-ripple@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/line-ripple/-/line-ripple-14.0.0-canary.7d8ea4624.0.tgz#682eb71b23c236a8a955ea4405bace3dcaa7e109" - integrity sha512-b9nQftcIuJVmhpuTNmKO1cXQUz0uJ90u2gZTm9JcXR0poajQ43P1axcBfMv1+OTopTwRoNwk7Y7kakc/cYSagA== +"@material/line-ripple@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/line-ripple/-/line-ripple-14.0.0-canary.c047f7c19.0.tgz#fbb58518722c0a4debab9e25648e4f4816225388" + integrity sha512-mwIxWYVo9qJYaNoVmJZ/0Qn7DYJehnaSrNLAYdszGnhFHDVDzbmkfJbVFrE1IvImzsqTNK/4I6HZw18DY545Dg== dependencies: - "@material/animation" "14.0.0-canary.7d8ea4624.0" - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" + "@material/animation" "14.0.0-canary.c047f7c19.0" + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/linear-progress@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/linear-progress/-/linear-progress-14.0.0-canary.7d8ea4624.0.tgz#64875946616846be2bfaba80681f2e00742314bc" - integrity sha512-tfKvOwbm1kSHruGEfypljXgrgrpwrL5lD9Iq9yJ/Z0lcvkd8nXXHRbNEQOphktexcQhaHjlPfEd+BIr/Y3ItAg== - dependencies: - "@material/animation" "14.0.0-canary.7d8ea4624.0" - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/dom" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/progress-indicator" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" +"@material/linear-progress@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/linear-progress/-/linear-progress-14.0.0-canary.c047f7c19.0.tgz#2c4b41f7a4bdd3cffdcfea26e9ec584e1db3e855" + integrity sha512-2ihxhS2hwLEw7YIWrumv7VmqrDbpXvevO1Ixw9UVFTLaYo0S5+V9oRcMHX3oxfbMfRJxvJtS6Fpljcb6cJhfKA== + dependencies: + "@material/animation" "14.0.0-canary.c047f7c19.0" + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/dom" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/progress-indicator" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/list@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/list/-/list-14.0.0-canary.7d8ea4624.0.tgz#768c30a63a81bce2635eb8d7d12b6006dea57c07" - integrity sha512-7issueqjka6oeFPNMWpzDuH1LRluuifi12F19SsDwbNkh6nAzn2MYJh5vria2JhefP2A34l4r2V8mu2ke+Iq5Q== - dependencies: - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/density" "14.0.0-canary.7d8ea4624.0" - "@material/dom" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/ripple" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/shape" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" - "@material/typography" "14.0.0-canary.7d8ea4624.0" +"@material/list@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/list/-/list-14.0.0-canary.c047f7c19.0.tgz#5fced32a8c1d450c8b243bb66de303c414751b74" + integrity sha512-WoS4mXjq+78aE/7U76nAgxDzdQGLWHGGWM6fokr6AsnzxhRIUnnh1YqWvs0e8z++fM2J9ntBefMDlSg4Z7Ouhg== + dependencies: + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/density" "14.0.0-canary.c047f7c19.0" + "@material/dom" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/ripple" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/shape" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" + "@material/typography" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/menu-surface@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/menu-surface/-/menu-surface-14.0.0-canary.7d8ea4624.0.tgz#e68574df425d3fcf68f298fa672a8ed67d88ef5f" - integrity sha512-HZ5Md/hg/cA9mnwp74BDN40zb2EYexWuw7BGQrBykbFZlOt6WjxbAfzajJqElUhgHQ6KiXcX2rKTm4Vtmw1gjg== - dependencies: - "@material/animation" "14.0.0-canary.7d8ea4624.0" - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/elevation" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/shape" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" +"@material/menu-surface@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/menu-surface/-/menu-surface-14.0.0-canary.c047f7c19.0.tgz#c4c25a30bf2b72aa26dbba5efa3750e5f717804d" + integrity sha512-Gj42G9PILYWX1KV7DVRPX1327HVLqVhkU1q+cvANfb5oDmXtmbBuOJ8ab+OwpZsVgzTUWryBHmKuXyjLdMHQBQ== + dependencies: + "@material/animation" "14.0.0-canary.c047f7c19.0" + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/elevation" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/shape" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/menu@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/menu/-/menu-14.0.0-canary.7d8ea4624.0.tgz#1678a8666559d14d206ecacbc26c72a25c975bb2" - integrity sha512-Ykp/PEMZCdCj43P7oauSj7eAXnAjg+UvRIifdMWQeYTlYjRMzrnToClcB/nv3s3JV3MMfz4/7kCwvO7aoRkXSQ== - dependencies: - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/dom" "14.0.0-canary.7d8ea4624.0" - "@material/elevation" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/list" "14.0.0-canary.7d8ea4624.0" - "@material/menu-surface" "14.0.0-canary.7d8ea4624.0" - "@material/ripple" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" +"@material/menu@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/menu/-/menu-14.0.0-canary.c047f7c19.0.tgz#a0b27e3b0557777eb93c1b2b38d24629ff98116b" + integrity sha512-rfdcOl5NMThdz5zcEyVYd2lf9+khBgUobBCL5McqhI7dYlYKGLRs0rzGpqQ5O/rLkr4kjrl4DeMF6nhP/XnRqA== + dependencies: + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/dom" "14.0.0-canary.c047f7c19.0" + "@material/elevation" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/list" "14.0.0-canary.c047f7c19.0" + "@material/menu-surface" "14.0.0-canary.c047f7c19.0" + "@material/ripple" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/notched-outline@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/notched-outline/-/notched-outline-14.0.0-canary.7d8ea4624.0.tgz#967cea3737a744bb28add033e517b568ee0d0b4c" - integrity sha512-JtgUueVZnfFalYHmUemMf7CANZIpudxRB3ZZkWqNPTGCK7ATTvKMUyTvs/cgXfUsEzmD9xVboupIn3vsiq7yOQ== - dependencies: - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/floating-label" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/shape" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" +"@material/notched-outline@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/notched-outline/-/notched-outline-14.0.0-canary.c047f7c19.0.tgz#be78e03b1171c29e1018dc0977bb30bfeb3c83e0" + integrity sha512-VT71ROAyvqIVq2Gy+sConIxW0TIERVwjY7HV7pkmNtcUKQVAkufg5Pm4UF9whHs/lj7kgr6NUdirqoEfVwKzKw== + dependencies: + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/floating-label" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/shape" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/progress-indicator@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/progress-indicator/-/progress-indicator-14.0.0-canary.7d8ea4624.0.tgz#fa0c9ecd7c50122e31a4269062444ce4d5707802" - integrity sha512-pYqJL1nCMnhqO2QhRXLuLzKUDt6q4iydVonu46KQL9R0ubJy/4q0+GTv25B4ygHvmU9CTcCTgFQUB6Mt3xPLaw== +"@material/progress-indicator@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/progress-indicator/-/progress-indicator-14.0.0-canary.c047f7c19.0.tgz#31f8b580fd5243df11980d825167d62c00f7d988" + integrity sha512-SfbrzN5SgCtqWlLdDqAhwTi1YtLPssMxnHYfUPaPDz5Zp12fAt+aDPSlNHoBJjBDb0+tc7UsN8o/sc0R6FQMpA== dependencies: tslib "^2.1.0" -"@material/radio@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/radio/-/radio-14.0.0-canary.7d8ea4624.0.tgz#09ff630d3eadb3247537a5d2805d6c4635fc8fc3" - integrity sha512-4+HtqzWkXX9HDbXje1VW2812Q7r9+3T9hiqRIVq+nBMxI66nGcVtgDF80+1sLNVpxiyNmPWMQLpSwIH6v6t3jQ== - dependencies: - "@material/animation" "14.0.0-canary.7d8ea4624.0" - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/density" "14.0.0-canary.7d8ea4624.0" - "@material/dom" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/focus-ring" "14.0.0-canary.7d8ea4624.0" - "@material/ripple" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" - "@material/touch-target" "14.0.0-canary.7d8ea4624.0" +"@material/radio@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/radio/-/radio-14.0.0-canary.c047f7c19.0.tgz#1c19e363981d8032b79c78586c395bbda53b70af" + integrity sha512-GgWexshtJ0I/WCaEcTq8MpnRi6/65nY5D3UQRska3KoH4/bTwWEulGRibG2SGcB3WimhkGb8wK+cGA+mW9kC/Q== + dependencies: + "@material/animation" "14.0.0-canary.c047f7c19.0" + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/density" "14.0.0-canary.c047f7c19.0" + "@material/dom" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/focus-ring" "14.0.0-canary.c047f7c19.0" + "@material/ripple" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" + "@material/touch-target" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/ripple@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/ripple/-/ripple-14.0.0-canary.7d8ea4624.0.tgz#6c650bebd79d60cf6cfcd18a887d9a88eb45efc6" - integrity sha512-LpRmw1ykO1876Kvxiu69vNbLV3CqJLlKDRJV93bKnhfKe1jEiTyQ7K6KZoqYf7ZYi+CLUMETa6hriACe73qNEA== - dependencies: - "@material/animation" "14.0.0-canary.7d8ea4624.0" - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/dom" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" +"@material/ripple@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/ripple/-/ripple-14.0.0-canary.c047f7c19.0.tgz#33918fc12a964aaa47125097459e2355492193dd" + integrity sha512-AJJFzsYbXfgQgWFoHsJShGWrmN7s+Wo8nEpy3vb1LlOyz90ClrOlCJRRKpoCb3Pyb5FqVh2rvTu9GtPOToAzwQ== + dependencies: + "@material/animation" "14.0.0-canary.c047f7c19.0" + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/dom" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/rtl@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/rtl/-/rtl-14.0.0-canary.7d8ea4624.0.tgz#59ed1f02b548169fa94f94086c997d05d53f777b" - integrity sha512-IQin1e3fw7mKY2d09gHx95fmjwCohTz6gXIyd/zzNqq3x9CCxVT8MxE7BlynGLkzLkRDNeVhjuEoglLZqOg5FQ== +"@material/rtl@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/rtl/-/rtl-14.0.0-canary.c047f7c19.0.tgz#581a01bfb0f144cdf454f34f0e4bc6d01fedae3f" + integrity sha512-tUX0cCiBYcINQp9d2tB32T9PWvLaL7E+O8G60Q9XeoGdgARG2rrfL/y2BmchqoccFO2N4Q5X5IYNQL1ZiafcQQ== dependencies: - "@material/theme" "14.0.0-canary.7d8ea4624.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/segmented-button@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/segmented-button/-/segmented-button-14.0.0-canary.7d8ea4624.0.tgz#75943cf0e15bba41530c16ab68b861d49c1c580b" - integrity sha512-PIzPIo/jc7hmCaEu7q5zqEVtk0sL+hkXGBckqbOljK14Zyo5AK/nvAQCQlVWeNvPI/HkF2TEGjQ0Og6f3hgHqg== - dependencies: - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/elevation" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/ripple" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" - "@material/touch-target" "14.0.0-canary.7d8ea4624.0" - "@material/typography" "14.0.0-canary.7d8ea4624.0" +"@material/segmented-button@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/segmented-button/-/segmented-button-14.0.0-canary.c047f7c19.0.tgz#ff216084245d0c6f259463605dd22cca050b95c3" + integrity sha512-jmgQceMjbYkuZ3ISVNL93r9GnloRQvCNiPIaYFDJgBHZaxGP/EPdYhPB20yW8sW83J8wsDTU+h9LAqyFIjcWlw== + dependencies: + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/elevation" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/ripple" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" + "@material/touch-target" "14.0.0-canary.c047f7c19.0" + "@material/typography" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/select@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/select/-/select-14.0.0-canary.7d8ea4624.0.tgz#664fbf03034818a93edfbd3f2ad7f1d88e272c97" - integrity sha512-qMuhfU7bMJXi76K0XoI22eOMv3lqJhcr4/RllZ1yedlEuUO1yUuWp5D0+tydFcHsYcq2xGLtTsMv9S3bBsQO5Q== - dependencies: - "@material/animation" "14.0.0-canary.7d8ea4624.0" - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/density" "14.0.0-canary.7d8ea4624.0" - "@material/dom" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/floating-label" "14.0.0-canary.7d8ea4624.0" - "@material/line-ripple" "14.0.0-canary.7d8ea4624.0" - "@material/list" "14.0.0-canary.7d8ea4624.0" - "@material/menu" "14.0.0-canary.7d8ea4624.0" - "@material/menu-surface" "14.0.0-canary.7d8ea4624.0" - "@material/notched-outline" "14.0.0-canary.7d8ea4624.0" - "@material/ripple" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/shape" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" - "@material/typography" "14.0.0-canary.7d8ea4624.0" +"@material/select@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/select/-/select-14.0.0-canary.c047f7c19.0.tgz#8682029d39d4047243c8625657d25881962fa26c" + integrity sha512-gTZlyoRMDPpmjy7ycIz7UfwJyWJA/0VwyGGGnyYIupYlANQrmk9M3jl+gbVQeDPbYWp07aTWAlMUcQMoZyiPVA== + dependencies: + "@material/animation" "14.0.0-canary.c047f7c19.0" + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/density" "14.0.0-canary.c047f7c19.0" + "@material/dom" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/floating-label" "14.0.0-canary.c047f7c19.0" + "@material/line-ripple" "14.0.0-canary.c047f7c19.0" + "@material/list" "14.0.0-canary.c047f7c19.0" + "@material/menu" "14.0.0-canary.c047f7c19.0" + "@material/menu-surface" "14.0.0-canary.c047f7c19.0" + "@material/notched-outline" "14.0.0-canary.c047f7c19.0" + "@material/ripple" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/shape" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" + "@material/typography" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/shape@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/shape/-/shape-14.0.0-canary.7d8ea4624.0.tgz#a27569775a6b050baacd4a90a5521c25ccfee57f" - integrity sha512-QzQ7lMpKbyR9fJywiQE9I0WqKEuLY7xfmJWe+oyH1lkRyPeR8hrctJNVKphuLCwTqhw5cyKNmaKhcZcklDq5dQ== +"@material/shape@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/shape/-/shape-14.0.0-canary.c047f7c19.0.tgz#c49f40a88b0fc74ed166eb241bf0336f527f5197" + integrity sha512-ZTXzd9tnp3KFOeao2YURJTS9AUuGjYBFVLb/HxgAtTlrxMMYE3IouBSXRv+r7eDdnWSPsKzIzz64hX4Y4hs7lg== dependencies: - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/slider@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/slider/-/slider-14.0.0-canary.7d8ea4624.0.tgz#ce9383dbb407ef48b061d0e43004e6eb7d1c4cc2" - integrity sha512-wrPnQm62/N8EOAtRqprObutnhoCJOSBfZU92r4va5C8AceN9PHFb+28pIylXXlf7OD2SxNj/OYlCCmmgA7Todg== - dependencies: - "@material/animation" "14.0.0-canary.7d8ea4624.0" - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/dom" "14.0.0-canary.7d8ea4624.0" - "@material/elevation" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/ripple" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" - "@material/typography" "14.0.0-canary.7d8ea4624.0" +"@material/slider@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/slider/-/slider-14.0.0-canary.c047f7c19.0.tgz#2554103a2fb20c07470246beaa9fe83bc466e0e9" + integrity sha512-dNtIrbgMsT+GsE72og0cUv7lHjnPMatrTZtiOy64zP3EvPqJaCFTv7c+KI85NX6sHsPg3qSkhVITIxYVRjYiBQ== + dependencies: + "@material/animation" "14.0.0-canary.c047f7c19.0" + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/dom" "14.0.0-canary.c047f7c19.0" + "@material/elevation" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/ripple" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" + "@material/typography" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/snackbar@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/snackbar/-/snackbar-14.0.0-canary.7d8ea4624.0.tgz#4a92da22f34a4aeeb78285ec8434cada3d234891" - integrity sha512-r7vVtQbOknXHv9LL/aBA18EcmZXNysq60qCC2Sf+M+vzATrIe92oZ22d9v/uXL17k3HAVw4sUWWRUo5owndS8A== - dependencies: - "@material/animation" "14.0.0-canary.7d8ea4624.0" - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/button" "14.0.0-canary.7d8ea4624.0" - "@material/dom" "14.0.0-canary.7d8ea4624.0" - "@material/elevation" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/icon-button" "14.0.0-canary.7d8ea4624.0" - "@material/ripple" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/shape" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" - "@material/typography" "14.0.0-canary.7d8ea4624.0" +"@material/snackbar@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/snackbar/-/snackbar-14.0.0-canary.c047f7c19.0.tgz#85a6ad431b163c9c034bf93774da1fd11963cab2" + integrity sha512-ZtO2l5gqTvknc+Orc+MbG6/vlnIgsLm8WFbswfhgPidltNNMZsCYARKZCcLgWc5B2A6T0JSx3f1CAQgD67dvVQ== + dependencies: + "@material/animation" "14.0.0-canary.c047f7c19.0" + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/button" "14.0.0-canary.c047f7c19.0" + "@material/dom" "14.0.0-canary.c047f7c19.0" + "@material/elevation" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/icon-button" "14.0.0-canary.c047f7c19.0" + "@material/ripple" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/shape" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" + "@material/typography" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/switch@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/switch/-/switch-14.0.0-canary.7d8ea4624.0.tgz#0ce869aa6509fae4c0e8d9ad6738d902b1b52610" - integrity sha512-oUL0sYEKrOHmskpsypMuGJhb94rg5PueH/i9RBsJKrQ/bWZV7H/4190+tJe33VojvaCEJZyjNfZgcdWf8tp8ww== - dependencies: - "@material/animation" "14.0.0-canary.7d8ea4624.0" - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/density" "14.0.0-canary.7d8ea4624.0" - "@material/dom" "14.0.0-canary.7d8ea4624.0" - "@material/elevation" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/ripple" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/shape" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" - "@material/tokens" "14.0.0-canary.7d8ea4624.0" +"@material/switch@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/switch/-/switch-14.0.0-canary.c047f7c19.0.tgz#e78298227382e444dd4979213c297f6939114f49" + integrity sha512-vQYTWVVbjCpDVHS6DCnTLp7VgayIkMbbwIVVeTBcqfxI4W0Q8UoUba7e5D6YBd9HDZLNmoBlc2qHHSUTzys8WQ== + dependencies: + "@material/animation" "14.0.0-canary.c047f7c19.0" + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/density" "14.0.0-canary.c047f7c19.0" + "@material/dom" "14.0.0-canary.c047f7c19.0" + "@material/elevation" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/ripple" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/shape" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" + "@material/tokens" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/tab-bar@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/tab-bar/-/tab-bar-14.0.0-canary.7d8ea4624.0.tgz#ec86c97ba83e5783b8b461a1260c2408a3710d64" - integrity sha512-zV+z5c8Q5tx27ox29+bPHBFQ5eF9nMHVpYm1jrnJvxCfpAl70VuKRWXl77DOZk0ONHn/SqklyJh9w1EXTRxTew== - dependencies: - "@material/animation" "14.0.0-canary.7d8ea4624.0" - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/density" "14.0.0-canary.7d8ea4624.0" - "@material/elevation" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/tab" "14.0.0-canary.7d8ea4624.0" - "@material/tab-indicator" "14.0.0-canary.7d8ea4624.0" - "@material/tab-scroller" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" - "@material/typography" "14.0.0-canary.7d8ea4624.0" +"@material/tab-bar@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/tab-bar/-/tab-bar-14.0.0-canary.c047f7c19.0.tgz#2ff1976af488c28313bfdce451e498c77f3e1a93" + integrity sha512-oSnXGuSbKfu6yC8UU7+SybIp5DR1k1ZHY1Yfdn79dGzRG5wus73KdzXcp7M5vKTZccVZCAujS9t781QULc34Gw== + dependencies: + "@material/animation" "14.0.0-canary.c047f7c19.0" + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/density" "14.0.0-canary.c047f7c19.0" + "@material/elevation" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/tab" "14.0.0-canary.c047f7c19.0" + "@material/tab-indicator" "14.0.0-canary.c047f7c19.0" + "@material/tab-scroller" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" + "@material/typography" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/tab-indicator@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/tab-indicator/-/tab-indicator-14.0.0-canary.7d8ea4624.0.tgz#378b9a88a44ba134e08ffd0dc7a7f12b9445ed49" - integrity sha512-lCvlc1zkmWwLAY5KMHRUOvbSwsikQStOZP3GqeHbalH8apBGvlA5nxICunEbOxqHDmk7++MSJ8/LsDB6yH+SCQ== +"@material/tab-indicator@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/tab-indicator/-/tab-indicator-14.0.0-canary.c047f7c19.0.tgz#41b046c7bd1597eff3bac22ff79733c6a53c1418" + integrity sha512-khqbjwyEwQiPcvWYqPXSgdLWS80bX6oCXf0VEtWe150i6aW4bEKYJe1Ic0g+FcTbU6xxWAkFUWUJvznUomkYVA== dependencies: - "@material/animation" "14.0.0-canary.7d8ea4624.0" - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" + "@material/animation" "14.0.0-canary.c047f7c19.0" + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/tab-scroller@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/tab-scroller/-/tab-scroller-14.0.0-canary.7d8ea4624.0.tgz#4c06e6e1f8254f369ab3c3c3006876697a88502d" - integrity sha512-Y8M8M7NKxSjm75o2eVWF9l1z3KWbhJ4VBer5bte3d+/G5QL8wIjcTFf2eN5GKFkEUziUvTEG/bAInExB8zoo+g== +"@material/tab-scroller@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/tab-scroller/-/tab-scroller-14.0.0-canary.c047f7c19.0.tgz#74aacb7714920ce8d07a29e3e93230ce3cead63d" + integrity sha512-LThMEYC9r6xClrkJrw4dAty5JDUDechiTvwXZBqlkbQBUwlfz+UMZV53p5z0LjwLFHgE23Y0wZmkW8RIcc7Z4w== dependencies: - "@material/animation" "14.0.0-canary.7d8ea4624.0" - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/dom" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/tab" "14.0.0-canary.7d8ea4624.0" + "@material/animation" "14.0.0-canary.c047f7c19.0" + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/dom" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/tab" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/tab@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/tab/-/tab-14.0.0-canary.7d8ea4624.0.tgz#4525c8451f193f6e52e01dc601dcb9cc5f90791f" - integrity sha512-ffINlenS8b/XwrWJTd9FvnmlWJkjUtcxOB4R8FRG1L3DysNdxhKQQEmKGGO3rswJcmoPxoOyWVR6SjADv9VCYA== - dependencies: - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/elevation" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/focus-ring" "14.0.0-canary.7d8ea4624.0" - "@material/ripple" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/tab-indicator" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" - "@material/typography" "14.0.0-canary.7d8ea4624.0" +"@material/tab@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/tab/-/tab-14.0.0-canary.c047f7c19.0.tgz#9af1e4a142d0ab2e81baad8596f0edf9c829a70b" + integrity sha512-B3GJNR4v08105o4BmWzbN1Dcw2nTgJExP5ruF9HTk/Lpn+20d+ogE4AEaqlQlYlFfCTHqQEWfh94TyL+MTm05A== + dependencies: + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/elevation" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/focus-ring" "14.0.0-canary.c047f7c19.0" + "@material/ripple" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/tab-indicator" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" + "@material/typography" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/textfield@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/textfield/-/textfield-14.0.0-canary.7d8ea4624.0.tgz#497bb289f8ffcb93b18e03a31c1b611377c92c3a" - integrity sha512-UpA12i6+O5iJDDnIDIQ+OGfZrnrgz0ukvYRiVPuaaJO4lXnBDNgXT7g2q+U1P6ZjYRVrBwGSDOLjRdWA6H9tPQ== - dependencies: - "@material/animation" "14.0.0-canary.7d8ea4624.0" - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/density" "14.0.0-canary.7d8ea4624.0" - "@material/dom" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/floating-label" "14.0.0-canary.7d8ea4624.0" - "@material/line-ripple" "14.0.0-canary.7d8ea4624.0" - "@material/notched-outline" "14.0.0-canary.7d8ea4624.0" - "@material/ripple" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/shape" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" - "@material/typography" "14.0.0-canary.7d8ea4624.0" +"@material/textfield@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/textfield/-/textfield-14.0.0-canary.c047f7c19.0.tgz#b9c6e402618538f6be59db27aa05d6e5865ec0b1" + integrity sha512-CbnOOLRhd8THHti8G8JXAM1e6AY/7QBZTfVDDGWiniryTKNWjIY3C6A4mQgg0E5kotGPbzBNDj3uWANVIyUEbw== + dependencies: + "@material/animation" "14.0.0-canary.c047f7c19.0" + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/density" "14.0.0-canary.c047f7c19.0" + "@material/dom" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/floating-label" "14.0.0-canary.c047f7c19.0" + "@material/line-ripple" "14.0.0-canary.c047f7c19.0" + "@material/notched-outline" "14.0.0-canary.c047f7c19.0" + "@material/ripple" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/shape" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" + "@material/typography" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/theme@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/theme/-/theme-14.0.0-canary.7d8ea4624.0.tgz#275b83daf348e18226035c94602f711f7ba3803f" - integrity sha512-lBO+Ztkc7jewV65bKPwJ9Lc4z9+DiEBxtT9Lx4cM+VHOuRNn5LcXSvbUuHzcnyPSLSzMmbUhvxfvLGs4PuKU6g== +"@material/theme@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/theme/-/theme-14.0.0-canary.c047f7c19.0.tgz#e61b8c8daaf2200b291e8faad75b459e0a772fc1" + integrity sha512-etZumekC7CPX6p9F4JDZa/phwFTIJEO09EHKXe6JWOhRZmEo4n2Ipi1qWS3lOG4WgeLlto5sINro47FVY4yzHA== dependencies: - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/tokens@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/tokens/-/tokens-14.0.0-canary.7d8ea4624.0.tgz#d18d8ec1131ae528e52623112c5760918f5178c6" - integrity sha512-hlIKvVzPQx2twwOKzzfFXAP59e5cpEh7IWn8VQZFhWhuucXJFS/WUMqTx2tpSXM+R1QF2o46E16pE3W1zKnOnA== - dependencies: - "@material/elevation" "14.0.0-canary.7d8ea4624.0" - -"@material/tooltip@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/tooltip/-/tooltip-14.0.0-canary.7d8ea4624.0.tgz#ca9b3f0f2378e2f18e96465478dd9e9ef572a4ec" - integrity sha512-Sdnlq7UC+/Dry3Lzd7yVpceWUK+7CfsDdXxs2wahIQixukF9O7+H1B1ZnJhX2hyfIOr18GNarvqlRlGrUh96/w== - dependencies: - "@material/animation" "14.0.0-canary.7d8ea4624.0" - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/dom" "14.0.0-canary.7d8ea4624.0" - "@material/elevation" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/shape" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" - "@material/typography" "14.0.0-canary.7d8ea4624.0" +"@material/tokens@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/tokens/-/tokens-14.0.0-canary.c047f7c19.0.tgz#e960989516fa63c0090dc4f589f91477f22eb6fb" + integrity sha512-aSKNcKQ2kJNMG6nlW8QyZoUyYgFt31NQFPtlzI5+Rw6IhWLONpMXmmjznNvzPcPYoB7KTvtCpxPMUNb2wukkWQ== + dependencies: + "@material/elevation" "14.0.0-canary.c047f7c19.0" + +"@material/tooltip@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/tooltip/-/tooltip-14.0.0-canary.c047f7c19.0.tgz#a1103aad3059d02e31c05b53b5a9727ecccdffde" + integrity sha512-sdjIbCr6G4Vji9IxLgfLVkso4Ypqx+31lQxcCWIH7OyDN9gjv8zEu6bMBJm2tmb75+mz2xrr0rSj5HRcQYDY7Q== + dependencies: + "@material/animation" "14.0.0-canary.c047f7c19.0" + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/dom" "14.0.0-canary.c047f7c19.0" + "@material/elevation" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/shape" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" + "@material/typography" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/top-app-bar@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/top-app-bar/-/top-app-bar-14.0.0-canary.7d8ea4624.0.tgz#8a06105d6d649105bd07bd6b0e42ee98e2a3dd7f" - integrity sha512-mSTcDEfFbzvbiiOGG9oFKFrkEGr+i/NFwL1CyJNy9rbNDp77e8wtPAABJG6Y5hcGjYyvRsKamduSjnSLHw/jZA== - dependencies: - "@material/animation" "14.0.0-canary.7d8ea4624.0" - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/elevation" "14.0.0-canary.7d8ea4624.0" - "@material/ripple" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/shape" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" - "@material/typography" "14.0.0-canary.7d8ea4624.0" +"@material/top-app-bar@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/top-app-bar/-/top-app-bar-14.0.0-canary.c047f7c19.0.tgz#5eb91022f02f74c3d8fa43aef89188d0bcbc7c8b" + integrity sha512-ZGmlpXXp2hmXrTdoRjzX7sZu29SaPRwoo9oHCqgZMQ/IaIpaXAuS42PHFP7oe+/4zmAr6UZv3q+uxMnBUJmpqQ== + dependencies: + "@material/animation" "14.0.0-canary.c047f7c19.0" + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/elevation" "14.0.0-canary.c047f7c19.0" + "@material/ripple" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/shape" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" + "@material/typography" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/touch-target@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/touch-target/-/touch-target-14.0.0-canary.7d8ea4624.0.tgz#c6b8e34fd382ad1d1022b5a95e01243e5785979d" - integrity sha512-3GAiUrzvQYxJQpmAudWL1PEgpiIYdUl3cXrIPv9aUmVttQvX4oQKfyQD+4vBIBH8/KXMq7YWbzCx2X6NdPJiyw== +"@material/touch-target@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/touch-target/-/touch-target-14.0.0-canary.c047f7c19.0.tgz#5e561ba676491ed634d583acce62ac3d86abb91f" + integrity sha512-1bh0IKCOFqB9NytQrm3SHmc8kaDWBljM9U0wA8lbsWQOtmCHDBHTKK+6Wbd7zxQZWtE/GXpoFEsl2BQjrwU9zA== dependencies: - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" -"@material/typography@14.0.0-canary.7d8ea4624.0": - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/@material/typography/-/typography-14.0.0-canary.7d8ea4624.0.tgz#acd4ebbdb0a154e46bc44cbbe4340466709c956e" - integrity sha512-iab54MYDwBpcsJEjHZwQjE9GTnP4mjb+qs/Ue2z77uDPJ1oJNp7Rlzf26zI/bQi089bK41deOcZrUiH/jtUz2w== +"@material/typography@14.0.0-canary.c047f7c19.0": + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/@material/typography/-/typography-14.0.0-canary.c047f7c19.0.tgz#0e7a8489d9a79ebef04d61fa3079eb3e70f16a00" + integrity sha512-7kBcW2v/ICcxCwXffz15TjLwZ48wGDhSIGaOCF0ABoJyHg7iOquHSqRvu0cB6z72E+ESFCiZABrTHPZ5ZyzYDQ== dependencies: - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" tslib "^2.1.0" "@microsoft/api-extractor-model@7.13.16": @@ -11028,60 +11028,60 @@ matcher@^3.0.0: dependencies: escape-string-regexp "^4.0.0" -material-components-web@14.0.0-canary.7d8ea4624.0: - version "14.0.0-canary.7d8ea4624.0" - resolved "https://registry.yarnpkg.com/material-components-web/-/material-components-web-14.0.0-canary.7d8ea4624.0.tgz#20de2b19ade7d39881a825e6ca3e7d83e0eee1fc" - integrity sha512-DCcruJ1a+Im+iMYnHcERlxo8byJ5U2+fzlrpZUIqEOLWa42lDbteOFpOFBLEfxBQpsCcNeWuraCrw4wvFNBHrA== - dependencies: - "@material/animation" "14.0.0-canary.7d8ea4624.0" - "@material/auto-init" "14.0.0-canary.7d8ea4624.0" - "@material/banner" "14.0.0-canary.7d8ea4624.0" - "@material/base" "14.0.0-canary.7d8ea4624.0" - "@material/button" "14.0.0-canary.7d8ea4624.0" - "@material/card" "14.0.0-canary.7d8ea4624.0" - "@material/checkbox" "14.0.0-canary.7d8ea4624.0" - "@material/chips" "14.0.0-canary.7d8ea4624.0" - "@material/circular-progress" "14.0.0-canary.7d8ea4624.0" - "@material/data-table" "14.0.0-canary.7d8ea4624.0" - "@material/density" "14.0.0-canary.7d8ea4624.0" - "@material/dialog" "14.0.0-canary.7d8ea4624.0" - "@material/dom" "14.0.0-canary.7d8ea4624.0" - "@material/drawer" "14.0.0-canary.7d8ea4624.0" - "@material/elevation" "14.0.0-canary.7d8ea4624.0" - "@material/fab" "14.0.0-canary.7d8ea4624.0" - "@material/feature-targeting" "14.0.0-canary.7d8ea4624.0" - "@material/floating-label" "14.0.0-canary.7d8ea4624.0" - "@material/focus-ring" "14.0.0-canary.7d8ea4624.0" - "@material/form-field" "14.0.0-canary.7d8ea4624.0" - "@material/icon-button" "14.0.0-canary.7d8ea4624.0" - "@material/image-list" "14.0.0-canary.7d8ea4624.0" - "@material/layout-grid" "14.0.0-canary.7d8ea4624.0" - "@material/line-ripple" "14.0.0-canary.7d8ea4624.0" - "@material/linear-progress" "14.0.0-canary.7d8ea4624.0" - "@material/list" "14.0.0-canary.7d8ea4624.0" - "@material/menu" "14.0.0-canary.7d8ea4624.0" - "@material/menu-surface" "14.0.0-canary.7d8ea4624.0" - "@material/notched-outline" "14.0.0-canary.7d8ea4624.0" - "@material/radio" "14.0.0-canary.7d8ea4624.0" - "@material/ripple" "14.0.0-canary.7d8ea4624.0" - "@material/rtl" "14.0.0-canary.7d8ea4624.0" - "@material/segmented-button" "14.0.0-canary.7d8ea4624.0" - "@material/select" "14.0.0-canary.7d8ea4624.0" - "@material/shape" "14.0.0-canary.7d8ea4624.0" - "@material/slider" "14.0.0-canary.7d8ea4624.0" - "@material/snackbar" "14.0.0-canary.7d8ea4624.0" - "@material/switch" "14.0.0-canary.7d8ea4624.0" - "@material/tab" "14.0.0-canary.7d8ea4624.0" - "@material/tab-bar" "14.0.0-canary.7d8ea4624.0" - "@material/tab-indicator" "14.0.0-canary.7d8ea4624.0" - "@material/tab-scroller" "14.0.0-canary.7d8ea4624.0" - "@material/textfield" "14.0.0-canary.7d8ea4624.0" - "@material/theme" "14.0.0-canary.7d8ea4624.0" - "@material/tokens" "14.0.0-canary.7d8ea4624.0" - "@material/tooltip" "14.0.0-canary.7d8ea4624.0" - "@material/top-app-bar" "14.0.0-canary.7d8ea4624.0" - "@material/touch-target" "14.0.0-canary.7d8ea4624.0" - "@material/typography" "14.0.0-canary.7d8ea4624.0" +material-components-web@14.0.0-canary.c047f7c19.0: + version "14.0.0-canary.c047f7c19.0" + resolved "https://registry.yarnpkg.com/material-components-web/-/material-components-web-14.0.0-canary.c047f7c19.0.tgz#23c2c7e82b762bc9af78c8ba1ff90fc6759f7a86" + integrity sha512-HgEmG+VAHb/o2atSDPEgukywwZ3vsiORO1oUXnb4h9LBBweQlchci8w7FawkhFI8EUoTmVajs2bFgOo38BGmjQ== + dependencies: + "@material/animation" "14.0.0-canary.c047f7c19.0" + "@material/auto-init" "14.0.0-canary.c047f7c19.0" + "@material/banner" "14.0.0-canary.c047f7c19.0" + "@material/base" "14.0.0-canary.c047f7c19.0" + "@material/button" "14.0.0-canary.c047f7c19.0" + "@material/card" "14.0.0-canary.c047f7c19.0" + "@material/checkbox" "14.0.0-canary.c047f7c19.0" + "@material/chips" "14.0.0-canary.c047f7c19.0" + "@material/circular-progress" "14.0.0-canary.c047f7c19.0" + "@material/data-table" "14.0.0-canary.c047f7c19.0" + "@material/density" "14.0.0-canary.c047f7c19.0" + "@material/dialog" "14.0.0-canary.c047f7c19.0" + "@material/dom" "14.0.0-canary.c047f7c19.0" + "@material/drawer" "14.0.0-canary.c047f7c19.0" + "@material/elevation" "14.0.0-canary.c047f7c19.0" + "@material/fab" "14.0.0-canary.c047f7c19.0" + "@material/feature-targeting" "14.0.0-canary.c047f7c19.0" + "@material/floating-label" "14.0.0-canary.c047f7c19.0" + "@material/focus-ring" "14.0.0-canary.c047f7c19.0" + "@material/form-field" "14.0.0-canary.c047f7c19.0" + "@material/icon-button" "14.0.0-canary.c047f7c19.0" + "@material/image-list" "14.0.0-canary.c047f7c19.0" + "@material/layout-grid" "14.0.0-canary.c047f7c19.0" + "@material/line-ripple" "14.0.0-canary.c047f7c19.0" + "@material/linear-progress" "14.0.0-canary.c047f7c19.0" + "@material/list" "14.0.0-canary.c047f7c19.0" + "@material/menu" "14.0.0-canary.c047f7c19.0" + "@material/menu-surface" "14.0.0-canary.c047f7c19.0" + "@material/notched-outline" "14.0.0-canary.c047f7c19.0" + "@material/radio" "14.0.0-canary.c047f7c19.0" + "@material/ripple" "14.0.0-canary.c047f7c19.0" + "@material/rtl" "14.0.0-canary.c047f7c19.0" + "@material/segmented-button" "14.0.0-canary.c047f7c19.0" + "@material/select" "14.0.0-canary.c047f7c19.0" + "@material/shape" "14.0.0-canary.c047f7c19.0" + "@material/slider" "14.0.0-canary.c047f7c19.0" + "@material/snackbar" "14.0.0-canary.c047f7c19.0" + "@material/switch" "14.0.0-canary.c047f7c19.0" + "@material/tab" "14.0.0-canary.c047f7c19.0" + "@material/tab-bar" "14.0.0-canary.c047f7c19.0" + "@material/tab-indicator" "14.0.0-canary.c047f7c19.0" + "@material/tab-scroller" "14.0.0-canary.c047f7c19.0" + "@material/textfield" "14.0.0-canary.c047f7c19.0" + "@material/theme" "14.0.0-canary.c047f7c19.0" + "@material/tokens" "14.0.0-canary.c047f7c19.0" + "@material/tooltip" "14.0.0-canary.c047f7c19.0" + "@material/top-app-bar" "14.0.0-canary.c047f7c19.0" + "@material/touch-target" "14.0.0-canary.c047f7c19.0" + "@material/typography" "14.0.0-canary.c047f7c19.0" mathml-tag-names@^2.1.3: version "2.1.3" From 6e62a0399d2b97aea6ce9cec3d29089ef354052e Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Thu, 6 Jan 2022 05:40:11 +0200 Subject: [PATCH 02/17] build: add unlisted dependencies to package.json (#24152) * Adds `@angular/platform-browser` to the `material` package.json since we have dependencies on it in a lot of modules. * Adds several missing dependencies (`animations`, `cdk`, `common`, `forms` and `platform-browser`) to the package.json in `material-experimental`. Fixes #24146. --- src/material-experimental/package.json | 5 +++++ src/material/package.json | 1 + 2 files changed, 6 insertions(+) diff --git a/src/material-experimental/package.json b/src/material-experimental/package.json index 14ee78052353..4385bc5bc2e3 100644 --- a/src/material-experimental/package.json +++ b/src/material-experimental/package.json @@ -23,7 +23,12 @@ } }, "peerDependencies": { + "@angular/animations": "0.0.0-NG", + "@angular/cdk": "0.0.0-PLACEHOLDER", "@angular/core": "0.0.0-NG", + "@angular/common": "0.0.0-NG", + "@angular/forms": "0.0.0-NG", + "@angular/platform-browser": "0.0.0-NG", "@angular/material": "0.0.0-PLACEHOLDER", "material-components-web": "0.0.0-MDC" }, diff --git a/src/material/package.json b/src/material/package.json index 49e931621e16..5f0f04f4c79d 100644 --- a/src/material/package.json +++ b/src/material/package.json @@ -49,6 +49,7 @@ "@angular/core": "0.0.0-NG", "@angular/common": "0.0.0-NG", "@angular/forms": "0.0.0-NG", + "@angular/platform-browser": "0.0.0-NG", "rxjs": "0.0.0-RXJS" }, "dependencies": { From 9b437ede4e380dade5a70e2a2c807d7f588b256c Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Thu, 6 Jan 2022 05:40:27 +0200 Subject: [PATCH 03/17] build: bump year (#24149) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Happy New Year! 🎉 --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 40cf2459805b..c24af42e203d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License -Copyright (c) 2021 Google LLC. +Copyright (c) 2022 Google LLC. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 73f5a5f7943eded609eab0ab2e1a3cc466e083c5 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Thu, 6 Jan 2022 05:40:45 +0200 Subject: [PATCH 04/17] build: add all prebuilt themes to experimental (#24142) Adds the same set of prebuilt themes to experimental as in the stable package. --- .../mdc-theming/BUILD.bazel | 39 +++++++++++++++++++ .../prebuilt/deeppurple-amber.scss | 24 ++++++++++++ .../mdc-theming/prebuilt/pink-bluegrey.scss | 24 ++++++++++++ .../mdc-theming/prebuilt/purple-green.scss | 24 ++++++++++++ src/material-experimental/package.json | 9 +++++ 5 files changed, 120 insertions(+) create mode 100644 src/material-experimental/mdc-theming/prebuilt/deeppurple-amber.scss create mode 100644 src/material-experimental/mdc-theming/prebuilt/pink-bluegrey.scss create mode 100644 src/material-experimental/mdc-theming/prebuilt/purple-green.scss diff --git a/src/material-experimental/mdc-theming/BUILD.bazel b/src/material-experimental/mdc-theming/BUILD.bazel index cb8ffe0b090b..bb7390e06214 100644 --- a/src/material-experimental/mdc-theming/BUILD.bazel +++ b/src/material-experimental/mdc-theming/BUILD.bazel @@ -6,7 +6,10 @@ filegroup( name = "mdc-theming", srcs = [ ":all_themes", + ":deeppurple_amber_prebuilt", ":indigo_pink_prebuilt", + ":pink_bluegrey_prebuilt", + ":purple_green_prebuilt", ], ) @@ -54,3 +57,39 @@ sass_binary( "//src/material-experimental/mdc-typography:all_typography", ], ) + +sass_binary( + name = "deeppurple_amber_prebuilt", + src = "prebuilt/deeppurple-amber.scss", + include_paths = [ + "external/npm/node_modules", + ], + deps = [ + ":all_themes", + "//src/material-experimental/mdc-typography:all_typography", + ], +) + +sass_binary( + name = "pink_bluegrey_prebuilt", + src = "prebuilt/pink-bluegrey.scss", + include_paths = [ + "external/npm/node_modules", + ], + deps = [ + ":all_themes", + "//src/material-experimental/mdc-typography:all_typography", + ], +) + +sass_binary( + name = "purple_green_prebuilt", + src = "prebuilt/purple-green.scss", + include_paths = [ + "external/npm/node_modules", + ], + deps = [ + ":all_themes", + "//src/material-experimental/mdc-typography:all_typography", + ], +) diff --git a/src/material-experimental/mdc-theming/prebuilt/deeppurple-amber.scss b/src/material-experimental/mdc-theming/prebuilt/deeppurple-amber.scss new file mode 100644 index 000000000000..87c14812ee2b --- /dev/null +++ b/src/material-experimental/mdc-theming/prebuilt/deeppurple-amber.scss @@ -0,0 +1,24 @@ +@use '../all-theme'; +@use '../../../material/core/core'; +@use '../../../material/core/core-theme'; +@use '../../../material/core/theming/palette'; +@use '../../../material/core/theming/theming'; +@use '../../../material/core/typography/typography'; + +// Define a theme. +$primary: theming.define-palette(palette.$deep-purple-palette); +$accent: theming.define-palette(palette.$amber-palette, A200, A100, A400); + +$theme: ( + color: theming.define-light-theme($primary, $accent), + // TODO(mmalerba): Update to `mat-mdc-typography-config()` once non-MDC components can handle + // 2018 configs. + typography: typography.define-typography-config() +); + +// Include non-theme styles for core. +@include core.core($theme); + +// Include all theme styles for the components. +@include core-theme.theme($theme); +@include all-theme.all-mdc-component-themes($theme); diff --git a/src/material-experimental/mdc-theming/prebuilt/pink-bluegrey.scss b/src/material-experimental/mdc-theming/prebuilt/pink-bluegrey.scss new file mode 100644 index 000000000000..934fc2ca9f92 --- /dev/null +++ b/src/material-experimental/mdc-theming/prebuilt/pink-bluegrey.scss @@ -0,0 +1,24 @@ +@use '../all-theme'; +@use '../../../material/core/core'; +@use '../../../material/core/core-theme'; +@use '../../../material/core/theming/palette'; +@use '../../../material/core/theming/theming'; +@use '../../../material/core/typography/typography'; + +// Define a theme. +$primary: theming.define-palette(palette.$pink-palette, 700, 500, 900); +$accent: theming.define-palette(palette.$blue-grey-palette, A200, A100, A400); + +$theme: ( + color: theming.define-dark-theme($primary, $accent), + // TODO(mmalerba): Update to `mat-mdc-typography-config()` once non-MDC components can handle + // 2018 configs. + typography: typography.define-typography-config() +); + +// Include non-theme styles for core. +@include core.core($theme); + +// Include all theme styles for the components. +@include core-theme.theme($theme); +@include all-theme.all-mdc-component-themes($theme); diff --git a/src/material-experimental/mdc-theming/prebuilt/purple-green.scss b/src/material-experimental/mdc-theming/prebuilt/purple-green.scss new file mode 100644 index 000000000000..45dc1462643b --- /dev/null +++ b/src/material-experimental/mdc-theming/prebuilt/purple-green.scss @@ -0,0 +1,24 @@ +@use '../all-theme'; +@use '../../../material/core/core'; +@use '../../../material/core/core-theme'; +@use '../../../material/core/theming/palette'; +@use '../../../material/core/theming/theming'; +@use '../../../material/core/typography/typography'; + +// Define a theme. +$primary: theming.define-palette(palette.$purple-palette, 700, 500, 800); +$accent: theming.define-palette(palette.$green-palette, A200, A100, A400); + +$theme: ( + color: theming.define-dark-theme($primary, $accent), + // TODO(mmalerba): Update to `mat-mdc-typography-config()` once non-MDC components can handle + // 2018 configs. + typography: typography.define-typography-config() +); + +// Include non-theme styles for core. +@include core.core($theme); + +// Include all theme styles for the components. +@include core-theme.theme($theme); +@include all-theme.all-mdc-component-themes($theme); diff --git a/src/material-experimental/package.json b/src/material-experimental/package.json index 4385bc5bc2e3..7bef8ffce011 100644 --- a/src/material-experimental/package.json +++ b/src/material-experimental/package.json @@ -18,6 +18,15 @@ "./mdc-theming/prebuilt/indigo-pink.css": { "style": "./mdc-theming/prebuilt/indigo-pink.css" }, + "./mdc-theming/prebuilt/deeppurple-amber.css": { + "style": "./mdc-theming/prebuilt/deeppurple-amber.css" + }, + "./mdc-theming/prebuilt/pink-bluegrey.css": { + "style": "./mdc-theming/prebuilt/pink-bluegrey.css" + }, + "./mdc-theming/prebuilt/purple-green.css": { + "style": "./mdc-theming/prebuilt/purple-green.css" + }, "./mdc-theming/prebuilt/*": { "style": "./mdc-theming/prebuilt/*.css" } From d93d9a3ae08330d9ab22abf57500396c9b10963a Mon Sep 17 00:00:00 2001 From: Pei Wang Date: Thu, 6 Jan 2022 06:59:47 -0800 Subject: [PATCH 05/17] ci: Add tsec_test for all ng_module targets. (#24066) * ci: Add tsec_test for all ng_module targets. Instead of modifying ~250 BUILD.bazel files, instrument the ng_module macro to conveniently create tsec_test for all modules. The ts_library macro is not instrumented since most of them are about testing, schematics and examples, which are not relevant to XSS. For those that are indeed security sensitive, tsec_test is manually added into individual BUILD.bazel files. * fixup! ci: Add tsec_test for all ng_module targets. * fixup! ci: Add tsec_test for all ng_module targets. --- goldens/BUILD.bazel | 1 + goldens/tsec-exemption.json | 17 +++++++++++++++++ package.json | 2 ++ src/BUILD.bazel | 9 +++++++++ src/cdk/a11y/focus-monitor/focus-monitor.ts | 2 +- .../mdc-chips/chip-row.ts | 2 +- src/tsconfig-tsec.json | 9 +++++++++ tools/defaults.bzl | 18 ++++++++++++++++++ yarn.lock | 10 +++++++++- 9 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 goldens/tsec-exemption.json create mode 100644 src/tsconfig-tsec.json diff --git a/goldens/BUILD.bazel b/goldens/BUILD.bazel index e8a75f0d5692..16bac4c0e639 100644 --- a/goldens/BUILD.bazel +++ b/goldens/BUILD.bazel @@ -1,3 +1,4 @@ exports_files([ "size-test.yaml", + "tsec-exemption.json", ]) diff --git a/goldens/tsec-exemption.json b/goldens/tsec-exemption.json new file mode 100644 index 000000000000..17bc2283c356 --- /dev/null +++ b/goldens/tsec-exemption.json @@ -0,0 +1,17 @@ +{ + "ban-trustedtypes-createpolicy": [ + "../src/material/icon/trusted-types.ts" + ], + "ban-element-innerhtml-assignments": [ + "../src/material/icon/icon-registry.ts" + ], + "ban-element-setattribute": [ + "../src/cdk/a11y/aria-describer/aria-reference.ts", + "../src/material-experimental/mdc-checkbox/checkbox.ts", + "../src/material-experimental/mdc-list/interactive-list-base.ts", + "../src/material-experimental/mdc-progress-spinner/progress-spinner.ts", + "../src/material-experimental/mdc-slide-toggle/slide-toggle.ts", + "../src/material/icon/icon-registry.ts", + "../src/material/icon/icon.ts" + ] +} diff --git a/package.json b/package.json index b0c6d67d34f2..cb0d40011277 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "test": "node ./scripts/run-component-tests.js", "test-local": "yarn -s test --local", "test-firefox": "yarn -s test --firefox", + "test-tsec": "yarn bazelisk test //... --build_tag_filters=tsec --test_tag_filters=tsec", "lint": "yarn -s tslint && yarn -s stylelint && yarn -s ownerslint && yarn -s ng-dev format changed --check", "e2e": "bazel test //src/... --build_tag_filters=e2e --test_tag_filters=e2e --build_tests_only", "deploy-dev-app": "node ./scripts/deploy-dev-app.js", @@ -211,6 +212,7 @@ "stylelint": "^14.0.1", "terser": "^5.9.0", "ts-node": "^10.2.1", + "tsec": "0.2.1", "tsickle": "0.39.1", "tslint": "^6.1.3", "tsutils": "^3.21.0", diff --git a/src/BUILD.bazel b/src/BUILD.bazel index d84776afa83c..5bd9ad3bf60e 100644 --- a/src/BUILD.bazel +++ b/src/BUILD.bazel @@ -49,3 +49,12 @@ ts_library( name = "dev_mode_types", srcs = ["dev-mode-types.d.ts"], ) + +ts_config( + name = "tsec_config", + src = "tsconfig-tsec.json", + deps = [ + ":bazel-tsconfig-build.json", + "//goldens:tsec-exemption.json", + ], +) diff --git a/src/cdk/a11y/focus-monitor/focus-monitor.ts b/src/cdk/a11y/focus-monitor/focus-monitor.ts index 4b827bf0e731..fe7b50acaf54 100644 --- a/src/cdk/a11y/focus-monitor/focus-monitor.ts +++ b/src/cdk/a11y/focus-monitor/focus-monitor.ts @@ -134,7 +134,7 @@ export class FocusMonitor implements OnDestroy { // Make a note of when the window regains focus, so we can // restore the origin info for the focused element. this._windowFocused = true; - this._windowFocusTimeoutId = setTimeout(() => (this._windowFocused = false)); + this._windowFocusTimeoutId = window.setTimeout(() => (this._windowFocused = false)); }; /** Used to reference correct document/window */ diff --git a/src/material-experimental/mdc-chips/chip-row.ts b/src/material-experimental/mdc-chips/chip-row.ts index b811863c02b4..08c57d940136 100644 --- a/src/material-experimental/mdc-chips/chip-row.ts +++ b/src/material-experimental/mdc-chips/chip-row.ts @@ -167,7 +167,7 @@ export class MatChipRow } // Wait to see if focus moves to the other gridcell - this._focusoutTimeout = setTimeout(() => { + this._focusoutTimeout = window.setTimeout(() => { this._hasFocusInternal = false; this._onBlur.next({chip: this}); this._handleInteraction(event); diff --git a/src/tsconfig-tsec.json b/src/tsconfig-tsec.json new file mode 100644 index 000000000000..e397df4d2315 --- /dev/null +++ b/src/tsconfig-tsec.json @@ -0,0 +1,9 @@ +{ + "extends": "./bazel-tsconfig-build.json", + "compilerOptions": { + "plugins": [ + {"name": "tsec", "exemptionConfig": "../goldens/tsec-exemption.json"} + ] + } +} + diff --git a/tools/defaults.bzl b/tools/defaults.bzl index 14a2ee33b646..853cfd4c4fea 100644 --- a/tools/defaults.bzl +++ b/tools/defaults.bzl @@ -12,6 +12,7 @@ load("@npm//@bazel/jasmine:index.bzl", _jasmine_node_test = "jasmine_node_test") load("@npm//@bazel/concatjs:index.bzl", _karma_web_test = "karma_web_test", _karma_web_test_suite = "karma_web_test_suite") load("@npm//@bazel/protractor:index.bzl", _protractor_web_test_suite = "protractor_web_test_suite") load("@npm//@bazel/typescript:index.bzl", _ts_library = "ts_library") +load("@npm//tsec:index.bzl", _tsec_test = "tsec_test") load("//:packages.bzl", "NO_STAMP_NPM_PACKAGE_SUBSTITUTIONS", "NPM_PACKAGE_SUBSTITUTIONS") load("//:pkg-externals.bzl", "PKG_EXTERNALS") load("//tools/markdown-to-html:index.bzl", _markdown_to_html = "markdown_to_html") @@ -31,6 +32,17 @@ integration_test = _integration_test esbuild = _esbuild esbuild_config = _esbuild_config +def _make_tsec_test(target): + package_name = native.package_name() + if not package_name.startswith("src/components-examples") and \ + not package_name.endswith("/testing") and \ + not package_name.endswith("/schematics"): + _tsec_test( + name = target + "_tsec_test", + target = target, + tsconfig = "//src:tsec_config", + ) + def _compute_module_name(testonly): current_pkg = native.package_name() @@ -109,6 +121,9 @@ def ts_library( **kwargs ) + if module_name and not testonly: + _make_tsec_test(kwargs["name"]) + def ng_module( deps = [], srcs = [], @@ -147,6 +162,9 @@ def ng_module( **kwargs ) + if module_name and not testonly: + _make_tsec_test(kwargs["name"]) + def ng_package(name, data = [], deps = [], externals = PKG_EXTERNALS, readme_md = None, visibility = None, **kwargs): # If no readme file has been specified explicitly, use the default readme for # release packages from "src/README.md". diff --git a/yarn.lock b/yarn.lock index d617ba351be0..f6e0afc7c154 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11272,7 +11272,7 @@ minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.4: +"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -15658,6 +15658,14 @@ ts-node@^10.2.1: make-error "^1.1.1" yn "3.1.1" +tsec@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tsec/-/tsec-0.2.1.tgz#017423174b2be54f26da5cb7591dc7035996086b" + integrity sha512-RP9vhbRbRI9VH4CfOlQvo5W9HdfiPKq0gdiUOWI5oKmLaZKNFN8CsPwBfT5ySmhnKNwmmAS/BtY3WoTfABwwig== + dependencies: + glob "^7.1.1" + minimatch "^3.0.3" + tsickle@0.39.1: version "0.39.1" resolved "https://registry.yarnpkg.com/tsickle/-/tsickle-0.39.1.tgz#7ccf672cde5b430f5dd0b281ee49e170ef390ff9" From a6d21a1ae9925d40646a24c5d7d2234a6c2c13b9 Mon Sep 17 00:00:00 2001 From: Jeri Peier Date: Thu, 6 Jan 2022 16:00:40 +0100 Subject: [PATCH 06/17] fix(cdk/overlay): fix positioning when zooming in Safari (#24160) Currently, when zooming in Safari in macOS and iOS the overlay is positioned at the wrong place, offset by the zoom offset (left/top). This fix corrects this by adding/subtracting the corresponding offset. --- ...exible-connected-position-strategy.spec.ts | 40 +++++++++++++++ .../flexible-connected-position-strategy.ts | 49 ++++++++++++------- 2 files changed, 72 insertions(+), 17 deletions(-) diff --git a/src/cdk/overlay/position/flexible-connected-position-strategy.spec.ts b/src/cdk/overlay/position/flexible-connected-position-strategy.spec.ts index c13f6502583d..d9014316a338 100644 --- a/src/cdk/overlay/position/flexible-connected-position-strategy.spec.ts +++ b/src/cdk/overlay/position/flexible-connected-position-strategy.spec.ts @@ -164,6 +164,46 @@ describe('FlexibleConnectedPositionStrategy', () => { originElement.remove(); }); + it('should calculate position with simulated zoom in Safari', () => { + let containerElement = overlayContainer.getContainerElement(); + spyOn(containerElement, 'getBoundingClientRect').and.returnValue({ + top: -200, + bottom: 900, + left: -200, + right: 100, + width: 100, + height: 100, + } as DOMRect); + + const originElement = createPositionedBlockElement(); + document.body.appendChild(originElement); + + // Position the element so it would have enough space to fit. + originElement.style.top = '200px'; + originElement.style.left = '70px'; + + attachOverlay({ + positionStrategy: overlay + .position() + .flexibleConnectedTo(originElement) + .withFlexibleDimensions(false) + .withPush(false) + .withPositions([ + { + originX: 'start', + originY: 'top', + overlayX: 'start', + overlayY: 'top', + }, + ]), + }); + + expect(getComputedStyle(overlayRef.overlayElement).left).toBe('270px'); + expect(getComputedStyle(overlayRef.overlayElement).top).toBe('400px'); + + originElement.remove(); + }); + it('should clean up after itself when disposed', () => { const origin = document.createElement('div'); const positionStrategy = overlay diff --git a/src/cdk/overlay/position/flexible-connected-position-strategy.ts b/src/cdk/overlay/position/flexible-connected-position-strategy.ts index 636efcc08756..df943e0d39cf 100644 --- a/src/cdk/overlay/position/flexible-connected-position-strategy.ts +++ b/src/cdk/overlay/position/flexible-connected-position-strategy.ts @@ -85,6 +85,9 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy { /** Cached viewport dimensions */ private _viewportRect: Dimensions; + /** Cached container dimensions */ + private _containerRect: Dimensions; + /** Amount of space that must be maintained between the overlay and the edge of the viewport. */ private _viewportMargin = 0; @@ -213,16 +216,18 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy { this._resetOverlayElementStyles(); this._resetBoundingBoxStyles(); - // We need the bounding rects for the origin and the overlay to determine how to position + // We need the bounding rects for the origin, the overlay and the container to determine how to position // the overlay relative to the origin. // We use the viewport rect to determine whether a position would go off-screen. this._viewportRect = this._getNarrowedViewportRect(); this._originRect = this._getOriginRect(); this._overlayRect = this._pane.getBoundingClientRect(); + this._containerRect = this._overlayContainer.getContainerElement().getBoundingClientRect(); const originRect = this._originRect; const overlayRect = this._overlayRect; const viewportRect = this._viewportRect; + const containerRect = this._containerRect; // Positions where the overlay will fit with flexible dimensions. const flexibleFits: FlexibleFit[] = []; @@ -234,7 +239,7 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy { // If a good fit is found, it will be applied immediately. for (let pos of this._preferredPositions) { // Get the exact (x, y) coordinate for the point-of-origin on the origin element. - let originPoint = this._getOriginPoint(originRect, pos); + let originPoint = this._getOriginPoint(originRect, containerRect, pos); // From that point-of-origin, get the exact (x, y) coordinate for the top-left corner of the // overlay in this position. We use the top-left corner for calculations and later translate @@ -359,9 +364,10 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy { this._originRect = this._getOriginRect(); this._overlayRect = this._pane.getBoundingClientRect(); this._viewportRect = this._getNarrowedViewportRect(); + this._containerRect = this._overlayContainer.getContainerElement().getBoundingClientRect(); const lastPosition = this._lastPosition || this._preferredPositions[0]; - const originPoint = this._getOriginPoint(this._originRect, lastPosition); + const originPoint = this._getOriginPoint(this._originRect, this._containerRect, lastPosition); this._applyPosition(lastPosition, originPoint); } @@ -479,7 +485,11 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy { /** * Gets the (x, y) coordinate of a connection point on the origin based on a relative position. */ - private _getOriginPoint(originRect: Dimensions, pos: ConnectedPosition): Point { + private _getOriginPoint( + originRect: Dimensions, + containerRect: Dimensions, + pos: ConnectedPosition, + ): Point { let x: number; if (pos.originX == 'center') { // Note: when centering we should always use the `left` @@ -491,6 +501,12 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy { x = pos.originX == 'start' ? startX : endX; } + // When zooming in Safari the container rectangle contains negative values for the position + // and we need to re-add them to the calculated coordinates. + if (containerRect.left < 0) { + x -= containerRect.left; + } + let y: number; if (pos.originY == 'center') { y = originRect.top + originRect.height / 2; @@ -498,6 +514,15 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy { y = pos.originY == 'top' ? originRect.top : originRect.bottom; } + // Normally the containerRect's top value would be zero, however when the overlay is attached to an input + // (e.g. in an autocomplete), mobile browsers will shift everything in order to put the input in the middle + // of the screen and to make space for the virtual keyboard. We need to account for this offset, + // otherwise our positioning will be thrown off. + // Additionally, when zooming in Safari this fixes the vertical position. + if (containerRect.top < 0) { + y -= containerRect.top; + } + return {x, y}; } @@ -580,7 +605,7 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy { /** * Whether the overlay can fit within the viewport when it may resize either its width or height. * @param fit How well the overlay fits in the viewport at some position. - * @param point The (x, y) coordinates of the overlat at some position. + * @param point The (x, y) coordinates of the overlay at some position. * @param viewport The geometry of the viewport. */ private _canFitWithFlexibleDimensions(fit: OverlayFit, point: Point, viewport: Dimensions) { @@ -606,7 +631,7 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy { * right and bottom). * * @param start Starting point from which the overlay is pushed. - * @param overlay Dimensions of the overlay. + * @param rawOverlayRect Dimensions of the overlay. * @param scrollPosition Current viewport scroll position. * @returns The point at which to position the overlay after pushing. This is effectively a new * originPoint. @@ -958,16 +983,6 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy { overlayPoint = this._pushOverlayOnScreen(overlayPoint, this._overlayRect, scrollPosition); } - let virtualKeyboardOffset = this._overlayContainer - .getContainerElement() - .getBoundingClientRect().top; - - // Normally this would be zero, however when the overlay is attached to an input (e.g. in an - // autocomplete), mobile browsers will shift everything in order to put the input in the middle - // of the screen and to make space for the virtual keyboard. We need to account for this offset, - // otherwise our positioning will be thrown off. - overlayPoint.y -= virtualKeyboardOffset; - // We want to set either `top` or `bottom` based on whether the overlay wants to appear // above or below the origin and the direction in which the element will expand. if (position.overlayY === 'bottom') { @@ -1183,7 +1198,7 @@ interface OverlayFit { visibleArea: number; } -/** Record of the measurments determining whether an overlay will fit in a specific position. */ +/** Record of the measurements determining whether an overlay will fit in a specific position. */ interface FallbackPosition { position: ConnectedPosition; originPoint: Point; From 93e09c62f4b9dfdbfa63db3f4bea2a2d91575080 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Thu, 6 Jan 2022 17:01:14 +0200 Subject: [PATCH 07/17] fix(cdk/text-field): handle undefined placeholder (#24159) Fixes that the string "undefined" would be used as the placeholder of an autosize `textarea` if the value is `undefined`. Fixes #24154. --- src/cdk/text-field/autosize.spec.ts | 7 +++++++ src/cdk/text-field/autosize.ts | 8 +++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/cdk/text-field/autosize.spec.ts b/src/cdk/text-field/autosize.spec.ts index 66877cf9be9a..eabb88228f97 100644 --- a/src/cdk/text-field/autosize.spec.ts +++ b/src/cdk/text-field/autosize.spec.ts @@ -373,6 +373,13 @@ describe('CdkTextareaAutosize', () => { .withContext('Expected textarea to have a scrollbar.') .toBeLessThan(textarea.scrollHeight); })); + + it('should handle an undefined placeholder', () => { + fixture.componentInstance.placeholder = undefined!; + fixture.detectChanges(); + + expect(textarea.hasAttribute('placeholder')).toBe(false); + }); }); // Styles to reset padding and border to make measurement comparisons easier. diff --git a/src/cdk/text-field/autosize.ts b/src/cdk/text-field/autosize.ts index 3170259f2d64..f07bf93bbddd 100644 --- a/src/cdk/text-field/autosize.ts +++ b/src/cdk/text-field/autosize.ts @@ -100,7 +100,13 @@ export class CdkTextareaAutosize implements AfterViewInit, DoCheck, OnDestroy { } set placeholder(value: string) { this._cachedPlaceholderHeight = undefined; - this._textareaElement.placeholder = value; + + if (value) { + this._textareaElement.setAttribute('placeholder', value); + } else { + this._textareaElement.removeAttribute('placeholder'); + } + this._cacheTextareaPlaceholderHeight(); } From 2d571af190165fde756cf139270710b7ffe32685 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Thu, 6 Jan 2022 17:03:42 +0200 Subject: [PATCH 08/17] fix(material/stepper): icon not centered in header if direction changes (#24131) Fixes that the icon in the step header was being rendered outside of the circle of the page direction changes. This seems to be a browser rendering issue due to the fact that we were applying a `position: absolute` and a `transform` both on the icon and its parent. Since this is unnecessary, I've removed the styles from the icon and added an extra `display: flex` to fix the centering. Fixes #24046. --- src/material/stepper/step-header.scss | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/material/stepper/step-header.scss b/src/material/stepper/step-header.scss index fde2dce109ac..a8387279b2e1 100644 --- a/src/material/stepper/step-header.scss +++ b/src/material/stepper/step-header.scss @@ -37,13 +37,16 @@ position: relative; } -.mat-step-icon-content, -.mat-step-icon .mat-icon { +.mat-step-icon-content { // Use absolute positioning to center the content, because it works better with text. position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); + + // We aren't using any flex features here, but using the `display: flex` prevents + // the browser from adding extra whitespace at the bottom of the element. + display: flex; } .mat-step-icon .mat-icon { From b0d9b251f0fa72c99634b651b621452927883586 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Thu, 6 Jan 2022 17:28:14 +0200 Subject: [PATCH 09/17] refactor(cdk/testing): reuse stabilize callback when creating test element (#24094) Any time we were creating a new test element, we were giving it a new stabilization callback. These changes reuse the same one between all elements in order to reduce the amount of memory for each element. --- src/cdk/testing/harness-environment.ts | 13 +++++++++---- .../selenium-web-driver-harness-environment.ts | 6 +++++- .../testing/testbed/testbed-harness-environment.ts | 6 +++++- tools/public_api_guard/cdk/testing.md | 3 ++- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/cdk/testing/harness-environment.ts b/src/cdk/testing/harness-environment.ts index e744da638ae7..cb2ea81521aa 100644 --- a/src/cdk/testing/harness-environment.ts +++ b/src/cdk/testing/harness-environment.ts @@ -45,11 +45,16 @@ type ParsedQueries = { */ export abstract class HarnessEnvironment implements HarnessLoader, LocatorFactory { // Implemented as part of the `LocatorFactory` interface. - rootElement: TestElement; - - protected constructor(protected rawRootElement: E) { - this.rootElement = this.createTestElement(rawRootElement); + get rootElement(): TestElement { + this._rootElement = this._rootElement || this.createTestElement(this.rawRootElement); + return this._rootElement; + } + set rootElement(element: TestElement) { + this._rootElement = element; } + private _rootElement: TestElement | undefined; + + protected constructor(protected rawRootElement: E) {} // Implemented as part of the `LocatorFactory` interface. documentRootLocatorFactory(): LocatorFactory { diff --git a/src/cdk/testing/selenium-webdriver/selenium-web-driver-harness-environment.ts b/src/cdk/testing/selenium-webdriver/selenium-web-driver-harness-environment.ts index 4c50f14ab00d..28f62408fbec 100644 --- a/src/cdk/testing/selenium-webdriver/selenium-web-driver-harness-environment.ts +++ b/src/cdk/testing/selenium-webdriver/selenium-web-driver-harness-environment.ts @@ -74,12 +74,16 @@ export class SeleniumWebDriverHarnessEnvironment extends HarnessEnvironment< /** The options for this environment. */ private _options: WebDriverHarnessEnvironmentOptions; + /** Environment stabilization callback passed to the created test elements. */ + private _stabilizeCallback: () => Promise; + protected constructor( rawRootElement: () => webdriver.WebElement, options?: WebDriverHarnessEnvironmentOptions, ) { super(rawRootElement); this._options = {...defaultEnvironmentOptions, ...options}; + this._stabilizeCallback = () => this.forceStabilize(); } /** Gets the ElementFinder corresponding to the given TestElement. */ @@ -123,7 +127,7 @@ export class SeleniumWebDriverHarnessEnvironment extends HarnessEnvironment< /** Creates a `TestElement` from a raw element. */ protected createTestElement(element: () => webdriver.WebElement): TestElement { - return new SeleniumWebDriverElement(element, () => this.forceStabilize()); + return new SeleniumWebDriverElement(element, this._stabilizeCallback); } /** Creates a `HarnessLoader` rooted at the given raw element. */ diff --git a/src/cdk/testing/testbed/testbed-harness-environment.ts b/src/cdk/testing/testbed/testbed-harness-environment.ts index 5378a2949a71..60f061853dc4 100644 --- a/src/cdk/testing/testbed/testbed-harness-environment.ts +++ b/src/cdk/testing/testbed/testbed-harness-environment.ts @@ -96,6 +96,9 @@ export class TestbedHarnessEnvironment extends HarnessEnvironment { /** The options for this environment. */ private _options: TestbedHarnessEnvironmentOptions; + /** Environment stabilization callback passed to the created test elements. */ + private _stabilizeCallback: () => Promise; + protected constructor( rawRootElement: Element, private _fixture: ComponentFixture, @@ -104,6 +107,7 @@ export class TestbedHarnessEnvironment extends HarnessEnvironment { super(rawRootElement); this._options = {...defaultEnvironmentOptions, ...options}; this._taskState = TaskStateZoneInterceptor.setup(); + this._stabilizeCallback = () => this.forceStabilize(); installAutoChangeDetectionStatusHandler(_fixture); _fixture.componentRef.onDestroy(() => { uninstallAutoChangeDetectionStatusHandler(_fixture); @@ -198,7 +202,7 @@ export class TestbedHarnessEnvironment extends HarnessEnvironment { /** Creates a `TestElement` from a raw element. */ protected createTestElement(element: Element): TestElement { - return new UnitTestElement(element, () => this.forceStabilize()); + return new UnitTestElement(element, this._stabilizeCallback); } /** Creates a `HarnessLoader` rooted at the given raw element. */ diff --git a/tools/public_api_guard/cdk/testing.md b/tools/public_api_guard/cdk/testing.md index 954a3e4de266..3d7a0ad36201 100644 --- a/tools/public_api_guard/cdk/testing.md +++ b/tools/public_api_guard/cdk/testing.md @@ -117,7 +117,8 @@ export abstract class HarnessEnvironment implements HarnessLoader, LocatorFac // (undocumented) protected rawRootElement: E; // (undocumented) - rootElement: TestElement; + get rootElement(): TestElement; + set rootElement(element: TestElement); // (undocumented) rootHarnessLoader(): Promise; // (undocumented) From 41320064dd4343e772c02005a71df518ddf939ee Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Fri, 7 Jan 2022 06:41:54 +0200 Subject: [PATCH 10/17] fix(cdk/schematics): remove file extensions in tilde migration (#24169) Expands the tilde migration to also drop the `.scss` file extensions. Fixes #24162. --- .../tilde-import-migration.ts | 9 ++++---- .../v13/misc/tilde-import-v13.spec.ts | 22 +++++++++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/cdk/schematics/ng-update/migrations/tilde-import-v13/tilde-import-migration.ts b/src/cdk/schematics/ng-update/migrations/tilde-import-v13/tilde-import-migration.ts index 671a1a8d08bd..3a6fe74917d4 100644 --- a/src/cdk/schematics/ng-update/migrations/tilde-import-v13/tilde-import-migration.ts +++ b/src/cdk/schematics/ng-update/migrations/tilde-import-v13/tilde-import-migration.ts @@ -21,10 +21,11 @@ export class TildeImportMigration extends DevkitMigration { if (extension === '.scss' || extension === '.css') { const content = stylesheet.content; const migratedContent = content.replace( - /@(?:import|use) +['"]~@angular\/.*['"].*;?/g, - match => { - const index = match.indexOf('~@angular'); - return match.slice(0, index) + match.slice(index + 1); + /@(?:import|use) +['"](~@angular\/.*)['"].*;?/g, + (match, importPath) => { + const index = match.indexOf(importPath); + const newImportPath = importPath.replace(/^~|\.scss$/g, ''); + return match.slice(0, index) + newImportPath + match.slice(index + importPath.length); }, ); diff --git a/src/cdk/schematics/ng-update/test-cases/v13/misc/tilde-import-v13.spec.ts b/src/cdk/schematics/ng-update/test-cases/v13/misc/tilde-import-v13.spec.ts index d831eaf148ff..360dd588a877 100644 --- a/src/cdk/schematics/ng-update/test-cases/v13/misc/tilde-import-v13.spec.ts +++ b/src/cdk/schematics/ng-update/test-cases/v13/misc/tilde-import-v13.spec.ts @@ -124,4 +124,26 @@ describe('v13 tilde import migration', () => { `@include mat-core();`, ]); }); + + it('should remove remove .scss file extension', async () => { + writeLines(TEST_PATH, [ + `@use '~@angular/material.scss' as mat;`, + `@import '~@angular/material/theming.scss';`, + `@import '~@angular/cdk/overlay-prebuilt.css';`, + + `@include mat.button-theme();`, + `@include mat-core();`, + ]); + + await runMigration(); + + expect(splitFile(TEST_PATH)).toEqual([ + `@use '@angular/material' as mat;`, + `@import '@angular/material/theming';`, + `@import '@angular/cdk/overlay-prebuilt.css';`, + + `@include mat.button-theme();`, + `@include mat-core();`, + ]); + }); }); From 1dd2955c1af3a779881a1c7bac68389009759806 Mon Sep 17 00:00:00 2001 From: Zach Arend Date: Thu, 6 Jan 2022 20:42:56 -0800 Subject: [PATCH 11/17] build: add .vimrc to gitignore (#24168) Adds .vimrc and .nvrc to the .gitignore file. This aligns components with how angular/angular does it https://github.com/angular/angular/blob/master/.gitignore. --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index ce0991dfb3e0..2a71b14567d2 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,8 @@ node_modules /.vs *.swo *.swp +.vimrc +.nvimrc # misc .DS_Store From ea78a473a17e0b5c23936af7772914f9db8cd058 Mon Sep 17 00:00:00 2001 From: Zack Elliott <4220717+zelliott@users.noreply.github.com> Date: Fri, 7 Jan 2022 08:46:09 -0800 Subject: [PATCH 12/17] feat(material/tabs): Refactor MatTabNav to follow the ARIA tabs pattern (#24062) by introducing a new tabpanel component. --- .../material/tabs/index.ts | 3 + .../tab-nav-bar-with-panel-example.css | 4 + .../tab-nav-bar-with-panel-example.html | 9 ++ .../tab-nav-bar-with-panel-example.ts | 14 ++ src/dev-app/mdc-tabs/mdc-tabs-demo.html | 9 ++ src/dev-app/tabs/tabs-demo.html | 4 +- src/material-experimental/mdc-tabs/module.ts | 4 +- .../mdc-tabs/public-api.ts | 2 +- .../mdc-tabs/tab-nav-bar/tab-nav-bar.spec.ts | 143 +++++++++++++++++- .../mdc-tabs/tab-nav-bar/tab-nav-bar.ts | 37 ++++- .../mdc-tabs/testing/tab-harness-filters.ts | 3 + .../mdc-tabs/testing/tab-nav-bar-harness.ts | 20 ++- .../mdc-tabs/testing/tab-nav-panel-harness.ts | 31 ++++ src/material/tabs/public-api.ts | 8 +- .../tabs/tab-nav-bar/tab-nav-bar.spec.ts | 143 +++++++++++++++++- src/material/tabs/tab-nav-bar/tab-nav-bar.ts | 95 +++++++++++- src/material/tabs/tabs-module.ts | 4 +- .../tabs/testing/tab-harness-filters.ts | 3 + .../tabs/testing/tab-nav-bar-harness.ts | 20 ++- .../tabs/testing/tab-nav-bar-shared.spec.ts | 11 +- .../tabs/testing/tab-nav-panel-harness.ts | 31 ++++ .../public_api_guard/material/tabs-testing.md | 5 + tools/public_api_guard/material/tabs.md | 33 +++- 23 files changed, 618 insertions(+), 18 deletions(-) create mode 100644 src/components-examples/material/tabs/tab-nav-bar-with-panel/tab-nav-bar-with-panel-example.css create mode 100644 src/components-examples/material/tabs/tab-nav-bar-with-panel/tab-nav-bar-with-panel-example.html create mode 100644 src/components-examples/material/tabs/tab-nav-bar-with-panel/tab-nav-bar-with-panel-example.ts create mode 100644 src/material-experimental/mdc-tabs/testing/tab-nav-panel-harness.ts create mode 100644 src/material/tabs/testing/tab-nav-panel-harness.ts diff --git a/src/components-examples/material/tabs/index.ts b/src/components-examples/material/tabs/index.ts index 6190a8240f2a..cb5279b3487b 100644 --- a/src/components-examples/material/tabs/index.ts +++ b/src/components-examples/material/tabs/index.ts @@ -20,6 +20,7 @@ import {TabGroupLazyLoadedExample} from './tab-group-lazy-loaded/tab-group-lazy- import {TabGroupStretchedExample} from './tab-group-stretched/tab-group-stretched-example'; import {TabGroupThemeExample} from './tab-group-theme/tab-group-theme-example'; import {TabNavBarBasicExample} from './tab-nav-bar-basic/tab-nav-bar-basic-example'; +import {TabNavBarWithPanelExample} from './tab-nav-bar-with-panel/tab-nav-bar-with-panel-example'; export { TabGroupAlignExample, @@ -35,6 +36,7 @@ export { TabGroupStretchedExample, TabGroupThemeExample, TabNavBarBasicExample, + TabNavBarWithPanelExample, }; const EXAMPLES = [ @@ -51,6 +53,7 @@ const EXAMPLES = [ TabGroupStretchedExample, TabGroupThemeExample, TabNavBarBasicExample, + TabNavBarWithPanelExample, ]; @NgModule({ diff --git a/src/components-examples/material/tabs/tab-nav-bar-with-panel/tab-nav-bar-with-panel-example.css b/src/components-examples/material/tabs/tab-nav-bar-with-panel/tab-nav-bar-with-panel-example.css new file mode 100644 index 000000000000..e7f8daa5cd3b --- /dev/null +++ b/src/components-examples/material/tabs/tab-nav-bar-with-panel/tab-nav-bar-with-panel-example.css @@ -0,0 +1,4 @@ +.example-action-button { + margin-top: 8px; + margin-right: 8px; +} diff --git a/src/components-examples/material/tabs/tab-nav-bar-with-panel/tab-nav-bar-with-panel-example.html b/src/components-examples/material/tabs/tab-nav-bar-with-panel/tab-nav-bar-with-panel-example.html new file mode 100644 index 000000000000..1ab8a3c4da0f --- /dev/null +++ b/src/components-examples/material/tabs/tab-nav-bar-with-panel/tab-nav-bar-with-panel-example.html @@ -0,0 +1,9 @@ + + + + diff --git a/src/components-examples/material/tabs/tab-nav-bar-with-panel/tab-nav-bar-with-panel-example.ts b/src/components-examples/material/tabs/tab-nav-bar-with-panel/tab-nav-bar-with-panel-example.ts new file mode 100644 index 000000000000..b7beb7ae2e2f --- /dev/null +++ b/src/components-examples/material/tabs/tab-nav-bar-with-panel/tab-nav-bar-with-panel-example.ts @@ -0,0 +1,14 @@ +import {Component} from '@angular/core'; + +/** + * @title Use of the tab nav bar with the dedicated panel component. + */ +@Component({ + selector: 'tab-nav-bar-with-panel-example', + templateUrl: 'tab-nav-bar-with-panel-example.html', + styleUrls: ['tab-nav-bar-with-panel-example.css'], +}) +export class TabNavBarWithPanelExample { + links = ['First', 'Second', 'Third']; + activeLink = this.links[0]; +} diff --git a/src/dev-app/mdc-tabs/mdc-tabs-demo.html b/src/dev-app/mdc-tabs/mdc-tabs-demo.html index 70156eec4d1c..daddf891f4f1 100644 --- a/src/dev-app/mdc-tabs/mdc-tabs-demo.html +++ b/src/dev-app/mdc-tabs/mdc-tabs-demo.html @@ -127,4 +127,13 @@

Tab nav bar

[active]="activeLink == link">{{link}} Disabled Link + +

Tab nav bar with panel

+ +
diff --git a/src/dev-app/tabs/tabs-demo.html b/src/dev-app/tabs/tabs-demo.html index 52d62976e2a8..9531a56be77a 100644 --- a/src/dev-app/tabs/tabs-demo.html +++ b/src/dev-app/tabs/tabs-demo.html @@ -18,5 +18,7 @@

Tab group stretched

Tab group theming

-

Tab Navigation Bar basic

+

Tab navigation bar basic

+

Tab navigation bar with panel

+ diff --git a/src/material-experimental/mdc-tabs/module.ts b/src/material-experimental/mdc-tabs/module.ts index 2398beea8cbe..43dec04f334f 100644 --- a/src/material-experimental/mdc-tabs/module.ts +++ b/src/material-experimental/mdc-tabs/module.ts @@ -19,7 +19,7 @@ import {MatTabLabelWrapper} from './tab-label-wrapper'; import {MatTab} from './tab'; import {MatTabHeader} from './tab-header'; import {MatTabGroup} from './tab-group'; -import {MatTabNav, MatTabLink} from './tab-nav-bar/tab-nav-bar'; +import {MatTabNav, MatTabNavPanel, MatTabLink} from './tab-nav-bar/tab-nav-bar'; @NgModule({ imports: [ @@ -37,6 +37,7 @@ import {MatTabNav, MatTabLink} from './tab-nav-bar/tab-nav-bar'; MatTab, MatTabGroup, MatTabNav, + MatTabNavPanel, MatTabLink, ], declarations: [ @@ -45,6 +46,7 @@ import {MatTabNav, MatTabLink} from './tab-nav-bar/tab-nav-bar'; MatTab, MatTabGroup, MatTabNav, + MatTabNavPanel, MatTabLink, // Private directives, should not be exported. diff --git a/src/material-experimental/mdc-tabs/public-api.ts b/src/material-experimental/mdc-tabs/public-api.ts index 4e6b1629af0e..6d05b9539377 100644 --- a/src/material-experimental/mdc-tabs/public-api.ts +++ b/src/material-experimental/mdc-tabs/public-api.ts @@ -15,7 +15,7 @@ export {MatTab} from './tab'; export {MatInkBar} from './ink-bar'; export {MatTabHeader} from './tab-header'; export {MatTabGroup} from './tab-group'; -export {MatTabNav, MatTabLink} from './tab-nav-bar/tab-nav-bar'; +export {MatTabNav, MatTabNavPanel, MatTabLink} from './tab-nav-bar/tab-nav-bar'; export { MatTabBodyPositionState, diff --git a/src/material-experimental/mdc-tabs/tab-nav-bar/tab-nav-bar.spec.ts b/src/material-experimental/mdc-tabs/tab-nav-bar/tab-nav-bar.spec.ts index d53b020ecf29..3b5dd8cdb19a 100644 --- a/src/material-experimental/mdc-tabs/tab-nav-bar/tab-nav-bar.spec.ts +++ b/src/material-experimental/mdc-tabs/tab-nav-bar/tab-nav-bar.spec.ts @@ -1,3 +1,4 @@ +import {SPACE} from '@angular/cdk/keycodes'; import {waitForAsync, ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing'; import {Component, QueryList, ViewChild, ViewChildren} from '@angular/core'; import { @@ -5,7 +6,11 @@ import { RippleGlobalOptions, } from '@angular/material-experimental/mdc-core'; import {By} from '@angular/platform-browser'; -import {dispatchFakeEvent, dispatchMouseEvent} from '../../../cdk/testing/private'; +import { + dispatchFakeEvent, + dispatchKeyboardEvent, + dispatchMouseEvent, +} from '../../../cdk/testing/private'; import {Direction, Directionality} from '@angular/cdk/bidi'; import {Subject} from 'rxjs'; import {MatTabsModule} from '../module'; @@ -30,6 +35,7 @@ describe('MDC-based MatTabNavBar', () => { TabLinkWithTabIndexBinding, TabLinkWithNativeTabindexAttr, TabBarWithInactiveTabsOnInit, + TabBarWithPanel, ], providers: [ {provide: MAT_RIPPLE_GLOBAL_OPTIONS, useFactory: () => globalRippleOptions}, @@ -309,6 +315,123 @@ describe('MDC-based MatTabNavBar', () => { expect(instance.tabNavBar.selectedIndex).toBe(1); }); + describe('without panel', () => { + let fixture: ComponentFixture; + + beforeEach(() => { + fixture = TestBed.createComponent(SimpleTabNavBarTestApp); + fixture.detectChanges(); + }); + + it('should have no explicit roles', () => { + const tabBar = fixture.nativeElement.querySelector('.mat-mdc-tab-nav-bar')!; + expect(tabBar.getAttribute('role')).toBe(null); + + const tabLinks = fixture.nativeElement.querySelectorAll('.mat-mdc-tab-link'); + expect(tabLinks[0].getAttribute('role')).toBe(null); + expect(tabLinks[1].getAttribute('role')).toBe(null); + expect(tabLinks[2].getAttribute('role')).toBe(null); + }); + + it('should not setup aria-controls', () => { + const tabLinks = fixture.nativeElement.querySelectorAll('.mat-mdc-tab-link'); + expect(tabLinks[0].getAttribute('aria-controls')).toBe(null); + expect(tabLinks[1].getAttribute('aria-controls')).toBe(null); + expect(tabLinks[2].getAttribute('aria-controls')).toBe(null); + }); + + it('should not manage aria-selected', () => { + const tabLinks = fixture.nativeElement.querySelectorAll('.mat-mdc-tab-link'); + expect(tabLinks[0].getAttribute('aria-selected')).toBe(null); + expect(tabLinks[1].getAttribute('aria-selected')).toBe(null); + expect(tabLinks[2].getAttribute('aria-selected')).toBe(null); + }); + + it('should not activate a link when space is pressed', () => { + const tabLinks = fixture.nativeElement.querySelectorAll('.mat-mdc-tab-link'); + expect(tabLinks[1].classList.contains('mdc-tab--active')).toBe(false); + + dispatchKeyboardEvent(tabLinks[1], 'keydown', SPACE); + fixture.detectChanges(); + + expect(tabLinks[1].classList.contains('mdc-tab--active')).toBe(false); + }); + }); + + describe('with panel', () => { + let fixture: ComponentFixture; + + beforeEach(() => { + fixture = TestBed.createComponent(TabBarWithPanel); + fixture.detectChanges(); + }); + + it('should have the proper roles', () => { + const tabBar = fixture.nativeElement.querySelector('.mat-mdc-tab-nav-bar')!; + expect(tabBar.getAttribute('role')).toBe('tablist'); + + const tabLinks = fixture.nativeElement.querySelectorAll('.mat-mdc-tab-link'); + expect(tabLinks[0].getAttribute('role')).toBe('tab'); + expect(tabLinks[1].getAttribute('role')).toBe('tab'); + expect(tabLinks[2].getAttribute('role')).toBe('tab'); + + const tabPanel = fixture.nativeElement.querySelector('.mat-mdc-tab-nav-panel')!; + expect(tabPanel.getAttribute('role')).toBe('tabpanel'); + }); + + it('should manage tabindex properly', () => { + const tabLinks = fixture.nativeElement.querySelectorAll('.mat-mdc-tab-link'); + expect(tabLinks[0].tabIndex).toBe(0); + expect(tabLinks[1].tabIndex).toBe(-1); + expect(tabLinks[2].tabIndex).toBe(-1); + + tabLinks[1].click(); + fixture.detectChanges(); + + expect(tabLinks[0].tabIndex).toBe(-1); + expect(tabLinks[1].tabIndex).toBe(0); + expect(tabLinks[2].tabIndex).toBe(-1); + }); + + it('should setup aria-controls properly', () => { + const tabLinks = fixture.nativeElement.querySelectorAll('.mat-mdc-tab-link'); + expect(tabLinks[0].getAttribute('aria-controls')).toBe('tab-panel'); + expect(tabLinks[1].getAttribute('aria-controls')).toBe('tab-panel'); + expect(tabLinks[2].getAttribute('aria-controls')).toBe('tab-panel'); + }); + + it('should not manage aria-current', () => { + const tabLinks = fixture.nativeElement.querySelectorAll('.mat-mdc-tab-link'); + expect(tabLinks[0].getAttribute('aria-current')).toBe(null); + expect(tabLinks[1].getAttribute('aria-current')).toBe(null); + expect(tabLinks[2].getAttribute('aria-current')).toBe(null); + }); + + it('should manage aria-selected properly', () => { + const tabLinks = fixture.nativeElement.querySelectorAll('.mat-mdc-tab-link'); + expect(tabLinks[0].getAttribute('aria-selected')).toBe('true'); + expect(tabLinks[1].getAttribute('aria-selected')).toBe('false'); + expect(tabLinks[2].getAttribute('aria-selected')).toBe('false'); + + tabLinks[1].click(); + fixture.detectChanges(); + + expect(tabLinks[0].getAttribute('aria-selected')).toBe('false'); + expect(tabLinks[1].getAttribute('aria-selected')).toBe('true'); + expect(tabLinks[2].getAttribute('aria-selected')).toBe('false'); + }); + + it('should activate a link when space is pressed', () => { + const tabLinks = fixture.nativeElement.querySelectorAll('.mat-mdc-tab-link'); + expect(tabLinks[1].classList.contains('mdc-tab--active')).toBe(false); + + dispatchKeyboardEvent(tabLinks[1], 'keydown', SPACE); + fixture.detectChanges(); + + expect(tabLinks[1].classList.contains('mdc-tab--active')).toBe(true); + }); + }); + describe('ripples', () => { let fixture: ComponentFixture; @@ -532,3 +655,21 @@ class TabLinkWithNativeTabindexAttr {} class TabBarWithInactiveTabsOnInit { tabs = [0, 1, 2]; } + +@Component({ + template: ` + + Tab panel + `, +}) +class TabBarWithPanel { + tabs = [0, 1, 2]; + activeIndex = 0; +} diff --git a/src/material-experimental/mdc-tabs/tab-nav-bar/tab-nav-bar.ts b/src/material-experimental/mdc-tabs/tab-nav-bar/tab-nav-bar.ts index ca883653cf59..bb88dce83f2c 100644 --- a/src/material-experimental/mdc-tabs/tab-nav-bar/tab-nav-bar.ts +++ b/src/material-experimental/mdc-tabs/tab-nav-bar/tab-nav-bar.ts @@ -56,6 +56,7 @@ import {takeUntil} from 'rxjs/operators'; templateUrl: 'tab-nav-bar.html', styleUrls: ['tab-nav-bar.css'], host: { + '[attr.role]': '_getRole()', 'class': 'mat-mdc-tab-nav-bar mat-mdc-tab-header', '[class.mat-mdc-tab-header-pagination-controls-enabled]': '_showPaginationControls', '[class.mat-mdc-tab-header-rtl]': "_getLayoutDirection() == 'rtl'", @@ -127,12 +128,17 @@ export class MatTabNav extends _MatTabNavBase implements AfterContentInit { styleUrls: ['tab-link.css'], host: { 'class': 'mdc-tab mat-mdc-tab-link mat-mdc-focus-indicator', - '[attr.aria-current]': 'active ? "page" : null', + '[attr.aria-controls]': '_getAriaControls()', + '[attr.aria-current]': '_getAriaCurrent()', '[attr.aria-disabled]': 'disabled', - '[attr.tabIndex]': 'tabIndex', + '[attr.aria-selected]': '_getAriaSelected()', + '[attr.id]': 'id', + '[attr.tabIndex]': '_getTabIndex()', + '[attr.role]': '_getRole()', '[class.mat-mdc-tab-disabled]': 'disabled', '[class.mdc-tab--active]': 'active', '(focus)': '_handleFocus()', + '(keydown)': '_handleKeydown($event)', }, }) export class MatTabLink extends _MatTabLinkBase implements MatInkBarItem, OnInit, OnDestroy { @@ -167,3 +173,30 @@ export class MatTabLink extends _MatTabLinkBase implements MatInkBarItem, OnInit this._foundation.destroy(); } } + +// Increasing integer for generating unique ids for tab nav components. +let nextUniqueId = 0; + +/** + * Tab panel component associated with MatTabNav. + */ +@Component({ + selector: 'mat-tab-nav-panel', + exportAs: 'matTabNavPanel', + template: '', + host: { + '[attr.aria-labelledby]': '_activeTabId', + '[attr.id]': 'id', + 'class': 'mat-mdc-tab-nav-panel', + 'role': 'tabpanel', + }, + encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class MatTabNavPanel { + /** Unique id for the tab panel. */ + @Input() id = `mat-tab-nav-panel-${nextUniqueId++}`; + + /** Id of the active tab in the nav bar. */ + _activeTabId?: string; +} diff --git a/src/material-experimental/mdc-tabs/testing/tab-harness-filters.ts b/src/material-experimental/mdc-tabs/testing/tab-harness-filters.ts index 65ada6d2e4cb..727365af322f 100644 --- a/src/material-experimental/mdc-tabs/testing/tab-harness-filters.ts +++ b/src/material-experimental/mdc-tabs/testing/tab-harness-filters.ts @@ -27,3 +27,6 @@ export interface TabLinkHarnessFilters extends BaseHarnessFilters { /** A set of criteria that can be used to filter a list of `MatTabNavBarHarness` instances. */ export interface TabNavBarHarnessFilters extends BaseHarnessFilters {} + +/** A set of criteria that can be used to filter a list of `MatTabNavBarHarness` instances. */ +export interface TabNavPanelHarnessFilters extends BaseHarnessFilters {} diff --git a/src/material-experimental/mdc-tabs/testing/tab-nav-bar-harness.ts b/src/material-experimental/mdc-tabs/testing/tab-nav-bar-harness.ts index f0ea4723aae5..75482b61bf43 100644 --- a/src/material-experimental/mdc-tabs/testing/tab-nav-bar-harness.ts +++ b/src/material-experimental/mdc-tabs/testing/tab-nav-bar-harness.ts @@ -7,8 +7,13 @@ */ import {ComponentHarness, HarnessPredicate, parallel} from '@angular/cdk/testing'; -import {TabNavBarHarnessFilters, TabLinkHarnessFilters} from './tab-harness-filters'; +import { + TabNavBarHarnessFilters, + TabNavPanelHarnessFilters, + TabLinkHarnessFilters, +} from './tab-harness-filters'; import {MatTabLinkHarness} from './tab-link-harness'; +import {MatTabNavPanelHarness} from './tab-nav-panel-harness'; /** Harness for interacting with an MDC-based mat-tab-nav-bar in tests. */ export class MatTabNavBarHarness extends ComponentHarness { @@ -57,4 +62,17 @@ export class MatTabNavBarHarness extends ComponentHarness { } await tabs[0].click(); } + + /** Gets the panel associated with the nav bar. */ + async getPanel(): Promise { + const link = await this.getActiveLink(); + const host = await link.host(); + const panelId = await host.getAttribute('aria-controls'); + if (!panelId) { + throw Error('No panel is controlled by the nav bar.'); + } + + const filter: TabNavPanelHarnessFilters = {selector: `#${panelId}`}; + return await this.documentRootLocatorFactory().locatorFor(MatTabNavPanelHarness.with(filter))(); + } } diff --git a/src/material-experimental/mdc-tabs/testing/tab-nav-panel-harness.ts b/src/material-experimental/mdc-tabs/testing/tab-nav-panel-harness.ts new file mode 100644 index 000000000000..40afef7436b5 --- /dev/null +++ b/src/material-experimental/mdc-tabs/testing/tab-nav-panel-harness.ts @@ -0,0 +1,31 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import {ContentContainerComponentHarness, HarnessPredicate} from '@angular/cdk/testing'; +import {TabNavPanelHarnessFilters} from './tab-harness-filters'; + +/** Harness for interacting with a standard mat-tab-nav-panel in tests. */ +export class MatTabNavPanelHarness extends ContentContainerComponentHarness { + /** The selector for the host element of a `MatTabNavPanel` instance. */ + static hostSelector = '.mat-mdc-tab-nav-panel'; + + /** + * Gets a `HarnessPredicate` that can be used to search for a `MatTabNavPanel` that meets + * certain criteria. + * @param options Options for filtering which tab nav panel instances are considered a match. + * @return a `HarnessPredicate` configured with the given options. + */ + static with(options: TabNavPanelHarnessFilters = {}): HarnessPredicate { + return new HarnessPredicate(MatTabNavPanelHarness, options); + } + + /** Gets the tab panel text content. */ + async getTextContent(): Promise { + return (await this.host()).text(); + } +} diff --git a/src/material/tabs/public-api.ts b/src/material/tabs/public-api.ts index 7c14d0697dd8..9fdca2961430 100644 --- a/src/material/tabs/public-api.ts +++ b/src/material/tabs/public-api.ts @@ -20,7 +20,13 @@ export {MatTabHeader, _MatTabHeaderBase} from './tab-header'; export {MatTabLabelWrapper} from './tab-label-wrapper'; export {MatTab, MAT_TAB_GROUP} from './tab'; export {MatTabLabel, MAT_TAB} from './tab-label'; -export {MatTabNav, MatTabLink, _MatTabNavBase, _MatTabLinkBase} from './tab-nav-bar/index'; +export { + MatTabNav, + MatTabLink, + MatTabNavPanel, + _MatTabNavBase, + _MatTabLinkBase, +} from './tab-nav-bar/index'; export {MatTabContent} from './tab-content'; export {ScrollDirection} from './paginated-tab-header'; export * from './tabs-animations'; diff --git a/src/material/tabs/tab-nav-bar/tab-nav-bar.spec.ts b/src/material/tabs/tab-nav-bar/tab-nav-bar.spec.ts index 99ddc9657259..ba4c4f1e8d0a 100644 --- a/src/material/tabs/tab-nav-bar/tab-nav-bar.spec.ts +++ b/src/material/tabs/tab-nav-bar/tab-nav-bar.spec.ts @@ -1,8 +1,13 @@ +import {SPACE} from '@angular/cdk/keycodes'; import {waitForAsync, ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing'; import {Component, ViewChild, ViewChildren, QueryList} from '@angular/core'; import {MAT_RIPPLE_GLOBAL_OPTIONS, RippleGlobalOptions} from '@angular/material/core'; import {By} from '@angular/platform-browser'; -import {dispatchFakeEvent, dispatchMouseEvent} from '../../../cdk/testing/private'; +import { + dispatchFakeEvent, + dispatchKeyboardEvent, + dispatchMouseEvent, +} from '../../../cdk/testing/private'; import {Direction, Directionality} from '@angular/cdk/bidi'; import {Subject} from 'rxjs'; import {MatTabLink, MatTabNav, MatTabsModule} from '../index'; @@ -24,6 +29,7 @@ describe('MatTabNavBar', () => { TabLinkWithTabIndexBinding, TabLinkWithNativeTabindexAttr, TabBarWithInactiveTabsOnInit, + TabBarWithPanel, ], providers: [ {provide: MAT_RIPPLE_GLOBAL_OPTIONS, useFactory: () => globalRippleOptions}, @@ -295,6 +301,123 @@ describe('MatTabNavBar', () => { expect(instance.tabNavBar.selectedIndex).toBe(1); }); + describe('without panel', () => { + let fixture: ComponentFixture; + + beforeEach(() => { + fixture = TestBed.createComponent(SimpleTabNavBarTestApp); + fixture.detectChanges(); + }); + + it('should have no explicit roles', () => { + const tabBar = fixture.nativeElement.querySelector('.mat-tab-nav-bar')!; + expect(tabBar.getAttribute('role')).toBe(null); + + const tabLinks = fixture.nativeElement.querySelectorAll('.mat-tab-link'); + expect(tabLinks[0].getAttribute('role')).toBe(null); + expect(tabLinks[1].getAttribute('role')).toBe(null); + expect(tabLinks[2].getAttribute('role')).toBe(null); + }); + + it('should not setup aria-controls', () => { + const tabLinks = fixture.nativeElement.querySelectorAll('.mat-tab-link'); + expect(tabLinks[0].getAttribute('aria-controls')).toBe(null); + expect(tabLinks[1].getAttribute('aria-controls')).toBe(null); + expect(tabLinks[2].getAttribute('aria-controls')).toBe(null); + }); + + it('should not manage aria-selected', () => { + const tabLinks = fixture.nativeElement.querySelectorAll('.mat-tab-link'); + expect(tabLinks[0].getAttribute('aria-selected')).toBe(null); + expect(tabLinks[1].getAttribute('aria-selected')).toBe(null); + expect(tabLinks[2].getAttribute('aria-selected')).toBe(null); + }); + + it('should not activate a link when space is pressed', () => { + const tabLinks = fixture.nativeElement.querySelectorAll('.mat-tab-link'); + expect(tabLinks[1].classList.contains('mat-tab-label-active')).toBe(false); + + dispatchKeyboardEvent(tabLinks[1], 'keydown', SPACE); + fixture.detectChanges(); + + expect(tabLinks[1].classList.contains('mat-tab-label-active')).toBe(false); + }); + }); + + describe('with panel', () => { + let fixture: ComponentFixture; + + beforeEach(() => { + fixture = TestBed.createComponent(TabBarWithPanel); + fixture.detectChanges(); + }); + + it('should have the proper roles', () => { + const tabBar = fixture.nativeElement.querySelector('.mat-tab-nav-bar')!; + expect(tabBar.getAttribute('role')).toBe('tablist'); + + const tabLinks = fixture.nativeElement.querySelectorAll('.mat-tab-link'); + expect(tabLinks[0].getAttribute('role')).toBe('tab'); + expect(tabLinks[1].getAttribute('role')).toBe('tab'); + expect(tabLinks[2].getAttribute('role')).toBe('tab'); + + const tabPanel = fixture.nativeElement.querySelector('.mat-tab-nav-panel')!; + expect(tabPanel.getAttribute('role')).toBe('tabpanel'); + }); + + it('should manage tabindex properly', () => { + const tabLinks = fixture.nativeElement.querySelectorAll('.mat-tab-link'); + expect(tabLinks[0].tabIndex).toBe(0); + expect(tabLinks[1].tabIndex).toBe(-1); + expect(tabLinks[2].tabIndex).toBe(-1); + + tabLinks[1].click(); + fixture.detectChanges(); + + expect(tabLinks[0].tabIndex).toBe(-1); + expect(tabLinks[1].tabIndex).toBe(0); + expect(tabLinks[2].tabIndex).toBe(-1); + }); + + it('should setup aria-controls properly', () => { + const tabLinks = fixture.nativeElement.querySelectorAll('.mat-tab-link'); + expect(tabLinks[0].getAttribute('aria-controls')).toBe('tab-panel'); + expect(tabLinks[1].getAttribute('aria-controls')).toBe('tab-panel'); + expect(tabLinks[2].getAttribute('aria-controls')).toBe('tab-panel'); + }); + + it('should not manage aria-current', () => { + const tabLinks = fixture.nativeElement.querySelectorAll('.mat-tab-link'); + expect(tabLinks[0].getAttribute('aria-current')).toBe(null); + expect(tabLinks[1].getAttribute('aria-current')).toBe(null); + expect(tabLinks[2].getAttribute('aria-current')).toBe(null); + }); + + it('should manage aria-selected properly', () => { + const tabLinks = fixture.nativeElement.querySelectorAll('.mat-tab-link'); + expect(tabLinks[0].getAttribute('aria-selected')).toBe('true'); + expect(tabLinks[1].getAttribute('aria-selected')).toBe('false'); + expect(tabLinks[2].getAttribute('aria-selected')).toBe('false'); + + tabLinks[1].click(); + fixture.detectChanges(); + + expect(tabLinks[0].getAttribute('aria-selected')).toBe('false'); + expect(tabLinks[1].getAttribute('aria-selected')).toBe('true'); + expect(tabLinks[2].getAttribute('aria-selected')).toBe('false'); + }); + + it('should activate a link when space is pressed', () => { + const tabLinks = fixture.nativeElement.querySelectorAll('.mat-tab-link'); + expect(tabLinks[1].classList.contains('mat-tab-label-active')).toBe(false); + + dispatchKeyboardEvent(tabLinks[1], 'keydown', SPACE); + fixture.detectChanges(); + + expect(tabLinks[1].classList.contains('mat-tab-label-active')).toBe(true); + }); + }); + describe('ripples', () => { let fixture: ComponentFixture; @@ -449,3 +572,21 @@ class TabLinkWithNativeTabindexAttr {} class TabBarWithInactiveTabsOnInit { tabs = [0, 1, 2]; } + +@Component({ + template: ` + + Tab panel + `, +}) +class TabBarWithPanel { + tabs = [0, 1, 2]; + activeIndex = 0; +} diff --git a/src/material/tabs/tab-nav-bar/tab-nav-bar.ts b/src/material/tabs/tab-nav-bar/tab-nav-bar.ts index ffc5b573535a..cde06f52e2f7 100644 --- a/src/material/tabs/tab-nav-bar/tab-nav-bar.ts +++ b/src/material/tabs/tab-nav-bar/tab-nav-bar.ts @@ -6,6 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ import {FocusableOption, FocusMonitor} from '@angular/cdk/a11y'; +import {SPACE} from '@angular/cdk/keycodes'; import {Directionality} from '@angular/cdk/bidi'; import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion'; import {Platform} from '@angular/cdk/platform'; @@ -50,6 +51,9 @@ import {startWith, takeUntil} from 'rxjs/operators'; import {MatInkBar} from '../ink-bar'; import {MatPaginatedTabHeader, MatPaginatedTabHeaderItem} from '../paginated-tab-header'; +// Increasing integer for generating unique ids for tab nav components. +let nextUniqueId = 0; + /** * Base class with all of the `MatTabNav` functionality. * @docs-private @@ -60,7 +64,7 @@ export abstract class _MatTabNavBase implements AfterContentChecked, AfterContentInit, OnDestroy { /** Query list of all tab links of the tab navigation. */ - abstract override _items: QueryList; + abstract override _items: QueryList; /** Background color of the tab nav. */ @Input() @@ -92,6 +96,13 @@ export abstract class _MatTabNavBase /** Theme color of the nav bar. */ @Input() color: ThemePalette = 'primary'; + /** + * Associated tab panel controlled by the nav bar. If not provided, then the nav bar + * follows the ARIA link / navigation landmark pattern. If provided, it follows the + * ARIA tabs design pattern. + */ + @Input() tabPanel?: MatTabNavPanel; + constructor( elementRef: ElementRef, @Optional() dir: Directionality, @@ -130,6 +141,11 @@ export abstract class _MatTabNavBase if (items[i].active) { this.selectedIndex = i; this._changeDetectorRef.markForCheck(); + + if (this.tabPanel) { + this.tabPanel._activeTabId = items[i].id; + } + return; } } @@ -138,6 +154,10 @@ export abstract class _MatTabNavBase this.selectedIndex = -1; this._inkBar.hide(); } + + _getRole(): string | null { + return this.tabPanel ? 'tablist' : this._elementRef.nativeElement.getAttribute('role'); + } } /** @@ -151,6 +171,7 @@ export abstract class _MatTabNavBase templateUrl: 'tab-nav-bar.html', styleUrls: ['tab-nav-bar.css'], host: { + '[attr.role]': '_getRole()', 'class': 'mat-tab-nav-bar mat-tab-header', '[class.mat-tab-header-pagination-controls-enabled]': '_showPaginationControls', '[class.mat-tab-header-rtl]': "_getLayoutDirection() == 'rtl'", @@ -238,6 +259,9 @@ export class _MatTabLinkBase ); } + /** Unique id for the tab. */ + @Input() id = `mat-tab-link-${nextUniqueId++}`; + constructor( private _tabNavBar: _MatTabNavBase, /** @docs-private */ public elementRef: ElementRef, @@ -274,6 +298,42 @@ export class _MatTabLinkBase // have to update the focused index whenever the link receives focus. this._tabNavBar.focusIndex = this._tabNavBar._items.toArray().indexOf(this); } + + _handleKeydown(event: KeyboardEvent) { + if (this._tabNavBar.tabPanel && event.keyCode === SPACE) { + this.elementRef.nativeElement.click(); + } + } + + _getAriaControls(): string | null { + return this._tabNavBar.tabPanel + ? this._tabNavBar.tabPanel?.id + : this.elementRef.nativeElement.getAttribute('aria-controls'); + } + + _getAriaSelected(): string | null { + if (this._tabNavBar.tabPanel) { + return this.active ? 'true' : 'false'; + } else { + return this.elementRef.nativeElement.getAttribute('aria-selected'); + } + } + + _getAriaCurrent(): string | null { + return this.active && !this._tabNavBar.tabPanel ? 'page' : null; + } + + _getRole(): string | null { + return this._tabNavBar.tabPanel ? 'tab' : this.elementRef.nativeElement.getAttribute('role'); + } + + _getTabIndex(): number { + if (this._tabNavBar.tabPanel) { + return this._isActive ? 0 : -1; + } else { + return this.tabIndex; + } + } } /** @@ -285,12 +345,17 @@ export class _MatTabLinkBase inputs: ['disabled', 'disableRipple', 'tabIndex'], host: { 'class': 'mat-tab-link mat-focus-indicator', - '[attr.aria-current]': 'active ? "page" : null', + '[attr.aria-controls]': '_getAriaControls()', + '[attr.aria-current]': '_getAriaCurrent()', '[attr.aria-disabled]': 'disabled', - '[attr.tabIndex]': 'tabIndex', + '[attr.aria-selected]': '_getAriaSelected()', + '[attr.id]': 'id', + '[attr.tabIndex]': '_getTabIndex()', + '[attr.role]': '_getRole()', '[class.mat-tab-disabled]': 'disabled', '[class.mat-tab-label-active]': 'active', '(focus)': '_handleFocus()', + '(keydown)': '_handleKeydown($event)', }, }) export class MatTabLink extends _MatTabLinkBase implements OnDestroy { @@ -317,3 +382,27 @@ export class MatTabLink extends _MatTabLinkBase implements OnDestroy { this._tabLinkRipple._removeTriggerEvents(); } } + +/** + * Tab panel component associated with MatTabNav. + */ +@Component({ + selector: 'mat-tab-nav-panel', + exportAs: 'matTabNavPanel', + template: '', + host: { + '[attr.aria-labelledby]': '_activeTabId', + '[attr.id]': 'id', + 'class': 'mat-tab-nav-panel', + 'role': 'tabpanel', + }, + encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class MatTabNavPanel { + /** Unique id for the tab panel. */ + @Input() id = `mat-tab-nav-panel-${nextUniqueId++}`; + + /** Id of the active tab in the nav bar. */ + _activeTabId?: string; +} diff --git a/src/material/tabs/tabs-module.ts b/src/material/tabs/tabs-module.ts index f6fb760eac74..e932044d5dd6 100644 --- a/src/material/tabs/tabs-module.ts +++ b/src/material/tabs/tabs-module.ts @@ -20,7 +20,7 @@ import {MatTabGroup} from './tab-group'; import {MatTabHeader} from './tab-header'; import {MatTabLabel} from './tab-label'; import {MatTabLabelWrapper} from './tab-label-wrapper'; -import {MatTabLink, MatTabNav} from './tab-nav-bar/tab-nav-bar'; +import {MatTabLink, MatTabNav, MatTabNavPanel} from './tab-nav-bar/tab-nav-bar'; @NgModule({ imports: [ @@ -38,6 +38,7 @@ import {MatTabLink, MatTabNav} from './tab-nav-bar/tab-nav-bar'; MatTabLabel, MatTab, MatTabNav, + MatTabNavPanel, MatTabLink, MatTabContent, ], @@ -48,6 +49,7 @@ import {MatTabLink, MatTabNav} from './tab-nav-bar/tab-nav-bar'; MatInkBar, MatTabLabelWrapper, MatTabNav, + MatTabNavPanel, MatTabLink, MatTabBody, MatTabBodyPortal, diff --git a/src/material/tabs/testing/tab-harness-filters.ts b/src/material/tabs/testing/tab-harness-filters.ts index 6421982988c3..1ba0149fe04e 100644 --- a/src/material/tabs/testing/tab-harness-filters.ts +++ b/src/material/tabs/testing/tab-harness-filters.ts @@ -27,3 +27,6 @@ export interface TabLinkHarnessFilters extends BaseHarnessFilters { /** A set of criteria that can be used to filter a list of `MatTabNavBarHarness` instances. */ export interface TabNavBarHarnessFilters extends BaseHarnessFilters {} + +/** A set of criteria that can be used to filter a list of `MatTabNavBarHarness` instances. */ +export interface TabNavPanelHarnessFilters extends BaseHarnessFilters {} diff --git a/src/material/tabs/testing/tab-nav-bar-harness.ts b/src/material/tabs/testing/tab-nav-bar-harness.ts index 39f62879b369..9b1ba673dd97 100644 --- a/src/material/tabs/testing/tab-nav-bar-harness.ts +++ b/src/material/tabs/testing/tab-nav-bar-harness.ts @@ -7,8 +7,13 @@ */ import {ComponentHarness, HarnessPredicate, parallel} from '@angular/cdk/testing'; -import {TabNavBarHarnessFilters, TabLinkHarnessFilters} from './tab-harness-filters'; +import { + TabNavBarHarnessFilters, + TabNavPanelHarnessFilters, + TabLinkHarnessFilters, +} from './tab-harness-filters'; import {MatTabLinkHarness} from './tab-link-harness'; +import {MatTabNavPanelHarness} from './tab-nav-panel-harness'; /** Harness for interacting with a standard mat-tab-nav-bar in tests. */ export class MatTabNavBarHarness extends ComponentHarness { @@ -57,4 +62,17 @@ export class MatTabNavBarHarness extends ComponentHarness { } await tabs[0].click(); } + + /** Gets the panel associated with the nav bar. */ + async getPanel(): Promise { + const link = await this.getActiveLink(); + const host = await link.host(); + const panelId = await host.getAttribute('aria-controls'); + if (!panelId) { + throw Error('No panel is controlled by the nav bar.'); + } + + const filter: TabNavPanelHarnessFilters = {selector: `#${panelId}`}; + return await this.documentRootLocatorFactory().locatorFor(MatTabNavPanelHarness.with(filter))(); + } } diff --git a/src/material/tabs/testing/tab-nav-bar-shared.spec.ts b/src/material/tabs/testing/tab-nav-bar-shared.spec.ts index b5101e0c578f..c6b5b62cc54c 100644 --- a/src/material/tabs/testing/tab-nav-bar-shared.spec.ts +++ b/src/material/tabs/testing/tab-nav-bar-shared.spec.ts @@ -92,11 +92,17 @@ export function runTabNavBarHarnessTests( expect(await links[1].isActive()).toBe(true); expect(await links[2].isActive()).toBe(false); }); + + it('should be able to get the associated tab panel', async () => { + const navBar = await loader.getHarness(tabNavBarHarness); + const navPanel = await navBar.getPanel(); + expect(await navPanel.getTextContent()).toBe('Tab content'); + }); } @Component({ template: ` -