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

Color Schemes: Add Color Scheme Picker #17200

Merged

Conversation

frontdevde
Copy link
Contributor

@frontdevde frontdevde commented Aug 15, 2017

This PR is part of a series of PRs aiming to provide support for Color Schemes in Calypso.
This PR focuses on adding the color scheme picker based on the components added in PR #17157.

color-scheme-picker

Notable additions in this PR:

  • The <ColorSchemePicker> component allows for the selection of a color scheme.
  • When using the component as is, any selection will immediately be saved to the colorSchemes property in the calypso_settings. When the props temporarySelection and onSelection are provided, any selection will only be set locally and the provided onSelection handler called (e.g. to save the selection via a save button in a form).
  • The component is added to the Blocks overview page for future reference.

How to test

Visit https://calypso.live/devdocs/blocks/color-scheme-picker?branch=add/color-schemes/color-scheme-picker or test locally.
Navigate to the Blocks overview page and proceed to the ColorSchemePicker section.

Suggestions as to what to test

  • Does the component behave as expected?
  • Can the component easily be reused in the future?
  • Is the current responsive behavior sufficient?

Note

This PR currently compares its changes to PR #17157. This is so the changes can be easily identified. This PR will be pointed at master once PR #17157 has been merged. It also needs to be merged prior to PR #17259 which is based on this PR.

For a more detailed description of the feature, the chosen approach and its advantages feel free to check out my post on the subject: p4TIVU-75d-p2 (internal reference).

@frontdevde frontdevde self-assigned this Aug 15, 2017
@frontdevde frontdevde requested a review from ehg August 15, 2017 01:53
@matticbot matticbot added OSS Citizen [Size] XL Probably needs to be broken down into multiple smaller issues labels Aug 15, 2017
@frontdevde
Copy link
Contributor Author

Note: I created the theme previews in Photoshop, that's why they are currently PNGs. I've already noted down converting them to SVGs as a future todo :)

