@pareto-engineering/design-system 5.2.0 → 5.3.0

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 (80) hide show
  1. package/dist/cjs/a/Charts/AreaChart/AreaChart.js +61 -5
  2. package/dist/cjs/a/Charts/AreaChart/styles.scss +22 -0
  3. package/dist/cjs/a/Charts/BarChart/BarChart.js +1 -0
  4. package/dist/cjs/a/Charts/Common/CustomLegend/CustomLegend.js +23 -5
  5. package/dist/cjs/a/Charts/Common/CustomLegend/styles.scss +10 -2
  6. package/dist/cjs/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.js +139 -42
  7. package/dist/cjs/a/Charts/Common/CustomTooltipContent/styles.scss +4 -0
  8. package/dist/cjs/a/Charts/PieChart/PieChart.js +39 -8
  9. package/dist/cjs/a/Charts/PieChart/styles.scss +88 -0
  10. package/dist/cjs/a/HamburgerButton/styles.scss +151 -9
  11. package/dist/cjs/a/ThroughPutIndicator/ThroughPutIndicator.js +78 -0
  12. package/dist/cjs/a/ThroughPutIndicator/index.js +13 -0
  13. package/dist/cjs/a/ThroughPutIndicator/styles.scss +35 -0
  14. package/dist/cjs/a/ToggleSwitch/ToggleSwitch.js +2 -1
  15. package/dist/cjs/a/ToggleSwitch/styles.scss +9 -2
  16. package/dist/cjs/a/Tooltip/Tooltip.js +19 -2
  17. package/dist/cjs/a/Tooltip/styles.scss +32 -4
  18. package/dist/cjs/a/XMLEditor/XMLEditor.js +4 -1
  19. package/dist/cjs/a/index.js +8 -1
  20. package/dist/cjs/f/FormInput/FormInput.js +7 -1
  21. package/dist/cjs/f/fields/ToggleInput/ToggleInput.js +126 -0
  22. package/dist/cjs/f/fields/ToggleInput/index.js +13 -0
  23. package/dist/cjs/f/fields/ToggleInput/styles.scss +22 -0
  24. package/dist/cjs/f/fields/index.js +8 -1
  25. package/dist/cjs/utils/formatting.js +27 -18
  26. package/dist/cjs/utils/index.js +6 -0
  27. package/dist/es/a/Charts/AreaChart/AreaChart.js +62 -6
  28. package/dist/es/a/Charts/AreaChart/styles.scss +22 -0
  29. package/dist/es/a/Charts/BarChart/BarChart.js +1 -0
  30. package/dist/es/a/Charts/Common/CustomLegend/CustomLegend.js +23 -5
  31. package/dist/es/a/Charts/Common/CustomLegend/styles.scss +10 -2
  32. package/dist/es/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.js +128 -40
  33. package/dist/es/a/Charts/Common/CustomTooltipContent/styles.scss +4 -0
  34. package/dist/es/a/Charts/PieChart/PieChart.js +39 -8
  35. package/dist/es/a/Charts/PieChart/styles.scss +88 -0
  36. package/dist/es/a/HamburgerButton/styles.scss +151 -9
  37. package/dist/es/a/ThroughPutIndicator/ThroughPutIndicator.js +66 -0
  38. package/dist/es/a/ThroughPutIndicator/index.js +2 -0
  39. package/dist/es/a/ThroughPutIndicator/styles.scss +35 -0
  40. package/dist/es/a/ToggleSwitch/ToggleSwitch.js +2 -1
  41. package/dist/es/a/ToggleSwitch/styles.scss +9 -2
  42. package/dist/es/a/Tooltip/Tooltip.js +31 -12
  43. package/dist/es/a/Tooltip/styles.scss +32 -4
  44. package/dist/es/a/XMLEditor/XMLEditor.js +6 -3
  45. package/dist/es/a/index.js +2 -1
  46. package/dist/es/f/FormInput/FormInput.js +8 -2
  47. package/dist/es/f/fields/ToggleInput/ToggleInput.js +116 -0
  48. package/dist/es/f/fields/ToggleInput/index.js +2 -0
  49. package/dist/es/f/fields/ToggleInput/styles.scss +22 -0
  50. package/dist/es/f/fields/index.js +2 -1
  51. package/dist/es/utils/formatting.js +25 -17
  52. package/dist/es/utils/index.js +1 -1
  53. package/package.json +7 -6
  54. package/src/ui/a/Charts/AreaChart/AreaChart.jsx +74 -9
  55. package/src/ui/a/Charts/AreaChart/styles.scss +22 -0
  56. package/src/ui/a/Charts/BarChart/BarChart.jsx +1 -0
  57. package/src/ui/a/Charts/Common/CustomLegend/CustomLegend.jsx +26 -3
  58. package/src/ui/a/Charts/Common/CustomLegend/styles.scss +10 -2
  59. package/src/ui/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.jsx +132 -48
  60. package/src/ui/a/Charts/Common/CustomTooltipContent/styles.scss +4 -0
  61. package/src/ui/a/Charts/PieChart/PieChart.jsx +54 -16
  62. package/src/ui/a/Charts/PieChart/styles.scss +88 -0
  63. package/src/ui/a/HamburgerButton/styles.scss +151 -9
  64. package/src/ui/a/ThroughPutIndicator/ThroughPutIndicator.jsx +90 -0
  65. package/src/ui/a/ThroughPutIndicator/index.js +2 -0
  66. package/src/ui/a/ThroughPutIndicator/styles.scss +35 -0
  67. package/src/ui/a/ToggleSwitch/ToggleSwitch.jsx +1 -1
  68. package/src/ui/a/ToggleSwitch/styles.scss +9 -2
  69. package/src/ui/a/Tooltip/Tooltip.jsx +55 -26
  70. package/src/ui/a/Tooltip/styles.scss +32 -4
  71. package/src/ui/a/XMLEditor/XMLEditor.jsx +15 -2
  72. package/src/ui/a/index.js +1 -0
  73. package/src/ui/f/FormInput/FormInput.jsx +11 -0
  74. package/src/ui/f/fields/ToggleInput/ToggleInput.jsx +140 -0
  75. package/src/ui/f/fields/ToggleInput/index.js +2 -0
  76. package/src/ui/f/fields/ToggleInput/styles.scss +22 -0
  77. package/src/ui/f/fields/index.js +1 -0
  78. package/src/ui/utils/formatting.js +38 -29
  79. package/src/ui/utils/index.js +1 -1
  80. package/tests/__snapshots__/Storyshots.test.js.snap +433 -160
