@zesty-io/material 0.0.3 → 0.1.1

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 (87) hide show
  1. package/.storybook/main.js +15 -2
  2. package/.storybook/preview-head.html +1 -0
  3. package/.storybook/preview.js +14 -8
  4. package/es/ConfirmModal/ConfirmModal.stories.d.ts +6 -0
  5. package/es/ConfirmModal/ConfirmModal.stories.js +24 -0
  6. package/es/ConfirmModal/index.d.ts +18 -0
  7. package/es/ConfirmModal/index.js +11 -0
  8. package/es/CopyButton/CopyButton.stories.d.ts +5 -0
  9. package/es/CopyButton/CopyButton.stories.js +14 -0
  10. package/es/CopyButton/index.d.ts +10 -0
  11. package/es/CopyButton/index.js +26 -0
  12. package/es/FieldTypeColor/FieldTypeColor.stories.d.ts +5 -0
  13. package/es/FieldTypeColor/FieldTypeColor.stories.js +21 -0
  14. package/es/FieldTypeColor/index.d.ts +6 -0
  15. package/es/FieldTypeColor/index.js +16 -0
  16. package/es/FieldTypeDate/FieldTypeDate.stories.d.ts +5 -0
  17. package/es/FieldTypeDate/FieldTypeDate.stories.js +17 -0
  18. package/es/FieldTypeDate/index.d.ts +9 -0
  19. package/es/FieldTypeDate/index.js +10 -0
  20. package/es/FieldTypeDateTime/FieldTypeDateTime.stories.d.ts +5 -0
  21. package/es/FieldTypeDateTime/FieldTypeDateTime.stories.js +17 -0
  22. package/es/FieldTypeDateTime/index.d.ts +9 -0
  23. package/es/FieldTypeDateTime/index.js +10 -0
  24. package/es/FieldTypeDropdown/FieldTypeDropwdon.stories.d.ts +5 -0
  25. package/es/FieldTypeDropdown/FieldTypeDropwdon.stories.js +35 -0
  26. package/es/FieldTypeDropdown/index.d.ts +11 -0
  27. package/es/FieldTypeDropdown/index.js +10 -0
  28. package/es/FieldTypeNumber/FieldTypeNumber.stories.d.ts +5 -0
  29. package/es/FieldTypeNumber/FieldTypeNumber.stories.js +21 -0
  30. package/es/FieldTypeNumber/index.d.ts +6 -0
  31. package/es/FieldTypeNumber/index.js +7 -0
  32. package/es/FieldTypeOneToMany/FieldTypeOneToMany.stories.d.ts +5 -0
  33. package/es/FieldTypeOneToMany/FieldTypeOneToMany.stories.js +29 -0
  34. package/es/FieldTypeOneToMany/index.d.ts +14 -0
  35. package/es/FieldTypeOneToMany/index.js +30 -0
  36. package/es/FieldTypeOneToOne/FieldTypeOneToOne.stories.d.ts +5 -0
  37. package/es/FieldTypeOneToOne/FieldTypeOneToOne.stories.js +28 -0
  38. package/es/FieldTypeOneToOne/index.d.ts +34 -0
  39. package/es/FieldTypeOneToOne/index.js +33 -0
  40. package/es/FieldTypeSort/FieldTypeSort.stories.d.ts +5 -0
  41. package/es/FieldTypeSort/FieldTypeSort.stories.js +22 -0
  42. package/es/FieldTypeSort/index.d.ts +7 -0
  43. package/es/FieldTypeSort/index.js +22 -0
  44. package/es/FieldTypeText/FieldTypeText.stories.d.ts +6 -0
  45. package/es/FieldTypeText/FieldTypeText.stories.js +29 -0
  46. package/es/FieldTypeText/index.d.ts +12 -0
  47. package/es/FieldTypeText/index.js +7 -0
  48. package/es/FieldTypeUrl/FieldTypeUrl.stories.d.ts +5 -0
  49. package/es/FieldTypeUrl/FieldTypeUrl.stories.js +21 -0
  50. package/es/FieldTypeUrl/index.d.ts +12 -0
  51. package/es/FieldTypeUrl/index.js +13 -0
  52. package/es/index.d.ts +12 -0
  53. package/es/index.js +12 -0
  54. package/es/theme/Theme.stories.d.ts +4 -0
  55. package/es/theme/Theme.stories.js +10 -0
  56. package/es/theme/index.js +36 -8
  57. package/es/utils/virtualization.d.ts +3 -0
  58. package/es/utils/virtualization.js +74 -0
  59. package/package.json +8 -3
  60. package/src/ConfirmModal/ConfirmModal.stories.tsx +35 -0
  61. package/src/ConfirmModal/index.tsx +50 -0
  62. package/src/CopyButton/CopyButton.stories.tsx +20 -0
  63. package/src/CopyButton/index.tsx +55 -0
  64. package/src/FieldTypeColor/FieldTypeColor.stories.tsx +35 -0
  65. package/src/FieldTypeColor/index.tsx +43 -0
  66. package/src/FieldTypeDate/FieldTypeDate.stories.tsx +23 -0
  67. package/src/FieldTypeDate/index.tsx +34 -0
  68. package/src/FieldTypeDateTime/FieldTypeDateTime.stories.tsx +23 -0
  69. package/src/FieldTypeDateTime/index.tsx +35 -0
  70. package/src/FieldTypeDropdown/FieldTypeDropwdon.stories.tsx +52 -0
  71. package/src/FieldTypeDropdown/index.tsx +41 -0
  72. package/src/FieldTypeNumber/FieldTypeNumber.stories.tsx +35 -0
  73. package/src/FieldTypeNumber/index.tsx +22 -0
  74. package/src/FieldTypeOneToMany/FieldTypeOneToMany.stories.tsx +47 -0
  75. package/src/FieldTypeOneToMany/index.tsx +65 -0
  76. package/src/FieldTypeOneToOne/FieldTypeOneToOne.stories.tsx +46 -0
  77. package/src/FieldTypeOneToOne/index.tsx +97 -0
  78. package/src/FieldTypeSort/FieldTypeSort.stories.tsx +36 -0
  79. package/src/FieldTypeSort/index.tsx +56 -0
  80. package/src/FieldTypeText/FieldTypeText.stories.tsx +45 -0
  81. package/src/FieldTypeText/index.tsx +35 -0
  82. package/src/FieldTypeUrl/FieldTypeUrl.stories.tsx +33 -0
  83. package/src/FieldTypeUrl/index.tsx +43 -0
  84. package/src/index.ts +12 -0
  85. package/src/{stories → theme}/Theme.stories.tsx +1 -1
  86. package/src/theme/index.ts +41 -9
  87. package/src/utils/virtualization.tsx +125 -0
