@bloklabs/angular 1.2.5 → 1.3.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.
@@ -182,7 +182,8 @@ class BlokContentDirective {
182
182
  /** Emits the live Blok instance once it is ready, after `instance` is populated. */
183
183
  ready = new EventEmitter();
184
184
  /** The live Blok instance, or null before `isReady` resolves / after destroy. */
185
- instance = signal(null, ...(ngDevMode ? [{ debugName: "instance" }] : []));
185
+ instance = signal(null, /* @ts-ignore */
186
+ ...(ngDevMode ? [{ debugName: "instance" }] : /* istanbul ignore next */ []));
186
187
  /** The editor created by the most recent construction; used as the staleness key. */
187
188
  current = null;
188
189
  destroyed = false;
@@ -250,10 +251,10 @@ class BlokContentDirective {
250
251
  this.registry = undefined;
251
252
  this.instance.set(null);
252
253
  }
253
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: BlokContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
254
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.25", type: BlokContentDirective, isStandalone: true, selector: "[blokContent]", inputs: { config: "config", recreateKey: "recreateKey" }, outputs: { ready: "ready" }, ngImport: i0 });
254
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: BlokContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
255
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.7", type: BlokContentDirective, isStandalone: true, selector: "[blokContent]", inputs: { config: "config", recreateKey: "recreateKey" }, outputs: { ready: "ready" }, ngImport: i0 });
255
256
  }
