@abidibo/react-cam-roi 0.0.13 → 0.2.0
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/README.md +22 -33
- package/package.json +28 -1
- package/dist/Components/BoolField/BoolField.module.css +0 -60
- package/dist/Components/BoolField/index.d.ts +0 -5
- package/dist/Components/BoolField/index.js +0 -13
- package/dist/Components/Button/Button.module.css +0 -29
- package/dist/Components/Button/index.d.ts +0 -8
- package/dist/Components/Button/index.js +0 -15
- package/dist/Components/EnumField/EnumField.module.css +0 -61
- package/dist/Components/EnumField/index.d.ts +0 -10
- package/dist/Components/EnumField/index.js +0 -16
- package/dist/Components/IconButton/IconButton.module.css +0 -20
- package/dist/Components/IconButton/index.d.ts +0 -7
- package/dist/Components/IconButton/index.js +0 -10
- package/dist/Components/Loader/Loader.module.css +0 -25
- package/dist/Components/Loader/index.d.ts +0 -1
- package/dist/Components/Loader/index.js +0 -9
- package/dist/Components/Modal/Modal.module.css +0 -92
- package/dist/Components/Modal/index.d.ts +0 -10
- package/dist/Components/Modal/index.js +0 -16
- package/dist/Components/NumberField/NumberField.module.css +0 -60
- package/dist/Components/NumberField/index.d.ts +0 -3
- package/dist/Components/NumberField/index.js +0 -13
- package/dist/Components/RoiEditor/Canvas.d.ts +0 -10
- package/dist/Components/RoiEditor/Canvas.js +0 -28
- package/dist/Components/RoiEditor/ColorPicker.d.ts +0 -5
- package/dist/Components/RoiEditor/ColorPicker.js +0 -12
- package/dist/Components/RoiEditor/ColorPicker.module.css +0 -17
- package/dist/Components/RoiEditor/Header.d.ts +0 -2
- package/dist/Components/RoiEditor/Header.js +0 -22
- package/dist/Components/RoiEditor/Header.module.css +0 -32
- package/dist/Components/RoiEditor/Hooks.d.ts +0 -35
- package/dist/Components/RoiEditor/Hooks.js +0 -321
- package/dist/Components/RoiEditor/ParameterField.d.ts +0 -9
- package/dist/Components/RoiEditor/ParameterField.js +0 -27
- package/dist/Components/RoiEditor/ParametersModalForm/ParametersModalForm.module.css +0 -5
- package/dist/Components/RoiEditor/ParametersModalForm/index.d.ts +0 -16
- package/dist/Components/RoiEditor/ParametersModalForm/index.js +0 -40
- package/dist/Components/RoiEditor/Polygon.d.ts +0 -18
- package/dist/Components/RoiEditor/Polygon.js +0 -77
- package/dist/Components/RoiEditor/Polyline.d.ts +0 -28
- package/dist/Components/RoiEditor/Polyline.js +0 -75
- package/dist/Components/RoiEditor/Rectangle.d.ts +0 -21
- package/dist/Components/RoiEditor/Rectangle.js +0 -73
- package/dist/Components/RoiEditor/RoiEditor.module.css +0 -5
- package/dist/Components/RoiEditor/RoisInfo.d.ts +0 -2
- package/dist/Components/RoiEditor/RoisInfo.js +0 -43
- package/dist/Components/RoiEditor/ShapesList.d.ts +0 -2
- package/dist/Components/RoiEditor/ShapesList.js +0 -77
- package/dist/Components/RoiEditor/ShapesList.module.css +0 -67
- package/dist/Components/RoiEditor/Toolbar.d.ts +0 -2
- package/dist/Components/RoiEditor/Toolbar.js +0 -25
- package/dist/Components/RoiEditor/Toolbar.module.css +0 -41
- package/dist/Components/RoiEditor/Types.d.ts +0 -119
- package/dist/Components/RoiEditor/Types.js +0 -15
- package/dist/Components/RoiEditor/Utils.d.ts +0 -22
- package/dist/Components/RoiEditor/Utils.js +0 -150
- package/dist/Components/RoiEditor/index.d.ts +0 -10
- package/dist/Components/RoiEditor/index.js +0 -78
- package/dist/Components/RoleField.d.ts +0 -7
- package/dist/Components/RoleField.js +0 -35
- package/dist/Components/TextField/TextField.module.css +0 -61
- package/dist/Components/TextField/index.d.ts +0 -6
- package/dist/Components/TextField/index.js +0 -13
- package/dist/Components/Typography/index.d.ts +0 -9
- package/dist/Components/Typography/index.js +0 -6
- package/dist/Icons/AnnotateIcon.d.ts +0 -6
- package/dist/Icons/AnnotateIcon.js +0 -5
- package/dist/Icons/CloseIcon.d.ts +0 -6
- package/dist/Icons/CloseIcon.js +0 -5
- package/dist/Icons/CopyIcon.d.ts +0 -6
- package/dist/Icons/CopyIcon.js +0 -5
- package/dist/Icons/DeleteIcon.d.ts +0 -6
- package/dist/Icons/DeleteIcon.js +0 -5
- package/dist/Icons/EditIcon.d.ts +0 -6
- package/dist/Icons/EditIcon.js +0 -5
- package/dist/Icons/PointerIcon.d.ts +0 -6
- package/dist/Icons/PointerIcon.js +0 -5
- package/dist/Icons/PolygonIcon.d.ts +0 -6
- package/dist/Icons/PolygonIcon.js +0 -5
- package/dist/Icons/PolylineIcon.d.ts +0 -6
- package/dist/Icons/PolylineIcon.js +0 -5
- package/dist/Icons/RectangleIcon.d.ts +0 -6
- package/dist/Icons/RectangleIcon.js +0 -5
- package/dist/Icons/SaveIcon.d.ts +0 -6
- package/dist/Icons/SaveIcon.js +0 -5
- package/dist/Icons/SelectIcon.d.ts +0 -6
- package/dist/Icons/SelectIcon.js +0 -5
- package/dist/Providers/EditorProvider.d.ts +0 -26
- package/dist/Providers/EditorProvider.js +0 -29
- package/dist/Providers/UiProvider.d.ts +0 -84
- package/dist/Providers/UiProvider.js +0 -107
- package/dist/Types.d.ts +0 -10
- package/dist/Types.js +0 -1
- package/dist/Utils/Dispatcher.d.ts +0 -16
- package/dist/Utils/Dispatcher.js +0 -65
- package/dist/Utils/index.d.ts +0 -4
- package/dist/Utils/index.js +0 -14
- package/dist/index.d.ts +0 -4
- package/dist/index.js +0 -4
package/README.md
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
This is a react component which lets you draw regions of interest (ROI) over images, manage metadata and import/export everything.
|
6
6
|
Metadata are dynamic information that can be attached to the whole image and/or to each ROI. The number of drawable ROIs can also be configured.
|
7
7
|
|
8
|
-

