goobs-frontend 0.8.7 → 0.8.9

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 (27) hide show
  1. package/package.json +15 -15
  2. package/src/components/Button/index.tsx +91 -109
  3. package/src/components/Checkbox/index.tsx +79 -0
  4. package/src/components/ConfirmationCodeInput/index.tsx +120 -46
  5. package/src/components/Content/Structure/checkbox/useCheckbox.tsx +65 -0
  6. package/src/components/Content/Structure/typography/useGridTypography.tsx +2 -0
  7. package/src/components/Content/index.tsx +5 -0
  8. package/src/components/DataGrid/Footer/index.tsx +169 -0
  9. package/src/components/DataGrid/Jotai/atom.ts +91 -0
  10. package/src/components/DataGrid/ManageColumn/index.tsx +211 -0
  11. package/src/components/DataGrid/ManageRow/index.tsx +348 -0
  12. package/src/components/DataGrid/Table/index.tsx +275 -0
  13. package/src/components/DataGrid/VerticalDivider/index.tsx +6 -0
  14. package/src/components/DataGrid/index.tsx +296 -0
  15. package/src/components/DataGrid/utils/useManageColumn.tsx +138 -0
  16. package/src/components/DataGrid/utils/useSearchbar.tsx +122 -0
  17. package/src/components/Dropdown/index.tsx +63 -14
  18. package/src/components/Form/DataGrid/index.tsx +72 -0
  19. package/src/components/Form/Popup/index.tsx +30 -63
  20. package/src/components/Grid/index.tsx +83 -101
  21. package/src/components/Nav/VerticalVariant/index.tsx +14 -10
  22. package/src/components/Searchbar/index.tsx +98 -42
  23. package/src/components/TextField/index.tsx +0 -1
  24. package/src/components/Toolbar/index.tsx +37 -19
  25. package/src/components/Typography/index.tsx +8 -4
  26. package/src/index.ts +16 -1
  27. package/src/components/ConfirmationCodeInput/utils/useCodeConfirmation.tsx +0 -150
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "goobs-frontend",
3
- "version": "0.8.7",
3
+ "version": "0.8.9",
4
4
  "type": "module",
5
5
  "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.",
6
6
  "license": "MIT",
@@ -22,31 +22,31 @@
22
22
  "@emotion/cache": "^11.13.5",
23
23
  "@emotion/react": "^11.13.5",
24
24
  "@emotion/styled": "^11.13.5",
25
- "@mui/icons-material": "^6.1.8",
26
- "@mui/material": "^6.1.8",
25
+ "@mui/icons-material": "^6.1.10",
26
+ "@mui/material": "^6.1.10",
27
27
  "@types/lodash": "^4.17.13",
28
28
  "highlight.js": "^11.10.0",
29
29
  "jotai": "^2.10.3",
30
30
  "lodash": "^4.17.21",
31
- "next": "15.0.3",
31
+ "next": "15.0.4",
32
32
  "otplib": "^12.0.1",
33
33
  "react-datepicker": "^7.5.0",
34
34
  "react-qr-code": "^2.0.15"
35
35
  },
36
36
  "devDependencies": {
37
- "@next/eslint-plugin-next": "^15.0.3",
38
- "@types/node": "^22.10.0",
39
- "@types/react": "18.3.12",
40
- "@types/react-dom": "^18.3.1",
41
- "@typescript-eslint/eslint-plugin": "^8.16.0",
42
- "@typescript-eslint/parser": "^8.16.0",
43
- "eslint": "^9.15.0",
44
- "eslint-config-next": "^15.0.3",
37
+ "@next/eslint-plugin-next": "^15.0.4",
38
+ "@types/node": "^22.10.1",
39
+ "@types/react": "19.0.1",
40
+ "@types/react-dom": "^19.0.1",
41
+ "@typescript-eslint/eslint-plugin": "^8.17.0",
42
+ "@typescript-eslint/parser": "^8.17.0",
43
+ "eslint": "^9.16.0",
44
+ "eslint-config-next": "^15.0.4",
45
45
  "eslint-config-prettier": "^9.1.0",
46
46
  "eslint-plugin-prettier": "^5.2.1",
47
- "prettier": "^3.4.1",
48
- "react": "^18.3.1",
49
- "react-dom": "^18.3.1",
47
+ "prettier": "^3.4.2",
48
+ "react": "^19.0.0",
49
+ "react-dom": "^19.0.0",
50
50
  "typescript": "^5.7.2"
51
51
  },
