@formicoidea/labre-core 0.48.0 → 0.49.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 (222) hide show
  1. package/dist/_pkgs/affine-block-data-view/configs/slash-menu.js +3 -1
  2. package/dist/_pkgs/affine-block-data-view/view.d.ts +17 -1
  3. package/dist/_pkgs/affine-block-data-view/view.js +21 -2
  4. package/dist/_pkgs/affine-block-database/commands.d.ts +2 -2
  5. package/dist/_pkgs/affine-block-database/commands.js +3 -3
  6. package/dist/_pkgs/affine-block-database/components/values-banner.d.ts +28 -0
  7. package/dist/_pkgs/affine-block-database/components/values-banner.js +199 -0
  8. package/dist/_pkgs/affine-block-database/configs/slash-menu.d.ts +6 -1
  9. package/dist/_pkgs/affine-block-database/configs/slash-menu.js +57 -70
  10. package/dist/_pkgs/affine-block-database/data-source.d.ts +9 -5
  11. package/dist/_pkgs/affine-block-database/data-source.js +11 -7
  12. package/dist/_pkgs/affine-block-database/database-block-styles.d.ts +2 -0
  13. package/dist/_pkgs/affine-block-database/database-block-styles.js +15 -0
  14. package/dist/_pkgs/affine-block-database/database-block.d.ts +23 -0
  15. package/dist/_pkgs/affine-block-database/database-block.js +141 -19
  16. package/dist/_pkgs/affine-block-database/effects.js +2 -0
  17. package/dist/_pkgs/affine-block-database/external-data-source.d.ts +69 -2
  18. package/dist/_pkgs/affine-block-database/external-data-source.js +88 -16
  19. package/dist/_pkgs/affine-block-database/index.d.ts +2 -0
  20. package/dist/_pkgs/affine-block-database/index.js +2 -0
  21. package/dist/_pkgs/affine-block-database/linked-view.d.ts +38 -0
  22. package/dist/_pkgs/affine-block-database/linked-view.js +109 -0
  23. package/dist/_pkgs/affine-block-database/properties/index.d.ts +2 -0
  24. package/dist/_pkgs/affine-block-database/properties/index.js +2 -0
  25. package/dist/_pkgs/affine-block-database/properties/text/hosted.d.ts +15 -0
  26. package/dist/_pkgs/affine-block-database/properties/text/hosted.js +24 -0
  27. package/dist/_pkgs/affine-block-database/properties/title/hosted.d.ts +16 -0
  28. package/dist/_pkgs/affine-block-database/properties/title/hosted.js +42 -0
  29. package/dist/_pkgs/affine-block-database/service/index.d.ts +3 -0
  30. package/dist/_pkgs/affine-block-database/service/index.js +3 -0
  31. package/dist/_pkgs/affine-block-database/service/new-row-menu.d.ts +49 -0
  32. package/dist/_pkgs/affine-block-database/service/new-row-menu.js +21 -0
  33. package/dist/_pkgs/affine-block-database/service/open-row.d.ts +77 -0
  34. package/dist/_pkgs/affine-block-database/service/open-row.js +62 -0
  35. package/dist/_pkgs/affine-block-database/service/properties-panel.d.ts +23 -0
  36. package/dist/_pkgs/affine-block-database/service/properties-panel.js +33 -0
  37. package/dist/_pkgs/affine-block-database/translations.d.ts +10 -0
  38. package/dist/_pkgs/affine-block-database/translations.js +35 -0
  39. package/dist/_pkgs/affine-block-database/view-creation.d.ts +10 -0
  40. package/dist/_pkgs/affine-block-database/view-creation.js +14 -0
  41. package/dist/_pkgs/affine-block-database/view.d.ts +31 -1
  42. package/dist/_pkgs/affine-block-database/view.js +44 -5
  43. package/dist/_pkgs/affine-block-database/views/index.d.ts +30 -3
  44. package/dist/_pkgs/affine-block-database/views/index.js +44 -3
  45. package/dist/_pkgs/affine-components/date-picker/date-picker.d.ts +20 -0
  46. package/dist/_pkgs/affine-components/date-picker/date-picker.js +60 -26
  47. package/dist/_pkgs/affine-components/date-picker/style.js +1 -0
  48. package/dist/_pkgs/affine-components/translations.d.ts +4 -0
  49. package/dist/_pkgs/affine-components/translations.js +26 -0
  50. package/dist/_pkgs/affine-fragment-doc-title/doc-title.d.ts +18 -0
  51. package/dist/_pkgs/affine-fragment-doc-title/doc-title.js +41 -2
  52. package/dist/_pkgs/affine-fragment-doc-title/title-band/band-cell.d.ts +8 -0
  53. package/dist/_pkgs/affine-fragment-doc-title/title-band/band-cell.js +12 -0
  54. package/dist/_pkgs/affine-fragment-doc-title/title-band/title-band.d.ts +5 -0
  55. package/dist/_pkgs/affine-fragment-doc-title/title-band/title-band.js +44 -4
  56. package/dist/_pkgs/affine-model/blocks/database/types.d.ts +16 -0
  57. package/dist/_pkgs/affine-model/blocks/database/types.js +5 -1
  58. package/dist/_pkgs/affine-shared/services/data-source-picker-service.d.ts +139 -0
  59. package/dist/_pkgs/affine-shared/services/data-source-picker-service.js +22 -0
  60. package/dist/_pkgs/affine-shared/services/index.d.ts +1 -0
  61. package/dist/_pkgs/affine-shared/services/index.js +1 -0
  62. package/dist/_pkgs/affine-shared/services/telemetry-service/database.d.ts +59 -0
  63. package/dist/_pkgs/affine-shared/services/title-band-service.d.ts +24 -0
  64. package/dist/_pkgs/data-view/core/component/cell-status/cell-status-css.d.ts +2 -0
  65. package/dist/_pkgs/data-view/core/component/cell-status/cell-status-css.js +16 -0
  66. package/dist/_pkgs/data-view/core/component/cell-status/cell-status.d.ts +10 -0
  67. package/dist/_pkgs/data-view/core/component/cell-status/cell-status.js +23 -0
  68. package/dist/_pkgs/data-view/core/component/index.d.ts +1 -0
  69. package/dist/_pkgs/data-view/core/component/index.js +1 -0
  70. package/dist/_pkgs/data-view/core/component/overflow/fit.d.ts +26 -0
  71. package/dist/_pkgs/data-view/core/component/overflow/fit.js +48 -0
  72. package/dist/_pkgs/data-view/core/component/overflow/overflow.d.ts +26 -3
  73. package/dist/_pkgs/data-view/core/component/overflow/overflow.js +84 -31
  74. package/dist/_pkgs/data-view/core/component/tags/colors.d.ts +7 -0
  75. package/dist/_pkgs/data-view/core/component/tags/colors.js +22 -10
  76. package/dist/_pkgs/data-view/core/component/tags/multi-tag-select.d.ts +18 -0
  77. package/dist/_pkgs/data-view/core/component/tags/multi-tag-select.js +63 -21
  78. package/dist/_pkgs/data-view/core/data-source/base.d.ts +5 -1
  79. package/dist/_pkgs/data-view/core/data-source/base.js +7 -1
  80. package/dist/_pkgs/data-view/core/data-source/hydration.d.ts +44 -0
  81. package/dist/_pkgs/data-view/core/data-source/hydration.js +31 -0
  82. package/dist/_pkgs/data-view/core/data-source/index.d.ts +1 -0
  83. package/dist/_pkgs/data-view/core/data-source/index.js +1 -0
  84. package/dist/_pkgs/data-view/core/data-view.d.ts +22 -2
  85. package/dist/_pkgs/data-view/core/data-view.js +14 -0
  86. package/dist/_pkgs/data-view/core/effect.js +2 -0
  87. package/dist/_pkgs/data-view/core/group-by/collapsed-state.d.ts +3 -0
  88. package/dist/_pkgs/data-view/core/group-by/collapsed-state.js +59 -0
  89. package/dist/_pkgs/data-view/core/group-by/group-properties.d.ts +21 -0
  90. package/dist/_pkgs/data-view/core/group-by/group-properties.js +38 -0
  91. package/dist/_pkgs/data-view/core/group-by/group-title.js +4 -0
  92. package/dist/_pkgs/data-view/core/group-by/group-visibility.d.ts +40 -0
  93. package/dist/_pkgs/data-view/core/group-by/group-visibility.js +291 -0
  94. package/dist/_pkgs/data-view/core/group-by/setting.d.ts +11 -3
  95. package/dist/_pkgs/data-view/core/group-by/setting.js +81 -8
  96. package/dist/_pkgs/data-view/core/group-by/trait.d.ts +22 -0
  97. package/dist/_pkgs/data-view/core/group-by/trait.js +62 -1
  98. package/dist/_pkgs/data-view/core/index.d.ts +3 -0
  99. package/dist/_pkgs/data-view/core/index.js +3 -0
  100. package/dist/_pkgs/data-view/core/property/base-cell.d.ts +15 -1
  101. package/dist/_pkgs/data-view/core/property/base-cell.js +28 -3
  102. package/dist/_pkgs/data-view/core/property/standalone-cell.d.ts +15 -1
  103. package/dist/_pkgs/data-view/core/property/standalone-cell.js +19 -1
  104. package/dist/_pkgs/data-view/core/telemetry.d.ts +16 -0
  105. package/dist/_pkgs/data-view/core/telemetry.js +22 -0
  106. package/dist/_pkgs/data-view/core/utils/new-tab-click.d.ts +2 -0
  107. package/dist/_pkgs/data-view/core/utils/new-tab-click.js +4 -0
  108. package/dist/_pkgs/data-view/core/utils/wording.d.ts +11 -0
  109. package/dist/_pkgs/data-view/core/utils/wording.js +9 -0
  110. package/dist/_pkgs/data-view/core/view/data-view.d.ts +7 -0
  111. package/dist/_pkgs/data-view/core/view/default-name.d.ts +10 -0
  112. package/dist/_pkgs/data-view/core/view/default-name.js +14 -0
  113. package/dist/_pkgs/data-view/core/view/index.d.ts +2 -0
  114. package/dist/_pkgs/data-view/core/view/index.js +2 -0
  115. package/dist/_pkgs/data-view/core/view/open-in.d.ts +27 -0
  116. package/dist/_pkgs/data-view/core/view/open-in.js +39 -0
  117. package/dist/_pkgs/data-view/core/view-manager/cell.d.ts +5 -0
  118. package/dist/_pkgs/data-view/core/view-manager/cell.js +11 -0
  119. package/dist/_pkgs/data-view/core/view-manager/index.d.ts +3 -0
  120. package/dist/_pkgs/data-view/core/view-manager/index.js +3 -0
  121. package/dist/_pkgs/data-view/core/view-manager/new-row-menu-opener.d.ts +18 -0
  122. package/dist/_pkgs/data-view/core/view-manager/new-row-menu-opener.js +2 -0
  123. package/dist/_pkgs/data-view/core/view-manager/properties-panel-opener.d.ts +8 -0
  124. package/dist/_pkgs/data-view/core/view-manager/properties-panel-opener.js +9 -0
  125. package/dist/_pkgs/data-view/core/view-manager/property.d.ts +8 -0
  126. package/dist/_pkgs/data-view/core/view-manager/single-view.d.ts +28 -1
  127. package/dist/_pkgs/data-view/core/view-manager/single-view.js +45 -1
  128. package/dist/_pkgs/data-view/core/view-manager/view-creation.d.ts +49 -0
  129. package/dist/_pkgs/data-view/core/view-manager/view-creation.js +40 -0
  130. package/dist/_pkgs/data-view/core/view-manager/view-manager.d.ts +6 -2
  131. package/dist/_pkgs/data-view/core/view-manager/view-manager.js +2 -2
  132. package/dist/_pkgs/data-view/property-presets/date/cell-renderer.d.ts +2 -0
  133. package/dist/_pkgs/data-view/property-presets/date/cell-renderer.js +11 -2
  134. package/dist/_pkgs/data-view/property-presets/multi-select/cell-renderer.js +2 -0
  135. package/dist/_pkgs/data-view/property-presets/select/cell-renderer.js +2 -0
  136. package/dist/_pkgs/data-view/translations.d.ts +55 -0
  137. package/dist/_pkgs/data-view/translations.js +181 -0
  138. package/dist/_pkgs/data-view/view-presets/calendar/define.js +3 -1
  139. package/dist/_pkgs/data-view/view-presets/convert.js +2 -0
  140. package/dist/_pkgs/data-view/view-presets/effect.js +4 -0
  141. package/dist/_pkgs/data-view/view-presets/flat/flat-converts.d.ts +2 -0
  142. package/dist/_pkgs/data-view/view-presets/flat/flat-converts.js +35 -0
  143. package/dist/_pkgs/data-view/view-presets/flat/flat-view-manager.d.ts +79 -0
  144. package/dist/_pkgs/data-view/view-presets/flat/flat-view-manager.js +194 -0
  145. package/dist/_pkgs/data-view/view-presets/flat/flat-view-ui.d.ts +56 -0
  146. package/dist/_pkgs/data-view/view-presets/flat/flat-view-ui.js +266 -0
  147. package/dist/_pkgs/data-view/view-presets/gallery/define.d.ts +14 -0
  148. package/dist/_pkgs/data-view/view-presets/gallery/define.js +15 -0
  149. package/dist/_pkgs/data-view/view-presets/gallery/effect.d.ts +1 -0
  150. package/dist/_pkgs/data-view/view-presets/gallery/effect.js +4 -0
  151. package/dist/_pkgs/data-view/view-presets/gallery/gallery-view.d.ts +27 -0
  152. package/dist/_pkgs/data-view/view-presets/gallery/gallery-view.js +179 -0
  153. package/dist/_pkgs/data-view/view-presets/gallery/index.d.ts +2 -0
  154. package/dist/_pkgs/data-view/view-presets/gallery/index.js +2 -0
  155. package/dist/_pkgs/data-view/view-presets/gallery/renderer.d.ts +1 -0
  156. package/dist/_pkgs/data-view/view-presets/gallery/renderer.js +11 -0
  157. package/dist/_pkgs/data-view/view-presets/index.d.ts +5 -0
  158. package/dist/_pkgs/data-view/view-presets/index.js +7 -0
  159. package/dist/_pkgs/data-view/view-presets/kanban/define.js +3 -1
  160. package/dist/_pkgs/data-view/view-presets/kanban/kanban-view-manager.js +5 -53
  161. package/dist/_pkgs/data-view/view-presets/kanban/mobile/card.js +8 -1
  162. package/dist/_pkgs/data-view/view-presets/kanban/mobile/cell.js +6 -1
  163. package/dist/_pkgs/data-view/view-presets/kanban/mobile/group.d.ts +4 -2
  164. package/dist/_pkgs/data-view/view-presets/kanban/mobile/group.js +52 -6
  165. package/dist/_pkgs/data-view/view-presets/kanban/mobile/kanban-view-ui-logic.js +5 -1
  166. package/dist/_pkgs/data-view/view-presets/kanban/pc/card.js +2 -0
  167. package/dist/_pkgs/data-view/view-presets/kanban/pc/cell.js +4 -0
  168. package/dist/_pkgs/data-view/view-presets/kanban/pc/group.d.ts +4 -2
  169. package/dist/_pkgs/data-view/view-presets/kanban/pc/group.js +51 -6
  170. package/dist/_pkgs/data-view/view-presets/kanban/pc/kanban-view-ui-logic.js +5 -1
  171. package/dist/_pkgs/data-view/view-presets/list/define.d.ts +14 -0
  172. package/dist/_pkgs/data-view/view-presets/list/define.js +15 -0
  173. package/dist/_pkgs/data-view/view-presets/list/effect.d.ts +1 -0
  174. package/dist/_pkgs/data-view/view-presets/list/effect.js +4 -0
  175. package/dist/_pkgs/data-view/view-presets/list/index.d.ts +2 -0
  176. package/dist/_pkgs/data-view/view-presets/list/index.js +2 -0
  177. package/dist/_pkgs/data-view/view-presets/list/list-view.d.ts +24 -0
  178. package/dist/_pkgs/data-view/view-presets/list/list-view.js +194 -0
  179. package/dist/_pkgs/data-view/view-presets/list/renderer.d.ts +1 -0
  180. package/dist/_pkgs/data-view/view-presets/list/renderer.js +11 -0
  181. package/dist/_pkgs/data-view/view-presets/table/collapsed-state.d.ts +3 -14
  182. package/dist/_pkgs/data-view/view-presets/table/collapsed-state.js +6 -30
  183. package/dist/_pkgs/data-view/view-presets/table/consts.d.ts +2 -0
  184. package/dist/_pkgs/data-view/view-presets/table/consts.js +2 -0
  185. package/dist/_pkgs/data-view/view-presets/table/define.js +3 -1
  186. package/dist/_pkgs/data-view/view-presets/table/mobile/cell.js +4 -1
  187. package/dist/_pkgs/data-view/view-presets/table/mobile/column-header.js +2 -2
  188. package/dist/_pkgs/data-view/view-presets/table/mobile/group.d.ts +3 -1
  189. package/dist/_pkgs/data-view/view-presets/table/mobile/group.js +20 -5
  190. package/dist/_pkgs/data-view/view-presets/table/mobile/row.js +10 -2
  191. package/dist/_pkgs/data-view/view-presets/table/mobile/table-view-ui-logic.js +4 -1
  192. package/dist/_pkgs/data-view/view-presets/table/pc/cell.js +4 -1
  193. package/dist/_pkgs/data-view/view-presets/table/pc/controller/hotkeys.js +1 -1
  194. package/dist/_pkgs/data-view/view-presets/table/pc/group.d.ts +3 -1
  195. package/dist/_pkgs/data-view/view-presets/table/pc/group.js +20 -5
  196. package/dist/_pkgs/data-view/view-presets/table/pc/menu.d.ts +1 -1
  197. package/dist/_pkgs/data-view/view-presets/table/pc/menu.js +2 -1
  198. package/dist/_pkgs/data-view/view-presets/table/pc/row/row.js +3 -2
  199. package/dist/_pkgs/data-view/view-presets/table/pc/table-view-ui-logic.js +4 -1
  200. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/controller/hotkeys.js +1 -1
  201. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/group/bottom/stats/column-stats-column.js +5 -1
  202. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/group/top/group-title.js +22 -19
  203. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/row/cell.js +4 -1
  204. package/dist/_pkgs/data-view/view-presets/table/pc-virtual/table-view-ui-logic.js +7 -2
  205. package/dist/_pkgs/data-view/view-presets/table/stats/column-stats-column.js +5 -1
  206. package/dist/_pkgs/data-view/view-presets/table/table-view-manager.js +5 -53
  207. package/dist/_pkgs/data-view/widget-presets/tools/presets/table-add-row/add-row.d.ts +1 -0
  208. package/dist/_pkgs/data-view/widget-presets/tools/presets/table-add-row/add-row.js +60 -2
  209. package/dist/_pkgs/data-view/widget-presets/tools/presets/view-options/view-options.d.ts +18 -1
  210. package/dist/_pkgs/data-view/widget-presets/tools/presets/view-options/view-options.js +121 -124
  211. package/dist/_pkgs/data-view/widget-presets/tools/presets/view-options/view-settings.d.ts +43 -0
  212. package/dist/_pkgs/data-view/widget-presets/tools/presets/view-options/view-settings.js +187 -0
  213. package/dist/_pkgs/data-view/widget-presets/views-bar/views-view.d.ts +36 -3
  214. package/dist/_pkgs/data-view/widget-presets/views-bar/views-view.js +187 -59
  215. package/dist/extensions/view.d.ts +2 -2
  216. package/dist/extensions/view.js +10 -3
  217. package/dist/flags.d.ts +8 -4
  218. package/dist/flags.js +8 -4
  219. package/dist/frameworks.d.ts +27 -0
  220. package/dist/frameworks.js +28 -0
  221. package/dist/translations.js +13 -1
  222. package/package.json +5 -1
