Skip to content

Commit

Permalink
push
Browse files Browse the repository at this point in the history
  • Loading branch information
Samuel Hobl committed May 4, 2021
1 parent 3929458 commit 1c45d4a
Show file tree
Hide file tree
Showing 50 changed files with 1,808 additions and 257 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ module.exports = {
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/naming-convention': 'off',
'@typescript-eslint/no-unnecessary-condition': ['error'],
'react/destructuring-assignment': 'off',
'react/prop-types': 'off',
'react/require-default-props': 'off',
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
"workspaces": [
"packages/utils",
"packages/interpolate",
"packages/interpolate-new",
"packages/integral",
"packages/jsx",
"packages/otion",
"packages/quark",
"packages/kwark",
"packages/theme-base",
Expand Down
35 changes: 35 additions & 0 deletions packages/interpolate-new/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"name": "@gumption-ui/interpolate-new",
"version": "0.0.1",
"private": true,
"license": "MIT",
"main": "./dist/index.js",
"module": "./dist/index.esm.js",
"source": "./src/index.ts",
"types": "./dist/index.d.ts",
"files": [
"dist/",
"src/",
"!*.test.*"
],
"scripts": {
"build": "microbundle --no-compress --tsconfig tsconfig.json --globals @gumption-ui/utils=utils",
"develop": "microbundle watch --no-compress --tsconfig tsconfig.json --globals @gumption-ui/utils=utils",
"typecheck": "tsc --noEmit",
"test": "jest"
},
"jest": {
"modulePathIgnorePatterns": [
"dist"
],
"preset": "ts-jest",
"testEnvironment": "node"
},
"dependencies": {
"@gumption-ui/utils": "0.0.1",
"csstype": "^3.0.6"
},
"devDependencies": {
"@gumption-ui/theme-base": "0.0.1"
}
}
12 changes: 12 additions & 0 deletions packages/interpolate-new/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Interpolate

## Installation

Install `@gumption-ui/interpolate-new`

# Inspiration

- https://github.com/system-ui/theme-ui
- https://github.com/styled-system/styled-system
- https://github.com/kripod/glaze
- https://github.com/jamesknelson/use-sx
2 changes: 2 additions & 0 deletions packages/interpolate-new/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './interpolate';
export * from './types';
178 changes: 178 additions & 0 deletions packages/interpolate-new/src/interpolate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
import { get, isFunction } from '@gumption-ui/utils';
import {
Shorthands,
Aliases,
Theme,
GumptionUIStyleObject,
GumptionUICSSObject,
CSSObject,
} from './types';

const transforms = [
'margin',
'marginTop',
'marginRight',
'marginBottom',
'marginLeft',
'marginX',
'marginY',
'top',
'bottom',
'left',
'right',
].reduce(
(acc, curr) => ({
...acc,
[curr]: positiveOrNegative,
}),
{},
);

type CSSPropsArgument = { theme: Theme } | Theme;

type FuncsArg<T = Record<string, any>> = {
styles: T;
theme: T;
};
type Funcs = Array<(funcsArgs: FuncsArg) => FuncsArg>;

export const interpolate = <
T extends Record<string, any> = GumptionUIStyleObject,
R = CSSObject
>(
...funcs: Funcs
) => (args?: T) => (props: CSSPropsArgument = {}): R => {
const theme = 'theme' in props ? props.theme : props;
const result: any = {};

funcs.push(getObjectWithVariants);

const { styles } = pipe<FuncsArg>(...funcs)({
styles: isFunction(args) ? args(theme) : args || {},
theme,
});

// eslint-disable-next-line guard-for-in, no-restricted-syntax
for (const alias in styles) {
const value = styles[alias as keyof GumptionUICSSObject];

if (value != null) {
const { aliases, shorthands } = theme;

const shorthand =
aliases && alias in aliases
? aliases[alias as Aliases]
: (alias as Exclude<keyof GumptionUICSSObject, Aliases>);

const properties =
shorthands && shorthand in shorthands
? shorthands[shorthand as Shorthands]
: [shorthand as Exclude<typeof shorthand, Shorthands>];

// eslint-disable-next-line no-plusplus
for (let i = 0, len = properties.length; i < len; i++) {
const property = properties[i];

if (typeof value === 'object') {
result[property] = interpolate(...funcs)(
(value as unknown) as GumptionUICSSObject,
)(theme);
} else {
const { matchers = {}, scales = {} } = theme;
const scaleName = get(matchers, property);
const scale = get(scales, scaleName);

if (!scale) {
result[property] = value;
continue; // eslint-disable-line no-continue
}

const transform = get(transforms, property, get);

/*
* `value` can be:
* a) a function
* b) reference to another token value
* c) scale value
* d) css value
*/

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: TODO ThemedStyle currently does not support functions as value
let val = isFunction(value) ? value(theme) : value;
const scaleValue =
typeof val === 'number' ? scale[val] : get(scale, val as string);

const refrenceScaleValue = get(scale, scaleValue || '');

val = refrenceScaleValue ?? scaleValue ?? val;
result[property] = transform(scale, val, val);
}
}
}
}
return result;
};

function getObjectWithVariants({
styles,
theme,
}: {
styles: GumptionUICSSObject;
theme: Theme;
}) {
if (styles.variant) {
const { variant, ...restStyle } = styles;
let next: any = restStyle;

const variants =
typeof variant === 'string' ? variant.split(' ') : [variant];

for (let i = 0, len = variants.length; i < len; i += 1) {
const variant = variants[i]; // eslint-disable-line @typescript-eslint/no-shadow

const { styles: variantStyles } = getObjectWithVariants({
styles: get(theme, `variants.${variant as string}`, {}),
theme,
});

next = { ...next, ...variantStyles };
}

return {
styles: next,
theme,
};
}

return {
styles,
theme,
};
}

function positiveOrNegative(
scale: Record<string, unknown>,
value: string | number,
): string | number {
if (typeof value !== 'number' || value >= 0) {
if (typeof value === 'string' && value.startsWith('-')) {
const valueWithoutMinus = value.substring(1);
const n = get(scale, valueWithoutMinus, valueWithoutMinus);
if (typeof n === 'number') return Number(n) * -1;
return `-${n}`;
}
return get(scale, value, value);
}
const absolute = Math.abs(value);
const n = get(scale, absolute, absolute);
if (typeof n === 'string') return `-${n}`;
return Number(n) * -1;
}

function pipe<R>(...fns: Array<(a: R) => R>) {
return fns.reduce(
(f, g) => (...value) => f(g(...value)),
(value) => value,
);
}
Loading

0 comments on commit 1c45d4a

Please sign in to comment.