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 search input to chain, bridges and exchanges pages #305

Merged
merged 16 commits into from
Sep 30, 2024

Conversation

DNR500
Copy link
Contributor

@DNR500 DNR500 commented Sep 24, 2024

JIra: LF-8523

This PR adds stick search inputs to the chains, bridges and exchanges pages

Screenshot 2024-09-24 at 20 06 58
Screenshot 2024-09-24 at 20 07 12

It reuses and makes a component out of the search input thats already in use for token selection and creates a set of reusable components across the pages.

There were a couple of caveats around the different layout height modes

  • When the layout is in default or max height mode the page could potentially collapse whilst a users was searching and this looked odd so the useFullPageInMaxHeightLayout hook was made with the intention ensuring the page takes up the maximum amount of space available.
  • Sticky mode when the Widget is in Full height layout mode requires some thought to ensure that it displays correctly. It also needs access to the header height, which it does using the useHeaderHeight hook.
    • Whilst working on this I noticed that useHeaderHeight wasn't working properly I've created an alternative implementation here that use MutationObserver as a potential work around. I've some other ideas for potentially improvements in relation to this that I'll mention on the PR too.

      • Screenshot 2024-09-24 at 19 42 46

There needed to be some thought around the checkbox functionality as well on the Bridges and Exchanges pages - mainly around the select all and deselect all checkbox. It would be good to check that if the behaviour that I have put together here is desirable.

checkbox-capture

@DNR500 DNR500 added the WIP Work in progress label Sep 24, 2024
resizeObserver.disconnect();
}
};
}, [elementId, headerHeight, headerElement, setHeaderHeight]);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Using the MutationObserver here in place of the imperative if checks we were doing previously - that was getting more difficult to get to get it to work in certain situations.

For the split subvariant there was still this problem in full height layout mode. And this problem can happen on other pages.

Screenshot 2024-09-24 at 19 42 46

One improvement I think that would still be good here is to move the useLayoutEffect to the Header component itself and have that set a value on the Header Store - the useHeaderHeight hook would then become an access point for the height value in the store and using zustand shallow checks would actually be able to limit potential renders in the Widget where the height value it used

Copy link
Member

Choose a reason for hiding this comment

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

@DNR500 are we sure we want to see headerHeight in the deps array?

Copy link
Member

Choose a reason for hiding this comment

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

One improvement I think that would still be good here is to move the useLayoutEffect to the Header component itself and have that set a value on the Header Store - the useHeaderHeight hook would then become an access point for the height value in the store and using zustand shallow checks would actually be able to limit potential renders in the Widget where the height value it used

Should we do it now? 👀

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'm doing this move now and the deps array is much simpler and doesn't need the headerHeight.

@DNR500 DNR500 marked this pull request as ready for review September 24, 2024 18:18
@DNR500 DNR500 added testing and removed WIP Work in progress labels Sep 24, 2024
Copy link

Hey! This is your new endopint: https://67ac0ba3.widget-addsearchi.pages.dev

resizeObserver.disconnect();
}
};
}, [elementId, headerHeight, headerElement, setHeaderHeight]);
Copy link
Member

Choose a reason for hiding this comment

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

@DNR500 are we sure we want to see headerHeight in the deps array?

Comment on lines 7 to 14
// When the Widgets layout is set to use max height or in its default height mode the default behaviour
// is for pages to use only the minimum height that they need to show their content.
// On some pages you might want to always ensure that the page always up the maximum height available.
// To do this just add this hook at the page level.
// The other height layout will by default always occupy the maximum space available.
// NOTE: this hook is implicitly tied to the widget height functionality in the
// AppExpandedContainer, RelativeContainer and CssBaselineContainer components as defined in AppContainer.ts
// CSS changes in those components can have implications for the functionality in this hook
Copy link
Member

Choose a reason for hiding this comment

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

This thing becomes so complex 🥲

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've decided to go with a way to let CSS carry the load here.

Have deleted this hook and created a full page container component

export const FullPageContainer = styled((props: PageContainerProps) => (
<PageContainer
{...props}
className={`${props.className} full-page-container`}
/>
))``;

The css for this lives in the AppContainer

[`&:has(.full-page-container)`]: {
height: theme.container?.maxHeight
? theme.container?.maxHeight
: theme.container?.height || defaultMaxHeight,
},

