aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/atoms/forms
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/atoms/forms')
-rw-r--r--src/components/atoms/forms/boolean-field.stories.tsx10
-rw-r--r--src/components/atoms/forms/boolean-field.test.tsx2
-rw-r--r--src/components/atoms/forms/boolean-field.tsx34
-rw-r--r--src/components/atoms/forms/field.stories.tsx2
-rw-r--r--src/components/atoms/forms/field.test.tsx2
-rw-r--r--src/components/atoms/forms/field.tsx20
-rw-r--r--src/components/atoms/forms/form.test.tsx2
-rw-r--r--src/components/atoms/forms/form.tsx32
-rw-r--r--src/components/atoms/forms/index.ts5
-rw-r--r--src/components/atoms/forms/label.stories.tsx2
-rw-r--r--src/components/atoms/forms/label.test.tsx2
-rw-r--r--src/components/atoms/forms/label.tsx23
-rw-r--r--src/components/atoms/forms/select.stories.tsx2
-rw-r--r--src/components/atoms/forms/select.test.tsx2
-rw-r--r--src/components/atoms/forms/select.tsx32
15 files changed, 61 insertions, 111 deletions
diff --git a/src/components/atoms/forms/boolean-field.stories.tsx b/src/components/atoms/forms/boolean-field.stories.tsx
index 8b6136b..3d6f8c3 100644
--- a/src/components/atoms/forms/boolean-field.stories.tsx
+++ b/src/components/atoms/forms/boolean-field.stories.tsx
@@ -1,13 +1,13 @@
import { ComponentMeta, ComponentStory } from '@storybook/react';
import { useState } from 'react';
-import BooleanFieldComponent from './boolean-field';
+import { BooleanField } from './boolean-field';
/**
* BooleanField - Storybook Meta
*/
export default {
title: 'Atoms/Forms',
- component: BooleanFieldComponent,
+ component: BooleanField,
args: {
hidden: false,
},
@@ -130,9 +130,9 @@ export default {
},
},
},
-} as ComponentMeta<typeof BooleanFieldComponent>;
+} as ComponentMeta<typeof BooleanField>;
-const Template: ComponentStory<typeof BooleanFieldComponent> = ({
+const Template: ComponentStory<typeof BooleanField> = ({
checked,
onChange: _onChange,
...args
@@ -140,7 +140,7 @@ const Template: ComponentStory<typeof BooleanFieldComponent> = ({
const [isChecked, setIsChecked] = useState<boolean>(checked);
return (
- <BooleanFieldComponent
+ <BooleanField
checked={isChecked}
onChange={() => {
setIsChecked(!isChecked);
diff --git a/src/components/atoms/forms/boolean-field.test.tsx b/src/components/atoms/forms/boolean-field.test.tsx
index b6fa625..503d1ce 100644
--- a/src/components/atoms/forms/boolean-field.test.tsx
+++ b/src/components/atoms/forms/boolean-field.test.tsx
@@ -1,5 +1,5 @@
import { render, screen } from '../../../../tests/utils';
-import BooleanField from './boolean-field';
+import { BooleanField } from './boolean-field';
describe('BooleanField', () => {
it('renders an unchecked checkbox', () => {
diff --git a/src/components/atoms/forms/boolean-field.tsx b/src/components/atoms/forms/boolean-field.tsx
index 946e375..8f33a42 100644
--- a/src/components/atoms/forms/boolean-field.tsx
+++ b/src/components/atoms/forms/boolean-field.tsx
@@ -1,24 +1,15 @@
-import { ChangeEventHandler, FC, MouseEventHandler } from 'react';
+import { FC, InputHTMLAttributes } from 'react';
import styles from './boolean-field.module.scss';
-export type BooleanFieldProps = {
- /**
- * One or more ids that refers to the checkbox name.
- */
- 'aria-labelledby'?: string;
+export type BooleanFieldProps = Omit<
+ InputHTMLAttributes<HTMLInputElement>,
+ 'checked' | 'hidden' | 'name' | 'type' | 'value'
+> & {
/**
* True if the field should be checked.
*/
checked: boolean;
/**
- * Add classnames to the checkbox.
- */
- className?: string;
- /**
- * Field id attribute.
- */
- id: string;
- /**
* True if the field should be visually hidden. Default: false.
*/
hidden?: boolean;
@@ -27,14 +18,6 @@ export type BooleanFieldProps = {
*/
name: string;
/**
- * Callback function to handle state change.
- */
- onChange: ChangeEventHandler<HTMLInputElement>;
- /**
- * A callback function to handle click.
- */
- onClick?: MouseEventHandler<HTMLInputElement>;
- /**
* The input type.
*/
type: 'checkbox' | 'radio';
@@ -49,14 +32,13 @@ export type BooleanFieldProps = {
*
* Render a checkbox or a radio input type.
*/
-const BooleanField: FC<BooleanFieldProps> = ({
+export const BooleanField: FC<BooleanFieldProps> = ({
className = '',
hidden = false,
...props
}) => {
const modifier = hidden ? 'hidden' : '';
+ const inputClass = `${styles[modifier]} ${className}`;
- return <input className={`${styles[modifier]} ${className}`} {...props} />;
+ return <input {...props} className={inputClass} />;
};
-
-export default BooleanField;
diff --git a/src/components/atoms/forms/field.stories.tsx b/src/components/atoms/forms/field.stories.tsx
index 00a183d..27fd3be 100644
--- a/src/components/atoms/forms/field.stories.tsx
+++ b/src/components/atoms/forms/field.stories.tsx
@@ -1,6 +1,6 @@
import { ComponentMeta, ComponentStory } from '@storybook/react';
import { useState } from 'react';
-import Field from './field';
+import { Field } from './field';
/**
* Field - Storybook Meta
diff --git a/src/components/atoms/forms/field.test.tsx b/src/components/atoms/forms/field.test.tsx
index 26ad764..492aa48 100644
--- a/src/components/atoms/forms/field.test.tsx
+++ b/src/components/atoms/forms/field.test.tsx
@@ -1,5 +1,5 @@
import { render, screen } from '../../../../tests/utils';
-import Field from './field';
+import { Field } from './field';
describe('Field', () => {
it('renders a text input', () => {
diff --git a/src/components/atoms/forms/field.tsx b/src/components/atoms/forms/field.tsx
index 377e1b0..a4553e3 100644
--- a/src/components/atoms/forms/field.tsx
+++ b/src/components/atoms/forms/field.tsx
@@ -72,12 +72,7 @@ export type FieldProps = {
value: string;
};
-/**
- * Field component.
- *
- * Render either an input or a textarea.
- */
-const Field: ForwardRefRenderFunction<HTMLInputElement, FieldProps> = (
+const FieldWithRef: ForwardRefRenderFunction<HTMLInputElement, FieldProps> = (
{ className = '', setValue, type, ...props },
ref
) => {
@@ -93,19 +88,24 @@ const Field: ForwardRefRenderFunction<HTMLInputElement, FieldProps> = (
return type === 'textarea' ? (
<textarea
- onChange={updateValue}
- className={`${styles.field} ${styles['field--textarea']} ${className}`}
{...props}
+ className={`${styles.field} ${styles['field--textarea']} ${className}`}
+ onChange={updateValue}
/>
) : (
<input
+ {...props}
className={`${styles.field} ${className}`}
onChange={updateValue}
ref={ref}
type={type}
- {...props}
/>
);
};
-export default forwardRef(Field);
+/**
+ * Field component.
+ *
+ * Render either an input or a textarea.
+ */
+export const Field = forwardRef(FieldWithRef);
diff --git a/src/components/atoms/forms/form.test.tsx b/src/components/atoms/forms/form.test.tsx
index 3a055ed..b040665 100644
--- a/src/components/atoms/forms/form.test.tsx
+++ b/src/components/atoms/forms/form.test.tsx
@@ -1,5 +1,5 @@
import { render, screen } from '../../../../tests/utils';
-import Form from './form';
+import { Form } from './form';
describe('Form', () => {
it('renders a form', () => {
diff --git a/src/components/atoms/forms/form.tsx b/src/components/atoms/forms/form.tsx
index 3307153..85ff8fd 100644
--- a/src/components/atoms/forms/form.tsx
+++ b/src/components/atoms/forms/form.tsx
@@ -1,24 +1,22 @@
-import { Children, FC, FormEvent, Fragment, ReactNode } from 'react';
+import {
+ Children,
+ FC,
+ FormEvent,
+ FormHTMLAttributes,
+ Fragment,
+ ReactNode,
+} from 'react';
import styles from './forms.module.scss';
-export type FormProps = {
- /**
- * An accessible name.
- */
- 'aria-label'?: string;
- /**
- * One or more ids that refers to the form name.
- */
- 'aria-labelledby'?: string;
+export type FormProps = Omit<
+ FormHTMLAttributes<HTMLFormElement>,
+ 'onSubmit'
+> & {
/**
* The form body.
*/
children: ReactNode;
/**
- * Set additional classnames to the form wrapper.
- */
- className?: string;
- /**
* Wrap each items with a div. Default: true.
*/
grouped?: boolean;
@@ -37,7 +35,7 @@ export type FormProps = {
*
* Render children wrapped in a form element.
*/
-const Form: FC<FormProps> = ({
+export const Form: FC<FormProps> = ({
children,
grouped = true,
itemsClassName = '',
@@ -75,10 +73,8 @@ const Form: FC<FormProps> = ({
};
return (
- <form onSubmit={handleSubmit} {...props}>
+ <form {...props} onSubmit={handleSubmit}>
{getFormItems()}
</form>
);
};
-
-export default Form;
diff --git a/src/components/atoms/forms/index.ts b/src/components/atoms/forms/index.ts
new file mode 100644
index 0000000..0af138f
--- /dev/null
+++ b/src/components/atoms/forms/index.ts
@@ -0,0 +1,5 @@
+export * from './boolean-field';
+export * from './field';
+export * from './form';
+export * from './label';
+export * from './select';
diff --git a/src/components/atoms/forms/label.stories.tsx b/src/components/atoms/forms/label.stories.tsx
index f66aa13..3adc92a 100644
--- a/src/components/atoms/forms/label.stories.tsx
+++ b/src/components/atoms/forms/label.stories.tsx
@@ -1,5 +1,5 @@
import { ComponentMeta, ComponentStory } from '@storybook/react';
-import LabelComponent from './label';
+import { Label as LabelComponent } from './label';
/**
* Label - Storybook Meta
diff --git a/src/components/atoms/forms/label.test.tsx b/src/components/atoms/forms/label.test.tsx
index 761d3b4..091737b 100644
--- a/src/components/atoms/forms/label.test.tsx
+++ b/src/components/atoms/forms/label.test.tsx
@@ -1,5 +1,5 @@
import { render, screen } from '../../../../tests/utils';
-import Label from './label';
+import { Label } from './label';
describe('Label', () => {
it('renders a field label', () => {
diff --git a/src/components/atoms/forms/label.tsx b/src/components/atoms/forms/label.tsx
index 2ec614f..6764579 100644
--- a/src/components/atoms/forms/label.tsx
+++ b/src/components/atoms/forms/label.tsx
@@ -1,24 +1,12 @@
-import { FC, ReactNode } from 'react';
+import { FC, LabelHTMLAttributes, ReactNode } from 'react';
import styles from './label.module.scss';
-export type LabelProps = {
- /**
- * An accessible name for the label.
- */
- 'aria-label'?: string;
+export type LabelProps = LabelHTMLAttributes<HTMLLabelElement> & {
/**
* The label body.
*/
children: ReactNode;
/**
- * Add classnames to the label.
- */
- className?: string;
- /**
- * The field id.
- */
- htmlFor?: string;
- /**
* Is the field required? Default: false.
*/
required?: boolean;
@@ -33,7 +21,7 @@ export type LabelProps = {
*
* Render a HTML label element.
*/
-const Label: FC<LabelProps> = ({
+export const Label: FC<LabelProps> = ({
children,
className = '',
required = false,
@@ -41,13 +29,12 @@ const Label: FC<LabelProps> = ({
...props
}) => {
const sizeClass = styles[`label--${size}`];
+ const labelClass = `${styles.label} ${sizeClass} ${className}`;
return (
- <label className={`${styles.label} ${sizeClass} ${className}`} {...props}>
+ <label {...props} className={labelClass}>
{children}
{required && <span className={styles.required}> *</span>}
</label>
);
};
-
-export default Label;
diff --git a/src/components/atoms/forms/select.stories.tsx b/src/components/atoms/forms/select.stories.tsx
index 7127597..b98ebed 100644
--- a/src/components/atoms/forms/select.stories.tsx
+++ b/src/components/atoms/forms/select.stories.tsx
@@ -1,6 +1,6 @@
import { ComponentMeta, ComponentStory } from '@storybook/react';
import { useState } from 'react';
-import SelectComponent from './select';
+import { Select as SelectComponent } from './select';
const selectOptions = [
{ id: 'option1', name: 'Option 1', value: 'option1' },
diff --git a/src/components/atoms/forms/select.test.tsx b/src/components/atoms/forms/select.test.tsx
index ca9f6d3..53d9b1f 100644
--- a/src/components/atoms/forms/select.test.tsx
+++ b/src/components/atoms/forms/select.test.tsx
@@ -1,5 +1,5 @@
import { render, screen } from '../../../../tests/utils';
-import Select from './select';
+import { Select } from './select';
const selectOptions = [
{ id: 'option1', name: 'Option 1', value: 'option1' },
diff --git a/src/components/atoms/forms/select.tsx b/src/components/atoms/forms/select.tsx
index dbe9b37..14f85dc 100644
--- a/src/components/atoms/forms/select.tsx
+++ b/src/components/atoms/forms/select.tsx
@@ -1,4 +1,4 @@
-import { ChangeEvent, FC, SetStateAction } from 'react';
+import { ChangeEvent, FC, SelectHTMLAttributes, SetStateAction } from 'react';
import styles from './forms.module.scss';
export type SelectOptions = {
@@ -16,19 +16,7 @@ export type SelectOptions = {
value: string;
};
-export type SelectProps = {
- /**
- * One or more ids that refers to the select field name.
- */
- 'aria-labelledby'?: string;
- /**
- * Add classnames to the select field.
- */
- className?: string;
- /**
- * Field state. Either enabled (false) or disabled (true).
- */
- disabled?: boolean;
+export type SelectProps = SelectHTMLAttributes<HTMLSelectElement> & {
/**
* Field id attribute.
*/
@@ -42,10 +30,6 @@ export type SelectProps = {
*/
options: SelectOptions[];
/**
- * True if the field is required. Default: false.
- */
- required?: boolean;
- /**
* Callback function to set field value.
*/
setValue: (value: SetStateAction<string>) => void;
@@ -60,12 +44,14 @@ export type SelectProps = {
*
* Render a HTML select element.
*/
-const Select: FC<SelectProps> = ({
+export const Select: FC<SelectProps> = ({
className = '',
options,
setValue,
...props
}) => {
+ const selectClass = `${styles.field} ${styles['field--select']} ${className}`;
+
/**
* Update select value when an option is selected.
* @param e - The option change event.
@@ -86,14 +72,8 @@ const Select: FC<SelectProps> = ({
));
return (
- <select
- className={`${styles.field} ${styles['field--select']} ${className}`}
- onChange={updateValue}
- {...props}
- >
+ <select {...props} className={selectClass} onChange={updateValue}>
{getOptions()}
</select>
);
};
-
-export default Select;