diff --git a/.changeset/sharp-cups-attend.md b/.changeset/sharp-cups-attend.md new file mode 100644 index 000000000..0bd6fcac8 --- /dev/null +++ b/.changeset/sharp-cups-attend.md @@ -0,0 +1,5 @@ +--- +'@primer/react-brand': patch +--- + +Ensure accessible content order in `PricingOptions` markup diff --git a/packages/react/src/Footnotes/Footnotes.visual.spec.ts-snapshots/Visual-Comparison-Footnotes-Footnotes-Rivers-With-Citations-1-linux.png b/packages/react/src/Footnotes/Footnotes.visual.spec.ts-snapshots/Visual-Comparison-Footnotes-Footnotes-Rivers-With-Citations-1-linux.png index 7839420d1..97db0e3a8 100644 Binary files a/packages/react/src/Footnotes/Footnotes.visual.spec.ts-snapshots/Visual-Comparison-Footnotes-Footnotes-Rivers-With-Citations-1-linux.png and b/packages/react/src/Footnotes/Footnotes.visual.spec.ts-snapshots/Visual-Comparison-Footnotes-Footnotes-Rivers-With-Citations-1-linux.png differ diff --git a/packages/react/src/PricingOptions/PricingOptions.features.stories.tsx b/packages/react/src/PricingOptions/PricingOptions.features.stories.tsx index c6fb90a3e..6b04b4aa2 100644 --- a/packages/react/src/PricingOptions/PricingOptions.features.stories.tsx +++ b/packages/react/src/PricingOptions/PricingOptions.features.stories.tsx @@ -8,15 +8,7 @@ import imageExample from '../fixtures/images/bento/3.png' import {CopilotIcon} from '@primer/octicons-react' const decorators = Story => ( - + diff --git a/packages/react/src/PricingOptions/PricingOptions.module.css b/packages/react/src/PricingOptions/PricingOptions.module.css index e8398e33b..851c3ba8d 100644 --- a/packages/react/src/PricingOptions/PricingOptions.module.css +++ b/packages/react/src/PricingOptions/PricingOptions.module.css @@ -6,13 +6,38 @@ --brand-pricing-options-item-gap: var(--brand-PricingOptions-items-gap); --brand-pricing-options-container-padding-inline: 0; + /* prettier-ignore */ + --brand-pricing-options-template-areas: + 'leadingComponent' + 'label' + 'heading' + 'description' + 'price' + 'actions' + 'feature-list' + 'footnote' + ; + + /* prettier-ignore */ + --brand-pricing-options-template-areas-single-item: + 'leadingComponent actions' + 'label actions' + 'heading actions' + 'description actions' + 'price actions' + 'feature-list actions'; + display: grid; - grid-template-columns: 1fr; - grid-template-rows: auto; row-gap: var(--brand-pricing-options-item-gap); padding-inline: var(--brand-pricing-options-container-padding-inline); } +@media (min-width: 63.25rem) { + .PricingOptions { + grid-template-areas: var(--brand-pricing-options-template-areas); + } +} + /* ---------------------------------------------------------- */ /* Layout: default */ /* ---------------------------------------------------------- */ @@ -48,7 +73,6 @@ position: absolute; inset-inline: 0; height: 1px; - margin-block-start: calc(var(--brand-pricing-options-item-gap) * -1); background-color: var(--brand-color-border-default); } @@ -92,13 +116,7 @@ grid-template-columns: 1fr 1fr; column-gap: calc(var(--base-size-96) * 2); grid-template-rows: repeat(auto-fit, minmax(0, 1fr)); - grid-template-areas: - 'leadingComponent actions' - 'label actions' - 'heading actions' - 'description actions' - 'price actions' - 'feature-list actions'; + grid-template-areas: var(--brand-pricing-options-template-areas-single-item); } .PricingOptions--items1 .PricingOptions__actions { @@ -113,20 +131,9 @@ @media (min-width: 63.25rem) { .PricingOptions--items2, .PricingOptions--items3 { - display: grid; grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); column-gap: var(--brand-pricing-options-item-gap); row-gap: 0; - - grid-template-areas: - 'leadingComponent' - 'label' - 'heading' - 'description' - 'price' - 'actions' - 'feature-list' - 'footnote'; } .PricingOptions--variant-default.PricingOptions--items2 { @@ -144,9 +151,13 @@ /* Item inner layout */ /* ---------------------------------------------------------- */ +.PricingOptions__item { + display: grid; + grid-template-areas: var(--brand-pricing-options-template-areas); +} + @media (min-width: 63.28rem) { .PricingOptions__item { - display: grid; grid-row: label / footnote; grid-template-rows: subgrid; } @@ -164,17 +175,9 @@ @supports not (grid-template-rows: subgrid) { @media (min-width: 63.28rem) { .PricingOptions__item { + grid-template-areas: var(--brand-pricing-options-template-areas); grid-template-columns: 1fr; grid-template-rows: auto; - grid-template-areas: - 'leadingComponent' - 'label' - 'heading' - 'description' - 'price' - 'actions' - 'feature-list' - 'footnote'; } } } diff --git a/packages/react/src/PricingOptions/PricingOptions.stories.tsx b/packages/react/src/PricingOptions/PricingOptions.stories.tsx index 95aa0a3f1..c1f7fb682 100644 --- a/packages/react/src/PricingOptions/PricingOptions.stories.tsx +++ b/packages/react/src/PricingOptions/PricingOptions.stories.tsx @@ -9,15 +9,7 @@ export default { } as Meta export const Default = () => ( - + diff --git a/packages/react/src/PricingOptions/PricingOptions.tsx b/packages/react/src/PricingOptions/PricingOptions.tsx index 00f1c8274..7e66ec628 100644 --- a/packages/react/src/PricingOptions/PricingOptions.tsx +++ b/packages/react/src/PricingOptions/PricingOptions.tsx @@ -7,9 +7,9 @@ import { Accordion, Button, ButtonBaseProps, - Heading, + Heading as HeadingComponent, HeadingProps, - Label, + Label as LabelComponent, Text, UnorderedList, UnorderedListProps, @@ -126,58 +126,53 @@ const PricingOptionsItem = forwardRef( ref: Ref, ) => { type FilteredChildren = { - Content: React.ReactElement< - | PricingOptionsLabelProps - | PricingOptionsHeadingProps - | PricingOptionsDescriptionProps - | PricingOptionsPriceProps - >[] FeatureList: React.ReactElement | null Actions: React.ReactElement[] Footnote: React.ReactElement | null + Heading: React.ReactElement | null + Description: React.ReactElement | null + Label: React.ReactElement | null + Price: React.ReactElement | null } const memoizedChildren = useMemo(() => React.Children.toArray(children), [children]) - const {Content, FeatureList, Actions, Footnote} = memoizedChildren.reduce( - (acc, child) => { - if (React.isValidElement(child) && typeof child.type !== 'string') { - if (child.type === PricingOptionsFeatureList) { - acc.FeatureList = child as React.ReactElement | null + const {Heading, Description, Label, Price, FeatureList, Actions, Footnote} = + memoizedChildren.reduce( + (acc, child) => { + if (React.isValidElement(child) && typeof child.type !== 'string') { + if (child.type === PricingOptionsFeatureList) { + acc.FeatureList = child as React.ReactElement | null + } + + if (child.type === PricingOptionsPrimaryAction || child.type === PricingOptionsSecondaryAction) { + acc.Actions.push(child as React.ReactElement) + } + + if (child.type === PricingOptionsFootnote) { + acc.Footnote = child as React.ReactElement + } + + if (child.type === PricingOptionsHeading) { + acc.Heading = child as React.ReactElement + } + + if (child.type === PricingOptionsDescription) { + acc.Description = child as React.ReactElement + } + + if (child.type === PricingOptionsLabel) { + acc.Label = child as React.ReactElement + } + + if (child.type === PricingOptionsPrice) { + acc.Price = child as React.ReactElement + } } - - if (child.type === PricingOptionsPrimaryAction || child.type === PricingOptionsSecondaryAction) { - acc.Actions.push(child as React.ReactElement) - } - - if (child.type === PricingOptionsFootnote) { - acc.Footnote = child as React.ReactElement - } - - if ( - child.type === PricingOptionsLabel || - child.type === PricingOptionsHeading || - child.type === PricingOptionsDescription || - child.type === PricingOptionsPrice - ) { - acc.Content.push( - child as React.ReactElement< - | PricingOptionsLabelProps - | PricingOptionsDescriptionProps - | PricingOptionsHeadingProps - | PricingOptionsPriceProps - >, - ) - } - } - return acc - }, - {Content: [], FeatureList: null, Actions: [], Footnote: null}, - ) - - if (leadingComponent) { - Content.unshift(
{leadingComponent}
) - } + return acc + }, + {FeatureList: null, Actions: [], Footnote: null, Heading: null, Description: null, Label: null, Price: null}, + ) return (
)} > - {Content} + {Heading} + {Label} + {Description} + {Price} + {leadingComponent &&
{leadingComponent}
} {Actions.length > 0 &&
{Actions}
} {FeatureList} {Footnote} @@ -206,7 +205,7 @@ type PricingOptionsLabelProps = PropsWithChildren> & const PricingOptionsLabel = forwardRef( ({children, className, 'data-testid': testId, ...rest}, ref) => { return ( - + ) }, ) @@ -249,7 +248,7 @@ type PricingOptionsHeadingProps = PropsWithChildren( ({as = 'h3', children, 'data-testid': testId, size = '5', className, ...rest}, ref) => { return ( - {children} - + ) }, ) @@ -463,7 +462,7 @@ type PricingOptionsFeatureHeadingProps = PropsWithChildren( ({children, className, 'data-testid': testId, ...rest}, ref) => { return ( - {children} - + ) }, ) diff --git a/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-Mobile-viewp-6e07a-anded-Narrow-PricingOptions-Expanded-Narrow-1-linux.png b/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-Mobile-viewp-6e07a-anded-Narrow-PricingOptions-Expanded-Narrow-1-linux.png index 18a27c5e7..44e50b595 100644 Binary files a/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-Mobile-viewp-6e07a-anded-Narrow-PricingOptions-Expanded-Narrow-1-linux.png and b/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-Mobile-viewp-6e07a-anded-Narrow-PricingOptions-Expanded-Narrow-1-linux.png differ diff --git a/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Cards-Variant-1-linux.png b/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Cards-Variant-1-linux.png index 40805e2cd..b6375d9d6 100644 Binary files a/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Cards-Variant-1-linux.png and b/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Cards-Variant-1-linux.png differ diff --git a/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Collapsed-Features-1-linux.png b/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Collapsed-Features-1-linux.png index 5718a2f25..577641b98 100644 Binary files a/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Collapsed-Features-1-linux.png and b/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Collapsed-Features-1-linux.png differ diff --git a/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Collapsed-Features-No-Dividers-1-linux.png b/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Collapsed-Features-No-Dividers-1-linux.png index a67155143..ae90e8c95 100644 Binary files a/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Collapsed-Features-No-Dividers-1-linux.png and b/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Collapsed-Features-No-Dividers-1-linux.png differ diff --git a/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Default-1-linux.png b/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Default-1-linux.png index 233f5cf2a..2428e76c7 100644 Binary files a/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Default-1-linux.png and b/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Default-1-linux.png differ diff --git a/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Default-Variant-1-linux.png b/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Default-Variant-1-linux.png index bfbad31de..52a214466 100644 Binary files a/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Default-Variant-1-linux.png and b/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Default-Variant-1-linux.png differ diff --git a/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Leading-Component-1-linux.png b/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Leading-Component-1-linux.png index 0e8e8981b..137ede7c7 100644 Binary files a/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Leading-Component-1-linux.png and b/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Leading-Component-1-linux.png differ diff --git a/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Three-Options-1-linux.png b/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Three-Options-1-linux.png index 5a216a5b4..12da4d8f1 100644 Binary files a/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Three-Options-1-linux.png and b/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Three-Options-1-linux.png differ diff --git a/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Two-Options-1-linux.png b/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Two-Options-1-linux.png index e93770367..92b91ad53 100644 Binary files a/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Two-Options-1-linux.png and b/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Two-Options-1-linux.png differ diff --git a/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-With-Feature-Sets-1-linux.png b/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-With-Feature-Sets-1-linux.png index 30593b97b..4e096c977 100644 Binary files a/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-With-Feature-Sets-1-linux.png and b/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-With-Feature-Sets-1-linux.png differ diff --git a/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-With-Included-And-Excluded-Features-1-linux.png b/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-With-Included-And-Excluded-Features-1-linux.png index c95d70b87..cd1e948cb 100644 Binary files a/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-With-Included-And-Excluded-Features-1-linux.png and b/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-With-Included-And-Excluded-Features-1-linux.png differ diff --git a/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Without-Features-1-linux.png b/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Without-Features-1-linux.png index 30c6668fc..88b190067 100644 Binary files a/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Without-Features-1-linux.png and b/packages/react/src/PricingOptions/PricingOptions.visual.spec.ts-snapshots/Visual-Comparison-PricingOptions-PricingOptions-Without-Features-1-linux.png differ