TranscendencePopover closes properly
This commit is contained in:
parent
46467a354f
commit
e5a1fb7b1e
3 changed files with 127 additions and 96 deletions
|
|
@ -17,6 +17,7 @@ interface Props
|
||||||
HTMLDivElement
|
HTMLDivElement
|
||||||
> {
|
> {
|
||||||
type: 'character' | 'summon'
|
type: 'character' | 'summon'
|
||||||
|
starRef: React.RefObject<HTMLDivElement>
|
||||||
open: boolean
|
open: boolean
|
||||||
stage: number
|
stage: number
|
||||||
onOpenChange?: (open: boolean) => void
|
onOpenChange?: (open: boolean) => void
|
||||||
|
|
@ -24,8 +25,9 @@ interface Props
|
||||||
}
|
}
|
||||||
|
|
||||||
const TranscendencePopover = ({
|
const TranscendencePopover = ({
|
||||||
children,
|
|
||||||
open: popoverOpen,
|
open: popoverOpen,
|
||||||
|
starRef,
|
||||||
|
children,
|
||||||
type,
|
type,
|
||||||
stage,
|
stage,
|
||||||
tabIndex,
|
tabIndex,
|
||||||
|
|
@ -45,8 +47,8 @@ const TranscendencePopover = ({
|
||||||
})
|
})
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (open) popoverRef.current?.focus()
|
setOpen(popoverOpen)
|
||||||
}, [])
|
}, [popoverOpen])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (stage) setCurrentStage(stage)
|
if (stage) setCurrentStage(stage)
|
||||||
|
|
@ -57,10 +59,6 @@ const TranscendencePopover = ({
|
||||||
else if (type === 'summon') setBaseLevel(200)
|
else if (type === 'summon') setBaseLevel(200)
|
||||||
}, [type])
|
}, [type])
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setOpen(popoverOpen)
|
|
||||||
}, [popoverOpen])
|
|
||||||
|
|
||||||
function handleFragmentClicked(newStage: number) {
|
function handleFragmentClicked(newStage: number) {
|
||||||
setCurrentStage(newStage)
|
setCurrentStage(newStage)
|
||||||
if (sendValue) sendValue(newStage)
|
if (sendValue) sendValue(newStage)
|
||||||
|
|
@ -70,13 +68,33 @@ const TranscendencePopover = ({
|
||||||
setCurrentStage(newStage)
|
setCurrentStage(newStage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function closePopover() {
|
||||||
|
setOpen(false)
|
||||||
|
if (onOpenChange) onOpenChange(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
function handlePointerDownOutside(
|
||||||
|
event: CustomEvent<{ originalEvent: PointerEvent }>
|
||||||
|
) {
|
||||||
|
const target = event.detail.originalEvent.target as Element
|
||||||
|
if (
|
||||||
|
target &&
|
||||||
|
starRef.current &&
|
||||||
|
target.closest('.TranscendenceStar') !== starRef.current
|
||||||
|
) {
|
||||||
|
closePopover()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Popover open={open} onOpenChange={onOpenChange}>
|
<Popover open={open}>
|
||||||
<PopoverAnchor>{children}</PopoverAnchor>
|
<PopoverAnchor>{children}</PopoverAnchor>
|
||||||
<PopoverContent
|
<PopoverContent
|
||||||
className={styles.transcendence}
|
className="transcendence"
|
||||||
ref={popoverRef}
|
ref={popoverRef}
|
||||||
tabIndex={tabIndex}
|
tabIndex={tabIndex}
|
||||||
|
onEscapeKeyDown={closePopover}
|
||||||
|
onPointerDownOutside={handlePointerDownOutside}
|
||||||
>
|
>
|
||||||
<TranscendenceStar
|
<TranscendenceStar
|
||||||
className="interactive base"
|
className="interactive base"
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,9 @@ interface Props
|
||||||
|
|
||||||
const NUM_FRAGMENTS = 5
|
const NUM_FRAGMENTS = 5
|
||||||
|
|
||||||
const TranscendenceStar = ({
|
const TranscendenceStar = React.forwardRef<HTMLDivElement, Props>(
|
||||||
|
function TranscendenceStar(
|
||||||
|
{
|
||||||
className,
|
className,
|
||||||
interactive,
|
interactive,
|
||||||
stage,
|
stage,
|
||||||
|
|
@ -29,13 +31,16 @@ const TranscendenceStar = ({
|
||||||
onStarClick,
|
onStarClick,
|
||||||
onFragmentClick,
|
onFragmentClick,
|
||||||
onFragmentHover,
|
onFragmentHover,
|
||||||
}: Props) => {
|
}: Props,
|
||||||
|
forwardedRef
|
||||||
|
) {
|
||||||
const [visibleStage, setVisibleStage] = useState(0)
|
const [visibleStage, setVisibleStage] = useState(0)
|
||||||
const [currentStage, setCurrentStage] = useState(0)
|
const [currentStage, setCurrentStage] = useState(0)
|
||||||
const [immutable, setImmutable] = useState(false)
|
const [immutable, setImmutable] = useState(false)
|
||||||
|
|
||||||
// Classes
|
// Classes
|
||||||
const starClasses = classnames({
|
const starClasses = classnames({
|
||||||
|
TranscendenceStar: true,
|
||||||
[styles.star]: true,
|
[styles.star]: true,
|
||||||
[styles.immutable]: immutable,
|
[styles.immutable]: immutable,
|
||||||
[styles.empty]: stage === 0,
|
[styles.empty]: stage === 0,
|
||||||
|
|
@ -59,9 +64,7 @@ const TranscendenceStar = ({
|
||||||
}, [stage])
|
}, [stage])
|
||||||
|
|
||||||
function handleClick() {
|
function handleClick() {
|
||||||
if (onStarClick) {
|
if (onStarClick) onStarClick()
|
||||||
onStarClick()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleFragmentClick(index: number) {
|
function handleFragmentClick(index: number) {
|
||||||
|
|
@ -88,6 +91,7 @@ const TranscendenceStar = ({
|
||||||
className={starClasses}
|
className={starClasses}
|
||||||
onClick={editable ? handleClick : () => {}}
|
onClick={editable ? handleClick : () => {}}
|
||||||
onMouseLeave={interactive ? handleMouseLeave : () => {}}
|
onMouseLeave={interactive ? handleMouseLeave : () => {}}
|
||||||
|
ref={forwardedRef}
|
||||||
tabIndex={tabIndex}
|
tabIndex={tabIndex}
|
||||||
>
|
>
|
||||||
<div className={styles.fragments}>
|
<div className={styles.fragments}>
|
||||||
|
|
@ -110,7 +114,8 @@ const TranscendenceStar = ({
|
||||||
<i className={baseImageClasses} />
|
<i className={baseImageClasses} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
TranscendenceStar.defaultProps = {
|
TranscendenceStar.defaultProps = {
|
||||||
stage: 0,
|
stage: 0,
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@ const UncapIndicator = (props: Props) => {
|
||||||
|
|
||||||
const [popoverOpen, setPopoverOpen] = useState(false)
|
const [popoverOpen, setPopoverOpen] = useState(false)
|
||||||
|
|
||||||
|
const transcendenceStarRef = React.createRef<HTMLDivElement>()
|
||||||
|
|
||||||
const classes = classNames(
|
const classes = classNames(
|
||||||
{
|
{
|
||||||
[styles.wrapper]: true,
|
[styles.wrapper]: true,
|
||||||
|
|
@ -82,7 +84,11 @@ const UncapIndicator = (props: Props) => {
|
||||||
|
|
||||||
function sendTranscendenceStage(stage: number) {
|
function sendTranscendenceStage(stage: number) {
|
||||||
if (props.updateTranscendence) props.updateTranscendence(stage)
|
if (props.updateTranscendence) props.updateTranscendence(stage)
|
||||||
togglePopover(false)
|
setPopoverOpen(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleStarClicked() {
|
||||||
|
if (props.editable) togglePopover(!popoverOpen)
|
||||||
}
|
}
|
||||||
|
|
||||||
const transcendence = (i: number) => {
|
const transcendence = (i: number) => {
|
||||||
|
|
@ -90,25 +96,27 @@ const UncapIndicator = (props: Props) => {
|
||||||
return props.type === 'character' || props.type === 'summon' ? (
|
return props.type === 'character' || props.type === 'summon' ? (
|
||||||
<TranscendencePopover
|
<TranscendencePopover
|
||||||
open={popoverOpen}
|
open={popoverOpen}
|
||||||
stage={props.transcendenceStage ? props.transcendenceStage : 0}
|
stage={props.transcendenceStage || 0}
|
||||||
type={props.type}
|
type={props.type}
|
||||||
onOpenChange={togglePopover}
|
onOpenChange={togglePopover}
|
||||||
sendValue={sendTranscendenceStage}
|
sendValue={sendTranscendenceStage}
|
||||||
key={`star_${i}`}
|
key={`popover_${i}_${popoverOpen}`}
|
||||||
|
starRef={transcendenceStarRef}
|
||||||
tabIndex={tabIndex}
|
tabIndex={tabIndex}
|
||||||
>
|
>
|
||||||
<TranscendenceStar
|
<TranscendenceStar
|
||||||
key={`star_${i}`}
|
key={`star_${i}`}
|
||||||
stage={props.transcendenceStage}
|
stage={props.transcendenceStage || 0}
|
||||||
editable={props.editable}
|
editable={props.editable}
|
||||||
interactive={false}
|
interactive={false}
|
||||||
onStarClick={() => togglePopover(true)}
|
ref={transcendenceStarRef}
|
||||||
|
onStarClick={handleStarClicked}
|
||||||
/>
|
/>
|
||||||
</TranscendencePopover>
|
</TranscendencePopover>
|
||||||
) : (
|
) : (
|
||||||
<TranscendenceStar
|
<TranscendenceStar
|
||||||
key={`star_${i}`}
|
key={`star_${i}`}
|
||||||
stage={props.transcendenceStage}
|
stage={props.transcendenceStage || 0}
|
||||||
editable={props.editable}
|
editable={props.editable}
|
||||||
interactive={false}
|
interactive={false}
|
||||||
tabIndex={tabIndex}
|
tabIndex={tabIndex}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue