@formicoidea/labre-core 0.47.0 → 0.48.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 (72) hide show
  1. package/dist/_pkgs/affine-block-attachment/configs/slash-menu.js +2 -2
  2. package/dist/_pkgs/affine-block-attachment/translations.js +2 -2
  3. package/dist/_pkgs/affine-block-database/view.js +5 -0
  4. package/dist/_pkgs/affine-block-embed/embed-html-block/configs/toolbar.js +1 -1
  5. package/dist/_pkgs/affine-block-embed/embed-iframe-block/configs/toolbar.d.ts +1 -1
  6. package/dist/_pkgs/affine-block-embed/embed-iframe-block/configs/toolbar.js +1 -1
  7. package/dist/_pkgs/affine-block-embed/translations.d.ts +1 -1
  8. package/dist/_pkgs/affine-block-embed/translations.js +2 -2
  9. package/dist/_pkgs/affine-block-embed-doc/embed-linked-doc-block/configs/new-doc.d.ts +25 -0
  10. package/dist/_pkgs/affine-block-embed-doc/embed-linked-doc-block/configs/new-doc.js +71 -0
  11. package/dist/_pkgs/affine-block-embed-doc/embed-linked-doc-block/configs/slash-menu.js +9 -17
  12. package/dist/_pkgs/affine-block-embed-doc/embed-linked-doc-block/configs/toolbar.js +1 -1
  13. package/dist/_pkgs/affine-block-embed-doc/embed-synced-doc-block/configs/toolbar.js +3 -3
  14. package/dist/_pkgs/affine-block-embed-doc/translations.d.ts +1 -1
  15. package/dist/_pkgs/affine-block-embed-doc/translations.js +8 -8
  16. package/dist/_pkgs/affine-block-frame/frame-toolbar.js +2 -2
  17. package/dist/_pkgs/affine-block-frame/translations.js +1 -1
  18. package/dist/_pkgs/affine-block-note/translations.js +8 -8
  19. package/dist/_pkgs/affine-block-root/commands/copy-link-commands.js +2 -2
  20. package/dist/_pkgs/affine-block-root/configs/toolbar.d.ts +1 -1
  21. package/dist/_pkgs/affine-block-root/configs/toolbar.js +1 -1
  22. package/dist/_pkgs/affine-block-root/edgeless/configs/toolbar/misc.d.ts +1 -1
  23. package/dist/_pkgs/affine-block-root/edgeless/configs/toolbar/more.d.ts +1 -1
  24. package/dist/_pkgs/affine-block-root/edgeless/configs/toolbar/more.js +1 -1
  25. package/dist/_pkgs/affine-block-root/translations.d.ts +1 -1
  26. package/dist/_pkgs/affine-block-root/translations.js +2 -2
  27. package/dist/_pkgs/affine-block-surface/extensions/canvas-grid/commands.js +1 -1
  28. package/dist/_pkgs/affine-block-surface/extensions/interchange-import.js +1 -1
  29. package/dist/_pkgs/affine-block-surface/extensions/selection-pane/commands.js +1 -1
  30. package/dist/_pkgs/affine-block-surface/renderer/element-highlight-overlay.d.ts +8 -2
  31. package/dist/_pkgs/affine-block-surface/renderer/element-highlight-overlay.js +11 -13
  32. package/dist/_pkgs/affine-block-surface-ref/translations.js +8 -8
  33. package/dist/_pkgs/affine-components/translations.js +6 -6
  34. package/dist/_pkgs/affine-fragment-doc-title/index.d.ts +1 -1
  35. package/dist/_pkgs/affine-fragment-doc-title/index.js +1 -1
  36. package/dist/_pkgs/affine-fragment-doc-title/title-band/band-cell.d.ts +22 -0
  37. package/dist/_pkgs/affine-fragment-doc-title/title-band/band-cell.js +125 -0
  38. package/dist/_pkgs/affine-fragment-doc-title/title-band/format.d.ts +7 -19
  39. package/dist/_pkgs/affine-fragment-doc-title/title-band/format.js +0 -38
  40. package/dist/_pkgs/affine-fragment-doc-title/title-band/show-here.d.ts +19 -0
  41. package/dist/_pkgs/affine-fragment-doc-title/title-band/show-here.js +61 -0
  42. package/dist/_pkgs/affine-fragment-doc-title/title-band/title-band.d.ts +28 -18
  43. package/dist/_pkgs/affine-fragment-doc-title/title-band/title-band.js +225 -207
  44. package/dist/_pkgs/affine-fragment-doc-title/translations.d.ts +7 -4
  45. package/dist/_pkgs/affine-fragment-doc-title/translations.js +12 -9
  46. package/dist/_pkgs/affine-gfx-group/toolbar/config.d.ts +2 -2
  47. package/dist/_pkgs/affine-gfx-group/toolbar/config.js +2 -2
  48. package/dist/_pkgs/affine-gfx-group/translations.js +1 -1
  49. package/dist/_pkgs/affine-gfx-note/translations.js +2 -2
  50. package/dist/_pkgs/affine-shared/services/linked-doc-creation-service.d.ts +15 -6
  51. package/dist/_pkgs/affine-shared/services/title-band-service.d.ts +10 -7
  52. package/dist/_pkgs/affine-shared/services/translation-service/chrome.d.ts +3 -3
  53. package/dist/_pkgs/affine-shared/services/translation-service/chrome.js +17 -17
  54. package/dist/_pkgs/affine-shared/utils/model/doc.d.ts +10 -2
  55. package/dist/_pkgs/affine-shared/utils/model/doc.js +17 -7
  56. package/dist/_pkgs/affine-widget-edgeless-auto-connect/translations.js +2 -2
  57. package/dist/_pkgs/affine-widget-edgeless-selected-rect/translations.js +1 -1
  58. package/dist/_pkgs/affine-widget-linked-doc/translations.js +3 -3
  59. package/dist/_pkgs/affine-widget-slash-menu/translations.js +1 -1
  60. package/dist/_pkgs/data-view/core/component/tags/multi-tag-select.d.ts +7 -2
  61. package/dist/_pkgs/data-view/core/component/tags/multi-tag-select.js +22 -15
  62. package/dist/_pkgs/data-view/core/effect.js +2 -0
  63. package/dist/_pkgs/data-view/core/property/index.d.ts +1 -0
  64. package/dist/_pkgs/data-view/core/property/index.js +1 -0
  65. package/dist/_pkgs/data-view/core/property/standalone-cell.d.ts +95 -0
  66. package/dist/_pkgs/data-view/core/property/standalone-cell.js +306 -0
  67. package/dist/_pkgs/data-view/core/view-manager/property.d.ts +6 -0
  68. package/dist/_pkgs/data-view/property-presets/multi-select/cell-renderer.js +1 -1
  69. package/dist/_pkgs/data-view/property-presets/select/cell-renderer.js +1 -1
  70. package/dist/_pkgs/data-view/property-presets/text/cell-renderer.js +3 -1
  71. package/dist/translations.js +1 -1
  72. package/package.json +1 -1
