154 lines
5.1 KiB
PHP
154 lines
5.1 KiB
PHP
<?php
|
|
|
|
namespace App\View\Helper\BootstrapElements;
|
|
|
|
use App\View\Helper\BootstrapGeneric;
|
|
|
|
/**
|
|
* Creates an collapsible accordion component
|
|
*
|
|
* # Options:
|
|
* - stayOpen: Should collapsible components stay open when another one is opened
|
|
* - class: Additional classes to add to the main accordion container
|
|
* - content: Definition of the collapsible components. Must have at least the $body key set. See the "# Content" section for the options
|
|
*
|
|
* # Content:
|
|
* - class: Additional class to add to the body container
|
|
* - open: Should that collapsible element be opened by default
|
|
* - variant: The background variant to be applied to the body element
|
|
* - header: The definition of the interactive header. Accepts the following options:
|
|
* - variant: The bootstrap variant to apply on the header element
|
|
* - text: The text content of the header
|
|
* - html: The HTML content of the header
|
|
*
|
|
* # Usage:
|
|
* $this->Bootstrap->accordion(
|
|
* [
|
|
* 'stayOpen' => true,
|
|
* ],
|
|
* [
|
|
* [
|
|
* 'open' => true,
|
|
* 'header' => [
|
|
* 'variant' => 'danger',
|
|
* 'text' => 'nav 1',
|
|
* ],
|
|
* 'body' => '<b>body</b>',
|
|
* ],
|
|
* [
|
|
* 'class' => ['opacity-50'],
|
|
* 'variant' => 'success',
|
|
* 'header' => [
|
|
* 'html' => '<i>nav 1</i>',
|
|
* ],
|
|
* 'body' => '<b>body</b>',
|
|
* ],
|
|
* ]
|
|
* );
|
|
*/
|
|
class BootstrapAccordion extends BootstrapGeneric
|
|
{
|
|
private $defaultOptions = [
|
|
'stayOpen' => false,
|
|
'class' => [],
|
|
];
|
|
|
|
function __construct($options, $content, $btHelper)
|
|
{
|
|
$this->allowedOptionValues = [];
|
|
$this->content = $content;
|
|
$this->btHelper = $btHelper;
|
|
$this->processOptions($options);
|
|
}
|
|
|
|
private function processOptions($options)
|
|
{
|
|
$this->options = array_merge($this->defaultOptions, $options);
|
|
$this->checkOptionValidity();
|
|
$this->options['class'] = $this->convertToArrayIfNeeded($this->options['class']);
|
|
$this->seed = 'acc-' . mt_rand();
|
|
$this->contentSeeds = [];
|
|
foreach ($this->content as $accordionItem) {
|
|
$this->contentSeeds[] = mt_rand();
|
|
}
|
|
|
|
foreach ($this->content as $i => $item) {
|
|
$this->content[$i]['class'] = $this->convertToArrayIfNeeded($item['class'] ?? []);
|
|
$this->content[$i]['header']['class'] = $this->convertToArrayIfNeeded($item['header']['class'] ?? []);
|
|
}
|
|
}
|
|
|
|
public function accordion()
|
|
{
|
|
return $this->genAccordion();
|
|
}
|
|
|
|
private function genHeader($accordionItem, $i)
|
|
{
|
|
$html = $this->nodeOpen('h2', [
|
|
'class' => ['accordion-header'],
|
|
'id' => 'head-' . $this->contentSeeds[$i]
|
|
]);
|
|
$content = $accordionItem['header']['html'] ?? h($accordionItem['header']['text']);
|
|
$buttonOptions = [
|
|
'class' => array_merge(
|
|
[
|
|
'accordion-button',
|
|
empty($accordionItem['open']) ? 'collapsed' : '',
|
|
self::getBGAndTextClassForVariant($accordionItem['header']['variant'] ?? ''),
|
|
],
|
|
$accordionItem['header']['class'],
|
|
),
|
|
'type' => 'button',
|
|
'data-bs-toggle' => 'collapse',
|
|
'data-bs-target' => '#body-' . $this->contentSeeds[$i],
|
|
'aria-expanded' => 'false',
|
|
'aria-controls' => 'body-' . $this->contentSeeds[$i],
|
|
];
|
|
$html .= $this->node('button', $buttonOptions, $content);
|
|
$html .= $this->nodeClose(('h2'));
|
|
return $html;
|
|
}
|
|
|
|
private function genBody($accordionItem, $i)
|
|
{
|
|
$content = $this->node('div', [
|
|
'class' => ['accordion-body']
|
|
], $accordionItem['body']);
|
|
$divOptions = [
|
|
'class' => array_merge(
|
|
[
|
|
'accordion-collapse collapse',
|
|
empty($accordionItem['open']) ? '' : 'show',
|
|
self::getBGAndTextClassForVariant($accordionItem['variant'] ?? ''),
|
|
],
|
|
$accordionItem['class'],
|
|
),
|
|
'id' => 'body-' . $this->contentSeeds[$i],
|
|
'aria-labelledby' => 'head-' . $this->contentSeeds[$i],
|
|
];
|
|
if (empty($this->options['stayOpen'])) {
|
|
$divOptions['data-bs-parent'] = '#' . $this->seed;
|
|
}
|
|
$html = $this->node('div', $divOptions, $content);
|
|
return $html;
|
|
}
|
|
|
|
private function genAccordion()
|
|
{
|
|
$html = $this->nodeOpen('div', [
|
|
'class' => array_merge(['accordion'], $this->options['class']),
|
|
'id' => $this->seed
|
|
]);
|
|
foreach ($this->content as $i => $accordionItem) {
|
|
$html .= $this->nodeOpen('div', [
|
|
'class' => array_merge(['accordion-item'])
|
|
]);
|
|
$html .= $this->genHeader($accordionItem, $i);
|
|
$html .= $this->genBody($accordionItem, $i);
|
|
$html .= $this->nodeClose('div');
|
|
}
|
|
$html .= $this->nodeClose('div');
|
|
return $html;
|
|
}
|
|
} |