goobs-frontend 0.7.53
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/LICENSE +21 -0
- package/README.md +190 -0
- package/package.json +122 -0
- package/src/app/_app.tsx +8 -0
- package/src/atoms/helperfooter.ts +21 -0
- package/src/components/Button/index.tsx +241 -0
- package/src/components/ConfirmationCodeInput/index.tsx +108 -0
- package/src/components/ConfirmationCodeInput/utils/useCodeConfirmation.tsx +129 -0
- package/src/components/Content/Structure/animations.tsx +106 -0
- package/src/components/Content/Structure/button/useButton.tsx +80 -0
- package/src/components/Content/Structure/confirmationinput/useConfirmationInput.tsx +56 -0
- package/src/components/Content/Structure/image/useImage.tsx +62 -0
- package/src/components/Content/Structure/link/useLink.tsx +60 -0
- package/src/components/Content/Structure/radiogroup/useGridRadioGroup.tsx +62 -0
- package/src/components/Content/Structure/styledcomponent/useStyledComponent.tsx +96 -0
- package/src/components/Content/Structure/typography/useGridTypography.tsx +53 -0
- package/src/components/Content/index.tsx +147 -0
- package/src/components/Form/Popup/index.tsx +121 -0
- package/src/components/Grid/defaultconfig.tsx +131 -0
- package/src/components/Grid/index.tsx +265 -0
- package/src/components/Icons/Calendar.tsx +21 -0
- package/src/components/Icons/DownArrowFilled.tsx +9 -0
- package/src/components/Icons/Drag.tsx +9 -0
- package/src/components/Icons/FavoriteIcon.tsx +24 -0
- package/src/components/Icons/Info.tsx +12 -0
- package/src/components/Icons/Search.tsx +29 -0
- package/src/components/Icons/ShowHideEye.tsx +16 -0
- package/src/components/RadioGroup/index.tsx +96 -0
- package/src/components/StyledComponent/adornments.tsx +118 -0
- package/src/components/StyledComponent/helperfooter/useHelperFooter.tsx +411 -0
- package/src/components/StyledComponent/hooks/useDropdown.tsx +144 -0
- package/src/components/StyledComponent/hooks/usePassword.tsx +23 -0
- package/src/components/StyledComponent/hooks/usePhoneNumber.tsx +75 -0
- package/src/components/StyledComponent/hooks/useSearchbar.tsx +44 -0
- package/src/components/StyledComponent/hooks/useSplitButton.tsx +66 -0
- package/src/components/StyledComponent/index.tsx +404 -0
- package/src/components/Typography/index.tsx +268 -0
- package/src/index.ts +210 -0
- package/src/main.tsx +7 -0
- package/src/styles/Form/index.ts +7 -0
- package/src/styles/StyledComponent/Label/index.ts +76 -0
- package/src/styles/palette.ts +143 -0
- package/src/styles/typography.ts +184 -0
- package/src/types/async-lock.d.ts +35 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import React, { ChangeEvent, KeyboardEvent } from 'react'
|
|
3
|
+
import { Input, Box } from '@mui/material'
|
|
4
|
+
import { useCodeConfirmation } from './utils/useCodeConfirmation'
|
|
5
|
+
import { columnconfig } from '../../components/Grid'
|
|
6
|
+
import { red, green } from '../../styles/palette'
|
|
7
|
+
|
|
8
|
+
export interface ConfirmationCodeInputsProps {
|
|
9
|
+
identifier?: string
|
|
10
|
+
columnconfig?: columnconfig
|
|
11
|
+
isValid: boolean
|
|
12
|
+
codeLength?: number
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* ConfirmationCodeInputs component renders a set of input fields for entering a confirmation code.
|
|
17
|
+
* It uses the useCodeConfirmation hook to handle code changes and key events.
|
|
18
|
+
* @param props The props for the ConfirmationCodeInputs component.
|
|
19
|
+
* @returns The rendered ConfirmationCodeInputs component.
|
|
20
|
+
*/
|
|
21
|
+
const ConfirmationCodeInputs: React.FC<ConfirmationCodeInputsProps> = ({
|
|
22
|
+
codeLength = 6,
|
|
23
|
+
isValid,
|
|
24
|
+
...props
|
|
25
|
+
}) => {
|
|
26
|
+
const { handleCodeChange, handleKeyDown } = useCodeConfirmation({
|
|
27
|
+
codeLength,
|
|
28
|
+
isValid,
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* handleChange function is called when the value of an input field changes.
|
|
33
|
+
* It updates the code state using the handleCodeChange function from the useCodeConfirmation hook.
|
|
34
|
+
* If the input field has a value, it focuses on the next input field.
|
|
35
|
+
* @param event The change event triggered by the input field.
|
|
36
|
+
* @param index The index of the input field.
|
|
37
|
+
*/
|
|
38
|
+
const handleChange = (
|
|
39
|
+
event: ChangeEvent<HTMLInputElement>,
|
|
40
|
+
index: number
|
|
41
|
+
) => {
|
|
42
|
+
handleCodeChange(event, index)
|
|
43
|
+
if (event.target.value) {
|
|
44
|
+
const nextInput = document.querySelector(
|
|
45
|
+
`input[name=code${index + 2}]`
|
|
46
|
+
) as HTMLInputElement | null
|
|
47
|
+
if (nextInput) {
|
|
48
|
+
nextInput.focus()
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* handleKeyDownWrapper function is a wrapper for the handleKeyDown function from the useCodeConfirmation hook.
|
|
55
|
+
* It is called when a key is pressed while an input field is focused.
|
|
56
|
+
* @param event The keyboard event triggered by the input field.
|
|
57
|
+
* @param index The index of the input field.
|
|
58
|
+
*/
|
|
59
|
+
const handleKeyDownWrapper = (
|
|
60
|
+
event: KeyboardEvent<HTMLInputElement>,
|
|
61
|
+
index: number
|
|
62
|
+
) => {
|
|
63
|
+
handleKeyDown(event, index)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<Box display="flex" flexDirection="row" alignItems="center">
|
|
68
|
+
<Box display="flex" gap={1}>
|
|
69
|
+
{Array.from({ length: codeLength }, (_, index) => (
|
|
70
|
+
<Input
|
|
71
|
+
key={index}
|
|
72
|
+
name={`code${index + 1}`}
|
|
73
|
+
inputProps={{
|
|
74
|
+
maxLength: 1,
|
|
75
|
+
}}
|
|
76
|
+
sx={{
|
|
77
|
+
border: '1px solid',
|
|
78
|
+
borderColor: 'black',
|
|
79
|
+
borderRadius: 1,
|
|
80
|
+
width: 50,
|
|
81
|
+
height: 50,
|
|
82
|
+
input: {
|
|
83
|
+
textAlign: 'center',
|
|
84
|
+
color: 'black',
|
|
85
|
+
},
|
|
86
|
+
}}
|
|
87
|
+
onChange={(event: ChangeEvent<HTMLInputElement>) =>
|
|
88
|
+
handleChange(event, index)
|
|
89
|
+
}
|
|
90
|
+
onKeyDown={(event: KeyboardEvent<HTMLInputElement>) =>
|
|
91
|
+
handleKeyDownWrapper(event, index)
|
|
92
|
+
}
|
|
93
|
+
{...props}
|
|
94
|
+
/>
|
|
95
|
+
))}
|
|
96
|
+
</Box>
|
|
97
|
+
<Box
|
|
98
|
+
width={20}
|
|
99
|
+
height={20}
|
|
100
|
+
borderRadius="50%"
|
|
101
|
+
bgcolor={isValid ? green.main : red.main}
|
|
102
|
+
ml={2}
|
|
103
|
+
/>
|
|
104
|
+
</Box>
|
|
105
|
+
)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export default ConfirmationCodeInputs
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import React, { useCallback, useState, useEffect } from 'react'
|
|
3
|
+
import { ConfirmationCodeInputsProps } from '..'
|
|
4
|
+
|
|
5
|
+
interface CodeState {
|
|
6
|
+
code1: string
|
|
7
|
+
code2: string
|
|
8
|
+
code3: string
|
|
9
|
+
code4: string
|
|
10
|
+
code5: string
|
|
11
|
+
code6: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface UseCodeConfirmationProps extends ConfirmationCodeInputsProps {
|
|
15
|
+
codeLength: number
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* useCodeConfirmation hook handles the state and logic for a confirmation code input.
|
|
20
|
+
* @param codeLength The length of the confirmation code.
|
|
21
|
+
* @param isValid A boolean indicating whether the entered code is valid.
|
|
22
|
+
* @returns An object containing the necessary handlers and state for the confirmation code input.
|
|
23
|
+
*/
|
|
24
|
+
export const useCodeConfirmation = ({
|
|
25
|
+
codeLength,
|
|
26
|
+
isValid,
|
|
27
|
+
}: UseCodeConfirmationProps) => {
|
|
28
|
+
const [code, setCode] = useState<CodeState>({
|
|
29
|
+
code1: '',
|
|
30
|
+
code2: '',
|
|
31
|
+
code3: '',
|
|
32
|
+
code4: '',
|
|
33
|
+
code5: '',
|
|
34
|
+
code6: '',
|
|
35
|
+
})
|
|
36
|
+
const [iconColor, setIconColor] = useState<string>('red')
|
|
37
|
+
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (isValid) {
|
|
40
|
+
setIconColor('green')
|
|
41
|
+
} else {
|
|
42
|
+
setIconColor('red')
|
|
43
|
+
}
|
|
44
|
+
}, [isValid])
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* handleCodeChange updates the code state when an input value changes.
|
|
48
|
+
* @param event The change event triggered by the input.
|
|
49
|
+
* @param index The index of the input field.
|
|
50
|
+
*/
|
|
51
|
+
const handleCodeChange = useCallback(
|
|
52
|
+
(event: React.ChangeEvent<HTMLInputElement>, index: number) => {
|
|
53
|
+
const value = event.target.value.replace(/[^0-9]/g, '')
|
|
54
|
+
setCode(prevCode => ({
|
|
55
|
+
...prevCode,
|
|
56
|
+
[`code${index + 1}`]: value,
|
|
57
|
+
}))
|
|
58
|
+
},
|
|
59
|
+
[]
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* handleKeyDown handles the keydown event on the input fields.
|
|
64
|
+
* @param event The keydown event triggered by the input.
|
|
65
|
+
* @param index The index of the input field.
|
|
66
|
+
*/
|
|
67
|
+
const handleKeyDown = useCallback(
|
|
68
|
+
(event: React.KeyboardEvent<HTMLInputElement>, index: number) => {
|
|
69
|
+
if (
|
|
70
|
+
event.key === 'Backspace' &&
|
|
71
|
+
!code[`code${index + 1}` as keyof CodeState] &&
|
|
72
|
+
index > 0
|
|
73
|
+
) {
|
|
74
|
+
setCode(prevCode => ({
|
|
75
|
+
...prevCode,
|
|
76
|
+
[`code${index}`]: '',
|
|
77
|
+
}))
|
|
78
|
+
} else if (event.key === 'ArrowLeft') {
|
|
79
|
+
if (index > 0) {
|
|
80
|
+
const prevInput = document.querySelector(
|
|
81
|
+
`input[identifier=code${index}]`
|
|
82
|
+
) as HTMLInputElement | null
|
|
83
|
+
if (prevInput) {
|
|
84
|
+
prevInput.focus()
|
|
85
|
+
setTimeout(() => {
|
|
86
|
+
if (code[`code${index}` as keyof CodeState]) {
|
|
87
|
+
prevInput.setSelectionRange(
|
|
88
|
+
prevInput.value.length,
|
|
89
|
+
prevInput.value.length
|
|
90
|
+
)
|
|
91
|
+
} else {
|
|
92
|
+
prevInput.setSelectionRange(0, 0)
|
|
93
|
+
}
|
|
94
|
+
}, 0)
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
} else if (event.key === 'ArrowRight') {
|
|
98
|
+
if (index < codeLength - 1) {
|
|
99
|
+
const nextInput = document.querySelector(
|
|
100
|
+
`input[identifier=code${index + 2}]`
|
|
101
|
+
) as HTMLInputElement | null
|
|
102
|
+
if (nextInput) {
|
|
103
|
+
nextInput.focus()
|
|
104
|
+
setTimeout(() => {
|
|
105
|
+
if (code[`code${index + 2}` as keyof CodeState]) {
|
|
106
|
+
nextInput.setSelectionRange(
|
|
107
|
+
nextInput.value.length,
|
|
108
|
+
nextInput.value.length
|
|
109
|
+
)
|
|
110
|
+
} else {
|
|
111
|
+
nextInput.setSelectionRange(0, 0)
|
|
112
|
+
}
|
|
113
|
+
}, 0)
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
[code, codeLength]
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
const combinedCode = Object.values(code).join('')
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
handleCodeChange,
|
|
125
|
+
handleKeyDown,
|
|
126
|
+
combinedCode,
|
|
127
|
+
iconColor,
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { Box, styled, keyframes } from '@mui/material'
|
|
3
|
+
import React, { useEffect } from 'react'
|
|
4
|
+
|
|
5
|
+
export type Animation =
|
|
6
|
+
| 'none'
|
|
7
|
+
| 'slideIn'
|
|
8
|
+
| 'slideInUp'
|
|
9
|
+
| 'slideInDown'
|
|
10
|
+
| 'slideInLeft'
|
|
11
|
+
| 'slideInRight'
|
|
12
|
+
| 'stuckOnScroll'
|
|
13
|
+
| 'fadeOut'
|
|
14
|
+
| 'fadeIn'
|
|
15
|
+
|
|
16
|
+
export const slideIn = keyframes`
|
|
17
|
+
0% { opacity: 0; transform: translateX(-20px); }
|
|
18
|
+
100% { opacity: 1; transform: translateX(0); }
|
|
19
|
+
`
|
|
20
|
+
|
|
21
|
+
export const slideInUp = keyframes`
|
|
22
|
+
0% { opacity: 0; transform: translateY(20px); }
|
|
23
|
+
100% { opacity: 1; transform: translateY(0); }
|
|
24
|
+
`
|
|
25
|
+
|
|
26
|
+
export const slideInDown = keyframes`
|
|
27
|
+
0% { opacity: 0; transform: translateY(-20px); }
|
|
28
|
+
100% { opacity: 1; transform: translateY(0); }
|
|
29
|
+
`
|
|
30
|
+
|
|
31
|
+
export const slideInLeft = keyframes`
|
|
32
|
+
0% { opacity: 0; transform: translateX(-20px); }
|
|
33
|
+
100% { opacity: 1; transform: translateX(0); }
|
|
34
|
+
`
|
|
35
|
+
|
|
36
|
+
export const slideInRight = keyframes`
|
|
37
|
+
0% { opacity: 0; transform: translateX(20px); }
|
|
38
|
+
100% { opacity: 1; transform: translateX(0); }
|
|
39
|
+
`
|
|
40
|
+
|
|
41
|
+
export const fadeOut = keyframes`
|
|
42
|
+
0% { opacity: 1; }
|
|
43
|
+
100% { opacity: 0; }
|
|
44
|
+
`
|
|
45
|
+
|
|
46
|
+
export const fadeIn = keyframes`
|
|
47
|
+
0% { opacity: 0; }
|
|
48
|
+
100% { opacity: 1; }
|
|
49
|
+
`
|
|
50
|
+
|
|
51
|
+
interface AnimationProps {
|
|
52
|
+
animationtype?: Animation
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const animationStyles: Record<Animation, string> = {
|
|
56
|
+
none: 'none',
|
|
57
|
+
slideIn: `${slideIn} 1s ease-in-out forwards`,
|
|
58
|
+
slideInUp: `${slideInUp} 1s ease-in-out forwards`,
|
|
59
|
+
slideInDown: `${slideInDown} 1s ease-in-out forwards`,
|
|
60
|
+
slideInLeft: `${slideInLeft} 1s ease-in-out forwards`,
|
|
61
|
+
slideInRight: `${slideInRight} 1s ease-in-out forwards`,
|
|
62
|
+
fadeOut: `${fadeOut} 0.5s ease-out forwards`,
|
|
63
|
+
fadeIn: `${fadeIn} 0.5s ease-in forwards`,
|
|
64
|
+
stuckOnScroll: 'none', // Assuming no animation for 'stuckOnScroll' as it's likely a CSS position behavior.
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export const AnimatedElement = styled(Box)<AnimationProps>(
|
|
68
|
+
({ animationtype }) => ({
|
|
69
|
+
opacity: animationtype === 'none' ? 1 : 0,
|
|
70
|
+
animation: animationtype ? animationStyles[animationtype] : 'none',
|
|
71
|
+
})
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
export const StuckElement = styled(Box)`
|
|
75
|
+
position: sticky;
|
|
76
|
+
top: 0;
|
|
77
|
+
z-index: 1;
|
|
78
|
+
`
|
|
79
|
+
|
|
80
|
+
export function useAnimation(ref: React.RefObject<HTMLDivElement>) {
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
const observer = new IntersectionObserver(
|
|
83
|
+
entries => {
|
|
84
|
+
entries.forEach(entry => {
|
|
85
|
+
if (entry.isIntersecting) {
|
|
86
|
+
entry.target.classList.add('animate')
|
|
87
|
+
} else {
|
|
88
|
+
entry.target.classList.remove('animate')
|
|
89
|
+
}
|
|
90
|
+
})
|
|
91
|
+
},
|
|
92
|
+
{ threshold: 0.2 }
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
const currentRef = ref.current
|
|
96
|
+
if (currentRef) {
|
|
97
|
+
observer.observe(currentRef)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return () => {
|
|
101
|
+
if (currentRef) {
|
|
102
|
+
observer.unobserve(currentRef)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}, [ref])
|
|
106
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import CustomButton, { CustomButtonProps } from './../../../Button'
|
|
4
|
+
import { columnconfig, cellconfig } from '../../../Grid'
|
|
5
|
+
import { TypographyPropsVariantOverrides } from '@mui/material'
|
|
6
|
+
|
|
7
|
+
export interface ExtendedButtonProps extends CustomButtonProps {
|
|
8
|
+
columnconfig?: columnconfig
|
|
9
|
+
cellconfig?: cellconfig
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const useButton = (grid: {
|
|
13
|
+
button?: ExtendedButtonProps | ExtendedButtonProps[]
|
|
14
|
+
}) => {
|
|
15
|
+
if (!grid.button) return null
|
|
16
|
+
|
|
17
|
+
const renderButton = (
|
|
18
|
+
buttonItem: ExtendedButtonProps,
|
|
19
|
+
index: number
|
|
20
|
+
): columnconfig => {
|
|
21
|
+
const {
|
|
22
|
+
text,
|
|
23
|
+
name,
|
|
24
|
+
backgroundcolor,
|
|
25
|
+
outlinecolor,
|
|
26
|
+
fontcolor,
|
|
27
|
+
width,
|
|
28
|
+
fontlocation,
|
|
29
|
+
fontvariant,
|
|
30
|
+
icon,
|
|
31
|
+
iconcolor,
|
|
32
|
+
iconsize,
|
|
33
|
+
iconlocation,
|
|
34
|
+
variant,
|
|
35
|
+
onClick,
|
|
36
|
+
helperfooter,
|
|
37
|
+
columnconfig: itemColumnConfig,
|
|
38
|
+
cellconfig,
|
|
39
|
+
...restProps
|
|
40
|
+
} = buttonItem
|
|
41
|
+
|
|
42
|
+
const mergedConfig: columnconfig = {
|
|
43
|
+
...itemColumnConfig,
|
|
44
|
+
cellconfig: {
|
|
45
|
+
...cellconfig,
|
|
46
|
+
},
|
|
47
|
+
component: (
|
|
48
|
+
<CustomButton
|
|
49
|
+
key={`button-${index}`}
|
|
50
|
+
text={text}
|
|
51
|
+
name={name}
|
|
52
|
+
backgroundcolor={backgroundcolor}
|
|
53
|
+
outlinecolor={outlinecolor}
|
|
54
|
+
fontcolor={fontcolor}
|
|
55
|
+
width={width}
|
|
56
|
+
fontlocation={fontlocation}
|
|
57
|
+
fontvariant={fontvariant as keyof TypographyPropsVariantOverrides}
|
|
58
|
+
icon={icon}
|
|
59
|
+
iconcolor={iconcolor}
|
|
60
|
+
iconsize={iconsize}
|
|
61
|
+
iconlocation={iconlocation}
|
|
62
|
+
variant={variant}
|
|
63
|
+
onClick={onClick}
|
|
64
|
+
helperfooter={helperfooter}
|
|
65
|
+
{...restProps}
|
|
66
|
+
/>
|
|
67
|
+
),
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return mergedConfig
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (Array.isArray(grid.button)) {
|
|
74
|
+
return grid.button.map(renderButton)
|
|
75
|
+
} else {
|
|
76
|
+
return [renderButton(grid.button, 0)]
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export default useButton
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import ConfirmationCodeInputs, {
|
|
4
|
+
ConfirmationCodeInputsProps,
|
|
5
|
+
} from '../../../ConfirmationCodeInput'
|
|
6
|
+
import { columnconfig, cellconfig } from '../../../Grid'
|
|
7
|
+
|
|
8
|
+
export interface ExtendedConfirmationCodeInputsProps
|
|
9
|
+
extends ConfirmationCodeInputsProps {
|
|
10
|
+
columnconfig?: columnconfig
|
|
11
|
+
cellconfig?: cellconfig
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const useConfirmationInput = (grid: {
|
|
15
|
+
confirmationcodeinput?:
|
|
16
|
+
| ExtendedConfirmationCodeInputsProps
|
|
17
|
+
| ExtendedConfirmationCodeInputsProps[]
|
|
18
|
+
}): columnconfig | columnconfig[] | null => {
|
|
19
|
+
if (!grid.confirmationcodeinput) return null
|
|
20
|
+
|
|
21
|
+
const renderConfirmationInput = (
|
|
22
|
+
confirmationCodeInputProps: ExtendedConfirmationCodeInputsProps,
|
|
23
|
+
index: number
|
|
24
|
+
): columnconfig => {
|
|
25
|
+
const {
|
|
26
|
+
identifier,
|
|
27
|
+
isValid,
|
|
28
|
+
columnconfig: itemColumnConfig,
|
|
29
|
+
cellconfig,
|
|
30
|
+
...restProps
|
|
31
|
+
} = confirmationCodeInputProps
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
...itemColumnConfig,
|
|
35
|
+
cellconfig: {
|
|
36
|
+
...cellconfig,
|
|
37
|
+
},
|
|
38
|
+
component: (
|
|
39
|
+
<ConfirmationCodeInputs
|
|
40
|
+
key={`confirmationcodeinput-${index}`}
|
|
41
|
+
identifier={identifier}
|
|
42
|
+
isValid={isValid}
|
|
43
|
+
{...restProps}
|
|
44
|
+
/>
|
|
45
|
+
),
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (Array.isArray(grid.confirmationcodeinput)) {
|
|
50
|
+
return grid.confirmationcodeinput.map(renderConfirmationInput)
|
|
51
|
+
} else {
|
|
52
|
+
return renderConfirmationInput(grid.confirmationcodeinput, 0)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export default useConfirmationInput
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import Image from 'next/image'
|
|
4
|
+
import { columnconfig, cellconfig } from '../../../Grid'
|
|
5
|
+
|
|
6
|
+
type ImageProps = {
|
|
7
|
+
url: string
|
|
8
|
+
alt?: string
|
|
9
|
+
width?: number
|
|
10
|
+
height?: number
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface ExtendedImageProps extends Omit<ImageProps, 'columnconfig'> {
|
|
14
|
+
columnconfig?: columnconfig
|
|
15
|
+
cellconfig?: cellconfig
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const useImage = (grid: {
|
|
19
|
+
image?: ExtendedImageProps | ExtendedImageProps[]
|
|
20
|
+
}) => {
|
|
21
|
+
if (!grid.image) return null
|
|
22
|
+
|
|
23
|
+
const renderImage = (
|
|
24
|
+
imageItem: ExtendedImageProps,
|
|
25
|
+
index: number
|
|
26
|
+
): columnconfig => {
|
|
27
|
+
const {
|
|
28
|
+
url,
|
|
29
|
+
alt = '',
|
|
30
|
+
columnconfig: itemColumnConfig,
|
|
31
|
+
cellconfig,
|
|
32
|
+
...restProps
|
|
33
|
+
} = imageItem
|
|
34
|
+
|
|
35
|
+
if (!url) return itemColumnConfig || {}
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
...itemColumnConfig,
|
|
39
|
+
cellconfig: {
|
|
40
|
+
...cellconfig,
|
|
41
|
+
},
|
|
42
|
+
component: (
|
|
43
|
+
<Image
|
|
44
|
+
key={`image-${index}`}
|
|
45
|
+
src={url}
|
|
46
|
+
alt={alt || 'image'}
|
|
47
|
+
style={{ width: '100%', height: 'auto' }}
|
|
48
|
+
fill
|
|
49
|
+
{...restProps}
|
|
50
|
+
/>
|
|
51
|
+
),
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (Array.isArray(grid.image)) {
|
|
56
|
+
return grid.image.map(renderImage)
|
|
57
|
+
} else {
|
|
58
|
+
return [renderImage(grid.image, 0)]
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export default useImage
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import Link from 'next/link'
|
|
4
|
+
import { Typography, TypographyProps } from '../../../Typography'
|
|
5
|
+
import { columnconfig, cellconfig } from '../../../Grid'
|
|
6
|
+
|
|
7
|
+
export interface ExtendedTypographyProps extends TypographyProps {
|
|
8
|
+
columnconfig?: columnconfig
|
|
9
|
+
cellconfig?: cellconfig
|
|
10
|
+
link?: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const useLink = (grid: {
|
|
14
|
+
link?: ExtendedTypographyProps | ExtendedTypographyProps[]
|
|
15
|
+
}) => {
|
|
16
|
+
if (!grid.link) return null
|
|
17
|
+
|
|
18
|
+
const renderLink = (
|
|
19
|
+
linkItem: ExtendedTypographyProps,
|
|
20
|
+
index: number
|
|
21
|
+
): columnconfig => {
|
|
22
|
+
const {
|
|
23
|
+
link,
|
|
24
|
+
text,
|
|
25
|
+
fontcolor,
|
|
26
|
+
fontvariant,
|
|
27
|
+
columnconfig: itemColumnConfig,
|
|
28
|
+
cellconfig,
|
|
29
|
+
...restProps
|
|
30
|
+
} = linkItem
|
|
31
|
+
|
|
32
|
+
if (!link) {
|
|
33
|
+
throw new Error('Link property is required in ExtendedTypographyProps')
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
...itemColumnConfig,
|
|
38
|
+
cellconfig: {
|
|
39
|
+
...cellconfig,
|
|
40
|
+
},
|
|
41
|
+
component: (
|
|
42
|
+
<Link key={`link-${index}`} href={link} passHref {...restProps}>
|
|
43
|
+
<Typography
|
|
44
|
+
text={text}
|
|
45
|
+
fontvariant={fontvariant}
|
|
46
|
+
fontcolor={fontcolor}
|
|
47
|
+
/>
|
|
48
|
+
</Link>
|
|
49
|
+
),
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (Array.isArray(grid.link)) {
|
|
54
|
+
return grid.link.map(renderLink)
|
|
55
|
+
} else {
|
|
56
|
+
return [renderLink(grid.link, 0)]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export default useLink
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import RadioGroup from '../../../RadioGroup'
|
|
3
|
+
import { columnconfig, cellconfig } from '../../../Grid'
|
|
4
|
+
import { RadioGroupProps as BaseRadioGroupProps } from '../../../../components/RadioGroup'
|
|
5
|
+
|
|
6
|
+
export interface ExtendedRadioGroupProps
|
|
7
|
+
extends Omit<BaseRadioGroupProps, 'columnconfig'> {
|
|
8
|
+
columnconfig?: columnconfig
|
|
9
|
+
cellconfig?: cellconfig
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const useGridRadioGroup = (grid: {
|
|
13
|
+
radiogroup?: ExtendedRadioGroupProps | ExtendedRadioGroupProps[]
|
|
14
|
+
}) => {
|
|
15
|
+
if (!grid.radiogroup) return null
|
|
16
|
+
|
|
17
|
+
const renderRadioGroup = (
|
|
18
|
+
radiogroup: ExtendedRadioGroupProps,
|
|
19
|
+
index: number
|
|
20
|
+
): columnconfig => {
|
|
21
|
+
const {
|
|
22
|
+
label,
|
|
23
|
+
options,
|
|
24
|
+
defaultValue,
|
|
25
|
+
name,
|
|
26
|
+
labelFontVariant,
|
|
27
|
+
labelFontColor,
|
|
28
|
+
labelText,
|
|
29
|
+
columnconfig: itemColumnConfig,
|
|
30
|
+
cellconfig,
|
|
31
|
+
...restProps
|
|
32
|
+
} = radiogroup
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
...itemColumnConfig,
|
|
36
|
+
cellconfig: {
|
|
37
|
+
...cellconfig,
|
|
38
|
+
},
|
|
39
|
+
component: (
|
|
40
|
+
<RadioGroup
|
|
41
|
+
key={`radiogroup-${index}`}
|
|
42
|
+
label={label}
|
|
43
|
+
options={options}
|
|
44
|
+
defaultValue={defaultValue}
|
|
45
|
+
name={name}
|
|
46
|
+
labelFontVariant={labelFontVariant}
|
|
47
|
+
labelFontColor={labelFontColor}
|
|
48
|
+
labelText={labelText}
|
|
49
|
+
{...restProps}
|
|
50
|
+
/>
|
|
51
|
+
),
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (Array.isArray(grid.radiogroup)) {
|
|
56
|
+
return grid.radiogroup.map(renderRadioGroup)
|
|
57
|
+
} else {
|
|
58
|
+
return [renderRadioGroup(grid.radiogroup, 0)]
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export default useGridRadioGroup
|