@formicoidea/labre-core 0.41.0 → 0.42.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 (252) hide show
  1. package/LICENSE +384 -0
  2. package/dist/_pkgs/affine-block-bookmark/bookmark-block.js +2 -2
  3. package/dist/_pkgs/affine-block-edgeless-text/edgeless-toolbar/config.js +7 -1
  4. package/dist/_pkgs/affine-block-embed/embed-figma-block/embed-figma-block.js +2 -1
  5. package/dist/_pkgs/affine-block-embed/embed-github-block/embed-github-block.js +2 -1
  6. package/dist/_pkgs/affine-block-embed/embed-iframe-block/consts.d.ts +2 -0
  7. package/dist/_pkgs/affine-block-embed/embed-iframe-block/consts.js +5 -0
  8. package/dist/_pkgs/affine-block-embed/embed-iframe-block/embed-iframe-block.d.ts +1 -0
  9. package/dist/_pkgs/affine-block-embed/embed-iframe-block/embed-iframe-block.js +30 -8
  10. package/dist/_pkgs/affine-block-embed/embed-iframe-block/utils.d.ts +8 -0
  11. package/dist/_pkgs/affine-block-embed/embed-iframe-block/utils.js +19 -0
  12. package/dist/_pkgs/affine-block-embed/embed-loom-block/embed-loom-block.js +2 -1
  13. package/dist/_pkgs/affine-block-embed/embed-youtube-block/embed-youtube-block.js +2 -1
  14. package/dist/_pkgs/affine-block-frame/frame-manager.js +1 -1
  15. package/dist/_pkgs/affine-block-frame/frame-tool.js +1 -1
  16. package/dist/_pkgs/affine-block-frame/frame-toolbar.js +6 -1
  17. package/dist/_pkgs/affine-block-list/list-keymap.js +7 -0
  18. package/dist/_pkgs/affine-block-note/note-keymap.js +7 -1
  19. package/dist/_pkgs/affine-block-paragraph/paragraph-keymap.js +7 -1
  20. package/dist/_pkgs/affine-block-root/commands/pivot-commands.js +1 -8
  21. package/dist/_pkgs/affine-block-root/commands/tag-commands.js +1 -8
  22. package/dist/_pkgs/affine-block-root/edgeless/edgeless-keyboard.d.ts +9 -0
  23. package/dist/_pkgs/affine-block-root/edgeless/edgeless-keyboard.js +51 -0
  24. package/dist/_pkgs/affine-block-root/edgeless/edgeless-root-block.d.ts +22 -0
  25. package/dist/_pkgs/affine-block-root/edgeless/edgeless-root-block.js +46 -0
  26. package/dist/_pkgs/affine-block-root/edgeless/utils/pinch-zoom.d.ts +21 -0
  27. package/dist/_pkgs/affine-block-root/edgeless/utils/pinch-zoom.js +24 -0
  28. package/dist/_pkgs/affine-block-root/edgeless/utils/query.js +8 -0
  29. package/dist/_pkgs/affine-block-root/keyboard/keymap.js +1 -16
  30. package/dist/_pkgs/affine-block-surface/element-model/index.d.ts +21 -3
  31. package/dist/_pkgs/affine-block-surface/element-model/index.js +14 -2
  32. package/dist/_pkgs/affine-block-surface/extensions/export-svg/command.d.ts +23 -0
  33. package/dist/_pkgs/affine-block-surface/extensions/export-svg/command.js +89 -0
  34. package/dist/_pkgs/affine-block-surface/extensions/export-svg/index.d.ts +7 -0
  35. package/dist/_pkgs/affine-block-surface/extensions/export-svg/index.js +5 -0
  36. package/dist/_pkgs/affine-block-surface/extensions/export-svg/render.d.ts +41 -0
  37. package/dist/_pkgs/affine-block-surface/extensions/export-svg/render.js +70 -0
  38. package/dist/_pkgs/affine-block-surface/extensions/export-svg/svg-context.d.ts +49 -0
  39. package/dist/_pkgs/affine-block-surface/extensions/export-svg/svg-context.js +257 -0
  40. package/dist/_pkgs/affine-block-surface/extensions/export-svg/tagged-path.d.ts +16 -0
  41. package/dist/_pkgs/affine-block-surface/extensions/export-svg/tagged-path.js +24 -0
  42. package/dist/_pkgs/affine-block-surface/extensions/export-svg/toolbar.d.ts +24 -0
  43. package/dist/_pkgs/affine-block-surface/extensions/export-svg/toolbar.js +66 -0
  44. package/dist/_pkgs/affine-block-surface/extensions/index.d.ts +4 -0
  45. package/dist/_pkgs/affine-block-surface/extensions/index.js +4 -0
  46. package/dist/_pkgs/affine-block-surface/extensions/interchange-import.d.ts +66 -4
  47. package/dist/_pkgs/affine-block-surface/extensions/interchange-import.js +241 -11
  48. package/dist/_pkgs/affine-block-surface/extensions/interchange.d.ts +18 -0
  49. package/dist/_pkgs/affine-block-surface/extensions/legend-toolbar.d.ts +81 -0
  50. package/dist/_pkgs/affine-block-surface/extensions/legend-toolbar.js +81 -0
  51. package/dist/_pkgs/affine-block-surface/extensions/legend.d.ts +136 -0
  52. package/dist/_pkgs/affine-block-surface/extensions/legend.js +439 -0
  53. package/dist/_pkgs/affine-block-surface/extensions/reading-widget.d.ts +17 -3
  54. package/dist/_pkgs/affine-block-surface/extensions/reading-widget.js +35 -13
  55. package/dist/_pkgs/affine-block-surface/extensions/reading.d.ts +61 -1
  56. package/dist/_pkgs/affine-block-surface/extensions/reading.js +85 -39
  57. package/dist/_pkgs/affine-block-surface/extensions/record-action.d.ts +66 -0
  58. package/dist/_pkgs/affine-block-surface/extensions/record-action.js +145 -0
  59. package/dist/_pkgs/affine-block-surface/extensions/validation.d.ts +253 -28
  60. package/dist/_pkgs/affine-block-surface/extensions/validation.js +489 -41
  61. package/dist/_pkgs/affine-block-surface/framework-background/background-view.d.ts +115 -0
  62. package/dist/_pkgs/affine-block-surface/framework-background/background-view.js +185 -0
  63. package/dist/_pkgs/affine-block-surface/framework-background/index.d.ts +1 -0
  64. package/dist/_pkgs/affine-block-surface/framework-background/index.js +1 -0
  65. package/dist/_pkgs/affine-block-surface/framework-background/labels.d.ts +16 -1
  66. package/dist/_pkgs/affine-block-surface/framework-background/labels.js +31 -21
  67. package/dist/_pkgs/affine-block-surface/framework-background/renderer.js +29 -5
  68. package/dist/_pkgs/affine-block-surface/framework-background/stacking.d.ts +6 -4
  69. package/dist/_pkgs/affine-block-surface/framework-background/stacking.js +56 -8
  70. package/dist/_pkgs/affine-block-surface/renderer/canvas-renderer.d.ts +12 -0
  71. package/dist/_pkgs/affine-block-surface/renderer/canvas-renderer.js +15 -0
  72. package/dist/_pkgs/affine-block-surface/view.js +8 -1
  73. package/dist/_pkgs/affine-block-surface-ref/configs/slash-menu.js +1 -1
  74. package/dist/_pkgs/affine-components/color-picker/button.d.ts +56 -1
  75. package/dist/_pkgs/affine-components/color-picker/button.js +168 -23
  76. package/dist/_pkgs/affine-components/color-picker/framework-palette.d.ts +106 -0
  77. package/dist/_pkgs/affine-components/color-picker/framework-palette.js +177 -0
  78. package/dist/_pkgs/affine-components/color-picker/index.d.ts +2 -0
  79. package/dist/_pkgs/affine-components/color-picker/index.js +2 -0
  80. package/dist/_pkgs/affine-components/color-picker/palette-carousel.d.ts +85 -0
  81. package/dist/_pkgs/affine-components/color-picker/palette-carousel.js +440 -0
  82. package/dist/_pkgs/affine-components/edgeless-shape-color-picker/color-picker.d.ts +31 -1
  83. package/dist/_pkgs/affine-components/edgeless-shape-color-picker/color-picker.js +189 -63
  84. package/dist/_pkgs/affine-components/resource/resource.js +29 -16
  85. package/dist/_pkgs/affine-components/translations.d.ts +8 -0
  86. package/dist/_pkgs/affine-components/translations.js +17 -0
  87. package/dist/_pkgs/affine-foundation/view.js +2 -1
  88. package/dist/_pkgs/affine-gfx-brush/element-renderer.js +2 -2
  89. package/dist/_pkgs/affine-gfx-brush/toolbar/configs/brush.js +6 -1
  90. package/dist/_pkgs/affine-gfx-brush/toolbar/configs/highlighter.js +6 -1
  91. package/dist/_pkgs/affine-gfx-connector/connector-manager.d.ts +9 -1
  92. package/dist/_pkgs/affine-gfx-connector/connector-manager.js +61 -0
  93. package/dist/_pkgs/affine-gfx-connector/element-renderer/connector-dom/index.d.ts +7 -1
  94. package/dist/_pkgs/affine-gfx-connector/element-renderer/connector-dom/index.js +87 -17
  95. package/dist/_pkgs/affine-gfx-connector/element-renderer/index.js +78 -17
  96. package/dist/_pkgs/affine-gfx-connector/element-renderer/utils.d.ts +24 -2
  97. package/dist/_pkgs/affine-gfx-connector/element-renderer/utils.js +31 -8
  98. package/dist/_pkgs/affine-gfx-connector/text/edgeless-connector-label-editor.d.ts +124 -3
  99. package/dist/_pkgs/affine-gfx-connector/text/edgeless-connector-label-editor.js +216 -54
  100. package/dist/_pkgs/affine-gfx-connector/text/text.d.ts +13 -4
  101. package/dist/_pkgs/affine-gfx-connector/text/text.js +13 -44
  102. package/dist/_pkgs/affine-gfx-connector/toolbar/config.d.ts +56 -0
  103. package/dist/_pkgs/affine-gfx-connector/toolbar/config.js +72 -4
  104. package/dist/_pkgs/affine-gfx-connector/toolbar/hollow-endpoint-icons.d.ts +8 -0
  105. package/dist/_pkgs/affine-gfx-connector/toolbar/hollow-endpoint-icons.js +118 -0
  106. package/dist/_pkgs/affine-gfx-connector/view/view.d.ts +37 -1
  107. package/dist/_pkgs/affine-gfx-connector/view/view.js +97 -8
  108. package/dist/_pkgs/affine-gfx-group/command/group-api.js +1 -1
  109. package/dist/_pkgs/affine-gfx-group/store.js +0 -2
  110. package/dist/_pkgs/affine-gfx-group/translations.d.ts +9 -10
  111. package/dist/_pkgs/affine-gfx-group/translations.js +9 -13
  112. package/dist/_pkgs/affine-gfx-mindmap/templates/index.js +1 -1
  113. package/dist/_pkgs/affine-gfx-mindmap/toolbar/basket-elements.js +1 -1
  114. package/dist/_pkgs/affine-gfx-mindmap/toolbar/utils/import-mindmap.js +2 -2
  115. package/dist/_pkgs/affine-gfx-mindmap/translations.d.ts +1 -1
  116. package/dist/_pkgs/affine-gfx-mindmap/translations.js +1 -1
  117. package/dist/_pkgs/affine-gfx-shape/element-renderer/highlighter.js +2 -2
  118. package/dist/_pkgs/affine-gfx-shape/overlay/polygon-drawing-overlay.d.ts +6 -0
  119. package/dist/_pkgs/affine-gfx-shape/overlay/polygon-drawing-overlay.js +30 -1
  120. package/dist/_pkgs/affine-gfx-shape/polygon-tool.d.ts +20 -1
  121. package/dist/_pkgs/affine-gfx-shape/polygon-tool.js +9 -1
  122. package/dist/_pkgs/affine-gfx-shape/toolbar/config.js +6 -1
  123. package/dist/_pkgs/affine-gfx-shape/toolbar/palette-color-action.js +11 -1
  124. package/dist/_pkgs/affine-gfx-template/builtin/other.js +1 -1
  125. package/dist/_pkgs/affine-gfx-template/snapshot-from-action.js +32 -119
  126. package/dist/_pkgs/affine-gfx-template/toolbar/template-type.d.ts +1 -1
  127. package/dist/_pkgs/affine-gfx-text/dblclick-add-edgeless-text.d.ts +13 -1
  128. package/dist/_pkgs/affine-gfx-text/dblclick-add-edgeless-text.js +19 -4
  129. package/dist/_pkgs/affine-gfx-text/edgeless-text-editor.d.ts +41 -0
  130. package/dist/_pkgs/affine-gfx-text/edgeless-text-editor.js +57 -2
  131. package/dist/_pkgs/affine-gfx-text/toolbar/actions.d.ts +8 -1
  132. package/dist/_pkgs/affine-gfx-text/toolbar/actions.js +12 -2
  133. package/dist/_pkgs/affine-gfx-text/translations.d.ts +1 -0
  134. package/dist/_pkgs/affine-gfx-text/translations.js +2 -1
  135. package/dist/_pkgs/affine-inline-preset/markdown.js +5 -1
  136. package/dist/_pkgs/affine-model/consts/connector.d.ts +28 -2
  137. package/dist/_pkgs/affine-model/consts/connector.js +26 -0
  138. package/dist/_pkgs/affine-model/elements/bpmn/pool.js +1 -1
  139. package/dist/_pkgs/affine-model/elements/brush/brush.js +1 -1
  140. package/dist/_pkgs/affine-model/elements/c4/board.js +1 -1
  141. package/dist/_pkgs/affine-model/elements/c4/boundary.js +1 -1
  142. package/dist/_pkgs/affine-model/elements/connector/connector.d.ts +135 -0
  143. package/dist/_pkgs/affine-model/elements/connector/connector.js +246 -5
  144. package/dist/_pkgs/affine-model/elements/connector/end-label.d.ts +83 -0
  145. package/dist/_pkgs/affine-model/elements/connector/end-label.js +119 -0
  146. package/dist/_pkgs/affine-model/elements/connector/index.d.ts +1 -0
  147. package/dist/_pkgs/affine-model/elements/connector/index.js +1 -0
  148. package/dist/_pkgs/affine-model/elements/context-map/context-map.js +1 -1
  149. package/dist/_pkgs/affine-model/elements/core-domain/core-domain.d.ts +28 -0
  150. package/dist/_pkgs/affine-model/elements/core-domain/core-domain.js +129 -2
  151. package/dist/_pkgs/affine-model/elements/cynefin/cynefin.d.ts +8 -0
  152. package/dist/_pkgs/affine-model/elements/cynefin/cynefin.js +45 -2
  153. package/dist/_pkgs/affine-model/elements/edgy/board.js +1 -1
  154. package/dist/_pkgs/affine-model/elements/edgy/facets.js +1 -1
  155. package/dist/_pkgs/affine-model/elements/estuarine/estuarine.d.ts +6 -0
  156. package/dist/_pkgs/affine-model/elements/estuarine/estuarine.js +36 -2
  157. package/dist/_pkgs/affine-model/elements/event-storming/event-storming.d.ts +18 -7
  158. package/dist/_pkgs/affine-model/elements/event-storming/event-storming.js +23 -8
  159. package/dist/_pkgs/affine-model/elements/framework-background/background.d.ts +16 -0
  160. package/dist/_pkgs/affine-model/elements/framework-background/background.js +18 -0
  161. package/dist/_pkgs/affine-model/elements/highlighter/highlighter.js +1 -1
  162. package/dist/_pkgs/affine-model/elements/index.d.ts +8 -0
  163. package/dist/_pkgs/affine-model/elements/index.js +1 -0
  164. package/dist/_pkgs/affine-model/elements/shape/shape.js +1 -1
  165. package/dist/_pkgs/affine-model/elements/text/text.js +1 -1
  166. package/dist/_pkgs/affine-model/elements/uml/band.d.ts +39 -0
  167. package/dist/_pkgs/affine-model/elements/uml/band.js +31 -0
  168. package/dist/_pkgs/affine-model/elements/uml/diagram.d.ts +158 -0
  169. package/dist/_pkgs/affine-model/elements/uml/diagram.js +229 -0
  170. package/dist/_pkgs/affine-model/elements/uml/fragment.d.ts +161 -0
  171. package/dist/_pkgs/affine-model/elements/uml/fragment.js +205 -0
  172. package/dist/_pkgs/affine-model/elements/uml/index.d.ts +8 -0
  173. package/dist/_pkgs/affine-model/elements/uml/index.js +8 -0
  174. package/dist/_pkgs/affine-model/elements/uml/lifeline.d.ts +77 -0
  175. package/dist/_pkgs/affine-model/elements/uml/lifeline.js +89 -0
  176. package/dist/_pkgs/affine-model/elements/uml/node.d.ts +142 -0
  177. package/dist/_pkgs/affine-model/elements/uml/node.js +190 -0
  178. package/dist/_pkgs/affine-model/elements/uml/partition.d.ts +106 -0
  179. package/dist/_pkgs/affine-model/elements/uml/partition.js +172 -0
  180. package/dist/_pkgs/affine-model/elements/uml/region.d.ts +75 -0
  181. package/dist/_pkgs/affine-model/elements/uml/region.js +150 -0
  182. package/dist/_pkgs/affine-model/elements/uml/subject.d.ts +37 -0
  183. package/dist/_pkgs/affine-model/elements/uml/subject.js +108 -0
  184. package/dist/_pkgs/affine-model/elements/wardley/wardley.js +1 -1
  185. package/dist/_pkgs/affine-shared/services/embed-iframe/embed-iframe-config.d.ts +1 -0
  186. package/dist/_pkgs/affine-shared/services/font-loader/config.d.ts +7 -0
  187. package/dist/_pkgs/affine-shared/services/font-loader/config.js +43 -0
  188. package/dist/_pkgs/affine-shared/services/pivot-materiality-publisher.js +1 -9
  189. package/dist/_pkgs/affine-shared/services/telemetry-service/document-damage-watcher.d.ts +53 -0
  190. package/dist/_pkgs/affine-shared/services/telemetry-service/document-damage-watcher.js +95 -0
  191. package/dist/_pkgs/affine-shared/services/telemetry-service/index.d.ts +1 -0
  192. package/dist/_pkgs/affine-shared/services/telemetry-service/index.js +1 -0
  193. package/dist/_pkgs/affine-shared/services/telemetry-service/lifecycle.d.ts +26 -1
  194. package/dist/_pkgs/affine-shared/services/telemetry-service/telemetry-service.d.ts +2 -2
  195. package/dist/_pkgs/affine-shared/services/toolbar-service/command-action.d.ts +34 -0
  196. package/dist/_pkgs/affine-shared/services/toolbar-service/command-action.js +63 -0
  197. package/dist/_pkgs/affine-shared/services/toolbar-service/index.d.ts +1 -0
  198. package/dist/_pkgs/affine-shared/services/toolbar-service/index.js +1 -0
  199. package/dist/_pkgs/affine-shared/services/translation-service/chrome.d.ts +77 -7
  200. package/dist/_pkgs/affine-shared/services/translation-service/chrome.js +97 -7
  201. package/dist/_pkgs/affine-shared/styles/index.d.ts +1 -0
  202. package/dist/_pkgs/affine-shared/styles/index.js +1 -0
  203. package/dist/_pkgs/affine-shared/styles/motion.d.ts +14 -0
  204. package/dist/_pkgs/affine-shared/styles/motion.js +38 -0
  205. package/dist/_pkgs/affine-shared/utils/event.d.ts +10 -0
  206. package/dist/_pkgs/affine-shared/utils/event.js +20 -0
  207. package/dist/_pkgs/affine-shared/utils/file/filesys.d.ts +16 -0
  208. package/dist/_pkgs/affine-shared/utils/file/filesys.js +25 -0
  209. package/dist/_pkgs/affine-shared/utils/index.d.ts +1 -0
  210. package/dist/_pkgs/affine-shared/utils/index.js +1 -0
  211. package/dist/_pkgs/affine-shared/utils/link-preview-refresh.d.ts +12 -0
  212. package/dist/_pkgs/affine-shared/utils/link-preview-refresh.js +13 -0
  213. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/artefact-catalogue-widget.d.ts +12 -4
  214. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/artefact-catalogue-widget.js +27 -4
  215. package/dist/_pkgs/affine-widget-edgeless-toolbar/create-popper.js +13 -0
  216. package/dist/_pkgs/affine-widget-edgeless-toolbar/index.d.ts +2 -0
  217. package/dist/_pkgs/affine-widget-edgeless-toolbar/index.js +2 -0
  218. package/dist/_pkgs/affine-widget-edgeless-toolbar/menu/command-menu.d.ts +80 -0
  219. package/dist/_pkgs/affine-widget-edgeless-toolbar/menu/command-menu.js +270 -81
  220. package/dist/_pkgs/affine-widget-edgeless-toolbar/menu/senior-menu-selection.d.ts +15 -0
  221. package/dist/_pkgs/affine-widget-edgeless-toolbar/menu/senior-menu-selection.js +15 -0
  222. package/dist/_pkgs/affine-widget-edgeless-toolbar/panel/font-weight-and-style-panel.js +8 -1
  223. package/dist/_pkgs/affine-widget-edgeless-toolbar/placement/artefact-ghost-overlay.d.ts +42 -0
  224. package/dist/_pkgs/affine-widget-edgeless-toolbar/placement/artefact-ghost-overlay.js +100 -0
  225. package/dist/_pkgs/affine-widget-edgeless-toolbar/placement/artefact-placement-tool.d.ts +100 -0
  226. package/dist/_pkgs/affine-widget-edgeless-toolbar/placement/artefact-placement-tool.js +274 -0
  227. package/dist/_pkgs/affine-widget-edgeless-toolbar/placement/index.d.ts +3 -0
  228. package/dist/_pkgs/affine-widget-edgeless-toolbar/placement/index.js +3 -0
  229. package/dist/_pkgs/affine-widget-edgeless-toolbar/placement/translate-created.d.ts +25 -0
  230. package/dist/_pkgs/affine-widget-edgeless-toolbar/placement/translate-created.js +67 -0
  231. package/dist/_pkgs/affine-widget-edgeless-toolbar/view.js +5 -0
  232. package/dist/_pkgs/global/gfx/xywh.js +7 -0
  233. package/dist/_pkgs/std/extension/command-registry.d.ts +158 -1
  234. package/dist/_pkgs/std/extension/command-registry.js +22 -0
  235. package/dist/_pkgs/std/gfx/index.d.ts +1 -1
  236. package/dist/_pkgs/std/gfx/interactivity/gfx-view-event-handler.d.ts +12 -0
  237. package/dist/_pkgs/std/gfx/interactivity/gfx-view-event-handler.js +20 -1
  238. package/dist/_pkgs/std/gfx/interactivity/manager.d.ts +10 -0
  239. package/dist/_pkgs/std/gfx/interactivity/manager.js +12 -0
  240. package/dist/_pkgs/std/gfx/model/surface/element-model.js +12 -7
  241. package/dist/_pkgs/std/gfx/model/surface/surface-model.d.ts +56 -0
  242. package/dist/_pkgs/std/gfx/model/surface/surface-model.js +84 -3
  243. package/dist/_pkgs/std/gfx/view/view.d.ts +11 -2
  244. package/dist/_pkgs/std/gfx/view/view.js +16 -2
  245. package/dist/commands.d.ts +6 -0
  246. package/dist/commands.js +8 -1
  247. package/dist/frameworks.d.ts +9 -0
  248. package/dist/frameworks.js +19 -0
  249. package/dist/translations.js +16 -0
  250. package/package.json +9 -4
  251. package/dist/_pkgs/affine-gfx-group/group-watcher.d.ts +0 -1
  252. package/dist/_pkgs/affine-gfx-group/group-watcher.js +0 -20
