@blockslides/react 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,11 +1,16 @@
1
1
  import * as react_jsx_runtime_js from 'react/jsx-runtime.js';
2
- import { EditorOptions, Editor, MarkViewRendererOptions, MarkView, MarkViewProps, MarkViewRenderer, NodeViewProps, NodeViewRendererOptions, NodeView, NodeViewRendererProps, NodeViewRenderer } from '@blockslides/core';
2
+ import * as _blockslides_core from '@blockslides/core';
3
+ import { EditorOptions, Editor, MarkViewRendererOptions, MarkView, MarkViewProps, MarkViewRenderer, NodeViewProps, NodeViewRendererOptions, NodeView, NodeViewRendererProps, NodeViewRenderer, JSONContent, AnyExtension } from '@blockslides/core';
3
4
  export * from '@blockslides/core';
4
5
  import * as React from 'react';
5
- import React__default, { DependencyList, ReactNode, HTMLAttributes, HTMLProps, ForwardedRef, ComponentProps, ComponentClass, FunctionComponent, ForwardRefExoticComponent, PropsWithoutRef, RefAttributes, ComponentType as ComponentType$1 } from 'react';
6
+ import React__default, { DependencyList, ReactNode, HTMLAttributes, HTMLProps, ForwardedRef, ComponentProps, ComponentClass, FunctionComponent, ForwardRefExoticComponent, PropsWithoutRef, RefAttributes, ComponentType as ComponentType$1, CSSProperties } from 'react';
6
7
  import { Node } from '@blockslides/pm/model';
7
8
  import { Decoration, DecorationSource } from '@blockslides/pm/view';
9
+ import * as packages_ai_context_src_templates_v1_presetTemplateBuilder_js from 'packages/ai-context/src/templates/v1/presetTemplateBuilder.js';
10
+ import * as _blockslides_extension_kit from '@blockslides/extension-kit';
11
+ import { ExtensionKitOptions } from '@blockslides/extension-kit';
8
12
  import { BubbleMenuPresetOptions } from '@blockslides/extension-bubble-menu-preset';
13
+ import { templatesV1 } from '@blockslides/ai-context';
9
14
 
10
15
  /**
11
16
  * The options for the `useEditor` hook.
@@ -287,6 +292,79 @@ declare class ReactNodeView<T = HTMLElement, Component extends ComponentType$1<R
287
292
  */
288
293
  declare function ReactNodeViewRenderer<T = HTMLElement>(component: ComponentType$1<ReactNodeViewProps<T>>, options?: Partial<ReactNodeViewRendererOptions>): NodeViewRenderer;
289
294
 
