dce-reactkit 3.0.0-beta.31 → 3.0.0-beta.34

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/index.d.ts CHANGED
@@ -7,7 +7,7 @@ import React from 'react';
7
7
  * @author Gabe Abrams
8
8
  */
9
9
 
10
- declare type Props$3 = {
10
+ declare type Props$4 = {
11
11
  children: React.ReactNode;
12
12
  sendRequest: SendRequestFunction;
13
13
  dark?: boolean;
@@ -52,7 +52,7 @@ declare const confirm: (title: string, text: string) => Promise<boolean>;
52
52
  * @param [errorTitle] title of the error box
53
53
  */
54
54
  declare const showFatalError: (error: any, errorTitle?: string) => undefined;
55
- declare const AppWrapper: React.FC<Props$3>;
55
+ declare const AppWrapper: React.FC<Props$4>;
56
56
 
57
57
  /**
58
58
  * Loading spinner/indicator
@@ -65,12 +65,12 @@ declare const LoadingSpinner: () => JSX.Element;
65
65
  * @author Gabe Abrams
66
66
  */
67
67
 
68
- declare type Props$2 = {
68
+ declare type Props$3 = {
69
69
  error: any;
70
70
  title?: string;
71
71
  onClose?: () => void;
72
72
  };
73
- declare const ErrorBox: React.FC<Props$2>;
73
+ declare const ErrorBox: React.FC<Props$3>;
74
74
 
75
75
  /**
76
76
  * Bootstrap variants
@@ -136,7 +136,7 @@ declare enum ModalType {
136
136
  * @author Gabe Abrams
137
137
  */
138
138
 
139
- declare type Props$1 = {
139
+ declare type Props$2 = {
140
140
  type?: ModalType;
141
141
  size?: ModalSize;
142
142
  title?: React.ReactNode;
@@ -165,19 +165,38 @@ declare type Props$1 = {
165
165
  confirmVariant?: Variant;
166
166
  onTopOfOtherModals?: boolean;
167
167
  };
168
- declare const Modal: React.FC<Props$1>;
168
+ declare const Modal: React.FC<Props$2>;
169
169
 
170
170
  /**
171
171
  * A box with a tab on the top that holds buttons and other content
172
172
  * @author Gabe Abrams
173
173
  */
174
174
 
175
- declare type Props = {
175
+ declare type Props$1 = {
176
176
  title: React.ReactNode;
177
177
  children: React.ReactNode;
178
178
  noBottomPadding?: boolean;
179
179
  };
180
- declare const TabBox: React.FC<Props>;
180
+ declare const TabBox: React.FC<Props$1>;
181
+
182
+ /**
183
+ * A radio selection button
184
+ * @author Gabe Abrams
185
+ */
186
+
187
+ declare type Props = {
188
+ text: string;
189
+ onSelected: () => void;
190
+ ariaLabel: string;
191
+ title?: string;
192
+ selected?: boolean;
193
+ id?: string;
194
+ noMarginOnRight?: boolean;
195
+ selectedVariant?: Variant;
196
+ unselectedVariant?: Variant;
197
+ small?: boolean;
198
+ };
199
+ declare const RadioButton: React.FC<Props>;
181
200
 
182
201
  /**
183
202
  * An error with a code
@@ -393,4 +412,4 @@ declare enum ReactKitErrorCode {
393
412
  NoCACCLGetLaunchInfoFunction = "DRK8"
394
413
  }
395
414
 
396
- export { AppWrapper, ErrorBox, ErrorWithCode, LoadingSpinner, Modal, ModalButtonType, ModalSize, ModalType, ParamType, ReactKitErrorCode, TabBox, Variant, abbreviate, alert, avg, ceilToNumDecimals, confirm, floorToNumDecimals, forceNumIntoBounds, genRouteHandler, handleError, handleSuccess, initServer, padDecimalZeros, padZerosLeft, roundToNumDecimals, showFatalError, sum, visitServerEndpoint, waitMs };
415
+ export { AppWrapper, ErrorBox, ErrorWithCode, LoadingSpinner, Modal, ModalButtonType, ModalSize, ModalType, ParamType, RadioButton, ReactKitErrorCode, TabBox, Variant, abbreviate, alert, avg, ceilToNumDecimals, confirm, floorToNumDecimals, forceNumIntoBounds, genRouteHandler, handleError, handleSuccess, initServer, padDecimalZeros, padZerosLeft, roundToNumDecimals, showFatalError, sum, visitServerEndpoint, waitMs };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dce-reactkit",
3
- "version": "3.0.0-beta.31",
3
+ "version": "3.0.0-beta.34",
4
4
  "description": "Shared components for Harvard DCE apps",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -19,6 +19,7 @@
19
19
  },
20
20
  "homepage": "https://github.com/harvard-edtech/dce-reactkit#readme",
21
21
  "peerDependencies": {
22
+ "@fortawesome/free-regular-svg-icons": "^6.1.1",
22
23
  "@fortawesome/free-solid-svg-icons": "^6.1.1",
23
24
  "@fortawesome/react-fontawesome": "^0.1.18",
24
25
  "bootstrap": "^5.1.3",
@@ -314,10 +314,12 @@ const AppWrapper: React.FC<Props> = (props: Props): React.ReactElement => {
314
314
  if (alertInfo) {
315
315
  modal = (
316
316
  <Modal
317
+ key={`alert-${alertInfo.title}-${alertInfo.text}`}
317
318
  title={alertInfo.title}
318
319
  type={ModalType.Okay}
319
320
  onClose={() => {
320
321
  // Alert closed
322
+ setAlertInfo(undefined);
321
323
  if (onAlertClosed) {
322
324
  onAlertClosed();
323
325
  }
@@ -334,13 +336,14 @@ const AppWrapper: React.FC<Props> = (props: Props): React.ReactElement => {
334
336
  if (confirmInfo) {
335
337
  modal = (
336
338
  <Modal
339
+ key={`confirm-${confirmInfo.title}-${confirmInfo.text}`}
337
340
  title={confirmInfo.title}
338
341
  type={ModalType.OkayCancel}
339
342
  onClose={(buttonType) => {
343
+ setConfirmInfo(undefined);
340
344
  if (onConfirmClosed) {
341
345
  onConfirmClosed(buttonType === ModalButtonType.Okay);
342
346
  }
343
- setConfirmInfo(undefined);
344
347
  }}
345
348
  dontAllowBackdropExit
346
349
  >
@@ -406,6 +406,7 @@ const Modal: React.FC<Props> = (props) => {
406
406
  // Create the button
407
407
  return (
408
408
  <button
409
+ key={ModalButtonType}
409
410
  type="button"
410
411
  className={`Modal-${ModalButtonType}-button btn btn-${variant} ${last ? '' : 'me-1'}`}
411
412
  onClick={() => {
@@ -0,0 +1,102 @@
1
+ /**
2
+ * A radio selection button
3
+ * @author Gabe Abrams
4
+ */
5
+
6
+ // Import React
7
+ import React from 'react';
8
+
9
+ // Import FontAwesome Icons
10
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
11
+ import { faDotCircle } from '@fortawesome/free-solid-svg-icons';
12
+ import { faCircle } from '@fortawesome/free-regular-svg-icons';
13
+
14
+ // Import shared types
15
+ import Variant from '../types/Variant';
16
+
17
+ /*------------------------------------------------------------------------*/
18
+ /* Types */
19
+ /*------------------------------------------------------------------------*/
20
+
21
+ type Props = {
22
+ // Text of the button
23
+ text: string,
24
+ // Handler for when this item is selected (not called if already selected)
25
+ onSelected: () => void,
26
+ // Aria label
27
+ ariaLabel: string,
28
+ // Button title
29
+ title?: string,
30
+ // True if selected
31
+ selected?: boolean,
32
+ // The id of the button
33
+ id?: string,
34
+ // If true, no margin on right
35
+ noMarginOnRight?: boolean,
36
+ // Variant for when radio is selected
37
+ selectedVariant?: Variant,
38
+ // Variant for when radio is not selected
39
+ unselectedVariant?: Variant,
40
+ // True if using a small button
41
+ small?: boolean,
42
+ };
43
+
44
+ /*------------------------------------------------------------------------*/
45
+ /* Component */
46
+ /*------------------------------------------------------------------------*/
47
+
48
+ const RadioButton: React.FC<Props> = (props) => {
49
+ /*------------------------------------------------------------------------*/
50
+ /* Setup */
51
+ /*------------------------------------------------------------------------*/
52
+
53
+ /* -------------- Props ------------- */
54
+
55
+ const {
56
+ text,
57
+ onSelected,
58
+ ariaLabel,
59
+ title,
60
+ selected,
61
+ id,
62
+ noMarginOnRight,
63
+ selectedVariant = Variant.Primary,
64
+ unselectedVariant = Variant.Light,
65
+ small,
66
+ } = props;
67
+
68
+ /*------------------------------------------------------------------------*/
69
+ /* Render */
70
+ /*------------------------------------------------------------------------*/
71
+
72
+ /*----------------------------------------*/
73
+ /* Main UI */
74
+ /*----------------------------------------*/
75
+
76
+ return (
77
+ <button
78
+ type="button"
79
+ id={id}
80
+ title={title}
81
+ className={`btn btn-${selected ? selectedVariant : unselectedVariant}${selected ? ' selected' : ''}${small ? ' btn-sm' : ''} m-0${noMarginOnRight ? '' : ' mr-2'}`}
82
+ aria-label={`${ariaLabel}${selected ? ': currently selected' : ''}`}
83
+ onClick={() => {
84
+ if (!selected) {
85
+ onSelected();
86
+ }
87
+ }}
88
+ >
89
+ <FontAwesomeIcon
90
+ icon={selected ? faDotCircle : faCircle}
91
+ className="mr-1"
92
+ />
93
+ {text}
94
+ </button>
95
+ );
96
+ };
97
+
98
+ /*------------------------------------------------------------------------*/
99
+ /* Wrap up */
100
+ /*------------------------------------------------------------------------*/
101
+
102
+ export default RadioButton;
package/src/index.ts CHANGED
@@ -4,6 +4,7 @@ import LoadingSpinner from './components/LoadingSpinner';
4
4
  import ErrorBox from './components/ErrorBox';
5
5
  import Modal from './components/Modal';
6
6
  import TabBox from './components/TabBox';
7
+ import RadioButton from './components/RadioButton';
7
8
 
8
9
  // Import errors
9
10
  import ErrorWithCode from './errors/ErrorWithCode';
@@ -41,6 +42,7 @@ export {
41
42
  ErrorBox,
42
43
  Modal,
43
44
  TabBox,
45
+ RadioButton,
44
46
  // Global functions
45
47
  alert,
46
48
  confirm,