@pautena/react-design-system 0.1.2 → 0.1.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.
Files changed (175) hide show
  1. package/package.json +1 -1
  2. package/src/components/app-bar/app-bar.stories.tsx +54 -0
  3. package/src/components/app-bar/app-bar.test.tsx +142 -0
  4. package/src/components/app-bar/app-bar.tsx +150 -0
  5. package/src/components/app-bar/app-bar.types.ts +17 -0
  6. package/src/components/app-bar/index.ts +3 -0
  7. package/src/components/app-bar/mini-app-bar/index.ts +1 -0
  8. package/src/components/app-bar/mini-app-bar/mini-app-bar.tsx +31 -0
  9. package/src/components/bullet/bullet.stories.tsx +43 -0
  10. package/src/components/bullet/bullet.test.tsx +24 -0
  11. package/src/components/bullet/bullet.tsx +30 -0
  12. package/src/components/bullet/index.ts +1 -0
  13. package/src/components/center-container/center-container.stories.tsx +50 -0
  14. package/src/components/center-container/center-container.test.tsx +16 -0
  15. package/src/components/center-container/center-container.tsx +32 -0
  16. package/src/components/center-container/index.ts +1 -0
  17. package/src/components/content/content.stories.tsx +23 -0
  18. package/src/components/content/content.test.tsx +26 -0
  19. package/src/components/content/content.tsx +11 -0
  20. package/src/components/content/content.types.ts +5 -0
  21. package/src/components/content/index.ts +2 -0
  22. package/src/components/drawer/__snapshots__/drawer.test.tsx.snap +20 -0
  23. package/src/components/drawer/drawer.context.ts +20 -0
  24. package/src/components/drawer/drawer.mixins.ts +24 -0
  25. package/src/components/drawer/drawer.mock.tsx +100 -0
  26. package/src/components/drawer/drawer.provider.tsx +23 -0
  27. package/src/components/drawer/drawer.test.tsx +97 -0
  28. package/src/components/drawer/drawer.tsx +30 -0
  29. package/src/components/drawer/drawer.types.ts +53 -0
  30. package/src/components/drawer/index.ts +5 -0
  31. package/src/components/drawer/mini-drawer/index.ts +1 -0
  32. package/src/components/drawer/mini-drawer/mini-drawer.stories.tsx +34 -0
  33. package/src/components/drawer/mini-drawer/mini-drawer.tsx +67 -0
  34. package/src/components/drawer-content/drawer-content.stories.tsx +29 -0
  35. package/src/components/drawer-content/drawer-content.test.tsx +34 -0
  36. package/src/components/drawer-content/drawer-content.tsx +18 -0
  37. package/src/components/drawer-content/index.ts +1 -0
  38. package/src/components/drawer-item/drawer-item.stories.tsx +62 -0
  39. package/src/components/drawer-item/drawer-item.test.tsx +119 -0
  40. package/src/components/drawer-item/drawer-item.tsx +71 -0
  41. package/src/components/drawer-item/index.ts +1 -0
  42. package/src/components/drawer-section/drawer-section.mock.tsx +39 -0
  43. package/src/components/drawer-section/drawer-section.stories.tsx +28 -0
  44. package/src/components/drawer-section/drawer-section.test.tsx +44 -0
  45. package/src/components/drawer-section/drawer-section.tsx +40 -0
  46. package/src/components/drawer-section/index.ts +1 -0
  47. package/src/components/header/header.dummy.ts +55 -0
  48. package/src/components/header/header.stories.tsx +116 -0
  49. package/src/components/header/header.test.tsx +169 -0
  50. package/src/components/header/header.tsx +121 -0
  51. package/src/components/header/header.types.ts +61 -0
  52. package/src/components/header/index.ts +2 -0
  53. package/src/components/index.ts +18 -0
  54. package/src/components/label/index.ts +1 -0
  55. package/src/components/label/label.stories.tsx +49 -0
  56. package/src/components/label/label.test.tsx +30 -0
  57. package/src/components/label/label.tsx +60 -0
  58. package/src/components/link/index.ts +1 -0
  59. package/src/components/link/link.tsx +17 -0
  60. package/src/components/loading-area/index.ts +1 -0
  61. package/src/components/loading-area/loading-area.stories.tsx +17 -0
  62. package/src/components/loading-area/loading-area.test.tsx +11 -0
  63. package/src/components/loading-area/loading-area.tsx +13 -0
  64. package/src/components/placeholder/index.ts +1 -0
  65. package/src/components/placeholder/placeholder.mock.ts +15 -0
  66. package/src/components/placeholder/placeholder.stories.tsx +44 -0
  67. package/src/components/placeholder/placeholder.test.tsx +76 -0
  68. package/src/components/placeholder/placeholder.tsx +75 -0
  69. package/src/components/query-container/index.ts +1 -0
  70. package/src/components/query-container/query-container.stories.tsx +68 -0
  71. package/src/components/query-container/query-container.test.tsx +95 -0
  72. package/src/components/query-container/query-container.tsx +71 -0
  73. package/src/components/sign-in/index.ts +1 -0
  74. package/src/components/sign-in/sign-in.stories.tsx +36 -0
  75. package/src/components/sign-in/sign-in.test.tsx +95 -0
  76. package/src/components/sign-in/sign-in.tsx +97 -0
  77. package/src/components/tab/index.ts +2 -0
  78. package/src/components/tab/tab-card/index.ts +1 -0
  79. package/src/components/tab/tab-card/tab-card.dummy.tsx +30 -0
  80. package/src/components/tab/tab-card/tab-card.stories.tsx +22 -0
  81. package/src/components/tab/tab-card/tab-card.test.tsx +53 -0
  82. package/src/components/tab/tab-card/tab-card.tsx +27 -0
  83. package/src/components/tab/tab-panel/index.ts +1 -0
  84. package/src/components/tab/tab-panel/tab-panel.test.tsx +26 -0
  85. package/src/components/tab/tab-panel/tab-panel.tsx +27 -0
  86. package/src/components/table/enhanced-remote-table/enhanced-remote-table.mock.tsx +27 -0
  87. package/src/components/table/enhanced-remote-table/enhanced-remote-table.stories.tsx +24 -0
  88. package/src/components/table/enhanced-remote-table/enhanced-remote-table.test.tsx +77 -0
  89. package/src/components/table/enhanced-remote-table/enhanced-remote-table.tsx +74 -0
  90. package/src/components/table/enhanced-remote-table/index.ts +1 -0
  91. package/src/components/table/enhanced-table/enhanced-table-head.tsx +58 -0
  92. package/src/components/table/enhanced-table/enhanced-table.mock.tsx +93 -0
  93. package/src/components/table/enhanced-table/enhanced-table.stories.tsx +21 -0
  94. package/src/components/table/enhanced-table/enhanced-table.test.tsx +107 -0
  95. package/src/components/table/enhanced-table/enhanced-table.tsx +136 -0
  96. package/src/components/table/enhanced-table/index.ts +2 -0
  97. package/src/components/table/index.ts +2 -0
  98. package/src/components/table-list/index.ts +1 -0
  99. package/src/components/table-list/table-list.stories.tsx +75 -0
  100. package/src/components/table-list/table-list.test.tsx +284 -0
  101. package/src/components/table-list/table-list.tsx +127 -0
  102. package/src/components/value-displays/group-value-card/group-value-card.mock.tsx +35 -0
  103. package/src/components/value-displays/group-value-card/group-value-card.stories.tsx +26 -0
  104. package/src/components/value-displays/group-value-card/group-value-card.test.tsx +58 -0
  105. package/src/components/value-displays/group-value-card/group-value-card.tsx +63 -0
  106. package/src/components/value-displays/group-value-card/index.ts +1 -0
  107. package/src/components/value-displays/index.ts +4 -0
  108. package/src/components/value-displays/value-boolean/index.ts +1 -0
  109. package/src/components/value-displays/value-boolean/value-boolean.stories.tsx +25 -0
  110. package/src/components/value-displays/value-boolean/value-boolean.test.tsx +27 -0
  111. package/src/components/value-displays/value-boolean/value-boolean.tsx +33 -0
  112. package/src/components/value-displays/value-card/index.ts +1 -0
  113. package/src/components/value-displays/value-card/value-card.stories.tsx +22 -0
  114. package/src/components/value-displays/value-card/value-card.test.tsx +18 -0
  115. package/src/components/value-displays/value-card/value-card.tsx +12 -0
  116. package/src/components/value-displays/value-text/index.ts +1 -0
  117. package/src/components/value-displays/value-text/value-test.test.tsx +21 -0
  118. package/src/components/value-displays/value-text/value-text.stories.tsx +26 -0
  119. package/src/components/value-displays/value-text/value-text.tsx +32 -0
  120. package/src/generators/generators.mock.ts +238 -0
  121. package/src/generators/generators.model.ts +46 -0
  122. package/src/generators/index.ts +4 -0
  123. package/src/generators/model-form/index.ts +1 -0
  124. package/src/generators/model-form/model-form.stories.tsx +30 -0
  125. package/src/generators/model-form/model-form.test.tsx +100 -0
  126. package/src/generators/model-form/model-form.tsx +97 -0
  127. package/src/generators/model-router/index.ts +1 -0
  128. package/src/generators/model-router/model-router.test.tsx +666 -0
  129. package/src/generators/model-router/model-router.tsx +29 -0
  130. package/src/generators/model-router/model-router.types.ts +14 -0
  131. package/src/generators/model-router/screens/add-screen.tsx +69 -0
  132. package/src/generators/model-router/screens/details-screen.tsx +62 -0
  133. package/src/generators/model-router/screens/index.ts +4 -0
  134. package/src/generators/model-router/screens/list-screen.tsx +110 -0
  135. package/src/generators/model-router/screens/screens.types.ts +13 -0
  136. package/src/generators/model-router/screens/update-screen.tsx +96 -0
  137. package/src/generators/model-router/stories/details-screen.stories.tsx +38 -0
  138. package/src/generators/model-router/stories/list-screen.stories.tsx +45 -0
  139. package/src/generators/model-router/stories/model-router.stories.tsx +164 -0
  140. package/src/generators/model-router/stories/templates.tsx +39 -0
  141. package/src/generators/object-details/index.ts +1 -0
  142. package/src/generators/object-details/object-details.stories.tsx +20 -0
  143. package/src/generators/object-details/object-details.test.tsx +21 -0
  144. package/src/generators/object-details/object-details.tsx +76 -0
  145. package/src/index.ts +4 -0
  146. package/src/layouts/app-bar-with-drawer-layout/app-bar-with-drawer-layout.stories.tsx +28 -0
  147. package/src/layouts/app-bar-with-drawer-layout/app-bar-with-drawer-layout.test.tsx +30 -0
  148. package/src/layouts/app-bar-with-drawer-layout/app-bar-with-drawer-layout.tsx +37 -0
  149. package/src/layouts/app-bar-with-drawer-layout/index.ts +1 -0
  150. package/src/layouts/header-layout/header-layout.stories.tsx +204 -0
  151. package/src/layouts/header-layout/header-layout.test.tsx +37 -0
  152. package/src/layouts/header-layout/header-layout.tsx +23 -0
  153. package/src/layouts/header-layout/index.ts +1 -0
  154. package/src/layouts/index.ts +2 -0
  155. package/src/providers/index.ts +2 -0
  156. package/src/providers/notification-center/index.ts +2 -0
  157. package/src/providers/notification-center/notification-center.context.ts +37 -0
  158. package/src/providers/notification-center/notification-center.provider.tsx +51 -0
  159. package/src/providers/notification-center/notification-center.stories.tsx +52 -0
  160. package/src/providers/notification-center/notification-center.test.tsx +112 -0
  161. package/src/providers/tab-provider/index.ts +2 -0
  162. package/src/providers/tab-provider/tab-provider.context.ts +8 -0
  163. package/src/providers/tab-provider/tab-provider.provider.tsx +13 -0
  164. package/src/storybook.tsx +90 -0
  165. package/src/tests/assertions.ts +76 -0
  166. package/src/tests/components.tsx +60 -0
  167. package/src/tests/content-placeholder.stories.tsx +16 -0
  168. package/src/tests/index.ts +3 -0
  169. package/src/tests/skeleton-card.stories.tsx +18 -0
  170. package/src/tests/testing-library.tsx +65 -0
  171. package/src/utils/arrays.test.ts +9 -0
  172. package/src/utils/arrays.ts +7 -0
  173. package/src/utils/index.ts +2 -0
  174. package/src/utils/theme.ts +11 -0
  175. package/.prettierrc.js +0 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pautena/react-design-system",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "My custom design system on top of MUI",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -0,0 +1,54 @@
