goobs-frontend 0.7.60 → 0.7.63
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.
- package/package.json +2 -2
- package/src/components/Button/index.tsx +103 -65
- package/src/components/ConfirmationCodeInput/index.tsx +2 -2
- package/src/components/Content/index.tsx +13 -7
- package/src/components/Form/Popup/index.tsx +29 -10
- package/src/components/Icons/ShowHideEye.tsx +8 -2
- package/src/components/Nav/HorizontalVariant/index.tsx +92 -91
- package/src/components/Nav/VerticalVariant/index.tsx +41 -0
- package/src/components/Nav/index.tsx +2 -14
- package/src/components/PricingTable/defaultconfig.tsx +35 -115
- package/src/components/PricingTable/index.tsx +7 -11
- package/src/components/StyledComponent/adornment/index.tsx +6 -8
- package/src/components/StyledComponent/helperfooter/useHelperFooter.tsx +383 -340
- package/src/components/StyledComponent/hooks/useDropdown.tsx +60 -15
- package/src/components/StyledComponent/hooks/usePhoneNumber.tsx +53 -27
- package/src/components/StyledComponent/index.tsx +107 -66
- package/src/components/StyledComponent/useEffects/index.tsx +0 -5
- package/src/components/StyledComponent/hooks/usePassword.tsx +0 -23
|
@@ -3,6 +3,9 @@ import { StyledComponentProps } from '..'
|
|
|
3
3
|
import { styled, Menu, MenuItem } from '@mui/material'
|
|
4
4
|
import React from 'react'
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Styled MenuItem component for the dropdown menu.
|
|
8
|
+
*/
|
|
6
9
|
const StyledSelectMenu = styled(MenuItem)({
|
|
7
10
|
backgroundColor: 'white',
|
|
8
11
|
color: 'black',
|
|
@@ -13,41 +16,83 @@ const StyledSelectMenu = styled(MenuItem)({
|
|
|
13
16
|
},
|
|
14
17
|
})
|
|
15
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Custom hook for managing a dropdown component.
|
|
21
|
+
*
|
|
22
|
+
* @param {StyledComponentProps} props - The props passed to the StyledComponent.
|
|
23
|
+
* @param {React.RefObject<HTMLDivElement>} inputBoxRef - Ref to the input box element.
|
|
24
|
+
* @param {(option: string) => void} [onOptionSelect] - Optional callback function when an option is selected.
|
|
25
|
+
* @returns {Object} An object containing state and handlers for the dropdown.
|
|
26
|
+
*/
|
|
16
27
|
export const useDropdown = (
|
|
17
28
|
props: StyledComponentProps,
|
|
18
|
-
inputBoxRef: React.RefObject<HTMLDivElement
|
|
29
|
+
inputBoxRef: React.RefObject<HTMLDivElement>,
|
|
30
|
+
onOptionSelect?: (option: string) => void
|
|
19
31
|
) => {
|
|
32
|
+
/** State to control if the dropdown is open */
|
|
20
33
|
const [isDropdownOpen, setIsDropdownOpen] = useState(false)
|
|
34
|
+
/** State to store the anchor element for the dropdown */
|
|
21
35
|
const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null)
|
|
36
|
+
/** State to store the filtered options */
|
|
22
37
|
const [filteredOptions, setFilteredOptions] = useState<string[]>([])
|
|
38
|
+
/** State to store the currently selected option */
|
|
23
39
|
const [selectedOption, setSelectedOption] = useState('')
|
|
40
|
+
/** State to track if the dropdown is focused */
|
|
24
41
|
const [isDropdownFocused, setIsDropdownFocused] = useState(false)
|
|
25
|
-
const { componentvariant, options, value } = props
|
|
26
42
|
|
|
43
|
+
const { componentvariant, options, value, defaultOption } = props
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Effect to set filtered options when component variant is dropdown and options are provided
|
|
47
|
+
*/
|
|
27
48
|
useEffect(() => {
|
|
28
49
|
if (componentvariant === 'dropdown' && options) {
|
|
29
50
|
setFilteredOptions([...options])
|
|
30
51
|
}
|
|
31
52
|
}, [componentvariant, options])
|
|
32
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Effect to set the selected option based on value, defaultOption, or first option
|
|
56
|
+
*/
|
|
33
57
|
useEffect(() => {
|
|
34
58
|
if (value !== undefined) {
|
|
35
59
|
setSelectedOption(value)
|
|
60
|
+
} else if (defaultOption !== undefined) {
|
|
61
|
+
setSelectedOption(defaultOption)
|
|
62
|
+
} else if (options && options.length > 0) {
|
|
63
|
+
setSelectedOption(options[0])
|
|
36
64
|
}
|
|
37
|
-
}, [value])
|
|
65
|
+
}, [value, defaultOption, options])
|
|
38
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Handle click on the dropdown to open/close it
|
|
69
|
+
*/
|
|
39
70
|
const handleDropdownClick = useCallback(() => {
|
|
40
71
|
if (componentvariant === 'dropdown') {
|
|
41
72
|
setAnchorEl(inputBoxRef.current)
|
|
42
|
-
setIsDropdownOpen(!
|
|
73
|
+
setIsDropdownOpen(prev => !prev)
|
|
43
74
|
}
|
|
44
|
-
}, [componentvariant, inputBoxRef
|
|
75
|
+
}, [componentvariant, inputBoxRef])
|
|
45
76
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
77
|
+
/**
|
|
78
|
+
* Handle selection of an option from the dropdown
|
|
79
|
+
* @param {string} option - The selected option
|
|
80
|
+
*/
|
|
81
|
+
const handleOptionSelect = useCallback(
|
|
82
|
+
(option: string) => {
|
|
83
|
+
setSelectedOption(option)
|
|
84
|
+
setIsDropdownOpen(false)
|
|
85
|
+
if (onOptionSelect) {
|
|
86
|
+
onOptionSelect(option)
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
[onOptionSelect]
|
|
90
|
+
)
|
|
50
91
|
|
|
92
|
+
/**
|
|
93
|
+
* Handle focus/blur of the dropdown input
|
|
94
|
+
* @param {boolean} focused - Whether the input is focused
|
|
95
|
+
*/
|
|
51
96
|
const handleInputFocus = useCallback(
|
|
52
97
|
(focused: boolean) => {
|
|
53
98
|
if (componentvariant === 'dropdown') {
|
|
@@ -57,11 +102,10 @@ export const useDropdown = (
|
|
|
57
102
|
[componentvariant]
|
|
58
103
|
)
|
|
59
104
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const renderMenu = anchorEl !== null && isDropdownOpen !== undefined && (
|
|
105
|
+
/**
|
|
106
|
+
* Render the dropdown menu
|
|
107
|
+
*/
|
|
108
|
+
const renderMenu = (
|
|
65
109
|
<Menu
|
|
66
110
|
anchorEl={anchorEl}
|
|
67
111
|
open={isDropdownOpen}
|
|
@@ -77,12 +121,13 @@ export const useDropdown = (
|
|
|
77
121
|
<StyledSelectMenu
|
|
78
122
|
key={option}
|
|
79
123
|
onClick={() => handleOptionSelect(option)}
|
|
124
|
+
selected={option === selectedOption}
|
|
80
125
|
>
|
|
81
126
|
{option}
|
|
82
127
|
</StyledSelectMenu>
|
|
83
128
|
))
|
|
84
129
|
) : (
|
|
85
|
-
<
|
|
130
|
+
<MenuItem disabled>No Options Found</MenuItem>
|
|
86
131
|
)}
|
|
87
132
|
</Menu>
|
|
88
133
|
)
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import React, { useCallback } from 'react'
|
|
1
|
+
import React, { useState, useCallback } from 'react'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* @param value The string
|
|
7
|
-
* @returns
|
|
4
|
+
* Formats a string of digits into a US phone number format with a "+1" country code.
|
|
5
|
+
*
|
|
6
|
+
* @param {string} value - The input string to be formatted.
|
|
7
|
+
* @returns {string} A formatted phone number string in the format "+1 xxx-xxx-xxxx".
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* formatPhoneNumber("1234567890") // returns "+1 123-456-7890"
|
|
11
|
+
* formatPhoneNumber("12345") // returns "+1 123-45"
|
|
8
12
|
*/
|
|
9
13
|
export const formatPhoneNumber = (value: string): string => {
|
|
10
|
-
// Remove all non-digit characters
|
|
11
14
|
const digits = value.replace(/\D/g, '')
|
|
12
|
-
|
|
15
|
+
const limitedDigits = digits.slice(0, 10)
|
|
13
16
|
let formattedNumber = '+1 '
|
|
14
|
-
if (
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if (digits.length > 6) {
|
|
21
|
-
// Add second dash and last four digits
|
|
22
|
-
formattedNumber += '-' + digits.slice(6, 10)
|
|
17
|
+
if (limitedDigits.length > 0) {
|
|
18
|
+
formattedNumber += limitedDigits.slice(0, 3)
|
|
19
|
+
if (limitedDigits.length > 3) {
|
|
20
|
+
formattedNumber += '-' + limitedDigits.slice(3, 6)
|
|
21
|
+
if (limitedDigits.length > 6) {
|
|
22
|
+
formattedNumber += '-' + limitedDigits.slice(6)
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
}
|
|
@@ -27,28 +27,54 @@ export const formatPhoneNumber = (value: string): string => {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* @param
|
|
33
|
-
* @returns An object containing the
|
|
30
|
+
* A custom React hook for managing and formatting a phone number input.
|
|
31
|
+
*
|
|
32
|
+
* @param {string} [initialValue=''] - The initial value of the phone number.
|
|
33
|
+
* @returns {Object} An object containing the current phone number state and functions to update it.
|
|
34
|
+
* @property {string} phoneNumber - The current formatted phone number.
|
|
35
|
+
* @property {function} handlePhoneNumberChange - A function to handle changes to the phone number input.
|
|
36
|
+
* @property {function} updatePhoneNumber - A function to directly update the phone number.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* const { phoneNumber, handlePhoneNumberChange, updatePhoneNumber } = usePhoneNumber();
|
|
34
40
|
*/
|
|
35
|
-
export const usePhoneNumber = () => {
|
|
41
|
+
export const usePhoneNumber = (initialValue: string = '') => {
|
|
36
42
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
|
|
43
|
+
* The current state of the formatted phone number.
|
|
44
|
+
* @type {[string, function]}
|
|
45
|
+
*/
|
|
46
|
+
const [phoneNumber, setPhoneNumber] = useState(
|
|
47
|
+
formatPhoneNumber(initialValue)
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Handles changes to the phone number input.
|
|
52
|
+
*
|
|
53
|
+
* @param {React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>} e - The change event.
|
|
40
54
|
*/
|
|
41
55
|
const handlePhoneNumberChange = useCallback(
|
|
42
56
|
(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
|
43
57
|
const input = e.target.value
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
|
|
58
|
+
// Remove the "+1 " prefix if it exists
|
|
59
|
+
const strippedInput = input.startsWith('+1 ') ? input.slice(3) : input
|
|
60
|
+
const formattedValue = formatPhoneNumber(strippedInput)
|
|
61
|
+
setPhoneNumber(formattedValue)
|
|
47
62
|
},
|
|
48
63
|
[]
|
|
49
64
|
)
|
|
50
65
|
|
|
66
|
+
/**
|
|
67
|
+
* Updates the phone number state with a new value.
|
|
68
|
+
*
|
|
69
|
+
* @param {string} newValue - The new phone number value to set.
|
|
70
|
+
*/
|
|
71
|
+
const updatePhoneNumber = useCallback((newValue: string) => {
|
|
72
|
+
setPhoneNumber(formatPhoneNumber(newValue))
|
|
73
|
+
}, [])
|
|
74
|
+
|
|
51
75
|
return {
|
|
76
|
+
phoneNumber,
|
|
52
77
|
handlePhoneNumberChange,
|
|
78
|
+
updatePhoneNumber,
|
|
53
79
|
}
|
|
54
80
|
}
|
|
@@ -4,7 +4,6 @@ import React, { useState, useRef, useEffect } from 'react'
|
|
|
4
4
|
import { Box, InputLabel, OutlinedInput, styled } from '@mui/material'
|
|
5
5
|
import { useDropdown } from './hooks/useDropdown'
|
|
6
6
|
import { usePhoneNumber } from './hooks/usePhoneNumber'
|
|
7
|
-
import { usePassword } from './hooks/usePassword'
|
|
8
7
|
import { useSplitButton } from './hooks/useSplitButton'
|
|
9
8
|
import { Typography } from './../Typography'
|
|
10
9
|
import { red, green } from '../../styles/palette'
|
|
@@ -17,18 +16,29 @@ import labelStyles from '../../styles/StyledComponent/Label'
|
|
|
17
16
|
import { useHasInputEffect, usePreventAutocompleteEffect } from './useEffects'
|
|
18
17
|
|
|
19
18
|
/**
|
|
20
|
-
* Props interface for the StyledComponent
|
|
19
|
+
* Props interface for the StyledComponent.
|
|
20
|
+
* @interface
|
|
21
21
|
*/
|
|
22
22
|
export interface StyledComponentProps {
|
|
23
|
+
/** Name attribute for the input element */
|
|
23
24
|
name?: string
|
|
25
|
+
/** Color of the input outline */
|
|
24
26
|
outlinecolor?: string
|
|
27
|
+
/** Color of the icon */
|
|
25
28
|
iconcolor?: string
|
|
29
|
+
/** Background color of the input */
|
|
26
30
|
backgroundcolor?: string
|
|
31
|
+
/** Whether the input is notched */
|
|
27
32
|
notched?: boolean
|
|
33
|
+
/** Combined font color for the input */
|
|
28
34
|
combinedfontcolor?: string
|
|
35
|
+
/** Font color when the label is not shrunk */
|
|
29
36
|
unshrunkfontcolor?: string
|
|
37
|
+
/** Font color when the label is shrunk */
|
|
30
38
|
shrunkfontcolor?: string
|
|
39
|
+
/** Autocomplete attribute for the input */
|
|
31
40
|
autoComplete?: string
|
|
41
|
+
/** Variant of the component */
|
|
32
42
|
componentvariant?:
|
|
33
43
|
| 'multilinetextfield'
|
|
34
44
|
| 'dropdown'
|
|
@@ -46,26 +56,48 @@ export interface StyledComponentProps {
|
|
|
46
56
|
| 'time'
|
|
47
57
|
| 'date'
|
|
48
58
|
| 'splitbutton'
|
|
59
|
+
/** Options for dropdown variant */
|
|
49
60
|
options?: readonly string[]
|
|
61
|
+
/** Default option for dropdown variant */
|
|
62
|
+
defaultOption?: string
|
|
63
|
+
/** Helper footer message */
|
|
50
64
|
helperfooter?: HelperFooterMessage
|
|
65
|
+
/** Placeholder text for the input */
|
|
51
66
|
placeholder?: string
|
|
67
|
+
/** Minimum number of rows for multiline text field */
|
|
52
68
|
minRows?: number
|
|
69
|
+
/** Name of the form the input belongs to */
|
|
53
70
|
formname?: string
|
|
71
|
+
/** Label text for the input */
|
|
54
72
|
label?: string
|
|
73
|
+
/** Location of the shrunk label */
|
|
55
74
|
shrunklabellocation?: 'onnotch' | 'above'
|
|
75
|
+
/** Value of the input */
|
|
56
76
|
value?: string
|
|
77
|
+
/** Status of the value */
|
|
57
78
|
valuestatus?: boolean
|
|
79
|
+
/** Whether the input is focused */
|
|
58
80
|
focused?: boolean
|
|
81
|
+
/** Whether the input is required */
|
|
59
82
|
required?: boolean
|
|
83
|
+
/** Whether the form has been submitted */
|
|
60
84
|
formSubmitted?: boolean
|
|
85
|
+
/** ARIA label for the input */
|
|
61
86
|
'aria-label'?: string
|
|
87
|
+
/** ARIA required attribute */
|
|
62
88
|
'aria-required'?: boolean
|
|
89
|
+
/** ARIA invalid attribute */
|
|
63
90
|
'aria-invalid'?: boolean
|
|
91
|
+
/** ARIA describedby attribute */
|
|
64
92
|
'aria-describedby'?: string
|
|
93
|
+
/** Callback function when an option is selected (for dropdown variant) */
|
|
94
|
+
onOptionSelect?: (option: string) => void
|
|
95
|
+
/** Callback function when the input value changes */
|
|
96
|
+
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void
|
|
65
97
|
}
|
|
66
98
|
|
|
67
99
|
/**
|
|
68
|
-
* Styled component
|
|
100
|
+
* Styled OutlinedInput component that prevents autofill styling.
|
|
69
101
|
*/
|
|
70
102
|
const NoAutofillOutlinedInput = styled(OutlinedInput)(() => ({
|
|
71
103
|
'& .MuiInputBase-input': {
|
|
@@ -85,9 +117,9 @@ const NoAutofillOutlinedInput = styled(OutlinedInput)(() => ({
|
|
|
85
117
|
}))
|
|
86
118
|
|
|
87
119
|
/**
|
|
88
|
-
* StyledComponent is a
|
|
89
|
-
* @param props The props for the StyledComponent
|
|
90
|
-
* @returns The rendered StyledComponent
|
|
120
|
+
* StyledComponent is a versatile input component that can render various types of inputs based on the provided props.
|
|
121
|
+
* @param {StyledComponentProps} props - The props for the StyledComponent
|
|
122
|
+
* @returns {React.ReactElement} The rendered StyledComponent
|
|
91
123
|
*/
|
|
92
124
|
const StyledComponent: React.FC<StyledComponentProps> = props => {
|
|
93
125
|
const {
|
|
@@ -110,47 +142,60 @@ const StyledComponent: React.FC<StyledComponentProps> = props => {
|
|
|
110
142
|
'aria-required': ariaRequired,
|
|
111
143
|
'aria-invalid': ariaInvalid,
|
|
112
144
|
'aria-describedby': ariaDescribedBy,
|
|
145
|
+
onOptionSelect,
|
|
146
|
+
onChange,
|
|
113
147
|
} = props
|
|
114
148
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
})
|
|
122
|
-
|
|
123
|
-
const { validateField, validateRequiredField, helperFooterValue } =
|
|
124
|
-
useHelperFooter()
|
|
149
|
+
const {
|
|
150
|
+
validateField,
|
|
151
|
+
validateRequiredField,
|
|
152
|
+
helperFooterValue,
|
|
153
|
+
initializeRequiredFields,
|
|
154
|
+
} = useHelperFooter()
|
|
125
155
|
const [isFocused, setIsFocused] = useState(false)
|
|
126
156
|
const [hasInput, setHasInput] = useState(false)
|
|
127
157
|
const [showError, setShowError] = useState(false)
|
|
158
|
+
const [passwordVisible, setPasswordVisible] = useState(false)
|
|
128
159
|
const inputRefInternal = useRef<HTMLInputElement>(null)
|
|
129
160
|
const inputBoxRef = useRef<HTMLDivElement>(null)
|
|
130
161
|
|
|
131
|
-
|
|
132
|
-
const { renderMenu, selectedOption, isDropdownOpen } = useDropdown(
|
|
162
|
+
const { renderMenu, selectedOption, handleDropdownClick } = useDropdown(
|
|
133
163
|
props,
|
|
134
|
-
inputBoxRef
|
|
164
|
+
inputBoxRef,
|
|
165
|
+
onOptionSelect
|
|
135
166
|
)
|
|
136
|
-
const { handlePhoneNumberChange } =
|
|
137
|
-
|
|
167
|
+
const { phoneNumber, handlePhoneNumberChange, updatePhoneNumber } =
|
|
168
|
+
usePhoneNumber(value || '')
|
|
138
169
|
const {
|
|
139
170
|
value: splitButtonValue,
|
|
140
171
|
handleIncrement,
|
|
141
172
|
handleDecrement,
|
|
142
173
|
} = useSplitButton(props)
|
|
143
174
|
|
|
144
|
-
// useEffect hooks
|
|
145
175
|
useHasInputEffect(value, valuestatus, setHasInput)
|
|
146
176
|
usePreventAutocompleteEffect(inputRefInternal)
|
|
147
177
|
|
|
178
|
+
/**
|
|
179
|
+
* Initialize required fields when the form name changes
|
|
180
|
+
*/
|
|
181
|
+
useEffect(() => {
|
|
182
|
+
if (formname) {
|
|
183
|
+
initializeRequiredFields(formname)
|
|
184
|
+
}
|
|
185
|
+
}, [formname, initializeRequiredFields])
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Validate required field when relevant props change
|
|
189
|
+
*/
|
|
148
190
|
useEffect(() => {
|
|
149
191
|
if (required && formname && name && label) {
|
|
150
192
|
validateRequiredField(required, formname, name, label)
|
|
151
193
|
}
|
|
152
194
|
}, [required, formname, name, label, validateRequiredField])
|
|
153
195
|
|
|
196
|
+
/**
|
|
197
|
+
* Show error after a delay when form is submitted or input has value
|
|
198
|
+
*/
|
|
154
199
|
useEffect(() => {
|
|
155
200
|
const timer = setTimeout(() => {
|
|
156
201
|
setShowError(formSubmitted || hasInput)
|
|
@@ -159,27 +204,37 @@ const StyledComponent: React.FC<StyledComponentProps> = props => {
|
|
|
159
204
|
return () => clearTimeout(timer)
|
|
160
205
|
}, [formSubmitted, hasInput])
|
|
161
206
|
|
|
207
|
+
/**
|
|
208
|
+
* Update phone number when componentvariant is 'phonenumber' and value changes
|
|
209
|
+
*/
|
|
210
|
+
useEffect(() => {
|
|
211
|
+
if (componentvariant === 'phonenumber' && value) {
|
|
212
|
+
updatePhoneNumber(value)
|
|
213
|
+
}
|
|
214
|
+
}, [componentvariant, value, updatePhoneNumber])
|
|
215
|
+
|
|
162
216
|
const currentHelperFooter = name ? helperFooterValue[name] : undefined
|
|
163
|
-
console.log('StyledComponent: Current helper footer', currentHelperFooter)
|
|
164
217
|
|
|
165
218
|
/**
|
|
166
|
-
* Handle
|
|
167
|
-
* @param e The change event
|
|
219
|
+
* Handle change event for the input
|
|
220
|
+
* @param {React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>} e - The change event
|
|
168
221
|
*/
|
|
169
222
|
const handleChange = (
|
|
170
223
|
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
|
|
171
224
|
) => {
|
|
172
|
-
console.log('StyledComponent: handleChange called', {
|
|
173
|
-
name: e.target.name,
|
|
174
|
-
value: e.target.value,
|
|
175
|
-
})
|
|
176
|
-
|
|
177
225
|
if (componentvariant === 'phonenumber') {
|
|
178
226
|
handlePhoneNumberChange(e)
|
|
227
|
+
if (onChange) {
|
|
228
|
+
onChange(e as React.ChangeEvent<HTMLInputElement>)
|
|
229
|
+
}
|
|
179
230
|
} else if (componentvariant === 'splitbutton') {
|
|
180
|
-
// Only allow numbers for splitbutton
|
|
181
231
|
const numValue = e.target.value.replace(/[^0-9]/g, '')
|
|
182
232
|
e.target.value = numValue
|
|
233
|
+
if (onChange) {
|
|
234
|
+
onChange(e as React.ChangeEvent<HTMLInputElement>)
|
|
235
|
+
}
|
|
236
|
+
} else if (onChange) {
|
|
237
|
+
onChange(e as React.ChangeEvent<HTMLInputElement>)
|
|
183
238
|
}
|
|
184
239
|
|
|
185
240
|
setHasInput(!!e.target.value)
|
|
@@ -187,43 +242,36 @@ const StyledComponent: React.FC<StyledComponentProps> = props => {
|
|
|
187
242
|
const formData = new FormData()
|
|
188
243
|
formData.append(e.target.name, e.target.value)
|
|
189
244
|
if (name && label && formname) {
|
|
190
|
-
console.log('StyledComponent: Calling validateField', {
|
|
191
|
-
name,
|
|
192
|
-
label,
|
|
193
|
-
required,
|
|
194
|
-
formname,
|
|
195
|
-
})
|
|
196
245
|
validateField(name, formData, label, required, formname)
|
|
197
246
|
}
|
|
198
247
|
}
|
|
199
248
|
|
|
200
249
|
/**
|
|
201
|
-
* Handle
|
|
250
|
+
* Handle focus event for the input
|
|
202
251
|
*/
|
|
203
252
|
const handleFocus = () => {
|
|
204
|
-
console.log('StyledComponent: handleFocus called')
|
|
205
253
|
setIsFocused(true)
|
|
206
254
|
}
|
|
207
255
|
|
|
208
256
|
/**
|
|
209
|
-
* Handle
|
|
257
|
+
* Handle blur event for the input
|
|
210
258
|
*/
|
|
211
259
|
const handleBlur = () => {
|
|
212
|
-
console.log('StyledComponent: handleBlur called')
|
|
213
260
|
setIsFocused(false)
|
|
214
261
|
if (name && label && !hasInput && formname) {
|
|
215
|
-
console.log('StyledComponent: Calling validateField on blur', {
|
|
216
|
-
name,
|
|
217
|
-
label,
|
|
218
|
-
required,
|
|
219
|
-
formname,
|
|
220
|
-
})
|
|
221
262
|
const formData = new FormData()
|
|
222
263
|
formData.append(name, '')
|
|
223
264
|
validateField(name, formData, label, required, formname)
|
|
224
265
|
}
|
|
225
266
|
}
|
|
226
267
|
|
|
268
|
+
/**
|
|
269
|
+
* Toggle password visibility for password input
|
|
270
|
+
*/
|
|
271
|
+
const togglePasswordVisibility = () => {
|
|
272
|
+
setPasswordVisible(!passwordVisible)
|
|
273
|
+
}
|
|
274
|
+
|
|
227
275
|
const isDropdownVariant = componentvariant === 'dropdown'
|
|
228
276
|
const isSplitButtonVariant = componentvariant === 'splitbutton'
|
|
229
277
|
const isNotchedVariant =
|
|
@@ -233,24 +281,13 @@ const StyledComponent: React.FC<StyledComponentProps> = props => {
|
|
|
233
281
|
!!label
|
|
234
282
|
const hasPlaceholder = !!placeholder
|
|
235
283
|
|
|
236
|
-
/**
|
|
237
|
-
* Determine if the label should be shrunk based on various conditions.
|
|
238
|
-
*/
|
|
239
284
|
const shouldShrinkLabel =
|
|
240
285
|
isFocused ||
|
|
241
286
|
isDropdownVariant ||
|
|
242
287
|
isSplitButtonVariant ||
|
|
243
288
|
hasPlaceholder ||
|
|
244
289
|
hasInput ||
|
|
245
|
-
componentvariant === 'phonenumber'
|
|
246
|
-
|
|
247
|
-
console.log('StyledComponent: Rendering', {
|
|
248
|
-
name,
|
|
249
|
-
showError,
|
|
250
|
-
hasHelperFooter: !!currentHelperFooter,
|
|
251
|
-
helperFooterStatus: currentHelperFooter?.status,
|
|
252
|
-
helperFooterMessage: currentHelperFooter?.statusMessage,
|
|
253
|
-
})
|
|
290
|
+
(componentvariant === 'phonenumber' && phoneNumber !== '')
|
|
254
291
|
|
|
255
292
|
return (
|
|
256
293
|
<Box
|
|
@@ -341,6 +378,7 @@ const StyledComponent: React.FC<StyledComponentProps> = props => {
|
|
|
341
378
|
<EndAdornment
|
|
342
379
|
componentvariant={componentvariant || ''}
|
|
343
380
|
passwordVisible={passwordVisible}
|
|
381
|
+
togglePasswordVisibility={togglePasswordVisibility}
|
|
344
382
|
iconcolor={iconcolor}
|
|
345
383
|
handleIncrement={handleIncrement}
|
|
346
384
|
handleDecrement={handleDecrement}
|
|
@@ -349,17 +387,20 @@ const StyledComponent: React.FC<StyledComponentProps> = props => {
|
|
|
349
387
|
onChange={handleChange}
|
|
350
388
|
onFocus={handleFocus}
|
|
351
389
|
onBlur={handleBlur}
|
|
390
|
+
onClick={isDropdownVariant ? handleDropdownClick : undefined}
|
|
352
391
|
fullWidth
|
|
353
392
|
multiline={componentvariant === 'multilinetextfield'}
|
|
354
393
|
label={label}
|
|
355
394
|
autoComplete="off"
|
|
356
395
|
name={name}
|
|
357
396
|
value={
|
|
358
|
-
|
|
359
|
-
?
|
|
360
|
-
:
|
|
361
|
-
?
|
|
362
|
-
:
|
|
397
|
+
componentvariant === 'phonenumber'
|
|
398
|
+
? phoneNumber
|
|
399
|
+
: isDropdownVariant
|
|
400
|
+
? selectedOption
|
|
401
|
+
: isSplitButtonVariant
|
|
402
|
+
? splitButtonValue
|
|
403
|
+
: value
|
|
363
404
|
}
|
|
364
405
|
readOnly={isDropdownVariant}
|
|
365
406
|
notched={
|
|
@@ -367,10 +408,10 @@ const StyledComponent: React.FC<StyledComponentProps> = props => {
|
|
|
367
408
|
((isDropdownVariant || isSplitButtonVariant) &&
|
|
368
409
|
shrunklabellocation !== 'above') ||
|
|
369
410
|
hasPlaceholder ||
|
|
370
|
-
componentvariant === 'phonenumber'
|
|
411
|
+
(componentvariant === 'phonenumber' && phoneNumber !== '')
|
|
371
412
|
}
|
|
372
413
|
/>
|
|
373
|
-
{isDropdownVariant &&
|
|
414
|
+
{isDropdownVariant && renderMenu}
|
|
374
415
|
</Box>
|
|
375
416
|
</Box>
|
|
376
417
|
{showError && currentHelperFooter?.statusMessage && (
|
|
@@ -18,7 +18,6 @@ export const useHasInputEffect = (
|
|
|
18
18
|
) => {
|
|
19
19
|
useEffect(() => {
|
|
20
20
|
const hasInput = !!value || !!valuestatus
|
|
21
|
-
console.log('useHasInputEffect: Setting hasInput to', hasInput)
|
|
22
21
|
setHasInput(hasInput)
|
|
23
22
|
}, [value, valuestatus, setHasInput])
|
|
24
23
|
}
|
|
@@ -39,16 +38,12 @@ export const usePreventAutocompleteEffect = (
|
|
|
39
38
|
inputRefInternal: React.RefObject<HTMLInputElement>
|
|
40
39
|
) => {
|
|
41
40
|
useEffect(() => {
|
|
42
|
-
console.log('usePreventAutocompleteEffect: Starting effect')
|
|
43
41
|
const input = inputRefInternal.current
|
|
44
42
|
if (input) {
|
|
45
|
-
console.log('usePreventAutocompleteEffect: Setting input attributes')
|
|
46
43
|
input.setAttribute('autocomplete', 'new-password')
|
|
47
44
|
input.setAttribute('autocorrect', 'off')
|
|
48
45
|
input.setAttribute('autocapitalize', 'none')
|
|
49
46
|
input.setAttribute('spellcheck', 'false')
|
|
50
|
-
} else {
|
|
51
|
-
console.log('usePreventAutocompleteEffect: Input ref is null')
|
|
52
47
|
}
|
|
53
48
|
}, [inputRefInternal])
|
|
54
49
|
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { useState } from 'react'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* usePassword hook provides functionality for managing password visibility state.
|
|
5
|
-
* It allows toggling the visibility of the password field between masked and unmasked states.
|
|
6
|
-
* @returns An object containing the passwordVisible state and the togglePasswordVisibility function.
|
|
7
|
-
*/
|
|
8
|
-
export const usePassword = () => {
|
|
9
|
-
const [passwordVisible, setPasswordVisible] = useState(false)
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* togglePasswordVisibility function toggles the visibility state of the password field.
|
|
13
|
-
* It switches between the masked and unmasked states.
|
|
14
|
-
*/
|
|
15
|
-
const togglePasswordVisibility = () => {
|
|
16
|
-
setPasswordVisible(!passwordVisible)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
return {
|
|
20
|
-
passwordVisible,
|
|
21
|
-
togglePasswordVisibility,
|
|
22
|
-
}
|
|
23
|
-
}
|