@formicoidea/labre-core 0.56.0 → 0.58.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.
Files changed (28) hide show
  1. package/architecture/code.c4 +13 -13
  2. package/architecture/domain.c4 +2504 -0
  3. package/architecture/likec4.config.json +3 -3
  4. package/dist/_pkgs/affine-block-surface/extensions/reading-toolbar.js +12 -12
  5. package/dist/_pkgs/affine-components/highlight-dropdown-menu/highlight-duotone-icon.js +8 -8
  6. package/dist/_pkgs/affine-components/highlight-dropdown-menu/text-duotone-icon.js +11 -11
  7. package/dist/_pkgs/affine-fragment-doc-title/title-band/title-band.d.ts +3 -1
  8. package/dist/_pkgs/affine-fragment-doc-title/title-band/title-band.js +15 -2
  9. package/dist/_pkgs/affine-fragment-frame-panel/body/frame-panel-body.js +4 -4
  10. package/dist/_pkgs/affine-fragment-frame-panel/card/frame-card-title.d.ts +19 -6
  11. package/dist/_pkgs/affine-fragment-frame-panel/card/frame-card-title.js +136 -52
  12. package/dist/_pkgs/affine-fragment-frame-panel/card/frame-card.js +22 -4
  13. package/dist/_pkgs/affine-fragment-frame-panel/card/frame-preview.d.ts +12 -0
  14. package/dist/_pkgs/affine-fragment-frame-panel/card/frame-preview.js +81 -5
  15. package/dist/_pkgs/affine-fragment-frame-panel/card/preview-size.d.ts +9 -0
  16. package/dist/_pkgs/affine-fragment-frame-panel/card/preview-size.js +20 -0
  17. package/dist/_pkgs/affine-fragment-frame-panel/effects.js +0 -2
  18. package/dist/_pkgs/affine-fragment-frame-panel/frame-panel.js +2 -0
  19. package/dist/_pkgs/affine-widget-edgeless-zoom-toolbar/index.js +26 -26
  20. package/dist/_pkgs/affine-widget-keyboard-toolbar/icons.js +98 -98
  21. package/dist/_pkgs/affine-widget-page-dragging-area/index.js +10 -10
  22. package/dist/_pkgs/affine-widget-viewport-overlay/index.js +13 -13
  23. package/dist/_pkgs/data-view/core/utils/menu-title.js +17 -17
  24. package/dist/host-panels.d.ts +9 -4
  25. package/dist/host-panels.js +19 -4
  26. package/package.json +1 -1
  27. package/dist/_pkgs/affine-fragment-frame-panel/card/frame-card-title-editor.d.ts +0 -25
  28. package/dist/_pkgs/affine-fragment-frame-panel/card/frame-card-title-editor.js +0 -181
@@ -1,3 +1,3 @@
1
- {
2
- "name": "blocksuite"
3
- }
1
+ {
2
+ "name": "blocksuite"
3
+ }
@@ -58,18 +58,18 @@ const READ_LABEL_FALLBACK = 'Read this component';
58
58
  * Drawn inline like its neighbours: this package does not depend on
59
59
  * `@blocksuite/icons` and one glyph is not worth a new dependency.
60
60
  */
