import { css, html } from "lit";
import { property } from "lit/decorators.js";
import { BaseElement } from "../../core/base-element.ts";
/**
* A minimal chevron button that rotates between up/down states
*
* @element ct-chevron-button
*
* @attr {boolean} expanded - Whether the chevron is in expanded (down) state
* @attr {boolean} loading - Whether to show loading animation instead of chevron
* @attr {string} size - Size variant: "sm" | "md" | "lg" (default: "md")
*
* @fires ct-toggle - Fired when button is clicked
*
* @example
*
*/
export class CTChevronButton extends BaseElement {
static override styles = [
BaseElement.baseStyles,
css`
:host {
display: block;
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
.chevron-button {
background: none;
border: none;
cursor: pointer;
padding: 0;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
color: var(--ct-theme-color-text-muted, var(--ct-color-gray-500, #999));
transition: color 200ms ease;
}
.chevron-button:hover {
color: var(--ct-theme-color-text, var(--ct-color-gray-700, #666));
}
.chevron-button:active {
color: var(--ct-theme-color-text, var(--ct-color-gray-900, #333));
}
.chevron-icon {
display: flex;
transition: transform 300ms cubic-bezier(0.34, 1.56, 0.64, 1);
}
:host([expanded]) .chevron-icon {
transform: rotate(180deg);
}
/* Size variants */
:host([size="sm"]) .chevron-button {
padding: 4px 0;
}
:host([size="lg"]) .chevron-button {
padding: 8px 0;
}
svg {
width: var(--chevron-size, 24px);
height: var(--chevron-size, 24px);
}
:host([size="sm"]) svg {
--chevron-size: 20px;
}
:host([size="lg"]) svg {
--chevron-size: 28px;
}
/* Loading animation - scrolling sine wave */
.loading-wave {
display: flex;
overflow: hidden;
width: var(--chevron-size, 24px);
}
.loading-wave svg {
width: 48px;
min-width: 48px;
animation: wave-scroll 0.8s linear infinite;
}
@keyframes wave-scroll {
0% {
transform: translateX(-12px);
}
100% {
transform: translateX(-24px);
}
}
`,
];
static override properties = {
expanded: { type: Boolean, reflect: true },
loading: { type: Boolean, reflect: true },
size: { type: String, reflect: true },
};
@property({ type: Boolean, reflect: true })
declare expanded: boolean;
@property({ type: Boolean, reflect: true })
declare loading: boolean;
@property({ type: String, reflect: true })
declare size: "sm" | "md" | "lg";
constructor() {
super();
this.expanded = false;
this.loading = false;
this.size = "md";
}
private _handleClick = () => {
this.emit("ct-toggle");
};
override render() {
return html`
`;
}
}
if (!globalThis.customElements.get("ct-chevron-button")) {
globalThis.customElements.define("ct-chevron-button", CTChevronButton);
}