Skip to content

Commit

Permalink
refactor: update story and enhanch component file structure for gende…
Browse files Browse the repository at this point in the history
…r id -tckt-365
  • Loading branch information
kalasgarov committed Dec 6, 2024
1 parent 6cc6d47 commit 491d00c
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 154 deletions.
56 changes: 15 additions & 41 deletions packages/design/src/Form/components/GenderId/GenderId.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { type Meta, type StoryObj } from '@storybook/react';
import { GenderIdPattern } from './GenderId.js';
import GenderIdPattern from './index.js';

const meta: Meta<typeof GenderIdPattern> = {
title: 'patterns/GenderIdPattern',
Expand All @@ -24,67 +24,41 @@ const meta: Meta<typeof GenderIdPattern> = {

export default meta;

const defaultArgs = {
genderId: 'gender-identity',
label: 'Gender identity',
hint: 'For example, man, woman, non-binary',
required: true,
preferNotToAnswerText: 'Prefer not to share my gender identity',
};

export const Default: StoryObj<typeof GenderIdPattern> = {
args: {
genderId: 'gender-identity',
label: 'Gender identity',
hint: 'For example, man, woman, non-binary',
required: true,
preferNotToAnswerText: 'Prefer not to share my gender identity',
},
args: { ...defaultArgs },
};

export const Optional: StoryObj<typeof GenderIdPattern> = {
args: {
genderId: 'gender-identity',
label: 'Gender identity',
hint: 'For example, man, woman, non-binary',
required: false,
preferNotToAnswerText: 'Prefer not to share my gender identity',
},
args: { ...defaultArgs, required: false },
};

export const WithError: StoryObj<typeof GenderIdPattern> = {
args: {
genderId: 'gender-identity',
...defaultArgs,
label: 'Gender identity with error',
hint: 'For example, man, woman, non-binary',
required: true,
error: {
type: 'custom',
message: 'This field has an error',
},
preferNotToAnswerText: 'Prefer not to share my gender identity',
},
};

export const WithHint: StoryObj<typeof GenderIdPattern> = {
args: {
genderId: 'gender-identity',
label: 'Gender identity',
hint: 'For example, man, woman, non-binary',
required: true,
preferNotToAnswerText: 'Prefer not to share my gender identity',
},
args: { ...defaultArgs },
};

export const WithCheckboxChecked: StoryObj<typeof GenderIdPattern> = {
args: {
genderId: 'gender-identity',
label: 'Gender identity',
hint: 'For example, man, woman, non-binary',
required: true,
preferNotToAnswerText: 'Prefer not to share my gender identity',
preferNotToAnswerChecked: true,
},
args: { ...defaultArgs, preferNotToAnswerChecked: true },
};

export const WithoutCheckbox: StoryObj<typeof GenderIdPattern> = {
args: {
genderId: 'gender-identity',
label: 'Gender identity',
hint: 'For example, man, woman, non-binary',
required: true,
preferNotToAnswerText: undefined,
},
args: { ...defaultArgs, preferNotToAnswerText: undefined },
};
112 changes: 0 additions & 112 deletions packages/design/src/Form/components/GenderId/GenderId.tsx

This file was deleted.

113 changes: 112 additions & 1 deletion packages/design/src/Form/components/GenderId/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,114 @@
import { GenderIdPattern } from './GenderId.js';
import React, { useEffect, useState } from 'react';
import classNames from 'classnames';
import { useFormContext } from 'react-hook-form';
import { type GenderIdProps } from '@atj/forms';

import { type PatternComponent } from '../../index.js';

const GenderIdPattern: PatternComponent<GenderIdProps> = ({
genderId,
hint,
label,
required,
error,
value,
preferNotToAnswerText,
preferNotToAnswerChecked: initialPreferNotToAnswerChecked = false,
}) => {
const { register, setValue } = useFormContext();
const [preferNotToAnswerChecked, setPreferNotToAnswerChecked] = useState(
initialPreferNotToAnswerChecked
);

const errorId = `input-error-message-${genderId}`;
const hintId = `hint-${genderId}`;
const preferNotToAnswerId = `prefer-not-to-answer-${genderId}`;

useEffect(() => {
if (preferNotToAnswerChecked) {
setValue(genderId, preferNotToAnswerText, { shouldValidate: true });
} else {
setValue(genderId, value, { shouldValidate: true });
}
}, [
preferNotToAnswerChecked,
setValue,
genderId,
preferNotToAnswerText,
value,
]);

const handleCheckboxChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setPreferNotToAnswerChecked(event.target.checked);
setValue(preferNotToAnswerId, event.target.checked);
};

return (
<fieldset className="usa-fieldset">
<div className={classNames('usa-form-group margin-top-2')}>
<label
className={classNames('usa-label', {
'usa-label--error': error,
})}
htmlFor={genderId}
>
{label || 'Gender identity'}
{required && <span className="required-indicator">*</span>}
</label>
{hint && (
<div className="usa-hint" id={hintId}>
{hint}
</div>
)}
{error && (
<div className="usa-error-message" id={errorId} role="alert">
{error.message}
</div>
)}
<input
className={classNames('usa-input', {
'usa-input--error': error,
})}
style={
preferNotToAnswerChecked
? {
backgroundColor: '#e9ecef',
pointerEvents: 'none',
opacity: 0.65,
}
: {}
}
id={genderId}
type="text"
defaultValue={value}
{...register(genderId, { required })}
aria-describedby={
`${hint ? `${hintId}` : ''}${error ? ` ${errorId}` : ''}`.trim() ||
undefined
}
/>
{preferNotToAnswerText && (
<div className="usa-checkbox">
<input
className="usa-checkbox__input"
id={preferNotToAnswerId}
type="checkbox"
value="prefer-not-to-answer"
checked={preferNotToAnswerChecked}
{...register(preferNotToAnswerId)}
onChange={handleCheckboxChange}
/>
<label
className="usa-checkbox__label"
htmlFor={preferNotToAnswerId}
>
{preferNotToAnswerText}
</label>
</div>
)}
</div>
</fieldset>
);
};

export default GenderIdPattern;

0 comments on commit 491d00c

Please sign in to comment.