From 7f111ed289c02c8a3b5c88020090abbd45e19185 Mon Sep 17 00:00:00 2001 From: donskov Date: Wed, 28 Feb 2024 18:40:02 +0200 Subject: [PATCH] chore(react-components): add default "id" generation for TextField and TextareaField --- .../__snapshots__/text_field.test.tsx.snap | 180 +------- .../src/TextField/text_field.stories.tsx | 5 - .../src/TextField/text_field.test.tsx | 57 ++- .../src/TextField/text_field.tsx | 8 +- .../textarea_field.test.tsx.snap | 421 ++++++++++++++++++ .../src/TextareaField/textarea_field.test.tsx | 43 +- .../src/TextareaField/textarea_field.tsx | 16 +- 7 files changed, 528 insertions(+), 202 deletions(-) diff --git a/packages/react-components/src/TextField/__snapshots__/text_field.test.tsx.snap b/packages/react-components/src/TextField/__snapshots__/text_field.test.tsx.snap index 6c261fc6..52f5769a 100644 --- a/packages/react-components/src/TextField/__snapshots__/text_field.test.tsx.snap +++ b/packages/react-components/src/TextField/__snapshots__/text_field.test.tsx.snap @@ -74,6 +74,7 @@ exports[` TextField render sizes size "large" 1`] = `
@@ -155,6 +156,7 @@ exports[` TextField render sizes size "medium" 1`] = `
@@ -236,6 +238,7 @@ exports[` TextField render sizes size "small" 1`] = `
@@ -318,6 +321,7 @@ exports[` TextField render variants should be disabled 1`] = ` @@ -401,6 +405,7 @@ exports[` TextField render variants should have className 1`] = ` > @@ -482,6 +487,7 @@ exports[` TextField render variants should have defaultValue 1`] =
@@ -574,6 +580,7 @@ exports[` TextField render variants should have error alert 1`] = ` @@ -586,88 +593,6 @@ exports[` TextField render variants should have error alert 1`] = ` `; -exports[` TextField render variants should have id 1`] = ` - - .emotion-0 { - margin: 0; - color: var(--pv-color-black); - font-weight: var(--pv-text-b3-weight); - font-size: var(--pv-text-b3-size); - line-height: var(--pv-text-b3-height); - letter-spacing: var(--pv-text-b3-spacing); - font-family: inherit; - outline: none; - box-sizing: border-box; - width: 100%; - border-radius: 4px; - padding: 0 var(--pv-size-base-2); - background-color: var(--pv-color-gray-1); - border-style: solid; - border-width: 1px; - -webkit-transition: background-color 200ms,color 200ms,border-color 200ms; - transition: background-color 200ms,color 200ms,border-color 200ms; - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; - -webkit-appearance: none; - -moz-appearance: none; - -ms-appearance: none; - appearance: none; - height: var(--pv-size-base-7); - color: var(--pv-color-black); - border-color: var(--pv-color-gray-8); -} - -.emotion-0::-webkit-input-placeholder { - color: var(--pv-color-gray-9); -} - -.emotion-0::-moz-placeholder { - color: var(--pv-color-gray-9); -} - -.emotion-0:-ms-input-placeholder { - color: var(--pv-color-gray-9); -} - -.emotion-0::placeholder { - color: var(--pv-color-gray-9); -} - -.emotion-0:hover { - background-color: var(--pv-color-gray-3); - border-color: var(--pv-color-gray-7); -} - -.emotion-0:disabled { - cursor: not-allowed; - background-color: var(--pv-color-gray-1); - border-color: var(--pv-color-gray-5); - color: var(--pv-color-gray-7); -} - -.emotion-0:not(:disabled)[aria-invalid] { - background-color: var(--pv-color-wrong-tint-5); - border-color: var(--pv-color-wrong-tint-3); -} - -.emotion-0:not(:disabled):focus-visible { - background-color: var(--pv-color-secondary-tint-5); - border-color: var(--pv-color-secondary-tint-3); -} - -
- -
-
-`; - exports[` TextField render variants should have label 1`] = ` .emotion-0 { @@ -756,6 +681,8 @@ exports[` TextField render variants should have label 1`] = `
@@ -846,6 +774,7 @@ exports[` TextField render variants should have name attr 1`] = `
TextField render variants should have placeholder 1`] = `
TextField render variants should have required 1`] = `
TextField render variants should have required 1`] = ` `; -exports[` TextField render variants should have test id 1`] = ` - - .emotion-0 { - margin: 0; - color: var(--pv-color-black); - font-weight: var(--pv-text-b3-weight); - font-size: var(--pv-text-b3-size); - line-height: var(--pv-text-b3-height); - letter-spacing: var(--pv-text-b3-spacing); - font-family: inherit; - outline: none; - box-sizing: border-box; - width: 100%; - border-radius: 4px; - padding: 0 var(--pv-size-base-2); - background-color: var(--pv-color-gray-1); - border-style: solid; - border-width: 1px; - -webkit-transition: background-color 200ms,color 200ms,border-color 200ms; - transition: background-color 200ms,color 200ms,border-color 200ms; - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; - -webkit-appearance: none; - -moz-appearance: none; - -ms-appearance: none; - appearance: none; - height: var(--pv-size-base-7); - color: var(--pv-color-black); - border-color: var(--pv-color-gray-8); -} - -.emotion-0::-webkit-input-placeholder { - color: var(--pv-color-gray-9); -} - -.emotion-0::-moz-placeholder { - color: var(--pv-color-gray-9); -} - -.emotion-0:-ms-input-placeholder { - color: var(--pv-color-gray-9); -} - -.emotion-0::placeholder { - color: var(--pv-color-gray-9); -} - -.emotion-0:hover { - background-color: var(--pv-color-gray-3); - border-color: var(--pv-color-gray-7); -} - -.emotion-0:disabled { - cursor: not-allowed; - background-color: var(--pv-color-gray-1); - border-color: var(--pv-color-gray-5); - color: var(--pv-color-gray-7); -} - -.emotion-0:not(:disabled)[aria-invalid] { - background-color: var(--pv-color-wrong-tint-5); - border-color: var(--pv-color-wrong-tint-3); -} - -.emotion-0:not(:disabled):focus-visible { - background-color: var(--pv-color-secondary-tint-5); - border-color: var(--pv-color-secondary-tint-3); -} - -
- -
-
-`; - exports[` TextField render variants should have value 1`] = ` .emotion-0 { @@ -1175,6 +1023,7 @@ exports[` TextField render variants should have value 1`] = `
@@ -1256,6 +1105,7 @@ exports[` TextField render variants should render as default 1`] =
diff --git a/packages/react-components/src/TextField/text_field.stories.tsx b/packages/react-components/src/TextField/text_field.stories.tsx index f933f627..389c29bb 100644 --- a/packages/react-components/src/TextField/text_field.stories.tsx +++ b/packages/react-components/src/TextField/text_field.stories.tsx @@ -27,30 +27,25 @@ export const FormExample = () => ( defaultValue="Hello World" required label="Required" - id="TextField-required" /> ); diff --git a/packages/react-components/src/TextField/text_field.test.tsx b/packages/react-components/src/TextField/text_field.test.tsx index 79277643..ea95b746 100644 --- a/packages/react-components/src/TextField/text_field.test.tsx +++ b/packages/react-components/src/TextField/text_field.test.tsx @@ -5,7 +5,7 @@ import { TextField } from './index'; describe('', () => { describe('TextField render variants', () => { it('should render as default', () => { - const { asFragment } = render(); + const { asFragment } = render(); const input = screen.getByRole('textbox'); @@ -17,43 +17,42 @@ describe('', () => { }); it('should have label', () => { - const { asFragment } = render(); - - expect(asFragment()).toMatchSnapshot(); - }); - - it('should have id', () => { - const { asFragment } = render(); + const { asFragment } = render( + , + ); expect(asFragment()).toMatchSnapshot(); }); it('should be disabled', () => { - const { asFragment } = render(); + const { asFragment } = render(); expect(asFragment()).toMatchSnapshot(); }); it('should have required', () => { - const { asFragment } = render(); + const { asFragment } = render(); expect(asFragment()).toMatchSnapshot(); }); it('should have name attr', () => { - const { asFragment } = render(); - - expect(asFragment()).toMatchSnapshot(); - }); - - it('should have test id', () => { - const { asFragment } = render(); + const { asFragment } = render(); expect(asFragment()).toMatchSnapshot(); }); it('should have className', () => { - const { asFragment } = render(); + const { asFragment } = render( + , + ); expect(asFragment()).toMatchSnapshot(); }); @@ -79,7 +78,7 @@ describe('', () => { }); it('should have placeholder', () => { - const { asFragment } = render(); + const { asFragment } = render(); const input = screen.getByRole('textbox'); @@ -89,7 +88,7 @@ describe('', () => { }); it('should have defaultValue', () => { - const { asFragment } = render(); + const { asFragment } = render(); const input = screen.getByRole('textbox'); @@ -101,7 +100,13 @@ describe('', () => { it('should have value', () => { const onChange = jest.fn(); - const { asFragment } = render(); + const { asFragment } = render( + , + ); const input = screen.getByRole('textbox'); @@ -111,7 +116,13 @@ describe('', () => { }); it('should have error alert', () => { - const { asFragment } = render(); + const { asFragment } = render( + , + ); expect(screen.getByText('Error message')).toBeInTheDocument(); @@ -129,7 +140,7 @@ describe('', () => { sizes.forEach((size) => { it(`size "${size}"`, () => { const { asFragment } = render( - , + , ); expect(asFragment()).toMatchSnapshot(); diff --git a/packages/react-components/src/TextField/text_field.tsx b/packages/react-components/src/TextField/text_field.tsx index 031b599b..bb9c7ddc 100644 --- a/packages/react-components/src/TextField/text_field.tsx +++ b/packages/react-components/src/TextField/text_field.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import styled from '@emotion/styled'; import { Typography } from '../Typography'; +import { useId } from '../hooks/use_id'; /** * Types. @@ -35,7 +36,7 @@ type TextFieldOwnProps = { */ id?: string; /** - * The label of the input. It is only used for layout. + * The label content. */ label?: string; /** @@ -192,7 +193,7 @@ export const TextField = React.forwardRef((props inputProps = {}, disabled, defaultValue, - id, + id: idProp, value, placeholder, required, @@ -206,6 +207,8 @@ export const TextField = React.forwardRef((props onChange, ...other } = props; + const id = useId(idProp); + const inputLabelId = label && id ? `${id}-label` : undefined; return (
((props {label && ( should be disabled 1`] = ` + + .emotion-0 { + margin: 0; + color: var(--pv-color-black); + font-weight: var(--pv-text-b3-weight); + font-size: var(--pv-text-b3-size); + line-height: var(--pv-text-b3-height); + letter-spacing: var(--pv-text-b3-spacing); + font-family: inherit; + outline: none; + box-sizing: border-box; + width: 100%; + border-radius: 4px; + padding: var(--pv-size-base) var(--pv-size-base-2); + background-color: var(--pv-color-gray-1); + border-style: solid; + border-width: 1px; + -webkit-transition: background-color 200ms,color 200ms,border-color 200ms; + transition: background-color 200ms,color 200ms,border-color 200ms; + display: block; + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + appearance: none; + resize: none; + min-height: var(--pv-size-base-14); + color: var(--pv-color-black); + border-color: var(--pv-color-gray-8); +} + +.emotion-0::-webkit-input-placeholder { + color: var(--pv-color-gray-9); +} + +.emotion-0::-moz-placeholder { + color: var(--pv-color-gray-9); +} + +.emotion-0:-ms-input-placeholder { + color: var(--pv-color-gray-9); +} + +.emotion-0::placeholder { + color: var(--pv-color-gray-9); +} + +.emotion-0:hover { + background-color: var(--pv-color-gray-3); + border-color: var(--pv-color-gray-7); +} + +.emotion-0:disabled { + cursor: not-allowed; + background-color: var(--pv-color-gray-1); + border-color: var(--pv-color-gray-5); + color: var(--pv-color-gray-7); +} + +.emotion-0:not(:disabled)[aria-invalid] { + background-color: var(--pv-color-wrong-tint-5); + border-color: var(--pv-color-wrong-tint-3); +} + +.emotion-0:not(:disabled):focus-visible { + background-color: var(--pv-color-secondary-tint-5); + border-color: var(--pv-color-secondary-tint-3); +} + +
+