playbook_ui 12.27.0 → 12.28.0.pre.alpha.PLAY814removemomentjs871

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_date/_date.tsx +7 -8
  3. data/app/pb_kits/playbook/pb_date_range_inline/_date_range_inline.tsx +45 -31
  4. data/app/pb_kits/playbook/pb_date_range_stacked/_date_range_stacked.tsx +5 -3
  5. data/app/pb_kits/playbook/pb_date_stacked/_date_stacked.tsx +24 -21
  6. data/app/pb_kits/playbook/pb_date_time/_date_time.tsx +1 -1
  7. data/app/pb_kits/playbook/pb_date_time/dateTime.test.js +1 -1
  8. data/app/pb_kits/playbook/pb_date_time_stacked/_date_time_stacked.tsx +2 -2
  9. data/app/pb_kits/playbook/pb_date_time_stacked/date_time_stacked.test.js +1 -1
  10. data/app/pb_kits/playbook/pb_date_year_stacked/_date_year_stacked.tsx +6 -8
  11. data/app/pb_kits/playbook/pb_kit/dateTime.ts +139 -67
  12. data/app/pb_kits/playbook/pb_label_value/_label_value.tsx +52 -31
  13. data/app/pb_kits/playbook/pb_message/_message.tsx +25 -25
  14. data/app/pb_kits/playbook/pb_multi_level_select/_multi_level_select.tsx +28 -3
  15. data/app/pb_kits/playbook/pb_multi_level_select/docs/_multi_level_select_default.jsx +1 -0
  16. data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +26 -5
  17. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_access_input_element.jsx +26 -0
  18. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_access_input_element.md +3 -0
  19. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_clear_field.jsx +30 -0
  20. data/app/pb_kits/playbook/pb_phone_number_input/docs/_phone_number_input_clear_field.md +3 -0
  21. data/app/pb_kits/playbook/pb_phone_number_input/docs/example.yml +2 -0
  22. data/app/pb_kits/playbook/pb_phone_number_input/docs/index.js +2 -0
  23. data/app/pb_kits/playbook/pb_selectable_card_icon/docs/_selectable_card_icon_custom.html.erb +11 -0
  24. data/app/pb_kits/playbook/pb_selectable_card_icon/docs/_selectable_card_icon_custom.jsx +36 -0
  25. data/app/pb_kits/playbook/pb_selectable_card_icon/docs/_selectable_card_icon_custom.md +19 -0
  26. data/app/pb_kits/playbook/pb_selectable_card_icon/docs/example.yml +2 -2
  27. data/app/pb_kits/playbook/pb_selectable_card_icon/docs/index.js +1 -0
  28. data/app/pb_kits/playbook/pb_selectable_card_icon/selectable_card_icon.html.erb +2 -0
  29. data/app/pb_kits/playbook/pb_selectable_card_icon/selectable_card_icon.rb +2 -0
  30. data/app/pb_kits/playbook/pb_selectable_icon/selectable_icon.html.erb +1 -1
  31. data/app/pb_kits/playbook/pb_selectable_icon/selectable_icon.rb +2 -0
  32. data/app/pb_kits/playbook/pb_time/_time.tsx +9 -11
  33. data/app/pb_kits/playbook/pb_time_range_inline/_time_range_inline.tsx +46 -49
  34. data/app/pb_kits/playbook/pb_time_stacked/_time_stacked.tsx +4 -6
  35. data/app/pb_kits/playbook/pb_timestamp/_timestamp.tsx +10 -10
  36. data/app/pb_kits/playbook/pb_weekday_stacked/_weekday_stacked.tsx +8 -11
  37. data/dist/playbook-rails.js +6 -6
  38. data/lib/playbook/version.rb +2 -2
  39. metadata +14 -8
  40. data/app/pb_kits/playbook/pb_logistic/_logistic.jsx +0 -120
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c8a90666ee111265053efa8a6306dcf5312bd5db5b1f9ed04f9f308efc4b800c
4
- data.tar.gz: 5ff43b2f9c0b59121483cb30cfd1fcd24ba8fa02c65381000fb86b8ef5097fa9
3
+ metadata.gz: 6bff4ae5eea63203df312bfe5084059ccbf7c03b00e21191e8febfdadef69e40
4
+ data.tar.gz: 4b2d45e698f7101b05145fe30247ceb58c007e91e9e8d239ce2ee81c9715bc99
5
5
  SHA512:
