Skip to content

Commit

Permalink
feat: new component TextArea (#3199)
Browse files Browse the repository at this point in the history
* feat: new component TextArea

* fix: feedbacks

* fix: absolute content padding

* fix: update spacing between label and field

---------

Co-authored-by: Fabien Hébert <[email protected]>
  • Loading branch information
fabienhebert and Fabien Hébert authored Dec 18, 2023
1 parent 00233d1 commit 10c677f
Show file tree
Hide file tree
Showing 24 changed files with 2,145 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .changeset/hot-gorillas-behave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@ultraviolet/form': minor
'@ultraviolet/ui': minor
---

new components: `TextArea` and `TextAreaField`
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Template } from './Template.stories'

export const Playground = Template.bind({})

Playground.args = Template.args
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { StoryFn } from '@storybook/react'
import { Stack } from '@ultraviolet/ui'
import type { TextAreaFieldProps } from '..'
import { TextAreaField } from '..'
import { Submit } from '../../Submit'
import { Template } from './Template.stories'

export const Required: StoryFn<TextAreaFieldProps> = args => (
<Stack gap={1}>
<TextAreaField {...args} />
<Submit>Submit</Submit>
</Stack>
)

Required.args = { ...Template.args, required: true }
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { StoryFn } from '@storybook/react'
import type { TextAreaFieldProps } from '..'
import { TextAreaField } from '..'
import { Submit, TextInputField } from '../..'

export const Template: StoryFn<TextAreaFieldProps> = args => (
<div>
<TextAreaField {...args} />
<TextInputField name="example" required regex={[/[a-z]+/]} />
<Submit>Submit</Submit>
</div>
)

Template.args = {
label: 'Label',
name: 'textarea',
required: true,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { Meta } from '@storybook/react'
import { TextAreaField } from '..'
import { Form } from '../..'
import { mockErrors } from '../../../mocks'

export default {
component: TextAreaField,
decorators: [
ChildStory => (
<Form
onRawSubmit={() => {}}
errors={mockErrors}
initialValues={{
textarea: 'A long time ago in a galaxy far, far away',
}}
>
{ChildStory()}
</Form>
),
],
title: 'Form/Components/Fields/TextAreaField',
} as Meta

export { Playground } from './Playground.stories'
export { Required } from './Required.stories'
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`TextAreaField should render correctly 1`] = `
<DocumentFragment>
.cache-16otux {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
gap: 4px;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
-webkit-align-items: normal;
-webkit-box-align: normal;
-ms-flex-align: normal;
align-items: normal;
-webkit-box-pack: normal;
-ms-flex-pack: normal;
-webkit-justify-content: normal;
justify-content: normal;
-webkit-box-flex-wrap: nowrap;
-webkit-flex-wrap: nowrap;
-ms-flex-wrap: nowrap;
flex-wrap: nowrap;
}
.cache-9bqyx6 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
gap: 8px;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: normal;
-ms-flex-pack: normal;
-webkit-justify-content: normal;
justify-content: normal;
-webkit-box-flex-wrap: nowrap;
-webkit-flex-wrap: nowrap;
-ms-flex-wrap: nowrap;
flex-wrap: nowrap;
}
.cache-1l08jzy {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
gap: 4px;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
-webkit-align-items: start;
-webkit-box-align: start;
-ms-flex-align: start;
align-items: start;
-webkit-box-pack: normal;
-ms-flex-pack: normal;
-webkit-justify-content: normal;
justify-content: normal;
-webkit-box-flex-wrap: nowrap;
-webkit-flex-wrap: nowrap;
-ms-flex-wrap: nowrap;
flex-wrap: nowrap;
}
.cache-1qrwkk1 {
color: #3f4250;
font-size: 14px;
font-family: Inter,Asap;
font-weight: 500;
letter-spacing: 0;
line-height: 20px;
text-transform: none;
-webkit-text-decoration: none;
text-decoration: none;
}
.cache-8k1832 {
position: relative;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
.cache-m7sh0y {
width: 100%;
resize: vertical;
background: #ffffff;
border: 1px solid #d9dadd;
color: #3f4250;
border-radius: 4px;
padding: 12px 8px 12px 16px;
padding-right: calc(24px + 0px + 0px);
}
.cache-m7sh0y::-webkit-input-placeholder {
color: #727683;
}
.cache-m7sh0y::-moz-placeholder {
color: #727683;
}
.cache-m7sh0y:-ms-input-placeholder {
color: #727683;
}
.cache-m7sh0y::placeholder {
color: #727683;
}
.cache-m7sh0y:hover {
border-color: #8c40ef;
}
.cache-m7sh0y:focus {
outline: none;
border-color: #8c40ef;
box-shadow: 0px 0px 0px 3px #8c40ef40;
}
.cache-104ftim {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
gap: 8px;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: normal;
-ms-flex-pack: normal;
-webkit-justify-content: normal;
justify-content: normal;
-webkit-box-flex-wrap: nowrap;
-webkit-flex-wrap: nowrap;
-ms-flex-wrap: nowrap;
flex-wrap: nowrap;
position: absolute;
top: 12px;
right: 8px;
}
<form
novalidate=""
>
<div
class="cache-16otux ehpbis70"
>
<div
class="cache-9bqyx6 ehpbis70"
>
<div
class="cache-1l08jzy ehpbis70"
>
<label
class="cache-1qrwkk1 e13y3mga0"
for=":r0:"
>
Test
</label>
</div>
</div>
<div
class="cache-8k1832 enu776d2"
>
<textarea
aria-invalid="false"
class="cache-m7sh0y enu776d0"
id=":r0:"
name="test"
rows="3"
/>
<div
class="cache-104ftim enu776d1"
/>
</div>
</div>
</form>
</DocumentFragment>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { describe, expect, jest, test } from '@jest/globals'
import { screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { TextAreaField } from '..'
import { Submit } from '../..'
import {
renderWithTheme,
shouldMatchEmotionSnapshotFormWrapper,
} from '../../../../.jest/helpers'
import { mockErrors } from '../../../mocks'
import { Form } from '../../Form'

describe('TextAreaField', () => {
test('should render correctly', () =>
shouldMatchEmotionSnapshotFormWrapper(
<TextAreaField label="Test" name="test" />,
))

test('should render correctly generated', async () => {
const onSubmit = jest.fn<(values: { test: string }) => void>()

renderWithTheme(
<Form onRawSubmit={onSubmit} errors={mockErrors}>
<TextAreaField label="Test" name="test" required clearable />
<Submit>Submit</Submit>
</Form>,
)

await userEvent.click(screen.getByText('Submit'))
await waitFor(() => {
expect(onSubmit).toHaveBeenCalledTimes(0)
})
const textareaInput = screen.getByLabelText('Test')
await userEvent.type(textareaInput, 'This is an example')
await userEvent.click(screen.getByText('Submit'))
await waitFor(() => {
expect(onSubmit.mock.calls[0][0]).toEqual({
test: 'This is an example',
})
})
})
})
Loading

0 comments on commit 10c677f

Please sign in to comment.