Skip to content

Commit 196c0c3

Browse files
Break up Animation demo into component files
1 parent 33b2e8b commit 196c0c3

11 files changed

Lines changed: 1681 additions & 1766 deletions

packages/react-core/src/demos/Animations/Animations.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ section: design-foundations
44
source: demo
55
---
66

7-
import { Fragment, useRef, useState, useEffect } from 'react';
7+
import { Fragment, useRef, useState, useEffect, useCallback } from 'react';
88

99
import BellIcon from '@patternfly/react-icons/dist/esm/icons/bell-icon';
1010
import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon';
@@ -25,7 +25,12 @@ import l_gallery_GridTemplateColumns_min from '@patternfly/react-tokens/dist/esm
2525
import {applicationsData} from './examples/ResourceTableData.jsx';
2626
import SkeletonTable from "@patternfly/react-component-groups/dist/dynamic/SkeletonTable";
2727
import t_global_text_color_subtle from '@patternfly/react-tokens/dist/esm/t_global_text_color_subtle';
28-
28+
import { AnimationsOverview } from '@patternfly/react-core/dist/js/demos/Animations/AnimationsOverview';
29+
import { AnimationsNotificationsDrawer } from '@patternfly/react-core/dist/js/demos/Animations/AnimationsNotificationsDrawer';
30+
import { AnimationsHeaderToolbar } from '@patternfly/react-core/dist/js/demos/Animations/AnimationsHeaderToolbar';
31+
import { AnimationsTourModal } from '@patternfly/react-core/dist/js/demos/Animations/AnimationsTourModal';
32+
import { AnimationsCreateDatabaseForm } from '@patternfly/react-core/dist/js/demos/Animations/AnimationsCreateDatabaseForm';
33+
import { GuidedTourProvider, useGuidedTour } from '@patternfly/react-core/dist/js/demos/Animations/GuidedTourContext';
2934

