Skip to content

Commit

Permalink
Create rounded corner frame content (#11846)
Browse files Browse the repository at this point in the history
### WHY are these changes introduced?

Part of https://github.com/Shopify/polaris-internal/issues/1470

### WHAT is this pull request doing?
Round corners of the admin frame content (nav and main content) behind a
beta flag. To achieve this:

* Change background color to `var(--p-color-bg-inverse)`
* Wrap content and nav in the frame in a border radius shadow bevel
container
* Move scroll bar from full frame (including top bar) to just content +
nav container
* Wrap all new changes in a feature flag

|Before|After|
|-|-|
|<img width="1283" alt="Screenshot 2024-04-08 at 9 29 12 PM"
src="https://github.com/Shopify/polaris/assets/20652326/e4679480-c593-4886-9718-cc3cd85b2310">|<img
width="1282" alt="Screenshot 2024-04-08 at 9 29 01 PM"
src="https://github.com/Shopify/polaris/assets/20652326/752e6da2-73a2-4a45-8c6c-5051e779259f">|

### How to 🎩

Toggle `dynamicTopBarAndReframe` feature flag on details story
Make sure feature flag off doesn't affect admin
([spin](https://admin.web.web-bua6.sophie-schneider.us.spin.dev/store/shop1))

### 🎩 checklist

- [x] Tested a
[snapshot](https://github.com/Shopify/polaris/blob/main/documentation/Releasing.md#-snapshot-releases)
- [x] Tested on
[mobile](https://github.com/Shopify/polaris/blob/main/documentation/Tophatting.md#cross-browser-testing)
- [x] Tested on [multiple
browsers](https://help.shopify.com/en/manual/shopify-admin/supported-browsers)
- [x] Tested for
[accessibility](https://github.com/Shopify/polaris/blob/main/documentation/Accessibility%20testing.md)
- [ ] Updated the component's `README.md` with documentation changes
- [ ] [Tophatted
documentation](https://github.com/Shopify/polaris/blob/main/documentation/Tophatting%20documentation.md)
changes in the style guide
  • Loading branch information
sophschneider committed Apr 10, 2024
1 parent b5427bd commit ce6353b
Show file tree
Hide file tree
Showing 7 changed files with 171 additions and 32 deletions.
5 changes: 5 additions & 0 deletions .changeset/clean-turtles-grab.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/polaris': patch
---

Restyled Frame content behind dynamicTopBarAndReframe feature flag
16 changes: 15 additions & 1 deletion polaris-react/src/components/AppProvider/AppProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ export class AppProvider extends Component<AppProviderProps, State> {
const {i18n, linkComponent} = this.props;

this.setRootAttributes();
/* Temporary for dynamicTopBarAndReframe feature. Remove when feature flag is removed. */
this.setBodyStyles();

if (i18n === prevI18n && linkComponent === prevLinkComponent) {
return;
Expand All @@ -150,8 +152,20 @@ export class AppProvider extends Component<AppProviderProps, State> {
}

setBodyStyles = () => {
const {features} = this.props;

document.body.style.backgroundColor = 'var(--p-color-bg)';
document.body.style.color = 'var(--p-color-text)';

/* Temporary for dynamicTopBarAndReframe feature.
* Remove when feature flag is removed and apply
* styles directly to body in the global stylesheet.
*/
if (features?.dynamicTopBarAndReframe) {
document.body.style.overflow = 'hidden';
} else {
document.body.style.overflow = '';
}
};

setRootAttributes = () => {
Expand All @@ -168,7 +182,7 @@ export class AppProvider extends Component<AppProviderProps, State> {
getThemeName = (): ThemeName => this.props.theme ?? themeNameDefault;

render() {
const {children, features} = this.props;
const {children, features = {}} = this.props;
const themeName = this.getThemeName();

const {intl, link} = this.state;
Expand Down
65 changes: 65 additions & 0 deletions polaris-react/src/components/Frame/Frame.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,25 @@
}
}

.hasSidebar-TopBarAndReframe {
transition: width var(--p-motion-duration-250) var(--p-motion-ease);

/* Sidebar breakpoint is 1200px */
/* stylelint-disable-next-line polaris/media-queries/polaris/media-query-allowed-list -- custom breakpoint */
@media screen and (min-width: 1200px) {
/* stylelint-disable-next-line polaris/conventions/polaris/custom-property-allowed-list -- private token from component */
width: calc(100% - var(--pc-sidebar-width));
}
}

.Frame-TopBarAndReframe {
/* stylelint-disable -- Polaris component custom properties */
--pc-sidebar-width: calc(356px + var(--p-space-100));
/* stylelint-enable */
background-color: var(--p-color-bg-inverse);
transition: width var(--p-motion-duration-250) var(--p-motion-ease);
}

.Navigation {
position: fixed;
z-index: var(--p-z-index-8);
Expand Down Expand Up @@ -219,6 +238,24 @@
}
}

.Main-TopBarAndReframe {
border-inline-end: none;
background-color: var(--p-color-bg);
border-top-left-radius: var(--p-border-radius-300);
border-top-right-radius: var(--p-border-radius-300);
height: 100vh;
overflow: hidden;

.hasTopBar & {
/* stylelint-disable-next-line -- polaris custom global property */
margin-top: var(--pg-top-bar-height);
padding-top: 0;
@media print {
margin-top: 0;
}
}
}

.Content {
position: relative;
/* stylelint-disable-next-line -- generated by polaris-migrator DO NOT COPY */
Expand All @@ -237,6 +274,21 @@
}
}

.Content-TopBarAndReframe {
overflow-y: scroll;
/* stylelint-disable-next-line polaris/conventions/polaris/custom-property-allowed-list -- top bar global space */
margin-bottom: var(--pg-top-bar-height);
margin-right: var(--p-space-050);

.hasSidebar & {
/* Sidebar breakpoint is 1200px */
/* stylelint-disable-next-line polaris/media-queries/polaris/media-query-allowed-list -- custom breakpoint */
@media screen and (min-width: 1200px) {
margin-right: unset;
}
}
}

.GlobalRibbonContainer {
position: fixed;
z-index: var(--p-z-index-3);
Expand Down Expand Up @@ -321,3 +373,16 @@
}
}
}

.ShadowBevel {
width: 100%;

@mixin shadow-bevel var(--p-shadow-100), var(--p-border-radius-300),
var(--p-z-index-1);

&::before {
/* stylelint-disable-next-line polaris/conventions/polaris/custom-property-allowed-list -- top bar global space */
top: var(--pg-top-bar-height);
background-color: var(--p-color-bg);
}
}
91 changes: 63 additions & 28 deletions polaris-react/src/components/Frame/Frame.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import type {
ToastPropsWithID,
} from '../../utilities/frame';
import {UseTheme} from '../../utilities/use-theme';
import {UseFeatures} from '../../utilities/features';
import type {FeaturesConfig} from '../../utilities/features';

import {
ToastManager,
Expand Down Expand Up @@ -238,12 +240,17 @@ class FrameInner extends PureComponent<CombinedProps, State> {
}
: {};

const frameClassName = classNames(
styles.Frame,
navigation && styles.hasNav,
topBar && styles.hasTopBar,
sidebar && styles.hasSidebar,
);
const getFrameClassName = (features: FeaturesConfig) =>
classNames(
styles.Frame,
features?.dynamicTopBarAndReframe && styles['Frame-TopBarAndReframe'],
navigation && styles.hasNav,
topBar && styles.hasTopBar,
sidebar && styles.hasSidebar,
sidebar &&
features?.dynamicTopBarAndReframe &&
styles['hasSidebar-TopBarAndReframe'],
);

const contextualSaveBarMarkup = (
<CSSAnimation
Expand Down Expand Up @@ -279,28 +286,56 @@ class FrameInner extends PureComponent<CombinedProps, State> {

return (
<FrameContext.Provider value={context}>
<div
className={frameClassName}
{...layer.props}
{...navigationAttributes}
>
{skipMarkup}
{topBarMarkup}
{navigationMarkup}
{contextualSaveBarMarkup}
{loadingMarkup}
{navigationOverlayMarkup}
<main
className={styles.Main}
id={APP_FRAME_MAIN}
data-has-global-ribbon={Boolean(globalRibbon)}
>
<div className={styles.Content}>{children}</div>
</main>
<ToastManager toastMessages={toastMessages} />
{globalRibbonMarkup}
<EventListener event="resize" handler={this.handleResize} />
</div>
<UseFeatures>
{(features) => (
<div
className={getFrameClassName(features)}
{...layer.props}
{...navigationAttributes}
>
{skipMarkup}
{topBarMarkup}
{features?.dynamicTopBarAndReframe ? null : navigationMarkup}
{contextualSaveBarMarkup}
{loadingMarkup}
{navigationOverlayMarkup}
{features?.dynamicTopBarAndReframe ? (
<div className={styles.ShadowBevel}>
{navigationMarkup}
<main
className={classNames(
styles.Main,
styles['Main-TopBarAndReframe'],
)}
id={APP_FRAME_MAIN}
data-has-global-ribbon={Boolean(globalRibbon)}
>
<div
className={classNames(
styles.Content,
features?.dynamicTopBarAndReframe &&
styles['Content-TopBarAndReframe'],
)}
>
{children}
</div>
</main>
</div>
) : (
<main
className={styles.Main}
id={APP_FRAME_MAIN}
data-has-global-ribbon={Boolean(globalRibbon)}
>
<div className={styles.Content}>{children}</div>
</main>
)}
<ToastManager toastMessages={toastMessages} />
{globalRibbonMarkup}
<EventListener event="resize" handler={this.handleResize} />
</div>
)}
</UseFeatures>
</FrameContext.Provider>
);
}
Expand Down
4 changes: 4 additions & 0 deletions polaris-react/src/components/Navigation/Navigation.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@
}
}

.NavigationFrame-TopBarAndReframe {
border-top-left-radius: var(--p-border-radius-300);
}

.PrimaryNavigation {
display: flex;
overflow: auto;
Expand Down
20 changes: 18 additions & 2 deletions polaris-react/src/components/Navigation/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {UnstyledLink} from '../UnstyledLink';
import {classNames} from '../../utilities/css';
import {getWidth} from '../../utilities/get-width';
import {useFrame} from '../../utilities/frame';
import {useFeatures} from '../../utilities/features';

import {NavigationContext} from './context';
import {Section, Item} from './components';
Expand Down Expand Up @@ -71,12 +72,27 @@ export const Navigation: React.FunctionComponent<NavigationProps> & {
[location, onDismiss],
);

const features = useFeatures();

return (
<NavigationContext.Provider value={context}>
<WithinContentContext.Provider value>
<nav className={styles.Navigation} aria-labelledby={ariaLabelledBy}>
<nav
className={classNames(
styles.Navigation,
features?.dynamicTopBarAndReframe &&
styles['NavigationFrame-TopBarAndReframe'],
)}
aria-labelledby={ariaLabelledBy}
>
{mediaMarkup}
<Scrollable className={styles.PrimaryNavigation}>
<Scrollable
className={classNames(
styles.PrimaryNavigation,
features?.dynamicTopBarAndReframe &&
styles['NavigationFrame-TopBarAndReframe'],
)}
>
{children}
</Scrollable>
</nav>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export function PolarisTestProvider({
i18n,
link,
mediaQuery,
features,
features = {},
frame,
theme: themeName = themeNameDefault,
}: PolarisTestProviderProps) {
Expand Down

0 comments on commit ce6353b

Please sign in to comment.