page-element.html 9.33 KB
<link rel="import" href="../../bower_components/iron-selector/iron-selector.html">
<link rel="import" href="../../bower_components/iron-icons/iron-icons.html">
<link rel="import" href="../../bower_components/paper-toolbar/paper-toolbar.html">
<link rel="import" href="../../bower_components/paper-item/paper-item.html">
<link rel="import" href="../../bower_components/paper-header-panel/paper-header-panel.html">
<link rel="import" href="../../bower_components/paper-drawer-panel/paper-drawer-panel.html">
<link rel="import" href="../../bower_components/iron-component-page/iron-component-page.html">
<link rel="import" href="../../bower_components/paper-menu/paper-menu.html">
<link rel="import" href="../../bower_components/paper-item/paper-item.html">

<link rel="import" href="../catalog-data/catalog-data.html">
<link rel="import" href="../catalog-element/catalog-element.html">
<link rel="import" href="../catalog-package/catalog-package.html">
<link rel="import" href="../package-symbol/package-symbol.html">
<link rel="import" href="../responsive-element/responsive-element.html">
<link rel="import" href="../theme-color/theme-color.html">
<link rel="import" href="../cart-icon/cart-icon.html">
<link rel="import" href="../cart-item-icon/cart-item-icon.html">

<dom-module id="page-element">
  <link rel="import" type="css" href="page-element.css">
  <template>
    <catalog-element name="[[element]]" data="{{metadata}}"></catalog-element>
    <catalog-package name="[[metadata.package]]" data="{{package}}"></catalog-package>
    <catalog-data elements="{{elements}}" behavior-map="{{behaviorMap}}"></catalog-data>
    <paper-drawer-panel id="drawerPanel" narrow="{{narrowDrawer}}" responsive-width="900px" drawer-width="272px" disable-edge-swipe>
        <app-sidebar drawer>
          <paper-toolbar>
            <app-logo class="flex"></app-logo>
            <app-bar class="horizontal layout center end-justified" query="{{q}}"></app-bar>
          </paper-toolbar>
          <div class="content">
            <a is="app-link" href="[[_packageLink(package.name)]]" class="horizontal layout center" id="package-heading">
              <iron-icon icon="chevron-left"></iron-icon>
              <package-symbol color="[[package.color]]" symbol="[[package.symbol]]"></package-symbol>
              <span class="name flex">[[package.title]]</span>
            </a>
            <div id="element-header">
              <span class="version">[[metadata.version]]</span>
              <h2 id="element-title">[[element]]</h2>
              <div id="element-desc">
                <p>[[metadata.description]]</p>
              </div>
            </div>

            <nav id="nav" class="nav" attr-for-selected="name" selected="{{view}}">
              <a is="app-link" class="item" href="[[_link(active,'docs')]]" active$="[[_isEqual(view,'docs')]]"><iron-icon icon="description"></iron-icon> <span>Docs</span></a>
              <template is="dom-repeat" items="[[docDemos]]">
                <a is="app-link" class="item" href="[[_demoLink(active,item.path)]]" active$="[[_demoActive(item.path,view)]]"><iron-icon icon="visibility"></iron-icon> <span>[[_demoName(item.desc)]]</span></a>
              </template>
              <a class="item" href="[[_githubLink(metadata.source)]]" target="_blank"><iron-icon icon="code"></iron-icon> <span>Source</span></a>
            </nav>

            <div class="nav" id="cart-add">
              <paper-item hidden$="[[!metadata]]" on-tap="toggleCart"><cart-item-icon id="cartIcon" element="[[element]]"></cart-item-icon></paper-item>
            </div>

            <div class="bower-command-label">Bower Command</div>
            <input class="bower-command" title="Bower Command" readonly value="[[_bowerCommand(metadata.source)]]" on-tap="_selectAllBowerCommand">

            <section hidden$="[[_oneOrFewer(docElements, docBehaviors)]]" class="shrinkable">
              <h4>Bundled Elements</h4>

              <nav id="elnav" class="nav">
                <template is="dom-repeat" items="[[docElements]]">
                  <a is="app-link" class="item" href$="[[_link(item.is,view)]]" active$="[[_isEqual(item.is,active)]]">[[item.is]]</a>
                </template>
              </nav>
            </section>

            <section class="shrinkable" hidden$="[[_oneOrFewer(docBehaviors, docElements)]]">
              <h4>Bundled Behaviors</h4>
              <nav id="elnav" class="nav" attr-for-selected="name" selected="[[active]]">
                <template is="dom-repeat" items="[[docBehaviors]]">
                  <a is="app-link" class="item" href$="[[_link(item.is,view)]]" active$="[[_isEqual(item.is,active)]]">[[item.is]]</a>
                </template>
              </nav>
            </section>
          </div>
        </app-sidebar>
        <section main class="fit">
          <iron-component-page 
            _catalog
            id="componentPage"
            scroll-mode="[[_getScrollMode(narrowDrawer)]]"
            package$="[[package.name]]"
            version="[[metadata.version]]"
            doc-src="[[docSrc(element)]]"
            base="[[baseURI(element)]]"
            view="{{view}}"
            doc-elements="{{docElements}}"
            doc-behaviors="{{docBehaviors}}"
            doc-demos="{{docDemos}}"
            active="{{active}}"
            on-iron-doc-viewer-component-selected="navToBehavior"
            on-iron-component-page-error="_handleError">
          </iron-component-page>
          <paper-icon-button icon="menu" paper-drawer-toggle></paper-icon-button>
          <cart-icon fade-out$="[[_isCartIconHidden(view)]]"></cart-icon>
        </section>
      </paper-drawer-panel>
  </template>
