| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- <?php
- namespace Dcat\Admin\Widgets;
- use Dcat\Admin\Support\Helper;
- use Illuminate\Support\Str;
- class Dropdown extends Widget
- {
- const DIVIDER = '_divider';
- /**
- * @var string
- */
- protected static $dividerHtml = '<li class="dropdown-divider"></li>';
- protected $view = 'admin::widgets.dropdown';
- /**
- * @var array
- */
- protected $button = [
- 'text' => null,
- 'class' => 'btn btn-sm btn-white waves-effect',
- 'style' => null,
- ];
- /**
- * @var string
- */
- protected $buttonId;
- /**
- * @var \Closure
- */
- protected $builder;
- /**
- * @var bool
- */
- protected $divider;
- /**
- * @var bool
- */
- protected $click = false;
- public function __construct(array $options = [])
- {
- $this->options($options);
- }
- /**
- * Set the options of dropdown menus.
- *
- * @param array $options
- * @param string|null $title
- *
- * @return $this
- */
- public function options($options = [], ?string $title = null)
- {
- if (! $options) {
- return $this;
- }
- $this->options[] = [$title, Helper::array($options)];
- return $this;
- }
- /**
- * Set the button text.
- *
- * @param string|null $text
- *
- * @return $this
- */
- public function button(?string $text)
- {
- $this->button['text'] = $text;
- return $this;
- }
- /**
- * Set the button class.
- *
- * @param string $class
- *
- * @return $this
- */
- public function buttonClass(?string $class)
- {
- $this->button['class'] = $class;
- return $this;
- }
- /**
- * Set the button style.
- *
- * @param string $class
- *
- * @return $this
- */
- public function buttonStyle(?string $style)
- {
- $this->button['style'] = $style;
- return $this;
- }
- /**
- * Show divider.
- *
- * @param string $class
- *
- * @return $this
- */
- public function divider()
- {
- $this->divider = true;
- return $this;
- }
- /**
- * Applies the callback to the elements of the options.
- *
- * @param string $class
- *
- * @return $this
- */
- public function map(\Closure $builder)
- {
- $this->builder = $builder;
- return $this;
- }
- /**
- * Add click event listener.
- *
- * @param string|null $defaultLabel
- *
- * @return $this
- */
- public function click(?string $defaultLabel = null)
- {
- $this->click = true;
- $this->buttonId = 'dropd-'.Str::random(8);
- if ($defaultLabel !== null) {
- $this->button($defaultLabel);
- }
- return $this;
- }
- /**
- * @return string
- */
- public function getButtonId()
- {
- return $this->buttonId;
- }
- /**
- * @return string
- */
- protected function renderOptions()
- {
- $html = '';
- foreach ($this->options as &$items) {
- [$title, $options] = $items;
- if ($title) {
- $html .= "<li class='dropdown-header'>$title</li>";
- }
- foreach ($options as $key => $val) {
- $html .= $this->renderOption($key, $val);
- }
- }
- return $html;
- }
- /**
- * @param mixed $k
- * @param mixed $v
- *
- * @return mixed|string
- */
- protected function renderOption($k, $v)
- {
- if ($v === static::DIVIDER) {
- return static::$dividerHtml;
- }
- if ($builder = $this->builder) {
- $v = $builder->call($this, $v, $k);
- }
- $v = mb_strpos($v, '</a>') ? $v : "<a href='javascript:void(0)'>$v</a>";
- $v = "<li class='dropdown-item'>$v</li>";
- if ($this->divider) {
- $v .= static::$dividerHtml;
- $this->divider = null;
- }
- return $v;
- }
- /**
- * @return string
- */
- public function render()
- {
- $this->addVariables([
- 'options' => $this->renderOptions(),
- 'button' => $this->button,
- 'buttonId' => $this->buttonId,
- 'click' => $this->click,
- ]);
- return parent::render();
- }
- }
|