Browse Source

feat(ui): adds sidebar item override (#26665)

This PR adds a new hook called sidebar:item-override which allows us to conditionally send props to sidebar items. Currently, I am only wrapping the performance sidebar item. See getsentry/getsentry#5763 for details on what props we are sending.
Stephen Cefali 3 years ago
parent
commit
e3a0424600
3 changed files with 35 additions and 13 deletions
  1. 24 13
      static/app/components/sidebar/index.tsx
  2. 1 0
      static/app/stores/hookStore.tsx
  3. 10 0
      static/app/types/hooks.tsx

+ 24 - 13
static/app/components/sidebar/index.tsx

@@ -10,6 +10,7 @@ import {hideSidebar, showSidebar} from 'app/actionCreators/preferences';
 import SidebarPanelActions from 'app/actions/sidebarPanelActions';
 import Feature from 'app/components/acl/feature';
 import GuideAnchor from 'app/components/assistant/guideAnchor';
+import HookOrDefault from 'app/components/hookOrDefault';
 import {extractSelectionParameters} from 'app/components/organizations/globalSelectionHeader/utils';
 import {
   IconActivity,
@@ -45,6 +46,11 @@ import SidebarDropdown from './sidebarDropdown';
 import SidebarItem from './sidebarItem';
 import {SidebarOrientation, SidebarPanelKey} from './types';
 
+const SidebarOverride = HookOrDefault({
+  hookName: 'sidebar:item-override',
+  defaultComponent: ({children}) => <React.Fragment>{children({})}</React.Fragment>,
+});
+
 type ActivePanelType = SidebarPanelKey | '';
 
 type Props = {
@@ -267,19 +273,24 @@ class Sidebar extends React.Component<Props, State> {
         features={['performance-view']}
         organization={organization}
       >
-        <SidebarItem
-          {...sidebarItemProps}
-          onClick={(_id, evt) =>
-            this.navigateWithGlobalSelection(
-              `/organizations/${organization.slug}/performance/`,
-              evt
-            )
-          }
-          icon={<IconLightning size="md" />}
-          label={<GuideAnchor target="performance">{t('Performance')}</GuideAnchor>}
-          to={`/organizations/${organization.slug}/performance/`}
-          id="performance"
-        />
+        <SidebarOverride id="performance-override">
+          {(overideProps: Partial<React.ComponentProps<typeof SidebarItem>>) => (
+            <SidebarItem
+              {...sidebarItemProps}
+              onClick={(_id, evt) =>
+                this.navigateWithGlobalSelection(
+                  `/organizations/${organization.slug}/performance/`,
+                  evt
+                )
+              }
+              icon={<IconLightning size="md" />}
+              label={<GuideAnchor target="performance">{t('Performance')}</GuideAnchor>}
+              to={`/organizations/${organization.slug}/performance/`}
+              id="performance"
+              {...overideProps}
+            />
+          )}
+        </SidebarOverride>
       </Feature>
     );
 

+ 1 - 0
static/app/stores/hookStore.tsx

@@ -71,6 +71,7 @@ const validHookNames = new Set<HookName>([
   'sidebar:bottom-items',
   'sidebar:help-menu',
   'sidebar:item-label',
+  'sidebar:item-override',
   'sidebar:organization-dropdown-menu',
   'sidebar:organization-dropdown-menu-bottom',
 ]);

+ 10 - 0
static/app/types/hooks.tsx

@@ -1,3 +1,4 @@
+import React from 'react';
 import {Route, RouteComponentProps} from 'react-router';
 
 import {ChildrenRenderFn} from 'app/components/acl/feature';
@@ -145,6 +146,7 @@ export type InterfaceChromeHooks = {
   'sidebar:organization-dropdown-menu-bottom': GenericOrganizationComponentHook;
   'sidebar:bottom-items': SidebarBottomItemsHook;
   'sidebar:item-label': SidebarItemLabelHook;
+  'sidebar:item-override': SidebarItemOverrideHook;
   'help-modal:footer': HelpModalFooterHook;
 };
 
@@ -335,6 +337,14 @@ type SidebarItemLabelHook = () => React.ComponentType<{
   children: React.ReactNode;
 }>;
 
+type SidebarItemOverrideHook = () => React.ComponentType<{
+  /**
+   * The item label being wrapped
+   */
+  children: (props: Partial<React.ComponentProps<typeof SidebarItem>>) => React.ReactNode;
+  id?: string;
+}>;
+
 type SidebarProps = Pick<
   React.ComponentProps<typeof SidebarItem>,
   'orientation' | 'collapsed' | 'hasPanel'