-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Checkbox question type #25
base: dev
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import React, { ChangeEvent, useEffect, useState } from 'react' | ||
import { v4 } from 'uuid' | ||
|
||
import styles from '../styles/Checkboxes.module.css' | ||
|
||
export type CheckboxesProps = { | ||
disabled?: boolean | ||
options: string[] | ||
updateCallback?: (update: string) => void | ||
} | ||
const Checkboxes = ({ | ||
disabled = false, | ||
options, | ||
updateCallback | ||
}: CheckboxesProps) => { | ||
const [selectedOptions, updateSelectedOptions] = useState( | ||
options.map(() => false) | ||
) | ||
|
||
useEffect( | ||
() => { | ||
if (!updateCallback) return | ||
updateCallback(selectedOptions.toString()) | ||
}, | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
[selectedOptions] | ||
) | ||
|
||
const uuid = v4() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmmm. Does this cause the id to change on every rerender? Like when a box is checked and unchecked? |
||
|
||
const onSelectionChange = (e: ChangeEvent<HTMLInputElement>) => { | ||
const index = parseInt((e.target as HTMLInputElement).value) | ||
const clonedSelectedOptions = Array.from(selectedOptions) | ||
clonedSelectedOptions[index] = !clonedSelectedOptions[index] | ||
updateSelectedOptions(clonedSelectedOptions) | ||
} | ||
|
||
return ( | ||
<div className={styles.container}> | ||
{options?.map((option, index) => ( | ||
<label htmlFor={`${uuid}-${index}`} key={index}> | ||
<input | ||
aria-labelledby={`${option}-label`} | ||
className={styles.button} | ||
defaultChecked={selectedOptions[index] === true} | ||
disabled={disabled} | ||
id={`${uuid}-${index}`} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why not just use |
||
name={uuid} | ||
onChange={onSelectionChange} | ||
type="checkbox" | ||
value={index} | ||
/> | ||
<span className={styles.label} id={`${option}-label`}> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you are using |
||
{option} | ||
</span> | ||
</label> | ||
))} | ||
</div> | ||
) | ||
} | ||
export { Checkboxes } |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import React from 'react' | ||
import { action } from '@storybook/addon-actions' | ||
import { ComponentMeta } from '@storybook/react' | ||
|
||
import { Checkboxes } from '../Checkboxes' | ||
|
||
export default { | ||
component: Checkboxes, | ||
title: 'Check Boxes' | ||
} as ComponentMeta<typeof Checkboxes> | ||
|
||
export const Default = () => ( | ||
<Checkboxes | ||
options={['first', 'second', 'third']} | ||
updateCallback={action('Option is selected')} | ||
/> | ||
) | ||
|
||
export const WithTitle = () => ( | ||
<> | ||
<h1>How many stars are there in the sky?</h1> | ||
<Checkboxes | ||
options={['one', 'two', 'three', 'four', 'five']} | ||
updateCallback={action('Option is selected')} | ||
/> | ||
</> | ||
miles-grant-ibigroup marked this conversation as resolved.
Show resolved
Hide resolved
|
||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
.container { | ||
font-size: 25px; | ||
} | ||
|
||
.container label { | ||
display: grid; | ||
align-items: center; | ||
grid-template-columns: 25px 1fr; | ||
grid-gap: 1ch; | ||
padding-bottom: 0.33333ch; | ||
} | ||
.container label input { | ||
height: 25px; | ||
width: 25px; | ||
} | ||
|
||
.button ~ .label { | ||
color: #333; | ||
transition: all 0.1s ease-in-out; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't use
useEffect
here. Just make a callback function that callsupdateSelectedOptions
andupdateCallback
and call that function from line 35 where you callupdateSelectedOptions
now