@estiva-app/ui 0.72.0-widgets2.2 → 0.73.0-inline-text.1
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/InlineText.d.ts +56 -0
- package/dist/InlineText.d.ts.map +1 -0
- package/dist/SelectionToolbar.d.ts +17 -1
- package/dist/SelectionToolbar.d.ts.map +1 -1
- package/dist/editor.d.ts +4 -1
- package/dist/editor.d.ts.map +1 -1
- package/dist/editor.js +748 -240
- 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 +403 -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/InlineText.mdx +64 -0
- package/src/InlineText.stories.tsx +86 -0
- package/src/InlineText.test.tsx +187 -0
- package/src/InlineText.tsx +187 -0
- package/src/SelectionToolbar.actions.test.tsx +44 -0
- package/src/SelectionToolbar.mdx +1 -0
- package/src/SelectionToolbar.tsx +36 -2
- package/src/editor.ts +16 -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 +3 -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 -105
- 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 -585
- package/dist/widgets-2.js.map +0 -7
- package/src/widgets-2/fixtures.ts +0 -161
- package/src/widgets-2/places.tsx +0 -316
- 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,187 @@
|
|
|
1
|
+
import { useCallback, useEffect, useImperativeHandle, useRef, useState, type Ref } from 'react'
|
|
2
|
+
import { Extension, Node } from '@tiptap/core'
|
|
3
|
+
import { history, redo, undo } from '@tiptap/pm/history'
|
|
4
|
+
import { EditorContent, useEditor } from '@tiptap/react'
|
|
5
|
+
import { cn } from './cn'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A line of plain text on a page that you edit where it stands, as in a
|
|
9
|
+
* document: a title, a summary. Ship's title editor (Katerina, 29 September,
|
|
10
|
+
* findings E1 and E2), moved here for the summary (Miky, 16 October: "it feels
|
|
11
|
+
* like a document, not a form") so every app's header edits the same way.
|
|
12
|
+
*
|
|
13
|
+
* - **No box**, on hover or on click, and nothing moves: the text is the
|
|
14
|
+
* editor, in its own size and colour. The text cursor is the only sign.
|
|
15
|
+
* - **The caret goes where you click**, and nothing is selected.
|
|
16
|
+
* - **Enter saves and moves on** — `onEnter` says where: the title to the
|
|
17
|
+
* summary, the summary to the description.
|
|
18
|
+
* - **Escape stops editing and keeps the text**, saving it, as leaving does.
|
|
19
|
+
* Nothing is thrown away; Ctrl+Z undoes.
|
|
20
|
+
* - **An unchanged value is not a write.** Leaving it empty brings the saved
|
|
21
|
+
* one back, unless `clearable`: then empty is saved, as nothing.
|
|
22
|
+
* - **A refused save keeps your text where it is**, and the app says why
|
|
23
|
+
* beside it; a change made elsewhere does not overwrite it until you have
|
|
24
|
+
* saved, changed or emptied it.
|
|
25
|
+
*
|
|
26
|
+
* One paragraph and no marks, so pasted line breaks become spaces and it wraps
|
|
27
|
+
* like text, which a one-line `<input>` cannot. A Tiptap editor rather than a
|
|
28
|
+
* raw `contenteditable`, so it is the same kind of surface as the description
|
|
29
|
+
* under it.
|
|
30
|
+
*/
|
|
31
|
+
export interface InlineTextProps {
|
|
32
|
+
/** The saved text. A new value is loaded when you are not in the field and hold nothing unsaved. */
|
|
33
|
+
value: string
|
|
34
|
+
/** What it is for, muted, while it is empty: "Untitled", "Add a summary". */
|
|
35
|
+
placeholder: string
|
|
36
|
+
/** The accessible name: "Title", "Summary". */
|
|
37
|
+
label: string
|
|
38
|
+
/** Save it: resolve `true` when saved; `false` keeps your text in place. */
|
|
39
|
+
onCommit: (value: string) => Promise<boolean> | boolean
|
|
40
|
+
/** The text as it is being written, on focus and every change; `null` when you leave. For a count. */
|
|
41
|
+
onText?: (text: string | null) => void
|
|
42
|
+
/** Enter, after the save has started: where the caret goes next. */
|
|
43
|
+
onEnter?: () => void
|
|
44
|
+
/** `title`: the page's heading. `summary`: the line under it, quieter. */
|
|
45
|
+
variant?: 'title' | 'summary'
|
|
46
|
+
/** Empty is a value (a summary). Otherwise leaving it empty brings the saved one back (a title). */
|
|
47
|
+
clearable?: boolean
|
|
48
|
+
/** Text only, the same size and place: nobody can change it, or the editor is not ready. */
|
|
49
|
+
readOnly?: boolean
|
|
50
|
+
/** Placement only. */
|
|
51
|
+
className?: string
|
|
52
|
+
ref?: Ref<InlineTextHandle>
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
type CaretAt = 'start' | 'end'
|
|
56
|
+
|
|
57
|
+
export interface InlineTextHandle {
|
|
58
|
+
/** Put the caret in it, at the start or the end. */
|
|
59
|
+
focus: (at?: CaretAt) => void
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Size and tone, per variant: the same for the text at rest and while it is written. */
|
|
63
|
+
const VARIANT = {
|
|
64
|
+
title: 'text-h2 text-text-primary',
|
|
65
|
+
summary: 'text-body-1 text-text-secondary',
|
|
66
|
+
} as const
|
|
67
|
+
|
|
68
|
+
/** The room around the text: the caret has a little space at the edges, and the text still lines up with what is above and below it. */
|
|
69
|
+
const ROOM = '-mx-2 px-2 py-1'
|
|
70
|
+
|
|
71
|
+
// The whole schema: one paragraph of text. Written with the core, so the
|
|
72
|
+
// package's peers stay what they were.
|
|
73
|
+
const OneLine = Node.create({ name: 'doc', topNode: true, content: 'paragraph' })
|
|
74
|
+
const Paragraph = Node.create({
|
|
75
|
+
name: 'paragraph',
|
|
76
|
+
content: 'text*',
|
|
77
|
+
parseHTML: () => [{ tag: 'p' }],
|
|
78
|
+
renderHTML: () => ['p', 0],
|
|
79
|
+
})
|
|
80
|
+
const Text = Node.create({ name: 'text' })
|
|
81
|
+
const Undo = Extension.create({
|
|
82
|
+
name: 'inlineTextUndo',
|
|
83
|
+
addProseMirrorPlugins: () => [history()],
|
|
84
|
+
addKeyboardShortcuts() {
|
|
85
|
+
const run = (command: typeof undo) => () => command(this.editor.state, this.editor.view.dispatch)
|
|
86
|
+
return { 'Mod-z': run(undo), 'Shift-Mod-z': run(redo), 'Mod-y': run(redo) }
|
|
87
|
+
},
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
const doc = (text: string) => ({ type: 'doc', content: [{ type: 'paragraph', content: text ? [{ type: 'text', text }] : [] }] })
|
|
91
|
+
|
|
92
|
+
/** One line: every run of white space, line breaks included, is one space. */
|
|
93
|
+
const oneLine = (text: string) => text.replace(/\s+/g, ' ').trim()
|
|
94
|
+
|
|
95
|
+
export function InlineText({ value, placeholder, label, onCommit, onText, onEnter, variant = 'title', clearable = false, readOnly = false, className, ref }: InlineTextProps) {
|
|
96
|
+
const saved = useRef(value)
|
|
97
|
+
// The placeholder follows the text as it is typed or deleted, not the saved value.
|
|
98
|
+
const [empty, setEmpty] = useState(!value)
|
|
99
|
+
// Read at key time: the editor's handlers are built once, and a prop they
|
|
100
|
+
// closed over would be the first render's.
|
|
101
|
+
const latest = useRef({ onEnter, onText, onCommit, clearable })
|
|
102
|
+
latest.current = { onEnter, onText, onCommit, clearable }
|
|
103
|
+
|
|
104
|
+
const save = useCallback(async (text: string) => {
|
|
105
|
+
const next = oneLine(text)
|
|
106
|
+
if (next === saved.current) return
|
|
107
|
+
if (!next && !latest.current.clearable) return
|
|
108
|
+
if (await latest.current.onCommit(next)) saved.current = next
|
|
109
|
+
}, [])
|
|
110
|
+
|
|
111
|
+
const editor = useEditor({
|
|
112
|
+
extensions: [OneLine, Paragraph, Text, Undo],
|
|
113
|
+
content: doc(value),
|
|
114
|
+
editable: !readOnly,
|
|
115
|
+
editorProps: {
|
|
116
|
+
attributes: {
|
|
117
|
+
'aria-label': label,
|
|
118
|
+
role: 'textbox',
|
|
119
|
+
'aria-multiline': 'false',
|
|
120
|
+
'aria-placeholder': placeholder,
|
|
121
|
+
...(readOnly ? { 'aria-readonly': 'true' } : {}),
|
|
122
|
+
class: 'outline-none',
|
|
123
|
+
},
|
|
124
|
+
handleKeyDown: (view, event) => {
|
|
125
|
+
if (event.key === 'Enter') {
|
|
126
|
+
event.preventDefault()
|
|
127
|
+
void save(view.state.doc.textContent)
|
|
128
|
+
latest.current.onEnter?.()
|
|
129
|
+
return true
|
|
130
|
+
}
|
|
131
|
+
if (event.key === 'Escape') {
|
|
132
|
+
view.dom.blur()
|
|
133
|
+
return true
|
|
134
|
+
}
|
|
135
|
+
return false
|
|
136
|
+
},
|
|
137
|
+
// A paste is its plain text on this one line, whatever it was copied from.
|
|
138
|
+
handlePaste: (view, event) => {
|
|
139
|
+
const text = event.clipboardData?.getData('text/plain')
|
|
140
|
+
if (text == null) return false
|
|
141
|
+
view.dispatch(view.state.tr.insertText(text.replace(/\s+/g, ' ')))
|
|
142
|
+
return true
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
onFocus: ({ editor: e }) => latest.current.onText?.(e.getText()),
|
|
146
|
+
onUpdate: ({ editor: e }) => {
|
|
147
|
+
setEmpty(e.isEmpty)
|
|
148
|
+
latest.current.onText?.(e.getText())
|
|
149
|
+
},
|
|
150
|
+
onBlur: ({ editor: e }) => {
|
|
151
|
+
latest.current.onText?.(null)
|
|
152
|
+
// Left empty where empty is not a value: the saved text comes back, so
|
|
153
|
+
// the page never shows the placeholder while everyone else sees the text.
|
|
154
|
+
if (e.isEmpty && saved.current && !latest.current.clearable) {
|
|
155
|
+
e.commands.setContent(doc(saved.current), { emitUpdate: false })
|
|
156
|
+
setEmpty(false)
|
|
157
|
+
return
|
|
158
|
+
}
|
|
159
|
+
void save(e.getText())
|
|
160
|
+
},
|
|
161
|
+
}, [readOnly])
|
|
162
|
+
|
|
163
|
+
// A change made elsewhere is loaded while you are not in the field and hold
|
|
164
|
+
// nothing unsaved; your own save coming back is left alone.
|
|
165
|
+
useEffect(() => {
|
|
166
|
+
if (!editor || editor.isDestroyed || value === saved.current || editor.isFocused) return
|
|
167
|
+
if (oneLine(editor.getText()) !== saved.current) return
|
|
168
|
+
editor.commands.setContent(doc(value), { emitUpdate: false })
|
|
169
|
+
saved.current = value
|
|
170
|
+
setEmpty(!value)
|
|
171
|
+
}, [editor, value])
|
|
172
|
+
|
|
173
|
+
useImperativeHandle(ref, () => ({
|
|
174
|
+
focus: (at = 'start') => editor?.commands.focus(at),
|
|
175
|
+
}), [editor])
|
|
176
|
+
|
|
177
|
+
return (
|
|
178
|
+
<div className={cn('relative', VARIANT[variant], className)}>
|
|
179
|
+
<EditorContent editor={editor} className={cn(ROOM, !readOnly && 'cursor-text')} />
|
|
180
|
+
{/* Empty — never saved, or just deleted — shows what it is for, muted,
|
|
181
|
+
and is not part of the text. Drawn over the editor, where the text starts. */}
|
|
182
|
+
{empty && !readOnly && (
|
|
183
|
+
<span aria-hidden className="pointer-events-none absolute left-0 top-1 text-text-muted">{placeholder}</span>
|
|
184
|
+
)}
|
|
185
|
+
</div>
|
|
186
|
+
)
|
|
187
|
+
}
|
|
@@ -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,22 @@
|
|
|
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 { InlineText, type InlineTextProps, type InlineTextHandle } from './InlineText'
|
|
13
|
+
export {
|
|
14
|
+
CommentHighlights,
|
|
15
|
+
setCommentAnchors,
|
|
16
|
+
commentPlace,
|
|
17
|
+
commentElement,
|
|
18
|
+
anchorOfSelection,
|
|
19
|
+
quoteText,
|
|
20
|
+
type CommentAnchor,
|
|
21
|
+
type CommentHighlightsOptions,
|
|
22
|
+
type CommentPlace,
|
|
23
|
+
type CommentQuote,
|
|
24
|
+
type SelectionAnchor,
|
|
25
|
+
} from './CommentHighlights'
|
|
11
26
|
export { PastedImages, pastedImages, pastedImageName, type PastedImagesOptions, type ClipboardSource } from './PastedImages'
|
|
12
27
|
export { PastedMarkdown, type PastedMarkdownOptions } from './PastedMarkdown'
|
|
13
28
|
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 178 names over 84 files: 119 components, 57 helpers and 2 hooks (InlineText, a title or the line under it edited where it stands (SUM-4), on 16 October; 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: 119, helper: 57, hook: 2 })
|
|
58
|
+
expect(new Set(registry.entries.map((one) => one.sourceFile)).size).toBe(84)
|
|
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(80)
|
|
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,9 @@ 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
|
+
| A page's title or the line under it, edited where it stands, as in a document | **InlineText**, from `@estiva-app/ui/editor` — no box; Enter saves and moves on |
|
|
76
|
+
| 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` |
|
|
77
|
+
| 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
78
|
| 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
79
|
| Add or delete a table's rows and columns in a document being edited | **EditorTableControls**, from `@estiva-app/ui/editor`, inside the EditorBlockHandle |
|
|
77
80
|
| 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,105 +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
|
-
/**
|
|
52
|
-
* The file whose page this message is read on, as under "Mentioned in": it
|
|
53
|
-
* gets no card, since you are already on it; its chip and row still draw
|
|
54
|
-
* (Miky, 15 Oct, WID-3).
|
|
55
|
-
*/
|
|
56
|
-
here?: Thing;
|
|
57
|
-
className?: string;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* A message's text, and under it the one file's card. A file with its card
|
|
61
|
-
* under the message draws no row in it (a chip in a sentence still draws), so
|
|
62
|
-
* a message that is only one link shows its card alone.
|
|
63
|
-
*/
|
|
64
|
-
export declare function PlacedMessage({ lines, removed, onRemove, removeOnHover, oldCompact, here, className }: PlacedMessageProps): import("react").JSX.Element;
|
|
65
|
-
/** A sent message whose author can remove its card with ✕, live: try it. */
|
|
66
|
-
export declare function SentMessage({ lines, author, className }: {
|
|
67
|
-
lines: Line[];
|
|
68
|
-
author?: boolean;
|
|
69
|
-
className?: string;
|
|
70
|
-
}): import("react").JSX.Element;
|
|
71
|
-
export interface ChipMenuProps {
|
|
72
|
-
thing: Thing;
|
|
73
|
-
/**
|
|
74
|
-
* A lone-line link offers its card; a chip in a sentence offers Open only,
|
|
75
|
-
* and so does a link to what has no card worth choosing (a Folder, a file
|
|
76
|
-
* that is not a picture).
|
|
77
|
-
*/
|
|
78
|
-
alone?: boolean;
|
|
79
|
-
shownAs?: 'row' | 'card';
|
|
80
|
-
onShowAs?: (as: 'row' | 'card') => void;
|
|
81
|
-
onOpen?: () => void;
|
|
82
|
-
}
|
|
83
|
-
/** 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. */
|
|
84
|
-
export declare function ChipMenu({ thing, alone, shownAs, onShowAs, onOpen }: ChipMenuProps): import("react").JSX.Element;
|
|
85
|
-
/** A document's text with its chip menu, live: click a lone-line link, then choose Row or Card. */
|
|
86
|
-
export declare function PlacedDocument({ lines, initialCards, className }: {
|
|
87
|
-
lines: Line[];
|
|
88
|
-
initialCards?: number[];
|
|
89
|
-
className?: string;
|
|
90
|
-
}): import("react").JSX.Element;
|
|
91
|
-
/**
|
|
92
|
-
* A description's and a page's `/` menu with the widget entry (Miky's QA note,
|
|
93
|
-
* 15 Oct: "`/` section where you can use `[` to insert a widget"). Format rows
|
|
94
|
-
* shortened to three; Insert as the app has it, plus the link.
|
|
95
|
-
*/
|
|
96
|
-
export declare function SlashMenuWithLink({ file, table }: {
|
|
97
|
-
file?: boolean;
|
|
98
|
-
table?: boolean;
|
|
99
|
-
}): import("react").JSX.Element;
|
|
100
|
-
/** The `[` list the widget entry opens: the files to link, each led by its kind's icon. */
|
|
101
|
-
export declare function LinkPicker({ files, query }: {
|
|
102
|
-
files: Thing[];
|
|
103
|
-
query?: string;
|
|
104
|
-
}): import("react").JSX.Element;
|
|
105
|
-
//# sourceMappingURL=places.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"places.d.ts","sourceRoot":"","sources":["../../src/widgets-2/places.tsx"],"names":[],"mappings":"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"}
|