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: Add logic for new requireScroll prop for Snap Footer component #29863

Draft
wants to merge 34 commits into
base: main
Choose a base branch
from

Conversation

hmalik88
Copy link
Contributor

@hmalik88 hmalik88 commented Jan 22, 2025

Description

Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions:

  1. What is the reason for the change? A new prop was added: requireScroll.
  2. What is the improvement/solution? Snap devs can now optionally include the requireScroll prop in their footers. The prop ensures that the footer buttons are disabled until the snap ui content has been viewed. This prop also means that a scroll arrow is displayed based on the isScrolledToBottom prop.

Related issues

Fixes: MetaMask/snaps#3021

Manual testing steps

  1. Go to https://github.com/hmalik88/swiss-knife-snap and pull down the repo.
  2. Install the snap and click "Trigger long content"
  3. Observe that a scroll arrow appears and that the footer is disabled until content is scrolled.

Screenshots/Recordings

After

Screen.Recording.2025-02-05.at.12.46.34.PM.mov

Pre-merge author checklist

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Copy link
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbot metamaskbot added the team-snaps-platform Snaps Platform team label Jan 22, 2025
@metamaskbot
Copy link
Collaborator

Builds ready [fb1ef7c]
Page Load Metrics (1814 ± 116 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint27622621720409196
domContentLoaded136722351789242116
load143722621814242116
domInteractive246738126
backgroundConnect676242210
firstReactRender1579332210
getState4106192512
initialActions0492115
loadScripts9901733132520398
setupStore65819209
uiStartup163526862089308148
Bundle size diffs
  • background: 0 Bytes (0.00%)
  • ui: 999 Bytes (0.01%)
  • common: 0 Bytes (0.00%)

@metamaskbot
Copy link
Collaborator

Builds ready [22be388]
Page Load Metrics (1687 ± 87 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint29522931563455218
domContentLoaded14902226165917082
load15152298168718087
domInteractive23100382110
backgroundConnect988302713
firstReactRender1598382613
getState46316168
initialActions00000
loadScripts10641716121415273
setupStore691242412
uiStartup168126571954246118
Bundle size diffs
  • background: 0 Bytes (0.00%)
  • ui: 999 Bytes (0.01%)
  • common: 0 Bytes (0.00%)

}, [rawContent, scrollState, scrollArrow, requireScroll]);
};

const LoadingSpinner = memo(function LoadingSpinner() {
Copy link
Member

Choose a reason for hiding this comment

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

Why is this moved out?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For readability

Copy link
Contributor Author

Choose a reason for hiding this comment

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

and memoizing because it's static no need to re-create on every render

@metamaskbot
Copy link
Collaborator

Builds ready [995774c]
Page Load Metrics (1716 ± 89 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint15302354171718689
domContentLoaded15172337168018086
load15292361171618689
domInteractive23101382311
backgroundConnect10143383215
firstReactRender15104442914
getState55617178
initialActions01000
loadScripts10791741122614972
setupStore77817199
uiStartup176126271991241116
Bundle size diffs
  • background: 0 Bytes (0.00%)
  • ui: 4.77 KiB (0.06%)
  • common: 0 Bytes (0.00%)

@metamaskbot
Copy link
Collaborator

Builds ready [f7bac01]
Page Load Metrics (1708 ± 47 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint1560199017099747
domContentLoaded1545193616829546
load1561198917089747
domInteractive25153483316
backgroundConnect95726168
firstReactRender1676372412
getState45214157
initialActions01000
loadScripts1059139212097938
setupStore765212110
uiStartup18042207195310048
Bundle size diffs
  • background: 0 Bytes (0.00%)
  • ui: 3.15 KiB (0.04%)
  • common: 0 Bytes (0.00%)

@metamaskbot
Copy link
Collaborator

Builds ready [1697674]
Page Load Metrics (1613 ± 66 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint21719531550328157
domContentLoaded13961929159012259
load14012023161313766
domInteractive248336189
backgroundConnect877252010
firstReactRender1469352311
getState48011168
initialActions0724168
loadScripts9631406113710852
setupStore763192110
uiStartup158127481883243117
Bundle size diffs
  • background: 0 Bytes (0.00%)
  • ui: 2.78 KiB (0.04%)
  • common: 0 Bytes (0.00%)

@@ -82,7 +83,7 @@ export const SnapUIFooterButton: FunctionComponent<
{...props}
size={ButtonSize.Lg}
block
disabled={disabled}
disabled={requireScroll ? !buttonsEnabled : disabled}
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't the disabled prop always take priority here?

Suggested change
disabled={requireScroll ? !buttonsEnabled : disabled}
disabled={disabled || (requireScroll && !buttonsEnabled)}

let hasReachedBottom;
switch (action.type) {
case 'MANUAL_SCROLL':
hasReachedBottom = state.hasReachedBottom || action.isAtBottom;
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this needs to be a mutable variable.

}, [interfaceState?.content]);

const requireScroll = useMemo(
() => Boolean(content?.props?.children?.[1]?.props?.requireScroll),
Copy link
Member

Choose a reason for hiding this comment

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

Is this guaranteed to be the correct component?

? rawContent
: Container({ children: rawContent });
}, [interfaceState?.content]);

const requireScroll = useMemo(
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this needs to be memoised.

return;
}

const isActuallyAtBottom =
Copy link
Member

Choose a reason for hiding this comment

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

Is this different from useScrollRequired's hasScrolledToBottomState? Can we deduplicate?

Comment on lines +165 to +169
// Prevent multiple clicks
if (isProgrammaticScrollRef.current) {
return;
}
isProgrammaticScrollRef.current = true;
Copy link
Member

Choose a reason for hiding this comment

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

Why is this a ref? Is this necessary in the first place?

contentBackgroundColor ??
mapToExtensionCompatibleColor(content?.props?.backgroundColor) ??
BackgroundColor.backgroundAlternative;
const backgroundColor = useMemo(
Copy link
Member

Choose a reason for hiding this comment

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

Again doesn't feel like this needs to be memoised.


// The renderer should only have a footer if there is a default cancel action
// or if the footer component has been used.
const hasFooter = useMemo(
Copy link
Member

Choose a reason for hiding this comment

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

Same here regarding memoisation.

expect(getByText('Foo')).toBeDefined();
expect(container).toMatchSnapshot();
});
describe('Basic Rendering', () => {
Copy link
Member

Choose a reason for hiding this comment

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

The change in nesting makes this diff very difficult to read. Maybe move it to a separate PR, and only add the required changes here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
team-snaps-platform Snaps Platform team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add prop & logic to disable footer actions until the entire content is viewed
6 participants