Skip to content

Commit

Permalink
refactor(theme): simplify theme mapping config (#209)
Browse files Browse the repository at this point in the history
* refactor(theme): simplify theme mapping config

* test(theme): add tests for undefined mappings
  • Loading branch information
artyorsh authored and malashkevich committed Dec 12, 2018
1 parent e6d030c commit 37274c4
Show file tree
Hide file tree
Showing 12 changed files with 143 additions and 243 deletions.
22 changes: 5 additions & 17 deletions src/framework/theme/component/mapping/type.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,10 @@
export interface ThemeMappingType {
name: string;
parameters: ParameterType[];
variants: VariantType[];
}

export interface ParameterType {
name: string;
}
// TODO(mapping/type): declare Config/Token type

export interface VariantType {
name: string;
mapping: MappingType[];
}
export type ThemeMappingConfigType = any;

export interface MappingType {
parameter: string;
token: string;
export interface ThemeMappingType {
parameters: string[];
variants: any;
}

// TODO(mapping/type): declare Token type
export type TokenType = any;
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ import {
} from '../theme';
import {
ThemeMappingProvider,
ThemeMappingType,
ThemeMappingConfigType,
} from '../mapping';

export interface Props {
mapping: ThemeMappingType[];
mapping: ThemeMappingConfigType;
theme: ThemeType;
children: JSX.Element | React.ReactNode;
}

interface State {
mapping: ThemeMappingType[];
mapping: ThemeMappingConfigType;
theme: ThemeType;
}

Expand Down
4 changes: 1 addition & 3 deletions src/framework/theme/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@ export {
ThemedComponentProps,

ThemeType,
ThemeMappingConfigType,
ThemeMappingType,
ParameterType,
VariantType,
MappingType,
TokenType,
ThemedStyleType,
StyleSheetType,
Expand Down
70 changes: 44 additions & 26 deletions src/framework/theme/service/mappingUtil.service.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,26 @@
import {
ThemeMappingType,
VariantType,
MappingType,
TokenType,
} from '../component';
import { ThemeMappingType, TokenType } from '../component';

export const VARIANT_DEFAULT = 'default';

/**
* @param component: string - component name. Using displayName is recommended
* @param mapping: ThemeMappingType[] - theme mapping configuration array
*
* @return ThemeMappingType if presents in theme mapping, undefined otherwise
* @return ThemeMappingType if presents in mapping, undefined otherwise
*/
export function getComponentThemeMapping(component: string, mapping: ThemeMappingType[]): ThemeMappingType | undefined {
return mapping.find(value => value.name === component);
export function getComponentThemeMapping(component: string, mapping: any): ThemeMappingType | undefined {
return mapping[component];
}

/**
* @param token: string - theme mapping token name
* @param tokens: TokenType[] - theme mapping tokens array
* @param tokens: TokenType - theme tokens
*
* @return TokenType if presents in tokens, undefined otherwise
*/
export function getThemeMappingToken(token: string, tokens: TokenType): TokenType | undefined {
const value = {};
if (tokens[token] !== undefined) {
const value = {};
value[token] = tokens[token];
return value;
} else {
Expand All @@ -34,44 +29,67 @@ export function getThemeMappingToken(token: string, tokens: TokenType): TokenTyp
}

/**
* @param name: string - variant name. Default is 'default'
* @param variant: string - variant name. Default is 'default'
* @param mapping: ThemeMappingType - component mapping configuration
*
* @return VariantType if presents in mapping, undefined otherwise
* @return variant if presents in mapping, undefined otherwise
*/
export function getComponentVariant(name: string, mapping: ThemeMappingType): VariantType | undefined {
return mapping.variants.find(value => value.name === name);
export function getComponentVariant(variant: string, mapping: ThemeMappingType): any | undefined {
return mapping.variants[variant];
}

/**
* @param mapping: ThemeMappingType - component mapping configuration
* @param parameter: string - parameter name.
* @param variant: string - variant name. Default is 'default'
* @param mapping: ThemeMappingType - component mapping configuration
*
* @return MappingType[] if presents in variant, undefined otherwise
* @return parameterMapping if presents in variant, undefined otherwise
*/
export function getComponentMappings(mapping: ThemeMappingType,
variant: string = VARIANT_DEFAULT): MappingType[] | undefined {
export function getParameterMapping(parameter: string,
variant: string,
mapping: ThemeMappingType): any | undefined {

const componentVariant = getComponentVariant(variant, mapping);
return componentVariant && componentVariant.mapping;
return componentVariant && componentVariant[parameter];
}

/**
* @param parameter: string - parameter name.
* @param variant: string - variant name.
* @param mapping: ThemeMappingType - component mapping configuration
* @param tokens: TokenType - theme tokens
*
* @return theme token if presents in variant, undefined otherwise
*/
export function getParameterValue(parameter: string,
variant: string,
mapping: ThemeMappingType,
tokens: TokenType): any | undefined {

const parameterMapping = getParameterMapping(parameter, variant, mapping);
return parameterMapping && getThemeMappingToken(parameterMapping, tokens);
}

/**
* @param tokens: TokenType[] - theme mapping tokens array
* @param tokens: TokenType - theme mapping tokens array
* @param mapping: ThemeMappingType - component mapping configuration
* @param variant: string - variant name. Default is 'default'
*
* @return TokenType[] specific for component's variant if presents in variant, undefined otherwise
* @return TokenType specific for component's variant if presents in variant, undefined otherwise
*/
export function getVariantTokens(tokens: TokenType,
mapping: ThemeMappingType,
variant: string = VARIANT_DEFAULT): TokenType | undefined {

const assignParameter = (origin: TokenType, prop: MappingType) => {
const componentVariant = getComponentVariant(variant, mapping);
if (componentVariant === undefined) {
return undefined;
}
const assignParameter = (origin: TokenType, parameter: string) => {
return {
...origin,
...getThemeMappingToken(prop.token, tokens),
...getParameterValue(parameter, variant, mapping, tokens),
};
};
const componentMappings = getComponentMappings(mapping, variant);
return componentMappings.reduce(assignParameter, {});
return Object.keys(componentVariant).reduce(assignParameter, {});
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import {
getComponentMappings,
getComponentVariant,
VARIANT_DEFAULT,
} from './mappingUtil.service';
import {
ThemeMappingType,
MappingType,
ThemeType,
StyleType,
} from '../component';
Expand Down Expand Up @@ -48,14 +47,10 @@ export function getThemeValue(name: string, theme: ThemeType): any | undefined {
}

function createStyleFromVariant(theme: ThemeType, mapping: ThemeMappingType, variant: string): StyleType {
const variantMapping = getComponentMappings(mapping, variant);
return createStyleFromMapping(variantMapping, theme);
}

function createStyleFromMapping(mapping: MappingType[], theme: ThemeType): StyleType {
const assignParameter = (style: any, prop: MappingType) => {
style[prop.parameter] = getThemeValue(prop.token, theme);
const componentVariant = getComponentVariant(variant, mapping);
const assignParameter = (style: any, parameter: any) => {
style[parameter] = getThemeValue(componentVariant[parameter], theme);
return style;
};
return mapping.reduce(assignParameter, {});
return Object.keys(componentVariant).reduce(assignParameter, {});
}
118 changes: 24 additions & 94 deletions src/framework/theme/tests/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,110 +8,40 @@ export const values = {
textSuccess: '#00E676',
};

export const mappings = {
Test: {
parameters: [
'backgroundColor',
'textColor',
],
variants: {
default: {
backgroundColor: 'backgroundColorTestDefault',
textColor: 'textColorTestDefault',
},
dark: {
backgroundColor: 'backgroundColorTestDark',
textColor: 'textColorTestDark',
},
success: {
textColor: 'textColorTestSuccess',
},
},
},
};

export const theme: ThemeType = {
backgroundColorTestDefault: values.backgroundDefault,
backgroundColorTestDark: values.backgroundDark,
textColorTestDefault: values.textDefault,
textColorTestDark: values.textDark,
textColorTestSuccess: values.textSuccess,
};

export const themeInverse: ThemeType = {
backgroundColorTestDefault: values.backgroundDark,
backgroundColorTestDark: values.backgroundDefault,
textColorTestDefault: values.textDark,
textColorTestDark: values.textDefault,
textColorTestSuccess: values.textDefault,
};

export const mappings = {
testDefault: [
{
parameter: 'backgroundColor',
token: 'backgroundColorTestDefault',
},
{
parameter: 'textColor',
token: 'textColorTestDefault',
},
],
testDark: [
{
parameter: 'backgroundColor',
token: 'backgroundColorTestDark',
},
],
testSuccess: [
{
parameter: 'textColor',
token: 'textColorTestSuccess',
},
],
testInverseDefault: [
{
parameter: 'backgroundColor',
token: 'backgroundColorTestDefault',
},
{
parameter: 'textColor',
token: 'textColorTestDefault',
},
],
mockBackground: [
{
parameter: 'backgroundColor',
token: 'backgroundColorTestDefault',
},
],
};

export const variants = {
testDefault: {
name: 'default',
mapping: mappings.testDefault,
},
testDark: {
name: 'dark',
mapping: mappings.testDark,
},
testSuccess: {
name: 'success',
mapping: mappings.testSuccess,
},
testInverseDefault: {
name: 'default',
mapping: mappings.testInverseDefault,
},
mockDefault: {
name: 'default',
mapping: mappings.mockBackground,
},
};

export const themeMappings = {
test: {
name: 'Test',
parameters: [
{
name: 'backgroundColor',
},
],
variants: [variants.testDefault, variants.testDark, variants.testSuccess],
},
testInverse: {
name: 'Test',
parameters: [
{
name: 'backgroundColor',
},
],
variants: [variants.testInverseDefault],
},
mock: {
name: 'Mock',
parameters: [
{
name: 'backgroundColor',
},
],
variants: [variants.mockDefault],
},
};
Loading

0 comments on commit 37274c4

Please sign in to comment.