@gpichot/spectacle-deck 1.11.0 → 1.12.1

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.
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Registers keyboard shortcuts for presentation remote controllers:
3
+ * - PageDown / PageUp: next / previous (standard step-by-step navigation)
4
+ * - VolumeUp / VolumeDown: next / previous slide (skipping steps)
5
+ */
6
+ export declare function RemoteControllerShortcut(): any;
package/index.cjs CHANGED
@@ -62,9 +62,9 @@ __export(src_exports, {
62
62
  noneTransition: () => noneTransition,
63
63
  resolveTransition: () => resolveTransition
64
64
  });
65
- var import_react17 = require("@mdx-js/react");
66
- var import_react18 = __toESM(require("react"));
67
- var import_spectacle12 = require("spectacle");
65
+ var import_react18 = require("@mdx-js/react");
66
+ var import_react19 = __toESM(require("react"));
67
+ var import_spectacle13 = require("spectacle");
68
68
  var import_styled_components20 = require("styled-components");
69
69
 
70
70
  // src/colors.ts
@@ -1613,16 +1613,61 @@ var layouts_default = {
1613
1613
  twoColumn: TwoColumnLayout
1614
1614
  };
1615
1615
 
1616
- // src/SkipStepsShortcut.tsx
1616
+ // src/RemoteControllerShortcut.tsx
1617
1617
  var import_react9 = require("react");
1618
1618
  var import_spectacle6 = require("spectacle");
