fix(dashboard) Standardize heading levels for consistent hierarchy (#13861)

## Summary

**What** — What changes are introduced in this PR?

This PR standardizes heading levels across dashboard components to maintain proper semantic HTML hierarchy.

**Why** — Why are these changes relevant or necessary?  

*Please provide answer here*

**How** — How have these changes been implemented?

- Added optional `headingLevel` prop `"h1" | "h2" | "h3"` to `DataTable` component with default value of `"h1"`

- Modified `Heading` component usage to explicitly specify the appropriate level based on context

**Testing** — How have these changes been tested, or how can the reviewer test the feature?

*Please provide answer here*

---

## Checklist

Please ensure the following before requesting a review:

- [x] I have added a **changeset** for this PR
    - Every non-breaking change should be marked as a **patch**
    - To add a changeset, run `yarn changeset` and follow the prompts
- [ ] The changes are covered by relevant **tests**
- [x] I have verified the code works as intended locally
- [ ] I have linked the related issue(s) if applicable
This commit is contained in:
Radek Napora
2025-10-28 12:11:50 +00:00
committed by GitHub
parent 0b202cc509
commit c1c0e1490a
14 changed files with 22 additions and 18 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"@medusajs/dashboard": patch
---
fix(dashboard) standardize heading levels for consistent hierarchy
@@ -77,6 +77,7 @@ interface DataTableProps<TData> {
rowHref?: (row: TData) => string
emptyState?: DataTableEmptyStateProps
heading?: string
headingLevel?: "h1" | "h2" | "h3"
subHeading?: string
prefix?: string
pageSize?: number
@@ -117,6 +118,7 @@ export const DataTable = <TData,>({
enableFilterMenu,
rowHref,
heading,
headingLevel = "h1",
subHeading,
prefix,
pageSize = 10,
@@ -384,7 +386,7 @@ export const DataTable = <TData,>({
<div className="flex items-center gap-x-4">
{shouldRenderHeading && (
<div>
{heading && <Heading>{heading}</Heading>}
{heading && <Heading level={headingLevel}>{heading}</Heading>}
{subHeading && (
<Text size="small" className="text-ui-fg-subtle">
{subHeading}
@@ -56,6 +56,7 @@ export const ApiKeySalesChannelSection = ({
filters={filters}
commands={commands}
heading={t("salesChannels.domain")}
headingLevel="h2"
getRowId={(row) => row.id}
rowCount={count}
isLoading={isPending}
@@ -53,7 +53,7 @@ export const ApiKeyManagementListTable = ({
<Container className="divide-y p-0">
<div className="flex items-center justify-between px-6 py-4">
<div>
<Heading level="h2">
<Heading level="h1">
{keyType === "publishable"
? t(`apiKeyManagement.domain.publishable`)
: t("apiKeyManagement.domain.secret")}
@@ -30,19 +30,14 @@ export const CampaignBudget = ({ campaign }: CampaignBudgetProps) => {
return (
<Container className="flex flex-col gap-y-4 px-6 py-4">
<div className="flex justify-between">
<div className="flex-grow">
<div className="bg-ui-bg-base shadow-borders-base float-start flex size-7 items-center justify-center rounded-md">
<div className="mb-2 grid flex-grow grid-cols-[28px_1fr] items-center gap-x-3">
<div className="bg-ui-bg-base shadow-borders-base flex size-7 items-center justify-center rounded-md">
<div className="bg-ui-bg-component flex size-6 items-center justify-center rounded-[4px]">
<ChartPie className="text-ui-fg-subtle" />
</div>
</div>
<Heading
className="text-ui-fg-subtle ms-10 mt-[1.5px] font-normal"
level="h3"
>
{getTranslation()}
</Heading>
<Heading level="h2">{getTranslation()}</Heading>
</div>
<ActionMenu
@@ -19,7 +19,7 @@ export const CampaignSpend = ({ campaign }: CampaignSpendProps) => {
</div>
</div>
<Heading level="h3" className="text-ui-fg-subtle font-normal">
<Heading level="h2">
{campaign.budget?.type === "use_by_attribute"
? t("campaigns.fields.totalUsedByAttribute")
: campaign.budget?.type === "spend"
@@ -50,7 +50,7 @@ export const CampaignListTable = () => {
return (
<Container className="divide-y p-0">
<div className="flex items-center justify-between px-6 py-4">
<Heading level="h2">{t("campaigns.domain")}</Heading>
<Heading level="h1">{t("campaigns.domain")}</Heading>
<Link to="/campaigns/create">
<Button size="small" variant="secondary">
{t("actions.create")}
@@ -15,7 +15,7 @@ export const InventoryItemLocationLevelsSection = ({
return (
<Container className="divide-y p-0">
<div className="flex items-center justify-between px-6 py-4">
<Heading>{t("inventory.locationLevels")}</Heading>
<Heading level="h2">{t("inventory.locationLevels")}</Heading>
<Button size="small" variant="secondary" asChild>
<Link to="locations">{t("inventory.manageLocations")}</Link>
</Button>
@@ -15,7 +15,7 @@ export const InventoryItemReservationsSection = ({
return (
<Container className="divide-y p-0">
<div className="flex items-center justify-between px-6 py-4">
<Heading>{t("reservations.domain")}</Heading>
<Heading level="h2">{t("reservations.domain")}</Heading>
<Button size="small" variant="secondary" asChild>
<Link to={`/reservations/create?item_id=${inventoryItem.id}`}>
{t("actions.create")}
@@ -113,7 +113,7 @@ export const PriceListProductSection = ({
return (
<Container className="divide-y p-0">
<div className="flex items-center justify-between px-6 py-4">
<Heading>{t("priceLists.products.header")}</Heading>
<Heading level="h2">{t("priceLists.products.header")}</Heading>
<ActionMenu
groups={[
{
@@ -103,6 +103,7 @@ export const ProductVariantSection = ({
pageSize={PAGE_SIZE}
isLoading={isPending}
heading={t("products.variants.header")}
headingLevel="h2"
emptyState={{
empty: {
heading: t("products.variants.empty.heading"),
@@ -68,7 +68,7 @@ export const ProductListTable = () => {
return (
<Container className="divide-y p-0">
<div className="flex items-center justify-between px-6 py-4">
<Heading level="h2">{t("products.domain")}</Heading>
<Heading level="h1">{t("products.domain")}</Heading>
<div className="flex items-center justify-center gap-x-2">
<Button size="small" variant="secondary" asChild>
<Link to={`export${location.search}`}>{t("actions.export")}</Link>
@@ -58,7 +58,7 @@ export const PromotionConditionsSection = ({
<Container className="p-0">
<div className="flex items-center justify-between px-6 py-4">
<div className="flex flex-col">
<Heading>
<Heading level="h2">
{t(
ruleType === "target-rules"
? `promotions.fields.conditions.${ruleType}.${applicationMethodTargetType}.title`
@@ -55,7 +55,7 @@ export const PromotionListTable = () => {
return (
<Container className="divide-y p-0">
<div className="flex items-center justify-between px-6 py-4">
<Heading level="h2">{t("promotions.domain")}</Heading>
<Heading level="h1">{t("promotions.domain")}</Heading>
<Button size="small" variant="secondary" asChild>
<Link to="create">{t("actions.create")}</Link>