From 14b882a6968560f1cb8c2d21ab57b6955c35f573 Mon Sep 17 00:00:00 2001 From: Juan Pablo Garcia Ripa Date: Mon, 10 Jan 2022 18:14:46 +0100 Subject: [PATCH] Move layout context to SidabarPage Signed-off-by: Juan Pablo Garcia Ripa --- .../src/layout/Content/Content.tsx | 4 +- .../layout/LayoutProvider/LayoutProvider.tsx | 59 ------------------- .../src/layout/LayoutProvider/index.ts | 16 ----- .../src/layout/Sidebar/Page.tsx | 34 ++++++++++- .../src/layout/Sidebar/index.ts | 2 +- .../components/SearchModal/SearchModal.tsx | 4 +- .../SidebarSearch/SidebarSearch.tsx | 7 +-- 7 files changed, 40 insertions(+), 86 deletions(-) delete mode 100644 packages/core-components/src/layout/LayoutProvider/LayoutProvider.tsx delete mode 100644 packages/core-components/src/layout/LayoutProvider/index.ts diff --git a/packages/core-components/src/layout/Content/Content.tsx b/packages/core-components/src/layout/Content/Content.tsx index 8d91d335be..a26f74710d 100644 --- a/packages/core-components/src/layout/Content/Content.tsx +++ b/packages/core-components/src/layout/Content/Content.tsx @@ -17,7 +17,7 @@ import { makeStyles, Theme } from '@material-ui/core/styles'; import classNames from 'classnames'; import React, { PropsWithChildren } from 'react'; -import { useLayoutContent } from '../LayoutProvider/LayoutProvider'; +import { useContent } from '../Sidebar'; /** @public */ export type BackstageContentClassKey = 'root' | 'stretch' | 'noPadding'; @@ -64,7 +64,7 @@ type Props = { export function Content(props: PropsWithChildren) { const { className, stretch, noPadding, children, ...restProps } = props; - const { contentRef } = useLayoutContent(); + const { contentRef } = useContent(); const classes = useStyles(); return ( diff --git a/packages/core-components/src/layout/LayoutProvider/LayoutProvider.tsx b/packages/core-components/src/layout/LayoutProvider/LayoutProvider.tsx deleted file mode 100644 index 1dcc91d817..0000000000 --- a/packages/core-components/src/layout/LayoutProvider/LayoutProvider.tsx +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React, { - createContext, - PropsWithChildren, - useCallback, - useContext, - useRef, -} from 'react'; - -export type LayoutContextType = { - content: { - contentRef?: React.MutableRefObject; - }; -}; - -const LayoutContext = createContext({ - content: { - contentRef: undefined, - }, -}); - -export function LayoutProvider(props: PropsWithChildren<{}>) { - const contentRef = useRef(null); - - const content = { - contentRef, - }; - - return ( - - {props.children} - - ); -} - -export function useLayoutContent() { - const { content } = useContext(LayoutContext); - - const focusContent = useCallback(() => { - content.contentRef?.current?.focus(); - }, [content]); - - return { focusContent, contentRef: content.contentRef }; -} diff --git a/packages/core-components/src/layout/LayoutProvider/index.ts b/packages/core-components/src/layout/LayoutProvider/index.ts deleted file mode 100644 index 4f8b38f7e9..0000000000 --- a/packages/core-components/src/layout/LayoutProvider/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { LayoutProvider, useLayoutContent } from './LayoutProvider'; diff --git a/packages/core-components/src/layout/Sidebar/Page.tsx b/packages/core-components/src/layout/Sidebar/Page.tsx index 665468231b..7192bbf4fa 100644 --- a/packages/core-components/src/layout/Sidebar/Page.tsx +++ b/packages/core-components/src/layout/Sidebar/Page.tsx @@ -19,7 +19,10 @@ import { makeStyles } from '@material-ui/core/styles'; import React, { createContext, PropsWithChildren, + useCallback, + useContext, useEffect, + useRef, useState, } from 'react'; import { sidebarConfig } from './config'; @@ -89,11 +92,28 @@ export const SidebarPinStateContext = createContext( }, ); +type PageContextType = { + content: { + contentRef?: React.MutableRefObject; + }; +}; + +const PageContext = createContext({ + content: { + contentRef: undefined, + }, +}); export function SidebarPage(props: SidebarPageProps) { const [isPinned, setIsPinned] = useState(() => LocalStorage.getSidebarPinState(), ); + const contentRef = useRef(null); + + const content = { + contentRef, + }; + useEffect(() => { LocalStorage.setSidebarPinState(isPinned); }, [isPinned]); @@ -114,7 +134,19 @@ export function SidebarPage(props: SidebarPageProps) { isMobile, }} > -
{props.children}
+ +
{props.children}
+
); } + +export function useContent() { + const { content } = useContext(PageContext); + + const focusContent = useCallback(() => { + content?.contentRef?.current?.focus(); + }, [content]); + + return { focusContent, contentRef: content?.contentRef }; +} diff --git a/packages/core-components/src/layout/Sidebar/index.ts b/packages/core-components/src/layout/Sidebar/index.ts index 2ee84199de..96fedaa75a 100644 --- a/packages/core-components/src/layout/Sidebar/index.ts +++ b/packages/core-components/src/layout/Sidebar/index.ts @@ -30,13 +30,13 @@ export type { SidebarClassKey, SidebarProps } from './Bar'; export { SidebarPage, SidebarPinStateContext as SidebarPinStateContext, + useContent, } from './Page'; export type { SidebarPinStateContextType as SidebarPinStateContextType, SidebarPageClassKey, SidebarPageProps, } from './Page'; - export { SidebarDivider, SidebarItem, diff --git a/plugins/search/src/components/SearchModal/SearchModal.tsx b/plugins/search/src/components/SearchModal/SearchModal.tsx index 101b58c334..1f0a879f96 100644 --- a/plugins/search/src/components/SearchModal/SearchModal.tsx +++ b/plugins/search/src/components/SearchModal/SearchModal.tsx @@ -34,7 +34,7 @@ import { SearchResult } from '../SearchResult'; import { SearchContextProvider, useSearch } from '../SearchContext'; import { SearchResultPager } from '../SearchResultPager'; import { useRouteRef } from '@backstage/core-plugin-api'; -import { Link, useLayoutContent } from '@backstage/core-components'; +import { Link, useContent } from '@backstage/core-components'; import { rootRouteRef } from '../../plugin'; export interface SearchModalProps { @@ -62,7 +62,7 @@ export const Modal = ({ open = true, toggleModal }: SearchModalProps) => { const classes = useStyles(); const { term } = useSearch(); - const { focusContent } = useLayoutContent(); + const { focusContent } = useContent(); const { transitions } = useTheme(); const handleResultClick = () => { diff --git a/plugins/search/src/components/SidebarSearch/SidebarSearch.tsx b/plugins/search/src/components/SidebarSearch/SidebarSearch.tsx index 16fd6deb36..25d41fa10f 100644 --- a/plugins/search/src/components/SidebarSearch/SidebarSearch.tsx +++ b/plugins/search/src/components/SidebarSearch/SidebarSearch.tsx @@ -19,10 +19,7 @@ import { useNavigate } from 'react-router-dom'; import { rootRouteRef } from '../../plugin'; import { useRouteRef, IconComponent } from '@backstage/core-plugin-api'; -import { - SidebarSearchField, - useLayoutContent, -} from '@backstage/core-components'; +import { SidebarSearchField, useContent } from '@backstage/core-components'; export type SidebarSearchProps = { icon?: IconComponent; @@ -30,7 +27,7 @@ export type SidebarSearchProps = { export const SidebarSearch = (props: SidebarSearchProps) => { const searchRoute = useRouteRef(rootRouteRef); - const { focusContent } = useLayoutContent(); + const { focusContent } = useContent(); const navigate = useNavigate(); const handleSearch = useCallback( (query: string): void => {