Skip to content

Commit

Permalink
feat: add decorator addon
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich committed Mar 15, 2018
1 parent ca0f9b0 commit 381d4fd
Show file tree
Hide file tree
Showing 15 changed files with 198 additions and 178 deletions.
10 changes: 6 additions & 4 deletions .storybook/atoms.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@ import {createElement as h} from 'react';
import {storiesOf} from '@storybook/react';
const {action} = require('@storybook/addon-actions');
const {linkTo} = require('@storybook/addon-links');
const {create} = require('../lib');
const {addon} = require('../addon/atoms');
const {create} = require('../index');
const {addon: addonRule} = require('../addon/rule');
const {addon: addonAtoms} = require('../addon/atoms');

const renderer = create({h});
addon(renderer);
addonRule(renderer);
addonAtoms(renderer);
const {rule} = renderer;

const className = rule({
bd: '1px solid red'
}, 'atoms');

storiesOf('Addons/Atoms', module)
storiesOf('Atoms', module)
.add('Default', () =>
h('div', {className}, 'Red')
)
41 changes: 37 additions & 4 deletions .storybook/decorator.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ import {storiesOf} from '@storybook/react';
const {action} = require('@storybook/addon-actions');
const {linkTo} = require('@storybook/addon-links');

import {create} from '../lib';
import {addon} from '../addon/decorator';
import {create} from '../index';
import {addon as addonRule} from '../addon/rule';
import {addon as addonCache} from '../addon/cache';
import {addon as addonDecorator} from '../addon/decorator';
const renderer = create({h});
addon(renderer);
addonRule(renderer);
addonCache(renderer);
addonDecorator(renderer);
const {css} = renderer;

