Skip to content

bento: add jss styling for amp-carousel.#29713

Merged
samouri merged 20 commits intoampproject:masterfrom
samouri:jss
Aug 17, 2020
Merged

bento: add jss styling for amp-carousel.#29713
samouri merged 20 commits intoampproject:masterfrom
samouri:jss

Conversation

@samouri
Copy link
Copy Markdown
Member

@samouri samouri commented Aug 6, 2020

summary
Implements the preact/storybook half of the Bento: stylesheets via JSS proposal

  • Adds required dependencies (jss, react-jss)
  • Adds alias to storybook build from react/react-dom to the preact equivalent, which enables react-jss to use the preact hooks.
  • converts the .css.js and inline styles into equivalent jss.
  • Migrate the js based :hover/:active to css.

Note: I think it would be nice to either import or create our own version of the classnames lib to clean up our classname concatenation.

@samouri samouri self-assigned this Aug 6, 2020
@google-cla google-cla bot added the cla: yes label Aug 6, 2020
@samouri samouri changed the title bento: add jss styling bento: add jss styling for amp-carousel. Aug 6, 2020
@samouri samouri requested review from caroqliu and dvoytenko August 6, 2020 21:12
advance(by);
};
const styles = useStyles();
let classNames =
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit, but this might be better:

const classNames = `${styles.arrowPlacement} ${by < 0 ? styles.arrowLeft : styles.arrowRight} ${isDisabled ? styles.arrowDisabled : ''}`;

Just looking for good patterns here since we'll be doing this quite a bit.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Done.

I'm in favor of a classnames like helper lib going forward. Would transform this to the much clearer:

const  classNames = cx(
    styles.arrowPlacement,
    by < 0 ? styles.arrowLeft : styles.arrowRight,
    {[styles.arrowDisabled]: isDisabled}
)


// TODO discuss this sidestepping of local/no-export-side-effect.
// eslint-disable-next-line local/no-export-side-effect
export const useStyles = createUseStyles(styles);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I liked your idea of putting this into the base-carousel.jss.js because:

  1. It removes the danger of misusing the style objects.
  2. It makes it really obvious where to find useStyles styles.
  3. Limits the react-jss import to only one type of module.
  4. Simplifies rewriting conceptually - only one type of module is rewritten. It could also make rewriting slightly more difficult technically, but I think it's a good tradeoff.
  5. Also, down the line I'd like a lint that only allows react-jss and jss to be imported in a .jss.js modules.

@samouri samouri marked this pull request as ready for review August 7, 2020 18:33
@amp-owners-bot
Copy link
Copy Markdown

amp-owners-bot bot commented Aug 7, 2020

Hey @wassgha! These files were changed:

build-system/tasks/storybook/preact-env/webpack.config.js

Copy link
Copy Markdown
Contributor

@dvoytenko dvoytenko left a comment

Choose a reason for hiding this comment

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

This is very close to mergeable. Just one more recommendation that I think would get it even closer and less disruptive.

container./* OK */ scrollLeft += container./* OK */ offsetWidth * by;
},
}));
// TODO: uncomment when build step is ready..
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Here's an idea. Let's actually create the useStyles() fake in the .jss.js file. It'd simply look like this:

export function useStyles() {
  return classes;
}

Then we can do a couple of things:

  1. All component modules would look exactly like we want them to look. When build step is ready, none of them would need to change.
  2. We can shield classes export and thus reduce public surface of the jss file.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I wish I had thought of this. on it!


// export const useStyles = createUseStyles(JSS);
// TODO: remove in favor of line above when build step is ready.
if (!globalThis.AMP) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Per suggestion about exporting fake useStyles. We can use that same fake to exist this code. And as soon as the build step is complete, it all becomes unneeded.

*
* @return {{classes: Object<string, string>}}
*/
export function useStyles() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Much happier with this approach.

@samouri samouri requested a review from caroqliu August 14, 2020 15:47
const classes = useStyles();
const classNames = `${classes.arrowPlacement} ${
by < 0 ? classes.arrowPrev : classes.arrowNext
} ${isDisabled ? classes.arrowDisabled : ''}`;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Question: Do we prefer using classes.arrowDisabled for more precise specificity, or would we prefer defining a CSS rule for ${classes.arrowPlacement}[disabled]? With the second approach we would also append disabled={isDisabled} as the prop.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

good question. not sure

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Here's my quick 2 cents on this. The most purist CSS way is .x:disabled {} - but that's not always applicable. The other options are .x[disabled] {} and .x.x-disabled {}. The important considerations here are:

  1. The most important thing for us here is specificity. And all .x:disabled, .x[disabled] and .x.x-disabled all have exactly the same specificity (https://specificity.keegan.st/). So no clear winners there. However, the special case we can make .x-disabled {} that would include combined styles. This will have a lower specificity. But, I think this is a rare case where a lower specificity is actually harmful. I think the combined selector is a good thing.
  2. .x[disabled] IMHO "feels" more semantic and self-documenting. But this is potentially less visible inside a component.
  3. .x.x-disabled is faster, though in this case shouldn't be too big of a difference.
  4. .x.x-disabled is slightly repetitive. We still need to add the disabled and aria-disabled attributes.

I think the bigger answer is that there's no a clear winner here. We can keep moving with a class and reassess/change later since these are fully compatible options due to the same specificity.

@samouri samouri requested a review from dvoytenko August 14, 2020 23:40
@samouri samouri merged commit 904177f into ampproject:master Aug 17, 2020
@samouri samouri deleted the jss branch August 17, 2020 17:13
ed-bird pushed a commit to ed-bird/amphtml that referenced this pull request Dec 10, 2020
* bento: add jss styling

* naive approach, litter with TODOs

* move jss to deps vs. devDep

* updates after discussion with Dima

* hover/active styles

* forgot a file, some fixes

* it builds, but useStyles throws

* className --> class

* works

* switch back to useStyles throughout now that hooks are unbroken with the alias

* use eslint disable

* nit

* make mergable

* final dima suggestions

* fix css

* forgot an override

* no idea how className crept back in

* fix

* fix type

* FIX Types
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.

5 participants