@@ -0,0 +1,90 @@
1
+ import * as React from 'react'
2
+ import PropTypes from 'prop-types'
3
+
4
+ import styleNames from '@pareto-engineering/bem/exports'
5
+
6
+ import './styles.scss'
7
+
8
+ // Local Definitions
9
+ const baseClassName = styleNames.base
10
+ const componentClassName = 'throughput-indicator'
11
+
12
+ const ThroughPutIndicator = ({ data, keyName = 'reserved' }) => {
13
+ const renderNoChange = () => (
14
+ <div
15
+ className={[
16
+ baseClassName,
17
+ componentClassName,
18
+ ]
19
+ .filter((e) => e)
20
+ .join(' ')}
21
+ >
22
+ <span className="no-change-text">No change</span>
23
+ </div>
24
+ )
25
+
26
+ const renderChange = (direction, percentage, icon = direction === 'positive' ? 'S' : 'R') => (
27
+ <div
28
+ className={[
29
+ baseClassName,
30
+ componentClassName,
31
+ ]
32
+ .filter((e) => e)
33
+ .join(' ')}
34
+ >
35
+ <span className={`ai-icon ${direction}-throughput-indicator`}>{icon}</span>
36
+ <p>
37
+ {percentage}
38
+ %
39
+ </p>
40
+ </div>
41
+ )
42
+
43
+ // Handle invalid or insufficient data
44
+ if (!data || data.length < 2) {
45
+ return renderNoChange()
46
+ }
47
+
48
+ const first = data[0][keyName]
49
+ const last = data[data.length - 1][keyName]
50
+
51
+ // Handle no change scenarios
52
+ if (first === 0 && last === 0) {
53
+ return renderNoChange()
54
+ }
55
+
56
+ // Handle special case: starting from zero
57
+ if (first === 0 && last !== 0) {
58
+ return renderChange('positive', '100')
59
+ }
60
+
61
+ // Calculate percentage change
62
+ const percentChange = ((last - first) / Math.abs(first)) * 100
63
+ const rounded = Math.abs(percentChange).toFixed(1)
64
+
65
+ // No change
66
+ if (percentChange === 0) {
67
+ return renderNoChange()
68
+ }
69
+
70
+ // Positive or negative change
71
+ const direction = percentChange > 0 ? 'positive' : 'negative'
72
+ const icon = direction === 'positive' ? 'S' : 'R'
73
+
74
+ return renderChange(direction, rounded, icon)
75
+ }
76
+
77
+ ThroughPutIndicator.propTypes = {
78
+ /**
79
+ * The data to be displayed in the throughput indicator
80
+ */
81
+ // eslint-disable-next-line react/forbid-prop-types
82
+ data:PropTypes.arrayOf(PropTypes.object).isRequired,
83
+
84
+ /**
85
+ * The key name to be displayed in the throughput indicator
86
+ */
87
+ keyName:PropTypes.string,
88
+ }
89
+
90
+ export default ThroughPutIndicator
@@ -0,0 +1,2 @@
1
+ /* @pareto-engineering/generator-front 1.0.12 */
2
+ export { default as ThroughPutIndicator } from './ThroughPutIndicator'
@@ -0,0 +1,35 @@
1
+ /* @pareto-engineering/generator-front 1.0.12 */
2
+
3
+ @use "@pareto-engineering/bem";
4
+
5
+ $default-text-font-size: calc(var(--s-1) * 1rem);
6
+
7
+ .#{bem.$base} {
8
+ .throughput-indicator {
9
+ align-items: center;
10
+ border: 1px solid var(--hard-grey);
11
+ border-radius: 2rem;
12
+ display: flex;
13
+ gap: .5rem;
14
+ height: 3rem;
15
+ padding: .5rem;
16
+
17
+ .positive-throughput-indicator {
18
+ color: var(--success);
19
+ font-size: 1rem;
20
+ }
21
+
22
+ .negative-throughput-indicator {
23
+ color: var(--error);
24
+ font-size: .75rem;
25
+ }
26
+
27
+ .no-change-text {
28
+ color: var(--paragraph);
29
+ }
30
+
31
+ p {
32
+ font-size: 1rem;
33
+ }
34
+ }
35
+ }
@@ -51,7 +51,7 @@ const ToggleSwitch = ({
51
51
  onChange={handleOnChange}
52
52
  />
53
53
  {/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
54
- <label htmlFor={inputId} />
54
+ <label htmlFor={inputId} className={checked ? 'checked' : ''} />
55
55
  </button>
56
56
  )
57
57
 
@@ -7,7 +7,7 @@ $default-size: var(--size, 1.2em);
7
7
  $default-slider-color: var(--slider-color, var(--background-far));
8
8
  $default-slider-border-color: var(--slider-border-color, var(--ui-lines));
9
9
  $default-background-color: var(--slider-background-color, var(--interactive));
10
-
10
+ $default-background-disabled: var(--disabled, var(--background-far));
11
11
  .#{bem.$base}.toggle-switch {
12
12
  background: transparent;
13
13
  border: none;
@@ -21,7 +21,6 @@ $default-background-color: var(--slider-background-color, var(--interactive));
21
21
  }
22
22
 
23
23
  >label {
24
- background: $default-background-color;
25
24
  border-radius: $default-border-radius;
26
25
  cursor: pointer;
27
26
  display: block;
@@ -29,6 +28,14 @@ $default-background-color: var(--slider-background-color, var(--interactive));
29
28
  position: relative;
30
29
  width: calc($default-size * 2);
31
30
 
31
+ &.checked {
32
+ background: $default-background-color;
33
+ }
34
+
35
+ &:not(.checked) {
36
+ background: $default-background-disabled;
37
+ }
38
+
32
39
  &::after {
33
40
  background: $default-slider-color;
34
41
  border: 1px solid $default-slider-border-color;
@@ -1,5 +1,6 @@
1
1
  /* @pareto-engineering/generator-front 1.0.12 */
2
2
  import * as React from 'react'
3
+ import { useEffect } from 'react'
3
4
 
4
5
  import PropTypes from 'prop-types'
5
6
 
@@ -21,40 +22,63 @@ const Tooltip = ({
21
22
  className:userClassName,
22
23
  style,
23
24
  position,
25
+ isFloating,
24
26
  color,
25
27
  description,
26
28
  content,
27
29
  children,
28
30
  // ...otherProps
29
- }) => (
30
- <div
31
- id={id}
32
- className={[
33
- baseClassName,
34
- componentClassName,
35
- userClassName,
36
- `x-${color}`,
37
- ]
38
- .filter((e) => e)
39
- .join(' ')}
40
- style={style}
41
-
42
- >
43
- <div
44
- className="tooltip-trigger-wrapper"
45
- aria-describedby={description}
46
- >
47
- {children}
48
- </div>
31
+ }) => {
32
+ useEffect(() => {
33
+ const handleMouseMove = (e) => {
34
+ document.documentElement.style.setProperty('--mouse-x', `${e.clientX}px`)
35
+ document.documentElement.style.setProperty('--mouse-y', `${e.clientY}px`)
36
+ }
37
+
38
+ if (!isFloating) {
39
+ return () => window.removeEventListener('mousemove', handleMouseMove)
40
+ }
41
+
42
+ window.addEventListener('mousemove', handleMouseMove)
43
+
44
+ return () => window.removeEventListener('mousemove', handleMouseMove)
45
+ }, [isFloating])
46
+
47
+ return (
49
48
  <div
50
- className={`tooltip-content ${position}`}
51
- role="tooltip"
52
- id={description}
49
+ id={id}
50
+ className={[
51
+ baseClassName,
52
+ componentClassName,
53
+ userClassName,
54
+ `x-${color}`,
55
+ ]
56
+ .filter((e) => e)
57
+ .join(' ')}
58
+ style={style}
53
59
  >
54
- {content}
60
+ <div
61
+ className="tooltip-trigger-wrapper"
62
+ aria-describedby={description}
63
+ >
64
+ {children}
65
+ </div>
66
+ <div
67
+ className={[
68
+ 'tooltip-content',
69
+ position,
70
+ isFloating ? 'floating' : '',
71
+ ]
72
+ .filter((e) => e)
73
+ .join(' ')}
74
+ role="tooltip"
75
+ id={description}
76
+ >
77
+ {content}
78
+ </div>
55
79
  </div>
56
- </div>
57
- )
80
+ )
81
+ }
58
82
 
59
83
  Tooltip.propTypes = {
60
84
  /**
@@ -92,6 +116,11 @@ Tooltip.propTypes = {
92
116
  */
93
117
  position:PropTypes.oneOf(['top', 'bottom', 'left', 'right']),
94
118
 
119
+ /**
120
+ * Whether or not the tooltip should be floating
121
+ */
122
+ isFloating:PropTypes.bool,
123
+
95
124
  /**
96
125
  * The base color of the tooltip
97
126
  */
@@ -24,25 +24,53 @@ $default-width: var(--tooltip-width, 20rem);
24
24
  visibility: hidden;
25
25
  z-index: 10;
26
26
 
27
- &.top {
27
+ &.floating.top {
28
+ left: var(--mouse-x);
29
+ position: fixed;
30
+ top: calc(var(--mouse-y) - $default-block-padding);
31
+ transform: translate(-50%, -100%);
32
+ }
33
+
34
+ &.floating.right {
35
+ left: calc(var(--mouse-x) + $default-inline-padding);
36
+ position: fixed;
37
+ top: var(--mouse-y);
38
+ transform: translateY(-50%);
39
+ }
40
+
41
+ &.floating.bottom {
42
+ left: var(--mouse-x);
43
+ position: fixed;
44
+ top: calc(var(--mouse-y) + $default-block-padding);
45
+ transform: translateX(-50%);
46
+ }
47
+
48
+ &.floating.left {
49
+ left: calc(var(--mouse-x) - $default-inline-padding);
50
+ position: fixed;
51
+ top: var(--mouse-y);
52
+ transform: translate(-100%, -50%);
53
+ }
54
+
55
+ &:not(.floating).top {
28
56
  --horizontal: -50%;
29
57
  bottom: calc(100% + $default-block-padding);
30
58
  left: 50%;
31
59
  }
32
60
 
33
- &.right {
61
+ &:not(.floating).right {
34
62
  --vertical: 50%;
35
63
  bottom: 50%;
36
64
  left: calc(100% + $default-inline-padding);
37
65
  }
38
66
 
39
- &.bottom {
67
+ &:not(.floating).bottom {
40
68
  --horizontal: -50%;
41
69
  left: 50%;
42
70
  top: calc(100% + $default-block-padding);
43
71
  }
44
72
 
45
- &.left {
73
+ &:not(.floating).left {
46
74
  --vertical: 50%;
47
75
  bottom: 50%;
48
76
  right: calc(100% + $default-inline-padding);
@@ -5,7 +5,7 @@ import { useEffect, useRef } from 'react'
5
5
 
6
6
  import PropTypes from 'prop-types'
7
7
 
8
- import { EditorState } from '@codemirror/state'
8
+ import { EditorState, Prec } from '@codemirror/state'
9
9
 
10
10
  import {
11
11
  EditorView,
@@ -25,6 +25,7 @@ import {
25
25
  indentWithTab,
26
26
  history,
27
27
  historyKeymap,
28
+ insertNewlineAndIndent,
28
29
  } from '@codemirror/commands'
29
30
 
30
31
  import {
@@ -67,7 +68,19 @@ const XMLEditor = ({
67
68
  const startState = EditorState.create({
68
69
  doc :config,
69
70
  extensions:[
70
- keymap.of([defaultKeymap, indentWithTab, ...historyKeymap]),
71
+ Prec.highest(
72
+ keymap.of([
73
+ {
74
+ key:'Enter',
75
+ run:(view) => insertNewlineAndIndent(view),
76
+ },
77
+ ]),
78
+ ),
79
+ keymap.of([
80
+ defaultKeymap,
81
+ indentWithTab,
82
+ ...historyKeymap,
83
+ ]),
71
84
  indentOnInput(),
72
85
  lineNumbers(),
73
86
  bracketMatching(),
package/src/ui/a/index.js CHANGED
@@ -31,3 +31,4 @@ export { XMLEditor } from './XMLEditor'
31
31
  export { DatePicker } from './DatePicker'
32
32
  export { Tooltip } from './Tooltip'
33
33
  export { AreaChart, BarChart, PieChart } from './Charts'
34
+ export { ThroughPutIndicator } from './ThroughPutIndicator'
@@ -19,6 +19,7 @@ import {
19
19
  EditorInput,
20
20
  FileUpload,
21
21
  LatexPreviewInput,
22
+ ToggleInput,
22
23
  } from '../fields'
23
24
 
24
25
  import './styles.scss'
@@ -100,6 +101,15 @@ const FormInput = ({
100
101
  />
101
102
  )
102
103
  }
104
+ if (type === 'toggle') {
105
+ return (
106
+ <ToggleInput
107
+ className={newClassName}
108
+ disabled={disabled}
109
+ {...otherProps}
110
+ />
111
+ )
112
+ }
103
113
 
104
114
  if (type === 'query-choices') {
105
115
  return (
@@ -218,6 +228,7 @@ FormInput.propTypes = {
218
228
  'url',
219
229
  'rating',
220
230
  'checkbox',
231
+ 'toggle',
221
232
  // to be removed
222
233
  'extendedTypeInput',
223
234
  ]),
@@ -0,0 +1,140 @@
1
+ /* @pareto-engineering/generator-front 1.1.1-alpha.3 */
2
+ import * as React from 'react'
3
+ import PropTypes from 'prop-types'
4
+ import { useField } from 'formik'
5
+ import styleNames from '@pareto-engineering/bem/exports'
6
+ import { ToggleSwitch } from 'ui/a'
7
+ import { FormLabel, FormDescription } from '../../common'
8
+
9
+ import './styles.scss'
10
+
11
+ // Local Definitions
12
+ const baseClassName = styleNames.base
13
+ const componentClassName = 'toggle-input'
14
+
15
+ /**
16
+ * Toggle input field component that wraps ToggleSwitch for use with Formik
17
+ */
18
+ const ToggleInput = ({
19
+ id,
20
+ className: userClassName,
21
+ style,
22
+ name,
23
+ label,
24
+ color,
25
+ labelColor,
26
+ validate,
27
+ description,
28
+ disabled,
29
+ optional,
30
+ size,
31
+ // ...otherProps
32
+ }) => {
33
+ const [field, , helpers] = useField({ name, validate, type: 'checkbox' })
34
+
35
+ const handleChange = () => {
36
+ helpers.setValue(!field.value)
37
+ }
38
+
39
+ return (
40
+ <div
41
+ id={id}
42
+ className={[
43
+ baseClassName,
44
+ componentClassName,
45
+ userClassName,
46
+ `y-${color}`,
47
+ ]
48
+ .filter((e) => e)
49
+ .join(' ')}
50
+ style={style}
51
+ >
52
+ <FormLabel
53
+ name={name}
54
+ color={labelColor}
55
+ optional={optional}
56
+ >
57
+ {label}
58
+ </FormLabel>
59
+ <div className="toggle-wrapper">
60
+ <ToggleSwitch
61
+ checked={Boolean(field.value)}
62
+ handleOnChange={handleChange}
63
+ inputId={name}
64
+ size={size}
65
+ disabled={disabled}
66
+ />
67
+ </div>
68
+ <FormDescription className="s-1" description={description} name={name} />
69
+ </div>
70
+ )
71
+ }
72
+
73
+ ToggleInput.propTypes = {
74
+ /**
75
+ * The HTML id for this element
76
+ */
77
+ id:PropTypes.string,
78
+
79
+ /**
80
+ * The HTML class names for this element
81
+ */
82
+ className:PropTypes.string,
83
+
84
+ /**
85
+ * The React-written, css properties for this element.
86
+ */
87
+ style:PropTypes.objectOf(PropTypes.string),
88
+
89
+ /**
90
+ * The input name (html - and Formik state)
91
+ */
92
+ name:PropTypes.string.isRequired,
93
+
94
+ /**
95
+ * The input label
96
+ */
97
+ label:PropTypes.string.isRequired,
98
+
99
+ /**
100
+ * The input label color
101
+ */
102
+ labelColor:PropTypes.string,
103
+
104
+ /**
105
+ * The input field validator function
106
+ */
107
+ validate:PropTypes.func,
108
+
109
+ /**
110
+ * Input description
111
+ */
112
+ description:PropTypes.string,
113
+
114
+ /**
115
+ * Whether the toggle input should be disabled
116
+ */
117
+ disabled:PropTypes.bool,
118
+
119
+ /**
120
+ * The text input color
121
+ */
122
+ color:PropTypes.string,
123
+
124
+ /**
125
+ * Whether the input is optional or not
126
+ */
127
+ optional:PropTypes.bool,
128
+
129
+ /**
130
+ * The size of the toggle switch
131
+ */
132
+ size:PropTypes.string,
133
+ }
134
+
135
+ ToggleInput.defaultProps = {
136
+ color :'paragraph',
137
+ disabled:false,
138
+ }
139
+
140
+ export default ToggleInput
@@ -0,0 +1,2 @@
1
+ /* @pareto-engineering/generator-front 1.1.1-alpha.3 */
2
+ export { default as ToggleInput } from './ToggleInput'
@@ -0,0 +1,22 @@
1
+ /* @pareto-engineering/generator-front 1.1.1-alpha.3 */
2
+
3
+ @use "@pareto-engineering/bem";
4
+ @use "@pareto-engineering/styles/src/mixins";
5
+ @use "@pareto-engineering/styles/src/globals" as *;
6
+
7
+ .#{bem.$base}.toggle-input {
8
+ display: flex;
9
+ flex-direction: column;
10
+
11
+ > .#{bem.$base}.form-label {
12
+ margin-bottom: var(--gap);
13
+ }
14
+
15
+ > .toggle-wrapper {
16
+ align-items: center;
17
+ display: flex;
18
+ margin-bottom: calc(var(--gap) / 2);
19
+ }
20
+ }
21
+
22
+
@@ -19,3 +19,4 @@ export {
19
19
  getFileType,
20
20
  getFileTypeFromUrl,
21
21
  } from './FileUpload'
22
+ export { ToggleInput } from './ToggleInput'
@@ -1,11 +1,12 @@
1
1
  export const DATE_FORMATS = {
2
- HUMAN_READABLE:'human_readable',
3
- TIME :'time',
4
- DATETIME :'datetime',
5
- CHART_DATE :'chart_date',
6
- CHART_TIME :'chart_time',
7
- WEEKDAY_DATE :'weekday_date',
8
- DAY_VIEW :'day_view',
2
+ HUMAN_READABLE :'human_readable',
3
+ HUMAN_READABLE_WITH_TIME:'human_readable_with_time',
4
+ TIME :'time',
5
+ DATETIME :'datetime',
6
+ CHART_DATE :'chart_date',
7
+ CHART_TIME :'chart_time',
8
+ WEEKDAY_DATE :'weekday_date',
9
+ DAY_VIEW :'day_view',
9
10
  }
10
11
 
11
12
  const isValidDate = (date) => date instanceof Date && !Number.isNaN(date)
@@ -52,28 +53,6 @@ export const formatTime = (seconds) => {
52
53
  return parts.join(' ')
53
54
  }
54
55
 
55
- const parseDate = (input) => {
56
- if (input instanceof Date) return input
57
- if (typeof input === 'number') return new Date(input)
58
-
59
- if (typeof input === 'string') {
60
- if (isTimeSliceFormat(input)) {
61
- return createTimeFromSlice(input)
62
- }
63
-
64
- const parsed = new Date(input)
65
- if (isValidDate(parsed)) return parsed
66
-
67
- const timestamp = parseInt(input, 10)
68
- if (!Number.isNaN(timestamp)) {
69
- const date = new Date(timestamp * 1000)
70
- if (isValidDate(date)) return date
71
- }
72
- }
73
-
74
- return null
75
- }
76
-
77
56
  const formatStrategies = {
78
57
  [DATE_FORMATS.CHART_DATE]:(date) => {
79
58
  const monthDay = date.toLocaleDateString('en-US', {
@@ -95,9 +74,39 @@ const formatStrategies = {
95
74
  timeZone:'UTC',
96
75
  }),
97
76
 
77
+ [DATE_FORMATS.HUMAN_READABLE_WITH_TIME]:(date) => date.toLocaleString('en-US', {
78
+ year :'numeric',
79
+ month :'short',
80
+ day :'numeric',
81
+ hour :'2-digit',
82
+ timeZone:'UTC',
83
+ }),
84
+
98
85
  default:(date) => date.toISOString(),
99
86
  }
100
87
 
88
+ export const parseDate = (input) => {
89
+ if (input instanceof Date) return input
90
+ if (typeof input === 'number') return new Date(input)
91
+
92
+ if (typeof input === 'string') {
93
+ if (isTimeSliceFormat(input)) {
94
+ return createTimeFromSlice(input)
95
+ }
96
+
97
+ const parsed = new Date(input)
98
+ if (isValidDate(parsed)) return parsed
99
+
100
+ const timestamp = parseInt(input, 10)
101
+ if (!Number.isNaN(timestamp)) {
102
+ const date = new Date(timestamp * 1000)
103
+ if (isValidDate(date)) return date
104
+ }
105
+ }
106
+
107
+ return null
108
+ }
109
+
101
110
  export const formatDate = (input, format = DATE_FORMATS.HUMAN_READABLE) => {
102
111
  try {
103
112
  if (typeof input === 'string' && isTimeSliceFormat(input)) {
@@ -1,5 +1,5 @@
1
1
  export { useWindowSize, useDynamicPosition, useOutsideClick } from './hooks'
2
2
  export {
3
- formatTime, formatDate, DATE_FORMATS, snakeCaseToTitleCase,
3
+ formatTime, formatDate, DATE_FORMATS, parseDate, snakeCaseToTitleCase,
4
4
  } from './formatting'
5
5
  export { applyCharacterLimit } from './applyCharacterLimit'