@bloklabs/angular 1.16.0 → 2.0.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/README.md +12 -0
- package/fesm2022/bloklabs-angular.mjs +330 -15
- package/package.json +2 -2
- package/types/bloklabs-angular.d.ts +76 -755
- package/fesm2022/bloklabs-angular.mjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as i0 from "@angular/core";
|
|
2
|
-
import { AfterViewInit, DoCheck, ElementRef, EnvironmentProviders, EventEmitter, InjectionToken, OnDestroy, Signal, Type } from "@angular/core";
|
|
2
|
+
import { AfterViewInit, DoCheck, ElementRef, EnvironmentProviders, EventEmitter, InjectionToken, OnChanges, OnDestroy, Signal, SimpleChanges, Type } from "@angular/core";
|
|
3
3
|
import { ControlValueAccessor } from "@angular/forms";
|
|
4
|
-
import { API, BlockAPI, BlockMutationEvent, BlockOrigin, BlockPosition, BlockRenderedPayload, BlockToolConstructable, BlockToolConstructorOptions, BlockToolData, BlockTuneData, BlocksRenderedPayload, Blok, BlokConfig, EditorWidth,
|
|
4
|
+
import { API, BlockAPI, BlockMutationEvent, BlockOrigin, BlockPosition, BlockRenderedPayload, BlockToolConstructable, BlockToolConstructorOptions, BlockToolData, BlockTuneData, BlocksRenderedPayload, Blok, BlokConfig, EditorWidth, LooseOutputData, MarkdownImportConfig, OutputBlockData, OutputData, ResolvedTheme, ThemeMode, ToolboxConfig } from "@bloklabs/core";
|
|
5
5
|
/**
|
|
6
6
|
* Configuration for the Angular adapter. Same as `BlokConfig` but without
|
|
7
7
|
* `holder` (the adapter owns the host element), plus the reactive `width` prop.
|
|
@@ -364,12 +364,6 @@ export declare class BlokEditorComponent implements AfterViewInit, DoCheck, OnDe
|
|
|
364
364
|
"blockRendered": "blockRendered";
|
|
365
365
|
}, never, never, true, never>;
|
|
366
366
|
}
|
|
367
|
-
/**
|
|
368
|
-
* The `collaboration` the given editor was constructed with.
|
|
369
|
-
* @param editor - a Blok instance built by `BlokContentDirective`
|
|
370
|
-
* @returns the mount-time collaboration config, `undefined` when there was none
|
|
371
|
-
*/
|
|
372
|
-
declare function getConstructedCollaboration(editor: WeakKey): BlokAngularConfig['collaboration'];
|
|
373
367
|
/**
|
|
374
368
|
* Escape-hatch directive and lifecycle engine for Blok (mirrors React's
|
|
375
369
|
* `useBlok` + `BlokContent`). Constructs a Blok instance into its own host
|
|
@@ -434,6 +428,29 @@ export declare class BlokContentDirective implements OnDestroy {
|
|
|
434
428
|
"ready": "ready";
|
|
435
429
|
}, never, never, true, never>;
|
|
436
430
|
}
|
|
431
|
+
/**
|
|
432
|
+
* Places the editor's page title in this element, through `editor.title.mount`.
|
|
433
|
+
* The editor needs `pageTitle` set; this only moves the title.
|
|
434
|
+
* On destroy the title goes back above the first block. Projected content is not rendered.
|
|
435
|
+
*
|
|
436
|
+
* ```html
|
|
437
|
+
* <blok-title [editor]="ed.instance()"></blok-title>
|
|
438
|
+
* <blok-editor #ed="blok" [config]="{ pageTitle: true }"></blok-editor>
|
|
439
|
+
* ```
|
|
440
|
+
*/
|
|
441
|
+
export declare class BlokTitleComponent implements OnChanges, OnDestroy {
|
|
442
|
+
private readonly host;
|
|
443
|
+
editor: Blok | null;
|
|
444
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
445
|
+
ngOnDestroy(): void;
|
|
446
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<BlokTitleComponent, never>;
|
|
447
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<BlokTitleComponent, "blok-title", never, {
|
|
448
|
+
"editor": {
|
|
449
|
+
"alias": "editor";
|
|
450
|
+
"required": false;
|
|
451
|
+
};
|
|
452
|
+
}, {}, never, never, true, never>;
|
|
453
|
+
}
|
|
437
454
|
/**
|
|
438
455
|
* DI token holding app-wide Blok defaults (shared tools registry, default theme,
|
|
439
456
|
* i18n). Merged under per-instance inputs by `BlokEditorComponent`.
|
|
@@ -512,6 +529,20 @@ interface InsertSpec {
|
|
|
512
529
|
*/
|
|
513
530
|
caret?: CaretTarget;
|
|
514
531
|
}
|
|
532
|
+
/** Spec for {@link UseBlocksApi.create}. */
|
|
533
|
+
interface CreateSpec {
|
|
534
|
+
type?: string;
|
|
535
|
+
data?: BlockToolData;
|
|
536
|
+
/** `null` is the root. Omitted: the `before`/`after` sibling's parent, or the root. */
|
|
537
|
+
parentId?: string | null;
|
|
538
|
+
/** Defaults to `'end'`. */
|
|
539
|
+
position?: InsertPosition;
|
|
540
|
+
id?: string;
|
|
541
|
+
tunes?: {
|
|
542
|
+
[name: string]: BlockTuneData;
|
|
543
|
+
};
|
|
544
|
+
focus?: boolean;
|
|
545
|
+
}
|
|
515
546
|
/**
|
|
516
547
|
* One node of a pre-built nested subtree for {@link UseBlocksApi.insertTree}.
|
|
517
548
|
*
|
|
@@ -618,7 +649,7 @@ interface UseBlocksApi {
|
|
|
618
649
|
*
|
|
619
650
|
* `config` (optional {@link MarkdownImportConfig}) is forwarded to the
|
|
620
651
|
* converter so custom-tool consumers can map markdown nodes into their tools
|
|
621
|
-
* (`toolMap`/`onUnknownNode`)
|
|
652
|
+
* (`toolMap`/`onUnknownNode`) or toggle GFM.
|
|
622
653
|
*
|
|
623
654
|
* Returns ALL created {@link BlockNode}s in document order — including any the
|
|
624
655
|
* markdown nested internally (e.g. a table's cell children), not just the
|
|
@@ -640,9 +671,12 @@ interface UseBlocksApi {
|
|
|
640
671
|
* additive {@link insertMarkdown}). Async: the serializer is lazy-loaded, like
|
|
641
672
|
* the importer. Markdown cannot express every block, so some structure is
|
|
642
673
|
* dropped (table `colspan`/`rowspan`, heading columns). Returns `''` for an
|
|
643
|
-
* empty document. Pre-ready: resolves to `''`.
|
|
674
|
+
* empty document. Pre-ready: resolves to `''`. `title: true` writes the
|
|
675
|
+
* page title first, as core's does.
|
|
644
676
|
*/
|
|
645
|
-
exportMarkdown(
|
|
677
|
+
exportMarkdown(options?: {
|
|
678
|
+
title?: boolean;
|
|
679
|
+
}): Promise<string>;
|
|
646
680
|
move(id: string, target: MoveTarget): void;
|
|
647
681
|
nest(id: string, parentId: string): void;
|
|
648
682
|
unnest(id: string): void;
|
|
@@ -761,6 +795,14 @@ interface UseBlocksApi {
|
|
|
761
795
|
* dep array. Pre-ready: `null`.
|
|
762
796
|
*/
|
|
763
797
|
insertInsideParent(parentId: string, insertIndex: number, childData?: BlockToolData): BlockNode | null;
|
|
798
|
+
/**
|
|
799
|
+
* Add a block the way a toolbox pick does, for a host button such as "New
|
|
800
|
+
* page" — delegates to core's `blocks.create`. Goes to the end of the root
|
|
801
|
+
* unless `parentId`/`position` say otherwise. Resolves `null` for an unknown
|
|
802
|
+
* tool or a place that does not exist; rejects with the tool's
|
|
803
|
+
* `prepareInsert` error, inserting nothing. Pre-ready: `null`.
|
|
804
|
+
*/
|
|
805
|
+
create(spec?: CreateSpec): Promise<BlockNode | null>;
|
|
764
806
|
/**
|
|
765
807
|
* Replace the WHOLE document with blocks parsed from saved {@link OutputData}
|
|
766
808
|
* (the `save()` shape) — delegates to core's `blocks.render`. Unlike
|
|
@@ -784,249 +826,6 @@ interface UseBlocksApi {
|
|
|
784
826
|
*/
|
|
785
827
|
isSyncingFromYjs(): boolean;
|
|
786
828
|
}
|
|
787
|
-
/** The minimal slice of editor.blocks that the snapshot helpers read. */
|
|
788
|
-
interface BlocksReader {
|
|
789
|
-
getBlocksCount(): number;
|
|
790
|
-
getBlockByIndex(index: number): {
|
|
791
|
-
id: string;
|
|
792
|
-
name: string;
|
|
793
|
-
parentId: string | null;
|
|
794
|
-
} | undefined;
|
|
795
|
-
}
|
|
796
|
-
/**
|
|
797
|
-
* Enumerate the editor's blocks once into BlockNode records, in flat order,
|
|
798
|
-
* deriving each node's contentIds from the children that name it as parent.
|
|
799
|
-
*/
|
|
800
|
-
declare const snapshotNodes: (reader: BlocksReader) => BlockNode[];
|
|
801
|
-
/** BlocksReader plus id→flat-index lookup. */
|
|
802
|
-
interface IndexReader extends BlocksReader {
|
|
803
|
-
getBlockIndex(id: string): number | undefined;
|
|
804
|
-
}
|
|
805
|
-
/** Map of block id -> parentId, in flat order. */
|
|
806
|
-
declare const parentMap: (reader: BlocksReader) => Map<string, string | null>;
|
|
807
|
-
/** True if `id` descends from `ancestorId` via the parentId chain. */
|
|
808
|
-
declare const isDescendantOf: (parentOf: Map<string, string | null>, id: string, ancestorId: string) => boolean;
|
|
809
|
-
/**
|
|
810
|
-
* The flat index of the last block in the contiguous subtree rooted at `index`.
|
|
811
|
-
* In flat (DFS) order a block's descendants sit immediately after it, so this
|
|
812
|
-
* walks forward while blocks remain descendants of the block at `index`.
|
|
813
|
-
* Returns `index` itself when the block has no descendants.
|
|
814
|
-
*/
|
|
815
|
-
declare const subtreeEndIndex: (reader: BlocksReader, index: number) => number;
|
|
816
|
-
/**
|
|
817
|
-
* The flat index at which a new block should be inserted.
|
|
818
|
-
*
|
|
819
|
-
* `replace` flips the meaning of a before/after `position`: under replace the
|
|
820
|
-
* ref IS the block being overwritten (a "turn into"), not a sibling anchor, so
|
|
821
|
-
* it resolves to the ref's OWN flat slot regardless of which parent it lives in
|
|
822
|
-
* — bypassing the sibling-relative parent guard that would otherwise redirect a
|
|
823
|
-
* nested target to the requested parent's end and replace the wrong block.
|
|
824
|
-
*/
|
|
825
|
-
declare const resolveInsertIndex: (reader: IndexReader, parentId: string | null, position: InsertPosition, replace?: boolean) => number;
|
|
826
|
-
/** The flat toIndex for editor.blocks.move. */
|
|
827
|
-
declare const resolveMoveIndex: (reader: IndexReader, target: MoveTarget) => number;
|
|
828
|
-
/** Adapt the live editor to the IndexReader the snapshot helpers expect. */
|
|
829
|
-
declare const readerFor: (editor: Blok) => IndexReader;
|
|
830
|
-
/**
|
|
831
|
-
* Stable API returned while the editor is null (before the adapter resolves).
|
|
832
|
-
* Every read returns empty/null and every MUTATOR is a no-op — EXCEPT
|
|
833
|
-
* `transact`/`transactWithoutCapture`, which still invoke their callback so a
|
|
834
|
-
* consumer wrapping conditional work in `transact` still runs that work even
|
|
835
|
-
* pre-ready.
|
|
836
|
-
*/
|
|
837
|
-
declare const EMPTY_API: UseBlocksApi;
|
|
838
|
-
/**
|
|
839
|
-
* Does a `block changed` event touch the subtree rooted at `withinId`?
|
|
840
|
-
*
|
|
841
|
-
* The reactivity filter behind `useBlocks(editor, { within })` in all three
|
|
842
|
-
* adapters. Without it every consumer of `useBlocks` re-renders on every change
|
|
843
|
-
* anywhere in the document — so a container block that only renders its own
|
|
844
|
-
* children still re-rendered on each keystroke in an unrelated block, and a page
|
|
845
|
-
* of N such containers turned one keystroke into N re-renders.
|
|
846
|
-
*
|
|
847
|
-
* INDETERMINATE READS AS "TOUCHED". The walk resolves ancestry through the LIVE
|
|
848
|
-
* tree, and a removal commonly emits after the block is already gone, so its
|
|
849
|
-
* parent chain cannot be read. Answering `false` there would leave a container
|
|
850
|
-
* rendering a child that no longer exists; answering `true` costs one extra
|
|
851
|
-
* render pass. Same for a payload with no readable target.
|
|
852
|
-
*
|
|
853
|
-
* Ancestry is walked UPWARD one `getById` at a time rather than snapshotted with
|
|
854
|
-
* `parentMap`: this runs on every emission — i.e. on every keystroke — so it must
|
|
855
|
-
* cost O(depth), not O(document).
|
|
856
|
-
* @param editor - the live Blok instance
|
|
857
|
-
* @param payload - the `block changed` payload
|
|
858
|
-
* @param withinId - id of the block whose subtree is the scope
|
|
859
|
-
* @returns true when the change is inside the scope (or cannot be placed)
|
|
860
|
-
*/
|
|
861
|
-
declare const changeTouchesSubtree: (editor: Blok, payload: unknown, withinId: string) => boolean;
|
|
862
|
-
/**
|
|
863
|
-
* Build the framework-agnostic, id/parentId-relative block-tree API over a LIVE
|
|
864
|
-
* editor. Mutators route through the editor-level `blocks` API (core's
|
|
865
|
-
* chokepoints), so undo/redo and Yjs sync are inherited rather than
|
|
866
|
-
* re-implemented; readers enumerate the live tree on every call.
|
|
867
|
-
*
|
|
868
|
-
* This is the shared engine behind both the React (`useSyncExternalStore`) and
|
|
869
|
-
* Vue (`shallowRef` version) `useBlocks` wrappers — one implementation so the
|
|
870
|
-
* two adapters cannot drift. Each adapter supplies the `onRead` seam:
|
|
871
|
-
*
|
|
872
|
-
* - React leaves it the default no-op: `useSyncExternalStore` re-renders the
|
|
873
|
-
* whole component on `block changed`, and the reads run live during that
|
|
874
|
-
* render, so no per-call dependency tracking is needed.
|
|
875
|
-
* - Vue passes `() => { void version.value }` so a read inside a `computed` /
|
|
876
|
-
* template touches the reactive version ref and re-runs on every structural
|
|
877
|
-
* mutation.
|
|
878
|
-
*
|
|
879
|
-
* `onRead` is invoked at the top of every read method; mutators never call it.
|
|
880
|
-
* The editor MUST be the raw (non-proxied) instance — adapters `toRaw`-unwrap
|
|
881
|
-
* before calling, so a Vue reactive proxy never reaches core (Risk R0).
|
|
882
|
-
*
|
|
883
|
-
* @param editor - the live Blok instance (never null; callers gate on EMPTY_API)
|
|
884
|
-
* @param onRead - reactivity seam called at the start of each read (default no-op)
|
|
885
|
-
*/
|
|
886
|
-
declare const createBlocksApiForEditor: (editor: Blok, onRead?: () => void) => UseBlocksApi;
|
|
887
|
-
/**
|
|
888
|
-
* Normalized shape of the `readOnly` config option
|
|
889
|
-
*/
|
|
890
|
-
interface NormalizedReadOnlyConfig {
|
|
891
|
-
enabled: boolean;
|
|
892
|
-
hideControls: boolean;
|
|
893
|
-
}
|
|
894
|
-
/**
|
|
895
|
-
* Single source of truth for interpreting the `readOnly` config option.
|
|
896
|
-
* The object form always means read-only is enabled.
|
|
897
|
-
* @param value - raw `readOnly` value from BlokConfig
|
|
898
|
-
*/
|
|
899
|
-
declare function normalizeReadOnlyConfig(value: boolean | ReadOnlyModeConfig | undefined): NormalizedReadOnlyConfig;
|
|
900
|
-
/**
|
|
901
|
-
* Structural deep equality for JSON-like values (Blok `OutputData`).
|
|
902
|
-
*
|
|
903
|
-
* Framework-agnostic: shared by the React and Angular adapters to dedupe
|
|
904
|
-
* reactive `data` updates so identical content does not trigger a redundant
|
|
905
|
-
* re-render that would clobber the caret/selection. Handles the value shapes
|
|
906
|
-
* that appear in editor data: plain objects, arrays, and primitives (including
|
|
907
|
-
* `null`/`undefined`).
|
|
908
|
-
* @param a - first value to compare
|
|
909
|
-
* @param b - second value to compare
|
|
910
|
-
* @returns true when both values are structurally equal
|
|
911
|
-
*/
|
|
912
|
-
declare function deepEqual(a: unknown, b: unknown): boolean;
|
|
913
|
-
type AnyOutputData = OutputData | LooseOutputData | null | undefined;
|
|
914
|
-
/**
|
|
915
|
-
* Options for {@link equalsOutputData}.
|
|
916
|
-
*/
|
|
917
|
-
interface EqualsOutputDataOptions {
|
|
918
|
-
/**
|
|
919
|
-
* Ignore empty default blocks on both sides before comparing. A fresh editor
|
|
920
|
-
* always seeds one empty default paragraph, so a pristine document
|
|
921
|
-
* (`[{ type: 'paragraph', data: { text: '' } }]`) does not content-equal a
|
|
922
|
-
* saved-empty baseline (`[]`) by default. Turn this on for dirty-vs-baseline
|
|
923
|
-
* checks ("has the user actually typed anything?"): empty blocks of the
|
|
924
|
-
* default paragraph tool are dropped from both documents first, so pristine
|
|
925
|
-
* scaffolding and trailing empty lines don't register as a change. Empty
|
|
926
|
-
* NON-default blocks (a content-less divider, an empty image) are kept — they
|
|
927
|
-
* are meaningful content.
|
|
928
|
-
*/
|
|
929
|
-
ignoreEmptyDefaultBlocks?: boolean;
|
|
930
|
-
}
|
|
931
|
-
/**
|
|
932
|
-
* Structural equality for saved documents. Compares the `blocks` arrays
|
|
933
|
-
* deeply; the volatile `time` and `version` envelope fields are ignored, so a
|
|
934
|
-
* document round-tripped through `save()` compares equal to its echo. Block
|
|
935
|
-
* ids are compared only when both sides carry one — the editor mints fresh
|
|
936
|
-
* ids for id-less content, so a legacy document still equals its saved echo.
|
|
937
|
-
* Edit metadata (`lastEditedAt`/`lastEditedBy`) is ignored for the same reason:
|
|
938
|
-
* it records who touched a block and when, not what it says. Nullish documents
|
|
939
|
-
* compare equal to `{ blocks: [] }`.
|
|
940
|
-
*
|
|
941
|
-
* Pass `{ ignoreEmptyDefaultBlocks: true }` for dirty-vs-baseline checks so a
|
|
942
|
-
* pristine editor (one empty default paragraph) equals a saved-empty baseline —
|
|
943
|
-
* see {@link EqualsOutputDataOptions}.
|
|
944
|
-
* @param a - first document to compare
|
|
945
|
-
* @param b - second document to compare
|
|
946
|
-
* @param options - comparison options
|
|
947
|
-
* @returns true when both documents hold structurally equal blocks
|
|
948
|
-
*/
|
|
949
|
-
declare function equalsOutputData(a: AnyOutputData, b: AnyOutputData, options?: EqualsOutputDataOptions): boolean;
|
|
950
|
-
/**
|
|
951
|
-
* A bounded window of the editor's recently emitted `onSave` payloads, used by
|
|
952
|
-
* the framework adapters to recognize controlled-`data` echoes. Deduping
|
|
953
|
-
* against only the LAST emitted payload is not enough: a host that persists on
|
|
954
|
-
* save and refetches can hand the adapter a STALE echo — an earlier save
|
|
955
|
-
* arriving after a newer one already replaced the baseline — and re-rendering
|
|
956
|
-
* it would clobber the caret and any content typed since. Matching is
|
|
957
|
-
* structural ({@link equalsOutputData}), so envelopes reshaped in transit
|
|
958
|
-
* (fresh `time`, stripped ids) still count as echoes.
|
|
959
|
-
* @param capacity - number of payloads retained before the oldest is evicted
|
|
960
|
-
* @returns the echo window
|
|
961
|
-
*/
|
|
962
|
-
declare function createEmittedEchoWindow(capacity?: number): {
|
|
963
|
-
/** Records a payload the editor emitted via `onSave`. */
|
|
964
|
-
record(data: OutputData | LooseOutputData): void;
|
|
965
|
-
/** True when the document content-equals any recorded payload. */
|
|
966
|
-
matches(data: AnyOutputData): boolean;
|
|
967
|
-
/** Forgets all recorded payloads (external content took over). */
|
|
968
|
-
clear(): void;
|
|
969
|
-
};
|
|
970
|
-
/**
|
|
971
|
-
* A shared, deeply frozen empty document. Consumers persisting editor content
|
|
972
|
-
* repeatedly hand-write `{ blocks: [] }` for cleared/pristine baselines; this
|
|
973
|
-
* is the canonical value to use instead. Frozen (blocks array included) so a
|
|
974
|
-
* shared reference can never be mutated into a stale non-empty baseline.
|
|
975
|
-
*/
|
|
976
|
-
declare const EMPTY_OUTPUT_DATA: OutputData;
|
|
977
|
-
/**
|
|
978
|
-
* Maps a controlled `data` value to something the editor's `render()` accepts.
|
|
979
|
-
* A whole-document `null` — a controlled "clear to empty" — becomes
|
|
980
|
-
* `{ blocks: [] }`; any real document passes through untouched.
|
|
981
|
-
*
|
|
982
|
-
* The framework adapters (React/Vue/Angular) route their reactive `data` path
|
|
983
|
-
* through this so a `null` never reaches `render()`, whose strict guard reads
|
|
984
|
-
* `data.blocks` and would throw on `null`. `undefined` (uncontrolled) is handled
|
|
985
|
-
* by the adapters before this point, so it is intentionally not an input here.
|
|
986
|
-
* @param data - a controlled document, or `null` for an empty document
|
|
987
|
-
* @returns a document `render()` can consume
|
|
988
|
-
*/
|
|
989
|
-
declare function toRenderableData(data: OutputData | LooseOutputData | null): OutputData | LooseOutputData;
|
|
990
|
-
/**
|
|
991
|
-
* Normalizes blocks from the loose wire shape into the strict saved shape at
|
|
992
|
-
* the editor's input boundaries: a `null`/missing `data` becomes `{}`, a
|
|
993
|
-
* `null`/empty `id` is dropped so the block factory generates a fresh one, and
|
|
994
|
-
* nullish/empty hierarchy references (`parent`, `content`) are dropped so a
|
|
995
|
-
* root-level, childless block is spelled the one way the editor and `save()`
|
|
996
|
-
* both spell it — absent. Idempotent — strict blocks pass through unchanged
|
|
997
|
-
* (shallow-copied).
|
|
998
|
-
* @param blocks - blocks in either the strict or the loose wire shape
|
|
999
|
-
* @returns blocks in the strict saved shape
|
|
1000
|
-
*/
|
|
1001
|
-
declare function normalizeOutputBlocks(blocks: Array<OutputBlockData | LooseOutputBlockData>): OutputBlockData[];
|
|
1002
|
-
/**
|
|
1003
|
-
* Normalizes a whole loose wire document into the strict saved
|
|
1004
|
-
* {@link OutputData} shape at an input boundary. A nullish document becomes
|
|
1005
|
-
* `{ blocks: [] }`; `null` envelope fields (`time`/`version`) are dropped and a
|
|
1006
|
-
* non-empty `id` is kept; each
|
|
1007
|
-
* block is passed through {@link normalizeOutputBlocks}, so `null`/missing
|
|
1008
|
-
* `data` becomes `{}`, `null`/empty ids are dropped for regeneration and
|
|
1009
|
-
* nullish/empty `parent`/`content` references are dropped as absent.
|
|
1010
|
-
*
|
|
1011
|
-
* Unlike a hand-written `blocks.map(...)` mapper, this preserves every block
|
|
1012
|
-
* passthrough field — `tunes`, real `parent`/`content` references, `indent`,
|
|
1013
|
-
* edit metadata — so a backend DTO can be turned into strict `OutputData`
|
|
1014
|
-
* without silently losing hierarchy or tunes. Idempotent: a strict document
|
|
1015
|
-
* passes through unchanged (shallow-copied).
|
|
1016
|
-
* @param data - a document in the strict or loose wire shape, or nullish
|
|
1017
|
-
* @returns the document in the strict saved shape
|
|
1018
|
-
*/
|
|
1019
|
-
declare function normalizeOutputData(data: AnyOutputData): OutputData;
|
|
1020
|
-
/**
|
|
1021
|
-
* True when the document carries no user content: it is nullish, has no
|
|
1022
|
-
* blocks, or every block's data holds only empty values (see
|
|
1023
|
-
* {@link isEmptyValue}). Note that content-less visual blocks (e.g. a divider,
|
|
1024
|
-
* whose data is `{}`) count as empty — check `blocks.length` when mere block
|
|
1025
|
-
* presence matters.
|
|
1026
|
-
* @param data - document to inspect
|
|
1027
|
-
* @returns true when the document carries no user content
|
|
1028
|
-
*/
|
|
1029
|
-
declare function isEmptyOutputData(data: AnyOutputData): boolean;
|
|
1030
829
|
/** One field of a block's prop schema. */
|
|
1031
830
|
interface PropSchemaEntry {
|
|
1032
831
|
/** Default value, used when the incoming data omits this key. */
|
|
@@ -1040,504 +839,6 @@ interface PropSchemaEntry {
|
|
|
1040
839
|
* written as its explicit default, never dropped).
|
|
1041
840
|
*/
|
|
1042
841
|
type PropSchema = Record<string, PropSchemaEntry>;
|
|
1043
|
-
/**
|
|
1044
|
-
* Fill a data object against the schema: every schema key present, incoming
|
|
1045
|
-
* value when defined else the schema default, and ONLY schema keys (so `save()`
|
|
1046
|
-
* is never partial). Returns a frozen plain object — safe to hand straight to
|
|
1047
|
-
* core's per-key Yjs sync.
|
|
1048
|
-
*/
|
|
1049
|
-
declare const fillDefaults: <Data>(schema: PropSchema, data: Record<string, unknown>) => Readonly<Data>;
|
|
1050
|
-
/**
|
|
1051
|
-
* Every child slot carries one of these — first-party containers and every
|
|
1052
|
-
* adapter's `<BlockChildren>` alike. `BlockHierarchy` reads the same selector,
|
|
1053
|
-
* so the two sides agree on which blocks own a slot.
|
|
1054
|
-
*/
|
|
1055
|
-
declare const CHILD_SLOT_SELECTOR = "[data-blok-toggle-children], [data-blok-nested-blocks]";
|
|
1056
|
-
/**
|
|
1057
|
-
* Parents that place their children themselves (per cell / per view). Their
|
|
1058
|
-
* descendants must never be pulled into an enclosing slot.
|
|
1059
|
-
*/
|
|
1060
|
-
declare const SELF_PLACING_PARENTS: ReadonlySet<string>;
|
|
1061
|
-
/**
|
|
1062
|
-
* A slotless block renders its children as flat sibling holders right after
|
|
1063
|
-
* itself, in whatever slot holds the block — the same as nesting at root.
|
|
1064
|
-
* @param block - the block to test
|
|
1065
|
-
*/
|
|
1066
|
-
declare const isSlotless: (block: {
|
|
1067
|
-
holder: HTMLElement;
|
|
1068
|
-
name?: string;
|
|
1069
|
-
}) => boolean;
|
|
1070
|
-
/**
|
|
1071
|
-
* The blocks a container slot hosts: its children, each followed by the
|
|
1072
|
-
* descendants of a slotless child (depth-first, flat order). A child that owns a
|
|
1073
|
-
* slot keeps its own descendants.
|
|
1074
|
-
* @param children - the container block's model children, in model order
|
|
1075
|
-
* @param getChildren - model children of a block, by id
|
|
1076
|
-
*/
|
|
1077
|
-
declare const withSlotlessDescendants: <T extends {
|
|
1078
|
-
holder: HTMLElement;
|
|
1079
|
-
id?: string;
|
|
1080
|
-
name?: string;
|
|
1081
|
-
}>(children: T[], getChildren: (id: string) => T[]) => T[];
|
|
1082
|
-
/**
|
|
1083
|
-
* Mount child block holders into a container, skipping children that are
|
|
1084
|
-
* already in place or claimed by another nested-blocks container.
|
|
1085
|
-
*
|
|
1086
|
-
* Used by toggle, header, column, and callout tools — and by the React, Vue and
|
|
1087
|
-
* Angular block adapters — to reconcile child holders during the `rendered()`
|
|
1088
|
-
* lifecycle hook. It is the standing DOM↔model reconciler for container blocks:
|
|
1089
|
-
* safe to call on every render, and the only thing that heals a child holder
|
|
1090
|
-
* that core parked outside the container while the container's own slot had not
|
|
1091
|
-
* been created yet.
|
|
1092
|
-
* @param container - the container element child holders belong in; usually the
|
|
1093
|
-
* element carrying `data-blok-nested-blocks`.
|
|
1094
|
-
* @param children - the container block's MODEL children, in model order (e.g.
|
|
1095
|
-
* `api.blocks.getChildren(blockId)`).
|
|
1096
|
-
*/
|
|
1097
|
-
declare const mountChildBlocks: (container: HTMLElement, children: {
|
|
1098
|
-
holder: HTMLElement;
|
|
1099
|
-
}[]) => void;
|
|
1100
|
-
/**
|
|
1101
|
-
* One child's decoration: attribute name → value. `null`/`undefined` removes the
|
|
1102
|
-
* attribute; a boolean or number is stringified (so `false` writes
|
|
1103
|
-
* `data-active="false"`, which CSS can select, rather than dropping the hook).
|
|
1104
|
-
*/
|
|
1105
|
-
type ChildAttributes$1 = Record<string, string | number | boolean | null | undefined>;
|
|
1106
|
-
/** The minimum a child must expose for a decoration pass. */
|
|
1107
|
-
interface DecoratableChild {
|
|
1108
|
-
id: string;
|
|
1109
|
-
holder: HTMLElement;
|
|
1110
|
-
}
|
|
1111
|
-
/**
|
|
1112
|
-
* A per-child decorator: what to write for the child at `index`.
|
|
1113
|
-
*
|
|
1114
|
-
* Generic over the child so an adapter can declare its decorators in terms of the
|
|
1115
|
-
* full `BlockAPI` its authors receive. A non-generic `(child: DecoratableChild)`
|
|
1116
|
-
* parameter would REJECT those: a function that demands a full BlockAPI is not
|
|
1117
|
-
* assignable to one promising to accept the structural minimum.
|
|
1118
|
-
*/
|
|
1119
|
-
type ChildAttributesFn$1<Child extends DecoratableChild = DecoratableChild> = (child: Child, index: number) => ChildAttributes$1;
|
|
1120
|
-
/** What the previous decoration pass wrote for one child, so it can be undone. */
|
|
1121
|
-
interface StampedChild {
|
|
1122
|
-
/** The element written to — a holder for one ledger, a content wrapper for the other. */
|
|
1123
|
-
target: HTMLElement;
|
|
1124
|
-
names: string[];
|
|
1125
|
-
}
|
|
1126
|
-
/** The ledgers a container keeps between passes; create one per child slot. */
|
|
1127
|
-
interface ChildDecorationLedger {
|
|
1128
|
-
holders: Map<string, StampedChild>;
|
|
1129
|
-
contents: Map<string, StampedChild>;
|
|
1130
|
-
}
|
|
1131
|
-
/**
|
|
1132
|
-
* A fresh pair of ledgers for one container's child slot.
|
|
1133
|
-
* @returns empty holder/content ledgers
|
|
1134
|
-
*/
|
|
1135
|
-
declare const createChildDecorationLedger: () => ChildDecorationLedger;
|
|
1136
|
-
/**
|
|
1137
|
-
* Decorate a container's children: named attributes on each child's HOLDER and,
|
|
1138
|
-
* separately, on each child's `[data-blok-element-content]` wrapper.
|
|
1139
|
-
*
|
|
1140
|
-
* The single implementation behind the React, Vue and Angular per-child
|
|
1141
|
-
* decoration channels, so the three cannot drift on which element a hook lands
|
|
1142
|
-
* on or on when a dropped hook is cleaned up.
|
|
1143
|
-
*
|
|
1144
|
-
* BOTH levels exist because core's child-holder decoration law blesses both, and
|
|
1145
|
-
* a container needs both: the holder is the child's outer box (rails, indices,
|
|
1146
|
-
* hover states), while the content wrapper is where the child's own text box
|
|
1147
|
-
* begins — which is what a numbered rail or a connector line has to align to.
|
|
1148
|
-
* With only the holder reachable, a container had to encode core's wrapper chain
|
|
1149
|
-
* in its own CSS (`[data-step] > [data-blok-element-content] > …`) and broke
|
|
1150
|
-
* whenever that chain changed. Neither hook may introduce an element: holders
|
|
1151
|
-
* stay DIRECT children of the slot because core's reparenting and caret
|
|
1152
|
-
* sibling checks compare `holder.parentElement` by identity.
|
|
1153
|
-
*
|
|
1154
|
-
* Both are inert with respect to change tracking: core's mutation filter drops a
|
|
1155
|
-
* holder- or content-targeted attribute record for the CHILD block (both are
|
|
1156
|
-
* ancestors of the child's tool element, not descendants) and scores it
|
|
1157
|
-
* mutation-free for the CONTAINER (whose own `data-blok-mutation-free` host is
|
|
1158
|
-
* the nearest such ancestor).
|
|
1159
|
-
* @param ledger - the slot's ledgers from {@link createChildDecorationLedger}
|
|
1160
|
-
* @param children - the container's model children, in model order
|
|
1161
|
-
* @param decorators - the authored per-child decorators
|
|
1162
|
-
* @param decorators.childAttributes - written on each child's holder
|
|
1163
|
-
* @param decorators.childContentAttributes - written on each child's content wrapper
|
|
1164
|
-
*/
|
|
1165
|
-
declare const applyChildDecoration: <Child extends DecoratableChild>(ledger: ChildDecorationLedger, children: Child[], decorators: {
|
|
1166
|
-
childAttributes?: ChildAttributesFn$1<Child>;
|
|
1167
|
-
childContentAttributes?: ChildAttributesFn$1<Child>;
|
|
1168
|
-
}) => void;
|
|
1169
|
-
/**
|
|
1170
|
-
* Centralized data attributes used across the Blok editor.
|
|
1171
|
-
* This is the single source of truth for all data-blok-* attributes.
|
|
1172
|
-
*
|
|
1173
|
-
* Exported as Blok.DATA_ATTR for users.
|
|
1174
|
-
*
|
|
1175
|
-
* Naming convention:
|
|
1176
|
-
* - Remove 'data-blok-' prefix and convert to camelCase
|
|
1177
|
-
* - Global attributes: hidden, disabled, focused
|
|
1178
|
-
* - Component prefixed: popover, popoverItem, toolbar, etc.
|
|
1179
|
-
*/
|
|
1180
|
-
declare const DATA_ATTR: {
|
|
1181
|
-
/** Interface type identifier (blok, inline-toolbar, tooltip) */
|
|
1182
|
-
readonly interface: "data-blok-interface";
|
|
1183
|
-
/** Block element wrapper */
|
|
1184
|
-
readonly element: "data-blok-element";
|
|
1185
|
-
/** Block element content wrapper */
|
|
1186
|
-
readonly elementContent: "data-blok-element-content";
|
|
1187
|
-
/** Editor wrapper container */
|
|
1188
|
-
readonly editor: "data-blok-editor";
|
|
1189
|
-
/** Per-instance discriminator on the editor wrapper (a monotonic counter, as a
|
|
1190
|
-
* string). Two editors on one page share every other scope attribute, so this
|
|
1191
|
-
* is what lets a page-level stylesheet — Blok's own injected `style.fontSize`
|
|
1192
|
-
* sheet, or a host rule — address ONE editor. Public styling hook. */
|
|
1193
|
-
readonly instance: "data-blok-instance";
|
|
1194
|
-
/** Redactor zone */
|
|
1195
|
-
readonly redactor: "data-blok-redactor";
|
|
1196
|
-
/** Present on the editor wrapper once a `blocks.render()` batch has finished
|
|
1197
|
-
* inserting blocks into the DOM; removed while a re-render is in flight.
|
|
1198
|
-
* Acts as a stable render-readiness gate for consumers (e.g. E2E waits). */
|
|
1199
|
-
readonly rendered: "data-blok-rendered";
|
|
1200
|
-
/** Present on the editor wrapper while the loading skeleton owns it.
|
|
1201
|
-
* Public styling hook. */
|
|
1202
|
-
readonly loading: "data-blok-loading";
|
|
1203
|
-
/** The loading skeleton overlay (a wrapper child, never inside the redactor). */
|
|
1204
|
-
readonly loadingSkeleton: "data-blok-loading-skeleton";
|
|
1205
|
-
/** One skeleton row; the value is its kind: heading | paragraph | list. */
|
|
1206
|
-
readonly skeletonBar: "data-blok-skeleton-bar";
|
|
1207
|
-
/** Blok version number stamped on the editor wrapper (e.g. '1.10.0', 'dev').
|
|
1208
|
-
* Consumed by browser extensions to identify the running version. */
|
|
1209
|
-
readonly version: "data-blok-version";
|
|
1210
|
-
/** Block unique identifier */
|
|
1211
|
-
readonly id: "data-blok-id";
|
|
1212
|
-
readonly pageId: "data-blok-page-id";
|
|
1213
|
-
/** Block component/tool type */
|
|
1214
|
-
readonly component: "data-blok-component";
|
|
1215
|
-
/** Tool type attribute */
|
|
1216
|
-
readonly tool: "data-blok-tool";
|
|
1217
|
-
readonly blockContextMenu: "data-blok-block-context-menu";
|
|
1218
|
-
/** Block nesting depth (derived from the parentId chain) */
|
|
1219
|
-
readonly depth: "data-blok-depth";
|
|
1220
|
-
/** Flat list-nesting indentation level (0 = root); tool-agnostic, mirrors list depth */
|
|
1221
|
-
readonly indent: "data-blok-indent";
|
|
1222
|
-
/** Header tool's heading level (1-6). Public styling hook — keyed by level rather
|
|
1223
|
-
* than by tag name, so a level remapped to a custom tag via `levelOverrides[n].tag`
|
|
1224
|
-
* (types/tools/header.d.ts) still matches its level's typography rules. */
|
|
1225
|
-
readonly headingLevel: "data-blok-heading-level";
|
|
1226
|
-
/** Element is hidden from view */
|
|
1227
|
-
readonly hidden: "data-blok-hidden";
|
|
1228
|
-
/** Element is disabled and non-interactive */
|
|
1229
|
-
readonly disabled: "data-blok-disabled";
|
|
1230
|
-
/** Element is focused via keyboard navigation */
|
|
1231
|
-
readonly focused: "data-blok-focused";
|
|
1232
|
-
/** On a popover once a navigation key moved its cursor; gates the focus ring */
|
|
1233
|
-
readonly keyboardNavigated: "data-blok-keyboard-navigated";
|
|
1234
|
-
/** Block is selected */
|
|
1235
|
-
readonly selected: "data-blok-selected";
|
|
1236
|
-
/** On a block's spotlight target while it is being pointed out (Show in the failed-image notice) */
|
|
1237
|
-
readonly spotlight: "data-blok-spotlight";
|
|
1238
|
-
/** Marks the element inside a block that Show points at, e.g. the image's error card */
|
|
1239
|
-
readonly spotlightTarget: "data-blok-spotlight-target";
|
|
1240
|
-
/** Marks the control inside a spotlight target that receives focus, e.g. Retry */
|
|
1241
|
-
readonly spotlightFocus: "data-blok-spotlight-focus";
|
|
1242
|
-
/** Block is stretched */
|
|
1243
|
-
readonly stretched: "data-blok-stretched";
|
|
1244
|
-
/** Editor or element is empty */
|
|
1245
|
-
readonly empty: "data-blok-empty";
|
|
1246
|
-
/** Present on the editor wrapper while read-only mode is active.
|
|
1247
|
-
* Public styling hook — lets hosts key rules off the editing state
|
|
1248
|
-
* without JS. Deliberately does NOT collapse the gutter: plain
|
|
1249
|
-
* read-only still shows the block-hover copy-link control there, and
|
|
1250
|
-
* in-place readOnly.set() flips must not shift the layout. */
|
|
1251
|
-
readonly readonly: "data-blok-readonly";
|
|
1252
|
-
/** Present on the editor wrapper while read-only mode hides ALL editor
|
|
1253
|
-
* controls (readOnly: { hideControls: true }). Public styling hook —
|
|
1254
|
-
* drives the gutter auto-collapse for genuinely chromeless read-only. */
|
|
1255
|
-
readonly controlsHidden: "data-blok-controls-hidden";
|
|
1256
|
-
/** Present on the editor wrapper when config.hideToolbar is true.
|
|
1257
|
-
* Public styling hook — drives the gutter auto-collapse (the gutter
|
|
1258
|
-
* exists solely to house the toolbar's +/⠿ controls). */
|
|
1259
|
-
readonly toolbarHidden: "data-blok-toolbar-hidden";
|
|
1260
|
-
/** Which gutter the floating block controls occupy: 'left' (default,
|
|
1261
|
-
* inline-start) or 'right' (inline-end). Written on the editor wrapper from
|
|
1262
|
-
* config.toolbarPosition and kept in sync by `toolbar.setPosition()`.
|
|
1263
|
-
* Public styling hook — drives the gutter swap and the actions-bar side. */
|
|
1264
|
-
readonly toolbarPosition: "data-blok-toolbar-position";
|
|
1265
|
-
/** Content alignment mode (left, center, right) */
|
|
1266
|
-
readonly contentAlign: "data-blok-content-align";
|
|
1267
|
-
/** Right-to-left mode */
|
|
1268
|
-
readonly rtl: "data-blok-rtl";
|
|
1269
|
-
/** Editor content width mode (present with value "full" for wide mode; absent = narrow) */
|
|
1270
|
-
readonly width: "data-blok-width";
|
|
1271
|
-
/** Present on the editor wrapper when config.style.nativeSelection is true.
|
|
1272
|
-
* Public styling hook — disables Blok's ::selection repaint (preflight.css)
|
|
1273
|
-
* and re-points the fake-background highlight at the UA Highlight color
|
|
1274
|
-
* (colors.css), so selection falls back to native/host-defined colors. */
|
|
1275
|
-
readonly nativeSelection: "data-blok-native-selection";
|
|
1276
|
-
/** Present on the editor wrapper while a cross-block TEXT selection is painted.
|
|
1277
|
-
* Suppresses the engine's own ::selection paint (main.css) so the
|
|
1278
|
-
* ::highlight() sub-ranges are the only thing drawn — Chromium and Firefox
|
|
1279
|
-
* paint such a range natively too and would otherwise double it up. */
|
|
1280
|
-
readonly crossSelection: "data-blok-cross-selection";
|
|
1281
|
-
/** Block is being dragged */
|
|
1282
|
-
readonly dragging: "data-blok-dragging";
|
|
1283
|
-
/** Multiple blocks being dragged */
|
|
1284
|
-
readonly draggingMulti: "data-blok-dragging-multi";
|
|
1285
|
-
/** Block is being duplicated (Alt+drag) */
|
|
1286
|
-
readonly duplicating: "data-blok-duplicating";
|
|
1287
|
-
/** Drag handle element */
|
|
1288
|
-
readonly dragHandle: "data-blok-drag-handle";
|
|
1289
|
-
/** Toolbar element */
|
|
1290
|
-
readonly toolbar: "data-blok-toolbar";
|
|
1291
|
-
/** The floating block-controls bar (plus button + drag/settings handle)
|
|
1292
|
-
* inside the toolbar. Public styling hook — the side it docks to is driven
|
|
1293
|
-
* from the wrapper's `data-blok-toolbar-position`. */
|
|
1294
|
-
readonly toolbarActions: "data-blok-toolbar-actions";
|
|
1295
|
-
/** Settings toggler button */
|
|
1296
|
-
readonly settingsToggler: "data-blok-settings-toggler";
|
|
1297
|
-
/** Toolbox is open */
|
|
1298
|
-
readonly toolboxOpened: "data-blok-toolbox-opened";
|
|
1299
|
-
/** Block settings is open */
|
|
1300
|
-
readonly blockSettingsOpened: "data-blok-block-settings-opened";
|
|
1301
|
-
/** Element is opened (generic) */
|
|
1302
|
-
readonly opened: "data-blok-opened";
|
|
1303
|
-
/** Root popover element */
|
|
1304
|
-
readonly popover: "data-blok-popover";
|
|
1305
|
-
/** Popover container wrapper */
|
|
1306
|
-
readonly popoverContainer: "data-blok-popover-container";
|
|
1307
|
-
/** Popover items list */
|
|
1308
|
-
readonly popoverItems: "data-blok-popover-items";
|
|
1309
|
-
/** Custom, engine-independent scrollbar thumb overlaid on the popover items */
|
|
1310
|
-
readonly popoverScrollbar: "data-blok-popover-scrollbar";
|
|
1311
|
-
/** Stamped on the custom scrollbar thumb while it is being dragged (keeps it revealed) */
|
|
1312
|
-
readonly popoverScrollbarDragging: "data-blok-dragging";
|
|
1313
|
-
/** Stamped on a scroll container while it is actively scrolling (reveals the auto-hidden scrollbar thumb) */
|
|
1314
|
-
readonly scrolling: "data-blok-scrolling";
|
|
1315
|
-
/** Popover overlay element */
|
|
1316
|
-
readonly popoverOverlay: "data-blok-popover-overlay";
|
|
1317
|
-
/** Popover custom content area */
|
|
1318
|
-
readonly popoverCustomContent: "data-blok-popover-custom-content";
|
|
1319
|
-
/** Popover custom class */
|
|
1320
|
-
readonly popoverCustomClass: "data-blok-popover-custom-class";
|
|
1321
|
-
/** Inline popover variant */
|
|
1322
|
-
readonly popoverInline: "data-blok-popover-inline";
|
|
1323
|
-
/** Popover is open */
|
|
1324
|
-
readonly popoverOpened: "data-blok-popover-opened";
|
|
1325
|
-
/** Popover opens upward */
|
|
1326
|
-
readonly popoverOpenTop: "data-blok-popover-open-top";
|
|
1327
|
-
/** Popover opens leftward */
|
|
1328
|
-
readonly popoverOpenLeft: "data-blok-popover-open-left";
|
|
1329
|
-
/** Nested popover indicator */
|
|
1330
|
-
readonly nested: "data-blok-nested";
|
|
1331
|
-
/** Nesting level value */
|
|
1332
|
-
readonly nestedLevel: "data-blok-nested-level";
|
|
1333
|
-
/** Group label for promoted search results from nested children */
|
|
1334
|
-
readonly promotedGroupLabel: "data-blok-promoted-group-label";
|
|
1335
|
-
/** A nested child shown in the host menu's search results. The convert-menu styles skip it, so the host keeps its own layout. */
|
|
1336
|
-
readonly promotedItem: "data-blok-promoted-item";
|
|
1337
|
-
/** Group label for top-level matches in search results */
|
|
1338
|
-
readonly topLevelGroupLabel: "data-blok-top-level-group-label";
|
|
1339
|
-
/** Header container */
|
|
1340
|
-
readonly popoverHeader: "data-blok-popover-header";
|
|
1341
|
-
/** Header text element */
|
|
1342
|
-
readonly popoverHeaderText: "data-blok-popover-header-text";
|
|
1343
|
-
/** Back button in nested popover */
|
|
1344
|
-
readonly popoverHeaderBackButton: "data-blok-popover-header-back-button";
|
|
1345
|
-
/** Item container */
|
|
1346
|
-
readonly popoverItem: "data-blok-popover-item";
|
|
1347
|
-
/** Item icon wrapper */
|
|
1348
|
-
readonly popoverItemIcon: "data-blok-popover-item-icon";
|
|
1349
|
-
/** Chevron icon for nested items */
|
|
1350
|
-
readonly popoverItemIconChevronRight: "data-blok-popover-item-icon-chevron-right";
|
|
1351
|
-
/** Item title text */
|
|
1352
|
-
readonly popoverItemTitle: "data-blok-popover-item-title";
|
|
1353
|
-
/** Item secondary title */
|
|
1354
|
-
readonly popoverItemSecondaryTitle: "data-blok-popover-item-secondary-title";
|
|
1355
|
-
/** Item is active/selected */
|
|
1356
|
-
readonly popoverItemActive: "data-blok-popover-item-active";
|
|
1357
|
-
/** Item's child menu is currently open — keeps the trigger looking selected */
|
|
1358
|
-
readonly popoverItemChildrenOpen: "data-blok-popover-item-children-open";
|
|
1359
|
-
/** Confirmation state */
|
|
1360
|
-
readonly popoverItemConfirmation: "data-blok-popover-item-confirmation";
|
|
1361
|
-
/** Disable hover styling */
|
|
1362
|
-
readonly popoverItemNoHover: "data-blok-popover-item-no-hover";
|
|
1363
|
-
/** Disable focus handling */
|
|
1364
|
-
readonly popoverItemNoFocus: "data-blok-popover-item-no-focus";
|
|
1365
|
-
/** Destructive action item (e.g. delete) */
|
|
1366
|
-
readonly popoverItemDestructive: "data-blok-popover-item-destructive";
|
|
1367
|
-
/** Separator item */
|
|
1368
|
-
readonly popoverItemSeparator: "data-blok-popover-item-separator";
|
|
1369
|
-
/** Separator line element */
|
|
1370
|
-
readonly popoverItemSeparatorLine: "data-blok-popover-item-separator-line";
|
|
1371
|
-
/** HTML-based item */
|
|
1372
|
-
readonly popoverItemHtml: "data-blok-popover-item-html";
|
|
1373
|
-
/** Item has child menu */
|
|
1374
|
-
readonly hasChildren: "data-blok-has-children";
|
|
1375
|
-
/** Item name identifier */
|
|
1376
|
-
readonly itemName: "data-blok-item-name";
|
|
1377
|
-
/** No search results shown */
|
|
1378
|
-
readonly nothingFoundDisplayed: "data-blok-nothing-found-displayed";
|
|
1379
|
-
/** Selection overlay */
|
|
1380
|
-
readonly overlay: "data-blok-overlay";
|
|
1381
|
-
/** Overlay container */
|
|
1382
|
-
readonly overlayContainer: "data-blok-overlay-container";
|
|
1383
|
-
/** Selection rectangle */
|
|
1384
|
-
readonly overlayRectangle: "data-blok-overlay-rectangle";
|
|
1385
|
-
/** Overlay is hidden */
|
|
1386
|
-
readonly overlayHidden: "data-blok-overlay-hidden";
|
|
1387
|
-
/** Fake cursor indicator */
|
|
1388
|
-
readonly fakeCursor: "data-blok-fake-cursor";
|
|
1389
|
-
/** Fake background for selection */
|
|
1390
|
-
readonly fakeBackground: "data-blok-fake-background";
|
|
1391
|
-
/** Auto-scroll zone (top/bottom) */
|
|
1392
|
-
readonly scrollZone: "data-blok-scroll-zone";
|
|
1393
|
-
/** Scroll is locked */
|
|
1394
|
-
readonly scrollLocked: "data-blok-scroll-locked";
|
|
1395
|
-
/** Hard scroll lock */
|
|
1396
|
-
readonly scrollLockedHard: "data-blok-scroll-locked-hard";
|
|
1397
|
-
/** Shadow caret element */
|
|
1398
|
-
readonly shadowCaret: "data-blok-shadow-caret";
|
|
1399
|
-
/** Placeholder text */
|
|
1400
|
-
readonly placeholder: "data-blok-placeholder";
|
|
1401
|
-
/** Active placeholder text */
|
|
1402
|
-
readonly placeholderActive: "data-blok-placeholder-active";
|
|
1403
|
-
/** The columns row rendered by the column_list tool (the flex container).
|
|
1404
|
-
* Public styling hook — its direct `[data-blok-element]` children are the
|
|
1405
|
-
* column holders, whose shrink floor reads `--blok-column-min-width` and
|
|
1406
|
-
* whose gutter reads `--blok-column-gutter`. */
|
|
1407
|
-
readonly columns: "data-blok-columns";
|
|
1408
|
-
/** A single column inside a columns row. */
|
|
1409
|
-
readonly column: "data-blok-column";
|
|
1410
|
-
/** Drag-to-resize separator between two adjacent columns. Present only in
|
|
1411
|
-
* edit mode — the separators ARE the gutter there. */
|
|
1412
|
-
readonly columnResizer: "data-blok-column-resizer";
|
|
1413
|
-
/** Present on a columns row whose gutter comes from the container's own
|
|
1414
|
-
* column-gap instead of from resizer elements. Set in read-only mode, where
|
|
1415
|
-
* no resizers are built — the discriminator between an editable row and a
|
|
1416
|
-
* published one. */
|
|
1417
|
-
readonly columnsStaticGutter: "data-blok-columns-static-gutter";
|
|
1418
|
-
/** Container that hosts nested block holders (table cells, toggle/callout/header children).
|
|
1419
|
-
* Used as a universal guard: before moving a block holder via appendChild,
|
|
1420
|
-
* check `holder.closest([nestedBlocks])` — if truthy, the holder is already
|
|
1421
|
-
* claimed by another container and must not be stolen. */
|
|
1422
|
-
readonly nestedBlocks: "data-blok-nested-blocks";
|
|
1423
|
-
/** A drop zone. Empty value: an empty container's placeholder (an empty
|
|
1424
|
-
* tab); while the block's own holder shows one without the `hidden` class,
|
|
1425
|
-
* a drop on the block nests the dragged blocks as its first children.
|
|
1426
|
-
* A block id (a tab pill): a drop on the zone appends the dragged blocks
|
|
1427
|
-
* as the LAST children of that block. */
|
|
1428
|
-
readonly dropInto: "data-blok-drop-into";
|
|
1429
|
-
/** Set by core on a named drop zone while it is the drop target. */
|
|
1430
|
-
readonly dropIntoActive: "data-blok-drop-into-active";
|
|
1431
|
-
/** A container's empty-state hint that stands in for its first child block
|
|
1432
|
-
* (empty tab, empty toggle body). It is not a block, so hovering or pressing
|
|
1433
|
-
* it shows no block toolbar; the block a click creates gets its own. */
|
|
1434
|
-
readonly childStandIn: "data-blok-child-stand-in";
|
|
1435
|
-
/** Element excluded from mutation tracking */
|
|
1436
|
-
readonly mutationFree: "data-blok-mutation-free";
|
|
1437
|
-
/** Tool UI inside a block that is not the user's content (a list marker, a
|
|
1438
|
-
* checkbox, a code block's language button and line numbers). `Block.isEmpty`
|
|
1439
|
-
* and the block's copied HTML skip it. Never put it on an element that holds
|
|
1440
|
-
* child blocks or the user's text: that content would be skipped too. */
|
|
1441
|
-
readonly chrome: "data-blok-chrome";
|
|
1442
|
-
/** Marks a subtree whose keyboard belongs to the Tool that rendered it, not to
|
|
1443
|
-
* the editor. Blok's block-level keydown/keyup handling stands down entirely
|
|
1444
|
-
* for events originating inside it — Escape, Tab, the arrows, "/" and the
|
|
1445
|
-
* Enter/Backspace/Delete structural keys all reach the element untouched.
|
|
1446
|
-
*
|
|
1447
|
-
* Blok already exempts native `<input>`/`<textarea>` from the STRUCTURAL keys
|
|
1448
|
-
* (Enter/Backspace/Delete and "/") because those are contenteditable-shaped
|
|
1449
|
-
* and would splice the document around a form field. Escape/Tab/arrows are
|
|
1450
|
-
* deliberately NOT exempt — they are how a user leaves a field. That default
|
|
1451
|
-
* is right for a one-line title input and wrong for a field with its own
|
|
1452
|
-
* keyboard semantics (Tab between sub-fields, Escape to cancel an edit, arrows
|
|
1453
|
-
* to walk a suggestion list), which is exactly what this attribute is for.
|
|
1454
|
-
* Public authoring hook. */
|
|
1455
|
-
readonly keyboardOwner: "data-blok-keyboard-owner";
|
|
1456
|
-
/** Marks a subtree whose links belong to the tool: Blok's link hover card
|
|
1457
|
-
* and link-click navigation stand down inside it. For a link the tool opens
|
|
1458
|
-
* and previews itself (the page block). Public authoring hook. */
|
|
1459
|
-
readonly linkOwner: "data-blok-link-owner";
|
|
1460
|
-
/** Block has navigation focus */
|
|
1461
|
-
readonly navigationFocused: "data-blok-navigation-focused";
|
|
1462
|
-
/** Flipper navigation target */
|
|
1463
|
-
readonly flipperNavigationTarget: "data-blok-flipper-navigation-target";
|
|
1464
|
-
/** Inline toolbar enabled on external element */
|
|
1465
|
-
readonly inlineToolbar: "data-blok-inline-toolbar";
|
|
1466
|
-
/** Link tool is active */
|
|
1467
|
-
readonly linkToolActive: "data-blok-link-tool-active";
|
|
1468
|
-
/** Link tool unlink mode */
|
|
1469
|
-
readonly linkToolUnlink: "data-blok-link-tool-unlink";
|
|
1470
|
-
/** Link tool input is opened */
|
|
1471
|
-
readonly linkToolInputOpened: "data-blok-link-tool-input-opened";
|
|
1472
|
-
/** Bold collapsed length tracking */
|
|
1473
|
-
readonly boldCollapsedLength: "data-blok-bold-collapsed-length";
|
|
1474
|
-
/** Bold collapsed active state */
|
|
1475
|
-
readonly boldCollapsedActive: "data-blok-bold-collapsed-active";
|
|
1476
|
-
/** Bold previous length tracking */
|
|
1477
|
-
readonly boldPrevLength: "data-blok-bold-prev-length";
|
|
1478
|
-
/** Bold leading whitespace */
|
|
1479
|
-
readonly boldLeadingWs: "data-blok-bold-leading-ws";
|
|
1480
|
-
/** Bold marker */
|
|
1481
|
-
readonly boldMarker: "data-blok-bold-marker";
|
|
1482
|
-
/** Tooltip is shown */
|
|
1483
|
-
readonly shown: "data-blok-shown";
|
|
1484
|
-
/** Tooltip placement */
|
|
1485
|
-
readonly placement: "data-blok-placement";
|
|
1486
|
-
/** Bounce in animation */
|
|
1487
|
-
readonly bounceIn: "data-blok-bounce-in";
|
|
1488
|
-
/** Live region announcer */
|
|
1489
|
-
readonly announcer: "data-blok-announcer";
|
|
1490
|
-
/** Stub block element */
|
|
1491
|
-
readonly stub: "data-blok-stub";
|
|
1492
|
-
/** Stub info section */
|
|
1493
|
-
readonly stubInfo: "data-blok-stub-info";
|
|
1494
|
-
/** Stub title */
|
|
1495
|
-
readonly stubTitle: "data-blok-stub-title";
|
|
1496
|
-
/** Stub subtitle */
|
|
1497
|
-
readonly stubSubtitle: "data-blok-stub-subtitle";
|
|
1498
|
-
/** Slash search active on content editable */
|
|
1499
|
-
readonly slashSearch: "data-blok-slash-search";
|
|
1500
|
-
/** Test identifier (for E2E tests) */
|
|
1501
|
-
readonly testid: "data-blok-testid";
|
|
1502
|
-
/** Force hover state (for tests/storybook) */
|
|
1503
|
-
readonly forceHover: "data-blok-force-hover";
|
|
1504
|
-
};
|
|
1505
|
-
/**
|
|
1506
|
-
* Type for DATA_ATTR keys
|
|
1507
|
-
*/
|
|
1508
|
-
type DataAttrKey = keyof typeof DATA_ATTR;
|
|
1509
|
-
/**
|
|
1510
|
-
* Type for DATA_ATTR values
|
|
1511
|
-
*/
|
|
1512
|
-
type DataAttrValue = (typeof DATA_ATTR)[DataAttrKey];
|
|
1513
|
-
/**
|
|
1514
|
-
* Helper function to create a CSS selector from an attribute
|
|
1515
|
-
*
|
|
1516
|
-
* @param attr - The data attribute name from DATA_ATTR
|
|
1517
|
-
* @param value - Optional value for the attribute (defaults to presence selector)
|
|
1518
|
-
* @returns CSS selector string
|
|
1519
|
-
*
|
|
1520
|
-
* @example
|
|
1521
|
-
* createSelector(DATA_ATTR.element) // '[data-blok-element]'
|
|
1522
|
-
* createSelector(DATA_ATTR.selected, true) // '[data-blok-selected="true"]'
|
|
1523
|
-
* createSelector(DATA_ATTR.tool, 'paragraph') // '[data-blok-tool="paragraph"]'
|
|
1524
|
-
*/
|
|
1525
|
-
declare const createSelector: (attr: DataAttrValue, value?: string | boolean) => string;
|
|
1526
|
-
/**
|
|
1527
|
-
* Fired when a CONTAINER block's child holders have been mounted into its
|
|
1528
|
-
* child slot — the moment the child DOM has settled and a caret set into a
|
|
1529
|
-
* freshly inserted child sticks.
|
|
1530
|
-
*
|
|
1531
|
-
* Emitted by the React, Vue and Angular block adapters, whose portals commit a
|
|
1532
|
-
* frame AFTER core's `rendered()` hook; a vanilla container tool mounts its
|
|
1533
|
-
* children synchronously inside `rendered()`, so for those `block:rendered`
|
|
1534
|
-
* already means "settled". It fires on every reconciliation pass of the slot,
|
|
1535
|
-
* not only the first, so treat it as a settle signal rather than a change
|
|
1536
|
-
* signal.
|
|
1537
|
-
*
|
|
1538
|
-
* Public event name: `block:childrenMounted`.
|
|
1539
|
-
*/
|
|
1540
|
-
declare const BlockChildrenMounted = "block:childrenMounted";
|
|
1541
842
|
/**
|
|
1542
843
|
* Every STATIC member of core's block-tool contract an Angular block may declare
|
|
1543
844
|
* for itself — `ownsChildren`, `keepsChildrenOnEnter`, `conversionConfig`,
|
|
@@ -1623,6 +924,19 @@ interface CreateAngularBlockSpec<Data = BlockToolData> {
|
|
|
1623
924
|
* @param block - this block's per-block API
|
|
1624
925
|
*/
|
|
1625
926
|
onNavigationEnter?: (event: KeyboardEvent, block: BlockAPI) => boolean;
|
|
927
|
+
/**
|
|
928
|
+
* Core's `isReadOnly` hook: true when this block takes no edits from the
|
|
929
|
+
* user or an agent while the editor stays editable (no delete, move, merge,
|
|
930
|
+
* nesting or undo into it). Asked on each gesture; a throw counts as true.
|
|
931
|
+
* @param block - this block's per-block API
|
|
932
|
+
*/
|
|
933
|
+
isReadOnly?: (block: BlockAPI) => boolean;
|
|
934
|
+
/**
|
|
935
|
+
* Core's `isDataReadOnly` hook: true when only this block's own data is
|
|
936
|
+
* frozen and its children stay open. A throw counts as true.
|
|
937
|
+
* @param block - this block's per-block API
|
|
938
|
+
*/
|
|
939
|
+
isDataReadOnly?: (block: BlockAPI) => boolean;
|
|
1626
940
|
/** Optional lifecycle callbacks mapped from Blok's block hooks. */
|
|
1627
941
|
onRendered?: (block: BlockAPI) => void;
|
|
1628
942
|
/**
|
|
@@ -1676,7 +990,10 @@ interface CreateAngularBlockSpec<Data = BlockToolData> {
|
|
|
1676
990
|
*/
|
|
1677
991
|
onCreated?: (block: BlockAPI, context: AngularBlockMountedContext) => void;
|
|
1678
992
|
onMoved?: (block: BlockAPI) => void;
|
|
1679
|
-
|
|
993
|
+
/** `removal.deleted` is true when a local edit deleted the block (see BlockTool.removed). */
|
|
994
|
+
onRemoved?: (block: BlockAPI, removal?: {
|
|
995
|
+
deleted: boolean;
|
|
996
|
+
}) => void;
|
|
1680
997
|
}
|
|
1681
998
|
/**
|
|
1682
999
|
* Author a first-party Angular block. Returns a `BlockToolConstructable`
|
|
@@ -1701,9 +1018,13 @@ export declare function createAngularBlock<Data = BlockToolData>(spec: CreateAng
|
|
|
1701
1018
|
setReadOnly(state: boolean): void;
|
|
1702
1019
|
getToolbarAnchorElement(): HTMLElement | undefined;
|
|
1703
1020
|
onNavigationEnter(event: KeyboardEvent): boolean;
|
|
1021
|
+
isReadOnly(): boolean;
|
|
1022
|
+
isDataReadOnly(): boolean;
|
|
1704
1023
|
rendered(): void;
|
|
1705
1024
|
moved(): void;
|
|
1706
|
-
removed(
|
|
1025
|
+
removed(removal?: {
|
|
1026
|
+
deleted: boolean;
|
|
1027
|
+
}): void;
|
|
1707
1028
|
destroy(): void;
|
|
1708
1029
|
}) & BlockToolStatics & {
|
|
1709
1030
|
readonly __isBlokAngularBlock: true;
|
|
@@ -1935,4 +1256,4 @@ export declare const BLOK_EDITOR_INSTANCE: InjectionToken<Signal<Blok | null>>;
|
|
|
1935
1256
|
* Outside an editor it returns a signal of null.
|
|
1936
1257
|
*/
|
|
1937
1258
|
export declare function injectBlokInstance(): Signal<Blok | null>;
|
|
1938
|
-
export type { AngularBlockMountedContext, AngularBlockRenderContext, BlockNode, BlockToolStatics, BlokAngularConfig, BlokReadyScope, CaretTarget, ChildAttributes, ChildAttributesFn, CreateAngularBlockSpec, InjectBlocksOptions, InjectBlokReadyOptions, InsertPosition, InsertSpec, MoveTarget, PropSchema, PropSchemaEntry, TreeInsertSpec, UseBlocksApi };
|
|
1259
|
+
export type { AngularBlockMountedContext, AngularBlockRenderContext, BlockNode, BlockToolStatics, BlokAngularConfig, BlokReadyScope, CaretTarget, ChildAttributes, ChildAttributesFn, CreateAngularBlockSpec, CreateSpec, InjectBlocksOptions, InjectBlokReadyOptions, InsertPosition, InsertSpec, MoveTarget, PropSchema, PropSchemaEntry, TreeInsertSpec, UseBlocksApi };
|