Skip to content

Commit

Permalink
Implement ResizeAware Mixin
Browse files Browse the repository at this point in the history
  • Loading branch information
lenadax committed Aug 23, 2024
1 parent ef20e07 commit 89324b5
Show file tree
Hide file tree
Showing 7 changed files with 221 additions and 132 deletions.
4 changes: 2 additions & 2 deletions js/src/header.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export class Header extends LayoutAware {
}

/**
* Binds event listeners for navbar collapse events.
* Binds event listeners for bootstrap navbar collapse events.
*/
bind() {
const wrapper = this.navbar_content_wrapper;
Expand All @@ -83,7 +83,7 @@ export class Header extends LayoutAware {
}

/**
* Sets a header classto indicate the mobile menu is open.
* Sets a header class to indicate the mobile menu is open.
*/
set_mobile_menu_open() {
this.elem.addClass('mobile-menu-open');
Expand Down
54 changes: 54 additions & 0 deletions js/src/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,57 @@ export class LayoutAware extends ts.Events {
// ...
}
}

/**
* A mixin to add window resize awareness to a class.
*
* This mixin expects that the class it extends has an `elem` property.
* It attaches a resize event listener to the window that triggers the
* `on_window_resize` method defined in the subclass.
*
* @param {class} Base - The base class to extend.
* @returns {class}
*/
export const ResizeAware = (Base) => class extends Base {

/**
* @param {...any} args
*/
constructor(...args) {
super(...args);

if (this.elem) {
ts.ajax.attach(this, this.elem);
}

this.on_window_resize = this.on_window_resize.bind(this);

$(window).on('resize', this.on_window_resize);
}

/**
* Handler for the window resize event.
*
* This method should be overridden in the subclass to define custom resize
* behavior.
*/
on_window_resize(evt) {
// Call `on_window_resize` of the base class, if it exists
if (super.on_window_resize) {
super.on_window_resize(evt);
}
}

/**
* Removes the resize event handler from the window.
*/
destroy() {
try {
super.destroy();
} catch (error) {
console.warn(error);
} finally {
$(window).off('resize', this.on_window_resize);
}
}
};
2 changes: 1 addition & 1 deletion js/src/mainmenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export class MainMenu extends LayoutAware {
* Binds the dropdown events for desktop view.
*/
bind_dropdowns_desktop() {
// this.elems.on(...) and this.elems.each(...on(...)) are deprecated in jquery 4.0.0-beta.2
// this.elems.on(...) deprecated in jquery 4.0.0-beta.2 (?)
this.elem.on('shown.bs.dropdown', '.nav-link.dropdown-toggle', this.on_show_dropdown_desktop);
this.elem.on('hidden.bs.dropdown', '.nav-link.dropdown-toggle', this.on_hide_dropdown_desktop);
}
Expand Down
31 changes: 16 additions & 15 deletions js/src/scrollbar.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import $ from 'jquery';
import ts from 'treibstoff';
import {ResizeAware} from './layout.js';

/**
* Class representing a generic scrollbar.
Expand All @@ -25,7 +26,7 @@ export class Scrollbar extends ts.Motion {
* @param {jQuery} elem
*/
constructor(elem) {
super();
super(elem);

this.elem = elem;
if (this.elem.data('scrollbar')) {
Expand All @@ -38,7 +39,7 @@ export class Scrollbar extends ts.Motion {
this.on_scroll = this.on_scroll.bind(this);
this.on_click = this.on_click.bind(this);
this.on_hover = this.on_hover.bind(this);
this.on_resize = this.on_resize.bind(this);
this.on_window_resize = this.on_window_resize.bind(this);

this.compile();
this.position = 0;
Expand All @@ -52,6 +53,17 @@ export class Scrollbar extends ts.Motion {
new ts.Property(this, 'is_mobile', is_mobile);
}

/**
* Handles window resize event to adjust the scrollbar.
* Invoked by ResizeAware mixin.
* @param {Event} evt
*/
on_window_resize(evt) {
this.is_mobile = $(window).innerWidth() <= 768; // bs5 small/medium breakpoint
this.position = this.safe_position(this.position);
this.render();
}

/**
* Gets the current scroll position.
* @returns {number}
Expand Down Expand Up @@ -123,7 +135,6 @@ export class Scrollbar extends ts.Motion {
this.elem.on('mousewheel wheel', this.on_scroll);
this.scrollbar.on('click', this.on_click);
this.set_scope(this.thumb, $(document), this.elem);
$(window).on('resize', this.on_resize);
}

/**
Expand All @@ -134,7 +145,6 @@ export class Scrollbar extends ts.Motion {
this.elem.off('mouseenter mouseleave', this.on_hover);
this.scrollbar.off('click', this.on_click);
$(this.thumb).off('mousedown', this._down_handle);
$(window).off('resize', this.on_resize);
}

/**
Expand Down Expand Up @@ -210,15 +220,6 @@ export class Scrollbar extends ts.Motion {
}
}

/**
* Handles window resize events to adjust the scrollbar.
*/
on_resize() {
this.is_mobile = $(window).width() <= 768; // bs5 small/medium breakpoint
this.position = this.safe_position(this.position);
this.render();
}

/**
* Handles hover events to show/hide the scrollbar.
* @param {Event} evt
Expand Down Expand Up @@ -343,7 +344,7 @@ export class Scrollbar extends ts.Motion {
* Class representing a horizontal scrollbar.
* @extends Scrollbar
*/
export class ScrollbarX extends Scrollbar {
export class ScrollbarX extends ResizeAware(Scrollbar) {

/**
* Gets the horizontal offset of the scrollbar element.
Expand Down Expand Up @@ -414,7 +415,7 @@ export class ScrollbarX extends Scrollbar {
* Class representing a vertical scrollbar.
* @extends Scrollbar
*/
export class ScrollbarY extends Scrollbar {
export class ScrollbarY extends ResizeAware(Scrollbar) {

/**
* Gets the vertical offset of the scrollbar element.
Expand Down
13 changes: 11 additions & 2 deletions js/src/sidebar.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import $ from 'jquery';
import ts from 'treibstoff';
import { global_events } from './globals.js';
import { ResizeAware } from './layout.js';

/**
* Class to manage the sidebar of the application.
* @extends ts.Motion
*/
export class Sidebar extends ts.Motion {
export class Sidebar extends ResizeAware(ts.Motion) {

/**
* Initializes the Sidebar instance.
Expand Down Expand Up @@ -48,7 +49,6 @@ export class Sidebar extends ts.Motion {
this.set_scope(resizer_elem, $(document));

this.responsive_toggle = this.responsive_toggle.bind(this);
$(window).on('resize', this.responsive_toggle);
this.responsive_toggle();

// Enable scroll to refresh page on mobile devices
Expand Down Expand Up @@ -79,6 +79,15 @@ export class Sidebar extends ts.Motion {
return this.elem.outerWidth() <= 0;
}

/**
* Handles sidebar responsive collapsed state.
* Invoked by ResizeAware mixin.
* @param {*} evt
*/
on_window_resize(evt) {
this.responsive_toggle();
}

/**
* Toggles the sidebar's responsive state and css class based on its width.
*/
Expand Down
Loading

0 comments on commit 89324b5

Please sign in to comment.