Skip to content

Commit

Permalink
filter, variables and functions
Browse files Browse the repository at this point in the history
within with() is nestable
  • Loading branch information
secretlifeof committed Aug 25, 2020
1 parent 937ecb8 commit c90d7fa
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 47 deletions.
86 changes: 58 additions & 28 deletions src/base/attachAttrs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,78 +2,108 @@ import render from '../system/render';
import { forwardRef } from '../system/setup';
import getFilteredProps from './getFilteredProps';

function as(this: any, a: any) {
function as(this: any, component: any, a: any) {
this.mergedProps = { ...this.mergedProps, as: a };

return this;
return component;
}

function withComponent(this: any, attrsIn: any, val: any, filter: string[]) {
function withComponent(
this: any,
{
forwardProps = {},
forwardFunctions = [],
forwardFilter = [],
forwardVariant = {}
},
val: any,
filter: string[] = []
) {
/* eslint-disable @typescript-eslint/no-use-before-define */
const attachAttrsBound = attachAttrs.bind(this);
/* eslint-enable @typescript-eslint/no-use-before-define */

const { mergedProps } = this;
const { mergedProps, variant } = this;
const filters = [
...this.removeProps,
...forwardFilter,
...Object.keys(variant),
...filter
];
const WrappedComponent = (props?: any, ref = { current: null }) => {
const refOut = ref && forwardRef ? { ref } : {};
const styles = typeof val === 'function' ? val(props) : val;
const attrs = typeof attrsIn === 'function' ? attrsIn(props) : attrsIn;
const attrs =
typeof forwardProps === 'function' ? forwardProps(props) : forwardProps;
const functionAttrs = forwardFunctions.reduce((acc, cur: any) => {
return { ...acc, ...(typeof cur === 'function' ? cur(props) : cur) };
}, {});
const initValues = this.getInitialValues(props);
const variantStyles = this.getVariantStyles(props);
const filteredProps = getFilteredProps(props, [
...this.removeProps,
...filter
]);
const variantStyles = this.getVariantStyles(props, {
...forwardVariant,
...variant
});
const filteredProps = getFilteredProps(props, filters);

return render({
...initValues,
...attrs,
...mergedProps,
...functionAttrs,
...variantStyles,
...styles,
...filteredProps,
...refOut
});
};

const parentProps = {
forwardProps: { ...forwardProps, ...mergedProps, ...val },
forwardFunctions: [...forwardFunctions, val],
forwardFilter: filters,
forwardVariant: variant
};

// if used without forwardRef
attachAttrsBound(WrappedComponent, { ...attrsIn, ...mergedProps, ...val });
attachAttrsBound(WrappedComponent, parentProps);

const Forwarded = forwardRef
? forwardRef(WrappedComponent)
: WrappedComponent;
// if used with forwardRef
attachAttrsBound(Forwarded, { ...mergedProps, ...val });
attachAttrsBound(Forwarded, parentProps);

this.mergedProps = {};
this.reset();

return forwardRef ? Forwarded : WrappedComponent;
return Forwarded;
}

function merge(this: any, components: any) {
const mergedProps = Array.isArray(components)
? components.reduce((acc: any, cur: any) => ({ ...acc, ...cur.attrs }), {})
: components.attrs;
function merge(this: any, component: any, componentsToBeMerged: any | any[]) {
const mergedProps = Array.isArray(componentsToBeMerged)
? componentsToBeMerged.reduce(
(acc: any, cur: any) => ({ ...acc, ...cur.attrs }),
{}
)
: componentsToBeMerged.attrs;

this.mergedProps = { ...this.mergedProps, ...mergedProps };

return this;
return component;
}

function variants(this: any, types: any) {
function variants(this: any, component: any, types: any) {
this.variant = types;

return this;
return component;
}

function attachAttrs(this: any, component: any, attrs: any) {
function attachAttrs(this: any, component: any, parentProps: any = {}) {
/* eslint no-param-reassign: ["error", { "props": false }] */
component.as = as.bind(this);
// attrs argument necessary for passing attrs to nested component
component.with = withComponent.bind(this, attrs);
component.attrs = attrs;
component.merge = merge.bind(this);
component.variants = variants.bind(this);
// components attribute is necessary for nesting components
component.as = as.bind(this, component);
component.with = withComponent.bind(this, parentProps);
component.merge = merge.bind(this, component);
component.variants = variants.bind(this, component);
}

export default attachAttrs;
4 changes: 2 additions & 2 deletions src/base/attachMethodsToInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ function attachMethodsToInstance(Component: any, instance: any) {
Component.variants = function w(variantObj: any) {
return instance.variants(variantObj);
};
Component.with = function w(props: any) {
return instance.with(props);
Component.with = function w(props: any, filter: string[]) {
return instance.with(props, filter);
};
}

Expand Down
35 changes: 19 additions & 16 deletions src/base/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// @ts-nocheck
import render from '../system/render';
import { forwardRef } from '../system/setup';
import attachAttrs from './attachAttrs';
Expand Down Expand Up @@ -42,8 +41,7 @@ class Base {
return typeof initValues === 'function' ? initValues(props) : initValues;
}

getVariantStyles(props: any) {
const variants = { ...this.variant };
getVariantStyles(props: any, variants: any = {}) {
const variantNames = Object.keys(variants);
let variantStyles = {};
for (let i = 0; i < variantNames.length; i++) {
Expand Down Expand Up @@ -81,19 +79,17 @@ class Base {
return this;
}

with(val: any, filter: string[]) {
with(val: any, filter: string[] = []) {
const attachAttrsBound = attachAttrs.bind(this);

const { mergedProps } = this;
const { mergedProps, variant } = this;
const filters = [...this.removeProps, ...Object.keys(variant), ...filter];
const WrappedComponent = (props?: any, ref = { current: null }) => {
const refOut = ref && forwardRef ? { ref } : {};
const styles = typeof val === 'function' ? val(props) : val;
const initValues = this.getInitialValues(props);
const variantStyles = this.getVariantStyles(props);
const filteredProps = getFilteredProps(props, [
...this.removeProps,
...filter
]);
const variantStyles = this.getVariantStyles(props, variant);
const filteredProps = getFilteredProps(props, [...filters]);

return render({
...initValues,
Expand All @@ -105,20 +101,27 @@ class Base {
});
};

const attachedProps = {
forwardProps: { ...mergedProps, ...val },
forwardFunctions: [val],
forwardFilter: filters,
forwardVariant: variant
// forwardMerge: mergedProps
};

// if used without forwardRef
attachAttrsBound(WrappedComponent, { ...mergedProps, ...val });
attachAttrsBound(WrappedComponent, attachedProps);

// if used with forwardRef
const Forwarded = forwardRef
? forwardRef(WrappedComponent)
: WrappedComponent;
// if used with forwardRef
attachAttrsBound(Forwarded, { ...mergedProps, ...val });
attachAttrsBound(Forwarded, attachedProps);

// this.reset();
this.mergedProps = {};
this.reset();

// return WrappedComponent;
return forwardRef ? Forwarded : WrappedComponent;
return Forwarded;
}

merge(components: any) {
Expand Down
2 changes: 1 addition & 1 deletion src/system/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ interface Config {
/* eslint-disable import/no-mutable-exports */
export let h: (nodeName: string, attributes: any, children: any[]) => any;
export let themeInternal: Theme = defaultTheme;
export let defaultFun = false;
export let defaultFun = true;
export let forwardRef: Function | undefined;
/* eslint-enable import/no-mutable-exports */

Expand Down

0 comments on commit c90d7fa

Please sign in to comment.