Make modal open on ContextMenuItem select

This commit is contained in:
Justin Edmund 2023-01-06 03:04:41 -08:00
parent 12a01ef31d
commit 40e218deb2
4 changed files with 90 additions and 22 deletions

View file

@ -1,11 +1,13 @@
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { useSnapshot } from 'valtio' import { useSnapshot } from 'valtio'
import { useTranslation } from 'next-i18next' import { Trans, useTranslation } from 'next-i18next'
import classnames from 'classnames' import classnames from 'classnames'
import Alert from '~components/Alert'
import Button from '~components/Button' import Button from '~components/Button'
import CharacterHovercard from '~components/CharacterHovercard' import CharacterHovercard from '~components/CharacterHovercard'
import CharacterModal from '~components/CharacterModal'
import { import {
ContextMenu, ContextMenu,
ContextMenuTrigger, ContextMenuTrigger,
@ -23,6 +25,7 @@ import SettingsIcon from '~public/icons/Settings.svg'
import type { SearchableObject } from '~types' import type { SearchableObject } from '~types'
import './index.scss' import './index.scss'
import { Dialog } from '~components/Dialog'
interface Props { interface Props {
gridCharacter?: GridCharacter gridCharacter?: GridCharacter
@ -30,6 +33,7 @@ interface Props {
editable: boolean editable: boolean
updateObject: (object: SearchableObject, position: number) => void updateObject: (object: SearchableObject, position: number) => void
updateUncap: (id: string, position: number, uncap: number) => void updateUncap: (id: string, position: number, uncap: number) => void
removeCharacter: (id: string) => void
} }
const CharacterUnit = (props: Props) => { const CharacterUnit = (props: Props) => {
@ -49,6 +53,9 @@ const CharacterUnit = (props: Props) => {
filled: props.gridCharacter !== undefined, filled: props.gridCharacter !== undefined,
}) })
const [modalOpen, setModalOpen] = useState(false)
const [alertOpen, setAlertOpen] = useState(false)
const gridCharacter = props.gridCharacter const gridCharacter = props.gridCharacter
const character = gridCharacter?.object const character = gridCharacter?.object
@ -115,22 +122,71 @@ const CharacterUnit = (props: Props) => {
</SearchModal> </SearchModal>
) )
const contextMenu = () => { function openCharacterModal(event: Event) {
return props.editable && gridCharacter && gridCharacter.id ? ( setModalOpen(true)
<ContextMenu> }
<ContextMenuTrigger asChild>
<Button accessoryIcon={<SettingsIcon />} className="Options" /> function onCharacterModalOpenChange(open: boolean) {
</ContextMenuTrigger> setModalOpen(open)
<ContextMenuContent align="start"> }
<ContextMenuItem>Modify character</ContextMenuItem>
<ContextMenuItem>Remove from grid</ContextMenuItem> function openRemoveCharacterAlert() {
</ContextMenuContent> setAlertOpen(true)
</ContextMenu> }
) : (
'' function removeCharacter() {
if (gridCharacter) props.removeCharacter(gridCharacter.id)
}
const removeAlert = () => {
return (
<Alert
open={alertOpen}
primaryAction={removeCharacter}
primaryActionText={t('modals.characters.buttons.remove')}
cancelAction={() => setAlertOpen(false)}
cancelActionText={t('buttons.cancel')}
message={
<Trans i18nKey="modals.characters.messages.remove">
Are you sure you want to remove{' '}
<strong>{{ character: gridCharacter?.object.name[locale] }}</strong>{' '}
from your team?
</Trans>
}
/>
) )
} }
const contextMenu = () => {
if (props.editable && gridCharacter && gridCharacter.id) {
return (
<>
<ContextMenu>
<ContextMenuTrigger asChild>
<Button accessoryIcon={<SettingsIcon />} className="Options" />
</ContextMenuTrigger>
<ContextMenuContent align="start">
<ContextMenuItem onSelect={openCharacterModal}>
Modify character
</ContextMenuItem>
<ContextMenuItem onSelect={openRemoveCharacterAlert}>
Remove from grid
</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>
<CharacterModal
gridCharacter={gridCharacter}
open={modalOpen}
onOpenChange={onCharacterModalOpenChange}
/>
{removeAlert()}
</>
)
}
}
//
const unitContent = ( const unitContent = (
<div className={classes}> <div className={classes}>
{contextMenu()} {contextMenu()}

View file

@ -4,11 +4,11 @@ import { DropdownMenuItem } from '@radix-ui/react-dropdown-menu'
import './index.scss' import './index.scss'
interface Props interface Props {
extends React.DetailedHTMLProps< className?: string
React.DialogHTMLAttributes<HTMLDivElement>, onSelect?: (event: Event) => void
HTMLDivElement children: React.ReactNode
> {} }
const ContextMenuItem = React.forwardRef<HTMLDivElement, Props>( const ContextMenuItem = React.forwardRef<HTMLDivElement, Props>(
function ContextMenu({ children, ...props }, forwardedRef) { function ContextMenu({ children, ...props }, forwardedRef) {
@ -19,7 +19,11 @@ const ContextMenuItem = React.forwardRef<HTMLDivElement, Props>(
props.className props.className
) )
return <DropdownMenuItem className={classes}>{children}</DropdownMenuItem> return (
<DropdownMenuItem className={classes} onSelect={props.onSelect}>
{children}
</DropdownMenuItem>
)
} }
) )

View file

@ -144,8 +144,12 @@
"earring": "Aetherial Mastery", "earring": "Aetherial Mastery",
"awakening": "Awakening" "awakening": "Awakening"
}, },
"messages": {
"remove": "Are you sure you want to remove <strong>{{character}}</strong> from your team?"
},
"buttons": { "buttons": {
"confirm": "Save character" "confirm": "Save character",
"remove": "Remove character"
} }
}, },
"conflict": { "conflict": {

View file

@ -144,8 +144,12 @@
"earring": "エーテリアルプラス", "earring": "エーテリアルプラス",
"awakening": "覚醒" "awakening": "覚醒"
}, },
"messages": {
"remove": "<strong>{{character}}</strong>を編成から削除しますか?"
},
"buttons": { "buttons": {
"confirm": "キャラクターを変更する" "confirm": "キャラクターを変更する",
"remove": "キャラクターを削除する"
} }
}, },
"conflict": { "conflict": {