sea-react-components 1.3.26 → 1.3.27
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/dist/components/button/index.js +1 -1
- package/dist/components/drawer/index.d.ts.map +1 -1
- package/dist/components/drawer/index.js +5 -5
- package/dist/components/searchable-select/index.d.ts +7 -2
- package/dist/components/searchable-select/index.d.ts.map +1 -1
- package/dist/components/searchable-select/index.js +93 -17
- package/package.json +2 -2
|
@@ -11,5 +11,5 @@ const classes = {
|
|
|
11
11
|
};
|
|
12
12
|
export default function Button({ loading = false, disabled, className, children, variant = "primary", ...props }) {
|
|
13
13
|
const classVariants = variant != "other" ? classes[variant] || classes["primary"] : className;
|
|
14
|
-
return (_jsx("button", { className: clsx("flex px-4 py-2 rounded-lg gap-1 items-center justify-center custom-animation", classVariants), disabled: disabled, ...props, children: loading ? (_jsx(Icon, { icon: "line-md:loading-loop", className: "w-6 h-6" })) : (children) }));
|
|
14
|
+
return (_jsx("button", { className: clsx("flex px-2 md:px-4 py-2 rounded-lg gap-1 items-center justify-center custom-animation", classVariants), disabled: disabled, ...props, children: loading ? (_jsx(Icon, { icon: "line-md:loading-loop", className: "w-6 h-6" })) : (children) }));
|
|
15
15
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/drawer/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAC5D,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEnD,MAAM,MAAM,KAAK,GAAG;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB,CAAC;AASF,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,EAC7B,MAAM,EACN,OAAO,EACP,SAAmB,EACnB,OAAc,EACd,SAAS,EACT,QAAQ,EACR,IAAW,GACZ,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/drawer/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAC5D,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEnD,MAAM,MAAM,KAAK,GAAG;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB,CAAC;AASF,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,EAC7B,MAAM,EACN,OAAO,EACP,SAAmB,EACnB,OAAc,EACd,SAAS,EACT,QAAQ,EACR,IAAW,GACZ,EAAE,KAAK,2CAsDP"}
|
|
@@ -2,10 +2,10 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
2
2
|
import clsx from "clsx";
|
|
3
3
|
import { Icon } from "@iconify/react";
|
|
4
4
|
const sizeClass = {
|
|
5
|
-
sm: "w-[
|
|
6
|
-
md: "
|
|
7
|
-
lg: "
|
|
8
|
-
xl: "
|
|
5
|
+
sm: "w-[100%] md:w-[320px]",
|
|
6
|
+
md: "w-[100%] sm:w-[400px] ",
|
|
7
|
+
lg: "w-[100%] md:w-[528px]",
|
|
8
|
+
xl: "w-[100%] md:w-[736px]",
|
|
9
9
|
};
|
|
10
10
|
export default function Drawer({ isOpen, onClose, placement = "right", overlay = true, className, children, size = "md", // NEW
|
|
11
11
|
}) {
|
|
@@ -20,5 +20,5 @@ export default function Drawer({ isOpen, onClose, placement = "right", overlay =
|
|
|
20
20
|
"top-0 left-0 max-h-screen h-full translate-x-0": placement === "left" && isOpen,
|
|
21
21
|
"bottom-0 left-0 w-full h-auto transform translate-y-full": placement === "bottom" && !isOpen,
|
|
22
22
|
"bottom-0 left-0 w-full h-auto translate-y-0": placement === "bottom" && isOpen,
|
|
23
|
-
}, widthClass, className), children: [_jsx("button", { onClick: onClose, className: "absolute top-2 right-2
|
|
23
|
+
}, widthClass, className), children: [_jsx("button", { onClick: onClose, className: "absolute top-2 right-2", children: _jsx(Icon, { icon: "line-md:close-small", className: "h-6 w-6 hover:scale-110 transition-all duration-300 ease-in-out" }) }), children] })] }));
|
|
24
24
|
}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { SelectProps } from "../../";
|
|
3
3
|
export type Props<T, K> = Omit<SelectProps<T>, "options" | "onChangeSearchInput"> & {
|
|
4
|
-
|
|
4
|
+
/** Fetch paginated / filtered list */
|
|
5
|
+
getItems: (query: string) => Promise<K[]>;
|
|
6
|
+
/** OPTIONAL: fetch single item by value (for selected values not in page) */
|
|
7
|
+
getOneItem?: (id: T) => Promise<K>;
|
|
8
|
+
/** Map item → label */
|
|
5
9
|
getLabel: (item: K) => React.ReactNode;
|
|
10
|
+
/** Map item → value */
|
|
6
11
|
getValue: (item: K) => T;
|
|
7
12
|
};
|
|
8
|
-
export default function SearchableSelect<T, K>({ getItems, getLabel, getValue, ...props }: Props<T, K>): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export default function SearchableSelect<T, K>({ getItems, getOneItem, getLabel, getValue, values, ...props }: Props<T, K>): import("react/jsx-runtime").JSX.Element;
|
|
9
14
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/searchable-select/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/searchable-select/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA+C,MAAM,OAAO,CAAC;AACpE,OAAO,EAAwB,WAAW,EAAE,MAAM,QAAQ,CAAC;AAY3D,MAAM,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,CAC5B,WAAW,CAAC,CAAC,CAAC,EACd,SAAS,GAAG,qBAAqB,CAClC,GAAG;IACF,sCAAsC;IACtC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAE1C,6EAA6E;IAC7E,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAEnC,uBAAuB;IACvB,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC;IAEvC,uBAAuB;IACvB,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC;CAC1B,CAAC;AAKF,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,EAC7C,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,MAAW,EACX,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,2CAoHb"}
|
|
@@ -1,28 +1,104 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
3
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
4
4
|
import { Select } from "../../";
|
|
5
|
-
|
|
5
|
+
/* ------------------------------------------------------------------ */
|
|
6
|
+
/* Utils */
|
|
7
|
+
/* ------------------------------------------------------------------ */
|
|
8
|
+
function isValidValue(value) {
|
|
9
|
+
return value !== undefined && value !== null && value !== "";
|
|
10
|
+
}
|
|
11
|
+
/* ------------------------------------------------------------------ */
|
|
12
|
+
/* Component */
|
|
13
|
+
/* ------------------------------------------------------------------ */
|
|
14
|
+
export default function SearchableSelect({ getItems, getOneItem, getLabel, getValue, values = [], ...props }) {
|
|
6
15
|
const [query, setQuery] = useState("");
|
|
7
|
-
const [
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
16
|
+
const [items, setItems] = useState([]);
|
|
17
|
+
const [resolvedSelected, setResolvedSelected] = useState([]);
|
|
18
|
+
/* ------------------------------------------------------------------
|
|
19
|
+
* Refs to avoid refetching on rerenders (Formik-safe)
|
|
20
|
+
* ------------------------------------------------------------------ */
|
|
21
|
+
const getItemsRef = useRef(getItems);
|
|
22
|
+
const getOneItemRef = useRef(getOneItem);
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
getItemsRef.current = getItems;
|
|
25
|
+
}, [getItems]);
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
getOneItemRef.current = getOneItem;
|
|
28
|
+
}, [getOneItem]);
|
|
29
|
+
/* ------------------------------------------------------------------
|
|
30
|
+
* Fetch list ONLY when query changes
|
|
31
|
+
* ------------------------------------------------------------------ */
|
|
12
32
|
useEffect(() => {
|
|
13
33
|
let active = true;
|
|
14
|
-
|
|
15
|
-
if (active)
|
|
16
|
-
|
|
34
|
+
getItemsRef.current(query).then((data) => {
|
|
35
|
+
if (active) {
|
|
36
|
+
setItems(data);
|
|
37
|
+
}
|
|
17
38
|
});
|
|
18
39
|
return () => {
|
|
19
|
-
active = false;
|
|
40
|
+
active = false;
|
|
20
41
|
};
|
|
21
42
|
}, [query]);
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
43
|
+
/* ------------------------------------------------------------------
|
|
44
|
+
* Resolve selected values not in current page (pagination-safe)
|
|
45
|
+
* ------------------------------------------------------------------ */
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
if (!getOneItemRef.current)
|
|
48
|
+
return;
|
|
49
|
+
if (!(values === null || values === void 0 ? void 0 : values.length))
|
|
50
|
+
return;
|
|
51
|
+
const validValues = values.filter(isValidValue);
|
|
52
|
+
if (!validValues.length)
|
|
53
|
+
return;
|
|
54
|
+
const knownIds = new Set([...items, ...resolvedSelected]
|
|
55
|
+
.map((i) => getValue(i))
|
|
56
|
+
.filter(isValidValue));
|
|
57
|
+
const missingIds = validValues.filter((id) => !knownIds.has(id));
|
|
58
|
+
if (!missingIds.length)
|
|
59
|
+
return;
|
|
60
|
+
let active = true;
|
|
61
|
+
Promise.all(missingIds.map((id) => getOneItemRef.current(id)))
|
|
62
|
+
.then((fetched) => {
|
|
63
|
+
if (!active)
|
|
64
|
+
return;
|
|
65
|
+
setResolvedSelected((prev) => {
|
|
66
|
+
const map = new Map();
|
|
67
|
+
[...prev, ...fetched].forEach((item) => {
|
|
68
|
+
const value = getValue(item);
|
|
69
|
+
if (isValidValue(value)) {
|
|
70
|
+
map.set(value, item);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
return Array.from(map.values());
|
|
74
|
+
});
|
|
75
|
+
})
|
|
76
|
+
.catch(() => {
|
|
77
|
+
/* ignore */
|
|
78
|
+
});
|
|
79
|
+
return () => {
|
|
80
|
+
active = false;
|
|
81
|
+
};
|
|
82
|
+
}, [values, items, resolvedSelected, getValue]);
|
|
83
|
+
/* ------------------------------------------------------------------
|
|
84
|
+
* Merge selected + paginated items
|
|
85
|
+
* Selected items always stay on top
|
|
86
|
+
* ------------------------------------------------------------------ */
|
|
87
|
+
const selectOptions = useMemo(() => {
|
|
88
|
+
const map = new Map();
|
|
89
|
+
[...resolvedSelected, ...items].forEach((item) => {
|
|
90
|
+
const value = getValue(item);
|
|
91
|
+
if (isValidValue(value)) {
|
|
92
|
+
map.set(value, item);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
return Array.from(map.values()).map((item) => ({
|
|
96
|
+
label: getLabel(item),
|
|
97
|
+
value: getValue(item),
|
|
98
|
+
}));
|
|
99
|
+
}, [items, resolvedSelected, getLabel, getValue]);
|
|
100
|
+
/* ------------------------------------------------------------------
|
|
101
|
+
* Render
|
|
102
|
+
* ------------------------------------------------------------------ */
|
|
103
|
+
return (_jsx(Select, { ...props, values: values, options: selectOptions, isSearchable: true, isRemote: true, onChangeSearchInput: setQuery }));
|
|
28
104
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sea-react-components",
|
|
3
3
|
"description": "SEA react components library",
|
|
4
|
-
"version": "1.3.
|
|
4
|
+
"version": "1.3.27",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "tsc --build && npx postcss src/styles.css -o dist/styles.css && npx postcss src/components/text-editor/style.css -o dist/components/text-editor/style.css",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"jwt-decode": "^4.0.0",
|
|
49
49
|
"lowlight": "^3.3.0",
|
|
50
50
|
"react-dom": "^18.3.1",
|
|
51
|
-
"sea-platform-helpers": "^1.5.
|
|
51
|
+
"sea-platform-helpers": "^1.5.22",
|
|
52
52
|
"sea-react-components": "file:",
|
|
53
53
|
"uuid": "^13.0.0",
|
|
54
54
|
"yup": "^1.5.0"
|