@estiva-app/ui 0.72.0-widgets2.1 → 0.72.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CommentHighlights.d.ts +100 -0
- package/dist/CommentHighlights.d.ts.map +1 -0
- package/dist/ComposeBox.d.ts +55 -0
- package/dist/ComposeBox.d.ts.map +1 -0
- package/dist/ComposerTriggers.d.ts.map +1 -1
- package/dist/SelectionToolbar.d.ts +17 -1
- package/dist/SelectionToolbar.d.ts.map +1 -1
- package/dist/editor.d.ts +3 -1
- package/dist/editor.d.ts.map +1 -1
- package/dist/editor.js +618 -217
- package/dist/editor.js.map +4 -4
- package/dist/index.js.map +1 -1
- package/dist/looks.d.ts +6 -0
- package/dist/looks.d.ts.map +1 -1
- package/package.json +1 -5
- package/registry.json +309 -3
- package/src/CommentHighlights.mdx +61 -0
- package/src/CommentHighlights.stories.tsx +72 -0
- package/src/CommentHighlights.test.ts +100 -0
- package/src/CommentHighlights.ts +413 -0
- package/src/ComposeBox.mdx +58 -0
- package/src/ComposeBox.stories.tsx +81 -0
- package/src/ComposeBox.tsx +183 -0
- package/src/ComposerTriggers.tsx +9 -3
- package/src/SelectionToolbar.actions.test.tsx +44 -0
- package/src/SelectionToolbar.mdx +1 -0
- package/src/SelectionToolbar.tsx +36 -2
- package/src/editor.ts +15 -1
- package/src/looks.ts +8 -0
- package/src/registry/app.test.ts +7 -1
- package/src/registry/registry.test.ts +6 -6
- package/stories/Choosing.mdx +2 -0
- package/dist/widgets-2/fixtures.d.ts +0 -102
- package/dist/widgets-2/fixtures.d.ts.map +0 -1
- package/dist/widgets-2/places.d.ts +0 -99
- package/dist/widgets-2/places.d.ts.map +0 -1
- package/dist/widgets-2/proposed.d.ts +0 -130
- package/dist/widgets-2/proposed.d.ts.map +0 -1
- package/dist/widgets-2.d.ts +0 -12
- package/dist/widgets-2.d.ts.map +0 -1
- package/dist/widgets-2.js +0 -584
- package/dist/widgets-2.js.map +0 -7
- package/src/widgets-2/fixtures.ts +0 -161
- package/src/widgets-2/places.tsx +0 -309
- package/src/widgets-2/proposed.tsx +0 -596
- package/src/widgets-2.ts +0 -11
- package/stories/widgets-2/ReadMe.mdx +0 -60
- package/stories/widgets-2/Widgets.stories.tsx +0 -504
- package/stories/widgets-2/today.tsx +0 -352
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { useCallback, useEffect, useState, type ReactNode } from 'react'
|
|
2
|
+
import { Extension } from '@tiptap/core'
|
|
3
|
+
import { EditorContent, type Editor } from '@tiptap/react'
|
|
4
|
+
import { IconArrowUp } from '@tabler/icons-react'
|
|
5
|
+
import { IconButton } from './IconButton'
|
|
6
|
+
import { Toolbar } from './Toolbar'
|
|
7
|
+
import { cn } from './cn'
|
|
8
|
+
import { richTextClassName } from './RichText'
|
|
9
|
+
import { WRITING_BOX_CLASSES } from './looks'
|
|
10
|
+
import { SelectionToolbar, type SelectionToolbarProps } from './SelectionToolbar'
|
|
11
|
+
import { isSuggestionActive } from './suggestionPopup'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The box a message, a reply or a comment is written in, from Katerina's Leaf
|
|
15
|
+
* prototype (9 October). Peek's `ComposeBox`, its look and its keys, with
|
|
16
|
+
* what only Peek knows left in Peek: drafts, uploads, highlights, its text
|
|
17
|
+
* format. The app makes the editor (its extensions are its own) and adds
|
|
18
|
+
* `ComposeKeys`; this draws the box around it and sends.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/** The editor's own classes inside the box: Peek's, rich text with no outline. Put them in `editorProps.attributes.class`. */
|
|
22
|
+
export const COMPOSE_EDITOR_CLASSES = richTextClassName('default', 'outline-none w-full bg-transparent min-h-[20px] [&>p+p]:-mt-1')
|
|
23
|
+
|
|
24
|
+
type ComposeKeysStorage = { send: (() => boolean) | null }
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Enter sends; Shift+Enter is a new line — in a list a new item (or out of the
|
|
28
|
+
* list, on an empty one), in a quote a new line (or out of it, on an empty one).
|
|
29
|
+
* Peek's keys, as its ComposeBox has them. Enter while a `/`, `@` or `[` list is
|
|
30
|
+
* open picks a row instead. `ComposeBox` says what sending does.
|
|
31
|
+
*/
|
|
32
|
+
export const ComposeKeys = Extension.create<Record<string, never>, ComposeKeysStorage>({
|
|
33
|
+
name: 'composeKeys',
|
|
34
|
+
addStorage() {
|
|
35
|
+
return { send: null }
|
|
36
|
+
},
|
|
37
|
+
addKeyboardShortcuts() {
|
|
38
|
+
return {
|
|
39
|
+
Enter: () => {
|
|
40
|
+
if (isSuggestionActive()) return false
|
|
41
|
+
this.storage.send?.()
|
|
42
|
+
return true
|
|
43
|
+
},
|
|
44
|
+
'Shift-Enter': ({ editor }) => {
|
|
45
|
+
const { $from } = editor.state.selection
|
|
46
|
+
for (let d = $from.depth; d > 0; d--) {
|
|
47
|
+
const node = $from.node(d)
|
|
48
|
+
if (node.type.name === 'listItem') {
|
|
49
|
+
return node.textContent.length === 0 ? editor.commands.liftListItem('listItem') : editor.commands.splitListItem('listItem')
|
|
50
|
+
}
|
|
51
|
+
if (node.type.name === 'blockquote') {
|
|
52
|
+
if ($from.parent.textContent.length === 0) return editor.commands.lift('paragraph')
|
|
53
|
+
break
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return editor.commands.splitBlock()
|
|
57
|
+
},
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
/** Nothing written: no text, no chip and no picture — empty lines, lists or quotes only. */
|
|
63
|
+
function isEmptyDoc(editor: Editor): boolean {
|
|
64
|
+
const doc = editor.state.doc
|
|
65
|
+
if (doc.textContent.length > 0) return false
|
|
66
|
+
let empty = true
|
|
67
|
+
doc.descendants((node) => {
|
|
68
|
+
if (node.isAtom && node.type.name !== 'hardBreak') empty = false
|
|
69
|
+
})
|
|
70
|
+
return empty
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface ComposeBoxProps {
|
|
74
|
+
/** The app's editor, with `ComposeKeys` in its extensions and `COMPOSE_EDITOR_CLASSES` on it. `null` while it loads. */
|
|
75
|
+
editor: Editor | null
|
|
76
|
+
/**
|
|
77
|
+
* Send what is written. The box empties afterwards — unless this returns
|
|
78
|
+
* `false`: nothing was sent, and the words stay.
|
|
79
|
+
*/
|
|
80
|
+
onSend: (editor: Editor) => void | boolean
|
|
81
|
+
/** Said in the empty box: words, and a `Kbd` where a key helps ("type / for commands"). */
|
|
82
|
+
placeholder: ReactNode
|
|
83
|
+
/** The tools under the text, left: `ToolbarButton`s (attach, highlight). One Tab stop. */
|
|
84
|
+
tools?: ReactNode
|
|
85
|
+
/** What is attached, under the text: `AttachmentCard pending`s. */
|
|
86
|
+
attachments?: ReactNode
|
|
87
|
+
/** Something to send even with no words — a file ready. */
|
|
88
|
+
ready?: boolean
|
|
89
|
+
/** Sending waits — a file still uploading. */
|
|
90
|
+
holding?: boolean
|
|
91
|
+
/** The bar down the text's left: an urgent mention or a highlight, as Peek draws it. */
|
|
92
|
+
marked?: boolean
|
|
93
|
+
/** The selection strip's buttons: its marks, Link, and the app's own (`actions`). */
|
|
94
|
+
selection?: Pick<SelectionToolbarProps, 'marks' | 'link' | 'actions'>
|
|
95
|
+
className?: string
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* The box for writing: the text, the selection strip over it, what is
|
|
100
|
+
* attached, the tools and Send. Enter sends (`ComposeKeys`), and so does the
|
|
101
|
+
* button.
|
|
102
|
+
*/
|
|
103
|
+
export function ComposeBox({ editor, onSend, placeholder, tools, attachments, ready = false, holding = false, marked = false, selection, className }: ComposeBoxProps) {
|
|
104
|
+
const [empty, setEmpty] = useState(true)
|
|
105
|
+
const canSend = (!empty || ready) && !holding
|
|
106
|
+
|
|
107
|
+
const send = useCallback((): boolean => {
|
|
108
|
+
if (!editor || holding || (isEmptyDoc(editor) && !ready)) return true
|
|
109
|
+
if (onSend(editor) === false) return true
|
|
110
|
+
editor.commands.clearContent(true)
|
|
111
|
+
editor.commands.focus()
|
|
112
|
+
return true
|
|
113
|
+
}, [editor, holding, ready, onSend])
|
|
114
|
+
|
|
115
|
+
// Enter, through `ComposeKeys`, sends the way the button does.
|
|
116
|
+
useEffect(() => {
|
|
117
|
+
if (!editor) return
|
|
118
|
+
const storage = (editor.storage as unknown as { composeKeys?: ComposeKeysStorage }).composeKeys
|
|
119
|
+
if (!storage) return
|
|
120
|
+
storage.send = send
|
|
121
|
+
return () => {
|
|
122
|
+
storage.send = null
|
|
123
|
+
}
|
|
124
|
+
}, [editor, send])
|
|
125
|
+
|
|
126
|
+
useEffect(() => {
|
|
127
|
+
if (!editor) return
|
|
128
|
+
const read = () => setEmpty(isEmptyDoc(editor))
|
|
129
|
+
read()
|
|
130
|
+
editor.on('update', read)
|
|
131
|
+
return () => {
|
|
132
|
+
editor.off('update', read)
|
|
133
|
+
}
|
|
134
|
+
}, [editor])
|
|
135
|
+
|
|
136
|
+
return (
|
|
137
|
+
<div className={cn('relative', className)}>
|
|
138
|
+
<div className={cn(WRITING_BOX_CLASSES, 'focus-within:border-border-strong transition-colors')}>
|
|
139
|
+
<div data-composer-editor className={cn('relative min-h-[20px] transition-all', marked && 'border-l-4 border-border-strong pl-2')}>
|
|
140
|
+
<EditorContent editor={editor} />
|
|
141
|
+
<SelectionToolbar editor={editor} {...selection} />
|
|
142
|
+
{empty && (
|
|
143
|
+
<div className="pointer-events-none absolute inset-0 flex flex-wrap items-center gap-1 text-body-2 text-text-muted">{placeholder}</div>
|
|
144
|
+
)}
|
|
145
|
+
</div>
|
|
146
|
+
|
|
147
|
+
{attachments && <div className="flex flex-wrap gap-2">{attachments}</div>}
|
|
148
|
+
|
|
149
|
+
{/* The tools are one strip — one Tab stop, arrows along it; Send, the answer rather than a tool, keeps its own. */}
|
|
150
|
+
<div className="flex items-center justify-between">
|
|
151
|
+
{tools ? (
|
|
152
|
+
<Toolbar aria-label="Compose tools" surface={false} className="flex items-center gap-1">
|
|
153
|
+
{tools}
|
|
154
|
+
</Toolbar>
|
|
155
|
+
) : (
|
|
156
|
+
<span />
|
|
157
|
+
)}
|
|
158
|
+
<div className="flex items-center gap-2.5">
|
|
159
|
+
<span className="hidden select-none font-mono text-menu font-normal tracking-wider text-text-muted signal:inline">Enter to send · Shift+Enter new line</span>
|
|
160
|
+
{/* Focus stays in the text: the press sends on its way down. A keyboard press is the click (`detail` 0), so a click never sends twice. */}
|
|
161
|
+
<IconButton
|
|
162
|
+
variant="primary"
|
|
163
|
+
onMouseDown={(e) => {
|
|
164
|
+
e.preventDefault()
|
|
165
|
+
send()
|
|
166
|
+
}}
|
|
167
|
+
onClick={(e) => {
|
|
168
|
+
if (e.detail === 0) send()
|
|
169
|
+
}}
|
|
170
|
+
disabled={!canSend}
|
|
171
|
+
aria-label="Send"
|
|
172
|
+
tooltip="Send"
|
|
173
|
+
tooltipShortcut="Enter"
|
|
174
|
+
glow={canSend}
|
|
175
|
+
>
|
|
176
|
+
<IconArrowUp size={16} stroke={1.5} />
|
|
177
|
+
</IconButton>
|
|
178
|
+
</div>
|
|
179
|
+
</div>
|
|
180
|
+
</div>
|
|
181
|
+
</div>
|
|
182
|
+
)
|
|
183
|
+
}
|
package/src/ComposerTriggers.tsx
CHANGED
|
@@ -7,6 +7,7 @@ import { NodeViewWrapper, ReactNodeViewRenderer, type ReactNodeViewProps } from
|
|
|
7
7
|
import { Avatar } from './Avatar'
|
|
8
8
|
import { EnterHint } from './Menu'
|
|
9
9
|
import { inlineChipClassName } from './InlineChip'
|
|
10
|
+
import { WithTooltip } from './Tooltip'
|
|
10
11
|
import type { SuggestionMenuRow } from './SuggestionMenu'
|
|
11
12
|
import { suggestionPopup, type SuggestionPopupOptions } from './suggestionPopup'
|
|
12
13
|
|
|
@@ -308,9 +309,14 @@ export const CaptionedReference = Mention.extend<MentionOptions & CaptionedRefer
|
|
|
308
309
|
const { icon, iconFor } = this.options
|
|
309
310
|
return ReactNodeViewRenderer(
|
|
310
311
|
({ node }: ReactNodeViewProps) => (
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
<
|
|
312
|
+
// The caption is cut at 24ch, so the whole of it is on hover, in the package's tooltip (UIG-14) — as Peek's sent chip has it.
|
|
313
|
+
<NodeViewWrapper as="span">
|
|
314
|
+
<WithTooltip inline label={captionOf(node.attrs.label, node.attrs.snippet)}>
|
|
315
|
+
<span className={inlineChipClassName('neutral', 'max-w-[24ch] cursor-default')}>
|
|
316
|
+
<span className="flex items-center justify-center w-4 h-4 shrink-0 text-text-secondary">{iconFor?.(node.attrs.uri ?? null) ?? icon}</span>
|
|
317
|
+
<span className="truncate">{captionOf(node.attrs.label, node.attrs.snippet)}</span>
|
|
318
|
+
</span>
|
|
319
|
+
</WithTooltip>
|
|
314
320
|
</NodeViewWrapper>
|
|
315
321
|
),
|
|
316
322
|
{ as: 'span' },
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
/**
|
|
3
|
+
* The app's own buttons on the selection strip (`actions`, LEAF-4): pressing
|
|
4
|
+
* one runs it with the selection in place, and the strip closes. jsdom has no
|
|
5
|
+
* layout, so the view's focus and coordinates are stood in for.
|
|
6
|
+
*/
|
|
7
|
+
import { afterEach, expect, it, vi } from 'vitest'
|
|
8
|
+
import { act, cleanup, render, screen } from '@testing-library/react'
|
|
9
|
+
import userEvent from '@testing-library/user-event'
|
|
10
|
+
import { Editor } from '@tiptap/core'
|
|
11
|
+
import StarterKit from '@tiptap/starter-kit'
|
|
12
|
+
import { KeptSelection, SelectionToolbar } from './SelectionToolbar'
|
|
13
|
+
|
|
14
|
+
let editor: Editor | undefined
|
|
15
|
+
|
|
16
|
+
afterEach(() => {
|
|
17
|
+
cleanup()
|
|
18
|
+
editor?.destroy()
|
|
19
|
+
editor = undefined
|
|
20
|
+
vi.useRealTimers()
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
it('runs an action with the selection in place, and closes the strip', async () => {
|
|
24
|
+
vi.useFakeTimers({ shouldAdvanceTime: true })
|
|
25
|
+
editor = new Editor({ extensions: [StarterKit, KeptSelection], content: '<p>some words to comment on</p>' })
|
|
26
|
+
vi.spyOn(editor.view, 'hasFocus').mockReturnValue(true)
|
|
27
|
+
vi.spyOn(editor.view, 'coordsAtPos').mockReturnValue({ top: 10, bottom: 20, left: 10, right: 20 })
|
|
28
|
+
const seen: { from: number; to: number }[] = []
|
|
29
|
+
const run = vi.fn((e: Editor) => seen.push({ from: e.state.selection.from, to: e.state.selection.to }))
|
|
30
|
+
render(<SelectionToolbar editor={editor} actions={[{ label: 'Comment', icon: <span aria-hidden />, run }]} />)
|
|
31
|
+
|
|
32
|
+
act(() => {
|
|
33
|
+
editor!.commands.setTextSelection({ from: 6, to: 11 })
|
|
34
|
+
})
|
|
35
|
+
await act(async () => {
|
|
36
|
+
await vi.advanceTimersByTimeAsync(400)
|
|
37
|
+
})
|
|
38
|
+
const button = await screen.findByRole('button', { name: 'Comment' })
|
|
39
|
+
await userEvent.setup({ advanceTimers: vi.advanceTimersByTime }).click(button)
|
|
40
|
+
|
|
41
|
+
expect(run).toHaveBeenCalledTimes(1)
|
|
42
|
+
expect(seen).toEqual([{ from: 6, to: 11 }])
|
|
43
|
+
expect(screen.queryByRole('button', { name: 'Comment' })).toBeNull()
|
|
44
|
+
})
|
package/src/SelectionToolbar.mdx
CHANGED
|
@@ -16,6 +16,7 @@ over text you have already selected in an editor.
|
|
|
16
16
|
itself when to appear: once a selection has stood still, centred over it.
|
|
17
17
|
- `marks` chooses the buttons, in order: `bold`, `italic`, `underline`, `code`.
|
|
18
18
|
The default is the first three.
|
|
19
|
+
- `actions` adds the app's own buttons at the end, past a separator — Comment, in a document. Each `run`s with the selection in place, and the strip closes after it.
|
|
19
20
|
- `link` adds the Link button, which turns the strip into one field for the
|
|
20
21
|
address. Select words that are already a link and the field opens by itself,
|
|
21
22
|
their address in it.
|
package/src/SelectionToolbar.tsx
CHANGED
|
@@ -7,7 +7,7 @@ import { IconBold, IconCode, IconItalic, IconLink, IconUnderline } from '@tabler
|
|
|
7
7
|
import { Form } from './Form'
|
|
8
8
|
import { Popover } from './Popover'
|
|
9
9
|
import { TextInput } from './TextInput'
|
|
10
|
-
import { Toolbar, ToolbarButton } from './Toolbar'
|
|
10
|
+
import { Toolbar, ToolbarButton, ToolbarSeparator } from './Toolbar'
|
|
11
11
|
import { shortcutLabel } from './shortcuts'
|
|
12
12
|
|
|
13
13
|
/**
|
|
@@ -228,9 +228,26 @@ export interface SelectionToolbarProps {
|
|
|
228
228
|
* nothing.
|
|
229
229
|
*/
|
|
230
230
|
children?: ReactNode
|
|
231
|
+
/**
|
|
232
|
+
* The app's own buttons after the marks, past a separator: "Comment". Each
|
|
233
|
+
* runs with the selection still in place, and the strip closes after it.
|
|
234
|
+
*/
|
|
235
|
+
actions?: readonly SelectionAction[]
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/** One of the app's buttons in the strip. */
|
|
239
|
+
export interface SelectionAction {
|
|
240
|
+
/** Says what it does: the tooltip and the button's name. */
|
|
241
|
+
label: string
|
|
242
|
+
/** A 16px icon. */
|
|
243
|
+
icon: ReactNode
|
|
244
|
+
/** The keys that do the same, shown in the tooltip ("Mod-Shift-M"). */
|
|
245
|
+
keys?: string
|
|
246
|
+
/** What it does, with the selection as it is. */
|
|
247
|
+
run: (editor: Editor) => void
|
|
231
248
|
}
|
|
232
249
|
|
|
233
|
-
export function SelectionToolbar({ editor, marks = ['bold', 'italic', 'underline'], link = false, children }: SelectionToolbarProps) {
|
|
250
|
+
export function SelectionToolbar({ editor, marks = ['bold', 'italic', 'underline'], link = false, children, actions = [] }: SelectionToolbarProps) {
|
|
234
251
|
/** The selection's top edge and horizontal centre; the face decides the rest. */
|
|
235
252
|
const [anchor, setAnchor] = useState<{ top: number; centre: number } | null>(null)
|
|
236
253
|
const [mode, setMode] = useState<Mode>('marks')
|
|
@@ -488,6 +505,23 @@ export function SelectionToolbar({ editor, marks = ['bold', 'italic', 'underline
|
|
|
488
505
|
</ToolbarButton>
|
|
489
506
|
)}
|
|
490
507
|
{children}
|
|
508
|
+
{actions.length > 0 && <ToolbarSeparator />}
|
|
509
|
+
{actions.map((action) => (
|
|
510
|
+
<ToolbarButton
|
|
511
|
+
key={action.label}
|
|
512
|
+
aria-label={action.label}
|
|
513
|
+
tooltip={action.label}
|
|
514
|
+
tooltipShortcut={action.keys ? shortcutLabel(action.keys) : undefined}
|
|
515
|
+
onMouseDown={(e) => e.preventDefault()}
|
|
516
|
+
onClick={() => {
|
|
517
|
+
// Closing first: it lets go of a kept selection, which the action may want to keep.
|
|
518
|
+
hide()
|
|
519
|
+
action.run(editor)
|
|
520
|
+
}}
|
|
521
|
+
>
|
|
522
|
+
{action.icon}
|
|
523
|
+
</ToolbarButton>
|
|
524
|
+
))}
|
|
491
525
|
</Toolbar>
|
|
492
526
|
)}
|
|
493
527
|
</Popover>
|
package/src/editor.ts
CHANGED
|
@@ -7,7 +7,21 @@
|
|
|
7
7
|
* as the eslint ones are. The rest of the package it draws with — `Popover`,
|
|
8
8
|
* `Toolbar`, `MenuItem`, `SuggestionMenu` — is the main entry's own, not a copy.
|
|
9
9
|
*/
|
|
10
|
-
export { KeptSelection, SelectionToolbar, normalizeHref, type MarkId, type SelectionToolbarProps } from './SelectionToolbar'
|
|
10
|
+
export { KeptSelection, SelectionToolbar, keepSelection, releaseSelection, normalizeHref, type MarkId, type SelectionAction, type SelectionToolbarProps } from './SelectionToolbar'
|
|
11
|
+
export { ComposeBox, ComposeKeys, COMPOSE_EDITOR_CLASSES, type ComposeBoxProps } from './ComposeBox'
|
|
12
|
+
export {
|
|
13
|
+
CommentHighlights,
|
|
14
|
+
setCommentAnchors,
|
|
15
|
+
commentPlace,
|
|
16
|
+
commentElement,
|
|
17
|
+
anchorOfSelection,
|
|
18
|
+
quoteText,
|
|
19
|
+
type CommentAnchor,
|
|
20
|
+
type CommentHighlightsOptions,
|
|
21
|
+
type CommentPlace,
|
|
22
|
+
type CommentQuote,
|
|
23
|
+
type SelectionAnchor,
|
|
24
|
+
} from './CommentHighlights'
|
|
11
25
|
export { PastedImages, pastedImages, pastedImageName, type PastedImagesOptions, type ClipboardSource } from './PastedImages'
|
|
12
26
|
export { PastedMarkdown, type PastedMarkdownOptions } from './PastedMarkdown'
|
|
13
27
|
export { CodeBlockColours } from './CodeBlockColours'
|
package/src/looks.ts
CHANGED
|
@@ -67,3 +67,11 @@ export const MENU_TRIGGER_CLASSES = 'cursor-pointer rounded-md transition-colors
|
|
|
67
67
|
* prefers-reduced-motion. CollapsibleSection's rows, and the rows under a NavItem.
|
|
68
68
|
*/
|
|
69
69
|
export const COLLAPSIBLE_PANEL_CLASSES = 'h-[var(--collapsible-panel-height)] overflow-hidden transition-[height] duration-150 ease-out motion-reduce:transition-none data-[starting-style]:h-0 data-[ending-style]:h-0'
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The box a message or a comment is written in: Peek's writing box (its
|
|
73
|
+
* `looks.ts`, Katerina 24 September), moved with ComposeBox. Inset, a hairline,
|
|
74
|
+
* 12px in, 16px between the text and the row under it; the focus ring in Signal.
|
|
75
|
+
*/
|
|
76
|
+
export const WRITING_BOX_CLASSES =
|
|
77
|
+
'relative bg-bg-inset border border-border-default rounded-lg p-3 flex flex-col gap-4 signal:transition-shadow signal:focus-within:border-border-focus signal:focus-within:shadow-focus-ring'
|
package/src/registry/app.test.ts
CHANGED
|
@@ -596,7 +596,13 @@ describe('one search over the package and the apps', () => {
|
|
|
596
596
|
root: app({ 'src/Composer.tsx': '/** Where a comment is written and sent. */\nexport function Composer() {\n return <form />\n}\n' }),
|
|
597
597
|
repo: 'fixture',
|
|
598
598
|
})
|
|
599
|
-
|
|
599
|
+
// Since the Leaf prototype (9 October) the package has a box for writing comments, ComposeBox, and it answers first by its
|
|
600
|
+
// own purpose. What this guards still holds: the app's composer is found above the parts the words reach only through notes.
|
|
601
|
+
const found = findInRegistries([packageRegistry, composer], 'comment composer', { limit: 10 }).map((f) => `${f.entry.repo}:${f.entry.name}`)
|
|
602
|
+
expect(found[0]).toBe('estiva-ui:ComposeBox')
|
|
603
|
+
expect(found.indexOf('fixture:Composer')).toBeGreaterThan(0)
|
|
604
|
+
const triggers = found.indexOf('estiva-ui:ComposerTriggers')
|
|
605
|
+
if (triggers >= 0) expect(found.indexOf('fixture:Composer')).toBeLessThan(triggers)
|
|
600
606
|
})
|
|
601
607
|
|
|
602
608
|
it('says which apps hand a package part on, and how a default is imported', () => {
|
|
@@ -26,7 +26,7 @@ import { SCHEMA_VERSION, validateRegistry, type Registry, type RegistryEntry } f
|
|
|
26
26
|
const root = process.cwd()
|
|
27
27
|
const registry = buildRegistry({ root })
|
|
28
28
|
/** Editor extensions: named like components by the catalogue, and not React components. */
|
|
29
|
-
const EDITOR_EXTENSIONS = ['KeptSelection', 'BlockId', 'UnknownBlock', 'ReferenceNode', 'AttachmentNode', 'PersonMention', 'UrgentPersonMention', 'CaptionedReference', 'ReferenceTrigger', 'SlashCommands', 'PastedImages', 'PastedMarkdown', 'CodeBlockColours', 'Checklist', 'Callout', 'ReferenceCards', 'LinkChips', 'ReferenceMenu']
|
|
29
|
+
const EDITOR_EXTENSIONS = ['KeptSelection', 'BlockId', 'UnknownBlock', 'ReferenceNode', 'AttachmentNode', 'PersonMention', 'UrgentPersonMention', 'CaptionedReference', 'ReferenceTrigger', 'SlashCommands', 'PastedImages', 'PastedMarkdown', 'CodeBlockColours', 'Checklist', 'Callout', 'ReferenceCards', 'LinkChips', 'ReferenceMenu', 'CommentHighlights', 'ComposeKeys']
|
|
30
30
|
const entry = (name: string): RegistryEntry => {
|
|
31
31
|
const found = registry.entries.find((candidate) => candidate.name === name)
|
|
32
32
|
if (!found) throw new Error(`no entry for ${name}`)
|
|
@@ -48,20 +48,20 @@ describe('the registry builds', () => {
|
|
|
48
48
|
expect(registry.entries.map((one) => one.name).sort()).toEqual(values.map((one) => one.name).sort())
|
|
49
49
|
})
|
|
50
50
|
|
|
51
|
-
it('counts
|
|
51
|
+
it('counts 177 names over 83 files: 118 components, 57 helpers and 2 hooks (ComposeBox with ComposeKeys and its classes, CommentHighlights with its five helpers, and keepSelection and releaseSelection, from the Leaf prototype (LEAF-4), on 16 October;NavTree, NavTreeSection, the composer triggers and UnreadDot joined on 2 October; BlockHandle and EditorBlockHandle (RIC-18) on 2 October, moveBlock and blockDropCursor, the drop in the gutter, on 5 October, MembersPill and MembersDialog, moved from Peek (SHI-31), on 6 October, ShowMore on 7 October, AppProvider on 8 October, and KindIcon, thingKindOf and PastedImages with its two helpers, moved from Peek, on 8 October; CodeBlockColours, the coloured code block of the editor, on 9 October; Checklist, Callout, isChecklistTick and calloutLook (RIC-19) on 13 October; EditorTableControls and its four actions (RIC-21) on 13 October; ReferenceCards, useReferenceCards and its three helpers, the card a chip in a document asks for, on 14 October; LinkChips and its two helpers, a URL in a document read as its chip, on 14 October; ReferenceMenu, ReferenceMenuView and three helpers, the menu of a chip while writing, on 14 October; PastedMarkdown, markdown pasted as the blocks it spells (LEAF-10), on 15 October; turnIntoRows, turnListInto and turnQuoteInto, the block menu’s Turn into for a list and a quote (LEAF-11), on 15 October)', () => {
|
|
52
52
|
// The reconciliation GATES.md §24 explains. If this changes, that changes.
|
|
53
53
|
// The `EDITOR_EXTENSIONS` count as components by their names; they are
|
|
54
54
|
// editor extensions, documented on SelectionToolbar's, BlockNodes' and
|
|
55
55
|
// ComposerTriggers' pages.
|
|
56
56
|
const kinds = registry.entries.reduce<Record<string, number>>((all, one) => ({ ...all, [one.kind]: (all[one.kind] ?? 0) + 1 }), {})
|
|
57
|
-
expect(kinds).toEqual({ component:
|
|
58
|
-
expect(new Set(registry.entries.map((one) => one.sourceFile)).size).toBe(
|
|
57
|
+
expect(kinds).toEqual({ component: 118, helper: 57, hook: 2 })
|
|
58
|
+
expect(new Set(registry.entries.map((one) => one.sourceFile)).size).toBe(83)
|
|
59
59
|
})
|
|
60
60
|
|
|
61
61
|
it('gives every entry a purpose, from its own page or from the comment above it', () => {
|
|
62
62
|
expect(registry.entries.filter((one) => one.purpose.trim() === '')).toEqual([])
|
|
63
|
-
expect(registry.entries.filter((one) => one.purposeFrom === 'page').length).toBe(
|
|
64
|
-
expect(registry.entries.filter((one) => one.purposeFrom === 'comment').length).toBe(
|
|
63
|
+
expect(registry.entries.filter((one) => one.purposeFrom === 'page').length).toBe(79)
|
|
64
|
+
expect(registry.entries.filter((one) => one.purposeFrom === 'comment').length).toBe(98)
|
|
65
65
|
})
|
|
66
66
|
|
|
67
67
|
it('takes a name with a page of its own from the page, and a name without one from the code', () => {
|
package/stories/Choosing.mdx
CHANGED
|
@@ -72,6 +72,8 @@ fork freely, owe nothing back, mention it on the package's ticket.
|
|
|
72
72
|
| Bold, italic and the like over selected text in an editor | **SelectionToolbar**, from `@estiva-app/ui/editor` — it follows the selection by itself |
|
|
73
73
|
| A composer's `@`, `!@`, `[` and `/` — mention a person, reference something, format or insert | **ComposerTriggers** — `PersonMention`, `UrgentPersonMention`, `CaptionedReference`, `ReferenceTrigger` and `SlashCommands` from `@estiva-app/ui/editor`; the app passes its people, its items and its own `/` rows |
|
|
74
74
|
| An editor that saves a block document and must keep its block ids | **BlockNodes** — `BlockId`, `UnknownBlock`, `ReferenceNode` and `AttachmentNode` from `@estiva-app/ui/editor`, beside StarterKit and TableKit |
|
|
75
|
+
| The box a message, a reply or a comment is written in and sent | **ComposeBox**, from `@estiva-app/ui/editor` — the app brings its editor and adds `ComposeKeys` |
|
|
76
|
+
| Comments on words, a passage or whole blocks of a document, drawn where they are | **CommentHighlights**, from `@estiva-app/ui/editor` — a run of blocks and the words quoted; says which was clicked and which moved or are gone |
|
|
75
77
|
| Move, turn, duplicate or delete one block of a document being edited | **EditorBlockHandle**, from `@estiva-app/ui/editor`, with your rows after its own |
|
|
76
78
|
| Add or delete a table's rows and columns in a document being edited | **EditorTableControls**, from `@estiva-app/ui/editor`, inside the EditorBlockHandle |
|
|
77
79
|
| Offer a link or a comment on one block of a document being read | **BlockHandle** — your rows only, and no Tiptap loaded |
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Widgets 2 prototype: the placeholder things every widget on these pages
|
|
3
|
-
* draws. Words are placeholders (stories-and-pages.md); the kinds are named,
|
|
4
|
-
* because telling them apart is what the prototype is for.
|
|
5
|
-
*/
|
|
6
|
-
import type { ThingKind } from '../KindIcon';
|
|
7
|
-
/** The colours a status draws in, as the apps' manifests name them. */
|
|
8
|
-
export type StatusColour = 'neutral' | 'blue' | 'green' | 'muted';
|
|
9
|
-
export interface Status {
|
|
10
|
-
label: string;
|
|
11
|
-
colour: StatusColour;
|
|
12
|
-
}
|
|
13
|
-
/** One thing a link can stand for, with every field any app draws today. */
|
|
14
|
-
export interface Thing {
|
|
15
|
-
/** The kinds the prototype covers, one more than KindIcon has: a page. */
|
|
16
|
-
kind: ThingKind | 'page';
|
|
17
|
-
/** The noun a card's corner says. */
|
|
18
|
-
noun: string;
|
|
19
|
-
/** The app it opens in. */
|
|
20
|
-
app: string;
|
|
21
|
-
title: string;
|
|
22
|
-
/** Its key, the way people say it: an issue's "WID-2". */
|
|
23
|
-
key?: string;
|
|
24
|
-
/** The line under the title: the project an issue is in, a page's Folder. */
|
|
25
|
-
subtitle?: string;
|
|
26
|
-
/** The opening of its description, a page's text, a message's words: what the apps draw today. */
|
|
27
|
-
body?: string;
|
|
28
|
-
/**
|
|
29
|
-
* A short summary of the file, one or two sentences (Miky, 15 Oct: detailed
|
|
30
|
-
* shows the summary, not the opening of the long description). No file
|
|
31
|
-
* carries one yet; it is its own project.
|
|
32
|
-
*/
|
|
33
|
-
summary?: string;
|
|
34
|
-
status?: Status;
|
|
35
|
-
assignee?: string;
|
|
36
|
-
author?: string;
|
|
37
|
-
/** Everyone who wrote a page. */
|
|
38
|
-
authors?: string[];
|
|
39
|
-
comments?: number;
|
|
40
|
-
/**
|
|
41
|
-
* The reader has something unread in its conversation: they are a member
|
|
42
|
-
* and it moved since they last read it (SPEC §11.8, membership-replaces-following).
|
|
43
|
-
*/
|
|
44
|
-
unread?: boolean;
|
|
45
|
-
/** A project's issues, drawn as rows inside its detailed card. */
|
|
46
|
-
children?: {
|
|
47
|
-
title: string;
|
|
48
|
-
key: string;
|
|
49
|
-
status: Status;
|
|
50
|
-
assignee?: string;
|
|
51
|
-
}[];
|
|
52
|
-
/** A project's progress line. */
|
|
53
|
-
progress?: string;
|
|
54
|
-
/** A project's progress as numbers, for the ring. */
|
|
55
|
-
done?: {
|
|
56
|
-
done: number;
|
|
57
|
-
total: number;
|
|
58
|
-
};
|
|
59
|
-
/** A topic: how many conversations, who is in it, and its latest one. */
|
|
60
|
-
conversations?: number;
|
|
61
|
-
members?: string[];
|
|
62
|
-
latest?: {
|
|
63
|
-
author: string;
|
|
64
|
-
body: string;
|
|
65
|
-
at: string;
|
|
66
|
-
};
|
|
67
|
-
updated?: string;
|
|
68
|
-
/** Where it is placed (WID-3): still loading, or not available to this reader. Ready when absent. */
|
|
69
|
-
state?: 'loading' | 'unavailable';
|
|
70
|
-
}
|
|
71
|
-
export declare const ISSUE: Thing;
|
|
72
|
-
export declare const PROJECT: Thing;
|
|
73
|
-
export declare const TOPIC: Thing;
|
|
74
|
-
export declare const MESSAGE: Thing;
|
|
75
|
-
export declare const PAGE: Thing;
|
|
76
|
-
/** A block of a description: drawn live, as the part it is. */
|
|
77
|
-
export declare const PART: {
|
|
78
|
-
heading: string;
|
|
79
|
-
noun: string;
|
|
80
|
-
app: string;
|
|
81
|
-
blocks: string[];
|
|
82
|
-
};
|
|
83
|
-
export declare const ATTACHMENT: {
|
|
84
|
-
name: string;
|
|
85
|
-
size: number;
|
|
86
|
-
contentType: string;
|
|
87
|
-
};
|
|
88
|
-
export declare const ATTACHMENT_FILE: {
|
|
89
|
-
name: string;
|
|
90
|
-
size: number;
|
|
91
|
-
contentType: string;
|
|
92
|
-
};
|
|
93
|
-
/** A file the reader cannot read: only its kind and app are known, from its address. */
|
|
94
|
-
export declare const UNREADABLE: {
|
|
95
|
-
kind: "issue";
|
|
96
|
-
noun: string;
|
|
97
|
-
app: string;
|
|
98
|
-
address: string;
|
|
99
|
-
};
|
|
100
|
-
/** A small picture for the attachment, drawn rather than fetched. */
|
|
101
|
-
export declare const PICTURE: string;
|
|
102
|
-
//# sourceMappingURL=fixtures.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../../src/widgets-2/fixtures.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAE5C,uEAAuE;AACvE,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAA;AAEjE,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,YAAY,CAAA;CACrB;AAED,4EAA4E;AAC5E,MAAM,WAAW,KAAK;IACpB,0EAA0E;IAC1E,IAAI,EAAE,SAAS,GAAG,MAAM,CAAA;IACxB,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAA;IACZ,2BAA2B;IAC3B,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,0DAA0D;IAC1D,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,kGAAkG;IAClG,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,iCAAiC;IACjC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,kEAAkE;IAClE,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAC9E,iCAAiC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,qDAAqD;IACrD,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;IACtC,yEAAyE;IACzE,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,MAAM,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;IACrD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,qGAAqG;IACrG,KAAK,CAAC,EAAE,SAAS,GAAG,aAAa,CAAA;CAClC;AAWD,eAAO,MAAM,KAAK,EAAE,KAanB,CAAA;AAED,eAAO,MAAM,OAAO,EAAE,KAiBrB,CAAA;AAED,eAAO,MAAM,KAAK,EAAE,KAUnB,CAAA;AAED,eAAO,MAAM,OAAO,EAAE,KAQrB,CAAA;AAED,eAAO,MAAM,IAAI,EAAE,KAYlB,CAAA;AAED,+DAA+D;AAC/D,eAAO,MAAM,IAAI;;;;;CAKhB,CAAA;AAED,eAAO,MAAM,UAAU;;;;CAAuE,CAAA;AAC9F,eAAO,MAAM,eAAe;;;;CAAgF,CAAA;AAE5G,wFAAwF;AACxF,eAAO,MAAM,UAAU;;;;;CAAiH,CAAA;AAExI,qEAAqE;AACrE,eAAO,MAAM,OAAO,QAIjB,CAAA"}
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { type ReactNode } from 'react';
|
|
2
|
-
import type { Thing } from './fixtures';
|
|
3
|
-
/** A piece of a sentence: words, or a link to a file. */
|
|
4
|
-
export type Piece = string | Thing;
|
|
5
|
-
/** One line of text: a link alone on its line, or a sentence of words and links. */
|
|
6
|
-
export type Line = Thing | Piece[];
|
|
7
|
-
/** Every file the lines link to, each once. */
|
|
8
|
-
export declare function linksIn(lines: Line[]): Thing[];
|
|
9
|
-
/** The file whose card goes under a message: the one it links. None when it links two or more. */
|
|
10
|
-
export declare function cardFileOf(lines: Line[]): Thing | undefined;
|
|
11
|
-
/** A message that is nothing but one link: it shows the card, not the row. */
|
|
12
|
-
export declare function isOnlyOneLink(lines: Line[]): boolean;
|
|
13
|
-
/** A file's card: a linked message draws as a message, every other file as its detailed card; loading and not available as the proposed kit draws them. */
|
|
14
|
-
export declare function CardOf({ thing }: {
|
|
15
|
-
thing: Thing;
|
|
16
|
-
}): import("react").JSX.Element;
|
|
17
|
-
export interface PlacedLinesProps {
|
|
18
|
-
lines: Line[];
|
|
19
|
-
/** In a document: the lone-line links switched to their card, by line index. */
|
|
20
|
-
cards?: number[];
|
|
21
|
-
/** In a document: a click on a lone-line link, which opens its chip menu. */
|
|
22
|
-
onLink?: (index: number) => void;
|
|
23
|
-
/** Drawn under a line, by line index: the chip menu, open. */
|
|
24
|
-
under?: (index: number) => ReactNode;
|
|
25
|
-
className?: string;
|
|
26
|
-
}
|
|
27
|
-
/** Text whose links draw by where they sit: a chip in a sentence, a row alone on its line, or (in a document) the card chosen for that line. */
|
|
28
|
-
export declare function PlacedLines({ lines, cards, onLink, under, className }: PlacedLinesProps): import("react").JSX.Element;
|
|
29
|
-
export interface CardUnderProps {
|
|
30
|
-
thing: Thing;
|
|
31
|
-
/** The ✕ that removes it: under the message box before sending, or the author's own on a sent message. */
|
|
32
|
-
onRemove?: () => void;
|
|
33
|
-
/** On a sent message the ✕ shows on hover; under the box it always shows. */
|
|
34
|
-
removeOnHover?: boolean;
|
|
35
|
-
className?: string;
|
|
36
|
-
}
|
|
37
|
-
/** The one file's card under a message, and the ✕ that removes it. */
|
|
38
|
-
export declare function CardUnder({ thing, onRemove, removeOnHover, className }: CardUnderProps): import("react").JSX.Element;
|
|
39
|
-
export interface PlacedMessageProps {
|
|
40
|
-
lines: Line[];
|
|
41
|
-
/** The card was removed with ✕: before sending, or by the author afterwards. */
|
|
42
|
-
removed?: boolean;
|
|
43
|
-
/** Draws the ✕; without it the card shows with none, as to anyone but the author. */
|
|
44
|
-
onRemove?: () => void;
|
|
45
|
-
removeOnHover?: boolean;
|
|
46
|
-
/**
|
|
47
|
-
* An old message, sent before Widgets 2 with a `compact` tag for each of
|
|
48
|
-
* these: no card was added to it, and each still draws as a row under it.
|
|
49
|
-
*/
|
|
50
|
-
oldCompact?: Thing[];
|
|
51
|
-
className?: string;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* A message's text, and under it the one file's card. A file with its card
|
|
55
|
-
* under the message draws no row in it (a chip in a sentence still draws), so
|
|
56
|
-
* a message that is only one link shows its card alone.
|
|
57
|
-
*/
|
|
58
|
-
export declare function PlacedMessage({ lines, removed, onRemove, removeOnHover, oldCompact, className }: PlacedMessageProps): import("react").JSX.Element;
|
|
59
|
-
/** A sent message whose author can remove its card with ✕, live: try it. */
|
|
60
|
-
export declare function SentMessage({ lines, author, className }: {
|
|
61
|
-
lines: Line[];
|
|
62
|
-
author?: boolean;
|
|
63
|
-
className?: string;
|
|
64
|
-
}): import("react").JSX.Element;
|
|
65
|
-
export interface ChipMenuProps {
|
|
66
|
-
thing: Thing;
|
|
67
|
-
/**
|
|
68
|
-
* A lone-line link offers its card; a chip in a sentence offers Open only,
|
|
69
|
-
* and so does a link to what has no card worth choosing (a Folder, a file
|
|
70
|
-
* that is not a picture).
|
|
71
|
-
*/
|
|
72
|
-
alone?: boolean;
|
|
73
|
-
shownAs?: 'row' | 'card';
|
|
74
|
-
onShowAs?: (as: 'row' | 'card') => void;
|
|
75
|
-
onOpen?: () => void;
|
|
76
|
-
}
|
|
77
|
-
/** What a link in a document offers its writer: Open, and on a lone-line link of a kind that has one, its card in that line's place. */
|
|
78
|
-
export declare function ChipMenu({ thing, alone, shownAs, onShowAs, onOpen }: ChipMenuProps): import("react").JSX.Element;
|
|
79
|
-
/** A document's text with its chip menu, live: click a lone-line link, then choose Row or Card. */
|
|
80
|
-
export declare function PlacedDocument({ lines, initialCards, className }: {
|
|
81
|
-
lines: Line[];
|
|
82
|
-
initialCards?: number[];
|
|
83
|
-
className?: string;
|
|
84
|
-
}): import("react").JSX.Element;
|
|
85
|
-
/**
|
|
86
|
-
* A description's and a page's `/` menu with the widget entry (Miky's QA note,
|
|
87
|
-
* 15 Oct: "`/` section where you can use `[` to insert a widget"). Format rows
|
|
88
|
-
* shortened to three; Insert as the app has it, plus the link.
|
|
89
|
-
*/
|
|
90
|
-
export declare function SlashMenuWithLink({ file, table }: {
|
|
91
|
-
file?: boolean;
|
|
92
|
-
table?: boolean;
|
|
93
|
-
}): import("react").JSX.Element;
|
|
94
|
-
/** The `[` list the widget entry opens: the files to link, each led by its kind's icon. */
|
|
95
|
-
export declare function LinkPicker({ files, query }: {
|
|
96
|
-
files: Thing[];
|
|
97
|
-
query?: string;
|
|
98
|
-
}): import("react").JSX.Element;
|
|
99
|
-
//# sourceMappingURL=places.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"places.d.ts","sourceRoot":"","sources":["../../src/widgets-2/places.tsx"],"names":[],"mappings":"AAwBA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAIhD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAGvC,yDAAyD;AACzD,MAAM,MAAM,KAAK,GAAG,MAAM,GAAG,KAAK,CAAA;AAClC,oFAAoF;AACpF,MAAM,MAAM,IAAI,GAAG,KAAK,GAAG,KAAK,EAAE,CAAA;AAIlC,+CAA+C;AAC/C,wBAAgB,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,EAAE,CAE9C;AAED,kGAAkG;AAClG,wBAAgB,UAAU,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,GAAG,SAAS,CAG3D;AAED,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,OAAO,CAEpD;AAED,2JAA2J;AAC3J,wBAAgB,MAAM,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,KAAK,CAAA;CAAE,+BAIjD;AAkBD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,IAAI,EAAE,CAAA;IACb,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAChC,8DAA8D;IAC9D,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,SAAS,CAAA;IACpC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,gJAAgJ;AAChJ,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,KAAU,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,gBAAgB,+BAqC5F;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,KAAK,CAAA;IACZ,0GAA0G;IAC1G,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,sEAAsE;AACtE,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,aAAqB,EAAE,SAAS,EAAE,EAAE,cAAc,+BAgB9F;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,IAAI,EAAE,CAAA;IACb,gFAAgF;IAChF,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,qFAAqF;IACrF,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB;;;OAGG;IACH,UAAU,CAAC,EAAE,KAAK,EAAE,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,OAAe,EAAE,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,kBAAkB,+BAY3H;AAED,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,MAAa,EAAE,SAAS,EAAE,EAAE;IAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAGvH;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,KAAK,CAAA;IACZ;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,OAAO,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;IACxB,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,KAAK,GAAG,MAAM,KAAK,IAAI,CAAA;IACvC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;CACpB;AAED,wIAAwI;AACxI,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,KAAY,EAAE,OAAe,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,aAAa,+BA2BjG;AAED,mGAAmG;AACnG,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,YAAiB,EAAE,SAAS,EAAE,EAAE;IAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BA4BrI;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,IAAW,EAAE,KAAY,EAAE,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,+BAkBnG;AAED,2FAA2F;AAC3F,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,KAAU,EAAE,EAAE;IAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,+BAYnF"}
|