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

replace dropdown in multiple dropdown question

parent 4fedfba9
No related branches found
No related tags found
No related merge requests found
......@@ -76,7 +76,6 @@ const TestModeDropDownComponent = ({ getPos, node, view, uniqueId }) => {
const context = useContext(WaxContext);
const {
pmViews: { main },
activeView,
} = context;
let isDisabled = false;
......
import React, { useContext, useEffect, useState } from 'react';
import { WaxContext, Icon } from 'wax-prosemirror-core';
import { v4 as uuidv4 } from 'uuid';
import styled, { css } from 'styled-components';
import ReadOnlyDropDown from './ReadOnlyDropDown';
......@@ -93,11 +94,5 @@ export default ({ node, getPos }) => {
);
}
return (
<ReadOnlyDropDown
getPos={getPos}
node={node}
options={node.attrs.options}
/>
);
return <ReadOnlyDropDown getPos={getPos} node={node} uniqueId={uuidv4()} />;
};
/* eslint-disable no-underscore-dangle */
import React, { useContext, useEffect, useMemo, useState } from 'react';
import React, {
useContext,
useMemo,
useEffect,
useState,
useRef,
createRef,
} from 'react';
import styled from 'styled-components';
import {
WaxContext,
DocumentHelpers,
ReactDropDownStyles,
Icon,
useOnClickOutside,
} from 'wax-prosemirror-core';
import Dropdown from 'react-dropdown';
import { v4 as uuidv4 } from 'uuid';
const Wrapper = styled.div`
display: inline-flex;
${ReactDropDownStyles};
`;
const DropdownStyled = styled(Dropdown)`
const DropDownButton = styled.button`
background: #fff;
border: 1px solid rgb(204, 204, 204);
color: #000;
cursor: ${props => (props.disabled ? 'not-allowed' : 'pointer')};
display: inline-flex;
cursor: not-allowed;
margin-left: auto;
opacity: ${props => (props.select ? 1 : 0.4)};
pointer-events: ${props => (props.select ? 'default' : 'none')};
.Dropdown-control {
// border: none;
padding: 8px 30px 8px 10px;
&:hover {
box-shadow: none;
}
opacity: ${props => (props.disabled ? `0.4` : `1`)};
padding: 8px 4px 4px 4px;
position: relative;
width: 165px;
span {
position: relative;
top: 2px;
}
&focus {
outline: 0;
}
`;
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: 35px auto auto;
position: absolute;
width: 170px;
max-height: 150px;
overflow-y: auto;
z-index: 2;
.Dropdown-arrow {
top: 17px;
span {
cursor: pointer;
padding: 8px 10px;
}
.Dropdown-menu {
width: 100%;
display: flex;
flex-direction: column;
align-items: flex-start;
.Dropdown-option {
width: 100%;
}
span:focus {
background: #f2f9fc;
outline: 2px solid #f2f9fc;
}
`;
const DropComponent = ({ getPos, node, options }) => {
const StyledIcon = styled(Icon)`
height: 18px;
width: 18px;
margin-left: auto;
`;
const DropComponent = ({ getPos, node, uniqueId }) => {
const [selectedOption, setSelectedOption] = useState(undefined);
const itemRefs = useRef([]);
const wrapperRef = useRef();
const [isOpen, setIsOpen] = useState(false);
const context = useContext(WaxContext);
const {
pmViews: { main },
......@@ -54,11 +86,15 @@ const DropComponent = ({ getPos, node, options }) => {
const customProps = main.props.customValues;
const { testMode } = customProps;
let isDisabled = false;
if (node.attrs.options.length === 0 || !testMode) isDisabled = true;
useEffect(() => {
const currentOption = node.attrs.options.filter(option => {
return option.value === node.attrs.correct;
});
if (!testMode && currentOption[0]) setSelectedOption(currentOption[0]);
if (!testMode && currentOption[0])
setSelectedOption(currentOption[0].value);
}, []);
const onChange = option => {
......@@ -73,26 +109,111 @@ const DropComponent = ({ getPos, node, options }) => {
}
});
main.dispatch(tr);
openCloseMenu();
setSelectedOption(option.value);
};
useOnClickOutside(wrapperRef, () => setIsOpen(false));
const onKeyDown = (e, index) => {
e.preventDefault();
if (e.keyCode === 40) {
// arrow down
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
) {
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) {
setIsOpen(false);
}
};
const MultipleDropDown = useMemo(
() => (
<Wrapper key={uuidv4()}>
<DropdownStyled
disabled={!testMode}
key={uuidv4()}
onChange={option => onChange(option)}
options={options}
placeholder="Select option"
select
value={
selectedOption === 'undedfined' ? 'Select Option' : selectedOption
}
/>
const openCloseMenu = () => {
if (!isDisabled) setIsOpen(!isOpen);
};
const MultipleDropDown = useMemo(() => {
let selectedValue;
if (selectedOption) {
selectedValue = node.attrs.options.filter(option => {
return option.value === selectedOption;
});
}
return (
<Wrapper disabled={isDisabled} ref={wrapperRef}>
<DropDownButton
aria-controls={uniqueId}
aria-expanded={isOpen}
aria-haspopup
disabled={isDisabled}
onKeyDown={e => {
if (e.keyCode === 40) {
if (!itemRefs.current[0].current) return;
itemRefs.current[0].current.focus();
}
if (e.keyCode === 27) {
setIsOpen(false);
}
if (e.keyCode === 13 || e.keyCode === 32) {
setIsOpen(true);
}
}}
onMouseDown={openCloseMenu}
role="combobox"
type="button"
>
{selectedOption === null || !selectedOption
? 'Select Option'
: selectedValue[0].label}
<StyledIcon name="expand" />
</DropDownButton>
<DropDownMenu
aria-label="Choose an option"
id={uniqueId}
isOpen={isOpen}
role="listbox"
>
{node.attrs.options.map((option, index) => {
itemRefs.current[index] = itemRefs.current[index] || createRef();
return (
<span
aria-selected={option.value === selectedOption}
key={option.value}
onClick={() => onChange(option)}
onKeyDown={e => onKeyDown(e, index)}
ref={itemRefs.current[index]}
role="option"
tabIndex="-1"
>
{option.label}
</span>
);
})}
</DropDownMenu>
</Wrapper>
),
[selectedOption],
);
);
}, [node.attrs.options, selectedOption, isOpen]);
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