refactor(header): unify top icon-cards on single zib-widget path #11

Merged
kate522 merged 1 commits from worktree-federated-meandering-harbor into main 2026-08-19 13:47:30 +00:00
9 changed files with 17 additions and 176 deletions
Showing only changes of commit 304d0bde74 - Show all commits
+1 -11
View File
@@ -37,15 +37,6 @@ body {
background-color: var(--surface-page);
}
/* Shared horizontal icon-card contract.
* Header components and widget areas use different layout wrappers, but the
* card itself must retain the compact Zibll proportions in every context. */
.icon-cover-card.aksrt-icon-cover-card {
padding: 10px;
font-size: 16px;
line-height: 1.6;
}
/* zibll compat: global link composite transition */
a[href] {
transition: color 0.2s, background 0.3s, opacity 0.3s, box-shadow 0.3s, transform 0.3s;
@@ -100,8 +91,7 @@ main.container,
/* Header multifunc icon cards need horizontal gutter (zibll content rows).
* Global .container padding is 0 for dual-column float math. */
.header-slider-card.container,
.header-components-card.container {
.header-slider-card.container {
padding-left: 15px;
padding-right: 15px;
box-sizing: border-box;
-143
View File
@@ -1,143 +0,0 @@
/* ============================================================
* Header icon cards — unified geometry (zibll 1:1)
*
* The top multi-function component ("顶部多功能组件") renders its icon
* cards through one path: aksrt_header_slide() →
* aksrt_icon_cover_card() (see inc/helpers/homepage/header-components.php
* and inc/helpers/aksrt-icon-cards.php). This file is the single source of
* truth for their size/layout, loaded after Zibll main.min.css on every
* page so cards stay identical across home / archive / single / search.
*
* DOM: .header-slider-card.container
* > (.zib-widget.padding-10 | div)
* > .flex.jse.flex-row.gutters-5.flex-col-sm-2
* > (.flex1 | .relative-h)
* > [.main-color] .icon-cover-card.aksrt-icon-cover-card.flex.ac.(zib-widget|padding-10)
* > .icon-cover-icon.badg.cir.(c-*|jb-*)[.radius4] (the badge)
* > .icon-cover-desc.ml10.flex1.px12-sm
* ============================================================ */
/* --- Equal-width cells + zibll gutters (both header wrapper aliases) --- */
.header-slider-card .flex,
.header-components-card .flex {
display: flex;
}
.header-slider-card .flex.jse,
.header-components-card .flex.jse,
.header-slider-card .jse,
.header-components-card .jse {
justify-content: space-evenly;
}
.header-slider-card .flex-row,
.header-components-card .flex-row {
flex-direction: row;
}
.header-slider-card .flex.ac,
.header-components-card .flex.ac,
.header-slider-card .ac,
.header-components-card .ac {
align-items: center;
}
.header-slider-card .gutters-5,
.header-components-card .gutters-5,
.header-slider-card .flex.jse.flex-row,
.header-components-card .flex.jse.flex-row {
margin: -5px;
}
.header-slider-card .gutters-5 > *,
.header-components-card .gutters-5 > *,
.header-slider-card .flex.jse.flex-row > *,
.header-components-card .flex.jse.flex-row > * {
padding: 5px !important;
box-sizing: border-box;
}
/* Higher-specificity scope selector wins over the single-post-only
* zibll-utilities.css `.flex1{flex:1 1 auto}` so every card is equal-width:
* zibll uses `flex:1; overflow:hidden`. */
.header-slider-card .flex1,
.header-components-card .flex1,
.header-slider-card .flex .flex1,
.header-components-card .flex .flex1 {
flex: 1 1 0;
overflow: hidden;
min-width: 0;
}
.header-slider-card .relative-h,
.header-components-card .relative-h {
position: relative;
height: 100%;
}
.header-slider-card,
.header-components-card {
position: relative;
margin-top: -40px;
z-index: 1;
width: 100%;
}
.header-slider-card .zib-widget,
.header-components-card .zib-widget {
margin-bottom: 0;
}
/* --- Card box: compact zibll proportions in every context --- */
.icon-cover-card.aksrt-icon-cover-card {
padding: 10px;
font-size: 16px;
line-height: 1.6;
height: 100%;
box-sizing: border-box;
}
/* --- Icon badge: fixed size so a custom (non-FA) icon cannot stretch it --- */
.icon-cover-card .icon-cover-icon {
display: flex;
align-items: center;
justify-content: center;
width: 45px;
height: 45px;
min-width: 45px;
font-size: 25px;
flex: 0 0 auto;
box-sizing: border-box;
}
.icon-cover-card .icon-cover-icon > img,
.icon-cover-card .icon-cover-icon > svg {
width: 1.6em;
height: 1.6em;
max-width: 1.6em;
max-height: 1.6em;
object-fit: contain;
}
/* --- Text column: equal truncation --- */
.icon-cover-card .icon-cover-desc {
min-width: 0;
}
/* --- Mobile: two columns + zibll padding overrides --- */
@media (max-width: 767px) {
.header-slider-card,
.header-components-card {
margin-top: -35px;
}
.header-slider-card .flex.flex-row.flex-col-sm-2,
.header-components-card .flex.flex-row.flex-col-sm-2 {
flex-wrap: wrap;
}
.header-slider-card .flex.flex-row.flex-col-sm-2 > *,
.header-components-card .flex.flex-row.flex-col-sm-2 > * {
flex-basis: 50%;
}
.header-slider-card .icon-cover-card.zib-widget,
.header-components-card .icon-cover-card.zib-widget {
padding: 10px;
}
.header-slider-card .icon-cover-card.padding-10,
.header-components-card .icon-cover-card.padding-10 {
padding: 2px;
}
}
+1 -1
View File
@@ -282,7 +282,7 @@ if (!function_exists('aksrt_icon_cover_card')) :
}
// Keep every horizontal icon card on the same compact visual contract,
// regardless of the page-specific wrapper that renders it.
$html .= '<div class="icon-cover-card aksrt-icon-cover-card flex ac ' . esc_attr((string) $args['class']) . '">';
$html .= '<div class="icon-cover-card flex ac ' . esc_attr((string) $args['class']) . '">';
$html .= $icon;
$html .= $text !== '' ? '<div class="icon-cover-desc ml10 flex1 px12-sm"> ' . $text . '</div>' : '';
$html .= '</div>';
+3 -6
View File
@@ -415,27 +415,24 @@ if (!function_exists('aksrt_header_slide')) {
$card_count = 0;
if (aksrt_header_slider_device_is_visible($args['header_slider_card_s'] ?? [])) {
$card_options = wp_parse_args((array) ($args['header_slider_card_option'] ?? []), [
'show_widget_bg' => false, 'icon_radius4' => false, 'cards' => [],
'icon_radius4' => false, 'cards' => [],
]);
$items = '';
foreach ((array) $card_options['cards'] as $card) {
if (!is_array($card) || (empty($card['icon']) && empty($card['customize_icon']) && empty($card['custom_icon']) && empty($card['icon_image']))) {
continue;
}
$card['class'] = !empty($card_options['show_widget_bg']) ? 'padding-10' : 'zib-widget';
$card['icon_class'] = trim((string) ($card['icon_class'] ?? '') . (!empty($card_options['icon_radius4']) ? ' radius4' : ''));
$inner = function_exists('aksrt_icon_cover_card') ? aksrt_icon_cover_card($card) : '';
if ($inner === '') {
continue;
}
$items .= !empty($card_options['show_widget_bg']) ? '<div class="relative-h">' : '<div class="flex1">';
$items .= $inner . '</div>';
$items .= '<div class="flex1">' . $inner . '</div>';
$card_count++;
}
if ($items !== '') {
$cards_html = '<div class="header-slider-card container">'
. (!empty($card_options['show_widget_bg']) ? '<div class="zib-widget padding-10">' : '<div class="">')
. '<div class="flex jse flex-row gutters-5 flex-col-sm-2">' . $items . '</div></div></div>';
. '<div class="flex jse flex-row gutters-5 flex-col-sm-2">' . $items . '</div></div>';
}
}
+2 -2
View File
@@ -262,7 +262,7 @@ final class PageConfigMetaBox {
],
];
}
return ['show_widget_bg' => !empty($value['show_widget_bg']), 'icon_radius4' => !empty($value['icon_radius4']), 'cards' => $cards];
return ['icon_radius4' => !empty($value['icon_radius4']), 'cards' => $cards];
}
/** @return array<string,mixed> */
@@ -293,7 +293,7 @@ final class PageConfigMetaBox {
/** @return array<string,mixed> */
private static function card_defaults(): array {
return ['show_widget_bg' => false, 'icon_radius4' => false, 'cards' => [
return ['icon_radius4' => false, 'cards' => [
['icon' => 'zibsvg-vip_1', 'customize_icon' => '', 'icon_class' => 'c-yellow', 'link' => [], 'title' => '图标卡片', 'desc' => '这是一个图标卡片示例'],
['icon' => 'zibsvg-vip_2', 'customize_icon' => '', 'icon_class' => 'c-blue-2', 'link' => [], 'title' => '原创作品', 'desc' => '这是一个图标卡片示例'],
['icon' => 'zibsvg-hot', 'customize_icon' => '', 'icon_class' => 'jb-pink', 'link' => [], 'title' => '灵感来源<badge class="ml6 jb-yellow">NEW</badge>', 'desc' => '这是一个图标卡片示例'],
+2 -2
View File
@@ -183,7 +183,7 @@ class SchemaPageDisplay {
}
private static function card_fields(): array {
return [self::field('show_widget_bg', '模块背景', 'switcher', false), self::field('icon_radius4', '方形图标', 'switcher', false), self::field('cards', '添加卡片', 'group', [], ['button_title' => '添加内容', 'fields' => [self::field('title', '文案标题', 'textarea', '', ['sanitize_type' => 'html']), self::field('desc', '文案简介', 'textarea', '', ['sanitize_type' => 'html']), self::field('icon', '选择图标', 'icon', 'fa fa-magic'), self::field('customize_icon', '自定义图标', 'textarea', '', ['sanitize_type' => 'html']), self::field('icon_class', '图标颜色', 'palette', 'c-yellow', ['options' => self::zib_palette(true)]), self::field('link', '跳转链接', 'link', [])]])];
return [self::field('icon_radius4', '方形图标', 'switcher', false), self::field('cards', '添加卡片', 'group', [], ['button_title' => '添加内容', 'fields' => [self::field('title', '文案标题', 'textarea', '', ['sanitize_type' => 'html']), self::field('desc', '文案简介', 'textarea', '', ['sanitize_type' => 'html']), self::field('icon', '选择图标', 'icon', 'fa fa-magic'), self::field('customize_icon', '自定义图标', 'textarea', '', ['sanitize_type' => 'html']), self::field('icon_class', '图标颜色', 'palette', 'c-yellow', ['options' => self::zib_palette(true)]), self::field('link', '跳转链接', 'link', [])]])];
}
private static function orderby_fields(): array { return [self::field('lists', '显示排序方式', 'select', ['modified', 'views', 'like', 'comment_count'], ['multiple' => true, 'sortable' => true, 'options' => self::post_order_options(false)]), self::field('dropdown', '更多排序方式', 'switcher', false)]; }
@@ -192,7 +192,7 @@ class SchemaPageDisplay {
private static function header_slider_defaults(): array { $img = self::asset('assets/vendor/zibll/img/'); return [['background' => $img . 'slider-bg.jpg', 'link' => ['url' => 'https://www.zibll.com/', 'target' => '_blank'], 'text' => ['title' => '', 'desc' => ''], 'text_align' => 'left-bottom', 'text_parallax' => 30, 'text_size_m' => 20, 'text_size_pc' => 30], ['background' => $img . 'user_t.jpg', 'link' => ['url' => 'https://www.zibll.com/', 'target' => '_blank'], 'text' => ['title' => '', 'desc' => ''], 'text_align' => 'left-bottom', 'text_parallax' => 30, 'text_size_m' => 20, 'text_size_pc' => 30]]; }
private static function slider_options_defaults(): array { return ['direction' => 'horizontal', 'loop' => true, 'button' => true, 'pagination' => true, 'effect' => 'slide', 'scale_height' => false, 'auto_height' => false, 'pc_height' => 550, 'm_height' => 280, 'spacebetween' => 0, 'speed' => 0, 'autoplay' => true, 'interval' => 6]; }
private static function search_defaults(): array { return ['show_keywords' => true, 'popular_limit' => 6, 'show_input_cat' => false, 'in_cat' => '', 'more_cats' => '', 'show_type' => false, 'in_type' => 'post', 'before_html' => '<div class="em16 font-bold mb10">更优雅的Wordpress主题</div>' . "\n" . '<div>这是导航栏幻灯片多功能组件,可在后台进行配置</div>', 'after_html' => '']; }
private static function card_defaults(): array { return ['show_widget_bg' => false, 'icon_radius4' => false, 'cards' => [['icon' => 'zibsvg-vip_1', 'customize_icon' => '', 'icon_class' => 'c-yellow', 'link' => [], 'title' => '图标卡片', 'desc' => '这是一个图标卡片示例'], ['icon' => 'zibsvg-vip_2', 'customize_icon' => '', 'icon_class' => 'c-blue-2', 'link' => [], 'title' => '原创作品', 'desc' => '这是一个图标卡片示例'], ['icon' => 'zibsvg-hot', 'customize_icon' => '', 'icon_class' => 'jb-pink', 'link' => [], 'title' => '灵感来源<badge class="ml6 jb-yellow">NEW</badge>', 'desc' => '这是一个图标卡片示例'], ['icon' => 'fa fa-ioxhost', 'customize_icon' => '', 'icon_class' => 'jb-cyan', 'link' => [], 'title' => '系统工具 <badge class="ml6 jb-blue">GO <span class="fa fa-angle-right em12"></span></badge>', 'desc' => '这是一个图标卡片示例']]]; }
private static function card_defaults(): array { return ['icon_radius4' => false, 'cards' => [['icon' => 'zibsvg-vip_1', 'customize_icon' => '', 'icon_class' => 'c-yellow', 'link' => [], 'title' => '图标卡片', 'desc' => '这是一个图标卡片示例'], ['icon' => 'zibsvg-vip_2', 'customize_icon' => '', 'icon_class' => 'c-blue-2', 'link' => [], 'title' => '原创作品', 'desc' => '这是一个图标卡片示例'], ['icon' => 'zibsvg-hot', 'customize_icon' => '', 'icon_class' => 'jb-pink', 'link' => [], 'title' => '灵感来源<badge class="ml6 jb-yellow">NEW</badge>', 'desc' => '这是一个图标卡片示例'], ['icon' => 'fa fa-ioxhost', 'customize_icon' => '', 'icon_class' => 'jb-cyan', 'link' => [], 'title' => '系统工具 <badge class="ml6 jb-blue">GO <span class="fa fa-angle-right em12"></span></badge>', 'desc' => '这是一个图标卡片示例']]]; }
private static function field(string $key, string $label, string $type, $default = null, array $extra = []): array { return array_merge(['key' => $key, 'label' => $label, 'type' => $type, 'default' => $default], $extra); }
private static function notice(string $content): array { return ['key' => '_notice_' . md5($content), 'type' => 'notice', 'content' => $content, 'tone' => 'warning']; }
-1
View File
@@ -106,7 +106,6 @@ trait ScriptsPart1b {
// AKSRT domain styles load after Zibll main.css. The old aggregate is
// intentionally not used because it contains the removed navigation CSS.
$enqueue_module('base');
$enqueue_module('header-cards');
$enqueue_module('card-primitives');
$enqueue_module('overlay-primitives');
$enqueue_module('layout');
-1
View File
@@ -132,7 +132,6 @@ trait DisplayPageGroups {
/** @return array<string,mixed> */
private static function header_slider_card_defaults(): array {
return [
'show_widget_bg' => false,
'icon_radius4' => false,
'cards' => [
['icon' => 'zibsvg-vip_1', 'customize_icon' => '', 'icon_class' => 'c-yellow', 'link' => [], 'title' => '图标卡片', 'desc' => '这是一个图标卡片示例'],
@@ -14,25 +14,24 @@ test('icon card renderers keep vertical and horizontal Zibll DOM contracts separ
const header = read('inc/helpers/homepage/header-components.php');
assert.match(helper, /<div class="icon-card /);
assert.match(helper, /<div class="icon-cover-card aksrt-icon-cover-card flex ac /);
assert.match(helper, /<div class="icon-cover-card flex ac /);
assert.match(helper, /icon-cover-icon badg cir/);
assert.match(helper, /icon-cover-desc ml10 flex1 px12-sm/);
assert.match(helper, /aksrt-icon-cover-card/);
assert.doesNotMatch(helper, /aksrt-icon-cover-card/);
assert.match(widgets, /'customize_icon' => \$card\['customize_icon'\] \?\? ''/);
assert.match(widgets, /'custom_icon'\s+=> \$card\['custom_icon'\] \?\? ''/);
assert.match(widgets, /'icon_image'\s+=> \$card\['icon_image'\] \?\? ''/);
assert.match(header, /empty\(\$card\['custom_icon'\]\)/);
});
test('homepage horizontal cards use the shared compact card contract and retain Zibll responsive rules', () => {
const css = read('assets/css/frontend/header-cards.css');
test('homepage horizontal cards render fully from Zibll CSS with no dedicated stylesheet', () => {
const baseCss = read('assets/css/frontend/base.css');
const widgetCss = read('assets/widgets/frontend.css');
const scripts = read('src/Core/ScriptsPart1b.php');
assert.match(baseCss, /\.icon-cover-card\.aksrt-icon-cover-card\s*\{\s*padding:\s*10px;\s*font-size:\s*16px;/);
assert.match(css, /\.icon-cover-card\.zib-widget[\s\S]*?padding:\s*10px;/);
assert.match(css, /\.icon-cover-card\.padding-10[\s\S]*?padding:\s*2px;/);
assert.doesNotMatch(css, /\.header-slider-card \.icon-cover-icon\.badg\.cir/);
assert.doesNotMatch(css, /\.header-slider-card \.icon-cover-icon img/);
assert.equal(fs.existsSync(path.join(root, 'assets/css/frontend/header-cards.css')), false);
assert.doesNotMatch(baseCss, /\.icon-cover-card\.aksrt-icon-cover-card/);
assert.doesNotMatch(baseCss, /\.header-components-card/);
assert.doesNotMatch(scripts, /header-cards/);
assert.doesNotMatch(widgetCss, /aksrt-widget-icon-cards \.icon-cover-card/);
});