@zesty-io/material 0.0.4 → 0.1.2

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 (76) hide show
  1. package/es/ConfirmDialog/ConfirmDialog.stories.d.ts +6 -0
  2. package/es/ConfirmDialog/ConfirmDialog.stories.js +24 -0
  3. package/es/ConfirmDialog/index.d.ts +18 -0
  4. package/es/ConfirmDialog/index.js +11 -0
  5. package/es/ConfirmModal/ConfirmModal.stories.d.ts +6 -0
  6. package/es/ConfirmModal/ConfirmModal.stories.js +24 -0
  7. package/es/ConfirmModal/index.d.ts +18 -0
  8. package/es/ConfirmModal/index.js +11 -0
  9. package/es/CopyButton/index.js +3 -3
  10. package/es/FieldTypeColor/FieldTypeColor.stories.d.ts +5 -0
  11. package/es/FieldTypeColor/FieldTypeColor.stories.js +21 -0
  12. package/es/FieldTypeColor/index.d.ts +6 -0
  13. package/es/FieldTypeColor/index.js +16 -0
  14. package/es/FieldTypeDate/FieldTypeDate.stories.d.ts +5 -0
  15. package/es/FieldTypeDate/FieldTypeDate.stories.js +17 -0
  16. package/es/FieldTypeDate/index.d.ts +9 -0
  17. package/es/FieldTypeDate/index.js +10 -0
  18. package/es/FieldTypeDateTime/FieldTypeDateTime.stories.d.ts +5 -0
  19. package/es/FieldTypeDateTime/FieldTypeDateTime.stories.js +17 -0
  20. package/es/FieldTypeDateTime/index.d.ts +9 -0
  21. package/es/FieldTypeDateTime/index.js +10 -0
  22. package/es/FieldTypeDropdown/FieldTypeDropwdon.stories.d.ts +5 -0
  23. package/es/FieldTypeDropdown/FieldTypeDropwdon.stories.js +35 -0
  24. package/es/FieldTypeDropdown/index.d.ts +11 -0
  25. package/es/FieldTypeDropdown/index.js +10 -0
  26. package/es/FieldTypeNumber/FieldTypeNumber.stories.d.ts +5 -0
  27. package/es/FieldTypeNumber/FieldTypeNumber.stories.js +21 -0
  28. package/es/FieldTypeNumber/index.d.ts +6 -0
  29. package/es/FieldTypeNumber/index.js +7 -0
  30. package/es/FieldTypeOneToMany/FieldTypeOneToMany.stories.d.ts +5 -0
  31. package/es/FieldTypeOneToMany/FieldTypeOneToMany.stories.js +28 -0
  32. package/es/FieldTypeOneToMany/index.d.ts +32 -0
  33. package/es/FieldTypeOneToMany/index.js +29 -0
  34. package/es/FieldTypeOneToOne/FieldTypeOneToOne.stories.d.ts +5 -0
  35. package/es/FieldTypeOneToOne/FieldTypeOneToOne.stories.js +28 -0
  36. package/es/FieldTypeOneToOne/index.d.ts +34 -0
  37. package/es/FieldTypeOneToOne/index.js +33 -0
  38. package/es/FieldTypeSort/FieldTypeSort.stories.js +3 -1
  39. package/es/FieldTypeSort/index.d.ts +1 -1
  40. package/es/FieldTypeSort/index.js +17 -29
  41. package/es/FieldTypeText/FieldTypeText.stories.js +6 -6
  42. package/es/FieldTypeText/index.d.ts +1 -1
  43. package/es/FieldTypeText/index.js +4 -12
  44. package/es/FieldTypeUrl/index.d.ts +1 -1
  45. package/es/FieldTypeUrl/index.js +8 -16
  46. package/es/index.d.ts +11 -0
  47. package/es/index.js +11 -0
  48. package/es/theme/index.js +13 -2
  49. package/es/utils/virtualization.d.ts +2 -0
  50. package/es/utils/virtualization.js +63 -0
  51. package/package.json +7 -3
  52. package/src/ConfirmDialog/ConfirmDialog.stories.tsx +35 -0
  53. package/src/ConfirmDialog/index.tsx +50 -0
  54. package/src/CopyButton/index.tsx +6 -6
  55. package/src/FieldTypeColor/FieldTypeColor.stories.tsx +35 -0
  56. package/src/FieldTypeColor/index.tsx +43 -0
  57. package/src/FieldTypeDate/FieldTypeDate.stories.tsx +23 -0
  58. package/src/FieldTypeDate/index.tsx +34 -0
  59. package/src/FieldTypeDateTime/FieldTypeDateTime.stories.tsx +23 -0
  60. package/src/FieldTypeDateTime/index.tsx +35 -0
  61. package/src/FieldTypeDropdown/FieldTypeDropwdon.stories.tsx +52 -0
  62. package/src/FieldTypeDropdown/index.tsx +41 -0
  63. package/src/FieldTypeNumber/FieldTypeNumber.stories.tsx +35 -0
  64. package/src/FieldTypeNumber/index.tsx +22 -0
  65. package/src/FieldTypeOneToMany/FieldTypeOneToMany.stories.tsx +47 -0
  66. package/src/FieldTypeOneToMany/index.tsx +90 -0
  67. package/src/FieldTypeOneToOne/FieldTypeOneToOne.stories.tsx +46 -0
  68. package/src/FieldTypeOneToOne/index.tsx +96 -0
  69. package/src/FieldTypeSort/FieldTypeSort.stories.tsx +3 -2
  70. package/src/FieldTypeSort/index.tsx +15 -68
  71. package/src/FieldTypeText/FieldTypeText.stories.tsx +11 -9
  72. package/src/FieldTypeText/index.tsx +11 -19
  73. package/src/FieldTypeUrl/index.tsx +12 -19
  74. package/src/index.ts +11 -0
  75. package/src/theme/index.ts +15 -2
  76. package/src/utils/virtualization.tsx +107 -0
