diff --git a/components/ILIAS/UI/UI.php b/components/ILIAS/UI/UI.php index 2b00ee377859..906f9496113c 100644 --- a/components/ILIAS/UI/UI.php +++ b/components/ILIAS/UI/UI.php @@ -41,7 +41,7 @@ public function init( $contribute[Component\Resource\PublicAsset::class] = fn() => new Component\Resource\ComponentJS($this, "js/Counter/dist/counter.js"); $contribute[Component\Resource\PublicAsset::class] = fn() => - new Component\Resource\ComponentJS($this, "js/Dropdown/dropdown.js"); + new Component\Resource\ComponentJS($this, "js/Dropdown/dist/dropdown.js"); $contribute[Component\Resource\PublicAsset::class] = fn() => new Component\Resource\NodeModule("dropzone/dist/min/dropzone.min.js"); diff --git a/components/ILIAS/UI/resources/js/Dropdown/dist/dropdown.js b/components/ILIAS/UI/resources/js/Dropdown/dist/dropdown.js new file mode 100644 index 000000000000..d36ed99d845a --- /dev/null +++ b/components/ILIAS/UI/resources/js/Dropdown/dist/dropdown.js @@ -0,0 +1,15 @@ +/** + * This file is part of ILIAS, a powerful learning management system + * published by ILIAS open source e-Learning e.V. + * + * ILIAS is licensed with the GPL-3.0, + * see https://www.gnu.org/licenses/gpl-3.0.en.html + * You should have received a copy of said license along with the + * source code, too. + * + * If this is not the case or you just want to try ILIAS, you'll find + * us at: + * https://www.ilias.de + * https://github.com/ILIAS-eLearning + */ +!function(t,e){"use strict";function i(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var n=i(t),s=i(e);class o{#t;#e;#i;#n;constructor(t,e){this.#t=t,this.#e=e;const i=this.#e.querySelectorAll(":scope > button");if(1!==i.length)throw new Error("Dropdown: Expected exactly one button in dropdown element.",this.#e);[this.#i]=i;const n=this.#e.querySelectorAll(":scope > ul");if(1!==n.length)throw new Error("Dropdown: Expected exactly one ul in dropdown element.",this.#e);[this.#n]=n,this.#i.addEventListener("keydown",(t=>{13===t.which&&this.toggleVisibility()})),this.#i.addEventListener("click",this.#s)}#o=t=>{27===t.which&&this.hide()};#s=t=>{t.stopPropagation(),this.show()};#h=()=>{this.hide()};toggleVisibility(){"block"===this.#n.style.display?this.hide():this.show()}show(){this.#n.style.display="block",this.#i.setAttribute("aria-expanded","true"),this.#t.addEventListener("keydown",this.#o),this.#t.addEventListener("click",this.#h),this.#i.removeEventListener("click",this.#s)}hide(){this.#n.style.display="none",this.#i.setAttribute("aria-expanded","false"),this.#t.removeEventListener("keydown",this.#o),this.#t.removeEventListener("click",this.#h),this.#i.addEventListener("click",this.#s)}}n.default.UI=n.default.UI||{},n.default.UI.dropdown=function(t){return new o(s.default,t)}}(il,document); diff --git a/components/ILIAS/UI/resources/js/Dropdown/dropdown.js b/components/ILIAS/UI/resources/js/Dropdown/dropdown.js deleted file mode 100755 index 2a61cf0310dd..000000000000 --- a/components/ILIAS/UI/resources/js/Dropdown/dropdown.js +++ /dev/null @@ -1,14 +0,0 @@ -(function($) { - $(document).on('shown.bs.dropdown', function(event) { - var dropdown = $(event.target); - dropdown.find('.dropdown-toggle').attr('aria-expanded', true); - //Fit Dropdowns correctly to page, omit for legacy component, add new Item, see #30856 - il.UI.page.fit(dropdown.find('.dropdown-menu:not(#il-add-new-item-gl)')); - }); - - // on close - $(document).on('hidden.bs.dropdown', function(event) { - var dropdown = $(event.target); - dropdown.find('.dropdown-toggle').attr('aria-expanded', false); - }); -})($); \ No newline at end of file diff --git a/components/ILIAS/UI/resources/js/Dropdown/rollup.config.js b/components/ILIAS/UI/resources/js/Dropdown/rollup.config.js new file mode 100644 index 000000000000..c8a9d8cbe049 --- /dev/null +++ b/components/ILIAS/UI/resources/js/Dropdown/rollup.config.js @@ -0,0 +1,27 @@ +import terser from '@rollup/plugin-terser'; +import copyright from '../../../../../../scripts/Copyright-Checker/copyright'; +import preserveCopyright from '../../../../../../scripts/Copyright-Checker/preserveCopyright'; + +export default { + external: [ + 'document', + 'ilias', + ], + input: './src/dropdown.js', + output: { + file: './dist/dropdown.js', + format: 'iife', + banner: copyright, + globals: { + document: 'document', + ilias: 'il', + }, + plugins: [ + terser({ + format: { + comments: preserveCopyright, + }, + }), + ], + }, +}; diff --git a/components/ILIAS/UI/resources/js/Dropdown/src/dropdown.class.js b/components/ILIAS/UI/resources/js/Dropdown/src/dropdown.class.js new file mode 100644 index 000000000000..fc510c930a75 --- /dev/null +++ b/components/ILIAS/UI/resources/js/Dropdown/src/dropdown.class.js @@ -0,0 +1,105 @@ +/** +* This file is part of ILIAS, a powerful learning management system +* published by ILIAS open source e-Learning e.V. +* +* ILIAS is licensed with the GPL-3.0, +* see https://www.gnu.org/licenses/gpl-3.0.en.html +* You should have received a copy of said license along with the +* source code, too. +* +* If this is not the case or you just want to try ILIAS, you'll find +* us at: +* https://www.ilias.de +* https://github.com/ILIAS-eLearning +*/ + +export default class Dropdown { + /** + * @type {DOMDocument} + */ + #document; + + /** + * @type {HTMLElement} + */ + #element; + + /** + * @type {HTMLElement} + */ + #button; + + /** + * @type {HTMLElement} + */ + #list; + + /** + * @param {DOMDocument} document + * @param {HTMLElement} element + */ + constructor(document, element) { + this.#document = document; + this.#element = element; + + const buttons = this.#element.querySelectorAll(':scope > button'); + if (buttons.length !== 1) { + throw new Error('Dropdown: Expected exactly one button in dropdown element.', this.#element); + } + [this.#button] = buttons; + + const lists = this.#element.querySelectorAll(':scope > ul'); + if (lists.length !== 1) { + throw new Error('Dropdown: Expected exactly one ul in dropdown element.', this.#element); + } + [this.#list] = lists; + + this.#button.addEventListener('keydown', (event) => { + if (event.which === 13) { // Enter + this.toggleVisibility(); + } + }); + + this.#button.addEventListener('click', this.#showOnClick); + } + + #hideOnEscape = (event) => { + if (event.which === 27) { // ESCAPE + this.hide(); + } + }; + + #showOnClick = (event) => { + event.stopPropagation(); + this.show(); + }; + + #hideOnClick = () => { + this.hide(); + }; + + toggleVisibility() { + const visible = this.#list.style.display === 'block'; + if (visible) { + this.hide(); + } else { + this.show(); + } + } + + show() { + this.#list.style.display = 'block'; + this.#button.setAttribute('aria-expanded', 'true'); + this.#document.addEventListener('keydown', this.#hideOnEscape); + this.#document.addEventListener('click', this.#hideOnClick); + this.#button.removeEventListener('click', this.#showOnClick); + } + + hide() { + this.#list.style.display = 'none'; + this.#button.setAttribute('aria-expanded', 'false'); + this.#document.removeEventListener('keydown', this.#hideOnEscape); + this.#document.removeEventListener('click', this.#hideOnClick); + this.#button.addEventListener('click', this.#showOnClick); + } +} diff --git a/components/ILIAS/UI/resources/js/Dropdown/src/dropdown.js b/components/ILIAS/UI/resources/js/Dropdown/src/dropdown.js new file mode 100644 index 000000000000..6dc23ada284e --- /dev/null +++ b/components/ILIAS/UI/resources/js/Dropdown/src/dropdown.js @@ -0,0 +1,23 @@ +/** + * This file is part of ILIAS, a powerful learning management system + * published by ILIAS open source e-Learning e.V. + * + * ILIAS is licensed with the GPL-3.0, + * see https://www.gnu.org/licenses/gpl-3.0.en.html + * You should have received a copy of said license along with the + * source code, too. + * + * If this is not the case or you just want to try ILIAS, you'll find + * us at: + * https://www.ilias.de + * https://github.com/ILIAS-eLearning + */ + +import il from 'ilias'; +import document from 'document'; +import Dropdown from './dropdown.class'; + +il.UI = il.UI || {}; +il.UI.dropdown = function (htmlElement) { + return new Dropdown(document, htmlElement); +}; diff --git a/components/ILIAS/UI/src/Implementation/Component/Dropdown/Renderer.php b/components/ILIAS/UI/src/Implementation/Component/Dropdown/Renderer.php index 00d2770d3038..b01fad526ff0 100755 --- a/components/ILIAS/UI/src/Implementation/Component/Dropdown/Renderer.php +++ b/components/ILIAS/UI/src/Implementation/Component/Dropdown/Renderer.php @@ -74,6 +74,11 @@ protected function renderDropdown(Dropdown $component, RendererInterface $defaul $tpl->parseCurrentBlock(); } + $component = $component->withAdditionalOnLoadCode( + fn($id) => + "il.UI.dropdown(document.getElementById(\"$id\"));" + ); + $this->renderId($component, $tpl); return $tpl->get(); diff --git a/components/ILIAS/UI/src/templates/default/Dropdown/tpl.standard.html b/components/ILIAS/UI/src/templates/default/Dropdown/tpl.standard.html index f2a0520d5acc..d141db0c606f 100755 --- a/components/ILIAS/UI/src/templates/default/Dropdown/tpl.standard.html +++ b/components/ILIAS/UI/src/templates/default/Dropdown/tpl.standard.html @@ -1,4 +1,4 @@ -