Skip to content

Commit

Permalink
attempt to fix validation around checkbox
Browse files Browse the repository at this point in the history
  • Loading branch information
MadMango committed Dec 11, 2023
1 parent 419555e commit fbbc117
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 87 deletions.
11 changes: 9 additions & 2 deletions packages/react/src/forms/FormControl/FormControl.module.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
section {
display: flex;
flex-direction: column;
}

.FormControl {
display: inline-flex;
font-family: var(--brand-body-fontFamily);
Expand Down Expand Up @@ -56,7 +61,8 @@
cursor: pointer;
font-size: var(--brand-text-size-100);
font-weight: var(--base-text-weight-semibold);
line-height: var(--base-size-24); /* FIXME */
line-height: var(--base-size-24);
/* FIXME */
position: relative;
top: 2px;
width: 100%;
Expand Down Expand Up @@ -105,8 +111,9 @@
opacity: 0;
transform: translateY(-100%);
}

100% {
opacity: 1;
transform: translateY(0);
}
}
}
12 changes: 12 additions & 0 deletions packages/react/src/forms/FormControl/FormControl.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,18 @@ export const CheckboxPlayground = args => {

CheckboxPlayground.storyName = 'w/ Checkbox - Playground'

export const CheckboxValidationPlayground = args => {
return (
<FormControl validationStatus="error">
<FormControl.Label>Day</FormControl.Label>
<Checkbox name="day" value="" />
<FormControl.Validation className="test">Please select at least one day</FormControl.Validation>
</FormControl>
)
}

CheckboxValidationPlayground.storyName = 'w/ Checkbox - Errors'

export const RadioPlayground = () => (
<>
<Stack direction={{narrow: 'vertical', regular: 'horizontal'}} gap="condensed" padding="condensed">
Expand Down
172 changes: 87 additions & 85 deletions packages/react/src/forms/FormControl/FormControl.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, {PropsWithChildren} from 'react'
import React, {PropsWithChildren, ReactElement} from 'react'
import {useId} from '@reach/auto-id' // TODO: Replace with useId from React v18 after upgrade
import clsx from 'clsx'
import {AlertFillIcon, CheckCircleFillIcon} from '@primer/octicons-react'
Expand Down Expand Up @@ -62,95 +62,97 @@ const Root = ({
child => React.isValidElement(child) && (child.type === Checkbox || child.type === Radio),
)

const childrenWithoutValidation = childrenArr.filter(child => (child as ReactElement).type !== FormControlValidation)
const validation = childrenArr.find(child => (child as ReactElement).type === FormControlValidation)

const classNameTest = clsx(
styles.FormControl,
fullWidth && styles[`FormControl--fullWidth`],
isInlineControl && styles['FormControl--checkbox'],
hasBorder && styles['FormControl--border'],
className,
)
return (
<section
id={`FormControl--${uniqueId}`}
className={clsx(
styles.FormControl,
fullWidth && styles[`FormControl--fullWidth`],
isInlineControl && styles['FormControl--checkbox'],
hasBorder && styles['FormControl--border'],
className,
)}
{...rest}
>
{React.Children.map(children, child => {
if (React.isValidElement(child)) {
const inputId = `${uniqueId}`
<section id={`FormControl--${uniqueId}`} {...rest}>
<div className={classNameTest}>
{childrenWithoutValidation.map(child => {
if (React.isValidElement(child)) {
const inputId = `${uniqueId}`

/**
* TextInput
*/
if (child.type === TextInput || child.type === Textarea) {
return React.cloneElement(child as React.ReactElement, {
className: clsx(child.props.className),
id: inputId,
name: child.props.name || inputId,
required: child.props.required || required,
validationStatus: child.props.validationStatus || validationStatus,
fullWidth,
size,
})
} else if (child.type === Select) {
/**
* Select
*/
return React.cloneElement(child as React.ReactElement, {
className: clsx(child.props.className),
id: inputId,
name: inputId,
required: child.props.required || required,
validationStatus: child.props.validationStatus || validationStatus,
fullWidth,
size,
})
} else if (child.type === Checkbox) {
/**
* Checkbox
* TextInput
*/
return React.cloneElement(child as React.ReactElement, {
className: clsx(child.props.className),
id: inputId,
name: child.props.name || inputId,
required: child.props.required || required,
validationStatus: child.props.validationStatus || validationStatus,
})
} else if (child.type === Radio) {
/**
* Radio
*/
return React.cloneElement(child as React.ReactElement, {
className: clsx(isInlineControl && styles['FormControl-control--radio'], child.props.className),
id: inputId,
name: child.props.name,
required: child.props.required || required,
validationStatus: child.props.validationStatus || validationStatus,
})
} else if (child.type === FormControlLabel) {
/**
* Label
*/
return React.cloneElement(child as React.ReactElement, {
className: clsx(isInlineControl && styles['FormControl-label--checkbox'], child.props.className),
htmlFor: inputId,
children: child.props.children,
required,
validationStatus,
size,
showRequiredIndicator: isInlineControl ? false : child.props.showRequiredIndicator,
})
} else if (child.type === FormControlValidation) {
/**
* Validation
*/
return React.cloneElement(child as React.ReactElement, {
validationStatus,
})
} else {
return child
if (child.type === TextInput || child.type === Textarea) {
return React.cloneElement(child as React.ReactElement, {
className: clsx(child.props.className),
id: inputId,
name: child.props.name || inputId,
required: child.props.required || required,
validationStatus: child.props.validationStatus || validationStatus,
fullWidth,
size,
})
} else if (child.type === Select) {
/**
* Select
*/
return React.cloneElement(child as React.ReactElement, {
className: clsx(child.props.className),
id: inputId,
name: inputId,
required: child.props.required || required,
validationStatus: child.props.validationStatus || validationStatus,
fullWidth,
size,
})
} else if (child.type === Checkbox) {
/**
* Checkbox
*/
return React.cloneElement(child as React.ReactElement, {
className: clsx(child.props.className),
id: inputId,
name: child.props.name || inputId,
required: child.props.required || required,
validationStatus: child.props.validationStatus || validationStatus,
})
} else if (child.type === Radio) {
/**
* Radio
*/
return React.cloneElement(child as React.ReactElement, {
className: clsx(isInlineControl && styles['FormControl-control--radio'], child.props.className),
id: inputId,
name: child.props.name,
required: child.props.required || required,
validationStatus: child.props.validationStatus || validationStatus,
})
} else if (child.type === FormControlLabel) {
/**
* Label
*/
return React.cloneElement(child as React.ReactElement, {
className: clsx(isInlineControl && styles['FormControl-label--checkbox'], child.props.className),
htmlFor: inputId,
children: child.props.children,
required,
validationStatus,
size,
showRequiredIndicator: isInlineControl ? false : child.props.showRequiredIndicator,
})
} else {
return child
}
}
}
})}
})}
</div>
{validation && (
<div className={classNameTest}>
{React.cloneElement(validation as React.ReactElement, {
validationStatus,
})}
</div>
)}
</section>
)
}
Expand Down

0 comments on commit fbbc117

Please sign in to comment.