@particle-academy/fancy-slides 0.7.0 → 0.8.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.cjs CHANGED
@@ -2250,10 +2250,10 @@ function EditorToolbar({
2250
2250
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-auto flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(reactFancy.Tooltip, { content: "Present (F)", children: /* @__PURE__ */ jsxRuntime.jsx(reactFancy.Action, { color: "violet", size: "sm", icon: "play", onClick: onPresent, children: "Present" }) }) })
2251
2251
  ] });
2252
2252
  }
2253
- function ElementInspector({ element, onPatch, onDelete, onLockToggle, slide, onSetTransition, onSetBackground, onSetAnimation, onSetElementAnimation }) {
2253
+ function ElementInspector({ element, onPatch, onDelete, onLockToggle, slide, onSetTransition, onSetBackground, onSetLayout, onSetAnimation, onSetElementAnimation }) {
2254
2254
  if (!element) {
2255
2255
  if (slide) {
2256
- return /* @__PURE__ */ jsxRuntime.jsx(SlideSettings, { slide, onSetTransition, onSetBackground, onSetElementAnimation });
2256
+ return /* @__PURE__ */ jsxRuntime.jsx(SlideSettings, { slide, onSetTransition, onSetBackground, onSetLayout, onSetElementAnimation });
2257
2257
  }
2258
2258
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fs-inspector flex h-full flex-col border-l border-zinc-200 bg-zinc-50 p-4 dark:border-zinc-800 dark:bg-zinc-900", children: [
2259
2259
  /* @__PURE__ */ jsxRuntime.jsx(reactFancy.Heading, { as: "h3", size: "xs", className: "!uppercase !tracking-wider !text-zinc-500", children: "Inspector" }),
@@ -2290,10 +2290,26 @@ function ElementInspector({ element, onPatch, onDelete, onLockToggle, slide, onS
2290
2290
  ] }) })
2291
2291
  ] });
2292
2292
  }
2293
+ var SLIDE_LAYOUTS = [
2294
+ { value: "blank", label: "Blank" },
2295
+ { value: "title", label: "Title" },
2296
+ { value: "title-content", label: "Title + content" },
2297
+ { value: "two-column", label: "Two column" },
2298
+ { value: "section-divider", label: "Section divider" },
2299
+ { value: "image-text", label: "Image + text" },
2300
+ { value: "text-image", label: "Text + image" },
2301
+ { value: "quote", label: "Quote" }
2302
+ ];
2303
+ function backgroundMode(bg) {
2304
+ if (bg?.gradient) return "gradient";
2305
+ if (bg?.image) return "image";
2306
+ return "color";
2307
+ }
2293
2308
  function SlideSettings({
2294
2309
  slide,
2295
2310
  onSetTransition,
2296
2311
  onSetBackground,
2312
+ onSetLayout,
2297
2313
  onSetElementAnimation
2298
2314
  }) {
2299
2315
  const transition = slide.transition;
@@ -2302,6 +2318,7 @@ function SlideSettings({
2302
2318
  const merged = { kind, duration: transition?.duration, direction: transition?.direction, ...next };
2303
2319
  onSetTransition?.(merged.kind === "none" ? { kind: "none" } : merged);
2304
2320
  };
2321
+ const bgMode = backgroundMode(slide.background);
2305
2322
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fs-inspector flex h-full w-full flex-col border-l border-zinc-200 bg-zinc-50 dark:border-zinc-800 dark:bg-zinc-900", children: [
2306
2323
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-between border-b border-zinc-200 px-3 py-2 dark:border-zinc-800", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
2307
2324
  /* @__PURE__ */ jsxRuntime.jsx(reactFancy.Heading, { as: "h3", size: "xs", className: "!font-mono !uppercase !tracking-wider !text-zinc-500", children: "slide" }),
@@ -2311,6 +2328,19 @@ function SlideSettings({
2311
2328
  ] })
2312
2329
  ] }) }),
2313
2330
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto p-3", children: [
2331
+ onSetLayout && /* @__PURE__ */ jsxRuntime.jsx(reactFancy.Card, { padding: "md", className: "mb-3 !bg-white dark:!bg-zinc-950", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
2332
+ /* @__PURE__ */ jsxRuntime.jsx(reactFancy.Heading, { as: "h4", size: "xs", className: "!uppercase !tracking-wider !text-zinc-500", children: "Layout" }),
2333
+ /* @__PURE__ */ jsxRuntime.jsx(
2334
+ reactFancy.Select,
2335
+ {
2336
+ label: "Preset",
2337
+ list: SLIDE_LAYOUTS,
2338
+ value: slide.layout ?? "blank",
2339
+ onValueChange: (v) => onSetLayout(v)
2340
+ }
2341
+ ),
2342
+ /* @__PURE__ */ jsxRuntime.jsx(reactFancy.Text, { size: "xs", className: "!text-zinc-500", children: "The layout hint the deck commits to \u2014 carried through to the pptx export's slide layout." })
2343
+ ] }) }),
2314
2344
  /* @__PURE__ */ jsxRuntime.jsx(reactFancy.Card, { padding: "md", className: "!bg-white dark:!bg-zinc-950", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
2315
2345
  /* @__PURE__ */ jsxRuntime.jsx(reactFancy.Heading, { as: "h4", size: "xs", className: "!uppercase !tracking-wider !text-zinc-500", children: "Transition" }),
2316
2346
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -2354,13 +2384,63 @@ function SlideSettings({
2354
2384
  ] }) }),