6
- metadata.gz: 23a90f57292ebf633ef4d2305b4ca7c038abd1bfa8a0a2e8729c5c279522c265b76ca3e8f616076d5483990467baeaec22999d70dec6cb015f9064a64cba7e6a
7
- data.tar.gz: ca7a82f0e5d3c9de8df3cef5c4913f1dbbd8890b0b29ebfd563f6cb02d5125c664a0a221cb676eb56a68e1f4be7ce26bd1507c0bf7893530a916ccf8e720891d
6
+ metadata.gz: '082571f8a9154aae27eea5c8087db5c24d1b9439cdbe8f699a5a9c8fdf72ea8d9ed8840595d4160500586ccbe73a6720ef3d221a464e971f825fff22b78abcc9'
7
+ data.tar.gz: 861ab41ccc20069e20fba759b72f8ea0d04cef37aa843ffa8ec4df6725b07a5a76ed10f90120dd3e90e1074cd86b53fa0c196a50a507b8aaa5f18885e79d6ea6
@@ -1,9 +1,9 @@
1
1
  import React from "react";
2
2
  import classnames from "classnames";
3
3
 
4
- import DateTime from "../pb_kit/dateTime";
5
4
  import { buildAriaProps, buildCss, buildDataProps } from "../utilities/props";
6
5
  import { globalProps } from "../utilities/globalProps";
6
+ import DateTime from '../pb_kit/dateTime';
7
7
 
8
8
  import Body from "../pb_body/_body";
9
9
  import Caption from "../pb_caption/_caption";
@@ -20,7 +20,7 @@ type PbDateProps = {
20
20
  showIcon?: boolean;
21
21
  size?: "sm" | "md" | "lg";
22
22
  unstyled?: boolean;
23
- value: string | Date;
23
+ value: Date;
24
24
  };
25
25
 
