fix(mobile): super editor autocomplete dropdowns (#2019)

This commit is contained in:
Aman Harwara
2022-11-17 02:44:16 +05:30
committed by GitHub
parent bb64320f80
commit d21f3ba6f3
8 changed files with 44 additions and 13 deletions

View File

@@ -21,6 +21,7 @@ import { GetDynamicTableBlocks, GetTableBlock } from './Blocks/Table'
import Popover from '@/Components/Popover/Popover'
import { PopoverClassNames } from '../ClassNames'
import { GetDatetimeBlocks } from './Blocks/DateTime'
import { isMobileScreen } from '@/Utils'
export default function BlockPickerMenuPlugin(): JSX.Element {
const [editor] = useLexicalComposerContext()
@@ -109,12 +110,14 @@ export default function BlockPickerMenuPlugin(): JSX.Element {
align="start"
anchorPoint={{
x: anchorElementRef.current.offsetLeft,
y: anchorElementRef.current.offsetTop + anchorElementRef.current.offsetHeight,
y: anchorElementRef.current.offsetTop + (!isMobileScreen() ? anchorElementRef.current.offsetHeight : 0),
}}
open={popoverOpen}
togglePopover={() => {
setPopoverOpen((prevValue) => !prevValue)
}}
disableMobileFullscreenTakeover={true}
side={isMobileScreen() ? 'top' : 'bottom'}
>
<div className={PopoverClassNames}>
<ul>

View File

@@ -11,6 +11,7 @@ import Popover from '@/Components/Popover/Popover'
import { INSERT_BUBBLE_COMMAND, INSERT_FILE_COMMAND } from '../Commands'
import { useLinkingController } from '../../../../../Controllers/LinkingControllerProvider'
import { PopoverClassNames } from '../ClassNames'
import { isMobileScreen } from '@/Utils'
type Props = {
currentNote: SNNote
@@ -106,12 +107,14 @@ export const ItemSelectionPlugin: FunctionComponent<Props> = ({ currentNote }) =
align="start"
anchorPoint={{
x: anchorElementRef.current.offsetLeft,
y: anchorElementRef.current.offsetTop + anchorElementRef.current.offsetHeight,
y: anchorElementRef.current.offsetTop + (!isMobileScreen() ? anchorElementRef.current.offsetHeight : 0),
}}
open={popoverOpen}
togglePopover={() => {
setPopoverOpen((prevValue) => !prevValue)
}}
disableMobileFullscreenTakeover={true}
side={isMobileScreen() ? 'top' : 'bottom'}
>
<div className={PopoverClassNames}>
<ul>

View File

@@ -102,7 +102,7 @@ export const SuperEditor: FunctionComponent<Props> = ({
<BlocksEditor
onChange={handleChange}
ignoreFirstChange={true}
className="relative relative h-full resize-none text-base focus:shadow-none focus:outline-none"
className="relative h-full resize-none text-base focus:shadow-none focus:outline-none"
previewLength={NotePreviewCharLimit}
spellcheck={spellcheck}
>

View File

@@ -4,10 +4,15 @@ import { PopoverAlignment, PopoverSide } from './Types'
import { OppositeSide, checkCollisions, getNonCollidingSide, getNonCollidingAlignment } from './Utils/Collisions'
import { getPositionedPopoverRect } from './Utils/Rect'
const getStylesFromRect = (rect: DOMRect): CSSProperties => {
const getStylesFromRect = (rect: DOMRect, disableMobileFullscreenTakeover?: boolean): CSSProperties => {
return {
willChange: 'transform',
transform: `translate(${rect.x}px, ${rect.y}px)`,
...(disableMobileFullscreenTakeover
? {
maxWidth: `${window.innerWidth - rect.x * 2}px`,
}
: {}),
}
}
@@ -17,6 +22,7 @@ type Options = {
documentRect: DOMRect
popoverRect?: DOMRect
side: PopoverSide
disableMobileFullscreenTakeover?: boolean
}
export const getPositionedPopoverStyles = ({
@@ -25,6 +31,7 @@ export const getPositionedPopoverStyles = ({
documentRect,
popoverRect,
side,
disableMobileFullscreenTakeover,
}: Options): [CSSProperties | null, PopoverSide, PopoverAlignment] => {
if (!popoverRect || !anchorRect) {
return [null, side, align]
@@ -32,7 +39,7 @@ export const getPositionedPopoverStyles = ({
const matchesMediumBreakpoint = matchMedia(MediaQueryBreakpoints.md).matches
if (!matchesMediumBreakpoint) {
if (!matchesMediumBreakpoint && !disableMobileFullscreenTakeover) {
return [null, side, align]
}
@@ -51,5 +58,5 @@ export const getPositionedPopoverStyles = ({
})
const finalPositionedRect = getPositionedPopoverRect(popoverRect, anchorRect, finalSide, finalAlignment)
return [getStylesFromRect(finalPositionedRect), finalSide, finalAlignment]
return [getStylesFromRect(finalPositionedRect, disableMobileFullscreenTakeover), finalSide, finalAlignment]
}

View File

@@ -27,7 +27,6 @@ const useRegisterPopoverToParent = (popoverId: string) => {
type Props = PopoverProps & {
open: boolean
disableClickOutside?: boolean
}
const Popover = ({
@@ -41,6 +40,7 @@ const Popover = ({
side,
togglePopover,
disableClickOutside,
disableMobileFullscreenTakeover,
}: Props) => {
const popoverId = useRef(UuidGenerator.GenerateUuid())
@@ -99,6 +99,7 @@ const Popover = ({
side={side}
togglePopover={togglePopover}
disableClickOutside={disableClickOutside}
disableMobileFullscreenTakeover={disableMobileFullscreenTakeover}
>
{children}
</PositionedPopoverContent>

View File

@@ -24,6 +24,7 @@ const PositionedPopoverContent = ({
side = 'bottom',
togglePopover,
disableClickOutside,
disableMobileFullscreenTakeover,
}: PopoverContentProps) => {
const [popoverElement, setPopoverElement] = useState<HTMLDivElement | null>(null)
const popoverRect = useAutoElementRect(popoverElement)
@@ -44,6 +45,7 @@ const PositionedPopoverContent = ({
documentRect,
popoverRect: popoverRect ?? popoverElement?.getBoundingClientRect(),
side,
disableMobileFullscreenTakeover: disableMobileFullscreenTakeover,
})
usePopoverCloseOnClickOutside({
@@ -72,23 +74,30 @@ const PositionedPopoverContent = ({
<Portal>
<div
className={classNames(
'absolute top-0 left-0 flex h-full w-full min-w-80 cursor-auto flex-col',
'absolute top-0 left-0 flex w-full min-w-80 cursor-auto flex-col',
'overflow-y-auto rounded bg-default shadow-main md:h-auto md:max-w-xs',
!disableMobileFullscreenTakeover && 'h-full',
overrideZIndex ? overrideZIndex : 'z-dropdown-menu',
!isDesktopScreen ? 'pt-safe-top pb-safe-bottom' : '',
!isDesktopScreen && !disableMobileFullscreenTakeover ? 'pt-safe-top pb-safe-bottom' : '',
!styles && 'md:invisible',
)}
style={{
...styles,
maxHeight: styles
? getPopoverMaxHeight(getAppRect(documentRect), anchorRect, positionedSide, positionedAlignment)
? getPopoverMaxHeight(
getAppRect(documentRect),
anchorRect,
positionedSide,
positionedAlignment,
disableMobileFullscreenTakeover,
)
: '',
top: !isDesktopScreen ? `${document.documentElement.scrollTop}px` : '',
}}
ref={setPopoverElement}
data-popover={id}
>
<div className="md:hidden">
<div className={classNames(disableMobileFullscreenTakeover && 'hidden', 'md:hidden')}>
<div className="flex items-center justify-end px-3 pt-2">
<button className="rounded-full border border-border p-1" onClick={togglePopover}>
<Icon type="close" className="h-6 w-6" />

View File

@@ -37,6 +37,8 @@ type CommonPopoverProps = {
overrideZIndex?: string
togglePopover: () => void
className?: string
disableClickOutside?: boolean
disableMobileFullscreenTakeover?: boolean
}
export type PopoverContentProps = CommonPopoverProps & {
@@ -44,7 +46,6 @@ export type PopoverContentProps = CommonPopoverProps & {
anchorPoint?: Point
childPopovers: Set<string>
id: string
disableClickOutside?: boolean
}
export type PopoverProps =

View File

@@ -6,14 +6,18 @@ export const getPopoverMaxHeight = (
buttonRect: DOMRect | undefined,
side: PopoverSide,
alignment: PopoverAlignment,
disableMobileFullscreenTakeover?: boolean,
): number | 'none' => {
const matchesMediumBreakpoint = matchMedia(MediaQueryBreakpoints.md).matches
if (!matchesMediumBreakpoint) {
if (!matchesMediumBreakpoint && !disableMobileFullscreenTakeover) {
return 'none'
}
const MarginFromAppBorderInPX = 10
const topSafeAreaInset = parseInt(
getComputedStyle(document.documentElement).getPropertyValue('--safe-area-inset-top'),
)
let constraint = 0
@@ -21,6 +25,9 @@ export const getPopoverMaxHeight = (
switch (side) {
case 'top':
constraint = appRect.height - buttonRect.top
if (topSafeAreaInset > 0) {
constraint += topSafeAreaInset
}
break
case 'bottom':
constraint = buttonRect.bottom