Skip to content

Commit

Permalink
feat: 🎸 change VRule interface, add vcssom docs
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich committed Mar 26, 2019
1 parent 6d25e55 commit 18cea49
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 5 deletions.
1 change: 1 addition & 0 deletions .storybook/VCSSOM.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ sheet.diff({
'@media only screen and (max-width: 600px)': {
'.test_vcssom': {
'text-decoration': 'underline',
color: 'green',
},
}
});
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
59 changes: 59 additions & 0 deletions addon/vcssom.d.ts
Original file line number Diff line number Diff line change
@@ -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;
}

Expand Down
10 changes: 5 additions & 5 deletions addon/vcssom.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand Down
7 changes: 7 additions & 0 deletions docs/cssom.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).
74 changes: 74 additions & 0 deletions docs/vcssom.md
Original file line number Diff line number Diff line change
@@ -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).

1 comment on commit 18cea49

@streamich
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Build version: 5.0.0-ssr.111 🤞 ssr on CircleCI 🎉

Please sign in to comment.