import { css, html } from "lit";
import { property } from "lit/decorators.js";
import { BaseElement } from "../../core/base-element.ts";
import { type ComponentSize } from "../theme-context.ts";
/**
* A minimal chevron button that rotates between up/down states
*
* @element cf-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: ComponentSize (default: "md")
*
* @fires cf-toggle - Fired when button is clicked
*
* @example
*
*/
export class CFChevronButton 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(--cf-theme-color-text-muted, #999);
transition: color 200ms ease;
}
.chevron-button:hover {
color: var(--cf-theme-color-text, #666);
}
.chevron-button:active {
color: var(--cf-theme-color-text, #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="xs"]) .chevron-button {
padding: var(--cf-size-xs-padding-v, 2px) 0;
}
:host([size="sm"]) .chevron-button {
padding: var(--cf-size-sm-padding-v, 4px) 0;
}
:host([size="lg"]) .chevron-button {
padding: var(--cf-size-lg-padding-v, 8px) 0;
}
:host([size="xl"]) .chevron-button {
padding: var(--cf-size-xl-padding-v, 12px) 0;
}
svg {
width: var(--chevron-size, var(--cf-size-md-icon-lg, 24px));
height: var(--chevron-size, var(--cf-size-md-icon-lg, 24px));
}
:host([size="xs"]) svg {
--chevron-size: var(--cf-size-xs-icon-lg, 12px);
}
:host([size="sm"]) svg {
--chevron-size: var(--cf-size-sm-icon-lg, 16px);
}
:host([size="lg"]) svg {
--chevron-size: var(--cf-size-lg-icon-lg, 24px);
}
:host([size="xl"]) svg {
--chevron-size: var(--cf-size-xl-icon-lg, 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 })
accessor expanded = false;
@property({ type: Boolean, reflect: true })
accessor loading = false;
@property({ type: String, reflect: true })
accessor size: ComponentSize = "md";
constructor() {
super();
}
private _handleClick = () => {
this.emit("cf-toggle");
};
override render() {
return html`
`;
}
}