@dvrd/dvr-controls 1.0.14 → 1.0.16

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.
Files changed (180) hide show
  1. package/index.ts +8 -1
  2. package/package.json +29 -23
  3. package/src/js/button/button.tsx +102 -0
  4. package/src/js/button/buttonController.tsx +179 -0
  5. package/src/js/button/closeButton.tsx +29 -0
  6. package/src/js/button/dvrdButton.tsx +128 -0
  7. package/src/js/button/outlinedButton.tsx +105 -0
  8. package/src/js/button/simpleButton.tsx +163 -0
  9. package/src/js/button/style/button.scss +95 -0
  10. package/src/js/button/style/closeButton.scss +15 -0
  11. package/src/js/button/style/dvrdButton.scss +30 -0
  12. package/src/js/button/style/outlinedButton.scss +84 -0
  13. package/src/js/button/style/simpleButton.scss +80 -0
  14. package/src/js/carousel/DVRCarousel.tsx +163 -0
  15. package/src/js/carousel/DVRCarouselController.tsx +95 -0
  16. package/src/js/carousel/style/DVRCarousel.scss +38 -0
  17. package/src/js/checkbox/checkbox.tsx +148 -0
  18. package/src/js/checkbox/checkboxController.tsx +131 -0
  19. package/src/js/checkbox/style/checkbox.scss +109 -0
  20. package/src/js/colorPicker/colorPicker.tsx +118 -0
  21. package/src/js/colorPicker/style/colorPicker.scss +20 -0
  22. package/src/js/date/dvrdDatePicker.tsx +357 -0
  23. package/src/js/date/style/dvrdDatePicker.scss +307 -0
  24. package/src/js/dialog/dialog.tsx +207 -0
  25. package/src/js/dialog/dialogController.tsx +70 -0
  26. package/src/js/dialog/inlineDialog.tsx +127 -0
  27. package/src/js/dialog/style/dialog.scss +61 -0
  28. package/src/js/events/withEvents.tsx +40 -0
  29. package/src/js/head/DVRHead.tsx +49 -0
  30. package/src/js/header/DVRHeader.tsx +417 -0
  31. package/src/js/header/style/header.scss +206 -0
  32. package/src/js/icon/awesomeIcon.tsx +20 -0
  33. package/src/js/image/imageUpload.tsx +69 -0
  34. package/src/js/image/style/imageUpload.scss +11 -0
  35. package/src/js/info/info.tsx +136 -0
  36. package/src/js/info/style/info.scss +39 -0
  37. package/src/js/input/animated/animatedTextField.tsx +159 -0
  38. package/src/js/input/date/dateField.tsx +360 -0
  39. package/src/js/input/date/dateFieldController.tsx +245 -0
  40. package/src/js/input/date/datePicker/datePicker.tsx +186 -0
  41. package/src/js/input/date/datePicker/style/datePicker.scss +102 -0
  42. package/src/js/input/date/input/dateInput.tsx +214 -0
  43. package/src/js/input/date/style/dateField.scss +40 -0
  44. package/src/js/input/date/timePicker/style/timePicker.scss +95 -0
  45. package/src/js/input/date/timePicker/timePicker.tsx +143 -0
  46. package/src/js/input/editor/DVREditor.tsx +21 -0
  47. package/src/js/input/number/numberInput.tsx +157 -0
  48. package/src/js/input/password/passwordInput.tsx +140 -0
  49. package/src/js/input/password/passwordRules.tsx +48 -0
  50. package/src/js/input/password/style/passwordInput.scss +39 -0
  51. package/src/js/input/password/style/passwordRules.scss +41 -0
  52. package/src/js/input/simple/style/simpleInput.scss +98 -0
  53. package/src/js/input/simple/v2/simpleInputV2.tsx +178 -0
  54. package/src/js/input/style/input.scss +138 -0
  55. package/src/js/input/v2/inputController_v2.tsx +250 -0
  56. package/src/js/input/v2/input_v2.tsx +7 -0
  57. package/src/js/label/label.tsx +196 -0
  58. package/src/js/label/style/label.scss +4 -0
  59. package/src/js/link/link.tsx +38 -0
  60. package/src/js/link/style/link.scss +30 -0
  61. package/src/js/loader/loader.tsx +79 -0
  62. package/src/js/loader/loaderController.tsx +61 -0
  63. package/src/js/loader/style/loader.scss +53 -0
  64. package/src/js/media/media.tsx +72 -0
  65. package/src/js/navigator/navigator.tsx +51 -0
  66. package/src/js/optionsList/dvrdOptionsList.tsx +112 -0
  67. package/src/js/optionsList/style/dvrdOptionsList.scss +84 -0
  68. package/src/js/optionsMenu/optionsMenu.tsx +187 -0
  69. package/src/js/optionsMenu/style/optionsMenu.scss +70 -0
  70. package/src/js/pdf/element/pdfElement.tsx +315 -0
  71. package/src/js/pdf/element/style/pdfElement.scss +111 -0
  72. package/src/js/pdf/history/pdfHistory.ts +57 -0
  73. package/src/js/pdf/image/pdfImage.tsx +175 -0
  74. package/src/js/pdf/image/style/pdfImage.scss +34 -0
  75. package/src/js/pdf/invoiceTable/pdfInvoiceTable.tsx +176 -0
  76. package/src/js/pdf/invoiceTable/style/pdfInvoiceTable.scss +32 -0
  77. package/src/js/pdf/pdfTemplateCreator.tsx +279 -0
  78. package/src/js/pdf/settings/buttons/iconButton.tsx +49 -0
  79. package/src/js/pdf/settings/buttons/style/iconButton.scss +50 -0
  80. package/src/js/pdf/settings/image/pdfImageSettings.tsx +82 -0
  81. package/src/js/pdf/settings/image/style/pdfImageSettings.scss +9 -0
  82. package/src/js/pdf/settings/invoiceTable/pdfInvoiceTableSettings.tsx +141 -0
  83. package/src/js/pdf/settings/invoiceTable/style/pdfInvoiceTableSettings.scss +38 -0
  84. package/src/js/pdf/settings/pdfElementSettings.tsx +86 -0
  85. package/src/js/pdf/settings/style/pdfElementSettings.scss +56 -0
  86. package/src/js/pdf/settings/text/pdfTextSettings.tsx +202 -0
  87. package/src/js/pdf/settings/text/style/pdfTextSettings.scss +94 -0
  88. package/src/js/pdf/style/pdfTemplateCreator.scss +118 -0
  89. package/src/js/pdf/text/pdfText.tsx +267 -0
  90. package/src/js/pdf/text/style/pdfText.scss +22 -0
  91. package/src/js/pdf/v2/pdfElement/pdfDraggableElement.tsx +193 -0
  92. package/src/js/pdf/v2/types/pdfTemplateTypes.ts +27 -0
  93. package/src/js/popup/style/withBackground.scss +29 -0
  94. package/src/js/popup/withBackground.tsx +92 -0
  95. package/src/js/select/async/asyncSelect.tsx +46 -0
  96. package/src/js/select/async/style/asyncSelect.scss +23 -0
  97. package/src/js/select/dvrdSelect.tsx +214 -0
  98. package/src/js/select/dvrdSelectController.tsx +81 -0
  99. package/src/js/select/select.tsx +310 -0
  100. package/src/js/select/selectController.tsx +341 -0
  101. package/src/js/select/style/dvrdSelect.scss +140 -0
  102. package/src/js/select/style/select.scss +199 -0
  103. package/src/js/sidebarMenu/sidebarMenu.tsx +167 -0
  104. package/src/js/sidebarMenu/style/sidebarMenu.scss +167 -0
  105. package/src/js/slider/DVRSlider.tsx +107 -0
  106. package/src/js/slider/style/DVRSlider.scss +88 -0
  107. package/src/js/snackbar/snackbar.tsx +72 -0
  108. package/src/js/snackbar/snackbarController.tsx +104 -0
  109. package/src/js/snackbar/style/snackbar.scss +46 -0
  110. package/src/js/switch/dvrdSwitch.tsx +53 -0
  111. package/src/js/switch/style/dvrdSwitch.scss +47 -0
  112. package/src/js/switch/style/switch.scss +84 -0
  113. package/src/js/switch/switch.tsx +115 -0
  114. package/src/js/switch/switchController.tsx +97 -0
  115. package/src/js/textField/dvrdInput.tsx +219 -0
  116. package/src/js/textField/dvrdInputController.tsx +97 -0
  117. package/src/js/textField/dvrdNumberInput.tsx +141 -0
  118. package/src/js/textField/dvrdPasswordInput.tsx +40 -0
  119. package/src/js/textField/style/dvrdInput.scss +114 -0
  120. package/src/js/textField/style/dvrdPassword.scss +15 -0
  121. package/src/js/topButton/style/topButton.scss +54 -0
  122. package/src/js/topButton/topButton.tsx +136 -0
  123. package/src/js/util/analyticsUtil.ts +41 -0
  124. package/src/js/util/colorUtil.ts +230 -0
  125. package/src/js/util/componentUtil.tsx +59 -0
  126. package/src/js/util/constants.ts +12 -0
  127. package/src/js/util/controlContext.tsx +46 -0
  128. package/src/js/util/controlUtil.ts +107 -0
  129. package/src/js/util/cookieUtil.ts +17 -0
  130. package/src/js/util/eventUtil.ts +65 -0
  131. package/src/js/util/googleUtil.ts +88 -0
  132. package/src/js/util/interfaces.ts +180 -0
  133. package/src/js/util/jwtUtil.ts +72 -0
  134. package/src/js/util/miscUtil.ts +170 -0
  135. package/src/js/util/momentUtil.ts +45 -0
  136. package/src/js/util/pdfUtil.ts +124 -0
  137. package/src/js/util/requestUtil.ts +145 -0
  138. package/src/js/util/responsiveUtil.ts +37 -0
  139. package/src/js/util/validationUtil.ts +13 -0
  140. package/src/res/img/lock-handle.png +0 -0
  141. package/src/res/img/lock-handle.webp +0 -0
  142. package/src/res/img/lock.png +0 -0
  143. package/src/res/img/lock.webp +0 -0
  144. package/src/style/common-icons-variables.scss +140 -0
  145. package/src/style/common-icons.scss +714 -0
  146. package/src/style/common-variables.scss +243 -0
  147. package/src/style/display-breakpoints.scss +141 -0
  148. package/src/style/fonts/common-icons.eot +0 -0
  149. package/src/style/fonts/common-icons.svg +150 -0
  150. package/src/style/fonts/common-icons.ttf +0 -0
  151. package/src/style/fonts/common-icons.woff +0 -0
  152. package/src/style/fonts/common-icons.woff2 +0 -0
  153. package/src/style/fonts/fontAwesome/css/all.css +7003 -0
  154. package/src/style/fonts/fontAwesome/css/all.min.css +6 -0
  155. package/src/style/fonts/fontAwesome/css/brands.css +1423 -0
  156. package/src/style/fonts/fontAwesome/css/brands.min.css +6 -0
  157. package/src/style/fonts/fontAwesome/css/fontawesome.css +5519 -0
  158. package/src/style/fonts/fontAwesome/css/fontawesome.min.css +6 -0
  159. package/src/style/fonts/fontAwesome/css/regular.css +19 -0
  160. package/src/style/fonts/fontAwesome/css/regular.min.css +6 -0
  161. package/src/style/fonts/fontAwesome/css/solid.css +19 -0
  162. package/src/style/fonts/fontAwesome/css/solid.min.css +6 -0
  163. package/src/style/fonts/fontAwesome/css/svg-with-js.css +634 -0
  164. package/src/style/fonts/fontAwesome/css/svg-with-js.min.css +6 -0
  165. package/src/style/fonts/fontAwesome/css/v4-font-face.css +26 -0
  166. package/src/style/fonts/fontAwesome/css/v4-font-face.min.css +6 -0
  167. package/src/style/fonts/fontAwesome/css/v4-shims.css +2146 -0
  168. package/src/style/fonts/fontAwesome/css/v4-shims.min.css +6 -0
  169. package/src/style/fonts/fontAwesome/css/v5-font-face.css +22 -0
  170. package/src/style/fonts/fontAwesome/css/v5-font-face.min.css +6 -0
  171. package/src/style/fonts/fontAwesome/webfonts/fa-brands-400.ttf +0 -0
  172. package/src/style/fonts/fontAwesome/webfonts/fa-brands-400.woff2 +0 -0
  173. package/src/style/fonts/fontAwesome/webfonts/fa-regular-400.ttf +0 -0
  174. package/src/style/fonts/fontAwesome/webfonts/fa-regular-400.woff2 +0 -0
  175. package/src/style/fonts/fontAwesome/webfonts/fa-solid-900.ttf +0 -0
  176. package/src/style/fonts/fontAwesome/webfonts/fa-solid-900.woff2 +0 -0
  177. package/src/style/fonts/fontAwesome/webfonts/fa-v4compatibility.ttf +0 -0
  178. package/src/style/fonts/fontAwesome/webfonts/fa-v4compatibility.woff2 +0 -0
  179. package/src/style/variables.scss +11 -0
  180. package/.gitignore +0 -31
