You are here

Classes.php in GridStack 8.2

File

src/Plugin/gridstack/stylizer/Classes.php
View source
<?php

namespace Drupal\gridstack\Plugin\gridstack\stylizer;

use Drupal\Component\Utility\Unicode;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\gridstack\GridStackDefault;

/**
 * Provides the classes styles.
 *
 * @GridStackStylizer(
 *   id = "classes",
 *   label = @Translation("Classes")
 * )
 */
class Classes extends Media {

  /**
   * The black opacity for backgrounds or colors.
   *
   * @var array
   */
  protected $opacity = [
    20,
    40,
    60,
    80,
    90,
  ];

  /**
   * Returns the module feature CSS classes, not available at CSS frameworks.
   */
  public function getInternalClasses() {
    $classes = $bg = $bg_pos = $padding = $min_height = $min_height_md = [];
    $min_height_lg = [];
    foreach ($this->opacity as $key) {
      $bg[] = 'bg-dark-' . $key;
    }
    foreach (array_keys(GridStackDefault::breakpoints()) as $key) {
      $min_height[] = 'mh-' . $key;
      $min_height_md[] = 'mh-md-' . $key;
      $min_height_lg[] = 'mh-lg-' . $key;
      $padding[] = 'p-' . $key;
    }
    $positions = [
      'center',
      'bottom',
      'bottom-left',
      'bottom-right',
      'left',
      'right',
      'top',
      'top-left',
      'top-right',
    ];
    foreach ($positions as $key) {
      $bg_pos[] = 'bg-' . $key;
    }
    $classes['background'] = $bg;
    $classes['bg_position'] = $bg_pos;
    $classes['min_height'] = $min_height;
    $classes['min_height_md'] = $min_height_md;
    $classes['min_height_lg'] = $min_height_lg;
    $classes['padding'] = $padding;
    return $classes;
  }

  /**
   * {@inheritdoc}
   */
  protected function classesElement($optionset, FormStateInterface $form_state, array $settings, array $extras = []) {
    $context = $settings['_scope'];
    $container = !empty($settings['_container']);
    $element = [];
    $wrapper_classes = [];
    $wrapper_class_value = trim($settings['wrapper_classes']);
    if ($wrapper_class_value) {
      $wrapper_classes = array_filter(array_map('trim', explode(" ", $wrapper_class_value)));
    }
    if ($classes = $this->manager
      ->getMergedClasses(FALSE)) {

      // Saves headaches from problematic options.
      $problems = [
        'hidden',
        'visible',
        'visibility',
        'height',
      ];
      foreach ($classes as $key => $options) {

        // Hiding the entire container is likely out of questions, skip.
        if ($container && in_array($key, $problems)) {
          continue;
        }

        // JS-driven layouts have pre-defined fixed heights, skip.
        if (!$optionset
          ->isFramework() && strpos($key, 'height') !== FALSE) {
          continue;
        }
        $refined_options = $this
          ->getPresetOptions($options);
        $element[$key] = $this
          ->classElement($key, $options, $refined_options, $context, $wrapper_classes);
        $element[$key]['#attributes']['class'][] = $optionset
          ->isFramework() ? 'is-gs-css-driven' : 'is-gs-js-driven';
        if ($framework = $this->manager
          ->engineManager()
          ->framework()) {
          if (in_array($key, $framework
            ->previewOptions())) {
            $element[$key]['#is_preview'] = TRUE;
            $element[$key]['#attributes']['class'][] = 'form-wrapper--preview';
            if (in_array($key, [
              'rounded',
              'text_color',
            ])) {
              $element[$key]['#attributes']['class'][] = 'form-wrapper--bg';
            }
          }
        }
      }
    }
    return $element;
  }

  /**
   * {@inheritdoc}
   */
  protected function rowClassesElement($optionset, FormStateInterface $form_state, array $settings, array $extras = []) {
    $context = $settings['_scope'];
    $container = !empty($settings['_container']);
    $element = [];

    // Only applicable to one dimensional for now.
    if (!$optionset
      ->isFramework() && !$container) {
      return [];
    }
    $wrapper_classes = [];
    $wrapper_class_value = trim($settings['row_classes']);
    if ($wrapper_class_value) {
      $wrapper_classes = array_filter(array_map('trim', explode(" ", $wrapper_class_value)));
    }
    if ($classes = $this->manager
      ->engineManager()
      ->getClassOptions('row')) {
      foreach ($classes as $key => $options) {
        $refined_options = $this
          ->getPresetRowOptions($options);
        $element[$key] = $this
          ->classElement($key, $options, $refined_options, $context, $wrapper_classes);
      }
    }
    return $element;
  }

