@applica-software-guru/react-admin 1.5.238 → 1.5.242

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 (38) hide show
  1. package/.husky/pre-commit +2 -1
  2. package/dist/components/ActionsMenu.d.ts.map +1 -1
  3. package/dist/components/ra-buttons/Button.d.ts +17 -0
  4. package/dist/components/ra-buttons/Button.d.ts.map +1 -0
  5. package/dist/components/ra-buttons/CreateInDialogButton.d.ts +9 -2
  6. package/dist/components/ra-buttons/CreateInDialogButton.d.ts.map +1 -1
  7. package/dist/components/ra-buttons/EditInDialogButton.d.ts +19 -0
  8. package/dist/components/ra-buttons/EditInDialogButton.d.ts.map +1 -1
  9. package/dist/components/ra-buttons/index.d.ts +1 -0
  10. package/dist/components/ra-buttons/index.d.ts.map +1 -1
  11. package/dist/components/ra-forms/Create.d.ts.map +1 -1
  12. package/dist/components/ra-forms/Edit.d.ts.map +1 -1
  13. package/dist/components/ra-forms/LongForm/BaseForm.d.ts.map +1 -1
  14. package/dist/components/ra-forms/SimpleForm.d.ts.map +1 -1
  15. package/dist/components/ra-forms/TabbedForm.d.ts.map +1 -1
  16. package/dist/components/ra-forms/Toolbar.d.ts.map +1 -1
  17. package/dist/index.d.ts +1 -1
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/react-admin.cjs.js +53 -53
  20. package/dist/react-admin.cjs.js.map +1 -1
  21. package/dist/react-admin.es.js +5483 -5411
  22. package/dist/react-admin.es.js.map +1 -1
  23. package/dist/react-admin.umd.js +51 -51
  24. package/dist/react-admin.umd.js.map +1 -1
  25. package/package.json +1 -1
  26. package/src/components/ActionsMenu.tsx +5 -0
  27. package/src/components/ra-buttons/Button.tsx +84 -0
  28. package/src/components/ra-buttons/CreateInDialogButton.tsx +26 -12
  29. package/src/components/ra-buttons/EditInDialogButton.tsx +61 -13
  30. package/src/components/ra-buttons/index.ts +1 -0
  31. package/src/components/ra-forms/Create.tsx +0 -1
  32. package/src/components/ra-forms/Edit.tsx +0 -1
  33. package/src/components/ra-forms/LongForm/BaseForm.tsx +0 -5
  34. package/src/components/ra-forms/SimpleForm.tsx +0 -1
  35. package/src/components/ra-forms/TabbedForm.tsx +0 -1
  36. package/src/components/ra-forms/Toolbar.tsx +2 -2
  37. package/src/index.ts +0 -1
  38. package/src/playground/components/ra-lists/CategoryList.jsx +4 -1
package/package.json CHANGED
@@ -115,5 +115,5 @@
115
115
  "type": "module",
116
116
  "types": "dist/index.d.ts",
117
117
  "typings": "dist/index.d.ts",
118
- "version": "1.5.238"
118
+ "version": "1.5.242"
119
119
  }
@@ -21,6 +21,11 @@ const StyledMenuPopover = styled(MenuPopover, {
21
21
  margin: 0,
22
22
  '& .MuiButton-startIcon': {
23
23
  marginRight: theme.spacing(0)
24
+ },
25
+ [theme.breakpoints.down('sm')]: {
26
+ '&>.MuiSvgIcon-root, & svg': {
27
+ marginRight: theme.spacing(0)
28
+ }
24
29
  }
25
30
  }
26
31
  }));