256
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: BlokContentDirective, decorators: [{
257
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: BlokContentDirective, decorators: [{
257
258
  type: Directive,
258
259
  args: [{
259
260
  selector: '[blokContent]',
@@ -1769,6 +1770,11 @@ const DATA_ATTR = {
1769
1770
  rtl: 'data-blok-rtl',
1770
1771
  /** Editor content width mode (present with value "full" for wide mode; absent = narrow) */
1771
1772
  width: 'data-blok-width',
1773
+ /** Present on the editor wrapper when config.style.nativeSelection is true.
1774
+ * Public styling hook — disables Blok's ::selection repaint (preflight.css)
1775
+ * and re-points the fake-background highlight at the UA Highlight color
1776
+ * (colors.css), so selection falls back to native/host-defined colors. */
1777
+ nativeSelection: 'data-blok-native-selection',
1772
1778
  // ============================================
1773
1779
  // Drag and Drop
1774
1780
  // ============================================
@@ -2075,7 +2081,8 @@ class BlokEditorComponent {
2075
2081
  defaults = inject(BLOK_DEFAULT_CONFIG, { optional: true }) ?? {};
2076
2082
  contentQuery;
2077
2083
  /** Signal bridge for the @ViewChild directive so effects react to its arrival. */
2078
- content = signal(null, ...(ngDevMode ? [{ debugName: "content" }] : []));
2084
+ content = signal(null, /* @ts-ignore */
2085
+ ...(ngDevMode ? [{ debugName: "content" }] : /* istanbul ignore next */ []));
2079
2086
  /**
2080
2087
  * Output half of two-way `[(data)]`. Emits the editor's serialized content on
2081
2088
  * every change. Wiring the core `onSave` callback is gated on this being
@@ -2110,28 +2117,44 @@ class BlokEditorComponent {
2110
2117
  // ---- Reactive inputs (signal-backed setters; synced in place, never recreate) ----
2111
2118
  // Default undefined (not false) so an unset input falls back to a provideBlok
2112
2119
  // default; the readOnly effect / buildConfig coerce undefined to false.
2113
- readOnly$ = signal(undefined, ...(ngDevMode ? [{ debugName: "readOnly$" }] : []));
2120
+ readOnly$ = signal(undefined, /* @ts-ignore */
2121
+ ...(ngDevMode ? [{ debugName: "readOnly$" }] : /* istanbul ignore next */ []));
2114
2122
  set readOnly(value) {
2115
2123
  this.readOnly$.set(value);
2116
2124
  }
2117
- theme$ = signal(undefined, ...(ngDevMode ? [{ debugName: "theme$" }] : []));
2125
+ theme$ = signal(undefined, /* @ts-ignore */
2126
+ ...(ngDevMode ? [{ debugName: "theme$" }] : /* istanbul ignore next */ []));
2118
2127
  set theme(value) {
2119
2128
  this.theme$.set(value);
2120
2129
  }
2121
- width$ = signal(undefined, ...(ngDevMode ? [{ debugName: "width$" }] : []));
2130
+ width$ = signal(undefined, /* @ts-ignore */
2131
+ ...(ngDevMode ? [{ debugName: "width$" }] : /* istanbul ignore next */ []));
2122
2132
  set width(value) {
2123
2133
  this.width$.set(value);
2124
2134
  }
2125
- placeholder$ = signal(undefined, ...(ngDevMode ? [{ debugName: "placeholder$" }] : []));
2135
+ placeholder$ = signal(undefined, /* @ts-ignore */
2136
+ ...(ngDevMode ? [{ debugName: "placeholder$" }] : /* istanbul ignore next */ []));
2126
2137
  set placeholder(value) {
2127
2138
  this.placeholder$.set(value);
2128
2139
  }
2129
- autofocus$ = signal(false, ...(ngDevMode ? [{ debugName: "autofocus$" }] : []));
2140
+ /**
2141
+ * Theme tokens. Construction-only config forced hosts with a live light/dark
2142
+ * toggle to recreate the editor or hand-write the global stylesheet Blok
2143
+ * already injects; this drives the runtime `tokens` API instead.
2144
+ */
2145
+ styleTokens$ = signal(undefined, /* @ts-ignore */
2146
+ ...(ngDevMode ? [{ debugName: "styleTokens$" }] : /* istanbul ignore next */ []));
2147
+ set styleTokens(value) {
2148
+ this.styleTokens$.set(value);
2149
+ }
2150
+ autofocus$ = signal(false, /* @ts-ignore */
2151
+ ...(ngDevMode ? [{ debugName: "autofocus$" }] : /* istanbul ignore next */ []));
2130
2152
  set autofocus(value) {
2131
2153
  this.autofocus$.set(value);
2132
2154
  }
2133
2155
  // ---- Reactive content (seeds construction, then re-renders on change) ----
2134
- data$ = signal(undefined, ...(ngDevMode ? [{ debugName: "data$" }] : []));
2156
+ data$ = signal(undefined, /* @ts-ignore */
2157
+ ...(ngDevMode ? [{ debugName: "data$" }] : /* istanbul ignore next */ []));
2135
2158
  set data(value) {
2136
2159
  this.data$.set(value);
2137
2160
  }
@@ -2151,6 +2174,8 @@ class BlokEditorComponent {
2151
2174
  * no-op, so it won't clobber the caret. Renders are serialized via `renderChain`.
2152
2175
  */
2153
2176
  lastRenderedData;
2177
+ /** Last token set pushed through `tokens.set`, for deep-equal deduping. */
2178
+ appliedTokens;
2154
2179
  seededEditor = null;
2155
2180
  renderChain = Promise.resolve();
2156
2181
  /** Registered by `ControlValueAccessor.registerOnChange` (Angular forms). */
@@ -2173,7 +2198,8 @@ class BlokEditorComponent {
2173
2198
  });
2174
2199
  };
2175
2200
  /** Live Blok instance, or null until `isReady` resolves / after destroy. */
2176
- instance = computed(() => this.content()?.instance() ?? null, ...(ngDevMode ? [{ debugName: "instance" }] : []));
2201
+ instance = computed(() => this.content()?.instance() ?? null, /* @ts-ignore */
2202
+ ...(ngDevMode ? [{ debugName: "instance" }] : /* istanbul ignore next */ []));
2177
2203
  /** Guards `ready` to one emission per editor instance. */
2178
2204
  lastReadyInstance = null;
2179
2205
  /**
@@ -2282,6 +2308,15 @@ class BlokEditorComponent {
2282
2308
  editor.placeholder.set(placeholder);
2283
2309
  }
2284
2310
  });
2311
+ effect(() => {
2312
+ const editor = this.instance();
2313
+ const tokens = this.styleTokens$() ?? this.config?.style?.tokens;
2314
+ if (!editor || tokens === undefined || deepEqual(tokens, this.appliedTokens)) {
2315
+ return;
2316
+ }
2317
+ this.appliedTokens = { ...tokens };
2318
+ editor.tokens.set(tokens);
2319
+ });
2285
2320
  effect(() => {
2286
2321
  const editor = this.instance();
2287
2322
  if (editor && this.autofocus$()) {
@@ -2361,8 +2396,8 @@ class BlokEditorComponent {
2361
2396
  setDisabledState(isDisabled) {
2362
2397
  this.readOnly$.set(isDisabled);
2363
2398
  }
2364
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: BlokEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2365
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.25", type: BlokEditorComponent, isStandalone: true, selector: "blok-editor", inputs: { onBeforeRender: "onBeforeRender", onBeforePaste: "onBeforePaste", readOnly: "readOnly", theme: "theme", width: "width", placeholder: "placeholder", autofocus: "autofocus", data: "data", tools: "tools", config: "config", recreateKey: "recreateKey" }, outputs: { ready: "ready", dataChange: "dataChange", save: "save", change: "change", afterRender: "afterRender", themeChange: "themeChange", blocksRendered: "blocksRendered", blockRendered: "blockRendered" }, providers: [
2399
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: BlokEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2400
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.7", type: BlokEditorComponent, isStandalone: true, selector: "blok-editor", inputs: { onBeforeRender: "onBeforeRender", onBeforePaste: "onBeforePaste", readOnly: "readOnly", theme: "theme", width: "width", placeholder: "placeholder", styleTokens: "styleTokens", autofocus: "autofocus", data: "data", tools: "tools", config: "config", recreateKey: "recreateKey" }, outputs: { ready: "ready", dataChange: "dataChange", save: "save", change: "change", afterRender: "afterRender", themeChange: "themeChange", blocksRendered: "blocksRendered", blockRendered: "blockRendered" }, providers: [
2366
2401
  {
2367
2402
  provide: NG_VALUE_ACCESSOR,
2368
2403
  useExisting: forwardRef(() => BlokEditorComponent),
@@ -2370,7 +2405,7 @@ class BlokEditorComponent {
2370
2405
  },
2371
2406
  ], viewQueries: [{ propertyName: "contentQuery", first: true, predicate: BlokContentDirective, descendants: true }], exportAs: ["blok"], ngImport: i0, template: `<div blokContent [config]="buildConfig()" [recreateKey]="recreateKey"></div>`, isInline: true, dependencies: [{ kind: "directive", type: BlokContentDirective, selector: "[blokContent]", inputs: ["config", "recreateKey"], outputs: ["ready"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2372
2407
  }
2373
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: BlokEditorComponent, decorators: [{
2408
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: BlokEditorComponent, decorators: [{
2374
2409
  type: Component,
2375
2410
  args: [{
2376
2411
  selector: 'blok-editor',
@@ -2418,6 +2453,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
2418
2453
  type: Input
2419
2454
  }], placeholder: [{
2420
2455
  type: Input
2456
+ }], styleTokens: [{
2457
+ type: Input
2421
2458
  }], autofocus: [{
2422
2459
  type: Input
2423
2460
  }], data: [{
@@ -2487,8 +2524,10 @@ function createAngularBlock(spec) {
2487
2524
  this.pointerDrag = () => api?.blocks?.isPointerDragActive === true;
2488
2525
  this.mirror = fillDefaults(spec.propSchema, (options.data ?? {}));
2489
2526
  this.lastRendered = this.mirror;
2490
- this.dataSig = signal(this.mirror, ...(ngDevMode ? [{ debugName: "dataSig" }] : []));
2491
- this.readOnlySig = signal(options.readOnly, ...(ngDevMode ? [{ debugName: "readOnlySig" }] : []));
2527
+ this.dataSig = signal(this.mirror, /* @ts-ignore */
2528
+ ...(ngDevMode ? [{ debugName: "dataSig" }] : /* istanbul ignore next */ []));
2529
+ this.readOnlySig = signal(options.readOnly, /* @ts-ignore */
2530
+ ...(ngDevMode ? [{ debugName: "readOnlySig" }] : /* istanbul ignore next */ []));
2492
2531
  this.ctx = {
2493
2532
  data: this.dataSig.asReadonly(),
2494
2533
  commit: this.commit,
@@ -2657,13 +2696,15 @@ const BLOCK_CHANGED_EVENT = 'block changed';
2657
2696
  function injectBlocks(editor) {
2658
2697
  // Bumped on every `block changed`; the shared API's read methods touch it (via
2659
2698
  // the onRead seam) so template/computed reads stay reactive.
2660
- const version = signal(0, ...(ngDevMode ? [{ debugName: "version" }] : []));
2699
+ const version = signal(0, /* @ts-ignore */
2700
+ ...(ngDevMode ? [{ debugName: "version" }] : /* istanbul ignore next */ []));
2661
2701
  const touch = () => {
2662
2702
  version();
2663
2703
  };
2664
2704
  // The API bound to the CURRENT editor; EMPTY_API while null. A signal so the
2665
2705
  // facade's reads track the editor-identity swap.
2666
- const bound = signal(EMPTY_API, ...(ngDevMode ? [{ debugName: "bound" }] : []));
2706
+ const bound = signal(EMPTY_API, /* @ts-ignore */
2707
+ ...(ngDevMode ? [{ debugName: "bound" }] : /* istanbul ignore next */ []));
2667
2708
  // One subscription record (no `let` reassignment), re-bound on editor change.
2668
2709
  const sub = { editor: null, handler: null };
2669
2710
  const unsubscribe = () => {