Merge pull request #26479 from stephenglass/star-color

allow custom override for entity star icon
This commit is contained in:
Ben Lambert
2024-09-09 16:56:20 +02:00
committed by GitHub
11 changed files with 51 additions and 13 deletions
+9
View File
@@ -0,0 +1,9 @@
---
'@backstage/core-components': patch
'@backstage/app-defaults': patch
'@backstage/plugin-catalog-react': patch
'@backstage/core-app-api': patch
'@backstage/test-utils': patch
---
Allow custom star icons to be provided via the `star` and `unstarred` icon overrides. See how to override existing icons in the [Backstage documentation](https://backstage.io/docs/getting-started/app-custom-theme/#custom-icons).
@@ -36,6 +36,8 @@ import MuiPersonIcon from '@material-ui/icons/Person';
import MuiWarningIcon from '@material-ui/icons/Warning';
import MuiStorageIcon from '@material-ui/icons/Storage';
import MuiFeaturedPlayListIcon from '@material-ui/icons/FeaturedPlayList';
import Star from '@material-ui/icons/Star';
import StarBorder from '@material-ui/icons/StarBorder';
export const icons = {
brokenImage: MuiBrokenImageIcon as IconComponent,
@@ -62,4 +64,6 @@ export const icons = {
'kind:template': MuiFeaturedPlayListIcon as IconComponent,
user: MuiPersonIcon as IconComponent,
warning: MuiWarningIcon as IconComponent,
star: Star as IconComponent,
unstarred: StarBorder as IconComponent,
};
+2
View File
@@ -196,6 +196,8 @@ export type AppIcons = {
techdocs: IconComponent;
user: IconComponent;
warning: IconComponent;
star: IconComponent;
unstarred: IconComponent;
};
// @public
+2
View File
@@ -115,6 +115,8 @@ export type AppIcons = {
techdocs: IconComponent;
user: IconComponent;
warning: IconComponent;
star: IconComponent;
unstarred: IconComponent;
};
/**
@@ -76,7 +76,7 @@ describe('BackwardsCompatProvider', () => {
expect(screen.getByTestId('ctx').textContent).toMatchInlineSnapshot(`
"plugins: test, app
components: NotFoundErrorPage, BootErrorPage, Progress, Router, ErrorBoundaryFallback
icons: brokenImage, catalog, scaffolder, techdocs, search, chat, dashboard, docs, email, github, group, help, kind:api, kind:component, kind:domain, kind:group, kind:location, kind:system, kind:user, kind:resource, kind:template, user, warning"
icons: brokenImage, catalog, scaffolder, techdocs, search, chat, dashboard, docs, email, github, group, help, kind:api, kind:component, kind:domain, kind:group, kind:location, kind:system, kind:user, kind:resource, kind:template, user, warning, star, unstarred"
`);
});
@@ -120,7 +120,7 @@ describe('ForwardsCompatProvider', () => {
expect(screen.getByTestId('ctx').textContent).toMatchInlineSnapshot(`
"components: progress=true, notFoundErrorPage=true, errorBoundaryFallback=true
icons: kind:api, kind:component, kind:domain, kind:group, kind:location, kind:system, kind:user, kind:resource, kind:template, brokenImage, catalog, scaffolder, techdocs, search, chat, dashboard, docs, email, github, group, help, user, warning"
icons: kind:api, kind:component, kind:domain, kind:group, kind:location, kind:system, kind:user, kind:resource, kind:template, brokenImage, catalog, scaffolder, techdocs, search, chat, dashboard, docs, email, github, group, help, user, warning, star, unstarred"
`);
});
+6
View File
@@ -1205,6 +1205,9 @@ export function SimpleStepperStep(
// @public (undocumented)
export type SimpleStepperStepClassKey = 'end';
// @public (undocumented)
export function StarIcon(props: IconComponentProps): React_2.JSX.Element;
// Warning: (ae-missing-release-tag) "StatusAborted" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
@@ -1474,6 +1477,9 @@ export function TrendLine(
},
): React_2.JSX.Element | null;
// @public (undocumented)
export function UnstarredIcon(props: IconComponentProps): React_2.JSX.Element;
// @public
export function useContent(): {
focusContent: () => void;
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { render } from '@testing-library/react';
import { renderInTestApp } from '@backstage/test-utils';
import { FavoriteToggle } from './FavoriteToggle';
import React from 'react';
import userEvent from '@testing-library/user-event';
@@ -33,20 +33,22 @@ describe('<FavoriteToggle />', () => {
});
it('renders with valid props', async () => {
const { getByRole } = render(<FavoriteToggle {...props} />);
const { getByRole } = await renderInTestApp(<FavoriteToggle {...props} />);
expect(getByRole('button', { name: props.title })).toBeInTheDocument();
});
it('should return inverted value on toggle', async () => {
const { getByRole } = render(<FavoriteToggle {...props} />);
const { getByRole } = await renderInTestApp(<FavoriteToggle {...props} />);
await userEvent.click(getByRole('button', { name: props.title }));
expect(onToggle).toHaveBeenCalledWith(!props.isFavorite);
});
it('should show accessible tooltip', async () => {
const { findByRole, getByRole } = render(<FavoriteToggle {...props} />);
const { findByRole, getByRole } = await renderInTestApp(
<FavoriteToggle {...props} />,
);
await userEvent.hover(getByRole('button', { name: props.title }));
@@ -16,9 +16,9 @@
import React, { ComponentProps } from 'react';
import IconButton from '@material-ui/core/IconButton';
import Tooltip from '@material-ui/core/Tooltip';
import Typography from '@material-ui/core/Typography';
import { Theme, makeStyles } from '@material-ui/core/styles';
import Star from '@material-ui/icons/Star';
import StarBorder from '@material-ui/icons/StarBorder';
import { StarIcon, UnstarredIcon } from '../../icons';
const useStyles = makeStyles<Theme>(
theme => ({
@@ -50,10 +50,13 @@ export function FavoriteToggleIcon(props: { isFavorite: boolean }) {
const { isFavorite } = props;
const classes = useStyles();
return isFavorite ? (
<Star className={classes.icon} />
) : (
<StarBorder className={classes.iconBorder} />
return (
<Typography
component="span"
className={isFavorite ? classes.icon : classes.iconBorder}
>
{isFavorite ? <StarIcon /> : <UnstarredIcon />}
</Typography>
);
}
@@ -95,3 +95,11 @@ export function UserIcon(props: IconComponentProps) {
export function WarningIcon(props: IconComponentProps) {
return <AppIcon id="warning" {...props} />;
}
/** @public */
export function StarIcon(props: IconComponentProps) {
return <AppIcon id="star" {...props} />;
}
/** @public */
export function UnstarredIcon(props: IconComponentProps) {
return <AppIcon id="unstarred" {...props} />;
}
@@ -63,6 +63,8 @@ const mockIcons = {
help: MockIcon,
user: MockIcon,
warning: MockIcon,
star: MockIcon,
unstarred: MockIcon,
};
const ErrorBoundaryFallback = ({ error }: { error: Error }) => {
@@ -28,7 +28,7 @@ import MenuItem from '@material-ui/core/MenuItem';
import Typography from '@material-ui/core/Typography';
import { makeStyles } from '@material-ui/core/styles';
import SettingsIcon from '@material-ui/icons/Settings';
import StarIcon from '@material-ui/icons/Star';
import { StarIcon } from '@backstage/core-components';
import React, { Fragment, useEffect, useMemo, useState } from 'react';
import { EntityUserFilter } from '../../filters';
import { useEntityList } from '../../hooks';