Skip to content

Commit

Permalink
Merge pull request #33 from WhiteMinds/feat/328_Scrollbar
Browse files Browse the repository at this point in the history
Replace the scrollbar when it has a width (e.g., on Windows PC's Chrome browser)
  • Loading branch information
WhiteMinds authored Dec 11, 2023
2 parents 276f7d7 + 2b71649 commit cd00694
Show file tree
Hide file tree
Showing 16 changed files with 165 additions and 79 deletions.
2 changes: 2 additions & 0 deletions packages/neuron/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
"next": "^13.4.4",
"next-i18next": "^13.2.2",
"observable-hooks": "^4.2.2",
"overlayscrollbars": "^2.4.5",
"overlayscrollbars-react": "^0.5.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-i18next": "^12.3.1",
Expand Down
7 changes: 1 addition & 6 deletions packages/neuron/src/components/Header/index.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,7 @@ $desktopHeaderContentHeight: 88px;
&Content {
// This approach may not be conducive to understanding and maintenance, but development is quite convenient for now.
// If maintenance becomes difficult later, it can be changed to control based on JS + CSS variables.
// `--scrollbarWidth` is provided by `_app.page.tsx`.
--menuIconRightOffset: calc(
max(calc((100vw - var(--contentAreaWidth) - var(--scrollbarWidth, 0px)) / 2), var(--contentWrapperPadding)) +
var(--scrollbarWidth, 0px)
);
--menuIconRightOffset: calc(max(calc((100vw - var(--contentAreaWidth)) / 2), var(--contentWrapperPadding)));

position: fixed;
top: 0;
Expand Down Expand Up @@ -144,7 +140,6 @@ $desktopHeaderContentHeight: 88px;

.content {
margin: 64px 0;
overflow: auto;
}

.close {
Expand Down
73 changes: 38 additions & 35 deletions packages/neuron/src/components/Header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Link from 'next/link'
import * as Dialog from '@radix-ui/react-dialog'
import { useRouter } from 'next/router'
import { useTranslation } from 'react-i18next'
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react'
import styles from './index.module.scss'
import IconLogo from './logo.svg'
import IconGithub from './github.svg'
Expand Down Expand Up @@ -98,43 +99,45 @@ const MenuDialog: FC = () => {
</Dialog.Close>
</div>

<div className={styles.content}>
<LinkWithEffect className={styles.title} href="/">
{t('Home')}
</LinkWithEffect>

<div className={styles.title}>{t('Services')}</div>
<div className={styles.links}>
<LinkWithEffect href="https://neuron.magickbase.com/">{t('Neuron Wallet')}</LinkWithEffect>
<span title="Coming soon">{t('CKB Explorer')}</span>
<span title="Coming soon">{t('Godwoke Explorer')}</span>
<span title="Coming soon">{t('Axon Explorer')}</span>
<span title="Coming soon">{t('Kuai')}</span>
</div>
<OverlayScrollbarsComponent options={{ scrollbars: { autoHide: 'never' } }}>
<div className={styles.content}>
<LinkWithEffect className={styles.title} href="/">
{t('Home')}
</LinkWithEffect>

<div className={styles.title}>{t('Services')}</div>
<div className={styles.links}>
<LinkWithEffect href="https://neuron.magickbase.com/">{t('Neuron Wallet')}</LinkWithEffect>
<span title="Coming soon">{t('CKB Explorer')}</span>
<span title="Coming soon">{t('Godwoke Explorer')}</span>
<span title="Coming soon">{t('Axon Explorer')}</span>
<span title="Coming soon">{t('Kuai')}</span>
</div>

<LinkWithEffect
className={styles.title}
href="https://github.com/nervosnetwork/ckb/wiki/Public-JSON-RPC-nodes"
>
{t('Public Node')}
</LinkWithEffect>

<div className={styles.title}>{t('Language')}</div>
<div className={clsx(styles.links, styles.languages)}>
{languages.map(language => (
<LinkWithEffect
key={language.name}
className={clsx(styles.languageItem, {
[styles.selected ?? '']: language.localeName === router.locale,
})}
href={{ pathname, query }}
locale={language.localeName}
>
{language.name}
</LinkWithEffect>
))}
<LinkWithEffect
className={styles.title}
href="https://github.com/nervosnetwork/ckb/wiki/Public-JSON-RPC-nodes"
>
{t('Public Node')}
</LinkWithEffect>

<div className={styles.title}>{t('Language')}</div>
<div className={clsx(styles.links, styles.languages)}>
{languages.map(language => (
<LinkWithEffect
key={language.name}
className={clsx(styles.languageItem, {
[styles.selected ?? '']: language.localeName === router.locale,
})}
href={{ pathname, query }}
locale={language.localeName}
>
{language.name}
</LinkWithEffect>
))}
</div>
</div>
</div>
</OverlayScrollbarsComponent>

<Contacts className={styles.contacts} />
</Dialog.Content>
Expand Down
7 changes: 4 additions & 3 deletions packages/neuron/src/hooks/useMarkdownProps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import remarkGfm from 'remark-gfm'
import rehypeRaw from 'rehype-raw'
import rehypeSanitize from 'rehype-sanitize'
import clsx from 'clsx'
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react'
import { TOCItem } from '../components/TableOfContents'
import { UpsideDownEffect } from '../components/UpsideDownEffect'

Expand Down Expand Up @@ -40,10 +41,10 @@ export function useMarkdownProps({
<img {...tagProps} alt={tagProps.alt ?? 'image'} className={clsx(tagProps.className, imgClass)} />
),
table: ({ node, ...tagProps }) => (
// The table is too wide, so we need to wrap it in a container with `overflow: auto`.
<div style={{ width: 'min-content', maxWidth: '100%', overflow: 'auto' }}>
// The table is too wide, so we need to wrap it in the OverlayScrollbarsComponent.
<OverlayScrollbarsComponent options={{ scrollbars: { autoHide: 'never' } }}>
<table {...tagProps} />
</div>
</OverlayScrollbarsComponent>
),
}),
[imgClass, supportToc],
Expand Down
22 changes: 21 additions & 1 deletion packages/neuron/src/pages/_app.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import { type AppType } from 'next/app'
import Head from 'next/head'
import { appWithTranslation, useTranslation } from 'next-i18next'
import localFont from 'next/font/local'
import { useOverlayScrollbars } from 'overlayscrollbars-react'
import { OverlayScrollbars } from 'overlayscrollbars'
import { api } from '../utils/api'
import 'overlayscrollbars/overlayscrollbars.css'
import '../styles/globals.scss'
import { TooltipProvider } from '../components/Tooltip'
import { useHighPrecisionScrollbarWidth } from '../hooks'
Expand All @@ -26,14 +29,31 @@ const App: AppType = ({ Component, pageProps }) => {
return () => document.body.classList.remove(fontProximaNova.className)
}, [])

const [initBodyOverlayScrollbars, getBodyOverlayScrollbarsInstance] = useOverlayScrollbars()

useEffect(() => {
const env = OverlayScrollbars.env()
env.setDefaultOptions({
...env.staticDefaultOptions,
scrollbars: {
...env.staticDefaultOptions.scrollbars,
autoHide: 'move',
},
// Only replace the scrollbar when it has a width (e.g., on Windows PC's Chrome browser).
showNativeOverlaidScrollbars: scrollbarWidth === 0,
})

initBodyOverlayScrollbars(document.body)
return () => getBodyOverlayScrollbarsInstance()?.destroy()
}, [getBodyOverlayScrollbarsInstance, initBodyOverlayScrollbars, scrollbarWidth])

return (
<TooltipProvider>
<Head>
{/* TODO: i18n not working, needs fixing. */}
<title>{t('Neuron Troubleshooting')}</title>
<link rel="icon" type="image/svg" href="/favicon.svg" />
<meta property="og:type" content="website" />
<style>{`:root { --scrollbarWidth: ${scrollbarWidth}px }`}</style>
</Head>
<main
// Here as redundancy in server-side rendering.
Expand Down
4 changes: 2 additions & 2 deletions packages/neuron/src/pages/_document.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { KEY_DARK_MODE } from '../services/AppSettings'
export default class CustomDocument<P> extends Document<P> {
render() {
return (
<Html lang="en">
<Html lang="en" data-overlayscrollbars-initialize>
<Head />
<body>
<body data-overlayscrollbars-initialize>
<Main />
<NextScript />
<Script
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,12 @@
}
}

.nodeCompatibleTableWrapper {
border-left: 1px solid #333;
}

.nodeCompatibleTable {
display: flex;
overflow-x: auto;
border-left: 1px solid #333;

.col {
display: flex;
Expand Down
30 changes: 18 additions & 12 deletions packages/neuron/src/pages/download/CompatibleTable/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ComponentProps, FC } from 'react'
import clsx from 'clsx'
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react'
import styles from './index.module.scss'
import { CompatibleData } from '../../../utils'
import { useIsMobile } from '../../../hooks'
Expand Down Expand Up @@ -95,17 +96,22 @@ const NodeCompatibleTable: FC<{
isCompatible: (neuronVersion: string, nodeVersion: string) => boolean
}> = ({ neuronVersions, nodeVersions, isCompatible }) => {
return (
<div className={styles.nodeCompatibleTable}>
{nodeVersions.map(nodeVer => (
<div key={nodeVer} className={styles.col}>
<div className={styles.cell}>{nodeVer}</div>
{neuronVersions.map(neuronVer => (
<div key={neuronVer} className={styles.cell}>
{isCompatible(neuronVer, nodeVer) ? <IconRight /> : <IconWrong />}
</div>
))}
</div>
))}
</div>
<OverlayScrollbarsComponent
className={styles.nodeCompatibleTableWrapper}
options={{ scrollbars: { autoHide: 'never' } }}
>
<div className={styles.nodeCompatibleTable}>
{nodeVersions.map(nodeVer => (
<div key={nodeVer} className={styles.col}>
<div className={styles.cell}>{nodeVer}</div>
{neuronVersions.map(neuronVer => (
<div key={neuronVer} className={styles.cell}>
{isCompatible(neuronVer, nodeVer) ? <IconRight /> : <IconWrong />}
</div>
))}
</div>
))}
</div>
</OverlayScrollbarsComponent>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
}

.accordionContent {
min-height: 0;

&[data-state='open'] {
animation: slideDown 300ms cubic-bezier(0.87, 0, 0.13, 1);
}
Expand Down
25 changes: 14 additions & 11 deletions packages/neuron/src/pages/posts/ClassifiedPosts/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { FC } from 'react'
import * as Accordion from '@radix-ui/react-accordion'
import clsx from 'clsx'
import { useTranslation } from 'react-i18next'
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react'
import { Post, TopLevelMenu, getPostURL } from '../../../utils'
import IconArrow from './arrow.svg'
import styles from './index.module.scss'
Expand Down Expand Up @@ -48,17 +49,19 @@ export const ClassifiedPosts: FC<
</Accordion.Header>

<Accordion.Content className={clsx(styles.accordionContent, postsClass)}>
{menu.posts?.map(post => (
<LinkWithEffect
key={post.key}
data-selected={post.key === viewingPost.key}
className={clsx(styles.post, postClass)}
href={getPostURL(post)}
fullWidth
>
{post.title}
</LinkWithEffect>
))}
<OverlayScrollbarsComponent style={{ maxHeight: '100%' }}>
{menu.posts?.map(post => (
<LinkWithEffect
key={post.key}
data-selected={post.key === viewingPost.key}
className={clsx(styles.post, postClass)}
href={getPostURL(post)}
fullWidth
>
{post.title}
</LinkWithEffect>
))}
</OverlayScrollbarsComponent>
</Accordion.Content>
</Accordion.Item>
))}
Expand Down
4 changes: 0 additions & 4 deletions packages/neuron/src/pages/posts/Sidebar/index.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,6 @@ $accordionTriggerHeight: 48px;
}

.posts {
&[data-state='open'] {
overflow: auto;
}

.post {
display: flex;
align-items: center;
Expand Down
11 changes: 9 additions & 2 deletions packages/neuron/src/pages/posts/[...slug].page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import clsx from 'clsx'
import { FC, useMemo } from 'react'
import { useObservableState } from 'observable-hooks'
import { useTranslation } from 'react-i18next'
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react'
import { TOCContextProvider, TOCItem } from '../../components/TableOfContents'
import {
Post,
Expand Down Expand Up @@ -87,13 +88,19 @@ export const PostPage$Desktop: FC<PageProps> = ({ post, menusWithPosts, menuWith
<div className={styles.item}>{post.title}</div>
</div>

<div ref={scrollContainerRef} className={clsx(CrawlableContentClassname, styles.postContent)}>
<OverlayScrollbarsComponent
ref={obj => {
const scrollContainer = obj?.osInstance()?.elements().viewport
scrollContainer && scrollContainerRef(scrollContainer)
}}
className={clsx(CrawlableContentClassname, styles.postContent)}
>
<TOCItem id={post.title} titleInTOC={post.title}>
<h1 className={styles.title}>{post.title}</h1>
</TOCItem>

<ReactMarkdown {...mdProps}>{post.body ?? ''}</ReactMarkdown>
</div>
</OverlayScrollbarsComponent>

<TOC className={styles.toc} />
</div>
Expand Down
1 change: 0 additions & 1 deletion packages/neuron/src/pages/posts/index.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@

.postContent {
padding: 0 24px 16px;
overflow: auto;

.img {
max-width: 100%;
Expand Down
23 changes: 23 additions & 0 deletions packages/neuron/src/styles/globals.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/* stylelint-disable custom-property-pattern */
/* stylelint-disable selector-class-pattern */
@import 'src/styles/presets.module';
@import 'src/styles/variables.module';

Expand Down Expand Up @@ -42,3 +44,24 @@ a {
.themeDark {
@include themeDark;
}

// Modify the default theme of overlayscrollbars.
// https://github.com/KingSora/OverlayScrollbars/blob/060cf1cd9c677482a3a04274cb237da894f0d4b8/README.md#css-custom-properties
.os-scrollbar {
// handle height = --os-size - padding - border = 6px
--os-size: 11px;
--os-handle-border: 0.5px solid rgb(153 153 153 / 50%);
--os-handle-border-radius: 32px;
--os-handle-bg: rgb(0 0 0 / 10%);
--os-handle-border-hover: var(--os-handle-border);
--os-handle-bg-hover: var(--os-handle-bg);
--os-handle-border-active: var(--os-handle-border);
--os-handle-bg-active: var(--os-handle-bg);

transition: opacity 0.2s;
}

.os-scrollbar-auto-hide.os-scrollbar-auto-hide-hidden {
// This is to ensure that the transition of os-scrollbar takes effect correctly.
visibility: unset;
}
8 changes: 8 additions & 0 deletions packages/neuron/src/typings/react.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
declare namespace React {
import { HTMLAttributes as ReactHTMLAttributes } from 'react'

export interface HTMLAttributes<T> extends ReactHTMLAttributes<T> {
// https://github.com/KingSora/OverlayScrollbars/blob/060cf1cd9c677482a3a04274cb237da894f0d4b8/README.md#bridging-initialization-flickering
'data-overlayscrollbars-initialize'?: boolean
}
}
Loading

2 comments on commit cd00694

@vercel
Copy link

@vercel vercel bot commented on cd00694 Dec 11, 2023

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

magickbase-website – ./packages/magickbase

magickbase-website-magickbase.vercel.app
magickbase.vercel.app
magickbase-website-git-master-magickbase.vercel.app

@vercel
Copy link

@vercel vercel bot commented on cd00694 Dec 11, 2023

Choose a reason for hiding this comment

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

Please sign in to comment.