You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
2.6 KiB
94 lines
2.6 KiB
import React, {useCallback, useEffect, useState} from "react";
|
|
import {ButtonStyling, ResponsiveButtonStyle, ResponsiveOptionsDropdown} from "./responsive-button.style.js";
|
|
|
|
const responsiveOptions = {
|
|
desktop: [1920, 1800, 1680, 1440, 1360, 1280, 1024],
|
|
tablet: [992, 768, 600],
|
|
mobile: [480, 414, 375, 360],
|
|
}
|
|
|
|
const defaultResponsiveOptions = {
|
|
reset: '100%',
|
|
desktop: responsiveOptions.desktop[0],
|
|
tablet: responsiveOptions.tablet[1],
|
|
mobile: responsiveOptions.mobile[2],
|
|
}
|
|
|
|
export function ResponsiveButton({mode, active, onSelect}) {
|
|
// active = true;
|
|
const [state, setState] = useState({open: true, breakpoint: defaultResponsiveOptions[mode]});
|
|
const updateState = (update) => {
|
|
// update.open = true;
|
|
setState(Object.assign({}, state, update));
|
|
}
|
|
|
|
useEffect(() => {
|
|
const closeDropdown = (e) => isEscHit(e) ? updateState({open: false}) : null;
|
|
|
|
if (state.open) {
|
|
document.addEventListener("keydown", closeDropdown);
|
|
}
|
|
|
|
// Unsubscribe from ESC listener.
|
|
return () => {
|
|
document.removeEventListener("keydown", closeDropdown);
|
|
}
|
|
});
|
|
|
|
// Blur event / Outside click
|
|
const outsideClickAction = async (e) => await isClickOutside(e) ? updateState({open: false}) : null;
|
|
const handleBlur = useCallback(outsideClickAction, []);
|
|
|
|
return <ResponsiveButtonStyle tabIndex='0' onBlur={handleBlur}>
|
|
<ButtonStyling data-mode={mode} data-active={active} onClick={() => select()}>{mode}</ButtonStyling>
|
|
{active && state.open && responsiveOptions[mode] &&
|
|
<ResponsiveOptionsDropdown>
|
|
{responsiveOptions[mode].map((breakpoint) => {
|
|
return <li>
|
|
<a className={state.breakpoint === breakpoint ? 'active' : ''} onClick={() => select(breakpoint)}>{breakpoint}</a>
|
|
</li>;
|
|
})}
|
|
</ResponsiveOptionsDropdown>
|
|
}
|
|
</ResponsiveButtonStyle>;
|
|
|
|
//
|
|
// Actions
|
|
//
|
|
|
|
function select(breakpoint = null) {
|
|
// Click on option in Dropdown.
|
|
if (breakpoint) {
|
|
updateState({open: false, breakpoint});
|
|
onSelect(breakpoint);
|
|
return;
|
|
}
|
|
|
|
// Click on device button.
|
|
if (!active) {
|
|
onSelect(state.breakpoint)
|
|
updateState({open: false});
|
|
} else {
|
|
updateState({open: true});
|
|
}
|
|
}
|
|
}
|
|
|
|
export function update(state, update) {
|
|
return Object.assign({}, state, update);
|
|
}
|
|
|
|
export async function isClickOutside(e) {
|
|
const currentTarget = e.currentTarget;
|
|
|
|
return new Promise(resolve => {
|
|
setTimeout(() => {
|
|
resolve(!currentTarget.contains(document.activeElement));
|
|
}, 100);
|
|
})
|
|
}
|
|
|
|
export function isEscHit(event) {
|
|
return event.key === 'Escape'
|
|
}
|
|
|
|
|