@formicoidea/labre-core 0.32.0 → 0.33.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 (227) hide show
  1. package/dist/_pkgs/affine-block-attachment/attachment-block.js +1 -1
  2. package/dist/_pkgs/affine-block-callout/callout-block.js +1 -1
  3. package/dist/_pkgs/affine-block-code/code-block-inline.js +1 -1
  4. package/dist/_pkgs/affine-block-code/code-toolbar/config.js +3 -1
  5. package/dist/_pkgs/affine-block-code/code-toolbar/index.js +1 -1
  6. package/dist/_pkgs/affine-block-database/data-source.js +1 -2
  7. package/dist/_pkgs/affine-block-database/external-data-source.js +1 -1
  8. package/dist/_pkgs/affine-block-edgeless-text/edgeless-text-block.js +1 -1
  9. package/dist/_pkgs/affine-block-edgeless-text/edgeless-toolbar/config.js +1 -1
  10. package/dist/_pkgs/affine-block-embed/embed-figma-block/embed-figma-service.js +1 -1
  11. package/dist/_pkgs/affine-block-embed/embed-iframe-block/configs/toolbar.js +2 -2
  12. package/dist/_pkgs/affine-block-embed-doc/embed-linked-doc-block/configs/toolbar.js +1 -1
  13. package/dist/_pkgs/affine-block-embed-doc/embed-linked-doc-block/utils.js +1 -1
  14. package/dist/_pkgs/affine-block-embed-doc/embed-synced-doc-block/configs/toolbar.js +1 -1
  15. package/dist/_pkgs/affine-block-embed-doc/embed-synced-doc-block/embed-synced-doc-block.js +1 -1
  16. package/dist/_pkgs/affine-block-frame/frame-manager.js +3 -1
  17. package/dist/_pkgs/affine-block-frame/frame-tool.js +1 -1
  18. package/dist/_pkgs/affine-block-image/components/page-image-block.js +1 -1
  19. package/dist/_pkgs/affine-block-image/image-edgeless-block.js +1 -1
  20. package/dist/_pkgs/affine-block-list/utils/forward-delete.js +1 -1
  21. package/dist/_pkgs/affine-block-note/commands/select-block.js +1 -1
  22. package/dist/_pkgs/affine-block-note/commands/select-blocks-between.js +1 -1
  23. package/dist/_pkgs/affine-block-note/move-block.js +1 -1
  24. package/dist/_pkgs/affine-block-paragraph/utils/forward-delete.js +2 -2
  25. package/dist/_pkgs/affine-block-paragraph/utils/merge-with-prev.js +1 -1
  26. package/dist/_pkgs/affine-block-root/edgeless/configs/toolbar/more.js +1 -1
  27. package/dist/_pkgs/affine-block-root/edgeless/edgeless-keyboard.js +1 -1
  28. package/dist/_pkgs/affine-block-root/edgeless/utils/clipboard-utils.js +1 -1
  29. package/dist/_pkgs/affine-block-surface/adapters/markdown/element-adapter/type.js +1 -1
  30. package/dist/_pkgs/affine-block-surface/adapters/plain-text/element-adapter/type.js +1 -1
  31. package/dist/_pkgs/affine-block-surface/element-model/index.d.ts +18 -3
  32. package/dist/_pkgs/affine-block-surface/element-model/index.js +12 -2
  33. package/dist/_pkgs/affine-block-surface/extensions/audit.js +23 -6
  34. package/dist/_pkgs/affine-block-surface/extensions/crud-extension.js +10 -5
  35. package/dist/_pkgs/affine-block-surface/extensions/editor-anchored-panel.js +2 -1
  36. package/dist/_pkgs/affine-block-surface/extensions/element-renderer.js +1 -1
  37. package/dist/_pkgs/affine-block-surface/extensions/export-manager/export-manager.js +1 -1
  38. package/dist/_pkgs/affine-block-surface/extensions/index.d.ts +4 -0
  39. package/dist/_pkgs/affine-block-surface/extensions/index.js +4 -0
  40. package/dist/_pkgs/affine-block-surface/extensions/interchange-import.d.ts +172 -0
  41. package/dist/_pkgs/affine-block-surface/extensions/interchange-import.js +393 -0
  42. package/dist/_pkgs/affine-block-surface/extensions/interchange.d.ts +306 -0
  43. package/dist/_pkgs/affine-block-surface/extensions/interchange.js +64 -0
  44. package/dist/_pkgs/affine-block-surface/extensions/map-quality-widget.js +61 -61
  45. package/dist/_pkgs/affine-block-surface/extensions/morph-toolbar.d.ts +248 -0
  46. package/dist/_pkgs/affine-block-surface/extensions/morph-toolbar.js +248 -0
  47. package/dist/_pkgs/affine-block-surface/extensions/reading-widget.js +78 -80
  48. package/dist/_pkgs/affine-block-surface/extensions/reading.js +2 -2
  49. package/dist/_pkgs/affine-block-surface/extensions/svg-sketch.d.ts +107 -0
  50. package/dist/_pkgs/affine-block-surface/extensions/svg-sketch.js +958 -0
  51. package/dist/_pkgs/affine-block-surface/extensions/validation.d.ts +809 -20
  52. package/dist/_pkgs/affine-block-surface/extensions/validation.js +1661 -50
  53. package/dist/_pkgs/affine-block-surface/extensions/violation-detail-widget.d.ts +50 -6
  54. package/dist/_pkgs/affine-block-surface/extensions/violation-detail-widget.js +129 -32
  55. package/dist/_pkgs/affine-block-surface/framework-background/def.d.ts +289 -0
  56. package/dist/_pkgs/affine-block-surface/framework-background/def.js +126 -1
  57. package/dist/_pkgs/affine-block-surface/framework-background/labels.d.ts +42 -2
  58. package/dist/_pkgs/affine-block-surface/framework-background/labels.js +80 -4
  59. package/dist/_pkgs/affine-block-surface/framework-background/renderer.js +172 -11
  60. package/dist/_pkgs/affine-block-surface/renderer/overlay.js +1 -1
  61. package/dist/_pkgs/affine-block-surface-ref/portal/note.js +2 -2
  62. package/dist/_pkgs/affine-block-table/commands.js +1 -1
  63. package/dist/_pkgs/affine-components/edgeless-shape-color-picker/color-picker.js +1 -1
  64. package/dist/_pkgs/affine-components/embed-card-modal/embed-card-edit-modal.js +1 -1
  65. package/dist/_pkgs/affine-components/filterable-list/styles.js +1 -1
  66. package/dist/_pkgs/affine-components/peek/peekable.js +1 -1
  67. package/dist/_pkgs/affine-components/toolbar/index.d.ts +1 -0
  68. package/dist/_pkgs/affine-components/toolbar/index.js +1 -0
  69. package/dist/_pkgs/affine-components/toolbar/menu-button.js +1 -1
  70. package/dist/_pkgs/affine-components/toolbar/picker-menu.d.ts +55 -0
  71. package/dist/_pkgs/affine-components/toolbar/picker-menu.js +47 -0
  72. package/dist/_pkgs/affine-fragment-frame-panel/body/frame-panel-body.js +2 -2
  73. package/dist/_pkgs/affine-fragment-frame-panel/header/frame-panel-header.js +2 -2
  74. package/dist/_pkgs/affine-fragment-frame-panel/header/frames-setting-menu.js +1 -1
  75. package/dist/_pkgs/affine-fragment-outline/mobile-outline-panel.js +1 -1
  76. package/dist/_pkgs/affine-gfx-brush/toolbar/components/pen/pen-tool-button.js +1 -1
  77. package/dist/_pkgs/affine-gfx-connector/connector-manager.js +7 -10
  78. package/dist/_pkgs/affine-gfx-connector/connector-tool.d.ts +19 -1
  79. package/dist/_pkgs/affine-gfx-connector/connector-tool.js +10 -2
  80. package/dist/_pkgs/affine-gfx-connector/connector-watcher.js +1 -4
  81. package/dist/_pkgs/affine-gfx-connector/direction/direction-reveal.js +2 -1
  82. package/dist/_pkgs/affine-gfx-connector/direction/invert-direction.js +1 -3
  83. package/dist/_pkgs/affine-gfx-connector/element-renderer/index.js +1 -1
  84. package/dist/_pkgs/affine-gfx-connector/element-renderer/utils.js +1 -1
  85. package/dist/_pkgs/affine-gfx-connector/toolbar/config.js +1 -1
  86. package/dist/_pkgs/affine-gfx-mindmap/adapter/markdown/index.js +1 -1
  87. package/dist/_pkgs/affine-gfx-mindmap/adapter/utils.js +1 -1
  88. package/dist/_pkgs/affine-gfx-mindmap/templates/index.js +583 -4
  89. package/dist/_pkgs/affine-gfx-mindmap/toolbar/mindmap-menu.js +23 -23
  90. package/dist/_pkgs/affine-gfx-mindmap/toolbar/mindmap-tool-button.js +5 -1
  91. package/dist/_pkgs/affine-gfx-mindmap/view/utils.js +1 -1
  92. package/dist/_pkgs/affine-gfx-note/overlay/overlay.js +1 -1
  93. package/dist/_pkgs/affine-gfx-note/toolbar/note-senior-button.js +1 -1
  94. package/dist/_pkgs/affine-gfx-shape/consts.js +1 -1
  95. package/dist/_pkgs/affine-gfx-shape/draggable/shape-draggable.js +1 -1
  96. package/dist/_pkgs/affine-gfx-shape/element-renderer/shape/polygon.js +17 -9
  97. package/dist/_pkgs/affine-gfx-shape/element-renderer/shape/utils.js +8 -3
  98. package/dist/_pkgs/affine-gfx-shape/element-view.js +19 -12
  99. package/dist/_pkgs/affine-gfx-shape/overlay/polygon-drawing-overlay.js +1 -1
  100. package/dist/_pkgs/affine-gfx-shape/overlay/polygon-vertex-editing-overlay.js +12 -7
  101. package/dist/_pkgs/affine-gfx-shape/overlay/shape-overlay.js +1 -1
  102. package/dist/_pkgs/affine-gfx-shape/polygon-tool.js +4 -2
  103. package/dist/_pkgs/affine-gfx-shape/shape-tool.js +1 -1
  104. package/dist/_pkgs/affine-gfx-shape/text/edgeless-shape-text-editor.js +1 -3
  105. package/dist/_pkgs/affine-gfx-template/builtin/other.js +66 -17
  106. package/dist/_pkgs/affine-gfx-template/toolbar/overlay-scrollbar.js +1 -1
  107. package/dist/_pkgs/affine-gfx-template/toolbar/template-panel.js +1 -1
  108. package/dist/_pkgs/affine-gfx-text/toolbar/actions.js +1 -1
  109. package/dist/_pkgs/affine-inline-link/command.js +1 -1
  110. package/dist/_pkgs/affine-inline-preset/command/format-block.js +1 -1
  111. package/dist/_pkgs/affine-inline-preset/command/format-native.js +2 -2
  112. package/dist/_pkgs/affine-inline-preset/command/format-text.js +1 -1
  113. package/dist/_pkgs/affine-inline-preset/inline-spec.js +1 -1
  114. package/dist/_pkgs/affine-inline-reference/reference-node/reference-node.js +1 -1
  115. package/dist/_pkgs/affine-model/elements/bpmn/node.d.ts +40 -7
  116. package/dist/_pkgs/affine-model/elements/bpmn/node.js +4 -2
  117. package/dist/_pkgs/affine-model/elements/bpmn/pool.d.ts +74 -17
  118. package/dist/_pkgs/affine-model/elements/bpmn/pool.js +55 -26
  119. package/dist/_pkgs/affine-model/elements/c4/board.d.ts +88 -0
  120. package/dist/_pkgs/affine-model/elements/c4/board.js +128 -0
  121. package/dist/_pkgs/affine-model/elements/c4/boundary.d.ts +63 -0
  122. package/dist/_pkgs/affine-model/elements/c4/boundary.js +134 -0
  123. package/dist/_pkgs/affine-model/elements/c4/index.d.ts +3 -0
  124. package/dist/_pkgs/affine-model/elements/c4/index.js +3 -0
  125. package/dist/_pkgs/affine-model/elements/c4/node.d.ts +97 -0
  126. package/dist/_pkgs/affine-model/elements/c4/node.js +130 -0
  127. package/dist/_pkgs/affine-model/elements/connector/connector.js +1 -1
  128. package/dist/_pkgs/affine-model/elements/context-map/context-map.d.ts +27 -0
  129. package/dist/_pkgs/affine-model/elements/context-map/context-map.js +94 -0
  130. package/dist/_pkgs/affine-model/elements/context-map/index.d.ts +1 -0
  131. package/dist/_pkgs/affine-model/elements/context-map/index.js +1 -0
  132. package/dist/_pkgs/affine-model/elements/core-domain/core-domain.d.ts +34 -17
  133. package/dist/_pkgs/affine-model/elements/core-domain/core-domain.js +28 -26
  134. package/dist/_pkgs/affine-model/elements/event-storming/event-storming.d.ts +36 -0
  135. package/dist/_pkgs/affine-model/elements/event-storming/event-storming.js +103 -0
  136. package/dist/_pkgs/affine-model/elements/event-storming/index.d.ts +1 -0
  137. package/dist/_pkgs/affine-model/elements/event-storming/index.js +1 -0
  138. package/dist/_pkgs/affine-model/elements/index.d.ts +11 -0
  139. package/dist/_pkgs/affine-model/elements/index.js +3 -0
  140. package/dist/_pkgs/affine-model/elements/shape/api/polygon.js +2 -8
  141. package/dist/_pkgs/affine-shared/adapters/html/block-adapter.js +1 -1
  142. package/dist/_pkgs/affine-shared/adapters/markdown/block-adapter.js +1 -1
  143. package/dist/_pkgs/affine-shared/adapters/markdown/delta-converter.js +1 -1
  144. package/dist/_pkgs/affine-shared/adapters/notion-html/block-adapter.js +1 -1
  145. package/dist/_pkgs/affine-shared/adapters/notion-html/delta-converter.js +1 -1
  146. package/dist/_pkgs/affine-shared/adapters/plain-text/block-adapter.js +1 -1
  147. package/dist/_pkgs/affine-shared/adapters/plain-text/delta-converter.js +1 -1
  148. package/dist/_pkgs/affine-shared/adapters/utils/color.js +5 -2
  149. package/dist/_pkgs/affine-shared/commands/model-crud/draft-selected-models.js +1 -1
  150. package/dist/_pkgs/affine-shared/commands/selection/focus-block-end.js +1 -1
  151. package/dist/_pkgs/affine-shared/commands/selection/focus-block-start.js +1 -1
  152. package/dist/_pkgs/affine-shared/consts/index.d.ts +10 -0
  153. package/dist/_pkgs/affine-shared/consts/index.js +10 -0
  154. package/dist/_pkgs/affine-shared/services/artefact-catalogue-service.d.ts +55 -0
  155. package/dist/_pkgs/affine-shared/services/artefact-catalogue-service.js +35 -0
  156. package/dist/_pkgs/affine-shared/services/audit-service.d.ts +11 -0
  157. package/dist/_pkgs/affine-shared/services/command-usage-service.d.ts +31 -0
  158. package/dist/_pkgs/affine-shared/services/command-usage-service.js +109 -0
  159. package/dist/_pkgs/affine-shared/services/comment-service/block-comment-manager.js +1 -1
  160. package/dist/_pkgs/affine-shared/services/doc-display-meta-service.js +1 -1
  161. package/dist/_pkgs/affine-shared/services/embed-iframe/embed-iframe-config.js +1 -1
  162. package/dist/_pkgs/affine-shared/services/index.d.ts +2 -0
  163. package/dist/_pkgs/affine-shared/services/index.js +2 -0
  164. package/dist/_pkgs/affine-shared/services/pivot-materiality-publisher.js +2 -1
  165. package/dist/_pkgs/affine-shared/services/telemetry-service/lifecycle.d.ts +73 -1
  166. package/dist/_pkgs/affine-shared/services/toolbar-service/registry.d.ts +44 -0
  167. package/dist/_pkgs/affine-shared/services/toolbar-service/registry.js +161 -3
  168. package/dist/_pkgs/affine-shared/services/universe-tag-defs-service.js +5 -3
  169. package/dist/_pkgs/affine-shared/test-utils/affine-template.js +1 -1
  170. package/dist/_pkgs/affine-shared/utils/edgeless.js +1 -1
  171. package/dist/_pkgs/affine-shared/utils/file/filesys.d.ts +34 -0
  172. package/dist/_pkgs/affine-shared/utils/file/filesys.js +48 -7
  173. package/dist/_pkgs/affine-shared/utils/zod-schema.js +1 -3
  174. package/dist/_pkgs/affine-widget-drag-handle/utils.js +1 -1
  175. package/dist/_pkgs/affine-widget-edgeless-auto-connect/index.js +1 -1
  176. package/dist/_pkgs/affine-widget-edgeless-dragging-area/edgeless-dragging-area-rect.js +1 -1
  177. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/artefact-catalogue-default.d.ts +14 -0
  178. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/artefact-catalogue-default.js +40 -0
  179. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/artefact-catalogue-widget.d.ts +158 -0
  180. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/artefact-catalogue-widget.js +572 -0
  181. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/catalogue-groups.d.ts +46 -0
  182. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/catalogue-groups.js +66 -0
  183. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/chord-format.d.ts +13 -0
  184. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/chord-format.js +50 -0
  185. package/dist/_pkgs/affine-widget-edgeless-toolbar/edgeless-toolbar.d.ts +6 -0
  186. package/dist/_pkgs/affine-widget-edgeless-toolbar/edgeless-toolbar.js +15 -5
  187. package/dist/_pkgs/affine-widget-edgeless-toolbar/effects.d.ts +2 -0
  188. package/dist/_pkgs/affine-widget-edgeless-toolbar/effects.js +2 -0
  189. package/dist/_pkgs/affine-widget-edgeless-toolbar/extension/index.d.ts +7 -0
  190. package/dist/_pkgs/affine-widget-edgeless-toolbar/index.d.ts +4 -0
  191. package/dist/_pkgs/affine-widget-edgeless-toolbar/index.js +4 -0
  192. package/dist/_pkgs/affine-widget-edgeless-toolbar/menu/command-menu.d.ts +19 -0
  193. package/dist/_pkgs/affine-widget-edgeless-toolbar/menu/command-menu.js +51 -10
  194. package/dist/_pkgs/affine-widget-edgeless-toolbar/view.js +9 -0
  195. package/dist/_pkgs/affine-widget-keyboard-toolbar/keyboard-tool-panel.js +1 -1
  196. package/dist/_pkgs/affine-widget-linked-doc/import-doc/import-doc.js +1 -1
  197. package/dist/_pkgs/affine-widget-linked-doc/linked-doc-popover.js +1 -1
  198. package/dist/_pkgs/affine-widget-page-dragging-area/index.js +1 -1
  199. package/dist/_pkgs/affine-widget-remote-selection/doc/doc-remote-selection.js +1 -1
  200. package/dist/_pkgs/affine-widget-toolbar/toolbar.js +6 -2
  201. package/dist/_pkgs/affine-widget-toolbar/utils.js +6 -2
  202. package/dist/_pkgs/data-view/view-presets/calendar/pc/actions.js +8 -12
  203. package/dist/_pkgs/data-view/view-presets/calendar/pc/view.js +52 -40
  204. package/dist/_pkgs/data-view/view-presets/table/mobile/group.js +3 -1
  205. package/dist/_pkgs/data-view/view-presets/table/pc/group.js +3 -1
  206. package/dist/_pkgs/std/clipboard/utils.js +4 -1
  207. package/dist/_pkgs/std/extension/command-registry.d.ts +159 -5
  208. package/dist/_pkgs/std/extension/command-registry.js +202 -4
  209. package/dist/_pkgs/std/extension/shortcut.js +2 -1
  210. package/dist/_pkgs/std/gfx/grid.js +1 -1
  211. package/dist/_pkgs/std/gfx/index.d.ts +1 -1
  212. package/dist/_pkgs/std/gfx/model/surface/element-model.d.ts +160 -0
  213. package/dist/_pkgs/std/gfx/model/surface/element-model.js +75 -1
  214. package/dist/_pkgs/std/gfx/model/surface/role.js +5 -3
  215. package/dist/_pkgs/std/gfx/model/surface/surface-model.js +2 -1
  216. package/dist/_pkgs/std/gfx/selection.js +1 -1
  217. package/dist/_pkgs/std/gfx/viewport.js +1 -1
  218. package/dist/_pkgs/std/inline/extensions/inline-manager.js +1 -1
  219. package/dist/_pkgs/std/inline/extensions/markdown-matcher.js +1 -1
  220. package/dist/_pkgs/store/model/store/crud.js +4 -1
  221. package/dist/commands.js +1 -1
  222. package/dist/extensions/command-usage.d.ts +23 -0
  223. package/dist/extensions/command-usage.js +37 -0
  224. package/dist/extensions/view.js +12 -0
  225. package/dist/frameworks.js +32 -0
  226. package/dist/translations.js +90 -2
  227. package/package.json +1 -1
