@bendyline/squisq-editor-react 2.3.2 → 2.3.3

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 CHANGED
@@ -78,6 +78,8 @@ and block-at-a-time / timeline editing primitives (`useBlockNavigator`,
78
78
  SVG preview gutter, `inlinePreviewWidth` default 320).
79
79
  - **Code & image modes** — pass `fileName` / `language` to get a Monaco-only
80
80
  code editor, or `imageSrc` (+ `imageMode: 'edit'`) for the image surface.
81
+ `.jsonc` files, `language="jsonc"`, and fenced `jsonc` snippets use JSON
82
+ highlighting with line and block comment support.
81
83
  - **Host-triggered Find mode** — control `findMode` and
82
84
  `onFindModeChange` (or call `setFindMode` from context) to replace the
83
85
  toolbar's editing actions with live search, previous/next navigation, and
@@ -0,0 +1,32 @@
1
+ // src/monacoWorkers.ts
2
+ function configureMonacoWorkers(workers) {
3
+ const host = globalThis;
4
+ host.MonacoEnvironment = {
5
+ getWorker(_workerId, label) {
6
+ switch (label) {
7
+ case "json":
8
+ if (workers.json) return new workers.json();
9
+ break;
10
+ case "css":
11
+ case "scss":
12
+ case "less":
13
+ if (workers.css) return new workers.css();
14
+ break;
15
+ case "html":
16
+ case "handlebars":
17
+ case "razor":
18
+ if (workers.html) return new workers.html();
19
+ break;
20
+ case "typescript":
21
+ case "javascript":
22
+ if (workers.ts) return new workers.ts();
23
+ break;
24
+ }
25
+ return new workers.editor();
26
+ }
27
+ };
28
+ }
29
+
30
+ export {
31
+ configureMonacoWorkers
32
+ };
@@ -75,6 +75,9 @@ var EXT_TO_LANGUAGE = {
75
75
  };
76
76
  var MARKDOWN_MODE_LANGUAGES = /* @__PURE__ */ new Set(["markdown", "plaintext"]);
77
77
  var IMAGE_MODE_LANGUAGES = /* @__PURE__ */ new Set(["image"]);