@@ -9,32 +9,71 @@ import { DatabaseConfigExtension } from './config.js';
9
9
  import { databaseSlashMenuConfig } from './configs/slash-menu.js';
10
10
  import { effects } from './effects.js';
11
11
  import { linkColumnConfig } from './properties/link/cell-renderer.js';
12
+ import { DatabaseViewCreationExtension } from './view-creation.js';
12
13
  const optionsSchema = z.object({
13
14
  configure: z
14
15
  .function()
15
16
  .args(z.instanceof(DatabaseBlockModel), z.custom())
16
17
  .returns(z.custom()),
17
18
  });
18
- export class DatabaseViewExtension extends ViewExtensionProvider {
19
+ /**
20
+ * Database rendering — ALWAYS registered, independent of the `database` and
21
+ * `data-view` flags (ADR 0009, ADR 0035 §5, issue B4). A document that holds a
22
+ * database must show it, let its cells be edited and its rows be opened
23
+ * whatever the flags say: until 0.48 the whole view sat behind `database`, and
24
+ * `{ database: false }` left every stored database rendered as nothing.
25
+ *
26
+ * What lives here is what an EXISTING database needs, the mirror of
27
+ * `CalloutRenderViewExtension`:
28
+ * - `effects()` whole: every element it defines draws a stored database (the
29
+ * block, its title, the cells, the row detail and its peek);
30
+ * - the flavour and the block view, the lookup `lit-host` performs; the block
31
+ * brings the presets, the cells and the row opening with it;
32
+ * - the link cell for the title band (ADR 0035 §11): a `link` value already
33
+ * stored on a page is drawn with it.
34
+ */
35
+ export class DatabaseRenderViewExtension extends ViewExtensionProvider {
19
36
  constructor() {
20
37
  super(...arguments);
21
- this.name = 'affine-database-block';
22
- this.schema = optionsSchema;
38
+ this.name = 'affine-database-render-block';
23
39
  }
24
40
  effect() {
25
41
  super.effect();
26
42
  effects();
27
43
  }
28
- setup(context, options) {
44
+ setup(context) {
29
45
  super.setup(context);
30
46
  context.register([
31
47
  FlavourExtension('affine:database'),
32
48
  BlockViewExtension('affine:database', literal `affine-database`),
33
- SlashMenuConfigExtension('affine:database', databaseSlashMenuConfig),
34
49
  // The title band draws a `link` / `url` property with the table's link
35
50
  // cell; it sits below this package and cannot import it (ADR 0035 §11).
36
51
  StandaloneCellMetaExtension(linkColumnConfig),
37
52
  ]);
53
+ }
54
+ }
55
+ /**
56
+ * Database creation tooling — flag-gated (`database`, ADR 0009, ADR 0035 §5):
57
+ * the slash-menu entries that insert a database, the "+ view" of a rendered
58
+ * one (`DatabaseViewCreationIdentifier`, `./view-creation.ts`), and the host's additions to
59
+ * the block's "⋯" menu (`configure`, kept on this class so a host's
60
+ * `viewManager.configure(DatabaseViewExtension, …)` still compiles and its
61
+ * entries follow the flag). With the flag off no database and no view can be
62
+ * made; the stored ones keep rendering through
63
+ * {@link DatabaseRenderViewExtension}.
64
+ */
65
+ export class DatabaseViewExtension extends ViewExtensionProvider {
66
+ constructor() {
67
+ super(...arguments);
68
+ this.name = 'affine-database-block';
69
+ this.schema = optionsSchema;
70
+ }
71
+ setup(context, options) {
72
+ super.setup(context);
73
+ context.register([
74
+ SlashMenuConfigExtension('affine:database', databaseSlashMenuConfig),
75
+ DatabaseViewCreationExtension,
76
+ ]);
38
77
  if (options) {
39
78
  context.register(DatabaseConfigExtension({ configure: options.configure }));
40
79
  }
@@ -1,6 +1,33 @@
1
1
  import type { ViewMeta } from '../../data-view/index.js';
2
+ /**
3
+ * Every preset a stored `affine:database` view can be drawn with (ADR 0035
4
+ * §6). Calendar stays here: calendar views were creatable until 0.48, so
5
+ * documents hold them, and a stored calendar keeps rendering and editing as a
6
+ * calendar. Never shrink this list: a mode that leaves it falls back to a
7
+ * table on every document that stores it.
8
+ */
9
+ export declare const databaseBlockRenderableViews: ViewMeta[];
10
+ /**
11
+ * The presets a user can CREATE, a subset of the renderable ones: what the
12
+ * data source answers as `viewMetas`, so the views bar ("+", "Create …") and
13
+ * the Layout switch list only these. Calendar left it after 0.48 (ADR 0035 §6,
14
+ * labre ADR-0046 §8): no new calendar, the stored ones still render.
15
+ */
2
16
  export declare const databaseBlockViews: ViewMeta[];
3
- export declare const databaseBlockViewMap: {
4
- [k: string]: ViewMeta;
5
- };
17
+ /** The preset a mode with none of its own is drawn with. */
18
+ export declare const databaseBlockFallbackView: ViewMeta;
19
+ export declare const databaseBlockViewMap: Record<string, ViewMeta | undefined>;
20
+ /**
21
+ * The preset that draws a stored `mode`. Never throws: a mode this client has
22
+ * no preset for (a `timeline`, a newer client's view, an import) is drawn as a
23
+ * table over the source's properties, and its stored data stays as it is
24
+ * (`SingleView.shownAsFallback$`). Up to 0.48 it threw `Unknown view type`
25
+ * and the whole database rendered nothing.
26
+ */
27
+ export declare function databaseBlockViewMetaGet(mode: string): ViewMeta;
28
+ /**
29
+ * Conversions INTO a creatable preset only: switching a view's layout to
30
+ * calendar would create a calendar. The conversions out of calendar stay, so a
31
+ * stored calendar can still become a table or a board.
32
+ */
6
33
  export declare const databaseBlockViewConverts: import("../index.js").ViewConvertConfig[];
@@ -1,8 +1,49 @@
1
1
  import { viewConverts, viewPresets } from '../../data-view/view-presets/index.js';
2
- export const databaseBlockViews = [
2
+ /**
3
+ * Every preset a stored `affine:database` view can be drawn with (ADR 0035
4
+ * §6). Calendar stays here: calendar views were creatable until 0.48, so
5
+ * documents hold them, and a stored calendar keeps rendering and editing as a
6
+ * calendar. Never shrink this list: a mode that leaves it falls back to a
7
+ * table on every document that stores it.
8
+ */
9
+ export const databaseBlockRenderableViews = [
3
10
  viewPresets.tableViewMeta,
4
11
  viewPresets.kanbanViewMeta,
5
12
  viewPresets.calendarViewMeta,
13
+ viewPresets.galleryViewMeta,
14
+ viewPresets.listViewMeta,
15
+ ];
16
+ /**
17
+ * The presets a user can CREATE, a subset of the renderable ones: what the
18
+ * data source answers as `viewMetas`, so the views bar ("+", "Create …") and
19
+ * the Layout switch list only these. Calendar left it after 0.48 (ADR 0035 §6,
20
+ * labre ADR-0046 §8): no new calendar, the stored ones still render.
21
+ */
22
+ export const databaseBlockViews = [
23
+ viewPresets.tableViewMeta,
24
+ viewPresets.kanbanViewMeta,
25
+ viewPresets.galleryViewMeta,
26
+ viewPresets.listViewMeta,
6
27
  ];
7
- export const databaseBlockViewMap = Object.fromEntries(databaseBlockViews.map(view => [view.type, view]));
8
- export const databaseBlockViewConverts = [...viewConverts];
28
+ /** The preset a mode with none of its own is drawn with. */
29
+ export const databaseBlockFallbackView = viewPresets.tableViewMeta;
30
+ // No prototype: a stored mode is any string, and `'constructor'` or
31
+ // `'__proto__'` must find no preset rather than Object's own members.
32
+ export const databaseBlockViewMap = Object.assign(Object.create(null), Object.fromEntries(databaseBlockRenderableViews.map(v => [v.type, v])));
33
+ /**
34
+ * The preset that draws a stored `mode`. Never throws: a mode this client has
35
+ * no preset for (a `timeline`, a newer client's view, an import) is drawn as a
36
+ * table over the source's properties, and its stored data stays as it is
37
+ * (`SingleView.shownAsFallback$`). Up to 0.48 it threw `Unknown view type`
38
+ * and the whole database rendered nothing.
39
+ */
40
+ export function databaseBlockViewMetaGet(mode) {
41
+ return databaseBlockViewMap[mode] ?? databaseBlockFallbackView;
42
+ }
43
+ const creatableModes = new Set(databaseBlockViews.map(view => view.type));
44
+ /**
45
+ * Conversions INTO a creatable preset only: switching a view's layout to
46
+ * calendar would create a calendar. The conversions out of calendar stay, so a
47
+ * stored calendar can still become a table or a board.
48
+ */
49
+ export const databaseBlockViewConverts = viewConverts.filter(convert => creatableModes.has(convert.to));
@@ -1,4 +1,13 @@
1
+ import type { ChromeWording } from '../../affine-shared/services/index.js';
1
2
  import { LitElement, type PropertyValues, type TemplateResult } from 'lit';
3
+ /**
4
+ * The week header, Sunday first, in two letters: `Intl` short weekdays cut to
5
+ * two (`Su Mo…` in `en-US`, `Di Lu…` in `fr`), so the default reads as it
6
+ * did before the names came from `Intl`.
7
+ */
8
+ export declare function weekdayLabels(locale: string): string[];
9
+ /** The month names of the header and the month grid (`Jan…` in `en-US`). */
10
+ export declare function monthLabels(locale: string): string[];
2
11
  export interface DateCell {
3
12
  date: Date;
4
13
  label: string;
@@ -95,6 +104,17 @@ export declare class DatePicker extends DatePicker_base {
95
104
  accessor size: number;
96
105
  /** Checked date timestamp */
97
106
  accessor value: number | undefined;
107
+ /**
108
+ * The BCP-47 locale of the day and month names (`formatLocale(std)` at the
109
+ * caller). `en-US` by default, which reads as the picker always did.
110
+ */
111
+ accessor locale: string;
112
+ /**
113
+ * Resolves the picker's own wordings: it renders in a popup, outside the
114
+ * editor, so its caller holds the catalogue. Absent, English.
115
+ */
116
+ accessor wording: ((wording: ChromeWording) => string) | undefined;
117
+ private say;
98
118
  }
99
119
  declare global {
100
120
  interface HTMLElementTagNameMap {
@@ -39,24 +39,29 @@ import { html, LitElement, nothing, } from 'lit';
39
39
  import { property } from 'lit/decorators.js';
40
40
  import { classMap } from 'lit/directives/class-map.js';
41
41
  import { styleMap } from 'lit/directives/style-map.js';
42
+ import { DATE_PICKER_CLEAR, DATE_PICKER_NEXT, DATE_PICKER_PREVIOUS, DATE_PICKER_TODAY, } from '../translations.js';
42
43
  import { arrowLeftIcon } from './icons.js';
43
44
  import { datePickerStyle } from './style.js';
44
45
  import { getMonthMatrix, toDate } from './utils.js';
45
- const days = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
46
- const months = [
47
- 'Jan',
48
- 'Feb',
49
- 'Mar',
50
- 'Apr',
51
- 'May',
52
- 'Jun',
53
- 'Jul',
54
- 'Aug',
55
- 'Sep',
56
- 'Oct',
57
- 'Nov',
58
- 'Dec',
59
- ];
46
+ /**
47
+ * The week header, Sunday first, in two letters: `Intl` short weekdays cut to
48
+ * two (`Su Mo…` in `en-US`, `Di Lu…` in `fr`), so the default reads as it
49
+ * did before the names came from `Intl`.
50
+ */
51
+ export function weekdayLabels(locale) {
52
+ const format = new Intl.DateTimeFormat(locale, { weekday: 'short' });
53
+ // 2023-01-01 is a Sunday.
54
+ return Array.from({ length: 7 }, (_, i) => {
55
+ const name = format.format(new Date(2023, 0, 1 + i)).slice(0, 2);
56
+ return name.charAt(0).toLocaleUpperCase(locale) + name.slice(1);
57
+ });
58
+ }
59
+ /** The month names of the header and the month grid (`Jan…` in `en-US`). */
60
+ export function monthLabels(locale) {
61
+ const format = new Intl.DateTimeFormat(locale, { month: 'short' });
62
+ return Array.from({ length: 12 }, (_, i) => format.format(new Date(2023, i, 1)));
63
+ }
64
+ const englishWording = (wording) => wording[1];
60
65
  /**
61
66
  * Date picker
62
67
  */
@@ -107,6 +112,12 @@ let DatePicker = (() => {
107
112
  let _value_decorators;
108
113
  let _value_initializers = [];
109
114
  let _value_extraInitializers = [];
115
+ let _locale_decorators;
116
+ let _locale_initializers = [];
117
+ let _locale_extraInitializers = [];
118
+ let _wording_decorators;
119
+ let _wording_initializers = [];
120
+ let _wording_extraInitializers = [];
110
121
  return class DatePicker extends _classSuper {
111
122
  static {
112
123
  const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
@@ -125,6 +136,8 @@ let DatePicker = (() => {
125
136
  _popup_decorators = [property({ type: Boolean })];
126
137
  _size_decorators = [property({ type: Number })];
127
138
  _value_decorators = [property({ type: Number })];
139
+ _locale_decorators = [property({ attribute: false })];
140
+ _wording_decorators = [property({ attribute: false })];
128
141
  __esDecorate(this, null, __matrix_decorators, { kind: "accessor", name: "_matrix", static: false, private: false, access: { has: obj => "_matrix" in obj, get: obj => obj._matrix, set: (obj, value) => { obj._matrix = value; } }, metadata: _metadata }, __matrix_initializers, __matrix_extraInitializers);
129
142
  __esDecorate(this, null, __mode_decorators, { kind: "accessor", name: "_mode", static: false, private: false, access: { has: obj => "_mode" in obj, get: obj => obj._mode, set: (obj, value) => { obj._mode = value; } }, metadata: _metadata }, __mode_initializers, __mode_extraInitializers);
130
143
  __esDecorate(this, null, __monthCursor_decorators, { kind: "accessor", name: "_monthCursor", static: false, private: false, access: { has: obj => "_monthCursor" in obj, get: obj => obj._monthCursor, set: (obj, value) => { obj._monthCursor = value; } }, metadata: _metadata }, __monthCursor_initializers, __monthCursor_extraInitializers);
@@ -140,6 +153,8 @@ let DatePicker = (() => {
140
153
  __esDecorate(this, null, _popup_decorators, { kind: "accessor", name: "popup", static: false, private: false, access: { has: obj => "popup" in obj, get: obj => obj.popup, set: (obj, value) => { obj.popup = value; } }, metadata: _metadata }, _popup_initializers, _popup_extraInitializers);
141
154
  __esDecorate(this, null, _size_decorators, { kind: "accessor", name: "size", static: false, private: false, access: { has: obj => "size" in obj, get: obj => obj.size, set: (obj, value) => { obj.size = value; } }, metadata: _metadata }, _size_initializers, _size_extraInitializers);
142
155
  __esDecorate(this, null, _value_decorators, { kind: "accessor", name: "value", static: false, private: false, access: { has: obj => "value" in obj, get: obj => obj.value, set: (obj, value) => { obj.value = value; } }, metadata: _metadata }, _value_initializers, _value_extraInitializers);
156
+ __esDecorate(this, null, _locale_decorators, { kind: "accessor", name: "locale", static: false, private: false, access: { has: obj => "locale" in obj, get: obj => obj.locale, set: (obj, value) => { obj.locale = value; } }, metadata: _metadata }, _locale_initializers, _locale_extraInitializers);
157
+ __esDecorate(this, null, _wording_decorators, { kind: "accessor", name: "wording", static: false, private: false, access: { has: obj => "wording" in obj, get: obj => obj.wording, set: (obj, value) => { obj.wording = value; } }, metadata: _metadata }, _wording_initializers, _wording_extraInitializers);
143
158
  if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
144
159
  }
145
160
  static { this.styles = datePickerStyle; }
@@ -168,7 +183,7 @@ let DatePicker = (() => {
168
183
  return this._cursor.getDay();
169
184
  }
170
185
  get dayLabel() {
171
- return days[this.day];
186
+ return weekdayLabels(this.locale)[this.day];
172
187
  }
173
188
  get minHeight() {
174
189
  const rowNum = this._matrix.length;
@@ -178,7 +193,7 @@ let DatePicker = (() => {
178
193
  return this._cursor.getMonth();
179
194
  }
180
195
  get monthLabel() {
181
- return months[this.month];
196
+ return monthLabels(this.locale)[this.month];
182
197
  }
183
198
  get year() {
184
199
  return this._cursor.getFullYear();
@@ -228,13 +243,13 @@ let DatePicker = (() => {
228
243
 
229
244
  ${this._navAction(() => this._moveMonth(-1), () => this._moveMonth(1), html `<button
230
245
  tabindex="0"
231
- aria-label="today"
246
+ aria-label=${this.say(DATE_PICKER_TODAY)}
232
247
  class="action-label interactive today"
233
248
  @click=${() => {
234
249
  this._onChange(new Date());
235
250
  }}
236
251
  >
237
- <span>TODAY</span>
252
+ <span>${this.say(DATE_PICKER_TODAY)}</span>
238
253
  </button>`)}
239
254
  </div>
240
255
  ${this._dayHeaderRenderer()}
@@ -247,11 +262,11 @@ let DatePicker = (() => {
247
262
  ? html `<div class="date-picker-footer">
248
263
  <button
249
264
  tabindex="0"
250
- aria-label="clear"
265
+ aria-label=${this.say(DATE_PICKER_CLEAR)}
251
266
  class="footer-button interactive"
252
267
  @click=${() => this.onClear?.()}
253
268
  >
254
- Clear
269
+ ${this.say(DATE_PICKER_CLEAR)}
255
270
  </button>
256
271
  </div>`
257
272
  : nothing}`;
@@ -259,7 +274,7 @@ let DatePicker = (() => {
259
274
  /** Week header */
260
275
  _dayHeaderRenderer() {
261
276
  return html `<div class="days-header">
262
- ${days.map(day => html `<div class="date-cell">${day}</div>`)}
277
+ ${weekdayLabels(this.locale).map(day => html `<div class="date-cell">${day}</div>`)}
263
278
  </div>`;
264
279
  }
265
280
  _getMatrix() {
@@ -307,7 +322,7 @@ let DatePicker = (() => {
307
322
  })}
308
323
  </div>
309
324
  <div class="date-picker-month">
310
- ${months.map((month, index) => {
325
+ ${monthLabels(this.locale).map((month, index) => {
311
326
  const isActive = this.value
312
327
  ? isSameMonth(this.value, new Date(this._monthPickYearCursor, index, 1))
313
328
  : false;
@@ -348,7 +363,7 @@ let DatePicker = (() => {
348
363
  });
349
364
  return html `<div class=${classes}>
350
365
  <button
351
- aria-label="previous month"
366
+ aria-label=${this.say(DATE_PICKER_PREVIOUS)}
352
367
  class="date-picker-small-action interactive left"
353
368
  @click=${onPrev}
354
369
  ?disabled=${prevDisable}
@@ -357,7 +372,7 @@ let DatePicker = (() => {
357
372
  </button>
358
373
  ${slot ?? nothing}
359
374
  <button
360
- aria-label="next month"
375
+ aria-label=${this.say(DATE_PICKER_NEXT)}
361
376
  class="date-picker-small-action interactive right"
362
377
  @click=${onNext}
363
378
  ?disabled=${nextDisable}
@@ -636,6 +651,23 @@ let DatePicker = (() => {
636
651
  /** Checked date timestamp */
637
652
  get value() { return this.#value_accessor_storage; }
638
653
  set value(value) { this.#value_accessor_storage = value; }
654
+ #locale_accessor_storage;
655
+ /**
656
+ * The BCP-47 locale of the day and month names (`formatLocale(std)` at the
657
+ * caller). `en-US` by default, which reads as the picker always did.
658
+ */
659
+ get locale() { return this.#locale_accessor_storage; }
660
+ set locale(value) { this.#locale_accessor_storage = value; }
661
+ #wording_accessor_storage;
662
+ /**
663
+ * Resolves the picker's own wordings: it renders in a popup, outside the
664
+ * editor, so its caller holds the catalogue. Absent, English.
665
+ */
666
+ get wording() { return this.#wording_accessor_storage; }
667
+ set wording(value) { this.#wording_accessor_storage = value; }
668
+ say(wording) {
669
+ return (this.wording ?? englishWording)(wording);
670
+ }
639
671
  constructor() {
640
672
  super(...arguments);
641
673
  /** current active month */
@@ -657,7 +689,9 @@ let DatePicker = (() => {
657
689
  this.#popup_accessor_storage = (__runInitializers(this, _padding_extraInitializers), __runInitializers(this, _popup_initializers, false));
658
690
  this.#size_accessor_storage = (__runInitializers(this, _popup_extraInitializers), __runInitializers(this, _size_initializers, 28));
659
691
  this.#value_accessor_storage = (__runInitializers(this, _size_extraInitializers), __runInitializers(this, _value_initializers, undefined));
660
- __runInitializers(this, _value_extraInitializers);
692
+ this.#locale_accessor_storage = (__runInitializers(this, _value_extraInitializers), __runInitializers(this, _locale_initializers, 'en-US'));
693
+ this.#wording_accessor_storage = (__runInitializers(this, _locale_extraInitializers), __runInitializers(this, _wording_initializers, undefined));
694
+ __runInitializers(this, _wording_extraInitializers);
661
695
  }
662
696
  };
663
697
  })();
@@ -32,6 +32,7 @@ export const datePickerStyle = css `
32
32
  .interactive.date-picker-small-action,
33
33
  .interactive.action-label.today {
34
34
  color: var(--affine-icon-color);
35
+ text-transform: uppercase;
35
36
  }
36
37
 
37
38
  .date-picker-small-action:hover {
@@ -35,6 +35,10 @@ export { COLOR_LABEL, FILL_COLOR_LABEL };
35
35
  export declare const BORDER_COLOR_LABEL: ChromeWording;
36
36
  export declare const CONTEXT_MENU_NO_RESULTS: ChromeWording;
37
37
  export declare const CONTEXT_MENU_DONE: ChromeWording;
38
+ export declare const DATE_PICKER_TODAY: ChromeWording;
39
+ export declare const DATE_PICKER_CLEAR: ChromeWording;
40
+ export declare const DATE_PICKER_PREVIOUS: ChromeWording;
41
+ export declare const DATE_PICKER_NEXT: ChromeWording;
38
42
  export declare const LINE_STYLE_SOLID: ChromeWording;
39
43
  export declare const LINE_STYLE_DASH: ChromeWording;
40
44
  export declare const LINE_STYLE_NONE: ChromeWording;
@@ -81,6 +81,28 @@ export const CONTEXT_MENU_DONE = [
81
81
  'com.labre.context-menu.done',
82
82
  'Done',
83
83
  ];
84
+ /* ── Date picker (database date cells, the chips band, date filters) ─── */
85
+ /*
86
+ * Its caller resolves them (the picker renders in a popup, outside the
87
+ * editor) and passes `wording`. Day and month names are not keys: they come
88
+ * from `Intl` in the caller's `locale` (`formatLocale(std)`).
89
+ */
90
+ export const DATE_PICKER_TODAY = [
91
+ 'com.labre.date-picker.today',
92
+ 'Today',
93
+ ];
94
+ export const DATE_PICKER_CLEAR = [
95
+ 'com.labre.date-picker.clear',
96
+ 'Clear',
97
+ ];
98
+ export const DATE_PICKER_PREVIOUS = [
99
+ 'com.labre.date-picker.previous-month',
100
+ 'Previous month',
101
+ ];
102
+ export const DATE_PICKER_NEXT = [
103
+ 'com.labre.date-picker.next-month',
104
+ 'Next month',
105
+ ];
84
106
  /* ── Edgeless line style / width panels ─────────────────────────────── */
85
107
  export const LINE_STYLE_SOLID = [
86
108
  'com.labre.line-style.solid',
@@ -415,6 +437,10 @@ export { ICON_BUTTON_COMING_SOON };
415
437
  * restated there.
416
438
  */
417
439
  export const COMPONENTS_WORDINGS = [
440
+ DATE_PICKER_TODAY,
441
+ DATE_PICKER_CLEAR,
442
+ DATE_PICKER_PREVIOUS,
443
+ DATE_PICKER_NEXT,
418
444
  CAPTION_PLACEHOLDER,
419
445
  CARD_STYLE_LABEL,
420
446
  FAVICON_ALT,
@@ -4,6 +4,14 @@ declare const DocTitle_base: typeof ShadowlessElement & import("../global/utils/
4
4
  export declare class DocTitle extends DocTitle_base {
5
5
  static styles: import("lit").CSSResult;
6
6
  private _getOrCreateFirstPageVisibleNote;
7
+ /**
8
+ * Leaves the title for `bodyBlockId`: the title loses the caret (its text
9
+ * is already stored, so that is all "validating" it means), then the block
10
+ * takes the caret where it can, through its `focusFirstCell` (a database
11
+ * block's: the first cell of a table or kanban view). A block without one,
12
+ * or a view without cells, keeps nothing focused. Writes nothing.
13
+ */
14
+ private _leaveForBodyBlock;
7
15
  private readonly _onTitleKeyDown;
8
16
  private readonly _updateTitleInMeta;
9
17
  private get _std();
@@ -27,5 +35,15 @@ export declare class DocTitle extends DocTitle_base {
27
35
  private accessor _richTextElement;
28
36
  accessor doc: Store;
29
37
  accessor wrapText: boolean;
38
+ /**
39
+ * The block that is the page's body, when the document's note is not (a
40
+ * database's full page, ADR 0035 B13: the document holds the database
41
+ * block and its schema blocks in a note the page never draws). Set, the
42
+ * title has no body of its own: Enter and ArrowDown leave the title for
43
+ * this block and never add or focus a paragraph, so nothing is ever
44
+ * written to the note. Unset (the default), Enter splits the title into a
45
+ * first paragraph and ArrowDown focuses or creates one, as in 0.48.
46
+ */
47
+ accessor bodyBlockId: string | undefined;
30
48
  }
31
49
  export {};
@@ -37,7 +37,7 @@ import { focusTextModel } from '../affine-rich-text/index.js';
37
37
  import { TitleBandProvider, translateKey } from '../affine-shared/services/index.js';
38
38
  import { matchModels } from '../affine-shared/utils/index.js';
39
39
  import { WithDisposable } from '../global/lit/index.js';
40
- import { ShadowlessElement } from '../std/index.js';
40
+ import { ShadowlessElement, } from '../std/index.js';
41
41
  import { effect } from '@preact/signals-core';
42
42
  import { css, html, nothing } from 'lit';
43
43
  import { property, query, state } from 'lit/decorators.js';
@@ -60,6 +60,9 @@ let DocTitle = (() => {
60
60
  let _wrapText_decorators;
61
61
  let _wrapText_initializers = [];
62
62
  let _wrapText_extraInitializers = [];
63
+ let _bodyBlockId_decorators;
64
+ let _bodyBlockId_initializers = [];
65
+ let _bodyBlockId_extraInitializers = [];
63
66
  return class DocTitle extends _classSuper {
64
67
  static {
65
68
  const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
@@ -68,11 +71,13 @@ let DocTitle = (() => {
68
71
  __richTextElement_decorators = [query('rich-text')];
69
72
  _doc_decorators = [property({ attribute: false })];
70
73
  _wrapText_decorators = [property({ attribute: false })];
74
+ _bodyBlockId_decorators = [property({ attribute: false })];
71
75
  __esDecorate(this, null, __isComposing_decorators, { kind: "accessor", name: "_isComposing", static: false, private: false, access: { has: obj => "_isComposing" in obj, get: obj => obj._isComposing, set: (obj, value) => { obj._isComposing = value; } }, metadata: _metadata }, __isComposing_initializers, __isComposing_extraInitializers);
72
76
  __esDecorate(this, null, __isReadonly_decorators, { kind: "accessor", name: "_isReadonly", static: false, private: false, access: { has: obj => "_isReadonly" in obj, get: obj => obj._isReadonly, set: (obj, value) => { obj._isReadonly = value; } }, metadata: _metadata }, __isReadonly_initializers, __isReadonly_extraInitializers);
73
77
  __esDecorate(this, null, __richTextElement_decorators, { kind: "accessor", name: "_richTextElement", static: false, private: false, access: { has: obj => "_richTextElement" in obj, get: obj => obj._richTextElement, set: (obj, value) => { obj._richTextElement = value; } }, metadata: _metadata }, __richTextElement_initializers, __richTextElement_extraInitializers);
74
78
  __esDecorate(this, null, _doc_decorators, { kind: "accessor", name: "doc", static: false, private: false, access: { has: obj => "doc" in obj, get: obj => obj.doc, set: (obj, value) => { obj.doc = value; } }, metadata: _metadata }, _doc_initializers, _doc_extraInitializers);
75
79
  __esDecorate(this, null, _wrapText_decorators, { kind: "accessor", name: "wrapText", static: false, private: false, access: { has: obj => "wrapText" in obj, get: obj => obj.wrapText, set: (obj, value) => { obj.wrapText = value; } }, metadata: _metadata }, _wrapText_initializers, _wrapText_extraInitializers);
80
+ __esDecorate(this, null, _bodyBlockId_decorators, { kind: "accessor", name: "bodyBlockId", static: false, private: false, access: { has: obj => "bodyBlockId" in obj, get: obj => obj.bodyBlockId, set: (obj, value) => { obj.bodyBlockId = value; } }, metadata: _metadata }, _bodyBlockId_initializers, _bodyBlockId_extraInitializers);
76
81
  if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
77
82
  }
78
83
  static { this.styles = css `
@@ -162,6 +167,19 @@ let DocTitle = (() => {
162
167
  const noteId = this.doc.addBlock('affine:note', {}, this._rootModel, 0);
163
168
  return this.doc.getBlock(noteId)?.model;
164
169
  }
170
+ /**
171
+ * Leaves the title for `bodyBlockId`: the title loses the caret (its text
172
+ * is already stored, so that is all "validating" it means), then the block
173
+ * takes the caret where it can, through its `focusFirstCell` (a database
174
+ * block's: the first cell of a table or kanban view). A block without one,
175
+ * or a view without cells, keeps nothing focused. Writes nothing.
176
+ */
177
+ _leaveForBodyBlock(std, blockId) {
178
+ this.inlineEditor?.setInlineRange(null);
179
+ this.inlineEditor?.rootElement?.blur();
180
+ const block = std.view.getBlock(blockId);
181
+ block?.focusFirstCell?.();
182
+ }
165
183
  get _std() {
166
184
  return this._viewport?.querySelector('editor-host')?.std;
167
185
  }
@@ -275,6 +293,18 @@ let DocTitle = (() => {
275
293
  #wrapText_accessor_storage;
276
294
  get wrapText() { return this.#wrapText_accessor_storage; }
277
295
  set wrapText(value) { this.#wrapText_accessor_storage = value; }
296
+ #bodyBlockId_accessor_storage;
297
+ /**
298
+ * The block that is the page's body, when the document's note is not (a
299
+ * database's full page, ADR 0035 B13: the document holds the database
300
+ * block and its schema blocks in a note the page never draws). Set, the
301
+ * title has no body of its own: Enter and ArrowDown leave the title for
302
+ * this block and never add or focus a paragraph, so nothing is ever
303
+ * written to the note. Unset (the default), Enter splits the title into a
304
+ * first paragraph and ArrowDown focuses or creates one, as in 0.48.
305
+ */
306
+ get bodyBlockId() { return this.#bodyBlockId_accessor_storage; }
307
+ set bodyBlockId(value) { this.#bodyBlockId_accessor_storage = value; }
278
308
  constructor() {
279
309
  super(...arguments);
280
310
  this._onTitleKeyDown = (event) => {
@@ -282,6 +312,14 @@ let DocTitle = (() => {
282
312
  return;
283
313
  if (!this._std)
284
314
  return;
315
+ if (this.bodyBlockId !== undefined &&
316
+ (event.key === 'Enter' || event.key === 'ArrowDown')) {
317
+ this._std.event.active = true;
318
+ event.preventDefault();
319
+ event.stopPropagation();
320
+ this._leaveForBodyBlock(this._std, this.bodyBlockId);
321
+ return;
322
+ }
285
323
  if (event.key === 'Enter') {
286
324
  this._std.event.active = true;
287
325
  event.preventDefault();
@@ -331,7 +369,8 @@ let DocTitle = (() => {
331
369
  this.#_richTextElement_accessor_storage = (__runInitializers(this, __isReadonly_extraInitializers), __runInitializers(this, __richTextElement_initializers, void 0));
332
370
  this.#doc_accessor_storage = (__runInitializers(this, __richTextElement_extraInitializers), __runInitializers(this, _doc_initializers, void 0));
333
371
  this.#wrapText_accessor_storage = (__runInitializers(this, _doc_extraInitializers), __runInitializers(this, _wrapText_initializers, true));
334
- __runInitializers(this, _wrapText_extraInitializers);
372
+ this.#bodyBlockId_accessor_storage = (__runInitializers(this, _wrapText_extraInitializers), __runInitializers(this, _bodyBlockId_initializers, undefined));
373
+ __runInitializers(this, _bodyBlockId_extraInitializers);
335
374
  }
336
375
  };
337
376
  })();
@@ -20,3 +20,11 @@ export declare function bandCellData(cellType: string, property: TitleBandProper
20
20
  export declare function bandWriteValue(value: unknown): unknown;
21
21
  /** Whether a committed value is the one the chip already shows. */
22
22
  export declare function sameBandValue(cellType: string, current: unknown, next: unknown): boolean;
23
+ /**
24
+ * Whether a chip's tag menu creates and renames options (product owner,
25
+ * 2026-10-14): a select or multi-select whose host takes a definition write
26
+ * (`setData`) and says so for this property (`dataWritable: true`). Anything
27
+ * else keeps its options fixed, the 0.48 band. A read-only chip opens no
28
+ * editor whatever this says.
29
+ */
30
+ export declare function bandOptionsWritable(cellType: string, property: TitleBandProperty, hasSetData: boolean): boolean;
@@ -123,3 +123,15 @@ export function sameBandValue(cellType, current, next) {
123
123
  }
124
124
  return a === b;
125
125
  }
126
+ /**
127
+ * Whether a chip's tag menu creates and renames options (product owner,
128
+ * 2026-10-14): a select or multi-select whose host takes a definition write
129
+ * (`setData`) and says so for this property (`dataWritable: true`). Anything
130
+ * else keeps its options fixed, the 0.48 band. A read-only chip opens no
131
+ * editor whatever this says.
132
+ */
133
+ export function bandOptionsWritable(cellType, property, hasSetData) {
134
+ return (hasSetData &&
135
+ property.dataWritable === true &&
136
+ (cellType === 'select' || cellType === 'multi-select'));
137
+ }
@@ -45,6 +45,11 @@ export declare class TitleBand extends TitleBand_base {
45
45
  private _isCollapsed;
46
46
  private _setCollapsed;
47
47
  private _write;
48
+ /**
49
+ * A definition a select's tag menu commits (a created or renamed option):
50
+ * handed to the host's `setData`, never applied here.
51
+ */
52
+ private _writeData;
48
53
  /** A value a cell commits: unchanged, nothing is written. */
49
54
  private _commit;
50
55
  /** Neither the property nor the document can be written, or the type. */