diff --git a/packages/leaflet/src/components/MapContainer.js b/packages/leaflet/src/components/MapContainer.js
new file mode 100644
index 00000000..9c22740c
--- /dev/null
+++ b/packages/leaflet/src/components/MapContainer.js
@@ -0,0 +1,6 @@
+import React from 'react';
+
+export default function MapContainer({ children }) {
+ const [mapTools, map] = React.children(children).toArray();
+ return React.cloneElement(map, {}, [mapTools, ...map.props.children]);
+}
diff --git a/packages/leaflet/src/components/Legend.js b/packages/leaflet/src/components/MapToolbar.js
similarity index 51%
rename from packages/leaflet/src/components/Legend.js
rename to packages/leaflet/src/components/MapToolbar.js
index 01623031..4df3a323 100644
--- a/packages/leaflet/src/components/Legend.js
+++ b/packages/leaflet/src/components/MapToolbar.js
@@ -2,8 +2,21 @@ import React from 'react';
import PropTypes from 'prop-types';
import { LayersControl } from 'react-leaflet';
const { BaseLayer, Overlay } = LayersControl;
+import { useComponents } from '@wq/react';
-export default function Legend({ position, collapsed, children }) {
+export default function MapToolbar({
+ overlays,
+ basemaps,
+ context,
+ position,
+ collapsed
+}) {
+ const {
+ AutoBasemap,
+ AutoOverlay,
+ BasemapToggle,
+ OverlayToggle
+ } = useComponents();
if (!position) {
position = 'topright';
}
@@ -12,11 +25,31 @@ export default function Legend({ position, collapsed, children }) {
}
return (
- {children}
+ {basemaps.map(conf => (
+
+
+
+ ))}
+ {overlays.map(conf => (
+
+
+
+ ))}
);
}
-Legend.propTypes = {
+MapToolbar.propTypes = {
+ overlays: PropTypes.arrayOf(PropTypes.object),
+ basemaps: PropTypes.arrayOf(PropTypes.object),
+ context: PropTypes.object,
position: PropTypes.object,
collapsed: PropTypes.bool,
children: PropTypes.node
diff --git a/packages/leaflet/src/components/index.js b/packages/leaflet/src/components/index.js
index 04046b24..ee3e57da 100644
--- a/packages/leaflet/src/components/index.js
+++ b/packages/leaflet/src/components/index.js
@@ -1,5 +1,13 @@
+import MapContainer from './MapContainer';
+import MapToolbar, { BasemapToggle, OverlayToggle } from './MapToolbar';
import Map from './Map';
import MapAutoZoom from './MapAutoZoom';
-import Legend, { BasemapToggle, OverlayToggle } from './Legend';
-export { Map, MapAutoZoom, Legend, BasemapToggle, OverlayToggle };
+export {
+ MapContainer,
+ MapToolbar,
+ Map,
+ MapAutoZoom,
+ BasemapToggle,
+ OverlayToggle
+};
diff --git a/packages/leaflet/src/index.js b/packages/leaflet/src/index.js
index e52dfeac..ebae2485 100644
--- a/packages/leaflet/src/index.js
+++ b/packages/leaflet/src/index.js
@@ -1,8 +1,9 @@
import map from '@wq/map';
import {
+ MapContainer,
+ MapToolbar,
Map,
MapAutoZoom,
- Legend,
BasemapToggle,
OverlayToggle
} from './components/index';
@@ -44,9 +45,11 @@ export default {
}));
},
components: {
+ MapContainer,
+ MapToolbar,
Map,
MapAutoZoom,
- Legend,
+ MapLayers: () => null,
BasemapToggle,
OverlayToggle
},
@@ -74,8 +77,9 @@ export default {
};
export {
+ MapContainer,
+ MapToolbar,
Map,
- Legend,
BasemapToggle,
OverlayToggle,
Tile,
diff --git a/packages/map-gl/src/components/BasemapToggle.js b/packages/map-gl/src/components/BasemapToggle.js
deleted file mode 100644
index 8f62f82a..00000000
--- a/packages/map-gl/src/components/BasemapToggle.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-
-export default function BasemapToggle({ active, children }) {
- if (!active) {
- return null;
- }
- return <>{children}>;
-}
-
-BasemapToggle.propTypes = {
- active: PropTypes.bool,
- children: PropTypes.node
-};
diff --git a/packages/map-gl/src/components/Legend.js b/packages/map-gl/src/components/Legend.js
deleted file mode 100644
index 39ba2fb1..00000000
--- a/packages/map-gl/src/components/Legend.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-
-export default function Legend({ children }) {
- return <>{children}>;
-}
-
-Legend.propTypes = {
- children: PropTypes.node
-};
diff --git a/packages/map-gl/src/components/MapLayers.js b/packages/map-gl/src/components/MapLayers.js
new file mode 100644
index 00000000..2fb7ea76
--- /dev/null
+++ b/packages/map-gl/src/components/MapLayers.js
@@ -0,0 +1,3 @@
+import { Fragment } from 'react';
+
+export default Fragment;
diff --git a/packages/map-gl/src/components/OverlayToggle.js b/packages/map-gl/src/components/OverlayToggle.js
deleted file mode 100644
index 341f531f..00000000
--- a/packages/map-gl/src/components/OverlayToggle.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-
-export default function OverlayToggle({ children }) {
- return <>{children}>;
-}
-
-OverlayToggle.propTypes = {
- children: PropTypes.node
-};
diff --git a/packages/map-gl/src/components/index.js b/packages/map-gl/src/components/index.js
index dfa55a46..516d0bce 100644
--- a/packages/map-gl/src/components/index.js
+++ b/packages/map-gl/src/components/index.js
@@ -1,17 +1,7 @@
-import BasemapToggle from './BasemapToggle';
-import Legend from './Legend';
import Map from './Map';
import MapInteraction from './MapInteraction';
import MapAutoZoom from './MapAutoZoom';
import MapIdentify from './MapIdentify';
-import OverlayToggle from './OverlayToggle';
+import MapLayers from './MapLayers';
-export {
- BasemapToggle,
- Legend,
- Map,
- MapInteraction,
- MapAutoZoom,
- MapIdentify,
- OverlayToggle
-};
+export { Map, MapInteraction, MapAutoZoom, MapIdentify, MapLayers };
diff --git a/packages/map-gl/src/index.js b/packages/map-gl/src/index.js
index a85bf67d..469d368f 100644
--- a/packages/map-gl/src/index.js
+++ b/packages/map-gl/src/index.js
@@ -5,9 +5,7 @@ import {
MapInteraction,
MapAutoZoom,
MapIdentify,
- Legend,
- BasemapToggle,
- OverlayToggle
+ MapLayers
} from './components/index';
import { VectorTile, Tile } from './basemaps/index';
@@ -31,9 +29,7 @@ export default {
MapInteraction,
MapAutoZoom,
MapIdentify,
- Legend,
- BasemapToggle,
- OverlayToggle
+ MapLayers
},
basemaps: {
VectorTile,
@@ -55,9 +51,6 @@ export {
MapInteraction,
MapAutoZoom,
MapIdentify,
- Legend,
- BasemapToggle,
- OverlayToggle,
VectorTile,
Tile,
Geojson,
diff --git a/packages/map/src/components/AutoMap.js b/packages/map/src/components/AutoMap.js
index f42dc701..7918dec2 100644
--- a/packages/map/src/components/AutoMap.js
+++ b/packages/map/src/components/AutoMap.js
@@ -1,26 +1,28 @@
import React from 'react';
-import { useComponents } from '@wq/react';
+import { useComponents, usePlugin } from '@wq/react';
import { useMapState, useOverlayComponents } from '../hooks';
import PropTypes from 'prop-types';
export default function AutoMap({
name,
+ toolbar = true,
containerStyle,
context,
state,
children
}) {
const mapState = useMapState(),
+ { showOverlay, hideOverlay, setBasemap } = usePlugin('map'),
{
+ MapContainer,
+ MapToolbar,
Map,
MapInteraction,
MapAutoZoom,
MapIdentify,
+ MapLayers,
AutoBasemap,
- AutoOverlay,
- Legend,
- BasemapToggle,
- OverlayToggle
+ AutoOverlay
} = useComponents(),
{ Highlight } = useOverlayComponents();
@@ -44,40 +46,45 @@ export default function AutoMap({
const identify = overlays.some(overlay => !!overlay.popup);
return (
-
+
+
);
}
@@ -91,6 +98,7 @@ AutoMap.makeComponent = props => {
AutoMap.propTypes = {
name: PropTypes.string,
+ toolbar: PropTypes.bool,
containerStyle: PropTypes.object,
context: PropTypes.object,
state: PropTypes.object,
diff --git a/packages/map/src/components/BasemapToggle.js b/packages/map/src/components/BasemapToggle.js
new file mode 100644
index 00000000..eca7f8b6
--- /dev/null
+++ b/packages/map/src/components/BasemapToggle.js
@@ -0,0 +1,30 @@
+import React from 'react';
+import { useComponents } from '@wq/react';
+import PropTypes from 'prop-types';
+
+export default function BasemapToggle({ name, active, setActive }) {
+ const { ListItem, RadioButton } = useComponents();
+ return (
+ setActive(true)}
+ icon={() => (
+
+ )}
+ >
+ {name}
+
+ );
+}
+
+BasemapToggle.propTypes = {
+ name: PropTypes.string,
+ active: PropTypes.bool,
+ setActive: PropTypes.func
+};
diff --git a/packages/map/src/components/Legend.js b/packages/map/src/components/Legend.js
index 9dabbe97..941f60f2 100644
--- a/packages/map/src/components/Legend.js
+++ b/packages/map/src/components/Legend.js
@@ -1,54 +1,28 @@
import React from 'react';
+import { useComponents } from '@wq/react';
import PropTypes from 'prop-types';
-export default function Legend({ children }) {
+export default function Legend({ legend }) {
+ const { Typography, LegendIcon } = useComponents();
return (
-
-
-
- Group |
- Name |
- Active |
- Detail |
-
-
- {children}
-
- );
-}
-Legend.propTypes = {
- children: PropTypes.node
-};
-
-export function BasemapToggle({ name, active, children }) {
- return (
-
- Basemap |
- {name} |
- {active ? 'Y' : 'N'} |
- {children} |
-
- );
-}
-BasemapToggle.propTypes = {
- name: PropTypes.string,
- active: PropTypes.bool,
- children: PropTypes.node
-};
-
-export function OverlayToggle({ name, active, children }) {
- return (
-
- Overlay |
- {name} |
- {active ? 'Y' : 'N'} |
- {children} |
-
+
+ {Object.entries(legend).map(([label, icon]) => (
+
+ ))}
+
);
}
-OverlayToggle.propTypes = {
- name: PropTypes.string,
- active: PropTypes.bool,
- children: PropTypes.node
+Legend.propTypes = {
+ legend: PropTypes.object
};
diff --git a/packages/map/src/components/LegendIcon.js b/packages/map/src/components/LegendIcon.js
new file mode 100644
index 00000000..dde8cabe
--- /dev/null
+++ b/packages/map/src/components/LegendIcon.js
@@ -0,0 +1,17 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+export default function LegendIcon({ name, label }) {
+ return (
+
+ );
+}
+
+LegendIcon.propTypes = {
+ name: PropTypes.string,
+ label: PropTypes.string
+};
diff --git a/packages/map/src/components/MapContainer.js b/packages/map/src/components/MapContainer.js
new file mode 100644
index 00000000..f63da449
--- /dev/null
+++ b/packages/map/src/components/MapContainer.js
@@ -0,0 +1,16 @@
+import React from 'react';
+import { useComponents } from '@wq/react';
+import PropTypes from 'prop-types';
+
+export default function MapContainer({ children }) {
+ const { View } = useComponents();
+ return (
+
+ {children}
+
+ );
+}
+
+MapContainer.propTypes = {
+ children: PropTypes.node
+};
diff --git a/packages/map/src/components/MapLayers.js b/packages/map/src/components/MapLayers.js
new file mode 100644
index 00000000..de42264c
--- /dev/null
+++ b/packages/map/src/components/MapLayers.js
@@ -0,0 +1,42 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+export default function MapLayers({ children }) {
+ return (
+
+
+
+ Group |
+ Name |
+ Active |
+ Detail |
+
+
+
+ {React.Children.map(children, element => (
+
+ ))}
+
+
+ );
+}
+MapLayers.propTypes = {
+ children: PropTypes.node
+};
+
+export function MapLayer({ element }) {
+ const type = element.type.isAutoBasemap ? 'Basemap' : 'Overlay',
+ { name, active } = element.props;
+ return (
+
+ {type} |
+ {name} |
+ {active ? 'Y' : 'N'} |
+ {element} |
+
+ );
+}
+
+MapLayer.propTypes = {
+ element: PropTypes.node
+};
diff --git a/packages/map/src/components/MapToolbar.js b/packages/map/src/components/MapToolbar.js
new file mode 100644
index 00000000..14e6fe16
--- /dev/null
+++ b/packages/map/src/components/MapToolbar.js
@@ -0,0 +1,88 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { useComponents } from '@wq/react';
+import { useMapInstance } from '../hooks';
+
+export default function MapToolbar({
+ name,
+ overlays,
+ basemaps,
+ showOverlay,
+ hideOverlay,
+ setBasemap,
+ children
+}) {
+ const {
+ SidePanel,
+ List,
+ ListSubheader,
+ OverlayToggle,
+ BasemapToggle
+ } = useComponents(),
+ map = useMapInstance(name),
+ hasMultipleOverlays =
+ overlays &&
+ (overlays.length > 1 || overlays.some(conf => conf.legend)),
+ hasMultipleBasemaps = basemaps && basemaps.length > 1;
+
+ if (!hasMultipleOverlays && !hasMultipleBasemaps) {
+ return null;
+ }
+
+ function resize() {
+ if (map && map.resize) {
+ map.resize();
+ }
+ }
+
+ return (
+
+ {children}
+
+ {hasMultipleOverlays && (
+ <>
+ Layers
+ {overlays.map(conf => (
+
+ active
+ ? showOverlay(conf.name)
+ : hideOverlay(conf.name)
+ }
+ />
+ ))}
+ >
+ )}
+ {hasMultipleBasemaps && (
+ <>
+ Basemap
+ {basemaps.map(conf => (
+
+ active && setBasemap(conf.name)
+ }
+ />
+ ))}
+ >
+ )}
+
+
+ );
+}
+
+MapToolbar.propTypes = {
+ name: PropTypes.string,
+ overlays: PropTypes.arrayOf(PropTypes.object),
+ basemaps: PropTypes.arrayOf(PropTypes.object),
+ showOverlay: PropTypes.func,
+ hideOverlay: PropTypes.func,
+ setBasemap: PropTypes.func,
+ children: PropTypes.node
+};
diff --git a/packages/map/src/components/OverlayToggle.js b/packages/map/src/components/OverlayToggle.js
new file mode 100644
index 00000000..f64adaf8
--- /dev/null
+++ b/packages/map/src/components/OverlayToggle.js
@@ -0,0 +1,27 @@
+import React from 'react';
+import { useComponents } from '@wq/react';
+import PropTypes from 'prop-types';
+
+export default function OverlayToggle({ name, legend, active, setActive }) {
+ const { ListItem, Switch, Legend } = useComponents();
+ return (
+ setActive(!active)}
+ icon={() => }
+ description={active && legend ? : null}
+ >
+ {name}
+
+ );
+}
+
+OverlayToggle.propTypes = {
+ name: PropTypes.string,
+ legend: PropTypes.object,
+ active: PropTypes.bool,
+ setActive: PropTypes.func
+};
diff --git a/packages/map/src/components/index.js b/packages/map/src/components/index.js
index 6462bb30..b67adca5 100644
--- a/packages/map/src/components/index.js
+++ b/packages/map/src/components/index.js
@@ -5,8 +5,14 @@ import StickyMap from './StickyMap';
import OffscreenMaps from './OffscreenMaps';
import HighlightPopup from './HighlightPopup';
import PropertyTable from './PropertyTable';
+import MapContainer from './MapContainer';
+import MapToolbar from './MapToolbar';
import Map from './Map';
-import Legend, { BasemapToggle, OverlayToggle } from './Legend';
+import MapLayers from './MapLayers';
+import BasemapToggle from './BasemapToggle';
+import OverlayToggle from './OverlayToggle';
+import Legend from './Legend';
+import LegendIcon from './LegendIcon';
import GeoTools from './GeoTools';
export {
@@ -17,9 +23,13 @@ export {
OffscreenMaps,
HighlightPopup,
PropertyTable,
+ MapContainer,
+ MapToolbar,
Map,
- Legend,
+ MapLayers,
BasemapToggle,
OverlayToggle,
+ Legend,
+ LegendIcon,
GeoTools
};
diff --git a/packages/map/src/index.js b/packages/map/src/index.js
index b9c01522..d864fdd6 100644
--- a/packages/map/src/index.js
+++ b/packages/map/src/index.js
@@ -20,6 +20,8 @@ import {
OffscreenMaps,
HighlightPopup,
PropertyTable,
+ Legend,
+ LegendIcon,
GeoTools
} from './components/index';
import { Geo, EmbeddedGeo } from './inputs/index';
@@ -47,6 +49,8 @@ export {
OffscreenMaps,
HighlightPopup,
PropertyTable,
+ Legend,
+ LegendIcon,
GeoTools,
Geo,
EmbeddedGeo,
diff --git a/packages/map/src/map.js b/packages/map/src/map.js
index b9894386..99ea76b0 100644
--- a/packages/map/src/map.js
+++ b/packages/map/src/map.js
@@ -6,10 +6,14 @@ import {
OffscreenMaps,
HighlightPopup,
PropertyTable,
+ MapContainer,
+ MapToolbar,
Map,
- Legend,
+ MapLayers,
BasemapToggle,
OverlayToggle,
+ Legend,
+ LegendIcon,
GeoTools
} from './components/index';
import { Geo, EmbeddedGeo } from './inputs/index';
@@ -125,13 +129,17 @@ const map = {
OffscreenMaps,
HighlightPopup,
PropertyTable,
+ MapContainer,
+ MapToolbar,
Map,
MapInteraction: () => null,
MapAutoZoom: () => null,
MapIdentify: () => null,
- Legend,
+ MapLayers,
BasemapToggle,
OverlayToggle,
+ Legend,
+ LegendIcon,
GeoTools
},
inputs: {
diff --git a/packages/material/src/components/CheckboxButton.js b/packages/material/src/components/CheckboxButton.js
new file mode 100644
index 00000000..267df3a0
--- /dev/null
+++ b/packages/material/src/components/CheckboxButton.js
@@ -0,0 +1,3 @@
+import Checkbox from '@material-ui/core/Checkbox';
+
+export default Checkbox;
diff --git a/packages/material/src/components/CheckboxButton.native.js b/packages/material/src/components/CheckboxButton.native.js
new file mode 100644
index 00000000..1a4ff952
--- /dev/null
+++ b/packages/material/src/components/CheckboxButton.native.js
@@ -0,0 +1,3 @@
+export default function NotImplemented() {
+ return null; // FIXME
+}
diff --git a/packages/material/src/components/RadioButton.js b/packages/material/src/components/RadioButton.js
new file mode 100644
index 00000000..7ef214d8
--- /dev/null
+++ b/packages/material/src/components/RadioButton.js
@@ -0,0 +1,3 @@
+import Radio from '@material-ui/core/Radio';
+
+export default Radio;
diff --git a/packages/material/src/components/RadioButton.native.js b/packages/material/src/components/RadioButton.native.js
new file mode 100644
index 00000000..1a4ff952
--- /dev/null
+++ b/packages/material/src/components/RadioButton.native.js
@@ -0,0 +1,3 @@
+export default function NotImplemented() {
+ return null; // FIXME
+}
diff --git a/packages/material/src/components/SidePanel.js b/packages/material/src/components/SidePanel.js
new file mode 100644
index 00000000..48481421
--- /dev/null
+++ b/packages/material/src/components/SidePanel.js
@@ -0,0 +1,60 @@
+import React, { useState, useEffect } from 'react';
+import { useComponents } from '@wq/react';
+import Drawer from '@material-ui/core/Drawer';
+import useMediaQuery from '@material-ui/core/useMediaQuery';
+import PropTypes from 'prop-types';
+
+export default function SidePanel({ children, compactChildren, onChange }) {
+ const mobile = useMediaQuery(theme => theme.breakpoints.down('sm')),
+ [open, setOpen] = useState(!mobile),
+ { IconButton } = useComponents();
+
+ useEffect(() => {
+ if (onChange) {
+ onChange(open);
+ }
+ }, [open, onChange]);
+
+ return (
+
+ {open ? (
+
+
+
+ setOpen(false)}
+ />
+
+
+ ) : (
+ setOpen(true)} />
+ )}
+ {open ? children : compactChildren}
+
+ );
+}
+
+SidePanel.propTypes = {
+ children: PropTypes.node,
+ compactChildren: PropTypes.node,
+ onChange: PropTypes.func
+};
diff --git a/packages/material/src/components/SidePanel.native.js b/packages/material/src/components/SidePanel.native.js
new file mode 100644
index 00000000..1a4ff952
--- /dev/null
+++ b/packages/material/src/components/SidePanel.native.js
@@ -0,0 +1,3 @@
+export default function NotImplemented() {
+ return null; // FIXME
+}
diff --git a/packages/material/src/components/Switch.js b/packages/material/src/components/Switch.js
new file mode 100644
index 00000000..4ca1a329
--- /dev/null
+++ b/packages/material/src/components/Switch.js
@@ -0,0 +1,3 @@
+import Switch from '@material-ui/core/Switch';
+
+export default Switch;
diff --git a/packages/material/src/components/Switch.native.js b/packages/material/src/components/Switch.native.js
new file mode 100644
index 00000000..1a4ff952
--- /dev/null
+++ b/packages/material/src/components/Switch.native.js
@@ -0,0 +1,3 @@
+export default function NotImplemented() {
+ return null; // FIXME
+}
diff --git a/packages/material/src/components/index.js b/packages/material/src/components/index.js
index b6b52282..6f196b33 100644
--- a/packages/material/src/components/index.js
+++ b/packages/material/src/components/index.js
@@ -17,6 +17,9 @@ import HomeLink from './HomeLink';
import IconButton from './IconButton';
import Fab from './Fab';
import Chip from './Chip';
+import Switch from './Switch';
+import CheckboxButton from './CheckboxButton';
+import RadioButton from './RadioButton';
import List from './List';
import ListItem from './ListItem';
@@ -46,6 +49,7 @@ import DeleteForm from './DeleteForm';
import Spinner from './Spinner';
import Popup from './Popup';
+import SidePanel from './SidePanel';
import Breadcrumbs from './Breadcrumbs';
import Pagination from './Pagination';
@@ -63,7 +67,18 @@ export {
FormatJson
};
-export { Link, Button, ButtonLink, HomeLink, IconButton, Fab, Chip };
+export {
+ Link,
+ Button,
+ ButtonLink,
+ HomeLink,
+ IconButton,
+ Fab,
+ Chip,
+ Switch,
+ CheckboxButton,
+ RadioButton
+};
export {
List,
@@ -90,4 +105,4 @@ export {
DeleteForm
};
-export { Spinner, Popup, Breadcrumbs, Pagination };
+export { Spinner, Popup, SidePanel, Breadcrumbs, Pagination };
diff --git a/packages/material/src/icons.js b/packages/material/src/icons.js
index 9c457b7b..c6cb00f3 100644
--- a/packages/material/src/icons.js
+++ b/packages/material/src/icons.js
@@ -7,6 +7,8 @@ import Pending from '@material-ui/icons/Sync';
import Close from '@material-ui/icons/Close';
import Expand from '@material-ui/icons/ExpandMore';
import Collapse from '@material-ui/icons/ExpandLess';
+import PanelOpen from '@material-ui/icons/ChevronRight';
+import PanelClose from '@material-ui/icons/ChevronLeft';
import GpsStart from '@material-ui/icons/GpsFixed';
import GpsStop from '@material-ui/icons/GpsOff';
import Search from '@material-ui/icons/Search';
@@ -21,6 +23,8 @@ export {
Close,
Expand,
Collapse,
+ PanelOpen,
+ PanelClose,
GpsStart,
GpsStop,
Search
diff --git a/packages/react/src/components/SidePanel.js b/packages/react/src/components/SidePanel.js
new file mode 100644
index 00000000..2fb7ea76
--- /dev/null
+++ b/packages/react/src/components/SidePanel.js
@@ -0,0 +1,3 @@
+import { Fragment } from 'react';
+
+export default Fragment;
diff --git a/packages/react/src/components/index.js b/packages/react/src/components/index.js
index 51334118..ca6dcc9e 100644
--- a/packages/react/src/components/index.js
+++ b/packages/react/src/components/index.js
@@ -55,6 +55,7 @@ import DeleteForm from './DeleteForm';
import Spinner from './Spinner';
import Popup from './Popup';
+import SidePanel from './SidePanel';
import Breadcrumbs from './Breadcrumbs';
import Pagination from './Pagination';
import DebugContext from './DebugContext';
@@ -103,4 +104,4 @@ export {
DeleteForm
};
-export { Spinner, Popup, Breadcrumbs, Pagination, DebugContext };
+export { Spinner, Popup, SidePanel, Breadcrumbs, Pagination, DebugContext };