78
+ var MONACO_LANGUAGE_ALIASES = {
79
+ jsonc: "json"
80
+ };
78
81
  function extractExtension(fileName) {
79
82
  const trimmed = fileName.trim();
80
83
  if (!trimmed) return null;
@@ -93,7 +96,8 @@ function detectLanguageFromFileName(fileName) {
93
96
  return EXT_TO_LANGUAGE[ext] ?? null;
94
97
  }
95
98
  function resolveFileKind(fileName, language) {
96
- const resolvedLanguage = language ?? (fileName ? detectLanguageFromFileName(fileName) : null);
99
+ const requestedLanguage = language ?? (fileName ? detectLanguageFromFileName(fileName) : null);
100
+ const resolvedLanguage = requestedLanguage ? MONACO_LANGUAGE_ALIASES[requestedLanguage.toLowerCase()] ?? requestedLanguage : null;
97
101
  if (!resolvedLanguage) {
98
102
  return { mode: "markdown", language: "markdown" };
99
103
  }
@@ -2679,7 +2683,7 @@ var TEMPLATE_ENTRIES = [
2679
2683
  {
2680
2684
  name: "sectionHeader",
2681
2685
  label: "Section Header",
2682
- description: "A clean section break with a prominent title and optional subtitle.",
2686
+ description: "A clean section break with a prominent title and optional background image.",
2683
2687
  icon: /* @__PURE__ */ jsxs5(TemplateIcon, { children: [
2684
2688
  /* @__PURE__ */ jsx8("rect", { x: 4, y: 4, width: 3, height: 32, rx: 1, fill: FA }),
2685
2689
  /* @__PURE__ */ jsx8("rect", { x: 11, y: 8, width: 36, height: 6, rx: 1, fill: F2 }),
@@ -2687,6 +2691,18 @@ var TEMPLATE_ENTRIES = [
2687
2691
  /* @__PURE__ */ jsx8("rect", { x: 11, y: 24, width: 20, height: 2.5, rx: 1, fill: F1, opacity: 0.7 })
2688
2692
  ] })
2689
2693
  },
2694
+ {
2695
+ name: "content",
2696
+ label: "Content",
2697
+ description: "Shows a heading and the complete body in a loss-averse content-first layout.",
2698
+ icon: /* @__PURE__ */ jsxs5(TemplateIcon, { children: [
2699
+ /* @__PURE__ */ jsx8("rect", { x: 7, y: 7, width: 34, height: 5, rx: 1, fill: FA }),
2700
+ /* @__PURE__ */ jsx8("rect", { x: 7, y: 17, width: 42, height: 2.5, rx: 1, fill: F2 }),
2701
+ /* @__PURE__ */ jsx8("rect", { x: 7, y: 22, width: 38, height: 2.5, rx: 1, fill: F1 }),
2702
+ /* @__PURE__ */ jsx8("rect", { x: 7, y: 27, width: 41, height: 2.5, rx: 1, fill: F1 }),
2703
+ /* @__PURE__ */ jsx8("rect", { x: 7, y: 32, width: 30, height: 2.5, rx: 1, fill: F1, opacity: 0.7 })
2704
+ ] })
2705
+ },
2690
2706
  {
2691
2707
  name: "statHighlight",
2692
2708
  label: "Stat Highlight",
@@ -8423,6 +8439,14 @@ var CODE_SNIPPET_LANGUAGES = [
8423
8439
  monacoLanguage: "json",
8424
8440
  starter: '{\n "key": "value"\n}'
8425
8441
  },
8442
+ {
8443
+ fenceLanguage: "jsonc",
8444
+ label: "JSONC",
8445
+ // Monaco exposes JSON-with-comments through its `json` language service;
8446
+ // it does not register a separate rich-service `jsonc` language id.
8447
+ monacoLanguage: "json",
8448
+ starter: '{\n // Comments are allowed.\n "key": "value"\n}'
8449
+ },
8426
8450
  {
8427
8451
  fenceLanguage: "html",
8428
8452
  label: "HTML",
@@ -8540,7 +8564,7 @@ var SPECIAL_FENCE_LANGUAGES = /* @__PURE__ */ new Set([
8540
8564
  "timeline",
8541
8565
  "mermaid"
8542
8566
  ]);
8543
- var MONACO_LANGUAGE_ALIASES = {
8567
+ var MONACO_LANGUAGE_ALIASES2 = {
8544
8568
  c: "c",
8545
8569
  "c++": "cpp",
8546
8570
  "c#": "csharp",
@@ -8550,6 +8574,7 @@ var MONACO_LANGUAGE_ALIASES = {
8550
8574
  htm: "html",
8551
8575
  js: "javascript",
8552
8576
  jsx: "javascript",
8577
+ jsonc: "json",
8553
8578
  md: "markdown",
8554
8579
  py: "python",
8555
8580
  rb: "ruby",
@@ -8570,7 +8595,7 @@ function isCodeSnippetFenceLanguage(language) {
8570
8595
  function monacoLanguageForFence(language) {
8571
8596
  const token = codeSnippetFenceLanguageToken(language);
8572
8597
  const catalogEntry = BY_FENCE_LANGUAGE.get(token);
8573
- return (catalogEntry?.monacoLanguage ?? MONACO_LANGUAGE_ALIASES[token] ?? token) || "plaintext";
8598
+ return (catalogEntry?.monacoLanguage ?? MONACO_LANGUAGE_ALIASES2[token] ?? token) || "plaintext";
8574
8599
  }
8575
8600
  function codeSnippetLanguageLabel(language) {
8576
8601
  const token = codeSnippetFenceLanguageToken(language);
@@ -32490,7 +32515,12 @@ function preparePopupDocument(popup, source, title) {
32490
32515
  function presentationTitle(docTitle) {
32491
32516
  return typeof docTitle === "string" && docTitle.trim() ? `${docTitle.trim()} - Presentation` : "Squisq Presentation";
32492
32517
  }
32493
- function PresentationModeProvider({ rootRef, children }) {
32518
+ function PresentationModeProvider({
32519
+ rootRef,
32520
+ children,
32521
+ allowWindow = true,
32522
+ allowFullscreen = true
32523
+ }) {
32494
32524
  const { activeView, colorScheme, doc } = useEditorContext();
32495
32525
  const popupNameId = useId14().replace(/[^a-zA-Z0-9_-]/g, "");
32496
32526
  const [selectedTarget, setSelectedTarget] = useState55("control");
@@ -32504,6 +32534,14 @@ function PresentationModeProvider({ rootRef, children }) {
32504
32534
  const popupRef = useRef46(null);
32505
32535
  const popupCleanupRef = useRef46(null);
32506
32536
  const fullscreenSupported = typeof document !== "undefined" && typeof document.documentElement.requestFullscreen === "function";
32537
+ const availableTargets = useMemo41(
32538
+ () => [
32539
+ "control",
32540
+ ...allowWindow ? ["window"] : [],
32541
+ ...allowFullscreen ? ["fullscreen"] : []
32542
+ ],
32543
+ [allowFullscreen, allowWindow]
32544
+ );
32507
32545
  const releasePopup = useCallback45((closeWindow) => {
32508
32546
  const popup = popupRef.current;
32509
32547
  popupCleanupRef.current?.();
@@ -32555,6 +32593,7 @@ function PresentationModeProvider({ rootRef, children }) {
32555
32593
  return;
32556
32594
  }
32557
32595
  if (selectedTarget === "fullscreen") {
32596
+ if (!allowFullscreen) return;
32558
32597
  if (typeof root.requestFullscreen !== "function") {
32559
32598
  setError("Browser full screen is not available here.");
32560
32599
  return;
@@ -32567,6 +32606,7 @@ function PresentationModeProvider({ rootRef, children }) {
32567
32606
  }
32568
32607
  return;
32569
32608
  }
32609
+ if (!allowWindow) return;
32570
32610
  let popup = null;
32571
32611
  try {
32572
32612
  const screenWidth = window.screen?.availWidth || POPUP_WIDTH;
@@ -32607,15 +32647,29 @@ function PresentationModeProvider({ rootRef, children }) {
32607
32647
  else if (popup && !popup.closed) popup.close();
32608
32648
  setError("The presentation window was blocked. Allow pop-ups and try again.");
32609
32649
  }
32610
- }, [doc?.frontmatter?.title, popupNameId, releasePopup, rootRef, selectedTarget]);
32650
+ }, [
32651
+ allowFullscreen,
32652
+ allowWindow,
32653
+ doc?.frontmatter?.title,
32654
+ popupNameId,
32655
+ releasePopup,
32656
+ rootRef,
32657
+ selectedTarget
32658
+ ]);
32611
32659
  const selectTarget = useCallback45(
32612
32660
  (target) => {
32661
+ if (!availableTargets.includes(target)) return;
32613
32662
  if (target === selectedTarget) return;
32614
32663
  setSelectedTarget(target);
32615
32664
  if (activeTargetRef.current !== null) void stop();
32616
32665
  },
32617
- [selectedTarget, stop]
32666
+ [availableTargets, selectedTarget, stop]
32618
32667
  );
32668
+ useEffect45(() => {
32669
+ if (availableTargets.includes(selectedTarget)) return;
32670
+ setSelectedTarget("control");
32671
+ if (activeTargetRef.current !== null) void stop();
32672
+ }, [availableTargets, selectedTarget, stop]);
32619
32673
  useEffect45(() => {
32620
32674
  const root = rootRef.current;
32621
32675
  const ownerDocument = root?.ownerDocument;
@@ -32683,12 +32737,22 @@ function PresentationModeProvider({ rootRef, children }) {
32683
32737
  selectedTarget,
32684
32738
  activeTarget,
32685
32739
  popupRoot,
32740
+ availableTargets,
32686
32741
  fullscreenSupported,
32687
32742
  selectTarget,
32688
32743
  start,
32689
32744
  stop
32690
32745
  }),
32691
- [selectedTarget, activeTarget, popupRoot, fullscreenSupported, selectTarget, start, stop]
32746
+ [
32747
+ selectedTarget,
32748
+ activeTarget,
32749
+ popupRoot,
32750
+ availableTargets,
32751
+ fullscreenSupported,
32752
+ selectTarget,
32753
+ start,
32754
+ stop
32755
+ ]
32692
32756
  );
32693
32757
  const exitButton = activeTarget ? /* @__PURE__ */ jsxs47(
32694
32758
  "button",
@@ -32739,13 +32803,22 @@ var MENU_WIDTH = 340;
32739
32803
  var MENU_MARGIN = 8;
32740
32804
  var MENU_GAP = 4;
32741
32805
  function PresentationModeControl() {
32742
- const { selectedTarget, activeTarget, fullscreenSupported, selectTarget, start, stop } = usePresentationMode();
32806
+ const {
32807
+ selectedTarget,
32808
+ activeTarget,
32809
+ availableTargets,
32810
+ fullscreenSupported,
32811
+ selectTarget,
32812
+ start,
32813
+ stop
32814
+ } = usePresentationMode();
32743
32815
  const { colorScheme } = useEditorContext();
32744
32816
  const triggerRef = useRef46(null);
32745
32817
  const menuRef = useRef46(null);
32746
32818
  const [open, setOpen] = useState55(false);
32747
32819
  const [anchor, setAnchor] = useState55(null);
32748
- const selected = PRESENTATION_OPTIONS.find((option) => option.target === selectedTarget) ?? PRESENTATION_OPTIONS[0];
32820
+ const options = PRESENTATION_OPTIONS.filter((option) => availableTargets.includes(option.target));
32821
+ const selected = options.find((option) => option.target === selectedTarget) ?? PRESENTATION_OPTIONS[0];
32749
32822
  const updatePosition = useCallback45(() => {
32750
32823
  const trigger = triggerRef.current;
32751
32824
  if (!trigger) return;
@@ -32810,7 +32883,7 @@ function PresentationModeControl() {
32810
32883
  children: /* @__PURE__ */ jsx63(Icon, { icon: "fa-solid fa-display" })
32811
32884
  }
32812
32885
  ),
32813
- /* @__PURE__ */ jsx63(
32886
+ options.length > 1 && /* @__PURE__ */ jsx63(
32814
32887
  "button",
32815
32888
  {
32816
32889
  ref: triggerRef,
@@ -32857,7 +32930,7 @@ function PresentationModeControl() {
32857
32930
  const nextIndex = event.key === "Home" ? 0 : event.key === "End" ? items.length - 1 : event.key === "ArrowUp" ? (currentIndex - 1 + items.length) % items.length : (currentIndex + 1) % items.length;
32858
32931
  items[nextIndex]?.focus();
32859
32932
  },
32860
- children: PRESENTATION_OPTIONS.map((option) => {
32933
+ children: options.map((option) => {
32861
32934
  const isSelected = option.target === selectedTarget;
32862
32935
  const disabled = option.target === "fullscreen" && !fullscreenSupported;
32863
32936
  return /* @__PURE__ */ jsxs47(
@@ -34431,6 +34504,9 @@ function EditorShell({
34431
34504
  toolbarSlotRight,
34432
34505
  statusBarSlotRight,
34433
34506
  showPlayTab = true,
34507
+ allowPresentationWindow = true,
34508
+ allowPresentationFullscreen = true,
34509
+ allowPrint = true,
34434
34510
  submitOnEnter,
34435
34511
  codeContext,
34436
34512
  fullWidth = false,
@@ -34525,6 +34601,9 @@ function EditorShell({
34525
34601
  toolbarSlotRight,
34526
34602
  statusBarSlotRight,
34527
34603
  showPlayTab,
34604
+ allowPresentationWindow,
34605
+ allowPresentationFullscreen,
34606
+ allowPrint,
34528
34607
  submitOnEnter,
34529
34608
  codeContext,
34530
34609
  fullWidth,
@@ -34547,20 +34626,30 @@ function EditorShell({
34547
34626
  }
34548
34627
  ) });
34549
34628
  }
34550
- function UseModeToolbarControls() {
34629
+ function UseModeToolbarControls({ allowPrint }) {
34551
34630
  const printMode = usePrintMode();
34552
34631
  if (printMode.active) return /* @__PURE__ */ jsx71(PrintPreviewToolbar, {});
34553
34632
  return /* @__PURE__ */ jsxs53(Fragment21, { children: [
34554
34633
  /* @__PURE__ */ jsx71(PreviewToolbarControls, {}),
34555
34634
  /* @__PURE__ */ jsx71(PresentationModeControl, {}),
34556
- /* @__PURE__ */ jsx71(PrintModeControl, {})
34635
+ allowPrint && /* @__PURE__ */ jsx71(PrintModeControl, {})
34557
34636
  ] });
34558
34637
  }
34559
34638
  function UseModeProviders({
34560
34639
  rootRef,
34561
- children
34640
+ children,
34641
+ allowPresentationWindow,
34642
+ allowPresentationFullscreen
34562
34643
  }) {
34563
- return /* @__PURE__ */ jsx71(PresentationModeProvider, { rootRef, children: /* @__PURE__ */ jsx71(PrintModeProvider, { rootRef, children }) });
34644
+ return /* @__PURE__ */ jsx71(
34645
+ PresentationModeProvider,
34646
+ {
34647
+ rootRef,
34648
+ allowWindow: allowPresentationWindow,
34649
+ allowFullscreen: allowPresentationFullscreen,
34650
+ children: /* @__PURE__ */ jsx71(PrintModeProvider, { rootRef, children })
34651
+ }
34652
+ );
34564
34653
  }
34565
34654
  function EditorShellInner({
34566
34655
  basePath,
@@ -34579,6 +34668,9 @@ function EditorShellInner({
34579
34668
  toolbarSlotRight,
34580
34669
  statusBarSlotRight,
34581
34670
  showPlayTab,
34671
+ allowPresentationWindow,
34672
+ allowPresentationFullscreen,
34673
+ allowPrint,
34582
34674
  submitOnEnter,
34583
34675
  codeContext,
34584
34676
  fullWidth,
@@ -34837,109 +34929,126 @@ ${snippet}` : snippet);
34837
34929
  },
34838
34930
  ...containerProps,
34839
34931
  children: [
34840
- /* @__PURE__ */ jsx71(CustomThemeProvider, { docThemes, onDocThemesChange, children: /* @__PURE__ */ jsx71(PreviewSettingsProvider, { doc, themeOverride, children: /* @__PURE__ */ jsxs53(UseModeProviders, { rootRef: shellRef, children: [
34841
- isImageMode ? (toolbarSlotLeft || toolbarSlotRight) && /* @__PURE__ */ jsxs53("div", { className: "squisq-editor-header squisq-editor-header--image", children: [
34842
- toolbarSlotLeft,
34843
- /* @__PURE__ */ jsx71("div", { style: { flex: 1 } }),
34844
- toolbarSlotRight
34845
- ] }) : /* @__PURE__ */ jsx71("div", { className: "squisq-editor-header", children: /* @__PURE__ */ jsx71(
34846
- Toolbar,
34847
- {
34848
- showFiles,
34849
- fileCount: mediaCount,
34850
- onToggleFiles: !isCodeMode && filesToggleEnabled ? handleToggleFiles : void 0,
34851
- slotLeft: toolbarSlotLeft,
34852
- slotAfterTabs: !isCodeMode && isPreview && /* @__PURE__ */ jsx71(UseModeToolbarControls, {}),
34853
- slotAfterActions: toolbarSlotAfterActions,
34854
- slotRight: toolbarSlotRight,
34855
- showPlayTab
34856
- }
34857
- ) }),
34858
- /* @__PURE__ */ jsxs53(
34859
- "div",
34860
- {
34861
- className: "squisq-editor-content",
34862
- style: {
34863
- flex: autoGrow ? "1 1 auto" : 1,
34864
- overflowY: autoGrow ? "auto" : "hidden",
34865
- overflowX: "hidden",
34866
- minHeight: 0,
34867
- position: "relative",
34868
- display: "flex"
34869
- },
34870
- children: [
34871
- /* @__PURE__ */ jsxs53(
34872
- "div",
34873
- {
34874
- style: {
34875
- flex: autoGrow ? "1 1 auto" : 1,
34876
- overflow: autoGrow ? "visible" : "hidden",
34877
- minHeight: 0,
34878
- position: "relative"
34879
- },
34880
- children: [
34881
- isImageMode && imageSrc && (imageMode === "edit" && imageEditorContainer ? /* @__PURE__ */ jsx71(
34882
- ImageEditor,
34883
- {
34884
- filesContainer: imageEditorContainer,
34885
- initialSrc: imageSrc,
34886
- allowVersioning,
34887
- versioningAutoSaveIdleMs,
34888
- onExport: onImageExport,
34889
- surface: colorScheme === "dark" ? DARK_SURFACE : LIGHT_SURFACE
34890
- }
34891
- ) : /* @__PURE__ */ jsx71(ImageViewer, { src: imageSrc, alt: imageAlt, theme: colorScheme })),
34892
- !isImageMode && activeView === "raw" && /* @__PURE__ */ jsxs53("div", { className: "squisq-editor-with-gutter", children: [
34893
- isMarkdownMode && outlineVisible && /* @__PURE__ */ jsx71(OutlinePanel, { width: outlineWidth, readOnly }, "outline"),
34894
- isCardMode ? /* @__PURE__ */ jsx71(
34895
- BlockCardView,
34896
- {
34897
- blockCount,
34898
- activeBlockKey,
34899
- onPrev: prevBlock,
34900
- onNext: nextBlock,
34901
- onAdd: addBlock,
34902
- children: /* @__PURE__ */ jsx71("div", { className: "squisq-raw-editor-container", children: /* @__PURE__ */ jsx71(
34932
+ /* @__PURE__ */ jsx71(CustomThemeProvider, { docThemes, onDocThemesChange, children: /* @__PURE__ */ jsx71(PreviewSettingsProvider, { doc, themeOverride, children: /* @__PURE__ */ jsxs53(
34933
+ UseModeProviders,
34934
+ {
34935
+ rootRef: shellRef,
34936
+ allowPresentationWindow,
34937
+ allowPresentationFullscreen,
34938
+ children: [
34939
+ isImageMode ? (toolbarSlotLeft || toolbarSlotRight) && /* @__PURE__ */ jsxs53("div", { className: "squisq-editor-header squisq-editor-header--image", children: [
34940
+ toolbarSlotLeft,
34941
+ /* @__PURE__ */ jsx71("div", { style: { flex: 1 } }),
34942
+ toolbarSlotRight
34943
+ ] }) : /* @__PURE__ */ jsx71("div", { className: "squisq-editor-header", children: /* @__PURE__ */ jsx71(
34944
+ Toolbar,
34945
+ {
34946
+ showFiles,
34947
+ fileCount: mediaCount,
34948
+ onToggleFiles: !isCodeMode && filesToggleEnabled ? handleToggleFiles : void 0,
34949
+ slotLeft: toolbarSlotLeft,
34950
+ slotAfterTabs: !isCodeMode && isPreview && /* @__PURE__ */ jsx71(UseModeToolbarControls, { allowPrint }),
34951
+ slotAfterActions: toolbarSlotAfterActions,
34952
+ slotRight: toolbarSlotRight,
34953
+ showPlayTab
34954
+ }
34955
+ ) }),
34956
+ /* @__PURE__ */ jsxs53(
34957
+ "div",
34958
+ {
34959
+ className: "squisq-editor-content",
34960
+ style: {
34961
+ flex: autoGrow ? "1 1 auto" : 1,
34962
+ overflowY: autoGrow ? "auto" : "hidden",
34963
+ overflowX: "hidden",
34964
+ minHeight: 0,
34965
+ position: "relative",
34966
+ display: "flex"
34967
+ },
34968
+ children: [
34969
+ /* @__PURE__ */ jsxs53(
34970
+ "div",
34971
+ {
34972
+ style: {
34973
+ flex: autoGrow ? "1 1 auto" : 1,
34974
+ overflow: autoGrow ? "visible" : "hidden",
34975
+ minHeight: 0,
34976
+ position: "relative"
34977
+ },
34978
+ children: [
34979
+ isImageMode && imageSrc && (imageMode === "edit" && imageEditorContainer ? /* @__PURE__ */ jsx71(
34980
+ ImageEditor,
34981
+ {
34982
+ filesContainer: imageEditorContainer,
34983
+ initialSrc: imageSrc,
34984
+ allowVersioning,
34985
+ versioningAutoSaveIdleMs,
34986
+ onExport: onImageExport,
34987
+ surface: colorScheme === "dark" ? DARK_SURFACE : LIGHT_SURFACE
34988
+ }
34989
+ ) : /* @__PURE__ */ jsx71(ImageViewer, { src: imageSrc, alt: imageAlt, theme: colorScheme })),
34990
+ !isImageMode && activeView === "raw" && /* @__PURE__ */ jsxs53("div", { className: "squisq-editor-with-gutter", children: [
34991
+ isMarkdownMode && outlineVisible && /* @__PURE__ */ jsx71(OutlinePanel, { width: outlineWidth, readOnly }, "outline"),
34992
+ isCardMode ? /* @__PURE__ */ jsx71(
34993
+ BlockCardView,
34994
+ {
34995
+ blockCount,
34996
+ activeBlockKey,
34997
+ onPrev: prevBlock,
34998
+ onNext: nextBlock,
34999
+ onAdd: addBlock,
35000
+ children: /* @__PURE__ */ jsx71("div", { className: "squisq-raw-editor-container", children: /* @__PURE__ */ jsx71(
35001
+ RawEditor,
35002
+ {
35003
+ monacoTheme: colorScheme === "dark" ? "vs-dark" : "vs",
35004
+ submitOnEnter,
35005
+ readOnly
35006
+ }
35007
+ ) }, "raw-editor")
35008
+ },
35009
+ "raw-card"
35010
+ ) : /* @__PURE__ */ jsx71("div", { className: "squisq-raw-editor-container", children: /* @__PURE__ */ jsx71(
34903
35011
  RawEditor,
34904
35012
  {
34905
35013
  monacoTheme: colorScheme === "dark" ? "vs-dark" : "vs",
34906
35014
  submitOnEnter,
34907
35015
  readOnly
34908
35016
  }
34909
- ) }, "raw-editor")
34910
- },
34911
- "raw-card"
34912
- ) : /* @__PURE__ */ jsx71("div", { className: "squisq-raw-editor-container", children: /* @__PURE__ */ jsx71(
34913
- RawEditor,
34914
- {
34915
- monacoTheme: colorScheme === "dark" ? "vs-dark" : "vs",
34916
- submitOnEnter,
34917
- readOnly
34918
- }
34919
- ) }, "raw-editor"),
34920
- isCodeMode && codeContext && /* @__PURE__ */ jsx71(CodeContextZones, { options: codeContext }, "code-context"),
34921
- isMarkdownMode && isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx71(BlockPreviewPanel, { basePath }, "block-preview"),
34922
- isMarkdownMode && !isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx71(
34923
- InlinePreviewGutter,
34924
- {
34925
- width: inlinePreviewWidth,
34926
- basePath,
34927
- mediaProvider
34928
- },
34929
- "inline"
34930
- )
34931
- ] }, "raw-shell"),
34932
- isMarkdownMode && activeView === "wysiwyg" && /* @__PURE__ */ jsxs53("div", { className: "squisq-editor-with-gutter", children: [
34933
- outlineVisible && /* @__PURE__ */ jsx71(OutlinePanel, { width: outlineWidth, readOnly }, "outline"),
34934
- isCardMode ? /* @__PURE__ */ jsx71(
34935
- BlockCardView,
34936
- {
34937
- blockCount,
34938
- activeBlockKey,
34939
- onPrev: prevBlock,
34940
- onNext: nextBlock,
34941
- onAdd: addBlock,
34942
- children: /* @__PURE__ */ jsx71(
35017
+ ) }, "raw-editor"),
35018
+ isCodeMode && codeContext && /* @__PURE__ */ jsx71(CodeContextZones, { options: codeContext }, "code-context"),
35019
+ isMarkdownMode && isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx71(BlockPreviewPanel, { basePath }, "block-preview"),
35020
+ isMarkdownMode && !isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx71(
35021
+ InlinePreviewGutter,
35022
+ {
35023
+ width: inlinePreviewWidth,
35024
+ basePath,
35025
+ mediaProvider
35026
+ },
35027
+ "inline"
35028
+ )
35029
+ ] }, "raw-shell"),
35030
+ isMarkdownMode && activeView === "wysiwyg" && /* @__PURE__ */ jsxs53("div", { className: "squisq-editor-with-gutter", children: [
35031
+ outlineVisible && /* @__PURE__ */ jsx71(OutlinePanel, { width: outlineWidth, readOnly }, "outline"),
35032
+ isCardMode ? /* @__PURE__ */ jsx71(
35033
+ BlockCardView,
35034
+ {
35035
+ blockCount,
35036
+ activeBlockKey,
35037
+ onPrev: prevBlock,
35038
+ onNext: nextBlock,
35039
+ onAdd: addBlock,
35040
+ children: /* @__PURE__ */ jsx71(
35041
+ WysiwygEditor,
35042
+ {
35043
+ submitOnEnter,
35044
+ placeholder,
35045
+ readOnly
35046
+ },
35047
+ "wysiwyg-editor"
35048
+ )
35049
+ },
35050
+ "wysiwyg-card"
35051
+ ) : /* @__PURE__ */ jsx71(
34943
35052
  WysiwygEditor,
34944
35053
  {
34945
35054
  submitOnEnter,
@@ -34947,60 +35056,51 @@ ${snippet}` : snippet);
34947
35056
  readOnly
34948
35057
  },
34949
35058
  "wysiwyg-editor"
35059
+ ),
35060
+ isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx71(BlockPreviewPanel, { basePath }, "block-preview"),
35061
+ !isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx71(
35062
+ InlinePreviewGutter,
35063
+ {
35064
+ width: inlinePreviewWidth,
35065
+ basePath,
35066
+ mediaProvider
35067
+ },
35068
+ "inline"
34950
35069
  )
34951
- },
34952
- "wysiwyg-card"
34953
- ) : /* @__PURE__ */ jsx71(
34954
- WysiwygEditor,
34955
- {
34956
- submitOnEnter,
34957
- placeholder,
34958
- readOnly
34959
- },
34960
- "wysiwyg-editor"
34961
- ),
34962
- isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx71(BlockPreviewPanel, { basePath }, "block-preview"),
34963
- !isCardMode && inlinePreviewVisible && /* @__PURE__ */ jsx71(
34964
- InlinePreviewGutter,
34965
- {
34966
- width: inlinePreviewWidth,
34967
- basePath,
34968
- mediaProvider
34969
- },
34970
- "inline"
34971
- )
34972
- ] }, "wysiwyg-shell"),
34973
- isMarkdownMode && isPreview && /* @__PURE__ */ jsx71(PreviewPanel, { basePath, workspaceContainer })
34974
- ]
34975
- }
34976
- ),
34977
- isMarkdownMode && showFiles && /* @__PURE__ */ jsx71(
34978
- MediaBin,
34979
- {
34980
- mediaProvider,
34981
- isDark,
34982
- refreshKey: mediaListRefreshKey,
34983
- usedMediaPaths,
34984
- onMediaUploaded: handleMediaUploaded,
34985
- onMediaRemoved: handleMediaRemoved,
34986
- onCountChange: setMediaCount
34987
- }
34988
- ),
34989
- isMarkdownMode && /* @__PURE__ */ jsx71(ThemeDesignerDock, {}),
34990
- isMarkdownMode && isDragging && !(activeView === "wysiwyg" && dragContentType === "media") && /* @__PURE__ */ jsx71(
34991
- DropZoneOverlay,
34992
- {
34993
- dragContentType,
34994
- zoneProps,
34995
- hasMediaProvider: mediaProvider !== null
34996
- }
34997
- )
34998
- ]
34999
- }
35000
- ),
35001
- isTimelineMode && /* @__PURE__ */ jsx71(TimelineTrack, {}),
35002
- statusBarVisible && !isImageMode && /* @__PURE__ */ jsx71(StatusBar, { slotRight: statusBarSlotRight })
35003
- ] }) }) }),
35070
+ ] }, "wysiwyg-shell"),
35071
+ isMarkdownMode && isPreview && /* @__PURE__ */ jsx71(PreviewPanel, { basePath, workspaceContainer })
35072
+ ]
35073
+ }
35074
+ ),
35075
+ isMarkdownMode && showFiles && /* @__PURE__ */ jsx71(
35076
+ MediaBin,
35077
+ {
35078
+ mediaProvider,
35079
+ isDark,
35080
+ refreshKey: mediaListRefreshKey,
35081
+ usedMediaPaths,
35082
+ onMediaUploaded: handleMediaUploaded,
35083
+ onMediaRemoved: handleMediaRemoved,
35084
+ onCountChange: setMediaCount
35085
+ }
35086
+ ),
35087
+ isMarkdownMode && /* @__PURE__ */ jsx71(ThemeDesignerDock, {}),
35088
+ isMarkdownMode && isDragging && !(activeView === "wysiwyg" && dragContentType === "media") && /* @__PURE__ */ jsx71(
35089
+ DropZoneOverlay,
35090
+ {
35091
+ dragContentType,
35092
+ zoneProps,
35093
+ hasMediaProvider: mediaProvider !== null
35094
+ }
35095
+ )
35096
+ ]
35097
+ }
35098
+ ),
35099
+ isTimelineMode && /* @__PURE__ */ jsx71(TimelineTrack, {}),
35100
+ statusBarVisible && !isImageMode && /* @__PURE__ */ jsx71(StatusBar, { slotRight: statusBarSlotRight })
35101
+ ]
35102
+ }
35103
+ ) }) }),
35004
35104
  /* @__PURE__ */ jsx71(TooltipLayer, {}),