61
- const ReadIcon = html `<svg
62
- width="20"
63
- height="20"
64
- viewBox="0 0 24 24"
65
- fill="none"
66
- stroke="currentColor"
67
- stroke-width="2"
68
- stroke-linecap="round"
69
- stroke-linejoin="round"
70
- >
71
- <path d="M2 12s3.5-6 10-6 10 6 10 6-3.5 6-10 6-10-6-10-6z" />
72
- <circle cx="12" cy="12" r="3" />
61
+ const ReadIcon = html `<svg
62
+ width="20"
63
+ height="20"
64
+ viewBox="0 0 24 24"
65
+ fill="none"
66
+ stroke="currentColor"
67
+ stroke-width="2"
68
+ stroke-linecap="round"
69
+ stroke-linejoin="round"
70
+ >
71
+ <path d="M2 12s3.5-6 10-6 10 6 10 6-3.5 6-10 6-10-6-10-6z" />
72
+ <circle cx="12" cy="12" r="3" />
73
73
  </svg>`;
74
74
  /** The command this module drives. Spelled once. */
75
75
  const ELEMENT_READ_ID = 'element.read';
@@ -1,14 +1,14 @@
1
1
  import { HighLightDuotoneIcon } from '@blocksuite/icons/lit';
2
2
  import { css, LitElement } from 'lit';
3
3
  export class HighlightDuotoneIcon extends LitElement {
4
- static { this.styles = css `
5
- svg {
6
- display: flex;
7
- font-size: 20px;
8
- }
9
- svg > path:nth-child(1) {
10
- fill: var(--color, unset);
11
- }
4
+ static { this.styles = css `
5
+ svg {
6
+ display: flex;
7
+ font-size: 20px;
8
+ }
9
+ svg > path:nth-child(1) {
10
+ fill: var(--color, unset);
11
+ }
12
12
  `; }