@@ -28,12 +28,15 @@ export function backgroundPoint(anchor, plot) {
28
28
  export const BROKEN_BACKGROUND_COLOR = '#ff00ff';
29
29
  /** Warn once per distinct problem: a renderer runs on every frame. */
30
30
  const warned = new Set();
31
- export function warnBrokenBackgroundColor(reason) {
31
+ function warnOnce(reason) {
32
32
  if (warned.has(reason))
33
33
  return;
34
34
  warned.add(reason);
35
35
  console.warn(`[framework-background] ${reason}`);
36
36
  }
37
+ export function warnBrokenBackgroundColor(reason) {
38
+ warnOnce(reason);
39
+ }
37
40
  /**
38
41
  * Resolve `@name` against the palette; anything else is a literal colour.
39
42
  *
@@ -51,6 +54,128 @@ export function backgroundColor(color, palette) {
51
54
  warnBrokenBackgroundColor(`no palette entry for "${color}"`);
52
55
  return BROKEN_BACKGROUND_COLOR;
53
56
  }
57
+ /** Nothing to report, shared so the common case allocates no array. */
58
+ const NO_INSTANCE_ZONES = Object.freeze([]);
59
+ /**
60
+ * The plot partition ONE instance carries, as rectangles in plot ratios.
61
+ *
62
+ * The semantic accessor onto {@link BackgroundInstanceZonesDef}: everything
63
+ * that has to know where a user's own zones sit — the renderer that draws their
64
+ * dividers and their names, the audit that reports them, the rules a later
65
+ * tranche will judge inside them — reads them here, so a lane is one shape and
66
+ * not four that must agree. Named consumer: the BPMN pool's lanes (couloirs).
67
+ *
68
+ * Pure: declaration plus the instance's bag of props in, plain data out. Ratios
69
+ * and not model units, for the reason every position in this file is a ratio —
70
+ * an instance stretched to twice its height keeps the same partition.
71
+ *
72
+ * ## What a malformed partition does
73
+ *
74
+ * A partition is data the user edits, so it gets typos and half-written rows,
75
+ * and none of them may take the frame down or paint a picture that lies:
76
+ *
77
+ * - a missing, empty or non-array prop yields `[]` — a background that simply
78
+ * has no partition yet, which is what every instance looks like the moment it
79
+ * is created;
80
+ * - an entry that is not an object, or carries no string id, is dropped;
81
+ * - a size that is not a finite number, or is `0` or less, is dropped with a
82
+ * warning: a zero-height band is a band nothing can be in, and a negative one
83
+ * would eat into its neighbours. Dropped rather than clamped, for the reason
84
+ * {@link FrameworkBackgroundDef.transitionBandWidth} drops its own degenerate
85
+ * case — silently inventing a size is worse than showing one band fewer;
86
+ * - once for each distinct problem, like every other diagnostic on the paint
87
+ * path (see {@link warnBrokenBackgroundColor}).
88
+ *
89
+ * The survivors keep their declaration ORDER, and their sizes are normalised
90
+ * over the sum of the survivors — so dropping a broken row redistributes its
91
+ * space rather than leaving a hole where it was.
92
+ */
93
+ export function backgroundInstanceZones(def, model) {
94
+ const spec = def.instanceZones;
95
+ if (spec === undefined)
96
+ return NO_INSTANCE_ZONES;
97
+ const raw = model[spec.prop];
98
+ if (!Array.isArray(raw) || raw.length === 0)
99
+ return NO_INSTANCE_ZONES;
100
+ const items = [];
101
+ let total = 0;
102
+ for (const entry of raw) {
103
+ if (typeof entry !== 'object' || entry === null)
104
+ continue;
105
+ const item = entry;
106
+ if (typeof item.id !== 'string' || item.id === '')
107
+ continue;
108
+ const size = item.size;
109
+ if (typeof size !== 'number' || !Number.isFinite(size) || size <= 0) {
110
+ warnOnce(`"${def.type}" instance zone "${item.id}" declares a size of ${String(size)} — a zone with no extent is one nothing can be inside, so it is ` +
111
+ `dropped and its neighbours share the space.`);
112
+ continue;
113
+ }
114
+ items.push({
115
+ id: item.id,
116
+ ...(typeof item.name === 'string' ? { name: item.name } : {}),
117
+ size,
118
+ });
119
+ total += size;
120
+ }
121
+ if (items.length === 0 || !(total > 0))
122
+ return NO_INSTANCE_ZONES;
123
+ const zones = [];
124
+ let at = 0;
125
+ for (const item of items) {
126
+ const share = item.size / total;
127
+ zones.push({
128
+ id: `${spec.idPrefix}:${item.id}`,
129
+ ...(item.name !== undefined ? { name: item.name } : {}),
130
+ rect: spec.stack === 'y'
131
+ ? { x: 0, y: at, w: 1, h: share }
132
+ : { x: at, y: 0, w: share, h: 1 },
133
+ });
134
+ at += share;
135
+ }
136
+ return zones;
137
+ }
138
+ /**
139
+ * The label STRIP of one instance zone, in element-local model units.
140
+ *
141
+ * `null` when the declaration asks for no band, or when there is no room for
142
+ * one. THE one place that knows where a lane title sits: the renderer paints
143
+ * from it and the framework's view hit-tests a double-click against it, so the
144
+ * words a user aims at and the words they get are the same rectangle by
145
+ * construction rather than by two constants that must agree.
146
+ *
147
+ * Clamped to the plot, the way a side band clamps to an element narrower than
148
+ * its own margin ({@link BackgroundSideBandDef}) — the same degenerate case,
149
+ * and the same answer.
150
+ */
151
+ export function backgroundInstanceZoneBand(def, zone, plot) {
152
+ const spec = def.instanceZones;
153
+ const band = spec?.label?.band;
154
+ if (spec === undefined || band === undefined)
155
+ return null;
156
+ if (!(band.width > 0))
157
+ return null;
158
+ if (spec.stack === 'y') {
159
+ const width = Math.min(band.width, plot.width);
160
+ if (!(width > 0))
161
+ return null;
162
+ return {
163
+ x: plot.x0,
164
+ y: plot.y0 + zone.rect.y * plot.height,
165
+ w: width,
166
+ h: zone.rect.h * plot.height,
167
+ };
168
+ }
169
+ const height = Math.min(band.width, plot.height);
170
+ if (!(height > 0))
171
+ return null;
172
+ return {
173
+ x: plot.x0 + zone.rect.x * plot.width,
174
+ y: plot.y0,
175
+ w: zone.rect.w * plot.width,
176
+ h: height,
177
+ };
178
+ }
54
179
  /**
55
180
  * Whether the resize handles are offered for this element.
56
181
  *
@@ -19,6 +19,22 @@ export type BackgroundModelLike = Record<string, unknown>;
19
19
  export declare function backgroundLabelText(source: BackgroundLabelSource, model: BackgroundModelLike, translation?: TranslationService | null): string;
20
20
  /** Whether a `visibleProp` gate is open. No gate means always drawn. */
21
21
  export declare function backgroundVisible(visibleProp: string | undefined, model: BackgroundModelLike): boolean;
22
+ /**
23
+ * Whether a piece of the declaration belongs to the variant this INSTANCE is
24
+ * currently reading — the one gate washes, zones and texts all pass through.
25
+ *
26
+ * A variant is a second reading of the same frame (a Core Domain Chart read for
27
+ * migration rather than for investment), so it is declared once, on the piece
28
+ * that belongs to it, and selected by a single model prop. Declaring `variants`
29
+ * with no {@link FrameworkBackgroundDef.variantProp} is a broken declaration and
30
+ * paints nothing: there is no prop to be one of them. It also says so out loud,
31
+ * once — a piece that is invisible everywhere with no diagnostic is the kind of
32
+ * authoring mistake somebody spends an afternoon on.
33
+ *
34
+ * Absent means every variant, which is what everything meant before variants
35
+ * existed.
36
+ */
37
+ export declare function backgroundInVariant(def: FrameworkBackgroundDef, variants: readonly string[] | undefined, model: BackgroundModelLike): boolean;
22
38
  /** A label's clickable box in element-local coordinates (axis-aligned, padded). */
23
39
  export interface BackgroundLabelHit {
24
40
  /** The declaration id of the text. */
@@ -39,11 +55,35 @@ export interface BackgroundLabelHit {
39
55
  maxY: number;
40
56
  }
41
57
  /**
42
- * Every text of a declaration, in PAINTING ORDER: zone labels, then each axis'
43
- * title followed by its end labels.
58
+ * Every text of a declaration, in PAINTING ORDER: the side-band labels, the
59
+ * zone labels, then each axis' title followed by its end labels.
44
60
  *
45
61
  * One walk, used by both the renderer and the hit tester, so a label can never
46
62
  * be drawn in one place and clicked in another.
63
+ *
64
+ * The bands lead because a band is part of the card, which is painted first.
65
+ * Two gates are INHERITED here rather than restated by every framework: a zone's
66
+ * variants reach its label, and an axis' visibility reaches its title. Both are
67
+ * overridden by a text that names its own.
68
+ *
69
+ * ## What this walk does NOT contain
70
+ *
71
+ * The names of the zones an INSTANCE declares
72
+ * ({@link FrameworkBackgroundDef.instanceZones} — a BPMN pool's lanes). This
73
+ * walk takes a declaration and nothing else, on purpose: it is what makes the
74
+ * hit boxes a pure function of the same data the renderer paints from, and
75
+ * every consumer of it — `backgroundLabelHits` above, the renderer's text
76
+ * stage — is built on that. Instance zone names come from the model, exist in a
77
+ * number the declaration does not know, and are anchored to a band whose
78
+ * position the declaration does not know either; widening the signature to take
79
+ * a model would push that question onto every caller to serve one of them.
80
+ *
81
+ * They are therefore drawn renderer-side and are NOT hit-testable: a zone name
82
+ * cannot be renamed by double-clicking it on the canvas. That is a deliberate
83
+ * limit and not an oversight — a zone is created and destroyed through its
84
+ * framework's own tooling, so that is where it is renamed too, and a label the
85
+ * hit tester never returns can never be drawn in one place and clicked in
86
+ * another either.
47
87
  */
48
88
  export declare function backgroundTexts(def: FrameworkBackgroundDef): BackgroundTextDef[];
49
89
  /**
@@ -1,4 +1,19 @@
1
1
  import { backgroundPlot, backgroundPoint } from './def.js';
2
+ /**
3
+ * Complain once per distinct problem.
4
+ *
5
+ * Same shape and same reason as the validation engine's own `warnOnce`: these
6
+ * primitives run on the PAINT path, once per piece of the declaration per
7
+ * frame, so a bare `console.warn` about a broken declaration would fill the
8
+ * console at the refresh rate while somebody drags the frame.
9
+ */
10
+ const warned = new Set();
11
+ function warnOnce(reason) {
12
+ if (warned.has(reason))
13
+ return;
14
+ warned.add(reason);
15
+ console.warn(`[framework-background] ${reason}`);
16
+ }
2
17
  /**
3
18
  * The words a label actually says.
4
19
  *
@@ -31,22 +46,78 @@ export function backgroundLabelText(source, model, translation) {
31
46
  export function backgroundVisible(visibleProp, model) {
32
47
  return visibleProp === undefined ? true : Boolean(model[visibleProp]);
33
48
  }
49
+ /**
50
+ * Whether a piece of the declaration belongs to the variant this INSTANCE is
51
+ * currently reading — the one gate washes, zones and texts all pass through.
52
+ *
53
+ * A variant is a second reading of the same frame (a Core Domain Chart read for
54
+ * migration rather than for investment), so it is declared once, on the piece
55
+ * that belongs to it, and selected by a single model prop. Declaring `variants`
56
+ * with no {@link FrameworkBackgroundDef.variantProp} is a broken declaration and
57
+ * paints nothing: there is no prop to be one of them. It also says so out loud,
58
+ * once — a piece that is invisible everywhere with no diagnostic is the kind of
59
+ * authoring mistake somebody spends an afternoon on.
60
+ *
61
+ * Absent means every variant, which is what everything meant before variants
62
+ * existed.
63
+ */
64
+ export function backgroundInVariant(def, variants, model) {
65
+ if (variants === undefined)
66
+ return true;
67
+ if (def.variantProp === undefined) {
68
+ warnOnce(`background "${def.type}" declares variants (${variants.join(', ')}) ` +
69
+ `with no variantProp to select them — the piece is never painted.`);
70
+ return false;
71
+ }
72
+ return variants.includes(String(model[def.variantProp]));
73
+ }
34
74
  /** Rough per-character advance — only used to size generous hit boxes. */
35
75
  const approxTextWidth = (text, fontSize) => Math.max(fontSize, text.length * fontSize * 0.6);
36
76
  /** Padding so double-clicking a label is forgiving. */
37
77
  const HIT_PAD = 6;
38
78
  /**
39
- * Every text of a declaration, in PAINTING ORDER: zone labels, then each axis'
40
- * title followed by its end labels.
79
+ * Every text of a declaration, in PAINTING ORDER: the side-band labels, the
80
+ * zone labels, then each axis' title followed by its end labels.
41
81
  *
42
82
  * One walk, used by both the renderer and the hit tester, so a label can never
43
83
  * be drawn in one place and clicked in another.
84
+ *
85
+ * The bands lead because a band is part of the card, which is painted first.
86
+ * Two gates are INHERITED here rather than restated by every framework: a zone's
87
+ * variants reach its label, and an axis' visibility reaches its title. Both are
88
+ * overridden by a text that names its own.
89
+ *
90
+ * ## What this walk does NOT contain
91
+ *
92
+ * The names of the zones an INSTANCE declares
93
+ * ({@link FrameworkBackgroundDef.instanceZones} — a BPMN pool's lanes). This
94
+ * walk takes a declaration and nothing else, on purpose: it is what makes the
95
+ * hit boxes a pure function of the same data the renderer paints from, and
96
+ * every consumer of it — `backgroundLabelHits` above, the renderer's text
97
+ * stage — is built on that. Instance zone names come from the model, exist in a
98
+ * number the declaration does not know, and are anchored to a band whose
99
+ * position the declaration does not know either; widening the signature to take
100
+ * a model would push that question onto every caller to serve one of them.
101
+ *
102
+ * They are therefore drawn renderer-side and are NOT hit-testable: a zone name
103
+ * cannot be renamed by double-clicking it on the canvas. That is a deliberate
104
+ * limit and not an oversight — a zone is created and destroyed through its
105
+ * framework's own tooling, so that is where it is renamed too, and a label the
106
+ * hit tester never returns can never be drawn in one place and clicked in
107
+ * another either.
44
108
  */
45
109
  export function backgroundTexts(def) {
46
110
  const texts = [];
111
+ for (const band of def.chrome?.sideBands ?? []) {
112
+ if (band.label)
113
+ texts.push(band.label);
114
+ }
47
115
  for (const zone of def.zones ?? []) {
48
- if (zone.label)
49
- texts.push(zone.label);
116
+ if (!zone.label)
117
+ continue;
118
+ texts.push(zone.variants === undefined || zone.label.variants !== undefined
119
+ ? zone.label
120
+ : { ...zone.label, variants: zone.variants });
50
121
  }
51
122
  for (const axis of def.axes ?? []) {
52
123
  // The title shares the axis' visibility; the end labels have their own.
@@ -73,6 +144,11 @@ export function backgroundLabelHits(def, model, w, h, translation) {
73
144
  for (const text of backgroundTexts(def)) {
74
145
  if (text.prop === undefined)
75
146
  continue;
147
+ // A label the instance's variant does not paint is not there to be
148
+ // double-clicked either: an editor opening on invisible words would offer
149
+ // to rename something the user cannot see.
150
+ if (!backgroundInVariant(def, text.variants, model))
151
+ continue;
76
152
  if (!backgroundVisible(text.visibleProp, model))
77
153
  continue;
78
154
  const words = backgroundLabelText(text, model, translation);
@@ -1,6 +1,6 @@
1
1
  import { TranslationProvider } from '../../affine-shared/services/index.js';
2
- import { backgroundColor, backgroundPlot, backgroundPoint, BROKEN_BACKGROUND_COLOR, DEFAULT_BACKGROUND_SURFACE, warnBrokenBackgroundColor, } from './def.js';
3
- import { backgroundLabelText, backgroundTexts, backgroundVisible, } from './labels.js';
2
+ import { backgroundColor, backgroundInstanceZoneBand, backgroundInstanceZones, backgroundPlot, backgroundPoint, BROKEN_BACKGROUND_COLOR, DEFAULT_BACKGROUND_SURFACE, warnBrokenBackgroundColor, } from './def.js';
3
+ import { backgroundInVariant, backgroundLabelText, backgroundTexts, backgroundVisible, } from './labels.js';
4
4
  /**
5
5
  * The framework-background PRIMITIVE (PF2.1): one renderer, driven entirely by
6
6
  * a {@link FrameworkBackgroundDef}. A framework gets its background by
@@ -12,12 +12,16 @@ import { backgroundLabelText, backgroundTexts, backgroundVisible, } from './labe
12
12
  * change, because order is what makes two backgrounds look like the same
13
13
  * product rather than two drawings:
14
14
  *
15
- * 1. the card — the element rectangle;
15
+ * 1. the card — the element rectangle, and the side bands that dress it: the
16
+ * fill, then the bands over it, then the border over both, so the frame
17
+ * keeps outlining the whole element;
16
18
  * 2. the washes, over the plot;
17
- * 3. the zone tints;
19
+ * 3. the zone tints, then the dividers between the zones THIS INSTANCE
20
+ * declares;
18
21
  * 4. the graduations of every axis;
19
22
  * 5. the axis lines and their arrowheads;
20
- * 6. every text — zone names, then per axis its title and its end labels.
23
+ * 6. every text — the band labels, the zone names, then per axis its title and
24
+ * its end labels, and last the names of the instance's own zones.
21
25
  *
22
26
  * A declaration that says nothing but its size therefore paints a plain white
23
27
  * rectangle: no axis, no zone, no decoration.
@@ -66,6 +70,19 @@ function fontOf(style, fallbackFamily) {
66
70
  }
67
71
  /** The family a declaration that names none falls back to. */
68
72
  const DEFAULT_FONT_FAMILY = 'Inter, sans-serif';
73
+ /**
74
+ * Where an instance zone's name sits in its band when the declaration states no
75
+ * offset: 8 model units in from the leading edge, 18 down from the top of the
76
+ * band.
77
+ *
78
+ * The two are not the same number, and that is not an oversight. The anchor is
79
+ * a BASELINE by default ({@link BackgroundTextStyle.baseline}), so the words
80
+ * hang ABOVE it: `dy` has to clear a cap height before it is an inset at all,
81
+ * and 18 leaves a name of the usual 12–15 units sitting just inside the top of
82
+ * its band. A declaration whose style anchors `middle` wants its own.
83
+ */
84
+ const DEFAULT_INSTANCE_ZONE_LABEL_DX = 8;
85
+ const DEFAULT_INSTANCE_ZONE_LABEL_DY = 18;
69
86
  /**
70
87
  * Build the canvas renderer of one declaration. Pure: the same declaration
71
88
  * always paints the same picture for the same model and size.
@@ -76,9 +93,16 @@ export function createFrameworkBackgroundRenderer(def) {
76
93
  const surface = def.chrome?.surface ?? DEFAULT_BACKGROUND_SURFACE;
77
94
  const color = (c) => backgroundColor(c, palette);
78
95
  const texts = backgroundTexts(def);
96
+ // The DECLARATION of the instance partition — how it stacks, how it is drawn.
97
+ // What it contains is the model's business and is read on every paint.
98
+ const instanceZonesDef = def.instanceZones;
79
99
  return (model, ctx, matrix, renderer) => {
80
100
  const props = model;
81
101
  const visible = (prop) => backgroundVisible(prop, props);
102
+ // Which READING of the frame this instance is showing. Washes, zones and
103
+ // texts all name the variants they belong to, and a declaration that names
104
+ // none belongs to every one of them.
105
+ const inVariant = (variants) => backgroundInVariant(def, variants, props);
82
106
  // The host's catalogue, resolved once per paint. Absent in a bare unit
83
107
  // test (the renderer is called with three arguments) and absent in a host
84
108
  // that ships no locale pack — both fall back to the declared wording.
@@ -110,7 +134,7 @@ export function createFrameworkBackgroundRenderer(def) {
110
134
  ctx.font = fontOf(style, family);
111
135
  ctx.fillStyle = color(style.color);
112
136
  ctx.textAlign = align ?? 'center';
113
- ctx.textBaseline = 'alphabetic';
137
+ ctx.textBaseline = style.baseline ?? 'alphabetic';
114
138
  ctx.fillText(words, 0, 0);
115
139
  ctx.restore();
116
140
  return;
@@ -118,28 +142,65 @@ export function createFrameworkBackgroundRenderer(def) {
118
142
  ctx.font = fontOf(style, family);
119
143
  ctx.fillStyle = color(style.color);
120
144
  ctx.textAlign = align ?? 'left';
121
- ctx.textBaseline = 'alphabetic';
145
+ ctx.textBaseline = style.baseline ?? 'alphabetic';
122
146
  ctx.fillText(words, ax, ay);
123
147
  };
124
- // ── 1. The card ─────────────────────────────────────────────────────
148
+ // ── 1. The card, and the bands that dress it ────────────────────────
125
149
  const border = surface.border;
126
150
  const inset = border ? border.width / 2 : 0;
127
- roundRectPath(ctx, inset, inset, w - inset * 2, h - inset * 2, border?.radius ?? 0);
151
+ const cardPath = () => roundRectPath(ctx, inset, inset, w - inset * 2, h - inset * 2, border?.radius ?? 0);
152
+ cardPath();
128
153
  if (surface.fill) {
129
154
  ctx.fillStyle = color(surface.fill);
130
155
  ctx.fill();
131
156
  }
157
+ // The side bands sit BETWEEN the fill and the border: a band is part of the
158
+ // card, and one painted over the frame would erase the edge it runs along,
159
+ // which reads as a broken card rather than as a band. Drawing a divider
160
+ // resets the current path, hence the second trace before the stroke — a
161
+ // declaration with no band never reaches it, so its picture is unchanged
162
+ // down to the operation.
163
+ const bands = def.chrome?.sideBands;
164
+ if (bands?.length) {
165
+ // The band IS the margin strip, clamped to an element narrower than its
166
+ // own margin — the one case where the two can disagree.
167
+ const bandWidth = Math.min(x0, w);
168
+ for (const band of bands) {
169
+ if (bandWidth <= 0)
170
+ continue;
171
+ if (band.fill) {
172
+ ctx.fillStyle = color(band.fill);
173
+ ctx.fillRect(0, 0, bandWidth, h);
174
+ }
175
+ const divider = band.divider;
176
+ if (divider) {
177
+ ctx.strokeStyle = color(divider.color);
178
+ ctx.lineWidth = divider.width;
179
+ if (divider.dash?.length)
180
+ ctx.setLineDash([...divider.dash]);
181
+ // Full height: the strip a margin gives up runs the whole side.
182
+ line(bandWidth, 0, bandWidth, h);
183
+ if (divider.dash?.length)
184
+ ctx.setLineDash([]);
185
+ }
186
+ }
187
+ if (border)
188
+ cardPath();
189
+ }
132
190
  if (border) {
133
191
  ctx.strokeStyle = color(border.color);
134
192
  ctx.lineWidth = border.width;
193
+ if (border.dash?.length)
194
+ ctx.setLineDash([...border.dash]);
135
195
  ctx.stroke();
196
+ if (border.dash?.length)
197
+ ctx.setLineDash([]);
136
198
  }
137
199
  // ── 2. Washes over the plot ─────────────────────────────────────────
138
200
  const washes = def.chrome?.washes;
139
201
  if (washes?.length) {
140
- const variant = def.variantProp === undefined ? undefined : props[def.variantProp];
141
202
  for (const wash of washes) {
142
- if (wash.variants && !wash.variants.includes(String(variant)))
203
+ if (!inVariant(wash.variants))
143
204
  continue;
144
205
  if (!visible(wash.visibleProp))
145
206
  continue;
@@ -156,11 +217,50 @@ export function createFrameworkBackgroundRenderer(def) {
156
217
  for (const zone of def.zones ?? []) {
157
218
  if (!zone.fill)
158
219
  continue;
220
+ if (!inVariant(zone.variants))
221
+ continue;
159
222
  if (!visible(zone.fillVisibleProp))
160
223
  continue;
161
224
  ctx.fillStyle = color(zone.fill);
162
225
  ctx.fillRect(x0 + zone.rect.x * pw, y0 + zone.rect.y * ph, zone.rect.w * pw, zone.rect.h * ph);
163
226
  }
227
+ // The partition THIS element carries, resolved once per paint: alone on
228
+ // this pipeline it is a function of the model rather than of the
229
+ // declaration. A framework that declares none never reads the model and
230
+ // never allocates.
231
+ const instanceZones = instanceZonesDef
232
+ ? backgroundInstanceZones(def, props)
233
+ : [];
234
+ // Dividers between adjacent instance zones: N zones, N−1 lines, on the
235
+ // INTERNAL boundaries only — the outer edges belong to the plot, and a line
236
+ // there would double the frame that is already drawn round it.
237
+ //
238
+ // Painted here, at the end of stage 3, rather than with the axis lines: a
239
+ // divider is part of what the zones ARE, so it belongs with the zones, and
240
+ // it must lie UNDER the graduations and the axes, which describe the frame
241
+ // of reference the user cannot move. After the tints, for the ordinary
242
+ // reason a fill goes under a line.
243
+ const zoneDivider = instanceZonesDef?.divider;
244
+ if (zoneDivider && instanceZones.length > 1) {
245
+ ctx.strokeStyle = color(zoneDivider.color);
246
+ ctx.lineWidth = zoneDivider.width;
247
+ if (zoneDivider.dash?.length)
248
+ ctx.setLineDash([...zoneDivider.dash]);
249
+ // Every zone but the first opens on a boundary with the one before it.
250
+ for (let i = 1; i < instanceZones.length; i++) {
251
+ const { x, y } = instanceZones[i].rect;
252
+ if (instanceZonesDef?.stack === 'y') {
253
+ const ty = y0 + y * ph;
254
+ line(x0, ty, x1, ty);
255
+ }
256
+ else {
257
+ const tx = x0 + x * pw;
258
+ line(tx, y0, tx, y1);
259
+ }
260
+ }
261
+ if (zoneDivider.dash?.length)
262
+ ctx.setLineDash([]);
263
+ }
164
264
  // ── 4. Graduations ──────────────────────────────────────────────────
165
265
  for (const axis of def.axes ?? []) {
166
266
  const graduations = axis.ticks;
@@ -191,11 +291,72 @@ export function createFrameworkBackgroundRenderer(def) {
191
291
  }
192
292
  // ── 6. Every text, in declaration order ─────────────────────────────
193
293
  for (const text of texts) {
294
+ if (!inVariant(text.variants))
295
+ continue;
194
296
  if (!visible(text.visibleProp))
195
297
  continue;
196
298
  const [tx, ty] = backgroundPoint(text.anchor, plot);
197
299
  drawText(backgroundLabelText(text, props, translation), tx, ty, text.style, text.align, text.vertical === true);
198
300
  }
301
+ // The instance's own zone names, after the declared texts — the same order
302
+ // the audit reports them in, and the same reason: what the framework says
303
+ // comes first, what this element adds comes after.
304
+ //
305
+ // Deliberately NOT routed through `backgroundTexts` (see `labels.ts`): that
306
+ // walk is a function of the DECLARATION alone, and these names are a
307
+ // function of the MODEL. A zone name is therefore not in the declaration's
308
+ // hit-test walk, and the two cannot disagree. Under the BAND placement the
309
+ // framework's own view hit-tests `backgroundInstanceZoneBand` instead —
310
+ // the very rectangle painted below — so the words a user aims at and the
311
+ // words they get are one shape rather than two constants that must agree.
312
+ const zoneLabel = instanceZonesDef?.label;
313
+ if (zoneLabel) {
314
+ const labelBand = zoneLabel.band;
315
+ const dx = zoneLabel.dx ?? DEFAULT_INSTANCE_ZONE_LABEL_DX;
316
+ const dy = zoneLabel.dy ?? DEFAULT_INSTANCE_ZONE_LABEL_DY;
317
+ const stackY = instanceZonesDef?.stack === 'y';
318
+ for (const zone of instanceZones) {
319
+ // The strip is drawn for EVERY zone, named or not: it is the lane's
320
+ // title band, and a lane whose name has been cleared still has one —
321
+ // an empty band that reads as a lane waiting to be named, rather than
322
+ // a lane that silently loses its structure. The NAME is what is
323
+ // conditional, exactly as under the corner placement.
324
+ const strip = labelBand
325
+ ? backgroundInstanceZoneBand(def, zone, plot)
326
+ : null;
327
+ if (strip && labelBand?.divider) {
328
+ const divider = labelBand.divider;
329
+ ctx.strokeStyle = color(divider.color);
330
+ ctx.lineWidth = divider.width;
331
+ if (divider.dash?.length)
332
+ ctx.setLineDash([...divider.dash]);
333
+ // The far edge of the strip, along the zone: the near edge is the
334
+ // plot boundary, already drawn by the frame or by the side band.
335
+ if (stackY) {
336
+ line(strip.x + strip.w, strip.y, strip.x + strip.w, strip.y + strip.h);
337
+ }
338
+ else {
339
+ line(strip.x, strip.y + strip.h, strip.x + strip.w, strip.y + strip.h);
340
+ }
341
+ if (divider.dash?.length)
342
+ ctx.setLineDash([]);
343
+ }
344
+ // An unnamed zone is a band and nothing else; it is not an empty label.
345
+ if (zone.name === undefined || zone.name === '')
346
+ continue;
347
+ if (strip) {
348
+ // Centred ACROSS the strip and ALONG it, the way the participant name
349
+ // is centred in its own band one level up. `middle` regardless of
350
+ // what the style says: the room the text is given is the width of the
351
+ // strip, and a baseline anchor there would push the words against the
352
+ // divider.
353
+ const style = { ...zoneLabel.style, baseline: 'middle' };
354
+ drawText(zone.name, strip.x + strip.w / 2, strip.y + strip.h / 2, style, 'center', stackY);
355
+ continue;
356
+ }
357
+ drawText(zone.name, x0 + zone.rect.x * pw + dx, y0 + zone.rect.y * ph + dy, zoneLabel.style, 'left', false);
358
+ }
359
+ }
199
360
  };
200
361
  }
201
362
  /**
@@ -1,6 +1,6 @@
1
1
  import { createIdentifier } from '../../global/di/index.js';
2
2
  import { BlockSuiteError, ErrorCode } from '../../global/exceptions/index.js';
3
- import { GfxControllerIdentifier, } from '../../std/gfx/index.js';
3
+ import { GfxControllerIdentifier } from '../../std/gfx/index.js';
4
4
  import { Extension } from '../../store/index.js';
5
5
  /**
6
6
  * An overlay is a layer covered on top of elements,
@@ -33,12 +33,12 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
33
33
  return useValue ? value : void 0;
34
34
  };
35
35
  import { ViewExtensionManagerIdentifier } from '../../affine-ext-loader/index.js';
36
- import { DefaultTheme, NoteDisplayMode, NoteShadow, } from '../../affine-model/index.js';
36
+ import { DefaultTheme, NoteDisplayMode, NoteShadow } from '../../affine-model/index.js';
37
37
  import { EDGELESS_BLOCK_CHILD_BORDER_WIDTH, EDGELESS_BLOCK_CHILD_PADDING, } from '../../affine-shared/consts/index.js';
38
38
  import { ThemeProvider } from '../../affine-shared/services/index.js';
39
39
  import { deserializeXYWH } from '../../global/gfx/index.js';
40
40
  import { WithDisposable } from '../../global/lit/index.js';
41
- import { BlockStdScope, ShadowlessElement, } from '../../std/index.js';
41
+ import { BlockStdScope, ShadowlessElement } from '../../std/index.js';
42
42
  import { RANGE_QUERY_EXCLUDE_ATTR } from '../../std/inline/index.js';
43
43
  import {} from '../../store/index.js';
44
44
  import { css, nothing } from 'lit';
@@ -1,4 +1,4 @@
1
- import { TableModelFlavour, } from '../affine-model/index.js';
1
+ import { TableModelFlavour } from '../affine-model/index.js';
2
2
  import {} from '../store/index.js';
3
3
  import { TableDataManager } from './table-data-manager.js';
4
4
  export const insertTableBlockCommand = (ctx, next) => {
@@ -34,7 +34,7 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
34
34
  };
35
35
  import { DefaultTheme, resolveColor, } from '../../affine-model/index.js';
36
36
  import { unsafeCSSVarV2 } from '../../affine-shared/theme/index.js';
37
- import { stopPropagation, } from '../../affine-shared/utils/index.js';
37
+ import { stopPropagation } from '../../affine-shared/utils/index.js';
38
38
  import { SignalWatcher, WithDisposable } from '../../global/lit/index.js';
39
39
  import { batch, signal } from '@preact/signals-core';
40
40
  import { css, html, LitElement } from 'lit';
@@ -36,7 +36,7 @@ import { EmbedLinkedDocModel, EmbedSyncedDocModel, isInternalEmbedModel, } from
36
36
  import { TelemetryProvider, } from '../../affine-shared/services/index.js';
37
37
  import { fontSMStyle, fontXSStyle } from '../../affine-shared/styles/index.js';
38
38
  import { unsafeCSSVarV2 } from '../../affine-shared/theme/index.js';
39
- import { listenClickAway, stopPropagation, } from '../../affine-shared/utils/index.js';
39
+ import { listenClickAway, stopPropagation } from '../../affine-shared/utils/index.js';
40
40
  import { SignalWatcher, WithDisposable } from '../../global/lit/index.js';
41
41
  import { nextTick } from '../../global/utils/index.js';
42
42
  import { EditorLifeCycleExtension, } from '../../std/index.js';
@@ -1,4 +1,4 @@
1
- import { panelBaseStyle, scrollbarStyle, } from '../../affine-shared/styles/index.js';
1
+ import { panelBaseStyle, scrollbarStyle } from '../../affine-shared/styles/index.js';
2
2
  import { css } from 'lit';
3
3
  export const filterableListStyles = css `
4
4
  ${panelBaseStyle(':host')}
@@ -1,7 +1,7 @@
1
1
  import { NoteBlockModel } from '../../affine-model/index.js';
2
2
  import { DocModeProvider } from '../../affine-shared/services/index.js';
3
3
  import { isInsideEdgelessEditor, matchModels, } from '../../affine-shared/utils/index.js';
4
- import { GfxBlockElementModel, GfxControllerIdentifier, } from '../../std/gfx/index.js';
4
+ import { GfxBlockElementModel, GfxControllerIdentifier } from '../../std/gfx/index.js';
5
5
  import { PeekableController } from './controller.js';
6
6
  const symbol = Symbol('peekable');
7
7
  export const isPeekable = (e) => {