@heyramzi/ui 2.11.0 → 2.11.2

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.
Files changed (267) hide show
  1. package/dist/agents/helpers.js +38 -38
  2. package/dist/agents/page-state.js +49 -50
  3. package/dist/agents/vendor/color.js +146 -127
  4. package/dist/agents/vendor/draw.js +617 -508
  5. package/dist/agents/vendor/engine.js +698 -599
  6. package/dist/agents/vendor/mesh.js +653 -683
  7. package/dist/agents/vendor/plastic.js +3913 -3112
  8. package/dist/agents/vendor/presets.js +163 -164
  9. package/dist/agents/vendor/shapes.js +21 -20
  10. package/dist/agents/vendor/ticker.js +41 -42
  11. package/dist/agents/vendor/types.js +1 -0
  12. package/dist/agents/vendor/wear.js +1421 -1448
  13. package/dist/ai/confirmation/confirmation-context.svelte.js +6 -6
  14. package/dist/ai/confirmation/index.js +3 -1
  15. package/dist/ai/index.js +33 -0
  16. package/dist/ai/prompt-input/index.js +3 -1
  17. package/dist/ai/reasoning/index.js +3 -1
  18. package/dist/ai/reasoning/reasoning-context.svelte.js +6 -6
  19. package/dist/ai/suggestion/index.js +3 -1
  20. package/dist/ai/typing-dots/index.js +3 -1
  21. package/dist/animations/text-swap.js +24 -24
  22. package/dist/brand/index.js +54 -48
  23. package/dist/canvas/card/resize.js +5 -3
  24. package/dist/canvas/edges/edge-path.js +255 -242
  25. package/dist/canvas/editor/context-menu.js +39 -36
  26. package/dist/canvas/editor/dispatch.svelte.js +154 -151
  27. package/dist/canvas/editor/editor-context.js +7 -2
  28. package/dist/canvas/editor/editor-mode.js +1 -0
  29. package/dist/canvas/editor/frame.js +73 -76
  30. package/dist/canvas/editor/hand-context.js +5 -2
  31. package/dist/canvas/editor/history-core.js +163 -191
  32. package/dist/canvas/editor/keymap.js +95 -169
  33. package/dist/canvas/editor/layout-actions.js +143 -144
  34. package/dist/canvas/editor/lock.js +52 -51
  35. package/dist/canvas/editor/rebase.js +217 -240
  36. package/dist/canvas/editor/style.js +132 -137
  37. package/dist/canvas/editor/text-field-context.js +7 -2
  38. package/dist/canvas/editor/z-order.js +65 -70
  39. package/dist/canvas/headless/alignment.js +22 -16
  40. package/dist/canvas/headless/break-apart-find.js +286 -279
  41. package/dist/canvas/headless/break-apart-pieces.js +62 -58
  42. package/dist/canvas/headless/break-apart-plan.js +299 -325
  43. package/dist/canvas/headless/break-apart-style.js +75 -70
  44. package/dist/canvas/headless/break-apart.js +188 -181
  45. package/dist/canvas/headless/canvas-cleanup.js +78 -58
  46. package/dist/canvas/headless/edge-anchors.js +115 -116
  47. package/dist/canvas/headless/edge-memo.js +24 -22
  48. package/dist/canvas/headless/edge-serialization.js +17 -27
  49. package/dist/canvas/headless/figure-geometry.js +232 -264
  50. package/dist/canvas/headless/fit-viewport.js +84 -67
  51. package/dist/canvas/headless/grid.js +88 -86
  52. package/dist/canvas/headless/icon-node.js +44 -36
  53. package/dist/canvas/headless/index.js +1 -0
  54. package/dist/canvas/headless/linkify.js +17 -19
  55. package/dist/canvas/headless/pen-marks.js +101 -95
  56. package/dist/canvas/headless/sketch.js +231 -209
  57. package/dist/canvas/headless/snap-guides.js +99 -83
  58. package/dist/canvas/headless/svg-figure.js +133 -117
  59. package/dist/canvas/headless/table-layout.js +146 -107
  60. package/dist/canvas/index.js +2 -0
  61. package/dist/canvas/lod/lod-mode.svelte.js +20 -18
  62. package/dist/canvas/lod/render-all.svelte.js +36 -39
  63. package/dist/canvas/ops/arrange.js +78 -71
  64. package/dist/canvas/ops/ops.js +260 -255
  65. package/dist/canvas/pen/colors.js +37 -35
  66. package/dist/canvas/pen/eraser.js +28 -27
  67. package/dist/canvas/pen/geometry.js +120 -130
  68. package/dist/canvas/pen/index.js +1 -0
  69. package/dist/canvas/pen/ops.js +11 -11
  70. package/dist/canvas/pen/pen-session.js +150 -159
  71. package/dist/canvas/pen/plugin.js +107 -104
  72. package/dist/canvas/pen/shapes.js +73 -68
  73. package/dist/canvas/pen/stroke-path.js +32 -30
  74. package/dist/canvas/pen/types.js +21 -21
  75. package/dist/canvas/pen/ui.js +10 -8
  76. package/dist/canvas/plugin.js +46 -46
  77. package/dist/canvas/screen/glyphs.js +12 -11
  78. package/dist/canvas/screen/labels.js +22 -22
  79. package/dist/canvas/screen/parts.js +98 -111
  80. package/dist/canvas/screen/plugin.js +47 -56
  81. package/dist/canvas/screen/types.js +30 -35
  82. package/dist/canvas/screen/ui.js +7 -7
  83. package/dist/canvas/test-utils.js +14 -14
  84. package/dist/canvas/types.js +1 -0
  85. package/dist/canvas/ui/forward-wheel.js +24 -25
  86. package/dist/canvas/ui/icons.js +64 -131
  87. package/dist/canvas/ui/place-panel.js +58 -49
  88. package/dist/canvas/ui/shortcut-tip.js +14 -12
  89. package/dist/canvas/ui/tools.js +300 -385
  90. package/dist/charts/dashboard/chart.js +4 -0
  91. package/dist/charts/dashboard/data-table.js +11 -0
  92. package/dist/charts/dashboard/windows.js +8 -3
  93. package/dist/charts/edge-fade.js +10 -5
  94. package/dist/charts/hover-band.js +16 -11
  95. package/dist/charts/index.js +0 -1
  96. package/dist/charts/motion.js +11 -7
  97. package/dist/charts/primitives/chart-utils.js +12 -12
  98. package/dist/components/copy/clipboard.js +32 -32
  99. package/dist/components/copy/copied.svelte.js +31 -23
  100. package/dist/components/data-table/data-table.js +39 -39
  101. package/dist/components/docs/index.js +4 -0
  102. package/dist/components/docs/scroll-spy.svelte.js +73 -68
  103. package/dist/components/list-page/filter-section.js +4 -1
  104. package/dist/components/list-page/index.js +2 -0
  105. package/dist/components/list-page/list-table.js +7 -2
  106. package/dist/components/list-page/queue-rail.js +14 -0
  107. package/dist/components/list-page/section-host.js +4 -2
  108. package/dist/components/list-page/step.js +4 -3
  109. package/dist/components/list-page/types.js +1 -0
  110. package/dist/components/picker/trigger.js +48 -30
  111. package/dist/components/picker/types.js +1 -0
  112. package/dist/components/segmented/collapse.js +38 -27
  113. package/dist/components/segmented/index.js +8 -0
  114. package/dist/components/segmented/segmented.js +67 -42
  115. package/dist/components/star-rating-input/index.js +3 -1
  116. package/dist/components/table-view/types.js +1 -0
  117. package/dist/components/tags-input/tags.js +81 -69
  118. package/dist/components/theme/index.js +4 -0
  119. package/dist/components/toolbar/index.js +4 -0
  120. package/dist/components/toolbar/toolbar-trigger.js +14 -1
  121. package/dist/editor/anchors.js +17 -13
  122. package/dist/editor/block-id.js +52 -51
  123. package/dist/editor/block-ops.js +108 -80
  124. package/dist/editor/doc-blocks.js +155 -166
  125. package/dist/editor/extensions.js +139 -180
  126. package/dist/editor/index.js +4 -0
  127. package/dist/editor/markdown-test-helpers.js +4 -2
  128. package/dist/editor/markdown.js +420 -408
  129. package/dist/editor/serializer.js +204 -200
  130. package/dist/editor/slash-items.js +89 -101
  131. package/dist/editor/youtube-url.js +25 -20
  132. package/dist/effects/animated-beam/path-calculator.svelte.js +43 -38
  133. package/dist/effects/animated-beam/types.js +1 -0
  134. package/dist/effects/border-beam/css.js +92 -78
  135. package/dist/effects/border-beam/presets.js +1705 -1720
  136. package/dist/effects/border-beam/register-properties.js +43 -33
  137. package/dist/effects/border-beam/types.js +1 -0
  138. package/dist/effects/image-comparison/compare.js +3 -2
  139. package/dist/effects/image-reveal/types.js +1 -0
  140. package/dist/effects/magnetic/magnetic.js +58 -52
  141. package/dist/effects/reveal/observe.js +50 -40
  142. package/dist/effects/reveal/types.js +1 -0
  143. package/dist/effects/shader-gradient/color.js +36 -29
  144. package/dist/effects/shader-gradient/renderer.js +384 -295
  145. package/dist/effects/shader-gradient/shaders.js +31 -0
  146. package/dist/effects/shader-gradient/types.js +1 -0
  147. package/dist/icons/apple-symbol-exports.js +99 -124
  148. package/dist/icons/sf-symbols.js +357 -461
  149. package/dist/icons/trades.js +43 -28
  150. package/dist/inbox/index.js +1 -0
  151. package/dist/inbox/logic.js +126 -122
  152. package/dist/inbox/types.js +43 -43
  153. package/dist/lib/arrive.js +19 -12
  154. package/dist/lib/icon-types.js +1 -0
  155. package/dist/lib/initials.js +16 -10
  156. package/dist/lib/layout.js +5 -0
  157. package/dist/lib/panel.js +13 -0
  158. package/dist/lib/result.js +22 -22
  159. package/dist/lib/sliding-pill.js +59 -44
  160. package/dist/lib/theme-transition.js +43 -43
  161. package/dist/lib/tone.js +31 -24
  162. package/dist/lib/utils.js +3 -1
  163. package/dist/onboarding/define-tours.js +24 -23
  164. package/dist/onboarding/onboarding.svelte.js +16 -12
  165. package/dist/onboarding/pick.js +10 -6
  166. package/dist/onboarding/stores.js +40 -41
  167. package/dist/onboarding/wait.js +24 -23
  168. package/dist/panel/side-panel-types.js +1 -0
  169. package/dist/record/demo-data.js +459 -486
  170. package/dist/record/fields.js +129 -131
  171. package/dist/record/format.js +70 -82
  172. package/dist/record/gutter.js +1 -0
  173. package/dist/record/kinds.js +95 -105
  174. package/dist/record/logic.js +238 -219
  175. package/dist/record/types.js +49 -48
  176. package/dist/shadcn/accordion/index.js +3 -1
  177. package/dist/shadcn/alert/index.js +3 -1
  178. package/dist/shadcn/alert-dialog/index.js +3 -1
  179. package/dist/shadcn/attachment/index.js +3 -1
  180. package/dist/shadcn/avatar/index.js +3 -1
  181. package/dist/shadcn/breadcrumb/index.js +3 -1
  182. package/dist/shadcn/bubble/index.js +3 -1
  183. package/dist/shadcn/button/index.js +3 -1
  184. package/dist/shadcn/calendar/index.js +3 -1
  185. package/dist/shadcn/card/index.js +3 -1
  186. package/dist/shadcn/checkbox/index.js +3 -1
  187. package/dist/shadcn/code-block/index.js +3 -1
  188. package/dist/shadcn/collapsible/index.js +3 -1
  189. package/dist/shadcn/command/index.js +4 -1
  190. package/dist/shadcn/context-menu/index.js +3 -1
  191. package/dist/shadcn/dialog/index.js +3 -1
  192. package/dist/shadcn/dropdown-menu/menu-item.js +40 -20
  193. package/dist/shadcn/empty/index.js +3 -1
  194. package/dist/shadcn/field/index.js +3 -1
  195. package/dist/shadcn/hooks/highlighter.js +77 -75
  196. package/dist/shadcn/hooks/is-mobile.svelte.js +3 -3
  197. package/dist/shadcn/hooks/use-highlighted-code.svelte.js +62 -62
  198. package/dist/shadcn/input/index.js +3 -1
  199. package/dist/shadcn/kbd/index.js +3 -1
  200. package/dist/shadcn/label/index.js +3 -1
  201. package/dist/shadcn/marker/index.js +3 -1
  202. package/dist/shadcn/message/index.js +3 -1
  203. package/dist/shadcn/message-scroller/index.js +3 -1
  204. package/dist/shadcn/popover/index.js +3 -1
  205. package/dist/shadcn/progress/index.js +3 -1
  206. package/dist/shadcn/progress/tone.js +8 -7
  207. package/dist/shadcn/radio-group/index.js +3 -1
  208. package/dist/shadcn/scroll-area/index.js +3 -1
  209. package/dist/shadcn/select/index.js +3 -1
  210. package/dist/shadcn/separator/index.js +3 -1
  211. package/dist/shadcn/sheet/index.js +3 -1
  212. package/dist/shadcn/sidebar/context.svelte.js +42 -28
  213. package/dist/shadcn/sidebar/index.js +3 -1
  214. package/dist/shadcn/skeleton/index.js +3 -1
  215. package/dist/shadcn/slider/index.js +3 -1
  216. package/dist/shadcn/switch/index.js +3 -1
  217. package/dist/shadcn/table/index.js +3 -1
  218. package/dist/shadcn/tabs/index.js +3 -1
  219. package/dist/shadcn/textarea/index.js +3 -1
  220. package/dist/shadcn/toggle/index.js +3 -1
  221. package/dist/shadcn/toggle-group/index.js +3 -1
  222. package/dist/shadcn/tooltip/context.js +7 -2
  223. package/dist/shadcn/tooltip/index.js +3 -1
  224. package/dist/shadcn/trace/index.js +3 -1
  225. package/dist/slides/bridges.js +65 -59
  226. package/dist/slides/deck-controller.svelte.js +210 -207
  227. package/dist/slides/export/capture.js +66 -71
  228. package/dist/slides/export/ffmpeg.js +76 -72
  229. package/dist/slides/export/index.js +3 -0
  230. package/dist/slides/export/launch.js +9 -6
  231. package/dist/slides/export/pdf.js +60 -54
  232. package/dist/slides/export/types.js +1 -0
  233. package/dist/slides/labels.js +24 -24
  234. package/dist/slides/layout.js +39 -41
  235. package/dist/slides/model.js +9 -7
  236. package/dist/slides/navigation.js +78 -73
  237. package/dist/slides/types.js +2 -2
  238. package/dist/status/define-statuses.js +18 -14
  239. package/dist/status/status-types.js +1 -0
  240. package/dist/test-setup.js +24 -20
  241. package/dist/thread/logic.js +73 -77
  242. package/dist/thread/types.js +21 -21
  243. package/dist/work/board-order.js +94 -90
  244. package/dist/work/dates.js +16 -9
  245. package/dist/work/detail/detail-types.js +18 -18
  246. package/dist/work/docs/edited.js +32 -29
  247. package/dist/work/docs/index.js +4 -0
  248. package/dist/work/docs/labels.js +34 -34
  249. package/dist/work/docs/menu.js +113 -106
  250. package/dist/work/docs/outline.js +39 -29
  251. package/dist/work/gantt/logic.js +211 -235
  252. package/dist/work/inbox/inbox-logic.js +71 -75
  253. package/dist/work/inbox/inbox-statuses.js +75 -72
  254. package/dist/work/inbox/inbox-types.js +1 -0
  255. package/dist/work/kanban-drag.js +27 -22
  256. package/dist/work/kanban-types.js +1 -0
  257. package/dist/work/presets/sales.js +36 -32
  258. package/dist/work/reorder.js +9 -8
  259. package/dist/work/task-types.js +1 -0
  260. package/dist/work/time/duration.js +51 -46
  261. package/dist/work/time/time-types.js +23 -23
  262. package/dist/work/use-kanban-dnd.svelte.js +126 -125
  263. package/package.json +3 -1
  264. package/src/components/list-page/master-detail.svelte +3 -1
  265. package/src/components/list-page/rail-row.svelte +4 -4
  266. package/src/components/tags-input/tags-input.svelte +2 -0
  267. package/src/editor/markdown.ts +30 -35
