Skip to content

Commit

Permalink
fix(ForgeLayout): fix performance/bg attachment (#1551)
Browse files Browse the repository at this point in the history
## πŸ“ Changes

- Stick background on scroll
- Try to fix some perf issues

## βœ… Checklist

Easy UI has certain UX standards that must be met. In general,
non-trivial changes should meet the following criteria:

- [x] Visuals match Design Specs in Figma
- [x] Stories accompany any component changes
- [x] Code is in accordance with our style guide
- [x] Design tokens are utilized
- [x] Unit tests accompany any component changes
- [x] TSDoc is written for any API surface area
- [x] Specs are up-to-date
- [x] Console is free from warnings
- [x] No accessibility violations are reported
- [x] Cross-browser check is performed (Chrome, Safari, Firefox)
- [x] Changeset is added

~Strikethrough~ any items that are not applicable to this pull request.
  • Loading branch information
stephenjwatkins authored Dec 19, 2024
1 parent 40e322a commit 2be5e1c
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 34 deletions.
5 changes: 5 additions & 0 deletions .changeset/cyan-goats-promise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@easypost/easy-ui": patch
---

fix(ForgeLayout): attach bg
57 changes: 29 additions & 28 deletions easy-ui-react/src/ForgeLayout/ForgeLayout.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
padding-right: component-token("forge-layout", "shell-gutter");
gap: component-token("forge-layout", "shell-gutter");
min-height: 100svh;
background-color: design-token("color.neutral.025");
position: relative;
overflow-x: clip;
}

.modeTest {
Expand All @@ -37,6 +37,15 @@
@include component-token("forge-layout", "header-border-width", 2px);
}

.bg {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: design-token("color.neutral.025");
}