2355
2385
  onSetBackground && /* @__PURE__ */ jsxRuntime.jsx(reactFancy.Card, { padding: "md", className: "mt-3 !bg-white dark:!bg-zinc-950", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
2356
2386
  /* @__PURE__ */ jsxRuntime.jsx(reactFancy.Heading, { as: "h4", size: "xs", className: "!uppercase !tracking-wider !text-zinc-500", children: "Background" }),
2357
- /* @__PURE__ */ jsxRuntime.jsx(FieldLabel, { label: "Color", children: /* @__PURE__ */ jsxRuntime.jsx(
2387
+ /* @__PURE__ */ jsxRuntime.jsx(
2388
+ reactFancy.Select,
2389
+ {
2390
+ label: "Type",
2391
+ list: [
2392
+ { value: "color", label: "Solid color" },
2393
+ { value: "gradient", label: "Gradient" },
2394
+ { value: "image", label: "Image" }
2395
+ ],
2396
+ value: bgMode,
2397
+ onValueChange: (v) => {
2398
+ if (v === "color") onSetBackground({ color: slide.background?.color ?? "#ffffff" });
2399
+ else if (v === "gradient") onSetBackground({ gradient: slide.background?.gradient ?? "linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)" });
2400
+ else onSetBackground({ image: slide.background?.image ?? "", imageFit: slide.background?.imageFit ?? "cover", color: slide.background?.color });
2401
+ }
2402
+ }
2403
+ ),
2404
+ bgMode === "color" && /* @__PURE__ */ jsxRuntime.jsx(FieldLabel, { label: "Color", children: /* @__PURE__ */ jsxRuntime.jsx(
2358
2405
  reactFancy.ColorPicker,
2359
2406
  {
2360
2407
  value: slide.background?.color ?? "#ffffff",
2361
- onChange: (c) => onSetBackground({ ...slide.background, color: c })
2408
+ onChange: (c) => onSetBackground({ color: c })
2362
2409
  }
2363
- ) })
2410
+ ) }),
2411
+ bgMode === "gradient" && /* @__PURE__ */ jsxRuntime.jsx(
2412
+ reactFancy.Textarea,
2413
+ {
2414
+ label: "CSS gradient",
2415
+ value: slide.background?.gradient ?? "",
2416
+ onValueChange: (v) => onSetBackground({ gradient: v }),
2417
+ rows: 2
2418
+ }
2419
+ ),
2420
+ bgMode === "image" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2421
+ /* @__PURE__ */ jsxRuntime.jsx(
2422
+ reactFancy.Textarea,
2423
+ {
2424
+ label: "Image URL",
2425
+ value: slide.background?.image ?? "",
2426
+ onValueChange: (v) => onSetBackground({ ...slide.background, image: v }),
2427
+ rows: 2
2428
+ }
2429
+ ),
2430
+ /* @__PURE__ */ jsxRuntime.jsx(
2431
+ reactFancy.Select,
2432
+ {
2433
+ label: "Fit",
2434
+ list: [
2435
+ { value: "cover", label: "Cover" },
2436
+ { value: "contain", label: "Contain" },
2437
+ { value: "fill", label: "Fill (stretch)" }
2438
+ ],
2439
+ value: slide.background?.imageFit ?? "cover",
2440
+ onValueChange: (v) => onSetBackground({ ...slide.background, imageFit: v })
2441
+ }
2442
+ )
2443
+ ] })
2364
2444
  ] }) }),
2365
2445
  onSetElementAnimation && /* @__PURE__ */ jsxRuntime.jsx(reactFancy.Card, { padding: "md", className: "mt-3 !bg-white dark:!bg-zinc-950", children: /* @__PURE__ */ jsxRuntime.jsx(BuildOrderList, { slide, onSetElementAnimation }) })
2366
2446
  ] })
@@ -2601,6 +2681,24 @@ function TextStyleControls({ element, onPatch }) {
2601
2681
  onValueChange: (v) => setStyle({ align: v })
2602
2682
  }
