@particle-academy/fancy-slides 0.10.0 → 0.12.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.cts CHANGED
@@ -300,13 +300,15 @@ interface EditorToolbarProps {
300
300
  onPresent?: () => void;
301
301
  /** When true, disables every Insert button (e.g. when no slide is selected). */
302
302
  disabled?: boolean;
303
+ /** Host-injected content rendered on the toolbar's trailing edge, left of Present. */
304
+ toolbarExtra?: ReactNode;
303
305
  }
304
306
  /**
305
307
  * Top toolbar. Built on react-fancy's `Action`, `Dropdown`, `Tooltip`,
306
308
  * `Badge`, `Separator`. Designed to be slotted into the editor chrome —
307
309
  * doesn't manage its own scroll or sticky behavior.
308
310
  */
309
- declare function EditorToolbar({ title, onTitleChange, themeName, onApplyTheme, onInsertText, onInsertImage, onInsertShape, onInsertChart, onInsertCode, onInsertTable, onPresent, disabled, }: EditorToolbarProps): react_jsx_runtime.JSX.Element;
311
+ declare function EditorToolbar({ title, onTitleChange, themeName, onApplyTheme, onInsertText, onInsertImage, onInsertShape, onInsertChart, onInsertCode, onInsertTable, onPresent, disabled, toolbarExtra, }: EditorToolbarProps): react_jsx_runtime.JSX.Element;
310
312
 
311
313
  interface ElementInspectorProps {
312
314
  /** Element being inspected. `null` falls back to slide settings (or the empty state). */
package/dist/index.d.ts CHANGED
@@ -300,13 +300,15 @@ interface EditorToolbarProps {
300
300
  onPresent?: () => void;
301
301
  /** When true, disables every Insert button (e.g. when no slide is selected). */
302
302
  disabled?: boolean;
303
+ /** Host-injected content rendered on the toolbar's trailing edge, left of Present. */
304
+ toolbarExtra?: ReactNode;
303
305
  }
304
306
  /**
305
307
  * Top toolbar. Built on react-fancy's `Action`, `Dropdown`, `Tooltip`,
306
308
  * `Badge`, `Separator`. Designed to be slotted into the editor chrome —
307
309
  * doesn't manage its own scroll or sticky behavior.
308
310
  */
309
- declare function EditorToolbar({ title, onTitleChange, themeName, onApplyTheme, onInsertText, onInsertImage, onInsertShape, onInsertChart, onInsertCode, onInsertTable, onPresent, disabled, }: EditorToolbarProps): react_jsx_runtime.JSX.Element;
311
+ declare function EditorToolbar({ title, onTitleChange, themeName, onApplyTheme, onInsertText, onInsertImage, onInsertShape, onInsertChart, onInsertCode, onInsertTable, onPresent, disabled, toolbarExtra, }: EditorToolbarProps): react_jsx_runtime.JSX.Element;
310
312
 
311
313
  interface ElementInspectorProps {
312
314
  /** Element being inspected. `null` falls back to slide settings (or the empty state). */
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { defaultElementRegistry } from './chunk-YEJZYKVB.js';
2
2
  import { isDarkColor, SlideContext } from './chunk-WIUXPQAK.js';
3
3
  export { useIsDarkSlide, useSlideContext, useSlideTheme } from './chunk-WIUXPQAK.js';
4
- import { useId, useRef, useState, useEffect, useMemo, useCallback } from 'react';
4
+ import { lazy, useId, useRef, useState, useEffect, useMemo, useCallback, Suspense } from 'react';
5
5
  import { Editor, ContentRenderer, Text, Action, ContextMenu, Separator, Tooltip, Dropdown, Badge, Heading, Tabs, Card, Select, Input, ColorPicker, Textarea, Slider, Switch } from '@particle-academy/react-fancy';
6
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
6
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
7
 
8
8
  // src/theme/default-theme.ts
9
9
  var defaultTheme = {
@@ -1963,7 +1963,8 @@ function EditorToolbar({
1963
1963
  onInsertCode,
1964
1964
  onInsertTable,
1965
1965
  onPresent,
1966
- disabled = false
1966
+ disabled = false,
1967
+ toolbarExtra
1967
1968
  }) {
1968
1969
  return /* @__PURE__ */ jsxs("div", { className: "fs-toolbar flex items-center gap-2 border-b border-zinc-200 bg-white px-4 py-2 dark:border-zinc-800 dark:bg-zinc-950", children: [
1969
1970
  /* @__PURE__ */ jsx(
@@ -2010,7 +2011,53 @@ function EditorToolbar({
2010
2011
  ] }) }),
2011
2012
  /* @__PURE__ */ jsx(Dropdown.Items, { children: Object.values(builtinThemes).map((t) => /* @__PURE__ */ jsx(Dropdown.Item, { onClick: () => onApplyTheme?.(t), children: t.name }, t.name)) })
2012
2013
  ] }),
2013
- /* @__PURE__ */ jsx("div", { className: "ml-auto flex items-center gap-2", children: /* @__PURE__ */ jsx(Tooltip, { content: "Present (F)", children: /* @__PURE__ */ jsx(Action, { color: "violet", size: "sm", icon: "play", onClick: onPresent, children: "Present" }) }) })
2014
+ /* @__PURE__ */ jsxs("div", { className: "ml-auto flex items-center gap-2", children: [
2015
+ toolbarExtra,
2016
+ /* @__PURE__ */ jsx(Tooltip, { content: "Present (F)", children: /* @__PURE__ */ jsx(Action, { color: "violet", size: "sm", icon: "play", onClick: onPresent, children: "Present" }) })
2017
+ ] })
2018
+ ] });
2019
+ }
2020
+ function FallbackTextarea({ value, onChange }) {
2021
+ return /* @__PURE__ */ jsx(
2022
+ "textarea",
2023
+ {
2024
+ className: "block w-full resize-y rounded-md border border-zinc-300 bg-zinc-950 p-2 font-mono text-xs text-zinc-100 dark:border-zinc-700",
2025
+ rows: 8,
2026
+ value,
2027
+ spellCheck: false,
2028
+ onChange: (e) => onChange(e.target.value)
2029
+ }
2030
+ );
2031
+ }
2032
+ var CodeInputInner = lazy(async () => {
2033
+ try {
2034
+ const mod = await import('@particle-academy/fancy-code');
2035
+ const CodeEditor = mod.CodeEditor;
2036
+ if (!CodeEditor) return { default: FallbackTextarea };
2037
+ return {
2038
+ default: ({ value, language, theme, onChange }) => /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-md border border-zinc-300 dark:border-zinc-700", children: /* @__PURE__ */ jsx(
2039
+ CodeEditor,
2040
+ {
2041
+ value,
2042
+ onChange,
2043
+ language,
2044
+ theme,
2045
+ lineNumbers: true,
2046
+ wordWrap: true,
2047
+ minHeight: 140,
2048
+ maxHeight: 280,
2049
+ children: /* @__PURE__ */ jsx(CodeEditor.Panel, {})
2050
+ }
2051
+ ) })
2052
+ };
2053
+ } catch {
2054
+ return { default: FallbackTextarea };
2055
+ }
2056
+ });
2057
+ function CodeInput(props) {
2058
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
2059
+ /* @__PURE__ */ jsx("label", { className: "block text-xs font-medium text-zinc-600 dark:text-zinc-400", children: "Code" }),
2060
+ /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(FallbackTextarea, { ...props }), children: /* @__PURE__ */ jsx(CodeInputInner, { ...props }) })
2014
2061
  ] });
