@@ -140,7 +140,7 @@ exports[`Heading renders the UI snapshot correctly 11`] = `
role="group"
>
diff --git a/src/components/Heading/headingChangelogData.ts b/src/components/Heading/headingChangelogData.ts
new file mode 100644
index 0000000000..f4cbd93294
--- /dev/null
+++ b/src/components/Heading/headingChangelogData.ts
@@ -0,0 +1,21 @@
+/** This data is used to populate the ComponentChangelogTable component.
+ *
+ * date: string (when adding new entry during development, set value as "Prerelease")
+ * version: string (when adding new entry during development, set value as "Prerelease")
+ * type: "Bug Fix" | "New Feature" | "Update";
+ * affects: array["Accessibility" | "Documentation" | "Functionality" | "Styles"];
+ * notes: array (will render as a bulleted list, add one array element for each list element)
+ */
+import { ChangelogData } from "../../utils/ComponentChangelogTable";
+
+export const changelogData: ChangelogData[] = [
+ {
+ date: "2023-10-26",
+ version: "2.1.1",
+ type: "Update",
+ affects: ["Accessibility"],
+ notes: [
+ 'Updated the `aria-roledescription` value to "subtitle" (a more familiar and recognizable term) for the `overline` element.',
+ ],
+ },
+];
diff --git a/src/components/Hero/Hero.mdx b/src/components/Hero/Hero.mdx
index 4b13f1962b..98daa54aaa 100644
--- a/src/components/Hero/Hero.mdx
+++ b/src/components/Hero/Hero.mdx
@@ -12,14 +12,15 @@ import Link from "../Link/Link";
| Component Version | DS Version |
| ----------------- | ---------- |
| Added | `0.2.0` |
-| Latest | `2.1.0` |
+| Latest | `2.1.1` |
## Table of Contents
- {Overview}
- {Component Props}
- {Accessibility}
-- {All Variations}
+- {Active Variants}
+- {Deprecated Variants}
- {Color Variations for Secondary Hero}
- {Changelog}
@@ -31,10 +32,15 @@ The `Hero` component is used to display a full width banner at the top of a page
The `Hero` will contain a required `h1` page title and may also include optional
descriptive text and images.
-There are currently five main hero types: `"primary"`, `"secondary"`,
-`"tertiary"`, `"campaign"`, and `"fiftyFifty"`. Under the `"secondary"` hero type,
-there are four additional subtypes: `"secondaryBooksAndMore"`, `"secondaryLocations"`,
-`"secondaryResearch"`, and `"secondaryWhatsOn"`.
+There are currently three main hero types: `"primary"`, `"tertiary"`, and
+`"campaign"`.
+
+Two hero types have been deprecated: `"secondary"` and `"fiftyFifty"`. The
+deprecated variants will be removed from the DS in a future release.
+
+Under the `"secondary"` hero type, there are four additional subtypes:
+`"secondaryBooksAndMore"`, `"secondaryLocations"`, `"secondaryResearch"`, and
+`"secondaryWhatsOn"`.
For the variations that use image "alt" and "src" attributes, the `imageProps`
prop should be used:
@@ -55,9 +61,10 @@ prop should be used:
language="jsx"
/>
-Note: the `imageProps` prop is not the same as the `backgroundImageSrc` prop used
-for some variations. For a full list of what props to use for each variant, check
-the All Variations section.
+Note: the `imageProps` prop is not the same as the `backgroundImageSrc` prop
+used for some variations. For a full list of what props to use for each variant,
+check the Active Variants
+section.
## Component Props
@@ -72,7 +79,7 @@ breadcrumbs and above the main content. This means that if the `Hero` displays
a heading element, it should be the first on the page and an `h1` element set
through `Heading`'s `level="h1"`.
-## All Variations
+## Active Variants
Each `Hero` variation can be rendered through the `heroType` prop.
@@ -92,24 +99,6 @@ heading={}
-### Secondary
-
-The `"secondary"` hero type can be used with the `heading`, `imageProps`, and
-`subHeaderText` props.
-
-
-}
-imageProps={imageProps}
-subHeaderText={secondarySubHeaderText}
-`}
- language="jsx"
-/>
-
-
-
### Tertiary
The `"tertiary"` hero type can be used with the `backgroundColor`, `foregroundColor`,
@@ -168,8 +157,34 @@ subHeaderText={otherSubHeaderText}
+## Deprecated Variants
+
+### Secondary
+
+This `"secondary"` variant of the `Hero` component has been deprecated. This
+variant will be removed from the DS in a future release.
+
+The `"secondary"` hero type can be used with the `heading`, `imageProps`, and
+`subHeaderText` props.
+
+
+}
+imageProps={imageProps}
+subHeaderText={secondarySubHeaderText}
+`}
+ language="jsx"
+/>
+
+
+
### FiftyFifty
+This `"fiftyFifty"` variant of the `Hero` component has been deprecated. This
+variant will be removed from the DS in a future release.
+
The `"fiftyFifty"` hero type can be used with the `backgroundColor`,
`foregroundColor`, `heading`, `imageProps`, and `subHeaderText` props. The
minimum props to use are `imageProps` and `subHeaderText`.
@@ -186,6 +201,10 @@ subHeaderText={otherSubHeaderText}
## Color Variations for Secondary Hero
+This `"secondary"` variant of the `Hero` component has been deprecated. This
+variant and the associated color variations will be removed from the DS in a
+future release.
+
The background color for the title bar in the `"secondary"` `Hero` changes based
on the `heroType` variants for the `"secondary"` main variant. There are four
subtypes: `"secondaryBooksAndMore"`, `"secondaryLocations"`, `"secondaryResearch"`,
diff --git a/src/components/Hero/Hero.stories.tsx b/src/components/Hero/Hero.stories.tsx
index 2be1f395f7..e69db1c4a7 100644
--- a/src/components/Hero/Hero.stories.tsx
+++ b/src/components/Hero/Hero.stories.tsx
@@ -17,6 +17,11 @@ const secondarySubHeaderText = (
in between.
>
);
+const deprecatedMessage = (
+
+ This variant has been deprecated.
+
+);
const otherSubHeaderText =
"With 92 locations across the Bronx, Manhattan, and Staten Island, The New York Public Library is an essential part of neighborhoods across the city. Visit us today.";
const otherSubHeaderTextLong = (
@@ -113,11 +118,20 @@ export const WithControls: Story = {
+
}
heroType={args.heroType}
imageProps={args.imageProps}
- subHeaderText={secondarySubHeaderText}
+ subHeaderText={
+ <>
+ {secondarySubHeaderText} {deprecatedMessage}
+ >
+ }
/>
)) ||
@@ -149,7 +163,11 @@ export const WithControls: Story = {
...args.imageProps,
src: "//placekitten.com/1200/400",
}}
- subHeaderText={otherSubHeaderText}
+ subHeaderText={
+ <>
+ {otherSubHeaderText} {deprecatedMessage}
+ >
+ }
/>
)),
parameters: {
@@ -182,6 +200,7 @@ export const Primary: Story = {
};
export const Secondary: Story = {
+ name: "Secondary (deprecated)",
render: () => (
}
heroType="secondary"
imageProps={imageProps}
- subHeaderText={secondarySubHeaderText}
+ subHeaderText={
+ <>
+ {secondarySubHeaderText} {deprecatedMessage}
+ >
+ }
/>
),
};
@@ -332,28 +355,39 @@ export const Campaign: Story = {
};
export const FiftyFifty: Story = {
+ name: "FiftyFifty (deprecated)",
render: () => (
+ {otherSubHeaderText} {deprecatedMessage}
+ >
+ }
/>
+ {otherSubHeaderTextLong} {deprecatedMessage}
+ >
+ }
/>
@@ -370,12 +404,16 @@ export const ColorVariations: Story = {
level="h1"
size="heading2"
id="main-secondary-hero"
- text="Secondary"
+ text="Secondary (deprecated)"
/>
}
heroType="secondary"
imageProps={imageProps}
- subHeaderText={secondarySubHeaderText}
+ subHeaderText={
+ <>
+ {secondarySubHeaderText} {deprecatedMessage}
+ >
+ }
/>
}
heroType="secondaryBooksAndMore"
imageProps={imageProps}
- subHeaderText={secondarySubHeaderText}
+ subHeaderText={
+ <>
+ {secondarySubHeaderText} {deprecatedMessage}
+ >
+ }
/>
}
heroType="secondaryLocations"
imageProps={imageProps}
- subHeaderText={secondarySubHeaderText}
+ subHeaderText={
+ <>
+ {secondarySubHeaderText} {deprecatedMessage}
+ >
+ }
/>
}
heroType="secondaryResearch"
imageProps={imageProps}
- subHeaderText={secondarySubHeaderText}
+ subHeaderText={
+ <>
+ {secondarySubHeaderText} {deprecatedMessage}
+ >
+ }
/>
}
heroType="secondaryWhatsOn"
imageProps={imageProps}
- subHeaderText={secondarySubHeaderText}
+ subHeaderText={
+ <>
+ {secondarySubHeaderText} {deprecatedMessage}
+ >
+ }
/>
),
diff --git a/src/components/Hero/Hero.tsx b/src/components/Hero/Hero.tsx
index 1f375da9a0..9f4637f4a0 100644
--- a/src/components/Hero/Hero.tsx
+++ b/src/components/Hero/Hero.tsx
@@ -1,4 +1,9 @@
-import { Box, chakra, useMultiStyleConfig } from "@chakra-ui/react";
+import {
+ Box,
+ chakra,
+ useColorModeValue,
+ useMultiStyleConfig,
+} from "@chakra-ui/react";
import React, { forwardRef } from "react";
import Image, { ComponentImageProps } from "../Image/Image";
@@ -149,24 +154,53 @@ export const Hero = chakra(
);
}
+ /** The _dark object in the theme file was overriding custom background
+ * colors. To overcome this issue, the background color styles were moved
+ * into the component file and the related styles for all variants, other
+ * than the "secondary" variant, were removed from the theme file. */
+ const allDefaultBackgroundColors = {
+ primary: useColorModeValue("ui.bg.default", "dark.ui.bg.default"),
+ secondary: useColorModeValue("ui.bg.default", "dark.ui.bg.default"),
+ tertiary: useColorModeValue("ui.gray.x-dark", "dark.ui.bg.default"),
+ campaign: useColorModeValue("dark.ui.bg.default", "dark.ui.bg.default"),
+ campaignBackdrop: useColorModeValue(
+ "dark.ui.bg.active",
+ "dark.ui.bg.active"
+ ),
+ fiftyFifty: useColorModeValue("ui.bg.default", "dark.ui.bg.default"),
+ };
+
+ const defaultBackgroundColor = allDefaultBackgroundColors[heroType];
if (heroType === "primary") {
backgroundImageStyle = backgroundImageSrc
- ? { backgroundImage: `url(${backgroundImageSrc})` }
+ ? {
+ bgColor: defaultBackgroundColor,
+ backgroundImage: `url(${backgroundImageSrc})`,
+ }
: {};
+ } else if (heroType === "secondary") {
+ backgroundImageStyle = { bgColor: defaultBackgroundColor };
} else if (heroType === "campaign") {
backgroundImageStyle = backgroundImageSrc
? { backgroundImage: `url(${backgroundImageSrc})` }
: backdropBackgroundColor
? { bgColor: backdropBackgroundColor }
- : { backgroundColor };
+ : { bgColor: allDefaultBackgroundColors["campaignBackdrop"] };
} else if (heroType === "tertiary" || heroType === "fiftyFifty") {
- backgroundImageStyle = backgroundColor ? { bg: backgroundColor } : {};
+ const tertiaryBgColor = backgroundColor
+ ? backgroundColor
+ : defaultBackgroundColor;
+ backgroundImageStyle = backgroundColor
+ ? { bgColor: backgroundColor }
+ : { bgColor: tertiaryBgColor };
}
if (!heroSecondaryTypes.includes(heroType)) {
contentBoxStyling = {
...(foregroundColor && { color: foregroundColor }),
- ...(backgroundColor && { backgroundColor }),
+ ...(backgroundColor
+ ? { backgroundColor }
+ : { defaultBackgroundColor }),
};
} else if (
foregroundColor ||
diff --git a/src/components/Hero/__snapshots__/Hero.test.tsx.snap b/src/components/Hero/__snapshots__/Hero.test.tsx.snap
index 15445ca814..5af4f1c932 100644
--- a/src/components/Hero/__snapshots__/Hero.test.tsx.snap
+++ b/src/components/Hero/__snapshots__/Hero.test.tsx.snap
@@ -2,19 +2,24 @@
exports[`Hero Renders the UI snapshot correctly 1`] = `
@@ -228,14 +233,18 @@ exports[`Hero Renders the UI snapshot correctly 6`] = `
exports[`Hero Renders the UI snapshot correctly 7`] = `
{
);
expect(
screen.getByLabelText(/What is your favorite color/i)
- ).toHaveAttribute(
- "aria-label",
- "What is your favorite color? - This is the helper text."
- );
+ ).toHaveAttribute("aria-label", "What is your favorite color?");
});
it("renders aria-describedby when helperText prop is passed", () => {
diff --git a/src/components/Slider/__snapshots__/Slider.test.tsx.snap b/src/components/Slider/__snapshots__/Slider.test.tsx.snap
index b8ccec1bd4..ef65740f1c 100644
--- a/src/components/Slider/__snapshots__/Slider.test.tsx.snap
+++ b/src/components/Slider/__snapshots__/Slider.test.tsx.snap
@@ -212,8 +212,9 @@ exports[`Slider Range Slider renders the UI snapshot correctly 2`] = `
className="css-79elbk"
>
` element. When `showLabel`
is set to false, the `` element's `aria-label` attribute is set to the
-required `labelText` value.
+required `labelText` value. Some components that use `TextInput`, like `DatePicker`,
+give the `` an `aria-label` regardless of whether `showLabel` is true or false.
+This is because interacting with these elements is not as obvious to those using
+screen readers and more information is necessary.
The `helperText` and the `invalidText` are associated with the `` element
through the `aria-describedby` attribute.
diff --git a/src/components/TextInput/TextInput.tsx b/src/components/TextInput/TextInput.tsx
index aec2ea2b79..f007edf09d 100644
--- a/src/components/TextInput/TextInput.tsx
+++ b/src/components/TextInput/TextInput.tsx
@@ -44,6 +44,8 @@ export const TextInputFormats = {
export type TextInputVariants = "default" | "searchBar" | "searchBarSelect";
export interface InputProps {
+ /** FOR INTERNAL DS USE ONLY: Adds an aria-label or appends to an existing aria-label for screen readers.*/
+ additionalAriaLabel?: string;
/** FOR INTERNAL DS USE ONLY: additional helper text id(s) to be used for the input's `aria-describedby` value.
* If more than one, separate each with a space */
additionalHelperTextIds?: string;
@@ -129,6 +131,7 @@ export const TextInput = chakra(
forwardRef(
(props, ref: React.Ref) => {
const {
+ additionalAriaLabel,
additionalHelperTextIds,
className,
defaultValue,
@@ -200,6 +203,7 @@ export const TextInput = chakra(
}
const ariaAttributes = getAriaAttrs({
+ additionalAriaLabel,
footnote,
id,
labelText,
diff --git a/src/theme/components/hero.ts b/src/theme/components/hero.ts
index bab6ef25e6..22a9495e02 100644
--- a/src/theme/components/hero.ts
+++ b/src/theme/components/hero.ts
@@ -4,6 +4,7 @@ import { screenreaderOnly } from "./globalMixins";
// Used for all "secondary" variants.
const secondaryBase = {
overflowX: "hidden",
+ bgColor: "ui.bg.default",
content: {
...wrapperStyles,
paddingEnd: "inset.default",
@@ -36,6 +37,9 @@ const secondaryBase = {
flex: { md: "1 1 50%" },
order: { base: "3", md: "2" },
},
+ _dark: {
+ bgColor: "dark.ui.bg.default",
+ },
};
// Used for all "secondary" variants' heading component.
const secondaryHeadingBase = {
@@ -136,7 +140,6 @@ const secondaryLocations = getSecondaryVariantStyles(
const secondaryResearch = getSecondaryVariantStyles("section.research.primary");
const secondaryWhatsOn = getSecondaryVariantStyles("section.whats-on.primary");
const tertiary = {
- bg: "ui.gray.x-dark",
content: {
...wrapperStyles,
color: "ui.typography.inverse.body",
@@ -162,9 +165,6 @@ const tertiary = {
p: {
marginBottom: "0",
},
- _dark: {
- bg: "dark.ui.bg.default",
- },
};
const campaign = {
alignItems: "center",
@@ -195,7 +195,6 @@ const campaign = {
position: { md: "relative" },
top: { md: "xxl" },
_dark: {
- bg: "dark.ui.bg.default",
color: "dark.ui.typography.body",
},
},
@@ -264,10 +263,7 @@ const fiftyFifty = {
};
const Hero = {
baseStyle: {
- bgColor: "ui.gray.x-light-cool",
- _dark: {
- bgColor: "dark.ui.bg.default",
- },
+ // ...
},
// Available variants:
variants: {
diff --git a/src/utils/utils.ts b/src/utils/utils.ts
index bc81046384..86132e55df 100644
--- a/src/utils/utils.ts
+++ b/src/utils/utils.ts
@@ -48,6 +48,7 @@ export const getStorybookHrefProps = (pageCount: number) => {
};
interface GetAriaAttrsProps {
+ additionalAriaLabel?: string;
footnote: HelperErrorTextType;
id: string;
labelText: HelperErrorTextType;
@@ -60,6 +61,7 @@ interface GetAriaAttrsProps {
* `aria-describedby` attributes, based on the label and footnote values.
*/
export const getAriaAttrs = ({
+ additionalAriaLabel,
footnote,
id,
labelText,
@@ -69,17 +71,31 @@ export const getAriaAttrs = ({
}: GetAriaAttrsProps): AriaAttributes => {
let ariaAttributes: AriaAttributes = {};
+ // If both a label and an aria-label are present, screen
+ // readers will only read the aria-label so we need to
+ // provide all necessary details in the aria-label.
+ if (additionalAriaLabel) {
+ ariaAttributes["aria-label"] = `${labelText}, ${additionalAriaLabel}`;
+ }
+
if (!showLabel) {
if (typeof labelText !== "string") {
console.warn(
`NYPL Reservoir ${name}: \`labelText\` must be a string when \`showLabel\` is false.`
);
}
- ariaAttributes["aria-label"] =
- labelText && footnote
- ? `${labelText} - ${footnote}`
- : (labelText as string);
- } else if (footnote) {
+ // If showLabel is false and we have not yet added an
+ // aria-label, we need to add one with all relevant
+ // details.
+ if (!("aria-label" in ariaAttributes)) {
+ ariaAttributes["aria-label"] = labelText as string;
+ }
+ }
+
+ // Screen readers will read both the `aria-label` and the
+ // `aria-describedby`. The footnote should not be added to
+ // the `aria-label` because it would be read twice.
+ if (footnote) {
ariaAttributes["aria-describedby"] = `${
additionalHelperTextIds ? additionalHelperTextIds + " " : ""
}${id}-helperText`;