@rnaga/wp-next-ui 1.0.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/Accordion.d.ts +4 -0
- package/Accordion.d.ts.map +1 -0
- package/Accordion.js +13 -0
- package/Accordions.d.ts +19 -0
- package/Accordions.d.ts.map +1 -0
- package/Accordions.js +39 -0
- package/Background.d.ts +5 -0
- package/Background.d.ts.map +1 -0
- package/Background.js +18 -0
- package/BadgeOnMouseOver.d.ts +12 -0
- package/BadgeOnMouseOver.d.ts.map +1 -0
- package/BadgeOnMouseOver.js +40 -0
- package/BasicMenuButton.d.ts +17 -0
- package/BasicMenuButton.d.ts.map +1 -0
- package/BasicMenuButton.js +61 -0
- package/Button.d.ts +10 -0
- package/Button.d.ts.map +1 -0
- package/Button.js +15 -0
- package/Card.d.ts +6 -0
- package/Card.d.ts.map +1 -0
- package/Card.js +13 -0
- package/CardImage.d.ts +10 -0
- package/CardImage.d.ts.map +1 -0
- package/CardImage.js +34 -0
- package/Checkbox.d.ts +6 -0
- package/Checkbox.d.ts.map +1 -0
- package/Checkbox.js +13 -0
- package/Chip.d.ts +10 -0
- package/Chip.d.ts.map +1 -0
- package/Chip.js +41 -0
- package/DateTimePicker.d.ts +6 -0
- package/DateTimePicker.d.ts.map +1 -0
- package/DateTimePicker.js +45 -0
- package/DraggableBox.d.ts +39 -0
- package/DraggableBox.d.ts.map +1 -0
- package/DraggableBox.js +171 -0
- package/Form.d.ts +4 -0
- package/Form.d.ts.map +1 -0
- package/Form.js +8 -0
- package/FormDataProvider.d.ts +5 -0
- package/FormDataProvider.d.ts.map +1 -0
- package/FormDataProvider.js +6 -0
- package/IconButtonDelete.d.ts +6 -0
- package/IconButtonDelete.d.ts.map +1 -0
- package/IconButtonDelete.js +14 -0
- package/Input.d.ts +14 -0
- package/Input.d.ts.map +1 -0
- package/Input.js +84 -0
- package/InputClickField.d.ts +13 -0
- package/InputClickField.d.ts.map +1 -0
- package/InputClickField.js +21 -0
- package/InputColor.d.ts +12 -0
- package/InputColor.d.ts.map +1 -0
- package/InputColor.js +141 -0
- package/InputMultiple.d.ts +15 -0
- package/InputMultiple.d.ts.map +1 -0
- package/InputMultiple.js +55 -0
- package/InputSearch.d.ts +7 -0
- package/InputSearch.d.ts.map +1 -0
- package/InputSearch.js +28 -0
- package/Link.d.ts +6 -0
- package/Link.d.ts.map +1 -0
- package/Link.js +15 -0
- package/LinkCopy.d.ts +6 -0
- package/LinkCopy.d.ts.map +1 -0
- package/LinkCopy.js +17 -0
- package/Loading.d.ts +7 -0
- package/Loading.d.ts.map +1 -0
- package/Loading.js +29 -0
- package/LoadingBox.d.ts +12 -0
- package/LoadingBox.d.ts.map +1 -0
- package/LoadingBox.js +30 -0
- package/MediaTag.d.ts +9 -0
- package/MediaTag.d.ts.map +1 -0
- package/MediaTag.js +19 -0
- package/Modal.d.ts +11 -0
- package/Modal.d.ts.map +1 -0
- package/Modal.js +65 -0
- package/ModalConfirm.d.ts +8 -0
- package/ModalConfirm.d.ts.map +1 -0
- package/ModalConfirm.js +58 -0
- package/PopperMenu.d.ts +7 -0
- package/PopperMenu.d.ts.map +1 -0
- package/PopperMenu.js +6 -0
- package/README.md +292 -0
- package/Select.d.ts +21 -0
- package/Select.d.ts.map +1 -0
- package/Select.js +23 -0
- package/SelectAutocomplete.d.ts +1208 -0
- package/SelectAutocomplete.d.ts.map +1 -0
- package/SelectAutocomplete.js +113 -0
- package/SelectMultiple.d.ts +16 -0
- package/SelectMultiple.d.ts.map +1 -0
- package/SelectMultiple.js +28 -0
- package/SelectWPPost.d.ts +17 -0
- package/SelectWPPost.d.ts.map +1 -0
- package/SelectWPPost.js +98 -0
- package/SelectWPTaxonomy.d.ts +9 -0
- package/SelectWPTaxonomy.d.ts.map +1 -0
- package/SelectWPTaxonomy.js +35 -0
- package/SelectWPTerm.d.ts +13 -0
- package/SelectWPTerm.d.ts.map +1 -0
- package/SelectWPTerm.js +92 -0
- package/SelectWPTerms.d.ts +27 -0
- package/SelectWPTerms.d.ts.map +1 -0
- package/SelectWPTerms.js +105 -0
- package/SelectWPUser.d.ts +16 -0
- package/SelectWPUser.d.ts.map +1 -0
- package/SelectWPUser.js +101 -0
- package/SortableList.d.ts +28 -0
- package/SortableList.d.ts.map +1 -0
- package/SortableList.js +195 -0
- package/Tabs.d.ts +17 -0
- package/Tabs.d.ts.map +1 -0
- package/Tabs.js +35 -0
- package/ThemeRegistry.d.ts +13 -0
- package/ThemeRegistry.d.ts.map +1 -0
- package/ThemeRegistry.js +36 -0
- package/Typography.d.ts +9 -0
- package/Typography.d.ts.map +1 -0
- package/Typography.js +12 -0
- package/Viewport.d.ts +6 -0
- package/Viewport.d.ts.map +1 -0
- package/Viewport.js +10 -0
- package/hooks/use-form-data.d.ts +39 -0
- package/hooks/use-form-data.d.ts.map +1 -0
- package/hooks/use-form-data.js +91 -0
- package/hooks/use-media-selector.d.ts +10 -0
- package/hooks/use-media-selector.d.ts.map +1 -0
- package/hooks/use-media-selector.js +33 -0
- package/hooks/use-mouse-move.d.ts +18 -0
- package/hooks/use-mouse-move.d.ts.map +1 -0
- package/hooks/use-mouse-move.js +112 -0
- package/hooks/use-scheme-toggle.d.ts +6 -0
- package/hooks/use-scheme-toggle.d.ts.map +1 -0
- package/hooks/use-scheme-toggle.js +16 -0
- package/hooks/use-viewport.d.ts +5 -0
- package/hooks/use-viewport.d.ts.map +1 -0
- package/hooks/use-viewport.js +9 -0
- package/list/ListGrid.d.ts +12 -0
- package/list/ListGrid.d.ts.map +1 -0
- package/list/ListGrid.js +15 -0
- package/list/ListTable.d.ts +43 -0
- package/list/ListTable.d.ts.map +1 -0
- package/list/ListTable.js +143 -0
- package/list/Pagination.d.ts +5 -0
- package/list/Pagination.d.ts.map +1 -0
- package/list/Pagination.js +24 -0
- package/list/index.d.ts +4 -0
- package/list/index.d.ts.map +1 -0
- package/list/index.js +3 -0
- package/media/MediaGridForm.d.ts +5 -0
- package/media/MediaGridForm.d.ts.map +1 -0
- package/media/MediaGridForm.js +128 -0
- package/media/MediaThumbnail.d.ts +4 -0
- package/media/MediaThumbnail.d.ts.map +1 -0
- package/media/MediaThumbnail.js +17 -0
- package/media/MediaUpload.d.ts +7 -0
- package/media/MediaUpload.d.ts.map +1 -0
- package/media/MediaUpload.js +76 -0
- package/media/index.d.ts +4 -0
- package/media/index.d.ts.map +1 -0
- package/media/index.js +3 -0
- package/media-selector/MediaSelectorList.d.ts +2 -0
- package/media-selector/MediaSelectorList.d.ts.map +1 -0
- package/media-selector/MediaSelectorList.js +43 -0
- package/media-selector/MediaSelectorPreview.d.ts +2 -0
- package/media-selector/MediaSelectorPreview.d.ts.map +1 -0
- package/media-selector/MediaSelectorPreview.js +80 -0
- package/media-selector/index.d.ts +2 -0
- package/media-selector/index.d.ts.map +1 -0
- package/media-selector/index.js +49 -0
- package/package.json +33 -0
- package/portal/Portal.d.ts +6 -0
- package/portal/Portal.d.ts.map +1 -0
- package/portal/Portal.js +7 -0
- package/portal/index.d.ts +3 -0
- package/portal/index.d.ts.map +1 -0
- package/portal/index.js +2 -0
- package/portal/use-portal.d.ts +4 -0
- package/portal/use-portal.d.ts.map +1 -0
- package/portal/use-portal.js +11 -0
- package/types/global-state.d.ts +27 -0
- package/types/hooks/filters.d.ts +20 -0
- package/types/hooks/index.d.ts +1 -0
- package/types/index.d.ts +3 -0
- package/types/wp-theme.d.ts +49 -0
- package/wp-theme/index.d.ts +3 -0
- package/wp-theme/index.d.ts.map +1 -0
- package/wp-theme/index.js +86 -0
package/DraggableBox.js
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* A draggable component that displays content in a floating container.
|
|
4
|
+
*
|
|
5
|
+
* Props:
|
|
6
|
+
* - children: The content to be displayed inside the draggable box.
|
|
7
|
+
* - open: Controls whether the box is visible or not.
|
|
8
|
+
* - onClose: Callback to close the box.
|
|
9
|
+
* - offset: Optional initial offset for the box's X and Y coordinates.
|
|
10
|
+
* - title: Optional title to display in the header.
|
|
11
|
+
* - size: Sets the Typography size ("small" | "medium").
|
|
12
|
+
* - targetRef: Reference to an element whose relative position determines the box's initial placement.
|
|
13
|
+
* - sx: Style overrides for the outer Box wrapping the content.
|
|
14
|
+
* - slotSxProps: Style overrides for the header and title.
|
|
15
|
+
*/
|
|
16
|
+
import { useCallback, useEffect, useRef, useState, } from "react";
|
|
17
|
+
import { Box } from "@mui/material";
|
|
18
|
+
import { Typography } from "./Typography";
|
|
19
|
+
import { Background } from "./Background";
|
|
20
|
+
import { Portal } from "./portal";
|
|
21
|
+
export const DraggableBox = (props) => {
|
|
22
|
+
// Destructure props
|
|
23
|
+
const { children, targetRef, ref: selfRef, title, size, onClose, open, sx, slotSxProps, offset: initialOffset = {}, zIndexLayer = 0, placement = "left", } = props;
|
|
24
|
+
// Provide default offset values for the box
|
|
25
|
+
const { left = 0, top = 0 } = initialOffset;
|
|
26
|
+
// Reference to the draggable box DOM element
|
|
27
|
+
const boxRef = useRef(null);
|
|
28
|
+
// State to store the current position of the draggable box
|
|
29
|
+
const [position, setPosition] = useState({ x: left, y: top });
|
|
30
|
+
// Determines if the box is currently being dragged
|
|
31
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
32
|
+
// Stores the mouse down offset within the box
|
|
33
|
+
const [offset, setOffset] = useState({ x: 0, y: 0 });
|
|
34
|
+
/**
|
|
35
|
+
* Ensures the new position is within the browser window bounds.
|
|
36
|
+
* Returns null if the position would place the box partially off-screen.
|
|
37
|
+
*/
|
|
38
|
+
const clampPosition = (x, y, width, height) => {
|
|
39
|
+
let newX = x;
|
|
40
|
+
let newY = y;
|
|
41
|
+
if (newX < 0 || newX + width > window.innerWidth)
|
|
42
|
+
return null;
|
|
43
|
+
if (newY < 0 || newY + height > window.innerHeight)
|
|
44
|
+
return null;
|
|
45
|
+
return { x: newX, y: newY };
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Callback ref to get the DOM element for the draggable box.
|
|
49
|
+
* Requires a targetRef to position the box relative to another element.
|
|
50
|
+
*/
|
|
51
|
+
const callbackRef = useCallback((ref) => {
|
|
52
|
+
if (!ref || !targetRef?.current)
|
|
53
|
+
return;
|
|
54
|
+
boxRef.current = ref;
|
|
55
|
+
if (selfRef) {
|
|
56
|
+
// If a selfRef is provided, assign the boxRef to it
|
|
57
|
+
selfRef.current = ref;
|
|
58
|
+
}
|
|
59
|
+
// Calculate the referenced element’s position
|
|
60
|
+
const rect = targetRef.current.getBoundingClientRect();
|
|
61
|
+
const boxWidth = boxRef.current.offsetWidth || 0;
|
|
62
|
+
const boxHeight = boxRef.current.offsetHeight || 0;
|
|
63
|
+
// Compute initial position based on target element
|
|
64
|
+
let newX = rect.left + left - boxWidth;
|
|
65
|
+
let newY = rect.bottom - boxHeight / 2 + top;
|
|
66
|
+
// if placemenet is "target", x and y are relative to the target element
|
|
67
|
+
if (placement === "target") {
|
|
68
|
+
newX = rect.left;
|
|
69
|
+
newY = rect.top;
|
|
70
|
+
}
|
|
71
|
+
// If the box goes off-screen at the bottom, adjust upward
|
|
72
|
+
if (newY + boxHeight > window.innerHeight) {
|
|
73
|
+
newY = window.innerHeight - boxHeight;
|
|
74
|
+
}
|
|
75
|
+
// Store the position state
|
|
76
|
+
setPosition({ x: newX, y: newY });
|
|
77
|
+
}, [targetRef, left, top]);
|
|
78
|
+
/**
|
|
79
|
+
* Called when the user presses the mouse button within the box header.
|
|
80
|
+
* Captures the offset from the mouse position to the box's top-left corner.
|
|
81
|
+
*/
|
|
82
|
+
const handleMouseDown = (e) => {
|
|
83
|
+
setIsDragging(true);
|
|
84
|
+
const rect = boxRef.current?.getBoundingClientRect();
|
|
85
|
+
if (rect) {
|
|
86
|
+
setOffset({ x: e.clientX - rect.left, y: e.clientY - rect.top });
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Called whenever the mouse moves, if dragging is active.
|
|
91
|
+
* Updates the box position while respecting window bounds.
|
|
92
|
+
*/
|
|
93
|
+
const handleMouseMove = (e) => {
|
|
94
|
+
if (!isDragging || !boxRef.current)
|
|
95
|
+
return;
|
|
96
|
+
const { offsetWidth, offsetHeight } = boxRef.current;
|
|
97
|
+
const newPos = clampPosition(e.clientX - offset.x, e.clientY - offset.y, offsetWidth, offsetHeight);
|
|
98
|
+
if (newPos)
|
|
99
|
+
setPosition(newPos);
|
|
100
|
+
};
|
|
101
|
+
// Called when the mouse is released. Ends the dragging session.
|
|
102
|
+
const handleMouseUp = () => setIsDragging(false);
|
|
103
|
+
/**
|
|
104
|
+
* Subscribes to mousemove and mouseup while dragging; unsubscribes otherwise.
|
|
105
|
+
* This ensures we only respond to these events when necessary.
|
|
106
|
+
*/
|
|
107
|
+
useEffect(() => {
|
|
108
|
+
if (isDragging) {
|
|
109
|
+
window.addEventListener("mousemove", handleMouseMove);
|
|
110
|
+
window.addEventListener("mouseup", handleMouseUp);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
window.removeEventListener("mousemove", handleMouseMove);
|
|
114
|
+
window.removeEventListener("mouseup", handleMouseUp);
|
|
115
|
+
}
|
|
116
|
+
return () => {
|
|
117
|
+
window.removeEventListener("mousemove", handleMouseMove);
|
|
118
|
+
window.removeEventListener("mouseup", handleMouseUp);
|
|
119
|
+
};
|
|
120
|
+
}, [isDragging, offset]);
|
|
121
|
+
/**
|
|
122
|
+
* Observes changes to the box size and repositions if part of the box
|
|
123
|
+
* moves off-screen. This keeps the box fully visible upon resizing.
|
|
124
|
+
*/
|
|
125
|
+
useEffect(() => {
|
|
126
|
+
if (!open || !boxRef.current)
|
|
127
|
+
return;
|
|
128
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
129
|
+
const rect = boxRef.current.getBoundingClientRect();
|
|
130
|
+
let { x, y } = position;
|
|
131
|
+
const { width, height } = rect;
|
|
132
|
+
// Clamp against right/bottom edges
|
|
133
|
+
if (rect.right > window.innerWidth)
|
|
134
|
+
x = Math.max(0, window.innerWidth - width);
|
|
135
|
+
if (rect.bottom > window.innerHeight)
|
|
136
|
+
y = Math.max(0, window.innerHeight - height);
|
|
137
|
+
// Only update position if there's a change
|
|
138
|
+
if (x !== position.x || y !== position.y)
|
|
139
|
+
setPosition({ x, y });
|
|
140
|
+
});
|
|
141
|
+
resizeObserver.observe(boxRef.current);
|
|
142
|
+
// Cleanup upon unmount or when the box is closed
|
|
143
|
+
return () => resizeObserver.disconnect();
|
|
144
|
+
}, [open, position]);
|
|
145
|
+
// If the box is not open, render nothing
|
|
146
|
+
if (!open)
|
|
147
|
+
return null;
|
|
148
|
+
return (_jsxs(_Fragment, { children: [_jsx(Background, { zIndex: 999 + zIndexLayer, onClose: onClose }), _jsx(Portal, { children: _jsxs(Box
|
|
149
|
+
// Attach our callback ref
|
|
150
|
+
, {
|
|
151
|
+
// Attach our callback ref
|
|
152
|
+
ref: callbackRef, sx: {
|
|
153
|
+
position: "fixed",
|
|
154
|
+
left: position.x,
|
|
155
|
+
top: position.y,
|
|
156
|
+
userSelect: "none",
|
|
157
|
+
minWidth: 300,
|
|
158
|
+
zIndex: 1000 + zIndexLayer,
|
|
159
|
+
bgcolor: "background.paper",
|
|
160
|
+
borderRadius: 2,
|
|
161
|
+
p: 1,
|
|
162
|
+
...sx,
|
|
163
|
+
}, children: [_jsx(Box, { sx: {
|
|
164
|
+
height: 30,
|
|
165
|
+
cursor: "move",
|
|
166
|
+
...slotSxProps?.header,
|
|
167
|
+
}, onMouseDown: handleMouseDown, children: _jsx(Typography, { size: size, sx: {
|
|
168
|
+
p: 0.5,
|
|
169
|
+
...slotSxProps?.title,
|
|
170
|
+
}, bold: true, children: title }) }), _jsx(Box, { children: children })] }) })] }));
|
|
171
|
+
};
|
package/Form.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { FormLabel as MuiFormLabel } from "@mui/material";
|
|
2
|
+
export declare const FormControl: import("@mui/material/OverridableComponent").OverridableComponent<import("@mui/material").FormControlTypeMap<{}, "div">>;
|
|
3
|
+
export declare const FormLabel: (props: React.ComponentProps<typeof MuiFormLabel>) => import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
//# sourceMappingURL=Form.d.ts.map
|
package/Form.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Form.d.ts","sourceRoot":"","sources":["../src/Form.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,SAAS,IAAI,YAAY,EAC1B,MAAM,eAAe,CAAC;AAGvB,eAAO,MAAM,WAAW,0HAAiB,CAAC;AAC1C,eAAO,MAAM,SAAS,GAAI,OAAO,KAAK,CAAC,cAAc,CAAC,OAAO,YAAY,CAAC,4CAgBzE,CAAC"}
|
package/Form.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { FormControl as MuiFormControl, FormLabel as MuiFormLabel, } from "@mui/material";
|
|
3
|
+
import { Typography } from "./Typography";
|
|
4
|
+
export const FormControl = MuiFormControl;
|
|
5
|
+
export const FormLabel = (props) => {
|
|
6
|
+
const { children, required, ...rest } = props;
|
|
7
|
+
return (_jsx(MuiFormLabel, { focused: false, ...rest, children: _jsxs(Typography, { size: "medium", bold: true, component: "span", children: [children, required ? (_jsx(Typography, { component: "span", color: "error.main", fontSize: 18, children: "*" })) : ("")] }) }));
|
|
8
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormDataProvider.d.ts","sourceRoot":"","sources":["../src/FormDataProvider.tsx"],"names":[],"mappings":"AAEA,eAAO,MAAM,eAAe,2CAA6C,CAAC;AAE1E,eAAO,MAAM,gBAAgB,GAAI,OAAO;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,4CAEpE,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext } from "react";
|
|
3
|
+
export const FormDataContext = createContext({});
|
|
4
|
+
export const FormDataProvider = (props) => {
|
|
5
|
+
return _jsx(FormDataContext, { value: new Map(), children: props.children });
|
|
6
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IconButtonDelete.d.ts","sourceRoot":"","sources":["../src/IconButtonDelete.tsx"],"names":[],"mappings":"AAIA,eAAO,MAAM,gBAAgB,GAAI,OAAO;IACtC,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,KAAK,GAAG,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;CACrC,4CAqBA,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import DeleteIcon from "@mui/icons-material/Delete";
|
|
3
|
+
import { Tooltip } from "@mui/material";
|
|
4
|
+
import { Button } from "./Button";
|
|
5
|
+
export const IconButtonDelete = (props) => {
|
|
6
|
+
const { onClick, title = "Trash", size } = props;
|
|
7
|
+
return (_jsx(Tooltip, { title: title, placement: "top", children: _jsx(Button, { size: size, color: "error", variant: "outlined", onClick: onClick, sx: {
|
|
8
|
+
borderRadius: 2,
|
|
9
|
+
minWidth: "unset",
|
|
10
|
+
"&:hover": {
|
|
11
|
+
opacity: 0.9,
|
|
12
|
+
},
|
|
13
|
+
}, children: _jsx(DeleteIcon, { fontSize: size }) }) }));
|
|
14
|
+
};
|
package/Input.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Input as MuiInput } from "@mui/material";
|
|
2
|
+
export declare const Input: (props: {
|
|
3
|
+
onChange?: (value: string, e?: React.ChangeEvent<HTMLInputElement>) => void;
|
|
4
|
+
onBlur?: (value: string) => void;
|
|
5
|
+
onClear?: () => void | Promise<void>;
|
|
6
|
+
canClear?: boolean;
|
|
7
|
+
value?: string | number;
|
|
8
|
+
size?: "small" | "medium" | "large";
|
|
9
|
+
disableBorder?: boolean;
|
|
10
|
+
clearable?: boolean;
|
|
11
|
+
readOnly?: boolean;
|
|
12
|
+
removeBorderOnFocus?: boolean;
|
|
13
|
+
} & Omit<Parameters<typeof MuiInput>[0], "onChange" | "value" | "onBlur" | "size" | "readOnly">) => import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
//# sourceMappingURL=Input.d.ts.map
|
package/Input.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../src/Input.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AAKnE,eAAO,MAAM,KAAK,GAChB,OAAO;IACL,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IAC5E,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B,GAAG,IAAI,CACN,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,EAC9B,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CACtD,4CA+HF,CAAC"}
|
package/Input.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box, IconButton, Input as MuiInput } from "@mui/material";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import ClearIcon from "@mui/icons-material/Clear";
|
|
5
|
+
export const Input = (props) => {
|
|
6
|
+
const { onChange, onBlur, onClear, canClear, size, disableBorder, sx, readOnly = false, clearable = false, removeBorderOnFocus = false, multiline, value: _value, ...rest } = props;
|
|
7
|
+
const [value, setValue] = useState(_value ?? "");
|
|
8
|
+
const handleChange = (e) => {
|
|
9
|
+
const value = e.target.value;
|
|
10
|
+
setValue(value);
|
|
11
|
+
onChange && onChange(value);
|
|
12
|
+
};
|
|
13
|
+
const handleBlur = (e) => {
|
|
14
|
+
const value = e.target.value;
|
|
15
|
+
if (!onBlur)
|
|
16
|
+
return;
|
|
17
|
+
setValue(value);
|
|
18
|
+
onBlur(value);
|
|
19
|
+
};
|
|
20
|
+
const handleClear = () => {
|
|
21
|
+
setValue("");
|
|
22
|
+
onClear && onClear();
|
|
23
|
+
};
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (_value === undefined || _value === null || "" == _value)
|
|
26
|
+
return;
|
|
27
|
+
setValue(_value);
|
|
28
|
+
}, [_value]);
|
|
29
|
+
return (_jsx(MuiInput, { disableUnderline: true, readOnly: readOnly, onBlur: handleBlur, value: value, onChange: handleChange, multiline: multiline,
|
|
30
|
+
// onFocus={(e) => e.target.select?.()}
|
|
31
|
+
sx: {
|
|
32
|
+
height: multiline
|
|
33
|
+
? "auto"
|
|
34
|
+
: size === "large"
|
|
35
|
+
? 36
|
|
36
|
+
: size == "medium"
|
|
37
|
+
? 32
|
|
38
|
+
: 24,
|
|
39
|
+
px: 1,
|
|
40
|
+
fontSize: size === "large" ? 16 : size == "medium" ? 14 : 12,
|
|
41
|
+
border: disableBorder || multiline
|
|
42
|
+
? undefined
|
|
43
|
+
: (theme) => `1px solid ${theme.palette.grey[400]}`,
|
|
44
|
+
borderRadius: 1,
|
|
45
|
+
"&:focus-within": removeBorderOnFocus
|
|
46
|
+
? {
|
|
47
|
+
border: "none",
|
|
48
|
+
borderColor: "transparent",
|
|
49
|
+
}
|
|
50
|
+
: {
|
|
51
|
+
// border: (theme) => `1px solid ${theme.palette.primary.main}`,
|
|
52
|
+
// borderColor: (theme) => theme.palette.primary.main,
|
|
53
|
+
},
|
|
54
|
+
"&.MuiInputBase-root": {
|
|
55
|
+
mt: 0,
|
|
56
|
+
...(multiline && {
|
|
57
|
+
p: 0,
|
|
58
|
+
}),
|
|
59
|
+
},
|
|
60
|
+
backgroundColor: readOnly ? "#f5f5f5" : "transparent",
|
|
61
|
+
color: (theme) => theme.palette.text.primary,
|
|
62
|
+
...sx,
|
|
63
|
+
}, slotProps: {
|
|
64
|
+
input: !disableBorder && multiline
|
|
65
|
+
? {
|
|
66
|
+
sx: {
|
|
67
|
+
border: (theme) => `1px solid ${theme.palette.grey[400]}`,
|
|
68
|
+
p: 1,
|
|
69
|
+
borderRadius: 1,
|
|
70
|
+
},
|
|
71
|
+
}
|
|
72
|
+
: undefined,
|
|
73
|
+
}, endAdornment: ((clearable && String(`${value}`).length > 0) || canClear === true) && (_jsx(Box, { sx: {
|
|
74
|
+
width: 20,
|
|
75
|
+
}, children: _jsx(IconButton, { onClick: (e) => {
|
|
76
|
+
e.stopPropagation();
|
|
77
|
+
handleClear();
|
|
78
|
+
}, sx: {
|
|
79
|
+
minHeight: 0,
|
|
80
|
+
display: "flex",
|
|
81
|
+
alignItems: "center",
|
|
82
|
+
justifyContent: "center",
|
|
83
|
+
}, children: _jsx(ClearIcon, { fontSize: "small" }) }) })), ...rest }));
|
|
84
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SxProps } from "@mui/material";
|
|
2
|
+
import { Input } from "./Input";
|
|
3
|
+
export declare const InputClickField: (props: {
|
|
4
|
+
label: string;
|
|
5
|
+
value?: string;
|
|
6
|
+
onClick: (e: MouseEvent) => void;
|
|
7
|
+
size?: "small" | "medium" | "large";
|
|
8
|
+
sx?: SxProps;
|
|
9
|
+
slotSxProps?: {
|
|
10
|
+
input?: SxProps;
|
|
11
|
+
};
|
|
12
|
+
} & Omit<Parameters<typeof Input>[0], "label" | "size" | "onClick" | "readOnly">) => import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=InputClickField.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InputClickField.d.ts","sourceRoot":"","sources":["../src/InputClickField.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,eAAO,MAAM,eAAe,GAC1B,OAAO;IACL,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IACjC,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,WAAW,CAAC,EAAE;QACZ,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB,CAAC;CACH,GAAG,IAAI,CACN,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,EAC3B,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,CAC1C,4CA4BF,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Input } from "./Input";
|
|
3
|
+
export const InputClickField = (props) => {
|
|
4
|
+
const { label, onClick, size, value, ...rest } = props;
|
|
5
|
+
return (_jsx(Input, { readOnly: true, placeholder: label, onClick: (e) => {
|
|
6
|
+
onClick(e);
|
|
7
|
+
}, slotProps: {
|
|
8
|
+
input: {
|
|
9
|
+
sx: {
|
|
10
|
+
py: 0.1,
|
|
11
|
+
"::placeholder": {
|
|
12
|
+
fontSize: size === "large" ? 16 : size === "medium" ? 14 : 12,
|
|
13
|
+
opacity: value ? 0.8 : 0.5,
|
|
14
|
+
},
|
|
15
|
+
...props.slotSxProps?.input,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
}, sx: {
|
|
19
|
+
...props.sx,
|
|
20
|
+
}, ...rest }));
|
|
21
|
+
};
|
package/InputColor.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { CSSProperties } from "react";
|
|
2
|
+
import { Input } from "./Input";
|
|
3
|
+
import { SxProps } from "@mui/material";
|
|
4
|
+
export declare const isColorString: (src: string) => boolean;
|
|
5
|
+
export declare const InputColor: (props: Omit<Parameters<typeof Input>[0], "sx"> & {
|
|
6
|
+
sx?: SxProps;
|
|
7
|
+
slotSxProps?: {
|
|
8
|
+
input?: SxProps;
|
|
9
|
+
color?: CSSProperties;
|
|
10
|
+
};
|
|
11
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
//# sourceMappingURL=InputColor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InputColor.d.ts","sourceRoot":"","sources":["../src/InputColor.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAoB,MAAM,OAAO,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAO,OAAO,EAAE,MAAM,eAAe,CAAC;AAK7C,eAAO,MAAM,aAAa,GAAI,KAAK,MAAM,KAAG,OAUzC,CAAC;AA2IJ,eAAO,MAAM,UAAU,GACrB,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG;IAC/C,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,WAAW,CAAC,EAAE;QACZ,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,KAAK,CAAC,EAAE,aAAa,CAAC;KACvB,CAAC;CACH,4CA6DF,CAAC"}
|
package/InputColor.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useRef, useState } from "react";
|
|
3
|
+
import { Input } from "./Input";
|
|
4
|
+
import { Box } from "@mui/material";
|
|
5
|
+
export const isColorString = (src) => /^#([\da-f]{3}|[\da-f]{6})$/i.test(src) ||
|
|
6
|
+
/^rgba?\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}(?:\s*,\s*[\d.]+)?\s*\)$/.test(src) ||
|
|
7
|
+
/^hsla?\(\s*[\d.]+\s*(deg|rad|turn)?\s*,\s*\d{1,3}%\s*,\s*\d{1,3}%/.test(src) ||
|
|
8
|
+
/^hsv\(\s*[\d.]+\s*(deg|rad|turn)?\s*,\s*\d{1,3}%\s*,\s*\d{1,3}%\s*\)$/.test(src);
|
|
9
|
+
/** Convert common CSS color strings to 7-char hex (#rrggbb) for <input type="color"> */
|
|
10
|
+
const toHexColor = (src) => {
|
|
11
|
+
const v = src.trim().toLowerCase();
|
|
12
|
+
// Return empty string if the input is empty
|
|
13
|
+
if (!v)
|
|
14
|
+
return "";
|
|
15
|
+
/* ---------- HEX ---------- */
|
|
16
|
+
const hex = v.replace(/^#/, "");
|
|
17
|
+
if (/^[\da-f]{3}$/i.test(hex) || /^[\da-f]{6}$/i.test(hex)) {
|
|
18
|
+
const full = hex.length === 3
|
|
19
|
+
? hex
|
|
20
|
+
.split("")
|
|
21
|
+
.map((c) => c + c)
|
|
22
|
+
.join("")
|
|
23
|
+
: hex;
|
|
24
|
+
return `#${full}`;
|
|
25
|
+
}
|
|
26
|
+
/* ---------- RGB / RGBA ---------- */
|
|
27
|
+
const rgbMatch = v.match(/^rgba?\(([^)]+)\)$/);
|
|
28
|
+
if (rgbMatch) {
|
|
29
|
+
const [r, g, b] = rgbMatch[1]
|
|
30
|
+
.split(",")
|
|
31
|
+
.slice(0, 3)
|
|
32
|
+
.map((n) => clamp(+n, 0, 255));
|
|
33
|
+
return rgbToHex(r, g, b);
|
|
34
|
+
}
|
|
35
|
+
/* ---------- HSL / HSLA ---------- */
|
|
36
|
+
const hslMatch = v.match(/^hsla?\(\s*([\d.]+)(deg|rad|turn)?\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%/);
|
|
37
|
+
if (hslMatch) {
|
|
38
|
+
const h = parseAngle(+hslMatch[1], hslMatch[2]);
|
|
39
|
+
const s = clamp(+hslMatch[3], 0, 100) / 100;
|
|
40
|
+
const l = clamp(+hslMatch[4], 0, 100) / 100;
|
|
41
|
+
return rgbToHex(...hslToRgb(h, s, l));
|
|
42
|
+
}
|
|
43
|
+
/* ---------- HSV ---------- */
|
|
44
|
+
const hsvMatch = v.match(/^hsv\(\s*([\d.]+)(deg|rad|turn)?\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%\s*\)$/);
|
|
45
|
+
if (hsvMatch) {
|
|
46
|
+
const h = parseAngle(+hsvMatch[1], hsvMatch[2]);
|
|
47
|
+
const s = clamp(+hsvMatch[3], 0, 100) / 100;
|
|
48
|
+
const vv = clamp(+hsvMatch[4], 0, 100) / 100;
|
|
49
|
+
return rgbToHex(...hsvToRgb(h, s, vv));
|
|
50
|
+
}
|
|
51
|
+
//throw new Error(`Unsupported color format: “${src}”`);
|
|
52
|
+
// return "#000000" as HexString;
|
|
53
|
+
return ""; // Return empty string for unsupported formats
|
|
54
|
+
};
|
|
55
|
+
/* ---------- helpers ---------- */
|
|
56
|
+
const clamp = (n, min, max) => Math.min(Math.max(n, min), max);
|
|
57
|
+
const rgbToHex = (r, g, b) => `#${[r, g, b]
|
|
58
|
+
.map((c) => c.toString(16).padStart(2, "0"))
|
|
59
|
+
.join("")}`;
|
|
60
|
+
const parseAngle = (val, unit = "deg") => {
|
|
61
|
+
switch (unit) {
|
|
62
|
+
case "turn":
|
|
63
|
+
return (val * 360) % 360;
|
|
64
|
+
case "rad":
|
|
65
|
+
return ((val * 180) / Math.PI) % 360;
|
|
66
|
+
default:
|
|
67
|
+
return val % 360; // deg
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
const hslToRgb = (h, s, l) => {
|
|
71
|
+
const c = (1 - Math.abs(2 * l - 1)) * s;
|
|
72
|
+
const hp = h / 60;
|
|
73
|
+
const x = c * (1 - Math.abs((hp % 2) - 1));
|
|
74
|
+
const [r1, g1, b1] = hp < 1
|
|
75
|
+
? [c, x, 0]
|
|
76
|
+
: hp < 2
|
|
77
|
+
? [x, c, 0]
|
|
78
|
+
: hp < 3
|
|
79
|
+
? [0, c, x]
|
|
80
|
+
: hp < 4
|
|
81
|
+
? [0, x, c]
|
|
82
|
+
: hp < 5
|
|
83
|
+
? [x, 0, c]
|
|
84
|
+
: [c, 0, x];
|
|
85
|
+
const m = l - c / 2;
|
|
86
|
+
return [r1 + m, g1 + m, b1 + m].map((v) => Math.round(v * 255));
|
|
87
|
+
};
|
|
88
|
+
const hsvToRgb = (h, s, v) => {
|
|
89
|
+
const c = v * s;
|
|
90
|
+
const hp = h / 60;
|
|
91
|
+
const x = c * (1 - Math.abs((hp % 2) - 1));
|
|
92
|
+
const [r1, g1, b1] = hp < 1
|
|
93
|
+
? [c, x, 0]
|
|
94
|
+
: hp < 2
|
|
95
|
+
? [x, c, 0]
|
|
96
|
+
: hp < 3
|
|
97
|
+
? [0, c, x]
|
|
98
|
+
: hp < 4
|
|
99
|
+
? [0, x, c]
|
|
100
|
+
: hp < 5
|
|
101
|
+
? [x, 0, c]
|
|
102
|
+
: [c, 0, x];
|
|
103
|
+
const m = v - c;
|
|
104
|
+
return [r1 + m, g1 + m, b1 + m].map((v) => Math.round(v * 255));
|
|
105
|
+
};
|
|
106
|
+
export const InputColor = (props) => {
|
|
107
|
+
const { size, onChange, sx, onBlur, slotSxProps, ...rest } = props;
|
|
108
|
+
const timeoutId = useRef(null);
|
|
109
|
+
const [value, setValue] = useState(`${props.value ?? ""}`);
|
|
110
|
+
const handleChange = (value) => {
|
|
111
|
+
setValue(value);
|
|
112
|
+
onChange && onChange(value);
|
|
113
|
+
};
|
|
114
|
+
const handleBlur = (value) => {
|
|
115
|
+
if (!onBlur)
|
|
116
|
+
return;
|
|
117
|
+
setValue(value);
|
|
118
|
+
onBlur(value);
|
|
119
|
+
};
|
|
120
|
+
return (_jsxs(Box, { sx: { display: "flex", gap: 1, alignItems: "center", ...sx }, children: [_jsx(Input, { size: size, onChange: (value) => {
|
|
121
|
+
handleChange(value);
|
|
122
|
+
}, onBlur: (value) => {
|
|
123
|
+
handleBlur(value);
|
|
124
|
+
}, sx: {
|
|
125
|
+
width: "100%",
|
|
126
|
+
...slotSxProps?.input,
|
|
127
|
+
}, ...rest, value: value ?? "" }), _jsx("input", { type: "color", style: {
|
|
128
|
+
width: "15%",
|
|
129
|
+
height: size === "medium" ? 28 : size == "large" ? 32 : 22,
|
|
130
|
+
...slotSxProps?.color,
|
|
131
|
+
}, value: toHexColor(value ?? ""), onChange: (e) => {
|
|
132
|
+
const value = e.target.value;
|
|
133
|
+
if (timeoutId.current) {
|
|
134
|
+
clearTimeout(timeoutId.current);
|
|
135
|
+
}
|
|
136
|
+
timeoutId.current = setTimeout(() => {
|
|
137
|
+
handleChange(value);
|
|
138
|
+
timeoutId.current = null;
|
|
139
|
+
}, 20);
|
|
140
|
+
} })] }));
|
|
141
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SxProps } from "@mui/material";
|
|
2
|
+
import { type SlotSxProps } from "./SelectAutocomplete";
|
|
3
|
+
import { SyntheticEvent } from "react";
|
|
4
|
+
export type InputMultipleItem = string;
|
|
5
|
+
export declare const InputMultiple: (props: {
|
|
6
|
+
value?: InputMultipleItem[];
|
|
7
|
+
onChange: (values: InputMultipleItem[], e: SyntheticEvent<Element, Event>) => void;
|
|
8
|
+
validate?: (value: string) => [true] | [false, string];
|
|
9
|
+
freeSolo?: boolean;
|
|
10
|
+
slotSxProps?: SlotSxProps;
|
|
11
|
+
size?: "small" | "medium";
|
|
12
|
+
limitTags?: number;
|
|
13
|
+
sx?: SxProps;
|
|
14
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
//# sourceMappingURL=InputMultiple.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InputMultiple.d.ts","sourceRoot":"","sources":["../src/InputMultiple.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAgB,OAAO,EAAE,MAAM,eAAe,CAAC;AAEtD,OAAO,EAAsB,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAgC,MAAM,OAAO,CAAC;AAOrE,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC;AAEvC,eAAO,MAAM,aAAa,GAAI,OAAO;IACnC,KAAK,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC5B,QAAQ,EAAE,CACR,MAAM,EAAE,iBAAiB,EAAE,EAC3B,CAAC,EAAE,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,KAC9B,IAAI,CAAC;IACV,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,CAAC,EAAE,OAAO,CAAC;CACd,4CA8FA,CAAC"}
|
package/InputMultiple.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Autocomplete } from "@mui/material";
|
|
4
|
+
import { SelectAutocomplete } from "./SelectAutocomplete";
|
|
5
|
+
import { useEffect, useMemo, useState } from "react";
|
|
6
|
+
import { Typography } from "./Typography";
|
|
7
|
+
const sxSelectAutocomplete = SelectAutocomplete.sx;
|
|
8
|
+
const SelectAutocompleteTextField = SelectAutocomplete.TextField;
|
|
9
|
+
export const InputMultiple = (props) => {
|
|
10
|
+
const { onChange, validate, freeSolo = true, slotSxProps, size, limitTags = 2, sx, } = props;
|
|
11
|
+
const [value, setValue] = useState([]);
|
|
12
|
+
const [error, setError] = useState();
|
|
13
|
+
// Filter out empty strings from the value array
|
|
14
|
+
// const value = useMemo(
|
|
15
|
+
// () => (props.value ?? []).filter((v) => `${v}`.trim() !== ""),
|
|
16
|
+
// [props.value]
|
|
17
|
+
// );
|
|
18
|
+
const items = useMemo(() => (value ?? []).map((item) => typeof item === "string" ? { label: item, id: item } : item), [value]);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
console.log("InputMultiple useEffect", props.value);
|
|
21
|
+
const newValue = (props.value ?? []).filter((v) => `${v}`.trim() !== "");
|
|
22
|
+
setValue(newValue);
|
|
23
|
+
}, [props.value]);
|
|
24
|
+
return (_jsxs(SelectAutocomplete.Wrapper, { size: size, slotSxProps: slotSxProps, children: [_jsx(Autocomplete, { size: "small", multiple: true, freeSolo: true, limitTags: limitTags, options: items, value: value, onChange: (event, value) => {
|
|
25
|
+
event.stopPropagation();
|
|
26
|
+
if (validate) {
|
|
27
|
+
for (const item of value) {
|
|
28
|
+
if (typeof item !== "string") {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
const [success, errorMessage] = validate(item);
|
|
32
|
+
if (!success) {
|
|
33
|
+
// If validation fails, do not update the value
|
|
34
|
+
setError(errorMessage);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const newValue = value.map((item) => typeof item === "string" ? item : item.id);
|
|
40
|
+
setError(undefined);
|
|
41
|
+
setValue(newValue);
|
|
42
|
+
onChange(newValue, event);
|
|
43
|
+
}, sx: sxSelectAutocomplete({
|
|
44
|
+
size: size ?? "small",
|
|
45
|
+
sx: { zIndex: 9999, ...slotSxProps?.input },
|
|
46
|
+
...sx,
|
|
47
|
+
}), renderInput: (params) => (_jsx(SelectAutocompleteTextField, { params: params, size: size, sx: slotSxProps?.textField })), slotProps: {
|
|
48
|
+
// Don't show the dropdown menu
|
|
49
|
+
popper: {
|
|
50
|
+
sx: {
|
|
51
|
+
display: "none",
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
} }), error && (_jsx(Typography, { size: size, color: "error", children: error }))] }));
|
|
55
|
+
};
|
package/InputSearch.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { SxProps } from "@mui/material";
|
|
2
|
+
export declare const InputSearch: (props: {
|
|
3
|
+
size?: "small" | "medium" | "large";
|
|
4
|
+
sx?: SxProps | undefined;
|
|
5
|
+
onChange?: (value: string, e?: React.ChangeEvent<HTMLInputElement>) => void;
|
|
6
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=InputSearch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InputSearch.d.ts","sourceRoot":"","sources":["../src/InputSearch.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAKxC,eAAO,MAAM,WAAW,GAAI,OAAO;IACjC,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,EAAE,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACzB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;CAC7E,4CA6CA,CAAC"}
|
package/InputSearch.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useRef } from "react";
|
|
3
|
+
import SearchIcon from "@mui/icons-material/Search";
|
|
4
|
+
import { useNavigation } from "@rnaga/wp-next-core/client/hooks/use-navigation";
|
|
5
|
+
import { Input } from "./Input";
|
|
6
|
+
export const InputSearch = (props) => {
|
|
7
|
+
const { size = "small" } = props;
|
|
8
|
+
const { queryObject, updateRouter } = useNavigation();
|
|
9
|
+
const ref = useRef(null);
|
|
10
|
+
const handleClear = () => {
|
|
11
|
+
updateRouter({ search: "" });
|
|
12
|
+
ref.current.value = "";
|
|
13
|
+
};
|
|
14
|
+
const handleChange = (value, e) => {
|
|
15
|
+
if (props.onChange) {
|
|
16
|
+
props.onChange(value, e);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
updateRouter({ search: value, page: 1 });
|
|
20
|
+
};
|
|
21
|
+
return (_jsx(Input, { ref: ref, size: size, placeholder: "Search", startAdornment: _jsx(SearchIcon, { sx: {
|
|
22
|
+
opacity: 0.5,
|
|
23
|
+
} }), value: queryObject?.search, slotProps: {
|
|
24
|
+
input: {
|
|
25
|
+
// TypeScript may require this to avoid type errors
|
|
26
|
+
},
|
|
27
|
+
}, clearable: true, sx: props.sx ?? {}, onChange: (value, e) => handleChange(value, e), onClear: handleClear }));
|
|
28
|
+
};
|