use attachComponentData instead of displayName in UserSettingsTab

Signed-off-by: Yousif Al-Raheem <yousifalraheem@gmail.com>
This commit is contained in:
yousifalraheem
2022-04-04 14:40:03 +02:00
committed by Yousif Al-Raheem
parent 0d32a893f9
commit 0a0a4fa178
4 changed files with 53 additions and 32 deletions
@@ -20,11 +20,13 @@ import {
SidebarPinStateContext,
TabbedLayout,
} from '@backstage/core-components';
import React, { useContext, ReactElement } from 'react';
import React, { useContext } from 'react';
import { useOutlet } from 'react-router';
import { useElementFilter } from '@backstage/core-plugin-api';
import { UserSettingsAuthProviders } from './AuthProviders';
import { UserSettingsFeatureFlags } from './FeatureFlags';
import { UserSettingsGeneral } from './General';
import { USER_SETTINGS_TAB_KEY, UserSettingsTabProps } from './UserSettingsTab';
type Props = {
providerSettings?: JSX.Element;
@@ -34,16 +36,13 @@ export const SettingsPage = ({ providerSettings }: Props) => {
const { isMobile } = useContext(SidebarPinStateContext);
const outlet = useOutlet();
const extraTabs = (React.Children.toArray(outlet?.props?.children) ||
[]) as Array<ReactElement>;
const notCompliantTab = Array.from(extraTabs).some(
child => (child.type as any)?.displayName !== 'UserSettingsTab',
const tabs = useElementFilter(outlet, elements =>
elements
.selectByComponentData({
key: USER_SETTINGS_TAB_KEY,
})
.getElements<UserSettingsTabProps>(),
);
if (notCompliantTab) {
throw new Error(
'Invalid element passed to SettingsPage Outlet. You may only pass children of type UserSettingsTab.',
);
}
return (
<Page themeId="home">
@@ -62,16 +61,11 @@ export const SettingsPage = ({ providerSettings }: Props) => {
<UserSettingsFeatureFlags />
</TabbedLayout.Route>
{extraTabs.map((child, i) => {
const path: string = child.props.path;
const title: string = child.props.title;
return (
<TabbedLayout.Route key={i} path={path} title={title}>
{child}
</TabbedLayout.Route>
);
})}
{tabs.map((child, i) => (
<TabbedLayout.Route key={i} {...child.props}>
{child}
</TabbedLayout.Route>
))}
</TabbedLayout>
</Page>
);
@@ -13,15 +13,28 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react';
import React, { PropsWithChildren } from 'react';
import { attachComponentData } from '@backstage/core-plugin-api';
interface Props {
export const USER_SETTINGS_TAB_KEY = 'user-settings.tab';
export type UserSettingsTabProps = PropsWithChildren<{
/**
* The path to the tab in the settings route
* @example `/settings/advanced
*/
path: string;
title: React.ReactNode;
}
/** The title of the tab. It will also reflect in the document title when the tab is active */
title: string;
}>;
export const UserSettingsTab: React.FC<Props> = ({ children }) => {
return <>{children}</>;
/**
* Renders a tab inside the settings page
* @param props - Component props
* @public
*/
export const UserSettingsTab = (props: UserSettingsTabProps) => {
return <>{props.children}</>;
};
UserSettingsTab.displayName = 'UserSettingsTab';
attachComponentData(UserSettingsTab, USER_SETTINGS_TAB_KEY, 'UserSettingsTab');