From 18cea49e1cf9d8f3e1e7f30aff5166a79753d26d Mon Sep 17 00:00:00 2001 From: streamich Date: Tue, 26 Mar 2019 09:54:28 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20change=20VRule=20interfa?= =?UTF-8?q?ce,=20add=20vcssom=20docs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .storybook/VCSSOM.stories.js | 1 + README.md | 2 + addon/vcssom.d.ts | 59 ++++++++++++++++++++++++++++ addon/vcssom.js | 10 ++--- docs/cssom.md | 7 ++++ docs/vcssom.md | 74 ++++++++++++++++++++++++++++++++++++ 6 files changed, 148 insertions(+), 5 deletions(-) create mode 100644 docs/vcssom.md diff --git a/.storybook/VCSSOM.stories.js b/.storybook/VCSSOM.stories.js index 286775e4..6b980753 100644 --- a/.storybook/VCSSOM.stories.js +++ b/.storybook/VCSSOM.stories.js @@ -26,6 +26,7 @@ sheet.diff({ '@media only screen and (max-width: 600px)': { '.test_vcssom': { 'text-decoration': 'underline', + color: 'green', }, } }); diff --git a/README.md b/README.md index a9c1d2b7..fa0819a2 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,8 @@ __Motto of `nano-css` is simple__: *create the smallest possible CSS-in-JS libra - [`extract`](./docs/extract.md) - [`sourcemaps`](./docs/sourcemaps.md) - [`.units`](./docs/units.md) + - [`cssom`](./docs/cssom.md) + - [`vcssom`](./docs/vcssom.md) - [Presets](./docs/Presets.md) - [Server-side rendering](./docs/SSR.md) diff --git a/addon/vcssom.d.ts b/addon/vcssom.d.ts index f13e959d..0dd5ba0b 100644 --- a/addon/vcssom.d.ts +++ b/addon/vcssom.d.ts @@ -1,12 +1,71 @@ import {CSSOMAddon} from './cssom'; import {Css} from './vcssom/cssToTree'; import {NanoRenderer} from '../types/nano'; +import {CSSOMRule} from './cssom'; +import {CssProps} from '../types/common'; + +export interface VRule { + /** + * CSS declarations, like `{color: 'red'}` + */ + decl: CssProps; + rule: CSSOMRule; + + /** + * Re-render css rule according to new CSS declarations. + * @param decl CSS declarations, like `{color: 'red'}` + */ + diff(decl: CssProps); + + /** + * Removes this `VRule` from CSSOM. After calling this method, you + * cannot call `diff` anymore as this rule will be removed from style sheet. + */ + del(); +} export interface VSheet { + /** + * Re-renders style sheet according to specified CSS-like object. The `css` + * object is a 3-level tree structure: + * + * ``` + * { + * media-query-prelude: { + * selector: { + * declarations + * } + * } + * } + * ``` + * + * Example: + * + * ```js + * sheet.diff({ + * '': { + * '.my-class': { + * color: 'red', + * }, + * '.my-class:hover': { + * color: 'blue', + * }, + * }, + * '@media only screen and (max-width: 600px)': { + * '.my-class': { + * color: 'green', + * }, + * }, + * }); + * ``` + * + * @param css CSS-like object with media queries as top level. + */ diff(css: Css); } export interface VCSSOMAddon { + VRule: new (selector: string, mediaQuery?: string) => VRule; VSheet: new () => VSheet; } diff --git a/addon/vcssom.js b/addon/vcssom.js index b7f6da16..2b3f690c 100644 --- a/addon/vcssom.js +++ b/addon/vcssom.js @@ -12,9 +12,9 @@ exports.addon = function (renderer) { var kebab = renderer.kebab; - function VRule (rule, decl) { - this.rule = rule; - this.decl = decl; + function VRule (selector, prelude) { + this.rule = renderer.createRule(selector, prelude); + this.decl = {}; } VRule.prototype.diff = function (newDecl) { var oldDecl = this.decl; @@ -60,7 +60,7 @@ exports.addon = function (renderer) { if (oldTree[prelude] === undefined) { // Whole media query is new. for (var selector in newTree[prelude]) { - var rule = new VRule(renderer.createRule(selector, prelude), {}); + var rule = new VRule(selector, prelude); rule.diff(newTree[prelude][selector]); newTree[prelude][selector] = rule; } @@ -81,7 +81,7 @@ exports.addon = function (renderer) { rule.diff(newRules[selector]); newRules[selector] = rule; } else { - rule = new VRule(renderer.createRule(selector, prelude), {}); + rule = new VRule(selector, prelude); rule.diff(newRules[selector]); newRules[selector] = rule; } diff --git a/docs/cssom.md b/docs/cssom.md index 6aed8be4..007012ed 100644 --- a/docs/cssom.md +++ b/docs/cssom.md @@ -31,3 +31,10 @@ Use `rule` object to set CSS. rule.style.color = 'red'; rule.style.setProperty('color', 'green'); ``` + + +## Installation + +Simply install `cssom` addon. + +Read more about the [Addon Installation](./Addons.md#addon-installation). diff --git a/docs/vcssom.md b/docs/vcssom.md new file mode 100644 index 00000000..79ac2ccd --- /dev/null +++ b/docs/vcssom.md @@ -0,0 +1,74 @@ +# `vcssom` Addon + +Adds `VRule` and `VSheet` classes, which can be used for rendering and diffing +virtual CSS. Both classes have `.diff()` methods. The `.diff()` method will compute +differences with the previous render and add or remove only necessary CSS rules/declarations. + + +## Usage + +Create a virtual CSS rule. + +```js +const rule = new nano.VRule('.my-class'); +``` + +Apply styles to it. + +```js +rule.diff({ + color: 'red', + 'font-weight': 'bold', +}); + +rule.diff({ + color: 'blue', +}); +``` + +Remove the rule from CSSOM (you cannot call `.diff` after this anymore). + +```js +rule.del(); +``` + +Create virtual CSS style sheet. + +```js +const sheet = new nano.VSheet(); +``` + +Render CSS. + +```js +sheet.diff({ + '': { + '.my-class': { + color: 'red', + }, + '.my-class:hover': { + color: 'blue', + }, + }, + '@media only screen and (max-width: 600px)': { + '.my-class': { + fontWeight: 'bold', + }, + }, +}); +``` + +Remove all rendered CSS. + +```js +sheet.diff({}); +``` + + +## Installation + +Simply install `vcssom` addon and its dependencies: + +- [`cssom`](./cssom.md) + +Read more about the [Addon Installation](./Addons.md#addon-installation).