]> git.ipfire.org Git - thirdparty/foundation/foundation-sites.git/commitdiff
initial commit
authorjk <j.koehler@modulingo.de>
Tue, 17 Jan 2017 16:27:03 +0000 (17:27 +0100)
committerjk <j.koehler@modulingo.de>
Tue, 17 Jan 2017 16:27:03 +0000 (17:27 +0100)
docs/pages/accordion.md
js/foundation.accordion.js

index 27a2078f58f81b60e95efe6d52861c39024840fa..fb157a143e29235d5e86b18c4eed8b66da2ad5f0 100644 (file)
@@ -122,3 +122,49 @@ By default, at least one pane in an accordion must be open. This can be changed
     </div>
   </li>
 </ul>
+
+---
+
+## Accordion and URLs
+
+### Browser history
+
+When the `data-deep-link` option is set to `true`, the current state of the accordion is recorded by adding a hash with the accordion panel ID to the browser URL when a accordion opens. By default, accordion *replace* the browser history (using `history.replaceState()`). Modify this behavior by using attribute `data-update-history="true"` to *append* to the browser history (using `history.pushState()`). In the latter case the browser back button will track each click that opens a accordion panel.
+
+By using deep linking (see below), the open state of a page's tabset may be shared by copy-pasting the browser URL.
+
+### Deep linking
+
+Add the attribute `data-deep-link="true"` to a accordion to:
+- modify the browser history when a accordion panel is clicked
+- allow users to open a particular accordion panel at page load with a hash-appended URL
+
+```html_example
+<ul class="accordion" data-accordion data-deep-link="true" id="deeplinked-accordion">
+  <li class="accordion-item is-active" data-accordion-item>
+    <a href="#deeplink1" class="accordion-title">Accordion 1</a>
+    <div class="accordion-content" data-tab-content id="deeplink1">
+      Panel 1. Lorem ipsum dolor
+    </div>
+  </li>
+  <li class="accordion-item" data-accordion-item>
+    <a href="#deeplink2" class="accordion-title">Accordion 2</a>
+    <div class="accordion-content" data-tab-content id="deeplink2">
+      Panel 2. Lorem ipsum dolor
+    </div>
+  </li>
+  <li class="accordion-item" data-accordion-item>
+    <a href="#deeplink3" class="accordion-title">Accordion 3</a>
+    <div class="accordion-content" data-tab-content id="deeplink3">
+      Panel 3. Lorem ipsum dolor
+    </div>
+  </li>
+</ul>
+```
+For example, <a target="_blank" href="#deeplink3">http://example.com/#deeplink3</a> will open the third accordion panel at page load. This example will open a new browser tab and scroll you to the open accordion panel.
+
+When linking directly to a accordion panel, it might not be obvious that the content appears within a accordion panel. An additional attribute `data-deep-link-smudge` rolls the page up slightly after deep linking (to a horizontal accordion) so that the accordion is at the top of the viewport.
+
+```html_example
+<ul class="accordion" data-deep-link="true" data-deep-link-smudge="true" data-deep-link-smudge-delay="600" data-accordion id="deeplinked-accordion-with-smudge">
+```
index 04e6291be3e1320eef6116d6ea22522435f6da2b..3449f7bef4c40708876ca871daf08901dbcfb9fb 100644 (file)
@@ -56,10 +56,45 @@ class Accordion {
 
       $content.attr({'role': 'tabpanel', 'aria-labelledby': linkId, 'aria-hidden': true, 'id': id});
     });
-    var $initActive = this.$element.find('.is-active').children('[data-tab-content]');
+    var $initActive = this.$element.find('.is-active').children('[data-tab-content]'),
+    firstTimeInit = true;
     if($initActive.length){
-      this.down($initActive, true);
+      this.down($initActive, firstTimeInit);
+      firstTimeInit = false;
     }
+
+    //use browser to open a tab, if it exists in this tabset
+    if (this.options.deepLink) {
+      var anchor = window.location.hash;
+      //need a hash and a relevant anchor in this tabset
+      if(anchor.length) {
+        var $link = this.$element.find('[href$="'+anchor+'"]'),
+        $anchor = $(anchor);
+
+        if ($link.length && $anchor) {
+          if (!$link.parent('[data-accordion-item]').hasClass('is-active')) {
+            this.down($anchor, firstTimeInit);
+            firstTimeInit = false;
+          };
+
+          //roll up a little to show the titles
+          if (this.options.deepLinkSmudge) {
+            var _this = this;
+            $(window).load(function() {
+              var offset = _this.$element.offset();
+              $('html, body').animate({ scrollTop: offset.top }, _this.options.deepLinkSmudgeDelay);
+            });
+          }
+
+          /**
+            * Fires when the zplugin has deeplinked at pageload
+            * @event Accordion#deeplink
+            */
+          this.$element.trigger('deeplink.zf.accordion', [$link, $anchor]);
+        }
+      }
+    }
+
     this._events();
   }
 
@@ -116,6 +151,16 @@ class Accordion {
     } else {
       this.down($target);
     }
+    //either replace or update browser history
+    if (this.options.deepLink) {
+      var anchor = $target.prev('a').attr('href');
+
+      if (this.options.updateHistory) {
+        history.pushState({}, '', anchor);
+      } else {
+        history.replaceState({}, '', anchor);
+      }
+    }
   }
 
   /**
@@ -220,7 +265,38 @@ Accordion.defaults = {
    * @type {boolean}
    * @default false
    */
-  allowAllClosed: false
+  allowAllClosed: false,
+  /**
+   * Allows the window to scroll to content of pane specified by hash anchor
+   * @option
+   * @type {boolean}
+   * @default false
+   */
+  deepLink: false,
+
+  /**
+   * Adjust the deep link scroll to make sure the top of the accordion panel is visible
+   * @option
+   * @type {boolean}
+   * @default false
+   */
+  deepLinkSmudge: false,
+
+  /**
+   * Animation time (ms) for the deep link adjustment
+   * @option
+   * @type {number}
+   * @default 300
+   */
+  deepLinkSmudgeDelay: 300,
+
+  /**
+   * Update the browser history with the open accordion
+   * @option
+   * @type {boolean}
+   * @default false
+   */
+  updateHistory: false
 };
 
 // Window exports