@pautena/react-design-system 0.4.7 → 0.4.8
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/value-displays/index.d.ts +2 -1
- package/dist/cjs/types/components/value-displays/value-base/index.d.ts +2 -0
- package/dist/cjs/types/components/value-displays/{value-displays.types.d.ts → value-base/value-displays.types.d.ts} +10 -0
- package/dist/cjs/types/components/value-displays/value-base/value-edit.d.ts +19 -0
- package/dist/cjs/types/components/value-displays/value-boolean/value-boolean.d.ts +3 -3
- package/dist/cjs/types/components/value-displays/value-datetime/value-datetime.d.ts +8 -3
- package/dist/cjs/types/components/value-displays/value-image/value-image.d.ts +1 -1
- package/dist/cjs/types/components/value-displays/value-rating/value-rating.d.ts +3 -3
- package/dist/cjs/types/components/value-displays/value-text/value-text.d.ts +3 -17
- package/dist/esm/index.js +4 -4
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/components/value-displays/index.d.ts +2 -1
- package/dist/esm/types/components/value-displays/value-base/index.d.ts +2 -0
- package/dist/esm/types/components/value-displays/{value-displays.types.d.ts → value-base/value-displays.types.d.ts} +10 -0
- package/dist/esm/types/components/value-displays/value-base/value-edit.d.ts +19 -0
- package/dist/esm/types/components/value-displays/value-boolean/value-boolean.d.ts +3 -3
- package/dist/esm/types/components/value-displays/value-datetime/value-datetime.d.ts +8 -3
- package/dist/esm/types/components/value-displays/value-image/value-image.d.ts +1 -1
- package/dist/esm/types/components/value-displays/value-rating/value-rating.d.ts +3 -3
- package/dist/esm/types/components/value-displays/value-text/value-text.d.ts +3 -17
- package/dist/index.d.ts +37 -18
- package/package.json +1 -1
- package/src/components/drawers/drawer-collapsable-item/drawer-collapsable-item.tsx +1 -3
- package/src/components/value-displays/index.ts +2 -1
- package/src/components/value-displays/value-base/index.ts +2 -0
- package/src/components/value-displays/{value-displays.types.ts → value-base/value-displays.types.ts} +12 -2
- package/src/components/value-displays/value-base/value-edit.tsx +59 -0
- package/src/components/value-displays/value-boolean/value-boolean.stories.tsx +7 -0
- package/src/components/value-displays/value-boolean/value-boolean.test.tsx +81 -2
- package/src/components/value-displays/value-boolean/value-boolean.tsx +33 -8
- package/src/components/value-displays/value-datetime/value-datetime.stories.tsx +29 -2
- package/src/components/value-displays/value-datetime/value-datetime.test.tsx +94 -5
- package/src/components/value-displays/value-datetime/value-datetime.tsx +64 -6
- package/src/components/value-displays/value-image/value-image.tsx +1 -1
- package/src/components/value-displays/value-rating/value-rating.stories.tsx +8 -0
- package/src/components/value-displays/value-rating/value-rating.test.tsx +71 -2
- package/src/components/value-displays/value-rating/value-rating.tsx +29 -5
- package/src/components/value-displays/value-text/value-text.test.tsx +5 -8
- package/src/components/value-displays/value-text/value-text.tsx +16 -60
- package/src/tests/actions.ts +2 -2
|
@@ -3,5 +3,6 @@ export * from "./value-card";
|
|
|
3
3
|
export * from "./value-boolean";
|
|
4
4
|
export * from "./value-datetime";
|
|
5
5
|
export * from "./group-value-card";
|
|
6
|
-
export * from "./value-displays.types";
|
|
6
|
+
export * from "./value-base/value-displays.types";
|
|
7
7
|
export * from "./value-rating";
|
|
8
|
+
export * from "./value-base";
|
|
@@ -12,4 +12,14 @@ export interface BaseValueProps<T> {
|
|
|
12
12
|
*/
|
|
13
13
|
placeholder?: string;
|
|
14
14
|
}
|
|
15
|
+
export interface EditableValueProps<T> {
|
|
16
|
+
/**
|
|
17
|
+
* This field can be edited or not
|
|
18
|
+
*/
|
|
19
|
+
editable?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Callback executed when the value is edited
|
|
22
|
+
*/
|
|
23
|
+
onEdit?: (value?: T) => void;
|
|
24
|
+
}
|
|
15
25
|
export declare const DefaultPlaceholder = "-";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { SxProps, Theme } from "@mui/material";
|
|
3
|
+
export interface ValueEditButtonsProps {
|
|
4
|
+
onClickCancel: () => void;
|
|
5
|
+
onSubmitEdit: () => void;
|
|
6
|
+
sx?: SxProps<Theme>;
|
|
7
|
+
}
|
|
8
|
+
export declare const ValueEditButtons: ({ onClickCancel, onSubmitEdit, sx }: ValueEditButtonsProps) => JSX.Element;
|
|
9
|
+
/**
|
|
10
|
+
* Hook to manage the editing behaviour
|
|
11
|
+
*/
|
|
12
|
+
export declare const useEditableValueDisplay: <T>(initialValue: T | undefined, onEdit: (value?: T | undefined) => void) => {
|
|
13
|
+
isEditing: boolean;
|
|
14
|
+
cancelEdit: () => void;
|
|
15
|
+
editValue: T | undefined;
|
|
16
|
+
setEditValue: React.Dispatch<React.SetStateAction<T | undefined>>;
|
|
17
|
+
startEdit: () => void;
|
|
18
|
+
submitEdit: () => void;
|
|
19
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { BaseValueProps } from "../value-
|
|
2
|
-
export type ValueBooleanProps = BaseValueProps<boolean>;
|
|
1
|
+
import { BaseValueProps, EditableValueProps } from "../value-base";
|
|
2
|
+
export type ValueBooleanProps = BaseValueProps<boolean> & EditableValueProps<boolean>;
|
|
3
3
|
/**
|
|
4
4
|
* Displays a boolean value with a label
|
|
5
5
|
*/
|
|
6
|
-
export declare const ValueBoolean: ({ label, value, placeholder, }: ValueBooleanProps) => JSX.Element;
|
|
6
|
+
export declare const ValueBoolean: ({ label, value, placeholder, editable, onEdit, }: ValueBooleanProps) => JSX.Element;
|
|
@@ -1,11 +1,16 @@
|
|
|
1
|
-
import { BaseValueProps } from "../value-displays.types";
|
|
2
|
-
export
|
|
1
|
+
import { BaseValueProps, EditableValueProps } from "../value-base/value-displays.types";
|
|
2
|
+
export type EditInputType = "datetime" | "date" | "time";
|
|
3
|
+
export interface ValueDatetimeProps extends BaseValueProps<Date>, EditableValueProps<Date> {
|
|
3
4
|
/**
|
|
4
5
|
* Datetime format
|
|
5
6
|
*/
|
|
6
7
|
format: string;
|
|
8
|
+
/**
|
|
9
|
+
* Edit input type
|
|
10
|
+
*/
|
|
11
|
+
editInputType?: EditInputType;
|
|
7
12
|
}
|
|
8
13
|
/**
|
|
9
14
|
* Displays a formated datetime with a label
|
|
10
15
|
*/
|
|
11
|
-
export declare const ValueDatetime: ({ label, value: valueProp, format: fmt, placeholder, }: ValueDatetimeProps) => JSX.Element;
|
|
16
|
+
export declare const ValueDatetime: ({ label, value: valueProp, format: fmt, placeholder, editable, editInputType, onEdit, }: ValueDatetimeProps) => JSX.Element;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { BaseValueProps } from "../value-displays.types";
|
|
1
|
+
import { BaseValueProps, EditableValueProps } from "../value-base/value-displays.types";
|
|
2
2
|
export type ValueRatingProps = BaseValueProps<number> & {
|
|
3
3
|
maxRating?: number;
|
|
4
|
-
}
|
|
4
|
+
} & EditableValueProps<number>;
|
|
5
5
|
/**
|
|
6
6
|
* Displays a number using stars
|
|
7
7
|
*/
|
|
8
|
-
export declare const ValueRating: ({ label, value, maxRating }: ValueRatingProps) => JSX.Element;
|
|
8
|
+
export declare const ValueRating: ({ label, value, maxRating, editable, onEdit, }: ValueRatingProps) => JSX.Element;
|
|
@@ -1,20 +1,6 @@
|
|
|
1
|
-
import { BaseValueProps } from "../value-
|
|
2
|
-
export type
|
|
3
|
-
export interface ValueTextProps<T extends TextValue> extends BaseValueProps<T> {
|
|
4
|
-
/**
|
|
5
|
-
* This field can be edited or not
|
|
6
|
-
*/
|
|
7
|
-
editable?: boolean;
|
|
8
|
-
/**
|
|
9
|
-
* Callback executed when the value is edited
|
|
10
|
-
*/
|
|
11
|
-
onEdit?: (value?: string) => void;
|
|
12
|
-
/**
|
|
13
|
-
* Callback called when the user cancels an edition
|
|
14
|
-
*/
|
|
15
|
-
onCancelEdit?: () => void;
|
|
16
|
-
}
|
|
1
|
+
import { BaseValueProps, EditableValueProps } from "../value-base";
|
|
2
|
+
export type ValueTextProps = BaseValueProps<string | number> & EditableValueProps<string>;
|
|
17
3
|
/**
|
|
18
4
|
* Displays a string value with a label
|
|
19
5
|
*/
|
|
20
|
-
export declare const ValueText:
|
|
6
|
+
export declare const ValueText: ({ label, value: valueProp, placeholder, editable, onEdit, }: ValueTextProps) => JSX.Element;
|
package/dist/index.d.ts
CHANGED
|
@@ -2,13 +2,31 @@
|
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import React__default, { PropsWithChildren, FunctionComponent, ReactElement, ReactNode, Dispatch, SetStateAction } from 'react';
|
|
4
4
|
import * as _mui_material from '@mui/material';
|
|
5
|
-
import { GridProps, AppBarProps as AppBarProps$1, PropTypes,
|
|
5
|
+
import { SxProps, Theme, GridProps, AppBarProps as AppBarProps$1, PropTypes, DrawerProps as DrawerProps$1, Color, AlertColor } from '@mui/material';
|
|
6
6
|
import * as _emotion_styled from '@emotion/styled';
|
|
7
7
|
import * as _mui_system from '@mui/system';
|
|
8
8
|
import { SelectInputProps } from '@mui/material/Select/SelectInput';
|
|
9
9
|
import { Variant } from '@mui/material/styles/createTypography';
|
|
10
10
|
import { LoremUnit } from 'lorem-ipsum/types/src/constants/units';
|
|
11
11
|
|
|
12
|
+
interface ValueEditButtonsProps {
|
|
13
|
+
onClickCancel: () => void;
|
|
14
|
+
onSubmitEdit: () => void;
|
|
15
|
+
sx?: SxProps<Theme>;
|
|
16
|
+
}
|
|
17
|
+
declare const ValueEditButtons: ({ onClickCancel, onSubmitEdit, sx }: ValueEditButtonsProps) => JSX.Element;
|
|
18
|
+
/**
|
|
19
|
+
* Hook to manage the editing behaviour
|
|
20
|
+
*/
|
|
21
|
+
declare const useEditableValueDisplay: <T>(initialValue: T | undefined, onEdit: (value?: T | undefined) => void) => {
|
|
22
|
+
isEditing: boolean;
|
|
23
|
+
cancelEdit: () => void;
|
|
24
|
+
editValue: T | undefined;
|
|
25
|
+
setEditValue: React__default.Dispatch<React__default.SetStateAction<T | undefined>>;
|
|
26
|
+
startEdit: () => void;
|
|
27
|
+
submitEdit: () => void;
|
|
28
|
+
};
|
|
29
|
+
|
|
12
30
|
interface BaseValueProps<T> {
|
|
13
31
|
/**
|
|
14
32
|
* Name of the displayed value
|
|
@@ -23,10 +41,7 @@ interface BaseValueProps<T> {
|
|
|
23
41
|
*/
|
|
24
42
|
placeholder?: string;
|
|
25
43
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
type TextValue = string | number;
|
|
29
|
-
interface ValueTextProps<T extends TextValue> extends BaseValueProps<T> {
|
|
44
|
+
interface EditableValueProps<T> {
|
|
30
45
|
/**
|
|
31
46
|
* This field can be edited or not
|
|
32
47
|
*/
|
|
@@ -34,16 +49,15 @@ interface ValueTextProps<T extends TextValue> extends BaseValueProps<T> {
|
|
|
34
49
|
/**
|
|
35
50
|
* Callback executed when the value is edited
|
|
36
51
|
*/
|
|
37
|
-
onEdit?: (value?:
|
|
38
|
-
/**
|
|
39
|
-
* Callback called when the user cancels an edition
|
|
40
|
-
*/
|
|
41
|
-
onCancelEdit?: () => void;
|
|
52
|
+
onEdit?: (value?: T) => void;
|
|
42
53
|
}
|
|
54
|
+
declare const DefaultPlaceholder = "-";
|
|
55
|
+
|
|
56
|
+
type ValueTextProps = BaseValueProps<string | number> & EditableValueProps<string>;
|
|
43
57
|
/**
|
|
44
58
|
* Displays a string value with a label
|
|
45
59
|
*/
|
|
46
|
-
declare const ValueText:
|
|
60
|
+
declare const ValueText: ({ label, value: valueProp, placeholder, editable, onEdit, }: ValueTextProps) => JSX.Element;
|
|
47
61
|
|
|
48
62
|
type ValueCardProps = PropsWithChildren;
|
|
49
63
|
/**
|
|
@@ -51,22 +65,27 @@ type ValueCardProps = PropsWithChildren;
|
|
|
51
65
|
*/
|
|
52
66
|
declare const ValueCard: ({ children }: ValueCardProps) => JSX.Element;
|
|
53
67
|
|
|
54
|
-
type ValueBooleanProps = BaseValueProps<boolean>;
|
|
68
|
+
type ValueBooleanProps = BaseValueProps<boolean> & EditableValueProps<boolean>;
|
|
55
69
|
/**
|
|
56
70
|
* Displays a boolean value with a label
|
|
57
71
|
*/
|
|
58
|
-
declare const ValueBoolean: ({ label, value, placeholder, }: ValueBooleanProps) => JSX.Element;
|
|
72
|
+
declare const ValueBoolean: ({ label, value, placeholder, editable, onEdit, }: ValueBooleanProps) => JSX.Element;
|
|
59
73
|
|
|
60
|
-
|
|
74
|
+
type EditInputType = "datetime" | "date" | "time";
|
|
75
|
+
interface ValueDatetimeProps extends BaseValueProps<Date>, EditableValueProps<Date> {
|
|
61
76
|
/**
|
|
62
77
|
* Datetime format
|
|
63
78
|
*/
|
|
64
79
|
format: string;
|
|
80
|
+
/**
|
|
81
|
+
* Edit input type
|
|
82
|
+
*/
|
|
83
|
+
editInputType?: EditInputType;
|
|
65
84
|
}
|
|
66
85
|
/**
|
|
67
86
|
* Displays a formated datetime with a label
|
|
68
87
|
*/
|
|
69
|
-
declare const ValueDatetime: ({ label, value: valueProp, format: fmt, placeholder, }: ValueDatetimeProps) => JSX.Element;
|
|
88
|
+
declare const ValueDatetime: ({ label, value: valueProp, format: fmt, placeholder, editable, editInputType, onEdit, }: ValueDatetimeProps) => JSX.Element;
|
|
70
89
|
|
|
71
90
|
type GroupValueItemProps = PropsWithChildren<Omit<GridProps, "item" | "container"> & {
|
|
72
91
|
bordered?: boolean;
|
|
@@ -87,11 +106,11 @@ declare const GroupValueCard: ({ title, subtitle, centered, children }: GroupVal
|
|
|
87
106
|
|
|
88
107
|
type ValueRatingProps = BaseValueProps<number> & {
|
|
89
108
|
maxRating?: number;
|
|
90
|
-
}
|
|
109
|
+
} & EditableValueProps<number>;
|
|
91
110
|
/**
|
|
92
111
|
* Displays a number using stars
|
|
93
112
|
*/
|
|
94
|
-
declare const ValueRating: ({ label, value, maxRating }: ValueRatingProps) => JSX.Element;
|
|
113
|
+
declare const ValueRating: ({ label, value, maxRating, editable, onEdit, }: ValueRatingProps) => JSX.Element;
|
|
95
114
|
|
|
96
115
|
/**
|
|
97
116
|
* Displays a centered loading indicator
|
|
@@ -829,4 +848,4 @@ type TabProviderProps = PropsWithChildren<{
|
|
|
829
848
|
}>;
|
|
830
849
|
declare const TabProvider: ({ children, initialValue }: TabProviderProps) => JSX.Element;
|
|
831
850
|
|
|
832
|
-
export { AppBarComponent, AppBarElement, AppBarProfile, AppBarProps, AppBarWithDrawerLayout, AppBarWithDrawerLayoutProps, ArrayFieldType, BaseFieldType, BaseValueProps, BasicModelInstance, Bullet, BulletProps, BulletVariant, CenterContainer, CenterContainerProps, Content, ContentComponent, ContentElement, ContentPlaceholder, ContentPlaceholderProps, ContentProps, DefaultPlaceholder, Drawer, DrawerComponent, DrawerContent, DrawerContentComponent, DrawerContentElement, DrawerContentProps, DrawerContext, DrawerContextProps, DrawerElement, DrawerItem, DrawerItemProps, DrawerProps, DrawerProvider, DrawerSection, DrawerSectionProps, EnhancedRemoteTable, EnhancedRemoteTableProps, EnhancedSelect, EnhancedSelectProps, EnhancedSelectSize, EnhancedTable, EnhancedTableHead, FieldType, GroupField, GroupInstanceType, GroupValueCard, GroupValueCardProps, GroupValueItem, GroupValueItemComponent, GroupValueItemElement, GroupValueItemProps, HeadCell, Header, HeaderAction, HeaderActionVariant, HeaderBreadcrumb, HeaderComponent, HeaderElement, HeaderLayout, HeaderLayoutProps, HeaderNavigationButton, HeaderPreset, HeaderProps, HeaderTab, IdleRequest, Label, LabelProps, LabelVariant, LoadingArea, LoadingRequest, LoremIpsumPlaceholder, LoremIpsumPlaceholderProps, MiniAppBar, MiniDrawer, Model, ModelField, ModelFieldTypes, ModelForm, ModelFormProps, ModelRouter, ModelRouterProps, Nav, NavItem, NavItemAvatar, NavItemBullet, NavItemCollapsable, NavItemLabel, NavItemLink, NavSection, Notification, NotificationCenterContext, NotificationCenterProps, NotificationCenterProvider, NotificationCenterProviderProps, NotificationCenterProviderUndefinedError, NotifyWhenValueChangesOptions, ObjectDetails, ObjectDetailsProps, Order, Placeholder, PlaceholderAction, PlaceholderIconArgs, PlaceholderProps, QueryContainer, QueryContainerError, QueryContainerProps, QueryContainerSuccess, RequestState, SignIn, SignInProps, SingleFieldType, SkeletonCard, SkeletonCardProps, SkeletonGrid, SkeletonGridProps, SuccessRequest, TabCard, TabCardProps, TabContext, TabContextProvider, TabPanel, TabProvider, TableList, TableListProps, TableRowOption,
|
|
851
|
+
export { AppBarComponent, AppBarElement, AppBarProfile, AppBarProps, AppBarWithDrawerLayout, AppBarWithDrawerLayoutProps, ArrayFieldType, BaseFieldType, BaseValueProps, BasicModelInstance, Bullet, BulletProps, BulletVariant, CenterContainer, CenterContainerProps, Content, ContentComponent, ContentElement, ContentPlaceholder, ContentPlaceholderProps, ContentProps, DefaultPlaceholder, Drawer, DrawerComponent, DrawerContent, DrawerContentComponent, DrawerContentElement, DrawerContentProps, DrawerContext, DrawerContextProps, DrawerElement, DrawerItem, DrawerItemProps, DrawerProps, DrawerProvider, DrawerSection, DrawerSectionProps, EditInputType, EditableValueProps, EnhancedRemoteTable, EnhancedRemoteTableProps, EnhancedSelect, EnhancedSelectProps, EnhancedSelectSize, EnhancedTable, EnhancedTableHead, FieldType, GroupField, GroupInstanceType, GroupValueCard, GroupValueCardProps, GroupValueItem, GroupValueItemComponent, GroupValueItemElement, GroupValueItemProps, HeadCell, Header, HeaderAction, HeaderActionVariant, HeaderBreadcrumb, HeaderComponent, HeaderElement, HeaderLayout, HeaderLayoutProps, HeaderNavigationButton, HeaderPreset, HeaderProps, HeaderTab, IdleRequest, Label, LabelProps, LabelVariant, LoadingArea, LoadingRequest, LoremIpsumPlaceholder, LoremIpsumPlaceholderProps, MiniAppBar, MiniDrawer, Model, ModelField, ModelFieldTypes, ModelForm, ModelFormProps, ModelRouter, ModelRouterProps, Nav, NavItem, NavItemAvatar, NavItemBullet, NavItemCollapsable, NavItemLabel, NavItemLink, NavSection, Notification, NotificationCenterContext, NotificationCenterProps, NotificationCenterProvider, NotificationCenterProviderProps, NotificationCenterProviderUndefinedError, NotifyWhenValueChangesOptions, ObjectDetails, ObjectDetailsProps, Order, Placeholder, PlaceholderAction, PlaceholderIconArgs, PlaceholderProps, QueryContainer, QueryContainerError, QueryContainerProps, QueryContainerSuccess, RequestState, SignIn, SignInProps, SingleFieldType, SkeletonCard, SkeletonCardProps, SkeletonGrid, SkeletonGridProps, SuccessRequest, TabCard, TabCardProps, TabContext, TabContextProvider, TabPanel, TabProvider, TableList, TableListProps, TableRowOption, UndefinedProvider, ValueBoolean, ValueBooleanProps, ValueCard, ValueCardProps, ValueDatetime, ValueDatetimeProps, ValueEditButtons, ValueEditButtonsProps, ValueRating, ValueRatingProps, ValueText, ValueTextProps, bulletClasses, getRandomItem, groupValueItemClasses, labelClasses, newArrayWithSize, newInstanceFromValuesOrZeroValue, useDrawer, useEditableValueDisplay, useGetDefaultThemeColor, useNotificationCenter, useNotifyWhenValueChanges, useTab };
|
package/package.json
CHANGED
|
@@ -2,14 +2,12 @@ import {
|
|
|
2
2
|
ListItem,
|
|
3
3
|
ListItemButton,
|
|
4
4
|
ListItemIcon,
|
|
5
|
-
ListItemAvatar,
|
|
6
|
-
Avatar,
|
|
7
5
|
ListItemText,
|
|
8
6
|
Collapse,
|
|
9
7
|
List,
|
|
10
8
|
} from "@mui/material";
|
|
11
9
|
import React, { ReactElement, useState } from "react";
|
|
12
|
-
import {
|
|
10
|
+
import { NavItemLink } from "../drawer/drawer.types";
|
|
13
11
|
import ExpandLess from "@mui/icons-material/ExpandLess";
|
|
14
12
|
import ExpandMore from "@mui/icons-material/ExpandMore";
|
|
15
13
|
import { DrawerItem } from "../drawer-item";
|
|
@@ -3,5 +3,6 @@ export * from "./value-card";
|
|
|
3
3
|
export * from "./value-boolean";
|
|
4
4
|
export * from "./value-datetime";
|
|
5
5
|
export * from "./group-value-card";
|
|
6
|
-
export * from "./value-displays.types";
|
|
6
|
+
export * from "./value-base/value-displays.types";
|
|
7
7
|
export * from "./value-rating";
|
|
8
|
+
export * from "./value-base";
|
package/src/components/value-displays/{value-displays.types.ts → value-base/value-displays.types.ts}
RENAMED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { ReactElement } from "react";
|
|
2
|
-
|
|
3
1
|
export interface BaseValueProps<T> {
|
|
4
2
|
/**
|
|
5
3
|
* Name of the displayed value
|
|
@@ -17,4 +15,16 @@ export interface BaseValueProps<T> {
|
|
|
17
15
|
placeholder?: string;
|
|
18
16
|
}
|
|
19
17
|
|
|
18
|
+
export interface EditableValueProps<T> {
|
|
19
|
+
/**
|
|
20
|
+
* This field can be edited or not
|
|
21
|
+
*/
|
|
22
|
+
editable?: boolean;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Callback executed when the value is edited
|
|
26
|
+
*/
|
|
27
|
+
onEdit?: (value?: T) => void;
|
|
28
|
+
}
|
|
29
|
+
|
|
20
30
|
export const DefaultPlaceholder = "-";
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import CheckIcon from "@mui/icons-material/Check";
|
|
3
|
+
import ClearIcon from "@mui/icons-material/Clear";
|
|
4
|
+
import { Button, InputAdornment, SxProps, Theme } from "@mui/material";
|
|
5
|
+
|
|
6
|
+
export interface ValueEditButtonsProps {
|
|
7
|
+
onClickCancel: () => void;
|
|
8
|
+
onSubmitEdit: () => void;
|
|
9
|
+
sx?: SxProps<Theme>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const ValueEditButtons = ({ onClickCancel, onSubmitEdit, sx }: ValueEditButtonsProps) => {
|
|
13
|
+
return (
|
|
14
|
+
<InputAdornment position="end" sx={sx}>
|
|
15
|
+
<Button
|
|
16
|
+
variant="contained"
|
|
17
|
+
size="small"
|
|
18
|
+
color="error"
|
|
19
|
+
startIcon={<ClearIcon />}
|
|
20
|
+
onClick={onClickCancel}
|
|
21
|
+
sx={{ paddingRight: 0, minWidth: 0, marginRight: 1 }}
|
|
22
|
+
/>
|
|
23
|
+
<Button
|
|
24
|
+
variant="contained"
|
|
25
|
+
size="small"
|
|
26
|
+
color="primary"
|
|
27
|
+
startIcon={<CheckIcon />}
|
|
28
|
+
onClick={onSubmitEdit}
|
|
29
|
+
sx={{ paddingRight: 0, minWidth: 0 }}
|
|
30
|
+
/>
|
|
31
|
+
</InputAdornment>
|
|
32
|
+
);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Hook to manage the editing behaviour
|
|
37
|
+
*/
|
|
38
|
+
export const useEditableValueDisplay = <T,>(
|
|
39
|
+
initialValue: T | undefined,
|
|
40
|
+
onEdit: (value?: T) => void,
|
|
41
|
+
) => {
|
|
42
|
+
const [isEditing, setIsEditing] = useState(false);
|
|
43
|
+
const [editValue, setEditValue] = useState<T | undefined>(initialValue);
|
|
44
|
+
|
|
45
|
+
const cancelEdit = () => {
|
|
46
|
+
setIsEditing(false);
|
|
47
|
+
setEditValue(initialValue);
|
|
48
|
+
};
|
|
49
|
+
const startEdit = () => {
|
|
50
|
+
setIsEditing(true);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const submitEdit = () => {
|
|
54
|
+
onEdit(editValue);
|
|
55
|
+
cancelEdit();
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
return { isEditing, cancelEdit, editValue, setEditValue, startEdit, submitEdit };
|
|
59
|
+
};
|
|
@@ -1,10 +1,29 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { ValueBoolean } from "./value-boolean";
|
|
3
3
|
import { render, screen } from "~/tests/testing-library";
|
|
4
|
+
import userEvent from "@testing-library/user-event";
|
|
4
5
|
|
|
5
6
|
describe("ValueBoolean", () => {
|
|
6
|
-
const renderComponent = ({
|
|
7
|
-
|
|
7
|
+
const renderComponent = ({
|
|
8
|
+
value,
|
|
9
|
+
placeholder,
|
|
10
|
+
editable,
|
|
11
|
+
}: {
|
|
12
|
+
value?: boolean;
|
|
13
|
+
placeholder?: string;
|
|
14
|
+
editable?: boolean;
|
|
15
|
+
}) => {
|
|
16
|
+
const onEdit = jest.fn();
|
|
17
|
+
render(
|
|
18
|
+
<ValueBoolean
|
|
19
|
+
label="Hello world"
|
|
20
|
+
value={value}
|
|
21
|
+
placeholder={placeholder}
|
|
22
|
+
editable={editable}
|
|
23
|
+
onEdit={onEdit}
|
|
24
|
+
/>,
|
|
25
|
+
);
|
|
26
|
+
return { onEdit };
|
|
8
27
|
};
|
|
9
28
|
|
|
10
29
|
it("would render the label", () => {
|
|
@@ -36,4 +55,64 @@ describe("ValueBoolean", () => {
|
|
|
36
55
|
|
|
37
56
|
expect(screen.getByText(/_/i)).toBeInTheDocument();
|
|
38
57
|
});
|
|
58
|
+
|
|
59
|
+
describe("editable", () => {
|
|
60
|
+
it("shouldn't render an option to edit if editable is false", () => {
|
|
61
|
+
renderComponent({ value: true, editable: false });
|
|
62
|
+
|
|
63
|
+
expect(screen.queryByTestId("EditIcon")).not.toBeInTheDocument();
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("should render an option to edit if editable is true", () => {
|
|
67
|
+
renderComponent({ value: true, editable: true });
|
|
68
|
+
|
|
69
|
+
expect(screen.getByTestId("EditIcon")).toBeVisible();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("should render an input with the value if the edit button is clicked", async () => {
|
|
73
|
+
renderComponent({ value: true, editable: true });
|
|
74
|
+
|
|
75
|
+
await userEvent.click(screen.getByTestId("EditIcon"));
|
|
76
|
+
|
|
77
|
+
expect(screen.getByRole("checkbox")).toBeChecked();
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it.each([
|
|
81
|
+
[true, false],
|
|
82
|
+
[false, true],
|
|
83
|
+
])(
|
|
84
|
+
"should submit %s if is edited and the initial value is %s",
|
|
85
|
+
async (expectedValue: boolean, initialValue: boolean) => {
|
|
86
|
+
const { onEdit } = renderComponent({ value: initialValue, editable: true });
|
|
87
|
+
|
|
88
|
+
await userEvent.click(screen.getByTestId("EditIcon"));
|
|
89
|
+
await userEvent.click(screen.getByRole("checkbox"));
|
|
90
|
+
await userEvent.click(screen.getByTestId("CheckIcon"));
|
|
91
|
+
|
|
92
|
+
expect(onEdit).toHaveBeenCalledTimes(1);
|
|
93
|
+
expect(onEdit).toHaveBeenCalledWith(expectedValue);
|
|
94
|
+
},
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
it("should not call onEdit if the edition is cancelled", async () => {
|
|
98
|
+
const { onEdit } = renderComponent({ value: true, editable: true });
|
|
99
|
+
|
|
100
|
+
await userEvent.click(screen.getByTestId("EditIcon"));
|
|
101
|
+
await userEvent.click(screen.getByRole("checkbox"));
|
|
102
|
+
await userEvent.click(screen.getByTestId("ClearIcon"));
|
|
103
|
+
|
|
104
|
+
expect(onEdit).not.toHaveBeenCalled();
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it("should have the original value if is edited again after clear a change", async () => {
|
|
108
|
+
renderComponent({ value: true, editable: true });
|
|
109
|
+
|
|
110
|
+
await userEvent.click(screen.getByTestId("EditIcon"));
|
|
111
|
+
await userEvent.click(screen.getByRole("checkbox"));
|
|
112
|
+
await userEvent.click(screen.getByTestId("ClearIcon"));
|
|
113
|
+
await userEvent.click(screen.getByTestId("EditIcon"));
|
|
114
|
+
|
|
115
|
+
expect(screen.getByRole("checkbox")).toBeChecked();
|
|
116
|
+
});
|
|
117
|
+
});
|
|
39
118
|
});
|
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
import { Typography, useTheme } from "@mui/material";
|
|
1
|
+
import { Box, IconButton, Switch, 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 {
|
|
5
|
+
import {
|
|
6
|
+
BaseValueProps,
|
|
7
|
+
DefaultPlaceholder,
|
|
8
|
+
EditableValueProps,
|
|
9
|
+
useEditableValueDisplay,
|
|
10
|
+
ValueEditButtons,
|
|
11
|
+
} from "../value-base";
|
|
6
12
|
import { ValueContent } from "../value-content";
|
|
13
|
+
import EditIcon from "@mui/icons-material/Edit";
|
|
7
14
|
|
|
8
|
-
export type ValueBooleanProps = BaseValueProps<boolean>;
|
|
15
|
+
export type ValueBooleanProps = BaseValueProps<boolean> & EditableValueProps<boolean>;
|
|
9
16
|
|
|
10
17
|
/**
|
|
11
18
|
* Displays a boolean value with a label
|
|
@@ -14,19 +21,37 @@ export const ValueBoolean = ({
|
|
|
14
21
|
label,
|
|
15
22
|
value,
|
|
16
23
|
placeholder = DefaultPlaceholder,
|
|
24
|
+
editable,
|
|
25
|
+
onEdit = () => null,
|
|
17
26
|
}: ValueBooleanProps) => {
|
|
18
27
|
const { typography } = useTheme();
|
|
28
|
+
const { isEditing, editValue, startEdit, cancelEdit, setEditValue, submitEdit } =
|
|
29
|
+
useEditableValueDisplay(value, onEdit);
|
|
19
30
|
|
|
20
31
|
const iconSx = { fontSize: typography.h5.fontSize };
|
|
21
32
|
|
|
22
33
|
return (
|
|
23
34
|
<ValueContent label={label}>
|
|
24
|
-
{
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
35
|
+
{isEditing ? (
|
|
36
|
+
<Box display="flex" alignItems="center">
|
|
37
|
+
<Switch checked={editValue} onChange={(e) => setEditValue(e.target.checked)} />
|
|
38
|
+
<ValueEditButtons onClickCancel={cancelEdit} onSubmitEdit={submitEdit} />
|
|
39
|
+
</Box>
|
|
28
40
|
) : (
|
|
29
|
-
<
|
|
41
|
+
<Box display="flex" alignItems="center">
|
|
42
|
+
{value === undefined ? (
|
|
43
|
+
<Typography variant="h5">{placeholder}</Typography>
|
|
44
|
+
) : value ? (
|
|
45
|
+
<CheckIcon color="success" sx={iconSx} />
|
|
46
|
+
) : (
|
|
47
|
+
<CloseIcon color="error" sx={iconSx} />
|
|
48
|
+
)}
|
|
49
|
+
{editable && (
|
|
50
|
+
<IconButton size="small" onClick={startEdit} sx={{ ml: 1 }}>
|
|
51
|
+
<EditIcon />
|
|
52
|
+
</IconButton>
|
|
53
|
+
)}
|
|
54
|
+
</Box>
|
|
30
55
|
)}
|
|
31
56
|
</ValueContent>
|
|
32
57
|
);
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { ComponentMeta } from "@storybook/react";
|
|
2
2
|
import { ValueDatetime } from "./value-datetime";
|
|
3
|
-
import { createTemplate, withContainer } from "../../../storybook";
|
|
3
|
+
import { createTemplate, withContainer, withLocalizationProvider } from "../../../storybook";
|
|
4
4
|
|
|
5
5
|
export default {
|
|
6
6
|
title: "Components/Value displays/ValueDatetime",
|
|
7
7
|
component: ValueDatetime,
|
|
8
|
-
decorators: [withContainer({ width:
|
|
8
|
+
decorators: [withContainer({ width: 600 }), withLocalizationProvider],
|
|
9
9
|
parameters: {
|
|
10
10
|
layout: "centered",
|
|
11
11
|
},
|
|
@@ -32,3 +32,30 @@ CustomPlaceholder.args = {
|
|
|
32
32
|
format: "yyyy/MM/dd",
|
|
33
33
|
placeholder: ".",
|
|
34
34
|
};
|
|
35
|
+
|
|
36
|
+
export const EditableDatetime = Template.bind({});
|
|
37
|
+
EditableDatetime.args = {
|
|
38
|
+
label: "Lorem",
|
|
39
|
+
value: new Date(2022, 8, 22, 12, 25),
|
|
40
|
+
format: "yyyy/MM/dd HH:mm",
|
|
41
|
+
editable: true,
|
|
42
|
+
editInputType: "datetime",
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const EditableTime = Template.bind({});
|
|
46
|
+
EditableTime.args = {
|
|
47
|
+
label: "Lorem",
|
|
48
|
+
value: new Date(2022, 8, 22, 12, 25),
|
|
49
|
+
format: "HH:mm",
|
|
50
|
+
editable: true,
|
|
51
|
+
editInputType: "time",
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const EditableDate = Template.bind({});
|
|
55
|
+
EditableDate.args = {
|
|
56
|
+
label: "Lorem",
|
|
57
|
+
value: new Date(2022, 8, 22),
|
|
58
|
+
format: "yyyy/MM/dd",
|
|
59
|
+
editable: true,
|
|
60
|
+
editInputType: "date",
|
|
61
|
+
};
|