import {type CSSResultGroup, html, type PropertyValues, unsafeCSS} from 'lit';
import {property, state} from "lit/decorators.js";
import ZincElement from '../../internal/zinc-element';
import type {ZnChangeEvent} from "../../events/zn-change";
import styles from './audio-select.scss';
interface AudioFile {
name: string;
url: string;
}
/**
* @summary Short summary of the component's intended use.
* @documentation https://zinc.style/components/audio-select
* @status experimental
* @since 1.0
*
* @slot - The default slot.
* @slot actions - The actions slot.
* @slot footer - The footer slot.
*
* @csspart base - The component's base wrapper.
*
* @cssproperty --example - An example CSS custom property.
*/
export default class ZnAudioSelect extends ZincElement {
static styles: CSSResultGroup = unsafeCSS(styles);
@state() private _isPlaying: boolean = false;
private readonly _audio: HTMLAudioElement;
@property() value = '';
@property() label = '';
@property() placeholder = '';
@property({type: Object}) files: AudioFile[] = [];
constructor() {
super();
this._audio = new Audio();
// Handle audio ending naturally
this._audio.addEventListener('ended', () => {
this._isPlaying = false;
// Reset to start so pressing play again restarts the audio
this._audio.currentTime = 0;
});
}
disconnectedCallback() {
super.disconnectedCallback();
this.stopAudio();
}
updated(changedProperties: PropertyValues) {
super.updated(changedProperties);
if (changedProperties.has('value')) {
this.stopAudio();
if (this.value) {
this._audio.src = this.value;
}
}
}
stopAudio() {
if (this._audio) {
this._audio.pause();
this._audio.currentTime = 0;
}
this._isPlaying = false;
}
handleSelectChange(e: ZnChangeEvent) {
if (e.target !== e.currentTarget) {
return;
}
this.value = (e.target as HTMLSelectElement).value;
}
togglePreview(e: CustomEvent) {
e.stopPropagation();
if (!this.value) {
e.preventDefault();
this._isPlaying = false;
this.requestUpdate();
return;
}
if (this._isPlaying) {
this._audio.pause();
this._isPlaying = false;
} else {
this._audio.play()
.then(() => {
this._isPlaying = true;
})
.catch(err => {
console.error("Audio playback failed:", err);
this._isPlaying = false;
this.requestUpdate();
});
}
}
render() {
return html`
${this.placeholder || 'Select audio'}
${this.files.map(file => html`
${file.name}
`)}
`;
}
}