@@ -1,121 +1,128 @@
1
+ /**
2
+ * The `…` menu as data: which items exist, which show, how a filter reads them and
3
+ * which keys fire them. The component only draws what this returns.
4
+ */
1
5
  import { tiptapToMarkdown } from "../../editor/markdown.js";
2
6
  export const SHORTCUTS = {
3
- move: {
4
- key: "P",
5
- shift: true
6
- },
7
- rename: {
8
- key: "R",
9
- shift: true
10
- },
11
- favorite: {
12
- key: "F",
13
- alt: true
14
- },
15
- remind: {
16
- key: "H",
17
- shift: true
18
- }
7
+ move: {
8
+ key: "P",
9
+ shift: true
10
+ },
11
+ rename: {
12
+ key: "R",
13
+ shift: true
14
+ },
15
+ favorite: {
16
+ key: "F",
17
+ alt: true
18
+ },
19
+ remind: {
20
+ key: "H",
21
+ shift: true
22
+ }
19
23
  };
24
+ /** "⇧P", "⌥F". */
20
25
  export function shortcutLabel(shortcut) {
21
- return `${shortcut.shift ? "⇧" : ""}${shortcut.alt ? "⌥" : ""}${shortcut.key.toUpperCase()}`;
26
+ return `${shortcut.shift ? "⇧" : ""}${shortcut.alt ? "⌥" : ""}${shortcut.key.toUpperCase()}`;
22
27
  }
