diff --git a/docs/pages/off-canvas.md b/docs/pages/off-canvas.md index 1aba0b6d66..e0a9414887 100644 --- a/docs/pages/off-canvas.md +++ b/docs/pages/off-canvas.md @@ -346,13 +346,17 @@ For an example of off-canvas, checkout this top bar with off-canvas navigation a ## In-Canvas to Off-Canvas -With this feature you can have a standard page element move off-canvas at a particular breakpoint. Use the new class .in-canvas-for-[BREAKPOINT] for this. This differs from the Reveal on Larger Screens feature it doesn't actually open the off-canvas for specific screen sizes but overrides the off-canvas styles so it behaves as a regular page element. This way you can place an element anywhere on the page and move it into off-canvas for e.g. small screens. +With this feature you can have a standard page element move off-canvas at a particular breakpoint. Use the inCanvasOn option for this. In-Canvas differs from the Reveal on Larger Screens feature as it doesn't actually open the off-canvas for specific screen sizes but overrides the off-canvas styles so it behaves as a regular page element. This way you can place an element anywhere on the page and move it into off-canvas for e.g. small screens only. + +
+

The inCanvasOn option will automatically add the .in-canvas-for-[BREAKPOINT] class since most of the work is done via CSS only. However you may also add this class yourself which will override the option.

+
```html_example -
+
I'm in-canvas for medium screen size and move off-canvas for medium down.
``` diff --git a/js/foundation.offcanvas.js b/js/foundation.offcanvas.js index 38720e8583..3d442f9fa1 100644 --- a/js/foundation.offcanvas.js +++ b/js/foundation.offcanvas.js @@ -35,6 +35,7 @@ class OffCanvas extends Plugin { this.position = 'left'; this.$content = $(); this.nested = !!(this.options.nested); + this.isInCanvas = false; // Defines the CSS transition/position classes of the off-canvas content container. $(['push', 'overlap']).each((index, val) => { @@ -136,6 +137,20 @@ class OffCanvas extends Plugin { this.$element.css('transition-duration', this.options.transitionTime); } + let inCanvasFor = this.$element.attr('class').match(/\bin-canvas-for-(\w+)/); + + if (inCanvasFor && inCanvasFor.length === 2) { + // Set `inCanvasOn` option if found in-canvas-for-[BREAKPONT] CSS class + this.options.inCanvasOn = inCanvasFor[1]; + } else if (this.options.inCanvasOn) { + // Ensure the CSS class is set + this.$element.addClass(`in-canvas-for-${this.options.inCanvasOn}`); + } + + if (this.options.inCanvasOn) { + this._checkInCanvas(); + } + // Initally remove all transition/position CSS classes from off-canvas content container. this._removeContentClasses(); } @@ -157,6 +172,13 @@ class OffCanvas extends Plugin { var $target = this.options.contentOverlay ? this.$overlay : this.$content; $target.on({'click.zf.offCanvas': this.close.bind(this)}); } + + if (this.options.inCanvasOn) { + $(window).on('changed.zf.mediaquery', () => { + this._checkInCanvas(); + }); + } + } /** @@ -181,6 +203,17 @@ class OffCanvas extends Plugin { }); } + /** + * Checks if InCanvas on current breakpoint and adjust off-canvas accordingly + * @private + */ + _checkInCanvas() { + this.isInCanvas = MediaQuery.atLeast(this.options.inCanvasOn); + if (this.isInCanvas === true) { + this.close(); + } + } + /** * Removes the CSS transition/position classes of the off-canvas content container. * Removing the classes is important when another off-canvas gets opened that uses the same content container. @@ -285,7 +318,7 @@ class OffCanvas extends Plugin { * @todo also trigger 'open' event? */ open(event, trigger) { - if (this.$element.hasClass('is-open') || this.isRevealed) { return; } + if (this.$element.hasClass('is-open') || this.isRevealed || this.isInCanvas) { return; } var _this = this; if (trigger) { @@ -533,7 +566,15 @@ OffCanvas.defaults = { revealOn: null, /** - * Force focus to the OffCanvas on open. If true, will focus the opening trigger on close. + * Breakpoint at which the off-canvas gets moved into canvas content and acts as regular page element. + * @option + * @type {?string} + * @default null + */ + inCanvasOn: null, + + /** + * Force focus to the offcanvas on open. If true, will focus the opening trigger on close. * @option * @type {boolean} * @default true