3035
## Demos
3136

Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
import { useRef, useState, FunctionComponent } from 'react';
2+
import {
3+
AlertGroup,
4+
Alert,
5+
Button,
6+
Form,
7+
FormGroup,
8+
FormHelperText,
9+
FormAlert,
10+
FormGroupLabelHelp,
11+
FormSelect,
12+
FormSelectOption,
13+
HelperText,
14+
HelperTextItem,
15+
List,
16+
ListItem,
17+
TextInput,
18+
Popover,
19+
ActionGroup
20+
} from '../..';
21+
22+
interface Props {
23+
onClose: () => void;
24+
}
25+
26+
export const AnimationsCreateDatabaseForm: FunctionComponent<Props> = ({ onClose }) => {
27+
// State variables
28+
const [name, setName] = useState('');
29+
const [email, setEmail] = useState('');
30+
const [version, setVersion] = useState('');
31+
const [selectedTimeZone, setSelectedTimeZone] = useState('');
32+
const [password, setPassword] = useState('');
33+
// Submit state variables
34+
const [isSuccess, setIsSuccess] = useState(false);
35+
const [actionCompleted, setActionCompleted] = useState(false);
36+
37+
const labelHelpRef = useRef(null);
38+
39+
// Re-introducing the type alias for validation status
40+
type validationStatus = 'success' | 'warning' | 'error' | 'default';
41+
42+
// Reverting useState to infer the type as a generic string
43+
const [isNameValid, setIsNameValid] = useState('default');
44+
const [isPasswordValid, setIsPasswordValid] = useState('default');
45+
const [isEmailValid, setIsEmailValid] = useState('default');
46+
const [isTimeZoneValid, setIsTimeZoneValid] = useState('default');
47+
const [errorMessages, setErrorMessages] = useState([]);
48+
49+
const handleNameChange = (_event: React.FormEvent<HTMLInputElement>, name: string) => {
50+
setName(name);
51+
};
52+
53+
const handleEmailChange = (_event: React.FormEvent<HTMLInputElement>, email: string) => {
54+
setEmail(email);
55+
};
56+
57+
const handleVersionChange = (_event: React.FormEvent<HTMLInputElement>, version: string) => {
58+
setVersion(version);
59+
};
60+
61+
const handlePasswordChange = (_event: React.FormEvent<HTMLInputElement>, password: string) => {
62+
setPassword(password);
63+
};
64+
65+
const handleTimeZoneChange = (event: React.FormEvent<HTMLSelectElement>, value: string) => {
66+
setSelectedTimeZone(value);
67+
};
68+
69+
const validateName = (value: string) => /^[a-z0-9-]+$/.test(value) && value.length > 0;
70+
const validatePassword = (value: string) => value.length >= 12 && /[0-9]/.test(value) && /[A-Z]/.test(value);
71+
const validateEmail = (value: string) => value.includes('@');
72+
const validateTimeZone = (value: string) => value !== '';
73+
74+
const handleNameBlur = () => {
75+
setIsNameValid(validateName(name) ? 'success' : 'error');
76+
};
77+
78+
const handlePasswordBlur = () => {
79+
setIsPasswordValid(validatePassword(password) ? 'success' : 'error');
80+
};
81+
82+
const handleEmailBlur = () => {
83+
setIsEmailValid(validateEmail(email) ? 'success' : 'error');
84+
};
85+
86+
const handleTimeZoneBlur = () => {
87+
setIsTimeZoneValid(validateTimeZone(selectedTimeZone) ? 'success' : 'error');
88+
};
89+
90+
const handleSubmit = () => {
91+
const isNameCurrentValid = validateName(name);
92+
const isPasswordCurrentValid = validatePassword(password);
93+
const isEmailCurrentValid = validateEmail(email);
94+
const isTimeZoneCurrentValid = validateTimeZone(selectedTimeZone);
95+
96+
setIsNameValid(isNameCurrentValid ? 'success' : 'error');
97+
setIsPasswordValid(isPasswordCurrentValid ? 'success' : 'error');
98+
setIsEmailValid(isEmailCurrentValid ? 'success' : 'error');
99+
setIsTimeZoneValid(isTimeZoneCurrentValid ? 'success' : 'error');
100+
101+
const allFieldsValid =
102+
isNameCurrentValid && isPasswordCurrentValid && isEmailCurrentValid && isTimeZoneCurrentValid;
103+
104+
setActionCompleted(true);
105+
setIsSuccess(allFieldsValid);
106+
if (allFieldsValid) {
107+
setErrorMessages([]);
108+
setTimeout(() => {
109+
setActionCompleted(false);
110+
setIsSuccess(false);
111+
}, 5000);
112+
} else {
113+
const errors: string[] = [];
114+
if (!isNameCurrentValid) {
115+
errors.push('Database instance name');
116+
}
117+
if (!isPasswordCurrentValid) {
118+
errors.push('Admin password');
119+
}
120+
if (!isEmailCurrentValid) {
121+
errors.push('Admin email');
122+
}
123+
if (!isTimeZoneCurrentValid) {
124+
errors.push('Time zone');
125+
}
126+
setErrorMessages(errors);
127+
setTimeout(() => {
128+
setActionCompleted(false);
129+
setIsSuccess(false);
130+
}, 5000);
131+
}
132+
};
133+
134+
return (
135+
<Form isWidthLimited>
136+
{actionCompleted &&
137+
(isSuccess ? (
138+
<FormAlert>
139+
<AlertGroup hasAnimations isLiveRegion>
140+
<Alert
141+
variant="success"
142+
title="Successfully created database"
143+
isInline
144+
timeout={4000}
145+
timeoutAnimation={4000}
146+
/>
147+
</AlertGroup>
148+
</FormAlert>
149+
) : (
150+
<FormAlert>
151+
<AlertGroup hasAnimations isLiveRegion>
152+
<Alert
153+
variant="danger"
154+
title="Failed to create database. Please ensure all fields are filled out correctly."
155+
isInline
156+
timeout={3000}
157+
timeoutAnimation={3000}
158+
>
159+
<List isPlain>
160+
{errorMessages.map((error) => (
161+
<ListItem key={error}>{error}</ListItem>
162+
))}
163+
</List>
164+
</Alert>
165+
</AlertGroup>
166+
</FormAlert>
167+
))}
168+
<FormGroup
169+
label="Database instance name"
170+
labelHelp={
171+
<Popover
172+
triggerRef={labelHelpRef}
173+
headerContent={<div>The name of your database</div>}
174+
bodyContent={
175+
<div>
176+
<p>
177+
The name of your database is used to identify it in the system. It must be unique and cannot be
178+
changed later.
179+
</p>
180+
</div>
181+
}
182+
>
183+
<FormGroupLabelHelp ref={labelHelpRef} aria-label="More info for name field" />
184+
</Popover>
185+
}
186+
isRequired
187+
fieldId="simple-form-name-01"
188+
>
189+
<TextInput
190+
isRequired
191+
type="text"
192+
id="simple-form-name-01"
193+
name="simple-form-name-01"
194+
aria-describedby="simple-form-name-01-helper"
195+
value={name}
196+
onChange={handleNameChange}
197+
onBlur={handleNameBlur}
198+
validated={isNameValid as validationStatus}
199+
/>
200+
{isNameValid === 'error' && (
201+
<FormHelperText>
202+
<HelperText>
203+
<HelperTextItem variant={isNameValid as validationStatus}>
204+
Must contain only lowercase letters, numbers, and hyphens.
205+
</HelperTextItem>
206+
</HelperText>
207+
</FormHelperText>
208+
)}
209+
</FormGroup>
210+
<FormGroup label="Admin email" isRequired fieldId="simple-form-email-01">
211+
<TextInput
212+
isRequired
213+
type="email"
214+
id="simple-form-email-01"
215+
name="simple-form-email-01"
216+
value={email}
217+
onChange={handleEmailChange}
218+
onBlur={handleEmailBlur}
219+
validated={isEmailValid as validationStatus}
220+
/>
221+
{isEmailValid === 'error' && (
222+
<FormHelperText>
223+
<HelperText>
224+
<HelperTextItem variant={isEmailValid as validationStatus}>
225+
Must be a valid email address containing an @ symbol.
226+
</HelperTextItem>
227+
</HelperText>
228+
</FormHelperText>
229+
)}
230+
</FormGroup>
231+
<FormGroup label="Database version" fieldId="simple-form-version-01">
232+
<TextInput
233+
type="text"
234+
id="simple-form-version-01"
235+
name="simple-form-version-01"
236+
placeholder="e.g. 12c"
237+
value={version}
238+
onChange={handleVersionChange}
239+
/>
240+
</FormGroup>
241+
<FormGroup isRequired label="Time zone" fieldId="timezone-select">
242+
<FormSelect
243+
id="timezone-select"
244+
value={selectedTimeZone}
245+
onChange={handleTimeZoneChange}
246+
aria-label="Select time zone"
247+
onBlur={handleTimeZoneBlur}
248+
validated={isTimeZoneValid as validationStatus}
249+
>
250+
<FormSelectOption isPlaceholder value="" label="Select a time zone" />
251+
<FormSelectOption value="Eastern" label="Eastern" />
252+
<FormSelectOption value="Central" label="Central" />
253+
<FormSelectOption value="Pacific" label="Pacific" />
254+
</FormSelect>
255+
{isTimeZoneValid === 'error' && (
256+
<FormHelperText>
257+
<HelperText>
258+
<HelperTextItem variant={isTimeZoneValid as validationStatus}>Please select a time zone</HelperTextItem>
259+
</HelperText>
260+
</FormHelperText>
261+
)}
262+
</FormGroup>
263+
<FormGroup label="Admin password" isRequired fieldId="simple-form-password-01">
264+
<TextInput
265+
isRequired
266+
type="password"
267+
id="simple-form-password-01"
268+
name="simple-form-password-01"
269+
value={password}
270+
onChange={handlePasswordChange}
271+
onBlur={handlePasswordBlur}
272+
validated={isPasswordValid as validationStatus}
273+
/>
274+
{isPasswordValid === 'error' && (
275+
<FormHelperText>
276+
<HelperText>
277+
<HelperTextItem variant={isPasswordValid as validationStatus}>
278+
Password must be at least 12 characters and include one uppercase letter and one number.
279+
</HelperTextItem>
280+
</HelperText>
281+
</FormHelperText>
282+
)}
283+
</FormGroup>
284+
<ActionGroup>
285+
<Button variant="primary" onClick={handleSubmit}>
286+
Submit
287+
</Button>
288+
<Button variant="link" onClick={onClose}>
289+
Cancel
290+
</Button>
291+
</ActionGroup>
292+
</Form>
293+
);
294+
};

0 commit comments

Comments
 (0)