twrnc
Version:
simple, expressive API for tailwindcss + react-native
198 lines (197 loc) • 6.69 kB
JavaScript
;
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.warn = exports.unconfiggedStyle = exports.parseUnconfigged = exports.parseAndConsumeDirection = exports.getDirection = exports.toPx = exports.toStyleVal = exports.parseStyleVal = exports.getStyle = exports.mergeStyle = exports.getCompleteStyle = exports.parseNumericValue = exports.complete = void 0;
const types_1 = require("./types");
function complete(style) {
return { kind: `complete`, style };
}
exports.complete = complete;
function parseNumericValue(value, context = {}) {
const { fractions } = context;
if (fractions && value.includes(`/`)) {
const [numerator = ``, denominator = ``] = value.split(`/`, 2);
const parsedNumerator = parseNumericValue(numerator);
const parsedDenominator = parseNumericValue(denominator);
if (!parsedNumerator || !parsedDenominator) {
return null;
}
return [parsedNumerator[0] / parsedDenominator[0], parsedDenominator[1]];
}
const number = parseFloat(value);
if (Number.isNaN(number)) {
return null;
}
const match = value.match(/(([a-z]{2,}|%))$/);
if (!match) {
return [number, types_1.Unit.none];
}
switch (match === null || match === void 0 ? void 0 : match[1]) {
case `rem`:
return [number, types_1.Unit.rem];
case `px`:
return [number, types_1.Unit.px];
case `em`:
return [number, types_1.Unit.em];
case `%`:
return [number, types_1.Unit.percent];
case `vw`:
return [number, types_1.Unit.vw];
case `vh`:
return [number, types_1.Unit.vh];
default:
return null;
}
}
exports.parseNumericValue = parseNumericValue;
function getCompleteStyle(prop, value, context = {}) {
const styleVal = parseStyleVal(value, context);
return styleVal === null ? null : complete({ [prop]: styleVal });
}
exports.getCompleteStyle = getCompleteStyle;
function mergeStyle(prop, value, style) {
const styleVal = parseStyleVal(value);
if (styleVal !== null) {
style[prop] = styleVal;
}
return style;
}
exports.mergeStyle = mergeStyle;
function getStyle(prop, value) {
const styleVal = parseStyleVal(value);
return styleVal === null ? null : { [prop]: styleVal };
}
exports.getStyle = getStyle;
function parseStyleVal(value, context = {}) {
if (value === undefined) {
return null;
}
const parsed = parseNumericValue(String(value), context);
if (parsed) {
return toStyleVal(...parsed, context);
}
else {
return null;
}
}
exports.parseStyleVal = parseStyleVal;
function toStyleVal(number, unit, context = {}) {
const { isNegative, device } = context;
switch (unit) {
case types_1.Unit.rem:
return number * 16 * (isNegative ? -1 : 1);
case types_1.Unit.px:
return number * (isNegative ? -1 : 1);
case types_1.Unit.percent:
return `${isNegative ? `-` : ``}${number}%`;
case types_1.Unit.none:
return number * (isNegative ? -1 : 1);
case types_1.Unit.vw:
if (!(device === null || device === void 0 ? void 0 : device.windowDimensions)) {
(0, exports.warn)(`\`vw\` CSS unit requires configuration with \`useDeviceContext()\``);
return null;
}
return device.windowDimensions.width * (number / 100);
case types_1.Unit.vh:
if (!(device === null || device === void 0 ? void 0 : device.windowDimensions)) {
(0, exports.warn)(`\`vh\` CSS unit requires configuration with \`useDeviceContext()\``);
return null;
}
return device.windowDimensions.height * (number / 100);
default:
return null;
}
}
exports.toStyleVal = toStyleVal;
function toPx(value) {
const parsed = parseNumericValue(value);
if (!parsed) {
return null;
}
const [number, unit] = parsed;
switch (unit) {
case types_1.Unit.rem:
return number * 16;
case types_1.Unit.px:
return number;
default:
return null;
}
}
exports.toPx = toPx;
const DIR_MAP = {
t: `Top`,
tr: `TopRight`,
tl: `TopLeft`,
b: `Bottom`,
br: `BottomRight`,
bl: `BottomLeft`,
l: `Left`,
r: `Right`,
x: `Horizontal`,
y: `Vertical`,
};
function getDirection(string) {
return DIR_MAP[string !== null && string !== void 0 ? string : ``] || `All`;
}
exports.getDirection = getDirection;
function parseAndConsumeDirection(utilityFragment) {
let direction = `All`;
const consumed = utilityFragment.replace(/^-(t|b|r|l|tr|tl|br|bl)(-|$)/, (_, dir) => {
direction = getDirection(dir);
return ``;
});
return [consumed, direction];
}
exports.parseAndConsumeDirection = parseAndConsumeDirection;
function parseUnconfigged(value, context = {}) {
if (value.includes(`/`)) {
const style = unconfiggedStyleVal(value, { ...context, fractions: true });
if (style)
return style;
}
if (value[0] === `[`) {
value = value.slice(1, -1);
}
return unconfiggedStyleVal(value, context);
}
exports.parseUnconfigged = parseUnconfigged;
function unconfiggedStyle(prop, value, context = {}) {
const styleVal = parseUnconfigged(value, context);
if (styleVal === null) {
return null;
}
return complete({ [prop]: styleVal });
}
exports.unconfiggedStyle = unconfiggedStyle;
function unconfiggedStyleVal(value, context = {}) {
if (value === `px`) {
return 1;
}
const parsed = parseNumericValue(value, context);
if (!parsed) {
return null;
}
let [number, unit] = parsed;
if (context.fractions) {
unit = types_1.Unit.percent;
number *= 100;
}
// not sure if this is the right approach, but this allows arbitrary
// non-bracket numbers, like top-73 and it INFERS the meaning to be
// tailwind's default scale for spacing, which is 1 = 0.25rem
if (unit === types_1.Unit.none) {
number = number / 4;
unit = types_1.Unit.rem;
}
return toStyleVal(number, unit, context);
}
function consoleWarn(...args) {
console.warn(...args); // eslint-disable-line no-console
}
function noopWarn(..._) {
// ¯\_(ツ)_/¯
}
exports.warn = typeof process === `undefined` || ((_a = process === null || process === void 0 ? void 0 : process.env) === null || _a === void 0 ? void 0 : _a.JEST_WORKER_ID) === undefined
? consoleWarn
: noopWarn;