@elliemae/ds-data-table 2.4.3-rc.4 → 2.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -57,11 +57,6 @@ const DataTableSchema = {
57
57
  withFilterBar: dsPropsHelpers.PropTypes.bool.description('Whether to display the filter bar'),
58
58
  filterBarProps: dsPropsHelpers.PropTypes.shape({
59
59
  customPillRenderer: dsPropsHelpers.PropTypes.oneOfType([dsPropsHelpers.PropTypes.func, dsPropsHelpers.PropTypes.element]).description('If you specify custom filters, you will need to render their pills here'),
60
- isDropdownMenuOpen: dsPropsHelpers.PropTypes.bool.description('Wether the DropdownMenu is Open or not.'),
61
- onDropdownMenuToggle: dsPropsHelpers.PropTypes.func.description('Callback to toggle the DropdownMenu.'),
62
- onClearAllFiltersClick: dsPropsHelpers.PropTypes.func.description('Callback for Clear Al Filters option.'),
63
- onDropdownMenuClickOutside: dsPropsHelpers.PropTypes.func.description('Callback triggered when clicking outside DropdownMenu.'),
64
- onDropdownMenuTriggerClick: dsPropsHelpers.PropTypes.func.description('Callback triggered when clicking DropdownMenu ellipsis.'),
65
60
  extraOptions: dsPropsHelpers.PropTypes.arrayOf(dsPropsHelpers.PropTypes.shape({
66
61
  type: dsPropsHelpers.PropTypes.string,
67
62
  id: dsPropsHelpers.PropTypes.string,
@@ -55,8 +55,6 @@ require('../../../../exported-related/Filters/applyOutOfTheBoxFilters.js');
55
55
  require('moment');
56
56
  require('core-js/modules/esnext.async-iterator.some.js');
57
57
  require('core-js/modules/esnext.iterator.some.js');
58
- require('../../../../redux/reducers/index.js');
59
- var useDispatchHeadersActions = require('../../../../redux/reducers/headersReducers/useDispatchHeadersActions.js');
60
58
 
61
59
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
62
60
 
@@ -82,9 +80,6 @@ const BaseSelectFilter = props => {
82
80
  innerRef,
83
81
  onValueChange
84
82
  } = props;
85
- const {
86
- patchHeaderFilterButtonAndMenu
87
- } = useDispatchHeadersActions.useDispatchHeadersActions();
88
83
  const filterOptions = React.useMemo(() => {
89
84
  // If the user didn't provide options, use the available ones
90
85
  if (!userFilterOptions) {
@@ -105,7 +100,6 @@ const BaseSelectFilter = props => {
105
100
 
106
101
  const handleOnChange = value => {
107
102
  onValueChange(type, value);
108
- if (!isMulti) patchHeaderFilterButtonAndMenu(column.id, true);
109
103
  };
110
104
 
111
105
  const [filters, setFilteredOptions] = React.useState(filterOptions);
@@ -54,11 +54,7 @@ const useDatatableConfig = props => {
54
54
  // Layout config
55
55
  // ===========================================================================
56
56
 
57
- const [gridLayout, setGridLayout] = React.useState(columnsToGrid.columnsToGrid(visibleColumns, props.colsLayoutStyle)); // We need to listen and update the state based on this props
58
-
59
- React.useEffect(() => {
60
- setGridLayout(columnsToGrid.columnsToGrid(visibleColumns, props.colsLayoutStyle));
61
- }, [visibleColumns, props.colsLayoutStyle]);
57
+ const [gridLayout, setGridLayout] = React.useState(columnsToGrid.columnsToGrid(visibleColumns, props.colsLayoutStyle));
62
58
  const totalColumnsWidth = React.useMemo(() => props.colsLayoutStyle === constants.ColsLayoutStyle.Fixed ? gridLayout.reduce((acc, cur) => acc + Number.parseInt(cur, 10), 0) : '100%', [props.colsLayoutStyle, gridLayout]);
63
59
  const layoutHelpers = React.useMemo(() => ({
64
60
  gridLayout,
@@ -55,15 +55,22 @@ const Toolbar = _ref => {
55
55
  children
56
56
  } = _ref;
57
57
  const [show, setShow] = React.useState(false);
58
+ const [clicked, setClicked] = React.useState(false);
58
59
  const toolbarRef = React.useRef(null);
59
- const handleOnClickOutside = React.useCallback(() => setShow(false), []);
60
- const handleOnClick = React.useCallback(() => setShow(true), []);
60
+ const handleOnClickOutside = React.useCallback(() => {
61
+ setShow(false);
62
+ setClicked(false);
63
+ }, []);
64
+ const handleOnClick = React.useCallback(() => {
65
+ setShow(true);
66
+ setClicked(true);
67
+ }, []);
61
68
  dsUtilities.useOnClickOutside(toolbarRef, handleOnClickOutside);
62
69
  return /*#__PURE__*/jsxRuntime.jsx(ToolbarPosition, {
63
70
  ref: toolbarRef,
64
71
  children: /*#__PURE__*/_jsx__default["default"](ToolbarWrapper, {
65
72
  onMouseEnter: () => setShow(true),
66
- onMouseLeave: () => setShow(false)
73
+ onMouseLeave: () => setShow(clicked)
67
74
  }, void 0, show && /*#__PURE__*/_jsx__default["default"](ToolbarBtns, {}, void 0, children), /*#__PURE__*/_jsx__default["default"](DSButton__default["default"], {
68
75
  buttonType: "text",
69
76
  className: "toolbar-trigger",
@@ -76,7 +76,6 @@ const FiltersBar = () => {
76
76
  },
77
77
  visibleColumns
78
78
  } = React.useContext(DataTableContext["default"]);
79
- const [isOpen, setIsOpen] = React.useState(false);
80
79
  const pillGroupRefs = React.useMemo(() => {
81
80
  const refs = [];
82
81
 
@@ -87,29 +86,7 @@ const FiltersBar = () => {
87
86
  const dropdownMenuRef = React.useRef(null);
88
87
  const removeAllFilters = React.useCallback(() => {
89
88
  onFiltersChange([]);
90
- filterBarProps?.onClearAllFiltersClick?.();
91
- }, [onFiltersChange, filterBarProps.onClearAllFiltersClick]);
92
- const onFilterBarClose = React.useCallback(() => {
93
- filterBarProps?.onDropdownMenuToggle?.(false, 'onClose');
94
- setIsOpen(false);
95
- }, [filterBarProps.onDropdownMenuToggle]);
96
- const onFilterBarOpen = React.useCallback(() => {
97
- filterBarProps?.onDropdownMenuToggle?.(true, 'onOpen');
98
- setIsOpen(true);
99
- }, [filterBarProps.onDropdownMenuToggle]);
100
- const onFilterBarOnClickOutside = React.useCallback(() => {
101
- filterBarProps?.onDropdownMenuToggle?.(false, 'onClickOutside');
102
- filterBarProps?.onDropdownMenuClickOutside?.();
103
- setIsOpen(false);
104
- }, [filterBarProps.onDropdownMenuToggle, filterBarProps.onDropdownMenuClickOutside]);
105
- const onTriggerClick = React.useCallback(() => {
106
- filterBarProps?.onDropdownMenuTriggerClick?.();
107
- onFilterBarOpen();
108
- }, [filterBarProps.onDropdownMenuTriggerClick]);
109
- const finalIsOpen = React.useMemo(() => {
110
- if (typeof filterBarProps?.isDropdownMenuOpen === 'boolean') return filterBarProps.isDropdownMenuOpen;
111
- return isOpen;
112
- }, [filterBarProps.isDropdownMenuOpen, isOpen]);
89
+ }, [onFiltersChange]);
113
90
  return /*#__PURE__*/_jsx__default["default"](styled.StyledWrapper, {
114
91
  width: width,
115
92
  "aria-live": "polite",
@@ -145,9 +122,6 @@ const FiltersBar = () => {
145
122
  }, column);
146
123
  }), /*#__PURE__*/_jsx__default["default"](styled.StyledDropdownMenu, {
147
124
  preventOverflow: "scrollParent",
148
- isOpen: finalIsOpen,
149
- onClose: onFilterBarClose,
150
- onClickOutsideMenu: onFilterBarOnClickOutside,
151
125
  options: [{
152
126
  id: '__internal__option__clear__filters',
153
127
  label: 'Clear Filters',
@@ -159,7 +133,6 @@ const FiltersBar = () => {
159
133
  },
160
134
  buttonType: "text",
161
135
  innerRef: dropdownMenuRef,
162
- onClick: onTriggerClick,
163
136
  icon: _MoreOptionsVert || (_MoreOptionsVert = /*#__PURE__*/_jsx__default["default"](dsIcons.MoreOptionsVert, {}))
164
137
  })
165
138
  }));
package/cjs/styled.js CHANGED
@@ -127,11 +127,12 @@ const StyledHeadWrapper = /*#__PURE__*/styled__default["default"].div.withConfig
127
127
  })(["position:relative;position:sticky;top:0;z-index:4;background:white;width:", ";"], props => props.colsLayoutStyle === constants.ColsLayoutStyle.Fixed ? sizeToCss.sizeToCss(props.totalColumnsWidth) : '100%');
128
128
  const StyledHeadTr = /*#__PURE__*/styled__default["default"](Grid__default["default"]).withConfig({
129
129
  componentId: "sc-38sgfo-6"
130
- })(["", ";", ";border-right:1px solid ", ";border-bottom:1px solid ", ";grid-auto-flow:column;"], props => props.colsLayoutStyle === constants.ColsLayoutStyle.Auto ? 'width:100%' : '', props => getGridTemplateColumnsStyle({
130
+ })(["", ";", ";border-right:1px solid ", ";border-bottom:1px solid ", ";"], props => props.colsLayoutStyle === constants.ColsLayoutStyle.Auto ? 'width:100%' : '', props => getGridTemplateColumnsStyle({
131
131
  cols: props.cols,
132
132
  isExpandable: props.isExpandable,
133
133
  colsLayoutStyle: props.colsLayoutStyle
134
134
  }), props => props.theme.colors.neutral['080'], props => props.theme.colors.neutral['080']);
135
+
135
136
  const StyledHeadTh = /*#__PURE__*/styled__default["default"].div.withConfig({
136
137
  componentId: "sc-38sgfo-7"
137
138
  })(["min-height:24px;line-height:normal;font-weight:600;text-transform:uppercase;font-size:0.923rem;text-align:left;", " color:#353c46;min-height:1.84615rem;position:sticky;z-index:", ";display:flex;justify-content:space-between;box-sizing:border-box;outline:none;", ":focus{&:after{display:block;content:' ';position:absolute;top:0;left:0;right:0;bottom:0;border:2px solid ", ";pointer-events:none;z-index:", ";}}"], cellPadding.columnPadding, zIndexInternalConfig.ZIndexDataTable.HEADER_ROW, props => props.isDraggingActive ? '' : `:hover {
@@ -53,11 +53,6 @@ const DataTableSchema = {
53
53
  withFilterBar: PropTypes.bool.description('Whether to display the filter bar'),
54
54
  filterBarProps: PropTypes.shape({
55
55
  customPillRenderer: PropTypes.oneOfType([PropTypes.func, PropTypes.element]).description('If you specify custom filters, you will need to render their pills here'),
56
- isDropdownMenuOpen: PropTypes.bool.description('Wether the DropdownMenu is Open or not.'),
57
- onDropdownMenuToggle: PropTypes.func.description('Callback to toggle the DropdownMenu.'),
58
- onClearAllFiltersClick: PropTypes.func.description('Callback for Clear Al Filters option.'),
59
- onDropdownMenuClickOutside: PropTypes.func.description('Callback triggered when clicking outside DropdownMenu.'),
60
- onDropdownMenuTriggerClick: PropTypes.func.description('Callback triggered when clicking DropdownMenu ellipsis.'),
61
56
  extraOptions: PropTypes.arrayOf(PropTypes.shape({
62
57
  type: PropTypes.string,
63
58
  id: PropTypes.string,
@@ -51,8 +51,6 @@ import '../../../../exported-related/Filters/applyOutOfTheBoxFilters.js';
51
51
  import 'moment';
52
52
  import 'core-js/modules/esnext.async-iterator.some.js';
53
53
  import 'core-js/modules/esnext.iterator.some.js';
54
- import '../../../../redux/reducers/index.js';
55
- import { useDispatchHeadersActions } from '../../../../redux/reducers/headersReducers/useDispatchHeadersActions.js';
56
54
 
57
55
  var _SearchXsmall;
58
56
  const BaseSelectFilter = props => {
@@ -74,9 +72,6 @@ const BaseSelectFilter = props => {
74
72
  innerRef,
75
73
  onValueChange
76
74
  } = props;
77
- const {
78
- patchHeaderFilterButtonAndMenu
79
- } = useDispatchHeadersActions();
80
75
  const filterOptions = useMemo(() => {
81
76
  // If the user didn't provide options, use the available ones
82
77
  if (!userFilterOptions) {
@@ -97,7 +92,6 @@ const BaseSelectFilter = props => {
97
92
 
98
93
  const handleOnChange = value => {
99
94
  onValueChange(type, value);
100
- if (!isMulti) patchHeaderFilterButtonAndMenu(column.id, true);
101
95
  };
102
96
 
103
97
  const [filters, setFilteredOptions] = useState(filterOptions);
@@ -50,11 +50,7 @@ const useDatatableConfig = props => {
50
50
  // Layout config
51
51
  // ===========================================================================
52
52
 
53
- const [gridLayout, setGridLayout] = useState(columnsToGrid(visibleColumns, props.colsLayoutStyle)); // We need to listen and update the state based on this props
54
-
55
- useEffect(() => {
56
- setGridLayout(columnsToGrid(visibleColumns, props.colsLayoutStyle));
57
- }, [visibleColumns, props.colsLayoutStyle]);
53
+ const [gridLayout, setGridLayout] = useState(columnsToGrid(visibleColumns, props.colsLayoutStyle));
58
54
  const totalColumnsWidth = useMemo(() => props.colsLayoutStyle === ColsLayoutStyle.Fixed ? gridLayout.reduce((acc, cur) => acc + Number.parseInt(cur, 10), 0) : '100%', [props.colsLayoutStyle, gridLayout]);
59
55
  const layoutHelpers = useMemo(() => ({
60
56
  gridLayout,
@@ -45,15 +45,22 @@ const Toolbar = _ref => {
45
45
  children
46
46
  } = _ref;
47
47
  const [show, setShow] = useState(false);
48
+ const [clicked, setClicked] = useState(false);
48
49
  const toolbarRef = useRef(null);
49
- const handleOnClickOutside = useCallback(() => setShow(false), []);
50
- const handleOnClick = useCallback(() => setShow(true), []);
50
+ const handleOnClickOutside = useCallback(() => {
51
+ setShow(false);
52
+ setClicked(false);
53
+ }, []);
54
+ const handleOnClick = useCallback(() => {
55
+ setShow(true);
56
+ setClicked(true);
57
+ }, []);
51
58
  useOnClickOutside(toolbarRef, handleOnClickOutside);
52
59
  return /*#__PURE__*/jsx(ToolbarPosition, {
53
60
  ref: toolbarRef,
54
61
  children: /*#__PURE__*/_jsx(ToolbarWrapper, {
55
62
  onMouseEnter: () => setShow(true),
56
- onMouseLeave: () => setShow(false)
63
+ onMouseLeave: () => setShow(clicked)
57
64
  }, void 0, show && /*#__PURE__*/_jsx(ToolbarBtns, {}, void 0, children), /*#__PURE__*/_jsx(DSButton, {
58
65
  buttonType: "text",
59
66
  className: "toolbar-trigger",
@@ -4,7 +4,7 @@ import 'core-js/modules/esnext.iterator.map.js';
4
4
  import 'core-js/modules/esnext.async-iterator.find.js';
5
5
  import 'core-js/modules/esnext.iterator.constructor.js';
6
6
  import 'core-js/modules/esnext.iterator.find.js';
7
- import React, { useContext, useState, useMemo, useRef, useCallback } from 'react';
7
+ import React, { useContext, useMemo, useRef, useCallback } from 'react';
8
8
  import DSButton from '@elliemae/ds-button';
9
9
  import { MoreOptionsVert } from '@elliemae/ds-icons';
10
10
  import 'core-js/modules/esnext.async-iterator.filter.js';
@@ -66,7 +66,6 @@ const FiltersBar = () => {
66
66
  },
67
67
  visibleColumns
68
68
  } = useContext(DataTableContext);
69
- const [isOpen, setIsOpen] = useState(false);
70
69
  const pillGroupRefs = useMemo(() => {
71
70
  const refs = [];
72
71
 
@@ -77,29 +76,7 @@ const FiltersBar = () => {
77
76
  const dropdownMenuRef = useRef(null);
78
77
  const removeAllFilters = useCallback(() => {
79
78
  onFiltersChange([]);
80
- filterBarProps?.onClearAllFiltersClick?.();
81
- }, [onFiltersChange, filterBarProps.onClearAllFiltersClick]);
82
- const onFilterBarClose = useCallback(() => {
83
- filterBarProps?.onDropdownMenuToggle?.(false, 'onClose');
84
- setIsOpen(false);
85
- }, [filterBarProps.onDropdownMenuToggle]);
86
- const onFilterBarOpen = useCallback(() => {
87
- filterBarProps?.onDropdownMenuToggle?.(true, 'onOpen');
88
- setIsOpen(true);
89
- }, [filterBarProps.onDropdownMenuToggle]);
90
- const onFilterBarOnClickOutside = useCallback(() => {
91
- filterBarProps?.onDropdownMenuToggle?.(false, 'onClickOutside');
92
- filterBarProps?.onDropdownMenuClickOutside?.();
93
- setIsOpen(false);
94
- }, [filterBarProps.onDropdownMenuToggle, filterBarProps.onDropdownMenuClickOutside]);
95
- const onTriggerClick = useCallback(() => {
96
- filterBarProps?.onDropdownMenuTriggerClick?.();
97
- onFilterBarOpen();
98
- }, [filterBarProps.onDropdownMenuTriggerClick]);
99
- const finalIsOpen = useMemo(() => {
100
- if (typeof filterBarProps?.isDropdownMenuOpen === 'boolean') return filterBarProps.isDropdownMenuOpen;
101
- return isOpen;
102
- }, [filterBarProps.isDropdownMenuOpen, isOpen]);
79
+ }, [onFiltersChange]);
103
80
  return /*#__PURE__*/_jsx(StyledWrapper, {
104
81
  width: width,
105
82
  "aria-live": "polite",
@@ -135,9 +112,6 @@ const FiltersBar = () => {
135
112
  }, column);
136
113
  }), /*#__PURE__*/_jsx(StyledDropdownMenu, {
137
114
  preventOverflow: "scrollParent",
138
- isOpen: finalIsOpen,
139
- onClose: onFilterBarClose,
140
- onClickOutsideMenu: onFilterBarOnClickOutside,
141
115
  options: [{
142
116
  id: '__internal__option__clear__filters',
143
117
  label: 'Clear Filters',
@@ -149,7 +123,6 @@ const FiltersBar = () => {
149
123
  },
150
124
  buttonType: "text",
151
125
  innerRef: dropdownMenuRef,
152
- onClick: onTriggerClick,
153
126
  icon: _MoreOptionsVert || (_MoreOptionsVert = /*#__PURE__*/_jsx(MoreOptionsVert, {}))
154
127
  })
155
128
  }));
package/esm/styled.js CHANGED
@@ -118,11 +118,12 @@ const StyledHeadWrapper = /*#__PURE__*/styled.div.withConfig({
118
118
  })(["position:relative;position:sticky;top:0;z-index:4;background:white;width:", ";"], props => props.colsLayoutStyle === ColsLayoutStyle.Fixed ? sizeToCss(props.totalColumnsWidth) : '100%');
119
119
  const StyledHeadTr = /*#__PURE__*/styled(Grid).withConfig({
120
120
  componentId: "sc-38sgfo-6"
121
- })(["", ";", ";border-right:1px solid ", ";border-bottom:1px solid ", ";grid-auto-flow:column;"], props => props.colsLayoutStyle === ColsLayoutStyle.Auto ? 'width:100%' : '', props => getGridTemplateColumnsStyle({
121
+ })(["", ";", ";border-right:1px solid ", ";border-bottom:1px solid ", ";"], props => props.colsLayoutStyle === ColsLayoutStyle.Auto ? 'width:100%' : '', props => getGridTemplateColumnsStyle({
122
122
  cols: props.cols,
123
123
  isExpandable: props.isExpandable,
124
124
  colsLayoutStyle: props.colsLayoutStyle
125
125
  }), props => props.theme.colors.neutral['080'], props => props.theme.colors.neutral['080']);
126
+
126
127
  const StyledHeadTh = /*#__PURE__*/styled.div.withConfig({
127
128
  componentId: "sc-38sgfo-7"
128
129
  })(["min-height:24px;line-height:normal;font-weight:600;text-transform:uppercase;font-size:0.923rem;text-align:left;", " color:#353c46;min-height:1.84615rem;position:sticky;z-index:", ";display:flex;justify-content:space-between;box-sizing:border-box;outline:none;", ":focus{&:after{display:block;content:' ';position:absolute;top:0;left:0;right:0;bottom:0;border:2px solid ", ";pointer-events:none;z-index:", ";}}"], columnPadding, ZIndexDataTable.HEADER_ROW, props => props.isDraggingActive ? '' : `:hover {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elliemae/ds-data-table",
3
- "version": "2.4.3-rc.4",
3
+ "version": "2.4.3",
4
4
  "license": "MIT",
5
5
  "description": "ICE MT - Dimsum - Data Table",
6
6
  "module": "./esm/index.js",
@@ -570,24 +570,24 @@
570
570
  "dependencies": {
571
571
  "@dnd-kit/core": "~4.0.1",
572
572
  "@dnd-kit/sortable": "~5.0.0",
573
- "@elliemae/ds-button": "2.4.3-rc.4",
574
- "@elliemae/ds-circular-progress-indicator": "2.4.3-rc.4",
575
- "@elliemae/ds-controlled-form": "2.4.3-rc.4",
576
- "@elliemae/ds-drag-and-drop": "2.4.3-rc.4",
577
- "@elliemae/ds-dropdownmenu": "2.4.3-rc.4",
578
- "@elliemae/ds-form": "2.4.3-rc.4",
579
- "@elliemae/ds-form-layout-blocks": "2.4.3-rc.4",
580
- "@elliemae/ds-grid": "2.4.3-rc.4",
581
- "@elliemae/ds-icons": "2.4.3-rc.4",
582
- "@elliemae/ds-indeterminate-progress-indicator": "2.4.3-rc.4",
583
- "@elliemae/ds-pagination": "2.4.3-rc.4",
584
- "@elliemae/ds-pills": "2.4.3-rc.4",
585
- "@elliemae/ds-popperjs": "2.4.3-rc.4",
586
- "@elliemae/ds-props-helpers": "2.4.3-rc.4",
587
- "@elliemae/ds-system": "2.4.3-rc.4",
588
- "@elliemae/ds-toolbar": "2.4.3-rc.4",
589
- "@elliemae/ds-truncated-tooltip-text": "2.4.3-rc.4",
590
- "@elliemae/ds-utilities": "2.4.3-rc.4",
573
+ "@elliemae/ds-button": "2.4.3",
574
+ "@elliemae/ds-circular-progress-indicator": "2.4.3",
575
+ "@elliemae/ds-controlled-form": "2.4.3",
576
+ "@elliemae/ds-drag-and-drop": "2.4.3",
577
+ "@elliemae/ds-dropdownmenu": "2.4.3",
578
+ "@elliemae/ds-form": "2.4.3",
579
+ "@elliemae/ds-form-layout-blocks": "2.4.3",
580
+ "@elliemae/ds-grid": "2.4.3",
581
+ "@elliemae/ds-icons": "2.4.3",
582
+ "@elliemae/ds-indeterminate-progress-indicator": "2.4.3",
583
+ "@elliemae/ds-pagination": "2.4.3",
584
+ "@elliemae/ds-pills": "2.4.3",
585
+ "@elliemae/ds-popperjs": "2.4.3",
586
+ "@elliemae/ds-props-helpers": "2.4.3",
587
+ "@elliemae/ds-system": "2.4.3",
588
+ "@elliemae/ds-toolbar": "2.4.3",
589
+ "@elliemae/ds-truncated-tooltip-text": "2.4.3",
590
+ "@elliemae/ds-utilities": "2.4.3",
591
591
  "@reduxjs/toolkit": "~1.6.2",
592
592
  "csstype": "~3.0.9",
593
593
  "moment": "~2.29.1",