@@ -2,15 +2,17 @@ import { getChromeAccentColor } from '../../affine-shared/services/index.js';
2
2
  import { DisposableGroup } from '../../global/disposable/index.js';
3
3
  import { effect } from '@preact/signals-core';
4
4
  import { Overlay } from './overlay.js';
5
- /** Ring thickness, in screen pixels. */
5
+ /** Border thickness, in screen pixels: the selection frame's. */
6
6
  const HIGHLIGHT_STROKE_WIDTH = 2;
7
- /** Gap between the element bounds and the ring, in screen pixels. */
8
- const HIGHLIGHT_GAP = 4;
9
- /** Ring corner radius, in screen pixels. */
10
- const HIGHLIGHT_RADIUS = 4;
11
7
  /**
12
- * Draws the transient emphasis ring around the elements held by
13
- * `gfx.highlight` (`ElementHighlightManager`).
8
+ * Draws the transient emphasis around the elements held by `gfx.highlight`
9
+ * (`ElementHighlightManager`).
10
+ *
11
+ * The emphasis is the canvas's existing vocabulary, a square border on the
12
+ * element's bounds like the selection frame (`edgeless-selected-rect`), not a
13
+ * second, detached ring: the product owner asked for the border alone after
14
+ * the P1 recette, so a selection-pane hover reads as « this one » and not as a
15
+ * new kind of mark.
14
16
  *
15
17
  * The overlay is a pure renderer: it owns no state, reads nothing from the
16
18
  * store and mutates nothing, which makes it safe on a read-only editor.
@@ -37,8 +39,6 @@ export class ElementHighlightOverlay extends Overlay {
37
39
  if (elements.length === 0)
38
40
  return;
39
41
  const { zoom } = this.gfx.viewport;
40
- const gap = HIGHLIGHT_GAP / zoom;
41
- const radius = HIGHLIGHT_RADIUS / zoom;
42
42
  ctx.save();
43
43
  ctx.strokeStyle = this._strokeColor;
44
44
  ctx.lineWidth = HIGHLIGHT_STROKE_WIDTH / zoom;
@@ -46,14 +46,12 @@ export class ElementHighlightOverlay extends Overlay {
46
46
  const [x, y, w, h] = element.deserializedXYWH;
47
47
  ctx.save();
48
48
  // Rotate around the element center so rotated elements keep a tight
49
- // ring; connectors and other non-rotatable elements use their bound box.
49
+ // border; connectors and other non-rotatable elements use their bound box.
50
50
  ctx.translate(x + w / 2, y + h / 2);
51
51
  if (element.rotate) {
52
52
  ctx.rotate((element.rotate * Math.PI) / 180);
53
53
  }
54
- ctx.beginPath();
55
- ctx.roundRect(-w / 2 - gap, -h / 2 - gap, w + gap * 2, h + gap * 2, radius);
56
- ctx.stroke();
54
+ ctx.strokeRect(-w / 2, -h / 2, w, h);
57
55
  ctx.restore();
58
56
  }
59
57
  ctx.restore();
@@ -94,35 +94,35 @@ export const SURFACE_REF_PLACEHOLDER_NOT_AVAILABLE = [
94
94
  */