@@ -0,0 +1,84 @@
1
+ import { Button as MuiButton } from '@mui/material';
2
+ import { styled } from '@mui/material/styles';
3
+ import { LocationDescriptor, Button as RaButton, ButtonProps as RaButtonProps, useTranslate } from 'react-admin';
4
+
5
+ type ButtonProps = RaButtonProps & {
6
+ /**
7
+ * Disable icon only in small screens.
8
+ */
9
+ disableIconOnly?: boolean;
10
+ };
11
+
12
+ const PREFIX = 'RaButton';
13
+ function getLinkParams(locationDescriptor?: LocationDescriptor | string) {
14
+ // eslint-disable-next-line eqeqeq
15
+ if (locationDescriptor == undefined) {
16
+ return undefined;
17
+ }
18
+
19
+ if (typeof locationDescriptor === 'string') {
20
+ return { to: locationDescriptor };
21
+ }
22
+
23
+ const { redirect, replace, state, ...to } = locationDescriptor;
24
+ return {
25
+ to,
26
+ redirect,
27
+ replace,
28
+ state
29
+ };
30
+ }
31
+ const StyledButton = styled(MuiButton, {
32
+ name: PREFIX,
33
+ overridesResolver: (_props, styles) => styles.root
34
+ })({
35
+ '&.MuiButton-sizeSmall': {
36
+ // fix for icon misalignment on small buttons, see https://github.com/mui/material-ui/pull/30240
37
+ lineHeight: 1.5
38
+ }
39
+ });
40
+
41
+ /**
42
+ * A button that can be displayed as a floating button on small screens.
43
+ * @param props The component props.
44
+ * @returns The component.
45
+ */
46
+ function Button(props: ButtonProps): JSX.Element {
47
+ const {
48
+ disableIconOnly = false,
49
+ label,
50
+ children,
51
+ className,
52
+ color,
53
+ size,
54
+ disabled,
55
+ alignIcon,
56
+ to: locationDescriptor,
57
+ ...rest
58
+ } = props;
59
+ const translate = useTranslate();
60
+ const linkParams = getLinkParams(locationDescriptor);
61
+
62
+ if (disableIconOnly) {
63
+ const translatedLabel = label ? translate(label, { _: label }) : undefined;
64
+ return (
65
+ <StyledButton
66
+ className={className}
67
+ color={color}
68
+ size={size}
69
+ aria-label={translatedLabel}
70
+ disabled={disabled}
71
+ startIcon={alignIcon === 'left' && children ? children : undefined}
72
+ endIcon={alignIcon === 'right' && children ? children : undefined}
73
+ {...linkParams}
74
+ {...rest}
75
+ >
76
+ {translatedLabel}
77
+ </StyledButton>
78
+ );
79
+ }
80
+ return <RaButton {...props} />;
81
+ }
82
+
83
+ export { Button };
84
+ export type { ButtonProps };
@@ -1,7 +1,9 @@
1
+ import { Button as RaButton } from './Button';
1
2
  import { Toolbar } from '@/components/ra-forms';
3
+ import { PlusCircleOutlined } from '@ant-design/icons';
2
4
  import { Breakpoint, Button, Dialog } from '@mui/material';
3
5
  import { CreateBase, UseCreateMutateParams, useResourceContext, useTranslate } from 'ra-core';
4
- import { CreateButton, CreateButtonProps, CreateProps, SaveButton } from 'ra-ui-materialui';
6
+ import { ButtonProps, CreateButton, CreateButtonProps, CreateProps, SaveButton } from 'ra-ui-materialui';
5
7
  import React, { Children, PropsWithChildren, useCallback, useState } from 'react';
6
8
  import { FieldValues, useFormContext } from 'react-hook-form';
7
9
  import { useQueryClient } from 'react-query';
@@ -27,11 +29,14 @@ function setListQueryData(res: any, data: any) {
27
29
  return res && res.data ? { ...res, data: updateColl(res.data, data), total: res.total + 1 } : res;
28
30
  }
29
31
 
