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

React: Add Standard Accordion Components to Mayflower React #85

Merged
merged 42 commits into from
Aug 22, 2018

Conversation

avrilpearl
Copy link
Contributor

@avrilpearl avrilpearl commented Jul 23, 2018

Description: This PR includes the addition of 4 new components that together create a standard accordion feature in Mayflower React. The design is pulled from Mayflower PL but were refactored in order to generate these new components. Also, in order to enable animations, this PR installs the react-transition-group library.

Question to Validate with React Team --> Is the approach to handling children in both accordion item and accordion wrapper appropriate here? Is the approach to animations here appropriate? Do we want to pull animation and focus scss in accordion item out to a higher level in the react library so it applies to all relevant components?

External Review Steps:

  1. npm install
  2. Go to @atoms/icons/SvgCircleChevron and confirm that the icon exist and matches mayflower PL
  3. Go to @molecules/AccordionItem and confirm that a single accordion item is displayed, matching the appearance of a single item in Mayflower PL
  4. Go to @organisms/AccordionWrapper and confirm that multiple accordion items are grouped and follow the same behavior as Mayflower PL

Updated Gifs
accordionnoicon
accordionsecondary
accordiondefault

@avrilpearl avrilpearl changed the title [WIP] Adds Accordon Component to Mayflower React React: Add Standard Accordion Components to Mayflower React Jul 24, 2018
@avrilpearl avrilpearl requested a review from mrjmd July 24, 2018 13:29
<Collapse in={this.state.open} dimension="height">
<div className="ma__accordion-content__body">
{ React.Children.map(this.props.children, (child) => {
if (allowedChildren.includes(child.type.name)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe should also check for React.isValidElement(child)) before child.type.name

Copy link
Contributor

Choose a reason for hiding this comment

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

this could also be refactored into a utility function?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added that to the wrapper - we can remove the child check if that is prefered here

<Collapse in={this.state.open} dimension="height">
<div className="ma__accordion-content__body">
{ React.Children.map(this.props.children, (child) => {
if (allowedChildren.includes(child.type.name)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

this could also be refactored into a utility function?

render() {
const buttonClasses = this.state.open ? 'ma__accordion-header__button is-open' : 'ma__accordion-header__button';
const accordionClasses = this.props.border ? 'ma__accordion-item' : 'ma__accordion-item__borderless';
const allowedChildren = ['Paragraph', 'OrderedList', 'UnorderedList', 'Heading', 'Table'];
Copy link
Contributor

Choose a reason for hiding this comment

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

where does this list come from? also see this in patternlab --> https://mayflower.digital.mass.gov/?p=molecules-contact-us-collapsed-with-more-link

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we can remove any check for children type if that is a better approach here..

{this.props.icon}
</div>
)}
<h2 className="ma__accordion-header__title">{this.props.title}</h2>
Copy link
Contributor

Choose a reason for hiding this comment

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

heading level should probably be passable

@clairesunstudio
Copy link
Contributor

I think this is a good use of children to prevent prop drilling. I can see many organisms or higher components can be refactored to use children especially for those don't care what order of children are passed and don't need to carry any logic at the wrapper level. The react-transition-group can potentially solve all the animation problems we are running into, e.g. page scroll. For this specific case, since everything is purely css, maybe we could use ReactCSSTransitionGroup a higher level api to handle the animation. thoughts?

@pmallett-mc pmallett-mc dismissed their stale review August 20, 2018 17:52

comments about css files were mistaken

}

&__title {
@include ma-h5;
Copy link
Contributor

Choose a reason for hiding this comment

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

why import both h4 and h5 styles?

Copy link
Contributor

Choose a reason for hiding this comment

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

if you want to include the margin, I'd recommend only import h4 and manually set margin

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i think i took this from a pl scss - but i will pull it out

@clairesunstudio
Copy link
Contributor

clairesunstudio commented Aug 20, 2018

Made some small changes to scss. The styles look good! There are a few warnings in AccordionItem.
screen shot 2018-08-20 at 5 07 55 pm
This could be a follow up in design --> currently accordions don't have a hover state style, and for secondary accordion, it might not seem actionable.

Copy link
Contributor

@pmallett-mc pmallett-mc left a comment

Choose a reason for hiding this comment

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

see code comments

@@ -10,15 +11,27 @@ let viewports;

// Scan for component names and set up viewports.
const componentsPath = `${__dirname}/../src/components/`;
components = listDirs(componentsPath)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should keep the main backstop.js as free from distraction as possible (it's already got more than we probably want with my split of atoms/non-atoms)-- it shouldn't care about how to get the list of components, that's a storybook-specific thing.

Instead of looping over the results of the other call into fs here & doing more fs access, let's rename storyBookBackstop listDirs to something like listComponents & fold this logic in there.

// Component directory names are capitalized.
.filter((filePath) => (/^[A-Z]/.test(path.basename(filePath))))
// Only test atoms with this backstop configuration.
.filter((filePath) => (filePath.indexOf('/atoms/') > -1))
// Skip table and media/Image, they need to be tested with larger viewports.
.filter((filePath) => ((filePath.indexOf('table') === -1) && (path.basename(filePath) !== 'Image')));
.filter((filePath) => ((filePath.indexOf('table') === -1) && (path.basename(filePath) !== 'Image')))
// Do not test components without stories;
Copy link
Contributor

Choose a reason for hiding this comment

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

Did this comment go with a line of code somewhere else?

}

function triggerBrowserReflow(node) {
node.offsetHeight; // eslint-disable-line no-unused-expressions
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this doing anything?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah this causes the redraw so the animation can happen

@@ -8,7 +8,7 @@ import CalloutLink from './index';
import CalloutLinkDocs from './CalloutLink.md';
import calloutLinkOptions from './CalloutLink.knobs.options';

storiesOf('molecules/CalloutLink', module).addDecorator(withKnobs)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think these changes resulted in stories being listed in two places
doubled-stories

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah this is so that backstop vr works correctly, it was getting the wrong stories before because of this nesting and that there is not a one to one relationship between src folder structure and storybook navigation - this was the simplest solution to solve this issue but we may want to refactor this in a followup

Copy link
Contributor

Choose a reason for hiding this comment

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

Could we do what we discussed about using the add.("[ComponentName]") in stories to create the reference url?

@@ -34,12 +34,14 @@ const getCommonPropsWithKnobs = () => ({
phone: null
});

storiesOf('molecules/ImagePromo', module).addDecorator(withKnobs)
Copy link
Contributor

Choose a reason for hiding this comment

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

see above comment

@@ -13,7 +13,7 @@ import SocialLinksLiveData from '../../molecules/SocialLinks/SocialLinksLive.jso
import stateSeal from '../../../../../assets/images/stateseal.png';


storiesOf('organisms/Footer', module).addDecorator(withKnobs)
storiesOf('organisms', module).addDecorator(withKnobs)
Copy link
Contributor

Choose a reason for hiding this comment

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

same issue as other example
double-footer

@@ -1,4 +1,4 @@
const listDirs = require('./listDirs');
const listComponents = require('./listComponents');
const storyBookBackstop = require('./storyBookBackstop');
const path = require('path');
const fs = require('fs');
Copy link
Contributor

Choose a reason for hiding this comment

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

this line can be removed

return(
/* eslint-disable no-console */
console.log(`Warning! You cannot pass a ${child.type.name} child to AccordionWrapper`)
/* eslint-disable no-console */
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this line was supposed to be eslint-enable

Copy link
Contributor

Choose a reason for hiding this comment

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

why should this be enable?

Copy link
Contributor

Choose a reason for hiding this comment

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

That or line 20 was maybe supposed to be eslint-disable-next-line instead of just disable

@clairesunstudio clairesunstudio merged commit 0fa00f8 into develop Aug 22, 2018
@clairesunstudio clairesunstudio deleted the react-add-accordion-to-mayflower-react branch August 22, 2018 19:37
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