26
26
  const PbDate = (props: PbDateProps) => {
@@ -37,12 +37,11 @@ const PbDate = (props: PbDateProps) => {
37
37
  value,
38
38
  } = props;
39
39
 
40
- const dateTimestamp = new DateTime({ value: value });
41
- const weekday = dateTimestamp.toWeekday();
42
- const month = dateTimestamp.toMonth();
43
- const day = dateTimestamp.toDay();
44
- const year = dateTimestamp.toYear();
45
- const currentYear = new Date().getFullYear().toString();
40
+ const weekday = DateTime.toWeekday(value);
41
+ const month = DateTime.toMonth(value);
42
+ const day = DateTime.toDay(value);
43
+ const year = DateTime.toYear(value);
44
+ const currentYear = new Date().getFullYear();
46
45
 
47
46
  const ariaProps = buildAriaProps(aria);
48
47
  const dataProps = buildDataProps(data);
@@ -3,7 +3,7 @@ import classnames from "classnames";
3
3
 
4
4
  import { globalProps } from "../utilities/globalProps";
5
5
  import { buildCss, buildDataProps } from "../utilities/props";
6
- import DateTime from "../pb_kit/dateTime";
6
+ import DateTime from '../pb_kit/dateTime';
7
7
 
8
8
  import Body from "../pb_body/_body";
9
9
  import Caption from "../pb_caption/_caption";
@@ -21,18 +21,16 @@ type DateRangeInlineProps = {
21
21
  endDate?: Date;
22
22
  };
23
23
 
24
- const dateTimestamp = (dateValue: Date | string, includeYear: boolean) => {
25
- const date = new DateTime({ value: dateValue });
24
+ const dateTimestamp = (dateValue: Date, includeYear: boolean) => {
26
25
  if (includeYear) {
27
- return `${date.toMonth()} ${date.toDay()}, ${date.toYear()}`;
26
+ return `${DateTime.toMonth(dateValue)} ${DateTime.toDay(dateValue)}, ${DateTime.toYear(dateValue)}`;
28
27
  } else {
29
- return `${date.toMonth()} ${date.toDay()}`;
28
+ return `${DateTime.toMonth(dateValue)} ${DateTime.toDay(dateValue)}`;
30
29
  }
31
30
  };
32
31
 
33
- const dateTimeIso = (dateValue: Date | string) => {
34
- const date = new DateTime({ value: dateValue });
35
- return date.toIso();
32
+ const dateTimeIso = (dateValue: Date) => {
33
+ return DateTime.toIso(dateValue);
36
34
  };
37
35
 
38
36
  const DateRangeInline = (props: DateRangeInlineProps) => {
@@ -52,14 +50,17 @@ const DateRangeInline = (props: DateRangeInlineProps) => {
52
50
  <>
53
51
  {icon && (
54
52
  <>
55
- <Body color="light" key={Math.random()} tag="span">
56
- <Icon
57
- className="pb_date_range_inline_icon"
58
- dark={dark}
59
- fixedWidth
60
- icon="calendar-alt"
61
- size={size}
53
+ <Body color="light"
54
+ key={Math.random()}
62
55
  tag="span"
56
+ >
57
+ <Icon
58
+ className="pb_date_range_inline_icon"
59
+ dark={dark}
60
+ fixedWidth
61
+ icon="calendar-alt"
62
+ size={size}
63
+ tag="span"
63
64
  />
64
65
  </Body>
65
66
  </>
@@ -78,7 +79,7 @@ const DateRangeInline = (props: DateRangeInlineProps) => {
78
79
 
79
80
  const dateRangeClasses = buildCss("pb_date_range_inline_kit", align);
80
81
  const dataProps = buildDataProps(data)
81
- const renderTime = (date: Date | string) => {
82
+ const renderTime = (date: Date) => {
82
83
  return (
83
84
  <time dateTime={dateTimeIso(date)}>
84
85
  {dateInCurrentYear() ? (
@@ -92,24 +93,30 @@ const DateRangeInline = (props: DateRangeInlineProps) => {
92
93
 
93
94
  return (
94
95
  <div
95
- {...dataProps}
96
- className={classnames(dateRangeClasses, globalProps(props), className)}
96
+ {...dataProps}
97
+ className={classnames(dateRangeClasses, globalProps(props), className)}
97
98
  >
98
99
  <div className="pb_date_range_inline_wrapper">
99
100
  {size == "xs" && (
100
101
  <>
101
102
  {iconContent()}
102
- <Caption dark={dark} tag="span">
103
+ <Caption dark={dark}
104
+ tag="span"
105
+ >
103
106
  {renderTime(startDate)}
104
107
  </Caption>
105
- <Caption dark={dark} tag="span">
108
+ <Caption dark={dark}
109
+ tag="span"
110
+ >
106
111
  <Icon
107
- className="pb_date_range_inline_arrow"
108
- fixedWidth
109
- icon="long-arrow-right"
112
+ className="pb_date_range_inline_arrow"
113
+ fixedWidth
114
+ icon="long-arrow-right"
110
115
  />
111
116
  </Caption>
112
- <Caption dark={dark} tag="span">
117
+ <Caption dark={dark}
118
+ tag="span"
119
+ >
113
120
  {renderTime(endDate)}
114
121
  </Caption>
115
122
  </>
@@ -118,18 +125,25 @@ const DateRangeInline = (props: DateRangeInlineProps) => {
118
125
  {size == "sm" && (
119
126
  <>
120
127
  {iconContent()}
121
- <Body dark={dark} tag="span">
128
+ <Body dark={dark}
129
+ tag="span"
130
+ >
122
131
  {renderTime(startDate)}
123
132
  </Body>
124
- <Body color="light" dark={dark} tag="span">
125
- <Icon
126
- className="pb_date_range_inline_arrow"
133
+ <Body color="light"
127
134
  dark={dark}
128
- fixedWidth
129
- icon="long-arrow-right"
135
+ tag="span"
136
+ >
137
+ <Icon
138
+ className="pb_date_range_inline_arrow"
139
+ dark={dark}
140
+ fixedWidth
141
+ icon="long-arrow-right"
130
142
  />
131
143
  </Body>
132
- <Body dark={dark} tag="span">
144
+ <Body dark={dark}
145
+ tag="span"
146
+ >
133
147
  {renderTime(endDate)}
134
148
  </Body>
135
149
  </>
@@ -14,9 +14,9 @@ type DateRangeStackedProps = {
14
14
  className?: string | string[],
15
15
  data?: string,
16
16
  dark?: boolean,
17
- endDate: string,
17
+ endDate: Date,
18
18
  id?: string,
19
- startDate: string,
19
+ startDate: Date,
20
20
  }
21
21
 
22
22
  const DateRangeStacked = (props: DateRangeStackedProps) => {
@@ -29,7 +29,9 @@ const DateRangeStacked = (props: DateRangeStackedProps) => {
29
29
  const dataProps = buildDataProps(data)
30
30
 
31
31
  return (
32
- <div {...dataProps} className={css}>
32
+ <div {...dataProps}
33
+ className={css}
34
+ >
33
35
  <Flex vertical="center">
34
36
  <FlexItem>
35
37
  <DateYearStacked
@@ -1,9 +1,9 @@
1
1
  import React from "react";
2
2
 
3
3
  import classnames from "classnames";
4
- import DateTime from "../pb_kit/dateTime";
5
4
  import { buildCss, buildDataProps } from "../utilities/props";
6
5
  import { globalProps } from "../utilities/globalProps";
6
+ import DateTime from '../pb_kit/dateTime';
7
7
 
8
8
  import Caption from "../pb_caption/_caption";
9
9
  import Title from "../pb_title/_title";
@@ -14,7 +14,7 @@ type DateStackedProps = {
14
14
  className?: string | string[];
15
15
  dark?: boolean;
16
16
  data?: string;
17
- date: string | Date;
17
+ date: Date;
18
18
  size?: "sm" | "md";
19
19
  id?: string;
20
20
  reverse?: boolean;
@@ -45,39 +45,42 @@ const DateStacked = (props: DateStackedProps) => {
45
45
  className
46
46
  );
47
47
 
48
- const currentYear = new Date().getFullYear().toString();
49
- const dateTimestamp = new DateTime({ value: date });
50
- const inputYear = dateTimestamp.toYear().toString();
48
+ const currentYear = new Date().getFullYear()
49
+ const inputYear = DateTime.toYear(date);
51
50
  const dataProps = buildDataProps(data)
52
51
 
53
52
  return (
54
53
  <>
55
54
  {bold == false ? (
56
- <div {...dataProps} className={classes}>
55
+ <div {...dataProps}
56
+ className={classes}
57
+ >
57
58
  <div className="pb_date_stacked_day_month">
58
- <Caption text={dateTimestamp.toMonth().toUpperCase()} />
59
+ <Caption text={DateTime.toMonth(date).toUpperCase()} />
59
60
  <Title
60
- dark={dark}
61
- size={sizes[size]}
62
- text={dateTimestamp.toDay()}
61
+ dark={dark}
62
+ size={sizes[size]}
63
+ text={DateTime.toDay(date).toString()}
63
64
  />
64
65
  </div>
65
66
  {currentYear != inputYear && <Caption size="xs">{inputYear}</Caption>}
66
67
  </div>
67
68
  ) : (
68
- <div {...dataProps} className={classes}>
69
+ <div {...dataProps}
70
+ className={classes}
71
+ >
69
72
  <div className="pb_date_stacked_day_month">
70
- <Title
71
- bold
72
- dark={dark}
73
- size="4"
74
- text={dateTimestamp.toMonth()}
73
+ <Title
74
+ bold
75
+ dark={dark}
76
+ size="4"
77
+ text={DateTime.toMonth(date)}
75
78
  />
76
- <Title
77
- bold
78
- dark={dark}
79
- size="4"
80
- text={dateTimestamp.toDay()}
79
+ <Title
80
+ bold
81
+ dark={dark}
82
+ size="4"
83
+ text={DateTime.toDay(date).toString()}
81
84
  />
82
85
  {currentYear != inputYear && <Title size="4">{inputYear}</Title>}
83
86
  </div>
@@ -13,7 +13,7 @@ type DateTimeProps = {
13
13
  aria?: { [key: string]: string; },
14
14
  className?: string,
15
15
  data?: { [key: string]: string; },
16
- datetime: string,
16
+ datetime: Date,
17
17
  id?: string,
18
18
  size?: "sm" | "md",
19
19
  showDayOfWeek: boolean,
@@ -89,7 +89,7 @@ describe('DateTime Kit', () => {
89
89
  const kit = screen.getByTestId(testId)
90
90
  const text = kit.querySelector('.pb_time_kit_md.ml_sm')
91
91
 
92
- expect(text.textContent).toEqual('2:00p JST')
92
+ expect(text.textContent).toEqual('2:00p GMT+9')
93
93
  })
94
94
  test('renders DatePicker size', () => {
95
95
  render(
@@ -12,8 +12,8 @@ import DateStacked from '../pb_date_stacked/_date_stacked'
12
12
 
13
13
  type DateTimeStackedProps = {
14
14
  id?: string,
15
- date: string,
16
- datetime: string,
15
+ date: Date,
16
+ datetime: Date,
17
17
  dark: boolean,
18
18
  timeZone?: string,
19
19
  }
@@ -34,7 +34,7 @@ test('renders time in default timezone', () => {
34
34
  test('renders time in timezone', () => {
35
35
  props.timeZone = 'Asia/Tokyo'
36
36
  const kit = renderKit(DateTimeStacked, props)
37
- expect(kit).toHaveTextContent(`${monthDayYear}2:00aJST`)
37
+ expect(kit).toHaveTextContent(`${monthDayYear}2:00aGMT+9`)
38
38
  })
39
39
 
40
40
  test('renders time in timezone', () => {
@@ -1,9 +1,9 @@
1
1
  import React from 'react'
2
2
  import classnames from 'classnames'
3
3
 
4
- import DateTime from '../pb_kit/dateTime'
5
4
  import { buildCss, buildDataProps } from '../utilities/props'
6
5
  import { globalProps } from '../utilities/globalProps'
6
+ import DateTime from '../pb_kit/dateTime';
7
7
 
8
8
  import Body from '../pb_body/_body'
9
9
  import Title from '../pb_title/_title'
@@ -13,13 +13,12 @@ type DateYearStackedProps = {
13
13
  className?: string | string[],
14
14
  dark?: boolean,
15
15
  data?: string,
16
- date: string,
16
+ date: Date,
17
17
  id?: string,
18
18
  }
19
19
 
20
20
  const DateYearStacked = (props: DateYearStackedProps) => {
21
21
  const { align = 'left', className, dark = false, date, data={} } = props
22
- const dateTimestamp = new DateTime({ value: date })
23
22
  const css = classnames(
24
23
  buildCss('pb_date_year_stacked', align),
25
24
  globalProps(props),
@@ -29,15 +28,14 @@ const DateYearStacked = (props: DateYearStackedProps) => {
29
28
 
30
29
  return (
31
30
  <div {...dataProps}
32
- className={css}>
31
+ className={css}
32
+ >
33
33
  <Title
34
34
  dark={dark}
35
35
  size={4}
36
- text={`${dateTimestamp.toDay()} ${dateTimestamp
37
- .toMonth()
38
- .toUpperCase()}`}
36
+ text={`${DateTime.toDay(date)} ${DateTime.toMonth(date).toUpperCase()}`}
39
37
  />
40
- <Body color="light">{dateTimestamp.toYear()}</Body>
38
+ <Body color="light">{DateTime.toYear(date)}</Body>
41
39
  </div>
42
40
  )
43
41
  }
@@ -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
- export default class DateTime {
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
- toCustomFormat(format = '%-m/%-d') {
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
- toYear() {
32
- return this.value.strftime('%Y')
7
+ export const toMinute = (newDate: Date, 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
- toMonth() {
36
- return this.value.strftime('%b')
16
+ export const toHour = (newDate: Date, 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
- toMonthNum() {
40
- return this.value.strftime('%-m')
41
- }
25
+ export const toDay = (newDate: Date, timeZone?: string): number => {
26
+ if (timeZone) {
27
+ const date = new Date(newDate.toLocaleString(undefined, { timeZone }));
28
+ return date.getUTCDate()
29
+ } else {
30
+ const date = new Date(newDate)
31
+ return date.getUTCDate()
32
+ }
33
+ }
42
34
 
43
- toMonthFull() {
44
- return this.value.strftime('%B')
45
- }
35
+ export const toDayAbbr = (newDate: Date): string => {
36
+ const date = new Date(newDate)
37
+ return ABBR_DAYS[date.getUTCDay()]
38
+ }
46
39
 
47
- toDay() {
48
- return this.value.strftime('%e')
49
- }
40
+ export const toWeekday = (newDate: Date): string => {
41
+ const date = new Date(newDate)
42
+ return days[date.getUTCDay()]
43
+ }
50
44
 
51
- toDayAbbr() {
52
- return ABBR_DAYS[this.value.day()]
53
- }
45
+ export const toMonth = (newDate: Date, 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
- toWeekday() {
56
- return this.value.strftime('%a')
57
- }
55
+ export const toMonthNum = (newDate: Date): number => {
56
+ const date = new Date(newDate)
57
+ return date.getUTCMonth() +1
58
+ }
58
59
 
59
- toHour() {
60
- return this.value.strftime('%l')
61
- }
60
+ export const toYear = (newDate: Date, 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
- toMinute() {
64
- return this.value.strftime('%M')
70
+ export const toTime = (newDate: Date, 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
- toMeridian() {
68
- return this.value.strftime('%P')[0]
69
- }
79
+ export const toMeridiem = (newDate: Date, 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
- toIso() {
72
- return this.value.toISOString()
73
- }
88
+ export const toTimeZone = (newDate: Date, 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
- toTime() {
76
- const time = this.value.strftime('%I:%M')
97
+ export const toTimeWithMeridiem = (newDate: Date, timeZone: string): string => {
98
+ const date = new Date(newDate)
99
+ return `${toTime(date, timeZone)}${toMeridiem(date, timeZone)}`;
100
+ }
77
101
 
78
- // strftime adds a leading 0 on single hour times. ie 08:31.
79
- // this removes that 0 to match the rails kit.
80
- return time.charAt() === '0' ? time.slice(1) : time
81
- }
102
+ export const toIso = (newDate: Date): string => {
103
+ const date = new Date(newDate)
104
+ return date.toISOString()
105
+ }
82
106
 
83
- toTimezone() {
84
- return this.value.strftime('%Z')
85
- }
107
+ export const fromNow = (newDate: Date): 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
- toTimeWithMeridian() {
88
- return this.toTime() + this.toMeridian()
137
+ export const toCustomFormat = (newDate: Date, 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
+ }