goobs-frontend 0.7.66 → 0.7.67
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/app/_app.tsx +8 -8
- package/src/components/Button/hook/useHelperFooter.tsx +65 -75
- package/src/components/Button/index.tsx +4 -9
- package/src/components/StyledComponent/hooks/useDropdown.tsx +31 -27
- package/src/components/StyledComponent/hooks/useInputHelperFooter.tsx +133 -176
- package/src/components/StyledComponent/hooks/usePhoneNumber.tsx +9 -6
- package/src/components/StyledComponent/hooks/useRequiredFieldsValidator.tsx +130 -77
- package/src/components/StyledComponent/hooks/useSearchbar.tsx +2 -0
- package/src/components/StyledComponent/hooks/useSplitButton.tsx +15 -11
- package/src/components/StyledComponent/index.tsx +212 -165
- package/src/components/StyledComponent/{useEffects → useCallbacks}/index.tsx +17 -20
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "goobs-frontend",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.67",
|
|
4
4
|
"description": "A comprehensive React-based UI library built on Material-UI, offering a wide range of customizable components including grids, typography, buttons, cards, forms, navigation, pricing tables, steppers, tooltips, accordions, and more. Designed for building responsive and consistent user interfaces with advanced features like form validation, theming, and code syntax highlighting.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"@mui/icons-material": "^5.16.6",
|
|
29
29
|
"@mui/material": "^5.16.6",
|
|
30
30
|
"@types/lodash": "^4.17.7",
|
|
31
|
-
"goobs-cache": "^1.
|
|
31
|
+
"goobs-cache": "^1.7.0",
|
|
32
32
|
"highlight.js": "^11.10.0",
|
|
33
33
|
"lodash": "^4.17.21",
|
|
34
34
|
"next": "14.2.5"
|
package/src/app/_app.tsx
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import type { AppProps } from 'next/app'
|
|
3
|
-
|
|
4
|
-
const MyApp = ({ Component, pageProps }: AppProps) => {
|
|
5
|
-
return <Component {...pageProps} />
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export default MyApp
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import type { AppProps } from 'next/app'
|
|
3
|
+
|
|
4
|
+
const MyApp = ({ Component, pageProps }: AppProps) => {
|
|
5
|
+
return <Component {...pageProps} />
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export default MyApp
|
|
@@ -16,79 +16,77 @@ const useHelperFooter = (initialFormname?: string) => {
|
|
|
16
16
|
initialFormname
|
|
17
17
|
)
|
|
18
18
|
|
|
19
|
-
const helperFooterAtom =
|
|
20
|
-
string,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const currentErrorIndexAtom = session.atom<number>(0)
|
|
19
|
+
const helperFooterAtom = useMemo(
|
|
20
|
+
() => session.atom<Record<string, HelperFooterMessage> | null>(null),
|
|
21
|
+
[]
|
|
22
|
+
)
|
|
23
|
+
const currentErrorIndexAtom = useMemo(() => session.atom<number>(0), [])
|
|
24
|
+
|
|
25
|
+
const [helperFooters, setHelperFooters] = session.useAtom(helperFooterAtom)
|
|
26
|
+
const [currentErrorIndex, setCurrentErrorIndex] = session.useAtom(
|
|
27
|
+
currentErrorIndexAtom
|
|
28
|
+
)
|
|
29
|
+
const [helperFooterResult] = session.useAtom(
|
|
30
|
+
useMemo(
|
|
31
|
+
() => session.atom(`helperfooter:${initialFormname}`),
|
|
32
|
+
[initialFormname]
|
|
33
|
+
)
|
|
34
|
+
)
|
|
24
35
|
|
|
25
|
-
const fetchHelperFooters = useCallback(
|
|
36
|
+
const fetchHelperFooters = useCallback((): Record<
|
|
26
37
|
string,
|
|
27
38
|
HelperFooterMessage
|
|
28
|
-
> | null
|
|
39
|
+
> | null => {
|
|
29
40
|
console.log('useHelperFooter: fetchHelperFooters called')
|
|
30
41
|
if (!initialFormname) {
|
|
31
42
|
console.log('useHelperFooter: No formname provided, returning null')
|
|
32
43
|
return null
|
|
33
44
|
}
|
|
34
45
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
'
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
fetchedHelperFooters[key] = {
|
|
62
|
-
status: value.status as 'error' | 'success' | 'emptyAndRequired',
|
|
63
|
-
statusMessage: String(value.statusMessage),
|
|
64
|
-
spreadMessage: String(value.spreadMessage),
|
|
65
|
-
spreadMessagePriority: Number(value.spreadMessagePriority),
|
|
66
|
-
required: Boolean(value.required),
|
|
67
|
-
hasInput: Boolean(value.hasInput),
|
|
68
|
-
}
|
|
46
|
+
if (
|
|
47
|
+
helperFooters === null &&
|
|
48
|
+
helperFooterResult &&
|
|
49
|
+
typeof helperFooterResult === 'object' &&
|
|
50
|
+
helperFooterResult !== null
|
|
51
|
+
) {
|
|
52
|
+
const fetchedHelperFooters: Record<string, HelperFooterMessage> = {}
|
|
53
|
+
|
|
54
|
+
for (const [key, value] of Object.entries(helperFooterResult)) {
|
|
55
|
+
if (
|
|
56
|
+
typeof value === 'object' &&
|
|
57
|
+
value !== null &&
|
|
58
|
+
'status' in value &&
|
|
59
|
+
'statusMessage' in value &&
|
|
60
|
+
'spreadMessage' in value &&
|
|
61
|
+
'spreadMessagePriority' in value &&
|
|
62
|
+
'required' in value &&
|
|
63
|
+
'hasInput' in value
|
|
64
|
+
) {
|
|
65
|
+
fetchedHelperFooters[key] = {
|
|
66
|
+
status: value.status as 'error' | 'success' | 'emptyAndRequired',
|
|
67
|
+
statusMessage: String(value.statusMessage),
|
|
68
|
+
spreadMessage: String(value.spreadMessage),
|
|
69
|
+
spreadMessagePriority: Number(value.spreadMessagePriority),
|
|
70
|
+
required: Boolean(value.required),
|
|
71
|
+
hasInput: Boolean(value.hasInput),
|
|
69
72
|
}
|
|
70
73
|
}
|
|
71
|
-
|
|
72
|
-
console.log(
|
|
73
|
-
'useHelperFooter: Fetched helper footers:',
|
|
74
|
-
fetchedHelperFooters
|
|
75
|
-
)
|
|
76
|
-
setHelperFooters(fetchedHelperFooters)
|
|
77
|
-
return fetchedHelperFooters
|
|
78
74
|
}
|
|
79
75
|
|
|
80
76
|
console.log(
|
|
81
|
-
'useHelperFooter:
|
|
77
|
+
'useHelperFooter: Fetched helper footers:',
|
|
78
|
+
fetchedHelperFooters
|
|
82
79
|
)
|
|
83
|
-
|
|
80
|
+
setHelperFooters(fetchedHelperFooters)
|
|
81
|
+
return fetchedHelperFooters
|
|
84
82
|
}
|
|
85
83
|
|
|
86
84
|
return helperFooters
|
|
87
|
-
}, [initialFormname,
|
|
85
|
+
}, [helperFooters, helperFooterResult, initialFormname, setHelperFooters])
|
|
88
86
|
|
|
89
|
-
const updateFormValidation = useCallback(
|
|
87
|
+
const updateFormValidation = useCallback((): boolean => {
|
|
90
88
|
console.log('useHelperFooter: updateFormValidation called')
|
|
91
|
-
const fetchedHelperFooters =
|
|
89
|
+
const fetchedHelperFooters = fetchHelperFooters()
|
|
92
90
|
|
|
93
91
|
if (fetchedHelperFooters) {
|
|
94
92
|
const errorFooters = Object.values(fetchedHelperFooters).filter(
|
|
@@ -100,7 +98,6 @@ const useHelperFooter = (initialFormname?: string) => {
|
|
|
100
98
|
console.log('useHelperFooter: Error footers:', errorFooters)
|
|
101
99
|
|
|
102
100
|
if (errorFooters.length === 0) {
|
|
103
|
-
const [, setCurrentErrorIndex] = session.useAtom(currentErrorIndexAtom)
|
|
104
101
|
setCurrentErrorIndex(0)
|
|
105
102
|
console.log('useHelperFooter: No errors found, returning true')
|
|
106
103
|
return true
|
|
@@ -110,9 +107,6 @@ const useHelperFooter = (initialFormname?: string) => {
|
|
|
110
107
|
(a, b) => a.spreadMessagePriority - b.spreadMessagePriority
|
|
111
108
|
)
|
|
112
109
|
|
|
113
|
-
const [currentErrorIndex, setCurrentErrorIndex] = session.useAtom(
|
|
114
|
-
currentErrorIndexAtom
|
|
115
|
-
)
|
|
116
110
|
if (currentErrorIndex >= errorFooters.length) {
|
|
117
111
|
setCurrentErrorIndex(0)
|
|
118
112
|
}
|
|
@@ -123,11 +117,11 @@ const useHelperFooter = (initialFormname?: string) => {
|
|
|
123
117
|
|
|
124
118
|
console.log('useHelperFooter: No helper footers, returning true')
|
|
125
119
|
return true
|
|
126
|
-
}, [fetchHelperFooters,
|
|
120
|
+
}, [fetchHelperFooters, currentErrorIndex, setCurrentErrorIndex])
|
|
127
121
|
|
|
128
|
-
const checkFormStatus = useCallback(
|
|
122
|
+
const checkFormStatus = useCallback(() => {
|
|
129
123
|
console.log('useHelperFooter: checkFormStatus called')
|
|
130
|
-
const fetchedHelperFooters =
|
|
124
|
+
const fetchedHelperFooters = fetchHelperFooters()
|
|
131
125
|
const status = fetchedHelperFooters
|
|
132
126
|
? Object.values(fetchedHelperFooters).every(
|
|
133
127
|
value => !value.required || (value.required && value.hasInput)
|
|
@@ -137,9 +131,9 @@ const useHelperFooter = (initialFormname?: string) => {
|
|
|
137
131
|
return status
|
|
138
132
|
}, [fetchHelperFooters])
|
|
139
133
|
|
|
140
|
-
const getEmptyRequiredFields = useCallback(
|
|
134
|
+
const getEmptyRequiredFields = useCallback(() => {
|
|
141
135
|
console.log('useHelperFooter: getEmptyRequiredFields called')
|
|
142
|
-
const fetchedHelperFooters =
|
|
136
|
+
const fetchedHelperFooters = fetchHelperFooters()
|
|
143
137
|
if (!fetchedHelperFooters) return []
|
|
144
138
|
const emptyFields = Object.entries(fetchedHelperFooters)
|
|
145
139
|
.filter(([, value]) => value.required && !value.hasInput)
|
|
@@ -148,9 +142,9 @@ const useHelperFooter = (initialFormname?: string) => {
|
|
|
148
142
|
return emptyFields
|
|
149
143
|
}, [fetchHelperFooters])
|
|
150
144
|
|
|
151
|
-
const getCurrentErrorMessage = useCallback(
|
|
145
|
+
const getCurrentErrorMessage = useCallback(() => {
|
|
152
146
|
console.log('useHelperFooter: getCurrentErrorMessage called')
|
|
153
|
-
const fetchedHelperFooters =
|
|
147
|
+
const fetchedHelperFooters = fetchHelperFooters()
|
|
154
148
|
if (!fetchedHelperFooters) return undefined
|
|
155
149
|
const errorFooters = Object.values(fetchedHelperFooters).filter(
|
|
156
150
|
footer =>
|
|
@@ -158,14 +152,13 @@ const useHelperFooter = (initialFormname?: string) => {
|
|
|
158
152
|
footer.required
|
|
159
153
|
)
|
|
160
154
|
if (errorFooters.length === 0) return undefined
|
|
161
|
-
const [currentErrorIndex] = session.useAtom(currentErrorIndexAtom)
|
|
162
155
|
const message = errorFooters[currentErrorIndex]?.spreadMessage
|
|
163
156
|
console.log('useHelperFooter: Current error message:', message)
|
|
164
157
|
return message
|
|
165
|
-
}, [fetchHelperFooters,
|
|
158
|
+
}, [fetchHelperFooters, currentErrorIndex])
|
|
166
159
|
|
|
167
|
-
const isFormValid = useCallback(
|
|
168
|
-
const fetchedHelperFooters =
|
|
160
|
+
const isFormValid = useCallback(() => {
|
|
161
|
+
const fetchedHelperFooters = fetchHelperFooters()
|
|
169
162
|
if (!fetchedHelperFooters) return true
|
|
170
163
|
const valid = Object.values(fetchedHelperFooters).every(
|
|
171
164
|
footer =>
|
|
@@ -175,9 +168,9 @@ const useHelperFooter = (initialFormname?: string) => {
|
|
|
175
168
|
return valid
|
|
176
169
|
}, [fetchHelperFooters])
|
|
177
170
|
|
|
178
|
-
const nextError = useCallback(
|
|
171
|
+
const nextError = useCallback(() => {
|
|
179
172
|
console.log('useHelperFooter: nextError called')
|
|
180
|
-
const fetchedHelperFooters =
|
|
173
|
+
const fetchedHelperFooters = fetchHelperFooters()
|
|
181
174
|
if (!fetchedHelperFooters) return
|
|
182
175
|
const errorFooters = Object.values(fetchedHelperFooters).filter(
|
|
183
176
|
footer =>
|
|
@@ -185,16 +178,13 @@ const useHelperFooter = (initialFormname?: string) => {
|
|
|
185
178
|
footer.required
|
|
186
179
|
)
|
|
187
180
|
if (errorFooters.length > 0) {
|
|
188
|
-
|
|
189
|
-
currentErrorIndexAtom
|
|
190
|
-
)
|
|
191
|
-
setCurrentErrorIndex((currentErrorIndex + 1) % errorFooters.length)
|
|
181
|
+
setCurrentErrorIndex(prevIndex => (prevIndex + 1) % errorFooters.length)
|
|
192
182
|
console.log(
|
|
193
183
|
'useHelperFooter: New error index:',
|
|
194
184
|
(currentErrorIndex + 1) % errorFooters.length
|
|
195
185
|
)
|
|
196
186
|
}
|
|
197
|
-
}, [fetchHelperFooters,
|
|
187
|
+
}, [fetchHelperFooters, currentErrorIndex, setCurrentErrorIndex])
|
|
198
188
|
|
|
199
189
|
const result = useMemo(
|
|
200
190
|
() => ({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useMemo, useCallback,
|
|
1
|
+
import React, { useMemo, useCallback, useState } from 'react'
|
|
2
2
|
import { Button, Box, ButtonProps } from '@mui/material'
|
|
3
3
|
import StarIcon from '@mui/icons-material/Star'
|
|
4
4
|
import Typography from '../Typography'
|
|
@@ -74,9 +74,6 @@ const CustomButton: React.FC<CustomButtonProps> = React.memo(
|
|
|
74
74
|
width,
|
|
75
75
|
} = props
|
|
76
76
|
|
|
77
|
-
const [isFormFinished, setIsFormFinished] = useState<boolean>(false)
|
|
78
|
-
const [isCheckingForm, setIsCheckingForm] = useState<boolean>(true)
|
|
79
|
-
|
|
80
77
|
const {
|
|
81
78
|
updateFormValidation,
|
|
82
79
|
checkFormStatus,
|
|
@@ -84,6 +81,9 @@ const CustomButton: React.FC<CustomButtonProps> = React.memo(
|
|
|
84
81
|
fetchHelperFooters,
|
|
85
82
|
} = useHelperFooter(formname)
|
|
86
83
|
|
|
84
|
+
const [isFormFinished, setIsFormFinished] = useState(false)
|
|
85
|
+
const [isCheckingForm, setIsCheckingForm] = useState(true)
|
|
86
|
+
|
|
87
87
|
const checkFormState = useCallback(async (): Promise<void> => {
|
|
88
88
|
console.log('CustomButton: Checking form state...')
|
|
89
89
|
setIsCheckingForm(true)
|
|
@@ -110,11 +110,6 @@ const CustomButton: React.FC<CustomButtonProps> = React.memo(
|
|
|
110
110
|
)
|
|
111
111
|
}, [checkFormStatus, getEmptyRequiredFields, fetchHelperFooters])
|
|
112
112
|
|
|
113
|
-
useEffect(() => {
|
|
114
|
-
console.log('CustomButton: Performing initial check')
|
|
115
|
-
checkFormState()
|
|
116
|
-
}, [checkFormState])
|
|
117
|
-
|
|
118
113
|
const handleButtonClick = useCallback(
|
|
119
114
|
async (event: React.MouseEvent<HTMLButtonElement>): Promise<void> => {
|
|
120
115
|
event.preventDefault()
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { useState, useCallback } from 'react'
|
|
2
4
|
import { StyledComponentProps } from '..'
|
|
3
5
|
import { styled, Menu, MenuItem } from '@mui/material'
|
|
4
6
|
import React from 'react'
|
|
@@ -29,41 +31,26 @@ export const useDropdown = (
|
|
|
29
31
|
inputBoxRef: React.RefObject<HTMLDivElement>,
|
|
30
32
|
onOptionSelect?: (option: string) => void
|
|
31
33
|
) => {
|
|
34
|
+
const { componentvariant, options, value, defaultOption } = props
|
|
35
|
+
|
|
32
36
|
/** State to control if the dropdown is open */
|
|
33
37
|
const [isDropdownOpen, setIsDropdownOpen] = useState(false)
|
|
34
38
|
/** State to store the anchor element for the dropdown */
|
|
35
39
|
const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null)
|
|
36
40
|
/** State to store the filtered options */
|
|
37
|
-
const [filteredOptions, setFilteredOptions] = useState<string[]>(
|
|
41
|
+
const [filteredOptions, setFilteredOptions] = useState<string[]>(
|
|
42
|
+
componentvariant === 'dropdown' && options ? [...options] : []
|
|
43
|
+
)
|
|
38
44
|
/** State to store the currently selected option */
|
|
39
|
-
const [selectedOption, setSelectedOption] = useState(
|
|
45
|
+
const [selectedOption, setSelectedOption] = useState(() => {
|
|
46
|
+
if (value !== undefined) return value
|
|
47
|
+
if (defaultOption !== undefined) return defaultOption
|
|
48
|
+
if (options && options.length > 0) return options[0]
|
|
49
|
+
return ''
|
|
50
|
+
})
|
|
40
51
|
/** State to track if the dropdown is focused */
|
|
41
52
|
const [isDropdownFocused, setIsDropdownFocused] = useState(false)
|
|
42
53
|
|
|
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
|
-
*/
|
|
48
|
-
useEffect(() => {
|
|
49
|
-
if (componentvariant === 'dropdown' && options) {
|
|
50
|
-
setFilteredOptions([...options])
|
|
51
|
-
}
|
|
52
|
-
}, [componentvariant, options])
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Effect to set the selected option based on value, defaultOption, or first option
|
|
56
|
-
*/
|
|
57
|
-
useEffect(() => {
|
|
58
|
-
if (value !== undefined) {
|
|
59
|
-
setSelectedOption(value)
|
|
60
|
-
} else if (defaultOption !== undefined) {
|
|
61
|
-
setSelectedOption(defaultOption)
|
|
62
|
-
} else if (options && options.length > 0) {
|
|
63
|
-
setSelectedOption(options[0])
|
|
64
|
-
}
|
|
65
|
-
}, [value, defaultOption, options])
|
|
66
|
-
|
|
67
54
|
/**
|
|
68
55
|
* Handle click on the dropdown to open/close it
|
|
69
56
|
*/
|
|
@@ -102,6 +89,22 @@ export const useDropdown = (
|
|
|
102
89
|
[componentvariant]
|
|
103
90
|
)
|
|
104
91
|
|
|
92
|
+
/**
|
|
93
|
+
* Update filtered options and selected option when props change
|
|
94
|
+
*/
|
|
95
|
+
const updateDropdownState = useCallback(() => {
|
|
96
|
+
if (componentvariant === 'dropdown' && options) {
|
|
97
|
+
setFilteredOptions([...options])
|
|
98
|
+
}
|
|
99
|
+
if (value !== undefined) {
|
|
100
|
+
setSelectedOption(value)
|
|
101
|
+
} else if (defaultOption !== undefined) {
|
|
102
|
+
setSelectedOption(defaultOption)
|
|
103
|
+
} else if (options && options.length > 0) {
|
|
104
|
+
setSelectedOption(options[0])
|
|
105
|
+
}
|
|
106
|
+
}, [componentvariant, options, value, defaultOption])
|
|
107
|
+
|
|
105
108
|
/**
|
|
106
109
|
* Render the dropdown menu
|
|
107
110
|
*/
|
|
@@ -142,5 +145,6 @@ export const useDropdown = (
|
|
|
142
145
|
handleOptionSelect,
|
|
143
146
|
isDropdownFocused,
|
|
144
147
|
handleInputFocus,
|
|
148
|
+
updateDropdownState,
|
|
145
149
|
}
|
|
146
150
|
}
|