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.
- package/dist/cjs/index.js +67 -21
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/components/CopiableBox.d.ts +3 -1
- package/dist/cjs/types/helpers/getPartOfDay.d.ts +6 -0
- package/dist/cjs/types/helpers/stringsToHumanReadableList.d.ts +10 -0
- package/dist/cjs/types/index.d.ts +3 -1
- package/dist/esm/index.js +66 -22
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/components/CopiableBox.d.ts +3 -1
- package/dist/esm/types/helpers/getPartOfDay.d.ts +6 -0
- package/dist/esm/types/helpers/stringsToHumanReadableList.d.ts +10 -0
- package/dist/esm/types/index.d.ts +3 -1
- package/dist/index.d.ts +20 -2
- package/package.json +1 -1
- package/src/components/CopiableBox.tsx +28 -28
- package/src/helpers/getPartOfDay.ts +19 -0
- package/src/helpers/stringsToHumanReadableList.ts +39 -0
- package/src/index.ts +4 -0
|
@@ -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
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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
|
-
|
|
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=
|
|
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
|