diff --git a/e2e/components/icon/icon.e2e.ts b/e2e/components/icon/icon.e2e.ts index 4d5648ac5d8d..9894a2fd9a3b 100644 --- a/e2e/components/icon/icon.e2e.ts +++ b/e2e/components/icon/icon.e2e.ts @@ -15,7 +15,8 @@ describe('icon', () => { it('should have the correct class when used', () => { testIcon.getAttribute('class').then((attr: string) => { - expect(attr).toEqual('md-24 material-icons'); + expect(attr).toContain('md-24'); + expect(attr).toContain('material-icons'); }); }); diff --git a/e2e/components/menu/menu-page.ts b/e2e/components/menu/menu-page.ts index 7e25d774004c..97fe77271352 100644 --- a/e2e/components/menu/menu-page.ts +++ b/e2e/components/menu/menu-page.ts @@ -6,7 +6,7 @@ export class MenuPage { browser.get('/menu'); } - menu() { return element(by.css('.md-menu')); } + menu() { return element(by.css('.md-menu-panel')); } start() { return element(by.id('start')); } @@ -28,11 +28,11 @@ export class MenuPage { combinedTrigger() { return element(by.id('combined-t')); } - beforeMenu() { return element(by.css('.md-menu.before')); } + beforeMenu() { return element(by.css('.md-menu-panel.before')); } - aboveMenu() { return element(by.css('.md-menu.above')); } + aboveMenu() { return element(by.css('.md-menu-panel.above')); } - combinedMenu() { return element(by.css('.md-menu.combined')); } + combinedMenu() { return element(by.css('.md-menu-panel.combined')); } // TODO(kara): move to common testing utility pressKey(key: any): void { @@ -46,7 +46,7 @@ export class MenuPage { } expectMenuPresent(expected: boolean) { - return browser.isElementPresent(by.css('.md-menu')).then((isPresent) => { + return browser.isElementPresent(by.css('.md-menu-panel')).then(isPresent => { expect(isPresent).toBe(expected); }); } diff --git a/e2e/components/menu/menu.e2e.ts b/e2e/components/menu/menu.e2e.ts index b247bc113ef8..4ba0402554de 100644 --- a/e2e/components/menu/menu.e2e.ts +++ b/e2e/components/menu/menu.e2e.ts @@ -62,7 +62,7 @@ describe('menu', () => { it('should mirror classes on host to menu template in overlay', () => { page.trigger().click(); page.menu().getAttribute('class').then((classes) => { - expect(classes).toEqual('md-menu custom'); + expect(classes).toEqual('md-menu-panel custom'); }); }); diff --git a/src/lib/core/compatibility/style-compatibility.ts b/src/lib/core/compatibility/style-compatibility.ts new file mode 100644 index 000000000000..4db50e4f2a59 --- /dev/null +++ b/src/lib/core/compatibility/style-compatibility.ts @@ -0,0 +1,74 @@ +import {NgModule, ModuleWithProviders, Directive, Renderer, ElementRef} from '@angular/core'; + + +/** Selector that matches all elements that may have style collisions with material1. */ +export const ELEMENTS_SELECTOR = ` + md-card, + md-card-actions, + md-card-content, + md-card-footer, + md-card-header, + md-card-subtitle, + md-card-title, + md-card-title-group, + md-checkbox, + md-dialog-container, + md-divider, + md-grid-list, + md-grid-tile, + md-grid-tile-footer, + md-grid-tile-header, + md-hint, + md-icon, + md-ink-bar, + md-input, + md-list, + md-list-item, + md-menu, + md-nav-list, + md-placeholder, + md-progress-bar, + md-progress-circle, + md-radio-button, + md-radio-group, + md-select, + md-sidenav, + md-slider, + md-spinner, + md-tab, + md-toolbar +`; + +/** + * Directive to apply to all material2 components that use the same element name as a + * component in material2. It does two things: + * 1) Adds the css class "md2" to the host element so that material1 can use this class with a + * :not() in order to avoid affecting material2 elements. + * 2) Adds a css class to the element that is identical to the element's tag. E.g., the element + * `` would be given a css class `md-card`. This is done so that material2 can style + * only these classes instead of defining element rules that would affect material1 components. + */ +@Directive({ + selector: ELEMENTS_SELECTOR, +}) +export class StyleCompatibility { + constructor(renderer: Renderer, elementRef: ElementRef) { + const element = elementRef.nativeElement as Node; + renderer.setElementClass(element, 'md2', true); + renderer.setElementClass(element, element.nodeName.toLowerCase(), true); + } +} + + +@NgModule({ + declarations: [StyleCompatibility], + exports: [StyleCompatibility], +}) +export class StyleCompatibilityModule { + static forRoot(): ModuleWithProviders { + return { + ngModule: StyleCompatibilityModule, + providers: [], + }; + } +} diff --git a/src/lib/core/core.ts b/src/lib/core/core.ts index ec467525210b..21bdb492d739 100644 --- a/src/lib/core/core.ts +++ b/src/lib/core/core.ts @@ -79,6 +79,8 @@ export {ComponentType} from './overlay/generic-component-type'; // Keybindings export * from './keyboard/keycodes'; +export * from './compatibility/style-compatibility'; + // Animation export * from './animation/animation'; diff --git a/src/lib/menu/_menu-theme.scss b/src/lib/menu/_menu-theme.scss index feb32dc56fe0..28930e22e900 100644 --- a/src/lib/menu/_menu-theme.scss +++ b/src/lib/menu/_menu-theme.scss @@ -6,7 +6,7 @@ $background: map-get($theme, background); $foreground: map-get($theme, foreground); - .md-menu { + .md-menu-panel { background: md-color($background, 'card'); } diff --git a/src/lib/menu/menu.html b/src/lib/menu/menu.html index b6a2d1a26bd0..bb6d522a79d7 100644 --- a/src/lib/menu/menu.html +++ b/src/lib/menu/menu.html @@ -1,6 +1,7 @@ -
\ No newline at end of file +
diff --git a/src/lib/menu/menu.scss b/src/lib/menu/menu.scss index a1eaca0fdaa1..c939bd12a0dc 100644 --- a/src/lib/menu/menu.scss +++ b/src/lib/menu/menu.scss @@ -16,7 +16,7 @@ $md-menu-font-size: 16px !default; $md-menu-side-padding: 16px !default; $md-menu-vertical-padding: 8px !default; -.md-menu { +.md-menu-panel { @include md-elevation(2); min-width: $md-menu-overlay-min-width; max-width: $md-menu-overlay-max-width; diff --git a/src/lib/menu/menu.spec.ts b/src/lib/menu/menu.spec.ts index 1bdf9b2e1977..baa0bb8accaa 100644 --- a/src/lib/menu/menu.spec.ts +++ b/src/lib/menu/menu.spec.ts @@ -18,13 +18,13 @@ describe('MdMenu', () => { it('should open the menu as an idempotent operation', () => { let fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); - let menu = fixture.debugElement.query(By.css('.md-menu')); + let menu = fixture.debugElement.query(By.css('.md-menu-panel')); expect(menu).toBe(null); expect(() => { fixture.componentInstance.trigger.openMenu(); fixture.componentInstance.trigger.openMenu(); - menu = fixture.debugElement.query(By.css('.md-menu')); + menu = fixture.debugElement.query(By.css('.md-menu-panel')); expect(menu.nativeElement.innerHTML.trim()).toEqual('Content'); }).not.toThrowError(); }); diff --git a/src/lib/module.ts b/src/lib/module.ts index cab0221ba967..754226b7f0c6 100644 --- a/src/lib/module.ts +++ b/src/lib/module.ts @@ -6,6 +6,7 @@ import { PortalModule, OverlayModule, A11yModule, + StyleCompatibilityModule, } from './core/index'; import {MdButtonToggleModule} from './button-toggle/index'; @@ -58,6 +59,7 @@ const MATERIAL_MODULES = [ PortalModule, RtlModule, A11yModule, + StyleCompatibilityModule, ]; @NgModule({ @@ -90,6 +92,7 @@ const MATERIAL_MODULES = [ MdSnackBarModule.forRoot(), MdTooltipModule.forRoot(), OverlayModule.forRoot(), + StyleCompatibilityModule.forRoot(), ], exports: MATERIAL_MODULES, })