13
13
  render() {
14
14
  return HighLightDuotoneIcon();
@@ -1,17 +1,17 @@
1
1
  import { TextBackgroundDuotoneIcon } from '@blocksuite/icons/lit';
2
2
  import { css, LitElement } from 'lit';
3
3
  export class TextDuotoneIcon extends LitElement {
4
- static { this.styles = css `
5
- svg {
6
- display: flex;
7
- font-size: 20px;
8
- }
9
- svg > path:nth-child(1) {
10
- fill: var(--background, unset);
11
- }
12
- svg > path:nth-child(3) {
13
- fill: var(--color, unset);
14
- }
4
+ static { this.styles = css `
5
+ svg {
6
+ display: flex;
7
+ font-size: 20px;
8
+ }
9
+ svg > path:nth-child(1) {
10
+ fill: var(--background, unset);
11
+ }
12
+ svg > path:nth-child(3) {
13
+ fill: var(--color, unset);
14
+ }
15
15
  `; }
16
16
  render() {
17
17
  return TextBackgroundDuotoneIcon();
@@ -1,5 +1,5 @@
1
1
  import { type BlockStdScope, ShadowlessElement } from '../../std/index.js';
2
- import { nothing, type TemplateResult } from 'lit';
2
+ import { nothing, type PropertyValues, type TemplateResult } from 'lit';
3
3
  export declare const LABRE_TITLE_BAND = "labre-title-band";
4
4
  declare const TitleBand_base: typeof ShadowlessElement & import("../../global/utils/types.js").Constructor<import("../../global/lit/with-disposable.js").DisposableClass>;
5
5
  /**
@@ -67,6 +67,8 @@ export declare class TitleBand extends TitleBand_base {
67
67
  private _renderTools;
68
68
  private _renderSheet;
69
69
  private _renderNotShown;
70
+ private readonly _stdProvider;
71
+ willUpdate(changed: PropertyValues<this>): void;
70
72
  connectedCallback(): void;
71
73
  render(): TemplateResult<1> | typeof nothing;
72
74
  accessor std: BlockStdScope | null;
@@ -37,10 +37,11 @@ import { DOC_UNTITLED, FeatureFlagService, formatLocale, PropertiesPanelProvider
37
37
  import { stopPropagation } from '../../affine-shared/utils/index.js';
38
38
  import { createStandaloneCell, StandaloneCellMetaProvider, } from '../../data-view/index.js';
39
39
  import { SignalWatcher, WithDisposable } from '../../global/lit/index.js';
40
- import { ShadowlessElement } from '../../std/index.js';
40
+ import { ShadowlessElement, stdContext } from '../../std/index.js';
41
+ import { ContextProvider } from '@lit/context';
41
42
  import { LinkedPageIcon, PlusIcon, SidebarIcon, ToggleDownIcon, ToggleRightIcon, } from '@blocksuite/icons/lit';
42
43
  import { computed, signal } from '@preact/signals-core';
43
- import { css, html, nothing } from 'lit';
44
+ import { css, html, nothing, } from 'lit';
44
45
  import { property } from 'lit/decorators.js';
45
46
  import { repeat } from 'lit/directives/repeat.js';
46
47
  import { TITLE_BAND_ADD, TITLE_BAND_COLLAPSE, TITLE_BAND_EMPTY, TITLE_BAND_EXPAND, TITLE_BAND_LABEL, TITLE_BAND_LOADING, TITLE_BAND_NOT_SHOWN, TITLE_BAND_OPEN_PANEL, TITLE_BAND_SHOW_HERE, } from '../translations.js';
@@ -629,6 +630,11 @@ let TitleBand = (() => {
629
630
  })}
630
631
  </div>`;
631
632
  }
633
+ willUpdate(changed) {
634
+ super.willUpdate(changed);
635
+ if (changed.has('std') && this.std)
636
+ this._stdProvider.setValue(this.std);
637
+ }
632
638
  connectedCallback() {
633
639
  super.connectedCallback();
634
640
  // The band lives inside the title and inside the note: a key or a press
@@ -697,6 +703,13 @@ let TitleBand = (() => {
697
703
  }
698
704
  this._openPanel();
699
705
  };
706
+ // The band is drawn in the title, outside `editor-host`, so its cells find
707
+ // no `stdContext` to consume and their tag menu and date picker spoke
708
+ // English under a French host (recette 1, 2026-10-22). The band hands them
709
+ // its own scope.
710
+ this._stdProvider = new ContextProvider(this, {
711
+ context: stdContext,
712
+ });
700
713
  this.#std_accessor_storage = __runInitializers(this, _std_initializers, null);
701
714
  this.#docId_accessor_storage = (__runInitializers(this, _std_extraInitializers), __runInitializers(this, _docId_initializers, ''));
702
715
  this.#surface_accessor_storage = (__runInitializers(this, _docId_extraInitializers), __runInitializers(this, _surface_initializers, 'page'));
@@ -64,13 +64,13 @@ function reorderCommand() {
64
64
  const styles = css `
65
65
  .frame-list-container {
66
66
  display: flex;
67
- align-items: start;
67
+ align-items: stretch;
68
68
  box-sizing: border-box;
69
69
  flex-direction: column;
70
70
  width: 100%;
71
71
  gap: 16px;
72
72
  position: relative;
73
- margin: 0 8px;
73
+ padding: 0 8px;
74
74
  }
75
75
 
76
76
  .no-frame-container {
@@ -101,8 +101,8 @@ const styles = css `
101
101
  background-color: var(--affine-blue-600);
102
102
  position: absolute;
103
103
  contain: layout size;
104
- width: 284px;
105
- left: 0;
104
+ left: 8px;
105
+ right: 8px;
106
106
  }
107
107
 
108
108
  /*
@@ -1,24 +1,37 @@
1
1
  import type { FrameBlockModel } from '../../affine-model/index.js';
2
- import { ShadowlessElement } from '../../std/index.js';
2
+ import { type BlockStdScope, ShadowlessElement } from '../../std/index.js';
3
3
  import { type PropertyValues } from 'lit';
4
4
  export declare const AFFINE_FRAME_CARD_TITLE = "affine-frame-card-title";
5
5
  declare const FrameCardTitle_base: typeof ShadowlessElement & import("../../global/utils/types.js").Constructor<import("../../global/lit/with-disposable.js").DisposableClass>;
6
+ /**
7
+ * A card's number and name. A double-click on the name renames the frame in
8
+ * place (recette 1, P0-1.4): Enter or leaving the field saves, Escape cancels.
9
+ *
10
+ * The field is a plain input committed once, through `canvas.frame.rename`
11
+ * (the selection pane's own rename): the read-only refusal, the empty and
12
+ * unchanged no-ops and the one undo step are the command's. It used to be a
13
+ * rich text bound live to the stored title, which wrote on every key — an
14
+ * Escape could not take a keystroke back. The descriptor is imported, not
15
+ * looked up in the registry, so the rename works in page mode too.
16
+ */
6
17
  export declare class FrameCardTitle extends FrameCardTitle_base {
7
18
  static styles: import("lit").CSSResult;
8
19
  private readonly _clearTitleDisposables;
9
- private readonly _mountTitleEditor;
10
20
  private _titleDisposables;
11
21
  private readonly _updateElement;
22
+ private readonly _startEditing;
23
+ private _commit;
24
+ private readonly _onKeydown;
12
25
  private _setFrameDisposables;
13
- connectedCallback(): void;
14
26
  disconnectedCallback(): void;
27
+ private _renderName;
15
28
  render(): import("lit-html").TemplateResult<1>;
16
29
  updated(_changedProperties: PropertyValues): void;
30
+ private accessor _editing;
31
+ private accessor _input;
17
32
  accessor cardIndex: number;
18
33
  accessor frame: FrameBlockModel;
19
- accessor titleContainer: HTMLElement;
20
- accessor titleContentElement: HTMLElement;
21
- accessor titleIndexElement: HTMLElement;
34
+ accessor std: BlockStdScope;
22
35
  }
23
36
  declare global {
24
37
  interface HTMLElementTagNameMap {
@@ -32,12 +32,13 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
32
32
  }
33
33
  return useValue ? value : void 0;
34
34
  };
35
+ import { selectionPaneCommands } from '../../affine-block-surface/index.js';
36
+ import { TOOLBAR_RENAME, translateKey } from '../../affine-shared/services/index.js';
35
37
  import { DisposableGroup } from '../../global/disposable/index.js';
36
38
  import { WithDisposable } from '../../global/lit/index.js';
37
- import { ShadowlessElement } from '../../std/index.js';
39
+ import { runCommand, ShadowlessElement, } from '../../std/index.js';
38
40
  import { css, html } from 'lit';
39
- import { property, query } from 'lit/decorators.js';
40
- import { FrameCardTitleEditor } from './frame-card-title-editor.js';
41
+ import { property, query, state } from 'lit/decorators.js';
41
42
  const styles = css `
42
43
  .frame-card-title-container {
43
44
  display: flex;
@@ -82,42 +83,90 @@ const styles = css `
82
83
  overflow: hidden;
83
84
  text-overflow: ellipsis;
84
85
  flex: 1;
86
+ min-width: 0;
87
+ }
88
+
89
+ .frame-card-title-container .card-title-input {
90
+ flex: 1;
91
+ min-width: 0;
92
+ height: 20px;
93
+ box-sizing: border-box;
94
+ padding: 0 4px;
95
+ border: 1px solid var(--affine-primary-color);
96
+ border-radius: 4px;
97
+ background: var(--affine-background-primary-color);
98
+ box-shadow: var(--affine-active-shadow);
99
+ color: var(--affine-text-primary-color);
100
+ font: inherit;
101
+ line-height: 18px;
102
+ outline: none;
85
103
  }
86
104
  `;
87
105
  export const AFFINE_FRAME_CARD_TITLE = 'affine-frame-card-title';
106
+ /** How the panel invokes the registry, like its reorder and the pane's rows. */
107
+ const PANEL_INVOCATION = {
108
+ surface: 'contextual-toolbar',
109
+ source: 'toolbar:general',
110
+ };
111
+ function renameCommand() {
112
+ const command = selectionPaneCommands.find(c => c.id === 'canvas.frame.rename');
113
+ if (!command)
114
+ throw new Error('frame panel: no canvas.frame.rename');
115
+ return command;
116
+ }
117
+ /**
118
+ * A card's number and name. A double-click on the name renames the frame in
119
+ * place (recette 1, P0-1.4): Enter or leaving the field saves, Escape cancels.
120
+ *
121
+ * The field is a plain input committed once, through `canvas.frame.rename`
122
+ * (the selection pane's own rename): the read-only refusal, the empty and
123
+ * unchanged no-ops and the one undo step are the command's. It used to be a
124
+ * rich text bound live to the stored title, which wrote on every key — an
125
+ * Escape could not take a keystroke back. The descriptor is imported, not
126
+ * looked up in the registry, so the rename works in page mode too.
127
+ */
88
128
  let FrameCardTitle = (() => {
89
129
  let _classSuper = WithDisposable(ShadowlessElement);
130
+ let __editing_decorators;
131
+ let __editing_initializers = [];
132
+ let __editing_extraInitializers = [];
133
+ let __input_decorators;
134
+ let __input_initializers = [];
135
+ let __input_extraInitializers = [];
90
136
  let _cardIndex_decorators;
91
137
  let _cardIndex_initializers = [];
92
138
  let _cardIndex_extraInitializers = [];
93
139
  let _frame_decorators;
94
140
  let _frame_initializers = [];
95
141
  let _frame_extraInitializers = [];
96
- let _titleContainer_decorators;
97
- let _titleContainer_initializers = [];
98
- let _titleContainer_extraInitializers = [];
99
- let _titleContentElement_decorators;
100
- let _titleContentElement_initializers = [];
101
- let _titleContentElement_extraInitializers = [];
102
- let _titleIndexElement_decorators;
103
- let _titleIndexElement_initializers = [];
104
- let _titleIndexElement_extraInitializers = [];
142
+ let _std_decorators;
143
+ let _std_initializers = [];
144
+ let _std_extraInitializers = [];
105
145
  return class FrameCardTitle extends _classSuper {
106
146
  static {
107
147
  const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
148
+ __editing_decorators = [state()];
149
+ __input_decorators = [query('.card-title-input')];
108
150
  _cardIndex_decorators = [property({ attribute: false })];
109
151
  _frame_decorators = [property({ attribute: false })];
110
- _titleContainer_decorators = [query('.frame-card-title-container')];
111
- _titleContentElement_decorators = [query('.frame-card-title-container .card-title')];
112
- _titleIndexElement_decorators = [query('.frame-card-title-container .card-index')];
152
+ _std_decorators = [property({ attribute: false })];
153
+ __esDecorate(this, null, __editing_decorators, { kind: "accessor", name: "_editing", static: false, private: false, access: { has: obj => "_editing" in obj, get: obj => obj._editing, set: (obj, value) => { obj._editing = value; } }, metadata: _metadata }, __editing_initializers, __editing_extraInitializers);
154
+ __esDecorate(this, null, __input_decorators, { kind: "accessor", name: "_input", static: false, private: false, access: { has: obj => "_input" in obj, get: obj => obj._input, set: (obj, value) => { obj._input = value; } }, metadata: _metadata }, __input_initializers, __input_extraInitializers);
113
155
  __esDecorate(this, null, _cardIndex_decorators, { kind: "accessor", name: "cardIndex", static: false, private: false, access: { has: obj => "cardIndex" in obj, get: obj => obj.cardIndex, set: (obj, value) => { obj.cardIndex = value; } }, metadata: _metadata }, _cardIndex_initializers, _cardIndex_extraInitializers);
114
156
  __esDecorate(this, null, _frame_decorators, { kind: "accessor", name: "frame", static: false, private: false, access: { has: obj => "frame" in obj, get: obj => obj.frame, set: (obj, value) => { obj.frame = value; } }, metadata: _metadata }, _frame_initializers, _frame_extraInitializers);
115
- __esDecorate(this, null, _titleContainer_decorators, { kind: "accessor", name: "titleContainer", static: false, private: false, access: { has: obj => "titleContainer" in obj, get: obj => obj.titleContainer, set: (obj, value) => { obj.titleContainer = value; } }, metadata: _metadata }, _titleContainer_initializers, _titleContainer_extraInitializers);
116
- __esDecorate(this, null, _titleContentElement_decorators, { kind: "accessor", name: "titleContentElement", static: false, private: false, access: { has: obj => "titleContentElement" in obj, get: obj => obj.titleContentElement, set: (obj, value) => { obj.titleContentElement = value; } }, metadata: _metadata }, _titleContentElement_initializers, _titleContentElement_extraInitializers);
117
- __esDecorate(this, null, _titleIndexElement_decorators, { kind: "accessor", name: "titleIndexElement", static: false, private: false, access: { has: obj => "titleIndexElement" in obj, get: obj => obj.titleIndexElement, set: (obj, value) => { obj.titleIndexElement = value; } }, metadata: _metadata }, _titleIndexElement_initializers, _titleIndexElement_extraInitializers);
157
+ __esDecorate(this, null, _std_decorators, { kind: "accessor", name: "std", static: false, private: false, access: { has: obj => "std" in obj, get: obj => obj.std, set: (obj, value) => { obj.std = value; } }, metadata: _metadata }, _std_initializers, _std_extraInitializers);
118
158
  if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
119
159
  }
120
160
  static { this.styles = styles; }
161
+ _commit(input) {
162
+ if (!this._editing)
163
+ return;
164
+ this._editing = false;
165
+ runCommand(this.std, renameCommand(), PANEL_INVOCATION, {
166
+ id: this.frame.id,
167
+ title: input.value,
168
+ });
169
+ }
121
170
  _setFrameDisposables(title) {
122
171
  this._clearTitleDisposables();
123
172
  title.observe(this._updateElement);
@@ -128,13 +177,39 @@ let FrameCardTitle = (() => {
128
177
  },
129
178
  });
130
179
  }
131
- connectedCallback() {
132
- super.connectedCallback();
133
- }
134
180
  disconnectedCallback() {
135
181
  super.disconnectedCallback();
136
182
  this._clearTitleDisposables();
137
183
  }
184
+ _renderName() {
185
+ const name = this.frame.props.title.toString();
186
+ if (!this._editing) {
187
+ return html `<div
188
+ class="card-title"
189
+ data-testid="frame-card-title"
190
+ title=${name}
191
+ @click=${(e) => e.stopPropagation()}
192
+ @dblclick=${this._startEditing}
193
+ >
194
+ ${name}
195
+ </div>`;
196
+ }
197
+ return html `<input
198
+ class="card-title-input"
199
+ data-testid="frame-card-title-input"
200
+ aria-label=${translateKey(this.std, ...TOOLBAR_RENAME)}
201
+ .value=${name}
202
+ @click=${(e) => e.stopPropagation()}
203
+ @dblclick=${(e) => e.stopPropagation()}
204
+ @select=${(e) => {
205
+ // The field's own text selection bubbles a native select event, which
206
+ // the card's own select listener would read as a frame pick.
207
+ e.stopPropagation();
208
+ }}
209
+ @keydown=${this._onKeydown}
210
+ @blur=${(e) => this._commit(e.target)}
211
+ />`;
212
+ }
138
213
  render() {
139
214
  return html `<div class="frame-card-title-container">
140
215
  <div
@@ -144,61 +219,70 @@ let FrameCardTitle = (() => {
144
219
  >
145
220
  ${this.cardIndex + 1}
146
221
  </div>
147
- <div class="card-title">
148
- <span
149
- @click=${(e) => e.stopPropagation()}
150
- @dblclick=${this._mountTitleEditor}
151
- >${this.frame.props.title}</span
152
- >
153
- </div>
222
+ ${this._renderName()}
154
223
  </div>`;
155
224
  }
156
225
  updated(_changedProperties) {
157
226
  if (_changedProperties.has('frame')) {
158
227
  this._setFrameDisposables(this.frame.props.title.yText);
159
228
  }
229
+ if (_changedProperties.has('_editing') && this._editing) {
230
+ this._input?.focus();
231
+ this._input?.select();
232
+ }
160
233
  }
234
+ #_editing_accessor_storage;
235
+ get _editing() { return this.#_editing_accessor_storage; }
236
+ set _editing(value) { this.#_editing_accessor_storage = value; }
237
+ #_input_accessor_storage;
238
+ get _input() { return this.#_input_accessor_storage; }
239
+ set _input(value) { this.#_input_accessor_storage = value; }
161
240
  #cardIndex_accessor_storage;
162
241
  get cardIndex() { return this.#cardIndex_accessor_storage; }
163
242
  set cardIndex(value) { this.#cardIndex_accessor_storage = value; }
164
243
  #frame_accessor_storage;
165
244
  get frame() { return this.#frame_accessor_storage; }
166
245
  set frame(value) { this.#frame_accessor_storage = value; }
167
- #titleContainer_accessor_storage;
168
- get titleContainer() { return this.#titleContainer_accessor_storage; }
169
- set titleContainer(value) { this.#titleContainer_accessor_storage = value; }
170
- #titleContentElement_accessor_storage;
171
- get titleContentElement() { return this.#titleContentElement_accessor_storage; }
172
- set titleContentElement(value) { this.#titleContentElement_accessor_storage = value; }
173
- #titleIndexElement_accessor_storage;
174
- get titleIndexElement() { return this.#titleIndexElement_accessor_storage; }
175
- set titleIndexElement(value) { this.#titleIndexElement_accessor_storage = value; }
246
+ #std_accessor_storage;
247
+ get std() { return this.#std_accessor_storage; }
248
+ set std(value) { this.#std_accessor_storage = value; }
176
249
  constructor() {
177
250
  super(...arguments);
178
251
  this._clearTitleDisposables = () => {
179
252
  this._titleDisposables?.dispose();
180
253
  this._titleDisposables = null;
181
254
  };
182
- this._mountTitleEditor = (e) => {
183
- e.stopPropagation();
184
- const titleEditor = new FrameCardTitleEditor();
185
- titleEditor.frameModel = this.frame;
186
- titleEditor.titleContentElement = this.titleContentElement;
187
- const left = this.titleIndexElement.offsetWidth + 6;
188
- titleEditor.left = left;
189
- titleEditor.maxWidth = this.titleContainer.offsetWidth - left - 6;
190
- this.titleContainer.append(titleEditor);
191
- };
192
255
  this._titleDisposables = null;
193
256
  this._updateElement = () => {
194
257
  this.requestUpdate();
195
258
  };
196
- this.#cardIndex_accessor_storage = __runInitializers(this, _cardIndex_initializers, void 0);
259
+ this._startEditing = (e) => {
260
+ e.stopPropagation();
261
+ if (this.std.store.readonly)
262
+ return;
263
+ this._editing = true;
264
+ };
265
+ this._onKeydown = (e) => {
266
+ // The canvas and the host's panel bind keys (Backspace, Escape closes a
267
+ // panel): a key typed into the name reaches neither.
268
+ e.stopPropagation();
269
+ if (e.isComposing)
270
+ return;
271
+ if (e.key === 'Enter') {
272
+ e.preventDefault();
273
+ this._commit(e.currentTarget);
274
+ }
275
+ else if (e.key === 'Escape') {
276
+ e.preventDefault();
277
+ this._editing = false;
278
+ }
279
+ };
280
+ this.#_editing_accessor_storage = __runInitializers(this, __editing_initializers, false);
281
+ this.#_input_accessor_storage = (__runInitializers(this, __editing_extraInitializers), __runInitializers(this, __input_initializers, null));
282
+ this.#cardIndex_accessor_storage = (__runInitializers(this, __input_extraInitializers), __runInitializers(this, _cardIndex_initializers, void 0));
197
283
  this.#frame_accessor_storage = (__runInitializers(this, _cardIndex_extraInitializers), __runInitializers(this, _frame_initializers, void 0));
198
- this.#titleContainer_accessor_storage = (__runInitializers(this, _frame_extraInitializers), __runInitializers(this, _titleContainer_initializers, void 0));
199
- this.#titleContentElement_accessor_storage = (__runInitializers(this, _titleContainer_extraInitializers), __runInitializers(this, _titleContentElement_initializers, void 0));
200
- this.#titleIndexElement_accessor_storage = (__runInitializers(this, _titleContentElement_extraInitializers), __runInitializers(this, _titleIndexElement_initializers, void 0));
201
- __runInitializers(this, _titleIndexElement_extraInitializers);
284
+ this.#std_accessor_storage = (__runInitializers(this, _frame_extraInitializers), __runInitializers(this, _std_initializers, void 0));
285
+ __runInitializers(this, _std_extraInitializers);
202
286
  }
203
287
  };
204
288
  })();
@@ -42,11 +42,16 @@ const styles = css `
42
42
  display: block;
43
43
  }
44
44
 
45
+ /*
46
+ The card takes the panel's width and its preview the frame's proportions
47
+ (recette 1, P0-1.2): widening the sidebar grows every card, so fewer fit
48
+ on screen. No fixed size anywhere; a ghost gets its width from the card it
49
+ copies.
50
+ */
45
51
  .frame-card-container {
46
52
  display: flex;
47
53
  flex-direction: column;
48
- width: 284px;
49
- height: 198px;
54
+ width: 100%;
50
55
  gap: 8px;
51
56
 
52
57
  position: relative;
@@ -55,7 +60,6 @@ const styles = css `
55
60
  .frame-card-body {
56
61
  display: flex;
57
62
  width: 100%;
58
- height: 170px;
59
63
  box-sizing: border-box;
60
64
  justify-content: center;
61
65
  align-items: center;
@@ -67,8 +71,15 @@ const styles = css `
67
71
  position: relative;
68
72
  }
69
73
 
74
+ /* A ring, not a thicker border: the preview inside keeps its width. */
70
75
  .frame-card-container.selected .frame-card-body {
71
- border: 2px solid var(--affine-primary-color);
76
+ border-color: var(--affine-primary-color);
77
+ box-shadow: 0 0 0 1px var(--affine-primary-color);
78
+ }
79
+
80
+ .frame-card-body > frame-preview {
81
+ border-radius: 7px;
82
+ overflow: hidden;
72
83
  }
73
84
 
74
85
  .frame-card-container.dragging {
@@ -84,6 +95,11 @@ const styles = css `
84
95
  display: none;
85
96
  }
86
97
 
98
+ /* The copy stacked behind draws no preview: it keeps a card's shape. */
99
+ .frame-card-container.dragging .frame-card-body {
100
+ aspect-ratio: 16 / 9;
101
+ }
102
+
87
103
  .frame-card-container.dragging .dragging-card-number {
88
104
  position: absolute;
89
105
  bottom: 0;
@@ -228,6 +244,7 @@ let FrameCard = (() => {
228
244
  : html `<affine-frame-card-title
229
245
  .cardIndex=${this.cardIndex}
230
246
  .frame=${this.frame}
247
+ .std=${this.std}
231
248
  ></affine-frame-card-title>`}
232
249
  <div
233
250
  class="frame-card-body"
@@ -240,6 +257,7 @@ let FrameCard = (() => {
240
257
  : html `<frame-preview
241
258
  .frame=${this.frame}
242
259
  .std=${this.std}
260
+ .fluid=${true}
243
261
  ></frame-preview>`}
244
262
  ${this._DraggingCardNumber()}
245
263
  </div>
@@ -13,6 +13,7 @@ export declare class FramePreview extends FramePreview_base {
13
13
  private _runtimePreviewExt;
14
14
  private get _viewExtensionManager();
15
15
  private get _previewSpec();
16
+ private _resizeObserver;
16
17
  private readonly _updateFrameViewportWH;
17
18
  get _originalDoc(): Store;
18
19
  private _initPreviewDoc;
@@ -22,10 +23,21 @@ export declare class FramePreview extends FramePreview_base {
22
23
  private _setFrameDisposables;
23
24
  connectedCallback(): void;
24
25
  disconnectedCallback(): void;
26
+ /** A fluid preview follows its own width: the panel's, as it is resized. */
27
+ private _observeWidth;
28
+ willUpdate(changed: PropertyValues): void;
25
29
  render(): import("lit-html").TemplateResult<1>;
26
30
  updated(_changedProperties: PropertyValues): void;
27
31
  accessor std: BlockStdScope;
32
+ /** The width a fluid preview measured on itself; `0` until laid out. */
33
+ private accessor _containerWidth;
28
34
  accessor fillScreen: boolean;
35
+ /**
36
+ * Take the container's width and the frame's proportions (recette 1,
37
+ * P0-1.2): the box grows and shrinks with the panel, never taller than
38
+ * wide, and `surfaceWidth` / `surfaceHeight` are computed, not read.
39
+ */
40
+ accessor fluid: boolean;
29
41
  accessor frame: FrameBlockModel;
30
42
  accessor frameViewportWH: {
31
43
  width: number;