@pautena/react-design-system 0.11.1 → 0.12.0
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 +9 -0
- package/dist/cjs/types/components/inputs/action/action.d.ts +2 -1
- 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 +9 -0
- package/dist/esm/types/components/inputs/action/action.d.ts +2 -1
- package/dist/esm/types/components/inputs/action/index.d.ts +1 -0
- package/dist/index.d.ts +32 -6
- 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 +37 -0
- package/src/components/inputs/action/action.tsx +5 -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
|
*/
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Variant } from "@mui/material/styles/createTypography";
|
|
2
|
+
type ActionVariant = "primary" | "error" | "warning" | "success";
|
|
3
|
+
export interface ActionHeaderProps {
|
|
4
|
+
variant?: ActionVariant;
|
|
5
|
+
title: string;
|
|
6
|
+
titleVariant?: Extract<Variant, "h4" | "h5" | "h6">;
|
|
7
|
+
}
|
|
8
|
+
export declare const ActionHeader: ({ title, titleVariant, variant, }: ActionHeaderProps) => JSX.Element;
|
|
9
|
+
export {};
|
|
@@ -4,6 +4,7 @@ export type ActionVariant = "primary" | "error" | "warning" | "success";
|
|
|
4
4
|
export interface ActionProps {
|
|
5
5
|
variant: ActionVariant;
|
|
6
6
|
title: string;
|
|
7
|
+
titleVariant?: Extract<Variant, "h4" | "h5" | "h6">;
|
|
7
8
|
description?: string | ReactElement;
|
|
8
9
|
descriptionVariant?: Variant;
|
|
9
10
|
helperText?: string;
|
|
@@ -15,4 +16,4 @@ export interface ActionProps {
|
|
|
15
16
|
passphrase?: string;
|
|
16
17
|
onAction: () => void;
|
|
17
18
|
}
|
|
18
|
-
export declare const Action: ({ variant, title, description, descriptionVariant, buttonText, helperText, helperTextVariant, confirmable, passphrase, confirmTitle, confirmDescription, onAction, }: ActionProps) => JSX.Element;
|
|
19
|
+
export declare const Action: ({ variant, title, titleVariant, description, descriptionVariant, buttonText, helperText, helperTextVariant, confirmable, passphrase, confirmTitle, confirmDescription, onAction, }: ActionProps) => JSX.Element;
|
package/dist/index.d.ts
CHANGED
|
@@ -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[];
|
|
@@ -559,10 +576,11 @@ type TextFieldProps = TextFieldProps$1 & {
|
|
|
559
576
|
};
|
|
560
577
|
declare const TextField: ({ id: overrideId, label, InputLabelProps, InputProps, fetching, loading, helperText, hexColor, size, fullWidth, sx, ...rest }: TextFieldProps) => JSX.Element;
|
|
561
578
|
|
|
562
|
-
type ActionVariant = "primary" | "error" | "warning" | "success";
|
|
579
|
+
type ActionVariant$1 = "primary" | "error" | "warning" | "success";
|
|
563
580
|
interface ActionProps {
|
|
564
|
-
variant: ActionVariant;
|
|
581
|
+
variant: ActionVariant$1;
|
|
565
582
|
title: string;
|
|
583
|
+
titleVariant?: Extract<Variant, "h4" | "h5" | "h6">;
|
|
566
584
|
description?: string | ReactElement;
|
|
567
585
|
descriptionVariant?: Variant;
|
|
568
586
|
helperText?: string;
|
|
@@ -574,7 +592,15 @@ interface ActionProps {
|
|
|
574
592
|
passphrase?: string;
|
|
575
593
|
onAction: () => void;
|
|
576
594
|
}
|
|
577
|
-
declare const Action: ({ variant, title, description, descriptionVariant, buttonText, helperText, helperTextVariant, confirmable, passphrase, confirmTitle, confirmDescription, onAction, }: ActionProps) => JSX.Element;
|
|
595
|
+
declare const Action: ({ variant, title, titleVariant, description, descriptionVariant, buttonText, helperText, helperTextVariant, confirmable, passphrase, confirmTitle, confirmDescription, onAction, }: ActionProps) => JSX.Element;
|
|
596
|
+
|
|
597
|
+
type ActionVariant = "primary" | "error" | "warning" | "success";
|
|
598
|
+
interface ActionHeaderProps {
|
|
599
|
+
variant?: ActionVariant;
|
|
600
|
+
title: string;
|
|
601
|
+
titleVariant?: Extract<Variant, "h4" | "h5" | "h6">;
|
|
602
|
+
}
|
|
603
|
+
declare const ActionHeader: ({ title, titleVariant, variant, }: ActionHeaderProps) => JSX.Element;
|
|
578
604
|
|
|
579
605
|
interface TabData {
|
|
580
606
|
text: string;
|
|
@@ -1084,4 +1110,4 @@ type TabProviderProps = PropsWithChildren<{
|
|
|
1084
1110
|
}>;
|
|
1085
1111
|
declare const TabProvider: ({ children, initialValue }: TabProviderProps) => JSX.Element;
|
|
1086
1112
|
|
|
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 };
|
|
1113
|
+
export { Action, ActionHeader, ActionHeaderProps, ActionProps, ActionVariant$1 as 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,37 @@
|
|
|
1
|
+
import { Typography, useTheme } from "@mui/material";
|
|
2
|
+
import { Variant } from "@mui/material/styles/createTypography";
|
|
3
|
+
import React from "react";
|
|
4
|
+
|
|
5
|
+
type ActionVariant = "primary" | "error" | "warning" | "success";
|
|
6
|
+
|
|
7
|
+
export interface ActionHeaderProps {
|
|
8
|
+
variant?: ActionVariant;
|
|
9
|
+
title: string;
|
|
10
|
+
titleVariant?: Extract<Variant, "h4" | "h5" | "h6">;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const ActionHeader = ({
|
|
14
|
+
title,
|
|
15
|
+
titleVariant = "h4",
|
|
16
|
+
variant = "primary",
|
|
17
|
+
}: ActionHeaderProps) => {
|
|
18
|
+
const { palette } = useTheme();
|
|
19
|
+
|
|
20
|
+
const titleColor: Record<ActionVariant, string | undefined> = {
|
|
21
|
+
primary: undefined,
|
|
22
|
+
error: "error",
|
|
23
|
+
warning: palette.warning.main,
|
|
24
|
+
success: palette.success.main,
|
|
25
|
+
};
|
|
26
|
+
return (
|
|
27
|
+
<Typography
|
|
28
|
+
color={titleColor[variant]}
|
|
29
|
+
variant={titleVariant}
|
|
30
|
+
pb={1}
|
|
31
|
+
borderBottom={1}
|
|
32
|
+
borderColor="grey.300"
|
|
33
|
+
>
|
|
34
|
+
{title}
|
|
35
|
+
</Typography>
|
|
36
|
+
);
|
|
37
|
+
};
|
|
@@ -1,13 +1,15 @@
|
|
|
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
|
|
|
8
9
|
export interface ActionProps {
|
|
9
10
|
variant: ActionVariant;
|
|
10
11
|
title: string;
|
|
12
|
+
titleVariant?: Extract<Variant, "h4" | "h5" | "h6">;
|
|
11
13
|
description?: string | ReactElement;
|
|
12
14
|
descriptionVariant?: Variant;
|
|
13
15
|
helperText?: string;
|
|
@@ -23,6 +25,7 @@ export interface ActionProps {
|
|
|
23
25
|
export const Action = ({
|
|
24
26
|
variant = "primary",
|
|
25
27
|
title,
|
|
28
|
+
titleVariant = "h4",
|
|
26
29
|
description,
|
|
27
30
|
descriptionVariant = "body2",
|
|
28
31
|
buttonText,
|
|
@@ -35,7 +38,6 @@ export const Action = ({
|
|
|
35
38
|
onAction,
|
|
36
39
|
}: ActionProps) => {
|
|
37
40
|
const { isOpen, open, close } = useDialog();
|
|
38
|
-
const { palette } = useTheme();
|
|
39
41
|
|
|
40
42
|
const handleClickActionButton = () => {
|
|
41
43
|
if (confirmable) {
|
|
@@ -50,26 +52,11 @@ export const Action = ({
|
|
|
50
52
|
close;
|
|
51
53
|
};
|
|
52
54
|
|
|
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
55
|
return (
|
|
61
56
|
<>
|
|
62
57
|
<Grid container spacing={1}>
|
|
63
58
|
<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>
|
|
59
|
+
<ActionHeader title={title} titleVariant={titleVariant} />
|
|
73
60
|
</Grid>
|
|
74
61
|
{description && (
|
|
75
62
|
<Grid item xs={12}>
|