23
28
  export function menuItems(available, labels, options = {}) {
24
- const all = [
25
- {
26
- id: "move",
27
- label: labels.moveTo,
28
- group: 0
29
- },
30
- {
31
- id: "duplicate",
32
- label: labels.duplicate,
33
- group: 0
34
- },
35
- {
36
- id: "rename",
37
- label: labels.rename,
38
- group: 0
39
- },
40
- {
41
- id: "template",
42
- label: labels.template,
43
- group: 0
44
- },
45
- {
46
- id: "favorite",
47
- label: options.favorited ? labels.unfavorite : labels.favorite,
48
- group: 1
49
- },
50
- {
51
- id: "copy",
52
- label: labels.copy,
53
- submenu: true,
54
- group: 1
55
- },
56
- {
57
- id: "remind",
58
- label: labels.remind,
59
- group: 1
60
- },
61
- {
62
- id: "history",
63
- label: labels.history,
64
- group: 2
65
- },
66
- {
67
- id: "delete",
68
- label: labels.delete,
69
- danger: true,
70
- group: 2
71
- }
72
- ];
73
- return all.filter((item)=>available[item.id]).map((item)=>Object.assign(item, {
74
- shortcut: SHORTCUTS[item.id]
75
- }));
29
+ const all = [
30
+ {
31
+ id: "move",
32
+ label: labels.moveTo,
33
+ group: 0
34
+ },
35
+ {
36
+ id: "duplicate",
37
+ label: labels.duplicate,
38
+ group: 0
39
+ },
40
+ {
41
+ id: "rename",
42
+ label: labels.rename,
43
+ group: 0
44
+ },
45
+ {
46
+ id: "template",
47
+ label: labels.template,
48
+ group: 0
49
+ },
50
+ {
51
+ id: "favorite",
52
+ label: options.favorited ? labels.unfavorite : labels.favorite,
53
+ group: 1
54
+ },
55
+ {
56
+ id: "copy",
57
+ label: labels.copy,
58
+ submenu: true,
59
+ group: 1
60
+ },
61
+ {
62
+ id: "remind",
63
+ label: labels.remind,
64
+ group: 1
65
+ },
66
+ {
67
+ id: "history",
68
+ label: labels.history,
69
+ group: 2
70
+ },
71
+ {
72
+ id: "delete",
73
+ label: labels.delete,
74
+ danger: true,
75
+ group: 2
76
+ }
77
+ ];
78
+ return all.filter((item) => available[item.id]).map((item) => Object.assign(item, { shortcut: SHORTCUTS[item.id] }));
76
79
  }
