@etsoo/react 1.2.11 → 1.2.15

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.
@@ -4,7 +4,7 @@ import { AutocompleteExtendedProps } from './AutocompleteExtendedProps';
4
4
  /**
5
5
  * Tiplist props
6
6
  */
7
- export interface TiplistProps<T extends Record<string, any>> extends Omit<AutocompleteExtendedProps<T>, 'options' | 'open'> {
7
+ export interface TiplistProps<T extends Record<string, any>> extends Omit<AutocompleteExtendedProps<T>, 'open'> {
8
8
  /**
9
9
  * Load data callback
10
10
  */
@@ -1,11 +1,45 @@
1
1
  import React from 'react';
2
- import { INotification, INotifier, Notification, NotificationAlign, NotificationContainer, NotificationRenderProps } from '@etsoo/notificationbase';
2
+ import { INotification, INotifier, Notification, NotificationAlign, NotificationCallProps, NotificationContainer, NotificationRenderProps } from '@etsoo/notificationbase';
3
3
  import { IAction } from '@etsoo/appscript';
4
4
  import { IProviderProps } from '../states/IState';
5
+ import { Breakpoint } from '@mui/material';
6
+ /**
7
+ * React notification call props
8
+ */
9
+ export interface NotificationReactCallProps extends NotificationCallProps {
10
+ /**
11
+ * Full width
12
+ */
13
+ fullWidth?: boolean;
14
+ /**
15
+ * Full screen
16
+ */
17
+ fullScreen?: boolean;
18
+ /**
19
+ * Inputs layout
20
+ */
21
+ inputs?: React.ReactNode;
22
+ /**
23
+ * Max width
24
+ */
25
+ maxWidth?: Breakpoint | false;
26
+ /**
27
+ * OK label
28
+ */
29
+ okLabel?: string;
30
+ /**
31
+ * Cancel label
32
+ */
33
+ cancelLabel?: string;
34
+ /**
35
+ * Type
36
+ */
37
+ type?: string;
38
+ }
5
39
  /**
6
40
  * React notification interface
7
41
  */
8
- export interface INotificationReact extends INotification<React.ReactNode> {
42
+ export interface INotificationReact extends INotification<React.ReactNode, NotificationReactCallProps> {
9
43
  }
10
44
  /**
11
45
  * Action to manage the notifier
@@ -23,7 +57,7 @@ interface INotifierAction extends IAction {
23
57
  /**
24
58
  * React notification
25
59
  */
26
- export declare abstract class NotificationReact extends Notification<React.ReactNode> {
60
+ export declare abstract class NotificationReact extends Notification<React.ReactNode, NotificationReactCallProps> {
27
61
  }
28
62
  /**
29
63
  * React notification render props
@@ -33,7 +67,7 @@ export interface NotificationReactRenderProps extends NotificationRenderProps, I
33
67
  /**
34
68
  * Notifier interface
35
69
  */
36
- export interface INotifierReact extends INotifier<React.ReactNode> {
70
+ export interface INotifierReact extends INotifier<React.ReactNode, NotificationReactCallProps> {
37
71
  /**
38
72
  * Create state provider
39
73
  * @param className Style class name
@@ -51,7 +85,7 @@ export interface INotifierOptions {
51
85
  /**
52
86
  * Notifier for React
53
87
  */
54
- export declare abstract class NotifierReact extends NotificationContainer<React.ReactNode> implements INotifierReact {
88
+ export declare abstract class NotifierReact extends NotificationContainer<React.ReactNode, NotificationReactCallProps> implements INotifierReact {
55
89
  private static _instance;
56
90
  /**
57
91
  * Singleton instance
@@ -76,13 +110,12 @@ export declare abstract class NotifierReact extends NotificationContainer<React.
76
110
  * @param children Children
77
111
  * @param options Other options
78
112
  */
79
- protected abstract createContainer(align: NotificationAlign, children: React.ReactNode[], options: any): React.ReactElement;
113
+ protected abstract createContainer(align: NotificationAlign, children: React.ReactNode[]): React.ReactElement;
80
114
  /**
81
115
  * Create state provider
82
116
  * @param className Style class name
83
- * @param optionGenerator Options generator
84
117
  * @returns Provider
85
118
  */
86
- createProvider(className?: string, optionGenerator?: INotifierOptions): React.FunctionComponent<NotificationReactRenderProps>;
119
+ createProvider(className?: string): React.FunctionComponent<NotificationReactRenderProps>;
87
120
  }
88
121
  export {};
@@ -35,25 +35,22 @@ export class NotifierReact extends NotificationContainer {
35
35
  /**
36
36
  * Create state provider
37
37
  * @param className Style class name
38
- * @param optionGenerator Options generator
39
38
  * @returns Provider
40
39
  */
41
- createProvider(className, optionGenerator) {
40
+ createProvider(className) {
42
41
  // Custom creator
43
42
  const creator = (state, update, props) => {
44
43
  // Hold the current state update
45
44
  this.stateUpdate = update;
46
- // Options
47
- const options = optionGenerator ? optionGenerator() : {};
48
45
  // Aligns collection
49
46
  const aligns = [];
50
47
  for (const align in state) {
51
48
  // Notifications under the align
52
49
  const notifications = state[align];
53
50
  // UI collections
54
- const ui = notifications.map((notification) => notification.render(props, className + '-item', options));
51
+ const ui = notifications.map((notification) => notification.render(props, className + '-item'));
55
52
  // Add to the collection
56
- aligns.push(this.createContainer(Number(align), ui, options));
53
+ aligns.push(this.createContainer(Number(align), ui));
57
54
  }
58
55
  // Generate the component
59
56
  return React.createElement('div', { className }, aligns);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/react",
3
- "version": "1.2.11",
3
+ "version": "1.2.15",
4
4
  "description": "TypeScript ReactJs framework",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -44,9 +44,9 @@
44
44
  "@emotion/react": "^11.4.1",
45
45
  "@emotion/style": "^0.8.0",
46
46
  "@emotion/styled": "^11.3.0",
47
- "@etsoo/appscript": "^1.0.99",
48
- "@etsoo/notificationbase": "^1.0.78",
49
- "@etsoo/shared": "^1.0.44",
47
+ "@etsoo/appscript": "^1.1.3",
48
+ "@etsoo/notificationbase": "^1.0.79",
49
+ "@etsoo/shared": "^1.0.46",
50
50
  "@mui/icons-material": "^5.0.1",
51
51
  "@mui/material": "^5.0.2",
52
52
  "@reach/router": "^1.3.4",
@@ -1,9 +1,10 @@
1
1
  import { NotificationReturn } from '@etsoo/notificationbase';
2
+ import { NotificationReactCallProps } from '../notifier/Notifier';
2
3
 
3
4
  /**
4
5
  * Input dialog props
5
6
  */
6
- export type InputDialogProps = {
7
+ export type InputDialogProps = NotificationReactCallProps & {
7
8
  /**
8
9
  * Title
9
10
  */
@@ -14,23 +15,8 @@ export type InputDialogProps = {
14
15
  */
15
16
  message: string;
16
17
 
17
- /**
18
- * Inputs layout
19
- */
20
- inputs: React.ReactNode;
21
-
22
18
  /**
23
19
  * Callback
24
20
  */
25
21
  callback: NotificationReturn<HTMLFormElement>;
26
-
27
- /**
28
- * OK label
29
- */
30
- okLabel?: string;
31
-
32
- /**
33
- * Cancel label
34
- */
35
- cancelLabel?: string;
36
22
  };
@@ -8,6 +8,7 @@ import {
8
8
  import { DataTypes } from '@etsoo/shared';
9
9
  import React from 'react';
10
10
  import { NotifierPromptProps } from '../mu/NotifierPromptProps';
11
+ import { NotificationReactCallProps } from '../notifier/Notifier';
11
12
  import { CultureAction } from '../states/CultureState';
12
13
  import { IStateProps } from '../states/IState';
13
14
  import { IPageData, PageAction, PageActionType } from '../states/PageState';
@@ -56,11 +57,29 @@ export interface IReactApp<
56
57
  S extends IAppSettings,
57
58
  D extends IUser,
58
59
  P extends IPageData
59
- > extends ICoreApp<S, React.ReactNode> {
60
+ > extends ICoreApp<S, React.ReactNode, NotificationReactCallProps> {
60
61
  /**
61
62
  * User state
62
63
  */
63
64
  readonly userState: UserState<D>;
65
+
66
+ /**
67
+ * Set page data
68
+ * @param data Page data
69
+ */
70
+ setPageData(data: P): void;
71
+
72
+ /**
73
+ * Set page title and data
74
+ * @param key Page title resource key
75
+ */
76
+ setPageKey(key: string): void;
77
+
78
+ /**
79
+ * Set page title and data
80
+ * @param title Page title
81
+ */
82
+ setPageTitle(title: string): void;
64
83
  }
65
84
 
66
85
  /**
@@ -71,7 +90,7 @@ export abstract class ReactApp<
71
90
  D extends IUser,
72
91
  P extends IPageData
73
92
  >
74
- extends CoreApp<S, React.ReactNode>
93
+ extends CoreApp<S, React.ReactNode, NotificationReactCallProps>
75
94
  implements IReactApp<S, D, P>
76
95
  {
77
96
  /**
@@ -190,17 +209,10 @@ export abstract class ReactApp<
190
209
  showInputDialog({
191
210
  title,
192
211
  message,
193
- inputs,
194
212
  callback,
195
- cancelLabel,
196
- okLabel
213
+ ...rest
197
214
  }: InputDialogProps): void {
198
- const props: NotifierPromptProps = {
199
- okLabel,
200
- cancelLabel,
201
- inputs
202
- };
203
- this.notifier.prompt<HTMLFormElement>(message, callback, title, props);
215
+ this.notifier.prompt<HTMLFormElement>(message, callback, title, rest);
204
216
  }
205
217
 
206
218
  /**
@@ -5,7 +5,10 @@ import { AutocompleteProps } from '@mui/material';
5
5
  * Autocomplete extended props
6
6
  */
7
7
  export interface AutocompleteExtendedProps<T extends Record<string, any>>
8
- extends Omit<AutocompleteProps<T, undefined, false, false>, 'renderInput'> {
8
+ extends Omit<
9
+ AutocompleteProps<T, undefined, false, false>,
10
+ 'renderInput' | 'options'
11
+ > {
9
12
  /**
10
13
  * Id field, default is id
11
14
  */
@@ -9,7 +9,17 @@ import { SearchField } from './SearchField';
9
9
  * ComboBox props
10
10
  */
11
11
  export interface ComboBoxProps<T extends Record<string, any>>
12
- extends AutocompleteExtendedProps<T> {}
12
+ extends AutocompleteExtendedProps<T> {
13
+ /**
14
+ * Load data callback
15
+ */
16
+ loadData?: () => PromiseLike<T[] | null | undefined>;
17
+
18
+ /**
19
+ * Array of options.
20
+ */
21
+ options?: ReadonlyArray<T>;
22
+ }
13
23
 
14
24
  /**
15
25
  * ComboBox
@@ -29,8 +39,9 @@ export function ComboBox<T extends Record<string, any>>(
29
39
  inputVariant,
30
40
  defaultValue,
31
41
  label,
42
+ loadData,
32
43
  name,
33
- options,
44
+ options = [],
34
45
  readOnly = true,
35
46
  onChange,
36
47
  value,
@@ -41,10 +52,14 @@ export function ComboBox<T extends Record<string, any>>(
41
52
  // Value input ref
42
53
  const inputRef = React.createRef<HTMLInputElement>();
43
54
 
55
+ // Options state
56
+ const [localOptions, setOptions] = React.useState(options);
57
+ const isMounted = React.useRef(true);
58
+
44
59
  // Local default value
45
60
  const localValue =
46
61
  idValue != null
47
- ? options.find((o) => o[idField] === idValue)
62
+ ? localOptions.find((o) => o[idField] === idValue)
48
63
  : defaultValue ?? value;
49
64
 
50
65
  // Current id value
@@ -64,6 +79,19 @@ export function ComboBox<T extends Record<string, any>>(
64
79
  return params;
65
80
  };
66
81
 
82
+ React.useEffect(() => {
83
+ if (loadData) {
84
+ loadData().then((result) => {
85
+ if (result == null || !isMounted.current) return;
86
+ setOptions(result);
87
+ });
88
+ }
89
+
90
+ return () => {
91
+ isMounted.current = false;
92
+ };
93
+ }, []);
94
+
67
95
  // Layout
68
96
  return (
69
97
  <div>
@@ -121,7 +149,7 @@ export function ComboBox<T extends Record<string, any>>(
121
149
  />
122
150
  )
123
151
  }
124
- options={options}
152
+ options={localOptions}
125
153
  {...rest}
126
154
  />
127
155
  </div>
@@ -16,7 +16,6 @@ import {
16
16
  Button,
17
17
  CircularProgress,
18
18
  CircularProgressProps,
19
- ClassNameMap,
20
19
  Dialog,
21
20
  DialogActions,
22
21
  DialogContent,
@@ -35,10 +34,10 @@ import { Labels } from '../app/Labels';
35
34
  import {
36
35
  INotificationReact,
37
36
  NotificationReact,
37
+ NotificationReactCallProps,
38
38
  NotifierReact
39
39
  } from '../notifier/Notifier';
40
40
  import { DraggablePaperComponent } from './DraggablePaperComponent';
41
- import { NotifierPromptProps } from './NotifierPromptProps';
42
41
  import { LoadingButton } from './LoadingButton';
43
42
 
44
43
  // Custom icon dialog title bar
@@ -69,13 +68,16 @@ export class NotificationMU extends NotificationReact {
69
68
  }
70
69
 
71
70
  // Create alert
72
- private createAlert(
73
- _props: NotificationRenderProps,
74
- className: string,
75
- classes: ClassNameMap<string>
76
- ) {
71
+ private createAlert(_props: NotificationRenderProps, className: string) {
77
72
  const labels = Labels.NotificationMU;
78
73
 
74
+ const {
75
+ inputs,
76
+ fullScreen,
77
+ fullWidth = true,
78
+ maxWidth
79
+ } = this.inputProps ?? {};
80
+
79
81
  let title = this.title;
80
82
  let icon: React.ReactNode;
81
83
  if (this.type === NotificationMessageType.Success) {
@@ -98,16 +100,17 @@ export class NotificationMU extends NotificationReact {
98
100
  open={this.open}
99
101
  PaperComponent={DraggablePaperComponent}
100
102
  className={className}
103
+ fullWidth={fullWidth}
104
+ maxWidth={maxWidth}
105
+ fullScreen={fullScreen}
101
106
  >
102
- <IconDialogTitle
103
- className={classes.iconTitle}
104
- id="draggable-dialog-title"
105
- >
107
+ <IconDialogTitle id="draggable-dialog-title">
106
108
  {icon}
107
109
  <span className="dialogTitle">{title}</span>
108
110
  </IconDialogTitle>
109
111
  <DialogContent>
110
112
  <DialogContentText>{this.content}</DialogContentText>
113
+ {inputs}
111
114
  </DialogContent>
112
115
  <DialogActions>
113
116
  <LoadingButton
@@ -123,16 +126,21 @@ export class NotificationMU extends NotificationReact {
123
126
  }
124
127
 
125
128
  // Create confirm
126
- private createConfirm(
127
- _props: NotificationRenderProps,
128
- className: string,
129
- classes: ClassNameMap<string>
130
- ) {
129
+ private createConfirm(_props: NotificationRenderProps, className: string) {
131
130
  const labels = Labels.NotificationMU;
132
131
  const title = this.title ?? labels.confirmTitle;
133
132
 
134
- const noLabel = labels.confirmNo;
135
- const yesLabel = labels.confirmYes;
133
+ const {
134
+ okLabel,
135
+ cancelLabel,
136
+ inputs,
137
+ fullScreen,
138
+ fullWidth = true,
139
+ maxWidth
140
+ } = this.inputProps ?? {};
141
+
142
+ const noLabel = cancelLabel ?? labels.confirmNo;
143
+ const yesLabel = okLabel ?? labels.confirmYes;
136
144
 
137
145
  return (
138
146
  <Dialog
@@ -140,16 +148,17 @@ export class NotificationMU extends NotificationReact {
140
148
  open={this.open}
141
149
  PaperComponent={DraggablePaperComponent}
142
150
  className={className}
151
+ fullWidth={fullWidth}
152
+ maxWidth={maxWidth}
153
+ fullScreen={fullScreen}
143
154
  >
144
- <IconDialogTitle
145
- className={classes.iconTitle}
146
- id="draggable-dialog-title"
147
- >
155
+ <IconDialogTitle id="draggable-dialog-title">
148
156
  <Help color="action" />
149
157
  <span className="dialogTitle">{title}</span>
150
158
  </IconDialogTitle>
151
159
  <DialogContent>
152
160
  <DialogContentText>{this.content}</DialogContentText>
161
+ {inputs}
153
162
  </DialogContent>
154
163
  <DialogActions>
155
164
  <LoadingButton
@@ -178,11 +187,7 @@ export class NotificationMU extends NotificationReact {
178
187
  }
179
188
 
180
189
  // Create message
181
- private createMessage(
182
- _props: NotificationRenderProps,
183
- className: string,
184
- _classes: ClassNameMap<string>
185
- ) {
190
+ private createMessage(_props: NotificationRenderProps, className: string) {
186
191
  if (!this.open) return <React.Fragment key={this.id}></React.Fragment>;
187
192
 
188
193
  const setupProps: AlertProps = {
@@ -208,11 +213,7 @@ export class NotificationMU extends NotificationReact {
208
213
  }
209
214
 
210
215
  // Create prompt
211
- private createPrompt(
212
- _props: NotificationRenderProps,
213
- className: string,
214
- classes: ClassNameMap<string>
215
- ) {
216
+ private createPrompt(_props: NotificationRenderProps, className: string) {
216
217
  const labels = Labels.NotificationMU;
217
218
  const title = this.title ?? labels.promptTitle;
218
219
 
@@ -221,8 +222,11 @@ export class NotificationMU extends NotificationReact {
221
222
  okLabel = labels.promptOK,
222
223
  inputs,
223
224
  type,
225
+ fullScreen,
226
+ fullWidth = true,
227
+ maxWidth,
224
228
  ...rest
225
- } = this.inputProps as NotifierPromptProps;
229
+ } = this.inputProps ?? {};
226
230
 
227
231
  const handleSubmit = async (
228
232
  event: React.MouseEvent<HTMLButtonElement>
@@ -286,6 +290,7 @@ export class NotificationMU extends NotificationReact {
286
290
  {...rest}
287
291
  value="true"
288
292
  autoFocus
293
+ required
289
294
  />
290
295
  );
291
296
  } else if (type === 'slider') {
@@ -297,6 +302,7 @@ export class NotificationMU extends NotificationReact {
297
302
  autoFocus
298
303
  fullWidth
299
304
  type={type}
305
+ required
300
306
  {...rest}
301
307
  />
302
308
  );
@@ -311,12 +317,12 @@ export class NotificationMU extends NotificationReact {
311
317
  open={this.open}
312
318
  PaperComponent={DraggablePaperComponent}
313
319
  className={className}
320
+ fullWidth={fullWidth}
321
+ maxWidth={maxWidth}
322
+ fullScreen={fullScreen}
314
323
  >
315
324
  <form>
316
- <IconDialogTitle
317
- className={classes.iconTitle}
318
- id="draggable-dialog-title"
319
- >
325
+ <IconDialogTitle id="draggable-dialog-title">
320
326
  <Info color="primary" />
321
327
  <span className="dialogTitle">{title}</span>
322
328
  </IconDialogTitle>
@@ -345,16 +351,15 @@ export class NotificationMU extends NotificationReact {
345
351
  }
346
352
 
347
353
  // Create loading
348
- private createLoading(
349
- _props: NotificationRenderProps,
350
- className: string,
351
- _classes: ClassNameMap<string>
352
- ) {
354
+ private createLoading(_props: NotificationRenderProps, className: string) {
353
355
  // Properties
354
356
  const setupProps: CircularProgressProps = { color: 'primary' };
355
357
 
356
358
  const labels = Labels.NotificationMU;
357
359
 
360
+ // Input props
361
+ const { maxWidth = 'xs' } = this.inputProps ?? {};
362
+
358
363
  // Content
359
364
  let content = this.content;
360
365
  if (content === '@') content = labels.loading.toString();
@@ -384,7 +389,13 @@ export class NotificationMU extends NotificationReact {
384
389
  }}
385
390
  >
386
391
  <CircularProgress {...setupProps} />
387
- {content && <Box maxWidth={640}>{content}</Box>}
392
+ {content && (
393
+ <Box
394
+ maxWidth={maxWidth === false ? undefined : maxWidth}
395
+ >
396
+ {content}
397
+ </Box>
398
+ )}
388
399
  </Box>
389
400
  </Backdrop>
390
401
  );
@@ -396,26 +407,22 @@ export class NotificationMU extends NotificationReact {
396
407
  * @param className Style class name
397
408
  * @param classes Style classes
398
409
  */
399
- render(
400
- props: NotificationRenderProps,
401
- className: string,
402
- classes: ClassNameMap<string>
403
- ) {
410
+ render(props: NotificationRenderProps, className: string) {
404
411
  // Loading bar
405
412
  if (this.type === NotificationType.Loading) {
406
- return this.createLoading(props, className, classes);
413
+ return this.createLoading(props, className);
407
414
  } else if (this.type === NotificationType.Confirm) {
408
- return this.createConfirm(props, className, classes);
415
+ return this.createConfirm(props, className);
409
416
  } else if (this.type === NotificationType.Prompt) {
410
- return this.createPrompt(props, className, classes);
417
+ return this.createPrompt(props, className);
411
418
  } else if (
412
419
  this.type === NotificationType.Error ||
413
420
  (this.modal && this.type in NotificationMessageType)
414
421
  ) {
415
422
  // Alert or modal message
416
- return this.createAlert(props, className, classes);
423
+ return this.createAlert(props, className);
417
424
  } else {
418
- return this.createMessage(props, className, classes);
425
+ return this.createMessage(props, className);
419
426
  }
420
427
  }
421
428
  }
@@ -499,8 +506,7 @@ export class NotifierMU extends NotifierReact {
499
506
  */
500
507
  protected createContainer = (
501
508
  align: NotificationAlign,
502
- children: React.ReactNode[],
503
- _options: ClassNameMap<string>
509
+ children: React.ReactNode[]
504
510
  ) => {
505
511
  // Each align group, class equal to something similar to 'align-topleft'
506
512
  const alignText = NotificationAlign[align].toLowerCase();
@@ -555,7 +561,7 @@ export class NotifierMU extends NotifierReact {
555
561
  * @param modal Show as modal
556
562
  */
557
563
  protected addRaw(
558
- data: INotificaseBase,
564
+ data: INotificaseBase<NotificationReactCallProps>,
559
565
  modal?: boolean
560
566
  ): INotificationReact {
561
567
  // Destruct
@@ -1,3 +1,5 @@
1
+ import { Breakpoint } from '@mui/material';
2
+
1
3
  /**
2
4
  * Notifier prompt props
3
5
  */