From c98492b5c0ea3865c6954e9e4a3b0c561fe3485d Mon Sep 17 00:00:00 2001 From: lublagg Date: Thu, 7 Sep 2023 16:38:38 -0400 Subject: [PATCH] User can select place / state options. --- src/assets/check-box-outline-blank.svg | 6 ++ src/assets/check-box.svg | 6 ++ src/assets/radio-button-checked.svg | 6 ++ src/assets/radio-button-unchecked.svg | 6 ++ src/components/app.tsx | 14 ++++ src/components/constants.ts | 65 ++++++++++++++++++ src/components/dropdown.scss | 8 ++- src/components/dropdown.tsx | 22 ++++++- src/components/options.scss | 54 +++++++++++++++ src/components/place-options.tsx | 91 ++++++++++++++++++++++++++ 10 files changed, 274 insertions(+), 4 deletions(-) create mode 100644 src/assets/check-box-outline-blank.svg create mode 100644 src/assets/check-box.svg create mode 100644 src/assets/radio-button-checked.svg create mode 100644 src/assets/radio-button-unchecked.svg create mode 100644 src/components/constants.ts create mode 100644 src/components/options.scss create mode 100644 src/components/place-options.tsx diff --git a/src/assets/check-box-outline-blank.svg b/src/assets/check-box-outline-blank.svg new file mode 100644 index 0000000..9b1e50b --- /dev/null +++ b/src/assets/check-box-outline-blank.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/assets/check-box.svg b/src/assets/check-box.svg new file mode 100644 index 0000000..b8830e9 --- /dev/null +++ b/src/assets/check-box.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/assets/radio-button-checked.svg b/src/assets/radio-button-checked.svg new file mode 100644 index 0000000..e843eec --- /dev/null +++ b/src/assets/radio-button-checked.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/assets/radio-button-unchecked.svg b/src/assets/radio-button-unchecked.svg new file mode 100644 index 0000000..859fecb --- /dev/null +++ b/src/assets/radio-button-unchecked.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/components/app.tsx b/src/components/app.tsx index 106a7e1..20a2974 100644 --- a/src/components/app.tsx +++ b/src/components/app.tsx @@ -3,9 +3,17 @@ import { Dropdown } from "./dropdown"; import css from "./app.scss"; import classnames from "classnames"; import { Information } from "./information"; +import { defaultSelectedOptions } from "./constants"; + function App() { const [showInfo, setShowInfo] = useState(false); + const [selectedOptions, setSelectedOptions] = useState(defaultSelectedOptions); + + const handleSetSelectedOptions = (option: string, value: string | string[]) => { + const newSelectedOptions = {...selectedOptions, [option]: value}; + setSelectedOptions(newSelectedOptions); + }; const handleInfoClick = () => { setShowInfo(true); @@ -33,16 +41,22 @@ function App() { sectionName={"Place"} sectionAltText={"Place alt text"} sectionDescription={"Place description"} + handleSetSelectedOptions={handleSetSelectedOptions} + selectedOptions={selectedOptions} />
diff --git a/src/components/constants.ts b/src/components/constants.ts new file mode 100644 index 0000000..22822be --- /dev/null +++ b/src/components/constants.ts @@ -0,0 +1,65 @@ +export const placeOptions = { + label: "Size of area for data", + options : ["State", "County"] +}; + +export const stateOptions = { + label: "Choose states to include in your dataset from the list below", + options: [ + "Alabama", + "Alaska", + "Arizona", + "Arkansas", + "California", + "Colorado", + "Connecticut", + "Delaware", + "Florida", + "Georgia", + "Hawaii", + "Idaho", + "Illinois", + "Indiana", + "Iowa", + "Kansas", + "Kentucky", + "Louisiana", + "Maine", + "Maryland", + "Massachusetts", + "Michigan", + "Minnesota", + "Mississippi", + "Missouri", + "Montana", + "Nebraska", + "Nevada", + "New Hampshire", + "New Jersey", + "New Mexico", + "New York", + "North Carolina", + "North Dakota", + "Ohio", + "Oklahoma", + "Oregon", + "Pennsylvania", + "Rhode Island", + "South Carolina", + "South Dakota", + "Tennessee", + "Texas", + "Utah", + "Vermont", + "Virginia", + "Washington", + "West Virginia", + "Wisconsin", + "Wyoming" + ] +}; + +export const defaultSelectedOptions = { + place: null, + states: [] +}; diff --git a/src/components/dropdown.scss b/src/components/dropdown.scss index 10f47c6..3e7db65 100644 --- a/src/components/dropdown.scss +++ b/src/components/dropdown.scss @@ -35,7 +35,7 @@ } .dropdown .dropdownBody { - padding: 0 12px; + padding: 0px 12px; overflow-y: hidden; transition-property: max-height; transition-duration: .5s; @@ -76,4 +76,10 @@ flex-shrink: 0; text-align: center; height: 16px; +} + +.options { + display: flex; + flex-direction: column; + padding: 12px 0px; } \ No newline at end of file diff --git a/src/components/dropdown.tsx b/src/components/dropdown.tsx index 6e61c1e..23ae174 100644 --- a/src/components/dropdown.tsx +++ b/src/components/dropdown.tsx @@ -1,21 +1,37 @@ import React, { useState } from "react"; import classnames from "classnames"; import css from "./dropdown.scss"; +import { PlaceOptions } from "./place-options"; +import { defaultSelectedOptions } from "./constants"; interface IProps { sectionName: string sectionAltText: string sectionDescription: string + handleSetSelectedOptions: (option: string, value: string|string[]) => void + selectedOptions: typeof defaultSelectedOptions; } export const Dropdown: React.FC = (props) => { - const {sectionName, sectionAltText, sectionDescription} = props; + const {sectionName, sectionAltText, sectionDescription, handleSetSelectedOptions, selectedOptions} = props; const [showItems, setShowItems] = useState(false); const handleClick = () => { setShowItems(!showItems); }; + const renderOptions = () => { + if (sectionName === "Place") { + return ( + + ); + } + }; + return (
@@ -24,8 +40,8 @@ export const Dropdown: React.FC = (props) => {
-

{sectionDescription}

-
+
+ {renderOptions()}
diff --git a/src/components/options.scss b/src/components/options.scss new file mode 100644 index 0000000..0d0d78e --- /dev/null +++ b/src/components/options.scss @@ -0,0 +1,54 @@ +.radioOptions, .checkOptions { + margin-top: 10px; + margin-bottom: 10px; +} + +.radioOptions { + display: flex; + flex-direction: row; + gap: 20px; +} + +.option { + display: flex; + align-items: center; + height: 24px; + flex-basis: 120px; + padding: 6px; + label { + padding-top: 3px; + } +} + +.radio { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + width: 17px; + height: 17px; + font-size: 17px; + background-image: url('../assets/radio-button-unchecked.svg'); + color: var(--teal-dark-75); + &:checked { + background-image: url('../assets/radio-button-checked.svg'); + } +} + +.checkbox { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + width: 17px; + height: 17px; + font-size: 17px; + background-image: url('../assets/check-box-outline-blank.svg'); + color: var(--teal-dark-75); + &:checked { + background-image: url('../assets/check-box.svg'); + } +} + +.checkOptions { + flex-wrap: wrap; + display: flex; +} \ No newline at end of file diff --git a/src/components/place-options.tsx b/src/components/place-options.tsx new file mode 100644 index 0000000..0774649 --- /dev/null +++ b/src/components/place-options.tsx @@ -0,0 +1,91 @@ +import React from "react"; +import { placeOptions, stateOptions } from "./constants"; + +import css from "./options.scss"; + +interface IProps { + handleSetSelectedOptions: (option: string, value: string|string[]) => void; + selectedPlace: string|null; + selectedStates: string[]; +} + +export const PlaceOptions: React.FC = (props) => { + const {handleSetSelectedOptions, selectedPlace, selectedStates} = props; + + const isStateSelected = (state: string) => { + return selectedStates.indexOf(state) > - 1; + }; + + const handleSelectPlace = (e: React.ChangeEvent) => { + handleSetSelectedOptions("place", e.target.value); + }; + + const handleSelectState = (e: React.ChangeEvent) => { + let newSelectedStates = [...selectedStates]; + if (e.currentTarget.checked) { + newSelectedStates.push(e.target.value); + newSelectedStates.sort(); + + } else { + if (isStateSelected(e.target.value)) { + newSelectedStates = newSelectedStates.filter((s) => s !== e.target.value); + } + } + handleSetSelectedOptions("states", newSelectedStates); + }; + + const createPlaceOptions = (options: string[]) => { + return ( + <> + {options.map((o) => { + return ( +
+ + +
+ ); + })} + + ); + }; + + const createStateOptions = (options: string[]) => { + return ( + <> + {options.map((o) => { + return ( +
+ + +
+ ); + })} + + ); + }; + + return ( + <> +
{placeOptions.label}:
+
{createPlaceOptions(placeOptions.options)}
+
{stateOptions.label}:
+
{createStateOptions(stateOptions.options)}
+ + ); +};