80
+ /** Case-insensitive, every typed word must appear. An empty query keeps everything. */
77
81
  export function filterMenu(items, query) {
78
- const words = query.toLowerCase().split(/\s+/).filter(Boolean);
79
- if (words.length === 0) return items;
80
- return items.filter((item)=>{
81
- const label = item.label.toLowerCase();
82
- return words.every((word)=>label.includes(word));
83
- });
82
+ const words = query.toLowerCase().split(/\s+/).filter(Boolean);
83
+ if (words.length === 0) return items;
84
+ return items.filter((item) => {
85
+ const label = item.label.toLowerCase();
86
+ return words.every((word) => label.includes(word));
87
+ });
84
88
  }
89
+ /** The item a key press fires, or null. `code` is the physical key, since Option+F types "ƒ". */
85
90
  export function shortcutTarget(event, items) {
86
- if (event.metaKey || event.ctrlKey) return null;
87
- const hit = items.find((item)=>item.shortcut && event.code === `Key${item.shortcut.key.toUpperCase()}` && !!item.shortcut.shift === event.shiftKey && !!item.shortcut.alt === event.altKey);
88
- return hit?.id ?? null;
91
+ if (event.metaKey || event.ctrlKey) return null;
92
+ const hit = items.find((item) => item.shortcut && event.code === `Key${item.shortcut.key.toUpperCase()}` && !!item.shortcut.shift === event.shiftKey && !!item.shortcut.alt === event.altKey);
93
+ return hit?.id ?? null;
89
94
  }
