pptx-vanilla-viewer 0.3.0 → 0.5.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
@@ -1,4 +1,4 @@
1
- import { n, o, m, P, a, e, f, X, p, q, r, s, t, u, v, w, x, y, z, A, B, D, E, F, G, H, J, K, L, i, j, l, k, g, h, a0 } from './presentation-BfnrtJV1.js';
1
+ import { n, o, m, P, a, e, f, X, p, q, r, s, t, u, v, w, x, y, z, A, B, D, E, F, G, H, J, K, L, i, j, l, k, g, h, a0, ca } from './presentation-BfnrtJV1.js';
2
2
  export { a as PptxElement, P as PptxSlide } from './presentation-BfnrtJV1.js';
3
3
  import { ViewerTheme } from './theme/index.js';
4
4
  export { ViewerTheme, ViewerThemeColors, defaultCssVars, defaultRadius, defaultThemeColors, themeToCssVars, vermilionDarkTheme, vermilionLightTheme } from './theme/index.js';
@@ -1431,6 +1431,42 @@ interface CollaborationConfig {
1431
1431
  /** A neutral CSS map (framework `CSSProperties` are structurally compatible). */
1432
1432
  type CssStyleMap = Record<string, string | number>;
1433
1433
 
1434
+ /**
1435
+ * `animation-authoring` — pure, immutable helpers for the editor's element
1436
+ * animation authoring UI (the Animations ribbon tab / animation panel).
1437
+ *
1438
+ * Animation data lives on the SLIDE (`PptxSlide.animations`), keyed by
1439
+ * `elementId`, NOT on the element itself. The authoring UI reads and emits the
1440
+ * entire slide-level `animations` array. Every function here returns a new
1441
+ * `PptxElementAnimation[]` without mutating its input, so they're trivially
1442
+ * unit-testable and safe to drive editor undo/redo from.
1443
+ *
1444
+ * Two families coexist here, both used across the bindings:
1445
+ *
1446
+ * - **Granular field setters** (`setAnimationEntrance` / `setTrigger` /
1447
+ * `setDuration` / … plus `reorderAnimationUp` / `removeAnimation`): the
1448
+ * Angular authoring panel + React's `useAnimationHandlers` model. They
1449
+ * upsert a single field on the element's entry, creating the entry with
1450
+ * sensible defaults when absent and removing it when all three effect
1451
+ * buckets become empty.
1452
+ * - **Group preset apply/remove** (`applyAnimationPreset` /
1453
+ * `removeElementAnimation`): the Vue ribbon model, a coarser
1454
+ * "set one of entrance/emphasis/exit, keep the rest" upsert.
1455
+ *
1456
+ * The option *catalogs* here are intentionally **value-only** (preset id +
1457
+ * nothing else): the human label / icon / i18n key for each option is
1458
+ * framework-specific (React uses `react-icons` + label keys, Angular uses
1459
+ * Unicode arrow glyphs + plain labels), so each binding maps these ids to its
1460
+ * own display metadata.
1461
+ *
1462
+ * Pure: imports only `pptx-viewer-core` types; no framework, no DOM.
1463
+ *
1464
+ * @module render/animation-authoring
1465
+ */
1466
+
1467
+ /** One of the three animation buckets a preset can occupy on an element. */
1468
+ type AnimationGroup = 'entrance' | 'emphasis' | 'exit';
1469
+
1434
1470
  /**
1435
1471
  * Pure geometry helpers for the align / distribute editor operations.
1436
1472
  *
@@ -1484,6 +1520,81 @@ type ChangeCaseMode = 'sentence' | 'lower' | 'upper' | 'capitalize' | 'toggle';
1484
1520
 
1485
1521
  /** Connection lifecycle states for the Yjs WebSocket provider. */
1486
1522
  type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'error';
1523
+ /** A single remote collaborator's cursor, in unscaled slide coordinates. */
1524
+ interface RemoteCursor {
1525
+ /** Stable id for the remote client (awareness clientId or peer id). */
1526
+ clientId: number | string;
1527
+ /** Display name shown in the label chip. */
1528
+ userName: string;
1529
+ /** Cursor + chip colour (any CSS colour string). */
1530
+ color: string;
1531
+ /** Unscaled slide-space X coordinate (px). */
1532
+ x: number;
1533
+ /** Unscaled slide-space Y coordinate (px). */
1534
+ y: number;
1535
+ /** Optional ids of elements this user has selected. */
1536
+ selectionIds?: string[];
1537
+ }
1538
+ /**
1539
+ * Presence data for a remote collaborator, sanitised from the awareness
1540
+ * protocol. Returned by {@link sanitizePresence}; coordinates are in unscaled
1541
+ * slide pixels, clamped to the supplied canvas bounds.
1542
+ */
1543
+ interface SanitizedPresence {
1544
+ clientId: number;
1545
+ userName: string;
1546
+ userAvatar?: string;
1547
+ userColor: string;
1548
+ activeSlideIndex: number;
1549
+ cursorX: number;
1550
+ cursorY: number;
1551
+ lastUpdated: string;
1552
+ selectedElementId?: string;
1553
+ role?: CollaborationRole;
1554
+ }
1555
+
1556
+ /**
1557
+ * Pure, framework-agnostic helpers for freehand ink drawing, shared by every
1558
+ * binding. No framework imports, so these can be unit-tested without TestBed.
1559
+ */
1560
+
1561
+ /** A 2D point in stage-local coordinates. */
1562
+ interface InkPoint {
1563
+ x: number;
1564
+ y: number;
1565
+ }
1566
+ /** Options for {@link strokeToInkElement}. */
1567
+ interface StrokeToInkElementOpts {
1568
+ points: InkPoint[];
1569
+ color: string;
1570
+ width: number;
1571
+ tool: 'pen' | 'highlighter' | 'freeform';
1572
+ }
1573
+
1574
+ /**
1575
+ * Pure helpers for the gradient picker editor control, shared by every binding.
1576
+ *
1577
+ * Readers extract current gradient values from a PptxElement (falling back to
1578
+ * sensible defaults), and patch-builders produce shallow-merge-ready
1579
+ * `Partial<PptxElement>` objects safe to pass to each binding's element-update
1580
+ * action.
1581
+ *
1582
+ * No framework imports; every type is concrete or `unknown` + narrowed.
1583
+ */
1584
+
1585
+ /** A single gradient stop, mirroring the ShapeStyle array item shape. */
1586
+ interface GradientStop {
1587
+ color: string;
1588
+ position: number;
1589
+ opacity?: number;
1590
+ }
1591
+ /** The editable gradient state surfaced to the component. */
1592
+ interface GradientState {
1593
+ type: 'linear' | 'radial';
1594
+ /** Angle in degrees (only meaningful for linear). */
1595
+ angle: number;
1596
+ stops: GradientStop[];
1597
+ }
1487
1598
  /** In-memory clipboard payload stored when an element is copied or cut. */
1488
1599
  interface ElementClipboardPayload {
1489
1600
  element: a;
@@ -1579,6 +1690,13 @@ interface Store<T extends object> {
1579
1690
 
1580
1691
  /** `zoom` is either an explicit scale factor (1 = 100%) or fit-to-viewport. */
1581
1692
  type ZoomLevel = number | 'fit';
1693
+ /**
1694
+ * The Draw ribbon tab's active tool. `'select'` means normal editing gestures
1695
+ * (move/resize/rotate/inline-edit) apply on the stage; every other value
1696
+ * routes stage pointer events to the ink-drawing gesture controller instead
1697
+ * (see `editor-draw-gestures.ts`).
1698
+ */
1699
+ type DrawTool = 'select' | 'pen' | 'highlighter' | 'eraser';
1582
1700
  /**
1583
1701
  * The vanilla viewer's reactive view state. Kept intentionally flat and small;
1584
1702
  * everything here is what the DOM render layer consumes.
@@ -1616,8 +1734,38 @@ interface ViewerState {
1616
1734
  * navigation for the life of the viewer instance (in-memory only).
1617
1735
  */
1618
1736
  notesExpanded: boolean;
1737
+ /** Remote collaborators currently in the session (empty when not collaborating). */
1738
+ remotePresences: SanitizedPresence[];
1739
+ /** Remote cursors visible on the current slide, projected from `remotePresences`. */
1740
+ cursors: RemoteCursor[];
1741
+ /** Client id of the peer the local user is following, or null when free. */
1742
+ followedClientId: number | null;
1619
1743
  /** In-memory clipboard payload from the last copy/cut, or null. */
1620
1744
  clipboardPayload: ElementClipboardPayload | null;
1745
+ /** Active Draw ribbon tool; `'select'` disables the ink-drawing gesture controller. */
1746
+ drawTool: DrawTool;
1747
+ /** Stroke colour for the pen/highlighter tools. */
1748
+ drawColor: string;
1749
+ /** Stroke width (px) for the pen/highlighter tools. */
1750
+ drawWidth: number;
1751
+ }
1752
+
1753
+ /**
1754
+ * Element-animation actions for the ribbon's Animations tab.
1755
+ *
1756
+ * Animation data lives on the SLIDE (`PptxSlide.animations`, keyed by
1757
+ * `elementId`), not on the element itself, matching how the presentation
1758
+ * playback state machine reads it (`buildClickGroups(slide.animations)` in
1759
+ * `animation/presentation-playback.ts`). Both actions target the currently
1760
+ * selected element and route through the shared `animation-authoring.ts`
1761
+ * "coarse group preset" model (`applyAnimationPreset` / `removeElementAnimation`),
1762
+ * the same one the Vue ribbon uses: applying a preset sets one of
1763
+ * entrance/emphasis/exit without touching the others; remove drops the whole
1764
+ * entry.
1765
+ */
1766
+ interface AnimationActions {
1767
+ addAnimation(group: AnimationGroup, preset: g): void;
1768
+ removeAnimation(): void;
1621
1769
  }
1622
1770
 
1623
1771
  /**
@@ -1651,6 +1799,18 @@ interface ArrangeActions {
1651
1799
  ungroupSelected(): void;
1652
1800
  }
1653
1801
 
1802
+ /**
1803
+ * Slide-background actions for the ribbon's Design > Format Background panel.
1804
+ * Solid-colour fill only (matches the docked panel's scope: a single colour
1805
+ * input); clearing removes every background field so the slide falls back to
1806
+ * its layout/master background. Both mutations are history-integrated,
1807
+ * mirroring `editor-slide-actions.ts`.
1808
+ */
1809
+ interface SlideBackgroundActions {
1810
+ setSlideBackgroundColor(color: string): void;
1811
+ clearSlideBackground(): void;
1812
+ }
1813
+
1654
1814
  /**
1655
1815
  * Cut/copy/paste actions for the ribbon's Home > Clipboard group, backed by
1656
1816
  * the shared `element-clipboard.ts` codec. The in-memory clipboard payload
@@ -1663,6 +1823,32 @@ interface ClipboardActions {
1663
1823
  paste(): void;
1664
1824
  }
1665
1825
 
1826
+ /**
1827
+ * Ink stroke actions for the Draw ribbon tab: commit a freehand pen/
1828
+ * highlighter stroke as a new `InkPptxElement`, or erase an existing one.
1829
+ * Both mutations are history-integrated (push -> mutate -> commit), mirroring
1830
+ * `editor-background-actions.ts` and the `insertElement` helper in
1831
+ * `editor-edit-ops.ts`. The pointer-event lifecycle that accumulates a
1832
+ * stroke's points lives separately in `editor-draw-gestures.ts`; this module
1833
+ * only owns the resulting slide/history mutation.
1834
+ */
1835
+ interface InkActions {
1836
+ /**
1837
+ * Build an `InkPptxElement` from a completed stroke (via the shared
1838
+ * `strokeToInkElement`) and append it to the current slide, selected.
1839
+ * A no-op when not editable, there is no current slide, or the stroke has
1840
+ * fewer than 2 points (shared helper returns `null`, matching a plain tap).
1841
+ */
1842
+ commitStroke(stroke: StrokeToInkElementOpts): void;
1843
+ /**
1844
+ * Remove the ink element with `id` from the current slide (Draw tab's
1845
+ * eraser tool). Returns `true` when an ink element was found and removed;
1846
+ * `false` for a missing id, a non-ink element, or a read-only viewer (safe
1847
+ * to call from a generic stage hit-test without a pre-check).
1848
+ */
1849
+ eraseInkElement(id: string): boolean;
1850
+ }
1851
+
1666
1852
  /**
1667
1853
  * Insert-element factories for the vanilla editor.
1668
1854
  *
@@ -1676,6 +1862,36 @@ interface ClipboardActions {
1676
1862
  /** The element kinds the Insert ribbon tab can create directly. */
1677
1863
  type InsertKind = 'text' | 'table' | 'shape';
1678
1864
 
1865
+ /**
1866
+ * Element-type-aware inspector actions: text vertical-align/wrap/autofit,
1867
+ * gradient fill + fill/stroke opacity, image brightness/contrast/saturation +
1868
+ * crop, and table-level header-row/banded-rows/cell-padding. Every method is a
1869
+ * thin `applyToSelected` wrapper around pure builders from `pptx-viewer-shared`
1870
+ * (or the local `patchShapeStyle`), mirroring `editor-text-actions.ts`.
1871
+ *
1872
+ * These extend the base position/size/rotation + flat fill/stroke inspector
1873
+ * that `editor-edit-ops.ts` already exposes; see `ui/inspector/` for the
1874
+ * per-element-type panels that call these.
1875
+ */
1876
+ interface InspectorActions {
1877
+ setTextVerticalAlign(vAlign: NonNullable<a0['vAlign']>): void;
1878
+ setTextWrap(wrap: NonNullable<a0['textWrap']>): void;
1879
+ setAutoFitMode(mode: NonNullable<a0['autoFitMode']>): void;
1880
+ setFillOpacity(opacity: number): void;
1881
+ setStrokeOpacity(opacity: number): void;
1882
+ setGradientFill(state: GradientState): void;
1883
+ addGradientStop(color: string, position: number): void;
1884
+ removeGradientStop(index: number): void;
1885
+ updateGradientStop(index: number, changes: Partial<GradientState['stops'][number]>): void;
1886
+ setImageBrightness(value: number): void;
1887
+ setImageContrast(value: number): void;
1888
+ setImageSaturation(value: number): void;
1889
+ setImageCrop(edge: 'left' | 'top' | 'right' | 'bottom', value: number): void;
1890
+ setTableHeaderRow(enabled: boolean): void;
1891
+ setTableBandedRows(enabled: boolean): void;
1892
+ setTableCellPadding(padding: number): void;
1893
+ }
1894
+
1679
1895
  /**
1680
1896
  * New/duplicate/delete-slide actions for the ribbon's Home > Slides group,
1681
1897
  * backed by the shared `slide-operations.ts` factory. Every mutation is
@@ -1718,6 +1934,23 @@ interface TextActions {
1718
1934
  setLineSpacing(value: number): void;
1719
1935
  }
1720
1936
 
1937
+ /**
1938
+ * Slide-transition actions for the ribbon's Transitions tab. Playback already
1939
+ * reads `PptxSlide.transition` (see `animation/presentation-playback.ts`), so
1940
+ * this only needs to write that same field, history-integrated like every
1941
+ * other ribbon mutation.
1942
+ *
1943
+ * `applyTransition` covers both the preset gallery buttons and the duration
1944
+ * input (the tab re-applies the currently-selected preset whenever the
1945
+ * duration changes), plus the "Apply to All Slides" checkbox: when
1946
+ * `applyToAll` is true every slide gets the same fresh `{ type, durationMs }`
1947
+ * transition; otherwise only the current slide is patched, preserving any
1948
+ * advanced fields (direction, sound, ...) it already carried.
1949
+ */
1950
+ interface TransitionActions {
1951
+ applyTransition(type: k, durationMs: number, applyToAll: boolean): void;
1952
+ }
1953
+
1721
1954
  /** A geometry patch from the inspector (all fields optional). */
1722
1955
  interface GeometryPatch {
1723
1956
  x?: number;
@@ -1735,7 +1968,7 @@ interface GeometryPatch {
1735
1968
  * directly here. Every mutating action is history-integrated (push -> mutate
1736
1969
  * -> commit) via the shared {@link EditorOps}.
1737
1970
  */
1738
- interface EditActions extends TextActions, ArrangeActions, ClipboardActions, SlideActions {
1971
+ interface EditActions extends TextActions, ArrangeActions, ClipboardActions, SlideActions, SlideBackgroundActions, TransitionActions, AnimationActions, InspectorActions, InkActions {
1739
1972
  setShapeFill(color: string): void;
1740
1973
  setShapeStroke(color: string): void;
1741
1974
  setShapeStrokeWidth(width: number): void;
@@ -1743,6 +1976,12 @@ interface EditActions extends TextActions, ArrangeActions, ClipboardActions, Sli
1743
1976
  setGeometry(patch: GeometryPatch): void;
1744
1977
  insert(kind: InsertKind, shapeType?: ShapePresetType): void;
1745
1978
  insertImage(): Promise<void>;
1979
+ insertMedia(): Promise<void>;
1980
+ insertChart(chartType: l): void;
1981
+ insertSmartArt(layout: ca, defaultItems: string[]): void;
1982
+ insertEquation(omml: Record<string, unknown>): void;
1983
+ insertActionButton(shapeType: string): void;
1984
+ insertField(fieldType: string, value?: string): void;
1746
1985
  duplicateSelected(): void;
1747
1986
  deleteSelected(): void;
1748
1987
  }
@@ -1788,10 +2027,13 @@ type TranslationMessages = Record<string, Record<string, string>>;
1788
2027
  */
1789
2028
  declare function createTranslator(locale?: string, messages?: TranslationMessages): Translator;
1790
2029
 
1791
- /** Selection-derived state the inspector reflects. */
2030
+ /** Selection-derived state the inspector reflects, computed by `buildInspectorState`. */
1792
2031
  interface InspectorState {
1793
2032
  hasSelection: boolean;
1794
2033
  canShape: boolean;
2034
+ canText: boolean;
2035
+ isImage: boolean;
2036
+ isTable: boolean;
1795
2037
  x: number;
1796
2038
  y: number;
1797
2039
  width: number;
@@ -1800,6 +2042,23 @@ interface InspectorState {
1800
2042
  fillColor: string | undefined;
1801
2043
  strokeColor: string | undefined;
1802
2044
  strokeWidth: number;
2045
+ fillOpacity: number;
2046
+ strokeOpacity: number;
2047
+ gradientEnabled: boolean;
2048
+ gradient: GradientState;
2049
+ vAlign: 'top' | 'middle' | 'bottom';
2050
+ textWrap: 'square' | 'none';
2051
+ autoFitMode: 'shrink' | 'normal' | 'none';
2052
+ imageBrightness: number;
2053
+ imageContrast: number;
2054
+ imageSaturation: number;
2055
+ cropLeft: number;
2056
+ cropTop: number;
2057
+ cropRight: number;
2058
+ cropBottom: number;
2059
+ tableHeaderRow: boolean;
2060
+ tableBandedRows: boolean;
2061
+ tableCellPadding: number;
1803
2062
  }
1804
2063
  interface Inspector {
1805
2064
  el: HTMLElement;
@@ -1824,6 +2083,12 @@ interface NotesPanel {
1824
2083
  setExpanded(expanded: boolean): void;
1825
2084
  }
1826
2085
 
2086
+ /** Draw tab state to reflect (current tool/colour/width). */
2087
+ interface RibbonDrawState {
2088
+ tool: DrawTool;
2089
+ color: string;
2090
+ width: number;
2091
+ }
1827
2092
  /** Nav-row state (prev/next/counter/zoom label). */
1828
2093
  interface RibbonNavState {
1829
2094
  current: number;
@@ -1852,6 +2117,8 @@ interface Ribbon {
1852
2117
  setEditable(editable: boolean): void;
1853
2118
  /** Reflect the current selection across the Home tab's Font/Paragraph/Arrange groups. */
1854
2119
  updateSelection(selectedElement: a | undefined, extra: RibbonSelectionState): void;
2120
+ /** Reflect the current Draw tab tool/colour/width (store-driven). */
2121
+ setDrawState(state: RibbonDrawState): void;
1855
2122
  }
1856
2123
 
1857
2124
  interface ThumbnailRail {
@@ -1914,6 +2181,12 @@ interface EditorController {
1914
2181
  deleteSelected(): void;
1915
2182
  duplicateSelected(): string | null;
1916
2183
  getSelectedElementId(): string | null;
2184
+ /** Switch the Draw ribbon tab's active tool (also clears selection when leaving `'select'`). */
2185
+ setDrawTool(tool: DrawTool): void;
2186
+ /** Set the pen/highlighter stroke colour used by the next committed stroke. */
2187
+ setDrawColor(color: string): void;
2188
+ /** Set the pen/highlighter stroke width used by the next committed stroke. */
2189
+ setDrawWidth(width: number): void;
1917
2190
  /** The formatting / insert / arrange actions for the editing chrome. */
1918
2191
  getEditActions(): EditActions;
1919
2192
  /** The Find & Replace actions for the ribbon's docked panel. */
@@ -2151,6 +2424,21 @@ interface RenderController {
2151
2424
  */
2152
2425
  type AutosaveStatus = 'idle' | 'saving' | 'saved' | 'error';
2153
2426
 
2427
+ /**
2428
+ * share-helpers.ts: pure (framework-free) helpers for the Share dialog.
2429
+ *
2430
+ * Mirrors the Vue `ShareDialog.vue` / Angular `share-helpers.ts` form
2431
+ * validation and config-assembly logic (see `useCollaborationWiring.onShareStart`
2432
+ * for the `role: 'collaborator'` config this produces). No DOM here so it is
2433
+ * trivially unit-testable; the DOM builder lives in `ui/share-dialog.ts`.
2434
+ */
2435
+ /** Prefilled values for the Share form fields. */
2436
+ interface ShareDefaults {
2437
+ roomId?: string;
2438
+ userName?: string;
2439
+ serverUrl?: string;
2440
+ }
2441
+
2154
2442
  /** Per-slide progress callback: `(currentSlideIndex, totalSlides)`. */
2155
2443
  type ExportProgress = (current: number, total: number) => void;
2156
2444
 
@@ -2376,6 +2664,13 @@ interface PptxViewerOptions extends PptxViewerCallbacks {
2376
2664
  * slide array, so a joiner's host-provided media can degrade.
2377
2665
  */
2378
2666
  collaboration?: CollaborationConfig;
2667
+ /**
2668
+ * Prefilled values for the built-in Share/Broadcast dialogs' form fields
2669
+ * (e.g. a host-generated display name), mirroring the Vue binding's
2670
+ * `shareDefaults` prop. The broadcast dialog uses `userName` as the
2671
+ * presenter's display name.
2672
+ */
2673
+ shareDefaults?: ShareDefaults;
2379
2674
  }
2380
2675
  /** The viewer handle returned by `createPptxViewer`. */
2381
2676
  interface PptxViewerInstance {
@@ -2500,6 +2795,9 @@ interface ChromeHost {
2500
2795
  commitNotes(notes: string): void;
2501
2796
  getEditActions(): EditActions;
2502
2797
  getFindReplaceActions(): FindReplaceActions;
2798
+ setDrawTool(tool: DrawTool): void;
2799
+ setDrawColor(color: string): void;
2800
+ setDrawWidth(width: number): void;
2503
2801
  };
2504
2802
  prev(): void;
2505
2803
  next(): void;
@@ -2519,6 +2817,7 @@ interface ChromeHost {
2519
2817
  exportGif(): Promise<void>;
2520
2818
  exportVideo(): Promise<void>;
2521
2819
  print(): Promise<boolean>;
2820
+ setTheme(theme: ViewerTheme | undefined): void;
2522
2821
  }
2523
2822
 
2524
2823
  /** The export slice of the public viewer API (see `PptxViewerInstance`). */