@@ -0,0 +1,207 @@
1
+ /*
2
+ * Copyright (c) 2021. Dave van Rijn Development
3
+ */
4
+
5
+ import './style/dialog.scss';
6
+
7
+ import React, {MouseEventHandler} from 'react';
8
+ import classNames from 'classnames';
9
+ import ButtonController from "../button/buttonController";
10
+ import {ControlContext} from "../util/controlContext";
11
+ import {enterPressed, generateUUID, hasHover} from "../util/controlUtil";
12
+ import {colorIsWhite, convertColor} from "../util/colorUtil";
13
+ import {ControlVariant} from "../util/interfaces";
14
+ import {DialogActions, DialogActionShape} from "./dialogController";
15
+
16
+ interface Props {
17
+ onClose?: (id?: string) => void;
18
+ className: string;
19
+ open?: boolean;
20
+ data?: DataShape;
21
+ id?: string;
22
+ }
23
+
24
+ interface State {
25
+ open: boolean;
26
+ message: string | React.ReactElement;
27
+ title: string;
28
+ actions?: DialogActions;
29
+ transparent: boolean;
30
+ content: React.ReactElement | null;
31
+ }
32
+
33
+ interface DataShape {
34
+ message: string | React.ReactElement;
35
+ title?: string;
36
+ actions?: DialogActions;
37
+ transparent?: boolean;
38
+ persistent?: boolean;
39
+ buttonVariant?: ControlVariant;
40
+ }
41
+
42
+ export default class Dialog extends React.Component<Props, State> {
43
+ declare context: React.ContextType<typeof ControlContext>;
44
+ static contextType = ControlContext;
45
+ static defaultProps = {
46
+ className: '',
47
+ };
48
+ private buttonVariant: ControlVariant = ControlVariant.OUTLINED;
49
+
50
+ onClose = () => {
51
+ const {onClose, id} = this.props;
52
+ this.removeKeyListener();
53
+ this.setState({open: false}, () => {
54
+ if (onClose) onClose(id);
55
+ });
56
+ };
57
+
58
+ getDefaultAction = (): DialogActions => ['Oke'];
59
+
60
+ state: State = {
61
+ open: false,
62
+ message: '',
63
+ content: null,
64
+ title: 'Bericht van het systeem',
65
+ actions: this.getDefaultAction(),
66
+ transparent: false,
67
+ };
68
+
69
+ dialog: HTMLElement | null = null;
70
+ id = generateUUID();
71
+ persistent = false;
72
+
73
+ onClickBackground = () => {
74
+ if (!this.persistent && this.dialog !== null && !hasHover(this.dialog))
75
+ this.onClose();
76
+ };
77
+
78
+ // =============== NOTE Use function below to open the dialog
79
+ onOpen = (data: DataShape) => {
80
+ const message = data.message, title = data.title === undefined ? 'Bericht van het systeem' : data.title,
81
+ actions = data.actions === undefined ? this.getDefaultAction() : data.actions,
82
+ transparent = data.transparent === undefined ? false : data.transparent;
83
+ this.persistent = data.persistent === undefined ? true : data.persistent;
84
+ if (data.buttonVariant) this.buttonVariant = data.buttonVariant;
85
+ this.setState({message, title, actions, transparent}, () => {
86
+ this.setState({open: true});
87
+ });
88
+ this.addKeyListener();
89
+ };
90
+
91
+ onEnterPressed = (evt: KeyboardEvent) => {
92
+ evt.stopPropagation();
93
+ const {actions} = this.state;
94
+ if (actions)
95
+ for (const action of actions) {
96
+ if (typeof (action) === 'string' || action.primary) {
97
+ if (typeof action === 'string') this.onClose();
98
+ else if (action.onClick) action.onClick(evt as any as React.MouseEvent);
99
+ break;
100
+ }
101
+ }
102
+ }
103
+
104
+ keyListener = (evt: KeyboardEvent) => {
105
+ if (enterPressed(evt)) {
106
+ this.onEnterPressed(evt);
107
+ }
108
+ };
109
+
110
+ addKeyListener = () => {
111
+ document.addEventListener('keydown', this.keyListener);
112
+ };
113
+
114
+ removeKeyListener = () => {
115
+ document.removeEventListener('keydown', this.keyListener);
116
+ };
117
+
118
+ getColorStyle = (): object => {
119
+ const {baseColor, contrastColor} = this.context,
120
+ color = colorIsWhite(baseColor) ? contrastColor : baseColor;
121
+ return {color: convertColor(color)};
122
+ };
123
+
124
+ extendOnClick = (onClick?: Function): MouseEventHandler => (evt: any) => {
125
+ this.onClose();
126
+ if (onClick !== undefined && onClick !== null)
127
+ onClick(evt);
128
+ };
129
+
130
+ getActions = () => {
131
+ const {actions} = this.state;
132
+ if (actions === undefined || actions === null) return this.generateDefaultAction();
133
+ if (Array.isArray(actions))
134
+ return actions.map(this.renderAction);
135
+ return this.renderAction(actions);
136
+ };
137
+
138
+ generateDefaultAction = (): React.ReactNode => (
139
+ <ButtonController label={'Oke'} onClick={this.onClose} type='outlined' containerClass='dialogButton'/>
140
+ );
141
+
142
+ renderAction = (action: DialogActionShape | string, index?: number) => {
143
+ const keyProp = index === undefined ? {} : {key: index};
144
+ if (typeof action === 'string') return (
145
+ <ButtonController {...keyProp} label={action} onClick={this.onClose}
146
+ type={this.buttonVariant} containerClass='dialogButton'/>
147
+ );
148
+ return (
149
+ <ButtonController {...keyProp} label={action.label} onClick={this.extendOnClick(action.onClick)}
150
+ type={this.buttonVariant} containerClass='dialogButton' primary={action.primary}/>
151
+ );
152
+ };
153
+
154
+ renderTitle = (): React.ReactNode => {
155
+ const {title} = this.state;
156
+ return (
157
+ <div className='dialogTitleContainer'>
158
+ <label className='dialogTitle' style={this.getColorStyle()}>{title}</label>
159
+ </div>
160
+ )
161
+ };
162
+
163
+ renderMessage = (): React.ReactNode => {
164
+ const {message} = this.state;
165
+ return (
166
+ <div className='dialogMessageContainer'>
167
+ {typeof message === 'string' ? <p className='dialogMessage'>{message}</p> : message}
168
+ </div>
169
+ )
170
+ };
171
+
172
+ renderActions = (): React.ReactNode => {
173
+ const actions = this.getActions();
174
+ return (
175
+ <div className='dialogActionsContainer'>
176
+ {actions}
177
+ </div>
178
+ )
179
+ };
180
+
181
+ componentDidMount = () => {
182
+ const {open, data} = this.props;
183
+ if (open && data) this.onOpen(data);
184
+ };
185
+
186
+ componentWillUnmount = () => {
187
+ this.removeKeyListener();
188
+ };
189
+
190
+ render = () => {
191
+ const {open, transparent} = this.state, {className} = this.props;
192
+ if (!open && !this.props.open) return null;
193
+ return (
194
+ <div className={classNames('dialogContainer', transparent && 'transparent')}
195
+ onClick={this.onClickBackground}>
196
+ <div className={classNames('dvr-dialog', className)} ref={ref => {
197
+ this.dialog = ref
198
+ }}>
199
+ {this.renderTitle()}
200
+ {this.renderMessage()}
201
+ {this.renderActions()}
202
+ </div>
203
+ </div>
204
+ // </WithEvents>
205
+ )
206
+ }
207
+ }
@@ -0,0 +1,70 @@
1
+ /*
2
+ * Copyright (c) 2021. Dave van Rijn Development
3
+ */
4
+
5
+ import * as React from 'react';
6
+ import {Fragment, MouseEventHandler, PureComponent, ReactElement} from 'react';
7
+ import {ControlVariant, CustomAppEvent, IndexedObject} from '../util/interfaces';
8
+ import Dialog from './dialog';
9
+ import {generateComponentId} from "../util/componentUtil";
10
+ import {WithEvents} from "../../../index";
11
+
12
+ export interface DialogActionShape {
13
+ label: string;
14
+ onClick?: MouseEventHandler;
15
+ primary?: boolean;
16
+ }
17
+
18
+ export type DialogActions = (DialogActionShape | string)[];
19
+
20
+ interface Props {
21
+ className?: string;
22
+ }
23
+
24
+ interface State {
25
+ dialogs: IndexedObject<ReactElement>
26
+ }
27
+
28
+ interface DataShape {
29
+ message: string | React.ReactElement;
30
+ title?: string;
31
+ actions?: DialogActions;
32
+ transparent?: boolean;
33
+ persistent?: boolean;
34
+ buttonVariant?: ControlVariant;
35
+ }
36
+
37
+ export default class DialogController extends PureComponent<Props, State> {
38
+ state: State = {
39
+ dialogs: {},
40
+ };
41
+
42
+ onClose = (id?: string) => {
43
+ if (id) {
44
+ const dialogs = Object.assign({}, this.state.dialogs);
45
+ delete dialogs[id];
46
+ this.setState({dialogs});
47
+ }
48
+ }
49
+
50
+ onOpen = (data: DataShape) => {
51
+ const dialogs = Object.assign({}, this.state.dialogs), id = generateComponentId();
52
+ dialogs[id] = <Dialog open data={data} id={id} onClose={this.onClose}/>;
53
+ this.setState({dialogs});
54
+ };
55
+
56
+ getEvents = (): CustomAppEvent[] => [
57
+ {eventName: 'onOpenDialog', handler: this.onOpen},
58
+ ];
59
+
60
+ render = () => {
61
+ const {className} = this.props;
62
+ return <WithEvents events={this.getEvents()}>
63
+ {Object.values(this.state.dialogs).map((element: ReactElement, key: number) => (
64
+ <Fragment key={key}>
65
+ {React.cloneElement(element, {className})}
66
+ </Fragment>
67
+ ))}
68
+ </WithEvents>
69
+ }
70
+ }
@@ -0,0 +1,127 @@
1
+ /*
2
+ * Copyright (c) 2021. Dave van Rijn Development
3
+ */
4
+
5
+ import './style/dialog.scss';
6
+
7
+ import React from 'react';
8
+ import classNames from 'classnames';
9
+ import ButtonController from "../button/buttonController";
10
+ import {ControlContext} from "../util/controlContext";
11
+ import {generateUUID, hasHover} from "../util/controlUtil";
12
+ import {colorIsWhite, convertColor} from "../util/colorUtil";
13
+ import {DialogActionShape} from "./dialogController";
14
+
15
+ interface DialogProps {
16
+ onClose: Function,
17
+ message: string,
18
+ open: boolean,
19
+ title?: string,
20
+ actions?: DialogActionShape[] | DialogActionShape | null,
21
+ transparent?: boolean,
22
+ persistent?: boolean,
23
+ content?: React.ReactElement | null,
24
+ containerClass: string,
25
+ }
26
+
27
+ export default class InlineDialog extends React.Component<DialogProps> {
28
+ declare context: React.ContextType<typeof ControlContext>;
29
+ static contextType = ControlContext;
30
+
31
+ static defaultProps = {
32
+ title: 'Bericht van Klaverjassen',
33
+ actions: null,
34
+ transparent: false,
35
+ persistent: true,
36
+ content: null,
37
+ containerClass: '',
38
+ };
39
+
40
+ constructor(props: any) {
41
+ super(props);
42
+ }
43
+
44
+ dialog: HTMLElement | null = null;
45
+ id = generateUUID();
46
+
47
+ onClickBackground = () => {
48
+ const {persistent, onClose} = this.props;
49
+ if (!persistent && this.dialog !== null && !hasHover(this.dialog))
50
+ onClose();
51
+ };
52
+
53
+ onClickAction = (onClick: Function | undefined) => (evt: React.MouseEvent) => {
54
+ if (onClick !== undefined) onClick(evt);
55
+ this.props.onClose();
56
+ };
57
+
58
+ onClickDefault = () => {
59
+ this.props.onClose();
60
+ }
61
+
62
+ getColorStyle = (): object => {
63
+ // noinspection JSDeprecatedSymbols
64
+ const {baseColor, contrastColor} = this.context,
65
+ color = colorIsWhite(contrastColor) ? baseColor : contrastColor;
66
+ return {color: convertColor(color)};
67
+ };
68
+
69
+ getActions = () => {
70
+ const {actions} = this.props;
71
+ if (actions === undefined || actions === null) return this.generateDefaultAction();
72
+ if (Array.isArray(actions))
73
+ return actions.map((action: DialogActionShape, key: any) => (
74
+ <ButtonController key={key} label={action.label} onClick={this.onClickAction(action.onClick)}
75
+ type='outlined' containerClass='dialogButton'/>
76
+ ));
77
+ return <ButtonController label={actions.label} onClick={this.onClickAction(actions.onClick)} type='outlined'/>
78
+ };
79
+
80
+ generateDefaultAction = (): React.ReactNode => <ButtonController label={'Oke'} onClick={this.onClickDefault}
81
+ type='outlined' containerClass='dialogButton'/>;
82
+
83
+ renderTitle = (): React.ReactNode => {
84
+ const {title} = this.props;
85
+ return (
86
+ <div className='dialogTitleContainer'>
87
+ <label className='dialogTitle' style={this.getColorStyle()}>{title}</label>
88
+ </div>
89
+ )
90
+ };
91
+
92
+ renderMessage = (): React.ReactNode => {
93
+ const {message, content} = this.props;
94
+ return (
95
+ <div className='dialogMessageContainer'>
96
+ <p className='dialogMessage'>{message}</p>
97
+ {content !== undefined && content}
98
+ </div>
99
+ )
100
+ };
101
+
102
+ renderActions = (): React.ReactNode => {
103
+ const actions = this.getActions();
104
+ return (
105
+ <div className='dialogActionsContainer'>
106
+ {actions}
107
+ </div>
108
+ )
109
+ };
110
+
111
+ render = () => {
112
+ const {open, transparent, containerClass} = this.props;
113
+ if (!open) return null;
114
+ return (
115
+ <div className={classNames('dialogContainer', transparent && 'transparent', containerClass)}
116
+ onClick={this.onClickBackground}>
117
+ <div className='dialog' ref={ref => {
118
+ this.dialog = ref
119
+ }}>
120
+ {this.renderTitle()}
121
+ {this.renderMessage()}
122
+ {this.renderActions()}
123
+ </div>
124
+ </div>
125
+ )
126
+ }
127
+ }
@@ -0,0 +1,61 @@
1
+ /*!
2
+ * Copyright (c) 2021. Dave van Rijn Development
3
+ */
4
+
5
+ @import '../../../style/variables';
6
+
7
+ .dialogContainer {
8
+ @include popupContainer;
9
+ z-index: $z-index-dialog;
10
+
11
+ &.transparent {
12
+ background-color: transparent;
13
+ }
14
+
15
+ .dvr-dialog {
16
+ @include popupDialog;
17
+ background-color: white;
18
+ display: flex;
19
+ flex-direction: column;
20
+ max-width: 40rem;
21
+ max-height: 100%;
22
+ padding: 1.5rem 2rem;
23
+
24
+ .dialogTitleContainer {
25
+
26
+ .dialogTitle {
27
+ font-size: 1.2rem;
28
+ user-select: none;
29
+ }
30
+ }
31
+
32
+ .dialogMessageContainer {
33
+ padding: 1.5rem 0;
34
+
35
+ .dialogMessage {
36
+ margin: 0;
37
+ color: $color-gray-5;
38
+ }
39
+ }
40
+
41
+ .dialogActionsContainer {
42
+ display: flex;
43
+ justify-content: flex-end;
44
+ align-items: center;
45
+ flex-wrap: wrap;
46
+
47
+ .dialogButton {
48
+ margin-right: .5rem;
49
+
50
+ &:last-child {
51
+ margin-right: 0;
52
+ }
53
+ }
54
+ }
55
+
56
+ @include break-sm-down {
57
+ width: 90vw;
58
+ box-sizing: border-box;
59
+ }
60
+ }
61
+ }
@@ -0,0 +1,40 @@
1
+ /*
2
+ * Copyright (c) 2021. Dave van Rijn Development
3
+ */
4
+
5
+ import React, { PropsWithChildren } from 'react';
6
+ import {addCustomEventListener, removeCustomEventListener} from '../util/eventUtil';
7
+ import {CustomAppEvent} from '../util/interfaces';
8
+ import {generateComponentId} from "../util/componentUtil";
9
+
10
+ interface Props {
11
+ events: CustomAppEvent | CustomAppEvent[],
12
+ componentName?: string;
13
+ }
14
+
15
+ export default class WithEvents extends React.PureComponent<PropsWithChildren<Props>> {
16
+ private readonly componentName: string;
17
+
18
+ constructor(props: Props) {
19
+ super(props);
20
+ this.componentName = generateComponentId(props.componentName);
21
+ }
22
+
23
+ componentDidMount = () => {
24
+ const {events} = this.props;
25
+ if (Array.isArray(events))
26
+ for (const event of events)
27
+ addCustomEventListener(this.componentName, event.eventName, event.handler);
28
+ else addCustomEventListener(this.componentName, events.eventName, events.handler);
29
+ };
30
+
31
+ componentWillUnmount = () => {
32
+ const {events} = this.props;
33
+ if (Array.isArray(events))
34
+ for (const event of events)
35
+ removeCustomEventListener(this.componentName, event.eventName);
36
+ else removeCustomEventListener(this.componentName, events.eventName);
37
+ };
38
+
39
+ render = () => this.props.children;
40
+ }
@@ -0,0 +1,49 @@
1
+ /*
2
+ * Copyright (c) 2021. Dave van Rijn Development
3
+ */
4
+
5
+ import React, {PureComponent, ReactElement} from 'react';
6
+
7
+ interface Props {
8
+ children?: any;
9
+ }
10
+
11
+ export default class DVRHead extends PureComponent<Props> {
12
+
13
+ private includeTags = () => {
14
+ const {children} = this.props;
15
+ this.removeAll();
16
+ if (children) {
17
+ if (Array.isArray(children)) for (const child of children) this.includeChild(child);
18
+ else this.includeChild(children);
19
+ }
20
+ };
21
+
22
+ private includeChild = (child: ReactElement) => {
23
+ const {type, props} = child,
24
+ elem = document.createElement(type as keyof HTMLElementTagNameMap);
25
+ for (const key of Object.keys(props)) {
26
+ if (key === 'children') elem.innerHTML = props[key];
27
+ else (elem as any)[key] = props[key];
28
+ }
29
+ elem.dataset.gen = 'dvr';
30
+ document.head.appendChild(elem);
31
+ };
32
+
33
+ private removeAll = () => {
34
+ const elems = document.querySelectorAll("[data-gen='dvr']");
35
+ for (const elem of elems) elem.parentElement?.removeChild(elem);
36
+ };
37
+
38
+ componentDidMount = () => {
39
+ this.includeTags();
40
+ };
41
+
42
+ componentDidUpdate = () => {
43
+ this.includeTags();
44
+ };
45
+
46
+ render = () => {
47
+ return null;
48
+ }
49
+ }