goobs-frontend 0.7.68 → 0.7.70

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "goobs-frontend",
3
- "version": "0.7.68",
3
+ "version": "0.7.70",
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,8 @@
28
28
  "jotai": "^2.9.3",
29
29
  "lodash": "^4.17.21",
30
30
  "next": "14.2.6",
31
- "react-datepicker": "^7.3.0"
31
+ "react-datepicker": "^7.3.0",
32
+ "react-qr-code": "^2.0.15"
32
33
  },
33
34
  "devDependencies": {
34
35
  "@next/eslint-plugin-next": "^14.2.6",
@@ -0,0 +1,69 @@
1
+ import React from 'react'
2
+ import QRCodeComponent, { QRCodeProps } from '../../../../components/QRCode'
3
+ import { columnconfig, cellconfig } from '../../../Grid'
4
+
5
+ type ExtendedColumnConfig = Omit<columnconfig, 'component'> & {
6
+ component?: columnconfig['component']
7
+ }
8
+
9
+ export interface ExtendedQRCodeProps extends Omit<QRCodeProps, 'sx'> {
10
+ columnconfig?: ExtendedColumnConfig
11
+ cellconfig?: cellconfig
12
+ }
13
+
14
+ const useQRCode = (grid: {
15
+ qrcode?: ExtendedQRCodeProps | ExtendedQRCodeProps[]
16
+ }): columnconfig | columnconfig[] | null => {
17
+ if (!grid.qrcode) return null
18
+
19
+ const renderQRCode = (
20
+ component: ExtendedQRCodeProps,
21
+ index: number
22
+ ): columnconfig => {
23
+ const {
24
+ value,
25
+ size,
26
+ title,
27
+ columnconfig: itemColumnConfig,
28
+ cellconfig,
29
+ ...restProps
30
+ } = component
31
+
32
+ if (
33
+ !itemColumnConfig ||
34
+ typeof itemColumnConfig !== 'object' ||
35
+ typeof itemColumnConfig.row !== 'number' ||
36
+ typeof itemColumnConfig.column !== 'number'
37
+ ) {
38
+ throw new Error(
39
+ 'columnconfig must be an object with row and column as numbers'
40
+ )
41
+ }
42
+
43
+ const mergedConfig: columnconfig = {
44
+ ...itemColumnConfig,
45
+ cellconfig: {
46
+ ...cellconfig,
47
+ },
48
+ component: (
49
+ <QRCodeComponent
50
+ key={`qrcode-${index}`}
51
+ value={value}
52
+ size={size}
53
+ title={title}
54
+ {...restProps}
55
+ />
56
+ ),
57
+ }
58
+
59
+ return mergedConfig
60
+ }
61
+
62
+ if (Array.isArray(grid.qrcode)) {
63
+ return grid.qrcode.map(renderQRCode)
64
+ } else {
65
+ return renderQRCode(grid.qrcode, 0)
66
+ }
67
+ }
68
+
69
+ export default useQRCode
@@ -56,6 +56,7 @@ import useNumberField, {
56
56
  import usePasswordField, {
57
57
  ExtendedPasswordFieldProps,
58
58
  } from './Structure/passwordField/usePasswordField'
59
+ import useQRCode, { ExtendedQRCodeProps } from './Structure/qrcode/useQRCode'
59
60
 
60
61
  /**
61
62
  * Props for the ContentSection component.
@@ -88,6 +89,7 @@ export interface ContentSectionProps {
88
89
  searchbar?: ExtendedSearchbarProps | ExtendedSearchbarProps[]
89
90
  numberField?: ExtendedNumberFieldProps | ExtendedNumberFieldProps[]
90
91
  passwordField?: ExtendedPasswordFieldProps | ExtendedPasswordFieldProps[]
92
+ qrcode?: ExtendedQRCodeProps | ExtendedQRCodeProps[]
91
93
  }>
92
94
  width?: number
93
95
  }
@@ -137,6 +139,7 @@ const RenderContent: React.FC<
137
139
  addToColumnConfigs(useSearchbar(props))
138
140
  addToColumnConfigs(useNumberField({ numberField: props.numberField }))
139
141
  addToColumnConfigs(usePasswordField({ passwordField: props.passwordField }))
142
+ addToColumnConfigs(useQRCode({ qrcode: props.qrcode }))
140
143
 
141
144
  const updatedGridConfig: gridconfig = {
142
145
  ...grid.gridconfig,
@@ -0,0 +1,105 @@
1
+ import React, { useMemo } from 'react'
2
+ import QRCode from 'react-qr-code'
3
+ import { Box, Typography, Paper, Theme, CircularProgress } from '@mui/material'
4
+ import { SxProps } from '@mui/system'
5
+
6
+ /**
7
+ * Props for the QRCodeComponent
8
+ * @typedef {Object} QRCodeProps
9
+ * @property {string} value - The value to be encoded in the QR code
10
+ * @property {number} [size] - The size of the QR code in pixels
11
+ * @property {string} [title] - An optional title to display above the QR code
12
+ * @property {SxProps<Theme>} [sx] - Custom styles to apply to the component
13
+ */
14
+ export interface QRCodeProps {
15
+ value: string
16
+ size?: number
17
+ title?: string
18
+ sx?: SxProps<Theme>
19
+ }
20
+
21
+ /**
22
+ * A component that displays a QR code with Material-UI styling
23
+ * @param {QRCodeProps} props - The props for the component
24
+ * @returns {React.ReactElement} The rendered QR code component
25
+ */
26
+ const QRCodeComponent: React.FC<QRCodeProps> = React.memo(
27
+ ({ value, size = 256, title, sx }) => {
28
+ // Validate the QR code value
29
+ const isValidValue = useMemo(() => {
30
+ if (!value) return false
31
+ try {
32
+ // Check if the value is a valid URL
33
+ new URL(value)
34
+ return true
35
+ } catch {
36
+ // If not a URL, check if it's a non-empty string
37
+ return typeof value === 'string' && value.trim().length > 0
38
+ }
39
+ }, [value])
40
+
41
+ // Calculate responsive size
42
+ const responsiveSize = useMemo(() => {
43
+ return Math.min(size, window.innerWidth - 32) // 32px for padding
44
+ }, [size])
45
+
46
+ if (!isValidValue) {
47
+ return (
48
+ <Box sx={{ ...sx, p: 2 }} role="alert">
49
+ <Typography color="error">
50
+ Error: Invalid or empty QR code value
51
+ </Typography>
52
+ </Box>
53
+ )
54
+ }
55
+
56
+ return (
57
+ <Paper
58
+ elevation={3}
59
+ sx={{
60
+ ...sx,
61
+ p: 3,
62
+ display: 'inline-block',
63
+ maxWidth: '100%',
64
+ boxSizing: 'border-box',
65
+ }}
66
+ >
67
+ {title && (
68
+ <Typography variant="h6" gutterBottom align="center">
69
+ {title}
70
+ </Typography>
71
+ )}
72
+ <Box
73
+ sx={{
74
+ display: 'flex',
75
+ justifyContent: 'center',
76
+ alignItems: 'center',
77
+ width: responsiveSize,
78
+ height: responsiveSize,
79
+ margin: 'auto',
80
+ }}
81
+ >
82
+ <React.Suspense
83
+ fallback={
84
+ <CircularProgress
85
+ size={responsiveSize / 4}
86
+ aria-label="Loading QR Code"
87
+ />
88
+ }
89
+ >
90
+ <QRCode
91
+ value={value}
92
+ size={responsiveSize}
93
+ style={{ height: 'auto', maxWidth: '100%', width: '100%' }}
94
+ aria-label={`QR Code for ${title || value}`}
95
+ />
96
+ </React.Suspense>
97
+ </Box>
98
+ </Paper>
99
+ )
100
+ }
101
+ )
102
+
103
+ QRCodeComponent.displayName = 'QRCodeComponent'
104
+
105
+ export default QRCodeComponent
package/src/index.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import React from 'react'
2
+
1
3
  // Components
2
4
  import CustomButton from './components/Button'
3
5
  import CustomGrid, {
@@ -34,7 +36,7 @@ import { CustomStepper, CustomStepperProps } from './components/Stepper'
34
36
  import CustomToolbar, { ToolbarProps } from './components/Toolbar'
35
37
  import TransferList, { TransferListProps } from './components/TransferList'
36
38
  import StyledTooltip, { CustomTooltipProps } from './components/Tooltip'
37
- import React from 'react'
39
+ import QRCodeComponent, { QRCodeProps } from './components/QRCode'
38
40
 
39
41
  // New imports
40
42
  import DateField from './components/DateField'
@@ -53,6 +55,7 @@ import { Animation } from './components/Content/Structure/animations'
53
55
  import { ExtendedButtonProps } from './components/Content/Structure/button/useButton'
54
56
  import { ExtendedTypographyProps } from './components/Content/Structure/typography/useGridTypography'
55
57
  import { ExtendedTextFieldProps } from './components/Content/Structure/textfield/useTextField'
58
+ import { ExtendedQRCodeProps } from './components/Content/Structure/qrcode/useQRCode'
56
59
 
57
60
  // Colors
58
61
  import {
@@ -183,6 +186,7 @@ export { CustomToolbar }
183
186
  export { TransferList }
184
187
  export { StyledTooltip }
185
188
  export { formContainerStyle }
189
+ export { QRCodeComponent }
186
190
 
187
191
  // New named exports
188
192
  export { DateField }
@@ -215,6 +219,8 @@ export type { CustomStepperProps }
215
219
  export type { ToolbarProps }
216
220
  export type { TransferListProps }
217
221
  export type { CustomTooltipProps }
222
+ export type { QRCodeProps }
223
+ export type { ExtendedQRCodeProps }
218
224
 
219
225
  // Additional type exports for the newly declared types
220
226
  export type { TypographyComponentProps }