@@ -0,0 +1,5 @@
1
+ import { Story, Meta } from '@storybook/react/types-6-0';
2
+ import { FieldTypeSortProps } from './';
3
+ declare const _default: Meta<import("@storybook/react/types-6-0").Args>;
4
+ export default _default;
5
+ export declare const Default: Story<FieldTypeSortProps>;
@@ -0,0 +1,22 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import FieldTypeSort from './';
4
+ export default {
5
+ title: 'FieldTypeSort',
6
+ component: FieldTypeSort,
7
+ argType: {},
8
+ };
9
+ const Template = (args) => {
10
+ const [value, setValue] = useState('3');
11
+ const handleOnChange = (e) => {
12
+ setValue(e.target.value);
13
+ };
14
+ return (_jsx(FieldTypeSort, { ...args, value: value, onChange: handleOnChange }));
15
+ };
16
+ export const Default = Template.bind({});
17
+ Default.args = {
18
+ placeholder: 'Placeholder Text...',
19
+ label: 'Sort label',
20
+ helperText: 'Sort helper text',
21
+ error: false,
22
+ };
@@ -0,0 +1,7 @@
1
+ /// <reference types="react" />
2
+ import { OutlinedTextFieldProps } from '@mui/material/TextField';
3
+ export interface FieldTypeSortProps extends Omit<OutlinedTextFieldProps, 'variant'> {
4
+ value: string;
5
+ }
6
+ declare const FieldTypeSort: ({ label, value, InputProps, required, ...props }: FieldTypeSortProps) => JSX.Element;
7
+ export default FieldTypeSort;
@@ -0,0 +1,22 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import MuiTextField from '@mui/material/TextField';
3
+ import { Button, FormControl, FormLabel, InputAdornment } from '@mui/material';
4
+ import AddIcon from '@mui/icons-material/Add';
5
+ import RemoveIcon from '@mui/icons-material/Remove';
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 })] }));
21
+ };
22
+ export default FieldTypeSort;
@@ -0,0 +1,6 @@
1
+ import { Story, Meta } from '@storybook/react/types-6-0';
2
+ import { FieldTypeTextProps } from './';
3
+ declare const _default: Meta<import("@storybook/react/types-6-0").Args>;
4
+ export default _default;
5
+ export declare const Default: Story<FieldTypeTextProps>;
6
+ export declare const TextArea: Story<FieldTypeTextProps>;
@@ -0,0 +1,29 @@
1
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import FieldTypeText from './';
4
+ export default {
5
+ title: 'FieldTypeText',
6
+ component: FieldTypeText,
7
+ argType: {},
8
+ };
9
+ const Template = (args) => {
10
+ const [value, setValue] = useState('');
11
+ const handleOnChange = (e) => {
12
+ setValue(e.target.value);
13
+ };
14
+ return (_jsx(_Fragment, { children: _jsx(FieldTypeText, { ...args, value: value, onChange: handleOnChange }) }));
15
+ };
16
+ export const Default = Template.bind({});
17
+ Default.args = {
18
+ placeholder: 'Placeholder Text...',
19
+ label: 'Text label',
20
+ helperText: 'Text helper text',
21
+ };
22
+ export const TextArea = Template.bind({});
23
+ TextArea.args = {
24
+ multiline: true,
25
+ rows: 4,
26
+ placeholder: 'Placeholder Text...',
27
+ label: 'Text Label',
28
+ helperText: 'Text helper text',
29
+ };
@@ -0,0 +1,12 @@
1
+ /// <reference types="react" />
2
+ import { OutlinedTextFieldProps } from '@mui/material/TextField';
3
+ export interface FieldTypeTextProps extends Omit<OutlinedTextFieldProps, 'variant'> {
4
+ /**
5
+ * Max length of the field
6
+ * @default 150
7
+ */
8
+ maxLength?: number;
9
+ value: string;
10
+ }
11
+ declare const FieldTypeText: ({ label, maxLength, value, helperText, required, ...props }: FieldTypeTextProps) => JSX.Element;
12
+ export default FieldTypeText;
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import MuiTextField from '@mui/material/TextField';
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 })] }));
6
+ };
7
+ export default FieldTypeText;
@@ -0,0 +1,5 @@
1
+ import { Story, Meta } from '@storybook/react/types-6-0';
2
+ import { FieldTypeUrlProps } from './';
3
+ declare const _default: Meta<import("@storybook/react/types-6-0").Args>;
4
+ export default _default;
5
+ export declare const Default: Story<FieldTypeUrlProps>;
@@ -0,0 +1,21 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import FieldTypeUrl from './';
4
+ export default {
5
+ title: 'FieldTypeUrl',
6
+ component: FieldTypeUrl,
7
+ argType: {},
8
+ };
9
+ const Template = (args) => {
10
+ const [value, setValue] = useState('');
11
+ const handleOnChange = (e) => {
12
+ setValue(e.target.value);
13
+ };
14
+ return (_jsx(FieldTypeUrl, { ...args, value: value, onChange: handleOnChange }));
15
+ };
16
+ export const Default = Template.bind({});
17
+ Default.args = {
18
+ placeholder: 'Placeholder Text...',
19
+ label: 'Some label',
20
+ fullWidth: true,
21
+ };
@@ -0,0 +1,12 @@
1
+ /// <reference types="react" />
2
+ import { OutlinedTextFieldProps } from '@mui/material/TextField';
3
+ export interface FieldTypeUrlProps extends Omit<OutlinedTextFieldProps, 'variant'> {
4
+ /**
5
+ * Max length of the field
6
+ * @default 2000
7
+ */
8
+ maxLength?: number;
9
+ value: string;
10
+ }
11
+ declare const FieldTypeUrl: ({ label, maxLength, value, helperText, required, inputProps, ...props }: FieldTypeUrlProps) => JSX.Element;
12
+ export default FieldTypeUrl;
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useRef } from 'react';
3
+ import MuiTextField from '@mui/material/TextField';
4
+ import { FormControl, FormLabel, Box } from '@mui/material';
5
+ const FieldTypeUrl = ({ label, maxLength = 2000, value, helperText, required, inputProps, ...props }) => {
6
+ const inputRef = useRef(null);
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 })] }));
12
+ };
13
+ export default FieldTypeUrl;
package/es/index.d.ts CHANGED
@@ -1 +1,13 @@
1
1
  export { default as theme } from './theme';
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 ConfirmModal } from './ConfirmModal';
package/es/index.js CHANGED
@@ -1 +1,13 @@
1
1
  export { default as theme } from './theme';
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 ConfirmModal } from './ConfirmModal';
@@ -0,0 +1,4 @@
1
+ import { Story, Meta } from '@storybook/react/types-6-0';
2
+ declare const _default: Meta<import("@storybook/react/types-6-0").Args>;
3
+ export default _default;
4
+ export declare const Default: Story<import("@storybook/react/types-6-0").Args>;
@@ -0,0 +1,10 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import ReactJson from 'react-json-view';
3
+ import theme from '.';
4
+ export default {
5
+ title: 'Theme',
6
+ };
7
+ const Template = (args) => {
8
+ return (_jsx(ReactJson, { src: theme }));
9
+ };
10
+ export const Default = Template.bind({});
package/es/theme/index.js CHANGED
@@ -7,26 +7,54 @@ let theme = createTheme({
7
7
  });
