@twip/web 0.0.0-canary-abcb2d5 → 0.0.0-canary-6f0bf0b

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.
@@ -1,5 +1,5 @@
1
1
  import type { RichText } from './review.js';
2
- import type { ControlKind, ControlOptions, DataBinding, ReferenceRule } from './services/elements.js';
2
+ import type { ControlKind, ControlOptions, DataBinding, ReferenceRule, SubTemplateVersion } from './services/elements.js';
3
3
  import type { TabAlignment, TabLeader, TabSelector } from './services/ruler.js';
4
4
  import type { ViewOptions } from './services/view.js';
5
5
  import type { AutoCorrectChange, HighlightColor, HorizontalPosition, LineSpacing, MarkupView, ObjectWrap, RowHeight, TablePosition, TableWidth, UnderlineStyle, VerticalPosition, WrapSide } from './state.js';
@@ -19,7 +19,10 @@ export interface PlaceholderLook {
19
19
  } | {
20
20
  prefix: string;
21
21
  } | 'default';
22
- /** A fill, label and icon, or an image. */
22
+ /**
23
+ * A fill, label and icon, or an image. With `placeholderUi` on, `fill` is the input block's base colour: its tint,
24
+ * outlines and primary button are derived from it.
25
+ */
23
26
  look: {
24
27
  fill?: Color;
25
28
  label?: string;
@@ -28,6 +31,19 @@ export interface PlaceholderLook {
28
31
  image: Uint8Array;
29
32
  mime: string;
30
33
  };
34
+ /** The hint an input block shows while hovered. Default: "Click to add". */
35
+ hint?: string;
36
+ /** The buttons a selected input block shows, in order; none: a press on the block activates it. */
37
+ actions?: PlaceholderAction[];
38
+ }
39
+ /** A button on a selected input block: a press raises `placeholderActivated` with its `id` as `action`. */
40
+ export interface PlaceholderAction {
41
+ /** What `placeholderActivated` names as `action`. */
42
+ id: string;
43
+ /** Its text. */
44
+ label: string;
45
+ /** Filled in the block's colour (the others are outlined); Enter presses it. Default: false. */
46
+ primary?: boolean;
31
47
  }
32
48
  /**
33
49
  * Every edit, one method per command. Each resolves after its change commits, with `getState()` already at that
@@ -476,6 +492,18 @@ export interface Commands {
476
492
  labels: Record<string, string>;
477
493
  merge?: boolean;
478
494
  }): Promise<void>;
495
+ /** The type text a field's caption shows, by field code (default: the field type, `MERGEFIELD`). View. */
496
+ setFieldTypes(options: {
497
+ types: Record<string, string>;
498
+ merge?: boolean;
499
+ }): Promise<void>;
500
+ /**
501
+ * The merge fields (by name, their first argument) the data source lacks: drawn neutral, struck through. Replaces
502
+ * the list, and `[]` clears it. View.
503
+ */
504
+ setUnmappedFields(options: {
505
+ names: string[];
506
+ }): Promise<void>;
479
507
  /** Which fields are sub-template references: replaces the rules; an empty list turns sub-templates off. View. */