95
95
  export const SURFACE_REF_PLACEHOLDER_DELETED_FRAME = [
96
96
  'com.labre.surface-ref.placeholder.deleted.frame',
97
- 'The frame is deleted or not in this doc.',
97
+ 'The frame is deleted or not in this page.',
98
98
  ];
99
99
  export const SURFACE_REF_PLACEHOLDER_DELETED_GROUP = [
100
100
  'com.labre.surface-ref.placeholder.deleted.group',
101
- 'The group is deleted or not in this doc.',
101
+ 'The group is deleted or not in this page.',
102
102
  ];
103
103
  export const SURFACE_REF_PLACEHOLDER_DELETED_MINDMAP = [
104
104
  'com.labre.surface-ref.placeholder.deleted.mindmap',
105
- 'The mind map is deleted or not in this doc.',
105
+ 'The mind map is deleted or not in this page.',
106
106
  ];
107
107
  export const SURFACE_REF_PLACEHOLDER_DELETED_EDGELESS = [
108
108
  'com.labre.surface-ref.placeholder.deleted.edgeless',
109
- 'The canvas content is deleted or not in this doc.',
109
+ 'The canvas content is deleted or not in this page.',
110
110
  ];
111
111
  export const SURFACE_REF_PLACEHOLDER_CANNOT_DISPLAY_FRAME = [
112
112
  'com.labre.surface-ref.placeholder.cannot-display.frame',
113
- 'The frame is inserted but cannot display in canvas mode. Switch to document mode to view the block.',
113
+ 'The frame is inserted but cannot display in canvas mode. Switch to page mode to view the block.',
114
114
  ];
115
115
  export const SURFACE_REF_PLACEHOLDER_CANNOT_DISPLAY_GROUP = [
116
116
  'com.labre.surface-ref.placeholder.cannot-display.group',
117
- 'The group is inserted but cannot display in canvas mode. Switch to document mode to view the block.',
117
+ 'The group is inserted but cannot display in canvas mode. Switch to page mode to view the block.',
118
118
  ];
119
119
  export const SURFACE_REF_PLACEHOLDER_CANNOT_DISPLAY_MINDMAP = [
120
120
  'com.labre.surface-ref.placeholder.cannot-display.mindmap',
121
- 'The mind map is inserted but cannot display in canvas mode. Switch to document mode to view the block.',
121
+ 'The mind map is inserted but cannot display in canvas mode. Switch to page mode to view the block.',
122
122
  ];
123
123
  export const SURFACE_REF_PLACEHOLDER_CANNOT_DISPLAY_EDGELESS = [
124
124
  'com.labre.surface-ref.placeholder.cannot-display.edgeless',
125
- 'The canvas content is inserted but cannot display in canvas mode. Switch to document mode to view the block.',
125
+ 'The canvas content is inserted but cannot display in canvas mode. Switch to page mode to view the block.',
126
126
  ];
127
127
  /**
128
128
  * Per-kind table joining the two placeholder sentences above to the
@@ -117,7 +117,7 @@ export const EMBED_CARD_TITLE_ALIAS_PLACEHOLDER = [
117
117
  ];
118
118
  export const EMBED_CARD_DESCRIPTION_ALIAS_PLACEHOLDER = [
119
119
  'com.labre.embed.card.description-alias-placeholder',
120
- 'Add description alias (empty to inherit document content)',
120
+ 'Add description alias (empty to inherit page content)',
121
121
  ];
122
122
  export const EMBED_CARD_TITLE_PLACEHOLDER = [
123
123
  'com.labre.embed.card.title-placeholder',
@@ -292,7 +292,7 @@ export const EMOJI_GROUP_WORDINGS = {
292
292
  /* ── Linked doc title chip ───────────────────────────────────────────── */
293
293
  export const DOC_TITLE_ARIA = [
294
294
  'com.labre.linked-doc.title-aria',
295
- 'Doc title',
295
+ 'Page title',
296
296
  ];