35005
35105
  imageEditTarget !== null && mediaProvider && /* @__PURE__ */ jsx71(
35006
35106
  ImageEditModal,
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as CodeContext, S as SceneTextChannel } from './shell-DYdK5qFd.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-DYdK5qFd.js';
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';
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';
@@ -8,6 +8,7 @@ import { MediaProvider, Theme, CustomTemplateDefinition, ThemeSeedColors, Viewpo
8
8
  import { IconFamily } from '@bendyline/squisq/icons';
9
9
  import { DisplayMode, CaptionStyle } from '@bendyline/squisq-react';
10
10
  import * as monaco_editor from 'monaco-editor';
11
+ export { MonacoWorkerConstructor, MonacoWorkerConstructors, configureMonacoWorkers } from './monaco-workers/index.js';
11
12
  import { ConnectorRouting, AsciiDiagram, Tree, AsciiTimeline, AsciiTimelineSide, AsciiTimelineMarker } from '@bendyline/squisq/doc';
12
13
  import * as _tiptap_core from '@tiptap/core';
13
14
  import { Extension } from '@tiptap/core';
@@ -1298,63 +1299,6 @@ interface UseMonacoLoaderResult {
1298
1299
  */
1299
1300
  declare function useMonacoLoader(): UseMonacoLoaderResult;
1300
1301
 
1301
- /**
1302
- * Monaco language-service worker wiring.
1303
- *
1304
- * Monaco offloads its heavy language services — css / html / json / typescript
1305
- * IntelliSense — plus a base editor service (word-based completions, link
1306
- * detection, diffing) to web workers. Those worker bundles must be produced by
1307
- * the HOST application's bundler: the mechanisms for it (Vite's `?worker`
1308
- * import suffix, `new Worker(new URL(...))`, webpack loaders) are all
1309
- * bundler-specific and cannot live inside this tsup-built library.
1310
- *
1311
- * So the division of labor is: the host supplies the five worker constructors
1312
- * (one line each with Vite's `?worker`), and this helper owns the
1313
- * `label → worker` mapping — the part that's fiddly and easy to get wrong.
1314
- *
1315
- * Call once, before the first editor mounts (typically in the app entry):
1316
- *
1317
- * ```ts
1318
- * import { configureMonacoWorkers } from '@bendyline/squisq-editor-react';
1319
- * import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
1320
- * import JsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
1321
- * import CssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker';
1322
- * import HtmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker';
1323
- * import TsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker';
1324
- *
1325
- * configureMonacoWorkers({
1326
- * editor: EditorWorker, json: JsonWorker, css: CssWorker,
1327
- * html: HtmlWorker, ts: TsWorker,
1328
- * });
1329
- * ```
1330
- *
1331
- * This is purely additive: without it, highlighting, editing, and custom
1332
- * completion providers (e.g. the `{[template]}` typeahead) still work — they
1333
- * run on the main thread. Only the language-service IntelliSense is dormant
1334
- * until the workers are wired.
1335
- */
1336
- /** Zero-arg worker constructor, as produced by Vite's `?worker` import. */
1337
- type MonacoWorkerConstructor = new () => Worker;
1338
- interface MonacoWorkerConstructors {
1339
- /** Base editor worker (word completions, links, diff). Required. */
1340
- editor: MonacoWorkerConstructor;
1341
- /** JSON language service. */
1342
- json?: MonacoWorkerConstructor;
1343
- /** CSS/SCSS/LESS language service. */
1344
- css?: MonacoWorkerConstructor;
1345
- /** HTML/Handlebars/Razor language service. */
1346
- html?: MonacoWorkerConstructor;
1347
- /** TypeScript service — also handles JavaScript. */
1348
- ts?: MonacoWorkerConstructor;
1349
- }
1350
- /**
1351
- * Install `globalThis.MonacoEnvironment.getWorker` so Monaco routes each
1352
- * language to the matching worker, falling back to the base editor worker for
1353
- * any label without a dedicated service (which is every plain language — its
1354
- * grammar-based highlighting needs no worker).
1355
- */
1356
- declare function configureMonacoWorkers(workers: MonacoWorkerConstructors): void;
1357
-
1358
1302
  interface CustomTemplateContextValue {
1359
1303
  /** Templates inlined into the current doc's frontmatter. */
1360
1304
  docTemplates: CustomTemplateDefinition[];
@@ -2705,4 +2649,4 @@ declare function applyTimelineCommand(editor: Editor, blockId: string, command:
2705
2649
  /** Paste gate for bare, high-confidence Unicode timeline art. */
2706
2650
  declare function shouldPasteAsTimelineFence(text: string): boolean;
2707
2651
 
2708
- export { ALL_PICKER_ENTRIES, type AddTimelineEventOptions, type AddTimelineEventResult, type ApplyAsciiDiagramCommandOptions, type AsciiDiagramBlockEntry, AsciiDiagramExtension, type AsciiDiagramExtensionOptions, type AsciiDiagramPluginState, type AsciiDiagramView, AsciiDiagramWidget, BlockCardView, type BlockCardViewProps, type BlockNavigator, BlockPropertiesPopover, type BlockPropertiesPopoverProps, type BlockRange, type BlockSlice, CODE_SNIPPET_KEY, CODE_SNIPPET_LANGUAGES, CodeContext, CodeContextZones, type CodeSnippetBlockEntry, type CodeSnippetData, CodeSnippetExtension, type CodeSnippetExtensionOptions, type CodeSnippetLanguage, type CodeSnippetPluginState, CodeSnippetWidget, type CodeSnippetWidgetProps, type CustomTemplateContextValue, CustomTemplateProvider, type CustomTemplateProviderProps, type CustomThemeContextValue, CustomThemeProvider, type CustomThemeProviderProps, DEFAULT_MERMAID_DIAGRAM_TYPE, DiagramCanvas, type DiagramCommand, type DiagramData, type DiagramEdge, type DiagramNode, type DirectionModel, type DocCustomTemplates, type DocCustomThemes, DocumentSettingsDialog, type DocumentSettingsDialogProps, type DragContentType, type DropTarget, DropZoneOverlay, type DropZoneOverlayProps, EMPTY_TRANSITION, EmojiPicker, type EmojiPickerProps, type FileCategory, type FileKind, type FolderEntry, FolderView, type FolderViewProps, type HeadingTransitionAttrs, HeadingWithTemplate, ImportThemeSection, type ImportThemeSectionProps, type ImportedThemeResult, InlinePreviewGutter, type InlinePreviewGutterProps, MERMAID_DIAGRAM_KEY, MERMAID_DIAGRAM_TYPES, MERMAID_FLOWCHART_SHAPES, MediaBin, type MediaBinProps, type MediaClipPatch, type MermaidDiagramBlockEntry, MermaidDiagramCanvas, type MermaidDiagramCanvasProps, type MermaidDiagramCategory, type MermaidDiagramData, MermaidDiagramExtension, type MermaidDiagramExtensionOptions, type MermaidDiagramPluginState, type MermaidDiagramPreview, type MermaidDiagramProperty, type MermaidDiagramType, MermaidDiagramTypeThumbnail, MermaidDiagramWidget, type MermaidDiagramWidgetProps, type MermaidEditCapabilities, type MermaidEditableDiagramKind, type MermaidEditableEdge, type MermaidEditableModel, type MermaidEditableNode, type MermaidEditableText, type MermaidEditableTextTarget, type MermaidFlowchartDirection, type MermaidFlowchartModel, type MermaidFlowchartShape, type MermaidFlowchartShapeId, type MermaidNodeCanvasAction, type MermaidRenderResult, type MermaidSelection, MermaidShapePalette, type MermaidShapePaletteProps, type MermaidSourceEditableModel, type MonacoWorkerConstructor, type MonacoWorkerConstructors, OutlinePanel, type OutlinePanelProps, PICKER_CATEGORIES, type PickerCategory, type PickerEntry, PlainHtmlPreview, type PlainHtmlPreviewProps, PreviewFormatSwitch, PreviewModeMenu, PreviewModeSwitch, type PreviewSettings, PreviewSettingsProvider, PreviewToolbarControls, REPAIRABLE_KEY, type RepairableBlockEntry, RepairableDiagramExtension, type RepairableDiagramExtensionOptions, type RepairablePluginState, StatusBar, type StatusBarProps, TIMELINE_VIEW_KEY, TRANSITION_ENTRIES, TRANSITION_GROUPS, TemplatePicker, ThemeCustomizerPanel, type ThemeCustomizerPanelProps, ThemePicker, type ThemePickerProps, type ThemeSaveExtras, type TimelineBlockEntry, type TimelineCommand, type TimelineCommandResult, TimelineEditorWidget, type TimelineEditorWidgetProps, type TimelineEventPatch, TimelineTrack, type TimelineTrackProps, type TimelineViewData, TimelineViewExtension, type TimelineViewExtensionOptions, type TimelineViewPluginState, Toolbar, type ToolbarProps, TooltipLayer, type TransitionCatalogEntry, type TransitionFields, type TransitionGroup, TransitionPicker, type TransitionPickerProps, type TreeBlockEntry, type TreeCommand, TreeOutlineWidget, type TreeViewData, TreeViewExtension, type TreeViewExtensionOptions, type TreeViewPluginState, type UseBlockNavigatorOptions, type UseFileDropOptions, type UseFileDropResult, type UseMonacoLoaderResult, VersionHistoryPanel, ViewMenuPanel, ViewSwitcher, type ViewSwitcherProps, addEdgeOp, addItemOp, addNodeOp, addTimelineEventOp, applyAsciiDiagramCommand, applyRepairCommand, applyTimelineCommand, applyTreeCommand, asciiDiagramToCanvas, buildPreviewDoc, classifyFile, codeSnippetFenceLanguageToken, codeSnippetLanguageLabel, codeSnippetMarkdown, configureMonacoWorkers, detectLanguageFromFileName, draftPatchFromImportedTheme, findAsciiDiagramBlockPos, findCodeSnippetBlockPos, findMermaidDiagramBlockPos, findRepairableBlockPos, findTimelineBlockPos, findTransitionEntry, findTreeBlockPos, formatSeconds, getBlockSlices, getTimelineForNode, indentItemOp, inspectMermaidSource, isAsciiSourceVisible, isCodeSnippetFenceLanguage, isCodeSnippetNode, isMermaidDiagramNode, isMermaidFlowchartShapeId, isMermaidSourceVisible, isRepairableFence, isTimelineSourceSafeForSemanticEdit, lineToOffset, markdownToTiptap, mermaidDiagramMarkdown, mermaidDiagramProperties, mermaidEditCapabilities, mermaidEditableTexts, mermaidErrorMessage, monacoLanguageForFence, moveItemDownOp, moveItemUpOp, moveNodeOp, nextTimelineEventId, normalizeMermaidFlowchartShape, offsetToLine, outdentItemOp, parseTimelineForNode, partitionFiles, processMediaFiles, processTextFile, processTextFiles, readBlockAttrsParams, readBlockAttrsTransition, readBlockAttrsValue, readHeadingLineTransition, removeEdgeOp, removeItemOp, removeNodeOp, removeTimelineEventOp, renameItemOp, renameNodeOp, renderMermaidDiagram, replaceAsciiFenceText, replaceCodeSnippetText, replaceAsciiFenceText as replaceTreeFenceText, resizeNodeOp, resolveFileKind, sanitizeAsciiLabel, sanitizeTimelineText, sanitizeTreeLabel, searchPickerEntries, setBlockAttrsValue, setBlockDurationInSource, setHeadingAttrsTransition, setHeadingLineTransition, setMediaClipInSource, shouldPasteAsAsciiFence, shouldPasteAsTimelineFence, shouldPasteAsTreeFence, sliceIndexAtOffset, spliceBlock, summarizeBlockProps, templateLabel, tiptapToMarkdown, toggleAsciiSource, toggleDirOp, toggleMermaidSource, transitionLabel, translateDiagramOp, updateTimelineEventOp, useAsciiDiagramData, useBlockNavigator, useCodeSnippetData, useCustomTemplates, useCustomThemes, useDocCustomTemplates, useDocCustomThemes, useFileDrop, useMermaidDiagramData, useMonacoLoader, usePreviewSettings, useTimelineData, useTreeViewData };
2652
+ export { ALL_PICKER_ENTRIES, type AddTimelineEventOptions, type AddTimelineEventResult, type ApplyAsciiDiagramCommandOptions, type AsciiDiagramBlockEntry, AsciiDiagramExtension, type AsciiDiagramExtensionOptions, type AsciiDiagramPluginState, type AsciiDiagramView, AsciiDiagramWidget, BlockCardView, type BlockCardViewProps, type BlockNavigator, BlockPropertiesPopover, type BlockPropertiesPopoverProps, type BlockRange, type BlockSlice, CODE_SNIPPET_KEY, CODE_SNIPPET_LANGUAGES, CodeContext, CodeContextZones, type CodeSnippetBlockEntry, type CodeSnippetData, CodeSnippetExtension, type CodeSnippetExtensionOptions, type CodeSnippetLanguage, type CodeSnippetPluginState, CodeSnippetWidget, type CodeSnippetWidgetProps, type CustomTemplateContextValue, CustomTemplateProvider, type CustomTemplateProviderProps, type CustomThemeContextValue, CustomThemeProvider, type CustomThemeProviderProps, DEFAULT_MERMAID_DIAGRAM_TYPE, DiagramCanvas, type DiagramCommand, type DiagramData, type DiagramEdge, type DiagramNode, type DirectionModel, type DocCustomTemplates, type DocCustomThemes, DocumentSettingsDialog, type DocumentSettingsDialogProps, type DragContentType, type DropTarget, DropZoneOverlay, type DropZoneOverlayProps, EMPTY_TRANSITION, EmojiPicker, type EmojiPickerProps, type FileCategory, type FileKind, type FolderEntry, FolderView, type FolderViewProps, type HeadingTransitionAttrs, HeadingWithTemplate, ImportThemeSection, type ImportThemeSectionProps, type ImportedThemeResult, InlinePreviewGutter, type InlinePreviewGutterProps, MERMAID_DIAGRAM_KEY, MERMAID_DIAGRAM_TYPES, MERMAID_FLOWCHART_SHAPES, MediaBin, type MediaBinProps, type MediaClipPatch, type MermaidDiagramBlockEntry, MermaidDiagramCanvas, type MermaidDiagramCanvasProps, type MermaidDiagramCategory, type MermaidDiagramData, MermaidDiagramExtension, type MermaidDiagramExtensionOptions, type MermaidDiagramPluginState, type MermaidDiagramPreview, type MermaidDiagramProperty, type MermaidDiagramType, MermaidDiagramTypeThumbnail, MermaidDiagramWidget, type MermaidDiagramWidgetProps, type MermaidEditCapabilities, type MermaidEditableDiagramKind, type MermaidEditableEdge, type MermaidEditableModel, type MermaidEditableNode, type MermaidEditableText, type MermaidEditableTextTarget, type MermaidFlowchartDirection, type MermaidFlowchartModel, type MermaidFlowchartShape, type MermaidFlowchartShapeId, type MermaidNodeCanvasAction, type MermaidRenderResult, type MermaidSelection, MermaidShapePalette, type MermaidShapePaletteProps, type MermaidSourceEditableModel, OutlinePanel, type OutlinePanelProps, PICKER_CATEGORIES, type PickerCategory, type PickerEntry, PlainHtmlPreview, type PlainHtmlPreviewProps, PreviewFormatSwitch, PreviewModeMenu, PreviewModeSwitch, type PreviewSettings, PreviewSettingsProvider, PreviewToolbarControls, REPAIRABLE_KEY, type RepairableBlockEntry, RepairableDiagramExtension, type RepairableDiagramExtensionOptions, type RepairablePluginState, StatusBar, type StatusBarProps, TIMELINE_VIEW_KEY, TRANSITION_ENTRIES, TRANSITION_GROUPS, TemplatePicker, ThemeCustomizerPanel, type ThemeCustomizerPanelProps, ThemePicker, type ThemePickerProps, type ThemeSaveExtras, type TimelineBlockEntry, type TimelineCommand, type TimelineCommandResult, TimelineEditorWidget, type TimelineEditorWidgetProps, type TimelineEventPatch, TimelineTrack, type TimelineTrackProps, type TimelineViewData, TimelineViewExtension, type TimelineViewExtensionOptions, type TimelineViewPluginState, Toolbar, type ToolbarProps, TooltipLayer, type TransitionCatalogEntry, type TransitionFields, type TransitionGroup, TransitionPicker, type TransitionPickerProps, type TreeBlockEntry, type TreeCommand, TreeOutlineWidget, type TreeViewData, TreeViewExtension, type TreeViewExtensionOptions, type TreeViewPluginState, type UseBlockNavigatorOptions, type UseFileDropOptions, type UseFileDropResult, type UseMonacoLoaderResult, VersionHistoryPanel, ViewMenuPanel, ViewSwitcher, type ViewSwitcherProps, addEdgeOp, addItemOp, addNodeOp, addTimelineEventOp, applyAsciiDiagramCommand, applyRepairCommand, applyTimelineCommand, applyTreeCommand, asciiDiagramToCanvas, buildPreviewDoc, classifyFile, codeSnippetFenceLanguageToken, codeSnippetLanguageLabel, codeSnippetMarkdown, detectLanguageFromFileName, draftPatchFromImportedTheme, findAsciiDiagramBlockPos, findCodeSnippetBlockPos, findMermaidDiagramBlockPos, findRepairableBlockPos, findTimelineBlockPos, findTransitionEntry, findTreeBlockPos, formatSeconds, getBlockSlices, getTimelineForNode, indentItemOp, inspectMermaidSource, isAsciiSourceVisible, isCodeSnippetFenceLanguage, isCodeSnippetNode, isMermaidDiagramNode, isMermaidFlowchartShapeId, isMermaidSourceVisible, isRepairableFence, isTimelineSourceSafeForSemanticEdit, lineToOffset, markdownToTiptap, mermaidDiagramMarkdown, mermaidDiagramProperties, mermaidEditCapabilities, mermaidEditableTexts, mermaidErrorMessage, monacoLanguageForFence, moveItemDownOp, moveItemUpOp, moveNodeOp, nextTimelineEventId, normalizeMermaidFlowchartShape, offsetToLine, outdentItemOp, parseTimelineForNode, partitionFiles, processMediaFiles, processTextFile, processTextFiles, readBlockAttrsParams, readBlockAttrsTransition, readBlockAttrsValue, readHeadingLineTransition, removeEdgeOp, removeItemOp, removeNodeOp, removeTimelineEventOp, renameItemOp, renameNodeOp, renderMermaidDiagram, replaceAsciiFenceText, replaceCodeSnippetText, replaceAsciiFenceText as replaceTreeFenceText, resizeNodeOp, resolveFileKind, sanitizeAsciiLabel, sanitizeTimelineText, sanitizeTreeLabel, searchPickerEntries, setBlockAttrsValue, setBlockDurationInSource, setHeadingAttrsTransition, setHeadingLineTransition, setMediaClipInSource, shouldPasteAsAsciiFence, shouldPasteAsTimelineFence, shouldPasteAsTreeFence, sliceIndexAtOffset, spliceBlock, summarizeBlockProps, templateLabel, tiptapToMarkdown, toggleAsciiSource, toggleDirOp, toggleMermaidSource, transitionLabel, translateDiagramOp, updateTimelineEventOp, useAsciiDiagramData, useBlockNavigator, useCodeSnippetData, useCustomTemplates, useCustomThemes, useDocCustomTemplates, useDocCustomThemes, useFileDrop, useMermaidDiagramData, useMonacoLoader, usePreviewSettings, useTimelineData, useTreeViewData };
package/dist/index.js CHANGED
@@ -1,3 +1,6 @@
1
+ import {
2
+ configureMonacoWorkers
3
+ } from "./chunk-BWPFPHWY.js";
1
4
  import {
2
5
  ALL_PICKER_ENTRIES,
3
6
  ANIMATION_SPEED_PRESETS,
@@ -179,7 +182,7 @@ import {
179
182
  usePreviewSettings,
180
183
  useTimelineData,
181
184
  useTreeViewData
182
- } from "./chunk-6QFPBDTY.js";
185
+ } from "./chunk-QN3Q64LV.js";
183
186
  import {
184
187
  JsonEditor
185
188
  } from "./chunk-54UGTQBO.js";
@@ -664,35 +667,6 @@ function ThemeCustomizerPanel({
664
667
  )
665
668
  ] });
666
669
  }
667
-
668
- // src/monacoWorkers.ts
669
- function configureMonacoWorkers(workers) {
670
- const host = globalThis;
671
- host.MonacoEnvironment = {
672
- getWorker(_workerId, label) {
673
- switch (label) {
674
- case "json":
675
- if (workers.json) return new workers.json();
676
- break;
677
- case "css":
678
- case "scss":
679
- case "less":
680
- if (workers.css) return new workers.css();
681
- break;
682
- case "html":
683
- case "handlebars":
684
- case "razor":
685
- if (workers.html) return new workers.html();
686
- break;
687
- case "typescript":
688
- case "javascript":
689
- if (workers.ts) return new workers.ts();
690
- break;
691
- }
692
- return new workers.editor();
693
- }
694
- };
695
- }
696
670
  export {
697
671
  ALL_PICKER_ENTRIES,
698
672
  AsciiDiagramExtension,
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Monaco language-service worker wiring.
3
+ *
4
+ * Monaco offloads its heavy language services — css / html / json / typescript
5
+ * IntelliSense — plus a base editor service (word-based completions, link
6
+ * detection, diffing) to web workers. Those worker bundles must be produced by
7
+ * the HOST application's bundler: the mechanisms for it (Vite's `?worker`
8
+ * import suffix, `new Worker(new URL(...))`, webpack loaders) are all
9
+ * bundler-specific and cannot live inside this tsup-built library.
10
+ *
11
+ * So the division of labor is: the host supplies the five worker constructors
12
+ * (one line each with Vite's `?worker`), and this helper owns the
13
+ * `label → worker` mapping — the part that's fiddly and easy to get wrong.
14
+ *
15
+ * Call once, before the first editor mounts (typically in the app entry):
16
+ *
17
+ * ```ts
18
+ * import { configureMonacoWorkers } from '@bendyline/squisq-editor-react/monaco-workers';
19
+ * import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
20
+ * import JsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
21
+ * import CssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker';
22
+ * import HtmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker';
23
+ * import TsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker';
24
+ *
25
+ * configureMonacoWorkers({
26
+ * editor: EditorWorker, json: JsonWorker, css: CssWorker,
27
+ * html: HtmlWorker, ts: TsWorker,
28
+ * });
29
+ * ```
30
+ *
31
+ * This is purely additive: without it, highlighting, editing, and custom
32
+ * completion providers (e.g. the `{[template]}` typeahead) still work — they
33
+ * run on the main thread. Only the language-service IntelliSense is dormant
34
+ * until the workers are wired.
35
+ */
36
+ /** Zero-arg worker constructor, as produced by Vite's `?worker` import. */
37
+ type MonacoWorkerConstructor = new () => Worker;
38
+ interface MonacoWorkerConstructors {
39
+ /** Base editor worker (word completions, links, diff). Required. */
40
+ editor: MonacoWorkerConstructor;
41
+ /** JSON language service. */
42
+ json?: MonacoWorkerConstructor;
43
+ /** CSS/SCSS/LESS language service. */
44
+ css?: MonacoWorkerConstructor;
45
+ /** HTML/Handlebars/Razor language service. */
46
+ html?: MonacoWorkerConstructor;
47
+ /** TypeScript service — also handles JavaScript. */
48
+ ts?: MonacoWorkerConstructor;
49
+ }
50
+ /**
51
+ * Install `globalThis.MonacoEnvironment.getWorker` so Monaco routes each
52
+ * language to the matching worker, falling back to the base editor worker for
53
+ * any label without a dedicated service (which is every plain language — its
54
+ * grammar-based highlighting needs no worker).
55
+ */
56
+ declare function configureMonacoWorkers(workers: MonacoWorkerConstructors): void;
57
+
58
+ export { type MonacoWorkerConstructor, type MonacoWorkerConstructors, configureMonacoWorkers };
@@ -0,0 +1,6 @@
1
+ import {
2
+ configureMonacoWorkers
3
+ } from "../chunk-BWPFPHWY.js";
4
+ export {
5
+ configureMonacoWorkers
6
+ };
package/dist/monaco.js CHANGED
@@ -1,3 +1,68 @@
1
1
  // src/monaco.ts
2
2
  import "monaco-editor/esm/vs/editor/editor.main.js";
3
+ import * as monaco from "monaco-editor/esm/vs/editor/editor.api.js";
4
+
5
+ // src/monacoJsonc.ts
6
+ var JSONC_LANGUAGE = {
7
+ defaultToken: "",
8
+ // Reuse Monaco's JSON token scopes so built-in and host themes color JSONC
9
+ // exactly like JSON instead of requiring JSONC-specific theme rules.
10
+ tokenPostfix: ".json",
11
+ brackets: [
12
+ { open: "{", close: "}", token: "delimiter.bracket" },
13
+ { open: "[", close: "]", token: "delimiter.array" }
14
+ ],
15
+ tokenizer: {
16
+ root: [
17
+ { include: "@whitespace" },
18
+ [/[{}[\]]/, "@brackets"],
19
+ [/[,:]/, "delimiter"],
20
+ [/-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?/, "number"],
21
+ [/"(?:[^"\\]|\\.)*"(?=\s*:)/, "string.key"],
22
+ [/"(?:[^"\\]|\\.)*"/, "string.value"],
23
+ [/\b(?:true|false|null)\b/, "keyword"]
24
+ ],
25
+ whitespace: [
26
+ [/[ \t\r\n]+/, ""],
27
+ [/\/\*/, "comment", "@comment"],
28
+ [/\/\/.*$/, "comment"]
29
+ ],
30
+ comment: [
31
+ [/[^*/]+/, "comment"],
32
+ [/\*\//, "comment", "@pop"],
33
+ [/[*/]/, "comment"]
34
+ ]
35
+ }
36
+ };
37
+ var JSONC_CONFIGURATION = {
38
+ comments: { lineComment: "//", blockComment: ["/*", "*/"] },
39
+ brackets: [
40
+ ["{", "}"],
41
+ ["[", "]"]
42
+ ],
43
+ autoClosingPairs: [
44
+ { open: "{", close: "}" },
45
+ { open: "[", close: "]" },
46
+ { open: '"', close: '"', notIn: ["string"] }
47
+ ],
48
+ surroundingPairs: [
49
+ { open: "{", close: "}" },
50
+ { open: "[", close: "]" },
51
+ { open: '"', close: '"' }
52
+ ]
53
+ };
54
+ function registerJsoncLanguage(monaco2) {
55
+ if (monaco2.languages.getLanguages().some(({ id }) => id === "jsonc")) return;
56
+ monaco2.languages.register({
57
+ id: "jsonc",
58
+ aliases: ["JSONC", "JSON with Comments", "jsonc"],
59
+ extensions: [".jsonc"],
60
+ mimetypes: ["application/jsonc"]
61
+ });
62
+ monaco2.languages.setLanguageConfiguration("jsonc", JSONC_CONFIGURATION);
63
+ monaco2.languages.setMonarchTokensProvider("jsonc", JSONC_LANGUAGE);
64
+ }
65
+
66
+ // src/monaco.ts
3
67
  export * from "monaco-editor/esm/vs/editor/editor.api.js";
68
+ registerJsoncLanguage(monaco);
@@ -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-DYdK5qFd.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-YIIUac26.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-6QFPBDTY.js";
8
+ } from "../chunk-QN3Q64LV.js";
9
9
  import "../chunk-NITZVAXL.js";
