Shopify / restyle

A type-enforced system for building UI components in React Native with TypeScript.

Home Page:https://shopify.github.io/restyle/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Custom themed components are losing spacing props after upgrade from 2.3.0 to 2.4.0

i-in-range opened this issue · comments

Current behavior

Custom themed components are losing padding and margin properties after I updated package from 2.3.0 to 2.4.0. I have got next console.log of props that my themed components (parent and nested) receives:

{
  "style": [
    {
      "flex": 1,
      "backgroundColor": "#000088",
      "padding": 0,
      "margin": 0
    }
  ]
}

{
  "style": [
    {
      "flex": 1,
      "backgroundColor": "#008800",
      "padding": 0,
      "margin": 0
    }
  ]
}

But the nested component (the second one) actually has settings of margin: 8 and padding: 8

Expected behavior

{
  "style": [
    {
      "flex": 1,
      "backgroundColor": "#000088",
      "padding": 0,
      "margin": 0
    }
  ]
}
{
  "style": [
    {
      "flex": 1,
      "backgroundColor": "#008800",
      "padding": 8,
      "margin": 8
    }
  ]
}

To Reproduce

Basic theme object:

import { createTheme } from "@shopify/restyle";

const theme = createTheme({
    colors: {
        parentBg: "#000088",
        nestedBg: "#008800",
    },
    spacing: {
        none: 0,
        m: 8,
    },
    breakpoints: {
        phone: 320,
        tablet: 768,
    },
    borderRadii: {},
    zIndices: {},

    container: {
        defaults: {},
        parent: {
            flex: 1,
            backgroundColor: "parentBg",
            padding: {
                phone: "none",
                tablet: "none",
            },
            margin: {
                phone: "none",
                tablet: "none",
            },
        },
        nested: {
            flex: 1,
            backgroundColor: "nestedBg",
            padding: {
                phone: "m",
                tablet: "m",
            },
            margin: {
                phone: "m",
                tablet: "m",
            },
        },
    },
});

export type Theme = typeof theme;
export default theme;

Simple themed component:

import {
    backgroundColor,
    BackgroundColorProps,
    border,
    BorderProps,
    composeRestyleFunctions,
    createVariant,
    spacing,
    SpacingProps,
    useRestyle,
    VariantProps,
} from "@shopify/restyle";
import * as React from "react";
import { View, ViewProps } from "react-native";
import { Theme } from "./theme";

type RestyleProps = SpacingProps<Theme> &
    BorderProps<Theme> &
    BackgroundColorProps<Theme> &
    VariantProps<Theme, "container">;

const restyleFunctions = composeRestyleFunctions<Theme, RestyleProps>([
    spacing,
    border,
    backgroundColor,
    createVariant({ themeKey: "container" }),
]);

type Props = RestyleProps & ViewProps;

export const Container = ({ children, ...rest }: Props) => {
    const props = useRestyle(restyleFunctions, rest);
    console.log(JSON.stringify(props, null, 2));
    return <View {...props}>{children}</View>;
};

And finally app.tsx:

import { ThemeProvider } from "@shopify/restyle";
import React from "react";
import { Container} from "../Container";
import theme from "../theme";

export default function App() {
  return (
    <ThemeProvider theme={theme}>
        <Container variant="parent">
            <Container variant="nested" />
        </Container >
    </ThemeProvider>
   );
}

Platform:

  • iOS
  • Android

Environment

The issue comes when I concurrently updated Expo to 48.0.0 and @shopify/restyle to 2.4.0

Before upgrade I use Expo 47.0.0 and @shopify/restyle 2.3.0

Now I downgraded @shopify/restyle to 2.3.0 and it works well with Expo 48.0.0

Hey @i-in-range 👋

Can you double check if this still happens with 2.4.1?

The bug is most likely related to the memoizations we've added in this PR.

The problem still exists, but it's not the only one for now. I noticed that when trying version 2.4.1, my child themed Views are being overridden by the parent's properties. Specifically, when the marginBottom property of all list items should be 2, they all end up with a value of 48, which is the exact marginBottom of the parent container located above the bottom tab bar with height 48. I've tried to adjust it, and it seems to me that Views inherit their parent's properties, but Pressables only receive zeros. Both of them has the same shape of their RestyleProps:

type RestyleProps = SpacingProps<Theme> &
    BorderProps<Theme> &
    LayoutProps<Theme> &
    BackgroundColorProps<Theme> &
    VariantProps<Theme, "pressable">;  // or "view"

Reproduced the issue on custom-themed-nested-components-props-overwrite branch by adding unit tests. Couldn't yet found the reason, so if anyone wants to take over, feel free to use the branch: run useRestyle tests to get the failing test.

Hey @i-in-range! We managed to find a potential fix for the issue you discovered. Please see this PR for more details. As Marek mentioned above, it was related to the memoizations added in a previous PR.