@@ -3,5 +3,5 @@ import { OutlinedTextFieldProps } from '@mui/material/TextField';
3
3
  export interface FieldTypeSortProps extends Omit<OutlinedTextFieldProps, 'variant'> {
4
4
  value: string;
5
5
  }
6
- declare const FieldTypeSort: ({ value, InputProps, InputLabelProps, inputProps, sx, ...props }: FieldTypeSortProps) => JSX.Element;
6
+ declare const FieldTypeSort: ({ label, value, InputProps, required, ...props }: FieldTypeSortProps) => JSX.Element;
7
7
  export default FieldTypeSort;
@@ -1,34 +1,22 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useRef } from 'react';
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
2
  import MuiTextField from '@mui/material/TextField';
4
- import { Button, InputAdornment } from '@mui/material';
3
+ import { Button, FormControl, FormLabel, InputAdornment } from '@mui/material';
5
4
  import AddIcon from '@mui/icons-material/Add';
6
5
  import RemoveIcon from '@mui/icons-material/Remove';
7
- const FieldTypeSort = ({ value, InputProps, InputLabelProps, inputProps, sx, ...props }) => {
8
- const inputRef = useRef(null);
9
- return (_jsx(MuiTextField, { size: "small", variant: 'outlined', type: 'number', value: value, sx: {
10
- width: 165,
11
- // Spread props at the end to allow sx prop overrides
12
- ...sx
13
- }, InputProps: {
14
- startAdornment: (_jsx(InputAdornment, { position: "start", children: _jsx(Button, { size: "small", variant: "contained", onClick: () => {
15
- if (inputRef.current)
16
- inputRef.current.value = String(+inputRef.current.value + 1);
17
- }, children: _jsx(AddIcon, { fontSize: 'small' }) }) })),
18
- endAdornment: (_jsx(InputAdornment, { position: "end", children: _jsx(Button, { size: "small", variant: "contained", onClick: () => {
19
- if (inputRef.current)
20
- inputRef.current.value = String(+inputRef.current.value - 1);
21
- }, children: _jsx(RemoveIcon, { fontSize: 'small' }) }) })),
22
- // Spread props at the end to allow Input prop overrides
23
- ...InputProps,
24
- }, InputLabelProps: {
25
- shrink: true,
26
- // Spread props at the end to allow InputLabel prop overrides
27
- ...InputLabelProps,
28
- }, inputProps: {
29
- ref: inputRef,
30
- // Spread props at the end to allow inputProps prop overrides
31
- ...inputProps,
32
- }, ...props }));
6
+ const FieldTypeSort = ({ label, value, InputProps, required, ...props }) => {
7
+ return (_jsxs(FormControl, { fullWidth: true, required: required, children: [_jsx(FormLabel, { children: label }), _jsx(MuiTextField, { size: "small", variant: 'outlined', type: 'number', value: value, InputProps: {
8
+ startAdornment: (_jsx(InputAdornment, { position: "start", children: _jsx(Button, { size: "small", variant: "contained", onClick: (e) => {
9
+ // References input via event in order to modify its value
10
+ const input = e.currentTarget?.parentElement?.parentElement?.childNodes?.[1];
11
+ input.value = String(+input.value - 1);
12
+ }, children: _jsx(RemoveIcon, { fontSize: 'small' }) }) })),
13
+ endAdornment: (_jsx(InputAdornment, { position: "end", children: _jsx(Button, { size: "small", variant: "contained", onClick: (e) => {
14
+ // References input via event in order to modify its value
15
+ const input = e.currentTarget?.parentElement?.parentElement?.childNodes?.[1];
16
+ input.value = String(+input.value + 1);
17
+ }, children: _jsx(AddIcon, { fontSize: 'small' }) }) })),
18
+ // Spread props at the end to allow Input prop overrides
19
+ ...InputProps,
20
+ }, ...props })] }));
33
21
  };
34
22
  export default FieldTypeSort;
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useState } from 'react';
3
3
  import FieldTypeText from './';
