buildSDK/dependancy_bootstrap.txt
[roojs1] / roojs-bootstrap-debug.js
index c75ca1b..3d4f568 100644 (file)
@@ -413,7 +413,7 @@ Roo.extend(Roo.bootstrap.Component, Roo.BoxComponent,  {
             return;
         }
          
-        this.getVisibilityEl().removeClass('hidden');
+        this.getVisibilityEl().removeClass(['hidden','d-none']);
         
         this.fireEvent('show', this);
         
@@ -428,7 +428,7 @@ Roo.extend(Roo.bootstrap.Component, Roo.BoxComponent,  {
             return;
         }
         
-        this.getVisibilityEl().addClass('hidden');
+        this.getVisibilityEl().addClass(['hidden','d-none']);
         
         this.fireEvent('hide', this);
         
@@ -589,7 +589,8 @@ Roo.extend(Roo.bootstrap.ButtonGroup, Roo.bootstrap.Component,  {
  * @cfg {String} href empty or href
  * @cfg {Boolean} disabled default false;
  * @cfg {Boolean} isClose default false;
- * @cfg {String} glyphicon depricated - use fs
+ * @cfg {String} glyphicon depricated - use fa
+ * @cfg {String} fa fontawesome icon - eg. 'comment' - without the fa/fas etc..
  * @cfg {String} badge text for badge
  * @cfg {String} theme (default|glow)  
  * @cfg {Boolean} inverse dark themed version
@@ -2409,7 +2410,7 @@ Roo.extend(Roo.bootstrap.Menu, Roo.bootstrap.Component,  {
             this.hide();
         } else {
             Roo.log('show');
-            this.show(this.triggerEl, false, false);
+            this.show(this.triggerEl, '?', false);
         }
         
         if(this.stopEvent || e.getTarget().nodeName.toLowerCase() === 'i'){
@@ -2513,7 +2514,7 @@ Roo.extend(Roo.bootstrap.MenuItem, Roo.bootstrap.Component,  {
         if(this.isContainer){
             return {
                 tag: 'li',
-                cls: 'dropdown-menu-item dropdown-item'
+                cls: 'dropdown-menu-item '
             };
         }
         var ctag = {
@@ -2523,6 +2524,7 @@ Roo.extend(Roo.bootstrap.MenuItem, Roo.bootstrap.Component,  {
         
         var anc = {
             tag : 'a',
+            cls : 'dropdown-item',
             href : '#',
             cn : [  ]
         };
@@ -2539,7 +2541,7 @@ Roo.extend(Roo.bootstrap.MenuItem, Roo.bootstrap.Component,  {
         
         var cfg= {
             tag: 'li',
-            cls: 'dropdown-menu-item dropdown-item',
+            cls: 'dropdown-menu-item',
             cn: [ anc ]
         };
         if (this.parent().type == 'treeview') {
@@ -2640,7 +2642,7 @@ Roo.extend(Roo.bootstrap.MenuSeparator, Roo.bootstrap.Component,  {
  * @cfg {Roo.Template} tmpl - a template with variables. to use it, add a handler in show:method  adn
  * @cfg {Boolean} specificTitle default false
  * @cfg {Array} buttons Array of buttons or standard button set..
- * @cfg {String} buttonPosition (left|right|center) default right
+ * @cfg {String} buttonPosition (left|right|center) default right (DEPRICATED) - use mr-auto on buttons to put them on the left
  * @cfg {Boolean} animate default true
  * @cfg {Boolean} allow_close default true
  * @cfg {Boolean} fitwindow default false
@@ -2766,7 +2768,7 @@ Roo.extend(Roo.bootstrap.Modal, Roo.bootstrap.Component,  {
 
                 var btn = Roo.factory(b);
 
-                btn.render(this.el.select('.modal-footer div').first());
+                btn.render(this.getButtonContainer());
 
             },this);
         }
@@ -2834,7 +2836,26 @@ Roo.extend(Roo.bootstrap.Modal, Roo.bootstrap.Component,  {
         if(this.size.length){
             size = 'modal-' + this.size;
         }
+        
+        var footer = Roo.bootstrap.version == 3 ?
+            {
+                cls : 'modal-footer',
+                cn : [
+                    {
+                        tag: 'div',
+                        cls: 'btn-' + this.buttonPosition
+                    }
+                ]
+
+            } :
+            {  // BS4 uses mr-auto on left buttons....
+                cls : 'modal-footer'
+            };
 
+            
+
+        
+        
         var modal = {
             cls: "modal",
              cn : [
@@ -2849,18 +2870,7 @@ Roo.extend(Roo.bootstrap.Modal, Roo.bootstrap.Component,  {
                                     cn : header
                                 },
                                 bdy,
-                                {
-                                    cls : 'modal-footer',
-                                    cn : [
-                                        {
-                                            tag: 'div',
-                                            cls: 'btn-' + this.buttonPosition
-                                        }
-                                    ]
-
-                                }
-
-
+                                footer
                             ]
 
                         }
@@ -2883,7 +2893,10 @@ Roo.extend(Roo.bootstrap.Modal, Roo.bootstrap.Component,  {
 
     },
     getButtonContainer : function() {
-         return this.el.select('.modal-footer div',true).first();
+        
+         return Roo.bootstrap.version == 4 ?
+            this.el.select('.modal-footer',true).first()
+            : this.el.select('.modal-footer div',true).first();
 
     },
     initEvents : function()
@@ -2904,9 +2917,15 @@ Roo.extend(Roo.bootstrap.Modal, Roo.bootstrap.Component,  {
         );
         
         if (this.fitwindow) {
+            
+            var view_height = Roo.lib.Dom.getViewportHeight(true);
+            
+            Roo.log("dialog height: "+this.height);
+            Roo.log("view height:" + view_height);
+            
             this.setSize(
                 this.width || Roo.lib.Dom.getViewportWidth(true) - 30,
-                this.height || Roo.lib.Dom.getViewportHeight(true) - 60
+                this.height || Roo.lib.Dom.getViewportHeight(true) // catering margin-top 30 margin-bottom 30
             );
             return;
         }
@@ -3059,7 +3078,7 @@ Roo.extend(Roo.bootstrap.Modal, Roo.bootstrap.Component,  {
 
         var btn = Roo.factory(b);
 
-        btn.render(this.el.select('.modal-footer div').first());
+        btn.render(this.getButtonContainer());
 
         return btn;
 
@@ -3069,22 +3088,18 @@ Roo.extend(Roo.bootstrap.Modal, Roo.bootstrap.Component,  {
     {
         //this.el.select('.modal-footer').()
     },
-    diff : false,
 
     resizeTo: function(w,h)
     {
-        // skip.. ?? why??
-
         this.dialogEl.setWidth(w);
-        if (this.diff === false) {
-            this.diff = this.dialogEl.getHeight() - this.bodyEl.getHeight();
-        }
-
-        this.bodyEl.setHeight(h - this.diff);
+        
+        var diff = this.headerEl.getHeight() + this.footerEl.getHeight() + 30; // dialog margin-bottom: 30  
 
+        this.bodyEl.setHeight(h - diff);
+        
         this.fireEvent('resize', this);
-
     },
+    
     setContentSize  : function(w, h)
     {
 
@@ -3311,10 +3326,11 @@ Roo.bootstrap.MessageBox = function(){
             buttons["cancel"].hide();
             buttons["yes"].hide();
             buttons["no"].hide();
-            //dlg.footer.dom.style.display = 'none';
+            dlg.footerEl.hide();
+            
             return width;
         }
-        dlg.footerEl.dom.style.display = '';
+        dlg.footerEl.show();
         for(var k in buttons){
             if(typeof buttons[k] != "function"){
                 if(b[k]){
@@ -3591,6 +3607,9 @@ Roo.Msg.show({
                 textareaEl.hide();
             }
             progressEl.setDisplayed(opt.progress === true);
+            if (opt.progress) {
+                d.animate = false; // do not animate progress, as it may not have finished animating before we close it..
+            }
             this.updateProgress(0);
             activeTextEl.dom.value = opt.value || "";
             if(opt.prompt){
@@ -3861,7 +3880,41 @@ Roo.extend(Roo.bootstrap.Navbar, Roo.bootstrap.Component,  {
         //Roo.log(this.el.select('.navbar-toggle',true));
         this.el.select('.navbar-toggle',true).on('click', function() {
             if(this.fireEvent('beforetoggle', this) !== false){
-               this.el.select('.navbar-collapse',true).toggleClass('in');                                 
+                var ce = this.el.select('.navbar-collapse',true).first();
+                ce.toggleClass('in'); // old...
+                if (ce.hasClass('collapse')) {
+                    // show it...
+                    ce.removeClass('collapse');
+                    ce.addClass('show');
+                    var h = ce.getHeight();
+                    Roo.log(h);
+                    ce.removeClass('show');
+                    // at this point we should be able to see it..
+                    ce.addClass('collapsing');
+                    
+                    ce.setHeight(0); // resize it ...
+                    ce.on('transitionend', function() {
+                        Roo.log('done transition');
+                        ce.removeClass('collapsing');
+                        ce.addClass('show');
+                        ce.removeClass('collapse');
+
+                        ce.dom.style.height = '';
+                    }, this, { single: true} );
+                    ce.setHeight(h);
+                    
+                } else {
+                    ce.setHeight(ce.getHeight());
+                    ce.removeClass('show');
+                    ce.addClass('collapsing');
+                    
+                    ce.on('transitionend', function() {
+                        ce.dom.style.height = '';
+                        ce.removeClass('collapsing');
+                        ce.addClass('collapse');
+                    }, this, { single: true} );
+                    ce.setHeight(0);
+                }
             }
             
         }, this);
@@ -3969,14 +4022,23 @@ Roo.extend(Roo.bootstrap.NavSimplebar, Roo.bootstrap.Navbar,  {
         
         var cfg = {
             tag : this.tag || 'div',
-            cls : 'navbar navbar-expand-lg'
+            cls : 'navbar navbar-expand-lg roo-navbar-simple'
         };
        if (['light','white'].indexOf(this.weight) > -1) {
            cfg.cls += ['light','white'].indexOf(this.weight) > -1 ? ' navbar-light' : ' navbar-dark';
        }
        cfg.cls += ' bg-' + this.weight;
        
-         
+       if (this.inverse) {
+            cfg.cls += ' navbar-inverse';
+            
+        }
+       
+       // i'm not actually sure these are really used - normally we add a navGroup to a navbar
+       
+       //if (Roo.bootstrap.version == 4) {
+       //    return cfg;
+       //}
        
         cfg.cn = [
             {
@@ -3987,7 +4049,7 @@ Roo.extend(Roo.bootstrap.NavSimplebar, Roo.bootstrap.Navbar,  {
         
          
         this.type = this.type || 'nav';
-        if (['tabs','pills'].indexOf(this.type)!==-1) {
+        if (['tabs','pills'].indexOf(this.type) != -1) {
             cfg.cn[0].cls += ' nav-' + this.type
         
         
@@ -4001,7 +4063,7 @@ Roo.extend(Roo.bootstrap.NavSimplebar, Roo.bootstrap.Navbar,  {
         
         
         
-        if (['stacked','justified'].indexOf(this.arrangement)!==-1) {
+        if (['stacked','justified'].indexOf(this.arrangement) != -1) {
             cfg.cn[0].cls += ' nav-' + this.arrangement;
         }
         
@@ -4010,10 +4072,7 @@ Roo.extend(Roo.bootstrap.NavSimplebar, Roo.bootstrap.Navbar,  {
             cfg.cn[0].cls += ' navbar-right';
         }
         
-        if (this.inverse) {
-            cfg.cls += ' navbar-inverse';
-            
-        }
+        
         
         
         return cfg;
@@ -4131,6 +4190,12 @@ Roo.extend(Roo.bootstrap.NavHeaderbar, Roo.bootstrap.NavSimplebar,  {
         
         cfg.cls += this.inverse ? ' navbar-inverse navbar-dark bg-dark' : ' navbar-default';
         
+        if (['light','white'].indexOf(this.weight) > -1) {
+           cfg.cls += ['light','white'].indexOf(this.weight) > -1 ? ' navbar-light' : ' navbar-dark';
+       }
+       cfg.cls += ' bg-' + this.weight;
+        
+        
         if (['fixed-top','fixed-bottom','static-top'].indexOf(this.position)>-1) {
             cfg.cls += ' navbar-' + this.position + ' ' + this.position ;
             
@@ -4307,15 +4372,22 @@ Roo.extend(Roo.bootstrap.NavGroup, Roo.bootstrap.Component,  {
             tag : 'ul',
             cls: 'nav' 
         };
-        
-        if (['tabs','pills'].indexOf(this.type)!==-1) {
-            cfg.cls += ' nav-' + this.type
-        } else {
-            if (this.type!=='nav') {
-                Roo.log('nav type must be nav/tabs/pills')
-            }
-            cfg.cls += ' navbar-nav'
-        }
+        if (Roo.bootstrap.version == 4) {
+           if (['tabs','pills'].indexOf(this.type) != -1) {
+               cfg.cls += ' nav-' + this.type; 
+           } else {
+               cfg.cls += ' navbar-nav';
+           }
+       } else {
+           if (['tabs','pills'].indexOf(this.type) != -1) {
+               cfg.cls += ' nav-' + this.type
+           } else {
+               if (this.type !== 'nav') {
+                   Roo.log('nav type must be nav/tabs/pills')
+               }
+               cfg.cls += ' navbar-nav'
+           }
+       }
         
         if (this.parent() && this.parent().sidebar) {
             cfg = {
@@ -4329,7 +4401,7 @@ Roo.extend(Roo.bootstrap.NavGroup, Roo.bootstrap.Component,  {
         if (this.form === true) {
             cfg = {
                 tag: 'form',
-                cls: 'navbar-form'
+                cls: 'navbar-form form-inline'
             };
             
             if (this.align === 'right') {
@@ -4416,7 +4488,10 @@ Roo.extend(Roo.bootstrap.NavGroup, Roo.bootstrap.Component,  {
     */
     addItem : function(cfg)
     {
-        var cn = new Roo.bootstrap.NavItem(cfg);
+        if (this.form && Roo.bootstrap.version == 4) {
+           cfg.tag = 'div';
+       }
+       var cn = new Roo.bootstrap.NavItem(cfg);
         this.register(cn);
         cn.parentId = this.id;
         cn.onRender(this.el, null);
@@ -4542,6 +4617,8 @@ Roo.apply(Roo.bootstrap.NavGroup, {
  * @extends Roo.bootstrap.Component
  * Bootstrap Navbar.NavItem class
  * @cfg {String} href  link to
+ * @cfg {String} button_weight (default | primary | secondary | success | info | warning | danger | link ) default none
+
  * @cfg {String} html content of button
  * @cfg {String} badge text inside badge
  * @cfg {String} badgecls (bg-green|bg-red|bg-yellow)the extra classes for the badge
@@ -4603,16 +4680,20 @@ Roo.extend(Roo.bootstrap.NavItem, Roo.bootstrap.Component,  {
     preventDefault : false,
     tabId : false,
     tagtype : 'a',
+    tag: 'li',
     disabled : false,
     animateRef : false,
     was_active : false,
+    button_weight : '',
+    button_outline : false,
+    
+    navLink: false,
     
     getAutoCreate : function(){
          
         var cfg = {
-            tag: 'li',
+            tag: this.tag,
             cls: 'nav-item'
-            
         };
         
         if (this.active) {
@@ -4621,6 +4702,27 @@ Roo.extend(Roo.bootstrap.NavItem, Roo.bootstrap.Component,  {
         if (this.disabled) {
             cfg.cls += ' disabled';
         }
+       
+       // BS4 only?
+       if (this.button_weight.length) {
+           cfg.tag = this.href ? 'a' : 'button';
+           cfg.html = this.html || '';
+           cfg.cls += ' btn btn' + (this.button_outline ? '-outline' : '') + '-' + this.button_weight;
+           if (this.href) {
+               cfg.href = this.href;
+           }
+           if (this.fa) {
+                cfg.html = '<i class="fa fas fa-'+this.fa+'"></i> <span>' + this.html + '</span>';
+            }
+           
+           // menu .. should add dropdown-menu class - so no need for carat..
+           
+           if (this.badge !== '') {
+                 
+                cfg.html += ' <span class="badge badge-secondary">' + this.badge + '</span>';
+            }
+           return cfg;
+       }
         
         if (this.href || this.html || this.glyphicon || this.icon || this.fa) {
             cfg.cn = [
@@ -4634,10 +4736,10 @@ Roo.extend(Roo.bootstrap.NavItem, Roo.bootstrap.Component,  {
                cfg.cn[0].cls = 'nav-link';
            }
             if (this.icon) {
-                cfg.cn[0].html = '<i class="'+this.icon+'"></i> <span>' + cfg.cn[0].html + '</span>'
+                cfg.cn[0].html = '<i class="'+this.icon+'"></i> <span>' + cfg.cn[0].html + '</span>';
             }
            if (this.fa) {
-                cfg.cn[0].html = '<i class="fa fas fa-'+this.fa+'"></i> <span>' + cfg.cn[0].html + '</span>'
+                cfg.cn[0].html = '<i class="fa fas fa-'+this.fa+'"></i> <span>' + cfg.cn[0].html + '</span>';
             }
             if(this.glyphicon) {
                 cfg.cn[0].html = '<span class="glyphicon glyphicon-' + this.glyphicon + '"></span> '  + cfg.cn[0].html;
@@ -4659,6 +4761,19 @@ Roo.extend(Roo.bootstrap.NavItem, Roo.bootstrap.Component,  {
         
         return cfg;
     },
+    onRender : function(ct, position)
+    {
+       // Roo.log("Call onRender: " + this.xtype);
+        if (Roo.bootstrap.version == 4 && ct.dom.type != 'ul') {
+           this.tag = 'div';
+       }
+       
+        var ret = Roo.bootstrap.NavItem.superclass.onRender.call(this, ct, position);
+       this.navLink = this.el.select('.nav-link',true).first();
+       return ret;
+    },
+      
+    
     initEvents: function() 
     {
         if (typeof (this.menu) != 'undefined') {
@@ -4760,8 +4875,14 @@ Roo.extend(Roo.bootstrap.NavItem, Roo.bootstrap.Component,  {
         
         if (!state ) {
             this.el.removeClass('active');
+           this.navLink ? this.navLink.removeClass('active') : false;
         } else if (!this.el.hasClass('active')) {
+           
             this.el.addClass('active');
+           if (Roo.bootstrap.version == 4 && this.navLink ) {
+               this.navLink.addClass('active');
+           }
+           
         }
         if (fire) {
             this.fireEvent('changed', this, state);
@@ -8914,12 +9035,12 @@ Roo.extend(Roo.bootstrap.Input, Roo.bootstrap.Component,  {
     
        
     /**
-     * @cfg {String} invalidClass The CSS class to use when marking a field invalid (defaults to "x-form-invalid")
+     * @cfg {String} invalidClass DEPRICATED - code uses BS4 - is-valid / is-invalid
      */
     invalidClass : "has-warning",
     
     /**
-     * @cfg {String} validClass The CSS class to use when marking a field valid (defaults to "x-form-invalid")
+     * @cfg {String} validClass DEPRICATED - code uses BS4 - is-valid / is-invalid
      */
     validClass : "has-success",
     
@@ -9198,7 +9319,7 @@ Roo.extend(Roo.bootstrap.Input, Roo.bootstrap.Component,  {
         }
         if (align ==='left' && this.fieldLabel.length) {
             
-            cfg.cls += ' roo-form-group-label-left row';
+            cfg.cls += ' roo-form-group-label-left'  + (Roo.bootstrap.version == 4 ? ' row' : '');
             
             cfg.cn = [
                 indicator,
@@ -9332,9 +9453,10 @@ Roo.extend(Roo.bootstrap.Input, Roo.bootstrap.Component,  {
            cfg.cls += ' navbar-form';
         }
         
-        if (this.parentType === 'NavGroup') {
-           cfg.cls += ' navbar-form';
-           cfg.tag = 'li';
+        if (this.parentType === 'NavGroup' && !(Roo.bootstrap.version == 4 && this.parent().form)) {
+            // on BS4 we do this only if not form 
+            cfg.cls += ' navbar-form';
+            cfg.tag = 'li';
         }
         
         return cfg;
@@ -9670,8 +9792,8 @@ Roo.extend(Roo.bootstrap.Input, Roo.bootstrap.Component,  {
             return;
         }
         
-     
-        this.el.removeClass(this.invalidClass);
+        
+        this.el.removeClass([this.invalidClass, 'is-invalid']);
         
         if(this.hasFeedback && this.inputType != 'hidden' && !this.allowBlank){
             
@@ -9701,7 +9823,8 @@ Roo.extend(Roo.bootstrap.Input, Roo.bootstrap.Component,  {
         }
         
         this.el.removeClass([this.invalidClass, this.validClass]);
-        
+        this.inputEl().removeClass(['is-valid', 'is-invalid']);
+
         var feedback = this.el.select('.form-control-feedback', true).first();
             
         if(feedback){
@@ -9720,9 +9843,12 @@ Roo.extend(Roo.bootstrap.Input, Roo.bootstrap.Component,  {
         if(this.allowBlank && !this.getRawValue().length){
             return;
         }
-        
-        this.el.addClass(this.validClass);
-        
+        if (Roo.bootstrap.version == 3) {
+            this.el.addClass(this.validClass);
+        } else {
+            this.inputEl().addClass('is-valid');
+        }
+
         if(this.hasFeedback && this.inputType != 'hidden' && !this.allowBlank && (this.getValue().length || this.forceFeedback)){
             
             var feedback = this.el.select('.form-control-feedback', true).first();
@@ -9748,11 +9874,13 @@ Roo.extend(Roo.bootstrap.Input, Roo.bootstrap.Component,  {
         }
         
         this.el.removeClass([this.invalidClass, this.validClass]);
+        this.inputEl().removeClass(['is-valid', 'is-invalid']);
         
         var feedback = this.el.select('.form-control-feedback', true).first();
             
         if(feedback){
-            this.el.select('.form-control-feedback', true).first().removeClass([this.invalidFeedbackClass, this.validFeedbackClass]);
+            this.el.select('.form-control-feedback', true).first().removeClass(
+                    [this.invalidFeedbackClass, this.validFeedbackClass]);
         }
 
         if(this.disabled){
@@ -9767,8 +9895,13 @@ Roo.extend(Roo.bootstrap.Input, Roo.bootstrap.Component,  {
             this.indicator.removeClass(this.indicatorpos == 'right' ? 'hidden' : 'invisible');
             this.indicator.addClass('visible');
         }
+        if (Roo.bootstrap.version == 3) {
+            this.el.addClass(this.invalidClass);
+        } else {
+            this.inputEl().addClass('is-invalid');
+        }
+        
         
-        this.el.addClass(this.invalidClass);
         
         if(this.hasFeedback && this.inputType != 'hidden' && !this.allowBlank){
             
@@ -10115,9 +10248,9 @@ Roo.extend(Roo.bootstrap.TextArea, Roo.bootstrap.Input,  {
         if(label && icon){
             icon.remove();
         }
-        
-        this.el.removeClass(this.invalidClass);
-        
+        this.el.removeClass( this.validClass);
+        this.inputEl().removeClass('is-invalid');
+         
         if(this.hasFeedback && this.inputType != 'hidden' && !this.allowBlank){
             
             var feedback = this.el.select('.form-control-feedback', true).first();
@@ -10141,6 +10274,7 @@ Roo.extend(Roo.bootstrap.TextArea, Roo.bootstrap.Input,  {
         }
         
         this.el.removeClass([this.invalidClass, this.validClass]);
+        this.inputEl().removeClass(['is-valid', 'is-invalid']);
         
         var feedback = this.el.select('.form-control-feedback', true).first();
             
@@ -10158,8 +10292,12 @@ Roo.extend(Roo.bootstrap.TextArea, Roo.bootstrap.Input,  {
         if(label && icon){
             icon.remove();
         }
+        if (Roo.bootstrap.version == 3) {
+            this.el.addClass(this.validClass);
+        } else {
+            this.inputEl().addClass('is-valid');
+        }
         
-        this.el.addClass(this.validClass);
         
         if(this.hasFeedback && this.inputType != 'hidden' && !this.allowBlank && (this.getValue().length || this.forceFeedback)){
             
@@ -10186,6 +10324,7 @@ Roo.extend(Roo.bootstrap.TextArea, Roo.bootstrap.Input,  {
         }
         
         this.el.removeClass([this.invalidClass, this.validClass]);
+        this.inputEl().removeClass(['is-valid', 'is-invalid']);
         
         var feedback = this.el.select('.form-control-feedback', true).first();
             
@@ -10208,9 +10347,14 @@ Roo.extend(Roo.bootstrap.TextArea, Roo.bootstrap.Input,  {
                 style : 'margin-right:5px;'
             }, label, true);
         }
-
-        this.el.addClass(this.invalidClass);
         
+        if (Roo.bootstrap.version == 3) {
+            this.el.addClass(this.invalidClass);
+        } else {
+            this.inputEl().addClass('is-invalid');
+        }
+        
+        // fixme ... this may be depricated need to test..
         if(this.hasFeedback && this.inputType != 'hidden' && !this.allowBlank){
             
             var feedback = this.el.select('.form-control-feedback', true).first();
@@ -10497,7 +10641,7 @@ Roo.extend(Roo.bootstrap.TriggerField, Roo.bootstrap.Input,  {
         
         if (align ==='left' && this.fieldLabel.length) {
             
-            cfg.cls += ' roo-form-group-label-left row';
+            cfg.cls += ' roo-form-group-label-left'  + (Roo.bootstrap.version == 4 ? ' row' : '');
 
             cfg.cn = [
                 indicator,
@@ -13186,12 +13330,12 @@ Roo.extend(Roo.bootstrap.ComboBox, Roo.bootstrap.TriggerField, {
     multiple : false,
     
     /**
-     * @cfg {String} invalidClass The CSS class to use when marking a field invalid (defaults to "x-form-invalid")
+     * @cfg {String} invalidClass DEPRICATED - uses BS4 is-valid now
      */
     invalidClass : "has-warning",
     
     /**
-     * @cfg {String} validClass The CSS class to use when marking a field valid (defaults to "x-form-invalid")
+     * @cfg {String} validClass DEPRICATED - uses BS4 is-valid now
      */
     validClass : "has-success",
     
@@ -13338,6 +13482,7 @@ Roo.extend(Roo.bootstrap.ComboBox, Roo.bootstrap.TriggerField, {
         
         var box = {
             tag: 'div',
+            style : 'display: contents',
             cn: [
                 {
                     tag: 'input',
@@ -13396,7 +13541,7 @@ Roo.extend(Roo.bootstrap.ComboBox, Roo.bootstrap.TriggerField, {
         }
         if (align ==='left' && this.fieldLabel.length) {
             
-            cfg.cls += ' roo-form-group-label-left row';
+            cfg.cls += ' roo-form-group-label-left'  + (Roo.bootstrap.version == 4 ? ' row' : '');
             
             cfg.cn = [
                 indicator,
@@ -18216,7 +18361,7 @@ Roo.extend(Roo.bootstrap.TabGroup, Roo.bootstrap.Column,  {
     {
         if(this.transition || typeof(pan) == 'undefined'){
             Roo.log("waiting for the transitionend");
-            return;
+            return false;
         }
         
         if (typeof(pan) == 'number') {
@@ -18248,22 +18393,28 @@ Roo.extend(Roo.bootstrap.TabGroup, Roo.bootstrap.Column,  {
         
         if (this.carousel && typeof(Roo.get(document.body).dom.style.transition) != 'undefined') {
             
+            //class="carousel-item carousel-item-next carousel-item-left"
+            
             this.transition = true;
             var dir = this.indexOfPanel(pan) > this.indexOfPanel(cur)  ? 'next' : 'prev';
             var lr = dir == 'next' ? 'left' : 'right';
             pan.el.addClass(dir); // or prev
+            pan.el.addClass('carousel-item-' + dir); // or prev
             pan.el.dom.offsetWidth; // find the offset with - causing a reflow?
             cur.el.addClass(lr); // or right
             pan.el.addClass(lr);
+            cur.el.addClass('carousel-item-' +lr); // or right
+            pan.el.addClass('carousel-item-' +lr);
+            
             
             var _this = this;
             cur.el.on('transitionend', function() {
                 Roo.log("trans end?");
                 
-                pan.el.removeClass([lr,dir]);
+                pan.el.removeClass([lr,dir, 'carousel-item-' + lr, 'carousel-item-' + dir]);
                 pan.setActive(true);
                 
-                cur.el.removeClass([lr]);
+                cur.el.removeClass([lr, 'carousel-item-' + lr]);
                 cur.setActive(false);
                 
                 _this.transition = false;
@@ -18455,10 +18606,12 @@ Roo.extend(Roo.bootstrap.TabPanel, Roo.bootstrap.Component,  {
     href : '',
     
     getAutoCreate : function(){
-        var cfg = {
+        
+       
+       var cfg = {
             tag: 'div',
             // item is needed for carousel - not sure if it has any effect otherwise
-            cls: 'tab-pane item' + ((this.href.length) ? ' clickable ' : ''),
+            cls: 'carousel-item tab-pane item' + ((this.href.length) ? ' clickable ' : ''),
             html: this.html || ''
         };
         
@@ -18470,6 +18623,7 @@ Roo.extend(Roo.bootstrap.TabPanel, Roo.bootstrap.Component,  {
             cfg.tabId = this.tabId;
         }
         
+       
         
         return cfg;
     },
@@ -21115,16 +21269,28 @@ Roo.extend(Roo.bootstrap.CheckBox, Roo.bootstrap.Input,  {
 
         if(this.inputType == 'radio'){
             Roo.each(this.el.up('form').select('input[name='+this.name+']', true).elements, function(e){
-                e.findParent('.form-group', false, true).removeClass([_this.invalidClass, _this.validClass]);
-                e.findParent('.form-group', false, true).addClass(_this.validClass);
+                var fg = e.findParent('.form-group', false, true);
+                if (Roo.bootstrap.version == 3) {
+                    fg.removeClass([_this.invalidClass, _this.validClass]);
+                    fg.addClass(_this.validClass);
+                } else {
+                    fg.removeClass(['is-valid', 'is-invalid']);
+                    fg.addClass('is-valid');
+                }
             });
             
             return;
         }
 
         if(!this.groupId){
-            this.el.findParent('.form-group', false, true).removeClass([this.invalidClass, this.validClass]);
-            this.el.findParent('.form-group', false, true).addClass(this.validClass);
+            var fg = this.el.findParent('.form-group', false, true);
+            if (Roo.bootstrap.version == 3) {
+                fg.removeClass([this.invalidClass, this.validClass]);
+                fg.addClass(this.validClass);
+            } else {
+                fg.removeClass(['is-valid', 'is-invalid']);
+                fg.addClass('is-valid');
+            }
             return;
         }
         
@@ -21135,8 +21301,14 @@ Roo.extend(Roo.bootstrap.CheckBox, Roo.bootstrap.Input,  {
         }
         
         for(var i in group){
-            group[i].el.findParent('.form-group', false, true).removeClass([this.invalidClass, this.validClass]);
-            group[i].el.findParent('.form-group', false, true).addClass(this.validClass);
+            var fg = group[i].el.findParent('.form-group', false, true);
+            if (Roo.bootstrap.version == 3) {
+                fg.removeClass([this.invalidClass, this.validClass]);
+                fg.addClass(this.validClass);
+            } else {
+                fg.removeClass(['is-valid', 'is-invalid']);
+                fg.addClass('is-valid');
+            }
         }
     },
     
@@ -21165,17 +21337,30 @@ Roo.extend(Roo.bootstrap.CheckBox, Roo.bootstrap.Input,  {
         }
             
         if(this.inputType == 'radio'){
+            
             Roo.each(this.el.up('form').select('input[name='+this.name+']', true).elements, function(e){
-                e.findParent('.form-group', false, true).removeClass([_this.invalidClass, _this.validClass]);
-                e.findParent('.form-group', false, true).addClass(_this.invalidClass);
+                var fg = e.findParent('.form-group', false, true);
+                if (Roo.bootstrap.version == 3) {
+                    fg.removeClass([_this.invalidClass, _this.validClass]);
+                    fg.addClass(_this.invalidClass);
+                } else {
+                    fg.removeClass(['is-invalid', 'is-valid']);
+                    fg.addClass('is-invalid');
+                }
             });
             
             return;
         }
         
         if(!this.groupId){
-            this.el.findParent('.form-group', false, true).removeClass([this.invalidClass, this.validClass]);
-            this.el.findParent('.form-group', false, true).addClass(this.invalidClass);
+            var fg = this.el.findParent('.form-group', false, true);
+            if (Roo.bootstrap.version == 3) {
+                fg.removeClass([_this.invalidClass, _this.validClass]);
+                fg.addClass(_this.invalidClass);
+            } else {
+                fg.removeClass(['is-invalid', 'is-valid']);
+                fg.addClass('is-invalid');
+            }
             return;
         }
         
@@ -21186,8 +21371,14 @@ Roo.extend(Roo.bootstrap.CheckBox, Roo.bootstrap.Input,  {
         }
         
         for(var i in group){
-            group[i].el.findParent('.form-group', false, true).removeClass([this.invalidClass, this.validClass]);
-            group[i].el.findParent('.form-group', false, true).addClass(this.invalidClass);
+            var fg = group[i].el.findParent('.form-group', false, true);
+            if (Roo.bootstrap.version == 3) {
+                fg.removeClass([_this.invalidClass, _this.validClass]);
+                fg.addClass(_this.invalidClass);
+            } else {
+                fg.removeClass(['is-invalid', 'is-valid']);
+                fg.addClass('is-invalid');
+            }
         }
         
     },
@@ -21201,8 +21392,8 @@ Roo.extend(Roo.bootstrap.CheckBox, Roo.bootstrap.Input,  {
         var label = Roo.bootstrap.FieldLabel.get(this.name + '-group');
         
         if (label && label.iconEl) {
-            label.iconEl.removeClass(label.validClass);
-            label.iconEl.removeClass(label.invalidClass);
+            label.iconEl.removeClass([ label.validClass, label.invalidClass ]);
+            label.iconEl.removeClass(['is-invalid', 'is-valid']);
         }
     },
     
@@ -23831,9 +24022,7 @@ Roo.extend(Roo.bootstrap.HtmlEditor, Roo.bootstrap.TextArea,  {
     /**
      * @cfg {String} inputType @hide
      */
-    /**
-     * @cfg {String} invalidClass @hide
-     */
+     
     /**
      * @cfg {String} invalidText @hide
      */
@@ -23933,7 +24122,8 @@ Roo.extend(Roo.bootstrap.htmleditor.ToolbarStandard, Roo.bootstrap.NavSimplebar,
                 size : 'sm',
                 xtype: 'Button',
                 xns: Roo.bootstrap,
-                glyphicon : id,
+                //glyphicon : id,
+                fa: id,
                 cmd : id || cmd,
                 enableToggle:toggle !== false,
                 html : html || '',
@@ -23953,7 +24143,7 @@ Roo.extend(Roo.bootstrap.htmleditor.ToolbarStandard, Roo.bootstrap.NavSimplebar,
                 xtype: 'Button',
                 size : 'sm',
                 xns: Roo.bootstrap,
-                glyphicon : 'font',
+                fa : 'font',
                 //html : 'submit'
                 menu : {
                     xtype: 'Menu',
@@ -29138,6 +29328,7 @@ Roo.extend(Roo.bootstrap.DocumentManager, Roo.bootstrap.Component,  {
         this.progressDialog = new Roo.bootstrap.Modal({
             cls : 'roo-document-manager-progress-dialog',
             allow_close : false,
+            animate : false,
             title : '',
             buttons : [
                 {
@@ -30253,8 +30444,8 @@ Roo.extend(Roo.bootstrap.NavProgressItem, Roo.bootstrap.Component,  {
  * @cfg {String} cls class of the element
  * @cfg {String} target label target 
  * @cfg {Boolean} allowBlank (true|false) target allowBlank default true
- * @cfg {String} invalidClass default "text-warning"
- * @cfg {String} validClass default "text-success"
+ * @cfg {String} invalidClass DEPRICATED - BS4 uses is-invalid
+ * @cfg {String} validClass DEPRICATED - BS4 uses is-valid
  * @cfg {String} iconTooltip default "This field is required"
  * @cfg {String} indicatorpos (left|right) default left
  * 
@@ -30376,10 +30567,14 @@ Roo.extend(Roo.bootstrap.FieldLabel, Roo.bootstrap.Component,  {
             this.indicator.removeClass('visible');
             this.indicator.addClass('invisible');
         }
+        if (Roo.bootstrap.version == 3) {
+           this.el.removeClass(this.invalidClass);
+           this.el.addClass(this.validClass);
+       } else {
+           this.el.removeClass('is-invalid');
+            this.el.addClass('is-valid');
+       }
         
-        this.el.removeClass(this.invalidClass);
-        
-        this.el.addClass(this.validClass);
         
         this.fireEvent('valid', this);
     },
@@ -30394,10 +30589,14 @@ Roo.extend(Roo.bootstrap.FieldLabel, Roo.bootstrap.Component,  {
             this.indicator.removeClass('invisible');
             this.indicator.addClass('visible');
         }
+          if (Roo.bootstrap.version == 3) {
+           this.el.removeClass(this.validClass);
+           this.el.addClass(this.invalidClass);
+       } else {
+           this.el.removeClass('is-valid');
+            this.el.addClass('is-invalid');
+       }
         
-        this.el.removeClass(this.validClass);
-        
-        this.el.addClass(this.invalidClass);
         
         this.fireEvent('invalid', this, msg);
     }
@@ -33969,21 +34168,23 @@ Roo.extend(Roo.bootstrap.RadioSet, Roo.bootstrap.Input,  {
                 }
             ]
         };
-        
-        if(this.indicatorpos == 'left'){
-            label.cn.unshift({
-                tag : 'i',
-                cls : 'roo-required-indicator left-indicator text-danger fa fa-lg fa-star',
-                tooltip : 'This field is required'
-            });
-        } else {
-            label.cn.push({
-                tag : 'i',
-                cls : 'roo-required-indicator right-indicator text-danger fa fa-lg fa-star',
-                tooltip : 'This field is required'
-            });
+        if (Roo.bootstrap.version == 3) {
+            
+            
+            if(this.indicatorpos == 'left'){
+                label.cn.unshift({
+                    tag : 'i',
+                    cls : 'roo-required-indicator left-indicator text-danger fa fa-lg fa-star',
+                    tooltip : 'This field is required'
+                });
+            } else {
+                label.cn.push({
+                    tag : 'i',
+                    cls : 'roo-required-indicator right-indicator text-danger fa fa-lg fa-star',
+                    tooltip : 'This field is required'
+                });
+            }
         }
-        
         var items = {
             tag : 'div',
             cls : 'roo-radio-set-items'
@@ -34135,14 +34336,19 @@ Roo.extend(Roo.bootstrap.RadioSet, Roo.bootstrap.Input,  {
     
     markValid : function()
     {
-        if(this.labelEl.isVisible(true)){
+        if(this.labelEl.isVisible(true) && this.indicatorEl()){
             this.indicatorEl().removeClass('visible');
             this.indicatorEl().addClass('invisible');
         }
         
-        this.el.removeClass([this.invalidClass, this.validClass]);
-        this.el.addClass(this.validClass);
         
+        if (Roo.bootstrap.version == 3) {
+            this.el.removeClass([this.invalidClass, this.validClass]);
+            this.el.addClass(this.validClass);
+        } else {
+            this.el.removeClass(['is-invalid','is-valid']);
+            this.el.addClass(['is-valid']);
+        }
         this.fireEvent('valid', this);
     },
     
@@ -34152,13 +34358,17 @@ Roo.extend(Roo.bootstrap.RadioSet, Roo.bootstrap.Input,  {
             return;
         }
         
-        if(this.labelEl.isVisible(true)){
+        if(this.labelEl.isVisible(true) && this.indicatorEl()){
             this.indicatorEl().removeClass('invisible');
             this.indicatorEl().addClass('visible');
         }
-        
-        this.el.removeClass([this.invalidClass, this.validClass]);
-        this.el.addClass(this.invalidClass);
+        if (Roo.bootstrap.version == 3) {
+            this.el.removeClass([this.invalidClass, this.validClass]);
+            this.el.addClass(this.invalidClass);
+        } else {
+            this.el.removeClass(['is-invalid','is-valid']);
+            this.el.addClass(['is-invalid']);
+        }
         
         this.fireEvent('invalid', this, msg);
         
@@ -35174,7 +35384,7 @@ layout.addxtype({
             case 'Content':  // ContentPanel (el, cfg)
             case 'Scroll':  // ContentPanel (el, cfg)
             case 'View': 
-                cfg.autoCreate = true;
+                cfg.autoCreate = cfg.autoCreate || true;
                 ret = new cfg.xns[cfg.xtype](cfg); // new panel!!!!!
                 //} else {
                 //    var el = this.el.createChild();
@@ -37874,6 +38084,7 @@ Roo.bootstrap.panel.Tabs = function(config){
     }
     this.stripWrap = Roo.get(this.createStrip(this.el.dom), true);
     this.stripEl = Roo.get(this.createStripList(this.stripWrap.dom), true);
+    this.stripEl.setVisibilityMode(Roo.Element.DISPLAY);
     this.stripBody = Roo.get(this.stripWrap.dom.firstChild.firstChild, true);
     if(Roo.isIE){
         Roo.fly(this.stripWrap.dom.firstChild).setStyle("overflow-x", "hidden");
@@ -38033,9 +38244,11 @@ Roo.extend(Roo.bootstrap.panel.Tabs, Roo.util.Observable, {
      * Adds an existing {@link Roo.TabPanelItem}.
      * @param {Roo.TabPanelItem} item The TabPanelItem to add
      */
-    addTabItem : function(item){
+    addTabItem : function(item)
+    {
         this.items[item.id] = item;
         this.items.push(item);
+        this.autoSizeTabs();
       //  if(this.resizeTabs){
     //       item.setWidth(this.currentTabWidth || this.preferredTabWidth);
   //         this.autoSizeTabs();
@@ -38117,7 +38330,8 @@ Roo.extend(Roo.bootstrap.panel.Tabs, Roo.util.Observable, {
      * @param {String/Number} id The id or index of the TabPanelItem to activate.
      * @return {Roo.TabPanelItem} The TabPanelItem.
      */
-    activate : function(id){
+    activate : function(id)
+    {
         var tab = this.items[id];
         if(!tab){
             return null;
@@ -38183,12 +38397,22 @@ Roo.extend(Roo.bootstrap.panel.Tabs, Roo.util.Observable, {
     /**
      * Manual call to resize the tabs (if {@link #resizeTabs} is false this does nothing)
      */
-    autoSizeTabs : function(){
+    autoSizeTabs : function()
+    {
         var count = this.items.length;
         var vcount = count - this.hiddenCount;
+        
+        if (vcount < 2) {
+            this.stripEl.hide();
+        } else {
+            this.stripEl.show();
+        }
+        
         if(!this.resizeTabs || count < 1 || vcount < 1 || this.updating) {
             return;
         }
+        
+        
         var w = Math.max(this.el.getWidth() - this.cpad, 10);
         var availWidth = Math.floor(w / vcount);
         var b = this.stripBody;
@@ -38248,7 +38472,9 @@ Roo.extend(Roo.bootstrap.panel.Tabs, Roo.util.Observable, {
     createStrip : function(container)
     {
         var strip = document.createElement("nav");
-        strip.className = "navbar navbar-default"; //"x-tabs-wrap";
+        strip.className = Roo.bootstrap.version == 4 ?
+            "navbar-light bg-light" : 
+            "navbar navbar-default"; //"x-tabs-wrap";
         container.appendChild(strip);
         return strip;
     },
@@ -38287,7 +38513,7 @@ Roo.extend(Roo.bootstrap.panel.Tabs, Roo.util.Observable, {
     createStripElements :  function(stripEl, text, closable, tpl)
     {
         var td = document.createElement("li"); // was td..
-        
+        td.className = 'nav-item';
         
         //stripEl.insertBefore(td, stripEl.childNodes[stripEl.childNodes.length-1]);
         
@@ -38327,12 +38553,18 @@ Roo.extend(Roo.bootstrap.panel.Tabs, Roo.util.Observable, {
             var template = tpl || this.tabTpl || false;
             
             if(!template){
-                
-                template = new Roo.Template(
-                   '<a href="#">' +
-                   '<span unselectable="on"' +
-                            (this.disableTooltips ? '' : ' title="{text}"') +
-                            ' >{text}</span></a>'
+                template =  new Roo.Template(
+                        Roo.bootstrap.version == 4 ? 
+                            (
+                                '<a class="nav-link" href="#" unselectable="on"' +
+                                     (this.disableTooltips ? '' : ' title="{text}"') +
+                                     ' >{text}</a>'
+                            ) : (
+                                '<a class="nav-link" href="#">' +
+                                '<span unselectable="on"' +
+                                         (this.disableTooltips ? '' : ' title="{text}"') +
+                                    ' >{text}</span></a>'
+                            )
                 );
             }
             
@@ -38399,8 +38631,13 @@ Roo.bootstrap.panel.TabItem = function(config){
     /** @private */
     this.el = Roo.get(els.el);
     this.inner = Roo.get(els.inner, true);
-    this.textEl = Roo.get(this.el.dom.firstChild, true);
-    this.pnode = Roo.get(els.el.parentNode, true);
+     this.textEl = Roo.bootstrap.version == 4 ?
+        this.el : Roo.get(this.el.dom.firstChild, true);
+
+    this.pnode = this.linode = Roo.get(els.el.parentNode, true);
+    this.status_node = Roo.bootstrap.version == 4 ? this.el : this.linode;
+
+    
 //    this.el.on("mousedown", this.onTabMouseDown, this);
     this.el.on("click", this.onTabClick, this);
     /** @private */
@@ -38455,7 +38692,7 @@ Roo.extend(Roo.bootstrap.panel.TabItem, Roo.util.Observable,
      * Shows this TabPanelItem -- this <b>does not</b> deactivate the currently active TabPanelItem.
      */
     show : function(){
-        this.pnode.addClass("active");
+        this.status_node.addClass("active");
         this.showAction();
         if(Roo.isOpera){
             this.tabPanel.stripWrap.repaint();
@@ -38475,7 +38712,7 @@ Roo.extend(Roo.bootstrap.panel.TabItem, Roo.util.Observable,
      * Hides this TabPanelItem -- if you don't activate another TabPanelItem this could look odd.
      */
     hide : function(){
-        this.pnode.removeClass("active");
+        this.status_node.removeClass("active");
         this.hideAction();
         this.fireEvent("deactivate", this.tabPanel, this);
     },
@@ -38522,10 +38759,10 @@ Roo.extend(Roo.bootstrap.panel.TabItem, Roo.util.Observable,
     },
 
     setWidth : function(width){
-        var iwidth = width - this.pnode.getPadding("lr");
+        var iwidth = width - this.linode.getPadding("lr");
         this.inner.setWidth(iwidth);
         this.textEl.setWidth(iwidth-this.inner.getPadding("lr"));
-        this.pnode.setWidth(width);
+        this.linode.setWidth(width);
     },
 */
     /**
@@ -38534,7 +38771,7 @@ Roo.extend(Roo.bootstrap.panel.TabItem, Roo.util.Observable,
      */
     setHidden : function(hidden){
         this.hidden = hidden;
-        this.pnode.setStyle("display", hidden ? "none" : "");
+        this.linode.setStyle("display", hidden ? "none" : "");
     },
 
     /**
@@ -38560,7 +38797,7 @@ Roo.extend(Roo.bootstrap.panel.TabItem, Roo.util.Observable,
          *  #2804 [new] Tabs in Roojs
          *  increase the width by 2-4 pixels to prevent the ellipssis showing in chrome
          */
-        //this.setWidth(this.textEl.dom.scrollWidth+this.pnode.getPadding("lr")+this.inner.getPadding("lr") + 2);
+        //this.setWidth(this.textEl.dom.scrollWidth+this.linode.getPadding("lr")+this.inner.getPadding("lr") + 2);
         //this.el.endMeasure();
     //},
 
@@ -38589,7 +38826,7 @@ Roo.extend(Roo.bootstrap.panel.TabItem, Roo.util.Observable,
     disable : function(){
         if(this.tabPanel.active != this){
             this.disabled = true;
-            this.pnode.addClass("disabled");
+            this.status_node.addClass("disabled");
         }
     },
 
@@ -38598,7 +38835,7 @@ Roo.extend(Roo.bootstrap.panel.TabItem, Roo.util.Observable,
      */
     enable : function(){
         this.disabled = false;
-        this.pnode.removeClass("disabled");
+        this.status_node.removeClass("disabled");
     },
 
     /**