@agent-native/core 0.137.1 → 0.137.2

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.
Files changed (34) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/slides/app/components/editor/AddSlidePopover.tsx +258 -0
  3. package/corpus/templates/slides/app/components/editor/EditorActionCluster.tsx +130 -0
  4. package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +25 -337
  5. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +73 -53
  6. package/corpus/templates/slides/app/components/editor/SlideContextToolbar.tsx +804 -0
  7. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +101 -45
  8. package/corpus/templates/slides/app/components/editor/SlideOverflowWarning.tsx +7 -4
  9. package/corpus/templates/slides/app/components/editor/bullet-editing.ts +11 -3
  10. package/corpus/templates/slides/app/components/editor/commit-active-edit.ts +21 -0
  11. package/corpus/templates/slides/app/components/editor/list-editing.ts +219 -0
  12. package/corpus/templates/slides/app/components/editor/selection-overlay-measurement.ts +0 -3
  13. package/corpus/templates/slides/app/components/editor/slide-style.ts +199 -0
  14. package/corpus/templates/slides/app/global.css +14 -3
  15. package/corpus/templates/slides/app/i18n/en-US.ts +8 -1
  16. package/corpus/templates/slides/app/pages/DeckEditor.tsx +48 -22
  17. package/corpus/templates/slides/changelog/2026-08-01-add-slide-moved-to-the-toolbar-and-the-slide-rail-is-now-mor.md +9 -0
  18. package/corpus/templates/slides/changelog/2026-08-01-add-slide-undo-redo-and-the-text-tool-now-lead-the-slide-too.md +9 -0
  19. package/corpus/templates/slides/changelog/2026-08-01-slide-styling-now-appears-in-a-contextual-toolbar-above-the-.md +6 -0
  20. package/corpus/templates/slides/changelog/2026-08-01-the-slide-style-side-panel-is-retired-all-styling-now-lives-.md +6 -0
  21. package/corpus/templates/slides/changelog/2026-08-03-the-slide-toolbar-is-denser-swatch-only-colors-dropdowns-for.md +10 -0
  22. package/corpus/templates/slides/changelog/2026-08-04-bullet-and-numbered-list-buttons-in-the-slide-toolbar-conver.md +6 -0
  23. package/corpus/templates/slides/changelog/2026-08-04-italic-and-underline-are-now-one-click-away-in-the-slide-too.md +6 -0
  24. package/dist/collab/awareness.d.ts +2 -2
  25. package/dist/collab/struct-routes.d.ts +1 -1
  26. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  27. package/dist/observability/routes.d.ts +3 -3
  28. package/dist/progress/routes.d.ts +1 -1
  29. package/dist/resources/handlers.d.ts +1 -1
  30. package/dist/secrets/routes.d.ts +3 -3
  31. package/dist/server/realtime-token.d.ts +1 -1
  32. package/dist/server/transcribe-voice.d.ts +1 -1
  33. package/package.json +2 -2
  34. package/corpus/templates/slides/app/components/editor/SlideStyleInspector.tsx +0 -763
@@ -27,14 +27,14 @@ import {
27
27
  IconAdjustments,
28
28
  IconPencilPlus,
29
29
  IconPin,
30
- IconLetterT,
31
30
  IconTool,
32
31
  IconDownload,
33
32
  IconSun,
34
33
  IconMoon,
35
34
  IconDotsVertical,
36
- IconPalette,
37
35
  IconLoader2,
36
+ IconArrowBackUp,
37
+ IconArrowForwardUp,
38
38
  } from "@tabler/icons-react";
39
39
  import { useTheme } from "next-themes";
40
40
  import { useState, useRef, useEffect } from "react";
@@ -57,7 +57,11 @@ import {
57
57
  } from "@/components/ui/tooltip";
58
58
  import { SaveStatusIndicator } from "@/components/visual-editor";
59
59
  import type { Deck, Slide, SlideLayout } from "@/context/DeckContext";