4
4
  export default {
@@ -11,19 +11,19 @@ const Template = (args) => {
11
11
  const handleOnChange = (e) => {
12
12
  setValue(e.target.value);
13
13
  };
14
- return (_jsx(FieldTypeText, { ...args, value: value, onChange: handleOnChange }));
14
+ return (_jsx(_Fragment, { children: _jsx(FieldTypeText, { ...args, value: value, onChange: handleOnChange }) }));
15
15
  };
16
16
  export const Default = Template.bind({});
17
17
  Default.args = {
18
18
  placeholder: 'Placeholder Text...',
19
- label: 'Some label',
20
- fullWidth: true,
19
+ label: 'Text label',
20
+ helperText: 'Text helper text',
21
21
  };
22
22
  export const TextArea = Template.bind({});
23
23
  TextArea.args = {
24
24
  multiline: true,
25
25
  rows: 4,
26
26
  placeholder: 'Placeholder Text...',
27
- label: 'Some Label',
28
- fullWidth: true,
27
+ label: 'Text Label',
28
+ helperText: 'Text helper text',
29
29
  };
@@ -8,5 +8,5 @@ export interface FieldTypeTextProps extends Omit<OutlinedTextFieldProps, 'varian
8
8
  maxLength?: number;
9
9
  value: string;
10
10
  }
11
- declare const FieldTypeText: ({ maxLength, value, helperText, InputProps, InputLabelProps, ...props }: FieldTypeTextProps) => JSX.Element;
11
+ declare const FieldTypeText: ({ label, maxLength, value, helperText, required, ...props }: FieldTypeTextProps) => JSX.Element;
12
12
  export default FieldTypeText;
