Skip to content

Conversation

chloerice
Copy link
Member

@chloerice chloerice commented Aug 28, 2019

WHY are these changes introduced?

The Orders team needs to be able to specify the order of their Page actions because one of their actions varies from being a secondaryAction or an actionGroup depending on the status of the order.

WHAT is this pull request doing?

Adds support for overriding the order of actions in the action menu.

How to 🎩

🖥 Local development instructions
🗒 General tophatting guidelines
📄 Changelog guidelines

Copy-paste this code in playground/Playground.tsx:
import React from 'react';
import {Page, Thumbnail, Badge} from '../src';

export function Playground() {
  return (
    <Page
      breadcrumbs={[{content: 'Products', url: '/products'}]}
      title="3/4 inch Leather pet collar"
      titleMetadata={<Badge status="success">Paid</Badge>}
      subtitle="Perfect for any pet"
      thumbnail={
        <Thumbnail
          source="https://burst.shopifycdn.com/photos/black-leather-choker-necklace_373x@2x.jpg"
          alt="Black leather pet collar"
        />
      }
      primaryAction={{content: 'Save', disabled: true}}
      secondaryActions={[
        {
          content: 'Duplicate',
          accessibilityLabel: 'Secondary action label',
        },
        {content: 'View on your store'},
      ]}
      actionGroups={[
        {
          index: 0,
          title: 'Promote',
          actions: [
            {
              content: 'Share on Facebook',
              accessibilityLabel: 'Individual action label',
              onAction: () => {},
            },
          ],
        },
      ]}
      pagination={{
        hasPrevious: true,
        hasNext: true,
      }}
      separator
    >
      <p>Page content</p>
    </Page>
  );
}

🎩 checklist

Copy link

@danrosenthal danrosenthal left a comment

Choose a reason for hiding this comment

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

I mentioned this IRL, but I think it would be interesting to explore an API that maps to the flexbox order property. As you said, this could even map directly to that property in the implementation, using flexbox to reorder these as specified. This would also probably simplify the code a good bit, and might be a positive for accessibility.

@chloerice
Copy link
Member Author

Quick update: This was initially done in and following an adhoc pairing session and will be prioritized next week.

@chloerice
Copy link
Member Author

chloerice commented Sep 5, 2019

I mentioned this IRL, but I think it would be interesting to explore an API that maps to the flexbox order property. As you said, this could even map directly to that property in the implementation, using flexbox to reorder these as specified. This would also probably simplify the code a good bit, and might be a positive for accessibility.

I think there was a mixup when I spoke briefly about this work during show and tell. The reason I named the property index vs order is because both secondaryActions and actionGroups are arrays of actions, and in order to override their order they are combined into a single array of actions and any with an index specified are moved into that place in the list.

The index provided maps to the order in the overall list of actions below the title. I'd mentioned that I initially called the property order, but changed it to index because I didn't want there to be confusion around the way the order is overridden under the hood. This is because the flexbox order property has accessibility issues that we don't want to propagate.

@chloerice chloerice force-pushed the action-order-override branch from 6b3d749 to 8ace217 Compare October 9, 2019 20:45
@github-actions
Copy link
Contributor

github-actions bot commented Oct 9, 2019

💦 Potential splash zone of changes introduced to src/**/*.tsx in this pull request:

Files modified7
Files potentially affected136

Details

All files potentially affected (total: 136)
📄 UNRELEASED.md (total: 0)

Files potentially affected (total: 0)

🧩 src/components/ActionMenu/ActionMenu.tsx (total: 2)

Files potentially affected (total: 2)

🧩 src/components/ActionMenu/tests/ActionMenu.test.tsx (total: 0)

Files potentially affected (total: 0)

🧩 src/components/ActionMenu/tests/utilities.test.ts (total: 0)

Files potentially affected (total: 0)

🧩 src/components/ActionMenu/utilities.ts (total: 3)

Files potentially affected (total: 3)

🧩 src/components/Page/components/Header/Header.tsx (total: 1)

Files potentially affected (total: 1)

🧩 src/types.ts (total: 136)

Files potentially affected (total: 136)


This comment automatically updates as changes are made to this pull request.
Feedback, troubleshooting: open an issue or reach out on Slack in #polaris-tooling.

@brandon-yetman
Copy link

Hey @chloerice, any update on when this will be ready to go?

@chloerice chloerice force-pushed the action-order-override branch 7 times, most recently from 82c6e6f to eb4e39c Compare January 9, 2020 21:55
@chloerice chloerice force-pushed the action-order-override branch 5 times, most recently from f3b37c0 to 7668662 Compare January 16, 2020 22:07
@chloerice chloerice changed the title [WIP][ActionMenu] Add support for explicit item order [ActionMenu] Add support for explicit item order Jan 16, 2020
@chloerice
Copy link
Member Author

@brandon-yetman This is ready to go! Codecov is still fighting me, though. @AndrewMusgrave looking at the diff in codecov vs the tests I have here, do you see any obvious holes in tests? It's driving me nuts 😣

