Provide a deprecation path for affected sidebar contexts.
Signed-off-by: Eric Peterson <ericpeterson@spotify.com>
This commit is contained in:
@@ -902,6 +902,9 @@ export const sidebarConfig: {
|
||||
mobileSidebarHeight: number;
|
||||
};
|
||||
|
||||
// @public @deprecated
|
||||
export const SidebarContext: React_2.Context<SidebarContextType>;
|
||||
|
||||
// @public
|
||||
export const SidebarContextProvider: ({
|
||||
children,
|
||||
@@ -1005,6 +1008,9 @@ export type SidebarPageProps = {
|
||||
children?: React_2.ReactNode;
|
||||
};
|
||||
|
||||
// @public @deprecated
|
||||
export const SidebarPinStateContext: React_2.Context<SidebarPinStateContextType>;
|
||||
|
||||
// @public
|
||||
export const SidebarPinStateContextProvider: ({
|
||||
children,
|
||||
|
||||
@@ -13,21 +13,45 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React, { ReactNode } from 'react';
|
||||
import { renderInTestApp } from '@backstage/test-utils';
|
||||
import { screen, waitFor } from '@testing-library/react';
|
||||
import React, { ReactNode, useContext } from 'react';
|
||||
import { renderWithEffects } from '@backstage/test-utils';
|
||||
import { waitFor } from '@testing-library/react';
|
||||
import { renderHook, act } from '@testing-library/react-hooks';
|
||||
import { SidebarContextProvider, useSidebar } from './SidebarContext';
|
||||
import {
|
||||
LegacySidebarContext,
|
||||
SidebarContextProvider,
|
||||
useSidebar,
|
||||
} from './SidebarContext';
|
||||
|
||||
describe('SidebarContext', () => {
|
||||
describe('SidebarContextProvider', () => {
|
||||
it('should render children', async () => {
|
||||
await renderInTestApp(
|
||||
const { findByText } = await renderWithEffects(
|
||||
<SidebarContextProvider value={{ isOpen: false, setOpen: () => {} }}>
|
||||
Child
|
||||
</SidebarContextProvider>,
|
||||
);
|
||||
expect(await screen.findByText('Child')).toBeInTheDocument();
|
||||
expect(await findByText('Child')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should provide the legacy context as well, for now', async () => {
|
||||
const LegacyContextSpy = () => {
|
||||
const { isOpen } = useContext(LegacySidebarContext);
|
||||
return <>{String(isOpen)}</>;
|
||||
};
|
||||
|
||||
const { findByText } = await renderWithEffects(
|
||||
<SidebarContextProvider
|
||||
value={{
|
||||
isOpen: true,
|
||||
setOpen: () => {},
|
||||
}}
|
||||
>
|
||||
<LegacyContextSpy />
|
||||
</SidebarContextProvider>,
|
||||
);
|
||||
|
||||
expect(await findByText('true')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -52,15 +76,16 @@ describe('SidebarContext', () => {
|
||||
{children}
|
||||
</SidebarContextProvider>
|
||||
);
|
||||
const { result } = renderHook(() => useSidebar(), { wrapper });
|
||||
const { result, rerender } = renderHook(() => useSidebar(), { wrapper });
|
||||
|
||||
expect(result.current.isOpen).toBe(true);
|
||||
|
||||
act(() => {
|
||||
result.current.setOpen(false);
|
||||
rerender();
|
||||
});
|
||||
|
||||
waitFor(() => {
|
||||
await waitFor(() => {
|
||||
expect(result.current.isOpen).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { ReactNode, useContext } from 'react';
|
||||
import React, { createContext, ReactNode, useContext } from 'react';
|
||||
import {
|
||||
createVersionedContext,
|
||||
createVersionedValueMap,
|
||||
@@ -30,6 +30,21 @@ export type SidebarContextType = {
|
||||
setOpen: (open: boolean) => void;
|
||||
};
|
||||
|
||||
const defaultSidebarContext = {
|
||||
isOpen: false,
|
||||
setOpen: () => {},
|
||||
};
|
||||
|
||||
/**
|
||||
* Context whether the `Sidebar` is open
|
||||
*
|
||||
* @public @deprecated
|
||||
* Use `<SidebarContextProvider>` + `useSidebar()` instead.
|
||||
*/
|
||||
export const LegacySidebarContext = createContext<SidebarContextType>(
|
||||
defaultSidebarContext,
|
||||
);
|
||||
|
||||
const VersionedSidebarContext = createVersionedContext<{
|
||||
1: SidebarContextType;
|
||||
}>('sidebar-context');
|
||||
@@ -46,11 +61,13 @@ export const SidebarContextProvider = ({
|
||||
children: ReactNode;
|
||||
value: SidebarContextType;
|
||||
}) => (
|
||||
<VersionedSidebarContext.Provider
|
||||
value={createVersionedValueMap({ 1: value })}
|
||||
>
|
||||
{children}
|
||||
</VersionedSidebarContext.Provider>
|
||||
<LegacySidebarContext.Provider value={value}>
|
||||
<VersionedSidebarContext.Provider
|
||||
value={createVersionedValueMap({ 1: value })}
|
||||
>
|
||||
{children}
|
||||
</VersionedSidebarContext.Provider>
|
||||
</LegacySidebarContext.Provider>
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -63,10 +80,7 @@ export const useSidebar = (): SidebarContextType => {
|
||||
|
||||
// Invoked from outside a SidbarContextProvider, return a default value.
|
||||
if (versionedSidebarContext === undefined) {
|
||||
return {
|
||||
isOpen: false,
|
||||
setOpen: () => {},
|
||||
};
|
||||
return defaultSidebarContext;
|
||||
}
|
||||
|
||||
const sidebarContext = versionedSidebarContext.atVersion(1);
|
||||
|
||||
@@ -13,19 +13,20 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React, { ReactNode } from 'react';
|
||||
import { renderInTestApp } from '@backstage/test-utils';
|
||||
import { screen, waitFor } from '@testing-library/react';
|
||||
import React, { ReactNode, useContext } from 'react';
|
||||
import { renderWithEffects } from '@backstage/test-utils';
|
||||
import { waitFor } from '@testing-library/react';
|
||||
import { renderHook, act } from '@testing-library/react-hooks';
|
||||
import {
|
||||
LegacySidebarPinStateContext,
|
||||
SidebarPinStateContextProvider,
|
||||
useSidebarPinState,
|
||||
} from './SidebarPinStateContext';
|
||||
|
||||
describe('SidebarContext', () => {
|
||||
describe('SidebarContextProvider', () => {
|
||||
describe('SidebarPinStateContext', () => {
|
||||
describe('SidebarPinStateContextProvider', () => {
|
||||
it('should render children', async () => {
|
||||
await renderInTestApp(
|
||||
const { findByText } = await renderWithEffects(
|
||||
<SidebarPinStateContextProvider
|
||||
value={{
|
||||
isPinned: true,
|
||||
@@ -36,11 +37,32 @@ describe('SidebarContext', () => {
|
||||
Child
|
||||
</SidebarPinStateContextProvider>,
|
||||
);
|
||||
expect(await screen.findByText('Child')).toBeInTheDocument();
|
||||
expect(await findByText('Child')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should provide the legacy context as well, for now', async () => {
|
||||
const LegacyContextSpy = () => {
|
||||
const { isMobile } = useContext(LegacySidebarPinStateContext);
|
||||
return <>{String(isMobile)}</>;
|
||||
};
|
||||
|
||||
const { findByText } = await renderWithEffects(
|
||||
<SidebarPinStateContextProvider
|
||||
value={{
|
||||
isPinned: true,
|
||||
isMobile: true,
|
||||
toggleSidebarPinState: () => {},
|
||||
}}
|
||||
>
|
||||
<LegacyContextSpy />
|
||||
</SidebarPinStateContextProvider>,
|
||||
);
|
||||
|
||||
expect(await findByText('true')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('useSidebar', () => {
|
||||
describe('useSidebarPinState', () => {
|
||||
it('does not need to be invoked within provider', () => {
|
||||
const { result } = renderHook(() => useSidebarPinState());
|
||||
expect(result.current.isPinned).toBe(true);
|
||||
@@ -63,15 +85,18 @@ describe('SidebarContext', () => {
|
||||
{children}
|
||||
</SidebarPinStateContextProvider>
|
||||
);
|
||||
const { result } = renderHook(() => useSidebarPinState(), { wrapper });
|
||||
const { result, rerender } = renderHook(() => useSidebarPinState(), {
|
||||
wrapper,
|
||||
});
|
||||
|
||||
expect(result.current.isPinned).toBe(true);
|
||||
|
||||
act(() => {
|
||||
result.current.toggleSidebarPinState();
|
||||
rerender();
|
||||
});
|
||||
|
||||
waitFor(() => {
|
||||
await waitFor(() => {
|
||||
expect(result.current.isPinned).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
createVersionedContext,
|
||||
createVersionedValueMap,
|
||||
} from '@backstage/version-bridge';
|
||||
import React, { ReactNode, useContext } from 'react';
|
||||
import React, { createContext, ReactNode, useContext } from 'react';
|
||||
|
||||
/**
|
||||
* Type of `SidebarPinStateContext`
|
||||
@@ -30,6 +30,21 @@ export type SidebarPinStateContextType = {
|
||||
isMobile?: boolean;
|
||||
};
|
||||
|
||||
const defaultSidebarPinStateContext = {
|
||||
isPinned: true,
|
||||
toggleSidebarPinState: () => {},
|
||||
isMobile: false,
|
||||
};
|
||||
|
||||
/**
|
||||
* Contains the state on how the `Sidebar` is rendered
|
||||
*
|
||||
* @public @deprecated
|
||||
* Use `<SidebarPinStateContextProvider>` + `useSidebarPinState()` instead.
|
||||
*/
|
||||
export const LegacySidebarPinStateContext =
|
||||
createContext<SidebarPinStateContextType>(defaultSidebarPinStateContext);
|
||||
|
||||
const VersionedSidebarPinStateContext = createVersionedContext<{
|
||||
1: SidebarPinStateContextType;
|
||||
}>('sidebar-pin-state-context');
|
||||
@@ -46,11 +61,13 @@ export const SidebarPinStateContextProvider = ({
|
||||
children: ReactNode;
|
||||
value: SidebarPinStateContextType;
|
||||
}) => (
|
||||
<VersionedSidebarPinStateContext.Provider
|
||||
value={createVersionedValueMap({ 1: value })}
|
||||
>
|
||||
{children}
|
||||
</VersionedSidebarPinStateContext.Provider>
|
||||
<LegacySidebarPinStateContext.Provider value={value}>
|
||||
<VersionedSidebarPinStateContext.Provider
|
||||
value={createVersionedValueMap({ 1: value })}
|
||||
>
|
||||
{children}
|
||||
</VersionedSidebarPinStateContext.Provider>
|
||||
</LegacySidebarPinStateContext.Provider>
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -63,11 +80,7 @@ export const useSidebarPinState = (): SidebarPinStateContextType => {
|
||||
|
||||
// Invoked from outside a SidebarPinStateContextProvider: default value.
|
||||
if (versionedSidebarContext === undefined) {
|
||||
return {
|
||||
isPinned: true,
|
||||
toggleSidebarPinState: () => {},
|
||||
isMobile: false,
|
||||
};
|
||||
return defaultSidebarPinStateContext;
|
||||
}
|
||||
|
||||
const sidebarContext = versionedSidebarContext.atVersion(1);
|
||||
|
||||
@@ -48,9 +48,14 @@ export { IntroCard, SidebarIntro } from './Intro';
|
||||
export type { SidebarIntroClassKey } from './Intro';
|
||||
export { SIDEBAR_INTRO_LOCAL_STORAGE, sidebarConfig } from './config';
|
||||
export type { SidebarOptions, SubmenuOptions } from './config';
|
||||
export { SidebarContextProvider, useSidebar } from './SidebarContext';
|
||||
export {
|
||||
LegacySidebarContext as SidebarContext,
|
||||
SidebarContextProvider,
|
||||
useSidebar,
|
||||
} from './SidebarContext';
|
||||
export type { SidebarContextType } from './SidebarContext';
|
||||
export {
|
||||
LegacySidebarPinStateContext as SidebarPinStateContext,
|
||||
SidebarPinStateContextProvider,
|
||||
useSidebarPinState,
|
||||
} from './SidebarPinStateContext';
|
||||
|
||||
Reference in New Issue
Block a user