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