@css({
Expand All @@ -18,7 +22,36 @@ class CssTest extends Component<any, any> {
}
}

storiesOf('Addons/@css decorator', module)
@css({
border: '1px solid red'
})
class Dynamic extends Component<any, any> {
@css(props => ({
color: 'green'
}))
render () {
return <div>Hello there</div>;
}
}

@css
class Static extends Component<any, any> {
static css = {
border: '1px dashed blue',
};

render () {
return <div>Hello there</div>;
}
}

storiesOf('@css decorator', module)
.add('Default', () =>
<CssTest />
)
.add('Dynamic styles', () =>
<Dynamic />
)
.add('Static decorator', () =>
<Static />
)
6 changes: 5 additions & 1 deletion .storybook/jsx.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ import {createElement as h} from 'react';
import {storiesOf} from '@storybook/react';
const {action} = require('@storybook/addon-actions');
const {linkTo} = require('@storybook/addon-links');
const {create} = require('../lib');
const {create} = require('../index');
const {addon: addonRule} = require('../addon/rule');
const {addon: addonJsx} = require('../addon/jsx');

const renderer = create({h});
addonRule(renderer);
addonJsx(renderer);
const {jsx} = renderer;

const RedBorder = jsx('div', {
Expand Down
10 changes: 6 additions & 4 deletions .storybook/nesting.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import {createElement as h} from 'react';
import {storiesOf} from '@storybook/react';
const {action} = require('@storybook/addon-actions');
const {linkTo} = require('@storybook/addon-links');
const {create} = require('../lib');
const {addon} = require('../addon/nesting');
const {create} = require('../index');
const {addon: addonRule} = require('../addon/rule');
const {addon: addonNesting} = require('../addon/nesting');

const renderer = create({h});
addon(renderer);
addonRule(renderer);
addonNesting(renderer);
const {rule} = renderer;

const className = rule({
Expand All @@ -16,7 +18,7 @@ const className = rule({
}
}, 'nesting');

storiesOf('Addons/Nesting', module)
storiesOf('Nesting', module)
.add('Default', () =>
h('div', {className}, 'Hover me!')
)
10 changes: 6 additions & 4 deletions .storybook/stable.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@ import {createElement as h} from 'react';
import {storiesOf} from '@storybook/react';
const {action} = require('@storybook/addon-actions');
const {linkTo} = require('@storybook/addon-links');
const {create} = require('../lib');
const {addon} = require('../addon/stable');
const {create} = require('../index');
const {addon: addonRule} = require('../addon/rule');
const {addon: addonStable} = require('../addon/stable');

const renderer = create({h});
addon(renderer);
addonRule(renderer);
addonStable(renderer);
const {rule} = renderer;

const className = rule({
bd: '1px solid red'
}, 'atoms');

storiesOf('Addons/Stable hash', module)
storiesOf('Stable hash', module)
.add('Default', () =>
h('div', {className}, 'Red')
)
4 changes: 2 additions & 2 deletions .storybook/useStyles.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {createElement as h} from 'react';
import {storiesOf} from '@storybook/react';
const {action} = require('@storybook/addon-actions');
const {linkTo} = require('@storybook/addon-links');
const {create} = require('../lib');
const {create} = require('../index');

const renderer = create({h});
require('../addon/sheet').addon(renderer);
Expand Down Expand Up @@ -37,7 +37,7 @@ function HelloWorld (props, styles) {

const Bordered = useStyles(styles2, HelloWorld);

storiesOf('Addons/useStyles()', module)
storiesOf('useStyles()', module)
.add('Default', () =>
h(Example1)
)
Expand Down
4 changes: 2 additions & 2 deletions .storybook/withStyles.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {createElement as h} from 'react';
import {storiesOf} from '@storybook/react';
const {action} = require('@storybook/addon-actions');
const {linkTo} = require('@storybook/addon-links');
const {create} = require('../lib');
const {create} = require('../index');

const renderer = create({h});
require('../addon/sheet').addon(renderer);
Expand Down Expand Up @@ -38,7 +38,7 @@ function HelloWorld ({styles}) {

const Bordered = withStyles(styles2, HelloWorld);

storiesOf('Addons/withStyles()', module)
storiesOf('withStyles()', module)
.add('Default', () =>
h(Example1)
)
Expand Down
107 changes: 5 additions & 102 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# ezcss
# nano-css

[![][npm-badge]][npm-url] [![][travis-badge]][travis-url]

Expand All @@ -11,110 +11,13 @@ Super lite CSS-in-JS solution at only __0.XKb__ packing more features than you w
- Does not create wrapper components.


## Usage

Import renderer.

```js
import {Renderer} from 'ezcss';

const renderer = new Renderer;
const {rule, sheet, withStyles, useStyles, styled, css} = renderer;
```

Render a single "rule".

```js
const className = rule({
border: '1px solid red'
}, 'MyName');

<div className={className} />
```

Create a "styles sheet" with multiple lazy-evaluating rules.

```js
const styles = sheet({
main: {
border: '1px solid red'
},
element: {
border: '1px solid blue'
}
}, 'MyName');

<div className={styles.main} />
```

Injects `styles` prop into component.

```js
const styles = {
main: {
border: '1px solid red'
}
};

const MyComp = withStyles(styles, function MyComp ({styles}) {
return <div className={styles.main} />
});
```

Use `styles` object in your component.

```js
const styles = {
main: {
border: '1px solid red'
}
};

const MyComp = useStyles(styles, function MyComp (props, styles) {
return <div className={styles.main} />
});
```

Create "styled" components.

```js
const Div = styled('div', {
border: '1px solid red'
}, 'RedBorderDiv');

<Div>Hello world!</Div>
```

Stateful component style decorator.

```js
@css({
border: '1px solid red'
})
class MyComponent extends Component {
render () {

}
}
```


## Server Side Rendering

`excss` works in Node.js environment as well. Use `.raw` property to access raw CSS styles
on server and include then in your template.

```js
const html += `<style>${renderer.raw}</style>`;
```


## License

[Unlicense](./LICENSE) &mdash; public domain.


[npm-url]: https://www.npmjs.com/package/ezcss
[npm-badge]: https://img.shields.io/npm/v/ezcss.svg
[travis-url]: https://travis-ci.org/streamich/ezcss
[travis-badge]: https://travis-ci.org/streamich/ezcss.svg?branch=master
[npm-url]: https://www.npmjs.com/package/nano-css
[npm-badge]: https://img.shields.io/npm/v/nano-css.svg
[travis-url]: https://travis-ci.org/streamich/nano-css
[travis-badge]: https://travis-ci.org/streamich/nano-css.svg?branch=master
73 changes: 24 additions & 49 deletions addon/decorator.js
Original file line number Diff line number Diff line change
@@ -1,61 +1,36 @@
'use strict';

var cloneElement = require('react').cloneElement;
var transformComponentStatic = require('./util/transformComponentStatic');
var transformComponentDynamic = require('./util/transformComponentDynamic');

exports.addon = function (renderer) {
var transformStatic = function (prototype, styles, block) {
var render_ = prototype.render;
var className = '';

prototype.render = function() {
var element = render_.call(this);

if (element) {
if (!className) {
className = renderer.rule(styles, block);
}

if (process.env.NODE_ENV === 'production') {
element.props.className = (element.props.className || '') + className;
} else {
element = cloneElement(element, {
className: (element.props.className || '') + className,
});
}
}
if (process.env.NODE_ENV !== 'production') {
require('./__dev__/warnOnMissingDependencies')('css', renderer, ['rule', 'cache']);
}

return element;
};
};
renderer.css = function (a, b) {
var isComponent = a && a.prototype && a.prototype.render;

/*
var transformDynamic = function (prototype, dynamicTemplate) {
var render_ = prototype.render;
prototype.render = function () {
var element = render_.apply(this, arguments);
var props = element.props;
var className =
(props.className || '') +
renderer.render(this.constructor, this, this[$$el], dynamicTemplate(this));
if (process.env.NODE_ENV === 'production') {
element.ref = ref;
props.className = className;
return element;
}
// Static class decorator.
if (isComponent) {
if (a.css) transformComponentStatic(renderer, a.prototype, a.css);

return cloneElement(element, Object.assign({}, props, {ref: ref, className: className}), props.children);
};
};
*/
return a;
}

renderer.css = function (a, b) {
return function (Klass) {
var block = b || Klass.displayName || Klass.name;
var prototype = Klass.prototype;
return function (instanceOrComp, key, descriptor) {
if (typeof key === 'string') {
// .render() method decorator
var Comp = instanceOrComp.constructor;

transformComponentDynamic(renderer, Comp, a);
descriptor.value = Comp.prototype.render;

return descriptor;
}

transformStatic(prototype, a, block);
// Class decorator
transformComponentStatic(renderer, instanceOrComp.prototype, a, b);
};
};
};

0 comments on commit 381d4fd

Please sign in to comment.