295
+ type BubbleMenuPresetProps = Omit<BubbleMenuPresetOptions, 'element' | 'pluginKey'> & React__default.HTMLAttributes<HTMLElement> & {
296
+ editor?: Editor | null;
297
+ };
298
+ declare const BubbleMenuPreset: React__default.ForwardRefExoticComponent<Omit<BubbleMenuPresetOptions, "element" | "pluginKey"> & React__default.HTMLAttributes<HTMLElement> & {
299
+ editor?: Editor | null;
300
+ } & React__default.RefAttributes<HTMLElement>>;
301
+
302
+ type PresetTemplates = ReturnType<typeof templatesV1.listPresetTemplates>;
303
+ type UseSlideEditorProps = {
304
+ /**
305
+ * Initial content for the editor. If omitted, a single preset slide is used.
306
+ */
307
+ content?: UseEditorOptions["content"];
308
+ /**
309
+ * Called on every update with the current JSON document.
310
+ */
311
+ onChange?: (doc: JSONContent, editor: Editor) => void;
312
+ /**
313
+ * Additional extensions to append after the ExtensionKit bundle.
314
+ */
315
+ extensions?: AnyExtension[];
316
+ /**
317
+ * Customize or disable pieces of ExtensionKit (e.g., bubbleMenu: false).
318
+ */
319
+ extensionKitOptions?: ExtensionKitOptions;
320
+ /**
321
+ * Optional preset list to power the add-slide button.
322
+ */
323
+ presetTemplates?: PresetTemplates;
324
+ /**
325
+ * Dependencies array forwarded to useEditor for re-instantiation control.
326
+ * Leave empty to avoid recreating the editor on prop changes.
327
+ */
328
+ deps?: DependencyList;
329
+ /**
330
+ * Called once when an editor instance is ready.
331
+ */
332
+ onEditorReady?: (editor: Editor) => void;
333
+ } & Omit<UseEditorOptions, "extensions" | "content">;
334
+ declare const useSlideEditor: ({ content, onChange, extensions, extensionKitOptions, presetTemplates, deps, onEditorReady, immediatelyRender, shouldRerenderOnTransaction, theme, editorProps, onUpdate, ...editorOptions }?: UseSlideEditorProps) => {
335
+ editor: Editor;
336
+ presets: templatesV1.PresetTemplate[];
337
+ };
338
+
339
+ declare const SlideEditor: React__default.ForwardRefExoticComponent<{
340
+ content?: UseEditorOptions["content"];
341
+ onChange?: (doc: _blockslides_core.JSONContent, editor: _blockslides_core.Editor) => void;
342
+ extensions?: _blockslides_core.AnyExtension[];
343
+ extensionKitOptions?: _blockslides_extension_kit.ExtensionKitOptions;
344
+ presetTemplates?: packages_ai_context_src_templates_v1_presetTemplateBuilder_js.PresetTemplate[];
345
+ deps?: React__default.DependencyList;
346
+ onEditorReady?: (editor: _blockslides_core.Editor) => void;
347
+ } & Omit<UseEditorOptions, "content" | "extensions"> & {
348
+ /**
349
+ * Toggle or customize the built-in BubbleMenuPreset.
350
+ * - true (default): render with defaults
351
+ * - false: disable entirely
352
+ * - object: pass through to BubbleMenuPreset
353
+ */
354
+ bubbleMenuPreset?: boolean | BubbleMenuPresetProps;
355
+ /**
356
+ * Additional props forwarded to EditorContent.
357
+ */
358
+ editorContentProps?: Omit<EditorContentProps, "editor">;
359
+ /**
360
+ * Viewport scale factor applied to the slide viewport.
361
+ * @default 1
362
+ */
363
+ viewportScale?: number;
364
+ className?: string;
365
+ style?: CSSProperties;
366
+ } & React__default.RefAttributes<HTMLDivElement>>;
367
+
290
368
  type EditorStateSnapshot<TEditor extends Editor | null = Editor | null> = {
291
369
  editor: TEditor;
292
370
  transactionNumber: number;
@@ -347,11 +425,4 @@ declare const ReactNodeViewContentProvider: ({ children, content }: {
347
425
  }) => React.FunctionComponentElement<React.ProviderProps<ReactNodeViewContextProps>>;
348
426
  declare const useReactNodeView: () => ReactNodeViewContextProps;
349
427
 
350
- type BubbleMenuPresetProps = Omit<BubbleMenuPresetOptions, 'element'> & React__default.HTMLAttributes<HTMLElement> & {
351
- editor?: Editor | null;
352
- };
353
- declare const BubbleMenuPreset: React__default.ForwardRefExoticComponent<Omit<BubbleMenuPresetOptions, "element"> & React__default.HTMLAttributes<HTMLElement> & {
354
- editor?: Editor | null;
355
- } & React__default.RefAttributes<HTMLElement>>;
356
-
357
- export { BubbleMenuPreset, type BubbleMenuPresetProps, EditorConsumer, EditorContent, type EditorContentProps, EditorContext, type EditorContextValue, EditorProvider, type EditorProviderProps, type EditorStateSnapshot, MarkViewContent, type MarkViewContentProps, type MarkViewContextProps, NodeViewContent, type NodeViewContentProps, NodeViewWrapper, type NodeViewWrapperProps, PureEditorContent, ReactMarkView, ReactMarkViewContext, ReactMarkViewRenderer, type ReactMarkViewRendererOptions, ReactNodeView, ReactNodeViewContentProvider, ReactNodeViewContext, type ReactNodeViewContextProps, type ReactNodeViewProps, ReactNodeViewRenderer, type ReactNodeViewRendererOptions, ReactRenderer, type ReactRendererOptions, type UseEditorOptions, type UseEditorStateOptions, useCurrentEditor, useEditor, useEditorState, useReactNodeView };
428
+ export { BubbleMenuPreset, type BubbleMenuPresetProps, EditorConsumer, EditorContent, type EditorContentProps, EditorContext, type EditorContextValue, EditorProvider, type EditorProviderProps, type EditorStateSnapshot, MarkViewContent, type MarkViewContentProps, type MarkViewContextProps, NodeViewContent, type NodeViewContentProps, NodeViewWrapper, type NodeViewWrapperProps, PureEditorContent, ReactMarkView, ReactMarkViewContext, ReactMarkViewRenderer, type ReactMarkViewRendererOptions, ReactNodeView, ReactNodeViewContentProvider, ReactNodeViewContext, type ReactNodeViewContextProps, type ReactNodeViewProps, ReactNodeViewRenderer, type ReactNodeViewRendererOptions, ReactRenderer, type ReactRendererOptions, SlideEditor as ReactSlideEditor, type UseEditorOptions, type UseEditorStateOptions, type UseSlideEditorProps, useCurrentEditor, useEditor, useEditorState, useReactNodeView, useSlideEditor };
package/dist/index.js CHANGED
@@ -1015,6 +1015,9 @@ function ReactNodeViewRenderer(component, options) {
1015
1015
  };
1016
1016
  }