@@ -1,15 +1,7 @@
1
- import { Fragment as _Fragment, jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import MuiTextField from '@mui/material/TextField';
3
- import { InputAdornment } from '@mui/material';
4
- const FieldTypeText = ({ maxLength = 150, value, helperText, InputProps, InputLabelProps, ...props }) => {
5
- return (_jsx(MuiTextField, { size: "small", variant: 'outlined', value: value, InputProps: {
6
- endAdornment: (_jsx(InputAdornment, { position: "end", children: _jsxs(_Fragment, { children: [value.length, "/", maxLength] }) })),
7
- // Spread props at the end to allow Input prop overrides
8
- ...InputProps,
9
- }, InputLabelProps: {
10
- shrink: true,
11
- // Spread props at the end to allow InputLabel prop overrides
12
- ...InputLabelProps,
13
- }, error: value.length > maxLength, helperText: value.length > maxLength ? 'Your input is over the specified limit' : helperText, ...props }));
3
+ import { FormControl, FormLabel, Box } from '@mui/material';
4
+ const FieldTypeText = ({ label, maxLength = 150, value, helperText, required, ...props }) => {
5
+ return (_jsxs(FormControl, { fullWidth: true, required: required, children: [_jsxs(FormLabel, { sx: { display: 'flex', justifyContent: 'space-between', '& .MuiFormLabel-asterisk': { order: 2 } }, children: [_jsx(Box, { sx: { order: 1 }, children: label }), _jsxs(Box, { sx: { order: 3, flex: 1, textAlign: 'right' }, children: [value?.length, "/", maxLength] })] }), _jsx(MuiTextField, { size: "small", variant: 'outlined', value: value, error: value?.length > maxLength, helperText: value?.length > maxLength ? 'Your input is over the specified limit' : helperText, ...props })] }));
14
6
  };
15
7
  export default FieldTypeText;
@@ -8,5 +8,5 @@ export interface FieldTypeUrlProps extends Omit<OutlinedTextFieldProps, 'variant
8
8
  maxLength?: number;
9
9
  value: string;
10
10
  }
11
- declare const FieldTypeUrl: ({ maxLength, value, helperText, InputProps, InputLabelProps, inputProps, ...props }: FieldTypeUrlProps) => JSX.Element;
11
+ declare const FieldTypeUrl: ({ label, maxLength, value, helperText, required, inputProps, ...props }: FieldTypeUrlProps) => JSX.Element;
12
12
  export default FieldTypeUrl;
@@ -1,21 +1,13 @@
1
- import { Fragment as _Fragment, jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useRef } from 'react';
3
3
  import MuiTextField from '@mui/material/TextField';
4
- import { InputAdornment } from '@mui/material';
5
- const FieldTypeUrl = ({ maxLength = 2000, value, helperText, InputProps, InputLabelProps, inputProps, ...props }) => {
4
+ import { FormControl, FormLabel, Box } from '@mui/material';
5
+ const FieldTypeUrl = ({ label, maxLength = 2000, value, helperText, required, inputProps, ...props }) => {
6
6
  const inputRef = useRef(null);
7
- return (_jsx(MuiTextField, { size: "small", type: 'url', variant: 'outlined', value: value, InputProps: {
8
- endAdornment: (_jsx(InputAdornment, { position: "end", children: _jsxs(_Fragment, { children: [value.length, "/", maxLength] }) })),
9
- // Spread props at the end to allow Input prop overrides
10
- ...InputProps,
11
- }, InputLabelProps: {
12
- shrink: true,
13
- // Spread props at the end to allow InputLabel prop overrides
14
- ...InputLabelProps,
15
- }, inputProps: {
16
- ref: inputRef,
17
- // Spread props at the end to allow inputProps prop overrides
18
- ...inputProps,
19
- }, error: (value && !inputRef.current?.validity.valid) || value.length > maxLength, helperText: value.length > maxLength ? 'Your input is over the specified limit' : (value && !inputRef.current?.validity.valid) ? 'Your input is not a valid url' : helperText, ...props }));
7
+ return (_jsxs(FormControl, { fullWidth: true, required: required, children: [_jsxs(FormLabel, { sx: { display: 'flex', justifyContent: 'space-between', '& .MuiFormLabel-asterisk': { order: 2 } }, children: [_jsx(Box, { sx: { order: 1 }, children: label }), _jsxs(Box, { sx: { order: 3, flex: 1, textAlign: 'right' }, children: [value?.length, "/", maxLength] })] }), _jsx(MuiTextField, { size: "small", type: 'url', variant: 'outlined', value: value, inputProps: {
8
+ ref: inputRef,
9
+ // Spread props at the end to allow inputProps prop overrides
10
+ ...inputProps,
11
+ }, error: (value && !inputRef.current?.validity.valid) || value?.length > maxLength, helperText: value?.length > maxLength ? 'Your input is over the specified limit' : (value && !inputRef.current?.validity.valid) ? 'Your input is not a valid url' : helperText, ...props })] }));
20
12
  };
21
13
  export default FieldTypeUrl;
package/es/index.d.ts CHANGED
@@ -1,2 +1,13 @@
1
1
  export { default as theme } from './theme';
2
2
  export { default as FieldTypeText } from './FieldTypeText';
3
+ export { default as FieldTypeSort } from './FieldTypeSort';
4
+ export { default as FieldTypeUrl } from './FieldTypeUrl';
5
+ export { default as FieldTypeDate } from './FieldTypeDate';
6
+ export { default as FieldTypeDateTime } from './FieldTypeDateTime';
7
+ export { default as FieldTypeColor } from './FieldTypeColor';
8
+ export { default as FieldTypeNumber } from './FieldTypeNumber';
9
+ export { default as FieldTypeDropdown } from './FieldTypeDropdown';
10
+ export { default as FieldTypeOneToOne } from './FieldTypeOneToOne';
11
+ export { default as FieldTypeOneToMany } from './FieldTypeOneToMany';
12
+ export { default as CopyButton } from './CopyButton';
13
+ export { default as ConfirmDialog } from './ConfirmDialog';
package/es/index.js CHANGED
@@ -1,2 +1,13 @@
1
1
  export { default as theme } from './theme';
2
2
  export { default as FieldTypeText } from './FieldTypeText';
3
+ export { default as FieldTypeSort } from './FieldTypeSort';
4
+ export { default as FieldTypeUrl } from './FieldTypeUrl';
5
+ export { default as FieldTypeDate } from './FieldTypeDate';
6
+ export { default as FieldTypeDateTime } from './FieldTypeDateTime';
7
+ export { default as FieldTypeColor } from './FieldTypeColor';
8
+ export { default as FieldTypeNumber } from './FieldTypeNumber';
9
+ export { default as FieldTypeDropdown } from './FieldTypeDropdown';
10
+ export { default as FieldTypeOneToOne } from './FieldTypeOneToOne';
11
+ export { default as FieldTypeOneToMany } from './FieldTypeOneToMany';
12
+ export { default as CopyButton } from './CopyButton';
13
+ export { default as ConfirmDialog } from './ConfirmDialog';
package/es/theme/index.js CHANGED
@@ -11,8 +11,8 @@ theme = createTheme(theme, {
11
11
  styleOverrides: {
12
12
  root: {
13
13
  minWidth: 'auto',
14
- }
15
- }
14
+ },
15
+ },
16
16
  },
17
17
  MuiTooltip: {
18
18
  styleOverrides: {
@@ -34,9 +34,20 @@ theme = createTheme(theme, {
34
34
  },
35
35
  },
36
36
  },
37
+ MuiFormLabel: {
38
+ styleOverrides: {
39
+ root: {
40
+ color: theme.palette.primary.dark,
41
+ },
42
+ asterisk: {
43
+ color: theme.palette.error.main,
44
+ }
45
+ },
46
+ },
37
47
  MuiToggleButton: {
38
48
  styleOverrides: {
39
49
  root: ({ ownerState, theme }) => ({
50
+ backgroundColor: `${theme.palette[ownerState.color].contrastText} !important`,
40
51
  ...(ownerState.selected && {
41
52
  color: `${theme.palette[ownerState.color].contrastText} !important`,
42
53
  backgroundColor: `${theme.palette[ownerState.color].main} !important`,
@@ -0,0 +1,2 @@
1
+ import * as React from 'react';
2
+ export declare const ListboxComponent: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLElement> & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,63 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import * as React from 'react';
3
+ import useMediaQuery from '@mui/material/useMediaQuery';
4
+ import ListSubheader from '@mui/material/ListSubheader';
5
+ import { useTheme } from '@mui/material/styles';
6
+ import { VariableSizeList } from 'react-window';
7
+ import Typography from '@mui/material/Typography';
8
+ const LISTBOX_PADDING = 8; // px
9
+ function renderRow(props) {
10
+ const { data, index, style } = props;
11
+ const dataSet = data[index];
12
+ const inlineStyle = {
13
+ ...style,
14
+ top: style.top + LISTBOX_PADDING,
15
+ };
16
+ if (dataSet.hasOwnProperty('group')) {
17
+ return (_jsx(ListSubheader, { component: "div", style: inlineStyle, children: dataSet.group }, dataSet.key));
18
+ }
19
+ return (_jsx(Typography, { component: "li", ...dataSet[0], noWrap: true, style: inlineStyle, children: dataSet[1] }));
20
+ }
21
+ const OuterElementContext = React.createContext({});
22
+ const OuterElementType = React.forwardRef((props, ref) => {
23
+ const outerProps = React.useContext(OuterElementContext);
24
+ return _jsx("div", { ref: ref, ...props, ...outerProps });
25
+ });
26
+ function useResetCache(data) {
27
+ const ref = React.useRef(null);
28
+ React.useEffect(() => {
29
+ if (ref.current != null) {
30
+ ref.current.resetAfterIndex(0, true);
31
+ }
32
+ }, [data]);
33
+ return ref;
34
+ }
35
+ // Adapter for react-window
36
+ export const ListboxComponent = React.forwardRef(function ListboxComponent(props, ref) {
37
+ const { children, ...other } = props;
38
+ const itemData = [];
39
+ children.forEach((item) => {
40
+ itemData.push(item);
41
+ itemData.push(...(item.children || []));
42
+ });
43
+ const theme = useTheme();
44
+ const smUp = useMediaQuery(theme.breakpoints.up('sm'), {
45
+ noSsr: true,
46
+ });
47
+ const itemCount = itemData.length;
48
+ const itemSize = smUp ? 36 : 48;
49
+ const getChildSize = (child) => {
50
+ if (child.hasOwnProperty('group')) {
51
+ return 48;
52
+ }
53
+ return itemSize;
54
+ };
55
+ const getHeight = () => {
56
+ if (itemCount > 8) {
57
+ return 8 * itemSize;
58
+ }
59
+ return itemData.map(getChildSize).reduce((a, b) => a + b, 0);
60
+ };
61
+ const gridRef = useResetCache(itemCount);
62
+ return (_jsx("div", { ref: ref, children: _jsx(OuterElementContext.Provider, { value: other, children: _jsx(VariableSizeList, { itemData: itemData, height: getHeight() + 2 * LISTBOX_PADDING, width: "100%", ref: gridRef, outerElementType: OuterElementType, innerElementType: "ul", itemSize: (index) => getChildSize(itemData[index]), overscanCount: 5, itemCount: itemCount, children: renderRow }) }) }));
63
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zesty-io/material",
3
- "version": "0.0.4",
3
+ "version": "0.1.2",
4
4
  "description": "Contains custom components which are in addition to the @mui design-system",
5
5
  "author": "Zesty.io",
6
6
  "license": "MIT",
@@ -16,7 +16,7 @@
16
16
  "module": "es/index.js",
17
17
  "types": "es/index.d.ts",
18
18
  "scripts": {
19
- "build": "tsc",
19
+ "build": "npm ci && tsc",
20
20
  "prerelease": "npm test",
21
21
  "release": "npm run build && npm publish --access public",
22
22
  "release:alpha": "npm run build && npm publish --access public --tag alpha",
@@ -30,7 +30,10 @@
30
30
  "@emotion/react": "^11.9.0",
31
31
  "@emotion/styled": "^11.8.1",
32
32
  "@mui/icons-material": "^5.6.2",
33
- "@mui/material": "^5.6.4"
33
+ "@mui/material": "^5.6.4",
34
+ "@mui/x-date-pickers": "^5.0.0-alpha.5",
35
+ "date-fns": "^2.28.0",
36
+ "react-window": "^1.8.7"
34
37
  },
35
38
  "devDependencies": {
36
39
  "@babel/core": "^7.17.10",
@@ -40,6 +43,7 @@
40
43
  "@storybook/addon-links": "^6.4.22",
41
44
  "@storybook/react": "^6.4.22",
42
45
  "@storybook/testing-library": "0.0.11",
46
+ "@types/react-window": "^1.8.5",
43
47
  "babel-loader": "^8.2.5",
44
48
  "gh-pages": "^3.2.3",
45
49
  "react": "^18.1.0",
@@ -0,0 +1,35 @@
1
+ import { useState } from 'react';
2
+ import { Story, Meta } from '@storybook/react/types-6-0';
3
+ import { Button, Stack } from '@mui/material';
4
+ import ConfirmDialog, { ConfirmDialogProps } from '.';
5
+
6
+ export default {
7
+ title: 'ConfirmDialog',
8
+ component: ConfirmDialog,
9
+ argType: {},
10
+ } as Meta;
11
+
12
+ const Template: Story<ConfirmDialogProps> = (args) => {
13
+ const [open, setOpen] = useState(false);
14
+
15
+ return (
16
+ <>
17
+ <Button variant="contained" onClick={() => setOpen(true)}>Click me to open</Button>
18
+ <ConfirmDialog {...args} open={open} callback={(confirmed) => setOpen(false) } />
19
+ </>
20
+ );
21
+ };
22
+
23
+ export const Default = Template.bind({});
24
+ Default.args = {
25
+ title: 'Confirm modal title',
26
+ content: 'Confirm modal content',
27
+ };
28
+
29
+ export const CustomChildren = Template.bind({});
30
+ CustomChildren.args = {
31
+ title: 'Confirm modal title',
32
+ content: 'Confirm modal content',
33
+ children: <><Button color="error" variant="contained">Custom 1</Button><Button color="success" variant="contained">Custom 2</Button></>
34
+ };
35
+
@@ -0,0 +1,50 @@
1
+ import { ReactNode } from 'react';
2
+ import Dialog, { DialogProps } from '@mui/material/Dialog';
3
+ import DialogActions from '@mui/material/DialogActions';
4
+ import DialogContent from '@mui/material/DialogContent';
5
+ import DialogContentText from '@mui/material/DialogContentText';
6
+ import DialogTitle from '@mui/material/DialogTitle';
7
+ import { Button } from '@mui/material';
8
+
9
+ export interface ConfirmDialogProps extends Omit<DialogProps, 'title'> {
10
+ /**
11
+ * Title of confirm dialog
12
+ */
13
+ title: string | ReactNode ;
14
+ /**
15
+ * Content of confirm dialog
16
+ */
17
+ content: string | ReactNode ;
18
+ /**
19
+ * Callback of confirm dialog
20
+ */
21
+ callback: (confirmed: boolean) => void ;
22
+ }
23
+
24
+ const ConfirmDialog = ({title, content, onClose, children, callback, ...props }: ConfirmDialogProps) => {
25
+
26
+ return (
27
+ <Dialog
28
+ {...props}
29
+ >
30
+ <DialogTitle>
31
+ {title}
32
+ </DialogTitle>
33
+ <DialogContent>
34
+ <DialogContentText>
35
+ {content}
36
+ </DialogContentText>
37
+ </DialogContent>
38
+ {children ? <DialogActions>{children}</DialogActions> : (
39
+ <DialogActions>
40
+ <Button variant="contained" onClick={() => callback(false)}>No</Button>
41
+ <Button variant="contained" onClick={() => callback(true)} autoFocus>
42
+ Yes
43
+ </Button>
44
+ </DialogActions>
45
+ )}
46
+ </Dialog>
47
+ );
48
+ };
49
+
50
+ export default ConfirmDialog;
@@ -39,15 +39,15 @@ const CopyButton = ({value, sx, ...props }: CopyButtonProps) => {
39
39
  // Spread sx prop at the end to allow sx prop overrides
40
40
  ...sx,
41
41
  }}
42
+ startIcon={copied ? (
43
+ <CheckIcon color='success' fontSize='small' />
44
+ ) : (
45
+ <ContentCopyIcon fontSize='small' />
46
+ )}
42
47
  // Spread props at the end to allow prop overrides
43
48
  {...props}
44
49
  >
45
- {copied ? (
46
- <CheckIcon color='success' fontSize='small' />
47
- ) : (
48
- <ContentCopyIcon fontSize='small' />
49
- )}
50
- {props.children ? props.children : value}
50
+ {props.children ? props.children : value}
51
51
  </Button>
52
52
  );
53
53
  };
@@ -0,0 +1,35 @@
1
+ import { ChangeEvent, useState } from 'react';
2
+ import { Story, Meta } from '@storybook/react/types-6-0';
3
+ import FieldTypeColor, { FieldTypeColorProps } from './';
4
+
5
+ export default {
6
+ title: 'FieldTypeColor',
7
+ component: FieldTypeColor,
8
+ argType: {},
9
+ } as Meta;
10
+
11
+ const Template: Story<FieldTypeColorProps> = (args) => {
12
+ const [value, setValue] = useState('');
13
+
14
+ const handleOnChange = (e: ChangeEvent<HTMLInputElement>) => {
15
+ setValue(e.target.value);
16
+ }
17
+
18
+ return (
19
+ <FieldTypeColor
20
+ {...args}
21
+ value={value}
22
+ onChange={handleOnChange}
23
+ />
24
+ );
25
+ };
26
+
27
+ export const Default = Template.bind({});
28
+ Default.args = {
29
+ placeholder: 'Placeholder Text...',
30
+ label: 'Color label',
31
+ helperText: 'Color helper text',
32
+ };
33
+
34
+
35
+
@@ -0,0 +1,43 @@
1
+ import { useRef } from 'react';
2
+ import MuiTextField, { OutlinedTextFieldProps } from '@mui/material/TextField';
3
+ import { Button, FormControl, FormHelperText, FormLabel, InputAdornment } from '@mui/material';
4
+ import BrushIcon from '@mui/icons-material/Brush';
5
+
6
+ export interface FieldTypeColorProps extends Omit<OutlinedTextFieldProps, 'variant'> {}
7
+
8
+ const FieldTypeColor = ({InputProps, label, required, ...props }: FieldTypeColorProps) => {
9
+
10
+ return (
11
+ <FormControl fullWidth required={required}>
12
+ <FormLabel>{label}</FormLabel>
13
+ <MuiTextField
14
+ size="small"
15
+ variant='outlined'
16
+ type='color'
17
+ InputProps={{
18
+ endAdornment: (
19
+ <InputAdornment position="end">
20
+ <Button
21
+ size="small"
22
+ variant="contained"
23
+ onClick={(e) => {
24
+ // References color input via event in order to open color picker
25
+ const input = e.currentTarget?.parentElement?.parentElement?.firstElementChild as HTMLInputElement;
26
+ input?.click()
27
+ }}
28
+ >
29
+ <BrushIcon fontSize='small' />
30
+ </Button>
31
+ </InputAdornment>
32
+ ),
33
+ // Spread props at the end to allow Input prop overrides
34
+ ...InputProps,
35
+ }}
36
+ // Spread props at the end to allow prop overrides
37
+ {...props}
38
+ />
39
+ </FormControl>
40
+ );
41
+ };
42
+
43
+ export default FieldTypeColor;
@@ -0,0 +1,23 @@
1
+ import {useState} from 'react';
2
+ import { Story, Meta } from '@storybook/react/types-6-0';
3
+ import FieldTypeDate, { FieldTypeDateProps } from '.';
4
+
5
+ export default {
6
+ title: 'FieldTypeDate',
7
+ component: FieldTypeDate,
8
+ argType: {},
9
+ } as Meta;
10
+
11
+ const Template: Story<FieldTypeDateProps> = (args) => {
12
+ const [value, setValue] = useState<Date | null>(null);
13
+
14
+ return (
15
+ <FieldTypeDate {...args} value={value} onChange={(value) => setValue(value)}/>
16
+ );
17
+ };
18
+
19
+ export const Default = Template.bind({});
20
+ Default.args = {
21
+ label: 'Date label',
22
+ helperText: 'Date helper text',
23
+ };
@@ -0,0 +1,34 @@
1
+ import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
2
+ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
3
+ import { DatePicker, DatePickerProps} from '@mui/x-date-pickers/DatePicker';
4
+ import { FormControl, FormLabel, TextField } from '@mui/material';
5
+
6
+ export interface FieldTypeDateProps extends Omit<DatePickerProps<Date, Date>, 'renderInput'> {
7
+ helperText?: string;
8
+ error?: boolean;
9
+ required?: boolean;
10
+ };
11
+
12
+ const FieldTypeDate = ({label, helperText, error, required, ...props}: FieldTypeDateProps) => {
13
+ return (
14
+ <FormControl fullWidth required={required}>
15
+ <FormLabel>{label}</FormLabel>
16
+ <LocalizationProvider dateAdapter={AdapterDateFns}>
17
+ <DatePicker
18
+ data-testid="zds-date-picker"
19
+ renderInput={(params) =>
20
+ <TextField
21
+ {...params}
22
+ helperText={helperText}
23
+ error={error}
24
+ />
25
+ }
26
+ // Spread props at the end to allow prop overrides
27
+ {...props}
28
+ />
29
+ </LocalizationProvider>
30
+ </FormControl>
31
+ );
32
+ }
33
+
34
+ export default FieldTypeDate;
@@ -0,0 +1,23 @@
1
+ import {useState} from 'react';
2
+ import { Story, Meta } from '@storybook/react/types-6-0';
3
+ import FieldTypeDateTime, { FieldTypeDateTimeProps } from '.';
4
+
5
+ export default {
6
+ title: 'FieldTypeDateTime',
7
+ component: FieldTypeDateTime,
8
+ argType: {},
9
+ } as Meta;
10
+
11
+ const Template: Story<FieldTypeDateTimeProps> = (args) => {
12
+ const [value, setValue] = useState<Date | null>(null);
13
+
14
+ return (
15
+ <FieldTypeDateTime {...args} value={value} onChange={(value) => setValue(value)}/>
16
+ );
17
+ };
18
+
19
+ export const Default = Template.bind({});
20
+ Default.args = {
21
+ label: 'Date label',
22
+ helperText: 'Date helper text',
23
+ };
@@ -0,0 +1,35 @@
1
+ import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
2
+ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
3
+ import { DateTimePicker, DateTimePickerProps} from '@mui/x-date-pickers/DateTimePicker';
4
+ import { TextField, FormControl, FormLabel } from '@mui/material';
5
+
6
+ export interface FieldTypeDateTimeProps extends Omit<DateTimePickerProps<Date, Date>, 'renderInput'> {
7
+ helperText?: string;
8
+ error?: boolean;
9
+ required?: boolean;
10
+ };
11
+
12
+ const FieldTypeDateTime = ({label, helperText, error, required, ...props}: FieldTypeDateTimeProps) => {
13
+ return (
14
+ <FormControl fullWidth required={required}>
15
+ <FormLabel>{label}</FormLabel>
16
+ <LocalizationProvider dateAdapter={AdapterDateFns}>
17
+ <DateTimePicker
18
+ data-testid="zds-date-picker"
19
+ renderInput={(params) =>
20
+ <TextField
21
+
22
+ {...params}
23
+ helperText={helperText}
24
+ error={error}
25
+ />
26
+ }
27
+ // Spread props at the end to allow prop overrides
28
+ {...props}
29
+ />
30
+ </LocalizationProvider>
31
+ </FormControl>
32
+ );
33
+ }
34
+
35
+ export default FieldTypeDateTime;