Files
web-app-starter/components/basic/action-button.php
T

97 lines
3.6 KiB
PHP

<?php return [
'render' => function($prop) {
static $assets_loaded = false;
$label = first($prop['label'] ?? false, $prop['text'] ?? false, $prop['caption'] ?? false, 'Action');
$route = array_key_exists('route', $prop) ? $prop['route'] : ($prop['url'] ?? '');
$params = is_array($prop['params'] ?? false) ? $prop['params'] : array();
$class = trim('action-button '.(string)first($prop['class'] ?? false, ''));
$variant = preg_replace('/[^a-z0-9_-]/i', '', (string)first($prop['variant'] ?? false, ''));
if($variant !== '') $class .= ' action-button--'.$variant;
$href = $route !== false ? URL::Link((string)$route, $params) : '';
$tag = strtolower((string)first($prop['tag'] ?? false, $href !== '' ? 'a' : 'button'));
if(!in_array($tag, array('a', 'button'), true)) $tag = 'button';
$method = strtolower((string)first($prop['method'] ?? false, 'get'));
$confirm = (string)first($prop['confirm'] ?? false, '');
$title = (string)first($prop['title'] ?? false, $prop['hint'] ?? false, '');
$attrs = array(
'class' => $class,
);
if($title !== '') $attrs['title'] = $title;
if($confirm !== '') $attrs['data-confirm'] = $confirm;
if($tag === 'a' && $href !== '') $attrs['href'] = $href;
else $attrs['type'] = first($prop['type'] ?? false, 'button');
if(!empty($prop['disabled'])) $attrs['disabled'] = 'disabled';
if(!empty($prop['htmx']))
{
$attrs[$method === 'post' ? 'hx-post' : 'hx-get'] = $href;
if($confirm !== '') $attrs['hx-confirm'] = $confirm;
if(!empty($prop['target'])) $attrs['hx-target'] = (string)$prop['target'];
if(!empty($prop['swap'])) $attrs['hx-swap'] = (string)$prop['swap'];
if(array_key_exists('push_url', $prop)) $attrs['hx-push-url'] = $prop['push_url'] ? 'true' : 'false';
if(!empty($prop['vals']) && is_array($prop['vals'])) $attrs['hx-vals'] = json_encode($prop['vals']);
}
else if($href !== '' && $tag !== 'a')
{
$attrs['data-href'] = $href;
}
$attr_html = '';
foreach($attrs as $name => $value)
$attr_html .= ' '.asafe($name).'="'.asafe((string)$value).'"';
ob_start();
if(!$assets_loaded)
{
$assets_loaded = true;
?>
<style>
.action-button {
display: inline-flex;
align-items: center;
justify-content: center;
gap: .45rem;
min-height: 2.25rem;
padding: .5rem .8rem;
border: 1px solid var(--border, rgba(0,0,0,.18));
border-radius: .5rem;
background: var(--surface-elevated, #fff);
color: var(--text-primary, #111827);
font: inherit;
font-weight: 650;
line-height: 1.1;
text-decoration: none;
cursor: pointer;
}
.action-button:hover { border-color: var(--primary, #2563eb); text-decoration: none; }
.action-button--primary { background: var(--primary, #2563eb); border-color: var(--primary, #2563eb); color: #fff; }
.action-button--danger { background: #b91c1c; border-color: #991b1b; color: #fff; }
.action-button[disabled] { opacity: .55; cursor: default; }
</style>
<script>
(function() {
if(window.StarterActionButton) return;
window.StarterActionButton = true;
document.addEventListener('click', function(event) {
var button = event.target.closest('.action-button');
if(!button) return;
var message = button.getAttribute('data-confirm');
if(message && !window.confirm(message)) {
event.preventDefault();
event.stopPropagation();
return false;
}
var href = button.getAttribute('data-href');
if(href) document.location.href = href;
});
})();
</script>
<?php
}
?> <<?= $tag ?><?= $attr_html ?>><?= safe($label) ?></<?= $tag ?>><?php
return ob_get_clean();
},
'about' => 'Reusable link/button action primitive inspired by htmx-crud-starter UI::url_button.',
];