playbook_ui 15.5.0.pre.alpha.draggableask12772 → 15.5.0.pre.alpha.draggableask12813

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 92a93fad43c2ffd951dfa2745d0ec9d274d88b255b8308cc63dc46e2013b32a9
4
- data.tar.gz: 90097889aad0c7a8fed5ed59646450a92451efa3ebc1516df42947751bff1470
3
+ metadata.gz: 33fdb9233b3792d2200f44167f3977d7fdb9aba1a739836866a47457278fa752
4
+ data.tar.gz: 9036b8c349e54ca64926514efa7d05639b0bc3a6d459f14a4d2cf3c72f97bdf8
5
5
  SHA512:
6
- metadata.gz: fb1e65b5882d2691a9cacac7be696c4c213b6ce7e4b69d5475daab6cedead5182d36eb41cf6056d4b323d9420e6fcb2da5b7e2a897edcb1fb928f240c797ad8a
7
- data.tar.gz: 958b3259b370b7b5bd53c06a040757f9b98b0ee80dc62c56e1416016f9752f9c1136981da6da21a16d15622bfe32a81e54cc44d31a46ffba4624a8a875e4e703
6
+ metadata.gz: c1a067b287e194cf06e8aeb9c825bdbf8a6b54fc27b33ebba59715256b0af3f8457da3b969171612cafd3996416432ee18ced28480c4969db9204de6ef7c0df7
7
+ data.tar.gz: 441d2491ce081ae388c60ca1f22ba89e7c57ab9b9e4af8dfc790aa845e7ebbdebbe4ff66bdb5f911bc9c6621ee8497b9adae19d57e1d7d4dc8bac6bb8f7a845b
@@ -102,16 +102,16 @@ const Background = (props: BackgroundProps): React.ReactElement => {
102
102
  useEffect(() => {
103
103
  const updateResponsiveProps = () => {
104
104
  setResponsiveProps({
105
- backgroundSize: getResponsiveValue(props.backgroundSize),
106
- backgroundPosition: getResponsiveValue(props.backgroundPosition),
107
- backgroundRepeat: getResponsiveValue(props.backgroundRepeat),
108
- backgroundColor: getResponsiveValue(props.backgroundColor),
109
- imageUrl: getResponsiveValue(props.imageUrl),
105
+ backgroundSize: getResponsiveValue(backgroundSize),
106
+ backgroundPosition: getResponsiveValue(backgroundPosition),
107
+ backgroundRepeat: getResponsiveValue(backgroundRepeat),
108
+ backgroundColor: getResponsiveValue(backgroundColor),
109
+ imageUrl: getResponsiveValue(imageUrl),
110
110
  });
111
111
  };
112
112
  window.addEventListener('resize', updateResponsiveProps);
113
113
  return () => window.removeEventListener('resize', updateResponsiveProps);
114
- }, [props]);
114
+ }, [backgroundSize, backgroundPosition, backgroundRepeat, backgroundColor, imageUrl]);
115
115
 
116
116
 
117
117
  // Extract currently applicable responsive values.
@@ -4,7 +4,6 @@ import Background from './_background'
4
4
 
5
5
  const props = {
6
6
  data: { testid: 'background' },
7
- backgroundColor: null,
8
7
  }
9
8
 