|
8
|
+

|
9
9
|
|
10
10
|
It provides one component: `RoiEditor` and one provider: `UiProvider`. The editor lets you draw regions of interest over a given image (url). Each ROI can have dynamic metadata attached.
|
11
11
|
|
@@ -37,11 +37,12 @@ const MyComponent: React.FC = () => {
|
|
37
37
|
const themMode = 'light'
|
38
38
|
const config = {} // see below
|
39
39
|
|
40
|
-
const handleSubmit = (data: Types.Output) => console.log(data)
|
40
|
+
const handleSubmit = (data: Types.Output) => console.log(data) // onSubmit runs validation
|
41
|
+
const handleUpdate = (data: Types.Output) => console.log(data) // onUpdate runs without validation
|
41
42
|
|
42
43
|
return (
|
43
44
|
<UiProvider themeMode={themeMode} IconButton={IconButton} Typography={Typography} DeleteIcon={() => <Delete />}>
|
44
|
-
<RoiEditor imageUrl={'https://placecats.com/800/600'} configuration={config} onSubmit={handleSubmit} />
|
45
|
+
<RoiEditor imageUrl={'https://placecats.com/800/600'} configuration={config} onSubmit={handleSubmit} onUpdate={handleUpdate} />
|
45
46
|
</UiProvider>
|
46
47
|
)
|
47
48
|
}
|
@@ -279,7 +280,6 @@ type UiContextType = {
|
|
279
280
|
Modal: React.FC<ModalProps> // modal dialog component (it displays metadata forms)
|
280
281
|
IconButton: React.FC<IconButtonProps> // wrapper for icon buttons
|
281
282
|
DeleteIcon: React.FC<DeleteIconProps> // delete icon
|
282
|
-
SelectIcon: React.FC<SelectIconProps> // select icon
|
283
283
|
CopyIcon: typeof CopyIcon // copy icon (clone a shape)
|
284
284
|
AnnotateIcon: typeof AnnotateIcon // annotate icon (open metadata form)
|
285
285
|
CloseIcon: typeof CloseIcon // close icon
|
@@ -321,11 +321,11 @@ type UiContextType = {
|
|
321
321
|
role: string
|
322
322
|
save: string
|
323
323
|
shapeParametersMetadata: string
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
324
|
+
shapesOfRoleShouldBeEqualToThreshold: string // with {role} and {threshold} placeholders
|
325
|
+
shapesOfRoleShouldBeGreaterThanThreshold: string // with {role} and {threshold} placeholders
|
326
|
+
shapesOfRoleShouldBeGreaterThanOrEqualToThreshold: string // with {role} and {threshold} placeholders
|
327
|
+
shapesOfRoleShouldBeLessThanThreshold: string // with {role} and {threshold} placeholders
|
328
|
+
shapesOfRoleShouldBeLessThanOrEqualToThreshold: string // with {role} and {threshold} placeholders
|
329
329
|
type: string
|
330
330
|
}
|
331
331
|
}
|
@@ -436,17 +436,6 @@ type EditIconProps = {
|
|
436
436
|
}
|
437
437
|
```
|
438
438
|
|
439
|
-
#### SelectIcon
|
440
|
-
|
441
|
-
##### Interface
|
442
|
-
|
443
|
-
```ts
|
444
|
-
type SelectIconProps = {
|
445
|
-
color?: string
|
446
|
-
style?: React.CSSProperties
|
447
|
-
}
|
448
|
-
```
|
449
|
-
|
450
439
|
#### CopyIcon
|
451
440
|
|
452
441
|
##### Interface
|
@@ -658,11 +647,17 @@ type INotify = { // compatible with toast (react-toastify)
|
|
658
647
|
|
659
648
|
There are components that cannot be overridden. But still you can use classes to style them.
|
660
649
|
|
661
|
-
####
|
650
|
+
#### Top bar
|
651
|
+
|
652
|
+
- `react-cam-roi-top-bar`
|
653
|
+
- `react-cam-roi-top-bar-light`
|
654
|
+
- `react-cam-roi-top-bar-dark`
|
662
655
|
|
663
|
-
|
664
|
-
|
665
|
-
- `react-cam-roi-
|
656
|
+
#### Canvas wrapper
|
657
|
+
|
658
|
+
- `react-cam-roi-canvas-wrapper`
|
659
|
+
- `react-cam-roi-canvas-wrapper-light`
|
660
|
+
- `react-cam-roi-canvas-wrapper-dark`
|
666
661
|
|
667
662
|
#### Header
|
668
663
|
|
@@ -741,12 +736,6 @@ Then rebuild this library to see your changes in the project.
|
|
741
736
|
|
742
737
|
## CI
|
743
738
|
|
744
|
-
A github action pipeline is provided,
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
```bash
|
749
|
-
$ npm version patch
|
750
|
-
$ git push
|
751
|
-
$ git push --tags
|
752
|
-
```
|
739
|
+
A github action pipeline is provided, which is triggered by every push to the main branch.
|
740
|
+
The pipeline will publish the package to npm and update the CHANGELOG following the [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/).
|
741
|
+
You need to add the `NODE_AUTH_TOKEN` and `GH_TOKEN` secrets to your repository settings, see [semantic-release](https://github.com/semantic-release/semantic-release) for more information.
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@abidibo/react-cam-roi",
|
3
|
-
"version": "0.0
|
3
|
+
"version": "0.2.0",
|
4
4
|
"description": "A react component for drawing ROI over images and managing metadata",
|
5
5
|
"repository": {
|
6
6
|
"type": "git",
|
@@ -33,6 +33,30 @@
|
|
33
33
|
"storybook": "storybook dev -p 6006",
|
34
34
|
"build-storybook": "storybook build -o docs"
|
35
35
|
},
|
36
|
+
"release": {
|
37
|
+
"branches": [
|
38
|
+
"main"
|
39
|
+
],
|
40
|
+
"plugins": [
|
41
|
+
"@semantic-release/commit-analyzer",
|
42
|
+
"@semantic-release/release-notes-generator",
|
43
|
+
[
|
44
|
+
"@semantic-release/changelog",
|
45
|
+
{
|
46
|
+
"changelogFile": "CHANGELOG.md"
|
47
|
+
}
|
48
|
+
],
|
49
|
+
[
|
50
|
+
"@semantic-release/git",
|
51
|
+
{
|
52
|
+
"assets": [
|
53
|
+
"CHANGELOG.md"
|
54
|
+
]
|
55
|
+
}
|
56
|
+
],
|
57
|
+
"@semantic-release/npm"
|
58
|
+
]
|
59
|
+
},
|
36
60
|
"author": "abidibo",
|
37
61
|
"license": "MIT",
|
38
62
|
"devDependencies": {
|
@@ -42,6 +66,8 @@
|
|
42
66
|
"@eslint/js": "^9.18.0",
|
43
67
|
"@fontsource/roboto": "^5.1.1",
|
44
68
|
"@mui/material": "^6.4.3",
|
69
|
+
"@semantic-release/changelog": "^6.0.3",
|
70
|
+
"@semantic-release/git": "^10.0.1",
|
45
71
|
"@storybook/addon-essentials": "^8.4.7",
|
46
72
|
"@storybook/addon-interactions": "^8.4.7",
|
47
73
|
"@storybook/addon-onboarding": "^8.4.7",
|
@@ -60,6 +86,7 @@
|
|
60
86
|
"globals": "^15.14.0",
|
61
87
|
"prettier": "^3.4.2",
|
62
88
|
"rimraf": "^6.0.1",
|
89
|
+
"semantic-release": "^24.2.2",
|
63
90
|
"storybook": "^8.4.7",
|
64
91
|
"typescript": "^5.7.3",
|
65
92
|
"typescript-eslint": "^8.20.0"
|
@@ -1,60 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
.bool-field-wrapper {
|
3
|
-
margin-bottom: 2rem;
|
4
|
-
}
|
5
|
-
.bool-field-wrapper-light {
|
6
|
-
}
|
7
|
-
.bool-field-wrapper-dark {
|
8
|
-
}
|
9
|
-
*/
|
10
|
-
|
11
|
-
.bool-field {
|
12
|
-
border-radius: 0.25rem;
|
13
|
-
box-sizing: border-box;
|
14
|
-
padding: 0.5rem;
|
15
|
-
}
|
16
|
-
.bool-field:focus-visible {
|
17
|
-
outline: none;
|
18
|
-
border: 1px solid #1976d2;
|
19
|
-
}
|
20
|
-
.bool-field-light {
|
21
|
-
background-color: #fff;
|
22
|
-
color: #333;
|
23
|
-
border: 1px solid #ccc;
|
24
|
-
}
|
25
|
-
.bool-field-dark {
|
26
|
-
background-color: #333;
|
27
|
-
border: 1px solid #666;
|
28
|
-
color: #fff;
|
29
|
-
}
|
30
|
-
.bool-field-error {
|
31
|
-
border: 1px solid #d32f2f;
|
32
|
-
}
|
33
|
-
.bool-field-label {
|
34
|
-
font-weight: bold;
|
35
|
-
display: block;
|
36
|
-
margin: 0 0 1rem 0;
|
37
|
-
}
|
38
|
-
/*
|
39
|
-
.text-fiel-label-light {
|
40
|
-
}
|
41
|
-
.bool-field-label-dark {
|
42
|
-
}
|
43
|
-
*/
|
44
|
-
.bool-field-label-error {
|
45
|
-
color: #d32f2f;
|
46
|
-
}
|
47
|
-
.bool-field-helper-text {
|
48
|
-
font-style: italic;
|
49
|
-
font-size: 0.9rem;
|
50
|
-
margin-top: 0.5rem;
|
51
|
-
}
|
52
|
-
/*
|
53
|
-
.bool-field-helper-text-light {
|
54
|
-
}
|
55
|
-
.bool-field-helper-text-dark {
|
56
|
-
}
|
57
|
-
*/
|
58
|
-
.bool-field-helper-text-error {
|
59
|
-
color: #d32f2f;
|
60
|
-
}
|
@@ -1,13 +0,0 @@
|
|
1
|
-
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
2
|
-
import { useContext } from "react";
|
3
|
-
import { UiContext } from "../../Providers/UiProvider";
|
4
|
-
import { css } from "../../Utils";
|
5
|
-
import styles from './BoolField.module.css';
|
6
|
-
const BoolField = ({ onChange, value, label, helperText, error, readOnly = false, disabled = false, required = false, }) => {
|
7
|
-
const { themeMode, Typography } = useContext(UiContext);
|
8
|
-
const handleChange = (e) => {
|
9
|
-
onChange(e.target.checked);
|
10
|
-
};
|
11
|
-
return (_jsxs("div", { className: css('bool-field-wrapper', styles, themeMode), children: [_jsx("label", { className: `${css('bool-field-label', styles, themeMode)} ${error ? css('bool-field-label-error', styles, null) : ''}`, children: _jsxs(Typography, { children: [label, required && ' *'] }) }), _jsx("input", { type: 'checkbox', className: `${css('bool-field', styles, themeMode)} ${error ? css('bool-field-error', styles, null) : ''}`, onChange: handleChange, checked: value, readOnly: readOnly, disabled: disabled }), helperText && (_jsx(Typography, { component: 'div', className: `${css('bool-field-helper-text', styles, themeMode)} ${error ? css('bool-field-helper-text-error', styles, null) : ''}`, children: helperText }))] }));
|
12
|
-
};
|
13
|
-
export default BoolField;
|
@@ -1,29 +0,0 @@
|
|
1
|
-
.button {
|
2
|
-
align-items: center;
|
3
|
-
border: none;
|
4
|
-
border-radius: 4px;
|
5
|
-
color: black;
|
6
|
-
padding: .5rem 1rem;
|
7
|
-
text-align: center;
|
8
|
-
text-decoration: none;
|
9
|
-
display: flex;
|
10
|
-
font-size: 16px;
|
11
|
-
gap: .5rem;
|
12
|
-
margin: 4px 2px;
|
13
|
-
cursor: pointer;
|
14
|
-
}
|
15
|
-
|
16
|
-
.button-light {
|
17
|
-
background-color: #c7c7c7;
|
18
|
-
color: black;
|
19
|
-
}
|
20
|
-
|
21
|
-
.button-dark {
|
22
|
-
background-color: #383838;
|
23
|
-
color: white;
|
24
|
-
}
|
25
|
-
|
26
|
-
.button-disabled {
|
27
|
-
cursor: not-allowed;
|
28
|
-
opacity: 0.5;
|
29
|
-
}
|
@@ -1,8 +0,0 @@
|
|
1
|
-
import { PropsWithChildren } from 'react';
|
2
|
-
export type ButtonProps = {
|
3
|
-
onClick: (event: React.MouseEvent) => void;
|
4
|
-
primary?: boolean;
|
5
|
-
disabled?: boolean;
|
6
|
-
};
|
7
|
-
declare const Button: ({ onClick, primary, disabled, children }: PropsWithChildren<ButtonProps>) => import("react/jsx-runtime").JSX.Element;
|
8
|
-
export default Button;
|
@@ -1,15 +0,0 @@
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
2
|
-
import { useContext } from 'react';
|
3
|
-
import { UiContext } from '../../Providers/UiProvider';
|
4
|
-
import { css } from '../../Utils';
|
5
|
-
import styles from './Button.module.css';
|
6
|
-
const Button = ({ onClick, primary, disabled, children }) => {
|
7
|
-
const { themeMode, primaryColor } = useContext(UiContext);
|
8
|
-
const style = {};
|
9
|
-
if (primary) {
|
10
|
-
style.backgroundColor = primaryColor;
|
11
|
-
style.color = 'white';
|
12
|
-
}
|
13
|
-
return (_jsx("button", { className: `${css('button', styles, themeMode)}${disabled ? ` ${css('button-disabled', styles, themeMode)}` : ''}`, style: style, onClick: onClick, disabled: disabled, children: children }));
|
14
|
-
};
|
15
|
-
export default Button;
|
@@ -1,61 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
.enum-field-wrapper {
|
3
|
-
margin-bottom: 2rem;
|
4
|
-
}
|
5
|
-
.enum-field-wrapper-light {
|
6
|
-
}
|
7
|
-
.enum-field-wrapper-dark {
|
8
|
-
}
|
9
|
-
*/
|
10
|
-
|
11
|
-
.enum-field {
|
12
|
-
border-radius: 0.25rem;
|
13
|
-
box-sizing: border-box;
|
14
|
-
padding: 0.5rem;
|
15
|
-
width: 100%;
|
16
|
-
}
|
17
|
-
.enum-field:focus-visible {
|
18
|
-
outline: none;
|
19
|
-
border: 1px solid #1976d2;
|
20
|
-
}
|
21
|
-
.enum-field-light {
|
22
|
-
background-color: #fff;
|
23
|
-
color: #333;
|
24
|
-
border: 1px solid #ccc;
|
25
|
-
}
|
26
|
-
.enum-field-dark {
|
27
|
-
background-color: #333;
|
28
|
-
border: 1px solid #666;
|
29
|
-
color: #fff;
|
30
|
-
}
|
31
|
-
.enum-field-error {
|
32
|
-
border: 1px solid #d32f2f;
|
33
|
-
}
|
34
|
-
.enum-field-label {
|
35
|
-
font-weight: bold;
|
36
|
-
display: block;
|
37
|
-
margin: 0 0 1rem 0;
|
38
|
-
}
|
39
|
-
/*
|
40
|
-
.text-fiel-label-light {
|
41
|
-
}
|
42
|
-
.enum-field-label-dark {
|
43
|
-
}
|
44
|
-
*/
|
45
|
-
.enum-field-label-error {
|
46
|
-
color: #d32f2f;
|
47
|
-
}
|
48
|
-
.enum-field-helper-text {
|
49
|
-
font-style: italic;
|
50
|
-
font-size: 0.9rem;
|
51
|
-
margin-top: 0.5rem;
|
52
|
-
}
|
53
|
-
/*
|
54
|
-
.enum-field-helper-text-light {
|
55
|
-
}
|
56
|
-
.enum-field-helper-text-dark {
|
57
|
-
}
|
58
|
-
*/
|
59
|
-
.enum-field-helper-text-error {
|
60
|
-
color: #d32f2f;
|
61
|
-
}
|
@@ -1,10 +0,0 @@
|
|
1
|
-
import { FieldProps } from '../../Types';
|
2
|
-
export type EnumOption<T> = {
|
3
|
-
value: T;
|
4
|
-
label: string;
|
5
|
-
};
|
6
|
-
declare const EnumField: <T extends string | number>({ onChange, value, label, helperText, error, options, disabled, required, multiple }: Omit<FieldProps<T | T[]>, "readOnly"> & {
|
7
|
-
options: EnumOption<T>[];
|
8
|
-
multiple?: boolean;
|
9
|
-
}) => import("react/jsx-runtime").JSX.Element;
|
10
|
-
export default EnumField;
|
@@ -1,16 +0,0 @@
|
|
1
|
-
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
2
|
-
import { useContext } from 'react';
|
3
|
-
import { UiContext } from '../../Providers/UiProvider';
|
4
|
-
import { css } from '../../Utils';
|
5
|
-
import styles from './EnumField.module.css';
|
6
|
-
const EnumField = ({ onChange, value, label, helperText, error, options, disabled = false, required = false, multiple = false }) => {
|
7
|
-
const { themeMode, Typography } = useContext(UiContext);
|
8
|
-
const handleChange = (e) => {
|
9
|
-
const selectedValues = Array.from(e.target.selectedOptions, (option) => {
|
10
|
-
return isNaN(Number(option.value)) ? option.value : Number(option.value);
|
11
|
-
});
|
12
|
-
onChange(multiple ? selectedValues : selectedValues[0]);
|
13
|
-
};
|
14
|
-
return (_jsxs("div", { className: css('enum-field-wrapper', styles, themeMode), children: [_jsx("label", { className: `${css('enum-field-label', styles, themeMode)} ${error ? css('enum-field-label-error', styles, null) : ''}`, children: _jsxs(Typography, { children: [label, required && ' *'] }) }), _jsxs("select", { className: `${css('enum-field', styles, themeMode)} ${error ? css('enum-field-error', styles, null) : ''}`, onChange: handleChange, value: value, disabled: disabled, multiple: multiple, children: [!required && _jsx("option", { value: '' }), options.map((option) => (_jsx("option", { value: option.value, children: option.label }, option.value)))] }), helperText && (_jsx(Typography, { component: 'div', className: `${css('enum-field-helper-text', styles, themeMode)} ${error ? css('enum-field-helper-text-error', styles, null) : ''}`, children: helperText }))] }));
|
15
|
-
};
|
16
|
-
export default EnumField;
|
@@ -1,20 +0,0 @@
|
|
1
|
-
.icon-button {
|
2
|
-
display: inline-block;
|
3
|
-
border-radius: 50%;
|
4
|
-
line-height: 0;
|
5
|
-
padding: 0.5rem;
|
6
|
-
cursor: pointer;
|
7
|
-
}
|
8
|
-
|
9
|
-
.icon-button-light:hover {
|
10
|
-
background-color: rgba(0, 0, 0, 0.1);
|
11
|
-
}
|
12
|
-
|
13
|
-
.icon-button-dark:hover {
|
14
|
-
background-color: rgba(255, 255, 255, 0.1);
|
15
|
-
}
|
16
|
-
|
17
|
-
.icon-button-disabled {
|
18
|
-
cursor: not-allowed;
|
19
|
-
opacity: 0.5;
|
20
|
-
}
|
@@ -1,10 +0,0 @@
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
2
|
-
import { useContext } from 'react';
|
3
|
-
import { UiContext } from '../../Providers/UiProvider';
|
4
|
-
import { css } from '../../Utils';
|
5
|
-
import styles from './IconButton.module.css';
|
6
|
-
const IconButton = ({ children, disabled, onClick }) => {
|
7
|
-
const { themeMode } = useContext(UiContext);
|
8
|
-
return (_jsx("div", { className: `${css('icon-button', styles, themeMode)} ${disabled ? css('icon-button-disabled', styles, themeMode) : ''}`, onClick: disabled ? undefined : onClick, children: children }));
|
9
|
-
};
|
10
|
-
export default IconButton;
|
@@ -1,25 +0,0 @@
|
|
1
|
-
.loader {
|
2
|
-
border-radius: 50%;
|
3
|
-
width: 40px;
|
4
|
-
height: 40px;
|
5
|
-
animation: spin 1s linear infinite;
|
6
|
-
}
|
7
|
-
|
8
|
-
.loader-light {
|
9
|
-
border: 10px solid #f3f3f3;
|
10
|
-
border-top: 10px solid #3498db;
|
11
|
-
}
|
12
|
-
|
13
|
-
.loader-dark {
|
14
|
-
border: 10px solid #333;
|
15
|
-
border-top: 10px solid #3498db;
|
16
|
-
}
|
17
|
-
|
18
|
-
@keyframes spin {
|
19
|
-
0% {
|
20
|
-
transform: rotate(0deg);
|
21
|
-
}
|
22
|
-
100% {
|
23
|
-
transform: rotate(360deg);
|
24
|
-
}
|
25
|
-
}
|
@@ -1 +0,0 @@
|
|
1
|
-
export declare const Loader: React.FC;
|
@@ -1,9 +0,0 @@
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
2
|
-
import { useContext } from 'react';
|
3
|
-
import { UiContext } from '../../Providers/UiProvider';
|
4
|
-
import styles from './Loader.module.css';
|
5
|
-
import { css } from '../../Utils';
|
6
|
-
export const Loader = () => {
|
7
|
-
const { themeMode } = useContext(UiContext);
|
8
|
-
return _jsx("div", { className: css('loader', styles, themeMode) });
|
9
|
-
};
|
@@ -1,92 +0,0 @@
|
|
1
|
-
.modal-overlay {
|
2
|
-
position: fixed;
|
3
|
-
top: 0;
|
4
|
-
left: 0;
|
5
|
-
width: 100%;
|
6
|
-
height: 100%;
|
7
|
-
display: flex;
|
8
|
-
justify-content: center;
|
9
|
-
align-items: center;
|
10
|
-
z-index: 9000;
|
11
|
-
}
|
12
|
-
|
13
|
-
.modal-overlay-light {
|
14
|
-
background-color: rgba(255, 255, 255, 0.7);
|
15
|
-
}
|
16
|
-
|
17
|
-
.modal-overlay-dark {
|
18
|
-
background-color: rgba(0, 0, 0, 0.7);
|
19
|
-
}
|
20
|
-
|
21
|
-
.modal {
|
22
|
-
max-width: 80%;
|
23
|
-
max-height: 80%;
|
24
|
-
overflow: auto;
|
25
|
-
padding: 20px;
|
26
|
-
border-radius: 5px;
|
27
|
-
}
|
28
|
-
|
29
|
-
.modal:focus-visible {
|
30
|
-
outline: none;
|
31
|
-
}
|
32
|
-
|
33
|
-
.modal-light {
|
34
|
-
background-color: #fff;
|
35
|
-
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
36
|
-
color: #000;
|
37
|
-
}
|
38
|
-
|
39
|
-
.modal-dark {
|
40
|
-
background-color: #333;
|
41
|
-
box-shadow: 0 0 10px rgba(255, 255, 255, 0.2);
|
42
|
-
color: #fff;
|
43
|
-
}
|
44
|
-
|
45
|
-
.modal-xs {
|
46
|
-
width: 400px;
|
47
|
-
}
|
48
|
-
|
49
|
-
.modal-sm {
|
50
|
-
width: 600px;
|
51
|
-
}
|
52
|
-
|
53
|
-
.modal-md {
|
54
|
-
width: 800px;
|
55
|
-
}
|
56
|
-
|
57
|
-
.modal-lg {
|
58
|
-
width: 1000px;
|
59
|
-
}
|
60
|
-
|
61
|
-
.modal-xl {
|
62
|
-
width: 1200px;
|
63
|
-
}
|
64
|
-
|
65
|
-
.modal-header {
|
66
|
-
display: flex;
|
67
|
-
justify-content: space-between;
|
68
|
-
align-items: center;
|
69
|
-
margin-bottom: 1rem;
|
70
|
-
}
|
71
|
-
|
72
|
-
.modal-title {
|
73
|
-
font-size: 1.5rem;
|
74
|
-
font-weight: bold;
|
75
|
-
margin: 0;
|
76
|
-
}
|
77
|
-
|
78
|
-
.modal-title-light {
|
79
|
-
color: #000;
|
80
|
-
}
|
81
|
-
|
82
|
-
.modal-title-dark {
|
83
|
-
color: #fff;
|
84
|
-
}
|
85
|
-
|
86
|
-
.modal-footer {
|
87
|
-
display: flex;
|
88
|
-
justify-content: flex-end;
|
89
|
-
margin-top: 1rem;
|
90
|
-
gap: .5rem;
|
91
|
-
}
|
92
|
-
|
@@ -1,10 +0,0 @@
|
|
1
|
-
import { PropsWithChildren } from 'react';
|
2
|
-
export type ModalProps = {
|
3
|
-
isOpen: boolean;
|
4
|
-
onClose: () => void;
|
5
|
-
title: string;
|
6
|
-
maxWidth: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
7
|
-
onSubmit?: () => void;
|
8
|
-
};
|
9
|
-
declare const Modal: React.FC<PropsWithChildren<ModalProps>>;
|
10
|
-
export default Modal;
|
@@ -1,16 +0,0 @@
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
2
|
-
import { createPortal } from 'react-dom';
|
3
|
-
import { useContext } from 'react';
|
4
|
-
import CloseIcon from '../../Icons/CloseIcon';
|
5
|
-
import { UiContext } from '../../Providers/UiProvider';
|
6
|
-
import { css } from '../../Utils';
|
7
|
-
import styles from './Modal.module.css';
|
8
|
-
const Modal = ({ isOpen, onClose, children, title, maxWidth, onSubmit }) => {
|
9
|
-
const { themeMode, IconButton, Typography, Button, strings } = useContext(UiContext);
|
10
|
-
const iconColor = themeMode === 'light' ? 'black' : 'white';
|
11
|
-
if (!isOpen) {
|
12
|
-
return null;
|
13
|
-
}
|
14
|
-
return createPortal(_jsx("div", { className: css('modal-overlay', styles, themeMode), children: _jsxs("div", { className: `${css('modal', styles, themeMode)} ${css(`modal-${maxWidth}`, styles, themeMode)}`, children: [_jsxs("div", { className: css('modal-header', styles, themeMode), children: [_jsx(Typography, { component: 'h6', className: css('modal-title', styles, themeMode), children: title }), _jsx(IconButton, { onClick: onClose, children: _jsx(CloseIcon, { color: iconColor }) })] }), children, _jsxs("div", { className: css('modal-footer', styles, themeMode), children: [_jsx(Button, { onClick: onClose, children: strings.cancel }), onSubmit && _jsx(Button, { primary: true, onClick: onSubmit, children: strings.save })] })] }) }), document.body);
|
15
|
-
};
|
16
|
-
export default Modal;
|
@@ -1,60 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
.number-field-wrapper {
|
3
|
-
}
|
4
|
-
.number-field-wrapper-light {
|
5
|
-
}
|
6
|
-
.number-field-wrapper-dark {
|
7
|
-
}
|
8
|
-
*/
|
9
|
-
|
10
|
-
.number-field {
|
11
|
-
border-radius: 0.25rem;
|
12
|
-
box-sizing: border-box;
|
13
|
-
padding: 0.5rem;
|
14
|
-
width: 100%;
|
15
|
-
}
|
16
|
-
.number-field:focus-visible {
|
17
|
-
outline: none;
|
18
|
-
border: 1px solid #1976d2;
|
19
|
-
}
|
20
|
-
.number-field-light {
|
21
|
-
background-color: #fff;
|
22
|
-
color: #333;
|
23
|
-
border: 1px solid #ccc;
|
24
|
-
}
|
25
|
-
.number-field-dark {
|
26
|
-
background-color: #333;
|
27
|
-
border: 1px solid #666;
|
28
|
-
color: #fff;
|
29
|
-
}
|
30
|
-
.number-field-error {
|
31
|
-
border: 1px solid #d32f2f;
|
32
|
-
}
|
33
|
-
.number-field-label {
|
34
|
-
font-weight: bold;
|
35
|
-
display: block;
|
36
|
-
margin: 0 0 1rem 0;
|
37
|
-
}
|
38
|
-
/*
|
39
|
-
.text-fiel-label-light {
|
40
|
-
}
|
41
|
-
.number-field-label-dark {
|
42
|
-
}
|
43
|
-
*/
|
44
|
-
.number-field-label-error {
|
45
|
-
color: #d32f2f;
|
46
|
-
}
|
47
|
-
.number-field-helper-text {
|
48
|
-
font-style: italic;
|
49
|
-
font-size: 0.9rem;
|
50
|
-
padding-top: 0.5rem;
|
51
|
-
}
|
52
|
-
/*
|
53
|
-
.number-field-helper-text-light {
|
54
|
-
}
|
55
|
-
.number-field-helper-text-dark {
|
56
|
-
}
|
57
|
-
*/
|
58
|
-
.number-field-helper-text-error {
|
59
|
-
color: #d32f2f;
|
60
|
-
}
|
@@ -1,13 +0,0 @@
|
|
1
|
-
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
2
|
-
import { useContext } from 'react';
|
3
|
-
import { UiContext } from '../../Providers/UiProvider';
|
4
|
-
import { css } from '../../Utils';
|
5
|
-
import styles from './NumberField.module.css';
|
6
|
-
const NumberField = ({ onChange, value, label, required, helperText, error }) => {
|
7
|
-
const { themeMode, Typography } = useContext(UiContext);
|
8
|
-
const handleChange = (e) => {
|
9
|
-
onChange(parseFloat(e.target.value));
|
10
|
-
};
|
11
|
-
return (_jsxs("div", { className: css('number-field-wrapper', styles, themeMode), children: [_jsx("label", { className: `${css('number-field-label', styles, themeMode)} ${error ? css('number-field-label-error', styles, null) : ''}`, children: _jsxs(Typography, { children: [label, required && ' *'] }) }), _jsx("input", { type: 'number', className: `${css('number-field', styles, themeMode)} ${error ? css('number-field-error', styles, null) : ''}`, onChange: handleChange, value: value !== null && value !== void 0 ? value : '' }), helperText && (_jsx(Typography, { component: 'div', className: `${css('number-field-helper-text', styles, themeMode)} ${error ? css('number-field-helper-text-error', styles, null) : ''}`, children: helperText }))] }));
|
12
|
-
};
|
13
|
-
export default NumberField;
|