</dom-module>

<script>
  Polymer({
    is: 'page-element',
    enableCustomStyleProperties: true,
    properties: {
      element: String,
      view: {type: String, value: 'docs'},
      active: {type: String, value: ''},
      docElements: Array,
      docBehaviors: Array,
      docDemos: Array,
      docs: Object,
      metadata: {type: Object, value: null},
      package: Object,
      router: Object,
      q: String,
      packageName: {
        type: String,
        reflectToAttribute: true
      },
      narrowDrawer: Boolean
    },
    observers: [
      'updateMeta(element,active)',
      'viewUpdated(view)',
      'analyze(importPath)',
      'search(q)',
      '_updateStyles(package)'
    ],
    attached: function() {
      this.updateMeta();
    },
    analyze: function() {
      this.$.analyzer.analyze();
    },
    _link: function(active,view) {
      return this.getURL(active,view);
    },
    _demoLink: function(active,path) {
      return this.getURL(active, 'demo:' + path, true);
    },
    _demoActive: function(path) {
      return this.view === 'demo:' + path;
    },
    _githubLink: function(source) {
      return 'https://github.com/' + source;
    },
    getURL: function(active,view,force) {
      var url = "/elements/" + this.element;
      var qs = [];
      if (force || (view && view.length && view !== 'docs')) qs.push('view=' + view);
      if (force || (active && active.length && active !== this.element)) qs.push('active=' + active);
      if (qs.length) url += "?" + qs.join("&");
      return url;
    },
    updateMeta: function(element,active) {
      this.$.drawerPanel.closeDrawer();
      this.fire('page-meta', {title: (this.active && this.active.length) ? this.active : this.element});
    },
    viewUpdated: function() {
      this.$.drawerPanel.closeDrawer();
    },
    _packageLink: function() {
      return "/browse?package=" + this.package.name;
    },
    navToElement: function(e) {
      this.router.go("/elements/" + e.currentTarget.getAttribute('name'));
    },
    navToBehavior: function(e, detail) {
      if (this.behaviorMap[detail]) {
        this.router.go("/elements/" + this.behaviorMap[detail] + "?active=" + detail);
      } else {
        this.fire('toast', {text: "No documentation available for " + detail});
      }
    },
    docSrc: function(element) {
      return "/data/docs/" + element + ".json";
    },
    baseURI: function(element) {
      return window.location.origin + "/bower_components/" + element + "/" + element + ".html";
    },
    search: function(q) {
      if (q || this.q) {
        this.router.go('/browse?q=' + (q || this.q));
      }
    },
    cartAdd: function() {
      this.fire('cart-add', this.element);
    },
    _oneOrFewer: function(arr1, arr2) {
      if (!arr1 || arr1.length === 0) {
        return true;
      }
      if (!arr2) {
        return arr1.length <= 1;
      }
      return arr1.length + arr2.length <= 1;
    },
    toggleCart: function() {
      this.$.cartIcon.toggle();
    },
    listFilter: function(el) {
      return el.package === this.package.name;
    },
    _demoName: function(name) {
      return name === 'demo' ? 'Demo' : name;
    },
    _isEqual: function(a,b) {
      return a === b;
    },
    _bowerCommand: function(source) {
      return 'bower install --save ' + source;
    },
    _selectAllBowerCommand: function(e) {
      e.currentTarget.select();
    },
    _isCartIconHidden: function(view) {
      return view.indexOf('demo:') === 0;
    },

    _handleError: function() {
      this.router.go('/404');
    },

    _updateStyles: function(packageInfo) {
      this.packageName = packageInfo.name;
      this.async(this.$.componentPage.updateStyles, 2);
    },
    _getScrollMode: function(narrowDrawer) {
      return narrowDrawer ? 'waterfall' : 'scroll';
    }
  });
</script>