1
+ import React from "react";
2
+ import { ComponentMeta } from "@storybook/react";
3
+ import { createTemplate } from "../../storybook";
4
+ import { AppBar } from "./app-bar";
5
+ import { DrawerProvider } from "../drawer";
6
+
7
+ export default {
8
+ title: "AppBars/AppBar",
9
+ component: AppBar,
10
+ parameters: {
11
+ layout: "fullscreen",
12
+ },
13
+ } as ComponentMeta<typeof AppBar>;
14
+
15
+ const Template = createTemplate((args) => {
16
+ return (
17
+ <DrawerProvider>
18
+ <AppBar {...args} />
19
+ </DrawerProvider>
20
+ );
21
+ });
22
+
23
+ export const Default = Template.bind({});
24
+ Default.args = {
25
+ title: "Lorem ipsum",
26
+ menu: true,
27
+ };
28
+
29
+ export const WithSearch = Template.bind({});
30
+ WithSearch.args = {
31
+ title: "Lorem ipsum",
32
+ search: true,
33
+ menu: true,
34
+ };
35
+
36
+ export const WithoutTitle = Template.bind({});
37
+ WithoutTitle.args = {
38
+ menu: true,
39
+ };
40
+
41
+ export const WihtoutMenu = Template.bind({});
42
+ WihtoutMenu.args = {
43
+ title: "Lorem ipsum",
44
+ menu: false,
45
+ };
46
+
47
+ export const WithProfile = Template.bind({});
48
+ WithProfile.args = {
49
+ title: "Lorem ipsum",
50
+ menu: true,
51
+ profile: {
52
+ name: "Test user",
53
+ },
54
+ };
@@ -0,0 +1,142 @@
1
+ import React from "react";
2
+ import { fireEvent, render, screen } from "../../tests";
3
+ import { AppBar } from "./app-bar";
4
+ import { DrawerProvider } from "../drawer";
5
+ import { AppBarProfile } from "./app-bar.types";
6
+ import userEvent from "@testing-library/user-event";
7
+
8
+ const profile: AppBarProfile = {
9
+ name: "John Smith",
10
+ };
11
+
12
+ describe("AppBar", () => {
13
+ const renderComponent = ({
14
+ search,
15
+ title,
16
+ menu,
17
+ initialOpen,
18
+ profile,
19
+ }: {
20
+ title?: string;
21
+ search?: boolean;
22
+ menu?: boolean;
23
+ initialOpen?: boolean;
24
+ profile?: AppBarProfile;
25
+ } = {}) => {
26
+ const onClickSignOut = jest.fn();
27
+ const instance = render(
28
+ <DrawerProvider initialOpen={initialOpen}>
29
+ <AppBar
30
+ title={title}
31
+ menu={menu}
32
+ search={search}
33
+ profile={profile}
34
+ onClickSignOut={onClickSignOut}
35
+ />
36
+ </DrawerProvider>,
37
+ );
38
+ return { ...instance, onClickSignOut };
39
+ };
40
+
41
+ const clickOutsideProfileMenu = () => {
42
+ const child = screen.getByRole("presentation").firstChild;
43
+ expect(child).toBeDefined();
44
+ child && fireEvent.click(child);
45
+ };
46
+
47
+ describe("title", () => {
48
+ it("wouldn't render a title if it's not defined", () => {
49
+ renderComponent({ title: undefined });
50
+
51
+ expect(screen.queryByRole("heading", { level: 1 })).not.toBeInTheDocument();
52
+ });
53
+
54
+ it("would render a title if it's defined", () => {
55
+ renderComponent({ title: "Lorem ipsum" });
56
+
57
+ expect(screen.queryByRole("heading", { level: 1, name: /lorem ipsum/i })).toBeInTheDocument();
58
+ });
59
+ });
60
+
61
+ describe("menu", () => {
62
+ it("wouldn't render a menu button if menu is not defined", () => {
63
+ renderComponent();
64
+
65
+ expect(screen.queryByRole("button", { name: /open drawer/i })).not.toBeInTheDocument();
66
+ });
67
+
68
+ it("wouldn't render a menu button if menu is false", () => {
69
+ renderComponent({ menu: false });
70
+
71
+ expect(screen.queryByRole("button", { name: /open drawer/i })).not.toBeInTheDocument();
72
+ });
73
+
74
+ it("would render a menu button if menu is true", () => {
75
+ renderComponent({ menu: true });
76
+
77
+ expect(screen.getByRole("button", { name: /open drawer/i })).toBeInTheDocument();
78
+ });
79
+ });
80
+
81
+ describe("search", () => {
82
+ it("wouldn't render a search box by default", () => {
83
+ renderComponent();
84
+
85
+ expect(screen.queryByRole("search")).not.toBeInTheDocument();
86
+ });
87
+
88
+ it("wouldn't render a search box if search is false", () => {
89
+ renderComponent({ search: false });
90
+
91
+ expect(screen.queryByRole("search")).not.toBeInTheDocument();
92
+ });
93
+
94
+ it("would render a search box if search is true", () => {
95
+ renderComponent({ search: true });
96
+
97
+ expect(screen.getByRole("search")).toBeInTheDocument();
98
+ });
99
+ });
100
+
101
+ describe("profile", () => {
102
+ it("wouldn't render the user profile if it's not set", () => {
103
+ renderComponent({ profile: undefined });
104
+
105
+ expect(screen.queryByRole("button", { name: /menu button/i })).not.toBeInTheDocument();
106
+ });
107
+
108
+ it("would render the user profile if the profile is defined", () => {
109
+ renderComponent({ profile });
110
+
111
+ expect(screen.getByRole("button", { name: /menu button/i })).toBeInTheDocument();
112
+ });
113
+
114
+ describe("the user click the profile button", () => {
115
+ it("would open the menu", async () => {
116
+ renderComponent({ profile });
117
+
118
+ await userEvent.click(screen.getByRole("button", { name: /menu button/i }));
119
+
120
+ expect(screen.getByRole("menu")).toBeInTheDocument();
121
+ });
122
+ });
123
+
124
+ it("would call onClickSignOut if the user press the sign out button", async () => {
125
+ const { onClickSignOut } = renderComponent({ profile });
126
+
127
+ await userEvent.click(screen.getByRole("button", { name: /menu button/i }));
128
+ await userEvent.click(screen.getByRole("menuitem", { name: /sign out/i }));
129
+
130
+ expect(onClickSignOut).toHaveBeenCalledTimes(1);
131
+ });
132
+
133
+ it("would hide the menu if the focus changes to an external element", async () => {
134
+ renderComponent({ profile, title: "lorem ipsum" });
135
+
136
+ await userEvent.click(screen.getByRole("button", { name: /menu button/i }));
137
+ clickOutsideProfileMenu();
138
+
139
+ expect(screen.queryByRole("menu")).not.toBeInTheDocument();
140
+ });
141
+ });
142
+ });
@@ -0,0 +1,150 @@
1
+ import * as React from "react";
2
+ import { styled, alpha } from "@mui/material/styles";
3
+ import MuiAppBar from "@mui/material/AppBar";
4
+ import Box from "@mui/material/Box";
5
+ import Toolbar from "@mui/material/Toolbar";
6
+ import IconButton from "@mui/material/IconButton";
7
+ import Typography from "@mui/material/Typography";
8
+ import InputBase from "@mui/material/InputBase";
9
+ import MenuItem from "@mui/material/MenuItem";
10
+ import Menu from "@mui/material/Menu";
11
+ import MenuIcon from "@mui/icons-material/Menu";
12
+ import SearchIcon from "@mui/icons-material/Search";
13
+ import AccountCircle from "@mui/icons-material/AccountCircle";
14
+ import { AppBarComponent, AppBarProps } from "./app-bar.types";
15
+ import { useDrawer } from "../drawer/drawer.context";
16
+
17
+ const Search = styled("div")(({ theme }) => ({
18
+ position: "relative",
19
+ borderRadius: theme.shape.borderRadius,
20
+ backgroundColor: alpha(theme.palette.common.white, 0.15),
21
+ "&:hover": {
22
+ backgroundColor: alpha(theme.palette.common.white, 0.25),
23
+ },
24
+ marginRight: theme.spacing(2),
25
+ marginLeft: 0,
26
+ width: "100%",
27
+ [theme.breakpoints.up("sm")]: {
28
+ marginLeft: theme.spacing(3),
29
+ width: "auto",
30
+ },
31
+ }));
32
+
33
+ const SearchIconWrapper = styled("div")(({ theme }) => ({
34
+ padding: theme.spacing(0, 2),
35
+ height: "100%",
36
+ position: "absolute",
37
+ pointerEvents: "none",
38
+ display: "flex",
39
+ alignItems: "center",
40
+ justifyContent: "center",
41
+ }));
42
+
43
+ const StyledInputBase = styled(InputBase)(({ theme }) => ({
44
+ color: "inherit",
45
+ "& .MuiInputBase-input": {
46
+ padding: theme.spacing(1, 1, 1, 0),
47
+ // vertical padding + font size from searchIcon
48
+ paddingLeft: `calc(1em + ${theme.spacing(4)})`,
49
+ transition: theme.transitions.create("width"),
50
+ width: "100%",
51
+ [theme.breakpoints.up("md")]: {
52
+ width: "20ch",
53
+ },
54
+ },
55
+ }));
56
+
57
+ export const AppBar: AppBarComponent = ({
58
+ search = false,
59
+ title,
60
+ menu = false,
61
+ profile,
62
+ onClickSignOut,
63
+ ...rest
64
+ }: AppBarProps) => {
65
+ const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
66
+ const { isOpen, open } = useDrawer();
67
+
68
+ const handleMenu = (event: React.MouseEvent<HTMLElement>) => {
69
+ setAnchorEl(event.currentTarget);
70
+ };
71
+
72
+ const handleClose = () => {
73
+ setAnchorEl(null);
74
+ };
75
+
76
+ return (
77
+ <MuiAppBar {...rest}>
78
+ <Toolbar>
79
+ {menu && (
80
+ <IconButton
81
+ color="inherit"
82
+ aria-label="open drawer"
83
+ onClick={open}
84
+ edge="start"
85
+ sx={{
86
+ marginRight: 5,
87
+ ...(isOpen && { display: "none" }),
88
+ }}
89
+ >
90
+ <MenuIcon />
91
+ </IconButton>
92
+ )}
93
+ {title && (
94
+ <Typography
95
+ variant="h6"
96
+ component="h1"
97
+ role="heading"
98
+ aria-level={1}
99
+ noWrap
100
+ sx={{ display: { xs: "none", sm: "block" } }}
101
+ >
102
+ {title}
103
+ </Typography>
104
+ )}
105
+ {search && (
106
+ <Search role="search">
107
+ <SearchIconWrapper>
108
+ <SearchIcon />
109
+ </SearchIconWrapper>
110
+ <StyledInputBase placeholder="Search…" inputProps={{ "aria-label": "search" }} />
111
+ </Search>
112
+ )}
113
+ <Box sx={{ flexGrow: 1 }} />
114
+ {profile && (
115
+ <Box sx={{ display: { xs: "none", md: "flex" } }}>
116
+ <IconButton
117
+ size="large"
118
+ aria-controls="menu-appbar"
119
+ aria-haspopup="true"
120
+ aria-label="menu button"
121
+ role="button"
122
+ aria-expanded={Boolean(anchorEl)}
123
+ onClick={handleMenu}
124
+ color="inherit"
125
+ >
126
+ <AccountCircle />
127
+ </IconButton>
128
+ <Menu
129
+ id="menu-appbar"
130
+ anchorEl={anchorEl}
131
+ anchorOrigin={{
132
+ vertical: "top",
133
+ horizontal: "right",
134
+ }}
135
+ keepMounted
136
+ transformOrigin={{
137
+ vertical: "top",
138
+ horizontal: "right",
139
+ }}
140
+ open={Boolean(anchorEl)}
141
+ onClose={handleClose}
142
+ >
143
+ <MenuItem onClick={onClickSignOut}>Sign out</MenuItem>
144
+ </Menu>
145
+ </Box>
146
+ )}
147
+ </Toolbar>
148
+ </MuiAppBar>
149
+ );
150
+ };
@@ -0,0 +1,17 @@
1
+ import { FunctionComponent, ReactElement } from "react";
2
+ import { AppBarProps as MuiAppBarProps } from "@mui/material";
3
+
4
+ export interface AppBarProfile {
5
+ name: string;
6
+ }
7
+
8
+ export interface AppBarProps extends MuiAppBarProps {
9
+ menu?: boolean;
10
+ title?: string;
11
+ search?: boolean;
12
+ profile?: AppBarProfile;
13
+ onClickSignOut: () => void;
14
+ }
15
+
16
+ export type AppBarComponent = FunctionComponent<AppBarProps>;
17
+ export type AppBarElement = ReactElement<AppBarProps, AppBarComponent>;
@@ -0,0 +1,3 @@
1
+ export * from "./mini-app-bar";
2
+ export * from "./mini-app-bar";
3
+ export * from "./app-bar.types";
@@ -0,0 +1 @@
1
+ export * from "./mini-app-bar";
@@ -0,0 +1,31 @@
1
+ import { styled } from "@mui/material/styles";
2
+ import { AppBar } from "../app-bar";
3
+ import { AppBarProps } from "@mui/material";
4
+ import { drawerWidth } from "../../drawer/drawer.mixins";
5
+ import { AppBarComponent } from "../app-bar.types";
6
+ import { useDrawer } from "../../drawer/drawer.context";
7
+
8
+ export const MiniAppBar: AppBarComponent = styled(AppBar)<AppBarProps>(({ theme }) => {
9
+ const { isOpen } = useDrawer();
10
+
11
+ return {
12
+ zIndex: theme.zIndex.drawer + 1,
13
+ transition: theme.transitions.create(["width", "margin"], {
14
+ easing: theme.transitions.easing.sharp,
15
+ duration: theme.transitions.duration.leavingScreen,
16
+ }),
17
+ ...(isOpen && {
18
+ marginLeft: drawerWidth,
19
+ width: `calc(100% - ${drawerWidth}px)`,
20
+ transition: theme.transitions.create(["width", "margin"], {
21
+ easing: theme.transitions.easing.sharp,
22
+ duration: theme.transitions.duration.enteringScreen,
23
+ }),
24
+ }),
25
+ };
26
+ });
27
+
28
+ MiniAppBar.defaultProps = {
29
+ position: "fixed",
30
+ menu: true,
31
+ };
@@ -0,0 +1,43 @@
1
+ import { ComponentMeta } from "@storybook/react";
2
+ import { createTemplate } from "../../storybook";
3
+ import { Bullet } from "./bullet";
4
+
5
+ export default {
6
+ title: "Data Display/Bullet",
7
+ component: Bullet,
8
+ parameters: {
9
+ layout: "centered",
10
+ },
11
+ } as ComponentMeta<typeof Bullet>;
12
+
13
+ const Template = createTemplate(Bullet);
14
+
15
+ export const Primary = Template.bind({});
16
+ Primary.args = {
17
+ variant: "primary",
18
+ };
19
+
20
+ export const Secondary = Template.bind({});
21
+ Secondary.args = {
22
+ variant: "secondary",
23
+ };
24
+
25
+ export const Default = Template.bind({});
26
+ Default.args = {
27
+ variant: "default",
28
+ };
29
+
30
+ export const Info = Template.bind({});
31
+ Info.args = {
32
+ variant: "info",
33
+ };
34
+
35
+ export const Warning = Template.bind({});
36
+ Warning.args = {
37
+ variant: "warning",
38
+ };
39
+
40
+ export const Error = Template.bind({});
41
+ Error.args = {
42
+ variant: "error",
43
+ };
@@ -0,0 +1,24 @@
1
+ import React from "react";
2
+ import { Bullet, BulletVariant } from "./bullet";
3
+ import { render, screen } from "../../tests";
4
+
5
+ describe("Bullet", () => {
6
+ const renderComponent = (variant: BulletVariant | undefined = undefined) => {
7
+ return render(<Bullet variant={variant} />);
8
+ };
9
+
10
+ it("renders as primary without a variant", () => {
11
+ renderComponent(undefined);
12
+
13
+ expect(screen.getByRole("bullet")).toHaveAttribute("aria-describedby", "primary");
14
+ });
15
+
16
+ it.each([["primary"], ["secondary"], ["default"], ["info"], ["warning"], ["error"]])(
17
+ "renders correctly with variant %s",
18
+ (variant: string) => {
19
+ renderComponent(variant as BulletVariant);
20
+
21
+ expect(screen.getByRole("bullet")).toHaveAttribute("aria-describedby", variant);
22
+ },
23
+ );
24
+ });
@@ -0,0 +1,30 @@
1
+ import { Badge } from "@mui/material";
2
+ import React from "react";
3
+
4
+ export type BulletVariant = "primary" | "secondary" | "default" | "info" | "warning" | "error";
5
+
6
+ export const bulletClasses = {
7
+ root: "RdsBullet-root",
8
+ };
9
+
10
+ export interface BulletProps {
11
+ /**
12
+ * Color palette used to draw the component
13
+ */
14
+ variant?: BulletVariant;
15
+ }
16
+
17
+ /**
18
+ * Dot to attract the user attention
19
+ */
20
+ export const Bullet = ({ variant = "primary" }: BulletProps) => {
21
+ return (
22
+ <Badge
23
+ color={variant}
24
+ variant="dot"
25
+ className={bulletClasses.root}
26
+ role="bullet"
27
+ aria-describedby={variant}
28
+ />
29
+ );
30
+ };
@@ -0,0 +1 @@
1
+ export * from "./bullet";
@@ -0,0 +1,50 @@
1
+ import React from "react";
2
+ import { ComponentMeta } from "@storybook/react";
3
+ import { CenterContainer, CenterContainerProps } from "./center-container";
4
+ import { Label } from "../label";
5
+ import { createTemplate, withContainer } from "../../storybook";
6
+
7
+ export default {
8
+ title: "Containers/CenterContainer",
9
+ component: CenterContainer,
10
+ decorators: [withContainer({ height: 500, bordered: true })],
11
+ parameters: {
12
+ layout: "fullscreen",
13
+ },
14
+ } as ComponentMeta<typeof CenterContainer>;
15
+
16
+ const Template = createTemplate((args: CenterContainerProps) => {
17
+ return (
18
+ <CenterContainer {...args}>
19
+ <Label text="Lorem ipsum" />
20
+ </CenterContainer>
21
+ );
22
+ });
23
+
24
+ export const Default = Template.bind({});
25
+ Default.args = {
26
+ centerVertical: true,
27
+ centerHorizontal: true,
28
+ };
29
+
30
+ export const VerticalCentered = Template.bind({});
31
+ VerticalCentered.args = {
32
+ centerVertical: true,
33
+ centerHorizontal: false,
34
+ };
35
+
36
+ export const HorizontallyCentered = Template.bind({});
37
+ HorizontallyCentered.args = {
38
+ centerVertical: false,
39
+ centerHorizontal: true,
40
+ };
41
+
42
+ export const CustomStyles = Template.bind({});
43
+ CustomStyles.args = {
44
+ centerVertical: false,
45
+ centerHorizontal: false,
46
+ sx: {
47
+ px: 3,
48
+ py: 2,
49
+ },
50
+ };
@@ -0,0 +1,16 @@
1
+ import React from "react";
2
+ import { Typography } from "@mui/material";
3
+ import { render, screen } from "../../tests";
4
+ import { CenterContainer } from "./center-container";
5
+
6
+ describe("CenterContainer", () => {
7
+ it("would render the children", () => {
8
+ render(
9
+ <CenterContainer>
10
+ <Typography>Content</Typography>
11
+ </CenterContainer>,
12
+ );
13
+
14
+ expect(screen.getByText(/content/i)).toBeInTheDocument();
15
+ });
16
+ });
@@ -0,0 +1,32 @@
1
+ import React, { ReactNode } from "react";
2
+ import { Box, SxProps, Theme } from "@mui/material";
3
+
4
+ export interface CenterContainerProps {
5
+ children: ReactNode | undefined;
6
+ centerVertical?: boolean;
7
+ centerHorizontal?: boolean;
8
+ sx?: SxProps<Theme>;
9
+ }
10
+
11
+ export function CenterContainer({
12
+ children,
13
+ centerVertical = true,
14
+ centerHorizontal = true,
15
+ sx,
16
+ }: CenterContainerProps) {
17
+ return (
18
+ <Box
19
+ width={1}
20
+ height={1}
21
+ sx={{
22
+ ...sx,
23
+ display: "flex",
24
+ flexDirection: "column",
25
+ justifyContent: centerVertical ? "center" : "flex-start",
26
+ alignItems: centerHorizontal ? "center" : "flex-start",
27
+ }}
28
+ >
29
+ {children}
30
+ </Box>
31
+ );
32
+ }
@@ -0,0 +1 @@
1
+ export * from "./center-container";
@@ -0,0 +1,23 @@
1
+ import React from "react";
2
+ import { ComponentMeta } from "@storybook/react";
3
+ import { createTemplate } from "../../storybook";
4
+ import { Content } from "./content";
5
+ import { SkeletonGrid } from "../../tests";
6
+
7
+ export default {
8
+ title: "Sections/Content",
9
+ component: Content,
10
+ parameters: {
11
+ layout: "fullscreen",
12
+ },
13
+ } as ComponentMeta<typeof Content>;
14
+
15
+ const Template = createTemplate(() => {
16
+ return (
17
+ <Content>
18
+ <SkeletonGrid />
19
+ </Content>
20
+ );
21
+ });
22
+
23
+ export const Default = Template.bind({});
@@ -0,0 +1,26 @@
1
+ import React from "react";
2
+ import { Content } from "./content";
3
+ import { render, screen } from "../../tests";
4
+ import { Typography } from "@mui/material";
5
+
6
+ describe("Content", () => {
7
+ const renderComponent = () => {
8
+ return render(
9
+ <Content>
10
+ <Typography>Children content</Typography>
11
+ </Content>,
12
+ );
13
+ };
14
+
15
+ it("would render a children", () => {
16
+ renderComponent();
17
+
18
+ expect(screen.getByText(/children content/i)).toBeInTheDocument();
19
+ });
20
+
21
+ it("would render a main element", () => {
22
+ renderComponent();
23
+
24
+ expect(screen.getByRole("main")).toBeInTheDocument();
25
+ });
26
+ });
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import { Container } from "@mui/material";
3
+ import { ContentProps } from "./content.types";
4
+
5
+ export const Content = ({ children }: ContentProps) => {
6
+ return (
7
+ <Container component="main" sx={{ py: 3, flexGrow: 1 }}>
8
+ {children}
9
+ </Container>
10
+ );
11
+ };