goobs-frontend 0.8.2 → 0.8.4

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.8.2",
3
+ "version": "0.8.4",
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",
@@ -21,31 +21,31 @@
21
21
  "@emotion/cache": "^11.13.1",
22
22
  "@emotion/react": "^11.13.3",
23
23
  "@emotion/styled": "^11.13.0",
24
- "@mui/icons-material": "^6.1.0",
25
- "@mui/material": "^6.1.0",
26
- "@types/lodash": "^4.17.7",
24
+ "@mui/icons-material": "^6.1.1",
25
+ "@mui/material": "^6.1.1",
26
+ "@types/lodash": "^4.17.9",
27
27
  "highlight.js": "^11.10.0",
28
- "jotai": "^2.9.3",
28
+ "jotai": "^2.10.0",
29
29
  "lodash": "^4.17.21",
30
- "next": "14.2.9",
31
- "react-datepicker": "^7.3.0",
30
+ "next": "14.2.13",
31
+ "react-datepicker": "^7.4.0",
32
32
  "react-qr-code": "^2.0.15"
33
33
  },
34
34
  "devDependencies": {
35
- "@next/eslint-plugin-next": "^14.2.9",
36
- "@types/node": "^22.5.4",
37
- "@types/react": "18.3.4",
35
+ "@next/eslint-plugin-next": "^14.2.13",
36
+ "@types/node": "^22.7.3",
37
+ "@types/react": "18.3.9",
38
38
  "@types/react-dom": "^18.3.0",
39
- "@typescript-eslint/eslint-plugin": "^8.5.0",
40
- "@typescript-eslint/parser": "^8.5.0",
41
- "eslint": "^9.9.1",
42
- "eslint-config-next": "^14.2.9",
39
+ "@typescript-eslint/eslint-plugin": "^8.7.0",
40
+ "@typescript-eslint/parser": "^8.7.0",
41
+ "eslint": "^9.11.1",
42
+ "eslint-config-next": "^14.2.13",
43
43
  "eslint-config-prettier": "^9.1.0",
44
44
  "eslint-plugin-prettier": "^5.2.1",
45
45
  "prettier": "^3.3.3",
46
46
  "react": "^18.3.1",
47
47
  "react-dom": "^18.3.1",
48
- "typescript": "^5.5.4"
48
+ "typescript": "^5.6.2"
49
49
  },
