Skip to content

Conversation

alexcambose
Copy link
Contributor

@alexcambose alexcambose commented Sep 26, 2025

Summary

Adding an initial version of ag-grid based grid.

Rationale

How has this been tested?

  • Current tests cover my changes
  • Added new tests
  • Manually tested the code

@alexcambose alexcambose self-assigned this Sep 26, 2025
Copy link

vercel bot commented Sep 26, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
component-library Ready Ready Preview Comment Oct 7, 2025 1:57pm
developer-hub Ready Ready Preview Comment Oct 7, 2025 1:57pm
entropy-explorer Ready Ready Preview Comment Oct 7, 2025 1:57pm
insights Ready Ready Preview Comment Oct 7, 2025 1:57pm
3 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
api-reference Skipped Skipped Oct 7, 2025 1:57pm
proposals Skipped Skipped Oct 7, 2025 1:57pm
staking Skipped Skipped Oct 7, 2025 1:57pm

Comment on lines 58 to 69
const mappedColDefs = useMemo(() => {
return colDefs.map((colDef) => {
return {
...colDef,
// the types in ag-grid are `any` for the cellRenderers which is throwing an error here
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
cellRenderer: isLoading
? (colDef.loadingCellRenderer ?? SkeletonCellRenderer)
: colDef.cellRenderer,
};
});
}, [colDefs, isLoading]);
Copy link
Contributor

Choose a reason for hiding this comment

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

IMO we should try to avoid mapping colDefs as much as we possibly can, since it implicitly means we've added an abstraction layer on top of AG grid, and in my experience this quickly becomes very messy.

For this specific use case is there any chance we can leverage the cellRendererSelector + defaultColDef instead?

Also - is it really correct that we should swap out the renderers of all cells instead of showing a loading overlay?

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 wanted to have a nicer loading state rather than disabling the whole thing - especially if the grid is full screen height. DIdn't know about about cellRendererSelector I'll try it 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.

Later edit: actually cellRendererSelector is on a per cell basis so we would still be doing the same mapping over colDefs, and also it might not work as its a function that uses the row data, so we might need to recreate this function that returns different renderers based on the loading state.

I propose we leave it like this for now and if it causes issue then we can remove it favor of the default loading overlay. It's very surprising it's so difficult to have a loading skeleton instead of the default loading overlay - which is a much better UX.

Copy link
Contributor

Choose a reason for hiding this comment

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

There's also a loadingOverlayComponent param we can pass to the grid btw, but maybe you've already looked at that.

Comment on lines +46 to +75
const PriceCellRenderer = ({ value }: { value: number }) => (
<span style={{ height: "100%", display: "flex", alignItems: "center" }}>
{`$${value.toLocaleString(undefined, {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
})}`}
</span>
);

const ConfidenceCellRenderer = ({ value }: { value: number }) => (
<span
style={{ height: "100%", display: "flex", alignItems: "center" }}
>{`+/- ${value.toFixed(2)}%`}</span>
);

const FeedCellRenderer = ({ value }: { value: string }) => (
<div style={{ height: "100%", display: "flex", alignItems: "center" }}>
<SymbolPairTag
displaySymbol={value}
icon={<BtcIcon />}
description={value}
/>
</div>
);

const FeedCellRendererLoading = () => (
<div style={{ height: "100%", display: "flex", alignItems: "center" }}>
<SymbolPairTag isLoading />
</div>
);
Copy link
Contributor

Choose a reason for hiding this comment

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

Very interesting discussion to be had here as well regarding what the right abstractions are.

  • Should priceCellRenderer inherit from a numberCellRenderer?
    • Perhaps there should even be a priceColDef?
      • And perhaps there should even be a priceColDefFactory, to which I can pass parameters like colorizeNumbers?
        • ...and so on ad infinitum (this was only 3 layers of abstraction deep!)

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 I think with these kind of things the best way is let things as simple as possible and then create the abstraction as needed, when we start duplicating the code or having a similar logic in 2-3 places.

Comment on lines +4 to +14
--ag-browser-color-scheme: light-dark(light, dark);
--ag-background-color: #{theme.color("background", "primary")};
--ag-header-background-color: var(--ag-background-color);
--ag-foreground-color: #{theme.color("paragraph")};
--ag-accent-color: #{theme.color("button", "outline", "background", "active")};
--ag-header-font-size: #{theme.font-size("xs")};
--ag-header-font-weight: #{theme.font-weight("medium")};
--ag-cell-font-size: #{theme.font-size("xs")};
--ag-wrapper-border: none;
--ag-cell-text-color: #{theme.color("paragraph")};
--ag-data-font-size: #{theme.font-size("base")};
Copy link
Collaborator

Choose a reason for hiding this comment

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

nice!

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.

3 participants