Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 34 additions & 17 deletions src/js/components/plans/header.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import PageHeader from '@salesforce/design-system-react/components/page-header';
import React, { ReactNode } from 'react';
import React, { ReactNode, useEffect, useRef } from 'react';
import { Trans } from 'react-i18next';

import ProductIcon from '@/js/components/products/icon';
Expand All @@ -23,21 +23,38 @@ const Header = ({
preflightStatus?: string | null | undefined;
preflightIsValid?: boolean;
preflightIsReady?: boolean;
}) => (
<>
<PageHeader
className="page-header slds-p-around_x-large"
title={plan.title}
trail={[
<Trans i18nKey="productWithVersion" key={product.slug}>
{{ product: product.title }} {{ version: version.label }}
</Trans>,
]}
onRenderActions={onRenderActions ? onRenderActions : null}
icon={<ProductIcon item={product} />}
variant="object-home"
/>
</>
);
}) => {
const headerRef = useRef<HTMLDivElement>(null);

useEffect(() => {
// Set focus to the header title on mount for proper focus order (WCAG 2.4.3)
// This ensures screen readers land on the heading first, especially on iOS VoiceOver
if (headerRef.current) {
const heading = headerRef.current.querySelector('h1, h2, [class*="heading"]');
if (heading && heading instanceof HTMLElement) {
// Set tabindex to make heading focusable, then focus it
heading.setAttribute('tabindex', '-1');
heading.focus();
}
}
}, [plan.id, product.id, version.id]);

return (
<div ref={headerRef}>
<PageHeader
className="page-header slds-p-around_x-large"
title={plan.title}
trail={[
<Trans i18nKey="productWithVersion" key={product.slug}>
{{ product: product.title }} {{ version: version.label }}
</Trans>,
]}
onRenderActions={onRenderActions ? onRenderActions : null}
icon={<ProductIcon item={product} />}
variant="object-home"
/>
</div>
);
};

export default Header;
56 changes: 36 additions & 20 deletions src/js/components/products/header.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import PageHeader from '@salesforce/design-system-react/components/page-header';
import React from 'react';
import React, { useEffect, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { Trans } from 'react-i18next';

Expand All @@ -15,27 +15,43 @@ const Header = ({
versionLabel: string;
}) => {
const { t } = useTranslation();
const headerRef = useRef<HTMLDivElement>(null);

return (
<PageHeader
className="page-header slds-p-around_x-large"
title={
product.layout === PRODUCT_LAYOUTS.Card
? product.title
: t('Select a Plan')
}
trail={
product.layout === PRODUCT_LAYOUTS.Card
? []
: [
<Trans i18nKey="productWithVersion" key={product.slug}>
{{ product: product.title }} {{ version: versionLabel }}
</Trans>,
]
useEffect(() => {
// Set focus to the header title on mount for proper focus order (WCAG 2.4.3)
// This ensures screen readers land on the heading first, especially on iOS VoiceOver
if (headerRef.current) {
const heading = headerRef.current.querySelector('h1, h2, [class*="heading"]');
if (heading && heading instanceof HTMLElement) {
// Set tabindex to make heading focusable, then focus it
heading.setAttribute('tabindex', '-1');
heading.focus();
}
icon={<ProductIcon item={product} />}
variant="object-home"
/>
}
}, [product.id, versionLabel]);

return (
<div ref={headerRef}>
<PageHeader
className="page-header slds-p-around_x-large"
title={
product.layout === PRODUCT_LAYOUTS.Card
? product.title
: t('Select a Plan')
}
trail={
product.layout === PRODUCT_LAYOUTS.Card
? []
: [
<Trans i18nKey="productWithVersion" key={product.slug}>
{{ product: product.title }} {{ version: versionLabel }}
</Trans>,
]
}
icon={<ProductIcon item={product} />}
variant="object-home"
/>
</div>
);
};

Expand Down
6 changes: 6 additions & 0 deletions src/sass/components/_header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@
border: none;
border-radius: 0;
box-shadow: none;

// Ensure programmatically focused headings don't show default focus outline
// Focus is set via JS for accessibility (WCAG 2.4.3) but shouldn't be visually intrusive
[tabindex='-1']:focus {
outline: none;
}
}

.site-logo {
Expand Down
Loading