@formicoidea/labre-core 0.39.1 → 0.40.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/_pkgs/affine-block-callout/emoji-margin.js +19 -11
- package/dist/_pkgs/affine-block-list/list-block.d.ts +8 -1
- package/dist/_pkgs/affine-block-list/list-block.js +27 -17
- package/dist/_pkgs/affine-block-note/configs/tooltips.d.ts +16 -0
- package/dist/_pkgs/affine-block-note/configs/tooltips.js +99 -66
- package/dist/_pkgs/affine-block-paragraph/paragraph-block.d.ts +8 -1
- package/dist/_pkgs/affine-block-paragraph/paragraph-block.js +30 -15
- package/dist/_pkgs/affine-block-paragraph/styles.js +30 -83
- package/dist/_pkgs/affine-block-paragraph/turbo/paragraph-layout-handler.js +1 -0
- package/dist/_pkgs/affine-block-paragraph/turbo/paragraph-painter.worker.d.ts +2 -0
- package/dist/_pkgs/affine-block-paragraph/turbo/paragraph-painter.worker.js +6 -1
- package/dist/_pkgs/affine-block-root/edgeless/clipboard/clipboard.js +3 -3
- package/dist/_pkgs/affine-block-root/keyboard/keymap.js +20 -0
- package/dist/_pkgs/affine-block-surface/extensions/export-manager/export-manager.d.ts +6 -4
- package/dist/_pkgs/affine-block-surface/extensions/export-manager/export-manager.js +15 -10
- package/dist/_pkgs/affine-block-surface/framework-background/def.d.ts +4 -1
- package/dist/_pkgs/affine-block-surface/framework-background/def.js +6 -2
- package/dist/_pkgs/affine-block-surface/utils/priority-queue.js +2 -2
- package/dist/_pkgs/affine-components/toggle-button/toggle-button.d.ts +5 -0
- package/dist/_pkgs/affine-components/toggle-button/toggle-button.js +31 -18
- package/dist/_pkgs/affine-gfx-template/builtin/other.js +31 -14
- package/dist/_pkgs/affine-inline-preset/markdown.d.ts +3 -0
- package/dist/_pkgs/affine-inline-preset/markdown.js +19 -0
- package/dist/_pkgs/affine-shared/adapters/middlewares/proxy.d.ts +10 -0
- package/dist/_pkgs/affine-shared/adapters/middlewares/proxy.js +19 -12
- package/dist/_pkgs/affine-shared/adapters/utils/fetch.js +4 -0
- package/dist/_pkgs/affine-shared/consts/heading.d.ts +29 -0
- package/dist/_pkgs/affine-shared/consts/heading.js +70 -0
- package/dist/_pkgs/affine-shared/consts/index.d.ts +2 -0
- package/dist/_pkgs/affine-shared/consts/index.js +2 -0
- package/dist/_pkgs/affine-shared/consts/notation.d.ts +67 -0
- package/dist/_pkgs/affine-shared/consts/notation.js +65 -0
- package/dist/_pkgs/std/gfx/model/surface/element-model.d.ts +2 -2
- package/dist/_pkgs/std/gfx/model/surface/element-model.js +2 -2
- package/dist/_pkgs/std/gfx/model/surface/surface-model.d.ts +1 -1
- package/dist/_pkgs/std/gfx/model/surface/surface-model.js +1 -1
- package/package.json +1 -1
|
@@ -1,22 +1,30 @@
|
|
|
1
1
|
import { ParagraphBlockModel, } from '../affine-model/index.js';
|
|
2
|
+
import { HEADING_LEVELS, HEADING_SCALE, headingLineBox, } from '../affine-shared/consts/index.js';
|
|
2
3
|
import { matchModels } from '../affine-shared/utils/index.js';
|
|
4
|
+
/** The emoji's box, px (`.affine-callout-emoji-container` in callout-block.ts). */
|
|
5
|
+
const EMOJI_BOX_PX = 24;
|
|
3
6
|
/**
|
|
4
|
-
*
|
|
7
|
+
* H1's bold caps read as sitting low when the emoji is centred on the line
|
|
8
|
+
* box mathematically; lifting the emoji by 1px levels it optically.
|
|
9
|
+
*/
|
|
10
|
+
const H1_OPTICAL_LIFT_PX = 1;
|
|
11
|
+
/**
|
|
12
|
+
* How far the emoji has to drop to sit level with the first line.
|
|
5
13
|
*
|
|
6
14
|
* The emoji is a fixed 24px box next to a column whose first line can be
|
|
7
15
|
* anything from an H1 to an ordinary paragraph. A single margin therefore
|
|
8
16
|
* cannot be right twice: level with a paragraph it floats above an H1, level
|
|
9
|
-
* with an H1 it sinks below a paragraph.
|
|
10
|
-
* heading
|
|
17
|
+
* with an H1 it sinks below a paragraph. Per heading level, the drop centres
|
|
18
|
+
* the emoji on the heading's first line box, below its margin-top:
|
|
19
|
+
* `marginTop + lineBox / 2 - emojiBox / 2`.
|
|
11
20
|
*/
|
|
12
|
-
const EMOJI_MARGIN_TOP_BY_TYPE = {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
};
|
|
21
|
+
const EMOJI_MARGIN_TOP_BY_TYPE = Object.fromEntries(HEADING_LEVELS.map(level => {
|
|
22
|
+
const centred = HEADING_SCALE[level].marginTop +
|
|
23
|
+
headingLineBox(level) / 2 -
|
|
24
|
+
EMOJI_BOX_PX / 2;
|
|
25
|
+
const drop = level === 'h1' ? centred - H1_OPTICAL_LIFT_PX : centred;
|
|
26
|
+
return [level, `${drop}px`];
|
|
27
|
+
}));
|
|
20
28
|
/** What a paragraph, a list, or an empty callout gets. */
|
|
21
29
|
const DEFAULT_EMOJI_MARGIN_TOP = '10px';
|
|
22
30
|
/**
|
|
@@ -6,6 +6,14 @@ import { type TemplateResult } from 'lit';
|
|
|
6
6
|
export declare class ListBlockComponent extends CaptionedBlockComponent<ListBlockModel> {
|
|
7
7
|
static styles: import("lit").CSSResult;
|
|
8
8
|
private _inlineRangeProvider;
|
|
9
|
+
/**
|
|
10
|
+
* The collapse state a READER holds locally. Same contract as
|
|
11
|
+
* `affine-paragraph`: a readonly document is never written, so the toggle
|
|
12
|
+
* carries the reader's own expansion here instead of in the model. A signal
|
|
13
|
+
* rather than a Lit `@state()`, so BlockSuite effects can depend on it.
|
|
14
|
+
*/
|
|
15
|
+
private readonly _readonlyCollapsed;
|
|
16
|
+
private _setReadonlyCollapsed;
|
|
9
17
|
private readonly _onClickIcon;
|
|
10
18
|
get attributeRenderer(): import("../std/inline/types.js").AttributeRenderer<import("../affine-shared/types/index.js").AffineTextAttributes>;
|
|
11
19
|
get attributesSchema(): import("zod").ZodType<any, import("zod").ZodTypeDef, any>;
|
|
@@ -16,7 +24,6 @@ export declare class ListBlockComponent extends CaptionedBlockComponent<ListBloc
|
|
|
16
24
|
connectedCallback(): void;
|
|
17
25
|
getUpdateComplete(): Promise<boolean>;
|
|
18
26
|
renderBlock(): TemplateResult<1>;
|
|
19
|
-
private accessor _readonlyCollapsed;
|
|
20
27
|
private accessor _richTextElement;
|
|
21
28
|
accessor blockContainerStyles: {
|
|
22
29
|
margin: string;
|
|
@@ -42,9 +42,9 @@ import { DocModeProvider } from '../affine-shared/services/index.js';
|
|
|
42
42
|
import { getViewportElement } from '../affine-shared/utils/index.js';
|
|
43
43
|
import { BlockSelection, TextSelection } from '../std/index.js';
|
|
44
44
|
import { getInlineRangeProvider, } from '../std/inline/index.js';
|
|
45
|
-
import { effect } from '@preact/signals-core';
|
|
45
|
+
import { effect, signal } from '@preact/signals-core';
|
|
46
46
|
import { html, nothing } from 'lit';
|
|
47
|
-
import { query
|
|
47
|
+
import { query } from 'lit/decorators.js';
|
|
48
48
|
import { classMap } from 'lit/directives/class-map.js';
|
|
49
49
|
import { styleMap } from 'lit/directives/style-map.js';
|
|
50
50
|
import { correctNumberedListsOrderToPrev } from './commands/utils.js';
|
|
@@ -52,9 +52,6 @@ import { listBlockStyles } from './styles.js';
|
|
|
52
52
|
import { getListIcon } from './utils/get-list-icon.js';
|
|
53
53
|
let ListBlockComponent = (() => {
|
|
54
54
|
let _classSuper = CaptionedBlockComponent;
|
|
55
|
-
let __readonlyCollapsed_decorators;
|
|
56
|
-
let __readonlyCollapsed_initializers = [];
|
|
57
|
-
let __readonlyCollapsed_extraInitializers = [];
|
|
58
55
|
let __richTextElement_decorators;
|
|
59
56
|
let __richTextElement_initializers = [];
|
|
60
57
|
let __richTextElement_extraInitializers = [];
|
|
@@ -62,12 +59,19 @@ let ListBlockComponent = (() => {
|
|
|
62
59
|
constructor() {
|
|
63
60
|
super(...arguments);
|
|
64
61
|
this._inlineRangeProvider = null;
|
|
62
|
+
/**
|
|
63
|
+
* The collapse state a READER holds locally. Same contract as
|
|
64
|
+
* `affine-paragraph`: a readonly document is never written, so the toggle
|
|
65
|
+
* carries the reader's own expansion here instead of in the model. A signal
|
|
66
|
+
* rather than a Lit `@state()`, so BlockSuite effects can depend on it.
|
|
67
|
+
*/
|
|
68
|
+
this._readonlyCollapsed = signal(false);
|
|
65
69
|
this._onClickIcon = (e) => {
|
|
66
70
|
e.stopPropagation();
|
|
67
71
|
e.preventDefault();
|
|
68
72
|
if (this.model.props.type === 'toggle') {
|
|
69
73
|
if (this.store.readonly) {
|
|
70
|
-
this.
|
|
74
|
+
this._setReadonlyCollapsed(!this._readonlyCollapsed.value);
|
|
71
75
|
}
|
|
72
76
|
else {
|
|
73
77
|
this.store.captureSync();
|
|
@@ -93,21 +97,22 @@ let ListBlockComponent = (() => {
|
|
|
93
97
|
}
|
|
94
98
|
this._select();
|
|
95
99
|
};
|
|
96
|
-
this.#
|
|
97
|
-
this.#_richTextElement_accessor_storage = (__runInitializers(this, __readonlyCollapsed_extraInitializers), __runInitializers(this, __richTextElement_initializers, null));
|
|
100
|
+
this.#_richTextElement_accessor_storage = __runInitializers(this, __richTextElement_initializers, null);
|
|
98
101
|
this.#blockContainerStyles_accessor_storage = (__runInitializers(this, __richTextElement_extraInitializers), {
|
|
99
102
|
margin: 'var(--affine-list-margin, 10px 0)',
|
|
100
103
|
});
|
|
101
104
|
}
|
|
102
105
|
static {
|
|
103
106
|
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
104
|
-
__readonlyCollapsed_decorators = [state()];
|
|
105
107
|
__richTextElement_decorators = [query('rich-text')];
|
|
106
|
-
__esDecorate(this, null, __readonlyCollapsed_decorators, { kind: "accessor", name: "_readonlyCollapsed", static: false, private: false, access: { has: obj => "_readonlyCollapsed" in obj, get: obj => obj._readonlyCollapsed, set: (obj, value) => { obj._readonlyCollapsed = value; } }, metadata: _metadata }, __readonlyCollapsed_initializers, __readonlyCollapsed_extraInitializers);
|
|
107
108
|
__esDecorate(this, null, __richTextElement_decorators, { kind: "accessor", name: "_richTextElement", static: false, private: false, access: { has: obj => "_richTextElement" in obj, get: obj => obj._richTextElement, set: (obj, value) => { obj._richTextElement = value; } }, metadata: _metadata }, __richTextElement_initializers, __richTextElement_extraInitializers);
|
|
108
109
|
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
109
110
|
}
|
|
110
111
|
static { this.styles = listBlockStyles; }
|
|
112
|
+
_setReadonlyCollapsed(collapsed) {
|
|
113
|
+
this._readonlyCollapsed.value = collapsed;
|
|
114
|
+
this.requestUpdate();
|
|
115
|
+
}
|
|
111
116
|
get attributeRenderer() {
|
|
112
117
|
return this.inlineManager.getRenderer();
|
|
113
118
|
}
|
|
@@ -137,9 +142,14 @@ let ListBlockComponent = (() => {
|
|
|
137
142
|
connectedCallback() {
|
|
138
143
|
super.connectedCallback();
|
|
139
144
|
this._inlineRangeProvider = getInlineRangeProvider(this);
|
|
145
|
+
// Only ENTERING readonly mode (or a later change of the persisted value)
|
|
146
|
+
// seeds the reader's local state; while readonly holds, the reader's own
|
|
147
|
+
// expansion is never overwritten. Aligned on `affine-paragraph`, where the
|
|
148
|
+
// unguarded version was a real defect (#262).
|
|
140
149
|
this.disposables.add(effect(() => {
|
|
141
|
-
|
|
142
|
-
|
|
150
|
+
if (this.store.readonly$.value) {
|
|
151
|
+
this._setReadonlyCollapsed(this.model.props.collapsed$.value);
|
|
152
|
+
}
|
|
143
153
|
}));
|
|
144
154
|
this.disposables.add(effect(() => {
|
|
145
155
|
const type = this.model.props.type$.value;
|
|
@@ -162,10 +172,12 @@ let ListBlockComponent = (() => {
|
|
|
162
172
|
renderBlock() {
|
|
163
173
|
const { model, _onClickIcon } = this;
|
|
164
174
|
const collapsed = this.store.readonly
|
|
165
|
-
? this._readonlyCollapsed
|
|
175
|
+
? this._readonlyCollapsed.value
|
|
166
176
|
: model.props.collapsed;
|
|
167
177
|
const listIcon = getListIcon(model, !collapsed, _onClickIcon);
|
|
178
|
+
const childrenId = `list-children-${this.model.id}`;
|
|
168
179
|
const children = html `<div
|
|
180
|
+
id=${childrenId}
|
|
169
181
|
class="affine-block-children-container"
|
|
170
182
|
style=${styleMap({
|
|
171
183
|
paddingLeft: `${BLOCK_CHILDREN_CONTAINER_PADDING_LEFT}px`,
|
|
@@ -187,9 +199,10 @@ let ListBlockComponent = (() => {
|
|
|
187
199
|
? html `
|
|
188
200
|
<blocksuite-toggle-button
|
|
189
201
|
.collapsed=${collapsed}
|
|
202
|
+
.controls=${childrenId}
|
|
190
203
|
.updateCollapsed=${(value) => {
|
|
191
204
|
if (this.store.readonly) {
|
|
192
|
-
this.
|
|
205
|
+
this._setReadonlyCollapsed(value);
|
|
193
206
|
}
|
|
194
207
|
else {
|
|
195
208
|
this.store.captureSync();
|
|
@@ -222,9 +235,6 @@ let ListBlockComponent = (() => {
|
|
|
222
235
|
</div>
|
|
223
236
|
`;
|
|
224
237
|
}
|
|
225
|
-
#_readonlyCollapsed_accessor_storage;
|
|
226
|
-
get _readonlyCollapsed() { return this.#_readonlyCollapsed_accessor_storage; }
|
|
227
|
-
set _readonlyCollapsed(value) { this.#_readonlyCollapsed_accessor_storage = value; }
|
|
228
238
|
#_richTextElement_accessor_storage;
|
|
229
239
|
get _richTextElement() { return this.#_richTextElement_accessor_storage; }
|
|
230
240
|
set _richTextElement(value) { this.#_richTextElement_accessor_storage = value; }
|
|
@@ -1,4 +1,20 @@
|
|
|
1
|
+
import { type HeadingLevel } from '../../affine-shared/consts/index.js';
|
|
1
2
|
import type { SlashMenuTooltip } from '../../affine-widget-slash-menu/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* The body lines of a heading preview that fit ENTIRELY in the frame, with the
|
|
5
|
+
* baseline each is set on.
|
|
6
|
+
*
|
|
7
|
+
* The body starts right under the heading's line box, so how many of its lines
|
|
8
|
+
* the card can show depends on the level: derived here from the geometry (line
|
|
9
|
+
* boxes, frame height, bottom padding) rather than tuned per level. At 10px on
|
|
10
|
+
* a 12px line, Inter's descenders end within a twentieth of a pixel of the line
|
|
11
|
+
* box's bottom edge, which the bottom padding covers: a line whose box fits is
|
|
12
|
+
* never clipped.
|
|
13
|
+
*/
|
|
14
|
+
export declare function headingPreviewBodyLines(level: HeadingLevel): {
|
|
15
|
+
y: number;
|
|
16
|
+
text: string;
|
|
17
|
+
}[];
|
|
2
18
|
export declare const BoldTextTooltip: import("lit-html").TemplateResult<1>;
|
|
3
19
|
export declare const ItalicTooltip: import("lit-html").TemplateResult<1>;
|
|
4
20
|
export declare const StrikethroughTooltip: import("lit-html").TemplateResult<1>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { HEADING_SCALE, headingLineBox, } from '../../affine-shared/consts/index.js';
|
|
2
|
+
import { html, svg } from 'lit';
|
|
2
3
|
// prettier-ignore
|
|
3
4
|
const TextTooltip = html `<svg width="170" height="68" viewBox="0 0 170 68" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
4
5
|
<rect width="170" height="68" rx="2" fill="white"/>
|
|
@@ -10,78 +11,110 @@ const TextTooltip = html `<svg width="170" height="68" viewBox="0 0 170 68" fill
|
|
|
10
11
|
</g>
|
|
11
12
|
</svg>
|
|
12
13
|
`;
|
|
14
|
+
/** The preview frame: every slash-menu figure is a 170×68 card. */
|
|
15
|
+
const PREVIEW_HEIGHT = 68;
|
|
16
|
+
/** Space above the first line of a preview, px. */
|
|
17
|
+
const PREVIEW_PADDING_TOP = 6;
|
|
18
|
+
/**
|
|
19
|
+
* Space a preview keeps free under its last line, px. A body line is drawn only
|
|
20
|
+
* if its whole line box ends above it, so no line is ever cut by the frame.
|
|
21
|
+
*/
|
|
22
|
+
const PREVIEW_PADDING_BOTTOM = 2;
|
|
23
|
+
/** The body text under a heading preview, shrunk to 10px on a 12px line. */
|
|
24
|
+
const BODY_FONT_SIZE = 10;
|
|
25
|
+
const BODY_LINE_HEIGHT = 12;
|
|
26
|
+
/** Extra space between two paragraphs of the body, px. */
|
|
27
|
+
const BODY_PARAGRAPH_GAP = 4;
|
|
28
|
+
/**
|
|
29
|
+
* The body, as the lines it is set in (the `text` preview's own wording). A
|
|
30
|
+
* paragraph ends with a newline, as the Figma export wrote it.
|
|
31
|
+
*/
|
|
32
|
+
const BODY_PARAGRAPHS = [
|
|
33
|
+
[
|
|
34
|
+
'In a decentralized system, we can have a kaleidoscopic ',
|
|
35
|
+
'complexity to our data.\n',
|
|
36
|
+
],
|
|
37
|
+
[
|
|
38
|
+
'Any user may have a different perspective on what data they ',
|
|
39
|
+
'either have, choose to share, or accept.\n',
|
|
40
|
+
],
|
|
41
|
+
[
|
|
42
|
+
'For example, one user\u2019s edits to a document might be on ',
|
|
43
|
+
'their laptop on an airplane; when the plane lands and the ',
|
|
44
|
+
'computer reconnects, those changes are distributed to ',
|
|
45
|
+
'other users.\n',
|
|
46
|
+
],
|
|
47
|
+
[
|
|
48
|
+
'Other users might choose to accept all, some, or none of ',
|
|
49
|
+
'those changes to their version of the document.',
|
|
50
|
+
],
|
|
51
|
+
];
|
|
52
|
+
/**
|
|
53
|
+
* Where Figma sets an Inter baseline in a line box: 4/11 em below the box's
|
|
54
|
+
* centre (half of Inter's ascent minus descent).
|
|
55
|
+
*/
|
|
56
|
+
function interBaseline(top, lineHeight, fontSize) {
|
|
57
|
+
return Number((top + lineHeight / 2 + (fontSize * 4) / 11).toFixed(4));
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The body lines of a heading preview that fit ENTIRELY in the frame, with the
|
|
61
|
+
* baseline each is set on.
|
|
62
|
+
*
|
|
63
|
+
* The body starts right under the heading's line box, so how many of its lines
|
|
64
|
+
* the card can show depends on the level: derived here from the geometry (line
|
|
65
|
+
* boxes, frame height, bottom padding) rather than tuned per level. At 10px on
|
|
66
|
+
* a 12px line, Inter's descenders end within a twentieth of a pixel of the line
|
|
67
|
+
* box's bottom edge, which the bottom padding covers: a line whose box fits is
|
|
68
|
+
* never clipped.
|
|
69
|
+
*/
|
|
70
|
+
export function headingPreviewBodyLines(level) {
|
|
71
|
+
const limit = PREVIEW_HEIGHT - PREVIEW_PADDING_BOTTOM;
|
|
72
|
+
const lines = [];
|
|
73
|
+
let top = PREVIEW_PADDING_TOP + headingLineBox(level);
|
|
74
|
+
for (const [index, paragraph] of BODY_PARAGRAPHS.entries()) {
|
|
75
|
+
if (index > 0)
|
|
76
|
+
top += BODY_PARAGRAPH_GAP;
|
|
77
|
+
for (const text of paragraph) {
|
|
78
|
+
if (top + BODY_LINE_HEIGHT > limit)
|
|
79
|
+
return lines;
|
|
80
|
+
lines.push({
|
|
81
|
+
y: interBaseline(top, BODY_LINE_HEIGHT, BODY_FONT_SIZE),
|
|
82
|
+
text,
|
|
83
|
+
});
|
|
84
|
+
top += BODY_LINE_HEIGHT;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return lines;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* A heading preview drawn at the heading's real size, weight and line box
|
|
91
|
+
* (from `HEADING_SCALE`), above as many lines of body text as the card shows
|
|
92
|
+
* whole (`headingPreviewBodyLines`).
|
|
93
|
+
*/
|
|
13
94
|
// prettier-ignore
|
|
14
|
-
|
|
95
|
+
function headingTooltip(level) {
|
|
96
|
+
const { fontSize, fontWeight, letterSpacing } = HEADING_SCALE[level];
|
|
97
|
+
const lineBox = headingLineBox(level);
|
|
98
|
+
const maskId = `mask_heading_tooltip_${level}`;
|
|
99
|
+
const body = headingPreviewBodyLines(level).map(line => svg `<tspan x="8" y=${line.y}>${line.text}</tspan>`);
|
|
100
|
+
return html `<svg width="170" height="68" viewBox="0 0 170 68" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
15
101
|
<rect width="170" height="68" rx="2" fill="white"/>
|
|
16
|
-
<mask id
|
|
102
|
+
<mask id=${maskId} style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="170" height="68">
|
|
17
103
|
<rect width="170" height="68" rx="2" fill="white"/>
|
|
18
104
|
</mask>
|
|
19
|
-
<g mask="url(
|
|
20
|
-
<text fill="#121212" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size
|
|
21
|
-
<text fill="#121212" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size
|
|
22
|
-
</g>
|
|
23
|
-
</svg>
|
|
24
|
-
`;
|
|
25
|
-
// prettier-ignore
|
|
26
|
-
const Heading2Tooltip = html `<svg width="170" height="68" viewBox="0 0 170 68" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
27
|
-
<rect width="170" height="68" rx="2" fill="white"/>
|
|
28
|
-
<mask id="mask0_16460_880" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="170" height="68">
|
|
29
|
-
<rect width="170" height="68" rx="2" fill="white"/>
|
|
30
|
-
</mask>
|
|
31
|
-
<g mask="url(#mask0_16460_880)">
|
|
32
|
-
<text fill="#121212" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size="26" font-weight="600" letter-spacing="-0.24px"><tspan x="8" y="33.4545">Heading 2</tspan></text>
|
|
33
|
-
<text fill="#121212" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size="10" letter-spacing="0px"><tspan x="8" y="51.6364">In a decentralized system, we can have a kaleidoscopic </tspan><tspan x="8" y="63.6364">complexity to our data. </tspan><tspan x="8" y="79.6364">Any user may have a different perspective on what data they </tspan><tspan x="8" y="91.6364">either have, choose to share, or accept. </tspan><tspan x="8" y="107.636">For example, one user’s edits to a document might be on </tspan><tspan x="8" y="119.636">their laptop on an airplane; when the plane lands and the </tspan><tspan x="8" y="131.636">computer reconnects, those changes are distributed to </tspan><tspan x="8" y="143.636">other users. </tspan><tspan x="8" y="159.636">Other users might choose to accept all, some, or none of </tspan><tspan x="8" y="171.636">those changes to their version of the document.</tspan></text>
|
|
34
|
-
</g>
|
|
35
|
-
</svg>
|
|
36
|
-
`;
|
|
37
|
-
// prettier-ignore
|
|
38
|
-
const Heading3Tooltip = html `<svg width="170" height="68" viewBox="0 0 170 68" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
39
|
-
<rect width="170" height="68" rx="2" fill="white"/>
|
|
40
|
-
<mask id="mask0_16460_887" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="170" height="68">
|
|
41
|
-
<rect width="170" height="68" rx="2" fill="white"/>
|
|
42
|
-
</mask>
|
|
43
|
-
<g mask="url(#mask0_16460_887)">
|
|
44
|
-
<text fill="#121212" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size="24" font-weight="600" letter-spacing="-0.24px"><tspan x="8" y="30.7273">Heading 3</tspan></text>
|
|
45
|
-
<text fill="#121212" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size="10" letter-spacing="0px"><tspan x="8" y="47.6364">In a decentralized system, we can have a kaleidoscopic </tspan><tspan x="8" y="59.6364">complexity to our data. </tspan><tspan x="8" y="75.6364">Any user may have a different perspective on what data they </tspan><tspan x="8" y="87.6364">either have, choose to share, or accept. </tspan><tspan x="8" y="103.636">For example, one user’s edits to a document might be on </tspan><tspan x="8" y="115.636">their laptop on an airplane; when the plane lands and the </tspan><tspan x="8" y="127.636">computer reconnects, those changes are distributed to </tspan><tspan x="8" y="139.636">other users. </tspan><tspan x="8" y="155.636">Other users might choose to accept all, some, or none of </tspan><tspan x="8" y="167.636">those changes to their version of the document.</tspan></text>
|
|
46
|
-
</g>
|
|
47
|
-
</svg>
|
|
48
|
-
`;
|
|
49
|
-
// prettier-ignore
|
|
50
|
-
const Heading4Tooltip = html `<svg width="170" height="68" viewBox="0 0 170 68" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
51
|
-
<rect width="170" height="68" rx="2" fill="white"/>
|
|
52
|
-
<mask id="mask0_16460_894" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="170" height="68">
|
|
53
|
-
<rect width="170" height="68" rx="2" fill="white"/>
|
|
54
|
-
</mask>
|
|
55
|
-
<g mask="url(#mask0_16460_894)">
|
|
56
|
-
<text fill="#121212" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size="22" font-weight="600" letter-spacing="0.24px"><tspan x="8" y="29">Heading 4</tspan></text>
|
|
57
|
-
<text fill="#121212" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size="10" letter-spacing="0px"><tspan x="8" y="45.6364">In a decentralized system, we can have a kaleidoscopic </tspan><tspan x="8" y="57.6364">complexity to our data. </tspan><tspan x="8" y="73.6364">Any user may have a different perspective on what data they </tspan><tspan x="8" y="85.6364">either have, choose to share, or accept. </tspan><tspan x="8" y="101.636">For example, one user’s edits to a document might be on </tspan><tspan x="8" y="113.636">their laptop on an airplane; when the plane lands and the </tspan><tspan x="8" y="125.636">computer reconnects, those changes are distributed to </tspan><tspan x="8" y="137.636">other users. </tspan><tspan x="8" y="153.636">Other users might choose to accept all, some, or none of </tspan><tspan x="8" y="165.636">those changes to their version of the document.</tspan></text>
|
|
58
|
-
</g>
|
|
59
|
-
</svg>
|
|
60
|
-
`;
|
|
61
|
-
// prettier-ignore
|
|
62
|
-
const Heading5Tooltip = html `<svg width="170" height="68" viewBox="0 0 170 68" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
63
|
-
<rect width="170" height="68" rx="2" fill="white"/>
|
|
64
|
-
<mask id="mask0_16460_901" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="170" height="68">
|
|
65
|
-
<rect width="170" height="68" rx="2" fill="white"/>
|
|
66
|
-
</mask>
|
|
67
|
-
<g mask="url(#mask0_16460_901)">
|
|
68
|
-
<text fill="#121212" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size="20" font-weight="600" letter-spacing="0.24px"><tspan x="8" y="27.2727">Heading 5</tspan></text>
|
|
69
|
-
<text fill="#121212" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size="10" letter-spacing="0px"><tspan x="8" y="43.6364">In a decentralized system, we can have a kaleidoscopic </tspan><tspan x="8" y="55.6364">complexity to our data. </tspan><tspan x="8" y="71.6364">Any user may have a different perspective on what data they </tspan><tspan x="8" y="83.6364">either have, choose to share, or accept. </tspan><tspan x="8" y="99.6364">For example, one user’s edits to a document might be on </tspan><tspan x="8" y="111.636">their laptop on an airplane; when the plane lands and the </tspan><tspan x="8" y="123.636">computer reconnects, those changes are distributed to </tspan><tspan x="8" y="135.636">other users. </tspan><tspan x="8" y="151.636">Other users might choose to accept all, some, or none of </tspan><tspan x="8" y="163.636">those changes to their version of the document.</tspan></text>
|
|
70
|
-
</g>
|
|
71
|
-
</svg>
|
|
72
|
-
`;
|
|
73
|
-
// prettier-ignore
|
|
74
|
-
const Heading6Tooltip = html `<svg width="170" height="68" viewBox="0 0 170 68" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
75
|
-
<rect width="170" height="68" rx="2" fill="white"/>
|
|
76
|
-
<mask id="mask0_16460_908" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="170" height="68">
|
|
77
|
-
<rect width="170" height="68" rx="2" fill="white"/>
|
|
78
|
-
</mask>
|
|
79
|
-
<g mask="url(#mask0_16460_908)">
|
|
80
|
-
<text fill="#121212" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size="18" font-weight="600" letter-spacing="0.24px"><tspan x="8" y="25.5455">Heading 6</tspan></text>
|
|
81
|
-
<text fill="#121212" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size="10" letter-spacing="0px"><tspan x="8" y="41.6364">In a decentralized system, we can have a kaleidoscopic </tspan><tspan x="8" y="53.6364">complexity to our data. </tspan><tspan x="8" y="69.6364">Any user may have a different perspective on what data they </tspan><tspan x="8" y="81.6364">either have, choose to share, or accept. </tspan><tspan x="8" y="97.6364">For example, one user’s edits to a document might be on </tspan><tspan x="8" y="109.636">their laptop on an airplane; when the plane lands and the </tspan><tspan x="8" y="121.636">computer reconnects, those changes are distributed to </tspan><tspan x="8" y="133.636">other users. </tspan><tspan x="8" y="149.636">Other users might choose to accept all, some, or none of </tspan><tspan x="8" y="161.636">those changes to their version of the document.</tspan></text>
|
|
105
|
+
<g mask="url(#${maskId})">
|
|
106
|
+
<text fill="#121212" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size=${fontSize} font-weight=${fontWeight} letter-spacing="${letterSpacing}em"><tspan x="8" y=${interBaseline(PREVIEW_PADDING_TOP, lineBox, fontSize)}>Heading ${level.slice(1)}</tspan></text>
|
|
107
|
+
<text fill="#121212" xml:space="preserve" style="white-space: pre" font-family="Inter" font-size=${BODY_FONT_SIZE} letter-spacing="0px">${body}</text>
|
|
82
108
|
</g>
|
|
83
109
|
</svg>
|
|
84
110
|
`;
|
|
111
|
+
}
|
|
112
|
+
const Heading1Tooltip = headingTooltip('h1');
|
|
113
|
+
const Heading2Tooltip = headingTooltip('h2');
|
|
114
|
+
const Heading3Tooltip = headingTooltip('h3');
|
|
115
|
+
const Heading4Tooltip = headingTooltip('h4');
|
|
116
|
+
const Heading5Tooltip = headingTooltip('h5');
|
|
117
|
+
const Heading6Tooltip = headingTooltip('h6');
|
|
85
118
|
// prettier-ignore
|
|
86
119
|
const CodeBlockTooltip = html `<svg width="170" height="68" viewBox="0 0 170 68" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
87
120
|
<rect width="170" height="68" rx="2" fill="white"/>
|
|
@@ -7,9 +7,17 @@ export declare class ParagraphBlockComponent extends CaptionedBlockComponent<Par
|
|
|
7
7
|
focused$: import("@preact/signals-core").ReadonlySignal<boolean>;
|
|
8
8
|
private readonly _composing;
|
|
9
9
|
private readonly _displayPlaceholder;
|
|
10
|
+
/**
|
|
11
|
+
* The collapse state a READER holds locally. A readonly document must never
|
|
12
|
+
* be written, so the chevron cannot touch `model.props.collapsed`; this
|
|
13
|
+
* signal carries the reader's own expansion instead. It is a signal rather
|
|
14
|
+
* than a Lit `@state()` so BlockSuite effects can depend on it as well.
|
|
15
|
+
*/
|
|
16
|
+
private readonly _readonlyCollapsed;
|
|
10
17
|
private _inlineRangeProvider;
|
|
11
18
|
private readonly _isInDatabase;
|
|
12
19
|
private get _placeholder();
|
|
20
|
+
private _setReadonlyCollapsed;
|
|
13
21
|
get citationService(): import("../affine-shared/services/index.js").CitationViewService;
|
|
14
22
|
get attributeRenderer(): import("../std/inline/types.js").AttributeRenderer<import("../affine-shared/types/index.js").AffineTextAttributes>;
|
|
15
23
|
get attributesSchema(): import("zod").ZodType<any, import("zod").ZodTypeDef, any>;
|
|
@@ -24,7 +32,6 @@ export declare class ParagraphBlockComponent extends CaptionedBlockComponent<Par
|
|
|
24
32
|
connectedCallback(): void;
|
|
25
33
|
getUpdateComplete(): Promise<boolean>;
|
|
26
34
|
renderBlock(): TemplateResult<1>;
|
|
27
|
-
private accessor _readonlyCollapsed;
|
|
28
35
|
private accessor _richTextElement;
|
|
29
36
|
accessor blockContainerStyles: {
|
|
30
37
|
margin: string;
|
|
@@ -42,7 +42,7 @@ import { TextSelection } from '../std/index.js';
|
|
|
42
42
|
import { getInlineRangeProvider, } from '../std/inline/index.js';
|
|
43
43
|
import { computed, effect, signal } from '@preact/signals-core';
|
|
44
44
|
import { html, nothing } from 'lit';
|
|
45
|
-
import { query
|
|
45
|
+
import { query } from 'lit/decorators.js';
|
|
46
46
|
import { classMap } from 'lit/directives/class-map.js';
|
|
47
47
|
import { styleMap } from 'lit/directives/style-map.js';
|
|
48
48
|
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
|
@@ -50,9 +50,6 @@ import { ParagraphBlockConfigExtension } from './paragraph-block-config.js';
|
|
|
50
50
|
import { paragraphBlockStyles } from './styles.js';
|
|
51
51
|
let ParagraphBlockComponent = (() => {
|
|
52
52
|
let _classSuper = CaptionedBlockComponent;
|
|
53
|
-
let __readonlyCollapsed_decorators;
|
|
54
|
-
let __readonlyCollapsed_initializers = [];
|
|
55
|
-
let __readonlyCollapsed_extraInitializers = [];
|
|
56
53
|
let __richTextElement_decorators;
|
|
57
54
|
let __richTextElement_initializers = [];
|
|
58
55
|
let __richTextElement_extraInitializers = [];
|
|
@@ -67,6 +64,13 @@ let ParagraphBlockComponent = (() => {
|
|
|
67
64
|
});
|
|
68
65
|
this._composing = signal(false);
|
|
69
66
|
this._displayPlaceholder = signal(false);
|
|
67
|
+
/**
|
|
68
|
+
* The collapse state a READER holds locally. A readonly document must never
|
|
69
|
+
* be written, so the chevron cannot touch `model.props.collapsed`; this
|
|
70
|
+
* signal carries the reader's own expansion instead. It is a signal rather
|
|
71
|
+
* than a Lit `@state()` so BlockSuite effects can depend on it as well.
|
|
72
|
+
*/
|
|
73
|
+
this._readonlyCollapsed = signal(false);
|
|
70
74
|
this._inlineRangeProvider = null;
|
|
71
75
|
this._isInDatabase = () => {
|
|
72
76
|
let parent = this.parentElement;
|
|
@@ -78,17 +82,14 @@ let ParagraphBlockComponent = (() => {
|
|
|
78
82
|
}
|
|
79
83
|
return false;
|
|
80
84
|
};
|
|
81
|
-
this.#
|
|
82
|
-
this.#_richTextElement_accessor_storage = (__runInitializers(this, __readonlyCollapsed_extraInitializers), __runInitializers(this, __richTextElement_initializers, null));
|
|
85
|
+
this.#_richTextElement_accessor_storage = __runInitializers(this, __richTextElement_initializers, null);
|
|
83
86
|
this.#blockContainerStyles_accessor_storage = (__runInitializers(this, __richTextElement_extraInitializers), {
|
|
84
87
|
margin: 'var(--affine-paragraph-margin, 10px 0)',
|
|
85
88
|
});
|
|
86
89
|
}
|
|
87
90
|
static {
|
|
88
91
|
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
89
|
-
__readonlyCollapsed_decorators = [state()];
|
|
90
92
|
__richTextElement_decorators = [query('rich-text')];
|
|
91
|
-
__esDecorate(this, null, __readonlyCollapsed_decorators, { kind: "accessor", name: "_readonlyCollapsed", static: false, private: false, access: { has: obj => "_readonlyCollapsed" in obj, get: obj => obj._readonlyCollapsed, set: (obj, value) => { obj._readonlyCollapsed = value; } }, metadata: _metadata }, __readonlyCollapsed_initializers, __readonlyCollapsed_extraInitializers);
|
|
92
93
|
__esDecorate(this, null, __richTextElement_decorators, { kind: "accessor", name: "_richTextElement", static: false, private: false, access: { has: obj => "_richTextElement" in obj, get: obj => obj._richTextElement, set: (obj, value) => { obj._richTextElement = value; } }, metadata: _metadata }, __richTextElement_initializers, __richTextElement_extraInitializers);
|
|
93
94
|
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
94
95
|
}
|
|
@@ -98,6 +99,10 @@ let ParagraphBlockComponent = (() => {
|
|
|
98
99
|
.get(ParagraphBlockConfigExtension.identifier)
|
|
99
100
|
?.getPlaceholder(this.model);
|
|
100
101
|
}
|
|
102
|
+
_setReadonlyCollapsed(collapsed) {
|
|
103
|
+
this._readonlyCollapsed.value = collapsed;
|
|
104
|
+
this.requestUpdate();
|
|
105
|
+
}
|
|
101
106
|
get citationService() {
|
|
102
107
|
return this.std.get(CitationProvider);
|
|
103
108
|
}
|
|
@@ -176,9 +181,19 @@ let ParagraphBlockComponent = (() => {
|
|
|
176
181
|
this.model.props.collapsed = false;
|
|
177
182
|
}
|
|
178
183
|
}));
|
|
184
|
+
// Entering readonly mode (and any later change of the persisted value)
|
|
185
|
+
// seeds the reader's local state. Deliberately NOT re-run on every
|
|
186
|
+
// selection change: this effect must not depend on the selection, or the
|
|
187
|
+
// reader's own expansion would be overwritten mid-drag.
|
|
188
|
+
this.disposables.add(effect(() => {
|
|
189
|
+
if (this.store.readonly$.value) {
|
|
190
|
+
this._setReadonlyCollapsed(this.model.props.collapsed$.value);
|
|
191
|
+
}
|
|
192
|
+
}));
|
|
179
193
|
this.disposables.add(effect(() => {
|
|
180
|
-
const collapsed = this.
|
|
181
|
-
|
|
194
|
+
const collapsed = this.store.readonly
|
|
195
|
+
? this._readonlyCollapsed.value
|
|
196
|
+
: this.model.props.collapsed$.value;
|
|
182
197
|
// reset text selection when selected block is collapsed
|
|
183
198
|
if (this.model.props.type$.value.startsWith('h') && collapsed) {
|
|
184
199
|
const collapsedSiblings = this.collapsedSiblings;
|
|
@@ -216,7 +231,7 @@ let ParagraphBlockComponent = (() => {
|
|
|
216
231
|
renderBlock() {
|
|
217
232
|
const { type$ } = this.model.props;
|
|
218
233
|
const collapsed = this.store.readonly
|
|
219
|
-
? this._readonlyCollapsed
|
|
234
|
+
? this._readonlyCollapsed.value
|
|
220
235
|
: this.model.props.collapsed;
|
|
221
236
|
const collapsedSiblings = this.collapsedSiblings;
|
|
222
237
|
let style = html ``;
|
|
@@ -231,7 +246,9 @@ let ParagraphBlockComponent = (() => {
|
|
|
231
246
|
</style>
|
|
232
247
|
`;
|
|
233
248
|
}
|
|
249
|
+
const childrenId = `heading-children-${this.model.id}`;
|
|
234
250
|
const children = html `<div
|
|
251
|
+
id=${childrenId}
|
|
235
252
|
class="affine-block-children-container"
|
|
236
253
|
style=${styleMap({
|
|
237
254
|
paddingLeft: `${BLOCK_CHILDREN_CONTAINER_PADDING_LEFT}px`,
|
|
@@ -275,9 +292,10 @@ let ParagraphBlockComponent = (() => {
|
|
|
275
292
|
? html `
|
|
276
293
|
<blocksuite-toggle-button
|
|
277
294
|
.collapsed=${collapsed}
|
|
295
|
+
.controls=${childrenId}
|
|
278
296
|
.updateCollapsed=${(value) => {
|
|
279
297
|
if (this.store.readonly) {
|
|
280
|
-
this.
|
|
298
|
+
this._setReadonlyCollapsed(value);
|
|
281
299
|
}
|
|
282
300
|
else {
|
|
283
301
|
this.store.captureSync();
|
|
@@ -328,9 +346,6 @@ let ParagraphBlockComponent = (() => {
|
|
|
328
346
|
</div>
|
|
329
347
|
`;
|
|
330
348
|
}
|
|
331
|
-
#_readonlyCollapsed_accessor_storage;
|
|
332
|
-
get _readonlyCollapsed() { return this.#_readonlyCollapsed_accessor_storage; }
|
|
333
|
-
set _readonlyCollapsed(value) { this.#_readonlyCollapsed_accessor_storage = value; }
|
|
334
349
|
#_richTextElement_accessor_storage;
|
|
335
350
|
get _richTextElement() { return this.#_richTextElement_accessor_storage; }
|
|
336
351
|
set _richTextElement(value) { this.#_richTextElement_accessor_storage = value; }
|