goobs-frontend 0.9.5 → 0.9.7

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.9.5",
3
+ "version": "0.9.7",
4
4
  "type": "module",
5
5
  "description": "A comprehensive React-based libary that extends the functionality of Material-UI",
6
6
  "license": "MIT",
@@ -55,7 +55,7 @@
55
55
  "@storybook/nextjs": "^8",
56
56
  "@storybook/react": "^8",
57
57
  "@storybook/test": "^8",
58
- "@types/node": "^22.13.8",
58
+ "@types/node": "^22",
59
59
  "@types/react": "^19",
60
60
  "@types/react-dom": "^19",
61
61
  "@typescript-eslint/eslint-plugin": "^8",
@@ -1,10 +1,10 @@
1
1
  'use client'
2
2
 
3
3
  import React, { useMemo } from 'react'
4
- import { Dialog, Box } from '@mui/material'
4
+ import { Box } from '@mui/material'
5
5
  import ContentSection, { ContentSectionProps } from '../../Content'
6
- import { formContainerStyle } from '../../../styles/Form'
7
6
  import { TypographyProps } from '../../Typography'
7
+ import CustomButton, { CustomButtonProps } from '../../Button'
8
8
 
9
9
  export interface CustomDialogProps {
10
10
  title?: string
@@ -12,6 +12,8 @@ export interface CustomDialogProps {
12
12
  grids?: ContentSectionProps['grids']
13
13
  content?: React.ReactNode
14
14
  width?: number
15
+ /** Optional array of button props for footer buttons */
16
+ buttons?: CustomButtonProps[]
15
17
  }
16
18
 
17
19
  function CustomDialog({
@@ -20,20 +22,19 @@ function CustomDialog({
20
22
  grids,
21
23
  content,
22
24
  width = 450,
25
+ buttons,
23
26
  }: CustomDialogProps) {
24
- // We render this dialog as always open (embedded in pages).
25
-
26
27
  const headerGrid = useMemo(
27
28
  (): ContentSectionProps['grids'][0] => ({
28
29
  typography: [
29
30
  {
30
31
  text: title,
31
- fontvariant: 'merrih5',
32
+ fontvariant: 'merrih4',
32
33
  fontcolor: 'black',
33
34
  },
34
35
  {
35
36
  text: description,
36
- fontvariant: 'merriparagraph',
37
+ fontvariant: 'merrih5',
37
38
  fontcolor: 'black',
38
39
  },
39
40
  ] as TypographyProps[],
@@ -46,31 +47,42 @@ function CustomDialog({
46
47
  [headerGrid]
47
48
  )
48
49
 
49
- const renderContent = useMemo(
50
- () => (
51
- <Box sx={formContainerStyle}>
52
- <Box mb={0}>{renderHeader}</Box>
53
- {content || (grids && <ContentSection grids={grids} />)}
50
+ const renderButtons = useMemo(() => {
51
+ if (!buttons || buttons.length === 0) return null
52
+
53
+ return (
54
+ <Box
55
+ sx={{
56
+ display: 'flex',
57
+ flexDirection: 'row',
58
+ justifyContent: 'space-between',
59
+ gap: 2,
60
+ marginTop: '15px',
61
+ }}
62
+ >
63
+ {buttons.map((buttonProps, index) => (
64
+ <CustomButton key={index} {...buttonProps} />
65
+ ))}
54
66
  </Box>
55
- ),
56
- [renderHeader, content, grids]
57
- )
67
+ )
68
+ }, [buttons])
58
69
 
59
70
  return (
60
- <Dialog
61
- open={true}
62
- fullWidth
63
- maxWidth={false}
64
- slotProps={{
65
- paper: {
66
- style: {
67
- width: `${width}px`,
68
- },
69
- },
71
+ <Box
72
+ sx={{
73
+ width: `${width}px`,
74
+ maxWidth: '100%',
75
+ borderRadius: '16px',
76
+ boxShadow: 3,
77
+ margin: '0 auto',
78
+ padding: 3,
79
+ bgcolor: 'white',
70
80
  }}
71
81
  >
72
- {renderContent}
73
- </Dialog>
82
+ {renderHeader}
83
+ {content || (grids && <ContentSection grids={grids} />)}
84
+ {renderButtons}
85
+ </Box>
74
86
  )
75
87
  }
76
88
 
@@ -4,7 +4,7 @@ import React, { useMemo, useState, useEffect } from 'react'
4
4
  import { Close } from '@mui/icons-material'
5
5
  import { Dialog, IconButton, Box } from '@mui/material'
6
6
  import ContentSection, { ContentSectionProps } from '../../Content'
7
- import { formContainerStyle } from '../../../styles/Form'
7
+ import CustomButton, { CustomButtonProps } from '../../Button'
8
8
 
9
9
  export interface PopupProps {
10
10
  open: boolean
@@ -21,6 +21,8 @@ export interface PopupProps {
21
21
  grids?: ContentSectionProps['grids']
22
22
  content?: React.ReactNode
23
23
  width?: number
24
+ /** Optional array of button props for footer buttons */
25
+ buttons?: CustomButtonProps[]
24
26
  }
25
27
 
26
28
  function Popup({
@@ -32,6 +34,7 @@ function Popup({
32
34
  grids,
33
35
  content,
34
36
  width = 450,
37
+ buttons,
35
38
  }: PopupProps) {
36
39
  // Local state syncing with props
37
40
  const [isOpen, setIsOpen] = useState(open)
@@ -57,12 +60,12 @@ function Popup({
57
60
  {
58
61
  text: title,
59
62
  // Cast to literal type as expected by goobs-frontend.
60
- fontvariant: 'merrih5' as const,
63
+ fontvariant: 'merrih4' as const,
61
64
  fontcolor: 'black',
62
65
  },
63
66
  {
64
67
  text: description,
65
- fontvariant: 'merriparagraph' as const,
68
+ fontvariant: 'merrih5' as const,
66
69
  fontcolor: 'black',
67
70
  },
68
71
  ],
@@ -75,15 +78,25 @@ function Popup({
75
78
  [headerGrid]
76
79
  )
77
80
 
78
- const renderContent = useMemo(
79
- () => (
80
- <Box sx={formContainerStyle}>
81
- <Box mb={0}>{renderHeader}</Box>
82
- {content || (grids && <ContentSection grids={grids} />)}
81
+ const renderButtons = useMemo(() => {
82
+ if (!buttons || buttons.length === 0) return null
83
+
84
+ return (
85
+ <Box
86
+ sx={{
87
+ display: 'flex',
88
+ flexDirection: 'row',
89
+ justifyContent: 'space-between',
90
+ gap: 2,
91
+ marginTop: '15px',
92
+ }}
93
+ >
94
+ {buttons.map((buttonProps, index) => (
95
+ <CustomButton key={index} {...buttonProps} />
96
+ ))}
83
97
  </Box>
84
- ),
85
- [renderHeader, content, grids]
86
- )
98
+ )
99
+ }, [buttons])
87
100
 
88
101
  const handleClose = () => {
89
102
  setIsOpen(false)
@@ -101,6 +114,10 @@ function Popup({
101
114
  paper: {
102
115
  style: {
103
116
  width: `${width}px`,
117
+ borderRadius: '16px',
118
+ backgroundColor: 'white',
119
+ boxShadow: '0px 4px 10px rgba(0, 0, 0, 0.2)',
120
+ padding: '24px',
104
121
  // Ensure pointer events are enabled inside the Dialog
105
122
  pointerEvents: 'auto',
106
123
  },
@@ -125,7 +142,9 @@ function Popup({
125
142
  >
126
143
  <Close />
127
144
  </IconButton>
128
- {renderContent}
145
+ {renderHeader}
146
+ {content || (grids && <ContentSection grids={grids} />)}
147
+ {renderButtons}
129
148
  </Dialog>
130
149
  )
131
150
  }
@@ -53,7 +53,7 @@ const NoUserAddTask: React.FC<NoUserAddTaskProps> = ({
53
53
 
54
54
  // ------------------ RENDER ------------------
55
55
  return (
56
- <Box sx={{ p: 3 }}>
56
+ <Box sx={{ p: 0 }}>
57
57
  <Typography variant="h5" sx={{ mb: 3 }}>
58
58
  Create Task
59
59
  </Typography>
@@ -3,6 +3,7 @@
3
3
  import {
4
4
  Typography as MuiTypography,
5
5
  TypographyProps as MuiTypographyProps,
6
+ useTheme,
6
7
  } from '@mui/material'
7
8
  import React, { JSX } from 'react'
8
9
 
@@ -19,7 +20,7 @@ export type TypographyVariant =
19
20
  | 'helperheader'
20
21
  | 'helperfooter'
21
22
 
22
- type CustomTypographyVariant = `${FontFamily}${TypographyVariant}`
23
+ export type CustomTypographyVariant = `${FontFamily}${TypographyVariant}`
23
24
 
24
25
  export interface TypographyProps extends Omit<MuiTypographyProps, 'variant'> {
25
26
  text?: string
@@ -29,6 +30,18 @@ export interface TypographyProps extends Omit<MuiTypographyProps, 'variant'> {
29
30
  children?: React.ReactNode
30
31
  }
31
32
 
33
+ // MUI's TextTransform type
34
+ type TextTransform = 'none' | 'capitalize' | 'uppercase' | 'lowercase'
35
+
36
+ // Define the structure expected for theme typography variants
37
+ interface TypographyVariantStyle {
38
+ fontFamily?: string
39
+ fontSize?: string
40
+ fontWeight?: number
41
+ textTransform?: TextTransform
42
+ lineHeight?: string | number
43
+ }
44
+
32
45
  const arapeyStyles: Record<TypographyVariant, React.CSSProperties> = {
33
46
  h1: {
34
47
  fontFamily: 'Arapey, serif',
@@ -206,48 +219,92 @@ const Typography = ({
206
219
  fontvariant,
207
220
  variant,
208
221
  children,
222
+ style,
209
223
  ...rest
210
224
  }: TypographyProps): JSX.Element => {
211
- let variantStyle: React.CSSProperties = {}
225
+ const theme = useTheme()
226
+ let variantStyle: Record<string, unknown> = {}
212
227
  const actualVariant = fontvariant || variant
213
228
 
214
- if (typeof actualVariant === 'string') {
215
- const fontFamily = actualVariant.startsWith('arapey')
216
- ? 'arapey'
217
- : actualVariant.startsWith('inter')
218
- ? 'inter'
219
- : actualVariant.startsWith('merri')
220
- ? 'merri'
221
- : null
229
+ if (typeof actualVariant === 'string' && actualVariant.length > 0) {
230
+ // First, try to get the variant from the theme
231
+ try {
232
+ // Log the actual variant being used
233
+ console.log('Using variant:', actualVariant)
234
+
235
+ // Check if we're using a custom font variant (e.g., 'merrih2')
236
+ if (/^(arapey|inter|merri)/.test(actualVariant)) {
237
+ // For custom variants, we need to check if they exist in the theme
238
+ // Use Record to avoid TypeScript errors
239
+ const themeTypography = theme.typography as unknown as Record<
240
+ string,
241
+ unknown
242
+ >
243
+
244
+ if (themeTypography && actualVariant in themeTypography) {
245
+ // Custom variant exists in theme, use its properties
246
+ const themeVariant = themeTypography[
247
+ actualVariant
248
+ ] as TypographyVariantStyle
249
+ console.log('Found theme variant:', themeVariant)
222
250
 
223
- if (fontFamily) {
224
- const variantPart = actualVariant.slice(
225
- fontFamily.length
226
- ) as TypographyVariant
227
- switch (fontFamily) {
228
- case 'arapey':
229
- variantStyle = arapeyStyles[variantPart] || {}
230
- break
231
- case 'inter':
232
- variantStyle = interStyles[variantPart] || {}
233
- break
234
- case 'merri':
235
- variantStyle = merriStyles[variantPart] || {}
236
- break
251
+ if (themeVariant) {
252
+ variantStyle = {
253
+ fontFamily: themeVariant.fontFamily,
254
+ fontSize: themeVariant.fontSize,
255
+ fontWeight: themeVariant.fontWeight,
256
+ textTransform: themeVariant.textTransform,
257
+ lineHeight: themeVariant.lineHeight,
258
+ }
259
+ }
260
+ } else {
261
+ // Custom variant not in theme, fallback to hardcoded styles
262
+ console.log('Custom variant not found in theme, using fallback')
263
+
264
+ const fontFamily = actualVariant.startsWith('arapey')
265
+ ? 'arapey'
266
+ : actualVariant.startsWith('inter')
267
+ ? 'inter'
268
+ : actualVariant.startsWith('merri')
269
+ ? 'merri'
270
+ : null
271
+
272
+ if (fontFamily) {
273
+ const variantPart = actualVariant.slice(
274
+ fontFamily.length
275
+ ) as TypographyVariant
276
+
277
+ switch (fontFamily) {
278
+ case 'arapey':
279
+ variantStyle = { ...arapeyStyles[variantPart] }
280
+ break
281
+ case 'inter':
282
+ variantStyle = { ...interStyles[variantPart] }
283
+ break
284
+ case 'merri':
285
+ variantStyle = { ...merriStyles[variantPart] }
286
+ break
287
+ }
288
+ }
289
+ }
290
+ } else {
291
+ // Standard MUI variant (h1, h2, etc.)
292
+ // Let MUI handle these by setting the variant prop
237
293
  }
294
+ } catch (error) {
295
+ console.error('Error applying typography variant:', error)
238
296
  }
239
297
  }
240
298
 
299
+ // Combine custom styles with variant-derived styles
300
+ const combinedStyle = {
301
+ ...variantStyle,
302
+ ...(fontcolor ? { color: fontcolor } : {}),
303
+ ...(style || {}),
304
+ }
305
+
241
306
  return (
242
- <MuiTypography
243
- component="span"
244
- style={{
245
- color: fontcolor,
246
- ...variantStyle,
247
- }}
248
- variant={actualVariant as MuiTypographyProps['variant']}
249
- {...rest}
250
- >
307
+ <MuiTypography component="div" style={combinedStyle} {...rest}>
251
308
  {text || children}
252
309
  </MuiTypography>
253
310
  )
@@ -1,7 +1,8 @@
1
- type TypographyConfig = {
1
+ export type TypographyConfig = {
2
2
  fontSize: string
3
3
  fontWeight: number
4
4
  textTransform: string
5
+ fontFamily?: string
5
6
  }
6
7
 
7
8
  // Define base configurations for each heading level