From 40a4d5c113aa5999606e30dcd8d05cb86b5da11d Mon Sep 17 00:00:00 2001 From: Josh Green Date: Mon, 25 Nov 2024 12:39:25 +0000 Subject: [PATCH 1/6] added collapsible contents block --- js/localgov-publications.js | 51 +++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/js/localgov-publications.js b/js/localgov-publications.js index 4e97426..1cea663 100644 --- a/js/localgov-publications.js +++ b/js/localgov-publications.js @@ -15,3 +15,54 @@ } }; })(jQuery, Drupal); + +/** + * Collapse able menu for Publication page + * + * @param {object} context + */ +Drupal.behaviors.publicationMenuToggle = { + attach: function(context) { + const menuCollapseBreakpoint = 992; + + var headers = [ + $('.bfc-publication-navigation__content-header', context), + $('.bfc-publication-tableofcontent__content-header', context) + ]; + var menus = [ + $('#block-bfc-publicationnavigation ul.list--no-style', context), + $('#block-bfc-publicationstableofcontentsblock .publication-content-block', context) + ]; + function toggleMenuVisibilityAndIcon(header, menu) { + header.on('click', function () { + menu.toggleClass('is-hidden'); + header.toggleClass('up-icon down-icon'); + }); + } + + let previousWidth = -1; + + function initializeStateForMenus() { + const previousCollapseState = previousWidth < menuCollapseBreakpoint; + const newCollapseState = window.innerWidth < menuCollapseBreakpoint; + + if (previousCollapseState === newCollapseState && !(previousWidth === -1)) { + return; + } + previousWidth = window.innerWidth; + + headers.forEach(function(header, index) { + menus[index].toggleClass('is-hidden', newCollapseState); + header.toggleClass('up-icon', !newCollapseState).toggleClass('down-icon', newCollapseState); + }); + } + headers.forEach(function(header, index) { + if (!header.data('menuToggleAttached')) { + toggleMenuVisibilityAndIcon(header, menus[index]); + header.data('menuToggleAttached', true); + } + }); + initializeStateForMenus(); + $(window).resize(initializeStateForMenus); + } +}; \ No newline at end of file From 96ccb5b2948a40af4e005b000542ca8d8a2e8830 Mon Sep 17 00:00:00 2001 From: Josh Green Date: Tue, 3 Dec 2024 13:55:57 +0000 Subject: [PATCH 2/6] put collapsable contents into own file and created template --- ...algov-publications-collapsible-contents.js | 50 +++++++++++++++++ js/localgov-publications.js | 53 +------------------ ...publicationstableofcontentsblock.html.twig | 28 ++++++++++ 3 files changed, 79 insertions(+), 52 deletions(-) create mode 100644 js/localgov-publications-collapsible-contents.js create mode 100644 templates/block--lgd-publicationstableofcontentsblock.html.twig diff --git a/js/localgov-publications-collapsible-contents.js b/js/localgov-publications-collapsible-contents.js new file mode 100644 index 0000000..f7e94c4 --- /dev/null +++ b/js/localgov-publications-collapsible-contents.js @@ -0,0 +1,50 @@ +/** + * Collapse able menu for Publication page + * + * @param {object} context + */ +Drupal.behaviors.publicationMenuToggle = { + attach: function(context) { + const menuCollapseBreakpoint = 992; + + var headers = [ + $('.lgd-publication-navigation__content-header', context), + $('.lgd-publication-tableofcontent__content-header', context) + ]; + var menus = [ + $('#block-lgd-publicationnavigation ul.list--no-style', context), + $('#block-lgd-publicationstableofcontentsblock .publication-content-block', context) + ]; + function toggleMenuVisibilityAndIcon(header, menu) { + header.on('click', function () { + menu.toggleClass('is-hidden'); + header.toggleClass('up-icon down-icon'); + }); + } + + let previousWidth = -1; + + function initializeStateForMenus() { + const previousCollapseState = previousWidth < menuCollapseBreakpoint; + const newCollapseState = window.innerWidth < menuCollapseBreakpoint; + + if (previousCollapseState === newCollapseState && !(previousWidth === -1)) { + return; + } + previousWidth = window.innerWidth; + + headers.forEach(function(header, index) { + menus[index].toggleClass('is-hidden', newCollapseState); + header.toggleClass('up-icon', !newCollapseState).toggleClass('down-icon', newCollapseState); + }); + } + headers.forEach(function(header, index) { + if (!header.data('menuToggleAttached')) { + toggleMenuVisibilityAndIcon(header, menus[index]); + header.data('menuToggleAttached', true); + } + }); + initializeStateForMenus(); + $(window).resize(initializeStateForMenus); + } +}; \ No newline at end of file diff --git a/js/localgov-publications.js b/js/localgov-publications.js index 1cea663..4ba3158 100644 --- a/js/localgov-publications.js +++ b/js/localgov-publications.js @@ -14,55 +14,4 @@ }); } }; -})(jQuery, Drupal); - -/** - * Collapse able menu for Publication page - * - * @param {object} context - */ -Drupal.behaviors.publicationMenuToggle = { - attach: function(context) { - const menuCollapseBreakpoint = 992; - - var headers = [ - $('.bfc-publication-navigation__content-header', context), - $('.bfc-publication-tableofcontent__content-header', context) - ]; - var menus = [ - $('#block-bfc-publicationnavigation ul.list--no-style', context), - $('#block-bfc-publicationstableofcontentsblock .publication-content-block', context) - ]; - function toggleMenuVisibilityAndIcon(header, menu) { - header.on('click', function () { - menu.toggleClass('is-hidden'); - header.toggleClass('up-icon down-icon'); - }); - } - - let previousWidth = -1; - - function initializeStateForMenus() { - const previousCollapseState = previousWidth < menuCollapseBreakpoint; - const newCollapseState = window.innerWidth < menuCollapseBreakpoint; - - if (previousCollapseState === newCollapseState && !(previousWidth === -1)) { - return; - } - previousWidth = window.innerWidth; - - headers.forEach(function(header, index) { - menus[index].toggleClass('is-hidden', newCollapseState); - header.toggleClass('up-icon', !newCollapseState).toggleClass('down-icon', newCollapseState); - }); - } - headers.forEach(function(header, index) { - if (!header.data('menuToggleAttached')) { - toggleMenuVisibilityAndIcon(header, menus[index]); - header.data('menuToggleAttached', true); - } - }); - initializeStateForMenus(); - $(window).resize(initializeStateForMenus); - } -}; \ No newline at end of file +})(jQuery, Drupal); \ No newline at end of file diff --git a/templates/block--lgd-publicationstableofcontentsblock.html.twig b/templates/block--lgd-publicationstableofcontentsblock.html.twig new file mode 100644 index 0000000..9eb5f3a --- /dev/null +++ b/templates/block--lgd-publicationstableofcontentsblock.html.twig @@ -0,0 +1,28 @@ +{# +/** + * @file + * Theme override to display a block. + * + * @see template_preprocess_block() + */ +#} +{% + set classes = [ + 'block', + 'block-' ~ configuration.provider|clean_class, + 'block-' ~ plugin_id|clean_class, +] +%} + + {{ title_prefix }} + {% if label %} +
+ {{ label }} +
+ {% endif %} + {{ title_suffix }} + + {% block content %} + {{ content }} + {% endblock %} + From 25697b79277c92fdda4b2bb8363222a0e4bd79b8 Mon Sep 17 00:00:00 2001 From: Graham Cole Date: Fri, 3 Jan 2025 14:58:12 +0000 Subject: [PATCH 3/6] WIP: block collapse configuration --- .../Block/PublicationNavigationBlock.php | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/Plugin/Block/PublicationNavigationBlock.php b/src/Plugin/Block/PublicationNavigationBlock.php index efe81cc..5411e38 100644 --- a/src/Plugin/Block/PublicationNavigationBlock.php +++ b/src/Plugin/Block/PublicationNavigationBlock.php @@ -95,6 +95,48 @@ public static function create(ContainerInterface $container, array $configuratio ); } + + /** + * {@inheritdoc} + */ + public function defaultConfiguration() { + return [ + 'collapsible' => TRUE, + 'collapse_width' => '768', + ]; + } + + /** + * {@inheritdoc} + */ + public function blockForm($form, FormStateInterface $form_state) { + + $form['collapsible'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Collapsible'), + '#description' => $this->t(''), + '#default_value' => $this->configuration['collapsible'], + + ]; + + $form['collapse_width'] = [ + '#type' => 'number', + '#title' => $this->t('Auto-collapse window width (px)'), + '#description' => $this->t(''), + '#default_value' => $this->configuration['collapse_width'], + ]; + + return $form; + } + + /** + * {@inheritdoc} + */ + public function blockSubmit($form, FormStateInterface $form_state) { + $this->configuration['collapsible'] = $form_state->getValue('collapsible'); + $this->configuration['collapse_width'] = $form_state->getValue('collapse_width'); + } + /** * {@inheritdoc} */ From 4e729400b89c1bae9551e926e95f1f37f34ccf67 Mon Sep 17 00:00:00 2001 From: Graham Cole Date: Fri, 3 Jan 2025 15:25:23 +0000 Subject: [PATCH 4/6] Add missing import --- src/Plugin/Block/PublicationNavigationBlock.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Plugin/Block/PublicationNavigationBlock.php b/src/Plugin/Block/PublicationNavigationBlock.php index 5411e38..b461e49 100644 --- a/src/Plugin/Block/PublicationNavigationBlock.php +++ b/src/Plugin/Block/PublicationNavigationBlock.php @@ -5,6 +5,7 @@ use Drupal\book\BookManagerInterface; use Drupal\Core\Block\BlockBase; use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Theme\ThemeManagerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; From 9881a49c3e5820be23b745ea13cad7964943000e Mon Sep 17 00:00:00 2001 From: Graham Cole Date: Fri, 3 Jan 2025 15:25:52 +0000 Subject: [PATCH 5/6] Make auto-collapse width hidden if checkbox unticked --- src/Plugin/Block/PublicationNavigationBlock.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Plugin/Block/PublicationNavigationBlock.php b/src/Plugin/Block/PublicationNavigationBlock.php index b461e49..3011a98 100644 --- a/src/Plugin/Block/PublicationNavigationBlock.php +++ b/src/Plugin/Block/PublicationNavigationBlock.php @@ -124,6 +124,11 @@ public function blockForm($form, FormStateInterface $form_state) { '#type' => 'number', '#title' => $this->t('Auto-collapse window width (px)'), '#description' => $this->t(''), + '#states' => [ + 'visible' => [ + ':input[name="settings[collapsible]"]' => ['checked' => TRUE], + ], + ], '#default_value' => $this->configuration['collapse_width'], ]; From 0696b6c106ed5d658e856c174dd596ef185f285b Mon Sep 17 00:00:00 2001 From: Graham Cole Date: Fri, 3 Jan 2025 15:58:11 +0000 Subject: [PATCH 6/6] WIP read collapse config from drupalSettings --- ...algov-publications-collapsible-contents.js | 45 ++++++++++++------- localgov_publications.libraries.yml | 8 ++++ .../Block/PublicationNavigationBlock.php | 9 ++++ 3 files changed, 47 insertions(+), 15 deletions(-) diff --git a/js/localgov-publications-collapsible-contents.js b/js/localgov-publications-collapsible-contents.js index f7e94c4..f13874f 100644 --- a/js/localgov-publications-collapsible-contents.js +++ b/js/localgov-publications-collapsible-contents.js @@ -1,11 +1,15 @@ -/** +(function ($, Drupal, drupalSettings) { + /** * Collapse able menu for Publication page * * @param {object} context */ Drupal.behaviors.publicationMenuToggle = { attach: function(context) { - const menuCollapseBreakpoint = 992; + + if (!drupalSettings.hasOwnProperty('localgov_publications')) { + return; + } var headers = [ $('.lgd-publication-navigation__content-header', context), @@ -24,27 +28,38 @@ Drupal.behaviors.publicationMenuToggle = { let previousWidth = -1; - function initializeStateForMenus() { + function initializeStateForMenus(menuCollapseBreakpoint) { + + return function () { const previousCollapseState = previousWidth < menuCollapseBreakpoint; const newCollapseState = window.innerWidth < menuCollapseBreakpoint; if (previousCollapseState === newCollapseState && !(previousWidth === -1)) { - return; + return; } previousWidth = window.innerWidth; - headers.forEach(function(header, index) { - menus[index].toggleClass('is-hidden', newCollapseState); - header.toggleClass('up-icon', !newCollapseState).toggleClass('down-icon', newCollapseState); + headers.forEach(function (header, index) { + menus[index].toggleClass('is-hidden', newCollapseState); + header.toggleClass('up-icon', !newCollapseState).toggleClass('down-icon', newCollapseState); }); - } - headers.forEach(function(header, index) { - if (!header.data('menuToggleAttached')) { + headers.forEach(function (header, index) { + if (!header.data('menuToggleAttached')) { toggleMenuVisibilityAndIcon(header, menus[index]); header.data('menuToggleAttached', true); - } - }); - initializeStateForMenus(); - $(window).resize(initializeStateForMenus); + } + }); + + } + } + + const resizeCallback = initializeStateForMenus(drupalSettings.localgov_publications.foo.collapse_width); + + if (drupalSettings.localgov_publications.foo.collapsible) { + resizeCallback(); + $(window).resize(resizeCallback); + } + } -}; \ No newline at end of file +}; +})(jQuery, Drupal, drupalSettings); diff --git a/localgov_publications.libraries.yml b/localgov_publications.libraries.yml index 15ab664..73913fa 100644 --- a/localgov_publications.libraries.yml +++ b/localgov_publications.libraries.yml @@ -9,6 +9,14 @@ localgov-publications: - core/drupal - core/drupal.form +localgov-publications-blocks: + js: + js/localgov-publications-collapsible-contents.js: {} + dependencies: + - core/jquery + - core/drupal + - core/drupalSettings + localgov-publications-icons: css: theme: diff --git a/src/Plugin/Block/PublicationNavigationBlock.php b/src/Plugin/Block/PublicationNavigationBlock.php index 3011a98..d9a0a50 100644 --- a/src/Plugin/Block/PublicationNavigationBlock.php +++ b/src/Plugin/Block/PublicationNavigationBlock.php @@ -168,6 +168,15 @@ public function build() { if (!empty($output)) { $this->node = $node; $this->setActiveClass($output['#items']); + + // TODO: block instance identifier? + $output['#attached']['drupalSettings']['localgov_publications']['foo'] = [ + 'collapsible' => $this->configuration['collapsible'], + 'collapse_width' => $this->configuration['collapse_width'], + ]; + + $output['#attached']['library'][] = 'localgov_publications/localgov-publications-blocks'; + return $output; } }