import { html } from 'lit'
import { customElement, property, state } from 'lit/decorators.js'
import { TailwindElement } from '@/shared/tailwind-element'
import { customClassMap } from '@/shared/directives'
export type ButtonVariants = 'primary' | 'secondary' | 'landing' | 'link'
export type ButtonSizes = 'small' | 'medium'
const LONG_PRESS_ANIMATION_DURATION_IN_MS = 2000
@customElement('lukso-button')
export class LuksoButton extends TailwindElement {
@property({ type: String })
variant: ButtonVariants = 'primary'
@property({ type: String })
size: ButtonSizes = 'medium'
@property({ type: Boolean })
disabled = false
@property({ type: Boolean, attribute: 'is-full-width' })
isFullWidth = false
@property({ type: Boolean, attribute: 'is-long-press' })
isLongPress = false
@state()
private isPressed = false
@state()
private noTransition = false
@state()
private timer = 0
private defaultStyles = `flex justify-center items-center relative
border border-solid cursor-pointer transition duration-0
hover:duration-250 active:scale-98 active:duration-25
disabled:shadow-none disabled:cursor-not-allowed disabled:scale-100`
private secondaryStyles = `bg-neutral-100 border-neutral-90 text-neutral-20
disabled:bg-neutral-90 disabled:border-neutral-90 disabled:text-neutral-100
hover:shadow-button-hover-secondary active:shadow-button-press-secondary`
private primaryStyles = `bg-neutral-20 border-neutral-20 text-neutral-100
disabled:bg-neutral-90 disabled:border-neutral-90
hover:shadow-button-hover-primary hover:bg-neutral-25 hover:border-neutral-25
active:shadow-button-press-primary active:bg-neutral-25 active:border-neutral-25
before:bg-neutral-10`
private landingStyles = `bg-purple-51 border-purple-51 text-neutral-100
disabled:bg-neutral-90 disabled:border-neutral-90
hover:shadow-button-hover-primary hover:bg-purple-58 hover:border-purple-58
active:shadow-button-press-primary
before:bg-purple-51`
private linkStyles = `bg-transparent border-none text-neutral-20
hover:text-neutral-35
active:text-neutral-35 active:scale-100
disabled:text-neutral-90`
private longPressStyles = `relative overflow-hidden z-[1] active:outline-0
before:absolute before:content-[''] before:top-0 before:left-0 before:w-0 before:h-[48px]
before:transition-all before:duration-[2000ms] before:z-[-1] before:rounded-none`
private pressedStyles = `before:w-full before:z-[-1]`
private noTransitionStyles = `before:transition-none`
private mediumSize = `py-3 px-6 paragraph-16-semi-bold rounded-xl`
private smallSize = `py-1 px-3 paragraph-12-regular rounded-lg hover:shadow-none active:shadow-none`
private handleMouseDown() {
// Additional check for using long press on non-primary and non-landing variants
if (this.variant !== 'primary' && this.variant !== 'landing') {
return console.warn(
'Long press is only available for primary and landing variants'
)
}
if (!this.isLongPress) {
return
}
this.isPressed = true
this.timer = window.setTimeout(() => {
const event = new CustomEvent('on-long-press-complete', {
bubbles: true,
composed: true,
})
this.dispatchEvent(event)
}, LONG_PRESS_ANIMATION_DURATION_IN_MS)
}
private handleMouseUp() {
if (!this.isLongPress) {
return
}
this.isPressed = false
this.noTransition = true
setTimeout(() => {
this.noTransition = false
}, 100)
this.timer && clearTimeout(this.timer)
}
render() {
return html`
`
}
}
declare global {
interface HTMLElementTagNameMap {
'lukso-button': LuksoButton
}
}