  /**
   * Returns common class element.
   */
  protected function classElement($key, $options, $refined_options, $context, $wrapper_classes = []) {
    $title = str_replace([
      '_',
      '-',
    ], ' ', $key);
    $value = '';

    // We don't store these, fecthing from wrapper_classes string instead.
    if ($wrapper_classes) {
      $values = array_values($options);
      $values = array_combine($values, $values);
      foreach ($wrapper_classes as $wrapper_class) {
        if (isset($values[$wrapper_class])) {
          $value = $values[$wrapper_class];
          break;
        }
      }
    }
    $css_classes = [
      'form-wrapper--' . str_replace('_', '-', $key),
      'is-collapsible',
      'is-collapsed',
      'is-gs-fieldset',
    ];
    return [
      '#type' => 'radios',
      '#title' => $this
        ->t('@title', [
        '@title' => Unicode::ucfirst($title),
      ]),
      '#options' => [
        '' => $this
          ->t('- None -'),
      ] + $refined_options,
      '#default_value' => $value,
      '#region' => $context,
      '#is_preview' => FALSE,
      '#after_build' => [
        [
          $this,
          'afterBuildPreset',
        ],
      ],
      '#group_name' => $key,
      '#attributes' => [
        'class' => $css_classes,
        'data-gs-preset-region' => $context,
      ],
    ];
  }

  /**
   * Provides preview classes.
   */
  public function afterBuildPreset(array $element) {
    foreach (Element::children($element) as $key) {
      $removed = [
        'form-wrapper--preview',
        'form-wrapper--' . str_replace('_', '-', $key),
        'form-wrapper--' . str_replace('_', '-', $element['#group_name']),
        'is-collapsible',
        'is-collapsed',
        'is-gs-fieldset',
      ];

      // Provides small preview for what the class looks like if so required.
      if (!empty($element['#is_preview'])) {
        $element[$key]['#wrapper_attributes']['class'][] = $key;
      }

      // Unfortunately fieldset classes are also inherited by each item.
      if (isset($element[$key]['#attributes']['class'])) {
        $classes = $element[$key]['#attributes']['class'];
        $classes = array_diff($classes, $removed);
        $element[$key]['#attributes']['class'] = $classes;
      }

      // @todo if (strpos($key, 'bg-white') !== FALSE) {}
      // @todo $element[$key]['#attributes']['data-gs-target-selector'] = '> .box__content';
    }
    return $element;
  }

  /**
   * {@inheritdoc}
   */
  protected function getPresetOptions(array $data) {
    $rm = [
      'bg-',
      'gradient-',
      'padding-',
      'mh-',
      'text-',
      'hidden-',
      'rounded-',
      'visible-',
    ];
    return $this
      ->getBasePresetOptions($data, $rm, 'gridstack_classes_preset_options');
  }

  /**
   * {@inheritdoc}
   */
  protected function getPresetRowOptions(array $data) {
    $rm = [
      'flex-',
      'justify-content-',
      'align-items-',
      'align-content-',
      'align-self-',
    ];
    return $this
      ->getBasePresetOptions($data, $rm, 'gridstack_classes_preset_row_options');
  }

  /**
   * {@inheritdoc}
   */
  protected function getBasePresetOptions(array $data, array $rm, $alter = 'gridstack_classes_preset_options') {
    $options = [];
    foreach ($data as $option) {
      $title = str_replace($rm, '', $option);
      $title = str_replace([
        '_',
        '-',
      ], ' ', $title);
      $options[$option] = $this
        ->t('@title', [
        '@title' => Unicode::ucfirst($title),
      ]);
    }
    $this->manager
      ->getModuleHandler()
      ->alter($alter, $options, $data);
    ksort($options);
    return $options;
  }

}

Classes

Namesort descending Description
Classes Provides the classes styles.