.backgroundDecoration01 {
background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzA5IiBoZWlnaHQ9IjI5NSIgdmlld0JveD0iMCAwIDMwOSAyOTUiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGQ9Ik00NC4xMTc1IDIyOC41NjdDMzQuNjg2OSAyMjYuOTU3IDI3LjcwMjEgMjE4LjkxOCAyNy40MjQgMjA5LjM1N0wyNS41MDk2IDE0My41NzNDMjUuMzM2NSAxMzcuNTU5IDI3Ljg2OTkgMTMxLjc4IDMyLjQxMTIgMTI3LjgzNEw2MS41MjM5IDEwMi41MzRDNjYuMDY1MiA5OC41ODc5IDcyLjEzOTggOTYuODg0NSA3OC4wNzQ4IDk3Ljg5NzhMMTA2LjE4NCAxMDIuNjk4TDExNi4zNjYgMTU0LjMzNkMxMTcuNzQ0IDE2MS4zMzQgMTIyLjczMyAxNjcuMDc2IDEyOS40NzMgMTY5LjQxN0wxNjEuMTU5IDE4MC40MzdMMTYxLjU1MiAxOTMuOTY3QzE2MS43MjkgMTk5Ljk4MiAxNTkuMTk1IDIwNS43NjEgMTU0LjY1NCAyMDkuNzA3TDEyNS41NDEgMjM1LjAwN0MxMjAuOTk3IDIzOC45NTIgMTE0LjkyMiAyNDAuNjU1IDEwOC45OTEgMjM5LjY0M0w0NC4xMTc1IDIyOC41NjdaIiBmaWxsPSIjRkI1QzU5Ii8+CjxwYXRoIGQ9Ik0yMDQuNjczIDE4NC44ODZDMTk5LjI0NCAxODkuNjAzIDE5MS43MDUgMTkxLjA1NSAxODQuOTEgMTg4LjY5NkwxNjEuMTU5IDE4MC40MzdMMTU5LjYzOCAxMjguMTgzQzE1OS4zNiAxMTguNjIyIDE1Mi4zNzkgMTEwLjU4NSAxNDIuOTQ4IDEwOC45NzRMMTA2LjE4NCAxMDIuNjk4TDEwNS4wMTMgOTYuNzUzM0MxMDMuNjIyIDg5LjY5NDIgMTA2LjExMiA4Mi40MzI2IDExMS41NDYgNzcuNzEzM0wxNTYuMDY0IDM5LjAyNzVDMTYxLjQ5MyAzNC4zMTA1IDE2OS4wMzIgMzIuODU3NyAxNzUuODI3IDM1LjIxNzZMMjMxLjI2NCA1NC40OTU3QzIzOC4wMDQgNTYuODM2OSAyNDIuOTkyIDYyLjU3OTMgMjQ0LjM3IDY5LjU3NzFMMjUyLjUzNSAxMTAuOTc4TDI0Ni40MzEgMTA2LjAwOEMyNDIuNjQzIDEwMi45MjQgMjM3LjE4OSAxMDMuMDE0IDIzMy41MDMgMTA2LjIxNUwyMDguOTM5IDEyNy41NjFDMjA1LjI1MyAxMzAuNzYyIDIwNC40MDggMTM2LjE1MiAyMDYuOTMyIDE0MC4zMjlMMjIwLjI5MyAxNjIuNDQ2QzIyMC44ODkgMTYzLjQzMiAyMjEuNjUzIDE2NC4zMSAyMjIuNTQ3IDE2NS4wMzlMMjI1LjEwOCAxNjcuMTI3TDIwNC42NzMgMTg0Ljg4NloiIGZpbGw9IiMxNjRERkYiLz4KPHBhdGggZD0iTTE2MS4xNTkgMTgwLjQzN0wxMjkuNDczIDE2OS40MTdDMTIyLjczMyAxNjcuMDc2IDExNy43NDQgMTYxLjMzNCAxMTYuMzY3IDE1NC4zMzZMMTA2LjE4NCAxMDIuNjk4TDE0Mi45NDggMTA4Ljk3NEMxNTIuMzc5IDExMC41ODQgMTU5LjM2IDExOC42MjIgMTU5LjYzOCAxMjguMTgzTDE2MS4xNTkgMTgwLjQzN1oiIGZpbGw9IiNGRURFREUiLz4KPHBhdGggZD0iTTI1NS41MDYgMTgxLjE0NkMyNTEuODIgMTg0LjM0OCAyNDYuMzYzIDE4NC40MzYgMjQyLjU3OCAxODEuMzUzTDIyNS4xMDggMTY3LjEyN0wyNDkuMTkxIDE0Ni4yQzI1NC42MjQgMTQxLjQ4IDI1Ny4xMTUgMTM0LjIxOSAyNTUuNzI0IDEyNy4xNkwyNTIuNTM1IDExMC45NzhMMjY2LjQ2MiAxMjIuMzIyQzI2Ny4zNTYgMTIzLjA1MSAyNjguMTIgMTIzLjkyOSAyNjguNzE2IDEyNC45MTZMMjgyLjA3NiAxNDcuMDMyQzI4NC42MDEgMTUxLjIwOSAyODMuNzUzIDE1Ni41OTggMjgwLjA2NyAxNTkuNzk5TDI1NS41MDYgMTgxLjE0NlYxODEuMTQ2WiIgZmlsbD0iIzAwRTVBRSIvPgo8cGF0aCBkPSJNMjI1LjEwOCAxNjcuMTI3TDIyMi41NDcgMTY1LjAzOUMyMjEuNjUzIDE2NC4zMSAyMjAuODg5IDE2My40MzIgMjIwLjI5MyAxNjIuNDQ1TDIwNi45MzIgMTQwLjMyOUMyMDQuNDA4IDEzNi4xNTIgMjA1LjI1MyAxMzAuNzYyIDIwOC45MzkgMTI3LjU2MUwyMzMuNTAzIDEwNi4yMTVDMjM3LjE4OSAxMDMuMDE0IDI0Mi42NDMgMTAyLjkyNCAyNDYuNDMxIDEwNi4wMDhMMjUyLjUzNSAxMTAuOTc4TDI1NS43MjQgMTI3LjE2QzI1Ny4xMTUgMTM0LjIxOSAyNTQuNjI0IDE0MS40OCAyNDkuMTkxIDE0Ni4yTDIyNS4xMDggMTY3LjEyN1YxNjcuMTI3WiIgZmlsbD0iI0ZGRjlGNSIvPgo8L3N2Zz4K"),
url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzEyIiBoZWlnaHQ9IjIyMyIgdmlld0JveD0iMCAwIDMxMiAyMjMiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGQ9Ik0yNzAuNDE1IDEwLjI3MTNDMjc0LjU0NCAxMS4zOSAyNzcuNzcxIDE0LjYxMzYgMjc4Ljg5IDE4Ljc0NjJMMjg4LjA5OCA1Mi43MjlDMjg5LjIzMSA1Ni44OTMgMjg4LjA0MSA2MS4zNDYgMjg0Ljk5IDY0LjM5OUwyNzMuOTUxIDc1LjQzN0wyNTYuMDQyIDUzLjU3MkMyNTEuNDcgNDcuOTg0OSAyNDQuNjI4IDQ0Ljc0NyAyMzcuNDA2IDQ0Ljc0ODdMMTk3LjY4OCA0NC43NDQ3TDE5Ni42MzUgNDAuODU2N0MxOTUuNTA2IDM2LjY4OTkgMTk2LjY5MiAzMi4yMzk2IDE5OS43NDMgMjkuMTg2NkwyMjQuNzYzIDQuMTcwNDFDMjI3LjgxNCAxLjExNzQxIDIzMi4yNjYgLTAuMDY3MjkxOSAyMzYuNDMgMS4wNjA5MUwyNzAuNDE1IDEwLjI3MTNaIiBmaWxsPSIjRkI1QzU5Ii8+CjxwYXRoIGQ9Ik0zMDYuMDg0IDExNC42NThDMzEzLjM1NSAxMjMuNTM1IDMxMy4zNTUgMTM2LjMxMiAzMDYuMDgyIDE0NS4xOUwyNTYuMDQ1IDIwNi4yNzRDMjUxLjQ3MSAyMTEuODYxIDI0NC42MjggMjE1LjEwMSAyMzcuNDA4IDIxNS4wOTdMMTkxLjEzMSAyMTUuMDk5QzE4My45MTMgMjE1LjA5OCAxNzcuMDcxIDIxMS44NjEgMTcyLjQ5NSAyMDYuMjc2TDE1NS41ODIgMTg1LjYyOUMxNTYuODc1IDE4My43NTUgMTU4LjA5MyAxODEuODIgMTU5LjIzNSAxNzkuODI0QzE3NC4yODkgMTUzLjU3NyAxNzQuMjg4IDEyMS4zMTggMTU5LjIzNSA5NS4wNzJDMTU2LjQ0IDkwLjE5OCAxNTMuMjA2IDg1LjY3MSAxNDkuNTk2IDgxLjUyNkwxNzIuNDkzIDUzLjU3M0MxNzcuMDY2IDQ3Ljk4NjcgMTgzLjkwNSA0NC43NDg3IDE5MS4xMjcgNDQuNzQ2OUwxOTcuNjg0IDQ0Ljc0NjZMMjA1LjgzOSA3NC44NDFDMjA2Ljk2MiA3OC45NzIgMjEwLjE4NiA4Mi4xOTcgMjE0LjMxNiA4My4zMkwyNDguMyA5Mi41MjdDMjUyLjQ2OSA5My42NTYgMjU2LjkxNiA5Mi40NyAyNTkuOTY5IDg5LjQyMUwyNzMuOTQ3IDc1LjQzOUwzMDYuMDggMTE0LjY2TDMwNi4wODQgMTE0LjY1OFoiIGZpbGw9IiMxNjRERkYiLz4KPHBhdGggZD0iTTI1Ni4wNDIgNTMuNTcyTDI3My45NTEgNzUuNDM3TDI1OS45NzIgODkuNDE5QzI1Ni45MTkgOTIuNDY4IDI1Mi40NzMgOTMuNjU1IDI0OC4zMDMgOTIuNTI1TDIxNC4zMiA4My4zMThDMjEwLjE4OSA4Mi4xOTYgMjA2Ljk2NiA3OC45NyAyMDUuODQzIDc0Ljg0TDE5Ny42ODggNDQuNzQ0OUwyMzcuNDA2IDQ0Ljc0OUMyNDQuNjI4IDQ0Ljc0NzIgMjUxLjQ3IDQ3Ljk4NTEgMjU2LjA0MiA1My41NzJaIiBmaWxsPSIjRkVERURFIi8+CjxwYXRoIGQ9Ik0xNTkuMjM2IDk1LjA2N0MxNzQuMjkyIDEyMS4zMTYgMTc0LjI5MyAxNTMuNTc1IDE1OS4yMzkgMTc5LjgyMkMxNTguMDk2IDE4MS44MTggMTU2Ljg3OCAxODMuNzUzIDE1NS41ODYgMTg1LjYyN0wxMjIuNDYxIDE0NS4xODZDMTE1LjE5IDEzNi4zMDkgMTE1LjE5IDEyMy41MzIgMTIyLjQ2MyAxMTQuNjUzTDE0OS42MDMgODEuNTIzQzE1My4yMTMgODUuNjY4IDE1Ni40NDcgOTAuMTk0IDE1OS4yNCA5NS4wNjVMMTU5LjIzNiA5NS4wNjdaIiBmaWxsPSIjQ0NGQUVGIi8+CjxwYXRoIGQ9Ik0xNDkuNTk5IDgxLjUyNUwxMjIuNDU5IDExNC42NTZDMTE1LjE4NiAxMjMuNTM0IDExNS4xODYgMTM2LjMxMSAxMjIuNDU3IDE0NS4xODhMMTU1LjU4MiAxODUuNjI5QzEzOS43ODkgMjA4LjY2MiAxMTMuNTY5IDIyMi42MjMgODUuMzU3IDIyMi42MjJMODUuMzUzIDIyMi42MjRDNTQuODM2NiAyMjIuNjIzIDI2LjY1MzIgMjA2LjI5NyAxMS40NjgyIDE3OS44MjRDMy45NDI0IDE2Ni43MDMgMC4xNzczMDIgMTUyLjA3NiAwLjE3OTkwMiAxMzcuNDQ1QzAuMTc4ODAyIDEyMi44MTYgMy45NDAyIDEwOC4xOTEgMTEuNDY5MiA5NS4wNjZDMTkuMDgxOCA4MS43OTQgMjkuOTYwMyA3MS4wNzIgNDIuNzY1NiA2My42NzlDNTUuNTcwOCA1Ni4yODYgNzAuMTM2IDUyLjI2OCA4NS4zNTMgNTIuMjdDMTEwLjI1NSA1Mi4yNjkgMTMzLjYwMyA2My4xMzYgMTQ5LjU5OSA4MS41MjVaIiBmaWxsPSIjMDBFNUFFIi8+Cjwvc3ZnPgo=");
Expand All @@ -53,13 +62,30 @@
}

