dce-reactkit 4.0.0 → 4.0.2-beta-simple-date-chooser.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.
@@ -0,0 +1,196 @@
1
+ /**
2
+ * A very simple, lightweight time chooser
3
+ * @author Gardenia Liu
4
+ */
5
+
6
+ // Import React
7
+ import React from 'react';
8
+
9
+ // Import helpers
10
+ import padZerosLeft from '../helpers/padZerosLeft';
11
+
12
+ /*------------------------------------------------------------------------*/
13
+ /* -------------------------------- Types ------------------------------- */
14
+ /*------------------------------------------------------------------------*/
15
+
16
+ type Props = {
17
+ // Aria label
18
+ ariaLabel: string,
19
+ // Name of the chooser (machine-readable, hyphenated)
20
+ name: string,
21
+ // Currently selected hour of the day (24hr)
22
+ hour: number,
23
+ // Currently selected minute within the hour
24
+ minute: number,
25
+ /**
26
+ * Handler for when time changes
27
+ * @param hour new 24hr hour number
28
+ * @param minute new minute number
29
+ */
30
+ onChange: (hour: number, minute: number) => void,
31
+ // Interval in minutes between each choice
32
+ // Allowed options: 15, 30, 60, defaults to 15
33
+ // If an unsupported interval is passed in, it will default to 15
34
+ intervalMin?: number,
35
+ };
36
+
37
+ /*------------------------------------------------------------------------*/
38
+ /* ------------------------------ Constants ----------------------------- */
39
+ /*------------------------------------------------------------------------*/
40
+
41
+ // Allowed intervals between options
42
+ const ALLOWED_INTERVALS = [15, 30, 60]; // min
43
+
44
+ // Default interval to use if an unsupported interval is passed in
45
+ const DEFAULT_INTERVAL = ALLOWED_INTERVALS[0]; // min
46
+
47
+ /*------------------------------------------------------------------------*/
48
+ /* ------------------------------ Component ----------------------------- */
49
+ /*------------------------------------------------------------------------*/
50
+
51
+ const SimpleTimeChooser: React.FC<Props> = (props) => {
52
+ /*------------------------------------------------------------------------*/
53
+ /* -------------------------------- Setup ------------------------------- */
54
+ /*------------------------------------------------------------------------*/
55
+
56
+ /* -------------- Props ------------- */
57
+
58
+ const {
59
+ ariaLabel,
60
+ name,
61
+ hour,
62
+ minute,
63
+ onChange,
64
+ } = props;
65
+ let {
66
+ intervalMin = DEFAULT_INTERVAL,
67
+ } = props;
68
+
69
+ // Use default interval if not supported
70
+ if (!ALLOWED_INTERVALS.includes(intervalMin)) {
71
+ intervalMin = DEFAULT_INTERVAL;
72
+ }
73
+
74
+ /*------------------------------------------------------------------------*/
75
+ /* ------------------------- Component Functions ------------------------ */
76
+ /*------------------------------------------------------------------------*/
77
+
78
+ /**
79
+ * Convert number of minutes since midnight into 24hour and minute format
80
+ * @author Gabe Abrams
81
+ * @param minSinceMidnight total minutes since midnight
82
+ * @returns hours (24) and minutes
83
+ */
84
+ const convertMinSinceMidnightToHoursAndMin = (minSinceMidnight: number): {
85
+ hours: number,
86
+ minutes: number,
87
+ } => {
88
+ return {
89
+ hours: Math.floor(minSinceMidnight / 60),
90
+ minutes: minSinceMidnight % 60,
91
+ };
92
+ };
93
+
94
+ /**
95
+ * Convert time in minutes into HH:MM format
96
+ * @author Gardenia Liu
97
+ * @param totalMinutes total minutes since midnight
98
+ * @returns formatted time string
99
+ */
100
+ const formatTime = (totalMinutes: number): string => {
101
+ // Handle special cases
102
+ if (totalMinutes === 0) {
103
+ return '12:00 Midnight';
104
+ }
105
+ if (totalMinutes === 12 * 60) {
106
+ return '12:00 Noon';
107
+ }
108
+
109
+ // All normal cases:
110
+ const timeInfo = convertMinSinceMidnightToHoursAndMin(totalMinutes);
111
+ let { hours } = timeInfo;
112
+ const { minutes } = timeInfo;
113
+
114
+ // Process 24hr -> 12hr
115
+ const isAM = (hours < 12);
116
+ if (hours === 0) {
117
+ hours = 12;
118
+ } else if (hours > 12) {
119
+ hours %= 12;
120
+ }
121
+
122
+ // Pad with zeros
123
+ const paddedMinutes = padZerosLeft(minutes, 2);
124
+
125
+ // Assemble time string
126
+ return `${hours}:${paddedMinutes} ${isAM ? 'AM' : 'PM'}`;
127
+ };
128
+
129
+ /*------------------------------------------------------------------------*/
130
+ /* ------------------------------- Render ------------------------------- */
131
+ /*------------------------------------------------------------------------*/
132
+
133
+ /*----------------------------------------*/
134
+ /* --------------- Main UI -------------- */
135
+ /*----------------------------------------*/
136
+
137
+ // Generate list of time options
138
+ const times: string[] = [];
139
+ for (let time = 0; time < 24 * 60; time += intervalMin) {
140
+ times.push(formatTime(time));
141
+ }
142
+
143
+ // Currently selected time in minutes since midnight
144
+ const selectedTimeMin = hour * 60 + minute;
145
+
146
+ // Create choice options
147
+ const timeOptions: React.ReactNode[] = times.map((timeString, timeIndex) => {
148
+ const numMinutesForChoice = timeIndex * intervalMin;
149
+
150
+ // Render the option
151
+ return (
152
+ <option
153
+ key={numMinutesForChoice}
154
+ value={numMinutesForChoice}
155
+ aria-label={`choose ${timeString}`}
156
+ >
157
+ {timeString}
158
+ </option>
159
+ );
160
+ });
161
+
162
+ return (
163
+ <div
164
+ className="SimpleTimeChooser-container"
165
+ aria-label={`time chooser with selected time: ${formatTime(selectedTimeMin)}`}
166
+ >
167
+ {/* Time Chooser */}
168
+ <select
169
+ aria-label={`time for ${ariaLabel}`}
170
+ className="custom-select d-inline-block"
171
+ style={{ width: 'auto' }}
172
+ id={`SimpleTimeChooser-${name}-time`}
173
+ value={selectedTimeMin}
174
+ onChange={(e) => {
175
+ // Parse selector value (string)
176
+ const newTime = Number.parseInt(e.target.value, 10);
177
+
178
+ // Convert minutes since midnight to hour and minute
179
+ const timeInfo = convertMinSinceMidnightToHoursAndMin(newTime);
180
+
181
+ // Notify parent
182
+ onChange(timeInfo.hours, timeInfo.minutes);
183
+ }}
184
+ >
185
+ {timeOptions}
186
+ </select>
187
+ </div>
188
+ );
189
+ };
190
+
191
+ /*------------------------------------------------------------------------*/
192
+ /* ------------------------------- Wrap Up ------------------------------ */
193
+ /*------------------------------------------------------------------------*/
194
+
195
+ // Export component
196
+ export default SimpleTimeChooser;
package/src/index.ts CHANGED
@@ -15,6 +15,7 @@ import RadioButton from './components/RadioButton';
15
15
  import CheckboxButton from './components/CheckboxButton';