@@ -1,5 +1,11 @@
1
1
  import type { DomRenderer } from '../../../affine-block-surface/index.js';
2
- import { type ConnectorElementModel } from '../../../affine-model/index.js';
2
+ import { type ConnectorElementModel, type PointStyle } from '../../../affine-model/index.js';
3
+ /**
4
+ * Exported for `src/__tests__/endpoint-style.unit.spec.ts`: the hollow heads are
5
+ * defined by the fact that `fill` and `stroke` differ, which is only observable
6
+ * on the marker node this builds.
7
+ */
8
+ export declare function createArrowMarker(id: string, style: PointStyle, color: string, strokeWidth: number, isStart?: boolean): SVGMarkerElement;
3
9
  /**
4
10
  * Renders a ConnectorElementModel to a given HTMLElement using DOM/SVG.
5
11
  * This function is intended to be registered via the DomElementRendererExtension.
@@ -1,8 +1,26 @@
1
1
  import { ConnectorMode, DefaultTheme, } from '../../../affine-model/index.js';
2
2
  import { PointLocation, SVGPathBuilder } from '../../../global/gfx/index.js';
3
3
  import { isConnectorWithLabel } from '../../connector-manager.js';
4
- import { DEFAULT_ARROW_SIZE } from '../utils.js';
4
+ import { DEFAULT_ARROW_SIZE, HOLLOW_HEAD_FILL } from '../utils.js';
5
5
  const SVG_NS = 'http://www.w3.org/2000/svg';
6
+ /**
7
+ * The outline width of a hollow head, in the marker's own `viewBox` units.
8
+ *
9
+ * Pinned rather than inherited. A marker declares `markerUnits="strokeWidth"`
10
+ * and a `0 0 20 20` viewBox mapped onto `markerWidth`, so one viewBox unit is
11
+ * already a fixed fraction of the connector's `strokeWidth` — the outline
12
+ * scales with the line without this attribute existing, and `1` is exactly the
13
+ * SVG default the solid heads get implicitly today. Nothing changes visually.
14
+ *
15
+ * It is set only on the hollow heads because they are the only ones where the
16
+ * value is observable: a solid head paints `fill` and `stroke` in the same
17
+ * colour, so its outline is invisible either way. On a hollow head the outline
18
+ * IS the head. Leaving it to a default that a future `stroke-width` on the
19
+ * `<svg>`, the `<defs>`, or the marker itself would override means the UML
20
+ * heads could silently thicken or vanish; the solid twins would not notice.
21
+ */
22
+ const HOLLOW_HEAD_STROKE_WIDTH = 1;
23
+ const LABEL_SLOTS = ['center', 'source', 'target'];
6
24
  /**
7
25
  * The nodes a connector host already owns, kept across renders. Rebuilding the
8
26
  * whole `<svg>` subtree on every frame allocated one element per connector per
@@ -46,7 +64,12 @@ function createConnectorPath(points, mode) {
46
64
  }
47
65
  return pathBuilder.build();
48
66
  }
49
- function createArrowMarker(id, style, color, strokeWidth, isStart = false) {
67
+ /**
68
+ * Exported for `src/__tests__/endpoint-style.unit.spec.ts`: the hollow heads are
69
+ * defined by the fact that `fill` and `stroke` differ, which is only observable
70
+ * on the marker node this builds.
71
+ */
72
+ export function createArrowMarker(id, style, color, strokeWidth, isStart = false) {
50
73
  const marker = document.createElementNS(SVG_NS, 'marker');
51
74
  const size = DEFAULT_ARROW_SIZE * (strokeWidth / 2);
52
75
  marker.id = id;
@@ -57,6 +80,8 @@ function createArrowMarker(id, style, color, strokeWidth, isStart = false) {
57
80
  marker.setAttribute('markerHeight', String(size));
58
81
  marker.setAttribute('orient', 'auto');
59
82
  marker.setAttribute('markerUnits', 'strokeWidth');
83
+ // No `default`, as on the canvas side: an unknown persisted `PointStyle`
84
+ // yields an empty marker rather than a wrong head.
60
85
  switch (style) {
61
86
  case 'Arrow': {
62
87
  const path = document.createElementNS(SVG_NS, 'path');
@@ -74,6 +99,15 @@ function createArrowMarker(id, style, color, strokeWidth, isStart = false) {
74
99
  marker.append(path);
75
100
  break;
76
101
  }
102
+ case 'TriangleHollow': {
103
+ const path = document.createElementNS(SVG_NS, 'path');
104
+ path.setAttribute('d', isStart ? 'M 20 7 L 12 10 L 20 13 Z' : 'M 0 7 L 8 10 L 0 13 Z');
105
+ path.setAttribute('fill', HOLLOW_HEAD_FILL);
106
+ path.setAttribute('stroke', color);
107
+ path.setAttribute('stroke-width', String(HOLLOW_HEAD_STROKE_WIDTH));
108
+ marker.append(path);
109
+ break;
110
+ }
77
111
  case 'Circle': {
78
112
  const circle = document.createElementNS(SVG_NS, 'circle');
79
113
  circle.setAttribute('cx', '10');
@@ -92,6 +126,15 @@ function createArrowMarker(id, style, color, strokeWidth, isStart = false) {
92
126
  marker.append(path);
93
127
  break;
94
128
  }
129
+ case 'DiamondHollow': {
130
+ const path = document.createElementNS(SVG_NS, 'path');
131
+ path.setAttribute('d', 'M 10 6 L 14 10 L 10 14 L 6 10 Z');
132
+ path.setAttribute('fill', HOLLOW_HEAD_FILL);
133
+ path.setAttribute('stroke', color);
134
+ path.setAttribute('stroke-width', String(HOLLOW_HEAD_STROKE_WIDTH));
135
+ marker.append(path);
136
+ break;
137
+ }
95
138
  }
96
139
  return marker;
97
140
  }
@@ -119,29 +162,53 @@ function getRetainedConnectorDom(element) {
119
162
  svg,
120
163
  defs,
121
164
  path,
122
- label: null,
165
+ labels: {},
123
166
  };
124
167
  retainedConnectorDom.set(element, retained);
125
168
  return retained;
126
169
  }
127
- function getOrCreateLabelElement(retained) {
128
- if (retained.label) {
129
- return retained.label;
170
+ function getOrCreateLabelElement(retained, slot) {
171
+ const existing = retained.labels[slot];
172
+ if (existing) {
173
+ return existing;
130
174
  }
131
175
  const label = document.createElement('div');
132
- retained.svg.insertAdjacentElement('afterend', label);
133
- retained.label = label;
176
+ // Appended after the `<svg>` rather than inserted directly behind it, so the
177
+ // three captions land in slot order instead of in reverse creation order.
178
+ // Every one of them is absolutely positioned, so document order is a
179
+ // debugging convenience, not a layout decision.
180
+ (retained.svg.parentElement ?? retained.svg).append(label);
181
+ retained.labels[slot] = label;
134
182
  return label;
135
183
  }
136
- function renderConnectorLabel(model, retained, renderer, zoom) {
137
- if (!isConnectorWithLabel(model) || !model.labelXYWH) {
138
- retained.label?.remove();
139
- retained.label = null;
184
+ /**
185
+ * The text and box one slot paints, or `null` when that caption is absent.
186
+ *
187
+ * The DOM twin of `paintedLabels` on the canvas side: same three slots, same
188
+ * `labelStyle` shared by all three, so the two renderers cannot disagree about
189
+ * what a connector is showing.
190
+ */
191
+ function labelContent(model, slot) {
192
+ if (slot === 'center') {
193
+ return isConnectorWithLabel(model) && model.labelXYWH
194
+ ? { text: model.text?.toString() ?? '', xywh: model.labelXYWH }
195
+ : null;
196
+ }
197
+ const xywh = model.endLabelXYWH(slot);
198
+ return model.hasEndLabel(slot) && xywh
199
+ ? { text: model.endLabelText(slot)?.toString() ?? '', xywh }
200
+ : null;
201
+ }
202
+ function renderConnectorLabel(model, retained, renderer, zoom, slot) {
203
+ const content = labelContent(model, slot);
204
+ if (!content) {
205
+ retained.labels[slot]?.remove();
206
+ delete retained.labels[slot];
140
207
  return;
141
208
  }
142
- const [lx, ly, lw, lh] = model.labelXYWH;
209
+ const [lx, ly, lw, lh] = content.xywh;
143
210
  const { labelStyle: { color, fontSize, fontWeight, fontStyle, fontFamily, textAlign, }, } = model;
144
- const labelElement = getOrCreateLabelElement(retained);
211
+ const labelElement = getOrCreateLabelElement(retained, slot);
145
212
  labelElement.style.position = 'absolute';
146
213
  labelElement.style.left = `${lx * zoom}px`;
147
214
  labelElement.style.top = `${ly * zoom}px`;
@@ -168,7 +235,7 @@ function renderConnectorLabel(model, retained, renderer, zoom) {
168
235
  labelElement.style.whiteSpace = 'pre-wrap';
169
236
  labelElement.style.wordWrap = 'break-word';
170
237
  // Add text content
171
- labelElement.textContent = model.text ? model.text.toString() : '';
238
+ labelElement.textContent = content.text;
172
239
  }
173
240
  /**
174
241
  * Renders a ConnectorElementModel to a given HTMLElement using DOM/SVG.
@@ -264,6 +331,9 @@ export const connectorDomRenderer = (model, element, renderer) => {
264
331
  element.style.height = `${model.h * zoom}px`;
265
332
  element.style.overflow = 'visible';
266
333
  element.style.pointerEvents = 'none';
267
- // Render label if present
268
- renderConnectorLabel(model, retained, renderer, zoom);
334
+ // Render each caption that is present — the centre name and the two end
335
+ // labels — and drop the node of any that is not.
336
+ for (const slot of LABEL_SLOTS) {
337
+ renderConnectorLabel(model, retained, renderer, zoom, slot);
338
+ }
269
339
  };
@@ -1,10 +1,35 @@
1
1
  import { ElementRendererExtension, } from '../../affine-block-surface/index.js';
2
2
  import { getFontString, getLineHeight, getTextWidth, isRTL, wrapTextDeltas, } from '../../affine-gfx-text/index.js';
3
3
  import { ConnectorMode, DefaultTheme, } from '../../affine-model/index.js';
4
- import { getBezierParameters } from '../../global/gfx/index.js';
4
+ import { getBezierParameters, } from '../../global/gfx/index.js';
5
5
  import { deltaInsertsToChunks } from '../../std/inline/index.js';
6
- import { isConnectorWithLabel } from '../connector-manager.js';
7
- import { DEFAULT_ARROW_SIZE, getArrowOptions, renderArrow, renderCircle, renderDiamond, renderTriangle, } from './utils.js';
6
+ import { isConnectorWithEndLabel, isConnectorWithLabel, } from '../connector-manager.js';
7
+ import { DEFAULT_ARROW_SIZE, getArrowOptions, HOLLOW_HEAD_FILL, renderArrow, renderCircle, renderDiamond, renderTriangle, } from './utils.js';
8
+ /** The captions this connector paints, in the order they are drawn. */
9
+ function paintedLabels(model) {
10
+ const labels = [];
11
+ if (isConnectorWithLabel(model)) {
12
+ const { text, labelXYWH, labelStyle, labelConstraints } = model;
13
+ labels.push({
14
+ text: text,
15
+ xywh: labelXYWH,
16
+ style: labelStyle,
17
+ constraints: labelConstraints,
18
+ });
19
+ }
20
+ for (const end of ['source', 'target']) {
21
+ if (!isConnectorWithEndLabel(model, end))
22
+ continue;
23
+ const connectorModel = model;
24
+ labels.push({
25
+ text: connectorModel.endLabelText(end),
26
+ xywh: connectorModel.endLabelXYWH(end),
27
+ style: connectorModel.labelStyle,
28
+ constraints: connectorModel.labelConstraints,
29
+ });
30
+ }
31
+ return labels;
32
+ }
8
33
  export const connector = (model, ctx, matrix, renderer, rc) => {
9
34
  const { mode, path: points, strokeStyle, frontEndpointStyle, rearEndpointStyle, strokeWidth, } = model;
10
35
  // points might not be build yet in some senarios
@@ -13,29 +38,39 @@ export const connector = (model, ctx, matrix, renderer, rc) => {
13
38
  return;
14
39
  }
15
40
  ctx.setTransform(matrix);
16
- const hasLabel = isConnectorWithLabel(model);
17
- let dx = 0;
18
- let dy = 0;
19
- if (hasLabel) {
41
+ const labels = paintedLabels(model);
42
+ // Each label's box, expressed relative to the element's own origin — the
43
+ // frame both the clip rects and the per-label transforms are written in.
44
+ let offsets = [];
45
+ if (labels.length) {
20
46
  ctx.save();
21
- const { deserializedXYWH, labelXYWH } = model;
47
+ const { deserializedXYWH } = model;
22
48
  const [x, y, w, h] = deserializedXYWH;
23
- const [lx, ly, lw, lh] = labelXYWH;
24
49
  const offset = DEFAULT_ARROW_SIZE * strokeWidth;
25
- dx = lx - x;
26
- dy = ly - y;
50
+ offsets = labels.map(label => [label.xywh[0] - x, label.xywh[1] - y]);
51
+ // One subtracted rect PER label: `evenodd` over the element rect and the
52
+ // caption rects leaves the stroke everywhere except under a caption, so a
53
+ // multiplicity beside an end punches the line exactly as the centre name
54
+ // always has.
27
55
  const path = new Path2D();
28
56
  path.rect(-offset / 2, -offset / 2, w + offset, h + offset);
29
- path.rect(dx - 3 - 0.5, dy - 3 - 0.5, lw + 6 + 1, lh + 6 + 1);
57
+ labels.forEach((label, index) => {
58
+ const [dx, dy] = offsets[index];
59
+ const [, , lw, lh] = label.xywh;
60
+ path.rect(dx - 3 - 0.5, dy - 3 - 0.5, lw + 6 + 1, lh + 6 + 1);
61
+ });
30
62
  ctx.clip(path, 'evenodd');
31
63
  }
32
64
  const strokeColor = renderer.getColorValue(model.stroke, DefaultTheme.connectorColor, true);
33
65
  renderPoints(model, ctx, rc, points, strokeStyle === 'dash', mode === ConnectorMode.Curve, strokeColor);
34
66
  renderEndpoint(model, points, ctx, rc, 'Front', frontEndpointStyle, strokeColor);
35
67
  renderEndpoint(model, points, ctx, rc, 'Rear', rearEndpointStyle, strokeColor);
36
- if (hasLabel) {
68
+ if (labels.length) {
37
69
  ctx.restore();
38
- renderLabel(model, ctx, matrix.translate(dx, dy), renderer);
70
+ labels.forEach((label, index) => {
71
+ const [dx, dy] = offsets[index];
72
+ renderLabel(label, ctx, matrix.translate(dx, dy), renderer);
73
+ });
39
74
  }
40
75
  };
41
76
  export const ConnectorElementRendererExtension = ElementRendererExtension('connector', connector);
@@ -93,6 +128,13 @@ function renderPoints(model, ctx, rc, points, dash, curve, stroke) {
93
128
  }
94
129
  function renderEndpoint(model, location, ctx, rc, end, style, stroke) {
95
130
  const arrowOptions = getArrowOptions(end, model, stroke);
131
+ // No `default` on purpose: `PointStyle` is a persisted, append-only enum, so
132
+ // a build older than a member paints no head rather than throwing or drawing
133
+ // a wrong one. See the enum's docblock in `@labre/affine-model`.
134
+ //
135
+ // The hollow spread lives inside its own case: this runs once per endpoint
136
+ // per frame, and a solid head — or `None`, the default on the front of every
137
+ // connector — should not allocate an options object it never reads.
96
138
  switch (style) {
97
139
  case 'Arrow':
98
140
  renderArrow(location, ctx, rc, arrowOptions);
@@ -100,23 +142,42 @@ function renderEndpoint(model, location, ctx, rc, end, style, stroke) {
100
142
  case 'Triangle':
101
143
  renderTriangle(location, ctx, rc, arrowOptions);
102
144
  break;
145
+ case 'TriangleHollow':
146
+ renderTriangle(location, ctx, rc, {
147
+ ...arrowOptions,
148
+ fillColor: HOLLOW_HEAD_FILL,
149
+ });
150
+ break;
103
151
  case 'Circle':
104
152
  renderCircle(location, ctx, rc, arrowOptions);
105
153
  break;
106
154
  case 'Diamond':
107
155
  renderDiamond(location, ctx, rc, arrowOptions);
108
156
  break;
157
+ case 'DiamondHollow':
158
+ renderDiamond(location, ctx, rc, {
159
+ ...arrowOptions,
160
+ fillColor: HOLLOW_HEAD_FILL,
161
+ });
162
+ break;
109
163
  }
110
164
  }
111
- function renderLabel(model, ctx, matrix, renderer) {
112
- const { text, labelXYWH, labelStyle: { color, fontSize, fontWeight, fontStyle, fontFamily, textAlign, }, labelConstraints: { hasMaxWidth, maxWidth }, } = model;
165
+ /**
166
+ * Paints ONE caption at the origin of `matrix`.
167
+ *
168
+ * Takes a label rather than the connector: the centre name and the two end
169
+ * labels are the same drawing, and the only thing that told them apart was
170
+ * which pair of fields the function reached into.
171
+ */
172
+ function renderLabel(label, ctx, matrix, renderer) {
173
+ const { text, xywh, style: { color, fontSize, fontWeight, fontStyle, fontFamily, textAlign }, constraints: { hasMaxWidth, maxWidth }, } = label;
113
174
  const font = getFontString({
114
175
  fontStyle,
115
176
  fontWeight,
116
177
  fontSize,
117
178
  fontFamily,
118
179
  });
119
- const [, , w, h] = labelXYWH;
180
+ const [, , w, h] = xywh;
120
181
  const cx = w / 2;
121
182
  const cy = h / 2;
122
183
  ctx.setTransform(matrix);
@@ -3,6 +3,17 @@ import { type ConnectorElementModel, ConnectorMode, type LocalConnectorElementMo
3
3
  import type { BezierCurveParameters, IVec, PointLocation } from '../../global/gfx/index.js';
4
4
  type ConnectorEnd = 'Front' | 'Rear';
5
5
  export declare const DEFAULT_ARROW_SIZE = 15;
6
+ /**
7
+ * The interior of a hollow endpoint head (`TriangleHollow`, `DiamondHollow`).
8
+ *
9
+ * The notation card fill (R33), NOT a theme-resolved token and NOT
10
+ * `transparent`: a UML hollow head reads as a white shape sitting on top of the
11
+ * line it terminates, exactly like the class box it points at — which is itself
12
+ * painted `NOTATION_NEUTRALS.cardFill` in every theme. `transparent` would let
13
+ * the connector's own line show through the head; a theme token would turn the
14
+ * head black-on-black next to a card-white box in a dark host.
15
+ */
16
+ export declare const HOLLOW_HEAD_FILL: string;
6
17
  export declare function getArrowPoints(points: PointLocation[], size: number | undefined, mode: ConnectorMode, bezierParameters: BezierCurveParameters, endPoint?: ConnectorEnd, radians?: number): {
7
18
  points: (IVec | PointLocation)[];
8
19
  };
@@ -12,7 +23,12 @@ export declare function getDiamondPoints(point: PointLocation, size?: number, en
12
23
  points: (IVec | PointLocation)[];
13
24
  };
14
25
  export type ArrowOptions = ReturnType<typeof getArrowOptions>;
15
- export declare function getArrowOptions(end: ConnectorEnd, model: ConnectorElementModel | LocalConnectorElementModel, strokeColor: string): {
26
+ /**
27
+ * @param fillColor the interior of a closed head. Defaults to `strokeColor`, so
28
+ * a `Triangle` or a `Diamond` stays the solid head it has always been; the
29
+ * hollow UML heads pass `HOLLOW_HEAD_FILL` instead.
30
+ */
31
+ export declare function getArrowOptions(end: ConnectorEnd, model: ConnectorElementModel | LocalConnectorElementModel, strokeColor: string, fillColor?: string): {
16
32
  end: ConnectorEnd;
17
33
  seed: number;
18
34
  mode: ConnectorMode;
@@ -32,7 +48,13 @@ export declare function getRcOptions(options: ArrowOptions): {
32
48
  fill: string;
33
49
  fillStyle: string;
34
50
  };
35
- export declare function renderRoundedPolygon(ctx: CanvasRenderingContext2D, points: IVec[], color: string, strokeWidth: number, fill?: boolean): void;
51
+ /**
52
+ * @param color the outline colour.
53
+ * @param fillColor the interior colour. Defaults to `color` — the solid head.
54
+ * A hollow head passes the notation card fill, so the outline stays the
55
+ * connector's colour while the inside reads as empty.
56
+ */
57
+ export declare function renderRoundedPolygon(ctx: CanvasRenderingContext2D, points: IVec[], color: string, strokeWidth: number, fill?: boolean, fillColor?: string): void;
36
58
  export declare function renderArrow(points: PointLocation[], ctx: CanvasRenderingContext2D, rc: RoughCanvas, options: ArrowOptions): void;
37
59
  export declare function renderTriangle(points: PointLocation[], ctx: CanvasRenderingContext2D, rc: RoughCanvas, options: ArrowOptions): void;
38
60
  export declare function renderDiamond(points: PointLocation[], ctx: CanvasRenderingContext2D, rc: RoughCanvas, options: ArrowOptions): void;
@@ -1,6 +1,18 @@
1
1
  import { ConnectorMode, } from '../../affine-model/index.js';
2
+ import { NOTATION_NEUTRALS } from '../../affine-shared/consts/index.js';
2
3
  import { getBezierParameters, getBezierTangent, Vec } from '../../global/gfx/index.js';
3
4
  export const DEFAULT_ARROW_SIZE = 15;
5
+ /**
6
+ * The interior of a hollow endpoint head (`TriangleHollow`, `DiamondHollow`).
7
+ *
8
+ * The notation card fill (R33), NOT a theme-resolved token and NOT
9
+ * `transparent`: a UML hollow head reads as a white shape sitting on top of the
10
+ * line it terminates, exactly like the class box it points at — which is itself
11
+ * painted `NOTATION_NEUTRALS.cardFill` in every theme. `transparent` would let
12
+ * the connector's own line show through the head; a theme token would turn the
13
+ * head black-on-black next to a card-white box in a dark host.
14
+ */
15
+ export const HOLLOW_HEAD_FILL = NOTATION_NEUTRALS.cardFill;
4
16
  export function getArrowPoints(points, size = 10, mode, bezierParameters, endPoint = 'Rear', radians = Math.PI / 4) {
5
17
  const anchorPoint = getPointWithTangent(points, mode, endPoint, bezierParameters);
6
18
  const unit = Vec.mul(anchorPoint.tangent, -1);
@@ -70,7 +82,12 @@ export function getDiamondPoints(point, size = 10, endPoint = 'Rear') {
70
82
  points: diamondPoints,
71
83
  };
72
84
  }
73
- export function getArrowOptions(end, model, strokeColor) {
85
+ /**
86
+ * @param fillColor the interior of a closed head. Defaults to `strokeColor`, so
87
+ * a `Triangle` or a `Diamond` stays the solid head it has always been; the
88
+ * hollow UML heads pass `HOLLOW_HEAD_FILL` instead.
89
+ */
90
+ export function getArrowOptions(end, model, strokeColor, fillColor = strokeColor) {
74
91
  const { seed, mode, rough, roughness, strokeWidth, path } = model;
75
92
  return {
76
93
  end,
@@ -80,7 +97,7 @@ export function getArrowOptions(end, model, strokeColor) {
80
97
  roughness,
81
98
  strokeWidth,
82
99
  strokeColor,
83
- fillColor: strokeColor,
100
+ fillColor,
84
101
  fillStyle: 'solid',
85
102
  bezierParameters: getBezierParameters(path),
86
103
  };
@@ -96,8 +113,14 @@ export function getRcOptions(options) {
96
113
  fillStyle: 'solid',
97
114
  };
98
115
  }
99
- export function renderRoundedPolygon(ctx, points, color, strokeWidth, fill = true) {
100
- ctx.fillStyle = color;
116
+ /**
117
+ * @param color the outline colour.
118
+ * @param fillColor the interior colour. Defaults to `color` — the solid head.
119
+ * A hollow head passes the notation card fill, so the outline stays the
120
+ * connector's colour while the inside reads as empty.
121
+ */
122
+ export function renderRoundedPolygon(ctx, points, color, strokeWidth, fill = true, fillColor = color) {
123
+ ctx.fillStyle = fillColor;
101
124
  ctx.strokeStyle = color;
102
125
  ctx.lineWidth = strokeWidth;
103
126
  ctx.lineJoin = 'round';
@@ -132,7 +155,7 @@ export function renderArrow(points, ctx, rc, options) {
132
155
  }
133
156
  }
134
157
  export function renderTriangle(points, ctx, rc, options) {
135
- const { mode, end, bezierParameters, rough, strokeColor, strokeWidth } = options;
158
+ const { mode, end, bezierParameters, rough, fillColor, strokeColor, strokeWidth, } = options;
136
159
  const radians = Math.PI / 6;
137
160
  const size = DEFAULT_ARROW_SIZE * (strokeWidth / 2);
138
161
  const { points: trianglePoints } = getArrowPoints(points, size, mode, bezierParameters, end, radians);
@@ -144,11 +167,11 @@ export function renderTriangle(points, ctx, rc, options) {
144
167
  ], getRcOptions(options));
145
168
  }
146
169
  else {
147
- renderRoundedPolygon(ctx, trianglePoints, strokeColor, strokeWidth);
170
+ renderRoundedPolygon(ctx, trianglePoints, strokeColor, strokeWidth, true, fillColor);
148
171
  }
149
172
  }
150
173
  export function renderDiamond(points, ctx, rc, options) {
151
- const { mode, end, rough, bezierParameters, strokeColor, strokeWidth } = options;
174
+ const { mode, end, rough, bezierParameters, fillColor, strokeColor, strokeWidth, } = options;
152
175
  const anchorPoint = getPointWithTangent(points, mode, end, bezierParameters);
153
176
  const size = 10 * (strokeWidth / 2);
154
177
  const { points: diamondPoints } = getDiamondPoints(anchorPoint, size, end);
@@ -161,7 +184,7 @@ export function renderDiamond(points, ctx, rc, options) {
161
184
  ], getRcOptions(options));
162
185
  }
163
186
  else {
164
- renderRoundedPolygon(ctx, diamondPoints, strokeColor, strokeWidth);
187
+ renderRoundedPolygon(ctx, diamondPoints, strokeColor, strokeWidth, true, fillColor);
165
188
  }
166
189
  }
167
190
  export function renderCircle(points, ctx, rc, options) {
@@ -1,17 +1,136 @@
1
- import type { ConnectorElementModel } from '../../affine-model/index.js';
1
+ import { type ConnectorElementModel, type ConnectorLabelEnd } from '../../affine-model/index.js';
2
2
  import type { RichText } from '../../affine-rich-text/index.js';
3
- import { type IVec } from '../../global/gfx/index.js';
3
+ import { type IVec, type XYWH } from '../../global/gfx/index.js';
4
4
  import { type BlockComponent, type BlockStdScope, ShadowlessElement } from '../../std/index.js';
5
- export declare function mountConnectorLabelEditor(connector: ConnectorElementModel, edgeless: BlockComponent, point?: IVec): void;
5
+ import * as Y from 'yjs';
6
+ /**
7
+ * Which of a connector's three labels a gesture is about — its centre caption,
8
+ * or one of the two end labels UML writes multiplicities and role names in
9
+ * (`docs/adr/0018` phase 2).
10
+ *
11
+ * Built on the model's own `ConnectorLabelEnd` rather than restating its two
12
+ * members: the ends are the model's vocabulary — they are the names of its two
13
+ * `Connection`s — and only the EDITOR has a third case, because only the editor
14
+ * has to be pointed at one label out of three.
15
+ */
16
+ export type ConnectorLabelWhich = 'center' | ConnectorLabelEnd;
17
+ /**
18
+ * The model fields each label lives in.
19
+ *
20
+ * Declared once, as data, because THREE places need the same answer — the
21
+ * editor's read, its resize write and its empty-commit delete — and three
22
+ * `which === 'center' ? … : …` chains is how one of them ends up writing the
23
+ * centre label's box under an end label's text.
24
+ */
25
+ export declare const CONNECTOR_LABEL_FIELDS: {
26
+ readonly center: {
27
+ readonly text: "text";
28
+ readonly xywh: "labelXYWH";
29
+ };
30
+ readonly source: {
31
+ readonly text: "sourceLabel";
32
+ readonly xywh: "sourceLabelXYWH";
33
+ };
34
+ readonly target: {
35
+ readonly text: "targetLabel";
36
+ readonly xywh: "targetLabelXYWH";
37
+ };
38
+ };
39
+ /** {@link CONNECTOR_LABEL_FIELDS}, defaulting to the centre label. */
40
+ export declare function connectorLabelFields(which?: ConnectorLabelWhich): {
41
+ readonly text: "text";
42
+ readonly xywh: "labelXYWH";
43
+ } | {
44
+ readonly text: "sourceLabel";
45
+ readonly xywh: "sourceLabelXYWH";
46
+ } | {
47
+ readonly text: "targetLabel";
48
+ readonly xywh: "targetLabelXYWH";
49
+ };
50
+ /** The `Y.Text` of `which`, or `undefined` when that label does not exist. */
51
+ export declare function connectorLabelText(connector: ConnectorElementModel, which?: ConnectorLabelWhich): Y.Text | undefined;
52
+ /** The box of `which`, or `undefined` when that label does not exist. */
53
+ export declare function connectorLabelXYWH(connector: ConnectorElementModel, which?: ConnectorLabelWhich): XYWH | undefined;
54
+ /**
55
+ * The box an end label of `size` takes on the current path — the one geometry
56
+ * helper the model owns, so the renderer, the editor and the hit test all place
57
+ * an end label in the same spot.
58
+ */
59
+ export declare function connectorEndLabelBoxFor(connector: ConnectorElementModel, which: ConnectorLabelEnd, size?: {
60
+ w: number;
61
+ h: number;
62
+ }): XYWH;
63
+ /**
64
+ * What to write so that `which` EXISTS, or `null` when it already does.
65
+ *
66
+ * The centre label is seeded where the pointer is, riding the path by an offset
67
+ * distance — it has always been a caption the author places. An end label is
68
+ * seeded at its ENDPOINT and ignores the pointer: the whole value of one is
69
+ * that it follows the end when the node moves (`docs/adr/0018`, "Alternatives
70
+ * rejected"), so where the double-click landed says nothing about where it
71
+ * belongs.
72
+ */
73
+ export declare function connectorLabelSeedProps(connector: ConnectorElementModel, which?: ConnectorLabelWhich, point?: IVec): Record<string, unknown> | null;
74
+ /**
75
+ * What to write when an editing session ENDS, or `null` when the text is
76
+ * already exactly what the model holds.
77
+ *
78
+ * A label committed empty clears both of its fields, so the connector reads
79
+ * as one that has none (`hasEndLabel` false, nothing painted, nothing
80
+ * exported). The KEYS stay in the Y.Map as `undefined` — the field setter
81
+ * writes what it is given — so only a connector that never carried an end
82
+ * label is byte-identical to a pre-0020 one; `docs/adr/0020`'s "no migration"
83
+ * promise is about that connector, not about this reset.
84
+ *
85
+ * Pure and exported: it is the one rule with three outcomes (delete, trim,
86
+ * nothing) times three labels, and a spec should be able to ask it directly.
87
+ */
88
+ export declare function connectorLabelCommitProps(raw: string, which?: ConnectorLabelWhich): Record<string, unknown> | null;
89
+ export type MountConnectorLabelEditorOptions = {
90
+ /** Which label to edit. Defaults to the centre one. */
91
+ which?: ConnectorLabelWhich;
92
+ };
93
+ /**
94
+ * Opens the label editor on ONE of a connector's three labels.
95
+ *
96
+ * This function used to exist twice — here and byte-alike in `text.ts`, which
97
+ * was the copy the package barrel re-exported — so the toolbar and the keyboard
98
+ * reached one body and the view's double-click the other. `docs/adr/0018`
99
+ * phase 2 makes the difference visible (a selector only one copy would have
100
+ * carried), so the duplicate is gone and `text.ts` re-exports this one.
101
+ */
102
+ export declare function mountConnectorLabelEditor(connector: ConnectorElementModel, edgeless: BlockComponent, point?: IVec, options?: MountConnectorLabelEditorOptions): void;
6
103
  declare const EdgelessConnectorLabelEditor_base: typeof ShadowlessElement & import("../../global/utils/types.js").Constructor<import("../../global/lit/with-disposable.js").DisposableClass>;
7
104
  export declare class EdgelessConnectorLabelEditor extends EdgelessConnectorLabelEditor_base {
8
105
  static styles: import("lit").CSSResult;
9
106
  get crud(): import("../../affine-block-surface/index.js").EdgelessCRUDExtension;
10
107
  get gfx(): import("../../std/gfx/controller.js").GfxController;
11
108
  get selection(): import("../../std/gfx/selection.js").GfxSelectionManager;
109
+ /** The two model fields this editor reads and writes. */
110
+ get fields(): {
111
+ readonly text: "text";
112
+ readonly xywh: "labelXYWH";
113
+ } | {
114
+ readonly text: "sourceLabel";
115
+ readonly xywh: "sourceLabelXYWH";
116
+ } | {
117
+ readonly text: "targetLabel";
118
+ readonly xywh: "targetLabelXYWH";
119
+ };
120
+ /** The `Y.Text` this editor is bound to. */
121
+ get yText(): Y.Text | undefined;
12
122
  private _isComposition;
13
123
  private _keeping;
124
+ private _removing;
14
125
  private _resizeObserver;
126
+ /**
127
+ * Where the editor sits, in MODEL coordinates.
128
+ *
129
+ * The centre label rides the path by its offset distance, so its anchor is
130
+ * recomputed from the connector; an end label's box is the anchor, and it is
131
+ * the box that follows the endpoint (see `connectorEndLabelBox`).
132
+ */
133
+ private get _labelCenter();
15
134
  private readonly _updateLabelRect;
16
135
  get inlineEditor(): import("../../affine-shared/types/index.js").AffineInlineEditor | null;
17
136
  get inlineEditorContainer(): import("../../std/inline/inline-editor.js").InlineRootElement<import("../../affine-shared/types/index.js").AffineTextAttributes> | null | undefined;
@@ -22,6 +141,8 @@ export declare class EdgelessConnectorLabelEditor extends EdgelessConnectorLabel
22
141
  render(): import("lit-html").TemplateResult<1>;
23
142
  setKeeping(keeping: boolean): void;
24
143
  accessor connector: ConnectorElementModel;
144
+ /** Which of the connector's three labels is being edited. */
145
+ accessor which: ConnectorLabelWhich;
25
146
  accessor std: BlockStdScope;
26
147
  accessor richText: RichText;
27
148
  }