Skip to content

Commit

Permalink
feat(theme): style consumer dispatch actions (#221)
Browse files Browse the repository at this point in the history
* refactor(ui): apply jest snapshot resolver
* refactor(theme): apply jest snapshot resolver
  • Loading branch information
artyorsh authored Jan 2, 2019
1 parent ca37382 commit cd60eb2
Show file tree
Hide file tree
Showing 36 changed files with 591 additions and 418 deletions.
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ module.exports = {
},
cacheDirectory: './dist/jest/cache',
coverageDirectory: './dist/jest/coverage',
snapshotResolver: '<rootDir>/jest.config.snapshot',
moduleNameMapper: pathsToModuleNameMapper(jestConfig.compilerOptions.paths, {
prefix: '<rootDir>/',
}),
Expand Down
8 changes: 8 additions & 0 deletions jest.config.snapshot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
resolveSnapshotPath: (path, extension) => {
return `${path}${extension}`;
},
resolveTestPath: (path, extension) => {
return path.slice(0, -extension.length);
},
};
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"babel-jest": "^23.6.0",
"coveralls": "^3.0.2",
"husky": "^1.1.2",
"jest": "^23.6.0",
"jest": "^24.0.0-alpha.9",
"metro-react-native-babel-preset": "^0.49.0",
"react": "^16.6.0",
"react-addons-test-utils": "^15.6.2",
Expand All @@ -49,7 +49,7 @@
"react-native-typescript-transformer": "^1.2.10",
"react-test-renderer": "^16.6.0",
"rimraf": "^2.6.2",
"ts-jest": "^23.10.4",
"ts-jest": "^23.10.5",
"tslint": "^5.11.0",
"typescript": "^3.1.6"
},
Expand Down
2 changes: 2 additions & 0 deletions src/framework/theme/component/style/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ export {
styled,
Props as StyledComponentProps,
} from './styleConsumer.component';

export * from './type';
56 changes: 31 additions & 25 deletions src/framework/theme/component/style/styleConsumer.component.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
import React from 'react';
import hoistNonReactStatics from 'hoist-non-react-statics';
import { ThemeMappingType } from '../mapping';
import {
ThemeType,
StyleType,
} from '../theme';
import {
ThemeMappingType,
ComponentMappingType,
} from '../mapping';
import ThemeContext from '../theme/themeContext';
import MappingContext from '../mapping/mappingContext';
import {
createStyle,
getComponentMapping,
StyleConsumerService,
} from '../../service';
} from '../../service/style';
import { getComponentMapping } from '../../service/mapping';
import { Interaction } from './type';

