goobs-frontend 0.7.67 → 0.7.69

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.
Files changed (42) hide show
  1. package/package.json +14 -16
  2. package/src/app/_app.tsx +8 -8
  3. package/src/components/Button/index.tsx +95 -203
  4. package/src/components/ConfirmationCodeInput/index.tsx +4 -6
  5. package/src/components/Content/Structure/button/useButton.tsx +1 -35
  6. package/src/components/Content/Structure/datefield/useDateField.tsx +55 -0
  7. package/src/components/Content/Structure/dropdown/useDropdown.tsx +55 -0
  8. package/src/components/Content/Structure/incremementNumberField/useIncremementNumberField.tsx +65 -0
  9. package/src/components/Content/Structure/numberField/useNumberField.tsx +55 -0
  10. package/src/components/Content/Structure/passwordField/usePasswordField.tsx +57 -0
  11. package/src/components/Content/Structure/phoneNumber/usePhoneNumber.tsx +0 -0
  12. package/src/components/Content/Structure/qrcode/useQRCode.tsx +69 -0
  13. package/src/components/Content/Structure/searchbar/useSearchbar.tsx +55 -0
  14. package/src/components/Content/Structure/textfield/useTextField.tsx +84 -0
  15. package/src/components/Content/index.tsx +44 -7
  16. package/src/components/DateField/index.tsx +112 -0
  17. package/src/components/Dropdown/index.tsx +91 -0
  18. package/src/components/Form/Popup/index.tsx +1 -1
  19. package/src/components/IncrementNumberField/index.tsx +123 -0
  20. package/src/components/Nav/HorizontalVariant/index.tsx +18 -12
  21. package/src/components/Nav/VerticalVariant/index.tsx +14 -10
  22. package/src/components/NumberField/index.tsx +95 -0
  23. package/src/components/PasswordField/index.tsx +105 -0
  24. package/src/components/PhoneNumberField/index.tsx +102 -0
  25. package/src/components/PricingTable/index.tsx +10 -8
  26. package/src/components/QRCode/index.tsx +105 -0
  27. package/src/components/Searchbar/index.tsx +77 -0
  28. package/src/components/TextField/index.tsx +130 -0
  29. package/src/components/Toolbar/index.tsx +11 -10
  30. package/src/index.ts +54 -9
  31. package/src/components/Button/hook/useHelperFooter.tsx +0 -214
  32. package/src/components/Content/Structure/styledcomponent/useStyledComponent.tsx +0 -104
  33. package/src/components/StyledComponent/adornment/index.tsx +0 -125
  34. package/src/components/StyledComponent/hooks/useDropdown.tsx +0 -150
  35. package/src/components/StyledComponent/hooks/useInputHelperFooter.tsx +0 -524
  36. package/src/components/StyledComponent/hooks/usePhoneNumber.tsx +0 -99
  37. package/src/components/StyledComponent/hooks/useRequiredFieldsValidator.tsx +0 -190
  38. package/src/components/StyledComponent/hooks/useSearchbar.tsx +0 -46
  39. package/src/components/StyledComponent/hooks/useSplitButton.tsx +0 -70
  40. package/src/components/StyledComponent/index.tsx +0 -473
  41. package/src/components/StyledComponent/useCallbacks/index.tsx +0 -46
  42. package/src/styles/StyledComponent/Label/index.ts +0 -76
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "goobs-frontend",
3
- "version": "0.7.67",
3
+ "version": "0.7.69",
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",
@@ -17,31 +17,29 @@
17
17
  "start": "next start",
18
18
  "lint": "next lint"
19
19
  },
20
- "peerDependencies": {
21
- "react": "^17.0.0 || ^18.0.0",
22
- "react-dom": "^17.0.0 || ^18.0.0"
23
- },
24
20
  "dependencies": {
25
21
  "@emotion/cache": "^11.13.1",
26
- "@emotion/react": "^11.13.0",
22
+ "@emotion/react": "^11.13.3",
27
23
  "@emotion/styled": "^11.13.0",
28
- "@mui/icons-material": "^5.16.6",
29
- "@mui/material": "^5.16.6",
24
+ "@mui/icons-material": "^5.16.7",
25
+ "@mui/material": "^5.16.7",
30
26
  "@types/lodash": "^4.17.7",
31
- "goobs-cache": "^1.7.0",
32
27
  "highlight.js": "^11.10.0",
28
+ "jotai": "^2.9.3",
33
29
  "lodash": "^4.17.21",
34
- "next": "14.2.5"
30
+ "next": "14.2.6",
31
+ "react-datepicker": "^7.3.0",
32
+ "react-qr-code": "^2.0.15"
35
33
  },