2015
2062
  }
2016
2063
  function ElementInspector({ element, onPatch, onDelete, onLockToggle, slide, onSetTransition, onSetBackground, onSetLayout, onSetAnimation, onSetElementAnimation }) {
@@ -2570,10 +2617,41 @@ function ShapeStyleControls({ element, onPatch }) {
2570
2617
  (element.shape === "rounded-rect" || element.shape === "rect") && /* @__PURE__ */ jsx(Slider, { label: "Corner radius", value: element.radius ?? 0, onValueChange: (v) => onPatch({ radius: Number(v) }), min: 0, max: 40 })
2571
2618
  ] });
2572
2619
  }
2620
+ var CODE_LANGUAGES = [
2621
+ { value: "javascript", label: "JavaScript" },
2622
+ { value: "typescript", label: "TypeScript" },
2623
+ { value: "jsx", label: "JSX" },
2624
+ { value: "tsx", label: "TSX" },
2625
+ { value: "html", label: "HTML" },
2626
+ { value: "css", label: "CSS" },
2627
+ { value: "json", label: "JSON" },
2628
+ { value: "python", label: "Python" },
2629
+ { value: "php", label: "PHP" },
2630
+ { value: "bash", label: "Bash" },
2631
+ { value: "go", label: "Go" },
2632
+ { value: "sql", label: "SQL" },
2633
+ { value: "markdown", label: "Markdown" }
2634
+ ];
2573
2635
  function CodeStyleControls({ element, onPatch }) {
2574
2636
  return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
2575
- /* @__PURE__ */ jsx(Textarea, { label: "Code", value: element.code, onValueChange: (v) => onPatch({ code: v }), rows: 6, autoResize: true }),
2576
- /* @__PURE__ */ jsx(Input, { label: "Language", value: element.language ?? "javascript", onChange: (e) => onPatch({ language: e.target.value }) }),
2637
+ /* @__PURE__ */ jsx(
2638
+ CodeInput,
2639
+ {
2640
+ value: element.code,
2641
+ language: element.language ?? "javascript",
2642
+ theme: element.codeTheme ?? "dark",
2643
+ onChange: (v) => onPatch({ code: v })
2644
+ }
2645
+ ),
2646
+ /* @__PURE__ */ jsx(
2647
+ Select,
2648
+ {
2649
+ label: "Language",
2650
+ list: CODE_LANGUAGES,
2651
+ value: element.language ?? "javascript",
2652
+ onValueChange: (v) => onPatch({ language: v })
2653
+ }
2654
+ ),
2577
2655
  /* @__PURE__ */ jsx(
2578
2656
  Select,
2579
2657
  {
@@ -3028,7 +3106,8 @@ function DeckEditor({
3028
3106
  onInsertCode: insertCode,
3029
3107
  onInsertTable: insertTable,
3030
3108
  onPresent,
3031
- disabled: !slide
3109
+ disabled: !slide,
3110
+ toolbarExtra
3032
3111
  }
3033
3112
  ),
3034
3113
  /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1", children: [
@@ -3099,8 +3178,7 @@ function DeckEditor({
3099
3178
  onSetElementAnimation: (eid, animation) => slide && ops.setAnimation(slide.id, eid, animation)
3100
3179
  }
3101
3180
  ) })
3102
- ] }),
3103
- toolbarExtra
3181
+ ] })
3104
3182
  ]
3105
3183
  }
3106
3184
  );