@pautena/react-design-system 0.4.2 → 0.4.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 (191) hide show
  1. package/dist/cjs/index.js +1 -31
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/cjs/types/components/app-bar/app-bar.types.d.ts +2 -2
  4. package/dist/cjs/types/components/bullet/bullet.d.ts +1 -1
  5. package/dist/cjs/types/components/content/content.types.d.ts +3 -3
  6. package/dist/cjs/types/components/drawer/drawer.provider.d.ts +1 -1
  7. package/dist/cjs/types/components/drawer/drawer.types.d.ts +4 -4
  8. package/dist/cjs/types/components/enhanced-select/enhanced-select.d.ts +1 -2
  9. package/dist/cjs/types/components/header/header.dummy.d.ts +1 -1
  10. package/dist/cjs/types/components/header/header.types.d.ts +6 -6
  11. package/dist/cjs/types/components/label/label.d.ts +1 -1
  12. package/dist/cjs/types/components/link/link.d.ts +1 -1
  13. package/dist/cjs/types/components/placeholder/placeholder.d.ts +1 -1
  14. package/dist/cjs/types/components/query-container/query-container.d.ts +1 -1
  15. package/dist/cjs/types/components/sign-in/sign-in.d.ts +2 -3
  16. package/dist/cjs/types/components/tab/tab-card/tab-card.d.ts +3 -4
  17. package/dist/cjs/types/components/tab/tab-card/tab-card.dummy.d.ts +2 -3
  18. package/dist/cjs/types/components/table/enhanced-remote-table/enhanced-remote-table.d.ts +5 -6
  19. package/dist/cjs/types/components/table/enhanced-remote-table/enhanced-remote-table.mock.d.ts +6 -6
  20. package/dist/cjs/types/components/table/enhanced-table/enhanced-table-head.d.ts +8 -8
  21. package/dist/cjs/types/components/table/enhanced-table/enhanced-table.d.ts +2 -2
  22. package/dist/cjs/types/components/table/enhanced-table/enhanced-table.mock.d.ts +6 -7
  23. package/dist/cjs/types/components/table-list/table-list.d.ts +2 -2
  24. package/dist/cjs/types/components/value-displays/group-value-card/group-value-card.d.ts +7 -4
  25. package/dist/cjs/types/components/value-displays/group-value-card/group-value-card.mock.d.ts +2 -1
  26. package/dist/cjs/types/components/value-displays/index.d.ts +1 -0
  27. package/dist/cjs/types/components/value-displays/value-boolean/value-boolean.d.ts +3 -11
  28. package/dist/cjs/types/components/value-displays/value-card/value-card.d.ts +1 -1
  29. package/dist/cjs/types/components/value-displays/value-content/index.d.ts +1 -0
  30. package/dist/cjs/types/components/value-displays/value-content/value-content.d.ts +24 -0
  31. package/dist/cjs/types/components/value-displays/value-datetime/value-datetime.d.ts +3 -10
  32. package/dist/cjs/types/components/value-displays/value-displays.types.d.ts +15 -0
  33. package/dist/cjs/types/components/value-displays/value-image/index.d.ts +1 -0
  34. package/dist/cjs/types/components/value-displays/value-image/value-image.d.ts +11 -0
  35. package/dist/cjs/types/components/value-displays/value-text/value-text.d.ts +3 -11
  36. package/dist/cjs/types/generators/generators.mock.d.ts +2 -1
  37. package/dist/cjs/types/generators/generators.model.d.ts +36 -20
  38. package/dist/cjs/types/generators/generators.model.test.d.ts +1 -0
  39. package/dist/cjs/types/generators/model-router/model-router.d.ts +1 -1
  40. package/dist/cjs/types/generators/model-router/screens/add-screen.d.ts +1 -1
  41. package/dist/cjs/types/generators/model-router/screens/details-screen.d.ts +1 -1
  42. package/dist/cjs/types/generators/model-router/screens/list-screen.d.ts +1 -1
  43. package/dist/cjs/types/generators/model-router/screens/update-screen.d.ts +1 -1
  44. package/dist/cjs/types/layouts/header-layout/header-layout.d.ts +1 -2
  45. package/dist/cjs/types/providers/notification-center/notification-center.context.d.ts +0 -2
  46. package/dist/cjs/types/providers/notification-center/notification-center.provider.d.ts +1 -1
  47. package/dist/cjs/types/providers/tab-provider/tab-provider.provider.d.ts +1 -1
  48. package/dist/cjs/types/utils/theme.d.ts +1 -1
  49. package/dist/esm/index.js +1 -31
  50. package/dist/esm/index.js.map +1 -1
  51. package/dist/esm/types/components/app-bar/app-bar.types.d.ts +2 -2
  52. package/dist/esm/types/components/bullet/bullet.d.ts +1 -1
  53. package/dist/esm/types/components/content/content.types.d.ts +3 -3
  54. package/dist/esm/types/components/drawer/drawer.provider.d.ts +1 -1
  55. package/dist/esm/types/components/drawer/drawer.types.d.ts +4 -4
  56. package/dist/esm/types/components/enhanced-select/enhanced-select.d.ts +1 -2
  57. package/dist/esm/types/components/header/header.dummy.d.ts +1 -1
  58. package/dist/esm/types/components/header/header.types.d.ts +6 -6
  59. package/dist/esm/types/components/label/label.d.ts +1 -1
  60. package/dist/esm/types/components/link/link.d.ts +1 -1
  61. package/dist/esm/types/components/placeholder/placeholder.d.ts +1 -1
  62. package/dist/esm/types/components/query-container/query-container.d.ts +1 -1
  63. package/dist/esm/types/components/sign-in/sign-in.d.ts +2 -3
  64. package/dist/esm/types/components/tab/tab-card/tab-card.d.ts +3 -4
  65. package/dist/esm/types/components/tab/tab-card/tab-card.dummy.d.ts +2 -3
  66. package/dist/esm/types/components/table/enhanced-remote-table/enhanced-remote-table.d.ts +5 -6
  67. package/dist/esm/types/components/table/enhanced-remote-table/enhanced-remote-table.mock.d.ts +6 -6
  68. package/dist/esm/types/components/table/enhanced-table/enhanced-table-head.d.ts +8 -8
  69. package/dist/esm/types/components/table/enhanced-table/enhanced-table.d.ts +2 -2
  70. package/dist/esm/types/components/table/enhanced-table/enhanced-table.mock.d.ts +6 -7
  71. package/dist/esm/types/components/table-list/table-list.d.ts +2 -2
  72. package/dist/esm/types/components/value-displays/group-value-card/group-value-card.d.ts +7 -4
  73. package/dist/esm/types/components/value-displays/group-value-card/group-value-card.mock.d.ts +2 -1
  74. package/dist/esm/types/components/value-displays/index.d.ts +1 -0
  75. package/dist/esm/types/components/value-displays/value-boolean/value-boolean.d.ts +3 -11
  76. package/dist/esm/types/components/value-displays/value-card/value-card.d.ts +1 -1
  77. package/dist/esm/types/components/value-displays/value-content/index.d.ts +1 -0
  78. package/dist/esm/types/components/value-displays/value-content/value-content.d.ts +24 -0
  79. package/dist/esm/types/components/value-displays/value-datetime/value-datetime.d.ts +3 -10
  80. package/dist/esm/types/components/value-displays/value-displays.types.d.ts +15 -0
  81. package/dist/esm/types/components/value-displays/value-image/index.d.ts +1 -0
  82. package/dist/esm/types/components/value-displays/value-image/value-image.d.ts +11 -0
  83. package/dist/esm/types/components/value-displays/value-text/value-text.d.ts +3 -11
  84. package/dist/esm/types/generators/generators.mock.d.ts +2 -1
  85. package/dist/esm/types/generators/generators.model.d.ts +36 -20
  86. package/dist/esm/types/generators/generators.model.test.d.ts +1 -0
  87. package/dist/esm/types/generators/model-router/model-router.d.ts +1 -1
  88. package/dist/esm/types/generators/model-router/screens/add-screen.d.ts +1 -1
  89. package/dist/esm/types/generators/model-router/screens/details-screen.d.ts +1 -1
  90. package/dist/esm/types/generators/model-router/screens/list-screen.d.ts +1 -1
  91. package/dist/esm/types/generators/model-router/screens/update-screen.d.ts +1 -1
  92. package/dist/esm/types/layouts/header-layout/header-layout.d.ts +1 -2
  93. package/dist/esm/types/providers/notification-center/notification-center.context.d.ts +0 -2
  94. package/dist/esm/types/providers/notification-center/notification-center.provider.d.ts +1 -1
  95. package/dist/esm/types/providers/tab-provider/tab-provider.provider.d.ts +1 -1
  96. package/dist/esm/types/utils/theme.d.ts +1 -1
  97. package/dist/index.d.ts +155 -150
  98. package/package.json +58 -53
  99. package/src/components/app-bar/app-bar.stories.tsx +2 -1
  100. package/src/components/app-bar/app-bar.test.tsx +1 -1
  101. package/src/components/bullet/bullet.test.tsx +1 -1
  102. package/src/components/center-container/center-container.test.tsx +1 -1
  103. package/src/components/content/content.stories.tsx +1 -1
  104. package/src/components/content/content.test.tsx +1 -1
  105. package/src/components/drawer/__snapshots__/drawer.test.tsx.snap +3 -3
  106. package/src/components/drawer/drawer.test.tsx +8 -8
  107. package/src/components/drawer-content/drawer-content.stories.tsx +0 -1
  108. package/src/components/drawer-content/drawer-content.test.tsx +1 -1
  109. package/src/components/drawer-item/drawer-item.test.tsx +3 -3
  110. package/src/components/drawer-section/drawer-section.test.tsx +1 -1
  111. package/src/components/enhanced-select/enhanced-select.stories.tsx +10 -10
  112. package/src/components/enhanced-select/enhanced-select.test.tsx +9 -4
  113. package/src/components/enhanced-select/enhanced-select.tsx +1 -3
  114. package/src/components/header/header.dummy.ts +1 -1
  115. package/src/components/header/header.stories.tsx +0 -6
  116. package/src/components/header/header.test.tsx +1 -1
  117. package/src/components/label/label.test.tsx +1 -1
  118. package/src/components/link/link.tsx +2 -2
  119. package/src/components/loading-area/loading-area.test.tsx +2 -1
  120. package/src/components/placeholder/placeholder.test.tsx +3 -2
  121. package/src/components/query-container/query-container.test.tsx +2 -1
  122. package/src/components/sign-in/sign-in.test.tsx +2 -1
  123. package/src/components/sign-in/sign-in.tsx +3 -3
  124. package/src/components/tab/tab-card/tab-card.dummy.tsx +2 -2
  125. package/src/components/tab/tab-card/tab-card.stories.tsx +2 -2
  126. package/src/components/tab/tab-card/tab-card.test.tsx +1 -1
  127. package/src/components/tab/tab-card/tab-card.tsx +3 -3
  128. package/src/components/table/enhanced-remote-table/enhanced-remote-table.mock.tsx +7 -6
  129. package/src/components/table/enhanced-remote-table/enhanced-remote-table.test.tsx +3 -3
  130. package/src/components/table/enhanced-remote-table/enhanced-remote-table.tsx +8 -8
  131. package/src/components/table/enhanced-table/enhanced-table-head.tsx +14 -9
  132. package/src/components/table/enhanced-table/enhanced-table.mock.tsx +12 -6
  133. package/src/components/table/enhanced-table/enhanced-table.test.tsx +6 -5
  134. package/src/components/table/enhanced-table/enhanced-table.tsx +8 -8
  135. package/src/components/table-list/table-list.stories.tsx +27 -17
  136. package/src/components/table-list/table-list.test.tsx +11 -6
  137. package/src/components/table-list/table-list.tsx +23 -12
  138. package/src/components/value-displays/group-value-card/group-value-card.mock.tsx +2 -2
  139. package/src/components/value-displays/group-value-card/group-value-card.stories.tsx +24 -1
  140. package/src/components/value-displays/group-value-card/group-value-card.test.tsx +7 -2
  141. package/src/components/value-displays/group-value-card/group-value-card.tsx +13 -4
  142. package/src/components/value-displays/index.ts +1 -0
  143. package/src/components/value-displays/value-boolean/value-boolean.test.tsx +15 -3
  144. package/src/components/value-displays/value-boolean/value-boolean.tsx +17 -17
  145. package/src/components/value-displays/value-card/value-card.test.tsx +1 -1
  146. package/src/components/value-displays/value-content/index.ts +1 -0
  147. package/src/components/value-displays/value-content/value-content.stories.tsx +20 -0
  148. package/src/components/value-displays/value-content/value-content.test.tsx +50 -0
  149. package/src/components/value-displays/value-content/value-content.tsx +55 -0
  150. package/src/components/value-displays/value-datetime/value-datetime.stories.tsx +13 -0
  151. package/src/components/value-displays/value-datetime/value-datetime.test.tsx +24 -5
  152. package/src/components/value-displays/value-datetime/value-datetime.tsx +15 -22
  153. package/src/components/value-displays/value-displays.types.ts +18 -0
  154. package/src/components/value-displays/value-image/index.ts +1 -0
  155. package/src/components/value-displays/value-image/value-image.stories.tsx +28 -0
  156. package/src/components/value-displays/value-image/value-image.test.tsx +22 -0
  157. package/src/components/value-displays/value-image/value-image.tsx +24 -0
  158. package/src/components/value-displays/value-text/value-text.stories.tsx +11 -0
  159. package/src/components/value-displays/value-text/value-text.test.tsx +19 -5
  160. package/src/components/value-displays/value-text/value-text.tsx +16 -22
  161. package/src/generators/generators.mock.ts +25 -22
  162. package/src/generators/generators.model.test.ts +77 -0
  163. package/src/generators/generators.model.ts +78 -6
  164. package/src/generators/model-form/model-form.test.tsx +11 -14
  165. package/src/generators/model-form/model-form.tsx +33 -65
  166. package/src/generators/model-router/model-router.test.tsx +45 -32
  167. package/src/generators/model-router/screens/add-screen.tsx +2 -1
  168. package/src/generators/model-router/screens/details-screen.tsx +2 -1
  169. package/src/generators/model-router/screens/list-screen.tsx +1 -1
  170. package/src/generators/model-router/screens/update-screen.tsx +4 -5
  171. package/src/generators/model-router/stories/model-router.stories.tsx +1 -1
  172. package/src/generators/object-details/object-details.test.tsx +2 -1
  173. package/src/generators/object-details/object-details.tsx +18 -9
  174. package/src/hooks/routing/routing.test.tsx +1 -1
  175. package/src/layouts/app-bar-with-drawer-layout/app-bar-with-drawer-layout.stories.tsx +1 -1
  176. package/src/layouts/app-bar-with-drawer-layout/app-bar-with-drawer-layout.test.tsx +2 -1
  177. package/src/layouts/header-layout/header-layout.stories.tsx +11 -4
  178. package/src/layouts/header-layout/header-layout.test.tsx +1 -1
  179. package/src/layouts/header-layout/header-layout.tsx +1 -1
  180. package/src/providers/notification-center/notification-center.context.ts +0 -6
  181. package/src/providers/notification-center/notification-center.stories.tsx +1 -1
  182. package/src/providers/notification-center/notification-center.test.tsx +6 -7
  183. package/src/storybook.tsx +1 -1
  184. package/src/tests/actions.ts +4 -0
  185. package/src/tests/assertions.ts +18 -10
  186. package/src/tests/components.tsx +35 -1
  187. package/src/tests/file-mock.ts +1 -0
  188. package/src/tests/mocks.ts +21 -0
  189. package/src/tests/testing-library.tsx +11 -8
  190. package/src/types/index.d.ts +4 -0
  191. package/src/tests/index.ts +0 -4
