Skip to content

Commit

Permalink
Implement shorthand syntax for spacing and backgroundColor (#22)
Browse files Browse the repository at this point in the history
* Implement shorthand syntax for spacing and backgroundColor

Its much nicer/cleaner to write out the spacing props in shorthand. This syntax is used in many similar projects that follow the system-ui spec.

* Separate shorthand props intro different functions

* Fix BoxProps type when shorthand is disabled and Fix type error in restyleFunctions

* Add BackgroundColorShorthandProps and SpacingShorthandProps to AllProps
  • Loading branch information
META-DREAMER authored Jul 23, 2020
1 parent 7b95ffa commit 9d8ecc6
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 15 deletions.
22 changes: 18 additions & 4 deletions src/createBox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import createRestyleComponent from './createRestyleComponent';
import {BaseTheme} from './types';
import {
backgroundColor,
backgroundColorShorthand,
opacity,
layout,
spacing,
Expand All @@ -20,36 +21,49 @@ import {
PositionProps,
visible,
VisibleProps,
SpacingShorthandProps,
BackgroundColorShorthandProps,
spacingShorthand,
} from './restyleFunctions';

export type BoxProps<Theme extends BaseTheme> = BackgroundColorProps<Theme> &
export type BoxProps<
Theme extends BaseTheme,
EnableShorthand extends boolean = true
> = BackgroundColorProps<Theme> &
OpacityProps<Theme> &
VisibleProps<Theme> &
LayoutProps<Theme> &
SpacingProps<Theme> &
BorderProps<Theme> &
ShadowProps<Theme> &
PositionProps<Theme>;
PositionProps<Theme> &
(EnableShorthand extends true
? SpacingShorthandProps<Theme> & BackgroundColorShorthandProps<Theme>
: Record<string, never>);

export const boxRestyleFunctions = [
backgroundColor,
backgroundColorShorthand,
opacity,
visible,
layout,
spacing,
spacingShorthand,
border,
shadow,
position,
];

const createBox = <
Theme extends BaseTheme,
Props = React.ComponentProps<typeof View> & {children?: React.ReactNode}
Props = React.ComponentProps<typeof View> & {children?: React.ReactNode},
EnableShorthand extends boolean = true
>(
BaseComponent: React.ComponentType<any> = View,
) => {
return createRestyleComponent<
BoxProps<Theme> & Omit<Props, keyof BoxProps<Theme>>,
BoxProps<Theme, EnableShorthand> &
Omit<Props, keyof BoxProps<Theme, EnableShorthand>>,
Theme
>(boxRestyleFunctions, BaseComponent);
};
Expand Down
4 changes: 2 additions & 2 deletions src/createRestyleFunction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import {
ResponsiveValue,
BaseTheme,
Dimensions,
RNStyle,
RestyleFunctionContainer,
RNStyleProperty,
} from './types';
import {getKeys} from './typeHelpers';

Expand Down Expand Up @@ -111,7 +111,7 @@ const createRestyleFunction = <
}: {
property: P;
transform?: StyleTransformFunction<Theme, K, TProps[P]>;
styleProperty?: keyof RNStyle;
styleProperty?: RNStyleProperty;
themeKey?: K;
}): RestyleFunctionContainer<TProps, Theme, P, K> => {
const styleProp = styleProperty || property.toString();
Expand Down
17 changes: 13 additions & 4 deletions src/createText.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,35 +16,44 @@ import {
TextShadowProps,
TypographyProps,
VisibleProps,
spacingShorthand,
SpacingShorthandProps,
} from './restyleFunctions';
import createVariant, {VariantProps} from './createVariant';

export type TextProps<Theme extends BaseTheme> = ColorProps<Theme> &
export type TextProps<
Theme extends BaseTheme,
EnableShorthand extends boolean = true
> = ColorProps<Theme> &
OpacityProps<Theme> &
VisibleProps<Theme> &
TypographyProps<Theme> &
SpacingProps<Theme> &
TextShadowProps<Theme> &
VariantProps<Theme, 'textVariants'>;
VariantProps<Theme, 'textVariants'> &
(EnableShorthand extends true ? SpacingShorthandProps<Theme> : never);

export const textRestyleFunctions = [
color,
opacity,
visible,
typography,
spacing,
spacingShorthand,
textShadow,
createVariant({themeKey: 'textVariants'}),
];

const createText = <
Theme extends BaseTheme,
Props = React.ComponentProps<typeof Text> & {children?: React.ReactNode}
Props = React.ComponentProps<typeof Text> & {children?: React.ReactNode},
EnableShorthand extends boolean = true
>(
BaseComponent: React.ComponentType<any> = Text,
) => {
return createRestyleComponent<
TextProps<Theme> & Omit<Props, keyof TextProps<Theme>>,
TextProps<Theme, EnableShorthand> &
Omit<Props, keyof TextProps<Theme, EnableShorthand>>,
Theme
>(textRestyleFunctions, BaseComponent);
};
Expand Down
63 changes: 58 additions & 5 deletions src/restyleFunctions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {TextStyle, FlexStyle, ViewStyle} from 'react-native';

import createRestyleFunction from './createRestyleFunction';
import {BaseTheme, ResponsiveValue} from './types';
import {BaseTheme, ResponsiveValue, RNStyleProperty} from './types';
import {getKeys} from './typeHelpers';

const spacingProperties = {
Expand All @@ -21,6 +21,23 @@ const spacingProperties = {
paddingVertical: true,
};

const spacingPropertiesShorthand = {
m: 'margin',
mt: 'marginTop',
mr: 'marginRight',
mb: 'marginBottom',
ml: 'marginLeft',
mx: 'marginHorizontal',
my: 'marginVertical',
p: 'padding',
pt: 'paddingTop',
pr: 'paddingRight',
pb: 'paddingBottom',
pl: 'paddingLeft',
px: 'paddingHorizontal',
py: 'paddingVertical',
};

const typographyProperties = {
fontFamily: true,
fontSize: true,
Expand Down Expand Up @@ -105,6 +122,12 @@ export const backgroundColor = createRestyleFunction({
themeKey: 'colors',
});

export const backgroundColorShorthand = createRestyleFunction({
property: 'bg',
styleProperty: 'backgroundColor',
themeKey: 'colors',
});

export const color = createRestyleFunction({
property: 'color',
themeKey: 'colors',
Expand All @@ -127,6 +150,20 @@ export const spacing = getKeys(spacingProperties).map(property => {
});
});

export const spacingShorthand = getKeys(spacingPropertiesShorthand).map(
property => {
const styleProperty = spacingPropertiesShorthand[
property
] as RNStyleProperty;

return createRestyleFunction({
property,
styleProperty,
themeKey: 'spacing',
});
},
);

export const typography = getKeys(typographyProperties).map(property => {
return createRestyleFunction({
property,
Expand Down Expand Up @@ -196,10 +233,12 @@ export const textShadow = [
];

export const all = [
backgroundColor,
color,
opacity,
backgroundColor,
backgroundColorShorthand,
...spacing,
...spacingShorthand,
...typography,
...layout,
...position,
Expand All @@ -208,9 +247,6 @@ export const all = [
...textShadow,
];

export interface BackgroundColorProps<Theme extends BaseTheme> {
backgroundColor?: ResponsiveValue<keyof Theme['colors'], Theme>;
}
export interface ColorProps<Theme extends BaseTheme> {
color?: ResponsiveValue<keyof Theme['colors'], Theme>;
}
Expand All @@ -222,13 +258,28 @@ export interface VisibleProps<Theme extends BaseTheme> {
visible?: ResponsiveValue<boolean, Theme>;
}

export interface BackgroundColorProps<Theme extends BaseTheme> {
backgroundColor?: ResponsiveValue<keyof Theme['colors'], Theme>;
}

export interface BackgroundColorShorthandProps<Theme extends BaseTheme> {
bg?: ResponsiveValue<keyof Theme['colors'], Theme>;
}

export type SpacingProps<Theme extends BaseTheme> = {
[Key in keyof typeof spacingProperties]?: ResponsiveValue<
keyof Theme['spacing'],
Theme
>;
};

export type SpacingShorthandProps<Theme extends BaseTheme> = {
[Key in keyof typeof spacingPropertiesShorthand]?: ResponsiveValue<
keyof Theme['spacing'],
Theme
>;
};

export type TypographyProps<Theme extends BaseTheme> = {
[Key in keyof typeof typographyProperties]?: ResponsiveValue<
TextStyle[Key],
Expand Down Expand Up @@ -293,9 +344,11 @@ export type TextShadowProps<Theme extends BaseTheme> = {
};

export type AllProps<Theme extends BaseTheme> = BackgroundColorProps<Theme> &
BackgroundColorShorthandProps<Theme> &
ColorProps<Theme> &
OpacityProps<Theme> &
SpacingProps<Theme> &
SpacingShorthandProps<Theme> &
TypographyProps<Theme> &
LayoutProps<Theme> &
PositionProps<Theme> &
Expand Down
4 changes: 4 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,7 @@ export type RestyleFunction<
};

export type RNStyle = ViewStyle | TextStyle | ImageStyle;
export type RNStyleProperty =
| keyof ViewStyle
| keyof TextStyle
| keyof ImageStyle;

0 comments on commit 9d8ecc6

Please sign in to comment.