ui_suite_dsfr_ft-1.0.0-rc3/src/Plugin/Block/DisplayModalBlock.php
src/Plugin/Block/DisplayModalBlock.php
<?php
namespace Drupal\ui_suite_dsfr_ft\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Form\SubformStateInterface;
/**
* Provides a block with multiple menu rendered inside patterns.
*
* @Block(
* id = "ui_suite_dsfr_display_modal",
* admin_label = @Translation("UI Suite dsfr display modal"),
* category = @Translation("UI Suite DSFR"),
* )
*/
class DisplayModalBlock extends BlockBase {
public const BASE_DIR = "./libraries/dsfr/dist/artwork/pictograms";
private static function getDefaultPathSvg() {
return [
'light' => self::BASE_DIR . '/environment/sun.svg',
'dark' => self::BASE_DIR . '/environment/moon.svg',
'system' => self::BASE_DIR . '/system/system.svg',
];
}
/**
* {@inheritdoc}
*/
public function blockForm($form, FormStateInterface $form_state) {
$form = parent::blockForm($form, $form_state);
$defaults = $this->getConfiguration();
$form['title'] = [
'#type' => 'textfield',
'#default_value' => $defaults['title'] ?? t('Display settings'),
'#required' => TRUE,
'#title' => t('Title of modal'),
];
// Cannot use the checkboxes element cause the #states/required not working.
$form['text'] = [
'#type' => 'textarea',
'#default_value' => $defaults['text'] ?? t('Choose a theme to personalize the appearance of site.'),
'#required' => TRUE,
'#title' => t('Body of modal'),
];
$display_options = $defaults['display_options'] ?? [
'light',
'dark',
'system',
];
$display_options_svg = $defaults['display_options_svg'] ?? [];
if (!empty($form_state->getTriggeringElement())) {
if ($form_state instanceof SubformStateInterface) {
$form_state = $form_state->getCompleteFormState();
}
$value = $form_state->getValues();
$display_options = $value['settings']['display_options'] ?? [];
$display_options_svg = $value['settings']['display_options_svg'] ?? $display_options_svg;
}
$options = [
'light' => t('Light'),
'dark' => t('Dark'),
'system' => t('System'),
];
$form['display_options'] = [
'#type' => 'checkboxes',
'#required' => TRUE,
'#default_value' => $display_options,
'#options' => $options,
'#ajax' => [
'callback' => [$this, 'svgAjaxCallback'],
// don't forget :: when calling a class method.
//'callback' => [$this, 'myAjaxCallback'], //alternative notation
// Or TRUE to prevent re-focusing on the triggering element.
'event' => 'change',
'wrapper' => 'display-svg',
// This element is updated with this AJAX callback.
'progress' => [
'type' => 'throbber',
'message' => $this->t('Scan directory'),
],
],
'#title' => t('Theme display option'),
'#description' => t('Check the display options available.'),
];
$form['display_options_svg'] = [
'#type' => 'container',
'#tree' => TRUE,
'#prefix' => '<div id="display-svg" >',
'#suffix' => '</div>',
];
$default_path = self::getDefaultPathSvg();
foreach ($display_options as $display_option) {
if (empty($display_option)) {
continue;
}
$key_svg = 'display_options_svg_' . $display_option;
$form['display_options_svg'][$key_svg] = [
'#type' => 'textfield',
'#required' => FALSE,
'#title' => $this->t('SVG for theme %theme', ['%theme' => $options[$display_option]]),
'#default_value' => $display_options_svg[$key_svg] ?? $default_path[$display_option],
'#attributes' => [
'placeholder' => $default_path[$display_option] ?? '',
],
'#autocomplete_route_name' => 'ui_suite_dsfr_fr.display_svg.autocomplete',
];
}
return $form;
}
/**
* Ajax callback to rebuild svg textfied.
*
* @param array $form
* Array of current block configuration form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state object.
*
* @return array
* The display options container element.
*/
public function svgAjaxCallback(array &$form, FormStateInterface $form_state) {
return $form['settings']['display_options_svg'];
}
/**
* {@inheritdoc}
*/
public function blockSubmit($form, FormStateInterface $form_state) {
$this->configuration['title'] = $form_state->getValue('title');
$this->configuration['text'] = $form_state->getValue('text');
$this->configuration['display_options'] = $form_state->getValue('display_options');
$this->configuration['display_options_svg'] = $form_state->getValue('display_options_svg');
}
/**
* {@inheritdoc}
*/
public function build() {
$modal_id = 'fr-theme-modal';
$default_path = self::getDefaultPathSvg();
// Add the modal to the content.
$dsfr_theme_display = [
'light' => [
'title' => t('Light'),
'attributes' => [
'id' => 'light',
'title' => t('Light Theme'),
],
],
'dark' => [
'title' => t('Dark'),
'attributes' => [
'id' => 'dark',
'title' => t('Dark Theme'),
],
],
'system' => [
'title' => t('System'),
'attributes' => [
'id' => 'system',
'title' => t('System Theme'),
],
],
];
$display_options_svg = $this->configuration['display_options_svg'];
foreach ($dsfr_theme_display as $theme_option => $theme_data) {
if (empty($this->configuration['display_options'][$theme_option])) {
unset($dsfr_theme_display[$theme_option]);
continue;
}
$dsfr_theme_display[$theme_option]['url'] = $display_options_svg['display_options_svg_' . $theme_option] ?? $default_path[$theme_option];
}
$display_content = [
'#type' => 'component',
'#component' => 'ui_suite_dsfr:display',
'#slots' => [
'title' => $this->configuration['text'] ?? t('Choose a theme to personalize the appearance of site.'),
],
'#props' => [
'themes' => $dsfr_theme_display,
],
];
return [
'#attached' => ['library' => 'ui_suite_dsfr_ft/dsfr-scheme'],
'modal' => [
'#type' => 'component',
'#component' => 'ui_suite_dsfr:modal',
'#slots' => [
'title' => $this->configuration['title'] ?? t('Display settings'),
'body' => $display_content,
],
'#props' => [
'id' => $modal_id,
],
],
];
}
}