95
+ /** The Copy submenu. A kind with nothing to copy is left out: no URL, no content. */
90
96
  export function copyOptions(source, labels) {
91
- const title = source.title.trim() || labels.untitled;
92
- const options = [];
93
- if (source.url) options.push({
94
- kind: "url",
95
- label: labels.copyUrl,
96
- text: source.url
97
- });
98
- options.push({
99
- kind: "title",
100
- label: labels.copyTitle,
101
- text: title
102
- });
103
- if (source.url) {
104
- options.push({
105
- kind: "link",
106
- label: labels.copyTitleAsLink,
107
- text: `[${title.replace(/([[\]\\])/g, "\\$1")}](${source.url})`
108
- });
109
- }
110
- if (source.content) {
111
- options.push({
112
- kind: "markdown",
113
- label: labels.copyMarkdown,
114
- text: tiptapToMarkdown(source.content)
115
- });
116
- }
117
- return options;
97
+ const title = source.title.trim() || labels.untitled;
98
+ const options = [];
99
+ if (source.url) options.push({
100
+ kind: "url",
101
+ label: labels.copyUrl,
102
+ text: source.url
103
+ });
104
+ options.push({
105
+ kind: "title",
106
+ label: labels.copyTitle,
107
+ text: title
108
+ });
109
+ if (source.url) {
110
+ options.push({
111
+ kind: "link",
112
+ label: labels.copyTitleAsLink,
113
+ text: `[${title.replace(/([[\]\\])/g, "\\$1")}](${source.url})`
114
+ });
115
+ }
116
+ if (source.content) {
117
+ options.push({
118
+ kind: "markdown",
119
+ label: labels.copyMarkdown,
120
+ text: tiptapToMarkdown(source.content)
121
+ });
122
+ }
123
+ return options;
118
124
  }
