diff --git a/workspaces/theme/.changeset/graduate-nfs-alpha-to-stable.md b/workspaces/theme/.changeset/graduate-nfs-alpha-to-stable.md new file mode 100644 index 00000000000..b48057a4bbb --- /dev/null +++ b/workspaces/theme/.changeset/graduate-nfs-alpha-to-stable.md @@ -0,0 +1,21 @@ +--- +'@red-hat-developer-hub/backstage-plugin-theme': major +--- + +**BREAKING**: Graduated the New Frontend System (NFS) theme module to stable API. + +The NFS `rhdhThemeModule` has been promoted from the `./alpha` subpath to the primary `.` entry point. The `./alpha` subpath has been removed. Legacy (OFS) exports (`getThemes`, `getAllThemes`, `LogoFull`, `LogoIcon`, etc.) have been moved to the new `./legacy` subpath. + +**Migration for NFS consumers (previously using `./alpha`):** + +```diff +- import { rhdhThemeModule } from '@red-hat-developer-hub/backstage-plugin-theme/alpha'; ++ import { rhdhThemeModule } from '@red-hat-developer-hub/backstage-plugin-theme'; +``` + +**Migration for OFS consumers:** + +```diff +- import { getThemes, LogoFull } from '@red-hat-developer-hub/backstage-plugin-theme'; ++ import { getThemes, LogoFull } from '@red-hat-developer-hub/backstage-plugin-theme/legacy'; +``` diff --git a/workspaces/theme/packages/app-legacy/src/App.tsx b/workspaces/theme/packages/app-legacy/src/App.tsx index 298fb845cfe..c71e29fd33f 100644 --- a/workspaces/theme/packages/app-legacy/src/App.tsx +++ b/workspaces/theme/packages/app-legacy/src/App.tsx @@ -59,7 +59,7 @@ import { BCCTestPage } from '@red-hat-developer-hub/backstage-plugin-bcc-test'; import { BUITestPage } from '@red-hat-developer-hub/backstage-plugin-bui-test'; import { MUI4TestPage } from '@red-hat-developer-hub/backstage-plugin-mui4-test'; import { MUI5TestPage } from '@red-hat-developer-hub/backstage-plugin-mui5-test'; -import { getAllThemes } from '@red-hat-developer-hub/backstage-plugin-theme'; +import { getAllThemes } from '@red-hat-developer-hub/backstage-plugin-theme/legacy'; const app = createApp({ apis, diff --git a/workspaces/theme/packages/app-legacy/src/components/Root/Root.tsx b/workspaces/theme/packages/app-legacy/src/components/Root/Root.tsx index be2e3bdb426..b4b46d5188e 100644 --- a/workspaces/theme/packages/app-legacy/src/components/Root/Root.tsx +++ b/workspaces/theme/packages/app-legacy/src/components/Root/Root.tsx @@ -46,7 +46,7 @@ import { NotificationsSidebarItem } from '@backstage/plugin-notifications'; import { LogoFull, LogoIcon, -} from '@red-hat-developer-hub/backstage-plugin-theme'; +} from '@red-hat-developer-hub/backstage-plugin-theme/legacy'; const SidebarLogo = () => { const { isOpen } = useSidebarOpenState(); diff --git a/workspaces/theme/packages/app/src/App.tsx b/workspaces/theme/packages/app/src/App.tsx index 20489390fc3..66380dba1dd 100644 --- a/workspaces/theme/packages/app/src/App.tsx +++ b/workspaces/theme/packages/app/src/App.tsx @@ -16,7 +16,7 @@ import { createApp } from '@backstage/frontend-defaults'; import { navModule } from './modules'; -import { rhdhThemeModule } from '@red-hat-developer-hub/backstage-plugin-theme/alpha'; +import { rhdhThemeModule } from '@red-hat-developer-hub/backstage-plugin-theme'; export default createApp({ features: [navModule, rhdhThemeModule], diff --git a/workspaces/theme/packages/app/src/modules/nav/Sidebar.tsx b/workspaces/theme/packages/app/src/modules/nav/Sidebar.tsx index be0faa1f834..38cf2df19c5 100644 --- a/workspaces/theme/packages/app/src/modules/nav/Sidebar.tsx +++ b/workspaces/theme/packages/app/src/modules/nav/Sidebar.tsx @@ -38,6 +38,7 @@ export const SidebarContent = NavContentBlueprint.make({ // Skipped items nav.take('page:search'); // Using search modal instead + nav.take('page:notifications'); // Using NotificationsSidebarItem instead return ( diff --git a/workspaces/theme/packages/app/src/modules/nav/SidebarLogo.tsx b/workspaces/theme/packages/app/src/modules/nav/SidebarLogo.tsx index 863294fee1d..57017193058 100644 --- a/workspaces/theme/packages/app/src/modules/nav/SidebarLogo.tsx +++ b/workspaces/theme/packages/app/src/modules/nav/SidebarLogo.tsx @@ -22,7 +22,7 @@ import Box from '@mui/material/Box'; import { LogoFull, LogoIcon, -} from '@red-hat-developer-hub/backstage-plugin-theme'; +} from '@red-hat-developer-hub/backstage-plugin-theme/legacy'; export const SidebarLogo = () => { const { isOpen } = useSidebarOpenState(); diff --git a/workspaces/theme/plugins/theme/README.md b/workspaces/theme/plugins/theme/README.md index 40ffd12f8f8..3b06b36ce0b 100644 --- a/workspaces/theme/plugins/theme/README.md +++ b/workspaces/theme/plugins/theme/README.md @@ -8,6 +8,8 @@ a [Storybook test-runner](https://github.com/storybookjs/test-runner) for automa ## API +### Legacy (OFS) — `@red-hat-developer-hub/backstage-plugin-theme/legacy` + Returns all testable themes (incl. the backstage default color scheme and older RHDH versions): - `getAllThemes: () => AppTheme[]` @@ -19,6 +21,21 @@ Returns the latest, not released RHDH light and dark theme for your backstage/RH - `useThemes: () => AppTheme[]` - `useLoaderTheme: () => MUIv5.Theme` +### New Frontend System (NFS) + +NFS is the primary package entry point. OFS (legacy) theme helpers are available at `./legacy`. + +Register the theme module in an NFS app: + +```tsx +import { createApp } from '@backstage/frontend-defaults'; +import { rhdhThemeModule } from '@red-hat-developer-hub/backstage-plugin-theme'; + +export default createApp({ + features: [rhdhThemeModule /* ...other features */], +}); +``` + ## Install dependencies ```shell @@ -46,7 +63,7 @@ On older RHDH instances you can install it: 2. In `packages/app/src/components/DynamicRoot/DynamicRoot.tsx` ```tsx - import { useThemes } from '@red-hat-developer-hub/backstage-plugin-theme'; + import { useThemes } from '@red-hat-developer-hub/backstage-plugin-theme/legacy'; // ... @@ -73,7 +90,7 @@ On older RHDH instances you can install it: 2. Update `packages/app/src/App.tsx` and apply the themes to `createApp`: ```tsx - import { getThemes } from '@red-hat-developer-hub/backstage-plugin-theme'; + import { getThemes } from '@red-hat-developer-hub/backstage-plugin-theme/legacy'; // ... @@ -94,7 +111,7 @@ On older RHDH instances you can install it: 2. Add to your `*/dev/index.tsx`: ```tsx - import { getAllThemes } from '@red-hat-developer-hub/backstage-plugin-theme'; + import { getAllThemes } from '@red-hat-developer-hub/backstage-plugin-theme/legacy'; // ... diff --git a/workspaces/theme/plugins/theme/dev/index.tsx b/workspaces/theme/plugins/theme/dev/index.tsx index eb8843c9974..9f66a01b037 100644 --- a/workspaces/theme/plugins/theme/dev/index.tsx +++ b/workspaces/theme/plugins/theme/dev/index.tsx @@ -43,7 +43,7 @@ import { SidebarSignOutButton, } from '@backstage/dev-utils'; -import { rhdhThemeModule } from '../src/alpha'; +import { rhdhThemeModule } from '../src'; import { ThemeTestPage } from './ThemeTestPage'; const rootRouteRef = createRouteRef({ diff --git a/workspaces/theme/plugins/theme/dev/legacy.tsx b/workspaces/theme/plugins/theme/dev/legacy.tsx index a5d5d1f87d4..6f751a44ef7 100644 --- a/workspaces/theme/plugins/theme/dev/legacy.tsx +++ b/workspaces/theme/plugins/theme/dev/legacy.tsx @@ -15,7 +15,7 @@ */ import { createDevApp } from '@backstage/dev-utils'; -import { getAllThemes } from '../src'; +import { getAllThemes } from '../src/legacyExports'; import { ThemeTestPage } from './ThemeTestPage'; createDevApp() diff --git a/workspaces/theme/plugins/theme/package.json b/workspaces/theme/plugins/theme/package.json index 44c584c5aa7..1a91941896e 100644 --- a/workspaces/theme/plugins/theme/package.json +++ b/workspaces/theme/plugins/theme/package.json @@ -25,13 +25,17 @@ ], "exports": { ".": "./src/index.ts", - "./alpha": "./src/alpha/index.ts", + "./legacy": "./src/legacyExports.ts", + "./rhdh-theme-module": "./src/rhdhThemeModuleExport.ts", "./package.json": "./package.json" }, "typesVersions": { "*": { - "alpha": [ - "src/alpha/index.ts" + "legacy": [ + "src/legacyExports.ts" + ], + "rhdh-theme-module": [ + "src/rhdhThemeModuleExport.ts" ], "package.json": [ "package.json" diff --git a/workspaces/theme/plugins/theme/report-legacy.api.md b/workspaces/theme/plugins/theme/report-legacy.api.md new file mode 100644 index 00000000000..944b6dbe11e --- /dev/null +++ b/workspaces/theme/plugins/theme/report-legacy.api.md @@ -0,0 +1,205 @@ +## API Report File for "@red-hat-developer-hub/backstage-plugin-theme" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { AppTheme } from '@backstage/core-plugin-api'; +import { default as DarkIcon } from '@mui/icons-material/Brightness2Rounded'; +import { JSX as JSX_2 } from 'react/jsx-runtime'; +import { default as LightIcon } from '@mui/icons-material/WbSunnyRounded'; +import { ReactNode } from 'react'; +import { Theme } from '@mui/material'; +import { UnifiedThemeOptions } from '@backstage/theme'; + +// @public (undocumented) +export type BackstageThemePalette = UnifiedThemeOptions['palette']; + +// @public (undocumented) +export interface Branding { + // (undocumented) + theme?: { + [key: string]: ThemeConfig; + }; +} + +// @public (undocumented) +export interface Config { + // (undocumented) + app: { + branding?: Branding; + }; +} + +export { DarkIcon }; + +// @public (undocumented) +export const darkThemeProvider: (props: { + children: ReactNode; +}) => JSX.Element | null; + +// @public (undocumented) +export const getAllThemes: () => AppTheme[]; + +// @public (undocumented) +export const getThemes: () => AppTheme[]; + +export { LightIcon }; + +// @public (undocumented) +export const lightThemeProvider: (props: { + children: ReactNode; +}) => JSX.Element | null; + +// @public (undocumented) +export const LogoFull: (props: React.ComponentProps<'svg'>) => JSX_2.Element; + +// @public (undocumented) +export const LogoIcon: (props: React.ComponentProps<'svg'>) => JSX_2.Element; + +// @public (undocumented) +export interface RHDHThemePalette { + // (undocumented) + cards?: { + headerTextColor: string; + headerBackgroundColor: string; + headerBackgroundImage: string; + }; + // (undocumented) + general: { + pageInset: string; + pageInsetBackgroundColor: string; + disabled: string; + disabledBackground: string; + paperBackgroundImage: string; + paperBorderColor: string; + popoverBoxShadow: string; + cardBackgroundColor: string; + cardBorderColor: string; + mainSectionBackgroundColor: string; + formControlBackgroundColor: string; + sidebarBackgroundColor: string; + sidebarDividerColor: string; + sidebarItemSelectedBackgroundColor: string; + tableTitleColor: string; + tableSubtitleColor: string; + tableColumnTitleColor: string; + tableRowHover: string; + tableBorderColor: string; + tableBackgroundColor: string; + tabsLinkHoverBackgroundColor: string; + contrastText: string; + appBarBackgroundScheme: 'light' | 'dark'; + appBarBackgroundColor: string; + appBarForegroundColor: string; + appBarBackgroundImage: string; + starredItemsColor: string; + }; + // (undocumented) + primary: { + main: string; + focusVisibleBorder: string; + }; + // (undocumented) + secondary: { + main: string; + focusVisibleBorder: string; + }; +} + +// @public (undocumented) +export interface ThemeConfig { + // (undocumented) + defaultPageTheme?: string; + // (undocumented) + fontFamily?: UnifiedThemeOptions['fontFamily']; + // (undocumented) + htmlFontSize?: UnifiedThemeOptions['htmlFontSize']; + mode?: 'light' | 'dark'; + // (undocumented) + options?: ThemeConfigOptions; + // (undocumented) + pageTheme?: Record; + // (undocumented) + palette?: ThemeConfigPalette; + // (undocumented) + typography?: UnifiedThemeOptions['typography']; + variant?: 'rhdh' | 'backstage'; +} + +// @public (undocumented) +export interface ThemeConfigOptions { + // (undocumented) + accordions?: 'patternfly' | 'mui'; + // (undocumented) + appBar?: 'patternfly' | 'mui'; + // (undocumented) + breadcrumbs?: 'patternfly' | 'mui'; + // (undocumented) + buttons?: 'patternfly' | 'mui'; + // (undocumented) + cards?: 'patternfly' | 'mui'; + // (undocumented) + checkbox?: 'patternfly' | 'mui'; + // (undocumented) + components?: 'rhdh' | 'backstage' | 'mui'; + // (undocumented) + dialogs?: 'patternfly' | 'mui'; + // (undocumented) + headers?: 'patternfly' | 'mui'; + // (undocumented) + inputs?: 'patternfly' | 'mui'; + // (undocumented) + pages?: 'patternfly' | 'mui'; + // (undocumented) + paper?: 'patternfly' | 'mui'; + // (undocumented) + rippleEffect?: 'on' | 'off'; + // (undocumented) + sidebars?: 'patternfly' | 'mui'; + // (undocumented) + tables?: 'patternfly' | 'mui'; + // (undocumented) + tabs?: 'patternfly' | 'mui'; + // (undocumented) + toolbars?: 'patternfly' | 'mui'; +} + +// @public (undocumented) +export interface ThemeConfigPageTheme { + // (undocumented) + backgroundColor?: string | string[]; + // (undocumented) + backgroundImage?: string; + // (undocumented) + colors?: string | string[]; + // (undocumented) + fontColor?: string; + // (undocumented) + shape?: string; +} + +// @public (undocumented) +export type ThemeConfigPalette = BackstageThemePalette & { + rhdh?: RHDHThemePalette; +}; + +// @public (undocumented) +export const useAllThemes: () => AppTheme[]; + +// @public (undocumented) +export const useBranding: () => Branding | undefined; + +// @public (undocumented) +export const useLoaderTheme: () => Theme; + +// @public (undocumented) +export const useThemeConfig: (themeName: string) => ThemeConfig; + +// @public +export const useThemeOptions: (themeConfig: ThemeConfig) => UnifiedThemeOptions; + +// @public (undocumented) +export const useThemes: () => AppTheme[]; + +// (No @packageDocumentation comment for this package) +``` diff --git a/workspaces/theme/plugins/theme/report-alpha.api.md b/workspaces/theme/plugins/theme/report-rhdh-theme-module.api.md similarity index 78% rename from workspaces/theme/plugins/theme/report-alpha.api.md rename to workspaces/theme/plugins/theme/report-rhdh-theme-module.api.md index d149c1a2b0e..a9bc5f84b14 100644 --- a/workspaces/theme/plugins/theme/report-alpha.api.md +++ b/workspaces/theme/plugins/theme/report-rhdh-theme-module.api.md @@ -5,8 +5,9 @@ ```ts import { FrontendModule } from '@backstage/frontend-plugin-api'; -// @public (undocumented) -export const rhdhThemeModule: FrontendModule; +// @public +const rhdhThemeModule: FrontendModule; +export default rhdhThemeModule; // (No @packageDocumentation comment for this package) ``` diff --git a/workspaces/theme/plugins/theme/report.api.md b/workspaces/theme/plugins/theme/report.api.md index 944b6dbe11e..a23b12416b8 100644 --- a/workspaces/theme/plugins/theme/report.api.md +++ b/workspaces/theme/plugins/theme/report.api.md @@ -3,203 +3,10 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { AppTheme } from '@backstage/core-plugin-api'; -import { default as DarkIcon } from '@mui/icons-material/Brightness2Rounded'; -import { JSX as JSX_2 } from 'react/jsx-runtime'; -import { default as LightIcon } from '@mui/icons-material/WbSunnyRounded'; -import { ReactNode } from 'react'; -import { Theme } from '@mui/material'; -import { UnifiedThemeOptions } from '@backstage/theme'; - -// @public (undocumented) -export type BackstageThemePalette = UnifiedThemeOptions['palette']; - -// @public (undocumented) -export interface Branding { - // (undocumented) - theme?: { - [key: string]: ThemeConfig; - }; -} - -// @public (undocumented) -export interface Config { - // (undocumented) - app: { - branding?: Branding; - }; -} - -export { DarkIcon }; - -// @public (undocumented) -export const darkThemeProvider: (props: { - children: ReactNode; -}) => JSX.Element | null; - -// @public (undocumented) -export const getAllThemes: () => AppTheme[]; - -// @public (undocumented) -export const getThemes: () => AppTheme[]; - -export { LightIcon }; - -// @public (undocumented) -export const lightThemeProvider: (props: { - children: ReactNode; -}) => JSX.Element | null; - -// @public (undocumented) -export const LogoFull: (props: React.ComponentProps<'svg'>) => JSX_2.Element; - -// @public (undocumented) -export const LogoIcon: (props: React.ComponentProps<'svg'>) => JSX_2.Element; - -// @public (undocumented) -export interface RHDHThemePalette { - // (undocumented) - cards?: { - headerTextColor: string; - headerBackgroundColor: string; - headerBackgroundImage: string; - }; - // (undocumented) - general: { - pageInset: string; - pageInsetBackgroundColor: string; - disabled: string; - disabledBackground: string; - paperBackgroundImage: string; - paperBorderColor: string; - popoverBoxShadow: string; - cardBackgroundColor: string; - cardBorderColor: string; - mainSectionBackgroundColor: string; - formControlBackgroundColor: string; - sidebarBackgroundColor: string; - sidebarDividerColor: string; - sidebarItemSelectedBackgroundColor: string; - tableTitleColor: string; - tableSubtitleColor: string; - tableColumnTitleColor: string; - tableRowHover: string; - tableBorderColor: string; - tableBackgroundColor: string; - tabsLinkHoverBackgroundColor: string; - contrastText: string; - appBarBackgroundScheme: 'light' | 'dark'; - appBarBackgroundColor: string; - appBarForegroundColor: string; - appBarBackgroundImage: string; - starredItemsColor: string; - }; - // (undocumented) - primary: { - main: string; - focusVisibleBorder: string; - }; - // (undocumented) - secondary: { - main: string; - focusVisibleBorder: string; - }; -} - -// @public (undocumented) -export interface ThemeConfig { - // (undocumented) - defaultPageTheme?: string; - // (undocumented) - fontFamily?: UnifiedThemeOptions['fontFamily']; - // (undocumented) - htmlFontSize?: UnifiedThemeOptions['htmlFontSize']; - mode?: 'light' | 'dark'; - // (undocumented) - options?: ThemeConfigOptions; - // (undocumented) - pageTheme?: Record; - // (undocumented) - palette?: ThemeConfigPalette; - // (undocumented) - typography?: UnifiedThemeOptions['typography']; - variant?: 'rhdh' | 'backstage'; -} - -// @public (undocumented) -export interface ThemeConfigOptions { - // (undocumented) - accordions?: 'patternfly' | 'mui'; - // (undocumented) - appBar?: 'patternfly' | 'mui'; - // (undocumented) - breadcrumbs?: 'patternfly' | 'mui'; - // (undocumented) - buttons?: 'patternfly' | 'mui'; - // (undocumented) - cards?: 'patternfly' | 'mui'; - // (undocumented) - checkbox?: 'patternfly' | 'mui'; - // (undocumented) - components?: 'rhdh' | 'backstage' | 'mui'; - // (undocumented) - dialogs?: 'patternfly' | 'mui'; - // (undocumented) - headers?: 'patternfly' | 'mui'; - // (undocumented) - inputs?: 'patternfly' | 'mui'; - // (undocumented) - pages?: 'patternfly' | 'mui'; - // (undocumented) - paper?: 'patternfly' | 'mui'; - // (undocumented) - rippleEffect?: 'on' | 'off'; - // (undocumented) - sidebars?: 'patternfly' | 'mui'; - // (undocumented) - tables?: 'patternfly' | 'mui'; - // (undocumented) - tabs?: 'patternfly' | 'mui'; - // (undocumented) - toolbars?: 'patternfly' | 'mui'; -} - -// @public (undocumented) -export interface ThemeConfigPageTheme { - // (undocumented) - backgroundColor?: string | string[]; - // (undocumented) - backgroundImage?: string; - // (undocumented) - colors?: string | string[]; - // (undocumented) - fontColor?: string; - // (undocumented) - shape?: string; -} - -// @public (undocumented) -export type ThemeConfigPalette = BackstageThemePalette & { - rhdh?: RHDHThemePalette; -}; - -// @public (undocumented) -export const useAllThemes: () => AppTheme[]; - -// @public (undocumented) -export const useBranding: () => Branding | undefined; - -// @public (undocumented) -export const useLoaderTheme: () => Theme; - -// @public (undocumented) -export const useThemeConfig: (themeName: string) => ThemeConfig; +import { FrontendModule } from '@backstage/frontend-plugin-api'; // @public -export const useThemeOptions: (themeConfig: ThemeConfig) => UnifiedThemeOptions; - -// @public (undocumented) -export const useThemes: () => AppTheme[]; +export const rhdhThemeModule: FrontendModule; // (No @packageDocumentation comment for this package) ``` diff --git a/workspaces/theme/plugins/theme/src/alpha/index.ts b/workspaces/theme/plugins/theme/src/alpha/index.ts deleted file mode 100644 index efa589ea5b5..00000000000 --- a/workspaces/theme/plugins/theme/src/alpha/index.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright Red Hat, Inc. - * - * 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. - */ - -/** - * RHDH themes as NFS extensions (ThemeBlueprint). - * Only the app can register ThemeBlueprint; we use the same theme definitions - * from the theme plugin (getAllThemes()) so behavior matches the legacy app. - * - * @packageDocumentation - */ - -import { createFrontendModule } from '@backstage/frontend-plugin-api'; -import { ThemeBlueprint } from '@backstage/plugin-app-react'; - -import '../assets/fonts/font.min.css'; - -import { getAllThemes } from '../themes'; - -const rhdhThemeExtensions = getAllThemes().map(appTheme => - ThemeBlueprint.make({ - name: appTheme.id, - params: { - theme: { - id: appTheme.id, - title: appTheme.title, - variant: appTheme.variant, - icon: appTheme.icon, - Provider: appTheme.Provider, - }, - }, - }), -); - -/* - * @alpha - */ -export const rhdhThemeModule = createFrontendModule({ - pluginId: 'app', - extensions: rhdhThemeExtensions, -}); diff --git a/workspaces/theme/plugins/theme/src/index.ts b/workspaces/theme/plugins/theme/src/index.ts index 5f033c89ba7..8d11c0b599f 100644 --- a/workspaces/theme/plugins/theme/src/index.ts +++ b/workspaces/theme/plugins/theme/src/index.ts @@ -14,21 +14,38 @@ * limitations under the License. */ -export { default as LightIcon } from '@mui/icons-material/WbSunnyRounded'; -export { default as DarkIcon } from '@mui/icons-material/Brightness2Rounded'; +/** + * RHDH Theme plugin for Backstage. + * @packageDocumentation + */ + +import { createFrontendModule } from '@backstage/frontend-plugin-api'; +import { ThemeBlueprint } from '@backstage/plugin-app-react'; import './assets/fonts/font.min.css'; +import { getAllThemes } from './themes'; -export * from './hooks'; -export * from './themes'; -export { LogoFull, LogoIcon } from './components'; -export type { - BackstageThemePalette, - RHDHThemePalette, - ThemeConfigPalette, - ThemeConfigPageTheme, - ThemeConfigOptions, - ThemeConfig, - Branding, - Config, -} from './types'; +/** + * RHDH themes as NFS extensions (ThemeBlueprint). + * Only the app can register ThemeBlueprint; we use the same theme definitions + * from the theme plugin (getAllThemes()) so behavior matches the legacy app. + * + * @public + */ +export const rhdhThemeModule = createFrontendModule({ + pluginId: 'app', + extensions: getAllThemes().map(appTheme => + ThemeBlueprint.make({ + name: appTheme.id, + params: { + theme: { + id: appTheme.id, + title: appTheme.title, + variant: appTheme.variant, + icon: appTheme.icon, + Provider: appTheme.Provider, + }, + }, + }), + ), +}); diff --git a/workspaces/theme/plugins/theme/src/legacyExports.ts b/workspaces/theme/plugins/theme/src/legacyExports.ts new file mode 100644 index 00000000000..5f033c89ba7 --- /dev/null +++ b/workspaces/theme/plugins/theme/src/legacyExports.ts @@ -0,0 +1,34 @@ +/* + * Copyright Red Hat, Inc. + * + * 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 { default as LightIcon } from '@mui/icons-material/WbSunnyRounded'; +export { default as DarkIcon } from '@mui/icons-material/Brightness2Rounded'; + +import './assets/fonts/font.min.css'; + +export * from './hooks'; +export * from './themes'; +export { LogoFull, LogoIcon } from './components'; +export type { + BackstageThemePalette, + RHDHThemePalette, + ThemeConfigPalette, + ThemeConfigPageTheme, + ThemeConfigOptions, + ThemeConfig, + Branding, + Config, +} from './types'; diff --git a/workspaces/theme/plugins/theme/src/nfsExports.test.tsx b/workspaces/theme/plugins/theme/src/nfsExports.test.tsx new file mode 100644 index 00000000000..5f282631660 --- /dev/null +++ b/workspaces/theme/plugins/theme/src/nfsExports.test.tsx @@ -0,0 +1,23 @@ +/* + * Copyright Red Hat, Inc. + * + * 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 { rhdhThemeModule } from './index'; + +describe('theme NFS exports', () => { + it('should export rhdhThemeModule', () => { + expect(rhdhThemeModule).toBeDefined(); + }); +}); diff --git a/workspaces/theme/plugins/theme/src/rhdhThemeModuleExport.ts b/workspaces/theme/plugins/theme/src/rhdhThemeModuleExport.ts new file mode 100644 index 00000000000..4a11eebe4e3 --- /dev/null +++ b/workspaces/theme/plugins/theme/src/rhdhThemeModuleExport.ts @@ -0,0 +1,17 @@ +/* + * Copyright Red Hat, Inc. + * + * 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 { rhdhThemeModule as default } from './index';