60
- import { defaultSlideContent, useSaveState } from "@/context/DeckContext";
60
+ import {
61
+ defaultSlideContent,
62
+ useDecks,
63
+ useSaveState,
64
+ } from "@/context/DeckContext";
61
65
  import {
62
66
  ASPECT_RATIO_VALUES,
63
67
  type AspectRatio,
@@ -65,7 +69,10 @@ import {
65
69
  } from "@/lib/aspect-ratios";
66
70
  import type { GoogleSlidesExportResult } from "@/lib/export-google-slides-client";
67
71
  import { parseUploadResponse } from "@/lib/upload-response";
72
+ import { shortcutLabel } from "@/lib/utils";
68
73
 
74
+ import { commitActiveEditThenRun } from "./commit-active-edit";
75
+ import { EditorActionCluster } from "./EditorActionCluster";
69
76
  import { ExportMenu } from "./ExportMenu";
70
77
  interface EditorToolbarProps {
71
78
  deck: Deck;
@@ -99,10 +106,6 @@ interface EditorToolbarProps {
99
106
  commentsOpen?: boolean;
100
107
  /** Toggle the comments panel */
101
108
  onToggleComments?: () => void;
102
- /** Whether the style panel is open */
103
- styleOpen?: boolean;
104
- /** Toggle the style panel */
105
- onToggleStyle?: () => void;
106
109
  /** Number of unresolved comments on the current slide */
107
110
  unresolvedCommentCount?: number;
108
111
  /** Current user email for avatar display */
@@ -139,6 +142,16 @@ interface EditorToolbarProps {
139
142
  aspectRatio?: AspectRatio;
140
143
  /** Change the deck's aspect ratio */
141
144
  onSetAspectRatio?: (ratio: AspectRatio) => void;
145
+ /** Insert a blank slide after the current one */
146
+ onAddEmptySlide?: () => void;
147
+ /** Duplicate the current slide */
148
+ onDuplicateCurrentSlide?: () => void;
149
+ /** Id of the current slide, so an agent add-slide lands in the right place */
150
+ currentSlideId?: string;
151
+ /** True while an agent add-slide request is in flight */
152
+ addSlideGenerating?: boolean;
153
+ /** Called when an agent add-slide request is submitted */
154
+ onAddSlideGeneratingChange?: (generating: boolean) => void;
142
155
  }
143
156
 
144
157
  const slideLayoutOptions: { value: SlideLayout; labelKey: string }[] = [
@@ -249,8 +262,6 @@ export default function EditorToolbar({
249
262
  agentActive,
250
263
  commentsOpen,
251
264
  onToggleComments,
252
- styleOpen,
253
- onToggleStyle,
254
265
  unresolvedCommentCount = 0,
255
266
  currentUserEmail,
256
267
  animationsOpen,
@@ -269,6 +280,11 @@ export default function EditorToolbar({
269
280
  onExportGoogleSlides,
270
281
  aspectRatio,
271
282
  onSetAspectRatio,
283
+ onAddEmptySlide,
284
+ onDuplicateCurrentSlide,
285
+ currentSlideId,
286
+ addSlideGenerating = false,
287
+ onAddSlideGeneratingChange,
272
288
  canEdit = true,
273
289
  }: EditorToolbarProps) {
274
290
  const t = useT();
@@ -317,6 +333,11 @@ export default function EditorToolbar({
317
333
  setLayoutOpen(false);
318
334
  };
319
335
  const [toolsOpen, setToolsOpen] = useState(false);
336
+ // The contextual toolbar hosts the action cluster whenever it is on screen.
337
+ // That row rides on SlideEditor, which only mounts for a real slide, so an
338
+ // empty deck must keep this fallback or it has no way to add one.
339
+ const contextToolbarVisible = canEdit && Boolean(currentSlide);
340
+ const { undo, redo, canUndo, canRedo } = useDecks();
320
341
  const fileInputRef = useRef<HTMLInputElement>(null);
321
342
  const [importing, setImporting] = useState(false);
322
343
  const { setTheme, resolvedTheme } = useTheme();
@@ -442,6 +463,26 @@ export default function EditorToolbar({
442
463
  <TooltipContent>{t("editorToolbar.toggleSlideList")}</TooltipContent>
443
464
  </Tooltip>
444
465
 
466
+ {/* Add slide and the text-box tool live at the head of the contextual
467
+ * toolbar below. That row is desktop-only and needs a slide to mount on,
468
+ * so keep a fallback here for narrow screens and empty decks. */}
469
+ {canEdit && (
470
+ <EditorActionCluster
471
+ className={contextToolbarVisible ? "lg:hidden" : undefined}
472
+ deckId={deckId}
473
+ deckTitle={deckTitle}
474
+ currentSlideId={currentSlideId}
475
+ slideCount={slideCount}
476
+ currentSlideIndex={currentSlideIndex}
477
+ addSlideGenerating={addSlideGenerating}
478
+ onAddSlideGeneratingChange={onAddSlideGeneratingChange}
479
+ onAddEmptySlide={onAddEmptySlide}
480
+ onDuplicateCurrentSlide={onDuplicateCurrentSlide}
481
+ textBoxMode={textBoxMode}
482
+ onToggleTextBoxMode={onToggleTextBoxMode}
483
+ />
484
+ )}
485
+
445
486
  {/* Deck title */}
446
487
  <input
447
488
  type="text"
@@ -745,29 +786,6 @@ graph TD
745
786
  </>
746
787
  )}
747
788
 
748
- {canEdit && onToggleTextBoxMode && (
749
- <Tooltip>
750
- <TooltipTrigger asChild>
751
- <button
752
- type="button"
753
- onClick={onToggleTextBoxMode}
754
- data-toolbar-textbox-button
755
- aria-label={t("editorToolbar.addTextBox")}
756
- aria-pressed={textBoxMode}
757
- aria-keyshortcuts="T"
758
- className={`${TOOLBAR_ICON_BUTTON_CLASS} ${
759
- textBoxMode
760
- ? "bg-accent text-foreground"
761
- : "text-muted-foreground hover:bg-accent hover:text-foreground/70"
762
- }`}
763
- >
764
- <IconLetterT className="size-4" />
765
- </button>
766
- </TooltipTrigger>
767
- <TooltipContent>{t("editorToolbar.addTextBox")} (T)</TooltipContent>
768
- </Tooltip>
769
- )}
770
-
771
789
  {/* Slide tools palette — animations, tweaks, draw, comment-pin all live
772
790
  * inside one popover so the toolbar doesn't drown in icons. Hidden in
773
791
  * view-only mode since none of these affordances apply. */}
@@ -879,27 +897,6 @@ graph TD
879
897
  className="flex-shrink-0 mr-0.5"
880
898
  />
881
899
 
882
- {/* Style toggle */}
883
- {canEdit && currentSlide && onToggleStyle && (
884
- <Tooltip>
885
- <TooltipTrigger asChild>
886
- <button
887
- onClick={onToggleStyle}
888
- data-slide-style-trigger="true"
889
- className={`${TOOLBAR_ICON_BUTTON_CLASS} relative ${
890
- styleOpen
891
- ? "bg-accent text-foreground"
892
- : "text-muted-foreground hover:bg-accent hover:text-foreground/70"
893
- }`}
894
- aria-label={t("styleInspector.title")}
895
- >
896
- <IconPalette className="size-4" />
897
- </button>
898
- </TooltipTrigger>
899
- <TooltipContent>{t("styleInspector.title")}</TooltipContent>
900
- </Tooltip>
901
- )}
902
-
903
900
  {/* Comments toggle */}
904
901
  {onToggleComments && (
905
902
  <Tooltip>
@@ -1008,6 +1005,29 @@ graph TD
1008
1005
  <TooltipContent>{t("editorToolbar.more")}</TooltipContent>
1009
1006
  </Tooltip>
1010
1007
  <DropdownMenuContent align="end" className="w-48">
1008
+ {canEdit && (
1009
+ <>
1010
+ <DropdownMenuItem
1011
+ disabled={!canUndo}
1012
+ onSelect={() => commitActiveEditThenRun(undo)}
1013
+ >
1014
+ <IconArrowBackUp className="w-4 h-4 mr-2" />
1015
+ {t("editorToolbar.undoWithShortcut", {
1016
+ shortcut: shortcutLabel("Cmd+Z"),
1017
+ })}
1018
+ </DropdownMenuItem>
1019
+ <DropdownMenuItem
1020
+ disabled={!canRedo}
1021
+ onSelect={() => commitActiveEditThenRun(redo)}
1022
+ >
1023
+ <IconArrowForwardUp className="w-4 h-4 mr-2" />
1024
+ {t("editorToolbar.redoWithShortcut", {
1025
+ shortcut: shortcutLabel("Cmd+Shift+Z"),
1026
+ })}
1027
+ </DropdownMenuItem>
1028
+ <DropdownMenuSeparator />
1029
+ </>
1030
+ )}
1011
1031
  <DropdownMenuItem
1012
1032
  disabled={importing}
1013
1033
  onSelect={() => fileInputRef.current?.click()}