{"version":3,"sources":["../src/elements/accordion-panel.ts"],"sourcesContent":["import { html, LitElement } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { emitEvent } from '../utilities/events';\nimport { stylesPanel } from '../styles/elements/accordion';\n\n/**\n * @since 1.0.0\n * @status stable\n *\n * @tagname kemet-accordion-panel\n * @summary A blade for an accordion.\n *\n * @prop {boolean} opened - Determines the opened state of the panel\n * @prop {string} maxHeight - Sets the max height of the panel's body\n * @prop {string} slug - Uniquely identifies a panel for accessibility purposes\n *\n * @slot trigger - The trigger button that opens and closes the panel.\n * @slot body - The body content of the panel.\n * @slot icon - The icon for the panel.\n *\n * @csspart trigger - Contains the trigger for the panel.\n * @csspart body - Contains the body for the panel.\n *\n * @event kemet-opened - Fires when a panel is opened\n * @event kemet-closed - Fires when a panel is closed\n *\n */\n\n@customElement('kemet-accordion-panel')\nexport default class KemetAccordionPanel extends LitElement {\n  static styles = [stylesPanel];\n\n  @property({ type: Boolean, reflect: true })\n  opened: boolean | undefined = undefined;\n\n  @property({ type: String, attribute: 'max-height' })\n  maxHeight: string = '0px';\n\n  @property({ type: String })\n  slug: string = 'panel';\n\n  @property({ type: Number })\n  index: number;\n\n  /** @internal */\n  @state()\n  focusableSelector: string;\n\n  /** @internal */\n  @state()\n  bodyElement: HTMLElement | null;\n\n  /** @internal */\n  @state()\n  bodyElementFirst: HTMLElement | null | undefined;\n\n  /** @internal */\n  @state()\n  bodyElementLast: HTMLElement | null | undefined;\n\n  firstUpdated() {\n    this.focusableSelector = 'body, a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]';\n    this.bodyElement = this.querySelector('[slot=\"body\"]');\n    this.bodyElementFirst = this.bodyElement?.querySelector(':first-child');\n    this.bodyElementLast = this.bodyElement?.querySelector(':last-child');\n\n    if (this.bodyElementFirst) this.bodyElementFirst.style.marginTop = '0';\n    if (this.bodyElementLast) this.bodyElementLast.style.marginBottom = '0';\n  }\n\n  updated(prevProps: Map<string, never>) {\n    if (!prevProps.get('opened') && this.opened === true) {\n      this.maxHeight = `${this.bodyElement?.offsetHeight}px`;\n      emitEvent(this, 'kemet-opened', this);\n    }\n\n    if (prevProps.get('opened') && this.opened === false) {\n      this.maxHeight = '0px';\n      emitEvent(this, 'kemet-closed', this);\n    }\n\n    this.a11y();\n    this.focusableBodyElements();\n  }\n\n  render() {\n    return html`\n      <button\n        class=\"trigger\"\n        part=\"trigger\"\n        @click=${() => this.toggle()}\n        @keydown=${(event: KeyboardEvent) => this.handleKeyDown(event)}\n      >\n        <slot name=\"trigger\"></slot>\n        <slot name=\"icon\"></slot>\n      </button>\n      <section class=\"body\" part=\"body\" style=\"max-height:${this.maxHeight};\">\n        <slot name=\"body\"></slot>\n      </section>\n    `;\n  }\n\n  toggle() {\n    this.opened = !this.opened;\n  }\n\n  focusableBodyElements() {\n    const focusableElements = this.bodyElement?.querySelectorAll(this.focusableSelector);\n\n    if (this.opened) {\n      focusableElements?.forEach((element) => {\n        element.removeAttribute('tabindex');\n      });\n    } else {\n      focusableElements?.forEach((element) => {\n        element.setAttribute('tabindex', '-1');\n      });\n    }\n  }\n\n  a11y() {\n    const trigger = this.shadowRoot?.querySelector('.trigger');\n    const body = this.shadowRoot?.querySelector('.body');\n\n    trigger?.setAttribute('id', `${this.slug}-button`);\n    trigger?.setAttribute('aria-controls', `${this.slug}-content`);\n\n    body?.setAttribute('id', `${this.slug}-content`);\n    body?.setAttribute('aria-labelledby', `${this.slug}-button`);\n    body?.setAttribute('aria-hidden', `${!this.opened}`);\n  }\n\n  handleKeyDown(event: KeyboardEvent) {\n    if (event.key === 'Space' || event.key === 'Enter') {\n      this.toggle();\n    }\n  }\n}\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    'kemet-accordion-panel': KemetAccordionPanel\n  }\n}\n"],"mappings":"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","names":[]}