feat: Add cardStyle attribute to feature cards for enhanced styling options

This commit is contained in:
Matt Batchelder
2026-04-17 21:24:11 -04:00
parent 93b571d6aa
commit 29ae3632f1
3 changed files with 44 additions and 11 deletions

View File

@@ -56,13 +56,13 @@ return <<<'ORIBI_SYNC_CONTENT'
<!-- /wp:oribi/feature-section --> <!-- /wp:oribi/feature-section -->
<!-- wp:oribi/feature-section {"heading":"Prove Every Play","lead":"Know exactly what's playing, where, and when. Export reports, automate delivery, and monitor the health of every player in your network."} --> <!-- wp:oribi/feature-section {"heading":"Prove Every Play","lead":"Know exactly what's playing, where, and when. Export reports, automate delivery, and monitor the health of every player in your network."} -->
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-chart-pie","title":"Proof of Play","description":"Track every piece of content at the layout, media, and widget level. Configurable retention depth lets you store as much history as you need."} /--> <!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-chart-pie","title":"Proof of Play","description":"Track every piece of content at the layout, media, and widget level. Configurable retention depth lets you store as much history as you need.","cardStyle":"bold-statement"} /-->
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-file-pdf","title":"Scheduled Reports","description":"Set up automated PDF reports and have them emailed to stakeholders on your schedule. Export raw data as CSV for deeper analysis."} /--> <!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-file-pdf","title":"Scheduled Reports","description":"Set up automated PDF reports and have them emailed to stakeholders on your schedule. Export raw data as CSV for deeper analysis.","cardStyle":"minimal-feature"} /-->
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-heart-pulse","title":"Player Health","description":"Monitor connection status, storage usage, and player performance live. Get alerted the moment a player goes offline."} /--> <!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-heart-pulse","title":"Player Health","description":"Monitor connection status, storage usage, and player performance live. Get alerted the moment a player goes offline.","cardStyle":"action"} /-->
<!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-box-archive","title":"Content Usage","description":"See which media is assigned to layouts and which is unused. Library usage reports by user help you manage storage and keep your library clean."} /--> <!-- wp:oribi/feature-card {"iconType":"fontawesome","faIcon":"fas fa-box-archive","title":"Content Usage","description":"See which media is assigned to layouts and which is unused. Library usage reports by user help you manage storage and keep your library clean.","cardStyle":"prominent-stat"} /-->
<!-- /wp:oribi/feature-section --> <!-- /wp:oribi/feature-section -->
<!-- wp:oribi/value-section {"variant":"alt","heading":"Live in Minutes. Secure on Every Plan.","lead":"Every plan includes 2FA, role-based access, and audit trails. Scale your team and your network without worrying about per-user fees or access limits.","columns":4} --> <!-- wp:oribi/value-section {"variant":"alt","heading":"Live in Minutes. Secure on Every Plan.","lead":"Every plan includes 2FA, role-based access, and audit trails. Scale your team and your network without worrying about per-user fees or access limits.","columns":4} -->

View File

