From 348b505e5f42b08e3685638d620d42337e32d32b Mon Sep 17 00:00:00 2001 From: Bruno Boi Date: Wed, 3 Nov 2021 10:00:15 +0100 Subject: [PATCH] [IMP] tags: reintroduce inline css tag The CSS tag is useful to define a css stylesheet in the javascript file: ```js class MyComponent extends Component { static template = xml`
some template
`; static style = css` .my-component { color: red; } `; } ``` The `css` tag registers internally the css information. Then, whenever the first instance of the component is created, will add a `); - // await app.mount(fixture); - // const style = getComputedStyle(app.el!); - // expect(style.color).toBe("red"); - // expect(fixture.innerHTML).toBe('
text
'); + class App extends Component { + static template = xml`
text
`; + static style = css` + .app { + color: red; + } + `; + } + expect(document.head.innerHTML).toBe(""); + const app = await mount(App, fixture); + expect(document.head.innerHTML).toBe(``); + const style = getComputedStyle(app.el as HTMLElement); + expect(style.color).toBe("red"); + expect(fixture.innerHTML).toBe('
text
'); }); test("inherited components properly apply css", async () => { - // class App extends Component { - // static template = xml`
text
`; - // static style = css` - // .app { - // color: red; - // } - // `; - // } - // class SubApp extends App { - // static style = css` - // .app { - // font-weight: bold; - // } - // `; - // } - // expect(document.head.innerHTML).toBe(""); - // const app = new SubApp(); - // expect(document.head.innerHTML).toBe(``); - // await app.mount(fixture); - // const style = getComputedStyle(app.el!); - // expect(style.color).toBe("red"); - // expect(style.fontWeight).toBe("bold"); - // expect(fixture.innerHTML).toBe('
text
'); + class App extends Component { + static template = xml`
text
`; + static style = css` + .app { + color: red; + } + `; + } + class SubApp extends App { + static style = css` + .app { + font-weight: bold; + } + `; + } + expect(document.head.innerHTML).toBe(""); + const app = await mount(SubApp, fixture); + expect(document.head.innerHTML).toBe(``); + const style = getComputedStyle(app.el as HTMLElement); + expect(style.color).toBe("red"); + expect(style.fontWeight).toBe("bold"); + expect(fixture.innerHTML).toBe('
text
'); + }); + + test("inherited components properly apply css, part 2", async () => { + class App extends Component { + static template = xml`
`; + static style = css` + .app { + color: tomato; + } + `; + } + class BetterApp extends App {} + class EvenBetterApp extends BetterApp { + static style = css` + .app { + background-color: papayawhip; + } + `; + } + expect(document.head.innerHTML).toBe(""); + await mount(EvenBetterApp, fixture); + expect(document.head.innerHTML).toBe(``); }); test("get a meaningful error message if css helper is missing", async () => { - // class App extends Component { - // static template = xml`
text
`; - // static style = `.app {color: red;}`; - // } - // let error; - // try { - // new App(); - // } catch (e) { - // error = e; - // } - // expect(error).toBeDefined(); - // expect(error.message).toBe( - // "Invalid css stylesheet for component 'App'. Did you forget to use the 'css' tag helper?" - // ); - // }); - // test("inline stylesheets are processed", async () => { - // class App extends Component { - // static template = xml`
text
`; - // static style = css` - // .app { - // color: red; - // .some-class { - // font-weight: bold; - // width: 40px; - // } - // display: block; - // } - // `; - // } - // new App(); - // expect(document.head.querySelector("style")!.innerHTML).toBe(`.app { - // color: red; - // } - // .app .some-class { - // font-weight: bold; - // width: 40px; - // } - // .app { - // display: block; - // }`); + class App extends Component { + static template = xml`
text
`; + static style = `.app {color: red;}`; + } + let error; + try { + await mount(App, fixture); + } catch (e) { + error = e; + } + expect(error).toBeDefined(); + expect(error.message).toBe( + "Invalid css stylesheet for component 'App'. Did you forget to use the 'css' tag helper?" + ); + }); + + test("inline stylesheets are processed", async () => { + class App extends Component { + static template = xml`
text
`; + static style = css` + .app { + color: red; + .some-class { + font-weight: bold; + width: 40px; + } + display: block; + } + `; + } + await mount(App, fixture); + expect(document.head.querySelector("style")!.innerHTML).toBe(`.app { + color: red; +} +.app .some-class { + font-weight: bold; + width: 40px; +} +.app { + display: block; +}`); }); test("properly handle rules with commas", async () => { - // const sheet = processSheet(`.parent-a, .parent-b { - // .child-a, .child-b { - // color: red; - // } - // }`); - // expect(sheet) - // .toBe(`.parent-a .child-a, .parent-a .child-b, .parent-b .child-a, .parent-b .child-b { - // color: red; - // }`); + class App extends Component { + static template = xml`
`; + static style = css` + .parent-a, + .parent-b { + .child-a, + .child-b { + color: red; + } + } + `; + } + await mount(App, fixture); + expect(document.head.querySelector("style")!.innerHTML) + .toBe(`.parent-a .child-a, .parent-a .child-b, .parent-b .child-a, .parent-b .child-b { + color: red; +}`); }); test("handle & selector", async () => { - // let sheet = processSheet(`.btn { - // &.danger { - // color: red; - // } - // }`); - // expect(sheet).toBe(`.btn.danger { - // color: red; - // }`); - // sheet = processSheet(`.some-class { - // &.btn { - // .other-class ~ & { - // color: red; - // } - // } - // }`); - // expect(sheet).toBe(`.other-class ~ .some-class.btn { - // color: red; - // }`); + class App extends Component { + static template = xml`
`; + static style = css` + .btn { + &.danger { + color: red; + } + } + .some-class { + &.btn { + .other-class ~ & { + color: red; + } + } + } + `; + } + await mount(App, fixture); + expect(document.head.querySelector("style")!.innerHTML).toBe(`.btn.danger { + color: red; +} +.other-class ~ .some-class.btn { + color: red; +}`); }); });