hensei-web/components/uncap/TranscendenceStar/index.tsx
Justin Edmund b50ea1fa31
(Hotfix) Popover and hovercard fixes (#379)
* Fix job accessory popover, so shields and manatura can be selected
again
* Don't show AX skill section in weapon hovercard if no AX skill is set
* Center uncap indicator under item image and fix hovercard header
layout
* Fix a bug that prevented all ring bonuses from displaying in hovercard
* Fix transcendence_step being set to 0 when updating a character's
masteries
* Fix weapon modal so you can set AX skills on weapons with rupee or exp
gain
* Ensure job accessory and transcendence popovers open/close properly
2023-09-01 16:13:39 -07:00

126 lines
3.1 KiB
TypeScript

import React, { useEffect, useState } from 'react'
import classnames from 'classnames'
import TranscendenceFragment from '~components/uncap/TranscendenceFragment'
import styles from './index.module.scss'
interface Props
extends React.DetailedHTMLProps<
React.DialogHTMLAttributes<HTMLDivElement>,
HTMLDivElement
> {
className?: string
stage: number
editable: boolean
interactive: boolean
onStarClick?: () => void
onFragmentClick?: (newStage: number) => void
onFragmentHover?: (newStage: number) => void
}
const NUM_FRAGMENTS = 5
const TranscendenceStar = React.forwardRef<HTMLDivElement, Props>(
function TranscendenceStar(
{
className,
interactive,
stage,
editable,
tabIndex,
onStarClick,
onFragmentClick,
onFragmentHover,
}: Props,
forwardedRef
) {
const [visibleStage, setVisibleStage] = useState(0)
const [currentStage, setCurrentStage] = useState(0)
const [immutable, setImmutable] = useState(false)
// Classes
const starClasses = classnames({
TranscendenceStar: true,
[styles.star]: true,
[styles.immutable]: immutable,
[styles.empty]: stage === 0,
[styles.stage1]: stage === 1,
[styles.stage2]: stage === 2,
[styles.stage3]: stage === 3,
[styles.stage4]: stage === 4,
[styles.stage5]: stage === 5,
})
const baseImageClasses = classnames(
{
[styles.figure]: true,
},
className?.split(' ').map((c) => styles[c])
)
useEffect(() => {
setVisibleStage(stage)
setCurrentStage(stage)
}, [stage])
function handleClick() {
if (onStarClick) onStarClick()
}
function handleFragmentClick(index: number) {
let newStage = index
if (index === currentStage) newStage = 0
setVisibleStage(newStage)
setCurrentStage(newStage)
if (onFragmentClick) onFragmentClick(newStage)
}
function handleFragmentHover(index: number) {
setVisibleStage(index)
if (onFragmentHover) onFragmentHover(index)
}
function handleMouseLeave() {
setVisibleStage(currentStage)
if (onFragmentHover) onFragmentHover(currentStage)
}
return (
<div
className={starClasses}
onClick={editable ? handleClick : () => {}}
onMouseLeave={interactive ? handleMouseLeave : () => {}}
ref={forwardedRef}
tabIndex={tabIndex}
>
<div className={styles.fragments}>
{[...Array(NUM_FRAGMENTS)].map((e, i) => {
const loopStage = i + 1
return interactive ? (
<TranscendenceFragment
key={`fragment_${loopStage}`}
stage={loopStage}
visible={loopStage <= visibleStage}
interactive={interactive}
onClick={handleFragmentClick}
onHover={handleFragmentHover}
/>
) : (
''
)
})}
</div>
<i className={baseImageClasses} />
</div>
)
}
)
TranscendenceStar.defaultProps = {
stage: 0,
editable: false,
interactive: false,
}
export default TranscendenceStar