diff --git a/packages/react-core/src/components/Form/ActionGroup.tsx b/packages/react-core/src/components/Form/ActionGroup.tsx index f01e78a3074..04843fd1a1b 100644 --- a/packages/react-core/src/components/Form/ActionGroup.tsx +++ b/packages/react-core/src/components/Form/ActionGroup.tsx @@ -1,6 +1,7 @@ import styles from '@patternfly/react-styles/css/components/Form/form'; import { css } from '@patternfly/react-styles'; +/** ActionGroup has been deprecated, please use ActionList, ActionListGroup, and ActionListItem in a FormGroup instead. */ export interface ActionGroupProps extends React.HTMLProps { /** Anything that can be rendered as ActionGroup content. */ children?: React.ReactNode; @@ -8,6 +9,7 @@ export interface ActionGroupProps extends React.HTMLProps { className?: string; } +/** ActionGroup has been deprecated, please use ActionList, ActionListGroup, and ActionListItem in a FormGroup instead. */ export const ActionGroup: React.FunctionComponent = ({ children = null, className = '', diff --git a/packages/react-core/src/components/Form/FormGroup.tsx b/packages/react-core/src/components/Form/FormGroup.tsx index abde71667e0..b6172fca3e7 100644 --- a/packages/react-core/src/components/Form/FormGroup.tsx +++ b/packages/react-core/src/components/Form/FormGroup.tsx @@ -21,6 +21,8 @@ export interface FormGroupProps extends Omit, 'l isInline?: boolean; /** Sets the FormGroupControl to be stacked */ isStack?: boolean; + /** Sets the FormGroup action modifier. Used to contain form action buttons. */ + isActionGroup?: boolean; /** Removes top spacer from label. */ hasNoPaddingTop?: boolean; /** ID of an individual field or a group of multiple fields. Required when a role of "group" or "radiogroup" is passed in. @@ -47,6 +49,7 @@ export const FormGroup: React.FunctionComponent = ({ isInline = false, hasNoPaddingTop = false, isStack = false, + isActionGroup = false, fieldId, role, ouiaId, @@ -75,7 +78,7 @@ export const FormGroup: React.FunctionComponent = ({ return (
{ expect(screen.getByTestId('form-group-test-id').firstElementChild).toHaveClass('pf-m-no-padding-top'); }); + test('should render action form group variant', () => { + render( + + + + ); + expect(screen.getByTestId('form-group-test-id')).toHaveClass('pf-m-action'); + }); + test('should render form group variant with required label', () => { const { asFragment } = render( diff --git a/packages/react-core/src/components/Form/__tests__/__snapshots__/FormGroup.test.tsx.snap b/packages/react-core/src/components/Form/__tests__/__snapshots__/FormGroup.test.tsx.snap index 9c61b9cfb36..963cdc3e163 100644 --- a/packages/react-core/src/components/Form/__tests__/__snapshots__/FormGroup.test.tsx.snap +++ b/packages/react-core/src/components/Form/__tests__/__snapshots__/FormGroup.test.tsx.snap @@ -4,7 +4,7 @@ exports[`FormGroup should render correctly when label is not a string with Child
@@ -78,7 +78,7 @@ exports[`FormGroup should render form group variant with node label 1`] = `
@@ -114,7 +114,7 @@ exports[`FormGroup should render form group variant with required label 1`] = `
@@ -154,7 +154,7 @@ exports[`FormGroup should render form group variant without label 1`] = `
@@ -173,7 +173,7 @@ exports[`FormGroup should render form group with additional label info 1`] = `
@@ -218,14 +218,14 @@ exports[`FormGroup should render horizontal form group variant 1`] = `
@@ -260,14 +260,14 @@ exports[`FormGroup should render stacked horizontal form group variant 1`] = `
diff --git a/packages/react-core/src/components/Form/examples/Form.md b/packages/react-core/src/components/Form/examples/Form.md index 8efa6679b1f..5b38dd1e4ef 100644 --- a/packages/react-core/src/components/Form/examples/Form.md +++ b/packages/react-core/src/components/Form/examples/Form.md @@ -6,6 +6,9 @@ cssPrefix: pf-v6-c-form propComponents: [ 'ActionGroup', + 'ActionList', + 'ActionListGroup', + 'ActionListItem', 'Form', 'FormGroup', 'FormGroupLabelHelp', diff --git a/packages/react-core/src/components/Form/examples/FormBasic.tsx b/packages/react-core/src/components/Form/examples/FormBasic.tsx index 93af5d17cb2..cfc5fc5bfc8 100644 --- a/packages/react-core/src/components/Form/examples/FormBasic.tsx +++ b/packages/react-core/src/components/Form/examples/FormBasic.tsx @@ -5,7 +5,9 @@ import { TextInput, Checkbox, Popover, - ActionGroup, + ActionList, + ActionListGroup, + ActionListItem, Button, Radio, HelperText, @@ -123,10 +125,18 @@ export const FormBasic: React.FunctionComponent = () => { - - - - + + + + + + + + + + + + ); }; diff --git a/packages/react-core/src/components/Form/examples/FormHorizontal.tsx b/packages/react-core/src/components/Form/examples/FormHorizontal.tsx index aaf4b02b43f..0bc134ca7c9 100644 --- a/packages/react-core/src/components/Form/examples/FormHorizontal.tsx +++ b/packages/react-core/src/components/Form/examples/FormHorizontal.tsx @@ -7,7 +7,9 @@ import { FormSelect, FormSelectOption, Checkbox, - ActionGroup, + ActionList, + ActionListGroup, + ActionListItem, Button, Radio, HelperText, @@ -112,10 +114,18 @@ export const FormHorizontal: React.FunctionComponent = () => { - - - - + + + + + + + + + + + + ); }; diff --git a/packages/react-core/src/components/Form/examples/FormLimitWidth.tsx b/packages/react-core/src/components/Form/examples/FormLimitWidth.tsx index ac3cfe2faf2..c1022b53206 100644 --- a/packages/react-core/src/components/Form/examples/FormLimitWidth.tsx +++ b/packages/react-core/src/components/Form/examples/FormLimitWidth.tsx @@ -5,7 +5,9 @@ import { TextInput, Checkbox, Popover, - ActionGroup, + ActionList, + ActionListGroup, + ActionListItem, Button, Radio, HelperText, @@ -123,10 +125,18 @@ export const FormLimitWidth: React.FunctionComponent = () => { - - - - + + + + + + + + + + + + ); }; diff --git a/packages/react-core/src/components/Form/examples/FormState.tsx b/packages/react-core/src/components/Form/examples/FormState.tsx index bf47aa95cac..beb9301b365 100644 --- a/packages/react-core/src/components/Form/examples/FormState.tsx +++ b/packages/react-core/src/components/Form/examples/FormState.tsx @@ -1,6 +1,8 @@ import { useState } from 'react'; import { - ActionGroup, + ActionList, + ActionListGroup, + ActionListItem, Button, ButtonType, ButtonVariant, @@ -89,25 +91,36 @@ export const FormState = () => { - - - - + if (!values['input-id']) { + setError('input-id', 'Input value is required.'); + } else { + alert(`Form submitted with: \n ${JSON.stringify(values)}`); + } + }} + > + Submit + + + + + + + + {formStateExpanded && ( <> diff --git a/packages/react-core/src/components/LoginPage/LoginForm.tsx b/packages/react-core/src/components/LoginPage/LoginForm.tsx index c237e79dc66..e1906e7e4b2 100644 --- a/packages/react-core/src/components/LoginPage/LoginForm.tsx +++ b/packages/react-core/src/components/LoginPage/LoginForm.tsx @@ -1,5 +1,5 @@ import { useState } from 'react'; -import { Form, FormGroup, ActionGroup, FormHelperText } from '../Form'; +import { Form, FormGroup, FormHelperText } from '../Form'; import { TextInput } from '../TextInput'; import { Button } from '../Button'; import { Checkbox } from '../Checkbox'; @@ -147,11 +147,9 @@ export const LoginForm: React.FunctionComponent = ({ /> )} - - - + ); }; diff --git a/packages/react-core/src/components/LoginPage/__tests__/__snapshots__/LoginForm.test.tsx.snap b/packages/react-core/src/components/LoginPage/__tests__/__snapshots__/LoginForm.test.tsx.snap index 0238714fa10..8a6429394b5 100644 --- a/packages/react-core/src/components/LoginPage/__tests__/__snapshots__/LoginForm.test.tsx.snap +++ b/packages/react-core/src/components/LoginPage/__tests__/__snapshots__/LoginForm.test.tsx.snap @@ -133,31 +133,19 @@ exports[`LoginForm LoginForm with rememberMeLabel 1`] = `
-
-
-
- -
-
-
+ Log In + +
`; @@ -303,31 +291,19 @@ exports[`LoginForm LoginForm with show password 1`] = `
-
-
-
- -
-
-
+ Log In + +
`; @@ -435,31 +411,19 @@ exports[`LoginForm should render Login form 1`] = `
-
-
-
- -
-
-
+ Log In + + `; diff --git a/packages/react-core/src/components/SearchInput/AdvancedSearchMenu.tsx b/packages/react-core/src/components/SearchInput/AdvancedSearchMenu.tsx index 05617c59f2f..4772cd2855c 100644 --- a/packages/react-core/src/components/SearchInput/AdvancedSearchMenu.tsx +++ b/packages/react-core/src/components/SearchInput/AdvancedSearchMenu.tsx @@ -1,6 +1,7 @@ import { useEffect, useRef, useState } from 'react'; import { Button } from '../Button'; -import { ActionGroup, Form, FormGroup } from '../Form'; +import { ActionList, ActionListGroup, ActionListItem } from '../ActionList'; +import { Form, FormGroup } from '../Form'; import { TextInput } from '../TextInput'; import { useSSRSafeId } from '../../helpers'; import { SearchInputSearchAttribute } from './SearchInput'; @@ -202,16 +203,24 @@ export const AdvancedSearchMenu: React.FunctionComponent {buildFormGroups()} {formAdditionalItems ? formAdditionalItems : null} - - - {!!onClear && ( - - )} - + + + + + + + {!!onClear && ( + + + + )} + + + diff --git a/packages/react-core/src/components/SearchInput/__tests__/__snapshots__/SearchInput.test.tsx.snap b/packages/react-core/src/components/SearchInput/__tests__/__snapshots__/SearchInput.test.tsx.snap index 3d7348cd8cb..c8783dc12bc 100644 --- a/packages/react-core/src/components/SearchInput/__tests__/__snapshots__/SearchInput.test.tsx.snap +++ b/packages/react-core/src/components/SearchInput/__tests__/__snapshots__/SearchInput.test.tsx.snap @@ -442,28 +442,40 @@ exports[`SearchInput advanced search with custom attributes 1`] = ` class="pf-v6-c-form__group-control" >
- - +
+
- Reset - - + +
+ diff --git a/packages/react-core/src/demos/Button/examples/ButtonProgress.tsx b/packages/react-core/src/demos/Button/examples/ButtonProgress.tsx index 6b6bb25a306..a9360de0ee2 100644 --- a/packages/react-core/src/demos/Button/examples/ButtonProgress.tsx +++ b/packages/react-core/src/demos/Button/examples/ButtonProgress.tsx @@ -1,5 +1,13 @@ import { useState } from 'react'; -import { Form, FormGroup, ActionGroup, TextInput, Button } from '@patternfly/react-core'; +import { + Form, + FormGroup, + TextInput, + Button, + ActionListItem, + ActionListGroup, + ActionList +} from '@patternfly/react-core'; import RhUiCheckCircleFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-check-circle-fill-icon'; export const ButtonProgress: React.FunctionComponent = () => { @@ -27,28 +35,34 @@ export const ButtonProgress: React.FunctionComponent = () => { aria-label="password input" /> - - - + isLoading={loginState === 'loading'} + icon={loginState === 'loggedIn' ? : null} + spinnerAriaValueText="Loading..." + > + {loginState === 'notLoggedIn' && 'Link account and log in'} + {loginState === 'loading' && 'Linking account'} + {loginState === 'loggedIn' && 'Logged in'} + + + + + ); }; diff --git a/packages/react-core/src/demos/SearchInput/examples/SearchInputAdvancedComposable.tsx b/packages/react-core/src/demos/SearchInput/examples/SearchInputAdvancedComposable.tsx index 6c784d6e873..e547067c993 100644 --- a/packages/react-core/src/demos/SearchInput/examples/SearchInputAdvancedComposable.tsx +++ b/packages/react-core/src/demos/SearchInput/examples/SearchInputAdvancedComposable.tsx @@ -1,6 +1,8 @@ import { useEffect, useRef, useState } from 'react'; import { - ActionGroup, + ActionList, + ActionListGroup, + ActionListItem, Button, DatePicker, Form, @@ -290,16 +292,24 @@ export const SearchInputAdvancedComposable: React.FunctionComponent = () => { - - - {!!onClear && ( - - )} - + + + + + + + + {!!onClear && ( + + )} + + + + diff --git a/packages/react-integration/cypress/integration/searchinput.spec.ts b/packages/react-integration/cypress/integration/searchinput.spec.ts index d522616efcf..5fda7d997c3 100644 --- a/packages/react-integration/cypress/integration/searchinput.spec.ts +++ b/packages/react-integration/cypress/integration/searchinput.spec.ts @@ -62,13 +62,13 @@ describe('Search Input Demo Test', () => { cy.get('#enabled-search .pf-v6-c-form-control > input').eq(1).should('have.value', 'hi'); cy.get('#enabled-search .pf-v6-c-form-control > input').eq(2).should('have.value', 'another test'); - cy.get('#enabled-search .pf-v6-c-form__actions button').eq(1).click({ force: true }); + cy.get('#enabled-search .pf-v6-c-action-list button').eq(1).click({ force: true }); cy.get('#enabled-search .pf-v6-c-text-input-group__text-input').should('have.value', ''); cy.get('#enabled-search .pf-v6-c-form-control > input').eq(1).should('have.value', ''); cy.get('#enabled-search .pf-v6-c-form-control > input').eq(2).should('have.value', ''); cy.get('#enabled-search .pf-v6-c-form-control > input').eq(0).type('test'); - cy.get('#enabled-search .pf-v6-c-form__actions button').eq(0).click({ force: true }); + cy.get('#enabled-search .pf-v6-c-action-list button').eq(0).click({ force: true }); cy.get('#enabled-search .pf-v6-c-form input').should('not.exist'); cy.get('#enabled-search .pf-v6-c-text-input-group__text-input').should('have.value', 'username:test'); });