.header {
position: sticky;
top: 0;
height: component-token("forge-layout", "header-height");

display: flex;
flex-wrap: nowrap;
align-items: center;
justify-content: space-between;
min-width: 0;

border-bottom: 2px solid transparent;
z-index: calc(#{design-token("z-index.nav")} + 1);
z-index: design-token("z-index.nav");
}

.headerBg {
position: absolute;
top: 0;
left: -100vw;
width: 300vw;
height: component-token("forge-layout", "header-height");

background-color: design-token("color.neutral.025");
border-bottom: component-token("forge-layout", "header-border-width") solid
component-token("forge-layout", "header-border-color");
}

.content {
Expand All @@ -68,33 +94,8 @@
}

.controls {
position: relative;
display: flex;
align-items: center;
gap: design-token("space.2");
}

.fauxContainer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;

display: flex;
flex-direction: column;
pointer-events: none;
}

.fauxHeader {
background-color: design-token("color.neutral.025");
border-bottom: component-token("forge-layout", "header-border-width") solid
component-token("forge-layout", "header-border-color");
z-index: design-token("z-index.nav");
}

.fauxHeader,
.header {
position: sticky;
top: 0;
height: component-token("forge-layout", "header-height");
}
2 changes: 1 addition & 1 deletion easy-ui-react/src/ForgeLayout/ForgeLayout.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ const Template = (args: Partial<ForgeLayoutProps>) => {
</ForgeLayout.Header>
<ForgeLayout.Content>
<Card background="primary" boxShadow="1" variant="solid">
<div style={{ height: 1000 }}>Page Content</div>
<div style={{ height: 4000 }}>Page Content</div>
</Card>
</ForgeLayout.Content>
</ForgeLayout.Body>
Expand Down
16 changes: 11 additions & 5 deletions easy-ui-react/src/ForgeLayout/ForgeLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,28 +168,34 @@ export function ForgeLayout(props: ForgeLayoutProps) {
} = props;
const className = classNames(
styles.ForgeLayout,
styles[variationName("backgroundDecoration", backgroundDecoration)],
styles[variationName("mode", mode)],
styles[variationName("navState", navState)],
);
const bgClassName = classNames(
styles.bg,
styles[variationName("backgroundDecoration", backgroundDecoration)],
);
const context = useMemo(() => {
return { mode, navState };
}, [mode, navState]);
return (
<ForgeLayoutContext.Provider value={context}>
<div className={bgClassName} />
<div className={className} data-testid="ForgeLayout">
{children}
<div className={styles.fauxContainer}>
<div className={styles.fauxHeader}></div>
</div>
</div>
</ForgeLayoutContext.Provider>
);
}

function ForgeLayoutHeader(props: ForgeLayoutHeaderProps) {
const { children } = props;
return <header className={styles.header}>{children}</header>;
return (
<header className={styles.header}>
<div className={styles.headerBg}></div>
{children}
</header>
);
}

function ForgeLayoutControls(props: ForgeLayoutControlsProps) {
Expand Down

0 comments on commit 2be5e1c

Please sign in to comment.