297
297
  /* ── Linked-doc notifications ─────────────────────────────────────────── */
298
298
  export const NOTIFY_SWITCHED_TO_CARD_TITLE = [
@@ -309,7 +309,7 @@ export const NOTIFY_SWITCHED_TO_EMBED_TITLE = [
309
309
  ];
310
310
  export const NOTIFY_SWITCHED_TO_EMBED_MESSAGE = [
311
311
  'com.labre.notify.linked-doc.switched-to-embed.message',
312
- 'Custom alias removed. The linked doc now displays the original title and description.',
312
+ 'Custom alias removed. The linked page now displays the original title and description.',
313
313
  ];
314
314
  export const NOTIFY_CLEARED_ALIASES_TITLE = [
315
315
  'com.labre.notify.linked-doc.cleared-aliases.title',
@@ -317,17 +317,17 @@ export const NOTIFY_CLEARED_ALIASES_TITLE = [
317
317
  ];
318
318
  export const NOTIFY_CLEARED_ALIASES_MESSAGE = [
319
319
  'com.labre.notify.linked-doc.cleared-aliases.message',
320
- 'Card view has been restored to original doc title and description. All custom aliases have been removed.',
320
+ 'Card view has been restored to original page title and description. All custom aliases have been removed.',
321
321
  ];
322
322
  /* ── Open-doc dropdown ────────────────────────────────────────────────── */
323
323
  export const OPEN_LABEL = ['com.labre.open-doc.open', 'Open'];
324
324
  export const OPEN_DOC_MENU_ARIA = [
325
325
  'com.labre.open-doc.menu-aria',
326
- 'Open doc menu',
326
+ 'Open page menu',
327
327
  ];
328
328
  export const OPEN_DOC_WITH_ARIA = [
329
329
  'com.labre.open-doc.with-aria',
330
- 'Open doc with',
330
+ 'Open page with',
331
331
  ];
332
332
  /* ── Resource popover (attachment / image not-found or retrieve error) ─ */
333
333
  /**
@@ -1,4 +1,4 @@
1
1
  export { DocTitle } from './doc-title.js';
2
- export { chipEditorKind, type ChipEditorKind, type ChipTag, chipValueView, type ChipValueView, formatPropertyValue, isPropertyValueEmpty, } from './title-band/format.js';
2
+ export { type ChipTag, chipValueView, type ChipValueView, formatPropertyValue, isPropertyValueEmpty, } from './title-band/format.js';
3
3
  export { LABRE_TITLE_BAND, TitleBand } from './title-band/title-band.js';
4
4
  export { getDocTitleByEditorHost } from './utils.js';
@@ -1,4 +1,4 @@
1
1
  export { DocTitle } from './doc-title.js';
2
- export { chipEditorKind, chipValueView, formatPropertyValue, isPropertyValueEmpty, } from './title-band/format.js';
2
+ export { chipValueView, formatPropertyValue, isPropertyValueEmpty, } from './title-band/format.js';
3
3
  export { LABRE_TITLE_BAND, TitleBand } from './title-band/title-band.js';
4
4
  export { getDocTitleByEditorHost } from './utils.js';
@@ -0,0 +1,22 @@
1
+ import type { TitleBandProperty } from '../../affine-shared/services/index.js';
2
+ import { type PropertyMetaConfig } from '../../data-view/index.js';
3
+ /** The data-view cell type that draws a band property of `type`, if any. */
4
+ export declare function bandCellType(type: string): string | undefined;
5
+ /**
6
+ * The cell's meta: one a package above registered for that cell type (the
7
+ * database block's `link`), else this package's preset. Without its
8
+ * registration a link is drawn by the `text` cell.
9
+ */
10
+ export declare function bandCellMeta(type: string, registered: (cellType: string) => PropertyMetaConfig | null): PropertyMetaConfig | null;
11
+ export declare function isBandReadonlyType(type: string): boolean;
12
+ /** The value in the raw shape of the cell type `cellType` reads. */
13
+ export declare function bandCellValue(cellType: string, value: unknown): unknown;
14
+ /** The property's config as the cell reads it: a select's tags, complete. */
15
+ export declare function bandCellData(cellType: string, property: TitleBandProperty): Record<string, unknown>;
16
+ /**
17
+ * What the band writes back for a value a cell commits: `null` for an empty
18
+ * one (the seam's "clear"), the value itself otherwise.
19
+ */
20
+ export declare function bandWriteValue(value: unknown): unknown;
21
+ /** Whether a committed value is the one the chip already shows. */
22
+ export declare function sameBandValue(cellType: string, current: unknown, next: unknown): boolean;
@@ -0,0 +1,125 @@
1
+ import { selectOptionColors, } from '../../data-view/index.js';
2
+ import { propertyPresets } from '../../data-view/property-presets/index.js';
3
+ import { chipOptions } from './format.js';
4
+ /**
5
+ * Which data-view cell draws a band property, and the value and config that
6
+ * cell is handed (ADR 0035 §11, amended 2026-10-13: the chips are the table's
7
+ * own cells).
8
+ *
9
+ * The band speaks the data-view types (§9d), plus the aliases a host's sheet
10
+ * holds whose shape a preset already reads: a URL is the table's `link` cell,
11
+ * the text-like types the `text` cell, the time stamps a read-only `date`.
12
+ * A type with no cell here (`relation`, `image`, an invented one) keeps the
13
+ * band's plain-text reading and opens the properties panel instead.
14
+ *
15
+ * The host's JSON is never trusted to have the preset's shape: a renderer
16
+ * that meets a string where it maps an array throws mid-render, so each value
17
+ * is narrowed to its cell's raw shape, and anything else reads as empty.
18
+ */
19
+ const CELL_TYPES = Object.assign(Object.create(null), {
20
+ checkbox: 'checkbox',
21
+ select: 'select',
22
+ 'multi-select': 'multi-select',
23
+ date: 'date',
24
+ 'created-time': 'date',
25
+ 'modified-time': 'date',
26
+ number: 'number',
27
+ progress: 'progress',
28
+ text: 'text',
29
+ 'rich-text': 'text',
30
+ title: 'text',
31
+ email: 'text',
32
+ phone: 'text',
33
+ link: 'link',
34
+ url: 'link',
35
+ });
36
+ /** Drawn by their cell, never edited from the band. */
37
+ const READ_ONLY_TYPES = new Set(['created-time', 'modified-time']);
38
+ const PRESETS = new Map([
39
+ propertyPresets.checkboxPropertyConfig,
40
+ propertyPresets.datePropertyConfig,
41
+ propertyPresets.multiSelectPropertyConfig,
42
+ propertyPresets.numberPropertyConfig,
43
+ propertyPresets.progressPropertyConfig,
44
+ propertyPresets.selectPropertyConfig,
45
+ propertyPresets.textPropertyConfig,
46
+ ].map(meta => [meta.type, meta]));
47
+ const DEFAULT_TAG_COLOR = selectOptionColors.at(-1)?.color ?? '';
48
+ /** The data-view cell type that draws a band property of `type`, if any. */
49
+ export function bandCellType(type) {
50
+ return CELL_TYPES[type];
51
+ }
52
+ /**
53
+ * The cell's meta: one a package above registered for that cell type (the
54
+ * database block's `link`), else this package's preset. Without its
55
+ * registration a link is drawn by the `text` cell.
56
+ */
57
+ export function bandCellMeta(type, registered) {
58
+ const cellType = bandCellType(type);
59
+ if (!cellType)
60
+ return null;
61
+ return (registered(cellType) ??
62
+ PRESETS.get(cellType) ??
63
+ (cellType === 'link' ? (PRESETS.get('text') ?? null) : null));
64
+ }
65
+ export function isBandReadonlyType(type) {
66
+ return READ_ONLY_TYPES.has(type);
67
+ }
68
+ const isFiniteNumber = (value) => typeof value === 'number' && Number.isFinite(value);
69
+ /** The value in the raw shape of the cell type `cellType` reads. */
70
+ export function bandCellValue(cellType, value) {
71
+ switch (cellType) {
72
+ case 'checkbox':
73
+ return value === true;
74
+ case 'select':
75
+ return typeof value === 'string' && value !== '' ? value : undefined;
76
+ case 'multi-select':
77
+ return Array.isArray(value)
78
+ ? value.filter((id) => typeof id === 'string')
79
+ : undefined;
80
+ case 'date':
81
+ case 'number':
82
+ case 'progress':
83
+ return isFiniteNumber(value) ? value : undefined;
84
+ default:
85
+ if (typeof value === 'string')
86
+ return value;
87
+ if (isFiniteNumber(value))
88
+ return String(value);
89
+ return undefined;
90
+ }
91
+ }
92
+ /** The property's config as the cell reads it: a select's tags, complete. */
93
+ export function bandCellData(cellType, property) {
94
+ if (cellType !== 'select' && cellType !== 'multi-select') {
95
+ return property.data;
96
+ }
97
+ const options = chipOptions(property).map(tag => ({
98
+ id: tag.id,
99
+ value: tag.label,
100
+ color: tag.color ?? DEFAULT_TAG_COLOR,
101
+ }));
102
+ return { ...property.data, options };
103
+ }
104
+ /**
105
+ * What the band writes back for a value a cell commits: `null` for an empty
106
+ * one (the seam's "clear"), the value itself otherwise.
107
+ */
108
+ export function bandWriteValue(value) {
109
+ if (value === undefined)
110
+ return null;
111
+ if (typeof value === 'string' && value.trim() === '')
112
+ return null;
113
+ if (typeof value === 'number' && Number.isNaN(value))
114
+ return null;
115
+ return value;
116
+ }
117
+ /** Whether a committed value is the one the chip already shows. */
118
+ export function sameBandValue(cellType, current, next) {
119
+ const a = bandWriteValue(bandCellValue(cellType, current));
120
+ const b = bandWriteValue(next);
121
+ if (Array.isArray(a) && Array.isArray(b)) {
122
+ return a.length === b.length && a.every((item, i) => item === b[i]);
123
+ }
124
+ return a === b;
125
+ }
@@ -1,9 +1,9 @@
1
1
  import type { TitleBandProperty } from '../../affine-shared/services/index.js';
2
2
  /**
3
- * How a chip of the title band draws a property's value, and which editor a
4
- * click opens — pure, render-free, so a host's own properties panel can show
5
- * the very text a chip shows (`formatPropertyValue`, re-exported by
6
- * `@labre/affine/host-panels`).
3
+ * A property's value as one line of text — pure, render-free, so a host's own
4
+ * properties panel can show what a chip reads (`formatPropertyValue`,
5
+ * re-exported by `@labre/affine/host-panels`), and the band can still read
6
+ * a type no data-view cell draws (`relation`, an unknown one).
7
7
  *
8
8
  * The value is the JSON a data-view cell of `type` holds (ADR 0035 §9d), and
9
9
  * the shapes below are the data-view presets' own: an option id for `select`,
@@ -11,12 +11,9 @@ import type { TitleBandProperty } from '../../affine-shared/services/index.js';
11
11
  * formatted with the number preset's options, so a chip and a database cell
12
12
  * read the same.
13
13
  *
14
- * ponytail: the band draws its chips and editors itself, per type, rather
15
- * than mounting the data-view cell renderers, which need a `Cell` bound to a
16
- * view and a data source the band does not have. The ceiling is a type the
17
- * band does not know: it is drawn as plain text and opens no editor. The
18
- * upgrade path is a hosted data source for the page's sheet once
19
- * `HostedDataSourceBase` exists (ADR 0035 §7, issue B1).
14
+ * The chips themselves no longer read this: each value is drawn and edited by
15
+ * the data-view cell of its type (`./band-cell.ts`, ADR 0035 §11 amended
16
+ * 2026-10-13). This text is the host panels' reading and the band's fallback.
20
17
  */
21
18
  /** A select option as a data-view `select` / `multi-select` holds it. */
22
19
  export interface ChipTag {
@@ -37,8 +34,6 @@ export type ChipValueView = {
37
34
  kind: 'tags';
38
35
  tags: ChipTag[];
39
36
  };
40
- /** The editor a click on a chip opens; `none` for a type the band cannot edit. */
41
- export type ChipEditorKind = 'toggle' | 'select' | 'multi-select' | 'date' | 'number' | 'text' | 'none';
42
37
  /**
43
38
  * The number preset's formats (`data-view/…/number/utils/formatter.ts`),
44
39
  * restated rather than imported: the preset formats with
@@ -60,10 +55,3 @@ export declare function chipValueView(property: TitleBandProperty, locale: strin
60
55
  * mark, not a word, so a host draws its own from `property.value`.
61
56
  */
62
57
  export declare function formatPropertyValue(property: TitleBandProperty, locale?: string): string;
63
- /**
64
- * A number typed in a chip's editor: blanks dropped, a decimal comma read as
65
- * a point. `NaN` for anything else, which the band writes as `null`.
66
- */
67
- export declare function parseChipNumber(text: string): number;
68
- /** The editor a click on this property's chip opens. */
69
- export declare function chipEditorKind(property: TitleBandProperty): ChipEditorKind;
@@ -1,12 +1,3 @@
1
- const TEXT_TYPES = new Set([
2
- 'text',
3
- 'rich-text',
4
- 'title',
5
- 'url',
6
- 'link',
7
- 'email',
8
- 'phone',
9
- ]);
10
1
  const DATE_TYPES = new Set(['date', 'created-time', 'modified-time']);
11
2
  const currency = (code) => ({
12
3
  style: 'currency',
@@ -151,32 +142,3 @@ export function formatPropertyValue(property, locale = 'en-US') {
151
142
  return '';
152
143
  }
153
144
  }
154
- /**
155
- * A number typed in a chip's editor: blanks dropped, a decimal comma read as
156
- * a point. `NaN` for anything else, which the band writes as `null`.
157
- */
158
- export function parseChipNumber(text) {
159
- const compact = text.replace(/\s/g, '');
160
- if (compact === '')
161
- return NaN;
162
- return Number(compact.replace(',', '.'));
163
- }
164
- /** The editor a click on this property's chip opens. */
165
- export function chipEditorKind(property) {
166
- if (property.readonly)
167
- return 'none';
168
- const { type } = property;
169
- if (type === 'checkbox')
170
- return 'toggle';
171
- if (type === 'select')
172
- return 'select';
173
- if (type === 'multi-select')
174
- return 'multi-select';
175
- if (type === 'date')
176
- return 'date';
177
- if (type === 'number' || type === 'progress')
178
- return 'number';
179
- if (TEXT_TYPES.has(type))
180
- return 'text';
181
- return 'none';
182
- }
@@ -0,0 +1,19 @@
1
+ import type { BlockStdScope } from '../../std/index.js';
2
+ /**
3
+ * "Show here" (labre ADR-0045 §7): insert a card of page `pageId` into the
4
+ * open document, so a child page the document held without showing becomes
5
+ * shown. The host computes the "Not shown" list; once the card exists, its
6
+ * own reading of the document drops the page from it. Nothing here knows a
7
+ * parent or a child: the card is an ordinary `affine:embed-linked-doc`,
8
+ * exactly what pasting a link to that page would make.
9
+ *
10
+ * - page view: at the end of the last note the page view shows (a new note
11
+ * when there is none);
12
+ * - canvas: centred in the visible part of the canvas, through the CRUD
13
+ * `addBlock`, which stamps the viewer's active layer (ADR 0031 §6), then
14
+ * selected so the reader sees what appeared.
15
+ *
16
+ * One gesture, one undo step (`captureSync`). A read-only document gets
17
+ * nothing. Returns the new card's id, or `null` when nothing was written.
18
+ */
19
+ export declare function showPageHere(std: BlockStdScope, surface: 'page' | 'canvas', pageId: string): string | null;
@@ -0,0 +1,61 @@
1
+ import { EdgelessCRUDIdentifier } from '../../affine-block-surface/index.js';
2
+ import { EMBED_CARD_HEIGHT, EMBED_CARD_WIDTH, } from '../../affine-shared/consts/index.js';
3
+ import { TelemetryProvider } from '../../affine-shared/services/index.js';
4
+ import { getLastNoteBlock } from '../../affine-shared/utils/index.js';
5
+ import { Bound } from '../../global/gfx/index.js';
6
+ import { GfxControllerIdentifier } from '../../std/gfx/index.js';
7
+ const LINKED_DOC = 'affine:embed-linked-doc';
8
+ /** The canvas card's style, the one "Linked doc" inserts on the canvas. */
9
+ const CANVAS_STYLE = 'vertical';
10
+ /**
11
+ * "Show here" (labre ADR-0045 §7): insert a card of page `pageId` into the
12
+ * open document, so a child page the document held without showing becomes
13
+ * shown. The host computes the "Not shown" list; once the card exists, its
14
+ * own reading of the document drops the page from it. Nothing here knows a
15
+ * parent or a child: the card is an ordinary `affine:embed-linked-doc`,
16
+ * exactly what pasting a link to that page would make.
17
+ *
18
+ * - page view: at the end of the last note the page view shows (a new note
19
+ * when there is none);
20
+ * - canvas: centred in the visible part of the canvas, through the CRUD
21
+ * `addBlock`, which stamps the viewer's active layer (ADR 0031 §6), then
22
+ * selected so the reader sees what appeared.
23
+ *
24
+ * One gesture, one undo step (`captureSync`). A read-only document gets
25
+ * nothing. Returns the new card's id, or `null` when nothing was written.
26
+ */
27
+ export function showPageHere(std, surface, pageId) {
28
+ const { store } = std;
29
+ if (store.readonly || !store.root || !pageId)
30
+ return null;
31
+ store.captureSync();
32
+ const id = surface === 'canvas'
33
+ ? insertOnCanvas(std, pageId)
34
+ : insertInPage(std, pageId);
35
+ if (id) {
36
+ std.getOptional(TelemetryProvider)?.track('BlockCreated', {
37
+ blockType: LINKED_DOC,
38
+ });
39
+ }
40
+ return id;
41
+ }
42
+ function insertInPage(std, pageId) {
43
+ const { store } = std;
44
+ const root = store.root;
45
+ if (!root)
46
+ return null;
47
+ const noteId = getLastNoteBlock(store)?.id ?? store.addBlock('affine:note', {}, root.id);
48
+ return store.addBlock(LINKED_DOC, { pageId }, noteId);
49
+ }
50
+ function insertOnCanvas(std, pageId) {
51
+ const gfx = std.get(GfxControllerIdentifier);
52
+ const surface = gfx.surface;
53
+ if (!surface)
54
+ return null;
55
+ const xywh = Bound.fromCenter([gfx.viewport.centerX, gfx.viewport.centerY], EMBED_CARD_WIDTH[CANVAS_STYLE], EMBED_CARD_HEIGHT[CANVAS_STYLE]).serialize();
56
+ const id = std
57
+ .get(EdgelessCRUDIdentifier)
58
+ .addBlock(LINKED_DOC, { pageId, xywh, style: CANVAS_STYLE }, surface);
59
+ gfx.selection.set({ elements: [id], editing: false });
60
+ return id;
61
+ }
@@ -14,40 +14,50 @@ declare const TitleBand_base: typeof ShadowlessElement & import("../../global/ut
14
14
  *
15
15
  * Fed by `TitleBandProvider` alone (§9d): no provider, nothing at all. The
16
16
  * chips are the sheet's visible properties in the host's order, an empty one
17
- * included (REQ-PR-1); a click opens the editor of the property's data-view
18
- * type and hands the value back through `set`, showing the chip as pending
19
- * until the host settles it. The band never writes to the document and never
20
- * applies a value. The "+" is drawn when the host passes `add`; the panel
21
- * button when a `PropertiesPanelProvider` is registered; the "Not shown in
22
- * this document" row only on the canvas (the page view's row is the host's).
17
+ * included (REQ-PR-1). Each value is drawn and edited by the cell the inline
18
+ * table mounts for its data-view type (`<dv-standalone-cell>`, ADR 0035
19
+ * §11 amended 2026-10-13): the checkbox, the tag menu of a select, the date
20
+ * picker, the number, text and link inputs, with the table's own styles. The
21
+ * value the cell commits goes back through `set`, the chip shows pending
22
+ * until the host settles it, and a type with no cell keeps a plain-text
23
+ * reading that opens the properties panel. The band never applies a value, and writes to
24
+ * the document only the card "Show here" inserts. The "+" is drawn when the
25
+ * host passes `add`; the panel button when a `PropertiesPanelProvider` is
26
+ * registered. The "Not shown on this page" row is drawn in both views
27
+ * from the host's `notShown$` (ADR 0035 §9d, amended 2026-10-13): each page
28
+ * opens through the linked-document path, and "Show here" inserts a card of
29
+ * it into this document; the host then drops the page from its list.
23
30
  */
24
31
  export declare class TitleBand extends TitleBand_base {
25
32
  static styles: import("lit").CSSResult;
26
33
  private _sources;
27
- /** The editor menu open now, put away with the band. */
28
- private _menu;
29
- private _pop;
30
34
  /** Collapse state when the host does not remember one. */
31
35
  private readonly _localCollapsed$;
32
36
  /** Property ids whose `set` has not settled yet. */
33
37
  private readonly _pending$;
34
38
  /** Read inside `render` it subscribes, through `SignalWatcher`. */
35
39
  private get _readonly();
40
+ /** The table's own flags, so a number reads as it does in a cell. */
41
+ private readonly _featureFlags$;
36
42
  private get _locale();
37
43
  private _t;
38
44
  private _getSources;
39
45
  private _isCollapsed;
40
46
  private _setCollapsed;
41
47
  private _write;
42
- private readonly _onChip;
43
- private _tagLabel;
44
- private _clearItem;
45
- private _popSelect;
46
- private _popMultiSelect;
47
- private _popDate;
48
- private _popInput;
48
+ /** A value a cell commits: unchanged, nothing is written. */
49
+ private _commit;
50
+ /** Neither the property nor the document can be written, or the type. */
51
+ private _isReadonlyChip;
52
+ /**
53
+ * The cell that draws `prop`, built once per property and type: its value,
54
+ * name and config are read from the sheet, so a new sheet updates the cell
55
+ * in place and an editor open in it stays open.
56
+ */
57
+ private _cellFor;
49
58
  private readonly _openPanel;
50
- private _renderValue;
59
+ private readonly _onChip;
60
+ private _renderFallback;
51
61
  private _renderChip;
52
62
  private _renderTools;
53
63
  private _renderSheet;
@@ -56,7 +66,7 @@ export declare class TitleBand extends TitleBand_base {
56
66
  render(): TemplateResult<1> | typeof nothing;
57
67
  accessor std: BlockStdScope | null;
58
68
  accessor docId: string;
59
- /** Where the band is drawn; only the canvas draws the "Not shown" row. */
69
+ /** Where the band is drawn: where "Show here" puts the card. */
60
70
  accessor surface: 'page' | 'canvas';
61
71
  }
62
72
  export {};