@openeuropa/bcl-theme-default 1.9.2 → 1.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/css/oe-bcl-ckeditor5.min.css +1 -1
  2. package/css/oe-bcl-ckeditor5.min.css.map +1 -1
  3. package/css/oe-bcl-default.css +896 -1
  4. package/css/oe-bcl-default.css.map +1 -1
  5. package/css/oe-bcl-default.min.css +1 -1
  6. package/css/oe-bcl-default.min.css.map +1 -1
  7. package/js/oe-bcl-default.bundle.js +107 -60
  8. package/js/oe-bcl-default.bundle.js.map +1 -1
  9. package/js/oe-bcl-default.bundle.min.js +1 -1
  10. package/js/oe-bcl-default.bundle.min.js.map +1 -1
  11. package/js/oe-bcl-default.esm.js +107 -60
  12. package/js/oe-bcl-default.esm.js.map +1 -1
  13. package/js/oe-bcl-default.esm.min.js +1 -1
  14. package/js/oe-bcl-default.esm.min.js.map +1 -1
  15. package/js/oe-bcl-default.umd.js +107 -60
  16. package/js/oe-bcl-default.umd.js.map +1 -1
  17. package/js/oe-bcl-default.umd.min.js +1 -1
  18. package/js/oe-bcl-default.umd.min.js.map +1 -1
  19. package/package.json +8 -7
  20. package/src/js/accessible-toggle/accessible-toggle.js +11 -3
  21. package/src/js/gallery/gallery.js +118 -62
  22. package/src/scss/_accordion.scss +4 -0
  23. package/src/scss/_multiselect-2.scss +1 -1
  24. package/src/scss/_multiselect.scss +21 -0
  25. package/src/scss/_timeline.scss +2 -0
  26. package/src/scss/base/_variables.scss +2 -3
  27. package/templates/bcl-accordion/accordion.html.twig +8 -3
  28. package/templates/bcl-dropdown/dropdown.html.twig +1 -1
  29. package/templates/bcl-file/file-translations.html.twig +2 -2
  30. package/templates/bcl-gallery/gallery-item.html.twig +1 -0
  31. package/templates/bcl-gallery/gallery.html.twig +2 -2
  32. package/templates/bcl-inpage-navigation/inpage-navigation.html.twig +4 -4
  33. package/templates/bcl-language-switcher/language-switcher.html.twig +2 -2
  34. package/templates/bcl-modal/modal.html.twig +2 -2
  35. package/templates/bcl-timeline/timeline.html.twig +2 -2
@@ -1702,7 +1702,7 @@ const EVENT_HIDDEN$5 = `hidden${EVENT_KEY$8}`;
1702
1702
  const EVENT_SHOW$5 = `show${EVENT_KEY$8}`;
1703
1703
  const EVENT_SHOWN$5 = `shown${EVENT_KEY$8}`;
1704
1704
  const EVENT_CLICK_DATA_API$4 = `click${EVENT_KEY$8}${DATA_API_KEY$5}`;
1705
- const EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY$8}${DATA_API_KEY$5}`;
1705
+ const EVENT_KEYDOWN_DATA_API$1 = `keydown${EVENT_KEY$8}${DATA_API_KEY$5}`;
1706
1706
  const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY$8}${DATA_API_KEY$5}`;
1707
1707
  const CLASS_NAME_SHOW$6 = 'show';
1708
1708
  const CLASS_NAME_DROPUP = 'dropup';
@@ -2028,8 +2028,8 @@ class Dropdown extends BaseComponent {
2028
2028
  * Data API implementation
2029
2029
  */
2030
2030
 
2031
- EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE$3, Dropdown.dataApiKeydownHandler);
2032
- EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler);
2031
+ EventHandler.on(document, EVENT_KEYDOWN_DATA_API$1, SELECTOR_DATA_TOGGLE$3, Dropdown.dataApiKeydownHandler);
2032
+ EventHandler.on(document, EVENT_KEYDOWN_DATA_API$1, SELECTOR_MENU, Dropdown.dataApiKeydownHandler);
2033
2033
  EventHandler.on(document, EVENT_CLICK_DATA_API$4, Dropdown.clearMenus);
