feat(widgets): Highlights animate + ComboInfo gutters/style depth
Add scroll-in animation and lazy covers for highlights; combo cards use row gutters, zibll CSS vars, and optional obs animation.
This commit is contained in:
@@ -44,16 +44,29 @@ class WidgetComboInfo extends \WP_Widget {
|
||||
echo $args['before_title'] . esc_html($title) . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
|
||||
$style = sprintf('--aksrt-zci-radius:%dpx;--aksrt-zci-band-h:%dpx;--aksrt-zci-pc:%d;--aksrt-zci-m:%d;', $radius, $band_h, $pc_row, $m_row);
|
||||
$wrap = 'aksrt-combo-info' . ($top_band ? ' has-band' : '');
|
||||
$style = sprintf('--aksrt-zci-radius:%dpx;--aksrt-zci-band-h:%dpx;--aksrt-zci-pc:%d;--aksrt-zci-m:%d;--zci-radius:%dpx;--zci-band-h:%dpx;', $radius, $band_h, $pc_row, $m_row, $radius, $band_h);
|
||||
$wrap = 'aksrt-combo-info zib-combo-info-card row gutters-10' . ($top_band ? ' has-band zci-has-band' : '');
|
||||
$anim = sanitize_key((string) ($instance['obs_animation'] ?? ''));
|
||||
$anim_repeat = !empty($instance['animation_repeat']);
|
||||
$pc_span = max(1, (int) floor(12 / $pc_row));
|
||||
$m_span = max(1, (int) floor(12 / $m_row));
|
||||
$col = 'col-sm-' . $pc_span . ' col-xs-' . $m_span;
|
||||
|
||||
echo '<div class="' . esc_attr($wrap) . '" style="' . esc_attr($style) . '">';
|
||||
$auto_idx = 0;
|
||||
$ci = 0;
|
||||
foreach ($cards as $card) {
|
||||
$html = $this->render_card($card, $cta_default, $auto_idx, $go_link, $top_band);
|
||||
if ($html !== '') {
|
||||
echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
if ($html === '') {
|
||||
continue;
|
||||
}
|
||||
$pack = function_exists('aksrt_obs_animate_attrs')
|
||||
? aksrt_obs_animate_attrs($anim, $anim_repeat, $ci * 0.1)
|
||||
: ['class' => '', 'attr' => ''];
|
||||
echo '<div class="' . esc_attr(trim($col . $pack['class'])) . '"' . $pack['attr'] . '>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
echo '</div>';
|
||||
$ci++;
|
||||
}
|
||||
echo '</div>';
|
||||
|
||||
@@ -219,6 +232,16 @@ class WidgetComboInfo extends \WP_Widget {
|
||||
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('top_band')); ?>" value="1" <?php checked(!empty($instance['top_band']) || !isset($instance['top_band'])); ?>> <?php esc_html_e('顶部色带', 'aksrt'); ?></label><br>
|
||||
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('go_link')); ?>" value="1" <?php checked(!empty($instance['go_link'])); ?>> <?php esc_html_e('外链跳转页', 'aksrt'); ?></label>
|
||||
</p>
|
||||
<p>
|
||||
<label><?php esc_html_e('入场动画', 'aksrt'); ?>
|
||||
<select name="<?php echo esc_attr($this->get_field_name('obs_animation')); ?>">
|
||||
<option value="" <?php selected(($instance['obs_animation'] ?? ''), ''); ?>><?php esc_html_e('无', 'aksrt'); ?></option>
|
||||
<option value="slideup" <?php selected(($instance['obs_animation'] ?? ''), 'slideup'); ?>><?php esc_html_e('上滑', 'aksrt'); ?></option>
|
||||
<option value="fade" <?php selected(($instance['obs_animation'] ?? ''), 'fade'); ?>><?php esc_html_e('淡入', 'aksrt'); ?></option>
|
||||
<option value="zoomin" <?php selected(($instance['obs_animation'] ?? ''), 'zoomin'); ?>><?php esc_html_e('放大', 'aksrt'); ?></option>
|
||||
</select>
|
||||
</label>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
@@ -233,6 +256,8 @@ class WidgetComboInfo extends \WP_Widget {
|
||||
'top_band_height' => max(20, min(160, (int) ($new_instance['top_band_height'] ?? 70))),
|
||||
'cta_text' => sanitize_text_field((string) ($new_instance['cta_text'] ?? '')),
|
||||
'go_link' => !empty($new_instance['go_link']) ? 1 : 0,
|
||||
'obs_animation' => sanitize_key((string) ($new_instance['obs_animation'] ?? '')),
|
||||
'animation_repeat'=> !empty($new_instance['animation_repeat']) ? 1 : 0,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Highlights cards (zibll zib_widget_highlights lite).
|
||||
* Highlights cards (zibll zib_widget_highlights) with scroll animation + go_link.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
@@ -22,12 +22,18 @@ class WidgetHighlights extends \WP_Widget {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $args
|
||||
* @param array<string,mixed> $instance
|
||||
*/
|
||||
public function widget($args, $instance): void {
|
||||
$cards = $this->normalize($instance['cards'] ?? []);
|
||||
if (!$cards) {
|
||||
return;
|
||||
}
|
||||
$go_link = !empty($instance['go_link']);
|
||||
$anim = sanitize_key((string) ($instance['obs_animation'] ?? 'slideup'));
|
||||
$anim_repeat = !empty($instance['animation_repeat']);
|
||||
|
||||
echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
$title = apply_filters('widget_title', (string) ($instance['title'] ?? ''), $instance, $this->id_base);
|
||||
@@ -38,30 +44,23 @@ class WidgetHighlights extends \WP_Widget {
|
||||
$large = array_values(array_filter($cards, static fn($c) => ($c['size'] ?? 'medium') === 'large'));
|
||||
$medium = array_values(array_filter($cards, static fn($c) => ($c['size'] ?? 'medium') === 'medium'));
|
||||
$small = array_values(array_filter($cards, static fn($c) => ($c['size'] ?? 'medium') === 'small'));
|
||||
// Fallback: if no size tags, treat all as medium.
|
||||
if (!$large && !$medium && !$small) {
|
||||
$medium = $cards;
|
||||
}
|
||||
|
||||
echo '<div class="aksrt-highlights">';
|
||||
if ($large) {
|
||||
echo '<div class="aksrt-highlights__row is-large">';
|
||||
foreach ($large as $c) {
|
||||
echo $this->card($c, 'large', $go_link); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
$idx = 0;
|
||||
foreach (['large' => $large, 'medium' => $medium, 'small' => $small] as $size => $group) {
|
||||
if (!$group) {
|
||||
continue;
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
if ($medium) {
|
||||
echo '<div class="aksrt-highlights__row is-medium">';
|
||||
foreach ($medium as $c) {
|
||||
echo $this->card($c, 'medium', $go_link); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
if ($small) {
|
||||
echo '<div class="aksrt-highlights__row is-small">';
|
||||
foreach ($small as $c) {
|
||||
echo $this->card($c, 'small', $go_link); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
echo '<div class="aksrt-highlights__row is-' . esc_attr($size) . '">';
|
||||
foreach ($group as $c) {
|
||||
$pack = function_exists('aksrt_obs_animate_attrs')
|
||||
? aksrt_obs_animate_attrs($anim, $anim_repeat, $idx * 0.08)
|
||||
: ['class' => '', 'attr' => ''];
|
||||
echo $this->card($c, $size, $go_link, $pack); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
$idx++;
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
@@ -72,8 +71,9 @@ class WidgetHighlights extends \WP_Widget {
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $c
|
||||
* @param array{class:string,attr:string} $pack
|
||||
*/
|
||||
private function card(array $c, string $size, bool $go_link): string {
|
||||
private function card(array $c, string $size, bool $go_link, array $pack): string {
|
||||
$color = sanitize_key((string) ($c['color'] ?? 'blue'));
|
||||
if (!in_array($color, ['blue', 'pink', 'purple', 'green', 'orange', 'cyan'], true)) {
|
||||
$color = 'blue';
|
||||
@@ -85,9 +85,11 @@ class WidgetHighlights extends \WP_Widget {
|
||||
$tag = $url !== '' ? 'a' : 'div';
|
||||
$href = $url !== '' ? ' href="' . esc_url($url) . '"' : '';
|
||||
$img = (string) ($c['image'] ?? '');
|
||||
$html = '<' . $tag . ' class="aksrt-hl-card size-' . esc_attr($size) . ' color-' . esc_attr($color) . '"' . $href . '>';
|
||||
$cls = 'aksrt-hl-card size-' . esc_attr($size) . ' color-' . esc_attr($color) . $pack['class'];
|
||||
$html = '<' . $tag . ' class="' . esc_attr(trim($cls)) . '"' . $href . $pack['attr'] . '>';
|
||||
if ($img !== '') {
|
||||
$html .= '<div class="aksrt-hl-card__media"><img src="' . esc_url($img) . '" alt="" loading="lazy" /></div>';
|
||||
$placeholder = get_template_directory_uri() . '/assets/img/placeholder.svg';
|
||||
$html .= '<div class="aksrt-hl-card__media"><img class="fit-cover aksrt-lazy lazyload" data-src="' . esc_url($img) . '" src="' . esc_url($placeholder) . '" alt="" loading="lazy" /></div>';
|
||||
}
|
||||
$html .= '<div class="aksrt-hl-card__body">';
|
||||
if (!empty($c['icon'])) {
|
||||
@@ -145,6 +147,9 @@ class WidgetHighlights extends \WP_Widget {
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $instance
|
||||
*/
|
||||
public function form($instance): void {
|
||||
$json = is_string($instance['cards'] ?? null)
|
||||
? (string) $instance['cards']
|
||||
@@ -161,17 +166,34 @@ class WidgetHighlights extends \WP_Widget {
|
||||
</label>
|
||||
<small><?php esc_html_e('size: large|medium|small;color: blue/pink/…', 'aksrt'); ?></small>
|
||||
</p>
|
||||
<p>
|
||||
<label><?php esc_html_e('入场动画', 'aksrt'); ?>
|
||||
<select name="<?php echo esc_attr($this->get_field_name('obs_animation')); ?>">
|
||||
<option value="" <?php selected(($instance['obs_animation'] ?? 'slideup'), ''); ?>><?php esc_html_e('无', 'aksrt'); ?></option>
|
||||
<option value="fade" <?php selected(($instance['obs_animation'] ?? 'slideup'), 'fade'); ?>><?php esc_html_e('淡入', 'aksrt'); ?></option>
|
||||
<option value="slideup" <?php selected(($instance['obs_animation'] ?? 'slideup'), 'slideup'); ?>><?php esc_html_e('上滑', 'aksrt'); ?></option>
|
||||
<option value="zoomin" <?php selected(($instance['obs_animation'] ?? 'slideup'), 'zoomin'); ?>><?php esc_html_e('放大', 'aksrt'); ?></option>
|
||||
</select>
|
||||
</label>
|
||||
</p>
|
||||
<p>
|
||||
<label><input type="checkbox" name="<?php echo esc_attr($this->get_field_name('go_link')); ?>" value="1" <?php checked(!empty($instance['go_link'])); ?>> <?php esc_html_e('外链跳转页', 'aksrt'); ?></label>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $new_instance
|
||||
* @param array<string,mixed> $old_instance
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function update($new_instance, $old_instance): array {
|
||||
return [
|
||||
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
|
||||
'cards' => $this->normalize($new_instance['cards'] ?? []),
|
||||
'go_link' => !empty($new_instance['go_link']) ? 1 : 0,
|
||||
'title' => sanitize_text_field((string) ($new_instance['title'] ?? '')),
|
||||
'cards' => $this->normalize($new_instance['cards'] ?? []),
|
||||
'go_link' => !empty($new_instance['go_link']) ? 1 : 0,
|
||||
'obs_animation' => sanitize_key((string) ($new_instance['obs_animation'] ?? 'slideup')),
|
||||
'animation_repeat' => !empty($new_instance['animation_repeat']) ? 1 : 0,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user