Skip to content

Commit 518a20a

Browse files
fix(homepage): add external link icon to Read documentation button an… (#1314)
* fix(homepage): add external link icon to Read documentation button and updated greetings * fix(homepage): add padding and made endicon more generic * add unit tests
1 parent 0dd7b78 commit 518a20a

6 files changed

Lines changed: 63 additions & 8 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@red-hat-developer-hub/backstage-plugin-dynamic-home-page': patch
3+
---
4+
5+
Added external link icon to Read documentaion and updated homepage greetings

workspaces/homepage/plugins/dynamic-home-page/src/components/OnboardingSection/OnboardingCard.test.tsx

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ describe('OnboardingCard', () => {
3636
buttonText: 'Learn More',
3737
buttonLink: '/docs',
3838
target: '_blank',
39+
ariaLabel: 'Learn more about getting started',
40+
endIcon: null,
3941
};
4042

4143
const renderWithTheme = (ui: ReactElement) => {
@@ -67,9 +69,31 @@ describe('OnboardingCard', () => {
6769
expect(link).toHaveAttribute('target', '_blank');
6870
});
6971

70-
it('should render the ArrowForwardIcon', () => {
72+
it('should render custom icon when provided', () => {
73+
const CustomIcon = () => <div data-testid="custom-icon">Custom</div>;
74+
const propsWithIcon = { ...mockProps, endIcon: <CustomIcon /> };
75+
76+
renderWithTheme(<OnboardingCard {...propsWithIcon} />);
77+
78+
expect(screen.getByTestId('custom-icon')).toBeInTheDocument();
79+
});
80+
81+
it('should apply aria-label when provided', () => {
7182
renderWithTheme(<OnboardingCard {...mockProps} />);
72-
const icon = screen.getByTestId('ArrowForwardIcon');
73-
expect(icon).toBeInTheDocument();
83+
const link = screen.getByRole('link', { name: /Learn More/i });
84+
85+
expect(link).toHaveAttribute(
86+
'aria-label',
87+
'Learn more about getting started',
88+
);
89+
});
90+
91+
it('should not apply aria-label when not provided', () => {
92+
const { ariaLabel, ...propsWithoutAriaLabel } = mockProps;
93+
94+
renderWithTheme(<OnboardingCard {...propsWithoutAriaLabel} />);
95+
const link = screen.getByRole('link', { name: /Learn More/i });
96+
97+
expect(link).not.toHaveAttribute('aria-label');
7498
});
7599
});

workspaces/homepage/plugins/dynamic-home-page/src/components/OnboardingSection/OnboardingCard.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import { Link as RouterLink } from 'react-router-dom';
1818

1919
import Box from '@mui/material/Box';
2020
import CardContent from '@mui/material/CardContent';
21-
import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
2221
import Button from '@mui/material/Button';
2322
import Typography from '@mui/material/Typography';
2423

@@ -29,6 +28,7 @@ interface OnboardingCardProps {
2928
buttonLink: string;
3029
target?: string;
3130
ariaLabel?: string;
31+
endIcon: React.ReactNode;
3232
}
3333

3434
const OnboardingCard: FC<OnboardingCardProps> = ({
@@ -38,6 +38,7 @@ const OnboardingCard: FC<OnboardingCardProps> = ({
3838
buttonLink,
3939
target,
4040
ariaLabel,
41+
endIcon,
4142
}) => {
4243
return (
4344
<Box>
@@ -78,9 +79,13 @@ const OnboardingCard: FC<OnboardingCardProps> = ({
7879
sx={{
7980
padding: theme => theme.spacing(1, 1.5),
8081
fontSize: '16px',
82+
'& .v5-MuiButton-endIcon': {
83+
marginRight: 0,
84+
},
8185
}}
86+
endIcon={endIcon}
8287
>
83-
{buttonText} <ArrowForwardIcon style={{ paddingLeft: '0.5rem' }} />
88+
{buttonText}{' '}
8489
</Button>
8590
</CardContent>
8691
</Box>

workspaces/homepage/plugins/dynamic-home-page/src/components/OnboardingSection/OnboardingSection.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import HomePageIllustrationDark from '../../images/homepage-illustration-dark.sv
3131
import HomePageIllustrationLight from '../../images/homepage-illustration-light.svg';
3232
import { LEARNING_SECTION_ITEMS } from '../../utils/constants';
3333
import useGreeting from '../../hooks/useGreeting';
34+
import { LearningSectionItem } from '../../types';
3435

3536
export const OnboardingSection = () => {
3637
const [user, setUser] = useState<string | null>();
@@ -99,7 +100,7 @@ export const OnboardingSection = () => {
99100
}}
100101
/>
101102
</Grid>
102-
{LEARNING_SECTION_ITEMS.map(item => (
103+
{LEARNING_SECTION_ITEMS.map((item: LearningSectionItem) => (
103104
<Grid
104105
item
105106
xs={12}
@@ -117,6 +118,7 @@ export const OnboardingSection = () => {
117118
buttonLink={item.buttonLink}
118119
target={item.target}
119120
ariaLabel={item.ariaLabel}
121+
endIcon={<item.endIcon />}
120122
/>
121123
</Grid>
122124
))}
@@ -143,7 +145,7 @@ export const OnboardingSection = () => {
143145
fontSize: '1.5rem',
144146
}}
145147
>
146-
{`${greeting} ${profileDisplayName() || 'Guest'}!`}
148+
{`${greeting}, ${profileDisplayName() || 'Guest'}!`}
147149
</Typography>
148150
)}
149151
{content}

workspaces/homepage/plugins/dynamic-home-page/src/types.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,13 @@ export type QuickAccessLink = {
6464
isExpanded?: boolean;
6565
links: (Tool & { iconUrl: string })[];
6666
};
67+
68+
export type LearningSectionItem = {
69+
title: string;
70+
description: string;
71+
buttonText: string;
72+
buttonLink: string;
73+
target?: string;
74+
ariaLabel?: string;
75+
endIcon: React.ComponentType;
76+
};

workspaces/homepage/plugins/dynamic-home-page/src/utils/constants.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,13 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
export const LEARNING_SECTION_ITEMS = [
16+
17+
import OpenInNewIcon from '@mui/icons-material/OpenInNew';
18+
import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
19+
20+
import { LearningSectionItem } from '../types';
21+
22+
export const LEARNING_SECTION_ITEMS: LearningSectionItem[] = [
1723
{
1824
title: 'Get started',
1925
description: 'Learn about Red Hat Developer Hub.',
@@ -22,6 +28,7 @@ export const LEARNING_SECTION_ITEMS = [
2228
'https://docs.redhat.com/en/documentation/red_hat_developer_hub/',
2329
target: '_blank',
2430
ariaLabel: 'Read documentation (opens in a new tab)',
31+
endIcon: OpenInNewIcon,
2532
},
2633
{
2734
title: 'Explore',
@@ -30,6 +37,7 @@ export const LEARNING_SECTION_ITEMS = [
3037
buttonLink: '/catalog',
3138
target: undefined,
3239
ariaLabel: 'Go to Catalog',
40+
endIcon: ArrowForwardIcon,
3341
},
3442
{
3543
title: 'Learn',
@@ -38,6 +46,7 @@ export const LEARNING_SECTION_ITEMS = [
3846
buttonLink: '/learning-paths',
3947
target: undefined,
4048
ariaLabel: 'Go to Learning Paths',
49+
endIcon: ArrowForwardIcon,
4150
},
4251
];
4352

0 commit comments

Comments
 (0)