Commit 4f02842a authored by Nick Poulden's avatar Nick Poulden
Browse files

Tab overflow

parent 61539ddc
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -60,7 +60,7 @@ desc "Run JSDuck on ExtJS SDK"
task :sdk do
  load_sdk_vars
  run_jsduck([
    "--extjs-path", "extjs/ext-all.js",
    "--extjs-path", "extjs/ext-all-debug.js",
    # to create symbolic links to template files instead of copying them over.
    # Useful for development.  Turn off for deployment.
    "--template-links",
+16 −2
Original line number Diff line number Diff line
@@ -65,6 +65,15 @@ Ext.define('Docs.controller.Tabs', {
                    //     }, this);
                    // }
                },
                resize: function() {
                    Ext.getCmp('doctabs').resizeTabs();
                },
                scope: this
            },
            '#tabOverflowMenu menuitem': {
                click: function(cmp) {
                    this.activateTab(cmp.href, true);
                },
                scope: this
            }
        });
@@ -110,6 +119,7 @@ Ext.define('Docs.controller.Tabs', {
                Ext.getCmp('doctabs').activateTab(next);
                Docs.History.push(next);
            }
            docTab.dom.removed = true;
            docTab.animate({
                to: { top: 30 }
            }).animate({
@@ -138,8 +148,7 @@ Ext.define('Docs.controller.Tabs', {
                return;
            }
            var url = Ext.get(el).down('.tabUrl').getAttribute('href');
            Ext.getCmp('doctabs').activateTab(url);
            Docs.History.push(url);
            this.activateTab(url);
        }, this, {
            delegate: '.doctab'
        });
@@ -148,6 +157,11 @@ Ext.define('Docs.controller.Tabs', {
            delegate: '.tabUrl',
            preventDefault: true
        });
    },

    activateTab: function(url, activateOverview) {
        Ext.getCmp('doctabs').activateTab(url, activateOverview);
        Docs.History.push(url);
    }

});
+153 −55
Original line number Diff line number Diff line
@@ -10,6 +10,11 @@ Ext.define('Docs.view.Tabs', {
    componentCls: 'doctabs',

    openTabs: [],
    tabBarTabs: [],
    overflowTabs: [],

    tabWidth: 140,
    minTabWidth: 80,

    initComponent: function() {
        var tpl = new Ext.XTemplate(
@@ -20,7 +25,8 @@ Ext.define('Docs.view.Tabs', {
                    '<div class="r"></div>',
                '</div>',
            '</tpl>',
            '<div style="float: left; width: 8px">&nbsp;</div>'
            '<div style="float: left; width: 8px">&nbsp;</div>',
            '<div id="tabOverflow"></div>'
        );

        this.html = tpl.applyTemplate([
@@ -34,6 +40,20 @@ Ext.define('Docs.view.Tabs', {
        this.callParent();
    },

    listeners: {
        afterrender: function() {
            Ext.create('Ext.button.Button', {
                baseCls: null,
                renderTo: 'tabOverflow',
                menu: {
                    id: 'tabOverflowMenu',
                    plain: true,
                    items: []
                }
            });
        }
    },

    tabQueue: [],

    /**
@@ -48,7 +68,41 @@ Ext.define('Docs.view.Tabs', {
     * @param {Boolean} opts.activate True to activate the tab
     */
    addTab: function(tab, opts) {

        // If there is room add tab
        // If no room, move last tab to overflow menu and update with current tab

        if (!Ext.Array.contains(this.openTabs, tab.href)) {

            this.openTabs.push(tab.href);
            Docs.Settings.set('openTabs', this.openTabs);

            if (this.overflowing()) {
                Ext.get('tabOverflow').show();
            } else {
                this.addTabToBar(tab, opts);
            }

            Ext.getCmp('tabOverflowMenu').add({
                text: tab.text,
                iconCls: tab.iconCls,
                origIcon: tab.iconCls,
                href: tab.href,
                cls: 'x-menu-item-checked' + (this.overflowing() ? ' overflow' : '')
            });
        }

        if (opts.activate) {
            this.activateTab(tab.href);
        }

        this.resizeTabs();
    },

    addTabToBar: function(tab, opts) {

        this.tabBarTabs.push(tab.url);

        var tpl = Ext.create('Ext.XTemplate',
            '<div class="doctab" style="visibility: hidden">',
                '<div class="l"></div>',
@@ -60,54 +114,88 @@ Ext.define('Docs.view.Tabs', {
            '</div>'
        );
        var docTab = Ext.get(tpl.append(this.el.dom, tab));
            docTab.dom.initialWidth = docTab.getWidth();

        if (opts.animate) {
            // Effect to 'slide' the tab out when it is created.
            docTab.setStyle('width', '10px');
            docTab.setStyle({ visibility: 'visible' });
            docTab.animate({
                    to: { width: docTab.dom.initialWidth }
                to: { width: this.tabWidth - this.tabDelta() }
            });
        }
        else {
            docTab.setStyle({ visibility: 'visible' });
        }
    },

            this.openTabs.push(tab.href);
            Docs.Settings.set('openTabs', this.openTabs);
        }
    /**
     * Returns the width of the Tab Bar
     * @return {Number} Tab bar width
     */
    tabBarWidth: function() {
        return Ext.getCmp('doctabs').getWidth() - 240;
    },

        if (opts.activate) {
            this.activateTab(tab.href);
        }
    /**
     * Returns the cumulative width of all visible tabs
     * @return {Number} Tabs width
     */
    totalTabsWidth: function() {
        return this.openTabs.length * this.tabWidth;
    },

        this.recalculateWidths();
    /**
     * Returns the cumulative width of all visible tabs
     * @return {Number} Tabs width
     */
    minTabsWidth: function() {
        return this.openTabs.length * this.minTabWidth;
    },

    recalculateWidths: function() {
    maxVisibleTabs: function() {
        return Math.ceil(this.tabBarWidth() / this.minTabWidth);
    },

        var maxWidth = Ext.getCmp('doctabs').getWidth() - 240;
        var numTabs = Ext.query('.doctab').length - 5;
    /**
     * Returns the width delta to be applied to each tab for them to fit within the tab bar
     * @return {Number} Number of pixels
     */
    tabDelta: function() {

        var tabsWidth = Ext.Array.sum(Ext.Array.map(Ext.query('.doctab'), function(t){
            var docTab = Ext.get(t);
            return docTab.dom.initialWidth - 5 || 0;
        }));
        var numTabs = this.maxVisibleTabs();
        if (this.openTabs.length < numTabs) numTabs = this.openTabs.length;

        var delta = Math.ceil((this.totalTabsWidth() - this.tabBarWidth()) / this.openTabs.length);
        return (delta < 0) ? 0 : delta;
    },

    /**
     * Returns true if the tab bar is overflowing
     */
    overflowing: function() {
        return ((this.openTabs.length - 1) * this.minTabWidth) > this.tabBarWidth();
    },

    /**
     * Resizes the tabs
     */
    resizeTabs: function() {

        clearTimeout(this.resizeTabsTimer);

        if (tabsWidth > maxWidth) {
            var tabDelta = Math.ceil((tabsWidth - maxWidth) / numTabs);
        if (this.totalTabsWidth() > this.tabBarWidth()) {

            var tabDelta = this.tabDelta();

            Ext.Array.each(Ext.query('.doctab'), function(t){
                var docTab = Ext.get(t);
                if (!docTab.hasCls('overview')) {
                    var width = docTab.dom.initialWidth;
                    var newWidth = (width - tabDelta) > 60 ? (width - tabDelta) : 60;
                if (!docTab.dom.removed && !docTab.hasCls('overview')) {
                    var newWidth = (this.tabWidth - tabDelta) > this.minTabWidth ? (this.tabWidth - tabDelta) : this.minTabWidth;
                    docTab.animate({
                        to: { width: newWidth }
                    });
                }
            });
            }, this);
        }
    },

@@ -116,7 +204,7 @@ Ext.define('Docs.view.Tabs', {
     *
     * @param {String} url URL of the tab to activate
     */
    activateTab: function(url) {
    activateTab: function(url, activateOverview) {
        this.activeTab = Ext.Array.indexOf(this.openTabs, url);
        Ext.Array.each(Ext.query('.doctab a[class=tabUrl]'), function(d) {
            Ext.get(d).up('.doctab').removeCls(['active', 'highlight']);
@@ -126,12 +214,19 @@ Ext.define('Docs.view.Tabs', {
            var docTab = Ext.get(activeTab).up('.doctab');
            docTab.addCls('active');
            if (!docTab.hasCls('overview')) {
                activateOverview = true;
            }
        }
        if (activateOverview) {
            var overviewTab = Ext.query('.doctab.' + this.getControllerName(url).toLowerCase());
            if (overviewTab && overviewTab[0]) {
                Ext.get(overviewTab[0]).addCls('highlight');
            }
        }
        }

        Ext.Array.each(Ext.ComponentQuery.query('#tabOverflowMenu menuitem'), function(menuItem) {
            menuItem.setIconCls(menuItem.href == url ? undefined : menuItem.origIcon);
        });
    },

    /**
@@ -149,7 +244,21 @@ Ext.define('Docs.view.Tabs', {
            if (this.activeTab > idx) {
                this.activeTab -= 1;
            }

            Ext.Array.each(Ext.ComponentQuery.query('#tabOverflowMenu menuitem[href=' + url + ']'), function(menuItem) {
                Ext.getCmp('tabOverflowMenu').remove(menuItem);
            });
        }

        if (this.resizeTabsTimer) {
            clearTimeout(this.resizeTabsTimer);
        }

        var self = this;
        this.resizeTabsTimer = setTimeout(function(){
            self.resizeTabs();
        }, 1000);

        if (idx === this.activeTab) {
            if (this.openTabs.length === 0) {
                Docs.App.getController(this.getControllerName(url)).loadIndex();
@@ -183,14 +292,3 @@ Ext.define('Docs.view.Tabs', {
        }
    }
});



// Ext.Array.each(Ext.query('.doctab'), function(t){
//     var docTab = Ext.get(t);
//     if (!docTab.hasCls('overview')) {
//         docTab.animate({
//             to: { width: 60 }
//         });
//     }
// });
+1.13 KiB
Loading image diff...
+21 −2
Original line number Diff line number Diff line
@@ -853,8 +853,7 @@ a {
      }
      a.tabUrl {
        padding: 0 14px 0 17px;
        max-width: 180px;
        text-overflow: ellipsis;
        width: 140px;
        overflow: hidden;
      }
      span.icn {
@@ -911,6 +910,9 @@ a {
  .doctab.overview .m {
    z-index: 6;
  }
  .doctab.overview .m a.tabUrl{
    width: auto !important;
  }
  .doctab.index .m a {
    background: url(../images/tab-icons.png) no-repeat 7px 1px;
    padding-left: 16px; padding-right: 12px; padding-bottom: 20px;
@@ -931,6 +933,23 @@ a {
    background: url(../images/tab-icons.png) no-repeat 7px -93px;
    padding-left: 16px; padding-right: 12px;
  }

  #tabOverflow {
    position: absolute;
    right: 5px;
    top: 8px;
    button {
      display: block;
      width: 14px;
      height: 20px;
      background: url(../images/tab-overflow.png) no-repeat;
      border: 0;
    }
  }
}

.overflow {
  background: #e3e3e3;
}

.all-demos {