<?php
|
namespace JVBase\ui;
|
|
if (!defined('ABSPATH')) {
|
exit;
|
}
|
|
/**
|
* Modal UI component with fluent interface
|
*
|
* Usage:
|
* $modal = new Modal('edit-profile');
|
* $modal->title('Edit Profile')
|
* ->content($formHtml)
|
* ->addAction('cancel', 'Cancel', 'x')
|
* ->addAction('save', 'Save', 'floppy-disk', 'submit')
|
* ->size('large');
|
* echo $modal->render();
|
*/
|
class Modal {
|
private string $class;
|
private string $title = '';
|
private string $content = '';
|
private array $actions = [];
|
private ?string $size = null;
|
private array $attributes = [];
|
private bool $defaultActions = true;
|
|
public function __construct(string $class) {
|
$this->class = $class;
|
}
|
|
/**
|
* Set the modal title
|
*
|
* @param string $title
|
* @return self
|
*/
|
public function title(string $title): self {
|
$this->title = $title;
|
return $this;
|
}
|
|
/**
|
* Set the modal content
|
*
|
* @param string $content
|
* @return self
|
*/
|
public function content(string $content): self {
|
$this->content = $content;
|
return $this;
|
}
|
|
/**
|
* Add a custom action button
|
*
|
* @param string $class CSS class for the button
|
* @param string $label Button label
|
* @param string|null $icon Icon name (optional)
|
* @param string $type Button type (button or submit)
|
* @return self
|
*/
|
public function addAction(string $class, string $label, ?string $icon = null, string $type = 'button'): self {
|
$this->defaultActions = false;
|
$this->actions[] = [
|
'class' => $class,
|
'label' => $label,
|
'icon' => $icon,
|
'type' => $type
|
];
|
return $this;
|
}
|
|
/**
|
* Use default cancel/save actions
|
*
|
* @param bool $use
|
* @return self
|
*/
|
public function useDefaultActions(bool $use = true): self {
|
$this->defaultActions = $use;
|
return $this;
|
}
|
|
/**
|
* Set modal size
|
*
|
* @param string $size Size class (e.g., 'small', 'large', 'full')
|
* @return self
|
*/
|
public function size(string $size): self {
|
$this->size = $size;
|
return $this;
|
}
|
|
/**
|
* Add custom attributes to the dialog element
|
*
|
* @param string $key Attribute name
|
* @param string $value Attribute value
|
* @return self
|
*/
|
public function attribute(string $key, string $value): self {
|
$this->attributes[$key] = $value;
|
return $this;
|
}
|
|
/**
|
* Render the modal HTML
|
*
|
* @param bool $return Whether to return or echo
|
* @return string
|
*/
|
public function render(bool $return = true): string {
|
$classes = $this->class;
|
if ($this->size) {
|
$classes .= ' ' . $this->size;
|
}
|
|
$attrs = '';
|
foreach ($this->attributes as $key => $value) {
|
$attrs .= ' ' . esc_attr($key) . '="' . esc_attr($value) . '"';
|
}
|
|
$html = '<dialog class="' . esc_attr($classes) . '"' . $attrs . '>
|
<div class="wrap">
|
<h2>' . esc_html($this->title) . '</h2>
|
' . $this->content;
|
|
// Add actions
|
if ($this->defaultActions || !empty($this->actions)) {
|
$html .= $this->renderActions();
|
}
|
|
$html .= '
|
</div>
|
</dialog>';
|
|
if ($return) {
|
return $html;
|
}
|
|
echo $html;
|
return $html;
|
}
|
|
/**
|
* Render action buttons
|
*
|
* @return string
|
*/
|
private function renderActions(): string {
|
$html = '<div class="m-actions row">';
|
|
if ($this->defaultActions) {
|
// Default cancel and save buttons
|
$html .= '<button type="button" class="cancel">' . jvbIcon('x') . '<span class="screen-reader-text">Cancel</span></button>';
|
$html .= '<button type="submit" class="save">' . jvbIcon('floppy-disk') . '<span class="screen-reader-text">Save</span></button>';
|
} else {
|
// Custom actions
|
foreach ($this->actions as $action) {
|
$html .= '<button type="' . esc_attr($action['type']) . '" class="' . esc_attr($action['class']) . '">';
|
if ($action['icon']) {
|
$html .= jvbIcon($action['icon']);
|
}
|
$html .= '<span class="screen-reader-text">' . esc_html($action['label']) . '</span>';
|
$html .= '</button>';
|
}
|
}
|
|
$html .= '</div>';
|
return $html;
|
}
|
}
|