10
9
  it('Should be accessible', async () => {
@@ -42,3 +41,8 @@ test('applies correct overlay class when imageOverlay prop is provided', () => {
42
41
  const kit = renderKit(Background, props, { imageOverlay: 'opacity_6' });
43
42
  expect(kit).toHaveClass('imageoverlay_opacity_6');
44
43
  });
44
+
45
+ test('Sets backgroundColor to light as default when no backgroundColor prop is provided', () => {
46
+ const kit = renderKit(Background, props);
47
+ expect(kit).toHaveClass('pb_background_color_light');
48
+ });
@@ -1,3 +1,3 @@
1
- <%= pb_rails("background", props: { background_color: "light", padding: "xl" }) do %>
1
+ <%= pb_rails("background", props: { padding: "xl" }) do %>
2
2
 
3
3
  <% end %>
@@ -3,7 +3,6 @@ import Background from '../../pb_background/_background'
3
3
 
4
4
  const BackgroundLight = (props) => (
5
5
  <Background
6
- backgroundColor="light"
7
6
  padding="xl"
8
7
  {...props}
9
8
  />
@@ -0,0 +1 @@
1
+ By default, the Background kit sets background color to 'light' as seen here.
@@ -1,7 +1,7 @@
1
1
  examples:
2
2
 
3
3
  rails:
4
- - background_light: Light
4
+ - background_light: Default
5
5
  - background_white: White
6
6
  - background_gradient: Gradient
7
7
  - background_image: Image
@@ -11,7 +11,7 @@ examples:
11
11
  - background_size: Size
12
12
 
13
13
  react:
14
- - background_light: Light
14
+ - background_light: Default
15
15
  - background_white: White
16
16
  - background_gradient: Gradient
17
17
  - background_image: Image
@@ -143,30 +143,25 @@ export default class PbDialog extends PbEnhancedElement {
143
143
 
144
144
  // Close dialog box on outside click
145
145
  dialogs.forEach((dialogElement) => {
146
- const originalClickHandler = dialogElement._outsideClickHandler
147
- if (originalClickHandler) dialogElement.removeEventListener("click", originalClickHandler)
148
-
146
+ const originalMousedownHandler = dialogElement._outsideClickHandler
147
+ if (originalMousedownHandler) dialogElement.removeEventListener("mousedown", originalMousedownHandler)
149
148
  dialogElement._outsideClickHandler = (event) => {
150
149
  const dialogParentDataset = dialogElement.parentElement.dataset
151
150
  if (dialogParentDataset.overlayClick === "overlay_close") return
152
151
 
153
- // Get the dialog's bounding box (the actual content area)
154
- const rect = dialogElement.getBoundingClientRect()
155
- const clickedInDialog = (
156
- event.clientX >= rect.left &&
157
- event.clientX <= rect.right &&
158
- event.clientY >= rect.top &&
159
- event.clientY <= rect.bottom
160
- )
161
-
162
- // Only close if clicked outside the dialog content (on the backdrop)
163
- if (!clickedInDialog) {
152
+ const dialogModal = event.target.getBoundingClientRect()
153
+ const clickedOutsideDialogModal = event.clientX < dialogModal.left ||
154
+ event.clientX > dialogModal.right ||
155
+ event.clientY < dialogModal.top ||
156
+ event.clientY > dialogModal.bottom
157
+
158
+ if (clickedOutsideDialogModal) {
164
159
  dialogElement.close()
165
160
  event.stopPropagation()
166
161
  }
167
162
  }
168
163
 
169
- dialogElement.addEventListener("click", dialogElement._outsideClickHandler);
164
+ dialogElement.addEventListener("mousedown", dialogElement._outsideClickHandler);
170
165
  })
171
166
  }
172
167
  }
@@ -1,4 +1,4 @@
1
- import React, { createContext, useReducer, useContext, useEffect, useMemo } from "react";
1
+ import React, { createContext, useReducer, useContext, useEffect, useMemo, useRef } from "react";
2
2
  import { InitialStateType, ActionType, DraggableProviderType } from "./types";
3
3
 
4
4
  const initialState: InitialStateType = {
@@ -8,9 +8,6 @@ const initialState: InitialStateType = {
8
8
  activeContainer: ""
9
9
  };
10
10
 
11
- // Track if a successful drop occurred to distinguish from dragEnd without drop
12
- let dropOccurred = false;
13
-
14
11
  const reducer = (state: InitialStateType, action: ActionType) => {
15
12
  switch (action.type) {
16
13
  case 'SET_ITEMS':
@@ -135,6 +132,19 @@ export const DraggableProvider = ({
135
132
  enableCrossContainerPreview = false,
136
133
  }: DraggableProviderType) => {
137
134
  const [state, dispatch] = useReducer(reducer, initialState);
135
+
136
+ // Track drag state for global listener
137
+ const dragStateRef = useRef<{
138
+ isDragging: boolean;
139
+ draggedItemId: string;
140
+ originalContainer: string;
141
+ dropOccurred: boolean;
142
+ }>({
143
+ isDragging: false,
144
+ draggedItemId: '',
145
+ originalContainer: '',
146
+ dropOccurred: false,
147
+ });
138
148
 
139
149
  // Parse dropZone prop - handle both string format (backward compatibility) and object format
140
150
  let dropZoneType = 'ghost';
@@ -164,7 +174,94 @@ export const DraggableProvider = ({
164
174
  onReorder(state.items);
165
175
  }, [state.items]);
166
176
 
177
+ // Monitor for failed drops by detecting mouse/pointer release during drag (this is needed for cross container preview)
178
+ useEffect(() => {
179
+ if (!enableCrossContainerPreview) return;
180
+
181
+ const handleGlobalMouseUp = () => {
182
+ // If we're dragging and mouse is released, wait a bit to see if drop occurs
183
+ if (dragStateRef.current.isDragging) {
184
+ setTimeout(() => {
185
+ // If drop still hasn't occurred, reset
186
+ if (dragStateRef.current.isDragging && !dragStateRef.current.dropOccurred) {
187
+ dispatch({
188
+ type: 'RESET_DRAG_CONTAINER',
189
+ payload: {
190
+ itemId: dragStateRef.current.draggedItemId,
191
+ originalContainer: dragStateRef.current.originalContainer,
192
+ },
193
+ });
194
+ dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
195
+ dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
196
+ dispatch({ type: 'SET_DRAG_DATA', payload: { id: "", initialGroup: "", originId: "" } });
197
+
198
+ // Clear drag state
199
+ dragStateRef.current = {
200
+ isDragging: false,
201
+ draggedItemId: '',
202
+ originalContainer: '',
203
+ dropOccurred: false,
204
+ };
205
+ }
206
+ }, 50); // Small delay to let drop event fire if it's going to
207
+ }
208
+ };
209
+
210
+ document.addEventListener('mouseup', handleGlobalMouseUp);
211
+ document.addEventListener('pointerup', handleGlobalMouseUp);
212
+
213
+ return () => {
214
+ document.removeEventListener('mouseup', handleGlobalMouseUp);
215
+ document.removeEventListener('pointerup', handleGlobalMouseUp);
216
+ };
217
+ }, [enableCrossContainerPreview]);
218
+
219
+ // Detect when dragging stops (isDragging goes from truthy to empty)
220
+ const prevIsDraggingRef = useRef(state.isDragging);
221
+
222
+ useEffect(() => {
223
+ if (!enableCrossContainerPreview) return;
224
+
225
+ const wasDragging = prevIsDraggingRef.current;
226
+ const isNowDragging = state.isDragging;
227
+
228
+ // Drag just ended (was dragging, now not)
229
+ if (wasDragging && !isNowDragging) {
230
+
231
+ // If drop didn't occur, reset to original container
232
+ if (!dragStateRef.current.dropOccurred && dragStateRef.current.draggedItemId) {
233
+ dispatch({
234
+ type: 'RESET_DRAG_CONTAINER',
235
+ payload: {
236
+ itemId: dragStateRef.current.draggedItemId,
237
+ originalContainer: dragStateRef.current.originalContainer,
238
+ },
239
+ });
240
+ }
241
+
242
+ // Clear drag state
243
+ dragStateRef.current = {
244
+ isDragging: false,
245
+ draggedItemId: '',
246
+ originalContainer: '',
247
+ dropOccurred: false,
248
+ };
249
+ }
250
+
251
+ prevIsDraggingRef.current = isNowDragging;
252
+ }, [state.isDragging, enableCrossContainerPreview]);
253
+
167
254
  const handleDragStart = (id: string, container: string) => {
255
+ // Track drag in ref for global listener
256
+ if (enableCrossContainerPreview) {
257
+ dragStateRef.current = {
258
+ isDragging: true,
259
+ draggedItemId: id,
260
+ originalContainer: container,
261
+ dropOccurred: false,
262
+ };
263
+ }
264
+
168
265
  dispatch({ type: 'SET_DRAG_DATA', payload: { id: id, initialGroup: container, originId: providerId } });
169
266
  dispatch({ type: 'SET_IS_DRAGGING', payload: id });
170
267
  if (onDragStart) onDragStart(id, container);
@@ -219,7 +316,7 @@ export const DraggableProvider = ({
219
316
  const originalContainer = state.dragData.initialGroup;
220
317
 
221
318
  // If enableCrossContainerPreview is true and no drop occurred, reset item to original container
222
- if (enableCrossContainerPreview && !dropOccurred && draggedItemId && originalContainer) {
319
+ if (enableCrossContainerPreview && draggedItemId && originalContainer) {
223
320
  dispatch({ type: 'RESET_DRAG_CONTAINER', payload: { itemId: draggedItemId, originalContainer } });
224
321
  }
225
322
 
@@ -227,9 +324,6 @@ export const DraggableProvider = ({
227
324
  dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
228
325
  dispatch({ type: 'SET_DRAG_DATA', payload: { id: "", initialGroup: "", originId: "" } });
229
326
 
230
- // Reset the drop flag
231
- dropOccurred = false;
232
-
233
327
  if (onDragEnd) {
234
328
  if (!enableCrossContainerPreview) {
235
329
  onDragEnd();
@@ -263,8 +357,10 @@ export const DraggableProvider = ({
263
357
  const draggedItemId = state.dragData.id;
264
358
  const originalContainer = state.dragData.initialGroup;
265
359
 
266
- // Mark that a successful drop occurred
267
- dropOccurred = true;
360
+ // Mark drop as successful in ref for global listener
361
+ if (enableCrossContainerPreview) {
362
+ dragStateRef.current.dropOccurred = true;
363
+ }
268
364
 
269
365
  dispatch({ type: 'SET_IS_DRAGGING', payload: "" });
270
366
  dispatch({ type: 'SET_ACTIVE_CONTAINER', payload: "" });
@@ -110,13 +110,25 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
110
110
  const inputRef = useRef<HTMLInputElement | null>(null)
111
111
  const itiRef = useRef<any>(null);
112
112
  const wrapperRef = useRef<HTMLDivElement | null>(null);
113
+ const hasBlurredRef = useRef<boolean>(false);
114
+ const formSubmittedRef = useRef<boolean>(false);
113
115
  const [inputValue, setInputValue] = useState(value)
114
116
  const [error, setError] = useState(props.error || "")
115
117
  const [dropDownIsOpen, setDropDownIsOpen] = useState(false)
116
118
  const [selectedData, setSelectedData] = useState()
117
119
  const [hasTyped, setHasTyped] = useState(false)
120
+ const [hasBlurred, setHasBlurred] = useState(false)
118
121
  const [formSubmitted, setFormSubmitted] = useState(false)
119
122
  const [hasStartedValidating, setHasStartedValidating] = useState(false)
123
+
124
+ // Keep refs in sync with state for use in event listeners
125
+ useEffect(() => {
126
+ hasBlurredRef.current = hasBlurred
127
+ }, [hasBlurred])
128
+
129
+ useEffect(() => {
130
+ formSubmittedRef.current = formSubmitted
131
+ }, [formSubmitted])
120
132
 
121
133
  // Only sync initial error from props, not continuous updates
122
134
  // Once validation starts, internal validation takes over
@@ -143,8 +155,8 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
143
155
  }
144
156
 
145
157
  // Determine which error to display
146
- // Show internal errors on blur (hasTyped) or on form submission (formSubmitted)
147
- const shouldShowInternalError = (hasTyped || formSubmitted) && required && error
158
+ // Show internal errors only after blur (hasBlurred) or on form submission (formSubmitted)
159
+ const shouldShowInternalError = (hasBlurred || formSubmitted) && error
148
160
  const displayError = shouldShowInternalError ? error : ""
149
161
 
150
162
  useEffect(() => {
@@ -259,7 +271,9 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
259
271
  return
260
272
  }
261
273
 
262
- if (!hasTyped && !error) return
274
+ // Only validate if field has been blurred or form has been submitted
275
+ // Use refs here since state updates are async and we need current values
276
+ if (!hasBlurredRef.current && !formSubmittedRef.current) return
263
277
 
264
278
  // Run validation checks
265
279
  if (itiRef.current) isValid(itiRef.current.isValidNumber())
@@ -280,6 +294,7 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
280
294
  if (phoneNumberContainer && phoneNumberContainer === wrapperRef.current) {
281
295
  const invalidInputName = target.name || target.getAttribute('name')
282
296
  if (invalidInputName === name) {
297
+ formSubmittedRef.current = true
283
298
  setFormSubmitted(true)
284
299
  // Trigger validation when form is submitted
285
300
  validateErrors()
@@ -305,6 +320,9 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
305
320
  setInputValue("")
306
321
  setError("")
307
322
  setHasTyped(false)
323
+ hasBlurredRef.current = false
324
+ setHasBlurred(false)
325
+ formSubmittedRef.current = false
308
326
  setFormSubmitted(false)
309
327
  setHasStartedValidating(false)
310
328
  // Only clear validation state if field was required
@@ -322,6 +340,7 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
322
340
 
323
341
  if (required && isEmpty) {
324
342
  setError('Missing phone number')
343
+ formSubmittedRef.current = true
325
344
  setFormSubmitted(true)
326
345
  return 'Missing phone number'
327
346
  }
@@ -378,6 +397,7 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
378
397
 
379
398
  // Set the error state so the validation attribute gets added
380
399
  setError(errorMessage)
400
+ formSubmittedRef.current = true
381
401
  setFormSubmitted(true)
382
402
  setHasTyped(true)
383
403
 
@@ -401,6 +421,7 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
401
421
 
402
422
  // Reset form submitted state when user types
403
423
  if (formSubmitted) {
424
+ formSubmittedRef.current = false
404
425
  setFormSubmitted(false)
405
426
  }
406
427
 
@@ -416,11 +437,15 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
416
437
 
417
438
  setSelectedData(phoneNumberData)
418
439
  onChange(phoneNumberData)
419
- isValid(itiRef.current.isValidNumber())
440
+
441
+ // Don't call isValid callback on change - only on blur or form submission
442
+ // This prevents triggering validation while typing
443
+ // Use refs to get current values in case this is called from event listener
444
+ if (hasBlurredRef.current || formSubmittedRef.current) {
445
+ isValid(itiRef.current.isValidNumber())
446
+ }
420
447
 
421
- // Trigger validation after onChange for React Hook Form
422
- // This ensures validation state is up-to-date
423
- setTimeout(() => validateErrors(), 0)
448
+ // Don't validate on change - only validate on blur or form submission
424
449
  }
425
450
 
426
451
  // Separating Concerns as React Docs Recommend
@@ -482,7 +507,12 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
482
507
 
483
508
  setSelectedData(phoneNumberData)
484
509
  onChange(phoneNumberData)
485
- isValid(telInputInit.isValidNumber())
510
+
511
+ // Don't call isValid callback on change - only on blur or form submission
512
+ // Use refs to check current blur state in the event listener (closure issue)
513
+ if (hasBlurredRef.current || formSubmittedRef.current) {
514
+ isValid(telInputInit.isValidNumber())
515
+ }
486
516
  })
487
517
  }
488
518
  }
@@ -492,12 +522,16 @@ const PhoneNumberInput = (props: PhoneNumberInputProps, ref?: React.Ref<unknown>
492
522
  dark,
493
523
  "data-phone-number": JSON.stringify(selectedData),
494
524
  disabled,
495
- error: hasTyped ? error : props.error || displayError,
525
+ error: displayError || props.error || "",
496
526
  type: 'tel',
497
527
  id,
498
528
  label,
499
529
  name,
500
- onBlur: validateErrors,
530
+ onBlur: () => {
531
+ hasBlurredRef.current = true
532
+ setHasBlurred(true)
533
+ validateErrors()
534
+ },
501
535
  onChange: formatAsYouType ? undefined : handleOnChange,
502
536
  value: inputValue
503
537
  }
@@ -1,12 +1,42 @@
1
1
  <form id="example-form-validation" action="" method="get">
2
- <%= pb_rails("phone_number_input", props: { error: "Missing phone number", id: "validation", initial_country: "af", value: "", required: true }) %>
2
+ <%= pb_rails("phone_number_input", props: {
3
+ id: "validation",
4
+ initial_country: "af",
5
+ value: "",
6
+ required: true
7
+ }) %>
3
8
  <%= pb_rails("button", props: {html_type: "submit", text: "Save Phone Number"}) %>
4
9
  </form>
5
10
 
6
11
  <%= javascript_tag do %>
7
12
  document.addEventListener('DOMContentLoaded', function () {
8
- document.querySelector('#example-form-validation').addEventListener('submit', function (e) {
9
- if (e.target.querySelectorAll('[error]:not([error=""])').length > 0) e.preventDefault();
10
- })
13
+ const form = document.querySelector('#example-form-validation');
14
+
15
+ // Wait for React component to mount
16
+ function waitForComponent() {
17
+ const phoneInput = form.querySelector('#validation');
18
+
19
+ if (!phoneInput) {
20
+ setTimeout(waitForComponent, 100);
21
+ return;
22
+ }
23
+
24
+ // Wait for intl-tel-input to initialize, then focus and blur to trigger validation
25
+ setTimeout(function() {
26
+ phoneInput.focus({ preventScroll: true });
27
+ setTimeout(function() {
28
+ phoneInput.blur();
29
+ }, 100);
30
+ }, 500);
31
+ }
32
+
33
+ waitForComponent();
34
+
35
+ // Prevent form submission if there are validation errors
36
+ form.addEventListener('submit', function (e) {
37
+ if (e.target.querySelectorAll('[error]:not([error=""])').length > 0) {
38
+ e.preventDefault();
39
+ }
40
+ });
11
41
  })
12
42
  <% end %>
@@ -10,8 +10,19 @@ const PhoneNumberInputValidation = (props) => {
10
10
  const [showFormErrors, setShowFormErrors] = useState(false);
11
11
  const [phoneNumber, setPhoneNumber] = useState("");
12
12
  const [countryCode, setCountryCode] = useState("af");
13
+ const [isValid, setIsValid] = useState(false);
14
+ const [hasInteracted, setHasInteracted] = useState(false);
15
+
16
+ // Start with initial error - will be cleared on blur if valid
17
+ const initialError = (
18
+ <>
19
+ <Icon icon="warning" /> Missing phone number.
20
+ </>
21
+ );
13
22
 
14
23
  const handleOnValidate = (valid) => {
24
+ setIsValid(valid);
25
+ setHasInteracted(true);
15
26
  setFormErrors(
16
27
  valid ? "" : "Please correct the fields below and try again."
17
28
  );
@@ -23,18 +34,16 @@ const PhoneNumberInputValidation = (props) => {
23
34
  };
24
35
 
25
36
  const handleOnSubmit = (e) => {
26
- if (showFormErrors) e.preventDefault()
37
+ if (!isValid) e.preventDefault()
27
38
  }
28
39
 
29
40
  useEffect(() => {
30
41
  setShowFormErrors(formErrors.length > 0);
31
42
  }, [formErrors]);
32
43
 
33
- const error = (
34
- <>
35
- <Icon icon="warning" /> Missing phone number.
36
- </>
37
- )
44
+ // Only show error prop initially, or if invalid after interaction
45
+ // Clear error prop once valid (component handles validation on blur)
46
+ const shouldShowError = !hasInteracted || (hasInteracted && !isValid);
38
47
 
39
48
  return (
40
49
  <form
@@ -50,7 +59,7 @@ const PhoneNumberInputValidation = (props) => {
50
59
  />
51
60
  )}
52
61
  <PhoneNumberInput
53
- error={error}
62
+ error={shouldShowError ? initialError : undefined}
54
63
  id="validation"
55
64
  initialCountry={countryCode}
56
65
  onChange={handleOnChange}