Skip to content

Commit

Permalink
wip: PreviewPopUp
Browse files Browse the repository at this point in the history
  • Loading branch information
jstarpl committed Sep 19, 2024
1 parent bf44c37 commit 1dbf75c
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 32 deletions.
65 changes: 41 additions & 24 deletions meteor/client/ui/PreviewPopUp/PreviewPopUp.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,27 @@
import React, { useMemo, useState } from 'react'
import React, { useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'
import classNames from 'classnames'
import { usePopper } from 'react-popper'
import { Padding, Placement, VirtualElement } from '@popperjs/core'

export function PreviewPopUp({
anchor,
padding,
placement,
hidden,
size,
preview,
controls,
contentInfo,
warnings,
}: {
anchor: HTMLElement | VirtualElement | null
padding: Padding
placement: Placement
size: 'small' | 'large'
hidden?: boolean
preview?: React.ReactNode
controls?: React.ReactNode
contentInfo?: React.ReactNode
warnings?: React.ReactNode
}): React.JSX.Element {
export const PreviewPopUp = React.forwardRef<
{
update: () => void
},
{
anchor: HTMLElement | VirtualElement | null
padding: Padding
placement: Placement
size: 'small' | 'large'
hidden?: boolean
preview?: React.ReactNode
controls?: React.ReactNode
contentInfo?: React.ReactNode
warnings?: React.ReactNode
}
>(function PreviewPopUp(
{ anchor, padding, placement, hidden, size, preview, controls, contentInfo, warnings },
ref
): React.JSX.Element {
const warningsCount = React.Children.count(warnings)

const [popperEl, setPopperEl] = useState<HTMLDivElement | null>(null)
Expand Down Expand Up @@ -62,7 +60,26 @@ export function PreviewPopUp({
}),
[padding]
)
const { styles, attributes } = usePopper(anchor, popperEl, popperOptions)
const { styles, attributes, update } = usePopper(anchor, popperEl, popperOptions)

const updateRef = useRef(update)

useEffect(() => {
updateRef.current = update
}, [update])

useImperativeHandle(
ref,
() => {
return {
update: () => {
if (!updateRef.current) return
updateRef.current().catch(console.error)
},
}
},
[]
)

return (
<div
Expand All @@ -87,4 +104,4 @@ export function PreviewPopUp({
)}
</div>
)
}
})
37 changes: 29 additions & 8 deletions meteor/client/ui/PreviewPopUp/PreviewPopUpContext.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import React, { useRef, useState } from 'react'

type VirtualElement = {
getBoundingClientRect: () => DOMRect
Expand Down Expand Up @@ -26,8 +26,14 @@ export type PreviewContent =
content: string
}

interface IPreviewPopUpHandle {
update: Readonly<(content?: PreviewContent) => void>
close: Readonly<() => void>
onClosed?: () => void
}

interface IPreviewPopUpContext {
display: (
requestPreview(
anchor: HTMLElement | VirtualElement,
content: PreviewContent,
opts?: {
Expand All @@ -36,19 +42,34 @@ interface IPreviewPopUpContext {
contentInfo?: React.ReactNode
warnings?: React.ReactNode
}
) => void
hide: () => void
): IPreviewPopUpHandle
}

const PreviewPopUpContext = React.createContext<IPreviewPopUpContext>({
display: () => void {},
hide: () => void {},
requestPreview: () => {
throw new Error('Preview PopUp needs to set up with `PreviewPopUpContextProvider`.')
},
})

export function PreviewPopUpContextProvider({ children }: React.PropsWithChildren<{}>): React.ReactNode {
const [isVisible, setVisible] = useState(false)
const [currentHandle, setCurrentHandle] = useRef()

const context: IPreviewPopUpContext = {
display: () => void {},
hide: () => void {},
requestPreview: (anchor, content, opts) => {
setVisible(true)

const handle: IPreviewPopUpHandle = {
close: () => {
setVisible(false)
},
update: () => {
// todo test
},
}

return handle
},
}

return <PreviewPopUpContext.Provider value={context}>{children}</PreviewPopUpContext.Provider>
Expand Down

0 comments on commit 1dbf75c

Please sign in to comment.