480
508
  setSubTemplateRules(options: {
481
509
  rules: ReferenceRule[];
@@ -510,6 +538,10 @@ export interface Commands {
510
538
  name: string;
511
539
  category?: string;
512
540
  }): Promise<void>;
541
+ /** The version text sub-templates' cards and tabs show, and their newer versions; replaces the list. View. */
542
+ setSubTemplateVersions(options: {
543
+ versions: SubTemplateVersion[];
544
+ }): Promise<void>;
513
545
  /** Inserts a content control, optionally around the selection. */
514
546
  insertControl(options: {
515
547
  kind: ControlKind;
@@ -583,6 +615,14 @@ export interface Commands {
583
615
  looks: PlaceholderLook[];
584
616
  merge?: boolean;
585
617
  }): Promise<void>;
618
+ /** Draws a placeholder hovered until cleared (`null`), as when the application's field list hovers it. View. */
619
+ highlightElement(options: {
620
+ id: ElementId | null;
621
+ }): Promise<void>;
622
+ /** Selects the next placeholder in document order, wrapping; Tab while one is selected. View. */
623
+ selectNextPlaceholder(): Promise<void>;
624
+ /** Selects the previous placeholder in document order, wrapping; Shift+Tab while one is selected. View. */
625
+ selectPreviousPlaceholder(): Promise<void>;
586
626
  /** Fills the selected placeholder, or every unfilled one with `key`. */
587
627
  fillPlaceholder(options: {
588
628
  key?: string;
@@ -659,7 +699,7 @@ export interface Commands {
659
699
  setZoom(zoom: number | 'pageWidth' | 'wholePage'): Promise<void>;
660
700
  /**
661
701
  * Sets view options: formatting marks (Ctrl+Shift+8), gridlines, text boundaries, live layout, the chrome's theme
662
- * and accent, the page's appearance, the measuring detail and the object grid.
702
+ * and accent, the page's appearance, the measuring detail, the object grid and the placeholder UI.
663
703
  */
664
704
  setViewOptions(options: ViewOptions): Promise<void>;
665
705
  /** Switches between editing and design mode. */
package/dist/commands.js CHANGED
@@ -143,6 +143,8 @@ const encodings = {
143
143
  unlinkFields: 'spread',
144
144
  showFieldCodes: 'spread',
145
145
  setFieldLabels: 'spread',
146
+ setFieldTypes: 'spread',
147
+ setUnmappedFields: 'spread',
146
148
  setSubTemplateRules: 'spread',
147
149
  setSubTemplateView: 'spread',
148
150
  editSubTemplate: 'spread',
@@ -150,6 +152,7 @@ const encodings = {
150
152
  createSubTemplate: 'spread',
151
153
  renameSubTemplate: 'spread',
152
154
  removeSubTemplate: 'spread',
155
+ setSubTemplateVersions: 'spread',
153
156
  insertControl: 'spread',
154
157
  setControl: 'spread',
155
158
  removeControl: 'spread',
@@ -160,6 +163,9 @@ const encodings = {
160
163
  replaceInElements: 'spread',
161
164
  markElements: 'spread',
162
165
  setPlaceholderLooks: 'spread',
166
+ highlightElement: 'spread',
167
+ selectNextPlaceholder: 'none',
168
+ selectPreviousPlaceholder: 'none',
163
169
  fillPlaceholder: 'spread',
164
170
  writeDataPart: 'spread',
165
171
  removeDataPart: 'spread',
package/dist/events.d.ts CHANGED
@@ -2,7 +2,7 @@ import type { EditorError } from './errors.js';
2
2
  import type { BalloonPlacement, CommentAnchor } from './review.js';
3
3
  import type { AnnouncementKind } from './services/accessibility.js';
4
4
  import type { DialogKind } from './services/dialogs.js';
5
- import type { ElementInfo } from './services/elements.js';
5
+ import type { ElementInfo, SubTemplateReference } from './services/elements.js';
6
6
  import type { ContextMenuEvent } from './services/menus.js';
7
7
  import type { RulerView } from './services/ruler.js';
8
8
  import type { GestureEvent, Popover } from './services/view.js';
@@ -21,10 +21,29 @@ export interface TwipEvents {
21
21
  address: string;
22
22
  via: 'ctrlClick' | 'click';
23
23
  };
24
- /** An unfilled picture placeholder was clicked. */
24
+ /**
25
+ * An unfilled picture placeholder was clicked, or one of its buttons (`action`: the button's id, or `replace` from a
26
+ * filled block's tab).
27
+ */
25
28
  placeholderActivated: {
26
29
  key: string;
27
30
  element: ElementId | null;
31
+ action?: string;
32
+ };
33
+ /**
34
+ * With `placeholderUi` on, the pointer starts or stops being over a placeholder, or the hovered one's anchor moves;
35
+ * `null` when it leaves.
36
+ */
37
+ placeholderHovered: PlaceholderTarget | null;
38
+ /**
39
+ * With `placeholderUi` on, the selection starts or stops covering exactly one placeholder, or the selected one's
40
+ * anchor moves (scroll, zoom, layout); `null` when it's no longer selected.
41
+ */
42
+ placeholderSelected: PlaceholderTarget | null;
43
+ /** A shown sub-template's newer-version notice (`setSubTemplateVersions`) was pressed: the application updates it. */
44
+ subTemplateUpdateRequested: {
45
+ name: string;
46
+ category: string;
28
47
  };
29
48
  /**
30
49
  * Typing, pasting or dropping was refused: into a sub-template's body shown in place of its reference (edit the
@@ -148,3 +167,26 @@ export interface Tooltip {
148
167
  /** The hovered thing's box. */
149
168
  rect: ClientRect;
150
169
  }
170
+ /** What kind of placeholder a {@link PlaceholderTarget} is. */
171
+ export type PlaceholderKind = 'field' | 'control' | 'repeatingSection' | 'subTemplate' | 'inputBlock' | 'ifField';
172
+ /** A placeholder the pointer is over or the selection covers, with `placeholderUi` on. */
173
+ export interface PlaceholderTarget {
174
+ /** The field or control; absent for an input block outside a content control. */
175
+ element?: ElementId;
176
+ /** What it is. */
177
+ kind: PlaceholderKind;
178
+ /** What it shows, in full: a field's label or result, a control's title. */
179
+ label: string;
180
+ /** A field's name (its first argument), a control's tag, or a picture placeholder's key. */
181
+ key?: string;
182
+ /** A field's code. */
183
+ code?: string;
184
+ /** The caption's type text: `setFieldTypes`' text for the code, else the field type (`MERGEFIELD`), or a control's kind. */
185
+ typeText: string;
186
+ /** The data source lacks the field (`setUnmappedFields`). */
187
+ unmapped: boolean;
188
+ /** For a sub-template reference: what it names and whether its body shows. */
189
+ reference?: SubTemplateReference;
190
+ /** Where it is, in the same space as a popover's anchor: a field's last line, else its box. */
191
+ anchor: ClientRect;
192
+ }
@@ -112,6 +112,7 @@ export function startChrome(s, dom, ledger, frames, report, toViewport) {
112
112
  setThemeColors: (themeColors) => setLook({ themeColors }),
113
113
  setAppearance: (appearance) => setLook({ appearance }),
114
114
  setDetail: (detail) => setLook({ detail }),
115
+ setPlaceholderUi: (placeholderUi) => setLook({ placeholderUi }),
115
116
  visiblePages: () => {
116
117
  const r = dom.canvas.getBoundingClientRect();
117
118
  return pages.map(({ page, rect }) => ({ page, rect: { ...rect, left: rect.left + r.left, top: rect.top + r.top } }));
@@ -34,6 +34,10 @@ export async function mountHost(container, s, options, claims) {
34
34
  const t = event;
35
35
  return { ...t, at: client(t.at), rect: { ...t.rect, left: t.rect.left + r.left, top: t.rect.top + r.top } };
36
36
  }
37
+ if ((type === 'placeholderHovered' || type === 'placeholderSelected') && event) {
38
+ const t = event;
39
+ return { ...t, anchor: { ...t.anchor, left: t.anchor.left + r.left, top: t.anchor.top + r.top } };
40
+ }
37
41
  if (type === 'popoverRequested') {
38
42
  const p = event;
39
43
  return { ...p, anchor: { ...p.anchor, left: p.anchor.left + r.left, top: p.anchor.top + r.top } };
package/dist/index.d.ts CHANGED
@@ -6,9 +6,9 @@
6
6
  */
7
7
  export { Editor, HeadlessEditor } from './editor.js';
8
8
  export type { ExportResult, MountOptions, SessionOptions } from './editor.js';
9
- export type { CommandEntry, CommandId, CommandInfo, Commands, FieldTargets, NoArgumentCommandId, Op, OpArgs, PlaceholderLook, } from './commands.js';
9
+ export type { CommandEntry, CommandId, CommandInfo, Commands, FieldTargets, NoArgumentCommandId, Op, OpArgs, PlaceholderAction, PlaceholderLook, } from './commands.js';
10
10
  export type { AutoCorrectChange, AutoCorrectEntry, AutoCorrectOptions, CharacterFormatting, CommandState, CommandValues, EditingTarget, EditorState, ElementContext, HighlightColor, HorizontalPosition, HorizontalReference, LineSpacing, MarkupView, Mixed, ObjectHorizontalAlignment, ObjectPlacement, ObjectSelection, ObjectVerticalAlignment, ObjectWrap, PageFormatting, ParagraphFormatting, ReviewState, RowHeight, SelectionSummary, TablePosition, TableSelection, TableStyleOptions, TableWidth, TextDistance, Tri, UnderlineStyle, VerticalPosition, VerticalReference, ViewState, WrapSide, } from './state.js';
11
- export type { HostCommand, Tooltip, TransactionRecord, TwipEvents } from './events.js';
11
+ export type { HostCommand, PlaceholderKind, PlaceholderTarget, Tooltip, TransactionRecord, TwipEvents } from './events.js';
12
12
  export { EditorError } from './errors.js';
13
13
  export type { ErrorCode } from './errors.js';
14
14
  export { FontLibrary } from './fonts/library.js';
@@ -18,7 +18,7 @@ export type { ContextMenu, ContextMenuEvent, MenuAction, MenuItem, MenuTarget, M
18
18
  export type { AccessibilityDialogSession, DialogKind, DialogSession, DialogSessionOf, DialogValues, Dialogs, FieldInfo, } from './services/dialogs.js';
19
19
  export type { Find, FindMatch, FindQuery, FindResult } from './services/find.js';
20
20
  export type { Dictionary, Spelling } from './services/spelling.js';
21
- export type { Block, ControlKind, ControlOptions, DataBinding, DataParts, ElementDetail, ElementInfo, Elements, MountedElements, PlaceholderInfo, ReferenceResolution, ReferenceRule, SubTemplateInfo, SubTemplateReference, SubTemplates, } from './services/elements.js';
21
+ export type { Block, ControlKind, ControlOptions, DataBinding, DataParts, ElementDetail, ElementInfo, Elements, MountedElements, PlaceholderInfo, ReferenceResolution, ReferenceRule, SubTemplateInfo, SubTemplateReference, SubTemplates, SubTemplateVersion, } from './services/elements.js';
22
22
  export type { Accessibility, AccessibleId, AccessibleNode, AnnouncementKind, CellPlace, ListPosition, Shortcuts } from './services/accessibility.js';
23
23
  export type { Heading, Navigation, StyleInfo, Styles } from './services/navigation.js';
24
24
  export type { Ruler, RulerModel, RulerModelSource, RulerUnit, RulerView, TabAlignment, TabLeader, TabSelector, } from './services/ruler.js';
@@ -37,6 +37,8 @@ export interface PlaceholderInfo {
37
37
  key: string;
38
38
  /** The control it is in. */
39
39
  element: ElementId | null;
40
+ /** The input block's button pressed (its id), or `replace` from a filled block's tab; absent: the block itself. */
41
+ action?: string;
40
42
  }
41
43
  /** {@link Elements} on a mounted editor: adds drop targets and hit testing. */
42
44
  export interface MountedElements extends Elements {
@@ -91,6 +93,17 @@ export interface ReferenceRule {
91
93
  /** The building block gallery (`custom1`), when it matters. */
92
94
  gallery?: string;
93
95
  }
96
+ /** A sub-template's version, as its card and its shown body's tab show it (`setSubTemplateVersions`). */
97
+ export interface SubTemplateVersion {
98
+ /** The sub-template's name. */
99
+ name: string;
100
+ /** Its category. Default: the first reference rule's. */
101
+ category?: string;
102
+ /** The version text (`v4`). */
103
+ version: string;
104
+ /** A newer version's notice (`v5 available`); a press on it raises `subTemplateUpdateRequested`. */
105
+ newer?: string;
106
+ }
94
107
  /** Whether a reference's sub-template resolves, or why its body can't show. */
95
108
  export type ReferenceResolution = 'resolved' | 'missing' | 'nearMatch' | 'cycle' | 'tooDeep' | 'notAlone' | 'notInBody';
96
109
  /** What a sub-template reference field names and whether its body shows. */
@@ -31,6 +31,12 @@ export interface View {
31
31
  setAppearance(appearance: DocumentAppearance): Promise<void>;
32
32
  /** How much the editor measures while you drag and hover. `setViewOptions` with `detail`. */
33
33
  setDetail(detail: MeasureDetail): Promise<void>;
34
+ /**
35
+ * Draws placeholders as editor UI (field marks, repeating sections, sub-template cards and input blocks), with the
36
+ * `placeholderHovered` and `placeholderSelected` events; never changes the output. `setViewOptions` with
37
+ * `placeholderUi`.
38
+ */
39
+ setPlaceholderUi(on: boolean): Promise<void>;
34
40
  /** The pages on screen, for a page navigator or a thumbnails strip. */
35
41
  visiblePages(): {
36
42
  page: number;
@@ -71,6 +77,8 @@ export interface ViewOptions {
71
77
  detail?: MeasureDetail;
72
78
  /** When the dot grid objects snap to shows (unrelated to `gridlines`, the table gridlines). */
73
79
  objectGrid?: ObjectGrid;
80
+ /** Draws placeholders as editor UI: field marks, repeating sections, sub-template cards and input blocks. Default: off. */
81
+ placeholderUi?: boolean;
74
82
  }
75
83
  /**
76
84
  * The editor chrome's colour scheme: the desk, rulers, handles, guides and readouts. `highContrast` takes the
package/dist/state.d.ts CHANGED
@@ -570,6 +570,8 @@ export interface ViewState {
570
570
  detail: MeasureDetail;
571
571
  /** When the objects' dot grid shows. */
572
572
  objectGrid: ObjectGrid;
573
+ /** Placeholders are drawn as editor UI (`placeholderUi`). */
574
+ placeholderUi: boolean;
573
575
  /** Which fields are sub-template references (`setSubTemplateRules`); absent when none are. */
574
576
  subTemplateRules?: ReferenceRule[];
575
577
  }
@@ -127,7 +127,7 @@ export function decodeEvent(wire) {
127
127
  return { type, event: 'value' in fields ? fields.value : fields };
128
128
  }
129
129
  /** The events whose payload always travels as `value`, an object or not: the engine's optional payloads. */
130
- const valueEvents = new Set(['tooltip']);
130
+ const valueEvents = new Set(['tooltip', 'placeholderHovered', 'placeholderSelected']);
131
131
  /** The inverse of {@link decodeEvent}. */
132
132
  export function encodeEvent(type, event) {
133
133
  if (event instanceof EditorError)
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twip/web",
3
- "version": "0.0.0-canary-abcb2d5",
3
+ "version": "0.0.0-canary-6f0bf0b",
4
4
  "description": "The Twip DOCX editor for the browser and Node: a managed, framework-independent editor over the WebAssembly engine.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",