And just means on the pages that we swap out the PageContainer for the FullPageContainer

This method was already being used for the SelectTokenPage by setting an id on the TokenList, I've just repurposed it here.

Copy link
Contributor Author

@DNR500 DNR500 Sep 25, 2024

Choose a reason for hiding this comment

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

In relation to the layout/height code I think there are still somethings that we can do to simplify the code further in future.

  • Consolidate the logic and styles in the AppContainer.tsx files AppExpandedContainer, RelativeContainer and CssBaselineContainerProps. It does get confusing where the height should be set to get the desired result for layouts
  • useTokenListHeight hook could potentially be replaced with a css implementation - I've managed to create a list in a side project that resizes in the way that the token list in our app does using just css. Though I have had a failed attempt at getting this working already I do think that at some point its worth another attempt.

Comment on lines 7 to 14

interface SearchStickyContainerProps {
headerHeight: number;
}

export const searchContainerHeight = 64;

// When the widget is in Full Height mode the
Copy link
Member

Choose a reason for hiding this comment

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

Something is missing at the end of the comment?

Copy link
Contributor Author

@DNR500 DNR500 Sep 25, 2024

Choose a reason for hiding this comment

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

Have reworded this

}));

// When in full height mode the list needs make an addition to the paddingTop of the SearchStickyContainer height
// this compensations for SearchStickyContainer being fixed position and compensates for it no long being in the document flow
Copy link
Member

Choose a reason for hiding this comment

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

It is not clear to me, especially the second part 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Have reworded this, hopefully it makes more sense

resizeObserver.disconnect();
}
};
}, [elementId, headerHeight, headerElement, setHeaderHeight]);
Copy link
Member

Choose a reason for hiding this comment

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

One improvement I think that would still be good here is to move the useLayoutEffect to the Header component itself and have that set a value on the Header Store - the useHeaderHeight hook would then become an access point for the height value in the store and using zustand shallow checks would actually be able to limit potential renders in the Widget where the height value it used

Should we do it now? 👀

Comment on lines +104 to +133
const allKeysInCollectionEnabled = toolKeys.every(
(toolKey) => state[`_enabled${toolType}`][toolKey],
);

// then toggle those keys to false
const updatedTools = toolKeys.reduce(
(accum, toolKey) => {
accum[toolKey] = !allKeysInCollectionEnabled;
return accum;
},
{
...state[`_enabled${toolType}`],
},
);

const enableKeys: string[] = [];
const disabledKeys: string[] = [];

Object.entries(updatedTools).forEach(([key, value]) => {
if (value) {
enableKeys.push(key);
} else {
disabledKeys.push(key);
}
});

return {
[`_enabled${toolType}`]: enabledTools,
[`enabled${toolType}`]: enableAll ? Object.keys(enabledTools) : [],
[`disabled${toolType}`]: enableAll ? [] : Object.keys(enabledTools),
[`_enabled${toolType}`]: updatedTools,
[`enabled${toolType}`]: enableKeys,
[`disabled${toolType}`]: disabledKeys,
Copy link
Member

Choose a reason for hiding this comment

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

Due to these changes here please double-check just in case that we send the correct filtering options to the API.

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 check this in the morning

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Have check that the bridge and exchanges are passed correctly to the options on request - it looks like its working

Copy link

Hey! This is your new endopint: https://f1b89902.widget-addsearchi.pages.dev

@DNR500
Copy link
Contributor Author

DNR500 commented Sep 25, 2024

I've also added some fixes to make the WIdgetSkeleton look better in relation to the different layout modes

Copy link

Hey! This is your new endopint: https://cc9ce090.widget-addsearchi.pages.dev

<Box
ref={parentRef}
style={{ height, overflow: 'auto' }}
id={createElementId(ElementId.TokenList, elementId)}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This isn't needed any more as the SelectTokenPage used the FullPageContainer

paddingRight: theme.spacing(3),
}));

export const SkeletonHeaderContainer = styled(Box)(({ theme }) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Some widget skeleton changes were needed so that the Skeleton doesn't apear broken in the various layout modes

@chybisov chybisov merged commit 5504d95 into main Sep 30, 2024
1 check passed
@chybisov chybisov deleted the add-search-input-to-chain-bridges-exchanges-pages branch September 30, 2024 12:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants