4747 role =" tab"
4848 @click.prevent =" setActive(tab.id)" >
4949 <span class =" app-sidebar-tabs__tab-icon" >
50- <NcVNodes v-if =" hasMdIcon(tab)" :vnodes =" tab.$slots.icon[0]" />
51- <span v-else :class =" tab.icon" />
50+ <NcVNodes :vnodes =" tab.renderIcon()" />
5251 </span >
5352 {{ tab.name }}
5453 </a >
6766<script >
6867import NcVNodes from ' ../NcVNodes/index.js'
6968
70- import Vue from ' vue'
71-
72- const IsValidString = function (value ) {
73- return value && typeof value === ' string' && value .trim () !== ' '
74- }
75-
76- const IsValidStringWithoutSpaces = function (value ) {
77- return IsValidString (value) && value .indexOf (' ' ) === - 1
78- }
79-
8069export default {
8170 name: ' NcAppSidebarTabs' ,
8271
@@ -85,6 +74,15 @@ export default {
8574 NcVNodes,
8675 },
8776
77+ provide () {
78+ return {
79+ registerTab: this .registerTab ,
80+ unregisterTab: this .unregisterTab ,
81+ // Getter as an alternative to Vue 2.7 computed(() => this.activeTab)
82+ getActiveTab : () => this .activeTab ,
83+ }
84+ },
85+
8886 props: {
8987 /**
9088 * Id of the tab to activate
@@ -107,10 +105,6 @@ export default {
107105 * The id of the currently active tab.
108106 */
109107 activeTab: ' ' ,
110- /**
111- * Dummy array to react on slot changes.
112- */
113- children: [],
114108 }
115109 },
116110
@@ -130,18 +124,6 @@ export default {
130124 this .updateActive ()
131125 }
132126 },
133-
134- children () {
135- this .updateTabs ()
136- },
137- },
138-
139- mounted () {
140- // Init the tabs list
141- this .updateTabs ()
142-
143- // Let's make the children list reactive
144- this .children = this .$children
145127 },
146128
147129 methods: {
@@ -216,62 +198,42 @@ export default {
216198 */
217199 updateActive () {
218200 this .activeTab = this .active
219- && this .tabs .findIndex (tab => tab .id === this .active ) !== - 1
201+ && this .tabs .some (tab => tab .id === this .active )
220202 ? this .active
221203 : this .tabs .length > 0
222204 ? this .tabs [0 ].id
223205 : ' '
224206 },
225207
226- hasMdIcon (tab ) {
227- return tab? .$slots ? .icon
228- },
229-
230208 /**
231- * Manually update the sidebar tabs according to $slots.default
209+ * Register child tab in the tabs
210+ *
211+ * @param {object} tab - tab props (only the "id" is used actually)
232212 */
233- updateTabs () {
234- if (! this .$slots .default ) {
235- this .tabs = []
236- return
237- }
238-
239- // Find all valid children (AppSidebarTab, other components, text nodes, etc.)
240- const children = this .$slots .default .filter (elem => elem .tag || elem .text .trim ())
241-
242- // Find all valid instances of AppSidebarTab
243- const invalidTabs = []
244- const tabs = children .reduce ((tabs , tabNode ) => {
245- const tab = tabNode .componentInstance
246- // Make sure all required props are provided and valid
247- if (IsValidString (tab? .name )
248- && IsValidStringWithoutSpaces (tab? .id )
249- && (IsValidStringWithoutSpaces (tab? .icon ) || tab? .$slots ? .icon )) {
250- tabs .push (tab)
251- } else {
252- invalidTabs .push (tabNode)
253- }
254- return tabs
255- }, [])
256-
257- // Tabs are optional, but you can use either tabs or non-tab-content only
258- if (tabs .length !== 0 && tabs .length !== children .length ) {
259- Vue .util .warn (' Mixing tabs and non-tab-content is not possible.' )
260- invalidTabs .map (invalid => console .debug (' Ignoring invalid tab' , invalid))
261- }
262-
263- // We sort the tabs by their order or by their name
264- this .tabs = tabs .sort ((a , b ) => {
265- const orderA = a .order || 0
266- const orderB = b .order || 0
267- if (orderA === orderB) {
213+ registerTab (tab ) {
214+ this .tabs .push (tab)
215+ this .tabs .sort ((a , b ) => {
216+ if (a .order === b .order ) {
268217 return OC .Util .naturalSortCompare (a .name , b .name )
269218 }
270- return orderA - orderB
219+ return a . order - b . order
271220 })
221+ if (! this .activeTab ) {
222+ this .updateActive ()
223+ }
224+ },
272225
273- // Init active tab if exists
274- if (this .tabs .length > 0 ) {
226+ /**
227+ * Unregister child tab in the tabs
228+ *
229+ * @param {string} id - tab's id
230+ */
231+ unregisterTab (id ) {
232+ const tabIndex = this .tabs .findIndex ((tab ) => tab .id === id)
233+ if (tabIndex !== - 1 ) {
234+ this .tabs .splice (tabIndex, 1 )
235+ }
236+ if (this .activeTab === id) {
275237 this .updateActive ()
276238 }
277239 },
0 commit comments