aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/commonStyles.tsx23
-rw-r--r--src/components/InputTypes/Checkbox.tsx27
-rw-r--r--src/components/InputTypes/Range.tsx64
-rw-r--r--src/components/InputTypes/index.tsx2
-rw-r--r--src/components/Question.tsx11
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;