UNPKG

vira

Version:

A simple and highly versatile design system using element-vir.

81 lines (77 loc) 2.52 kB
import { css, defineElementEvent, html, listen, onResize } from 'element-vir'; import { noNativeFormStyles, viraAnimationDurations } from '../styles/index.js'; import { defineViraElement } from './define-vira-element.js'; /** * A wrapper element that can collapse and expand to fit its content dynamically and efficiently. * * @category Collapsible * @category Elements * @see https://electrovir.github.io/element-vir/vira/book/elements/vira-collapsible-wrapper */ export const ViraCollapsibleWrapper = defineViraElement()({ tagName: 'vira-collapsible-wrapper', state() { return { contentHeight: 0, }; }, hostClasses: { 'vira-collapsible-wrapper-expanded': ({ inputs }) => inputs.expanded, }, slotNames: ['header'], styles: ({ hostClasses }) => css ` :host { display: flex; flex-direction: column; } .header-wrapper { ${noNativeFormStyles}; cursor: pointer; } .content-wrapper, .collapsing-element { display: flex; flex-direction: column; box-sizing: border-box; } .collapsing-element { transition: height ${viraAnimationDurations['vira-pretty-animation-duration'].value}; overflow: hidden; } ${hostClasses['vira-collapsible-wrapper-expanded'].name} .collapsing-element { pointer-events: none; } `, events: { expandChange: defineElementEvent(), }, render({ state, slotNames, updateState, dispatch, events, inputs }) { const collapsingStyles = inputs.expanded ? css ` height: ${state.contentHeight}px; ` : css ` height: 0; `; return html ` <button class="header-wrapper" ${listen('click', () => { dispatch(new events.expandChange(!inputs.expanded)); })} > <slot name=${slotNames.header}>Header</slot> </button> <div class="collapsing-element" style=${collapsingStyles} disabled="disabled"> <div ${onResize(({ contentRect }) => { updateState({ contentHeight: contentRect.height }); })} class="content-wrapper" > <slot></slot> </div> </div> `; }, });