├── .npmignore
├── circle.yml
├── .babelrc
├── .gitignore
├── example
├── index.html
├── components.js
├── clrs.js
├── product-card.js
├── profile-card.js
└── index.js
├── __tests__
├── __snapshots__
│ ├── with-color.test.js.snap
│ ├── with-background-color.test.js.snap
│ ├── with-size.test.js.snap
│ ├── with-base-styles.test.js.snap
│ ├── with-typography.test.js.snap
│ ├── with-spacing.test.js.snap
│ ├── with-border.test.js.snap
│ ├── with-defaults.test.js.snap
│ └── with-msrd.test.js.snap
├── style-helper.test.js
├── media-queries.test.js
├── with-color.test.js
├── with-base-styles.test.js
├── with-size.test.js
├── with-background-color.test.js
├── with-defaults.test.js
├── with-typography.test.js
├── with-spacing.test.js
├── with-border.test.js
├── with-msrd.test.js
└── utils.test.js
├── src
├── with-defaults.js
├── index.js
├── with-msrd.js
├── with-base-styles.js
├── style-helper.js
├── with-color.js
├── with-background-color.js
├── with-typography.js
├── media-queries.js
├── with-size.js
├── with-spacing.js
├── utils.js
└── with-border.js
├── webpack.dev.config.js
├── License
├── webpack.prod.config.js
├── .eslintrc
├── package.json
└── README.md
/.npmignore:
--------------------------------------------------------------------------------
1 | # dependencies
2 | node_modules
3 |
4 | # testing
5 | coverage
6 |
7 | # production
8 | build
9 |
10 | # misc
11 | .DS_Store
12 | .env
13 | npm-debug.log
14 | yarn-error.log
15 | stats.json
16 |
--------------------------------------------------------------------------------
/circle.yml:
--------------------------------------------------------------------------------
1 | machine:
2 | node:
3 | version: 6
4 |
5 | dependencies:
6 | override:
7 | - yarn
8 | cache_directories:
9 | - ~/.cache/yarn
10 |
11 | test:
12 | override:
13 | - yarn test
14 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "react"],
3 | "env": {
4 | "commonjs": {
5 | "presets": [
6 | ["es2015", { modules: false }],
7 | "react"
8 | ],
9 | }
10 | },
11 | "plugins": [
12 | "ramda",
13 | "transform-object-rest-spread"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | node_modules
5 |
6 | # testing
7 | coverage
8 |
9 | # production
10 | build
11 | dist
12 | lib
13 | es
14 |
15 | # misc
16 | .DS_Store
17 | .env
18 | npm-debug.log
19 | yarn-error.log
20 | stats.json
21 |
--------------------------------------------------------------------------------
/example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | tachyons msrd tests
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/__tests__/__snapshots__/with-color.test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Button 1`] = `
4 |
9 | `;
10 |
11 | exports[`Div 1`] = `
12 |
15 | `;
16 |
--------------------------------------------------------------------------------
/src/with-defaults.js:
--------------------------------------------------------------------------------
1 | import { createEagerElement } from './utils';
2 |
3 | export const withDefaults = props => (component) => {
4 | const WithDefaults = ownerProps =>
5 | createEagerElement(component, ownerProps);
6 | WithDefaults.defaultProps = props;
7 | WithDefaults.propTypes = component.propTypes;
8 |
9 | return WithDefaults;
10 | };
11 |
--------------------------------------------------------------------------------
/__tests__/__snapshots__/with-background-color.test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Button 1`] = `
4 |
9 | `;
10 |
11 | exports[`Div 1`] = `
12 |
15 | `;
16 |
--------------------------------------------------------------------------------
/__tests__/__snapshots__/with-size.test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Button 1`] = `
4 |
9 | `;
10 |
11 | exports[`Div 1`] = `
12 |
15 | `;
16 |
--------------------------------------------------------------------------------
/__tests__/__snapshots__/with-base-styles.test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Button 1`] = `
4 |
9 | `;
10 |
11 | exports[`Div 1`] = `
12 |
15 | `;
16 |
--------------------------------------------------------------------------------
/__tests__/style-helper.test.js:
--------------------------------------------------------------------------------
1 | import { classesFor } from '../src/style-helper';
2 |
3 | test('classesFor', () => {
4 | expect(classesFor({ ma: '', mt: undefined, ml: '', mr: null, mb: '', mv: '', mh: '' }))
5 | .toEqual(['ma', 'ml', 'mb', 'mv', 'mh']);
6 |
7 | expect(classesFor({ f: '-headline', 'lh-': 'title', '': 'washed-red' }))
8 | .toEqual(['f-headline', 'lh-title', 'washed-red']);
9 | });
10 |
--------------------------------------------------------------------------------
/__tests__/__snapshots__/with-typography.test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Button 1`] = `
4 |
9 | `;
10 |
11 | exports[`Div 1`] = `
12 |
15 | `;
16 |
--------------------------------------------------------------------------------
/__tests__/__snapshots__/with-spacing.test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Button 1`] = `
4 |
9 | `;
10 |
11 | exports[`Div 1`] = `
12 |
15 | `;
16 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import { compose as ramdaCompose } from 'ramda';
2 |
3 | export * from './with-spacing';
4 | export * from './with-background-color';
5 | export * from './with-color';
6 | export * from './with-size';
7 | export * from './with-border';
8 | export * from './with-typography';
9 | export * from './with-defaults';
10 | export * from './with-base-styles';
11 | export * from './with-msrd';
12 | export const compose = ramdaCompose;
13 |
--------------------------------------------------------------------------------
/__tests__/__snapshots__/with-border.test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Button 1`] = `
4 |
9 | `;
10 |
11 | exports[`Div 1`] = `
12 |
15 | `;
16 |
--------------------------------------------------------------------------------
/__tests__/media-queries.test.js:
--------------------------------------------------------------------------------
1 | import { mqObjToSelectors } from '../src/media-queries';
2 |
3 | test('mqObjToSelectors', () => {
4 | const fontClasses = mqObjToSelectors('f', { l: 1, m: 2, ns: 3, all: 4 });
5 | expect(fontClasses).toEqual(['f1-l', 'f2-m', 'f3-ns', 'f4']);
6 |
7 | expect(() => mqObjToSelectors('radius', { l: 3, all: 2, foo: 1 }))
8 | .toThrow('Invalid media query type supplied to \'radius\'. It only supports all, ns, m & l.');
9 | });
10 |
--------------------------------------------------------------------------------
/__tests__/__snapshots__/with-defaults.test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Button 1`] = `
4 |
13 | `;
14 |
15 | exports[`Div 1`] = `
16 |
23 | `;
24 |
--------------------------------------------------------------------------------
/src/with-msrd.js:
--------------------------------------------------------------------------------
1 | import { compose } from 'ramda';
2 | import { withSpacing } from './with-spacing';
3 | import { withBackgroundColor } from './with-background-color';
4 | import { withColor } from './with-color';
5 | import { withSize } from './with-size';
6 | import { withBorder } from './with-border';
7 | import { withTypography } from './with-typography';
8 |
9 | export const withMeasured = colors => compose(
10 | withSpacing,
11 | withBackgroundColor(colors),
12 | withColor(colors),
13 | withSize,
14 | withBorder(colors),
15 | withTypography,
16 | );
17 |
--------------------------------------------------------------------------------
/src/with-base-styles.js:
--------------------------------------------------------------------------------
1 | import R from 'ramda';
2 | import PropTypes from 'prop-types';
3 | import { cx, createWithStyleHoc } from './utils';
4 |
5 | const sizePropTypes = {
6 | className: PropTypes.any,
7 | };
8 |
9 | const styleTransform = baseStyles => ({ className, ...ownerProps }) =>
10 | R.merge(
11 | { className: cx([baseStyles, className]) },
12 | ownerProps,
13 | );
14 |
15 | export const withBaseStyles = styles => component => createWithStyleHoc({
16 | name: 'withBaseStyles',
17 | transformation: styleTransform(styles),
18 | propTypes: sizePropTypes,
19 | component,
20 | });
21 |
--------------------------------------------------------------------------------
/src/style-helper.js:
--------------------------------------------------------------------------------
1 | import R from 'ramda';
2 | import { mqObjToSelectors } from './media-queries';
3 | import { isPresent } from './utils';
4 |
5 | const hasMediaQuery = R.compose(R.is(Object), R.nth(1));
6 |
7 | const selectorFor = R.curry((prop, val) => `${prop}${val}`);
8 |
9 | const selectorWithMQFor = R.ifElse(hasMediaQuery,
10 | R.apply(mqObjToSelectors),
11 | R.apply(selectorFor),
12 | );
13 |
14 | /**
15 | * Get multiple tachyon classes
16 | * using an object where key is
17 | * selector type and value is value
18 | */
19 | export const classesFor = R.compose(
20 | R.map(selectorWithMQFor),
21 | R.toPairs,
22 | R.filter(isPresent),
23 | );
24 |
--------------------------------------------------------------------------------
/src/with-color.js:
--------------------------------------------------------------------------------
1 | import R from 'ramda';
2 | import PropTypes from 'prop-types';
3 | import { classesFor } from './style-helper';
4 | import { cx, createWithStyleHoc } from './utils';
5 |
6 | const colorPropTypes = colors => ({
7 | color: PropTypes.oneOf(colors),
8 | className: PropTypes.any,
9 | });
10 |
11 | function colorTransform({ className, color, ...ownerProps }) {
12 | return R.merge(
13 | { className: cx([classesFor({ '': color }), className]) },
14 | ownerProps,
15 | );
16 | }
17 |
18 | export const withColor = colors => component => createWithStyleHoc({
19 | name: 'withColor',
20 | transformation: colorTransform,
21 | propTypes: colorPropTypes(colors),
22 | component,
23 | });
24 |
--------------------------------------------------------------------------------
/__tests__/__snapshots__/with-msrd.test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Button 1`] = `
4 |
9 | `;
10 |
11 | exports[`Div 1`] = `
12 |
15 | `;
16 |
--------------------------------------------------------------------------------
/src/with-background-color.js:
--------------------------------------------------------------------------------
1 | import R from 'ramda';
2 | import PropTypes from 'prop-types';
3 | import { classesFor } from './style-helper';
4 | import { cx, createWithStyleHoc } from './utils';
5 |
6 | const backgroundColorPropTypes = colors => ({
7 | bg: PropTypes.oneOf(colors),
8 | className: PropTypes.any,
9 | });
10 |
11 | function backgroundColorTransform({ className, bg, ...ownerProps }) {
12 | return R.merge(
13 | { className: cx([classesFor({ 'bg-': bg }), className]) },
14 | ownerProps,
15 | );
16 | }
17 |
18 | export const withBackgroundColor = colors => component => createWithStyleHoc({
19 | name: 'withBackgroundColor',
20 | transformation: backgroundColorTransform,
21 | propTypes: backgroundColorPropTypes(colors),
22 | component,
23 | });
24 |
--------------------------------------------------------------------------------
/__tests__/with-color.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import renderer from 'react-test-renderer';
3 | import { withColor } from '../src/with-color';
4 | import clrs from '../example/clrs';
5 |
6 | const Button = withColor(clrs)(props => );
7 | const Div = withColor(clrs)('div');
8 |
9 | test('Button', () => {
10 | const tree = renderer.create(
11 |