diff --git a/lib/KBreadcrumbs.vue b/lib/KBreadcrumbs.vue index 589d7813b..daa79ae6b 100644 --- a/lib/KBreadcrumbs.vue +++ b/lib/KBreadcrumbs.vue @@ -1,137 +1,89 @@ + +
@@ -72,6 +87,13 @@ type: [Object, String], default: null, }, + overflowDirection: { + type: String, + default: 'start', + validator(value) { + return ['start', 'end'].includes(value); + }, + }, }, data() { return { @@ -122,7 +144,15 @@ if (!element) { return { width: 0, height: 0 }; } - const { width, height } = element.getBoundingClientRect(); + let { width, height } = element.getBoundingClientRect(); + + const style = element.currentStyle || window.getComputedStyle(element); + const marginX = parseFloat(style.marginLeft) + parseFloat(style.marginRight); + const marginY = parseFloat(style.marginTop) + parseFloat(style.marginBottom); + + width += marginX; + height += marginY; + return { width, height }; }, /** @@ -131,6 +161,7 @@ */ setOverflowItems() { const { list, listWrapper, moreButtonWrapper } = this.$refs; + if (!this.mounted || !listWrapper || !list) { this.overflowItems = []; return; @@ -153,15 +184,13 @@ const itemSize = this.getSize(item); itemsSizes.push(itemSize); } - + const indexSequence = [...Array(list.children.length).keys()]; + const directionIndexes = + this.overflowDirection === 'start' ? indexSequence.reverse() : indexSequence; const overflowItemsIdx = []; - for (let i = 0; i < list.children.length; i++) { - const item = list.children[i]; + directionIndexes.forEach(i => { const itemWidth = itemsSizes[i].width; - - // If the item dont fit in the available space or if we have already - // overflowed items, we hide it. This means that once one item overflows, - // all the following items will be hidden. + const item = list.children[i]; if (itemWidth >= availableWidth || overflowItemsIdx.length > 0) { overflowItemsIdx.push(i); item.style.visibility = 'hidden'; @@ -176,7 +205,7 @@ maxHeight = itemHeight; } } - } + }); // check if overflowed items would fit if the moreButton were not visible const overflowedWidth = overflowItemsIdx.reduce( @@ -188,6 +217,7 @@ const idx = overflowItemsIdx.pop(); const item = list.children[idx]; item.style.visibility = 'visible'; + item.style.position = 'unset'; maxWidth += itemsSizes[idx].width; } } @@ -203,6 +233,7 @@ list.style.maxWidth = `${maxWidth}px`; list.style.maxHeight = `${maxHeight}px`; }, + /** * Fixes the visibility of the dividers that are shown and hidden when the list overflows. * The visible list should not end with a divider, and the overflowed items should not @@ -217,16 +248,24 @@ } const { list } = this.$refs; - const [firstOverflowedIdx] = overflowItemsIdx; - if (this.isDivider(this.items[firstOverflowedIdx])) { - overflowItemsIdx.shift(); - } + if (this.overflowDirection === 'start') { + const [firstOverflowedIdx] = overflowItemsIdx; + const OverflowedIdx = list.children.length - 1 - firstOverflowedIdx; + if (this.isDivider(this.items[OverflowedIdx])) { + overflowItemsIdx.shift(); + } + } else { + const [firstOverflowedIdx] = overflowItemsIdx; + if (this.isDivider(this.items[firstOverflowedIdx])) { + overflowItemsIdx.shift(); + } - const lastVisibleIdx = firstOverflowedIdx - 1; - if (this.isDivider(this.items[lastVisibleIdx])) { - const dividerNode = list.children[lastVisibleIdx]; - dividerNode.style.visibility = 'hidden'; - return itemsSizes[lastVisibleIdx].width; + const lastVisibleIdx = firstOverflowedIdx - 1; + if (this.isDivider(this.items[lastVisibleIdx])) { + const dividerNode = list.children[lastVisibleIdx]; + dividerNode.style.visibility = 'hidden'; + return itemsSizes[lastVisibleIdx].width; + } } }, /** @@ -259,25 +298,26 @@ .list-wrapper { display: flex; - justify-content: space-between; + justify-content: flex-start; width: 100%; } .list { position: relative; display: flex; - flex-wrap: wrap; + flex-wrap: nowrap; align-items: center; - overflow: visible; + overflow: hidden; } .list > * { flex-shrink: 0; + min-width: 0; visibility: hidden; } .more-button-wrapper { - visibility: hidden; + visibility: visible; }