1619
- function SkipStepsShortcut() {
1619
+ function RemoteControllerShortcut() {
1620
1620
  const {
1621
1621
  skipTo,
1622
+ stepForward,
1623
+ stepBackward,
1622
1624
  activeView: { slideIndex },
1623
1625
  slideCount
1624
1626
  } = (0, import_react9.useContext)(import_spectacle6.DeckContext);
1625
1627
  (0, import_spectacle6.useMousetrap)(
1628
+ {
1629
+ pageup: () => {
1630
+ stepForward();
1631
+ },
1632
+ pagedown: () => {
1633
+ stepBackward();
1634
+ }
1635
+ },
1636
+ [stepForward, stepBackward]
1637
+ );
1638
+ (0, import_react9.useEffect)(() => {
1639
+ function handleKeyDown(e) {
1640
+ if (e.key === "AudioVolumeUp") {
1641
+ e.preventDefault();
1642
+ if (slideIndex < slideCount - 1) {
1643
+ skipTo({ slideIndex: slideIndex + 1, stepIndex: 0 });
1644
+ }
1645
+ } else if (e.key === "AudioVolumeDown") {
1646
+ e.preventDefault();
1647
+ if (slideIndex > 0) {
1648
+ skipTo({
1649
+ slideIndex: slideIndex - 1,
1650
+ stepIndex: null
1651
+ });
1652
+ }
1653
+ }
1654
+ }
1655
+ document.addEventListener("keydown", handleKeyDown);
1656
+ return () => document.removeEventListener("keydown", handleKeyDown);
1657
+ }, [slideIndex, slideCount, skipTo]);
1658
+ return null;
1659
+ }
1660
+
1661
+ // src/SkipStepsShortcut.tsx
1662
+ var import_react10 = require("react");
1663
+ var import_spectacle7 = require("spectacle");
1664
+ function SkipStepsShortcut() {
1665
+ const {
1666
+ skipTo,
1667
+ activeView: { slideIndex },
1668
+ slideCount
1669
+ } = (0, import_react10.useContext)(import_spectacle7.DeckContext);
1670
+ (0, import_spectacle7.useMousetrap)(
1626
1671
  {
1627
1672
  "shift+right": () => {
1628
1673
  if (slideIndex < slideCount - 1) {
@@ -1664,7 +1709,7 @@ function SlideWrapper({
1664
1709
  }
1665
1710
 
1666
1711
  // src/template.tsx
1667
- var import_spectacle7 = require("spectacle");
1712
+ var import_spectacle8 = require("spectacle");
1668
1713
  var import_jsx_runtime20 = require("react/jsx-runtime");
1669
1714
  var template = ({
1670
1715
  slideNumber,
@@ -1672,7 +1717,7 @@ var template = ({
1672
1717
  }) => {
1673
1718
  const percentage = slideNumber / numberOfSlides * 100;
1674
1719
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { position: "absolute", bottom: 0, left: 0, right: 0 }, children: [
1675
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_spectacle7.Box, { padding: "0 0 0.5em 0.7em", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_spectacle7.FullScreen, {}) }),
1720
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_spectacle8.Box, { padding: "0 0 0.5em 0.7em", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_spectacle8.FullScreen, {}) }),
1676
1721
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { width: "100%", height: "4px", background: "#ffffff11" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1677
1722
  "div",
1678
1723
  {
@@ -1716,7 +1761,7 @@ var theme_default = {
1716
1761
  };
1717
1762
 
1718
1763
  // src/transitions.ts
1719
- var import_spectacle8 = require("spectacle");
1764
+ var import_spectacle9 = require("spectacle");
1720
1765
  var dropTransition = {
1721
1766
  from: { transform: "translateY(-100%)", opacity: 0 },
1722
1767
  enter: { transform: "translateY(0%)", opacity: 1 },
@@ -1728,8 +1773,8 @@ var noneTransition = {
1728
1773
  leave: { opacity: 0 }
1729
1774
  };
1730
1775
  var transitionMap = {
1731
- fade: import_spectacle8.fadeTransition,
1732
- slide: import_spectacle8.slideTransition,
1776
+ fade: import_spectacle9.fadeTransition,
1777
+ slide: import_spectacle9.slideTransition,
1733
1778
  drop: dropTransition,
1734
1779
  none: noneTransition
1735
1780
  };
@@ -1745,11 +1790,11 @@ __reExport(src_exports, require("spectacle"));
1745
1790
  var import_web = require("@react-spring/web");
1746
1791
 
1747
1792
  // src/components/animations/useInView.ts
1748
- var import_react10 = __toESM(require("react"));
1793
+ var import_react11 = __toESM(require("react"));
1749
1794
  function useInView() {
1750
- const ref = import_react10.default.useRef(null);
1751
- const [isInView, setIsInView] = import_react10.default.useState(false);
1752
- import_react10.default.useEffect(() => {
1795
+ const ref = import_react11.default.useRef(null);
1796
+ const [isInView, setIsInView] = import_react11.default.useState(false);
1797
+ import_react11.default.useEffect(() => {
1753
1798
  const el = ref.current;
1754
1799
  if (!el) return;
1755
1800
  const observer = new IntersectionObserver(
@@ -1947,7 +1992,7 @@ function Spotlight({
1947
1992
 
1948
1993
  // src/components/animations/StaggerChildren.tsx
1949
1994
  var import_web5 = require("@react-spring/web");
1950
- var import_react11 = __toESM(require("react"));
1995
+ var import_react12 = __toESM(require("react"));
1951
1996
  var import_jsx_runtime26 = require("react/jsx-runtime");
1952
1997
  function StaggerChildren({
1953
1998
  children,
@@ -1958,7 +2003,7 @@ function StaggerChildren({
1958
2003
  distance = 20
1959
2004
  }) {
1960
2005
  const [ref, isInView] = useInView();
1961
- const items = import_react11.default.Children.toArray(children);
2006
+ const items = import_react12.default.Children.toArray(children);
1962
2007
  const translateMap = {
1963
2008
  up: `translateY(${distance}px)`,
1964
2009
  down: `translateY(-${distance}px)`,
@@ -1979,14 +2024,14 @@ function StaggerChildren({
1979
2024
  }
1980
2025
 
1981
2026
  // src/components/animations/TypeWriter.tsx
1982
- var import_react12 = __toESM(require("react"));
2027
+ var import_react13 = __toESM(require("react"));
1983
2028
  var import_jsx_runtime27 = require("react/jsx-runtime");
1984
2029
  function extractText(node) {
1985
2030
  if (typeof node === "string") return node;
1986
2031
  if (typeof node === "number") return String(node);
1987
2032
  if (!node) return "";
1988
2033
  if (Array.isArray(node)) return node.map(extractText).join("");
1989
- if (import_react12.default.isValidElement(node)) {
2034
+ if (import_react13.default.isValidElement(node)) {
1990
2035
  const props = node.props;
1991
2036
  return extractText(props.children);
1992
2037
  }
@@ -2000,9 +2045,9 @@ function TypeWriter({
2000
2045
  }) {
2001
2046
  const text = extractText(children);
2002
2047
  const [ref, isInView] = useInView();
2003
- const [displayed, setDisplayed] = import_react12.default.useState("");
2004
- const [done, setDone] = import_react12.default.useState(false);
2005
- import_react12.default.useEffect(() => {
2048
+ const [displayed, setDisplayed] = import_react13.default.useState("");
2049
+ const [done, setDone] = import_react13.default.useState(false);
2050
+ import_react13.default.useEffect(() => {
2006
2051
  if (!isInView) return;
2007
2052
  let index = 0;
2008
2053
  setDisplayed("");
@@ -2101,7 +2146,7 @@ function DocItem({ label, link }) {
2101
2146
  }
2102
2147
 
2103
2148
  // src/components/FilePane.tsx
2104
- var import_react13 = __toESM(require("react"));
2149
+ var import_react14 = __toESM(require("react"));
2105
2150
  var import_jsx_runtime29 = require("react/jsx-runtime");
2106
2151
  function FilePane({
2107
2152
  name,
@@ -2110,7 +2155,7 @@ function FilePane({
2110
2155
  minWidth,
2111
2156
  ...divProps
2112
2157
  }) {
2113
- const content = import_react13.default.isValidElement(children) ? import_react13.default.cloneElement(children, {
2158
+ const content = import_react14.default.isValidElement(children) ? import_react14.default.cloneElement(children, {
2114
2159
  // @ts-expect-error cloning
2115
2160
  priority,
2116
2161
  name
@@ -2124,8 +2169,8 @@ FilePane.mdxType = "FilePane";
2124
2169
 
2125
2170
  // src/components/HorizontalList.tsx
2126
2171
  var import_web6 = require("@react-spring/web");
2127
- var import_react14 = __toESM(require("react"));
2128
- var import_spectacle9 = require("spectacle");
2172
+ var import_react15 = __toESM(require("react"));
2173
+ var import_spectacle10 = require("spectacle");
2129
2174
  var import_styled_components15 = __toESM(require("styled-components"));
2130
2175
  var import_jsx_runtime30 = require("react/jsx-runtime");
2131
2176
  var Container = import_styled_components15.default.div`
@@ -2136,18 +2181,18 @@ function HorizontalList({
2136
2181
  children,
2137
2182
  columns = 3
2138
2183
  }) {
2139
- const items = import_react14.default.Children.toArray(children);
2140
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_spectacle9.Stepper, { values: items, children: (_, step) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
2184
+ const items = import_react15.default.Children.toArray(children);
2185
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_spectacle10.Stepper, { values: items, children: (_, step) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
2141
2186
  Container,
2142
2187
  {
2143
2188
  style: {
2144
2189
  gridTemplateColumns: `repeat(${columns}, 1fr)`
2145
2190
  },
2146
2191
  children: items.map((item, k) => {
2147
- if (!import_react14.default.isValidElement(item)) {
2192
+ if (!import_react15.default.isValidElement(item)) {
2148
2193
  return item;
2149
2194
  }
2150
- return import_react14.default.cloneElement(item, {
2195
+ return import_react15.default.cloneElement(item, {
2151
2196
  // @ts-expect-error cloning
2152
2197
  position: k + 1,
2153
2198
  isVisible: k <= step,
@@ -2285,14 +2330,14 @@ function IconBox({
2285
2330
 
2286
2331
  // src/components/ItemsColumn.tsx
2287
2332
  var import_web7 = require("@react-spring/web");
2288
- var import_react15 = __toESM(require("react"));
2289
- var import_spectacle10 = require("spectacle");
2333
+ var import_react16 = __toESM(require("react"));
2334
+ var import_spectacle11 = require("spectacle");
2290
2335
  var import_styled_components17 = __toESM(require("styled-components"));
2291
2336
  var import_jsx_runtime32 = require("react/jsx-runtime");
2292
2337
  function ItemsColumn(divProps) {
2293
2338
  const { style: style2, children, ...props } = divProps;
2294
- const childrenArray = import_react15.default.Children.toArray(children);
2295
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_spectacle10.Stepper, { values: childrenArray, children: (_value, step) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2339
+ const childrenArray = import_react16.default.Children.toArray(children);
2340
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_spectacle11.Stepper, { values: childrenArray, children: (_value, step) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2296
2341
  "div",
2297
2342
  {
2298
2343
  style: {
@@ -2307,7 +2352,7 @@ function ItemsColumn(divProps) {
2307
2352
  ...props,
2308
2353
  children: childrenArray.map((child, index) => {
2309
2354
  const isVisible = index <= step;
2310
- if (!import_react15.default.isValidElement(child)) {
2355
+ if (!import_react16.default.isValidElement(child)) {
2311
2356
  return child;
2312
2357
  }
2313
2358
  return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ItemColumnWrapper, { isVisible, children: child }, index);
@@ -2333,8 +2378,8 @@ function ItemColumnWrapper({
2333
2378
 
2334
2379
  // src/components/Timeline.tsx
2335
2380
  var import_web8 = require("@react-spring/web");
2336
- var import_react16 = __toESM(require("react"));
2337
- var import_spectacle11 = require("spectacle");
2381
+ var import_react17 = __toESM(require("react"));
2382
+ var import_spectacle12 = require("spectacle");
2338
2383
  var import_styled_components19 = __toESM(require("styled-components"));
2339
2384
 
2340
2385
  // src/components/Timeline.styled.tsx
@@ -2408,13 +2453,13 @@ var style = {
2408
2453
  };
2409
2454
  function Timeline(props) {
2410
2455
  const { activeIndex, ...rest } = props;
2411
- const children = import_react16.default.Children.toArray(rest.children);
2456
+ const children = import_react17.default.Children.toArray(rest.children);
2412
2457
  if (activeIndex != null) {
2413
2458
  return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { ...rest, style: { ...style, ...rest.style }, children: children.map((child, index) => {
2414
- if (!import_react16.default.isValidElement(child)) {
2459
+ if (!import_react17.default.isValidElement(child)) {
2415
2460
  return child;
2416
2461
  }
2417
- return import_react16.default.cloneElement(child, {
2462
+ return import_react17.default.cloneElement(child, {
2418
2463
  // @ts-expect-error cloning
2419
2464
  isPhantom: activeIndex < index,
2420
2465
  isLast: activeIndex === index
@@ -2422,7 +2467,7 @@ function Timeline(props) {
2422
2467
  }) });
2423
2468
  }
2424
2469
  return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
2425
- import_spectacle11.Stepper,
2470
+ import_spectacle12.Stepper,
2426
2471
  {
2427
2472
  ...rest,
2428
2473
  values: children,
@@ -2430,10 +2475,10 @@ function Timeline(props) {
2430
2475
  inactiveStyle: style,
2431
2476
  children: (_value, step) => {
2432
2477
  return children.map((child, index) => {
2433
- if (!import_react16.default.isValidElement(child)) {
2478
+ if (!import_react17.default.isValidElement(child)) {
2434
2479
  return child;
2435
2480
  }
2436
- return import_react16.default.cloneElement(child, {
2481
+ return import_react17.default.cloneElement(child, {
2437
2482
  // @ts-expect-error cloning
2438
2483
  isPhantom: step < index,
2439
2484
  isLast: step === index
@@ -2529,10 +2574,10 @@ function Deck({
2529
2574
  layouts: layouts2 = layouts_default,
2530
2575
  transition
2531
2576
  }) {
2532
- import_react18.default.useEffect(() => {
2577
+ import_react19.default.useEffect(() => {
2533
2578
  document.title = deck.metadata.title || "Untitled";
2534
2579
  }, [deck.metadata.title]);
2535
- const mergedTheme = import_react18.default.useMemo(() => {
2580
+ const mergedTheme = import_react19.default.useMemo(() => {
2536
2581
  const fonts = {
2537
2582
  ...theme_default.fonts,
2538
2583
  ...theme.themeTokens.fonts ?? {}
@@ -2543,7 +2588,7 @@ function Deck({
2543
2588
  fonts
2544
2589
  };
2545
2590
  }, [theme]);
2546
- const GlobalStyle = import_react18.default.useMemo(() => {
2591
+ const GlobalStyle = import_react19.default.useMemo(() => {
2547
2592
  const cssVariables = createCssVariables(theme.themeTokens.colors);
2548
2593
  return import_styled_components20.createGlobalStyle`
2549
2594
  :root {
@@ -2552,22 +2597,23 @@ function Deck({
2552
2597
  }
2553
2598
  `;
2554
2599
  }, [theme, mergedTheme]);
2555
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react18.default.StrictMode, { children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(PestacleProvider, { layouts: layouts2, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_react17.MDXProvider, { components: componentsMap2, children: [
2600
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react19.default.StrictMode, { children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(PestacleProvider, { layouts: layouts2, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_react18.MDXProvider, { components: componentsMap2, children: [
2556
2601
  /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(GlobalStyle, {}),
2557
2602
  /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
2558
- import_spectacle12.Deck,
2603
+ import_spectacle13.Deck,
2559
2604
  {
2560
2605
  theme: mergedTheme,
2561
2606
  template,
2562
2607
  transition: resolveTransition(transition),
2563
2608
  children: [
2564
2609
  /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(SkipStepsShortcut, {}),
2610
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(RemoteControllerShortcut, {}),
2565
2611
  deck.slides.map((slide, i) => {
2566
2612
  var _a;
2567
2613
  const Component = slide.slideComponent;
2568
2614
  const slideTransitionName = (_a = slide.metadata) == null ? void 0 : _a.transition;
2569
2615
  const slideTransition2 = resolveTransition(slideTransitionName);
2570
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_spectacle12.Slide, { transition: slideTransition2, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Component, {}) }, i);
2616
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_spectacle13.Slide, { transition: slideTransition2, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Component, {}) }, i);
2571
2617
  })
2572
2618
  ]
2573
2619
  }
package/index.mjs CHANGED
@@ -1554,16 +1554,61 @@ var layouts_default = {
1554
1554
  twoColumn: TwoColumnLayout
1555
1555
  };
1556
1556
 
1557
- // src/SkipStepsShortcut.tsx
1558
- import { useContext as useContext2 } from "react";
1557
+ // src/RemoteControllerShortcut.tsx
1558
+ import { useContext as useContext2, useEffect } from "react";
1559
1559
  import { DeckContext as DeckContext2, useMousetrap } from "spectacle";
1560
- function SkipStepsShortcut() {
1560
+ function RemoteControllerShortcut() {
1561
1561
  const {
1562
1562
  skipTo,
1563
+ stepForward,
1564
+ stepBackward,
1563
1565
  activeView: { slideIndex },
1564
1566
  slideCount
1565
1567
  } = useContext2(DeckContext2);
1566
1568
  useMousetrap(
1569
+ {
1570
+ pageup: () => {
1571
+ stepForward();
1572
+ },
1573
+ pagedown: () => {
1574
+ stepBackward();
1575
+ }
1576
+ },
1577
+ [stepForward, stepBackward]
1578
+ );
1579
+ useEffect(() => {
1580
+ function handleKeyDown(e) {
1581
+ if (e.key === "AudioVolumeUp") {
1582
+ e.preventDefault();
1583
+ if (slideIndex < slideCount - 1) {
1584
+ skipTo({ slideIndex: slideIndex + 1, stepIndex: 0 });
1585
+ }
1586
+ } else if (e.key === "AudioVolumeDown") {
1587
+ e.preventDefault();
1588
+ if (slideIndex > 0) {
1589
+ skipTo({
1590
+ slideIndex: slideIndex - 1,
1591
+ stepIndex: null
1592
+ });
1593
+ }
1594
+ }
1595
+ }
1596
+ document.addEventListener("keydown", handleKeyDown);
1597
+ return () => document.removeEventListener("keydown", handleKeyDown);
1598
+ }, [slideIndex, slideCount, skipTo]);
1599
+ return null;
1600
+ }
1601
+
1602
+ // src/SkipStepsShortcut.tsx
1603
+ import { useContext as useContext3 } from "react";
1604
+ import { DeckContext as DeckContext3, useMousetrap as useMousetrap2 } from "spectacle";
1605
+ function SkipStepsShortcut() {
1606
+ const {
1607
+ skipTo,
1608
+ activeView: { slideIndex },
1609
+ slideCount
1610
+ } = useContext3(DeckContext3);
1611
+ useMousetrap2(
1567
1612
  {
1568
1613
  "shift+right": () => {
1569
1614
  if (slideIndex < slideCount - 1) {
@@ -2506,6 +2551,7 @@ function Deck({
2506
2551
  transition: resolveTransition(transition),
2507
2552
  children: [
2508
2553
  /* @__PURE__ */ jsx34(SkipStepsShortcut, {}),
2554
+ /* @__PURE__ */ jsx34(RemoteControllerShortcut, {}),
2509
2555
  deck.slides.map((slide, i) => {
2510
2556
  var _a;
2511
2557
  const Component = slide.slideComponent;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gpichot/spectacle-deck",
3
- "version": "1.11.0",
3
+ "version": "1.12.1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "index.cjs",