10
10
  import "../chunk-V44VP242.js";
11
11
  import "../chunk-MJJK7YQB.js";
@@ -727,6 +727,18 @@ interface EditorShellProps {
727
727
  * sense (e.g. editing free-form prompt documents). Defaults to true.
728
728
  */
729
729
  showPlayTab?: boolean;
730
+ /**
731
+ * Whether Use mode may open its audience view in a separate browser window.
732
+ * Defaults to true. Disable this in embedded hosts that block popups.
733
+ */
734
+ allowPresentationWindow?: boolean;
735
+ /**
736
+ * Whether Use mode may enter browser full screen. Defaults to true. Disable
737
+ * this in embedded hosts whose webview does not support the Fullscreen API.
738
+ */
739
+ allowPresentationFullscreen?: boolean;
740
+ /** Whether to offer print preview and browser printing. Defaults to true. */
741
+ allowPrint?: boolean;
730
742
  /**
731
743
  * Optional "submit on Enter" callback. When provided, a plain Enter
732
744
  * keypress fires this callback instead of inserting a newline, and
@@ -983,7 +995,7 @@ interface EditorShellProps {
983
995
  * Complete markdown editor shell with toolbar, view switcher, and three
984
996
  * editing modes: Raw (Monaco), WYSIWYG (Tiptap), and Preview.
985
997
  */
986
- declare function EditorShell({ initialMarkdown, initialView, articleId, basePath, onChange, onLinkClick, colorScheme, className, height, minHeight, maxHeight, mediaProvider, workspaceContainer, allowVersioning, versionBasename, versioningPrunePolicy, versioningAutoSaveIdleMs, onSaveVersion, showFilesToggle, toolbarSlotLeft, toolbarSlotAfterActions, toolbarSlotRight, statusBarSlotRight, showPlayTab, submitOnEnter, codeContext, fullWidth, uxFont, thinMargins, writeCanvasSettings, showStatusBar, imageDisplayMode, fileName, language, findMode, onFindModeChange, mentionProvider, documentLinkProvider, linkSchemes, allowRecording, allowNarrate, placeholder, readOnly, imageSrc, imageAlt, imageMode, imageEditorContainer, onImageExport, inlinePreview, inlinePreviewWidth, outline, outlineWidth, blockTags, blockTagVisibility, themeInheritance, viewPreferences, onViewPreferencesChange, themeOverride, }: EditorShellProps): react_jsx_runtime.JSX.Element;
998
+ declare function EditorShell({ initialMarkdown, initialView, articleId, basePath, onChange, onLinkClick, colorScheme, className, height, minHeight, maxHeight, mediaProvider, workspaceContainer, allowVersioning, versionBasename, versioningPrunePolicy, versioningAutoSaveIdleMs, onSaveVersion, showFilesToggle, toolbarSlotLeft, toolbarSlotAfterActions, toolbarSlotRight, statusBarSlotRight, showPlayTab, allowPresentationWindow, allowPresentationFullscreen, allowPrint, submitOnEnter, codeContext, fullWidth, uxFont, thinMargins, writeCanvasSettings, showStatusBar, imageDisplayMode, fileName, language, findMode, onFindModeChange, mentionProvider, documentLinkProvider, linkSchemes, allowRecording, allowNarrate, placeholder, readOnly, imageSrc, imageAlt, imageMode, imageEditorContainer, onImageExport, inlinePreview, inlinePreviewWidth, outline, outlineWidth, blockTags, blockTagVisibility, themeInheritance, viewPreferences, onViewPreferencesChange, themeOverride, }: EditorShellProps): react_jsx_runtime.JSX.Element;
987
999
 
988
1000
  /**
989
1001
  * RawEditor
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bendyline/squisq-editor-react",
3
- "version": "2.3.2",
3
+ "version": "2.3.3",
4
4
  "description": "React editor shell with raw/WYSIWYG/preview modes for Squisq documents",
5
5
  "license": "MIT",
6
6
  "author": "Bendyline",
@@ -44,6 +44,10 @@
44
44
  "types": "./dist/monaco.d.ts",
45
45
  "import": "./dist/monaco.js"
46
46
  },
47
+ "./monaco-workers": {
48
+ "types": "./dist/monaco-workers/index.d.ts",
49
+ "import": "./dist/monaco-workers/index.js"
50
+ },
47
51
  "./shell": {
48
52
  "types": "./dist/shell/index.d.ts",
49
53
  "import": "./dist/shell/index.js"
@@ -80,9 +84,9 @@
80
84
  "react-dom": "^18.0.0 || ^19.0.0"
81
85
  },
82
86
  "dependencies": {
83
- "@bendyline/squisq": "2.3.1",
84
- "@bendyline/squisq-formats": "2.3.1",
85
- "@bendyline/squisq-react": "2.3.1",
87
+ "@bendyline/squisq": "2.3.2",
88
+ "@bendyline/squisq-formats": "2.3.2",
89
+ "@bendyline/squisq-react": "2.3.2",
86
90
  "@fortawesome/fontawesome-free": "7.2.0",
87
91
  "@tiptap/extension-image": "2.27.2",
88
92
  "@tiptap/extension-link": "2.27.2",