diff --git a/packages/manager/.changeset/pr-11841-changed-1741884096366.md b/packages/manager/.changeset/pr-11841-changed-1741884096366.md new file mode 100644 index 00000000000..f40405718e9 --- /dev/null +++ b/packages/manager/.changeset/pr-11841-changed-1741884096366.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Changed +--- + +Updated Breadcrumb component to conform to Akamai Design System specs ([#11841](https://github.com/linode/manager/pull/11841)) diff --git a/packages/manager/src/components/Breadcrumb/Breadcrumb.stories.tsx b/packages/manager/src/components/Breadcrumb/Breadcrumb.stories.tsx index a50d3a4206f..4edad9d654b 100644 --- a/packages/manager/src/components/Breadcrumb/Breadcrumb.stories.tsx +++ b/packages/manager/src/components/Breadcrumb/Breadcrumb.stories.tsx @@ -1,12 +1,57 @@ import { action } from '@storybook/addon-actions'; import { Meta, StoryObj } from '@storybook/react'; import React from 'react'; +import { Chip } from '@linode/ui'; import { Breadcrumb } from './Breadcrumb'; +const withBadgeCrumbs = [ + { + position: 3, + label: ( + <> + test + + + + + ), + }, +]; + +const noBadgeCrumbs = [ + { + position: 3, + label: test, + }, +]; + const meta: Meta = { component: Breadcrumb, title: 'Foundations/Breadcrumb', + argTypes: { + crumbOverrides: { + options: ['With Badge', 'No Badge'], + mapping: { + 'With Badge': withBadgeCrumbs, + 'No Badge': noBadgeCrumbs, + }, + control: { + type: 'radio', + labels: { + 'With Badge': 'Show Beta Badge', + 'No Badge': 'Hide Beta Badge', + }, + }, + defaultValue: 'No Badge', + }, + }, }; type Story = StoryObj; @@ -20,6 +65,7 @@ export const Default: Story = { onEdit: async () => action('onEdit'), }, pathname: '/linodes/9872893679817/test/lastcrumb', + crumbOverrides: noBadgeCrumbs, }, render: (args) => , }; diff --git a/packages/manager/src/components/Breadcrumb/Crumbs.styles.tsx b/packages/manager/src/components/Breadcrumb/Crumbs.styles.tsx index 241f6705b90..8536c2dffd8 100644 --- a/packages/manager/src/components/Breadcrumb/Crumbs.styles.tsx +++ b/packages/manager/src/components/Breadcrumb/Crumbs.styles.tsx @@ -3,23 +3,24 @@ import { styled } from '@mui/material'; export const StyledTypography = styled(Typography, { label: 'StyledTypography', -})(({}) => ({ +})(({ theme }) => ({ '&:hover': { textDecoration: 'underline', }, - fontSize: '1.125rem', + fontSize: '1rem', lineHeight: 'normal', textTransform: 'capitalize', whiteSpace: 'nowrap', + color: theme.tokens.component.Breadcrumb.LastItem.Text, })); export const StyledSlashTypography = styled(Typography, { label: 'StyledSlashTypography', })(({ theme }) => ({ color: theme.textColors.tableHeader, - fontSize: 20, - marginLeft: 2, - marginRight: 2, + fontSize: 16, + marginLeft: 4, + marginRight: 4, })); export const StyledDiv = styled('div', { label: 'StyledDiv' })({ diff --git a/packages/manager/src/components/Breadcrumb/Crumbs.tsx b/packages/manager/src/components/Breadcrumb/Crumbs.tsx index 174d86166c4..bd8e6585f87 100644 --- a/packages/manager/src/components/Breadcrumb/Crumbs.tsx +++ b/packages/manager/src/components/Breadcrumb/Crumbs.tsx @@ -14,7 +14,7 @@ import type { EditableProps, LabelProps } from './types'; import type { LinkProps } from 'react-router-dom'; export interface CrumbOverridesProps { - label?: string; + label?: string | React.ReactNode; linkTo?: LinkProps['to']; noCap?: boolean; position: number; diff --git a/packages/manager/src/components/Breadcrumb/FinalCrumb.styles.tsx b/packages/manager/src/components/Breadcrumb/FinalCrumb.styles.tsx index af43289b40f..0fd695b3110 100644 --- a/packages/manager/src/components/Breadcrumb/FinalCrumb.styles.tsx +++ b/packages/manager/src/components/Breadcrumb/FinalCrumb.styles.tsx @@ -14,16 +14,16 @@ export const StyledEditableText = styled(EditableText, { '& > div': { width: 250, }, - marginLeft: `-${theme.spacing()}`, })); export const StyledH1Header = styled(H1Header, { label: 'StyledH1Header' })( ({ theme }) => ({ - color: theme.textColors.tableStatic, - fontSize: '1.125rem', + color: theme.tokens.component.Breadcrumb.Normal.Text.Default, + fontSize: '1rem', + paddingLeft: 0, textTransform: 'capitalize', [theme.breakpoints.up('lg')]: { - fontSize: '1.125rem', + fontSize: '1rem', }, }) ); diff --git a/packages/manager/src/components/Breadcrumb/FinalCrumb.tsx b/packages/manager/src/components/Breadcrumb/FinalCrumb.tsx index 729f1222230..f5f011ff4fd 100644 --- a/packages/manager/src/components/Breadcrumb/FinalCrumb.tsx +++ b/packages/manager/src/components/Breadcrumb/FinalCrumb.tsx @@ -38,6 +38,7 @@ export const FinalCrumb = React.memo((props: Props) => { disabledBreadcrumbEditButton={disabledBreadcrumbEditButton} errorText={onEditHandlers.errorText} handleAnalyticsEvent={onEditHandlers.handleAnalyticsEvent} + isBreadcrumb onCancel={onEditHandlers.onCancel} onEdit={onEditHandlers.onEdit} text={onEditHandlers.editableTextTitle} diff --git a/packages/ui/src/components/EditableText/EditableText.tsx b/packages/ui/src/components/EditableText/EditableText.tsx index a19323bc83f..541bab797c9 100644 --- a/packages/ui/src/components/EditableText/EditableText.tsx +++ b/packages/ui/src/components/EditableText/EditableText.tsx @@ -13,7 +13,7 @@ import type { TextFieldProps } from '../TextField'; import type { Theme } from '@mui/material/styles'; import type { PropsWithChildren } from 'react'; -const useStyles = makeStyles()( +const useStyles = makeStyles()( (theme: Theme, _params, classes) => ({ button: { '&[aria-label="Save"]': { @@ -99,6 +99,11 @@ const useStyles = makeStyles()( textDecoration: 'underline !important', }, }, + breadcrumbText: { + color: theme.tokens.component.Breadcrumb.Normal.Text.Default, + fontSize: '1rem !important', + paddingLeft: 0, + }, }) ); @@ -135,6 +140,10 @@ interface BaseProps extends Omit { * Optional suffix to append to the text when it is not in editing mode */ textSuffix?: string; + /** + * Whether this EditableText is used as a breadcrumb + */ + isBreadcrumb?: boolean; } interface PropsWithoutLink extends BaseProps { @@ -163,7 +172,7 @@ interface PropsWithLink extends BaseProps { export type EditableTextProps = PropsWithLink | PropsWithoutLink; export const EditableText = (props: EditableTextProps) => { - const { classes } = useStyles(); + const { classes, cx } = useStyles(); const [isEditing, setIsEditing] = React.useState(Boolean(props.errorText)); const [text, setText] = React.useState(props.text); @@ -173,6 +182,7 @@ export const EditableText = (props: EditableTextProps) => { disabledBreadcrumbEditButton, errorText, handleAnalyticsEvent, + isBreadcrumb, labelLink, onCancel, onEdit, @@ -237,7 +247,7 @@ export const EditableText = (props: EditableTextProps) => { }; const labelText = ( @@ -245,7 +255,7 @@ export const EditableText = (props: EditableTextProps) => { return !isEditing && !errorText ? (
{!!labelLink ? ( @@ -258,7 +268,7 @@ export const EditableText = (props: EditableTextProps) => { {/** pencil icon */}
) : ( -
+