36
34
  "devDependencies": {
37
- "@next/eslint-plugin-next": "^14.2.5",
38
- "@types/node": "^22.1.0",
39
- "@types/react": "18.3.3",
35
+ "@next/eslint-plugin-next": "^14.2.6",
36
+ "@types/node": "^22.5.0",
37
+ "@types/react": "18.3.4",
40
38
  "@types/react-dom": "^18.3.0",
41
- "@typescript-eslint/eslint-plugin": "^8.0.1",
42
- "@typescript-eslint/parser": "^8.0.1",
39
+ "@typescript-eslint/eslint-plugin": "^8.2.0",
40
+ "@typescript-eslint/parser": "^8.2.0",
43
41
  "eslint": "^8.57.0",
44
- "eslint-config-next": "^14.2.5",
42
+ "eslint-config-next": "^14.2.6",
45
43
  "eslint-config-prettier": "^9.1.0",
46
44
  "eslint-plugin-prettier": "^5.2.1",
47
45
  "prettier": "^3.3.3",
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
@@ -1,213 +1,99 @@
1
- import React, { useMemo, useCallback, useState } from 'react'
1
+ 'use client'
2
+ import React from 'react'
2
3
  import { Button, Box, ButtonProps } from '@mui/material'
3
- import StarIcon from '@mui/icons-material/Star'
4
4
  import Typography from '../Typography'
5
- import { red } from '../../styles/palette'
6
- import useHelperFooter from './hook/useHelperFooter'
7
5
 
8
- export type ButtonAlignment = 'left' | 'center' | 'right'
9
-
10
- export interface CustomButtonProps
11
- extends Omit<ButtonProps, 'color' | 'variant'> {
6
+ export interface CustomButtonProps extends ButtonProps {
12
7
  text?: string
13
8
  backgroundcolor?: string
14
- outlinecolor?: string
15
9
  fontcolor?: string
16
- fontlocation?: ButtonAlignment
17
- fontvariant?:
18
- | 'arapeyh1'
19
- | 'arapeyh2'
20
- | 'arapeyh3'
21
- | 'arapeyh4'
22
- | 'arapeyh5'
23
- | 'arapeyh6'
24
- | 'arapeyparagraph'
25
- | 'arapeyhelperheader'
26
- | 'arapeyhelperfooter'
27
- | 'interh1'
28
- | 'interh2'
29
- | 'interh3'
30
- | 'interh4'
31
- | 'interh5'
32
- | 'interh6'
33
- | 'interparagraph'
34
- | 'interhelperheader'
35
- | 'interhelperfooter'
36
- | 'merrih1'
37
- | 'merrih2'
38
- | 'merrih3'
39
- | 'merrih4'
40
- | 'merrih5'
41
- | 'merrih6'
42
- | 'merriparagraph'
43
- | 'merrihelperheader'
44
- | 'merrihelperfooter'
45
- icon?: React.ReactNode | false
10
+ fontvariant?: 'merriparagraph' | 'merrihelperfooter'
11
+ width?: string
12
+ disableButton?: 'true' | 'false'
13
+ icon?: React.ReactNode
46
14
  iconcolor?: string
47
15
  iconsize?: string
48
- iconlocation?: 'left' | 'top' | 'right'
49
- variant?: 'text' | 'outlined' | 'contained'
50
- onClick?: () => void
51
- width?: string
52
- formname?: string
53
- name?: string
16
+ iconlocation?: 'left' | 'right' | 'above'
17
+ fontlocation?: 'left' | 'center' | 'right'
54
18
  }
55
19
 
56
20
  const CustomButton: React.FC<CustomButtonProps> = React.memo(
57
21
  props => {
22
+ console.log('[trace-button] CustomButton: Rendering component', { props })
58
23
  const {
59
24
  text,
60
25
  variant,
61
26
  fontvariant = 'merriparagraph',
62
- icon,
63
- iconlocation,
64
- iconsize,
65
- type,
66
27
  onClick,
67
28
  fontcolor,
68
- name,
69
- formname,
70
- outlinecolor,
71
29
  backgroundcolor,
72
- fontlocation,
73
- iconcolor,
74
30
  width,
31
+ disableButton,
32
+ icon,
33
+ iconcolor,
34
+ iconsize,
35
+ iconlocation = 'left',
36
+ fontlocation = 'center',
37
+ ...restProps
75
38
  } = props
76
39
 
77
- const {
78
- updateFormValidation,
79
- checkFormStatus,
80
- getEmptyRequiredFields,
81
- fetchHelperFooters,
82
- } = useHelperFooter(formname)
83
-
84
- const [isFormFinished, setIsFormFinished] = useState(false)
85
- const [isCheckingForm, setIsCheckingForm] = useState(true)
86
-
87
- const checkFormState = useCallback(async (): Promise<void> => {
88
- console.log('CustomButton: Checking form state...')
89
- setIsCheckingForm(true)
90
-
91
- const formStatus = await checkFormStatus()
92
- const emptyFields = await getEmptyRequiredFields()
93
- const helperFooters = await fetchHelperFooters()
94
-
95
- console.log('CustomButton: Form status:', formStatus)
96
- console.log('CustomButton: Empty fields:', emptyFields)
97
- console.log('CustomButton: Helper footers:', helperFooters)
98
-
99
- const newIsFormFinished =
100
- formStatus &&
101
- emptyFields.length === 0 &&
102
- (!helperFooters || Object.keys(helperFooters).length === 0)
103
-
104
- setIsFormFinished(newIsFormFinished)
105
- setIsCheckingForm(false)
106
-
107
- console.log(
108
- 'CustomButton: Form status changed. Is form finished:',
109
- newIsFormFinished
110
- )
111
- }, [checkFormStatus, getEmptyRequiredFields, fetchHelperFooters])
112
-
113
- const handleButtonClick = useCallback(
114
- async (event: React.MouseEvent<HTMLButtonElement>): Promise<void> => {
115
- event.preventDefault()
116
- console.log(
117
- 'CustomButton: Button clicked. Is form finished:',
118
- isFormFinished,
119
- 'Is checking form:',
120
- isCheckingForm
121
- )
122
- if (!isFormFinished || isCheckingForm) return
123
-
124
- const validationResult = await updateFormValidation()
125
- console.log('CustomButton: Validation result:', validationResult)
126
- if (validationResult && onClick) {
127
- onClick()
128
- }
129
- checkFormState()
130
- },
131
- [
132
- isFormFinished,
133
- isCheckingForm,
134
- updateFormValidation,
135
- onClick,
136
- checkFormState,
137
- ]
138
- )
139
-
140
- const renderIcon = useCallback((): React.ReactNode => {
141
- if (icon === false) {
142
- return null
143
- }
144
- if (React.isValidElement(icon)) {
145
- return React.cloneElement(icon as React.ReactElement, {
146
- style: { fontSize: iconsize },
40
+ const handleButtonClick = (
41
+ event: React.MouseEvent<HTMLButtonElement>
42
+ ): void => {
43
+ console.log('[trace-button] CustomButton: Button clicked')
44
+ event.preventDefault()
45
+ onClick?.(event)
46
+ }
47
+
48
+ const buttonStyle = {
49
+ backgroundColor: backgroundcolor,
50
+ width: width,
51
+ }
52
+
53
+ const isDisabled = disableButton === 'true'
54
+
55
+ const iconStyle = {
56
+ color: iconcolor,
57
+ fontSize: iconsize,
58
+ }
59
+
60
+ const IconComponent = icon
61
+ ? React.cloneElement(icon as React.ReactElement, {
62
+ style: { ...iconStyle, ...(icon as React.ReactElement).props.style },
147
63
  })
148
- }
149
- return <StarIcon style={{ fontSize: iconsize }} />
150
- }, [icon, iconsize])
151
-
152
- const buttonStyle = useMemo(
153
- () => ({
154
- minWidth: text ? 'auto' : 'fit-content',
155
- paddingLeft: text ? '8px' : '0',
156
- paddingRight: text ? '8px' : '0',
157
- justifyContent: fontlocation || 'center',
158
- backgroundColor: backgroundcolor,
159
- border: outlinecolor ? `1px solid ${outlinecolor}` : undefined,
160
- color: iconcolor,
161
- width: width,
162
- opacity: !isFormFinished || isCheckingForm ? 0.5 : 1,
163
- }),
164
- [
165
- text,
166
- fontlocation,
167
- backgroundcolor,
168
- outlinecolor,
169
- iconcolor,
170
- width,
171
- isFormFinished,
172
- isCheckingForm,
173
- ]
174
- )
175
-
176
- const buttonContent = useMemo(
177
- () => (
178
- <Box display="flex" alignItems="center">
179
- {iconlocation === 'left' && renderIcon()}
180
- {text && (
181
- <Typography
182
- fontvariant={fontvariant}
183
- fontcolor={fontcolor}
184
- text={text}
185
- />
186
- )}
187
- {iconlocation === 'right' && renderIcon()}
188
- </Box>
189
- ),
190
- [iconlocation, renderIcon, text, fontvariant, fontcolor]
191
- )
64
+ : null
192
65
 
193
- const messageComponent = useMemo(
194
- () =>
195
- !isFormFinished || isCheckingForm ? (
66
+ console.log('[trace-button] CustomButton: Rendering button', {
67
+ variant,
68
+ style: buttonStyle,
69
+ disableButton,
70
+ isDisabled,
71
+ })
72
+
73
+ const buttonContent = (
74
+ <>
75
+ {iconlocation === 'above' && IconComponent}
76
+ <Box
77
+ display="flex"
78
+ alignItems="center"
79
+ justifyContent={
80
+ fontlocation === 'left'
81
+ ? 'flex-start'
82
+ : fontlocation === 'right'
83
+ ? 'flex-end'
84
+ : 'center'
85
+ }
86
+ width="100%"
87
+ >
88
+ {iconlocation === 'left' && IconComponent}
196
89
  <Typography
197
- fontvariant="merrihelperfooter"
198
- fontcolor={red.main}
199
- text="Fill in required fields"
200
- marginTop={0.5}
201
- marginBottom={0}
202
- align="center"
203
- width="100%"
90
+ fontvariant={fontvariant}
91
+ fontcolor={isDisabled ? 'grey' : fontcolor}
92
+ text={text || ''}
204
93
  />
205
- ) : null,
206
- [isFormFinished, isCheckingForm]
207
- )
208
-
209
- console.log(
210
- `CustomButton: Rendering. Is form finished: ${isFormFinished} Is checking form: ${isCheckingForm}`
94
+ {iconlocation === 'right' && IconComponent}
95
+ </Box>
96
+ </>
211
97
  )
212
98
 
213
99
  return (
@@ -218,19 +104,23 @@ const CustomButton: React.FC<CustomButtonProps> = React.memo(
218
104
  width={width}
219
105
  >
220
106
  <Button
221
- disableElevation
107
+ {...restProps}
222
108
  variant={variant}
223
- startIcon={null}
224
- endIcon={null}
225
- type={type}
226
- name={name}
227
109
  onClick={handleButtonClick}
228
- style={buttonStyle}
229
- disabled={!isFormFinished || isCheckingForm}
110
+ style={{
111
+ ...buttonStyle,
112
+ flexDirection: iconlocation === 'above' ? 'column' : 'row',
113
+ justifyContent:
114
+ fontlocation === 'left'
115
+ ? 'flex-start'
116
+ : fontlocation === 'right'
117
+ ? 'flex-end'
118
+ : 'center',
119
+ }}
120
+ disabled={isDisabled}
230
121
  >
231
122
  {buttonContent}
232
123
  </Button>
233
- {messageComponent}
234
124
  </Box>
235
125
  )
236
126
  },
@@ -239,24 +129,26 @@ const CustomButton: React.FC<CustomButtonProps> = React.memo(
239
129
  prevProps.text === nextProps.text &&
240
130
  prevProps.variant === nextProps.variant &&
241
131
  prevProps.fontvariant === nextProps.fontvariant &&
242
- prevProps.icon === nextProps.icon &&
243
- prevProps.iconlocation === nextProps.iconlocation &&
244
- prevProps.iconsize === nextProps.iconsize &&
245
- prevProps.type === nextProps.type &&
246
132
  prevProps.onClick === nextProps.onClick &&
247
133
  prevProps.fontcolor === nextProps.fontcolor &&
248
- prevProps.name === nextProps.name &&
249
- prevProps.formname === nextProps.formname &&
250
- prevProps.outlinecolor === nextProps.outlinecolor &&
251
134
  prevProps.backgroundcolor === nextProps.backgroundcolor &&
252
- prevProps.fontlocation === nextProps.fontlocation &&
135
+ prevProps.width === nextProps.width &&
136
+ prevProps.disableButton === nextProps.disableButton &&
137
+ prevProps.icon === nextProps.icon &&
253
138
  prevProps.iconcolor === nextProps.iconcolor &&
254
- prevProps.width === nextProps.width
255
- console.log('CustomButton: Props changed:', !propsAreEqual)
139
+ prevProps.iconsize === nextProps.iconsize &&
140
+ prevProps.iconlocation === nextProps.iconlocation &&
141
+ prevProps.fontlocation === nextProps.fontlocation
142
+
143
+ console.log('[trace-button] CustomButton: Props comparison', {
144
+ propsAreEqual,
145
+ prevProps: Object.keys(prevProps),
146
+ nextProps: Object.keys(nextProps),
147
+ })
256
148
  return propsAreEqual
257
149
  }
258
150
  )
259
151
 
260
152
  CustomButton.displayName = 'CustomButton'
261
-
153
+ console.log('[trace-button] CustomButton: Component defined')
262
154
  export default CustomButton
@@ -1,10 +1,9 @@
1
1
  'use client'
2
- import React, { ChangeEvent, KeyboardEvent } from 'react'
2
+ import React, { ChangeEvent, KeyboardEvent, useState } from 'react'
3
3
  import { Input, Box } from '@mui/material'
4
4
  import { useCodeConfirmation } from './utils/useCodeConfirmation'
5
5
  import { columnconfig } from '../../components/Grid'
6
6
  import { red, green } from '../../styles/palette'
7
- import { session } from 'goobs-cache'
8
7
 
9
8
  export interface ConfirmationCodeInputsProps {
10
9
  identifier?: string
@@ -30,8 +29,7 @@ const ConfirmationCodeInputs: React.FC<ConfirmationCodeInputsProps> = ({
30
29
  'aria-invalid': ariaInvalid,
31
30
  ...props
32
31
  }) => {
33
- const verificationCodeAtom = session.atom<string>('')
34
- const [, setVerificationCode] = session.useAtom(verificationCodeAtom)
32
+ const [, setVerificationCode] = useState('')
35
33
 
36
34
  const { handleCodeChange, handleKeyDown, combinedCode } = useCodeConfirmation(
37
35
  {
@@ -76,14 +74,14 @@ const ConfirmationCodeInputs: React.FC<ConfirmationCodeInputsProps> = ({
76
74
  }
77
75
 
78
76
  /**
79
- * useEffect hook is used to set the verification code into the session atom using goobs-cache.
77
+ * useEffect hook is used to set the verification code into the state using useState.
80
78
  * It sets the code whenever the combinedCode changes and the code is valid.
81
79
  */
82
80
  React.useEffect(() => {
83
81
  if (isValid) {
84
82
  setVerificationCode(combinedCode)
85
83
  }
86
- }, [combinedCode, isValid, setVerificationCode])
84
+ }, [combinedCode, isValid])
87
85
 
88
86
  return (
89
87
  <Box
@@ -2,7 +2,6 @@
2
2
  import React from 'react'
3
3
  import CustomButton, { CustomButtonProps } from './../../../Button'
4
4
  import { columnconfig, cellconfig } from '../../../Grid'
5
- import { TypographyPropsVariantOverrides } from '@mui/material'
6
5
 
7
6
  export interface ExtendedButtonProps extends CustomButtonProps {
8
7
  columnconfig?: Partial<columnconfig>
@@ -19,20 +18,6 @@ const useButton = (grid: {
19
18
  index: number
20
19
  ): columnconfig => {
21
20
  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
21
  columnconfig: itemColumnConfig,
37
22
  cellconfig,
38
23
  ...restProps
@@ -54,26 +39,7 @@ const useButton = (grid: {
54
39
  cellconfig: {
55
40
  ...cellconfig,
56
41
  },
57
- component: (
58
- <CustomButton
59
- key={`button-${index}`}
60
- text={text}
61
- name={name}
62
- backgroundcolor={backgroundcolor}
63
- outlinecolor={outlinecolor}
64
- fontcolor={fontcolor}
65
- width={width}
66
- fontlocation={fontlocation}
67
- fontvariant={fontvariant as keyof TypographyPropsVariantOverrides}
68
- icon={icon}
69
- iconcolor={iconcolor}
70
- iconsize={iconsize}
71
- iconlocation={iconlocation}
72
- variant={variant}
73
- onClick={onClick}
74
- {...restProps}
75
- />
76
- ),
42
+ component: <CustomButton key={`button-${index}`} {...restProps} />,
77
43
  }
78
44
 
79
45
  return mergedConfig
@@ -0,0 +1,55 @@
1
+ 'use client'
2
+ import React from 'react'
3
+ import DateField, { DateFieldProps } from './../../../DateField'
4
+ import { columnconfig, cellconfig } from '../../../Grid'
5
+
6
+ export interface ExtendedDateFieldProps extends DateFieldProps {
7
+ columnconfig?: Partial<columnconfig>
8
+ cellconfig?: cellconfig
9
+ }
10
+
11
+ const useDateField = (grid: {
12
+ datefield?: ExtendedDateFieldProps | ExtendedDateFieldProps[]
13
+ }) => {
14
+ if (!grid.datefield) return null
15
+
16
+ const renderDateField = (
17
+ dateFieldItem: ExtendedDateFieldProps,
18
+ index: number
19
+ ): columnconfig => {
20
+ const {
21
+ columnconfig: itemColumnConfig,
22
+ cellconfig,
23
+ ...restProps
24
+ } = dateFieldItem
25
+
26
+ if (
27
+ !itemColumnConfig ||
28
+ typeof itemColumnConfig !== 'object' ||
29
+ typeof itemColumnConfig.row !== 'number' ||
30
+ typeof itemColumnConfig.column !== 'number'
31
+ ) {
32
+ throw new Error(
33
+ 'columnconfig must be an object with row and column as numbers'
34
+ )
35
+ }
36
+
37
+ const mergedConfig: columnconfig = {
38
+ ...(itemColumnConfig as columnconfig),
39
+ cellconfig: {
40
+ ...cellconfig,
41
+ },
42
+ component: <DateField key={`datefield-${index}`} {...restProps} />,
43
+ }
44
+
45
+ return mergedConfig
46
+ }
47
+
48
+ if (Array.isArray(grid.datefield)) {
49
+ return grid.datefield.map(renderDateField)
50
+ } else {
51
+ return [renderDateField(grid.datefield, 0)]
52
+ }
53
+ }
54
+
55
+ export default useDateField
@@ -0,0 +1,55 @@
1
+ 'use client'
2
+ import React from 'react'
3
+ import Dropdown, { DropdownProps } from './../../../Dropdown'
4
+ import { columnconfig, cellconfig } from '../../../Grid'
5
+
6
+ export interface ExtendedDropdownProps extends DropdownProps {
7
+ columnconfig?: Partial<columnconfig>
8
+ cellconfig?: cellconfig
9
+ }
10
+
11
+ const useDropdown = (grid: {
12
+ dropdown?: ExtendedDropdownProps | ExtendedDropdownProps[]
13
+ }) => {
14
+ if (!grid.dropdown) return null
15
+
16
+ const renderDropdown = (
17
+ dropdownItem: ExtendedDropdownProps,
18
+ index: number
19
+ ): columnconfig => {
20
+ const {
21
+ columnconfig: itemColumnConfig,
22
+ cellconfig,
23
+ ...restProps
24
+ } = dropdownItem
25
+
26
+ if (
27
+ !itemColumnConfig ||
28
+ typeof itemColumnConfig !== 'object' ||
29
+ typeof itemColumnConfig.row !== 'number' ||
30
+ typeof itemColumnConfig.column !== 'number'
31
+ ) {
32
+ throw new Error(
33
+ 'columnconfig must be an object with row and column as numbers'
34
+ )
35
+ }
36
+
37
+ const mergedConfig: columnconfig = {
38
+ ...(itemColumnConfig as columnconfig),
39
+ cellconfig: {
40
+ ...cellconfig,
41
+ },
42
+ component: <Dropdown key={`dropdown-${index}`} {...restProps} />,
43
+ }
44
+
45
+ return mergedConfig
46
+ }
47
+
48
+ if (Array.isArray(grid.dropdown)) {
49
+ return grid.dropdown.map(renderDropdown)
50
+ } else {
51
+ return [renderDropdown(grid.dropdown, 0)]
52
+ }
53
+ }
54
+
55
+ export default useDropdown