@@ -2,32 +2,32 @@ import { Box, Typography, useTheme } from "@mui/material";
2
2
  import React from "react";
3
3
  import CheckIcon from "@mui/icons-material/Check";
4
4
  import CloseIcon from "@mui/icons-material/Close";
5
+ import { BaseValueProps, DefaultPlaceholder } from "../value-displays.types";
6
+ import { ValueContent } from "../value-content";
5
7
 
6
- export interface ValueBooleanProps {
7
- /**
8
- * Name of the displayed value
9
- */
10
- label: string;
11
- /**
12
- * Value displayed
13
- */
14
- value: boolean;
15
- }
8
+ export type ValueBooleanProps = BaseValueProps<boolean>;
16
9
 
17
10
  /**
18
11
  * Displays a boolean value with a label
19
12
  */
20
- export const ValueBoolean = ({ label, value }: ValueBooleanProps) => {
13
+ export const ValueBoolean = ({
14
+ label,
15
+ value,
16
+ placeholder = DefaultPlaceholder,
17
+ }: ValueBooleanProps) => {
21
18
  const { typography } = useTheme();
22
19
 
23
20
  const iconSx = { fontSize: typography.h5.fontSize };
24
21
 
25
22
  return (
26
- <Box>
27
- <Typography variant="subtitle2" role="label">
28
- {label}
29
- </Typography>
30
- {value ? <CheckIcon color="success" sx={iconSx} /> : <CloseIcon color="error" sx={iconSx} />}
31
- </Box>
23
+ <ValueContent label={label}>
24
+ {value === undefined ? (
25
+ <Typography variant="h5">{placeholder}</Typography>
26
+ ) : value ? (
27
+ <CheckIcon color="success" sx={iconSx} />
28
+ ) : (
29
+ <CloseIcon color="error" sx={iconSx} />
30
+ )}
31
+ </ValueContent>
32
32
  );
33
33
  };
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import { ValueCard } from "./value-card";
3
- import { render, screen } from "../../../tests";
3
+ import { render, screen } from "~/tests/testing-library";
4
4
  import { ReactElement } from "react";
5
5
  import { ValueText } from "../value-text";
6
6
 
@@ -0,0 +1 @@
1
+ export * from "./value-content";
@@ -0,0 +1,20 @@
1
+ import { ComponentMeta } from "@storybook/react";
2
+ import { ValueContent } from "./value-content";
3
+ import { withContainer } from "../../../storybook";
4
+ import { Typography } from "@mui/material";
5
+ import React from "react";
6
+
7
+ export default {
8
+ title: "Value displays/ValueContent",
9
+ component: ValueContent,
10
+ decorators: [withContainer({ width: 200 })],
11
+ parameters: {
12
+ layout: "centered",
13
+ },
14
+ } as ComponentMeta<typeof ValueContent>;
15
+
16
+ export const Default = () => (
17
+ <ValueContent label="lorem ipsum">
18
+ <Typography>Demo content</Typography>
19
+ </ValueContent>
20
+ );
@@ -0,0 +1,50 @@
1
+ import React from "react";
2
+ import { Typography } from "@mui/material";
3
+ import { render, screen } from "~/tests/testing-library";
4
+ import { ValueContent } from "./value-content";
5
+ import userEvent from "@testing-library/user-event";
6
+
7
+ describe("ValueContent", () => {
8
+ const renderComponent = ({ tooltip }: { tooltip?: string } = {}) => {
9
+ render(
10
+ <ValueContent label="lorem ipsum" tooltip={tooltip} tooltipEnterDelay={0}>
11
+ <Typography>Test content</Typography>
12
+ </ValueContent>,
13
+ );
14
+ };
15
+
16
+ it("should render a label", () => {
17
+ renderComponent();
18
+
19
+ expect(screen.getByRole("label", { name: /lorem ipsum/i })).toBeInTheDocument();
20
+ });
21
+
22
+ describe("tooltip", () => {
23
+ it("should render a tooltip if is defined and the user hovers the value", async () => {
24
+ renderComponent({ tooltip: "dolor sit amet" });
25
+
26
+ await userEvent.hover(screen.getByText(/test content/i));
27
+
28
+ expect(await screen.findByRole("tooltip", { name: /dolor sit amet/i })).toBeInTheDocument();
29
+ });
30
+
31
+ it("shouldn't render a tooltip if it's not defined", () => {
32
+ renderComponent({ tooltip: undefined });
33
+
34
+ expect(screen.queryByRole("tooltip", { name: /dolor sit amet/i })).not.toBeInTheDocument();
35
+ });
36
+ });
37
+
38
+ describe("children", () => {
39
+ it("should render the children if tooltip is defined", () => {
40
+ renderComponent({ tooltip: "dolor sit amet" });
41
+
42
+ expect(screen.getByText(/test content/i)).toBeInTheDocument();
43
+ });
44
+ it("should render the children if tooltip is undefined", () => {
45
+ renderComponent({ tooltip: undefined });
46
+
47
+ expect(screen.getByText(/test content/i)).toBeInTheDocument();
48
+ });
49
+ });
50
+ });
@@ -0,0 +1,55 @@
1
+ import { Box, Tooltip, Typography } from "@mui/material";
2
+ import React, { PropsWithChildren } from "react";
3
+ import { BaseValueProps, DefaultPlaceholder } from "../value-displays.types";
4
+
5
+ export const getValueContentLabelId = (label: string): string =>
6
+ `label-${label.replace(/ /g, "-")}`;
7
+
8
+ export interface ValueContentProps {
9
+ /**
10
+ * Name of the displayed value
11
+ */
12
+ label: string;
13
+
14
+ /**
15
+ * If defined, a tooltip is going to be added arround the children;
16
+ */
17
+ tooltip?: string;
18
+
19
+ /**
20
+ * Timeout before the tooltip appears when the user hovers the value
21
+ */
22
+ tooltipEnterDelay?: number;
23
+
24
+ /**
25
+ * Component that's going to be renderd under the label
26
+ */
27
+ children: React.ReactElement<any, any>;
28
+ }
29
+
30
+ /**
31
+ * Displays a string value with a label
32
+ */
33
+ export const ValueContent = ({
34
+ label,
35
+ tooltip,
36
+ tooltipEnterDelay = 2000,
37
+ children,
38
+ }: ValueContentProps) => {
39
+ const id = getValueContentLabelId(label);
40
+
41
+ return (
42
+ <Box width={1}>
43
+ <Typography variant="subtitle2" role="label" id={id}>
44
+ {label}
45
+ </Typography>
46
+ {tooltip ? (
47
+ <Tooltip title={tooltip} placement="top" enterDelay={tooltipEnterDelay}>
48
+ {children}
49
+ </Tooltip>
50
+ ) : (
51
+ children
52
+ )}
53
+ </Box>
54
+ );
55
+ };
@@ -19,3 +19,16 @@ Default.args = {
19
19
  value: new Date(2022, 8, 22),
20
20
  format: "yyyy/MM/dd",
21
21
  };
22
+
23
+ export const Placeholder = Template.bind({});
24
+ Placeholder.args = {
25
+ label: "Lorem",
26
+ format: "yyyy/MM/dd",
27
+ };
28
+
29
+ export const CustomPlaceholder = Template.bind({});
30
+ CustomPlaceholder.args = {
31
+ label: "Lorem",
32
+ format: "yyyy/MM/dd",
33
+ placeholder: ".",
34
+ };
@@ -1,23 +1,42 @@
1
1
  import React from "react";
2
- import { render, screen } from "../../../tests";
2
+ import { render, screen } from "~/tests/testing-library";
3
3
  import { ValueDatetime } from "./value-datetime";
4
4
 
5
+ const DummyValue = new Date(2022, 7, 10);
6
+
5
7
  describe("ValueDatetime", () => {
6
- const renderComponent = () => {
8
+ const renderComponent = ({ value, placeholder }: { value?: Date; placeholder?: string }) => {
7
9
  return render(
8
- <ValueDatetime label="Hello world" value={new Date(2022, 7, 10)} format="dd-MM-yyyy" />,
10
+ <ValueDatetime
11
+ label="Hello world"
12
+ value={value}
13
+ placeholder={placeholder}
14
+ format="dd-MM-yyyy"
15
+ />,
9
16
  );
10
17
  };
11
18
 
12
19
  it("would render the label", () => {
13
- renderComponent();
20
+ renderComponent({ value: DummyValue });
14
21
 
15
22
  expect(screen.getByRole("label", { name: /hello world/i })).toBeInTheDocument();
16
23
  });
17
24
 
18
25
  it("would render the value", () => {
19
- renderComponent();
26
+ renderComponent({ value: DummyValue });
20
27
 
21
28
  expect(screen.getByText(/10-08-2022/i)).toBeInTheDocument();
22
29
  });
30
+
31
+ it("should render the placeholder if value is undefined", () => {
32
+ renderComponent({ value: undefined });
33
+
34
+ expect(screen.getByText(/-/i)).toBeInTheDocument();
35
+ });
36
+
37
+ it("should render the custom placeholder if value is undefined and placeholder has value", () => {
38
+ renderComponent({ value: undefined, placeholder: "_" });
39
+
40
+ expect(screen.getByText(/_/i)).toBeInTheDocument();
41
+ });
23
42
  });
@@ -1,17 +1,10 @@
1
1
  import { Box, Tooltip, Typography } from "@mui/material";
2
2
  import React from "react";
3
3
  import { format } from "date-fns";
4
+ import { BaseValueProps, DefaultPlaceholder } from "../value-displays.types";
5
+ import { getValueContentLabelId, ValueContent } from "../value-content";
4
6
 
5
- export interface ValueDatetimeProps {
6
- /**
7
- * Name of the displayed value
8
- */
9
- label: string;
10
- /**
11
- * Value displayed
12
- */
13
- value: Date;
14
-
7
+ export interface ValueDatetimeProps extends BaseValueProps<Date> {
15
8
  /**
16
9
  * Datetime format
17
10
  */
@@ -21,20 +14,20 @@ export interface ValueDatetimeProps {
21
14
  /**
22
15
  * Displays a formated datetime with a label
23
16
  */
24
- export const ValueDatetime = ({ label, value, format: fmt }: ValueDatetimeProps) => {
25
- const id = `label-${label.replace(/ /g, "-")}`;
26
- const formatedValue = format(value, fmt);
17
+ export const ValueDatetime = ({
18
+ label,
19
+ value: valueProp,
20
+ format: fmt,
21
+ placeholder = DefaultPlaceholder,
22
+ }: ValueDatetimeProps) => {
23
+ const id = getValueContentLabelId(label);
24
+ const value = (valueProp && format(valueProp, fmt)) || placeholder;
27
25
 
28
26
  return (
29
- <Box>
30
- <Typography variant="subtitle2" role="label" id={id}>
31
- {label}
27
+ <ValueContent label={label} tooltip={value}>
28
+ <Typography variant="h5" noWrap aria-labelledby={id}>
29
+ {value}
32
30
  </Typography>
33
- <Tooltip title={formatedValue} placement="top" enterDelay={2000}>
34
- <Typography variant="h5" noWrap aria-labelledby={id}>
35
- {formatedValue}
36
- </Typography>
37
- </Tooltip>
38
- </Box>
31
+ </ValueContent>
39
32
  );
40
33
  };
@@ -0,0 +1,18 @@
1
+ export interface BaseValueProps<T> {
2
+ /**
3
+ * Name of the displayed value
4
+ */
5
+ label: string;
6
+
7
+ /**
8
+ * Value displayed
9
+ */
10
+ value?: T;
11
+
12
+ /**
13
+ * String rendered if value is undefined
14
+ */
15
+ placeholder?: string;
16
+ }
17
+
18
+ export const DefaultPlaceholder = "-";
@@ -0,0 +1 @@
1
+ export * from "./value-image";
@@ -0,0 +1,28 @@
1
+ import { ComponentMeta } from "@storybook/react";
2
+ import { ValueImage } from "./value-image";
3
+ import { createTemplate, withContainer } from "../../../storybook";
4
+ import workInProgressImg from "../../../stories/assets/work-in-progress.jpg";
5
+
6
+ export default {
7
+ title: "Value displays/ValueImage",
8
+ component: ValueImage,
9
+ decorators: [withContainer({ width: 200 })],
10
+ parameters: {
11
+ layout: "centered",
12
+ },
13
+ } as ComponentMeta<typeof ValueImage>;
14
+
15
+ const Template = createTemplate(ValueImage);
16
+
17
+ export const Default = Template.bind({});
18
+ Default.args = {
19
+ label: "Lorem",
20
+ value: workInProgressImg,
21
+ };
22
+
23
+ export const CustomSize = Template.bind({});
24
+ CustomSize.args = {
25
+ label: "Lorem",
26
+ value: workInProgressImg,
27
+ size: 250,
28
+ };
@@ -0,0 +1,22 @@
1
+ import React from "react";
2
+ import { render, screen } from "~/tests/testing-library";
3
+ import { ValueImage } from "./value-image";
4
+ import workInProgressImg from "~/stories/assets/work-in-progress.jpg";
5
+
6
+ describe("ValueImage", () => {
7
+ const renderComponent = () => {
8
+ return render(<ValueImage label="Hello world" value={workInProgressImg} />);
9
+ };
10
+
11
+ it("should render the label", () => {
12
+ renderComponent();
13
+
14
+ expect(screen.getByRole("label", { name: /hello world/i })).toBeInTheDocument();
15
+ });
16
+
17
+ it("should render an image", () => {
18
+ renderComponent();
19
+
20
+ expect(screen.getByRole("img")).toBeInTheDocument();
21
+ });
22
+ });
@@ -0,0 +1,24 @@
1
+ import { Box } from "@mui/material";
2
+ import React from "react";
3
+ import { ValueContent } from "../value-content";
4
+ import { BaseValueProps } from "../value-displays.types";
5
+
6
+ export interface ValueImageProps extends BaseValueProps<string> {
7
+ /**
8
+ * Image size
9
+ */
10
+ size?: number;
11
+ }
12
+
13
+ const DefaultSize = 100;
14
+
15
+ /**
16
+ * Displays a image value with a label
17
+ */
18
+ export const ValueImage = ({ label, value, size = DefaultSize }: ValueImageProps) => {
19
+ return (
20
+ <ValueContent label={label}>
21
+ <Box component="img" src={value} alt={label} sx={{ width: size, height: size }} />
22
+ </ValueContent>
23
+ );
24
+ };
@@ -24,3 +24,14 @@ TruncatedText.args = {
24
24
  label: "Lorem",
25
25
  value: "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
26
26
  };
27
+
28
+ export const Placeholder = Template.bind({});
29
+ Placeholder.args = {
30
+ label: "Lorem",
31
+ };
32
+
33
+ export const CustomPlaceholder = Template.bind({});
34
+ CustomPlaceholder.args = {
35
+ label: "Lorem",
36
+ placeholder: ".",
37
+ };
@@ -1,21 +1,35 @@
1
1
  import React from "react";
2
- import { render, screen } from "../../../tests";
2
+ import { render, screen } from "~/tests/testing-library";
3
3
  import { ValueText } from "./value-text";
4
4
 
5
+ const DummyValue = "Lorem ipsum sit amet";
6
+
5
7
  describe("ValueText", () => {
6
- const renderComponent = () => {
7
- return render(<ValueText label="Hello world" value="Lorem ipsum sit amet" />);
8
+ const renderComponent = ({ value, placeholder }: { value?: string; placeholder?: string }) => {
9
+ return render(<ValueText label="Hello world" value={value} placeholder={placeholder} />);
8
10
  };
9
11
 
10
12
  it("would render the label", () => {
11
- renderComponent();
13
+ renderComponent({ value: DummyValue });
12
14
 
13
15
  expect(screen.getByRole("label", { name: /hello world/i })).toBeInTheDocument();
14
16
  });
15
17
 
16
18
  it("would render the value", () => {
17
- renderComponent();
19
+ renderComponent({ value: DummyValue });
18
20
 
19
21
  expect(screen.getByText(/lorem ipsum sit amet/i)).toBeInTheDocument();
20
22
  });
23
+
24
+ it("should render the placeholder if value is undefined", () => {
25
+ renderComponent({ value: undefined });
26
+
27
+ expect(screen.getByText(/-/i)).toBeInTheDocument();
28
+ });
29
+
30
+ it("should render the custom placeholder if value is undefined and placeholder has value", () => {
31
+ renderComponent({ value: undefined, placeholder: "_" });
32
+
33
+ expect(screen.getByText(/_/i)).toBeInTheDocument();
34
+ });
21
35
  });
@@ -1,32 +1,26 @@
1
- import { Box, Tooltip, Typography } from "@mui/material";
1
+ import { Typography } from "@mui/material";
2
2
  import React from "react";
3
+ import { BaseValueProps, DefaultPlaceholder } from "../value-displays.types";
4
+ import { getValueContentLabelId, ValueContent } from "../value-content";
3
5
 
4
- export interface ValueTextProps {
5
- /**
6
- * Name of the displayed value
7
- */
8
- label: string;
9
- /**
10
- * Value displayed
11
- */
12
- value: string;
13
- }
6
+ export type ValueTextProps = BaseValueProps<string>;
14
7
 
15
8
  /**
16
9
  * Displays a string value with a label
17
10
  */
18
- export const ValueText = ({ label, value }: ValueTextProps) => {
19
- const id = `label-${label.replace(/ /g, "-")}`;
11
+ export const ValueText = ({
12
+ label,
13
+ value: valueProp,
14
+ placeholder = DefaultPlaceholder,
15
+ }: ValueTextProps) => {
16
+ const id = getValueContentLabelId(label);
17
+ const value = valueProp || placeholder;
18
+
20
19
  return (
21
- <Box>
22
- <Typography variant="subtitle2" role="label" id={id}>
23
- {label}
20
+ <ValueContent label={label} tooltip={value}>
21
+ <Typography variant="h5" noWrap aria-labelledby={id}>
22
+ {value}
24
23
  </Typography>
25
- <Tooltip title={value} placement="top" enterDelay={2000}>
26
- <Typography variant="h5" noWrap aria-labelledby={id}>
27
- {value}
28
- </Typography>
29
- </Tooltip>
30
- </Box>
24
+ </ValueContent>
31
25
  );
32
26
  };
@@ -1,5 +1,6 @@
1
- import { BasicModelInstance, Model, ModelField } from "./generators.model";
1
+ import { BasicModelInstance, FieldType, Model, ModelField } from "./generators.model";
2
2
  import { faker } from "@faker-js/faker";
3
+ import * as R from "ramda";
3
4
  import { newArrayWithSize } from "../utils";
4
5
 
5
6
  export const BirthDateFormat = "dd/MM/yyyy";
@@ -65,7 +66,7 @@ export const mockModel: Model = {
65
66
  xs: 12,
66
67
  sm: 6,
67
68
  md: 3,
68
- listable: true,
69
+ listable: false,
69
70
  },
70
71
  {
71
72
  id: "birthDate",
@@ -141,7 +142,7 @@ export const mockModel: Model = {
141
142
  id: "returnTime",
142
143
  type: "time",
143
144
  format: ReturnTimeFormat,
144
- default: new Date(1970, 0, 1, 9, 0),
145
+ default: new Date(2022, 8, 21, 9, 0),
145
146
  description: "Lorem ipsum",
146
147
  name: "Return time",
147
148
  xs: 12,
@@ -208,9 +209,10 @@ export interface MockInstance {
208
209
  available: boolean;
209
210
  currency: string;
210
211
  tradeDate: Date;
212
+ [key: string]: FieldType;
211
213
  }
212
214
 
213
- const mockFieldValue = {
215
+ const mockFieldValue: Record<string, () => FieldType> = {
214
216
  id: () => faker.datatype.number({ min: 1000, max: 100000 }).toString(),
215
217
  firstName: faker.name.firstName,
216
218
  middleName: faker.name.middleName,
@@ -236,7 +238,7 @@ const mockFieldValue = {
236
238
  type: () => {
237
239
  const array = newArrayWithSize(faker.datatype.number({ min: 2, max: 5 }), 0);
238
240
  const result = array.map(() => faker.vehicle.type());
239
- return [...new Set(result)];
241
+ return R.uniq(result);
240
242
  },
241
243
  vin: faker.vehicle.vin,
242
244
  vrm: faker.vehicle.vrm,
@@ -248,30 +250,31 @@ const mockFieldValue = {
248
250
 
249
251
  export const createModelInstance = <T extends BasicModelInstance>(model: Model, seed = 100): T => {
250
252
  faker.seed(seed);
251
- const obj = {};
252
-
253
- model.fields.forEach((field) => {
254
- let value;
253
+ return model.fields.reduce((acc, field) => {
255
254
  if (field.type === "group") {
256
- value = {};
257
- field.value.forEach((groupField) => {
258
- value[groupField.id] = getModelFieldValue(groupField);
259
- });
255
+ return {
256
+ ...acc,
257
+ [field.id]: field.value.reduce(
258
+ (acc, groupField) => ({
259
+ ...acc,
260
+ [groupField.id]: getModelFieldValue(groupField),
261
+ }),
262
+ {},
263
+ ),
264
+ };
260
265
  } else {
261
- value = getModelFieldValue(field);
266
+ return {
267
+ ...acc,
268
+ [field.id]: getModelFieldValue(field),
269
+ };
262
270
  }
263
-
264
- obj[field.id] = value;
265
- });
266
-
267
- return obj as T;
271
+ }, {} as T);
268
272
  };
269
273
 
270
- const getModelFieldValue = ({ id, type }: ModelField) => {
274
+ const getModelFieldValue = ({ id }: ModelField): FieldType => {
271
275
  const fieldGenerator = mockFieldValue[id];
272
276
  if (!fieldGenerator) {
273
- const generator = faker.datatype[type];
274
- return generator ? generator() : faker.datatype.string();
277
+ return faker.datatype.string();
275
278
  }
276
279
  return fieldGenerator();
277
280
  };