125
+ /** What the delete confirm calls the doc. */
119
126
  export function deleteName(title, labels) {
120
- return title.trim() || labels.untitled;
127
+ return title.trim() || labels.untitled;
121
128
  }
@@ -1,39 +1,49 @@
1
+ /**
2
+ * The outline of a document: which headings it lists, and the anchor each one gets.
3
+ * Pure, so the editor's anchors and the outline's ids can never disagree.
4
+ */
1
5
  import { anchorIds } from "../../editor/anchors.js";
2
6
  export { anchorIds, slugify } from "../../editor/anchors.js";
3
7
  function textOf(node) {
4
- if (node.type === "text") return node.text ?? "";
5
- return (node.content ?? []).map(textOf).join("");
8
+ if (node.type === "text") return node.text ?? "";
9
+ return (node.content ?? []).map(textOf).join("");
6
10
  }
11
+ /** Every heading in document order, at any depth, with its anchor. */
7
12
  export function headingsOf(doc) {
8
- const found = [];
9
- const walk = (node)=>{
10
- if (node.type === "heading") {
11
- const level = typeof node.attrs?.level === "number" ? node.attrs.level : 1;
12
- found.push({
13
- label: textOf(node).trim(),
14
- level
15
- });
16
- return;
17
- }
18
- for (const child of node.content ?? [])walk(child);
19
- };
20
- if (doc && typeof doc === "object") walk(doc);
21
- const ids = anchorIds(found.map((heading)=>heading.label));
22
- return found.map((heading, i)=>({
23
- id: ids[i],
24
- label: heading.label,
25
- level: heading.level
26
- }));
13
+ const found = [];
14
+ const walk = (node) => {
15
+ if (node.type === "heading") {
16
+ const level = typeof node.attrs?.level === "number" ? node.attrs.level : 1;
17
+ found.push({
18
+ label: textOf(node).trim(),
19
+ level
20
+ });
21
+ return;
22
+ }
23
+ for (const child of node.content ?? []) walk(child);
24
+ };
25
+ if (doc && typeof doc === "object") walk(doc);
26
+ const ids = anchorIds(found.map((heading) => heading.label));
27
+ return found.map((heading, i) => ({
28
+ id: ids[i],
29
+ label: heading.label,
30
+ level: heading.level
31
+ }));
27
32
  }
33
+ /**
34
+ * What the outline lists: H2 and H3 with a label. H1 and H4 are ignored, and a
35
+ * document with fewer than two entries gets no outline at all.
36
+ */
28
37
  export function outlineOf(headings) {
29
- const items = headings.filter((heading)=>(heading.level === 2 || heading.level === 3) && heading.label !== "");
30
- if (items.length < 2) return [];
31
- return items.map(({ id, label, level })=>({
32
- id,
33
- label,
34
- level
35
- }));
38
+ const items = headings.filter((heading) => (heading.level === 2 || heading.level === 3) && heading.label !== "");
39
+ if (items.length < 2) return [];
40
+ return items.map(({ id, label, level }) => ({
41
+ id,
42
+ label,
43
+ level
44
+ }));
36
45
  }
46
+ /** The outline of a Tiptap document. */
37
47
  export function outlineOfDoc(doc) {
38
- return outlineOf(headingsOf(doc));
48
+ return outlineOf(headingsOf(doc));
39
49
  }