Skip to content

Commit

Permalink
[Frame] Add custom scrollbar styles for reframe (#11965)
Browse files Browse the repository at this point in the history
Edit: updated to use custom scrollbar styles instead of native ones

### WHY are these changes introduced?

Fixes Shopify/archive-polaris-backlog-2024#1379

### WHAT is this pull request doing?

https://admin.web.custom-scroll.sophie-schneider.us.spin.dev/store/shop1

|Change|Why?|
|-|-|
|Adds a `2px` margin to the right of the scrollbar|so it fits within the
rounded corner container|
|Use custom scrollbar|Match our other scrollbars in the admin, hide the
track so the right margin is less obvious. Using native scrollbars on
safari and `webkit` pseudo selector doesn't respect user's OS scroll
settings|
|Add lighter token for rest state of scrollbar|I cannot style the
scrollbar thumb hover state without the `webkit` pseudo selector so this
changes the scrollbar color depending on whether or not the user is
hovering over the full scroll container|

### Potential future improvements

1. Add a larger margin on firefox so the scrollbar isn't cut off there
2. Implement and "Overlay scrollbar" when "Always show scrollbars"
setting is on
3. Add border line for when "Always show scrollbars" setting is on to
always show the scroll track even when there isn't scrollable content

See demo below where there isn't a layout shift for the "Always show
scrollbars" setting on but it causes the content to look off centre
because of the gutter.

![Screen Recording 2024-05-03 at 3 51
37 PM](https://github.com/Shopify/polaris/assets/20652326/e9943bed-dcd6-460c-a8f0-dabbdcc6bb90)

### How to 🎩

https://admin.web.custom-scroll.sophie-schneider.us.spin.dev/store/shop1

Tophat with OS scroll settings set to "Always" and "When scrolling"
Check on chrome, firefox, safari, edge

<img width="713" alt="Screenshot 2024-05-06 at 12 03 45 PM"
src="https://github.com/Shopify/polaris/assets/20652326/ef9cfc0c-bd57-46d6-80d8-15795f1e84ab">


### 🎩 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)
  • Loading branch information
sophschneider authored May 6, 2024
1 parent 4f3bf99 commit 7a70238
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/sixty-pugs-wave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/polaris': patch
---

Added scrollbar styles for reframe
5 changes: 5 additions & 0 deletions .changeset/tricky-starfishes-fold.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/polaris-tokens': minor
---

Added `color-scrollbar-thumb-bg` token
46 changes: 44 additions & 2 deletions polaris-react/src/components/Frame/Frame.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
.Frame-TopBarAndReframe {
/* stylelint-disable -- Polaris component custom properties */
--pc-sidebar-width: calc(356px + var(--p-space-100));
--pc-scrollbar-spacer: 0;

/* stylelint-enable */
background-color: var(--p-color-bg-inverse);
transition: width var(--p-motion-duration-250) var(--p-motion-ease);
Expand All @@ -48,6 +50,13 @@
}
}

.ScrollbarAlwaysVisible {
/* Only apply spacing when scrollbar is set to always visible to create a gutter and prevent layout shifts */
/* stylelint-disable -- Polaris component custom properties */
--pc-scrollbar-spacer: var(--p-space-050);
/* stylelint-enable */
}

.Navigation {
position: fixed;
z-index: var(--p-z-index-8);
Expand Down Expand Up @@ -307,7 +316,8 @@
/* stylelint-disable -- polaris/conventions/polaris/custom-property-allowed-list -- Polaris component custom properties */
width: calc(
100vw - var(--pg-navigation-width) -
var(--pc-app-provider-scrollbar-width) - var(--pc-frame-offset, 0px)
var(--pc-app-provider-scrollbar-width) - var(--pc-frame-offset, 0px) -
var(--pc-scrollbar-spacer)
);
/* stylelint-enable -- polaris/conventions/polaris/custom-property-allowed-list */

Expand All @@ -326,7 +336,7 @@
width: calc(
100vw - var(--pg-navigation-width) -
var(--pc-app-provider-scrollbar-width) - var(--pc-sidebar-width) -
var(--pc-frame-offset, 0px)
var(--pc-frame-offset, 0px) - var(--pc-scrollbar-spacer)
);
margin-right: unset;
}
Expand Down Expand Up @@ -462,6 +472,38 @@

.Scrollable {
width: 100%;

/* Not using the spacer custom property so the space is applied always */
margin-right: var(--p-space-050);
/* stylelint-disable-next-line polaris/conventions/polaris/custom-property-allowed-list -- top bar global space */
height: calc(100% - var(--pg-top-bar-height));

scrollbar-width: thin;
scrollbar-color: var(--p-color-scrollbar-thumb-bg) transparent;
transition: scrollbar-color var(--p-motion-duration-100)
var(--p-motion-ease-in);

&:hover {
scrollbar-color: var(--p-color-scrollbar-thumb-bg-hover) transparent;
}
}

.Scrollable-ScrollbarAlwaysVisible {
/* Safari scrollbar styles until it adopts scrollbar-color, scrollbar-width */
&::-webkit-scrollbar {
/* Matches scrollbar-width: thin */
width: 11px;
background-color: var(--p-color-bg);
}

&::-webkit-scrollbar-thumb {
background-color: var(--p-color-scrollbar-thumb-bg);
border: var(--p-border-width-050) solid transparent;
border-radius: var(--p-border-radius-300);
background-clip: content-box;

&:hover {
background-color: var(--p-color-scrollbar-thumb-bg-hover);
}
}
}
21 changes: 20 additions & 1 deletion polaris-react/src/components/Frame/Frame.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ interface State {
loadingStack: number;
toastMessages: ToastPropsWithID[];
showContextualSaveBar: boolean;
scrollbarAlwaysVisible: boolean;
}

const APP_FRAME_MAIN = 'AppFrameMain';
Expand All @@ -88,6 +89,7 @@ class FrameInner extends PureComponent<CombinedProps, State> {
loadingStack: 0,
toastMessages: [],
showContextualSaveBar: false,
scrollbarAlwaysVisible: false,
};

private contextualSaveBar: ContextualSaveBarProps | null = null;
Expand All @@ -102,6 +104,7 @@ class FrameInner extends PureComponent<CombinedProps, State> {
this.setGlobalRibbonRootProperty();
this.setOffset();
this.setBodyStyles();
this.setScrollbarAlwaysVisible();
}

componentDidUpdate(prevProps: FrameProps) {
Expand Down Expand Up @@ -253,6 +256,7 @@ class FrameInner extends PureComponent<CombinedProps, State> {
topBar && styles.hasTopBar,
sidebar && styles.hasSidebar,
sidebar && hasDynamicTopBar && styles['hasSidebar-TopBarAndReframe'],
this.state.scrollbarAlwaysVisible && styles.ScrollbarAlwaysVisible,
);

const contextualSaveBarMarkup = this.props.dynamicTopBarAndReframe ? (
Expand Down Expand Up @@ -322,7 +326,11 @@ class FrameInner extends PureComponent<CombinedProps, State> {
<Scrollable
scrollbarWidth="thin"
horizontal={false}
className={styles.Scrollable}
className={classNames(
styles.Scrollable,
this.state.scrollbarAlwaysVisible &&
styles['Scrollable-ScrollbarAlwaysVisible'],
)}
id={APP_FRAME_SCROLLABLE}
>
<div
Expand Down Expand Up @@ -377,6 +385,17 @@ class FrameInner extends PureComponent<CombinedProps, State> {
setRootProperty('--pc-frame-offset', offset);
};

private setScrollbarAlwaysVisible = () => {
const scrollbarWidth = parseInt(
document.documentElement.style.getPropertyValue(
'--pc-app-provider-scrollbar-width',
),
10,
);

this.setState({scrollbarAlwaysVisible: scrollbarWidth > 0});
};

private setGlobalRibbonRootProperty = () => {
const {globalRibbonHeight} = this.state;
setRootProperty(
Expand Down
6 changes: 5 additions & 1 deletion polaris-tokens/src/themes/base/color.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ export type ColorBackgroundAlias =
| 'radio-button-bg-surface-disabled'
| 'video-thumbnail-play-button-bg-fill-hover'
| 'video-thumbnail-play-button-bg-fill'
| 'scrollbar-thumb-bg-hover';
| 'scrollbar-thumb-bg-hover'
| 'scrollbar-thumb-bg';

export type ColorBorderAlias =
| 'border-brand'
Expand Down Expand Up @@ -1223,4 +1224,7 @@ export const color: {
'color-scrollbar-thumb-bg-hover': {
value: colors.gray[12],
},
'color-scrollbar-thumb-bg': {
value: colors.gray[11],
},
};

0 comments on commit 7a70238

Please sign in to comment.