2034
2034
  EventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus);
2035
2035
  EventHandler.on(document, EVENT_CLICK_DATA_API$4, SELECTOR_DATA_TOGGLE$3, function (event) {
@@ -4802,23 +4802,16 @@ defineJQueryPlugin$1(Toast);
4802
4802
 
4803
4803
  /**
4804
4804
  * --------------------------------------------------------------------------
4805
- * Bootstrap (v5.1.3): gallery.js
4805
+ * Bootstrap (v5.1.3): gallery.js (Refactored)
4806
4806
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
4807
4807
  * --------------------------------------------------------------------------
4808
4808
  */
4809
4809
 
4810
-
4811
- /**
4812
- * ------------------------------------------------------------------------
4813
- * Constants
4814
- * ------------------------------------------------------------------------
4815
- */
4816
-
4817
- const Default = {};
4818
4810
  const NAME = 'gallery';
4819
4811
  const DATA_KEY = 'bs.gallery';
4820
4812
  const EVENT_KEY = `.${DATA_KEY}`;
4821
4813
  const DATA_API_KEY = '.data-api';
4814
+ const Default = {};
4822
4815
  const CAROUSEL_SELECTOR = '.carousel';
4823
4816
  const CAROUSEL_PAGER_SELECTOR = '.carousel-pager span';
4824
4817
  const CAROUSEL_ACTIVE_SELECTOR = '.carousel-item.active';
@@ -4828,72 +4821,115 @@ const MODAL_SELECTOR = '.modal';
4828
4821
  const EVENT_MODAL_HIDE = 'hide.bs.modal';
4829
4822
  const CAROUSEL_EVENT = 'slide.bs.carousel';
4830
4823
  const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
4831
-
4832
- /**
4833
- * ------------------------------------------------------------------------
4834
- * Class Definition
4835
- * ------------------------------------------------------------------------
4836
- */
4837
-
4824
+ const EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}`;
4838
4825
  class Gallery extends BaseComponent {
4839
4826
  constructor(element, config) {
4840
4827
  super(element, config);
4841
- /* eslint no-underscore-dangle: ["error", { "allow": ["_element"] }] */
4842
4828
  this.carousel = SelectorEngine.findOne(CAROUSEL_SELECTOR, this._element);
4843
4829
  this.carouselPager = SelectorEngine.findOne(CAROUSEL_PAGER_SELECTOR, this._element);
4844
- this.carouselStartIndex = element.getAttribute('data-gallery-start');
4845
- this.carouselActiveItem = SelectorEngine.find(CAROUSEL_ITEM_SELECTOR, this.carousel)[this.carouselStartIndex];
4846
- this.carouselPager.textContent = Number(this.carouselStartIndex) + 1;
4847
4830
  this.modal = SelectorEngine.findOne(MODAL_SELECTOR, this._element);
4848
- this.addEventListeners();
4849
- this.carouselLazyLoad(this.carouselActiveItem);
4831
+ this.carouselStartIndex = element.getAttribute('data-gallery-start') || 0;
4832
+ const allCarouselItems = SelectorEngine.find(CAROUSEL_ITEM_SELECTOR, this.carousel);
4833
+ const startIndexNum = Math.max(0, Math.min(Number(this.carouselStartIndex), allCarouselItems.length - 1));
4834
+ this.carouselPager.textContent = startIndexNum + 1;
4835
+ this.carouselActiveItem = allCarouselItems[startIndexNum];
4836
+ this._carouselLazyLoad(this.carouselActiveItem);
4837
+ EventHandler.on(this.carousel, CAROUSEL_EVENT, event => this._handleCarouselSlide(event));
4838
+ EventHandler.on(this.modal, EVENT_MODAL_HIDE, () => this._stopSlide());
4850
4839
  }
4851
4840
 
4852
4841
  // Getters
4853
4842
  static get NAME() {
4854
4843
  return NAME;
4855
4844
  }
4845
+ static get Default() {
4846
+ return Default;
4847
+ }
4856
4848
 
4857
- // Public
4858
- setSlide(event) {
4859
- const slideFrom = SelectorEngine.findOne(CAROUSEL_ACTIVE_SELECTOR, this.carousel);
4860
- const slideTo = event.relatedTarget;
4861
- this.carouselLazyLoad(slideTo);
4849
+ /**
4850
+ * Handle the carousel "slide.bs.carousel" event
4851
+ * @param {Event} event
4852
+ */
4853
+ _handleCarouselSlide(event) {
4854
+ const previousSlide = SelectorEngine.findOne(CAROUSEL_ACTIVE_SELECTOR, this.carousel);
4855
+ const currentSlide = event.relatedTarget;
4856
+ this._carouselLazyLoad(currentSlide);
4862
4857
  this.carouselPager.textContent = event.to + 1;
4863
- this.stopVideo(slideFrom);
4858
+ this._stopVideo(previousSlide);
4864
4859
  }
4865
- stopSlide() {
4860
+
4861
+ /**
4862
+ * Stop the current carousel slide (when modal hides or component is disposed)
4863
+ */
4864
+ _stopSlide() {
4866
4865
  const currentSlide = SelectorEngine.findOne(CAROUSEL_ACTIVE_SELECTOR, this.carousel);
4867
- this.stopVideo(currentSlide);
4866
+ this._stopVideo(currentSlide);
4868
4867
  }
4869
- stopVideo(slide) {
4868
+
4869
+ /**
4870
+ * Stop any video or iframe in the given slide
4871
+ * @param {HTMLElement} slide
4872
+ */
4873
+ _stopVideo(slide) {
4874
+ if (!slide) {
4875
+ return;
4876
+ }
4870
4877
  const iframe = SelectorEngine.findOne('iframe', slide);
4871
4878
  const video = SelectorEngine.findOne('video', slide);
4872
- if (iframe) {
4879
+ if (iframe && iframe.dataset.src) {
4873
4880
  iframe.src = iframe.dataset.src;
4874
4881
  } else if (video) {
4875
4882
  video.pause();
4876
4883
  }
4877
4884
  }
4878
4885
 
4879
- // Private
4880
- carouselLazyLoad(slide) {
4886
+ /**
4887
+ * Lazy load media (img, iframe, video, etc.) by copying data-src into src
4888
+ * @param {HTMLElement} slide
4889
+ */
4890
+ _carouselLazyLoad(slide) {
4891
+ if (!slide) {
4892
+ return;
4893
+ }
4881
4894
  const media = SelectorEngine.findOne('[data-src]', slide);
4882
4895
  if (media && !media.src) {
4883
4896
  media.src = media.dataset.src;
4884
4897
  }
4885
4898
  }
4886
- addEventListeners() {
4887
- EventHandler.on(this.carousel, CAROUSEL_EVENT, event => this.setSlide(event));
4888
- EventHandler.on(this.modal, EVENT_MODAL_HIDE, event => this.stopSlide(event));
4889
- }
4890
4899
 
4891
- // Static
4892
- static get Default() {
4893
- return Default;
4900
+ /**
4901
+ * Internal helper to open the modal and jump to a specific slide
4902
+ * @param {HTMLElement} gallery
4903
+ * @param {HTMLElement} targetLink
4904
+ */
4905
+ static _openModalAndShowSlide(gallery, targetLink) {
4906
+ if (!gallery || !targetLink) {
4907
+ return;
4908
+ }
4909
+ const firstSlide = Number(targetLink.getAttribute('data-bs-slide-to') || 0);
4910
+ gallery.dataset.galleryStart = firstSlide;
4911
+ const instance = Gallery.getOrCreateInstance(gallery);
4912
+ const overlay = SelectorEngine.findOne('.bcl-gallery__item-overlay', targetLink);
4913
+ if (overlay) {
4914
+ const modalId = overlay.getAttribute('data-bs-target');
4915
+ const modalElement = document.querySelector(modalId);
4916
+ if (modalElement) {
4917
+ const modal = bootstrap.Modal.getOrCreateInstance(modalElement);
4918
+ modal.show();
4919
+ }
4920
+ }
4921
+ setTimeout(() => {
4922
+ const carousel = SelectorEngine.findOne(CAROUSEL_SELECTOR, instance._element);
4923
+ const carouselInstance = bootstrap.Carousel.getOrCreateInstance(carousel);
4924
+ carouselInstance.to(firstSlide);
4925
+ const pager = SelectorEngine.findOne(CAROUSEL_PAGER_SELECTOR, instance._element);
4926
+ if (pager) {
4927
+ pager.textContent = firstSlide + 1;
4928
+ }
4929
+ }, 50);
4894
4930
  }
4895
4931
  static jQueryInterface(config) {
4896
- return this.each(function jInterface() {
4932
+ return this.each(function () {
4897
4933
  const data = Gallery.getOrCreateInstance(this);
4898
4934
  if (typeof config !== 'string') {
4899
4935
  return;
@@ -4908,24 +4944,28 @@ class Gallery extends BaseComponent {
4908
4944
 
4909
4945
  /**
4910
4946
  * ------------------------------------------------------------------------
4911
- * Data Api implementation
4947
+ * Data API implementation
4912
4948
  * ------------------------------------------------------------------------
4913
4949
  */
4914
4950
 
4951
+ const isEnterOrSpace = event => {
4952
+ return event.key === 'Enter' || event.key === ' ';
4953
+ };
4915
4954
  EventHandler.on(document, EVENT_CLICK_DATA_API, THUMBNAIL_SELECTOR, event => {
4955
+ event.preventDefault();
4956
+ const targetLink = event.target.closest('a');
4916
4957
  const gallery = event.target.closest('div.bcl-gallery');
4917
- const firstSlide = event.target.parentNode.getAttribute('data-bs-slide-to');
4918
- gallery.dataset.galleryStart = firstSlide;
4919
- Gallery.getOrCreateInstance(gallery);
4958
+ Gallery._openModalAndShowSlide(gallery, targetLink);
4959
+ });
4960
+ EventHandler.on(document, EVENT_KEYDOWN_DATA_API, THUMBNAIL_SELECTOR, event => {
4961
+ if (!isEnterOrSpace(event)) {
4962
+ return;
4963
+ }
4964
+ event.preventDefault();
4965
+ const targetLink = event.target.closest('a');
4966
+ const gallery = event.target.closest('div.bcl-gallery');
4967
+ Gallery._openModalAndShowSlide(gallery, targetLink);
4920
4968
  });
4921
-
4922
- /**
4923
- * ------------------------------------------------------------------------
4924
- * jQuery
4925
- * ------------------------------------------------------------------------
4926
- * add .gallery to jQuery only if jQuery is present
4927
- */
4928
-
4929
4969
  defineJQueryPlugin$1(Gallery);
4930
4970
 
4931
4971
  class AccordionToggle {
@@ -4993,9 +5033,16 @@ class AccessibleToggle {
4993
5033
  this.addEventListeners();
4994
5034
  }
4995
5035
  addAriaAttributes() {
4996
- if (this.triggerElement) {
4997
- this.triggerElement.setAttribute("aria-haspopup", "true");
4998
- this.triggerElement.setAttribute("aria-expanded", "false");
5036
+ if (this.type === 'modal') {
5037
+ if (this.triggerElement) {
5038
+ this.triggerElement.setAttribute('aria-haspopup', 'dialog');
5039
+ }
5040
+ }
5041
+ if (this.type === 'offcanvas') {
5042
+ if (this.triggerElement) {
5043
+ this.triggerElement.setAttribute('aria-haspopup', 'dialog');
5044
+ this.triggerElement.setAttribute('aria-expanded', 'false');
5045
+ }
4999
5046
  }
5000
5047
  }
5001
5048
  addEventListeners() {