three.cad/src/react/dropDown.jsx

85 lines
2.3 KiB
React
Raw Normal View History

import React, { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux'
2021-04-24 07:22:33 +08:00
import { sce, pako } from './app'
2021-04-24 04:13:49 +08:00
2021-04-24 07:22:33 +08:00
const utf8decoder = new TextDecoder();
export const DropDown = () => {
const arr = [
2021-04-24 07:22:33 +08:00
['https://howardhwang.s3-us-west-1.amazonaws.com/headphone-stand.json.gz', 'headphone-stand'],
// ['headphone-stand.json.gz', 'headphone-stand'],
]
const dispatch = useDispatch()
const [open, setOpen] = useState(false)
const handleOutsideClick = (ev) => {
/*
this handles inside click as well due to bubbling,
sets the open/close state of drop down
*/
setOpen(state => !state) // handle click on button & dropdown, always a toggle
2021-04-24 07:22:33 +08:00
document.addEventListener( // handles click outside buttona & dropdown
'pointerdown',
2021-04-24 07:22:33 +08:00
(e) => { !e.composedPath().includes(ev.target.parentNode) && setOpen(false) }
,
{ capture: true, once: true } // capture phase to allow for stopPropogation on others
)
}
2021-04-24 04:13:49 +08:00
const handleInsideClick = async (e) => {
// handles click inside dropdown, business logic here
const idx = Array.prototype.indexOf.call(e.target.parentNode.children, e.target)
2021-04-24 07:22:33 +08:00
if (idx !== -1) {
2021-04-24 07:22:33 +08:00
setOpen(false)
const state = sce.loadState(
utf8decoder.decode(
new Zlib.Gunzip(
new Uint8Array(
await (
await (
await fetch(arr[idx][0])
).blob()
).arrayBuffer()
)
).decompress()
)
)
dispatch({ type: 'restore-state', state })
2021-04-24 04:13:49 +08:00
sce.render()
}
}
2021-04-24 07:22:33 +08:00
return <div className="cursor-pointer w-28 h-full overflow-visible relative select-none"
2021-04-24 07:22:33 +08:00
>
2021-04-24 07:22:33 +08:00
<div className="btn text-gray-200 h-full w-full flex items-center justify-center" onClick={handleOutsideClick}>
Demo Parts
</div>
{
open &&
<div className="absolute drop-down-top -left-10 w-48 p-1 rounded bg-gray-700"
onClick={handleInsideClick}
>
{arr.map(([url, name], idx) => (
<div className="w-full h-8 p-0.5 flex items-center bg-transparent text-gray-200
hover:bg-gray-500 "
key={idx}
>
{name}
</div>
))}
<div className="arrow"></div>
</div>
}
</div>
}