diff --git a/desktop/app/src/createTablePlugin.tsx b/desktop/app/src/createTablePlugin.tsx
index ebe2f0a5f..261ebacbb 100644
--- a/desktop/app/src/createTablePlugin.tsx
+++ b/desktop/app/src/createTablePlugin.tsx
@@ -15,7 +15,7 @@ import {
} from './ui';
import FlexColumn from './ui/components/FlexColumn';
import Button from './ui/components/Button';
-import DetailSidebar from './chrome/DetailSidebar';
+import {DetailSidebar} from 'flipper-plugin';
import {FlipperPlugin} from './plugin';
import SearchableTable_immutable from './ui/components/searchable/SearchableTable_immutable';
import textContent from './utils/textContent';
diff --git a/desktop/app/src/index.tsx b/desktop/app/src/index.tsx
index 102c97b8f..68a12dfa6 100644
--- a/desktop/app/src/index.tsx
+++ b/desktop/app/src/index.tsx
@@ -49,7 +49,7 @@ export {shouldParseAndroidLog} from './utils/crashReporterUtility';
export {deconstructClientId} from './utils/clientUtils';
export {default as isProduction} from './utils/isProduction';
export {createTablePlugin} from './createTablePlugin';
-export {default as DetailSidebar} from './chrome/DetailSidebar';
+export {DetailSidebar} from 'flipper-plugin';
export {default as Device} from './devices/BaseDevice';
export {default as AndroidDevice} from './devices/AndroidDevice';
export {default as MetroDevice} from './devices/MetroDevice';
diff --git a/desktop/app/src/plugins/TableNativePlugin.tsx b/desktop/app/src/plugins/TableNativePlugin.tsx
index 546b56a78..adec16687 100644
--- a/desktop/app/src/plugins/TableNativePlugin.tsx
+++ b/desktop/app/src/plugins/TableNativePlugin.tsx
@@ -27,7 +27,7 @@ import {
TableColumnOrderVal,
TableBodyRow,
} from '../ui/components/table/types';
-import DetailSidebar from '../chrome/DetailSidebar';
+import {DetailSidebar} from 'flipper-plugin';
import {FlipperPlugin} from '../plugin';
import textContent from '../utils/textContent';
import createPaste from '../fb-stubs/createPaste';
diff --git a/desktop/app/src/sandy-chrome/DesignComponentDemos.tsx b/desktop/app/src/sandy-chrome/DesignComponentDemos.tsx
index 468a9a157..17f2203c4 100644
--- a/desktop/app/src/sandy-chrome/DesignComponentDemos.tsx
+++ b/desktop/app/src/sandy-chrome/DesignComponentDemos.tsx
@@ -213,7 +213,7 @@ const demos: PreviewProps[] = [
{
title: 'Layout.Top|Left|Right|Bottom',
description:
- "Divides all available space over two children. The (top|left|right|bottom)-most first child will keep it's own dimensions, and positioned (top|left|right|bottom) of the other child. All remaining space will be assigned to the remaining child.",
+ "Divides all available space over two children. The (top|left|right|bottom)-most first child will keep it's own dimensions, and positioned (top|left|right|bottom) of the other child. All remaining space will be assigned to the remaining child. If you are using a Layout.Right at the top level of your plugin, consider using DetailSidebar component instead, which will move its children to the right sidebar of Flipper.",
props: [
[
'scrollable',
diff --git a/desktop/app/src/chrome/DetailSidebar.tsx b/desktop/app/src/sandy-chrome/DetailSidebarImpl.tsx
similarity index 94%
rename from desktop/app/src/chrome/DetailSidebar.tsx
rename to desktop/app/src/sandy-chrome/DetailSidebarImpl.tsx
index 131f472fe..f78a2446c 100644
--- a/desktop/app/src/chrome/DetailSidebar.tsx
+++ b/desktop/app/src/sandy-chrome/DetailSidebarImpl.tsx
@@ -14,14 +14,18 @@ import {useDispatch, useStore} from '../utils/useStore';
import {ContentContainer} from '../sandy-chrome/ContentContainer';
import {Layout, _Sidebar} from 'flipper-plugin';
-type OwnProps = {
+export type DetailSidebarProps = {
children: any;
width?: number;
minWidth?: number;
};
/* eslint-disable react-hooks/rules-of-hooks */
-export default function DetailSidebar({children, width, minWidth}: OwnProps) {
+export function DetailSidebarImpl({
+ children,
+ width,
+ minWidth,
+}: DetailSidebarProps) {
const [domNode, setDomNode] = useState(
document.getElementById('detailsSidebar'),
);
diff --git a/desktop/app/src/utils/flipperLibImplementation.tsx b/desktop/app/src/utils/flipperLibImplementation.tsx
index 22d1882c1..670ecef88 100644
--- a/desktop/app/src/utils/flipperLibImplementation.tsx
+++ b/desktop/app/src/utils/flipperLibImplementation.tsx
@@ -17,6 +17,7 @@ import {clipboard} from 'electron';
import constants from '../fb-stubs/constants';
import {addNotification} from '../reducers/notifications';
import {deconstructPluginKey} from './clientUtils';
+import {DetailSidebarImpl} from '../sandy-chrome/DetailSidebarImpl';
export function initializeFlipperLibImplementation(
store: Store,
@@ -83,5 +84,6 @@ export function initializeFlipperLibImplementation(
}),
);
},
+ DetailsSidebarImplementation: DetailSidebarImpl,
});
}
diff --git a/desktop/flipper-plugin/src/__tests__/api.node.tsx b/desktop/flipper-plugin/src/__tests__/api.node.tsx
index 42771f7f3..9d4fa8cae 100644
--- a/desktop/flipper-plugin/src/__tests__/api.node.tsx
+++ b/desktop/flipper-plugin/src/__tests__/api.node.tsx
@@ -31,6 +31,7 @@ test('Correct top level API exposed', () => {
"DataFormatter",
"DataSource",
"DataTable",
+ "DetailSidebar",
"Layout",
"NUX",
"TestUtils",
diff --git a/desktop/flipper-plugin/src/index.ts b/desktop/flipper-plugin/src/index.ts
index e29b2f894..1fb97e2b2 100644
--- a/desktop/flipper-plugin/src/index.ts
+++ b/desktop/flipper-plugin/src/index.ts
@@ -56,6 +56,7 @@ export {
createNuxManager as _createNuxManager,
} from './ui/NUX';
export {Sidebar as _Sidebar} from './ui/Sidebar';
+export {DetailSidebar} from './ui/DetailSidebar';
export {renderReactRoot} from './utils/renderReactRoot';
export {
diff --git a/desktop/flipper-plugin/src/plugin/FlipperLib.tsx b/desktop/flipper-plugin/src/plugin/FlipperLib.tsx
index 647762727..c8b41d755 100644
--- a/desktop/flipper-plugin/src/plugin/FlipperLib.tsx
+++ b/desktop/flipper-plugin/src/plugin/FlipperLib.tsx
@@ -12,6 +12,7 @@ import {RealFlipperDevice} from './DevicePlugin';
import {NormalizedMenuEntry} from './MenuEntry';
import {RealFlipperClient} from './Plugin';
import {Notification} from './Notification';
+import {DetailSidebarProps} from '../ui/DetailSidebar';
/**
* This interface exposes all global methods for which an implementation will be provided by Flipper itself
@@ -35,6 +36,9 @@ export interface FlipperLib {
): void;
writeTextToClipboard(text: string): void;
showNotification(pluginKey: string, notification: Notification): void;
+ DetailsSidebarImplementation?(
+ props: DetailSidebarProps,
+ ): React.ReactElement | null;
}
let flipperLibInstance: FlipperLib | undefined;
diff --git a/desktop/flipper-plugin/src/ui/DetailSidebar.tsx b/desktop/flipper-plugin/src/ui/DetailSidebar.tsx
new file mode 100644
index 000000000..6bb9dcb82
--- /dev/null
+++ b/desktop/flipper-plugin/src/ui/DetailSidebar.tsx
@@ -0,0 +1,27 @@
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ * @format
+ */
+
+import React from 'react';
+import {tryGetFlipperLibImplementation} from '../plugin/FlipperLib';
+import {Layout} from './Layout';
+
+export type DetailSidebarProps = {
+ children: any;
+ width?: number;
+ minWidth?: number;
+};
+
+/* eslint-disable react-hooks/rules-of-hooks */
+export function DetailSidebar(props: DetailSidebarProps) {
+ const lib = tryGetFlipperLibImplementation();
+ if (lib?.DetailsSidebarImplementation) {
+ return ;
+ }
+ return {props.children};
+}
diff --git a/docs/extending/flipper-plugin.mdx b/docs/extending/flipper-plugin.mdx
index 936e53800..a9dee8869 100644
--- a/docs/extending/flipper-plugin.mdx
+++ b/docs/extending/flipper-plugin.mdx
@@ -789,6 +789,13 @@ Coming soon.
An element that can be used to provide a New User eXperience: Hints that give a one time introduction to new features to the current user.
See `View > Flipper Style Guide` inside the Flipper application for more details.
+### DetailSidebar
+
+An element that can be passed children which will be shown in the right sidebar of Flipper.
+Horizontal scrolling will be enabled by default.
+To fine-tune the default dimensions use `width` and `minWidth`.
+It doesn't really matter where exactly this component is used in your layout, as the contents will be moved to the main Flipper chrome, rather than being rendered in place.
+
### Tracked