30
- type ResponsiveButtonProps = CreateButtonProps & {
31
- label?: string;
32
- onClick?: () => void;
33
- };
32
+ type ResponsiveButtonProps = CreateButtonProps &
33
+ ButtonProps & {
34
+ label?: string;
35
+ onClick?: () => void;
36
+ disableFloatingButton?: boolean;
37
+ };
34
38
  function ResponsiveButton(props: ResponsiveButtonProps): JSX.Element {
39
+ const { disableFloatingButton, startIcon = <PlusCircleOutlined />, ...rest } = props;
35
40
  const handleClick = useCallback(
36
41
  (event: any) => {
37
42
  (event as Event).preventDefault();
@@ -40,7 +45,15 @@ function ResponsiveButton(props: ResponsiveButtonProps): JSX.Element {
40
45
  },
41
46
  [props]
42
47
  );
43
- return <CreateButton {...props} onClick={handleClick} />;
48
+ return disableFloatingButton ? (
49
+ <RaButton {...rest} onClick={handleClick}>
50
+ {startIcon as any}
51
+ </RaButton>
52
+ ) : (
53
+ <CreateButton {...props} onClick={handleClick}>
54
+ {startIcon as any}
55
+ </CreateButton>
56
+ );
44
57
  }
45
58
  type CloseDialogFunction = () => void;
46
59
  type SubmitFunction = (values: FieldValues, closeDialog: CloseDialogFunction) => void;
@@ -72,6 +85,12 @@ type CreateInDialogButtonProps = PropsWithChildren &
72
85
  maxWidth: Breakpoint;
73
86
  fullWidth?: boolean;
74
87
  fullScreen?: boolean;
88
+ /**
89
+ * Indicates whether the floating button should be disabled.
90
+ * Default is false, this mean that the floating button will be displayed on small screens.
91
+ * **If you have multiple buttons on the same page, they will be displayed over each other! **
92
+ */
93
+ disableFloatingButton?: boolean;
75
94
  scroll: 'paper' | 'body' | undefined;
76
95
  /**
77
96
  * Custom handler for the submit event, in this case you are responsible for closing the dialog.
@@ -122,7 +141,7 @@ function CreateInDialogButton(props: CreateInDialogButtonProps) {
122
141
 
123
142
  return (
124
143
  <>
125
- <ResponsiveButton {...rest} onClick={handleOpen} />
144
+ <ResponsiveButton {...(rest as any)} onClick={handleOpen} />
126
145
  <CreateBase
127
146
  {...props}
128
147
  mutationOptions={{
@@ -137,11 +156,6 @@ function CreateInDialogButton(props: CreateInDialogButtonProps) {
137
156
  maxWidth={maxWidth}
138
157
  fullWidth={fullWidth}
139
158
  fullScreen={fullScreen}
140
- sx={{
141
- '& .MuiToolbar-root': {
142
- position: 'relative !important'
143
- }
144
- }}
145
159
  >
146
160
  {React.isValidElement(Child)
147
161
  ? React.cloneElement(Child, {
@@ -1,8 +1,10 @@
1
+ import { Button } from './Button';
1
2
  import { Toolbar } from '@/components/ra-forms';
2
- import { Breakpoint, Button, Dialog } from '@mui/material';
3
- import { EditBase, UseUpdateMutateParams, useRecordContext, useTranslate } from 'ra-core';
3
+ import { Breakpoint, Dialog } from '@mui/material';
4
+ import { EditBase, UseUpdateMutateParams, useRecordContext } from 'ra-core';
4
5
  import { EditButton, EditProps, SaveButton } from 'ra-ui-materialui';
5
6
  import React, { Children, PropsWithChildren, useCallback, useState } from 'react';
7
+ import { FieldValues, useFormContext } from 'react-hook-form';
6
8
 
7
9
  type ResponsiveButtonProps = {
8
10
  label?: string;
@@ -21,6 +23,34 @@ function ResponsiveButton(props: ResponsiveButtonProps): JSX.Element {
21
23
  return <EditButton {...props} onClick={handleClick} />;
22
24
  }
23
25
 
26
+ type CloseDialogFunction = () => void;
27
+ type SubmitFunction = (values: FieldValues, closeDialog: CloseDialogFunction) => void;
28
+ type SubmitButtonProps = {
29
+ onSubmit: SubmitFunction;
30
+ closeDialog: CloseDialogFunction;
31
+ };
32
+ function SubmitButton(props: SubmitButtonProps) {
33
+ const { onSubmit, closeDialog } = props;
34
+ const { handleSubmit } = useFormContext();
35
+ const handleClick = useCallback(
36
+ (event: any) => {
37
+ (event as Event).preventDefault();
38
+ (event as Event).stopPropagation();
39
+ handleSubmit((fieldValues) => onSubmit(fieldValues, closeDialog))();
40
+ },
41
+ [handleSubmit, onSubmit, closeDialog]
42
+ );
43
+ return (
44
+ <Button
45
+ disableIconOnly
46
+ onClick={handleClick}
47
+ color="primary"
48
+ variant="contained"
49
+ size="medium"
50
+ label="ra.action.save"
51
+ />
52
+ );
53
+ }
24
54
  type EditInDialogButtonProps = PropsWithChildren &
25
55
  EditProps &
26
56
  ResponsiveButtonProps & {
@@ -28,9 +58,25 @@ type EditInDialogButtonProps = PropsWithChildren &
28
58
  fullWidth?: boolean;
29
59
  fullScreen?: boolean;
30
60
  scroll: 'paper' | 'body' | undefined;
61
+ /**
62
+ * Custom handler for the submit event, in this case you are responsible for closing the dialog.
63
+ * @example
64
+ *
65
+ * const handleSubmit = (values, closeDialog) => {
66
+ * console.log(values); // { title: 'Hello World' }
67
+ * closeDialog();
68
+ * }
69
+ * <CreateInDialogButton onSubmit={handleSubmit}>
70
+ * <SimpleForm>
71
+ * <TextInput source="title" />
72
+ * </SimpleForm>
73
+ * </CreateInDialogButton>
74
+ *
75
+ */
76
+ onSubmit?: SubmitFunction;
31
77
  };
