Skip to content
Snippets Groups Projects
Commit f2308ba5 authored by chris's avatar chris
Browse files

replace questions dropdown

parent 14db45b7
No related branches found
No related tags found
1 merge request!458Hhmi accessibility
/* eslint-disable react/jsx-props-no-spreading */
/* eslint react/prop-types: 0 */ /* eslint react/prop-types: 0 */
import React, { import React, {
useMemo, useMemo,
......
/* eslint-disable no-underscore-dangle */ /* eslint-disable no-underscore-dangle */
import React, { useContext, useMemo, useEffect, useState } from 'react'; /* eslint react/prop-types: 0 */
import React, {
useMemo,
useContext,
useState,
useEffect,
useRef,
createRef,
} from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import { WaxContext, ReactDropDownStyles } from 'wax-prosemirror-core'; import { WaxContext, Icon } from 'wax-prosemirror-core';
import Dropdown from 'react-dropdown';
import { v4 as uuidv4 } from 'uuid';
const Wrapper = styled.div` const Wrapper = styled.div`
${ReactDropDownStyles}; opacity: ${props => (props.disabled ? '0.4' : '1')};
cursor: ${props => (props.disabled ? 'not-allowed' : 'pointer')};
`; `;
const DropdownStyled = styled(Dropdown)`
display: inline-flex; const DropDownButton = styled.button`
cursor: not-allowed; background: #fff;
opacity: ${props => (props.select ? 1 : 0.4)}; border: none;
pointer-events: ${props => (props.select ? 'default' : 'none')}; color: #000;
.Dropdown-control { cursor: pointer;
border: none; display: flex;
padding: 12px 122px 8px 10px; position: relative;
&:hover { width: 215px;
box-shadow: none; height: 100%;
}
span {
position: relative;
top: 12px;
} }
`;
const DropDownMenu = styled.div`
visibility: ${props => (props.isOpen ? 'visible' : 'hidden')};
background: #fff;
display: flex;
flex-direction: column;
border: 1px solid #ddd;
border-radius: 0.25rem;
box-shadow: 0 0.2rem 0.4rem rgb(0 0 0 / 10%);
margin: 2px auto auto;
position: absolute;
width: 220px;
max-height: 150px;
overflow-y: scroll;
z-index: 2;
.Dropdown-arrow { span {
top: 17px; cursor: pointer;
padding: 8px 10px;
} }
.Dropdown-menu { span:focus {
width: 100.4%; background: #f2f9fc;
display: flex; outline: 2px solid #f2f9fc;
flex-direction: column;
align-items: flex-start;
.Dropdown-option {
width: 100%;
}
} }
`; `;
const StyledIcon = styled(Icon)`
height: 18px;
width: 18px;
margin-left: auto;
position: relative;
top: 10px;
`;
const DropDownComponent = ({ view, tools }) => { const DropDownComponent = ({ view, tools }) => {
const context = useContext(WaxContext); const context = useContext(WaxContext);
const { const {
...@@ -45,6 +75,9 @@ const DropDownComponent = ({ view, tools }) => { ...@@ -45,6 +75,9 @@ const DropDownComponent = ({ view, tools }) => {
} = context; } = context;
const { state } = view; const { state } = view;
const itemRefs = useRef([]);
const [isOpen, setIsOpen] = useState(false);
const [label, setLabel] = useState(null); const [label, setLabel] = useState(null);
const isEditable = main.props.editable(editable => { const isEditable = main.props.editable(editable => {
return editable; return editable;
...@@ -104,27 +137,93 @@ const DropDownComponent = ({ view, tools }) => { ...@@ -104,27 +137,93 @@ const DropDownComponent = ({ view, tools }) => {
}); });
}, [activeViewId]); }, [activeViewId]);
let isDisabled = tools[0].select(state, activeView); let isDisabled = !tools[0].select(state, activeView);
useEffect(() => {
if (isDisabled) setIsOpen(false);
}, [isDisabled]);
const openCloseMenu = () => {
if (!isDisabled) setIsOpen(!isOpen);
if (isOpen)
setTimeout(() => {
activeView.focus();
});
};
if (!isEditable) isDisabled = false; if (!isEditable) isDisabled = false;
const onChange = option => { const onKeyDown = (e, index) => {
tools[option.value].run(main, context); e.preventDefault();
// arrow down
if (e.keyCode === 40) {
if (index === itemRefs.current.length - 1) {
itemRefs.current[0].current.focus();
} else {
itemRefs.current[index + 1].current.focus();
}
}
// arrow up
if (e.keyCode === 38) {
if (index === 0) {
itemRefs.current[itemRefs.current.length - 1].current.focus();
} else {
itemRefs.current[index - 1].current.focus();
}
}
// enter
if (e.keyCode === 13) {
itemRefs.current[index].current.click();
}
// ESC
if (e.keyCode === 27) {
openCloseMenu();
}
}; };
const MultipleDropDown = useMemo( const MultipleDropDown = useMemo(
() => ( () => (
<Wrapper key={uuidv4()}> <Wrapper disabled={isDisabled}>
<DropdownStyled <DropDownButton
key={uuidv4()} aria-expanded={isOpen}
onChange={option => onChange(option)} aria-haspopup
options={dropDownOptions} onKeyDown={e => {
placeholder="Question Type" e.preventDefault();
select={isDisabled} if (e.keyCode === 40) {
value={label} itemRefs.current[0].current.focus();
/> }
}}
onMouseDown={openCloseMenu}
tabIndex="0"
type="button"
>
<span>Question type</span> <StyledIcon name="expand" />
</DropDownButton>
<DropDownMenu isOpen={isOpen} role="menu">
{dropDownOptions.map((option, index) => {
itemRefs.current[index] = itemRefs.current[index] || createRef();
return (
<span
key={option.value}
onClick={() => {
openCloseMenu();
}}
onKeyDown={e => onKeyDown(e, index)}
ref={itemRefs.current[index]}
role="menuitem"
tabIndex="-1"
>
{option.label}
</span>
);
})}
</DropDownMenu>
</Wrapper> </Wrapper>
), ),
[isDisabled, label], [isDisabled, isOpen],
); );
return MultipleDropDown; return MultipleDropDown;
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment