120 lines
3.7 KiB
PHP
120 lines
3.7 KiB
PHP
<?php
|
|
|
|
namespace App\View\Helper\BootstrapElements;
|
|
|
|
use Cake\Utility\Security;
|
|
|
|
use App\View\Helper\BootstrapGeneric;
|
|
|
|
/**
|
|
* Creates a Bootstrap collapsible component
|
|
*
|
|
* # Options:
|
|
* - text: The text of the control element
|
|
* - html: The HTML content of the control element
|
|
* - open: Should the collapsible element be opened by default
|
|
* - horizontal: Should the collapsible be revealed from the side
|
|
* - class: List of additional classes to be added to the main container
|
|
* - id: Optional ID to link the collapsible element with its control button
|
|
* - button: Configuration object to make the control element into a button. Accepts BootstrapElements\BootstrapButton parameters
|
|
* - card: Configuration object to adjust the content container based on configuration. Accepts BootstrapElements\BootstrapCard parameters
|
|
*
|
|
* # Usage:
|
|
* $this->Bootstrap->collapse([
|
|
* 'button' => [
|
|
* 'text' => 'Open sesame',
|
|
* 'variant' => 'success',
|
|
* ],
|
|
* 'card' => [
|
|
* 'bodyClass' => 'p-2 rounded-3',
|
|
* 'bodyVariant' => 'secondary',
|
|
* ]
|
|
* ], '<i>content</i>');
|
|
*/
|
|
|
|
class BootstrapCollapse extends BootstrapGeneric
|
|
{
|
|
private $defaultOptions = [
|
|
'text' => '',
|
|
'html' => null,
|
|
'open' => false,
|
|
'horizontal' => false,
|
|
'class' => [],
|
|
'button' => [],
|
|
'card' => [],
|
|
'attrs' => [],
|
|
];
|
|
|
|
function __construct($options, $content, $btHelper)
|
|
{
|
|
$this->allowedOptionValues = [];
|
|
$this->processOptions($options);
|
|
$this->content = $content;
|
|
$this->btHelper = $btHelper;
|
|
}
|
|
|
|
private function processOptions($options)
|
|
{
|
|
$this->options = array_merge($this->defaultOptions, $options);
|
|
$this->options['class'] = $this->convertToArrayIfNeeded($this->options['class']);
|
|
$this->options['class'][] = 'collapse';
|
|
if (!empty($this->options['horizontal'])) {
|
|
$this->options['class'][] = 'collapse-horizontal';
|
|
}
|
|
if ($this->options['open']) {
|
|
$this->options['class'][] = 'show';
|
|
}
|
|
if (empty($this->options['card']['bodyClass'])) {
|
|
$this->options['card']['bodyClass'] = ['p-0'];
|
|
}
|
|
if (empty($this->options['id'])) {
|
|
$this->options['id'] = 'c-' . Security::randomString(8);
|
|
}
|
|
$this->checkOptionValidity();
|
|
}
|
|
|
|
public function collapse()
|
|
{
|
|
return $this->genCollapse();
|
|
}
|
|
|
|
private function genControl()
|
|
{
|
|
$attrsConfig = [
|
|
'data-bs-toggle' => 'collapse',
|
|
'role' => 'button',
|
|
'aria-expanded' => 'false',
|
|
'aria-controls' => $this->options['id'],
|
|
'href' => '#' . $this->options['id'],
|
|
];
|
|
$html = '';
|
|
if (!empty($this->options['button'])) {
|
|
$btnConfig = array_merge($this->options['button'], ['attrs' => $attrsConfig]);
|
|
$html = $this->btHelper->button($btnConfig);
|
|
} else {
|
|
$nodeConfig = [
|
|
'class' => ['text-decoration-none'],
|
|
];
|
|
$nodeConfig = array_merge($nodeConfig, $attrsConfig);
|
|
$html = $this->node('a', $nodeConfig, $this->options['html'] ?? h($this->options['text']));
|
|
}
|
|
return $html;
|
|
}
|
|
|
|
private function genContent()
|
|
{
|
|
$cardConfig = $this->options['card'];
|
|
$cardConfig['bodyHTML'] = $this->content;
|
|
$content = $this->btHelper->card($cardConfig);
|
|
$container = $this->node('div', [
|
|
'class' => $this->options['class'],
|
|
'id' => $this->options['id'],
|
|
], $content);
|
|
return $container;
|
|
}
|
|
|
|
private function genCollapse()
|
|
{
|
|
return $this->genControl() . $this->genContent();
|
|
}
|
|
} |