Refactor sidebar (#6971)
* Refactor RightNav (cherry picked from commit 96bb02acfd2d7452df18a0e7410e6a7169a583ed) * Better gutter handling * Clean up styles * Memoize breakpoints * Format * Comment * Loosen spacing, handle overflow, smaller text to match prod * Fix circular imports on native * Return 0 instead of undefined for easier calculations * Re-assign * Fix * Port over fix from subs/base * Space out right nav feeds, widen sidebar to match prod * Fix lost padding on home header * Fix perf by not actually linking to new URL * Remove underline on focus * Foramt --------- Co-authored-by: Dan Abramov <dan.abramov@gmail.com>
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
import {useMemo} from 'react'
|
||||
import {useMediaQuery} from 'react-responsive'
|
||||
|
||||
export type Breakpoint = 'gtPhone' | 'gtMobile' | 'gtTablet'
|
||||
|
||||
export function useBreakpoints(): Record<Breakpoint, boolean> & {
|
||||
activeBreakpoint: Breakpoint | undefined
|
||||
} {
|
||||
const gtPhone = useMediaQuery({minWidth: 500})
|
||||
const gtMobile = useMediaQuery({minWidth: 800})
|
||||
const gtTablet = useMediaQuery({minWidth: 1300})
|
||||
return useMemo(() => {
|
||||
let active: Breakpoint | undefined
|
||||
if (gtTablet) {
|
||||
active = 'gtTablet'
|
||||
} else if (gtMobile) {
|
||||
active = 'gtMobile'
|
||||
} else if (gtPhone) {
|
||||
active = 'gtPhone'
|
||||
}
|
||||
return {
|
||||
activeBreakpoint: active,
|
||||
gtPhone,
|
||||
gtMobile,
|
||||
gtTablet,
|
||||
}
|
||||
}, [gtPhone, gtMobile, gtTablet])
|
||||
}
|
||||
+2
-13
@@ -1,5 +1,4 @@
|
||||
import React from 'react'
|
||||
import {useMediaQuery} from 'react-responsive'
|
||||
|
||||
import {
|
||||
computeFontScaleMultiplier,
|
||||
@@ -14,13 +13,14 @@ import {BLUE_HUE, GREEN_HUE, RED_HUE} from '#/alf/util/colorGeneration'
|
||||
import {Device} from '#/storage'
|
||||
|
||||
export {atoms} from '#/alf/atoms'
|
||||
export * from '#/alf/breakpoints'
|
||||
export * from '#/alf/fonts'
|
||||
export * as tokens from '#/alf/tokens'
|
||||
export * from '#/alf/types'
|
||||
export * from '#/alf/util/flatten'
|
||||
export * from '#/alf/util/platform'
|
||||
export * from '#/alf/util/themeSelector'
|
||||
export * from '#/alf/util/useGutterStyles'
|
||||
export * from '#/alf/util/useGutters'
|
||||
|
||||
export type Alf = {
|
||||
themeName: ThemeName
|
||||
@@ -142,14 +142,3 @@ export function useTheme(theme?: ThemeName) {
|
||||
return theme ? alf.themes[theme] : alf.theme
|
||||
}, [theme, alf])
|
||||
}
|
||||
|
||||
export function useBreakpoints() {
|
||||
const gtPhone = useMediaQuery({minWidth: 500})
|
||||
const gtMobile = useMediaQuery({minWidth: 800})
|
||||
const gtTablet = useMediaQuery({minWidth: 1300})
|
||||
return {
|
||||
gtPhone,
|
||||
gtMobile,
|
||||
gtTablet,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import React from 'react'
|
||||
|
||||
import {atoms as a, useBreakpoints, ViewStyleProp} from '#/alf'
|
||||
|
||||
export function useGutterStyles({
|
||||
top,
|
||||
bottom,
|
||||
}: {
|
||||
top?: boolean
|
||||
bottom?: boolean
|
||||
} = {}) {
|
||||
const {gtMobile} = useBreakpoints()
|
||||
return React.useMemo<ViewStyleProp['style']>(() => {
|
||||
return [
|
||||
a.px_lg,
|
||||
top && a.pt_md,
|
||||
bottom && a.pb_md,
|
||||
gtMobile && [a.px_xl, top && a.pt_lg, bottom && a.pb_lg],
|
||||
]
|
||||
}, [gtMobile, top, bottom])
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
import React from 'react'
|
||||
|
||||
import {Breakpoint, useBreakpoints} from '#/alf/breakpoints'
|
||||
import * as tokens from '#/alf/tokens'
|
||||
|
||||
type Gutter = 'compact' | 'base' | 'wide' | 0
|
||||
|
||||
const gutters: Record<
|
||||
Exclude<Gutter, 0>,
|
||||
Record<Breakpoint | 'default', number>
|
||||
> = {
|
||||
compact: {
|
||||
default: tokens.space.sm,
|
||||
gtPhone: tokens.space.sm,
|
||||
gtMobile: tokens.space.md,
|
||||
gtTablet: tokens.space.md,
|
||||
},
|
||||
base: {
|
||||
default: tokens.space.lg,
|
||||
gtPhone: tokens.space.lg,
|
||||
gtMobile: tokens.space.xl,
|
||||
gtTablet: tokens.space.xl,
|
||||
},
|
||||
wide: {
|
||||
default: tokens.space.xl,
|
||||
gtPhone: tokens.space.xl,
|
||||
gtMobile: tokens.space._3xl,
|
||||
gtTablet: tokens.space._3xl,
|
||||
},
|
||||
}
|
||||
|
||||
type Gutters = {
|
||||
paddingTop: number
|
||||
paddingRight: number
|
||||
paddingBottom: number
|
||||
paddingLeft: number
|
||||
}
|
||||
|
||||
export function useGutters([all]: [Gutter]): Gutters
|
||||
export function useGutters([vertical, horizontal]: [Gutter, Gutter]): Gutters
|
||||
export function useGutters([top, right, bottom, left]: [
|
||||
Gutter,
|
||||
Gutter,
|
||||
Gutter,
|
||||
Gutter,
|
||||
]): Gutters
|
||||
export function useGutters([top, right, bottom, left]: Gutter[]) {
|
||||
const {activeBreakpoint} = useBreakpoints()
|
||||
if (right === undefined) {
|
||||
right = bottom = left = top
|
||||
} else if (bottom === undefined) {
|
||||
bottom = top
|
||||
left = right
|
||||
}
|
||||
return React.useMemo(() => {
|
||||
return {
|
||||
paddingTop: top === 0 ? 0 : gutters[top][activeBreakpoint || 'default'],
|
||||
paddingRight:
|
||||
right === 0 ? 0 : gutters[right][activeBreakpoint || 'default'],
|
||||
paddingBottom:
|
||||
bottom === 0 ? 0 : gutters[bottom][activeBreakpoint || 'default'],
|
||||
paddingLeft:
|
||||
left === 0 ? 0 : gutters[left][activeBreakpoint || 'default'],
|
||||
}
|
||||
}, [activeBreakpoint, top, right, bottom, left])
|
||||
}
|
||||
Reference in New Issue
Block a user