2603
2683
  ),
2684
+ /* @__PURE__ */ jsxRuntime.jsx(
2685
+ reactFancy.Select,
2686
+ {
2687
+ label: "Vertical align",
2688
+ list: [
2689
+ { value: "top", label: "Top" },
2690
+ { value: "middle", label: "Middle" },
2691
+ { value: "bottom", label: "Bottom" }
2692
+ ],
2693
+ value: s.verticalAlign ?? "top",
2694
+ onValueChange: (v) => setStyle({ verticalAlign: v })
2695
+ }
2696
+ ),
2697
+ /* @__PURE__ */ jsxRuntime.jsx(reactFancy.Input, { label: "Line height", type: "number", value: String(s.lineHeight ?? 1.4), onChange: (e) => setStyle({ lineHeight: parseFloat(e.target.value) || 1.4 }) }),
2698
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-4", children: [
2699
+ /* @__PURE__ */ jsxRuntime.jsx(reactFancy.Switch, { label: "Italic", checked: !!s.italic, onCheckedChange: (v) => setStyle({ italic: v }) }),
2700
+ /* @__PURE__ */ jsxRuntime.jsx(reactFancy.Switch, { label: "Underline", checked: !!s.underline, onCheckedChange: (v) => setStyle({ underline: v }) })
2701
+ ] }),
2604
2702
  /* @__PURE__ */ jsxRuntime.jsx(FieldLabel, { label: "Color", children: /* @__PURE__ */ jsxRuntime.jsx(reactFancy.ColorPicker, { value: s.color ?? "#0f172a", onChange: (c) => setStyle({ color: c }) }) })
2605
2703
  ] });
2606
2704
  }
@@ -2683,6 +2781,7 @@ function ShapeStyleControls({ element, onPatch }) {
2683
2781
  /* @__PURE__ */ jsxRuntime.jsx(FieldLabel, { label: "Fill", children: /* @__PURE__ */ jsxRuntime.jsx(reactFancy.ColorPicker, { value: element.fill ?? "#ffffff", onChange: (c) => onPatch({ fill: c }) }) }),
2684
2782
  /* @__PURE__ */ jsxRuntime.jsx(FieldLabel, { label: "Stroke", children: /* @__PURE__ */ jsxRuntime.jsx(reactFancy.ColorPicker, { value: element.stroke ?? "#0f172a", onChange: (c) => onPatch({ stroke: c }) }) }),
2685
2783
  /* @__PURE__ */ jsxRuntime.jsx(reactFancy.Slider, { label: "Stroke width", value: element.strokeWidth ?? 2, onValueChange: (v) => onPatch({ strokeWidth: Number(v) }), min: 0, max: 20, step: 0.5 }),
2784
+ /* @__PURE__ */ jsxRuntime.jsx(reactFancy.Switch, { label: "Dashed stroke", checked: !!element.dashed, onCheckedChange: (v) => onPatch({ dashed: v }) }),
2686
2785
  (element.shape === "rounded-rect" || element.shape === "rect") && /* @__PURE__ */ jsxRuntime.jsx(reactFancy.Slider, { label: "Corner radius", value: element.radius ?? 0, onValueChange: (v) => onPatch({ radius: Number(v) }), min: 0, max: 40 })
2687
2786
  ] });
2688
2787
  }
@@ -2702,7 +2801,8 @@ function CodeStyleControls({ element, onPatch }) {
2702
2801
  value: element.codeTheme ?? "auto",
2703
2802
  onValueChange: (v) => onPatch({ codeTheme: v })
2704
2803
  }
2705
- )
2804
+ ),
2805
+ /* @__PURE__ */ jsxRuntime.jsx(reactFancy.Switch, { label: "Line numbers", checked: element.lineNumbers ?? true, onCheckedChange: (v) => onPatch({ lineNumbers: v }) })
2706
2806
  ] });
2707
2807
  }
2708
2808
  function ChartStyleControls({ element, onPatch }) {
@@ -3209,6 +3309,7 @@ function DeckEditor({
3209
3309
  onLockToggle: (locked) => slide && elementIdSelected && ops.updateElement(slide.id, elementIdSelected, { locked }),
3210
3310
  onSetTransition: (transition) => slide && ops.setTransition(slide.id, transition),
3211
3311
  onSetBackground: (background) => slide && ops.setBackground(slide.id, background),
3312
+ onSetLayout: (layout) => slide && ops.setLayout(slide.id, layout),
3212
3313
  onSetAnimation: (animation) => slide && elementIdSelected && ops.setAnimation(slide.id, elementIdSelected, animation),
3213
3314
  onSetElementAnimation: (eid, animation) => slide && ops.setAnimation(slide.id, eid, animation)
3214
3315
  }