diff --git a/.changeset/honest-teams-shave.md b/.changeset/honest-teams-shave.md new file mode 100644 index 0000000000..c779f20c8f --- /dev/null +++ b/.changeset/honest-teams-shave.md @@ -0,0 +1,8 @@ +--- +'@backstage/plugin-home-react': patch +'@backstage/plugin-home': patch +--- + +Export ContentModal from @backstage/plugin-home-react so people can use this in other scenarios. + +Make QuickStartCard docsLinkTitle prop more flexible to allow for any React.JSX.Element instead of just a string diff --git a/plugins/home-react/report.api.md b/plugins/home-react/report.api.md index c7e847fb36..c5a90553a9 100644 --- a/plugins/home-react/report.api.md +++ b/plugins/home-react/report.api.md @@ -5,9 +5,22 @@ ```ts import { Extension } from '@backstage/core-plugin-api'; import { JSX as JSX_2 } from 'react/jsx-runtime'; +import { JSX as JSX_3 } from 'react'; +import { Overrides } from '@material-ui/core/styles/overrides'; import { RJSFSchema } from '@rjsf/utils'; +import { StyleRules } from '@material-ui/core/styles/withStyles'; import { UiSchema } from '@rjsf/utils'; +// @public (undocumented) +export type BackstageContentModalClassKey = 'contentModal' | 'linkText'; + +// @public (undocumented) +export type BackstageOverrides = Overrides & { + [Name in keyof CatalogReactComponentsNameToClassKey]?: Partial< + StyleRules + >; +}; + // @public (undocumented) export type CardConfig = { layout?: CardLayout; @@ -39,6 +52,11 @@ export type CardSettings = { uiSchema?: UiSchema; }; +// @public (undocumented) +export type CatalogReactComponentsNameToClassKey = { + BackstageContentModal: BackstageContentModalClassKey; +}; + // @public (undocumented) export type ComponentParts = { Content: (props?: any) => JSX.Element; @@ -52,6 +70,15 @@ export type ComponentRenderer = { Renderer?: (props: RendererProps) => JSX.Element; }; +// @public +export const ContentModal: (props: ContentModalProps) => JSX_2.Element; + +// @public +export type ContentModalProps = { + modalContent: JSX_3.Element; + linkContent: string | JSX_3.Element; +}; + // @public export function createCardExtension(options: { title?: string; diff --git a/plugins/home/src/homePageComponents/QuickStart/ContentModal.tsx b/plugins/home-react/src/components/ContentModal.tsx similarity index 69% rename from plugins/home/src/homePageComponents/QuickStart/ContentModal.tsx rename to plugins/home-react/src/components/ContentModal.tsx index ff917f367c..7dfb746390 100644 --- a/plugins/home/src/homePageComponents/QuickStart/ContentModal.tsx +++ b/plugins/home-react/src/components/ContentModal.tsx @@ -1,5 +1,5 @@ /* - * Copyright 2022 The Backstage Authors + * Copyright 2025 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. @@ -18,14 +18,43 @@ import { JSX, useState } from 'react'; import { Link } from '@backstage/core-components'; import Modal from '@material-ui/core/Modal'; import Box from '@material-ui/core/Box'; +import { makeStyles, Theme } from '@material-ui/core/styles'; -import { useStyles } from './styles'; +/** @public */ +export type BackstageContentModalClassKey = 'contentModal' | 'linkText'; +export const useStyles = makeStyles( + (theme: Theme) => ({ + contentModal: { + position: 'absolute', + top: '50%', + left: '50%', + transform: 'translate(-50%, -50%)', + width: '80%', + height: 'auto', + }, + linkText: { + marginBottom: theme.spacing(1.5), + }, + }), + { name: 'BackstageContentModal' }, +); + +/** + * Props customizing the component. + * + * @public + */ export type ContentModalProps = { modalContent: JSX.Element; linkContent: string | JSX.Element; }; +/** + * A component to expand given content into a full screen modal. + * + * @public + */ export const ContentModal = (props: ContentModalProps) => { const { modalContent, linkContent } = props; const styles = useStyles(); diff --git a/plugins/home-react/src/components/index.ts b/plugins/home-react/src/components/index.ts index dce6968b36..9271da0e48 100644 --- a/plugins/home-react/src/components/index.ts +++ b/plugins/home-react/src/components/index.ts @@ -15,3 +15,7 @@ */ export { SettingsModal } from './SettingsModal'; +export { ContentModal } from './ContentModal'; + +export type { BackstageContentModalClassKey } from './ContentModal'; +export type { ContentModalProps } from './ContentModal'; diff --git a/plugins/home-react/src/index.ts b/plugins/home-react/src/index.ts index 1f02ded1c6..54602dc814 100644 --- a/plugins/home-react/src/index.ts +++ b/plugins/home-react/src/index.ts @@ -30,3 +30,4 @@ export type { CardSettings, CardConfig, } from './extensions'; +export * from './overridableComponents'; diff --git a/plugins/home-react/src/overridableComponents.ts b/plugins/home-react/src/overridableComponents.ts new file mode 100644 index 0000000000..8c5dff4465 --- /dev/null +++ b/plugins/home-react/src/overridableComponents.ts @@ -0,0 +1,36 @@ +/* + * Copyright 2025 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 { Overrides } from '@material-ui/core/styles/overrides'; +import { StyleRules } from '@material-ui/core/styles/withStyles'; +import { BackstageContentModalClassKey } from './'; + +/** @public */ +export type CatalogReactComponentsNameToClassKey = { + BackstageContentModal: BackstageContentModalClassKey; +}; + +/** @public */ +export type BackstageOverrides = Overrides & { + [Name in keyof CatalogReactComponentsNameToClassKey]?: Partial< + StyleRules + >; +}; + +declare module '@backstage/theme' { + interface OverrideComponentNameToClassKeys + extends CatalogReactComponentsNameToClassKey {} +} diff --git a/plugins/home/report.api.md b/plugins/home/report.api.md index 7c7f55fd47..0bfa6230e7 100644 --- a/plugins/home/report.api.md +++ b/plugins/home/report.api.md @@ -194,7 +194,7 @@ export const QuickStartCard: ( // @public export type QuickStartCardProps = { modalTitle?: string | JSX_3.Element; - docsLinkTitle?: string; + docsLinkTitle?: string | React.JSX.Element; docsLink?: string; video?: JSX_3.Element; image: JSX_3.Element; diff --git a/plugins/home/src/homePageComponents/QuickStart/Content.tsx b/plugins/home/src/homePageComponents/QuickStart/Content.tsx index 829b9ed191..3cb92f7178 100644 --- a/plugins/home/src/homePageComponents/QuickStart/Content.tsx +++ b/plugins/home/src/homePageComponents/QuickStart/Content.tsx @@ -18,7 +18,7 @@ import { JSX } from 'react'; import { Link } from '@backstage/core-components'; import Typography from '@material-ui/core/Typography'; import Grid from '@material-ui/core/Grid'; -import { ContentModal } from './ContentModal'; +import { ContentModal } from '@backstage/plugin-home-react'; import { useStyles } from './styles'; /** @@ -30,7 +30,7 @@ export type QuickStartCardProps = { /** The modal link title */ modalTitle?: string | JSX.Element; /** The link to docs title */ - docsLinkTitle?: string; + docsLinkTitle?: string | JSX.Element; /** The link to docs */ docsLink?: string; /** The video to play on the card */ diff --git a/plugins/home/src/homePageComponents/QuickStart/QuickStart.stories.tsx b/plugins/home/src/homePageComponents/QuickStart/QuickStart.stories.tsx index 18375c9c27..acc7c5d15e 100644 --- a/plugins/home/src/homePageComponents/QuickStart/QuickStart.stories.tsx +++ b/plugins/home/src/homePageComponents/QuickStart/QuickStart.stories.tsx @@ -18,6 +18,7 @@ import { QuickStartCard } from '../../plugin'; import { ComponentType, PropsWithChildren } from 'react'; import { wrapInTestApp } from '@backstage/test-utils'; import Grid from '@material-ui/core/Grid'; +import OpenInNewIcon from '@material-ui/icons/OpenInNew'; import ContentImage from './static/backstageSystemModel.png'; export default { @@ -65,3 +66,30 @@ export const Customized = () => { ); }; + +export const CustomDocLink = () => { + return ( + + + + Learn more with getting started docs + + } + docsLink="https://backstage.io/docs/getting-started" + image={ + quick start + } + cardDescription="Backstage system model will help you create new entities" + /> + + ); +};