32
78
  function EditInDialogButton(props: EditInDialogButtonProps): JSX.Element {
33
- const { children, maxWidth = 'md', fullWidth = true, fullScreen, mutationOptions, scroll, ...rest } = props;
79
+ const { children, maxWidth = 'md', fullWidth = true, fullScreen, mutationOptions, onSubmit, scroll, ...rest } = props;
34
80
  const [open, setOpen] = useState(false);
35
81
  const Child = Children.only(children);
36
82
  const handleOpen = useCallback(() => setOpen(true), []);
@@ -43,7 +89,6 @@ function EditInDialogButton(props: EditInDialogButtonProps): JSX.Element {
43
89
  [handleClose, props.mutationOptions]
44
90
  );
45
91
  const record = useRecordContext();
46
- const translate = useTranslate();
47
92
  return (
48
93
  <>
49
94
  <ResponsiveButton {...rest} onClick={handleOpen} />
@@ -64,11 +109,6 @@ function EditInDialogButton(props: EditInDialogButtonProps): JSX.Element {
64
109
  maxWidth={maxWidth}
65
110
  fullScreen={fullScreen}
66
111
  keepMounted={false}
67
- sx={{
68
- '& .MuiToolbar-root': {
69
- position: 'relative !important'
70
- }
71
- }}
72
112
  >
73
113
  {React.isValidElement(Child)
74
114
  ? React.cloneElement(Child, {
@@ -76,10 +116,18 @@ function EditInDialogButton(props: EditInDialogButtonProps): JSX.Element {
76
116
  modal: true,
77
117
  toolbar: (
78
118
  <Toolbar>
79
- <Button variant="text" size="medium" onClick={handleClose}>
80
- {translate('ra.action.cancel')}
81
- </Button>
82
- <SaveButton type="button" />
119
+ <Button
120
+ disableIconOnly
121
+ variant="text"
122
+ size="medium"
123
+ onClick={handleClose}
124
+ label="ra.action.cancel"
125
+ />
126
+ {onSubmit ? (
127
+ <SubmitButton onSubmit={onSubmit!} closeDialog={handleClose} />
128
+ ) : (
129
+ <SaveButton type="button" />
130
+ )}
83
131
  </Toolbar>
84
132
  )
85
133
  })
@@ -1,3 +1,4 @@
1
+ export * from './Button';
1
2
  export * from './CreateInDialogButton';
2
3
  export * from './EditInDialogButton';
3
4
  export * from './ImpersonateUserButton';
@@ -85,7 +85,6 @@ const Create = styled(CreateWithDefaults, { slot: 'root' })(({ theme }: { theme:
85
85
  backgroundColor: theme.palette.background.default
86
86
  },
87
87
  '& .RaToolbar-mobileToolbar': {
88
- position: 'initial !important',
89
88
  paddingLeft: `${theme.spacing(2.5)} !important`,
90
89
  paddingRight: `${theme.spacing(2.5)} !important`,
91
90
  paddingTop: '0 !important'
@@ -16,7 +16,6 @@ const StyledEdit = styled(RaEdit, { slot: 'root' })(({ theme }) => ({
16
16
  },
17
17
 
18
18
  '& .RaToolbar-mobileToolbar': {
19
- position: 'initial !important',
20
19
  paddingLeft: `${theme.spacing(2.5)} !important`,
21
20
  paddingRight: `${theme.spacing(2.5)} !important`,
22
21
  paddingTop: '0 !important'
@@ -15,22 +15,17 @@ const StyledGrid = styled(Grid, {
15
15
  // This style must be applied only to root toolbars used to save data in the form.
16
16
  // Other toolbars must be handled outside this rule.
17
17
  '& .MuiToolbar-root.RaToolbar-desktopToolbar': {
18
- position: 'initial',
19
- // marginTop: theme.spacing(2.5),
20
18
  marginLeft: `-${theme.spacing(3)}`,
21
19
  marginRight: `-${theme.spacing(3)}`,
22
20
  marginBottom: `-${theme.spacing(2)}`,
23
- // borderTop: `1px solid ${theme.palette.divider}`,
24
21
  paddingTop: theme.spacing(2.5),
25
22
  paddingBottom: theme.spacing(2.5),
26
23
  [theme.breakpoints.down('sm')]: {
27
- position: 'initial !important',
28
24
  width: 'auto !important',
29
25
  marginRight: 0
30
26
  }
31
27
  },
32
28
  '& .RaToolbar-mobileToolbar': {
33
- position: 'initial !important',
34
29
  paddingTop: `${theme.spacing(2.5)} !important`,
35
30
  paddingLeft: '0 !important',
36
31
  paddingRight: '0 !important',
@@ -49,7 +49,6 @@ function SimpleForm({
49
49
  sx={{
50
50
  ...sx,
51
51
  '& .MuiToolbar-root': {
52
- position: 'initial',
53
52
  paddingLeft: theme.spacing(2.5),
54
53
  paddingRight: theme.spacing(2.5),
55
54
  paddingBottom: theme.spacing(2.5),
@@ -73,7 +73,6 @@ function TabbedForm(props: TabbedFormProps): JSX.Element {
73
73
  mr: 2.5
74
74
  },
75
75
  '& .MuiToolbar-root.RaToolbar-desktopToolbar': {
76
- position: 'initial',
77
76
  paddingTop: modal ? theme.spacing(2.5) : 0
78
77
  },
79
78
  '& .MuiToolbar-root': {
@@ -6,6 +6,7 @@ const StyledToolbar = styled(RaToolbar, { slot: 'Root' })(({ theme }: { theme: a
6
6
  ...theme.mixins.toolbar,
7
7
  backgroundColor: theme.palette.background.paper,
8
8
  justifyContent: 'flex-end',
9
+ position: 'initial !important',
9
10
 
10
11
  '& .RaToolbar-defaultToolbar': {
11
12
  justifyContent: 'right',
@@ -20,8 +21,7 @@ const StyledToolbar = styled(RaToolbar, { slot: 'Root' })(({ theme }: { theme: a
20
21
  }));
21
22
 
22
23
  function Toolbar(props: ToolbarProps): JSX.Element {
23
- // @ts-ignore
24
- return <StyledToolbar {...props} />;
24
+ return <StyledToolbar {...(props as any)} />;
25
25
  }
26
26
 
27
27
  export { Toolbar };
package/src/index.ts CHANGED
@@ -13,7 +13,6 @@ export {
13
13
  ArrayInputContext,
14
14
  BooleanField,
15
15
  BulkDeleteWithConfirmButton,
16
- Button,
17
16
  ChipField,
18
17
  Confirm,
19
18
  CreateButton,
@@ -27,7 +27,7 @@ function CategorySubmitButton() {
27
27
  console.log(values);
28
28
  }
29
29
  return (
30
- <CreateInDialogButton onSubmit={handleSubmit} redirect="list" label="Submit">
30
+ <CreateInDialogButton onSubmit={handleSubmit} redirect="list" label="Submit" size="medium">
31
31
  <SimpleForm>
32
32
  <TextInput source="description" validate={required()} fullWidth />
33
33
  </SimpleForm>
@@ -55,6 +55,9 @@ function CategoryList() {
55
55
  <EditInDialogButton>
56
56
  <CategoryForm />
57
57
  </EditInDialogButton>
58
+ <EditInDialogButton label="Edit with Submit" onSubmit={console.log}>
59
+ <CategoryForm />
60
+ </EditInDialogButton>
58
61
  </Datagrid>
59
62
  </List>
60
63
  );