typestyle
Version:
106 lines (105 loc) • 3.85 kB
JavaScript
/** Raf for node + browser */
export var raf = typeof requestAnimationFrame === 'undefined'
/**
* Make sure setTimeout is always invoked with
* `this` set to `window` or `global` automatically
**/
? function (cb) { return setTimeout(cb); }
/**
* Make sure window.requestAnimationFrame is always invoked with `this` window
* We might have raf without window in case of `raf/polyfill` (recommended by React)
**/
: typeof window === 'undefined'
? requestAnimationFrame
: requestAnimationFrame.bind(window);
/**
* Utility to join classes conditionally
*/
export function classes() {
var classes = [];
for (var _i = 0; _i < arguments.length; _i++) {
classes[_i] = arguments[_i];
}
return classes
.map(function (c) { return c && typeof c === 'object' ? Object.keys(c).map(function (key) { return !!c[key] && key; }) : [c]; })
.reduce(function (flattened, c) { return flattened.concat(c); }, [])
.filter(function (c) { return !!c; })
.join(' ');
}
/**
* Merges various styles into a single style object.
* Note: if two objects have the same property the last one wins
*/
export function extend() {
var objects = [];
for (var _i = 0; _i < arguments.length; _i++) {
objects[_i] = arguments[_i];
}
/** The final result we will return */
var result = {};
for (var _a = 0, objects_1 = objects; _a < objects_1.length; _a++) {
var object = objects_1[_a];
if (object == null || object === false) {
continue;
}
for (var key in object) {
/** Falsy values except a explicit 0 is ignored */
var val = object[key];
if (!val && val !== 0) {
continue;
}
/** if nested media or pseudo selector */
if (key === '$nest' && val) {
result[key] = result['$nest'] ? extend(result['$nest'], val) : val;
}
/** if freestyle sub key that needs merging. We come here due to our recursive calls */
else if ((key.indexOf('&') !== -1 || key.indexOf('@media') === 0)) {
result[key] = result[key] ? extend(result[key], val) : val;
}
else {
result[key] = val;
}
}
}
return result;
}
/**
* Utility to help customize styles with media queries. e.g.
* ```
* style(
* media({maxWidth:500}, {color:'red'})
* )
* ```
*/
export var media = function (mediaQuery) {
var _a;
var objects = [];
for (var _i = 1; _i < arguments.length; _i++) {
objects[_i - 1] = arguments[_i];
}
var mediaQuerySections = [];
if (mediaQuery.type)
mediaQuerySections.push(mediaQuery.type);
if (mediaQuery.orientation)
mediaQuerySections.push("(orientation: " + mediaQuery.orientation + ")");
if (mediaQuery.minWidth)
mediaQuerySections.push("(min-width: " + mediaLength(mediaQuery.minWidth) + ")");
if (mediaQuery.maxWidth)
mediaQuerySections.push("(max-width: " + mediaLength(mediaQuery.maxWidth) + ")");
if (mediaQuery.minHeight)
mediaQuerySections.push("(min-height: " + mediaLength(mediaQuery.minHeight) + ")");
if (mediaQuery.maxHeight)
mediaQuerySections.push("(max-height: " + mediaLength(mediaQuery.maxHeight) + ")");
if (mediaQuery.prefersColorScheme)
mediaQuerySections.push("(prefers-color-scheme: " + mediaQuery.prefersColorScheme + ")");
var stringMediaQuery = "@media " + mediaQuerySections.join(' and ');
var object = {
$nest: (_a = {},
_a[stringMediaQuery] = extend.apply(void 0, objects),
_a)
};
return object;
};
var mediaLength = function (value) {
return typeof value === 'string' ? value : value + "px";
};