@frontdevde frontdevde added the [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. label Aug 15, 2017
@spen spen self-requested a review August 15, 2017 04:55
@frontdevde
Copy link
Contributor Author

/cc'ing @jonathansadowski @bluefuton @retrofox as GitHub suggests you as potential reviewers 🙂👋

@frontdevde frontdevde added the [Status] Needs Design Review Add this when you'd like to get a review / feedback from the Design team on your PR label Aug 17, 2017
Copy link
Contributor

@spen spen left a comment

Choose a reason for hiding this comment

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

I think I may have a couple more points but I'll take a look with fresh 👀 tomorrow :)

The biggest blocker here would be the translation of the strings I think - so far the rest are just minor nitpicks.
Thanks for this work - looks awesome and can't wait to see it in the flesh!


render() {
return (

Copy link
Contributor

Choose a reason for hiding this comment

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

blank line here


export const ColorSchemes = [
{
label: translate( 'Default' ),
Copy link
Contributor

Choose a reason for hiding this comment

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

I could be wrong here but I think there's some chance that calling translate early can cause issues. I think theres a chance that languages may not be loaded yet and so the passed in value will output as is.
I don't quite know the details but recently discussed this with @mcsf. Miguel, can you chime in here please?

Copy link
Member

Choose a reason for hiding this comment

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

Absolutely! The way I've done this in the past is wrapping translate calls in a function that takes a translate, and call that during the render phase, where we have this.props.translate. I found the same approach the other day in AppBanner:

export function getAppBannerData( translate, sectionName ) {
switch ( sectionName ) {
case EDITOR:
return {
title: translate( 'Rich mobile publishing.' ),
copy: translate( 'A streamlined editor with faster, simpler image uploading? Check and mate.' ),
};
case NOTES:
return {
title: translate( 'Watch engagement happening.' ),
copy: translate( 'Is your new post a hit? With push notifications, see reactions as they roll in.' ),
};
case READER:
return {
title: translate( 'Read online or off.' ),
copy: translate( 'Catch up with new posts when you have time, even if you are offline.' ),
};
case STATS:
return {
title: translate( 'Stats at your fingertips.' ),
copy: translate( "Add real-time stats to your device's notifications or widgets." ),
};
default:
return {
title: '',
copy: '',
};
}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@spen @mcsf Good point, thanks for the input! 👍


{ this.state.selectedColorScheme &&
<Notice
text={ `Selected color scheme: ${ this.state.selectedColorScheme }` }
Copy link
Contributor

Choose a reason for hiding this comment

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

We should use the localize HoC and the translate prop it provides for this string.
I think it may end up looking a little like this:

...
text={ 
  translate( 'Selected color scheme: %s', {
    args: this.state.selectedColorScheme
  } )
}

I'm not sure if this will open up those values to translation, but if done right this could help us avoid using translate() in the constants file.

( More details on substituting strings in localize)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@spen Didn't add translate here as it's not part of the actual component but just an additional notice for the example in the docs to better visualize that a selection happened. Are we localizing strings like that in docs as well?

Copy link
Contributor

Choose a reason for hiding this comment

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

Good point, I think I'd just forgotten I was looking at an example for a moment! Since it is an example this looks perfect - thanks for correcting me ;)

return (
<Card>
<ColorSchemePicker
temporarySelection={ true }
Copy link
Contributor

Choose a reason for hiding this comment

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

={ true } can be omitted here since it will be inferred by the prop being present without a value

<ColorSchemePicker
  temporarySelection

<Notice
text={ `Selected color scheme: ${ this.state.selectedColorScheme }` }
showDismiss={ false }
/> }
Copy link
Contributor

Choose a reason for hiding this comment

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

Slight nit but can we bump this } down a line to stay inline with the opening {?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It was on its own line initially but got moved up by Calypso prettier. If that is still a requirement we'd either have to not run prettier on the file or the prettier config would need to support that. Given that it's a readability nice to have I assume it's OK to leave it this way?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ahh yes :) I've not used prettier much so there'll likely be a few cases where I'm saying something counter to prettiers formatting... in those cases feel free to ignore :)

background-image: url( '/calypso/images/color-schemes/theme-default.png' );

&.is-light-theme {

Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: I think it'd be more in keeping with the rest of the stylesheets to remove the padded lines here and throughout this file.

<div className="color-scheme-picker">
<QueryPreferences />
<FormRadiosBar
isThumbnail={ true }
Copy link
Contributor

Choose a reason for hiding this comment

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

={ true } can be omitted here too.

colorSchemePreference: getPreference( state, 'colorScheme' ),
};
},
( dispatch, ownProps ) =>
Copy link
Member

@mcsf mcsf Aug 18, 2017

Choose a reason for hiding this comment

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

Prefer ( dispatch, { temporarySelection } ) =>, so we can see at a glance which are necessary to fetch state compute action creators.

},
},
dispatch
)
Copy link
Member

@mcsf mcsf Aug 18, 2017

Choose a reason for hiding this comment

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

bindActionCreators is seldom used in Calypso — passing an object of action creators to connect is the way we usually go, for simplicity.

Copy link
Member

@mcsf mcsf Aug 18, 2017

Choose a reason for hiding this comment

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

^ scratch that one, I forgot it depended on temporarySelection

Copy link
Member

Choose a reason for hiding this comment

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

That said, it would be quite conceivable to achieve the same the following way:

connect(
  ( state ) => ( {
    colorSchemePreference: getPreference( state, 'colorScheme' ),
  } ),
  { saveColorSchemePreference }
)( ColorSchemePicker );

// with
const saveColorSchemePreference = ( preference, isTemporary ) =>
  isTemporary
  ? setPreference( 'colorScheme', preference )
  : savePreference( 'colorScheme', preference );

// and make sure `isTemporary` is passed within `handleColorSchemeSelection`

This is a situation where there are no strong project guidelines to choose one way over the other: there is a bit of personal taste, and a subjective perception of readability. I prefer the latter option, but this one is up to you. :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I'd agree that this approach would improve readability 👌

const addSelection = handleFunction => handleFunction( event.currentTarget.value );
temporarySelection && addSelection( onSelection );
addSelection( saveColorSchemePreference );
};
Copy link
Member

Choose a reason for hiding this comment

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

addSelection seems like an unnecessary abstraction. This would IMO read better and avoid an extra function instantiation if done more or less like:

const { value } = event.currentTarget;
if ( temporarySelection ) {
  onSelection( value );
}
saveColorSchemePreference( value );

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, let's go for the more readable approach 👍

saveColorSchemePreference: PropTypes.func,
};

