@jackuait/blok 0.7.3-beta.2 → 0.7.3-beta.4

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.
@@ -138,7 +138,7 @@ var r = Object.create, i = Object.defineProperty, a = Object.getOwnPropertyDescr
138
138
  RIGHT: 2,
139
139
  BACKWARD: 3,
140
140
  FORWARD: 4
141
- }, g = () => "0.7.3-beta.2", _ = /* @__PURE__ */ function(e) {
141
+ }, g = () => "0.7.3-beta.3", _ = /* @__PURE__ */ function(e) {
142
142
  return e.VERBOSE = "VERBOSE", e.INFO = "INFO", e.WARN = "WARN", e.ERROR = "ERROR", e;
143
143
  }({}), v = (e, t, n = "log", r, i = "color: inherit") => {
144
144
  let a = typeof console > "u" ? void 0 : console;
@@ -1,4 +1,4 @@
1
- import { $ as e, A as t, B as n, Ct as r, D as i, F as a, G as o, H as s, I as c, J as l, Jt as u, K as d, L as f, M as p, Mt as m, N as h, Nt as g, Ot as _, P as ee, Q as te, R as ne, St as re, Tn as v, Tt as ie, U as ae, V as oe, W as se, X as ce, a as le, c as ue, ct as de, d as fe, dt as pe, et as me, f as he, ft as ge, g as _e, h as ve, ht as ye, i as be, it as xe, j as Se, k as Ce, kt as y, l as we, lt as Te, mt as Ee, n as De, nt as Oe, o as ke, ot as Ae, p as je, pt as Me, q as Ne, r as Pe, rt as Fe, s as Ie, st as Le, t as Re, tt as ze, u as b, ut as Be, v as Ve, vn as He, vt as Ue, wn as x, z as We } from "./constants-DWpV4hCh.mjs";
1
+ import { $ as e, A as t, B as n, Ct as r, D as i, F as a, G as o, H as s, I as c, J as l, Jt as u, K as d, L as f, M as p, Mt as m, N as h, Nt as g, Ot as _, P as ee, Q as te, R as ne, St as re, Tn as v, Tt as ie, U as ae, V as oe, W as se, X as ce, a as le, c as ue, ct as de, d as fe, dt as pe, et as me, f as he, ft as ge, g as _e, h as ve, ht as ye, i as be, it as xe, j as Se, k as Ce, kt as y, l as we, lt as Te, mt as Ee, n as De, nt as Oe, o as ke, ot as Ae, p as je, pt as Me, q as Ne, r as Pe, rt as Fe, s as Ie, st as Le, t as Re, tt as ze, u as b, ut as Be, v as Ve, vn as He, vt as Ue, wn as x, z as We } from "./constants-C_H9o9Ao.mjs";
2
2
  import { t as S } from "./objectSpread2-CyPxu8-u.mjs";
3
3
  import { n as C } from "./tw-DmW6-pCY.mjs";
4
4
  //#region src/components/utils/html.ts
package/dist/full.mjs CHANGED
@@ -1,7 +1,7 @@
1
- import { wn as e } from "./chunks/constants-DWpV4hCh.mjs";
2
- import { n as t, t as n } from "./chunks/blok-Cv1zWiST.mjs";
1
+ import { wn as e } from "./chunks/constants-C_H9o9Ao.mjs";
2
+ import { n as t, t as n } from "./chunks/blok-CdxHhr5i.mjs";
3
3
  import { t as r } from "./chunks/objectSpread2-CyPxu8-u.mjs";
4
- import { a as i, d as a, i as o, l as s, n as c, o as l, r as u, s as d, t as f, u as p } from "./chunks/tools-CUIpIxxP.mjs";
4
+ import { a as i, d as a, i as o, l as s, n as c, o as l, r as u, s as d, t as f, u as p } from "./chunks/tools-B0YXCZFW.mjs";
5
5
  //#region src/full.ts
6
6
  var m = {
7
7
  paragraph: {
package/dist/react.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import "./chunks/constants-DWpV4hCh.mjs";
2
- import { r as e, t } from "./chunks/blok-Cv1zWiST.mjs";
1
+ import "./chunks/constants-C_H9o9Ao.mjs";
2
+ import { r as e, t } from "./chunks/blok-CdxHhr5i.mjs";
3
3
  import { t as n } from "./chunks/objectSpread2-CyPxu8-u.mjs";
4
4
  import { forwardRef as r, useEffect as i, useMemo as a, useRef as o, useState as s } from "react";
5
5
  import { jsx as c } from "react/jsx-runtime";
package/dist/tools.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { m as e } from "./chunks/constants-DWpV4hCh.mjs";
2
- import { a as t, c as n, d as r, i, l as a, n as o, o as s, r as c, s as l, t as u, u as d } from "./chunks/tools-CUIpIxxP.mjs";
1
+ import { m as e } from "./chunks/constants-C_H9o9Ao.mjs";
2
+ import { a as t, c as n, d as r, i, l as a, n as o, o as s, r as c, s as l, t as u, u as d } from "./chunks/tools-B0YXCZFW.mjs";
3
3
  export { s as Bold, e as Convert, d as Header, t as Italic, i as Link, a as List, c as Marker, r as Paragraph, n as Table, l as Toggle, u as defaultBlockTools, o as defaultInlineTools };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jackuait/blok",
3
- "version": "0.7.3-beta.2",
3
+ "version": "0.7.3-beta.4",
4
4
  "description": "Blok — headless, highly extensible rich text editor built for developers who need to implement a block-based editing experience (similar to Notion) without building it from scratch",
5
5
  "module": "dist/blok.mjs",
6
6
  "types": "./types/index.d.ts",
@@ -200,4 +200,4 @@
200
200
  "optional": true
201
201
  }
202
202
  }
203
- }
203
+ }
@@ -41,11 +41,12 @@ interface LegacyListData {
41
41
 
42
42
  /**
43
43
  * Legacy toggle list data structure for data model transformation.
44
- * Old format: { title: string, isExpanded?: boolean, body: { blocks: [], time, version } }
44
+ * Old format: { title: string, isExpanded?: boolean, body: { blocks: [], time, version }, titleVariant?: number }
45
45
  */
46
46
  interface LegacyToggleListData {
47
47
  title: string;
48
48
  isExpanded?: boolean;
49
+ titleVariant?: number;
49
50
  body?: {
50
51
  time?: number;
51
52
  blocks?: OutputBlockData[];
@@ -326,19 +327,37 @@ const expandToggleListToHierarchical = (
326
327
  });
327
328
  }
328
329
 
329
- // Create the toggle block with mapped fields
330
- const toggleBlock: OutputBlockData = {
330
+ const sharedFields = {
331
331
  id: toggleId,
332
- type: 'toggle',
333
- data: {
334
- text: block.data.title,
335
- ...(typeof block.data.isExpanded === 'boolean' ? { isOpen: block.data.isExpanded } : {}),
336
- },
337
332
  ...(block.tunes !== undefined ? { tunes: block.tunes } : {}),
338
333
  ...(childIds.length > 0 ? { content: childIds } : {}),
339
334
  };
340
335
 
341
- blocks.push(toggleBlock);
336
+ const isOpenField = typeof block.data.isExpanded === 'boolean' ? { isOpen: block.data.isExpanded } : {};
337
+
338
+ // When titleVariant is set, produce a toggle heading (header with isToggleable)
339
+ if (typeof block.data.titleVariant === 'number') {
340
+ blocks.push({
341
+ ...sharedFields,
342
+ type: 'header',
343
+ data: {
344
+ text: block.data.title,
345
+ level: block.data.titleVariant,
346
+ isToggleable: true,
347
+ ...isOpenField,
348
+ },
349
+ });
350
+ } else {
351
+ blocks.push({
352
+ ...sharedFields,
353
+ type: 'toggle',
354
+ data: {
355
+ text: block.data.title,
356
+ ...isOpenField,
357
+ },
358
+ });
359
+ }
360
+
342
361
  blocks.push(...childBlocks);
343
362
 
344
363
  return blocks;
@@ -546,6 +565,65 @@ const isFlatModelToggleBlock = (block: OutputBlockData): boolean => {
546
565
  return block.type === 'toggle';
547
566
  };
548
567
 
568
+ /**
569
+ * Check if a block is a toggleable header (header with isToggleable: true)
570
+ */
571
+ const isToggleableHeaderBlock = (block: OutputBlockData): boolean => {
572
+ if (block.type !== 'header') {
573
+ return false;
574
+ }
575
+
576
+ const data: unknown = block.data;
577
+
578
+ return typeof data === 'object' && data !== null && (data as Record<string, unknown>).isToggleable === true;
579
+ };
580
+
581
+ /**
582
+ * Process a root toggleable header block and convert to a legacy toggleList block with titleVariant
583
+ */
584
+ const processRootToggleableHeader = (
585
+ block: OutputBlockData,
586
+ blockMap: Map<BlockId, OutputBlockData>,
587
+ processedIds: Set<BlockId>
588
+ ): OutputBlockData => {
589
+ markBlockAsProcessed(block.id, processedIds);
590
+
591
+ const data: unknown = block.data;
592
+ const text = isObjectWithText(data) ? data.text : '';
593
+ const level = typeof (data as Record<string, unknown>)?.level === 'number'
594
+ ? (data as Record<string, unknown>).level as number
595
+ : undefined;
596
+ const isOpen = typeof (data as Record<string, unknown>)?.isOpen === 'boolean'
597
+ ? (data as Record<string, unknown>).isOpen as boolean
598
+ : undefined;
599
+
600
+ const childBlocks: OutputBlockData[] = [];
601
+ const contentIds = block.content ?? [];
602
+
603
+ for (const childId of contentIds) {
604
+ const childBlock = blockMap.get(childId);
605
+
606
+ if (childBlock) {
607
+ markBlockAsProcessed(childId, processedIds);
608
+ childBlocks.push(stripHierarchyFields(childBlock));
609
+ }
610
+ }
611
+
612
+ const legacyBlock: OutputBlockData = {
613
+ id: block.id,
614
+ type: 'toggleList',
615
+ data: {
616
+ title: text,
617
+ ...(level !== undefined ? { titleVariant: level } : {}),
618
+ ...(isOpen !== undefined ? { isExpanded: isOpen } : {}),
619
+ ...(childBlocks.length > 0 ? { body: { blocks: childBlocks } } : {}),
620
+ },
621
+ ...(block.tunes !== undefined ? { tunes: block.tunes } : {}),
622
+ };
623
+
624
+ return legacyBlock;
625
+ };
626
+
549
627
  /**
550
628
  * Check if a block is a flat-model list block (has 'text' field instead of 'items')
551
629
  */
@@ -579,8 +657,9 @@ export const collapseToLegacy = (blocks: OutputBlockData[]): OutputBlockData[] =
579
657
  // If no flat-model list or toggle blocks, just strip hierarchy fields and return
580
658
  const hasFlatListBlocks = blocks.some(isFlatModelListBlock);
581
659
  const hasFlatToggleBlocks = blocks.some(isFlatModelToggleBlock);
660
+ const hasFlatToggleableHeaders = blocks.some(b => isToggleableHeaderBlock(b) && !b.parent);
582
661
 
583
- if (!hasFlatListBlocks && !hasFlatToggleBlocks) {
662
+ if (!hasFlatListBlocks && !hasFlatToggleBlocks && !hasFlatToggleableHeaders) {
584
663
  return blocks.map(stripHierarchyFields);
585
664
  }
586
665
 
@@ -599,7 +678,9 @@ export const collapseToLegacy = (blocks: OutputBlockData[]): OutputBlockData[] =
599
678
  const isRootListItem = isFlatListBlock && !block.parent;
600
679
  const isFlatToggleBlock = isFlatModelToggleBlock(block);
601
680
  const isRootToggleItem = isFlatToggleBlock && !block.parent;
602
- const isNonListItem = !isFlatListBlock && !isFlatToggleBlock;
681
+ const isToggleableHeader = isToggleableHeaderBlock(block);
682
+ const isRootToggleableHeader = isToggleableHeader && !block.parent;
683
+ const isNonListItem = !isFlatListBlock && !isFlatToggleBlock && !isToggleableHeader;
603
684
 
604
685
  if (isRootListItem) {
605
686
  const listBlock = processRootListItem(block, blockMap, processedIds);
@@ -613,6 +694,12 @@ export const collapseToLegacy = (blocks: OutputBlockData[]): OutputBlockData[] =
613
694
  result.push(toggleBlock);
614
695
  }
615
696
 
697
+ if (isRootToggleableHeader) {
698
+ const legacyBlock = processRootToggleableHeader(block, blockMap, processedIds);
699
+
700
+ result.push(legacyBlock);
701
+ }
702
+
616
703
  if (isNonListItem) {
617
704
  result.push(stripHierarchyFields(block));
618
705
  markBlockAsProcessed(block.id, processedIds);
@@ -0,0 +1,23 @@
1
+ import { BlockTool, BlockToolConstructable, BlockToolConstructorOptions, BlockToolData } from './block-tool';
2
+
3
+ /**
4
+ * Toggle Tool's input and output data format
5
+ */
6
+ export interface ToggleData extends BlockToolData {
7
+ /** Toggle item text content (can include HTML) */
8
+ text: string;
9
+ /** Whether the toggle is open (expanded). Persisted on save so state is restored on reload. */
10
+ isOpen?: boolean;
11
+ }
12
+
13
+ /**
14
+ * Toggle Tool's configuration
15
+ */
16
+ export interface ToggleConfig {
17
+ /** Custom placeholder text for empty toggle items */
18
+ placeholder?: string;
19
+ }
20
+
21
+ export interface ToggleConstructable extends BlockToolConstructable {
22
+ new(options: BlockToolConstructorOptions<ToggleData, ToggleConfig>): BlockTool;
23
+ }
@@ -7,6 +7,7 @@ import { HeaderConstructable, HeaderData, HeaderConfig } from './tools/header';
7
7
  import { ParagraphConstructable, ParagraphData, ParagraphConfig } from './tools/paragraph';
8
8
  import { ListConstructable, ListData, ListConfig, ListStyle } from './tools/list';
9
9
  import { TableConstructable, TableData, TableConfig, CellContent } from './tools/table';
10
+ import { ToggleConstructable, ToggleData, ToggleConfig } from './tools/toggle';
10
11
  import { InlineToolConstructable } from './tools/inline-tool';
11
12
  import { BlockTuneConstructable } from './block-tunes';
12
13
  import { ToolSettings } from './tools';
@@ -16,12 +17,14 @@ export const Paragraph: ParagraphConstructable;
16
17
  export const Header: HeaderConstructable;
17
18
  export const List: ListConstructable;
18
19
  export const Table: TableConstructable;
20
+ export const Toggle: ToggleConstructable;
19
21
 
20
22
  // Re-export data and config types for convenience
21
23
  export { HeaderData, HeaderConfig } from './tools/header';
22
24
  export { ParagraphData, ParagraphConfig } from './tools/paragraph';
23
25
  export { ListData, ListConfig, ListStyle } from './tools/list';
24
26
  export { TableData, TableConfig, CellContent } from './tools/table';
27
+ export { ToggleData, ToggleConfig } from './tools/toggle';
25
28
 
26
29
  // Inline tools
27
30
  export const Bold: InlineToolConstructable;