Skip to content
This repository has been archived by the owner on Feb 17, 2021. It is now read-only.

Commit

Permalink
refactor: total rafactoring
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Rewrote the user configuration validation module, deleted Ramda and Flow.
Reduced library size from 16.1kb to 4.07
  • Loading branch information
mg901 committed Mar 26, 2019
1 parent ad8a777 commit 839fc4f
Show file tree
Hide file tree
Showing 17 changed files with 266 additions and 107 deletions.
21 changes: 16 additions & 5 deletions src/helpers/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// is :: Object -> a -> Boolean
export const is = (type) => (x) => Object(x) instanceof type;

// type :: a -> String
export const type = (x) => Object.prototype.toString.call(x).slice(8, -1);

// objectValues :: (String, Maybe [a]) -> [a]
export const objectValues = (target, memo) => (obj) =>
Object.keys(Object(obj)).reduce(
Expand Down Expand Up @@ -36,23 +39,23 @@ export const all = (...fns) => (x) =>

// any :: [Function] -> a -> Boolean
export const any = (...fns) => (x) =>
fns.map((f) => f(x)).every((y) => y === true);
fns.map((f) => f(x)).some((y) => y === true);

// pipe :: [Function] -> a -> a
export const pipe = (...fns) => (x) => fns.reduce((acc, f) => f(acc), x);

// flatten :: [[a]] -> [a]
// flatten :: [a] -> [b]
export const flatten = (arr) =>
arr.reduce(
(acc, item) =>
Array.isArray(item) ? [...acc, ...flatten(item)] : [...acc, item],
[],
);

// reduce :: Function -> ([a], a) -> a
export const reduce = (fn) => (x, accum) => x.reduce(fn, accum);
// reduce :: (Function, a) -> a -> a
export const reduce = (fn, acc) => (x) => x.reduce(fn, acc);

// map :: (a -> b) -> ([a] | Object) -> [b] | Object
// map :: (a -> b) -> a -> b
export const map = (f) => (x) =>
Array.isArray(x)
? x.map(f)
Expand All @@ -64,6 +67,14 @@ export const map = (f) => (x) =>
{},
);

// filter :: (x -> Boolean) -> a -> a
export const filter = (f) => (x) =>
Array.isArray(x)
? x.filter(f)
: Object.keys(x)
.filter((key) => f(x[key]))
.reduce((acc, key) => ({ ...acc, [key]: x[key] }), {});

