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

feat: reserves space for button message and renders messageMarkup #2335

Merged
merged 8 commits into from
Feb 23, 2024

Conversation

danzhaaspaypal
Copy link
Contributor

Description

For the Buttons dynamic messaging feature:
In the Buttons component, reserves space for button message during 1st render and renders messageMarkup on second render.

Why are we making these changes? Include references to any related Jira tasks or GitHub Issues

Dynamic Messaging with Buttons Epic and Update button render to reserve message space Story

Reproduction Steps (if applicable)

Pass in message prop to button component, optionally specifying its own child property position with 'top' or 'bottom'. Conditionally, a 36 px space will populate above or below the group of buttons.

Screenshots (if applicable)

Screenshot 2024-02-14 at 1 14 04 PM
Screenshot 2024-02-14 at 1 14 15 PM
Screenshot 2024-02-14 at 1 14 21 PM

Dependent Changes (if applicable)

n/a

Groups who should review (if applicable)

Upstream Messaging
XO components

❤️ Thank you!

src/zoid/buttons/component.jsx Outdated Show resolved Hide resolved
src/ui/buttons/message.jsx Outdated Show resolved Hide resolved
src/ui/buttons/message.jsx Outdated Show resolved Hide resolved
src/ui/buttons/message.jsx Outdated Show resolved Hide resolved
src/ui/buttons/buttons.jsx Outdated Show resolved Hide resolved
src/ui/buttons/buttons.jsx Outdated Show resolved Hide resolved
src/ui/buttons/buttons.jsx Outdated Show resolved Hide resolved
src/ui/buttons/buttons.jsx Outdated Show resolved Hide resolved
src/ui/buttons/buttons.jsx Outdated Show resolved Hide resolved
src/ui/buttons/message.jsx Outdated Show resolved Hide resolved
src/ui/buttons/message.jsx Outdated Show resolved Hide resolved
src/ui/buttons/buttons.jsx Outdated Show resolved Hide resolved
test/integration/tests/button/message.js Outdated Show resolved Hide resolved
src/ui/buttons/buttons.jsx Outdated Show resolved Hide resolved
test/integration/tests/button/message.js Show resolved Hide resolved
test/integration/tests/button/message.js Outdated Show resolved Hide resolved
src/ui/buttons/buttons.jsx Outdated Show resolved Hide resolved
src/ui/buttons/buttons.jsx Outdated Show resolved Hide resolved
Copy link

codecov bot commented Feb 21, 2024

Codecov Report

Attention: Patch coverage is 58.06452% with 13 lines in your changes are missing coverage. Please review.

❗ No coverage uploaded for pull request base (feature/dynamic-messaging@0806df1). Click here to learn what that means.

Files Patch % Lines
src/ui/buttons/buttons.jsx 61.53% 5 Missing ⚠️
src/ui/buttons/util.js 58.33% 5 Missing ⚠️
src/ui/buttons/message.jsx 50.00% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@                     Coverage Diff                      @@
##             feature/dynamic-messaging    #2335   +/-   ##
============================================================
  Coverage                             ?   52.20%           
============================================================
  Files                                ?      106           
  Lines                                ?     2109           
  Branches                             ?      641           
============================================================
  Hits                                 ?     1101           
  Misses                               ?      904           
  Partials                             ?      104           
Flag Coverage Δ
jest 32.03% <35.48%> (?)
karma 51.25% <75.00%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@Seavenly Seavenly marked this pull request as ready for review February 21, 2024 20:48
@Seavenly Seavenly requested a review from a team as a code owner February 21, 2024 20:48
Comment on lines 16 to 25
const reservationDiv = `<div class="${CLASS.BUTTON_MESSAGE_RESERVE}" style="height:${INITIAL_RESERVED_HEIGHT}" ></div>`;

return (
<div
class={[CLASS.BUTTON_MESSAGE, `${CLASS.BUTTON_MESSAGE}-${position}`].join(
" "
)}
innerHTML={typeof markup === "string" ? markup : reservationDiv}
/>
);
Copy link
Member

Choose a reason for hiding this comment

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

Github UI probably won't format this well but I think something like this would be clearer in intention:

Suggested change
const reservationDiv = `<div class="${CLASS.BUTTON_MESSAGE_RESERVE}" style="height:${INITIAL_RESERVED_HEIGHT}" ></div>`;
return (
<div
class={[CLASS.BUTTON_MESSAGE, `${CLASS.BUTTON_MESSAGE}-${position}`].join(
" "
)}
innerHTML={typeof markup === "string" ? markup : reservationDiv}
/>
);
const messageClassNames = [CLASS.BUTTON_MESSAGE, `${CLASS.BUTTON_MESSAGE}-${position}`].join(" ")
if (!typeof markup === "string") {
return <div className={messageClassNames}>
<div className={CLASS.BUTTON_MESSAGE_RESERVE} style={`height:${INITIAL_RESERVED_HEIGHT}`} />
</div>
}
return (
<div
className={messageClassNames}
innerHTML={markup}
/>
);

