Skip to content

Commit

Permalink
feat(TextareaField)!: introduce 2.0 component (#1911)
Browse files Browse the repository at this point in the history
- add stories
- add component updates
- include checks and integrtion between InputField
  • Loading branch information
booc0mtaco authored Apr 3, 2024
1 parent f6ebbdf commit a68a255
Show file tree
Hide file tree
Showing 6 changed files with 520 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/components/InputField/InputField-v2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ export const InputField: InputFieldType = forwardRef(
leadingIcon,
maxLength,
onChange,
readOnly,
recommendedMaxLength,
required,
showHint,
Expand Down Expand Up @@ -289,6 +290,7 @@ export const InputField: InputFieldType = forwardRef(
setFieldText(e.target.value);
onChange && onChange(e);
}}
readOnly={readOnly}
ref={ref}
required={required}
type={type}
Expand Down
53 changes: 53 additions & 0 deletions src/components/TextareaField/TextareaField-v2.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
@import '../../design-tokens/mixins.css';

/*------------------------------------*\
# TEXTAREA FIELD
\*------------------------------------*/

/**
* Default input styles
*/
.textarea {
@mixin inputStylesV2;
}

/**
* Wraps the Label and the optional/required indicator.
*/
.textarea-field__overline {
display: flex;
margin-bottom: 0.25rem;
gap: 0.25rem;
}

.textarea-field__overline--no-label {
justify-content: flex-start;
}

.textarea-field__label {
font: var(--eds-theme-typography-form-label);
}

.textarea-field__label--disabled {
color: var(--eds-theme-color-text-utility-disabled-primary);
}

.textarea-field--invalid-length {
color: var(--eds-theme-color-text-utility-critical);
}

.textarea-field__footer {
display: flex;
justify-content: space-between;
}

.textarea-field__field-note {
flex: 1 0 50%;
}

.textarea-field__character-counter {
font: var(--eds-theme-typography-body-sm);

flex: 1 0 50%;
text-align: right;
}
161 changes: 161 additions & 0 deletions src/components/TextareaField/TextareaField-v2.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import type { StoryObj, Meta } from '@storybook/react';
import React from 'react';

import { TextareaField } from './TextareaField-v2';

const meta: Meta<typeof TextareaField> = {
title: 'Components/V2/TextareaField',
component: TextareaField,
args: {
placeholder: 'Enter long-form text here',
defaultValue: `Lorem ipsum, dolor sit amet consectetur adipisicing elit. Id neque nemo
dicta rerum commodi et fugiat quo optio veniam! Ea odio corporis nemo
praesentium, commodi eligendi asperiores quis dolorum porro.`,
label: 'Textarea Field',
rows: 5,
fieldNote: 'Longer Field description',
spellCheck: false,
},
parameters: {
badges: ['intro-1.3', 'current-2.0'],
},
decorators: [(Story) => <div className="p-8">{Story()}</div>],
};

export default meta;
type Story = StoryObj<typeof TextareaField>;

export const Default: Story = {
render: (args) => (
<TextareaField aria-label="Text Label" {...args}></TextareaField>
),
};

/**
* You can specify the content of `TextareaField` by using children. Convenient for cases where
* specifying `value` or `defaultValue` is inconvenient.
*/
export const WhenUsingChildren: Story = {
args: {
children: `Lorem ipsum, dolor sit amet consectetur adipisicing elit. Id neque nemo
dicta rerum commodi et fugiat quo optio veniam! Ea odio corporis nemo
praesentium, commodi eligendi asperiores quis dolorum porro.`,
defaultValue: '',
},
};

/**
* `TextareaField` does not require any initial content.
*/
export const WhenNoDefaultValue: Story = {
args: {
defaultValue: undefined,
fieldNote: undefined,
},
};

export const WhenDisabled: Story = {
args: {
disabled: true,
rows: 2,
},
parameters: {
axe: {
// Disabled input does not need to meet color contrast
disabledRules: ['color-contrast'],
},
},
};

export const WhenReadOnly: Story = {
args: {
readOnly: true,
rows: 2,
},
parameters: {
axe: {
// Disabled input does not need to meet color contrast
disabledRules: ['color-contrast'],
},
},
};

export const WhenError: Story = {
args: {
isError: true,
fieldNote: 'Text should be at least 100 characters',
},
};

export const WhenWarning: Story = {
args: {
isWarning: true,
fieldNote: 'Text should be at least 100 characters',
},
};

export const WhenRequired: Story = {
args: {
required: true,
showHint: true,
},
};

export const WhenOptional: Story = {
args: {
required: false,
showHint: true,
},
};

/**
* You can size `TextareaField` by specifying `row` attribute, inherited from
* [textarea](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea).
*/
export const WithADifferentSize: Story = {
args: {
rows: 10,
},
};

/**
* You can lock the maximum length of the text content of `TextareaField`. When setting `maxLength`,
* the field will reuse the browser's [textarea](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea)
* behavior (e.g., prevent further text from being typed, prevent keydown events, etc.).
*/
export const WithAMaxLength: Story = {
args: {
rows: 10,
maxLength: 144,
required: true,
},
render: (args) => <TextareaField {...args} />,
};

/**
* If you want to signal that a field has reached a maximum length but want to allow more text to be typed, you can use
* `recommendedMaxLength`. This will show a similar UI to using `maxLength` but will allow more text to be typed, and
* emit any appropriate events.
*/
export const WithARecommendedLength: Story = {
args: {
rows: 10,
recommendedMaxLength: 144,
required: true,
},
render: (args) => <TextareaField {...args} />,
};

/**
* Both `maxLength` and `recommendedMaxLength` can be specified at the same time. Text length between `recommendedMaxLength`
* and `maxLength` will show the treatment warning the user about the text length being violated.
*/
export const WithBothRecommendedAndMaxLengths: Story = {
args: {
rows: 10,
maxLength: 256,
recommendedMaxLength: 144,
required: true,
},
render: (args) => <TextareaField {...args} />,
};
Loading

0 comments on commit a68a255

Please sign in to comment.