All files / lib/components breadcrumb.vue

82.86% Statements 29/35
78.26% Branches 18/23
88.89% Functions 8/9
82.86% Lines 29/35
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 9418x 18x 18x   18x 18x                     18x       18x     18x                                             18x   18x       14x 14x   14x 56x     56x     56x     56x         56x 28x 28x     7x     56x   35x           56x 231x 84x     231x    
<template>
    <ol class="breadcrumb">
    I    <li v-for="normalizedItem in normalizedItems"
            :class="['breadcrumb-item', normalizedItem.active ? 'active' : null]"
           E @click="onClick(normalizedItem._originalItem)"
            role="presentation">
            <span v-if="normalizedItem.active"
                  :aria-current="ariaCurrent"
                  v-html="normalizedItem.text"></span>
            <b-link v-else
                    v-bind="normalizedItem._linkProps"
                    v-html="normalizedItem.text"></b-link>
        </li>
        <slot></slot>
    </ol>
</template>
 
<script>
import bLink from './link.vue';
import { props as linkProps } from '../mixins/link';
import { arrayIncludes } from '../utils/array';
import { assign, keys } from '../utils/object';
 
const bLinkPropKeys = keys(linkProps);
 
export default {
    components: { bLink },
    computed: {
        normalizedItems() {
            let userDefinedActive = false;
            const originalItemsLength = this.items.length;
 
            return this.items.map((item, index) => {
                let normalizedItem = { _originalItem: item };
                // if no active state is defined,
                // default to the last item in the array as active
                const isLast = index === originalItemsLength - 1;
 
                // nothing defined except the text
                if (typeof item === 'string') {
                    assign(normalizedItem, { text: item, link: '#', active: isLast });
                } else {
                    assign(normalizedItem, item);
                }
 
                // don't default the active state if given a boolean value,
                // or if a user defined value has already been given
                if (normalizedItem.active !== true && normalizedItem.active !== false && !userDefinedActive) {
                    normalizedItem.active = isLast;
                } else if (normalizedItem.active) {
                    // here we know we've been given an active value,
                    // so we won't set a default value
                    userDefinedActive = true;
                }
 
                if (normalizedItem.link) {
                    // default the link value to bLink's href prop
                    normalizedItem.href = normalizedItem.link;
                }
 
                // stuff all the bLink props into a single place
                // so we can bind to the component
                // fIor dynamic prop proxying
                normalizedItem._linkProps = keys(normalizedItem).reduce((memo, itemProp) => {
                    if (arrayIncludes(bLinkPropKeys, itemProp)) {
                        memo[itemProp] = normalizedItem[itemProp];
                    }
 
                    return memo;
                }, {});
 
                return normalizedItem;
            });
        }
    },
    props: {
        items: {
            type: Array,
            default: () => [],
            required: true
        },
        ariaCurrent: {
            type: String,
            default: 'location'
        }
    },
    methods: {
        onClick(item) {
            this.$emit('click', item);
        }
    }
};
</script>