Copy link
Member

Choose a reason for hiding this comment

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

or you could do something like this:

Suggested change
const reservationDiv = `<div class="${CLASS.BUTTON_MESSAGE_RESERVE}" style="height:${INITIAL_RESERVED_HEIGHT}" ></div>`;
return (
<div
class={[CLASS.BUTTON_MESSAGE, `${CLASS.BUTTON_MESSAGE}-${position}`].join(
" "
)}
innerHTML={typeof markup === "string" ? markup : reservationDiv}
/>
);
const messageClassNames = [CLASS.BUTTON_MESSAGE, `${CLASS.BUTTON_MESSAGE}-${position}`].join(" ")
if (!typeof markup === "string") {
return <div className={`${messageClassNames} $CLASS.BUTTON_MESSAGE_RESERVE}`} style={`height:${INITIAL_RESERVED_HEIGHT}`} />
}
return (
<div
className={messageClassNames}
innerHTML={markup}
/>
);

Copy link
Member

Choose a reason for hiding this comment

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

also also className -> class in all my examples i forgot i'm not writing React 😂

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will do

Copy link
Member

@jshawl jshawl left a comment

Choose a reason for hiding this comment

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

I added a few non-blocking comments but LGTM 🚀

return MESSAGE_POSITION.TOP;
}
return MESSAGE_POSITION.BOTTOM;
}
Copy link
Member

Choose a reason for hiding this comment

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

option to move this function ui/buttons/message.jsx (I did not see it used elsewhere and/or reference variables in the parent scope)

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 like the idea of decluttering buttons.jsx; I'd like to suggest ui/buttons/util.js as another good place to consider moving that function. Thoughts, preference?

Copy link
Member

Choose a reason for hiding this comment

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

I think ui/buttons/util.js would work well! 🚀

@@ -150,6 +152,28 @@ export function validateButtonProps(props: ButtonPropsInputs) {
normalizeButtonProps(props);
}

function calculateMessagePosition({ message, showPoweredBy, layout }): string {
if (!message) {
return "none";
Copy link
Member

@jshawl jshawl Feb 22, 2024

Choose a reason for hiding this comment

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

option to add a NONE constant here -

export const MESSAGE_POSITION = {
TOP: ("top": "top"),
BOTTOM: ("bottom": "bottom"),
};
(for consistency) and change the return type to $Values<typeof MESSAGE_POSITION> (just kind of cool)

Copy link
Contributor

Choose a reason for hiding this comment

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

We do not want NONE to be considered a valid input option which MESSAGE_POSITION is currently used for as a type. It's purely an internal computed value. Would it be beneficial to have a separate constant to capture the possible internal values?

Copy link
Member

Choose a reason for hiding this comment

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

ah that's a good point! I think if it were me I would leave it as-is. one other idea just for fun would be to make the return type string | void and the early return would return nothing/undefined. But I think I like what you have here better than that

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jshawl Nate and I tried a few different approaches being mindful of type returned here; the null return approach was our first attempted strategy, and if Flow would be mindful of our type logic, we would gladly go with that option. But it didn't exactly mind our logic correctly: it tried to suggest null should be a possible value in the Message component where it cannot logically be passed in due to logic on lines 302 and 359. And it seemed wrong to abide that workaround by accommodating null inside Message where it could not appear.

We tried a few other typing workarounds, and finally settled on this being the least of the evils.

Copy link
Member

Choose a reason for hiding this comment

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

this is flow's fault 😂

Copy link
Contributor Author

Choose a reason for hiding this comment

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

exactly

!fundingSource &&
!message;
const showPoweredBy =
layout === BUTTON_LAYOUT.VERTICAL && fundingSources.includes(FUNDING.CARD);
Copy link
Member

Choose a reason for hiding this comment

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

I think fundingSources will always include FUNDING.CARD -

if (fundingSources.indexOf(FUNDING.CARD) !== -1) {
fundingSources = [
...fundingSources.filter((src) => src !== FUNDING.CARD),
FUNDING.CARD,
];
}
(so can remove the && fundingSources.includes)

Copy link
Member

Choose a reason for hiding this comment

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

I actually don't think it would. Its confusing, but the standalone button case uses Buttons component but with fundingSource=paypal|venmo|card|etc. I think this check is precisely for those instances where we are in Standalone and its not the Card button

Copy link
Member

Choose a reason for hiding this comment

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

ah good catch! thank you for clarifying that!

Copy link
Member

Choose a reason for hiding this comment

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

Not a problem, actually that would be a good candidate for a refactor. It would probably simplify things if we created a StandaloneButton component and rendered that instead of Buttons if fundingSource was passed

});
});
});
});
Copy link
Member

Choose a reason for hiding this comment

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

awesome test coverage!! 💯 🏅

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jshawl thank you!

@Seavenly Seavenly merged commit 11989d5 into feature/dynamic-messaging Feb 23, 2024
1 of 3 checks passed
@Seavenly Seavenly deleted the feature/btn-msg-space1 branch February 23, 2024 19:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants