@formicoidea/labre-core 0.45.0 → 0.46.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/commands/turn-callout-into.d.ts +43 -0
- package/dist/_pkgs/affine-block-callout/commands/turn-callout-into.js +109 -0
- package/dist/_pkgs/affine-block-callout/configs/toolbar.d.ts +65 -0
- package/dist/_pkgs/affine-block-callout/configs/toolbar.js +178 -0
- package/dist/_pkgs/affine-block-callout/view.js +7 -1
- package/dist/_pkgs/affine-block-frame/commands.d.ts +27 -0
- package/dist/_pkgs/affine-block-frame/commands.js +49 -0
- package/dist/_pkgs/affine-block-frame/frame-manager.d.ts +11 -6
- package/dist/_pkgs/affine-block-frame/frame-manager.js +10 -5
- package/dist/_pkgs/affine-block-frame/frame-order.d.ts +43 -0
- package/dist/_pkgs/affine-block-frame/frame-order.js +93 -0
- package/dist/_pkgs/affine-block-frame/index.d.ts +2 -0
- package/dist/_pkgs/affine-block-frame/index.js +2 -0
- package/dist/_pkgs/affine-block-frame/present/frame-order-menu.d.ts +10 -2
- package/dist/_pkgs/affine-block-frame/present/frame-order-menu.js +32 -18
- package/dist/_pkgs/affine-block-frame/view.js +6 -0
- package/dist/_pkgs/affine-block-note/configs/toolbar.d.ts +19 -0
- package/dist/_pkgs/affine-block-note/configs/toolbar.js +38 -23
- package/dist/_pkgs/affine-block-note/translations.d.ts +2 -0
- package/dist/_pkgs/affine-block-note/translations.js +14 -1
- package/dist/_pkgs/affine-block-root/configs/toolbar.js +31 -2
- package/dist/_pkgs/affine-block-root/translations.d.ts +7 -2
- package/dist/_pkgs/affine-block-root/translations.js +10 -13
- package/dist/_pkgs/affine-block-surface/extensions/selection-pane/actions.d.ts +20 -9
- package/dist/_pkgs/affine-block-surface/extensions/selection-pane/actions.js +57 -20
- package/dist/_pkgs/affine-block-surface/extensions/selection-pane/commands.d.ts +6 -8
- package/dist/_pkgs/affine-block-surface/extensions/selection-pane/commands.js +21 -8
- package/dist/_pkgs/affine-block-surface/extensions/selection-pane/index.d.ts +1 -1
- package/dist/_pkgs/affine-block-surface/extensions/selection-pane/index.js +1 -1
- package/dist/_pkgs/affine-components/portal/portal.d.ts +1 -1
- package/dist/_pkgs/affine-foundation/view.d.ts +8 -8
- package/dist/_pkgs/affine-fragment-frame-panel/body/frame-panel-body.d.ts +34 -2
- package/dist/_pkgs/affine-fragment-frame-panel/body/frame-panel-body.js +194 -81
- package/dist/_pkgs/affine-fragment-frame-panel/card/frame-card.d.ts +7 -4
- package/dist/_pkgs/affine-fragment-frame-panel/card/frame-card.js +9 -24
- package/dist/_pkgs/affine-fragment-frame-panel/index.d.ts +1 -0
- package/dist/_pkgs/affine-fragment-frame-panel/index.js +1 -0
- package/dist/_pkgs/affine-model/utils/types.d.ts +2 -2
- package/dist/_pkgs/affine-shared/services/edit-props-store.d.ts +4 -4
- package/dist/_pkgs/affine-shared/services/font-loader/config.d.ts +2 -2
- package/dist/_pkgs/affine-shared/services/font-loader/font-loader-service.d.ts +3 -3
- package/dist/_pkgs/affine-shared/services/index.d.ts +1 -1
- package/dist/_pkgs/affine-shared/services/index.js +1 -1
- package/dist/_pkgs/affine-shared/services/link-preview-service/link-preview-storage.d.ts +4 -4
- package/dist/_pkgs/affine-shared/services/outline-panel-service.d.ts +31 -0
- package/dist/_pkgs/affine-shared/services/outline-panel-service.js +17 -0
- package/dist/_pkgs/affine-shared/services/translation-service/chrome.d.ts +11 -0
- package/dist/_pkgs/affine-shared/services/translation-service/chrome.js +19 -0
- package/dist/_pkgs/affine-shared/utils/index.d.ts +1 -0
- package/dist/_pkgs/affine-shared/utils/index.js +1 -0
- package/dist/_pkgs/affine-shared/utils/panel-reorder-drag.d.ts +85 -0
- package/dist/_pkgs/affine-shared/utils/panel-reorder-drag.js +162 -0
- package/dist/_pkgs/affine-widget-edgeless-toolbar/selection-pane/drop.d.ts +7 -6
- package/dist/_pkgs/affine-widget-edgeless-toolbar/selection-pane/drop.js +11 -8
- package/dist/_pkgs/affine-widget-edgeless-toolbar/selection-pane/selection-pane-widget.d.ts +31 -15
- package/dist/_pkgs/affine-widget-edgeless-toolbar/selection-pane/selection-pane-widget.js +178 -142
- package/dist/_pkgs/std/scope/std-scope.d.ts +1 -1
- package/dist/commands.js +2 -0
- package/dist/host-panels.d.ts +90 -0
- package/dist/host-panels.js +111 -0
- package/package.json +5 -1
- package/dist/_pkgs/affine-fragment-frame-panel/utils/drag.d.ts +0 -27
- package/dist/_pkgs/affine-fragment-frame-panel/utils/drag.js +0 -96
- package/dist/_pkgs/affine-shared/services/sidebar-service.d.ts +0 -8
- package/dist/_pkgs/affine-shared/services/sidebar-service.js +0 -7
|
@@ -24,8 +24,9 @@ export declare const EDGELESS_SELECTION_PANE_WIDGET = "edgeless-selection-pane-w
|
|
|
24
24
|
* (shift / ctrl / cmd adds or removes it, like on the canvas), the padlock
|
|
25
25
|
* locks that row alone, a double-click renames a group or a frame (a frame is
|
|
26
26
|
* a row at its place in the stack, ADR 0031 amendments), and a drag moves a row
|
|
27
|
-
*
|
|
28
|
-
*
|
|
27
|
+
* — or, pressed on a selected row, the whole selection of one stack — among
|
|
28
|
+
* its siblings (the side panels' one drag, ADR 0034). Every write goes through
|
|
29
|
+
* `runCommand`, so the read-only refusal and the undo step live in one place.
|
|
29
30
|
*/
|
|
30
31
|
export declare class EdgelessSelectionPaneWidget extends WidgetComponent<RootBlockModel> {
|
|
31
32
|
static styles: import("lit").CSSResult;
|
|
@@ -36,19 +37,22 @@ export declare class EdgelessSelectionPaneWidget extends WidgetComponent<RootBlo
|
|
|
36
37
|
private accessor _filter;
|
|
37
38
|
/** The group row being renamed, or `null`. */
|
|
38
39
|
private accessor _renaming;
|
|
39
|
-
/** Where the dragged
|
|
40
|
+
/** Where the dragged rows would land; `null` while refused. */
|
|
40
41
|
private accessor _drop;
|
|
41
42
|
/** Where the dragged row's ghost is drawn, in the panel's own box. */
|
|
42
43
|
private accessor _ghost;
|
|
43
44
|
/** Bumped when the canvas selection changes, so the rows repaint. */
|
|
44
45
|
private accessor _selectionRevision;
|
|
45
|
-
|
|
46
|
+
/** The drag under way, from its pick-up to its end. */
|
|
47
|
+
private accessor _drag;
|
|
48
|
+
/** The last row pressed: what a pick-up picks up. */
|
|
49
|
+
private _pressed;
|
|
50
|
+
/** The side panels' one reorder gesture, wired in `_wire()`. */
|
|
51
|
+
private _reorder;
|
|
46
52
|
/** The rows of the last render, top first: what a drag hit-tests. */
|
|
47
53
|
private _visibleRows;
|
|
48
54
|
/** The sibling lists before the filter: what a drop is computed in. */
|
|
49
55
|
private _lists;
|
|
50
|
-
/** A drag ends with a click on the row it started on; that click is not one. */
|
|
51
|
-
private _swallowNextClick;
|
|
52
56
|
get paneOpen(): boolean;
|
|
53
57
|
private get _gfx();
|
|
54
58
|
private _setOpen;
|
|
@@ -109,7 +113,21 @@ export declare class EdgelessSelectionPaneWidget extends WidgetComponent<RootBlo
|
|
|
109
113
|
private _onRowContextMenu;
|
|
110
114
|
private _commitRename;
|
|
111
115
|
private readonly _onRenameKeydown;
|
|
116
|
+
private _createReorderDrag;
|
|
117
|
+
private _panel;
|
|
118
|
+
private _paneBody;
|
|
119
|
+
/** The rows on screen, top first, with the rows they draw. */
|
|
120
|
+
private _shownRows;
|
|
112
121
|
private _onRowPointerDown;
|
|
122
|
+
/**
|
|
123
|
+
* The press became a drag. A canvas row picked up is selected, as the frame
|
|
124
|
+
* panel selects a card — unless it already is, and then the whole selection
|
|
125
|
+
* moves with it, as in the frame panel: every selected row the pane lists.
|
|
126
|
+
* Rows that are not all in the pressed row's stack and list have no one
|
|
127
|
+
* place to land, so every drop of theirs is refused, honestly, with a
|
|
128
|
+
* `not-allowed` cursor rather than a line that would write nothing.
|
|
129
|
+
*/
|
|
130
|
+
private _pickUp;
|
|
113
131
|
/**
|
|
114
132
|
* Which model stands for a row in the dragged row's own stack — the stack
|
|
115
133
|
* `canvas.element.reorder` restacks it in, the models sharing its raw
|
|
@@ -119,20 +137,18 @@ export declare class EdgelessSelectionPaneWidget extends WidgetComponent<RootBlo
|
|
|
119
137
|
* mindmap node moves with its mindmap).
|
|
120
138
|
*/
|
|
121
139
|
private _stackOf;
|
|
122
|
-
/**
|
|
140
|
+
/**
|
|
141
|
+
* Where a release over the gap `gap` (the controller's count of rows whose
|
|
142
|
+
* middle is above the pointer, at `clientY`) would land the dragged rows,
|
|
143
|
+
* or `null` to refuse it.
|
|
144
|
+
*/
|
|
123
145
|
private _dropAt;
|
|
124
|
-
private _moveGhost;
|
|
125
|
-
private readonly _onDocumentPointerMove;
|
|
126
|
-
/** A canvas row picked up is selected, as the frame panel selects a card. */
|
|
127
|
-
private _pickUp;
|
|
128
|
-
private readonly _onDocumentPointerUp;
|
|
129
146
|
/**
|
|
130
147
|
* One write per gesture, through the command: `layer` for a drop into a
|
|
131
|
-
* layer, one
|
|
132
|
-
* is where the
|
|
148
|
+
* layer, one restack for a slot. The command writes nothing when the slot
|
|
149
|
+
* is where the rows already are, and a refused drop never reaches it.
|
|
133
150
|
*/
|
|
134
151
|
private _commitDrop;
|
|
135
|
-
private _endDrag;
|
|
136
152
|
private _renderGhost;
|
|
137
153
|
private _renderDropIndicator;
|
|
138
154
|
private _filterName;
|
|
@@ -36,7 +36,8 @@ import { CanvasActiveLayer, EDITOR_ANCHORED_PANEL_Z_INDEX, filterSelectionPaneTr
|
|
|
36
36
|
import { menu, popMenu, popupTargetFromElement, } from '../../affine-components/context-menu/index.js';
|
|
37
37
|
import { FrameBlockModel, MindmapElementModel, } from '../../affine-model/index.js';
|
|
38
38
|
import { TOOLBAR_LOCK, TOOLBAR_RENAME, translateKey, } from '../../affine-shared/services/index.js';
|
|
39
|
-
import {
|
|
39
|
+
import { panelHeaderStyles } from '../../affine-shared/styles/index.js';
|
|
40
|
+
import { createPanelReorderDrag, } from '../../affine-shared/utils/index.js';
|
|
40
41
|
import { runCommand, WidgetComponent, WidgetViewExtension, } from '../../std/index.js';
|
|
41
42
|
import { DEFAULT_LAYER_ID, GfxBlockElementModel, GfxControllerIdentifier, } from '../../std/gfx/index.js';
|
|
42
43
|
import { ArrowDownSmallIcon, ArrowRightSmallIcon, CloseIcon, DeleteIcon, FilterIcon, InvisibleIcon, LayerIcon, LockIcon, MoreHorizontalIcon, PlusIcon, UnlockIcon, ViewIcon, } from '@blocksuite/icons/lit';
|
|
@@ -100,8 +101,9 @@ function rawGroupOf(model) {
|
|
|
100
101
|
* (shift / ctrl / cmd adds or removes it, like on the canvas), the padlock
|
|
101
102
|
* locks that row alone, a double-click renames a group or a frame (a frame is
|
|
102
103
|
* a row at its place in the stack, ADR 0031 amendments), and a drag moves a row
|
|
103
|
-
*
|
|
104
|
-
*
|
|
104
|
+
* — or, pressed on a selected row, the whole selection of one stack — among
|
|
105
|
+
* its siblings (the side panels' one drag, ADR 0034). Every write goes through
|
|
106
|
+
* `runCommand`, so the read-only refusal and the undo step live in one place.
|
|
105
107
|
*/
|
|
106
108
|
let EdgelessSelectionPaneWidget = (() => {
|
|
107
109
|
let _classSuper = WidgetComponent;
|
|
@@ -126,6 +128,9 @@ let EdgelessSelectionPaneWidget = (() => {
|
|
|
126
128
|
let __selectionRevision_decorators;
|
|
127
129
|
let __selectionRevision_initializers = [];
|
|
128
130
|
let __selectionRevision_extraInitializers = [];
|
|
131
|
+
let __drag_decorators;
|
|
132
|
+
let __drag_initializers = [];
|
|
133
|
+
let __drag_extraInitializers = [];
|
|
129
134
|
return class EdgelessSelectionPaneWidget extends _classSuper {
|
|
130
135
|
constructor() {
|
|
131
136
|
super(...arguments);
|
|
@@ -136,13 +141,15 @@ let EdgelessSelectionPaneWidget = (() => {
|
|
|
136
141
|
this.#_drop_accessor_storage = (__runInitializers(this, __renaming_extraInitializers), __runInitializers(this, __drop_initializers, null));
|
|
137
142
|
this.#_ghost_accessor_storage = (__runInitializers(this, __drop_extraInitializers), __runInitializers(this, __ghost_initializers, null));
|
|
138
143
|
this.#_selectionRevision_accessor_storage = (__runInitializers(this, __ghost_extraInitializers), __runInitializers(this, __selectionRevision_initializers, 0));
|
|
139
|
-
this
|
|
144
|
+
this.#_drag_accessor_storage = (__runInitializers(this, __selectionRevision_extraInitializers), __runInitializers(this, __drag_initializers, null));
|
|
145
|
+
/** The last row pressed: what a pick-up picks up. */
|
|
146
|
+
this._pressed = (__runInitializers(this, __drag_extraInitializers), null);
|
|
147
|
+
/** The side panels' one reorder gesture, wired in `_wire()`. */
|
|
148
|
+
this._reorder = null;
|
|
140
149
|
/** The rows of the last render, top first: what a drag hit-tests. */
|
|
141
150
|
this._visibleRows = [];
|
|
142
151
|
/** The sibling lists before the filter: what a drop is computed in. */
|
|
143
152
|
this._lists = paneLists([]);
|
|
144
|
-
/** A drag ends with a click on the row it started on; that click is not one. */
|
|
145
|
-
this._swallowNextClick = false;
|
|
146
153
|
/** Put the pane away. Writes nothing but its own state. */
|
|
147
154
|
this.closePanel = () => {
|
|
148
155
|
this._setOpen(false);
|
|
@@ -158,9 +165,8 @@ let EdgelessSelectionPaneWidget = (() => {
|
|
|
158
165
|
if (this._renaming)
|
|
159
166
|
return;
|
|
160
167
|
event.stopPropagation();
|
|
161
|
-
//
|
|
162
|
-
|
|
163
|
-
return;
|
|
168
|
+
// Escape during a drag never gets here: the drag controller cancels the
|
|
169
|
+
// drag and stops it in the capture phase, so the pane stays open.
|
|
164
170
|
this.closePanel();
|
|
165
171
|
};
|
|
166
172
|
/** Same capture as the catalogue: a wheel over the pane scrolls the pane. */
|
|
@@ -186,33 +192,6 @@ let EdgelessSelectionPaneWidget = (() => {
|
|
|
186
192
|
this._renaming = null;
|
|
187
193
|
}
|
|
188
194
|
};
|
|
189
|
-
this._onDocumentPointerMove = (event) => {
|
|
190
|
-
const drag = this._drag;
|
|
191
|
-
if (!drag)
|
|
192
|
-
return;
|
|
193
|
-
if (!drag.dragging) {
|
|
194
|
-
if (!panelDragStarted(drag, { x: event.clientX, y: event.clientY })) {
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
197
|
-
drag.dragging = true;
|
|
198
|
-
this._pickUp(drag);
|
|
199
|
-
}
|
|
200
|
-
this._moveGhost(event);
|
|
201
|
-
this._drop = this._dropAt(event.clientX, event.clientY);
|
|
202
|
-
};
|
|
203
|
-
this._onDocumentPointerUp = (event) => {
|
|
204
|
-
const drag = this._drag;
|
|
205
|
-
if (drag?.dragging) {
|
|
206
|
-
this._swallowNextClick = true;
|
|
207
|
-
// A click only follows when the press and the release land on the same
|
|
208
|
-
// row; otherwise nothing would ever clear the flag.
|
|
209
|
-
setTimeout(() => (this._swallowNextClick = false), 0);
|
|
210
|
-
const drop = this._dropAt(event.clientX, event.clientY);
|
|
211
|
-
if (drop)
|
|
212
|
-
this._commitDrop(drag, drop);
|
|
213
|
-
}
|
|
214
|
-
this._endDrag();
|
|
215
|
-
};
|
|
216
195
|
this._openFilterMenu = (event) => {
|
|
217
196
|
const targets = selectionPaneFilterTargets(this.std);
|
|
218
197
|
popMenu(popupTargetFromElement(event.currentTarget), {
|
|
@@ -258,6 +237,7 @@ let EdgelessSelectionPaneWidget = (() => {
|
|
|
258
237
|
__drop_decorators = [state()];
|
|
259
238
|
__ghost_decorators = [state()];
|
|
260
239
|
__selectionRevision_decorators = [state()];
|
|
240
|
+
__drag_decorators = [state()];
|
|
261
241
|
__esDecorate(this, null, __open_decorators, { kind: "accessor", name: "_open", static: false, private: false, access: { has: obj => "_open" in obj, get: obj => obj._open, set: (obj, value) => { obj._open = value; } }, metadata: _metadata }, __open_initializers, __open_extraInitializers);
|
|
262
242
|
__esDecorate(this, null, __collapsed_decorators, { kind: "accessor", name: "_collapsed", static: false, private: false, access: { has: obj => "_collapsed" in obj, get: obj => obj._collapsed, set: (obj, value) => { obj._collapsed = value; } }, metadata: _metadata }, __collapsed_initializers, __collapsed_extraInitializers);
|
|
263
243
|
__esDecorate(this, null, __filter_decorators, { kind: "accessor", name: "_filter", static: false, private: false, access: { has: obj => "_filter" in obj, get: obj => obj._filter, set: (obj, value) => { obj._filter = value; } }, metadata: _metadata }, __filter_initializers, __filter_extraInitializers);
|
|
@@ -265,6 +245,7 @@ let EdgelessSelectionPaneWidget = (() => {
|
|
|
265
245
|
__esDecorate(this, null, __drop_decorators, { kind: "accessor", name: "_drop", static: false, private: false, access: { has: obj => "_drop" in obj, get: obj => obj._drop, set: (obj, value) => { obj._drop = value; } }, metadata: _metadata }, __drop_initializers, __drop_extraInitializers);
|
|
266
246
|
__esDecorate(this, null, __ghost_decorators, { kind: "accessor", name: "_ghost", static: false, private: false, access: { has: obj => "_ghost" in obj, get: obj => obj._ghost, set: (obj, value) => { obj._ghost = value; } }, metadata: _metadata }, __ghost_initializers, __ghost_extraInitializers);
|
|
267
247
|
__esDecorate(this, null, __selectionRevision_decorators, { kind: "accessor", name: "_selectionRevision", static: false, private: false, access: { has: obj => "_selectionRevision" in obj, get: obj => obj._selectionRevision, set: (obj, value) => { obj._selectionRevision = value; } }, metadata: _metadata }, __selectionRevision_initializers, __selectionRevision_extraInitializers);
|
|
248
|
+
__esDecorate(this, null, __drag_decorators, { kind: "accessor", name: "_drag", static: false, private: false, access: { has: obj => "_drag" in obj, get: obj => obj._drag, set: (obj, value) => { obj._drag = value; } }, metadata: _metadata }, __drag_initializers, __drag_extraInitializers);
|
|
268
249
|
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
269
250
|
}
|
|
270
251
|
static { this.styles = css `
|
|
@@ -372,8 +353,8 @@ let EdgelessSelectionPaneWidget = (() => {
|
|
|
372
353
|
color: var(--affine-primary-color);
|
|
373
354
|
}
|
|
374
355
|
|
|
375
|
-
/* The
|
|
376
|
-
placeholder
|
|
356
|
+
/* The rows being dragged stay in place, dimmed, like the frame panel's
|
|
357
|
+
placeholder cards; the pressed row's ghost follows the pointer. */
|
|
377
358
|
.selection-pane-row[data-dragging] {
|
|
378
359
|
opacity: 0.5;
|
|
379
360
|
}
|
|
@@ -403,10 +384,10 @@ let EdgelessSelectionPaneWidget = (() => {
|
|
|
403
384
|
}
|
|
404
385
|
|
|
405
386
|
/*
|
|
406
|
-
The
|
|
407
|
-
the
|
|
408
|
-
|
|
409
|
-
it takes no hover.
|
|
387
|
+
The drag mask, created by the drag controller (createPanelReorderDrag):
|
|
388
|
+
over the whole viewport for the length of the drag, so the cursor —
|
|
389
|
+
set inline by the controller, "grabbing" or "not-allowed" — speaks
|
|
390
|
+
wherever the pointer is, and the canvas under it takes no hover.
|
|
410
391
|
*/
|
|
411
392
|
.selection-pane-drag-mask {
|
|
412
393
|
position: fixed;
|
|
@@ -439,6 +420,24 @@ let EdgelessSelectionPaneWidget = (() => {
|
|
|
439
420
|
flex: initial;
|
|
440
421
|
}
|
|
441
422
|
|
|
423
|
+
/* How many rows move with the ghost: the frame panel's card count. */
|
|
424
|
+
.selection-pane-drag-count {
|
|
425
|
+
flex: none;
|
|
426
|
+
margin-left: auto;
|
|
427
|
+
display: flex;
|
|
428
|
+
align-items: center;
|
|
429
|
+
justify-content: center;
|
|
430
|
+
min-width: 20px;
|
|
431
|
+
height: 20px;
|
|
432
|
+
padding: 0 4px;
|
|
433
|
+
box-sizing: border-box;
|
|
434
|
+
border-radius: 10px;
|
|
435
|
+
background: var(--affine-black);
|
|
436
|
+
color: var(--affine-white);
|
|
437
|
+
font-size: 12px;
|
|
438
|
+
line-height: 20px;
|
|
439
|
+
}
|
|
440
|
+
|
|
442
441
|
/* A row dragged onto a layer moves into it (ADR 0031 §5). */
|
|
443
442
|
.selection-pane-row[data-drop='into'] {
|
|
444
443
|
outline: 2px solid var(--affine-primary-color);
|
|
@@ -581,7 +580,7 @@ let EdgelessSelectionPaneWidget = (() => {
|
|
|
581
580
|
get _renaming() { return this.#_renaming_accessor_storage; }
|
|
582
581
|
set _renaming(value) { this.#_renaming_accessor_storage = value; }
|
|
583
582
|
#_drop_accessor_storage;
|
|
584
|
-
/** Where the dragged
|
|
583
|
+
/** Where the dragged rows would land; `null` while refused. */
|
|
585
584
|
get _drop() { return this.#_drop_accessor_storage; }
|
|
586
585
|
set _drop(value) { this.#_drop_accessor_storage = value; }
|
|
587
586
|
#_ghost_accessor_storage;
|
|
@@ -592,6 +591,10 @@ let EdgelessSelectionPaneWidget = (() => {
|
|
|
592
591
|
/** Bumped when the canvas selection changes, so the rows repaint. */
|
|
593
592
|
get _selectionRevision() { return this.#_selectionRevision_accessor_storage; }
|
|
594
593
|
set _selectionRevision(value) { this.#_selectionRevision_accessor_storage = value; }
|
|
594
|
+
#_drag_accessor_storage;
|
|
595
|
+
/** The drag under way, from its pick-up to its end. */
|
|
596
|
+
get _drag() { return this.#_drag_accessor_storage; }
|
|
597
|
+
set _drag(value) { this.#_drag_accessor_storage = value; }
|
|
595
598
|
get paneOpen() {
|
|
596
599
|
return this._open;
|
|
597
600
|
}
|
|
@@ -619,11 +622,15 @@ let EdgelessSelectionPaneWidget = (() => {
|
|
|
619
622
|
const subscription = this._gfx.selection.slots.updated.subscribe(() => {
|
|
620
623
|
this._selectionRevision++;
|
|
621
624
|
});
|
|
625
|
+
const reorder = this._createReorderDrag();
|
|
626
|
+
this._reorder = reorder;
|
|
622
627
|
this._disposables.add(() => {
|
|
623
628
|
host.removeEventListener('keydown', this._onHostKeydown, true);
|
|
624
629
|
host.removeEventListener('wheel', this._onHostWheel, true);
|
|
625
630
|
subscription.unsubscribe();
|
|
626
|
-
|
|
631
|
+
reorder.dispose();
|
|
632
|
+
if (this._reorder === reorder)
|
|
633
|
+
this._reorder = null;
|
|
627
634
|
});
|
|
628
635
|
}
|
|
629
636
|
connectedCallback() {
|
|
@@ -700,10 +707,9 @@ let EdgelessSelectionPaneWidget = (() => {
|
|
|
700
707
|
this._collapsed = next;
|
|
701
708
|
}
|
|
702
709
|
_onRowClick(event, node) {
|
|
703
|
-
|
|
704
|
-
|
|
710
|
+
// A drag ends with a click on the row it started on; that click is not one.
|
|
711
|
+
if (this._reorder?.consumeSwallowedClick())
|
|
705
712
|
return;
|
|
706
|
-
}
|
|
707
713
|
// A layer row is not on the canvas: a click makes it the active layer,
|
|
708
714
|
// where this viewer's new elements land (session only, never stored).
|
|
709
715
|
if (node.kind === 'layer') {
|
|
@@ -832,31 +838,106 @@ let EdgelessSelectionPaneWidget = (() => {
|
|
|
832
838
|
}
|
|
833
839
|
/* ── Drag to reorder ────────────────────────────────────────────────── */
|
|
834
840
|
/*
|
|
835
|
-
* The
|
|
836
|
-
*
|
|
837
|
-
*
|
|
838
|
-
*
|
|
839
|
-
*
|
|
840
|
-
*
|
|
841
|
-
* starts one.
|
|
841
|
+
* The gesture is the side panels' one controller (`createPanelReorderDrag`,
|
|
842
|
+
* `@labre/affine-shared/utils`, ADR 0034), shared with the frame panel:
|
|
843
|
+
* threshold, read-only refusal, mask and cursor, Escape and `pointercancel`
|
|
844
|
+
* as cancels, the swallowed click. What is the pane's own is below: which
|
|
845
|
+
* rows move (the pressed row, or the whole selection of one stack), where a
|
|
846
|
+
* gap lands them in their stack, the ghost and the line, and the write.
|
|
842
847
|
*/
|
|
848
|
+
_createReorderDrag() {
|
|
849
|
+
return createPanelReorderDrag({
|
|
850
|
+
readonly: () => this.std.store.readonly,
|
|
851
|
+
rows: () => this._shownRows().map(({ element }) => element),
|
|
852
|
+
bounds: () => this._paneBody(),
|
|
853
|
+
onPickUp: () => this._pickUp(),
|
|
854
|
+
dropAt: (gap, point) => this._dropAt(gap, point.clientY),
|
|
855
|
+
onMove: (drop, point) => {
|
|
856
|
+
this._drop = drop;
|
|
857
|
+
const panel = this._panel();
|
|
858
|
+
if (!panel)
|
|
859
|
+
return;
|
|
860
|
+
const box = panel.getBoundingClientRect();
|
|
861
|
+
this._ghost = {
|
|
862
|
+
x: point.clientX - box.left,
|
|
863
|
+
y: point.clientY - box.top,
|
|
864
|
+
};
|
|
865
|
+
},
|
|
866
|
+
onDrop: drop => this._commitDrop(drop),
|
|
867
|
+
onEnd: () => {
|
|
868
|
+
this._drag = null;
|
|
869
|
+
this._drop = null;
|
|
870
|
+
this._ghost = null;
|
|
871
|
+
},
|
|
872
|
+
mask: {
|
|
873
|
+
host: () => this._panel(),
|
|
874
|
+
className: 'selection-pane-drag-mask',
|
|
875
|
+
testId: 'selection-pane-drag-mask',
|
|
876
|
+
},
|
|
877
|
+
stateHost: () => this._panel(),
|
|
878
|
+
});
|
|
879
|
+
}
|
|
880
|
+
_panel() {
|
|
881
|
+
return (this.shadowRoot?.querySelector('[data-testid="selection-pane-panel"]') ?? null);
|
|
882
|
+
}
|
|
883
|
+
_paneBody() {
|
|
884
|
+
return (this.shadowRoot?.querySelector('[data-testid="selection-pane-body"]') ?? null);
|
|
885
|
+
}
|
|
886
|
+
/** The rows on screen, top first, with the rows they draw. */
|
|
887
|
+
_shownRows() {
|
|
888
|
+
const body = this._paneBody();
|
|
889
|
+
if (!body)
|
|
890
|
+
return [];
|
|
891
|
+
const byId = new Map(this._visibleRows.map(row => [row.node.id, row]));
|
|
892
|
+
return Array.from(body.querySelectorAll('[data-testid="selection-pane-row"], [data-testid="selection-pane-layer"]')).flatMap(element => {
|
|
893
|
+
const row = byId.get(element.dataset.id ?? '');
|
|
894
|
+
return row ? [{ element, row }] : [];
|
|
895
|
+
});
|
|
896
|
+
}
|
|
843
897
|
_onRowPointerDown(event, row) {
|
|
844
|
-
if (event.button !== 0 || this.std.store.readonly)
|
|
845
|
-
return;
|
|
846
898
|
const target = event.target;
|
|
847
899
|
if (target.closest('button, input'))
|
|
848
900
|
return;
|
|
849
|
-
this.
|
|
850
|
-
|
|
851
|
-
kind: row.node.kind,
|
|
852
|
-
parent: row.parent,
|
|
853
|
-
x: event.clientX,
|
|
854
|
-
y: event.clientY,
|
|
901
|
+
this._pressed = {
|
|
902
|
+
row,
|
|
855
903
|
width: event.currentTarget.getBoundingClientRect().width,
|
|
856
|
-
dragging: false,
|
|
857
904
|
};
|
|
858
|
-
|
|
859
|
-
|
|
905
|
+
this._reorder?.press(event);
|
|
906
|
+
}
|
|
907
|
+
/**
|
|
908
|
+
* The press became a drag. A canvas row picked up is selected, as the frame
|
|
909
|
+
* panel selects a card — unless it already is, and then the whole selection
|
|
910
|
+
* moves with it, as in the frame panel: every selected row the pane lists.
|
|
911
|
+
* Rows that are not all in the pressed row's stack and list have no one
|
|
912
|
+
* place to land, so every drop of theirs is refused, honestly, with a
|
|
913
|
+
* `not-allowed` cursor rather than a line that would write nothing.
|
|
914
|
+
*/
|
|
915
|
+
_pickUp() {
|
|
916
|
+
const pressed = this._pressed;
|
|
917
|
+
if (!pressed)
|
|
918
|
+
return;
|
|
919
|
+
const { node, parent } = pressed.row;
|
|
920
|
+
const drag = {
|
|
921
|
+
id: node.id,
|
|
922
|
+
kind: node.kind,
|
|
923
|
+
parent,
|
|
924
|
+
width: pressed.width,
|
|
925
|
+
moving: new Set([node.id]),
|
|
926
|
+
refused: false,
|
|
927
|
+
};
|
|
928
|
+
if (node.kind !== 'layer') {
|
|
929
|
+
const { selection } = this._gfx;
|
|
930
|
+
if (selection.selectedIds.includes(node.id)) {
|
|
931
|
+
const listed = selection.selectedIds.filter(id => this._lists.parentOf.has(id));
|
|
932
|
+
drag.moving = new Set([node.id, ...listed]);
|
|
933
|
+
const stackOf = this._stackOf(drag);
|
|
934
|
+
drag.refused = [...drag.moving].some(id => this._lists.parentOf.get(id) !== parent || stackOf?.(id) !== id);
|
|
935
|
+
}
|
|
936
|
+
else {
|
|
937
|
+
selection.set({ elements: [node.id], editing: false });
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
this._drag = drag;
|
|
860
941
|
}
|
|
861
942
|
/**
|
|
862
943
|
* Which model stands for a row in the dragged row's own stack — the stack
|
|
@@ -887,24 +968,16 @@ let EdgelessSelectionPaneWidget = (() => {
|
|
|
887
968
|
return undefined;
|
|
888
969
|
};
|
|
889
970
|
}
|
|
890
|
-
/**
|
|
891
|
-
|
|
971
|
+
/**
|
|
972
|
+
* Where a release over the gap `gap` (the controller's count of rows whose
|
|
973
|
+
* middle is above the pointer, at `clientY`) would land the dragged rows,
|
|
974
|
+
* or `null` to refuse it.
|
|
975
|
+
*/
|
|
976
|
+
_dropAt(gap, clientY) {
|
|
892
977
|
const drag = this._drag;
|
|
893
|
-
|
|
894
|
-
if (!drag || !body)
|
|
978
|
+
if (!drag || drag.refused)
|
|
895
979
|
return null;
|
|
896
|
-
const
|
|
897
|
-
if (clientX < box.left ||
|
|
898
|
-
clientX > box.right ||
|
|
899
|
-
clientY < box.top ||
|
|
900
|
-
clientY > box.bottom) {
|
|
901
|
-
return { kind: 'refused' };
|
|
902
|
-
}
|
|
903
|
-
const byId = new Map(this._visibleRows.map(row => [row.node.id, row]));
|
|
904
|
-
const shown = Array.from(body.querySelectorAll('[data-testid="selection-pane-row"], [data-testid="selection-pane-layer"]')).flatMap(element => {
|
|
905
|
-
const row = byId.get(element.dataset.id ?? '');
|
|
906
|
-
return row ? [{ element, row }] : [];
|
|
907
|
-
});
|
|
980
|
+
const shown = this._shownRows();
|
|
908
981
|
// A canvas row over a layer's header moves INTO that layer (§5).
|
|
909
982
|
if (drag.kind !== 'layer') {
|
|
910
983
|
const header = shown.find(({ element, row }) => {
|
|
@@ -916,23 +989,16 @@ let EdgelessSelectionPaneWidget = (() => {
|
|
|
916
989
|
if (header)
|
|
917
990
|
return { kind: 'into', id: header.row.node.id };
|
|
918
991
|
}
|
|
919
|
-
// The gap: past the middle of a row is below it.
|
|
920
|
-
let gap = 0;
|
|
921
|
-
for (const { element } of shown) {
|
|
922
|
-
const rect = element.getBoundingClientRect();
|
|
923
|
-
if (clientY > rect.top + rect.height / 2)
|
|
924
|
-
gap++;
|
|
925
|
-
}
|
|
926
992
|
const stackOf = this._stackOf(drag);
|
|
927
993
|
const slot = stackOf
|
|
928
994
|
? paneSlotAtGap(shown.map(({ row }) => row), gap, drag.parent, this._lists)
|
|
929
995
|
: null;
|
|
930
996
|
const list = slot ? this._lists.lists.get(slot.parent) : undefined;
|
|
931
997
|
const landing = slot && list && stackOf
|
|
932
|
-
? paneDropAbove(list, slot.index, drag.
|
|
998
|
+
? paneDropAbove(list, slot.index, drag.moving, stackOf)
|
|
933
999
|
: null;
|
|
934
1000
|
if (!slot || !landing)
|
|
935
|
-
return
|
|
1001
|
+
return null;
|
|
936
1002
|
const under = shown[gap]?.element;
|
|
937
1003
|
const last = shown[shown.length - 1]?.element;
|
|
938
1004
|
const top = under
|
|
@@ -947,57 +1013,30 @@ let EdgelessSelectionPaneWidget = (() => {
|
|
|
947
1013
|
left: 8 + slot.depth * INDENT_PX,
|
|
948
1014
|
};
|
|
949
1015
|
}
|
|
950
|
-
_moveGhost(event) {
|
|
951
|
-
const panel = this.shadowRoot?.querySelector('[data-testid="selection-pane-panel"]');
|
|
952
|
-
if (!panel)
|
|
953
|
-
return;
|
|
954
|
-
const box = panel.getBoundingClientRect();
|
|
955
|
-
this._ghost = { x: event.clientX - box.left, y: event.clientY - box.top };
|
|
956
|
-
}
|
|
957
|
-
/** A canvas row picked up is selected, as the frame panel selects a card. */
|
|
958
|
-
_pickUp(drag) {
|
|
959
|
-
if (drag.kind === 'layer')
|
|
960
|
-
return;
|
|
961
|
-
const { selection } = this._gfx;
|
|
962
|
-
if (selection.selectedIds.includes(drag.id))
|
|
963
|
-
return;
|
|
964
|
-
selection.set({ elements: [drag.id], editing: false });
|
|
965
|
-
}
|
|
966
1016
|
/**
|
|
967
1017
|
* One write per gesture, through the command: `layer` for a drop into a
|
|
968
|
-
* layer, one
|
|
969
|
-
* is where the
|
|
1018
|
+
* layer, one restack for a slot. The command writes nothing when the slot
|
|
1019
|
+
* is where the rows already are, and a refused drop never reaches it.
|
|
970
1020
|
*/
|
|
971
|
-
_commitDrop(
|
|
972
|
-
|
|
1021
|
+
_commitDrop(drop) {
|
|
1022
|
+
const drag = this._drag;
|
|
1023
|
+
if (!drag)
|
|
973
1024
|
return;
|
|
1025
|
+
const ids = [...drag.moving];
|
|
974
1026
|
if (drop.kind === 'into') {
|
|
975
|
-
this._run('canvas.layer.moveElements', {
|
|
976
|
-
ids: [drag.id],
|
|
977
|
-
layerId: drop.id,
|
|
978
|
-
});
|
|
1027
|
+
this._run('canvas.layer.moveElements', { ids, layerId: drop.id });
|
|
979
1028
|
return;
|
|
980
1029
|
}
|
|
981
1030
|
if (drag.kind === 'layer') {
|
|
982
1031
|
this._run('canvas.layer.reorder', { id: drag.id, above: drop.above });
|
|
983
1032
|
return;
|
|
984
1033
|
}
|
|
985
|
-
this._run('canvas.element.reorder', {
|
|
986
|
-
}
|
|
987
|
-
_endDrag() {
|
|
988
|
-
document.removeEventListener('pointermove', this._onDocumentPointerMove, true);
|
|
989
|
-
document.removeEventListener('pointerup', this._onDocumentPointerUp, true);
|
|
990
|
-
const wasDragging = this._drag?.dragging;
|
|
991
|
-
this._drag = null;
|
|
992
|
-
this._drop = null;
|
|
993
|
-
this._ghost = null;
|
|
994
|
-
if (wasDragging)
|
|
995
|
-
this.requestUpdate();
|
|
1034
|
+
this._run('canvas.element.reorder', { ids, above: drop.above });
|
|
996
1035
|
}
|
|
997
1036
|
_renderGhost() {
|
|
998
1037
|
const drag = this._drag;
|
|
999
1038
|
const at = this._ghost;
|
|
1000
|
-
if (!drag
|
|
1039
|
+
if (!drag || !at)
|
|
1001
1040
|
return nothing;
|
|
1002
1041
|
const style = styleMap({
|
|
1003
1042
|
transform: `translate(${at.x - 16}px, ${at.y - 8}px)`,
|
|
@@ -1021,6 +1060,7 @@ let EdgelessSelectionPaneWidget = (() => {
|
|
|
1021
1060
|
const type = model instanceof GfxBlockElementModel
|
|
1022
1061
|
? model.flavour
|
|
1023
1062
|
: model.type;
|
|
1063
|
+
const count = drag.moving.size;
|
|
1024
1064
|
return html `<div
|
|
1025
1065
|
class="selection-pane-drag-ghost"
|
|
1026
1066
|
data-testid="selection-pane-drag-ghost"
|
|
@@ -1030,11 +1070,18 @@ let EdgelessSelectionPaneWidget = (() => {
|
|
|
1030
1070
|
<span class="selection-pane-label"
|
|
1031
1071
|
>${selectionPaneRowLabel(this.std, model)}</span
|
|
1032
1072
|
>
|
|
1073
|
+
${count > 1
|
|
1074
|
+
? html `<span
|
|
1075
|
+
class="selection-pane-drag-count"
|
|
1076
|
+
data-testid="selection-pane-drag-count"
|
|
1077
|
+
>${count}</span
|
|
1078
|
+
>`
|
|
1079
|
+
: nothing}
|
|
1033
1080
|
</div>`;
|
|
1034
1081
|
}
|
|
1035
1082
|
_renderDropIndicator() {
|
|
1036
1083
|
const drop = this._drop;
|
|
1037
|
-
if (!this._drag
|
|
1084
|
+
if (!this._drag || drop?.kind !== 'slot')
|
|
1038
1085
|
return nothing;
|
|
1039
1086
|
return html `<div
|
|
1040
1087
|
class="selection-pane-drop-indicator"
|
|
@@ -1070,7 +1117,7 @@ let EdgelessSelectionPaneWidget = (() => {
|
|
|
1070
1117
|
const drop = this._drop?.kind === 'into' && this._drop.id === node.id
|
|
1071
1118
|
? 'into'
|
|
1072
1119
|
: undefined;
|
|
1073
|
-
const dragging = this._drag?.
|
|
1120
|
+
const dragging = this._drag?.moving.has(node.id) ?? false;
|
|
1074
1121
|
return html `<div
|
|
1075
1122
|
class="selection-pane-row selection-pane-layer-row"
|
|
1076
1123
|
role="treeitem"
|
|
@@ -1185,7 +1232,7 @@ let EdgelessSelectionPaneWidget = (() => {
|
|
|
1185
1232
|
const drop = this._drop?.kind === 'into' && this._drop.id === node.id
|
|
1186
1233
|
? 'into'
|
|
1187
1234
|
: undefined;
|
|
1188
|
-
const dragging = this._drag?.
|
|
1235
|
+
const dragging = this._drag?.moving.has(node.id) ?? false;
|
|
1189
1236
|
return html `<div
|
|
1190
1237
|
class="selection-pane-row"
|
|
1191
1238
|
role="treeitem"
|
|
@@ -1303,24 +1350,19 @@ let EdgelessSelectionPaneWidget = (() => {
|
|
|
1303
1350
|
this._visibleRows = rows;
|
|
1304
1351
|
this._lists = paneLists(full);
|
|
1305
1352
|
const title = translateKey(this.std, ...SELECTION_PANE_TITLE);
|
|
1306
|
-
const dragState = this._drag?.dragging
|
|
1307
|
-
? this._drop && this._drop.kind !== 'refused'
|
|
1308
|
-
? 'valid'
|
|
1309
|
-
: 'invalid'
|
|
1310
|
-
: undefined;
|
|
1311
1353
|
// `pointermove` too: the editor turns every move over the host into a
|
|
1312
1354
|
// cursor selection, and a selection with nothing recoverable in it makes
|
|
1313
1355
|
// the range binding focus the host — which blurred a layer's rename field
|
|
1314
1356
|
// the moment the pointer moved (a group's survived only because its click
|
|
1315
1357
|
// had selected it). The pane's own drag listens on the document, in the
|
|
1316
|
-
// capture phase, so it still sees every move.
|
|
1358
|
+
// capture phase, so it still sees every move. Its `data-drag` and its
|
|
1359
|
+
// mask are the drag controller's, set outside this template.
|
|
1317
1360
|
return html `<div
|
|
1318
1361
|
class="selection-pane-panel"
|
|
1319
1362
|
role="dialog"
|
|
1320
1363
|
tabindex="-1"
|
|
1321
1364
|
aria-label=${title}
|
|
1322
1365
|
data-testid="selection-pane-panel"
|
|
1323
|
-
data-drag=${dragState ?? nothing}
|
|
1324
1366
|
@pointerdown=${this._swallow}
|
|
1325
1367
|
@pointerup=${this._swallow}
|
|
1326
1368
|
@pointermove=${this._swallow}
|
|
@@ -1366,12 +1408,6 @@ let EdgelessSelectionPaneWidget = (() => {
|
|
|
1366
1408
|
</div>`}
|
|
1367
1409
|
${this._renderDropIndicator()}
|
|
1368
1410
|
</div>
|
|
1369
|
-
${this._drag?.dragging
|
|
1370
|
-
? html `<div
|
|
1371
|
-
class="selection-pane-drag-mask"
|
|
1372
|
-
data-testid="selection-pane-drag-mask"
|
|
1373
|
-
></div>`
|
|
1374
|
-
: nothing}
|
|
1375
1411
|
${this._renderGhost()}
|
|
1376
1412
|
</div>`;
|
|
1377
1413
|
}
|
|
@@ -18,7 +18,7 @@ export interface BlockStdOptions {
|
|
|
18
18
|
extensions: ExtensionType[];
|
|
19
19
|
}
|
|
20
20
|
export declare class BlockStdScope {
|
|
21
|
-
static internalExtensions: (typeof ViewStore | typeof UIEventDispatcher | typeof RangeManager | typeof CommandManager | typeof
|
|
21
|
+
static internalExtensions: (typeof ViewStore | typeof UIEventDispatcher | typeof RangeManager | typeof CommandManager | typeof ElementHighlightManager | typeof GridManager | typeof GfxSelectionManager | typeof SurfaceMiddlewareExtension | typeof ViewManager | typeof LayerManager | typeof ServiceManager)[];
|
|
22
22
|
readonly container: Container;
|
|
23
23
|
readonly store: Store;
|
|
24
24
|
readonly provider: ServiceProvider;
|
package/dist/commands.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { frameCommands } from './_pkgs/affine-block-frame/index.js';
|
|
1
2
|
import { copyLinkCommands, coreCommands, pivotCommands, readingCommands, tagCommands, } from './_pkgs/affine-block-root/index.js';
|
|
2
3
|
import { auditCommands, canvasGridCommands, exportSvgCommands, mapQualityCommands, selectionPaneCommands, userLayerCommands, } from './_pkgs/affine-block-surface/index.js';
|
|
3
4
|
import { edgeDirectionCommands } from './_pkgs/affine-gfx-connector/index.js';
|
|
@@ -55,6 +56,7 @@ export function getCommands(flags) {
|
|
|
55
56
|
...mapQualityCommands,
|
|
56
57
|
...exportSvgCommands,
|
|
57
58
|
...selectionPaneCommands,
|
|
59
|
+
...frameCommands,
|
|
58
60
|
...canvasGridCommands,
|
|
59
61
|
...userLayerCommands,
|
|
60
62
|
...edgeDirectionCommands,
|