8
8
  theme = createTheme(theme, {
9
9
  components: {
10
+ MuiButton: {
11
+ styleOverrides: {
12
+ root: {
13
+ minWidth: 'auto',
14
+ },
15
+ },
16
+ },
10
17
  MuiTooltip: {
11
18
  styleOverrides: {
12
19
  tooltip: {
13
20
  color: theme.palette.primary.contrastText,
14
21
  backgroundColor: theme.palette.primary.main,
15
- fontSize: "14px",
16
- lineHeight: "20px",
22
+ fontSize: '14px',
23
+ lineHeight: '20px',
17
24
  },
18
25
  arrow: {
19
26
  color: theme.palette.primary.main,
20
- }
21
- }
27
+ },
28
+ },
22
29
  },
23
30
  MuiInputBase: {
24
31
  styleOverrides: {
25
32
  root: {
26
- backgroundColor: theme.palette.primary.contrastText
33
+ backgroundColor: theme.palette.primary.contrastText,
34
+ },
35
+ },
36
+ },
37
+ MuiFormLabel: {
38
+ styleOverrides: {
39
+ root: {
40
+ color: theme.palette.primary.dark,
27
41
  },
28
- }
29
- }
30
- }
42
+ asterisk: {
43
+ color: theme.palette.error.main,
44
+ }
45
+ },
46
+ },
47
+ MuiToggleButton: {
48
+ styleOverrides: {
49
+ root: ({ ownerState, theme }) => ({
50
+ backgroundColor: `${theme.palette[ownerState.color].contrastText} !important`,
51
+ ...(ownerState.selected && {
52
+ color: `${theme.palette[ownerState.color].contrastText} !important`,
53
+ backgroundColor: `${theme.palette[ownerState.color].main} !important`,
54
+ }),
55
+ }),
56
+ },
57
+ },
58
+ },
31
59
  });
