diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/commonStyles.tsx | 23 | ||||
| -rw-r--r-- | src/components/InputTypes/Checkbox.tsx | 27 | ||||
| -rw-r--r-- | src/components/InputTypes/Range.tsx | 64 | ||||
| -rw-r--r-- | src/components/InputTypes/index.tsx | 2 | ||||
| -rw-r--r-- | src/components/Question.tsx | 11 | 
5 files changed, 57 insertions, 70 deletions
| diff --git a/src/commonStyles.tsx b/src/commonStyles.tsx index 5053846..71bbd13 100644 --- a/src/commonStyles.tsx +++ b/src/commonStyles.tsx @@ -14,6 +14,24 @@ const unselectable = css`    user-select: none;  `; +const hiddenInput = css` +  position: absolute; +  opacity: 0; +  height: 0; +  width: 0; +`; + +const multiSelectInput = css` +  display: inline-block; +  position: relative; + +  margin: 1rem 0.5rem 0 0; +  border: whitesmoke 0.2rem solid; + +  background-color: whitesmoke; +  transition: background-color 300ms; +`; +  const textInputs = css`    display: inline-block;    width: min(20rem, 90%); @@ -32,8 +50,11 @@ const textInputs = css`    border-radius: 8px;  `; +  export {      selectable,      unselectable, -    textInputs +    hiddenInput, +    multiSelectInput, +    textInputs,  }; diff --git a/src/components/InputTypes/Checkbox.tsx b/src/components/InputTypes/Checkbox.tsx index f63da31..3093caf 100644 --- a/src/components/InputTypes/Checkbox.tsx +++ b/src/components/InputTypes/Checkbox.tsx @@ -2,6 +2,7 @@  import { jsx, css } from "@emotion/react";  import React, { ChangeEvent } from "react";  import colors from "../../colors"; +import { multiSelectInput, hiddenInput } from "../../commonStyles";  interface CheckboxProps {      index: number, @@ -10,36 +11,25 @@ interface CheckboxProps {  }  const generalStyles = css` +  cursor: pointer; +            label { -    display: inline-block; -    position: relative; -    top: 0.3rem; -      width: 1em;      height: 1em; +    top: 0.3rem; -    margin: 1rem 0.5rem 0 0; -    border: whitesmoke 0.2rem solid;      border-radius: 25%; -     -    transition: background-color 300ms; +    cursor: pointer;    }    .unselected {      background-color: white;    } -  .unselected:hover { +  .unselected:focus-within, :hover .unselected {      background-color: lightgray;    } -  input { -    position: absolute; -    opacity: 0; -    height: 0; -    width: 0; -  } -    .checkmark {      position: absolute;    } @@ -65,9 +55,8 @@ const activeStyles = css`  export default function Checkbox(props: CheckboxProps): JSX.Element {      return (          <label css={[generalStyles, activeStyles]}> -            <label className="unselected"> -                <input type="checkbox" value={props.option} -                    name={`${("000" + props.index).slice(-4)}. ${props.option}`} onChange={props.handler}/> +            <label className="unselected" css={multiSelectInput}> +                <input type="checkbox" value={props.option} css={hiddenInput} name={`${("000" + props.index).slice(-4)}. ${props.option}`} onChange={props.handler}/>                  <span className="checkmark"/>              </label>              {props.option}<br/> diff --git a/src/components/InputTypes/Range.tsx b/src/components/InputTypes/Range.tsx index af46b05..e2f89f4 100644 --- a/src/components/InputTypes/Range.tsx +++ b/src/components/InputTypes/Range.tsx @@ -1,32 +1,13 @@  /** @jsx jsx */  import { jsx, css } from "@emotion/react"; -import React from "react"; +import React, { ChangeEvent } from "react";  import colors from "../../colors"; +import { hiddenInput, multiSelectInput } from "../../commonStyles";  interface RangeProps {      question_id: string,      options: Array<string>, -    state_dict: Map<string, string | boolean | null> -} - -interface handler_props { -    state_dict: Map<string, string | boolean | null>, -    ref: React.RefObject<HTMLLabelElement> -} - -let last_selection: Element; -function handler(this: handler_props): void { -    if (last_selection) { -        last_selection.classList.toggle("selected"); -    } - -    const dot: Element = this.ref.current!.lastElementChild!; // eslint-disable-line -    dot.classList.toggle("selected"); - -    last_selection = dot; - -    const value: string = this.ref.current!.textContent!; //eslint-disable-line -    this.state_dict.set("value", value); +    handler: (event: ChangeEvent<HTMLInputElement>) => void  }  const containerStyles = css` @@ -57,26 +38,25 @@ const optionStyles = css`    transition: transform 300ms;  `; -const rangeDotStyles = css` -  .range_dot { -    width: 0.8rem; -    height: 0.8rem; +const selectorStyles = css` +  cursor: pointer; + +  div { +    width: 1rem; +    height: 1rem; +      background-color: whitesmoke; -    border: 0.2rem solid whitesmoke;      border-radius: 50%; - -    transition: background-color 300ms; +    margin: 0 100% 0 0;    } -  .range_dot.selected { -    background-color: ${colors.blurple}; +  :hover div, :focus-within div { +    background-color: lightgray;    } -  @media (max-width: 800px) { -    .range_dot { -      margin-bottom: 1.5rem; -    } +  input:checked+div { +    background-color: ${colors.blurple};    }  `; @@ -88,15 +68,15 @@ const sliderContainerStyles = css`    position: absolute;    z-index: -1; -  top: 2rem; +  top: 2.1rem;    transition: all 300ms;    @media (max-width: 800px) {      width: 0.5rem; -    height: 88%; +    height: 80%; -    left: 0.32rem; +    left: 0.4rem;      background: whitesmoke;    } @@ -116,17 +96,17 @@ const sliderStyles = css`  export default function Range(props: RangeProps): JSX.Element {      const range = props.options.map((option, index) => { -        const ref: React.RefObject<HTMLLabelElement> = React.createRef();          return ( -            <label key={index} ref={ref} css={css`width: 1rem;`} onClick={handler.bind({state_dict: props.state_dict, ref})}> +            <label css={[selectorStyles, css`width: 1rem`]} key={index}>                  <span css={optionStyles}>{option}</span> -                <div className="range_dot"/> +                <input type="radio" name={props.question_id} css={hiddenInput} onChange={props.handler}/> +                <div css={multiSelectInput}/>              </label>          );      });      return ( -        <div css={[containerStyles, rangeDotStyles]}> +        <div css={containerStyles}>              { range }              <div css={sliderContainerStyles}> diff --git a/src/components/InputTypes/index.tsx b/src/components/InputTypes/index.tsx index b1d8afe..d75fbdc 100644 --- a/src/components/InputTypes/index.tsx +++ b/src/components/InputTypes/index.tsx @@ -54,7 +54,7 @@ export default function create_input({ question, public_state }: QuestionProp, h          break;      case QuestionType.Range: -        result = <Range question_id={question.id} options={options} state_dict={public_state}/>; +        result = <Range question_id={question.id} options={options} handler={handler}/>;          break;      case QuestionType.Code: diff --git a/src/components/Question.tsx b/src/components/Question.tsx index 54074f3..e1472e4 100644 --- a/src/components/Question.tsx +++ b/src/components/Question.tsx @@ -46,12 +46,13 @@ class RenderedQuestion extends React.Component<QuestionProp> {          let value: string | boolean;          switch (event.target.type) { -        case QuestionType.Checkbox: -            target = this.props.question.id; +        case "checkbox": +            target = event.target.name;              value = event.target.checked;              break; -        case QuestionType.Radio: +        case "radio": +            // This handles radios and ranges, as they are both based on the same fundamental input type              target = "value";              if (event.target.parentElement) {                  value = event.target.parentElement.innerText.trimEnd(); @@ -60,10 +61,6 @@ class RenderedQuestion extends React.Component<QuestionProp> {              }              break; -        case QuestionType.Select: -            // Handled by component -            return; -          default:              target = "value";              value = event.target.value; | 
