Skip to content

feat(core): directive to add extra classes to components for m1 compat #1498

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 19, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion e2e/components/icon/icon.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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');
});
});

Expand Down
10 changes: 5 additions & 5 deletions e2e/components/menu/menu-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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')); }

Expand All @@ -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 {
Expand All @@ -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);
});
}
Expand Down
2 changes: 1 addition & 1 deletion e2e/components/menu/menu.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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');
});
});

Expand Down
74 changes: 74 additions & 0 deletions src/lib/core/compatibility/style-compatibility.ts
Original file line number Diff line number Diff line change
@@ -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
* `<md-card>` 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: [],
};
}
}
2 changes: 2 additions & 0 deletions src/lib/core/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down
2 changes: 1 addition & 1 deletion src/lib/menu/_menu-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
$background: map-get($theme, background);
$foreground: map-get($theme, foreground);

.md-menu {
.md-menu-panel {
background: md-color($background, 'card');
}

Expand Down
5 changes: 3 additions & 2 deletions src/lib/menu/menu.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<template>
<div class="md-menu" [ngClass]="_classList" (click)="_emitCloseEvent()" (keydown)="_handleKeydown($event)">
<div class="md-menu-panel" [ngClass]="_classList"
(click)="_emitCloseEvent()" (keydown)="_handleKeydown($event)">
<ng-content></ng-content>
</div>
</template>
<div class="md-menu-click-catcher" *ngIf="_showClickCatcher" (click)="_emitCloseEvent()"></div>
<div class="md-menu-click-catcher" *ngIf="_showClickCatcher" (click)="_emitCloseEvent()"></div>
2 changes: 1 addition & 1 deletion src/lib/menu/menu.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions src/lib/menu/menu.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});
Expand Down
3 changes: 3 additions & 0 deletions src/lib/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
PortalModule,
OverlayModule,
A11yModule,
StyleCompatibilityModule,
} from './core/index';

import {MdButtonToggleModule} from './button-toggle/index';
Expand Down Expand Up @@ -58,6 +59,7 @@ const MATERIAL_MODULES = [
PortalModule,
RtlModule,
A11yModule,
StyleCompatibilityModule,
];

@NgModule({
Expand Down Expand Up @@ -90,6 +92,7 @@ const MATERIAL_MODULES = [
MdSnackBarModule.forRoot(),
MdTooltipModule.forRoot(),
OverlayModule.forRoot(),
StyleCompatibilityModule.forRoot(),
],
exports: MATERIAL_MODULES,
})
Expand Down