Skip to content

Commit

Permalink
fastr
Browse files Browse the repository at this point in the history
  • Loading branch information
stipsan committed Nov 22, 2024
1 parent cc38cd5 commit a891e97
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 142 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Box, Flex, rem, Skeleton, Stack, Text, TextSkeleton} from '@sanity/ui'
import classNames from 'classnames'
import {memo, useMemo} from 'react'
import {useMemo} from 'react'
import {styled} from 'styled-components'
import {getDevicePixelRatio} from 'use-device-pixel-ratio'

Expand Down Expand Up @@ -53,7 +53,7 @@ const SKELETON_DELAY = 300
/**
* @hidden
* @beta */
export const DefaultPreview = memo(function DefaultPreview(props: DefaultPreviewProps) {
export function DefaultPreview(props: DefaultPreviewProps) {
const {title, subtitle, media, status, isPlaceholder, children, styles} = props
const {t} = useTranslation()
const rootClassName = classNames(styles?.root, Boolean(subtitle) && styles?.hasSubtitle)
Expand Down Expand Up @@ -163,4 +163,4 @@ export const DefaultPreview = memo(function DefaultPreview(props: DefaultPreview
</Flex>
</Root>
)
})
}
276 changes: 140 additions & 136 deletions packages/sanity/src/core/presence/overlay/RegionsWithIntersections.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/* eslint-disable react/no-unused-prop-types */
import {
type ForwardedRef,
forwardRef,
memo,
type ReactNode,
useCallback,
useMemo,
Expand Down Expand Up @@ -42,140 +44,142 @@ interface RegionsWithIntersectionsProps {
const toPx = (num: number) => `${num}px`
const negate = (num: number) => 0 - num

export const RegionsWithIntersections = forwardRef(function RegionsWithIntersections(
props: RegionsWithIntersectionsProps,
ref: ForwardedRef<HTMLDivElement>,
) {
const {
regions,
render,
children,
margins: [mt, mr, mb, ml],
} = props

const overlayRef = useRef<HTMLDivElement | null>(null)

// Make sure `margins` is memoized
const margins = useMemo<[number, number, number, number]>(
() => [mt, mr, mb, ml],
[mt, mr, mb, ml],
)

const io = useMemo(
() =>
createIntersectionObserver({
rootMargin: margins.map(negate).map(toPx).join(' '),
threshold: INTERSECTION_THRESHOLDS,
}),
[margins],
)

const [intersections, setIntersections] = useState<
Record<
string,
| {
boundingClientRect: {top: number; bottom: number}
isIntersecting: boolean
intersectionRect: {top: number; bottom: number}
}
| undefined
>
>({})

const onIntersection = useCallback((id: any, entry: any) => {
setIntersections((current) => ({...current, [id]: entry}))
}, [])

const top = intersections['::top']
const bottom = intersections['::bottom']
const regionsWithIntersectionDetails: RegionWithIntersectionDetails[] = useMemo(
() =>
(top && bottom
? regions
.filter((region) => region.presence?.length > 0)
.map((region): RegionWithIntersectionDetails | null => {
const intersection = intersections[region.id]

if (!intersection) {
return null
}

const {bottom: boundsBottom, top: boundsTop} = intersection.boundingClientRect

const aboveTop = intersection.boundingClientRect.top < top.boundingClientRect.bottom
const belowBottom =
intersection.boundingClientRect.top < bottom.boundingClientRect.top

// eslint-disable-next-line no-nested-ternary
const distanceTop = intersection.isIntersecting
? boundsTop - (intersection.intersectionRect.top - INTERSECTION_ELEMENT_PADDING)
: aboveTop
? -top.boundingClientRect.bottom
: bottom.boundingClientRect.top

// eslint-disable-next-line no-nested-ternary
const distanceBottom = intersection.isIntersecting
? -(
boundsBottom -
(intersection.intersectionRect.bottom + INTERSECTION_ELEMENT_PADDING)
)
: belowBottom
? bottom.boundingClientRect.top
: -top.boundingClientRect.bottom

const position =
export const RegionsWithIntersections = memo(
forwardRef(function RegionsWithIntersections(
props: RegionsWithIntersectionsProps,
ref: ForwardedRef<HTMLDivElement>,
) {
const {
regions,
render,
children,
margins: [mt, mr, mb, ml],
} = props

const overlayRef = useRef<HTMLDivElement | null>(null)

// Make sure `margins` is memoized
const margins = useMemo<[number, number, number, number]>(
() => [mt, mr, mb, ml],
[mt, mr, mb, ml],
)

const io = useMemo(
() =>
createIntersectionObserver({
rootMargin: margins.map(negate).map(toPx).join(' '),
threshold: INTERSECTION_THRESHOLDS,
}),
[margins],
)

const [intersections, setIntersections] = useState<
Record<
string,
| {
boundingClientRect: {top: number; bottom: number}
isIntersecting: boolean
intersectionRect: {top: number; bottom: number}
}
| undefined
>
>({})

const onIntersection = useCallback((id: any, entry: any) => {
setIntersections((current) => ({...current, [id]: entry}))
}, [])

const top = intersections['::top']
const bottom = intersections['::bottom']
const regionsWithIntersectionDetails = useMemo(
() =>
(top && bottom
? regions
.filter((region) => region.presence?.length > 0)
.map((region): RegionWithIntersectionDetails | null => {
const intersection = intersections[region.id]

if (!intersection) {
return null
}

const {bottom: boundsBottom, top: boundsTop} = intersection.boundingClientRect

const aboveTop = intersection.boundingClientRect.top < top.boundingClientRect.bottom
const belowBottom =
intersection.boundingClientRect.top < bottom.boundingClientRect.top

// eslint-disable-next-line no-nested-ternary
const distanceTop = intersection.isIntersecting
? boundsTop - (intersection.intersectionRect.top - INTERSECTION_ELEMENT_PADDING)
: aboveTop
? -top.boundingClientRect.bottom
: bottom.boundingClientRect.top

// eslint-disable-next-line no-nested-ternary
distanceTop <= SNAP_TO_DOCK_DISTANCE_TOP
? 'top'
: distanceBottom <= SNAP_TO_DOCK_DISTANCE_BOTTOM
? 'bottom'
: 'inside'

return {
distanceTop,
distanceBottom,
region,
position,
}
})
.filter(Boolean)
: []) as RegionWithIntersectionDetails[],
[bottom, intersections, regions, top],
)

return (
<RootWrapper ref={ref}>
<TopRegionWrapper
$debug={DEBUG}
io={io}
id="::top"
onIntersection={onIntersection}
margins={margins}
/>
<div>{children}</div>
<OverlayWrapper ref={overlayRef}>
{overlayRef.current &&
render(regionsWithIntersectionDetails, overlayRef.current.offsetWidth)}
</OverlayWrapper>
{regions.map((region) => {
const forceWidth = region.rect.width === 0
return (
<MiddleRegionWrapper
$debug={DEBUG}
io={io}
onIntersection={onIntersection}
key={region.id}
id={region.id}
style={{
width: forceWidth ? 1 : region.rect.width,
left: region.rect.left - (forceWidth ? 1 : 0),
top: region.rect.top - INTERSECTION_ELEMENT_PADDING,
height: region.rect.height + INTERSECTION_ELEMENT_PADDING * 2,
}}
/>
)
})}
<BottomRegionWrapper $debug={DEBUG} id="::bottom" io={io} onIntersection={onIntersection} />
</RootWrapper>
)
})
const distanceBottom = intersection.isIntersecting
? -(
boundsBottom -
(intersection.intersectionRect.bottom + INTERSECTION_ELEMENT_PADDING)
)
: belowBottom
? bottom.boundingClientRect.top
: -top.boundingClientRect.bottom

const position =
// eslint-disable-next-line no-nested-ternary
distanceTop <= SNAP_TO_DOCK_DISTANCE_TOP
? 'top'
: distanceBottom <= SNAP_TO_DOCK_DISTANCE_BOTTOM
? 'bottom'
: 'inside'

return {
distanceTop,
distanceBottom,
region,
position,
}
})
.filter(Boolean)
: []) as RegionWithIntersectionDetails[],
[bottom, intersections, regions, top],
)

return (
<RootWrapper ref={ref}>
<TopRegionWrapper
$debug={DEBUG}
io={io}
id="::top"
onIntersection={onIntersection}
margins={margins}
/>
<div>{children}</div>
<OverlayWrapper ref={overlayRef}>
{overlayRef.current &&
render(regionsWithIntersectionDetails, overlayRef.current.offsetWidth)}
</OverlayWrapper>
{regions.map((region) => {
const forceWidth = region.rect.width === 0
return (
<MiddleRegionWrapper
$debug={DEBUG}
io={io}
onIntersection={onIntersection}
key={region.id}
id={region.id}
style={{
width: forceWidth ? 1 : region.rect.width,
left: region.rect.left - (forceWidth ? 1 : 0),
top: region.rect.top - INTERSECTION_ELEMENT_PADDING,
height: region.rect.height + INTERSECTION_ELEMENT_PADDING * 2,
}}
/>
)
})}
<BottomRegionWrapper $debug={DEBUG} id="::bottom" io={io} onIntersection={onIntersection} />
</RootWrapper>
)
}),
)
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable max-nested-callbacks */
import {Flex} from '@sanity/ui'
import {startCase} from 'lodash'
import {forwardRef, type Ref, useMemo, useState} from 'react'
import {forwardRef, memo, type Ref, useMemo, useState} from 'react'

import {Button} from '../../../../../ui-components'
import {useRovingFocus} from '../../../../components'
Expand All @@ -14,7 +15,7 @@ interface ToolCollapseMenuProps {
tools: Tool[]
}

export function ToolCollapseMenu(props: ToolCollapseMenuProps) {
export const ToolCollapseMenu = memo(function ToolCollapseMenu(props: ToolCollapseMenuProps) {
const {activeToolName, tools} = props
const scheme = useColorSchemeValue()
const [collapseMenuEl, setCollapseMenuEl] = useState<HTMLDivElement | null>(null)
Expand Down Expand Up @@ -77,4 +78,4 @@ export function ToolCollapseMenu(props: ToolCollapseMenuProps) {
</CollapseTabList>
</Flex>
)
}
})

0 comments on commit a891e97

Please sign in to comment.