@chloerice chloerice marked this pull request as ready for review January 16, 2020 22:52
@brandon-yetman
Copy link

Thanks so much for your hard work on this @chloerice !!

const {activeMenuGroup} = this.state;
const menuActions = [...actions, ...groups];

if (menuActions.length === 0) {
Copy link
Member

Choose a reason for hiding this comment

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

This branch was never executing because we're returning early in the render method

index: number;
};

export function sortAndOverrideActionOrder(
Copy link
Member

Choose a reason for hiding this comment

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

Here we're filtering out the descriptors without index, so we're never hitting the edges cases below.

@AndrewMusgrave
Copy link
Member

Here we're not hitting the default properties (indexA = 0)
Screen Shot 2020-01-17 at 11 43 03 AM
Here we're not hitting the else statement
Screen Shot 2020-01-17 at 11 43 07 AM
Here we're never exiciting this branch
Screen Shot 2020-01-17 at 11 43 11 AM

@AndrewMusgrave
Copy link
Member

That should bump codecov to 100% but I'll check back after lunch. Here're my changes, I left some comments. Let me know if you have any questions 😄

@AndrewMusgrave
Copy link
Member

💯

@chloerice
Copy link
Member Author

That should bump codecov to 100% but I'll check back after lunch. Here're my changes, I left some comments. Let me know if you have any questions 😄

Thank you so much @AndrewMusgrave!!! 🙏 🙌

Copy link

@brandon-yetman brandon-yetman left a comment

Choose a reason for hiding this comment

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

🎩 and code looks great!

One detail of note is that the rollup menu (i.e. on a mobile display) does not take into account the explicit item order, but this is a) not explicitly required for the use-case that brought about this PR, and b) potentially undesireable.

Thanks again @chloerice !

];

sortedActionsWithOverrides.forEach((action) => {
overriddenActions.splice(action.index, 0, action);

Choose a reason for hiding this comment

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

Very elegant solution 👍

Copy link
Member

@AndrewMusgrave AndrewMusgrave left a comment

Choose a reason for hiding this comment

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

LGTM 🎩 ✅ Left a few comments about type safety. We also should add a readme example, but it shouldn't delay this getting shipped 😄

@@ -1,60 +1,19 @@
# Unreleased changes

Copy link
Member

Choose a reason for hiding this comment

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

A rebase might be needed 😄

? groups.map(({title, ...rest}, index) => (
const actionMarkup = overriddenActions.map((action, index) => {
if (Object.hasOwnProperty.call(action, 'title')) {
const {title, actions, ...rest} = action as MenuGroupDescriptor;
Copy link
Member

Choose a reason for hiding this comment

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

The in keyword works as a type guard for narrowing.

  if ('title' in action) {
    const {title, actions, ...rest} = action;

{groupsMarkup}
</div>
) : null;
const {content, ...rest} = action as MenuActionDescriptor;
Copy link
Member

Choose a reason for hiding this comment

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

With the guard above we can remove this cast as well!

) {
const actionsWithOverrides = actions.filter(
(action) => action.index !== undefined,
) as MenuDescriptorWithIndex[];
Copy link
Member

Choose a reason for hiding this comment

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

If we wanted type safety we could approach it like this.

...
  const actionsWithOverrides = actions.filter(
    (action) => action.index !== undefined,
  ); // Cast removed

  if (isMenuDescriptionWithIndex(actionsWithOverrides)) { // reversed logic
    ...
  }

  return actions;
}

function isMenuDescriptionWithIndex( // narrowing function
  actions: (MenuActionDescriptor | MenuGroupDescriptor)[],
): actions is MenuDescriptorWithIndex[] {
  return actions.length !== 0;
}

@chloerice
Copy link
Member Author

🎩 and code looks great!

One detail of note is that the rollup menu (i.e. on a mobile display) does not take into account the explicit item order, but this is a) not explicitly required for the use-case that brought about this PR, and b) potentially undesireable.

Thanks again @chloerice !

Thanks @brandon-yetman! The rollup menu wasn't included in these changes because there would need to be a redesign of ActionList. Right now it always renders the sections (ActionMenu.groups on large screens) last so the items (ActionMenu.items on large screens) don't get lost in the lack of hierarchy. I'll make an issue and get some design feedback and ship this for now so it doesn't block you and your team.

@chloerice chloerice force-pushed the action-order-override branch from 5c84213 to 6ada143 Compare January 22, 2020 18:10
@brandon-yetman
Copy link

Yeah I figured it's out of scope for this PR anyways, just wanted to make sure it was noted. Thanks 🙌

@chloerice chloerice force-pushed the action-order-override branch from 574a5ea to 934e587 Compare January 22, 2020 20:39
@chloerice chloerice merged commit aa3dfba into master Jan 22, 2020
@chloerice chloerice deleted the action-order-override branch January 22, 2020 20:48
@dleroux dleroux temporarily deployed to production January 27, 2020 13:38 Inactive
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants