@jasperoosthoek/react-toolbox 0.8.1 → 0.9.1

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 (63) hide show
  1. package/change-log.md +330 -312
  2. package/dist/components/buttons/ConfirmButton.d.ts +2 -2
  3. package/dist/components/buttons/DeleteConfirmButton.d.ts +2 -2
  4. package/dist/components/buttons/IconButtons.d.ts +40 -41
  5. package/dist/components/errors/Errors.d.ts +1 -2
  6. package/dist/components/forms/FormField.d.ts +22 -0
  7. package/dist/components/forms/FormFields.d.ts +1 -56
  8. package/dist/components/forms/FormModal.d.ts +7 -34
  9. package/dist/components/forms/FormModalProvider.d.ts +25 -15
  10. package/dist/components/forms/FormProvider.d.ts +66 -0
  11. package/dist/components/forms/fields/FormBadgesSelection.d.ts +26 -0
  12. package/dist/components/forms/fields/FormCheckbox.d.ts +7 -0
  13. package/dist/components/forms/fields/FormDropdown.d.ts +19 -0
  14. package/dist/components/forms/fields/FormInput.d.ts +17 -0
  15. package/dist/components/forms/fields/FormSelect.d.ts +12 -0
  16. package/dist/components/forms/fields/index.d.ts +5 -0
  17. package/dist/components/indicators/CheckIndicator.d.ts +1 -2
  18. package/dist/components/indicators/LoadingIndicator.d.ts +4 -4
  19. package/dist/components/login/LoginPage.d.ts +1 -1
  20. package/dist/components/tables/DataTable.d.ts +2 -2
  21. package/dist/components/tables/DragAndDropList.d.ts +2 -2
  22. package/dist/components/tables/SearchBox.d.ts +2 -2
  23. package/dist/index.d.ts +3 -0
  24. package/dist/index.js +2 -2
  25. package/dist/index.js.LICENSE.txt +0 -4
  26. package/dist/localization/LocalizationContext.d.ts +1 -1
  27. package/dist/utils/hooks.d.ts +1 -1
  28. package/dist/utils/timeAndDate.d.ts +5 -2
  29. package/dist/utils/utils.d.ts +3 -3
  30. package/package.json +10 -11
  31. package/src/__tests__/buttons.test.tsx +545 -0
  32. package/src/__tests__/errors.test.tsx +339 -0
  33. package/src/__tests__/forms.test.tsx +3021 -0
  34. package/src/__tests__/hooks.test.tsx +413 -0
  35. package/src/__tests__/indicators.test.tsx +284 -0
  36. package/src/__tests__/localization.test.tsx +462 -0
  37. package/src/__tests__/login.test.tsx +417 -0
  38. package/src/__tests__/setupTests.ts +328 -0
  39. package/src/__tests__/tables.test.tsx +609 -0
  40. package/src/__tests__/timeAndDate.test.tsx +308 -0
  41. package/src/__tests__/utils.test.tsx +422 -0
  42. package/src/components/forms/FormField.tsx +92 -0
  43. package/src/components/forms/FormFields.tsx +3 -423
  44. package/src/components/forms/FormModal.tsx +168 -243
  45. package/src/components/forms/FormModalProvider.tsx +164 -85
  46. package/src/components/forms/FormProvider.tsx +218 -0
  47. package/src/components/forms/fields/FormBadgesSelection.tsx +108 -0
  48. package/src/components/forms/fields/FormCheckbox.tsx +76 -0
  49. package/src/components/forms/fields/FormDropdown.tsx +123 -0
  50. package/src/components/forms/fields/FormInput.tsx +114 -0
  51. package/src/components/forms/fields/FormSelect.tsx +47 -0
  52. package/src/components/forms/fields/index.ts +6 -0
  53. package/src/index.ts +32 -29
  54. package/src/localization/LocalizationContext.tsx +156 -131
  55. package/src/localization/localization.ts +131 -131
  56. package/src/utils/hooks.ts +108 -94
  57. package/src/utils/timeAndDate.ts +33 -4
  58. package/src/utils/utils.ts +74 -66
  59. package/dist/components/forms/CreateEditModal.d.ts +0 -41
  60. package/dist/components/forms/CreateEditModalProvider.d.ts +0 -41
  61. package/dist/components/forms/FormFields.test.d.ts +0 -4
  62. package/dist/login/Login.d.ts +0 -70
  63. package/src/components/forms/FormFields.test.tsx +0 -107
@@ -1,131 +1,156 @@
1
- import React, { useState, useContext } from 'react';
2
- import LocalizedStrings from 'react-localization';
3
- import {
4
- defaultLocalization,
5
- AdditionalLocalization,
6
- LocalizationElement,
7
- LocalizationFunction,
8
- defaultLanguages,
9
- } from './localization';
10
-
11
- const out_of_context_error = 'This function should only be used in a child of LocalizationProvider.';
12
-
13
- export const combineLocalization = (...locals: AdditionalLocalization[]) => {
14
- // Extract all unique language keys
15
- const languages = [...new Set(locals.flatMap(Object.keys))];
16
-
17
- return languages.reduce(
18
- (o, lang) => ({
19
- ...o,
20
- [lang]: locals.reduce<LocalizationElement>(
21
- (acc, l) => ({ ...acc, ...(l[lang] || {}) }),
22
- {} as LocalizationElement
23
- ),
24
- }),
25
- {} as AdditionalLocalization
26
- );
27
- };
28
-
29
- export const LocalizationContext = React.createContext({
30
- lang: 'en',
31
- languages: Object.keys(defaultLanguages),
32
- setLanguage: (lang: string) => console.error(out_of_context_error),
33
- text: (str: TemplateStringsArray, ...values: (string | number)[]) => {
34
- console.error(out_of_context_error);
35
- return str[0];
36
- },
37
- textByLang: (lang: string) => (str: TemplateStringsArray, ...values: (string | number)[]) => {
38
- console.error(out_of_context_error);
39
- return str[0];
40
- },
41
- strings: new LocalizedStrings({ en: {} }),
42
- localizationStrings: {} as AdditionalLocalization,
43
- setLocalization: (localization: AdditionalLocalization) => console.error(out_of_context_error),
44
- });
45
-
46
- export type RestProps = {
47
- [prop: string]: any;
48
- }
49
- export interface LocalizationProviderProps extends RestProps {
50
- lang?: string;
51
- localization?: AdditionalLocalization;
52
- languages?: string[];
53
- children?: any;
54
- [prop: string]: any;
55
- }
56
-
57
- export const LocalizationProvider = ({
58
- lang: initialLanguage = 'en',
59
- localization: additionalLocalizationInitial = {},
60
- languages: languagesOverride,
61
- children,
62
- ...restProps
63
- }: LocalizationProviderProps) => {
64
- const [additionalLocalization, setLocalization] = useState(additionalLocalizationInitial);
65
- const [lang, setLanguage] = useState(initialLanguage);
66
- const languages = Array.from(new Set([
67
- ...languagesOverride || Object.keys(defaultLocalization),
68
- ...Object.keys(additionalLocalization),
69
- ]));
70
- const localizationStrings = languages.reduce(
71
- (o, lang) => ({
72
- ...o,
73
- [lang]: {
74
- ...defaultLocalization[lang] || {},
75
- ...additionalLocalization[lang] || {},
76
- },
77
- }),
78
- {}
79
- );
80
-
81
- const strings = new LocalizedStrings(localizationStrings);
82
- strings.setLanguage(lang);
83
-
84
- const textByLang = (lang: string) => (str: TemplateStringsArray, ...values: (string | number)[]) => {
85
- const text_or_func = strings.getString(str[0], lang) as string | LocalizationFunction;
86
- if (!text_or_func) {
87
- console.error(`Language string not found: "${str[0]}"`);
88
- return str[0];
89
- } else if (typeof text_or_func === 'function') {
90
- if (text_or_func.length !== values.length) {
91
- console.error(
92
- `Language function "${str[0]}" expects exactly ${text_or_func.length} argument${text_or_func.length === 1 ? '' : 's'}. `
93
- + (
94
- text_or_func.length > 0
95
- ? ` Use text${'`'}${str[0]}${'${arg1}${arg2}`'}`
96
- : ` Use text${'`'}${str[0]}${'`'}`
97
- )
98
- );
99
- return text_or_func.length > 0 ? `${str[0]}${'${arg1}${arg2}'}` : str[0];
100
- }
101
- return text_or_func(...values);
102
- }
103
-
104
- return text_or_func;
105
- }
106
- return (
107
- <LocalizationContext.Provider
108
- value={{
109
- lang,
110
- languages,
111
- setLanguage: (lang: string) => {
112
- if (!languages.includes(lang)) {
113
- console.error(`Language ${lang} not available`);
114
- return;
115
- }
116
- setLanguage(lang);
117
- },
118
- strings,
119
- text: textByLang(lang),
120
- textByLang,
121
- localizationStrings,
122
- setLocalization,
123
- ...restProps,
124
- }}
125
- >
126
- {children}
127
- </LocalizationContext.Provider>
128
- );
129
- };
130
-
131
- export const useLocalization = () => useContext(LocalizationContext);
1
+ import React, { useState, useContext, useEffect, useMemo } from 'react';
2
+ import LocalizedStrings from 'react-localization';
3
+ import {
4
+ defaultLocalization,
5
+ AdditionalLocalization,
6
+ LocalizationElement,
7
+ LocalizationFunction,
8
+ defaultLanguages,
9
+ } from './localization';
10
+
11
+ const out_of_context_error = 'This function should only be used in a child of LocalizationProvider.';
12
+
13
+ export const combineLocalization = (...locals: AdditionalLocalization[]) => {
14
+ if (locals.length === 0) {
15
+ return {} as AdditionalLocalization;
16
+ }
17
+
18
+ // Filter out empty objects
19
+ const validLocals = locals.filter(local => local && Object.keys(local).length > 0);
20
+
21
+ if (validLocals.length === 0) {
22
+ return {} as AdditionalLocalization;
23
+ }
24
+
25
+ // Extract all unique language keys
26
+ const languages = [...new Set(validLocals.flatMap(Object.keys))];
27
+
28
+ return languages.reduce(
29
+ (o, lang) => ({
30
+ ...o,
31
+ [lang]: validLocals.reduce<LocalizationElement>(
32
+ (acc, l) => ({ ...acc, ...(l[lang] || {}) }),
33
+ {} as LocalizationElement
34
+ ),
35
+ }),
36
+ {} as AdditionalLocalization
37
+ );
38
+ };
39
+
40
+ export const LocalizationContext = React.createContext({
41
+ lang: 'en',
42
+ languages: Object.keys(defaultLanguages),
43
+ setLanguage: (lang: string) => console.error(out_of_context_error),
44
+ text: (str: TemplateStringsArray, ...values: (string | number)[]) => {
45
+ console.error(out_of_context_error);
46
+ return str[0];
47
+ },
48
+ textByLang: (lang: string) => (str: TemplateStringsArray, ...values: (string | number)[]) => {
49
+ console.error(out_of_context_error);
50
+ return str[0];
51
+ },
52
+ strings: new LocalizedStrings({ en: {} }),
53
+ localizationStrings: {} as AdditionalLocalization,
54
+ setLocalization: (localization: AdditionalLocalization) => console.error(out_of_context_error),
55
+ });
56
+
57
+ export type RestProps = {
58
+ [prop: string]: any;
59
+ }
60
+ export interface LocalizationProviderProps extends RestProps {
61
+ lang?: string;
62
+ localization?: AdditionalLocalization;
63
+ languages?: string[];
64
+ children?: any;
65
+ [prop: string]: any;
66
+ }
67
+
68
+ export const LocalizationProvider = ({
69
+ lang: initialLanguage = 'en',
70
+ localization: additionalLocalizationInitial = {},
71
+ languages: languagesOverride,
72
+ children,
73
+ ...restProps
74
+ }: LocalizationProviderProps) => {
75
+ const [additionalLocalization, setAdditionalLocalization] = useState(additionalLocalizationInitial);
76
+ const [lang, setLanguage] = useState(initialLanguage);
77
+
78
+ const languages = Array.from(new Set([
79
+ ...languagesOverride || Object.keys(defaultLocalization),
80
+ ...Object.keys(additionalLocalization),
81
+ ]));
82
+
83
+ const localizationStrings = useMemo(() => {
84
+ return languages.reduce(
85
+ (o, lang) => ({
86
+ ...o,
87
+ [lang]: {
88
+ ...defaultLocalization[lang] || {},
89
+ ...additionalLocalization[lang] || {},
90
+ },
91
+ }),
92
+ {}
93
+ );
94
+ }, [languages, additionalLocalization]);
95
+
96
+ const strings = useMemo(() => {
97
+ const localizedStrings = new LocalizedStrings(localizationStrings);
98
+ localizedStrings.setLanguage(lang);
99
+ return localizedStrings;
100
+ }, [localizationStrings, lang]);
101
+
102
+ const setLocalization = (newLocalization: AdditionalLocalization) => {
103
+ setAdditionalLocalization(prev => {
104
+ const merged = combineLocalization(prev, newLocalization);
105
+ return merged;
106
+ });
107
+ };
108
+
109
+ const textByLang = (lang: string) => (str: TemplateStringsArray, ...values: (string | number)[]) => {
110
+ const text_or_func = strings.getString(str[0], lang) as string | LocalizationFunction;
111
+ if (!text_or_func) {
112
+ console.error(`Language string not found: "${str[0]}"`);
113
+ return str[0];
114
+ } else if (typeof text_or_func === 'function') {
115
+ if (text_or_func.length !== values.length) {
116
+ console.error(
117
+ `Language function "${str[0]}" expects exactly ${text_or_func.length} argument${text_or_func.length === 1 ? '' : 's'}. `
118
+ + (
119
+ text_or_func.length > 0
120
+ ? ` Use text${'`'}${str[0]}${'${arg1}${arg2}`'}`
121
+ : ` Use text${'`'}${str[0]}${'`'}`
122
+ )
123
+ );
124
+ return text_or_func.length > 0 ? `${str[0]}${'${arg1}${arg2}'}` : str[0];
125
+ }
126
+ return text_or_func(...values);
127
+ }
128
+
129
+ return text_or_func;
130
+ }
131
+ return (
132
+ <LocalizationContext.Provider
133
+ value={{
134
+ lang,
135
+ languages,
136
+ setLanguage: (newLang: string) => {
137
+ if (!languages.includes(newLang)) {
138
+ console.error(`Language ${newLang} not available`);
139
+ return;
140
+ }
141
+ setLanguage(newLang);
142
+ },
143
+ strings,
144
+ text: textByLang(lang),
145
+ textByLang,
146
+ localizationStrings,
147
+ setLocalization,
148
+ ...restProps,
149
+ }}
150
+ >
151
+ {children}
152
+ </LocalizationContext.Provider>
153
+ );
154
+ };
155
+
156
+ export const useLocalization = () => useContext(LocalizationContext);
@@ -1,131 +1,131 @@
1
- export type LocalizationFunction = (...args: (string | number)[]) => string;
2
-
3
- export type LocalizationElement = {
4
- [languageString: string]: (string | LocalizationFunction)
5
- }
6
-
7
- export type AdditionalLocalization = {
8
- [lang: string]: LocalizationElement;
9
- }
10
-
11
- export interface LocalizationStrings {
12
- select: string;
13
- search: string;
14
- no_information_to_display: string;
15
- information_is_being_loaded: string;
16
- delete: string;
17
- are_you_sure: string;
18
- close: string;
19
- save: string;
20
- cancel: string;
21
- ok: string;
22
- your_email: string;
23
- enter_email: string;
24
- your_password: string;
25
- enter_password: string;
26
- login: string;
27
- logout: string;
28
- forgot_password: string;
29
- reset_password: string;
30
- required_field: string;
31
- choose_one: string;
32
- everything: string;
33
- number_of_rows: string;
34
- modal_create: string;
35
- modal_edit: string;
36
- }
37
-
38
- export type Localization = {
39
- [lang: string]: LocalizationStrings;
40
- }
41
-
42
- export type Languages = {
43
- [languageIso: string]: string;
44
- }
45
- export const defaultLanguages: Languages = {
46
- en: "English",
47
- fr: "Français",
48
- nl: "Nederlands",
49
- } as const;
50
-
51
- export const defaultLocalization: Localization = {
52
- en: {
53
- select: "Select",
54
- search: "Search",
55
- no_information_to_display: "No information to display",
56
- information_is_being_loaded: "The information is being loaded...",
57
- delete: "Delete",
58
- are_you_sure: "Are you sure?",
59
- close: "Close",
60
- save: "Save",
61
- cancel: "Cancel",
62
- ok: "OK",
63
- your_email: "Your email",
64
- enter_email: "Enter email address",
65
- your_password: "Your password",
66
- enter_password: "Enter password",
67
- login: "Login",
68
- logout: "Logout",
69
- forgot_password: "Forgot password?",
70
- reset_password: "Reset password",
71
- required_field: "required",
72
- choose_one: "Choose one",
73
- everything: "Everything",
74
- number_of_rows: "Number of rows",
75
- modal_create: 'New',
76
- modal_edit: 'Edit',
77
- },
78
- fr: {
79
- no_information_to_display: "Sélectionner",
80
- select: "Recherche",
81
- search: "Aucune information à afficher",
82
- information_is_being_loaded: "L'information est en cours de téléchargement...",
83
- delete: "Supprimer",
84
- are_you_sure: "Es-tu sûr?",
85
- close: "Fermer",
86
- save: "Sauvegarder",
87
- cancel: "Annuler",
88
- ok: "D'accord'",
89
- your_email: "Votre adresse e-mail",
90
- enter_email: "Entrez l'adresse e-mail",
91
- your_password: "Votre mot de passe",
92
- enter_password: "Entrez votre mot de passe",
93
- login: "Connexion",
94
- logout: "Se déconnecter",
95
- forgot_password: "Mot de passe oublié?",
96
- reset_password: "Réinitialiser le mot de passe",
97
- required_field: "requis",
98
- choose_one: "Choisissez-en un",
99
- number_of_rows: "Tout",
100
- everything: "Nombre de rangées",
101
- modal_create: 'Nouveau',
102
- modal_edit: 'Éditer',
103
- },
104
- nl: {
105
- no_information_to_display: "Geen informatie om weer te geven.",
106
- select: "Selecteer",
107
- search: "Zoeken",
108
- information_is_being_loaded: "De gegevens worden geladen...",
109
- delete: "Verwijderen",
110
- are_you_sure: "Weet u het zeker?",
111
- close: "Sluiten",
112
- save: "Opslaan",
113
- cancel: "Annuleren",
114
- ok: "OK",
115
- your_email: "Uw e-mail",
116
- enter_email: "Voer e-mailadres in",
117
- your_password: "Uw wachtwoord",
118
- enter_password: "Voer wachtwoord in",
119
- login: "Inloggen",
120
- logout: "Uitloggen",
121
- forgot_password: "Wachtwoord vergeten?",
122
- reset_password: "Wachtwoord resetten",
123
- required_field: "verplicht",
124
- choose_one: "Maak een keuze",
125
- number_of_rows: "Aantal rijen",
126
- everything: "Alles",
127
- modal_create: 'Nieuw',
128
- modal_edit: 'Bewerken',
129
- },
130
- } as const;
131
-
1
+ export type LocalizationFunction = (...args: (string | number)[]) => string;
2
+
3
+ export type LocalizationElement = {
4
+ [languageString: string]: (string | LocalizationFunction)
5
+ }
6
+
7
+ export type AdditionalLocalization = {
8
+ [lang: string]: LocalizationElement;
9
+ }
10
+
11
+ export interface LocalizationStrings {
12
+ select: string;
13
+ search: string;
14
+ no_information_to_display: string;
15
+ information_is_being_loaded: string;
16
+ delete: string;
17
+ are_you_sure: string;
18
+ close: string;
19
+ save: string;
20
+ cancel: string;
21
+ ok: string;
22
+ your_email: string;
23
+ enter_email: string;
24
+ your_password: string;
25
+ enter_password: string;
26
+ login: string;
27
+ logout: string;
28
+ forgot_password: string;
29
+ reset_password: string;
30
+ required_field: string;
31
+ choose_one: string;
32
+ everything: string;
33
+ number_of_rows: string;
34
+ modal_create: string;
35
+ modal_edit: string;
36
+ }
37
+
38
+ export type Localization = {
39
+ [lang: string]: LocalizationStrings;
40
+ }
41
+
42
+ export type Languages = {
43
+ [languageIso: string]: string;
44
+ }
45
+ export const defaultLanguages: Languages = {
46
+ en: "English",
47
+ fr: "Français",
48
+ nl: "Nederlands",
49
+ } as const;
50
+
51
+ export const defaultLocalization: Localization = {
52
+ en: {
53
+ select: "Select",
54
+ search: "Search",
55
+ no_information_to_display: "No information to display",
56
+ information_is_being_loaded: "The information is being loaded...",
57
+ delete: "Delete",
58
+ are_you_sure: "Are you sure?",
59
+ close: "Close",
60
+ save: "Save",
61
+ cancel: "Cancel",
62
+ ok: "OK",
63
+ your_email: "Your email",
64
+ enter_email: "Enter email address",
65
+ your_password: "Your password",
66
+ enter_password: "Enter password",
67
+ login: "Login",
68
+ logout: "Logout",
69
+ forgot_password: "Forgot password?",
70
+ reset_password: "Reset password",
71
+ required_field: "required",
72
+ choose_one: "Choose one",
73
+ everything: "Everything",
74
+ number_of_rows: "Number of rows",
75
+ modal_create: 'New',
76
+ modal_edit: 'Edit',
77
+ },
78
+ fr: {
79
+ select: "Sélectionner",
80
+ search: "Recherche",
81
+ no_information_to_display: "Aucune information à afficher",
82
+ information_is_being_loaded: "L'information est en cours de téléchargement...",
83
+ delete: "Supprimer",
84
+ are_you_sure: "Êtes-vous sûr?",
85
+ close: "Fermer",
86
+ save: "Sauvegarder",
87
+ cancel: "Annuler",
88
+ ok: "D'accord'",
89
+ your_email: "Votre adresse e-mail",
90
+ enter_email: "Entrez l'adresse e-mail",
91
+ your_password: "Votre mot de passe",
92
+ enter_password: "Entrez votre mot de passe",
93
+ login: "Connexion",
94
+ logout: "Se déconnecter",
95
+ forgot_password: "Mot de passe oublié?",
96
+ reset_password: "Réinitialiser le mot de passe",
97
+ required_field: "requis",
98
+ choose_one: "Choisissez-en un",
99
+ everything: "Tout",
100
+ number_of_rows: "Nombre de rangées",
101
+ modal_create: 'Nouveau',
102
+ modal_edit: 'Éditer',
103
+ },
104
+ nl: {
105
+ select: "Selecteer",
106
+ search: "Zoeken",
107
+ no_information_to_display: "Geen informatie om weer te geven.",
108
+ information_is_being_loaded: "De gegevens worden geladen...",
109
+ delete: "Verwijderen",
110
+ are_you_sure: "Weet u het zeker?",
111
+ close: "Sluiten",
112
+ save: "Opslaan",
113
+ cancel: "Annuleren",
114
+ ok: "OK",
115
+ your_email: "Uw e-mail",
116
+ enter_email: "Voer e-mailadres in",
117
+ your_password: "Uw wachtwoord",
118
+ enter_password: "Voer wachtwoord in",
119
+ login: "Inloggen",
120
+ logout: "Uitloggen",
121
+ forgot_password: "Wachtwoord vergeten?",
122
+ reset_password: "Wachtwoord resetten",
123
+ required_field: "verplicht",
124
+ choose_one: "Maak een keuze",
125
+ everything: "Alles",
126
+ number_of_rows: "Aantal rijen",
127
+ modal_create: 'Nieuw',
128
+ modal_edit: 'Bewerken',
129
+ },
130
+ } as const;
131
+