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.
+
+
+
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