diff --git a/client/dashboard/app/view-transitions.scss b/client/dashboard/app/view-transitions.scss
index 58bea8ce3cb4..f7dea0e75f2f 100644
--- a/client/dashboard/app/view-transitions.scss
+++ b/client/dashboard/app/view-transitions.scss
@@ -31,14 +31,14 @@ main div.dashboard-header-bar {
}
// Large and small must be separate so they don't cross-animate.
-.dashboard-page-layout.is-large .client-dashboard-components-page-header {
+.dashboard-page-layout.is-large .client-dashboard-components-section-header.is-level-1 {
view-transition-name: page-layout-header-large;
}
-.dashboard-page-layout.is-small .client-dashboard-components-page-header {
+.dashboard-page-layout.is-small .client-dashboard-components-section-header.is-level-1 {
view-transition-name: page-layout-header-small;
}
-.dashboard-page-layout.is-large .client-dashboard-components-page-header .components-button.is-primary {
+.dashboard-page-layout.is-large .client-dashboard-components-section-header.is-level-1 .components-button.is-primary {
view-transition-name: page-layout-header-large--button;
}
diff --git a/client/dashboard/components/page-header/index.tsx b/client/dashboard/components/page-header/index.tsx
index 30bfe45ddb8e..2ce2216e2389 100644
--- a/client/dashboard/components/page-header/index.tsx
+++ b/client/dashboard/components/page-header/index.tsx
@@ -1,70 +1,15 @@
-import {
- __experimentalVStack as VStack,
- __experimentalHStack as HStack,
- __experimentalText as Text,
-} from '@wordpress/components';
+import { SectionHeader } from '../section-header';
import type { PageHeaderProps } from './types';
-import './style.scss';
-
/**
* The PageHeader component provides a structured introduction to a page or section,
- * combining a title, optional description, and contextual actions. It supports
- * varying levels of hierarchy through semantic heading levels, and can include
+ * combining a title, optional description, and contextual actions. It can include
* visual decorations, navigational aids like breadcrumbs, and utility controls
* such as buttons or dropdowns.
*
- * ```jsx
- * import { PageHeader } from '@automattic/components';
- * import { Button } from '@wordpress/components';
- * import { cog } from '@wordpress/icons';
- *
- * function MyComponent() {
- * return (
- * }
- * actions={}
- * />
- * );
- * }
- * ```
+ * It's a thin wrapper around the SectionHeader component, primarily used for
+ * semantic clarity.
*/
-export const PageHeader = ( {
- title,
- description,
- actions,
- decoration,
- breadcrumbs,
-}: PageHeaderProps ) => {
- return (
-
- { breadcrumbs }
-
- { decoration && (
-
- { decoration }
-
- ) }
-
- { title }
- { /* The wrapper is always needed for view transitions. */ }
-
- { actions }
-
-
-
- { description && (
-
- { description }
-
- ) }
-
- );
+export const PageHeader = ( { breadcrumbs, ...rest }: PageHeaderProps ) => {
+ return ;
};
diff --git a/client/dashboard/components/page-header/style.scss b/client/dashboard/components/page-header/style.scss
deleted file mode 100644
index 5809d9af8ffc..000000000000
--- a/client/dashboard/components/page-header/style.scss
+++ /dev/null
@@ -1,40 +0,0 @@
-@import "@wordpress/base-styles/variables";
-
-.client-dashboard-components-page-header__heading {
- font-size: $font-size-2x-large;
- line-height: $font-line-height-2x-large;
- margin-block: 0;
-}
-
-.client-dashboard-components-page-header__decoration {
- display: inline-flex;
- width: $grid-unit-50;
- height: $grid-unit-50;
- flex-shrink: 0;
- align-items: center;
- justify-content: center;
-
- svg {
- fill: $gray-700;
- flex-shrink: 0;
- width: $grid-unit-30;
- height: $grid-unit-30;
- }
-
- img {
- flex-shrink: 0;
- width: 100%;
- height: 100%;
- object-fit: cover;
- border-radius: $radius-small;
- }
-}
-
-.client-dashboard-components-page-header__actions {
- flex-shrink: 0;
- align-self: stretch;
-}
-
-.client-dashboard-components-page-header__description {
- max-width: 75ch; /* stylelint-disable-line unit-allowed-list */
-}
diff --git a/client/dashboard/components/page-header/test/index.tsx b/client/dashboard/components/page-header/test/index.tsx
index 38fc2e88787b..f436ff0627f6 100644
--- a/client/dashboard/components/page-header/test/index.tsx
+++ b/client/dashboard/components/page-header/test/index.tsx
@@ -3,43 +3,9 @@
*/
import { Breadcrumbs } from '@automattic/components/src/breadcrumbs';
import { render, screen } from '@testing-library/react';
-import { Button, Icon } from '@wordpress/components';
-import { cog } from '@wordpress/icons';
import { PageHeader } from '..';
describe( 'PageHeader', () => {
- test( 'should render with title', () => {
- render( );
- expect( screen.getByRole( 'heading', { name: 'Test Title' } ) ).toBeVisible();
- } );
- test( 'should render with description', () => {
- render( );
- expect( screen.getByText( 'Test Description' ) ).toBeVisible();
- } );
- test( 'should render with action buttons', () => {
- render(
-
-
-
- >
- }
- />
- );
- expect( screen.getByRole( 'button', { name: 'Cancel' } ) ).toBeVisible();
- expect( screen.getByRole( 'button', { name: 'Save' } ) ).toBeVisible();
- } );
- test( 'should render with decoration', () => {
- render(
- }
- />
- );
- expect( screen.getByTestId( 'decoration' ) ).toBeVisible();
- } );
test( 'should render with breadcrumbs', () => {
render(
{
/**
* An optional breadcrumbs component used to indicate the user's current position
* in a complex navigational structure and allow quick access to parent levels.
diff --git a/client/dashboard/components/section-header/index.stories.tsx b/client/dashboard/components/section-header/index.stories.tsx
new file mode 100644
index 000000000000..1601a02ec307
--- /dev/null
+++ b/client/dashboard/components/section-header/index.stories.tsx
@@ -0,0 +1,88 @@
+import { Meta, StoryObj } from '@storybook/react';
+import { Button, Icon, DropdownMenu, MenuGroup, MenuItem } from '@wordpress/components';
+import { help, wordpress, moreVertical } from '@wordpress/icons';
+import { SectionHeader } from './index';
+
+const meta = {
+ title: 'client/dashboard/SectionHeader',
+ component: SectionHeader,
+ tags: [ 'autodocs' ],
+ parameters: {
+ actions: { argTypesRegex: '^on.*' },
+ },
+} satisfies Meta< typeof SectionHeader >;
+
+export default meta;
+type Story = StoryObj< typeof meta >;
+
+export const Default: Story = {
+ args: {
+ title: 'Settings',
+ description: 'Configure your application settings',
+ },
+};
+
+export const WithActions: Story = {
+ args: {
+ title: 'Site Settings',
+ description: `Manage how your site works and appears. Configure your site's basic functionality,
+ appearance, and behavior. These settings control everything from your site title to how your
+ content is displayed to visitors.`,
+ actions: (
+ <>
+
+
+ >
+ ),
+ },
+};
+
+export const ImageDecoration: Story = {
+ args: {
+ title: 'Site Customization',
+ description: 'Make your site look exactly how you want it to',
+ decoration:
,
+ actions: (
+ <>
+
+
+ >
+ ),
+ },
+};
+
+export const FullExample: Story = {
+ args: {
+ title: 'Site Customization',
+ description: 'Make your site look exactly how you want it to',
+ decoration: ,
+ actions: (
+ <>
+
+
+
+ { () => (
+ <>
+
+
+
+
+
+
+
+
+ >
+ ) }
+
+ >
+ ),
+ },
+};
diff --git a/client/dashboard/components/section-header/index.tsx b/client/dashboard/components/section-header/index.tsx
new file mode 100644
index 000000000000..8b708f6fb780
--- /dev/null
+++ b/client/dashboard/components/section-header/index.tsx
@@ -0,0 +1,59 @@
+import {
+ __experimentalVStack as VStack,
+ __experimentalHStack as HStack,
+ __experimentalText as Text,
+} from '@wordpress/components';
+import type { SectionHeaderProps } from './types';
+
+import './style.scss';
+
+/**
+ * The SectionHeader component provides a consistently structured introduction
+ * to a section of content, combining a title, optional description/decoration,
+ * and contextual actions. It is used to add hierarchy and clarity within page
+ * content or nested in composite components such as SummaryButtonList, or DataFormFields.
+ */
+export const SectionHeader = ( {
+ title,
+ description,
+ actions,
+ decoration,
+ level = 2,
+ prefix,
+}: SectionHeaderProps ) => {
+ const HeadingTag = `h${ level }` as keyof JSX.IntrinsicElements;
+ return (
+
+ { prefix }
+
+ { decoration && (
+
+ { decoration }
+
+ ) }
+
+
+ { title }
+
+ { /* The wrapper is always needed for view transitions. */ }
+
+ { actions }
+
+
+
+ { description && (
+
+ { description }
+
+ ) }
+
+ );
+};
diff --git a/client/dashboard/components/section-header/style.scss b/client/dashboard/components/section-header/style.scss
new file mode 100644
index 000000000000..9f872aec2d24
--- /dev/null
+++ b/client/dashboard/components/section-header/style.scss
@@ -0,0 +1,61 @@
+@import "@wordpress/base-styles/variables";
+
+.client-dashboard-components-section-header {
+ &.is-level-1 {
+ .client-dashboard-components-section-header__heading {
+ font-size: $font-size-2x-large;
+ line-height: $font-line-height-2x-large;
+ }
+ }
+
+ &.is-level-2 {
+ .client-dashboard-components-section-header__heading {
+ font-size: $font-size-x-large;
+ line-height: $font-line-height-x-large;
+ }
+ }
+
+ &.is-level-3 {
+ .client-dashboard-components-section-header__heading {
+ font-size: $font-size-x-large;
+ line-height: $font-line-height-x-large;
+ }
+ }
+}
+
+.client-dashboard-components-section-header__heading {
+ margin-block: 0;
+}
+
+.client-dashboard-components-section-header__decoration {
+ display: inline-flex;
+ width: $grid-unit-50;
+ height: $grid-unit-50;
+ flex-shrink: 0;
+ align-items: center;
+ justify-content: center;
+
+ svg {
+ fill: $gray-700;
+ flex-shrink: 0;
+ width: $grid-unit-30;
+ height: $grid-unit-30;
+ }
+
+ img {
+ flex-shrink: 0;
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ border-radius: $radius-small;
+ }
+}
+
+.client-dashboard-components-section-header__actions {
+ flex-shrink: 0;
+ align-self: stretch;
+}
+
+.client-dashboard-components-section-header__description {
+ max-width: 75ch; /* stylelint-disable-line unit-allowed-list */
+}
diff --git a/client/dashboard/components/section-header/test/index.tsx b/client/dashboard/components/section-header/test/index.tsx
new file mode 100644
index 000000000000..a31fb00cfc05
--- /dev/null
+++ b/client/dashboard/components/section-header/test/index.tsx
@@ -0,0 +1,64 @@
+/**
+ * @jest-environment jsdom
+ */
+import { render, screen } from '@testing-library/react';
+import { Button, Icon } from '@wordpress/components';
+import { cog } from '@wordpress/icons';
+import { SectionHeader } from '..';
+
+describe( 'SectionHeader', () => {
+ test( 'should render with title', () => {
+ render( );
+ expect( screen.getByRole( 'heading', { name: 'Test Title' } ) ).toBeVisible();
+ } );
+ test( 'should render with description', () => {
+ render( );
+ expect( screen.getByText( 'Test Description' ) ).toBeVisible();
+ } );
+ test( 'should render with action buttons', () => {
+ render(
+
+
+
+ >
+ }
+ />
+ );
+ expect( screen.getByRole( 'button', { name: 'Cancel' } ) ).toBeVisible();
+ expect( screen.getByRole( 'button', { name: 'Save' } ) ).toBeVisible();
+ } );
+ test( 'should render with decoration', () => {
+ render(
+ }
+ />
+ );
+ expect( screen.getByTestId( 'decoration' ) ).toBeVisible();
+ } );
+ test( 'should render with default level 3 heading', () => {
+ render( );
+ expect( screen.getByRole( 'heading', { name: 'Test Title' } ).tagName ).toBe( 'H3' );
+ } );
+ test( 'should render with level 2 heading', () => {
+ render( );
+ expect( screen.getByRole( 'heading', { name: 'Test Title' } ).tagName ).toBe( 'H2' );
+ } );
+ test( 'should render with level 3 heading when explicitly set', () => {
+ render( );
+ expect( screen.getByRole( 'heading', { name: 'Test Title' } ).tagName ).toBe( 'H3' );
+ } );
+ test( 'should render with prefix content', () => {
+ render(
+ Prefix Content }
+ />
+ );
+ expect( screen.getByTestId( 'prefix' ) ).toBeVisible();
+ expect( screen.getByText( 'Prefix Content' ) ).toBeVisible();
+ } );
+} );
diff --git a/client/dashboard/components/section-header/types.ts b/client/dashboard/components/section-header/types.ts
new file mode 100644
index 000000000000..3396eda39827
--- /dev/null
+++ b/client/dashboard/components/section-header/types.ts
@@ -0,0 +1,32 @@
+import React from 'react';
+
+export interface SectionHeaderProps {
+ /**
+ * The main heading text that identifies the page or section.
+ */
+ title: string;
+ /**
+ * Optional supporting text that provides additional context or
+ * guidance beneath the title.
+ */
+ description?: React.ReactNode;
+ /**
+ * A group of contextual controls, such as buttons, dropdowns,
+ * or a search input, relevant to the page or section.
+ */
+ actions?: React.ReactNode;
+ /**
+ * An optional visual element like an icon or small illustration
+ * to enhance recognition or provide visual interest.
+ */
+ decoration?: React.ReactNode;
+ /**
+ * Defines heading level and affects the appearance of the heading text.
+ * @default 2
+ */
+ level?: 1 | 2 | 3;
+ /**
+ * Optional content to be placed above the other elements of the component.
+ */
+ prefix?: React.ReactNode;
+}
diff --git a/client/dashboard/components/summary-button-list/index.stories.tsx b/client/dashboard/components/summary-button-list/index.stories.tsx
new file mode 100644
index 000000000000..5dea4902749d
--- /dev/null
+++ b/client/dashboard/components/summary-button-list/index.stories.tsx
@@ -0,0 +1,102 @@
+import { SummaryButton } from '@automattic/components';
+import { Meta, StoryObj } from '@storybook/react';
+import { Icon } from '@wordpress/components';
+import { brush, home, seen } from '@wordpress/icons';
+import { SummaryButtonList } from './';
+
+const meta: Meta< typeof SummaryButtonList > = {
+ title: 'client/dashboard/SummaryButtonList',
+ component: SummaryButtonList,
+ tags: [ 'autodocs' ],
+ parameters: {
+ actions: { argTypesRegex: '^on.*' },
+ },
+ decorators: [
+ ( Story ) => (
+
+
+
+ ),
+ ],
+};
+
+export default meta;
+type Story = StoryObj< typeof SummaryButtonList >;
+
+export const Default: Story = {
+ args: {
+ title: 'General Settings',
+ children: [
+ }
+ badges={ [ { text: 'Public', intent: 'success' } ] }
+ />,
+ }
+ badges={ [ { text: 'Twenty Twenty-Four' } ] }
+ />,
+ }
+ badges={ [ { text: 'Latest posts' } ] }
+ />,
+ ],
+ },
+};
+
+export const WithDescription: Story = {
+ args: {
+ ...Default.args,
+ description: 'Configure the basic settings for your site',
+ },
+};
+
+export const LowDensity: Story = {
+ args: {
+ ...Default.args,
+ density: 'low',
+ },
+};
+
+export const WithDescriptionsInButtons: Story = {
+ args: {
+ title: 'General Settings',
+ density: 'low',
+ children: [
+ }
+ badges={ [ { text: 'Public', intent: 'success' } ] }
+ />,
+ }
+ badges={ [ { text: 'Twenty Twenty-Four' } ] }
+ />,
+ }
+ badges={ [ { text: 'Latest posts' } ] }
+ />,
+ ],
+ },
+};
+
+export const Empty: Story = {
+ args: {
+ title: 'Empty Section',
+ description: 'This section has no buttons',
+ children: [],
+ },
+};
diff --git a/client/dashboard/components/summary-button-list/index.tsx b/client/dashboard/components/summary-button-list/index.tsx
new file mode 100644
index 000000000000..c70f597c9dfb
--- /dev/null
+++ b/client/dashboard/components/summary-button-list/index.tsx
@@ -0,0 +1,58 @@
+import { Card, CardHeader, __experimentalVStack as VStack } from '@wordpress/components';
+import clsx from 'clsx';
+import { isValidElement, cloneElement, Children, ReactElement } from 'react';
+import { SectionHeader } from '../section-header';
+import { SummaryButtonListProps } from './types';
+import './style.scss';
+
+/**
+ * The SummaryButtonList is a utility component that wraps multiple SummaryButton instances
+ * along with an optional section header. It provides consistent layout, spacing, and
+ * grouping behavior for presenting a collection of summary actions or options.
+ *
+ * This component ensures visual coherence and structural alignment when multiple
+ * SummaryButton elements are displayed together. It is intended for use in contexts
+ * where a list of summarised items or actions needs to be grouped under a shared
+ * label or heading.
+ */
+export function SummaryButtonList( {
+ title,
+ description,
+ density = 'medium',
+ children,
+}: SummaryButtonListProps ) {
+ const isMediumDensity = density === 'medium';
+ // Clone children and override their density prop.
+ const clonedChildren = Children.map( children, ( child ) => {
+ if ( isValidElement( child ) ) {
+ return cloneElement( child as ReactElement< { density?: string } >, { density } );
+ }
+ return child;
+ } );
+ const header = (
+
+ );
+ const className = clsx(
+ 'client-dashboard-components-summary-button-list',
+ `has-density-${ density }`
+ );
+ if ( isMediumDensity ) {
+ return (
+
+ { header }
+
+ { clonedChildren }
+
+
+ );
+ }
+ return (
+
+ { header }
+ { clonedChildren }
+
+ );
+}
diff --git a/client/dashboard/components/summary-button-list/style.scss b/client/dashboard/components/summary-button-list/style.scss
new file mode 100644
index 000000000000..400b10e4f51b
--- /dev/null
+++ b/client/dashboard/components/summary-button-list/style.scss
@@ -0,0 +1,31 @@
+@import "@wordpress/base-styles/variables";
+
+.client-dashboard-components-summary-button-list {
+
+ .client-dashboard-components-summary-button-list__heading {
+ margin: 0;
+ font-weight: $font-weight-medium;
+ }
+
+ &.has-density-low {
+ .client-dashboard-components-summary-button-list__heading {
+ font-size: $font-size-x-large;
+ line-height: $font-line-height-x-large;
+ }
+ }
+
+ &.has-density-medium {
+ .client-dashboard-components-summary-button-list__heading {
+ font-size: $font-size-large;
+ line-height: $font-line-height-large;
+ }
+
+ .client-dashboard-components-summary-button-list__children-container {
+ > *:last-child {
+ /* stylelint-disable-next-line scales/radii */
+ border-radius: 7px;
+ }
+
+ }
+ }
+}
diff --git a/client/dashboard/components/summary-button-list/test/index.tsx b/client/dashboard/components/summary-button-list/test/index.tsx
new file mode 100644
index 000000000000..34b4be3482b3
--- /dev/null
+++ b/client/dashboard/components/summary-button-list/test/index.tsx
@@ -0,0 +1,40 @@
+/**
+ * @jest-environment jsdom
+ */
+import '@testing-library/jest-dom';
+import { SummaryButton } from '@automattic/components';
+import { Density } from '@automattic/components/src/summary-button/types';
+import { render, screen } from '@testing-library/react';
+import * as React from 'react';
+import { SummaryButtonList } from '../index';
+
+describe( 'SummaryButtonList', () => {
+ it( 'renders a title and description', () => {
+ render(
+
+
+
+ );
+ const heading = screen.getByRole( 'heading', { name: 'My Settings' } );
+ expect( heading ).toBeVisible();
+ expect( screen.getByText( 'Configure your settings' ) ).toBeVisible();
+ } );
+ it( 'passes the density prop to children', () => {
+ interface TestChildProps {
+ density?: Density;
+ }
+ const TestChild = ( props: TestChildProps ) => (
+
+ );
+ render(
+
+
+
+ );
+ const testChild = screen.getByRole( 'button', { name: 'Test Child' } );
+ expect( testChild ).toBeVisible();
+ expect( testChild ).toHaveAttribute( 'data-density', 'low' );
+ } );
+} );
diff --git a/client/dashboard/components/summary-button-list/types.ts b/client/dashboard/components/summary-button-list/types.ts
new file mode 100644
index 000000000000..ea3779a681d1
--- /dev/null
+++ b/client/dashboard/components/summary-button-list/types.ts
@@ -0,0 +1,26 @@
+import { ReactNode } from 'react';
+import type { Density } from '@automattic/components/src/summary-button/types';
+
+export interface SummaryButtonListProps {
+ /**
+ * The main label that identifies the section.
+ */
+ title: string;
+ /**
+ * Optional supporting text that provides additional context or detail about the section.
+ */
+ description?: string;
+ /**
+ * The density of the component. This affects both the container styling
+ * and the density of child SummaryButton components. It should be one of the `Density` values
+ * from the SummaryButton component ('low|medium').
+ * @default 'medium'
+ */
+ density?: Density;
+ /**
+ * The child components should be either SummaryButton instances or components that
+ * wrap SummaryButton internally and pass the `density` prop to them. This is because
+ * the component will override the 'density' prop of these children to match the parent's density.
+ */
+ children: ReactNode;
+}
diff --git a/client/dashboard/sites/settings-site-visibility/summary.tsx b/client/dashboard/sites/settings-site-visibility/summary.tsx
index 9c20ff2542b7..28918fc7bf86 100644
--- a/client/dashboard/sites/settings-site-visibility/summary.tsx
+++ b/client/dashboard/sites/settings-site-visibility/summary.tsx
@@ -3,8 +3,15 @@ import { __ } from '@wordpress/i18n';
import { seen } from '@wordpress/icons';
import RouterLinkSummaryButton from '../../components/router-link-summary-button';
import type { Site } from '../../data/types';
+import type { Density } from '@automattic/components/src/summary-button/types';
-export default function SiteVisibilitySettingsSummary( { site }: { site: Site } ) {
+export default function SiteVisibilitySettingsSummary( {
+ site,
+ density,
+}: {
+ site: Site;
+ density?: Density;
+} ) {
let badges = [];
if ( site.launch_status === 'unlaunched' || site.is_coming_soon ) {
badges = [ { text: __( 'Coming soon' ), intent: 'warning' as const } ];
@@ -18,7 +25,7 @@ export default function SiteVisibilitySettingsSummary( { site }: { site: Site }
}
badges={ badges }
/>
diff --git a/client/dashboard/sites/settings-subscription-gifting/summary.tsx b/client/dashboard/sites/settings-subscription-gifting/summary.tsx
index 7d2de31a5ddd..98b4e33cfccd 100644
--- a/client/dashboard/sites/settings-subscription-gifting/summary.tsx
+++ b/client/dashboard/sites/settings-subscription-gifting/summary.tsx
@@ -4,13 +4,16 @@ import { heading } from '@wordpress/icons';
import RouterLinkSummaryButton from '../../components/router-link-summary-button';
import { hasSubscriptionGiftingFeature } from './utils';
import type { Site, SiteSettings } from '../../data/types';
+import type { Density } from '@automattic/components/src/summary-button/types';
export default function SubscriptionGiftingSettingsSummary( {
site,
settings,
+ density,
}: {
site: Site;
settings: SiteSettings;
+ density?: Density;
} ) {
if ( ! hasSubscriptionGiftingFeature( site ) ) {
return null;
@@ -19,7 +22,7 @@ export default function SubscriptionGiftingSettingsSummary( {
}
badges={
settings.wpcom_gifting_subscription
diff --git a/client/dashboard/sites/settings/danger-zone.tsx b/client/dashboard/sites/settings/danger-zone.tsx
index 9901d0733e0c..77a8f9ef87f8 100644
--- a/client/dashboard/sites/settings/danger-zone.tsx
+++ b/client/dashboard/sites/settings/danger-zone.tsx
@@ -1,7 +1,7 @@
-import { __experimentalHeading as Heading } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { ActionList } from '../../components/action-list';
import RouterLinkButton from '../../components/router-link-button';
+import { SectionHeader } from '../../components/section-header';
import { useCanTransferSite } from '../hooks/use-can-transfer-site';
import type { Site } from '../../data/types';
@@ -37,7 +37,7 @@ export default function DangerZone( { site }: { site: Site } ) {
return (
<>
- { __( 'Danger zone' ) }
+
{ actions }
>
);
diff --git a/client/dashboard/sites/settings/index.tsx b/client/dashboard/sites/settings/index.tsx
index 70ba669a716b..5a17925ed285 100644
--- a/client/dashboard/sites/settings/index.tsx
+++ b/client/dashboard/sites/settings/index.tsx
@@ -1,13 +1,9 @@
import { useQuery } from '@tanstack/react-query';
-import {
- __experimentalHeading as Heading,
- __experimentalVStack as VStack,
- Card,
-} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { siteQuery, siteSettingsQuery } from '../../app/queries';
import { PageHeader } from '../../components/page-header';
import PageLayout from '../../components/page-layout';
+import { SummaryButtonList } from '../../components/summary-button-list';
import SiteVisibilitySettingsSummary from '../settings-site-visibility/summary';
import SubscriptionGiftingSettingsSummary from '../settings-subscription-gifting/summary';
import WordPressSettingsSummary from '../settings-wordpress/summary';
@@ -24,19 +20,13 @@ export default function SiteSettings( { siteSlug }: { siteSlug: string } ) {
return (
}>
- { __( 'General' ) }
-
-
-
-
-
-
- { __( 'Server' ) }
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/client/dashboard/sites/settings/site-actions.tsx b/client/dashboard/sites/settings/site-actions.tsx
index 2320b191b649..eba32327a58d 100644
--- a/client/dashboard/sites/settings/site-actions.tsx
+++ b/client/dashboard/sites/settings/site-actions.tsx
@@ -1,11 +1,12 @@
import { useMutation } from '@tanstack/react-query';
-import { __experimentalHeading as Heading, Button } from '@wordpress/components';
+import { Button } from '@wordpress/components';
import { useDispatch } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
import { store as noticesStore } from '@wordpress/notices';
import { addQueryArgs } from '@wordpress/url';
import { restoreSitePlanSoftwareMutation } from '../../app/queries';
import { ActionList } from '../../components/action-list';
+import { SectionHeader } from '../../components/section-header';
import { DotcomFeatures } from '../../data/constants';
import type { Site } from '../../data/types';
@@ -88,7 +89,7 @@ export default function SiteActions( { site }: { site: Site } ) {
return (
<>
- { __( 'Actions' ) }
+
{ actions }
>
);
diff --git a/packages/components/src/summary-button/style.scss b/packages/components/src/summary-button/style.scss
index d71df3b6f293..00654ea3630c 100644
--- a/packages/components/src/summary-button/style.scss
+++ b/packages/components/src/summary-button/style.scss
@@ -73,13 +73,6 @@
padding: $grid-unit-15;
box-shadow: 0 2px 1px -1px $gray-100;
- // TODO: this should be handled better in `SummaryButtonList` component.
- // @see: https://github.com/Automattic/wp-calypso/pull/103233#issuecomment-2862541935
- &:focus-visible, &:hover:not(:disabled, [aria-disabled="true"]) {
- /* stylelint-disable-next-line scales/radii */
- border-radius: 7px;
- }
-
.summary-button-title {
@include body-medium;
}
diff --git a/packages/components/src/summary-button/types.ts b/packages/components/src/summary-button/types.ts
index c8ace8bf7417..39bb4762cffc 100644
--- a/packages/components/src/summary-button/types.ts
+++ b/packages/components/src/summary-button/types.ts
@@ -1,4 +1,4 @@
-type Density = 'low' | 'medium';
+export type Density = 'low' | 'medium';
/**
* `badges` property of `SummaryButton` component is used to display `CoreBadge`