@foxglove/embed-react 0.9.0 → 0.11.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.
@@ -1,4 +1,4 @@
1
- import { type DataSource, type OpaqueLayoutData, type SelectLayoutParams } from "@foxglove/embed";
1
+ import { type DataSource, type Keybinding, type OpaqueLayoutData, type SelectLayoutParams } from "@foxglove/embed";
2
2
  type Props = {
3
3
  /** The URL where the Foxglove app is hosted. Defaults to `https://embed.foxglove.dev/`. */
4
4
  src?: string;
@@ -32,6 +32,41 @@ type Props = {
32
32
  style?: React.CSSProperties;
33
33
  /** The class name to apply to the container. */
34
34
  className?: string;
35
+ /**
36
+ * Customize keybinding configuration for the embedded viewer. Allows overriding default
37
+ * keybindings and registering custom keybindings with handlers.
38
+ *
39
+ * Custom keybindings take priority over the viewer's default bindings. If multiple keybindings
40
+ * share the same key + modifiers, the viewer uses the first match and ignores the rest.
41
+ *
42
+ * Provide an empty array to clear any custom keybindings and restore the viewer's default
43
+ * keybindings.
44
+ *
45
+ * Ensure the keybindings are memoized to avoid unnecessary re-renders.
46
+ *
47
+ * @example
48
+ * [
49
+ * // Register a custom keybinding
50
+ * {
51
+ * key: "s",
52
+ * modifiers: ["Control", "Shift"],
53
+ * handler: () => {
54
+ * console.log("Custom keybinding triggered: take-snapshot");
55
+ * },
56
+ * },
57
+ * // Remap "player.togglePlayback" to the P key
58
+ * {
59
+ * key: "p",
60
+ * command: "player.togglePlayback",
61
+ * },
62
+ * // Suppress a built-in keybinding
63
+ * {
64
+ * key: "[",
65
+ * command: "noop",
66
+ * },
67
+ * ]
68
+ */
69
+ keybindings?: Keybinding[];
35
70
  /** A callback function that is called when the Foxglove app is ready. */
36
71
  onReady?: () => void;
37
72
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"FoxgloveViewer.d.ts","sourceRoot":"","sources":["../src/FoxgloveViewer.tsx"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,UAAU,EAEf,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACxB,MAAM,iBAAiB,CAAC;AAIzB,KAAK,KAAK,GAAG;IACX,2FAA2F;IAC3F,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wDAAwD;IACxD,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB;;;;OAIG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,6CAA6C;IAC7C,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B;;;;OAIG;IACH,UAAU,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAClC;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IACxC,2CAA2C;IAC3C,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;;SAGK;IACL,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC,CAAC;AAEF,MAAM,WAAW,uBAAuB;IACtC;;;;;OAKG;IACH,SAAS,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACxC;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,2GA8H1B,CAAC"}
1
+ {"version":3,"file":"FoxgloveViewer.d.ts","sourceRoot":"","sources":["../src/FoxgloveViewer.tsx"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,UAAU,EAEf,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACxB,MAAM,iBAAiB,CAAC;AAIzB,KAAK,KAAK,GAAG;IACX,2FAA2F;IAC3F,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wDAAwD;IACxD,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB;;;;OAIG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,6CAA6C;IAC7C,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B;;;;OAIG;IACH,UAAU,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAClC;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IACxC,2CAA2C;IAC3C,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;;SAGK;IACL,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC,CAAC;AAEF,MAAM,WAAW,uBAAuB;IACtC;;;;;OAKG;IACH,SAAS,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACxC;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,2GAsJ1B,CAAC"}
@@ -9,7 +9,7 @@ import { useShouldNotChangeOften } from "./useShouldNotChangeOften.js";
9
9
  * convenient API for embedding the Foxglove app in a React application.
10
10
  */
11
11
  export const FoxgloveViewer = forwardRef(function FoxgloveViewer(props, ref) {
12
- const { src, orgSlug, className, style, data, layoutData, layout, extensions, colorScheme } = props;
12
+ const { src, orgSlug, className, style, data, layoutData, layout, extensions, colorScheme, keybindings, } = props;
13
13
  // eslint-disable-next-line no-restricted-syntax
14
14
  const elem = useRef(null);
15
15
  const frame = useRef();
@@ -28,6 +28,9 @@ export const FoxgloveViewer = forwardRef(function FoxgloveViewer(props, ref) {
28
28
  useShouldNotChangeOften(extensions, () => {
29
29
  console.warn(`[FoxgloveViewer] "extensions" is changing too frequently. This may cause performance issues, consider memoizing this value.`);
30
30
  });
31
+ useShouldNotChangeOften(keybindings, () => {
32
+ console.warn(`[FoxgloveViewer] "keybindings" is changing too frequently. This may cause performance issues, consider memoizing this value.`);
33
+ });
31
34
  // Update onReady and onError refs when the props change.
32
35
  useEffect(() => {
33
36
  onReady.current = props.onReady;
@@ -90,6 +93,12 @@ export const FoxgloveViewer = forwardRef(function FoxgloveViewer(props, ref) {
90
93
  }
91
94
  frame.current.setColorScheme(colorScheme);
92
95
  }, [colorScheme]);
96
+ useEffect(() => {
97
+ if (frame.current == undefined) {
98
+ return;
99
+ }
100
+ frame.current.setKeybindings(keybindings ?? []);
101
+ }, [keybindings]);
93
102
  useImperativeHandle(ref, () => ({
94
103
  async getLayout() {
95
104
  return await frame.current?.getLayout();
@@ -1 +1 @@
1
- {"version":3,"file":"FoxgloveViewer.js","sourceRoot":"","sources":["../src/FoxgloveViewer.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FoxgloveViewer.js","sourceRoot":"","sources":["../src/FoxgloveViewer.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@foxglove/embed-react",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "author": {
@@ -31,7 +31,7 @@
31
31
  "prepack": "yarn build"
32
32
  },
33
33
  "dependencies": {
34
- "@foxglove/embed": "0.9.0"
34
+ "@foxglove/embed": "0.11.0"
35
35
  },
36
36
  "peerDependencies": {
37
37
  "react": ">=18",
@@ -4,6 +4,7 @@ import { forwardRef, useEffect, useImperativeHandle, useRef } from "react";
4
4
  import {
5
5
  type DataSource,
6
6
  FoxgloveViewer as FoxgloveViewerClass,
7
+ type Keybinding,
7
8
  type OpaqueLayoutData,
8
9
  type SelectLayoutParams,
9
10
  } from "@foxglove/embed";
@@ -43,6 +44,41 @@ type Props = {
43
44
  style?: React.CSSProperties;
44
45
  /** The class name to apply to the container. */
45
46
  className?: string;
47
+ /**
48
+ * Customize keybinding configuration for the embedded viewer. Allows overriding default
49
+ * keybindings and registering custom keybindings with handlers.
50
+ *
51
+ * Custom keybindings take priority over the viewer's default bindings. If multiple keybindings
52
+ * share the same key + modifiers, the viewer uses the first match and ignores the rest.
53
+ *
54
+ * Provide an empty array to clear any custom keybindings and restore the viewer's default
55
+ * keybindings.
56
+ *
57
+ * Ensure the keybindings are memoized to avoid unnecessary re-renders.
58
+ *
59
+ * @example
60
+ * [
61
+ * // Register a custom keybinding
62
+ * {
63
+ * key: "s",
64
+ * modifiers: ["Control", "Shift"],
65
+ * handler: () => {
66
+ * console.log("Custom keybinding triggered: take-snapshot");
67
+ * },
68
+ * },
69
+ * // Remap "player.togglePlayback" to the P key
70
+ * {
71
+ * key: "p",
72
+ * command: "player.togglePlayback",
73
+ * },
74
+ * // Suppress a built-in keybinding
75
+ * {
76
+ * key: "[",
77
+ * command: "noop",
78
+ * },
79
+ * ]
80
+ */
81
+ keybindings?: Keybinding[];
46
82
  /** A callback function that is called when the Foxglove app is ready. */
47
83
  onReady?: () => void;
48
84
  /**
@@ -70,8 +106,18 @@ export interface FoxgloveViewerInterface {
70
106
  */
71
107
  export const FoxgloveViewer = forwardRef<FoxgloveViewerInterface, Props>(
72
108
  function FoxgloveViewer(props, ref): ReactNode {
73
- const { src, orgSlug, className, style, data, layoutData, layout, extensions, colorScheme } =
74
- props;
109
+ const {
110
+ src,
111
+ orgSlug,
112
+ className,
113
+ style,
114
+ data,
115
+ layoutData,
116
+ layout,
117
+ extensions,
118
+ colorScheme,
119
+ keybindings,
120
+ } = props;
75
121
 
76
122
  // eslint-disable-next-line no-restricted-syntax
77
123
  const elem = useRef<HTMLIFrameElement | null>(null);
@@ -105,6 +151,12 @@ export const FoxgloveViewer = forwardRef<FoxgloveViewerInterface, Props>(
105
151
  );
106
152
  });
107
153
 
154
+ useShouldNotChangeOften(keybindings, () => {
155
+ console.warn(
156
+ `[FoxgloveViewer] "keybindings" is changing too frequently. This may cause performance issues, consider memoizing this value.`,
157
+ );
158
+ });
159
+
108
160
  // Update onReady and onError refs when the props change.
109
161
  useEffect(() => {
110
162
  onReady.current = props.onReady;
@@ -182,6 +234,14 @@ export const FoxgloveViewer = forwardRef<FoxgloveViewerInterface, Props>(
182
234
  frame.current.setColorScheme(colorScheme);
183
235
  }, [colorScheme]);
184
236
 
237
+ useEffect(() => {
238
+ if (frame.current == undefined) {
239
+ return;
240
+ }
241
+
242
+ frame.current.setKeybindings(keybindings ?? []);
243
+ }, [keybindings]);
244
+
185
245
  useImperativeHandle(
186
246
  ref,
187
247
  (): FoxgloveViewerInterface => ({