handleColorSchemeSelection = event => {
Copy link
Member

Choose a reason for hiding this comment

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

Calypso style recommends wrapping all func args, so: ( event ) =>

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mcsf The parentheses were there initially but got removed by Calypso prettier. If that is still a requirement then I guess the prettier config would need to support that?

Copy link
Member

Choose a reason for hiding this comment

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

Ah, interesting. Maybe @samouri knows more?

Copy link
Contributor

Choose a reason for hiding this comment

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

I didn't realize that we recommend that! Is it in our style guidelines? I know that all of the examples use parens but I didn't think we prefer it one way or the other.

If we want to wrap all func args like that we can make the change to calypso-prettier

Copy link
Contributor

Choose a reason for hiding this comment

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

FWIW I think that having the parentheses makes it clearer, so I'd +1 making the change :)

@frontdevde
Copy link
Contributor Author

@spen @mcsf Thanks for your input! I've added some comments and also pushed some updates based on your suggestions :)

Copy link
Contributor

@spen spen left a comment

Choose a reason for hiding this comment

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

Awesome work @frontdevde :)
Thanks a heap for making the tweaks and clarifying on some of the other points!

Tests well and looks great in the devdocs 🎉

I have one more little request but it's not critical so accepting :)


## Usage

```es6
Copy link
Contributor

Choose a reason for hiding this comment

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

Tiny nit that I missed the first time around - could we change this to jsx please?
That'll give slightly better syntax highlighting in GH :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, already pushed ;)

Copy link
Contributor

@folletto folletto left a comment

Choose a reason for hiding this comment

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

Let's remove the <Notice> appearing when the option gets changed. The component should showcase only the component itself. If someone browses the documentation and sees the notice appear, would infer that the component includes the notice to, which is not the case.

It's important to show only the component in the component example, except if there are obvious limitations to do it.

@folletto
Copy link
Contributor

Here you can find the images as SVGs (not minified, as it preserves the ID):
https://cloudup.com/cFktARQ9wSb

A consideration could be done here: it could inline the same SVG, and then style the color of each of the sub-components via CSS (the same CSS rules generated in the color scheme maybe?). Not required for this PR as it's better to have a simpler solution in, just as a general thought for later.

@frontdevde
Copy link
Contributor Author

Thanks for your feedback, @folletto!

The idea behind the notice was to give some additional feedback as to which theme has been selected. But I'd agree that that could be misleading and thus just removed it from the docs as suggested.

Thanks, as well, for sending over the SVGs. Will add those in now 👍

@frontdevde
Copy link
Contributor Author

OK, the SVGs are up as well. 👍 /cc @folletto

I like the idea of in the future using one as a template and styling them based on the color scheme styles themselves. Will add that to the list of potential future PRs/iterations.

Copy link
Contributor

@folletto folletto left a comment

Choose a reason for hiding this comment

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

Design is good, behaviour is good 👍

The SVG isn't exactly the same size, so it's slightly blurry, but let's review that later — it's good for now.

@folletto folletto removed the [Status] Needs Design Review Add this when you'd like to get a review / feedback from the Design team on your PR label Aug 21, 2017
@folletto
Copy link
Contributor

The SVG isn't exactly the same size, so it's slightly blurry, but let's review that later — it's good for now.

Fixed in i2: https://cloudup.com/c5afpz94OG6

@frontdevde
Copy link
Contributor Author

Fixed in i2: https://cloudup.com/c5afpz94OG6

Thanks 👍 Just pushed a commit that updates the SVG assets.

@frontdevde frontdevde force-pushed the add/color-schemes/color-scheme-picker branch from 7d5578b to 25c9550 Compare August 22, 2017 18:54
@frontdevde
Copy link
Contributor Author

frontdevde commented Aug 22, 2017

I did an interactive rebase to squash the SVG commits into the initial commit in order to remove v1 of the SVGs as well as the PNGs from Git. /cc @spen

@spen
Copy link
Contributor

spen commented Aug 23, 2017

I had another look over since the rebase (Thanks again for that!) and everything looks great!

I forgot to mention - I added the [Status] Blocked / Hold label to avoid this being merged mistakenly (since it relies on #17157).

@spen spen merged commit 023b8cd into add/color-schemes/form-components Aug 30, 2017
@matticbot matticbot removed the [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. label Aug 30, 2017
@alisterscott alisterscott deleted the add/color-schemes/color-scheme-picker branch February 1, 2018 06:36
@designsimply designsimply added [Feature] User & Account Settings (/me) Settings and tools for managing your WordPress.com user account. DevDocs and removed [Feature] User & Account Settings (/me) Settings and tools for managing your WordPress.com user account. labels Feb 12, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
DevDocs OSS Citizen [Size] XL Probably needs to be broken down into multiple smaller issues
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants