Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recreate styles when theme changes #128

Merged
merged 1 commit into from
Jan 22, 2018

Conversation

noratarano
Copy link
Collaborator

@noratarano noratarano commented Jan 18, 2018

Add the ability to recalculate styles if the theme has changed. This
allows for the style function of a component already having one to
recreate its style function from the updated theme, and will ensure
that every component is styled with the same theme.

to @majapw @ljharb @goatslacker

Copy link
Collaborator

@majapw majapw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI @gabergg @lencioni

This seems pretty reasonable to me! :)

@@ -42,10 +42,12 @@ export function withStyles(
themePropName = 'theme',
flushBefore = false,
pureComponent = false,
createStylesOnce = false,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so in theory, if we wanted to lock down a component and prevent retheming entirely, we could pass in true for this prop? If so, that'd be good to document in the README

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call!

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I probably have a slight preference for leaving this option out on this pass. I don't imagine many people will be intentionally registering new themes and counting on the fact that components that have already been rendered won't update.

@@ -57,11 +59,16 @@ export function withStyles(
}

maybeCreateStyles() {
const registeredTheme = ThemedStyleSheet.get();
const recreateStyles = !createStylesOnce && (currentTheme !== registeredTheme);
currentTheme = registeredTheme;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this is something we want to hold in the withStyles HOC or whether we'd want it as a flag in the ThemedStyleSheet.

This is probably more performant here @martinwin although maybe a bool in the ThemedStyleSheet would be cleaner. idk.

Copy link
Collaborator Author

@noratarano noratarano Jan 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. I had that thought too. I figured that ThemedStyleSheet shouldn't define the concept of changed this way necessarily (is it when a theme is registered, when the theme changes with !==, or when an invalidation function is called explicitly?), so I left it out of there. Or maybe it should? I can see it either way.
Thoughts? @majapw

Edit: Ignore bad code. The alternative would look like with the naming TBD: ```jsx // ThemedStyleSheet let themeChanged;

function registerTheme(theme) {
themeChanged = theme !== styleTheme;
styleTheme = theme;
}

function hasThemeChanged() {
return themeChanged;
}

```jsx
// withStyles
maybeCreateStyles() {
  const recreateStyles = !lockTheme && ThemedStyleSheet.hasThemeChanged();
  // ...
  if (isRTL && (!styleDefRTL || recreateStyles)) {
  // ...
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this may be cleaner ^

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm we'd have to have a way to prevent future recreates after this as well, e.g. once we've built the styleSheet with createRTL/createLTR we could update the themeChanged variable again (trickily, we'd have to ... have a flag for each direction, no?)

Copy link
Collaborator Author

@noratarano noratarano Jan 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait no, because if the theme is registered only once, then styles would be recreated every time.

@noratarano noratarano force-pushed the recreate-styles-when-theme-changes branch 3 times, most recently from e177254 to 5aa2955 Compare January 18, 2018 22:38
@noratarano
Copy link
Collaborator Author

@majapw, @gabergg PTAL, how's this?

@noratarano noratarano force-pushed the recreate-styles-when-theme-changes branch 2 times, most recently from d395bbb to 83ae3a7 Compare January 19, 2018 02:17
@@ -17,10 +25,12 @@ function create(makeFromTheme, createWithDirection) {
}

function createLTR(makeFromTheme) {
themeChangedLTR = false;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per our offline conversation, this global toggle will create an issue if multiple components have been rendered before the new theme is registered. The first component will recreate its styles, flipping the global toggle, and the rest of the components will fail to recreate their styles. So, it likely makes sense to bring this logic back into withStyles, so it's handled with a component-level flag.

@noratarano noratarano force-pushed the recreate-styles-when-theme-changes branch 2 times, most recently from b5e53c8 to cd63fcd Compare January 19, 2018 22:19
Copy link
Collaborator Author

@noratarano noratarano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK! Thanks @gabergg and @majapw for your insightful review. I put the theme tracking back in the HOC. This way, theme changes will be managed by each component and we prevent inter-component side effects. I also updated the tests to catch all of the cases we discussed. What do you think about this now?

Copy link
Collaborator

@majapw majapw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems legit! I'm wondering if we can somehow separate out the if/else of the LTR vs RTL world into one function that takes an argument.

@noratarano noratarano force-pushed the recreate-styles-when-theme-changes branch 2 times, most recently from 79e861b to dcdfe4a Compare January 22, 2018 19:19
Add the ability to recalculate styles if the theme has changed. This
allows for a component already having a style function to recreate it
from the updated theme, and will ensure that every component rendered
after a theme is registered is rendered with that theme.
@noratarano noratarano force-pushed the recreate-styles-when-theme-changes branch from dcdfe4a to 262d22b Compare January 22, 2018 19:30
@noratarano noratarano merged commit 7c2f5ce into master Jan 22, 2018
@noratarano noratarano deleted the recreate-styles-when-theme-changes branch January 22, 2018 19:47
@gabergg
Copy link

gabergg commented Jan 22, 2018

LGTM!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants