@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.
- package/change-log.md +330 -312
- package/dist/components/buttons/ConfirmButton.d.ts +2 -2
- package/dist/components/buttons/DeleteConfirmButton.d.ts +2 -2
- package/dist/components/buttons/IconButtons.d.ts +40 -41
- package/dist/components/errors/Errors.d.ts +1 -2
- package/dist/components/forms/FormField.d.ts +22 -0
- package/dist/components/forms/FormFields.d.ts +1 -56
- package/dist/components/forms/FormModal.d.ts +7 -34
- package/dist/components/forms/FormModalProvider.d.ts +25 -15
- package/dist/components/forms/FormProvider.d.ts +66 -0
- package/dist/components/forms/fields/FormBadgesSelection.d.ts +26 -0
- package/dist/components/forms/fields/FormCheckbox.d.ts +7 -0
- package/dist/components/forms/fields/FormDropdown.d.ts +19 -0
- package/dist/components/forms/fields/FormInput.d.ts +17 -0
- package/dist/components/forms/fields/FormSelect.d.ts +12 -0
- package/dist/components/forms/fields/index.d.ts +5 -0
- package/dist/components/indicators/CheckIndicator.d.ts +1 -2
- package/dist/components/indicators/LoadingIndicator.d.ts +4 -4
- package/dist/components/login/LoginPage.d.ts +1 -1
- package/dist/components/tables/DataTable.d.ts +2 -2
- package/dist/components/tables/DragAndDropList.d.ts +2 -2
- package/dist/components/tables/SearchBox.d.ts +2 -2
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -2
- package/dist/index.js.LICENSE.txt +0 -4
- package/dist/localization/LocalizationContext.d.ts +1 -1
- package/dist/utils/hooks.d.ts +1 -1
- package/dist/utils/timeAndDate.d.ts +5 -2
- package/dist/utils/utils.d.ts +3 -3
- package/package.json +10 -11
- package/src/__tests__/buttons.test.tsx +545 -0
- package/src/__tests__/errors.test.tsx +339 -0
- package/src/__tests__/forms.test.tsx +3021 -0
- package/src/__tests__/hooks.test.tsx +413 -0
- package/src/__tests__/indicators.test.tsx +284 -0
- package/src/__tests__/localization.test.tsx +462 -0
- package/src/__tests__/login.test.tsx +417 -0
- package/src/__tests__/setupTests.ts +328 -0
- package/src/__tests__/tables.test.tsx +609 -0
- package/src/__tests__/timeAndDate.test.tsx +308 -0
- package/src/__tests__/utils.test.tsx +422 -0
- package/src/components/forms/FormField.tsx +92 -0
- package/src/components/forms/FormFields.tsx +3 -423
- package/src/components/forms/FormModal.tsx +168 -243
- package/src/components/forms/FormModalProvider.tsx +164 -85
- package/src/components/forms/FormProvider.tsx +218 -0
- package/src/components/forms/fields/FormBadgesSelection.tsx +108 -0
- package/src/components/forms/fields/FormCheckbox.tsx +76 -0
- package/src/components/forms/fields/FormDropdown.tsx +123 -0
- package/src/components/forms/fields/FormInput.tsx +114 -0
- package/src/components/forms/fields/FormSelect.tsx +47 -0
- package/src/components/forms/fields/index.ts +6 -0
- package/src/index.ts +32 -29
- package/src/localization/LocalizationContext.tsx +156 -131
- package/src/localization/localization.ts +131 -131
- package/src/utils/hooks.ts +108 -94
- package/src/utils/timeAndDate.ts +33 -4
- package/src/utils/utils.ts +74 -66
- package/dist/components/forms/CreateEditModal.d.ts +0 -41
- package/dist/components/forms/CreateEditModalProvider.d.ts +0 -41
- package/dist/components/forms/FormFields.test.d.ts +0 -4
- package/dist/login/Login.d.ts +0 -70
- package/src/components/forms/FormFields.test.tsx +0 -107
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Form } from 'react-bootstrap';
|
|
3
|
+
import { useFormField } from '../FormField';
|
|
4
|
+
|
|
5
|
+
export interface FormCheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'name' | 'value' | 'onChange' | 'type'> {
|
|
6
|
+
name: string;
|
|
7
|
+
label?: React.ReactElement | string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const FormCheckbox = (props: FormCheckboxProps) => {
|
|
11
|
+
const { value, onChange, isInvalid, error, label, required, mergedProps } = useFormField(props);
|
|
12
|
+
|
|
13
|
+
const errorId = isInvalid && error ? `${props.name}-error` : undefined;
|
|
14
|
+
const checkboxId = `${props.name}-checkbox`; // Use different ID to avoid conflict
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<Form.Group controlId={props.name}>
|
|
18
|
+
{isInvalid && error && (
|
|
19
|
+
<Form.Text id={errorId} className="text-danger">
|
|
20
|
+
{error}
|
|
21
|
+
</Form.Text>
|
|
22
|
+
)}
|
|
23
|
+
<Form.Check
|
|
24
|
+
id={checkboxId}
|
|
25
|
+
type="checkbox"
|
|
26
|
+
{...mergedProps}
|
|
27
|
+
checked={!!value}
|
|
28
|
+
isInvalid={isInvalid}
|
|
29
|
+
aria-describedby={errorId}
|
|
30
|
+
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
|
31
|
+
onChange(e.target.checked);
|
|
32
|
+
}}
|
|
33
|
+
label={label ? (
|
|
34
|
+
<span>
|
|
35
|
+
{label}
|
|
36
|
+
{required && ' *'}
|
|
37
|
+
</span>
|
|
38
|
+
) : undefined}
|
|
39
|
+
/>
|
|
40
|
+
</Form.Group>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const FormSwitch = (props: FormCheckboxProps) => {
|
|
45
|
+
const { value, onChange, isInvalid, error, label, required, mergedProps } = useFormField(props);
|
|
46
|
+
|
|
47
|
+
const errorId = isInvalid && error ? `${props.name}-error` : undefined;
|
|
48
|
+
const switchId = `${props.name}-switch`; // Use different ID to avoid conflict
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<Form.Group controlId={props.name}>
|
|
52
|
+
{isInvalid && error && (
|
|
53
|
+
<Form.Text id={errorId} className="text-danger">
|
|
54
|
+
{error}
|
|
55
|
+
</Form.Text>
|
|
56
|
+
)}
|
|
57
|
+
<Form.Check
|
|
58
|
+
id={switchId}
|
|
59
|
+
type="switch"
|
|
60
|
+
{...mergedProps}
|
|
61
|
+
checked={!!value}
|
|
62
|
+
isInvalid={isInvalid}
|
|
63
|
+
aria-describedby={errorId}
|
|
64
|
+
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
|
65
|
+
onChange(e.target.checked);
|
|
66
|
+
}}
|
|
67
|
+
label={label ? (
|
|
68
|
+
<span>
|
|
69
|
+
{label}
|
|
70
|
+
{required && ' *'}
|
|
71
|
+
</span>
|
|
72
|
+
) : undefined}
|
|
73
|
+
/>
|
|
74
|
+
</Form.Group>
|
|
75
|
+
);
|
|
76
|
+
};
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import React, { useMemo, KeyboardEvent } from 'react';
|
|
2
|
+
import { Form } from 'react-bootstrap';
|
|
3
|
+
import { useFormField } from '../FormField';
|
|
4
|
+
import { useLocalization } from '../../../localization/LocalizationContext';
|
|
5
|
+
|
|
6
|
+
type DisabledProps = {
|
|
7
|
+
list: any[];
|
|
8
|
+
value: string | number;
|
|
9
|
+
state: any;
|
|
10
|
+
initialState: any;
|
|
11
|
+
initialValue: any;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface FormDropdownProps<T> extends Omit<
|
|
15
|
+
React.InputHTMLAttributes<HTMLInputElement>,
|
|
16
|
+
'name' | 'value' | 'onChange' | 'disabled' | 'list'
|
|
17
|
+
> {
|
|
18
|
+
name: string;
|
|
19
|
+
label?: React.ReactElement | string;
|
|
20
|
+
list?: T[];
|
|
21
|
+
options?: T[]; // Alias for list
|
|
22
|
+
idKey?: keyof T;
|
|
23
|
+
nameKey?: keyof T;
|
|
24
|
+
disabled?: boolean | ((props: DisabledProps) => boolean);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const FormDropdown = <T,>(props: FormDropdownProps<T>) => {
|
|
28
|
+
const {
|
|
29
|
+
list: listProp,
|
|
30
|
+
options,
|
|
31
|
+
idKey = 'value' as keyof T, // Change default to match test
|
|
32
|
+
nameKey = 'label' as keyof T, // Change default to match test
|
|
33
|
+
disabled,
|
|
34
|
+
...componentProps
|
|
35
|
+
} = props;
|
|
36
|
+
|
|
37
|
+
const { value, onChange, isInvalid, error, label, required, mergedProps, submit } = useFormField(componentProps);
|
|
38
|
+
const { strings } = useLocalization();
|
|
39
|
+
|
|
40
|
+
// Use options or list, with options taking precedence
|
|
41
|
+
const listBase = options || listProp;
|
|
42
|
+
|
|
43
|
+
const [list, mismatch] = useMemo(() => {
|
|
44
|
+
if (!listBase || !Array.isArray(listBase)) {
|
|
45
|
+
return [null, null] as [T[] | null, any];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Handle string arrays by converting them to { value, label } objects
|
|
49
|
+
if (listBase.length > 0 && typeof listBase[0] === 'string') {
|
|
50
|
+
const convertedList = listBase.map((item: any) => ({
|
|
51
|
+
value: item,
|
|
52
|
+
label: item
|
|
53
|
+
})) as unknown as T[];
|
|
54
|
+
return [convertedList, null];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Only validate object arrays
|
|
58
|
+
if (listBase.length > 0 && typeof listBase[0] === 'object') {
|
|
59
|
+
const mismatch = listBase?.find((item: any) => (
|
|
60
|
+
!['number', 'string'].includes(typeof item[idKey])
|
|
61
|
+
|| !['number', 'string'].includes(typeof item[nameKey])
|
|
62
|
+
))
|
|
63
|
+
if (mismatch) return [null, mismatch];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return [listBase, null];
|
|
67
|
+
}, [listBase, idKey, nameKey]);
|
|
68
|
+
|
|
69
|
+
if (!list) {
|
|
70
|
+
console.error(
|
|
71
|
+
`FormDropdown Error:
|
|
72
|
+
- Each item in 'list' must include a valid 'idKey' (${String(idKey)}) and 'nameKey' (${String(nameKey)}).
|
|
73
|
+
- Both keys must exist on every item and be of type 'string' or 'number'.
|
|
74
|
+
- One or more items failed this check.
|
|
75
|
+
|
|
76
|
+
Received list:`,
|
|
77
|
+
listBase,
|
|
78
|
+
...mismatch ? ['First mismatch:', mismatch] : []
|
|
79
|
+
);
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const selectedItem = list.find(item => item[idKey] === value);
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<Form.Group controlId={props.name}>
|
|
87
|
+
{label && <Form.Label htmlFor={props.name}>{label}{required && ' *'}</Form.Label>}
|
|
88
|
+
{isInvalid && error && (
|
|
89
|
+
<Form.Text className="text-danger">
|
|
90
|
+
{error}
|
|
91
|
+
</Form.Text>
|
|
92
|
+
)}
|
|
93
|
+
|
|
94
|
+
<Form.Select
|
|
95
|
+
id={props.name}
|
|
96
|
+
value={value || ''}
|
|
97
|
+
isInvalid={isInvalid}
|
|
98
|
+
onChange={(e) => onChange(e.target.value)}
|
|
99
|
+
onKeyDown={(e: KeyboardEvent<HTMLSelectElement>) => {
|
|
100
|
+
if (e.key === 'Enter') {
|
|
101
|
+
e.preventDefault();
|
|
102
|
+
submit();
|
|
103
|
+
}
|
|
104
|
+
}}
|
|
105
|
+
{...mergedProps}
|
|
106
|
+
>
|
|
107
|
+
{list.map((item, key) =>
|
|
108
|
+
<option
|
|
109
|
+
key={key}
|
|
110
|
+
value={item[idKey] as string | number}
|
|
111
|
+
disabled={
|
|
112
|
+
typeof disabled === 'function'
|
|
113
|
+
? disabled({ list, value: item[idKey] as number | string, state: {}, initialState: {}, initialValue: '' })
|
|
114
|
+
: disabled
|
|
115
|
+
}
|
|
116
|
+
>
|
|
117
|
+
{item[nameKey] as string}
|
|
118
|
+
</option>
|
|
119
|
+
)}
|
|
120
|
+
</Form.Select>
|
|
121
|
+
</Form.Group>
|
|
122
|
+
);
|
|
123
|
+
};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import React, { ChangeEvent, KeyboardEvent } from 'react';
|
|
2
|
+
import { Form } from 'react-bootstrap';
|
|
3
|
+
import { useFormField } from '../FormField';
|
|
4
|
+
|
|
5
|
+
export interface FormInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'name' | 'onChange'> {
|
|
6
|
+
name: string;
|
|
7
|
+
label?: React.ReactElement | string;
|
|
8
|
+
as?: string; // For textarea, select, etc.
|
|
9
|
+
rows?: number; // For textarea
|
|
10
|
+
onChange: (value: string) => void;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const FormInput = (props: FormInputProps) => {
|
|
14
|
+
const { value, onChange, isInvalid, error, label, required, mergedProps, submit } = useFormField(props);
|
|
15
|
+
|
|
16
|
+
const errorId = isInvalid && error ? `${props.name}-error` : undefined;
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<Form.Group controlId={props.name}>
|
|
20
|
+
{label && <Form.Label htmlFor={props.name}>{label}{required && ' *'}</Form.Label>}
|
|
21
|
+
{isInvalid && error && (
|
|
22
|
+
<Form.Text id={errorId} className="text-danger">
|
|
23
|
+
{error}
|
|
24
|
+
</Form.Text>
|
|
25
|
+
)}
|
|
26
|
+
<Form.Control
|
|
27
|
+
id={props.name}
|
|
28
|
+
autoComplete="off"
|
|
29
|
+
{...mergedProps}
|
|
30
|
+
value={value || ''}
|
|
31
|
+
isInvalid={isInvalid}
|
|
32
|
+
aria-describedby={errorId}
|
|
33
|
+
onChange={(e: ChangeEvent<HTMLInputElement>) => {
|
|
34
|
+
onChange(e.target.value);
|
|
35
|
+
}}
|
|
36
|
+
onKeyDown={(e: KeyboardEvent<HTMLInputElement>) => {
|
|
37
|
+
if (e.key === 'Enter' && mergedProps.as !== 'textarea') {
|
|
38
|
+
// Pressing the enter key will save data unless it is a multi line text area
|
|
39
|
+
e.preventDefault();
|
|
40
|
+
submit();
|
|
41
|
+
}
|
|
42
|
+
}}
|
|
43
|
+
/>
|
|
44
|
+
</Form.Group>
|
|
45
|
+
);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const FormTextarea = ({ rows = 3, ...props }: FormInputProps) => (
|
|
49
|
+
<FormInput as="textarea" rows={rows} {...props} />
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
export const FormDate = (props: FormInputProps) => (
|
|
53
|
+
<FormInput type="date" {...props} />
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
export interface FormDateTimeProps extends Omit<FormInputProps, 'value' | 'onChange'> {
|
|
57
|
+
value?: string | Date;
|
|
58
|
+
onChange?: (value: string) => void;
|
|
59
|
+
timezone?: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export const FormDateTime = ({ value, onChange, timezone, ...props }: FormDateTimeProps) => {
|
|
63
|
+
// Convert value to datetime-local format (YYYY-MM-DDTHH:mm)
|
|
64
|
+
const formatForInput = (val: string | Date | undefined) => {
|
|
65
|
+
if (!val) return '';
|
|
66
|
+
|
|
67
|
+
try {
|
|
68
|
+
const date = typeof val === 'string' ? new Date(val) : val;
|
|
69
|
+
if (isNaN(date.getTime())) return '';
|
|
70
|
+
|
|
71
|
+
// Format as YYYY-MM-DDTHH:mm for datetime-local input
|
|
72
|
+
const year = date.getFullYear();
|
|
73
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
74
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
75
|
+
const hours = String(date.getHours()).padStart(2, '0');
|
|
76
|
+
const minutes = String(date.getMinutes()).padStart(2, '0');
|
|
77
|
+
|
|
78
|
+
return `${year}-${month}-${day}T${hours}:${minutes}`;
|
|
79
|
+
} catch {
|
|
80
|
+
return '';
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const handleChange = (inputValue: string) => {
|
|
85
|
+
if (!onChange) return;
|
|
86
|
+
|
|
87
|
+
if (!inputValue) {
|
|
88
|
+
onChange('');
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
// Convert datetime-local value to ISO string
|
|
94
|
+
const date = new Date(inputValue);
|
|
95
|
+
if (isNaN(date.getTime())) {
|
|
96
|
+
onChange('');
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
onChange(date.toISOString());
|
|
101
|
+
} catch {
|
|
102
|
+
onChange('');
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
return (
|
|
107
|
+
<FormInput
|
|
108
|
+
type="datetime-local"
|
|
109
|
+
value={formatForInput(value)}
|
|
110
|
+
onChange={handleChange}
|
|
111
|
+
{...props}
|
|
112
|
+
/>
|
|
113
|
+
);
|
|
114
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Form } from 'react-bootstrap';
|
|
3
|
+
import { useFormField } from '../FormField';
|
|
4
|
+
|
|
5
|
+
export interface FormSelectProps extends Omit<React.SelectHTMLAttributes<HTMLSelectElement>, 'name' | 'value' | 'onChange'> {
|
|
6
|
+
name: string;
|
|
7
|
+
label?: React.ReactElement | string;
|
|
8
|
+
options: Array<{ value: string | number; label: string; disabled?: boolean }>;
|
|
9
|
+
placeholder?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const FormSelect = (props: FormSelectProps) => {
|
|
13
|
+
const { value, onChange, isInvalid, error, label, required, mergedProps } = useFormField(props);
|
|
14
|
+
const { options, placeholder = "Choose..." } = props;
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<Form.Group controlId={props.name}>
|
|
18
|
+
{label && <Form.Label>{label}{required && ' *'}</Form.Label>}
|
|
19
|
+
{isInvalid && error && (
|
|
20
|
+
<Form.Text className="text-danger">
|
|
21
|
+
{error}
|
|
22
|
+
</Form.Text>
|
|
23
|
+
)}
|
|
24
|
+
<Form.Select
|
|
25
|
+
{...mergedProps}
|
|
26
|
+
value={value || ''}
|
|
27
|
+
isInvalid={isInvalid}
|
|
28
|
+
onChange={(e: React.ChangeEvent<HTMLSelectElement>) => {
|
|
29
|
+
onChange(e.target.value);
|
|
30
|
+
}}
|
|
31
|
+
>
|
|
32
|
+
<option value="" disabled>
|
|
33
|
+
{placeholder}
|
|
34
|
+
</option>
|
|
35
|
+
{options.map((option, index) => (
|
|
36
|
+
<option
|
|
37
|
+
key={index}
|
|
38
|
+
value={option.value}
|
|
39
|
+
disabled={option.disabled}
|
|
40
|
+
>
|
|
41
|
+
{option.label}
|
|
42
|
+
</option>
|
|
43
|
+
))}
|
|
44
|
+
</Form.Select>
|
|
45
|
+
</Form.Group>
|
|
46
|
+
);
|
|
47
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -1,29 +1,32 @@
|
|
|
1
|
-
export * from './components/buttons/IconButtons';
|
|
2
|
-
export * from './components/buttons/ConfirmButton';
|
|
3
|
-
export { default as ConfirmButton } from './components/buttons/ConfirmButton';
|
|
4
|
-
export { default as DeleteConfirmButton } from './components/buttons/DeleteConfirmButton';
|
|
5
|
-
export * from './components/buttons/DeleteConfirmButton';
|
|
6
|
-
|
|
7
|
-
export * from './components/forms/
|
|
8
|
-
export * from './components/forms/
|
|
9
|
-
export * from './components/forms/
|
|
10
|
-
|
|
11
|
-
export * from './components/
|
|
12
|
-
export * from './components/
|
|
13
|
-
|
|
14
|
-
export * from './components/
|
|
15
|
-
export * from './components/
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
export * from './components/
|
|
19
|
-
export * from './components/
|
|
20
|
-
|
|
21
|
-
export * from './components/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
export * from './
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
export * from './
|
|
29
|
-
|
|
1
|
+
export * from './components/buttons/IconButtons';
|
|
2
|
+
export * from './components/buttons/ConfirmButton';
|
|
3
|
+
export { default as ConfirmButton } from './components/buttons/ConfirmButton';
|
|
4
|
+
export { default as DeleteConfirmButton } from './components/buttons/DeleteConfirmButton';
|
|
5
|
+
export * from './components/buttons/DeleteConfirmButton';
|
|
6
|
+
|
|
7
|
+
export * from './components/forms/FormProvider';
|
|
8
|
+
export * from './components/forms/FormModal';
|
|
9
|
+
export * from './components/forms/FormModalProvider';
|
|
10
|
+
export * from './components/forms/FormFields';
|
|
11
|
+
export * from './components/forms/FormField';
|
|
12
|
+
export * from './components/forms/fields';
|
|
13
|
+
|
|
14
|
+
export * from './components/indicators/LoadingIndicator';
|
|
15
|
+
export * from './components/indicators/CheckIndicator';
|
|
16
|
+
|
|
17
|
+
export * from './components/tables/DataTable';
|
|
18
|
+
export * from './components/tables/DragAndDropList';
|
|
19
|
+
export * from './components/tables/SearchBox';
|
|
20
|
+
|
|
21
|
+
export * from './components/errors/Errors';
|
|
22
|
+
export * from './components/errors/ErrorBoundary';
|
|
23
|
+
|
|
24
|
+
export * from './components/login/LoginPage';
|
|
25
|
+
|
|
26
|
+
export * from './utils/hooks';
|
|
27
|
+
export * from './utils/timeAndDate';
|
|
28
|
+
export * from './utils/utils';
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
export * from './localization/localization';
|
|
32
|
+
export * from './localization/LocalizationContext';
|