32
60
  export default theme;
@@ -0,0 +1,3 @@
1
+ import * as React from 'react';
2
+ export declare const ListboxComponent: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLElement> & React.RefAttributes<HTMLDivElement>>;
3
+ export declare const randomOptions: string[];
@@ -0,0 +1,74 @@
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
+ });
64
+ function random(length) {
65
+ const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
66
+ let result = '';
67
+ for (let i = 0; i < length; i += 1) {
68
+ result += characters.charAt(Math.floor(Math.random() * characters.length));
69
+ }
70
+ return result;
71
+ }
72
+ export const randomOptions = Array.from(new Array(10000))
73
+ .map(() => random(10 + Math.ceil(Math.random() * 20)))
74
+ .sort((a, b) => a.toUpperCase().localeCompare(b.toUpperCase()));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zesty-io/material",
3
- "version": "0.0.3",
3
+ "version": "0.1.1",
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,9 +43,11 @@
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",
50
+ "react-docgen-typescript": "^2.2.2",
46
51
  "react-dom": "^18.1.0",
47
52
  "react-json-view": "^1.21.3",
48
53
  "typescript": "^4.6.3"
@@ -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;
@@ -0,0 +1,20 @@
1
+ import { Story, Meta } from '@storybook/react/types-6-0';
2
+ import CopyButton, { CopyButtonProps } from '.';
3
+
4
+ export default {
5
+ title: 'CopyButton',
6
+ component: CopyButton,
7
+ argType: {},
8
+ } as Meta;
9
+
10
+ const Template: Story<CopyButtonProps> = (args) => {
11
+
12
+ return (
13
+ <CopyButton {...args} />
14
+ );
15
+ };
16
+
17
+ export const Default = Template.bind({});
18
+ Default.args = {
19
+ value: 'Copy Me!'
20
+ };
@@ -0,0 +1,55 @@
1
+ import { useCallback, useState, useEffect } from 'react';
2
+ import Button, { ButtonProps } from '@mui/material/Button';
3
+ import ContentCopyIcon from '@mui/icons-material/ContentCopy';
4
+ import CheckIcon from '@mui/icons-material/Check';
5
+
6
+ export interface CopyButtonProps extends ButtonProps {
7
+ /**
8
+ * Value to be copied to clipboard
9
+ */
10
+ value: string ;
11
+ }
12
+
13
+ const CopyButton = ({value, sx, ...props }: CopyButtonProps) => {
14
+ const [copied, setCopied] = useState(false);
15
+
16
+ const copyValue = useCallback(() => {
17
+ navigator?.clipboard.writeText(value);
18
+ setCopied(true);
19
+ }, [value]);
20
+
21
+ useEffect(() => {
22
+ const iconTimer = setTimeout(() => {
23
+ setCopied(false);
24
+ }, 500);
25
+
26
+ return () => {
27
+ clearTimeout(iconTimer);
28
+ };
29
+ }, [copied]);
30
+
31
+ return (
32
+ <Button
33
+ variant='outlined'
34
+ onClick={copyValue}
35
+ size="small"
36
+ title={props.children ? `Copy ${props.children}` : `Copy ${value}`}
37
+ sx={{
38
+ textTransform: 'unset',
39
+ // Spread sx prop at the end to allow sx prop overrides
40
+ ...sx,
41
+ }}
42
+ startIcon={copied ? (
43
+ <CheckIcon color='success' fontSize='small' />
44
+ ) : (
45
+ <ContentCopyIcon fontSize='small' />
46
+ )}
47
+ // Spread props at the end to allow prop overrides
48
+ {...props}
49
+ >
50
+ {props.children ? props.children : value}
51
+ </Button>
52
+ );
53
+ };
54
+
55
+ export default CopyButton;
@@ -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;