Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions frontend/src/components/DropdownBox/DropdownBox.css
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed there's quite a few hardcoded CSS px values. Its usually a more accessible choice and better for responsivity to consider using relative sizing like rem,em etc for windows, columns, fonts. Pixel values are best for borders and things that are not guaranteed to change.

Your margins, heights and widths should not use hardcoded pixel values. Its still mostly opinion based but my suggestion is if you stick to px values then you should add media-queries for the different device sizes

https://stackoverflow.com/questions/11799236/should-i-use-px-or-rem-value-units-in-my-css
https://wpengine.com/resources/choose-css-unit-create-better-site-layouts-how-to/#Absolute_CSS_Units

Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
.dropdown-wrapper {
position: relative;
}

.dropdown-header {
background-color: rgb(255, 255, 255);
border: 1px solid #000000;
padding: 8px;
cursor: pointer;
max-width: 200px; /* Adjust width as needed */
height: 31px;
border-radius: 0.25rem;
}

.dropdown-list {
position: absolute;
top: calc(100% + 5px);
left: 0;
background-color: rgba(234, 233, 233); /* Grey color with 30% opacity */
border: 1px solid #ccc;
padding: 12px;
max-height: 400px; /* Adjust max-height as needed */
overflow-y: auto;
z-index: 1000;
border-radius: 12px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); /* Adding drop shadow */
}

.dropdown-list-item {
display: flex;
align-items: center;
margin-bottom: 5px;
cursor: pointer;
}

.item-checkbox {
width: 12px;
height: 12px;
border: 1.5px solid #ccc;
margin-right: 5px;
border-radius: 3px;
position: relative;
background-color: white;
}

.item-checkbox-selected::after {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets use a native HTML component for the styling of the checkbox
A comment was made in the main component about using native HTML for the checkbox

content: '✔';
font-size: xx-small;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
}

.item-checkbox-selected {
background-color: rgba(3, 117, 251);
}

.item-name {
font-size: small;
}
.dropdown-list-confirm {
height: 30px;
width: 60px;
border-radius: 20px;
border: 2px solid rgba(158, 158, 158);
margin-left: 50%;
}
81 changes: 81 additions & 0 deletions frontend/src/components/DropdownBox/DropdownBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import React, { useState } from 'react';
import './DropdownBox.css';

type DropdownBoxProps = {
placeHolderText: string;
dataSource: Array<string>;
isOpen: boolean;
confirmText: string;
};

const DropdownBox = ({
placeHolderText,
dataSource,
isOpen,
confirmText,
}: DropdownBoxProps) => {
const [isDropdownBoxOpen, setIsDropdownBoxOpen] = useState(isOpen);
const [selectedItems, setSelectedItems] = useState(new Set<string>());

const toggleDropdownBox = () => {
setIsDropdownBoxOpen(!isDropdownBoxOpen);
};

const toggleSelectItem = (itemName: string) => {
const newSelectedItems = new Set(selectedItems);
if (newSelectedItems.has(itemName)) {
newSelectedItems.delete(itemName);
} else {
newSelectedItems.add(itemName);
}
setSelectedItems(newSelectedItems);
};

return (
<div className="dropdown-wrapper">
<button
type="button"
className="dropdown-header"
onClick={toggleDropdownBox}
>
<div className="dropdown-header-contents">
{placeHolderText}
{' '}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of using hardcoded whitespace
We can style the dropdown-header-contents to have space between the placeholder and the arrow
or you can make both into a span and simply add a space between like below
<span>{placeHolderText} {isDropdownBoxOpen ? '⇈' : '⇊'}</span>

{isDropdownBoxOpen ? '⇈' : '⇊'}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets not use hardcoded arrows like this

Check the Figma for an SVG icon for an arrow and use that
We can create one as well if necessary and simply import that from an SVGs list

</div>
</button>

{isDropdownBoxOpen && (
<>
<div className="dropdown-list">
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed the dropdown box was custom styled and this is okay if there is a significant change from the native HTML styling but since they are very similar (essentially the same) lets stick to using native HTML elements as they are designed to be accessible and cross platform

A suggestion is to map out everything and use input type = checkbox

Example

      {isDropdownBoxOpen && (
        <div className="dropdown-list">
          {dataSource.map((itemName) => (
            <label key={itemName} className="dropdown-list-item">
              <input
                type="checkbox"
                checked={selectedItems.has(itemName)}
                onChange={() => toggleSelectItem(itemName)}
              />
              <span className="item-name">{itemName}</span>
            </label>
          ))}

{dataSource.map((itemName) => (
<div
key={itemName}
className={`dropdown-list-item ${
selectedItems.has(itemName) ? 'item-selected' : ''
}`}
onClick={() => toggleSelectItem(itemName)}
>
<div
className={`item-checkbox ${
selectedItems.has(itemName) ? 'item-checkbox-selected' : ''
}`}
/>
<div className="item-name">{itemName}</div>
</div>
))}
<button
type="button"
className="dropdown-list-confirm"
onClick={toggleDropdownBox}
>
{confirmText}
</button>
</div>
</>
)}
</div>
);
};

export default DropdownBox;
28 changes: 11 additions & 17 deletions frontend/src/components/Modal/RiderModalInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import cn from 'classnames';
import { Button, Input, Label } from '../FormElements/FormElements';
import styles from './ridermodal.module.css';
import { ObjectType, Accessibility, Rider } from '../../types/index';
import { useState } from 'react';
import DropdownBox from '../DropdownBox/DropdownBox';

type ModalFormProps = {
onSubmit: (data: ObjectType) => void;
Expand Down Expand Up @@ -63,7 +65,6 @@ const RiderModalInfo = ({
const localUserType = localStorage.getItem('userType');
const isEditing = rider !== undefined;
const isStudentEditing = isEditing && localUserType === 'Rider';

return (
<form onSubmit={handleSubmit(beforeSubmit)} className={styles.form}>
<div className={cn(styles.inputContainer, styles.rideTime)}>
Expand Down Expand Up @@ -131,22 +132,15 @@ const RiderModalInfo = ({
)}
</div>
<div className={cn(styles.gridR2, styles.gridCBig1)}>
<Label className={styles.label} htmlFor="needs">
Needs:{' '}
</Label>
<select
name="needs"
aria-required="true"
ref={register({ required: true })}
>
{Object.values(Accessibility).map((value, index) => {
return (
<option key={index} value={value}>
{value}
</option>
);
})}
</select>
Needs:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason why this is not bolded when the screen size is changed is because it is not wrapped using a label.

The headers for each input type uses a label and there is a media-query which keeps the label bolded on different screen sizes. Check out the code in src/components/modal/ridermodal.module.css

Needs should be wrapped like the other labels

          <Label className={styles.label} htmlFor="needs">
            Needs:{' '}
          </Label>

<DropdownBox
placeHolderText="Select Your Needs"
dataSource={Object.values(Accessibility)
.splice(1)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of using the splice we can just remove the None value from the Accessibility enum since the stakeholders suggested there is no need for it to be there

.map((value, _) => value.toString())}
isOpen={false}
confirmText="Next"
/>
{errors.needs?.type === 'validate' && (
<p className={styles.error}>
Invalid needs. You can enter 'Assistant', 'Crutches', or
Expand Down