Skip to content

Commit

Permalink
feat: reduced styles evaluation for never used variant groups combina…
Browse files Browse the repository at this point in the history
…tions
  • Loading branch information
greenfrvr committed Dec 12, 2022
1 parent 55ffc8b commit f0d0b6a
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 40 deletions.
27 changes: 14 additions & 13 deletions packages/eva/mapping.json
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,6 @@
"default": false,
"priority": 1,
"scope": "mobile"
},
"focused": {
"default": false,
"priority": 2,
"scope": "mobile"
}
}
},
Expand Down Expand Up @@ -437,8 +432,7 @@
"appearances": {
"filled": {
"mapping": {
"textFontFamily": "text-font-family",
"iconMarginHorizontal": 4
"textFontFamily": "text-font-family"
},
"variantGroups": {
"status": {
Expand Down Expand Up @@ -4914,7 +4908,7 @@
},
"status": {
"basic": {
"default": false
"default": true
},
"primary": {
"default": false
Expand All @@ -4941,7 +4935,6 @@
"appearances": {
"default": {
"mapping": {
"color": "text-basic-color"
},
"variantGroups": {
"category": {
Expand Down Expand Up @@ -5037,13 +5030,21 @@
}
},
"alternative": {
"mapping": {
"color": "text-alternate-color"
"variantGroups": {
"status": {
"basic": {
"color": "text-alternate-color"
}
}
}
},
"hint": {
"mapping": {
"color": "text-hint-color"
"variantGroups": {
"status": {
"basic": {
"color": "text-hint-color"
}
}
}
}
}
Expand Down
39 changes: 30 additions & 9 deletions packages/processor/js/src/processor/mapping/mappingProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Processor } from '../processor';
import {
getComponentVariants,
getComponentStates,
needsAllVariantCases,
SEPARATOR_MAPPING_ENTRY,
} from '../../service';

Expand All @@ -29,21 +30,25 @@ export class MappingProcessor implements Processor<ThemeMappingType, MappingMeta

private getComponentMappingMeta(mapping: ThemeMappingType, component: string): MappingMetaType[] {
const componentMapping: ControlMappingType = mapping[component];
//variants and states possible configurations are the same across all appearances, so we can evaluate them once
const variants = this.getComponentVariants(mapping, component);
const states = this.getComponentStates(mapping, component);

return Object.keys(componentMapping.appearances).map((appearance: string): MappingMetaType => {
return {
name: component,
appearance: appearance,
variants: this.getComponentVariants(mapping, component),
states: this.getComponentStates(mapping, component),
appearance,
variants,
states,
};
});
}

private getComponentVariants(mapping: ThemeMappingType, component: string): string[] {
const needsAllCases = needsAllVariantCases(mapping, component);
const variants: string[][] = getComponentVariants(mapping, component);

return this.concatComponentVariants([...variants]);
return this.concatComponentVariants(variants, [], needsAllCases);
}

private getComponentStates(mapping: ThemeMappingType, component: string): string[] {
Expand All @@ -52,16 +57,32 @@ export class MappingProcessor implements Processor<ThemeMappingType, MappingMeta
return this.concatComponentStates([...states]);
}

private concatComponentVariants(variants: string[][], result: string[] = []): string[] {
private concatComponentVariants(variants: string[][], result: string[], needsAllCases: boolean): string[] {
if (variants.length === 0) {
return result;
}

const concat = variants.reduce((acc: string[], current: string[]) => {
return [...acc, ...this.concatVariantGroups(acc, current)];
}, variants.shift());
if (needsAllCases) {
//this is the case when there is no default path for variant groups,
//e.i. not all variant groups values has default values
//all possible combinations will be evaluated
const concat = variants.reduce((acc: string[], current: string[]) => {
return [...acc, ...this.concatVariantGroups(acc, current)];
}, variants.shift());

return this.concatComponentVariants(variants, [...result, ...concat]);
return this.concatComponentVariants(variants, [...result, ...concat], needsAllCases);
}

//by default, we will evaluate only required variant groups combinations
return variants.reduce((acc: string[], current: string[]) => {
if (acc.length === 0) {
return current;
}

return acc.reduce((res, c) => {
return [...res, ...current.map(x => c.concat(SEPARATOR_MAPPING_ENTRY, x))];
}, []);
}, []);
}

private concatVariantGroups(lhs: string[], rhs: string[]): string[] {
Expand Down
62 changes: 44 additions & 18 deletions packages/processor/js/src/service/style/style.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import {
ThemeMappingType,
ControlMappingType,
ThemedStyleType,
MappingType,
StrictTheme,
StatelessMappingType,
ParameterType,
} from '@eva-design/dss';
Expand Down Expand Up @@ -125,21 +123,26 @@ export function createAllStyles(mapping: ThemeMappingType,
variants: string[],
states: string[],
theme: ThemedStyleType): [string, ThemedStyleType][] {

const stateless = createStyleEntry(mapping,
component,
appearance,
appearance,
'',
'',
theme,
);

const withStates = states.reduce((acc: [string, ThemedStyleType][], current: string) => {
const key = appearance.concat(SEPARATOR_MAPPING_ENTRY, current);
const next = createStyleEntry(mapping, component, key, appearance, '', current, theme);
return [...acc, next];
}, []);
let stateless = undefined;
let withStates = [];

if (needsAllVariantCases(mapping, component)) {
//we need this config when there are no variant groups or there are no default paths defined
stateless = createStyleEntry(mapping,
component,
appearance,
appearance,
'',
'',
theme,
);

withStates = states.reduce((acc: [ string, ThemedStyleType ][], current: string) => {
const key = appearance.concat(SEPARATOR_MAPPING_ENTRY, current);
const next = createStyleEntry(mapping, component, key, appearance, '', current, theme);
return [ ...acc, next ];
}, []);
}

const withVariants = variants.map(variant => {
const key = appearance.concat(SEPARATOR_MAPPING_ENTRY, variant);
Expand All @@ -159,7 +162,7 @@ export function createAllStyles(mapping: ThemeMappingType,
...withStates,
...withVariants,
...withVariantStates,
];
].filter(Boolean);
}

export function getStyle(mapping: ThemeMappingType,
Expand Down Expand Up @@ -359,6 +362,29 @@ function createStyleEntry(mapping: ThemeMappingType,
return [key, value];
}

/**
* Tells if component requires all variant groups combinations to be generated.
* Basically that just means that default variant group values are not defined for all variant groups.
*
* @param mapping: ThemeMappingType - theme mapping configuration
* @param component: string - component name
*
* @return (boolean) - key identical to some of `source` keys if presents
*/
export function needsAllVariantCases(mapping: ThemeMappingType, component: string): boolean {
const { meta } = mapping[component];
const variantKeys = Object.keys(meta.variantGroups)

if (variantKeys.length === 0) {
return true;
}

return variantKeys.some(key => {
const group = meta.variantGroups[key];
return !Object.keys(group).find(x => group[x].default);
});
}

function normalize(params: string[]): string[] {
return noNulls(noDuplicates(params));
}
Expand Down

0 comments on commit f0d0b6a

Please sign in to comment.