@oat-sa/tao-core-ui 1.60.2 → 1.61.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +339 -339
- package/README.md +23 -18
- package/dist/actionbar.js +105 -105
- package/dist/adder.js +109 -109
- package/dist/animable/absorbable/absorbable.js +42 -42
- package/dist/animable/absorbable/css/absorb.css +7 -7
- package/dist/animable/absorbable/css/absorb.css.map +1 -1
- package/dist/animable/pulsable/css/pulse.css +7 -7
- package/dist/animable/pulsable/css/pulse.css.map +1 -1
- package/dist/animable/pulsable/pulsable.js +36 -36
- package/dist/areaBroker.js +51 -51
- package/dist/autocomplete/css/autocomplete.css +7 -7
- package/dist/autocomplete/css/autocomplete.css.map +1 -1
- package/dist/autocomplete.js +400 -400
- package/dist/autoscroll.js +22 -22
- package/dist/badge/badge.js +48 -48
- package/dist/badge/css/badge.css +7 -7
- package/dist/badge/css/badge.css.map +1 -1
- package/dist/breadcrumbs/css/breadcrumbs.css +7 -7
- package/dist/breadcrumbs/css/breadcrumbs.css.map +1 -1
- package/dist/breadcrumbs.js +70 -70
- package/dist/btngrouper.js +64 -64
- package/dist/bulkActionPopup/css/bulkActionPopup.css +7 -7
- package/dist/bulkActionPopup/css/bulkActionPopup.css.map +1 -1
- package/dist/bulkActionPopup.js +104 -104
- package/dist/button.js +102 -102
- package/dist/calculator/css/calculator.css +10 -10
- package/dist/calculator/css/calculator.css.map +1 -1
- package/dist/calculator.js +51 -51
- package/dist/cascadingComboBox.js +47 -47
- package/dist/ckeditor/ckConfigurator.js +48 -48
- package/dist/ckeditor/dtdHandler.js +110 -110
- package/dist/class/css/selector.css +7 -7
- package/dist/class/css/selector.css.map +1 -1
- package/dist/class/selector.js +111 -111
- package/dist/component/alignable.js +81 -81
- package/dist/component/containable.js +37 -37
- package/dist/component/css/components.css +7 -7
- package/dist/component/css/components.css.map +1 -1
- package/dist/component/css/windowComponent.css +7 -7
- package/dist/component/css/windowComponent.css.map +1 -1
- package/dist/component/draggable.js +25 -25
- package/dist/component/placeable.js +70 -70
- package/dist/component/resizable.js +61 -61
- package/dist/component/stackable.js +20 -20
- package/dist/component/windowed.js +59 -59
- package/dist/component.js +153 -153
- package/dist/container.js +76 -76
- package/dist/contextualPopup/css/contextualPopup.css +7 -7
- package/dist/contextualPopup/css/contextualPopup.css.map +1 -1
- package/dist/contextualPopup.js +113 -113
- package/dist/dashboard/css/dashboard.css +7 -7
- package/dist/dashboard/css/dashboard.css.map +1 -1
- package/dist/dashboard.js +75 -75
- package/dist/datalist/css/datalist.css +7 -7
- package/dist/datalist/css/datalist.css.map +1 -1
- package/dist/datalist.js +160 -160
- package/dist/datatable/css/datatable.css +11 -7
- package/dist/datatable/css/datatable.css.map +1 -1
- package/dist/datatable/filterStrategy/filterStrategy.js +27 -27
- package/dist/datatable/filterStrategy/multiple.js +25 -25
- package/dist/datatable/filterStrategy/single.js +25 -25
- package/dist/datatable.js +464 -431
- package/dist/dateRange/css/dateRange.css +7 -7
- package/dist/dateRange/css/dateRange.css.map +1 -1
- package/dist/dateRange/dateRange.js +110 -110
- package/dist/datetime/css/picker.css +7 -7
- package/dist/datetime/css/picker.css.map +1 -1
- package/dist/datetime/picker.js +174 -174
- package/dist/deleter.js +92 -92
- package/dist/destination/css/selector.css +7 -7
- package/dist/destination/css/selector.css.map +1 -1
- package/dist/destination/selector.js +65 -65
- package/dist/dialog/alert.js +26 -26
- package/dist/dialog/confirm.js +27 -27
- package/dist/dialog/confirmDelete.js +44 -44
- package/dist/dialog.js +156 -156
- package/dist/disabler.js +90 -90
- package/dist/documentViewer/css/documentViewer.css +7 -7
- package/dist/documentViewer/css/documentViewer.css.map +1 -1
- package/dist/documentViewer/providers/pdfViewer/fallback/viewer.js +43 -43
- package/dist/documentViewer/providers/pdfViewer/pdfjs/areaBroker.js +25 -25
- package/dist/documentViewer/providers/pdfViewer/pdfjs/findBar.js +133 -133
- package/dist/documentViewer/providers/pdfViewer/pdfjs/pageView.js +102 -102
- package/dist/documentViewer/providers/pdfViewer/pdfjs/pagesManager.js +52 -52
- package/dist/documentViewer/providers/pdfViewer/pdfjs/searchEngine.js +125 -125
- package/dist/documentViewer/providers/pdfViewer/pdfjs/textManager.js +67 -67
- package/dist/documentViewer/providers/pdfViewer/pdfjs/viewer.js +94 -94
- package/dist/documentViewer/providers/pdfViewer/pdfjs/wrapper.js +111 -111
- package/dist/documentViewer/providers/pdfViewer.js +42 -42
- package/dist/documentViewer/viewerFactory.js +71 -71
- package/dist/documentViewer.js +99 -99
- package/dist/dropdown/css/dropdown.css +7 -7
- package/dist/dropdown/css/dropdown.css.map +1 -1
- package/dist/dropdown.js +97 -97
- package/dist/durationer.js +58 -58
- package/dist/dynamicComponent/css/dynamicComponent.css +7 -7
- package/dist/dynamicComponent/css/dynamicComponent.css.map +1 -1
- package/dist/dynamicComponent.js +116 -116
- package/dist/feedback.js +97 -97
- package/dist/figure/FigureStateActive.js +117 -117
- package/dist/filesender.js +26 -26
- package/dist/filter.js +47 -47
- package/dist/form/css/dropdownForm.css +7 -7
- package/dist/form/css/dropdownForm.css.map +1 -1
- package/dist/form/css/form.css +7 -7
- package/dist/form/css/form.css.map +1 -1
- package/dist/form/dropdownForm.js +112 -112
- package/dist/form/form.js +245 -245
- package/dist/form/simpleForm.js +71 -71
- package/dist/form/validator/css/validator.css +7 -7
- package/dist/form/validator/css/validator.css.map +1 -1
- package/dist/form/validator/renderer.js +65 -65
- package/dist/form/validator/validator.js +87 -87
- package/dist/form/widget/css/widget.css +7 -7
- package/dist/form/widget/css/widget.css.map +1 -1
- package/dist/form/widget/definitions.js +24 -24
- package/dist/form/widget/loader.js +16 -16
- package/dist/form/widget/providers/checkBox.js +75 -75
- package/dist/form/widget/providers/comboBox.js +59 -59
- package/dist/form/widget/providers/default.js +35 -35
- package/dist/form/widget/providers/hidden.js +50 -50
- package/dist/form/widget/providers/hiddenBox.js +71 -71
- package/dist/form/widget/providers/radioBox.js +70 -70
- package/dist/form/widget/providers/textArea.js +48 -48
- package/dist/form/widget/providers/textBox.js +34 -34
- package/dist/form/widget/widget.js +154 -154
- package/dist/form.js +10 -10
- package/dist/formValidator/formValidator.js +61 -61
- package/dist/formValidator/highlighters/highlighter.js +41 -41
- package/dist/formValidator/highlighters/message.js +29 -29
- package/dist/formValidator/highlighters/tooltip.js +32 -32
- package/dist/generis/form/css/form.css +7 -7
- package/dist/generis/form/css/form.css.map +1 -1
- package/dist/generis/form/form.js +86 -86
- package/dist/generis/validator/css/validator.css +7 -7
- package/dist/generis/validator/css/validator.css.map +1 -1
- package/dist/generis/validator/validator.js +51 -51
- package/dist/generis/widget/checkBox/checkBox.js +52 -52
- package/dist/generis/widget/comboBox/comboBox.js +45 -45
- package/dist/generis/widget/css/widget.css +7 -7
- package/dist/generis/widget/css/widget.css.map +1 -1
- package/dist/generis/widget/hiddenBox/hiddenBox.js +53 -53
- package/dist/generis/widget/loader.js +20 -20
- package/dist/generis/widget/textBox/textBox.js +40 -40
- package/dist/generis/widget/widget.js +60 -60
- package/dist/groupedComboBox.js +49 -49
- package/dist/groupvalidator.js +19 -19
- package/dist/hider.js +41 -41
- package/dist/highlighter.js +262 -262
- package/dist/image/ImgStateActive/extractLabel.js +20 -20
- package/dist/image/ImgStateActive/helper.js +16 -16
- package/dist/image/ImgStateActive/initHelper.js +85 -85
- package/dist/image/ImgStateActive/initMediaEditor.js +48 -48
- package/dist/image/ImgStateActive/mediaSizer.js +32 -32
- package/dist/image/ImgStateActive.js +104 -104
- package/dist/incrementer.js +58 -58
- package/dist/inplacer.js +87 -87
- package/dist/interactUtils.js +42 -42
- package/dist/itemButtonList/css/item-button-list.css +23 -23
- package/dist/itemButtonList/css/item-button-list.css.map +1 -1
- package/dist/itemButtonList.js +115 -115
- package/dist/keyNavigation/navigableDomElement.js +76 -76
- package/dist/keyNavigation/navigator.js +158 -158
- package/dist/listbox/css/listbox.css +7 -7
- package/dist/listbox/css/listbox.css.map +1 -1
- package/dist/listbox.js +97 -97
- package/dist/liststyler.js +57 -57
- package/dist/loadingButton/css/button.css +7 -7
- package/dist/loadingButton/css/button.css.map +1 -1
- package/dist/loadingButton/loadingButton.js +48 -48
- package/dist/lock.js +125 -125
- package/dist/login/login.js +100 -100
- package/dist/maths/calculator/basicCalculator.js +63 -63
- package/dist/maths/calculator/calculatorComponent.js +29 -29
- package/dist/maths/calculator/core/areaBroker.js +25 -25
- package/dist/maths/calculator/core/board.js +313 -313
- package/dist/maths/calculator/core/expression.js +111 -111
- package/dist/maths/calculator/core/labels.js +29 -29
- package/dist/maths/calculator/core/plugin.js +19 -19
- package/dist/maths/calculator/core/terms.js +26 -26
- package/dist/maths/calculator/core/tokenizer.js +98 -98
- package/dist/maths/calculator/core/tokens.js +59 -59
- package/dist/maths/calculator/css/calculator.css +7 -7
- package/dist/maths/calculator/css/calculator.css.map +1 -1
- package/dist/maths/calculator/defaultCalculator.js +23 -23
- package/dist/maths/calculator/plugins/core/degrad.js +22 -22
- package/dist/maths/calculator/plugins/core/history.js +45 -45
- package/dist/maths/calculator/plugins/core/remind.js +22 -22
- package/dist/maths/calculator/plugins/core/stepNavigation.js +31 -31
- package/dist/maths/calculator/plugins/keyboard/templateKeyboard/templateKeyboard.js +61 -61
- package/dist/maths/calculator/plugins/modifiers/pow10.js +35 -35
- package/dist/maths/calculator/plugins/modifiers/sign.js +90 -90
- package/dist/maths/calculator/plugins/screen/simpleScreen/simpleScreen.js +60 -60
- package/dist/maths/calculator/pluginsLoader.js +21 -21
- package/dist/maths/calculator/scientificCalculator.js +91 -91
- package/dist/mediaEditor/mediaEditorComponent.js +64 -64
- package/dist/mediaEditor/plugins/mediaAlignment/helper.js +16 -16
- package/dist/mediaEditor/plugins/mediaAlignment/mediaAlignmentComponent.js +60 -60
- package/dist/mediaEditor/plugins/mediaAlignment/style.css +7 -7
- package/dist/mediaEditor/plugins/mediaDimension/helper.js +70 -70
- package/dist/mediaEditor/plugins/mediaDimension/mediaDimensionComponent.js +153 -153
- package/dist/mediaEditor/plugins/mediaDimension/style.css +141 -141
- package/dist/mediaplayer/css/player.css +7 -7
- package/dist/mediaplayer/css/player.css.map +1 -1
- package/dist/mediaplayer/players/html5.js +65 -65
- package/dist/mediaplayer/players/youtube.js +52 -52
- package/dist/mediaplayer/players.js +18 -18
- package/dist/mediaplayer/support.js +55 -55
- package/dist/mediaplayer/utils/reminder.js +100 -100
- package/dist/mediaplayer/utils/timeObserver.js +92 -92
- package/dist/mediaplayer/youtubeManager.js +35 -35
- package/dist/mediaplayer.js +460 -460
- package/dist/mediasizer.js +135 -135
- package/dist/modal.js +87 -87
- package/dist/movableComponent.js +35 -35
- package/dist/pageSizeSelector.js +44 -44
- package/dist/pageStatus.js +33 -33
- package/dist/pagination/css/pagination.css +7 -7
- package/dist/pagination/css/pagination.css.map +1 -1
- package/dist/pagination/paginationStrategy.js +23 -23
- package/dist/pagination/providers/pages.js +37 -37
- package/dist/pagination/providers/simple.js +35 -35
- package/dist/pagination.js +45 -45
- package/dist/previewer.js +67 -67
- package/dist/progressbar.js +58 -58
- package/dist/propertySelector/css/propertySelector.css +74 -0
- package/dist/propertySelector/css/propertySelector.css.map +1 -0
- package/dist/propertySelector/propertySelector.js +533 -0
- package/dist/report.js +86 -86
- package/dist/resource/css/selector.css +7 -7
- package/dist/resource/css/selector.css.map +1 -1
- package/dist/resource/filters.js +73 -73
- package/dist/resource/list.js +66 -66
- package/dist/resource/selectable.js +92 -92
- package/dist/resource/selector.js +195 -195
- package/dist/resource/tree.js +104 -104
- package/dist/resourcemgr/css/resourcemgr.css +7 -7
- package/dist/resourcemgr/css/resourcemgr.css.map +1 -1
- package/dist/resourcemgr/fileBrowser.js +88 -88
- package/dist/resourcemgr/fileSelector.js +58 -58
- package/dist/resourcemgr/util/updatePermissions.js +4 -4
- package/dist/resourcemgr.js +62 -62
- package/dist/scroller.js +26 -26
- package/dist/searchModal/advancedSearch.js +355 -161
- package/dist/searchModal/css/advancedSearch.css +7 -14
- package/dist/searchModal/css/advancedSearch.css.map +1 -1
- package/dist/searchModal/css/searchModal.css +29 -8
- package/dist/searchModal/css/searchModal.css.map +1 -1
- package/dist/searchModal.js +574 -190
- package/dist/selecter.js +6 -6
- package/dist/stacker.js +43 -43
- package/dist/switch/css/switch.css +7 -7
- package/dist/switch/css/switch.css.map +1 -1
- package/dist/switch/switch.js +75 -75
- package/dist/tableModel.js +33 -33
- package/dist/tabs/css/tabs.css +12 -12
- package/dist/tabs/css/tabs.css.map +1 -1
- package/dist/tabs.js +217 -217
- package/dist/taskQueue/css/taskQueue.css +7 -7
- package/dist/taskQueue/css/taskQueue.css.map +1 -1
- package/dist/taskQueue/status.js +72 -72
- package/dist/taskQueue/table.js +67 -67
- package/dist/taskQueue/taskQueue.js +18 -18
- package/dist/taskQueue/taskQueueModel.js +86 -86
- package/dist/taskQueue.js +47 -47
- package/dist/taskQueueButton/css/taskable.css +7 -7
- package/dist/taskQueueButton/css/taskable.css.map +1 -1
- package/dist/taskQueueButton/css/treeButton.css +7 -7
- package/dist/taskQueueButton/css/treeButton.css.map +1 -1
- package/dist/taskQueueButton/standardButton.js +39 -39
- package/dist/taskQueueButton/taskable.js +54 -54
- package/dist/taskQueueButton/treeButton.js +56 -56
- package/dist/themeLoader.js +75 -75
- package/dist/themes.js +84 -84
- package/dist/toggler.js +57 -57
- package/dist/tooltip.js +54 -54
- package/dist/tooltipster.js +17 -17
- package/dist/transformer.js +117 -117
- package/dist/tristateCheckboxGroup/css/tristateCheckboxGroup.css +7 -7
- package/dist/tristateCheckboxGroup/css/tristateCheckboxGroup.css.map +1 -1
- package/dist/tristateCheckboxGroup.js +75 -75
- package/dist/uploader.js +158 -158
- package/dist/validator/validators.js +48 -48
- package/dist/validator.js +24 -24
- package/dist/waitForMedia.js +33 -33
- package/dist/waitingDialog/css/waitingDialog.css +7 -7
- package/dist/waitingDialog/css/waitingDialog.css.map +1 -1
- package/dist/waitingDialog/waitingDialog.js +54 -54
- package/package.json +108 -107
- package/scss/basic.scss +16 -16
- package/scss/ckeditor/skins/tao/scss/inc/_ck-icons.scss +59 -59
- package/scss/ckeditor/skins/tao/scss/inc/_tao.scss +59 -59
- package/scss/font/tao/tao.svg +234 -234
- package/scss/inc/_base.scss +495 -495
- package/scss/inc/_bootstrap.scss +6 -6
- package/scss/inc/_buttons.scss +114 -114
- package/scss/inc/_colors.scss +93 -88
- package/scss/inc/_feedback.scss +150 -150
- package/scss/inc/_flex-grid.scss +15 -15
- package/scss/inc/_fonts.scss +4 -4
- package/scss/inc/_forms.scss +832 -832
- package/scss/inc/_functions.scss +283 -283
- package/scss/inc/_jquery.nouislider.scss +254 -254
- package/scss/inc/_normalize.scss +528 -528
- package/scss/inc/_report.scss +67 -67
- package/scss/inc/_secondary-properties.scss +89 -89
- package/scss/inc/_select2.scss +634 -634
- package/scss/inc/_toolbars.scss +155 -155
- package/scss/inc/_tooltip.scss +312 -312
- package/scss/inc/_variables.scss +21 -21
- package/scss/inc/base/_highlight.scss +5 -5
- package/scss/inc/base/_list-style.scss +58 -58
- package/scss/inc/base/_svg.scss +3 -3
- package/scss/inc/base/_table.scss +62 -62
- package/scss/inc/fonts/_source-sans-pro.scss +29 -29
- package/scss/inc/fonts/_tao-icon-classes.scss +226 -226
- package/scss/inc/fonts/_tao-icon-def.scss +12 -12
- package/scss/inc/fonts/_tao-icon-vars.scss +240 -240
- package/src/actionbar/tpl/main.tpl +8 -8
- package/src/actionbar.js +251 -251
- package/src/adder.js +250 -250
- package/src/animable/absorbable/absorbable.js +134 -134
- package/src/animable/absorbable/css/absorb.css +7 -7
- package/src/animable/absorbable/css/absorb.css.map +1 -1
- package/src/animable/absorbable/scss/absorb.scss +37 -37
- package/src/animable/pulsable/css/pulse.css +7 -7
- package/src/animable/pulsable/css/pulse.css.map +1 -1
- package/src/animable/pulsable/pulsable.js +90 -90
- package/src/animable/pulsable/scss/pulse.scss +22 -22
- package/src/areaBroker.js +160 -160
- package/src/autocomplete/css/autocomplete.css +7 -7
- package/src/autocomplete/css/autocomplete.css.map +1 -1
- package/src/autocomplete/scss/autocomplete.scss +37 -37
- package/src/autocomplete.js +1029 -1029
- package/src/autoscroll.js +57 -57
- package/src/badge/badge.js +119 -119
- package/src/badge/css/badge.css +7 -7
- package/src/badge/css/badge.css.map +1 -1
- package/src/badge/scss/badge.scss +92 -92
- package/src/badge/tpl/badge.tpl +4 -4
- package/src/breadcrumbs/css/breadcrumbs.css +7 -7
- package/src/breadcrumbs/css/breadcrumbs.css.map +1 -1
- package/src/breadcrumbs/scss/breadcrumbs.scss +52 -52
- package/src/breadcrumbs/tpl/breadcrumbs.tpl +20 -20
- package/src/breadcrumbs.js +99 -99
- package/src/btngrouper.js +213 -213
- package/src/bulkActionPopup/css/bulkActionPopup.css +7 -7
- package/src/bulkActionPopup/css/bulkActionPopup.css.map +1 -1
- package/src/bulkActionPopup/scss/bulkActionPopup.scss +63 -63
- package/src/bulkActionPopup/tpl/layout.tpl +76 -76
- package/src/bulkActionPopup/tpl/select.tpl +8 -8
- package/src/bulkActionPopup.js +274 -274
- package/src/button/tpl/button.tpl +4 -4
- package/src/button.js +135 -135
- package/src/calculator/css/calculator.css +10 -10
- package/src/calculator/css/calculator.css.map +1 -1
- package/src/calculator/scss/calculator.scss +139 -139
- package/src/calculator.js +188 -188
- package/src/cascadingComboBox.js +126 -126
- package/src/ckeditor/ckConfigurator.js +736 -736
- package/src/ckeditor/dtdHandler.js +1030 -1030
- package/src/class/css/selector.css +7 -7
- package/src/class/css/selector.css.map +1 -1
- package/src/class/scss/selector.scss +101 -101
- package/src/class/selector.js +329 -329
- package/src/class/tpl/listItem.tpl +9 -9
- package/src/class/tpl/selector.tpl +10 -10
- package/src/component/alignable.js +274 -274
- package/src/component/containable.js +122 -122
- package/src/component/css/components.css +7 -7
- package/src/component/css/components.css.map +1 -1
- package/src/component/css/windowComponent.css +7 -7
- package/src/component/css/windowComponent.css.map +1 -1
- package/src/component/draggable.js +104 -104
- package/src/component/placeable.js +233 -233
- package/src/component/resizable.js +195 -195
- package/src/component/scss/components.scss +507 -507
- package/src/component/scss/windowComponent.scss +62 -62
- package/src/component/stackable.js +67 -67
- package/src/component/tpl/window.tpl +7 -7
- package/src/component/windowed.js +206 -206
- package/src/component.js +401 -401
- package/src/container.js +200 -200
- package/src/contextualPopup/css/contextualPopup.css +7 -7
- package/src/contextualPopup/css/contextualPopup.css.map +1 -1
- package/src/contextualPopup/scss/contextualPopup.scss +78 -78
- package/src/contextualPopup/tpl/popup.tpl +10 -10
- package/src/contextualPopup.js +297 -297
- package/src/css/basic.css +103 -103
- package/src/css/basic.css.map +1 -1
- package/src/dashboard/css/dashboard.css +7 -7
- package/src/dashboard/css/dashboard.css.map +1 -1
- package/src/dashboard/scss/dashboard.scss +93 -93
- package/src/dashboard/tpl/dashboard.tpl +16 -16
- package/src/dashboard/tpl/dashboardMetricsList.tpl +15 -15
- package/src/dashboard.js +184 -184
- package/src/datalist/css/datalist.css +7 -7
- package/src/datalist/css/datalist.css.map +1 -1
- package/src/datalist/scss/datalist.scss +116 -116
- package/src/datalist/tpl/list.tpl +24 -24
- package/src/datalist/tpl/main.tpl +44 -44
- package/src/datalist.js +500 -500
- package/src/datatable/css/datatable.css +11 -7
- package/src/datatable/css/datatable.css.map +1 -1
- package/src/datatable/filterStrategy/filterStrategy.js +70 -70
- package/src/datatable/filterStrategy/multiple.js +126 -126
- package/src/datatable/filterStrategy/single.js +108 -108
- package/src/datatable/scss/datatable.scss +149 -146
- package/src/datatable/tpl/button.tpl +6 -6
- package/src/datatable/tpl/layout.tpl +158 -158
- package/src/datatable.js +1056 -1056
- package/src/dateRange/css/dateRange.css +7 -7
- package/src/dateRange/css/dateRange.css.map +1 -1
- package/src/dateRange/dateRange.js +341 -341
- package/src/dateRange/scss/dateRange.scss +7 -7
- package/src/dateRange/tpl/select.tpl +18 -18
- package/src/datetime/css/picker.css +7 -7
- package/src/datetime/css/picker.css.map +1 -1
- package/src/datetime/picker.js +576 -576
- package/src/datetime/scss/picker.scss +192 -192
- package/src/datetime/tpl/picker.tpl +18 -18
- package/src/deleter/undo.tpl +6 -6
- package/src/deleter.js +296 -296
- package/src/destination/css/selector.css +7 -7
- package/src/destination/css/selector.css.map +1 -1
- package/src/destination/scss/selector.scss +36 -36
- package/src/destination/selector.js +195 -195
- package/src/destination/tpl/selector.tpl +13 -13
- package/src/dialog/alert.js +70 -70
- package/src/dialog/confirm.js +85 -85
- package/src/dialog/confirmDelete.js +95 -95
- package/src/dialog/tpl/body.tpl +24 -24
- package/src/dialog/tpl/buttons.tpl +6 -6
- package/src/dialog/tpl/checkbox.tpl +5 -5
- package/src/dialog.js +517 -517
- package/src/disabler.js +230 -230
- package/src/documentViewer/css/documentViewer.css +7 -7
- package/src/documentViewer/css/documentViewer.css.map +1 -1
- package/src/documentViewer/providers/pdfViewer/fallback/viewer.js +69 -69
- package/src/documentViewer/providers/pdfViewer/pdfjs/areaBroker.js +41 -41
- package/src/documentViewer/providers/pdfViewer/pdfjs/findBar.js +475 -475
- package/src/documentViewer/providers/pdfViewer/pdfjs/findBar.tpl +20 -20
- package/src/documentViewer/providers/pdfViewer/pdfjs/match.tpl +1 -1
- package/src/documentViewer/providers/pdfViewer/pdfjs/page.tpl +4 -4
- package/src/documentViewer/providers/pdfViewer/pdfjs/pageView.js +318 -318
- package/src/documentViewer/providers/pdfViewer/pdfjs/pagesManager.js +167 -167
- package/src/documentViewer/providers/pdfViewer/pdfjs/searchEngine.js +451 -451
- package/src/documentViewer/providers/pdfViewer/pdfjs/textManager.js +252 -252
- package/src/documentViewer/providers/pdfViewer/pdfjs/viewer.js +299 -299
- package/src/documentViewer/providers/pdfViewer/pdfjs/viewer.tpl +16 -16
- package/src/documentViewer/providers/pdfViewer/pdfjs/wrapper.js +351 -351
- package/src/documentViewer/providers/pdfViewer.js +93 -93
- package/src/documentViewer/scss/documentViewer.scss +184 -184
- package/src/documentViewer/viewerFactory.js +191 -191
- package/src/documentViewer.js +238 -238
- package/src/dropdown/css/dropdown.css +7 -7
- package/src/dropdown/css/dropdown.css.map +1 -1
- package/src/dropdown/scss/dropdown.scss +99 -99
- package/src/dropdown/tpl/dropdown.tpl +8 -8
- package/src/dropdown/tpl/list-item.tpl +4 -4
- package/src/dropdown.js +255 -255
- package/src/durationer.js +222 -222
- package/src/dynamicComponent/css/dynamicComponent.css +7 -7
- package/src/dynamicComponent/css/dynamicComponent.css.map +1 -1
- package/src/dynamicComponent/scss/dynamicComponent.scss +98 -98
- package/src/dynamicComponent/tpl/layout.tpl +17 -17
- package/src/dynamicComponent.js +554 -554
- package/src/feedback/feedback.tpl +7 -7
- package/src/feedback.js +295 -295
- package/src/figure/FigureStateActive.js +174 -174
- package/src/filesender.js +114 -114
- package/src/filter/template.tpl +5 -5
- package/src/filter.js +135 -135
- package/src/form/css/dropdownForm.css +7 -7
- package/src/form/css/dropdownForm.css.map +1 -1
- package/src/form/css/form.css +7 -7
- package/src/form/css/form.css.map +1 -1
- package/src/form/dropdownForm.js +281 -281
- package/src/form/form.js +688 -688
- package/src/form/scss/dropdownForm.scss +60 -60
- package/src/form/scss/form.scss +25 -25
- package/src/form/simpleForm.js +125 -125
- package/src/form/tpl/dropdownForm.tpl +4 -4
- package/src/form/tpl/form.tpl +7 -7
- package/src/form/validator/css/validator.css +7 -7
- package/src/form/validator/css/validator.css.map +1 -1
- package/src/form/validator/renderer.js +118 -118
- package/src/form/validator/scss/validator.scss +14 -14
- package/src/form/validator/tpl/message.tpl +1 -1
- package/src/form/validator/tpl/validator.tpl +1 -1
- package/src/form/validator/validator.js +220 -220
- package/src/form/widget/css/widget.css +7 -7
- package/src/form/widget/css/widget.css.map +1 -1
- package/src/form/widget/definitions.js +51 -51
- package/src/form/widget/loader.js +40 -40
- package/src/form/widget/providers/checkBox.js +138 -138
- package/src/form/widget/providers/comboBox.js +63 -63
- package/src/form/widget/providers/default.js +90 -90
- package/src/form/widget/providers/hidden.js +62 -62
- package/src/form/widget/providers/hiddenBox.js +152 -152
- package/src/form/widget/providers/radioBox.js +99 -99
- package/src/form/widget/providers/textArea.js +52 -52
- package/src/form/widget/providers/textBox.js +48 -48
- package/src/form/widget/scss/widget.scss +55 -55
- package/src/form/widget/tpl/checkBox.tpl +25 -25
- package/src/form/widget/tpl/comboBox.tpl +13 -13
- package/src/form/widget/tpl/hidden.tpl +1 -1
- package/src/form/widget/tpl/hiddenBox.tpl +17 -17
- package/src/form/widget/tpl/label.tpl +6 -6
- package/src/form/widget/tpl/radioBox.tpl +25 -25
- package/src/form/widget/tpl/textArea.tpl +8 -8
- package/src/form/widget/tpl/widget.tpl +8 -8
- package/src/form/widget/widget.js +372 -372
- package/src/form.js +53 -53
- package/src/formValidator/formValidator.js +253 -253
- package/src/formValidator/highlighters/highlighter.js +102 -102
- package/src/formValidator/highlighters/message.js +70 -70
- package/src/formValidator/highlighters/tooltip.js +78 -78
- package/src/generis/form/css/form.css +7 -7
- package/src/generis/form/css/form.css.map +1 -1
- package/src/generis/form/form.js +239 -239
- package/src/generis/form/readme.md +70 -70
- package/src/generis/form/scss/form.scss +23 -23
- package/src/generis/form/tpl/form.tpl +16 -16
- package/src/generis/validator/css/validator.css +7 -7
- package/src/generis/validator/css/validator.css.map +1 -1
- package/src/generis/validator/readme.md +46 -46
- package/src/generis/validator/scss/validator.scss +13 -13
- package/src/generis/validator/validator.js +128 -128
- package/src/generis/widget/checkBox/checkBox.js +112 -112
- package/src/generis/widget/checkBox/checkBox.tpl +18 -18
- package/src/generis/widget/comboBox/comboBox.js +67 -67
- package/src/generis/widget/comboBox/comboBox.tpl +12 -12
- package/src/generis/widget/css/widget.css +7 -7
- package/src/generis/widget/css/widget.css.map +1 -1
- package/src/generis/widget/hiddenBox/hiddenBox.js +132 -132
- package/src/generis/widget/hiddenBox/hiddenBox.tpl +16 -16
- package/src/generis/widget/loader.js +49 -49
- package/src/generis/widget/readme.md +59 -59
- package/src/generis/widget/scss/widget.scss +61 -61
- package/src/generis/widget/textBox/textBox.js +65 -65
- package/src/generis/widget/textBox/textBox.tpl +7 -7
- package/src/generis/widget/widget.js +164 -164
- package/src/generis/widget/widget.tpl +5 -5
- package/src/groupedComboBox.js +99 -99
- package/src/groupvalidator.js +84 -84
- package/src/hider.js +88 -88
- package/src/highlighter.js +1166 -1166
- package/src/image/ImgStateActive/extractLabel.js +29 -29
- package/src/image/ImgStateActive/helper.js +36 -36
- package/src/image/ImgStateActive/initHelper.js +137 -137
- package/src/image/ImgStateActive/initMediaEditor.js +92 -92
- package/src/image/ImgStateActive/mediaSizer.js +63 -63
- package/src/image/ImgStateActive.js +115 -115
- package/src/incrementer.js +319 -319
- package/src/inplacer.js +316 -316
- package/src/interactUtils.js +140 -140
- package/src/itemButtonList/css/item-button-list.css +23 -23
- package/src/itemButtonList/css/item-button-list.css.map +1 -1
- package/src/itemButtonList/scss/item-button-list.scss +236 -236
- package/src/itemButtonList/tpl/itemButtonList.tpl +21 -21
- package/src/itemButtonList.js +274 -274
- package/src/keyNavigation/navigableDomElement.js +282 -282
- package/src/keyNavigation/navigator.js +543 -543
- package/src/listbox/css/listbox.css +7 -7
- package/src/listbox/css/listbox.css.map +1 -1
- package/src/listbox/scss/listbox.scss +116 -116
- package/src/listbox/tpl/list.tpl +14 -14
- package/src/listbox/tpl/main.tpl +9 -9
- package/src/listbox.js +251 -251
- package/src/liststyler.js +155 -155
- package/src/loadingButton/css/button.css +7 -7
- package/src/loadingButton/css/button.css.map +1 -1
- package/src/loadingButton/loadingButton.js +110 -110
- package/src/loadingButton/scss/button.scss +41 -41
- package/src/loadingButton/tpl/button.tpl +5 -5
- package/src/lock/lock.tpl +16 -16
- package/src/lock.js +395 -395
- package/src/login/login.js +322 -322
- package/src/login/tpl/login.tpl +29 -29
- package/src/login/tpl/passwordReveal.tpl +7 -7
- package/src/maths/calculator/basicCalculator.js +55 -55
- package/src/maths/calculator/calculatorComponent.js +128 -128
- package/src/maths/calculator/core/areaBroker.js +38 -38
- package/src/maths/calculator/core/board.js +841 -841
- package/src/maths/calculator/core/expression.js +430 -430
- package/src/maths/calculator/core/labels.js +116 -116
- package/src/maths/calculator/core/plugin.js +40 -40
- package/src/maths/calculator/core/terms.js +459 -459
- package/src/maths/calculator/core/tokenizer.js +245 -245
- package/src/maths/calculator/core/tokens.js +178 -178
- package/src/maths/calculator/core/tpl/board.tpl +4 -4
- package/src/maths/calculator/css/calculator.css +7 -7
- package/src/maths/calculator/css/calculator.css.map +1 -1
- package/src/maths/calculator/defaultCalculator.js +66 -66
- package/src/maths/calculator/plugins/core/degrad.js +90 -90
- package/src/maths/calculator/plugins/core/history.js +166 -166
- package/src/maths/calculator/plugins/core/remind.js +96 -96
- package/src/maths/calculator/plugins/core/stepNavigation.js +175 -175
- package/src/maths/calculator/plugins/keyboard/templateKeyboard/defaultTemplate.tpl +36 -36
- package/src/maths/calculator/plugins/keyboard/templateKeyboard/templateKeyboard.js +91 -91
- package/src/maths/calculator/plugins/modifiers/pow10.js +143 -143
- package/src/maths/calculator/plugins/modifiers/sign.js +339 -339
- package/src/maths/calculator/plugins/screen/simpleScreen/defaultTemplate.tpl +3 -3
- package/src/maths/calculator/plugins/screen/simpleScreen/history.tpl +3 -3
- package/src/maths/calculator/plugins/screen/simpleScreen/simpleScreen.js +191 -191
- package/src/maths/calculator/pluginsLoader.js +46 -46
- package/src/maths/calculator/scientificCalculator.js +74 -74
- package/src/maths/calculator/scss/calculator.scss +396 -396
- package/src/maths/calculator/tpl/basicKeyboard.tpl +37 -37
- package/src/maths/calculator/tpl/basicScreen.tpl +2 -2
- package/src/maths/calculator/tpl/scientificKeyboard.tpl +61 -61
- package/src/maths/calculator/tpl/scientificScreen.tpl +3 -3
- package/src/mediaEditor/mediaEditorComponent.js +141 -141
- package/src/mediaEditor/plugins/mediaAlignment/helper.js +62 -62
- package/src/mediaEditor/plugins/mediaAlignment/mediaAlignmentComponent.js +99 -99
- package/src/mediaEditor/plugins/mediaAlignment/style.css +7 -7
- package/src/mediaEditor/plugins/mediaAlignment/tpl/mediaAlignment.tpl +25 -25
- package/src/mediaEditor/plugins/mediaDimension/helper.js +189 -189
- package/src/mediaEditor/plugins/mediaDimension/mediaDimensionComponent.js +561 -561
- package/src/mediaEditor/plugins/mediaDimension/style.css +141 -141
- package/src/mediaEditor/plugins/mediaDimension/tpl/mediaDimension.tpl +55 -55
- package/src/mediaEditor/tpl/editor.tpl +4 -4
- package/src/mediaplayer/css/player.css +7 -7
- package/src/mediaplayer/css/player.css.map +1 -1
- package/src/mediaplayer/players/html5.js +564 -564
- package/src/mediaplayer/players/youtube.js +323 -323
- package/src/mediaplayer/players.js +29 -29
- package/src/mediaplayer/readme.md +305 -305
- package/src/mediaplayer/scss/player.scss +569 -569
- package/src/mediaplayer/support.js +126 -126
- package/src/mediaplayer/tpl/audio.tpl +6 -6
- package/src/mediaplayer/tpl/player.tpl +37 -37
- package/src/mediaplayer/tpl/source.tpl +1 -1
- package/src/mediaplayer/tpl/video.tpl +6 -6
- package/src/mediaplayer/tpl/youtube.tpl +1 -1
- package/src/mediaplayer/utils/reminder.js +184 -184
- package/src/mediaplayer/utils/timeObserver.js +143 -143
- package/src/mediaplayer/youtubeManager.js +161 -161
- package/src/mediaplayer.js +1606 -1606
- package/src/mediasizer/mediasizer.tpl +55 -55
- package/src/mediasizer.js +635 -635
- package/src/modal.js +365 -365
- package/src/movableComponent.js +78 -78
- package/src/pageSizeSelector/tpl/pageSizeSelector.tpl +9 -9
- package/src/pageSizeSelector.js +107 -107
- package/src/pageStatus.js +147 -147
- package/src/pagination/css/pagination.css +7 -7
- package/src/pagination/css/pagination.css.map +1 -1
- package/src/pagination/paginationStrategy.js +53 -53
- package/src/pagination/providers/pages.js +161 -161
- package/src/pagination/providers/simple.js +74 -74
- package/src/pagination/providers/tpl/pages/page.tpl +1 -1
- package/src/pagination/providers/tpl/pages.tpl +8 -8
- package/src/pagination/providers/tpl/simple.tpl +7 -7
- package/src/pagination/scss/pagination.scss +111 -111
- package/src/pagination.js +237 -237
- package/src/previewer.js +300 -300
- package/src/progressbar.js +165 -165
- package/src/propertySelector/css/propertySelector.css +74 -0
- package/src/propertySelector/css/propertySelector.css.map +1 -0
- package/src/propertySelector/propertySelector.js +286 -0
- package/src/propertySelector/scss/propertySelector.scss +66 -0
- package/src/propertySelector/tpl/highlighted-text.tpl +1 -0
- package/src/propertySelector/tpl/property-description.tpl +13 -0
- package/src/propertySelector/tpl/property-selector.tpl +7 -0
- package/src/report/feedback.tpl +11 -11
- package/src/report/layout.tpl +10 -10
- package/src/report.js +184 -184
- package/src/resource/css/selector.css +7 -7
- package/src/resource/css/selector.css.map +1 -1
- package/src/resource/filters.js +208 -208
- package/src/resource/list.js +200 -200
- package/src/resource/scss/_filters.scss +26 -26
- package/src/resource/scss/_resource-list.scss +107 -107
- package/src/resource/scss/_resource-tree.scss +205 -205
- package/src/resource/scss/selector.scss +187 -187
- package/src/resource/selectable.js +322 -322
- package/src/resource/selector.js +871 -871
- package/src/resource/tpl/filters.tpl +2 -2
- package/src/resource/tpl/list.tpl +7 -7
- package/src/resource/tpl/listNode.tpl +4 -4
- package/src/resource/tpl/selector.tpl +46 -46
- package/src/resource/tpl/tree.tpl +4 -4
- package/src/resource/tpl/treeNode.tpl +30 -30
- package/src/resource/tree.js +400 -400
- package/src/resourcemgr/css/resourcemgr.css +7 -7
- package/src/resourcemgr/css/resourcemgr.css.map +1 -1
- package/src/resourcemgr/fileBrowser.js +381 -381
- package/src/resourcemgr/filePreview.js +73 -73
- package/src/resourcemgr/fileSelector.js +348 -348
- package/src/resourcemgr/scss/resourcemgr.scss +254 -254
- package/src/resourcemgr/tpl/fileSelect.tpl +39 -39
- package/src/resourcemgr/tpl/folder.tpl +11 -11
- package/src/resourcemgr/tpl/layout.tpl +84 -84
- package/src/resourcemgr/tpl/rootFolder.tpl +13 -13
- package/src/resourcemgr/util/updatePermissions.js +53 -53
- package/src/resourcemgr.js +216 -216
- package/src/scroller.js +94 -94
- package/src/scss/basic.scss +16 -16
- package/src/searchModal/advancedSearch.js +638 -601
- package/src/searchModal/css/advancedSearch.css +7 -14
- package/src/searchModal/css/advancedSearch.css.map +1 -1
- package/src/searchModal/css/searchModal.css +29 -8
- package/src/searchModal/css/searchModal.css.map +1 -1
- package/src/searchModal/scss/advancedSearch.scss +171 -177
- package/src/searchModal/scss/searchModal.scss +393 -375
- package/src/searchModal/tpl/advanced-search.tpl +9 -9
- package/src/searchModal/tpl/criteria-alias.tpl +1 -0
- package/src/searchModal/tpl/criteria-class-label.tpl +1 -0
- package/src/searchModal/tpl/criteria-label.tpl +1 -0
- package/src/searchModal/tpl/highlighted-text.tpl +1 -0
- package/src/searchModal/tpl/info-message.tpl +3 -3
- package/src/searchModal/tpl/invalid-criteria-warning.tpl +10 -10
- package/src/searchModal/tpl/layout.tpl +27 -25
- package/src/searchModal/tpl/list-checkbox-criterion.tpl +17 -12
- package/src/searchModal/tpl/list-select-criterion.tpl +12 -6
- package/src/searchModal/tpl/property-select-button.tpl +1 -0
- package/src/searchModal/tpl/results-container.tpl +1 -0
- package/src/searchModal/tpl/text-criterion.tpl +11 -6
- package/src/searchModal.js +761 -496
- package/src/selecter.js +43 -43
- package/src/stacker.js +133 -133
- package/src/switch/css/switch.css +7 -7
- package/src/switch/css/switch.css.map +1 -1
- package/src/switch/scss/switch.scss +83 -83
- package/src/switch/switch.js +195 -195
- package/src/switch/tpl/switch.tpl +7 -7
- package/src/tableModel.js +112 -112
- package/src/tabs/css/tabs.css +12 -12
- package/src/tabs/css/tabs.css.map +1 -1
- package/src/tabs/scss/tabs.scss +50 -50
- package/src/tabs/tpl/panel.tpl +3 -3
- package/src/tabs/tpl/tabs.tpl +10 -10
- package/src/tabs.js +528 -528
- package/src/taskQueue/css/taskQueue.css +7 -7
- package/src/taskQueue/css/taskQueue.css.map +1 -1
- package/src/taskQueue/scss/taskQueue.scss +47 -47
- package/src/taskQueue/status.js +228 -228
- package/src/taskQueue/table.js +350 -350
- package/src/taskQueue/taskQueue.js +33 -33
- package/src/taskQueue/taskQueueModel.js +548 -548
- package/src/taskQueue/tpl/statusMessage.tpl +7 -7
- package/src/taskQueue.js +218 -218
- package/src/taskQueueButton/css/taskable.css +7 -7
- package/src/taskQueueButton/css/taskable.css.map +1 -1
- package/src/taskQueueButton/css/treeButton.css +7 -7
- package/src/taskQueueButton/css/treeButton.css.map +1 -1
- package/src/taskQueueButton/scss/taskable.scss +4 -4
- package/src/taskQueueButton/scss/treeButton.scss +34 -34
- package/src/taskQueueButton/standardButton.js +108 -108
- package/src/taskQueueButton/taskable.js +202 -202
- package/src/taskQueueButton/tpl/report.tpl +5 -5
- package/src/taskQueueButton/tpl/treeButton.tpl +6 -6
- package/src/taskQueueButton/treeButton.js +109 -109
- package/src/themeLoader.js +252 -252
- package/src/themes.js +162 -162
- package/src/toggler.js +200 -200
- package/src/tooltip/default.tpl +3 -3
- package/src/tooltip.js +160 -160
- package/src/tooltipster.js +25 -25
- package/src/transformer.js +327 -327
- package/src/tristateCheckboxGroup/css/tristateCheckboxGroup.css +7 -7
- package/src/tristateCheckboxGroup/css/tristateCheckboxGroup.css.map +1 -1
- package/src/tristateCheckboxGroup/scss/tristateCheckboxGroup.scss +15 -15
- package/src/tristateCheckboxGroup/tpl/li.tpl +6 -6
- package/src/tristateCheckboxGroup.js +207 -207
- package/src/uploader/fileEntry.tpl +6 -6
- package/src/uploader/uploader.tpl +32 -32
- package/src/uploader.js +594 -594
- package/src/validator/Report.js +10 -10
- package/src/validator/Validator.js +108 -108
- package/src/validator/validators.js +220 -220
- package/src/validator.js +264 -264
- package/src/waitForMedia.js +82 -82
- package/src/waitingDialog/css/waitingDialog.css +7 -7
- package/src/waitingDialog/css/waitingDialog.css.map +1 -1
- package/src/waitingDialog/scss/waitingDialog.scss +34 -34
- package/src/waitingDialog/waitingDialog.js +240 -240
package/src/tabs.js
CHANGED
|
@@ -1,528 +1,528 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This program is free software; you can redistribute it and/or
|
|
3
|
-
* modify it under the terms of the GNU General Public License
|
|
4
|
-
* as published by the Free Software Foundation; under version 2
|
|
5
|
-
* of the License (non-upgradable).
|
|
6
|
-
*
|
|
7
|
-
* This program is distributed in the hope that it will be useful,
|
|
8
|
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
9
|
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
10
|
-
* GNU General Public License for more details.
|
|
11
|
-
*
|
|
12
|
-
* You should have received a copy of the GNU General Public License
|
|
13
|
-
* along with this program; if not, write to the Free Software
|
|
14
|
-
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
15
|
-
*
|
|
16
|
-
* Copyright (c) 2019 (original work) Open Assessment Technologies SA ;
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* A simple Tabs component that:
|
|
21
|
-
* - manage a list of tabs
|
|
22
|
-
* - each tab is represented by an identifier and a label
|
|
23
|
-
* - only one tab can be activated at a time
|
|
24
|
-
* - when a tab is being activated, a `tabactivate` event is emitted, with the tab identifier as parameter
|
|
25
|
-
* - when a tab has been activated, a `tabchange` event is emitted, with the tab identifier as parameter
|
|
26
|
-
* - a panel can be linked to each tab, based a data attribute `data-tab-content` that should match the tab name
|
|
27
|
-
* - a tab can be disabled
|
|
28
|
-
*
|
|
29
|
-
* @author Martin Nicholson <martin@taotesting.com>
|
|
30
|
-
* @author Ricardo Proença, <ricardo@taotesting.com>
|
|
31
|
-
*/
|
|
32
|
-
import $ from 'jquery';
|
|
33
|
-
import _ from 'lodash';
|
|
34
|
-
import componentFactory from 'ui/component';
|
|
35
|
-
import tabsTpl from 'ui/tabs/tpl/tabs';
|
|
36
|
-
import 'ui/tabs/css/tabs.css';
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* @typedef {Object} tabsBarConfig
|
|
40
|
-
* @property {String} [activeTab] - The name of the active tab
|
|
41
|
-
* @property {Integer} [activeTabIndex] - the index of the tab to start on
|
|
42
|
-
* @property {tabConfig[]} [tabs] - The list of tabs
|
|
43
|
-
* @property {Boolean} [hideLoneTab] - Prevent to show the tabs when only one is registered
|
|
44
|
-
* @property {jQuery|HTMLElement|String|Boolean} [showHideTarget] - Defines the container where to wire up tabs to
|
|
45
|
-
* content, the link will be automatic, based on the data attribute `data-tab-content` that should match the tab name.
|
|
46
|
-
* If the value is `true` the component's container will be used to find the panels.
|
|
47
|
-
*/
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* @typedef {Object} tabConfig
|
|
51
|
-
* @property {Boolean} disabled - The tab is disabled
|
|
52
|
-
* @property {String} name - The tab identifier
|
|
53
|
-
* @property {String} label - The tab label
|
|
54
|
-
* @property {String} [icon] - An optional tab icon
|
|
55
|
-
* @property {String} [cls] - An optional CSS class name
|
|
56
|
-
*/
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* CSS class for the active tab
|
|
60
|
-
* @type {String}
|
|
61
|
-
*/
|
|
62
|
-
const activeTabCls = 'active';
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* CSS selector for the tabs
|
|
66
|
-
* @type {String}
|
|
67
|
-
*/
|
|
68
|
-
const tabSelector = '.tab';
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* CSS selector for the tab actions
|
|
72
|
-
* @type {String}
|
|
73
|
-
*/
|
|
74
|
-
const actionSelector = '.action';
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Name of the attribute that contain the tab identifier
|
|
78
|
-
* @type {String}
|
|
79
|
-
*/
|
|
80
|
-
const tabNameAttr = 'data-tab-name';
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Name of the attribute that contain the panel identifier
|
|
84
|
-
* @type {String}
|
|
85
|
-
*/
|
|
86
|
-
const panelNameAttr = 'data-tab-content';
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Builds an instance of the tabs component.
|
|
90
|
-
*
|
|
91
|
-
* @example
|
|
92
|
-
* // activate by index
|
|
93
|
-
* const instance = tabsFactory($container, {
|
|
94
|
-
* tabs: [
|
|
95
|
-
* { label: 'TAO Local', name: 'local-delivery' },
|
|
96
|
-
* { label: 'TAO Remote', name: 'remote-delivery' },
|
|
97
|
-
* { label: 'LTI-based', name: 'lti-delivery', disabled: true }
|
|
98
|
-
* ],
|
|
99
|
-
* activeTabIndex: 1
|
|
100
|
-
* });
|
|
101
|
-
*
|
|
102
|
-
* // activate by name
|
|
103
|
-
* const instance = tabsFactory($container, {
|
|
104
|
-
* tabs: [
|
|
105
|
-
* { label: 'TAO Local', name: 'local-delivery' },
|
|
106
|
-
* { label: 'TAO Remote', name: 'remote-delivery' },
|
|
107
|
-
* { label: 'LTI-based', name: 'lti-delivery', disabled: true }
|
|
108
|
-
* ],
|
|
109
|
-
* activeTab: 'remote-delivery'
|
|
110
|
-
* });
|
|
111
|
-
*
|
|
112
|
-
* // link to panels
|
|
113
|
-
* const instance = tabsFactory($container, {
|
|
114
|
-
* showHideTarget: $panelContainer,
|
|
115
|
-
* tabs: [
|
|
116
|
-
* { label: 'TAO Local', name: 'local-delivery' },
|
|
117
|
-
* { label: 'TAO Remote', name: 'remote-delivery' },
|
|
118
|
-
* { label: 'LTI-based', name: 'lti-delivery', disabled: true }
|
|
119
|
-
* ]
|
|
120
|
-
* });
|
|
121
|
-
*
|
|
122
|
-
* instance
|
|
123
|
-
* .on('ready', function onReady() {
|
|
124
|
-
* // the component is ready
|
|
125
|
-
* })
|
|
126
|
-
* .before('tabactivate', function beforeTabChange(e, name) {
|
|
127
|
-
* // a tab is being activated
|
|
128
|
-
* // it is possible to prevent its activation by returning a rejected promise
|
|
129
|
-
* if (name === 'lti-delivery') {
|
|
130
|
-
* return Promise.reject();
|
|
131
|
-
* }
|
|
132
|
-
* })
|
|
133
|
-
* .on('tabchange', function onTabChange(name) {
|
|
134
|
-
* // a tab has been activated
|
|
135
|
-
* });
|
|
136
|
-
*
|
|
137
|
-
* @param {HTMLElement|String} container
|
|
138
|
-
* @param {tabsBarConfig} config
|
|
139
|
-
* @param {String} [config.activeTab] - The name of the active tab
|
|
140
|
-
* @param {Integer} [config.activeTabIndex] - the index of the tab to start on
|
|
141
|
-
* @param {tabConfig[]} [config.tabs] - The list of tabs
|
|
142
|
-
* @param {Boolean} [config.hideLoneTab] - Prevent to show the tabs when only one is registered
|
|
143
|
-
* @param {jQuery|HTMLElement|String|Boolean} [config.showHideTarget] - Defines the container where to wire up tabs to
|
|
144
|
-
* content, the link will be automatic, based on the data attribute `data-tab-content` that should match the tab name.
|
|
145
|
-
* If the value is `true` the component's container will be used to find the panels.
|
|
146
|
-
* @returns {tabsBarComponent}
|
|
147
|
-
* @fires ready - When the component is ready to work
|
|
148
|
-
* @fires error - When the component encounters issue
|
|
149
|
-
* @fires tabactivate - Each time a tab must be activated
|
|
150
|
-
* @fires tabchange - Each time a tab has been activated
|
|
151
|
-
* @fires tabchange-${name} - Each time the named tab has been activated
|
|
152
|
-
* @fires tabsupdate - Each time the tabs are updated
|
|
153
|
-
*/
|
|
154
|
-
function tabsFactory(container, config) {
|
|
155
|
-
// the list of displayed tabs
|
|
156
|
-
let tabs = [];
|
|
157
|
-
|
|
158
|
-
// the current active tab
|
|
159
|
-
let activeTabName = null;
|
|
160
|
-
|
|
161
|
-
// enable/disable elements
|
|
162
|
-
const enableElement = $el => $el.prop('disabled', false);
|
|
163
|
-
const disableElement = $el => $el.prop('disabled', true);
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Gets a tab by its name
|
|
167
|
-
* @param {String} name
|
|
168
|
-
* @returns {tabConfig}
|
|
169
|
-
*/
|
|
170
|
-
const findTabByName = name => tabs.find(tab => tab.name === name);
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Gets a tab by its name, throw a TypeError if the tab does not exist
|
|
174
|
-
* @param {String} name - human-readable identifier
|
|
175
|
-
* @returns {tabConfig}
|
|
176
|
-
* @throws {TypeError} on invalid name param
|
|
177
|
-
*/
|
|
178
|
-
const findTabByNameOrThrow = name => {
|
|
179
|
-
const tab = findTabByName(name);
|
|
180
|
-
if (!tab) {
|
|
181
|
-
throw new TypeError(`No tab exists with the name: ${name}`);
|
|
182
|
-
}
|
|
183
|
-
return tab;
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Initializes the tabs
|
|
188
|
-
* @param {tabsBarComponent} component
|
|
189
|
-
*/
|
|
190
|
-
const initTabs = component => {
|
|
191
|
-
if (activeTabName) {
|
|
192
|
-
const activeTab = activeTabName;
|
|
193
|
-
activeTabName = null;
|
|
194
|
-
component.setActiveTab(activeTab);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
if (component.getConfig().hideLoneTab && tabs.length === 1) {
|
|
198
|
-
component.hide();
|
|
199
|
-
}
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* API of the tabs component
|
|
204
|
-
* @exports ui/tabs
|
|
205
|
-
*/
|
|
206
|
-
const tabsApi = {
|
|
207
|
-
/**
|
|
208
|
-
* Set new values for the tabs
|
|
209
|
-
* @param {Array} newTabs
|
|
210
|
-
* @returns {tabsBarComponent} instance
|
|
211
|
-
* @throws {TypeError} on non-Array tabs
|
|
212
|
-
* @fires tabsupdate once the tabs have been updated
|
|
213
|
-
* @fires tabactivate once the active tab is updated
|
|
214
|
-
*/
|
|
215
|
-
setTabs(newTabs) {
|
|
216
|
-
if (!Array.isArray(newTabs)) {
|
|
217
|
-
throw new TypeError('The provided tabs are not a valid array');
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
tabs = [...newTabs];
|
|
221
|
-
|
|
222
|
-
// reset tab to default if needed
|
|
223
|
-
if (!activeTabName || !findTabByName(activeTabName)) {
|
|
224
|
-
activeTabName = this.getDefaultActiveTab();
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
// replace the displayed tabs if already rendered
|
|
228
|
-
if (this.is('rendered')) {
|
|
229
|
-
const template = this.getTemplate();
|
|
230
|
-
this.getElement().html(
|
|
231
|
-
$(template({tabs})).html()
|
|
232
|
-
);
|
|
233
|
-
|
|
234
|
-
// make sure the tab is selected and hide lone tab if needed
|
|
235
|
-
initTabs(this);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
/**
|
|
239
|
-
* @event tabsupdate - Tabs have been updated
|
|
240
|
-
* @param {Array} newTabs
|
|
241
|
-
*/
|
|
242
|
-
this.trigger('tabsupdate', newTabs);
|
|
243
|
-
|
|
244
|
-
return this;
|
|
245
|
-
},
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
* Retrieve internal tabs array
|
|
249
|
-
* @returns {Array} tabs list
|
|
250
|
-
*/
|
|
251
|
-
getTabs() {
|
|
252
|
-
return [...tabs];
|
|
253
|
-
},
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* Gets the name of the active tab (if any)
|
|
257
|
-
* @returns {String}
|
|
258
|
-
*/
|
|
259
|
-
getActiveTab() {
|
|
260
|
-
return activeTabName;
|
|
261
|
-
},
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* Gets the index of the current active tab (if any)
|
|
265
|
-
* @returns {Number}
|
|
266
|
-
*/
|
|
267
|
-
getActiveTabIndex() {
|
|
268
|
-
return tabs.findIndex(tab => tab.name === activeTabName);
|
|
269
|
-
},
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* Gets the name of the default active tab
|
|
273
|
-
* @returns {String|null}
|
|
274
|
-
*/
|
|
275
|
-
getDefaultActiveTab() {
|
|
276
|
-
const {activeTab, activeTabIndex} = this.getConfig();
|
|
277
|
-
|
|
278
|
-
if (activeTab && findTabByName(activeTab)) {
|
|
279
|
-
return activeTab;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
if (typeof activeTabIndex === 'number' && tabs[activeTabIndex]) {
|
|
283
|
-
return tabs[activeTabIndex].name;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
return tabs.length && tabs[0].name || null;
|
|
287
|
-
},
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
* Activates a single tab by its name (deactivating others)
|
|
291
|
-
* @param {String} name - human-readable identifier
|
|
292
|
-
* @returns {tabsBarComponent} instance
|
|
293
|
-
* @throws {TypeError} on invalid name param
|
|
294
|
-
* @fires tabactivate
|
|
295
|
-
*/
|
|
296
|
-
setActiveTab(name) {
|
|
297
|
-
const tab = findTabByNameOrThrow(name);
|
|
298
|
-
|
|
299
|
-
if (!tab.disabled) {
|
|
300
|
-
/**
|
|
301
|
-
* @event tabactivate - A tab is being activated
|
|
302
|
-
* @param {String} - name
|
|
303
|
-
*/
|
|
304
|
-
this.trigger('tabactivate', tab.name);
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
return this;
|
|
308
|
-
},
|
|
309
|
-
|
|
310
|
-
/**
|
|
311
|
-
* Activates a single tab by its index (deactivating others)
|
|
312
|
-
* Triggers the automatic showing & hiding of target tab-contents
|
|
313
|
-
* @param {Number} index - zero-based
|
|
314
|
-
* @returns {tabsBarComponent} instance
|
|
315
|
-
* @throws {TypeError} on invalid index param
|
|
316
|
-
* @fires tabactivate
|
|
317
|
-
*/
|
|
318
|
-
setActiveTabIndex(index) {
|
|
319
|
-
if (typeof index !== 'number' || index < 0 || index >= tabs.length) {
|
|
320
|
-
throw new TypeError(`No tab exists at index: ${index}`);
|
|
321
|
-
}
|
|
322
|
-
const tab = tabs[index];
|
|
323
|
-
if (!tab.disabled) {
|
|
324
|
-
/**
|
|
325
|
-
* @event tabactivate - A tab is being activated
|
|
326
|
-
* @param {String} - name
|
|
327
|
-
*/
|
|
328
|
-
this.trigger('tabactivate', tab.name);
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
return this;
|
|
332
|
-
},
|
|
333
|
-
|
|
334
|
-
/**
|
|
335
|
-
* Enables a single tab by its name
|
|
336
|
-
* @param {String} name - human-readable identifier
|
|
337
|
-
* @returns {tabsBarComponent} instance
|
|
338
|
-
* @throws {TypeError} on invalid name param
|
|
339
|
-
* @fires tabenable
|
|
340
|
-
*/
|
|
341
|
-
enableTab(name) {
|
|
342
|
-
const tab = findTabByNameOrThrow(name);
|
|
343
|
-
|
|
344
|
-
tab.disabled = false;
|
|
345
|
-
|
|
346
|
-
if (this.is('rendered')) {
|
|
347
|
-
enableElement(this.getElement().find(`[${tabNameAttr}="${name}"] ${actionSelector}`));
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
/**
|
|
351
|
-
* @event tabenable - A tab is enabled
|
|
352
|
-
* @param {String} - name
|
|
353
|
-
*/
|
|
354
|
-
this.trigger('tabenable', name);
|
|
355
|
-
|
|
356
|
-
return this;
|
|
357
|
-
},
|
|
358
|
-
|
|
359
|
-
/**
|
|
360
|
-
* Disables a single tab by its name
|
|
361
|
-
* @param {String} name - human-readable identifier
|
|
362
|
-
* @returns {tabsBarComponent} instance
|
|
363
|
-
* @throws {TypeError} on invalid name param
|
|
364
|
-
* @fires tabdisable
|
|
365
|
-
*/
|
|
366
|
-
disableTab(name) {
|
|
367
|
-
const tab = findTabByNameOrThrow(name);
|
|
368
|
-
|
|
369
|
-
tab.disabled = true;
|
|
370
|
-
|
|
371
|
-
if (this.is('rendered')) {
|
|
372
|
-
disableElement(this.getElement().find(`[${tabNameAttr}="${name}"] ${actionSelector}`));
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
/**
|
|
376
|
-
* @event tabdisable - A tab is disabled
|
|
377
|
-
* @param {String} - name
|
|
378
|
-
*/
|
|
379
|
-
this.trigger('tabdisable', name);
|
|
380
|
-
},
|
|
381
|
-
|
|
382
|
-
/**
|
|
383
|
-
* Shows one tab content, hides the rest
|
|
384
|
-
* The tab content elements are not tied to any template and can be located anywhere in the DOM
|
|
385
|
-
* @param {String} name - human-readable identifier
|
|
386
|
-
* @throws {TypeError} on invalid name param
|
|
387
|
-
* @fires tabshowcontent
|
|
388
|
-
*/
|
|
389
|
-
showTabContent(name) {
|
|
390
|
-
findTabByNameOrThrow(name);
|
|
391
|
-
|
|
392
|
-
const {showHideTarget} = this.getConfig();
|
|
393
|
-
if (showHideTarget) {
|
|
394
|
-
(showHideTarget === true ? this.getContainer() : $(showHideTarget))
|
|
395
|
-
.find(`[${panelNameAttr}]`)
|
|
396
|
-
.addClass('hidden')
|
|
397
|
-
.filter(`[${panelNameAttr}="${name}"]`)
|
|
398
|
-
.removeClass('hidden');
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
/**
|
|
402
|
-
* @event tabshowcontent - A tab panel is displayed
|
|
403
|
-
* @param {String} - name
|
|
404
|
-
*/
|
|
405
|
-
this.trigger('tabshowcontent', name);
|
|
406
|
-
}
|
|
407
|
-
};
|
|
408
|
-
|
|
409
|
-
/**
|
|
410
|
-
* @typedef {component} tabsBarComponent
|
|
411
|
-
*/
|
|
412
|
-
const tabsBarComponent = componentFactory(tabsApi)
|
|
413
|
-
// set the component's layout
|
|
414
|
-
.setTemplate(tabsTpl)
|
|
415
|
-
|
|
416
|
-
// auto render on init
|
|
417
|
-
.on('init', function onTabsBarInit() {
|
|
418
|
-
try {
|
|
419
|
-
// extract the tabs from the config
|
|
420
|
-
if (this.config && this.config.tabs) {
|
|
421
|
-
this.setTabs(this.config.tabs);
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
// auto render on init (defer the call to give a chance to the init event to be completed before)
|
|
425
|
-
_.defer(() => this.render(container));
|
|
426
|
-
} catch (err) {
|
|
427
|
-
/**
|
|
428
|
-
* @event error
|
|
429
|
-
* @param {Error} err
|
|
430
|
-
*/
|
|
431
|
-
this.trigger('error', err);
|
|
432
|
-
}
|
|
433
|
-
})
|
|
434
|
-
|
|
435
|
-
// renders the component
|
|
436
|
-
.on('render', function onTabsBarRender() {
|
|
437
|
-
try {
|
|
438
|
-
// make sure the tab is selected and hide lone tab if needed
|
|
439
|
-
initTabs(this);
|
|
440
|
-
} catch (err) {
|
|
441
|
-
/**
|
|
442
|
-
* @event error
|
|
443
|
-
* @param {Error} err
|
|
444
|
-
*/
|
|
445
|
-
this.trigger('error', err);
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
// delegate the click on tabs
|
|
449
|
-
this.getElement().on('click', tabSelector, e => {
|
|
450
|
-
try {
|
|
451
|
-
this.setActiveTab(e.currentTarget.getAttribute(tabNameAttr));
|
|
452
|
-
} catch (err) {
|
|
453
|
-
/**
|
|
454
|
-
* @event error
|
|
455
|
-
* @param {Error} err
|
|
456
|
-
*/
|
|
457
|
-
this.trigger('error', err);
|
|
458
|
-
}
|
|
459
|
-
});
|
|
460
|
-
|
|
461
|
-
/**
|
|
462
|
-
* @event ready - The component is ready to work
|
|
463
|
-
*/
|
|
464
|
-
this.trigger('ready');
|
|
465
|
-
})
|
|
466
|
-
|
|
467
|
-
// take care of the disable state
|
|
468
|
-
.on('disable', function onButtonDisable() {
|
|
469
|
-
if (this.is('rendered')) {
|
|
470
|
-
disableElement(this.getElement().find(`[${tabNameAttr}] ${actionSelector}`));
|
|
471
|
-
}
|
|
472
|
-
})
|
|
473
|
-
.on('enable', function onButtonEnable() {
|
|
474
|
-
if (this.is('rendered')) {
|
|
475
|
-
this.getElement()
|
|
476
|
-
.find(`[${tabNameAttr}] ${actionSelector}`)
|
|
477
|
-
.each((index, el) => {
|
|
478
|
-
const tab = findTabByName(el.parentNode.getAttribute(tabNameAttr));
|
|
479
|
-
if (!tab || !tab.disabled) {
|
|
480
|
-
el.disabled = false;
|
|
481
|
-
}
|
|
482
|
-
});
|
|
483
|
-
}
|
|
484
|
-
})
|
|
485
|
-
|
|
486
|
-
// reacts to tab activate
|
|
487
|
-
.on('tabactivate', function onTabActivate(name) {
|
|
488
|
-
const tab = findTabByName(name);
|
|
489
|
-
if (tab && !tab.disabled && name !== activeTabName) {
|
|
490
|
-
activeTabName = name;
|
|
491
|
-
|
|
492
|
-
if (this.is('rendered')) {
|
|
493
|
-
this.getElement()
|
|
494
|
-
.find(tabSelector)
|
|
495
|
-
.removeClass(activeTabCls)
|
|
496
|
-
.filter(`[${tabNameAttr}="${name}"]`)
|
|
497
|
-
.addClass(activeTabCls);
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
/**
|
|
501
|
-
* @event tabchange - A tab is activated
|
|
502
|
-
* @param {String} - name
|
|
503
|
-
*/
|
|
504
|
-
this.trigger('tabchange', name);
|
|
505
|
-
}
|
|
506
|
-
})
|
|
507
|
-
|
|
508
|
-
// reacts to tab change
|
|
509
|
-
.on('tabchange', function onTabChange(name) {
|
|
510
|
-
// auto show the linked panel
|
|
511
|
-
if (this.getConfig().showHideTarget) {
|
|
512
|
-
this.showTabContent(name);
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
/**
|
|
516
|
-
* @event tabchange-${name} - The tab is activated
|
|
517
|
-
*/
|
|
518
|
-
this.trigger(`tabchange-${name}`);
|
|
519
|
-
});
|
|
520
|
-
|
|
521
|
-
// initialize the component with the provided config
|
|
522
|
-
// defer the call to allow to listen to the init event
|
|
523
|
-
_.defer(() => tabsBarComponent.init(config));
|
|
524
|
-
|
|
525
|
-
return tabsBarComponent;
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
export default tabsFactory;
|
|
1
|
+
/**
|
|
2
|
+
* This program is free software; you can redistribute it and/or
|
|
3
|
+
* modify it under the terms of the GNU General Public License
|
|
4
|
+
* as published by the Free Software Foundation; under version 2
|
|
5
|
+
* of the License (non-upgradable).
|
|
6
|
+
*
|
|
7
|
+
* This program is distributed in the hope that it will be useful,
|
|
8
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
9
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
10
|
+
* GNU General Public License for more details.
|
|
11
|
+
*
|
|
12
|
+
* You should have received a copy of the GNU General Public License
|
|
13
|
+
* along with this program; if not, write to the Free Software
|
|
14
|
+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
15
|
+
*
|
|
16
|
+
* Copyright (c) 2019 (original work) Open Assessment Technologies SA ;
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* A simple Tabs component that:
|
|
21
|
+
* - manage a list of tabs
|
|
22
|
+
* - each tab is represented by an identifier and a label
|
|
23
|
+
* - only one tab can be activated at a time
|
|
24
|
+
* - when a tab is being activated, a `tabactivate` event is emitted, with the tab identifier as parameter
|
|
25
|
+
* - when a tab has been activated, a `tabchange` event is emitted, with the tab identifier as parameter
|
|
26
|
+
* - a panel can be linked to each tab, based a data attribute `data-tab-content` that should match the tab name
|
|
27
|
+
* - a tab can be disabled
|
|
28
|
+
*
|
|
29
|
+
* @author Martin Nicholson <martin@taotesting.com>
|
|
30
|
+
* @author Ricardo Proença, <ricardo@taotesting.com>
|
|
31
|
+
*/
|
|
32
|
+
import $ from 'jquery';
|
|
33
|
+
import _ from 'lodash';
|
|
34
|
+
import componentFactory from 'ui/component';
|
|
35
|
+
import tabsTpl from 'ui/tabs/tpl/tabs';
|
|
36
|
+
import 'ui/tabs/css/tabs.css';
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @typedef {Object} tabsBarConfig
|
|
40
|
+
* @property {String} [activeTab] - The name of the active tab
|
|
41
|
+
* @property {Integer} [activeTabIndex] - the index of the tab to start on
|
|
42
|
+
* @property {tabConfig[]} [tabs] - The list of tabs
|
|
43
|
+
* @property {Boolean} [hideLoneTab] - Prevent to show the tabs when only one is registered
|
|
44
|
+
* @property {jQuery|HTMLElement|String|Boolean} [showHideTarget] - Defines the container where to wire up tabs to
|
|
45
|
+
* content, the link will be automatic, based on the data attribute `data-tab-content` that should match the tab name.
|
|
46
|
+
* If the value is `true` the component's container will be used to find the panels.
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @typedef {Object} tabConfig
|
|
51
|
+
* @property {Boolean} disabled - The tab is disabled
|
|
52
|
+
* @property {String} name - The tab identifier
|
|
53
|
+
* @property {String} label - The tab label
|
|
54
|
+
* @property {String} [icon] - An optional tab icon
|
|
55
|
+
* @property {String} [cls] - An optional CSS class name
|
|
56
|
+
*/
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* CSS class for the active tab
|
|
60
|
+
* @type {String}
|
|
61
|
+
*/
|
|
62
|
+
const activeTabCls = 'active';
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* CSS selector for the tabs
|
|
66
|
+
* @type {String}
|
|
67
|
+
*/
|
|
68
|
+
const tabSelector = '.tab';
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* CSS selector for the tab actions
|
|
72
|
+
* @type {String}
|
|
73
|
+
*/
|
|
74
|
+
const actionSelector = '.action';
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Name of the attribute that contain the tab identifier
|
|
78
|
+
* @type {String}
|
|
79
|
+
*/
|
|
80
|
+
const tabNameAttr = 'data-tab-name';
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Name of the attribute that contain the panel identifier
|
|
84
|
+
* @type {String}
|
|
85
|
+
*/
|
|
86
|
+
const panelNameAttr = 'data-tab-content';
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Builds an instance of the tabs component.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* // activate by index
|
|
93
|
+
* const instance = tabsFactory($container, {
|
|
94
|
+
* tabs: [
|
|
95
|
+
* { label: 'TAO Local', name: 'local-delivery' },
|
|
96
|
+
* { label: 'TAO Remote', name: 'remote-delivery' },
|
|
97
|
+
* { label: 'LTI-based', name: 'lti-delivery', disabled: true }
|
|
98
|
+
* ],
|
|
99
|
+
* activeTabIndex: 1
|
|
100
|
+
* });
|
|
101
|
+
*
|
|
102
|
+
* // activate by name
|
|
103
|
+
* const instance = tabsFactory($container, {
|
|
104
|
+
* tabs: [
|
|
105
|
+
* { label: 'TAO Local', name: 'local-delivery' },
|
|
106
|
+
* { label: 'TAO Remote', name: 'remote-delivery' },
|
|
107
|
+
* { label: 'LTI-based', name: 'lti-delivery', disabled: true }
|
|
108
|
+
* ],
|
|
109
|
+
* activeTab: 'remote-delivery'
|
|
110
|
+
* });
|
|
111
|
+
*
|
|
112
|
+
* // link to panels
|
|
113
|
+
* const instance = tabsFactory($container, {
|
|
114
|
+
* showHideTarget: $panelContainer,
|
|
115
|
+
* tabs: [
|
|
116
|
+
* { label: 'TAO Local', name: 'local-delivery' },
|
|
117
|
+
* { label: 'TAO Remote', name: 'remote-delivery' },
|
|
118
|
+
* { label: 'LTI-based', name: 'lti-delivery', disabled: true }
|
|
119
|
+
* ]
|
|
120
|
+
* });
|
|
121
|
+
*
|
|
122
|
+
* instance
|
|
123
|
+
* .on('ready', function onReady() {
|
|
124
|
+
* // the component is ready
|
|
125
|
+
* })
|
|
126
|
+
* .before('tabactivate', function beforeTabChange(e, name) {
|
|
127
|
+
* // a tab is being activated
|
|
128
|
+
* // it is possible to prevent its activation by returning a rejected promise
|
|
129
|
+
* if (name === 'lti-delivery') {
|
|
130
|
+
* return Promise.reject();
|
|
131
|
+
* }
|
|
132
|
+
* })
|
|
133
|
+
* .on('tabchange', function onTabChange(name) {
|
|
134
|
+
* // a tab has been activated
|
|
135
|
+
* });
|
|
136
|
+
*
|
|
137
|
+
* @param {HTMLElement|String} container
|
|
138
|
+
* @param {tabsBarConfig} config
|
|
139
|
+
* @param {String} [config.activeTab] - The name of the active tab
|
|
140
|
+
* @param {Integer} [config.activeTabIndex] - the index of the tab to start on
|
|
141
|
+
* @param {tabConfig[]} [config.tabs] - The list of tabs
|
|
142
|
+
* @param {Boolean} [config.hideLoneTab] - Prevent to show the tabs when only one is registered
|
|
143
|
+
* @param {jQuery|HTMLElement|String|Boolean} [config.showHideTarget] - Defines the container where to wire up tabs to
|
|
144
|
+
* content, the link will be automatic, based on the data attribute `data-tab-content` that should match the tab name.
|
|
145
|
+
* If the value is `true` the component's container will be used to find the panels.
|
|
146
|
+
* @returns {tabsBarComponent}
|
|
147
|
+
* @fires ready - When the component is ready to work
|
|
148
|
+
* @fires error - When the component encounters issue
|
|
149
|
+
* @fires tabactivate - Each time a tab must be activated
|
|
150
|
+
* @fires tabchange - Each time a tab has been activated
|
|
151
|
+
* @fires tabchange-${name} - Each time the named tab has been activated
|
|
152
|
+
* @fires tabsupdate - Each time the tabs are updated
|
|
153
|
+
*/
|
|
154
|
+
function tabsFactory(container, config) {
|
|
155
|
+
// the list of displayed tabs
|
|
156
|
+
let tabs = [];
|
|
157
|
+
|
|
158
|
+
// the current active tab
|
|
159
|
+
let activeTabName = null;
|
|
160
|
+
|
|
161
|
+
// enable/disable elements
|
|
162
|
+
const enableElement = $el => $el.prop('disabled', false);
|
|
163
|
+
const disableElement = $el => $el.prop('disabled', true);
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Gets a tab by its name
|
|
167
|
+
* @param {String} name
|
|
168
|
+
* @returns {tabConfig}
|
|
169
|
+
*/
|
|
170
|
+
const findTabByName = name => tabs.find(tab => tab.name === name);
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Gets a tab by its name, throw a TypeError if the tab does not exist
|
|
174
|
+
* @param {String} name - human-readable identifier
|
|
175
|
+
* @returns {tabConfig}
|
|
176
|
+
* @throws {TypeError} on invalid name param
|
|
177
|
+
*/
|
|
178
|
+
const findTabByNameOrThrow = name => {
|
|
179
|
+
const tab = findTabByName(name);
|
|
180
|
+
if (!tab) {
|
|
181
|
+
throw new TypeError(`No tab exists with the name: ${name}`);
|
|
182
|
+
}
|
|
183
|
+
return tab;
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Initializes the tabs
|
|
188
|
+
* @param {tabsBarComponent} component
|
|
189
|
+
*/
|
|
190
|
+
const initTabs = component => {
|
|
191
|
+
if (activeTabName) {
|
|
192
|
+
const activeTab = activeTabName;
|
|
193
|
+
activeTabName = null;
|
|
194
|
+
component.setActiveTab(activeTab);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (component.getConfig().hideLoneTab && tabs.length === 1) {
|
|
198
|
+
component.hide();
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* API of the tabs component
|
|
204
|
+
* @exports ui/tabs
|
|
205
|
+
*/
|
|
206
|
+
const tabsApi = {
|
|
207
|
+
/**
|
|
208
|
+
* Set new values for the tabs
|
|
209
|
+
* @param {Array} newTabs
|
|
210
|
+
* @returns {tabsBarComponent} instance
|
|
211
|
+
* @throws {TypeError} on non-Array tabs
|
|
212
|
+
* @fires tabsupdate once the tabs have been updated
|
|
213
|
+
* @fires tabactivate once the active tab is updated
|
|
214
|
+
*/
|
|
215
|
+
setTabs(newTabs) {
|
|
216
|
+
if (!Array.isArray(newTabs)) {
|
|
217
|
+
throw new TypeError('The provided tabs are not a valid array');
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
tabs = [...newTabs];
|
|
221
|
+
|
|
222
|
+
// reset tab to default if needed
|
|
223
|
+
if (!activeTabName || !findTabByName(activeTabName)) {
|
|
224
|
+
activeTabName = this.getDefaultActiveTab();
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// replace the displayed tabs if already rendered
|
|
228
|
+
if (this.is('rendered')) {
|
|
229
|
+
const template = this.getTemplate();
|
|
230
|
+
this.getElement().html(
|
|
231
|
+
$(template({tabs})).html()
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
// make sure the tab is selected and hide lone tab if needed
|
|
235
|
+
initTabs(this);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* @event tabsupdate - Tabs have been updated
|
|
240
|
+
* @param {Array} newTabs
|
|
241
|
+
*/
|
|
242
|
+
this.trigger('tabsupdate', newTabs);
|
|
243
|
+
|
|
244
|
+
return this;
|
|
245
|
+
},
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Retrieve internal tabs array
|
|
249
|
+
* @returns {Array} tabs list
|
|
250
|
+
*/
|
|
251
|
+
getTabs() {
|
|
252
|
+
return [...tabs];
|
|
253
|
+
},
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Gets the name of the active tab (if any)
|
|
257
|
+
* @returns {String}
|
|
258
|
+
*/
|
|
259
|
+
getActiveTab() {
|
|
260
|
+
return activeTabName;
|
|
261
|
+
},
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Gets the index of the current active tab (if any)
|
|
265
|
+
* @returns {Number}
|
|
266
|
+
*/
|
|
267
|
+
getActiveTabIndex() {
|
|
268
|
+
return tabs.findIndex(tab => tab.name === activeTabName);
|
|
269
|
+
},
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Gets the name of the default active tab
|
|
273
|
+
* @returns {String|null}
|
|
274
|
+
*/
|
|
275
|
+
getDefaultActiveTab() {
|
|
276
|
+
const {activeTab, activeTabIndex} = this.getConfig();
|
|
277
|
+
|
|
278
|
+
if (activeTab && findTabByName(activeTab)) {
|
|
279
|
+
return activeTab;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
if (typeof activeTabIndex === 'number' && tabs[activeTabIndex]) {
|
|
283
|
+
return tabs[activeTabIndex].name;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
return tabs.length && tabs[0].name || null;
|
|
287
|
+
},
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Activates a single tab by its name (deactivating others)
|
|
291
|
+
* @param {String} name - human-readable identifier
|
|
292
|
+
* @returns {tabsBarComponent} instance
|
|
293
|
+
* @throws {TypeError} on invalid name param
|
|
294
|
+
* @fires tabactivate
|
|
295
|
+
*/
|
|
296
|
+
setActiveTab(name) {
|
|
297
|
+
const tab = findTabByNameOrThrow(name);
|
|
298
|
+
|
|
299
|
+
if (!tab.disabled) {
|
|
300
|
+
/**
|
|
301
|
+
* @event tabactivate - A tab is being activated
|
|
302
|
+
* @param {String} - name
|
|
303
|
+
*/
|
|
304
|
+
this.trigger('tabactivate', tab.name);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return this;
|
|
308
|
+
},
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Activates a single tab by its index (deactivating others)
|
|
312
|
+
* Triggers the automatic showing & hiding of target tab-contents
|
|
313
|
+
* @param {Number} index - zero-based
|
|
314
|
+
* @returns {tabsBarComponent} instance
|
|
315
|
+
* @throws {TypeError} on invalid index param
|
|
316
|
+
* @fires tabactivate
|
|
317
|
+
*/
|
|
318
|
+
setActiveTabIndex(index) {
|
|
319
|
+
if (typeof index !== 'number' || index < 0 || index >= tabs.length) {
|
|
320
|
+
throw new TypeError(`No tab exists at index: ${index}`);
|
|
321
|
+
}
|
|
322
|
+
const tab = tabs[index];
|
|
323
|
+
if (!tab.disabled) {
|
|
324
|
+
/**
|
|
325
|
+
* @event tabactivate - A tab is being activated
|
|
326
|
+
* @param {String} - name
|
|
327
|
+
*/
|
|
328
|
+
this.trigger('tabactivate', tab.name);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
return this;
|
|
332
|
+
},
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Enables a single tab by its name
|
|
336
|
+
* @param {String} name - human-readable identifier
|
|
337
|
+
* @returns {tabsBarComponent} instance
|
|
338
|
+
* @throws {TypeError} on invalid name param
|
|
339
|
+
* @fires tabenable
|
|
340
|
+
*/
|
|
341
|
+
enableTab(name) {
|
|
342
|
+
const tab = findTabByNameOrThrow(name);
|
|
343
|
+
|
|
344
|
+
tab.disabled = false;
|
|
345
|
+
|
|
346
|
+
if (this.is('rendered')) {
|
|
347
|
+
enableElement(this.getElement().find(`[${tabNameAttr}="${name}"] ${actionSelector}`));
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* @event tabenable - A tab is enabled
|
|
352
|
+
* @param {String} - name
|
|
353
|
+
*/
|
|
354
|
+
this.trigger('tabenable', name);
|
|
355
|
+
|
|
356
|
+
return this;
|
|
357
|
+
},
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Disables a single tab by its name
|
|
361
|
+
* @param {String} name - human-readable identifier
|
|
362
|
+
* @returns {tabsBarComponent} instance
|
|
363
|
+
* @throws {TypeError} on invalid name param
|
|
364
|
+
* @fires tabdisable
|
|
365
|
+
*/
|
|
366
|
+
disableTab(name) {
|
|
367
|
+
const tab = findTabByNameOrThrow(name);
|
|
368
|
+
|
|
369
|
+
tab.disabled = true;
|
|
370
|
+
|
|
371
|
+
if (this.is('rendered')) {
|
|
372
|
+
disableElement(this.getElement().find(`[${tabNameAttr}="${name}"] ${actionSelector}`));
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* @event tabdisable - A tab is disabled
|
|
377
|
+
* @param {String} - name
|
|
378
|
+
*/
|
|
379
|
+
this.trigger('tabdisable', name);
|
|
380
|
+
},
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Shows one tab content, hides the rest
|
|
384
|
+
* The tab content elements are not tied to any template and can be located anywhere in the DOM
|
|
385
|
+
* @param {String} name - human-readable identifier
|
|
386
|
+
* @throws {TypeError} on invalid name param
|
|
387
|
+
* @fires tabshowcontent
|
|
388
|
+
*/
|
|
389
|
+
showTabContent(name) {
|
|
390
|
+
findTabByNameOrThrow(name);
|
|
391
|
+
|
|
392
|
+
const {showHideTarget} = this.getConfig();
|
|
393
|
+
if (showHideTarget) {
|
|
394
|
+
(showHideTarget === true ? this.getContainer() : $(showHideTarget))
|
|
395
|
+
.find(`[${panelNameAttr}]`)
|
|
396
|
+
.addClass('hidden')
|
|
397
|
+
.filter(`[${panelNameAttr}="${name}"]`)
|
|
398
|
+
.removeClass('hidden');
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* @event tabshowcontent - A tab panel is displayed
|
|
403
|
+
* @param {String} - name
|
|
404
|
+
*/
|
|
405
|
+
this.trigger('tabshowcontent', name);
|
|
406
|
+
}
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* @typedef {component} tabsBarComponent
|
|
411
|
+
*/
|
|
412
|
+
const tabsBarComponent = componentFactory(tabsApi)
|
|
413
|
+
// set the component's layout
|
|
414
|
+
.setTemplate(tabsTpl)
|
|
415
|
+
|
|
416
|
+
// auto render on init
|
|
417
|
+
.on('init', function onTabsBarInit() {
|
|
418
|
+
try {
|
|
419
|
+
// extract the tabs from the config
|
|
420
|
+
if (this.config && this.config.tabs) {
|
|
421
|
+
this.setTabs(this.config.tabs);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// auto render on init (defer the call to give a chance to the init event to be completed before)
|
|
425
|
+
_.defer(() => this.render(container));
|
|
426
|
+
} catch (err) {
|
|
427
|
+
/**
|
|
428
|
+
* @event error
|
|
429
|
+
* @param {Error} err
|
|
430
|
+
*/
|
|
431
|
+
this.trigger('error', err);
|
|
432
|
+
}
|
|
433
|
+
})
|
|
434
|
+
|
|
435
|
+
// renders the component
|
|
436
|
+
.on('render', function onTabsBarRender() {
|
|
437
|
+
try {
|
|
438
|
+
// make sure the tab is selected and hide lone tab if needed
|
|
439
|
+
initTabs(this);
|
|
440
|
+
} catch (err) {
|
|
441
|
+
/**
|
|
442
|
+
* @event error
|
|
443
|
+
* @param {Error} err
|
|
444
|
+
*/
|
|
445
|
+
this.trigger('error', err);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// delegate the click on tabs
|
|
449
|
+
this.getElement().on('click', tabSelector, e => {
|
|
450
|
+
try {
|
|
451
|
+
this.setActiveTab(e.currentTarget.getAttribute(tabNameAttr));
|
|
452
|
+
} catch (err) {
|
|
453
|
+
/**
|
|
454
|
+
* @event error
|
|
455
|
+
* @param {Error} err
|
|
456
|
+
*/
|
|
457
|
+
this.trigger('error', err);
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* @event ready - The component is ready to work
|
|
463
|
+
*/
|
|
464
|
+
this.trigger('ready');
|
|
465
|
+
})
|
|
466
|
+
|
|
467
|
+
// take care of the disable state
|
|
468
|
+
.on('disable', function onButtonDisable() {
|
|
469
|
+
if (this.is('rendered')) {
|
|
470
|
+
disableElement(this.getElement().find(`[${tabNameAttr}] ${actionSelector}`));
|
|
471
|
+
}
|
|
472
|
+
})
|
|
473
|
+
.on('enable', function onButtonEnable() {
|
|
474
|
+
if (this.is('rendered')) {
|
|
475
|
+
this.getElement()
|
|
476
|
+
.find(`[${tabNameAttr}] ${actionSelector}`)
|
|
477
|
+
.each((index, el) => {
|
|
478
|
+
const tab = findTabByName(el.parentNode.getAttribute(tabNameAttr));
|
|
479
|
+
if (!tab || !tab.disabled) {
|
|
480
|
+
el.disabled = false;
|
|
481
|
+
}
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
})
|
|
485
|
+
|
|
486
|
+
// reacts to tab activate
|
|
487
|
+
.on('tabactivate', function onTabActivate(name) {
|
|
488
|
+
const tab = findTabByName(name);
|
|
489
|
+
if (tab && !tab.disabled && name !== activeTabName) {
|
|
490
|
+
activeTabName = name;
|
|
491
|
+
|
|
492
|
+
if (this.is('rendered')) {
|
|
493
|
+
this.getElement()
|
|
494
|
+
.find(tabSelector)
|
|
495
|
+
.removeClass(activeTabCls)
|
|
496
|
+
.filter(`[${tabNameAttr}="${name}"]`)
|
|
497
|
+
.addClass(activeTabCls);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* @event tabchange - A tab is activated
|
|
502
|
+
* @param {String} - name
|
|
503
|
+
*/
|
|
504
|
+
this.trigger('tabchange', name);
|
|
505
|
+
}
|
|
506
|
+
})
|
|
507
|
+
|
|
508
|
+
// reacts to tab change
|
|
509
|
+
.on('tabchange', function onTabChange(name) {
|
|
510
|
+
// auto show the linked panel
|
|
511
|
+
if (this.getConfig().showHideTarget) {
|
|
512
|
+
this.showTabContent(name);
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* @event tabchange-${name} - The tab is activated
|
|
517
|
+
*/
|
|
518
|
+
this.trigger(`tabchange-${name}`);
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
// initialize the component with the provided config
|
|
522
|
+
// defer the call to allow to listen to the init event
|
|
523
|
+
_.defer(() => tabsBarComponent.init(config));
|
|
524
|
+
|
|
525
|
+
return tabsBarComponent;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
export default tabsFactory;
|