16
16
  import ButtonInputGroup from './components/ButtonInputGroup';
17
17
  import SimpleDateChooser from './components/SimpleDateChooser';
18
+ import SimpleTimeChooser from './components/SimpleTimeChooser';
18
19
  import Drawer from './components/Drawer';
19
20
  import PopSuccessMark from './components/PopSuccessMark';
20
21
  import PopFailureMark from './components/PopFailureMark';
@@ -133,6 +134,7 @@ export {
133
134
  CheckboxButton,
134
135
  ButtonInputGroup,
135
136
  SimpleDateChooser,
137
+ SimpleTimeChooser,
136
138
  Drawer,
137
139
  PopSuccessMark,
138
140
  PopFailureMark,
@@ -7,6 +7,6 @@ enum LogSource {
7
7
  Client = 'client',
8
8
  // Server
9
9
  Server = 'server',
10
- };
10
+ }
11
11
 
12
12
  export default LogSource;
@@ -1,4 +1,4 @@
1
- // Highest error code = DRK34
1
+ // Highest error code = DRK36
2
2
 
3
3
  /**
4
4
  * List of error codes built into the react kit
@@ -9,6 +9,8 @@ enum ReactKitErrorCode {
9
9
  NoCode = 'DRK2',
10
10
  SessionExpired = 'DRK3',
11
11
  NoCACCLSendRequestFunction = 'DRK7',
12
+ SimpleDateChooserInvalidDateRange = 'DRK35',
13
+ SimpleDateChooserInvalidNumMonths = 'DRK36',
12
14
  }
13
15
 
14
16
  export default ReactKitErrorCode;