@centreon/ui 26.12.2 → 26.12.3
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
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
|
|
11
11
|
import { useCallback, useState } from 'react';
|
|
12
12
|
import { useTranslation } from 'react-i18next';
|
|
13
|
-
import { makeStyles } from 'tss-react/mui';
|
|
14
13
|
|
|
15
14
|
import type { Group } from './Inputs/models';
|
|
16
15
|
|
|
@@ -23,22 +22,6 @@ interface Props {
|
|
|
23
22
|
isCollapsible: boolean;
|
|
24
23
|
}
|
|
25
24
|
|
|
26
|
-
const useStyles = makeStyles()((theme) => ({
|
|
27
|
-
expandCollapseIcon: {
|
|
28
|
-
justifySelf: 'flex-end'
|
|
29
|
-
},
|
|
30
|
-
groupTitleContainer: {
|
|
31
|
-
alignItems: 'center',
|
|
32
|
-
columnGap: theme.spacing(1),
|
|
33
|
-
display: 'flex',
|
|
34
|
-
flexDirection: 'row'
|
|
35
|
-
},
|
|
36
|
-
title: {},
|
|
37
|
-
tooltip: {
|
|
38
|
-
maxWidth: theme.spacing(60)
|
|
39
|
-
}
|
|
40
|
-
}));
|
|
41
|
-
|
|
42
25
|
const CollapsibleGroup = ({
|
|
43
26
|
children,
|
|
44
27
|
isCollapsible,
|
|
@@ -47,7 +30,6 @@ const CollapsibleGroup = ({
|
|
|
47
30
|
defaultIsOpen = false,
|
|
48
31
|
className
|
|
49
32
|
}: Props): JSX.Element => {
|
|
50
|
-
const { classes, cx } = useStyles();
|
|
51
33
|
const { t } = useTranslation();
|
|
52
34
|
|
|
53
35
|
const [isOpen, setIsOpen] = useState(isCollapsible && defaultIsOpen);
|
|
@@ -56,7 +38,7 @@ const CollapsibleGroup = ({
|
|
|
56
38
|
setIsOpen((currentIsOpen) => !currentIsOpen);
|
|
57
39
|
};
|
|
58
40
|
|
|
59
|
-
const containerClassName = className || ''
|
|
41
|
+
const containerClassName = `flex items-center gap-x-2 ${className || ''}`;
|
|
60
42
|
|
|
61
43
|
const CollapseIcon = isOpen ? ExpandLess : ExpandMore;
|
|
62
44
|
const ContainerComponent = useCallback(
|
|
@@ -66,7 +48,7 @@ const CollapsibleGroup = ({
|
|
|
66
48
|
isCollapsible ? (
|
|
67
49
|
<ListItemButton
|
|
68
50
|
aria-label={group?.name}
|
|
69
|
-
className={`${
|
|
51
|
+
className={`${containerClassName} bg-background-listing-header rounded-lg`}
|
|
70
52
|
dense
|
|
71
53
|
disableGutters
|
|
72
54
|
disableRipple
|
|
@@ -75,18 +57,9 @@ const CollapsibleGroup = ({
|
|
|
75
57
|
{containerComponentChildren}
|
|
76
58
|
</ListItemButton>
|
|
77
59
|
) : (
|
|
78
|
-
<Box className={
|
|
79
|
-
{containerComponentChildren}
|
|
80
|
-
</Box>
|
|
60
|
+
<Box className={containerClassName}>{containerComponentChildren}</Box>
|
|
81
61
|
),
|
|
82
|
-
[
|
|
83
|
-
isCollapsible,
|
|
84
|
-
classes.groupTitleContainer,
|
|
85
|
-
containerClassName,
|
|
86
|
-
cx,
|
|
87
|
-
group?.name,
|
|
88
|
-
toggle
|
|
89
|
-
]
|
|
62
|
+
[isCollapsible, containerClassName, group?.name, toggle]
|
|
90
63
|
);
|
|
91
64
|
|
|
92
65
|
return (
|
|
@@ -100,7 +73,7 @@ const CollapsibleGroup = ({
|
|
|
100
73
|
data-testid={`${group?.name}-header`}
|
|
101
74
|
>
|
|
102
75
|
<Typography
|
|
103
|
-
className="groupText scroll-m-12 snap-start"
|
|
76
|
+
className="groupText scroll-m-12 snap-start text-base font-medium"
|
|
104
77
|
variant="h6"
|
|
105
78
|
{...group?.titleAttributes}
|
|
106
79
|
data-section-group-form-id={group?.name}
|
|
@@ -110,7 +83,7 @@ const CollapsibleGroup = ({
|
|
|
110
83
|
{group?.EndIcon && (
|
|
111
84
|
<Tooltip
|
|
112
85
|
classes={{
|
|
113
|
-
tooltip:
|
|
86
|
+
tooltip: 'max-w-120'
|
|
114
87
|
}}
|
|
115
88
|
placement="top"
|
|
116
89
|
title={group?.TooltipContent ? <group.TooltipContent /> : ''}
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { Typography } from '@mui/material';
|
|
2
2
|
|
|
3
|
+
import { ThemeMode, userAtom } from '@centreon/ui-context';
|
|
4
|
+
|
|
3
5
|
import { faker } from '@faker-js/faker';
|
|
4
6
|
import { rs } from '@rstest/core';
|
|
5
7
|
import { render } from '@test-setup/render';
|
|
6
8
|
import { screen, waitFor, within } from '@testing-library/react';
|
|
7
9
|
import userEvent from '@testing-library/user-event';
|
|
8
10
|
import { useFormikContext } from 'formik';
|
|
11
|
+
import { createStore, Provider } from 'jotai';
|
|
9
12
|
import { object } from 'yup';
|
|
10
13
|
|
|
11
14
|
import type { SelectEntry } from '..';
|
|
12
15
|
import { Button } from '../components';
|
|
16
|
+
import ThemeProvider from '../ThemeProvider';
|
|
13
17
|
import { Form } from './Form';
|
|
14
18
|
import { type InputProps, InputType } from './Inputs/models';
|
|
15
19
|
|
|
@@ -443,3 +447,107 @@ describe('Form with sections', () => {
|
|
|
443
447
|
);
|
|
444
448
|
});
|
|
445
449
|
});
|
|
450
|
+
|
|
451
|
+
// The theme mode comes from the user atom, and the Tailwind tokens from the
|
|
452
|
+
// `dark` class on the document.
|
|
453
|
+
const initializeFormTitles = (themeMode: ThemeMode): void => {
|
|
454
|
+
const store = createStore();
|
|
455
|
+
store.set(userAtom, { ...store.get(userAtom), themeMode });
|
|
456
|
+
|
|
457
|
+
document.documentElement.classList.toggle(
|
|
458
|
+
'dark',
|
|
459
|
+
themeMode === ThemeMode.dark
|
|
460
|
+
);
|
|
461
|
+
|
|
462
|
+
render(
|
|
463
|
+
<Provider store={store}>
|
|
464
|
+
<ThemeProvider>
|
|
465
|
+
<Form
|
|
466
|
+
areGroupsOpen
|
|
467
|
+
groups={[{ name: 'Titles section', order: 1 }]}
|
|
468
|
+
initialValues={{ gridField: '', topLevelField: '' }}
|
|
469
|
+
inputs={[
|
|
470
|
+
{
|
|
471
|
+
additionalLabel: 'Top level block title',
|
|
472
|
+
fieldName: 'topLevelField',
|
|
473
|
+
group: 'Titles section',
|
|
474
|
+
label: 'Top level field',
|
|
475
|
+
type: InputType.Text
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
fieldName: '',
|
|
479
|
+
grid: {
|
|
480
|
+
columns: [
|
|
481
|
+
{
|
|
482
|
+
additionalLabel: 'Grid block title',
|
|
483
|
+
fieldName: 'gridField',
|
|
484
|
+
label: 'Grid field',
|
|
485
|
+
type: InputType.Text
|
|
486
|
+
}
|
|
487
|
+
]
|
|
488
|
+
},
|
|
489
|
+
group: 'Titles section',
|
|
490
|
+
label: 'Grid',
|
|
491
|
+
type: InputType.Grid
|
|
492
|
+
}
|
|
493
|
+
]}
|
|
494
|
+
isCollapsible
|
|
495
|
+
submit={rs.fn()}
|
|
496
|
+
validationSchema={object()}
|
|
497
|
+
/>
|
|
498
|
+
</ThemeProvider>
|
|
499
|
+
</Provider>
|
|
500
|
+
);
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
const textPrimaryColor = {
|
|
504
|
+
[ThemeMode.dark]: 'rgb(255, 255, 255)',
|
|
505
|
+
[ThemeMode.light]: 'rgb(0, 0, 0)'
|
|
506
|
+
};
|
|
507
|
+
|
|
508
|
+
[ThemeMode.light, ThemeMode.dark].forEach((themeMode) => {
|
|
509
|
+
describe(`Form titles in ${themeMode} mode`, () => {
|
|
510
|
+
beforeEach(() => {
|
|
511
|
+
expect.hasAssertions();
|
|
512
|
+
});
|
|
513
|
+
beforeEach(() => initializeFormTitles(themeMode));
|
|
514
|
+
|
|
515
|
+
afterEach(() => {
|
|
516
|
+
document.documentElement.classList.remove('dark');
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
it('displays the section title in 16px medium on a 24px line', async () => {
|
|
520
|
+
const title = await screen.findByText('Titles section');
|
|
521
|
+
|
|
522
|
+
expect(title).toHaveStyle({
|
|
523
|
+
fontSize: '16px',
|
|
524
|
+
fontWeight: '500',
|
|
525
|
+
lineHeight: '24px'
|
|
526
|
+
});
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
it('rounds the collapsible section header with an 8px radius', async () => {
|
|
530
|
+
expect(await screen.findByLabelText('Titles section')).toHaveStyle({
|
|
531
|
+
borderRadius: '8px'
|
|
532
|
+
});
|
|
533
|
+
});
|
|
534
|
+
|
|
535
|
+
it('displays the grid block title in 16px bold with the text colour', async () => {
|
|
536
|
+
expect(await screen.findByText('Grid block title')).toHaveStyle({
|
|
537
|
+
color: textPrimaryColor[themeMode],
|
|
538
|
+
fontSize: '16px',
|
|
539
|
+
fontWeight: '700',
|
|
540
|
+
lineHeight: '24px'
|
|
541
|
+
});
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
it('displays the top level block title like the grid block title', async () => {
|
|
545
|
+
expect(await screen.findByText('Top level block title')).toHaveStyle({
|
|
546
|
+
color: textPrimaryColor[themeMode],
|
|
547
|
+
fontSize: '16px',
|
|
548
|
+
fontWeight: '700',
|
|
549
|
+
lineHeight: '24px'
|
|
550
|
+
});
|
|
551
|
+
});
|
|
552
|
+
});
|
|
553
|
+
});
|
package/src/Form/Inputs/Grid.tsx
CHANGED
|
@@ -45,8 +45,7 @@ const Grid = ({
|
|
|
45
45
|
<Box key={key as string} sx={{ width: '100%' }}>
|
|
46
46
|
{field.additionalLabel && (
|
|
47
47
|
<Typography
|
|
48
|
-
className={field?.additionalLabelClassName}
|
|
49
|
-
sx={{ color: 'primary.main', marginBottom: 0.5 }}
|
|
48
|
+
className={`mb-1 text-base font-bold text-text-primary ${field?.additionalLabelClassName || ''}`}
|
|
50
49
|
variant="h6"
|
|
51
50
|
>
|
|
52
51
|
{field.additionalLabel}
|
|
@@ -26,7 +26,6 @@ import {
|
|
|
26
26
|
toPairs
|
|
27
27
|
} from 'ramda';
|
|
28
28
|
import { Fragment, useMemo } from 'react';
|
|
29
|
-
import { makeStyles } from 'tss-react/mui';
|
|
30
29
|
|
|
31
30
|
import { GroupDirection } from '..';
|
|
32
31
|
import CollapsibleGroup from '../CollapsibleGroup';
|
|
@@ -104,42 +103,6 @@ export const getInput = cond<
|
|
|
104
103
|
[T, always(TextInput)]
|
|
105
104
|
]);
|
|
106
105
|
|
|
107
|
-
interface StylesProps {
|
|
108
|
-
groupDirection?: GroupDirection;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const useStyles = makeStyles<StylesProps>()((theme, { groupDirection }) => ({
|
|
112
|
-
additionalLabel: {
|
|
113
|
-
marginBottom: theme.spacing(0.5)
|
|
114
|
-
},
|
|
115
|
-
buttons: {
|
|
116
|
-
columnGap: theme.spacing(2),
|
|
117
|
-
display: 'flex',
|
|
118
|
-
flexDirection: 'row',
|
|
119
|
-
justifyContent: 'flex-end'
|
|
120
|
-
},
|
|
121
|
-
divider: {
|
|
122
|
-
margin: equals(groupDirection, GroupDirection.Horizontal)
|
|
123
|
-
? theme.spacing(0, 2)
|
|
124
|
-
: theme.spacing(2, 0)
|
|
125
|
-
},
|
|
126
|
-
groups: {
|
|
127
|
-
display: 'flex',
|
|
128
|
-
flexDirection: equals(groupDirection, GroupDirection.Horizontal)
|
|
129
|
-
? 'row'
|
|
130
|
-
: 'column'
|
|
131
|
-
},
|
|
132
|
-
inputs: {
|
|
133
|
-
display: 'flex',
|
|
134
|
-
flexDirection: 'column',
|
|
135
|
-
margin: theme.spacing(2, 0),
|
|
136
|
-
rowGap: theme.spacing(2)
|
|
137
|
-
},
|
|
138
|
-
inputWrapper: {
|
|
139
|
-
width: '100%'
|
|
140
|
-
}
|
|
141
|
-
}));
|
|
142
|
-
|
|
143
106
|
interface Props {
|
|
144
107
|
areGroupsOpen?: boolean;
|
|
145
108
|
groupDirection?: GroupDirection;
|
|
@@ -161,7 +124,7 @@ const Inputs = ({
|
|
|
161
124
|
areGroupsOpen,
|
|
162
125
|
inputsClassName
|
|
163
126
|
}: Props): JSX.Element => {
|
|
164
|
-
const
|
|
127
|
+
const isHorizontal = equals(groupDirection, GroupDirection.Horizontal);
|
|
165
128
|
const formikContext = useFormikContext<FormikValues>();
|
|
166
129
|
|
|
167
130
|
const groupsName = pluck('name', groups);
|
|
@@ -217,7 +180,7 @@ const Inputs = ({
|
|
|
217
180
|
) as Array<[string | null, Array<InputProps>]>;
|
|
218
181
|
|
|
219
182
|
return (
|
|
220
|
-
<div className={
|
|
183
|
+
<div className={`flex ${isHorizontal ? 'flex-row' : 'flex-col'}`}>
|
|
221
184
|
{normalizedInputsByGroup.map(([groupName, groupedInputs], index) => {
|
|
222
185
|
const hasGroupTitle = not(isNil(groupName));
|
|
223
186
|
|
|
@@ -238,7 +201,9 @@ const Inputs = ({
|
|
|
238
201
|
hasGroupTitle={hasGroupTitle}
|
|
239
202
|
isCollapsible={isCollapsible}
|
|
240
203
|
>
|
|
241
|
-
<div
|
|
204
|
+
<div
|
|
205
|
+
className={`flex flex-col my-4 gap-y-4 ${inputsClassName || ''}`}
|
|
206
|
+
>
|
|
242
207
|
{groupedInputs.map((inputProps) => {
|
|
243
208
|
const key =
|
|
244
209
|
isNotNil(inputProps.label) || isNotEmpty(inputProps.label)
|
|
@@ -257,14 +222,11 @@ const Inputs = ({
|
|
|
257
222
|
const Input = getInput(inputProps.type);
|
|
258
223
|
|
|
259
224
|
return (
|
|
260
|
-
<div className=
|
|
225
|
+
<div className="w-full" key={key as string}>
|
|
261
226
|
{inputProps.additionalLabel && (
|
|
262
227
|
<Typography
|
|
263
|
-
className={
|
|
264
|
-
|
|
265
|
-
inputProps?.additionalLabelClassName
|
|
266
|
-
)}
|
|
267
|
-
variant="body1"
|
|
228
|
+
className={`mb-1 text-base font-bold text-text-primary ${inputProps?.additionalLabelClassName || ''}`}
|
|
229
|
+
variant="h6"
|
|
268
230
|
>
|
|
269
231
|
{inputProps.additionalLabel}
|
|
270
232
|
</Typography>
|
|
@@ -282,13 +244,9 @@ const Inputs = ({
|
|
|
282
244
|
hasGroupTitle &&
|
|
283
245
|
not(equals(lastGroup, groupName as string)) && (
|
|
284
246
|
<Divider
|
|
285
|
-
className={
|
|
247
|
+
className={isHorizontal ? 'my-0 mx-4' : 'my-4 mx-0'}
|
|
286
248
|
flexItem
|
|
287
|
-
orientation={
|
|
288
|
-
equals(groupDirection, GroupDirection.Horizontal)
|
|
289
|
-
? 'vertical'
|
|
290
|
-
: 'horizontal'
|
|
291
|
-
}
|
|
249
|
+
orientation={isHorizontal ? 'vertical' : 'horizontal'}
|
|
292
250
|
/>
|
|
293
251
|
)}
|
|
294
252
|
</Fragment>
|