playbook_ui 12.32.0 → 12.33.0.pre.alpha.PLAY905reactionbuttons979
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/index.js +1 -1
- data/app/pb_kits/playbook/pb_background/_background.tsx +10 -1
- data/app/pb_kits/playbook/pb_background/background.html.erb +2 -1
- data/app/pb_kits/playbook/pb_background/background.rb +4 -2
- data/app/pb_kits/playbook/pb_body/_body_mixins.scss +1 -0
- data/app/pb_kits/playbook/pb_button/_button.scss +33 -0
- data/app/pb_kits/playbook/pb_button/_button.tsx +65 -26
- data/app/pb_kits/playbook/pb_button/_button_mixins.scss +6 -6
- data/app/pb_kits/playbook/pb_button/button.html.erb +13 -0
- data/app/pb_kits/playbook/pb_button/button.rb +13 -2
- data/app/pb_kits/playbook/pb_button/docs/_button_reaction.html.erb +3 -0
- data/app/pb_kits/playbook/pb_button/docs/_button_reaction.jsx +38 -0
- data/app/pb_kits/playbook/pb_button/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_button/docs/index.js +2 -1
- data/app/pb_kits/playbook/pb_circle_icon_button/_circle_icon_button.scss +1 -1
- data/app/pb_kits/playbook/pb_date/_date.tsx +7 -8
- data/app/pb_kits/playbook/pb_date/docs/_date_alignment.jsx +2 -2
- data/app/pb_kits/playbook/pb_date/docs/_date_default.jsx +4 -4
- data/app/pb_kits/playbook/pb_date/docs/_date_unstyled.jsx +2 -2
- data/app/pb_kits/playbook/pb_date/docs/_date_variants.jsx +5 -5
- data/app/pb_kits/playbook/pb_date_range_inline/_date_range_inline.tsx +45 -31
- data/app/pb_kits/playbook/pb_date_range_stacked/_date_range_stacked.tsx +5 -3
- data/app/pb_kits/playbook/pb_date_stacked/_date_stacked.tsx +24 -21
- data/app/pb_kits/playbook/pb_date_time/_date_time.tsx +1 -1
- data/app/pb_kits/playbook/pb_date_time/dateTime.test.js +1 -1
- data/app/pb_kits/playbook/pb_date_time_stacked/_date_time_stacked.tsx +2 -2
- data/app/pb_kits/playbook/pb_date_time_stacked/date_time_stacked.test.js +1 -1
- data/app/pb_kits/playbook/pb_date_year_stacked/_date_year_stacked.tsx +6 -8
- data/app/pb_kits/playbook/pb_dialog/_dialog.scss +321 -316
- data/app/pb_kits/playbook/pb_dialog/_dialog.tsx +12 -9
- data/app/pb_kits/playbook/pb_dialog/dialog.html.erb +8 -8
- data/app/pb_kits/playbook/pb_dialog/dialogHelper.js +16 -15
- data/app/pb_kits/playbook/pb_icon/_icon.tsx +4 -2
- data/app/pb_kits/playbook/pb_icon/docs/_icon_fa_kit.html.erb +1 -0
- data/app/pb_kits/playbook/pb_icon/docs/_icon_fa_kit.jsx +21 -0
- data/app/pb_kits/playbook/pb_icon/docs/_icon_fa_kit.md +7 -0
- data/app/pb_kits/playbook/pb_icon/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_icon/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_icon/icon.rb +1 -1
- data/app/pb_kits/playbook/pb_icon_circle/_icon_circle.tsx +14 -4
- data/app/pb_kits/playbook/pb_icon_circle/icon_circle.rb +1 -1
- data/app/pb_kits/playbook/pb_icon_stat_value/_icon_stat_value.tsx +12 -1
- data/app/pb_kits/playbook/pb_icon_stat_value/docs/_icon_stat_value_color.html.erb +6 -0
- data/app/pb_kits/playbook/pb_icon_stat_value/docs/_icon_stat_value_color.jsx +9 -0
- data/app/pb_kits/playbook/pb_icon_stat_value/icon_stat_value.html.erb +16 -12
- data/app/pb_kits/playbook/pb_icon_stat_value/icon_stat_value.rb +2 -2
- data/app/pb_kits/playbook/pb_kit/dateTime.ts +139 -67
- data/app/pb_kits/playbook/pb_label_value/_label_value.tsx +52 -31
- data/app/pb_kits/playbook/pb_map/_map.scss +4 -0
- data/app/pb_kits/playbook/pb_message/_message.tsx +24 -24
- data/app/pb_kits/playbook/pb_time/_time.tsx +9 -11
- data/app/pb_kits/playbook/pb_time_range_inline/_time_range_inline.tsx +46 -49
- data/app/pb_kits/playbook/pb_time_stacked/_time_stacked.tsx +4 -6
- data/app/pb_kits/playbook/pb_timestamp/_timestamp.tsx +11 -11
- data/app/pb_kits/playbook/pb_weekday_stacked/_weekday_stacked.tsx +8 -11
- data/app/pb_kits/playbook/tokens/_colors.scss +4 -2
- data/app/pb_kits/playbook/utilities/_border_radius.scss +11 -1
- data/app/pb_kits/playbook/utilities/_line_height.scss +1 -2
- data/app/pb_kits/playbook/utilities/_shadow.scss +0 -1
- data/app/pb_kits/playbook/utilities/globalProps.ts +1 -1
- data/dist/playbook-rails.js +7 -7
- data/lib/playbook/version.rb +2 -2
- metadata +12 -8
- data/app/pb_kits/playbook/pb_logistic/_logistic.jsx +0 -120
@@ -181,7 +181,10 @@ const Dialog = (props: DialogProps) => {
|
|
181
181
|
{title && !status ? <Dialog.Header>{title}</Dialog.Header> : null}
|
182
182
|
{!status && text ? <Dialog.Body>{text}</Dialog.Body> : null}
|
183
183
|
{status && (
|
184
|
-
<Dialog.Body
|
184
|
+
<Dialog.Body
|
185
|
+
className="dialog_status_text_align"
|
186
|
+
padding="md"
|
187
|
+
>
|
185
188
|
<Flex align="center" orientation="column">
|
186
189
|
<IconCircle
|
187
190
|
icon={sweetAlertStatus[status].icon}
|
@@ -197,17 +200,17 @@ const Dialog = (props: DialogProps) => {
|
|
197
200
|
)}
|
198
201
|
{cancelButton && confirmButton ? (
|
199
202
|
<Dialog.Footer>
|
200
|
-
<Button
|
201
|
-
loading={loading}
|
202
|
-
onClick={onConfirm}
|
203
|
-
htmlType="button"
|
203
|
+
<Button
|
204
|
+
loading={loading}
|
205
|
+
onClick={onConfirm}
|
206
|
+
htmlType="button"
|
204
207
|
variant="primary">
|
205
208
|
{confirmButton}
|
206
209
|
</Button>
|
207
|
-
<Button
|
208
|
-
id="cancel-button"
|
209
|
-
onClick={onCancel}
|
210
|
-
variant="link"
|
210
|
+
<Button
|
211
|
+
id="cancel-button"
|
212
|
+
onClick={onCancel}
|
213
|
+
variant="link"
|
211
214
|
htmlType="button">
|
212
215
|
{cancelButton}
|
213
216
|
</Button>
|
@@ -5,38 +5,38 @@
|
|
5
5
|
id: object.id,
|
6
6
|
class: object.classname) do %>
|
7
7
|
<% if object.status === "" && object.title %>
|
8
|
-
<%= pb_rails("dialog/dialog_header", props: {title: object.title, id: object.id }) %>
|
8
|
+
<%= pb_rails("dialog/dialog_header", props: { title: object.title, id: object.id }) %>
|
9
9
|
<% end %>
|
10
10
|
<% if object.status === "" && object.text %>
|
11
11
|
<%= pb_rails("dialog/dialog_body", props: { text: object.text }) %>
|
12
12
|
<% end %>
|
13
13
|
<% if object.status != "" %>
|
14
|
-
<%= pb_rails("dialog/dialog_body", props: {padding: "md"}) do %>
|
15
|
-
<%= pb_rails("flex", props: {align: "center", orientation: "column"}) do %>
|
14
|
+
<%= pb_rails("dialog/dialog_body", props: { classname: "dialog_status_text_align" ,padding: "md" }) do %>
|
15
|
+
<%= pb_rails("flex", props: { align: "center", orientation: "column" }) do %>
|
16
16
|
<%= pb_rails("icon_circle", props: {
|
17
17
|
icon: object.status_alerts[0],
|
18
18
|
variant: object.status_alerts[1],
|
19
19
|
size: "lg"
|
20
20
|
}) %>
|
21
21
|
<%= pb_rails("title", props: { text: object.title, tag: "h1", size: 3, margin_top: "sm" }) %>
|
22
|
-
<%= pb_rails("body", props: {text: object.text, margin_top: "sm"}) %>
|
22
|
+
<%= pb_rails("body", props: { text: object.text, margin_top: "sm" }) %>
|
23
23
|
<% end %>
|
24
24
|
<% end %>
|
25
25
|
<% end %>
|
26
26
|
<% if object.cancel_button && object.confirm_button %>
|
27
27
|
<%= pb_rails("dialog/dialog_footer", props: {
|
28
|
-
cancel_button: object.cancel_button,
|
28
|
+
cancel_button: object.cancel_button,
|
29
29
|
confirm_button: object.confirm_button,
|
30
30
|
id: object.id
|
31
31
|
}) %>
|
32
32
|
<% end %>
|
33
|
-
|
33
|
+
|
34
34
|
<%= content %>
|
35
35
|
<% end %>
|
36
36
|
</div>
|
37
37
|
|
38
38
|
<%= javascript_tag do %>
|
39
|
-
window.addEventListener("DOMContentLoaded", () => {
|
39
|
+
window.addEventListener("DOMContentLoaded", () => {
|
40
40
|
dialogHelper()
|
41
41
|
})
|
42
|
-
|
42
|
+
<% end %>
|
@@ -1,6 +1,7 @@
|
|
1
1
|
const dialogHelper = () => {
|
2
2
|
const openTrigger = document.querySelectorAll("[data-open-dialog]");
|
3
3
|
const closeTrigger = document.querySelectorAll("[data-close-dialog]");
|
4
|
+
const dialogs = document.querySelectorAll(".pb_dialog_rails")
|
4
5
|
|
5
6
|
openTrigger.forEach((open) => {
|
6
7
|
open.addEventListener("click", () => {
|
@@ -8,21 +9,6 @@ const dialogHelper = () => {
|
|
8
9
|
var targetDialog = document.getElementById(openTriggerData)
|
9
10
|
if (targetDialog.open) return;
|
10
11
|
targetDialog.showModal();
|
11
|
-
|
12
|
-
//the following allows you to close dialog by clicking on overlay
|
13
|
-
targetDialog.addEventListener('click',((event) => {
|
14
|
-
var dialogContainerData = targetDialog.parentElement.dataset
|
15
|
-
if (dialogContainerData.overlayClick === "overlay_close") return;
|
16
|
-
let rect = event.target.getBoundingClientRect();
|
17
|
-
if (rect.left > event.clientX ||
|
18
|
-
rect.right < event.clientX ||
|
19
|
-
rect.top > event.clientY ||
|
20
|
-
rect.bottom < event.clientY
|
21
|
-
) {
|
22
|
-
targetDialog.close();
|
23
|
-
}
|
24
|
-
})
|
25
|
-
);
|
26
12
|
});
|
27
13
|
});
|
28
14
|
|
@@ -32,6 +18,21 @@ const dialogHelper = () => {
|
|
32
18
|
document.getElementById(closeTriggerData).close();
|
33
19
|
});
|
34
20
|
});
|
21
|
+
|
22
|
+
// Close dialog box on outside click
|
23
|
+
dialogs.forEach((dialogElement) => {
|
24
|
+
dialogElement.addEventListener("click", (event) => {
|
25
|
+
const dialogParentDataset = dialogElement.parentElement.dataset
|
26
|
+
if (dialogParentDataset.overlayClick === "overlay_close") return
|
27
|
+
|
28
|
+
const clickedOutsideDialogBox = event.target.classList.contains("pb_dialog_rails")
|
29
|
+
|
30
|
+
if (clickedOutsideDialogBox) {
|
31
|
+
dialogElement.close()
|
32
|
+
event.stopPropagation()
|
33
|
+
}
|
34
|
+
})
|
35
|
+
})
|
35
36
|
};
|
36
37
|
|
37
38
|
export default dialogHelper;
|
@@ -34,7 +34,7 @@ type IconProps = {
|
|
34
34
|
pulse?: boolean,
|
35
35
|
rotation?: 90 | 180 | 270,
|
36
36
|
size?: IconSizes,
|
37
|
-
fontStyle?: 'far' | 'fas' | 'fab',
|
37
|
+
fontStyle?: 'far' | 'fas' | 'fab' | 'fak',
|
38
38
|
spin?: boolean,
|
39
39
|
} & GlobalProps
|
40
40
|
|
@@ -76,6 +76,7 @@ const Icon = (props: IconProps) => {
|
|
76
76
|
[`fa-${size}`]: size,
|
77
77
|
[`fa-pull-${pull}`]: pull,
|
78
78
|
[`fa-rotate-${rotation}`]: rotation,
|
79
|
+
|
79
80
|
}
|
80
81
|
|
81
82
|
// Lets check and see if the icon prop is referring to a custom Power icon...
|
@@ -83,7 +84,7 @@ const Icon = (props: IconProps) => {
|
|
83
84
|
// this ensures the JS will not do any further operations
|
84
85
|
// faClasses[`fa-${icon}`] = customIcon ? 'custom' : icon
|
85
86
|
if (!customIcon) faClasses[`fa-${icon}`] = icon
|
86
|
-
|
87
|
+
|
87
88
|
const classes = classnames(
|
88
89
|
flipMap[flip],
|
89
90
|
'pb_icon_kit',
|
@@ -110,6 +111,7 @@ const Icon = (props: IconProps) => {
|
|
110
111
|
return emojiRegex.test(emoji);
|
111
112
|
};
|
112
113
|
|
114
|
+
|
113
115
|
// Add a conditional here to show only the SVG if custom
|
114
116
|
const displaySVG = (customIcon: any) => {
|
115
117
|
if (customIcon)
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= pb_rails("icon", props: { icon: "powergon", font_style: "fak", fixed_width: true, size: "5x" }) %>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
|
3
|
+
import Icon from '../_icon'
|
4
|
+
|
5
|
+
import '../../../../../../playbook-website/app/javascript/scripts/custom-icons'
|
6
|
+
|
7
|
+
const IconFaKit = (props) => {
|
8
|
+
return (
|
9
|
+
<div>
|
10
|
+
<Icon
|
11
|
+
{...props}
|
12
|
+
fixedWidth
|
13
|
+
fontStyle="fak"
|
14
|
+
icon="powergon"
|
15
|
+
size="5x"
|
16
|
+
/>
|
17
|
+
</div>
|
18
|
+
)
|
19
|
+
}
|
20
|
+
|
21
|
+
export default IconFaKit
|
@@ -0,0 +1,7 @@
|
|
1
|
+
Our Icon kit allows integration with [FontAwesome's custom kit](https://fontawesome.com/v6/docs/web/setup/use-kit#contentHeader) functionality out-of-the-box.
|
2
|
+
|
3
|
+
All you need to do is 3 things:
|
4
|
+
1) Import your custom-icon.js file as outlined in the FontAwesome docs.
|
5
|
+
2) Use our fontStyle prop called "fak" so that our Icon component knows you are using a "fa-kit" icon.
|
6
|
+
3) Pass in your FaKit name as a string to our icon prop (This is the name that you designated when you uploaded the icon on their site).
|
7
|
+
|
@@ -8,6 +8,7 @@ examples:
|
|
8
8
|
- icon_border: Icon Border
|
9
9
|
- icon_sizes: Icon Sizes
|
10
10
|
- icon_custom: Icon Custom
|
11
|
+
- icon_fa_kit: Icon with FontAwesome Kit
|
11
12
|
|
12
13
|
react:
|
13
14
|
- icon_default: Icon Default
|
@@ -18,3 +19,4 @@ examples:
|
|
18
19
|
- icon_border: Icon Border
|
19
20
|
- icon_sizes: Icon Sizes
|
20
21
|
- icon_custom: Icon Custom
|
22
|
+
- icon_fa_kit: Icon with FontAwesome Kit
|
@@ -6,3 +6,4 @@ export { default as IconPull } from './_icon_pull.jsx'
|
|
6
6
|
export { default as IconBorder } from './_icon_border.jsx'
|
7
7
|
export { default as IconSizes } from './_icon_sizes.jsx'
|
8
8
|
export { default as IconCustom } from './_icon_custom.jsx'
|
9
|
+
export { default as IconFaKit} from './_icon_fa_kit.jsx'
|
@@ -33,7 +33,7 @@ module Playbook
|
|
33
33
|
values: ["lg", "xs", "sm", "1x", "2x", "3x", "4x", "5x", "6x", "7x", "8x", "9x", "10x", nil],
|
34
34
|
default: nil
|
35
35
|
prop :font_style, type: Playbook::Props::Enum,
|
36
|
-
values: %w[far fas fab],
|
36
|
+
values: %w[far fas fab fak],
|
37
37
|
default: "far"
|
38
38
|
prop :spin, type: Playbook::Props::Boolean,
|
39
39
|
default: false
|
@@ -22,11 +22,21 @@ type IconCircleProps = {
|
|
22
22
|
| "teal"
|
23
23
|
| "red"
|
24
24
|
| "yellow"
|
25
|
+
| "orange"
|
25
26
|
| "green",
|
26
27
|
}
|
27
28
|
|
28
29
|
const IconCircle = (props: IconCircleProps) => {
|
29
|
-
const {
|
30
|
+
const {
|
31
|
+
aria = {},
|
32
|
+
className,
|
33
|
+
dark = false,
|
34
|
+
data = {},
|
35
|
+
icon,
|
36
|
+
id,
|
37
|
+
size = 'md',
|
38
|
+
variant = 'default'
|
39
|
+
} = props
|
30
40
|
|
31
41
|
const ariaProps = buildAriaProps(aria)
|
32
42
|
const dataProps = buildDataProps(data)
|
@@ -41,10 +51,10 @@ const IconCircle = (props: IconCircleProps) => {
|
|
41
51
|
id={id}
|
42
52
|
>
|
43
53
|
<Icon
|
44
|
-
|
45
|
-
|
54
|
+
dark={dark}
|
55
|
+
icon={icon}
|
46
56
|
/>
|
47
|
-
|
57
|
+
|
48
58
|
</div>
|
49
59
|
)
|
50
60
|
}
|
@@ -10,7 +10,7 @@ module Playbook
|
|
10
10
|
values: %w[xs sm md base lg xl],
|
11
11
|
default: "md"
|
12
12
|
prop :variant, type: Playbook::Props::Enum,
|
13
|
-
values: %w[default royal blue orange purple teal red yellow green],
|
13
|
+
values: %w[default royal blue orange purple teal red yellow green orange],
|
14
14
|
default: "default"
|
15
15
|
|
16
16
|
def classname
|
@@ -14,6 +14,7 @@ type IconStatValueProps = {
|
|
14
14
|
aria?: { [key: string]: string },
|
15
15
|
className?: string,
|
16
16
|
data?: object,
|
17
|
+
dark?: boolean,
|
17
18
|
icon: string,
|
18
19
|
id?: string,
|
19
20
|
orientation?: "vertical" | "horizontal",
|
@@ -28,6 +29,7 @@ type IconStatValueProps = {
|
|
28
29
|
| "teal"
|
29
30
|
| "red"
|
30
31
|
| "yellow"
|
32
|
+
| "orange"
|
31
33
|
| "green",
|
32
34
|
}
|
33
35
|
|
@@ -36,6 +38,7 @@ const IconStatValue = (props: IconStatValueProps) => {
|
|
36
38
|
aria = {},
|
37
39
|
className,
|
38
40
|
data = {},
|
41
|
+
dark = false,
|
39
42
|
icon,
|
40
43
|
id,
|
41
44
|
orientation = 'horizontal',
|
@@ -55,6 +58,7 @@ const IconStatValue = (props: IconStatValueProps) => {
|
|
55
58
|
if (size == 'lg') {
|
56
59
|
return (
|
57
60
|
<Title
|
61
|
+
dark={dark}
|
58
62
|
size={1}
|
59
63
|
tag="span"
|
60
64
|
text={`${value}`}
|
@@ -63,6 +67,7 @@ const IconStatValue = (props: IconStatValueProps) => {
|
|
63
67
|
} else if (size == 'md') {
|
64
68
|
return (
|
65
69
|
<Title
|
70
|
+
dark={dark}
|
66
71
|
size={2}
|
67
72
|
tag="span"
|
68
73
|
text={`${value}`}
|
@@ -71,6 +76,7 @@ const IconStatValue = (props: IconStatValueProps) => {
|
|
71
76
|
} else {
|
72
77
|
return (
|
73
78
|
<Title
|
79
|
+
dark={dark}
|
74
80
|
size={3}
|
75
81
|
tag="span"
|
76
82
|
text={`${value}`}
|
@@ -87,6 +93,7 @@ const IconStatValue = (props: IconStatValueProps) => {
|
|
87
93
|
id={id}
|
88
94
|
>
|
89
95
|
<IconCircle
|
96
|
+
dark={dark}
|
90
97
|
icon={icon}
|
91
98
|
size={size}
|
92
99
|
variant={variant}
|
@@ -99,10 +106,14 @@ const IconStatValue = (props: IconStatValueProps) => {
|
|
99
106
|
{titleSize(size)}
|
100
107
|
|
101
108
|
<Body
|
109
|
+
dark={dark}
|
102
110
|
text={unit}
|
103
111
|
/>
|
104
112
|
</Flex>
|
105
|
-
<Caption
|
113
|
+
<Caption
|
114
|
+
dark={dark}
|
115
|
+
text={text}
|
116
|
+
/>
|
106
117
|
</div>
|
107
118
|
|
108
119
|
</div>
|
@@ -4,22 +4,26 @@
|
|
4
4
|
data: object.data,
|
5
5
|
class: object.classname) do %>
|
6
6
|
|
7
|
-
<%= pb_rails
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
<%= pb_rails("icon_circle", props: {
|
8
|
+
dark: object.dark,
|
9
|
+
icon: object.icon,
|
10
|
+
size: object.size,
|
11
|
+
variant: object.variant }) %>
|
11
12
|
|
12
|
-
|
13
|
+
<div>
|
13
14
|
<%= pb_rails("flex", props: { align: "baseline" }) do %>
|
14
|
-
<%= pb_rails
|
15
|
+
<%= pb_rails("title", props: {
|
16
|
+
dark: object.dark,
|
15
17
|
tag: "span",
|
16
18
|
text: object.value_string,
|
17
|
-
size: object.title_size } %>
|
19
|
+
size: object.title_size }) %>
|
18
20
|
|
19
|
-
<%= pb_rails
|
20
|
-
|
21
|
+
<%= pb_rails("body", props: {
|
22
|
+
dark: object.dark,
|
23
|
+
text: object.unit }) %>
|
21
24
|
<% end %>
|
22
|
-
<%= pb_rails
|
23
|
-
|
24
|
-
|
25
|
+
<%= pb_rails("caption", props: {
|
26
|
+
dark: object.dark,
|
27
|
+
text: object.text }) %>
|
28
|
+
</div>
|
25
29
|
<% end %>
|
@@ -9,7 +9,7 @@ module Playbook
|
|
9
9
|
values: %w[sm md lg],
|
10
10
|
default: "sm"
|
11
11
|
prop :variant, type: Playbook::Props::Enum,
|
12
|
-
values: %w[default royal blue purple teal red yellow green],
|
12
|
+
values: %w[default royal blue purple teal red yellow green orange],
|
13
13
|
default: "default"
|
14
14
|
|
15
15
|
prop :orientation, type: Playbook::Props::Enum,
|
@@ -22,7 +22,7 @@ module Playbook
|
|
22
22
|
prop :text, type: Playbook::Props::String,
|
23
23
|
default: ""
|
24
24
|
|
25
|
-
prop :value
|
25
|
+
prop :value
|
26
26
|
|
27
27
|
def classname
|
28
28
|
generate_classname("pb_icon_stat_value_kit", orientation, size, variant)
|
@@ -1,90 +1,162 @@
|
|
1
|
-
|
2
|
-
import moment, { Moment } from 'moment'
|
3
|
-
import 'moment-strftime'
|
4
|
-
import 'moment-timezone'
|
5
|
-
|
6
|
-
type DateTimeType = {
|
7
|
-
value: string | Date,
|
8
|
-
zone?: string,
|
9
|
-
}
|
10
|
-
|
11
1
|
const ABBR_DAYS = ['SU', 'M', 'T', 'W', 'TH', 'F', 'S']
|
12
2
|
|
13
|
-
|
14
|
-
value: Moment & any
|
15
|
-
constructor({ value, zone = 'America/New_York' }: DateTimeType) {
|
16
|
-
this.value = this.convertToTimestampZone(value, zone)
|
17
|
-
}
|
18
|
-
|
19
|
-
convertToTimestampZone(value: string | Date, zone: string) {
|
20
|
-
return moment(value).tz(zone)
|
21
|
-
}
|
22
|
-
|
23
|
-
convertToTimezone() {
|
24
|
-
return this.value.strftime('%Z')
|
25
|
-
}
|
3
|
+
const days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
26
4
|
|
27
|
-
|
28
|
-
return this.value.strftime(format)
|
29
|
-
}
|
5
|
+
const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
|
30
6
|
|
31
|
-
|
32
|
-
|
7
|
+
export const toMinute = (newDate: Date | string, timeZone?: string): string => {
|
8
|
+
const date = new Date(newDate)
|
9
|
+
if (timeZone) {
|
10
|
+
return date.toLocaleTimeString(undefined, {timeZone, hour: "2-digit", minute: "2-digit"}).slice(3, 5);
|
11
|
+
} else {
|
12
|
+
return date.toLocaleTimeString(undefined, {hour: "2-digit", minute: "2-digit"}).slice(3, 5);
|
33
13
|
}
|
14
|
+
}
|
34
15
|
|
35
|
-
|
36
|
-
|
16
|
+
export const toHour = (newDate: Date | string, timeZone?: string): string => {
|
17
|
+
const date = new Date(newDate)
|
18
|
+
if (timeZone) {
|
19
|
+
return date.toLocaleTimeString(undefined, {timeZone, hour: "numeric"}).split(' ')[0];
|
20
|
+
} else {
|
21
|
+
return date.toLocaleTimeString(undefined, {hour: "numeric"}).split(' ')[0];
|
37
22
|
}
|
23
|
+
}
|
38
24
|
|
39
|
-
|
40
|
-
|
41
|
-
|
25
|
+
export const toDay = (newDate: Date | string, timeZone?: string): number => {
|
26
|
+
if (timeZone) {
|
27
|
+
const date = new Date(newDate.toLocaleString(undefined, { timeZone }));
|
28
|
+
return date.getDate()
|
29
|
+
} else {
|
30
|
+
const date = new Date(newDate)
|
31
|
+
return date.getDate()
|
32
|
+
}
|
33
|
+
}
|
42
34
|
|
43
|
-
|
44
|
-
|
45
|
-
|
35
|
+
export const toDayAbbr = (newDate: Date | string): string => {
|
36
|
+
const date = new Date(newDate)
|
37
|
+
return ABBR_DAYS[date.getUTCDay()]
|
38
|
+
}
|
46
39
|
|
47
|
-
|
48
|
-
|
49
|
-
|
40
|
+
export const toWeekday = (newDate: Date | string): string => {
|
41
|
+
const date = new Date(newDate)
|
42
|
+
return days[date.getUTCDay()]
|
43
|
+
}
|
50
44
|
|
51
|
-
|
52
|
-
|
53
|
-
|
45
|
+
export const toMonth = (newDate: Date | string, timeZone?: string): string => {
|
46
|
+
if (timeZone) {
|
47
|
+
const date = new Date(newDate.toLocaleString(undefined, { timeZone }));
|
48
|
+
return months[date.getUTCMonth()]
|
49
|
+
} else {
|
50
|
+
const date = new Date(newDate)
|
51
|
+
return months[date.getUTCMonth()]
|
52
|
+
}
|
53
|
+
}
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
|
55
|
+
export const toMonthNum = (newDate: Date | string): number => {
|
56
|
+
const date = new Date(newDate)
|
57
|
+
return date.getUTCMonth() +1
|
58
|
+
}
|
58
59
|
|
59
|
-
|
60
|
-
|
61
|
-
|
60
|
+
export const toYear = (newDate: Date | string, timeZone?: string): number => {
|
61
|
+
if (timeZone) {
|
62
|
+
const date = new Date(newDate.toLocaleString(undefined, { timeZone }));
|
63
|
+
return date.getUTCFullYear()
|
64
|
+
} else {
|
65
|
+
const date = new Date(newDate)
|
66
|
+
return date.getUTCFullYear()
|
67
|
+
}
|
68
|
+
}
|
62
69
|
|
63
|
-
|
64
|
-
|
70
|
+
export const toTime = (newDate: Date | string, timeZone?: string): string => {
|
71
|
+
const date = new Date(newDate)
|
72
|
+
if (timeZone) {
|
73
|
+
return date.toLocaleTimeString(undefined, {timeZone, timeStyle: "short"}).split(' ')[0];
|
74
|
+
} else {
|
75
|
+
return date.toLocaleTimeString(undefined, {timeStyle: "short"}).split(' ')[0];
|
65
76
|
}
|
77
|
+
}
|
66
78
|
|
67
|
-
|
68
|
-
|
69
|
-
|
79
|
+
export const toMeridiem = (newDate: Date | string, timeZone?: string): string => {
|
80
|
+
const date = new Date(newDate)
|
81
|
+
if (timeZone) {
|
82
|
+
return date.toLocaleString(undefined, {timeZone, hour12: true }).slice(-2).charAt(0).toLocaleLowerCase();
|
83
|
+
} else {
|
84
|
+
return date.toLocaleString(undefined, {hour12: true }).slice(-2).charAt(0).toLocaleLowerCase();
|
85
|
+
}
|
86
|
+
}
|
70
87
|
|
71
|
-
|
72
|
-
|
73
|
-
|
88
|
+
export const toTimeZone = (newDate: Date | string, timeZone?: string): string => {
|
89
|
+
const date = new Date(newDate)
|
90
|
+
if (timeZone) {
|
91
|
+
return date.toLocaleString(undefined, {timeZone, timeZoneName: "short"}).split(' ')[3];
|
92
|
+
} else {
|
93
|
+
return date.toLocaleString(undefined, {timeZoneName: "short"}).split(' ')[3];
|
94
|
+
}
|
95
|
+
}
|
74
96
|
|
75
|
-
|
76
|
-
|
97
|
+
export const toTimeWithMeridiem = (newDate: Date | string, timeZone: string): string => {
|
98
|
+
const date = new Date(newDate)
|
99
|
+
return `${toTime(date, timeZone)}${toMeridiem(date, timeZone)}`;
|
100
|
+
}
|
77
101
|
|
78
|
-
|
79
|
-
|
80
|
-
return
|
81
|
-
|
102
|
+
export const toIso = (newDate: Date | string): string => {
|
103
|
+
const date = new Date(newDate)
|
104
|
+
return date.toISOString()
|
105
|
+
}
|
82
106
|
|
83
|
-
|
84
|
-
|
85
|
-
|
107
|
+
export const fromNow = (newDate: Date | string): string => {
|
108
|
+
|
109
|
+
const startDate = new Date(newDate).getTime()
|
110
|
+
const endDate = new Date().getTime()
|
111
|
+
const elapsedTime = endDate - startDate
|
112
|
+
let elapsedTimeString = `${Math.round(elapsedTime / (365.25 * 24 * 60 * 60 * 1000))} years ago.`; // 730+ days
|
113
|
+
|
114
|
+
const elapsedTimeData = [
|
115
|
+
{ min: 0, max: 44999, value: "a few seconds ago" }, // 0-44 seconds
|
116
|
+
{ min: 45000, max: 89999, value: "a minute ago" }, // 45-89 seconds
|
117
|
+
{ min: 90000, max: 2649999, value: `${Math.round(elapsedTime / 60000)} minutes ago`}, // 90s-44 minutes
|
118
|
+
{ min: 2650000, max: 7299999, value: "an hour ago" }, // 45-120 minutes
|
119
|
+
{ min: 7300000, max: 75699999, value: `${Math.round(elapsedTime / 3600000)} hours ago`}, // 2-21 hours
|
120
|
+
{ min: 75700000, max: 172899999, value: "a day ago" }, // 22-48 hours
|
121
|
+
{ min: 172900000, max: 2169999999, value: `${Math.round(elapsedTime / 86400000)} days ago`}, // 2-25 days
|
122
|
+
{ min: 2170000000, max: 5184999999, value: "a month ago"}, // 26-60 days
|
123
|
+
{ min: 5185000000, max: 27561699999, value: `${Math.round(elapsedTime / 30.44 * 24 * 60 * 60 * 1000)} months ago`}, // 60-319 days
|
124
|
+
{ min: 27561700000, max: 63072999999, value: "a year ago"}, // 320-730 days
|
125
|
+
];
|
126
|
+
|
127
|
+
for (const timeDate of elapsedTimeData) {
|
128
|
+
if (elapsedTime >= timeDate.min && elapsedTime <= timeDate.max) {
|
129
|
+
elapsedTimeString = timeDate.value;
|
130
|
+
break;
|
131
|
+
}
|
132
|
+
}
|
133
|
+
|
134
|
+
return elapsedTimeString
|
135
|
+
}
|
86
136
|
|
87
|
-
|
88
|
-
|
137
|
+
export const toCustomFormat = (newDate: Date | string, format = 'month_day'): string => {
|
138
|
+
const date = new Date(newDate)
|
139
|
+
if (format == "month_day") {
|
140
|
+
return `${toMonthNum(date)}/${toDay(date)}`
|
141
|
+
} else {
|
142
|
+
return `${date.toLocaleString(undefined, {month: "short"})} ${toDay(date)}`
|
89
143
|
}
|
90
144
|
}
|
145
|
+
|
146
|
+
export default {
|
147
|
+
toMinute,
|
148
|
+
toHour,
|
149
|
+
toDay,
|
150
|
+
toDayAbbr,
|
151
|
+
toWeekday,
|
152
|
+
toMonth,
|
153
|
+
toMonthNum,
|
154
|
+
toYear,
|
155
|
+
toTime,
|
156
|
+
toMeridiem,
|
157
|
+
toTimeZone,
|
158
|
+
toTimeWithMeridiem,
|
159
|
+
toIso,
|
160
|
+
fromNow,
|
161
|
+
toCustomFormat,
|
162
|
+
}
|