diff --git a/src/css/common/_theme.scss b/src/css/common/_theme.scss index 7ef72fe22..dc877098f 100644 --- a/src/css/common/_theme.scss +++ b/src/css/common/_theme.scss @@ -9,6 +9,14 @@ $brand-facebook: #3b5998; $cloud: #00bcd4; $cloud-update: #ff9800; +// WordPress classic admin control palette. WP 7.0's "modern" redesign restyles native form +// controls; these restore the classic metrics our admin UI is designed around (see +// common/_wp-admin.scss). +$accent-hover: #0a4b78; +$control-border: #8c8f94; +$control-text: #2c3338; +$control-height: 30px; + /* format: background-color [color] */ $badges: ( php: #1d97c6, diff --git a/src/css/common/_wp-admin.scss b/src/css/common/_wp-admin.scss new file mode 100644 index 000000000..67b4a92a4 --- /dev/null +++ b/src/css/common/_wp-admin.scss @@ -0,0 +1,151 @@ +@use 'theme'; + +/** + * WordPress 7.0 admin compatibility. + * + * WP 7.0 ships the "modern" admin redesign, which enlarges native form controls + * (40px tall vs. 30/32px), reduces their corner radius (2px vs. 3/4px) and recolours + * secondary buttons with a transparent fill and the modern accent (#3858E9). Our admin + * UI was designed against the classic control metrics and the brand accent (#2271b1), + * so the redesign throws our spacing and colours out of alignment. + * + * These rules restore the classic control metrics for native elements inside our admin + * pages so the layout renders consistently on both WP 6.9 and WP 7.0. They deliberately + * leave the admin menu, admin bar and `@wordpress/components` React widgets untouched — + * only native inputs/buttons rendered inside our own markup are normalised. + */ + +@mixin classic-controls { + // Native single-line text controls and selects: restore 30px height + classic border. + // `@wordpress/components` inputs/selects (`.components-*`) keep their own design — they + // are excluded so React widgets such as the tags token field are left untouched. + // `.snippet-priority` (the borderless list-table priority field) is excluded so it keeps + // its plain transparent styling rather than gaining a bordered box. + input[type='text']:not([class*='components-']), + input[type='search']:not([class*='components-']), + input[type='number']:not([class*='components-'], .snippet-priority), + input[type='email']:not([class*='components-']), + input[type='url']:not([class*='components-']), + input[type='password']:not([class*='components-']), + input[type='tel']:not([class*='components-']) { + // `min-block-size` (not a fixed `block-size`) so controls floor at 30px but can still + // flex-stretch where the layout calls for it (e.g. the 54px cloud search bar). + min-block-size: theme.$control-height; + padding-block: 0; + padding-inline: 8px; + border: 1px solid theme.$control-border; + border-radius: 4px; + line-height: 2; + color: theme.$control-text; + font-size: 14px; + + &:focus { + border-color: theme.$accent; + box-shadow: 0 0 0 1px theme.$accent; + outline: 2px solid transparent; + } + } + + // Selects: same metrics, but preserve room for the WP dropdown chevron on the inline-end + // side. WP 7.0 keeps the chevron as a background image; clamping both paddings to 8px (as + // for text inputs) would let the arrow overlap the text, so the inline-end padding is wider. + select:not([class*='components-']) { + min-block-size: theme.$control-height; + padding-block: 0; + padding-inline: 8px 24px; + border: 1px solid theme.$control-border; + border-radius: 3px; + + // WP 7.0 leaves a tall (≈38px) line-height on selects, pushing the value off-centre in + // the 30px control. Pin it so the text stays vertically centred. + line-height: 2; + color: theme.$control-text; + font-size: 14px; + + &:focus { + border-color: theme.$accent; + box-shadow: 0 0 0 1px theme.$accent; + outline: 2px solid transparent; + } + } + + // Secondary buttons: restore classic geometry, the grey fill and the brand accent + // border/text in place of WP 7.0's transparent + modern-blue treatment. `.button-primary` + // is excluded so its solid fill below is not overwritten. + .button:not(.button-primary), + .button-secondary { + min-block-size: theme.$control-height; + padding-block: 0; + padding-inline: 12px; + border-radius: 3px; + line-height: 2.3077; + font-size: 13px; + font-weight: 400; + background: #f6f7f7; + border-color: theme.$accent; + color: theme.$accent; + + &:hover:not(:disabled) { + background: #f0f0f1; + border-color: theme.$accent-hover; + color: theme.$accent-hover; + } + + &:focus:not(:disabled) { + border-color: #3582c4; + box-shadow: 0 0 0 1px #3582c4; + outline: 2px solid transparent; + } + } + + // Primary buttons: WP 7.0 recolours these with the modern accent and drops the solid + // fill. Restore the classic solid brand-accent fill with white text. + .button-primary { + min-block-size: theme.$control-height; + padding-block: 0; + padding-inline: 12px; + border-radius: 3px; + line-height: 2.3077; + font-size: 13px; + font-weight: 400; + background: theme.$accent; + border-color: theme.$accent; + color: #fff; + + &:hover:not(:disabled) { + background: theme.$accent-hover; + border-color: theme.$accent-hover; + color: #fff; + } + + &:focus:not(:disabled) { + background: theme.$accent-hover; + border-color: theme.$accent-hover; + box-shadow: 0 0 0 1px #fff, 0 0 0 3px theme.$accent; + outline: 2px solid transparent; + } + } + + // Small buttons stay compact rather than inheriting the 40px control height. + .button-small { + min-block-size: 26px; + line-height: 2.1818; + font-size: 11px; + } + + // WP 7.0's taller button line-height leaks onto dashicon glyphs inside buttons (e.g. the + // conditions badge icon), pushing them out of vertical alignment. Reset it so icons stay + // centred — mirrors the existing `.button svg` rule for SVG icons. + .button .dashicons { + line-height: 1; + } +} + +// Scope to our admin page content. We intentionally keep this to a single `.wrap` class so +// the rules sit just above WordPress core defaults (which we must override) but below the +// plugin's own more-specific per-control rules, which are emitted later in each bundle and so +// win on equal specificity. This lets bespoke controls (conditions button, row-action links, +// priority input, etc.) keep their intended styling without per-element exclusions here. +.wrap { + @include classic-controls; +} diff --git a/src/css/edit.scss b/src/css/edit.scss index c08c4689d..5a3a92cc3 100644 --- a/src/css/edit.scss +++ b/src/css/edit.scss @@ -12,6 +12,7 @@ @use 'common/notices'; @use 'common/upsell'; @use 'common/toolbar'; +@use 'common/wp-admin'; @use 'edit/form'; @use 'edit/sidebar'; @use 'edit/editor'; diff --git a/src/css/edit/_sidebar.scss b/src/css/edit/_sidebar.scss index 0ba8c56a3..f08a86644 100644 --- a/src/css/edit/_sidebar.scss +++ b/src/css/edit/_sidebar.scss @@ -36,27 +36,45 @@ .row-actions { display: flex; + // Row-action buttons render as plain inline links. Neutralise the generic `.button` + // WP 7.0 compatibility styling (fill/border/radius/40px height) here — emitted after + // the wp-admin layer at equal specificity, so it wins. Export/Download inherit the accent. .button { + block-size: auto; + min-block-size: theme.$control-height; + padding-block: 0; + padding-inline: 10px; + border: 0; + border-radius: 0; background: none; - border: none; + box-shadow: none; + font-weight: 400; + + &:hover:not(:disabled), + &:focus:not(:disabled) { + background: none; + border: 0; + box-shadow: none; + } } - } - .delete-button { - color: #cc1818; + // Nested under `.row-actions` so the dark-red trash colour outranks the generic + // `.button` accent text colour from the wp-admin compatibility layer. + .delete-button { + color: #cc1818; - &:disabled { - color: #a7aaad; - cursor: not-allowed; - } + &:disabled { + color: #a7aaad; + cursor: not-allowed; + } - &:hover:not(:disabled) { - color: #9e1313; - } + &:hover:not(:disabled) { + color: #9e1313; + } - &:focus:not(:disabled) { - color: #710d0d; - border-color: #710d0d; + &:focus:not(:disabled) { + color: #710d0d; + } } } diff --git a/src/css/import.scss b/src/css/import.scss index d79b507ab..c53285e62 100644 --- a/src/css/import.scss +++ b/src/css/import.scss @@ -1,4 +1,5 @@ @use 'common/toolbar'; +@use 'common/wp-admin'; @use 'import/page'; @use 'import/card'; @use 'import/upload'; diff --git a/src/css/import/_upload.scss b/src/css/import/_upload.scss index 9d0062ebf..4c90abb32 100644 --- a/src/css/import/_upload.scss +++ b/src/css/import/_upload.scss @@ -55,7 +55,7 @@ $type-colors: ( .drop-zone-icon { font-size: 48px; - margin-block-end: 10px; + margin-block-end: 20px; color: #666; } diff --git a/src/css/manage.scss b/src/css/manage.scss index d526c4b7a..ad5183bd6 100644 --- a/src/css/manage.scss +++ b/src/css/manage.scss @@ -7,6 +7,7 @@ @use 'common/notices'; @use 'common/upsell'; @use 'common/toolbar'; +@use 'common/wp-admin'; @use 'prism'; @use 'manage/snippets-table'; @use 'manage/cloud-community'; diff --git a/src/css/manage/_cloud-community.scss b/src/css/manage/_cloud-community.scss index 93143046f..209b60162 100644 --- a/src/css/manage/_cloud-community.scss +++ b/src/css/manage/_cloud-community.scss @@ -185,7 +185,9 @@ margin: 0; } -.cloud-pro-button.button { +// Anchored to the card container so this keeps its brand-orange fill above the WP-admin +// compatibility layer's secondary-button styling (equal specificity, resolved by source order). +.cloud-search-result .cloud-pro-button.button { background-color: theme.$secondary; border-color: theme.$secondary; color: #fff; diff --git a/src/css/manage/_snippets-table.scss b/src/css/manage/_snippets-table.scss index 5a37fb8d9..abb4322b5 100644 --- a/src/css/manage/_snippets-table.scss +++ b/src/css/manage/_snippets-table.scss @@ -31,6 +31,31 @@ font-weight: 600; } +// WP 7.0 changes the default admin link colour to the modern blue. Pin the classic accent on +// active rows (names and row-action links) so links keep their original colour; inactive rows +// are handled by the muted link-colors mixin below, and the trash button keeps its dark red +// from the `.delete` rule further down. +.wp-list-table .active-snippet a { + color: theme.$accent; + + &:hover, + &:focus { + color: theme.$accent-hover; + } +} + +// Status filter links (All | Active | Inactive | …): WP 7.0 recolours these with the modern +// blue. Restore the classic accent for non-current links; the current one keeps its own colour. +/* stylelint-disable-next-line no-descending-specificity -- unrelated element; ordering is fine. */ +.subsubsub a:not(.current) { + color: theme.$accent; + + &:hover, + &:focus { + color: theme.$accent-hover; + } +} + .active-snippet { td, th { background-color: rgba(#78c8e6, 0.06); @@ -41,12 +66,26 @@ } } -.priority-column input { +// `.wp-list-table` prefix keeps this above WP 7.0's 40px control height so the borderless +// priority field stays 30px tall and vertically aligned with the rest of the row. +.wp-list-table .priority-column input { appearance: none; background: none; border: none; box-shadow: none; + box-sizing: border-box; + min-block-size: theme.$control-height; + block-size: theme.$control-height; inline-size: 4em; + + // Pin the box model so padding/margins/line-height match WP 6.9 regardless of WP 7.0's + // taller default control metrics; this keeps the value aligned in both the resting and + // hovered (native spinner) states. + padding-block: 0; + padding-inline: 8px; + margin-block: 0; + margin-inline: 1px; + line-height: 2; color: #666; text-align: center; @@ -113,13 +152,30 @@ position: relative; inset-inline-start: 0; + // Row-action buttons render as plain inline links. On WP 7.0 the generic `.button` + // compatibility styling would otherwise give them a fill, border, radius and fixed + // height, so fully neutralise it here (this rule is emitted after the wp-admin layer + // at equal specificity, so it wins). Non-delete links inherit the accent text colour. .button-link { - min-block-size: unset; - line-height: unset; - border: none; - - &:hover { + block-size: auto; + min-block-size: 0; + padding: 0; + border: 0; + border-radius: 0; + background: none; + box-shadow: none; + line-height: inherit; + font-weight: 400; + + &:hover:not(:disabled), + &:focus:not(:disabled) { background: none; + border: 0; + box-shadow: none; + } + + &.delete { + color: #b32d2e; } } diff --git a/src/css/menu.scss b/src/css/menu.scss index 074e4e741..e329afa5c 100644 --- a/src/css/menu.scss +++ b/src/css/menu.scss @@ -1,3 +1,5 @@ +@use 'common/theme'; + #adminmenu { .toplevel_page_snippets div.wp-menu-image::before { content: ''; @@ -11,6 +13,15 @@ color: #fff; background-color: #d46f4d; border: none; + + // WP 7.0 restyles `.button`/`.button-primary` with wider padding, a 2px radius and a + // 40px min-height; pin these so the menu pill keeps its classic dimensions and stays + // aligned with the surrounding submenu items across WP versions. + border-radius: 3px; + padding-block: 0; + padding-inline: 10px; + min-block-size: theme.$control-height; + block-size: auto; text-align: center; font-weight: bold; transition: background-color .1s linear; @@ -31,6 +42,10 @@ .dashicons { vertical-align: text-bottom; color: inherit; + + // WP 7.0's taller button line-height (≈38px) leaks onto the icon and pushes it out + // of alignment; reset it so the glyph stays centred within the flex pill. + line-height: 1; } } diff --git a/src/css/settings.scss b/src/css/settings.scss index 54b451ec7..f7383b431 100644 --- a/src/css/settings.scss +++ b/src/css/settings.scss @@ -1,5 +1,6 @@ @use 'common/codemirror'; @use 'common/toolbar'; +@use 'common/wp-admin'; $sections: general, editor, debug, version-switch; diff --git a/src/css/welcome.scss b/src/css/welcome.scss index 61ec73b7d..f3eaca227 100644 --- a/src/css/welcome.scss +++ b/src/css/welcome.scss @@ -2,6 +2,7 @@ @use 'common/theme'; @use 'common/badges'; @use 'common/toolbar'; +@use 'common/wp-admin'; $breakpoint: 1060px; diff --git a/src/js/components/common/ListTable/ListTable.tsx b/src/js/components/common/ListTable/ListTable.tsx index ab8c1339f..86fcc7f1b 100644 --- a/src/js/components/common/ListTable/ListTable.tsx +++ b/src/js/components/common/ListTable/ListTable.tsx @@ -137,6 +137,9 @@ export const ListTable = ({ extraTableNav, disabled = false, useQueryVars = true, + fixed, + striped, + className, ...tableRowsProps }: ListTableProps) => { const [selected, setSelected] = useState(() => new Set()) @@ -147,7 +150,6 @@ export const ListTable = ({ const visibleItems: T[] = useMemo( () => pageItems(sortItems(items, sortColumn, sortDirection), { currentPage, totalPages }), [items, sortColumn, sortDirection, currentPage, totalPages]) - return ( ({ >