├── .gitignore
├── .travis.yml
├── contributing.md
├── demo
└── src
│ └── index.js
├── example.gif
├── license
├── logo.png
├── nwb.config.js
├── package.json
├── readme.md
└── src
├── components
├── box.js
├── flex.js
└── index.js
├── context.js
├── index.js
├── provider.js
└── styled.js
/.gitignore:
--------------------------------------------------------------------------------
1 | /coverage
2 | /demo/dist
3 | /es
4 | /lib
5 | /node_modules
6 | npm-debug.log*
7 | package-lock.json
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 |
3 | language: node_js
4 | node_js:
5 | - 6
6 |
7 | before_install:
8 | - npm install codecov.io coveralls
9 |
10 | after_success:
11 | - cat ./coverage/lcov.info | ./node_modules/codecov.io/bin/codecov.io.js
12 | - cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js
13 |
14 | branches:
15 | only:
16 | - master
17 |
--------------------------------------------------------------------------------
/contributing.md:
--------------------------------------------------------------------------------
1 | ## Prerequisites
2 |
3 | [Node.js](http://nodejs.org/) >= v4 must be installed.
4 |
5 | ## Installation
6 |
7 | - Running `npm install` in the components's root directory will install everything you need for development.
8 |
9 | ## Demo Development Server
10 |
11 | - `npm start` will run a development server with the component's demo app at [http://localhost:3000](http://localhost:3000) with hot module reloading.
12 |
13 | ## Running Tests
14 |
15 | - `npm test` will run the tests once.
16 |
17 | - `npm run test:coverage` will run the tests and produce a coverage report in `coverage/`.
18 |
19 | - `npm run test:watch` will run the tests on every change.
20 |
21 | ## Building
22 |
23 | - `npm run build` will build the component for publishing to npm and also bundle the demo app.
24 |
25 | - `npm run clean` will delete built resources.
26 |
--------------------------------------------------------------------------------
/demo/src/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { render } from 'react-dom'
3 | import inject from 'insert-css'
4 |
5 | import {
6 | StyleProvider,
7 | createRenderer,
8 | Flex,
9 | Box
10 | } from '../../src'
11 |
12 | const renderer = createRenderer()
13 |
14 | renderer.renderStatic(
15 | {
16 | margin: 0
17 | },
18 | 'body, html'
19 | )
20 |
21 | renderer.renderStatic(
22 | {
23 | boxSizing: 'border-box'
24 | },
25 | '*'
26 | )
27 |
28 | const CenteredBox = ({ children, ...props }) => (
29 |
35 | {children}
36 |
37 | )
38 |
39 | const fontFamily = `
40 | -apple-system,
41 | BlinkMacSystemFont,
42 | Segoe UI,
43 | Helvetica Neue,
44 | sans-serif
45 | `
46 |
47 | const App = () => (
48 |
53 | 1
54 | 2
55 |
56 | )
57 |
58 | class Demo extends Component {
59 | render () {
60 | return (
61 |
62 |
63 |
64 | )
65 | }
66 | }
67 |
68 | render(, document.querySelector('#demo'))
69 | inject(renderer.renderToString())
70 |
--------------------------------------------------------------------------------
/example.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queckezz/veel/dfb6dc825c7f722dd062c457db4a61006aa3672d/example.gif
--------------------------------------------------------------------------------
/license:
--------------------------------------------------------------------------------
1 | (The MIT License)
2 |
3 | Copyright (c) 2017 Fabian Eichenberger
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining
6 | a copy of this software and associated documentation files (the
7 | 'Software'), to deal in the Software without restriction, including
8 | without limitation the rights to use, copy, modify, merge, publish,
9 | distribute, sublicense, and/or sell copies of the Software, and to
10 | permit persons to whom the Software is furnished to do so, subject to
11 | the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be
14 | included in all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/queckezz/veel/dfb6dc825c7f722dd062c457db4a61006aa3672d/logo.png
--------------------------------------------------------------------------------
/nwb.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | type: 'react-component',
3 | npm: {
4 | esModules: true,
5 | umd: false
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "veel",
3 | "version": "1.0.0-beta.3",
4 | "description": "Base react styling components using fela with a design system",
5 | "main": "lib/index.js",
6 | "module": "es/index.js",
7 | "files": [
8 | "css",
9 | "es",
10 | "lib",
11 | "umd"
12 | ],
13 | "scripts": {
14 | "build": "nwb build-react-component",
15 | "clean": "nwb clean-module && nwb clean-demo",
16 | "start": "nwb serve-react-demo",
17 | "test": "nwb test-react",
18 | "test:coverage": "nwb test-react --coverage",
19 | "test:watch": "nwb test-react --server"
20 | },
21 | "dependencies": {
22 | "@f/is-function": "^1.1.1",
23 | "fela": "^5.0.2",
24 | "prop-types": "^15.5.10",
25 | "styled-system": "^1.0.0-7"
26 | },
27 | "peerDependencies": {
28 | "react": "15.x"
29 | },
30 | "devDependencies": {
31 | "insert-css": "^2.0.0",
32 | "nwb": "0.17.x",
33 | "react": "^15.6.1",
34 | "react-dom": "^15.6.1"
35 | },
36 | "author": "queckezz ",
37 | "license": "MIT",
38 | "repository": "queckezz/veel",
39 | "keywords": [
40 | "react-component",
41 | "design system",
42 | "fela",
43 | "styling",
44 | "css-in-js",
45 | "ui",
46 | "react"
47 | ]
48 | }
49 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 |
2 | 
3 |
4 | # veel [![NPM version][version-image]][version-url] [![Js Standard Style][standard-image]][standard-url]
5 |
6 | :package: Base React styling components using [`Fela`](http://fela.js.org) with a [design system](https://github.com/jxnblk/styled-system)
7 |
8 | * **Low-Level** - Exposes only a few components which can be used as a base layer to build your UI components upon
9 | * **Consistency** - Uses `styled-system` which encourages consistency of spacing, typography and color
10 | * **Universal** - By using fela it's really easy to prerender your styles on the server or anywhere
11 |
12 | ```
13 | npm install veel
14 | ```
15 |
16 | ```js
17 | const Badge = (props) => (
18 |
25 | )
26 | ```
27 |
28 | ## Contents
29 |
30 | * [Example](#example)
31 | * [Usage](#usage)
32 | * [Components](#components)
33 | + [Box](#box)
34 | + [Flex](#flex)
35 | * [Plugins](#plugins)
36 | + [Recommend plugins](#recommend-plugins)
37 | * [Author](#author)
38 |
39 | ## Example
40 |
41 | The following renders a responsive row with two equally divided divs collapsing on mobile.
42 |
43 | 
44 |
45 | ```js
46 | const CenteredBox = props => (
47 |
53 | )
54 |
55 | const App = () => (
56 |
61 | 1
62 | 2
63 |
64 | )
65 | ```
66 |
67 | ## Usage
68 |
69 | 1. Create a [`fela`](http://fela.js.org/docs/api/fela-native/createRenderer.html) renderer.
70 |
71 | ```js
72 | import { createRenderer } from 'veel'
73 | const renderer = createRenderer()
74 | ```
75 |
76 | 2. Wrap your application in a `StyleProvider` so that each `veel` component has access to the renderer and the optional theme.
77 |
78 | ```js
79 | import { StyleProvider, Box } from 'veel'
80 |
81 | class App extends React.Component {
82 | render() {
83 | return (
84 |
85 | Application
86 |
87 | )
88 | }
89 | }
90 | ```
91 |
92 | 3. Now you need some way of injecting the generated css into the html. There are many ways to do it, each with their positive and negative aspects.
93 |
94 | **Injecting the css dynamically**
95 | ```js
96 | require('inject-css')(renderer.renderToString())
97 | ```
98 |
99 | **Render to a sheet list ([Next.js](http://ghub.io/next) example)**
100 |
101 | This makes the most sense when you create the document skeleton with JSX.
102 |
103 | ```js
104 | import Document, { Head } from 'next/document'
105 |
106 | class CustomDocument extends Document {
107 | static getInitialProps ({ renderPage }) {
108 | const page = renderPage()
109 | const sheets = renderer.renderToSheetList()
110 | renderer.clear()
111 | return { ...page, sheets }
112 | }
113 |
114 | render () {
115 | const sheets = this.props.sheets
116 | return (
117 |
118 | {sheets.map(({ type, media, css }) => (
119 |
120 | ))}
121 |
122 |
123 | ...
124 | )
125 | }
126 | }
127 | ```
128 |
129 | 4. You're done!
130 |
131 | ## Components
132 |
133 | ### Box
134 |
135 | ```js
136 | Hello Veel!
137 | ```
138 |
139 | The core layout component. Take a look at [`styled-system`](https://github.com/jxnblk/styled-system/blob/master/README.md) for documentation on `` `props`.
140 |
141 | #### `Box.is`
142 |
143 | By default a `` component will render out to a `div`. You can change the tag by providing an `is` property.
144 |
145 | ### Flex
146 |
147 | ```js
148 |
149 | ```
150 |
151 | [View the example](./demo/src/index.js) on how to use it.
152 |
153 | #### `Flex.center`
154 |
155 | Sets both `alignItems` and `justifyContent` to `center`.
156 |
157 | #### `Flex.wrap`
158 |
159 | Sets `flexWrap` to `wrap`.
160 |
161 | #### `Flex.column`
162 |
163 | Sets `flexDirection` to `column`.
164 |
165 | #### `Flex.justify`
166 |
167 | CSS `justifyContent` property.
168 |
169 | #### `Flex.align`
170 |
171 | CSS `alignItem` property.
172 |
173 | #### `Flex.order`
174 |
175 | CSS `order` property.
176 |
177 | ## Plugins
178 |
179 | By using fela you have a wide variety of plugins available. Check out the [plugin list](http://fela.js.org/docs/introduction/Ecosystem.html#plugins)
180 |
181 | ### Recommend plugins
182 |
183 | * [**`fela-plugin-embedded`**](https://github.com/rofrischmann/fela/tree/master/packages/fela-plugin-embedded) - Inline keyframes and font-faces
184 |
185 | ```js
186 |
192 |
193 | // -> { animationName: 'k1' }
194 | ```
195 |
196 | ## Author
197 |
198 | **veel** © [Fabian Eichenberger](https://github.com/queckezz), Released under the [MIT](./license) License.
199 | Authored and maintained by Fabian Eichenberger with help from contributors ([list](https://github.com/queckezz/veel/contributors)).
200 |
201 | > GitHub [@queckezz](https://github.com/queckezz) · Twitter [@queckezz](https://twitter.com/queckezz)
202 |
203 | [version-image]: https://img.shields.io/npm/v/veel.svg?style=flat-square
204 | [version-url]: https://npmjs.org/package/veel
205 |
206 | [standard-image]: https://img.shields.io/badge/code-standard-brightgreen.svg?style=flat-square
207 | [standard-url]: https://github.com/feross/standard
208 |
--------------------------------------------------------------------------------
/src/components/box.js:
--------------------------------------------------------------------------------
1 | import styled from '../styled'
2 |
3 | const Box = styled('div')
4 |
5 | export default Box
6 |
--------------------------------------------------------------------------------
/src/components/flex.js:
--------------------------------------------------------------------------------
1 | import { oneOf, bool, number } from 'prop-types'
2 | import styled from '../styled'
3 | import React from 'react'
4 |
5 | const Flex = styled(
6 | (
7 | theme,
8 | {
9 | justify,
10 | column,
11 | center,
12 | order,
13 | align,
14 | wrap,
15 | ...props
16 | }
17 | ) => ({
18 | props,
19 | css: {
20 | display: 'flex',
21 | alignItems: align,
22 | justifyContent: justify,
23 | flexWrap: wrap ? 'wrap' : null,
24 | flexDirection: column ? 'column' : null,
25 | order,
26 |
27 | ...(center
28 | ? {
29 | alignItems: 'center',
30 | justifyContent: 'center'
31 | }
32 | : {})
33 | }
34 | })
35 | )
36 |
37 | Flex.PropTypes = {
38 | align: oneOf([
39 | 'flex-start',
40 | 'flex-end',
41 | 'baseline',
42 | 'center',
43 | 'stretch'
44 | ]),
45 |
46 | justify: oneOf([
47 | 'flex-start',
48 | 'flex-end',
49 | 'center',
50 | 'space-between',
51 | 'space-around'
52 | ]),
53 |
54 | order: number,
55 | column: bool,
56 | wrap: bool
57 | }
58 |
59 | export default Flex
60 |
--------------------------------------------------------------------------------
/src/components/index.js:
--------------------------------------------------------------------------------
1 | export { default as Flex } from './flex'
2 | export { default as Box } from './box'
--------------------------------------------------------------------------------
/src/context.js:
--------------------------------------------------------------------------------
1 | import { shape, object, array, number } from 'prop-types'
2 |
3 | const ns = '__VEEL__'
4 |
5 | const types = {
6 | [ns]: shape({
7 | renderer: object.isRequired,
8 |
9 | config: shape({
10 | space: array,
11 | fontSizes: array,
12 | breakpoints: array,
13 | colors: object
14 | })
15 | })
16 | }
17 |
18 | export default { types, ns }
19 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | export { default as StyleProvider } from './provider'
2 | export { createRenderer } from 'fela'
3 | export * from './components'
4 |
--------------------------------------------------------------------------------
/src/provider.js:
--------------------------------------------------------------------------------
1 | import context from './context'
2 | import { Component, Children } from 'react'
3 |
4 | class StyleProvider extends Component {
5 | getChildContext() {
6 | return {
7 | [context.ns]: this.props
8 | }
9 | }
10 |
11 | render() {
12 | const children = Children.only(this.props.children)
13 | return children
14 | }
15 | }
16 |
17 | StyleProvider.childContextTypes = context.types
18 |
19 | export default StyleProvider
20 |
--------------------------------------------------------------------------------
/src/styled.js:
--------------------------------------------------------------------------------
1 | import context from './context'
2 | import isFunction from '@f/is-function'
3 | import React from 'react'
4 |
5 | import {
6 | removeProps,
7 | fontSize,
8 | space,
9 | width,
10 | color
11 | } from 'styled-system'
12 |
13 | import { combineRules } from 'fela'
14 |
15 | const styled = (BaseComponent = 'div', createComponent) => {
16 | if (isFunction(BaseComponent)) {
17 | createComponent = BaseComponent
18 | BaseComponent = 'div'
19 | }
20 |
21 | const VeelComponent = ({ is, css, ...props }, ctx) => {
22 | const { renderer, theme } = ctx[context.ns]
23 |
24 | const style = createComponent
25 | ? createComponent(theme, props)
26 | : { props }
27 |
28 | const cn = renderer.renderRule(
29 | combineRules(fontSize, space, width, color, () => ({
30 | ...style.css,
31 | ...css
32 | })),
33 | props
34 | )
35 |
36 | const Component = is || BaseComponent
37 |
38 | return (
39 |
43 | )
44 | }
45 |
46 | VeelComponent.contextTypes = context.types
47 | return VeelComponent
48 | }
49 |
50 | export default styled
51 |
--------------------------------------------------------------------------------