interface PrivateProps<T> {
forwardedRef: React.RefObject<T>;
Expand All @@ -29,50 +27,58 @@ export interface Props {
appearance?: string;
theme?: ThemeType;
themedStyle?: StyleType;
requestStateStyle?: (state: string[]) => StyleType;
dispatch?: (interaction: Interaction[]) => void;
}

interface State {
interaction: Interaction[];
}

export const styled = <T extends React.Component, P extends object>(Component: React.ComponentClass<P>) => {

type ComponentProps = Props & P;
type WrapperProps = PrivateProps<T> & ComponentProps;

class Wrapper extends React.Component<WrapperProps> {
class Wrapper extends React.Component<WrapperProps, State> {

service: StyleConsumerService = new StyleConsumerService();

getComponentName = (): string => Component.displayName || Component.name;

createComponentStyle = (theme: ThemeType,
mapping: ComponentMappingType,
appearance: string,
variant: string[],
state: string[]): StyleType => {
state: State = {
interaction: [],
};

if (state.length === 0) {
console.warn('Redundant `requestStateStyle` call! Use `this.props.themedStyle` instead!');
}
return createStyle(theme, mapping, appearance, variant, state);
private onDispatch = (interaction: Interaction[]) => {
this.setState({
interaction: interaction,
});
};

createCustomProps = (props: ConsumerProps, componentProps: P & Props): Props => {
private getComponentName = (): string => Component.displayName || Component.name;

private createCustomProps = (props: ConsumerProps, componentProps: P & Props): Props => {
const mapping = getComponentMapping(props.mapping, this.getComponentName());
const variants = this.service.getVariantPropKeys<P & Props>(mapping, componentProps);

const style = createStyle(
props.theme,
mapping,
componentProps.appearance,
this.service.getVariantPropKeys(mapping, componentProps),
this.service.getStatePropKeys(mapping, componentProps, this.state.interaction),
);

return {
appearance: componentProps.appearance,
theme: props.theme,
themedStyle: createStyle(props.theme, mapping, componentProps.appearance, variants),
requestStateStyle: state => {
return this.createComponentStyle(props.theme, mapping, componentProps.appearance, variants, state);
},
themedStyle: style,
dispatch: this.onDispatch,
};
};

renderWrappedComponent = (props: ConsumerProps) => {
// TS issue: with spreading Generics https://github.com/Microsoft/TypeScript/issues/15792
const { forwardedRef, ...restProps } = this.props as PrivateProps<T>;
const componentProps = restProps as P & Props;

return (
<Component
ref={forwardedRef}
Expand Down
21 changes: 21 additions & 0 deletions src/framework/theme/component/style/type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export enum Interaction {
ACTIVE = 'active',
}

export enum State {
CHECKED = 'checked',
DISABLED = 'disabled',
FOCUSED = 'focused',
}

export namespace Interaction {
export function parse(interaction: string): Interaction | undefined {
return Interaction[interaction.toUpperCase()];
}
}

export namespace State {
export function parse(state: string): State | undefined {
return State[state.toUpperCase()];
}
}
1 change: 1 addition & 0 deletions src/framework/theme/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export {
ThemedStyleType,
StyleSheetType,
StyleType,
Interaction,
} from './component';

export {
Expand Down
7 changes: 3 additions & 4 deletions src/framework/theme/service/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export * from './mappingUtil.service';
export * from './themeUtil.service';
export * from './styleUtil.service';
export * from './styleConsumer.service';
export * from './mapping';
export * from './theme';
export * from './style';
1 change: 1 addition & 0 deletions src/framework/theme/service/mapping/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './mapping.service';
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
VariantGroupType,
MappingType,
StateType,
} from '../component';
} from '../../component';

export const APPEARANCE_DEFAULT = 'default';

Expand Down
99 changes: 99 additions & 0 deletions src/framework/theme/service/mapping/mapping.spec.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
export const mapping = {
Test: {
appearance: {
default: {
mapping: {
size: 36,
innerSize: 24,
borderWidth: 2,
borderColor: 'grayPrimary',
selectColor: 'transparent',
state: {
active: {
borderColor: 'grayDark',
},
checked: {
borderColor: 'bluePrimary',
selectColor: 'bluePrimary',
},
disabled: {
borderColor: 'grayLight',
},
'active.checked': {
borderColor: 'blueDark',
},
'checked.disabled': {
selectColor: 'grayPrimary',
},
},
},
variant: {
status: {
info: {
mapping: {
state: {
checked: {
borderColor: 'orangePrimary',
selectColor: 'orangePrimary',
},
'active.checked': {
borderColor: 'orangeDark',
},
},
},
},
success: {
mapping: {
state: {
checked: {
borderColor: 'tealPrimary',
selectColor: 'tealPrimary',
},
'active.checked': {
borderColor: 'tealDark',
},
},
},
},
},
size: {
big: {
mapping: {
size: 42,
innerSize: 28,
},
},
small: {
mapping: {
size: 30,
innerSize: 20,
},
},
},
},
},
custom: {
mapping: {
borderWidth: 4,
state: {
active: {
borderColor: 'grayLight',
},
},
},
variant: {
status: {
success: {
mapping: {
borderColor: 'tealPrimary',
},
},
},
},
},
},
},
Empty: {
appearance: {},
},
};
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { mapping } from './config';
import * as Service from '../service/mappingUtil.service';
import * as Service from './mapping.service';
import * as config from './mapping.spec.config';

describe('@mapping: service methods checks', () => {

const { Test: testMapping } = mapping;
const { Test: testMapping } = config.mapping;

const json = (object: any) => JSON.stringify(object);

Expand Down
2 changes: 2 additions & 0 deletions src/framework/theme/service/style/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './style.service';
export * from './styleConsumer.service';
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import {
getStatelessVariantMapping,
getStateAppearanceMapping,
getStateVariantMapping,
} from './mappingUtil.service';
} from '../mapping/mapping.service';
import {
ComponentMappingType,
ThemeType,
StyleType,
} from '../component';
} from '../../component';

const SEPARATOR_STATE = '.';

Expand Down
Loading

0 comments on commit cd60eb2

Please sign in to comment.