BAccordion is a simple Vue component that created an expanding and collapsing block. It uses the vue transition expand and can be paired with the Sass mixin accordion().

Vue Component

BpAccordion

Props

  • block - the block class (defaults to ‘accordion’)
  • headingElement - the heading element (defaults to ‘heading’)
  • contentElement - the content element (defaults to ‘content’)
  • id - A unique string to identify an accordion item for accessibility purposes (defaults to generating a random number)

Sass Mixin

@mixin accordion()

Parameters

None.

<bp-accordion class="accordion" :id="'content1'">
    <template #heading>
        <h3 class="accordion__heading">Content 1</h3>
    </template>
    <p>
        Amet consectetur dignissimos at sequi officiis? Debitis accusamus veritatis voluptatem quas quis? Optio velit maxime ipsam temporibus ratione, temporibus. Fugiat eligendi officiis <a href="#">impedit</a> voluptate recusandae. Veniam expedita velit aut ad.
    </p>
</bp-accordion>
<bp-accordion class="accordion" :id="'content2'">
    <template #heading>
        <h3 class="accordion__heading">Content 2</h3>
    </template>
    <p>
        Elit laboriosam ipsum dolorem earum quisquam consequuntur? Voluptatibus qui sed!
    </p>
</bp-accordion>
<bp-accordion class="accordion">
    <template #heading>
        <h3 class="accordion__heading">Content 3</h3>
    </template>
    <p>
        Ipsum voluptatem provident sit ab odio magni, repudiandae veritatis. Beatae nisi reprehenderit earum voluptates fugit nam. Explicabo laboriosam corporis sed est iusto veniam error. Sequi corrupti iusto sed itaque repudiandae saepe voluptas ipsa Ut et ab vitae temporibus repellat Cumque omnis autem culpa accusantium voluptatibus est? Molestiae voluptatem eaque vero?
    </p>
</bp-accordion>
<bp-accordion class="accordion" :id="'content4'">
    <template #heading>
        <h3 class="accordion__heading">Content 4</h3>
    </template>
    <p>
        Dolor reprehenderit ut fugiat necessitatibus debitis veniam in Tenetur deleniti suscipit dignissimos corporis expedita Vitae eum quia quia in modi adipisci voluptate nihil Ullam delectus assumenda consequatur aperiam nam explicabo!
    </p>
</bp-accordion>
<bp-accordion class="accordion" :id="'content5'">
    <template #heading>
        <h3 class="accordion__heading">Content 5</h3>
    </template>
    <p>
        Dolor quibusdam beatae sint provident nihil. Dolorem minus consectetur cumque voluptas fuga Soluta eaque quos aspernatur aliquam rerum. Exercitationem illum vel quod nemo fugiat totam. Optio et ducimus consequatur at
    </p>
</bp-accordion>
  • Content:
    <template>
        <div :class="[block, isOpen ? '-open' : '-closed' ]">
            <header>
                <div
                    :id="`${id}-control`"
                    :class="`${block}__${headerElement}`"
                    :aria-expanded="`${isOpen}`"
                    :aria-controls="id"
                    tabindex="0"
                    role="button"
                    @click="open"
                    @keyup.enter="open"
                >
                    <slot name="heading" />
                    <slot name="icon">
                        <svg :class="`${block}__icon`" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none">
                            <polyline points="6 9 12 15 18 9" />
                        </svg>
                    </slot>
                </div>
            </header>
            <transition
                name="accordion__transition"
                @enter="startTransition"
                @after-enter="endTransition"
                @before-leave="startTransition"
                @after-leave="endTransition"
            >
                <div
                    v-if="isOpen"
                    :id="id"
                    ref="content"
                    :class="`${block}__${contentElement}`"
                    :aria-labelledby="`${id}-control`"
                >
                    <slot />
                </div>
            </transition>
        </div>
    </template>
    <script>
    export default {
        props: {
            block: {
                type: String,
                default: 'accordion',
            },
            headerElement: {
                type: String,
                default: 'header',
            },
            contentElement: {
                type: String,
                default: 'content',
            },
            id: {
                type: String,
                default: () => Math.random().toString(36).substr(2),
            },
        },
        data: () => ({ isOpen: false }),
        methods: {
            open () {
                this.isOpen = !this.isOpen
            },
    
            /**
             * The following methods and transition hooks are necessary to work
             * around the fact that CSS transitions can't navigate to auto values.
             */
            startTransition (el) {
                el.style.height = el.scrollHeight + 'px'
            },
            endTransition (el) {
                el.style.height = ''
            },
        },
    }
    </script>
    
  • URL: /components/raw/accordion/BpAccordion.vue
  • Filesystem Path: resources/styles/molecules/accordion/BpAccordion.vue
  • Size: 2.3 KB
  • Content:
    ///
    /// ACCORDION
    ///
    /// ACCORDION requires the accordion.plugin.js file. Call the ACCORDION
    /// function on your outer element (in our example we use an .accordion div).
    /// You can pass in optional plugin options. See the demo page for a list.
    /// Within the outer element class each accordion item requires a div wrapper.
    /// Within the div wrapper there is a .header class and a .content class.
    ///
    @mixin accordion() {
        box-shadow: $med-shadow;
        margin-bottom: 1.5rem;
        $b: &;
    
        &__header {
            cursor: pointer;
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: $thin-padding;
        }
    
        &__heading {
            margin-bottom: 0;
        }
    
        &__content {
            border-top: 1px solid $gray-100;
            padding: $thin-v-space 0;
            margin: 0 1rem;
        }
    
        &__icon {
            transition: transform $fast $ease-out-quint;
        }
    
        &.-open {
            #{$b}__icon {
                transform: rotate(-180deg);
            }
        }
    
        &__transition {
            &-enter,
            &-leave-to {
                height: 0 !important;
            }
    
            &-enter-active,
            &-leave-active {
                transition: height $moderate $entrance-easing;
                overflow: hidden;
            }
        }
    }
    
    .accordion {
        @include accordion;
    }
    
  • URL: /components/raw/accordion/accordion.scss
  • Filesystem Path: resources/styles/molecules/accordion/accordion.scss
  • Size: 1.3 KB