diff --git a/CHANGELOG.md b/CHANGELOG.md index 8089bdc7..c47a707b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## Next +- Better TypeScript type support [#216](https://github.com/Shopify/restyle/pull/216) by [FranzMoreno](https://github.com/FranzMoreno) & [fortmarek](https://github.com/fortmarek) + ## 2.2.0 - 2023-01-24 - Upgrade React Native to 0.71 in [#207](https://github.com/Shopify/restyle/pull/207) by [mattfrances](https://github.com/mattfrances) diff --git a/src/createVariant.ts b/src/createVariant.ts index b497d5ce..f52ce16e 100644 --- a/src/createVariant.ts +++ b/src/createVariant.ts @@ -82,7 +82,10 @@ export type VariantProps< K extends keyof Theme, Property extends keyof any = 'variant', > = { - [key in Property]?: ResponsiveValue, Theme>; + [key in Property]?: ResponsiveValue< + keyof Omit, + Theme['breakpoints'] + >; }; export default createVariant; diff --git a/src/hooks/useResponsiveProp.ts b/src/hooks/useResponsiveProp.ts index 79d70730..6095b57a 100644 --- a/src/hooks/useResponsiveProp.ts +++ b/src/hooks/useResponsiveProp.ts @@ -9,7 +9,7 @@ import { import useTheme from './useTheme'; const useResponsiveProp = ( - propValue: ResponsiveValue, + propValue: ResponsiveValue, ) => { const theme = useTheme(); const dimensions = useWindowDimensions(); diff --git a/src/responsiveHelpers.ts b/src/responsiveHelpers.ts index 4bf7a14a..166150f2 100644 --- a/src/responsiveHelpers.ts +++ b/src/responsiveHelpers.ts @@ -32,7 +32,7 @@ export const getValueForScreenSize = ({ breakpoints, dimensions, }: { - responsiveValue: AtLeastOneResponsiveValue; + responsiveValue: AtLeastOneResponsiveValue; breakpoints: Theme['breakpoints']; dimensions: Dimensions; }): TVal | undefined => { @@ -62,9 +62,9 @@ export const getValueForScreenSize = ({ }; export const isResponsiveObjectValue = ( - val: ResponsiveValue, + val: ResponsiveValue, theme: Theme, -): val is AtLeastOneResponsiveValue => { +): val is AtLeastOneResponsiveValue => { if (!val) return false; if (typeof val !== 'object') return false; return getKeys(val).reduce((acc: boolean, key) => { @@ -77,7 +77,7 @@ export const getResponsiveValue = < Theme extends BaseTheme, K extends keyof Theme | undefined, >( - propValue: ResponsiveValue, + propValue: ResponsiveValue, { theme, transform, diff --git a/src/restyleFunctions.ts b/src/restyleFunctions.ts index b6b49ff9..b64b42ae 100644 --- a/src/restyleFunctions.ts +++ b/src/restyleFunctions.ts @@ -272,97 +272,103 @@ export const all = [ ]; export interface ColorProps { - color?: ResponsiveValue; + color?: ResponsiveValue; } export interface OpacityProps { - opacity?: ResponsiveValue; + opacity?: ResponsiveValue; } export interface VisibleProps { - visible?: ResponsiveValue; + visible?: ResponsiveValue; } export interface BackgroundColorProps { - backgroundColor?: ResponsiveValue; + backgroundColor?: ResponsiveValue< + keyof Theme['colors'], + Theme['breakpoints'] + >; } export interface BackgroundColorShorthandProps { - bg?: ResponsiveValue; + bg?: ResponsiveValue; } export type SpacingProps = { [Key in keyof typeof spacingProperties]?: ResponsiveValue< keyof Theme['spacing'], - Theme + Theme['breakpoints'] >; }; export type SpacingShorthandProps = { [Key in keyof typeof spacingPropertiesShorthand]?: ResponsiveValue< keyof Theme['spacing'], - Theme + Theme['breakpoints'] >; }; export type TypographyProps = { [Key in keyof typeof typographyProperties]?: ResponsiveValue< TextStyle[Key], - Theme + Theme['breakpoints'] >; }; export type LayoutProps = { [Key in keyof typeof layoutProperties]?: ResponsiveValue< FlexStyle[Key], - Theme + Theme['breakpoints'] >; }; export type PositionProps = { [Key in keyof typeof positionProperties]?: ResponsiveValue< FlexStyle[Key], - Theme + Theme['breakpoints'] >; } & { zIndex?: ResponsiveValue< Theme['zIndices'] extends object ? keyof Theme['zIndices'] : number, - Theme + Theme['breakpoints'] >; }; export type BorderProps = { [Key in keyof typeof borderProperties]?: ResponsiveValue< ViewStyle[Key], - Theme + Theme['breakpoints'] >; } & { [Key in keyof typeof borderColorProperties]?: ResponsiveValue< keyof Theme['colors'], - Theme + Theme['breakpoints'] >; } & { [Key in keyof typeof borderRadiusProperties]?: ResponsiveValue< Theme['borderRadii'] extends object ? keyof Theme['borderRadii'] : number, - Theme + Theme['breakpoints'] >; }; export type ShadowProps = { [Key in keyof typeof shadowProperties]?: ResponsiveValue< ViewStyle[Key], - Theme + Theme['breakpoints'] >; } & { - shadowColor?: ResponsiveValue; + shadowColor?: ResponsiveValue; }; export type TextShadowProps = { [Key in keyof typeof textShadowProperties]?: ResponsiveValue< TextStyle[Key], - Theme + Theme['breakpoints'] >; } & { - textShadowColor?: ResponsiveValue; + textShadowColor?: ResponsiveValue< + keyof Theme['colors'], + Theme['breakpoints'] + >; }; export type AllProps = BackgroundColorProps & diff --git a/src/types.ts b/src/types.ts index 1085eefc..cc955ff6 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2,17 +2,16 @@ import {ImageStyle, TextStyle, ViewStyle, StyleProp} from 'react-native'; export type AtLeastOneResponsiveValue< Value, - Theme extends BaseTheme, - B = Theme['breakpoints'], + B extends BaseTheme['breakpoints'], R = {[Key in keyof B]: {[key in Key]: Value}}, > = Partial<{ [K in keyof B]: Value; }> & R[keyof R]; -export type ResponsiveValue = +export type ResponsiveValue = | Value - | AtLeastOneResponsiveValue; + | AtLeastOneResponsiveValue; export type SafeVariants = Omit;