Skip to content
Draft
12 changes: 9 additions & 3 deletions packages/gamut/src/ConnectedForm/ConnectedFormGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { css } from '@codecademy/gamut-styles';
import styled from '@emotion/styled';
import { useEffect } from 'react';
import * as React from 'react';
import { RegisterOptions } from 'react-hook-form';

import { FormError, FormGroup, FormGroupLabel, FormGroupProps } from '..';
import { Anchor } from '../Anchor';
Expand Down Expand Up @@ -42,7 +43,10 @@ export interface ConnectedFormGroupProps<T extends ConnectedField>
/**
* An object consisting of a `component` key to specify what ConnectedFormInput to render - the remaining key/value pairs are that components desired props.
*/
field: Omit<React.ComponentProps<T>, 'name' | 'disabled'> & FieldProps<T>;
field: Omit<React.ComponentProps<T>, 'name' | 'disabled'> &
FieldProps<T> & {
customValidations?: RegisterOptions;
};
}

export function ConnectedFormGroup<T extends ConnectedField>({
Expand All @@ -60,11 +64,12 @@ export function ConnectedFormGroup<T extends ConnectedField>({
isSoloField,
infotip,
}: ConnectedFormGroupProps<T>) {
const { component: Component, customValidations, ...rest } = field;
const { error, isFirstError, isDisabled, setError, validation } = useField({
name,
disabled,
customValidations,
});
const { component: Component, ...rest } = field;

useEffect(() => {
if (customError) {
Expand All @@ -81,7 +86,7 @@ export function ConnectedFormGroup<T extends ConnectedField>({
htmlFor={id || name}
infotip={infotip}
isSoloField={isSoloField}
required={!!validation?.required}
required={Boolean(validation?.required)}
size={labelSize}
>
{label}
Expand All @@ -99,6 +104,7 @@ export function ConnectedFormGroup<T extends ConnectedField>({
{...(rest as any)}
aria-describedby={errorId}
aria-invalid={showError}
customValidations={customValidations}
disabled={disabled}
name={name}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ export const ConnectedCheckbox: React.FC<ConnectedCheckboxProps> = ({
name,
onUpdate,
spacing,
customValidations,
}) => {
const { isDisabled, control, validation, isRequired } = useField({
name,
disabled,
customValidations,
});

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import { ConnectedInputProps } from './types';
export const ConnectedInput: React.FC<ConnectedInputProps> = ({
disabled,
name,
customValidations,
...rest
}) => {
const { error, isDisabled, ref, isRequired } = useField({
name,
disabled,
customValidations,
});

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ import {

export const ConnectedNestedCheckboxes: React.FC<
ConnectedNestedCheckboxesProps
> = ({ name, options, disabled, onUpdate, spacing }) => {
> = ({ name, options, disabled, onUpdate, spacing, customValidations }) => {
const { isDisabled, control, validation, isRequired, getValues, setValue } =
useField({
name,
disabled,
customValidations,
});

const defaultValue: string[] = getValues()[name];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import { ConnectedRadioProps } from './types';
export const ConnectedRadio: React.FC<ConnectedRadioProps> = ({
disabled,
name,
customValidations,
...rest
}) => {
const { error, isDisabled, ref } = useField({
name,
disabled,
customValidations,
});

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import { ConnectedRadioGroupProps } from './types';
export const ConnectedRadioGroup: React.FC<ConnectedRadioGroupProps> = ({
name,
onChange,
customValidations,
...rest
}) => {
const { setValue, isRequired } = useField({ name });
const { setValue, isRequired } = useField({ name, customValidations });

return (
<RadioGroup
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@ import { ConnectedRadioGroupInputProps } from './types';

export const ConnectedRadioGroupInput: React.FC<
ConnectedRadioGroupInputProps
> = ({ name, options, disabled, ...rest }) => {
> = ({ name, options, disabled, customValidations, ...rest }) => {
return (
<ConnectedRadioGroup name={name} {...rest}>
<ConnectedRadioGroup
customValidations={customValidations}
name={name}
{...rest}
>
{options.map((elem) => {
return (
<ConnectedRadio
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import { ConnectedSelectProps } from './types';
export const ConnectedSelect: React.FC<ConnectedSelectProps> = ({
disabled,
name,
customValidations,
...rest
}) => {
const { error, isDisabled, ref, isRequired } = useField({
name,
disabled,
customValidations,
});

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import { ConnectedTextAreaProps } from './types';
export const ConnectedTextArea: React.FC<ConnectedTextAreaProps> = ({
disabled,
name,
customValidations,
...rest
}) => {
const { error, isDisabled, ref, isRequired } = useField({
name,
disabled,
customValidations,
});

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ReactNode } from 'react';
import { RegisterOptions } from 'react-hook-form';

import {
CheckboxLabelUnion,
Expand All @@ -15,6 +16,7 @@ export interface BaseConnectedFieldProps {
}
export interface ConnectedFieldProps extends BaseConnectedFieldProps {
name: string;
customValidations?: RegisterOptions;
}

export interface MinimalCheckboxProps
Expand Down Expand Up @@ -74,7 +76,10 @@ export type NestedConnectedCheckboxOption = Omit<
};

export interface ConnectedNestedCheckboxesProps
extends Pick<BaseConnectedCheckboxProps, 'name' | 'disabled' | 'spacing'> {
extends Pick<
BaseConnectedCheckboxProps,
'name' | 'disabled' | 'spacing' | 'customValidations'
> {
options: NestedConnectedCheckboxOption[];
onUpdate?: (values: string[]) => void;
}
Loading
Loading