From b198f0b87e58fd915505bbbf1ec288477985c12a Mon Sep 17 00:00:00 2001 From: Eric Olkowski Date: Mon, 22 Jan 2024 08:22:49 -0500 Subject: [PATCH 1/5] feat(HelperText): consumed Penta updates --- .../components/HelperText/HelperTextItem.tsx | 54 ++++++------------- .../HelperText/examples/HelperText.md | 20 ++----- .../HelperText/examples/HelperTextBasic.tsx | 22 ++++++++ .../HelperText/examples/HelperTextDynamic.tsx | 41 -------------- .../examples/HelperTextDynamicList.tsx | 16 ------ .../examples/HelperTextMultipleItems.tsx | 10 ++++ .../examples/HelperTextMultipleStatic.tsx | 10 ---- .../HelperText/examples/HelperTextStatic.tsx | 22 -------- .../HelperTextStaticWithDefaultIcon.tsx | 30 ----------- ...mIcon.tsx => HelperTextWithCustomIcon.tsx} | 10 ++-- .../HelperTextDynamicVariantStaticText.tsx | 4 +- 11 files changed, 61 insertions(+), 178 deletions(-) create mode 100644 packages/react-core/src/components/HelperText/examples/HelperTextBasic.tsx delete mode 100644 packages/react-core/src/components/HelperText/examples/HelperTextDynamic.tsx delete mode 100644 packages/react-core/src/components/HelperText/examples/HelperTextDynamicList.tsx create mode 100644 packages/react-core/src/components/HelperText/examples/HelperTextMultipleItems.tsx delete mode 100644 packages/react-core/src/components/HelperText/examples/HelperTextMultipleStatic.tsx delete mode 100644 packages/react-core/src/components/HelperText/examples/HelperTextStatic.tsx delete mode 100644 packages/react-core/src/components/HelperText/examples/HelperTextStaticWithDefaultIcon.tsx rename packages/react-core/src/components/HelperText/examples/{HelperTextStaticWithCustomIcon.tsx => HelperTextWithCustomIcon.tsx} (75%) diff --git a/packages/react-core/src/components/HelperText/HelperTextItem.tsx b/packages/react-core/src/components/HelperText/HelperTextItem.tsx index 46665f777c4..13f62dc3717 100644 --- a/packages/react-core/src/components/HelperText/HelperTextItem.tsx +++ b/packages/react-core/src/components/HelperText/HelperTextItem.tsx @@ -13,72 +13,52 @@ export interface HelperTextItemProps extends React.HTMLProps, + warning: , + success: , + error: }; export const HelperTextItem: React.FunctionComponent = ({ children, className, component = 'div', - variant = 'default', + status, icon, - isDynamic = false, - hasIcon = isDynamic, id, - screenReaderText = `${variant} status`, + screenReaderText = `${status} status`, ...props }: HelperTextItemProps) => { const Component = component as any; return ( - - {icon && ( - - {icon} - - )} - {hasIcon && !icon && ( + + {(status || icon) && ( - {(variant === 'default' || variant === 'indeterminate') && } - {variant === 'warning' && } - {variant === 'success' && } - {variant === 'error' && } + {icon || defaultStatusIcons[status]} )} {children} - {isDynamic && : {screenReaderText};} + {status && : {screenReaderText};} ); diff --git a/packages/react-core/src/components/HelperText/examples/HelperText.md b/packages/react-core/src/components/HelperText/examples/HelperText.md index 0351e8b92b3..4c73fe3a04c 100644 --- a/packages/react-core/src/components/HelperText/examples/HelperText.md +++ b/packages/react-core/src/components/HelperText/examples/HelperText.md @@ -13,32 +13,22 @@ import ExclamationIcon from '@patternfly/react-icons/dist/esm/icons/exclamation- ## Examples -### Static +### Basic ```ts file="HelperTextStatic.tsx" -``` - -### Static with default icons -```ts file="HelperTextStaticWithDefaultIcon.tsx" ``` -### Static with custom icons +### With custom icons ```ts file="HelperTextStaticWithCustomIcon.tsx" -``` - -### Multiple static -```ts file="HelperTextMultipleStatic.tsx" ``` -### Dynamic +### Multiple items -```ts file="HelperTextDynamic.tsx" -``` +You can pass multiple `` components inside a single `` container. -### Dynamic list +```ts file="HelperTextMultipleStatic.tsx" -```ts file="HelperTextDynamicList.tsx" ``` diff --git a/packages/react-core/src/components/HelperText/examples/HelperTextBasic.tsx b/packages/react-core/src/components/HelperText/examples/HelperTextBasic.tsx new file mode 100644 index 00000000000..5ee386ee82d --- /dev/null +++ b/packages/react-core/src/components/HelperText/examples/HelperTextBasic.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { HelperText, HelperTextItem } from '@patternfly/react-core'; + +export const HelperTextBasic: React.FunctionComponent = () => ( + + + This is default helper text + + + This is indeterminate helper text + + + This is warning helper text + + + This is success helper text + + + This is error helper text + + +); diff --git a/packages/react-core/src/components/HelperText/examples/HelperTextDynamic.tsx b/packages/react-core/src/components/HelperText/examples/HelperTextDynamic.tsx deleted file mode 100644 index 23791753dce..00000000000 --- a/packages/react-core/src/components/HelperText/examples/HelperTextDynamic.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import React from 'react'; -import { HelperText, HelperTextItem } from '@patternfly/react-core'; -import TimesIcon from '@patternfly/react-icons/dist/esm/icons/times-icon'; - -export const HelperTextDynamic: React.FunctionComponent = () => ( - - - This is default helper text - - - - This is indeterminate helper text - - - - - This is warning helper text - - - - - This is success helper text - - - - - This is error helper text - - - - }> - This is error helper text with a custom icon - - - - - This is error helper text with no icon - - - -); diff --git a/packages/react-core/src/components/HelperText/examples/HelperTextDynamicList.tsx b/packages/react-core/src/components/HelperText/examples/HelperTextDynamicList.tsx deleted file mode 100644 index adf3941c412..00000000000 --- a/packages/react-core/src/components/HelperText/examples/HelperTextDynamicList.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react'; -import { HelperText, HelperTextItem } from '@patternfly/react-core'; - -export const HelperTextDynamicList: React.FunctionComponent = () => ( - - - Must be at least 14 characters - - - Cannot contain any variation of the word "redhat" - - - Must include at least 3 of the following: lowercase letter, uppercase letters, numbers, symbols - - -); diff --git a/packages/react-core/src/components/HelperText/examples/HelperTextMultipleItems.tsx b/packages/react-core/src/components/HelperText/examples/HelperTextMultipleItems.tsx new file mode 100644 index 00000000000..b8fc8b2afc8 --- /dev/null +++ b/packages/react-core/src/components/HelperText/examples/HelperTextMultipleItems.tsx @@ -0,0 +1,10 @@ +import React from 'react'; +import { HelperText, HelperTextItem } from '@patternfly/react-core'; + +export const HelperTextMultipleItems: React.FunctionComponent = () => ( + + This is default helper text + This is another default helper text in the same HelperText block + And this is more default text in the same HelperText block + +); diff --git a/packages/react-core/src/components/HelperText/examples/HelperTextMultipleStatic.tsx b/packages/react-core/src/components/HelperText/examples/HelperTextMultipleStatic.tsx deleted file mode 100644 index e9f8e07c5c2..00000000000 --- a/packages/react-core/src/components/HelperText/examples/HelperTextMultipleStatic.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react'; -import { HelperText, HelperTextItem } from '@patternfly/react-core'; - -export const HelperTextMultipleStatic: React.FunctionComponent = () => ( - - This is default helper text - This is another default helper text in the same block - And this is more default text in the same block - -); diff --git a/packages/react-core/src/components/HelperText/examples/HelperTextStatic.tsx b/packages/react-core/src/components/HelperText/examples/HelperTextStatic.tsx deleted file mode 100644 index f7b68670707..00000000000 --- a/packages/react-core/src/components/HelperText/examples/HelperTextStatic.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import React from 'react'; -import { HelperText, HelperTextItem } from '@patternfly/react-core'; - -export const HelperTextStatic: React.FunctionComponent = () => ( - - - This is default helper text - - - This is indeterminate helper text - - - This is warning helper text - - - This is success helper text - - - This is error helper text - - -); diff --git a/packages/react-core/src/components/HelperText/examples/HelperTextStaticWithDefaultIcon.tsx b/packages/react-core/src/components/HelperText/examples/HelperTextStaticWithDefaultIcon.tsx deleted file mode 100644 index da1b3a6a731..00000000000 --- a/packages/react-core/src/components/HelperText/examples/HelperTextStaticWithDefaultIcon.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react'; -import { HelperText, HelperTextItem } from '@patternfly/react-core'; - -export const HelperTextStaticWithDefaultIcon: React.FunctionComponent = () => ( - - - This is default helper text - - - - This is indeterminate helper text - - - - - This is warning helper text - - - - - This is success helper text - - - - - This is error helper text - - - -); diff --git a/packages/react-core/src/components/HelperText/examples/HelperTextStaticWithCustomIcon.tsx b/packages/react-core/src/components/HelperText/examples/HelperTextWithCustomIcon.tsx similarity index 75% rename from packages/react-core/src/components/HelperText/examples/HelperTextStaticWithCustomIcon.tsx rename to packages/react-core/src/components/HelperText/examples/HelperTextWithCustomIcon.tsx index 3e93d8646de..d2d81de7ffb 100644 --- a/packages/react-core/src/components/HelperText/examples/HelperTextStaticWithCustomIcon.tsx +++ b/packages/react-core/src/components/HelperText/examples/HelperTextWithCustomIcon.tsx @@ -6,28 +6,28 @@ import ExclamationIcon from '@patternfly/react-icons/dist/esm/icons/exclamation- import CheckIcon from '@patternfly/react-icons/dist/esm/icons/check-icon'; import TimesIcon from '@patternfly/react-icons/dist/esm/icons/times-icon'; -export const HelperTextStaticWithCustomIcon: React.FunctionComponent = () => ( +export const HelperTextWithCustomIcon: React.FunctionComponent = () => ( }>This is default helper text - }> + }> This is indeterminate helper text - }> + }> This is warning helper text - }> + }> This is success helper text - }> + }> This is error helper text diff --git a/packages/react-core/src/demos/examples/HelperText/HelperTextDynamicVariantStaticText.tsx b/packages/react-core/src/demos/examples/HelperText/HelperTextDynamicVariantStaticText.tsx index 127959f66d6..aa332c7bfa4 100644 --- a/packages/react-core/src/demos/examples/HelperText/HelperTextDynamicVariantStaticText.tsx +++ b/packages/react-core/src/demos/examples/HelperText/HelperTextDynamicVariantStaticText.tsx @@ -57,10 +57,10 @@ export const HelperTextDynamicVariantDynamicText: React.FunctionComponent = () = /> - + Must be at least 5 characters in length - + Must include at least 1 number From cffb89ebaac1af09cdf296a7236af0059ed2ca60 Mon Sep 17 00:00:00 2001 From: Eric Olkowski Date: Mon, 22 Jan 2024 09:56:43 -0500 Subject: [PATCH 2/5] Updated examples and tests --- .../components/HelperText/HelperTextItem.tsx | 37 +++++++++----- .../__tests__/HelperTextItem.test.tsx | 51 ++++++++++--------- .../HelperText/examples/HelperTextBasic.tsx | 8 +-- .../examples/HelperTextWithCustomIcon.tsx | 8 +-- .../examples/MultipleFileUploadBasic.tsx | 4 +- packages/react-core/src/demos/HelperText.md | 25 +++++---- ...tDynamicText.tsx => HelperTextDynamic.tsx} | 4 +- ...antStaticText.tsx => HelperTextStatic.tsx} | 4 +- ...=> HelperTextStaticTextDynamicVariant.tsx} | 20 ++++---- .../PasswordStrength/PasswordStrengthDemo.tsx | 6 +-- 10 files changed, 93 insertions(+), 74 deletions(-) rename packages/react-core/src/demos/examples/HelperText/{HelperTextStaticVariantDynamicText.tsx => HelperTextDynamic.tsx} (88%) rename packages/react-core/src/demos/examples/HelperText/{HelperTextStaticVariantStaticText.tsx => HelperTextStatic.tsx} (80%) rename packages/react-core/src/demos/examples/HelperText/{HelperTextDynamicVariantStaticText.tsx => HelperTextStaticTextDynamicVariant.tsx} (78%) diff --git a/packages/react-core/src/components/HelperText/HelperTextItem.tsx b/packages/react-core/src/components/HelperText/HelperTextItem.tsx index 13f62dc3717..25812cc9ee1 100644 --- a/packages/react-core/src/components/HelperText/HelperTextItem.tsx +++ b/packages/react-core/src/components/HelperText/HelperTextItem.tsx @@ -6,6 +6,13 @@ import ExclamationTriangleIcon from '@patternfly/react-icons/dist/esm/icons/excl import CheckCircleIcon from '@patternfly/react-icons/dist/esm/icons/check-circle-icon'; import ExclamationCircleIcon from '@patternfly/react-icons/dist/esm/icons/exclamation-circle-icon'; +export enum HelperTextItemVariant { + default = 'default', + warning = 'warning', + error = 'error', + success = 'success' +} + export interface HelperTextItemProps extends React.HTMLProps { /** Content rendered inside the helper text item. */ children?: React.ReactNode; @@ -13,24 +20,25 @@ export interface HelperTextItemProps extends React.HTMLProps, indeterminate: , warning: , success: , @@ -41,24 +49,29 @@ export const HelperTextItem: React.FunctionComponent = ({ children, className, component = 'div', - status, + variant = 'default', icon, id, - screenReaderText = `${status} status`, + screenReaderText = `${variant} status`, ...props }: HelperTextItemProps) => { const Component = component as any; + const isNotDefaultVariant = variant !== 'default'; return ( - - {(status || icon) && ( + + {(isNotDefaultVariant || icon) && ( - {icon || defaultStatusIcons[status]} + {icon || defaultVariantIcons[variant]} )} {children} - {status && : {screenReaderText};} + {isNotDefaultVariant && : {screenReaderText};} ); diff --git a/packages/react-core/src/components/HelperText/__tests__/HelperTextItem.test.tsx b/packages/react-core/src/components/HelperText/__tests__/HelperTextItem.test.tsx index 158f88c7d68..4ef5fb26b7a 100644 --- a/packages/react-core/src/components/HelperText/__tests__/HelperTextItem.test.tsx +++ b/packages/react-core/src/components/HelperText/__tests__/HelperTextItem.test.tsx @@ -30,6 +30,12 @@ test('Renders custom className', () => { expect(screen.getByText('help test text 1').parentElement).toHaveClass('custom'); }); +test('Does not render screen reader text by default', () => { + render(help test text 1); + + expect(screen.queryByText('help test text 1')?.querySelector('.pf-v5-screen-reader')).not.toBeInTheDocument(); +}); + Object.values(['indeterminate', 'warning', 'success', 'error']).forEach((variant) => { test(`Renders with class ${styles.modifiers[variant]} when variant = ${variant}`, () => { render( @@ -39,6 +45,15 @@ Object.values(['indeterminate', 'warning', 'success', 'error']).forEach((variant ); expect(screen.getByText('text').parentElement).toHaveClass(styles.modifiers[variant]); }); + + test(`Renders default screenreader text when variant = ${variant}`, () => { + render( + + text + + ); + expect(screen.getByText('text').querySelector('span')).toHaveTextContent(`: ${variant} status;`); + }); }); test('Renders id when id is passed', () => { @@ -56,38 +71,26 @@ test('Renders with element passed to component prop', () => { expect(screen.getByText('help test text 1').parentElement?.tagName).toBe('LI'); }); -test('Renders custom icon', () => { - render(test}>help test text); - expect(screen.getByText('test').parentElement).toHaveClass(styles.helperTextItemIcon); -}); - -test('Renders default icon when hasIcon = true and icon is not passed', () => { - render(help test text); - expect(screen.getByText('help test text').parentElement?.querySelector('span')).toHaveClass( - styles.helperTextItemIcon - ); +test('Does not render an icon by default', () => { + render(help test text); + expect(screen.queryByText('help test text')?.previousSibling).not.toBeInTheDocument(); }); -test('Renders custom icon when icon is passed and hasIcon = true', () => { - render( - test}> - help test text - - ); - expect(screen.getByText('test').parentElement).toHaveClass(styles.helperTextItemIcon); +test('Renders a default icon when variant is passed and icon is not passed', () => { + render(help test text); + expect(screen.getByText('help test text').previousSibling).toHaveClass(styles.helperTextItemIcon); }); -test('Renders dynamic helper text', () => { - render(help test text); - expect(screen.getByText('help test text').parentElement).toHaveClass(styles.modifiers.dynamic); - expect(screen.getByText('help test text').querySelector('span')).toHaveClass('pf-v5-screen-reader'); +test('Renders custom icon when icon prop is passed', () => { + render(icon content}>help test text); + expect(screen.getByText('icon content').parentElement).toHaveClass(styles.helperTextItemIcon); }); -test('Renders custom screenreader text when isDynamic = true and screenReaderText is passed', () => { +test('Renders custom icon instead of variant icon when icon and variant are passed', () => { render( - + icon content} variant="success"> help test text ); - expect(screen.getByText('help test text').querySelector('span')).toHaveTextContent('sr test'); + expect(screen.getByText('icon content').parentElement).toHaveClass(styles.helperTextItemIcon); }); diff --git a/packages/react-core/src/components/HelperText/examples/HelperTextBasic.tsx b/packages/react-core/src/components/HelperText/examples/HelperTextBasic.tsx index 5ee386ee82d..0ef67cced25 100644 --- a/packages/react-core/src/components/HelperText/examples/HelperTextBasic.tsx +++ b/packages/react-core/src/components/HelperText/examples/HelperTextBasic.tsx @@ -7,16 +7,16 @@ export const HelperTextBasic: React.FunctionComponent = () => ( This is default helper text - This is indeterminate helper text + This is indeterminate helper text - This is warning helper text + This is warning helper text - This is success helper text + This is success helper text - This is error helper text + This is error helper text ); diff --git a/packages/react-core/src/components/HelperText/examples/HelperTextWithCustomIcon.tsx b/packages/react-core/src/components/HelperText/examples/HelperTextWithCustomIcon.tsx index d2d81de7ffb..162f573a655 100644 --- a/packages/react-core/src/components/HelperText/examples/HelperTextWithCustomIcon.tsx +++ b/packages/react-core/src/components/HelperText/examples/HelperTextWithCustomIcon.tsx @@ -12,22 +12,22 @@ export const HelperTextWithCustomIcon: React.FunctionComponent = () => ( }>This is default helper text - }> + }> This is indeterminate helper text - }> + }> This is warning helper text - }> + }> This is success helper text - }> + }> This is error helper text diff --git a/packages/react-core/src/components/MultipleFileUpload/examples/MultipleFileUploadBasic.tsx b/packages/react-core/src/components/MultipleFileUpload/examples/MultipleFileUploadBasic.tsx index a55c4f73bb5..ab3f92982f9 100644 --- a/packages/react-core/src/components/MultipleFileUpload/examples/MultipleFileUploadBasic.tsx +++ b/packages/react-core/src/components/MultipleFileUpload/examples/MultipleFileUploadBasic.tsx @@ -63,7 +63,7 @@ export const MultipleFileUploadBasic: React.FunctionComponent = () => { if (fileUploadShouldFail) { const corruptedFiles = files.map((file) => ({ ...file, lastModified: 'foo' as unknown as number })); // eslint-disable-next-line - setCurrentFiles((prevFiles) => [...prevFiles, ...corruptedFiles as any]); + setCurrentFiles((prevFiles) => [...prevFiles, ...(corruptedFiles as any)]); } else { setCurrentFiles((prevFiles) => [...prevFiles, ...files]); } @@ -101,7 +101,7 @@ export const MultipleFileUploadBasic: React.FunctionComponent = () => { if (fileResult?.loadError) { return ( - {fileResult.loadError.toString()} + {fileResult.loadError.toString()} ); } diff --git a/packages/react-core/src/demos/HelperText.md b/packages/react-core/src/demos/HelperText.md index 7c339cdc3e0..5e2823e067e 100644 --- a/packages/react-core/src/demos/HelperText.md +++ b/packages/react-core/src/demos/HelperText.md @@ -12,20 +12,21 @@ import TimesIcon from '@patternfly/react-icons/dist/esm/icons/times-icon'; ## Demos -### Static variant with static text +### Static helper text -In this demo, the static variant of the helper text item component (the default) is used, and the text itself will always be visible to users and will never change. +In this demo the text content of the helper text item will always be visible to users and will never change. The `aria-describedby` attribute is passed into the text input component and is linked to the `id` of the helper text component. This allows assistive technologies to notify users of the helper text content when the input receives focus, which can be helpful if a user navigates away from and then back to the input. Note that this demo does not validate the text input component. When it would need to be validated, there are other steps that would need to be taken to make it accessible, such as passing in `aria-invalid` and `aria-live` attributes to the appropriate components. -```ts file='./examples/HelperText/HelperTextStaticVariantStaticText.tsx' +```ts file='./examples/HelperText/HelperTextStatic.tsx' + ``` -### Static variant with dynamic text +### Dynamic helper text -In this demo, the static variant of the helper text item component (the default) is used with the `hasIcon` prop passed in when there is an error, and the text itself dynamically updates based on the input value. When the input has a value of `johndoe`, an error is rendered to simulate a username already being taken, while an empty input renders other helper text. When the input is valid, no helper text is rendered. +In this demo the text content of the helper text item dynamically updates based on the input value. When the input has a value of `johndoe`, an error is rendered to simulate a username already being taken, while an empty input renders default text. When the input is valid, no helper text is rendered. The `aria-describedby` attribute is passed into the text input component and is linked to the `id` of the helper text component. Similar to the static variant with static text demo, this allows assistive technologies to notify users of the helper text content when the navigating to the input. @@ -33,16 +34,18 @@ An `aria-live` region is passed into the helper text component, which allows ass The `aria-invalid` attribute is also passed into the text input, which allows assistive technologies to notify users that an input is invalid. When this attribute is true, it's important that users are notified of what is causing the input to be invalid; in this case, `aria-describedby` and `aria-live` help accomplish this. -```ts file='./examples/HelperText/HelperTextStaticVariantDynamicText.tsx' +```ts file='./examples/HelperText/HelperTextDynamic.tsx' + ``` -### Dynamic variant with static text +### Static text and dynamic status + +In this demo the text content of the helper text item remains static and never changes, but the icons and styling will change as the validation of the input changes. -In this demo, the helper text item components have the `isDynamic` prop passed in. While the text content of the components is static, the icons and styling will change as the validation of the input changes. +The `aria-describedby` attribute is passed into the text input component and is linked to the `id` attribute of a helper text item that results in an invalid input. This will allow assistive technologies to only be notified of any outstanding criteria that has not been met when the input receives focus. -The `aria-describedby` attribute is passed into the text input component and is linked to the id attribute of a helper text item that results in an invalid input. This will allow assistive technologies to only be notified of any outstanding criteria that has not been met when the input receives focus. +Similar to the [with dynamic text example](/components/helper-text/react-demos#with-dynamic-text), the `aria-invalid` attribute is passed in, allowing assistive technologies to announce to users when at least 1 item is causing the input to be invalid. -Similar to the static variant with dynamic text example, the `aria-invalid` attribute is passed in, allowing assistive technologies to announce to users when at least 1 item is causing the input to be invalid. +```ts file='./examples/HelperText/HelperTextStaticTextDynamicVariant.tsx' -```ts file='./examples/HelperText/HelperTextDynamicVariantStaticText.tsx' ``` diff --git a/packages/react-core/src/demos/examples/HelperText/HelperTextStaticVariantDynamicText.tsx b/packages/react-core/src/demos/examples/HelperText/HelperTextDynamic.tsx similarity index 88% rename from packages/react-core/src/demos/examples/HelperText/HelperTextStaticVariantDynamicText.tsx rename to packages/react-core/src/demos/examples/HelperText/HelperTextDynamic.tsx index d191a20b43a..9b7489d8b5d 100644 --- a/packages/react-core/src/demos/examples/HelperText/HelperTextStaticVariantDynamicText.tsx +++ b/packages/react-core/src/demos/examples/HelperText/HelperTextDynamic.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Form, FormGroup, FormHelperText, TextInput, HelperText, HelperTextItem } from '@patternfly/react-core'; -export const HelperTextStaticVariantDynamicText: React.FunctionComponent = () => { +export const HelperTextDynamic: React.FunctionComponent = () => { const [value, setValue] = React.useState(''); const [inputValidation, setInputValidation] = React.useState('default'); @@ -35,7 +35,7 @@ export const HelperTextStaticVariantDynamicText: React.FunctionComponent = () => {inputValidation !== 'success' && ( - + {inputValidation === 'default' ? 'Please enter a username' : 'Username already exists'} )} diff --git a/packages/react-core/src/demos/examples/HelperText/HelperTextStaticVariantStaticText.tsx b/packages/react-core/src/demos/examples/HelperText/HelperTextStatic.tsx similarity index 80% rename from packages/react-core/src/demos/examples/HelperText/HelperTextStaticVariantStaticText.tsx rename to packages/react-core/src/demos/examples/HelperText/HelperTextStatic.tsx index a351be55e54..b3ad325fcf9 100644 --- a/packages/react-core/src/demos/examples/HelperText/HelperTextStaticVariantStaticText.tsx +++ b/packages/react-core/src/demos/examples/HelperText/HelperTextStatic.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Form, FormGroup, FormHelperText, TextInput, HelperText, HelperTextItem } from '@patternfly/react-core'; -export const HelperTextStaticVariantStaticText: React.FunctionComponent = () => { +export const HelperTextStaticText: React.FunctionComponent = () => { const [value, setValue] = React.useState(''); const handleInputChange = (_event, inputValue: string) => { @@ -21,7 +21,7 @@ export const HelperTextStaticVariantStaticText: React.FunctionComponent = () => /> - Enter your middle name or your middle initial + Enter your middle name or your middle initial diff --git a/packages/react-core/src/demos/examples/HelperText/HelperTextDynamicVariantStaticText.tsx b/packages/react-core/src/demos/examples/HelperText/HelperTextStaticTextDynamicVariant.tsx similarity index 78% rename from packages/react-core/src/demos/examples/HelperText/HelperTextDynamicVariantStaticText.tsx rename to packages/react-core/src/demos/examples/HelperText/HelperTextStaticTextDynamicVariant.tsx index aa332c7bfa4..084534ead40 100644 --- a/packages/react-core/src/demos/examples/HelperText/HelperTextDynamicVariantStaticText.tsx +++ b/packages/react-core/src/demos/examples/HelperText/HelperTextStaticTextDynamicVariant.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Form, FormGroup, FormHelperText, TextInput, HelperText, HelperTextItem } from '@patternfly/react-core'; -export const HelperTextDynamicVariantDynamicText: React.FunctionComponent = () => { +export const HelperTextStaticTextDynamicVariant: React.FunctionComponent = () => { const [value, setValue] = React.useState(''); const [inputValidation, setInputValidation] = React.useState({ ruleLength: 'indeterminate', @@ -10,8 +10,8 @@ export const HelperTextDynamicVariantDynamicText: React.FunctionComponent = () = const { ruleLength, ruleCharacterTypes } = inputValidation; React.useEffect(() => { - let lengthStatus = ruleLength; - let typeStatus = ruleCharacterTypes; + let lengthVariant = ruleLength; + let typeVariant = ruleCharacterTypes; if (value === '') { setInputValidation({ @@ -22,18 +22,18 @@ export const HelperTextDynamicVariantDynamicText: React.FunctionComponent = () = } if (!/\d/g.test(value)) { - typeStatus = 'error'; + typeVariant = 'error'; } else { - typeStatus = 'success'; + typeVariant = 'success'; } if (value.length < 5) { - lengthStatus = 'error'; + lengthVariant = 'error'; } else { - lengthStatus = 'success'; + lengthVariant = 'success'; } - setInputValidation({ ruleLength: lengthStatus, ruleCharacterTypes: typeStatus }); + setInputValidation({ ruleLength: lengthVariant, ruleCharacterTypes: typeVariant }); }, [value, ruleLength, ruleCharacterTypes]); const handleInputChange = (_event, inputValue: string) => { @@ -57,10 +57,10 @@ export const HelperTextDynamicVariantDynamicText: React.FunctionComponent = () = /> - + Must be at least 5 characters in length - + Must include at least 1 number diff --git a/packages/react-core/src/demos/examples/PasswordStrength/PasswordStrengthDemo.tsx b/packages/react-core/src/demos/examples/PasswordStrength/PasswordStrengthDemo.tsx index 53e9ea1a1d1..4cbf30cb6c8 100644 --- a/packages/react-core/src/demos/examples/PasswordStrength/PasswordStrengthDemo.tsx +++ b/packages/react-core/src/demos/examples/PasswordStrength/PasswordStrengthDemo.tsx @@ -136,13 +136,13 @@ export const PasswordStrengthDemo: React.FunctionComponent = () => { /> - + Must be at least 14 characters - + Cannot contain the word "redhat" - + Must include at least 3 of the following: lowercase letter, uppercase letters, numbers, symbols From a658ca30a7b6bd790694e3cc53f9a583452cae90 Mon Sep 17 00:00:00 2001 From: Eric Olkowski Date: Mon, 22 Jan 2024 10:44:46 -0500 Subject: [PATCH 3/5] Fixed example file names --- .../react-core/src/components/HelperText/HelperTextItem.tsx | 6 +++--- .../src/components/HelperText/examples/HelperText.md | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/react-core/src/components/HelperText/HelperTextItem.tsx b/packages/react-core/src/components/HelperText/HelperTextItem.tsx index 25812cc9ee1..0cb1a870581 100644 --- a/packages/react-core/src/components/HelperText/HelperTextItem.tsx +++ b/packages/react-core/src/components/HelperText/HelperTextItem.tsx @@ -38,7 +38,6 @@ export interface HelperTextItemProps extends React.HTMLProps, indeterminate: , warning: , success: , @@ -57,15 +56,16 @@ export const HelperTextItem: React.FunctionComponent = ({ }: HelperTextItemProps) => { const Component = component as any; const isNotDefaultVariant = variant !== 'default'; + const defaultIcon = isNotDefaultVariant && defaultVariantIcons[variant]; return ( - {(isNotDefaultVariant || icon) && ( + {(defaultIcon || icon) && ( - {icon || defaultVariantIcons[variant]} + {icon || defaultIcon} )} diff --git a/packages/react-core/src/components/HelperText/examples/HelperText.md b/packages/react-core/src/components/HelperText/examples/HelperText.md index 4c73fe3a04c..c9805fae7d6 100644 --- a/packages/react-core/src/components/HelperText/examples/HelperText.md +++ b/packages/react-core/src/components/HelperText/examples/HelperText.md @@ -15,13 +15,13 @@ import ExclamationIcon from '@patternfly/react-icons/dist/esm/icons/exclamation- ### Basic -```ts file="HelperTextStatic.tsx" +```ts file="HelperTextBasic.tsx" ``` ### With custom icons -```ts file="HelperTextStaticWithCustomIcon.tsx" +```ts file="HelperTextWithCustomIcon.tsx" ``` @@ -29,6 +29,6 @@ import ExclamationIcon from '@patternfly/react-icons/dist/esm/icons/exclamation- You can pass multiple `` components inside a single `` container. -```ts file="HelperTextMultipleStatic.tsx" +```ts file="HelperTextMultipleItems.tsx" ``` From d7cb7b1be5778c4b692543e20ef9e0bc7cf258ff Mon Sep 17 00:00:00 2001 From: Eric Olkowski Date: Wed, 24 Jan 2024 15:03:41 -0500 Subject: [PATCH 4/5] Updated tests per Austin feedback --- .../HelperText/__tests__/HelperTextItem.test.tsx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/react-core/src/components/HelperText/__tests__/HelperTextItem.test.tsx b/packages/react-core/src/components/HelperText/__tests__/HelperTextItem.test.tsx index 4ef5fb26b7a..81bc38d3275 100644 --- a/packages/react-core/src/components/HelperText/__tests__/HelperTextItem.test.tsx +++ b/packages/react-core/src/components/HelperText/__tests__/HelperTextItem.test.tsx @@ -33,7 +33,7 @@ test('Renders custom className', () => { test('Does not render screen reader text by default', () => { render(help test text 1); - expect(screen.queryByText('help test text 1')?.querySelector('.pf-v5-screen-reader')).not.toBeInTheDocument(); + expect(screen.queryByText('status')).not.toBeInTheDocument(); }); Object.values(['indeterminate', 'warning', 'success', 'error']).forEach((variant) => { @@ -52,10 +52,21 @@ Object.values(['indeterminate', 'warning', 'success', 'error']).forEach((variant text ); - expect(screen.getByText('text').querySelector('span')).toHaveTextContent(`: ${variant} status;`); + expect(screen.getByText(`: ${variant} status;`)).toBeInTheDocument(); }); }); +test('Renders custom screen reader text', () => { + render( + + help test text 1 + + ); + + expect(screen.queryByText(': error status;')).not.toBeInTheDocument(); + expect(screen.getByText(': danger;')).toBeInTheDocument(); +}); + test('Renders id when id is passed', () => { render(help test text 1); expect(screen.getByText('help test text 1').parentElement).toHaveAttribute('id', 'text-item'); From 1a4ec156d49aeecf2273c3e985d8bf96f16db617 Mon Sep 17 00:00:00 2001 From: Eric Olkowski Date: Wed, 24 Jan 2024 15:21:27 -0500 Subject: [PATCH 5/5] Updated test to avoid false positive --- .../src/components/HelperText/__tests__/HelperTextItem.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-core/src/components/HelperText/__tests__/HelperTextItem.test.tsx b/packages/react-core/src/components/HelperText/__tests__/HelperTextItem.test.tsx index 81bc38d3275..8bf3a0d7cfe 100644 --- a/packages/react-core/src/components/HelperText/__tests__/HelperTextItem.test.tsx +++ b/packages/react-core/src/components/HelperText/__tests__/HelperTextItem.test.tsx @@ -33,7 +33,7 @@ test('Renders custom className', () => { test('Does not render screen reader text by default', () => { render(help test text 1); - expect(screen.queryByText('status')).not.toBeInTheDocument(); + expect(screen.queryByText('status', { exact: false })).not.toBeInTheDocument(); }); Object.values(['indeterminate', 'warning', 'success', 'error']).forEach((variant) => {