11import React , { useRef , useState } from 'react'
2+ import { PreviewPopUp , PreviewPopUpHandle } from './PreviewPopUp'
3+ import { Padding , Placement } from '@popperjs/core'
24
35type VirtualElement = {
46 getBoundingClientRect : ( ) => DOMRect
@@ -25,24 +27,54 @@ export type PreviewContent =
2527 type : 'text'
2628 content : string
2729 }
30+ | {
31+ type : 'boxLayout'
32+ content : unknown
33+ }
2834
29- interface IPreviewPopUpHandle {
30- update : Readonly < ( content ?: PreviewContent ) => void >
31- close : Readonly < ( ) => void >
35+ interface IPreviewPopUpSession {
36+ /**
37+ * Update the open preview with new content or modify the content already being previewed, such as change current showing
38+ * time in the video, etc.
39+ */
40+ readonly update : ( content ?: PreviewContent ) => void
41+ /**
42+ * Close the preview
43+ */
44+ readonly close : ( ) => void
45+ /**
46+ * Callback for when the preview session is closed by using close() or another preview starting
47+ */
3248 onClosed ?: ( ) => void
3349}
3450
51+ interface PreviewRequestOptions {
52+ /** Padding to be used for placing the Preview PopUp around the anchor element */
53+ padding ?: Padding
54+ /** Where to place the Preview popUp around the anchor element */
55+ placement ?: Placement
56+ /** Which size of the preview to use. Will default to small. */
57+ size ?: 'small' | 'large'
58+ /** Show additional controls underneath the preview content area */
59+ controls ?: React . ReactNode
60+ /** Additional content information that's not part of the preview */
61+ contentInfo ?: React . ReactNode
62+ /** Warnings for the content being previewed */
63+ warnings ?: React . ReactNode [ ]
64+ }
65+
3566interface IPreviewPopUpContext {
67+ /**
68+ * Request a new preview session
69+ * @param anchor The HTML element the preview
70+ * @param content The description of what is to be previewed
71+ * @param opts
72+ */
3673 requestPreview (
3774 anchor : HTMLElement | VirtualElement ,
3875 content : PreviewContent ,
39- opts ?: {
40- size ?: 'small' | 'large'
41- controls ?: React . ReactNode
42- contentInfo ?: React . ReactNode
43- warnings ?: React . ReactNode
44- }
45- ) : IPreviewPopUpHandle
76+ opts ?: PreviewRequestOptions
77+ ) : IPreviewPopUpSession
4678}
4779
4880const PreviewPopUpContext = React . createContext < IPreviewPopUpContext > ( {
@@ -51,26 +83,68 @@ const PreviewPopUpContext = React.createContext<IPreviewPopUpContext>({
5183 } ,
5284} )
5385
86+ interface PreviewSession {
87+ anchor : HTMLElement | VirtualElement
88+ padding : Padding
89+ placement : Placement
90+ size : 'small' | 'large'
91+ /** Show additional controls underneath the preview content area */
92+ controls ?: React . ReactNode
93+ /** Additional content information that's not part of the preview */
94+ contentInfo ?: React . ReactNode
95+ /** Warnings for the content being previewed */
96+ warnings ?: React . ReactNode [ ]
97+ }
98+
5499export function PreviewPopUpContextProvider ( { children } : React . PropsWithChildren < { } > ) : React . ReactNode {
55- const [ isVisible , setVisible ] = useState ( false )
56- const [ currentHandle , setCurrentHandle ] = useRef ( )
100+ const currentHandle = useRef < IPreviewPopUpSession > ( )
101+ const previewRef = useRef < PreviewPopUpHandle > ( null )
102+
103+ const [ previewSession , setPreviewSession ] = useState < PreviewSession | null > ( null )
104+ const [ previewContent , setPreviewContent ] = useState < PreviewContent | null > ( null )
57105
58106 const context : IPreviewPopUpContext = {
59107 requestPreview : ( anchor , content , opts ) => {
60- setVisible ( true )
108+ setPreviewSession ( {
109+ anchor,
110+ padding : opts ?. padding ?? 0 ,
111+ placement : opts ?. placement ?? 'top' ,
112+ size : opts ?. size ?? 'small' ,
113+ controls : opts ?. controls ,
114+ contentInfo : opts ?. contentInfo ,
115+ warnings : opts ?. warnings ,
116+ } )
117+ setPreviewContent ( content )
61118
62- const handle : IPreviewPopUpHandle = {
119+ const handle : IPreviewPopUpSession = {
63120 close : ( ) => {
64- setVisible ( false )
121+ setPreviewSession ( null )
65122 } ,
66123 update : ( ) => {
67- // todo test
124+ previewRef . current ?. update ( )
68125 } ,
69126 }
127+ currentHandle . current = handle
70128
71129 return handle
72130 } ,
73131 }
74132
75- return < PreviewPopUpContext . Provider value = { context } > { children } </ PreviewPopUpContext . Provider >
133+ return (
134+ < PreviewPopUpContext . Provider value = { context } >
135+ { children }
136+ { previewSession && (
137+ < PreviewPopUp
138+ ref = { previewRef }
139+ anchor = { previewSession . anchor }
140+ padding = { previewSession . padding }
141+ size = { previewSession . size }
142+ placement = { previewSession . placement }
143+ contentInfo = { previewSession . contentInfo }
144+ controls = { previewSession . controls }
145+ warnings = { previewSession . warnings }
146+ />
147+ ) }
148+ </ PreviewPopUpContext . Provider >
149+ )
76150}
0 commit comments