// invariant :: (a, String) -> Void
export const invariant = (condition, message) => {
if (!condition) {
Expand Down
47 changes: 28 additions & 19 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
import { makeBreakpointsModel } from './make-breakpoints-model';
import constants from './constants';
import { percentage, toEm, toPx } from './convertors';
import { isNumeric } from './validators';
import {
camelize,
normalizeString,
toKebabCase,
toRem,
toSnakeCase,
} from './utils-public';
import { modularScale } from './utils-public/modular-scale';
import {
getTailBreaksValues,
getTailBreaksNames,
makeBreakNamesRow,
export {
is,
type,
head,
tail,
every,
all,
any,
pipe,
flatten,
map,
reduce,
filter,
invariant,
invariantWithPrefix,
} from './helpers';
export { isNumeric } from './utils/validators';
export { camelize, normalizeString, toKebabCase, toSnakeCase } from './utils';
export { modularScale } from './utils/modular-scale';
export {
getTailBreakpointsValues,
getTailBreakpointsNames,
makeBreakpointNamesList,
makeBreakpoints,
getDefaultBreak,
getBreaksModelOrDefaultModel,
} from './utils-public/breakpoints';
getInitialBreakpoint,
} from './utils/breakpoints';
export { makeBreakpointsModel } from './make-breakpoints-model';
export * as constants from './constants';
export { percentage, toEm, toPx, toRem } from './utils/convertors';

export const ratios = {
AUGMENTED_FOURTH: 1.41421,
Expand Down
50 changes: 26 additions & 24 deletions src/make-breakpoints-model/index.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import memoizeone from 'memoize-one';
import { toPxBreakValue } from '../utils/breakpoint-value';
import { basePropProcess } from '../utils/base';
import { calcRatioProcess } from '../utils/ratio';
import { setPropRoot } from '../utils/root';
import { isNotObject, isObject } from '../utils/validators';
import { isValidUserConfig } from '../validate-user-config';
import { pipe, map, reduce } from '../helpers';
import { pipe, map, reduce, filter } from '../helpers';

// makeDefaultBreakpoint :: UserConfig -> [Object]
export const makeDefaultBreakpoint = ({ base, lineHeight, ratio }) =>
// makeInitialBreakpoint :: UserConfig -> [Object]
export const makeInitialBreakpoint = (x) =>
Array.of({
base,
lineHeight,
ratio,
...filter(isNotObject)(x),
name: 'initial',
value: '0px',
});
Expand All @@ -23,12 +21,15 @@ export const setPropName = ([breakName, breakBody]) => ({
});

// makeNamedBreakpoints :: UserConfig -> [Object]
export const makeNamedBreakpoints = ({ base, lineHeight, ratio, ...breaks }) =>
Object.entries(breaks).map(setPropName);
export const makeNamedBreakpoints = pipe(
filter(isObject),
Object.entries,
map(setPropName),
);

// createBreakpoints :: UserConfig -> [Object]
export const createBreakpoints = (x) => [
...makeDefaultBreakpoint(x),
...makeInitialBreakpoint(x),
...makeNamedBreakpoints(x),
];

Expand All @@ -50,29 +51,30 @@ export const inheritProps = (acc, item, index) => [
},
];

// makeBreakpointsMap :: (Object, Object) -> Object
export const makeBreakpointsMap = (acc, breakpoint) => ({
// setBreakpointNameProp :: (Object, Object) -> Object
export const setBreakpointNameProp = (acc, { name, ...breakpoint }) => ({
...acc,
[breakpoint.name]: breakpoint,
[name]: breakpoint,
});

// removePropName :: Object -> Object
export const removePropName = ({ name, ...breaks }) => breaks;

// makeMemoizedBreakpoints :: UserConfig -> Object
export const makeMemoizedBreakpoints = pipe(
// makeBreakpointsProcess :: UserConfig -> Object
export const makeBreakpointsProcess = pipe(
createBreakpoints,
map(renameProp('breakpoint', 'value')),
map(toPxBreakValue),
reduce(inheritProps, []),
map(basePropProcess),
map(calcRatioProcess),
map(setPropRoot),
reduce(makeBreakpointsMap, {}),
map(removePropName),
memoizeone,
reduce(setBreakpointNameProp, {}),
);

const memoizedMakeBreakpoints = memoizeone(makeBreakpointsProcess);

// makeBreakpointsModel :: UserConfig -> Object | Void
export const makeBreakpointsModel = (x) =>
isValidUserConfig(x) ? makeMemoizedBreakpoints(x) : null;

// eslint-disable-next-line consistent-return
export const makeBreakpointsModel = (x) => {
if (isValidUserConfig(x)) {
return memoizedMakeBreakpoints(x);
}
};
80 changes: 80 additions & 0 deletions src/mocks/breakpoints.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
export const breakpoints = [
{
base: [16, 32],
lineHeight: 1.5,
name: 'initial',
ratio: 1.1880883987824906,
root: 12,
value: '0px',
},
{
base: [17],
lineHeight: 1.5,
name: 'tablet',
ratio: 1.1761442744249144,
root: 13,
value: '640px',
},
{
base: [18],
lineHeight: 1.7,
name: 'desktop',
ratio: 1.333,
root: 15.5,
value: '1024px',
},
{
base: [20],
lineHeight: 1.7,
name: 'lgDesktop',
ratio: 1.333,
root: 17,
value: '1200px',
},
{
base: [22],
lineHeight: 1.7,
name: 'xlDesktop',
ratio: 1.333,
root: 18.5,
value: '1600px',
},
];

export const breakpointsModel = {
initial: {
base: [16, 32],
lineHeight: 1.5,
ratio: 1.1880883987824906,
root: 12,
value: '0px',
},
tablet: {
base: [17],
lineHeight: 1.5,
ratio: 1.1761442744249144,
root: 13,
value: '768px',
},
desktop: {
base: [18],
lineHeight: 1.7,
ratio: 1.333,
root: 15.5,
value: '992px',
},
lgDesktop: {
base: [20],
lineHeight: 1.7,
ratio: 1.333,
root: 17,
value: '1200px',
},
xlDesktop: {
base: [22],
lineHeight: 1.7,
ratio: 1.333,
root: 18.5,
value: '1600px',
},
};
2 changes: 2 additions & 0 deletions src/mocks/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { breakpoints, breakpointsModel } from './breakpoints';
export { userConfig, invalidUserConfig } from './user-configs';
45 changes: 45 additions & 0 deletions src/mocks/user-configs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
export const userConfig = {
base: ['16px', '32px'],
lineHeight: 1.5,
ratio: '45px at 6',
tablet: {
breakpoint: '768px',
base: '17px',
},
desktop: {
breakpoint: '992px',
base: '18px',
lineHeight: 1.7,
ratio: 1.333,
},
lgDesktop: {
breakpoint: '1200px',
base: '20px',
},
xlDesktop: {
breakpoint: '1600px',
base: '22px',
},
};

export const invalidUserConfig = {
base: ['1rem', '2em'],
lineHeight: 1.5,
ratio: '45 at 6',
tablet: {
base: '17px',
},
desktop: {
breakpoint: '64rem',
base: '18px',
lineHeight: '1.7',
ratio: 1.333,
},
lgDesktop: {
breakpoint: '75rem',
base: '20px',
},
xlDesktop: {
breakpoint: '100rem',
},
};
5 changes: 2 additions & 3 deletions src/utils/base/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { toPxIfHasEm, toArrIsNotArr } from '../convertors';
import { toArrIsNotArr } from '../convertors';

// makeBase :: (String | [String]) -> [Number]
export const makeBase = (x) =>
toArrIsNotArr(x).map((b) => parseFloat(toPxIfHasEm(b)));
export const makeBase = (x) => toArrIsNotArr(x).map((b) => parseFloat(b));

// basePropProcess :: Object -> Object
export const basePropProcess = ({ base, ...breakpoint }) => ({
Expand Down
7 changes: 0 additions & 7 deletions src/utils/breakpoint-value/index.js

This file was deleted.

24 changes: 15 additions & 9 deletions src/utils/breakpoints/index.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
const { makeBreakpointsModel } = require('../../make-breakpoints-model');
const { pipe, map, tail, head } = require('../../helpers');
import { makeBreakpointsProcess } from '../../make-breakpoints-model';
import { pipe, tail, head, map } from '../../helpers';

// getTailBreakpointsValues :: Object -> [Object]
// getTailBreakpointsValues :: BreakpointsModel -> [Object]
export const getTailBreakpointsValues = pipe(
Object.values,
tail,
);

// getTailBreakpointsNames :: Object -> [String]
// getTailBreakpointsNames :: BreakpointsModel -> [String]
export const getTailBreakpointsNames = pipe(
Object.keys,
tail,
);

// makeBreakpointNamesList :: UserConfig -> String
export const makeBreakpointNamesList = (breaksMap) =>
`'${getTailBreakpointsNames(breaksMap).join(', ')}'`;
// makeBreakpointNamesList :: BreakpointsModel -> String
export const makeBreakpointNamesList = (x) =>
`'${getTailBreakpointsNames(x).join(', ')}'`;

// getPropValue :: Object -> String
// eslint-disable-next-line no-unused-vars
Expand All @@ -26,13 +26,19 @@ export const removeDefaultBreakpooint = ({ initial, ...breaks }) => breaks;

// makeBreakpoints :: UserConfig -> Object
export const makeBreakpoints = pipe(
makeBreakpointsModel,
makeBreakpointsProcess,
removeDefaultBreakpooint,
map(getPropValue),
);

// getInitialBreakpoint :: [Object] -> Object
// getInitialBreakpoint :: BreakpointsModel -> Object
export const getInitialBreakpoint = pipe(
Object.values,
head,
);

// setBreakpointNameProp :: (Object, Object) -> Object
export const setBreakpointNameProp = (acc, { name, ...breakpoint }) => ({
...acc,
[name]: breakpoint,
});
Loading

0 comments on commit 839fc4f

Please sign in to comment.