move devices
This commit is contained in:
@@ -1656,7 +1656,80 @@ p:last-child { margin-bottom: 0; }
|
||||
font-size: .9rem;
|
||||
}
|
||||
|
||||
/* ── 8d. Image Card ────────────────────────────────────────── */
|
||||
/* ── 8d. Device Card ───────────────────────────────────────── */
|
||||
.device-grid {
|
||||
--cols: 2;
|
||||
}
|
||||
.oribi-card.device-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-top: 3px solid var(--color-primary);
|
||||
background: var(--card-bg);
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.device-card img,
|
||||
.device-card .card-image {
|
||||
width: 100%;
|
||||
aspect-ratio: 4 / 3;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
}
|
||||
.device-card-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
.device-best-for {
|
||||
display: inline-block;
|
||||
font-size: var(--wp--preset--font-size--xs, .75rem);
|
||||
background: var(--color-primary-lt);
|
||||
color: var(--color-primary);
|
||||
padding: .25rem .75rem;
|
||||
border-radius: 999px;
|
||||
margin-bottom: .75rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
.device-card h3 {
|
||||
color: var(--color-heading);
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
.device-card p {
|
||||
font-size: .9rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.device-specs {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: .25rem .75rem;
|
||||
font-size: .85rem;
|
||||
margin: 0 0 1.25rem;
|
||||
padding: 0;
|
||||
}
|
||||
.device-specs dt {
|
||||
color: var(--color-muted, #6b7280);
|
||||
font-weight: 500;
|
||||
}
|
||||
.device-specs dd {
|
||||
margin: 0;
|
||||
font-weight: 600;
|
||||
color: var(--color-heading);
|
||||
}
|
||||
.device-price {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
color: var(--color-primary);
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
.device-card-btn {
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
/* ── 8e. Image Card ────────────────────────────────────────── */
|
||||
.image-card {
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
|
||||
@@ -1007,6 +1007,86 @@
|
||||
save: function () { return null; }
|
||||
});
|
||||
|
||||
/* ── Device Card ──────────────────────────────────────────────────────── */
|
||||
reg('oribi/device-card', {
|
||||
title: 'Device Card',
|
||||
icon: 'laptop',
|
||||
category: 'oribi',
|
||||
parent: ['oribi/device-section'],
|
||||
supports: { html: false, reusable: false },
|
||||
attributes: Object.assign({}, {
|
||||
title: { type: 'string', default: '' },
|
||||
description: { type: 'string', default: '' },
|
||||
price: { type: 'string', default: '' },
|
||||
bestFor: { type: 'string', default: '' },
|
||||
specs: { type: 'array', default: [], items: { type: 'object' } },
|
||||
btnText: { type: 'string', default: 'Order Now' },
|
||||
btnUrl: { type: 'string', default: '/contact' },
|
||||
}, CARD_IMAGE_ATTRS),
|
||||
edit: function (props) {
|
||||
var a = props.attributes, s = props.setAttributes;
|
||||
var imgPrev = cardImagePreview(a);
|
||||
|
||||
function updateSpec(i, field, val) {
|
||||
var next = (a.specs || []).slice();
|
||||
next[i] = Object.assign({}, next[i], {});
|
||||
next[i][field] = val;
|
||||
s({ specs: next });
|
||||
}
|
||||
function addSpec() {
|
||||
s({ specs: (a.specs || []).concat([{ key: '', value: '' }]) });
|
||||
}
|
||||
function removeSpec(i) {
|
||||
var next = (a.specs || []).slice();
|
||||
next.splice(i, 1);
|
||||
s({ specs: next });
|
||||
}
|
||||
|
||||
var specsRows = (a.specs || []).map(function (sp, i) {
|
||||
return el('div', { key: i, style: { display: 'flex', gap: '8px', marginBottom: '6px' } },
|
||||
el(TC, { label: 'Key', value: sp.key || '', onChange: function (v) { updateSpec(i, 'key', v); }, style: { flex: 1 } }),
|
||||
el(TC, { label: 'Value', value: sp.value || '', onChange: function (v) { updateSpec(i, 'value', v); }, style: { flex: 1 } }),
|
||||
el('button', { onClick: function () { removeSpec(i); }, style: { alignSelf: 'flex-end', marginBottom: '8px' }, className: 'button is-small is-destructive' }, '✕')
|
||||
);
|
||||
});
|
||||
|
||||
return el(Frag, null,
|
||||
el(IC, null,
|
||||
el(PB, { title: 'Card Content' },
|
||||
el(TC, { label: 'Best For (pill)', value: a.bestFor || '', onChange: function (v) { s({ bestFor: v }); } }),
|
||||
el(TC, { label: 'Price', value: a.price || '', onChange: function (v) { s({ price: v }); } }),
|
||||
el(TC, { label: 'Button Text', value: a.btnText || '', onChange: function (v) { s({ btnText: v }); } }),
|
||||
el(TC, { label: 'Button URL', value: a.btnUrl || '', onChange: function (v) { s({ btnUrl: v }); } })
|
||||
),
|
||||
el(PB, { title: 'Specs' },
|
||||
specsRows,
|
||||
el('button', { onClick: addSpec, className: 'button is-secondary', style: { marginTop: '4px' } }, '+ Add Spec')
|
||||
),
|
||||
cardImageControls(a, s)
|
||||
),
|
||||
el('div', { className: 'oribi-card device-card' },
|
||||
imgPrev,
|
||||
el('div', { className: 'device-card-body' },
|
||||
a.bestFor ? el('span', { className: 'device-best-for' }, a.bestFor) : null,
|
||||
el(RT, { tagName: 'h3', value: a.title, onChange: function (v) { s({ title: v }); }, placeholder: 'Device name...' }),
|
||||
el(RT, { tagName: 'p', value: a.description, onChange: function (v) { s({ description: v }); }, placeholder: 'Short description...' }),
|
||||
(a.specs || []).length ? el('dl', { className: 'device-specs' },
|
||||
(a.specs || []).map(function (sp, i) {
|
||||
return [
|
||||
el('dt', { key: 'k' + i }, sp.key || ''),
|
||||
el('dd', { key: 'v' + i }, sp.value || '')
|
||||
];
|
||||
})
|
||||
) : null,
|
||||
a.price ? el('div', { className: 'device-price' }, a.price) : null,
|
||||
el('span', { className: 'wp-block-button__link device-card-btn' }, a.btnText || 'Order Now')
|
||||
)
|
||||
)
|
||||
);
|
||||
},
|
||||
save: function () { return null; }
|
||||
});
|
||||
|
||||
/* ── Image Card ───────────────────────────────────────────────────────── */
|
||||
reg('oribi/image-card', {
|
||||
title: 'Image Card',
|
||||
@@ -1586,6 +1666,17 @@
|
||||
save: function () { return el(IB.Content); }
|
||||
});
|
||||
|
||||
/* DEVICE SECTION ───────────────────────────────────────────────────────── */
|
||||
reg('oribi/device-section', {
|
||||
title: 'Oribi Device Section',
|
||||
icon: 'laptop',
|
||||
category: 'oribi',
|
||||
supports: { align: ['full'], html: false },
|
||||
attributes: SECTION_ATTRS,
|
||||
edit: createCardSectionEdit(['oribi/device-card'], [['oribi/device-card', {}]], 'Device Card'),
|
||||
save: function () { return el(IB.Content); }
|
||||
});
|
||||
|
||||
/* IMAGE SECTION ────────────────────────────────────────────────────────── */
|
||||
reg('oribi/image-section', {
|
||||
title: 'Oribi Image Section',
|
||||
|
||||
@@ -455,6 +455,31 @@ add_action('init', function () {
|
||||
'render_callback' => 'oribi_render_addon_card',
|
||||
]);
|
||||
|
||||
/* Device Section (parent) */
|
||||
register_block_type('oribi/device-section', [
|
||||
'attributes' => oribi_card_section_attributes(2),
|
||||
'supports' => $block_supports,
|
||||
'render_callback' => 'oribi_render_device_section',
|
||||
]);
|
||||
|
||||
/* Device Card (child) */
|
||||
register_block_type('oribi/device-card', [
|
||||
'attributes' => array_merge(
|
||||
[
|
||||
'title' => ['type' => 'string', 'default' => ''],
|
||||
'description' => ['type' => 'string', 'default' => ''],
|
||||
'price' => ['type' => 'string', 'default' => ''],
|
||||
'bestFor' => ['type' => 'string', 'default' => ''],
|
||||
'specs' => ['type' => 'array', 'default' => [], 'items' => ['type' => 'object']],
|
||||
'btnText' => ['type' => 'string', 'default' => ''],
|
||||
'btnUrl' => ['type' => 'string', 'default' => ''],
|
||||
],
|
||||
oribi_card_image_attributes()
|
||||
),
|
||||
'supports' => $block_supports,
|
||||
'render_callback' => 'oribi_render_device_card',
|
||||
]);
|
||||
|
||||
/* Image Section (parent) */
|
||||
register_block_type('oribi/image-section', [
|
||||
'attributes' => oribi_card_section_attributes(3),
|
||||
@@ -1655,6 +1680,56 @@ function oribi_render_addon_card($a)
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/* ── Device Section ────────────────────────────────────────────────────────── */
|
||||
function oribi_render_device_section($a, $content)
|
||||
{
|
||||
return oribi_render_card_section($a, $content, 'grid device-grid', 2);
|
||||
}
|
||||
|
||||
/* ── Device Card ───────────────────────────────────────────────────────────── */
|
||||
function oribi_render_device_card($a)
|
||||
{
|
||||
$img = oribi_card_image_html($a);
|
||||
$img_cls = $img['card_class'] ? ' ' . $img['card_class'] : '';
|
||||
|
||||
$specs = !empty($a['specs']) && is_array($a['specs']) ? $a['specs'] : [];
|
||||
$price = !empty($a['price']) ? $a['price'] : '';
|
||||
$bestFor = !empty($a['bestFor']) ? $a['bestFor'] : '';
|
||||
$btnText = !empty($a['btnText']) ? $a['btnText'] : 'Order Now';
|
||||
$btnUrl = !empty($a['btnUrl']) ? $a['btnUrl'] : '/contact';
|
||||
|
||||
ob_start(); ?>
|
||||
<div class="oribi-card device-card<?php echo esc_attr($img_cls); ?>">
|
||||
<?php if ($img['html']): echo $img['html']; endif; ?>
|
||||
<div class="device-card-body">
|
||||
<?php if ($bestFor): ?>
|
||||
<span class="device-best-for"><?php echo esc_html($bestFor); ?></span>
|
||||
<?php endif; ?>
|
||||
<h3><?php echo wp_kses_post($a['title']); ?></h3>
|
||||
<p><?php echo wp_kses_post($a['description']); ?></p>
|
||||
<?php if ($specs): ?>
|
||||
<dl class="device-specs">
|
||||
<?php foreach ($specs as $spec):
|
||||
$k = isset($spec['key']) ? $spec['key'] : '';
|
||||
$v = isset($spec['value']) ? $spec['value'] : '';
|
||||
if (!$k && !$v) continue; ?>
|
||||
<dt><?php echo esc_html($k); ?></dt>
|
||||
<dd><?php echo esc_html($v); ?></dd>
|
||||
<?php endforeach; ?>
|
||||
</dl>
|
||||
<?php endif; ?>
|
||||
<?php if ($price): ?>
|
||||
<div class="device-price"><?php echo esc_html($price); ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if ($btnText && $btnUrl): ?>
|
||||
<a href="<?php echo esc_url($btnUrl); ?>" class="wp-block-button__link device-card-btn"><?php echo esc_html($btnText); ?></a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/* ── Image Section ─────────────────────────────────────────────────────────── */
|
||||
function oribi_render_image_section($a, $content)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user