52
52
  "files": [
@@ -1,7 +1,8 @@
1
1
  'use client'
2
2
  import React from 'react'
3
- import { Button, Box, ButtonProps } from '@mui/material'
3
+ import { Button, Box, ButtonProps, SxProps, Theme } from '@mui/material'
4
4
  import Typography from '../Typography'
5
+ import { SvgIconProps } from '@mui/material/SvgIcon'
5
6
 
6
7
  export interface CustomButtonProps extends ButtonProps {
7
8
  text?: string
@@ -9,131 +10,112 @@ export interface CustomButtonProps extends ButtonProps {
9
10
  fontcolor?: string
10
11
  fontvariant?: 'merriparagraph' | 'merrihelperfooter'
11
12
  width?: string
13
+ height?: string
12
14
  disableButton?: 'true' | 'false'
13
- icon?: React.ReactNode
15
+ icon?: React.ReactElement<SvgIconProps>
14
16
  iconcolor?: string
15
17
  iconsize?: string
16
18
  iconlocation?: 'left' | 'right' | 'above'
17
19
  fontlocation?: 'left' | 'center' | 'right'
18
20
  }
19
21
 
20
- const CustomButton: React.FC<CustomButtonProps> = React.memo(
21
- props => {
22
- const {
23
- text,
24
- variant,
25
- fontvariant = 'merriparagraph',
26
- onClick,
27
- fontcolor,
28
- backgroundcolor,
29
- width,
30
- disableButton,
31
- icon,
32
- iconcolor,
33
- iconsize,
34
- iconlocation = 'left',
35
- fontlocation = 'center',
36
- ...restProps
37
- } = props
38
-
39
- const handleButtonClick = (
40
- event: React.MouseEvent<HTMLButtonElement>
41
- ): void => {
42
- event.preventDefault()
43
- onClick?.(event)
44
- }
45
-
46
- const buttonStyle = {
47
- backgroundColor: backgroundcolor,
48
- width: width,
49
- }
50
-
51
- const isDisabled = disableButton === 'true'
22
+ const CustomButton: React.FC<CustomButtonProps> = ({
23
+ text,
24
+ variant,
25
+ fontvariant = 'merriparagraph',
26
+ onClick,
27
+ fontcolor,
28
+ backgroundcolor,
29
+ width,
30
+ height,
31
+ disableButton,
32
+ icon,
33
+ iconcolor,
34
+ iconsize,
35
+ iconlocation = 'left',
36
+ fontlocation = 'center',
37
+ sx,
38
+ ...restProps
39
+ }) => {
40
+ const handleButtonClick = (
41
+ event: React.MouseEvent<HTMLButtonElement>
42
+ ): void => {
43
+ event.preventDefault()
44
+ onClick?.(event)
45
+ }
52
46
 
53
- const iconStyle = {
54
- color: iconcolor,
55
- fontSize: iconsize,
56
- }
47
+ const buttonSx: SxProps<Theme> = {
48
+ ...(backgroundcolor && { backgroundColor: backgroundcolor }),
49
+ ...(width && { width }),
50
+ ...(height && { height }),
51
+ flexDirection: iconlocation === 'above' ? 'column' : 'row',
52
+ justifyContent:
53
+ fontlocation === 'left'
54
+ ? 'flex-start'
55
+ : fontlocation === 'right'
56
+ ? 'flex-end'
57
+ : 'center',
58
+ ...(sx as object),
59
+ }
57
60
 
58
- const IconComponent = icon
59
- ? React.cloneElement(icon as React.ReactElement, {
60
- style: { ...iconStyle, ...(icon as React.ReactElement).props.style },
61
- })
62
- : null
61
+ const isDisabled = disableButton === 'true'
63
62
 
64
- const buttonContent = (
65
- <>
66
- {iconlocation === 'above' && IconComponent}
67
- <Box
68
- display="flex"
69
- alignItems="center"
70
- justifyContent={
71
- fontlocation === 'left'
72
- ? 'flex-start'
73
- : fontlocation === 'right'
74
- ? 'flex-end'
75
- : 'center'
76
- }
77
- width="100%"
78
- >
79
- {iconlocation === 'left' && IconComponent}
80
- <Typography
81
- fontvariant={fontvariant}
82
- fontcolor={isDisabled ? 'grey' : fontcolor}
83
- text={text || ''}
84
- />
85
- {iconlocation === 'right' && IconComponent}
86
- </Box>
87
- </>
88
- )
63
+ const IconComponent = icon
64
+ ? React.cloneElement(icon, {
65
+ sx: {
66
+ color: iconcolor,
67
+ fontSize: iconsize,
68
+ },
69
+ } as Partial<SvgIconProps>)
70
+ : null
89
71
 
90
- return (
72
+ const buttonContent = (
73
+ <>
74
+ {iconlocation === 'above' && IconComponent}
91
75
  <Box
92
76
  display="flex"
93
- flexDirection="column"
94
77
  alignItems="center"
95
- width={width}
78
+ justifyContent={
79
+ fontlocation === 'left'
80
+ ? 'flex-start'
81
+ : fontlocation === 'right'
82
+ ? 'flex-end'
83
+ : 'center'
84
+ }
85
+ width="100%"
86
+ height="100%"
96
87
  >
97
- <Button
98
- {...restProps}
99
- variant={variant}
100
- onClick={handleButtonClick}
101
- style={{
102
- ...buttonStyle,
103
- flexDirection: iconlocation === 'above' ? 'column' : 'row',
104
- justifyContent:
105
- fontlocation === 'left'
106
- ? 'flex-start'
107
- : fontlocation === 'right'
108
- ? 'flex-end'
109
- : 'center',
110
- }}
111
- disabled={isDisabled}
112
- >
113
- {buttonContent}
114
- </Button>
88
+ {iconlocation === 'left' && IconComponent}
89
+ <Typography
90
+ fontvariant={fontvariant}
91
+ fontcolor={isDisabled ? 'grey' : fontcolor}
92
+ text={text || ''}
93
+ />
94
+ {iconlocation === 'right' && IconComponent}
115
95
  </Box>
116
- )
117
- },
118
- (prevProps, nextProps) => {
119
- const propsAreEqual =
120
- prevProps.text === nextProps.text &&
121
- prevProps.variant === nextProps.variant &&
122
- prevProps.fontvariant === nextProps.fontvariant &&
123
- prevProps.onClick === nextProps.onClick &&
124
- prevProps.fontcolor === nextProps.fontcolor &&
125
- prevProps.backgroundcolor === nextProps.backgroundcolor &&
126
- prevProps.width === nextProps.width &&
127
- prevProps.disableButton === nextProps.disableButton &&
128
- prevProps.icon === nextProps.icon &&
129
- prevProps.iconcolor === nextProps.iconcolor &&
130
- prevProps.iconsize === nextProps.iconsize &&
131
- prevProps.iconlocation === nextProps.iconlocation &&
132
- prevProps.fontlocation === nextProps.fontlocation
96
+ </>
97
+ )
133
98
 
134
- return propsAreEqual
135
- }
136
- )
99
+ return (
100
+ <Box
101
+ display="flex"
102
+ flexDirection="column"
103
+ alignItems="center"
104
+ width={width}
105
+ height={height}
106
+ >
107
+ <Button
108
+ {...restProps}
109
+ variant={variant}
110
+ onClick={handleButtonClick}
111
+ sx={buttonSx}
112
+ disabled={isDisabled}
113
+ >
114
+ {buttonContent}
115
+ </Button>
116
+ </Box>
117
+ )
118
+ }
137
119
 
138
120
  CustomButton.displayName = 'CustomButton'
139
121
  export default CustomButton
@@ -0,0 +1,79 @@
1
+ 'use client'
2
+
3
+ import { Checkbox } from '@mui/material'
4
+ import React from 'react'
5
+ import * as palette from '../../styles/palette'
6
+
7
+ interface DataGridCheckboxProps {
8
+ onClick?: (event: React.MouseEvent) => void
9
+ checked?: boolean
10
+ indeterminate?: boolean
11
+ onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void
12
+ disabled?: boolean
13
+ }
14
+
15
+ function DataGridCheckbox({
16
+ onClick,
17
+ checked,
18
+ indeterminate,
19
+ onChange,
20
+ disabled,
21
+ ...props
22
+ }: DataGridCheckboxProps) {
23
+ console.log('DataGridCheckbox render:', { checked, indeterminate, disabled })
24
+
25
+ const handleClick = (event: React.MouseEvent) => {
26
+ console.log('Checkbox clicked:', {
27
+ checked,
28
+ indeterminate,
29
+ eventTarget: event.target,
30
+ })
31
+
32
+ if (onClick) {
33
+ onClick(event)
34
+ }
35
+ }
36
+
37
+ const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
38
+ event.stopPropagation()
39
+
40
+ console.log('Checkbox changed:', {
41
+ newChecked: event.target.checked,
42
+ previousChecked: checked,
43
+ indeterminate,
44
+ })
45
+
46
+ if (onChange) {
47
+ onChange(event)
48
+ }
49
+ }
50
+
51
+ return (
52
+ <Checkbox
53
+ sx={{
54
+ color: palette.marine.main,
55
+ '&.Mui-checked': {
56
+ color: palette.marine.main,
57
+ },
58
+ '&.Mui-indeterminate': {
59
+ color: palette.marine.main,
60
+ },
61
+ '&.Mui-disabled': {
62
+ color: palette.greyborder.main,
63
+ },
64
+ '&:hover': {
65
+ backgroundColor: palette.marine.light,
66
+ opacity: 0.1,
67
+ },
68
+ }}
69
+ checked={checked}
70
+ indeterminate={indeterminate}
71
+ onClick={handleClick}
72
+ onChange={handleChange}
73
+ disabled={disabled}
74
+ {...props}
75
+ />
76
+ )
77
+ }
78
+
79
+ export default DataGridCheckbox
@@ -1,8 +1,7 @@
1
1
  'use client'
2
- import React, { ChangeEvent, KeyboardEvent, useState } from 'react'
2
+ import React, { ChangeEvent, KeyboardEvent, useState, useCallback } from 'react'
3
3
  import { Input, Box } from '@mui/material'
4
- import { useCodeConfirmation } from './utils/useCodeConfirmation'
5
- import { columnconfig } from '../../components/Grid'
4
+ import { columnconfig } from '../Grid'
6
5
  import { red, green } from '../../styles/palette'
7
6
 
8
7
  export interface ConfirmationCodeInputsProps {
@@ -13,59 +12,138 @@ export interface ConfirmationCodeInputsProps {
13
12
  'aria-label'?: string
14
13
  'aria-required'?: boolean
15
14
  'aria-invalid'?: boolean
15
+ onChange?: (value: string) => void
16
+ value?: string
17
+ }
18
+
19
+ interface UseCodeConfirmationProps {
20
+ codeLength: number
21
+ onChange?: (value: string) => void
22
+ }
23
+
24
+ const useCodeConfirmation = ({
25
+ codeLength,
26
+ onChange,
27
+ }: UseCodeConfirmationProps) => {
28
+ const [code, setCode] = useState<Record<string, string>>(
29
+ Object.fromEntries(
30
+ Array.from({ length: codeLength }, (_, i) => [`code${i + 1}`, ''])
31
+ )
32
+ )
33
+
34
+ const handleCodeChange = useCallback(
35
+ (event: React.ChangeEvent<HTMLInputElement>, index: number) => {
36
+ const value = event.target.value.replace(/\D/g, '') // Only keep digits
37
+ if (value.length <= 1) {
38
+ // Only process if it's a single digit or empty
39
+ setCode(prevCode => {
40
+ const newCode = {
41
+ ...prevCode,
42
+ [`code${index + 1}`]: value,
43
+ }
44
+ const combinedValue = Object.values(newCode).join('')
45
+ onChange?.(combinedValue)
46
+ return newCode
47
+ })
48
+ }
49
+ },
50
+ [onChange]
51
+ )
52
+
53
+ const handleKeyDown = useCallback(
54
+ (event: React.KeyboardEvent<HTMLInputElement>, index: number) => {
55
+ // Allow only numeric keys, navigation keys, and backspace
56
+ const allowedKeys = [
57
+ 'Backspace',
58
+ 'ArrowLeft',
59
+ 'ArrowRight',
60
+ 'Tab',
61
+ 'Delete',
62
+ 'Home',
63
+ 'End',
64
+ ]
65
+
66
+ if (!allowedKeys.includes(event.key) && !/^\d$/.test(event.key)) {
67
+ event.preventDefault()
68
+ return
69
+ }
70
+
71
+ if (event.key === 'Backspace' && !code[`code${index + 1}`] && index > 0) {
72
+ setCode(prevCode => {
73
+ const newCode = {
74
+ ...prevCode,
75
+ [`code${index}`]: '',
76
+ }
77
+ const combinedValue = Object.values(newCode).join('')
78
+ onChange?.(combinedValue)
79
+ return newCode
80
+ })
81
+
82
+ const prevInput = document.querySelector(
83
+ `input[name=code${index}]`
84
+ ) as HTMLInputElement | null
85
+ if (prevInput) {
86
+ prevInput.focus()
87
+ }
88
+ } else if (event.key === 'ArrowLeft' && index > 0) {
89
+ const prevInput = document.querySelector(
90
+ `input[name=code${index}]`
91
+ ) as HTMLInputElement | null
92
+ if (prevInput) {
93
+ prevInput.focus()
94
+ }
95
+ } else if (event.key === 'ArrowRight' && index < codeLength - 1) {
96
+ const nextInput = document.querySelector(
97
+ `input[name=code${index + 2}]`
98
+ ) as HTMLInputElement | null
99
+ if (nextInput) {
100
+ nextInput.focus()
101
+ }
102
+ }
103
+ },
104
+ [code, codeLength, onChange]
105
+ )
106
+
107
+ return {
108
+ handleCodeChange,
109
+ handleKeyDown,
110
+ }
16
111
  }
17
112
 
18
- /**
19
- * ConfirmationCodeInputs component renders a set of input fields for entering a confirmation code.
20
- * It uses the useCodeConfirmation hook to handle code changes and key events.
21
- * @param props The props for the ConfirmationCodeInputs component.
22
- * @returns The rendered ConfirmationCodeInputs component.
23
- */
24
113
  const ConfirmationCodeInputs: React.FC<ConfirmationCodeInputsProps> = ({
25
114
  codeLength = 6,
26
115
  isValid,
116
+ onChange,
117
+ value,
27
118
  'aria-label': ariaLabel,
28
119
  'aria-required': ariaRequired,
29
120
  'aria-invalid': ariaInvalid,
30
121
  ...props
31
122
  }) => {
32
- const [, setVerificationCode] = useState('')
123
+ const { handleCodeChange, handleKeyDown } = useCodeConfirmation({
124
+ codeLength,
125
+ onChange,
126
+ })
33
127
 
34
- const { handleCodeChange, handleKeyDown, combinedCode } = useCodeConfirmation(
35
- {
36
- codeLength,
37
- isValid,
38
- }
39
- )
40
-
41
- /**
42
- * handleChange function is called when the value of an input field changes.
43
- * It updates the code state using the handleCodeChange function from the useCodeConfirmation hook.
44
- * If the input field has a value, it focuses on the next input field.
45
- * @param event The change event triggered by the input field.
46
- * @param index The index of the input field.
47
- */
48
128
  const handleChange = (
49
129
  event: ChangeEvent<HTMLInputElement>,
50
130
  index: number
51
131
  ) => {
52
- handleCodeChange(event, index)
53
- if (event.target.value) {
54
- const nextInput = document.querySelector(
55
- `input[name=code${index + 2}]`
56
- ) as HTMLInputElement | null
57
- if (nextInput) {
58
- nextInput.focus()
132
+ const inputValue = event.target.value.replace(/\D/g, '') // Only keep digits
133
+ if (inputValue.length <= 1) {
134
+ // Only process if it's a single digit or empty
135
+ handleCodeChange(event, index)
136
+ if (inputValue) {
137
+ const nextInput = document.querySelector(
138
+ `input[name=code${index + 2}]`
139
+ ) as HTMLInputElement | null
140
+ if (nextInput) {
141
+ nextInput.focus()
142
+ }
59
143
  }
60
144
  }
61
145
  }
62
146
 
63
- /**
64
- * handleKeyDownWrapper function is a wrapper for the handleKeyDown function from the useCodeConfirmation hook.
65
- * It is called when a key is pressed while an input field is focused.
66
- * @param event The keyboard event triggered by the input field.
67
- * @param index The index of the input field.
68
- */
69
147
  const handleKeyDownWrapper = (
70
148
  event: KeyboardEvent<HTMLInputElement>,
71
149
  index: number
@@ -73,15 +151,8 @@ const ConfirmationCodeInputs: React.FC<ConfirmationCodeInputsProps> = ({
73
151
  handleKeyDown(event, index)
74
152
  }
75
153
 
76
- /**
77
- * useEffect hook is used to set the verification code into the state using useState.
78
- * It sets the code whenever the combinedCode changes and the code is valid.
79
- */
80
- React.useEffect(() => {
81
- if (isValid) {
82
- setVerificationCode(combinedCode)
83
- }
84
- }, [combinedCode, isValid])
154
+ // Split the value into individual digits
155
+ const digits = value?.split('') || Array(codeLength).fill('')
85
156
 
86
157
  return (
87
158
  <Box
@@ -96,8 +167,11 @@ const ConfirmationCodeInputs: React.FC<ConfirmationCodeInputsProps> = ({
96
167
  <Input
97
168
  key={index}
98
169
  name={`code${index + 1}`}
170
+ value={digits[index] || ''}
99
171
  inputProps={{
100
172
  maxLength: 1,
173
+ pattern: '[0-9]*',
174
+ inputMode: 'numeric',
101
175
  'aria-label': `Code Digit ${index + 1}`,
102
176
  'aria-required': ariaRequired,
103
177
  'aria-invalid': ariaInvalid,
@@ -0,0 +1,65 @@
1
+ 'use client'
2
+ import React from 'react'
3
+ import { columnconfig, cellconfig } from '../../../Grid'
4
+ import DataGridCheckbox from './../../../../components/Checkbox'
5
+
6
+ type ExtendedColumnConfig = Omit<columnconfig, 'component'> & {
7
+ component?: columnconfig['component']
8
+ }
9
+
10
+ export interface ExtendedCheckboxProps {
11
+ columnconfig?: ExtendedColumnConfig
12
+ cellconfig?: cellconfig
13
+ onClick?: (event: React.MouseEvent) => void
14
+ checked?: boolean
15
+ indeterminate?: boolean
16
+ onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void
17
+ disabled?: boolean
18
+ }
19
+
20
+ const useCheckbox = (grid: {
21
+ checkbox?: ExtendedCheckboxProps | ExtendedCheckboxProps[]
22
+ }): columnconfig | columnconfig[] | null => {
23
+ if (!grid.checkbox) return null
24
+
25
+ const renderCheckbox = (
26
+ checkboxProps: ExtendedCheckboxProps,
27
+ index: number
28
+ ): columnconfig => {
29
+ const {
30
+ columnconfig: itemColumnConfig,
31
+ cellconfig,
32
+ ...restProps
33
+ } = checkboxProps
34
+
35
+ if (
36
+ !itemColumnConfig ||
37
+ typeof itemColumnConfig !== 'object' ||
38
+ typeof itemColumnConfig.row !== 'number' ||
39
+ typeof itemColumnConfig.column !== 'number'
40
+ ) {
41
+ throw new Error(
42
+ 'columnconfig must be an object with row and column as numbers'
43
+ )
44
+ }
45
+
46
+ // Merge the existing columnconfig with the new props
47
+ const mergedConfig: columnconfig = {
48
+ ...itemColumnConfig,
49
+ cellconfig: {
50
+ ...cellconfig,
51
+ },
52
+ component: <DataGridCheckbox key={`checkbox-${index}`} {...restProps} />,
53
+ }
54
+
55
+ return mergedConfig
56
+ }
57
+
58
+ if (Array.isArray(grid.checkbox)) {
59
+ return grid.checkbox.map(renderCheckbox)
60
+ } else {
61
+ return renderCheckbox(grid.checkbox, 0)
62
+ }
63
+ }
64
+
65
+ export default useCheckbox
@@ -27,6 +27,7 @@ const useGridTypography = (grid: {
27
27
  fontvariant,
28
28
  columnconfig: itemColumnConfig,
29
29
  cellconfig,
30
+ component,
30
31
  ...restProps
31
32
  } = typographyItem
32
33
 
@@ -53,6 +54,7 @@ const useGridTypography = (grid: {
53
54
  text={text}
54
55
  fontvariant={fontvariant}
55
56
  fontcolor={fontcolor}
57
+ component={component || 'span'}
56
58
  {...restProps}
57
59
  />
58
60
  ),
@@ -60,6 +60,9 @@ import useQRCode, { ExtendedQRCodeProps } from './Structure/qrcode/useQRCode'
60
60
  import usePhoneNumber, {
61
61
  ExtendedPhoneNumberFieldProps,
62
62
  } from './Structure/phoneNumber/usePhoneNumber'
63
+ import useCheckbox, {
64
+ ExtendedCheckboxProps,
65
+ } from './Structure/checkbox/useCheckbox'
63
66
  /**
64
67
  * Props for the ContentSection component.
65
68
  * Includes configuration for various content elements.
@@ -95,6 +98,7 @@ export interface ContentSectionProps {
95
98
  phoneNumberField?:
96
99
  | ExtendedPhoneNumberFieldProps
97
100
  | ExtendedPhoneNumberFieldProps[]
101
+ checkbox?: ExtendedCheckboxProps | ExtendedCheckboxProps[]
98
102
  }>
99
103
  width?: number
100
104
  }
@@ -135,6 +139,7 @@ const RenderContent: React.FC<
135
139
  addToColumnConfigs(useCodeCopy(props))
136
140
  addToColumnConfigs(useTextField(props))
137
141
  addToColumnConfigs(useDateField(props))
142
+ addToColumnConfigs(useCheckbox(props))
138
143
  addToColumnConfigs(usePhoneNumber(props))
139
144
  addToColumnConfigs(useDropdown(props))
140
145
  addToColumnConfigs(