feat(widgets): shared aksrt_icon_card/cover helpers + obs animate map
Add zibll-parity icon-card and icon-cover-card renderers plus aksrt_obs_animate_attrs mapping to data-aksrt-animate scroll hooks.
This commit is contained in:
@@ -49,6 +49,7 @@ require_once AKSRT_DIR . '/inc/helpers/aksrt-header-menu-buttons.php';
|
||||
require_once AKSRT_DIR . '/inc/helpers/aksrt-runtime-win.php';
|
||||
require_once AKSRT_DIR . '/inc/helpers/aksrt-identity.php';
|
||||
require_once AKSRT_DIR . '/inc/helpers/aksrt-graphic-card.php';
|
||||
require_once AKSRT_DIR . '/inc/helpers/aksrt-icon-cards.php';
|
||||
require_once AKSRT_DIR . '/inc/helpers/aksrt-user-card.php';
|
||||
require_once AKSRT_DIR . '/inc/helpers/aksrt-rewards.php';
|
||||
require_once AKSRT_DIR . '/inc/helpers/menu-decoration.php';
|
||||
|
||||
@@ -0,0 +1,276 @@
|
||||
<?php
|
||||
/**
|
||||
* Icon card helpers (zibll zib_icon_card / zib_icon_cover_card).
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
if (!function_exists('aksrt_icon_card')) :
|
||||
/**
|
||||
* Vertical icon card (icon above title/desc).
|
||||
*
|
||||
* @param array<string,mixed> $args
|
||||
* @param bool $echo
|
||||
*/
|
||||
function aksrt_icon_card(array $args = [], bool $echo = false): string {
|
||||
$defaults = [
|
||||
'type' => '',
|
||||
'class' => 'box-body nopw-sm',
|
||||
'icon' => '',
|
||||
'icon_size' => 0,
|
||||
'customize_icon' => '',
|
||||
'icon_image' => '',
|
||||
'link' => [
|
||||
'url' => '',
|
||||
'target' => '',
|
||||
],
|
||||
'icon_radius' => false,
|
||||
'icon_color' => '',
|
||||
'icon_custom_color' => '',
|
||||
'icon_class' => '',
|
||||
'title' => '',
|
||||
'desc' => '',
|
||||
];
|
||||
$args = wp_parse_args($args, $defaults);
|
||||
|
||||
$icon_fa = sanitize_text_field((string) $args['icon']);
|
||||
$icon_img = esc_url_raw(trim((string) ($args['icon_image'] !== '' ? $args['icon_image'] : $args['customize_icon'])));
|
||||
// customize_icon may be raw HTML (img) from older data.
|
||||
$custom_html = '';
|
||||
if ($icon_img === '' && is_string($args['customize_icon']) && str_contains((string) $args['customize_icon'], '<')) {
|
||||
$custom_html = wp_kses((string) $args['customize_icon'], [
|
||||
'i' => ['class' => true, 'aria-hidden' => true],
|
||||
'img' => ['src' => true, 'alt' => true, 'class' => true, 'width' => true, 'height' => true, 'loading' => true],
|
||||
'span'=> ['class' => true],
|
||||
]);
|
||||
}
|
||||
if ($icon_fa === '' && $icon_img === '' && $custom_html === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$link = $args['link'];
|
||||
if (is_string($link)) {
|
||||
$link = ['url' => $link, 'target' => ''];
|
||||
}
|
||||
if (!is_array($link)) {
|
||||
$link = ['url' => '', 'target' => ''];
|
||||
}
|
||||
$url = esc_url(trim((string) ($link['url'] ?? '')));
|
||||
$target = sanitize_text_field((string) ($link['target'] ?? ''));
|
||||
$tgt = $target !== '' ? ' target="' . esc_attr($target) . '" rel="noopener noreferrer"' : '';
|
||||
|
||||
$icon_color = sanitize_html_class((string) $args['icon_color']);
|
||||
$icon_class_extra = sanitize_html_class((string) $args['icon_class']);
|
||||
$radius = !empty($args['icon_radius']);
|
||||
$icon_class = $radius
|
||||
? 'card-icon toggle-radius fa-3x ' . ($icon_class_extra !== '' ? $icon_class_extra : $icon_color)
|
||||
: 'card-icon fa-4x ' . $icon_color;
|
||||
if ($icon_class_extra !== '' && !$radius) {
|
||||
$icon_class .= ' ' . $icon_class_extra;
|
||||
}
|
||||
|
||||
$style = '';
|
||||
$custom_color = sanitize_hex_color((string) $args['icon_custom_color']);
|
||||
if (!$radius && $custom_color) {
|
||||
$style = ' style="color:' . esc_attr($custom_color) . ';"';
|
||||
}
|
||||
|
||||
if ($custom_html !== '') {
|
||||
$icon_inner = $custom_html;
|
||||
} elseif ($icon_img !== '') {
|
||||
$icon_inner = '<img src="' . esc_url($icon_img) . '" alt="" loading="lazy" />';
|
||||
} else {
|
||||
if ($icon_fa !== '' && !str_contains($icon_fa, 'fa-') && !str_contains($icon_fa, ' ')) {
|
||||
$icon_fa = 'fa fa-' . $icon_fa;
|
||||
}
|
||||
$icon_inner = '<i class="' . esc_attr($icon_fa) . '" aria-hidden="true"></i>';
|
||||
}
|
||||
|
||||
$icon = '<span class="' . esc_attr(trim($icon_class)) . '"' . $style . '>' . $icon_inner . '</span>';
|
||||
if ($url !== '') {
|
||||
$icon = '<a href="' . esc_url($url) . '"' . $tgt . '>' . $icon . '</a>';
|
||||
}
|
||||
$icon_size = (int) $args['icon_size'];
|
||||
if ($icon_size > 0) {
|
||||
$icon = '<span style="font-size:' . (int) $icon_size . 'px;">' . $icon . '</span>';
|
||||
}
|
||||
|
||||
$title = trim((string) $args['title']);
|
||||
$desc = trim((string) $args['desc']);
|
||||
if ($url !== '' && $title !== '') {
|
||||
$title_html = '<a class="main-color" href="' . esc_url($url) . '"' . $tgt . '>' . esc_html($title) . '</a>';
|
||||
} else {
|
||||
$title_html = $title !== '' ? esc_html($title) : '';
|
||||
}
|
||||
|
||||
$body = '';
|
||||
if ($title_html !== '') {
|
||||
$body .= '<div class="mt10 em12 text-ellipsis">' . $title_html . '</div>';
|
||||
}
|
||||
if ($desc !== '') {
|
||||
$body .= '<div class="muted-color mt6">' . esc_html($desc) . '</div>';
|
||||
}
|
||||
|
||||
$class = trim((string) $args['class'] . ' ' . (string) $args['type']);
|
||||
$html = '<div class="icon-card ' . esc_attr($class) . '">';
|
||||
$html .= $icon;
|
||||
$html .= $body !== '' ? '<div class="px12-sm">' . $body . '</div>' : '';
|
||||
$html .= '</div>';
|
||||
|
||||
if ($echo) {
|
||||
echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
return '';
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_icon_cover_card')) :
|
||||
/**
|
||||
* Horizontal icon cover card (icon left, title/desc right).
|
||||
*
|
||||
* @param array<string,mixed> $args
|
||||
* @param bool $echo
|
||||
*/
|
||||
function aksrt_icon_cover_card(array $args = [], bool $echo = false): string {
|
||||
$defaults = [
|
||||
'class' => 'zib-widget',
|
||||
'icon' => '',
|
||||
'icon_size' => 25,
|
||||
'customize_icon' => '',
|
||||
'icon_image' => '',
|
||||
'link' => [
|
||||
'url' => '',
|
||||
'target' => '',
|
||||
],
|
||||
'icon_radius' => false,
|
||||
'icon_color' => '',
|
||||
'icon_custom_color' => '',
|
||||
'icon_class' => '',
|
||||
'title' => '',
|
||||
'desc' => '',
|
||||
];
|
||||
$args = wp_parse_args($args, $defaults);
|
||||
|
||||
$icon_fa = sanitize_text_field((string) $args['icon']);
|
||||
$icon_img = esc_url_raw(trim((string) ($args['icon_image'] !== '' ? $args['icon_image'] : '')));
|
||||
$custom_html = '';
|
||||
if ($icon_img === '' && is_string($args['customize_icon']) && str_contains((string) $args['customize_icon'], '<')) {
|
||||
$custom_html = wp_kses((string) $args['customize_icon'], [
|
||||
'i' => ['class' => true, 'aria-hidden' => true],
|
||||
'img' => ['src' => true, 'alt' => true, 'class' => true, 'loading' => true],
|
||||
'span'=> ['class' => true],
|
||||
]);
|
||||
} elseif ($icon_img === '' && is_string($args['customize_icon']) && filter_var((string) $args['customize_icon'], FILTER_VALIDATE_URL)) {
|
||||
$icon_img = esc_url_raw((string) $args['customize_icon']);
|
||||
}
|
||||
if ($icon_fa === '' && $icon_img === '' && $custom_html === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
$link = $args['link'];
|
||||
if (is_string($link)) {
|
||||
$link = ['url' => $link, 'target' => ''];
|
||||
}
|
||||
if (!is_array($link)) {
|
||||
$link = ['url' => '', 'target' => ''];
|
||||
}
|
||||
$url = esc_url(trim((string) ($link['url'] ?? '')));
|
||||
$target = sanitize_text_field((string) ($link['target'] ?? ''));
|
||||
$tgt = $target !== '' ? ' target="' . esc_attr($target) . '" rel="noopener noreferrer"' : '';
|
||||
|
||||
$icon_class = trim('icon-cover-icon badg cir ' . sanitize_html_class((string) $args['icon_class']) . ' ' . sanitize_html_class((string) $args['icon_color']));
|
||||
if (!empty($args['icon_radius'])) {
|
||||
$icon_class .= ' radius4';
|
||||
}
|
||||
$icon_size = max(14, min(64, (int) $args['icon_size']));
|
||||
$style = 'font-size:' . $icon_size . 'px;';
|
||||
$custom_color = sanitize_hex_color((string) $args['icon_custom_color']);
|
||||
if ($custom_color) {
|
||||
$style .= 'color:' . $custom_color . ';';
|
||||
}
|
||||
|
||||
if ($custom_html !== '') {
|
||||
$icon_inner = $custom_html;
|
||||
} elseif ($icon_img !== '') {
|
||||
$icon_inner = '<img src="' . esc_url($icon_img) . '" alt="" loading="lazy" />';
|
||||
} else {
|
||||
if ($icon_fa !== '' && !str_contains($icon_fa, 'fa-') && !str_contains($icon_fa, ' ')) {
|
||||
$icon_fa = 'fa fa-' . $icon_fa;
|
||||
}
|
||||
$icon_inner = '<i class="' . esc_attr($icon_fa) . ' em09" aria-hidden="true"></i>';
|
||||
}
|
||||
$icon = '<div class="' . esc_attr(trim($icon_class)) . '" style="' . esc_attr($style) . '">' . $icon_inner . '</div>';
|
||||
|
||||
$title = trim((string) $args['title']);
|
||||
$desc = trim((string) $args['desc']);
|
||||
$text = '';
|
||||
if ($title !== '') {
|
||||
$text .= '<div class="em12 text-ellipsis font-bold">' . esc_html($title) . '</div>';
|
||||
}
|
||||
if ($desc !== '') {
|
||||
$text .= '<div class="muted-color mt6 text-ellipsis">' . esc_html($desc) . '</div>';
|
||||
}
|
||||
|
||||
$html = '';
|
||||
if ($url !== '') {
|
||||
$html .= '<a class="main-color" href="' . esc_url($url) . '"' . $tgt . '>';
|
||||
}
|
||||
$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>';
|
||||
if ($url !== '') {
|
||||
$html .= '</a>';
|
||||
}
|
||||
|
||||
if ($echo) {
|
||||
echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
return '';
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
endif;
|
||||
|
||||
if (!function_exists('aksrt_obs_animate_attrs')) :
|
||||
/**
|
||||
* Build class + attribute string for scroll-in animation (maps to data-aksrt-animate).
|
||||
*
|
||||
* @param string $animation fade|slideup|slidedown|slideright|slideleft|zoomin|zoomout|''
|
||||
* @param bool $repeat
|
||||
* @param float|int $delay_s
|
||||
* @return array{class:string,attr:string}
|
||||
*/
|
||||
function aksrt_obs_animate_attrs(string $animation, bool $repeat = false, $delay_s = 0): array {
|
||||
$animation = sanitize_key($animation);
|
||||
$map = [
|
||||
'fade' => 'fadeIn',
|
||||
'slideup' => 'fadeInUp',
|
||||
'slidedown' => 'fadeInDown',
|
||||
'slideright' => 'fadeInRight',
|
||||
'slideleft' => 'fadeInLeft',
|
||||
'zoomin' => 'zoomIn',
|
||||
'zoomout' => 'fadeIn',
|
||||
'fadein' => 'fadeIn',
|
||||
'fadeinup' => 'fadeInUp',
|
||||
];
|
||||
if ($animation === '' || !isset($map[$animation]) && !in_array($animation, $map, true)) {
|
||||
if (!isset($map[$animation])) {
|
||||
return ['class' => '', 'attr' => ''];
|
||||
}
|
||||
}
|
||||
$aksrt = $map[$animation] ?? $animation;
|
||||
$delay_ms = (int) round(((float) $delay_s) * 1000);
|
||||
$class = ' obs-animate ani-' . $animation;
|
||||
$attr = ' data-aksrt-animate="' . esc_attr($aksrt) . '"';
|
||||
if ($delay_ms > 0) {
|
||||
$attr .= ' data-aksrt-animate-delay="' . esc_attr((string) $delay_ms) . '"';
|
||||
}
|
||||
if ($repeat) {
|
||||
$attr .= ' data-animation-repeat="true"';
|
||||
}
|
||||
return ['class' => $class, 'attr' => $attr];
|
||||
}
|
||||
endif;
|
||||
Reference in New Issue
Block a user