diff --git a/packages/core/src/layout/Header/Header.stories.tsx b/packages/core/src/layout/Header/Header.stories.tsx index f4ca74d3f8..62e6e3e52c 100644 --- a/packages/core/src/layout/Header/Header.stories.tsx +++ b/packages/core/src/layout/Header/Header.stories.tsx @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { pageTheme } from '@backstage/theme'; import React from 'react'; import { Header } from '.'; import { HeaderLabel } from '../HeaderLabel'; @@ -33,7 +32,7 @@ const labels = ( ); export const Home = () => ( - +
{labels}
@@ -47,7 +46,7 @@ export const HomeWithSubtitle = () => ( ); export const Tool = () => ( - +
{labels}
@@ -55,7 +54,7 @@ export const Tool = () => ( ); export const Service = () => ( - +
{labels}
@@ -63,7 +62,7 @@ export const Service = () => ( ); export const Website = () => ( - +
{labels}
@@ -71,7 +70,7 @@ export const Website = () => ( ); export const Library = () => ( - +
{labels}
@@ -79,7 +78,7 @@ export const Library = () => ( ); export const App = () => ( - +
{labels}
@@ -87,7 +86,7 @@ export const App = () => ( ); export const Documentation = () => ( - +
{labels}
@@ -95,7 +94,7 @@ export const Documentation = () => ( ); export const Other = () => ( - +
{labels}
diff --git a/packages/core/src/layout/Page/Page.stories.tsx b/packages/core/src/layout/Page/Page.stories.tsx index 882b989bae..b3a75c19e9 100644 --- a/packages/core/src/layout/Page/Page.stories.tsx +++ b/packages/core/src/layout/Page/Page.stories.tsx @@ -15,7 +15,6 @@ */ import React, { useState } from 'react'; -import { pageTheme } from '@backstage/theme'; import { Header, Page, @@ -196,7 +195,7 @@ export const PluginWithData = () => { const [selectedTab, setSelectedTab] = useState(2); return (
- + { export const PluginWithTable = () => { return (
- + diff --git a/packages/core/src/layout/Page/Page.tsx b/packages/core/src/layout/Page/Page.tsx index 4bc1917659..a14f772334 100644 --- a/packages/core/src/layout/Page/Page.tsx +++ b/packages/core/src/layout/Page/Page.tsx @@ -15,7 +15,7 @@ */ import React, { FC } from 'react'; -import { PageTheme } from '@backstage/theme'; +import { BackstageTheme } from '@backstage/theme'; import { makeStyles, ThemeProvider } from '@material-ui/core'; const useStyles = makeStyles(() => ({ @@ -30,13 +30,18 @@ const useStyles = makeStyles(() => ({ })); type Props = { - theme: PageTheme; + themeId: string; }; -export const Page: FC = ({ theme, children }) => { +export const Page: FC = ({ themeId, children }) => { const classes = useStyles(); return ( - ({ ...baseTheme, page: theme })}> + ({ + ...baseTheme, + page: baseTheme.getPageTheme({ themeId }), + })} + >
{children}
); diff --git a/packages/core/src/layout/SignInPage/SignInPage.tsx b/packages/core/src/layout/SignInPage/SignInPage.tsx index b2b049d161..ebc9bf278f 100644 --- a/packages/core/src/layout/SignInPage/SignInPage.tsx +++ b/packages/core/src/layout/SignInPage/SignInPage.tsx @@ -19,8 +19,7 @@ import { Page } from '../Page'; import { Header } from '../Header'; import { Content } from '../Content/Content'; import { ContentHeader } from '../ContentHeader/ContentHeader'; -import { BackstageTheme } from '@backstage/theme'; -import { Grid, useTheme } from '@material-ui/core'; +import { Grid } from '@material-ui/core'; import { SignInPageProps, useApi, configApiRef } from '@backstage/core-api'; import { useSignInProviders, getSignInProviders } from './providers'; import { IdentityProviders } from './types'; @@ -39,7 +38,6 @@ export const SignInPage: FC = ({ title, align = 'left', }) => { - const backstageTheme = useTheme(); const configApi = useApi(configApiRef); const classes = useStyles(); @@ -54,7 +52,7 @@ export const SignInPage: FC = ({ } return ( - +
{title && } diff --git a/plugins/api-docs/src/components/ApiEntityPage/ApiEntityPage.tsx b/plugins/api-docs/src/components/ApiEntityPage/ApiEntityPage.tsx index 85250a8569..f755705ac7 100644 --- a/plugins/api-docs/src/components/ApiEntityPage/ApiEntityPage.tsx +++ b/plugins/api-docs/src/components/ApiEntityPage/ApiEntityPage.tsx @@ -23,9 +23,8 @@ import { Progress, useApi, } from '@backstage/core'; -import { BackstageTheme } from '@backstage/theme'; import { catalogApiRef } from '@backstage/plugin-catalog'; -import { Box, useTheme } from '@material-ui/core'; +import { Box } from '@material-ui/core'; import { Alert } from '@material-ui/lab'; import React, { useEffect } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; @@ -65,7 +64,6 @@ const EntityPageTitle = ({ title }: EntityPageTitleProps) => ( ); export const ApiEntityPage = () => { - const backstageTheme = useTheme(); const { optionalNamespaceAndName } = useParams() as { optionalNamespaceAndName: string; }; @@ -102,11 +100,7 @@ export const ApiEntityPage = () => { ); return ( - +
} pageTitleOverride={headerTitle} diff --git a/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerLayout.tsx b/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerLayout.tsx index 410432d715..b534489487 100644 --- a/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerLayout.tsx +++ b/plugins/api-docs/src/components/ApiExplorerPage/ApiExplorerLayout.tsx @@ -15,8 +15,6 @@ */ import { Header, Page } from '@backstage/core'; -import { BackstageTheme } from '@backstage/theme'; -import { useTheme } from '@material-ui/core'; import React from 'react'; type Props = { @@ -24,14 +22,8 @@ type Props = { }; export const ApiExplorerLayout = ({ children }: Props) => { - const backstageTheme = useTheme(); - return ( - +
{ - const backstageTheme = useTheme(); const greeting = getTimeBasedGreeting(); const profile = useApi(identityApiRef).getProfile(); const userId = useApi(identityApiRef).getUserId(); return ( - +
{ - const backstageTheme = useTheme(); const { optionalNamespaceAndName, kind } = useParams() as { optionalNamespaceAndName: string; kind: string; @@ -89,11 +87,7 @@ export const EntityPageLayout = ({ const showRemovalDialog = () => setConfirmationDialogOpen(true); return ( - +
} pageTitleOverride={headerTitle} diff --git a/plugins/cost-insights/src/components/AlertInstructionsLayout/AlertInstructionsLayout.tsx b/plugins/cost-insights/src/components/AlertInstructionsLayout/AlertInstructionsLayout.tsx index f4baf227db..82954baa86 100644 --- a/plugins/cost-insights/src/components/AlertInstructionsLayout/AlertInstructionsLayout.tsx +++ b/plugins/cost-insights/src/components/AlertInstructionsLayout/AlertInstructionsLayout.tsx @@ -14,15 +14,8 @@ * limitations under the License. */ -import { BackstageTheme } from '@backstage/theme'; import React, { ReactNode } from 'react'; -import { - Box, - Button, - Container, - makeStyles, - useTheme, -} from '@material-ui/core'; +import { Box, Button, Container, makeStyles } from '@material-ui/core'; import ChevronLeftIcon from '@material-ui/icons/ChevronLeft'; import { Header, Page } from '@backstage/core'; import { CostInsightsThemeProvider } from '../CostInsightsPage/CostInsightsThemeProvider'; @@ -44,13 +37,12 @@ const AlertInstructionsLayout = ({ title, children, }: AlertInstructionsLayoutProps) => { - const backstageTheme = useTheme(); const classes = useStyles(); return ( - +
{ - const backstageTheme = useTheme(); const classes = useStyles(); return ( - +
{ const classes = useStyles(); - const backstageTheme = useTheme(); return ( - +
{ @@ -112,14 +111,8 @@ const labels = ( ); export const NewProjectPage = () => { - const backstageTheme = useTheme(); - return ( - +
{labels}
diff --git a/plugins/gcp-projects/src/components/ProjectDetailsPage/ProjectDetailsPage.tsx b/plugins/gcp-projects/src/components/ProjectDetailsPage/ProjectDetailsPage.tsx index eb86b6fd03..7e44618441 100644 --- a/plugins/gcp-projects/src/components/ProjectDetailsPage/ProjectDetailsPage.tsx +++ b/plugins/gcp-projects/src/components/ProjectDetailsPage/ProjectDetailsPage.tsx @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { BackstageTheme } from '@backstage/theme'; import { Content, ContentHeader, @@ -36,7 +35,6 @@ import { TableRow, Theme, Typography, - useTheme, } from '@material-ui/core'; import React from 'react'; import { useAsync } from 'react-use'; @@ -148,13 +146,8 @@ const labels = ( ); export const ProjectDetailsPage = () => { - const backstageTheme = useTheme(); return ( - +
{labels}
diff --git a/plugins/gcp-projects/src/components/ProjectListPage/ProjectListPage.tsx b/plugins/gcp-projects/src/components/ProjectListPage/ProjectListPage.tsx index 33b3813c2a..b2148bcfc8 100644 --- a/plugins/gcp-projects/src/components/ProjectListPage/ProjectListPage.tsx +++ b/plugins/gcp-projects/src/components/ProjectListPage/ProjectListPage.tsx @@ -15,7 +15,6 @@ */ // NEEDS WORK -import { BackstageTheme } from '@backstage/theme'; import { Content, ContentHeader, @@ -38,7 +37,6 @@ import { TableRow, Tooltip, Typography, - useTheme, } from '@material-ui/core'; import React from 'react'; import { useAsync } from 'react-use'; @@ -135,14 +133,8 @@ const PageContents = () => { }; export const ProjectListPage = () => { - const backstageTheme = useTheme(); - return ( - +
{labels}
diff --git a/plugins/gitops-profiles/src/components/ClusterList/ClusterList.tsx b/plugins/gitops-profiles/src/components/ClusterList/ClusterList.tsx index 3b33320abe..70bf4c8c3f 100644 --- a/plugins/gitops-profiles/src/components/ClusterList/ClusterList.tsx +++ b/plugins/gitops-profiles/src/components/ClusterList/ClusterList.tsx @@ -14,7 +14,6 @@ * limitations under the License. */ -import { BackstageTheme } from '@backstage/theme'; import React, { FC, useState } from 'react'; import { Content, @@ -29,13 +28,12 @@ import { } from '@backstage/core'; import ClusterTable from '../ClusterTable/ClusterTable'; -import { Button, useTheme } from '@material-ui/core'; +import { Button } from '@material-ui/core'; import { useAsync } from 'react-use'; import { gitOpsApiRef } from '../../api'; import { Alert } from '@material-ui/lab'; const ClusterList: FC<{}> = () => { - const backstageTheme = useTheme(); const api = useApi(gitOpsApiRef); const githubAuth = useApi(githubAuthApiRef); const [githubUsername, setGithubUsername] = useState(String); @@ -92,11 +90,7 @@ const ClusterList: FC<{}> = () => { } return ( - +
diff --git a/plugins/gitops-profiles/src/components/ClusterPage/ClusterPage.tsx b/plugins/gitops-profiles/src/components/ClusterPage/ClusterPage.tsx index f7205c3326..9b6e5bdb08 100644 --- a/plugins/gitops-profiles/src/components/ClusterPage/ClusterPage.tsx +++ b/plugins/gitops-profiles/src/components/ClusterPage/ClusterPage.tsx @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { BackstageTheme } from '@backstage/theme'; import React, { FC, useEffect, useState } from 'react'; import { Content, @@ -26,13 +25,12 @@ import { githubAuthApiRef, } from '@backstage/core'; -import { Link, useTheme } from '@material-ui/core'; +import { Link } from '@material-ui/core'; import { useParams } from 'react-router-dom'; import { gitOpsApiRef, Status } from '../../api'; import { transformRunStatus } from '../ProfileCatalog'; const ClusterPage: FC<{}> = () => { - const backstageTheme = useTheme(); const params = useParams() as { owner: string; repo: string }; const [pollingLog, setPollingLog] = useState(true); @@ -85,11 +83,7 @@ const ClusterPage: FC<{}> = () => { }, [pollingLog, api, params, githubAuth, githubAccessToken, githubUsername]); return ( - +
diff --git a/plugins/gitops-profiles/src/components/ProfileCatalog/ProfileCatalog.tsx b/plugins/gitops-profiles/src/components/ProfileCatalog/ProfileCatalog.tsx index fe1e97235a..a70cf97342 100644 --- a/plugins/gitops-profiles/src/components/ProfileCatalog/ProfileCatalog.tsx +++ b/plugins/gitops-profiles/src/components/ProfileCatalog/ProfileCatalog.tsx @@ -14,7 +14,6 @@ * limitations under the License. */ -import { BackstageTheme } from '@backstage/theme'; import React, { FC, useEffect, useState } from 'react'; import { Header, @@ -37,7 +36,7 @@ import { useApi, githubAuthApiRef, } from '@backstage/core'; -import { TextField, List, ListItem, Link, useTheme } from '@material-ui/core'; +import { TextField, List, ListItem, Link } from '@material-ui/core'; import ClusterTemplateCardList from '../ClusterTemplateCardList'; import ProfileCardList from '../ProfileCardList'; @@ -81,8 +80,6 @@ export const transformRunStatus = (x: Status[]) => { }; const ProfileCatalog: FC<{}> = () => { - const backstageTheme = useTheme(); - // TODO: get data from REST API const [clusterTemplates] = React.useState([ { @@ -261,11 +258,7 @@ const ProfileCatalog: FC<{}> = () => { ]; return ( - +
{ - const backstageTheme = useTheme(); const graphQlBrowseApi = useApi(graphQlBrowseApiRef); const endpoints = useAsync(() => graphQlBrowseApi.getEndpoints()); @@ -60,11 +58,7 @@ export const GraphiQLPage = () => { } return ( - +
diff --git a/plugins/kubernetes/src/components/KubernetesContent/KubernetesContent.tsx b/plugins/kubernetes/src/components/KubernetesContent/KubernetesContent.tsx index 451383df58..a3e82e79a4 100644 --- a/plugins/kubernetes/src/components/KubernetesContent/KubernetesContent.tsx +++ b/plugins/kubernetes/src/components/KubernetesContent/KubernetesContent.tsx @@ -14,9 +14,8 @@ * limitations under the License. */ -import { BackstageTheme } from '@backstage/theme'; import React, { ReactElement, useEffect, useState } from 'react'; -import { Grid, TabProps, useTheme } from '@material-ui/core'; +import { Grid, TabProps } from '@material-ui/core'; import { Config } from '@backstage/config'; import { CardTab, @@ -102,7 +101,6 @@ const groupResponses = (fetchResponse: FetchResponse[]) => { type KubernetesContentProps = { entity: Entity; children?: React.ReactNode }; export const KubernetesContent = ({ entity }: KubernetesContentProps) => { - const backstageTheme = useTheme(); const kubernetesApi = useApi(kubernetesApiRef); const [kubernetesObjects, setKubernetesObjects] = useState< @@ -149,11 +147,7 @@ export const KubernetesContent = ({ entity }: KubernetesContentProps) => { kubernetesObjects?.items.filter(r => r.errors.length > 0) ?? []; return ( - + {kubernetesObjects === undefined && error === undefined && ( diff --git a/plugins/lighthouse/src/components/AuditList/index.tsx b/plugins/lighthouse/src/components/AuditList/index.tsx index cae1761ecb..117a40a901 100644 --- a/plugins/lighthouse/src/components/AuditList/index.tsx +++ b/plugins/lighthouse/src/components/AuditList/index.tsx @@ -13,11 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { BackstageTheme } from '@backstage/theme'; import React, { useState, useMemo, FC, ReactNode } from 'react'; import { useLocalStorage, useAsync } from 'react-use'; import { useNavigate } from 'react-router-dom'; -import { Grid, Button, useTheme } from '@material-ui/core'; +import { Grid, Button } from '@material-ui/core'; import Alert from '@material-ui/lab/Alert'; import Pagination from '@material-ui/lab/Pagination'; import { @@ -41,7 +40,6 @@ import { createAuditRouteRef } from '../../plugin'; export const LIMIT = 10; const AuditList: FC<{}> = () => { - const backstageTheme = useTheme(); const [dismissedStored] = useLocalStorage(LIGHTHOUSE_INTRO_LOCAL_STORAGE); const [dismissed, setDismissed] = useState(dismissedStored); @@ -95,11 +93,7 @@ const AuditList: FC<{}> = () => { } return ( - +
= () => { }; const ConnectedAuditView = () => { - const backstageTheme = useTheme(); return ( - +
= () => { }; const CreateAudit = () => { - const backstageTheme = useTheme(); return ( - +
= () => { - const backstageTheme = useTheme(); return ( - +
diff --git a/plugins/register-component/src/components/RegisterComponentPage/RegisterComponentPage.tsx b/plugins/register-component/src/components/RegisterComponentPage/RegisterComponentPage.tsx index 722e2e1964..cd3eb1adbb 100644 --- a/plugins/register-component/src/components/RegisterComponentPage/RegisterComponentPage.tsx +++ b/plugins/register-component/src/components/RegisterComponentPage/RegisterComponentPage.tsx @@ -14,9 +14,8 @@ * limitations under the License. */ -import { BackstageTheme } from '@backstage/theme'; import React, { useState } from 'react'; -import { Grid, makeStyles, useTheme } from '@material-ui/core'; +import { Grid, makeStyles } from '@material-ui/core'; import { InfoCard, Page, @@ -61,7 +60,6 @@ export const RegisterComponentPage = ({ }: { catalogRouteRef: RouteRef; }) => { - const backstageTheme = useTheme(); const classes = useStyles(); const catalogApi = useApi(catalogApiRef); const [formState, setFormState] = useState>( @@ -114,11 +112,7 @@ export const RegisterComponentPage = ({ }; return ( - +
diff --git a/plugins/rollbar/src/components/RollbarHome/RollbarHome.tsx b/plugins/rollbar/src/components/RollbarHome/RollbarHome.tsx index f219be9615..fe99e70575 100644 --- a/plugins/rollbar/src/components/RollbarHome/RollbarHome.tsx +++ b/plugins/rollbar/src/components/RollbarHome/RollbarHome.tsx @@ -14,23 +14,16 @@ * limitations under the License. */ -import { BackstageTheme } from '@backstage/theme'; -import { useTheme } from '@material-ui/core'; import React from 'react'; import { Content, Header, Page } from '@backstage/core'; import { RollbarProjectTable } from '../RollbarProjectTable/RollbarProjectTable'; import { useRollbarEntities } from '../../hooks/useRollbarEntities'; export const RollbarHome = () => { - const backstageTheme = useTheme(); const { entities, loading, error } = useRollbarEntities(); return ( - +
{ - const backstageTheme = useTheme(); const { entity } = useCatalogEntity(); return ( - +
diff --git a/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx b/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx index bd70fd9565..d0cb25f254 100644 --- a/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx +++ b/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx @@ -14,7 +14,6 @@ * limitations under the License. */ -import { BackstageTheme } from '@backstage/theme'; import { TemplateEntityV1alpha1 } from '@backstage/catalog-model'; import { Content, @@ -29,7 +28,7 @@ import { WarningPanel, } from '@backstage/core'; import { catalogApiRef } from '@backstage/plugin-catalog'; -import { Button, Grid, Link, Typography, useTheme } from '@material-ui/core'; +import { Button, Grid, Link, Typography } from '@material-ui/core'; import React, { useEffect } from 'react'; import { Link as RouterLink } from 'react-router-dom'; import useStaleWhileRevalidate from 'swr'; @@ -49,7 +48,6 @@ const getTemplateCardProps = ( }; export const ScaffolderPage = () => { - const backstageTheme = useTheme(); const catalogApi = useApi(catalogApiRef); const errorApi = useApi(errorApiRef); @@ -67,7 +65,7 @@ export const ScaffolderPage = () => { }, [error, errorApi]); return ( - +
{ - const backstageTheme = useTheme(); const errorApi = useApi(errorApiRef); const catalogApi = useApi(catalogApiRef); const scaffolderApi = useApi(scaffolderApiRef); @@ -146,7 +144,7 @@ export const TemplatePage = () => { } return ( - +
= () => { - const backstageTheme = useTheme(); const [statsFor, setStatsFor] = useState<'12h' | '24h'>('12h'); const toggleStatsFor = () => setStatsFor(statsFor === '12h' ? '12h' : '24h'); const sentryProjectId = 'sample-sentry-project-id'; return ( - +
diff --git a/plugins/tech-radar/src/components/RadarPage.tsx b/plugins/tech-radar/src/components/RadarPage.tsx index d23061b094..d5c4355b0e 100644 --- a/plugins/tech-radar/src/components/RadarPage.tsx +++ b/plugins/tech-radar/src/components/RadarPage.tsx @@ -14,9 +14,8 @@ * limitations under the License. */ -import { BackstageTheme } from '@backstage/theme'; import React from 'react'; -import { Grid, useTheme } from '@material-ui/core'; +import { Grid } from '@material-ui/core'; import { Content, ContentHeader, @@ -40,13 +39,8 @@ export const RadarPage = ({ pageTitle, ...props }: TechRadarPageProps): JSX.Element => { - const backstageTheme = useTheme(); return ( - +
diff --git a/plugins/techdocs/src/reader/components/TechDocsHome.tsx b/plugins/techdocs/src/reader/components/TechDocsHome.tsx index 016f6df4f0..0408a540ca 100644 --- a/plugins/techdocs/src/reader/components/TechDocsHome.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsHome.tsx @@ -14,11 +14,10 @@ * limitations under the License. */ -import { BackstageTheme } from '@backstage/theme'; import React from 'react'; import { useAsync } from 'react-use'; import { useNavigate, generatePath } from 'react-router-dom'; -import { Grid, useTheme } from '@material-ui/core'; +import { Grid } from '@material-ui/core'; import { ItemCard, Progress, @@ -31,7 +30,6 @@ import { catalogApiRef } from '@backstage/plugin-catalog'; import { rootDocsRouteRef } from '../../plugin'; export const TechDocsHome = () => { - const backstageTheme = useTheme(); const catalogApi = useApi(catalogApiRef); const navigate = useNavigate(); @@ -44,11 +42,7 @@ export const TechDocsHome = () => { if (loading) { return ( - +
{ if (error) { return ( - +
{ } return ( - +
{ - const backstageTheme = useTheme(); const [documentReady, setDocumentReady] = useState(false); const { namespace, kind, name } = useParams(); @@ -48,11 +45,7 @@ export const TechDocsPage = () => { }; return ( - + { - const backstageTheme = useTheme(); const [activeTab, setActiveTab] = useState(0); const onTabChange = (index: number) => { setActiveTab(index); @@ -46,11 +43,7 @@ export const SettingsPage = ({ providerSettings }: Props) => { ]; return ( - +
{content[activeTab]} diff --git a/plugins/welcome/src/components/WelcomePage/WelcomePage.tsx b/plugins/welcome/src/components/WelcomePage/WelcomePage.tsx index 7c68ab96bf..7b94024948 100644 --- a/plugins/welcome/src/components/WelcomePage/WelcomePage.tsx +++ b/plugins/welcome/src/components/WelcomePage/WelcomePage.tsx @@ -14,7 +14,6 @@ * limitations under the License. */ -import { BackstageTheme } from '@backstage/theme'; import React from 'react'; import { Link as RouterLink } from 'react-router-dom'; import { @@ -24,7 +23,6 @@ import { ListItem, ListItemText, Link, - useTheme, } from '@material-ui/core'; import { Content, @@ -40,17 +38,12 @@ import { } from '@backstage/core'; const WelcomePage = () => { - const backstageTheme = useTheme(); const appTitle = useApi(configApiRef).getOptionalString('app.title') ?? 'Backstage'; const profile = { givenName: '' }; return ( - +