@@ -781,17 +781,19 @@
title: { type: 'string', default: '' }, title: { type: 'string', default: '' },
description: { type: 'string', default: '' }, description: { type: 'string', default: '' },
url: { type: 'string', default: '' }, url: { type: 'string', default: '' },
centered: { type: 'boolean', default: false } centered: { type: 'boolean', default: false },
cardStyle: { type: 'string', default: '' }
}, CARD_IMAGE_ATTRS), }, CARD_IMAGE_ATTRS),
edit: function (props) { edit: function (props) {
var a = props.attributes, s = props.setAttributes; var a = props.attributes, s = props.setAttributes;
var imgPos = a.imgPosition || 'top'; var imgPos = a.imgPosition || 'top';
var imgPrev = cardImagePreview(a); var imgPrev = cardImagePreview(a);
var centeredStyle = a.centered ? { marginInline: 'auto' } : {}; var centeredStyle = a.centered ? { marginInline: 'auto' } : {};
var styleClass = a.cardStyle ? ' ' + a.cardStyle : '';
var cardPreview; var cardPreview;
if (a.imgUrl && imgPos === 'left') { if (a.imgUrl && imgPos === 'left') {
cardPreview = el('div', { className: 'oribi-card img-left' }, cardPreview = el('div', { className: 'oribi-card img-left' + styleClass },
imgPrev, imgPrev,
el('div', { className: 'oribi-card-body' }, el('div', { className: 'oribi-card-body' },
el(RT, { tagName: 'h3', value: a.title, onChange: function (v) { s({ title: v }); }, placeholder: 'Card title...' }), el(RT, { tagName: 'h3', value: a.title, onChange: function (v) { s({ title: v }); }, placeholder: 'Card title...' }),
@@ -799,7 +801,7 @@
) )
); );
} else if (a.imgUrl && imgPos === 'background') { } else if (a.imgUrl && imgPos === 'background') {
cardPreview = el('div', { className: 'oribi-card img-bg', style: { backgroundImage: 'url(' + a.imgUrl + ')', backgroundSize: 'cover', backgroundPosition: 'center', color: '#fff' } }, cardPreview = el('div', { className: 'oribi-card img-bg' + styleClass, style: { backgroundImage: 'url(' + a.imgUrl + ')', backgroundSize: 'cover', backgroundPosition: 'center', color: '#fff' } },
el('div', { className: 'oribi-card-body' }, el('div', { className: 'oribi-card-body' },
iconPreview(a, 'feature-icon', centeredStyle), iconPreview(a, 'feature-icon', centeredStyle),
el(RT, { tagName: 'h3', value: a.title, onChange: function (v) { s({ title: v }); }, placeholder: 'Card title...' }), el(RT, { tagName: 'h3', value: a.title, onChange: function (v) { s({ title: v }); }, placeholder: 'Card title...' }),
@@ -808,7 +810,7 @@
); );
} else { } else {
var showIconPrev = !a.imgUrl || imgPos !== 'replace-icon'; var showIconPrev = !a.imgUrl || imgPos !== 'replace-icon';
cardPreview = el('div', { className: 'oribi-card' + (a.centered ? ' text-center' : '') + (a.imgUrl ? ' img-' + imgPos : '') }, cardPreview = el('div', { className: 'oribi-card' + styleClass + (a.centered ? ' text-center' : '') + (a.imgUrl ? ' img-' + imgPos : '') },
a.imgUrl && (imgPos === 'top' || imgPos === 'replace-icon') ? imgPrev : null, a.imgUrl && (imgPos === 'top' || imgPos === 'replace-icon') ? imgPrev : null,
showIconPrev ? iconPreview(a, 'feature-icon', centeredStyle) : null, showIconPrev ? iconPreview(a, 'feature-icon', centeredStyle) : null,
el(RT, { tagName: 'h3', value: a.title, onChange: function (v) { s({ title: v }); }, placeholder: 'Card title...' }), el(RT, { tagName: 'h3', value: a.title, onChange: function (v) { s({ title: v }); }, placeholder: 'Card title...' }),
@@ -821,6 +823,20 @@
el(PB, { title: 'Card Settings' }, el(PB, { title: 'Card Settings' },
iconControls(a, s), iconControls(a, s),
el(TC, { label: 'URL (optional)', value: a.url || '', onChange: function (v) { s({ url: v }); } }), el(TC, { label: 'URL (optional)', value: a.url || '', onChange: function (v) { s({ url: v }); } }),
el(SC, {
label: 'Card Style',
value: a.cardStyle || '',
options: [
{ label: 'Default', value: '' },
{ label: 'Bold Statement', value: 'bold-statement' },
{ label: 'Minimal Feature', value: 'minimal-feature' },
{ label: 'Prominent Stat', value: 'prominent-stat' },
{ label: 'Testimonial', value: 'testimonial' },
{ label: 'Action', value: 'action' },
{ label: 'Comparison Row', value: 'comparison-row' }
],
onChange: function (v) { s({ cardStyle: v }); }
}),
el(TG, { label: 'Centered', checked: !!a.centered, onChange: function (v) { s({ centered: v }); } }) el(TG, { label: 'Centered', checked: !!a.centered, onChange: function (v) { s({ centered: v }); } })
), ),
cardImageControls(a, s) cardImageControls(a, s)

View File

@@ -388,6 +388,7 @@ add_action('init', function () {
'url' => ['type' => 'string', 'default' => ''], 'url' => ['type' => 'string', 'default' => ''],
'centered' => ['type' => 'boolean', 'default' => false], 'centered' => ['type' => 'boolean', 'default' => false],
'scene' => ['type' => 'string', 'default' => ''], 'scene' => ['type' => 'string', 'default' => ''],
'cardStyle' => ['type' => 'string', 'default' => ''],
], ],
oribi_card_image_attributes() oribi_card_image_attributes()
), ),
@@ -1209,10 +1210,26 @@ function oribi_render_feature_card($a)
$scene = !empty($a['scene']) ? trim($a['scene']) : ''; $scene = !empty($a['scene']) ? trim($a['scene']) : '';
$img = oribi_card_image_html($a); $img = oribi_card_image_html($a);
$img_cls = $img['card_class'] ? ' ' . $img['card_class'] : ''; $img_cls = $img['card_class'] ? ' ' . $img['card_class'] : '';
$style_cls = '';
if (!empty($a['cardStyle'])) {
$allowed_styles = [
'bold-statement',
'minimal-feature',
'prominent-stat',
'testimonial',
'action',
'comparison-row',
];
$style = sanitize_html_class($a['cardStyle']);
if (in_array($style, $allowed_styles, true)) {
$style_cls = ' ' . $style;
}
}
ob_start(); ob_start();
if ($img['html'] && $img['position'] === 'left'): ?> if ($img['html'] && $img['position'] === 'left'): ?>
<<?php echo $tag . $href; ?> class="oribi-card<?php echo esc_attr($link_cls . $img_cls); ?>"> <<?php echo $tag . $href; ?> class="oribi-card<?php echo esc_attr($link_cls . $img_cls . $style_cls); ?>">
<?php echo $img['html']; ?> <?php echo $img['html']; ?>
<div class="oribi-card-body"> <div class="oribi-card-body">
<h3><?php echo wp_kses_post($a['title']); ?></h3> <h3><?php echo wp_kses_post($a['title']); ?></h3>
@@ -1221,7 +1238,7 @@ function oribi_render_feature_card($a)
</<?php echo $tag; ?>> </<?php echo $tag; ?>>
<?php <?php
elseif ($img['html'] && $img['position'] === 'background'): ?> elseif ($img['html'] && $img['position'] === 'background'): ?>
<<?php echo $tag . $href; ?> class="oribi-card<?php echo esc_attr($link_cls . $img_cls); ?>"> <<?php echo $tag . $href; ?> class="oribi-card<?php echo esc_attr($link_cls . $img_cls . $style_cls); ?>">
<?php echo $img['html']; ?> <?php echo $img['html']; ?>
<div class="oribi-card-body"> <div class="oribi-card-body">
<?php if (oribi_has_icon($a)): ?><div class="feature-icon"<?php echo $center ? ' style="margin-inline:auto;"' : ''; ?>><?php echo oribi_render_icon($a); ?></div><?php <?php if (oribi_has_icon($a)): ?><div class="feature-icon"<?php echo $center ? ' style="margin-inline:auto;"' : ''; ?>><?php echo oribi_render_icon($a); ?></div><?php
@@ -1232,7 +1249,7 @@ function oribi_render_feature_card($a)
</<?php echo $tag; ?>> </<?php echo $tag; ?>>
<?php <?php
else: ?> else: ?>
<<?php echo $tag . $href; ?> class="oribi-card<?php echo esc_attr($link_cls . $img_cls); ?><?php echo $center ? ' text-center' : ''; ?>"> <<?php echo $tag . $href; ?> class="oribi-card<?php echo esc_attr($link_cls . $img_cls . $style_cls); ?><?php echo $center ? ' text-center' : ''; ?>">
<?php if ($img['html'] && ($img['position'] === 'top' || $img['position'] === 'replace-icon')): ?> <?php if ($img['html'] && ($img['position'] === 'top' || $img['position'] === 'replace-icon')): ?>
<?php echo $img['html']; ?> <?php echo $img['html']; ?>
<?php <?php