bs_lib-8.x-1.0-alpha3/src/Plugin/Block/BSLibScrollToTopBlock.php
src/Plugin/Block/BSLibScrollToTopBlock.php
<?php namespace Drupal\bs_lib\Plugin\Block; use Drupal\Component\Utility\Html; use Drupal\Core\Block\BlockBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Url; /** * Provides a 'BSLibScrollToTopBlock' block. * * @Block( * id = "bs_lib_scroll_to_top_block", * admin_label = @Translation("Scroll to top"), * ) */ class BSLibScrollToTopBlock extends BlockBase { /** * {@inheritdoc} */ public function defaultConfiguration() { return [ 'css_class' => '', 'duration' => 700, 'easing' => 'swing', 'offset' => 300, 'offset_opacity' => 1200, 'position' => 'static', 'position_fixed_disable_element' => '', 'text' => 'To top', ]; } /** * {@inheritdoc} */ public function blockForm($form, FormStateInterface $form_state) { $config = $this->getConfiguration(); $form['text'] = [ '#type' => 'textfield', '#title' => $this->t('Text'), '#description' => $this->t('Text of a scroll to top element.'), '#maxlength' => 255, '#default_value' => $config['text'], ]; $form['duration'] = [ '#type' => 'textfield', '#title' => $this->t('Duration'), '#description' => $this->t('Scroll duration in milliseconds.'), '#maxlength' => 255, '#default_value' => $config['duration'], ]; $easing_functions = ['swing' => 'swing', 'linear' => 'linear']; $form['easing'] = [ '#type' => 'select', '#title' => $this->t('Easing'), '#description' => $this->t('Easing function used for animation.'), '#maxlength' => 255, '#default_value' => $config['easing'], '#options' => $easing_functions, ]; $form['css_class'] = [ '#type' => 'textfield', '#title' => $this->t('CSS classes'), '#description' => $this->t('Add CSS classes to the element.'), '#maxlength' => 255, '#default_value' => $config['css_class'], ]; $position_id = Html::getUniqueId('scroll-to-top-position'); $form['position'] = [ '#id' => $position_id, '#type' => 'select', '#title' => $this->t('Position'), '#options' => [ 'static' => $this->t('Static'), 'fixed' => $this->t('Fixed'), ], '#description' => $this->t('Position of the element on the page.'), '#maxlength' => 255, '#default_value' => $config['position'], ]; $form['offset'] = [ '#type' => 'textfield', '#title' => $this->t('Offset'), '#description' => $this->t('Browser window scroll (in pixels) after which the "back to top" link is shown.'), '#maxlength' => 255, '#default_value' => $config['offset'], '#states' => [ 'visible' => [ ':input[id="' . $position_id . '"]' => ['value' => 'fixed'], ], ], ]; $form['offset_opacity'] = [ '#type' => 'textfield', '#title' => $this->t('Offset opacity'), '#description' => $this->t('Browser window scroll (in pixels) after which the "back to top" link opacity is reduced.'), '#maxlength' => 255, '#default_value' => $config['offset_opacity'], '#states' => [ 'visible' => [ ':input[id="' . $position_id . '"]' => ['value' => 'fixed'], ], ], ]; $form['position_fixed_disable_element'] = [ '#type' => 'textfield', '#title' => $this->t('Disable fixed for element'), '#description' => $this->t('CSS selector of element for which fixed positioning will be disabled when to top element reach selected parent element vertically. Leave empty to disable this feature.'), '#maxlength' => 255, '#default_value' => $config['position_fixed_disable_element'], '#states' => [ 'visible' => [ ':input[id="' . $position_id . '"]' => ['value' => 'fixed'], ], ], ]; return $form; } /** * {@inheritdoc} */ public function blockSubmit($form, FormStateInterface $form_state) { foreach ($this->defaultConfiguration() as $item => $value) { $this->configuration[$item] = $form_state->getValue($item); } } /** * {@inheritdoc} */ public function build() { $config = $this->getConfiguration(); $data = []; $exclude_data = ['css_class', 'position', 'text']; foreach ($this->defaultConfiguration() as $item => $value) { if (!in_array($item, $exclude_data)) { $data['data-' . $item] = $config[$item]; } } $library = ['bs_lib/scroll_to_top']; if (!empty($config['easing']) && ($config['easing'] != 'swing' || $config['easing'] != 'linear')) { $library[] = 'core/jquery.ui.effects.core'; } $classes = ['bs-lib-scroll-to-top', 'bs-lib-scroll-to-top--' . $config['position']]; if ($config['offset'] == 0) { $classes[] = 'bs-lib-scroll-to-top--show'; } // MDN suggest that a tag should be used only by links that are going // somewhere. This is a reason we are using #main-content hash tag. // @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#Accessibility_recommendations // Using hashtag that exist on page will help with screen readers and also // when JS is disabled. return [ '#type' => 'link', '#title' => ['#markup' => '<span class="label">' . $config['text'] . '</span>'], // #main-content is hardcoded because all core themes also use the same // element id. '#url' => Url::fromUserInput('#main-content', [ 'attributes' => [ 'class' => array_merge($classes, explode(' ', $config['css_class'])), 'aria-label' => $config['text'], ] + $data, ]), '#attached' => ['library' => $library], ]; } }