File size: 2,040 Bytes
6f91ce5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import { createContext, useContext, type CSSProperties, type ReactNode } from 'react'
import type { Editor } from 'tldraw'
import type { PaperCardShape } from '../../shared/shapes.ts'
import type { Related } from './fade.ts'

// What every widget around the open paper shares, from OpenPaper in PaperWidgets.tsx.

export interface Toast {
	text: string
	undo?: () => void
}

export interface LinkedPaper {
	shapeId: string
	paperId: string
	kind: PaperCardShape['props']['kind']
	label: string
	fit: 'low' | 'medium' | 'high' | null
	/** How it's linked to the open paper: "cites it", "cited by it", "similar", or a person's label. */
	relation: string
	/** It cites the open paper, or the open paper cites it. */
	cites: 'in' | 'out' | null
}

export interface WidgetsApi {
	editor: Editor
	boardId: string
	memberId: string
	shape: PaperCardShape
	goal: string
	more: boolean
	related: Related
	linked: LinkedPaper[]
	/** Reports a widget's natural height for the layout. */
	measure(key: string): (el: HTMLElement | null) => void
	/** Widgets the layout holds below their natural height. */
	limits: Record<string, number>
	/** The grow-out-of-the-node animation for a widget, once the layout is known. */
	pop(key: string): CSSProperties | undefined
	/** The widget holding what's being peeked at (it stays visible while the rest fade). */
	peekKey: string | null
	/** Lights papers up on the board and fades every widget but `key`; null ends it. */
	peek(key: string | null, paperIds?: string[]): void
	/** Shows a dark popover under `el`, peeking at `peek` while it's open. */
	showPop(el: HTMLElement, content: ReactNode, peek?: { key: string; paperIds: string[] }): void
	hidePop(): void
	toast(toast: Toast): void
	openFigure(): void
	close(): void
	noteDraft: boolean
	setNoteDraft(on: boolean): void
}

export const WidgetsContext = createContext<WidgetsApi | null>(null)

export function useWidgets(): WidgetsApi {
	const api = useContext(WidgetsContext)
	if (!api) throw new Error('useWidgets outside OpenPaper')
	return api
}