@pautena/react-design-system 0.11.1 → 0.11.2
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/dist/cjs/index.js +4 -4
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/components/data-display/header/header-title.d.ts +9 -0
- package/dist/cjs/types/components/data-display/header/header.types.d.ts +10 -2
- package/dist/cjs/types/components/data-display/header/index.d.ts +1 -0
- package/dist/cjs/types/components/inputs/action/action-header.d.ts +7 -0
- package/dist/cjs/types/components/inputs/action/index.d.ts +1 -0
- package/dist/esm/index.js +4 -4
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/components/data-display/header/header-title.d.ts +9 -0
- package/dist/esm/types/components/data-display/header/header.types.d.ts +10 -2
- package/dist/esm/types/components/data-display/header/index.d.ts +1 -0
- package/dist/esm/types/components/inputs/action/action-header.d.ts +7 -0
- package/dist/esm/types/components/inputs/action/index.d.ts +1 -0
- package/dist/index.d.ts +31 -7
- package/package.json +1 -1
- package/src/components/data-display/header/header-title.tsx +51 -0
- package/src/components/data-display/header/header.stories.tsx +40 -1
- package/src/components/data-display/header/header.test.tsx +62 -7
- package/src/components/data-display/header/header.tsx +7 -8
- package/src/components/data-display/header/header.types.ts +10 -2
- package/src/components/data-display/header/index.ts +1 -0
- package/src/components/inputs/action/action-header.test.tsx +11 -0
- package/src/components/inputs/action/action-header.tsx +30 -0
- package/src/components/inputs/action/action.tsx +3 -18
- package/src/components/inputs/action/index.ts +1 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { PropsWithChildren } from "react";
|
|
2
|
+
export type HeaderTitleProps = PropsWithChildren<{
|
|
3
|
+
loading?: boolean;
|
|
4
|
+
}>;
|
|
5
|
+
export declare const HeaderTitle: ({ loading, children }: HeaderTitleProps) => JSX.Element;
|
|
6
|
+
export type HeaderSubtitleProps = PropsWithChildren<{
|
|
7
|
+
loading?: boolean;
|
|
8
|
+
}>;
|
|
9
|
+
export declare const HeaderSubtitle: ({ loading, children }: HeaderSubtitleProps) => JSX.Element;
|
|
@@ -38,11 +38,19 @@ export type HeaderProps = {
|
|
|
38
38
|
/**
|
|
39
39
|
* Title of the header
|
|
40
40
|
*/
|
|
41
|
-
title
|
|
41
|
+
title?: string | ReactElement;
|
|
42
|
+
/**
|
|
43
|
+
* Show a loading indicator in the title position
|
|
44
|
+
*/
|
|
45
|
+
loadingTitle?: boolean;
|
|
42
46
|
/**
|
|
43
47
|
* Subtitle of the header
|
|
44
48
|
*/
|
|
45
|
-
subtitle?: string;
|
|
49
|
+
subtitle?: string | ReactElement;
|
|
50
|
+
/**
|
|
51
|
+
* Show a loading indicator in the subtitle position
|
|
52
|
+
*/
|
|
53
|
+
loadingSubtitle?: boolean;
|
|
46
54
|
/**
|
|
47
55
|
* Color palete used to render the component
|
|
48
56
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ import * as _emotion_styled from '@emotion/styled';
|
|
|
11
11
|
import * as csstype from 'csstype';
|
|
12
12
|
import * as _mui_material_OverridableComponent from '@mui/material/OverridableComponent';
|
|
13
13
|
import { SelectInputProps } from '@mui/material/Select/SelectInput';
|
|
14
|
-
import { Variant } from '@mui/material/styles/createTypography';
|
|
14
|
+
import { Variant as Variant$1 } from '@mui/material/styles/createTypography';
|
|
15
15
|
import { LoremUnit } from 'lorem-ipsum/types/src/constants/units';
|
|
16
16
|
|
|
17
17
|
interface ValueEditButtonsProps {
|
|
@@ -270,11 +270,19 @@ type HeaderProps = {
|
|
|
270
270
|
/**
|
|
271
271
|
* Title of the header
|
|
272
272
|
*/
|
|
273
|
-
title
|
|
273
|
+
title?: string | ReactElement;
|
|
274
|
+
/**
|
|
275
|
+
* Show a loading indicator in the title position
|
|
276
|
+
*/
|
|
277
|
+
loadingTitle?: boolean;
|
|
274
278
|
/**
|
|
275
279
|
* Subtitle of the header
|
|
276
280
|
*/
|
|
277
|
-
subtitle?: string;
|
|
281
|
+
subtitle?: string | ReactElement;
|
|
282
|
+
/**
|
|
283
|
+
* Show a loading indicator in the subtitle position
|
|
284
|
+
*/
|
|
285
|
+
loadingSubtitle?: boolean;
|
|
278
286
|
/**
|
|
279
287
|
* Color palete used to render the component
|
|
280
288
|
*/
|
|
@@ -318,6 +326,15 @@ type HeaderElement = ReactElement<HeaderProps, HeaderComponent>;
|
|
|
318
326
|
*/
|
|
319
327
|
declare const Header: HeaderComponent;
|
|
320
328
|
|
|
329
|
+
type HeaderTitleProps = PropsWithChildren<{
|
|
330
|
+
loading?: boolean;
|
|
331
|
+
}>;
|
|
332
|
+
declare const HeaderTitle: ({ loading, children }: HeaderTitleProps) => JSX.Element;
|
|
333
|
+
type HeaderSubtitleProps = PropsWithChildren<{
|
|
334
|
+
loading?: boolean;
|
|
335
|
+
}>;
|
|
336
|
+
declare const HeaderSubtitle: ({ loading, children }: HeaderSubtitleProps) => JSX.Element;
|
|
337
|
+
|
|
321
338
|
type BoardProps = PropsWithChildren<{
|
|
322
339
|
markdown?: string;
|
|
323
340
|
content?: string | string[];
|
|
@@ -564,9 +581,9 @@ interface ActionProps {
|
|
|
564
581
|
variant: ActionVariant;
|
|
565
582
|
title: string;
|
|
566
583
|
description?: string | ReactElement;
|
|
567
|
-
descriptionVariant?: Variant;
|
|
584
|
+
descriptionVariant?: Variant$1;
|
|
568
585
|
helperText?: string;
|
|
569
|
-
helperTextVariant?: Variant;
|
|
586
|
+
helperTextVariant?: Variant$1;
|
|
570
587
|
buttonText: string;
|
|
571
588
|
confirmable?: boolean;
|
|
572
589
|
confirmTitle?: string;
|
|
@@ -576,6 +593,13 @@ interface ActionProps {
|
|
|
576
593
|
}
|
|
577
594
|
declare const Action: ({ variant, title, description, descriptionVariant, buttonText, helperText, helperTextVariant, confirmable, passphrase, confirmTitle, confirmDescription, onAction, }: ActionProps) => JSX.Element;
|
|
578
595
|
|
|
596
|
+
type Variant = "primary" | "error" | "warning" | "success";
|
|
597
|
+
interface ActionHeaderProps {
|
|
598
|
+
variant?: Variant;
|
|
599
|
+
title: string;
|
|
600
|
+
}
|
|
601
|
+
declare const ActionHeader: ({ title, variant }: ActionHeaderProps) => JSX.Element;
|
|
602
|
+
|
|
579
603
|
interface TabData {
|
|
580
604
|
text: string;
|
|
581
605
|
icon?: ReactElement;
|
|
@@ -683,7 +707,7 @@ declare const ContentPlaceholder: ({ size, children, p }: ContentPlaceholderProp
|
|
|
683
707
|
interface LoremIpsumPlaceholderProps {
|
|
684
708
|
count?: number;
|
|
685
709
|
units?: LoremUnit;
|
|
686
|
-
variant?: Variant;
|
|
710
|
+
variant?: Variant$1;
|
|
687
711
|
}
|
|
688
712
|
declare const LoremIpsumPlaceholder: ({ count, units, variant, }: LoremIpsumPlaceholderProps) => JSX.Element;
|
|
689
713
|
|
|
@@ -1084,4 +1108,4 @@ type TabProviderProps = PropsWithChildren<{
|
|
|
1084
1108
|
}>;
|
|
1085
1109
|
declare const TabProvider: ({ children, initialValue }: TabProviderProps) => JSX.Element;
|
|
1086
1110
|
|
|
1087
|
-
export { Action, ActionProps, ActionVariant, ArrayFieldType, ArrayGroupField, ArrayInstanceType, Autocomplete, AutocompleteProps, BaseFieldType, BaseValueProps, BasicModelInstance, Board, BoardProps, BootstrapDialog, BootstrapDialogDialogProps, Bullet, BulletProps, BulletVariant, CenterContainer, CenterContainerProps, ConfirmDialog, ConfirmDialogProps, Content, ContentComponent, ContentElement, ContentPlaceholder, ContentPlaceholderProps, ContentProps, DateRangeCalendar, DateRangeCalendarProps, DateRangePicker, DateRangePickerProps, DefaultPlaceholder, DialogAction, Drawer, DrawerAppBar, DrawerAppBarComponent, DrawerAppBarElement, DrawerAppBarProps, DrawerComponent, DrawerContent, DrawerContentComponent, DrawerContentElement, DrawerContentProps, DrawerContext, DrawerContextProps, DrawerElement, DrawerHeader, DrawerItemAvatar, DrawerItemBullet, DrawerItemLabel, DrawerLayout, DrawerLayoutProps, DrawerMain, DrawerMainProps, DrawerNavigation, DrawerNavigationItem, DrawerNavigationItemCollapsable, DrawerNavigationItemLink, DrawerNavigationSection, DrawerProps, DrawerProvider, DrawerProviderProps, DrawerSection, DrawerSectionProps, DrawerSize, DrawerState, DrawerSubheader, DrawerSubheaderProps, DrawerVariant, EditInputType, EditableValueProps, EnhancedRemoteTable, EnhancedRemoteTableProps, EnhancedTable, EnhancedTableHead, ExpandableAlert, ExpandableAlertProps, FieldType, FormDialog, FormDialogProps, GroupField, GroupInstanceType, GroupValueCard, GroupValueCardProps, HeadCell, Header, HeaderAction, HeaderActionVariant, HeaderBreadcrumb, HeaderComponent, HeaderElement, HeaderLayout, HeaderLayoutError, HeaderLayoutProps, HeaderNavigationButton, HeaderPreset, HeaderProps, HeaderTab, IdleRequest, Label, LabelProps, LabelVariant, ListPanel, ListPanelContext, ListPanelContextProvider, ListPanelItem, ListPanelProps, LoadingArea, LoadingRequest, LoremIpsumPlaceholder, LoremIpsumPlaceholderProps, Markdown, MarkdownProps, Model, ModelField, ModelFieldTypes, ModelForm, ModelFormProps, ModelRouter, ModelRouterProps, Notification, NotificationCenterContext, NotificationCenterProps, NotificationCenterProvider, NotificationCenterProviderProps, NotificationCenterProviderUndefinedError, NotifyWhenValueChangesOptions, ObjectDetails, ObjectDetailsProps, Order, Placeholder, PlaceholderAction, PlaceholderIcon, PlaceholderIconArgs, PlaceholderProps, QueryContainer, QueryContainerError, QueryContainerProps, QueryContainerSuccess, RequestState, Select, SelectProps, SelectSize, SignIn, SignInProps, SingleFieldType, SkeletonCard, SkeletonCardProps, SkeletonGrid, SkeletonGridProps, SuccessRequest, TabCard, TabCardPanel, TabCardPanelProps, TabCardProps, TabContext, TabContextProvider, TabData, TabPanel, TabProvider, TableList, TableListProps, TableRowOption, TextField, TextFieldProps, UndefinedProvider, ValueBoolean, ValueBooleanProps, ValueCard, ValueCardProps, ValueDatetime, ValueDatetimeProps, ValueEditButton, ValueEditButtonProps, ValueEditButtons, ValueEditButtonsProps, ValueItem, ValueItemComponent, ValueItemElement, ValueItemProps, ValueLabel, ValueLabelProps, ValueRating, ValueRatingProps, ValueText, ValueTextProps, bulletClasses, getDrawerItemColors, getFormData, getRandomItem, labelClasses, markdownDefaultOptions, newArrayWithSize, newBreakpointsCounter, newInstanceFromValuesOrZeroValue, useDialog, useDrawer, useEditableValueDisplay, useGetDefaultThemeColor, useListPanel, useNotificationCenter, useNotifyWhenValueChanges, useTab, valueItemClasses };
|
|
1111
|
+
export { Action, ActionHeader, ActionHeaderProps, ActionProps, ActionVariant, ArrayFieldType, ArrayGroupField, ArrayInstanceType, Autocomplete, AutocompleteProps, BaseFieldType, BaseValueProps, BasicModelInstance, Board, BoardProps, BootstrapDialog, BootstrapDialogDialogProps, Bullet, BulletProps, BulletVariant, CenterContainer, CenterContainerProps, ConfirmDialog, ConfirmDialogProps, Content, ContentComponent, ContentElement, ContentPlaceholder, ContentPlaceholderProps, ContentProps, DateRangeCalendar, DateRangeCalendarProps, DateRangePicker, DateRangePickerProps, DefaultPlaceholder, DialogAction, Drawer, DrawerAppBar, DrawerAppBarComponent, DrawerAppBarElement, DrawerAppBarProps, DrawerComponent, DrawerContent, DrawerContentComponent, DrawerContentElement, DrawerContentProps, DrawerContext, DrawerContextProps, DrawerElement, DrawerHeader, DrawerItemAvatar, DrawerItemBullet, DrawerItemLabel, DrawerLayout, DrawerLayoutProps, DrawerMain, DrawerMainProps, DrawerNavigation, DrawerNavigationItem, DrawerNavigationItemCollapsable, DrawerNavigationItemLink, DrawerNavigationSection, DrawerProps, DrawerProvider, DrawerProviderProps, DrawerSection, DrawerSectionProps, DrawerSize, DrawerState, DrawerSubheader, DrawerSubheaderProps, DrawerVariant, EditInputType, EditableValueProps, EnhancedRemoteTable, EnhancedRemoteTableProps, EnhancedTable, EnhancedTableHead, ExpandableAlert, ExpandableAlertProps, FieldType, FormDialog, FormDialogProps, GroupField, GroupInstanceType, GroupValueCard, GroupValueCardProps, HeadCell, Header, HeaderAction, HeaderActionVariant, HeaderBreadcrumb, HeaderComponent, HeaderElement, HeaderLayout, HeaderLayoutError, HeaderLayoutProps, HeaderNavigationButton, HeaderPreset, HeaderProps, HeaderSubtitle, HeaderSubtitleProps, HeaderTab, HeaderTitle, HeaderTitleProps, IdleRequest, Label, LabelProps, LabelVariant, ListPanel, ListPanelContext, ListPanelContextProvider, ListPanelItem, ListPanelProps, LoadingArea, LoadingRequest, LoremIpsumPlaceholder, LoremIpsumPlaceholderProps, Markdown, MarkdownProps, Model, ModelField, ModelFieldTypes, ModelForm, ModelFormProps, ModelRouter, ModelRouterProps, Notification, NotificationCenterContext, NotificationCenterProps, NotificationCenterProvider, NotificationCenterProviderProps, NotificationCenterProviderUndefinedError, NotifyWhenValueChangesOptions, ObjectDetails, ObjectDetailsProps, Order, Placeholder, PlaceholderAction, PlaceholderIcon, PlaceholderIconArgs, PlaceholderProps, QueryContainer, QueryContainerError, QueryContainerProps, QueryContainerSuccess, RequestState, Select, SelectProps, SelectSize, SignIn, SignInProps, SingleFieldType, SkeletonCard, SkeletonCardProps, SkeletonGrid, SkeletonGridProps, SuccessRequest, TabCard, TabCardPanel, TabCardPanelProps, TabCardProps, TabContext, TabContextProvider, TabData, TabPanel, TabProvider, TableList, TableListProps, TableRowOption, TextField, TextFieldProps, UndefinedProvider, ValueBoolean, ValueBooleanProps, ValueCard, ValueCardProps, ValueDatetime, ValueDatetimeProps, ValueEditButton, ValueEditButtonProps, ValueEditButtons, ValueEditButtonsProps, ValueItem, ValueItemComponent, ValueItemElement, ValueItemProps, ValueLabel, ValueLabelProps, ValueRating, ValueRatingProps, ValueText, ValueTextProps, bulletClasses, getDrawerItemColors, getFormData, getRandomItem, labelClasses, markdownDefaultOptions, newArrayWithSize, newBreakpointsCounter, newInstanceFromValuesOrZeroValue, useDialog, useDrawer, useEditableValueDisplay, useGetDefaultThemeColor, useListPanel, useNotificationCenter, useNotifyWhenValueChanges, useTab, valueItemClasses };
|
package/package.json
CHANGED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { CircularProgress, Typography, useTheme } from "@mui/material";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { PropsWithChildren } from "react";
|
|
4
|
+
|
|
5
|
+
export type HeaderTitleProps = PropsWithChildren<{ loading?: boolean }>;
|
|
6
|
+
|
|
7
|
+
export const HeaderTitle = ({ loading, children }: HeaderTitleProps) => {
|
|
8
|
+
const { typography } = useTheme();
|
|
9
|
+
|
|
10
|
+
if (loading) {
|
|
11
|
+
return (
|
|
12
|
+
<CircularProgress color="inherit" size={typography.h4.fontSize} aria-label="title loading" />
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (typeof children === "string") {
|
|
17
|
+
return (
|
|
18
|
+
<Typography variant="h4" role="heading" aria-level={1}>
|
|
19
|
+
{children}
|
|
20
|
+
</Typography>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return <>{children}</>;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type HeaderSubtitleProps = PropsWithChildren<{ loading?: boolean }>;
|
|
28
|
+
|
|
29
|
+
export const HeaderSubtitle = ({ loading, children }: HeaderSubtitleProps) => {
|
|
30
|
+
const { typography } = useTheme();
|
|
31
|
+
|
|
32
|
+
if (loading) {
|
|
33
|
+
return (
|
|
34
|
+
<CircularProgress
|
|
35
|
+
color="inherit"
|
|
36
|
+
size={typography.body1.fontSize}
|
|
37
|
+
aria-label="subtitle loading"
|
|
38
|
+
/>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (typeof children === "string") {
|
|
43
|
+
return (
|
|
44
|
+
<Typography variant="body1" role="heading" aria-level={2}>
|
|
45
|
+
{children}
|
|
46
|
+
</Typography>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return <>{children}</>;
|
|
51
|
+
};
|
|
@@ -9,6 +9,7 @@ import { Content } from "~/components/containers";
|
|
|
9
9
|
import { Box, Typography } from "@mui/material";
|
|
10
10
|
import { TabPanel } from "~/components/navigation/tab-panel";
|
|
11
11
|
import { Route, Routes, useLocation } from "react-router-dom";
|
|
12
|
+
import { Label } from "../label";
|
|
12
13
|
|
|
13
14
|
export default {
|
|
14
15
|
title: "Components/Data Display/Header",
|
|
@@ -24,7 +25,7 @@ export const Default: Story = {
|
|
|
24
25
|
args: {
|
|
25
26
|
title: "Lorem ipsum",
|
|
26
27
|
subtitle: "Dolor sit amet",
|
|
27
|
-
preset: "
|
|
28
|
+
preset: "default",
|
|
28
29
|
breadcrumbs,
|
|
29
30
|
actions,
|
|
30
31
|
},
|
|
@@ -36,6 +37,44 @@ export const OnlyTitle: Story = {
|
|
|
36
37
|
},
|
|
37
38
|
};
|
|
38
39
|
|
|
40
|
+
export const CustomTitle: Story = {
|
|
41
|
+
args: {
|
|
42
|
+
...Default.args,
|
|
43
|
+
title: (
|
|
44
|
+
<Box display="flex" flexDirection="row" alignItems="center">
|
|
45
|
+
<Typography variant="h6">Lorem ipsum</Typography>
|
|
46
|
+
<Label variant="primary" text="4 items" sx={{ ml: 1 }} />
|
|
47
|
+
</Box>
|
|
48
|
+
),
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const TitleLoading: Story = {
|
|
53
|
+
args: {
|
|
54
|
+
...Default.args,
|
|
55
|
+
loadingTitle: true,
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const CustomSubtitle: Story = {
|
|
60
|
+
args: {
|
|
61
|
+
...Default.args,
|
|
62
|
+
subtitle: (
|
|
63
|
+
<Box display="flex" flexDirection="row" alignItems="center">
|
|
64
|
+
<Typography variant="body2">Dolor sit amet</Typography>
|
|
65
|
+
<Label variant="error" text="since yesterday" sx={{ ml: 1 }} />
|
|
66
|
+
</Box>
|
|
67
|
+
),
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export const SubtitleLoading: Story = {
|
|
72
|
+
args: {
|
|
73
|
+
...Default.args,
|
|
74
|
+
loadingSubtitle: true,
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
|
|
39
78
|
export const ColorInherit: Story = {
|
|
40
79
|
args: {
|
|
41
80
|
title: "Lorem ipsum",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import React, { ReactElement } from "react";
|
|
2
2
|
import { render, screen } from "~/tests/testing-library";
|
|
3
3
|
import userEvent from "@testing-library/user-event";
|
|
4
4
|
import { Header } from "./header";
|
|
@@ -13,12 +13,17 @@ import {
|
|
|
13
13
|
import { breadcrumbs, actions as actionsData, tabs, linkedTabs } from "./header.dummy";
|
|
14
14
|
import { TabProvider } from "../../../providers";
|
|
15
15
|
import { WithLinkedTabs, WithPanelTabs } from "./header.stories";
|
|
16
|
+
import { Typography } from "@mui/material";
|
|
17
|
+
import { Box } from "@mui/system";
|
|
18
|
+
import { Label } from "../label";
|
|
16
19
|
|
|
17
20
|
const actions = actionsData.map((a) => ({ ...a, onClick: a.onClick && vi.fn() }));
|
|
18
21
|
|
|
19
22
|
const renderInstance = ({
|
|
20
23
|
title = "Lorem ipsum",
|
|
24
|
+
loadingTitle,
|
|
21
25
|
subtitle,
|
|
26
|
+
loadingSubtitle,
|
|
22
27
|
preset = "default",
|
|
23
28
|
breadcrumbs,
|
|
24
29
|
actions,
|
|
@@ -27,8 +32,10 @@ const renderInstance = ({
|
|
|
27
32
|
selectedTab,
|
|
28
33
|
navigationButton,
|
|
29
34
|
}: {
|
|
30
|
-
title?: string;
|
|
31
|
-
subtitle?: string |
|
|
35
|
+
title?: string | ReactElement;
|
|
36
|
+
subtitle?: string | ReactElement;
|
|
37
|
+
loadingTitle?: boolean;
|
|
38
|
+
loadingSubtitle?: boolean;
|
|
32
39
|
preset?: HeaderPreset;
|
|
33
40
|
breadcrumbs?: HeaderBreadcrumb[];
|
|
34
41
|
actions?: HeaderAction[];
|
|
@@ -41,7 +48,9 @@ const renderInstance = ({
|
|
|
41
48
|
<TabProvider initialValue={selectedTab}>
|
|
42
49
|
<Header
|
|
43
50
|
title={title}
|
|
51
|
+
loadingTitle={loadingTitle}
|
|
44
52
|
subtitle={subtitle}
|
|
53
|
+
loadingSubtitle={loadingSubtitle}
|
|
45
54
|
preset={preset}
|
|
46
55
|
breadcrumbs={breadcrumbs}
|
|
47
56
|
actions={actions}
|
|
@@ -56,14 +65,39 @@ const renderInstance = ({
|
|
|
56
65
|
};
|
|
57
66
|
|
|
58
67
|
describe("Header", () => {
|
|
59
|
-
|
|
60
|
-
|
|
68
|
+
describe("title", () => {
|
|
69
|
+
it("should render the title", () => {
|
|
70
|
+
renderInstance({ title: "Lorem ipsum" });
|
|
61
71
|
|
|
62
|
-
|
|
72
|
+
expect(screen.getByRole("heading", { level: 1, name: /lorem ipsum/i })).toBeInTheDocument();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it("should render the custom title", () => {
|
|
76
|
+
renderInstance({
|
|
77
|
+
title: (
|
|
78
|
+
<Box display="flex" flexDirection="row" alignItems="center">
|
|
79
|
+
<Typography variant="h6">custom title</Typography>
|
|
80
|
+
<Label variant="primary" text="4 items" sx={{ ml: 1 }} />
|
|
81
|
+
</Box>
|
|
82
|
+
),
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
expect(screen.getByRole("heading", { level: 6, name: /custom title/i })).toBeVisible();
|
|
86
|
+
expect(screen.getByText(/4 items/i)).toBeVisible();
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it("should render a loading indicator if title is loading", () => {
|
|
90
|
+
renderInstance({ title: "Lorem ipsum", loadingTitle: true });
|
|
91
|
+
|
|
92
|
+
expect(
|
|
93
|
+
screen.queryByRole("heading", { level: 1, name: /lorem ipsum/i }),
|
|
94
|
+
).not.toBeInTheDocument();
|
|
95
|
+
expect(screen.queryByRole("progressbar", { name: /title loading/i })).toBeInTheDocument();
|
|
96
|
+
});
|
|
63
97
|
});
|
|
64
98
|
|
|
65
99
|
describe("subtitle", () => {
|
|
66
|
-
it("should
|
|
100
|
+
it("should render when is set", () => {
|
|
67
101
|
renderInstance({ subtitle: "sit amet" });
|
|
68
102
|
|
|
69
103
|
expect(screen.queryByRole("heading", { level: 2, name: /sit amet/i })).toBeInTheDocument();
|
|
@@ -74,6 +108,27 @@ describe("Header", () => {
|
|
|
74
108
|
|
|
75
109
|
expect(screen.queryByRole("heading", { level: 2 })).not.toBeInTheDocument();
|
|
76
110
|
});
|
|
111
|
+
|
|
112
|
+
it("should render the custom title", () => {
|
|
113
|
+
renderInstance({
|
|
114
|
+
subtitle: (
|
|
115
|
+
<Box display="flex" flexDirection="row" alignItems="center">
|
|
116
|
+
<Typography variant="body2">Dolor sit amet</Typography>
|
|
117
|
+
<Label variant="error" text="since yesterday" sx={{ ml: 1 }} />
|
|
118
|
+
</Box>
|
|
119
|
+
),
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
expect(screen.getByText(/dolor sit amet/i)).toBeVisible();
|
|
123
|
+
expect(screen.getByText(/since yesterday/i)).toBeVisible();
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it("should render a loading indicator if title is loading", () => {
|
|
127
|
+
renderInstance({ subtitle: "sit amet", loadingSubtitle: true });
|
|
128
|
+
|
|
129
|
+
expect(screen.queryByRole("heading", { level: 2 })).not.toBeInTheDocument();
|
|
130
|
+
expect(screen.queryByRole("progressbar", { name: /subtitle loading/i })).toBeInTheDocument();
|
|
131
|
+
});
|
|
77
132
|
});
|
|
78
133
|
|
|
79
134
|
describe("breadcrumbs", () => {
|
|
@@ -14,14 +14,17 @@ import { useGetDefaultThemeColor } from "../../../utils";
|
|
|
14
14
|
import { HeaderComponent, HeaderPreset, HeaderProps } from "./header.types";
|
|
15
15
|
import { useTab } from "~/providers";
|
|
16
16
|
import { useLocation } from "react-router-dom";
|
|
17
|
+
import { HeaderSubtitle, HeaderTitle } from "./header-title";
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* Section used to explain give basic information about the page
|
|
20
21
|
* and put the main actions
|
|
21
22
|
*/
|
|
22
23
|
export const Header: HeaderComponent = ({
|
|
23
|
-
title,
|
|
24
|
+
title = "",
|
|
25
|
+
loadingTitle,
|
|
24
26
|
subtitle,
|
|
27
|
+
loadingSubtitle,
|
|
25
28
|
preset = "default",
|
|
26
29
|
actionsVariant = "outlined",
|
|
27
30
|
breadcrumbs,
|
|
@@ -93,13 +96,9 @@ export const Header: HeaderComponent = ({
|
|
|
93
96
|
))}
|
|
94
97
|
</Breadcrumbs>
|
|
95
98
|
)}
|
|
96
|
-
<
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
{subtitle && (
|
|
100
|
-
<Typography variant="body1" role="heading" aria-level={2}>
|
|
101
|
-
{subtitle}
|
|
102
|
-
</Typography>
|
|
99
|
+
<HeaderTitle loading={loadingTitle}>{title}</HeaderTitle>
|
|
100
|
+
{(subtitle || loadingSubtitle) && (
|
|
101
|
+
<HeaderSubtitle loading={loadingSubtitle}>{subtitle}</HeaderSubtitle>
|
|
103
102
|
)}
|
|
104
103
|
</Box>
|
|
105
104
|
{actions && (
|
|
@@ -44,11 +44,19 @@ export type HeaderProps = {
|
|
|
44
44
|
/**
|
|
45
45
|
* Title of the header
|
|
46
46
|
*/
|
|
47
|
-
title
|
|
47
|
+
title?: string | ReactElement;
|
|
48
|
+
/**
|
|
49
|
+
* Show a loading indicator in the title position
|
|
50
|
+
*/
|
|
51
|
+
loadingTitle?: boolean;
|
|
48
52
|
/**
|
|
49
53
|
* Subtitle of the header
|
|
50
54
|
*/
|
|
51
|
-
subtitle?: string;
|
|
55
|
+
subtitle?: string | ReactElement;
|
|
56
|
+
/**
|
|
57
|
+
* Show a loading indicator in the subtitle position
|
|
58
|
+
*/
|
|
59
|
+
loadingSubtitle?: boolean;
|
|
52
60
|
/**
|
|
53
61
|
* Color palete used to render the component
|
|
54
62
|
*/
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { render, screen } from "@testing-library/react";
|
|
2
|
+
import { ActionHeader } from "./action-header";
|
|
3
|
+
import React from "react";
|
|
4
|
+
|
|
5
|
+
describe("ActionHeader", () => {
|
|
6
|
+
it("should render the title", () => {
|
|
7
|
+
render(<ActionHeader title="Lorem ipsum" />);
|
|
8
|
+
|
|
9
|
+
expect(screen.getByRole("heading", { name: /lorem ipsum/i, level: 4 }));
|
|
10
|
+
});
|
|
11
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Typography, useTheme } from "@mui/material";
|
|
2
|
+
import React from "react";
|
|
3
|
+
|
|
4
|
+
type Variant = "primary" | "error" | "warning" | "success";
|
|
5
|
+
export interface ActionHeaderProps {
|
|
6
|
+
variant?: Variant;
|
|
7
|
+
title: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const ActionHeader = ({ title, variant = "primary" }: ActionHeaderProps) => {
|
|
11
|
+
const { palette } = useTheme();
|
|
12
|
+
|
|
13
|
+
const titleColor: Record<Variant, string | undefined> = {
|
|
14
|
+
primary: undefined,
|
|
15
|
+
error: "error",
|
|
16
|
+
warning: palette.warning.main,
|
|
17
|
+
success: palette.success.main,
|
|
18
|
+
};
|
|
19
|
+
return (
|
|
20
|
+
<Typography
|
|
21
|
+
color={titleColor[variant]}
|
|
22
|
+
variant="h4"
|
|
23
|
+
pb={1}
|
|
24
|
+
borderBottom={1}
|
|
25
|
+
borderColor="grey.300"
|
|
26
|
+
>
|
|
27
|
+
{title}
|
|
28
|
+
</Typography>
|
|
29
|
+
);
|
|
30
|
+
};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Grid, Button, Typography,
|
|
1
|
+
import { Grid, Button, Typography, DialogContentText } from "@mui/material";
|
|
2
2
|
import { Variant } from "@mui/material/styles/createTypography";
|
|
3
3
|
import React, { ReactElement } from "react";
|
|
4
4
|
import { ConfirmDialog, useDialog } from "~/components/dialogs";
|
|
5
|
+
import { ActionHeader } from "./action-header";
|
|
5
6
|
|
|
6
7
|
export type ActionVariant = "primary" | "error" | "warning" | "success";
|
|
7
8
|
|
|
@@ -35,7 +36,6 @@ export const Action = ({
|
|
|
35
36
|
onAction,
|
|
36
37
|
}: ActionProps) => {
|
|
37
38
|
const { isOpen, open, close } = useDialog();
|
|
38
|
-
const { palette } = useTheme();
|
|
39
39
|
|
|
40
40
|
const handleClickActionButton = () => {
|
|
41
41
|
if (confirmable) {
|
|
@@ -50,26 +50,11 @@ export const Action = ({
|
|
|
50
50
|
close;
|
|
51
51
|
};
|
|
52
52
|
|
|
53
|
-
const titleColor: Record<ActionVariant, string | undefined> = {
|
|
54
|
-
primary: undefined,
|
|
55
|
-
error: "error",
|
|
56
|
-
warning: palette.warning.main,
|
|
57
|
-
success: palette.success.main,
|
|
58
|
-
};
|
|
59
|
-
|
|
60
53
|
return (
|
|
61
54
|
<>
|
|
62
55
|
<Grid container spacing={1}>
|
|
63
56
|
<Grid item xs={12} mb={2}>
|
|
64
|
-
<
|
|
65
|
-
color={titleColor[variant]}
|
|
66
|
-
variant="h4"
|
|
67
|
-
pb={1}
|
|
68
|
-
borderBottom={1}
|
|
69
|
-
borderColor="grey.300"
|
|
70
|
-
>
|
|
71
|
-
{title}
|
|
72
|
-
</Typography>
|
|
57
|
+
<ActionHeader title={title} />
|
|
73
58
|
</Grid>
|
|
74
59
|
{description && (
|
|
75
60
|
<Grid item xs={12}>
|