@bendyline/squisq-editor-react 2.3.3 → 2.3.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.
@@ -30160,7 +30160,12 @@ function InlinePreviewGutter({
30160
30160
  }
30161
30161
 
30162
30162
  // src/buildPreviewDoc.ts
30163
- import { deriveTemplateInputs as deriveTemplateInputs3, flattenRenderableBlocks, hasTemplate as hasTemplate2 } from "@bendyline/squisq/doc";
30163
+ import {
30164
+ coerceTemplateParams,
30165
+ deriveTemplateInputs as deriveTemplateInputs3,
30166
+ flattenRenderableBlocks,
30167
+ hasTemplate as hasTemplate2
30168
+ } from "@bendyline/squisq/doc";
30164
30169
  import { extractPlainText as extractPlainText4, KNOWN_BLOCK_META_KEYS as KNOWN_BLOCK_META_KEYS2 } from "@bendyline/squisq/markdown";
30165
30170
  import { getChildren as getChildren2 } from "@bendyline/squisq/markdown";
30166
30171
  import { iconMarker } from "@bendyline/squisq/icon-marker";
@@ -30312,6 +30317,8 @@ function blockToSlide(block, index2, knownTemplates) {
30312
30317
  const recognized = hasTemplate2(requestedTemplate) || isCustomTemplate;
30313
30318
  const template = recognized ? requestedTemplate : "sectionHeader";
30314
30319
  const defaults = getTemplateDefaults2(template, headingText2, block);
30320
+ const templateOverrides = omitStringBlockMeta(block.templateOverrides);
30321
+ const coercedTemplateOverrides = templateOverrides ? coerceTemplateParams(template, templateOverrides).input : void 0;
30315
30322
  const {
30316
30323
  id: _id,
30317
30324
  startTime: _st,
@@ -30361,7 +30368,7 @@ function blockToSlide(block, index2, knownTemplates) {
30361
30368
  // `transition=vortex` into the string `"vortex"`, which the player can't
30362
30369
  // animate. Omit them from the content spreads so the typed fields win.
30363
30370
  ...omitBlockMeta(block.templateData),
30364
- ...omitBlockMeta(block.templateOverrides)
30371
+ ...coercedTemplateOverrides
30365
30372
  };
30366
30373
  }
30367
30374
  var BLOCK_META_KEYS2 = new Set(Object.keys(KNOWN_BLOCK_META_KEYS2));
@@ -30378,6 +30385,19 @@ function omitBlockMeta(data) {
30378
30385
  }
30379
30386
  return hit ? out : data;
30380
30387
  }
30388
+ function omitStringBlockMeta(data) {
30389
+ if (!data) return data;
30390
+ let hit = false;
30391
+ const out = {};
30392
+ for (const key of Object.keys(data)) {
30393
+ if (BLOCK_META_KEYS2.has(key)) {
30394
+ hit = true;
30395
+ continue;
30396
+ }
30397
+ out[key] = data[key];
30398
+ }
30399
+ return hit ? out : data;
30400
+ }
30381
30401
  var IMAGE_MOTIONS = [
30382
30402
  "zoomIn",
30383
30403
  "zoomOut",
@@ -32173,9 +32193,11 @@ function PlainHtmlPreview({
32173
32193
  className,
32174
32194
  style,
32175
32195
  globalKeyboardShortcuts = false,
32176
- onFrameChange
32196
+ onFrameChange,
32197
+ onLinkClick
32177
32198
  }) {
32178
32199
  const iframeRef = useRef45(null);
32200
+ const removeFrameLinkHandlerRef = useRef45(() => void 0);
32179
32201
  const setIframeRef = useCallback44(
32180
32202
  (frame) => {
32181
32203
  iframeRef.current = frame;
@@ -32236,6 +32258,29 @@ function PlainHtmlPreview({
32236
32258
  () => renderFn ? renderFn(mdDoc, { title, images: mergedImages, theme, iconsCss }) : "",
32237
32259
  [renderFn, mdDoc, title, mergedImages, theme, iconsCss]
32238
32260
  );
32261
+ const installFrameLinkHandler = useCallback44(() => {
32262
+ removeFrameLinkHandlerRef.current();
32263
+ removeFrameLinkHandlerRef.current = () => void 0;
32264
+ const frameDocument = iframeRef.current?.contentDocument;
32265
+ const FrameElement = frameDocument?.defaultView?.Element;
32266
+ if (!frameDocument || !FrameElement || !onLinkClick) return;
32267
+ const handleClick = (event) => {
32268
+ if (event.button !== 0) return;
32269
+ const target = event.target instanceof FrameElement ? event.target : null;
32270
+ const anchor = target?.closest("a[href]");
32271
+ if (!anchor || !frameDocument.contains(anchor)) return;
32272
+ const href = anchor.getAttribute("href");
32273
+ if (!href || onLinkClick(href) === false) return;
32274
+ event.preventDefault();
32275
+ event.stopPropagation();
32276
+ };
32277
+ frameDocument.addEventListener("click", handleClick, true);
32278
+ removeFrameLinkHandlerRef.current = () => frameDocument.removeEventListener("click", handleClick, true);
32279
+ }, [onLinkClick]);
32280
+ useEffect44(() => {
32281
+ installFrameLinkHandler();
32282
+ return () => removeFrameLinkHandlerRef.current();
32283
+ }, [html, installFrameLinkHandler]);
32239
32284
  useEffect44(() => {
32240
32285
  if (!globalKeyboardShortcuts) return;
32241
32286
  const handleKeyDown = (event) => {
@@ -32268,6 +32313,7 @@ function PlainHtmlPreview({
32268
32313
  "data-testid": "plain-html-preview",
32269
32314
  title: title ?? "HTML preview",
32270
32315
  srcDoc: html,
32316
+ onLoad: installFrameLinkHandler,
32271
32317
  sandbox: "allow-same-origin",
32272
32318
  style: { ...IFRAME_STYLE, ...style }
32273
32319
  }
@@ -33292,7 +33338,12 @@ function PrintPreview({
33292
33338
 
33293
33339
  // src/PreviewPanel.tsx
33294
33340
  import { Fragment as Fragment19, jsx as jsx66, jsxs as jsxs50 } from "react/jsx-runtime";
33295
- function PreviewPanel({ basePath = "/", className, workspaceContainer }) {
33341
+ function PreviewPanel({
33342
+ basePath = "/",
33343
+ className,
33344
+ workspaceContainer,
33345
+ onLinkClick
33346
+ }) {
33296
33347
  const {
33297
33348
  doc,
33298
33349
  parseError,
@@ -33483,7 +33534,8 @@ function PreviewPanel({ basePath = "/", className, workspaceContainer }) {
33483
33534
  mediaProvider,
33484
33535
  mediaRevision,
33485
33536
  theme: activeTheme,
33486
- globalKeyboardShortcuts: !audience
33537
+ globalKeyboardShortcuts: !audience,
33538
+ onLinkClick
33487
33539
  }
33488
33540
  );
33489
33541
  }
@@ -35068,7 +35120,14 @@ ${snippet}` : snippet);
35068
35120
  "inline"
35069
35121
  )
35070
35122
  ] }, "wysiwyg-shell"),
35071
- isMarkdownMode && isPreview && /* @__PURE__ */ jsx71(PreviewPanel, { basePath, workspaceContainer })
35123
+ isMarkdownMode && isPreview && /* @__PURE__ */ jsx71(
35124
+ PreviewPanel,
35125
+ {
35126
+ basePath,
35127
+ workspaceContainer,
35128
+ onLinkClick
35129
+ }
35130
+ )
35072
35131
  ]
35073
35132
  }
35074
35133
  ),
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as CodeContext, S as SceneTextChannel } from './shell-YIIUac26.js';
2
- export { B as BlockTagVisibility, a as CodeContextSection, D as DocumentLinkCandidate, b as DocumentLinkProvider, E as EditorActions, c as EditorColorScheme, d as EditorContextValue, e as EditorMode, f as EditorProvider, g as EditorProviderProps, h as EditorShell, i as EditorShellProps, j as EditorState, k as EditorView, I as ImageDisplayMode, L as LayoutMode, M as MentionCandidate, l as MentionProvider, P as PreviewPanel, m as PreviewPanelProps, R as RawEditor, n as RawEditorProps, T as ThemeInheritance, V as ViewPreferences, W as WriteCanvasSettings, o as WysiwygEditor, p as WysiwygEditorProps, u as useEditorContext } from './shell-YIIUac26.js';
1
+ import { C as CodeContext, S as SceneTextChannel } from './shell-C-KkTBz7.js';
2
+ export { B as BlockTagVisibility, a as CodeContextSection, D as DocumentLinkCandidate, b as DocumentLinkProvider, E as EditorActions, c as EditorColorScheme, d as EditorContextValue, e as EditorMode, f as EditorProvider, g as EditorProviderProps, h as EditorShell, i as EditorShellProps, j as EditorState, k as EditorView, I as ImageDisplayMode, L as LayoutMode, M as MentionCandidate, l as MentionProvider, P as PreviewPanel, m as PreviewPanelProps, R as RawEditor, n as RawEditorProps, T as ThemeInheritance, V as ViewPreferences, W as WriteCanvasSettings, o as WysiwygEditor, p as WysiwygEditorProps, u as useEditorContext } from './shell-C-KkTBz7.js';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import * as react from 'react';
5
5
  import { ReactNode, CSSProperties } from 'react';
@@ -324,8 +324,13 @@ interface PlainHtmlPreviewProps {
324
324
  globalKeyboardShortcuts?: boolean;
325
325
  /** Receives the rendered iframe, primarily for printing its isolated document. */
326
326
  onFrameChange?: (frame: HTMLIFrameElement | null) => void;
327
+ /**
328
+ * Delegate link activation from the isolated iframe to the embedding host.
329
+ * Return `false` to allow the iframe's default navigation.
330
+ */
331
+ onLinkClick?: (href: string) => boolean | undefined;
327
332
  }
328
- declare function PlainHtmlPreview({ markdown, title, images, mediaProvider, mediaRevision, theme, className, style, globalKeyboardShortcuts, onFrameChange, }: PlainHtmlPreviewProps): react_jsx_runtime.JSX.Element;
333
+ declare function PlainHtmlPreview({ markdown, title, images, mediaProvider, mediaRevision, theme, className, style, globalKeyboardShortcuts, onFrameChange, onLinkClick, }: PlainHtmlPreviewProps): react_jsx_runtime.JSX.Element;
329
334
 
330
335
  /**
331
336
  * Emoji Dataset
package/dist/index.js CHANGED
@@ -182,7 +182,7 @@ import {
182
182
  usePreviewSettings,
183
183
  useTimelineData,
184
184
  useTreeViewData
185
- } from "./chunk-QN3Q64LV.js";
185
+ } from "./chunk-GNIVYDZH.js";
186
186
  import {
187
187
  JsonEditor
188
188
  } from "./chunk-54UGTQBO.js";
@@ -1,4 +1,4 @@
1
- export { B as BlockTagVisibility, D as DocumentLinkCandidate, b as DocumentLinkProvider, E as EditorActions, c as EditorColorScheme, d as EditorContextValue, e as EditorMode, f as EditorProvider, g as EditorProviderProps, h as EditorShell, i as EditorShellProps, j as EditorState, k as EditorView, I as ImageDisplayMode, L as LayoutMode, M as MentionCandidate, l as MentionProvider, P as PreviewPanel, m as PreviewPanelProps, R as RawEditor, n as RawEditorProps, T as ThemeInheritance, V as ViewPreferences, o as WysiwygEditor, p as WysiwygEditorProps, u as useEditorContext } from '../shell-YIIUac26.js';
1
+ export { B as BlockTagVisibility, D as DocumentLinkCandidate, b as DocumentLinkProvider, E as EditorActions, c as EditorColorScheme, d as EditorContextValue, e as EditorMode, f as EditorProvider, g as EditorProviderProps, h as EditorShell, i as EditorShellProps, j as EditorState, k as EditorView, I as ImageDisplayMode, L as LayoutMode, M as MentionCandidate, l as MentionProvider, P as PreviewPanel, m as PreviewPanelProps, R as RawEditor, n as RawEditorProps, T as ThemeInheritance, V as ViewPreferences, o as WysiwygEditor, p as WysiwygEditorProps, u as useEditorContext } from '../shell-C-KkTBz7.js';
2
2
  import 'react/jsx-runtime';
3
3
  import 'react';
4
4
  import '@bendyline/squisq/schemas';
@@ -5,7 +5,7 @@ import {
5
5
  RawEditor,
6
6
  WysiwygEditor,
7
7
  useEditorContext
8
- } from "../chunk-QN3Q64LV.js";
8
+ } from "../chunk-GNIVYDZH.js";
9
9
  import "../chunk-NITZVAXL.js";
10
10
  import "../chunk-V44VP242.js";
11
11
  import "../chunk-MJJK7YQB.js";
@@ -1071,12 +1071,14 @@ interface PreviewPanelProps {
1071
1071
  * `timing.json` reading.
1072
1072
  */
1073
1073
  workspaceContainer?: ContentContainer | null;
1074
+ /** Delegate authored link activation to the embedding host. */
1075
+ onLinkClick?: (href: string) => boolean | undefined;
1074
1076
  }
1075
1077
  /**
1076
1078
  * Live preview panel that renders the current document as a slideshow
1077
1079
  * or document view. Controls (viewport, mode, theme, transform, captions)
1078
1080
  * are rendered in the main toolbar via PreviewToolbarControls.
1079
1081
  */
1080
- declare function PreviewPanel({ basePath, className, workspaceContainer }: PreviewPanelProps): react_jsx_runtime.JSX.Element;
1082
+ declare function PreviewPanel({ basePath, className, workspaceContainer, onLinkClick, }: PreviewPanelProps): react_jsx_runtime.JSX.Element;
1081
1083
 
1082
1084
  export { type BlockTagVisibility as B, type CodeContext as C, type DocumentLinkCandidate as D, type EditorActions as E, type ImageDisplayMode as I, type LayoutMode as L, type MentionCandidate as M, PreviewPanel as P, RawEditor as R, type SceneTextChannel as S, type ThemeInheritance as T, type ViewPreferences as V, type WriteCanvasSettings as W, type CodeContextSection as a, type DocumentLinkProvider as b, type EditorColorScheme as c, type EditorContextValue as d, type EditorMode as e, EditorProvider as f, type EditorProviderProps as g, EditorShell as h, type EditorShellProps as i, type EditorState as j, type EditorView as k, type MentionProvider as l, type PreviewPanelProps as m, type RawEditorProps as n, WysiwygEditor as o, type WysiwygEditorProps as p, useEditorContext as u };
@@ -14938,10 +14938,20 @@
14938
14938
  padding: 5px 9px;
14939
14939
  border: 1px solid var(--squisq-border, #cbd5e1);
14940
14940
  border-radius: 6px;
14941
- background: var(--squisq-surface-subtle, #f8fafc);
14942
- color: inherit;
14941
+ background: var( --squisq-surface-subtle, var(--squisq-surface-raised, var(--squisq-input-bg, #f8fafc)) );
14942
+ color: var(--squisq-text, #1e293b);
14943
14943
  cursor: pointer;
14944
14944
  }
14945
+ .squisq-mermaid-properties-header button:hover,
14946
+ .squisq-mermaid-properties-footer button:hover {
14947
+ border-color: var(--squisq-accent, #4f46e5);
14948
+ background: var( --squisq-surface-hover, var(--squisq-surface-subtle, var(--squisq-input-bg, #f1f5f9)) );
14949
+ }
14950
+ .squisq-mermaid-properties-header button:focus-visible,
14951
+ .squisq-mermaid-properties-footer button:focus-visible {
14952
+ outline: 2px solid var(--squisq-accent, #4f46e5);
14953
+ outline-offset: 2px;
14954
+ }
14945
14955
  .squisq-mermaid-properties-header button {
14946
14956
  width: 30px;
14947
14957
  padding: 0;
@@ -14950,9 +14960,13 @@
14950
14960
  justify-content: flex-end;
14951
14961
  }
14952
14962
  .squisq-mermaid-properties-footer button[data-primary=true] {
14953
- border-color: #4f46e5;
14954
- background: #4f46e5;
14955
- color: #fff;
14963
+ border-color: var(--squisq-accent, #4f46e5);
14964
+ background: var(--squisq-accent, #4f46e5);
14965
+ color: var(--squisq-text-on-accent, #fff);
14966
+ }
14967
+ .squisq-mermaid-properties-footer button[data-primary=true]:hover {
14968
+ border-color: var(--squisq-accent-hover, var(--squisq-accent, #4338ca));
14969
+ background: var(--squisq-accent-hover, var(--squisq-accent, #4338ca));
14956
14970
  }
14957
14971
  .squisq-mermaid-properties-fields {
14958
14972
  display: flex;
@@ -14987,6 +15001,9 @@
14987
15001
  min-height: 30px;
14988
15002
  color: var(--squisq-text, #1e293b);
14989
15003
  }
15004
+ .squisq-mermaid-property-toggle input {
15005
+ accent-color: var(--squisq-accent, #4f46e5);
15006
+ }
14990
15007
  .squisq-mermaid-shape-search {
14991
15008
  box-sizing: border-box;
14992
15009
  width: 100%;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bendyline/squisq-editor-react",
3
- "version": "2.3.3",
3
+ "version": "2.3.4",
4
4
  "description": "React editor shell with raw/WYSIWYG/preview modes for Squisq documents",
5
5
  "license": "MIT",
6
6
  "author": "Bendyline",
@@ -84,9 +84,9 @@
84
84
  "react-dom": "^18.0.0 || ^19.0.0"
85
85
  },
86
86
  "dependencies": {
87
- "@bendyline/squisq": "2.3.2",
88
- "@bendyline/squisq-formats": "2.3.2",
89
- "@bendyline/squisq-react": "2.3.2",
87
+ "@bendyline/squisq": "2.3.3",
88
+ "@bendyline/squisq-formats": "2.3.3",
89
+ "@bendyline/squisq-react": "2.3.3",
90
90
  "@fortawesome/fontawesome-free": "7.2.0",
91
91
  "@tiptap/extension-image": "2.27.2",
92
92
  "@tiptap/extension-link": "2.27.2",