1017
1017
 
1018
+ // src/SlideEditor.tsx
1019
+ import { forwardRef as forwardRef2, useMemo as useMemo3 } from "react";
1020
+
1018
1021
  // src/menus/BubbleMenuPreset.tsx
1019
1022
  import React5, { useEffect as useEffect3, useRef as useRef2 } from "react";
1020
1023
  import { createPortal } from "react-dom";
@@ -1035,7 +1038,6 @@ import { isTextSelection } from "@blockslides/core";
1035
1038
  import { jsx as jsx8 } from "react/jsx-runtime";
1036
1039
  var BubbleMenuPreset = React5.forwardRef(
1037
1040
  ({
1038
- pluginKey = "bubbleMenuPreset",
1039
1041
  editor,
1040
1042
  updateDelay,
1041
1043
  resizeDelay,
@@ -1055,6 +1057,7 @@ var BubbleMenuPreset = React5.forwardRef(
1055
1057
  onImageReplace,
1056
1058
  ...rest
1057
1059
  }, ref) => {
1060
+ const pluginKey = "bubbleMenuPreset";
1058
1061
  const { editor: currentEditor } = useCurrentEditor();
1059
1062
  const menuEl = useRef2(null);
1060
1063
  useEffect3(() => {
@@ -1114,7 +1117,6 @@ var BubbleMenuPreset = React5.forwardRef(
1114
1117
  }, [
1115
1118
  editor,
1116
1119
  currentEditor,
1117
- pluginKey,
1118
1120
  updateDelay,
1119
1121
  resizeDelay,
1120
1122
  appendTo,
@@ -1138,6 +1140,222 @@ var BubbleMenuPreset = React5.forwardRef(
1138
1140
  );
1139
1141
  BubbleMenuPreset.displayName = "BubbleMenuPreset";
1140
1142
 
1143
+ // src/useSlideEditor.ts
1144
+ import { useEffect as useEffect4, useMemo as useMemo2 } from "react";
1145
+ import { templatesV1 } from "@blockslides/ai-context";
1146
+ import {
1147
+ ExtensionKit
1148
+ } from "@blockslides/extension-kit";
1149
+ var defaultSlide = () => ({
1150
+ /**
1151
+ * Placeholder slide if no content is provided.
1152
+ */
1153
+ type: "doc",
1154
+ content: [
1155
+ {
1156
+ type: "slide",
1157
+ attrs: {
1158
+ size: "16x9",
1159
+ className: "",
1160
+ id: "slide-1",
1161
+ backgroundMode: "none",
1162
+ backgroundColor: null,
1163
+ backgroundImage: null,
1164
+ backgroundOverlayColor: null,
1165
+ backgroundOverlayOpacity: null
1166
+ },
1167
+ content: [
1168
+ {
1169
+ type: "column",
1170
+ attrs: {
1171
+ align: "center",
1172
+ padding: "lg",
1173
+ margin: null,
1174
+ gap: "md",
1175
+ backgroundColor: "#ffffff",
1176
+ backgroundImage: null,
1177
+ borderRadius: null,
1178
+ border: null,
1179
+ fill: true,
1180
+ width: null,
1181
+ height: null,
1182
+ justify: "center"
1183
+ },
1184
+ content: [
1185
+ {
1186
+ type: "heading",
1187
+ attrs: {
1188
+ align: null,
1189
+ padding: null,
1190
+ margin: null,
1191
+ gap: null,
1192
+ backgroundColor: null,
1193
+ backgroundImage: null,
1194
+ borderRadius: null,
1195
+ border: null,
1196
+ fill: null,
1197
+ width: null,
1198
+ height: null,
1199
+ justify: null,
1200
+ id: "1fc4664c-333d-4203-a3f1-3ad27a54c535",
1201
+ "data-toc-id": "1fc4664c-333d-4203-a3f1-3ad27a54c535",
1202
+ level: 1
1203
+ },
1204
+ content: [
1205
+ {
1206
+ type: "text",
1207
+ text: "Lorem ipsum dolor sit amet"
1208
+ }
1209
+ ]
1210
+ },
1211
+ {
1212
+ type: "paragraph",
1213
+ attrs: {
1214
+ align: null,
1215
+ padding: null,
1216
+ margin: null,
1217
+ gap: null,
1218
+ backgroundColor: null,
1219
+ backgroundImage: null,
1220
+ borderRadius: null,
1221
+ border: null,
1222
+ fill: null,
1223
+ width: null,
1224
+ height: null,
1225
+ justify: null
1226
+ },
1227
+ content: [
1228
+ {
1229
+ type: "text",
1230
+ text: "Consectetur adipiscing elit. Sed do eiusmod tempor incididunt. "
1231
+ }
1232
+ ]
1233
+ }
1234
+ ]
1235
+ }
1236
+ ]
1237
+ }
1238
+ ]
1239
+ });
1240
+ var defaultAddSlideButton = (presets) => ({
1241
+ showPresets: true,
1242
+ presets,
1243
+ presetBackground: "#0f172a",
1244
+ presetForeground: "#e5e7eb"
1245
+ });
1246
+ var defaultSlideOptions = {
1247
+ renderMode: "dynamic",
1248
+ hoverOutline: { color: "#3b82f6", width: "1.5px", offset: "4px" },
1249
+ hoverOutlineCascade: false
1250
+ };
1251
+ var useSlideEditor = ({
1252
+ content,
1253
+ onChange,
1254
+ extensions,
1255
+ extensionKitOptions,
1256
+ presetTemplates,
1257
+ deps = [],
1258
+ onEditorReady,
1259
+ immediatelyRender = false,
1260
+ shouldRerenderOnTransaction = false,
1261
+ theme = "light",
1262
+ editorProps,
1263
+ onUpdate,
1264
+ ...editorOptions
1265
+ } = {}) => {
1266
+ var _a;
1267
+ const presets = useMemo2(
1268
+ () => presetTemplates != null ? presetTemplates : templatesV1.listPresetTemplates(),
1269
+ [presetTemplates]
1270
+ );
1271
+ const mergedExtensionKitOptions = useMemo2(() => {
1272
+ var _a2, _b;
1273
+ const addSlideButton = (extensionKitOptions == null ? void 0 : extensionKitOptions.addSlideButton) === false ? false : {
1274
+ ...defaultAddSlideButton(presets),
1275
+ ...(_a2 = extensionKitOptions == null ? void 0 : extensionKitOptions.addSlideButton) != null ? _a2 : {}
1276
+ };
1277
+ const slide = (extensionKitOptions == null ? void 0 : extensionKitOptions.slide) === false ? false : {
1278
+ ...defaultSlideOptions,
1279
+ ...(_b = extensionKitOptions == null ? void 0 : extensionKitOptions.slide) != null ? _b : {}
1280
+ };
1281
+ return {
1282
+ ...extensionKitOptions,
1283
+ addSlideButton,
1284
+ slide
1285
+ };
1286
+ }, [extensionKitOptions, presets]);
1287
+ const resolvedExtensions = useMemo2(() => {
1288
+ const kit = ExtensionKit.configure(mergedExtensionKitOptions);
1289
+ return extensions ? [kit, ...extensions] : [kit];
1290
+ }, [extensions, mergedExtensionKitOptions]);
1291
+ const initialContent = content != null ? content : defaultSlide();
1292
+ const editor = useEditor(
1293
+ {
1294
+ content: initialContent,
1295
+ extensions: resolvedExtensions,
1296
+ immediatelyRender,
1297
+ shouldRerenderOnTransaction,
1298
+ theme,
1299
+ editorProps: {
1300
+ attributes: {
1301
+ autocomplete: "off",
1302
+ autocorrect: "off",
1303
+ autocapitalize: "off",
1304
+ class: "min-h-full min-w-full",
1305
+ ...(_a = editorProps == null ? void 0 : editorProps.attributes) != null ? _a : {}
1306
+ },
1307
+ ...editorProps
1308
+ },
1309
+ ...editorOptions,
1310
+ onUpdate: (ctx) => {
1311
+ const json = ctx.editor.getJSON();
1312
+ onChange == null ? void 0 : onChange(json, ctx.editor);
1313
+ onUpdate == null ? void 0 : onUpdate(ctx);
1314
+ }
1315
+ },
1316
+ deps
1317
+ );
1318
+ useEffect4(() => {
1319
+ if (editor && !editor.isDestroyed) {
1320
+ onEditorReady == null ? void 0 : onEditorReady(editor);
1321
+ }
1322
+ }, [editor, onEditorReady]);
1323
+ return { editor, presets };
1324
+ };
1325
+
1326
+ // src/SlideEditor.tsx
1327
+ import { jsx as jsx9, jsxs as jsxs3 } from "react/jsx-runtime";
1328
+ var SlideEditor = forwardRef2(
1329
+ ({
1330
+ bubbleMenuPreset = true,
1331
+ editorContentProps,
1332
+ viewportScale = 1,
1333
+ className,
1334
+ style,
1335
+ ...hookProps
1336
+ }, ref) => {
1337
+ const { editor } = useSlideEditor(hookProps);
1338
+ const bubbleMenuProps = useMemo3(() => {
1339
+ if (bubbleMenuPreset === false) return null;
1340
+ if (bubbleMenuPreset === true) return {};
1341
+ return bubbleMenuPreset;
1342
+ }, [bubbleMenuPreset]);
1343
+ if (!editor) return null;
1344
+ return /* @__PURE__ */ jsx9("div", { ref, className, style, children: /* @__PURE__ */ jsxs3(
1345
+ "div",
1346
+ {
1347
+ className: "bs-viewport",
1348
+ style: { ["--zoom"]: viewportScale },
1349
+ children: [
1350
+ /* @__PURE__ */ jsx9(EditorContent, { editor, ...editorContentProps }),
1351
+ bubbleMenuProps && /* @__PURE__ */ jsx9(BubbleMenuPreset, { editor, ...bubbleMenuProps })
1352
+ ]
1353
+ }
1354
+ ) });
1355
+ }
1356
+ );
1357
+ SlideEditor.displayName = "SlideEditor";
1358
+
1141
1359
  // src/index.ts
1142
1360
  export * from "@blockslides/core";
1143
1361
  export {
@@ -1158,9 +1376,11 @@ export {
1158
1376
  ReactNodeViewContext,
1159
1377
  ReactNodeViewRenderer,
1160
1378
  ReactRenderer,
1379
+ SlideEditor as ReactSlideEditor,
1161
1380
  useCurrentEditor,
1162
1381
  useEditor,
1163
1382
  useEditorState,
1164
- useReactNodeView
1383
+ useReactNodeView,
1384
+ useSlideEditor
1165
1385
  };
1166
1386
  //# sourceMappingURL=index.js.map