2023-09-29 16:01:27 +02:00
|
|
|
// __SDEFILE__ - This file is a dependency for the stand-alone environment
|
2023-06-29 16:41:11 +00:00
|
|
|
import { useContext, useState, useEffect } from 'react'
|
2023-06-29 14:35:46 +00:00
|
|
|
import { ModalContext } from 'shared/context/modal-context.mjs'
|
|
|
|
import { ModalWrapper } from 'shared/components/wrappers/modal.mjs'
|
|
|
|
import { CloseIcon } from 'shared/components/icons.mjs'
|
|
|
|
import { MobileMenubarContext } from 'shared/context/mobile-menubar-context.mjs'
|
2023-08-30 10:44:35 +02:00
|
|
|
import { MenuAltIcon } from 'shared/components/icons.mjs'
|
2023-06-29 14:35:46 +00:00
|
|
|
|
2023-06-29 17:29:13 +00:00
|
|
|
/**
|
|
|
|
* A component to display menu buttons and actions in mobile.
|
|
|
|
* Draws its contents from items added to the {@link MobileMenubarContext}
|
|
|
|
* @returns
|
|
|
|
*/
|
2023-06-29 14:35:46 +00:00
|
|
|
export const MobileMenubar = () => {
|
|
|
|
const { setModal, clearModal, modalContent } = useContext(ModalContext)
|
2023-06-29 15:44:23 +00:00
|
|
|
const { menus, actions } = useContext(MobileMenubarContext)
|
2023-06-29 14:35:46 +00:00
|
|
|
const [selectedModal, setSelectedModal] = useState(false)
|
|
|
|
|
2023-06-29 17:29:13 +00:00
|
|
|
// get the content of the selected modal because this is what will be changing if there are updates
|
2023-06-29 14:35:46 +00:00
|
|
|
const selectedMenu = menus[selectedModal]
|
|
|
|
|
2023-06-29 17:29:13 +00:00
|
|
|
// when the content changes, or the selection changes
|
2023-06-29 14:35:46 +00:00
|
|
|
useEffect(() => {
|
2023-06-29 16:41:11 +00:00
|
|
|
// there's no selected modal, we're in the clear
|
2023-06-29 14:35:46 +00:00
|
|
|
if (!selectedModal) return
|
|
|
|
|
2023-06-29 17:29:13 +00:00
|
|
|
// generate a new modal with the content
|
2023-06-29 16:41:11 +00:00
|
|
|
const Modal = () => {
|
|
|
|
const closeModal = () => {
|
|
|
|
setSelectedModal(false)
|
|
|
|
clearModal()
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<ModalWrapper
|
|
|
|
slideFrom="right"
|
|
|
|
keepOpenOnClick={selectedMenu.keepOpenOnClick}
|
|
|
|
keepOpenOnSwipe
|
2023-08-30 10:44:35 +02:00
|
|
|
fullWidth
|
2023-06-29 16:41:11 +00:00
|
|
|
>
|
|
|
|
<div className="mb-16">{selectedMenu.menuContent}</div>
|
|
|
|
<button
|
|
|
|
className="btn btn-accent btn-circle fixed bottom-4 right-4 z-20"
|
|
|
|
onClick={closeModal}
|
|
|
|
>
|
|
|
|
<CloseIcon />
|
|
|
|
</button>
|
|
|
|
</ModalWrapper>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2023-06-29 17:29:13 +00:00
|
|
|
// set it
|
2023-06-29 14:35:46 +00:00
|
|
|
setModal(Modal)
|
2023-06-29 16:41:11 +00:00
|
|
|
}, [selectedMenu, selectedModal, clearModal, setModal])
|
2023-06-29 14:35:46 +00:00
|
|
|
|
2023-06-29 17:29:13 +00:00
|
|
|
// clear the selection if the modal was cleared externally
|
2023-06-29 14:35:46 +00:00
|
|
|
useEffect(() => {
|
|
|
|
if (modalContent === null) {
|
|
|
|
setSelectedModal(false)
|
|
|
|
}
|
|
|
|
}, [modalContent, setSelectedModal])
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div
|
|
|
|
className={`
|
2023-06-29 17:29:13 +00:00
|
|
|
lg:hidden
|
|
|
|
sticky bottom-0 w-20 -ml-20 self-end
|
2023-08-30 10:44:35 +02:00
|
|
|
duration-300 transition-all
|
|
|
|
flex flex-col-reverse gap-2 mb-2
|
2023-06-29 17:29:13 +00:00
|
|
|
z-20
|
|
|
|
mobile-menubar
|
|
|
|
`}
|
2023-06-29 14:35:46 +00:00
|
|
|
>
|
|
|
|
{Object.keys(menus)
|
|
|
|
.sort((a, b) => menus[a].order - menus[b].order)
|
|
|
|
.map((m) => {
|
2023-08-30 10:44:35 +02:00
|
|
|
const Icon = m === 'nav' ? MenuAltIcon : menus[m].Icon
|
2023-06-29 14:35:46 +00:00
|
|
|
return (
|
|
|
|
<button
|
|
|
|
key={m}
|
2023-08-30 10:44:35 +02:00
|
|
|
className={`btn ${m === 'nav' ? 'btn-neutral' : 'btn-primary'} btn-circle mx-4`}
|
2023-06-29 14:35:46 +00:00
|
|
|
onClick={() => setSelectedModal(m)}
|
|
|
|
>
|
|
|
|
<Icon />
|
|
|
|
</button>
|
|
|
|
)
|
|
|
|
})}
|
2023-06-29 15:44:23 +00:00
|
|
|
{Object.keys(actions)
|
|
|
|
.sort((a, b) => actions[a].order - actions[b].order)
|
|
|
|
.map((a) => (
|
|
|
|
<div key={a}>{actions[a].actionContent}</div>
|
|
|
|
))}
|
2023-06-29 14:35:46 +00:00
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|