dce-reactkit 3.0.45 → 3.0.48

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.
@@ -19,10 +19,10 @@ import { faClipboard } from '@fortawesome/free-solid-svg-icons';
19
19
 
20
20
  // Props definition
21
21
  type Props = {
22
- // Unique name of the item to copy (no spaces, compatible with css classes)
23
- name: string,
24
22
  // The text to copy
25
23
  text: string,
24
+ // If defined, the text area will have a maximum width
25
+ maxTextWidthRem?: number,
26
26
  // Human-readable label of the copy field
27
27
  label: string,
28
28
  // FontAwesome icon to place before the label
@@ -35,6 +35,10 @@ type Props = {
35
35
  numVisibleLines?: number,
36
36
  // If defined, text box becomes clickable and this is the handler
37
37
  onClick?: () => void,
38
+ // Id of the text area
39
+ textAreaId?: string,
40
+ // Id of the copy button
41
+ copyButtonId?: string,
38
42
  };
39
43
 
40
44
  /*------------------------------------------------------------------------*/
@@ -104,14 +108,16 @@ const CopiableBox: React.FC<Props> = (props) => {
104
108
 
105
109
  // Destructure all props
106
110
  const {
107
- name,
108
111
  text,
112
+ maxTextWidthRem,
109
113
  label,
110
114
  labelIcon,
111
115
  minLabelWidthRem,
112
116
  multiline,
113
117
  numVisibleLines = 10,
114
118
  onClick,
119
+ textAreaId,
120
+ copyButtonId,
115
121
  } = props;
116
122
 
117
123
  /* -------------- State ------------- */
@@ -133,38 +139,19 @@ const CopiableBox: React.FC<Props> = (props) => {
133
139
  /* Component Functions */
134
140
  /*------------------------------------------------------------------------*/
135
141
 
136
- // Determine the id for the copiable text field
137
- const copiableFieldClassName = `CopiableBox-text-box-${name}`;
138
-
139
142
  /**
140
143
  * Perform a copy
141
144
  * @author Gabe Abrams
142
145
  */
143
146
  const performCopy = async () => {
144
147
  // Write to clipboard
145
- let copyFailed = false;
146
148
  try {
147
149
  await navigator.clipboard.writeText(text);
148
150
  } catch (err) {
149
- copyFailed = true;
150
- }
151
-
152
- // Try copy again if it failed
153
- if (copyFailed) {
154
- try {
155
- const input = (
156
- document.getElementsByClassName(copiableFieldClassName)[0]
157
- ) as HTMLInputElement;
158
- input.focus();
159
- input.select();
160
- document.execCommand('copy');
161
- input.blur();
162
- } catch (err) {
163
- return alert(
164
- 'Unable to copy',
165
- 'Oops! We couldn\'t copy that to the clipboard. Please copy the text manually.',
166
- );
167
- }
151
+ return alert(
152
+ 'Unable to copy',
153
+ 'Oops! We couldn\'t copy that to the clipboard. Please copy the text manually.',
154
+ );
168
155
  }
169
156
 
170
157
  // Show copied notice
@@ -216,7 +203,8 @@ const CopiableBox: React.FC<Props> = (props) => {
216
203
  multiline
217
204
  ? (
218
205
  <textarea
219
- className={`${copiableFieldClassName} CopiableBox-text-multiline form-control bg-white text-dark`}
206
+ id={textAreaId}
207
+ className="CopiableBox-text CopiableBox-text-multiline form-control bg-white text-dark"
220
208
  value={text}
221
209
  aria-label={`${label} text`}
222
210
  rows={numVisibleLines}
@@ -232,14 +220,20 @@ const CopiableBox: React.FC<Props> = (props) => {
232
220
  ? 'underline'
233
221
  : undefined
234
222
  ),
223
+ maxWidth: (
224
+ maxTextWidthRem
225
+ ? `${maxTextWidthRem}rem`
226
+ : undefined
227
+ ),
235
228
  }}
236
229
  readOnly
237
230
  />
238
231
  )
239
232
  : (
240
233
  <input
234
+ id={textAreaId}
241
235
  type="text"
242
- className={`${copiableFieldClassName} CopiableBox-text-single-line form-control bg-white text-dark`}
236
+ className="CopiableBox-text CopiableBox-text-single-line form-control bg-white text-dark"
243
237
  value={text}
244
238
  aria-label={`${label} text`}
245
239
  onClick={onClick}
@@ -254,6 +248,11 @@ const CopiableBox: React.FC<Props> = (props) => {
254
248
  ? 'underline'
255
249
  : undefined
256
250
  ),
251
+ maxWidth: (
252
+ maxTextWidthRem
253
+ ? `${maxTextWidthRem}rem`
254
+ : undefined
255
+ ),
257
256
  }}
258
257
  readOnly
259
258
  />
@@ -261,6 +260,7 @@ const CopiableBox: React.FC<Props> = (props) => {
261
260
  }
262
261
 
263
262
  <button
263
+ id={copyButtonId}
264
264
  className="btn btn-secondary"
265
265
  type="button"
266
266
  aria-label={`copy ${label} to the clipboard`}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Get the current part of day (morning, evening, etc.)
3
+ * @author Gabe Abrams
4
+ */
5
+ const getPartOfDay = () => {
6
+ // Setup the post-it time of day
7
+ let partOfDay = 'day';
8
+ let hours = new Date().getHours();
9
+ if (hours < 12) {
10
+ partOfDay = 'morning';
11
+ } else if (hours >= 12 && hours <= 16) {
12
+ partOfDay = 'afternoon';
13
+ } else if (hours > 16 && hours <= 24) {
14
+ partOfDay = 'evening';
15
+ }
16
+ return partOfDay;
17
+ };
18
+
19
+ export default getPartOfDay;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Create a human readable list from an array of strings.
3
+ * For example, ['apple', 'orange'] becomes "apple and orange"
4
+ * and ['apple', 'orange', 'mango'] becomes "apple, orange, and mango"
5
+ * @author Gabe Abrams
6
+ * @param items list of items in the list
7
+ * @returns human-readable list
8
+ */
9
+ const stringsToHumanReadableList = (items: string[]): string => {
10
+ // Handle 0-item case
11
+ if (items.length === 0) {
12
+ return '';
13
+ }
14
+
15
+ // Handle 1-item case
16
+ if (items.length === 1) {
17
+ return items[0];
18
+ }
19
+
20
+ // Handle 2-item case
21
+ if (items.length === 2) {
22
+ return `${items[0]} and ${items[1]}`;
23
+ }
24
+
25
+ // Handle 3+ item case
26
+ let list = '';
27
+ items.forEach((item, i) => {
28
+ if (i === items.length - 1) {
29
+ // Last item
30
+ list += `, and ${item}`;
31
+ }
32
+
33
+ // Previous items
34
+ list += `, ${item}`;
35
+ });
36
+ return list;
37
+ };
38
+
39
+ export default stringsToHumanReadableList;
package/src/index.ts CHANGED
@@ -43,6 +43,8 @@ import getTimeInfoInET from './helpers/getTimeInfoInET';
43
43
  import stubServerEndpoint from './helpers/stubServerEndpoint';
44
44
  import startMinWait from './helpers/startMinWait';
45
45
  import getHumanReadableDate from './helpers/getHumanReadableDate';
46
+ import getPartOfDay from './helpers/getPartOfDay';
47
+ import stringsToHumanReadableList from './helpers/stringsToHumanReadableList';
46
48
 
47
49
  // Import types
48
50
  import ModalButtonType from './types/ModalButtonType';
@@ -95,6 +97,8 @@ export {
95
97
  stubServerEndpoint,
96
98
  startMinWait,
97
99
  getHumanReadableDate,
100
+ getPartOfDay,
101
+ stringsToHumanReadableList,
98
102
  // Client helpers
99
103
  visitServerEndpoint,
100
104
  // Server helpers