@bloklabs/angular 1.6.2 → 1.8.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.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bloklabs/angular",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "Angular block editor — official Angular bindings for Blok, the headless Notion-like rich text editor. Standalone components that render blocks and save to JSON (APF partial-Ivy bundle).",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "JackUait",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"@angular/common": ">=20 <23",
|
|
37
37
|
"@angular/core": ">=20 <23",
|
|
38
38
|
"@angular/forms": ">=20 <23",
|
|
39
|
-
"@bloklabs/core": "1.
|
|
39
|
+
"@bloklabs/core": "1.8.0"
|
|
40
40
|
},
|
|
41
41
|
"module": "fesm2022/bloklabs-angular.mjs",
|
|
42
42
|
"typings": "./index.d.ts",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { AfterViewInit, EventEmitter, OnDestroy, InjectionToken, EnvironmentProviders, Type, Signal, ElementRef } from '@angular/core';
|
|
2
|
+
import { AfterViewInit, DoCheck, EventEmitter, OnDestroy, InjectionToken, EnvironmentProviders, Type, Signal, ElementRef } from '@angular/core';
|
|
3
3
|
import { ControlValueAccessor } from '@angular/forms';
|
|
4
|
-
import { BlokConfig, EditorWidth, Blok, OutputData, API, BlockMutationEvent, ResolvedTheme, BlocksRenderedPayload, BlockRenderedPayload, OutputBlockData, ThemeMode, LooseOutputData, BlockToolData, BlockTuneData, MarkdownImportConfig, ToolboxConfig, BlockAPI, BlockToolConstructorOptions } from '@bloklabs/core';
|
|
4
|
+
import { BlokConfig, EditorWidth, Blok, OutputData, API, BlockMutationEvent, ResolvedTheme, BlocksRenderedPayload, BlockRenderedPayload, OutputBlockData, ThemeMode, LooseOutputData, BlockToolData, BlockTuneData, MarkdownImportConfig, BlockOrigin, BlockToolConstructable, ToolboxConfig, BlockAPI, BlockToolConstructorOptions } from '@bloklabs/core';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Configuration for the Angular adapter. Same as `BlokConfig` but without
|
|
@@ -26,15 +26,15 @@ type BlokAngularConfig = Omit<BlokConfig, 'holder'> & {
|
|
|
26
26
|
* `styleTokens` through `editor.tokens.set()` (replace semantics),
|
|
27
27
|
* `i18n` through `editor.i18n.update()` (deep-equal–deduped; seeded at
|
|
28
28
|
* construction so the locale resolves during boot) and `data`
|
|
29
|
-
* through `editor.render()` (
|
|
30
|
-
* construction.
|
|
29
|
+
* through `editor.render()` (content-deduped via `equalsOutputData`); everything
|
|
30
|
+
* else seeds construction.
|
|
31
31
|
*
|
|
32
32
|
* Implementation note: classic `@Input()`/`@ViewChild()` decorators are used
|
|
33
33
|
* (not signal `input()`/`viewChild()`) for JIT compatibility — see
|
|
34
34
|
* `BlokContentDirective`. Each reactive input is backed by an internal `signal`
|
|
35
35
|
* so effect-based syncing still works; the public template API is unchanged.
|
|
36
36
|
*/
|
|
37
|
-
declare class BlokEditorComponent implements AfterViewInit, ControlValueAccessor {
|
|
37
|
+
declare class BlokEditorComponent implements AfterViewInit, DoCheck, ControlValueAccessor {
|
|
38
38
|
private readonly ngZone;
|
|
39
39
|
/** App-wide defaults from `provideBlok()`; merged UNDER per-instance inputs. */
|
|
40
40
|
private readonly defaults;
|
|
@@ -124,9 +124,12 @@ declare class BlokEditorComponent implements AfterViewInit, ControlValueAccessor
|
|
|
124
124
|
/** Changing this input's identity destroys and recreates the editor (≙ React `deps`). */
|
|
125
125
|
recreateKey: unknown;
|
|
126
126
|
/**
|
|
127
|
-
* Content the editor currently reflects. Set when seeded
|
|
128
|
-
*
|
|
129
|
-
*
|
|
127
|
+
* Content the editor currently reflects. Set when seeded, when the data effect
|
|
128
|
+
* renders, when the editor emits its own output (`coreOnSave`) and when the
|
|
129
|
+
* imperative `render()` facade lands. A controlled `data` echo that
|
|
130
|
+
* content-equals this baseline is a no-op, so it won't clobber the caret.
|
|
131
|
+
* Renders are serialized via `renderChain`. `undefined` means "nothing recorded
|
|
132
|
+
* yet" — never an empty document.
|
|
130
133
|
*/
|
|
131
134
|
private lastRenderedData?;
|
|
132
135
|
/** Last token set pushed through `tokens.set`, for deep-equal deduping. */
|
|
@@ -148,8 +151,40 @@ declare class BlokEditorComponent implements AfterViewInit, ControlValueAccessor
|
|
|
148
151
|
* it straight back into `data` deep-equals the baseline and is deduped to a
|
|
149
152
|
* no-op (no redundant render, no caret reset). Re-enters the Angular zone since
|
|
150
153
|
* the editor runs outside it.
|
|
154
|
+
*
|
|
155
|
+
* Falls back to an escape-hatch `[config]` callback when nothing Angular-side
|
|
156
|
+
* consumes the save — the baseline is recorded either way, so the controlled
|
|
157
|
+
* `data` dedupe works on both paths.
|
|
151
158
|
*/
|
|
152
159
|
private readonly coreOnSave;
|
|
160
|
+
/**
|
|
161
|
+
* Stable wrappers for the remaining live callbacks. Each resolves its target
|
|
162
|
+
* at call time (an observed output, else the `[config]` escape hatch), so a
|
|
163
|
+
* pushed handler never goes stale and only PRESENCE has to be synced.
|
|
164
|
+
*/
|
|
165
|
+
private readonly coreOnChange;
|
|
166
|
+
private readonly coreOnAfterRender;
|
|
167
|
+
private readonly coreOnBeforeRender;
|
|
168
|
+
private readonly coreOnEnter;
|
|
169
|
+
private readonly coreOnSubmit;
|
|
170
|
+
/** provideBlok defaults merged under the `[config]` escape hatch. */
|
|
171
|
+
private escapeHatchConfig;
|
|
172
|
+
/** True when an output, a two-way binding or Angular forms consumes `onSave`. */
|
|
173
|
+
private hasSaveConsumer;
|
|
174
|
+
/**
|
|
175
|
+
* The live callbacks this component currently wires into core, keyed by
|
|
176
|
+
* handler name — `undefined` for the ones nothing consumes.
|
|
177
|
+
*
|
|
178
|
+
* PRESENCE is the semantics in core (an `onSubmit` turns Enter into
|
|
179
|
+
* serialize-and-submit, an `onSave` arms the change-observation pipeline), so
|
|
180
|
+
* an unconsumed callback must stay absent. One source of truth for both the
|
|
181
|
+
* construction config and the runtime sync in `ngDoCheck`, so the two cannot
|
|
182
|
+
* drift.
|
|
183
|
+
* @returns the wrappers to install, `undefined` where nothing is wired
|
|
184
|
+
*/
|
|
185
|
+
private liveHandlers;
|
|
186
|
+
/** Handler presence installed on the live editor (the sync dedupe baseline). */
|
|
187
|
+
private appliedHandlers;
|
|
153
188
|
/** Live Blok instance, or null until `isReady` resolves / after destroy. */
|
|
154
189
|
readonly instance: i0.Signal<Blok | null>;
|
|
155
190
|
/** Guards `ready` to one emission per editor instance. */
|
|
@@ -161,11 +196,38 @@ declare class BlokEditorComponent implements AfterViewInit, ControlValueAccessor
|
|
|
161
196
|
*/
|
|
162
197
|
buildConfig(): Partial<BlokAngularConfig>;
|
|
163
198
|
ngAfterViewInit(): void;
|
|
199
|
+
/**
|
|
200
|
+
* Reactive callback presence.
|
|
201
|
+
*
|
|
202
|
+
* Callback wiring was decided once, at construction, and in core the presence
|
|
203
|
+
* of a handler IS the semantics: an `onSubmit` makes Enter serialize-and-submit
|
|
204
|
+
* instead of splitting the block, an `onSave` arms the whole change-observation
|
|
205
|
+
* pipeline. A `[config]` swap, an `*ngIf`-gated `(save)` output or a
|
|
206
|
+
* `registerOnChange` from Angular forms arriving after mount therefore needed a
|
|
207
|
+
* `recreateKey` bump — destroying the editor and losing caret and undo history.
|
|
208
|
+
*
|
|
209
|
+
* Diff the wired handlers against what is installed and push genuine flips
|
|
210
|
+
* through the runtime `handlers.set` API, writing `undefined` for a handler
|
|
211
|
+
* that lost its consumer so the change stays reversible. `ngDoCheck` (not an
|
|
212
|
+
* `effect`) because `EventEmitter.observed` and the plain `@Input` transforms
|
|
213
|
+
* are not signals; the comparison is six identity checks against stable
|
|
214
|
+
* wrappers, so an unchanged cycle pushes nothing.
|
|
215
|
+
*/
|
|
216
|
+
ngDoCheck(): void;
|
|
164
217
|
/** Serialize the current content. Resolves undefined until the editor is ready. */
|
|
165
218
|
save$(): Promise<OutputData> | undefined;
|
|
166
219
|
/** Move the caret into the editor. */
|
|
167
220
|
focus(atEnd?: boolean): void;
|
|
168
|
-
/**
|
|
221
|
+
/**
|
|
222
|
+
* Replace the editor content. Resolves undefined until the editor is ready.
|
|
223
|
+
*
|
|
224
|
+
* Safe to mix with a controlled `[data]` input: the rendered document becomes
|
|
225
|
+
* the content baseline once the call lands, so a later `[data]` change back to
|
|
226
|
+
* the previous document still re-renders instead of being deduped against a
|
|
227
|
+
* baseline the editor no longer reflects. Recorded only on the resolved path —
|
|
228
|
+
* a failed render leaves the editor on its previous content.
|
|
229
|
+
* @param data - the document to render
|
|
230
|
+
*/
|
|
169
231
|
render(data: OutputData | LooseOutputData): Promise<void> | undefined;
|
|
170
232
|
constructor();
|
|
171
233
|
/** Seeds/renders an externally-set form value through the same dedup machinery. */
|
|
@@ -597,6 +659,37 @@ interface PropSchemaEntry {
|
|
|
597
659
|
*/
|
|
598
660
|
type PropSchema = Record<string, PropSchemaEntry>;
|
|
599
661
|
|
|
662
|
+
/**
|
|
663
|
+
* Every STATIC member of core's block-tool contract an Angular block may declare
|
|
664
|
+
* for itself — `ownsChildren`, `keepsChildrenOnEnter`, `conversionConfig`,
|
|
665
|
+
* `pasteConfig`, `sanitize`, `shortcut`, `upgradeData`, and whatever core adds
|
|
666
|
+
* next. Derived from
|
|
667
|
+
* `BlockToolConstructable` rather than enumerated, so a new core static needs no
|
|
668
|
+
* adapter change to become reachable.
|
|
669
|
+
*
|
|
670
|
+
* `toolbox` and `isReadOnlySupported` are excluded because the factory owns
|
|
671
|
+
* them: `toolbox` is authored as {@link CreateAngularBlockSpec.toolbox}, and
|
|
672
|
+
* in-place read-only support is unconditional.
|
|
673
|
+
*/
|
|
674
|
+
type BlockToolStatics = Omit<BlockToolConstructable, 'toolbox' | 'isReadOnlySupported'>;
|
|
675
|
+
/**
|
|
676
|
+
* Second argument of {@link CreateAngularBlockSpec.onMounted} and
|
|
677
|
+
* {@link CreateAngularBlockSpec.onCreated} — everything the block cannot read
|
|
678
|
+
* off its own `BlockAPI`.
|
|
679
|
+
*/
|
|
680
|
+
interface AngularBlockMountedContext {
|
|
681
|
+
/**
|
|
682
|
+
* Why this block instance was constructed: a CREATION origin (`user`, `api`,
|
|
683
|
+
* `convert`) means the author just made it, so seeding default children is
|
|
684
|
+
* correct; a RESTORE origin (`load`, `replay`, `paste`) means the document
|
|
685
|
+
* already says what the children are. `probe` is an off-tree instance built
|
|
686
|
+
* only to read a tool's default data — it must not touch the block tree at
|
|
687
|
+
* all. Defaults to `'api'` when the constructor was handed no origin.
|
|
688
|
+
*/
|
|
689
|
+
origin: BlockOrigin;
|
|
690
|
+
/** The editor-level API (`api.blocks`, `api.caret`, `api.events`…). */
|
|
691
|
+
api: API;
|
|
692
|
+
}
|
|
600
693
|
/** Spec for {@link createAngularBlock}. Authored as a standalone component. */
|
|
601
694
|
interface CreateAngularBlockSpec<Data = BlockToolData> {
|
|
602
695
|
/** Tool type name (registered key). */
|
|
@@ -610,8 +703,90 @@ interface CreateAngularBlockSpec<Data = BlockToolData> {
|
|
|
610
703
|
* per-block context via `inject(BLOK_BLOCK_CONTEXT)`.
|
|
611
704
|
*/
|
|
612
705
|
component: Type<unknown>;
|
|
706
|
+
/**
|
|
707
|
+
* Static members of core's tool contract, forwarded verbatim onto the
|
|
708
|
+
* generated tool class — the single channel for everything core reads off the
|
|
709
|
+
* CLASS rather than the instance (`ownsChildren`, `keepsChildrenOnEnter`,
|
|
710
|
+
* `conversionConfig`, `pasteConfig`, `sanitize`, `shortcut`, `upgradeData`…).
|
|
711
|
+
* Without it the only way to declare one was to subclass the generated class.
|
|
712
|
+
*
|
|
713
|
+
* `keepsChildrenOnEnter` is the per-tool Enter POLICY: declare it and Enter on
|
|
714
|
+
* this container's empty LAST child creates the new line INSIDE the container
|
|
715
|
+
* instead of escaping to the container's parent (Blok's default, which is
|
|
716
|
+
* Notion's callout behaviour). Core cannot read that off the DOM — a callout
|
|
717
|
+
* renders the same `data-blok-nested-blocks` slot as a column yet wants the
|
|
718
|
+
* escape — so before it existed a layout container (a card, a `steps` block)
|
|
719
|
+
* had to hijack the editor-global `config.onEnter` and re-derive containment.
|
|
720
|
+
*
|
|
721
|
+
* `toolbox` and `isReadOnlySupported` are owned by the factory and cannot be
|
|
722
|
+
* overridden here (see {@link BlockToolStatics}).
|
|
723
|
+
*/
|
|
724
|
+
statics?: BlockToolStatics;
|
|
725
|
+
/**
|
|
726
|
+
* The element the +/drag toolbar should vertically center on — core's
|
|
727
|
+
* `getToolbarAnchorElement` hook, resolved against this block's host element
|
|
728
|
+
* on every call (never cached, so it tracks re-renders).
|
|
729
|
+
*
|
|
730
|
+
* A container block whose own chrome is not editable needs it: with no anchor,
|
|
731
|
+
* core centers the toolbar on the first `[contenteditable]` under the host,
|
|
732
|
+
* which for a container is its FIRST CHILD BLOCK. Return `null`/`undefined`
|
|
733
|
+
* (or omit the field) to keep core's default.
|
|
734
|
+
* @param host - this block's mutation-free host element
|
|
735
|
+
* @param block - this block's per-block API
|
|
736
|
+
*/
|
|
737
|
+
getToolbarAnchorElement?: (host: HTMLElement, block: BlockAPI) => HTMLElement | null | undefined;
|
|
613
738
|
/** Optional lifecycle callbacks mapped from Blok's block hooks. */
|
|
614
739
|
onRendered?: (block: BlockAPI) => void;
|
|
740
|
+
/**
|
|
741
|
+
* Fired ONCE per block instance, once the component's DOM (and, for a
|
|
742
|
+
* container, the child holders its `ctx.mountChildren` adopted) exists.
|
|
743
|
+
* Angular mounts the block synchronously while core is still inside
|
|
744
|
+
* `render()`, so this lands with `rendered()` — the first hook at which the
|
|
745
|
+
* host is also in the document. The React and Vue adapters spell the same
|
|
746
|
+
* contract; there it is genuinely LATER than `onRendered`, because their
|
|
747
|
+
* portals commit a frame after core returns.
|
|
748
|
+
*
|
|
749
|
+
* It is also the create-vs-restore signal: `context.origin` says whether the
|
|
750
|
+
* author just made this block (`user`/`api`/`convert`) or the document is
|
|
751
|
+
* being re-materialised (`load`/`replay`/`paste`) — so a container can seed
|
|
752
|
+
* its default children here exactly once, without the "children are
|
|
753
|
+
* transiently empty during a replay" trap.
|
|
754
|
+
* @example
|
|
755
|
+
* ```ts
|
|
756
|
+
* onMounted: (block, { origin, api }) => {
|
|
757
|
+
* if (origin === 'user' && block.getChildren().length === 0) {
|
|
758
|
+
* api.blocks.insertInsideParent(block.id);
|
|
759
|
+
* }
|
|
760
|
+
* }
|
|
761
|
+
* ```
|
|
762
|
+
*/
|
|
763
|
+
onMounted?: (block: BlockAPI, context: AngularBlockMountedContext) => void;
|
|
764
|
+
/**
|
|
765
|
+
* The SEEDING hook: `onMounted`, narrowed to a genuine creation. Fired ONCE
|
|
766
|
+
* per block instance, once the component's DOM exists, and only when this
|
|
767
|
+
* instance is the author making a new block (`origin` of `user`, `api` or
|
|
768
|
+
* `convert`) — never for a `load`/`replay`/`paste` restore, and never for the
|
|
769
|
+
* off-tree `probe` instance core builds to read a tool's default data.
|
|
770
|
+
*
|
|
771
|
+
* That predicate is why the hook exists rather than leaving every block to
|
|
772
|
+
* read `context.origin` in `onMounted`: the intuitive `origin === 'user'` test
|
|
773
|
+
* is wrong. It drops `api.blocks.insert('steps')` and turn-into, so a
|
|
774
|
+
* container seeded that way comes up empty for every path except a keystroke.
|
|
775
|
+
* Core refused to ship that axis into its own `column`/`column_list`; this
|
|
776
|
+
* encodes the correct one once, here.
|
|
777
|
+
*
|
|
778
|
+
* The `context` is the same object {@link CreateAngularBlockSpec.onMounted}
|
|
779
|
+
* receives, so a block that only seeds can read `origin` for finer decisions.
|
|
780
|
+
* @example
|
|
781
|
+
* ```ts
|
|
782
|
+
* onCreated: (block, { api }) => {
|
|
783
|
+
* if (block.getChildren().length === 0) {
|
|
784
|
+
* api.blocks.insertInsideParent(block.id);
|
|
785
|
+
* }
|
|
786
|
+
* }
|
|
787
|
+
* ```
|
|
788
|
+
*/
|
|
789
|
+
onCreated?: (block: BlockAPI, context: AngularBlockMountedContext) => void;
|
|
615
790
|
onMoved?: (block: BlockAPI) => void;
|
|
616
791
|
onRemoved?: (block: BlockAPI) => void;
|
|
617
792
|
}
|
|
@@ -636,11 +811,12 @@ declare function createAngularBlock<Data = BlockToolData>(spec: CreateAngularBlo
|
|
|
636
811
|
save(): BlockToolData;
|
|
637
812
|
setData(newData: BlockToolData): Promise<boolean>;
|
|
638
813
|
setReadOnly(state: boolean): void;
|
|
814
|
+
getToolbarAnchorElement(): HTMLElement | undefined;
|
|
639
815
|
rendered(): void;
|
|
640
816
|
moved(): void;
|
|
641
817
|
removed(): void;
|
|
642
818
|
destroy(): void;
|
|
643
|
-
}) & {
|
|
819
|
+
}) & BlockToolStatics & {
|
|
644
820
|
readonly __isBlokAngularBlock: true;
|
|
645
821
|
readonly toolbox: ToolboxConfig | undefined;
|
|
646
822
|
readonly isReadOnlySupported: boolean;
|
|
@@ -723,6 +899,14 @@ interface InjectBlokReadyOptions {
|
|
|
723
899
|
*/
|
|
724
900
|
declare function injectBlokReady(options?: InjectBlokReadyOptions): Signal<boolean>;
|
|
725
901
|
|
|
902
|
+
/**
|
|
903
|
+
* One child's decoration: attribute name → value. `null`/`undefined` removes the
|
|
904
|
+
* attribute; a boolean or number is stringified (so `false` writes
|
|
905
|
+
* `data-active="false"`, which CSS can select, rather than dropping the hook).
|
|
906
|
+
*/
|
|
907
|
+
type ChildAttributes = Record<string, string | number | boolean | null | undefined>;
|
|
908
|
+
/** The per-child decorator accepted by {@link AngularBlockRenderContext.mountChildren}. */
|
|
909
|
+
type ChildAttributesFn = (child: BlockAPI, index: number) => ChildAttributes;
|
|
726
910
|
/**
|
|
727
911
|
* Context handed to a `createAngularBlock` component. Delivered via DI (the
|
|
728
912
|
* BLOK_BLOCK_CONTEXT token) rather than @Input, because core constructs the tool
|
|
@@ -736,6 +920,17 @@ interface AngularBlockRenderContext<Data> {
|
|
|
736
920
|
commit: (patch: Partial<Data>) => void;
|
|
737
921
|
/** This block's per-block API (id, getChildren, dispatchChange…). */
|
|
738
922
|
block: BlockAPI;
|
|
923
|
+
/**
|
|
924
|
+
* The EDITOR-level API this block belongs to (`api.blocks`, `api.caret`,
|
|
925
|
+
* `api.toolbar`…) — the same object a vanilla tool receives in its
|
|
926
|
+
* constructor. Reach for it when a block has to drive the document around it
|
|
927
|
+
* instead of routing everything through `block.call()` string dispatch.
|
|
928
|
+
*
|
|
929
|
+
* For the reactive, id/parentId-relative view of the tree (and to re-render
|
|
930
|
+
* when your own children change), pair `injectBlocks` with
|
|
931
|
+
* `injectBlokInstance()` instead — the api handle itself is not reactive.
|
|
932
|
+
*/
|
|
933
|
+
api: API;
|
|
739
934
|
/**
|
|
740
935
|
* Reactive read-only flag. Read `readOnly()` in the template to disable
|
|
741
936
|
* editing (drop `contenteditable`, hide controls). Toggled IN PLACE by core's
|
|
@@ -749,11 +944,57 @@ interface AngularBlockRenderContext<Data> {
|
|
|
749
944
|
* (a `data-blok-nested` element the author owns). Call it once in
|
|
750
945
|
* `ngAfterViewInit`; the factory re-runs the same mount on every data change
|
|
751
946
|
* so late-added children appear. Angular must NOT manage these child holders.
|
|
947
|
+
*
|
|
948
|
+
* `childAttributes` decorates each child's HOLDER after the holders are
|
|
949
|
+
* mounted, and is REMEMBERED — every later remount re-applies it. Named hooks
|
|
950
|
+
* (`data-step-index`, `data-active`…) replace positional `:nth-child()` CSS
|
|
951
|
+
* over Blok's holders, which breaks the moment a child is inserted, removed or
|
|
952
|
+
* reordered. The holders stay DIRECT children of `host` — core requires that
|
|
953
|
+
* (hierarchy reparenting and caret navigation compare `holder.parentElement`
|
|
954
|
+
* by identity), so decoration is attributes, never wrapper elements.
|
|
955
|
+
* Attributes the callback stops producing are removed on the next pass.
|
|
956
|
+
*
|
|
957
|
+
* Writing on a child's holder is inert by design: core's mutation filter drops
|
|
958
|
+
* a holder-targeted attribute record for the child block and suppresses it for
|
|
959
|
+
* the container. The guarantee stops at the holder and its
|
|
960
|
+
* `[data-blok-element-content]` wrapper — writing AT or BELOW a child's tool
|
|
961
|
+
* root DOES score as that child's edit.
|
|
752
962
|
*/
|
|
753
|
-
mountChildren: (host: HTMLElement) => void;
|
|
963
|
+
mountChildren: (host: HTMLElement, childAttributes?: ChildAttributesFn) => void;
|
|
754
964
|
}
|
|
755
965
|
/** DI token carrying the per-block render context into the authored component. */
|
|
756
966
|
declare const BLOK_BLOCK_CONTEXT: InjectionToken<AngularBlockRenderContext<unknown>>;
|
|
757
967
|
|
|
758
|
-
|
|
759
|
-
|
|
968
|
+
/**
|
|
969
|
+
* DI token carrying the LIVE editor instance (as a signal) into every block
|
|
970
|
+
* mounted by `createAngularBlock`. `BlokContentDirective` publishes its own
|
|
971
|
+
* `instance` signal through it, so the value is null before the editor is ready
|
|
972
|
+
* and after teardown — matching the React/Vue adapters' pre-ready contract.
|
|
973
|
+
*
|
|
974
|
+
* Provided on the block's ELEMENT injector by the portal registry, so it is
|
|
975
|
+
* per-EDITOR: two editors on one page each publish their own instance.
|
|
976
|
+
*/
|
|
977
|
+
declare const BLOK_EDITOR_INSTANCE: InjectionToken<Signal<Blok | null>>;
|
|
978
|
+
/**
|
|
979
|
+
* The live Blok instance the component is mounted inside, as a signal, or a
|
|
980
|
+
* signal of null before it exists. Inside a `createAngularBlock` component this
|
|
981
|
+
* is the block's OWN editor — so a block can drive the tree it lives in without
|
|
982
|
+
* the host prop-drilling the instance into it:
|
|
983
|
+
*
|
|
984
|
+
* ```ts
|
|
985
|
+
* private readonly editor = injectBlokInstance();
|
|
986
|
+
* private readonly blocks = injectBlocks(this.editor);
|
|
987
|
+
* ```
|
|
988
|
+
*
|
|
989
|
+
* That pairing is also what makes a container block REACTIVE to its own child
|
|
990
|
+
* tree: `injectBlocks` refreshes on the editor's `block changed` event, which
|
|
991
|
+
* core emits for every structural mutation — including children the adapter
|
|
992
|
+
* itself never sees (a pasted paragraph, a Tab-indent from the keyboard).
|
|
993
|
+
*
|
|
994
|
+
* Call it in an injection context (a field initializer or the constructor).
|
|
995
|
+
* Outside an editor it returns a signal of null.
|
|
996
|
+
*/
|
|
997
|
+
declare function injectBlokInstance(): Signal<Blok | null>;
|
|
998
|
+
|
|
999
|
+
export { BLOK_BLOCK_CONTEXT, BLOK_DEFAULT_CONFIG, BLOK_EDITOR_INSTANCE, BlokContentDirective, BlokEditorComponent, createAngularBlock, injectBlocks, injectBlokInstance, injectBlokReady, provideBlok };
|
|
1000
|
+
export type { AngularBlockMountedContext, AngularBlockRenderContext, BlockNode, BlockToolStatics, BlokAngularConfig, BlokReadyScope, CaretTarget, ChildAttributes, ChildAttributesFn, CreateAngularBlockSpec, InjectBlokReadyOptions, InsertPosition, InsertSpec, MoveTarget, PropSchema, PropSchemaEntry, TreeInsertSpec, UseBlocksApi };
|