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:
@@ -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}
|
||||
|
||||
+1
@@ -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}
|
||||
|
||||
+1
-1
@@ -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")}
|
||||
|
||||
+3
-8
@@ -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
|
||||
|
||||
+1
-1
@@ -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"
|
||||
|
||||
+1
-1
@@ -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")}
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-1
@@ -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")}
|
||||
|
||||
+1
-1
@@ -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={[
|
||||
{
|
||||
|
||||
+1
@@ -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"),
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-1
@@ -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`
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user