50
50
  "files": [
51
51
  "src"
@@ -7,7 +7,7 @@ import 'react-datepicker/dist/react-datepicker.css'
7
7
  import CalendarTodayIcon from '@mui/icons-material/CalendarToday'
8
8
 
9
9
  export interface DateFieldProps extends Omit<TextFieldProps, 'onChange'> {
10
- onChange?: () => void
10
+ onChange?: (date: Date) => void
11
11
  backgroundcolor?: string
12
12
  outlinecolor?: string
13
13
  fontcolor?: string
@@ -58,7 +58,9 @@ const DateField: React.FC<DateFieldProps> = ({
58
58
 
59
59
  const handleChange = (dates: [Date | null, Date | null]) => {
60
60
  setDateRange(dates)
61
- onChange?.()
61
+ if (dates[0]) {
62
+ onChange?.(dates[0])
63
+ }
62
64
  }
63
65
 
64
66
  const formatDateRange = (range: [Date | null, Date | null]) => {
@@ -6,70 +6,35 @@ import {
6
6
  InputLabel,
7
7
  SelectProps,
8
8
  FormHelperText,
9
+ Typography,
9
10
  } from '@mui/material'
10
11
  import { styled } from '@mui/material/styles'
11
12
 
12
- export interface DropdownOption {
13
+ export interface SimpleDropdownOption {
13
14
  value: string
14
- label: string
15
15
  }
16
16
 
17
+ export interface ComplexDropdownOption extends SimpleDropdownOption {
18
+ attribute1?: string
19
+ attribute2?: string
20
+ }
21
+
22
+ export type DropdownOption = SimpleDropdownOption | ComplexDropdownOption
23
+
17
24
  export interface DropdownProps extends Omit<SelectProps, 'onChange'> {
18
- /**
19
- * The label for the dropdown.
20
- */
21
25
  label: string
22
- /**
23
- * The options for the dropdown.
24
- */
25
26
  options: DropdownOption[]
26
- /**
27
- * The default value for the dropdown.
28
- */
29
27
  defaultValue?: string
30
- /**
31
- * The background color of the dropdown.
32
- */
33
28
  backgroundcolor?: string
34
- /**
35
- * The outline color of the dropdown.
36
- */
37
29
  outlinecolor?: string
38
- /**
39
- * The font color of the dropdown.
40
- */
41
30
  fontcolor?: string
42
- /**
43
- * The font color of the dropdown label when shrunk.
44
- */
45
31
  shrunkfontcolor?: string
46
- /**
47
- * Callback function triggered when the dropdown value changes.
48
- */
49
32
  onChange?: SelectProps['onChange']
50
- /**
51
- * Indicates if the dropdown is in an error state.
52
- */
53
33
  error?: boolean
54
- /**
55
- * The helper text to display below the dropdown.
56
- */
57
34
  helperText?: string
58
- /**
59
- * The name of the dropdown.
60
- */
61
35
  name?: string
62
- /**
63
- * Indicates if the dropdown is required.
64
- */
65
36
  required?: boolean
66
- /**
67
- * Callback function triggered when the dropdown loses focus.
68
- */
69
37
  onBlur?: SelectProps['onBlur']
70
- /**
71
- * Callback function triggered when the dropdown receives focus.
72
- */
73
38
  onFocus?: SelectProps['onFocus']
74
39
  }
75
40
 
@@ -100,9 +65,16 @@ const StyledInputLabel = styled(InputLabel)<{ shrunkfontcolor?: string }>(
100
65
  })
101
66
  )
102
67
 
103
- /**
104
- * Dropdown component built with Material UI.
105
- */
68
+ const StyledMenuItem = styled(MenuItem)(({ theme }) => ({
69
+ display: 'flex',
70
+ flexDirection: 'column',
71
+ alignItems: 'flex-start',
72
+ }))
73
+
74
+ const capitalizeFirstLetter = (string: string) => {
75
+ return string.charAt(0).toUpperCase() + string.slice(1)
76
+ }
77
+
106
78
  const Dropdown: React.FC<DropdownProps> = ({
107
79
  label,
108
80
  options,
@@ -139,6 +111,27 @@ const Dropdown: React.FC<DropdownProps> = ({
139
111
  onFocus?.(event)
140
112
  }
141
113
 
114
+ const renderMenuItem = (option: DropdownOption) => {
115
+ const label = capitalizeFirstLetter(option.value.replace(/_/g, ' '))
116
+ if (!('attribute1' in option)) {
117
+ return (
118
+ <MenuItem key={option.value} value={option.value}>
119
+ {label}
120
+ </MenuItem>
121
+ )
122
+ } else {
123
+ return (
124
+ <StyledMenuItem key={option.value} value={option.value}>
125
+ <Typography variant="body1">{label}</Typography>
126
+ <Typography variant="caption" color="textSecondary">
127
+ {option.attribute1}
128
+ {option.attribute2 && ` | ${option.attribute2}`}
129
+ </Typography>
130
+ </StyledMenuItem>
131
+ )
132
+ }
133
+ }
134
+
142
135
  return (
143
136
  <StyledFormControl
144
137
  backgroundcolor={backgroundcolor}
@@ -161,11 +154,7 @@ const Dropdown: React.FC<DropdownProps> = ({
161
154
  aria-labelledby={`${name}-label`}
162
155
  {...rest}
163
156
  >
164
- {options.map(option => (
165
- <MenuItem key={option.value} value={option.value}>
166
- {option.label}
167
- </MenuItem>
168
- ))}
157
+ {options.map(renderMenuItem)}
169
158
  </Select>
170
159
  {helperText && <FormHelperText>{helperText}</FormHelperText>}
171
160
  </StyledFormControl>
@@ -62,6 +62,7 @@ function VerticalVariant({
62
62
  }: VerticalVariantProps) {
63
63
  const router = useRouter()
64
64
  const [selectedNav, setSelectedNav] = useState<string | null>(null)
65
+ const [searchValue, setSearchValue] = useState('')
65
66
 
66
67
  const navOptions = items
67
68
  .filter((item): item is NavProps => 'title' in item && 'subnavs' in item)
@@ -92,6 +93,15 @@ function VerticalVariant({
92
93
  []
93
94
  )
94
95
 
96
+ const handleSearchChange = useCallback(
97
+ (e: React.ChangeEvent<HTMLInputElement>) => {
98
+ const newValue = e.target.value
99
+ setSearchValue(newValue)
100
+ console.log('Search value changed to:', newValue)
101
+ },
102
+ []
103
+ )
104
+
95
105
  const renderItem = useCallback(
96
106
  (
97
107
  item: NavProps | SubNav | View,
@@ -390,9 +400,8 @@ function VerticalVariant({
390
400
  outlinecolor="none"
391
401
  fontcolor={white.main}
392
402
  placeholder="Search..."
393
- onChange={() => {
394
- console.log('Search value changed')
395
- }}
403
+ value={searchValue}
404
+ onChange={handleSearchChange}
396
405
  />
397
406
  )}
398
407
  </Stack>
@@ -9,13 +9,14 @@ export interface SearchbarProps {
9
9
  outlinecolor?: string
10
10
  fontcolor?: string
11
11
  placeholder?: string
12
- onChange?: () => void
12
+ value: string
13
+ onChange: (e: React.ChangeEvent<HTMLInputElement>) => void
13
14
  }
14
15
 
15
16
  const StyledTextField = styled(TextField)<{
16
17
  backgroundcolor?: string
17
18
  outlinecolor?: string
18
- $fontcolor?: string // Use $ prefix to avoid passing it as DOM attribute
19
+ $fontcolor?: string
19
20
  }>(({ theme, backgroundcolor, outlinecolor, $fontcolor }) => ({
20
21
  '& .MuiOutlinedInput-root': {
21
22
  backgroundColor: backgroundcolor || theme.palette.background.paper,
@@ -47,12 +48,9 @@ const Searchbar: React.FC<SearchbarProps> = ({
47
48
  outlinecolor,
48
49
  fontcolor,
49
50
  placeholder,
51
+ value,
50
52
  onChange,
51
53
  }) => {
52
- const handleChange = () => {
53
- onChange?.()
54
- }
55
-
56
54
  return (
57
55
  <StyledTextField
58
56
  label={label}
@@ -62,14 +60,17 @@ const Searchbar: React.FC<SearchbarProps> = ({
62
60
  backgroundcolor={backgroundcolor}
63
61
  outlinecolor={outlinecolor}
64
62
  $fontcolor={fontcolor}
65
- InputProps={{
66
- startAdornment: (
67
- <InputAdornment position="start">
68
- <SearchIcon style={{ color: iconcolor }} />
69
- </InputAdornment>
70
- ),
63
+ value={value}
64
+ onChange={onChange}
65
+ slotProps={{
66
+ input: {
67
+ startAdornment: (
68
+ <InputAdornment position="start">
69
+ <SearchIcon style={{ color: iconcolor }} />
70
+ </InputAdornment>
71
+ ),
72
+ },
71
73
  }}
72
- onChange={handleChange}
73
74
  />
74
75
  )
75
76
  }
@@ -20,7 +20,7 @@ const VerticalDivider = styled(Box)({
20
20
  export interface ToolbarProps {
21
21
  buttons?: CustomButtonProps[]
22
22
  dropdowns?: DropdownProps[]
23
- searchbarProps?: SearchbarProps
23
+ searchbarProps?: Partial<SearchbarProps>
24
24
  }
25
25
 
26
26
  /**
@@ -106,7 +106,8 @@ function CustomToolbar({ buttons, dropdowns, searchbarProps }: ToolbarProps) {
106
106
  label="Search the DataGrid"
107
107
  fontcolor={black.main}
108
108
  iconcolor={black.main}
109
- onChange={() => console.log('Search changed')}
109
+ value={searchbarProps?.value || ''}
110
+ onChange={searchbarProps?.onChange || (() => {})}
110
111
  {...searchbarProps}
111
112
  />
112
113
  </Box>
@@ -1,6 +1,6 @@
1
1
  'use client'
2
2
 
3
- import React from 'react'
3
+ import React, { useEffect } from 'react'
4
4
  import Grid from '@mui/material/Grid'
5
5
  import List from '@mui/material/List'
6
6
  import ListItemButton from '@mui/material/ListItemButton'
@@ -21,7 +21,7 @@ function intersection(a: readonly string[], b: readonly string[]) {
21
21
  export interface TransferListProps {
22
22
  leftItems: readonly string[]
23
23
  rightItems: readonly string[]
24
- onChange?: () => void
24
+ onChange: (leftItems: string[], rightItems: string[]) => void
25
25
  }
26
26
 
27
27
  const TransferList: React.FC<TransferListProps> = ({
@@ -33,6 +33,11 @@ const TransferList: React.FC<TransferListProps> = ({
33
33
  const [left, setLeft] = React.useState<readonly string[]>(leftItems)
34
34
  const [right, setRight] = React.useState<readonly string[]>(rightItems)
35
35
 
36
+ useEffect(() => {
37
+ setLeft(leftItems)
38
+ setRight(rightItems)
39
+ }, [leftItems, rightItems])
40
+
36
41
  const leftChecked = intersection(checked, left)
37
42
  const rightChecked = intersection(checked, right)
38
43
 
@@ -50,37 +55,35 @@ const TransferList: React.FC<TransferListProps> = ({
50
55
  }
51
56
 
52
57
  const handleAllRight = () => {
53
- setRight(right.concat(left))
58
+ const newRight = right.concat(left)
59
+ setRight(newRight)
54
60
  setLeft([])
55
- if (onChange) {
56
- onChange()
57
- }
61
+ onChange([], newRight)
58
62
  }
59
63
 
60
64
  const handleCheckedRight = () => {
61
- setRight(right.concat(leftChecked))
62
- setLeft(not(left, leftChecked))
65
+ const newRight = right.concat(leftChecked)
66
+ const newLeft = not(left, leftChecked)
67
+ setRight(newRight)
68
+ setLeft(newLeft)
63
69
  setChecked(not(checked, leftChecked))
64
- if (onChange) {
65
- onChange()
66
- }
70
+ onChange(newLeft, newRight)
67
71
  }
68
72
 
69
73
  const handleCheckedLeft = () => {
70
- setLeft(left.concat(rightChecked))
71
- setRight(not(right, rightChecked))
74
+ const newLeft = left.concat(rightChecked)
75
+ const newRight = not(right, rightChecked)
76
+ setLeft(newLeft)
77
+ setRight(newRight)
72
78
  setChecked(not(checked, rightChecked))
73
- if (onChange) {
74
- onChange()
75
- }
79
+ onChange(newLeft, newRight)
76
80
  }
77
81
 
78
82
  const handleAllLeft = () => {
79
- setLeft(left.concat(right))
83
+ const newLeft = left.concat(right)
84
+ setLeft(newLeft)
80
85
  setRight([])
81
- if (onChange) {
82
- onChange()
83
- }
86
+ onChange(newLeft, [])
84
87
  }
85
88
 
86
89
  const customList = (items: readonly string[]) => (
package/src/index.ts CHANGED
@@ -40,7 +40,7 @@ import QRCodeComponent, { QRCodeProps } from './components/QRCode'
40
40
 
41
41
  // New imports
42
42
  import DateField from './components/DateField'
43
- import Dropdown from './components/Dropdown'
43
+ import Dropdown, { DropdownOption } from './components/Dropdown'
44
44
  import IncrementNumberField from './components/IncrementNumberField'
45
45
  import NumberField from './components/NumberField'
46
46
  import PasswordField from './components/PasswordField'
@@ -71,7 +71,7 @@ import { ExtendedImageProps } from './components/Content/Structure/image/useImag
71
71
  import { ExtendedConfirmationCodeInputsProps } from './components/Content/Structure/confirmationinput/useConfirmationInput'
72
72
  import { ExtendedRadioGroupProps } from './components/Content/Structure/radiogroup/useRadioGroup'
73
73
  import { ExtendedPhoneNumberFieldProps } from './components/Content/Structure/phoneNumber/usePhoneNumber'
74
-
74
+ import { CustomTextFieldProps } from './components/TextField'
75
75
  // Colors
76
76
  import {
77
77
  moss,
@@ -267,6 +267,8 @@ export type { CustomStepperComponentProps }
267
267
  export type { CustomToolbarComponentProps }
268
268
  export type { TransferListComponentProps }
269
269
  export type { StyledTooltipComponentProps }
270
+ export type { DropdownOption }
271
+ export type { CustomTextFieldProps }
270
272
 
271
273
  // New type exports
272
274
  export type { DateFieldProps }