Skip to content

Commit

Permalink
User can select place / state options.
Browse files Browse the repository at this point in the history
  • Loading branch information
lublagg committed Sep 7, 2023
1 parent 2f73e87 commit c98492b
Show file tree
Hide file tree
Showing 10 changed files with 274 additions and 4 deletions.
6 changes: 6 additions & 0 deletions src/assets/check-box-outline-blank.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions src/assets/check-box.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions src/assets/radio-button-checked.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions src/assets/radio-button-unchecked.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions src/components/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<boolean>(false);
const [selectedOptions, setSelectedOptions] = useState<typeof defaultSelectedOptions>(defaultSelectedOptions);

const handleSetSelectedOptions = (option: string, value: string | string[]) => {
const newSelectedOptions = {...selectedOptions, [option]: value};
setSelectedOptions(newSelectedOptions);
};

const handleInfoClick = () => {
setShowInfo(true);
Expand Down Expand Up @@ -33,16 +41,22 @@ function App() {
sectionName={"Place"}
sectionAltText={"Place alt text"}
sectionDescription={"Place description"}
handleSetSelectedOptions={handleSetSelectedOptions}
selectedOptions={selectedOptions}
/>
<Dropdown
sectionName={"Attributes"}
sectionAltText={"Attributes alt text"}
sectionDescription={"Attributes description"}
handleSetSelectedOptions={handleSetSelectedOptions}
selectedOptions={selectedOptions}
/>
<Dropdown
sectionName={"Years"}
sectionAltText={"Years alt text"}
sectionDescription={"Years description"}
handleSetSelectedOptions={handleSetSelectedOptions}
selectedOptions={selectedOptions}
/>
</div>
<div className={css.summary}>
Expand Down
65 changes: 65 additions & 0 deletions src/components/constants.ts
Original file line number Diff line number Diff line change
@@ -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: []
};
8 changes: 7 additions & 1 deletion src/components/dropdown.scss
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
}

.dropdown .dropdownBody {
padding: 0 12px;
padding: 0px 12px;
overflow-y: hidden;
transition-property: max-height;
transition-duration: .5s;
Expand Down Expand Up @@ -76,4 +76,10 @@
flex-shrink: 0;
text-align: center;
height: 16px;
}

.options {
display: flex;
flex-direction: column;
padding: 12px 0px;
}
22 changes: 19 additions & 3 deletions src/components/dropdown.tsx
Original file line number Diff line number Diff line change
@@ -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<IProps> = (props) => {
const {sectionName, sectionAltText, sectionDescription} = props;
const {sectionName, sectionAltText, sectionDescription, handleSetSelectedOptions, selectedOptions} = props;

Check warning on line 16 in src/components/dropdown.tsx

View workflow job for this annotation

GitHub Actions / Build and Run Jest Tests

'sectionDescription' is assigned a value but never used

Check warning on line 16 in src/components/dropdown.tsx

View workflow job for this annotation

GitHub Actions / Build and Run Jest Tests

'sectionDescription' is assigned a value but never used

Check warning on line 16 in src/components/dropdown.tsx

View workflow job for this annotation

GitHub Actions / S3 Deploy

'sectionDescription' is assigned a value but never used

Check warning on line 16 in src/components/dropdown.tsx

View workflow job for this annotation

GitHub Actions / S3 Deploy

'sectionDescription' is assigned a value but never used
const [showItems, setShowItems] = useState<boolean>(false);

const handleClick = () => {
setShowItems(!showItems);
};

const renderOptions = () => {
if (sectionName === "Place") {
return (
<PlaceOptions
handleSetSelectedOptions={handleSetSelectedOptions}
selectedPlace={selectedOptions.place}
selectedStates={selectedOptions.states}
/>
);
}
};

return (
<div className={`${css.dropdown}`}>
<div className={`${css.sectionHeaderLine} ${css.dropdownHeader}`} title={sectionAltText}>
Expand All @@ -24,8 +40,8 @@ export const Dropdown: React.FC<IProps> = (props) => {
<span className={classnames(css.dropdownIndicator, {[css.up]: showItems})} onClick={handleClick}></span>
</div>
<div className={classnames(css.dropdownBody, {[css.hidden]: !showItems})}>
<p>{sectionDescription}</p>
<div className={css.selectionItems}>
<div className={css.options}>
{renderOptions()}
</div>
</div>
</div>
Expand Down
54 changes: 54 additions & 0 deletions src/components/options.scss
Original file line number Diff line number Diff line change
@@ -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;
}
91 changes: 91 additions & 0 deletions src/components/place-options.tsx
Original file line number Diff line number Diff line change
@@ -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<IProps> = (props) => {
const {handleSetSelectedOptions, selectedPlace, selectedStates} = props;

const isStateSelected = (state: string) => {
return selectedStates.indexOf(state) > - 1;
};

const handleSelectPlace = (e: React.ChangeEvent<HTMLInputElement>) => {
handleSetSelectedOptions("place", e.target.value);
};

const handleSelectState = (e: React.ChangeEvent<HTMLInputElement>) => {
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 (
<div key={`radio-option-${o}`} className={css.option}>
<input
className={css.radio}
id={o}
type="radio"
key={`radio-${o}`}
value={o}
checked={selectedPlace === o}
onChange={handleSelectPlace}
/>
<label className={css.label} htmlFor={o} key={`label-${o}`}>{o}</label>
</div>
);
})}
</>
);
};

const createStateOptions = (options: string[]) => {
return (
<>
{options.map((o) => {
return (
<div key={`checkbox-option-${o}`} className={css.option}>
<input
id={o}
className={css.checkbox}
type="checkbox"
key={`checkbox-${o}`}
value={o}
checked={isStateSelected(o)}
onChange={handleSelectState}
/>
<label className={css.label} htmlFor={o} key={`label-${o}`}>{o}</label>
</div>
);
})}
</>
);
};

return (
<>
<div className={css.instruction}>{placeOptions.label}:</div>
<div className={css.radioOptions}>{createPlaceOptions(placeOptions.options)}</div>
<div className={css.instruction}>{stateOptions.label}:</div>
<div className={css.checkOptions}>{createStateOptions(stateOptions.options)}</div>
</>
);
};

0 comments on commit c98492b

Please sign in to comment.